resolved conflicts for merge of 845fdba7 to master
Change-Id: I716b6ceb03bd733f9e7f49008112c8f2c53ad9ce
diff --git a/camera/Android.mk b/camera/Android.mk
index 2f16923..7286f92 100644
--- a/camera/Android.mk
+++ b/camera/Android.mk
@@ -6,21 +6,18 @@
CameraParameters.cpp \
ICamera.cpp \
ICameraClient.cpp \
- ICameraService.cpp
+ ICameraService.cpp \
+ ICameraRecordingProxy.cpp \
+ ICameraRecordingProxyListener.cpp
LOCAL_SHARED_LIBRARIES := \
libcutils \
libutils \
libbinder \
libhardware \
- libsurfaceflinger_client \
libui \
libgui
LOCAL_MODULE:= libcamera_client
-ifeq ($(TARGET_SIMULATOR),true)
- LOCAL_LDLIBS += -lpthread
-endif
-
include $(BUILD_SHARED_LIBRARY)
diff --git a/camera/Camera.cpp b/camera/Camera.cpp
index e288312..7ac3cc1 100644
--- a/camera/Camera.cpp
+++ b/camera/Camera.cpp
@@ -19,11 +19,12 @@
#define LOG_TAG "Camera"
#include <utils/Log.h>
#include <utils/threads.h>
-
+#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/IMemory.h>
#include <camera/Camera.h>
+#include <camera/ICameraRecordingProxyListener.h>
#include <camera/ICameraService.h>
#include <surfaceflinger/Surface.h>
@@ -205,22 +206,6 @@
return c->startPreview();
}
-int32_t Camera::getNumberOfVideoBuffers() const
-{
- LOGV("getNumberOfVideoBuffers");
- sp <ICamera> c = mCamera;
- if (c == 0) return 0;
- return c->getNumberOfVideoBuffers();
-}
-
-sp<IMemory> Camera::getVideoBuffer(int32_t index) const
-{
- LOGV("getVideoBuffer: %d", index);
- sp <ICamera> c = mCamera;
- if (c == 0) return 0;
- return c->getVideoBuffer(index);
-}
-
status_t Camera::storeMetaDataInBuffers(bool enabled)
{
LOGV("storeMetaDataInBuffers: %s",
@@ -252,6 +237,10 @@
void Camera::stopRecording()
{
LOGV("stopRecording");
+ {
+ Mutex::Autolock _l(mLock);
+ mRecordingProxyListener.clear();
+ }
sp <ICamera> c = mCamera;
if (c == 0) return;
c->stopRecording();
@@ -343,6 +332,12 @@
mListener = listener;
}
+void Camera::setRecordingProxyListener(const sp<ICameraRecordingProxyListener>& listener)
+{
+ Mutex::Autolock _l(mLock);
+ mRecordingProxyListener = listener;
+}
+
void Camera::setPreviewCallbackFlags(int flag)
{
LOGV("setPreviewCallbackFlags");
@@ -365,7 +360,8 @@
}
// callback from camera service when frame or image is ready
-void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr)
+void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr,
+ camera_frame_metadata_t *metadata)
{
sp<CameraListener> listener;
{
@@ -373,13 +369,26 @@
listener = mListener;
}
if (listener != NULL) {
- listener->postData(msgType, dataPtr);
+ listener->postData(msgType, dataPtr, metadata);
}
}
// callback from camera service when timestamped frame is ready
void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
{
+ // If recording proxy listener is registered, forward the frame and return.
+ // The other listener (mListener) is ignored because the receiver needs to
+ // call releaseRecordingFrame.
+ sp<ICameraRecordingProxyListener> proxylistener;
+ {
+ Mutex::Autolock _l(mLock);
+ proxylistener = mRecordingProxyListener;
+ }
+ if (proxylistener != NULL) {
+ proxylistener->dataCallbackTimestamp(timestamp, msgType, dataPtr);
+ return;
+ }
+
sp<CameraListener> listener;
{
Mutex::Autolock _l(mLock);
@@ -405,4 +414,34 @@
LOGW("Camera server died!");
}
+sp<ICameraRecordingProxy> Camera::getRecordingProxy() {
+ LOGV("getProxy");
+ return new RecordingProxy(this);
+}
+
+status_t Camera::RecordingProxy::startRecording(const sp<ICameraRecordingProxyListener>& listener)
+{
+ LOGV("RecordingProxy::startRecording");
+ mCamera->setRecordingProxyListener(listener);
+ mCamera->reconnect();
+ return mCamera->startRecording();
+}
+
+void Camera::RecordingProxy::stopRecording()
+{
+ LOGV("RecordingProxy::stopRecording");
+ mCamera->stopRecording();
+}
+
+void Camera::RecordingProxy::releaseRecordingFrame(const sp<IMemory>& mem)
+{
+ LOGV("RecordingProxy::releaseRecordingFrame");
+ mCamera->releaseRecordingFrame(mem);
+}
+
+Camera::RecordingProxy::RecordingProxy(const sp<Camera>& camera)
+{
+ mCamera = camera;
+}
+
}; // namespace android
diff --git a/camera/CameraParameters.cpp b/camera/CameraParameters.cpp
index 0fd79a4..51b96c1 100644
--- a/camera/CameraParameters.cpp
+++ b/camera/CameraParameters.cpp
@@ -59,6 +59,8 @@
const char CameraParameters::KEY_SUPPORTED_FLASH_MODES[] = "flash-mode-values";
const char CameraParameters::KEY_FOCUS_MODE[] = "focus-mode";
const char CameraParameters::KEY_SUPPORTED_FOCUS_MODES[] = "focus-mode-values";
+const char CameraParameters::KEY_MAX_NUM_FOCUS_AREAS[] = "max-num-focus-areas";
+const char CameraParameters::KEY_FOCUS_AREAS[] = "focus-areas";
const char CameraParameters::KEY_FOCAL_LENGTH[] = "focal-length";
const char CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE[] = "horizontal-view-angle";
const char CameraParameters::KEY_VERTICAL_VIEW_ANGLE[] = "vertical-view-angle";
@@ -66,6 +68,12 @@
const char CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION[] = "max-exposure-compensation";
const char CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION[] = "min-exposure-compensation";
const char CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP[] = "exposure-compensation-step";
+const char CameraParameters::KEY_AUTO_EXPOSURE_LOCK[] = "auto-exposure-lock";
+const char CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED[] = "auto-exposure-lock-supported";
+const char CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK[] = "auto-whitebalance-lock";
+const char CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED[] = "auto-whitebalance-lock-supported";
+const char CameraParameters::KEY_MAX_NUM_METERING_AREAS[] = "max-num-metering-areas";
+const char CameraParameters::KEY_METERING_AREAS[] = "metering-areas";
const char CameraParameters::KEY_ZOOM[] = "zoom";
const char CameraParameters::KEY_MAX_ZOOM[] = "max-zoom";
const char CameraParameters::KEY_ZOOM_RATIOS[] = "zoom-ratios";
@@ -76,8 +84,12 @@
const char CameraParameters::KEY_VIDEO_SIZE[] = "video-size";
const char CameraParameters::KEY_SUPPORTED_VIDEO_SIZES[] = "video-size-values";
const char CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO[] = "preferred-preview-size-for-video";
+const char CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW[] = "max-num-detected-faces-hw";
+const char CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW[] = "max-num-detected-faces-sw";
+const char CameraParameters::KEY_RECORDING_HINT[] = "recording-hint";
const char CameraParameters::TRUE[] = "true";
+const char CameraParameters::FALSE[] = "false";
const char CameraParameters::FOCUS_DISTANCE_INFINITY[] = "Infinity";
// Values for white balance settings.
@@ -137,7 +149,9 @@
const char CameraParameters::PIXEL_FORMAT_YUV422I[] = "yuv422i-yuyv";
const char CameraParameters::PIXEL_FORMAT_YUV420P[] = "yuv420p";
const char CameraParameters::PIXEL_FORMAT_RGB565[] = "rgb565";
+const char CameraParameters::PIXEL_FORMAT_RGBA8888[] = "rgba8888";
const char CameraParameters::PIXEL_FORMAT_JPEG[] = "jpeg";
+const char CameraParameters::PIXEL_FORMAT_BAYER_RGGB[] = "bayer-rggb";
// Values for focus mode settings.
const char CameraParameters::FOCUS_MODE_AUTO[] = "auto";
diff --git a/camera/ICamera.cpp b/camera/ICamera.cpp
index 931b57d..5f6e5ef 100644
--- a/camera/ICamera.cpp
+++ b/camera/ICamera.cpp
@@ -46,8 +46,6 @@
STOP_RECORDING,
RECORDING_ENABLED,
RELEASE_RECORDING_FRAME,
- GET_NUM_VIDEO_BUFFERS,
- GET_VIDEO_BUFFER,
STORE_META_DATA_IN_BUFFERS,
};
@@ -149,27 +147,6 @@
remote()->transact(RELEASE_RECORDING_FRAME, data, &reply);
}
- int32_t getNumberOfVideoBuffers() const
- {
- LOGV("getNumberOfVideoBuffers");
- Parcel data, reply;
- data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
- remote()->transact(GET_NUM_VIDEO_BUFFERS, data, &reply);
- return reply.readInt32();
- }
-
- sp<IMemory> getVideoBuffer(int32_t index) const
- {
- LOGV("getVideoBuffer: %d", index);
- Parcel data, reply;
- data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
- data.writeInt32(index);
- remote()->transact(GET_VIDEO_BUFFER, data, &reply);
- sp<IMemory> mem = interface_cast<IMemory>(
- reply.readStrongBinder());
- return mem;
- }
-
status_t storeMetaDataInBuffers(bool enabled)
{
LOGV("storeMetaDataInBuffers: %s", enabled? "true": "false");
@@ -355,19 +332,6 @@
releaseRecordingFrame(mem);
return NO_ERROR;
} break;
- case GET_NUM_VIDEO_BUFFERS: {
- LOGV("GET_NUM_VIDEO_BUFFERS");
- CHECK_INTERFACE(ICamera, data, reply);
- reply->writeInt32(getNumberOfVideoBuffers());
- return NO_ERROR;
- } break;
- case GET_VIDEO_BUFFER: {
- LOGV("GET_VIDEO_BUFFER");
- CHECK_INTERFACE(ICamera, data, reply);
- int32_t index = data.readInt32();
- reply->writeStrongBinder(getVideoBuffer(index)->asBinder());
- return NO_ERROR;
- } break;
case STORE_META_DATA_IN_BUFFERS: {
LOGV("STORE_META_DATA_IN_BUFFERS");
CHECK_INTERFACE(ICamera, data, reply);
diff --git a/camera/ICameraClient.cpp b/camera/ICameraClient.cpp
index cb3bd0c..183429a 100644
--- a/camera/ICameraClient.cpp
+++ b/camera/ICameraClient.cpp
@@ -51,13 +51,18 @@
}
// generic data callback from camera service to app with image data
- void dataCallback(int32_t msgType, const sp<IMemory>& imageData)
+ void dataCallback(int32_t msgType, const sp<IMemory>& imageData,
+ camera_frame_metadata_t *metadata)
{
LOGV("dataCallback");
Parcel data, reply;
data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
data.writeInt32(msgType);
data.writeStrongBinder(imageData->asBinder());
+ if (metadata) {
+ data.writeInt32(metadata->number_of_faces);
+ data.write(metadata->faces, sizeof(camera_face_t) * metadata->number_of_faces);
+ }
remote()->transact(DATA_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
}
@@ -96,7 +101,15 @@
CHECK_INTERFACE(ICameraClient, data, reply);
int32_t msgType = data.readInt32();
sp<IMemory> imageData = interface_cast<IMemory>(data.readStrongBinder());
- dataCallback(msgType, imageData);
+ camera_frame_metadata_t *metadata = NULL;
+ if (data.dataAvail() > 0) {
+ metadata = new camera_frame_metadata_t;
+ metadata->number_of_faces = data.readInt32();
+ metadata->faces = (camera_face_t *) data.readInplace(
+ sizeof(camera_face_t) * metadata->number_of_faces);
+ }
+ dataCallback(msgType, imageData, metadata);
+ if (metadata) delete metadata;
return NO_ERROR;
} break;
case DATA_CALLBACK_TIMESTAMP: {
diff --git a/camera/ICameraRecordingProxy.cpp b/camera/ICameraRecordingProxy.cpp
new file mode 100644
index 0000000..64b6a5c
--- /dev/null
+++ b/camera/ICameraRecordingProxy.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2011 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 "ICameraRecordingProxy"
+#include <camera/ICameraRecordingProxy.h>
+#include <camera/ICameraRecordingProxyListener.h>
+#include <binder/IMemory.h>
+#include <binder/Parcel.h>
+#include <stdint.h>
+#include <utils/Log.h>
+
+namespace android {
+
+enum {
+ START_RECORDING = IBinder::FIRST_CALL_TRANSACTION,
+ STOP_RECORDING,
+ RELEASE_RECORDING_FRAME,
+};
+
+
+class BpCameraRecordingProxy: public BpInterface<ICameraRecordingProxy>
+{
+public:
+ BpCameraRecordingProxy(const sp<IBinder>& impl)
+ : BpInterface<ICameraRecordingProxy>(impl)
+ {
+ }
+
+ status_t startRecording(const sp<ICameraRecordingProxyListener>& listener)
+ {
+ LOGV("startRecording");
+ Parcel data, reply;
+ data.writeInterfaceToken(ICameraRecordingProxy::getInterfaceDescriptor());
+ data.writeStrongBinder(listener->asBinder());
+ remote()->transact(START_RECORDING, data, &reply);
+ return reply.readInt32();
+ }
+
+ void stopRecording()
+ {
+ LOGV("stopRecording");
+ Parcel data, reply;
+ data.writeInterfaceToken(ICameraRecordingProxy::getInterfaceDescriptor());
+ remote()->transact(STOP_RECORDING, data, &reply);
+ }
+
+ void releaseRecordingFrame(const sp<IMemory>& mem)
+ {
+ LOGV("releaseRecordingFrame");
+ Parcel data, reply;
+ data.writeInterfaceToken(ICameraRecordingProxy::getInterfaceDescriptor());
+ data.writeStrongBinder(mem->asBinder());
+ remote()->transact(RELEASE_RECORDING_FRAME, data, &reply);
+ }
+};
+
+IMPLEMENT_META_INTERFACE(CameraRecordingProxy, "android.hardware.ICameraRecordingProxy");
+
+// ----------------------------------------------------------------------
+
+status_t BnCameraRecordingProxy::onTransact(
+ uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+ switch(code) {
+ case START_RECORDING: {
+ LOGV("START_RECORDING");
+ CHECK_INTERFACE(ICameraRecordingProxy, data, reply);
+ sp<ICameraRecordingProxyListener> listener =
+ interface_cast<ICameraRecordingProxyListener>(data.readStrongBinder());
+ reply->writeInt32(startRecording(listener));
+ return NO_ERROR;
+ } break;
+ case STOP_RECORDING: {
+ LOGV("STOP_RECORDING");
+ CHECK_INTERFACE(ICameraRecordingProxy, data, reply);
+ stopRecording();
+ return NO_ERROR;
+ } break;
+ case RELEASE_RECORDING_FRAME: {
+ LOGV("RELEASE_RECORDING_FRAME");
+ CHECK_INTERFACE(ICameraRecordingProxy, data, reply);
+ sp<IMemory> mem = interface_cast<IMemory>(data.readStrongBinder());
+ releaseRecordingFrame(mem);
+ return NO_ERROR;
+ } break;
+
+ default:
+ return BBinder::onTransact(code, data, reply, flags);
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
diff --git a/camera/ICameraRecordingProxyListener.cpp b/camera/ICameraRecordingProxyListener.cpp
new file mode 100644
index 0000000..f8cece5
--- /dev/null
+++ b/camera/ICameraRecordingProxyListener.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2011 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 "ICameraRecordingProxyListener"
+#include <camera/ICameraRecordingProxyListener.h>
+#include <binder/IMemory.h>
+#include <binder/Parcel.h>
+#include <utils/Log.h>
+
+namespace android {
+
+enum {
+ DATA_CALLBACK_TIMESTAMP = IBinder::FIRST_CALL_TRANSACTION,
+};
+
+class BpCameraRecordingProxyListener: public BpInterface<ICameraRecordingProxyListener>
+{
+public:
+ BpCameraRecordingProxyListener(const sp<IBinder>& impl)
+ : BpInterface<ICameraRecordingProxyListener>(impl)
+ {
+ }
+
+ void dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& imageData)
+ {
+ LOGV("dataCallback");
+ Parcel data, reply;
+ data.writeInterfaceToken(ICameraRecordingProxyListener::getInterfaceDescriptor());
+ data.writeInt64(timestamp);
+ data.writeInt32(msgType);
+ data.writeStrongBinder(imageData->asBinder());
+ remote()->transact(DATA_CALLBACK_TIMESTAMP, data, &reply, IBinder::FLAG_ONEWAY);
+ }
+};
+
+IMPLEMENT_META_INTERFACE(CameraRecordingProxyListener, "android.hardware.ICameraRecordingProxyListener");
+
+// ----------------------------------------------------------------------
+
+status_t BnCameraRecordingProxyListener::onTransact(
+ uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+ switch(code) {
+ case DATA_CALLBACK_TIMESTAMP: {
+ LOGV("DATA_CALLBACK_TIMESTAMP");
+ CHECK_INTERFACE(ICameraRecordingProxyListener, data, reply);
+ nsecs_t timestamp = data.readInt64();
+ int32_t msgType = data.readInt32();
+ sp<IMemory> imageData = interface_cast<IMemory>(data.readStrongBinder());
+ dataCallbackTimestamp(timestamp, msgType, imageData);
+ return NO_ERROR;
+ } break;
+ default:
+ return BBinder::onTransact(code, data, reply, flags);
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
diff --git a/cmds/stagefright/Android.mk b/cmds/stagefright/Android.mk
index 1b13dd9..e9642f7 100644
--- a/cmds/stagefright/Android.mk
+++ b/cmds/stagefright/Android.mk
@@ -8,7 +8,7 @@
LOCAL_SHARED_LIBRARIES := \
libstagefright libmedia libutils libbinder libstagefright_foundation \
- libskia libsurfaceflinger_client libgui
+ libskia libgui
LOCAL_C_INCLUDES:= \
$(JNI_H_INCLUDE) \
@@ -107,7 +107,7 @@
stream.cpp \
LOCAL_SHARED_LIBRARIES := \
- libstagefright liblog libutils libbinder libsurfaceflinger_client \
+ libstagefright liblog libutils libbinder libgui \
libstagefright_foundation libmedia
LOCAL_C_INCLUDES:= \
@@ -132,7 +132,7 @@
LOCAL_SHARED_LIBRARIES := \
libstagefright liblog libutils libbinder libstagefright_foundation \
- libmedia libsurfaceflinger_client libcutils libui
+ libmedia libgui libcutils libui
LOCAL_C_INCLUDES:= \
$(JNI_H_INCLUDE) \
diff --git a/cmds/stagefright/audioloop.cpp b/cmds/stagefright/audioloop.cpp
index 8733662..858681f 100644
--- a/cmds/stagefright/audioloop.cpp
+++ b/cmds/stagefright/audioloop.cpp
@@ -11,6 +11,8 @@
#include <media/stagefright/OMXClient.h>
#include <media/stagefright/OMXCodec.h>
+#include <system/audio.h>
+
using namespace android;
int main() {
@@ -31,8 +33,8 @@
AUDIO_SOURCE_DEFAULT,
kSampleRate,
kNumChannels == 1
- ? AudioSystem::CHANNEL_IN_MONO
- : AudioSystem::CHANNEL_IN_STEREO);
+ ? AUDIO_CHANNEL_IN_MONO
+ : AUDIO_CHANNEL_IN_STEREO);
#endif
sp<MetaData> meta = new MetaData;
diff --git a/cmds/stagefright/recordvideo.cpp b/cmds/stagefright/recordvideo.cpp
index 1264215..c402286 100644
--- a/cmds/stagefright/recordvideo.cpp
+++ b/cmds/stagefright/recordvideo.cpp
@@ -34,7 +34,7 @@
fprintf(stderr, "usage: %s\n", me);
fprintf(stderr, " -h(elp)\n");
fprintf(stderr, " -b bit rate in bits per second (default: 300000)\n");
- fprintf(stderr, " -c YUV420 color format: [0] semi planar or [1] planar (default: 1)\n");
+ fprintf(stderr, " -c YUV420 color format: [0] semi planar or [1] planar or other omx YUV420 color format (default: 1)\n");
fprintf(stderr, " -f frame rate in frames per second (default: 30)\n");
fprintf(stderr, " -i I frame interval in seconds (default: 1)\n");
fprintf(stderr, " -n number of frames to be recorded (default: 300)\n");
@@ -59,11 +59,6 @@
mSize((width * height * 3) / 2) {
mGroup.add_buffer(new MediaBuffer(mSize));
-
- // Check the color format to make sure
- // that the buffer size mSize it set correctly above.
- CHECK(colorFormat == OMX_COLOR_FormatYUV420SemiPlanar ||
- colorFormat == OMX_COLOR_FormatYUV420Planar);
}
virtual sp<MetaData> getFormat() {
@@ -144,9 +139,13 @@
case kYUV420P:
return OMX_COLOR_FormatYUV420Planar;
default:
- fprintf(stderr, "Unsupported color: %d\n", color);
- return -1;
+ fprintf(stderr, "Custom OMX color format: %d\n", color);
+ if (color == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar ||
+ color == OMX_QCOM_COLOR_FormatYVU420SemiPlanar) {
+ return color;
+ }
}
+ return -1;
}
int main(int argc, char **argv) {
diff --git a/cmds/stagefright/sf2.cpp b/cmds/stagefright/sf2.cpp
index c1d0803..6fa66cf 100644
--- a/cmds/stagefright/sf2.cpp
+++ b/cmds/stagefright/sf2.cpp
@@ -29,6 +29,7 @@
#include <media/stagefright/MediaExtractor.h>
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/MetaData.h>
+#include <media/stagefright/NativeWindowWrapper.h>
#include <media/stagefright/Utils.h>
#include <surfaceflinger/ISurfaceComposer.h>
@@ -39,10 +40,12 @@
using namespace android;
struct Controller : public AHandler {
- Controller(const char *uri, bool decodeAudio, const sp<Surface> &surface)
+ Controller(const char *uri, bool decodeAudio,
+ const sp<Surface> &surface, bool renderToSurface)
: mURI(uri),
mDecodeAudio(decodeAudio),
mSurface(surface),
+ mRenderToSurface(renderToSurface),
mCodec(new ACodec) {
CHECK(!mDecodeAudio || mSurface == NULL);
}
@@ -97,7 +100,8 @@
sp<AMessage> format = makeFormat(mSource->getFormat());
if (mSurface != NULL) {
- format->setObject("surface", mSurface);
+ format->setObject(
+ "native-window", new NativeWindowWrapper(mSurface));
}
mCodec->initiateSetup(format);
@@ -220,6 +224,7 @@
AString mURI;
bool mDecodeAudio;
sp<Surface> mSurface;
+ bool mRenderToSurface;
sp<ACodec> mCodec;
sp<MediaSource> mSource;
@@ -451,7 +456,7 @@
inBuffer->release();
inBuffer = NULL;
- // break; // Don't coalesce
+ break; // Don't coalesce
}
LOGV("coalesced %d input buffers", n);
@@ -479,6 +484,10 @@
sp<AMessage> reply;
CHECK(msg->findMessage("reply", &reply));
+ if (mRenderToSurface) {
+ reply->setInt32("render", 1);
+ }
+
reply->post();
}
@@ -491,7 +500,8 @@
fprintf(stderr, " -a(udio)\n");
fprintf(stderr,
- " -s(surface) Allocate output buffers on a surface.\n");
+ " -S(urface) Allocate output buffers on a surface.\n"
+ " -R(ender) Render surface-allocated buffers.\n");
}
int main(int argc, char **argv) {
@@ -499,18 +509,23 @@
bool decodeAudio = false;
bool useSurface = false;
+ bool renderToSurface = false;
int res;
- while ((res = getopt(argc, argv, "has")) >= 0) {
+ while ((res = getopt(argc, argv, "haSR")) >= 0) {
switch (res) {
case 'a':
decodeAudio = true;
break;
- case 's':
+ case 'S':
useSurface = true;
break;
+ case 'R':
+ renderToSurface = true;
+ break;
+
case '?':
case 'h':
default:
@@ -543,7 +558,6 @@
CHECK_EQ(composerClient->initCheck(), (status_t)OK);
control = composerClient->createSurface(
- getpid(),
String8("A Surface"),
0,
1280,
@@ -554,16 +568,18 @@
CHECK(control != NULL);
CHECK(control->isValid());
- CHECK_EQ(composerClient->openTransaction(), (status_t)OK);
+ SurfaceComposerClient::openGlobalTransaction();
CHECK_EQ(control->setLayer(30000), (status_t)OK);
CHECK_EQ(control->show(), (status_t)OK);
- CHECK_EQ(composerClient->closeTransaction(), (status_t)OK);
+ SurfaceComposerClient::closeGlobalTransaction();
surface = control->getSurface();
CHECK(surface != NULL);
}
- sp<Controller> controller = new Controller(argv[0], decodeAudio, surface);
+ sp<Controller> controller =
+ new Controller(argv[0], decodeAudio, surface, renderToSurface);
+
looper->registerHandler(controller);
controller->startAsync();
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index a875c3a..34f0a64 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -66,6 +66,7 @@
static long gMaxNumFrames; // 0 means decode all available.
static long gReproduceBug; // if not -1.
static bool gPreferSoftwareCodec;
+static bool gForceToUseHardwareCodec;
static bool gPlaybackAudio;
static bool gWriteMP4;
static bool gDisplayHistogram;
@@ -73,8 +74,6 @@
static sp<ANativeWindow> gSurface;
-#define USE_SURFACE_COMPOSER 0
-
static int64_t getNowUs() {
struct timeval tv;
gettimeofday(&tv, NULL);
@@ -144,10 +143,18 @@
if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_RAW, mime)) {
rawSource = source;
} else {
+ int flags = 0;
+ if (gPreferSoftwareCodec) {
+ flags |= OMXCodec::kPreferSoftwareCodecs;
+ }
+ if (gForceToUseHardwareCodec) {
+ CHECK(!gPreferSoftwareCodec);
+ flags |= OMXCodec::kHardwareCodecsOnly;
+ }
rawSource = OMXCodec::Create(
client->interface(), meta, false /* createEncoder */, source,
NULL /* matchComponentName */,
- gPreferSoftwareCodec ? OMXCodec::kPreferSoftwareCodecs : 0,
+ flags,
gSurface);
if (rawSource == NULL) {
@@ -379,13 +386,15 @@
sp<MediaSource> mSource;
StreamType mStreamType;
+ bool mSawFirstIDRFrame;
DISALLOW_EVIL_CONSTRUCTORS(DetectSyncSource);
};
DetectSyncSource::DetectSyncSource(const sp<MediaSource> &source)
: mSource(source),
- mStreamType(OTHER) {
+ mStreamType(OTHER),
+ mSawFirstIDRFrame(false) {
const char *mime;
CHECK(mSource->getFormat()->findCString(kKeyMIMEType, &mime));
@@ -401,6 +410,8 @@
}
status_t DetectSyncSource::start(MetaData *params) {
+ mSawFirstIDRFrame = false;
+
return mSource->start(params);
}
@@ -430,16 +441,30 @@
status_t DetectSyncSource::read(
MediaBuffer **buffer, const ReadOptions *options) {
- status_t err = mSource->read(buffer, options);
+ for (;;) {
+ status_t err = mSource->read(buffer, options);
- if (err != OK) {
- return err;
- }
+ if (err != OK) {
+ return err;
+ }
- if (mStreamType == AVC && isIDRFrame(*buffer)) {
- (*buffer)->meta_data()->setInt32(kKeyIsSyncFrame, true);
- } else {
- (*buffer)->meta_data()->setInt32(kKeyIsSyncFrame, true);
+ if (mStreamType == AVC) {
+ bool isIDR = isIDRFrame(*buffer);
+ (*buffer)->meta_data()->setInt32(kKeyIsSyncFrame, isIDR);
+ if (isIDR) {
+ mSawFirstIDRFrame = true;
+ }
+ } else {
+ (*buffer)->meta_data()->setInt32(kKeyIsSyncFrame, true);
+ }
+
+ if (mStreamType != AVC || mSawFirstIDRFrame) {
+ break;
+ }
+
+ // Ignore everything up to the first IDR frame.
+ (*buffer)->release();
+ *buffer = NULL;
}
return OK;
@@ -545,12 +570,14 @@
fprintf(stderr, " -p(rofiles) dump decoder profiles supported\n");
fprintf(stderr, " -t(humbnail) extract video thumbnail or album art\n");
fprintf(stderr, " -s(oftware) prefer software codec\n");
+ fprintf(stderr, " -r(hardware) force to use hardware codec\n");
fprintf(stderr, " -o playback audio\n");
fprintf(stderr, " -w(rite) filename (write to .mp4 file)\n");
fprintf(stderr, " -k seek test\n");
fprintf(stderr, " -x display a histogram of decoding times/fps "
"(video only)\n");
fprintf(stderr, " -S allocate buffers from a surface\n");
+ fprintf(stderr, " -T allocate buffers from a surface texture\n");
}
int main(int argc, char **argv) {
@@ -562,10 +589,12 @@
bool extractThumbnail = false;
bool seekTest = false;
bool useSurfaceAlloc = false;
+ bool useSurfaceTexAlloc = false;
gNumRepetitions = 1;
gMaxNumFrames = 0;
gReproduceBug = -1;
gPreferSoftwareCodec = false;
+ gForceToUseHardwareCodec = false;
gPlaybackAudio = false;
gWriteMP4 = false;
gDisplayHistogram = false;
@@ -575,7 +604,7 @@
sp<LiveSession> liveSession;
int res;
- while ((res = getopt(argc, argv, "han:lm:b:ptsow:kxS")) >= 0) {
+ while ((res = getopt(argc, argv, "han:lm:b:ptsrow:kxST")) >= 0) {
switch (res) {
case 'a':
{
@@ -636,6 +665,12 @@
break;
}
+ case 'r':
+ {
+ gForceToUseHardwareCodec = true;
+ break;
+ }
+
case 'o':
{
gPlaybackAudio = true;
@@ -660,6 +695,12 @@
break;
}
+ case 'T':
+ {
+ useSurfaceTexAlloc = true;
+ break;
+ }
+
case '?':
case 'h':
default:
@@ -695,12 +736,14 @@
for (int k = 0; k < argc; ++k) {
const char *filename = argv[k];
+ bool failed = true;
CHECK_EQ(retriever->setDataSource(filename), (status_t)OK);
sp<IMemory> mem =
retriever->getFrameAtTime(-1,
MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
if (mem != NULL) {
+ failed = false;
printf("getFrameAtTime(%s) => OK\n", filename);
VideoFrame *frame = (VideoFrame *)mem->pointer();
@@ -715,16 +758,21 @@
"/sdcard/out.jpg", bitmap,
SkImageEncoder::kJPEG_Type,
SkImageEncoder::kDefaultQuality));
- } else {
+ }
+
+ {
mem = retriever->extractAlbumArt();
if (mem != NULL) {
+ failed = false;
printf("extractAlbumArt(%s) => OK\n", filename);
- } else {
- printf("both getFrameAtTime and extractAlbumArt "
- "failed on file '%s'.\n", filename);
}
}
+
+ if (failed) {
+ printf("both getFrameAtTime and extractAlbumArt "
+ "failed on file '%s'.\n", filename);
+ }
}
return 0;
@@ -745,7 +793,9 @@
MEDIA_MIMETYPE_VIDEO_AVC, MEDIA_MIMETYPE_VIDEO_MPEG4,
MEDIA_MIMETYPE_VIDEO_H263, MEDIA_MIMETYPE_AUDIO_AAC,
MEDIA_MIMETYPE_AUDIO_AMR_NB, MEDIA_MIMETYPE_AUDIO_AMR_WB,
- MEDIA_MIMETYPE_AUDIO_MPEG
+ MEDIA_MIMETYPE_AUDIO_MPEG, MEDIA_MIMETYPE_AUDIO_G711_MLAW,
+ MEDIA_MIMETYPE_AUDIO_G711_ALAW, MEDIA_MIMETYPE_AUDIO_VORBIS,
+ MEDIA_MIMETYPE_VIDEO_VPX
};
for (size_t k = 0; k < sizeof(kMimeTypes) / sizeof(kMimeTypes[0]);
@@ -753,6 +803,7 @@
printf("type '%s':\n", kMimeTypes[k]);
Vector<CodecCapabilities> results;
+ // will retrieve hardware and software codecs
CHECK_EQ(QueryCodecs(omx, kMimeTypes[k],
true, // queryDecoders
&results), (status_t)OK);
@@ -794,41 +845,47 @@
for (List<IOMX::ComponentInfo>::iterator it = list.begin();
it != list.end(); ++it) {
- printf("%s\n", (*it).mName.string());
+ printf("%s\t Roles: ", (*it).mName.string());
+ for (List<String8>::iterator itRoles = (*it).mRoles.begin() ;
+ itRoles != (*it).mRoles.end() ; ++itRoles) {
+ printf("%s\t", (*itRoles).string());
+ }
+ printf("\n");
}
}
sp<SurfaceComposerClient> composerClient;
sp<SurfaceControl> control;
- if (useSurfaceAlloc && !audioOnly) {
-#if USE_SURFACE_COMPOSER
- composerClient = new SurfaceComposerClient;
- CHECK_EQ(composerClient->initCheck(), (status_t)OK);
+ if ((useSurfaceAlloc || useSurfaceTexAlloc) && !audioOnly) {
+ if (useSurfaceAlloc) {
+ composerClient = new SurfaceComposerClient;
+ CHECK_EQ(composerClient->initCheck(), (status_t)OK);
- control = composerClient->createSurface(
- getpid(),
- String8("A Surface"),
- 0,
- 1280,
- 800,
- PIXEL_FORMAT_RGB_565,
- 0);
+ control = composerClient->createSurface(
+ String8("A Surface"),
+ 0,
+ 1280,
+ 800,
+ PIXEL_FORMAT_RGB_565,
+ 0);
- CHECK(control != NULL);
- CHECK(control->isValid());
+ CHECK(control != NULL);
+ CHECK(control->isValid());
- CHECK_EQ(composerClient->openTransaction(), (status_t)OK);
- CHECK_EQ(control->setLayer(30000), (status_t)OK);
- CHECK_EQ(control->show(), (status_t)OK);
- CHECK_EQ(composerClient->closeTransaction(), (status_t)OK);
+ SurfaceComposerClient::openGlobalTransaction();
+ CHECK_EQ(control->setLayer(30000), (status_t)OK);
+ CHECK_EQ(control->show(), (status_t)OK);
+ SurfaceComposerClient::closeGlobalTransaction();
- gSurface = control->getSurface();
- CHECK(gSurface != NULL);
-#else
- sp<SurfaceTexture> texture = new SurfaceTexture(0 /* tex */);
- gSurface = new SurfaceTextureClient(texture);
-#endif
+ gSurface = control->getSurface();
+ CHECK(gSurface != NULL);
+ } else {
+ CHECK(useSurfaceTexAlloc);
+
+ sp<SurfaceTexture> texture = new SurfaceTexture(0 /* tex */);
+ gSurface = new SurfaceTextureClient(texture);
+ }
}
DataSource::RegisterDefaultSniffers();
@@ -921,6 +978,17 @@
fprintf(stderr, "could not create extractor.\n");
return -1;
}
+
+ sp<MetaData> meta = extractor->getMetaData();
+
+ if (meta != NULL) {
+ const char *mime;
+ CHECK(meta->findCString(kKeyMIMEType, &mime));
+
+ if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2TS)) {
+ syncInfoPresent = false;
+ }
+ }
}
size_t numTracks = extractor->countTracks();
@@ -1008,12 +1076,12 @@
}
}
- if (useSurfaceAlloc && !audioOnly) {
+ if ((useSurfaceAlloc || useSurfaceTexAlloc) && !audioOnly) {
gSurface.clear();
-#if USE_SURFACE_COMPOSER
- composerClient->dispose();
-#endif
+ if (useSurfaceAlloc) {
+ composerClient->dispose();
+ }
}
client.disconnect();
diff --git a/cmds/stagefright/stream.cpp b/cmds/stagefright/stream.cpp
index bb84bd1..ee91c29 100644
--- a/cmds/stagefright/stream.cpp
+++ b/cmds/stagefright/stream.cpp
@@ -20,6 +20,11 @@
#include <media/mediaplayer.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/DataSource.h>
+#include <media/stagefright/MPEG2TSWriter.h>
+#include <media/stagefright/MediaExtractor.h>
+#include <media/stagefright/MediaSource.h>
+#include <media/stagefright/MetaData.h>
#include <binder/IServiceManager.h>
#include <media/IMediaPlayerService.h>
@@ -31,7 +36,7 @@
using namespace android;
struct MyStreamSource : public BnStreamSource {
- // Caller retains ownership of fd.
+ // Object assumes ownership of fd.
MyStreamSource(int fd);
virtual void setListener(const sp<IStreamListener> &listener);
@@ -64,6 +69,8 @@
}
MyStreamSource::~MyStreamSource() {
+ close(mFd);
+ mFd = -1;
}
void MyStreamSource::setListener(const sp<IStreamListener> &listener) {
@@ -99,6 +106,143 @@
mListener->queueBuffer(index, n);
}
}
+////////////////////////////////////////////////////////////////////////////////
+
+struct MyConvertingStreamSource : public BnStreamSource {
+ MyConvertingStreamSource(const char *filename);
+
+ virtual void setListener(const sp<IStreamListener> &listener);
+ virtual void setBuffers(const Vector<sp<IMemory> > &buffers);
+
+ virtual void onBufferAvailable(size_t index);
+
+protected:
+ virtual ~MyConvertingStreamSource();
+
+private:
+ Mutex mLock;
+ Condition mCondition;
+
+ sp<IStreamListener> mListener;
+ Vector<sp<IMemory> > mBuffers;
+
+ sp<MPEG2TSWriter> mWriter;
+
+ ssize_t mCurrentBufferIndex;
+ size_t mCurrentBufferOffset;
+
+ List<size_t> mBufferQueue;
+
+ static ssize_t WriteDataWrapper(void *me, const void *data, size_t size);
+ ssize_t writeData(const void *data, size_t size);
+
+ DISALLOW_EVIL_CONSTRUCTORS(MyConvertingStreamSource);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+MyConvertingStreamSource::MyConvertingStreamSource(const char *filename)
+ : mCurrentBufferIndex(-1),
+ mCurrentBufferOffset(0) {
+ sp<DataSource> dataSource = DataSource::CreateFromURI(filename);
+ CHECK(dataSource != NULL);
+
+ sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource);
+ CHECK(extractor != NULL);
+
+ mWriter = new MPEG2TSWriter(
+ this, &MyConvertingStreamSource::WriteDataWrapper);
+
+ for (size_t i = 0; i < extractor->countTracks(); ++i) {
+ const sp<MetaData> &meta = extractor->getTrackMetaData(i);
+
+ const char *mime;
+ CHECK(meta->findCString(kKeyMIMEType, &mime));
+
+ if (strncasecmp("video/", mime, 6) && strncasecmp("audio/", mime, 6)) {
+ continue;
+ }
+
+ CHECK_EQ(mWriter->addSource(extractor->getTrack(i)), (status_t)OK);
+ }
+
+ CHECK_EQ(mWriter->start(), (status_t)OK);
+}
+
+MyConvertingStreamSource::~MyConvertingStreamSource() {
+}
+
+void MyConvertingStreamSource::setListener(
+ const sp<IStreamListener> &listener) {
+ mListener = listener;
+}
+
+void MyConvertingStreamSource::setBuffers(
+ const Vector<sp<IMemory> > &buffers) {
+ mBuffers = buffers;
+}
+
+ssize_t MyConvertingStreamSource::WriteDataWrapper(
+ void *me, const void *data, size_t size) {
+ return static_cast<MyConvertingStreamSource *>(me)->writeData(data, size);
+}
+
+ssize_t MyConvertingStreamSource::writeData(const void *data, size_t size) {
+ size_t totalWritten = 0;
+
+ while (size > 0) {
+ Mutex::Autolock autoLock(mLock);
+
+ if (mCurrentBufferIndex < 0) {
+ while (mBufferQueue.empty()) {
+ mCondition.wait(mLock);
+ }
+
+ mCurrentBufferIndex = *mBufferQueue.begin();
+ mCurrentBufferOffset = 0;
+
+ mBufferQueue.erase(mBufferQueue.begin());
+ }
+
+ sp<IMemory> mem = mBuffers.itemAt(mCurrentBufferIndex);
+
+ size_t copy = size;
+ if (copy + mCurrentBufferOffset > mem->size()) {
+ copy = mem->size() - mCurrentBufferOffset;
+ }
+
+ memcpy((uint8_t *)mem->pointer() + mCurrentBufferOffset, data, copy);
+ mCurrentBufferOffset += copy;
+
+ if (mCurrentBufferOffset == mem->size()) {
+ mListener->queueBuffer(mCurrentBufferIndex, mCurrentBufferOffset);
+ mCurrentBufferIndex = -1;
+ }
+
+ data = (const uint8_t *)data + copy;
+ size -= copy;
+
+ totalWritten += copy;
+ }
+
+ return (ssize_t)totalWritten;
+}
+
+void MyConvertingStreamSource::onBufferAvailable(size_t index) {
+ Mutex::Autolock autoLock(mLock);
+
+ mBufferQueue.push_back(index);
+ mCondition.signal();
+
+ if (mWriter->reachedEOS()) {
+ if (mCurrentBufferIndex >= 0) {
+ mListener->queueBuffer(mCurrentBufferIndex, mCurrentBufferOffset);
+ mCurrentBufferIndex = -1;
+ }
+
+ mListener->issueCommand(IStreamListener::EOS, false /* synchronous */);
+ }
+}
////////////////////////////////////////////////////////////////////////////////
@@ -107,7 +251,7 @@
: mEOS(false) {
}
- virtual void notify(int msg, int ext1, int ext2) {
+ virtual void notify(int msg, int ext1, int ext2, const Parcel *obj) {
Mutex::Autolock autoLock(mLock);
if (msg == MEDIA_ERROR || msg == MEDIA_PLAYBACK_COMPLETE) {
@@ -139,6 +283,8 @@
int main(int argc, char **argv) {
android::ProcessState::self()->startThreadPool();
+ DataSource::RegisterDefaultSniffers();
+
if (argc != 2) {
fprintf(stderr, "Usage: %s filename\n", argv[0]);
return 1;
@@ -149,7 +295,6 @@
sp<SurfaceControl> control =
composerClient->createSurface(
- getpid(),
String8("A Surface"),
0,
1280,
@@ -160,10 +305,10 @@
CHECK(control != NULL);
CHECK(control->isValid());
- CHECK_EQ(composerClient->openTransaction(), (status_t)OK);
+ SurfaceComposerClient::openGlobalTransaction();
CHECK_EQ(control->setLayer(30000), (status_t)OK);
CHECK_EQ(control->show(), (status_t)OK);
- CHECK_EQ(composerClient->closeTransaction(), (status_t)OK);
+ SurfaceComposerClient::closeGlobalTransaction();
sp<Surface> surface = control->getSurface();
CHECK(surface != NULL);
@@ -174,17 +319,28 @@
CHECK(service.get() != NULL);
- int fd = open(argv[1], O_RDONLY);
-
- if (fd < 0) {
- fprintf(stderr, "Failed to open file '%s'.", argv[1]);
- return 1;
- }
-
sp<MyClient> client = new MyClient;
+ sp<IStreamSource> source;
+
+ size_t len = strlen(argv[1]);
+ if (len >= 3 && !strcasecmp(".ts", &argv[1][len - 3])) {
+ int fd = open(argv[1], O_RDONLY);
+
+ if (fd < 0) {
+ fprintf(stderr, "Failed to open file '%s'.", argv[1]);
+ return 1;
+ }
+
+ source = new MyStreamSource(fd);
+ } else {
+ printf("Converting file to transport stream for streaming...\n");
+
+ source = new MyConvertingStreamSource(argv[1]);
+ }
+
sp<IMediaPlayer> player =
- service->create(getpid(), client, new MyStreamSource(fd), 0);
+ service->create(getpid(), client, source, 0);
if (player != NULL) {
player->setVideoSurface(surface);
@@ -197,9 +353,6 @@
fprintf(stderr, "failed to instantiate player.\n");
}
- close(fd);
- fd = -1;
-
composerClient->dispose();
return 0;
diff --git a/drm/common/DrmInfoEvent.cpp b/drm/common/DrmInfoEvent.cpp
index 8d115a8..27a5a2d 100644
--- a/drm/common/DrmInfoEvent.cpp
+++ b/drm/common/DrmInfoEvent.cpp
@@ -19,7 +19,7 @@
using namespace android;
-DrmInfoEvent::DrmInfoEvent(int uniqueId, int infoType, const String8& message)
+DrmInfoEvent::DrmInfoEvent(int uniqueId, int infoType, const String8 message)
: mUniqueId(uniqueId),
mInfoType(infoType),
mMessage(message) {
@@ -34,7 +34,7 @@
return mInfoType;
}
-const String8& DrmInfoEvent::getMessage() const {
+const String8 DrmInfoEvent::getMessage() const {
return mMessage;
}
diff --git a/drm/common/DrmSupportInfo.cpp b/drm/common/DrmSupportInfo.cpp
index c0bff0e..5400bdd 100644
--- a/drm/common/DrmSupportInfo.cpp
+++ b/drm/common/DrmSupportInfo.cpp
@@ -15,6 +15,7 @@
*/
#include <drm/DrmSupportInfo.h>
+#include <strings.h>
using namespace android;
@@ -42,6 +43,10 @@
}
bool DrmSupportInfo::isSupportedMimeType(const String8& mimeType) const {
+ if (String8("") == mimeType) {
+ return false;
+ }
+
for (unsigned int i = 0; i < mMimeTypeVector.size(); i++) {
const String8 item = mMimeTypeVector.itemAt(i);
@@ -152,4 +157,3 @@
mIndex++;
return value;
}
-
diff --git a/drm/common/IDrmManagerService.cpp b/drm/common/IDrmManagerService.cpp
index 346934b..0b76a36 100644
--- a/drm/common/IDrmManagerService.cpp
+++ b/drm/common/IDrmManagerService.cpp
@@ -37,7 +37,7 @@
using namespace android;
-static void writeDecrptHandleToParcelData(
+static void writeDecryptHandleToParcelData(
const DecryptHandle* handle, Parcel* data) {
data->writeInt32(handle->decryptId);
data->writeString8(handle->mimeType);
@@ -46,14 +46,14 @@
int size = handle->copyControlVector.size();
data->writeInt32(size);
- for(int i = 0; i < size; i++) {
+ for (int i = 0; i < size; i++) {
data->writeInt32(handle->copyControlVector.keyAt(i));
data->writeInt32(handle->copyControlVector.valueAt(i));
}
size = handle->extendedData.size();
data->writeInt32(size);
- for(int i = 0; i < size; i++) {
+ for (int i = 0; i < size; i++) {
data->writeString8(handle->extendedData.keyAt(i));
data->writeString8(handle->extendedData.valueAt(i));
}
@@ -77,14 +77,14 @@
handle->status = data.readInt32();
int size = data.readInt32();
- for (int i = 0; i < size; i ++) {
+ for (int i = 0; i < size; i++) {
DrmCopyControl key = (DrmCopyControl)data.readInt32();
int value = data.readInt32();
handle->copyControlVector.add(key, value);
}
size = data.readInt32();
- for (int i = 0; i < size; i ++) {
+ for (int i = 0; i < size; i++) {
String8 key = data.readString8();
String8 value = data.readString8();
handle->extendedData.add(key, value);
@@ -107,13 +107,14 @@
handle->decryptInfo = NULL;
}
handle->copyControlVector.clear();
+ handle->extendedData.clear();
}
-int BpDrmManagerService::addUniqueId(int uniqueId) {
+int BpDrmManagerService::addUniqueId(bool isNative) {
LOGV("add uniqueid");
Parcel data, reply;
data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
- data.writeInt32(uniqueId);
+ data.writeInt32(isNative);
remote()->transact(ADD_UNIQUEID, data, &reply);
return reply.readInt32();
}
@@ -416,7 +417,7 @@
data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
data.writeInt32(uniqueId);
- writeDecrptHandleToParcelData(decryptHandle, &data);
+ writeDecryptHandleToParcelData(decryptHandle, &data);
data.writeInt32(action);
data.writeInt32(static_cast< int>(reserve));
@@ -433,7 +434,7 @@
data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
data.writeInt32(uniqueId);
- writeDecrptHandleToParcelData(decryptHandle, &data);
+ writeDecryptHandleToParcelData(decryptHandle, &data);
data.writeInt32(playbackStatus);
data.writeInt64(position);
@@ -646,15 +647,10 @@
data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
data.writeInt32(uniqueId);
- writeDecrptHandleToParcelData(decryptHandle, &data);
+ writeDecryptHandleToParcelData(decryptHandle, &data);
remote()->transact(CLOSE_DECRYPT_SESSION, data, &reply);
- if (NULL != decryptHandle->decryptInfo) {
- LOGV("deleting decryptInfo");
- delete decryptHandle->decryptInfo; decryptHandle->decryptInfo = NULL;
- }
- delete decryptHandle; decryptHandle = NULL;
return reply.readInt32();
}
@@ -667,7 +663,7 @@
data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
data.writeInt32(uniqueId);
- writeDecrptHandleToParcelData(decryptHandle, &data);
+ writeDecryptHandleToParcelData(decryptHandle, &data);
data.writeInt32(decryptUnitId);
@@ -687,7 +683,7 @@
data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
data.writeInt32(uniqueId);
- writeDecrptHandleToParcelData(decryptHandle, &data);
+ writeDecryptHandleToParcelData(decryptHandle, &data);
data.writeInt32(decryptUnitId);
data.writeInt32((*decBuffer)->length);
@@ -720,7 +716,7 @@
data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
data.writeInt32(uniqueId);
- writeDecrptHandleToParcelData(decryptHandle, &data);
+ writeDecryptHandleToParcelData(decryptHandle, &data);
data.writeInt32(decryptUnitId);
@@ -738,7 +734,7 @@
data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
data.writeInt32(uniqueId);
- writeDecrptHandleToParcelData(decryptHandle, &data);
+ writeDecryptHandleToParcelData(decryptHandle, &data);
data.writeInt32(numBytes);
data.writeInt64(offset);
@@ -812,7 +808,9 @@
LOGV("BnDrmManagerService::onTransact :INSTALL_DRM_ENGINE");
CHECK_INTERFACE(IDrmManagerService, data, reply);
- status_t status = installDrmEngine(data.readInt32(), data.readString8());
+ const int uniqueId = data.readInt32();
+ const String8 engineFile = data.readString8();
+ status_t status = installDrmEngine(uniqueId, engineFile);
reply->writeInt32(status);
return DRM_NO_ERROR;
@@ -826,7 +824,8 @@
const int uniqueId = data.readInt32();
const String8 path = data.readString8();
- DrmConstraints* drmConstraints = getConstraints(uniqueId, &path, data.readInt32());
+ DrmConstraints* drmConstraints
+ = getConstraints(uniqueId, &path, data.readInt32());
if (NULL != drmConstraints) {
//Filling DRM Constraints contents
@@ -952,7 +951,9 @@
const int uniqueId = data.readInt32();
//Filling DRM info Request
- DrmInfoRequest* drmInfoRequest = new DrmInfoRequest(data.readInt32(), data.readString8());
+ const int infoType = data.readInt32();
+ const String8 mimeType = data.readString8();
+ DrmInfoRequest* drmInfoRequest = new DrmInfoRequest(infoType, mimeType);
const int size = data.readInt32();
for (int index = 0; index < size; ++index) {
@@ -1025,7 +1026,9 @@
LOGV("BnDrmManagerService::onTransact :GET_ORIGINAL_MIMETYPE");
CHECK_INTERFACE(IDrmManagerService, data, reply);
- const String8 originalMimeType = getOriginalMimeType(data.readInt32(), data.readString8());
+ const int uniqueId = data.readInt32();
+ const String8 path = data.readString8();
+ const String8 originalMimeType = getOriginalMimeType(uniqueId, path);
reply->writeString8(originalMimeType);
return DRM_NO_ERROR;
@@ -1036,8 +1039,10 @@
LOGV("BnDrmManagerService::onTransact :GET_DRM_OBJECT_TYPE");
CHECK_INTERFACE(IDrmManagerService, data, reply);
- const int drmObjectType
- = getDrmObjectType(data.readInt32(), data.readString8(), data.readString8());
+ const int uniqueId = data.readInt32();
+ const String8 path = data.readString8();
+ const String8 mimeType = data.readString8();
+ const int drmObjectType = getDrmObjectType(uniqueId, path, mimeType);
reply->writeInt32(drmObjectType);
return DRM_NO_ERROR;
@@ -1048,8 +1053,10 @@
LOGV("BnDrmManagerService::onTransact :CHECK_RIGHTS_STATUS");
CHECK_INTERFACE(IDrmManagerService, data, reply);
- const int result
- = checkRightsStatus(data.readInt32(), data.readString8(), data.readInt32());
+ const int uniqueId = data.readInt32();
+ const String8 path = data.readString8();
+ const int action = data.readInt32();
+ const int result = checkRightsStatus(uniqueId, path, action);
reply->writeInt32(result);
return DRM_NO_ERROR;
@@ -1065,9 +1072,10 @@
DecryptHandle handle;
readDecryptHandleFromParcelData(&handle, data);
+ const int action = data.readInt32();
+ const bool reserve = static_cast<bool>(data.readInt32());
const status_t status
- = consumeRights(uniqueId, &handle, data.readInt32(),
- static_cast<bool>(data.readInt32()));
+ = consumeRights(uniqueId, &handle, action, reserve);
reply->writeInt32(status);
clearDecryptHandle(&handle);
@@ -1084,8 +1092,10 @@
DecryptHandle handle;
readDecryptHandleFromParcelData(&handle, data);
+ const int playbackStatus = data.readInt32();
+ const int64_t position = data.readInt64();
const status_t status
- = setPlaybackStatus(uniqueId, &handle, data.readInt32(), data.readInt64());
+ = setPlaybackStatus(uniqueId, &handle, playbackStatus, position);
reply->writeInt32(status);
clearDecryptHandle(&handle);
@@ -1097,11 +1107,13 @@
LOGV("BnDrmManagerService::onTransact :VALIDATE_ACTION");
CHECK_INTERFACE(IDrmManagerService, data, reply);
- bool result = validateAction(
- data.readInt32(),
- data.readString8(),
- data.readInt32(),
- ActionDescription(data.readInt32(), data.readInt32()));
+ const int uniqueId = data.readInt32();
+ const String8 path = data.readString8();
+ const int action = data.readInt32();
+ const int outputType = data.readInt32();
+ const int configuration = data.readInt32();
+ bool result = validateAction(uniqueId, path, action,
+ ActionDescription(outputType, configuration));
reply->writeInt32(result);
return DRM_NO_ERROR;
@@ -1112,7 +1124,9 @@
LOGV("BnDrmManagerService::onTransact :REMOVE_RIGHTS");
CHECK_INTERFACE(IDrmManagerService, data, reply);
- const status_t status = removeRights(data.readInt32(), data.readString8());
+ int uniqueId = data.readInt32();
+ String8 path = data.readString8();
+ const status_t status = removeRights(uniqueId, path);
reply->writeInt32(status);
return DRM_NO_ERROR;
@@ -1134,7 +1148,9 @@
LOGV("BnDrmManagerService::onTransact :OPEN_CONVERT_SESSION");
CHECK_INTERFACE(IDrmManagerService, data, reply);
- const int convertId = openConvertSession(data.readInt32(), data.readString8());
+ const int uniqueId = data.readInt32();
+ const String8 mimeType = data.readString8();
+ const int convertId = openConvertSession(uniqueId, mimeType);
reply->writeInt32(convertId);
return DRM_NO_ERROR;
@@ -1180,8 +1196,10 @@
LOGV("BnDrmManagerService::onTransact :CLOSE_CONVERT_SESSION");
CHECK_INTERFACE(IDrmManagerService, data, reply);
- DrmConvertedStatus* drmConvertedStatus
- = closeConvertSession(data.readInt32(), data.readInt32());
+ const int uniqueId = data.readInt32();
+ const int convertId = data.readInt32();
+ DrmConvertedStatus* drmConvertedStatus
+ = closeConvertSession(uniqueId, convertId);
if (NULL != drmConvertedStatus) {
//Filling Drm Converted Ststus
@@ -1245,11 +1263,13 @@
const int uniqueId = data.readInt32();
const int fd = data.readFileDescriptor();
+ const off64_t offset = data.readInt64();
+ const off64_t length = data.readInt64();
DecryptHandle* handle
- = openDecryptSession(uniqueId, fd, data.readInt64(), data.readInt64());
+ = openDecryptSession(uniqueId, fd, offset, length);
if (NULL != handle) {
- writeDecrptHandleToParcelData(handle, reply);
+ writeDecryptHandleToParcelData(handle, reply);
clearDecryptHandle(handle);
delete handle; handle = NULL;
}
@@ -1267,7 +1287,7 @@
DecryptHandle* handle = openDecryptSession(uniqueId, uri.string());
if (NULL != handle) {
- writeDecrptHandleToParcelData(handle, reply);
+ writeDecryptHandleToParcelData(handle, reply);
clearDecryptHandle(handle);
delete handle; handle = NULL;
diff --git a/drm/drmserver/Android.mk b/drm/drmserver/Android.mk
index f94f9a3..fd417cb 100644
--- a/drm/drmserver/Android.mk
+++ b/drm/drmserver/Android.mk
@@ -22,14 +22,10 @@
DrmManagerService.cpp
LOCAL_SHARED_LIBRARIES := \
+ libmedia \
libutils \
- libbinder
-
-ifeq ($(TARGET_SIMULATOR),true)
- LOCAL_LDLIBS += -ldl
-else
- LOCAL_SHARED_LIBRARIES += libdl
-endif
+ libbinder \
+ libdl
LOCAL_STATIC_LIBRARIES := libdrmframeworkcommon
diff --git a/drm/drmserver/DrmManager.cpp b/drm/drmserver/DrmManager.cpp
index 1eee5f2..3e4fe8c 100644
--- a/drm/drmserver/DrmManager.cpp
+++ b/drm/drmserver/DrmManager.cpp
@@ -37,7 +37,6 @@
using namespace android;
-Vector<int> DrmManager::mUniqueIdVector;
const String8 DrmManager::EMPTY_STRING("");
DrmManager::DrmManager() :
@@ -50,32 +49,42 @@
}
-int DrmManager::addUniqueId(int uniqueId) {
+int DrmManager::addUniqueId(bool isNative) {
Mutex::Autolock _l(mLock);
- if (0 == uniqueId) {
- int temp = 0;
- bool foundUniqueId = false;
- srand(time(NULL));
- while (!foundUniqueId) {
- const int size = mUniqueIdVector.size();
- temp = rand() % 100;
+ int temp = 0;
+ bool foundUniqueId = false;
+ const int size = mUniqueIdVector.size();
+ const int uniqueIdRange = 0xfff;
+ int maxLoopTimes = (uniqueIdRange - 1) / 2;
+ srand(time(NULL));
- int index = 0;
- for (; index < size; ++index) {
- if (mUniqueIdVector.itemAt(index) == temp) {
- foundUniqueId = false;
- break;
- }
- }
- if (index == size) {
- foundUniqueId = true;
+ while (!foundUniqueId) {
+ temp = rand() & uniqueIdRange;
+
+ if (isNative) {
+ // set a flag to differentiate DrmManagerClient
+ // created from native side and java side
+ temp |= 0x1000;
+ }
+
+ int index = 0;
+ for (; index < size; ++index) {
+ if (mUniqueIdVector.itemAt(index) == temp) {
+ foundUniqueId = false;
+ break;
}
}
- uniqueId = temp;
+ if (index == size) {
+ foundUniqueId = true;
+ }
+
+ maxLoopTimes --;
+ LOG_FATAL_IF(maxLoopTimes <= 0, "cannot find an unique ID for this session");
}
- mUniqueIdVector.push(uniqueId);
- return uniqueId;
+
+ mUniqueIdVector.push(temp);
+ return temp;
}
void DrmManager::removeUniqueId(int uniqueId) {
@@ -102,6 +111,7 @@
DrmSupportInfo* info = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(0);
if (NULL != info) {
mSupportInfoToPlugInIdMap.add(*info, plugInPath);
+ delete info;
}
}
}
@@ -179,6 +189,7 @@
DrmSupportInfo* info = rDrmEngine.getSupportInfo(0);
mSupportInfoToPlugInIdMap.add(*info, absolutePath);
+ delete info;
return DRM_NO_ERROR;
}
diff --git a/drm/drmserver/DrmManagerService.cpp b/drm/drmserver/DrmManagerService.cpp
index 0901a44..7ebcac3 100644
--- a/drm/drmserver/DrmManagerService.cpp
+++ b/drm/drmserver/DrmManagerService.cpp
@@ -19,6 +19,7 @@
#include <utils/Log.h>
#include <private/android_filesystem_config.h>
+#include <media/MemoryLeakTrackUtil.h>
#include <errno.h>
#include <utils/threads.h>
@@ -77,8 +78,8 @@
delete mDrmManager; mDrmManager = NULL;
}
-int DrmManagerService::addUniqueId(int uniqueId) {
- return mDrmManager->addUniqueId(uniqueId);
+int DrmManagerService::addUniqueId(bool isNative) {
+ return mDrmManager->addUniqueId(isNative);
}
void DrmManagerService::removeUniqueId(int uniqueId) {
@@ -256,3 +257,31 @@
return mDrmManager->pread(uniqueId, decryptHandle, buffer, numBytes, offset);
}
+status_t DrmManagerService::dump(int fd, const Vector<String16>& args)
+{
+ const size_t SIZE = 256;
+ char buffer[SIZE];
+ String8 result;
+ if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
+ snprintf(buffer, SIZE, "Permission Denial: "
+ "can't dump DrmManagerService from pid=%d, uid=%d\n",
+ IPCThreadState::self()->getCallingPid(),
+ IPCThreadState::self()->getCallingUid());
+ result.append(buffer);
+ } else {
+#if DRM_MEMORY_LEAK_TRACK
+ bool dumpMem = false;
+ for (size_t i = 0; i < args.size(); i++) {
+ if (args[i] == String16("-m")) {
+ dumpMem = true;
+ }
+ }
+ if (dumpMem) {
+ dumpMemoryAddresses(fd);
+ }
+#endif
+ }
+ write(fd, result.string(), result.size());
+ return NO_ERROR;
+}
+
diff --git a/drm/libdrmframework/Android.mk b/drm/libdrmframework/Android.mk
index 99133ba..c534402 100644
--- a/drm/libdrmframework/Android.mk
+++ b/drm/libdrmframework/Android.mk
@@ -25,13 +25,8 @@
LOCAL_SHARED_LIBRARIES := \
libutils \
- libbinder
-
-ifeq ($(TARGET_SIMULATOR),true)
- LOCAL_LDLIBS += -ldl
-else
- LOCAL_SHARED_LIBRARIES += libdl
-endif
+ libbinder \
+ libdl
LOCAL_STATIC_LIBRARIES := \
libdrmframeworkcommon
@@ -40,7 +35,7 @@
$(TOP)/frameworks/base/drm/libdrmframework/include \
$(TOP)/frameworks/base/include
-LOCAL_PRELINK_MODULE := false
+
LOCAL_MODULE_TAGS := optional
diff --git a/drm/libdrmframework/DrmManagerClient.cpp b/drm/libdrmframework/DrmManagerClient.cpp
index c1f382a..c9c0d57 100644
--- a/drm/libdrmframework/DrmManagerClient.cpp
+++ b/drm/libdrmframework/DrmManagerClient.cpp
@@ -24,7 +24,7 @@
DrmManagerClient::DrmManagerClient():
mUniqueId(0), mDrmManagerClientImpl(NULL) {
- mDrmManagerClientImpl = DrmManagerClientImpl::create(&mUniqueId);
+ mDrmManagerClientImpl = DrmManagerClientImpl::create(&mUniqueId, true);
mDrmManagerClientImpl->addClient(mUniqueId);
}
@@ -76,12 +76,13 @@
return mDrmManagerClientImpl->checkRightsStatus(mUniqueId, path, action);
}
-status_t DrmManagerClient::consumeRights(DecryptHandle* decryptHandle, int action, bool reserve) {
+status_t DrmManagerClient::consumeRights(
+ sp<DecryptHandle> &decryptHandle, int action, bool reserve) {
return mDrmManagerClientImpl->consumeRights(mUniqueId, decryptHandle, action, reserve);
}
status_t DrmManagerClient::setPlaybackStatus(
- DecryptHandle* decryptHandle, int playbackStatus, int64_t position) {
+ sp<DecryptHandle> &decryptHandle, int playbackStatus, int64_t position) {
return mDrmManagerClientImpl
->setPlaybackStatus(mUniqueId, decryptHandle, playbackStatus, position);
}
@@ -115,37 +116,39 @@
return mDrmManagerClientImpl->getAllSupportInfo(mUniqueId, length, drmSupportInfoArray);
}
-DecryptHandle* DrmManagerClient::openDecryptSession(int fd, off64_t offset, off64_t length) {
+sp<DecryptHandle> DrmManagerClient::openDecryptSession(int fd, off64_t offset, off64_t length) {
return mDrmManagerClientImpl->openDecryptSession(mUniqueId, fd, offset, length);
}
-DecryptHandle* DrmManagerClient::openDecryptSession(const char* uri) {
+sp<DecryptHandle> DrmManagerClient::openDecryptSession(const char* uri) {
return mDrmManagerClientImpl->openDecryptSession(mUniqueId, uri);
}
-status_t DrmManagerClient::closeDecryptSession(DecryptHandle* decryptHandle) {
+status_t DrmManagerClient::closeDecryptSession(sp<DecryptHandle> &decryptHandle) {
return mDrmManagerClientImpl->closeDecryptSession(mUniqueId, decryptHandle);
}
status_t DrmManagerClient::initializeDecryptUnit(
- DecryptHandle* decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo) {
+ sp<DecryptHandle> &decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo) {
return mDrmManagerClientImpl->initializeDecryptUnit(
mUniqueId, decryptHandle, decryptUnitId, headerInfo);
}
status_t DrmManagerClient::decrypt(
- DecryptHandle* decryptHandle, int decryptUnitId,
- const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
+ sp<DecryptHandle> &decryptHandle, int decryptUnitId,
+ const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
return mDrmManagerClientImpl->decrypt(
mUniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer, IV);
}
-status_t DrmManagerClient::finalizeDecryptUnit(DecryptHandle* decryptHandle, int decryptUnitId) {
- return mDrmManagerClientImpl->finalizeDecryptUnit(mUniqueId, decryptHandle, decryptUnitId);
+status_t DrmManagerClient::finalizeDecryptUnit(
+ sp<DecryptHandle> &decryptHandle, int decryptUnitId) {
+ return mDrmManagerClientImpl->finalizeDecryptUnit(mUniqueId,
+ decryptHandle, decryptUnitId);
}
ssize_t DrmManagerClient::pread(
- DecryptHandle* decryptHandle, void* buffer, ssize_t numBytes, off64_t offset) {
+ sp<DecryptHandle> &decryptHandle, void* buffer, ssize_t numBytes, off64_t offset) {
return mDrmManagerClientImpl->pread(mUniqueId, decryptHandle, buffer, numBytes, offset);
}
diff --git a/drm/libdrmframework/DrmManagerClientImpl.cpp b/drm/libdrmframework/DrmManagerClientImpl.cpp
index 9c7fed3..67f58ca 100644
--- a/drm/libdrmframework/DrmManagerClientImpl.cpp
+++ b/drm/libdrmframework/DrmManagerClientImpl.cpp
@@ -33,13 +33,10 @@
sp<DrmManagerClientImpl::DeathNotifier> DrmManagerClientImpl::sDeathNotifier;
const String8 DrmManagerClientImpl::EMPTY_STRING("");
-DrmManagerClientImpl* DrmManagerClientImpl::create(int* pUniqueId) {
- if (0 == *pUniqueId) {
- int uniqueId = getDrmManagerService()->addUniqueId(*pUniqueId);
- *pUniqueId = uniqueId;
- } else {
- getDrmManagerService()->addUniqueId(*pUniqueId);
- }
+DrmManagerClientImpl* DrmManagerClientImpl::create(
+ int* pUniqueId, bool isNative) {
+ *pUniqueId = getDrmManagerService()->addUniqueId(isNative);
+
return new DrmManagerClientImpl();
}
@@ -81,14 +78,16 @@
}
status_t DrmManagerClientImpl::setOnInfoListener(
- int uniqueId, const sp<DrmManagerClient::OnInfoListener>& infoListener) {
+ int uniqueId,
+ const sp<DrmManagerClient::OnInfoListener>& infoListener) {
Mutex::Autolock _l(mLock);
mOnInfoListener = infoListener;
return getDrmManagerService()->setDrmServiceListener(uniqueId,
(NULL != infoListener.get()) ? this : NULL);
}
-status_t DrmManagerClientImpl::installDrmEngine(int uniqueId, const String8& drmEngineFile) {
+status_t DrmManagerClientImpl::installDrmEngine(
+ int uniqueId, const String8& drmEngineFile) {
status_t status = DRM_ERROR_UNKNOWN;
if (EMPTY_STRING != drmEngineFile) {
status = getDrmManagerService()->installDrmEngine(uniqueId, drmEngineFile);
@@ -100,7 +99,8 @@
int uniqueId, const String8* path, const int action) {
DrmConstraints *drmConstraints = NULL;
if ((NULL != path) && (EMPTY_STRING != *path)) {
- drmConstraints = getDrmManagerService()->getConstraints(uniqueId, path, action);
+ drmConstraints =
+ getDrmManagerService()->getConstraints(uniqueId, path, action);
}
return drmConstraints;
}
@@ -113,7 +113,8 @@
return drmMetadata;
}
-bool DrmManagerClientImpl::canHandle(int uniqueId, const String8& path, const String8& mimeType) {
+bool DrmManagerClientImpl::canHandle(
+ int uniqueId, const String8& path, const String8& mimeType) {
bool retCode = false;
if ((EMPTY_STRING != path) || (EMPTY_STRING != mimeType)) {
retCode = getDrmManagerService()->canHandle(uniqueId, path, mimeType);
@@ -121,7 +122,8 @@
return retCode;
}
-DrmInfoStatus* DrmManagerClientImpl::processDrmInfo(int uniqueId, const DrmInfo* drmInfo) {
+DrmInfoStatus* DrmManagerClientImpl::processDrmInfo(
+ int uniqueId, const DrmInfo* drmInfo) {
DrmInfoStatus *drmInfoStatus = NULL;
if (NULL != drmInfo) {
drmInfoStatus = getDrmManagerService()->processDrmInfo(uniqueId, drmInfo);
@@ -129,7 +131,8 @@
return drmInfoStatus;
}
-DrmInfo* DrmManagerClientImpl::acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest) {
+DrmInfo* DrmManagerClientImpl::acquireDrmInfo(
+ int uniqueId, const DrmInfoRequest* drmInfoRequest) {
DrmInfo* drmInfo = NULL;
if (NULL != drmInfoRequest) {
drmInfo = getDrmManagerService()->acquireDrmInfo(uniqueId, drmInfoRequest);
@@ -139,14 +142,12 @@
status_t DrmManagerClientImpl::saveRights(int uniqueId, const DrmRights& drmRights,
const String8& rightsPath, const String8& contentPath) {
- status_t status = DRM_ERROR_UNKNOWN;
- if (EMPTY_STRING != contentPath) {
- status = getDrmManagerService()->saveRights(uniqueId, drmRights, rightsPath, contentPath);
- }
- return status;
+ return getDrmManagerService()->saveRights(
+ uniqueId, drmRights, rightsPath, contentPath);
}
-String8 DrmManagerClientImpl::getOriginalMimeType(int uniqueId, const String8& path) {
+String8 DrmManagerClientImpl::getOriginalMimeType(
+ int uniqueId, const String8& path) {
String8 mimeType = EMPTY_STRING;
if (EMPTY_STRING != path) {
mimeType = getDrmManagerService()->getOriginalMimeType(uniqueId, path);
@@ -158,7 +159,8 @@
int uniqueId, const String8& path, const String8& mimeType) {
int drmOjectType = DrmObjectType::UNKNOWN;
if ((EMPTY_STRING != path) || (EMPTY_STRING != mimeType)) {
- drmOjectType = getDrmManagerService()->getDrmObjectType(uniqueId, path, mimeType);
+ drmOjectType =
+ getDrmManagerService()->getDrmObjectType(uniqueId, path, mimeType);
}
return drmOjectType;
}
@@ -167,35 +169,41 @@
int uniqueId, const String8& path, int action) {
int rightsStatus = RightsStatus::RIGHTS_INVALID;
if (EMPTY_STRING != path) {
- rightsStatus = getDrmManagerService()->checkRightsStatus(uniqueId, path, action);
+ rightsStatus =
+ getDrmManagerService()->checkRightsStatus(uniqueId, path, action);
}
return rightsStatus;
}
status_t DrmManagerClientImpl::consumeRights(
- int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) {
+ int uniqueId, sp<DecryptHandle> &decryptHandle,
+ int action, bool reserve) {
status_t status = DRM_ERROR_UNKNOWN;
- if (NULL != decryptHandle) {
- status = getDrmManagerService()->consumeRights(uniqueId, decryptHandle, action, reserve);
+ if (NULL != decryptHandle.get()) {
+ status = getDrmManagerService()->consumeRights(
+ uniqueId, decryptHandle.get(), action, reserve);
}
return status;
}
status_t DrmManagerClientImpl::setPlaybackStatus(
- int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position) {
+ int uniqueId, sp<DecryptHandle> &decryptHandle,
+ int playbackStatus, int64_t position) {
status_t status = DRM_ERROR_UNKNOWN;
- if (NULL != decryptHandle) {
+ if (NULL != decryptHandle.get()) {
status = getDrmManagerService()->setPlaybackStatus(
- uniqueId, decryptHandle, playbackStatus, position);
+ uniqueId, decryptHandle.get(), playbackStatus, position);
}
return status;
}
bool DrmManagerClientImpl::validateAction(
- int uniqueId, const String8& path, int action, const ActionDescription& description) {
+ int uniqueId, const String8& path,
+ int action, const ActionDescription& description) {
bool retCode = false;
if (EMPTY_STRING != path) {
- retCode = getDrmManagerService()->validateAction(uniqueId, path, action, description);
+ retCode = getDrmManagerService()->validateAction(
+ uniqueId, path, action, description);
}
return retCode;
}
@@ -212,7 +220,8 @@
return getDrmManagerService()->removeAllRights(uniqueId);
}
-int DrmManagerClientImpl::openConvertSession(int uniqueId, const String8& mimeType) {
+int DrmManagerClientImpl::openConvertSession(
+ int uniqueId, const String8& mimeType) {
int retCode = INVALID_VALUE;
if (EMPTY_STRING != mimeType) {
retCode = getDrmManagerService()->openConvertSession(uniqueId, mimeType);
@@ -224,12 +233,14 @@
int uniqueId, int convertId, const DrmBuffer* inputData) {
DrmConvertedStatus* drmConvertedStatus = NULL;
if (NULL != inputData) {
- drmConvertedStatus = getDrmManagerService()->convertData(uniqueId, convertId, inputData);
+ drmConvertedStatus =
+ getDrmManagerService()->convertData(uniqueId, convertId, inputData);
}
return drmConvertedStatus;
}
-DrmConvertedStatus* DrmManagerClientImpl::closeConvertSession(int uniqueId, int convertId) {
+DrmConvertedStatus* DrmManagerClientImpl::closeConvertSession(
+ int uniqueId, int convertId) {
return getDrmManagerService()->closeConvertSession(uniqueId, convertId);
}
@@ -237,17 +248,19 @@
int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray) {
status_t status = DRM_ERROR_UNKNOWN;
if ((NULL != drmSupportInfoArray) && (NULL != length)) {
- status = getDrmManagerService()->getAllSupportInfo(uniqueId, length, drmSupportInfoArray);
+ status = getDrmManagerService()->getAllSupportInfo(
+ uniqueId, length, drmSupportInfoArray);
}
return status;
}
-DecryptHandle* DrmManagerClientImpl::openDecryptSession(
+sp<DecryptHandle> DrmManagerClientImpl::openDecryptSession(
int uniqueId, int fd, off64_t offset, off64_t length) {
return getDrmManagerService()->openDecryptSession(uniqueId, fd, offset, length);
}
-DecryptHandle* DrmManagerClientImpl::openDecryptSession(int uniqueId, const char* uri) {
+sp<DecryptHandle> DrmManagerClientImpl::openDecryptSession(
+ int uniqueId, const char* uri) {
DecryptHandle* handle = NULL;
if (NULL != uri) {
handle = getDrmManagerService()->openDecryptSession(uniqueId, uri);
@@ -255,50 +268,57 @@
return handle;
}
-status_t DrmManagerClientImpl::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
+status_t DrmManagerClientImpl::closeDecryptSession(
+ int uniqueId, sp<DecryptHandle> &decryptHandle) {
status_t status = DRM_ERROR_UNKNOWN;
- if (NULL != decryptHandle) {
- status = getDrmManagerService()->closeDecryptSession( uniqueId, decryptHandle);
+ if (NULL != decryptHandle.get()) {
+ status = getDrmManagerService()->closeDecryptSession(
+ uniqueId, decryptHandle.get());
}
return status;
}
-status_t DrmManagerClientImpl::initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
- int decryptUnitId, const DrmBuffer* headerInfo) {
+status_t DrmManagerClientImpl::initializeDecryptUnit(
+ int uniqueId, sp<DecryptHandle> &decryptHandle,
+ int decryptUnitId, const DrmBuffer* headerInfo) {
status_t status = DRM_ERROR_UNKNOWN;
- if ((NULL != decryptHandle) && (NULL != headerInfo)) {
+ if ((NULL != decryptHandle.get()) && (NULL != headerInfo)) {
status = getDrmManagerService()->initializeDecryptUnit(
- uniqueId, decryptHandle, decryptUnitId, headerInfo);
+ uniqueId, decryptHandle.get(), decryptUnitId, headerInfo);
}
return status;
}
-status_t DrmManagerClientImpl::decrypt(int uniqueId, DecryptHandle* decryptHandle,
- int decryptUnitId, const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
+status_t DrmManagerClientImpl::decrypt(
+ int uniqueId, sp<DecryptHandle> &decryptHandle,
+ int decryptUnitId, const DrmBuffer* encBuffer,
+ DrmBuffer** decBuffer, DrmBuffer* IV) {
status_t status = DRM_ERROR_UNKNOWN;
- if ((NULL != decryptHandle) && (NULL != encBuffer)
+ if ((NULL != decryptHandle.get()) && (NULL != encBuffer)
&& (NULL != decBuffer) && (NULL != *decBuffer)) {
status = getDrmManagerService()->decrypt(
- uniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer, IV);
+ uniqueId, decryptHandle.get(), decryptUnitId,
+ encBuffer, decBuffer, IV);
}
return status;
}
status_t DrmManagerClientImpl::finalizeDecryptUnit(
- int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
+ int uniqueId, sp<DecryptHandle> &decryptHandle, int decryptUnitId) {
status_t status = DRM_ERROR_UNKNOWN;
- if (NULL != decryptHandle) {
- status
- = getDrmManagerService()->finalizeDecryptUnit(uniqueId, decryptHandle, decryptUnitId);
+ if (NULL != decryptHandle.get()) {
+ status = getDrmManagerService()->finalizeDecryptUnit(
+ uniqueId, decryptHandle.get(), decryptUnitId);
}
return status;
}
-ssize_t DrmManagerClientImpl::pread(int uniqueId, DecryptHandle* decryptHandle,
+ssize_t DrmManagerClientImpl::pread(int uniqueId, sp<DecryptHandle> &decryptHandle,
void* buffer, ssize_t numBytes, off64_t offset) {
ssize_t retCode = INVALID_VALUE;
- if ((NULL != decryptHandle) && (NULL != buffer) && (0 < numBytes)) {
- retCode = getDrmManagerService()->pread(uniqueId, decryptHandle, buffer, numBytes, offset);
+ if ((NULL != decryptHandle.get()) && (NULL != buffer) && (0 < numBytes)) {
+ retCode = getDrmManagerService()->pread(
+ uniqueId, decryptHandle.get(), buffer, numBytes, offset);
}
return retCode;
}
diff --git a/drm/libdrmframework/include/DrmManager.h b/drm/libdrmframework/include/DrmManager.h
index c7276f9..ac2b946 100644
--- a/drm/libdrmframework/include/DrmManager.h
+++ b/drm/libdrmframework/include/DrmManager.h
@@ -30,7 +30,6 @@
class DrmRegistrationInfo;
class DrmUnregistrationInfo;
class DrmRightsAcquisitionInfo;
-class DrmContentIds;
class DrmConstraints;
class DrmMetadata;
class DrmRights;
@@ -54,7 +53,7 @@
virtual ~DrmManager();
public:
- int addUniqueId(int uniqueId);
+ int addUniqueId(bool isNative);
void removeUniqueId(int uniqueId);
@@ -141,7 +140,7 @@
bool canHandle(int uniqueId, const String8& path);
private:
- static Vector<int> mUniqueIdVector;
+ Vector<int> mUniqueIdVector;
static const String8 EMPTY_STRING;
int mDecryptSessionId;
diff --git a/drm/libdrmframework/include/DrmManagerClientImpl.h b/drm/libdrmframework/include/DrmManagerClientImpl.h
index 429e4c3..e3338d9 100644
--- a/drm/libdrmframework/include/DrmManagerClientImpl.h
+++ b/drm/libdrmframework/include/DrmManagerClientImpl.h
@@ -38,7 +38,7 @@
DrmManagerClientImpl() { }
public:
- static DrmManagerClientImpl* create(int* pUniqueId);
+ static DrmManagerClientImpl* create(int* pUniqueId, bool isNative);
static void remove(int uniqueId);
@@ -189,7 +189,7 @@
* @return status_t
* Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
*/
- status_t consumeRights(int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve);
+ status_t consumeRights(int uniqueId, sp<DecryptHandle> &decryptHandle, int action, bool reserve);
/**
* Informs the DRM engine about the playback actions performed on the DRM files.
@@ -203,7 +203,7 @@
* Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
*/
status_t setPlaybackStatus(
- int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position);
+ int uniqueId, sp<DecryptHandle> &decryptHandle, int playbackStatus, int64_t position);
/**
* Validates whether an action on the DRM content is allowed or not.
@@ -303,7 +303,7 @@
* @return
* Handle for the decryption session
*/
- DecryptHandle* openDecryptSession(int uniqueId, int fd, off64_t offset, off64_t length);
+ sp<DecryptHandle> openDecryptSession(int uniqueId, int fd, off64_t offset, off64_t length);
/**
* Open the decrypt session to decrypt the given protected content
@@ -313,7 +313,7 @@
* @return
* Handle for the decryption session
*/
- DecryptHandle* openDecryptSession(int uniqueId, const char* uri);
+ sp<DecryptHandle> openDecryptSession(int uniqueId, const char* uri);
/**
* Close the decrypt session for the given handle
@@ -323,7 +323,7 @@
* @return status_t
* Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
*/
- status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
+ status_t closeDecryptSession(int uniqueId, sp<DecryptHandle> &decryptHandle);
/**
* Initialize decryption for the given unit of the protected content
@@ -335,7 +335,7 @@
* @return status_t
* Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
*/
- status_t initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+ status_t initializeDecryptUnit(int uniqueId, sp<DecryptHandle> &decryptHandle,
int decryptUnitId, const DrmBuffer* headerInfo);
/**
@@ -355,7 +355,7 @@
* DRM_ERROR_SESSION_NOT_OPENED, DRM_ERROR_DECRYPT_UNIT_NOT_INITIALIZED,
* DRM_ERROR_DECRYPT for failure.
*/
- status_t decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+ status_t decrypt(int uniqueId, sp<DecryptHandle> &decryptHandle, int decryptUnitId,
const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV);
/**
@@ -367,7 +367,7 @@
* @return status_t
* Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
*/
- status_t finalizeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId);
+ status_t finalizeDecryptUnit(int uniqueId, sp<DecryptHandle> &decryptHandle, int decryptUnitId);
/**
* Reads the specified number of bytes from an open DRM file.
@@ -380,7 +380,7 @@
*
* @return Number of bytes read. Returns -1 for Failure.
*/
- ssize_t pread(int uniqueId, DecryptHandle* decryptHandle,
+ ssize_t pread(int uniqueId, sp<DecryptHandle> &decryptHandle,
void* buffer, ssize_t numBytes, off64_t offset);
/**
diff --git a/drm/libdrmframework/include/DrmManagerService.h b/drm/libdrmframework/include/DrmManagerService.h
index d0a0db7..9cb5804 100644
--- a/drm/libdrmframework/include/DrmManagerService.h
+++ b/drm/libdrmframework/include/DrmManagerService.h
@@ -46,7 +46,7 @@
virtual ~DrmManagerService();
public:
- int addUniqueId(int uniqueId);
+ int addUniqueId(bool isNative);
void removeUniqueId(int uniqueId);
@@ -115,6 +115,8 @@
ssize_t pread(int uniqueId, DecryptHandle* decryptHandle,
void* buffer, ssize_t numBytes, off64_t offset);
+ virtual status_t dump(int fd, const Vector<String16>& args);
+
private:
DrmManager* mDrmManager;
};
diff --git a/drm/libdrmframework/include/IDrmManagerService.h b/drm/libdrmframework/include/IDrmManagerService.h
index 2424ea5..b9618bb 100644
--- a/drm/libdrmframework/include/IDrmManagerService.h
+++ b/drm/libdrmframework/include/IDrmManagerService.h
@@ -25,7 +25,6 @@
namespace android {
-class DrmContentIds;
class DrmConstraints;
class DrmMetadata;
class DrmRights;
@@ -82,7 +81,7 @@
DECLARE_META_INTERFACE(DrmManagerService);
public:
- virtual int addUniqueId(int uniqueId) = 0;
+ virtual int addUniqueId(bool isNative) = 0;
virtual void removeUniqueId(int uniqueId) = 0;
@@ -168,7 +167,7 @@
BpDrmManagerService(const sp<IBinder>& impl)
: BpInterface<IDrmManagerService>(impl) {}
- virtual int addUniqueId(int uniqueId);
+ virtual int addUniqueId(bool isNative);
virtual void removeUniqueId(int uniqueId);
diff --git a/drm/libdrmframework/include/PlugInManager.h b/drm/libdrmframework/include/PlugInManager.h
index 8029138..7bb143f 100644
--- a/drm/libdrmframework/include/PlugInManager.h
+++ b/drm/libdrmframework/include/PlugInManager.h
@@ -202,7 +202,7 @@
Vector<String8> getPlugInPathList(const String8& rsDirPath) {
Vector<String8> fileList;
DIR* pDir = opendir(rsDirPath.string());
- struct dirent* pEntry = new dirent();
+ struct dirent* pEntry;
while (NULL != pDir && NULL != (pEntry = readdir(pDir))) {
if (!isPlugIn(pEntry)) {
@@ -219,8 +219,6 @@
if (NULL != pDir) {
closedir(pDir);
}
- delete pEntry;
- pEntry = NULL;
return fileList;
}
diff --git a/drm/libdrmframework/plugins/common/include/DrmEngineBase.h b/drm/libdrmframework/plugins/common/include/DrmEngineBase.h
index b61e3d3..4a5afcf 100644
--- a/drm/libdrmframework/plugins/common/include/DrmEngineBase.h
+++ b/drm/libdrmframework/plugins/common/include/DrmEngineBase.h
@@ -143,7 +143,13 @@
* Register a callback to be invoked when the caller required to
* receive necessary information
*
- * @param[in] uniqueId Unique identifier for a session
+ * @param[in] uniqueId Unique identifier for a session. uniqueId is a random
+ * number generated in the DRM service. If the DrmManagerClient
+ * is created in native code, uniqueId will be a number ranged
+ * from 0x1000 to 0x1fff. If it comes from Java code, the uniqueId
+ * will be a number ranged from 0x00 to 0xfff. So bit 0x1000 in
+ * uniqueId could be used in DRM plugins to differentiate native
+ * OnInfoListener and Java OnInfoListener.
* @param[in] infoListener Listener
* @return status_t
* Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
diff --git a/drm/libdrmframework/plugins/common/include/IDrmEngine.h b/drm/libdrmframework/plugins/common/include/IDrmEngine.h
index d05c24f..77460f6 100644
--- a/drm/libdrmframework/plugins/common/include/IDrmEngine.h
+++ b/drm/libdrmframework/plugins/common/include/IDrmEngine.h
@@ -21,7 +21,6 @@
namespace android {
-class DrmContentIds;
class DrmConstraints;
class DrmMetadata;
class DrmRights;
diff --git a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.mk b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.mk
index 35fa734..e359dbd 100644
--- a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.mk
+++ b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.mk
@@ -50,7 +50,7 @@
libfwdlock-converter \
libfwdlock-decoder
-LOCAL_PRELINK_MODULE := false
+
LOCAL_C_INCLUDES += \
$(JNI_H_INCLUDE) \
diff --git a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/src/FwdLockEngine.cpp b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/src/FwdLockEngine.cpp
index 9453a20..e184545 100644
--- a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/src/FwdLockEngine.cpp
+++ b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/src/FwdLockEngine.cpp
@@ -472,11 +472,14 @@
} else {
LOG_VERBOSE("FwdLockEngine::onOpenDecryptSession Integrity Check failed for the fd");
FwdLockFile_detach(fileDesc);
- ::close(fileDesc);
delete decodeSession;
}
}
+ if (DRM_NO_ERROR != result && -1 < fileDesc) {
+ ::close(fileDesc);
+ }
+
LOG_VERBOSE("FwdLockEngine::onOpenDecryptSession Exit. result = %d", result);
return result;
@@ -526,6 +529,19 @@
}
}
+ if (NULL != decryptHandle) {
+ if (NULL != decryptHandle->decryptInfo) {
+ delete decryptHandle->decryptInfo;
+ decryptHandle->decryptInfo = NULL;
+ }
+
+ decryptHandle->copyControlVector.clear();
+ decryptHandle->extendedData.clear();
+
+ delete decryptHandle;
+ decryptHandle = NULL;
+ }
+
LOG_VERBOSE("FwdLockEngine::onCloseDecryptSession Exit");
return result;
}
diff --git a/drm/libdrmframework/plugins/passthru/Android.mk b/drm/libdrmframework/plugins/passthru/Android.mk
index 7856d37..d0d1439 100644
--- a/drm/libdrmframework/plugins/passthru/Android.mk
+++ b/drm/libdrmframework/plugins/passthru/Android.mk
@@ -24,15 +24,9 @@
LOCAL_STATIC_LIBRARIES := libdrmframeworkcommon
LOCAL_SHARED_LIBRARIES := \
- libutils
+ libutils \
+ libdl
-ifeq ($(TARGET_SIMULATOR),true)
- LOCAL_LDLIBS += -ldl
-else
- LOCAL_SHARED_LIBRARIES += libdl
-endif
-
-LOCAL_PRELINK_MODULE := false
LOCAL_C_INCLUDES += \
$(TOP)/frameworks/base/drm/libdrmframework/include \
diff --git a/include/camera/Camera.h b/include/camera/Camera.h
index f3c8f64..234e165 100644
--- a/include/camera/Camera.h
+++ b/include/camera/Camera.h
@@ -18,124 +18,32 @@
#define ANDROID_HARDWARE_CAMERA_H
#include <utils/Timers.h>
-#include <camera/ICameraClient.h>
#include <gui/ISurfaceTexture.h>
+#include <system/camera.h>
+#include <camera/ICameraClient.h>
+#include <camera/ICameraRecordingProxy.h>
+#include <camera/ICameraRecordingProxyListener.h>
namespace android {
-/*
- * A set of bit masks for specifying how the received preview frames are
- * handled before the previewCallback() call.
- *
- * The least significant 3 bits of an "int" value are used for this purpose:
- *
- * ..... 0 0 0
- * ^ ^ ^
- * | | |---------> determine whether the callback is enabled or not
- * | |-----------> determine whether the callback is one-shot or not
- * |-------------> determine whether the frame is copied out or not
- *
- * WARNING:
- * When a frame is sent directly without copying, it is the frame receiver's
- * responsiblity to make sure that the frame data won't get corrupted by
- * subsequent preview frames filled by the camera. This flag is recommended
- * only when copying out data brings significant performance price and the
- * handling/processing of the received frame data is always faster than
- * the preview frame rate so that data corruption won't occur.
- *
- * For instance,
- * 1. 0x00 disables the callback. In this case, copy out and one shot bits
- * are ignored.
- * 2. 0x01 enables a callback without copying out the received frames. A
- * typical use case is the Camcorder application to avoid making costly
- * frame copies.
- * 3. 0x05 is enabling a callback with frame copied out repeatedly. A typical
- * use case is the Camera application.
- * 4. 0x07 is enabling a callback with frame copied out only once. A typical use
- * case is the Barcode scanner application.
- */
-#define FRAME_CALLBACK_FLAG_ENABLE_MASK 0x01
-#define FRAME_CALLBACK_FLAG_ONE_SHOT_MASK 0x02
-#define FRAME_CALLBACK_FLAG_COPY_OUT_MASK 0x04
-
-// Typical use cases
-#define FRAME_CALLBACK_FLAG_NOOP 0x00
-#define FRAME_CALLBACK_FLAG_CAMCORDER 0x01
-#define FRAME_CALLBACK_FLAG_CAMERA 0x05
-#define FRAME_CALLBACK_FLAG_BARCODE_SCANNER 0x07
-
-// msgType in notifyCallback and dataCallback functions
-enum {
- CAMERA_MSG_ERROR = 0x0001,
- CAMERA_MSG_SHUTTER = 0x0002,
- CAMERA_MSG_FOCUS = 0x0004,
- CAMERA_MSG_ZOOM = 0x0008,
- CAMERA_MSG_PREVIEW_FRAME = 0x0010,
- CAMERA_MSG_VIDEO_FRAME = 0x0020,
- CAMERA_MSG_POSTVIEW_FRAME = 0x0040,
- CAMERA_MSG_RAW_IMAGE = 0x0080,
- CAMERA_MSG_COMPRESSED_IMAGE = 0x0100,
- CAMERA_MSG_RAW_IMAGE_NOTIFY = 0x0200,
- CAMERA_MSG_ALL_MSGS = 0xFFFF
-};
-
-// cmdType in sendCommand functions
-enum {
- CAMERA_CMD_START_SMOOTH_ZOOM = 1,
- CAMERA_CMD_STOP_SMOOTH_ZOOM = 2,
- // Set the clockwise rotation of preview display (setPreviewDisplay) in
- // degrees. This affects the preview frames and the picture displayed after
- // snapshot. This method is useful for portrait mode applications. Note that
- // preview display of front-facing cameras is flipped horizontally before
- // the rotation, that is, the image is reflected along the central vertical
- // axis of the camera sensor. So the users can see themselves as looking
- // into a mirror.
- //
- // This does not affect the order of byte array of CAMERA_MSG_PREVIEW_FRAME,
- // CAMERA_MSG_VIDEO_FRAME, CAMERA_MSG_POSTVIEW_FRAME, CAMERA_MSG_RAW_IMAGE,
- // or CAMERA_MSG_COMPRESSED_IMAGE. This is not allowed to be set during
- // preview.
- CAMERA_CMD_SET_DISPLAY_ORIENTATION = 3,
-
- // cmdType to disable/enable shutter sound.
- // In sendCommand passing arg1 = 0 will disable,
- // while passing arg1 = 1 will enable the shutter sound.
- CAMERA_CMD_ENABLE_SHUTTER_SOUND = 4,
-
- // cmdType to play recording sound.
- CAMERA_CMD_PLAY_RECORDING_SOUND = 5,
-};
-
-// camera fatal errors
-enum {
- CAMERA_ERROR_UNKNOWN = 1,
- CAMERA_ERROR_SERVER_DIED = 100
-};
-
-enum {
- CAMERA_FACING_BACK = 0, /* The facing of the camera is opposite to that of the screen. */
- CAMERA_FACING_FRONT = 1 /* The facing of the camera is the same as that of the screen. */
-};
-
struct CameraInfo {
-
/**
- * The direction that the camera faces to. It should be
- * CAMERA_FACING_BACK or CAMERA_FACING_FRONT.
+ * The direction that the camera faces to. It should be CAMERA_FACING_BACK
+ * or CAMERA_FACING_FRONT.
*/
int facing;
/**
* The orientation of the camera image. The value is the angle that the
- * camera image needs to be rotated clockwise so it shows correctly on
- * the display in its natural orientation. It should be 0, 90, 180, or 270.
+ * camera image needs to be rotated clockwise so it shows correctly on the
+ * display in its natural orientation. It should be 0, 90, 180, or 270.
*
* For example, suppose a device has a naturally tall screen. The
* back-facing camera sensor is mounted in landscape. You are looking at
* the screen. If the top side of the camera sensor is aligned with the
* right edge of the screen in natural orientation, the value should be
- * 90. If the top side of a front-facing camera sensor is aligned with
- * the right of the screen, the value should be 270.
+ * 90. If the top side of a front-facing camera sensor is aligned with the
+ * right of the screen, the value should be 270.
*/
int orientation;
};
@@ -151,7 +59,8 @@
{
public:
virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2) = 0;
- virtual void postData(int32_t msgType, const sp<IMemory>& dataPtr) = 0;
+ virtual void postData(int32_t msgType, const sp<IMemory>& dataPtr,
+ camera_frame_metadata_t *metadata) = 0;
virtual void postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) = 0;
};
@@ -164,7 +73,7 @@
static status_t getCameraInfo(int cameraId,
struct CameraInfo* cameraInfo);
static sp<Camera> connect(int cameraId);
- ~Camera();
+ virtual ~Camera();
void init();
status_t reconnect();
@@ -219,25 +128,37 @@
// send command to camera driver
status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2);
- // return the total number of available video buffers.
- int32_t getNumberOfVideoBuffers() const;
-
- // return the individual video buffer corresponding to the given index.
- sp<IMemory> getVideoBuffer(int32_t index) const;
-
// tell camera hal to store meta data or real YUV in video buffers.
status_t storeMetaDataInBuffers(bool enabled);
void setListener(const sp<CameraListener>& listener);
+ void setRecordingProxyListener(const sp<ICameraRecordingProxyListener>& listener);
void setPreviewCallbackFlags(int preview_callback_flag);
+ sp<ICameraRecordingProxy> getRecordingProxy();
+
// ICameraClient interface
virtual void notifyCallback(int32_t msgType, int32_t ext, int32_t ext2);
- virtual void dataCallback(int32_t msgType, const sp<IMemory>& dataPtr);
+ virtual void dataCallback(int32_t msgType, const sp<IMemory>& dataPtr,
+ camera_frame_metadata_t *metadata);
virtual void dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);
sp<ICamera> remote();
+ class RecordingProxy : public BnCameraRecordingProxy
+ {
+ public:
+ RecordingProxy(const sp<Camera>& camera);
+
+ // ICameraRecordingProxy interface
+ virtual status_t startRecording(const sp<ICameraRecordingProxyListener>& listener);
+ virtual void stopRecording();
+ virtual void releaseRecordingFrame(const sp<IMemory>& mem);
+
+ private:
+ sp<Camera> mCamera;
+ };
+
private:
Camera();
Camera(const Camera&);
@@ -262,12 +183,12 @@
status_t mStatus;
sp<CameraListener> mListener;
+ sp<ICameraRecordingProxyListener> mRecordingProxyListener;
friend class DeathNotifier;
static Mutex mLock;
static sp<ICameraService> mCameraService;
-
};
}; // namespace android
diff --git a/include/camera/CameraHardwareInterface.h b/include/camera/CameraHardwareInterface.h
deleted file mode 100644
index 86bd849..0000000
--- a/include/camera/CameraHardwareInterface.h
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * Copyright (C) 2008 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 ANDROID_HARDWARE_CAMERA_HARDWARE_INTERFACE_H
-#define ANDROID_HARDWARE_CAMERA_HARDWARE_INTERFACE_H
-
-#include <binder/IMemory.h>
-#include <ui/egl/android_natives.h>
-#include <utils/RefBase.h>
-#include <surfaceflinger/ISurface.h>
-#include <ui/android_native_buffer.h>
-#include <ui/GraphicBuffer.h>
-#include <camera/Camera.h>
-#include <camera/CameraParameters.h>
-
-namespace android {
-
-/**
- * The size of image for display.
- */
-typedef struct image_rect_struct
-{
- uint32_t width; /* Image width */
- uint32_t height; /* Image height */
-} image_rect_type;
-
-
-typedef void (*notify_callback)(int32_t msgType,
- int32_t ext1,
- int32_t ext2,
- void* user);
-
-typedef void (*data_callback)(int32_t msgType,
- const sp<IMemory>& dataPtr,
- void* user);
-
-typedef void (*data_callback_timestamp)(nsecs_t timestamp,
- int32_t msgType,
- const sp<IMemory>& dataPtr,
- void* user);
-
-/**
- * CameraHardwareInterface.h defines the interface to the
- * camera hardware abstraction layer, used for setting and getting
- * parameters, live previewing, and taking pictures.
- *
- * It is a referenced counted interface with RefBase as its base class.
- * CameraService calls openCameraHardware() to retrieve a strong pointer to the
- * instance of this interface and may be called multiple times. The
- * following steps describe a typical sequence:
- *
- * -# After CameraService calls openCameraHardware(), getParameters() and
- * setParameters() are used to initialize the camera instance.
- * CameraService calls getPreviewHeap() to establish access to the
- * preview heap so it can be registered with SurfaceFlinger for
- * efficient display updating while in preview mode.
- * -# startPreview() is called. The camera instance then periodically
- * sends the message CAMERA_MSG_PREVIEW_FRAME (if enabled) each time
- * a new preview frame is available. If data callback code needs to use
- * this memory after returning, it must copy the data.
- *
- * Prior to taking a picture, CameraService calls autofocus(). When auto
- * focusing has completed, the camera instance sends a CAMERA_MSG_FOCUS notification,
- * which informs the application whether focusing was successful. The camera instance
- * only sends this message once and it is up to the application to call autoFocus()
- * again if refocusing is desired.
- *
- * CameraService calls takePicture() to request the camera instance take a
- * picture. At this point, if a shutter, postview, raw, and/or compressed callback
- * is desired, the corresponding message must be enabled. As with CAMERA_MSG_PREVIEW_FRAME,
- * any memory provided in a data callback must be copied if it's needed after returning.
- */
-class CameraHardwareInterface : public virtual RefBase {
-public:
- virtual ~CameraHardwareInterface() { }
-
- /** Set the ANativeWindow to which preview frames are sent */
- virtual status_t setPreviewWindow(const sp<ANativeWindow>& buf) = 0;
-
- /** Return the IMemoryHeap for the raw image heap */
- virtual sp<IMemoryHeap> getRawHeap() const = 0;
-
- /** Set the notification and data callbacks */
- virtual void setCallbacks(notify_callback notify_cb,
- data_callback data_cb,
- data_callback_timestamp data_cb_timestamp,
- void* user) = 0;
-
- /**
- * The following three functions all take a msgtype,
- * which is a bitmask of the messages defined in
- * include/ui/Camera.h
- */
-
- /**
- * Enable a message, or set of messages.
- */
- virtual void enableMsgType(int32_t msgType) = 0;
-
- /**
- * Disable a message, or a set of messages.
- *
- * Once received a call to disableMsgType(CAMERA_MSG_VIDEO_FRAME), camera hal
- * should not rely on its client to call releaseRecordingFrame() to release
- * video recording frames sent out by the cameral hal before and after the
- * disableMsgType(CAMERA_MSG_VIDEO_FRAME) call. Camera hal clients must not
- * modify/access any video recording frame after calling
- * disableMsgType(CAMERA_MSG_VIDEO_FRAME).
- */
- virtual void disableMsgType(int32_t msgType) = 0;
-
- /**
- * Query whether a message, or a set of messages, is enabled.
- * Note that this is operates as an AND, if any of the messages
- * queried are off, this will return false.
- */
- virtual bool msgTypeEnabled(int32_t msgType) = 0;
-
- /**
- * Start preview mode.
- */
- virtual status_t startPreview() = 0;
-
- /**
- * Stop a previously started preview.
- */
- virtual void stopPreview() = 0;
-
- /**
- * Returns true if preview is enabled.
- */
- virtual bool previewEnabled() = 0;
-
- /**
- * Retrieve the total number of available buffers from camera hal for passing
- * video frame data in a recording session. Must be called again if a new
- * recording session is started.
- *
- * This method should be called after startRecording(), since
- * the some camera hal may choose to allocate the video buffers only after
- * recording is started.
- *
- * Some camera hal may not implement this method, and 0 can be returned to
- * indicate that this feature is not available.
- *
- * @return the number of video buffers that camera hal makes available.
- * Zero (0) is returned to indicate that camera hal does not support
- * this feature.
- */
- virtual int32_t getNumberOfVideoBuffers() const { return 0; }
-
- /**
- * Retrieve the video buffer corresponding to the given index in a
- * recording session. Must be called again if a new recording session
- * is started.
- *
- * It allows a client to retrieve all video buffers that camera hal makes
- * available to passing video frame data by calling this method with all
- * valid index values. The valid index value ranges from 0 to n, where
- * n = getNumberOfVideoBuffers() - 1. With an index outside of the valid
- * range, 0 must be returned. This method should be called after
- * startRecording().
- *
- * The video buffers should NOT be modified/released by camera hal
- * until stopRecording() is called and all outstanding video buffers
- * previously sent out via CAMERA_MSG_VIDEO_FRAME have been released
- * via releaseVideoBuffer().
- *
- * @param index an index to retrieve the corresponding video buffer.
- *
- * @return the video buffer corresponding to the given index.
- */
- virtual sp<IMemory> getVideoBuffer(int32_t index) const { return 0; }
-
- /**
- * Request the camera hal to store meta data or real YUV data in
- * the video buffers send out via CAMERA_MSG_VIDEO_FRRAME for a
- * recording session. If it is not called, the default camera
- * hal behavior is to store real YUV data in the video buffers.
- *
- * This method should be called before startRecording() in order
- * to be effective.
- *
- * If meta data is stored in the video buffers, it is up to the
- * receiver of the video buffers to interpret the contents and
- * to find the actual frame data with the help of the meta data
- * in the buffer. How this is done is outside of the scope of
- * this method.
- *
- * Some camera hal may not support storing meta data in the video
- * buffers, but all camera hal should support storing real YUV data
- * in the video buffers. If the camera hal does not support storing
- * the meta data in the video buffers when it is requested to do
- * do, INVALID_OPERATION must be returned. It is very useful for
- * the camera hal to pass meta data rather than the actual frame
- * data directly to the video encoder, since the amount of the
- * uncompressed frame data can be very large if video size is large.
- *
- * @param enable if true to instruct the camera hal to store
- * meta data in the video buffers; false to instruct
- * the camera hal to store real YUV data in the video
- * buffers.
- *
- * @return OK on success.
- */
- virtual status_t storeMetaDataInBuffers(bool enable) {
- return enable? INVALID_OPERATION: OK;
- }
-
- /**
- * Start record mode. When a record image is available a CAMERA_MSG_VIDEO_FRAME
- * message is sent with the corresponding frame. Every record frame must be released
- * by a cameral hal client via releaseRecordingFrame() before the client calls
- * disableMsgType(CAMERA_MSG_VIDEO_FRAME). After the client calls
- * disableMsgType(CAMERA_MSG_VIDEO_FRAME), it is camera hal's responsibility
- * to manage the life-cycle of the video recording frames, and the client must
- * not modify/access any video recording frames.
- */
- virtual status_t startRecording() = 0;
-
- /**
- * Stop a previously started recording.
- */
- virtual void stopRecording() = 0;
-
- /**
- * Returns true if recording is enabled.
- */
- virtual bool recordingEnabled() = 0;
-
- /**
- * Release a record frame previously returned by CAMERA_MSG_VIDEO_FRAME.
- *
- * It is camera hal client's responsibility to release video recording
- * frames sent out by the camera hal before the camera hal receives
- * a call to disableMsgType(CAMERA_MSG_VIDEO_FRAME). After it receives
- * the call to disableMsgType(CAMERA_MSG_VIDEO_FRAME), it is camera hal's
- * responsibility of managing the life-cycle of the video recording
- * frames.
- */
- virtual void releaseRecordingFrame(const sp<IMemory>& mem) = 0;
-
- /**
- * Start auto focus, the notification callback routine is called
- * with CAMERA_MSG_FOCUS once when focusing is complete. autoFocus()
- * will be called again if another auto focus is needed.
- */
- virtual status_t autoFocus() = 0;
-
- /**
- * Cancels auto-focus function. If the auto-focus is still in progress,
- * this function will cancel it. Whether the auto-focus is in progress
- * or not, this function will return the focus position to the default.
- * If the camera does not support auto-focus, this is a no-op.
- */
- virtual status_t cancelAutoFocus() = 0;
-
- /**
- * Take a picture.
- */
- virtual status_t takePicture() = 0;
-
- /**
- * Cancel a picture that was started with takePicture. Calling this
- * method when no picture is being taken is a no-op.
- */
- virtual status_t cancelPicture() = 0;
-
- /**
- * Set the camera parameters. This returns BAD_VALUE if any parameter is
- * invalid or not supported. */
- virtual status_t setParameters(const CameraParameters& params) = 0;
-
- /** Return the camera parameters. */
- virtual CameraParameters getParameters() const = 0;
-
- /**
- * Send command to camera driver.
- */
- virtual status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) = 0;
-
- /**
- * Release the hardware resources owned by this object. Note that this is
- * *not* done in the destructor.
- */
- virtual void release() = 0;
-
- /**
- * Dump state of the camera hardware
- */
- virtual status_t dump(int fd, const Vector<String16>& args) const = 0;
-};
-
-/**
- * The functions need to be provided by the camera HAL.
- *
- * If getNumberOfCameras() returns N, the valid cameraId for getCameraInfo()
- * and openCameraHardware() is 0 to N-1.
- */
-extern "C" int HAL_getNumberOfCameras();
-extern "C" void HAL_getCameraInfo(int cameraId, struct CameraInfo* cameraInfo);
-/* HAL should return NULL if it fails to open camera hardware. */
-extern "C" sp<CameraHardwareInterface> HAL_openCameraHardware(int cameraId);
-
-}; // namespace android
-
-#endif
diff --git a/include/camera/CameraParameters.h b/include/camera/CameraParameters.h
index da2f049..b661496 100644
--- a/include/camera/CameraParameters.h
+++ b/include/camera/CameraParameters.h
@@ -247,6 +247,45 @@
// Supported focus modes.
// Example value: "auto,macro,fixed". Read only.
static const char KEY_SUPPORTED_FOCUS_MODES[];
+ // The maximum number of focus areas supported. This is the maximum length
+ // of KEY_FOCUS_AREAS.
+ // Example value: "0" or "2". Read only.
+ static const char KEY_MAX_NUM_FOCUS_AREAS[];
+ // Current focus areas.
+ //
+ // Before accessing this parameter, apps should check
+ // KEY_MAX_NUM_FOCUS_AREAS first to know the maximum number of focus areas
+ // first. If the value is 0, focus area is not supported.
+ //
+ // Each focus area is a five-element int array. The first four elements are
+ // the rectangle of the area (left, top, right, bottom). The direction is
+ // relative to the sensor orientation, that is, what the sensor sees. The
+ // direction is not affected by the rotation or mirroring of
+ // CAMERA_CMD_SET_DISPLAY_ORIENTATION. Coordinates range from -1000 to 1000.
+ // (-1000,-1000) is the upper left point. (1000, 1000) is the lower right
+ // point. The width and height of focus areas cannot be 0 or negative.
+ //
+ // The fifth element is the weight. Values for weight must range from 1 to
+ // 1000. The weight should be interpreted as a per-pixel weight - all
+ // pixels in the area have the specified weight. This means a small area
+ // with the same weight as a larger area will have less influence on the
+ // focusing than the larger area. Focus areas can partially overlap and the
+ // driver will add the weights in the overlap region.
+ //
+ // A special case of single focus area (0,0,0,0,0) means driver to decide
+ // the focus area. For example, the driver may use more signals to decide
+ // focus areas and change them dynamically. Apps can set (0,0,0,0,0) if they
+ // want the driver to decide focus areas.
+ //
+ // Focus areas are relative to the current field of view (KEY_ZOOM). No
+ // matter what the zoom level is, (-1000,-1000) represents the top of the
+ // currently visible camera frame. The focus area cannot be set to be
+ // outside the current field of view, even when using zoom.
+ //
+ // Focus area only has effect if the current focus mode is FOCUS_MODE_AUTO,
+ // FOCUS_MODE_MACRO, or FOCUS_MODE_CONTINOUS_VIDEO.
+ // Example value: "(-10,-10,0,0,300),(0,0,10,10,700)". Read/write.
+ static const char KEY_FOCUS_AREAS[];
// Focal length in millimeter.
// Example value: "4.31". Read only.
static const char KEY_FOCAL_LENGTH[];
@@ -270,6 +309,94 @@
// 0.3333, EV is -2.
// Example value: "0.333333333" or "0.5". Read only.
static const char KEY_EXPOSURE_COMPENSATION_STEP[];
+ // The state of the auto-exposure lock. "true" means that
+ // auto-exposure is locked to its current value and will not
+ // change. "false" means the auto-exposure routine is free to
+ // change exposure values. If auto-exposure is already locked,
+ // setting this to true again has no effect (the driver will not
+ // recalculate exposure values). Changing exposure compensation
+ // settings will still affect the exposure settings while
+ // auto-exposure is locked. Stopping preview or taking a still
+ // image will release the lock. However, the lock can be
+ // re-enabled prior to preview being re-started, to keep the
+ // exposure values from the previous lock. In conjunction with
+ // exposure compensation, this allows for capturing multi-exposure
+ // brackets with known relative exposure values. Locking
+ // auto-exposure after open but before the first call to
+ // startPreview may result in severely over- or under-exposed
+ // images. The driver may independently enable the AE lock after
+ // auto-focus completes. If it does so, this key must have its
+ // value updated to reflect the lock's existence. Applications are
+ // free to release such a lock, to re-enable AE without restarting
+ // preview.
+ static const char KEY_AUTO_EXPOSURE_LOCK[];
+ // Whether locking the auto-exposure is supported. "true" means it is, and
+ // "false" or this key not existing means it is not supported.
+ static const char KEY_AUTO_EXPOSURE_LOCK_SUPPORTED[];
+ // The state of the auto-white balance lock. "true" means that
+ // auto-white balance is locked to its current value and will not
+ // change. "false" means the auto-white balance routine is free to
+ // change white balance values. If auto-white balance is already
+ // locked, setting this to true again has no effect (the driver
+ // will not recalculate white balance values). Stopping preview or
+ // taking a still image will release the lock. However, the lock
+ // can be re-enabled prior to preview being re-started, to keep
+ // the white balance values from the previous lock. In conjunction
+ // with exposure compensation, this allows for capturing
+ // multi-exposure brackets with fixed white balance. Locking
+ // auto-white balance after open but before the first call to
+ // startPreview may result in severely incorrect color. The
+ // driver may independently enable the AWB lock after auto-focus
+ // completes. If it does so, this key must have its value updated
+ // to reflect the lock's existence. Applications are free to
+ // release such a lock, to re-enable AWB without restarting
+ // preview.
+ static const char KEY_AUTO_WHITEBALANCE_LOCK[];
+ // Whether locking the auto-white balance is supported. "true"
+ // means it is, and "false" or this key not existing means it is
+ // not supported.
+ static const char KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED[];
+
+ // The maximum number of metering areas supported. This is the maximum
+ // length of KEY_METERING_AREAS.
+ // Example value: "0" or "2". Read only.
+ static const char KEY_MAX_NUM_METERING_AREAS[];
+ // Current metering areas. Camera driver uses these areas to decide
+ // exposure.
+ //
+ // Before accessing this parameter, apps should check
+ // KEY_MAX_NUM_METERING_AREAS first to know the maximum number of metering
+ // areas first. If the value is 0, metering area is not supported.
+ //
+ // Each metering area is a rectangle with specified weight. The direction is
+ // relative to the sensor orientation, that is, what the sensor sees. The
+ // direction is not affected by the rotation or mirroring of
+ // CAMERA_CMD_SET_DISPLAY_ORIENTATION. Coordinates of the rectangle range
+ // from -1000 to 1000. (-1000, -1000) is the upper left point. (1000, 1000)
+ // is the lower right point. The width and height of metering areas cannot
+ // be 0 or negative.
+ //
+ // The fifth element is the weight. Values for weight must range from 1 to
+ // 1000. The weight should be interpreted as a per-pixel weight - all
+ // pixels in the area have the specified weight. This means a small area
+ // with the same weight as a larger area will have less influence on the
+ // metering than the larger area. Metering areas can partially overlap and
+ // the driver will add the weights in the overlap region.
+ //
+ // A special case of all-zero single metering area means driver to decide
+ // the metering area. For example, the driver may use more signals to decide
+ // metering areas and change them dynamically. Apps can set all-zero if they
+ // want the driver to decide metering areas.
+ //
+ // Metering areas are relative to the current field of view (KEY_ZOOM).
+ // No matter what the zoom level is, (-1000,-1000) represents the top of the
+ // currently visible camera frame. The metering area cannot be set to be
+ // outside the current field of view, even when using zoom.
+ //
+ // No matter what metering areas are, the final exposure are compensated
+ // by KEY_EXPOSURE_COMPENSATION.
+ // Example value: "(-10,-10,0,0,300),(0,0,10,10,700)". Read/write.
+ static const char KEY_METERING_AREAS[];
// Current zoom value.
// Example value: "0" or "6". Read/write.
static const char KEY_ZOOM[];
@@ -328,6 +455,16 @@
// Example: "176x144,1280x720". Read only.
static const char KEY_SUPPORTED_VIDEO_SIZES[];
+ // The maximum number of detected faces supported by hardware face
+ // detection. If the value is 0, hardware face detection is not supported.
+ // Example: "5". Read only
+ static const char KEY_MAX_NUM_DETECTED_FACES_HW[];
+
+ // The maximum number of detected faces supported by software face
+ // detection. If the value is 0, software face detection is not supported.
+ // Example: "5". Read only
+ static const char KEY_MAX_NUM_DETECTED_FACES_SW[];
+
// Preferred preview frame size in pixels for video recording.
// The width and height must be one of the supported sizes retrieved
// via KEY_SUPPORTED_PREVIEW_SIZES. This key can be used only when
@@ -347,8 +484,20 @@
// Example value: "yuv420sp" or PIXEL_FORMAT_XXX constants. Read only.
static const char KEY_VIDEO_FRAME_FORMAT[];
+ // Sets the hint of the recording mode. If this is true, MediaRecorder.start
+ // may be faster or has less glitches. This should be called before starting
+ // the preview for the best result. But it is allowed to change the hint
+ // while the preview is active. The default value is false.
+ //
+ // The apps can still call Camera.takePicture when the hint is true. The
+ // apps can call MediaRecorder.start when the hint is false. But the
+ // performance may be worse.
+ // Example value: "true" or "false". Read/write.
+ static const char KEY_RECORDING_HINT[];
+
// Value for KEY_ZOOM_SUPPORTED or KEY_SMOOTH_ZOOM_SUPPORTED.
static const char TRUE[];
+ static const char FALSE[];
// Value for KEY_FOCUS_DISTANCES.
static const char FOCUS_DISTANCE_INFINITY[];
@@ -422,7 +571,11 @@
static const char PIXEL_FORMAT_YUV422I[]; // YUY2
static const char PIXEL_FORMAT_YUV420P[]; // YV12
static const char PIXEL_FORMAT_RGB565[];
+ static const char PIXEL_FORMAT_RGBA8888[];
static const char PIXEL_FORMAT_JPEG[];
+ // Raw bayer format used for images, which is 10 bit precision samples
+ // stored in 16 bit words. The filter pattern is RGGB.
+ static const char PIXEL_FORMAT_BAYER_RGGB[];
// Values for focus mode settings.
// Auto-focus mode. Applications should call
diff --git a/include/camera/ICamera.h b/include/camera/ICamera.h
index 2344b3f..400d7f4 100644
--- a/include/camera/ICamera.h
+++ b/include/camera/ICamera.h
@@ -102,12 +102,6 @@
// send command to camera driver
virtual status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) = 0;
- // return the total number of available video buffers
- virtual int32_t getNumberOfVideoBuffers() const = 0;
-
- // return the individual video buffer corresponding to the given index.
- virtual sp<IMemory> getVideoBuffer(int32_t index) const = 0;
-
// tell the camera hal to store meta data or real YUV data in video buffers.
virtual status_t storeMetaDataInBuffers(bool enabled) = 0;
};
diff --git a/include/camera/ICameraClient.h b/include/camera/ICameraClient.h
index 236d0f6..b30aa7a 100644
--- a/include/camera/ICameraClient.h
+++ b/include/camera/ICameraClient.h
@@ -22,6 +22,7 @@
#include <binder/Parcel.h>
#include <binder/IMemory.h>
#include <utils/Timers.h>
+#include <system/camera.h>
namespace android {
@@ -31,7 +32,8 @@
DECLARE_META_INTERFACE(CameraClient);
virtual void notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) = 0;
- virtual void dataCallback(int32_t msgType, const sp<IMemory>& data) = 0;
+ virtual void dataCallback(int32_t msgType, const sp<IMemory>& data,
+ camera_frame_metadata_t *metadata) = 0;
virtual void dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& data) = 0;
};
diff --git a/include/camera/ICameraRecordingProxy.h b/include/camera/ICameraRecordingProxy.h
new file mode 100644
index 0000000..2aac284
--- /dev/null
+++ b/include/camera/ICameraRecordingProxy.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2011 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 ANDROID_HARDWARE_ICAMERA_RECORDING_PROXY_H
+#define ANDROID_HARDWARE_ICAMERA_RECORDING_PROXY_H
+
+#include <binder/IInterface.h>
+#include <utils/RefBase.h>
+
+namespace android {
+
+class ICameraRecordingProxyListener;
+class IMemory;
+class Parcel;
+
+/*
+ * The purpose of ICameraRecordingProxy and ICameraRecordingProxyListener is to
+ * allow applications using the camera during recording.
+ *
+ * Camera service allows only one client at a time. Since camcorder application
+ * needs to own the camera to do things like zoom, the media recorder cannot
+ * access the camera directly during recording. So ICameraRecordingProxy is a
+ * proxy of ICamera, which allows the media recorder to start/stop the recording
+ * and release recording frames. ICameraRecordingProxyListener is an interface
+ * that allows the recorder to receive video frames during recording.
+ *
+ * ICameraRecordingProxy
+ * startRecording()
+ * stopRecording()
+ * releaseRecordingFrame()
+ *
+ * ICameraRecordingProxyListener
+ * dataCallbackTimestamp()
+
+ * The camcorder app opens the camera and starts the preview. The app passes
+ * ICamera and ICameraRecordingProxy to the media recorder by
+ * MediaRecorder::setCamera(). The recorder uses ICamera to setup the camera in
+ * MediaRecorder::start(). After setup, the recorder disconnects from camera
+ * service. The recorder calls ICameraRecordingProxy::startRecording() and
+ * passes a ICameraRecordingProxyListener to the app. The app connects back to
+ * camera service and starts the recording. The app owns the camera and can do
+ * things like zoom. The media recorder receives the video frames from the
+ * listener and releases them by ICameraRecordingProxy::releaseRecordingFrame.
+ * The recorder calls ICameraRecordingProxy::stopRecording() to stop the
+ * recording.
+ *
+ * The call sequences are as follows:
+ * 1. The app: Camera.unlock().
+ * 2. The app: MediaRecorder.setCamera().
+ * 3. Start recording
+ * (1) The app: MediaRecorder.start().
+ * (2) The recorder: ICamera.unlock() and ICamera.disconnect().
+ * (3) The recorder: ICameraRecordingProxy.startRecording().
+ * (4) The app: ICamera.reconnect().
+ * (5) The app: ICamera.startRecording().
+ * 4. During recording
+ * (1) The recorder: receive frames from ICameraRecordingProxyListener.dataCallbackTimestamp()
+ * (2) The recorder: release frames by ICameraRecordingProxy.releaseRecordingFrame().
+ * 5. Stop recording
+ * (1) The app: MediaRecorder.stop()
+ * (2) The recorder: ICameraRecordingProxy.stopRecording().
+ * (3) The app: ICamera.stopRecording().
+ */
+
+class ICameraRecordingProxy: public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(CameraRecordingProxy);
+
+ virtual status_t startRecording(const sp<ICameraRecordingProxyListener>& listener) = 0;
+ virtual void stopRecording() = 0;
+ virtual void releaseRecordingFrame(const sp<IMemory>& mem) = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnCameraRecordingProxy: public BnInterface<ICameraRecordingProxy>
+{
+public:
+ virtual status_t onTransact( uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+};
+
+}; // namespace android
+
+#endif
diff --git a/include/camera/ICameraRecordingProxyListener.h b/include/camera/ICameraRecordingProxyListener.h
new file mode 100644
index 0000000..b6c0624
--- /dev/null
+++ b/include/camera/ICameraRecordingProxyListener.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2011 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 ANDROID_HARDWARE_ICAMERA_RECORDING_PROXY_LISTENER_H
+#define ANDROID_HARDWARE_ICAMERA_RECORDING_PROXY_LISTENER_H
+
+#include <binder/IInterface.h>
+#include <stdint.h>
+#include <utils/RefBase.h>
+#include <utils/Timers.h>
+
+namespace android {
+
+class Parcel;
+class IMemory;
+
+class ICameraRecordingProxyListener: public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(CameraRecordingProxyListener);
+
+ virtual void dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType,
+ const sp<IMemory>& data) = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnCameraRecordingProxyListener: public BnInterface<ICameraRecordingProxyListener>
+{
+public:
+ virtual status_t onTransact( uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+};
+
+}; // namespace android
+
+#endif
diff --git a/include/drm/DrmInfoEvent.h b/include/drm/DrmInfoEvent.h
index add33d3..dfca228 100644
--- a/include/drm/DrmInfoEvent.h
+++ b/include/drm/DrmInfoEvent.h
@@ -77,7 +77,7 @@
* @param[in] infoType Type of information
* @param[in] message Message description
*/
- DrmInfoEvent(int uniqueId, int infoType, const String8& message);
+ DrmInfoEvent(int uniqueId, int infoType, const String8 message);
/**
* Destructor for DrmInfoEvent
@@ -104,12 +104,12 @@
*
* @return Message description
*/
- const String8& getMessage() const;
+ const String8 getMessage() const;
private:
int mUniqueId;
int mInfoType;
- const String8& mMessage;
+ const String8 mMessage;
};
};
diff --git a/include/drm/DrmManagerClient.h b/include/drm/DrmManagerClient.h
index 7a0bf4f..b8fe46d 100644
--- a/include/drm/DrmManagerClient.h
+++ b/include/drm/DrmManagerClient.h
@@ -69,7 +69,7 @@
* @return
* Handle for the decryption session
*/
- DecryptHandle* openDecryptSession(int fd, off64_t offset, off64_t length);
+ sp<DecryptHandle> openDecryptSession(int fd, off64_t offset, off64_t length);
/**
* Open the decrypt session to decrypt the given protected content
@@ -78,7 +78,7 @@
* @return
* Handle for the decryption session
*/
- DecryptHandle* openDecryptSession(const char* uri);
+ sp<DecryptHandle> openDecryptSession(const char* uri);
/**
* Close the decrypt session for the given handle
@@ -87,7 +87,7 @@
* @return status_t
* Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
*/
- status_t closeDecryptSession(DecryptHandle* decryptHandle);
+ status_t closeDecryptSession(sp<DecryptHandle> &decryptHandle);
/**
* Consumes the rights for a content.
@@ -101,7 +101,7 @@
* Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure.
* In case license has been expired, DRM_ERROR_LICENSE_EXPIRED will be returned.
*/
- status_t consumeRights(DecryptHandle* decryptHandle, int action, bool reserve);
+ status_t consumeRights(sp<DecryptHandle> &decryptHandle, int action, bool reserve);
/**
* Informs the DRM engine about the playback actions performed on the DRM files.
@@ -113,7 +113,8 @@
* @return status_t
* Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
*/
- status_t setPlaybackStatus(DecryptHandle* decryptHandle, int playbackStatus, int64_t position);
+ status_t setPlaybackStatus(
+ sp<DecryptHandle> &decryptHandle, int playbackStatus, int64_t position);
/**
* Initialize decryption for the given unit of the protected content
@@ -125,7 +126,7 @@
* Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
*/
status_t initializeDecryptUnit(
- DecryptHandle* decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo);
+ sp<DecryptHandle> &decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo);
/**
* Decrypt the protected content buffers for the given unit
@@ -144,7 +145,7 @@
* DRM_ERROR_DECRYPT for failure.
*/
status_t decrypt(
- DecryptHandle* decryptHandle, int decryptUnitId,
+ sp<DecryptHandle> &decryptHandle, int decryptUnitId,
const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV = NULL);
/**
@@ -155,7 +156,8 @@
* @return status_t
* Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
*/
- status_t finalizeDecryptUnit(DecryptHandle* decryptHandle, int decryptUnitId);
+ status_t finalizeDecryptUnit(
+ sp<DecryptHandle> &decryptHandle, int decryptUnitId);
/**
* Reads the specified number of bytes from an open DRM file.
@@ -167,7 +169,8 @@
*
* @return Number of bytes read. Returns -1 for Failure.
*/
- ssize_t pread(DecryptHandle* decryptHandle, void* buffer, ssize_t numBytes, off64_t offset);
+ ssize_t pread(sp<DecryptHandle> &decryptHandle,
+ void* buffer, ssize_t numBytes, off64_t offset);
/**
* Validates whether an action on the DRM content is allowed or not.
diff --git a/include/drm/drm_framework_common.h b/include/drm/drm_framework_common.h
index 9057f98..2632cbd 100644
--- a/include/drm/drm_framework_common.h
+++ b/include/drm/drm_framework_common.h
@@ -19,6 +19,7 @@
#include <utils/Vector.h>
#include <utils/KeyedVector.h>
+#include <utils/RefBase.h>
#include <utils/String8.h>
#include <utils/Errors.h>
@@ -255,7 +256,7 @@
/**
* Defines decryption handle
*/
-class DecryptHandle {
+class DecryptHandle : public RefBase {
public:
/**
* Decryption session Handle
@@ -311,10 +312,15 @@
decryptId(INVALID_VALUE),
mimeType(""),
decryptApiType(INVALID_VALUE),
- status(INVALID_VALUE) {
+ status(INVALID_VALUE),
+ decryptInfo(NULL) {
}
+ ~DecryptHandle() {
+ delete decryptInfo; decryptInfo = NULL;
+ }
+
bool operator<(const DecryptHandle& handle) const {
return (decryptId < handle.decryptId);
}
diff --git a/include/media/AudioEffect.h b/include/media/AudioEffect.h
index cda2be0..1417416 100644
--- a/include/media/AudioEffect.h
+++ b/include/media/AudioEffect.h
@@ -21,9 +21,10 @@
#include <sys/types.h>
#include <media/IAudioFlinger.h>
+#include <media/IAudioPolicyService.h>
#include <media/IEffect.h>
#include <media/IEffectClient.h>
-#include <media/EffectApi.h>
+#include <hardware/audio_effect.h>
#include <media/AudioSystem.h>
#include <utils/RefBase.h>
@@ -44,50 +45,6 @@
public:
/*
- * Static methods for effect libraries management.
- */
-
- /*
- * Loads the effect library which path is given as first argument.
- * This must be the full path of a dynamic library (.so) implementing one or
- * more effect engines and exposing the effect library interface described in
- * EffectApi.h. The function returns a handle on the library for use by
- * further call to unloadEffectLibrary() to unload the library.
- *
- * Parameters:
- * libPath: full path of the dynamic library file in the file system.
- * handle: address where to return the library handle
- *
- * Returned status (from utils/Errors.h) can be:
- * NO_ERROR successful operation.
- * PERMISSION_DENIED could not get AudioFlinger interface or
- * application does not have permission to configure audio
- * NO_INIT effect factory not initialized or
- * library could not be loaded or
- * library does not implement required functions
- * BAD_VALUE invalid libPath string or handle
- *
- * Returned value:
- * *handle updated with library handle
- */
- static status_t loadEffectLibrary(const char *libPath, int *handle);
-
- /*
- * Unloads the effect library which handle is given as argument.
- *
- * Parameters:
- * handle: library handle
- *
- * Returned status (from utils/Errors.h) can be:
- * NO_ERROR successful operation.
- * PERMISSION_DENIED could not get AudioFlinger interface or
- * application does not have permission to configure audio
- * NO_INIT effect factory not initialized
- * BAD_VALUE invalid handle
- */
- static status_t unloadEffectLibrary(int handle);
-
- /*
* Static methods for effects enumeration.
*/
@@ -155,6 +112,36 @@
/*
+ * Returns a list of descriptors corresponding to the pre processings enabled by default
+ * on an AudioRecord with the supplied audio session ID.
+ *
+ * Parameters:
+ * audioSession: audio session ID.
+ * descriptors: address where the effect descriptors should be returned.
+ * count: as input, the maximum number of descriptor than should be returned
+ * as output, the number of descriptor returned if status is NO_ERROR or the actual
+ * number of enabled pre processings if status is NO_MEMORY
+ *
+ * Returned status (from utils/Errors.h) can be:
+ * NO_ERROR successful operation.
+ * NO_MEMORY the number of descriptor to return is more than the maximum number
+ * indicated by count.
+ * PERMISSION_DENIED could not get AudioFlinger interface
+ * NO_INIT effect library failed to initialize
+ * BAD_VALUE invalid audio session or descriptor pointers
+ *
+ * Returned value
+ * *descriptor updated with descriptors of pre processings enabled by default
+ * *count number of descriptors returned if returned status is N_ERROR.
+ * total number of pre processing enabled by default if returned status is
+ * NO_MEMORY. This happens if the count passed as input is less than the number
+ * of descriptors to return
+ */
+ static status_t queryDefaultPreProcessing(int audioSession,
+ effect_descriptor_t *descriptors,
+ uint32_t *count);
+
+ /*
* Events used by callback function (effect_callback_t).
*/
enum event_type {
@@ -232,7 +219,7 @@
* sessionID: audio session this effect is associated to. If 0, the effect will be global to
* the output mix. If not 0, the effect will be applied to all players
* (AudioTrack or MediaPLayer) within the same audio session.
- * output: HAL audio output stream to which this effect must be attached. Leave at 0 for
+ * io: HAL audio output or input stream to which this effect must be attached. Leave at 0 for
* automatic output selection by AudioFlinger.
*/
@@ -242,7 +229,7 @@
effect_callback_t cbf = 0,
void* user = 0,
int sessionId = 0,
- audio_io_handle_t output = 0
+ audio_io_handle_t io = 0
);
/* Constructor.
@@ -254,7 +241,7 @@
effect_callback_t cbf = 0,
void* user = 0,
int sessionId = 0,
- audio_io_handle_t output = 0
+ audio_io_handle_t io = 0
);
/* Terminates the AudioEffect and unregisters it from AudioFlinger.
@@ -276,7 +263,7 @@
effect_callback_t cbf = 0,
void* user = 0,
int sessionId = 0,
- audio_io_handle_t output = 0
+ audio_io_handle_t io = 0
);
/* Result of constructing the AudioEffect. This must be checked
@@ -298,7 +285,7 @@
*/
int32_t id() const { return mId; }
- /* Returns a descriptor for the effect (see effect_descriptor_t in EffectApi.h).
+ /* Returns a descriptor for the effect (see effect_descriptor_t in audio_effect.h).
*/
effect_descriptor_t descriptor() const;
@@ -324,7 +311,7 @@
*
* Parameters:
* param: pointer to effect_param_t structure containing the parameter
- * and its value (See EffectApi.h).
+ * and its value (See audio_effect.h).
* Returned status (from utils/Errors.h) can be:
* - NO_ERROR: successful operation.
* - INVALID_OPERATION: the application does not have control of the effect engine.
@@ -340,7 +327,7 @@
*
* Parameters:
* param: pointer to effect_param_t structure containing the parameter
- * and its value (See EffectApi.h).
+ * and its value (See audio_effect.h).
*
* Returned status (from utils/Errors.h) can be:
* - NO_ERROR: successful operation.
@@ -368,7 +355,7 @@
*
* Parameters:
* param: pointer to effect_param_t structure containing the parameter
- * and the returned value (See EffectApi.h).
+ * and the returned value (See audio_effect.h).
*
* Returned status (from utils/Errors.h) can be:
* - NO_ERROR: successful operation.
@@ -379,7 +366,7 @@
virtual status_t getParameter(effect_param_t *param);
/* Sends a command and receives a response to/from effect engine.
- * See EffectApi.h for details on effect command() function, valid command codes
+ * See audio_effect.h for details on effect command() function, valid command codes
* and formats.
*/
virtual status_t command(uint32_t cmdCode,
diff --git a/include/media/AudioParameter.h b/include/media/AudioParameter.h
new file mode 100644
index 0000000..79d5d82
--- /dev/null
+++ b/include/media/AudioParameter.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2008-2011 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 ANDROID_AUDIOPARAMETER_H_
+#define ANDROID_AUDIOPARAMETER_H_
+
+#include <utils/Errors.h>
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
+
+namespace android {
+
+class AudioParameter {
+
+public:
+ AudioParameter() {}
+ AudioParameter(const String8& keyValuePairs);
+ virtual ~AudioParameter();
+
+ // reserved parameter keys for changing standard parameters with setParameters() function.
+ // Using these keys is mandatory for AudioFlinger to properly monitor audio output/input
+ // configuration changes and act accordingly.
+ // keyRouting: to change audio routing, value is an int in audio_devices_t
+ // keySamplingRate: to change sampling rate routing, value is an int
+ // keyFormat: to change audio format, value is an int in audio_format_t
+ // keyChannels: to change audio channel configuration, value is an int in audio_channels_t
+ // keyFrameCount: to change audio output frame count, value is an int
+ // keyInputSource: to change audio input source, value is an int in audio_source_t
+ // (defined in media/mediarecorder.h)
+ static const char *keyRouting;
+ static const char *keySamplingRate;
+ static const char *keyFormat;
+ static const char *keyChannels;
+ static const char *keyFrameCount;
+ static const char *keyInputSource;
+
+ String8 toString();
+
+ status_t add(const String8& key, const String8& value);
+ status_t addInt(const String8& key, const int value);
+ status_t addFloat(const String8& key, const float value);
+
+ status_t remove(const String8& key);
+
+ status_t get(const String8& key, String8& value);
+ status_t getInt(const String8& key, int& value);
+ status_t getFloat(const String8& key, float& value);
+ status_t getAt(size_t index, String8& key, String8& value);
+
+ size_t size() { return mParameters.size(); }
+
+private:
+ String8 mKeyValuePairs;
+ KeyedVector <String8, String8> mParameters;
+};
+
+}; // namespace android
+
+#endif /*ANDROID_AUDIOPARAMETER_H_*/
diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h
index 293764d..605680a 100644
--- a/include/media/AudioRecord.h
+++ b/include/media/AudioRecord.h
@@ -30,6 +30,7 @@
#include <binder/IMemory.h>
#include <utils/threads.h>
+#include <system/audio.h>
namespace android {
@@ -127,9 +128,9 @@
*
* inputSource: Select the audio input to record to (e.g. AUDIO_SOURCE_DEFAULT).
* sampleRate: Track sampling rate in Hz.
- * format: Audio format (e.g AudioSystem::PCM_16_BIT for signed
+ * format: Audio format (e.g AUDIO_FORMAT_PCM_16_BIT for signed
* 16 bits per sample).
- * channels: Channel mask: see AudioSystem::audio_channels.
+ * channelMask: Channel mask: see audio_channels_t.
* frameCount: Total size of track PCM buffer in frames. This defines the
* latency of the track.
* flags: A bitmask of acoustic values from enum record_flags. It enables
@@ -142,15 +143,15 @@
*/
enum record_flags {
- RECORD_AGC_ENABLE = AudioSystem::AGC_ENABLE,
- RECORD_NS_ENABLE = AudioSystem::NS_ENABLE,
- RECORD_IIR_ENABLE = AudioSystem::TX_IIR_ENABLE
+ RECORD_AGC_ENABLE = AUDIO_IN_ACOUSTICS_AGC_ENABLE,
+ RECORD_NS_ENABLE = AUDIO_IN_ACOUSTICS_NS_ENABLE,
+ RECORD_IIR_ENABLE = AUDIO_IN_ACOUSTICS_TX_IIR_ENABLE,
};
AudioRecord(int inputSource,
uint32_t sampleRate = 0,
int format = 0,
- uint32_t channels = AudioSystem::CHANNEL_IN_MONO,
+ uint32_t channelMask = AUDIO_CHANNEL_IN_MONO,
int frameCount = 0,
uint32_t flags = 0,
callback_t cbf = 0,
@@ -176,7 +177,7 @@
status_t set(int inputSource = 0,
uint32_t sampleRate = 0,
int format = 0,
- uint32_t channels = AudioSystem::CHANNEL_IN_MONO,
+ uint32_t channelMask = AUDIO_CHANNEL_IN_MONO,
int frameCount = 0,
uint32_t flags = 0,
callback_t cbf = 0,
@@ -347,8 +348,8 @@
bool processAudioBuffer(const sp<ClientRecordThread>& thread);
status_t openRecord_l(uint32_t sampleRate,
- int format,
- int channelCount,
+ uint32_t format,
+ uint32_t channelMask,
int frameCount,
uint32_t flags,
audio_io_handle_t input);
@@ -363,10 +364,10 @@
uint32_t mFrameCount;
audio_track_cblk_t* mCblk;
- uint8_t mFormat;
+ uint32_t mFormat;
uint8_t mChannelCount;
uint8_t mInputSource;
- uint8_t mReserved;
+ uint8_t mReserved[2];
status_t mStatus;
uint32_t mLatency;
@@ -381,7 +382,7 @@
uint32_t mNewPosition;
uint32_t mUpdatePeriod;
uint32_t mFlags;
- uint32_t mChannels;
+ uint32_t mChannelMask;
audio_io_handle_t mInput;
int mSessionId;
};
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index 2dc4beb..f20e234 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -21,10 +21,15 @@
#include <utils/threads.h>
#include <media/IAudioFlinger.h>
+#include <system/audio.h>
+#include <system/audio_policy.h>
+
+/* XXX: Should be include by all the users instead */
+#include <media/AudioParameter.h>
+
namespace android {
typedef void (*audio_error_callback)(status_t err);
-typedef int audio_io_handle_t;
class IAudioPolicyService;
class String8;
@@ -33,151 +38,6 @@
{
public:
- enum stream_type {
- DEFAULT =-1,
- VOICE_CALL = 0,
- SYSTEM = 1,
- RING = 2,
- MUSIC = 3,
- ALARM = 4,
- NOTIFICATION = 5,
- BLUETOOTH_SCO = 6,
- ENFORCED_AUDIBLE = 7, // Sounds that cannot be muted by user and must be routed to speaker
- DTMF = 8,
- TTS = 9,
- NUM_STREAM_TYPES
- };
-
- // Audio sub formats (see AudioSystem::audio_format).
- enum pcm_sub_format {
- PCM_SUB_16_BIT = 0x1, // must be 1 for backward compatibility
- PCM_SUB_8_BIT = 0x2, // must be 2 for backward compatibility
- };
-
- // MP3 sub format field definition : can use 11 LSBs in the same way as MP3 frame header to specify
- // bit rate, stereo mode, version...
- enum mp3_sub_format {
- //TODO
- };
-
- // AMR NB/WB sub format field definition: specify frame block interleaving, bandwidth efficient or octet aligned,
- // encoding mode for recording...
- enum amr_sub_format {
- //TODO
- };
-
- // AAC sub format field definition: specify profile or bitrate for recording...
- enum aac_sub_format {
- //TODO
- };
-
- // VORBIS sub format field definition: specify quality for recording...
- enum vorbis_sub_format {
- //TODO
- };
-
- // Audio format consists in a main format field (upper 8 bits) and a sub format field (lower 24 bits).
- // The main format indicates the main codec type. The sub format field indicates options and parameters
- // for each format. The sub format is mainly used for record to indicate for instance the requested bitrate
- // or profile. It can also be used for certain formats to give informations not present in the encoded
- // audio stream (e.g. octet alignement for AMR).
- enum audio_format {
- INVALID_FORMAT = -1,
- FORMAT_DEFAULT = 0,
- PCM = 0x00000000, // must be 0 for backward compatibility
- MP3 = 0x01000000,
- AMR_NB = 0x02000000,
- AMR_WB = 0x03000000,
- AAC = 0x04000000,
- HE_AAC_V1 = 0x05000000,
- HE_AAC_V2 = 0x06000000,
- VORBIS = 0x07000000,
- MAIN_FORMAT_MASK = 0xFF000000,
- SUB_FORMAT_MASK = 0x00FFFFFF,
- // Aliases
- PCM_16_BIT = (PCM|PCM_SUB_16_BIT),
- PCM_8_BIT = (PCM|PCM_SUB_8_BIT)
- };
-
-
- // Channel mask definitions must be kept in sync with JAVA values in /media/java/android/media/AudioFormat.java
- enum audio_channels {
- // output channels
- CHANNEL_OUT_FRONT_LEFT = 0x4,
- CHANNEL_OUT_FRONT_RIGHT = 0x8,
- CHANNEL_OUT_FRONT_CENTER = 0x10,
- CHANNEL_OUT_LOW_FREQUENCY = 0x20,
- CHANNEL_OUT_BACK_LEFT = 0x40,
- CHANNEL_OUT_BACK_RIGHT = 0x80,
- CHANNEL_OUT_FRONT_LEFT_OF_CENTER = 0x100,
- CHANNEL_OUT_FRONT_RIGHT_OF_CENTER = 0x200,
- CHANNEL_OUT_BACK_CENTER = 0x400,
- CHANNEL_OUT_MONO = CHANNEL_OUT_FRONT_LEFT,
- CHANNEL_OUT_STEREO = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT),
- CHANNEL_OUT_QUAD = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
- CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT),
- CHANNEL_OUT_SURROUND = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
- CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_BACK_CENTER),
- CHANNEL_OUT_5POINT1 = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
- CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_LOW_FREQUENCY | CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT),
- CHANNEL_OUT_7POINT1 = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
- CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_LOW_FREQUENCY | CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT |
- CHANNEL_OUT_FRONT_LEFT_OF_CENTER | CHANNEL_OUT_FRONT_RIGHT_OF_CENTER),
- CHANNEL_OUT_ALL = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
- CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_LOW_FREQUENCY | CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT |
- CHANNEL_OUT_FRONT_LEFT_OF_CENTER | CHANNEL_OUT_FRONT_RIGHT_OF_CENTER | CHANNEL_OUT_BACK_CENTER),
-
- // input channels
- CHANNEL_IN_LEFT = 0x4,
- CHANNEL_IN_RIGHT = 0x8,
- CHANNEL_IN_FRONT = 0x10,
- CHANNEL_IN_BACK = 0x20,
- CHANNEL_IN_LEFT_PROCESSED = 0x40,
- CHANNEL_IN_RIGHT_PROCESSED = 0x80,
- CHANNEL_IN_FRONT_PROCESSED = 0x100,
- CHANNEL_IN_BACK_PROCESSED = 0x200,
- CHANNEL_IN_PRESSURE = 0x400,
- CHANNEL_IN_X_AXIS = 0x800,
- CHANNEL_IN_Y_AXIS = 0x1000,
- CHANNEL_IN_Z_AXIS = 0x2000,
- CHANNEL_IN_VOICE_UPLINK = 0x4000,
- CHANNEL_IN_VOICE_DNLINK = 0x8000,
- CHANNEL_IN_MONO = CHANNEL_IN_FRONT,
- CHANNEL_IN_STEREO = (CHANNEL_IN_LEFT | CHANNEL_IN_RIGHT),
- CHANNEL_IN_ALL = (CHANNEL_IN_LEFT | CHANNEL_IN_RIGHT | CHANNEL_IN_FRONT | CHANNEL_IN_BACK|
- CHANNEL_IN_LEFT_PROCESSED | CHANNEL_IN_RIGHT_PROCESSED | CHANNEL_IN_FRONT_PROCESSED | CHANNEL_IN_BACK_PROCESSED|
- CHANNEL_IN_PRESSURE | CHANNEL_IN_X_AXIS | CHANNEL_IN_Y_AXIS | CHANNEL_IN_Z_AXIS |
- CHANNEL_IN_VOICE_UPLINK | CHANNEL_IN_VOICE_DNLINK)
- };
-
- enum audio_mode {
- MODE_INVALID = -2,
- MODE_CURRENT = -1,
- MODE_NORMAL = 0,
- MODE_RINGTONE,
- MODE_IN_CALL,
- MODE_IN_COMMUNICATION,
- NUM_MODES // not a valid entry, denotes end-of-list
- };
-
- enum audio_in_acoustics {
- AGC_ENABLE = 0x0001,
- AGC_DISABLE = 0,
- NS_ENABLE = 0x0002,
- NS_DISABLE = 0,
- TX_IIR_ENABLE = 0x0004,
- TX_DISABLE = 0
- };
-
- // special audio session values
- enum audio_sessions {
- SESSION_OUTPUT_STAGE = -1, // session for effects attached to a particular output stream
- // (value must be less than 0)
- SESSION_OUTPUT_MIX = 0, // session for effects applied to output mix. These effects can
- // be moved by audio policy manager to another output stream
- // (value must be 0)
- };
-
/* These are static methods to control the system-wide AudioFlinger
* only privileged processes can have access to them
*/
@@ -189,6 +49,7 @@
// set/get master volume
static status_t setMasterVolume(float value);
static status_t getMasterVolume(float* volume);
+
// mute/unmute audio outputs
static status_t setMasterMute(bool mute);
static status_t getMasterMute(bool* mute);
@@ -201,7 +62,7 @@
static status_t setStreamMute(int stream, bool mute);
static status_t getStreamMute(int stream, bool* mute);
- // set audio mode in audio hardware (see AudioSystem::audio_mode)
+ // set audio mode in audio hardware (see audio_mode_t)
static status_t setMode(int mode);
// returns true in *state if tracks are active on the specified stream or has been active
@@ -222,9 +83,9 @@
static float linearToLog(int volume);
static int logToLinear(float volume);
- static status_t getOutputSamplingRate(int* samplingRate, int stream = DEFAULT);
- static status_t getOutputFrameCount(int* frameCount, int stream = DEFAULT);
- static status_t getOutputLatency(uint32_t* latency, int stream = DEFAULT);
+ static status_t getOutputSamplingRate(int* samplingRate, int stream = AUDIO_STREAM_DEFAULT);
+ static status_t getOutputFrameCount(int* frameCount, int stream = AUDIO_STREAM_DEFAULT);
+ static status_t getOutputLatency(uint32_t* latency, int stream = AUDIO_STREAM_DEFAULT);
static bool routedToA2dpOutput(int streamType);
@@ -234,7 +95,7 @@
static status_t setVoiceVolume(float volume);
// return the number of audio frames written by AudioFlinger to audio HAL and
- // audio dsp to DAC since the output on which the specificed stream is playing
+ // audio dsp to DAC since the output on which the specified stream is playing
// has exited standby.
// returned status (from utils/Errors.h) can be:
// - NO_ERROR: successful operation, halFrames and dspFrames point to valid data
@@ -242,93 +103,11 @@
// - BAD_VALUE: invalid parameter
// NOTE: this feature is not supported on all hardware platforms and it is
// necessary to check returned status before using the returned values.
- static status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, int stream = DEFAULT);
+ static status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, int stream = AUDIO_STREAM_DEFAULT);
static unsigned int getInputFramesLost(audio_io_handle_t ioHandle);
static int newAudioSessionId();
- //
- // AudioPolicyService interface
- //
-
- enum audio_devices {
- // output devices
- DEVICE_OUT_EARPIECE = 0x1,
- DEVICE_OUT_SPEAKER = 0x2,
- DEVICE_OUT_WIRED_HEADSET = 0x4,
- DEVICE_OUT_WIRED_HEADPHONE = 0x8,
- DEVICE_OUT_BLUETOOTH_SCO = 0x10,
- DEVICE_OUT_BLUETOOTH_SCO_HEADSET = 0x20,
- DEVICE_OUT_BLUETOOTH_SCO_CARKIT = 0x40,
- DEVICE_OUT_BLUETOOTH_A2DP = 0x80,
- DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES = 0x100,
- DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER = 0x200,
- DEVICE_OUT_AUX_DIGITAL = 0x400,
- DEVICE_OUT_ANLG_DOCK_HEADSET = 0x800,
- DEVICE_OUT_DGTL_DOCK_HEADSET = 0x1000,
- DEVICE_OUT_DEFAULT = 0x8000,
- DEVICE_OUT_ALL = (DEVICE_OUT_EARPIECE | DEVICE_OUT_SPEAKER | DEVICE_OUT_WIRED_HEADSET |
- DEVICE_OUT_WIRED_HEADPHONE | DEVICE_OUT_BLUETOOTH_SCO | DEVICE_OUT_BLUETOOTH_SCO_HEADSET |
- DEVICE_OUT_BLUETOOTH_SCO_CARKIT | DEVICE_OUT_BLUETOOTH_A2DP | DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
- DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER | DEVICE_OUT_AUX_DIGITAL |
- DEVICE_OUT_ANLG_DOCK_HEADSET | DEVICE_OUT_DGTL_DOCK_HEADSET |
- DEVICE_OUT_DEFAULT),
- DEVICE_OUT_ALL_A2DP = (DEVICE_OUT_BLUETOOTH_A2DP | DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
- DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER),
-
- // input devices
- DEVICE_IN_COMMUNICATION = 0x10000,
- DEVICE_IN_AMBIENT = 0x20000,
- DEVICE_IN_BUILTIN_MIC = 0x40000,
- DEVICE_IN_BLUETOOTH_SCO_HEADSET = 0x80000,
- DEVICE_IN_WIRED_HEADSET = 0x100000,
- DEVICE_IN_AUX_DIGITAL = 0x200000,
- DEVICE_IN_VOICE_CALL = 0x400000,
- DEVICE_IN_BACK_MIC = 0x800000,
- DEVICE_IN_DEFAULT = 0x80000000,
-
- DEVICE_IN_ALL = (DEVICE_IN_COMMUNICATION | DEVICE_IN_AMBIENT | DEVICE_IN_BUILTIN_MIC |
- DEVICE_IN_BLUETOOTH_SCO_HEADSET | DEVICE_IN_WIRED_HEADSET | DEVICE_IN_AUX_DIGITAL |
- DEVICE_IN_VOICE_CALL | DEVICE_IN_BACK_MIC | DEVICE_IN_DEFAULT)
- };
-
- // device connection states used for setDeviceConnectionState()
- enum device_connection_state {
- DEVICE_STATE_UNAVAILABLE,
- DEVICE_STATE_AVAILABLE,
- NUM_DEVICE_STATES
- };
-
- // request to open a direct output with getOutput() (by opposition to sharing an output with other AudioTracks)
- enum output_flags {
- OUTPUT_FLAG_INDIRECT = 0x0,
- OUTPUT_FLAG_DIRECT = 0x1
- };
-
- // device categories used for setForceUse()
- enum forced_config {
- FORCE_NONE,
- FORCE_SPEAKER,
- FORCE_HEADPHONES,
- FORCE_BT_SCO,
- FORCE_BT_A2DP,
- FORCE_WIRED_ACCESSORY,
- FORCE_BT_CAR_DOCK,
- FORCE_BT_DESK_DOCK,
- FORCE_ANALOG_DOCK,
- FORCE_DIGITAL_DOCK,
- NUM_FORCE_CONFIG,
- FORCE_DEFAULT = FORCE_NONE
- };
-
- // usages used for setForceUse()
- enum force_use {
- FOR_COMMUNICATION,
- FOR_MEDIA,
- FOR_RECORD,
- FOR_DOCK,
- NUM_FORCE_USE
- };
// types of io configuration change events received with ioConfigChanged()
enum io_config_event {
@@ -359,44 +138,45 @@
//
// IAudioPolicyService interface (see AudioPolicyInterface for method descriptions)
//
- static status_t setDeviceConnectionState(audio_devices device, device_connection_state state, const char *device_address);
- static device_connection_state getDeviceConnectionState(audio_devices device, const char *device_address);
+ static status_t setDeviceConnectionState(audio_devices_t device, audio_policy_dev_state_t state, const char *device_address);
+ static audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device, const char *device_address);
static status_t setPhoneState(int state);
static status_t setRingerMode(uint32_t mode, uint32_t mask);
- static status_t setForceUse(force_use usage, forced_config config);
- static forced_config getForceUse(force_use usage);
- static audio_io_handle_t getOutput(stream_type stream,
+ static status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config);
+ static audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage);
+ static audio_io_handle_t getOutput(audio_stream_type_t stream,
uint32_t samplingRate = 0,
- uint32_t format = FORMAT_DEFAULT,
- uint32_t channels = CHANNEL_OUT_STEREO,
- output_flags flags = OUTPUT_FLAG_INDIRECT);
+ uint32_t format = AUDIO_FORMAT_DEFAULT,
+ uint32_t channels = AUDIO_CHANNEL_OUT_STEREO,
+ audio_policy_output_flags_t flags = AUDIO_POLICY_OUTPUT_FLAG_INDIRECT);
static status_t startOutput(audio_io_handle_t output,
- AudioSystem::stream_type stream,
+ audio_stream_type_t stream,
int session = 0);
static status_t stopOutput(audio_io_handle_t output,
- AudioSystem::stream_type stream,
+ audio_stream_type_t stream,
int session = 0);
static void releaseOutput(audio_io_handle_t output);
static audio_io_handle_t getInput(int inputSource,
uint32_t samplingRate = 0,
- uint32_t format = FORMAT_DEFAULT,
- uint32_t channels = CHANNEL_IN_MONO,
- audio_in_acoustics acoustics = (audio_in_acoustics)0);
+ uint32_t format = AUDIO_FORMAT_DEFAULT,
+ uint32_t channels = AUDIO_CHANNEL_IN_MONO,
+ audio_in_acoustics_t acoustics = (audio_in_acoustics_t)0,
+ int sessionId = 0);
static status_t startInput(audio_io_handle_t input);
static status_t stopInput(audio_io_handle_t input);
static void releaseInput(audio_io_handle_t input);
- static status_t initStreamVolume(stream_type stream,
+ static status_t initStreamVolume(audio_stream_type_t stream,
int indexMin,
int indexMax);
- static status_t setStreamVolumeIndex(stream_type stream, int index);
- static status_t getStreamVolumeIndex(stream_type stream, int *index);
+ static status_t setStreamVolumeIndex(audio_stream_type_t stream, int index);
+ static status_t getStreamVolumeIndex(audio_stream_type_t stream, int *index);
- static uint32_t getStrategyForStream(stream_type stream);
- static uint32_t getDevicesForStream(stream_type stream);
+ static uint32_t getStrategyForStream(audio_stream_type_t stream);
+ static uint32_t getDevicesForStream(audio_stream_type_t stream);
static audio_io_handle_t getOutputForEffect(effect_descriptor_t *desc);
static status_t registerEffect(effect_descriptor_t *desc,
- audio_io_handle_t output,
+ audio_io_handle_t io,
uint32_t strategy,
int session,
int id);
@@ -406,17 +186,6 @@
// ----------------------------------------------------------------------------
- static uint32_t popCount(uint32_t u);
- static bool isOutputDevice(audio_devices device);
- static bool isInputDevice(audio_devices device);
- static bool isA2dpDevice(audio_devices device);
- static bool isBluetoothScoDevice(audio_devices device);
- static bool isLowVisibility(stream_type stream);
- static bool isOutputChannel(uint32_t channel);
- static bool isInputChannel(uint32_t channel);
- static bool isValidFormat(uint32_t format);
- static bool isLinearPCM(uint32_t format);
-
private:
class AudioFlingerClient: public IBinder::DeathRecipient, public BnAudioFlingerClient
@@ -468,50 +237,6 @@
static DefaultKeyedVector<audio_io_handle_t, OutputDescriptor *> gOutputs;
};
-class AudioParameter {
-
-public:
- AudioParameter() {}
- AudioParameter(const String8& keyValuePairs);
- virtual ~AudioParameter();
-
- // reserved parameter keys for changing standard parameters with setParameters() function.
- // Using these keys is mandatory for AudioFlinger to properly monitor audio output/input
- // configuration changes and act accordingly.
- // keyRouting: to change audio routing, value is an int in AudioSystem::audio_devices
- // keySamplingRate: to change sampling rate routing, value is an int
- // keyFormat: to change audio format, value is an int in AudioSystem::audio_format
- // keyChannels: to change audio channel configuration, value is an int in AudioSystem::audio_channels
- // keyFrameCount: to change audio output frame count, value is an int
- // keyInputSource: to change audio input source, value is an int in audio_source
- // (defined in media/mediarecorder.h)
- static const char *keyRouting;
- static const char *keySamplingRate;
- static const char *keyFormat;
- static const char *keyChannels;
- static const char *keyFrameCount;
- static const char *keyInputSource;
-
- String8 toString();
-
- status_t add(const String8& key, const String8& value);
- status_t addInt(const String8& key, const int value);
- status_t addFloat(const String8& key, const float value);
-
- status_t remove(const String8& key);
-
- status_t get(const String8& key, String8& value);
- status_t getInt(const String8& key, int& value);
- status_t getFloat(const String8& key, float& value);
- status_t getAt(size_t index, String8& key, String8& value);
-
- size_t size() { return mParameters.size(); }
-
-private:
- String8 mKeyValuePairs;
- KeyedVector <String8, String8> mParameters;
-};
-
}; // namespace android
#endif /*ANDROID_AUDIOSYSTEM_H_*/
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index 3e346db..df30e8c 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -30,7 +30,6 @@
#include <binder/IMemory.h>
#include <utils/threads.h>
-
namespace android {
// ----------------------------------------------------------------------------
@@ -70,8 +69,8 @@
MUTE = 0x00000001
};
uint32_t flags;
- int channelCount;
int format;
+ int channelCount; // will be removed in the future, do not use
size_t frameCount;
size_t size;
union {
@@ -126,11 +125,11 @@
* Parameters:
*
* streamType: Select the type of audio stream this track is attached to
- * (e.g. AudioSystem::MUSIC).
+ * (e.g. AUDIO_STREAM_MUSIC).
* sampleRate: Track sampling rate in Hz.
- * format: Audio format (e.g AudioSystem::PCM_16_BIT for signed
+ * format: Audio format (e.g AUDIO_FORMAT_PCM_16_BIT for signed
* 16 bits per sample).
- * channels: Channel mask: see AudioSystem::audio_channels.
+ * channelMask: Channel mask: see audio_channels_t.
* frameCount: Total size of track PCM buffer in frames. This defines the
* latency of the track.
* flags: Reserved for future use.
@@ -144,7 +143,7 @@
AudioTrack( int streamType,
uint32_t sampleRate = 0,
int format = 0,
- int channels = 0,
+ int channelMask = 0,
int frameCount = 0,
uint32_t flags = 0,
callback_t cbf = 0,
@@ -164,7 +163,7 @@
AudioTrack( int streamType,
uint32_t sampleRate = 0,
int format = 0,
- int channels = 0,
+ int channelMask = 0,
const sp<IMemory>& sharedBuffer = 0,
uint32_t flags = 0,
callback_t cbf = 0,
@@ -188,7 +187,7 @@
status_t set(int streamType =-1,
uint32_t sampleRate = 0,
int format = 0,
- int channels = 0,
+ int channelMask = 0,
int frameCount = 0,
uint32_t flags = 0,
callback_t cbf = 0,
@@ -439,8 +438,8 @@
bool processAudioBuffer(const sp<AudioTrackThread>& thread);
status_t createTrack_l(int streamType,
uint32_t sampleRate,
- int format,
- int channelCount,
+ uint32_t format,
+ uint32_t channelMask,
int frameCount,
uint32_t flags,
const sp<IMemory>& sharedBuffer,
@@ -460,11 +459,12 @@
uint32_t mFrameCount;
audio_track_cblk_t* mCblk;
+ uint32_t mFormat;
uint8_t mStreamType;
- uint8_t mFormat;
uint8_t mChannelCount;
uint8_t mMuted;
- uint32_t mChannels;
+ uint8_t mReserved;
+ uint32_t mChannelMask;
status_t mStatus;
uint32_t mLatency;
diff --git a/include/media/EffectApi.h b/include/media/EffectApi.h
deleted file mode 100644
index 6e6660c..0000000
--- a/include/media/EffectApi.h
+++ /dev/null
@@ -1,796 +0,0 @@
-/*
- * Copyright (C) 2010 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 ANDROID_EFFECTAPI_H_
-#define ANDROID_EFFECTAPI_H_
-
-#include <errno.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#if __cplusplus
-extern "C" {
-#endif
-
-/////////////////////////////////////////////////
-// Effect control interface
-/////////////////////////////////////////////////
-
-// The effect control interface is exposed by each effect engine implementation. It consists of
-// a set of functions controlling the configuration, activation and process of the engine.
-// The functions are grouped in a structure of type effect_interface_s:
-// struct effect_interface_s {
-// effect_process_t process;
-// effect_command_t command;
-// };
-
-
-// effect_interface_t: Effect control interface handle.
-// The effect_interface_t serves two purposes regarding the implementation of the effect engine:
-// - 1 it is the address of a pointer to an effect_interface_s structure where the functions
-// of the effect control API for a particular effect are located.
-// - 2 it is the address of the context of a particular effect instance.
-// A typical implementation in the effect library would define a structure as follows:
-// struct effect_module_s {
-// const struct effect_interface_s *itfe;
-// effect_config_t config;
-// effect_context_t context;
-// }
-// The implementation of EffectCreate() function would then allocate a structure of this
-// type and return its address as effect_interface_t
-typedef struct effect_interface_s **effect_interface_t;
-
-
-// Effect API version 1.0
-#define EFFECT_API_VERSION 0x0100 // Format 0xMMmm MM: Major version, mm: minor version
-
-// Maximum length of character strings in structures defines by this API.
-#define EFFECT_STRING_LEN_MAX 64
-
-//
-//--- Effect descriptor structure effect_descriptor_t
-//
-
-// Unique effect ID (can be generated from the following site:
-// http://www.itu.int/ITU-T/asn1/uuid.html)
-// This format is used for both "type" and "uuid" fields of the effect descriptor structure.
-// - When used for effect type and the engine is implementing and effect corresponding to a standard
-// OpenSL ES interface, this ID must be the one defined in OpenSLES_IID.h for that interface.
-// - When used as uuid, it should be a unique UUID for this particular implementation.
-typedef struct effect_uuid_s {
- uint32_t timeLow;
- uint16_t timeMid;
- uint16_t timeHiAndVersion;
- uint16_t clockSeq;
- uint8_t node[6];
-} effect_uuid_t;
-
-// NULL UUID definition (matches SL_IID_NULL_)
-#define EFFECT_UUID_INITIALIZER { 0xec7178ec, 0xe5e1, 0x4432, 0xa3f4, \
- { 0x46, 0x57, 0xe6, 0x79, 0x52, 0x10 } }
-static const effect_uuid_t EFFECT_UUID_NULL_ = EFFECT_UUID_INITIALIZER;
-const effect_uuid_t * const EFFECT_UUID_NULL = &EFFECT_UUID_NULL_;
-const char * const EFFECT_UUID_NULL_STR = "ec7178ec-e5e1-4432-a3f4-4657e6795210";
-
-// The effect descriptor contains necessary information to facilitate the enumeration of the effect
-// engines present in a library.
-typedef struct effect_descriptor_s {
- effect_uuid_t type; // UUID of to the OpenSL ES interface implemented by this effect
- effect_uuid_t uuid; // UUID for this particular implementation
- uint16_t apiVersion; // Version of the effect API implemented: matches EFFECT_API_VERSION
- uint32_t flags; // effect engine capabilities/requirements flags (see below)
- uint16_t cpuLoad; // CPU load indication (see below)
- uint16_t memoryUsage; // Data Memory usage (see below)
- char name[EFFECT_STRING_LEN_MAX]; // human readable effect name
- char implementor[EFFECT_STRING_LEN_MAX]; // human readable effect implementor name
-} effect_descriptor_t;
-
-// CPU load and memory usage indication: each effect implementation must provide an indication of
-// its CPU and memory usage for the audio effect framework to limit the number of effects
-// instantiated at a given time on a given platform.
-// The CPU load is expressed in 0.1 MIPS units as estimated on an ARM9E core (ARMv5TE) with 0 WS.
-// The memory usage is expressed in KB and includes only dynamically allocated memory
-
-// Definitions for flags field of effect descriptor.
-// +---------------------------+-----------+-----------------------------------
-// | description | bits | values
-// +---------------------------+-----------+-----------------------------------
-// | connection mode | 0..1 | 0 insert: after track process
-// | | | 1 auxiliary: connect to track auxiliary
-// | | | output and use send level
-// | | | 2 replace: replaces track process function;
-// | | | must implement SRC, volume and mono to stereo.
-// | | | 3 reserved
-// +---------------------------+-----------+-----------------------------------
-// | insertion preference | 2..4 | 0 none
-// | | | 1 first of the chain
-// | | | 2 last of the chain
-// | | | 3 exclusive (only effect in the insert chain)
-// | | | 4..7 reserved
-// +---------------------------+-----------+-----------------------------------
-// | Volume management | 5..6 | 0 none
-// | | | 1 implements volume control
-// | | | 2 requires volume indication
-// | | | 3 reserved
-// +---------------------------+-----------+-----------------------------------
-// | Device indication | 7..8 | 0 none
-// | | | 1 requires device updates
-// | | | 2..3 reserved
-// +---------------------------+-----------+-----------------------------------
-// | Sample input mode | 9..10 | 0 direct: process() function or EFFECT_CMD_CONFIGURE
-// | | | command must specify a buffer descriptor
-// | | | 1 provider: process() function uses the
-// | | | bufferProvider indicated by the
-// | | | EFFECT_CMD_CONFIGURE command to request input.
-// | | | buffers.
-// | | | 2 both: both input modes are supported
-// | | | 3 reserved
-// +---------------------------+-----------+-----------------------------------
-// | Sample output mode | 11..12 | 0 direct: process() function or EFFECT_CMD_CONFIGURE
-// | | | command must specify a buffer descriptor
-// | | | 1 provider: process() function uses the
-// | | | bufferProvider indicated by the
-// | | | EFFECT_CMD_CONFIGURE command to request output
-// | | | buffers.
-// | | | 2 both: both output modes are supported
-// | | | 3 reserved
-// +---------------------------+-----------+-----------------------------------
-// | Hardware acceleration | 13..15 | 0 No hardware acceleration
-// | | | 1 non tunneled hw acceleration: the process() function
-// | | | reads the samples, send them to HW accelerated
-// | | | effect processor, reads back the processed samples
-// | | | and returns them to the output buffer.
-// | | | 2 tunneled hw acceleration: the process() function is
-// | | | transparent. The effect interface is only used to
-// | | | control the effect engine. This mode is relevant for
-// | | | global effects actually applied by the audio
-// | | | hardware on the output stream.
-// +---------------------------+-----------+-----------------------------------
-// | Audio Mode indication | 16..17 | 0 none
-// | | | 1 requires audio mode updates
-// | | | 2..3 reserved
-// +---------------------------+-----------+-----------------------------------
-
-// Insert mode
-#define EFFECT_FLAG_TYPE_MASK 0x00000003
-#define EFFECT_FLAG_TYPE_INSERT 0x00000000
-#define EFFECT_FLAG_TYPE_AUXILIARY 0x00000001
-#define EFFECT_FLAG_TYPE_REPLACE 0x00000002
-
-// Insert preference
-#define EFFECT_FLAG_INSERT_MASK 0x0000001C
-#define EFFECT_FLAG_INSERT_ANY 0x00000000
-#define EFFECT_FLAG_INSERT_FIRST 0x00000004
-#define EFFECT_FLAG_INSERT_LAST 0x00000008
-#define EFFECT_FLAG_INSERT_EXCLUSIVE 0x0000000C
-
-
-// Volume control
-#define EFFECT_FLAG_VOLUME_MASK 0x00000060
-#define EFFECT_FLAG_VOLUME_CTRL 0x00000020
-#define EFFECT_FLAG_VOLUME_IND 0x00000040
-#define EFFECT_FLAG_VOLUME_NONE 0x00000000
-
-// Device indication
-#define EFFECT_FLAG_DEVICE_MASK 0x00000180
-#define EFFECT_FLAG_DEVICE_IND 0x00000080
-#define EFFECT_FLAG_DEVICE_NONE 0x00000000
-
-// Sample input modes
-#define EFFECT_FLAG_INPUT_MASK 0x00000600
-#define EFFECT_FLAG_INPUT_DIRECT 0x00000000
-#define EFFECT_FLAG_INPUT_PROVIDER 0x00000200
-#define EFFECT_FLAG_INPUT_BOTH 0x00000400
-
-// Sample output modes
-#define EFFECT_FLAG_OUTPUT_MASK 0x00001800
-#define EFFECT_FLAG_OUTPUT_DIRECT 0x00000000
-#define EFFECT_FLAG_OUTPUT_PROVIDER 0x00000800
-#define EFFECT_FLAG_OUTPUT_BOTH 0x00001000
-
-// Hardware acceleration mode
-#define EFFECT_FLAG_HW_ACC_MASK 0x00006000
-#define EFFECT_FLAG_HW_ACC_SIMPLE 0x00002000
-#define EFFECT_FLAG_HW_ACC_TUNNEL 0x00004000
-
-// Audio mode indication
-#define EFFECT_FLAG_AUDIO_MODE_MASK 0x00018000
-#define EFFECT_FLAG_AUDIO_MODE_IND 0x00008000
-#define EFFECT_FLAG_AUDIO_MODE_NONE 0x00000000
-
-// Forward definition of type audio_buffer_t
-typedef struct audio_buffer_s audio_buffer_t;
-
-////////////////////////////////////////////////////////////////////////////////
-//
-// Function: process
-//
-// Description: Effect process function. Takes input samples as specified
-// (count and location) in input buffer descriptor and output processed
-// samples as specified in output buffer descriptor. If the buffer descriptor
-// is not specified the function must use either the buffer or the
-// buffer provider function installed by the EFFECT_CMD_CONFIGURE command.
-// The effect framework will call the process() function after the EFFECT_CMD_ENABLE
-// command is received and until the EFFECT_CMD_DISABLE is received. When the engine
-// receives the EFFECT_CMD_DISABLE command it should turn off the effect gracefully
-// and when done indicate that it is OK to stop calling the process() function by
-// returning the -ENODATA status.
-//
-// NOTE: the process() function implementation should be "real-time safe" that is
-// it should not perform blocking calls: malloc/free, sleep, read/write/open/close,
-// pthread_cond_wait/pthread_mutex_lock...
-//
-// Input:
-// effect_interface_t: handle to the effect interface this function
-// is called on.
-// inBuffer: buffer descriptor indicating where to read samples to process.
-// If NULL, use the configuration passed by EFFECT_CMD_CONFIGURE command.
-//
-// inBuffer: buffer descriptor indicating where to write processed samples.
-// If NULL, use the configuration passed by EFFECT_CMD_CONFIGURE command.
-//
-// Output:
-// returned value: 0 successful operation
-// -ENODATA the engine has finished the disable phase and the framework
-// can stop calling process()
-// -EINVAL invalid interface handle or
-// invalid input/output buffer description
-////////////////////////////////////////////////////////////////////////////////
-typedef int32_t (*effect_process_t)(effect_interface_t self,
- audio_buffer_t *inBuffer,
- audio_buffer_t *outBuffer);
-
-////////////////////////////////////////////////////////////////////////////////
-//
-// Function: command
-//
-// Description: Send a command and receive a response to/from effect engine.
-//
-// Input:
-// effect_interface_t: handle to the effect interface this function
-// is called on.
-// cmdCode: command code: the command can be a standardized command defined in
-// effect_command_e (see below) or a proprietary command.
-// cmdSize: size of command in bytes
-// pCmdData: pointer to command data
-// pReplyData: pointer to reply data
-//
-// Input/Output:
-// replySize: maximum size of reply data as input
-// actual size of reply data as output
-//
-// Output:
-// returned value: 0 successful operation
-// -EINVAL invalid interface handle or
-// invalid command/reply size or format according to command code
-// The return code should be restricted to indicate problems related to the this
-// API specification. Status related to the execution of a particular command should be
-// indicated as part of the reply field.
-//
-// *pReplyData updated with command response
-//
-////////////////////////////////////////////////////////////////////////////////
-typedef int32_t (*effect_command_t)(effect_interface_t self,
- uint32_t cmdCode,
- uint32_t cmdSize,
- void *pCmdData,
- uint32_t *replySize,
- void *pReplyData);
-
-
-// Effect control interface definition
-struct effect_interface_s {
- effect_process_t process;
- effect_command_t command;
-};
-
-
-//
-//--- Standardized command codes for command() function
-//
-enum effect_command_e {
- EFFECT_CMD_INIT, // initialize effect engine
- EFFECT_CMD_CONFIGURE, // configure effect engine (see effect_config_t)
- EFFECT_CMD_RESET, // reset effect engine
- EFFECT_CMD_ENABLE, // enable effect process
- EFFECT_CMD_DISABLE, // disable effect process
- EFFECT_CMD_SET_PARAM, // set parameter immediately (see effect_param_t)
- EFFECT_CMD_SET_PARAM_DEFERRED, // set parameter deferred
- EFFECT_CMD_SET_PARAM_COMMIT, // commit previous set parameter deferred
- EFFECT_CMD_GET_PARAM, // get parameter
- EFFECT_CMD_SET_DEVICE, // set audio device (see audio_device_e)
- EFFECT_CMD_SET_VOLUME, // set volume
- EFFECT_CMD_SET_AUDIO_MODE, // set the audio mode (normal, ring, ...)
- EFFECT_CMD_FIRST_PROPRIETARY = 0x10000 // first proprietary command code
-};
-
-//==================================================================================================
-// command: EFFECT_CMD_INIT
-//--------------------------------------------------------------------------------------------------
-// description:
-// Initialize effect engine: All configurations return to default
-//--------------------------------------------------------------------------------------------------
-// command format:
-// size: 0
-// data: N/A
-//--------------------------------------------------------------------------------------------------
-// reply format:
-// size: sizeof(int)
-// data: status
-//==================================================================================================
-// command: EFFECT_CMD_CONFIGURE
-//--------------------------------------------------------------------------------------------------
-// description:
-// Apply new audio parameters configurations for input and output buffers
-//--------------------------------------------------------------------------------------------------
-// command format:
-// size: sizeof(effect_config_t)
-// data: effect_config_t
-//--------------------------------------------------------------------------------------------------
-// reply format:
-// size: sizeof(int)
-// data: status
-//==================================================================================================
-// command: EFFECT_CMD_RESET
-//--------------------------------------------------------------------------------------------------
-// description:
-// Reset the effect engine. Keep configuration but resets state and buffer content
-//--------------------------------------------------------------------------------------------------
-// command format:
-// size: 0
-// data: N/A
-//--------------------------------------------------------------------------------------------------
-// reply format:
-// size: 0
-// data: N/A
-//==================================================================================================
-// command: EFFECT_CMD_ENABLE
-//--------------------------------------------------------------------------------------------------
-// description:
-// Enable the process. Called by the framework before the first call to process()
-//--------------------------------------------------------------------------------------------------
-// command format:
-// size: 0
-// data: N/A
-//--------------------------------------------------------------------------------------------------
-// reply format:
-// size: sizeof(int)
-// data: status
-//==================================================================================================
-// command: EFFECT_CMD_DISABLE
-//--------------------------------------------------------------------------------------------------
-// description:
-// Disable the process. Called by the framework after the last call to process()
-//--------------------------------------------------------------------------------------------------
-// command format:
-// size: 0
-// data: N/A
-//--------------------------------------------------------------------------------------------------
-// reply format:
-// size: sizeof(int)
-// data: status
-//==================================================================================================
-// command: EFFECT_CMD_SET_PARAM
-//--------------------------------------------------------------------------------------------------
-// description:
-// Set a parameter and apply it immediately
-//--------------------------------------------------------------------------------------------------
-// command format:
-// size: sizeof(effect_param_t) + size of param and value
-// data: effect_param_t + param + value. See effect_param_t definition below for value offset
-//--------------------------------------------------------------------------------------------------
-// reply format:
-// size: sizeof(int)
-// data: status
-//==================================================================================================
-// command: EFFECT_CMD_SET_PARAM_DEFERRED
-//--------------------------------------------------------------------------------------------------
-// description:
-// Set a parameter but apply it only when receiving EFFECT_CMD_SET_PARAM_COMMIT command
-//--------------------------------------------------------------------------------------------------
-// command format:
-// size: sizeof(effect_param_t) + size of param and value
-// data: effect_param_t + param + value. See effect_param_t definition below for value offset
-//--------------------------------------------------------------------------------------------------
-// reply format:
-// size: 0
-// data: N/A
-//==================================================================================================
-// command: EFFECT_CMD_SET_PARAM_COMMIT
-//--------------------------------------------------------------------------------------------------
-// description:
-// Apply all previously received EFFECT_CMD_SET_PARAM_DEFERRED commands
-//--------------------------------------------------------------------------------------------------
-// command format:
-// size: 0
-// data: N/A
-//--------------------------------------------------------------------------------------------------
-// reply format:
-// size: sizeof(int)
-// data: status
-//==================================================================================================
-// command: EFFECT_CMD_GET_PARAM
-//--------------------------------------------------------------------------------------------------
-// description:
-// Get a parameter value
-//--------------------------------------------------------------------------------------------------
-// command format:
-// size: sizeof(effect_param_t) + size of param
-// data: effect_param_t + param
-//--------------------------------------------------------------------------------------------------
-// reply format:
-// size: sizeof(effect_param_t) + size of param and value
-// data: effect_param_t + param + value. See effect_param_t definition below for value offset
-//==================================================================================================
-// command: EFFECT_CMD_SET_DEVICE
-//--------------------------------------------------------------------------------------------------
-// description:
-// Set the rendering device the audio output path is connected to. See audio_device_e for device
-// values.
-// The effect implementation must set EFFECT_FLAG_DEVICE_IND flag in its descriptor to receive this
-// command when the device changes
-//--------------------------------------------------------------------------------------------------
-// command format:
-// size: sizeof(uint32_t)
-// data: audio_device_e
-//--------------------------------------------------------------------------------------------------
-// reply format:
-// size: 0
-// data: N/A
-//==================================================================================================
-// command: EFFECT_CMD_SET_VOLUME
-//--------------------------------------------------------------------------------------------------
-// description:
-// Set and get volume. Used by audio framework to delegate volume control to effect engine.
-// The effect implementation must set EFFECT_FLAG_VOLUME_IND or EFFECT_FLAG_VOLUME_CTRL flag in
-// its descriptor to receive this command before every call to process() function
-// If EFFECT_FLAG_VOLUME_CTRL flag is set in the effect descriptor, the effect engine must return
-// the volume that should be applied before the effect is processed. The overall volume (the volume
-// actually applied by the effect engine multiplied by the returned value) should match the value
-// indicated in the command.
-//--------------------------------------------------------------------------------------------------
-// command format:
-// size: n * sizeof(uint32_t)
-// data: volume for each channel defined in effect_config_t for output buffer expressed in
-// 8.24 fixed point format
-//--------------------------------------------------------------------------------------------------
-// reply format:
-// size: n * sizeof(uint32_t) / 0
-// data: - if EFFECT_FLAG_VOLUME_CTRL is set in effect descriptor:
-// volume for each channel defined in effect_config_t for output buffer expressed in
-// 8.24 fixed point format
-// - if EFFECT_FLAG_VOLUME_CTRL is not set in effect descriptor:
-// N/A
-// It is legal to receive a null pointer as pReplyData in which case the effect framework has
-// delegated volume control to another effect
-//==================================================================================================
-// command: EFFECT_CMD_SET_AUDIO_MODE
-//--------------------------------------------------------------------------------------------------
-// description:
-// Set the audio mode. The effect implementation must set EFFECT_FLAG_AUDIO_MODE_IND flag in its
-// descriptor to receive this command when the audio mode changes.
-//--------------------------------------------------------------------------------------------------
-// command format:
-// size: sizeof(uint32_t)
-// data: audio_mode_e
-//--------------------------------------------------------------------------------------------------
-// reply format:
-// size: 0
-// data: N/A
-//==================================================================================================
-// command: EFFECT_CMD_FIRST_PROPRIETARY
-//--------------------------------------------------------------------------------------------------
-// description:
-// All proprietary effect commands must use command codes above this value. The size and format of
-// command and response fields is free in this case
-//==================================================================================================
-
-
-// Audio buffer descriptor used by process(), bufferProvider() functions and buffer_config_t
-// structure. Multi-channel audio is always interleaved. The channel order is from LSB to MSB with
-// regard to the channel mask definition in audio_channels_e e.g :
-// Stereo: left, right
-// 5 point 1: front left, front right, front center, low frequency, back left, back right
-// The buffer size is expressed in frame count, a frame being composed of samples for all
-// channels at a given time. Frame size for unspecified format (AUDIO_FORMAT_OTHER) is 8 bit by
-// definition
-struct audio_buffer_s {
- size_t frameCount; // number of frames in buffer
- union {
- void* raw; // raw pointer to start of buffer
- int32_t* s32; // pointer to signed 32 bit data at start of buffer
- int16_t* s16; // pointer to signed 16 bit data at start of buffer
- uint8_t* u8; // pointer to unsigned 8 bit data at start of buffer
- };
-};
-
-// The buffer_provider_s structure contains functions that can be used
-// by the effect engine process() function to query and release input
-// or output audio buffer.
-// The getBuffer() function is called to retrieve a buffer where data
-// should read from or written to by process() function.
-// The releaseBuffer() function MUST be called when the buffer retrieved
-// with getBuffer() is not needed anymore.
-// The process function should use the buffer provider mechanism to retrieve
-// input or output buffer if the inBuffer or outBuffer passed as argument is NULL
-// and the buffer configuration (buffer_config_t) given by the EFFECT_CMD_CONFIGURE
-// command did not specify an audio buffer.
-
-typedef int32_t (* buffer_function_t)(void *cookie, audio_buffer_t *buffer);
-
-typedef struct buffer_provider_s {
- buffer_function_t getBuffer; // retrieve next buffer
- buffer_function_t releaseBuffer; // release used buffer
- void *cookie; // for use by client of buffer provider functions
-} buffer_provider_t;
-
-
-// The buffer_config_s structure specifies the input or output audio format
-// to be used by the effect engine. It is part of the effect_config_t
-// structure that defines both input and output buffer configurations and is
-// passed by the EFFECT_CMD_CONFIGURE command.
-typedef struct buffer_config_s {
- audio_buffer_t buffer; // buffer for use by process() function if not passed explicitly
- uint32_t samplingRate; // sampling rate
- uint32_t channels; // channel mask (see audio_channels_e)
- buffer_provider_t bufferProvider; // buffer provider
- uint8_t format; // Audio format (see audio_format_e)
- uint8_t accessMode; // read/write or accumulate in buffer (effect_buffer_access_e)
- uint16_t mask; // indicates which of the above fields is valid
-} buffer_config_t;
-
-// Sample format
-enum audio_format_e {
- SAMPLE_FORMAT_PCM_S15, // PCM signed 16 bits
- SAMPLE_FORMAT_PCM_U8, // PCM unsigned 8 bits
- SAMPLE_FORMAT_PCM_S7_24, // PCM signed 7.24 fixed point representation
- SAMPLE_FORMAT_OTHER // other format (e.g. compressed)
-};
-
-// Channel mask
-enum audio_channels_e {
- CHANNEL_FRONT_LEFT = 0x1, // front left channel
- CHANNEL_FRONT_RIGHT = 0x2, // front right channel
- CHANNEL_FRONT_CENTER = 0x4, // front center channel
- CHANNEL_LOW_FREQUENCY = 0x8, // low frequency channel
- CHANNEL_BACK_LEFT = 0x10, // back left channel
- CHANNEL_BACK_RIGHT = 0x20, // back right channel
- CHANNEL_FRONT_LEFT_OF_CENTER = 0x40, // front left of center channel
- CHANNEL_FRONT_RIGHT_OF_CENTER = 0x80, // front right of center channel
- CHANNEL_BACK_CENTER = 0x100, // back center channel
- CHANNEL_MONO = CHANNEL_FRONT_LEFT,
- CHANNEL_STEREO = (CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT),
- CHANNEL_QUAD = (CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
- CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT),
- CHANNEL_SURROUND = (CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
- CHANNEL_FRONT_CENTER | CHANNEL_BACK_CENTER),
- CHANNEL_5POINT1 = (CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
- CHANNEL_FRONT_CENTER | CHANNEL_LOW_FREQUENCY | CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT),
- CHANNEL_7POINT1 = (CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
- CHANNEL_FRONT_CENTER | CHANNEL_LOW_FREQUENCY | CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT |
- CHANNEL_FRONT_LEFT_OF_CENTER | CHANNEL_FRONT_RIGHT_OF_CENTER),
-};
-
-// Render device
-enum audio_device_e {
- DEVICE_EARPIECE = 0x1, // earpiece
- DEVICE_SPEAKER = 0x2, // speaker
- DEVICE_WIRED_HEADSET = 0x4, // wired headset, with microphone
- DEVICE_WIRED_HEADPHONE = 0x8, // wired headphone, without microphone
- DEVICE_BLUETOOTH_SCO = 0x10, // generic bluetooth SCO
- DEVICE_BLUETOOTH_SCO_HEADSET = 0x20, // bluetooth SCO headset
- DEVICE_BLUETOOTH_SCO_CARKIT = 0x40, // bluetooth SCO car kit
- DEVICE_BLUETOOTH_A2DP = 0x80, // generic bluetooth A2DP
- DEVICE_BLUETOOTH_A2DP_HEADPHONES = 0x100, // bluetooth A2DP headphones
- DEVICE_BLUETOOTH_A2DP_SPEAKER = 0x200, // bluetooth A2DP speakers
- DEVICE_AUX_DIGITAL = 0x400, // digital output
- DEVICE_EXTERNAL_SPEAKER = 0x800 // external speaker (stereo and High quality)
-};
-
-// Audio mode
-enum audio_mode_e {
- AUDIO_EFFECT_MODE_NORMAL, // device idle
- AUDIO_EFFECT_MODE_RINGTONE, // device ringing
- AUDIO_EFFECT_MODE_IN_CALL // audio call connected (VoIP or telephony)
-};
-
-// Values for "accessMode" field of buffer_config_t:
-// overwrite, read only, accumulate (read/modify/write)
-enum effect_buffer_access_e {
- EFFECT_BUFFER_ACCESS_WRITE,
- EFFECT_BUFFER_ACCESS_READ,
- EFFECT_BUFFER_ACCESS_ACCUMULATE
-
-};
-
-// Values for bit field "mask" in buffer_config_t. If a bit is set, the corresponding field
-// in buffer_config_t must be taken into account when executing the EFFECT_CMD_CONFIGURE command
-#define EFFECT_CONFIG_BUFFER 0x0001 // buffer field must be taken into account
-#define EFFECT_CONFIG_SMP_RATE 0x0002 // samplingRate field must be taken into account
-#define EFFECT_CONFIG_CHANNELS 0x0004 // channels field must be taken into account
-#define EFFECT_CONFIG_FORMAT 0x0008 // format field must be taken into account
-#define EFFECT_CONFIG_ACC_MODE 0x0010 // accessMode field must be taken into account
-#define EFFECT_CONFIG_PROVIDER 0x0020 // bufferProvider field must be taken into account
-#define EFFECT_CONFIG_ALL (EFFECT_CONFIG_BUFFER | EFFECT_CONFIG_SMP_RATE | \
- EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT | \
- EFFECT_CONFIG_ACC_MODE | EFFECT_CONFIG_PROVIDER)
-
-
-// effect_config_s structure describes the format of the pCmdData argument of EFFECT_CMD_CONFIGURE
-// command to configure audio parameters and buffers for effect engine input and output.
-typedef struct effect_config_s {
- buffer_config_t inputCfg;
- buffer_config_t outputCfg;;
-} effect_config_t;
-
-
-// effect_param_s structure describes the format of the pCmdData argument of EFFECT_CMD_SET_PARAM
-// command and pCmdData and pReplyData of EFFECT_CMD_GET_PARAM command.
-// psize and vsize represent the actual size of parameter and value.
-//
-// NOTE: the start of value field inside the data field is always on a 32 bit boundary:
-//
-// +-----------+
-// | status | sizeof(int)
-// +-----------+
-// | psize | sizeof(int)
-// +-----------+
-// | vsize | sizeof(int)
-// +-----------+
-// | | | |
-// ~ parameter ~ > psize |
-// | | | > ((psize - 1)/sizeof(int) + 1) * sizeof(int)
-// +-----------+ |
-// | padding | |
-// +-----------+
-// | | |
-// ~ value ~ > vsize
-// | | |
-// +-----------+
-
-typedef struct effect_param_s {
- int32_t status; // Transaction status (unused for command, used for reply)
- uint32_t psize; // Parameter size
- uint32_t vsize; // Value size
- char data[]; // Start of Parameter + Value data
-} effect_param_t;
-
-
-/////////////////////////////////////////////////
-// Effect library interface
-/////////////////////////////////////////////////
-
-// An effect library is required to implement and expose the following functions
-// to enable effect enumeration and instantiation. The name of these functions must be as
-// specified here as the effect framework will get the function address with dlsym():
-//
-// - effect_QueryNumberEffects_t EffectQueryNumberEffects;
-// - effect_QueryEffect_t EffectQueryEffect;
-// - effect_CreateEffect_t EffectCreate;
-// - effect_ReleaseEffect_t EffectRelease;
-
-
-////////////////////////////////////////////////////////////////////////////////
-//
-// Function: EffectQueryNumberEffects
-//
-// Description: Returns the number of different effects exposed by the
-// library. Each effect must have a unique effect uuid (see
-// effect_descriptor_t). This function together with EffectQueryEffect()
-// is used to enumerate all effects present in the library.
-//
-// Input/Output:
-// pNumEffects: address where the number of effects should be returned.
-//
-// Output:
-// returned value: 0 successful operation.
-// -ENODEV library failed to initialize
-// -EINVAL invalid pNumEffects
-// *pNumEffects: updated with number of effects in library
-//
-////////////////////////////////////////////////////////////////////////////////
-typedef int32_t (*effect_QueryNumberEffects_t)(uint32_t *pNumEffects);
-
-////////////////////////////////////////////////////////////////////////////////
-//
-// Function: EffectQueryEffect
-//
-// Description: Returns the descriptor of the effect engine which index is
-// given as first argument.
-// See effect_descriptor_t for details on effect descriptors.
-// This function together with EffectQueryNumberEffects() is used to enumerate all
-// effects present in the library. The enumeration sequence is:
-// EffectQueryNumberEffects(&num_effects);
-// for (i = 0; i < num_effects; i++)
-// EffectQueryEffect(i,...);
-//
-// Input/Output:
-// index: index of the effect
-// pDescriptor: address where to return the effect descriptor.
-//
-// Output:
-// returned value: 0 successful operation.
-// -ENODEV library failed to initialize
-// -EINVAL invalid pDescriptor or index
-// -ENOSYS effect list has changed since last execution of
-// EffectQueryNumberEffects()
-// -ENOENT no more effect available
-// *pDescriptor: updated with the effect descriptor.
-//
-////////////////////////////////////////////////////////////////////////////////
-typedef int32_t (*effect_QueryEffect_t)(uint32_t index,
- effect_descriptor_t *pDescriptor);
-
-////////////////////////////////////////////////////////////////////////////////
-//
-// Function: EffectCreate
-//
-// Description: Creates an effect engine of the specified type and returns an
-// effect control interface on this engine. The function will allocate the
-// resources for an instance of the requested effect engine and return
-// a handle on the effect control interface.
-//
-// Input:
-// uuid: pointer to the effect uuid.
-// sessionId: audio session to which this effect instance will be attached. All effects
-// created with the same session ID are connected in series and process the same signal
-// stream. Knowing that two effects are part of the same effect chain can help the
-// library implement some kind of optimizations.
-// ioId: identifies the output or input stream this effect is directed to at audio HAL.
-// For future use especially with tunneled HW accelerated effects
-//
-// Input/Output:
-// pInterface: address where to return the effect interface.
-//
-// Output:
-// returned value: 0 successful operation.
-// -ENODEV library failed to initialize
-// -EINVAL invalid pEffectUuid or pInterface
-// -ENOENT no effect with this uuid found
-// *pInterface: updated with the effect interface handle.
-//
-////////////////////////////////////////////////////////////////////////////////
-typedef int32_t (*effect_CreateEffect_t)(effect_uuid_t *uuid,
- int32_t sessionId,
- int32_t ioId,
- effect_interface_t *pInterface);
-
-////////////////////////////////////////////////////////////////////////////////
-//
-// Function: EffectRelease
-//
-// Description: Releases the effect engine whose handle is given as argument.
-// All resources allocated to this particular instance of the effect are
-// released.
-//
-// Input:
-// interface: handle on the effect interface to be released.
-//
-// Output:
-// returned value: 0 successful operation.
-// -ENODEV library failed to initialize
-// -EINVAL invalid interface handle
-//
-////////////////////////////////////////////////////////////////////////////////
-typedef int32_t (*effect_ReleaseEffect_t)(effect_interface_t interface);
-
-
-#if __cplusplus
-} // extern "C"
-#endif
-
-
-#endif /*ANDROID_EFFECTAPI_H_*/
diff --git a/include/media/EffectBassBoostApi.h b/include/media/EffectBassBoostApi.h
deleted file mode 100644
index 75f8d78..0000000
--- a/include/media/EffectBassBoostApi.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2010 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 ANDROID_EFFECTBASSBOOSTAPI_H_
-#define ANDROID_EFFECTBASSBOOSTAPI_H_
-
-#include <media/EffectApi.h>
-
-#if __cplusplus
-extern "C" {
-#endif
-
-#ifndef OPENSL_ES_H_
-static const effect_uuid_t SL_IID_BASSBOOST_ = { 0x0634f220, 0xddd4, 0x11db, 0xa0fc, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
-const effect_uuid_t * const SL_IID_BASSBOOST = &SL_IID_BASSBOOST_;
-#endif //OPENSL_ES_H_
-
-/* enumerated parameter settings for BassBoost effect */
-typedef enum
-{
- BASSBOOST_PARAM_STRENGTH_SUPPORTED,
- BASSBOOST_PARAM_STRENGTH
-} t_bassboost_params;
-
-#if __cplusplus
-} // extern "C"
-#endif
-
-
-#endif /*ANDROID_EFFECTBASSBOOSTAPI_H_*/
diff --git a/include/media/EffectEnvironmentalReverbApi.h b/include/media/EffectEnvironmentalReverbApi.h
deleted file mode 100644
index 36accd8..0000000
--- a/include/media/EffectEnvironmentalReverbApi.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2010 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 ANDROID_EFFECTENVIRONMENTALREVERBAPI_H_
-#define ANDROID_EFFECTENVIRONMENTALREVERBAPI_H_
-
-#include <media/EffectApi.h>
-
-#if __cplusplus
-extern "C" {
-#endif
-
-#ifndef OPENSL_ES_H_
-static const effect_uuid_t SL_IID_ENVIRONMENTALREVERB_ = { 0xc2e5d5f0, 0x94bd, 0x4763, 0x9cac, { 0x4e, 0x23, 0x4d, 0x6, 0x83, 0x9e } };
-const effect_uuid_t * const SL_IID_ENVIRONMENTALREVERB = &SL_IID_ENVIRONMENTALREVERB_;
-#endif //OPENSL_ES_H_
-
-/* enumerated parameter settings for environmental reverb effect */
-typedef enum
-{
- // Parameters below are as defined in OpenSL ES specification for environmental reverb interface
- REVERB_PARAM_ROOM_LEVEL, // in millibels, range -6000 to 0
- REVERB_PARAM_ROOM_HF_LEVEL, // in millibels, range -4000 to 0
- REVERB_PARAM_DECAY_TIME, // in milliseconds, range 100 to 20000
- REVERB_PARAM_DECAY_HF_RATIO, // in permilles, range 100 to 1000
- REVERB_PARAM_REFLECTIONS_LEVEL, // in millibels, range -6000 to 0
- REVERB_PARAM_REFLECTIONS_DELAY, // in milliseconds, range 0 to 65
- REVERB_PARAM_REVERB_LEVEL, // in millibels, range -6000 to 0
- REVERB_PARAM_REVERB_DELAY, // in milliseconds, range 0 to 65
- REVERB_PARAM_DIFFUSION, // in permilles, range 0 to 1000
- REVERB_PARAM_DENSITY, // in permilles, range 0 to 1000
- REVERB_PARAM_PROPERTIES,
- REVERB_PARAM_BYPASS
-} t_env_reverb_params;
-
-//t_reverb_settings is equal to SLEnvironmentalReverbSettings defined in OpenSL ES specification.
-typedef struct s_reverb_settings {
- int16_t roomLevel;
- int16_t roomHFLevel;
- uint32_t decayTime;
- int16_t decayHFRatio;
- int16_t reflectionsLevel;
- uint32_t reflectionsDelay;
- int16_t reverbLevel;
- uint32_t reverbDelay;
- int16_t diffusion;
- int16_t density;
-} __attribute__((packed)) t_reverb_settings;
-
-
-#if __cplusplus
-} // extern "C"
-#endif
-
-
-#endif /*ANDROID_EFFECTENVIRONMENTALREVERBAPI_H_*/
diff --git a/include/media/EffectEqualizerApi.h b/include/media/EffectEqualizerApi.h
deleted file mode 100644
index 0492ea0..0000000
--- a/include/media/EffectEqualizerApi.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2010 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 ANDROID_EFFECTEQUALIZERAPI_H_
-#define ANDROID_EFFECTEQUALIZERAPI_H_
-
-#include <media/EffectApi.h>
-
-#ifndef OPENSL_ES_H_
-static const effect_uuid_t SL_IID_EQUALIZER_ = { 0x0bed4300, 0xddd6, 0x11db, 0x8f34, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
-const effect_uuid_t * const SL_IID_EQUALIZER = &SL_IID_EQUALIZER_;
-#endif //OPENSL_ES_H_
-
-#if __cplusplus
-extern "C" {
-#endif
-
-/* enumerated parameters for Equalizer effect */
-typedef enum
-{
- EQ_PARAM_NUM_BANDS, // Gets the number of frequency bands that the equalizer supports.
- EQ_PARAM_LEVEL_RANGE, // Returns the minimum and maximum band levels supported.
- EQ_PARAM_BAND_LEVEL, // Gets/Sets the gain set for the given equalizer band.
- EQ_PARAM_CENTER_FREQ, // Gets the center frequency of the given band.
- EQ_PARAM_BAND_FREQ_RANGE, // Gets the frequency range of the given frequency band.
- EQ_PARAM_GET_BAND, // Gets the band that has the most effect on the given frequency.
- EQ_PARAM_CUR_PRESET, // Gets/Sets the current preset.
- EQ_PARAM_GET_NUM_OF_PRESETS, // Gets the total number of presets the equalizer supports.
- EQ_PARAM_GET_PRESET_NAME, // Gets the preset name based on the index.
- EQ_PARAM_PROPERTIES // Gets/Sets all parameters at a time.
-} t_equalizer_params;
-
-//t_equalizer_settings groups all current equalizer setting for backup and restore.
-typedef struct s_equalizer_settings {
- uint16_t curPreset;
- uint16_t numBands;
- uint16_t bandLevels[];
-} t_equalizer_settings;
-
-#if __cplusplus
-} // extern "C"
-#endif
-
-
-#endif /*ANDROID_EFFECTEQUALIZERAPI_H_*/
diff --git a/include/media/EffectPresetReverbApi.h b/include/media/EffectPresetReverbApi.h
deleted file mode 100644
index a3f094c..0000000
--- a/include/media/EffectPresetReverbApi.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2010 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 ANDROID_EFFECTPRESETREVERBAPI_H_
-#define ANDROID_EFFECTPRESETREVERBAPI_H_
-
-#include <media/EffectApi.h>
-
-#if __cplusplus
-extern "C" {
-#endif
-
-#ifndef OPENSL_ES_H_
-static const effect_uuid_t SL_IID_PRESETREVERB_ = { 0x47382d60, 0xddd8, 0x11db, 0xbf3a, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
-const effect_uuid_t * const SL_IID_PRESETREVERB = &SL_IID_PRESETREVERB_;
-#endif //OPENSL_ES_H_
-
-/* enumerated parameter settings for preset reverb effect */
-typedef enum
-{
- REVERB_PARAM_PRESET
-} t_preset_reverb_params;
-
-
-typedef enum
-{
- REVERB_PRESET_NONE,
- REVERB_PRESET_SMALLROOM,
- REVERB_PRESET_MEDIUMROOM,
- REVERB_PRESET_LARGEROOM,
- REVERB_PRESET_MEDIUMHALL,
- REVERB_PRESET_LARGEHALL,
- REVERB_PRESET_PLATE,
- REVERB_PRESET_LAST = REVERB_PRESET_PLATE
-} t_reverb_presets;
-
-#if __cplusplus
-} // extern "C"
-#endif
-
-
-#endif /*ANDROID_EFFECTPRESETREVERBAPI_H_*/
diff --git a/include/media/EffectVirtualizerApi.h b/include/media/EffectVirtualizerApi.h
deleted file mode 100644
index c3d5131..0000000
--- a/include/media/EffectVirtualizerApi.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2010 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 ANDROID_EFFECTVIRTUALIZERAPI_H_
-#define ANDROID_EFFECTVIRTUALIZERAPI_H_
-
-#include <media/EffectApi.h>
-
-#if __cplusplus
-extern "C" {
-#endif
-
-#ifndef OPENSL_ES_H_
-static const effect_uuid_t SL_IID_VIRTUALIZER_ = { 0x37cc2c00, 0xdddd, 0x11db, 0x8577, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
-const effect_uuid_t * const SL_IID_VIRTUALIZER = &SL_IID_VIRTUALIZER_;
-#endif //OPENSL_ES_H_
-
-/* enumerated parameter settings for virtualizer effect */
-typedef enum
-{
- VIRTUALIZER_PARAM_STRENGTH_SUPPORTED,
- VIRTUALIZER_PARAM_STRENGTH
-} t_virtualizer_params;
-
-#if __cplusplus
-} // extern "C"
-#endif
-
-
-#endif /*ANDROID_EFFECTVIRTUALIZERAPI_H_*/
diff --git a/include/media/EffectVisualizerApi.h b/include/media/EffectVisualizerApi.h
deleted file mode 100644
index bef1a4f..0000000
--- a/include/media/EffectVisualizerApi.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2010 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 ANDROID_EFFECTVISUALIZERAPI_H_
-#define ANDROID_EFFECTVISUALIZERAPI_H_
-
-#include <media/EffectApi.h>
-
-#if __cplusplus
-extern "C" {
-#endif
-
-#ifndef OPENSL_ES_H_
-static const effect_uuid_t SL_IID_VISUALIZATION_ =
- { 0xe46b26a0, 0xdddd, 0x11db, 0x8afd, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
-const effect_uuid_t * const SL_IID_VISUALIZATION = &SL_IID_VISUALIZATION_;
-#endif //OPENSL_ES_H_
-
-#define VISUALIZER_CAPTURE_SIZE_MAX 1024 // maximum capture size in samples
-#define VISUALIZER_CAPTURE_SIZE_MIN 128 // minimum capture size in samples
-
-/* enumerated parameters for Visualizer effect */
-typedef enum
-{
- VISU_PARAM_CAPTURE_SIZE, // Sets the number PCM samples in the capture.
-} t_visualizer_params;
-
-/* commands */
-typedef enum
-{
- VISU_CMD_CAPTURE = EFFECT_CMD_FIRST_PROPRIETARY, // Gets the latest PCM capture.
-}t_visualizer_cmds;
-
-// VISU_CMD_CAPTURE retrieves the latest PCM snapshot captured by the visualizer engine.
-// It returns the number of samples specified by VISU_PARAM_CAPTURE_SIZE
-// in 8 bit unsigned format (0 = 0x80)
-
-#if __cplusplus
-} // extern "C"
-#endif
-
-
-#endif /*ANDROID_EFFECTVISUALIZERAPI_H_*/
diff --git a/include/media/EffectsFactoryApi.h b/include/media/EffectsFactoryApi.h
index 0ed1a14..8ae13cc 100644
--- a/include/media/EffectsFactoryApi.h
+++ b/include/media/EffectsFactoryApi.h
@@ -20,7 +20,7 @@
#include <errno.h>
#include <stdint.h>
#include <sys/types.h>
-#include <media/EffectApi.h>
+#include <hardware/audio_effect.h>
#if __cplusplus
extern "C" {
@@ -99,17 +99,17 @@
// use especially with tunneled HW accelerated effects
//
// Input/Output:
-// pInterface: address where to return the effect interface.
+// pHandle: address where to return the effect handle.
//
// Output:
// returned value: 0 successful operation.
// -ENODEV factory failed to initialize
-// -EINVAL invalid pEffectUuid or pInterface
+// -EINVAL invalid pEffectUuid or pHandle
// -ENOENT no effect with this uuid found
-// *pInterface: updated with the effect interface.
+// *pHandle: updated with the effect handle.
//
////////////////////////////////////////////////////////////////////////////////
-int EffectCreate(effect_uuid_t *pEffectUuid, int32_t sessionId, int32_t ioId, effect_interface_t *pInterface);
+int EffectCreate(effect_uuid_t *pEffectUuid, int32_t sessionId, int32_t ioId, effect_handle_t *pHandle);
////////////////////////////////////////////////////////////////////////////////
//
@@ -120,7 +120,7 @@
// released.
//
// Input:
-// interface: handler on the effect interface to be released.
+// handle: handler on the effect interface to be released.
//
// Output:
// returned value: 0 successful operation.
@@ -128,51 +128,7 @@
// -EINVAL invalid interface handler
//
////////////////////////////////////////////////////////////////////////////////
-int EffectRelease(effect_interface_t interface);
-
-////////////////////////////////////////////////////////////////////////////////
-//
-// Function: EffectLoadLibrary
-//
-// Description: Loads the effect library which path is given as first argument.
-// This must be the full path of a dynamic library (.so) implementing one or
-// more effect engines and exposing the effect library interface described in
-// EffectApi.h. The function returns a handle on the library for used by
-// further call to EffectUnloadLibrary() to unload the library.
-//
-// Input:
-// libPath: full path of the dynamic library file in the file system.
-//
-// handle: address where to return the library handle
-//
-// Output:
-// returned value: 0 successful operation.
-// -ENODEV effect factory not initialized or
-// library could not be loaded or
-// library does not implement required functions
-// -EINVAL invalid libPath string or handle
-//
-////////////////////////////////////////////////////////////////////////////////
-int EffectLoadLibrary(const char *libPath, int *handle);
-
-////////////////////////////////////////////////////////////////////////////////
-//
-// Function: EffectUnloadLibrary
-//
-// Description: Unloads the effect library which handle is given as argument.
-//
-// Input:
-// handle: library handle
-//
-// Output:
-// returned value: 0 successful operation.
-// -ENODEV effect factory not initialized
-// -ENOENT invalid handle
-//
-////////////////////////////////////////////////////////////////////////////////
-int EffectUnloadLibrary(int handle);
-
-
+int EffectRelease(effect_handle_t handle);
////////////////////////////////////////////////////////////////////////////////
//
diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h
index 589f7cd..4037c46 100644
--- a/include/media/IAudioFlinger.h
+++ b/include/media/IAudioFlinger.h
@@ -27,7 +27,7 @@
#include <media/IAudioTrack.h>
#include <media/IAudioRecord.h>
#include <media/IAudioFlingerClient.h>
-#include <media/EffectApi.h>
+#include <hardware/audio_effect.h>
#include <media/IEffect.h>
#include <media/IEffectClient.h>
#include <utils/String8.h>
@@ -48,8 +48,8 @@
pid_t pid,
int streamType,
uint32_t sampleRate,
- int format,
- int channelCount,
+ uint32_t format,
+ uint32_t channelMask,
int frameCount,
uint32_t flags,
const sp<IMemory>& sharedBuffer,
@@ -61,8 +61,8 @@
pid_t pid,
int input,
uint32_t sampleRate,
- int format,
- int channelCount,
+ uint32_t format,
+ uint32_t channelMask,
int frameCount,
uint32_t flags,
int *sessionId,
@@ -73,7 +73,7 @@
*/
virtual uint32_t sampleRate(int output) const = 0;
virtual int channelCount(int output) const = 0;
- virtual int format(int output) const = 0;
+ virtual uint32_t format(int output) const = 0;
virtual size_t frameCount(int output) const = 0;
virtual uint32_t latency(int output) const = 0;
@@ -139,10 +139,6 @@
virtual int newAudioSessionId() = 0;
- virtual status_t loadEffectLibrary(const char *libPath, int *handle) = 0;
-
- virtual status_t unloadEffectLibrary(int handle) = 0;
-
virtual status_t queryNumberEffects(uint32_t *numEffects) = 0;
virtual status_t queryEffect(uint32_t index, effect_descriptor_t *pDescriptor) = 0;
diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h
index 720a562..ed265e1 100644
--- a/include/media/IAudioPolicyService.h
+++ b/include/media/IAudioPolicyService.h
@@ -26,6 +26,7 @@
#include <binder/IInterface.h>
#include <media/AudioSystem.h>
+#include <system/audio_policy.h>
namespace android {
@@ -39,50 +40,54 @@
//
// IAudioPolicyService interface (see AudioPolicyInterface for method descriptions)
//
- virtual status_t setDeviceConnectionState(AudioSystem::audio_devices device,
- AudioSystem::device_connection_state state,
+ virtual status_t setDeviceConnectionState(audio_devices_t device,
+ audio_policy_dev_state_t state,
const char *device_address) = 0;
- virtual AudioSystem::device_connection_state getDeviceConnectionState(AudioSystem::audio_devices device,
+ virtual audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device,
const char *device_address) = 0;
virtual status_t setPhoneState(int state) = 0;
virtual status_t setRingerMode(uint32_t mode, uint32_t mask) = 0;
- virtual status_t setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config) = 0;
- virtual AudioSystem::forced_config getForceUse(AudioSystem::force_use usage) = 0;
- virtual audio_io_handle_t getOutput(AudioSystem::stream_type stream,
+ virtual status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config) = 0;
+ virtual audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage) = 0;
+ virtual audio_io_handle_t getOutput(audio_stream_type_t stream,
uint32_t samplingRate = 0,
- uint32_t format = AudioSystem::FORMAT_DEFAULT,
+ uint32_t format = AUDIO_FORMAT_DEFAULT,
uint32_t channels = 0,
- AudioSystem::output_flags flags = AudioSystem::OUTPUT_FLAG_INDIRECT) = 0;
+ audio_policy_output_flags_t flags = AUDIO_POLICY_OUTPUT_FLAG_INDIRECT) = 0;
virtual status_t startOutput(audio_io_handle_t output,
- AudioSystem::stream_type stream,
+ audio_stream_type_t stream,
int session = 0) = 0;
virtual status_t stopOutput(audio_io_handle_t output,
- AudioSystem::stream_type stream,
+ audio_stream_type_t stream,
int session = 0) = 0;
virtual void releaseOutput(audio_io_handle_t output) = 0;
virtual audio_io_handle_t getInput(int inputSource,
uint32_t samplingRate = 0,
- uint32_t format = AudioSystem::FORMAT_DEFAULT,
+ uint32_t format = AUDIO_FORMAT_DEFAULT,
uint32_t channels = 0,
- AudioSystem::audio_in_acoustics acoustics = (AudioSystem::audio_in_acoustics)0) = 0;
+ audio_in_acoustics_t acoustics = (audio_in_acoustics_t)0,
+ int audioSession = 0) = 0;
virtual status_t startInput(audio_io_handle_t input) = 0;
virtual status_t stopInput(audio_io_handle_t input) = 0;
virtual void releaseInput(audio_io_handle_t input) = 0;
- virtual status_t initStreamVolume(AudioSystem::stream_type stream,
+ virtual status_t initStreamVolume(audio_stream_type_t stream,
int indexMin,
int indexMax) = 0;
- virtual status_t setStreamVolumeIndex(AudioSystem::stream_type stream, int index) = 0;
- virtual status_t getStreamVolumeIndex(AudioSystem::stream_type stream, int *index) = 0;
- virtual uint32_t getStrategyForStream(AudioSystem::stream_type stream) = 0;
- virtual uint32_t getDevicesForStream(AudioSystem::stream_type stream) = 0;
+ virtual status_t setStreamVolumeIndex(audio_stream_type_t stream, int index) = 0;
+ virtual status_t getStreamVolumeIndex(audio_stream_type_t stream, int *index) = 0;
+ virtual uint32_t getStrategyForStream(audio_stream_type_t stream) = 0;
+ virtual uint32_t getDevicesForStream(audio_stream_type_t stream) = 0;
virtual audio_io_handle_t getOutputForEffect(effect_descriptor_t *desc) = 0;
virtual status_t registerEffect(effect_descriptor_t *desc,
- audio_io_handle_t output,
+ audio_io_handle_t io,
uint32_t strategy,
int session,
int id) = 0;
virtual status_t unregisterEffect(int id) = 0;
virtual bool isStreamActive(int stream, uint32_t inPastMs = 0) const = 0;
+ virtual status_t queryDefaultPreProcessing(int audioSession,
+ effect_descriptor_t *descriptors,
+ uint32_t *count) = 0;
};
diff --git a/include/media/IMediaMetadataRetriever.h b/include/media/IMediaMetadataRetriever.h
index 8e3cdbb..1c1c268 100644
--- a/include/media/IMediaMetadataRetriever.h
+++ b/include/media/IMediaMetadataRetriever.h
@@ -18,10 +18,11 @@
#ifndef ANDROID_IMEDIAMETADATARETRIEVER_H
#define ANDROID_IMEDIAMETADATARETRIEVER_H
-#include <utils/RefBase.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>
#include <binder/IMemory.h>
+#include <utils/KeyedVector.h>
+#include <utils/RefBase.h>
namespace android {
@@ -30,7 +31,11 @@
public:
DECLARE_META_INTERFACE(MediaMetadataRetriever);
virtual void disconnect() = 0;
- virtual status_t setDataSource(const char* srcUrl) = 0;
+
+ virtual status_t setDataSource(
+ const char *srcUrl,
+ const KeyedVector<String8, String8> *headers = NULL) = 0;
+
virtual status_t setDataSource(int fd, int64_t offset, int64_t length) = 0;
virtual sp<IMemory> getFrameAtTime(int64_t timeUs, int option) = 0;
virtual sp<IMemory> extractAlbumArt() = 0;
diff --git a/include/media/IMediaPlayer.h b/include/media/IMediaPlayer.h
index 70519ef..d552b2e 100644
--- a/include/media/IMediaPlayer.h
+++ b/include/media/IMediaPlayer.h
@@ -24,7 +24,6 @@
namespace android {
class Parcel;
-class ISurface;
class Surface;
class ISurfaceTexture;
@@ -52,6 +51,8 @@
virtual status_t setVolume(float leftVolume, float rightVolume) = 0;
virtual status_t setAuxEffectSendLevel(float level) = 0;
virtual status_t attachAuxEffect(int effectId) = 0;
+ virtual status_t setParameter(int key, const Parcel& request) = 0;
+ virtual status_t getParameter(int key, Parcel* reply) = 0;
// Invoke a generic method on the player by using opaque parcels
// for the request and reply.
diff --git a/include/media/IMediaPlayerClient.h b/include/media/IMediaPlayerClient.h
index eee6c97..daec1c7 100644
--- a/include/media/IMediaPlayerClient.h
+++ b/include/media/IMediaPlayerClient.h
@@ -28,7 +28,7 @@
public:
DECLARE_META_INTERFACE(MediaPlayerClient);
- virtual void notify(int msg, int ext1, int ext2) = 0;
+ virtual void notify(int msg, int ext1, int ext2, const Parcel *obj) = 0;
};
// ----------------------------------------------------------------------------
diff --git a/include/media/IMediaRecorder.h b/include/media/IMediaRecorder.h
index 28be7c1..ec84e25 100644
--- a/include/media/IMediaRecorder.h
+++ b/include/media/IMediaRecorder.h
@@ -24,35 +24,38 @@
class Surface;
class ICamera;
+class ICameraRecordingProxy;
class IMediaRecorderClient;
+class ISurfaceTexture;
class IMediaRecorder: public IInterface
{
public:
DECLARE_META_INTERFACE(MediaRecorder);
- virtual status_t setCamera(const sp<ICamera>& camera) = 0;
- virtual status_t setPreviewSurface(const sp<Surface>& surface) = 0;
- virtual status_t setVideoSource(int vs) = 0;
- virtual status_t setAudioSource(int as) = 0;
- virtual status_t setOutputFormat(int of) = 0;
- virtual status_t setVideoEncoder(int ve) = 0;
- virtual status_t setAudioEncoder(int ae) = 0;
- virtual status_t setOutputFile(const char* path) = 0;
- virtual status_t setOutputFile(int fd, int64_t offset, int64_t length) = 0;
- virtual status_t setOutputFileAuxiliary(int fd) = 0;
- virtual status_t setVideoSize(int width, int height) = 0;
- virtual status_t setVideoFrameRate(int frames_per_second) = 0;
- virtual status_t setParameters(const String8& params) = 0;
- virtual status_t setListener(const sp<IMediaRecorderClient>& listener) = 0;
- virtual status_t prepare() = 0;
- virtual status_t getMaxAmplitude(int* max) = 0;
- virtual status_t start() = 0;
- virtual status_t stop() = 0;
- virtual status_t reset() = 0;
- virtual status_t init() = 0;
- virtual status_t close() = 0;
- virtual status_t release() = 0;
+ virtual status_t setCamera(const sp<ICamera>& camera,
+ const sp<ICameraRecordingProxy>& proxy) = 0;
+ virtual status_t setPreviewSurface(const sp<Surface>& surface) = 0;
+ virtual status_t setVideoSource(int vs) = 0;
+ virtual status_t setAudioSource(int as) = 0;
+ virtual status_t setOutputFormat(int of) = 0;
+ virtual status_t setVideoEncoder(int ve) = 0;
+ virtual status_t setAudioEncoder(int ae) = 0;
+ virtual status_t setOutputFile(const char* path) = 0;
+ virtual status_t setOutputFile(int fd, int64_t offset, int64_t length) = 0;
+ virtual status_t setVideoSize(int width, int height) = 0;
+ virtual status_t setVideoFrameRate(int frames_per_second) = 0;
+ virtual status_t setParameters(const String8& params) = 0;
+ virtual status_t setListener(const sp<IMediaRecorderClient>& listener) = 0;
+ virtual status_t prepare() = 0;
+ virtual status_t getMaxAmplitude(int* max) = 0;
+ virtual status_t start() = 0;
+ virtual status_t stop() = 0;
+ virtual status_t reset() = 0;
+ virtual status_t init() = 0;
+ virtual status_t close() = 0;
+ virtual status_t release() = 0;
+ virtual sp<ISurfaceTexture> querySurfaceMediaSource() = 0;
};
// ----------------------------------------------------------------------------
diff --git a/include/media/IOMX.h b/include/media/IOMX.h
index 16a9342..02ad703 100644
--- a/include/media/IOMX.h
+++ b/include/media/IOMX.h
@@ -33,7 +33,6 @@
class IMemory;
class IOMXObserver;
class IOMXRenderer;
-class ISurface;
class Surface;
class IOMX : public IInterface {
@@ -185,6 +184,11 @@
uint32_t flags = 0);
};
+struct CodecProfileLevel {
+ OMX_U32 mProfile;
+ OMX_U32 mLevel;
+};
+
} // namespace android
#endif // ANDROID_IOMX_H_
diff --git a/include/media/IStreamSource.h b/include/media/IStreamSource.h
index d310cee..cc63356 100644
--- a/include/media/IStreamSource.h
+++ b/include/media/IStreamSource.h
@@ -51,6 +51,17 @@
// will be suppressed until media time reaches this timestamp.
static const char *const kKeyResumeAtPTS;
+ // When signalling a discontinuity you can optionally
+ // signal that this is a "hard" discontinuity, i.e. the format
+ // or configuration of subsequent stream data differs from that
+ // currently active. To do so, include a non-zero int32_t value
+ // under the key "kKeyFormatChange" when issuing the DISCONTINUITY
+ // command.
+ // The new logical stream must start with proper codec initialization
+ // information for playback to continue, i.e. SPS and PPS in the case
+ // of AVC video etc.
+ static const char *const kKeyFormatChange;
+
virtual void issueCommand(
Command cmd, bool synchronous, const sp<AMessage> &msg = NULL) = 0;
};
diff --git a/include/media/MediaMetadataRetrieverInterface.h b/include/media/MediaMetadataRetrieverInterface.h
index 0449122..27b7e4d 100644
--- a/include/media/MediaMetadataRetrieverInterface.h
+++ b/include/media/MediaMetadataRetrieverInterface.h
@@ -30,7 +30,11 @@
public:
MediaMetadataRetrieverBase() {}
virtual ~MediaMetadataRetrieverBase() {}
- virtual status_t setDataSource(const char *url) = 0;
+
+ virtual status_t setDataSource(
+ const char *url,
+ const KeyedVector<String8, String8> *headers = NULL) = 0;
+
virtual status_t setDataSource(int fd, int64_t offset, int64_t length) = 0;
virtual VideoFrame* getFrameAtTime(int64_t timeUs, int option) = 0;
virtual MediaAlbumArt* extractAlbumArt() = 0;
diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h
index 117d7eb..4328d3c 100644
--- a/include/media/MediaPlayerInterface.h
+++ b/include/media/MediaPlayerInterface.h
@@ -32,7 +32,6 @@
namespace android {
class Parcel;
-class ISurface;
class Surface;
class ISurfaceTexture;
@@ -56,7 +55,8 @@
// callback mechanism for passing messages to MediaPlayer object
-typedef void (*notify_callback_f)(void* cookie, int msg, int ext1, int ext2);
+typedef void (*notify_callback_f)(void* cookie,
+ int msg, int ext1, int ext2, const Parcel *obj);
// abstract base class - use MediaPlayerInterface
class MediaPlayerBase : public RefBase
@@ -85,7 +85,7 @@
// audio data.
virtual status_t open(
uint32_t sampleRate, int channelCount,
- int format=AudioSystem::PCM_16_BIT,
+ int format=AUDIO_FORMAT_PCM_16_BIT,
int bufferCount=DEFAULT_AUDIOSINK_BUFFERCOUNT,
AudioCallback cb = NULL,
void *cookie = NULL) = 0;
@@ -103,6 +103,10 @@
virtual status_t initCheck() = 0;
virtual bool hardwareOutput() = 0;
+ virtual status_t setUID(uid_t uid) {
+ return INVALID_OPERATION;
+ }
+
virtual status_t setDataSource(
const char *url,
const KeyedVector<String8, String8> *headers = NULL) = 0;
@@ -132,6 +136,8 @@
virtual status_t reset() = 0;
virtual status_t setLooping(int loop) = 0;
virtual player_type playerType() = 0;
+ virtual status_t setParameter(int key, const Parcel &request) = 0;
+ virtual status_t getParameter(int key, Parcel *reply) = 0;
// Invoke a generic method on the player by using opaque parcels
// for the request and reply.
@@ -160,9 +166,14 @@
mCookie = cookie; mNotify = notifyFunc;
}
- void sendEvent(int msg, int ext1=0, int ext2=0) {
+ void sendEvent(int msg, int ext1=0, int ext2=0,
+ const Parcel *obj=NULL) {
Mutex::Autolock autoLock(mNotifyLock);
- if (mNotify) mNotify(mCookie, msg, ext1, ext2);
+ if (mNotify) mNotify(mCookie, msg, ext1, ext2, obj);
+ }
+
+ virtual status_t dump(int fd, const Vector<String16> &args) const {
+ return INVALID_OPERATION;
}
private:
diff --git a/include/media/MediaProfiles.h b/include/media/MediaProfiles.h
index f2107ec..69d5001 100644
--- a/include/media/MediaProfiles.h
+++ b/include/media/MediaProfiles.h
@@ -45,6 +45,18 @@
CAMCORDER_QUALITY_TIME_LAPSE_LIST_END = 1006,
};
+/**
+ *Set CIF as default maximum import and export resolution of video editor.
+ *The maximum import and export resolutions are platform specific,
+ *which should be defined in media_profiles.xml.
+ */
+enum videoeditor_capability {
+ VIDEOEDITOR_DEFAULT_MAX_INPUT_FRAME_WIDTH = 352,
+ VIDEOEDITOR_DEFUALT_MAX_INPUT_FRAME_HEIGHT = 288,
+ VIDEOEDITOR_DEFAULT_MAX_OUTPUT_FRAME_WIDTH = 352,
+ VIDEOEDITOR_DEFUALT_MAX_OUTPUT_FRAME_HEIGHT = 288,
+};
+
enum video_decoder {
VIDEO_DECODER_WMV,
};
@@ -117,6 +129,17 @@
int getVideoEncoderParamByName(const char *name, video_encoder codec) const;
/**
+ * Returns the value for the given param name for the video editor cap
+ * param or -1 if error.
+ * Supported param name are:
+ * videoeditor.input.width.max - max input video frame width
+ * videoeditor.input.height.max - max input video frame height
+ * videoeditor.output.width.max - max output video frame width
+ * videoeditor.output.height.max - max output video frame height
+ */
+ int getVideoEditorCapParamByName(const char *name) const;
+
+ /**
* Returns the audio encoders supported.
*/
Vector<audio_encoder> getAudioEncoders() const;
@@ -150,6 +173,12 @@
*/
Vector<int> getImageEncodingQualityLevels(int cameraId) const;
+ /**
+ * Returns the start time offset (in ms) for the given camera Id.
+ * If the given camera Id does not exist, -1 will be returned.
+ */
+ int getStartTimeOffsetMs(int cameraId) const;
+
private:
enum {
// Camcorder profiles (high/low) and timelapse profiles (high/low)
@@ -158,7 +187,7 @@
MediaProfiles& operator=(const MediaProfiles&); // Don't call me
MediaProfiles(const MediaProfiles&); // Don't call me
- MediaProfiles() {} // Dummy default constructor
+ MediaProfiles() { mVideoEditorCap = NULL; } // Dummy default constructor
~MediaProfiles(); // Don't delete me
struct VideoCodec {
@@ -304,6 +333,22 @@
Vector<int> mLevels;
};
+ struct VideoEditorCap {
+ VideoEditorCap(int inFrameWidth, int inFrameHeight,
+ int outFrameWidth, int outFrameHeight)
+ : mMaxInputFrameWidth(inFrameWidth),
+ mMaxInputFrameHeight(inFrameHeight),
+ mMaxOutputFrameWidth(outFrameWidth),
+ mMaxOutputFrameHeight(outFrameHeight) {}
+
+ ~VideoEditorCap() {}
+
+ int mMaxInputFrameWidth;
+ int mMaxInputFrameHeight;
+ int mMaxOutputFrameWidth;
+ int mMaxOutputFrameHeight;
+ };
+
int getCamcorderProfileIndex(int cameraId, camcorder_quality quality) const;
void initRequiredProfileRefs(const Vector<int>& cameraIds);
int getRequiredProfileRefIndex(int cameraId);
@@ -315,6 +360,7 @@
static void logAudioEncoderCap(const AudioEncoderCap& cap);
static void logVideoDecoderCap(const VideoDecoderCap& cap);
static void logAudioDecoderCap(const AudioDecoderCap& cap);
+ static void logVideoEditorCap(const VideoEditorCap& cap);
// If the xml configuration file does exist, use the settings
// from the xml
@@ -326,12 +372,16 @@
static VideoDecoderCap* createVideoDecoderCap(const char **atts);
static VideoEncoderCap* createVideoEncoderCap(const char **atts);
static AudioEncoderCap* createAudioEncoderCap(const char **atts);
+ static VideoEditorCap* createVideoEditorCap(
+ const char **atts, MediaProfiles *profiles);
static CamcorderProfile* createCamcorderProfile(
int cameraId, const char **atts, Vector<int>& cameraIds);
static int getCameraId(const char **atts);
+ void addStartTimeOffset(int cameraId, const char **atts);
+
ImageEncodingQualityLevels* findImageEncodingQualityLevels(int cameraId) const;
void addImageEncodingQualityLevel(int cameraId, const char** atts);
@@ -367,6 +417,7 @@
static void createDefaultEncoderOutputFileFormats(MediaProfiles *profiles);
static void createDefaultImageEncodingQualityLevels(MediaProfiles *profiles);
static void createDefaultImageDecodingMaxMemory(MediaProfiles *profiles);
+ static void createDefaultVideoEditorCap(MediaProfiles *profiles);
static VideoEncoderCap* createDefaultH263VideoEncoderCap();
static VideoEncoderCap* createDefaultM4vVideoEncoderCap();
static AudioEncoderCap* createDefaultAmrNBEncoderCap();
@@ -408,6 +459,7 @@
Vector<VideoDecoderCap*> mVideoDecoders;
Vector<output_format> mEncoderOutputFileFormats;
Vector<ImageEncodingQualityLevels *> mImageEncodingQualityLevels;
+ KeyedVector<int, int> mStartTimeOffsets;
typedef struct {
bool mHasRefProfile; // Refers to an existing profile
@@ -422,6 +474,7 @@
RequiredProfiles *mRequiredProfileRefs;
Vector<int> mCameraIds;
+ VideoEditorCap* mVideoEditorCap;
};
}; // namespace android
diff --git a/include/media/MediaRecorderBase.h b/include/media/MediaRecorderBase.h
index c42346e..ef799f5 100644
--- a/include/media/MediaRecorderBase.h
+++ b/include/media/MediaRecorderBase.h
@@ -20,23 +20,28 @@
#include <media/mediarecorder.h>
+#include <system/audio.h>
+
namespace android {
+class ICameraRecordingProxy;
class Surface;
+class ISurfaceTexture;
struct MediaRecorderBase {
MediaRecorderBase() {}
virtual ~MediaRecorderBase() {}
virtual status_t init() = 0;
- virtual status_t setAudioSource(audio_source as) = 0;
+ virtual status_t setAudioSource(audio_source_t as) = 0;
virtual status_t setVideoSource(video_source vs) = 0;
virtual status_t setOutputFormat(output_format of) = 0;
virtual status_t setAudioEncoder(audio_encoder ae) = 0;
virtual status_t setVideoEncoder(video_encoder ve) = 0;
virtual status_t setVideoSize(int width, int height) = 0;
virtual status_t setVideoFrameRate(int frames_per_second) = 0;
- virtual status_t setCamera(const sp<ICamera>& camera) = 0;
+ virtual status_t setCamera(const sp<ICamera>& camera,
+ const sp<ICameraRecordingProxy>& proxy) = 0;
virtual status_t setPreviewSurface(const sp<Surface>& surface) = 0;
virtual status_t setOutputFile(const char *path) = 0;
virtual status_t setOutputFile(int fd, int64_t offset, int64_t length) = 0;
@@ -50,6 +55,7 @@
virtual status_t reset() = 0;
virtual status_t getMaxAmplitude(int *max) = 0;
virtual status_t dump(int fd, const Vector<String16>& args) const = 0;
+ virtual sp<ISurfaceTexture> querySurfaceMediaSource() const = 0;
private:
MediaRecorderBase(const MediaRecorderBase &);
diff --git a/include/media/MemoryLeakTrackUtil.h b/include/media/MemoryLeakTrackUtil.h
new file mode 100644
index 0000000..290b748
--- /dev/null
+++ b/include/media/MemoryLeakTrackUtil.h
@@ -0,0 +1,28 @@
+
+/*
+ * Copyright 2011, 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 MEMORY_LEAK_TRACK_UTIL_H
+#define MEMORY_LEAK_TRACK_UTIL_H
+
+namespace android {
+/*
+ * Dump the memory adddress of the calling process to the given fd.
+ */
+extern void dumpMemoryAddresses(int fd);
+
+};
+
+#endif // MEMORY_LEAK_TRACK_UTIL_H
diff --git a/include/media/Metadata.h b/include/media/Metadata.h
index 9c915ce..07567eb 100644
--- a/include/media/Metadata.h
+++ b/include/media/Metadata.h
@@ -51,47 +51,46 @@
static const Type kAny = 0;
- // Keep in sync with android/media/Metadata.java
- static const Type kTitle = 1; // String
- static const Type kComment = 2; // String
- static const Type kCopyright = 3; // String
- static const Type kAlbum = 4; // String
- static const Type kArtist = 5; // String
- static const Type kAuthor = 6; // String
- static const Type kComposer = 7; // String
- static const Type kGenre = 8; // String
- static const Type kDate = 9; // Date
- static const Type kDuration = 10; // Integer(millisec)
- static const Type kCdTrackNum = 11; // Integer 1-based
- static const Type kCdTrackMax = 12; // Integer
- static const Type kRating = 13; // String
- static const Type kAlbumArt = 14; // byte[]
- static const Type kVideoFrame = 15; // Bitmap
- static const Type kCaption = 16; // TimedText
+ // Playback capabilities.
+ static const Type kPauseAvailable = 1; // Boolean
+ static const Type kSeekBackwardAvailable = 2; // Boolean
+ static const Type kSeekForwardAvailable = 3; // Boolean
+ static const Type kSeekAvailable = 4; // Boolean
- static const Type kBitRate = 17; // Integer, Aggregate rate of
+ // Keep in sync with android/media/Metadata.java
+ static const Type kTitle = 5; // String
+ static const Type kComment = 6; // String
+ static const Type kCopyright = 7; // String
+ static const Type kAlbum = 8; // String
+ static const Type kArtist = 9; // String
+ static const Type kAuthor = 10; // String
+ static const Type kComposer = 11; // String
+ static const Type kGenre = 12; // String
+ static const Type kDate = 13; // Date
+ static const Type kDuration = 14; // Integer(millisec)
+ static const Type kCdTrackNum = 15; // Integer 1-based
+ static const Type kCdTrackMax = 16; // Integer
+ static const Type kRating = 17; // String
+ static const Type kAlbumArt = 18; // byte[]
+ static const Type kVideoFrame = 19; // Bitmap
+
+ static const Type kBitRate = 20; // Integer, Aggregate rate of
// all the streams in bps.
- static const Type kAudioBitRate = 18; // Integer, bps
- static const Type kVideoBitRate = 19; // Integer, bps
- static const Type kAudioSampleRate = 20; // Integer, Hz
- static const Type kVideoframeRate = 21; // Integer, Hz
+ static const Type kAudioBitRate = 21; // Integer, bps
+ static const Type kVideoBitRate = 22; // Integer, bps
+ static const Type kAudioSampleRate = 23; // Integer, Hz
+ static const Type kVideoframeRate = 24; // Integer, Hz
// See RFC2046 and RFC4281.
- static const Type kMimeType = 22; // String
- static const Type kAudioCodec = 23; // String
- static const Type kVideoCodec = 24; // String
+ static const Type kMimeType = 25; // String
+ static const Type kAudioCodec = 26; // String
+ static const Type kVideoCodec = 27; // String
- static const Type kVideoHeight = 25; // Integer
- static const Type kVideoWidth = 26; // Integer
- static const Type kNumTracks = 27; // Integer
- static const Type kDrmCrippled = 28; // Boolean
-
- // Playback capabilities.
- static const Type kPauseAvailable = 29; // Boolean
- static const Type kSeekBackwardAvailable = 30; // Boolean
- static const Type kSeekForwardAvailable = 31; // Boolean
- static const Type kSeekAvailable = 32; // Boolean
+ static const Type kVideoHeight = 28; // Integer
+ static const Type kVideoWidth = 29; // Integer
+ static const Type kNumTracks = 30; // Integer
+ static const Type kDrmCrippled = 31; // Boolean
// @param p[inout] The parcel to append the metadata records
// to. The global metadata header should have been set already.
diff --git a/include/media/Visualizer.h b/include/media/Visualizer.h
index b8746c2..5d2c874 100644
--- a/include/media/Visualizer.h
+++ b/include/media/Visualizer.h
@@ -18,7 +18,7 @@
#define ANDROID_MEDIA_VISUALIZER_H
#include <media/AudioEffect.h>
-#include <media/EffectVisualizerApi.h>
+#include <audio_effects/effect_visualizer.h>
#include <string.h>
/**
diff --git a/include/media/mediametadataretriever.h b/include/media/mediametadataretriever.h
index e905006..9aa6700 100644
--- a/include/media/mediametadataretriever.h
+++ b/include/media/mediametadataretriever.h
@@ -47,6 +47,14 @@
METADATA_KEY_ALBUMARTIST = 13,
METADATA_KEY_DISC_NUMBER = 14,
METADATA_KEY_COMPILATION = 15,
+ METADATA_KEY_HAS_AUDIO = 16,
+ METADATA_KEY_HAS_VIDEO = 17,
+ METADATA_KEY_VIDEO_WIDTH = 18,
+ METADATA_KEY_VIDEO_HEIGHT = 19,
+ METADATA_KEY_BITRATE = 20,
+ METADATA_KEY_TIMED_TEXT_LANGUAGES = 21,
+ METADATA_KEY_IS_DRM = 22,
+
// Add more here...
};
@@ -56,7 +64,11 @@
MediaMetadataRetriever();
~MediaMetadataRetriever();
void disconnect();
- status_t setDataSource(const char* dataSourceUrl);
+
+ status_t setDataSource(
+ const char *dataSourceUrl,
+ const KeyedVector<String8, String8> *headers = NULL);
+
status_t setDataSource(int fd, int64_t offset, int64_t length);
sp<IMemory> getFrameAtTime(int64_t timeUs, int option);
sp<IMemory> extractAlbumArt();
diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h
index 528eeb9..1a67671 100644
--- a/include/media/mediaplayer.h
+++ b/include/media/mediaplayer.h
@@ -25,6 +25,8 @@
#include <utils/KeyedVector.h>
#include <utils/String8.h>
+class ANativeWindow;
+
namespace android {
class Surface;
@@ -37,6 +39,7 @@
MEDIA_BUFFERING_UPDATE = 3,
MEDIA_SEEK_COMPLETE = 4,
MEDIA_SET_VIDEO_SIZE = 5,
+ MEDIA_TIMED_TEXT = 99,
MEDIA_ERROR = 100,
MEDIA_INFO = 200,
};
@@ -99,6 +102,9 @@
MEDIA_INFO_BUFFERING_START = 701,
// MediaPlayer is resuming playback after filling buffers.
MEDIA_INFO_BUFFERING_END = 702,
+ // Bandwidth in recent past
+ MEDIA_INFO_NETWORK_BANDWIDTH = 703,
+
// 8xx
// Bad interleaving means that a media has been improperly interleaved or not
// interleaved at all, e.g has all the video samples first then all the audio
@@ -124,12 +130,28 @@
MEDIA_PLAYER_PLAYBACK_COMPLETE = 1 << 7
};
+// Keep KEY_PARAMETER_* in sync with MediaPlayer.java.
+// The same enum space is used for both set and get, in case there are future keys that
+// can be both set and get. But as of now, all parameters are either set only or get only.
+enum media_parameter_keys {
+ KEY_PARAMETER_TIMED_TEXT_TRACK_INDEX = 1000, // set only
+ KEY_PARAMETER_TIMED_TEXT_ADD_OUT_OF_BAND_SOURCE = 1001, // set only
+
+ // Streaming/buffering parameters
+ KEY_PARAMETER_CACHE_STAT_COLLECT_FREQ_MS = 1100, // set only
+
+ // Return a Parcel containing a single int, which is the channel count of the
+ // audio track, or zero for error (e.g. no audio track) or unknown.
+ KEY_PARAMETER_AUDIO_CHANNEL_COUNT = 1200, // get only
+
+};
+
// ----------------------------------------------------------------------------
// ref-counted object for callbacks
class MediaPlayerListener: virtual public RefBase
{
public:
- virtual void notify(int msg, int ext1, int ext2) = 0;
+ virtual void notify(int msg, int ext1, int ext2, const Parcel *obj) = 0;
};
class MediaPlayer : public BnMediaPlayerClient,
@@ -166,7 +188,7 @@
status_t setLooping(int loop);
bool isLooping();
status_t setVolume(float leftVolume, float rightVolume);
- void notify(int msg, int ext1, int ext2);
+ void notify(int msg, int ext1, int ext2, const Parcel *obj = NULL);
static sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat);
static sp<IMemory> decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat);
status_t invoke(const Parcel& request, Parcel *reply);
@@ -176,12 +198,17 @@
int getAudioSessionId();
status_t setAuxEffectSendLevel(float level);
status_t attachAuxEffect(int effectId);
+ status_t setParameter(int key, const Parcel& request);
+ status_t getParameter(int key, Parcel* reply);
+
private:
void clear_l();
status_t seekTo_l(int msec);
status_t prepareAsync_l();
status_t getDuration_l(int *msec);
status_t setDataSource(const sp<IMediaPlayer>& player);
+ void disconnectNativeWindow();
+ status_t reset_l();
sp<IMediaPlayer> mPlayer;
thread_id_t mLockThreadId;
@@ -204,6 +231,8 @@
int mVideoHeight;
int mAudioSessionId;
float mSendLevel;
+ sp<ANativeWindow> mConnectedWindow;
+ sp<IBinder> mConnectedWindowBinder;
};
}; // namespace android
diff --git a/include/media/mediarecorder.h b/include/media/mediarecorder.h
index a710546..30db642 100644
--- a/include/media/mediarecorder.h
+++ b/include/media/mediarecorder.h
@@ -30,29 +30,16 @@
class Surface;
class IMediaRecorder;
class ICamera;
+class ICameraRecordingProxy;
+class ISurfaceTexture;
+class SurfaceTextureClient;
typedef void (*media_completion_f)(status_t status, void *cookie);
-/* Do not change these values without updating their counterparts
- * in media/java/android/media/MediaRecorder.java!
- */
-enum audio_source {
- AUDIO_SOURCE_DEFAULT = 0,
- AUDIO_SOURCE_MIC = 1,
- AUDIO_SOURCE_VOICE_UPLINK = 2,
- AUDIO_SOURCE_VOICE_DOWNLINK = 3,
- AUDIO_SOURCE_VOICE_CALL = 4,
- AUDIO_SOURCE_CAMCORDER = 5,
- AUDIO_SOURCE_VOICE_RECOGNITION = 6,
- AUDIO_SOURCE_VOICE_COMMUNICATION = 7,
- AUDIO_SOURCE_MAX = AUDIO_SOURCE_VOICE_COMMUNICATION,
-
- AUDIO_SOURCE_LIST_END // must be last - used to validate audio source type
-};
-
enum video_source {
VIDEO_SOURCE_DEFAULT = 0,
VIDEO_SOURCE_CAMERA = 1,
+ VIDEO_SOURCE_GRALLOC_BUFFER = 2,
VIDEO_SOURCE_LIST_END // must be last - used to validate audio source type
};
@@ -104,35 +91,62 @@
};
/*
- * The state machine of the media_recorder uses a set of different state names.
- * The mapping between the media_recorder and the pvauthorengine is shown below:
- *
- * mediarecorder pvauthorengine
- * ----------------------------------------------------------------
- * MEDIA_RECORDER_ERROR ERROR
- * MEDIA_RECORDER_IDLE IDLE
- * MEDIA_RECORDER_INITIALIZED OPENED
- * MEDIA_RECORDER_DATASOURCE_CONFIGURED
- * MEDIA_RECORDER_PREPARED INITIALIZED
- * MEDIA_RECORDER_RECORDING RECORDING
+ * The state machine of the media_recorder.
*/
enum media_recorder_states {
+ // Error state.
MEDIA_RECORDER_ERROR = 0,
+
+ // Recorder was just created.
MEDIA_RECORDER_IDLE = 1 << 0,
+
+ // Recorder has been initialized.
MEDIA_RECORDER_INITIALIZED = 1 << 1,
+
+ // Configuration of the recorder has been completed.
MEDIA_RECORDER_DATASOURCE_CONFIGURED = 1 << 2,
+
+ // Recorder is ready to start.
MEDIA_RECORDER_PREPARED = 1 << 3,
+
+ // Recording is in progress.
MEDIA_RECORDER_RECORDING = 1 << 4,
};
// The "msg" code passed to the listener in notify.
enum media_recorder_event_type {
+ MEDIA_RECORDER_EVENT_LIST_START = 1,
MEDIA_RECORDER_EVENT_ERROR = 1,
- MEDIA_RECORDER_EVENT_INFO = 2
+ MEDIA_RECORDER_EVENT_INFO = 2,
+ MEDIA_RECORDER_EVENT_LIST_END = 99,
+
+ // Track related event types
+ MEDIA_RECORDER_TRACK_EVENT_LIST_START = 100,
+ MEDIA_RECORDER_TRACK_EVENT_ERROR = 100,
+ MEDIA_RECORDER_TRACK_EVENT_INFO = 101,
+ MEDIA_RECORDER_TRACK_EVENT_LIST_END = 1000,
};
+/*
+ * The (part of) "what" code passed to the listener in notify.
+ * When the error or info type is track specific, the what has
+ * the following layout:
+ * the left-most 16-bit is meant for error or info type.
+ * the right-most 4-bit is meant for track id.
+ * the rest is reserved.
+ *
+ * | track id | reserved | error or info type |
+ * 31 28 16 0
+ *
+ */
enum media_recorder_error_type {
- MEDIA_RECORDER_ERROR_UNKNOWN = 1
+ MEDIA_RECORDER_ERROR_UNKNOWN = 1,
+
+ // Track related error type
+ MEDIA_RECORDER_TRACK_ERROR_LIST_START = 100,
+ MEDIA_RECORDER_TRACK_ERROR_GENERAL = 100,
+ MEDIA_RECORDER_ERROR_VIDEO_NO_SYNC_FRAME = 200,
+ MEDIA_RECORDER_TRACK_ERROR_LIST_END = 1000,
};
// The codes are distributed as follow:
@@ -141,11 +155,38 @@
//
enum media_recorder_info_type {
MEDIA_RECORDER_INFO_UNKNOWN = 1,
+
MEDIA_RECORDER_INFO_MAX_DURATION_REACHED = 800,
MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED = 801,
- MEDIA_RECORDER_INFO_COMPLETION_STATUS = 802,
- MEDIA_RECORDER_INFO_PROGRESS_FRAME_STATUS = 803,
- MEDIA_RECORDER_INFO_PROGRESS_TIME_STATUS = 804,
+
+ // All track related informtional events start here
+ MEDIA_RECORDER_TRACK_INFO_LIST_START = 1000,
+ MEDIA_RECORDER_TRACK_INFO_COMPLETION_STATUS = 1000,
+ MEDIA_RECORDER_TRACK_INFO_PROGRESS_IN_TIME = 1001,
+ MEDIA_RECORDER_TRACK_INFO_TYPE = 1002,
+ MEDIA_RECORDER_TRACK_INFO_DURATION_MS = 1003,
+
+ // The time to measure the max chunk duration
+ MEDIA_RECORDER_TRACK_INFO_MAX_CHUNK_DUR_MS = 1004,
+
+ MEDIA_RECORDER_TRACK_INFO_ENCODED_FRAMES = 1005,
+
+ // The time to measure how well the audio and video
+ // track data is interleaved.
+ MEDIA_RECORDER_TRACK_INTER_CHUNK_TIME_MS = 1006,
+
+ // The time to measure system response. Note that
+ // the delay does not include the intentional delay
+ // we use to eliminate the recording sound.
+ MEDIA_RECORDER_TRACK_INFO_INITIAL_DELAY_MS = 1007,
+
+ // The time used to compensate for initial A/V sync.
+ MEDIA_RECORDER_TRACK_INFO_START_OFFSET_MS = 1008,
+
+ // Total number of bytes of the media data.
+ MEDIA_RECORDER_TRACK_INFO_DATA_KBYTES = 1009,
+
+ MEDIA_RECORDER_TRACK_INFO_LIST_END = 2000,
};
// ----------------------------------------------------------------------------
@@ -165,7 +206,7 @@
void died();
status_t initCheck();
- status_t setCamera(const sp<ICamera>& camera);
+ status_t setCamera(const sp<ICamera>& camera, const sp<ICameraRecordingProxy>& proxy);
status_t setPreviewSurface(const sp<Surface>& surface);
status_t setVideoSource(int vs);
status_t setAudioSource(int as);
@@ -174,7 +215,6 @@
status_t setAudioEncoder(int ae);
status_t setOutputFile(const char* path);
status_t setOutputFile(int fd, int64_t offset, int64_t length);
- status_t setOutputFileAuxiliary(int fd);
status_t setVideoSize(int width, int height);
status_t setVideoFrameRate(int frames_per_second);
status_t setParameters(const String8& params);
@@ -188,6 +228,7 @@
status_t close();
status_t release();
void notify(int msg, int ext1, int ext2);
+ sp<ISurfaceTexture> querySurfaceMediaSourceFromMediaServer();
private:
void doCleanUp();
@@ -195,13 +236,18 @@
sp<IMediaRecorder> mMediaRecorder;
sp<MediaRecorderListener> mListener;
+
+ // Reference toISurfaceTexture
+ // for encoding GL Frames. That is useful only when the
+ // video source is set to VIDEO_SOURCE_GRALLOC_BUFFER
+ sp<ISurfaceTexture> mSurfaceMediaSource;
+
media_recorder_states mCurrentState;
bool mIsAudioSourceSet;
bool mIsVideoSourceSet;
bool mIsAudioEncoderSet;
bool mIsVideoEncoderSet;
bool mIsOutputFileSet;
- bool mIsAuxiliaryOutputFileSet;
Mutex mLock;
Mutex mNotifyLock;
};
diff --git a/include/media/mediascanner.h b/include/media/mediascanner.h
index 765c039..803bffb 100644
--- a/include/media/mediascanner.h
+++ b/include/media/mediascanner.h
@@ -23,23 +23,33 @@
#include <utils/Errors.h>
#include <pthread.h>
+struct dirent;
+
namespace android {
class MediaScannerClient;
class StringArray;
+enum MediaScanResult {
+ // This file or directory was scanned successfully.
+ MEDIA_SCAN_RESULT_OK,
+ // This file or directory was skipped because it was not found, could
+ // not be opened, was of an unsupported type, or was malfored in some way.
+ MEDIA_SCAN_RESULT_SKIPPED,
+ // The scan should be aborted due to a fatal error such as out of memory
+ // or an exception.
+ MEDIA_SCAN_RESULT_ERROR,
+};
+
struct MediaScanner {
MediaScanner();
virtual ~MediaScanner();
- virtual status_t processFile(
- const char *path, const char *mimeType,
- MediaScannerClient &client) = 0;
+ virtual MediaScanResult processFile(
+ const char *path, const char *mimeType, MediaScannerClient &client) = 0;
- typedef bool (*ExceptionCheck)(void* env);
- virtual status_t processDirectory(
- const char *path, MediaScannerClient &client,
- ExceptionCheck exceptionCheck, void *exceptionEnv);
+ virtual MediaScanResult processDirectory(
+ const char *path, MediaScannerClient &client);
void setLocale(const char *locale);
@@ -53,9 +63,11 @@
// current locale (like "ja_JP"), created/destroyed with strdup()/free()
char *mLocale;
- status_t doProcessDirectory(
- char *path, int pathRemaining, MediaScannerClient &client,
- bool noMedia, ExceptionCheck exceptionCheck, void *exceptionEnv);
+ MediaScanResult doProcessDirectory(
+ char *path, int pathRemaining, MediaScannerClient &client, bool noMedia);
+ MediaScanResult doProcessDirectoryEntry(
+ char *path, int pathRemaining, MediaScannerClient &client, bool noMedia,
+ struct dirent* entry, char* fileSpot);
MediaScanner(const MediaScanner &);
MediaScanner &operator=(const MediaScanner &);
@@ -68,13 +80,13 @@
virtual ~MediaScannerClient();
void setLocale(const char* locale);
void beginFile();
- bool addStringTag(const char* name, const char* value);
+ status_t addStringTag(const char* name, const char* value);
void endFile();
- virtual bool scanFile(const char* path, long long lastModified,
+ virtual status_t scanFile(const char* path, long long lastModified,
long long fileSize, bool isDirectory, bool noMedia) = 0;
- virtual bool handleStringTag(const char* name, const char* value) = 0;
- virtual bool setMimeType(const char* mimeType) = 0;
+ virtual status_t handleStringTag(const char* name, const char* value) = 0;
+ virtual status_t setMimeType(const char* mimeType) = 0;
protected:
void convertValues(uint32_t encoding);
diff --git a/include/media/stagefright/AACWriter.h b/include/media/stagefright/AACWriter.h
new file mode 100644
index 0000000..fa3ab8a
--- /dev/null
+++ b/include/media/stagefright/AACWriter.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2011 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 AAC_WRITER_H_
+#define AAC_WRITER_H_
+
+#include <media/stagefright/MediaWriter.h>
+#include <utils/threads.h>
+
+namespace android {
+
+struct MediaSource;
+struct MetaData;
+
+struct AACWriter : public MediaWriter {
+ AACWriter(const char *filename);
+ AACWriter(int fd);
+
+ status_t initCheck() const;
+
+ virtual status_t addSource(const sp<MediaSource> &source);
+ virtual bool reachedEOS();
+ virtual status_t start(MetaData *params = NULL);
+ virtual status_t stop();
+ virtual status_t pause();
+
+protected:
+ virtual ~AACWriter();
+
+private:
+ enum {
+ kAdtsHeaderLength = 7, // # of bytes for the adts header
+ kSamplesPerFrame = 1024, // # of samples in a frame
+ };
+
+ int mFd;
+ status_t mInitCheck;
+ sp<MediaSource> mSource;
+ bool mStarted;
+ volatile bool mPaused;
+ volatile bool mResumed;
+ volatile bool mDone;
+ volatile bool mReachedEOS;
+ pthread_t mThread;
+ int64_t mEstimatedSizeBytes;
+ int64_t mEstimatedDurationUs;
+ int32_t mChannelCount;
+ int32_t mSampleRate;
+ int32_t mFrameDurationUs;
+
+ static void *ThreadWrapper(void *);
+ status_t threadFunc();
+ bool exceedsFileSizeLimit();
+ bool exceedsFileDurationLimit();
+ status_t writeAdtsHeader(uint32_t frameLength);
+
+ DISALLOW_EVIL_CONSTRUCTORS(AACWriter);
+};
+
+} // namespace android
+
+#endif // AAC_WRITER_H_
diff --git a/include/media/stagefright/AudioPlayer.h b/include/media/stagefright/AudioPlayer.h
index d12ee9c..0b79324 100644
--- a/include/media/stagefright/AudioPlayer.h
+++ b/include/media/stagefright/AudioPlayer.h
@@ -108,6 +108,8 @@
void reset();
+ uint32_t getNumFramesPendingPlayout() const;
+
AudioPlayer(const AudioPlayer &);
AudioPlayer &operator=(const AudioPlayer &);
};
diff --git a/include/media/stagefright/AudioSource.h b/include/media/stagefright/AudioSource.h
index 9e6f0e2..19bd31b 100644
--- a/include/media/stagefright/AudioSource.h
+++ b/include/media/stagefright/AudioSource.h
@@ -24,16 +24,18 @@
#include <media/stagefright/MediaBuffer.h>
#include <utils/List.h>
+#include <system/audio.h>
+
namespace android {
class AudioRecord;
struct AudioSource : public MediaSource, public MediaBufferObserver {
// Note that the "channels" parameter is _not_ the number of channels,
- // but a bitmask of AudioSystem::audio_channels constants.
+ // but a bitmask of audio_channels_t constants.
AudioSource(
int inputSource, uint32_t sampleRate,
- uint32_t channels = AudioSystem::CHANNEL_IN_MONO);
+ uint32_t channels = AUDIO_CHANNEL_IN_MONO);
status_t initCheck() const;
diff --git a/include/media/stagefright/CameraSource.h b/include/media/stagefright/CameraSource.h
index 4a39fbf..8c1c593 100644
--- a/include/media/stagefright/CameraSource.h
+++ b/include/media/stagefright/CameraSource.h
@@ -21,6 +21,7 @@
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MediaSource.h>
#include <camera/ICamera.h>
+#include <camera/ICameraRecordingProxyListener.h>
#include <camera/CameraParameters.h>
#include <utils/List.h>
#include <utils/RefBase.h>
@@ -68,6 +69,7 @@
* @return NULL on error.
*/
static CameraSource *CreateFromCamera(const sp<ICamera> &camera,
+ const sp<ICameraRecordingProxy> &proxy,
int32_t cameraId,
Size videoSize,
int32_t frameRate,
@@ -99,34 +101,6 @@
virtual sp<MetaData> getFormat();
/**
- * Retrieve the total number of video buffers available from
- * this source.
- *
- * This method is useful if these video buffers are used
- * for passing video frame data to other media components,
- * such as OMX video encoders, in order to eliminate the
- * memcpy of the data.
- *
- * @return the total numbner of video buffers. Returns 0 to
- * indicate that this source does not make the video
- * buffer information availalble.
- */
- size_t getNumberOfVideoBuffers() const;
-
- /**
- * Retrieve the individual video buffer available from
- * this source.
- *
- * @param index the index corresponding to the video buffer.
- * Valid range of the index is [0, n], where n =
- * getNumberOfVideoBuffers() - 1.
- *
- * @return the video buffer corresponding to the given index.
- * If index is out of range, 0 should be returned.
- */
- sp<IMemory> getVideoBuffer(size_t index) const;
-
- /**
* Tell whether this camera source stores meta data or real YUV
* frame data in video buffers.
*
@@ -139,6 +113,23 @@
virtual void signalBufferReturned(MediaBuffer* buffer);
protected:
+ class ProxyListener: public BnCameraRecordingProxyListener {
+ public:
+ ProxyListener(const sp<CameraSource>& source);
+ virtual void dataCallbackTimestamp(int64_t timestampUs, int32_t msgType,
+ const sp<IMemory> &data);
+
+ private:
+ sp<CameraSource> mSource;
+ };
+
+ // isBinderAlive needs linkToDeath to work.
+ class DeathNotifier: public IBinder::DeathRecipient {
+ public:
+ DeathNotifier() {}
+ virtual void binderDied(const wp<IBinder>& who);
+ };
+
enum CameraFlags {
FLAGS_SET_CAMERA = 1L << 0,
FLAGS_HOT_CAMERA = 1L << 1,
@@ -151,6 +142,8 @@
status_t mInitCheck;
sp<Camera> mCamera;
+ sp<ICameraRecordingProxy> mCameraRecordingProxy;
+ sp<DeathNotifier> mDeathNotifier;
sp<Surface> mSurface;
sp<MetaData> mMeta;
@@ -160,7 +153,8 @@
bool mStarted;
int32_t mNumFramesEncoded;
- CameraSource(const sp<ICamera>& camera, int32_t cameraId,
+ CameraSource(const sp<ICamera>& camera, const sp<ICameraRecordingProxy>& proxy,
+ int32_t cameraId,
Size videoSize, int32_t frameRate,
const sp<Surface>& surface,
bool storeMetaDataInVideoBuffers);
@@ -200,10 +194,18 @@
void releaseOneRecordingFrame(const sp<IMemory>& frame);
- status_t init(const sp<ICamera>& camera, int32_t cameraId,
- Size videoSize, int32_t frameRate,
- bool storeMetaDataInVideoBuffers);
- status_t isCameraAvailable(const sp<ICamera>& camera, int32_t cameraId);
+ status_t init(const sp<ICamera>& camera, const sp<ICameraRecordingProxy>& proxy,
+ int32_t cameraId, Size videoSize, int32_t frameRate,
+ bool storeMetaDataInVideoBuffers);
+
+ status_t initWithCameraAccess(
+ const sp<ICamera>& camera, const sp<ICameraRecordingProxy>& proxy,
+ int32_t cameraId, Size videoSize, int32_t frameRate,
+ bool storeMetaDataInVideoBuffers);
+
+ status_t isCameraAvailable(const sp<ICamera>& camera,
+ const sp<ICameraRecordingProxy>& proxy,
+ int32_t cameraId);
status_t isCameraColorFormatSupported(const CameraParameters& params);
status_t configureCamera(CameraParameters* params,
int32_t width, int32_t height,
diff --git a/include/media/stagefright/CameraSourceTimeLapse.h b/include/media/stagefright/CameraSourceTimeLapse.h
index 0e5d534..0e264c7 100644
--- a/include/media/stagefright/CameraSourceTimeLapse.h
+++ b/include/media/stagefright/CameraSourceTimeLapse.h
@@ -33,6 +33,7 @@
public:
static CameraSourceTimeLapse *CreateFromCamera(
const sp<ICamera> &camera,
+ const sp<ICameraRecordingProxy> &proxy,
int32_t cameraId,
Size videoSize,
int32_t videoFrameRate,
@@ -52,27 +53,10 @@
void startQuickReadReturns();
private:
- // If true, will use still camera takePicture() for time lapse frames
- // If false, will use the videocamera frames instead.
- bool mUseStillCameraForTimeLapse;
-
- // Size of picture taken from still camera. This may be larger than the size
- // of the video, as still camera may not support the exact video resolution
- // demanded. See setPictureSizeToClosestSupported().
- int32_t mPictureWidth;
- int32_t mPictureHeight;
-
// size of the encoded video.
int32_t mVideoWidth;
int32_t mVideoHeight;
- // True if we need to crop the still camera image to get the video frame.
- bool mNeedCropping;
-
- // Start location of the cropping rectangle.
- int32_t mCropRectStartX;
- int32_t mCropRectStartY;
-
// Time between capture of two frames during time lapse recording
// Negative value indicates that timelapse is disabled.
int64_t mTimeBetweenTimeLapseFrameCaptureUs;
@@ -83,9 +67,6 @@
// Real timestamp of the last encoded time lapse frame
int64_t mLastTimeLapseFrameRealTimestampUs;
- // Thread id of thread which takes still picture and sleeps in a loop.
- pthread_t mThreadTimeLapse;
-
// Variable set in dataCallbackTimestamp() to help skipCurrentFrame()
// to know if current frame needs to be skipped.
bool mSkipCurrentFrame;
@@ -110,9 +91,6 @@
// Lock for accessing quick stop variables.
Mutex mQuickStopLock;
- // Condition variable to wake up still picture thread.
- Condition mTakePictureCondition;
-
// mQuickStop is set to true if we use quick read() returns, otherwise it is set
// to false. Once in this mode read() return a copy of the last read frame
// with the same time stamp. See startQuickReadReturns().
@@ -132,6 +110,7 @@
CameraSourceTimeLapse(
const sp<ICamera> &camera,
+ const sp<ICameraRecordingProxy> &proxy,
int32_t cameraId,
Size videoSize,
int32_t videoFrameRate,
@@ -146,32 +125,13 @@
// Wrapper over CameraSource::read() to implement quick stop.
virtual status_t read(MediaBuffer **buffer, const ReadOptions *options = NULL);
- // For still camera case starts a thread which calls camera's takePicture()
- // in a loop. For video camera case, just starts the camera's video recording.
- virtual void startCameraRecording();
-
- // For still camera case joins the thread created in startCameraRecording().
// For video camera case, just stops the camera's video recording.
virtual void stopCameraRecording();
- // For still camera case don't need to do anything as memory is locally
- // allocated with refcounting.
- // For video camera case just tell the camera to release the frame.
- virtual void releaseRecordingFrame(const sp<IMemory>& frame);
-
// mSkipCurrentFrame is set to true in dataCallbackTimestamp() if the current
// frame needs to be skipped and this function just returns the value of mSkipCurrentFrame.
virtual bool skipCurrentFrame(int64_t timestampUs);
- // Handles the callback to handle raw frame data from the still camera.
- // Creates a copy of the frame data as the camera can reuse the frame memory
- // once this callback returns. The function also sets a new timstamp corresponding
- // to one frame time ahead of the last encoded frame's time stamp. It then
- // calls dataCallbackTimestamp() of the base class with the copied data and the
- // modified timestamp, which will think that it recieved the frame from a video
- // camera and proceed as usual.
- virtual void dataCallback(int32_t msgType, const sp<IMemory> &data);
-
// In the video camera case calls skipFrameAndModifyTimeStamp() to modify
// timestamp and set mSkipCurrentFrame.
// Then it calls the base CameraSource::dataCallbackTimestamp()
@@ -187,24 +147,6 @@
// Otherwise returns false.
bool trySettingVideoSize(int32_t width, int32_t height);
- // The still camera may not support the demanded video width and height.
- // We look for the supported picture sizes from the still camera and
- // choose the smallest one with either dimensions higher than the corresponding
- // video dimensions. The still picture will be cropped to get the video frame.
- // The function returns true if the camera supports picture sizes greater than
- // or equal to the passed in width and height, and false otherwise.
- bool setPictureSizeToClosestSupported(int32_t width, int32_t height);
-
- // Computes the offset of the rectangle from where to start cropping the
- // still image into the video frame. We choose the center of the image to be
- // cropped. The offset is stored in (mCropRectStartX, mCropRectStartY).
- bool computeCropRectangleOffset();
-
- // Crops the source data into a smaller image starting at
- // (mCropRectStartX, mCropRectStartY) and of the size of the video frame.
- // The data is returned into a newly allocated IMemory.
- sp<IMemory> cropYUVImage(const sp<IMemory> &source_data);
-
// When video camera is used for time lapse capture, returns true
// until enough time has passed for the next time lapse frame. When
// the frame needs to be encoded, it returns false and also modifies
@@ -215,22 +157,6 @@
// Wrapper to enter threadTimeLapseEntry()
static void *ThreadTimeLapseWrapper(void *me);
- // Runs a loop which sleeps until a still picture is required
- // and then calls mCamera->takePicture() to take the still picture.
- // Used only in the case mUseStillCameraForTimeLapse = true.
- void threadTimeLapseEntry();
-
- // Wrapper to enter threadStartPreview()
- static void *ThreadStartPreviewWrapper(void *me);
-
- // Starts the camera's preview.
- void threadStartPreview();
-
- // Starts thread ThreadStartPreviewWrapper() for restarting preview.
- // Needs to be done in a thread so that dataCallback() which calls this function
- // can return, and the camera can know that takePicture() is done.
- void restartPreview();
-
// Creates a copy of source_data into a new memory of final type MemoryBase.
sp<IMemory> createIMemoryCopy(const sp<IMemory> &source_data);
diff --git a/include/media/stagefright/ColorConverter.h b/include/media/stagefright/ColorConverter.h
index 2ae8a5b..85ba920 100644
--- a/include/media/stagefright/ColorConverter.h
+++ b/include/media/stagefright/ColorConverter.h
@@ -76,6 +76,9 @@
status_t convertYUV420SemiPlanar(
const BitmapParams &src, const BitmapParams &dst);
+ status_t convertTIYUV420PackedSemiPlanar(
+ const BitmapParams &src, const BitmapParams &dst);
+
ColorConverter(const ColorConverter &);
ColorConverter &operator=(const ColorConverter &);
};
diff --git a/include/media/stagefright/DataSource.h b/include/media/stagefright/DataSource.h
index f95e56a..713af92 100644
--- a/include/media/stagefright/DataSource.h
+++ b/include/media/stagefright/DataSource.h
@@ -20,6 +20,7 @@
#include <sys/types.h>
+#include <media/stagefright/MediaErrors.h>
#include <utils/Errors.h>
#include <utils/KeyedVector.h>
#include <utils/List.h>
@@ -38,6 +39,7 @@
kWantsPrefetching = 1,
kStreamedFromLocalHost = 2,
kIsCachingDataSource = 4,
+ kIsHTTPBasedSource = 8,
};
static sp<DataSource> CreateFromURI(
@@ -60,6 +62,10 @@
return 0;
}
+ virtual status_t reconnectAtOffset(off64_t offset) {
+ return ERROR_UNSUPPORTED;
+ }
+
////////////////////////////////////////////////////////////////////////////
bool sniff(String8 *mimeType, float *confidence, sp<AMessage> *meta);
@@ -75,15 +81,17 @@
static void RegisterDefaultSniffers();
// for DRM
- virtual DecryptHandle* DrmInitialization() {
+ virtual sp<DecryptHandle> DrmInitialization() {
return NULL;
}
- virtual void getDrmInfo(DecryptHandle **handle, DrmManagerClient **client) {};
+ virtual void getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client) {};
virtual String8 getUri() {
return String8();
}
+ virtual String8 getMIMEType() const;
+
protected:
virtual ~DataSource() {}
diff --git a/include/media/stagefright/FileSource.h b/include/media/stagefright/FileSource.h
index 51a4343..6cf86dc 100644
--- a/include/media/stagefright/FileSource.h
+++ b/include/media/stagefright/FileSource.h
@@ -38,9 +38,9 @@
virtual status_t getSize(off64_t *size);
- virtual DecryptHandle* DrmInitialization();
+ virtual sp<DecryptHandle> DrmInitialization();
- virtual void getDrmInfo(DecryptHandle **handle, DrmManagerClient **client);
+ virtual void getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client);
protected:
virtual ~FileSource();
@@ -52,7 +52,7 @@
Mutex mLock;
/*for DRM*/
- DecryptHandle *mDecryptHandle;
+ sp<DecryptHandle> mDecryptHandle;
DrmManagerClient *mDrmManagerClient;
int64_t mDrmBufOffset;
int64_t mDrmBufSize;
diff --git a/include/media/stagefright/HardwareAPI.h b/include/media/stagefright/HardwareAPI.h
index d1ecaaf..32eed3f 100644
--- a/include/media/stagefright/HardwareAPI.h
+++ b/include/media/stagefright/HardwareAPI.h
@@ -84,7 +84,7 @@
OMX_U32 nPortIndex;
OMX_PTR pAppPrivate;
OMX_BUFFERHEADERTYPE **bufferHeader;
- const sp<android_native_buffer_t>& nativeBuffer;
+ const sp<ANativeWindowBuffer>& nativeBuffer;
};
// A pointer to this struct is passed to OMX_GetParameter when the extension
@@ -99,6 +99,13 @@
OMX_U32 nUsage; // OUT
};
+// An enum OMX_COLOR_FormatAndroidOpaque to indicate an opaque colorformat
+// is declared in media/stagefright/openmax/OMX_IVCommon.h
+// This will inform the encoder that the actual
+// colorformat will be relayed by the GRalloc Buffers.
+// OMX_COLOR_FormatAndroidOpaque = 0x7F000001,
+
+
} // namespace android
extern android::OMXPluginBase *createOMXPlugin();
diff --git a/include/media/stagefright/MPEG2TSWriter.h b/include/media/stagefright/MPEG2TSWriter.h
index f2c6505..e4c1c49 100644
--- a/include/media/stagefright/MPEG2TSWriter.h
+++ b/include/media/stagefright/MPEG2TSWriter.h
@@ -31,6 +31,10 @@
MPEG2TSWriter(int fd);
MPEG2TSWriter(const char *filename);
+ MPEG2TSWriter(
+ void *cookie,
+ ssize_t (*write)(void *cookie, const void *data, size_t size));
+
virtual status_t addSource(const sp<MediaSource> &source);
virtual status_t start(MetaData *param = NULL);
virtual status_t stop();
@@ -51,6 +55,10 @@
struct SourceInfo;
FILE *mFile;
+
+ void *mWriteCookie;
+ ssize_t (*mWriteFunc)(void *cookie, const void *data, size_t size);
+
sp<ALooper> mLooper;
sp<AHandlerReflector<MPEG2TSWriter> > mReflector;
@@ -69,6 +77,8 @@
void writeProgramMap();
void writeAccessUnit(int32_t sourceIndex, const sp<ABuffer> &buffer);
+ ssize_t internalWrite(const void *data, size_t size);
+
DISALLOW_EVIL_CONSTRUCTORS(MPEG2TSWriter);
};
diff --git a/include/media/stagefright/MPEG4Writer.h b/include/media/stagefright/MPEG4Writer.h
index 5c5229d..77166ed 100644
--- a/include/media/stagefright/MPEG4Writer.h
+++ b/include/media/stagefright/MPEG4Writer.h
@@ -55,6 +55,10 @@
status_t setInterleaveDuration(uint32_t duration);
int32_t getTimeScale() const { return mTimeScale; }
+ status_t setGeoData(int latitudex10000, int longitudex10000);
+ void setStartTimeOffsetMs(int ms) { mStartTimeOffsetMs = ms; }
+ int32_t getStartTimeOffsetMs() const { return mStartTimeOffsetMs; }
+
protected:
virtual ~MPEG4Writer();
@@ -67,7 +71,8 @@
bool mUse32BitOffset;
bool mIsFileSizeLimitExplicitlyRequested;
bool mPaused;
- bool mStarted;
+ bool mStarted; // Writer thread + track threads started successfully
+ bool mWriterThreadStarted; // Only writer thread started successfully
off64_t mOffset;
off_t mMdatOffset;
uint8_t *mMoovBoxBuffer;
@@ -79,6 +84,10 @@
uint32_t mInterleaveDurationUs;
int32_t mTimeScale;
int64_t mStartTimestampUs;
+ int mLatitudex10000;
+ int mLongitudex10000;
+ bool mAreGeoTagsAvailable;
+ int32_t mStartTimeOffsetMs;
Mutex mLock;
@@ -108,6 +117,13 @@
struct ChunkInfo {
Track *mTrack; // Owner
List<Chunk> mChunks; // Remaining chunks to be written
+
+ // Previous chunk timestamp that has been written
+ int64_t mPrevChunkTimestampUs;
+
+ // Max time interval between neighboring chunks
+ int64_t mMaxInterChunkDurUs;
+
};
bool mIsFirstChunk;
@@ -157,8 +173,17 @@
bool use32BitFileOffset() const;
bool exceedsFileDurationLimit();
bool isFileStreamable() const;
- void trackProgressStatus(const Track* track, int64_t timeUs, status_t err = OK);
+ void trackProgressStatus(size_t trackId, int64_t timeUs, status_t err = OK);
void writeCompositionMatrix(int32_t degrees);
+ void writeMvhdBox(int64_t durationUs);
+ void writeMoovBox(int64_t durationUs);
+ void writeFtypBox(MetaData *param);
+ void writeUdtaBox();
+ void writeGeoDataBox();
+ void writeLatitude(int degreex10000);
+ void writeLongitude(int degreex10000);
+ void sendSessionSummary();
+ void release();
MPEG4Writer(const MPEG4Writer &);
MPEG4Writer &operator=(const MPEG4Writer &);
diff --git a/include/media/stagefright/MediaDefs.h b/include/media/stagefright/MediaDefs.h
index 66dfff6..3e48459 100644
--- a/include/media/stagefright/MediaDefs.h
+++ b/include/media/stagefright/MediaDefs.h
@@ -26,6 +26,7 @@
extern const char *MEDIA_MIMETYPE_VIDEO_AVC;
extern const char *MEDIA_MIMETYPE_VIDEO_MPEG4;
extern const char *MEDIA_MIMETYPE_VIDEO_H263;
+extern const char *MEDIA_MIMETYPE_VIDEO_MPEG2;
extern const char *MEDIA_MIMETYPE_VIDEO_RAW;
extern const char *MEDIA_MIMETYPE_AUDIO_AMR_NB;
@@ -45,9 +46,12 @@
extern const char *MEDIA_MIMETYPE_CONTAINER_OGG;
extern const char *MEDIA_MIMETYPE_CONTAINER_MATROSKA;
extern const char *MEDIA_MIMETYPE_CONTAINER_MPEG2TS;
+extern const char *MEDIA_MIMETYPE_CONTAINER_AVI;
extern const char *MEDIA_MIMETYPE_CONTAINER_WVM;
+extern const char *MEDIA_MIMETYPE_TEXT_3GPP;
+
} // namespace android
#endif // MEDIA_DEFS_H_
diff --git a/include/media/stagefright/MediaExtractor.h b/include/media/stagefright/MediaExtractor.h
index a82106e..eb45237 100644
--- a/include/media/stagefright/MediaExtractor.h
+++ b/include/media/stagefright/MediaExtractor.h
@@ -56,7 +56,12 @@
virtual uint32_t flags() const;
// for DRM
- virtual void setDrmFlag(bool flag) {};
+ virtual void setDrmFlag(bool flag) {
+ mIsDrm = flag;
+ };
+ virtual bool getDrmFlag() {
+ return mIsDrm;
+ }
virtual char* getDrmTrackInfo(size_t trackID, int *len) {
return NULL;
}
@@ -66,6 +71,8 @@
virtual ~MediaExtractor() {}
private:
+ bool mIsDrm;
+
MediaExtractor(const MediaExtractor &);
MediaExtractor &operator=(const MediaExtractor &);
};
diff --git a/include/media/stagefright/MediaSource.h b/include/media/stagefright/MediaSource.h
index a31395e..3818e63 100644
--- a/include/media/stagefright/MediaSource.h
+++ b/include/media/stagefright/MediaSource.h
@@ -22,13 +22,14 @@
#include <media/stagefright/MediaErrors.h>
#include <utils/RefBase.h>
+#include <utils/Vector.h>
namespace android {
class MediaBuffer;
class MetaData;
-struct MediaSource : public RefBase {
+struct MediaSource : public virtual RefBase {
MediaSource();
// To be called before any other methods on this object, except
@@ -99,6 +100,15 @@
return ERROR_UNSUPPORTED;
}
+ // The consumer of this media source requests that the given buffers
+ // are to be returned exclusively in response to read calls.
+ // This will be called after a successful start() and before the
+ // first read() call.
+ // Callee assumes ownership of the buffers if no error is returned.
+ virtual status_t setBuffers(const Vector<MediaBuffer *> &buffers) {
+ return ERROR_UNSUPPORTED;
+ }
+
protected:
virtual ~MediaSource();
diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h
index f7f2235..57f678c 100644
--- a/include/media/stagefright/MetaData.h
+++ b/include/media/stagefright/MetaData.h
@@ -55,6 +55,7 @@
kKeyIsSyncFrame = 'sync', // int32_t (bool)
kKeyIsCodecConfig = 'conf', // int32_t (bool)
kKeyTime = 'time', // int64_t (usecs)
+ kKeyDecodingTime = 'decT', // int64_t (decoding timestamp in usecs)
kKeyNTPTime = 'ntpT', // uint64_t (ntp-timestamp)
kKeyTargetTime = 'tarT', // int64_t (usecs)
kKeyDriftTime = 'dftT', // int64_t (usecs)
@@ -114,6 +115,14 @@
// An indication that a video buffer has been rendered.
kKeyRendered = 'rend', // bool (int32_t)
+
+ // The language code for this media
+ kKeyMediaLanguage = 'lang', // cstring
+
+ // To store the timed text format data
+ kKeyTextFormatData = 'text', // raw data
+
+ kKeyRequiresSecureBuffers = 'secu', // bool (int32_t)
};
enum {
diff --git a/include/media/stagefright/MetadataBufferType.h b/include/media/stagefright/MetadataBufferType.h
new file mode 100644
index 0000000..4eaf8ac
--- /dev/null
+++ b/include/media/stagefright/MetadataBufferType.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2011 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 METADATA_BUFFER_TYPE_H
+#define METADATA_BUFFER_TYPE_H
+
+#ifdef __cplusplus
+extern "C" {
+namespace android {
+#endif
+
+/*
+ * MetadataBufferType defines the type of the metadata buffers that
+ * can be passed to video encoder component for encoding, via Stagefright
+ * media recording framework. To see how to work with the metadata buffers
+ * in media recording framework, please consult HardwareAPI.h
+ *
+ * The creator of metadata buffers and video encoder share common knowledge
+ * on what is actually being stored in these metadata buffers, and
+ * how the information can be used by the video encoder component
+ * to locate the actual pixel data as the source input for video
+ * encoder, plus whatever other information that is necessary. Stagefright
+ * media recording framework does not need to know anything specific about the
+ * metadata buffers, except for receving each individual metadata buffer
+ * as the source input, making a copy of the metadata buffer, and passing the
+ * copy via OpenMAX API to the video encoder component.
+ *
+ * The creator of the metadata buffers must ensure that the first
+ * 4 bytes in every metadata buffer indicates its buffer type,
+ * and the rest of the metadata buffer contains the
+ * actual metadata information. When a video encoder component receives
+ * a metadata buffer, it uses the first 4 bytes in that buffer to find
+ * out the type of the metadata buffer, and takes action appropriate
+ * to that type of metadata buffers (for instance, locate the actual
+ * pixel data input and then encoding the input data to produce a
+ * compressed output buffer).
+ *
+ * The following shows the layout of a metadata buffer,
+ * where buffer type is a 4-byte field of MetadataBufferType,
+ * and the payload is the metadata information.
+ *
+ * --------------------------------------------------------------
+ * | buffer type | payload |
+ * --------------------------------------------------------------
+ *
+ */
+typedef enum {
+
+ /*
+ * kMetadataBufferTypeCameraSource is used to indicate that
+ * the source of the metadata buffer is the camera component.
+ */
+ kMetadataBufferTypeCameraSource = 0,
+
+ /*
+ * kMetadataBufferTypeGrallocSource is used to indicate that
+ * the payload of the metadata buffers can be interpreted as
+ * a buffer_handle_t.
+ * So in this case,the metadata that the encoder receives
+ * will have a byte stream that consists of two parts:
+ * 1. First, there is an integer indicating that it is a GRAlloc
+ * source (kMetadataBufferTypeGrallocSource)
+ * 2. This is followed by the buffer_handle_t that is a handle to the
+ * GRalloc buffer. The encoder needs to interpret this GRalloc handle
+ * and encode the frames.
+ * --------------------------------------------------------------
+ * | kMetadataBufferTypeGrallocSource | sizeof(buffer_handle_t) |
+ * --------------------------------------------------------------
+ */
+ kMetadataBufferTypeGrallocSource = 1,
+
+ // Add more here...
+
+} MetadataBufferType;
+
+#ifdef __cplusplus
+} // namespace android
+}
+#endif
+
+#endif // METADATA_BUFFER_TYPE_H
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index 93b5d24..2932744 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -53,6 +53,9 @@
// Enable GRALLOC_USAGE_PROTECTED for output buffers from native window
kEnableGrallocUsageProtected = 128,
+
+ // Secure decoding mode
+ kUseSecureInputBuffers = 256,
};
static sp<MediaSource> Create(
const sp<IOMX> &omx,
@@ -79,6 +82,13 @@
// from MediaBufferObserver
virtual void signalBufferReturned(MediaBuffer *buffer);
+ // for use by ACodec
+ static void findMatchingCodecs(
+ const char *mime,
+ bool createEncoder, const char *matchComponentName,
+ uint32_t flags,
+ Vector<String8> *matchingCodecs);
+
protected:
virtual ~OMXCodec();
@@ -157,6 +167,10 @@
bool mOMXLivesLocally;
IOMX::node_id mNode;
uint32_t mQuirks;
+
+ // Flags specified in the creation of the codec.
+ uint32_t mFlags;
+
bool mIsEncoder;
char *mMIME;
char *mComponentName;
@@ -198,11 +212,12 @@
List<size_t> mFilledBuffers;
Condition mBufferFilled;
- bool mIsMetaDataStoredInVideoBuffers;
- bool mOnlySubmitOneBufferAtOneTime;
- bool mEnableGrallocUsageProtected;
+ // Used to record the decoding time for an output picture from
+ // a video encoder.
+ List<int64_t> mDecodingTimeList;
- OMXCodec(const sp<IOMX> &omx, IOMX::node_id node, uint32_t quirks,
+ OMXCodec(const sp<IOMX> &omx, IOMX::node_id node,
+ uint32_t quirks, uint32_t flags,
bool isEncoder, const char *mime, const char *componentName,
const sp<MediaSource> &source,
const sp<ANativeWindow> &nativeWindow);
@@ -214,6 +229,7 @@
void setAMRFormat(bool isWAMR, int32_t bitRate);
void setAACFormat(int32_t numChannels, int32_t sampleRate, int32_t bitRate);
+ void setG711Format(int32_t numChannels);
status_t setVideoPortFormatType(
OMX_U32 portIndex,
@@ -275,6 +291,10 @@
void drainInputBuffers();
void fillOutputBuffers();
+ bool drainAnyInputBuffer();
+ BufferInfo *findInputBufferByDataPointer(void *ptr);
+ BufferInfo *findEmptyInputBuffer();
+
// Returns true iff a flush was initiated and a completion event is
// upcoming, false otherwise (A flush was not necessary as we own all
// the buffers on that port).
@@ -301,30 +321,22 @@
void dumpPortStatus(OMX_U32 portIndex);
- status_t configureCodec(const sp<MetaData> &meta, uint32_t flags);
+ status_t configureCodec(const sp<MetaData> &meta);
static uint32_t getComponentQuirks(
const char *componentName, bool isEncoder);
- static void findMatchingCodecs(
- const char *mime,
- bool createEncoder, const char *matchComponentName,
- uint32_t flags,
- Vector<String8> *matchingCodecs);
-
void restorePatchedDataPointer(BufferInfo *info);
status_t applyRotation();
+ status_t waitForBufferFilled_l();
+
+ int64_t retrieveDecodingTimeUs(bool isCodecSpecific);
OMXCodec(const OMXCodec &);
OMXCodec &operator=(const OMXCodec &);
};
-struct CodecProfileLevel {
- OMX_U32 mProfile;
- OMX_U32 mLevel;
-};
-
struct CodecCapabilities {
String8 mComponentName;
Vector<CodecProfileLevel> mProfileLevels;
@@ -337,6 +349,8 @@
// that encode content of the given type.
// profile and level indications only make sense for h.263, mpeg4 and avc
// video.
+// If hwCodecOnly==true, only returns hardware-based components, software and
+// hardware otherwise.
// The profile/level values correspond to
// OMX_VIDEO_H263PROFILETYPE, OMX_VIDEO_MPEG4PROFILETYPE,
// OMX_VIDEO_AVCPROFILETYPE, OMX_VIDEO_H263LEVELTYPE, OMX_VIDEO_MPEG4LEVELTYPE
@@ -344,6 +358,11 @@
status_t QueryCodecs(
const sp<IOMX> &omx,
+ const char *mimeType, bool queryDecoders, bool hwCodecOnly,
+ Vector<CodecCapabilities> *results);
+
+status_t QueryCodecs(
+ const sp<IOMX> &omx,
const char *mimeType, bool queryDecoders,
Vector<CodecCapabilities> *results);
diff --git a/include/media/stagefright/ShoutcastSource.h b/include/media/stagefright/ShoutcastSource.h
deleted file mode 100644
index bc67156..0000000
--- a/include/media/stagefright/ShoutcastSource.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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 SHOUTCAST_SOURCE_H_
-
-#define SHOUTCAST_SOURCE_H_
-
-#include <sys/types.h>
-
-#include <media/stagefright/MediaSource.h>
-
-namespace android {
-
-class HTTPStream;
-class MediaBufferGroup;
-
-class ShoutcastSource : public MediaSource {
-public:
- // Assumes ownership of "http".
- ShoutcastSource(HTTPStream *http);
-
- virtual status_t start(MetaData *params = NULL);
- virtual status_t stop();
-
- virtual sp<MetaData> getFormat();
-
- virtual status_t read(
- MediaBuffer **buffer, const ReadOptions *options = NULL);
-
-protected:
- virtual ~ShoutcastSource();
-
-private:
- HTTPStream *mHttp;
- size_t mMetaDataOffset;
- size_t mBytesUntilMetaData;
-
- MediaBufferGroup *mGroup;
- bool mStarted;
-
- ShoutcastSource(const ShoutcastSource &);
- ShoutcastSource &operator= (const ShoutcastSource &);
-};
-
-} // namespace android
-
-#endif // SHOUTCAST_SOURCE_H_
-
diff --git a/include/media/stagefright/StagefrightMediaScanner.h b/include/media/stagefright/StagefrightMediaScanner.h
index 108acb4..6510a59 100644
--- a/include/media/stagefright/StagefrightMediaScanner.h
+++ b/include/media/stagefright/StagefrightMediaScanner.h
@@ -26,7 +26,7 @@
StagefrightMediaScanner();
virtual ~StagefrightMediaScanner();
- virtual status_t processFile(
+ virtual MediaScanResult processFile(
const char *path, const char *mimeType,
MediaScannerClient &client);
@@ -35,6 +35,10 @@
private:
StagefrightMediaScanner(const StagefrightMediaScanner &);
StagefrightMediaScanner &operator=(const StagefrightMediaScanner &);
+
+ MediaScanResult processFileInternal(
+ const char *path, const char *mimeType,
+ MediaScannerClient &client);
};
} // namespace android
diff --git a/include/media/stagefright/SurfaceMediaSource.h b/include/media/stagefright/SurfaceMediaSource.h
new file mode 100644
index 0000000..fab258c
--- /dev/null
+++ b/include/media/stagefright/SurfaceMediaSource.h
@@ -0,0 +1,354 @@
+/*
+ * Copyright (C) 2011 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 ANDROID_GUI_SURFACEMEDIASOURCE_H
+#define ANDROID_GUI_SURFACEMEDIASOURCE_H
+
+#include <gui/ISurfaceTexture.h>
+
+#include <utils/threads.h>
+#include <utils/Vector.h>
+#include <media/stagefright/MediaSource.h>
+#include <media/stagefright/MediaBuffer.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+class IGraphicBufferAlloc;
+class String8;
+class GraphicBuffer;
+
+class SurfaceMediaSource : public BnSurfaceTexture, public MediaSource,
+ public MediaBufferObserver {
+public:
+ enum { MIN_UNDEQUEUED_BUFFERS = 3 };
+ enum {
+ MIN_ASYNC_BUFFER_SLOTS = MIN_UNDEQUEUED_BUFFERS + 1,
+ MIN_SYNC_BUFFER_SLOTS = MIN_UNDEQUEUED_BUFFERS
+ };
+ enum { NUM_BUFFER_SLOTS = 32 };
+ enum { NO_CONNECTED_API = 0 };
+
+ struct FrameAvailableListener : public virtual RefBase {
+ // onFrameAvailable() is called from queueBuffer() is the FIFO is
+ // empty. You can use SurfaceMediaSource::getQueuedCount() to
+ // figure out if there are more frames waiting.
+ // This is called without any lock held can be called concurrently by
+ // multiple threads.
+ virtual void onFrameAvailable() = 0;
+ };
+
+ SurfaceMediaSource(uint32_t bufW, uint32_t bufH);
+
+ virtual ~SurfaceMediaSource();
+
+
+ // For the MediaSource interface for use by StageFrightRecorder:
+ virtual status_t start(MetaData *params = NULL);
+ virtual status_t stop();
+ virtual status_t read(
+ MediaBuffer **buffer, const ReadOptions *options = NULL);
+ virtual sp<MetaData> getFormat();
+
+ // Pass the metadata over to the buffer, call when you have the lock
+ void passMetadataBufferLocked(MediaBuffer **buffer);
+ bool checkBufferMatchesSlot(int slot, MediaBuffer *buffer);
+
+ // Get / Set the frame rate used for encoding. Default fps = 30
+ status_t setFrameRate(int32_t fps) ;
+ int32_t getFrameRate( ) const;
+
+ // The call for the StageFrightRecorder to tell us that
+ // it is done using the MediaBuffer data so that its state
+ // can be set to FREE for dequeuing
+ virtual void signalBufferReturned(MediaBuffer* buffer);
+ // end of MediaSource interface
+
+ uint32_t getBufferCount( ) const { return mBufferCount;}
+
+
+ // setBufferCount updates the number of available buffer slots. After
+ // calling this all buffer slots are both unallocated and owned by the
+ // SurfaceMediaSource object (i.e. they are not owned by the client).
+ virtual status_t setBufferCount(int bufferCount);
+
+ virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf);
+
+ // dequeueBuffer gets the next buffer slot index for the client to use. If a
+ // buffer slot is available then that slot index is written to the location
+ // pointed to by the buf argument and a status of OK is returned. If no
+ // slot is available then a status of -EBUSY is returned and buf is
+ // unmodified.
+ virtual status_t dequeueBuffer(int *buf, uint32_t w, uint32_t h,
+ uint32_t format, uint32_t usage);
+
+ // queueBuffer returns a filled buffer to the SurfaceMediaSource. In addition, a
+ // timestamp must be provided for the buffer. The timestamp is in
+ // nanoseconds, and must be monotonically increasing. Its other semantics
+ // (zero point, etc) are client-dependent and should be documented by the
+ // client.
+ virtual status_t queueBuffer(int buf, int64_t timestamp,
+ uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform);
+ virtual void cancelBuffer(int buf);
+
+ // onFrameReceivedLocked informs the buffer consumers (StageFrightRecorder)
+ // or listeners that a frame has been received
+ // The buffer is not made available for dequeueing immediately. We need to
+ // wait to hear from StageFrightRecorder to set the buffer FREE
+ // Make sure this is called when the mutex is locked
+ virtual status_t onFrameReceivedLocked();
+
+ virtual status_t setScalingMode(int mode) { } // no op for encoding
+ virtual int query(int what, int* value);
+
+ // Just confirming to the ISurfaceTexture interface as of now
+ virtual status_t setCrop(const Rect& reg) { return OK; }
+ virtual status_t setTransform(uint32_t transform) {return OK;}
+
+ // setSynchronousMode set whether dequeueBuffer is synchronous or
+ // asynchronous. In synchronous mode, dequeueBuffer blocks until
+ // a buffer is available, the currently bound buffer can be dequeued and
+ // queued buffers will be retired in order.
+ // The default mode is synchronous.
+ // TODO: Clarify the minute differences bet sycn /async
+ // modes (S.Encoder vis-a-vis SurfaceTexture)
+ virtual status_t setSynchronousMode(bool enabled);
+
+ // connect attempts to connect a client API to the SurfaceMediaSource. This
+ // must be called before any other ISurfaceTexture methods are called except
+ // for getAllocator.
+ //
+ // This method will fail if the connect was previously called on the
+ // SurfaceMediaSource and no corresponding disconnect call was made.
+ virtual status_t connect(int api);
+
+ // disconnect attempts to disconnect a client API from the SurfaceMediaSource.
+ // Calling this method will cause any subsequent calls to other
+ // ISurfaceTexture methods to fail except for getAllocator and connect.
+ // Successfully calling connect after this will allow the other methods to
+ // succeed again.
+ //
+ // This method will fail if the the SurfaceMediaSource is not currently
+ // connected to the specified client API.
+ virtual status_t disconnect(int api);
+
+ // getqueuedCount returns the number of queued frames waiting in the
+ // FIFO. In asynchronous mode, this always returns 0 or 1 since
+ // frames are not accumulating in the FIFO.
+ size_t getQueuedCount() const;
+
+ // setBufferCountServer set the buffer count. If the client has requested
+ // a buffer count using setBufferCount, the server-buffer count will
+ // take effect once the client sets the count back to zero.
+ status_t setBufferCountServer(int bufferCount);
+
+ // getTimestamp retrieves the timestamp associated with the image
+ // set by the most recent call to read()
+ //
+ // The timestamp is in nanoseconds, and is monotonically increasing. Its
+ // other semantics (zero point, etc) are source-dependent and should be
+ // documented by the source.
+ int64_t getTimestamp();
+
+ // setFrameAvailableListener sets the listener object that will be notified
+ // when a new frame becomes available.
+ void setFrameAvailableListener(const sp<FrameAvailableListener>& listener);
+
+ // getCurrentBuffer returns the buffer associated with the current image.
+ sp<GraphicBuffer> getCurrentBuffer() const;
+
+ // dump our state in a String
+ void dump(String8& result) const;
+ void dump(String8& result, const char* prefix, char* buffer,
+ size_t SIZE) const;
+
+ // isMetaDataStoredInVideoBuffers tells the encoder whether we will
+ // pass metadata through the buffers. Currently, it is force set to true
+ bool isMetaDataStoredInVideoBuffers() const;
+
+protected:
+
+ // freeAllBuffers frees the resources (both GraphicBuffer and EGLImage) for
+ // all slots.
+ void freeAllBuffers();
+ static bool isExternalFormat(uint32_t format);
+
+private:
+
+ status_t setBufferCountServerLocked(int bufferCount);
+
+ enum { INVALID_BUFFER_SLOT = -1 };
+
+ struct BufferSlot {
+
+ BufferSlot()
+ : mBufferState(BufferSlot::FREE),
+ mRequestBufferCalled(false),
+ mTimestamp(0) {
+ }
+
+ // mGraphicBuffer points to the buffer allocated for this slot or is
+ // NULL if no buffer has been allocated.
+ sp<GraphicBuffer> mGraphicBuffer;
+
+ // BufferState represents the different states in which a buffer slot
+ // can be.
+ enum BufferState {
+ // FREE indicates that the buffer is not currently being used and
+ // will not be used in the future until it gets dequeued and
+ // subseqently queued by the client.
+ FREE = 0,
+
+ // DEQUEUED indicates that the buffer has been dequeued by the
+ // client, but has not yet been queued or canceled. The buffer is
+ // considered 'owned' by the client, and the server should not use
+ // it for anything.
+ //
+ // Note that when in synchronous-mode (mSynchronousMode == true),
+ // the buffer that's currently attached to the texture may be
+ // dequeued by the client. That means that the current buffer can
+ // be in either the DEQUEUED or QUEUED state. In asynchronous mode,
+ // however, the current buffer is always in the QUEUED state.
+ DEQUEUED = 1,
+
+ // QUEUED indicates that the buffer has been queued by the client,
+ // and has not since been made available for the client to dequeue.
+ // Attaching the buffer to the texture does NOT transition the
+ // buffer away from the QUEUED state. However, in Synchronous mode
+ // the current buffer may be dequeued by the client under some
+ // circumstances. See the note about the current buffer in the
+ // documentation for DEQUEUED.
+ QUEUED = 2,
+ };
+
+ // mBufferState is the current state of this buffer slot.
+ BufferState mBufferState;
+
+ // mRequestBufferCalled is used for validating that the client did
+ // call requestBuffer() when told to do so. Technically this is not
+ // needed but useful for debugging and catching client bugs.
+ bool mRequestBufferCalled;
+
+ // mTimestamp is the current timestamp for this buffer slot. This gets
+ // to set by queueBuffer each time this slot is queued.
+ int64_t mTimestamp;
+ };
+
+ // mSlots is the array of buffer slots that must be mirrored on the client
+ // side. This allows buffer ownership to be transferred between the client
+ // and server without sending a GraphicBuffer over binder. The entire array
+ // is initialized to NULL at construction time, and buffers are allocated
+ // for a slot when requestBuffer is called with that slot's index.
+ BufferSlot mSlots[NUM_BUFFER_SLOTS];
+
+ // mDefaultWidth holds the default width of allocated buffers. It is used
+ // in requestBuffers() if a width and height of zero is specified.
+ uint32_t mDefaultWidth;
+
+ // mDefaultHeight holds the default height of allocated buffers. It is used
+ // in requestBuffers() if a width and height of zero is specified.
+ uint32_t mDefaultHeight;
+
+ // mPixelFormat holds the pixel format of allocated buffers. It is used
+ // in requestBuffers() if a format of zero is specified.
+ uint32_t mPixelFormat;
+
+ // mBufferCount is the number of buffer slots that the client and server
+ // must maintain. It defaults to MIN_ASYNC_BUFFER_SLOTS and can be changed
+ // by calling setBufferCount or setBufferCountServer
+ int mBufferCount;
+
+ // mClientBufferCount is the number of buffer slots requested by the
+ // client. The default is zero, which means the client doesn't care how
+ // many buffers there are
+ int mClientBufferCount;
+
+ // mServerBufferCount buffer count requested by the server-side
+ int mServerBufferCount;
+
+ // mCurrentSlot is the buffer slot index of the buffer that is currently
+ // being used by buffer consumer
+ // (e.g. StageFrightRecorder in the case of SurfaceMediaSource or GLTexture
+ // in the case of SurfaceTexture).
+ // It is initialized to INVALID_BUFFER_SLOT,
+ // indicating that no buffer slot is currently bound to the texture. Note,
+ // however, that a value of INVALID_BUFFER_SLOT does not necessarily mean
+ // that no buffer is bound to the texture. A call to setBufferCount will
+ // reset mCurrentTexture to INVALID_BUFFER_SLOT.
+ int mCurrentSlot;
+
+
+ // mCurrentBuf is the graphic buffer of the current slot to be used by
+ // buffer consumer. It's possible that this buffer is not associated
+ // with any buffer slot, so we must track it separately in order to
+ // properly use IGraphicBufferAlloc::freeAllGraphicBuffersExcept.
+ sp<GraphicBuffer> mCurrentBuf;
+
+
+ // mCurrentTimestamp is the timestamp for the current texture. It
+ // gets set to mLastQueuedTimestamp each time updateTexImage is called.
+ int64_t mCurrentTimestamp;
+
+ // mGraphicBufferAlloc is the connection to SurfaceFlinger that is used to
+ // allocate new GraphicBuffer objects.
+ sp<IGraphicBufferAlloc> mGraphicBufferAlloc;
+
+ // mFrameAvailableListener is the listener object that will be called when a
+ // new frame becomes available. If it is not NULL it will be called from
+ // queueBuffer.
+ sp<FrameAvailableListener> mFrameAvailableListener;
+
+ // mSynchronousMode whether we're in synchronous mode or not
+ bool mSynchronousMode;
+
+ // mConnectedApi indicates the API that is currently connected to this
+ // SurfaceTexture. It defaults to NO_CONNECTED_API (= 0), and gets updated
+ // by the connect and disconnect methods.
+ int mConnectedApi;
+
+ // mDequeueCondition condition used for dequeueBuffer in synchronous mode
+ mutable Condition mDequeueCondition;
+
+
+ // mQueue is a FIFO of queued buffers used in synchronous mode
+ typedef Vector<int> Fifo;
+ Fifo mQueue;
+
+ // mMutex is the mutex used to prevent concurrent access to the member
+ // variables of SurfaceMediaSource objects. It must be locked whenever the
+ // member variables are accessed.
+ mutable Mutex mMutex;
+
+ ////////////////////////// For MediaSource
+ // Set to a default of 30 fps if not specified by the client side
+ int32_t mFrameRate;
+
+ // mStarted is a flag to check if the recording has started
+ bool mStarted;
+
+ // mFrameAvailableCondition condition used to indicate whether there
+ // is a frame available for dequeuing
+ Condition mFrameAvailableCondition;
+ Condition mFrameCompleteCondition;
+
+ // Avoid copying and equating and default constructor
+ DISALLOW_IMPLICIT_CONSTRUCTORS(SurfaceMediaSource);
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_GUI_SURFACEMEDIASOURCE_H
diff --git a/include/media/stagefright/openmax/OMX_IVCommon.h b/include/media/stagefright/openmax/OMX_IVCommon.h
index 4a8be7b..97170d7 100644
--- a/include/media/stagefright/openmax/OMX_IVCommon.h
+++ b/include/media/stagefright/openmax/OMX_IVCommon.h
@@ -16,29 +16,29 @@
* -------------------------------------------------------------------
*/
/**
- * Copyright (c) 2008 The Khronos Group Inc.
- *
+ * Copyright (c) 2008 The Khronos Group Inc.
+ *
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject
- * to the following conditions:
+ * to the following conditions:
* The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
+ * in all copies or substantial portions of the Software.
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-/**
+/**
* @file OMX_IVCommon.h - OpenMax IL version 1.1.2
* The structures needed by Video and Image components to exchange
* parameters and configuration data with the components.
@@ -53,7 +53,7 @@
/**
* Each OMX header must include all required header files to allow the header
* to compile without errors. The includes below are required for this header
- * file to compile successfully
+ * file to compile successfully
*/
#include <OMX_Core.h>
@@ -64,8 +64,8 @@
*/
-/**
- * Enumeration defining possible uncompressed image/video formats.
+/**
+ * Enumeration defining possible uncompressed image/video formats.
*
* ENUMS:
* Unused : Placeholder value when format is N/A
@@ -113,7 +113,7 @@
OMX_COLOR_Format16bitBGR565,
OMX_COLOR_Format18bitRGB666,
OMX_COLOR_Format18bitARGB1665,
- OMX_COLOR_Format19bitARGB1666,
+ OMX_COLOR_Format19bitARGB1666,
OMX_COLOR_Format24bitRGB888,
OMX_COLOR_Format24bitBGR888,
OMX_COLOR_Format24bitARGB1887,
@@ -136,53 +136,62 @@
OMX_COLOR_FormatRawBayer8bit,
OMX_COLOR_FormatRawBayer10bit,
OMX_COLOR_FormatRawBayer8bitcompressed,
- OMX_COLOR_FormatL2,
- OMX_COLOR_FormatL4,
- OMX_COLOR_FormatL8,
- OMX_COLOR_FormatL16,
- OMX_COLOR_FormatL24,
+ OMX_COLOR_FormatL2,
+ OMX_COLOR_FormatL4,
+ OMX_COLOR_FormatL8,
+ OMX_COLOR_FormatL16,
+ OMX_COLOR_FormatL24,
OMX_COLOR_FormatL32,
OMX_COLOR_FormatYUV420PackedSemiPlanar,
OMX_COLOR_FormatYUV422PackedSemiPlanar,
OMX_COLOR_Format18BitBGR666,
OMX_COLOR_Format24BitARGB6666,
OMX_COLOR_Format24BitABGR6666,
- OMX_COLOR_FormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_COLOR_FormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_COLOR_FormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ /**<Reserved android opaque colorformat. Tells the encoder that
+ * the actual colorformat will be relayed by the
+ * Gralloc Buffers.
+ * FIXME: In the process of reserving some enum values for
+ * Android-specific OMX IL colorformats. Change this enum to
+ * an acceptable range once that is done.*/
+ OMX_COLOR_FormatAndroidOpaque = 0x7F000001,
+ OMX_TI_COLOR_FormatYUV420PackedSemiPlanar = 0x7F000100,
+ OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00,
OMX_COLOR_FormatMax = 0x7FFFFFFF
} OMX_COLOR_FORMATTYPE;
-/**
+/**
* Defines the matrix for conversion from RGB to YUV or vice versa.
- * iColorMatrix should be initialized with the fixed point values
+ * iColorMatrix should be initialized with the fixed point values
* used in converting between formats.
*/
typedef struct OMX_CONFIG_COLORCONVERSIONTYPE {
OMX_U32 nSize; /**< Size of the structure in bytes */
- OMX_VERSIONTYPE nVersion; /**< OMX specification version info */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version info */
OMX_U32 nPortIndex; /**< Port that this struct applies to */
OMX_S32 xColorMatrix[3][3]; /**< Stored in signed Q16 format */
OMX_S32 xColorOffset[4]; /**< Stored in signed Q16 format */
}OMX_CONFIG_COLORCONVERSIONTYPE;
-/**
- * Structure defining percent to scale each frame dimension. For example:
+/**
+ * Structure defining percent to scale each frame dimension. For example:
* To make the width 50% larger, use fWidth = 1.5 and to make the width
* 1/2 the original size, use fWidth = 0.5
*/
typedef struct OMX_CONFIG_SCALEFACTORTYPE {
OMX_U32 nSize; /**< Size of the structure in bytes */
- OMX_VERSIONTYPE nVersion; /**< OMX specification version info */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version info */
OMX_U32 nPortIndex; /**< Port that this struct applies to */
OMX_S32 xWidth; /**< Fixed point value stored as Q16 */
OMX_S32 xHeight; /**< Fixed point value stored as Q16 */
}OMX_CONFIG_SCALEFACTORTYPE;
-/**
- * Enumeration of possible image filter types
+/**
+ * Enumeration of possible image filter types
*/
typedef enum OMX_IMAGEFILTERTYPE {
OMX_ImageFilterNone,
@@ -193,23 +202,23 @@
OMX_ImageFilterOilPaint,
OMX_ImageFilterHatch,
OMX_ImageFilterGpen,
- OMX_ImageFilterAntialias,
- OMX_ImageFilterDeRing,
+ OMX_ImageFilterAntialias,
+ OMX_ImageFilterDeRing,
OMX_ImageFilterSolarize,
- OMX_ImageFilterKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_ImageFilterKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_ImageFilterVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_ImageFilterMax = 0x7FFFFFFF
} OMX_IMAGEFILTERTYPE;
-/**
- * Image filter configuration
+/**
+ * Image filter configuration
*
* STRUCT MEMBERS:
- * nSize : Size of the structure in bytes
+ * nSize : Size of the structure in bytes
* nVersion : OMX specification version information
- * nPortIndex : Port that this structure applies to
- * eImageFilter : Image filter type enumeration
+ * nPortIndex : Port that this structure applies to
+ * eImageFilter : Image filter type enumeration
*/
typedef struct OMX_CONFIG_IMAGEFILTERTYPE {
OMX_U32 nSize;
@@ -219,22 +228,22 @@
} OMX_CONFIG_IMAGEFILTERTYPE;
-/**
- * Customized U and V for color enhancement
+/**
+ * Customized U and V for color enhancement
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
- * nVersion : OMX specification version information
+ * nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* bColorEnhancement : Enable/disable color enhancement
- * nCustomizedU : Practical values: 16-240, range: 0-255, value set for
+ * nCustomizedU : Practical values: 16-240, range: 0-255, value set for
* U component
- * nCustomizedV : Practical values: 16-240, range: 0-255, value set for
+ * nCustomizedV : Practical values: 16-240, range: 0-255, value set for
* V component
*/
typedef struct OMX_CONFIG_COLORENHANCEMENTTYPE {
OMX_U32 nSize;
- OMX_VERSIONTYPE nVersion;
+ OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
OMX_BOOL bColorEnhancement;
OMX_U8 nCustomizedU;
@@ -242,12 +251,12 @@
} OMX_CONFIG_COLORENHANCEMENTTYPE;
-/**
- * Define color key and color key mask
+/**
+ * Define color key and color key mask
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
- * nVersion : OMX specification version information
+ * nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* nARGBColor : 32bit Alpha, Red, Green, Blue Color
* nARGBMask : 32bit Mask for Alpha, Red, Green, Blue channels
@@ -261,12 +270,12 @@
} OMX_CONFIG_COLORKEYTYPE;
-/**
- * List of color blend types for pre/post processing
+/**
+ * List of color blend types for pre/post processing
*
* ENUMS:
* None : No color blending present
- * AlphaConstant : Function is (alpha_constant * src) +
+ * AlphaConstant : Function is (alpha_constant * src) +
* (1 - alpha_constant) * dst)
* AlphaPerPixel : Function is (alpha * src) + (1 - alpha) * dst)
* Alternate : Function is alternating pixels from src and dst
@@ -282,21 +291,21 @@
OMX_ColorBlendAnd,
OMX_ColorBlendOr,
OMX_ColorBlendInvert,
- OMX_ColorBlendKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_ColorBlendKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_ColorBlendVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_ColorBlendMax = 0x7FFFFFFF
} OMX_COLORBLENDTYPE;
-/**
- * Color blend configuration
+/**
+ * Color blend configuration
*
* STRUCT MEMBERS:
- * nSize : Size of the structure in bytes
- * nVersion : OMX specification version information
- * nPortIndex : Port that this structure applies to
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
* nRGBAlphaConstant : Constant global alpha values when global alpha is used
- * eColorBlend : Color blend type enumeration
+ * eColorBlend : Color blend type enumeration
*/
typedef struct OMX_CONFIG_COLORBLENDTYPE {
OMX_U32 nSize;
@@ -307,15 +316,15 @@
} OMX_CONFIG_COLORBLENDTYPE;
-/**
+/**
* Hold frame dimension
*
* STRUCT MEMBERS:
- * nSize : Size of the structure in bytes
+ * nSize : Size of the structure in bytes
* nVersion : OMX specification version information
- * nPortIndex : Port that this structure applies to
- * nWidth : Frame width in pixels
- * nHeight : Frame height in pixels
+ * nPortIndex : Port that this structure applies to
+ * nWidth : Frame width in pixels
+ * nHeight : Frame height in pixels
*/
typedef struct OMX_FRAMESIZETYPE {
OMX_U32 nSize;
@@ -327,69 +336,69 @@
/**
- * Rotation configuration
+ * Rotation configuration
*
* STRUCT MEMBERS:
- * nSize : Size of the structure in bytes
+ * nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
- * nRotation : +/- integer rotation value
+ * nRotation : +/- integer rotation value
*/
typedef struct OMX_CONFIG_ROTATIONTYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
- OMX_S32 nRotation;
+ OMX_S32 nRotation;
} OMX_CONFIG_ROTATIONTYPE;
-/**
- * Possible mirroring directions for pre/post processing
+/**
+ * Possible mirroring directions for pre/post processing
*
* ENUMS:
- * None : No mirroring
- * Vertical : Vertical mirroring, flip on X axis
- * Horizontal : Horizontal mirroring, flip on Y axis
+ * None : No mirroring
+ * Vertical : Vertical mirroring, flip on X axis
+ * Horizontal : Horizontal mirroring, flip on Y axis
* Both : Both vertical and horizontal mirroring
*/
typedef enum OMX_MIRRORTYPE {
OMX_MirrorNone = 0,
OMX_MirrorVertical,
OMX_MirrorHorizontal,
- OMX_MirrorBoth,
- OMX_MirrorKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_MirrorBoth,
+ OMX_MirrorKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_MirrorVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
- OMX_MirrorMax = 0x7FFFFFFF
+ OMX_MirrorMax = 0x7FFFFFFF
} OMX_MIRRORTYPE;
-/**
- * Mirroring configuration
+/**
+ * Mirroring configuration
*
* STRUCT MEMBERS:
- * nSize : Size of the structure in bytes
+ * nSize : Size of the structure in bytes
* nVersion : OMX specification version information
- * nPortIndex : Port that this structure applies to
- * eMirror : Mirror type enumeration
+ * nPortIndex : Port that this structure applies to
+ * eMirror : Mirror type enumeration
*/
typedef struct OMX_CONFIG_MIRRORTYPE {
OMX_U32 nSize;
- OMX_VERSIONTYPE nVersion;
+ OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
OMX_MIRRORTYPE eMirror;
} OMX_CONFIG_MIRRORTYPE;
-/**
- * Position information only
+/**
+ * Position information only
*
* STRUCT MEMBERS:
- * nSize : Size of the structure in bytes
+ * nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
- * nX : X coordinate for the point
- * nY : Y coordinate for the point
- */
+ * nX : X coordinate for the point
+ * nY : Y coordinate for the point
+ */
typedef struct OMX_CONFIG_POINTTYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
@@ -399,37 +408,37 @@
} OMX_CONFIG_POINTTYPE;
-/**
- * Frame size plus position
+/**
+ * Frame size plus position
*
* STRUCT MEMBERS:
- * nSize : Size of the structure in bytes
- * nVersion : OMX specification version information
- * nPortIndex : Port that this structure applies to
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
* nLeft : X Coordinate of the top left corner of the rectangle
* nTop : Y Coordinate of the top left corner of the rectangle
- * nWidth : Width of the rectangle
- * nHeight : Height of the rectangle
+ * nWidth : Width of the rectangle
+ * nHeight : Height of the rectangle
*/
typedef struct OMX_CONFIG_RECTTYPE {
OMX_U32 nSize;
- OMX_VERSIONTYPE nVersion;
- OMX_U32 nPortIndex;
- OMX_S32 nLeft;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_S32 nLeft;
OMX_S32 nTop;
OMX_U32 nWidth;
OMX_U32 nHeight;
} OMX_CONFIG_RECTTYPE;
-/**
- * Deblocking state; it is required to be set up before starting the codec
+/**
+ * Deblocking state; it is required to be set up before starting the codec
*
* STRUCT MEMBERS:
- * nSize : Size of the structure in bytes
- * nVersion : OMX specification version information
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
- * bDeblocking : Enable/disable deblocking mode
+ * bDeblocking : Enable/disable deblocking mode
*/
typedef struct OMX_PARAM_DEBLOCKINGTYPE {
OMX_U32 nSize;
@@ -439,13 +448,13 @@
} OMX_PARAM_DEBLOCKINGTYPE;
-/**
- * Stabilization state
+/**
+ * Stabilization state
*
* STRUCT MEMBERS:
- * nSize : Size of the structure in bytes
- * nVersion : OMX specification version information
- * nPortIndex : Port that this structure applies to
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
* bStab : Enable/disable frame stabilization state
*/
typedef struct OMX_CONFIG_FRAMESTABTYPE {
@@ -456,8 +465,8 @@
} OMX_CONFIG_FRAMESTABTYPE;
-/**
- * White Balance control type
+/**
+ * White Balance control type
*
* STRUCT MEMBERS:
* SunLight : Referenced in JSR-234
@@ -474,20 +483,20 @@
OMX_WhiteBalControlIncandescent,
OMX_WhiteBalControlFlash,
OMX_WhiteBalControlHorizon,
- OMX_WhiteBalControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_WhiteBalControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_WhiteBalControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_WhiteBalControlMax = 0x7FFFFFFF
} OMX_WHITEBALCONTROLTYPE;
-/**
- * White Balance control configuration
+/**
+ * White Balance control configuration
*
* STRUCT MEMBERS:
- * nSize : Size of the structure in bytes
+ * nSize : Size of the structure in bytes
* nVersion : OMX specification version information
- * nPortIndex : Port that this structure applies to
- * eWhiteBalControl : White balance enumeration
+ * nPortIndex : Port that this structure applies to
+ * eWhiteBalControl : White balance enumeration
*/
typedef struct OMX_CONFIG_WHITEBALCONTROLTYPE {
OMX_U32 nSize;
@@ -497,8 +506,8 @@
} OMX_CONFIG_WHITEBALCONTROLTYPE;
-/**
- * Exposure control type
+/**
+ * Exposure control type
*/
typedef enum OMX_EXPOSURECONTROLTYPE {
OMX_ExposureControlOff = 0,
@@ -511,20 +520,20 @@
OMX_ExposureControlBeach,
OMX_ExposureControlLargeAperture,
OMX_ExposureControlSmallApperture,
- OMX_ExposureControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_ExposureControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_ExposureControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_ExposureControlMax = 0x7FFFFFFF
} OMX_EXPOSURECONTROLTYPE;
-/**
- * White Balance control configuration
+/**
+ * White Balance control configuration
*
* STRUCT MEMBERS:
- * nSize : Size of the structure in bytes
+ * nSize : Size of the structure in bytes
* nVersion : OMX specification version information
- * nPortIndex : Port that this structure applies to
- * eExposureControl : Exposure control enumeration
+ * nPortIndex : Port that this structure applies to
+ * eExposureControl : Exposure control enumeration
*/
typedef struct OMX_CONFIG_EXPOSURECONTROLTYPE {
OMX_U32 nSize;
@@ -534,16 +543,16 @@
} OMX_CONFIG_EXPOSURECONTROLTYPE;
-/**
- * Defines sensor supported mode.
+/**
+ * Defines sensor supported mode.
*
* STRUCT MEMBERS:
- * nSize : Size of the structure in bytes
+ * nSize : Size of the structure in bytes
* nVersion : OMX specification version information
- * nPortIndex : Port that this structure applies to
- * nFrameRate : Single shot mode is indicated by a 0
+ * nPortIndex : Port that this structure applies to
+ * nFrameRate : Single shot mode is indicated by a 0
* bOneShot : Enable for single shot, disable for streaming
- * sFrameSize : Framesize
+ * sFrameSize : Framesize
*/
typedef struct OMX_PARAM_SENSORMODETYPE {
OMX_U32 nSize;
@@ -555,13 +564,13 @@
} OMX_PARAM_SENSORMODETYPE;
-/**
- * Defines contrast level
+/**
+ * Defines contrast level
*
* STRUCT MEMBERS:
- * nSize : Size of the structure in bytes
- * nVersion : OMX specification version information
- * nPortIndex : Port that this structure applies to
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
* nContrast : Values allowed for contrast -100 to 100, zero means no change
*/
typedef struct OMX_CONFIG_CONTRASTTYPE {
@@ -572,14 +581,14 @@
} OMX_CONFIG_CONTRASTTYPE;
-/**
- * Defines brightness level
+/**
+ * Defines brightness level
*
* STRUCT MEMBERS:
- * nSize : Size of the structure in bytes
- * nVersion : OMX specification version information
- * nPortIndex : Port that this structure applies to
- * nBrightness : 0-100%
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * nBrightness : 0-100%
*/
typedef struct OMX_CONFIG_BRIGHTNESSTYPE {
OMX_U32 nSize;
@@ -589,16 +598,16 @@
} OMX_CONFIG_BRIGHTNESSTYPE;
-/**
- * Defines backlight level configuration for a video sink, e.g. LCD panel
+/**
+ * Defines backlight level configuration for a video sink, e.g. LCD panel
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
- * nVersion : OMX specification version information
+ * nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* nBacklight : Values allowed for backlight 0-100%
- * nTimeout : Number of milliseconds before backlight automatically turns
- * off. A value of 0x0 disables backight timeout
+ * nTimeout : Number of milliseconds before backlight automatically turns
+ * off. A value of 0x0 disables backight timeout
*/
typedef struct OMX_CONFIG_BACKLIGHTTYPE {
OMX_U32 nSize;
@@ -609,12 +618,12 @@
} OMX_CONFIG_BACKLIGHTTYPE;
-/**
- * Defines setting for Gamma
+/**
+ * Defines setting for Gamma
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
- * nVersion : OMX specification version information
+ * nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* nGamma : Values allowed for gamma -100 to 100, zero means no change
*/
@@ -626,14 +635,14 @@
} OMX_CONFIG_GAMMATYPE;
-/**
- * Define for setting saturation
- *
+/**
+ * Define for setting saturation
+ *
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
- * nSaturation : Values allowed for saturation -100 to 100, zero means
+ * nSaturation : Values allowed for saturation -100 to 100, zero means
* no change
*/
typedef struct OMX_CONFIG_SATURATIONTYPE {
@@ -644,14 +653,14 @@
} OMX_CONFIG_SATURATIONTYPE;
-/**
- * Define for setting Lightness
+/**
+ * Define for setting Lightness
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
- * nLightness : Values allowed for lightness -100 to 100, zero means no
+ * nLightness : Values allowed for lightness -100 to 100, zero means no
* change
*/
typedef struct OMX_CONFIG_LIGHTNESSTYPE {
@@ -662,17 +671,17 @@
} OMX_CONFIG_LIGHTNESSTYPE;
-/**
- * Plane blend configuration
+/**
+ * Plane blend configuration
*
* STRUCT MEMBERS:
- * nSize : Size of the structure in bytes
+ * nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Index of input port associated with the plane.
- * nDepth : Depth of the plane in relation to the screen. Higher
- * numbered depths are "behind" lower number depths.
+ * nDepth : Depth of the plane in relation to the screen. Higher
+ * numbered depths are "behind" lower number depths.
* This number defaults to the Port Index number.
- * nAlpha : Transparency blending component for the entire plane.
+ * nAlpha : Transparency blending component for the entire plane.
* See blending modes for more detail.
*/
typedef struct OMX_CONFIG_PLANEBLENDTYPE {
@@ -684,17 +693,17 @@
} OMX_CONFIG_PLANEBLENDTYPE;
-/**
+/**
* Define interlace type
*
* STRUCT MEMBERS:
- * nSize : Size of the structure in bytes
- * nVersion : OMX specification version information
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
- * bEnable : Enable control variable for this functionality
+ * bEnable : Enable control variable for this functionality
* (see below)
- * nInterleavePortIndex : Index of input or output port associated with
- * the interleaved plane.
+ * nInterleavePortIndex : Index of input or output port associated with
+ * the interleaved plane.
* pPlanarPortIndexes[4] : Index of input or output planar ports.
*/
typedef struct OMX_PARAM_INTERLEAVETYPE {
@@ -706,8 +715,8 @@
} OMX_PARAM_INTERLEAVETYPE;
-/**
- * Defines the picture effect used for an input picture
+/**
+ * Defines the picture effect used for an input picture
*/
typedef enum OMX_TRANSITIONEFFECTTYPE {
OMX_EffectNone,
@@ -717,18 +726,18 @@
OMX_EffectDissolve,
OMX_EffectWipe,
OMX_EffectUnspecifiedMixOfTwoScenes,
- OMX_EffectKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_EffectKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_EffectVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_EffectMax = 0x7FFFFFFF
} OMX_TRANSITIONEFFECTTYPE;
-/**
- * Structure used to configure current transition effect
+/**
+ * Structure used to configure current transition effect
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
- * nVersion : OMX specification version information
+ * nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* eEffect : Effect to enable
*/
@@ -740,43 +749,43 @@
} OMX_CONFIG_TRANSITIONEFFECTTYPE;
-/**
- * Defines possible data unit types for encoded video data. The data unit
+/**
+ * Defines possible data unit types for encoded video data. The data unit
* types are used both for encoded video input for playback as well as
- * encoded video output from recording.
+ * encoded video output from recording.
*/
typedef enum OMX_DATAUNITTYPE {
OMX_DataUnitCodedPicture,
OMX_DataUnitVideoSegment,
OMX_DataUnitSeveralSegments,
OMX_DataUnitArbitraryStreamSection,
- OMX_DataUnitKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_DataUnitKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_DataUnitVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_DataUnitMax = 0x7FFFFFFF
} OMX_DATAUNITTYPE;
-/**
- * Defines possible encapsulation types for coded video data unit. The
- * encapsulation information is used both for encoded video input for
- * playback as well as encoded video output from recording.
+/**
+ * Defines possible encapsulation types for coded video data unit. The
+ * encapsulation information is used both for encoded video input for
+ * playback as well as encoded video output from recording.
*/
typedef enum OMX_DATAUNITENCAPSULATIONTYPE {
OMX_DataEncapsulationElementaryStream,
OMX_DataEncapsulationGenericPayload,
OMX_DataEncapsulationRtpPayload,
- OMX_DataEncapsulationKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_DataEncapsulationKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_DataEncapsulationVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_DataEncapsulationMax = 0x7FFFFFFF
} OMX_DATAUNITENCAPSULATIONTYPE;
-/**
- * Structure used to configure the type of being decoded/encoded
+/**
+ * Structure used to configure the type of being decoded/encoded
*/
typedef struct OMX_PARAM_DATAUNITTYPE {
OMX_U32 nSize; /**< Size of the structure in bytes */
- OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
OMX_U32 nPortIndex; /**< Port that this structure applies to */
OMX_DATAUNITTYPE eUnitType;
OMX_DATAUNITENCAPSULATIONTYPE eEncapsulationType;
@@ -784,25 +793,25 @@
/**
- * Defines dither types
+ * Defines dither types
*/
typedef enum OMX_DITHERTYPE {
OMX_DitherNone,
OMX_DitherOrdered,
OMX_DitherErrorDiffusion,
OMX_DitherOther,
- OMX_DitherKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_DitherKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_DitherVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_DitherMax = 0x7FFFFFFF
} OMX_DITHERTYPE;
-/**
- * Structure used to configure current type of dithering
+/**
+ * Structure used to configure current type of dithering
*/
typedef struct OMX_CONFIG_DITHERTYPE {
OMX_U32 nSize; /**< Size of the structure in bytes */
- OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
OMX_U32 nPortIndex; /**< Port that this structure applies to */
OMX_DITHERTYPE eDither; /**< Type of dithering to use */
} OMX_CONFIG_DITHERTYPE;
@@ -811,28 +820,28 @@
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex; /**< Port that this structure applies to */
- OMX_BOOL bContinuous; /**< If true then ignore frame rate and emit capture
+ OMX_BOOL bContinuous; /**< If true then ignore frame rate and emit capture
* data as fast as possible (otherwise obey port's frame rate). */
- OMX_BOOL bFrameLimited; /**< If true then terminate capture after the port emits the
- * specified number of frames (otherwise the port does not
- * terminate the capture until instructed to do so by the client).
- * Even if set, the client may manually terminate the capture prior
+ OMX_BOOL bFrameLimited; /**< If true then terminate capture after the port emits the
+ * specified number of frames (otherwise the port does not
+ * terminate the capture until instructed to do so by the client).
+ * Even if set, the client may manually terminate the capture prior
* to reaching the limit. */
OMX_U32 nFrameLimit; /**< Limit on number of frames emitted during a capture (only
* valid if bFrameLimited is set). */
} OMX_CONFIG_CAPTUREMODETYPE;
typedef enum OMX_METERINGTYPE {
-
+
OMX_MeteringModeAverage, /**< Center-weighted average metering. */
OMX_MeteringModeSpot, /**< Spot (partial) metering. */
OMX_MeteringModeMatrix, /**< Matrix or evaluative metering. */
-
- OMX_MeteringKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+
+ OMX_MeteringKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_MeteringVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_EVModeMax = 0x7fffffff
} OMX_METERINGTYPE;
-
+
typedef struct OMX_CONFIG_EXPOSUREVALUETYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
@@ -841,14 +850,14 @@
OMX_S32 xEVCompensation; /**< Fixed point value stored as Q16 */
OMX_U32 nApertureFNumber; /**< e.g. nApertureFNumber = 2 implies "f/2" - Q16 format */
OMX_BOOL bAutoAperture; /**< Whether aperture number is defined automatically */
- OMX_U32 nShutterSpeedMsec; /**< Shutterspeed in milliseconds */
- OMX_BOOL bAutoShutterSpeed; /**< Whether shutter speed is defined automatically */
+ OMX_U32 nShutterSpeedMsec; /**< Shutterspeed in milliseconds */
+ OMX_BOOL bAutoShutterSpeed; /**< Whether shutter speed is defined automatically */
OMX_U32 nSensitivity; /**< e.g. nSensitivity = 100 implies "ISO 100" */
OMX_BOOL bAutoSensitivity; /**< Whether sensitivity is defined automatically */
} OMX_CONFIG_EXPOSUREVALUETYPE;
-/**
- * Focus region configuration
+/**
+ * Focus region configuration
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
@@ -879,8 +888,8 @@
OMX_BOOL bBottomRight;
} OMX_CONFIG_FOCUSREGIONTYPE;
-/**
- * Focus Status type
+/**
+ * Focus Status type
*/
typedef enum OMX_FOCUSSTATUSTYPE {
OMX_FocusStatusOff = 0,
@@ -888,13 +897,13 @@
OMX_FocusStatusReached,
OMX_FocusStatusUnableToReach,
OMX_FocusStatusLost,
- OMX_FocusStatusKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_FocusStatusKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_FocusStatusVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_FocusStatusMax = 0x7FFFFFFF
} OMX_FOCUSSTATUSTYPE;
-/**
- * Focus status configuration
+/**
+ * Focus status configuration
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
diff --git a/include/media/stagefright/openmax/OMX_Video.h b/include/media/stagefright/openmax/OMX_Video.h
index 2738bdc..4f8485d 100644
--- a/include/media/stagefright/openmax/OMX_Video.h
+++ b/include/media/stagefright/openmax/OMX_Video.h
@@ -85,6 +85,7 @@
OMX_VIDEO_CodingRV, /**< all versions of Real Video */
OMX_VIDEO_CodingAVC, /**< H.264/AVC */
OMX_VIDEO_CodingMJPEG, /**< Motion JPEG */
+ OMX_VIDEO_CodingVPX, /**< Google VPX, formerly known as On2 VP8 */
OMX_VIDEO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_VIDEO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_VIDEO_CodingMax = 0x7FFFFFFF
diff --git a/include/private/binder/binder_module.h b/include/private/binder/binder_module.h
index fdf327e..a8dd64f 100644
--- a/include/private/binder/binder_module.h
+++ b/include/private/binder/binder_module.h
@@ -21,126 +21,11 @@
namespace android {
#endif
-#if defined(HAVE_ANDROID_OS)
-
/* obtain structures and constants from the kernel header */
#include <sys/ioctl.h>
#include <linux/binder.h>
-#else
-
-/* Some parts of the simulator need fake versions of this
- * stuff in order to compile. Really this should go away
- * entirely...
- */
-
-#define BINDER_CURRENT_PROTOCOL_VERSION 7
-
-#define BINDER_TYPE_BINDER 1
-#define BINDER_TYPE_WEAK_BINDER 2
-#define BINDER_TYPE_HANDLE 3
-#define BINDER_TYPE_WEAK_HANDLE 4
-#define BINDER_TYPE_FD 5
-
-struct flat_binder_object {
- unsigned long type;
- unsigned long flags;
- union {
- void *binder;
- signed long handle;
- };
- void *cookie;
-};
-
-struct binder_write_read {
- signed long write_size;
- signed long write_consumed;
- unsigned long write_buffer;
- signed long read_size;
- signed long read_consumed;
- unsigned long read_buffer;
-};
-
-struct binder_transaction_data {
- union {
- size_t handle;
- void *ptr;
- } target;
- void *cookie;
- unsigned int code;
-
- unsigned int flags;
- pid_t sender_pid;
- uid_t sender_euid;
- size_t data_size;
- size_t offsets_size;
-
- union {
- struct {
- const void *buffer;
- const void *offsets;
- } ptr;
- uint8_t buf[8];
- } data;
-};
-
-enum transaction_flags {
- TF_ONE_WAY = 0x01,
- TF_ROOT_OBJECT = 0x04,
- TF_STATUS_CODE = 0x08,
- TF_ACCEPT_FDS = 0x10,
-};
-
-
-enum {
- FLAT_BINDER_FLAG_PRIORITY_MASK = 0xff,
- FLAT_BINDER_FLAG_ACCEPTS_FDS = 0x100,
-};
-
-enum BinderDriverReturnProtocol {
- BR_ERROR,
- BR_OK,
- BR_TRANSACTION,
- BR_REPLY,
- BR_ACQUIRE_RESULT,
- BR_DEAD_REPLY,
- BR_TRANSACTION_COMPLETE,
- BR_INCREFS,
- BR_ACQUIRE,
- BR_RELEASE,
- BR_DECREFS,
- BR_ATTEMPT_ACQUIRE,
- BR_NOOP,
- BR_SPAWN_LOOPER,
- BR_FINISHED,
- BR_DEAD_BINDER,
- BR_CLEAR_DEATH_NOTIFICATION_DONE,
- BR_FAILED_REPLY,
-};
-
-enum BinderDriverCommandProtocol {
- BC_TRANSACTION,
- BC_REPLY,
- BC_ACQUIRE_RESULT,
- BC_FREE_BUFFER,
- BC_INCREFS,
- BC_ACQUIRE,
- BC_RELEASE,
- BC_DECREFS,
- BC_INCREFS_DONE,
- BC_ACQUIRE_DONE,
- BC_ATTEMPT_ACQUIRE,
- BC_REGISTER_LOOPER,
- BC_ENTER_LOOPER,
- BC_EXIT_LOOPER,
- BC_REQUEST_DEATH_NOTIFICATION,
- BC_CLEAR_DEATH_NOTIFICATION,
- BC_DEAD_BINDER_DONE,
-};
-
-#endif
-
#ifdef __cplusplus
} // namespace android
#endif
diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h
index 4610135..20abd51 100644
--- a/include/private/media/AudioTrackShared.h
+++ b/include/private/media/AudioTrackShared.h
@@ -26,7 +26,6 @@
// ----------------------------------------------------------------------------
-#define THREAD_PRIORITY_AUDIO_CLIENT (ANDROID_PRIORITY_AUDIO)
// Maximum cumulated timeout milliseconds before restarting audioflinger thread
#define MAX_STARTUP_TIMEOUT_MS 3000 // Longer timeout period at startup to cope with A2DP init time
#define MAX_RUN_TIMEOUT_MS 1000
@@ -82,15 +81,15 @@
// 16 bit because data is converted to 16 bit before being stored in buffer
uint8_t frameSize;
- uint8_t channelCount;
- uint16_t flags;
-
+ uint8_t pad1;
uint16_t bufferTimeoutMs; // Maximum cumulated timeout before restarting audioflinger
- uint16_t waitTimeMs; // Cumulated wait time
+ uint16_t waitTimeMs; // Cumulated wait time
uint16_t sendLevel;
- uint16_t reserved;
+ volatile int32_t flags;
+
// Cache line boundary (32 bytes)
+
audio_track_cblk_t();
uint32_t stepUser(uint32_t frameCount);
bool stepServer(uint32_t frameCount);
@@ -98,6 +97,7 @@
uint32_t framesAvailable();
uint32_t framesAvailable_l();
uint32_t framesReady();
+ bool tryLock();
};
diff --git a/include/private/opengles/gl_context.h b/include/private/opengles/gl_context.h
index c7db9a6..6b1fa77 100644
--- a/include/private/opengles/gl_context.h
+++ b/include/private/opengles/gl_context.h
@@ -26,14 +26,11 @@
#endif
#include <private/pixelflinger/ggl_context.h>
-#include <hardware/copybit.h>
#include <hardware/gralloc.h>
#include <GLES/gl.h>
#include <GLES/glext.h>
-struct android_native_buffer_t;
-
namespace android {
@@ -604,14 +601,6 @@
void (*renderTriangle)(GL, vertex_t*, vertex_t*, vertex_t*);
};
-struct copybits_context_t {
- // A handle to the blit engine, if it exists, else NULL.
- copybit_device_t* blitEngine;
- int32_t minScale;
- int32_t maxScale;
- android_native_buffer_t* drawSurfaceBuffer;
-};
-
struct ogles_context_t {
context_t rasterizer;
array_machine_t arrays __attribute__((aligned(32)));
@@ -636,13 +625,6 @@
EGLSurfaceManager* surfaceManager;
EGLBufferObjectManager* bufferObjectManager;
- // copybits is only used if LIBAGL_USE_GRALLOC_COPYBITS is
- // defined, but it is always present because ogles_context_t is a public
- // struct that is used by clients of libagl. We want the size and offsets
- // to stay the same, whether or not LIBAGL_USE_GRALLOC_COPYBITS is defined.
-
- copybits_context_t copybits;
-
GLenum error;
static inline ogles_context_t* get() {
diff --git a/include/private/surfaceflinger/LayerState.h b/include/private/surfaceflinger/LayerState.h
index d7fe572..d2fed41 100644
--- a/include/private/surfaceflinger/LayerState.h
+++ b/include/private/surfaceflinger/LayerState.h
@@ -29,6 +29,7 @@
namespace android {
class Parcel;
+class ISurfaceComposerClient;
struct layer_state_t {
@@ -68,6 +69,13 @@
Region transparentRegion;
};
+struct ComposerState {
+ sp<ISurfaceComposerClient> client;
+ layer_state_t state;
+ status_t write(Parcel& output) const;
+ status_t read(const Parcel& input);
+};
+
}; // namespace android
#endif // ANDROID_SF_LAYER_STATE_H
diff --git a/include/private/surfaceflinger/SharedBufferStack.h b/include/private/surfaceflinger/SharedBufferStack.h
index 717f837..0da03d1 100644
--- a/include/private/surfaceflinger/SharedBufferStack.h
+++ b/include/private/surfaceflinger/SharedBufferStack.h
@@ -20,355 +20,12 @@
#include <stdint.h>
#include <sys/types.h>
-#include <cutils/compiler.h>
-
#include <utils/Debug.h>
-#include <utils/threads.h>
-#include <utils/String8.h>
-
-#include <ui/Rect.h>
namespace android {
// ---------------------------------------------------------------------------
-/*
- * These classes manage a stack of buffers in shared memory.
- *
- * SharedClient: represents a client with several stacks
- * SharedBufferStack: represents a stack of buffers
- * SharedBufferClient: manipulates the SharedBufferStack from the client side
- * SharedBufferServer: manipulates the SharedBufferStack from the server side
- *
- * Buffers can be dequeued until there are none available, they can be locked
- * unless they are in use by the server, which is only the case for the last
- * dequeue-able buffer. When these various conditions are not met, the caller
- * waits until the condition is met.
- *
- */
-
-// ----------------------------------------------------------------------------
-
-class Region;
-class SharedBufferStack;
-class SharedClient;
-
-// ----------------------------------------------------------------------------
-
-class SharedBufferStack
-{
- friend class SharedClient;
- friend class SharedBufferBase;
- friend class SharedBufferClient;
- friend class SharedBufferServer;
-
-public:
- // When changing these values, the COMPILE_TIME_ASSERT at the end of this
- // file need to be updated.
- static const unsigned int NUM_LAYERS_MAX = 31;
- static const unsigned int NUM_BUFFER_MAX = 32;
- static const unsigned int NUM_BUFFER_MIN = 2;
- static const unsigned int NUM_DISPLAY_MAX = 4;
-
- struct Statistics { // 4 longs
- typedef int32_t usecs_t;
- usecs_t totalTime;
- usecs_t reserved[3];
- };
-
- struct SmallRect {
- uint16_t l, t, r, b;
- };
-
- struct FlatRegion { // 52 bytes = 4 * (1 + 2*N)
- static const unsigned int NUM_RECT_MAX = 5;
- uint32_t count;
- SmallRect rects[NUM_RECT_MAX];
- };
-
- struct BufferData {
- FlatRegion dirtyRegion;
- SmallRect crop;
- uint8_t transform;
- uint8_t reserved[3];
- };
-
- SharedBufferStack();
- void init(int32_t identity);
- status_t setDirtyRegion(int buffer, const Region& reg);
- status_t setCrop(int buffer, const Rect& reg);
- status_t setTransform(int buffer, uint8_t transform);
- Region getDirtyRegion(int buffer) const;
- Rect getCrop(int buffer) const;
- uint32_t getTransform(int buffer) const;
-
- // these attributes are part of the conditions/updates
- volatile int32_t head; // server's current front buffer
- volatile int32_t available; // number of dequeue-able buffers
- volatile int32_t queued; // number of buffers waiting for post
- volatile int32_t reserved1;
- volatile status_t status; // surface's status code
-
- // not part of the conditions
- volatile int32_t reallocMask;
- volatile int8_t index[NUM_BUFFER_MAX];
-
- int32_t identity; // surface's identity (const)
- int32_t token; // surface's token (for debugging)
- Statistics stats;
- int8_t headBuf; // last retired buffer
- uint8_t reservedBytes[3];
- int32_t reserved;
- BufferData buffers[NUM_BUFFER_MAX]; // 1024 bytes
-};
-
-// ----------------------------------------------------------------------------
-
-// 64 KB max
-class SharedClient
-{
-public:
- SharedClient();
- ~SharedClient();
- status_t validate(size_t token) const;
-
-private:
- friend class SharedBufferBase;
- friend class SharedBufferClient;
- friend class SharedBufferServer;
-
- // FIXME: this should be replaced by a lock-less primitive
- Mutex lock;
- Condition cv;
- SharedBufferStack surfaces[ SharedBufferStack::NUM_LAYERS_MAX ];
-};
-
-// ============================================================================
-
-class SharedBufferBase
-{
-public:
- SharedBufferBase(SharedClient* sharedClient, int surface,
- int32_t identity);
- ~SharedBufferBase();
- status_t getStatus() const;
- int32_t getIdentity() const;
- String8 dump(char const* prefix) const;
-
-protected:
- SharedClient* const mSharedClient;
- SharedBufferStack* const mSharedStack;
- const int mIdentity;
-
- friend struct Update;
- friend struct QueueUpdate;
-
- struct ConditionBase {
- SharedBufferStack& stack;
- inline ConditionBase(SharedBufferBase* sbc)
- : stack(*sbc->mSharedStack) { }
- virtual ~ConditionBase() { };
- virtual bool operator()() const = 0;
- virtual const char* name() const = 0;
- };
- status_t waitForCondition(const ConditionBase& condition);
-
- struct UpdateBase {
- SharedBufferStack& stack;
- inline UpdateBase(SharedBufferBase* sbb)
- : stack(*sbb->mSharedStack) { }
- };
- template <typename T>
- status_t updateCondition(T update);
-};
-
-template <typename T>
-status_t SharedBufferBase::updateCondition(T update) {
- SharedClient& client( *mSharedClient );
- Mutex::Autolock _l(client.lock);
- ssize_t result = update();
- client.cv.broadcast();
- return result;
-}
-
-// ----------------------------------------------------------------------------
-
-class SharedBufferClient : public SharedBufferBase
-{
-public:
- SharedBufferClient(SharedClient* sharedClient, int surface, int num,
- int32_t identity);
-
- ssize_t dequeue();
- status_t undoDequeue(int buf);
-
- status_t lock(int buf);
- status_t cancel(int buf);
- status_t queue(int buf);
- bool needNewBuffer(int buffer) const;
- status_t setDirtyRegion(int buffer, const Region& reg);
- status_t setCrop(int buffer, const Rect& reg);
- status_t setTransform(int buffer, uint32_t transform);
-
- class SetBufferCountCallback {
- friend class SharedBufferClient;
- virtual status_t operator()(int bufferCount) const = 0;
- protected:
- virtual ~SetBufferCountCallback() { }
- };
- status_t setBufferCount(int bufferCount, const SetBufferCountCallback& ipc);
-
-private:
- friend struct Condition;
- friend struct DequeueCondition;
- friend struct LockCondition;
-
- struct QueueUpdate : public UpdateBase {
- inline QueueUpdate(SharedBufferBase* sbb);
- inline ssize_t operator()();
- };
-
- struct DequeueUpdate : public UpdateBase {
- inline DequeueUpdate(SharedBufferBase* sbb);
- inline ssize_t operator()();
- };
-
- struct CancelUpdate : public UpdateBase {
- int tail, buf;
- inline CancelUpdate(SharedBufferBase* sbb, int tail, int buf);
- inline ssize_t operator()();
- };
-
- // --
-
- struct DequeueCondition : public ConditionBase {
- inline DequeueCondition(SharedBufferClient* sbc);
- inline bool operator()() const;
- inline const char* name() const { return "DequeueCondition"; }
- };
-
- struct LockCondition : public ConditionBase {
- int buf;
- inline LockCondition(SharedBufferClient* sbc, int buf);
- inline bool operator()() const;
- inline const char* name() const { return "LockCondition"; }
- };
-
- int32_t computeTail() const;
-
- mutable RWLock mLock;
- int mNumBuffers;
-
- int32_t tail;
- int32_t queued_head;
- // statistics...
- nsecs_t mDequeueTime[SharedBufferStack::NUM_BUFFER_MAX];
-};
-
-// ----------------------------------------------------------------------------
-
-class SharedBufferServer
- : public SharedBufferBase,
- public LightRefBase<SharedBufferServer>
-{
-public:
- SharedBufferServer(SharedClient* sharedClient, int surface, int num,
- int32_t identity);
-
- ssize_t retireAndLock();
- void setStatus(status_t status);
- status_t reallocateAll();
- status_t reallocateAllExcept(int buffer);
- int32_t getQueuedCount() const;
- Region getDirtyRegion(int buffer) const;
- Rect getCrop(int buffer) const;
- uint32_t getTransform(int buffer) const;
-
- status_t resize(int newNumBuffers);
- status_t grow(int newNumBuffers);
- status_t shrink(int newNumBuffers);
-
- SharedBufferStack::Statistics getStats() const;
-
-
-private:
- friend class LightRefBase<SharedBufferServer>;
- ~SharedBufferServer();
-
- /*
- * BufferList is basically a fixed-capacity sorted-vector of
- * unsigned 5-bits ints using a 32-bits int as storage.
- * it has efficient iterators to find items in the list and not in the list.
- */
- class BufferList {
- size_t mCapacity;
- uint32_t mList;
- public:
- BufferList(size_t c = SharedBufferStack::NUM_BUFFER_MAX)
- : mCapacity(c), mList(0) { }
- status_t add(int value);
- status_t remove(int value);
- uint32_t getMask() const { return mList; }
-
- class const_iterator {
- friend class BufferList;
- uint32_t mask, curr;
- const_iterator(uint32_t mask) :
- mask(mask), curr(__builtin_clz(mask)) {
- }
- public:
- inline bool operator == (const const_iterator& rhs) const {
- return mask == rhs.mask;
- }
- inline bool operator != (const const_iterator& rhs) const {
- return mask != rhs.mask;
- }
- inline int operator *() const { return curr; }
- inline const const_iterator& operator ++() {
- mask &= ~(1<<(31-curr));
- curr = __builtin_clz(mask);
- return *this;
- }
- };
-
- inline const_iterator begin() const {
- return const_iterator(mList);
- }
- inline const_iterator end() const {
- return const_iterator(0);
- }
- inline const_iterator free_begin() const {
- uint32_t mask = (1 << (32-mCapacity)) - 1;
- return const_iterator( ~(mList | mask) );
- }
- };
-
- // this protects mNumBuffers and mBufferList
- mutable RWLock mLock;
- int mNumBuffers;
- BufferList mBufferList;
-
- struct BuffersAvailableCondition : public ConditionBase {
- int mNumBuffers;
- inline BuffersAvailableCondition(SharedBufferServer* sbs,
- int numBuffers);
- inline bool operator()() const;
- inline const char* name() const { return "BuffersAvailableCondition"; }
- };
-
- struct RetireUpdate : public UpdateBase {
- const int numBuffers;
- inline RetireUpdate(SharedBufferBase* sbb, int numBuffers);
- inline ssize_t operator()();
- };
-
- struct StatusUpdate : public UpdateBase {
- const status_t status;
- inline StatusUpdate(SharedBufferBase* sbb, status_t status);
- inline ssize_t operator()();
- };
-};
-
-// ===========================================================================
+#define NUM_DISPLAY_MAX 4
struct display_cblk_t
{
@@ -389,12 +46,11 @@
uint8_t connected;
uint8_t reserved[3];
uint32_t pad[7];
- display_cblk_t displays[SharedBufferStack::NUM_DISPLAY_MAX];
+ display_cblk_t displays[NUM_DISPLAY_MAX];
};
// ---------------------------------------------------------------------------
-COMPILE_TIME_ASSERT(sizeof(SharedClient) <= 65536)
COMPILE_TIME_ASSERT(sizeof(surface_flinger_cblk_t) <= 4096)
// ---------------------------------------------------------------------------
diff --git a/media/libeffects/data/audio_effects.conf b/media/libeffects/data/audio_effects.conf
new file mode 100644
index 0000000..b8fa487
--- /dev/null
+++ b/media/libeffects/data/audio_effects.conf
@@ -0,0 +1,126 @@
+# List of effect libraries to load. Each library element must contain a "path" element
+# giving the full path of the library .so file.
+# libraries {
+# <lib name> {
+# path <lib path>
+# }
+# }
+libraries {
+ bundle {
+ path /system/lib/soundfx/libbundlewrapper.so
+ }
+ reverb {
+ path /system/lib/soundfx/libreverbwrapper.so
+ }
+ visualizer {
+ path /system/lib/soundfx/libvisualizer.so
+ }
+ pre_processing {
+ path /system/lib/soundfx/libaudiopreprocessing.so
+ }
+}
+
+# list of effects to load. Each effect element must contain a "library" and a "uuid" element.
+# The value of the "library" element must correspond to the name of one library element in the
+# "libraries" element.
+# The name of the effect element is indicative, only the value of the "uuid" element
+# designates the effect.
+# The uuid is the implementation specific UUID as specified by the effect vendor. This is not the
+# generic effect type UUID.
+# effects {
+# <fx name> {
+# library <lib name>
+# uuid <effect uuid>
+# }
+# ...
+# }
+
+effects {
+ bassboost {
+ library bundle
+ uuid 8631f300-72e2-11df-b57e-0002a5d5c51b
+ }
+ virtualizer {
+ library bundle
+ uuid 1d4033c0-8557-11df-9f2d-0002a5d5c51b
+ }
+ equalizer {
+ library bundle
+ uuid ce772f20-847d-11df-bb17-0002a5d5c51b
+ }
+ volume {
+ library bundle
+ uuid 119341a0-8469-11df-81f9- 0002a5d5c51b
+ }
+ reverb_env_aux {
+ library reverb
+ uuid 4a387fc0-8ab3-11df-8bad- 0002a5d5c51b
+ }
+ reverb_env_ins {
+ library reverb
+ uuid c7a511a0-a3bb-11df-860e-0002a5d5c51b
+ }
+ reverb_pre_aux {
+ library reverb
+ uuid f29a1400-a3bb-11df-8ddc-0002a5d5c51b
+ }
+ reverb_pre_ins {
+ library reverb
+ uuid 172cdf00-a3bc-11df-a72f-0002a5d5c51b
+ }
+ visualizer {
+ library visualizer
+ uuid d069d9e0-8329-11df-9168-0002a5d5c51b
+ }
+ agc {
+ library pre_processing
+ uuid aa8130e0-66fc-11e0-bad0-0002a5d5c51b
+ }
+ aec {
+ library pre_processing
+ uuid bb392ec0-8d4d-11e0-a896-0002a5d5c51b
+ }
+ ns {
+ library pre_processing
+ uuid c06c8400-8e06-11e0-9cb6-0002a5d5c51b
+ }
+}
+# Audio preprocessor configurations.
+# The pre processor configuration consists in a list of elements each describing
+# pre processor settings for a given input source. Valid input source names are:
+# "mic", "camcorder", "voice_recognition", "voice_communication"
+# Each input source element contains a list of effects elements. The name of the effect
+# element must be the name of one of the effects in the "effects" list of the file.
+# Each effect element may optionally contain a list of parameters and their
+# default value to apply when the pre processor effect is created.
+# A parameter is defined by a "param" element and a "value" element. Each of these elements
+# consists in one or more elements specifying a type followed by a value.
+# The types defined are: "int", "short", "float", "bool" and "string"
+# When both "param" and "value" are a single int, a simple form is allowed where just
+# the param and value pair is present in the parameter description
+# pre_processing {
+# <input source name> {
+# <fx name> {
+# <param 1 name> {
+# param {
+# int|short|float|bool|string <value>
+# [ int|short|float|bool|string <value> ]
+# ...
+# }
+# value {
+# int|short|float|bool|string <value>
+# [ int|short|float|bool|string <value> ]
+# ...
+# }
+# }
+# <param 2 name > {<param> <value>}
+# ...
+# }
+# ...
+# }
+# ...
+# }
+
+#
+# TODO: add default audio pre processor configurations after debug and tuning phase
+#
diff --git a/media/libeffects/factory/Android.mk b/media/libeffects/factory/Android.mk
index 20f58e5..2f2b974 100644
--- a/media/libeffects/factory/Android.mk
+++ b/media/libeffects/factory/Android.mk
@@ -12,14 +12,9 @@
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)
LOCAL_MODULE:= libeffects
-ifeq ($(TARGET_OS)-$(TARGET_SIMULATOR),linux-true)
-LOCAL_LDLIBS += -ldl
-endif
-
-ifneq ($(TARGET_SIMULATOR),true)
LOCAL_SHARED_LIBRARIES += libdl
-endif
LOCAL_C_INCLUDES := \
+ system/media/audio_effects/include
include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libeffects/factory/EffectsFactory.c b/media/libeffects/factory/EffectsFactory.c
index c19a505..d333510 100644
--- a/media/libeffects/factory/EffectsFactory.c
+++ b/media/libeffects/factory/EffectsFactory.c
@@ -22,6 +22,9 @@
#include <stdlib.h>
#include <dlfcn.h>
+#include <cutils/misc.h>
+#include <cutils/config_utils.h>
+#include <audio_effects/audio_effects_conf.h>
static list_elem_t *gEffectList; // list of effect_entry_t: all currently created effects
static list_elem_t *gLibraryList; // list of lib_entry_t: all currently loaded libraries
@@ -30,30 +33,39 @@
static list_elem_t *gCurLib; // current library in enumeration process
static list_elem_t *gCurEffect; // current effect in enumeration process
static uint32_t gCurEffectIdx; // current effect index in enumeration process
+static lib_entry_t *gCachedLibrary; // last library accessed by getLibrary()
-const char * const gEffectLibPath = "/system/lib/soundfx"; // path to built-in effect libraries
static int gInitDone; // true is global initialization has been preformed
-static int gNextLibId; // used by loadLibrary() to allocate unique library handles
static int gCanQueryEffect; // indicates that call to EffectQueryEffect() is valid, i.e. that the list of effects
// was not modified since last call to EffectQueryNumberEffects()
+
/////////////////////////////////////////////////
// Local functions prototypes
/////////////////////////////////////////////////
static int init();
-static int loadLibrary(const char *libPath, int *handle);
-static int unloadLibrary(int handle);
+static int loadEffectConfigFile(const char *path);
+static int loadLibraries(cnode *root);
+static int loadLibrary(cnode *root, const char *name);
+static int loadEffects(cnode *root);
+static int loadEffect(cnode *node);
+static lib_entry_t *getLibrary(const char *path);
static void resetEffectEnumeration();
static uint32_t updateNumEffects();
-static int findEffect(effect_uuid_t *uuid, lib_entry_t **lib, effect_descriptor_t **desc);
+static int findEffect(effect_uuid_t *type,
+ effect_uuid_t *uuid,
+ lib_entry_t **lib,
+ effect_descriptor_t **desc);
static void dumpEffectDescriptor(effect_descriptor_t *desc, char *str, size_t len);
+static int stringToUuid(const char *str, effect_uuid_t *uuid);
+static int uuidToString(const effect_uuid_t *uuid, char *str, size_t maxLen);
/////////////////////////////////////////////////
// Effect Control Interface functions
/////////////////////////////////////////////////
-int Effect_Process(effect_interface_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer)
+int Effect_Process(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer)
{
int ret = init();
if (ret < 0) {
@@ -73,7 +85,7 @@
return ret;
}
-int Effect_Command(effect_interface_t self,
+int Effect_Command(effect_handle_t self,
uint32_t cmdCode,
uint32_t cmdSize,
void *pCmdData,
@@ -98,9 +110,64 @@
return ret;
}
+int Effect_GetDescriptor(effect_handle_t self,
+ effect_descriptor_t *desc)
+{
+ int ret = init();
+ if (ret < 0) {
+ return ret;
+ }
+ effect_entry_t *fx = (effect_entry_t *)self;
+ pthread_mutex_lock(&gLibLock);
+ if (fx->lib == NULL) {
+ pthread_mutex_unlock(&gLibLock);
+ return -EPIPE;
+ }
+ pthread_mutex_lock(&fx->lib->lock);
+ pthread_mutex_unlock(&gLibLock);
+
+ ret = (*fx->subItfe)->get_descriptor(fx->subItfe, desc);
+ pthread_mutex_unlock(&fx->lib->lock);
+ return ret;
+}
+
+int Effect_ProcessReverse(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer)
+{
+ int ret = init();
+ if (ret < 0) {
+ return ret;
+ }
+ effect_entry_t *fx = (effect_entry_t *)self;
+ pthread_mutex_lock(&gLibLock);
+ if (fx->lib == NULL) {
+ pthread_mutex_unlock(&gLibLock);
+ return -EPIPE;
+ }
+ pthread_mutex_lock(&fx->lib->lock);
+ pthread_mutex_unlock(&gLibLock);
+
+ if ((*fx->subItfe)->process_reverse != NULL) {
+ ret = (*fx->subItfe)->process_reverse(fx->subItfe, inBuffer, outBuffer);
+ } else {
+ ret = -ENOSYS;
+ }
+ pthread_mutex_unlock(&fx->lib->lock);
+ return ret;
+}
+
+
const struct effect_interface_s gInterface = {
Effect_Process,
- Effect_Command
+ Effect_Command,
+ Effect_GetDescriptor,
+ NULL
+};
+
+const struct effect_interface_s gInterfaceWithReverse = {
+ Effect_Process,
+ Effect_Command,
+ Effect_GetDescriptor,
+ Effect_ProcessReverse
};
/////////////////////////////////////////////////
@@ -182,7 +249,7 @@
return -EINVAL;
}
pthread_mutex_lock(&gLibLock);
- ret = findEffect(uuid, &l, &d);
+ ret = findEffect(NULL, uuid, &l, &d);
if (ret == 0) {
memcpy(pDescriptor, d, sizeof(effect_descriptor_t));
}
@@ -190,17 +257,17 @@
return ret;
}
-int EffectCreate(effect_uuid_t *uuid, int32_t sessionId, int32_t ioId, effect_interface_t *pInterface)
+int EffectCreate(effect_uuid_t *uuid, int32_t sessionId, int32_t ioId, effect_handle_t *pHandle)
{
list_elem_t *e = gLibraryList;
lib_entry_t *l = NULL;
effect_descriptor_t *d = NULL;
- effect_interface_t itfe;
+ effect_handle_t itfe;
effect_entry_t *fx;
int found = 0;
int ret;
- if (uuid == NULL || pInterface == NULL) {
+ if (uuid == NULL || pHandle == NULL) {
return -EINVAL;
}
@@ -218,22 +285,28 @@
pthread_mutex_lock(&gLibLock);
- ret = findEffect(uuid, &l, &d);
+ ret = findEffect(NULL, uuid, &l, &d);
if (ret < 0){
goto exit;
}
// create effect in library
- ret = l->createFx(uuid, sessionId, ioId, &itfe);
+ ret = l->desc->create_effect(uuid, sessionId, ioId, &itfe);
if (ret != 0) {
- LOGW("EffectCreate() library %s: could not create fx %s, error %d", l->path, d->name, ret);
+ LOGW("EffectCreate() library %s: could not create fx %s, error %d", l->name, d->name, ret);
goto exit;
}
// add entry to effect list
fx = (effect_entry_t *)malloc(sizeof(effect_entry_t));
fx->subItfe = itfe;
- fx->itfe = (struct effect_interface_s *)&gInterface;
+ if ((*itfe)->process_reverse != NULL) {
+ fx->itfe = (struct effect_interface_s *)&gInterfaceWithReverse;
+ LOGV("EffectCreate() gInterfaceWithReverse");
+ } else {
+ fx->itfe = (struct effect_interface_s *)&gInterface;
+ LOGV("EffectCreate() gInterface");
+ }
fx->lib = l;
e = (list_elem_t *)malloc(sizeof(list_elem_t));
@@ -241,16 +314,16 @@
e->next = gEffectList;
gEffectList = e;
- *pInterface = (effect_interface_t)fx;
+ *pHandle = (effect_handle_t)fx;
- LOGV("EffectCreate() created entry %p with sub itfe %p in library %s", *pInterface, itfe, l->path);
+ LOGV("EffectCreate() created entry %p with sub itfe %p in library %s", *pHandle, itfe, l->name);
exit:
pthread_mutex_unlock(&gLibLock);
return ret;
}
-int EffectRelease(effect_interface_t interface)
+int EffectRelease(effect_handle_t handle)
{
effect_entry_t *fx;
list_elem_t *e1;
@@ -266,7 +339,7 @@
e1 = gEffectList;
e2 = NULL;
while (e1) {
- if (e1->object == interface) {
+ if (e1->object == handle) {
if (e2) {
e2->next = e1->next;
} else {
@@ -286,10 +359,10 @@
// release effect in library
if (fx->lib == NULL) {
- LOGW("EffectRelease() fx %p library already unloaded", interface);
+ LOGW("EffectRelease() fx %p library already unloaded", handle);
} else {
pthread_mutex_lock(&fx->lib->lock);
- fx->lib->releaseFx(fx->subItfe);
+ fx->lib->desc->release_effect(fx->subItfe);
pthread_mutex_unlock(&fx->lib->lock);
}
free(fx);
@@ -299,33 +372,6 @@
return ret;
}
-int EffectLoadLibrary(const char *libPath, int *handle)
-{
- int ret = init();
- if (ret < 0) {
- return ret;
- }
- if (libPath == NULL) {
- return -EINVAL;
- }
-
- ret = loadLibrary(libPath, handle);
- updateNumEffects();
- return ret;
-}
-
-int EffectUnloadLibrary(int handle)
-{
- int ret = init();
- if (ret < 0) {
- return ret;
- }
-
- ret = unloadLibrary(handle);
- updateNumEffects();
- return ret;
-}
-
int EffectIsNullUuid(effect_uuid_t *uuid)
{
if (memcmp(uuid, EFFECT_UUID_NULL, sizeof(effect_uuid_t))) {
@@ -339,9 +385,6 @@
/////////////////////////////////////////////////
int init() {
- struct dirent *ent;
- DIR *dir = NULL;
- char libpath[PATH_MAX];
int hdl;
if (gInitDone) {
@@ -350,214 +393,210 @@
pthread_mutex_init(&gLibLock, NULL);
- // load built-in libraries
- dir = opendir(gEffectLibPath);
- if (dir == NULL) {
- return -ENODEV;
+ if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) {
+ loadEffectConfigFile(AUDIO_EFFECT_VENDOR_CONFIG_FILE);
+ } else if (access(AUDIO_EFFECT_DEFAULT_CONFIG_FILE, R_OK) == 0) {
+ loadEffectConfigFile(AUDIO_EFFECT_DEFAULT_CONFIG_FILE);
}
- while ((ent = readdir(dir)) != NULL) {
- LOGV("init() reading file %s", ent->d_name);
- if ((strlen(ent->d_name) < 3) ||
- strncmp(ent->d_name, "lib", 3) != 0 ||
- strncmp(ent->d_name + strlen(ent->d_name) - 3, ".so", 3) != 0) {
- continue;
- }
- strcpy(libpath, gEffectLibPath);
- strcat(libpath, "/");
- strcat(libpath, ent->d_name);
- if (loadLibrary(libpath, &hdl) < 0) {
- LOGW("init() failed to load library %s",libpath);
- }
- }
- closedir(dir);
+
updateNumEffects();
gInitDone = 1;
LOGV("init() done");
return 0;
}
-
-int loadLibrary(const char *libPath, int *handle)
+int loadEffectConfigFile(const char *path)
{
+ cnode *root;
+ char *data;
+
+ data = load_file(path, NULL);
+ if (data == NULL) {
+ return -ENODEV;
+ }
+ root = config_node("", "");
+ config_load(root, data);
+ loadLibraries(root);
+ loadEffects(root);
+ config_free(root);
+ free(root);
+ free(data);
+
+ return 0;
+}
+
+int loadLibraries(cnode *root)
+{
+ cnode *node;
+
+ node = config_find(root, LIBRARIES_TAG);
+ if (node == NULL) {
+ return -ENOENT;
+ }
+ node = node->first_child;
+ while (node) {
+ loadLibrary(node, node->name);
+ node = node->next;
+ }
+ return 0;
+}
+
+int loadLibrary(cnode *root, const char *name)
+{
+ cnode *node;
void *hdl;
- effect_QueryNumberEffects_t queryNumFx;
- effect_QueryEffect_t queryFx;
- effect_CreateEffect_t createFx;
- effect_ReleaseEffect_t releaseFx;
- uint32_t numFx;
- uint32_t fx;
- int ret;
- list_elem_t *e, *descHead = NULL;
+ audio_effect_library_t *desc;
+ list_elem_t *e;
lib_entry_t *l;
- if (handle == NULL) {
+ node = config_find(root, PATH_TAG);
+ if (node == NULL) {
return -EINVAL;
}
- *handle = 0;
-
- hdl = dlopen(libPath, RTLD_NOW);
- if (hdl == 0) {
- LOGW("could open lib %s", libPath);
- return -ENODEV;
- }
-
- // Check functions availability
- queryNumFx = (effect_QueryNumberEffects_t)dlsym(hdl, "EffectQueryNumberEffects");
- if (queryNumFx == NULL) {
- LOGW("could not get EffectQueryNumberEffects from lib %s", libPath);
- ret = -ENODEV;
- goto error;
- }
- queryFx = (effect_QueryEffect_t)dlsym(hdl, "EffectQueryEffect");
- if (queryFx == NULL) {
- LOGW("could not get EffectQueryEffect from lib %s", libPath);
- ret = -ENODEV;
- goto error;
- }
- createFx = (effect_CreateEffect_t)dlsym(hdl, "EffectCreate");
- if (createFx == NULL) {
- LOGW("could not get EffectCreate from lib %s", libPath);
- ret = -ENODEV;
- goto error;
- }
- releaseFx = (effect_ReleaseEffect_t)dlsym(hdl, "EffectRelease");
- if (releaseFx == NULL) {
- LOGW("could not get EffectRelease from lib %s", libPath);
- ret = -ENODEV;
+ hdl = dlopen(node->value, RTLD_NOW);
+ if (hdl == NULL) {
+ LOGW("loadLibrary() failed to open %s", node->value);
goto error;
}
- // load effect descriptors
- ret = queryNumFx(&numFx);
- if (ret) {
+ desc = (audio_effect_library_t *)dlsym(hdl, AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR);
+ if (desc == NULL) {
+ LOGW("loadLibrary() could not find symbol %s", AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR);
goto error;
}
- for (fx = 0; fx < numFx; fx++) {
- effect_descriptor_t *d = malloc(sizeof(effect_descriptor_t));
- if (d == NULL) {
- ret = -ENOMEM;
- goto error;
- }
- ret = queryFx(fx, d);
- if (ret == 0) {
-#if (LOG_NDEBUG==0)
- char s[256];
- dumpEffectDescriptor(d, s, 256);
- LOGV("loadLibrary() read descriptor %p:%s",d, s);
-#endif
- if (d->apiVersion != EFFECT_API_VERSION) {
- LOGW("Bad API version %04x on lib %s", d->apiVersion, libPath);
- free(d);
- continue;
- }
- e = malloc(sizeof(list_elem_t));
- if (e == NULL) {
- free(d);
- ret = -ENOMEM;
- goto error;
- }
- e->object = d;
- e->next = descHead;
- descHead = e;
- } else {
- LOGW("Error querying effect # %d on lib %s", fx, libPath);
- }
+ if (AUDIO_EFFECT_LIBRARY_TAG != desc->tag) {
+ LOGW("getLibrary() bad tag %08x in lib info struct", desc->tag);
+ goto error;
}
- pthread_mutex_lock(&gLibLock);
+ if (EFFECT_API_VERSION_MAJOR(desc->version) !=
+ EFFECT_API_VERSION_MAJOR(EFFECT_LIBRARY_API_VERSION)) {
+ LOGW("loadLibrary() bad lib version %08x", desc->version);
+ goto error;
+ }
// add entry for library in gLibraryList
l = malloc(sizeof(lib_entry_t));
- l->id = ++gNextLibId;
+ l->name = strndup(name, PATH_MAX);
+ l->path = strndup(node->value, PATH_MAX);
l->handle = hdl;
- strncpy(l->path, libPath, PATH_MAX);
- l->createFx = createFx;
- l->releaseFx = releaseFx;
- l->effects = descHead;
+ l->desc = desc;
+ l->effects = NULL;
pthread_mutex_init(&l->lock, NULL);
e = malloc(sizeof(list_elem_t));
- e->next = gLibraryList;
e->object = l;
+ pthread_mutex_lock(&gLibLock);
+ e->next = gLibraryList;
gLibraryList = e;
pthread_mutex_unlock(&gLibLock);
- LOGV("loadLibrary() linked library %p", l);
-
- *handle = l->id;
+ LOGV("getLibrary() linked library %p for path %s", l, node->value);
return 0;
error:
- LOGW("loadLibrary() error: %d on lib: %s", ret, libPath);
- while (descHead) {
- free(descHead->object);
- e = descHead->next;
- free(descHead);
- descHead = e;;
+ if (hdl != NULL) {
+ dlclose(hdl);
}
- dlclose(hdl);
- return ret;
+ return -EINVAL;
}
-int unloadLibrary(int handle)
+int loadEffects(cnode *root)
{
- void *hdl;
- int ret;
- list_elem_t *el1, *el2;
- lib_entry_t *l;
- effect_entry_t *fx;
+ cnode *node;
- pthread_mutex_lock(&gLibLock);
- el1 = gLibraryList;
- el2 = NULL;
- while (el1) {
- l = (lib_entry_t *)el1->object;
- if (handle == l->id) {
- if (el2) {
- el2->next = el1->next;
- } else {
- gLibraryList = el1->next;
- }
- free(el1);
- break;
- }
- el2 = el1;
- el1 = el1->next;
- }
- pthread_mutex_unlock(&gLibLock);
- if (el1 == NULL) {
+ node = config_find(root, EFFECTS_TAG);
+ if (node == NULL) {
return -ENOENT;
}
-
- // clear effect descriptor list
- el1 = l->effects;
- while (el1) {
- free(el1->object);
- el2 = el1->next;
- free(el1);
- el1 = el2;
+ node = node->first_child;
+ while (node) {
+ loadEffect(node);
+ node = node->next;
}
-
- // disable all effects from this library
- pthread_mutex_lock(&l->lock);
-
- el1 = gEffectList;
- while (el1) {
- fx = (effect_entry_t *)el1->object;
- if (fx->lib == l) {
- fx->lib = NULL;
- }
- el1 = el1->next;
- }
- pthread_mutex_unlock(&l->lock);
-
- dlclose(l->handle);
- free(l);
return 0;
}
+int loadEffect(cnode *root)
+{
+ cnode *node;
+ effect_uuid_t uuid;
+ lib_entry_t *l;
+ effect_descriptor_t *d;
+ list_elem_t *e;
+
+ node = config_find(root, LIBRARY_TAG);
+ if (node == NULL) {
+ return -EINVAL;
+ }
+
+ l = getLibrary(node->value);
+ if (l == NULL) {
+ LOGW("loadEffect() could not get library %s", node->value);
+ return -EINVAL;
+ }
+
+ node = config_find(root, UUID_TAG);
+ if (node == NULL) {
+ return -EINVAL;
+ }
+ if (stringToUuid(node->value, &uuid) != 0) {
+ LOGW("loadEffect() invalid uuid %s", node->value);
+ return -EINVAL;
+ }
+
+ d = malloc(sizeof(effect_descriptor_t));
+ if (l->desc->get_descriptor(&uuid, d) != 0) {
+ char s[40];
+ uuidToString(&uuid, s, 40);
+ LOGW("Error querying effect %s on lib %s", s, l->name);
+ free(d);
+ return -EINVAL;
+ }
+#if (LOG_NDEBUG==0)
+ char s[256];
+ dumpEffectDescriptor(d, s, 256);
+ LOGV("loadEffect() read descriptor %p:%s",d, s);
+#endif
+ if (EFFECT_API_VERSION_MAJOR(d->apiVersion) !=
+ EFFECT_API_VERSION_MAJOR(EFFECT_CONTROL_API_VERSION)) {
+ LOGW("Bad API version %08x on lib %s", d->apiVersion, l->name);
+ free(d);
+ return -EINVAL;
+ }
+ e = malloc(sizeof(list_elem_t));
+ e->object = d;
+ e->next = l->effects;
+ l->effects = e;
+
+ return 0;
+}
+
+lib_entry_t *getLibrary(const char *name)
+{
+ list_elem_t *e;
+
+ if (gCachedLibrary &&
+ !strncmp(gCachedLibrary->name, name, PATH_MAX)) {
+ return gCachedLibrary;
+ }
+
+ e = gLibraryList;
+ while (e) {
+ lib_entry_t *l = (lib_entry_t *)e->object;
+ if (!strcmp(l->name, name)) {
+ gCachedLibrary = l;
+ return l;
+ }
+ e = e->next;
+ }
+
+ return NULL;
+}
+
+
void resetEffectEnumeration()
{
gCurLib = gLibraryList;
@@ -589,7 +628,10 @@
return cnt;
}
-int findEffect(effect_uuid_t *uuid, lib_entry_t **lib, effect_descriptor_t **desc)
+int findEffect(effect_uuid_t *type,
+ effect_uuid_t *uuid,
+ lib_entry_t **lib,
+ effect_descriptor_t **desc)
{
list_elem_t *e = gLibraryList;
lib_entry_t *l = NULL;
@@ -602,7 +644,11 @@
list_elem_t *efx = l->effects;
while (efx) {
d = (effect_descriptor_t *)efx->object;
- if (memcmp(&d->uuid, uuid, sizeof(effect_uuid_t)) == 0) {
+ if (type != NULL && memcmp(&d->type, type, sizeof(effect_uuid_t)) == 0) {
+ found = 1;
+ break;
+ }
+ if (uuid != NULL && memcmp(&d->uuid, uuid, sizeof(effect_uuid_t)) == 0) {
found = 1;
break;
}
@@ -614,9 +660,11 @@
LOGV("findEffect() effect not found");
ret = -ENOENT;
} else {
- LOGV("findEffect() found effect: %s in lib %s", d->name, l->path);
+ LOGV("findEffect() found effect: %s in lib %s", d->name, l->name);
*lib = l;
- *desc = d;
+ if (desc) {
+ *desc = d;
+ }
}
return ret;
@@ -626,17 +674,12 @@
char s[256];
snprintf(str, len, "\nEffect Descriptor %p:\n", desc);
- sprintf(s, "- UUID: %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X\n",
- desc->uuid.timeLow, desc->uuid.timeMid, desc->uuid.timeHiAndVersion,
- desc->uuid.clockSeq, desc->uuid.node[0], desc->uuid.node[1],desc->uuid.node[2],
- desc->uuid.node[3],desc->uuid.node[4],desc->uuid.node[5]);
- strncat(str, s, len);
- sprintf(s, "- TYPE: %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X\n",
- desc->type.timeLow, desc->type.timeMid, desc->type.timeHiAndVersion,
- desc->type.clockSeq, desc->type.node[0], desc->type.node[1],desc->type.node[2],
- desc->type.node[3],desc->type.node[4],desc->type.node[5]);
- strncat(str, s, len);
- sprintf(s, "- apiVersion: %04X\n- flags: %08X\n",
+ strncat(str, "- TYPE: ", len);
+ uuidToString(&desc->uuid, s, 256);
+ snprintf(str, len, "- UUID: %s\n", s);
+ uuidToString(&desc->type, s, 256);
+ snprintf(str, len, "- TYPE: %s\n", s);
+ sprintf(s, "- apiVersion: %08X\n- flags: %08X\n",
desc->apiVersion, desc->flags);
strncat(str, s, len);
sprintf(s, "- name: %s\n", desc->name);
@@ -645,3 +688,43 @@
strncat(str, s, len);
}
+int stringToUuid(const char *str, effect_uuid_t *uuid)
+{
+ int tmp[10];
+
+ if (sscanf(str, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
+ tmp, tmp+1, tmp+2, tmp+3, tmp+4, tmp+5, tmp+6, tmp+7, tmp+8, tmp+9) < 10) {
+ return -EINVAL;
+ }
+ uuid->timeLow = (uint32_t)tmp[0];
+ uuid->timeMid = (uint16_t)tmp[1];
+ uuid->timeHiAndVersion = (uint16_t)tmp[2];
+ uuid->clockSeq = (uint16_t)tmp[3];
+ uuid->node[0] = (uint8_t)tmp[4];
+ uuid->node[1] = (uint8_t)tmp[5];
+ uuid->node[2] = (uint8_t)tmp[6];
+ uuid->node[3] = (uint8_t)tmp[7];
+ uuid->node[4] = (uint8_t)tmp[8];
+ uuid->node[5] = (uint8_t)tmp[9];
+
+ return 0;
+}
+
+int uuidToString(const effect_uuid_t *uuid, char *str, size_t maxLen)
+{
+
+ snprintf(str, maxLen, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
+ uuid->timeLow,
+ uuid->timeMid,
+ uuid->timeHiAndVersion,
+ uuid->clockSeq,
+ uuid->node[0],
+ uuid->node[1],
+ uuid->node[2],
+ uuid->node[3],
+ uuid->node[4],
+ uuid->node[5]);
+
+ return 0;
+}
+
diff --git a/media/libeffects/factory/EffectsFactory.h b/media/libeffects/factory/EffectsFactory.h
index 8f543ca..c1d4319 100644
--- a/media/libeffects/factory/EffectsFactory.h
+++ b/media/libeffects/factory/EffectsFactory.h
@@ -22,29 +22,28 @@
#include <dirent.h>
#include <media/EffectsFactoryApi.h>
-
#if __cplusplus
extern "C" {
#endif
+
typedef struct list_elem_s {
void *object;
struct list_elem_s *next;
} list_elem_t;
typedef struct lib_entry_s {
- char path[PATH_MAX];
+ audio_effect_library_t *desc;
+ char *name;
+ char *path;
void *handle;
- int id;
- effect_CreateEffect_t createFx;
- effect_ReleaseEffect_t releaseFx;
list_elem_t *effects; //list of effect_descriptor_t
pthread_mutex_t lock;
} lib_entry_t;
typedef struct effect_entry_s {
struct effect_interface_s *itfe;
- effect_interface_t subItfe;
+ effect_handle_t subItfe;
lib_entry_t *lib;
} effect_entry_t;
diff --git a/media/libeffects/lvm/lib/Android.mk b/media/libeffects/lvm/lib/Android.mk
index ff34707..f49267e 100644
--- a/media/libeffects/lvm/lib/Android.mk
+++ b/media/libeffects/lvm/lib/Android.mk
@@ -105,7 +105,7 @@
LOCAL_MODULE:= libmusicbundle
-LOCAL_PRELINK_MODULE := false
+
LOCAL_C_INCLUDES += \
$(LOCAL_PATH)/Eq/lib \
@@ -168,7 +168,7 @@
LOCAL_MODULE:= libreverb
-LOCAL_PRELINK_MODULE := false
+
LOCAL_C_INCLUDES += \
$(LOCAL_PATH)/Reverb/lib \
diff --git a/media/libeffects/lvm/wrapper/Android.mk b/media/libeffects/lvm/wrapper/Android.mk
index 2e9b9b4..f097dd0 100644
--- a/media/libeffects/lvm/wrapper/Android.mk
+++ b/media/libeffects/lvm/wrapper/Android.mk
@@ -13,24 +13,20 @@
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx
-LOCAL_PRELINK_MODULE := false
+
LOCAL_STATIC_LIBRARIES += libmusicbundle
LOCAL_SHARED_LIBRARIES := \
libcutils \
-
-ifeq ($(TARGET_SIMULATOR),true)
-LOCAL_LDLIBS += -ldl
-else
-LOCAL_SHARED_LIBRARIES += libdl
-endif
+ libdl
LOCAL_C_INCLUDES += \
$(LOCAL_PATH)/Bundle \
$(LOCAL_PATH)/../lib/Common/lib/ \
- $(LOCAL_PATH)/../lib/Bundle/lib/
+ $(LOCAL_PATH)/../lib/Bundle/lib/ \
+ system/media/audio_effects/include
include $(BUILD_SHARED_LIBRARY)
@@ -47,23 +43,18 @@
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx
-LOCAL_PRELINK_MODULE := false
+
LOCAL_STATIC_LIBRARIES += libreverb
LOCAL_SHARED_LIBRARIES := \
libcutils \
-
-ifeq ($(TARGET_SIMULATOR),true)
-LOCAL_LDLIBS += -ldl
-else
-LOCAL_SHARED_LIBRARIES += libdl
-endif
+ libdl
LOCAL_C_INCLUDES += \
$(LOCAL_PATH)/Reverb \
$(LOCAL_PATH)/../lib/Common/lib/ \
$(LOCAL_PATH)/../lib/Reverb/lib/ \
-
+ system/media/audio_effects/include
include $(BUILD_SHARED_LIBRARY)
\ No newline at end of file
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
index 0b061db..efa1c45 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
@@ -27,7 +27,7 @@
#include <EffectBundle.h>
-// effect_interface_t interface implementation for bass boost
+// effect_handle_t interface implementation for bass boost
extern "C" const struct effect_interface_s gLvmEffectInterface;
#define LVM_ERROR_CHECK(LvmStatus, callingFunc, calledFunc){\
@@ -71,7 +71,7 @@
const effect_descriptor_t gBassBoostDescriptor = {
{0x0634f220, 0xddd4, 0x11db, 0xa0fc, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b }},
{0x8631f300, 0x72e2, 0x11df, 0xb57e, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // uuid
- EFFECT_API_VERSION,
+ EFFECT_CONTROL_API_VERSION,
(EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST | EFFECT_FLAG_DEVICE_IND
| EFFECT_FLAG_VOLUME_CTRL),
BASS_BOOST_CUP_LOAD_ARM9E,
@@ -84,7 +84,7 @@
const effect_descriptor_t gVirtualizerDescriptor = {
{0x37cc2c00, 0xdddd, 0x11db, 0x8577, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
{0x1d4033c0, 0x8557, 0x11df, 0x9f2d, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
- EFFECT_API_VERSION,
+ EFFECT_CONTROL_API_VERSION,
(EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST | EFFECT_FLAG_DEVICE_IND
| EFFECT_FLAG_VOLUME_CTRL),
VIRTUALIZER_CUP_LOAD_ARM9E,
@@ -97,7 +97,7 @@
const effect_descriptor_t gEqualizerDescriptor = {
{0x0bed4300, 0xddd6, 0x11db, 0x8f34, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // type
{0xce772f20, 0x847d, 0x11df, 0xbb17, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // uuid Eq NXP
- EFFECT_API_VERSION,
+ EFFECT_CONTROL_API_VERSION,
(EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST | EFFECT_FLAG_VOLUME_CTRL),
EQUALIZER_CUP_LOAD_ARM9E,
BUNDLE_MEM_USAGE,
@@ -109,7 +109,7 @@
const effect_descriptor_t gVolumeDescriptor = {
{0x09e8ede0, 0xddde, 0x11db, 0xb4f6, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b }},
{0x119341a0, 0x8469, 0x11df, 0x81f9, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b }}, //uuid VOL NXP
- EFFECT_API_VERSION,
+ EFFECT_CONTROL_API_VERSION,
(EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST | EFFECT_FLAG_VOLUME_CTRL),
VOLUME_CUP_LOAD_ARM9E,
BUNDLE_MEM_USAGE,
@@ -187,7 +187,7 @@
extern "C" int EffectCreate(effect_uuid_t *uuid,
int32_t sessionId,
int32_t ioId,
- effect_interface_t *pInterface){
+ effect_handle_t *pHandle){
int ret = 0;
int sessionNo;
int i;
@@ -197,7 +197,7 @@
LOGV("\n\tEffectCreate start session %d", sessionId);
- if (pInterface == NULL || uuid == NULL){
+ if (pHandle == NULL || uuid == NULL){
LOGV("\tLVM_ERROR : EffectCreate() called with NULL pointer");
ret = -EINVAL;
goto exit;
@@ -355,19 +355,19 @@
}
delete pContext;
}
- *pInterface = (effect_interface_t)NULL;
+ *pHandle = (effect_handle_t)NULL;
} else {
- *pInterface = (effect_interface_t)pContext;
+ *pHandle = (effect_handle_t)pContext;
}
LOGV("\tEffectCreate end..\n\n");
return ret;
} /* end EffectCreate */
-extern "C" int EffectRelease(effect_interface_t interface){
- LOGV("\n\tEffectRelease start %p", interface);
- EffectContext * pContext = (EffectContext *)interface;
+extern "C" int EffectRelease(effect_handle_t handle){
+ LOGV("\n\tEffectRelease start %p", handle);
+ EffectContext * pContext = (EffectContext *)handle;
- LOGV("\tEffectRelease start interface: %p, context %p", interface, pContext->pBundledContext);
+ LOGV("\tEffectRelease start handle: %p, context %p", handle, pContext->pBundledContext);
if (pContext == NULL){
LOGV("\tLVM_ERROR : EffectRelease called with NULL pointer");
return -EINVAL;
@@ -460,6 +460,34 @@
} /* end EffectRelease */
+extern "C" int EffectGetDescriptor(effect_uuid_t *uuid,
+ effect_descriptor_t *pDescriptor) {
+ const effect_descriptor_t *desc = NULL;
+
+ if (pDescriptor == NULL || uuid == NULL){
+ LOGV("EffectGetDescriptor() called with NULL pointer");
+ return -EINVAL;
+ }
+
+ if (memcmp(uuid, &gBassBoostDescriptor.uuid, sizeof(effect_uuid_t)) == 0) {
+ desc = &gBassBoostDescriptor;
+ } else if (memcmp(uuid, &gVirtualizerDescriptor.uuid, sizeof(effect_uuid_t)) == 0) {
+ desc = &gVirtualizerDescriptor;
+ } else if (memcmp(uuid, &gEqualizerDescriptor.uuid, sizeof(effect_uuid_t)) == 0) {
+ desc = &gEqualizerDescriptor;
+ } else if (memcmp(uuid, &gVolumeDescriptor.uuid, sizeof(effect_uuid_t)) == 0) {
+ desc = &gVolumeDescriptor;
+ }
+
+ if (desc == NULL) {
+ return -EINVAL;
+ }
+
+ memcpy(pDescriptor, desc, sizeof(effect_descriptor_t));
+
+ return 0;
+} /* end EffectGetDescriptor */
+
void LvmGlobalBundle_init(){
LOGV("\tLvmGlobalBundle_init start");
for(int i=0; i<LVM_MAX_SESSIONS; i++){
@@ -493,16 +521,16 @@
LOGV("\tLvmBundle_init start");
pContext->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
- pContext->config.inputCfg.channels = CHANNEL_STEREO;
- pContext->config.inputCfg.format = SAMPLE_FORMAT_PCM_S15;
+ pContext->config.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
+ pContext->config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
pContext->config.inputCfg.samplingRate = 44100;
pContext->config.inputCfg.bufferProvider.getBuffer = NULL;
pContext->config.inputCfg.bufferProvider.releaseBuffer = NULL;
pContext->config.inputCfg.bufferProvider.cookie = NULL;
pContext->config.inputCfg.mask = EFFECT_CONFIG_ALL;
pContext->config.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE;
- pContext->config.outputCfg.channels = CHANNEL_STEREO;
- pContext->config.outputCfg.format = SAMPLE_FORMAT_PCM_S15;
+ pContext->config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
+ pContext->config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
pContext->config.outputCfg.samplingRate = 44100;
pContext->config.outputCfg.bufferProvider.getBuffer = NULL;
pContext->config.outputCfg.bufferProvider.releaseBuffer = NULL;
@@ -928,10 +956,10 @@
CHECK_ARG(pConfig->inputCfg.samplingRate == pConfig->outputCfg.samplingRate);
CHECK_ARG(pConfig->inputCfg.channels == pConfig->outputCfg.channels);
CHECK_ARG(pConfig->inputCfg.format == pConfig->outputCfg.format);
- CHECK_ARG(pConfig->inputCfg.channels == CHANNEL_STEREO);
+ CHECK_ARG(pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_STEREO);
CHECK_ARG(pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_WRITE
|| pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE);
- CHECK_ARG(pConfig->inputCfg.format == SAMPLE_FORMAT_PCM_S15);
+ CHECK_ARG(pConfig->inputCfg.format == AUDIO_FORMAT_PCM_16_BIT);
memcpy(&pContext->config, pConfig, sizeof(effect_config_t));
@@ -2545,8 +2573,9 @@
} // namespace
} // namespace
+extern "C" {
/* Effect Control Interface Implementation: Process */
-extern "C" int Effect_process(effect_interface_t self,
+int Effect_process(effect_handle_t self,
audio_buffer_t *inBuffer,
audio_buffer_t *outBuffer){
EffectContext * pContext = (EffectContext *) self;
@@ -2666,7 +2695,7 @@
} /* end Effect_process */
/* Effect Control Interface Implementation: Command */
-extern "C" int Effect_command(effect_interface_t self,
+int Effect_command(effect_handle_t self,
uint32_t cmdCode,
uint32_t cmdSize,
void *pCmdData,
@@ -3016,11 +3045,11 @@
case EFFECT_CMD_SET_DEVICE:
{
LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_SET_DEVICE start");
- audio_device_e device = *(audio_device_e *)pCmdData;
+ uint32_t device = *(uint32_t *)pCmdData;
if(pContext->EffectType == LVM_BASS_BOOST){
- if((device == DEVICE_SPEAKER)||(device == DEVICE_BLUETOOTH_SCO_CARKIT)||
- (device == DEVICE_BLUETOOTH_A2DP_SPEAKER)){
+ if((device == AUDIO_DEVICE_OUT_SPEAKER)||(device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT)||
+ (device == AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER)){
LOGV("\tEFFECT_CMD_SET_DEVICE device is invalid for LVM_BASS_BOOST %d",
*(int32_t *)pCmdData);
LOGV("\tEFFECT_CMD_SET_DEVICE temporary disable LVM_BAS_BOOST");
@@ -3051,8 +3080,8 @@
}
}
if(pContext->EffectType == LVM_VIRTUALIZER){
- if((device == DEVICE_SPEAKER)||(device == DEVICE_BLUETOOTH_SCO_CARKIT)||
- (device == DEVICE_BLUETOOTH_A2DP_SPEAKER)){
+ if((device == AUDIO_DEVICE_OUT_SPEAKER)||(device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT)||
+ (device == AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER)){
LOGV("\tEFFECT_CMD_SET_DEVICE device is invalid for LVM_VIRTUALIZER %d",
*(int32_t *)pCmdData);
LOGV("\tEFFECT_CMD_SET_DEVICE temporary disable LVM_VIRTUALIZER");
@@ -3164,9 +3193,58 @@
return 0;
} /* end Effect_command */
-// effect_interface_t interface implementation for effect
+/* Effect Control Interface Implementation: get_descriptor */
+int Effect_getDescriptor(effect_handle_t self,
+ effect_descriptor_t *pDescriptor)
+{
+ EffectContext * pContext = (EffectContext *) self;
+ const effect_descriptor_t *desc;
+
+ if (pContext == NULL || pDescriptor == NULL) {
+ LOGV("Effect_getDescriptor() invalid param");
+ return -EINVAL;
+ }
+
+ switch(pContext->EffectType) {
+ case LVM_BASS_BOOST:
+ desc = &android::gBassBoostDescriptor;
+ break;
+ case LVM_VIRTUALIZER:
+ desc = &android::gVirtualizerDescriptor;
+ break;
+ case LVM_EQUALIZER:
+ desc = &android::gEqualizerDescriptor;
+ break;
+ case LVM_VOLUME:
+ desc = &android::gVolumeDescriptor;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ memcpy(pDescriptor, desc, sizeof(effect_descriptor_t));
+
+ return 0;
+} /* end Effect_getDescriptor */
+
+// effect_handle_t interface implementation for effect
const struct effect_interface_s gLvmEffectInterface = {
Effect_process,
- Effect_command
+ Effect_command,
+ Effect_getDescriptor,
+ NULL,
}; /* end gLvmEffectInterface */
+audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
+ tag : AUDIO_EFFECT_LIBRARY_TAG,
+ version : EFFECT_LIBRARY_API_VERSION,
+ name : "Effect Bundle Library",
+ implementor : "NXP Software Ltd.",
+ query_num_effects : android::EffectQueryNumberEffects,
+ query_effect : android::EffectQueryEffect,
+ create_effect : android::EffectCreate,
+ release_effect : android::EffectRelease,
+ get_descriptor : android::EffectGetDescriptor,
+};
+
+}
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h
index 2b51029..5634ca1 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h
@@ -17,9 +17,9 @@
#ifndef ANDROID_EFFECTBUNDLE_H_
#define ANDROID_EFFECTBUNDLE_H_
-#include <media/EffectEqualizerApi.h>
-#include <media/EffectBassBoostApi.h>
-#include <media/EffectVirtualizerApi.h>
+#include <audio_effects/effect_bassboost.h>
+#include <audio_effects/effect_equalizer.h>
+#include <audio_effects/effect_virtualizer.h>
#include <LVM.h>
#include <limits.h>
diff --git a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
index 9097e20..663f8ff 100755
--- a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
+++ b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
@@ -27,7 +27,7 @@
#include <EffectReverb.h>
#include <LVREV.h>
-// effect_interface_t interface implementation for reverb
+// effect_handle_t interface implementation for reverb
extern "C" const struct effect_interface_s gReverbInterface;
#define LVM_ERROR_CHECK(LvmStatus, callingFunc, calledFunc){\
@@ -77,7 +77,7 @@
const effect_descriptor_t gAuxEnvReverbDescriptor = {
{ 0xc2e5d5f0, 0x94bd, 0x4763, 0x9cac, { 0x4e, 0x23, 0x4d, 0x06, 0x83, 0x9e } },
{ 0x4a387fc0, 0x8ab3, 0x11df, 0x8bad, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
- EFFECT_API_VERSION,
+ EFFECT_CONTROL_API_VERSION,
EFFECT_FLAG_TYPE_AUXILIARY,
LVREV_CUP_LOAD_ARM9E,
LVREV_MEM_USAGE,
@@ -89,7 +89,7 @@
static const effect_descriptor_t gInsertEnvReverbDescriptor = {
{0xc2e5d5f0, 0x94bd, 0x4763, 0x9cac, {0x4e, 0x23, 0x4d, 0x06, 0x83, 0x9e}},
{0xc7a511a0, 0xa3bb, 0x11df, 0x860e, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
- EFFECT_API_VERSION,
+ EFFECT_CONTROL_API_VERSION,
EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_FIRST | EFFECT_FLAG_VOLUME_CTRL,
LVREV_CUP_LOAD_ARM9E,
LVREV_MEM_USAGE,
@@ -101,7 +101,7 @@
static const effect_descriptor_t gAuxPresetReverbDescriptor = {
{0x47382d60, 0xddd8, 0x11db, 0xbf3a, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
{0xf29a1400, 0xa3bb, 0x11df, 0x8ddc, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
- EFFECT_API_VERSION,
+ EFFECT_CONTROL_API_VERSION,
EFFECT_FLAG_TYPE_AUXILIARY,
LVREV_CUP_LOAD_ARM9E,
LVREV_MEM_USAGE,
@@ -113,7 +113,7 @@
static const effect_descriptor_t gInsertPresetReverbDescriptor = {
{0x47382d60, 0xddd8, 0x11db, 0xbf3a, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
{0x172cdf00, 0xa3bc, 0x11df, 0xa72f, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
- EFFECT_API_VERSION,
+ EFFECT_CONTROL_API_VERSION,
EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_FIRST | EFFECT_FLAG_VOLUME_CTRL,
LVREV_CUP_LOAD_ARM9E,
LVREV_MEM_USAGE,
@@ -192,7 +192,8 @@
return 0;
} /* end EffectQueryNumberEffects */
-extern "C" int EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescriptor){
+extern "C" int EffectQueryEffect(uint32_t index,
+ effect_descriptor_t *pDescriptor){
LOGV("\n\tEffectQueryEffect start");
LOGV("\tEffectQueryEffect processing index %d", index);
if (pDescriptor == NULL){
@@ -211,7 +212,7 @@
extern "C" int EffectCreate(effect_uuid_t *uuid,
int32_t sessionId,
int32_t ioId,
- effect_interface_t *pInterface){
+ effect_handle_t *pHandle){
int ret;
int i;
int length = sizeof(gDescriptors) / sizeof(const effect_descriptor_t *);
@@ -219,7 +220,7 @@
LOGV("\t\nEffectCreate start");
- if (pInterface == NULL || uuid == NULL){
+ if (pHandle == NULL || uuid == NULL){
LOGV("\tLVM_ERROR : EffectCreate() called with NULL pointer");
return -EINVAL;
}
@@ -270,7 +271,7 @@
return ret;
}
- *pInterface = (effect_interface_t)pContext;
+ *pHandle = (effect_handle_t)pContext;
#ifdef LVM_PCM
pContext->PcmInPtr = NULL;
@@ -295,10 +296,10 @@
return 0;
} /* end EffectCreate */
-extern "C" int EffectRelease(effect_interface_t interface){
- ReverbContext * pContext = (ReverbContext *)interface;
+extern "C" int EffectRelease(effect_handle_t handle){
+ ReverbContext * pContext = (ReverbContext *)handle;
- LOGV("\tEffectRelease %p", interface);
+ LOGV("\tEffectRelease %p", handle);
if (pContext == NULL){
LOGV("\tLVM_ERROR : EffectRelease called with NULL pointer");
return -EINVAL;
@@ -315,6 +316,28 @@
return 0;
} /* end EffectRelease */
+extern "C" int EffectGetDescriptor(effect_uuid_t *uuid,
+ effect_descriptor_t *pDescriptor) {
+ int i;
+ int length = sizeof(gDescriptors) / sizeof(const effect_descriptor_t *);
+
+ if (pDescriptor == NULL || uuid == NULL){
+ LOGV("EffectGetDescriptor() called with NULL pointer");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < length; i++) {
+ if (memcmp(uuid, &gDescriptors[i]->uuid, sizeof(effect_uuid_t)) == 0) {
+ memcpy(pDescriptor, gDescriptors[i], sizeof(effect_descriptor_t));
+ LOGV("EffectGetDescriptor - UUID matched Reverb type %d, UUID = %x",
+ i, gDescriptors[i]->uuid.timeLow);
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+} /* end EffectGetDescriptor */
+
/* local functions */
#define CHECK_ARG(cond) { \
if (!(cond)) { \
@@ -418,9 +441,9 @@
// Check that the input is either mono or stereo
- if (pContext->config.inputCfg.channels == CHANNEL_STEREO) {
+ if (pContext->config.inputCfg.channels == AUDIO_CHANNEL_OUT_STEREO) {
samplesPerFrame = 2;
- } else if (pContext->config.inputCfg.channels != CHANNEL_MONO) {
+ } else if (pContext->config.inputCfg.channels != AUDIO_CHANNEL_OUT_MONO) {
LOGV("\tLVREV_ERROR : process invalid PCM format");
return -EINVAL;
}
@@ -608,12 +631,12 @@
CHECK_ARG(pConfig->inputCfg.samplingRate == pConfig->outputCfg.samplingRate);
CHECK_ARG(pConfig->inputCfg.format == pConfig->outputCfg.format);
- CHECK_ARG((pContext->auxiliary && pConfig->inputCfg.channels == CHANNEL_MONO) ||
- ((!pContext->auxiliary) && pConfig->inputCfg.channels == CHANNEL_STEREO));
- CHECK_ARG(pConfig->outputCfg.channels == CHANNEL_STEREO);
+ CHECK_ARG((pContext->auxiliary && pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_MONO) ||
+ ((!pContext->auxiliary) && pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_STEREO));
+ CHECK_ARG(pConfig->outputCfg.channels == AUDIO_CHANNEL_OUT_STEREO);
CHECK_ARG(pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_WRITE
|| pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE);
- CHECK_ARG(pConfig->inputCfg.format == SAMPLE_FORMAT_PCM_S15);
+ CHECK_ARG(pConfig->inputCfg.format == AUDIO_FORMAT_PCM_16_BIT);
if(pConfig->inputCfg.samplingRate != 44100){
return -EINVAL;
@@ -700,20 +723,20 @@
pContext->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
if (pContext->auxiliary) {
- pContext->config.inputCfg.channels = CHANNEL_MONO;
+ pContext->config.inputCfg.channels = AUDIO_CHANNEL_OUT_MONO;
} else {
- pContext->config.inputCfg.channels = CHANNEL_STEREO;
+ pContext->config.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
}
- pContext->config.inputCfg.format = SAMPLE_FORMAT_PCM_S15;
+ pContext->config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
pContext->config.inputCfg.samplingRate = 44100;
pContext->config.inputCfg.bufferProvider.getBuffer = NULL;
pContext->config.inputCfg.bufferProvider.releaseBuffer = NULL;
pContext->config.inputCfg.bufferProvider.cookie = NULL;
pContext->config.inputCfg.mask = EFFECT_CONFIG_ALL;
pContext->config.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE;
- pContext->config.outputCfg.channels = CHANNEL_STEREO;
- pContext->config.outputCfg.format = SAMPLE_FORMAT_PCM_S15;
+ pContext->config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
+ pContext->config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
pContext->config.outputCfg.samplingRate = 44100;
pContext->config.outputCfg.bufferProvider.getBuffer = NULL;
pContext->config.outputCfg.bufferProvider.releaseBuffer = NULL;
@@ -800,7 +823,7 @@
params.OperatingMode = LVM_MODE_ON;
params.SampleRate = LVM_FS_44100;
- if(pContext->config.inputCfg.channels == CHANNEL_MONO){
+ if(pContext->config.inputCfg.channels == AUDIO_CHANNEL_OUT_MONO){
params.SourceFormat = LVM_MONO;
} else {
params.SourceFormat = LVM_STEREO;
@@ -1832,8 +1855,9 @@
} // namespace
} // namespace
+extern "C" {
/* Effect Control Interface Implementation: Process */
-extern "C" int Reverb_process(effect_interface_t self,
+int Reverb_process(effect_handle_t self,
audio_buffer_t *inBuffer,
audio_buffer_t *outBuffer){
android::ReverbContext * pContext = (android::ReverbContext *) self;
@@ -1868,7 +1892,7 @@
} /* end Reverb_process */
/* Effect Control Interface Implementation: Command */
-extern "C" int Reverb_command(effect_interface_t self,
+int Reverb_command(effect_handle_t self,
uint32_t cmdCode,
uint32_t cmdSize,
void *pCmdData,
@@ -2075,9 +2099,55 @@
return 0;
} /* end Reverb_command */
-// effect_interface_t interface implementation for Reverb effect
+/* Effect Control Interface Implementation: get_descriptor */
+int Reverb_getDescriptor(effect_handle_t self,
+ effect_descriptor_t *pDescriptor)
+{
+ android::ReverbContext * pContext = (android::ReverbContext *)self;
+ const effect_descriptor_t *desc;
+
+ if (pContext == NULL || pDescriptor == NULL) {
+ LOGV("Reverb_getDescriptor() invalid param");
+ return -EINVAL;
+ }
+
+ if (pContext->auxiliary) {
+ if (pContext->preset) {
+ desc = &android::gAuxPresetReverbDescriptor;
+ } else {
+ desc = &android::gAuxEnvReverbDescriptor;
+ }
+ } else {
+ if (pContext->preset) {
+ desc = &android::gInsertPresetReverbDescriptor;
+ } else {
+ desc = &android::gInsertEnvReverbDescriptor;
+ }
+ }
+
+ memcpy(pDescriptor, desc, sizeof(effect_descriptor_t));
+
+ return 0;
+} /* end Reverb_getDescriptor */
+
+// effect_handle_t interface implementation for Reverb effect
const struct effect_interface_s gReverbInterface = {
Reverb_process,
- Reverb_command
+ Reverb_command,
+ Reverb_getDescriptor,
+ NULL,
}; /* end gReverbInterface */
+audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
+ tag : AUDIO_EFFECT_LIBRARY_TAG,
+ version : EFFECT_LIBRARY_API_VERSION,
+ name : "Reverb Library",
+ implementor : "NXP Software Ltd.",
+ query_num_effects : android::EffectQueryNumberEffects,
+ query_effect : android::EffectQueryEffect,
+ create_effect : android::EffectCreate,
+ release_effect : android::EffectRelease,
+ get_descriptor : android::EffectGetDescriptor,
+};
+
+}
diff --git a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.h b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.h
index 093992b..7c15b18 100644
--- a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.h
+++ b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.h
@@ -17,8 +17,8 @@
#ifndef ANDROID_EFFECTREVERB_H_
#define ANDROID_EFFECTREVERB_H_
-#include <media/EffectEnvironmentalReverbApi.h>
-#include <media/EffectPresetReverbApi.h>
+#include <audio_effects/effect_environmentalreverb.h>
+#include <audio_effects/effect_presetreverb.h>
#if __cplusplus
extern "C" {
diff --git a/media/libeffects/preprocessing/Android.mk b/media/libeffects/preprocessing/Android.mk
new file mode 100755
index 0000000..77d40b6
--- /dev/null
+++ b/media/libeffects/preprocessing/Android.mk
@@ -0,0 +1,32 @@
+LOCAL_PATH:= $(call my-dir)
+
+# audio preprocessing wrapper
+include $(CLEAR_VARS)
+
+LOCAL_MODULE:= libaudiopreprocessing
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx
+
+LOCAL_SRC_FILES:= \
+ PreProcessing.cpp
+
+LOCAL_C_INCLUDES += \
+ external/webrtc/src \
+ external/webrtc/src/modules/interface \
+ external/webrtc/src/modules/audio_processing/main/interface \
+ system/media/audio_effects/include
+
+LOCAL_C_INCLUDES += $(call include-path-for, speex)
+
+LOCAL_SHARED_LIBRARIES := \
+ libwebrtc_audio_preprocessing \
+ libspeexresampler \
+ libutils
+
+ifeq ($(TARGET_SIMULATOR),true)
+LOCAL_LDLIBS += -ldl
+else
+LOCAL_SHARED_LIBRARIES += libdl
+endif
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libeffects/preprocessing/PreProcessing.cpp b/media/libeffects/preprocessing/PreProcessing.cpp
new file mode 100755
index 0000000..ba286a1
--- /dev/null
+++ b/media/libeffects/preprocessing/PreProcessing.cpp
@@ -0,0 +1,1609 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#define LOG_TAG "PreProcessing"
+//#define LOG_NDEBUG 0
+#include <utils/Log.h>
+#include <utils/Timers.h>
+#include <hardware/audio_effect.h>
+#include <audio_effects/effect_aec.h>
+#include <audio_effects/effect_agc.h>
+#include <audio_effects/effect_ns.h>
+#include "modules/interface/module_common_types.h"
+#include "modules/audio_processing/main/interface/audio_processing.h"
+#include "speex/speex_resampler.h"
+
+
+//------------------------------------------------------------------------------
+// local definitions
+//------------------------------------------------------------------------------
+
+// maximum number of sessions
+#define PREPROC_NUM_SESSIONS 8
+
+// types of pre processing modules
+enum preproc_id
+{
+ PREPROC_AGC, // Automatic Gain Control
+ PREPROC_AEC, // Acoustic Echo Canceler
+ PREPROC_NS, // Noise Suppressor
+ PREPROC_NUM_EFFECTS
+};
+
+// Session state
+enum preproc_session_state {
+ PREPROC_SESSION_STATE_INIT, // initialized
+ PREPROC_SESSION_STATE_CONFIG // configuration received
+};
+
+// Effect/Preprocessor state
+enum preproc_effect_state {
+ PREPROC_EFFECT_STATE_INIT, // initialized
+ PREPROC_EFFECT_STATE_CREATED, // webRTC engine created
+ PREPROC_EFFECT_STATE_CONFIG, // configuration received/disabled
+ PREPROC_EFFECT_STATE_ACTIVE // active/enabled
+};
+
+// handle on webRTC engine
+typedef void* preproc_fx_handle_t;
+
+typedef struct preproc_session_s preproc_session_t;
+typedef struct preproc_effect_s preproc_effect_t;
+typedef struct preproc_ops_s preproc_ops_t;
+
+// Effect operation table. Functions for all pre processors are declared in sPreProcOps[] table.
+// Function pointer can be null if no action required.
+struct preproc_ops_s {
+ int (* create)(preproc_effect_t *fx);
+ int (* init)(preproc_effect_t *fx);
+ int (* reset)(preproc_effect_t *fx);
+ void (* enable)(preproc_effect_t *fx);
+ void (* disable)(preproc_effect_t *fx);
+ int (* set_parameter)(preproc_effect_t *fx, void *param, void *value);
+ int (* get_parameter)(preproc_effect_t *fx, void *param, size_t *size, void *value);
+ int (* set_device)(preproc_effect_t *fx, uint32_t device);
+};
+
+// Effect context
+struct preproc_effect_s {
+ const struct effect_interface_s *itfe;
+ uint32_t procId; // type of pre processor (enum preproc_id)
+ uint32_t state; // current state (enum preproc_effect_state)
+ preproc_session_t *session; // session the effect is on
+ const preproc_ops_t *ops; // effect ops table
+ preproc_fx_handle_t engine; // handle on webRTC engine
+};
+
+// Session context
+struct preproc_session_s {
+ struct preproc_effect_s effects[PREPROC_NUM_EFFECTS]; // effects in this session
+ uint32_t state; // current state (enum preproc_session_state)
+ int id; // audio session ID
+ int io; // handle of input stream this session is on
+ webrtc::AudioProcessing* apm; // handle on webRTC audio processing module (APM)
+ size_t apmFrameCount; // buffer size for webRTC process (10 ms)
+ uint32_t apmSamplingRate; // webRTC APM sampling rate (8/16 or 32 kHz)
+ size_t frameCount; // buffer size before input resampler ( <=> apmFrameCount)
+ uint32_t samplingRate; // sampling rate at effect process interface
+ uint32_t inChannelCount; // input channel count
+ uint32_t outChannelCount; // output channel count
+ uint32_t createdMsk; // bit field containing IDs of crested pre processors
+ uint32_t enabledMsk; // bit field containing IDs of enabled pre processors
+ uint32_t processedMsk; // bit field containing IDs of pre processors already
+ // processed in current round
+ webrtc::AudioFrame *procFrame; // audio frame passed to webRTC AMP ProcessStream()
+ int16_t *inBuf; // input buffer used when resampling
+ size_t inBufSize; // input buffer size in frames
+ size_t framesIn; // number of frames in input buffer
+ SpeexResamplerState *inResampler; // handle on input speex resampler
+ int16_t *outBuf; // output buffer used when resampling
+ size_t outBufSize; // output buffer size in frames
+ size_t framesOut; // number of frames in output buffer
+ SpeexResamplerState *outResampler; // handle on output speex resampler
+ uint32_t revChannelCount; // number of channels on reverse stream
+ uint32_t revEnabledMsk; // bit field containing IDs of enabled pre processors
+ // with reverse channel
+ uint32_t revProcessedMsk; // bit field containing IDs of pre processors with reverse
+ // channel already processed in current round
+ webrtc::AudioFrame *revFrame; // audio frame passed to webRTC AMP AnalyzeReverseStream()
+ int16_t *revBuf; // reverse channel input buffer
+ size_t revBufSize; // reverse channel input buffer size
+ size_t framesRev; // number of frames in reverse channel input buffer
+ SpeexResamplerState *revResampler; // handle on reverse channel input speex resampler
+};
+
+//------------------------------------------------------------------------------
+// Effect descriptors
+//------------------------------------------------------------------------------
+
+// UUIDs for effect types have been generated from http://www.itu.int/ITU-T/asn1/uuid.html
+// as the pre processing effects are not defined by OpenSL ES
+
+// Automatic Gain Control
+static const effect_descriptor_t sAgcDescriptor = {
+ { 0x0a8abfe0, 0x654c, 0x11e0, 0xba26, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }, // type
+ { 0xaa8130e0, 0x66fc, 0x11e0, 0xbad0, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }, // uuid
+ EFFECT_CONTROL_API_VERSION,
+ (EFFECT_FLAG_TYPE_PRE_PROC|EFFECT_FLAG_DEVICE_IND),
+ 0, //FIXME indicate CPU load
+ 0, //FIXME indicate memory usage
+ "Automatic Gain Control",
+ "The Android Open Source Project"
+};
+
+// Acoustic Echo Cancellation
+static const effect_descriptor_t sAecDescriptor = {
+ { 0x7b491460, 0x8d4d, 0x11e0, 0xbd61, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }, // type
+ { 0xbb392ec0, 0x8d4d, 0x11e0, 0xa896, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }, // uuid
+ EFFECT_CONTROL_API_VERSION,
+ (EFFECT_FLAG_TYPE_PRE_PROC|EFFECT_FLAG_DEVICE_IND),
+ 0, //FIXME indicate CPU load
+ 0, //FIXME indicate memory usage
+ "Acoustic Echo Canceler",
+ "The Android Open Source Project"
+};
+
+// Noise suppression
+static const effect_descriptor_t sNsDescriptor = {
+ { 0x58b4b260, 0x8e06, 0x11e0, 0xaa8e, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }, // type
+ { 0xc06c8400, 0x8e06, 0x11e0, 0x9cb6, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }, // uuid
+ EFFECT_CONTROL_API_VERSION,
+ (EFFECT_FLAG_TYPE_PRE_PROC|EFFECT_FLAG_DEVICE_IND),
+ 0, //FIXME indicate CPU load
+ 0, //FIXME indicate memory usage
+ "Noise Suppression",
+ "The Android Open Source Project"
+};
+
+
+static const effect_descriptor_t *sDescriptors[PREPROC_NUM_EFFECTS] = {
+ &sAgcDescriptor,
+ &sAecDescriptor,
+ &sNsDescriptor
+};
+
+//------------------------------------------------------------------------------
+// Helper functions
+//------------------------------------------------------------------------------
+
+const effect_uuid_t * const sUuidToPreProcTable[PREPROC_NUM_EFFECTS] = {
+ FX_IID_AGC,
+ FX_IID_AEC,
+ FX_IID_NS
+};
+
+
+const effect_uuid_t * ProcIdToUuid(int procId)
+{
+ if (procId >= PREPROC_NUM_EFFECTS) {
+ return EFFECT_UUID_NULL;
+ }
+ return sUuidToPreProcTable[procId];
+}
+
+uint32_t UuidToProcId(const effect_uuid_t * uuid)
+{
+ size_t i;
+ for (i = 0; i < PREPROC_NUM_EFFECTS; i++) {
+ if (memcmp(uuid, sUuidToPreProcTable[i], sizeof(*uuid)) == 0) {
+ break;
+ }
+ }
+ return i;
+}
+
+bool HasReverseStream(uint32_t procId)
+{
+ if (procId == PREPROC_AEC) {
+ return true;
+ }
+ return false;
+}
+
+
+//------------------------------------------------------------------------------
+// Automatic Gain Control (AGC)
+//------------------------------------------------------------------------------
+
+static const int kAgcDefaultTargetLevel = 0;
+static const int kAgcDefaultCompGain = 90;
+static const bool kAgcDefaultLimiter = true;
+
+int AgcInit (preproc_effect_t *effect)
+{
+ LOGV("AgcInit");
+ webrtc::GainControl *agc = static_cast<webrtc::GainControl *>(effect->engine);
+ agc->set_mode(webrtc::GainControl::kFixedDigital);
+ agc->set_target_level_dbfs(kAgcDefaultTargetLevel);
+ agc->set_compression_gain_db(kAgcDefaultCompGain);
+ agc->enable_limiter(kAgcDefaultLimiter);
+ return 0;
+}
+
+int AgcCreate(preproc_effect_t *effect)
+{
+ webrtc::GainControl *agc = effect->session->apm->gain_control();
+ LOGV("AgcCreate got agc %p", agc);
+ if (agc == NULL) {
+ LOGW("AgcCreate Error");
+ return -ENOMEM;
+ }
+ effect->engine = static_cast<preproc_fx_handle_t>(agc);
+ AgcInit(effect);
+ return 0;
+}
+
+int AgcGetParameter(preproc_effect_t *effect,
+ void *pParam,
+ size_t *pValueSize,
+ void *pValue)
+{
+ int status = 0;
+ uint32_t param = *(uint32_t *)pParam;
+ t_agc_settings *pProperties = (t_agc_settings *)pValue;
+ webrtc::GainControl *agc = static_cast<webrtc::GainControl *>(effect->engine);
+
+ switch (param) {
+ case AGC_PARAM_TARGET_LEVEL:
+ case AGC_PARAM_COMP_GAIN:
+ if (*pValueSize < sizeof(int16_t)) {
+ *pValueSize = 0;
+ return -EINVAL;
+ }
+ break;
+ case AGC_PARAM_LIMITER_ENA:
+ if (*pValueSize < sizeof(bool)) {
+ *pValueSize = 0;
+ return -EINVAL;
+ }
+ break;
+ case AGC_PARAM_PROPERTIES:
+ if (*pValueSize < sizeof(t_agc_settings)) {
+ *pValueSize = 0;
+ return -EINVAL;
+ }
+ break;
+
+ default:
+ LOGW("AgcGetParameter() unknown param %08x", param);
+ status = -EINVAL;
+ break;
+ }
+
+ switch (param) {
+ case AGC_PARAM_TARGET_LEVEL:
+ *(int16_t *) pValue = (int16_t)(agc->target_level_dbfs() * -100);
+ LOGV("AgcGetParameter() target level %d milliBels", *(int16_t *) pValue);
+ break;
+ case AGC_PARAM_COMP_GAIN:
+ *(int16_t *) pValue = (int16_t)(agc->compression_gain_db() * 100);
+ LOGV("AgcGetParameter() comp gain %d milliBels", *(int16_t *) pValue);
+ break;
+ case AGC_PARAM_LIMITER_ENA:
+ *(bool *) pValue = (bool)agc->is_limiter_enabled();
+ LOGV("AgcGetParameter() limiter enabled %s",
+ (*(int16_t *) pValue != 0) ? "true" : "false");
+ break;
+ case AGC_PARAM_PROPERTIES:
+ pProperties->targetLevel = (int16_t)(agc->target_level_dbfs() * -100);
+ pProperties->compGain = (int16_t)(agc->compression_gain_db() * 100);
+ pProperties->limiterEnabled = (bool)agc->is_limiter_enabled();
+ break;
+ default:
+ LOGW("AgcGetParameter() unknown param %d", param);
+ status = -EINVAL;
+ break;
+ }
+ return status;
+}
+
+int AgcSetParameter (preproc_effect_t *effect, void *pParam, void *pValue)
+{
+ int status = 0;
+ uint32_t param = *(uint32_t *)pParam;
+ t_agc_settings *pProperties = (t_agc_settings *)pValue;
+ webrtc::GainControl *agc = static_cast<webrtc::GainControl *>(effect->engine);
+
+ switch (param) {
+ case AGC_PARAM_TARGET_LEVEL:
+ LOGV("AgcSetParameter() target level %d milliBels", *(int16_t *)pValue);
+ status = agc->set_target_level_dbfs(-(*(int16_t *)pValue / 100));
+ break;
+ case AGC_PARAM_COMP_GAIN:
+ LOGV("AgcSetParameter() comp gain %d milliBels", *(int16_t *)pValue);
+ status = agc->set_compression_gain_db(*(int16_t *)pValue / 100);
+ break;
+ case AGC_PARAM_LIMITER_ENA:
+ LOGV("AgcSetParameter() limiter enabled %s", *(bool *)pValue ? "true" : "false");
+ status = agc->enable_limiter(*(bool *)pValue);
+ break;
+ case AGC_PARAM_PROPERTIES:
+ LOGV("AgcSetParameter() properties level %d, gain %d limiter %d",
+ pProperties->targetLevel,
+ pProperties->compGain,
+ pProperties->limiterEnabled);
+ status = agc->set_target_level_dbfs(-(pProperties->targetLevel / 100));
+ if (status != 0) break;
+ status = agc->set_compression_gain_db(pProperties->compGain / 100);
+ if (status != 0) break;
+ status = agc->enable_limiter(pProperties->limiterEnabled);
+ break;
+ default:
+ LOGW("AgcSetParameter() unknown param %08x value %08x", param, *(uint32_t *)pValue);
+ status = -EINVAL;
+ break;
+ }
+
+ LOGV("AgcSetParameter() done status %d", status);
+
+ return status;
+}
+
+void AgcEnable(preproc_effect_t *effect)
+{
+ webrtc::GainControl *agc = static_cast<webrtc::GainControl *>(effect->engine);
+ LOGV("AgcEnable agc %p", agc);
+ agc->Enable(true);
+}
+
+void AgcDisable(preproc_effect_t *effect)
+{
+ LOGV("AgcDisable");
+ webrtc::GainControl *agc = static_cast<webrtc::GainControl *>(effect->engine);
+ agc->Enable(false);
+}
+
+
+static const preproc_ops_t sAgcOps = {
+ AgcCreate,
+ AgcInit,
+ NULL,
+ AgcEnable,
+ AgcDisable,
+ AgcSetParameter,
+ AgcGetParameter,
+ NULL
+};
+
+
+//------------------------------------------------------------------------------
+// Acoustic Echo Canceler (AEC)
+//------------------------------------------------------------------------------
+
+static const webrtc::EchoControlMobile::RoutingMode kAecDefaultMode =
+ webrtc::EchoControlMobile::kEarpiece;
+static const bool kAecDefaultComfortNoise = true;
+
+int AecInit (preproc_effect_t *effect)
+{
+ LOGV("AecInit");
+ webrtc::EchoControlMobile *aec = static_cast<webrtc::EchoControlMobile *>(effect->engine);
+ aec->set_routing_mode(kAecDefaultMode);
+ aec->enable_comfort_noise(kAecDefaultComfortNoise);
+ return 0;
+}
+
+int AecCreate(preproc_effect_t *effect)
+{
+ webrtc::EchoControlMobile *aec = effect->session->apm->echo_control_mobile();
+ LOGV("AecCreate got aec %p", aec);
+ if (aec == NULL) {
+ LOGW("AgcCreate Error");
+ return -ENOMEM;
+ }
+ effect->engine = static_cast<preproc_fx_handle_t>(aec);
+ AecInit (effect);
+ return 0;
+}
+
+int AecGetParameter(preproc_effect_t *effect,
+ void *pParam,
+ size_t *pValueSize,
+ void *pValue)
+{
+ int status = 0;
+ uint32_t param = *(uint32_t *)pParam;
+
+ if (*pValueSize < sizeof(uint32_t)) {
+ return -EINVAL;
+ }
+ switch (param) {
+ case AEC_PARAM_ECHO_DELAY:
+ case AEC_PARAM_PROPERTIES:
+ *(uint32_t *)pValue = 1000 * effect->session->apm->stream_delay_ms();
+ LOGV("AecGetParameter() echo delay %d us", *(uint32_t *)pValue);
+ break;
+ default:
+ LOGW("AecGetParameter() unknown param %08x value %08x", param, *(uint32_t *)pValue);
+ status = -EINVAL;
+ break;
+ }
+ return status;
+}
+
+int AecSetParameter (preproc_effect_t *effect, void *pParam, void *pValue)
+{
+ int status = 0;
+ uint32_t param = *(uint32_t *)pParam;
+ uint32_t value = *(uint32_t *)pValue;
+
+ switch (param) {
+ case AEC_PARAM_ECHO_DELAY:
+ case AEC_PARAM_PROPERTIES:
+ status = effect->session->apm->set_stream_delay_ms(value/1000);
+ LOGV("AecSetParameter() echo delay %d us, status %d", value, status);
+ break;
+ default:
+ LOGW("AecSetParameter() unknown param %08x value %08x", param, *(uint32_t *)pValue);
+ status = -EINVAL;
+ break;
+ }
+ return status;
+}
+
+void AecEnable(preproc_effect_t *effect)
+{
+ webrtc::EchoControlMobile *aec = static_cast<webrtc::EchoControlMobile *>(effect->engine);
+ LOGV("AecEnable aec %p", aec);
+ aec->Enable(true);
+}
+
+void AecDisable(preproc_effect_t *effect)
+{
+ LOGV("AecDisable");
+ webrtc::EchoControlMobile *aec = static_cast<webrtc::EchoControlMobile *>(effect->engine);
+ aec->Enable(false);
+}
+
+int AecSetDevice(preproc_effect_t *effect, uint32_t device)
+{
+ LOGV("AecSetDevice %08x", device);
+ webrtc::EchoControlMobile *aec = static_cast<webrtc::EchoControlMobile *>(effect->engine);
+ webrtc::EchoControlMobile::RoutingMode mode = webrtc::EchoControlMobile::kQuietEarpieceOrHeadset;
+
+ switch(device) {
+ case AUDIO_DEVICE_OUT_EARPIECE:
+ mode = webrtc::EchoControlMobile::kEarpiece;
+ break;
+ case AUDIO_DEVICE_OUT_SPEAKER:
+ mode = webrtc::EchoControlMobile::kSpeakerphone;
+ break;
+ case AUDIO_DEVICE_OUT_WIRED_HEADSET:
+ case AUDIO_DEVICE_OUT_WIRED_HEADPHONE:
+ default:
+ break;
+ }
+ aec->set_routing_mode(mode);
+ return 0;
+}
+
+static const preproc_ops_t sAecOps = {
+ AecCreate,
+ AecInit,
+ NULL,
+ AecEnable,
+ AecDisable,
+ AecSetParameter,
+ AecGetParameter,
+ AecSetDevice
+};
+
+//------------------------------------------------------------------------------
+// Noise Suppression (NS)
+//------------------------------------------------------------------------------
+
+static const webrtc::NoiseSuppression::Level kNsDefaultLevel = webrtc::NoiseSuppression::kModerate;
+
+int NsInit (preproc_effect_t *effect)
+{
+ LOGV("NsInit");
+ webrtc::NoiseSuppression *ns = static_cast<webrtc::NoiseSuppression *>(effect->engine);
+ ns->set_level(kNsDefaultLevel);
+ return 0;
+}
+
+int NsCreate(preproc_effect_t *effect)
+{
+ webrtc::NoiseSuppression *ns = effect->session->apm->noise_suppression();
+ LOGV("NsCreate got ns %p", ns);
+ if (ns == NULL) {
+ LOGW("AgcCreate Error");
+ return -ENOMEM;
+ }
+ effect->engine = static_cast<preproc_fx_handle_t>(ns);
+ NsInit (effect);
+ return 0;
+}
+
+int NsGetParameter(preproc_effect_t *effect,
+ void *pParam,
+ size_t *pValueSize,
+ void *pValue)
+{
+ int status = 0;
+ return status;
+}
+
+int NsSetParameter (preproc_effect_t *effect, void *pParam, void *pValue)
+{
+ int status = 0;
+ return status;
+}
+
+void NsEnable(preproc_effect_t *effect)
+{
+ webrtc::NoiseSuppression *ns = static_cast<webrtc::NoiseSuppression *>(effect->engine);
+ LOGV("NsEnable ns %p", ns);
+ ns->Enable(true);
+}
+
+void NsDisable(preproc_effect_t *effect)
+{
+ LOGV("NsDisable");
+ webrtc::NoiseSuppression *ns = static_cast<webrtc::NoiseSuppression *>(effect->engine);
+ ns->Enable(false);
+}
+
+static const preproc_ops_t sNsOps = {
+ NsCreate,
+ NsInit,
+ NULL,
+ NsEnable,
+ NsDisable,
+ NsSetParameter,
+ NsGetParameter,
+ NULL
+};
+
+
+static const preproc_ops_t *sPreProcOps[PREPROC_NUM_EFFECTS] = {
+ &sAgcOps,
+ &sAecOps,
+ &sNsOps
+};
+
+
+//------------------------------------------------------------------------------
+// Effect functions
+//------------------------------------------------------------------------------
+
+void Session_SetProcEnabled(preproc_session_t *session, uint32_t procId, bool enabled);
+
+extern "C" const struct effect_interface_s sEffectInterface;
+extern "C" const struct effect_interface_s sEffectInterfaceReverse;
+
+#define BAD_STATE_ABORT(from, to) \
+ LOG_ALWAYS_FATAL("Bad state transition from %d to %d", from, to);
+
+int Effect_SetState(preproc_effect_t *effect, uint32_t state)
+{
+ int status = 0;
+ LOGV("Effect_SetState proc %d, new %d old %d", effect->procId, state, effect->state);
+ switch(state) {
+ case PREPROC_EFFECT_STATE_INIT:
+ switch(effect->state) {
+ case PREPROC_EFFECT_STATE_ACTIVE:
+ effect->ops->disable(effect);
+ Session_SetProcEnabled(effect->session, effect->procId, false);
+ case PREPROC_EFFECT_STATE_CONFIG:
+ case PREPROC_EFFECT_STATE_CREATED:
+ case PREPROC_EFFECT_STATE_INIT:
+ break;
+ default:
+ BAD_STATE_ABORT(effect->state, state);
+ }
+ break;
+ case PREPROC_EFFECT_STATE_CREATED:
+ switch(effect->state) {
+ case PREPROC_EFFECT_STATE_INIT:
+ status = effect->ops->create(effect);
+ break;
+ case PREPROC_EFFECT_STATE_CREATED:
+ case PREPROC_EFFECT_STATE_ACTIVE:
+ case PREPROC_EFFECT_STATE_CONFIG:
+ LOGE("Effect_SetState invalid transition");
+ status = -ENOSYS;
+ break;
+ default:
+ BAD_STATE_ABORT(effect->state, state);
+ }
+ break;
+ case PREPROC_EFFECT_STATE_CONFIG:
+ switch(effect->state) {
+ case PREPROC_EFFECT_STATE_INIT:
+ LOGE("Effect_SetState invalid transition");
+ status = -ENOSYS;
+ break;
+ case PREPROC_EFFECT_STATE_ACTIVE:
+ effect->ops->disable(effect);
+ Session_SetProcEnabled(effect->session, effect->procId, false);
+ break;
+ case PREPROC_EFFECT_STATE_CREATED:
+ case PREPROC_EFFECT_STATE_CONFIG:
+ break;
+ default:
+ BAD_STATE_ABORT(effect->state, state);
+ }
+ break;
+ case PREPROC_EFFECT_STATE_ACTIVE:
+ switch(effect->state) {
+ case PREPROC_EFFECT_STATE_INIT:
+ case PREPROC_EFFECT_STATE_CREATED:
+ case PREPROC_EFFECT_STATE_ACTIVE:
+ LOGE("Effect_SetState invalid transition");
+ status = -ENOSYS;
+ break;
+ case PREPROC_EFFECT_STATE_CONFIG:
+ effect->ops->enable(effect);
+ Session_SetProcEnabled(effect->session, effect->procId, true);
+ break;
+ default:
+ BAD_STATE_ABORT(effect->state, state);
+ }
+ break;
+ default:
+ BAD_STATE_ABORT(effect->state, state);
+ }
+ if (status == 0) {
+ effect->state = state;
+ }
+ return status;
+}
+
+int Effect_Init(preproc_effect_t *effect, uint32_t procId)
+{
+ if (HasReverseStream(procId)) {
+ effect->itfe = &sEffectInterfaceReverse;
+ } else {
+ effect->itfe = &sEffectInterface;
+ }
+ effect->ops = sPreProcOps[procId];
+ effect->procId = procId;
+ effect->state = PREPROC_EFFECT_STATE_INIT;
+ return 0;
+}
+
+int Effect_Create(preproc_effect_t *effect,
+ preproc_session_t *session,
+ effect_handle_t *interface)
+{
+ effect->session = session;
+ *interface = (effect_handle_t)&effect->itfe;
+ return Effect_SetState(effect, PREPROC_EFFECT_STATE_CREATED);
+}
+
+int Effect_Release(preproc_effect_t *effect)
+{
+ return Effect_SetState(effect, PREPROC_EFFECT_STATE_INIT);
+}
+
+
+//------------------------------------------------------------------------------
+// Session functions
+//------------------------------------------------------------------------------
+
+#define RESAMPLER_QUALITY SPEEX_RESAMPLER_QUALITY_VOIP
+
+static const int kPreprocDefaultSr = 16000;
+static const int kPreProcDefaultCnl = 1;
+
+int Session_Init(preproc_session_t *session)
+{
+ size_t i;
+ int status = 0;
+
+ session->state = PREPROC_SESSION_STATE_INIT;
+ session->id = 0;
+ session->io = 0;
+ session->createdMsk = 0;
+ session->apm = NULL;
+ for (i = 0; i < PREPROC_NUM_EFFECTS && status == 0; i++) {
+ status = Effect_Init(&session->effects[i], i);
+ }
+ return status;
+}
+
+
+extern "C" int Session_CreateEffect(preproc_session_t *session,
+ int32_t procId,
+ effect_handle_t *interface)
+{
+ int status = -ENOMEM;
+
+ LOGV("Session_CreateEffect procId %d, createdMsk %08x", procId, session->createdMsk);
+
+ if (session->createdMsk == 0) {
+ session->apm = webrtc::AudioProcessing::Create(session->io);
+ if (session->apm == NULL) {
+ LOGW("Session_CreateEffect could not get apm engine");
+ goto error;
+ }
+ session->apm->set_sample_rate_hz(kPreprocDefaultSr);
+ session->apm->set_num_channels(kPreProcDefaultCnl, kPreProcDefaultCnl);
+ session->apm->set_num_reverse_channels(kPreProcDefaultCnl);
+ session->procFrame = new webrtc::AudioFrame();
+ if (session->procFrame == NULL) {
+ LOGW("Session_CreateEffect could not allocate audio frame");
+ goto error;
+ }
+ session->revFrame = new webrtc::AudioFrame();
+ if (session->revFrame == NULL) {
+ LOGW("Session_CreateEffect could not allocate reverse audio frame");
+ goto error;
+ }
+ session->apmSamplingRate = kPreprocDefaultSr;
+ session->apmFrameCount = (kPreprocDefaultSr) / 100;
+ session->frameCount = session->apmFrameCount;
+ session->samplingRate = kPreprocDefaultSr;
+ session->inChannelCount = kPreProcDefaultCnl;
+ session->outChannelCount = kPreProcDefaultCnl;
+ session->procFrame->_frequencyInHz = kPreprocDefaultSr;
+ session->procFrame->_audioChannel = kPreProcDefaultCnl;
+ session->revChannelCount = kPreProcDefaultCnl;
+ session->revFrame->_frequencyInHz = kPreprocDefaultSr;
+ session->revFrame->_audioChannel = kPreProcDefaultCnl;
+ session->enabledMsk = 0;
+ session->processedMsk = 0;
+ session->revEnabledMsk = 0;
+ session->revProcessedMsk = 0;
+ session->inResampler = NULL;
+ session->inBuf = NULL;
+ session->inBufSize = 0;
+ session->outResampler = NULL;
+ session->outBuf = NULL;
+ session->outBufSize = 0;
+ session->revResampler = NULL;
+ session->revBuf = NULL;
+ session->revBufSize = 0;
+ }
+ status = Effect_Create(&session->effects[procId], session, interface);
+ if (status < 0) {
+ goto error;
+ }
+ LOGV("Session_CreateEffect OK");
+ session->createdMsk |= (1<<procId);
+ return status;
+
+error:
+ if (session->createdMsk == 0) {
+ delete session->revFrame;
+ session->revFrame = NULL;
+ delete session->procFrame;
+ session->procFrame = NULL;
+ webrtc::AudioProcessing::Destroy(session->apm);
+ session->apm = NULL;
+ }
+ return status;
+}
+
+int Session_ReleaseEffect(preproc_session_t *session,
+ preproc_effect_t *fx)
+{
+ LOGW_IF(Effect_Release(fx) != 0, " Effect_Release() failed for proc ID %d", fx->procId);
+ session->createdMsk &= ~(1<<fx->procId);
+ if (session->createdMsk == 0) {
+ webrtc::AudioProcessing::Destroy(session->apm);
+ session->apm = NULL;
+ delete session->procFrame;
+ session->procFrame = NULL;
+ delete session->revFrame;
+ session->revFrame = NULL;
+ if (session->inResampler != NULL) {
+ speex_resampler_destroy(session->inResampler);
+ session->inResampler = NULL;
+ }
+ if (session->outResampler != NULL) {
+ speex_resampler_destroy(session->outResampler);
+ session->outResampler = NULL;
+ }
+ if (session->revResampler != NULL) {
+ speex_resampler_destroy(session->revResampler);
+ session->revResampler = NULL;
+ }
+ delete session->inBuf;
+ session->inBuf = NULL;
+ delete session->outBuf;
+ session->outBuf = NULL;
+ delete session->revBuf;
+ session->revBuf = NULL;
+
+ session->io = 0;
+ }
+
+ return 0;
+}
+
+
+int Session_SetConfig(preproc_session_t *session, effect_config_t *config)
+{
+ uint32_t sr;
+ uint32_t inCnl = popcount(config->inputCfg.channels);
+ uint32_t outCnl = popcount(config->outputCfg.channels);
+
+ if (config->inputCfg.samplingRate != config->outputCfg.samplingRate ||
+ config->inputCfg.format != config->outputCfg.format ||
+ config->inputCfg.format != AUDIO_FORMAT_PCM_16_BIT) {
+ return -EINVAL;
+ }
+
+ LOGV("Session_SetConfig sr %d cnl %08x",
+ config->inputCfg.samplingRate, config->inputCfg.channels);
+ int status;
+
+ // AEC implementation is limited to 16kHz
+ if (config->inputCfg.samplingRate >= 32000 && !(session->createdMsk & (1 << PREPROC_AEC))) {
+ session->apmSamplingRate = 32000;
+ } else
+ if (config->inputCfg.samplingRate >= 16000) {
+ session->apmSamplingRate = 16000;
+ } else if (config->inputCfg.samplingRate >= 8000) {
+ session->apmSamplingRate = 8000;
+ }
+ status = session->apm->set_sample_rate_hz(session->apmSamplingRate);
+ if (status < 0) {
+ return -EINVAL;
+ }
+ status = session->apm->set_num_channels(inCnl, outCnl);
+ if (status < 0) {
+ return -EINVAL;
+ }
+ status = session->apm->set_num_reverse_channels(inCnl);
+ if (status < 0) {
+ return -EINVAL;
+ }
+
+ session->samplingRate = config->inputCfg.samplingRate;
+ session->apmFrameCount = session->apmSamplingRate / 100;
+ if (session->samplingRate == session->apmSamplingRate) {
+ session->frameCount = session->apmFrameCount;
+ } else {
+ session->frameCount = (session->apmFrameCount * session->samplingRate) /
+ session->apmSamplingRate + 1;
+ }
+ session->inChannelCount = inCnl;
+ session->outChannelCount = outCnl;
+ session->procFrame->_audioChannel = inCnl;
+ session->procFrame->_frequencyInHz = session->apmSamplingRate;
+
+ session->revChannelCount = inCnl;
+ session->revFrame->_audioChannel = inCnl;
+ session->revFrame->_frequencyInHz = session->apmSamplingRate;
+
+ if (session->inResampler != NULL) {
+ speex_resampler_destroy(session->inResampler);
+ session->inResampler = NULL;
+ }
+ if (session->outResampler != NULL) {
+ speex_resampler_destroy(session->outResampler);
+ session->outResampler = NULL;
+ }
+ if (session->revResampler != NULL) {
+ speex_resampler_destroy(session->revResampler);
+ session->revResampler = NULL;
+ }
+ if (session->samplingRate != session->apmSamplingRate) {
+ int error;
+ session->inResampler = speex_resampler_init(session->inChannelCount,
+ session->samplingRate,
+ session->apmSamplingRate,
+ RESAMPLER_QUALITY,
+ &error);
+ if (session->inResampler == NULL) {
+ LOGW("Session_SetConfig Cannot create speex resampler: %s",
+ speex_resampler_strerror(error));
+ return -EINVAL;
+ }
+ session->outResampler = speex_resampler_init(session->outChannelCount,
+ session->apmSamplingRate,
+ session->samplingRate,
+ RESAMPLER_QUALITY,
+ &error);
+ if (session->outResampler == NULL) {
+ LOGW("Session_SetConfig Cannot create speex resampler: %s",
+ speex_resampler_strerror(error));
+ speex_resampler_destroy(session->inResampler);
+ session->inResampler = NULL;
+ return -EINVAL;
+ }
+ session->revResampler = speex_resampler_init(session->inChannelCount,
+ session->samplingRate,
+ session->apmSamplingRate,
+ RESAMPLER_QUALITY,
+ &error);
+ if (session->revResampler == NULL) {
+ LOGW("Session_SetConfig Cannot create speex resampler: %s",
+ speex_resampler_strerror(error));
+ speex_resampler_destroy(session->inResampler);
+ session->inResampler = NULL;
+ speex_resampler_destroy(session->outResampler);
+ session->outResampler = NULL;
+ return -EINVAL;
+ }
+ }
+
+ session->state = PREPROC_SESSION_STATE_CONFIG;
+ return 0;
+}
+
+int Session_SetReverseConfig(preproc_session_t *session, effect_config_t *config)
+{
+ if (config->inputCfg.samplingRate != config->outputCfg.samplingRate ||
+ config->inputCfg.format != config->outputCfg.format ||
+ config->inputCfg.format != AUDIO_FORMAT_PCM_16_BIT) {
+ return -EINVAL;
+ }
+
+ LOGV("Session_SetReverseConfig sr %d cnl %08x",
+ config->inputCfg.samplingRate, config->inputCfg.channels);
+
+ if (session->state < PREPROC_SESSION_STATE_CONFIG) {
+ return -ENOSYS;
+ }
+ if (config->inputCfg.samplingRate != session->samplingRate ||
+ config->inputCfg.format != AUDIO_FORMAT_PCM_16_BIT) {
+ return -EINVAL;
+ }
+ uint32_t inCnl = popcount(config->inputCfg.channels);
+ int status = session->apm->set_num_reverse_channels(inCnl);
+ if (status < 0) {
+ return -EINVAL;
+ }
+ session->revChannelCount = inCnl;
+ session->revFrame->_audioChannel = inCnl;
+ session->revFrame->_frequencyInHz = session->apmSamplingRate;
+ return 0;
+}
+
+void Session_SetProcEnabled(preproc_session_t *session, uint32_t procId, bool enabled)
+{
+ if (enabled) {
+ if(session->enabledMsk == 0) {
+ session->framesIn = 0;
+ if (session->inResampler != NULL) {
+ speex_resampler_reset_mem(session->inResampler);
+ }
+ session->framesOut = 0;
+ if (session->outResampler != NULL) {
+ speex_resampler_reset_mem(session->outResampler);
+ }
+ }
+ session->enabledMsk |= (1 << procId);
+ if (HasReverseStream(procId)) {
+ session->framesRev = 0;
+ if (session->revResampler != NULL) {
+ speex_resampler_reset_mem(session->revResampler);
+ }
+ session->revEnabledMsk |= (1 << procId);
+ }
+ } else {
+ session->enabledMsk &= ~(1 << procId);
+ if (HasReverseStream(procId)) {
+ session->revEnabledMsk &= ~(1 << procId);
+ }
+ }
+ LOGV("Session_SetProcEnabled proc %d, enabled %d enabledMsk %08x revEnabledMsk %08x",
+ procId, enabled, session->enabledMsk, session->revEnabledMsk);
+ session->processedMsk = 0;
+ if (HasReverseStream(procId)) {
+ session->revProcessedMsk = 0;
+ }
+}
+
+//------------------------------------------------------------------------------
+// Bundle functions
+//------------------------------------------------------------------------------
+
+static int sInitStatus = 1;
+static preproc_session_t sSessions[PREPROC_NUM_SESSIONS];
+
+preproc_session_t *PreProc_GetSession(int32_t procId, int32_t sessionId, int32_t ioId)
+{
+ size_t i;
+ int free = -1;
+ for (i = 0; i < PREPROC_NUM_SESSIONS; i++) {
+ if (sSessions[i].io == ioId) {
+ if (sSessions[i].createdMsk & (1 << procId)) {
+ return NULL;
+ }
+ return &sSessions[i];
+ }
+ }
+ for (i = 0; i < PREPROC_NUM_SESSIONS; i++) {
+ if (sSessions[i].io == 0) {
+ sSessions[i].id = sessionId;
+ sSessions[i].io = ioId;
+ return &sSessions[i];
+ }
+ }
+ return NULL;
+}
+
+
+int PreProc_Init() {
+ size_t i;
+ int status = 0;
+
+ if (sInitStatus <= 0) {
+ return sInitStatus;
+ }
+ for (i = 0; i < PREPROC_NUM_SESSIONS && status == 0; i++) {
+ status = Session_Init(&sSessions[i]);
+ }
+ sInitStatus = status;
+ return sInitStatus;
+}
+
+const effect_descriptor_t *PreProc_GetDescriptor(effect_uuid_t *uuid)
+{
+ size_t i;
+ for (i = 0; i < PREPROC_NUM_EFFECTS; i++) {
+ if (memcmp(&sDescriptors[i]->uuid, uuid, sizeof(effect_uuid_t)) == 0) {
+ return sDescriptors[i];
+ }
+ }
+ return NULL;
+}
+
+
+extern "C" {
+
+//------------------------------------------------------------------------------
+// Effect Control Interface Implementation
+//------------------------------------------------------------------------------
+
+int PreProcessingFx_Process(effect_handle_t self,
+ audio_buffer_t *inBuffer,
+ audio_buffer_t *outBuffer)
+{
+ preproc_effect_t * effect = (preproc_effect_t *)self;
+ int status = 0;
+
+ if (effect == NULL){
+ LOGV("PreProcessingFx_Process() ERROR effect == NULL");
+ return -EINVAL;
+ }
+ preproc_session_t * session = (preproc_session_t *)effect->session;
+
+ if (inBuffer == NULL || inBuffer->raw == NULL ||
+ outBuffer == NULL || outBuffer->raw == NULL){
+ LOGW("PreProcessingFx_Process() ERROR bad pointer");
+ return -EINVAL;
+ }
+
+ session->processedMsk |= (1<<effect->procId);
+
+// LOGV("PreProcessingFx_Process In %d frames enabledMsk %08x processedMsk %08x",
+// inBuffer->frameCount, session->enabledMsk, session->processedMsk);
+
+ if ((session->processedMsk & session->enabledMsk) == session->enabledMsk) {
+ effect->session->processedMsk = 0;
+ size_t framesRq = outBuffer->frameCount;
+ size_t framesWr = 0;
+ if (session->framesOut) {
+ size_t fr = session->framesOut;
+ if (outBuffer->frameCount < fr) {
+ fr = outBuffer->frameCount;
+ }
+ memcpy(outBuffer->s16,
+ session->outBuf,
+ fr * session->outChannelCount * sizeof(int16_t));
+ memcpy(session->outBuf,
+ session->outBuf + fr * session->outChannelCount,
+ (session->framesOut - fr) * session->outChannelCount * sizeof(int16_t));
+ session->framesOut -= fr;
+ framesWr += fr;
+ }
+ outBuffer->frameCount = framesWr;
+ if (framesWr == framesRq) {
+ inBuffer->frameCount = 0;
+ return 0;
+ }
+
+ if (session->inResampler != NULL) {
+ size_t fr = session->frameCount - session->framesIn;
+ if (inBuffer->frameCount < fr) {
+ fr = inBuffer->frameCount;
+ }
+ if (session->inBufSize < session->framesIn + fr) {
+ session->inBufSize = session->framesIn + fr;
+ session->inBuf = (int16_t *)realloc(session->inBuf,
+ session->inBufSize * session->inChannelCount * sizeof(int16_t));
+ }
+ memcpy(session->inBuf + session->framesIn * session->inChannelCount,
+ inBuffer->s16,
+ fr * session->inChannelCount * sizeof(int16_t));
+
+ session->framesIn += fr;
+ inBuffer->frameCount = fr;
+ if (session->framesIn < session->frameCount) {
+ return 0;
+ }
+ size_t frIn = session->framesIn;
+ size_t frOut = session->apmFrameCount;
+ if (session->inChannelCount == 1) {
+ speex_resampler_process_int(session->inResampler,
+ 0,
+ session->inBuf,
+ &frIn,
+ session->procFrame->_payloadData,
+ &frOut);
+ } else {
+ speex_resampler_process_interleaved_int(session->inResampler,
+ session->inBuf,
+ &frIn,
+ session->procFrame->_payloadData,
+ &frOut);
+ }
+ memcpy(session->inBuf,
+ session->inBuf + frIn * session->inChannelCount,
+ (session->framesIn - frIn) * session->inChannelCount * sizeof(int16_t));
+ session->framesIn -= frIn;
+ } else {
+ size_t fr = session->frameCount - session->framesIn;
+ if (inBuffer->frameCount < fr) {
+ fr = inBuffer->frameCount;
+ }
+ memcpy(session->procFrame->_payloadData + session->framesIn * session->inChannelCount,
+ inBuffer->s16,
+ fr * session->inChannelCount * sizeof(int16_t));
+ session->framesIn += fr;
+ inBuffer->frameCount = fr;
+ if (session->framesIn < session->frameCount) {
+ return 0;
+ }
+ session->framesIn = 0;
+ }
+ session->procFrame->_payloadDataLengthInSamples =
+ session->apmFrameCount * session->inChannelCount;
+
+ effect->session->apm->ProcessStream(session->procFrame);
+
+ if (session->outBufSize < session->framesOut + session->frameCount) {
+ session->outBufSize = session->framesOut + session->frameCount;
+ session->outBuf = (int16_t *)realloc(session->outBuf,
+ session->outBufSize * session->outChannelCount * sizeof(int16_t));
+ }
+
+ if (session->outResampler != NULL) {
+ size_t frIn = session->apmFrameCount;
+ size_t frOut = session->frameCount;
+ if (session->inChannelCount == 1) {
+ speex_resampler_process_int(session->outResampler,
+ 0,
+ session->procFrame->_payloadData,
+ &frIn,
+ session->outBuf + session->framesOut * session->outChannelCount,
+ &frOut);
+ } else {
+ speex_resampler_process_interleaved_int(session->outResampler,
+ session->procFrame->_payloadData,
+ &frIn,
+ session->outBuf + session->framesOut * session->outChannelCount,
+ &frOut);
+ }
+ session->framesOut += frOut;
+ } else {
+ memcpy(session->outBuf + session->framesOut * session->outChannelCount,
+ session->procFrame->_payloadData,
+ session->frameCount * session->outChannelCount * sizeof(int16_t));
+ session->framesOut += session->frameCount;
+ }
+ size_t fr = session->framesOut;
+ if (framesRq - framesWr < fr) {
+ fr = framesRq - framesWr;
+ }
+ memcpy(outBuffer->s16 + framesWr * session->outChannelCount,
+ session->outBuf,
+ fr * session->outChannelCount * sizeof(int16_t));
+ memcpy(session->outBuf,
+ session->outBuf + fr * session->outChannelCount,
+ (session->framesOut - fr) * session->outChannelCount * sizeof(int16_t));
+ session->framesOut -= fr;
+ outBuffer->frameCount += fr;
+
+ return 0;
+ } else {
+ return -ENODATA;
+ }
+}
+
+int PreProcessingFx_Command(effect_handle_t self,
+ uint32_t cmdCode,
+ uint32_t cmdSize,
+ void *pCmdData,
+ uint32_t *replySize,
+ void *pReplyData)
+{
+ preproc_effect_t * effect = (preproc_effect_t *) self;
+ int retsize;
+ int status;
+
+ if (effect == NULL){
+ return -EINVAL;
+ }
+
+ //LOGV("PreProcessingFx_Command: command %d cmdSize %d",cmdCode, cmdSize);
+
+ switch (cmdCode){
+ case EFFECT_CMD_INIT:
+ if (pReplyData == NULL || *replySize != sizeof(int)){
+ return -EINVAL;
+ }
+ if (effect->ops->init) {
+ effect->ops->init(effect);
+ }
+ *(int *)pReplyData = 0;
+ break;
+
+ case EFFECT_CMD_CONFIGURE:
+ if (pCmdData == NULL||
+ cmdSize != sizeof(effect_config_t)||
+ pReplyData == NULL||
+ *replySize != sizeof(int)){
+ LOGV("PreProcessingFx_Command cmdCode Case: "
+ "EFFECT_CMD_CONFIGURE: ERROR");
+ return -EINVAL;
+ }
+ *(int *)pReplyData = Session_SetConfig(effect->session, (effect_config_t *)pCmdData);
+ if (*(int *)pReplyData != 0) {
+ break;
+ }
+ *(int *)pReplyData = Effect_SetState(effect, PREPROC_EFFECT_STATE_CONFIG);
+ break;
+
+ case EFFECT_CMD_CONFIGURE_REVERSE:
+ if (pCmdData == NULL||
+ cmdSize != sizeof(effect_config_t)||
+ pReplyData == NULL||
+ *replySize != sizeof(int)){
+ LOGV("PreProcessingFx_Command cmdCode Case: "
+ "EFFECT_CMD_CONFIGURE_REVERSE: ERROR");
+ return -EINVAL;
+ }
+ *(int *)pReplyData = Session_SetReverseConfig(effect->session,
+ (effect_config_t *)pCmdData);
+ if (*(int *)pReplyData != 0) {
+ break;
+ }
+ break;
+
+ case EFFECT_CMD_RESET:
+ if (effect->ops->reset) {
+ effect->ops->reset(effect);
+ }
+ break;
+
+ case EFFECT_CMD_GET_PARAM:{
+ if (pCmdData == NULL ||
+ cmdSize < (int)sizeof(effect_param_t) ||
+ pReplyData == NULL ||
+ *replySize < (int)sizeof(effect_param_t)){
+ LOGV("PreProcessingFx_Command cmdCode Case: "
+ "EFFECT_CMD_GET_PARAM: ERROR");
+ return -EINVAL;
+ }
+ effect_param_t *p = (effect_param_t *)pCmdData;
+
+ memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + p->psize);
+
+ p = (effect_param_t *)pReplyData;
+
+ int voffset = ((p->psize - 1) / sizeof(int32_t) + 1) * sizeof(int32_t);
+
+ if (effect->ops->get_parameter) {
+ p->status = effect->ops->get_parameter(effect, p->data,
+ (size_t *)&p->vsize,
+ p->data + voffset);
+ *replySize = sizeof(effect_param_t) + voffset + p->vsize;
+ }
+ } break;
+
+ case EFFECT_CMD_SET_PARAM:{
+ if (pCmdData == NULL||
+ cmdSize < (int)sizeof(effect_param_t) ||
+ pReplyData == NULL ||
+ *replySize != sizeof(int32_t)){
+ LOGV("PreProcessingFx_Command cmdCode Case: "
+ "EFFECT_CMD_SET_PARAM: ERROR");
+ return -EINVAL;
+ }
+ effect_param_t *p = (effect_param_t *) pCmdData;
+
+ if (p->psize != sizeof(int32_t)){
+ LOGV("PreProcessingFx_Command cmdCode Case: "
+ "EFFECT_CMD_SET_PARAM: ERROR, psize is not sizeof(int32_t)");
+ return -EINVAL;
+ }
+ if (effect->ops->set_parameter) {
+ *(int *)pReplyData = effect->ops->set_parameter(effect,
+ (void *)p->data,
+ p->data + p->psize);
+ }
+ } break;
+
+ case EFFECT_CMD_ENABLE:
+ if (pReplyData == NULL || *replySize != sizeof(int)){
+ LOGV("PreProcessingFx_Command cmdCode Case: EFFECT_CMD_ENABLE: ERROR");
+ return -EINVAL;
+ }
+ *(int *)pReplyData = Effect_SetState(effect, PREPROC_EFFECT_STATE_ACTIVE);
+ break;
+
+ case EFFECT_CMD_DISABLE:
+ if (pReplyData == NULL || *replySize != sizeof(int)){
+ LOGV("PreProcessingFx_Command cmdCode Case: EFFECT_CMD_DISABLE: ERROR");
+ return -EINVAL;
+ }
+ *(int *)pReplyData = Effect_SetState(effect, PREPROC_EFFECT_STATE_CONFIG);
+ break;
+
+ case EFFECT_CMD_SET_DEVICE:
+ case EFFECT_CMD_SET_INPUT_DEVICE:
+ if (pCmdData == NULL ||
+ cmdSize != sizeof(uint32_t)) {
+ LOGV("PreProcessingFx_Command cmdCode Case: EFFECT_CMD_SET_DEVICE: ERROR");
+ return -EINVAL;
+ }
+
+ if (effect->ops->set_device) {
+ effect->ops->set_device(effect, *(uint32_t *)pCmdData);
+ }
+ break;
+
+ case EFFECT_CMD_SET_VOLUME:
+ case EFFECT_CMD_SET_AUDIO_MODE:
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+
+int PreProcessingFx_GetDescriptor(effect_handle_t self,
+ effect_descriptor_t *pDescriptor)
+{
+ preproc_effect_t * effect = (preproc_effect_t *) self;
+
+ if (effect == NULL || pDescriptor == NULL) {
+ return -EINVAL;
+ }
+
+ memcpy(pDescriptor, sDescriptors[effect->procId], sizeof(effect_descriptor_t));
+
+ return 0;
+}
+
+int PreProcessingFx_ProcessReverse(effect_handle_t self,
+ audio_buffer_t *inBuffer,
+ audio_buffer_t *outBuffer)
+{
+ preproc_effect_t * effect = (preproc_effect_t *)self;
+ int status = 0;
+
+ if (effect == NULL){
+ LOGW("PreProcessingFx_ProcessReverse() ERROR effect == NULL");
+ return -EINVAL;
+ }
+ preproc_session_t * session = (preproc_session_t *)effect->session;
+
+ if (inBuffer == NULL || inBuffer->raw == NULL){
+ LOGW("PreProcessingFx_ProcessReverse() ERROR bad pointer");
+ return -EINVAL;
+ }
+
+ session->revProcessedMsk |= (1<<effect->procId);
+
+// LOGV("PreProcessingFx_ProcessReverse In %d frames revEnabledMsk %08x revProcessedMsk %08x",
+// inBuffer->frameCount, session->revEnabledMsk, session->revProcessedMsk);
+
+
+ if ((session->revProcessedMsk & session->revEnabledMsk) == session->revEnabledMsk) {
+ effect->session->revProcessedMsk = 0;
+ if (session->revResampler != NULL) {
+ size_t fr = session->frameCount - session->framesRev;
+ if (inBuffer->frameCount < fr) {
+ fr = inBuffer->frameCount;
+ }
+ if (session->revBufSize < session->framesRev + fr) {
+ session->revBufSize = session->framesRev + fr;
+ session->revBuf = (int16_t *)realloc(session->revBuf,
+ session->revBufSize * session->inChannelCount * sizeof(int16_t));
+ }
+ memcpy(session->revBuf + session->framesRev * session->inChannelCount,
+ inBuffer->s16,
+ fr * session->inChannelCount * sizeof(int16_t));
+
+ session->framesRev += fr;
+ inBuffer->frameCount = fr;
+ if (session->framesRev < session->frameCount) {
+ return 0;
+ }
+ size_t frIn = session->framesRev;
+ size_t frOut = session->apmFrameCount;
+ if (session->inChannelCount == 1) {
+ speex_resampler_process_int(session->revResampler,
+ 0,
+ session->revBuf,
+ &frIn,
+ session->revFrame->_payloadData,
+ &frOut);
+ } else {
+ speex_resampler_process_interleaved_int(session->revResampler,
+ session->revBuf,
+ &frIn,
+ session->revFrame->_payloadData,
+ &frOut);
+ }
+ memcpy(session->revBuf,
+ session->revBuf + frIn * session->inChannelCount,
+ (session->framesRev - frIn) * session->inChannelCount * sizeof(int16_t));
+ session->framesRev -= frIn;
+ } else {
+ size_t fr = session->frameCount - session->framesRev;
+ if (inBuffer->frameCount < fr) {
+ fr = inBuffer->frameCount;
+ }
+ memcpy(session->revFrame->_payloadData + session->framesRev * session->inChannelCount,
+ inBuffer->s16,
+ fr * session->inChannelCount * sizeof(int16_t));
+ session->framesRev += fr;
+ inBuffer->frameCount = fr;
+ if (session->framesRev < session->frameCount) {
+ return 0;
+ }
+ session->framesRev = 0;
+ }
+ session->revFrame->_payloadDataLengthInSamples =
+ session->apmFrameCount * session->inChannelCount;
+ effect->session->apm->AnalyzeReverseStream(session->revFrame);
+ return 0;
+ } else {
+ return -ENODATA;
+ }
+}
+
+
+// effect_handle_t interface implementation for effect
+const struct effect_interface_s sEffectInterface = {
+ PreProcessingFx_Process,
+ PreProcessingFx_Command,
+ PreProcessingFx_GetDescriptor,
+ NULL
+};
+
+const struct effect_interface_s sEffectInterfaceReverse = {
+ PreProcessingFx_Process,
+ PreProcessingFx_Command,
+ PreProcessingFx_GetDescriptor,
+ PreProcessingFx_ProcessReverse
+};
+
+//------------------------------------------------------------------------------
+// Effect Library Interface Implementation
+//------------------------------------------------------------------------------
+
+int PreProcessingLib_QueryNumberEffects(uint32_t *pNumEffects)
+{
+ if (PreProc_Init() != 0) {
+ return sInitStatus;
+ }
+ if (pNumEffects == NULL) {
+ return -EINVAL;
+ }
+ *pNumEffects = PREPROC_NUM_EFFECTS;
+ return sInitStatus;
+}
+
+int PreProcessingLib_QueryEffect(uint32_t index, effect_descriptor_t *pDescriptor)
+{
+ if (PreProc_Init() != 0) {
+ return sInitStatus;
+ }
+ if (index >= PREPROC_NUM_EFFECTS) {
+ return -EINVAL;
+ }
+ memcpy(pDescriptor, sDescriptors[index], sizeof(effect_descriptor_t));
+ return 0;
+}
+
+int PreProcessingLib_Create(effect_uuid_t *uuid,
+ int32_t sessionId,
+ int32_t ioId,
+ effect_handle_t *pInterface)
+{
+ LOGV("EffectCreate: uuid: %08x session %d IO: %d", uuid->timeLow, sessionId, ioId);
+
+ int status;
+ const effect_descriptor_t *desc;
+ preproc_session_t *session;
+ uint32_t procId;
+
+ if (PreProc_Init() != 0) {
+ return sInitStatus;
+ }
+ desc = PreProc_GetDescriptor(uuid);
+ if (desc == NULL) {
+ LOGW("EffectCreate: fx not found uuid: %08x", uuid->timeLow);
+ return -EINVAL;
+ }
+ procId = UuidToProcId(&desc->type);
+
+ session = PreProc_GetSession(procId, sessionId, ioId);
+ if (session == NULL) {
+ LOGW("EffectCreate: no more session available");
+ return -EINVAL;
+ }
+
+ status = Session_CreateEffect(session, procId, pInterface);
+
+ if (status < 0 && session->createdMsk == 0) {
+ session->io = 0;
+ }
+ return status;
+}
+
+int PreProcessingLib_Release(effect_handle_t interface)
+{
+ int status;
+ LOGV("EffectRelease start %p", interface);
+ if (PreProc_Init() != 0) {
+ return sInitStatus;
+ }
+
+ preproc_effect_t *fx = (preproc_effect_t *)interface;
+
+ if (fx->session->io == 0) {
+ return -EINVAL;
+ }
+ return Session_ReleaseEffect(fx->session, fx);
+}
+
+int PreProcessingLib_GetDescriptor(effect_uuid_t *uuid,
+ effect_descriptor_t *pDescriptor) {
+
+ if (pDescriptor == NULL || uuid == NULL){
+ return -EINVAL;
+ }
+
+ const effect_descriptor_t *desc = PreProc_GetDescriptor(uuid);
+ if (desc == NULL) {
+ LOGV("PreProcessingLib_GetDescriptor() not found");
+ return -EINVAL;
+ }
+
+ LOGV("PreProcessingLib_GetDescriptor() got fx %s", desc->name);
+
+ memcpy(pDescriptor, desc, sizeof(effect_descriptor_t));
+ return 0;
+}
+
+audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
+ tag : AUDIO_EFFECT_LIBRARY_TAG,
+ version : EFFECT_LIBRARY_API_VERSION,
+ name : "Audio Preprocessing Library",
+ implementor : "The Android Open Source Project",
+ query_num_effects : PreProcessingLib_QueryNumberEffects,
+ query_effect : PreProcessingLib_QueryEffect,
+ create_effect : PreProcessingLib_Create,
+ release_effect : PreProcessingLib_Release,
+ get_descriptor : PreProcessingLib_GetDescriptor
+};
+
+}; // extern "C"
diff --git a/media/libeffects/testlibs/Android.mk_ b/media/libeffects/testlibs/Android.mk_
index 9ba71ed..249ebf4 100644
--- a/media/libeffects/testlibs/Android.mk_
+++ b/media/libeffects/testlibs/Android.mk_
@@ -23,9 +23,10 @@
endif
LOCAL_C_INCLUDES := \
+ system/media/audio_effects/include \
$(call include-path-for, graphics corecg)
-LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE_TAGS := optional
include $(BUILD_SHARED_LIBRARY)
@@ -58,9 +59,10 @@
endif
LOCAL_C_INCLUDES := \
- $(call include-path-for, graphics corecg)
+ $(call include-path-for, graphics corecg) \
+ system/media/audio_effects/include
-LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE_TAGS := optional
include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libeffects/testlibs/AudioFormatAdapter.h b/media/libeffects/testlibs/AudioFormatAdapter.h
index d93ebe9..41f1810 100644
--- a/media/libeffects/testlibs/AudioFormatAdapter.h
+++ b/media/libeffects/testlibs/AudioFormatAdapter.h
@@ -18,7 +18,7 @@
#ifndef AUDIOFORMATADAPTER_H_
#define AUDIOFORMATADAPTER_H_
-#include <media/EffectApi.h>
+#include <hardware/audio_effect.h>
#define min(x,y) (((x) < (y)) ? (x) : (y))
@@ -75,7 +75,7 @@
while (numSamples > 0) {
uint32_t numSamplesIter = min(numSamples, mMaxSamplesPerCall);
uint32_t nSamplesChannels = numSamplesIter * mNumChannels;
- if (mPcmFormat == SAMPLE_FORMAT_PCM_S7_24) {
+ if (mPcmFormat == AUDIO_FORMAT_PCM_8_24_BIT) {
if (mBehavior == EFFECT_BUFFER_ACCESS_WRITE) {
mpProcessor->process(
reinterpret_cast<const audio_sample_t *> (pIn),
@@ -125,7 +125,7 @@
// sample.
// numSamples The number of single-channel samples to process.
void ConvertInput(const void *& pIn, uint32_t numSamples) {
- if (mPcmFormat == SAMPLE_FORMAT_PCM_S15) {
+ if (mPcmFormat == AUDIO_FORMAT_PCM_16_BIT) {
const int16_t * pIn16 = reinterpret_cast<const int16_t *>(pIn);
audio_sample_t * pOut = mBuffer;
while (numSamples-- > 0) {
@@ -143,7 +143,7 @@
// When function exist will point to the next output sample.
// numSamples The number of single-channel samples to process.
void ConvertOutput(void *& pOut, uint32_t numSamples) {
- if (mPcmFormat == SAMPLE_FORMAT_PCM_S15) {
+ if (mPcmFormat == AUDIO_FORMAT_PCM_16_BIT) {
const audio_sample_t * pIn = mBuffer;
int16_t * pOut16 = reinterpret_cast<int16_t *>(pOut);
if (mBehavior == EFFECT_BUFFER_ACCESS_WRITE) {
diff --git a/media/libeffects/testlibs/EffectEqualizer.cpp b/media/libeffects/testlibs/EffectEqualizer.cpp
index f8e4357..b22ebec 100644
--- a/media/libeffects/testlibs/EffectEqualizer.cpp
+++ b/media/libeffects/testlibs/EffectEqualizer.cpp
@@ -26,9 +26,10 @@
#include "AudioEqualizer.h"
#include "AudioBiquadFilter.h"
#include "AudioFormatAdapter.h"
-#include <media/EffectEqualizerApi.h>
+#include <audio_effects/effect_equalizer.h>
-// effect_interface_t interface implementation for equalizer effect
+
+// effect_handle_t interface implementation for equalizer effect
extern "C" const struct effect_interface_s gEqualizerInterface;
enum equalizer_state_e {
@@ -44,12 +45,12 @@
const effect_descriptor_t gEqualizerDescriptor = {
{0x0bed4300, 0xddd6, 0x11db, 0x8f34, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // type
{0xe25aa840, 0x543b, 0x11df, 0x98a5, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // uuid
- EFFECT_API_VERSION,
+ EFFECT_CONTROL_API_VERSION,
(EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST),
0, // TODO
1,
"Graphic Equalizer",
- "Google Inc.",
+ "The Android Open Source Project",
};
/////////////////// BEGIN EQ PRESETS ///////////////////////////////////////////
@@ -127,7 +128,8 @@
return 0;
} /* end EffectQueryNumberEffects */
-extern "C" int EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescriptor) {
+extern "C" int EffectQueryEffect(uint32_t index,
+ effect_descriptor_t *pDescriptor) {
if (pDescriptor == NULL) {
return -EINVAL;
}
@@ -139,15 +141,15 @@
} /* end EffectQueryNext */
extern "C" int EffectCreate(effect_uuid_t *uuid,
- int32_t sessionId,
- int32_t ioId,
- effect_interface_t *pInterface) {
+ int32_t sessionId,
+ int32_t ioId,
+ effect_handle_t *pHandle) {
int ret;
int i;
LOGV("EffectLibCreateEffect start");
- if (pInterface == NULL || uuid == NULL) {
+ if (pHandle == NULL || uuid == NULL) {
return -EINVAL;
}
@@ -168,19 +170,20 @@
return ret;
}
- *pInterface = (effect_interface_t)pContext;
+ *pHandle = (effect_handle_t)pContext;
pContext->state = EQUALIZER_STATE_INITIALIZED;
- LOGV("EffectLibCreateEffect %p, size %d", pContext, AudioEqualizer::GetInstanceSize(kNumBands)+sizeof(EqualizerContext));
+ LOGV("EffectLibCreateEffect %p, size %d",
+ pContext, AudioEqualizer::GetInstanceSize(kNumBands)+sizeof(EqualizerContext));
return 0;
} /* end EffectCreate */
-extern "C" int EffectRelease(effect_interface_t interface) {
- EqualizerContext * pContext = (EqualizerContext *)interface;
+extern "C" int EffectRelease(effect_handle_t handle) {
+ EqualizerContext * pContext = (EqualizerContext *)handle;
- LOGV("EffectLibReleaseEffect %p", interface);
+ LOGV("EffectLibReleaseEffect %p", handle);
if (pContext == NULL) {
return -EINVAL;
}
@@ -192,6 +195,22 @@
return 0;
} /* end EffectRelease */
+extern "C" int EffectGetDescriptor(effect_uuid_t *uuid,
+ effect_descriptor_t *pDescriptor) {
+
+ if (pDescriptor == NULL || uuid == NULL){
+ LOGV("EffectGetDescriptor() called with NULL pointer");
+ return -EINVAL;
+ }
+
+ if (memcmp(uuid, &gEqualizerDescriptor.uuid, sizeof(effect_uuid_t)) == 0) {
+ memcpy(pDescriptor, &gEqualizerDescriptor, sizeof(effect_descriptor_t));
+ return 0;
+ }
+
+ return -EINVAL;
+} /* end EffectGetDescriptor */
+
//
//--- local functions
@@ -228,14 +247,15 @@
CHECK_ARG(pConfig->inputCfg.samplingRate == pConfig->outputCfg.samplingRate);
CHECK_ARG(pConfig->inputCfg.channels == pConfig->outputCfg.channels);
CHECK_ARG(pConfig->inputCfg.format == pConfig->outputCfg.format);
- CHECK_ARG((pConfig->inputCfg.channels == CHANNEL_MONO) || (pConfig->inputCfg.channels == CHANNEL_STEREO));
+ CHECK_ARG((pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_MONO) ||
+ (pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_STEREO));
CHECK_ARG(pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_WRITE
|| pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE);
- CHECK_ARG(pConfig->inputCfg.format == SAMPLE_FORMAT_PCM_S7_24
- || pConfig->inputCfg.format == SAMPLE_FORMAT_PCM_S15);
+ CHECK_ARG(pConfig->inputCfg.format == AUDIO_FORMAT_PCM_8_24_BIT
+ || pConfig->inputCfg.format == AUDIO_FORMAT_PCM_16_BIT);
int channelCount;
- if (pConfig->inputCfg.channels == CHANNEL_MONO) {
+ if (pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_MONO) {
channelCount = 1;
} else {
channelCount = 2;
@@ -281,16 +301,16 @@
}
pContext->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
- pContext->config.inputCfg.channels = CHANNEL_STEREO;
- pContext->config.inputCfg.format = SAMPLE_FORMAT_PCM_S15;
+ pContext->config.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
+ pContext->config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
pContext->config.inputCfg.samplingRate = 44100;
pContext->config.inputCfg.bufferProvider.getBuffer = NULL;
pContext->config.inputCfg.bufferProvider.releaseBuffer = NULL;
pContext->config.inputCfg.bufferProvider.cookie = NULL;
pContext->config.inputCfg.mask = EFFECT_CONFIG_ALL;
pContext->config.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE;
- pContext->config.outputCfg.channels = CHANNEL_STEREO;
- pContext->config.outputCfg.format = SAMPLE_FORMAT_PCM_S15;
+ pContext->config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
+ pContext->config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
pContext->config.outputCfg.samplingRate = 44100;
pContext->config.outputCfg.bufferProvider.getBuffer = NULL;
pContext->config.outputCfg.bufferProvider.releaseBuffer = NULL;
@@ -402,7 +422,8 @@
case EQ_PARAM_LEVEL_RANGE:
*(int16_t *)pValue = -9600;
*((int16_t *)pValue + 1) = 4800;
- LOGV("Equalizer_getParameter() EQ_PARAM_LEVEL_RANGE min %d, max %d", *(int32_t *)pValue, *((int32_t *)pValue + 1));
+ LOGV("Equalizer_getParameter() EQ_PARAM_LEVEL_RANGE min %d, max %d",
+ *(int32_t *)pValue, *((int32_t *)pValue + 1));
break;
case EQ_PARAM_BAND_LEVEL:
@@ -412,7 +433,8 @@
break;
}
*(int16_t *)pValue = (int16_t)pEqualizer->getGain(param2);
- LOGV("Equalizer_getParameter() EQ_PARAM_BAND_LEVEL band %d, level %d", param2, *(int32_t *)pValue);
+ LOGV("Equalizer_getParameter() EQ_PARAM_BAND_LEVEL band %d, level %d",
+ param2, *(int32_t *)pValue);
break;
case EQ_PARAM_CENTER_FREQ:
@@ -422,7 +444,8 @@
break;
}
*(int32_t *)pValue = pEqualizer->getFrequency(param2);
- LOGV("Equalizer_getParameter() EQ_PARAM_CENTER_FREQ band %d, frequency %d", param2, *(int32_t *)pValue);
+ LOGV("Equalizer_getParameter() EQ_PARAM_CENTER_FREQ band %d, frequency %d",
+ param2, *(int32_t *)pValue);
break;
case EQ_PARAM_BAND_FREQ_RANGE:
@@ -432,13 +455,15 @@
break;
}
pEqualizer->getBandRange(param2, *(uint32_t *)pValue, *((uint32_t *)pValue + 1));
- LOGV("Equalizer_getParameter() EQ_PARAM_BAND_FREQ_RANGE band %d, min %d, max %d", param2, *(int32_t *)pValue, *((int32_t *)pValue + 1));
+ LOGV("Equalizer_getParameter() EQ_PARAM_BAND_FREQ_RANGE band %d, min %d, max %d",
+ param2, *(int32_t *)pValue, *((int32_t *)pValue + 1));
break;
case EQ_PARAM_GET_BAND:
param2 = *pParam;
*(uint16_t *)pValue = (uint16_t)pEqualizer->getMostRelevantBand(param2);
- LOGV("Equalizer_getParameter() EQ_PARAM_GET_BAND frequency %d, band %d", param2, *(int32_t *)pValue);
+ LOGV("Equalizer_getParameter() EQ_PARAM_GET_BAND frequency %d, band %d",
+ param2, *(int32_t *)pValue);
break;
case EQ_PARAM_CUR_PRESET:
@@ -461,7 +486,8 @@
strncpy(name, pEqualizer->getPresetName(param2), *pValueSize - 1);
name[*pValueSize - 1] = 0;
*pValueSize = strlen(name) + 1;
- LOGV("Equalizer_getParameter() EQ_PARAM_GET_PRESET_NAME preset %d, name %s len %d", param2, gEqualizerPresets[param2].name, *pValueSize);
+ LOGV("Equalizer_getParameter() EQ_PARAM_GET_PRESET_NAME preset %d, name %s len %d",
+ param2, gEqualizerPresets[param2].name, *pValueSize);
break;
case EQ_PARAM_PROPERTIES: {
@@ -571,7 +597,7 @@
//--- Effect Control Interface Implementation
//
-extern "C" int Equalizer_process(effect_interface_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer)
+extern "C" int Equalizer_process(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer)
{
android::EqualizerContext * pContext = (android::EqualizerContext *) self;
@@ -596,7 +622,7 @@
return 0;
} // end Equalizer_process
-extern "C" int Equalizer_command(effect_interface_t self, uint32_t cmdCode, uint32_t cmdSize,
+extern "C" int Equalizer_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize,
void *pCmdData, uint32_t *replySize, void *pReplyData) {
android::EqualizerContext * pContext = (android::EqualizerContext *) self;
@@ -647,7 +673,8 @@
} break;
case EFFECT_CMD_SET_PARAM: {
- LOGV("Equalizer_command EFFECT_CMD_SET_PARAM cmdSize %d pCmdData %p, *replySize %d, pReplyData %p", cmdSize, pCmdData, *replySize, pReplyData);
+ LOGV("Equalizer_command EFFECT_CMD_SET_PARAM cmdSize %d pCmdData %p, *replySize %d, pReplyData %p",
+ cmdSize, pCmdData, *replySize, pReplyData);
if (pCmdData == NULL || cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) ||
pReplyData == NULL || *replySize != sizeof(int32_t)) {
return -EINVAL;
@@ -690,10 +717,38 @@
return 0;
}
-// effect_interface_t interface implementation for equalizer effect
+extern "C" int Equalizer_getDescriptor(effect_handle_t self,
+ effect_descriptor_t *pDescriptor)
+{
+ android::EqualizerContext * pContext = (android::EqualizerContext *) self;
+
+ if (pContext == NULL || pDescriptor == NULL) {
+ LOGV("Equalizer_getDescriptor() invalid param");
+ return -EINVAL;
+ }
+
+ memcpy(pDescriptor, &android::gEqualizerDescriptor, sizeof(effect_descriptor_t));
+
+ return 0;
+}
+
+// effect_handle_t interface implementation for equalizer effect
const struct effect_interface_s gEqualizerInterface = {
Equalizer_process,
- Equalizer_command
+ Equalizer_command,
+ Equalizer_getDescriptor,
+ NULL
};
+audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
+ tag : AUDIO_EFFECT_LIBRARY_TAG,
+ version : EFFECT_LIBRARY_API_VERSION,
+ name : "Test Equalizer Library",
+ implementor : "The Android Open Source Project",
+ query_num_effects : android::EffectQueryNumberEffects,
+ query_effect : android::EffectQueryEffect,
+ create_effect : android::EffectCreate,
+ release_effect : android::EffectRelease,
+ get_descriptor : android::EffectGetDescriptor,
+};
diff --git a/media/libeffects/testlibs/EffectReverb.c b/media/libeffects/testlibs/EffectReverb.c
index 3eb8b2c..405f908 100644
--- a/media/libeffects/testlibs/EffectReverb.c
+++ b/media/libeffects/testlibs/EffectReverb.c
@@ -23,59 +23,61 @@
#include "EffectReverb.h"
#include "EffectsMath.h"
-// effect_interface_t interface implementation for reverb effect
+// effect_handle_t interface implementation for reverb effect
const struct effect_interface_s gReverbInterface = {
Reverb_Process,
- Reverb_Command
+ Reverb_Command,
+ Reverb_GetDescriptor,
+ NULL
};
// Google auxiliary environmental reverb UUID: 1f0ae2e0-4ef7-11df-bc09-0002a5d5c51b
static const effect_descriptor_t gAuxEnvReverbDescriptor = {
{0xc2e5d5f0, 0x94bd, 0x4763, 0x9cac, {0x4e, 0x23, 0x4d, 0x06, 0x83, 0x9e}},
{0x1f0ae2e0, 0x4ef7, 0x11df, 0xbc09, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
- EFFECT_API_VERSION,
+ EFFECT_CONTROL_API_VERSION,
// flags other than EFFECT_FLAG_TYPE_AUXILIARY set for test purpose
EFFECT_FLAG_TYPE_AUXILIARY | EFFECT_FLAG_DEVICE_IND | EFFECT_FLAG_AUDIO_MODE_IND,
0, // TODO
33,
"Aux Environmental Reverb",
- "Google Inc."
+ "The Android Open Source Project"
};
// Google insert environmental reverb UUID: aa476040-6342-11df-91a4-0002a5d5c51b
static const effect_descriptor_t gInsertEnvReverbDescriptor = {
{0xc2e5d5f0, 0x94bd, 0x4763, 0x9cac, {0x4e, 0x23, 0x4d, 0x06, 0x83, 0x9e}},
{0xaa476040, 0x6342, 0x11df, 0x91a4, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
- EFFECT_API_VERSION,
+ EFFECT_CONTROL_API_VERSION,
EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_FIRST,
0, // TODO
33,
"Insert Environmental reverb",
- "Google Inc."
+ "The Android Open Source Project"
};
// Google auxiliary preset reverb UUID: 63909320-53a6-11df-bdbd-0002a5d5c51b
static const effect_descriptor_t gAuxPresetReverbDescriptor = {
{0x47382d60, 0xddd8, 0x11db, 0xbf3a, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
{0x63909320, 0x53a6, 0x11df, 0xbdbd, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
- EFFECT_API_VERSION,
+ EFFECT_CONTROL_API_VERSION,
EFFECT_FLAG_TYPE_AUXILIARY,
0, // TODO
33,
"Aux Preset Reverb",
- "Google Inc."
+ "The Android Open Source Project"
};
// Google insert preset reverb UUID: d93dc6a0-6342-11df-b128-0002a5d5c51b
static const effect_descriptor_t gInsertPresetReverbDescriptor = {
{0x47382d60, 0xddd8, 0x11db, 0xbf3a, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
{0xd93dc6a0, 0x6342, 0x11df, 0xb128, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
- EFFECT_API_VERSION,
+ EFFECT_CONTROL_API_VERSION,
EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_FIRST,
0, // TODO
33,
"Insert Preset Reverb",
- "Google Inc."
+ "The Android Open Source Project"
};
// gDescriptors contains pointers to all defined effect descriptor in this library
@@ -112,7 +114,7 @@
int EffectCreate(effect_uuid_t *uuid,
int32_t sessionId,
int32_t ioId,
- effect_interface_t *pInterface) {
+ effect_handle_t *pHandle) {
int ret;
int i;
reverb_module_t *module;
@@ -122,7 +124,7 @@
LOGV("EffectLibCreateEffect start");
- if (pInterface == NULL || uuid == NULL) {
+ if (pHandle == NULL || uuid == NULL) {
return -EINVAL;
}
@@ -157,7 +159,7 @@
return ret;
}
- *pInterface = (effect_interface_t) module;
+ *pHandle = (effect_handle_t) module;
module->context.mState = REVERB_STATE_INITIALIZED;
@@ -166,11 +168,11 @@
return 0;
}
-int EffectRelease(effect_interface_t interface) {
- reverb_module_t *pRvbModule = (reverb_module_t *)interface;
+int EffectRelease(effect_handle_t handle) {
+ reverb_module_t *pRvbModule = (reverb_module_t *)handle;
- LOGV("EffectLibReleaseEffect %p", interface);
- if (interface == NULL) {
+ LOGV("EffectLibReleaseEffect %p", handle);
+ if (handle == NULL) {
return -EINVAL;
}
@@ -180,10 +182,31 @@
return 0;
}
+int EffectGetDescriptor(effect_uuid_t *uuid,
+ effect_descriptor_t *pDescriptor) {
+ int i;
+ int length = sizeof(gDescriptors) / sizeof(const effect_descriptor_t *);
+
+ if (pDescriptor == NULL || uuid == NULL){
+ LOGV("EffectGetDescriptor() called with NULL pointer");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < length; i++) {
+ if (memcmp(uuid, &gDescriptors[i]->uuid, sizeof(effect_uuid_t)) == 0) {
+ memcpy(pDescriptor, gDescriptors[i], sizeof(effect_descriptor_t));
+ LOGV("EffectGetDescriptor - UUID matched Reverb type %d, UUID = %x",
+ i, gDescriptors[i]->uuid.timeLow);
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+} /* end EffectGetDescriptor */
/*--- Effect Control Interface Implementation ---*/
-static int Reverb_Process(effect_interface_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer) {
+static int Reverb_Process(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer) {
reverb_object_t *pReverb;
int16_t *pSrc, *pDst;
reverb_module_t *pRvbModule = (reverb_module_t *)self;
@@ -270,7 +293,7 @@
}
-static int Reverb_Command(effect_interface_t self, uint32_t cmdCode, uint32_t cmdSize,
+static int Reverb_Command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize,
void *pCmdData, uint32_t *replySize, void *pReplyData) {
reverb_module_t *pRvbModule = (reverb_module_t *) self;
reverb_object_t *pReverb;
@@ -383,6 +406,38 @@
return 0;
}
+int Reverb_GetDescriptor(effect_handle_t self,
+ effect_descriptor_t *pDescriptor)
+{
+ reverb_module_t *pRvbModule = (reverb_module_t *) self;
+ reverb_object_t *pReverb;
+ const effect_descriptor_t *desc;
+
+ if (pRvbModule == NULL ||
+ pRvbModule->context.mState == REVERB_STATE_UNINITIALIZED) {
+ return -EINVAL;
+ }
+
+ pReverb = (reverb_object_t*) &pRvbModule->context;
+
+ if (pReverb->m_Aux) {
+ if (pReverb->m_Preset) {
+ desc = &gAuxPresetReverbDescriptor;
+ } else {
+ desc = &gAuxEnvReverbDescriptor;
+ }
+ } else {
+ if (pReverb->m_Preset) {
+ desc = &gInsertPresetReverbDescriptor;
+ } else {
+ desc = &gInsertEnvReverbDescriptor;
+ }
+ }
+
+ memcpy(pDescriptor, desc, sizeof(effect_descriptor_t));
+
+ return 0;
+} /* end Reverb_getDescriptor */
/*----------------------------------------------------------------------------
* Reverb internal functions
@@ -418,19 +473,19 @@
pRvbModule->config.inputCfg.samplingRate = 44100;
if (aux) {
- pRvbModule->config.inputCfg.channels = CHANNEL_MONO;
+ pRvbModule->config.inputCfg.channels = AUDIO_CHANNEL_OUT_MONO;
} else {
- pRvbModule->config.inputCfg.channels = CHANNEL_STEREO;
+ pRvbModule->config.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
}
- pRvbModule->config.inputCfg.format = SAMPLE_FORMAT_PCM_S15;
+ pRvbModule->config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
pRvbModule->config.inputCfg.bufferProvider.getBuffer = NULL;
pRvbModule->config.inputCfg.bufferProvider.releaseBuffer = NULL;
pRvbModule->config.inputCfg.bufferProvider.cookie = NULL;
pRvbModule->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
pRvbModule->config.inputCfg.mask = EFFECT_CONFIG_ALL;
pRvbModule->config.outputCfg.samplingRate = 44100;
- pRvbModule->config.outputCfg.channels = CHANNEL_STEREO;
- pRvbModule->config.outputCfg.format = SAMPLE_FORMAT_PCM_S15;
+ pRvbModule->config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
+ pRvbModule->config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
pRvbModule->config.outputCfg.bufferProvider.getBuffer = NULL;
pRvbModule->config.outputCfg.bufferProvider.releaseBuffer = NULL;
pRvbModule->config.outputCfg.bufferProvider.cookie = NULL;
@@ -474,13 +529,13 @@
if (pConfig->inputCfg.samplingRate
!= pConfig->outputCfg.samplingRate
|| pConfig->outputCfg.channels != OUTPUT_CHANNELS
- || pConfig->inputCfg.format != SAMPLE_FORMAT_PCM_S15
- || pConfig->outputCfg.format != SAMPLE_FORMAT_PCM_S15) {
+ || pConfig->inputCfg.format != AUDIO_FORMAT_PCM_16_BIT
+ || pConfig->outputCfg.format != AUDIO_FORMAT_PCM_16_BIT) {
LOGV("Reverb_Configure invalid config");
return -EINVAL;
}
- if ((pReverb->m_Aux && (pConfig->inputCfg.channels != CHANNEL_MONO)) ||
- (!pReverb->m_Aux && (pConfig->inputCfg.channels != CHANNEL_STEREO))) {
+ if ((pReverb->m_Aux && (pConfig->inputCfg.channels != AUDIO_CHANNEL_OUT_MONO)) ||
+ (!pReverb->m_Aux && (pConfig->inputCfg.channels != AUDIO_CHANNEL_OUT_STEREO))) {
LOGV("Reverb_Configure invalid config");
return -EINVAL;
}
@@ -2133,3 +2188,15 @@
return 0;
}
+
+audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
+ .tag = AUDIO_EFFECT_LIBRARY_TAG,
+ .version = EFFECT_LIBRARY_API_VERSION,
+ .name = "Test Equalizer Library",
+ .implementor = "The Android Open Source Project",
+ .query_num_effects = EffectQueryNumberEffects,
+ .query_effect = EffectQueryEffect,
+ .create_effect = EffectCreate,
+ .release_effect = EffectRelease,
+ .get_descriptor = EffectGetDescriptor,
+};
diff --git a/media/libeffects/testlibs/EffectReverb.h b/media/libeffects/testlibs/EffectReverb.h
index dbcd192..8e2cc31 100644
--- a/media/libeffects/testlibs/EffectReverb.h
+++ b/media/libeffects/testlibs/EffectReverb.h
@@ -17,8 +17,8 @@
#ifndef ANDROID_EFFECTREVERB_H_
#define ANDROID_EFFECTREVERB_H_
-#include <media/EffectEnvironmentalReverbApi.h>
-#include <media/EffectPresetReverbApi.h>
+#include <audio_effects/effect_environmentalreverb.h>
+#include <audio_effects/effect_presetreverb.h>
/*------------------------------------
@@ -40,7 +40,7 @@
)
#define NUM_OUTPUT_CHANNELS 2
-#define OUTPUT_CHANNELS CHANNEL_STEREO
+#define OUTPUT_CHANNELS AUDIO_CHANNEL_OUT_STEREO
#define REVERB_BUFFER_SIZE_IN_SAMPLES_MAX 16384
@@ -306,19 +306,22 @@
int EffectCreate(effect_uuid_t *effectUID,
int32_t sessionId,
int32_t ioId,
- effect_interface_t *pInterface);
-int EffectRelease(effect_interface_t interface);
+ effect_handle_t *pHandle);
+int EffectRelease(effect_handle_t handle);
+int EffectGetDescriptor(effect_uuid_t *uuid,
+ effect_descriptor_t *pDescriptor);
-static int Reverb_Process(effect_interface_t self,
+static int Reverb_Process(effect_handle_t self,
audio_buffer_t *inBuffer,
audio_buffer_t *outBuffer);
-static int Reverb_Command(effect_interface_t self,
+static int Reverb_Command(effect_handle_t self,
uint32_t cmdCode,
uint32_t cmdSize,
void *pCmdData,
uint32_t *replySize,
void *pReplyData);
-
+static int Reverb_GetDescriptor(effect_handle_t self,
+ effect_descriptor_t *pDescriptor);
/*------------------------------------
* internal functions
diff --git a/media/libeffects/visualizer/Android.mk b/media/libeffects/visualizer/Android.mk
index e6ff654..2160177 100644
--- a/media/libeffects/visualizer/Android.mk
+++ b/media/libeffects/visualizer/Android.mk
@@ -9,22 +9,15 @@
LOCAL_CFLAGS+= -O2
LOCAL_SHARED_LIBRARIES := \
- libcutils
+ libcutils \
+ libdl
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx
LOCAL_MODULE:= libvisualizer
-ifeq ($(TARGET_OS)-$(TARGET_SIMULATOR),linux-true)
-LOCAL_LDLIBS += -ldl
-endif
-
-ifneq ($(TARGET_SIMULATOR),true)
-LOCAL_SHARED_LIBRARIES += libdl
-endif
-
LOCAL_C_INCLUDES := \
- $(call include-path-for, graphics corecg)
+ $(call include-path-for, graphics corecg) \
+ system/media/audio_effects/include
-LOCAL_PRELINK_MODULE := false
include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libeffects/visualizer/EffectVisualizer.cpp b/media/libeffects/visualizer/EffectVisualizer.cpp
index c957dba..3c3af8f 100644
--- a/media/libeffects/visualizer/EffectVisualizer.cpp
+++ b/media/libeffects/visualizer/EffectVisualizer.cpp
@@ -21,23 +21,24 @@
#include <stdlib.h>
#include <string.h>
#include <new>
-#include <media/EffectVisualizerApi.h>
+#include <audio_effects/effect_visualizer.h>
-namespace android {
-// effect_interface_t interface implementation for visualizer effect
-extern "C" const struct effect_interface_s gVisualizerInterface;
+extern "C" {
+
+// effect_handle_t interface implementation for visualizer effect
+extern const struct effect_interface_s gVisualizerInterface;
// Google Visualizer UUID: d069d9e0-8329-11df-9168-0002a5d5c51b
const effect_descriptor_t gVisualizerDescriptor = {
{0xe46b26a0, 0xdddd, 0x11db, 0x8afd, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // type
{0xd069d9e0, 0x8329, 0x11df, 0x9168, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // uuid
- EFFECT_API_VERSION,
+ EFFECT_CONTROL_API_VERSION,
(EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_FIRST),
0, // TODO
1,
"Visualizer",
- "Google Inc.",
+ "The Android Open Source Project",
};
enum visualizer_state_e {
@@ -90,10 +91,10 @@
if (pConfig->inputCfg.samplingRate != pConfig->outputCfg.samplingRate) return -EINVAL;
if (pConfig->inputCfg.channels != pConfig->outputCfg.channels) return -EINVAL;
if (pConfig->inputCfg.format != pConfig->outputCfg.format) return -EINVAL;
- if (pConfig->inputCfg.channels != CHANNEL_STEREO) return -EINVAL;
+ if (pConfig->inputCfg.channels != AUDIO_CHANNEL_OUT_STEREO) return -EINVAL;
if (pConfig->outputCfg.accessMode != EFFECT_BUFFER_ACCESS_WRITE &&
pConfig->outputCfg.accessMode != EFFECT_BUFFER_ACCESS_ACCUMULATE) return -EINVAL;
- if (pConfig->inputCfg.format != SAMPLE_FORMAT_PCM_S15) return -EINVAL;
+ if (pConfig->inputCfg.format != AUDIO_FORMAT_PCM_16_BIT) return -EINVAL;
memcpy(&pContext->mConfig, pConfig, sizeof(effect_config_t));
@@ -118,16 +119,16 @@
int Visualizer_init(VisualizerContext *pContext)
{
pContext->mConfig.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
- pContext->mConfig.inputCfg.channels = CHANNEL_STEREO;
- pContext->mConfig.inputCfg.format = SAMPLE_FORMAT_PCM_S15;
+ pContext->mConfig.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
+ pContext->mConfig.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
pContext->mConfig.inputCfg.samplingRate = 44100;
pContext->mConfig.inputCfg.bufferProvider.getBuffer = NULL;
pContext->mConfig.inputCfg.bufferProvider.releaseBuffer = NULL;
pContext->mConfig.inputCfg.bufferProvider.cookie = NULL;
pContext->mConfig.inputCfg.mask = EFFECT_CONFIG_ALL;
pContext->mConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE;
- pContext->mConfig.outputCfg.channels = CHANNEL_STEREO;
- pContext->mConfig.outputCfg.format = SAMPLE_FORMAT_PCM_S15;
+ pContext->mConfig.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
+ pContext->mConfig.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
pContext->mConfig.outputCfg.samplingRate = 44100;
pContext->mConfig.outputCfg.bufferProvider.getBuffer = NULL;
pContext->mConfig.outputCfg.bufferProvider.releaseBuffer = NULL;
@@ -145,12 +146,13 @@
//--- Effect Library Interface Implementation
//
-extern "C" int EffectQueryNumberEffects(uint32_t *pNumEffects) {
+int VisualizerLib_QueryNumberEffects(uint32_t *pNumEffects) {
*pNumEffects = 1;
return 0;
}
-extern "C" int EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescriptor) {
+int VisualizerLib_QueryEffect(uint32_t index,
+ effect_descriptor_t *pDescriptor) {
if (pDescriptor == NULL) {
return -EINVAL;
}
@@ -161,14 +163,14 @@
return 0;
}
-extern "C" int EffectCreate(effect_uuid_t *uuid,
- int32_t sessionId,
- int32_t ioId,
- effect_interface_t *pInterface) {
+int VisualizerLib_Create(effect_uuid_t *uuid,
+ int32_t sessionId,
+ int32_t ioId,
+ effect_handle_t *pHandle) {
int ret;
int i;
- if (pInterface == NULL || uuid == NULL) {
+ if (pHandle == NULL || uuid == NULL) {
return -EINVAL;
}
@@ -183,25 +185,25 @@
ret = Visualizer_init(pContext);
if (ret < 0) {
- LOGW("EffectCreate() init failed");
+ LOGW("VisualizerLib_Create() init failed");
delete pContext;
return ret;
}
- *pInterface = (effect_interface_t)pContext;
+ *pHandle = (effect_handle_t)pContext;
pContext->mState = VISUALIZER_STATE_INITIALIZED;
- LOGV("EffectCreate %p", pContext);
+ LOGV("VisualizerLib_Create %p", pContext);
return 0;
}
-extern "C" int EffectRelease(effect_interface_t interface) {
- VisualizerContext * pContext = (VisualizerContext *)interface;
+int VisualizerLib_Release(effect_handle_t handle) {
+ VisualizerContext * pContext = (VisualizerContext *)handle;
- LOGV("EffectRelease %p", interface);
+ LOGV("VisualizerLib_Release %p", handle);
if (pContext == NULL) {
return -EINVAL;
}
@@ -211,6 +213,22 @@
return 0;
}
+int VisualizerLib_GetDescriptor(effect_uuid_t *uuid,
+ effect_descriptor_t *pDescriptor) {
+
+ if (pDescriptor == NULL || uuid == NULL){
+ LOGV("VisualizerLib_GetDescriptor() called with NULL pointer");
+ return -EINVAL;
+ }
+
+ if (memcmp(uuid, &gVisualizerDescriptor.uuid, sizeof(effect_uuid_t)) == 0) {
+ memcpy(pDescriptor, &gVisualizerDescriptor, sizeof(effect_descriptor_t));
+ return 0;
+ }
+
+ return -EINVAL;
+} /* end VisualizerLib_GetDescriptor */
+
//
//--- Effect Control Interface Implementation
//
@@ -222,10 +240,10 @@
return sample;
}
-extern "C" int Visualizer_process(
- effect_interface_t self,audio_buffer_t *inBuffer, audio_buffer_t *outBuffer)
+int Visualizer_process(
+ effect_handle_t self,audio_buffer_t *inBuffer, audio_buffer_t *outBuffer)
{
- android::VisualizerContext * pContext = (android::VisualizerContext *)self;
+ VisualizerContext * pContext = (VisualizerContext *)self;
if (pContext == NULL) {
return -EINVAL;
@@ -244,7 +262,7 @@
// this gives more interesting captures for display.
int32_t shift = 32;
int len = inBuffer->frameCount * 2;
- for (size_t i = 0; i < len; i++) {
+ for (int i = 0; i < len; i++) {
int32_t smp = inBuffer->s16[i];
if (smp < 0) smp = -smp - 1; // take care to keep the max negative in range
int32_t clz = __builtin_clz(smp);
@@ -293,10 +311,10 @@
return 0;
} // end Visualizer_process
-extern "C" int Visualizer_command(effect_interface_t self, uint32_t cmdCode, uint32_t cmdSize,
+int Visualizer_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize,
void *pCmdData, uint32_t *replySize, void *pReplyData) {
- android::VisualizerContext * pContext = (android::VisualizerContext *)self;
+ VisualizerContext * pContext = (VisualizerContext *)self;
int retsize;
if (pContext == NULL || pContext->mState == VISUALIZER_STATE_UNINITIALIZED) {
@@ -357,7 +375,7 @@
p->status = 0;
*replySize = sizeof(effect_param_t) + sizeof(uint32_t);
if (p->psize != sizeof(uint32_t) ||
- *(uint32_t *)p->data != VISU_PARAM_CAPTURE_SIZE) {
+ *(uint32_t *)p->data != VISUALIZER_PARAM_CAPTURE_SIZE) {
p->status = -EINVAL;
break;
}
@@ -376,7 +394,7 @@
effect_param_t *p = (effect_param_t *)pCmdData;
if (p->psize != sizeof(uint32_t) ||
p->vsize != sizeof(uint32_t) ||
- *(uint32_t *)p->data != VISU_PARAM_CAPTURE_SIZE) {
+ *(uint32_t *)p->data != VISUALIZER_PARAM_CAPTURE_SIZE) {
*(int32_t *)pReplyData = -EINVAL;
break;;
}
@@ -389,9 +407,9 @@
break;
- case VISU_CMD_CAPTURE:
+ case VISUALIZER_CMD_CAPTURE:
if (pReplyData == NULL || *replySize != pContext->mCaptureSize) {
- LOGV("VISU_CMD_CAPTURE() error *replySize %d pContext->mCaptureSize %d",
+ LOGV("VISUALIZER_CMD_CAPTURE() error *replySize %d pContext->mCaptureSize %d",
*replySize, pContext->mCaptureSize);
return -EINVAL;
}
@@ -412,11 +430,41 @@
return 0;
}
-// effect_interface_t interface implementation for visualizer effect
+/* Effect Control Interface Implementation: get_descriptor */
+int Visualizer_getDescriptor(effect_handle_t self,
+ effect_descriptor_t *pDescriptor)
+{
+ VisualizerContext * pContext = (VisualizerContext *) self;
+
+ if (pContext == NULL || pDescriptor == NULL) {
+ LOGV("Visualizer_getDescriptor() invalid param");
+ return -EINVAL;
+ }
+
+ memcpy(pDescriptor, &gVisualizerDescriptor, sizeof(effect_descriptor_t));
+
+ return 0;
+} /* end Visualizer_getDescriptor */
+
+// effect_handle_t interface implementation for visualizer effect
const struct effect_interface_s gVisualizerInterface = {
Visualizer_process,
- Visualizer_command
+ Visualizer_command,
+ Visualizer_getDescriptor,
+ NULL,
};
-} // namespace
+audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
+ tag : AUDIO_EFFECT_LIBRARY_TAG,
+ version : EFFECT_LIBRARY_API_VERSION,
+ name : "Visualizer Library",
+ implementor : "The Android Open Source Project",
+ query_num_effects : VisualizerLib_QueryNumberEffects,
+ query_effect : VisualizerLib_QueryEffect,
+ create_effect : VisualizerLib_Create,
+ release_effect : VisualizerLib_Release,
+ get_descriptor : VisualizerLib_GetDescriptor,
+};
+
+}; // extern "C"
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index fd4c6c6..7af4a87 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -1,4 +1,14 @@
LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ AudioParameter.cpp
+LOCAL_MODULE:= libmedia_helper
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_STATIC_LIBRARY)
+
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
@@ -33,28 +43,24 @@
IEffectClient.cpp \
AudioEffect.cpp \
Visualizer.cpp \
+ MemoryLeakTrackUtil.cpp \
fixedfft.cpp.arm
LOCAL_SHARED_LIBRARIES := \
libui libcutils libutils libbinder libsonivox libicuuc libexpat \
- libsurfaceflinger_client libcamera_client libstagefright_foundation \
- libgui
+ libcamera_client libstagefright_foundation \
+ libgui libdl
+
+LOCAL_WHOLE_STATIC_LIBRARY := libmedia_helper
LOCAL_MODULE:= libmedia
-ifeq ($(TARGET_OS)-$(TARGET_SIMULATOR),linux-true)
-LOCAL_LDLIBS += -ldl -lpthread
-endif
-
-ifneq ($(TARGET_SIMULATOR),true)
-LOCAL_SHARED_LIBRARIES += libdl
-endif
-
LOCAL_C_INCLUDES := \
$(JNI_H_INCLUDE) \
$(call include-path-for, graphics corecg) \
$(TOP)/frameworks/base/include/media/stagefright/openmax \
external/icu4c/common \
- external/expat/lib
+ external/expat/lib \
+ system/media/audio_effects/include
include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libmedia/AudioEffect.cpp b/media/libmedia/AudioEffect.cpp
index aadeba5..0633744 100644
--- a/media/libmedia/AudioEffect.cpp
+++ b/media/libmedia/AudioEffect.cpp
@@ -47,11 +47,11 @@
effect_callback_t cbf,
void* user,
int sessionId,
- audio_io_handle_t output
+ audio_io_handle_t io
)
: mStatus(NO_INIT)
{
- mStatus = set(type, uuid, priority, cbf, user, sessionId, output);
+ mStatus = set(type, uuid, priority, cbf, user, sessionId, io);
}
AudioEffect::AudioEffect(const char *typeStr,
@@ -60,7 +60,7 @@
effect_callback_t cbf,
void* user,
int sessionId,
- audio_io_handle_t output
+ audio_io_handle_t io
)
: mStatus(NO_INIT)
{
@@ -83,7 +83,7 @@
}
}
- mStatus = set(pType, pUuid, priority, cbf, user, sessionId, output);
+ mStatus = set(pType, pUuid, priority, cbf, user, sessionId, io);
}
status_t AudioEffect::set(const effect_uuid_t *type,
@@ -92,13 +92,13 @@
effect_callback_t cbf,
void* user,
int sessionId,
- audio_io_handle_t output)
+ audio_io_handle_t io)
{
sp<IEffect> iEffect;
sp<IMemory> cblk;
int enabled;
- LOGV("set %p mUserData: %p", this, user);
+ LOGV("set %p mUserData: %p uuid: %p timeLow %08x", this, user, type, type ? type->timeLow : 0);
if (mIEffect != 0) {
LOGW("Effect already in use");
@@ -135,7 +135,7 @@
mIEffectClient = new EffectClient(this);
iEffect = audioFlinger->createEffect(getpid(), (effect_descriptor_t *)&mDescriptor,
- mIEffectClient, priority, output, mSessionId, &mStatus, &mId, &enabled);
+ mIEffectClient, priority, io, mSessionId, &mStatus, &mId, &enabled);
if (iEffect == 0 || (mStatus != NO_ERROR && mStatus != ALREADY_EXISTS)) {
LOGE("set(): AudioFlinger could not create effect, status: %d", mStatus);
@@ -170,7 +170,6 @@
LOGV("Destructor %p", this);
if (mStatus == NO_ERROR || mStatus == ALREADY_EXISTS) {
- setEnabled(false);
if (mIEffect != NULL) {
mIEffect->disconnect();
mIEffect->asBinder()->unlinkToDeath(mIEffectClient);
@@ -399,20 +398,6 @@
// -------------------------------------------------------------------------
-status_t AudioEffect::loadEffectLibrary(const char *libPath, int *handle)
-{
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
- if (af == 0) return PERMISSION_DENIED;
- return af->loadEffectLibrary(libPath, handle);
-}
-
-status_t AudioEffect::unloadEffectLibrary(int handle)
-{
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
- if (af == 0) return PERMISSION_DENIED;
- return af->unloadEffectLibrary(handle);
-}
-
status_t AudioEffect::queryNumberEffects(uint32_t *numEffects)
{
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
@@ -434,6 +419,15 @@
return af->getEffectDescriptor(uuid, descriptor);
}
+
+status_t AudioEffect::queryDefaultPreProcessing(int audioSession,
+ effect_descriptor_t *descriptors,
+ uint32_t *count)
+{
+ const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ if (aps == 0) return PERMISSION_DENIED;
+ return aps->queryDefaultPreProcessing(audioSession, descriptors, count);
+}
// -------------------------------------------------------------------------
status_t AudioEffect::stringToGuid(const char *str, effect_uuid_t *guid)
diff --git a/media/libmedia/AudioParameter.cpp b/media/libmedia/AudioParameter.cpp
new file mode 100644
index 0000000..59ccfd0
--- /dev/null
+++ b/media/libmedia/AudioParameter.cpp
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2006-2011 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_TAG "AudioParameter"
+//#define LOG_NDEBUG 0
+
+#include <utils/Log.h>
+
+#include <media/AudioParameter.h>
+
+namespace android {
+
+const char *AudioParameter::keyRouting = "routing";
+const char *AudioParameter::keySamplingRate = "sampling_rate";
+const char *AudioParameter::keyFormat = "format";
+const char *AudioParameter::keyChannels = "channels";
+const char *AudioParameter::keyFrameCount = "frame_count";
+const char *AudioParameter::keyInputSource = "input_source";
+
+AudioParameter::AudioParameter(const String8& keyValuePairs)
+{
+ char *str = new char[keyValuePairs.length()+1];
+ mKeyValuePairs = keyValuePairs;
+
+ strcpy(str, keyValuePairs.string());
+ char *pair = strtok(str, ";");
+ while (pair != NULL) {
+ if (strlen(pair) != 0) {
+ size_t eqIdx = strcspn(pair, "=");
+ String8 key = String8(pair, eqIdx);
+ String8 value;
+ if (eqIdx == strlen(pair)) {
+ value = String8("");
+ } else {
+ value = String8(pair + eqIdx + 1);
+ }
+ if (mParameters.indexOfKey(key) < 0) {
+ mParameters.add(key, value);
+ } else {
+ mParameters.replaceValueFor(key, value);
+ }
+ } else {
+ LOGV("AudioParameter() cstor empty key value pair");
+ }
+ pair = strtok(NULL, ";");
+ }
+
+ delete[] str;
+}
+
+AudioParameter::~AudioParameter()
+{
+ mParameters.clear();
+}
+
+String8 AudioParameter::toString()
+{
+ String8 str = String8("");
+
+ size_t size = mParameters.size();
+ for (size_t i = 0; i < size; i++) {
+ str += mParameters.keyAt(i);
+ str += "=";
+ str += mParameters.valueAt(i);
+ if (i < (size - 1)) str += ";";
+ }
+ return str;
+}
+
+status_t AudioParameter::add(const String8& key, const String8& value)
+{
+ if (mParameters.indexOfKey(key) < 0) {
+ mParameters.add(key, value);
+ return NO_ERROR;
+ } else {
+ mParameters.replaceValueFor(key, value);
+ return ALREADY_EXISTS;
+ }
+}
+
+status_t AudioParameter::addInt(const String8& key, const int value)
+{
+ char str[12];
+ if (snprintf(str, 12, "%d", value) > 0) {
+ String8 str8 = String8(str);
+ return add(key, str8);
+ } else {
+ return BAD_VALUE;
+ }
+}
+
+status_t AudioParameter::addFloat(const String8& key, const float value)
+{
+ char str[23];
+ if (snprintf(str, 23, "%.10f", value) > 0) {
+ String8 str8 = String8(str);
+ return add(key, str8);
+ } else {
+ return BAD_VALUE;
+ }
+}
+
+status_t AudioParameter::remove(const String8& key)
+{
+ if (mParameters.indexOfKey(key) >= 0) {
+ mParameters.removeItem(key);
+ return NO_ERROR;
+ } else {
+ return BAD_VALUE;
+ }
+}
+
+status_t AudioParameter::get(const String8& key, String8& value)
+{
+ if (mParameters.indexOfKey(key) >= 0) {
+ value = mParameters.valueFor(key);
+ return NO_ERROR;
+ } else {
+ return BAD_VALUE;
+ }
+}
+
+status_t AudioParameter::getInt(const String8& key, int& value)
+{
+ String8 str8;
+ status_t result = get(key, str8);
+ value = 0;
+ if (result == NO_ERROR) {
+ int val;
+ if (sscanf(str8.string(), "%d", &val) == 1) {
+ value = val;
+ } else {
+ result = INVALID_OPERATION;
+ }
+ }
+ return result;
+}
+
+status_t AudioParameter::getFloat(const String8& key, float& value)
+{
+ String8 str8;
+ status_t result = get(key, str8);
+ value = 0;
+ if (result == NO_ERROR) {
+ float val;
+ if (sscanf(str8.string(), "%f", &val) == 1) {
+ value = val;
+ } else {
+ result = INVALID_OPERATION;
+ }
+ }
+ return result;
+}
+
+status_t AudioParameter::getAt(size_t index, String8& key, String8& value)
+{
+ if (mParameters.size() > index) {
+ key = mParameters.keyAt(index);
+ value = mParameters.valueAt(index);
+ return NO_ERROR;
+ } else {
+ return BAD_VALUE;
+ }
+}
+
+}; // namespace android
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index a18bedb..16554c2 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -35,6 +35,10 @@
#include <binder/Parcel.h>
#include <binder/IPCThreadState.h>
#include <utils/Timers.h>
+#include <utils/Atomic.h>
+
+#include <system/audio.h>
+#include <cutils/bitops.h>
#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
@@ -65,8 +69,8 @@
// We double the size of input buffer for ping pong use of record buffer.
size <<= 1;
- if (AudioSystem::isLinearPCM(format)) {
- size /= channelCount * (format == AudioSystem::PCM_16_BIT ? 2 : 1);
+ if (audio_is_linear_pcm(format)) {
+ size /= channelCount * audio_bytes_per_sample(format);
}
*frameCount = size;
@@ -84,7 +88,7 @@
int inputSource,
uint32_t sampleRate,
int format,
- uint32_t channels,
+ uint32_t channelMask,
int frameCount,
uint32_t flags,
callback_t cbf,
@@ -93,7 +97,7 @@
int sessionId)
: mStatus(NO_INIT), mSessionId(0)
{
- mStatus = set(inputSource, sampleRate, format, channels,
+ mStatus = set(inputSource, sampleRate, format, channelMask,
frameCount, flags, cbf, user, notificationFrames, sessionId);
}
@@ -117,7 +121,7 @@
int inputSource,
uint32_t sampleRate,
int format,
- uint32_t channels,
+ uint32_t channelMask,
int frameCount,
uint32_t flags,
callback_t cbf,
@@ -127,7 +131,7 @@
int sessionId)
{
- LOGV("set(): sampleRate %d, channels %d, frameCount %d",sampleRate, channels, frameCount);
+ LOGV("set(): sampleRate %d, channelMask %d, frameCount %d",sampleRate, channelMask, frameCount);
AutoMutex lock(mLock);
@@ -144,22 +148,33 @@
}
// these below should probably come from the audioFlinger too...
if (format == 0) {
- format = AudioSystem::PCM_16_BIT;
+ format = AUDIO_FORMAT_PCM_16_BIT;
}
// validate parameters
- if (!AudioSystem::isValidFormat(format)) {
+ if (!audio_is_valid_format(format)) {
LOGE("Invalid format");
return BAD_VALUE;
}
- if (!AudioSystem::isInputChannel(channels)) {
+ if (!audio_is_input_channel(channelMask)) {
return BAD_VALUE;
}
- int channelCount = AudioSystem::popCount(channels);
+ int channelCount = popcount(channelMask);
+
+ if (sessionId == 0 ) {
+ mSessionId = AudioSystem::newAudioSessionId();
+ } else {
+ mSessionId = sessionId;
+ }
+ LOGV("set(): mSessionId %d", mSessionId);
audio_io_handle_t input = AudioSystem::getInput(inputSource,
- sampleRate, format, channels, (AudioSystem::audio_in_acoustics)flags);
+ sampleRate,
+ format,
+ channelMask,
+ (audio_in_acoustics_t)flags,
+ mSessionId);
if (input == 0) {
LOGE("Could not get audio input for record source %d", inputSource);
return BAD_VALUE;
@@ -183,10 +198,8 @@
notificationFrames = frameCount/2;
}
- mSessionId = sessionId;
-
// create the IAudioRecord
- status = openRecord_l(sampleRate, format, channelCount,
+ status = openRecord_l(sampleRate, format, channelMask,
frameCount, flags, input);
if (status != NO_ERROR) {
return status;
@@ -205,7 +218,7 @@
// Update buffer size in case it has been limited by AudioFlinger during track creation
mFrameCount = mCblk->frameCount;
mChannelCount = (uint8_t)channelCount;
- mChannels = channels;
+ mChannelMask = channelMask;
mActive = 0;
mCbf = cbf;
mNotificationFrames = notificationFrames;
@@ -253,8 +266,8 @@
int AudioRecord::frameSize() const
{
- if (AudioSystem::isLinearPCM(mFormat)) {
- return channelCount()*((format() == AudioSystem::PCM_8_BIT) ? sizeof(uint8_t) : sizeof(int16_t));
+ if (audio_is_linear_pcm(mFormat)) {
+ return channelCount()*audio_bytes_per_sample(mFormat);
} else {
return sizeof(uint8_t);
}
@@ -299,7 +312,7 @@
ret = mAudioRecord->start();
cblk->lock.lock();
if (ret == DEAD_OBJECT) {
- cblk->flags |= CBLK_INVALID_MSK;
+ android_atomic_or(CBLK_INVALID_ON, &cblk->flags);
}
}
if (cblk->flags & CBLK_INVALID_MSK) {
@@ -311,9 +324,9 @@
cblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
cblk->waitTimeMs = 0;
if (t != 0) {
- t->run("ClientRecordThread", THREAD_PRIORITY_AUDIO_CLIENT);
+ t->run("ClientRecordThread", ANDROID_PRIORITY_AUDIO);
} else {
- setpriority(PRIO_PROCESS, 0, THREAD_PRIORITY_AUDIO_CLIENT);
+ setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_AUDIO);
}
} else {
mActive = 0;
@@ -433,8 +446,8 @@
// must be called with mLock held
status_t AudioRecord::openRecord_l(
uint32_t sampleRate,
- int format,
- int channelCount,
+ uint32_t format,
+ uint32_t channelMask,
int frameCount,
uint32_t flags,
audio_io_handle_t input)
@@ -447,7 +460,7 @@
sp<IAudioRecord> record = audioFlinger->openRecord(getpid(), input,
sampleRate, format,
- channelCount,
+ channelMask,
frameCount,
((uint16_t)flags) << 16,
&mSessionId,
@@ -467,7 +480,7 @@
mCblkMemory = cblk;
mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer());
mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
- mCblk->flags &= ~CBLK_DIRECTION_MSK;
+ android_atomic_and(~CBLK_DIRECTION_MSK, &mCblk->flags);
mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
mCblk->waitTimeMs = 0;
return NO_ERROR;
@@ -477,7 +490,7 @@
{
AutoMutex lock(mLock);
int active;
- status_t result;
+ status_t result = NO_ERROR;
audio_track_cblk_t* cblk = mCblk;
uint32_t framesReq = audioBuffer->frameCount;
uint32_t waitTimeMs = (waitCount < 0) ? cblk->bufferTimeoutMs : WAIT_PERIOD_MS;
@@ -522,7 +535,7 @@
result = mAudioRecord->start();
cblk->lock.lock();
if (result == DEAD_OBJECT) {
- cblk->flags |= CBLK_INVALID_MSK;
+ android_atomic_or(CBLK_INVALID_ON, &cblk->flags);
create_new_record:
result = AudioRecord::restoreRecord_l(cblk);
}
@@ -577,7 +590,7 @@
audio_io_handle_t AudioRecord::getInput()
{
AutoMutex lock(mLock);
- return getInput_l();
+ return mInput;
}
// must be called with mLock held
@@ -585,8 +598,10 @@
{
mInput = AudioSystem::getInput(mInputSource,
mCblk->sampleRate,
- mFormat, mChannels,
- (AudioSystem::audio_in_acoustics)mFlags);
+ mFormat,
+ mChannelMask,
+ (audio_in_acoustics_t)mFlags,
+ mSessionId);
return mInput;
}
@@ -722,9 +737,8 @@
// Manage overrun callback
if (mActive && (cblk->framesAvailable() == 0)) {
LOGV("Overrun user: %x, server: %x, flags %04x", cblk->user, cblk->server, cblk->flags);
- if ((cblk->flags & CBLK_UNDERRUN_MSK) == CBLK_UNDERRUN_OFF) {
+ if (!(android_atomic_or(CBLK_UNDERRUN_ON, &cblk->flags) & CBLK_UNDERRUN_MSK)) {
mCbf(EVENT_OVERRUN, mUserData, 0);
- cblk->flags |= CBLK_UNDERRUN_ON;
}
}
@@ -743,10 +757,8 @@
{
status_t result;
- if (!(cblk->flags & CBLK_RESTORING_MSK)) {
+ if (!(android_atomic_or(CBLK_RESTORING_ON, &cblk->flags) & CBLK_RESTORING_MSK)) {
LOGW("dead IAudioRecord, creating a new one");
-
- cblk->flags |= CBLK_RESTORING_ON;
// signal old cblk condition so that other threads waiting for available buffers stop
// waiting now
cblk->cv.broadcast();
@@ -755,7 +767,7 @@
// if the new IAudioRecord is created, openRecord_l() will modify the
// following member variables: mAudioRecord, mCblkMemory and mCblk.
// It will also delete the strong references on previous IAudioRecord and IMemory
- result = openRecord_l(cblk->sampleRate, mFormat, mChannelCount,
+ result = openRecord_l(cblk->sampleRate, mFormat, mChannelMask,
mFrameCount, mFlags, getInput_l());
if (result == NO_ERROR) {
result = mAudioRecord->start();
@@ -765,10 +777,8 @@
}
// signal old cblk condition for other threads waiting for restore completion
- cblk->lock.lock();
- cblk->flags |= CBLK_RESTORED_MSK;
+ android_atomic_or(CBLK_RESTORED_ON, &cblk->flags);
cblk->cv.broadcast();
- cblk->lock.unlock();
} else {
if (!(cblk->flags & CBLK_RESTORED_MSK)) {
LOGW("dead IAudioRecord, waiting for a new one to be created");
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index 2f694ba..5009957 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -23,12 +23,7 @@
#include <media/IAudioPolicyService.h>
#include <math.h>
-// ----------------------------------------------------------------------------
-// the sim build doesn't have gettid
-
-#ifndef HAVE_GETTID
-# define gettid getpid
-#endif
+#include <system/audio.h>
// ----------------------------------------------------------------------------
@@ -45,7 +40,7 @@
// Cached values for recording queries
uint32_t AudioSystem::gPrevInSamplingRate = 16000;
-int AudioSystem::gPrevInFormat = AudioSystem::PCM_16_BIT;
+int AudioSystem::gPrevInFormat = AUDIO_FORMAT_PCM_16_BIT;
int AudioSystem::gPrevInChannelCount = 1;
size_t AudioSystem::gInBuffSize = 0;
@@ -127,7 +122,7 @@
status_t AudioSystem::setStreamVolume(int stream, float value, int output)
{
- if (uint32_t(stream) >= NUM_STREAM_TYPES) return BAD_VALUE;
+ if (uint32_t(stream) >= AUDIO_STREAM_CNT) return BAD_VALUE;
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
af->setStreamVolume(stream, value, output);
@@ -136,7 +131,7 @@
status_t AudioSystem::setStreamMute(int stream, bool mute)
{
- if (uint32_t(stream) >= NUM_STREAM_TYPES) return BAD_VALUE;
+ if (uint32_t(stream) >= AUDIO_STREAM_CNT) return BAD_VALUE;
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
af->setStreamMute(stream, mute);
@@ -145,7 +140,7 @@
status_t AudioSystem::getStreamVolume(int stream, float* volume, int output)
{
- if (uint32_t(stream) >= NUM_STREAM_TYPES) return BAD_VALUE;
+ if (uint32_t(stream) >= AUDIO_STREAM_CNT) return BAD_VALUE;
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
*volume = af->streamVolume(stream, output);
@@ -154,7 +149,7 @@
status_t AudioSystem::getStreamMute(int stream, bool* mute)
{
- if (uint32_t(stream) >= NUM_STREAM_TYPES) return BAD_VALUE;
+ if (uint32_t(stream) >= AUDIO_STREAM_CNT) return BAD_VALUE;
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
*mute = af->streamMute(stream);
@@ -163,7 +158,7 @@
status_t AudioSystem::setMode(int mode)
{
- if (mode >= NUM_MODES) return BAD_VALUE;
+ if (mode >= AUDIO_MODE_CNT) return BAD_VALUE;
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
return af->setMode(mode);
@@ -213,11 +208,11 @@
OutputDescriptor *outputDesc;
audio_io_handle_t output;
- if (streamType == DEFAULT) {
- streamType = MUSIC;
+ if (streamType == AUDIO_STREAM_DEFAULT) {
+ streamType = AUDIO_STREAM_MUSIC;
}
- output = getOutput((stream_type)streamType);
+ output = getOutput((audio_stream_type_t)streamType);
if (output == 0) {
return PERMISSION_DENIED;
}
@@ -246,11 +241,11 @@
OutputDescriptor *outputDesc;
audio_io_handle_t output;
- if (streamType == DEFAULT) {
- streamType = MUSIC;
+ if (streamType == AUDIO_STREAM_DEFAULT) {
+ streamType = AUDIO_STREAM_MUSIC;
}
- output = getOutput((stream_type)streamType);
+ output = getOutput((audio_stream_type_t)streamType);
if (output == 0) {
return PERMISSION_DENIED;
}
@@ -277,11 +272,11 @@
OutputDescriptor *outputDesc;
audio_io_handle_t output;
- if (streamType == DEFAULT) {
- streamType = MUSIC;
+ if (streamType == AUDIO_STREAM_DEFAULT) {
+ streamType = AUDIO_STREAM_MUSIC;
}
- output = getOutput((stream_type)streamType);
+ output = getOutput((audio_stream_type_t)streamType);
if (output == 0) {
return PERMISSION_DENIED;
}
@@ -338,11 +333,11 @@
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
- if (stream == DEFAULT) {
- stream = MUSIC;
+ if (stream == AUDIO_STREAM_DEFAULT) {
+ stream = AUDIO_STREAM_MUSIC;
}
- return af->getRenderPosition(halFrames, dspFrames, getOutput((stream_type)stream));
+ return af->getRenderPosition(halFrames, dspFrames, getOutput((audio_stream_type_t)stream));
}
unsigned int AudioSystem::getInputFramesLost(audio_io_handle_t ioHandle) {
@@ -455,10 +450,10 @@
bool AudioSystem::routedToA2dpOutput(int streamType) {
switch(streamType) {
- case MUSIC:
- case VOICE_CALL:
- case BLUETOOTH_SCO:
- case SYSTEM:
+ case AUDIO_STREAM_MUSIC:
+ case AUDIO_STREAM_VOICE_CALL:
+ case AUDIO_STREAM_BLUETOOTH_SCO:
+ case AUDIO_STREAM_SYSTEM:
return true;
default:
return false;
@@ -497,9 +492,9 @@
return gAudioPolicyService;
}
-status_t AudioSystem::setDeviceConnectionState(audio_devices device,
- device_connection_state state,
- const char *device_address)
+status_t AudioSystem::setDeviceConnectionState(audio_devices_t device,
+ audio_policy_dev_state_t state,
+ const char *device_address)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
@@ -507,11 +502,11 @@
return aps->setDeviceConnectionState(device, state, device_address);
}
-AudioSystem::device_connection_state AudioSystem::getDeviceConnectionState(audio_devices device,
+audio_policy_dev_state_t AudioSystem::getDeviceConnectionState(audio_devices_t device,
const char *device_address)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
- if (aps == 0) return DEVICE_STATE_UNAVAILABLE;
+ if (aps == 0) return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
return aps->getDeviceConnectionState(device, device_address);
}
@@ -531,26 +526,26 @@
return aps->setRingerMode(mode, mask);
}
-status_t AudioSystem::setForceUse(force_use usage, forced_config config)
+status_t AudioSystem::setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
return aps->setForceUse(usage, config);
}
-AudioSystem::forced_config AudioSystem::getForceUse(force_use usage)
+audio_policy_forced_cfg_t AudioSystem::getForceUse(audio_policy_force_use_t usage)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
- if (aps == 0) return FORCE_NONE;
+ if (aps == 0) return AUDIO_POLICY_FORCE_NONE;
return aps->getForceUse(usage);
}
-audio_io_handle_t AudioSystem::getOutput(stream_type stream,
+audio_io_handle_t AudioSystem::getOutput(audio_stream_type_t stream,
uint32_t samplingRate,
uint32_t format,
uint32_t channels,
- output_flags flags)
+ audio_policy_output_flags_t flags)
{
audio_io_handle_t output = 0;
// Do not use stream to output map cache if the direct output
@@ -561,9 +556,9 @@
// be reworked for proper operation with direct outputs. This code is too specific
// to the first use case we want to cover (Voice Recognition and Voice Dialer over
// Bluetooth SCO
- if ((flags & AudioSystem::OUTPUT_FLAG_DIRECT) == 0 &&
- ((stream != AudioSystem::VOICE_CALL && stream != AudioSystem::BLUETOOTH_SCO) ||
- channels != AudioSystem::CHANNEL_OUT_MONO ||
+ if ((flags & AUDIO_POLICY_OUTPUT_FLAG_DIRECT) == 0 &&
+ ((stream != AUDIO_STREAM_VOICE_CALL && stream != AUDIO_STREAM_BLUETOOTH_SCO) ||
+ channels != AUDIO_CHANNEL_OUT_MONO ||
(samplingRate != 8000 && samplingRate != 16000))) {
Mutex::Autolock _l(gLock);
output = AudioSystem::gStreamOutputMap.valueFor(stream);
@@ -573,7 +568,7 @@
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return 0;
output = aps->getOutput(stream, samplingRate, format, channels, flags);
- if ((flags & AudioSystem::OUTPUT_FLAG_DIRECT) == 0) {
+ if ((flags & AUDIO_POLICY_OUTPUT_FLAG_DIRECT) == 0) {
Mutex::Autolock _l(gLock);
AudioSystem::gStreamOutputMap.add(stream, output);
}
@@ -582,7 +577,7 @@
}
status_t AudioSystem::startOutput(audio_io_handle_t output,
- AudioSystem::stream_type stream,
+ audio_stream_type_t stream,
int session)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
@@ -591,7 +586,7 @@
}
status_t AudioSystem::stopOutput(audio_io_handle_t output,
- AudioSystem::stream_type stream,
+ audio_stream_type_t stream,
int session)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
@@ -610,11 +605,12 @@
uint32_t samplingRate,
uint32_t format,
uint32_t channels,
- audio_in_acoustics acoustics)
+ audio_in_acoustics_t acoustics,
+ int sessionId)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return 0;
- return aps->getInput(inputSource, samplingRate, format, channels, acoustics);
+ return aps->getInput(inputSource, samplingRate, format, channels, acoustics, sessionId);
}
status_t AudioSystem::startInput(audio_io_handle_t input)
@@ -638,7 +634,7 @@
aps->releaseInput(input);
}
-status_t AudioSystem::initStreamVolume(stream_type stream,
+status_t AudioSystem::initStreamVolume(audio_stream_type_t stream,
int indexMin,
int indexMax)
{
@@ -647,28 +643,28 @@
return aps->initStreamVolume(stream, indexMin, indexMax);
}
-status_t AudioSystem::setStreamVolumeIndex(stream_type stream, int index)
+status_t AudioSystem::setStreamVolumeIndex(audio_stream_type_t stream, int index)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
return aps->setStreamVolumeIndex(stream, index);
}
-status_t AudioSystem::getStreamVolumeIndex(stream_type stream, int *index)
+status_t AudioSystem::getStreamVolumeIndex(audio_stream_type_t stream, int *index)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
return aps->getStreamVolumeIndex(stream, index);
}
-uint32_t AudioSystem::getStrategyForStream(AudioSystem::stream_type stream)
+uint32_t AudioSystem::getStrategyForStream(audio_stream_type_t stream)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return 0;
return aps->getStrategyForStream(stream);
}
-uint32_t AudioSystem::getDevicesForStream(AudioSystem::stream_type stream)
+uint32_t AudioSystem::getDevicesForStream(audio_stream_type_t stream)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return 0;
@@ -683,14 +679,14 @@
}
status_t AudioSystem::registerEffect(effect_descriptor_t *desc,
- audio_io_handle_t output,
+ audio_io_handle_t io,
uint32_t strategy,
int session,
int id)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
- return aps->registerEffect(desc, output, strategy, session, id);
+ return aps->registerEffect(desc, io, strategy, session, id);
}
status_t AudioSystem::unregisterEffect(int id)
@@ -700,9 +696,11 @@
return aps->unregisterEffect(id);
}
-status_t AudioSystem::isStreamActive(int stream, bool* state, uint32_t inPastMs) {
+status_t AudioSystem::isStreamActive(int stream, bool* state, uint32_t inPastMs)
+{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
+ if (state == NULL) return BAD_VALUE;
*state = aps->isStreamActive(stream, inPastMs);
return NO_ERROR;
}
@@ -717,276 +715,5 @@
LOGW("AudioPolicyService server died!");
}
-// ---------------------------------------------------------------------------
-
-
-// use emulated popcount optimization
-// http://www.df.lth.se/~john_e/gems/gem002d.html
-uint32_t AudioSystem::popCount(uint32_t u)
-{
- u = ((u&0x55555555) + ((u>>1)&0x55555555));
- u = ((u&0x33333333) + ((u>>2)&0x33333333));
- u = ((u&0x0f0f0f0f) + ((u>>4)&0x0f0f0f0f));
- u = ((u&0x00ff00ff) + ((u>>8)&0x00ff00ff));
- u = ( u&0x0000ffff) + (u>>16);
- return u;
-}
-
-bool AudioSystem::isOutputDevice(audio_devices device)
-{
- if ((popCount(device) == 1 ) &&
- ((device & ~AudioSystem::DEVICE_OUT_ALL) == 0)) {
- return true;
- } else {
- return false;
- }
-}
-
-bool AudioSystem::isInputDevice(audio_devices device)
-{
- if ((popCount(device) == 1 ) &&
- ((device & ~AudioSystem::DEVICE_IN_ALL) == 0)) {
- return true;
- } else {
- return false;
- }
-}
-
-bool AudioSystem::isA2dpDevice(audio_devices device)
-{
- if ((popCount(device) == 1 ) &&
- (device & (AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP |
- AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
- AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER))) {
- return true;
- } else {
- return false;
- }
-}
-
-bool AudioSystem::isBluetoothScoDevice(audio_devices device)
-{
- if ((popCount(device) == 1 ) &&
- (device & (AudioSystem::DEVICE_OUT_BLUETOOTH_SCO |
- AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET |
- AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT |
- AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET))) {
- return true;
- } else {
- return false;
- }
-}
-
-bool AudioSystem::isLowVisibility(stream_type stream)
-{
- if (stream == AudioSystem::SYSTEM ||
- stream == AudioSystem::NOTIFICATION ||
- stream == AudioSystem::RING) {
- return true;
- } else {
- return false;
- }
-}
-
-bool AudioSystem::isInputChannel(uint32_t channel)
-{
- if ((channel & ~AudioSystem::CHANNEL_IN_ALL) == 0) {
- return true;
- } else {
- return false;
- }
-}
-
-bool AudioSystem::isOutputChannel(uint32_t channel)
-{
- if ((channel & ~AudioSystem::CHANNEL_OUT_ALL) == 0) {
- return true;
- } else {
- return false;
- }
-}
-
-bool AudioSystem::isValidFormat(uint32_t format)
-{
- switch (format & MAIN_FORMAT_MASK) {
- case PCM:
- case MP3:
- case AMR_NB:
- case AMR_WB:
- case AAC:
- case HE_AAC_V1:
- case HE_AAC_V2:
- case VORBIS:
- return true;
- default:
- return false;
- }
-}
-
-bool AudioSystem::isLinearPCM(uint32_t format)
-{
- switch (format) {
- case PCM_16_BIT:
- case PCM_8_BIT:
- return true;
- default:
- return false;
- }
-}
-
-//------------------------- AudioParameter class implementation ---------------
-
-const char *AudioParameter::keyRouting = "routing";
-const char *AudioParameter::keySamplingRate = "sampling_rate";
-const char *AudioParameter::keyFormat = "format";
-const char *AudioParameter::keyChannels = "channels";
-const char *AudioParameter::keyFrameCount = "frame_count";
-const char *AudioParameter::keyInputSource = "input_source";
-
-AudioParameter::AudioParameter(const String8& keyValuePairs)
-{
- char *str = new char[keyValuePairs.length()+1];
- mKeyValuePairs = keyValuePairs;
-
- strcpy(str, keyValuePairs.string());
- char *pair = strtok(str, ";");
- while (pair != NULL) {
- if (strlen(pair) != 0) {
- size_t eqIdx = strcspn(pair, "=");
- String8 key = String8(pair, eqIdx);
- String8 value;
- if (eqIdx == strlen(pair)) {
- value = String8("");
- } else {
- value = String8(pair + eqIdx + 1);
- }
- if (mParameters.indexOfKey(key) < 0) {
- mParameters.add(key, value);
- } else {
- mParameters.replaceValueFor(key, value);
- }
- } else {
- LOGV("AudioParameter() cstor empty key value pair");
- }
- pair = strtok(NULL, ";");
- }
-
- delete[] str;
-}
-
-AudioParameter::~AudioParameter()
-{
- mParameters.clear();
-}
-
-String8 AudioParameter::toString()
-{
- String8 str = String8("");
-
- size_t size = mParameters.size();
- for (size_t i = 0; i < size; i++) {
- str += mParameters.keyAt(i);
- str += "=";
- str += mParameters.valueAt(i);
- if (i < (size - 1)) str += ";";
- }
- return str;
-}
-
-status_t AudioParameter::add(const String8& key, const String8& value)
-{
- if (mParameters.indexOfKey(key) < 0) {
- mParameters.add(key, value);
- return NO_ERROR;
- } else {
- mParameters.replaceValueFor(key, value);
- return ALREADY_EXISTS;
- }
-}
-
-status_t AudioParameter::addInt(const String8& key, const int value)
-{
- char str[12];
- if (snprintf(str, 12, "%d", value) > 0) {
- String8 str8 = String8(str);
- return add(key, str8);
- } else {
- return BAD_VALUE;
- }
-}
-
-status_t AudioParameter::addFloat(const String8& key, const float value)
-{
- char str[23];
- if (snprintf(str, 23, "%.10f", value) > 0) {
- String8 str8 = String8(str);
- return add(key, str8);
- } else {
- return BAD_VALUE;
- }
-}
-
-status_t AudioParameter::remove(const String8& key)
-{
- if (mParameters.indexOfKey(key) >= 0) {
- mParameters.removeItem(key);
- return NO_ERROR;
- } else {
- return BAD_VALUE;
- }
-}
-
-status_t AudioParameter::get(const String8& key, String8& value)
-{
- if (mParameters.indexOfKey(key) >= 0) {
- value = mParameters.valueFor(key);
- return NO_ERROR;
- } else {
- return BAD_VALUE;
- }
-}
-
-status_t AudioParameter::getInt(const String8& key, int& value)
-{
- String8 str8;
- status_t result = get(key, str8);
- value = 0;
- if (result == NO_ERROR) {
- int val;
- if (sscanf(str8.string(), "%d", &val) == 1) {
- value = val;
- } else {
- result = INVALID_OPERATION;
- }
- }
- return result;
-}
-
-status_t AudioParameter::getFloat(const String8& key, float& value)
-{
- String8 str8;
- status_t result = get(key, str8);
- value = 0;
- if (result == NO_ERROR) {
- float val;
- if (sscanf(str8.string(), "%f", &val) == 1) {
- value = val;
- } else {
- result = INVALID_OPERATION;
- }
- }
- return result;
-}
-
-status_t AudioParameter::getAt(size_t index, String8& key, String8& value)
-{
- if (mParameters.size() > index) {
- key = mParameters.keyAt(index);
- value = mParameters.valueAt(index);
- return NO_ERROR;
- } else {
- return BAD_VALUE;
- }
-}
}; // namespace android
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 8d8f67b..31eb97a 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -35,6 +35,12 @@
#include <binder/Parcel.h>
#include <binder/IPCThreadState.h>
#include <utils/Timers.h>
+#include <utils/Atomic.h>
+
+#include <cutils/bitops.h>
+
+#include <system/audio.h>
+#include <system/audio_policy.h>
#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
@@ -81,7 +87,7 @@
int streamType,
uint32_t sampleRate,
int format,
- int channels,
+ int channelMask,
int frameCount,
uint32_t flags,
callback_t cbf,
@@ -90,7 +96,7 @@
int sessionId)
: mStatus(NO_INIT)
{
- mStatus = set(streamType, sampleRate, format, channels,
+ mStatus = set(streamType, sampleRate, format, channelMask,
frameCount, flags, cbf, user, notificationFrames,
0, false, sessionId);
}
@@ -99,7 +105,7 @@
int streamType,
uint32_t sampleRate,
int format,
- int channels,
+ int channelMask,
const sp<IMemory>& sharedBuffer,
uint32_t flags,
callback_t cbf,
@@ -108,7 +114,7 @@
int sessionId)
: mStatus(NO_INIT)
{
- mStatus = set(streamType, sampleRate, format, channels,
+ mStatus = set(streamType, sampleRate, format, channelMask,
0, flags, cbf, user, notificationFrames,
sharedBuffer, false, sessionId);
}
@@ -135,7 +141,7 @@
int streamType,
uint32_t sampleRate,
int format,
- int channels,
+ int channelMask,
int frameCount,
uint32_t flags,
callback_t cbf,
@@ -164,39 +170,41 @@
}
// handle default values first.
- if (streamType == AudioSystem::DEFAULT) {
- streamType = AudioSystem::MUSIC;
+ if (streamType == AUDIO_STREAM_DEFAULT) {
+ streamType = AUDIO_STREAM_MUSIC;
}
if (sampleRate == 0) {
sampleRate = afSampleRate;
}
// these below should probably come from the audioFlinger too...
if (format == 0) {
- format = AudioSystem::PCM_16_BIT;
+ format = AUDIO_FORMAT_PCM_16_BIT;
}
- if (channels == 0) {
- channels = AudioSystem::CHANNEL_OUT_STEREO;
+ if (channelMask == 0) {
+ channelMask = AUDIO_CHANNEL_OUT_STEREO;
}
// validate parameters
- if (!AudioSystem::isValidFormat(format)) {
+ if (!audio_is_valid_format(format)) {
LOGE("Invalid format");
return BAD_VALUE;
}
// force direct flag if format is not linear PCM
- if (!AudioSystem::isLinearPCM(format)) {
- flags |= AudioSystem::OUTPUT_FLAG_DIRECT;
+ if (!audio_is_linear_pcm(format)) {
+ flags |= AUDIO_POLICY_OUTPUT_FLAG_DIRECT;
}
- if (!AudioSystem::isOutputChannel(channels)) {
+ if (!audio_is_output_channel(channelMask)) {
LOGE("Invalid channel mask");
return BAD_VALUE;
}
- uint32_t channelCount = AudioSystem::popCount(channels);
+ uint32_t channelCount = popcount(channelMask);
- audio_io_handle_t output = AudioSystem::getOutput((AudioSystem::stream_type)streamType,
- sampleRate, format, channels, (AudioSystem::output_flags)flags);
+ audio_io_handle_t output = AudioSystem::getOutput(
+ (audio_stream_type_t)streamType,
+ sampleRate,format, channelMask,
+ (audio_policy_output_flags_t)flags);
if (output == 0) {
LOGE("Could not get audio output for stream type %d", streamType);
@@ -214,8 +222,8 @@
// create the IAudioTrack
status_t status = createTrack_l(streamType,
sampleRate,
- format,
- channelCount,
+ (uint32_t)format,
+ (uint32_t)channelMask,
frameCount,
flags,
sharedBuffer,
@@ -237,8 +245,8 @@
mStatus = NO_ERROR;
mStreamType = streamType;
- mFormat = format;
- mChannels = channels;
+ mFormat = (uint32_t)format;
+ mChannelMask = (uint32_t)channelMask;
mChannelCount = channelCount;
mSharedBuffer = sharedBuffer;
mMuted = false;
@@ -289,8 +297,8 @@
int AudioTrack::frameSize() const
{
- if (AudioSystem::isLinearPCM(mFormat)) {
- return channelCount()*((format() == AudioSystem::PCM_8_BIT) ? sizeof(uint8_t) : sizeof(int16_t));
+ if (audio_is_linear_pcm(mFormat)) {
+ return channelCount()*audio_bytes_per_sample(mFormat);
} else {
return sizeof(uint8_t);
}
@@ -306,7 +314,7 @@
void AudioTrack::start()
{
sp<AudioTrackThread> t = mAudioTrackThread;
- status_t status;
+ status_t status = NO_ERROR;
LOGV("start %p", this);
if (t != 0) {
@@ -329,23 +337,23 @@
if (mActive == 0) {
mActive = 1;
mNewPosition = cblk->server + mUpdatePeriod;
+ cblk->lock.lock();
cblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS;
cblk->waitTimeMs = 0;
- cblk->flags &= ~CBLK_DISABLED_ON;
+ android_atomic_and(~CBLK_DISABLED_ON, &cblk->flags);
if (t != 0) {
- t->run("AudioTrackThread", THREAD_PRIORITY_AUDIO_CLIENT);
+ t->run("AudioTrackThread", ANDROID_PRIORITY_AUDIO);
} else {
- setpriority(PRIO_PROCESS, 0, THREAD_PRIORITY_AUDIO_CLIENT);
+ setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_AUDIO);
}
LOGV("start %p before lock cblk %p", this, mCblk);
- cblk->lock.lock();
if (!(cblk->flags & CBLK_INVALID_MSK)) {
cblk->lock.unlock();
status = mAudioTrack->start();
cblk->lock.lock();
if (status == DEAD_OBJECT) {
- cblk->flags |= CBLK_INVALID_MSK;
+ android_atomic_or(CBLK_INVALID_ON, &cblk->flags);
}
}
if (cblk->flags & CBLK_INVALID_MSK) {
@@ -546,12 +554,13 @@
}
if (loopStart >= loopEnd ||
- loopEnd - loopStart > cblk->frameCount) {
+ loopEnd - loopStart > cblk->frameCount ||
+ cblk->server > loopStart) {
LOGE("setLoop invalid value: loopStart %d, loopEnd %d, loopCount %d, framecount %d, user %d", loopStart, loopEnd, loopCount, cblk->frameCount, cblk->user);
return BAD_VALUE;
}
- if ((mSharedBuffer != 0) && (loopEnd > cblk->frameCount)) {
+ if ((mSharedBuffer != 0) && (loopEnd > cblk->frameCount)) {
LOGE("setLoop invalid value: loop markers beyond data: loopStart %d, loopEnd %d, framecount %d",
loopStart, loopEnd, cblk->frameCount);
return BAD_VALUE;
@@ -635,7 +644,7 @@
if (position > mCblk->user) return BAD_VALUE;
mCblk->server = position;
- mCblk->flags |= CBLK_FORCEREADY_ON;
+ android_atomic_or(CBLK_FORCEREADY_ON, &mCblk->flags);
return NO_ERROR;
}
@@ -671,8 +680,8 @@
// must be called with mLock held
audio_io_handle_t AudioTrack::getOutput_l()
{
- return AudioSystem::getOutput((AudioSystem::stream_type)mStreamType,
- mCblk->sampleRate, mFormat, mChannels, (AudioSystem::output_flags)mFlags);
+ return AudioSystem::getOutput((audio_stream_type_t)mStreamType,
+ mCblk->sampleRate, mFormat, mChannelMask, (audio_policy_output_flags_t)mFlags);
}
int AudioTrack::getSessionId()
@@ -696,8 +705,8 @@
status_t AudioTrack::createTrack_l(
int streamType,
uint32_t sampleRate,
- int format,
- int channelCount,
+ uint32_t format,
+ uint32_t channelMask,
int frameCount,
uint32_t flags,
const sp<IMemory>& sharedBuffer,
@@ -725,7 +734,7 @@
}
mNotificationFramesAct = mNotificationFramesReq;
- if (!AudioSystem::isLinearPCM(format)) {
+ if (!audio_is_linear_pcm(format)) {
if (sharedBuffer != 0) {
frameCount = sharedBuffer->size();
}
@@ -758,6 +767,7 @@
}
} else {
// Ensure that buffer alignment matches channelcount
+ int channelCount = popcount(channelMask);
if (((uint32_t)sharedBuffer->pointer() & (channelCount | 1)) != 0) {
LOGE("Invalid buffer alignement: address %p, channelCount %d", sharedBuffer->pointer(), channelCount);
return BAD_VALUE;
@@ -770,7 +780,7 @@
streamType,
sampleRate,
format,
- channelCount,
+ channelMask,
frameCount,
((uint16_t)flags) << 16,
sharedBuffer,
@@ -792,7 +802,7 @@
mCblkMemory.clear();
mCblkMemory = cblk;
mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer());
- mCblk->flags |= CBLK_DIRECTION_OUT;
+ android_atomic_or(CBLK_DIRECTION_OUT, &mCblk->flags);
if (sharedBuffer == 0) {
mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
} else {
@@ -815,7 +825,7 @@
{
AutoMutex lock(mLock);
int active;
- status_t result;
+ status_t result = NO_ERROR;
audio_track_cblk_t* cblk = mCblk;
uint32_t framesReq = audioBuffer->frameCount;
uint32_t waitTimeMs = (waitCount < 0) ? cblk->bufferTimeoutMs : WAIT_PERIOD_MS;
@@ -825,6 +835,12 @@
uint32_t framesAvail = cblk->framesAvailable();
+ cblk->lock.lock();
+ if (cblk->flags & CBLK_INVALID_MSK) {
+ goto create_new_track;
+ }
+ cblk->lock.unlock();
+
if (framesAvail == 0) {
cblk->lock.lock();
goto start_loop_here;
@@ -866,7 +882,7 @@
result = mAudioTrack->start();
cblk->lock.lock();
if (result == DEAD_OBJECT) {
- cblk->flags |= CBLK_INVALID_MSK;
+ android_atomic_or(CBLK_INVALID_ON, &cblk->flags);
create_new_track:
result = restoreTrack_l(cblk, false);
}
@@ -893,7 +909,7 @@
// restart track if it was disabled by audioflinger due to previous underrun
if (mActive && (cblk->flags & CBLK_DISABLED_MSK)) {
- cblk->flags &= ~CBLK_DISABLED_ON;
+ android_atomic_and(~CBLK_DISABLED_ON, &cblk->flags);
LOGW("obtainBuffer() track %p disabled, restarting", this);
mAudioTrack->start();
}
@@ -915,8 +931,8 @@
audioBuffer->channelCount = mChannelCount;
audioBuffer->frameCount = framesReq;
audioBuffer->size = framesReq * cblk->frameSize;
- if (AudioSystem::isLinearPCM(mFormat)) {
- audioBuffer->format = AudioSystem::PCM_16_BIT;
+ if (audio_is_linear_pcm(mFormat)) {
+ audioBuffer->format = AUDIO_FORMAT_PCM_16_BIT;
} else {
audioBuffer->format = mFormat;
}
@@ -957,9 +973,10 @@
ssize_t written = 0;
const int8_t *src = (const int8_t *)buffer;
Buffer audioBuffer;
+ size_t frameSz = (size_t)frameSize();
do {
- audioBuffer.frameCount = userSize/frameSize();
+ audioBuffer.frameCount = userSize/frameSz;
// Calling obtainBuffer() with a negative wait count causes
// an (almost) infinite wait time.
@@ -973,7 +990,7 @@
size_t toWrite;
- if (mFormat == AudioSystem::PCM_8_BIT && !(mFlags & AudioSystem::OUTPUT_FLAG_DIRECT)) {
+ if (mFormat == AUDIO_FORMAT_PCM_8_BIT && !(mFlags & AUDIO_POLICY_OUTPUT_FLAG_DIRECT)) {
// Divide capacity by 2 to take expansion into account
toWrite = audioBuffer.size>>1;
// 8 to 16 bit conversion
@@ -991,7 +1008,7 @@
written += toWrite;
releaseBuffer(&audioBuffer);
- } while (userSize);
+ } while (userSize >= frameSz);
return written;
}
@@ -1013,14 +1030,13 @@
mLock.unlock();
// Manage underrun callback
- if (mActive && (cblk->framesReady() == 0)) {
+ if (mActive && (cblk->framesAvailable() == cblk->frameCount)) {
LOGV("Underrun user: %x, server: %x, flags %04x", cblk->user, cblk->server, cblk->flags);
- if ((cblk->flags & CBLK_UNDERRUN_MSK) == CBLK_UNDERRUN_OFF) {
+ if (!(android_atomic_or(CBLK_UNDERRUN_ON, &cblk->flags) & CBLK_UNDERRUN_MSK)) {
mCbf(EVENT_UNDERRUN, mUserData, 0);
if (cblk->server == cblk->frameCount) {
mCbf(EVENT_BUFFER_END, mUserData, 0);
}
- cblk->flags |= CBLK_UNDERRUN_ON;
if (mSharedBuffer != 0) return false;
}
}
@@ -1077,7 +1093,7 @@
// Divide buffer size by 2 to take into account the expansion
// due to 8 to 16 bit conversion: the callback must fill only half
// of the destination buffer
- if (mFormat == AudioSystem::PCM_8_BIT && !(mFlags & AudioSystem::OUTPUT_FLAG_DIRECT)) {
+ if (mFormat == AUDIO_FORMAT_PCM_8_BIT && !(mFlags & AUDIO_POLICY_OUTPUT_FLAG_DIRECT)) {
audioBuffer.size >>= 1;
}
@@ -1096,7 +1112,7 @@
}
if (writtenSize > reqSize) writtenSize = reqSize;
- if (mFormat == AudioSystem::PCM_8_BIT && !(mFlags & AudioSystem::OUTPUT_FLAG_DIRECT)) {
+ if (mFormat == AUDIO_FORMAT_PCM_8_BIT && !(mFlags & AUDIO_POLICY_OUTPUT_FLAG_DIRECT)) {
// 8 to 16 bit conversion
const int8_t *src = audioBuffer.i8 + writtenSize-1;
int count = writtenSize;
@@ -1134,11 +1150,10 @@
{
status_t result;
- if (!(cblk->flags & CBLK_RESTORING_MSK)) {
+ if (!(android_atomic_or(CBLK_RESTORING_ON, &cblk->flags) & CBLK_RESTORING_MSK)) {
LOGW("dead IAudioTrack, creating a new one from %s",
fromStart ? "start()" : "obtainBuffer()");
- cblk->flags |= CBLK_RESTORING_ON;
// signal old cblk condition so that other threads waiting for available buffers stop
// waiting now
cblk->cv.broadcast();
@@ -1150,7 +1165,7 @@
result = createTrack_l(mStreamType,
cblk->sampleRate,
mFormat,
- mChannelCount,
+ mChannelMask,
mFrameCount,
mFlags,
mSharedBuffer,
@@ -1158,10 +1173,20 @@
false);
if (result == NO_ERROR) {
+ // restore write index and set other indexes to reflect empty buffer status
+ mCblk->user = cblk->user;
+ mCblk->server = cblk->user;
+ mCblk->userBase = cblk->user;
+ mCblk->serverBase = cblk->user;
+ // restore loop: this is not guaranteed to succeed if new frame count is not
+ // compatible with loop length
+ setLoop_l(cblk->loopStart, cblk->loopEnd, cblk->loopCount);
if (!fromStart) {
mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
}
- result = mAudioTrack->start();
+ if (mActive) {
+ result = mAudioTrack->start();
+ }
if (fromStart && result == NO_ERROR) {
mNewPosition = mCblk->server + mUpdatePeriod;
}
@@ -1171,10 +1196,8 @@
}
// signal old cblk condition for other threads waiting for restore completion
- cblk->lock.lock();
- cblk->flags |= CBLK_RESTORED_MSK;
+ android_atomic_or(CBLK_RESTORED_ON, &cblk->flags);
cblk->cv.broadcast();
- cblk->lock.unlock();
} else {
if (!(cblk->flags & CBLK_RESTORED_MSK)) {
LOGW("dead IAudioTrack, waiting for a new one");
@@ -1248,11 +1271,12 @@
// =========================================================================
+
audio_track_cblk_t::audio_track_cblk_t()
: lock(Mutex::SHARED), cv(Condition::SHARED), user(0), server(0),
userBase(0), serverBase(0), buffers(0), frameCount(0),
loopStart(UINT_MAX), loopEnd(UINT_MAX), loopCount(0), volumeLR(0),
- flags(0), sendLevel(0)
+ sendLevel(0), flags(0)
{
}
@@ -1279,25 +1303,17 @@
this->user = u;
// Clear flow control error condition as new data has been written/read to/from buffer.
- flags &= ~CBLK_UNDERRUN_MSK;
+ if (flags & CBLK_UNDERRUN_MSK) {
+ android_atomic_and(~CBLK_UNDERRUN_MSK, &flags);
+ }
return u;
}
bool audio_track_cblk_t::stepServer(uint32_t frameCount)
{
- // the code below simulates lock-with-timeout
- // we MUST do this to protect the AudioFlinger server
- // as this lock is shared with the client.
- status_t err;
-
- err = lock.tryLock();
- if (err == -EBUSY) { // just wait a bit
- usleep(1000);
- err = lock.tryLock();
- }
- if (err != NO_ERROR) {
- // probably, the client just died.
+ if (!tryLock()) {
+ LOGW("stepServer() could not lock cblk");
return false;
}
@@ -1374,18 +1390,42 @@
if (u < loopEnd) {
return u - s;
} else {
- Mutex::Autolock _l(lock);
- if (loopCount >= 0) {
- return (loopEnd - loopStart)*loopCount + u - s;
- } else {
- return UINT_MAX;
+ // do not block on mutex shared with client on AudioFlinger side
+ if (!tryLock()) {
+ LOGW("framesReady() could not lock cblk");
+ return 0;
}
+ uint32_t frames = UINT_MAX;
+ if (loopCount >= 0) {
+ frames = (loopEnd - loopStart)*loopCount + u - s;
+ }
+ lock.unlock();
+ return frames;
}
} else {
return s - u;
}
}
+bool audio_track_cblk_t::tryLock()
+{
+ // the code below simulates lock-with-timeout
+ // we MUST do this to protect the AudioFlinger server
+ // as this lock is shared with the client.
+ status_t err;
+
+ err = lock.tryLock();
+ if (err == -EBUSY) { // just wait a bit
+ usleep(1000);
+ err = lock.tryLock();
+ }
+ if (err != NO_ERROR) {
+ // probably, the client just died.
+ return false;
+ }
+ return true;
+}
+
// -------------------------------------------------------------------------
}; // namespace android
diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp
index eec47c0..4a12962 100644
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -63,8 +63,6 @@
GET_RENDER_POSITION,
GET_INPUT_FRAMES_LOST,
NEW_AUDIO_SESSION_ID,
- LOAD_EFFECT_LIBRARY,
- UNLOAD_EFFECT_LIBRARY,
QUERY_NUM_EFFECTS,
QUERY_EFFECT,
GET_EFFECT_DESCRIPTOR,
@@ -84,8 +82,8 @@
pid_t pid,
int streamType,
uint32_t sampleRate,
- int format,
- int channelCount,
+ uint32_t format,
+ uint32_t channelMask,
int frameCount,
uint32_t flags,
const sp<IMemory>& sharedBuffer,
@@ -100,7 +98,7 @@
data.writeInt32(streamType);
data.writeInt32(sampleRate);
data.writeInt32(format);
- data.writeInt32(channelCount);
+ data.writeInt32(channelMask);
data.writeInt32(frameCount);
data.writeInt32(flags);
data.writeStrongBinder(sharedBuffer->asBinder());
@@ -131,8 +129,8 @@
pid_t pid,
int input,
uint32_t sampleRate,
- int format,
- int channelCount,
+ uint32_t format,
+ uint32_t channelMask,
int frameCount,
uint32_t flags,
int *sessionId,
@@ -145,7 +143,7 @@
data.writeInt32(input);
data.writeInt32(sampleRate);
data.writeInt32(format);
- data.writeInt32(channelCount);
+ data.writeInt32(channelMask);
data.writeInt32(frameCount);
data.writeInt32(flags);
int lSessionId = 0;
@@ -188,7 +186,7 @@
return reply.readInt32();
}
- virtual int format(int output) const
+ virtual uint32_t format(int output) const
{
Parcel data, reply;
data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
@@ -528,37 +526,6 @@
return id;
}
- virtual status_t loadEffectLibrary(const char *libPath, int *handle)
- {
- if (libPath == NULL || handle == NULL) {
- return BAD_VALUE;
- }
- *handle = 0;
- Parcel data, reply;
- data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
- data.writeCString(libPath);
- status_t status = remote()->transact(LOAD_EFFECT_LIBRARY, data, &reply);
- if (status == NO_ERROR) {
- status = reply.readInt32();
- if (status == NO_ERROR) {
- *handle = reply.readInt32();
- }
- }
- return status;
- }
-
- virtual status_t unloadEffectLibrary(int handle)
- {
- Parcel data, reply;
- data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
- data.writeInt32(handle);
- status_t status = remote()->transact(UNLOAD_EFFECT_LIBRARY, data, &reply);
- if (status == NO_ERROR) {
- status = reply.readInt32();
- }
- return status;
- }
-
virtual status_t queryNumberEffects(uint32_t *numEffects)
{
Parcel data, reply;
@@ -952,21 +919,6 @@
reply->writeInt32(newAudioSessionId());
return NO_ERROR;
} break;
- case LOAD_EFFECT_LIBRARY: {
- CHECK_INTERFACE(IAudioFlinger, data, reply);
- int handle;
- status_t status = loadEffectLibrary(data.readCString(), &handle);
- reply->writeInt32(status);
- if (status == NO_ERROR) {
- reply->writeInt32(handle);
- }
- return NO_ERROR;
- }
- case UNLOAD_EFFECT_LIBRARY: {
- CHECK_INTERFACE(IAudioFlinger, data, reply);
- reply->writeInt32(unloadEffectLibrary(data.readInt32()));
- return NO_ERROR;
- }
case QUERY_NUM_EFFECTS: {
CHECK_INTERFACE(IAudioFlinger, data, reply);
uint32_t numEffects;
diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp
index b89a278..15f4be0 100644
--- a/media/libmedia/IAudioPolicyService.cpp
+++ b/media/libmedia/IAudioPolicyService.cpp
@@ -25,6 +25,8 @@
#include <media/IAudioPolicyService.h>
+#include <system/audio.h>
+
namespace android {
enum {
@@ -51,6 +53,7 @@
UNREGISTER_EFFECT,
IS_STREAM_ACTIVE,
GET_DEVICES_FOR_STREAM,
+ QUERY_DEFAULT_PRE_PROCESSING
};
class BpAudioPolicyService : public BpInterface<IAudioPolicyService>
@@ -62,8 +65,8 @@
}
virtual status_t setDeviceConnectionState(
- AudioSystem::audio_devices device,
- AudioSystem::device_connection_state state,
+ audio_devices_t device,
+ audio_policy_dev_state_t state,
const char *device_address)
{
Parcel data, reply;
@@ -75,8 +78,8 @@
return static_cast <status_t> (reply.readInt32());
}
- virtual AudioSystem::device_connection_state getDeviceConnectionState(
- AudioSystem::audio_devices device,
+ virtual audio_policy_dev_state_t getDeviceConnectionState(
+ audio_devices_t device,
const char *device_address)
{
Parcel data, reply;
@@ -84,7 +87,7 @@
data.writeInt32(static_cast <uint32_t>(device));
data.writeCString(device_address);
remote()->transact(GET_DEVICE_CONNECTION_STATE, data, &reply);
- return static_cast <AudioSystem::device_connection_state>(reply.readInt32());
+ return static_cast <audio_policy_dev_state_t>(reply.readInt32());
}
virtual status_t setPhoneState(int state)
@@ -106,7 +109,7 @@
return static_cast <status_t> (reply.readInt32());
}
- virtual status_t setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config)
+ virtual status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
@@ -116,21 +119,21 @@
return static_cast <status_t> (reply.readInt32());
}
- virtual AudioSystem::forced_config getForceUse(AudioSystem::force_use usage)
+ virtual audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
data.writeInt32(static_cast <uint32_t>(usage));
remote()->transact(GET_FORCE_USE, data, &reply);
- return static_cast <AudioSystem::forced_config> (reply.readInt32());
+ return static_cast <audio_policy_forced_cfg_t> (reply.readInt32());
}
virtual audio_io_handle_t getOutput(
- AudioSystem::stream_type stream,
+ audio_stream_type_t stream,
uint32_t samplingRate,
uint32_t format,
uint32_t channels,
- AudioSystem::output_flags flags)
+ audio_policy_output_flags_t flags)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
@@ -144,7 +147,7 @@
}
virtual status_t startOutput(audio_io_handle_t output,
- AudioSystem::stream_type stream,
+ audio_stream_type_t stream,
int session)
{
Parcel data, reply;
@@ -157,7 +160,7 @@
}
virtual status_t stopOutput(audio_io_handle_t output,
- AudioSystem::stream_type stream,
+ audio_stream_type_t stream,
int session)
{
Parcel data, reply;
@@ -182,7 +185,8 @@
uint32_t samplingRate,
uint32_t format,
uint32_t channels,
- AudioSystem::audio_in_acoustics acoustics)
+ audio_in_acoustics_t acoustics,
+ int audioSession)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
@@ -191,6 +195,7 @@
data.writeInt32(static_cast <uint32_t>(format));
data.writeInt32(channels);
data.writeInt32(static_cast <uint32_t>(acoustics));
+ data.writeInt32(audioSession);
remote()->transact(GET_INPUT, data, &reply);
return static_cast <audio_io_handle_t> (reply.readInt32());
}
@@ -221,7 +226,7 @@
remote()->transact(RELEASE_INPUT, data, &reply);
}
- virtual status_t initStreamVolume(AudioSystem::stream_type stream,
+ virtual status_t initStreamVolume(audio_stream_type_t stream,
int indexMin,
int indexMax)
{
@@ -234,7 +239,7 @@
return static_cast <status_t> (reply.readInt32());
}
- virtual status_t setStreamVolumeIndex(AudioSystem::stream_type stream, int index)
+ virtual status_t setStreamVolumeIndex(audio_stream_type_t stream, int index)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
@@ -244,7 +249,7 @@
return static_cast <status_t> (reply.readInt32());
}
- virtual status_t getStreamVolumeIndex(AudioSystem::stream_type stream, int *index)
+ virtual status_t getStreamVolumeIndex(audio_stream_type_t stream, int *index)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
@@ -255,7 +260,7 @@
return static_cast <status_t> (reply.readInt32());
}
- virtual uint32_t getStrategyForStream(AudioSystem::stream_type stream)
+ virtual uint32_t getStrategyForStream(audio_stream_type_t stream)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
@@ -264,7 +269,7 @@
return reply.readInt32();
}
- virtual uint32_t getDevicesForStream(AudioSystem::stream_type stream)
+ virtual uint32_t getDevicesForStream(audio_stream_type_t stream)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
@@ -283,7 +288,7 @@
}
virtual status_t registerEffect(effect_descriptor_t *desc,
- audio_io_handle_t output,
+ audio_io_handle_t io,
uint32_t strategy,
int session,
int id)
@@ -291,7 +296,7 @@
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
data.write(desc, sizeof(effect_descriptor_t));
- data.writeInt32(output);
+ data.writeInt32(io);
data.writeInt32(strategy);
data.writeInt32(session);
data.writeInt32(id);
@@ -317,6 +322,31 @@
remote()->transact(IS_STREAM_ACTIVE, data, &reply);
return reply.readInt32();
}
+
+ virtual status_t queryDefaultPreProcessing(int audioSession,
+ effect_descriptor_t *descriptors,
+ uint32_t *count)
+ {
+ if (descriptors == NULL || count == NULL) {
+ return BAD_VALUE;
+ }
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+ data.writeInt32(audioSession);
+ data.writeInt32(*count);
+ status_t status = remote()->transact(QUERY_DEFAULT_PRE_PROCESSING, data, &reply);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = static_cast <status_t> (reply.readInt32());
+ uint32_t retCount = reply.readInt32();
+ if (retCount != 0) {
+ uint32_t numDesc = (retCount < *count) ? retCount : *count;
+ reply.read(descriptors, sizeof(effect_descriptor_t) * numDesc);
+ }
+ *count = retCount;
+ return status;
+ }
};
IMPLEMENT_META_INTERFACE(AudioPolicyService, "android.media.IAudioPolicyService");
@@ -330,10 +360,10 @@
switch(code) {
case SET_DEVICE_CONNECTION_STATE: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- AudioSystem::audio_devices device =
- static_cast <AudioSystem::audio_devices>(data.readInt32());
- AudioSystem::device_connection_state state =
- static_cast <AudioSystem::device_connection_state>(data.readInt32());
+ audio_devices_t device =
+ static_cast <audio_devices_t>(data.readInt32());
+ audio_policy_dev_state_t state =
+ static_cast <audio_policy_dev_state_t>(data.readInt32());
const char *device_address = data.readCString();
reply->writeInt32(static_cast<uint32_t> (setDeviceConnectionState(device,
state,
@@ -343,8 +373,8 @@
case GET_DEVICE_CONNECTION_STATE: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- AudioSystem::audio_devices device =
- static_cast<AudioSystem::audio_devices> (data.readInt32());
+ audio_devices_t device =
+ static_cast<audio_devices_t> (data.readInt32());
const char *device_address = data.readCString();
reply->writeInt32(static_cast<uint32_t> (getDeviceConnectionState(device,
device_address)));
@@ -367,29 +397,29 @@
case SET_FORCE_USE: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- AudioSystem::force_use usage = static_cast <AudioSystem::force_use>(data.readInt32());
- AudioSystem::forced_config config =
- static_cast <AudioSystem::forced_config>(data.readInt32());
+ audio_policy_force_use_t usage = static_cast <audio_policy_force_use_t>(data.readInt32());
+ audio_policy_forced_cfg_t config =
+ static_cast <audio_policy_forced_cfg_t>(data.readInt32());
reply->writeInt32(static_cast <uint32_t>(setForceUse(usage, config)));
return NO_ERROR;
} break;
case GET_FORCE_USE: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- AudioSystem::force_use usage = static_cast <AudioSystem::force_use>(data.readInt32());
+ audio_policy_force_use_t usage = static_cast <audio_policy_force_use_t>(data.readInt32());
reply->writeInt32(static_cast <uint32_t>(getForceUse(usage)));
return NO_ERROR;
} break;
case GET_OUTPUT: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- AudioSystem::stream_type stream =
- static_cast <AudioSystem::stream_type>(data.readInt32());
+ audio_stream_type_t stream =
+ static_cast <audio_stream_type_t>(data.readInt32());
uint32_t samplingRate = data.readInt32();
uint32_t format = data.readInt32();
uint32_t channels = data.readInt32();
- AudioSystem::output_flags flags =
- static_cast <AudioSystem::output_flags>(data.readInt32());
+ audio_policy_output_flags_t flags =
+ static_cast <audio_policy_output_flags_t>(data.readInt32());
audio_io_handle_t output = getOutput(stream,
samplingRate,
@@ -406,7 +436,7 @@
uint32_t stream = data.readInt32();
int session = data.readInt32();
reply->writeInt32(static_cast <uint32_t>(startOutput(output,
- (AudioSystem::stream_type)stream,
+ (audio_stream_type_t)stream,
session)));
return NO_ERROR;
} break;
@@ -417,7 +447,7 @@
uint32_t stream = data.readInt32();
int session = data.readInt32();
reply->writeInt32(static_cast <uint32_t>(stopOutput(output,
- (AudioSystem::stream_type)stream,
+ (audio_stream_type_t)stream,
session)));
return NO_ERROR;
} break;
@@ -435,13 +465,15 @@
uint32_t samplingRate = data.readInt32();
uint32_t format = data.readInt32();
uint32_t channels = data.readInt32();
- AudioSystem::audio_in_acoustics acoustics =
- static_cast <AudioSystem::audio_in_acoustics>(data.readInt32());
+ audio_in_acoustics_t acoustics =
+ static_cast <audio_in_acoustics_t>(data.readInt32());
+ int audioSession = data.readInt32();
audio_io_handle_t input = getInput(inputSource,
samplingRate,
format,
channels,
- acoustics);
+ acoustics,
+ audioSession);
reply->writeInt32(static_cast <int>(input));
return NO_ERROR;
} break;
@@ -469,8 +501,8 @@
case INIT_STREAM_VOLUME: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- AudioSystem::stream_type stream =
- static_cast <AudioSystem::stream_type>(data.readInt32());
+ audio_stream_type_t stream =
+ static_cast <audio_stream_type_t>(data.readInt32());
int indexMin = data.readInt32();
int indexMax = data.readInt32();
reply->writeInt32(static_cast <uint32_t>(initStreamVolume(stream, indexMin,indexMax)));
@@ -479,8 +511,8 @@
case SET_STREAM_VOLUME: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- AudioSystem::stream_type stream =
- static_cast <AudioSystem::stream_type>(data.readInt32());
+ audio_stream_type_t stream =
+ static_cast <audio_stream_type_t>(data.readInt32());
int index = data.readInt32();
reply->writeInt32(static_cast <uint32_t>(setStreamVolumeIndex(stream, index)));
return NO_ERROR;
@@ -488,8 +520,8 @@
case GET_STREAM_VOLUME: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- AudioSystem::stream_type stream =
- static_cast <AudioSystem::stream_type>(data.readInt32());
+ audio_stream_type_t stream =
+ static_cast <audio_stream_type_t>(data.readInt32());
int index;
status_t status = getStreamVolumeIndex(stream, &index);
reply->writeInt32(index);
@@ -499,16 +531,16 @@
case GET_STRATEGY_FOR_STREAM: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- AudioSystem::stream_type stream =
- static_cast <AudioSystem::stream_type>(data.readInt32());
+ audio_stream_type_t stream =
+ static_cast <audio_stream_type_t>(data.readInt32());
reply->writeInt32(getStrategyForStream(stream));
return NO_ERROR;
} break;
case GET_DEVICES_FOR_STREAM: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- AudioSystem::stream_type stream =
- static_cast <AudioSystem::stream_type>(data.readInt32());
+ audio_stream_type_t stream =
+ static_cast <audio_stream_type_t>(data.readInt32());
reply->writeInt32(static_cast <int>(getDevicesForStream(stream)));
return NO_ERROR;
} break;
@@ -526,12 +558,12 @@
CHECK_INTERFACE(IAudioPolicyService, data, reply);
effect_descriptor_t desc;
data.read(&desc, sizeof(effect_descriptor_t));
- audio_io_handle_t output = data.readInt32();
+ audio_io_handle_t io = data.readInt32();
uint32_t strategy = data.readInt32();
int session = data.readInt32();
int id = data.readInt32();
reply->writeInt32(static_cast <int32_t>(registerEffect(&desc,
- output,
+ io,
strategy,
session,
id)));
@@ -553,6 +585,29 @@
return NO_ERROR;
} break;
+ case QUERY_DEFAULT_PRE_PROCESSING: {
+ CHECK_INTERFACE(IAudioPolicyService, data, reply);
+ int audioSession = data.readInt32();
+ uint32_t count = data.readInt32();
+ uint32_t retCount = count;
+ effect_descriptor_t *descriptors =
+ (effect_descriptor_t *)new char[count * sizeof(effect_descriptor_t)];
+ status_t status = queryDefaultPreProcessing(audioSession, descriptors, &retCount);
+ reply->writeInt32(status);
+ if (status != NO_ERROR && status != NO_MEMORY) {
+ retCount = 0;
+ }
+ reply->writeInt32(retCount);
+ if (retCount) {
+ if (retCount < count) {
+ count = retCount;
+ }
+ reply->write(descriptors, sizeof(effect_descriptor_t) * count);
+ }
+ delete[] descriptors;
+ return status;
+ }
+
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/media/libmedia/IMediaMetadataRetriever.cpp b/media/libmedia/IMediaMetadataRetriever.cpp
index d5298c9..07152d8 100644
--- a/media/libmedia/IMediaMetadataRetriever.cpp
+++ b/media/libmedia/IMediaMetadataRetriever.cpp
@@ -20,6 +20,7 @@
#include <binder/Parcel.h>
#include <SkBitmap.h>
#include <media/IMediaMetadataRetriever.h>
+#include <utils/String8.h>
// The binder is supposed to propagate the scheduler group across
// the binder interface so that remote calls are executed with
@@ -29,26 +30,6 @@
// foreground thread.
#ifndef DISABLE_GROUP_SCHEDULE_HACK
-/* desktop Linux needs a little help with gettid() */
-#if defined(HAVE_GETTID) && !defined(HAVE_ANDROID_OS)
-#define __KERNEL__
-# include <linux/unistd.h>
-#ifdef _syscall0
-_syscall0(pid_t,gettid)
-#else
-pid_t gettid() { return syscall(__NR_gettid);}
-#endif
-#undef __KERNEL__
-#endif
-
-static int myTid() {
-#ifdef HAVE_GETTID
- return gettid();
-#else
- return getpid();
-#endif
-}
-
#undef LOG_TAG
#define LOG_TAG "IMediaMetadataRetriever"
#include <utils/Log.h>
@@ -59,18 +40,18 @@
static void sendSchedPolicy(Parcel& data)
{
SchedPolicy policy;
- get_sched_policy(myTid(), &policy);
+ get_sched_policy(gettid(), &policy);
data.writeInt32(policy);
}
static void setSchedPolicy(const Parcel& data)
{
SchedPolicy policy = (SchedPolicy) data.readInt32();
- set_sched_policy(myTid(), policy);
+ set_sched_policy(gettid(), policy);
}
static void restoreSchedPolicy()
{
- set_sched_policy(myTid(), SP_FOREGROUND);
+ set_sched_policy(gettid(), SP_FOREGROUND);
}
}; // end namespace android
#endif
@@ -102,11 +83,24 @@
remote()->transact(DISCONNECT, data, &reply);
}
- status_t setDataSource(const char* srcUrl)
+ status_t setDataSource(
+ const char *srcUrl, const KeyedVector<String8, String8> *headers)
{
Parcel data, reply;
data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor());
data.writeCString(srcUrl);
+
+ if (headers == NULL) {
+ data.writeInt32(0);
+ } else {
+ // serialize the headers
+ data.writeInt32(headers->size());
+ for (size_t i = 0; i < headers->size(); ++i) {
+ data.writeString8(headers->keyAt(i));
+ data.writeString8(headers->valueAt(i));
+ }
+ }
+
remote()->transact(SET_DATA_SOURCE_URL, data, &reply);
return reply.readInt32();
}
@@ -188,7 +182,18 @@
case SET_DATA_SOURCE_URL: {
CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
const char* srcUrl = data.readCString();
- reply->writeInt32(setDataSource(srcUrl));
+
+ KeyedVector<String8, String8> headers;
+ int32_t numHeaders = data.readInt32();
+ for (int i = 0; i < numHeaders; ++i) {
+ String8 key = data.readString8();
+ String8 value = data.readString8();
+ headers.add(key, value);
+ }
+
+ reply->writeInt32(
+ setDataSource(srcUrl, numHeaders > 0 ? &headers : NULL));
+
return NO_ERROR;
} break;
case SET_DATA_SOURCE_FD: {
diff --git a/media/libmedia/IMediaPlayer.cpp b/media/libmedia/IMediaPlayer.cpp
index 2399216..52885d2 100644
--- a/media/libmedia/IMediaPlayer.cpp
+++ b/media/libmedia/IMediaPlayer.cpp
@@ -48,6 +48,8 @@
SET_AUX_EFFECT_SEND_LEVEL,
ATTACH_AUX_EFFECT,
SET_VIDEO_SURFACETEXTURE,
+ SET_PARAMETER,
+ GET_PARAMETER,
};
class BpMediaPlayer: public BpInterface<IMediaPlayer>
@@ -192,8 +194,9 @@
}
status_t invoke(const Parcel& request, Parcel *reply)
- { // Avoid doing any extra copy. The interface descriptor should
- // have been set by MediaPlayer.java.
+ {
+ // Avoid doing any extra copy. The interface descriptor should
+ // have been set by MediaPlayer.java.
return remote()->transact(INVOKE, request, reply);
}
@@ -235,6 +238,26 @@
return reply.readInt32();
}
+ status_t setParameter(int key, const Parcel& request)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
+ data.writeInt32(key);
+ if (request.dataSize() > 0) {
+ data.appendFrom(const_cast<Parcel *>(&request), 0, request.dataSize());
+ }
+ remote()->transact(SET_PARAMETER, data, &reply);
+ return reply.readInt32();
+ }
+
+ status_t getParameter(int key, Parcel *reply)
+ {
+ Parcel data;
+ data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
+ data.writeInt32(key);
+ return remote()->transact(GET_PARAMETER, data, reply);
+ }
+
};
IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer");
@@ -329,13 +352,15 @@
} break;
case SET_VOLUME: {
CHECK_INTERFACE(IMediaPlayer, data, reply);
- reply->writeInt32(setVolume(data.readFloat(), data.readFloat()));
+ float leftVolume = data.readFloat();
+ float rightVolume = data.readFloat();
+ reply->writeInt32(setVolume(leftVolume, rightVolume));
return NO_ERROR;
} break;
case INVOKE: {
CHECK_INTERFACE(IMediaPlayer, data, reply);
- invoke(data, reply);
- return NO_ERROR;
+ status_t result = invoke(data, reply);
+ return result;
} break;
case SET_METADATA_FILTER: {
CHECK_INTERFACE(IMediaPlayer, data, reply);
@@ -344,7 +369,9 @@
} break;
case GET_METADATA: {
CHECK_INTERFACE(IMediaPlayer, data, reply);
- const status_t retcode = getMetadata(data.readInt32(), data.readInt32(), reply);
+ bool update_only = static_cast<bool>(data.readInt32());
+ bool apply_filter = static_cast<bool>(data.readInt32());
+ const status_t retcode = getMetadata(update_only, apply_filter, reply);
reply->setDataPosition(0);
reply->writeInt32(retcode);
reply->setDataPosition(0);
@@ -360,6 +387,23 @@
reply->writeInt32(attachAuxEffect(data.readInt32()));
return NO_ERROR;
} break;
+ case SET_PARAMETER: {
+ CHECK_INTERFACE(IMediaPlayer, data, reply);
+ int key = data.readInt32();
+
+ Parcel request;
+ if (data.dataAvail() > 0) {
+ request.appendFrom(
+ const_cast<Parcel *>(&data), data.dataPosition(), data.dataAvail());
+ }
+ request.setDataPosition(0);
+ reply->writeInt32(setParameter(key, request));
+ return NO_ERROR;
+ } break;
+ case GET_PARAMETER: {
+ CHECK_INTERFACE(IMediaPlayer, data, reply);
+ return getParameter(data.readInt32(), reply);
+ } break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/media/libmedia/IMediaPlayerClient.cpp b/media/libmedia/IMediaPlayerClient.cpp
index bf51829..1f135c4 100644
--- a/media/libmedia/IMediaPlayerClient.cpp
+++ b/media/libmedia/IMediaPlayerClient.cpp
@@ -35,13 +35,16 @@
{
}
- virtual void notify(int msg, int ext1, int ext2)
+ virtual void notify(int msg, int ext1, int ext2, const Parcel *obj)
{
Parcel data, reply;
data.writeInterfaceToken(IMediaPlayerClient::getInterfaceDescriptor());
data.writeInt32(msg);
data.writeInt32(ext1);
data.writeInt32(ext2);
+ if (obj && obj->dataSize() > 0) {
+ data.appendFrom(const_cast<Parcel *>(obj), 0, obj->dataSize());
+ }
remote()->transact(NOTIFY, data, &reply, IBinder::FLAG_ONEWAY);
}
};
@@ -59,7 +62,12 @@
int msg = data.readInt32();
int ext1 = data.readInt32();
int ext2 = data.readInt32();
- notify(msg, ext1, ext2);
+ Parcel obj;
+ if (data.dataAvail() > 0) {
+ obj.appendFrom(const_cast<Parcel *>(&data), data.dataPosition(), data.dataAvail());
+ }
+
+ notify(msg, ext1, ext2, &obj);
return NO_ERROR;
} break;
default:
diff --git a/media/libmedia/IMediaRecorder.cpp b/media/libmedia/IMediaRecorder.cpp
index 59cd1b7..38e111e 100644
--- a/media/libmedia/IMediaRecorder.cpp
+++ b/media/libmedia/IMediaRecorder.cpp
@@ -23,14 +23,17 @@
#include <camera/ICamera.h>
#include <media/IMediaRecorderClient.h>
#include <media/IMediaRecorder.h>
+#include <gui/ISurfaceTexture.h>
#include <unistd.h>
+
namespace android {
enum {
RELEASE = IBinder::FIRST_CALL_TRANSACTION,
INIT,
CLOSE,
+ QUERY_SURFACE_MEDIASOURCE,
RESET,
STOP,
START,
@@ -43,7 +46,6 @@
SET_AUDIO_ENCODER,
SET_OUTPUT_FILE_PATH,
SET_OUTPUT_FILE_FD,
- SET_OUTPUT_FILE_AUXILIARY_FD,
SET_VIDEO_SIZE,
SET_VIDEO_FRAMERATE,
SET_PARAMETERS,
@@ -60,16 +62,30 @@
{
}
- status_t setCamera(const sp<ICamera>& camera)
+ status_t setCamera(const sp<ICamera>& camera, const sp<ICameraRecordingProxy>& proxy)
{
- LOGV("setCamera(%p)", camera.get());
+ LOGV("setCamera(%p,%p)", camera.get(), proxy.get());
Parcel data, reply;
data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
data.writeStrongBinder(camera->asBinder());
+ data.writeStrongBinder(proxy->asBinder());
remote()->transact(SET_CAMERA, data, &reply);
return reply.readInt32();
}
+ sp<ISurfaceTexture> querySurfaceMediaSource()
+ {
+ LOGV("Query SurfaceMediaSource");
+ Parcel data, reply;
+ data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
+ remote()->transact(QUERY_SURFACE_MEDIASOURCE, data, &reply);
+ int returnedNull = reply.readInt32();
+ if (returnedNull) {
+ return NULL;
+ }
+ return interface_cast<ISurfaceTexture>(reply.readStrongBinder());
+ }
+
status_t setPreviewSurface(const sp<Surface>& surface)
{
LOGV("setPreviewSurface(%p)", surface.get());
@@ -160,15 +176,6 @@
return reply.readInt32();
}
- status_t setOutputFileAuxiliary(int fd) {
- LOGV("setOutputFileAuxiliary(%d)", fd);
- Parcel data, reply;
- data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
- data.writeFileDescriptor(fd);
- remote()->transact(SET_OUTPUT_FILE_AUXILIARY_FD, data, &reply);
- return reply.readInt32();
- }
-
status_t setVideoSize(int width, int height)
{
LOGV("setVideoSize(%dx%d)", width, height);
@@ -387,13 +394,6 @@
::close(fd);
return NO_ERROR;
} break;
- case SET_OUTPUT_FILE_AUXILIARY_FD: {
- LOGV("SET_OUTPUT_FILE_AUXILIARY_FD");
- CHECK_INTERFACE(IMediaRecorder, data, reply);
- int fd = dup(data.readFileDescriptor());
- reply->writeInt32(setOutputFileAuxiliary(fd));
- return NO_ERROR;
- } break;
case SET_VIDEO_SIZE: {
LOGV("SET_VIDEO_SIZE");
CHECK_INTERFACE(IMediaRecorder, data, reply);
@@ -434,7 +434,23 @@
LOGV("SET_CAMERA");
CHECK_INTERFACE(IMediaRecorder, data, reply);
sp<ICamera> camera = interface_cast<ICamera>(data.readStrongBinder());
- reply->writeInt32(setCamera(camera));
+ sp<ICameraRecordingProxy> proxy =
+ interface_cast<ICameraRecordingProxy>(data.readStrongBinder());
+ reply->writeInt32(setCamera(camera, proxy));
+ return NO_ERROR;
+ } break;
+ case QUERY_SURFACE_MEDIASOURCE: {
+ LOGV("QUERY_SURFACE_MEDIASOURCE");
+ CHECK_INTERFACE(IMediaRecorder, data, reply);
+ // call the mediaserver side to create
+ // a surfacemediasource
+ sp<ISurfaceTexture> surfaceMediaSource = querySurfaceMediaSource();
+ // The mediaserver might have failed to create a source
+ int returnedNull= (surfaceMediaSource == NULL) ? 1 : 0 ;
+ reply->writeInt32(returnedNull);
+ if (!returnedNull) {
+ reply->writeStrongBinder(surfaceMediaSource->asBinder());
+ }
return NO_ERROR;
} break;
default:
diff --git a/media/libmedia/IStreamSource.cpp b/media/libmedia/IStreamSource.cpp
index c14ee82..b311f35 100644
--- a/media/libmedia/IStreamSource.cpp
+++ b/media/libmedia/IStreamSource.cpp
@@ -29,6 +29,9 @@
// static
const char *const IStreamListener::kKeyResumeAtPTS = "resume-at-PTS";
+// static
+const char *const IStreamListener::kKeyFormatChange = "format-change";
+
enum {
// IStreamSource
SET_LISTENER = IBinder::FIRST_CALL_TRANSACTION,
diff --git a/media/libmedia/JetPlayer.cpp b/media/libmedia/JetPlayer.cpp
index ee9e1d8..8b953e0 100644
--- a/media/libmedia/JetPlayer.cpp
+++ b/media/libmedia/JetPlayer.cpp
@@ -23,13 +23,6 @@
#include <media/JetPlayer.h>
-#ifdef HAVE_GETTID
-static pid_t myTid() { return gettid(); }
-#else
-static pid_t myTid() { return getpid(); }
-#endif
-
-
namespace android
{
@@ -96,10 +89,10 @@
// create the output AudioTrack
mAudioTrack = new AudioTrack();
- mAudioTrack->set(AudioSystem::MUSIC, //TODO parametrize this
+ mAudioTrack->set(AUDIO_STREAM_MUSIC, //TODO parametrize this
pLibConfig->sampleRate,
1, // format = PCM 16bits per sample,
- (pLibConfig->numChannels == 2) ? AudioSystem::CHANNEL_OUT_STEREO : AudioSystem::CHANNEL_OUT_MONO,
+ (pLibConfig->numChannels == 2) ? AUDIO_CHANNEL_OUT_STEREO : AUDIO_CHANNEL_OUT_MONO,
mTrackBufferSize,
0);
@@ -188,7 +181,7 @@
// signal main thread that we started
{
Mutex::Autolock l(mMutex);
- mTid = myTid();
+ mTid = gettid();
LOGV("JetPlayer::render(): render thread(%d) signal", mTid);
mCondition.signal();
}
diff --git a/media/libmedia/MediaProfiles.cpp b/media/libmedia/MediaProfiles.cpp
index e6f3a33..f0f07a2 100644
--- a/media/libmedia/MediaProfiles.cpp
+++ b/media/libmedia/MediaProfiles.cpp
@@ -132,6 +132,16 @@
LOGV("codec = %d", cap.mCodec);
}
+/*static*/ void
+MediaProfiles::logVideoEditorCap(const MediaProfiles::VideoEditorCap& cap)
+{
+ LOGV("videoeditor cap:");
+ LOGV("mMaxInputFrameWidth = %d", cap.mMaxInputFrameWidth);
+ LOGV("mMaxInputFrameHeight = %d", cap.mMaxInputFrameHeight);
+ LOGV("mMaxOutputFrameWidth = %d", cap.mMaxOutputFrameWidth);
+ LOGV("mMaxOutputFrameHeight = %d", cap.mMaxOutputFrameHeight);
+}
+
/*static*/ int
MediaProfiles::findTagForName(const MediaProfiles::NameToTagMap *map, size_t nMappings, const char *name)
{
@@ -356,6 +366,36 @@
return atoi(atts[1]);
}
+void MediaProfiles::addStartTimeOffset(int cameraId, const char** atts)
+{
+ int offsetTimeMs = 700;
+ if (atts[2]) {
+ CHECK(!strcmp("startOffsetMs", atts[2]));
+ offsetTimeMs = atoi(atts[3]);
+ }
+
+ LOGV("%s: cameraId=%d, offset=%d ms", __func__, cameraId, offsetTimeMs);
+ mStartTimeOffsets.replaceValueFor(cameraId, offsetTimeMs);
+}
+
+/*static*/ MediaProfiles::VideoEditorCap*
+MediaProfiles::createVideoEditorCap(const char **atts, MediaProfiles *profiles)
+{
+ CHECK(!strcmp("maxInputFrameWidth", atts[0]) &&
+ !strcmp("maxInputFrameHeight", atts[2]) &&
+ !strcmp("maxOutputFrameWidth", atts[4]) &&
+ !strcmp("maxOutputFrameHeight", atts[6]));
+
+ MediaProfiles::VideoEditorCap *pVideoEditorCap =
+ new MediaProfiles::VideoEditorCap(atoi(atts[1]), atoi(atts[3]),
+ atoi(atts[5]), atoi(atts[7]));
+
+ logVideoEditorCap(*pVideoEditorCap);
+ profiles->mVideoEditorCap = pVideoEditorCap;
+
+ return pVideoEditorCap;
+}
+
/*static*/ void
MediaProfiles::startElementHandler(void *userData, const char *name, const char **atts)
{
@@ -380,11 +420,14 @@
profiles->mEncoderOutputFileFormats.add(createEncoderOutputFileFormat(atts));
} else if (strcmp("CamcorderProfiles", name) == 0) {
profiles->mCurrentCameraId = getCameraId(atts);
+ profiles->addStartTimeOffset(profiles->mCurrentCameraId, atts);
} else if (strcmp("EncoderProfile", name) == 0) {
profiles->mCamcorderProfiles.add(
createCamcorderProfile(profiles->mCurrentCameraId, atts, profiles->mCameraIds));
} else if (strcmp("ImageEncoding", name) == 0) {
profiles->addImageEncodingQualityLevel(profiles->mCurrentCameraId, atts);
+ } else if (strcmp("VideoEditorCap", name) == 0) {
+ createVideoEditorCap(atts, profiles);
}
}
@@ -777,6 +820,17 @@
profiles->mImageEncodingQualityLevels.add(levels);
}
+/*static*/ void
+MediaProfiles::createDefaultVideoEditorCap(MediaProfiles *profiles)
+{
+ profiles->mVideoEditorCap =
+ new MediaProfiles::VideoEditorCap(
+ VIDEOEDITOR_DEFAULT_MAX_INPUT_FRAME_WIDTH,
+ VIDEOEDITOR_DEFUALT_MAX_INPUT_FRAME_HEIGHT,
+ VIDEOEDITOR_DEFAULT_MAX_OUTPUT_FRAME_WIDTH,
+ VIDEOEDITOR_DEFUALT_MAX_OUTPUT_FRAME_HEIGHT);
+}
+
/*static*/ MediaProfiles*
MediaProfiles::createDefaultInstance()
{
@@ -788,6 +842,7 @@
createDefaultAudioDecoders(profiles);
createDefaultEncoderOutputFileFormats(profiles);
createDefaultImageEncodingQualityLevels(profiles);
+ createDefaultVideoEditorCap(profiles);
return profiles;
}
@@ -886,6 +941,28 @@
return -1;
}
+int MediaProfiles::getVideoEditorCapParamByName(const char *name) const
+{
+ LOGV("getVideoEditorCapParamByName: %s", name);
+
+ if (mVideoEditorCap == NULL) {
+ LOGE("The mVideoEditorCap is not created, then create default cap.");
+ createDefaultVideoEditorCap(sInstance);
+ }
+
+ if (!strcmp("videoeditor.input.width.max", name))
+ return mVideoEditorCap->mMaxInputFrameWidth;
+ if (!strcmp("videoeditor.input.height.max", name))
+ return mVideoEditorCap->mMaxInputFrameHeight;
+ if (!strcmp("videoeditor.output.width.max", name))
+ return mVideoEditorCap->mMaxOutputFrameWidth;
+ if (!strcmp("videoeditor.output.height.max", name))
+ return mVideoEditorCap->mMaxOutputFrameHeight;
+
+ LOGE("The given video editor param name %s is not found", name);
+ return -1;
+}
+
Vector<audio_encoder> MediaProfiles::getAudioEncoders() const
{
Vector<audio_encoder> encoders;
@@ -997,6 +1074,16 @@
return result;
}
+int MediaProfiles::getStartTimeOffsetMs(int cameraId) const {
+ int offsetTimeMs = -1;
+ ssize_t index = mStartTimeOffsets.indexOfKey(cameraId);
+ if (index >= 0) {
+ offsetTimeMs = mStartTimeOffsets.valueFor(cameraId);
+ }
+ LOGV("%s: offsetTime=%d ms and cameraId=%d", offsetTimeMs, cameraId);
+ return offsetTimeMs;
+}
+
MediaProfiles::~MediaProfiles()
{
CHECK("destructor should never be called" == 0);
diff --git a/media/libmedia/MediaScanner.cpp b/media/libmedia/MediaScanner.cpp
index 45bdff4..41f8593 100644
--- a/media/libmedia/MediaScanner.cpp
+++ b/media/libmedia/MediaScanner.cpp
@@ -47,16 +47,15 @@
return mLocale;
}
-status_t MediaScanner::processDirectory(
- const char *path, MediaScannerClient &client,
- ExceptionCheck exceptionCheck, void *exceptionEnv) {
+MediaScanResult MediaScanner::processDirectory(
+ const char *path, MediaScannerClient &client) {
int pathLength = strlen(path);
if (pathLength >= PATH_MAX) {
- return UNKNOWN_ERROR;
+ return MEDIA_SCAN_RESULT_SKIPPED;
}
char* pathBuffer = (char *)malloc(PATH_MAX + 1);
if (!pathBuffer) {
- return UNKNOWN_ERROR;
+ return MEDIA_SCAN_RESULT_ERROR;
}
int pathRemaining = PATH_MAX - pathLength;
@@ -69,21 +68,18 @@
client.setLocale(locale());
- status_t result =
- doProcessDirectory(pathBuffer, pathRemaining, client, false, exceptionCheck, exceptionEnv);
+ MediaScanResult result = doProcessDirectory(pathBuffer, pathRemaining, client, false);
free(pathBuffer);
return result;
}
-status_t MediaScanner::doProcessDirectory(
- char *path, int pathRemaining, MediaScannerClient &client,
- bool noMedia, ExceptionCheck exceptionCheck, void *exceptionEnv) {
+MediaScanResult MediaScanner::doProcessDirectory(
+ char *path, int pathRemaining, MediaScannerClient &client, bool noMedia) {
// place to copy file or directory name
char* fileSpot = path + strlen(path);
struct dirent* entry;
- struct stat statbuf;
// Treat all files as non-media in directories that contain a ".nomedia" file
if (pathRemaining >= 8 /* strlen(".nomedia") */ ) {
@@ -99,76 +95,88 @@
DIR* dir = opendir(path);
if (!dir) {
- LOGD("opendir %s failed, errno: %d", path, errno);
- return UNKNOWN_ERROR;
+ LOGW("Error opening directory '%s', skipping: %s.", path, strerror(errno));
+ return MEDIA_SCAN_RESULT_SKIPPED;
}
+ MediaScanResult result = MEDIA_SCAN_RESULT_OK;
while ((entry = readdir(dir))) {
- const char* name = entry->d_name;
-
- // ignore "." and ".."
- if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) {
- continue;
+ if (doProcessDirectoryEntry(path, pathRemaining, client, noMedia, entry, fileSpot)
+ == MEDIA_SCAN_RESULT_ERROR) {
+ result = MEDIA_SCAN_RESULT_ERROR;
+ break;
}
+ }
+ closedir(dir);
+ return result;
+}
- int nameLength = strlen(name);
- if (nameLength + 1 > pathRemaining) {
- // path too long!
- continue;
+MediaScanResult MediaScanner::doProcessDirectoryEntry(
+ char *path, int pathRemaining, MediaScannerClient &client, bool noMedia,
+ struct dirent* entry, char* fileSpot) {
+ struct stat statbuf;
+ const char* name = entry->d_name;
+
+ // ignore "." and ".."
+ if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) {
+ return MEDIA_SCAN_RESULT_SKIPPED;
+ }
+
+ int nameLength = strlen(name);
+ if (nameLength + 1 > pathRemaining) {
+ // path too long!
+ return MEDIA_SCAN_RESULT_SKIPPED;
+ }
+ strcpy(fileSpot, name);
+
+ int type = entry->d_type;
+ if (type == DT_UNKNOWN) {
+ // If the type is unknown, stat() the file instead.
+ // This is sometimes necessary when accessing NFS mounted filesystems, but
+ // could be needed in other cases well.
+ if (stat(path, &statbuf) == 0) {
+ if (S_ISREG(statbuf.st_mode)) {
+ type = DT_REG;
+ } else if (S_ISDIR(statbuf.st_mode)) {
+ type = DT_DIR;
+ }
+ } else {
+ LOGD("stat() failed for %s: %s", path, strerror(errno) );
}
- strcpy(fileSpot, name);
+ }
+ if (type == DT_DIR) {
+ bool childNoMedia = noMedia;
+ // set noMedia flag on directories with a name that starts with '.'
+ // for example, the Mac ".Trashes" directory
+ if (name[0] == '.')
+ childNoMedia = true;
- int type = entry->d_type;
- if (type == DT_UNKNOWN) {
- // If the type is unknown, stat() the file instead.
- // This is sometimes necessary when accessing NFS mounted filesystems, but
- // could be needed in other cases well.
- if (stat(path, &statbuf) == 0) {
- if (S_ISREG(statbuf.st_mode)) {
- type = DT_REG;
- } else if (S_ISDIR(statbuf.st_mode)) {
- type = DT_DIR;
- }
- } else {
- LOGD("stat() failed for %s: %s", path, strerror(errno) );
+ // report the directory to the client
+ if (stat(path, &statbuf) == 0) {
+ status_t status = client.scanFile(path, statbuf.st_mtime, 0,
+ true /*isDirectory*/, childNoMedia);
+ if (status) {
+ return MEDIA_SCAN_RESULT_ERROR;
}
}
- if (type == DT_REG || type == DT_DIR) {
- if (type == DT_DIR) {
- bool childNoMedia = noMedia;
- // set noMedia flag on directories with a name that starts with '.'
- // for example, the Mac ".Trashes" directory
- if (name[0] == '.')
- childNoMedia = true;
- // report the directory to the client
- if (stat(path, &statbuf) == 0) {
- client.scanFile(path, statbuf.st_mtime, 0, true, childNoMedia);
- }
-
- // and now process its contents
- strcat(fileSpot, "/");
- int err = doProcessDirectory(path, pathRemaining - nameLength - 1, client,
- childNoMedia, exceptionCheck, exceptionEnv);
- if (err) {
- // pass exceptions up - ignore other errors
- if (exceptionCheck && exceptionCheck(exceptionEnv)) goto failure;
- LOGE("Error processing '%s' - skipping\n", path);
- continue;
- }
- } else {
- stat(path, &statbuf);
- client.scanFile(path, statbuf.st_mtime, statbuf.st_size, false, noMedia);
- if (exceptionCheck && exceptionCheck(exceptionEnv)) goto failure;
- }
+ // and now process its contents
+ strcat(fileSpot, "/");
+ MediaScanResult result = doProcessDirectory(path, pathRemaining - nameLength - 1,
+ client, childNoMedia);
+ if (result == MEDIA_SCAN_RESULT_ERROR) {
+ return MEDIA_SCAN_RESULT_ERROR;
+ }
+ } else if (type == DT_REG) {
+ stat(path, &statbuf);
+ status_t status = client.scanFile(path, statbuf.st_mtime, statbuf.st_size,
+ false /*isDirectory*/, noMedia);
+ if (status) {
+ return MEDIA_SCAN_RESULT_ERROR;
}
}
- closedir(dir);
- return OK;
-failure:
- closedir(dir);
- return -1;
+ return MEDIA_SCAN_RESULT_OK;
}
} // namespace android
diff --git a/media/libmedia/MediaScannerClient.cpp b/media/libmedia/MediaScannerClient.cpp
index bd3596e..7a7aeb6 100644
--- a/media/libmedia/MediaScannerClient.cpp
+++ b/media/libmedia/MediaScannerClient.cpp
@@ -62,7 +62,7 @@
mValues = new StringArray;
}
-bool MediaScannerClient::addStringTag(const char* name, const char* value)
+status_t MediaScannerClient::addStringTag(const char* name, const char* value)
{
if (mLocaleEncoding != kEncodingNone) {
// don't bother caching strings that are all ASCII.
@@ -212,8 +212,10 @@
// finally, push all name/value pairs to the client
for (int i = 0; i < mNames->size(); i++) {
- if (!handleStringTag(mNames->getEntry(i), mValues->getEntry(i)))
+ status_t status = handleStringTag(mNames->getEntry(i), mValues->getEntry(i));
+ if (status) {
break;
+ }
}
}
// else addStringTag() has done all the work so we have nothing to do
diff --git a/media/libmedia/MemoryLeakTrackUtil.cpp b/media/libmedia/MemoryLeakTrackUtil.cpp
new file mode 100644
index 0000000..6a108ae
--- /dev/null
+++ b/media/libmedia/MemoryLeakTrackUtil.cpp
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2011, 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.
+ */
+
+#include <media/MemoryLeakTrackUtil.h>
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+/*
+ * The code here originally resided in MediaPlayerService.cpp and was
+ * shamelessly copied over to support memory leak tracking from
+ * multiple places.
+ */
+namespace android {
+
+#if defined(__arm__)
+
+extern "C" void get_malloc_leak_info(uint8_t** info, size_t* overallSize,
+ size_t* infoSize, size_t* totalMemory, size_t* backtraceSize);
+
+extern "C" void free_malloc_leak_info(uint8_t* info);
+
+// Use the String-class below instead of String8 to allocate all memory
+// beforehand and not reenter the heap while we are examining it...
+struct MyString8 {
+ static const size_t MAX_SIZE = 256 * 1024;
+
+ MyString8()
+ : mPtr((char *)malloc(MAX_SIZE)) {
+ *mPtr = '\0';
+ }
+
+ ~MyString8() {
+ free(mPtr);
+ }
+
+ void append(const char *s) {
+ strcat(mPtr, s);
+ }
+
+ const char *string() const {
+ return mPtr;
+ }
+
+ size_t size() const {
+ return strlen(mPtr);
+ }
+
+private:
+ char *mPtr;
+
+ MyString8(const MyString8 &);
+ MyString8 &operator=(const MyString8 &);
+};
+
+void dumpMemoryAddresses(int fd)
+{
+ const size_t SIZE = 256;
+ char buffer[SIZE];
+ MyString8 result;
+
+ typedef struct {
+ size_t size;
+ size_t dups;
+ intptr_t * backtrace;
+ } AllocEntry;
+
+ uint8_t *info = NULL;
+ size_t overallSize = 0;
+ size_t infoSize = 0;
+ size_t totalMemory = 0;
+ size_t backtraceSize = 0;
+
+ get_malloc_leak_info(&info, &overallSize, &infoSize, &totalMemory, &backtraceSize);
+ if (info) {
+ uint8_t *ptr = info;
+ size_t count = overallSize / infoSize;
+
+ snprintf(buffer, SIZE, " Allocation count %i\n", count);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Total memory %i\n", totalMemory);
+ result.append(buffer);
+
+ AllocEntry * entries = new AllocEntry[count];
+
+ for (size_t i = 0; i < count; i++) {
+ // Each entry should be size_t, size_t, intptr_t[backtraceSize]
+ AllocEntry *e = &entries[i];
+
+ e->size = *reinterpret_cast<size_t *>(ptr);
+ ptr += sizeof(size_t);
+
+ e->dups = *reinterpret_cast<size_t *>(ptr);
+ ptr += sizeof(size_t);
+
+ e->backtrace = reinterpret_cast<intptr_t *>(ptr);
+ ptr += sizeof(intptr_t) * backtraceSize;
+ }
+
+ // Now we need to sort the entries. They come sorted by size but
+ // not by stack trace which causes problems using diff.
+ bool moved;
+ do {
+ moved = false;
+ for (size_t i = 0; i < (count - 1); i++) {
+ AllocEntry *e1 = &entries[i];
+ AllocEntry *e2 = &entries[i+1];
+
+ bool swap = e1->size < e2->size;
+ if (e1->size == e2->size) {
+ for(size_t j = 0; j < backtraceSize; j++) {
+ if (e1->backtrace[j] == e2->backtrace[j]) {
+ continue;
+ }
+ swap = e1->backtrace[j] < e2->backtrace[j];
+ break;
+ }
+ }
+ if (swap) {
+ AllocEntry t = entries[i];
+ entries[i] = entries[i+1];
+ entries[i+1] = t;
+ moved = true;
+ }
+ }
+ } while (moved);
+
+ for (size_t i = 0; i < count; i++) {
+ AllocEntry *e = &entries[i];
+
+ snprintf(buffer, SIZE, "size %8i, dup %4i, ", e->size, e->dups);
+ result.append(buffer);
+ for (size_t ct = 0; (ct < backtraceSize) && e->backtrace[ct]; ct++) {
+ if (ct) {
+ result.append(", ");
+ }
+ snprintf(buffer, SIZE, "0x%08x", e->backtrace[ct]);
+ result.append(buffer);
+ }
+ result.append("\n");
+ }
+
+ delete[] entries;
+ free_malloc_leak_info(info);
+ }
+
+ write(fd, result.string(), result.size());
+}
+
+#else
+// Does nothing
+void dumpMemoryAddresses(int fd) {}
+
+#endif
+} // namespace android
diff --git a/media/libmedia/Metadata.cpp b/media/libmedia/Metadata.cpp
index aec96f1..8eeebbb 100644
--- a/media/libmedia/Metadata.cpp
+++ b/media/libmedia/Metadata.cpp
@@ -32,7 +32,7 @@
// All these constants below must be kept in sync with Metadata.java.
enum MetadataId {
FIRST_SYSTEM_ID = 1,
- LAST_SYSTEM_ID = 32,
+ LAST_SYSTEM_ID = 31,
FIRST_CUSTOM_ID = 8192
};
@@ -43,7 +43,6 @@
BOOLEAN_VAL,
LONG_VAL,
DOUBLE_VAL,
- TIMED_TEXT_VAL,
DATE_VAL,
BYTE_ARRAY_VAL,
};
diff --git a/media/libmedia/ToneGenerator.cpp b/media/libmedia/ToneGenerator.cpp
index 82fe2d4..7c2200e 100644
--- a/media/libmedia/ToneGenerator.cpp
+++ b/media/libmedia/ToneGenerator.cpp
@@ -21,7 +21,6 @@
#include <stdio.h>
#include <math.h>
#include <utils/Log.h>
-#include <sys/resource.h>
#include <utils/RefBase.h>
#include <utils/Timers.h>
#include <cutils/properties.h>
@@ -1026,8 +1025,8 @@
mpAudioTrack->set(mStreamType,
0,
- AudioSystem::PCM_16_BIT,
- AudioSystem::CHANNEL_OUT_MONO,
+ AUDIO_FORMAT_PCM_16_BIT,
+ AUDIO_CHANNEL_OUT_MONO,
0,
0,
audioCallback,
diff --git a/media/libmedia/Visualizer.cpp b/media/libmedia/Visualizer.cpp
index 43571cf..bf40481 100644
--- a/media/libmedia/Visualizer.cpp
+++ b/media/libmedia/Visualizer.cpp
@@ -24,6 +24,8 @@
#include <sys/types.h>
#include <limits.h>
+#include <cutils/bitops.h>
+
#include <media/Visualizer.h>
extern void fixed_fft_real(int n, int32_t *v);
@@ -127,7 +129,7 @@
{
if (size > VISUALIZER_CAPTURE_SIZE_MAX ||
size < VISUALIZER_CAPTURE_SIZE_MIN ||
- AudioSystem::popCount(size) != 1) {
+ popcount(size) != 1) {
return BAD_VALUE;
}
@@ -141,7 +143,7 @@
p->psize = sizeof(uint32_t);
p->vsize = sizeof(uint32_t);
- *(int32_t *)p->data = VISU_PARAM_CAPTURE_SIZE;
+ *(int32_t *)p->data = VISUALIZER_PARAM_CAPTURE_SIZE;
*((int32_t *)p->data + 1)= size;
status_t status = setParameter(p);
@@ -169,7 +171,7 @@
status_t status = NO_ERROR;
if (mEnabled) {
uint32_t replySize = mCaptureSize;
- status = command(VISU_CMD_CAPTURE, 0, NULL, &replySize, waveform);
+ status = command(VISUALIZER_CMD_CAPTURE, 0, NULL, &replySize, waveform);
LOGV("getWaveForm() command returned %d", status);
if (replySize == 0) {
status = NOT_ENOUGH_DATA;
@@ -274,7 +276,7 @@
p->psize = sizeof(uint32_t);
p->vsize = sizeof(uint32_t);
- *(int32_t *)p->data = VISU_PARAM_CAPTURE_SIZE;
+ *(int32_t *)p->data = VISUALIZER_PARAM_CAPTURE_SIZE;
status_t status = getParameter(p);
if (status == NO_ERROR) {
diff --git a/media/libmedia/mediametadataretriever.cpp b/media/libmedia/mediametadataretriever.cpp
index 8dfcb3b..cee06ab 100644
--- a/media/libmedia/mediametadataretriever.cpp
+++ b/media/libmedia/mediametadataretriever.cpp
@@ -92,7 +92,8 @@
}
}
-status_t MediaMetadataRetriever::setDataSource(const char* srcUrl)
+status_t MediaMetadataRetriever::setDataSource(
+ const char *srcUrl, const KeyedVector<String8, String8> *headers)
{
LOGV("setDataSource");
Mutex::Autolock _l(mLock);
@@ -105,7 +106,7 @@
return UNKNOWN_ERROR;
}
LOGV("data source (%s)", srcUrl);
- return mRetriever->setDataSource(srcUrl);
+ return mRetriever->setDataSource(srcUrl, headers);
}
status_t MediaMetadataRetriever::setDataSource(int fd, int64_t offset, int64_t length)
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index 0ee0249..3dd9249 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -27,6 +27,8 @@
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
+#include <gui/SurfaceTextureClient.h>
+
#include <media/mediaplayer.h>
#include <media/AudioTrack.h>
@@ -37,6 +39,9 @@
#include <utils/KeyedVector.h>
#include <utils/String8.h>
+#include <system/audio.h>
+#include <system/window.h>
+
namespace android {
MediaPlayer::MediaPlayer()
@@ -45,7 +50,7 @@
mListener = NULL;
mCookie = NULL;
mDuration = -1;
- mStreamType = AudioSystem::MUSIC;
+ mStreamType = AUDIO_STREAM_MUSIC;
mCurrentPosition = -1;
mSeekPosition = -1;
mCurrentState = MEDIA_PLAYER_IDLE;
@@ -79,6 +84,8 @@
if (p != 0) {
p->disconnect();
}
+
+ disconnectNativeWindow();
}
// always call with lock held
@@ -192,13 +199,63 @@
return mPlayer->getMetadata(update_only, apply_filter, metadata);
}
+void MediaPlayer::disconnectNativeWindow() {
+ if (mConnectedWindow != NULL) {
+ status_t err = native_window_api_disconnect(mConnectedWindow.get(),
+ NATIVE_WINDOW_API_MEDIA);
+
+ if (err != OK) {
+ LOGW("native_window_api_disconnect returned an error: %s (%d)",
+ strerror(-err), err);
+ }
+ }
+ mConnectedWindow.clear();
+}
+
status_t MediaPlayer::setVideoSurface(const sp<Surface>& surface)
{
LOGV("setVideoSurface");
Mutex::Autolock _l(mLock);
if (mPlayer == 0) return NO_INIT;
- return mPlayer->setVideoSurface(surface);
+ sp<IBinder> binder(surface == NULL ? NULL : surface->asBinder());
+ if (mConnectedWindowBinder == binder) {
+ return OK;
+ }
+
+ if (surface != NULL) {
+ status_t err = native_window_api_connect(surface.get(),
+ NATIVE_WINDOW_API_MEDIA);
+
+ if (err != OK) {
+ LOGE("setVideoSurface failed: %d", err);
+ // Note that we must do the reset before disconnecting from the ANW.
+ // Otherwise queue/dequeue calls could be made on the disconnected
+ // ANW, which may result in errors.
+ reset_l();
+
+ disconnectNativeWindow();
+
+ return err;
+ }
+ }
+
+ // Note that we must set the player's new surface before disconnecting the
+ // old one. Otherwise queue/dequeue calls could be made on the disconnected
+ // ANW, which may result in errors.
+ status_t err = mPlayer->setVideoSurface(surface);
+
+ disconnectNativeWindow();
+
+ mConnectedWindow = surface;
+
+ if (err == OK) {
+ mConnectedWindowBinder = binder;
+ } else {
+ disconnectNativeWindow();
+ }
+
+ return err;
}
status_t MediaPlayer::setVideoSurfaceTexture(
@@ -208,7 +265,47 @@
Mutex::Autolock _l(mLock);
if (mPlayer == 0) return NO_INIT;
- return mPlayer->setVideoSurfaceTexture(surfaceTexture);
+ sp<IBinder> binder(surfaceTexture == NULL ? NULL :
+ surfaceTexture->asBinder());
+ if (mConnectedWindowBinder == binder) {
+ return OK;
+ }
+
+ sp<ANativeWindow> anw;
+ if (surfaceTexture != NULL) {
+ anw = new SurfaceTextureClient(surfaceTexture);
+ status_t err = native_window_api_connect(anw.get(),
+ NATIVE_WINDOW_API_MEDIA);
+
+ if (err != OK) {
+ LOGE("setVideoSurfaceTexture failed: %d", err);
+ // Note that we must do the reset before disconnecting from the ANW.
+ // Otherwise queue/dequeue calls could be made on the disconnected
+ // ANW, which may result in errors.
+ reset_l();
+
+ disconnectNativeWindow();
+
+ return err;
+ }
+ }
+
+ // Note that we must set the player's new SurfaceTexture before
+ // disconnecting the old one. Otherwise queue/dequeue calls could be made
+ // on the disconnected ANW, which may result in errors.
+ status_t err = mPlayer->setVideoSurfaceTexture(surfaceTexture);
+
+ disconnectNativeWindow();
+
+ mConnectedWindow = anw;
+
+ if (err == OK) {
+ mConnectedWindowBinder = binder;
+ } else {
+ disconnectNativeWindow();
+ }
+
+ return err;
}
// must call with lock held
@@ -432,10 +529,8 @@
return result;
}
-status_t MediaPlayer::reset()
+status_t MediaPlayer::reset_l()
{
- LOGV("reset");
- Mutex::Autolock _l(mLock);
mLoop = false;
if (mCurrentState == MEDIA_PLAYER_IDLE) return NO_ERROR;
mPrepareSync = false;
@@ -456,6 +551,13 @@
return NO_ERROR;
}
+status_t MediaPlayer::reset()
+{
+ LOGV("reset");
+ Mutex::Autolock _l(mLock);
+ return reset_l();
+}
+
status_t MediaPlayer::setAudioStreamType(int type)
{
LOGV("MediaPlayer::setAudioStreamType");
@@ -551,7 +653,29 @@
return mPlayer->attachAuxEffect(effectId);
}
-void MediaPlayer::notify(int msg, int ext1, int ext2)
+status_t MediaPlayer::setParameter(int key, const Parcel& request)
+{
+ LOGV("MediaPlayer::setParameter(%d)", key);
+ Mutex::Autolock _l(mLock);
+ if (mPlayer != NULL) {
+ return mPlayer->setParameter(key, request);
+ }
+ LOGV("setParameter: no active player");
+ return INVALID_OPERATION;
+}
+
+status_t MediaPlayer::getParameter(int key, Parcel *reply)
+{
+ LOGV("MediaPlayer::getParameter(%d)", key);
+ Mutex::Autolock _l(mLock);
+ if (mPlayer != NULL) {
+ return mPlayer->getParameter(key, reply);
+ }
+ LOGV("getParameter: no active player");
+ return INVALID_OPERATION;
+}
+
+void MediaPlayer::notify(int msg, int ext1, int ext2, const Parcel *obj)
{
LOGV("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2);
bool send = true;
@@ -641,6 +765,9 @@
mVideoWidth = ext1;
mVideoHeight = ext2;
break;
+ case MEDIA_TIMED_TEXT:
+ LOGV("Received timed text message");
+ break;
default:
LOGV("unrecognized message: (%d, %d, %d)", msg, ext1, ext2);
break;
@@ -653,7 +780,7 @@
if ((listener != 0) && send) {
Mutex::Autolock _l(mNotifyLock);
LOGV("callback application");
- listener->notify(msg, ext1, ext2);
+ listener->notify(msg, ext1, ext2, obj);
LOGV("back from callback");
}
}
diff --git a/media/libmedia/mediarecorder.cpp b/media/libmedia/mediarecorder.cpp
index 0100a17..11d281f 100644
--- a/media/libmedia/mediarecorder.cpp
+++ b/media/libmedia/mediarecorder.cpp
@@ -25,12 +25,13 @@
#include <media/IMediaPlayerService.h>
#include <media/IMediaRecorder.h>
#include <media/mediaplayer.h> // for MEDIA_ERROR_SERVER_DIED
+#include <gui/ISurfaceTexture.h>
namespace android {
-status_t MediaRecorder::setCamera(const sp<ICamera>& camera)
+status_t MediaRecorder::setCamera(const sp<ICamera>& camera, const sp<ICameraRecordingProxy>& proxy)
{
- LOGV("setCamera(%p)", camera.get());
+ LOGV("setCamera(%p,%p)", camera.get(), proxy.get());
if(mMediaRecorder == NULL) {
LOGE("media recorder is not initialized yet");
return INVALID_OPERATION;
@@ -40,7 +41,7 @@
return INVALID_OPERATION;
}
- status_t ret = mMediaRecorder->setCamera(camera);
+ status_t ret = mMediaRecorder->setCamera(camera, proxy);
if (OK != ret) {
LOGV("setCamera failed: %d", ret);
mCurrentState = MEDIA_RECORDER_ERROR;
@@ -127,7 +128,9 @@
return INVALID_OPERATION;
}
+ // following call is made over the Binder Interface
status_t ret = mMediaRecorder->setVideoSource(vs);
+
if (OK != ret) {
LOGV("setVideoSource failed: %d", ret);
mCurrentState = MEDIA_RECORDER_ERROR;
@@ -319,32 +322,6 @@
return ret;
}
-status_t MediaRecorder::setOutputFileAuxiliary(int fd)
-{
- LOGV("setOutputFileAuxiliary(%d)", fd);
- if(mMediaRecorder == NULL) {
- LOGE("media recorder is not initialized yet");
- return INVALID_OPERATION;
- }
- if (mIsAuxiliaryOutputFileSet) {
- LOGE("output file has already been set");
- return INVALID_OPERATION;
- }
- if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
- LOGE("setOutputFile called in an invalid state(%d)", mCurrentState);
- return INVALID_OPERATION;
- }
-
- status_t ret = mMediaRecorder->setOutputFileAuxiliary(fd);
- if (OK != ret) {
- LOGV("setOutputFileAuxiliary failed: %d", ret);
- mCurrentState = MEDIA_RECORDER_ERROR;
- return ret;
- }
- mIsAuxiliaryOutputFileSet = true;
- return ret;
-}
-
status_t MediaRecorder::setVideoSize(int width, int height)
{
LOGV("setVideoSize(%d, %d)", width, height);
@@ -357,7 +334,7 @@
return INVALID_OPERATION;
}
if (!mIsVideoSourceSet) {
- LOGE("try to set video size without setting video source first");
+ LOGE("Cannot set video size without setting video source first");
return INVALID_OPERATION;
}
@@ -367,9 +344,27 @@
mCurrentState = MEDIA_RECORDER_ERROR;
return ret;
}
+
return ret;
}
+// Query a SurfaceMediaSurface through the Mediaserver, over the
+// binder interface. This is used by the Filter Framework (MeidaEncoder)
+// to get an <ISurfaceTexture> object to hook up to ANativeWindow.
+sp<ISurfaceTexture> MediaRecorder::
+ querySurfaceMediaSourceFromMediaServer()
+{
+ Mutex::Autolock _l(mLock);
+ mSurfaceMediaSource =
+ mMediaRecorder->querySurfaceMediaSource();
+ if (mSurfaceMediaSource == NULL) {
+ LOGE("SurfaceMediaSource could not be initialized!");
+ }
+ return mSurfaceMediaSource;
+}
+
+
+
status_t MediaRecorder::setVideoFrameRate(int frames_per_second)
{
LOGV("setVideoFrameRate(%d)", frames_per_second);
@@ -382,7 +377,7 @@
return INVALID_OPERATION;
}
if (!mIsVideoSourceSet) {
- LOGE("try to set video frame rate without setting video source first");
+ LOGE("Cannot set video frame rate without setting video source first");
return INVALID_OPERATION;
}
@@ -608,7 +603,6 @@
mIsAudioEncoderSet = false;
mIsVideoEncoderSet = false;
mIsOutputFileSet = false;
- mIsAuxiliaryOutputFileSet = false;
}
// Release should be OK in any state
@@ -621,7 +615,7 @@
return INVALID_OPERATION;
}
-MediaRecorder::MediaRecorder()
+MediaRecorder::MediaRecorder() : mSurfaceMediaSource(NULL)
{
LOGV("constructor");
@@ -632,6 +626,8 @@
if (mMediaRecorder != NULL) {
mCurrentState = MEDIA_RECORDER_IDLE;
}
+
+
doCleanUp();
}
@@ -646,6 +642,10 @@
if (mMediaRecorder != NULL) {
mMediaRecorder.clear();
}
+
+ if (mSurfaceMediaSource != NULL) {
+ mSurfaceMediaSource.clear();
+ }
}
status_t MediaRecorder::setListener(const sp<MediaRecorderListener>& listener)
diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk
index e65f6d8..ec7d8a0 100644
--- a/media/libmediaplayerservice/Android.mk
+++ b/media/libmediaplayerservice/Android.mk
@@ -16,10 +16,6 @@
StagefrightPlayer.cpp \
StagefrightRecorder.cpp
-ifeq ($(TARGET_OS)-$(TARGET_SIMULATOR),linux-true)
-LOCAL_LDLIBS += -ldl -lpthread
-endif
-
LOCAL_SHARED_LIBRARIES := \
libcutils \
libutils \
@@ -31,18 +27,14 @@
libandroid_runtime \
libstagefright \
libstagefright_omx \
- libstagefright_foundation \
- libsurfaceflinger_client \
- libgui
+ libstagefright_foundation \
+ libgui \
+ libdl
LOCAL_STATIC_LIBRARIES := \
libstagefright_rtsp \
libstagefright_nuplayer \
-ifneq ($(TARGET_SIMULATOR),true)
-LOCAL_SHARED_LIBRARIES += libdl
-endif
-
LOCAL_C_INCLUDES := \
$(JNI_H_INCLUDE) \
$(call include-path-for, graphics corecg) \
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 0156634..1e7c969 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -51,6 +51,9 @@
#include <media/MediaMetadataRetrieverInterface.h>
#include <media/Metadata.h>
#include <media/AudioTrack.h>
+#include <media/MemoryLeakTrackUtil.h>
+
+#include <system/audio.h>
#include <private/android_filesystem_config.h>
@@ -65,18 +68,6 @@
#include <OMX.h>
-/* desktop Linux needs a little help with gettid() */
-#if defined(HAVE_GETTID) && !defined(HAVE_ANDROID_OS)
-#define __KERNEL__
-# include <linux/unistd.h>
-#ifdef _syscall0
-_syscall0(pid_t,gettid)
-#else
-pid_t gettid() { return syscall(__NR_gettid);}
-#endif
-#undef __KERNEL__
-#endif
-
namespace {
using android::media::Metadata;
using android::status_t;
@@ -259,7 +250,11 @@
const KeyedVector<String8, String8> *headers, int audioSessionId)
{
int32_t connId = android_atomic_inc(&mNextConnId);
- sp<Client> c = new Client(this, pid, connId, client, audioSessionId);
+
+ sp<Client> c = new Client(
+ this, pid, connId, client, audioSessionId,
+ IPCThreadState::self()->getCallingUid());
+
LOGV("Create new client(%d) from pid %d, url=%s, connId=%d, audioSessionId=%d",
connId, pid, url, connId, audioSessionId);
if (NO_ERROR != c->setDataSource(url, headers))
@@ -277,7 +272,11 @@
int fd, int64_t offset, int64_t length, int audioSessionId)
{
int32_t connId = android_atomic_inc(&mNextConnId);
- sp<Client> c = new Client(this, pid, connId, client, audioSessionId);
+
+ sp<Client> c = new Client(
+ this, pid, connId, client, audioSessionId,
+ IPCThreadState::self()->getCallingUid());
+
LOGV("Create new client(%d) from pid %d, fd=%d, offset=%lld, length=%lld, audioSessionId=%d",
connId, pid, fd, offset, length, audioSessionId);
if (NO_ERROR != c->setDataSource(fd, offset, length)) {
@@ -295,7 +294,10 @@
pid_t pid, const sp<IMediaPlayerClient> &client,
const sp<IStreamSource> &source, int audioSessionId) {
int32_t connId = android_atomic_inc(&mNextConnId);
- sp<Client> c = new Client(this, pid, connId, client, audioSessionId);
+
+ sp<Client> c = new Client(
+ this, pid, connId, client, audioSessionId,
+ IPCThreadState::self()->getCallingUid());
LOGV("Create new client(%d) from pid %d, audioSessionId=%d",
connId, pid, audioSessionId);
@@ -377,6 +379,9 @@
mPid, mConnId, mStatus, mLoop?"true": "false");
result.append(buffer);
write(fd, result.string(), result.size());
+ if (mPlayer != NULL) {
+ mPlayer->dump(fd, args);
+ }
if (mAudioOutput != 0) {
mAudioOutput->dump(fd, args);
}
@@ -384,147 +389,6 @@
return NO_ERROR;
}
-static int myTid() {
-#ifdef HAVE_GETTID
- return gettid();
-#else
- return getpid();
-#endif
-}
-
-#if defined(__arm__)
-extern "C" void get_malloc_leak_info(uint8_t** info, size_t* overallSize,
- size_t* infoSize, size_t* totalMemory, size_t* backtraceSize);
-extern "C" void free_malloc_leak_info(uint8_t* info);
-
-// Use the String-class below instead of String8 to allocate all memory
-// beforehand and not reenter the heap while we are examining it...
-struct MyString8 {
- static const size_t MAX_SIZE = 256 * 1024;
-
- MyString8()
- : mPtr((char *)malloc(MAX_SIZE)) {
- *mPtr = '\0';
- }
-
- ~MyString8() {
- free(mPtr);
- }
-
- void append(const char *s) {
- strcat(mPtr, s);
- }
-
- const char *string() const {
- return mPtr;
- }
-
- size_t size() const {
- return strlen(mPtr);
- }
-
-private:
- char *mPtr;
-
- MyString8(const MyString8 &);
- MyString8 &operator=(const MyString8 &);
-};
-
-void memStatus(int fd, const Vector<String16>& args)
-{
- const size_t SIZE = 256;
- char buffer[SIZE];
- MyString8 result;
-
- typedef struct {
- size_t size;
- size_t dups;
- intptr_t * backtrace;
- } AllocEntry;
-
- uint8_t *info = NULL;
- size_t overallSize = 0;
- size_t infoSize = 0;
- size_t totalMemory = 0;
- size_t backtraceSize = 0;
-
- get_malloc_leak_info(&info, &overallSize, &infoSize, &totalMemory, &backtraceSize);
- if (info) {
- uint8_t *ptr = info;
- size_t count = overallSize / infoSize;
-
- snprintf(buffer, SIZE, " Allocation count %i\n", count);
- result.append(buffer);
- snprintf(buffer, SIZE, " Total memory %i\n", totalMemory);
- result.append(buffer);
-
- AllocEntry * entries = new AllocEntry[count];
-
- for (size_t i = 0; i < count; i++) {
- // Each entry should be size_t, size_t, intptr_t[backtraceSize]
- AllocEntry *e = &entries[i];
-
- e->size = *reinterpret_cast<size_t *>(ptr);
- ptr += sizeof(size_t);
-
- e->dups = *reinterpret_cast<size_t *>(ptr);
- ptr += sizeof(size_t);
-
- e->backtrace = reinterpret_cast<intptr_t *>(ptr);
- ptr += sizeof(intptr_t) * backtraceSize;
- }
-
- // Now we need to sort the entries. They come sorted by size but
- // not by stack trace which causes problems using diff.
- bool moved;
- do {
- moved = false;
- for (size_t i = 0; i < (count - 1); i++) {
- AllocEntry *e1 = &entries[i];
- AllocEntry *e2 = &entries[i+1];
-
- bool swap = e1->size < e2->size;
- if (e1->size == e2->size) {
- for(size_t j = 0; j < backtraceSize; j++) {
- if (e1->backtrace[j] == e2->backtrace[j]) {
- continue;
- }
- swap = e1->backtrace[j] < e2->backtrace[j];
- break;
- }
- }
- if (swap) {
- AllocEntry t = entries[i];
- entries[i] = entries[i+1];
- entries[i+1] = t;
- moved = true;
- }
- }
- } while (moved);
-
- for (size_t i = 0; i < count; i++) {
- AllocEntry *e = &entries[i];
-
- snprintf(buffer, SIZE, "size %8i, dup %4i, ", e->size, e->dups);
- result.append(buffer);
- for (size_t ct = 0; (ct < backtraceSize) && e->backtrace[ct]; ct++) {
- if (ct) {
- result.append(", ");
- }
- snprintf(buffer, SIZE, "0x%08x", e->backtrace[ct]);
- result.append(buffer);
- }
- result.append("\n");
- }
-
- delete[] entries;
- free_malloc_leak_info(info);
- }
-
- write(fd, result.string(), result.size());
-}
-#endif
-
status_t MediaPlayerService::dump(int fd, const Vector<String16>& args)
{
const size_t SIZE = 256;
@@ -556,7 +420,7 @@
}
result.append(" Files opened and/or mapped:\n");
- snprintf(buffer, SIZE, "/proc/%d/maps", myTid());
+ snprintf(buffer, SIZE, "/proc/%d/maps", gettid());
FILE *f = fopen(buffer, "r");
if (f) {
while (!feof(f)) {
@@ -576,13 +440,13 @@
result.append("\n");
}
- snprintf(buffer, SIZE, "/proc/%d/fd", myTid());
+ snprintf(buffer, SIZE, "/proc/%d/fd", gettid());
DIR *d = opendir(buffer);
if (d) {
struct dirent *ent;
while((ent = readdir(d)) != NULL) {
if (strcmp(ent->d_name,".") && strcmp(ent->d_name,"..")) {
- snprintf(buffer, SIZE, "/proc/%d/fd/%s", myTid(), ent->d_name);
+ snprintf(buffer, SIZE, "/proc/%d/fd/%s", gettid(), ent->d_name);
struct stat s;
if (lstat(buffer, &s) == 0) {
if ((s.st_mode & S_IFMT) == S_IFLNK) {
@@ -623,7 +487,6 @@
result.append("\n");
}
-#if defined(__arm__)
bool dumpMem = false;
for (size_t i = 0; i < args.size(); i++) {
if (args[i] == String16("-m")) {
@@ -631,9 +494,8 @@
}
}
if (dumpMem) {
- memStatus(fd, args);
+ dumpMemoryAddresses(fd);
}
-#endif
}
write(fd, result.string(), result.size());
return NO_ERROR;
@@ -645,8 +507,10 @@
mClients.remove(client);
}
-MediaPlayerService::Client::Client(const sp<MediaPlayerService>& service, pid_t pid,
- int32_t connId, const sp<IMediaPlayerClient>& client, int audioSessionId)
+MediaPlayerService::Client::Client(
+ const sp<MediaPlayerService>& service, pid_t pid,
+ int32_t connId, const sp<IMediaPlayerClient>& client,
+ int audioSessionId, uid_t uid)
{
LOGV("Client(%d) constructor", connId);
mPid = pid;
@@ -656,6 +520,7 @@
mLoop = false;
mStatus = NO_INIT;
mAudioSessionId = audioSessionId;
+ mUID = uid;
#if CALLBACK_ANTAGONIZER
LOGD("create Antagonizer");
@@ -820,6 +685,9 @@
if (p == NULL) {
p = android::createPlayer(playerType, this, notify);
}
+
+ p->setUID(mUID);
+
return p;
}
@@ -1156,7 +1024,22 @@
return NO_ERROR;
}
-void MediaPlayerService::Client::notify(void* cookie, int msg, int ext1, int ext2)
+status_t MediaPlayerService::Client::setParameter(int key, const Parcel &request) {
+ LOGV("[%d] setParameter(%d)", mConnId, key);
+ sp<MediaPlayerBase> p = getPlayer();
+ if (p == 0) return UNKNOWN_ERROR;
+ return p->setParameter(key, request);
+}
+
+status_t MediaPlayerService::Client::getParameter(int key, Parcel *reply) {
+ LOGV("[%d] getParameter(%d)", mConnId, key);
+ sp<MediaPlayerBase> p = getPlayer();
+ if (p == 0) return UNKNOWN_ERROR;
+ return p->getParameter(key, reply);
+}
+
+void MediaPlayerService::Client::notify(
+ void* cookie, int msg, int ext1, int ext2, const Parcel *obj)
{
Client* client = static_cast<Client*>(cookie);
@@ -1173,7 +1056,7 @@
client->addNewMetadataUpdate(metadata_type);
}
LOGV("[%d] notify (%p, %d, %d, %d)", client->mConnId, cookie, msg, ext1, ext2);
- client->mClient->notify(msg, ext1, ext2);
+ client->mClient->notify(msg, ext1, ext2, obj);
}
@@ -1281,7 +1164,7 @@
mem = new MemoryBase(cache->getHeap(), 0, cache->size());
*pSampleRate = cache->sampleRate();
*pNumChannels = cache->channelCount();
- *pFormat = cache->format();
+ *pFormat = (int)cache->format();
LOGV("return memory @ %p, sampleRate=%u, channelCount = %d, format = %d", mem->pointer(), *pSampleRate, *pNumChannels, *pFormat);
Exit:
@@ -1342,7 +1225,7 @@
mSessionId(sessionId) {
LOGV("AudioOutput(%d)", sessionId);
mTrack = 0;
- mStreamType = AudioSystem::MUSIC;
+ mStreamType = AUDIO_STREAM_MUSIC;
mLeftVolume = 1.0;
mRightVolume = 1.0;
mLatency = 0;
@@ -1452,7 +1335,7 @@
mStreamType,
sampleRate,
format,
- (channelCount == 2) ? AudioSystem::CHANNEL_OUT_STEREO : AudioSystem::CHANNEL_OUT_MONO,
+ (channelCount == 2) ? AUDIO_CHANNEL_OUT_STEREO : AUDIO_CHANNEL_OUT_MONO,
frameCount,
0 /* flags */,
CallbackWrapper,
@@ -1464,7 +1347,7 @@
mStreamType,
sampleRate,
format,
- (channelCount == 2) ? AudioSystem::CHANNEL_OUT_STEREO : AudioSystem::CHANNEL_OUT_MONO,
+ (channelCount == 2) ? AUDIO_CHANNEL_OUT_STEREO : AUDIO_CHANNEL_OUT_MONO,
frameCount,
0,
NULL,
@@ -1583,8 +1466,15 @@
size_t actualSize = (*me->mCallback)(
me, buffer->raw, buffer->size, me->mCallbackCookie);
- buffer->size = actualSize;
+ if (actualSize == 0 && buffer->size > 0) {
+ // We've reached EOS but the audio track is not stopped yet,
+ // keep playing silence.
+ memset(buffer->raw, 0, buffer->size);
+ actualSize = buffer->size;
+ }
+
+ buffer->size = actualSize;
}
int MediaPlayerService::AudioOutput::getSessionId()
@@ -1750,7 +1640,8 @@
return mError;
}
-void MediaPlayerService::AudioCache::notify(void* cookie, int msg, int ext1, int ext2)
+void MediaPlayerService::AudioCache::notify(
+ void* cookie, int msg, int ext1, int ext2, const Parcel *obj)
{
LOGV("notify(%p, %d, %d, %d)", cookie, msg, ext1, ext2);
AudioCache* p = static_cast<AudioCache*>(cookie);
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index ff6ccf5..e32b92a 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -30,6 +30,8 @@
#include <media/MediaPlayerInterface.h>
#include <media/Metadata.h>
+#include <system/audio.h>
+
namespace android {
class IMediaRecorder;
@@ -130,7 +132,7 @@
virtual ssize_t bufferSize() const { return frameSize() * mFrameCount; }
virtual ssize_t frameCount() const { return mFrameCount; }
virtual ssize_t channelCount() const { return (ssize_t)mChannelCount; }
- virtual ssize_t frameSize() const { return ssize_t(mChannelCount * ((mFormat == AudioSystem::PCM_16_BIT)?sizeof(int16_t):sizeof(u_int8_t))); }
+ virtual ssize_t frameSize() const { return ssize_t(mChannelCount * ((mFormat == AUDIO_FORMAT_PCM_16_BIT)?sizeof(int16_t):sizeof(u_int8_t))); }
virtual uint32_t latency() const;
virtual float msecsPerFrame() const;
virtual status_t getPosition(uint32_t *position);
@@ -156,7 +158,8 @@
sp<IMemoryHeap> getHeap() const { return mHeap; }
- static void notify(void* cookie, int msg, int ext1, int ext2);
+ static void notify(void* cookie, int msg,
+ int ext1, int ext2, const Parcel *obj);
virtual status_t dump(int fd, const Vector<String16>& args) const;
private:
@@ -276,6 +279,8 @@
Parcel *reply);
virtual status_t setAuxEffectSendLevel(float level);
virtual status_t attachAuxEffect(int effectId);
+ virtual status_t setParameter(int key, const Parcel &request);
+ virtual status_t getParameter(int key, Parcel *reply);
sp<MediaPlayerBase> createPlayer(player_type playerType);
@@ -287,7 +292,8 @@
status_t setDataSource(const sp<IStreamSource> &source);
- static void notify(void* cookie, int msg, int ext1, int ext2);
+ static void notify(void* cookie, int msg,
+ int ext1, int ext2, const Parcel *obj);
pid_t pid() const { return mPid; }
virtual status_t dump(int fd, const Vector<String16>& args) const;
@@ -300,7 +306,8 @@
pid_t pid,
int32_t connId,
const sp<IMediaPlayerClient>& client,
- int audioSessionId);
+ int audioSessionId,
+ uid_t uid);
Client();
virtual ~Client();
@@ -330,6 +337,7 @@
bool mLoop;
int32_t mConnId;
int mAudioSessionId;
+ uid_t mUID;
// Metadata filters.
media::Metadata::Filter mMetadataAllow; // protected by mLock
diff --git a/media/libmediaplayerservice/MediaRecorderClient.cpp b/media/libmediaplayerservice/MediaRecorderClient.cpp
index 1a1780c..6f80b35 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.cpp
+++ b/media/libmediaplayerservice/MediaRecorderClient.cpp
@@ -35,10 +35,13 @@
#include <media/AudioTrack.h>
+#include <system/audio.h>
+
#include "MediaRecorderClient.h"
#include "MediaPlayerService.h"
#include "StagefrightRecorder.h"
+#include <gui/ISurfaceTexture.h>
namespace android {
@@ -55,7 +58,22 @@
return ok;
}
-status_t MediaRecorderClient::setCamera(const sp<ICamera>& camera)
+
+sp<ISurfaceTexture> MediaRecorderClient::querySurfaceMediaSource()
+{
+ LOGV("Query SurfaceMediaSource");
+ Mutex::Autolock lock(mLock);
+ if (mRecorder == NULL) {
+ LOGE("recorder is not initialized");
+ return NULL;
+ }
+ return mRecorder->querySurfaceMediaSource();
+}
+
+
+
+status_t MediaRecorderClient::setCamera(const sp<ICamera>& camera,
+ const sp<ICameraRecordingProxy>& proxy)
{
LOGV("setCamera");
Mutex::Autolock lock(mLock);
@@ -63,7 +81,7 @@
LOGE("recorder is not initialized");
return NO_INIT;
}
- return mRecorder->setCamera(camera);
+ return mRecorder->setCamera(camera, proxy);
}
status_t MediaRecorderClient::setPreviewSurface(const sp<Surface>& surface)
@@ -102,7 +120,7 @@
LOGE("recorder is not initialized");
return NO_INIT;
}
- return mRecorder->setAudioSource((audio_source)as);
+ return mRecorder->setAudioSource((audio_source_t)as);
}
status_t MediaRecorderClient::setOutputFormat(int of)
@@ -160,17 +178,6 @@
return mRecorder->setOutputFile(fd, offset, length);
}
-status_t MediaRecorderClient::setOutputFileAuxiliary(int fd)
-{
- LOGV("setOutputFileAuxiliary(%d)", fd);
- Mutex::Autolock lock(mLock);
- if (mRecorder == NULL) {
- LOGE("recorder is not initialized");
- return NO_INIT;
- }
- return mRecorder->setOutputFileAuxiliary(fd);
-}
-
status_t MediaRecorderClient::setVideoSize(int width, int height)
{
LOGV("setVideoSize(%dx%d)", width, height);
diff --git a/media/libmediaplayerservice/MediaRecorderClient.h b/media/libmediaplayerservice/MediaRecorderClient.h
index fded98e..c9ccf22 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.h
+++ b/media/libmediaplayerservice/MediaRecorderClient.h
@@ -24,44 +24,51 @@
class MediaRecorderBase;
class MediaPlayerService;
+class ICameraRecordingProxy;
+class ISurfaceTexture;
class MediaRecorderClient : public BnMediaRecorder
{
public:
- virtual status_t setCamera(const sp<ICamera>& camera);
- virtual status_t setPreviewSurface(const sp<Surface>& surface);
- virtual status_t setVideoSource(int vs);
- virtual status_t setAudioSource(int as);
- virtual status_t setOutputFormat(int of);
- virtual status_t setVideoEncoder(int ve);
- virtual status_t setAudioEncoder(int ae);
- virtual status_t setOutputFile(const char* path);
- virtual status_t setOutputFile(int fd, int64_t offset, int64_t length);
- virtual status_t setOutputFileAuxiliary(int fd);
- virtual status_t setVideoSize(int width, int height);
- virtual status_t setVideoFrameRate(int frames_per_second);
- virtual status_t setParameters(const String8& params);
- virtual status_t setListener(const sp<IMediaRecorderClient>& listener);
- virtual status_t prepare();
- virtual status_t getMaxAmplitude(int* max);
- virtual status_t start();
- virtual status_t stop();
- virtual status_t reset();
- virtual status_t init();
- virtual status_t close();
- virtual status_t release();
+ virtual status_t setCamera(const sp<ICamera>& camera,
+ const sp<ICameraRecordingProxy>& proxy);
+ virtual status_t setPreviewSurface(const sp<Surface>& surface);
+ virtual status_t setVideoSource(int vs);
+ virtual status_t setAudioSource(int as);
+ virtual status_t setOutputFormat(int of);
+ virtual status_t setVideoEncoder(int ve);
+ virtual status_t setAudioEncoder(int ae);
+ virtual status_t setOutputFile(const char* path);
+ virtual status_t setOutputFile(int fd, int64_t offset,
+ int64_t length);
+ virtual status_t setVideoSize(int width, int height);
+ virtual status_t setVideoFrameRate(int frames_per_second);
+ virtual status_t setParameters(const String8& params);
+ virtual status_t setListener(
+ const sp<IMediaRecorderClient>& listener);
+ virtual status_t prepare();
+ virtual status_t getMaxAmplitude(int* max);
+ virtual status_t start();
+ virtual status_t stop();
+ virtual status_t reset();
+ virtual status_t init();
+ virtual status_t close();
+ virtual status_t release();
+ virtual status_t dump(int fd, const Vector<String16>& args) const;
+ virtual sp<ISurfaceTexture> querySurfaceMediaSource();
- virtual status_t dump(int fd, const Vector<String16>& args) const;
private:
- friend class MediaPlayerService; // for accessing private constructor
+ friend class MediaPlayerService; // for accessing private constructor
- MediaRecorderClient(const sp<MediaPlayerService>& service, pid_t pid);
- virtual ~MediaRecorderClient();
+ MediaRecorderClient(
+ const sp<MediaPlayerService>& service,
+ pid_t pid);
+ virtual ~MediaRecorderClient();
- pid_t mPid;
- Mutex mLock;
- MediaRecorderBase *mRecorder;
- sp<MediaPlayerService> mMediaPlayerService;
+ pid_t mPid;
+ Mutex mLock;
+ MediaRecorderBase *mRecorder;
+ sp<MediaPlayerService> mMediaPlayerService;
};
}; // namespace android
diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.cpp b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
index 5fcf2a7..d574ea3 100644
--- a/media/libmediaplayerservice/MetadataRetrieverClient.cpp
+++ b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
@@ -21,7 +21,6 @@
#include <sys/types.h>
#include <sys/stat.h>
-#include <sys/resource.h>
#include <dirent.h>
#include <unistd.h>
@@ -40,18 +39,6 @@
#include "MetadataRetrieverClient.h"
#include "StagefrightMetadataRetriever.h"
-/* desktop Linux needs a little help with gettid() */
-#if defined(HAVE_GETTID) && !defined(HAVE_ANDROID_OS)
-#define __KERNEL__
-# include <linux/unistd.h>
-#ifdef _syscall0
-_syscall0(pid_t,gettid)
-#else
-pid_t gettid() { return syscall(__NR_gettid);}
-#endif
-#undef __KERNEL__
-#endif
-
namespace android {
extern player_type getPlayerType(const char* url);
@@ -120,7 +107,8 @@
return p;
}
-status_t MetadataRetrieverClient::setDataSource(const char *url)
+status_t MetadataRetrieverClient::setDataSource(
+ const char *url, const KeyedVector<String8, String8> *headers)
{
LOGV("setDataSource(%s)", url);
Mutex::Autolock lock(mLock);
@@ -131,7 +119,7 @@
LOGV("player type = %d", playerType);
sp<MediaMetadataRetrieverBase> p = createRetriever(playerType);
if (p == NULL) return NO_INIT;
- status_t ret = p->setDataSource(url);
+ status_t ret = p->setDataSource(url, headers);
if (ret == NO_ERROR) mRetriever = p;
return ret;
}
diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.h b/media/libmediaplayerservice/MetadataRetrieverClient.h
index b834715..f08f933 100644
--- a/media/libmediaplayerservice/MetadataRetrieverClient.h
+++ b/media/libmediaplayerservice/MetadataRetrieverClient.h
@@ -41,7 +41,10 @@
// Implements IMediaMetadataRetriever interface
// These methods are called in IMediaMetadataRetriever.cpp?
virtual void disconnect();
- virtual status_t setDataSource(const char *url);
+
+ virtual status_t setDataSource(
+ const char *url, const KeyedVector<String8, String8> *headers);
+
virtual status_t setDataSource(int fd, int64_t offset, int64_t length);
virtual sp<IMemory> getFrameAtTime(int64_t timeUs, int option);
virtual sp<IMemory> extractAlbumArt();
diff --git a/media/libmediaplayerservice/MidiFile.cpp b/media/libmediaplayerservice/MidiFile.cpp
index 1b0b05f..7e04523 100644
--- a/media/libmediaplayerservice/MidiFile.cpp
+++ b/media/libmediaplayerservice/MidiFile.cpp
@@ -29,15 +29,12 @@
#include <libsonivox/eas_reverb.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <unistd.h>
+
+#include <system/audio.h>
#include "MidiFile.h"
-#ifdef HAVE_GETTID
-static pid_t myTid() { return gettid(); }
-#else
-static pid_t myTid() { return getpid(); }
-#endif
-
// ----------------------------------------------------------------------------
namespace android {
@@ -58,7 +55,7 @@
MidiFile::MidiFile() :
mEasData(NULL), mEasHandle(NULL), mAudioBuffer(NULL),
mPlayTime(-1), mDuration(-1), mState(EAS_STATE_ERROR),
- mStreamType(AudioSystem::MUSIC), mLoop(false), mExit(false),
+ mStreamType(AUDIO_STREAM_MUSIC), mLoop(false), mExit(false),
mPaused(false), mRender(false), mTid(-1)
{
LOGV("constructor");
@@ -423,7 +420,7 @@
}
status_t MidiFile::createOutputTrack() {
- if (mAudioSink->open(pLibConfig->sampleRate, pLibConfig->numChannels, AudioSystem::PCM_16_BIT, 2) != NO_ERROR) {
+ if (mAudioSink->open(pLibConfig->sampleRate, pLibConfig->numChannels, AUDIO_FORMAT_PCM_16_BIT, 2) != NO_ERROR) {
LOGE("mAudioSink open failed");
return ERROR_OPEN_FAILED;
}
@@ -453,7 +450,7 @@
// signal main thread that we started
{
Mutex::Autolock l(mMutex);
- mTid = myTid();
+ mTid = gettid();
LOGV("render thread(%d) signal", mTid);
mCondition.signal();
}
diff --git a/media/libmediaplayerservice/MidiFile.h b/media/libmediaplayerservice/MidiFile.h
index a98231c..b35696f 100644
--- a/media/libmediaplayerservice/MidiFile.h
+++ b/media/libmediaplayerservice/MidiFile.h
@@ -55,6 +55,13 @@
virtual status_t invoke(const Parcel& request, Parcel *reply) {
return INVALID_OPERATION;
}
+ virtual status_t setParameter(int key, const Parcel &request) {
+ return INVALID_OPERATION;
+ }
+ virtual status_t getParameter(int key, Parcel *reply) {
+ return INVALID_OPERATION;
+ }
+
private:
status_t createOutputTrack();
diff --git a/media/libmediaplayerservice/MidiMetadataRetriever.cpp b/media/libmediaplayerservice/MidiMetadataRetriever.cpp
index ad95fac..aaf2d18 100644
--- a/media/libmediaplayerservice/MidiMetadataRetriever.cpp
+++ b/media/libmediaplayerservice/MidiMetadataRetriever.cpp
@@ -35,7 +35,8 @@
mMetadataValues[0][0] = '\0';
}
-status_t MidiMetadataRetriever::setDataSource(const char *url)
+status_t MidiMetadataRetriever::setDataSource(
+ const char *url, const KeyedVector<String8, String8> *headers)
{
LOGV("setDataSource: %s", url? url: "NULL pointer");
Mutex::Autolock lock(mLock);
@@ -43,8 +44,7 @@
if (mMidiPlayer == 0) {
mMidiPlayer = new MidiFile();
}
- // TODO: support headers in MetadataRetriever interface!
- return mMidiPlayer->setDataSource(url, NULL /* headers */);
+ return mMidiPlayer->setDataSource(url, headers);
}
status_t MidiMetadataRetriever::setDataSource(int fd, int64_t offset, int64_t length)
diff --git a/media/libmediaplayerservice/MidiMetadataRetriever.h b/media/libmediaplayerservice/MidiMetadataRetriever.h
index 73ff347..4cee42d 100644
--- a/media/libmediaplayerservice/MidiMetadataRetriever.h
+++ b/media/libmediaplayerservice/MidiMetadataRetriever.h
@@ -31,7 +31,9 @@
MidiMetadataRetriever() {}
~MidiMetadataRetriever() {}
- virtual status_t setDataSource(const char *url);
+ virtual status_t setDataSource(
+ const char *url, const KeyedVector<String8, String8> *headers);
+
virtual status_t setDataSource(int fd, int64_t offset, int64_t length);
virtual const char* extractMetadata(int keyCode);
diff --git a/media/libmediaplayerservice/StagefrightPlayer.cpp b/media/libmediaplayerservice/StagefrightPlayer.cpp
index c5cbd23..40e055c 100644
--- a/media/libmediaplayerservice/StagefrightPlayer.cpp
+++ b/media/libmediaplayerservice/StagefrightPlayer.cpp
@@ -47,6 +47,12 @@
return OK;
}
+status_t StagefrightPlayer::setUID(uid_t uid) {
+ mPlayer->setUID(uid);
+
+ return OK;
+}
+
status_t StagefrightPlayer::setDataSource(
const char *url, const KeyedVector<String8, String8> *headers) {
return mPlayer->setDataSource(url, headers);
@@ -110,7 +116,7 @@
}
status_t StagefrightPlayer::seekTo(int msec) {
- LOGV("seekTo");
+ LOGV("seekTo %.2f secs", msec / 1E3);
status_t err = mPlayer->seekTo((int64_t)msec * 1000);
@@ -177,6 +183,16 @@
mPlayer->setAudioSink(audioSink);
}
+status_t StagefrightPlayer::setParameter(int key, const Parcel &request) {
+ LOGV("setParameter");
+ return mPlayer->setParameter(key, request);
+}
+
+status_t StagefrightPlayer::getParameter(int key, Parcel *reply) {
+ LOGV("getParameter");
+ return mPlayer->getParameter(key, reply);
+}
+
status_t StagefrightPlayer::getMetadata(
const media::Metadata::Filter& ids, Parcel *records) {
using media::Metadata;
@@ -204,4 +220,8 @@
return OK;
}
+status_t StagefrightPlayer::dump(int fd, const Vector<String16> &args) const {
+ return mPlayer->dump(fd, args);
+}
+
} // namespace android
diff --git a/media/libmediaplayerservice/StagefrightPlayer.h b/media/libmediaplayerservice/StagefrightPlayer.h
index e2796d2..cbc6d49 100644
--- a/media/libmediaplayerservice/StagefrightPlayer.h
+++ b/media/libmediaplayerservice/StagefrightPlayer.h
@@ -31,6 +31,8 @@
virtual status_t initCheck();
+ virtual status_t setUID(uid_t uid);
+
virtual status_t setDataSource(
const char *url, const KeyedVector<String8, String8> *headers);
@@ -55,10 +57,14 @@
virtual player_type playerType();
virtual status_t invoke(const Parcel &request, Parcel *reply);
virtual void setAudioSink(const sp<AudioSink> &audioSink);
+ virtual status_t setParameter(int key, const Parcel &request);
+ virtual status_t getParameter(int key, Parcel *reply);
virtual status_t getMetadata(
const media::Metadata::Filter& ids, Parcel *records);
+ virtual status_t dump(int fd, const Vector<String16> &args) const;
+
private:
AwesomePlayer *mPlayer;
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index e3dfabb..6fdb726 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -26,10 +26,9 @@
#include <media/IMediaPlayerService.h>
#include <media/stagefright/AudioSource.h>
#include <media/stagefright/AMRWriter.h>
+#include <media/stagefright/AACWriter.h>
#include <media/stagefright/CameraSource.h>
-#include <media/stagefright/VideoSourceDownSampler.h>
#include <media/stagefright/CameraSourceTimeLapse.h>
-#include <media/stagefright/MediaSourceSplitter.h>
#include <media/stagefright/MPEG2TSWriter.h>
#include <media/stagefright/MPEG4Writer.h>
#include <media/stagefright/MediaDebug.h>
@@ -37,15 +36,19 @@
#include <media/stagefright/MetaData.h>
#include <media/stagefright/OMXClient.h>
#include <media/stagefright/OMXCodec.h>
+#include <media/stagefright/SurfaceMediaSource.h>
#include <media/MediaProfiles.h>
#include <camera/ICamera.h>
#include <camera/CameraParameters.h>
#include <surfaceflinger/Surface.h>
+
#include <utils/Errors.h>
#include <sys/types.h>
#include <ctype.h>
#include <unistd.h>
+#include <system/audio.h>
+
#include "ARTPWriter.h"
namespace android {
@@ -62,11 +65,11 @@
StagefrightRecorder::StagefrightRecorder()
- : mWriter(NULL), mWriterAux(NULL),
- mOutputFd(-1), mOutputFdAux(-1),
- mAudioSource(AUDIO_SOURCE_LIST_END),
+ : mWriter(NULL),
+ mOutputFd(-1),
+ mAudioSource(AUDIO_SOURCE_CNT),
mVideoSource(VIDEO_SOURCE_LIST_END),
- mStarted(false) {
+ mStarted(false), mSurfaceMediaSource(NULL) {
LOGV("Constructor");
reset();
@@ -82,10 +85,18 @@
return OK;
}
-status_t StagefrightRecorder::setAudioSource(audio_source as) {
+// The client side of mediaserver asks it to creat a SurfaceMediaSource
+// and return a interface reference. The client side will use that
+// while encoding GL Frames
+sp<ISurfaceTexture> StagefrightRecorder::querySurfaceMediaSource() const {
+ LOGV("Get SurfaceMediaSource");
+ return mSurfaceMediaSource;
+}
+
+status_t StagefrightRecorder::setAudioSource(audio_source_t as) {
LOGV("setAudioSource: %d", as);
if (as < AUDIO_SOURCE_DEFAULT ||
- as >= AUDIO_SOURCE_LIST_END) {
+ as >= AUDIO_SOURCE_CNT) {
LOGE("Invalid audio source: %d", as);
return BAD_VALUE;
}
@@ -195,14 +206,20 @@
return OK;
}
-status_t StagefrightRecorder::setCamera(const sp<ICamera> &camera) {
+status_t StagefrightRecorder::setCamera(const sp<ICamera> &camera,
+ const sp<ICameraRecordingProxy> &proxy) {
LOGV("setCamera");
if (camera == 0) {
LOGE("camera is NULL");
return BAD_VALUE;
}
+ if (proxy == 0) {
+ LOGE("camera proxy is NULL");
+ return BAD_VALUE;
+ }
mCamera = camera;
+ mCameraProxy = proxy;
return OK;
}
@@ -240,24 +257,6 @@
return OK;
}
-status_t StagefrightRecorder::setOutputFileAuxiliary(int fd) {
- LOGV("setOutputFileAuxiliary: %d", fd);
-
- if (fd < 0) {
- LOGE("Invalid file descriptor: %d", fd);
- return -EBADF;
- }
-
- mCaptureAuxVideo = true;
-
- if (mOutputFdAux >= 0) {
- ::close(mOutputFdAux);
- }
- mOutputFdAux = dup(fd);
-
- return OK;
-}
-
// Attempt to parse an int64 literal optionally surrounded by whitespace,
// returns true on success, false otherwise.
static bool safe_strtoi64(const char *s, int64_t *val) {
@@ -554,39 +553,23 @@
return OK;
}
-status_t StagefrightRecorder::setParamAuxVideoWidth(int32_t width) {
- LOGV("setParamAuxVideoWidth : %d", width);
+status_t StagefrightRecorder::setParamGeoDataLongitude(
+ int32_t longitudex10000) {
- if (width <= 0) {
- LOGE("Width (%d) is not positive", width);
+ if (longitudex10000 > 1800000 || longitudex10000 < -1800000) {
return BAD_VALUE;
}
-
- mAuxVideoWidth = width;
+ mLongitudex10000 = longitudex10000;
return OK;
}
-status_t StagefrightRecorder::setParamAuxVideoHeight(int32_t height) {
- LOGV("setParamAuxVideoHeight : %d", height);
+status_t StagefrightRecorder::setParamGeoDataLatitude(
+ int32_t latitudex10000) {
- if (height <= 0) {
- LOGE("Height (%d) is not positive", height);
+ if (latitudex10000 > 900000 || latitudex10000 < -900000) {
return BAD_VALUE;
}
-
- mAuxVideoHeight = height;
- return OK;
-}
-
-status_t StagefrightRecorder::setParamAuxVideoEncodingBitRate(int32_t bitRate) {
- LOGV("StagefrightRecorder::setParamAuxVideoEncodingBitRate: %d", bitRate);
-
- if (bitRate <= 0) {
- LOGE("Invalid video encoding bit rate: %d", bitRate);
- return BAD_VALUE;
- }
-
- mAuxVideoBitRate = bitRate;
+ mLatitudex10000 = latitudex10000;
return OK;
}
@@ -618,6 +601,16 @@
if (safe_strtoi32(value.string(), &use64BitOffset)) {
return setParam64BitFileOffset(use64BitOffset != 0);
}
+ } else if (key == "param-geotag-longitude") {
+ int32_t longitudex10000;
+ if (safe_strtoi32(value.string(), &longitudex10000)) {
+ return setParamGeoDataLongitude(longitudex10000);
+ }
+ } else if (key == "param-geotag-latitude") {
+ int32_t latitudex10000;
+ if (safe_strtoi32(value.string(), &latitudex10000)) {
+ return setParamGeoDataLatitude(latitudex10000);
+ }
} else if (key == "param-track-time-status") {
int64_t timeDurationUs;
if (safe_strtoi64(value.string(), &timeDurationUs)) {
@@ -689,21 +682,6 @@
return setParamTimeBetweenTimeLapseFrameCapture(
1000LL * timeBetweenTimeLapseFrameCaptureMs);
}
- } else if (key == "video-aux-param-width") {
- int32_t auxWidth;
- if (safe_strtoi32(value.string(), &auxWidth)) {
- return setParamAuxVideoWidth(auxWidth);
- }
- } else if (key == "video-aux-param-height") {
- int32_t auxHeight;
- if (safe_strtoi32(value.string(), &auxHeight)) {
- return setParamAuxVideoHeight(auxHeight);
- }
- } else if (key == "video-aux-param-encoding-bitrate") {
- int32_t auxVideoBitRate;
- if (safe_strtoi32(value.string(), &auxVideoBitRate)) {
- return setParamAuxVideoEncodingBitRate(auxVideoBitRate);
- }
} else {
LOGE("setParameter: failed to find key %s", key.string());
}
@@ -800,7 +778,7 @@
mStarted = true;
uint32_t params = IMediaPlayerService::kBatteryDataCodecStarted;
- if (mAudioSource != AUDIO_SOURCE_LIST_END) {
+ if (mAudioSource != AUDIO_SOURCE_CNT) {
params |= IMediaPlayerService::kBatteryDataTrackAudio;
}
if (mVideoSource != VIDEO_SOURCE_LIST_END) {
@@ -870,15 +848,21 @@
}
status_t StagefrightRecorder::startAACRecording() {
- CHECK(mOutputFormat == OUTPUT_FORMAT_AAC_ADIF ||
- mOutputFormat == OUTPUT_FORMAT_AAC_ADTS);
+ // FIXME:
+ // Add support for OUTPUT_FORMAT_AAC_ADIF
+ CHECK(mOutputFormat == OUTPUT_FORMAT_AAC_ADTS);
CHECK(mAudioEncoder == AUDIO_ENCODER_AAC);
- CHECK(mAudioSource != AUDIO_SOURCE_LIST_END);
+ CHECK(mAudioSource != AUDIO_SOURCE_CNT);
- CHECK(0 == "AACWriter is not implemented yet");
+ mWriter = new AACWriter(mOutputFd);
+ status_t status = startRawAudioRecording();
+ if (status != OK) {
+ mWriter.clear();
+ mWriter = NULL;
+ }
- return OK;
+ return status;
}
status_t StagefrightRecorder::startAMRRecording() {
@@ -900,7 +884,17 @@
}
}
- if (mAudioSource >= AUDIO_SOURCE_LIST_END) {
+ mWriter = new AMRWriter(mOutputFd);
+ status_t status = startRawAudioRecording();
+ if (status != OK) {
+ mWriter.clear();
+ mWriter = NULL;
+ }
+ return status;
+}
+
+status_t StagefrightRecorder::startRawAudioRecording() {
+ if (mAudioSource >= AUDIO_SOURCE_CNT) {
LOGE("Invalid audio source: %d", mAudioSource);
return BAD_VALUE;
}
@@ -915,7 +909,7 @@
return UNKNOWN_ERROR;
}
- mWriter = new AMRWriter(mOutputFd);
+ CHECK(mWriter != 0);
mWriter->addSource(audioEncoder);
if (mMaxFileDurationUs != 0) {
@@ -933,9 +927,9 @@
status_t StagefrightRecorder::startRTPRecording() {
CHECK_EQ(mOutputFormat, OUTPUT_FORMAT_RTP_AVP);
- if ((mAudioSource != AUDIO_SOURCE_LIST_END
+ if ((mAudioSource != AUDIO_SOURCE_CNT
&& mVideoSource != VIDEO_SOURCE_LIST_END)
- || (mAudioSource == AUDIO_SOURCE_LIST_END
+ || (mAudioSource == AUDIO_SOURCE_CNT
&& mVideoSource == VIDEO_SOURCE_LIST_END)) {
// Must have exactly one source.
return BAD_VALUE;
@@ -947,17 +941,17 @@
sp<MediaSource> source;
- if (mAudioSource != AUDIO_SOURCE_LIST_END) {
+ if (mAudioSource != AUDIO_SOURCE_CNT) {
source = createAudioSource();
} else {
- sp<CameraSource> cameraSource;
- status_t err = setupCameraSource(&cameraSource);
+ sp<MediaSource> mediaSource;
+ status_t err = setupMediaSource(&mediaSource);
if (err != OK) {
return err;
}
- err = setupVideoEncoder(cameraSource, mVideoBitRate, &source);
+ err = setupVideoEncoder(mediaSource, mVideoBitRate, &source);
if (err != OK) {
return err;
}
@@ -975,7 +969,7 @@
sp<MediaWriter> writer = new MPEG2TSWriter(mOutputFd);
- if (mAudioSource != AUDIO_SOURCE_LIST_END) {
+ if (mAudioSource != AUDIO_SOURCE_CNT) {
if (mAudioEncoder != AUDIO_ENCODER_AAC) {
return ERROR_UNSUPPORTED;
}
@@ -987,20 +981,19 @@
}
}
- if (mVideoSource == VIDEO_SOURCE_DEFAULT
- || mVideoSource == VIDEO_SOURCE_CAMERA) {
+ if (mVideoSource < VIDEO_SOURCE_LIST_END) {
if (mVideoEncoder != VIDEO_ENCODER_H264) {
return ERROR_UNSUPPORTED;
}
- sp<CameraSource> cameraSource;
- status_t err = setupCameraSource(&cameraSource);
+ sp<MediaSource> mediaSource;
+ status_t err = setupMediaSource(&mediaSource);
if (err != OK) {
return err;
}
sp<MediaSource> encoder;
- err = setupVideoEncoder(cameraSource, mVideoBitRate, &encoder);
+ err = setupVideoEncoder(mediaSource, mVideoBitRate, &encoder);
if (err != OK) {
return err;
@@ -1081,10 +1074,69 @@
clipVideoFrameRate();
clipVideoFrameWidth();
clipVideoFrameHeight();
+ setDefaultProfileIfNecessary();
}
return OK;
}
+// Set to use AVC baseline profile if the encoding parameters matches
+// CAMCORDER_QUALITY_LOW profile; this is for the sake of MMS service.
+void StagefrightRecorder::setDefaultProfileIfNecessary() {
+ LOGV("setDefaultProfileIfNecessary");
+
+ camcorder_quality quality = CAMCORDER_QUALITY_LOW;
+
+ int64_t durationUs = mEncoderProfiles->getCamcorderProfileParamByName(
+ "duration", mCameraId, quality) * 1000000LL;
+
+ int fileFormat = mEncoderProfiles->getCamcorderProfileParamByName(
+ "file.format", mCameraId, quality);
+
+ int videoCodec = mEncoderProfiles->getCamcorderProfileParamByName(
+ "vid.codec", mCameraId, quality);
+
+ int videoBitRate = mEncoderProfiles->getCamcorderProfileParamByName(
+ "vid.bps", mCameraId, quality);
+
+ int videoFrameRate = mEncoderProfiles->getCamcorderProfileParamByName(
+ "vid.fps", mCameraId, quality);
+
+ int videoFrameWidth = mEncoderProfiles->getCamcorderProfileParamByName(
+ "vid.width", mCameraId, quality);
+
+ int videoFrameHeight = mEncoderProfiles->getCamcorderProfileParamByName(
+ "vid.height", mCameraId, quality);
+
+ int audioCodec = mEncoderProfiles->getCamcorderProfileParamByName(
+ "aud.codec", mCameraId, quality);
+
+ int audioBitRate = mEncoderProfiles->getCamcorderProfileParamByName(
+ "aud.bps", mCameraId, quality);
+
+ int audioSampleRate = mEncoderProfiles->getCamcorderProfileParamByName(
+ "aud.hz", mCameraId, quality);
+
+ int audioChannels = mEncoderProfiles->getCamcorderProfileParamByName(
+ "aud.ch", mCameraId, quality);
+
+ if (durationUs == mMaxFileDurationUs &&
+ fileFormat == mOutputFormat &&
+ videoCodec == mVideoEncoder &&
+ videoBitRate == mVideoBitRate &&
+ videoFrameRate == mFrameRate &&
+ videoFrameWidth == mVideoWidth &&
+ videoFrameHeight == mVideoHeight &&
+ audioCodec == mAudioEncoder &&
+ audioBitRate == mAudioBitRate &&
+ audioSampleRate == mSampleRate &&
+ audioChannels == mAudioChannels) {
+ if (videoCodec == VIDEO_ENCODER_H264) {
+ LOGI("Force to use AVC baseline profile");
+ setParamVideoEncoderProfile(OMX_VIDEO_AVCProfileBaseline);
+ }
+ }
+}
+
status_t StagefrightRecorder::checkAudioEncoderCapabilities() {
clipAudioBitRate();
clipAudioSampleRate();
@@ -1175,6 +1227,60 @@
}
}
+// Set up the appropriate MediaSource depending on the chosen option
+status_t StagefrightRecorder::setupMediaSource(
+ sp<MediaSource> *mediaSource) {
+ if (mVideoSource == VIDEO_SOURCE_DEFAULT
+ || mVideoSource == VIDEO_SOURCE_CAMERA) {
+ sp<CameraSource> cameraSource;
+ status_t err = setupCameraSource(&cameraSource);
+ if (err != OK) {
+ return err;
+ }
+ *mediaSource = cameraSource;
+ } else if (mVideoSource == VIDEO_SOURCE_GRALLOC_BUFFER) {
+ // If using GRAlloc buffers, setup surfacemediasource.
+ // Later a handle to that will be passed
+ // to the client side when queried
+ status_t err = setupSurfaceMediaSource();
+ if (err != OK) {
+ return err;
+ }
+ *mediaSource = mSurfaceMediaSource;
+ } else {
+ return INVALID_OPERATION;
+ }
+ return OK;
+}
+
+// setupSurfaceMediaSource creates a source with the given
+// width and height and framerate.
+// TODO: This could go in a static function inside SurfaceMediaSource
+// similar to that in CameraSource
+status_t StagefrightRecorder::setupSurfaceMediaSource() {
+ status_t err = OK;
+ mSurfaceMediaSource = new SurfaceMediaSource(mVideoWidth, mVideoHeight);
+ if (mSurfaceMediaSource == NULL) {
+ return NO_INIT;
+ }
+
+ if (mFrameRate == -1) {
+ int32_t frameRate = 0;
+ CHECK (mSurfaceMediaSource->getFormat()->findInt32(
+ kKeyFrameRate, &frameRate));
+ LOGI("Frame rate is not explicitly set. Use the current frame "
+ "rate (%d fps)", frameRate);
+ mFrameRate = frameRate;
+ } else {
+ err = mSurfaceMediaSource->setFrameRate(mFrameRate);
+ }
+ CHECK(mFrameRate != -1);
+
+ mIsMetaDataStoredInVideoBuffers =
+ mSurfaceMediaSource->isMetaDataStoredInVideoBuffers();
+ return err;
+}
+
status_t StagefrightRecorder::setupCameraSource(
sp<CameraSource> *cameraSource) {
status_t err = OK;
@@ -1186,15 +1292,17 @@
videoSize.height = mVideoHeight;
if (mCaptureTimeLapse) {
mCameraSourceTimeLapse = CameraSourceTimeLapse::CreateFromCamera(
- mCamera, mCameraId,
+ mCamera, mCameraProxy, mCameraId,
videoSize, mFrameRate, mPreviewSurface,
mTimeBetweenTimeLapseFrameCaptureUs);
*cameraSource = mCameraSourceTimeLapse;
} else {
*cameraSource = CameraSource::CreateFromCamera(
- mCamera, mCameraId, videoSize, mFrameRate,
+ mCamera, mCameraProxy, mCameraId, videoSize, mFrameRate,
mPreviewSurface, true /*storeMetaDataInVideoBuffers*/);
}
+ mCamera.clear();
+ mCameraProxy.clear();
if (*cameraSource == NULL) {
return UNKNOWN_ERROR;
}
@@ -1338,7 +1446,6 @@
}
status_t StagefrightRecorder::setupMPEG4Recording(
- bool useSplitCameraSource,
int outputFd,
int32_t videoWidth, int32_t videoHeight,
int32_t videoBitRate,
@@ -1349,29 +1456,16 @@
status_t err = OK;
sp<MediaWriter> writer = new MPEG4Writer(outputFd);
- if (mVideoSource == VIDEO_SOURCE_DEFAULT
- || mVideoSource == VIDEO_SOURCE_CAMERA) {
+ if (mVideoSource < VIDEO_SOURCE_LIST_END) {
- sp<MediaSource> cameraMediaSource;
- if (useSplitCameraSource) {
- LOGV("Using Split camera source");
- cameraMediaSource = mCameraSourceSplitter->createClient();
- } else {
- sp<CameraSource> cameraSource;
- err = setupCameraSource(&cameraSource);
- cameraMediaSource = cameraSource;
- }
- if ((videoWidth != mVideoWidth) || (videoHeight != mVideoHeight)) {
- // Use downsampling from the original source.
- cameraMediaSource =
- new VideoSourceDownSampler(cameraMediaSource, videoWidth, videoHeight);
- }
+ sp<MediaSource> mediaSource;
+ err = setupMediaSource(&mediaSource);
if (err != OK) {
return err;
}
sp<MediaSource> encoder;
- err = setupVideoEncoder(cameraMediaSource, videoBitRate, &encoder);
+ err = setupVideoEncoder(mediaSource, videoBitRate, &encoder);
if (err != OK) {
return err;
}
@@ -1383,7 +1477,7 @@
// Audio source is added at the end if it exists.
// This help make sure that the "recoding" sound is suppressed for
// camcorder applications in the recorded files.
- if (!mCaptureTimeLapse && (mAudioSource != AUDIO_SOURCE_LIST_END)) {
+ if (!mCaptureTimeLapse && (mAudioSource != AUDIO_SOURCE_CNT)) {
err = setupAudioEncoder(writer);
if (err != OK) return err;
*totalBitRate += mAudioBitRate;
@@ -1393,6 +1487,10 @@
reinterpret_cast<MPEG4Writer *>(writer.get())->
setInterleaveDuration(mInterleaveDurationUs);
}
+ if (mLongitudex10000 > -3600000 && mLatitudex10000 > -3600000) {
+ reinterpret_cast<MPEG4Writer *>(writer.get())->
+ setGeoData(mLatitudex10000, mLongitudex10000);
+ }
if (mMaxFileDurationUs != 0) {
writer->setMaxFileDuration(mMaxFileDurationUs);
}
@@ -1400,6 +1498,12 @@
writer->setMaxFileSize(mMaxFileSizeBytes);
}
+ mStartTimeOffsetMs = mEncoderProfiles->getStartTimeOffsetMs(mCameraId);
+ if (mStartTimeOffsetMs > 0) {
+ reinterpret_cast<MPEG4Writer *>(writer.get())->
+ setStartTimeOffsetMs(mStartTimeOffsetMs);
+ }
+
writer->setListener(mListener);
*mediaWriter = writer;
return OK;
@@ -1423,24 +1527,8 @@
}
status_t StagefrightRecorder::startMPEG4Recording() {
- if (mCaptureAuxVideo) {
- if (!mCaptureTimeLapse) {
- LOGE("Auxiliary video can be captured only in time lapse mode");
- return UNKNOWN_ERROR;
- }
- LOGV("Creating MediaSourceSplitter");
- sp<CameraSource> cameraSource;
- status_t err = setupCameraSource(&cameraSource);
- if (err != OK) {
- return err;
- }
- mCameraSourceSplitter = new MediaSourceSplitter(cameraSource);
- } else {
- mCameraSourceSplitter = NULL;
- }
-
int32_t totalBitRate;
- status_t err = setupMPEG4Recording(mCaptureAuxVideo,
+ status_t err = setupMPEG4Recording(
mOutputFd, mVideoWidth, mVideoHeight,
mVideoBitRate, &totalBitRate, &mWriter);
if (err != OK) {
@@ -1456,33 +1544,6 @@
return err;
}
- if (mCaptureAuxVideo) {
- CHECK(mOutputFdAux >= 0);
- if (mWriterAux != NULL) {
- LOGE("Auxiliary File writer is not avaialble");
- return UNKNOWN_ERROR;
- }
- if ((mAuxVideoWidth > mVideoWidth) || (mAuxVideoHeight > mVideoHeight) ||
- ((mAuxVideoWidth == mVideoWidth) && mAuxVideoHeight == mVideoHeight)) {
- LOGE("Auxiliary video size (%d x %d) same or larger than the main video size (%d x %d)",
- mAuxVideoWidth, mAuxVideoHeight, mVideoWidth, mVideoHeight);
- return UNKNOWN_ERROR;
- }
-
- int32_t totalBitrateAux;
- err = setupMPEG4Recording(mCaptureAuxVideo,
- mOutputFdAux, mAuxVideoWidth, mAuxVideoHeight,
- mAuxVideoBitRate, &totalBitrateAux, &mWriterAux);
- if (err != OK) {
- return err;
- }
-
- sp<MetaData> metaAux = new MetaData;
- setupMPEG4MetaData(startTimeUs, totalBitrateAux, &metaAux);
-
- return mWriterAux->start(metaAux.get());
- }
-
return OK;
}
@@ -1493,18 +1554,11 @@
}
mWriter->pause();
- if (mCaptureAuxVideo) {
- if (mWriterAux == NULL) {
- return UNKNOWN_ERROR;
- }
- mWriterAux->pause();
- }
-
if (mStarted) {
mStarted = false;
uint32_t params = 0;
- if (mAudioSource != AUDIO_SOURCE_LIST_END) {
+ if (mAudioSource != AUDIO_SOURCE_CNT) {
params |= IMediaPlayerService::kBatteryDataTrackAudio;
}
if (mVideoSource != VIDEO_SOURCE_LIST_END) {
@@ -1527,13 +1581,6 @@
mCameraSourceTimeLapse = NULL;
}
- if (mCaptureAuxVideo) {
- if (mWriterAux != NULL) {
- mWriterAux->stop();
- mWriterAux.clear();
- }
- }
-
if (mWriter != NULL) {
err = mWriter->stop();
mWriter.clear();
@@ -1544,18 +1591,11 @@
mOutputFd = -1;
}
- if (mCaptureAuxVideo) {
- if (mOutputFdAux >= 0) {
- ::close(mOutputFdAux);
- mOutputFdAux = -1;
- }
- }
-
if (mStarted) {
mStarted = false;
uint32_t params = 0;
- if (mAudioSource != AUDIO_SOURCE_LIST_END) {
+ if (mAudioSource != AUDIO_SOURCE_CNT) {
params |= IMediaPlayerService::kBatteryDataTrackAudio;
}
if (mVideoSource != VIDEO_SOURCE_LIST_END) {
@@ -1581,7 +1621,7 @@
stop();
// No audio or video source by default
- mAudioSource = AUDIO_SOURCE_LIST_END;
+ mAudioSource = AUDIO_SOURCE_CNT;
mVideoSource = VIDEO_SOURCE_LIST_END;
// Default parameters
@@ -1590,11 +1630,8 @@
mVideoEncoder = VIDEO_ENCODER_H263;
mVideoWidth = 176;
mVideoHeight = 144;
- mAuxVideoWidth = 176;
- mAuxVideoHeight = 144;
mFrameRate = -1;
mVideoBitRate = 192000;
- mAuxVideoBitRate = 192000;
mSampleRate = 8000;
mAudioChannels = 1;
mAudioBitRate = 12200;
@@ -1606,6 +1643,7 @@
mAudioTimeScale = -1;
mVideoTimeScale = -1;
mCameraId = 0;
+ mStartTimeOffsetMs = -1;
mVideoEncoderProfile = -1;
mVideoEncoderLevel = -1;
mMaxFileDurationUs = 0;
@@ -1613,15 +1651,14 @@
mTrackEveryTimeDurationUs = 0;
mCaptureTimeLapse = false;
mTimeBetweenTimeLapseFrameCaptureUs = -1;
- mCaptureAuxVideo = false;
- mCameraSourceSplitter = NULL;
mCameraSourceTimeLapse = NULL;
mIsMetaDataStoredInVideoBuffers = false;
mEncoderProfiles = MediaProfiles::getInstance();
mRotationDegrees = 0;
+ mLatitudex10000 = -3600000;
+ mLongitudex10000 = -3600000;
mOutputFd = -1;
- mOutputFdAux = -1;
return OK;
}
@@ -1658,8 +1695,6 @@
snprintf(buffer, SIZE, " Recorder: %p\n", this);
snprintf(buffer, SIZE, " Output file (fd %d):\n", mOutputFd);
result.append(buffer);
- snprintf(buffer, SIZE, " Output file Auxiliary (fd %d):\n", mOutputFdAux);
- result.append(buffer);
snprintf(buffer, SIZE, " File format: %d\n", mOutputFormat);
result.append(buffer);
snprintf(buffer, SIZE, " Max file size (bytes): %lld\n", mMaxFileSizeBytes);
@@ -1692,6 +1727,8 @@
result.append(buffer);
snprintf(buffer, SIZE, " Camera Id: %d\n", mCameraId);
result.append(buffer);
+ snprintf(buffer, SIZE, " Start time offset (ms): %d\n", mStartTimeOffsetMs);
+ result.append(buffer);
snprintf(buffer, SIZE, " Encoder: %d\n", mVideoEncoder);
result.append(buffer);
snprintf(buffer, SIZE, " Encoder profile: %d\n", mVideoEncoderProfile);
@@ -1702,14 +1739,10 @@
result.append(buffer);
snprintf(buffer, SIZE, " Frame size (pixels): %dx%d\n", mVideoWidth, mVideoHeight);
result.append(buffer);
- snprintf(buffer, SIZE, " Aux Frame size (pixels): %dx%d\n", mAuxVideoWidth, mAuxVideoHeight);
- result.append(buffer);
snprintf(buffer, SIZE, " Frame rate (fps): %d\n", mFrameRate);
result.append(buffer);
snprintf(buffer, SIZE, " Bit rate (bps): %d\n", mVideoBitRate);
result.append(buffer);
- snprintf(buffer, SIZE, " Aux Bit rate (bps): %d\n", mAuxVideoBitRate);
- result.append(buffer);
::write(fd, result.string(), result.size());
return OK;
}
diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h
index 2c440c1..5c5f05c 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.h
+++ b/media/libmediaplayerservice/StagefrightRecorder.h
@@ -22,35 +22,38 @@
#include <camera/CameraParameters.h>
#include <utils/String8.h>
+#include <system/audio.h>
+
namespace android {
class Camera;
+class ICameraRecordingProxy;
class CameraSource;
class CameraSourceTimeLapse;
-class MediaSourceSplitter;
struct MediaSource;
struct MediaWriter;
class MetaData;
struct AudioSource;
class MediaProfiles;
+class ISurfaceTexture;
+class SurfaceMediaSource;
struct StagefrightRecorder : public MediaRecorderBase {
StagefrightRecorder();
virtual ~StagefrightRecorder();
virtual status_t init();
- virtual status_t setAudioSource(audio_source as);
+ virtual status_t setAudioSource(audio_source_t as);
virtual status_t setVideoSource(video_source vs);
virtual status_t setOutputFormat(output_format of);
virtual status_t setAudioEncoder(audio_encoder ae);
virtual status_t setVideoEncoder(video_encoder ve);
virtual status_t setVideoSize(int width, int height);
virtual status_t setVideoFrameRate(int frames_per_second);
- virtual status_t setCamera(const sp<ICamera>& camera);
+ virtual status_t setCamera(const sp<ICamera>& camera, const sp<ICameraRecordingProxy>& proxy);
virtual status_t setPreviewSurface(const sp<Surface>& surface);
virtual status_t setOutputFile(const char *path);
virtual status_t setOutputFile(int fd, int64_t offset, int64_t length);
- virtual status_t setOutputFileAuxiliary(int fd);
virtual status_t setParameters(const String8& params);
virtual status_t setListener(const sp<IMediaRecorderClient>& listener);
virtual status_t prepare();
@@ -61,24 +64,27 @@
virtual status_t reset();
virtual status_t getMaxAmplitude(int *max);
virtual status_t dump(int fd, const Vector<String16>& args) const;
+ // Querying a SurfaceMediaSourcer
+ virtual sp<ISurfaceTexture> querySurfaceMediaSource() const;
private:
sp<ICamera> mCamera;
+ sp<ICameraRecordingProxy> mCameraProxy;
sp<Surface> mPreviewSurface;
sp<IMediaRecorderClient> mListener;
- sp<MediaWriter> mWriter, mWriterAux;
+ sp<MediaWriter> mWriter;
+ int mOutputFd;
sp<AudioSource> mAudioSourceNode;
- audio_source mAudioSource;
+ audio_source_t mAudioSource;
video_source mVideoSource;
output_format mOutputFormat;
audio_encoder mAudioEncoder;
video_encoder mVideoEncoder;
bool mUse64BitFileOffset;
int32_t mVideoWidth, mVideoHeight;
- int32_t mAuxVideoWidth, mAuxVideoHeight;
int32_t mFrameRate;
- int32_t mVideoBitRate, mAuxVideoBitRate;
+ int32_t mVideoBitRate;
int32_t mAudioBitRate;
int32_t mAudioChannels;
int32_t mSampleRate;
@@ -94,23 +100,28 @@
int64_t mMaxFileDurationUs;
int64_t mTrackEveryTimeDurationUs;
int32_t mRotationDegrees; // Clockwise
+ int32_t mLatitudex10000;
+ int32_t mLongitudex10000;
+ int32_t mStartTimeOffsetMs;
bool mCaptureTimeLapse;
int64_t mTimeBetweenTimeLapseFrameCaptureUs;
- bool mCaptureAuxVideo;
- sp<MediaSourceSplitter> mCameraSourceSplitter;
sp<CameraSourceTimeLapse> mCameraSourceTimeLapse;
+
String8 mParams;
- int mOutputFd, mOutputFdAux;
bool mIsMetaDataStoredInVideoBuffers;
MediaProfiles *mEncoderProfiles;
bool mStarted;
+ // Needed when GLFrames are encoded.
+ // An <ISurfaceTexture> pointer
+ // will be sent to the client side using which the
+ // frame buffers will be queued and dequeued
+ sp<SurfaceMediaSource> mSurfaceMediaSource;
status_t setupMPEG4Recording(
- bool useSplitCameraSource,
int outputFd,
int32_t videoWidth, int32_t videoHeight,
int32_t videoBitRate,
@@ -121,12 +132,20 @@
status_t startMPEG4Recording();
status_t startAMRRecording();
status_t startAACRecording();
+ status_t startRawAudioRecording();
status_t startRTPRecording();
status_t startMPEG2TSRecording();
sp<MediaSource> createAudioSource();
status_t checkVideoEncoderCapabilities();
status_t checkAudioEncoderCapabilities();
+ // Generic MediaSource set-up. Returns the appropriate
+ // source (CameraSource or SurfaceMediaSource)
+ // depending on the videosource type
+ status_t setupMediaSource(sp<MediaSource> *mediaSource);
status_t setupCameraSource(sp<CameraSource> *cameraSource);
+ // setup the surfacemediasource for the encoder
+ status_t setupSurfaceMediaSource();
+
status_t setupAudioEncoder(const sp<MediaWriter>& writer);
status_t setupVideoEncoder(
sp<MediaSource> cameraSource,
@@ -141,9 +160,6 @@
status_t setParamAudioTimeScale(int32_t timeScale);
status_t setParamTimeLapseEnable(int32_t timeLapseEnable);
status_t setParamTimeBetweenTimeLapseFrameCapture(int64_t timeUs);
- status_t setParamAuxVideoHeight(int32_t height);
- status_t setParamAuxVideoWidth(int32_t width);
- status_t setParamAuxVideoEncodingBitRate(int32_t bitRate);
status_t setParamVideoEncodingBitRate(int32_t bitRate);
status_t setParamVideoIFramesInterval(int32_t seconds);
status_t setParamVideoEncoderProfile(int32_t profile);
@@ -157,6 +173,8 @@
status_t setParamMaxFileDurationUs(int64_t timeUs);
status_t setParamMaxFileSizeBytes(int64_t bytes);
status_t setParamMovieTimeScale(int32_t timeScale);
+ status_t setParamGeoDataLongitude(int32_t longitudex10000);
+ status_t setParamGeoDataLatitude(int32_t latitudex10000);
void clipVideoBitRate();
void clipVideoFrameRate();
void clipVideoFrameWidth();
@@ -164,6 +182,8 @@
void clipAudioBitRate();
void clipAudioSampleRate();
void clipNumberOfAudioChannels();
+ void setDefaultProfileIfNecessary();
+
StagefrightRecorder(const StagefrightRecorder &);
StagefrightRecorder &operator=(const StagefrightRecorder &);
diff --git a/media/libmediaplayerservice/TestPlayerStub.h b/media/libmediaplayerservice/TestPlayerStub.h
index d9c3db3..802a11b 100644
--- a/media/libmediaplayerservice/TestPlayerStub.h
+++ b/media/libmediaplayerservice/TestPlayerStub.h
@@ -99,6 +99,12 @@
virtual status_t invoke(const android::Parcel& in, android::Parcel *out) {
return mPlayer->invoke(in, out);
}
+ virtual status_t setParameter(int key, const Parcel &request) {
+ return mPlayer->setParameter(key, request);
+ }
+ virtual status_t getParameter(int key, Parcel *reply) {
+ return mPlayer->getParameter(key, reply);
+ }
// @return true if the current build is 'eng' or 'test' and the
diff --git a/media/libmediaplayerservice/nuplayer/Android.mk b/media/libmediaplayerservice/nuplayer/Android.mk
index c20e279..e761509 100644
--- a/media/libmediaplayerservice/nuplayer/Android.mk
+++ b/media/libmediaplayerservice/nuplayer/Android.mk
@@ -8,7 +8,6 @@
NuPlayerDriver.cpp \
NuPlayerRenderer.cpp \
NuPlayerStreamListener.cpp \
- DecoderWrapper.cpp \
StreamingSource.cpp \
LOCAL_C_INCLUDES := \
diff --git a/media/libmediaplayerservice/nuplayer/DecoderWrapper.cpp b/media/libmediaplayerservice/nuplayer/DecoderWrapper.cpp
deleted file mode 100644
index 802d1fb..0000000
--- a/media/libmediaplayerservice/nuplayer/DecoderWrapper.cpp
+++ /dev/null
@@ -1,576 +0,0 @@
-/*
- * Copyright (C) 2010 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 "DecoderWrapper"
-#include <utils/Log.h>
-
-#include "DecoderWrapper.h"
-
-#include "AACDecoder.h"
-
-#include <media/stagefright/foundation/hexdump.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/ACodec.h>
-#include <media/stagefright/MediaBuffer.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MediaSource.h>
-#include <media/stagefright/MetaData.h>
-
-namespace android {
-
-struct DecoderWrapper::WrapperSource : public MediaSource {
- WrapperSource(
- const sp<MetaData> &meta,
- const sp<AMessage> ¬ify);
-
- virtual status_t start(MetaData *params);
- virtual status_t stop();
- virtual sp<MetaData> getFormat();
-
- virtual status_t read(
- MediaBuffer **buffer, const ReadOptions *options);
-
- void queueBuffer(const sp<ABuffer> &buffer);
- void queueEOS(status_t finalResult);
- void clear();
-
-protected:
- virtual ~WrapperSource();
-
-private:
- Mutex mLock;
- Condition mCondition;
-
- sp<MetaData> mMeta;
- sp<AMessage> mNotify;
-
- List<sp<ABuffer> > mQueue;
- status_t mFinalResult;
-
- DISALLOW_EVIL_CONSTRUCTORS(WrapperSource);
-};
-
-DecoderWrapper::WrapperSource::WrapperSource(
- const sp<MetaData> &meta, const sp<AMessage> ¬ify)
- : mMeta(meta),
- mNotify(notify),
- mFinalResult(OK) {
-}
-
-DecoderWrapper::WrapperSource::~WrapperSource() {
-}
-
-status_t DecoderWrapper::WrapperSource::start(MetaData *params) {
- return OK;
-}
-
-status_t DecoderWrapper::WrapperSource::stop() {
- return OK;
-}
-
-sp<MetaData> DecoderWrapper::WrapperSource::getFormat() {
- return mMeta;
-}
-
-status_t DecoderWrapper::WrapperSource::read(
- MediaBuffer **out, const ReadOptions *options) {
- Mutex::Autolock autoLock(mLock);
-
- bool requestedBuffer = false;
-
- while (mQueue.empty() && mFinalResult == OK) {
- if (!requestedBuffer) {
- mNotify->dup()->post();
- requestedBuffer = true;
- }
-
- mCondition.wait(mLock);
- }
-
- if (mQueue.empty()) {
- return mFinalResult;
- }
-
- sp<ABuffer> src = *mQueue.begin();
- mQueue.erase(mQueue.begin());
-
- MediaBuffer *dst = new MediaBuffer(src->size());
- memcpy(dst->data(), src->data(), src->size());
-
- int64_t timeUs;
- CHECK(src->meta()->findInt64("timeUs", &timeUs));
-
- dst->meta_data()->setInt64(kKeyTime, timeUs);
-
- *out = dst;
-
- return OK;
-}
-
-void DecoderWrapper::WrapperSource::queueBuffer(const sp<ABuffer> &buffer) {
- Mutex::Autolock autoLock(mLock);
- mQueue.push_back(buffer);
- mCondition.broadcast();
-}
-
-void DecoderWrapper::WrapperSource::queueEOS(status_t finalResult) {
- CHECK_NE(finalResult, (status_t)OK);
-
- Mutex::Autolock autoLock(mLock);
- mFinalResult = finalResult;
- mCondition.broadcast();
-}
-
-void DecoderWrapper::WrapperSource::clear() {
- Mutex::Autolock autoLock(mLock);
- mQueue.clear();
- mFinalResult = OK;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-struct DecoderWrapper::WrapperReader : public AHandler {
- WrapperReader(
- const sp<MediaSource> &decoder,
- const sp<AMessage> ¬ify);
-
- void start();
- void stop();
- void readMore(bool flush = false);
-
-protected:
- virtual ~WrapperReader();
-
- virtual void onMessageReceived(const sp<AMessage> &msg);
-
-private:
- enum {
- kWhatRead
- };
-
- sp<MediaSource> mDecoder;
- sp<AMessage> mNotify;
- bool mEOS;
- bool mSentFormat;
-
- void sendFormatChange();
-
- DISALLOW_EVIL_CONSTRUCTORS(WrapperReader);
-};
-
-DecoderWrapper::WrapperReader::WrapperReader(
- const sp<MediaSource> &decoder, const sp<AMessage> ¬ify)
- : mDecoder(decoder),
- mNotify(notify),
- mEOS(false),
- mSentFormat(false) {
-}
-
-DecoderWrapper::WrapperReader::~WrapperReader() {
-}
-
-void DecoderWrapper::WrapperReader::start() {
- CHECK_EQ(mDecoder->start(), (status_t)OK);
- readMore();
-}
-
-void DecoderWrapper::WrapperReader::stop() {
- CHECK_EQ(mDecoder->stop(), (status_t)OK);
-}
-
-void DecoderWrapper::WrapperReader::readMore(bool flush) {
- if (!flush && mEOS) {
- return;
- }
-
- sp<AMessage> msg = new AMessage(kWhatRead, id());
- msg->setInt32("flush", static_cast<int32_t>(flush));
- msg->post();
-}
-
-void DecoderWrapper::WrapperReader::onMessageReceived(
- const sp<AMessage> &msg) {
- switch (msg->what()) {
- case kWhatRead:
- {
- int32_t flush;
- CHECK(msg->findInt32("flush", &flush));
-
- MediaSource::ReadOptions options;
- if (flush) {
- // Dummy seek
- options.setSeekTo(0);
- mEOS = false;
- }
-
- CHECK(!mEOS);
-
- MediaBuffer *src;
- status_t err = mDecoder->read(&src, &options);
-
- if (err == OK) {
- if (!mSentFormat) {
- sendFormatChange();
- mSentFormat = true;
- }
-
- sp<AMessage> notify = mNotify->dup();
-
- sp<AMessage> realNotify;
- CHECK(notify->findMessage("real-notify", &realNotify));
-
- realNotify->setInt32("what", ACodec::kWhatDrainThisBuffer);
-
- sp<ABuffer> dst = new ABuffer(src->range_length());
- memcpy(dst->data(),
- (const uint8_t *)src->data() + src->range_offset(),
- src->range_length());
-
- int64_t timeUs;
- CHECK(src->meta_data()->findInt64(kKeyTime, &timeUs));
- src->release();
- src = NULL;
-
- dst->meta()->setInt64("timeUs", timeUs);
-
- realNotify->setObject("buffer", dst);
-
- notify->post();
- } else if (err == INFO_FORMAT_CHANGED) {
- sendFormatChange();
-
- readMore(false /* flush */);
- } else {
- sp<AMessage> notify = mNotify->dup();
-
- sp<AMessage> realNotify;
- CHECK(notify->findMessage("real-notify", &realNotify));
-
- realNotify->setInt32("what", ACodec::kWhatEOS);
- mEOS = true;
-
- notify->post();
- }
- break;
- }
-
- default:
- TRESPASS();
- break;
- }
-}
-
-void DecoderWrapper::WrapperReader::sendFormatChange() {
- sp<AMessage> notify = mNotify->dup();
-
- sp<AMessage> realNotify;
- CHECK(notify->findMessage("real-notify", &realNotify));
-
- realNotify->setInt32("what", ACodec::kWhatOutputFormatChanged);
-
- sp<MetaData> meta = mDecoder->getFormat();
-
- const char *mime;
- CHECK(meta->findCString(kKeyMIMEType, &mime));
-
- realNotify->setString("mime", mime);
-
- if (!strncasecmp("audio/", mime, 6)) {
- int32_t numChannels;
- CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
-
- int32_t sampleRate;
- CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
-
- realNotify->setInt32("channel-count", numChannels);
- realNotify->setInt32("sample-rate", sampleRate);
- } else {
- CHECK(!strncasecmp("video/", mime, 6));
-
- int32_t width, height;
- CHECK(meta->findInt32(kKeyWidth, &width));
- CHECK(meta->findInt32(kKeyHeight, &height));
-
- realNotify->setInt32("width", width);
- realNotify->setInt32("height", height);
-
- int32_t cropLeft, cropTop, cropRight, cropBottom;
- if (!meta->findRect(
- kKeyCropRect,
- &cropLeft, &cropTop, &cropRight, &cropBottom)) {
- cropLeft = 0;
- cropTop = 0;
- cropRight = width - 1;
- cropBottom = height - 1;
- }
-
- realNotify->setRect("crop", cropLeft, cropTop, cropRight, cropBottom);
- }
-
- notify->post();
-
- mSentFormat = true;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-DecoderWrapper::DecoderWrapper()
- : mNumOutstandingInputBuffers(0),
- mNumOutstandingOutputBuffers(0),
- mNumPendingDecodes(0),
- mFlushing(false) {
-}
-
-DecoderWrapper::~DecoderWrapper() {
-}
-
-void DecoderWrapper::setNotificationMessage(const sp<AMessage> &msg) {
- mNotify = msg;
-}
-
-void DecoderWrapper::initiateSetup(const sp<AMessage> &msg) {
- msg->setWhat(kWhatSetup);
- msg->setTarget(id());
- msg->post();
-}
-
-void DecoderWrapper::initiateShutdown() {
- (new AMessage(kWhatShutdown, id()))->post();
-}
-
-void DecoderWrapper::signalFlush() {
- (new AMessage(kWhatFlush, id()))->post();
-}
-
-void DecoderWrapper::signalResume() {
- (new AMessage(kWhatResume, id()))->post();
-}
-
-void DecoderWrapper::onMessageReceived(const sp<AMessage> &msg) {
- switch (msg->what()) {
- case kWhatSetup:
- onSetup(msg);
- break;
-
- case kWhatShutdown:
- onShutdown();
- break;
-
- case kWhatInputDataRequested:
- {
- postFillBuffer();
- ++mNumOutstandingInputBuffers;
- break;
- }
-
- case kWhatInputBufferFilled:
- {
- CHECK_GT(mNumOutstandingInputBuffers, 0);
- --mNumOutstandingInputBuffers;
-
- if (mFlushing) {
- mSource->queueEOS(INFO_DISCONTINUITY);
-
- completeFlushIfPossible();
- break;
- }
-
- sp<RefBase> obj;
- if (!msg->findObject("buffer", &obj)) {
- int32_t err = OK;
- CHECK(msg->findInt32("err", &err));
-
- mSource->queueEOS(err);
- break;
- }
-
- sp<ABuffer> buffer = static_cast<ABuffer *>(obj.get());
-
- mSource->queueBuffer(buffer);
- break;
- }
-
- case kWhatFillBufferDone:
- {
- sp<AMessage> notify;
- CHECK(msg->findMessage("real-notify", ¬ify));
-
- int32_t what;
- CHECK(notify->findInt32("what", &what));
-
- if (what == ACodec::kWhatDrainThisBuffer) {
- CHECK_GT(mNumPendingDecodes, 0);
- --mNumPendingDecodes;
-
- sp<AMessage> reply =
- new AMessage(kWhatOutputBufferDrained, id());
-
- notify->setMessage("reply", reply);
-
- ++mNumOutstandingOutputBuffers;
- } else if (what == ACodec::kWhatEOS) {
- CHECK_GT(mNumPendingDecodes, 0);
- --mNumPendingDecodes;
-
- if (mFlushing) {
- completeFlushIfPossible();
- break;
- }
- }
-
- notify->post();
- break;
- }
-
- case kWhatOutputBufferDrained:
- {
- CHECK_GT(mNumOutstandingOutputBuffers, 0);
- --mNumOutstandingOutputBuffers;
-
- if (mFlushing) {
- completeFlushIfPossible();
- break;
- }
-
- ++mNumPendingDecodes;
- mReader->readMore();
- break;
- }
-
- case kWhatFlush:
- {
- onFlush();
- break;
- }
-
- case kWhatResume:
- {
- onResume();
- break;
- }
-
- default:
- TRESPASS();
- break;
- }
-}
-
-void DecoderWrapper::onSetup(const sp<AMessage> &msg) {
- AString mime;
- CHECK(msg->findString("mime", &mime));
-
- CHECK(!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC));
-
- int32_t numChannels, sampleRate;
- CHECK(msg->findInt32("channel-count", &numChannels));
- CHECK(msg->findInt32("sample-rate", &sampleRate));
-
- sp<RefBase> obj;
- CHECK(msg->findObject("esds", &obj));
- sp<ABuffer> esds = static_cast<ABuffer *>(obj.get());
-
- sp<MetaData> meta = new MetaData;
- meta->setCString(kKeyMIMEType, mime.c_str());
- meta->setInt32(kKeySampleRate, sampleRate);
- meta->setInt32(kKeyChannelCount, numChannels);
- meta->setData(kKeyESDS, 0, esds->data(), esds->size());
-
- mSource = new WrapperSource(
- meta, new AMessage(kWhatInputDataRequested, id()));
-
- sp<MediaSource> decoder = new AACDecoder(mSource);
-
- mReaderLooper = new ALooper;
- mReaderLooper->setName("DecoderWrapper looper");
-
- mReaderLooper->start(
- false, /* runOnCallingThread */
- false, /* canCallJava */
- PRIORITY_AUDIO);
-
- sp<AMessage> notify = new AMessage(kWhatFillBufferDone, id());
- notify->setMessage("real-notify", mNotify);
-
- mReader = new WrapperReader(decoder, notify);
- mReaderLooper->registerHandler(mReader);
-
- mReader->start();
- ++mNumPendingDecodes;
-}
-
-void DecoderWrapper::onShutdown() {
- mReaderLooper->stop();
- mReaderLooper.clear();
-
- mReader->stop();
- mReader.clear();
-
- mSource.clear();
-
- mNumOutstandingInputBuffers = 0;
- mNumOutstandingOutputBuffers = 0;
- mNumPendingDecodes = 0;
- mFlushing = false;
-
- sp<AMessage> notify = mNotify->dup();
- notify->setInt32("what", ACodec::kWhatShutdownCompleted);
- notify->post();
-}
-
-void DecoderWrapper::postFillBuffer() {
- sp<AMessage> notify = mNotify->dup();
- notify->setInt32("what", ACodec::kWhatFillThisBuffer);
- sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, id());
- notify->setMessage("reply", reply);
- notify->post();
-}
-
-void DecoderWrapper::onFlush() {
- CHECK(!mFlushing);
- mFlushing = true;
-
- completeFlushIfPossible();
-}
-
-void DecoderWrapper::completeFlushIfPossible() {
- CHECK(mFlushing);
-
- if (mNumOutstandingInputBuffers > 0
- || mNumOutstandingOutputBuffers > 0
- || mNumPendingDecodes > 0) {
- return;
- }
-
- mFlushing = false;
-
- sp<AMessage> notify = mNotify->dup();
- notify->setInt32("what", ACodec::kWhatFlushCompleted);
- notify->post();
-}
-
-void DecoderWrapper::onResume() {
- CHECK(!mFlushing);
-
- ++mNumPendingDecodes;
-
- mSource->clear();
- mReader->readMore(true /* flush */);
-}
-
-} // namespace android
diff --git a/media/libmediaplayerservice/nuplayer/DecoderWrapper.h b/media/libmediaplayerservice/nuplayer/DecoderWrapper.h
deleted file mode 100644
index b9be12c..0000000
--- a/media/libmediaplayerservice/nuplayer/DecoderWrapper.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2010 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 DECODER_WRAPPER_H_
-
-#define DECODER_WRAPPER_H_
-
-#include <media/stagefright/foundation/AHandler.h>
-
-namespace android {
-
-struct MediaSource;
-
-struct DecoderWrapper : public AHandler {
- DecoderWrapper();
-
- void setNotificationMessage(const sp<AMessage> &msg);
- void initiateSetup(const sp<AMessage> &msg);
- void initiateShutdown();
- void signalFlush();
- void signalResume();
-
-protected:
- virtual ~DecoderWrapper();
-
- virtual void onMessageReceived(const sp<AMessage> &msg);
-
-private:
- struct WrapperSource;
- struct WrapperReader;
-
- enum {
- kWhatSetup,
- kWhatInputBufferFilled,
- kWhatOutputBufferDrained,
- kWhatShutdown,
- kWhatFillBufferDone,
- kWhatInputDataRequested,
- kWhatFlush,
- kWhatResume,
- };
-
- sp<AMessage> mNotify;
-
- sp<WrapperSource> mSource;
-
- sp<ALooper> mReaderLooper;
- sp<WrapperReader> mReader;
-
- int32_t mNumOutstandingInputBuffers;
- int32_t mNumOutstandingOutputBuffers;
- int32_t mNumPendingDecodes;
- bool mFlushing;
-
- void onSetup(const sp<AMessage> &msg);
- void onShutdown();
- void onFlush();
- void onResume();
-
- void postFillBuffer();
- void completeFlushIfPossible();
-
- DISALLOW_EVIL_CONSTRUCTORS(DecoderWrapper);
-};
-
-} // namespace android
-
-#endif // DECODER_WRAPPER_H_
-
diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
index d07ea1b..0251baf 100644
--- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
@@ -33,16 +33,35 @@
namespace android {
-NuPlayer::HTTPLiveSource::HTTPLiveSource(const char *url, uint32_t flags)
+NuPlayer::HTTPLiveSource::HTTPLiveSource(
+ const char *url,
+ const KeyedVector<String8, String8> *headers,
+ bool uidValid, uid_t uid)
: mURL(url),
- mFlags(flags),
+ mUIDValid(uidValid),
+ mUID(uid),
+ mFlags(0),
mEOS(false),
mOffset(0) {
+ if (headers) {
+ mExtraHeaders = *headers;
+
+ ssize_t index =
+ mExtraHeaders.indexOfKey(String8("x-hide-urls-from-log"));
+
+ if (index >= 0) {
+ mFlags |= kFlagIncognito;
+
+ mExtraHeaders.removeItemsAt(index);
+ }
+ }
}
NuPlayer::HTTPLiveSource::~HTTPLiveSource() {
- mLiveSession->disconnect();
- mLiveLooper->stop();
+ if (mLiveSession != NULL) {
+ mLiveSession->disconnect();
+ mLiveLooper->stop();
+ }
}
void NuPlayer::HTTPLiveSource::start() {
@@ -51,18 +70,20 @@
mLiveLooper->start();
mLiveSession = new LiveSession(
- (mFlags & kFlagIncognito) ? LiveSession::kFlagIncognito : 0);
+ (mFlags & kFlagIncognito) ? LiveSession::kFlagIncognito : 0,
+ mUIDValid, mUID);
mLiveLooper->registerHandler(mLiveSession);
- mLiveSession->connect(mURL.c_str());
+ mLiveSession->connect(
+ mURL.c_str(), mExtraHeaders.isEmpty() ? NULL : &mExtraHeaders);
mTSParser = new ATSParser;
}
sp<MetaData> NuPlayer::HTTPLiveSource::getFormat(bool audio) {
ATSParser::SourceType type =
- audio ? ATSParser::MPEG2ADTS_AUDIO : ATSParser::AVC_VIDEO;
+ audio ? ATSParser::AUDIO : ATSParser::VIDEO;
sp<AnotherPacketSource> source =
static_cast<AnotherPacketSource *>(mTSParser->getSource(type).get());
@@ -116,7 +137,7 @@
status_t NuPlayer::HTTPLiveSource::dequeueAccessUnit(
bool audio, sp<ABuffer> *accessUnit) {
ATSParser::SourceType type =
- audio ? ATSParser::MPEG2ADTS_AUDIO : ATSParser::AVC_VIDEO;
+ audio ? ATSParser::AUDIO : ATSParser::VIDEO;
sp<AnotherPacketSource> source =
static_cast<AnotherPacketSource *>(mTSParser->getSource(type).get());
diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h
index a8ce7f4..36c67c5 100644
--- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h
+++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h
@@ -27,11 +27,11 @@
struct LiveSession;
struct NuPlayer::HTTPLiveSource : public NuPlayer::Source {
- enum Flags {
- // Don't log any URLs.
- kFlagIncognito = 1,
- };
- HTTPLiveSource(const char *url, uint32_t flags = 0);
+ HTTPLiveSource(
+ const char *url,
+ const KeyedVector<String8, String8> *headers,
+ bool uidValid = false,
+ uid_t uid = 0);
virtual void start();
@@ -49,7 +49,15 @@
virtual ~HTTPLiveSource();
private:
+ enum Flags {
+ // Don't log any URLs.
+ kFlagIncognito = 1,
+ };
+
AString mURL;
+ KeyedVector<String8, String8> mExtraHeaders;
+ bool mUIDValid;
+ uid_t mUID;
uint32_t mFlags;
bool mEOS;
off64_t mOffset;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index d439f6e..b06f20d 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -44,7 +44,8 @@
////////////////////////////////////////////////////////////////////////////////
NuPlayer::NuPlayer()
- : mAudioEOS(false),
+ : mUIDValid(false),
+ mAudioEOS(false),
mVideoEOS(false),
mScanSourcesPending(false),
mScanSourcesGeneration(0),
@@ -57,6 +58,11 @@
NuPlayer::~NuPlayer() {
}
+void NuPlayer::setUID(uid_t uid) {
+ mUIDValid = true;
+ mUID = uid;
+}
+
void NuPlayer::setDriver(const wp<NuPlayerDriver> &driver) {
mDriver = driver;
}
@@ -72,17 +78,7 @@
const char *url, const KeyedVector<String8, String8> *headers) {
sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
- uint32_t flags = 0;
-
- if (headers) {
- ssize_t index = headers->indexOfKey(String8("x-hide-urls-from-log"));
-
- if (index >= 0) {
- flags |= HTTPLiveSource::kFlagIncognito;
- }
- }
-
- msg->setObject("source", new HTTPLiveSource(url, flags));
+ msg->setObject("source", new HTTPLiveSource(url, headers, mUIDValid, mUID));
msg->post();
}
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index fb5b001..cf9185b 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -33,6 +33,8 @@
struct NuPlayer : public AHandler {
NuPlayer();
+ void setUID(uid_t uid);
+
void setDriver(const wp<NuPlayerDriver> &driver);
void setDataSource(const sp<IStreamSource> &source);
@@ -84,6 +86,8 @@
};
wp<NuPlayerDriver> mDriver;
+ bool mUIDValid;
+ uid_t mUID;
sp<Source> mSource;
sp<NativeWindowWrapper> mNativeWindow;
sp<MediaPlayerBase::AudioSink> mAudioSink;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index 517acc9..81b41ef 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -20,7 +20,6 @@
#include "NuPlayerDecoder.h"
-#include "DecoderWrapper.h"
#include "ESDS.h"
#include <media/stagefright/foundation/ABuffer.h>
@@ -47,7 +46,6 @@
void NuPlayer::Decoder::configure(const sp<MetaData> &meta) {
CHECK(mCodec == NULL);
- CHECK(mWrapper == NULL);
const char *mime;
CHECK(meta->findCString(kKeyMIMEType, &mime));
@@ -61,19 +59,11 @@
format->setObject("native-window", mNativeWindow);
}
- if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
- mWrapper = new DecoderWrapper;
- looper()->registerHandler(mWrapper);
+ mCodec = new ACodec;
+ looper()->registerHandler(mCodec);
- mWrapper->setNotificationMessage(notifyMsg);
- mWrapper->initiateSetup(format);
- } else {
- mCodec = new ACodec;
- looper()->registerHandler(mCodec);
-
- mCodec->setNotificationMessage(notifyMsg);
- mCodec->initiateSetup(format);
- }
+ mCodec->setNotificationMessage(notifyMsg);
+ mCodec->initiateSetup(format);
}
void NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) {
@@ -214,7 +204,6 @@
msg->setObject("csd", buffer);
} else if (meta->findData(kKeyESDS, &type, &data, &size)) {
-#if 0
ESDS esds((const char *)data, size);
CHECK_EQ(esds.InitCheck(), (status_t)OK);
@@ -230,12 +219,6 @@
buffer->meta()->setInt32("csd", true);
mCSD.push(buffer);
-#else
- sp<ABuffer> buffer = new ABuffer(size);
- memcpy(buffer->data(), data, size);
-
- msg->setObject("esds", buffer);
-#endif
}
return msg;
@@ -270,27 +253,18 @@
void NuPlayer::Decoder::signalFlush() {
if (mCodec != NULL) {
mCodec->signalFlush();
- } else {
- CHECK(mWrapper != NULL);
- mWrapper->signalFlush();
}
}
void NuPlayer::Decoder::signalResume() {
if (mCodec != NULL) {
mCodec->signalResume();
- } else {
- CHECK(mWrapper != NULL);
- mWrapper->signalResume();
}
}
void NuPlayer::Decoder::initiateShutdown() {
if (mCodec != NULL) {
mCodec->initiateShutdown();
- } else {
- CHECK(mWrapper != NULL);
- mWrapper->initiateShutdown();
}
}
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
index 732f090..fabc606 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
@@ -25,7 +25,6 @@
namespace android {
struct ABuffer;
-struct DecoderWrapper;
struct NuPlayer::Decoder : public AHandler {
Decoder(const sp<AMessage> ¬ify,
@@ -51,7 +50,6 @@
sp<NativeWindowWrapper> mNativeWindow;
sp<ACodec> mCodec;
- sp<DecoderWrapper> mWrapper;
Vector<sp<ABuffer> > mCSD;
size_t mCSDIndex;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index 0eca958..c6fca2c 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -55,6 +55,12 @@
return OK;
}
+status_t NuPlayerDriver::setUID(uid_t uid) {
+ mPlayer->setUID(uid);
+
+ return OK;
+}
+
status_t NuPlayerDriver::setDataSource(
const char *url, const KeyedVector<String8, String8> *headers) {
CHECK_EQ((int)mState, (int)UNINITIALIZED);
@@ -112,9 +118,15 @@
mPlayer->start();
if (mStartupSeekTimeUs >= 0) {
- mPlayer->seekToAsync(mStartupSeekTimeUs);
+ if (mStartupSeekTimeUs == 0) {
+ notifySeekComplete();
+ } else {
+ mPlayer->seekToAsync(mStartupSeekTimeUs);
+ }
+
mStartupSeekTimeUs = -1;
}
+
break;
}
case PLAYING:
@@ -246,6 +258,14 @@
mPlayer->setAudioSink(audioSink);
}
+status_t NuPlayerDriver::setParameter(int key, const Parcel &request) {
+ return INVALID_OPERATION;
+}
+
+status_t NuPlayerDriver::getParameter(int key, Parcel *reply) {
+ return INVALID_OPERATION;
+}
+
status_t NuPlayerDriver::getMetadata(
const media::Metadata::Filter& ids, Parcel *records) {
return INVALID_OPERATION;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
index 67d0f3e..1bb7ca2 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
@@ -28,6 +28,8 @@
virtual status_t initCheck();
+ virtual status_t setUID(uid_t uid);
+
virtual status_t setDataSource(
const char *url, const KeyedVector<String8, String8> *headers);
@@ -52,6 +54,8 @@
virtual player_type playerType();
virtual status_t invoke(const Parcel &request, Parcel *reply);
virtual void setAudioSink(const sp<AudioSink> &audioSink);
+ virtual status_t setParameter(int key, const Parcel &request);
+ virtual status_t getParameter(int key, Parcel *reply);
virtual status_t getMetadata(
const media::Metadata::Filter& ids, Parcel *records);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 369a3a8..828e008 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -198,18 +198,21 @@
}
void NuPlayer::Renderer::onDrainAudioQueue() {
- uint32_t numFramesPlayed;
- CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), (status_t)OK);
- ssize_t numFramesAvailableToWrite =
- mAudioSink->frameCount() - (mNumFramesWritten - numFramesPlayed);
+ for (;;) {
+ uint32_t numFramesPlayed;
+ CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), (status_t)OK);
- CHECK_GE(numFramesAvailableToWrite, 0);
+ ssize_t numFramesAvailableToWrite =
+ mAudioSink->frameCount() - (mNumFramesWritten - numFramesPlayed);
- size_t numBytesAvailableToWrite =
- numFramesAvailableToWrite * mAudioSink->frameSize();
+ size_t numBytesAvailableToWrite =
+ numFramesAvailableToWrite * mAudioSink->frameSize();
- while (numBytesAvailableToWrite > 0) {
+ if (numBytesAvailableToWrite == 0) {
+ break;
+ }
+
if (mAudioQueue.empty()) {
break;
}
@@ -264,10 +267,10 @@
if (entry->mOffset == entry->mBuffer->size()) {
entry->mNotifyConsumed->post();
mAudioQueue.erase(mAudioQueue.begin());
+
entry = NULL;
}
- numBytesAvailableToWrite -= copy;
mNumFramesWritten += copy / mAudioSink->frameSize();
}
diff --git a/media/libmediaplayerservice/nuplayer/StreamingSource.cpp b/media/libmediaplayerservice/nuplayer/StreamingSource.cpp
index 2016282..a6a3a18 100644
--- a/media/libmediaplayerservice/nuplayer/StreamingSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/StreamingSource.cpp
@@ -63,8 +63,17 @@
mEOS = true;
break;
} else if (n == INFO_DISCONTINUITY) {
- mTSParser->signalDiscontinuity(
- ATSParser::DISCONTINUITY_SEEK, extra);
+ ATSParser::DiscontinuityType type = ATSParser::DISCONTINUITY_SEEK;
+
+ int32_t formatChange;
+ if (extra != NULL
+ && extra->findInt32(
+ IStreamListener::kKeyFormatChange, &formatChange)
+ && formatChange != 0) {
+ type = ATSParser::DISCONTINUITY_FORMATCHANGE;
+ }
+
+ mTSParser->signalDiscontinuity(type, extra);
} else if (n < 0) {
CHECK_EQ(n, -EWOULDBLOCK);
break;
@@ -87,7 +96,7 @@
sp<MetaData> NuPlayer::StreamingSource::getFormat(bool audio) {
ATSParser::SourceType type =
- audio ? ATSParser::MPEG2ADTS_AUDIO : ATSParser::AVC_VIDEO;
+ audio ? ATSParser::AUDIO : ATSParser::VIDEO;
sp<AnotherPacketSource> source =
static_cast<AnotherPacketSource *>(mTSParser->getSource(type).get());
@@ -102,7 +111,7 @@
status_t NuPlayer::StreamingSource::dequeueAccessUnit(
bool audio, sp<ABuffer> *accessUnit) {
ATSParser::SourceType type =
- audio ? ATSParser::MPEG2ADTS_AUDIO : ATSParser::AVC_VIDEO;
+ audio ? ATSParser::AUDIO : ATSParser::VIDEO;
sp<AnotherPacketSource> source =
static_cast<AnotherPacketSource *>(mTSParser->getSource(type).get());
diff --git a/media/libstagefright/AACExtractor.cpp b/media/libstagefright/AACExtractor.cpp
index 4203b6e..a5a6b64 100644
--- a/media/libstagefright/AACExtractor.cpp
+++ b/media/libstagefright/AACExtractor.cpp
@@ -92,7 +92,7 @@
size_t frameSize = 0;
uint8_t syncword[2];
- if (source->readAt(0, &syncword, 2) != 2) {
+ if (source->readAt(offset, &syncword, 2) != 2) {
return 0;
}
if ((syncword[0] != 0xff) || ((syncword[1] & 0xf6) != 0xf0)) {
diff --git a/media/libstagefright/AACWriter.cpp b/media/libstagefright/AACWriter.cpp
new file mode 100644
index 0000000..d133e91
--- /dev/null
+++ b/media/libstagefright/AACWriter.cpp
@@ -0,0 +1,381 @@
+/*
+ * Copyright (C) 2011 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 "AACWriter"
+#include <utils/Log.h>
+
+#include <media/stagefright/AACWriter.h>
+#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/MediaSource.h>
+#include <media/stagefright/MetaData.h>
+#include <media/mediarecorder.h>
+#include <sys/prctl.h>
+#include <fcntl.h>
+
+namespace android {
+
+AACWriter::AACWriter(const char *filename)
+ : mFd(-1),
+ mInitCheck(NO_INIT),
+ mStarted(false),
+ mPaused(false),
+ mResumed(false),
+ mChannelCount(-1),
+ mSampleRate(-1) {
+
+ LOGV("AACWriter Constructor");
+
+ mFd = open(filename, O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR);
+ if (mFd >= 0) {
+ mInitCheck = OK;
+ }
+}
+
+AACWriter::AACWriter(int fd)
+ : mFd(dup(fd)),
+ mInitCheck(mFd < 0? NO_INIT: OK),
+ mStarted(false),
+ mPaused(false),
+ mResumed(false),
+ mChannelCount(-1),
+ mSampleRate(-1) {
+}
+
+AACWriter::~AACWriter() {
+ if (mStarted) {
+ stop();
+ }
+
+ if (mFd != -1) {
+ close(mFd);
+ mFd = -1;
+ }
+}
+
+status_t AACWriter::initCheck() const {
+ return mInitCheck;
+}
+
+static int writeInt8(int fd, uint8_t x) {
+ return ::write(fd, &x, 1);
+}
+
+
+status_t AACWriter::addSource(const sp<MediaSource> &source) {
+ if (mInitCheck != OK) {
+ return mInitCheck;
+ }
+
+ if (mSource != NULL) {
+ LOGE("AAC files only support a single track of audio.");
+ return UNKNOWN_ERROR;
+ }
+
+ sp<MetaData> meta = source->getFormat();
+
+ const char *mime;
+ CHECK(meta->findCString(kKeyMIMEType, &mime));
+
+ CHECK(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC));
+ CHECK(meta->findInt32(kKeyChannelCount, &mChannelCount));
+ CHECK(meta->findInt32(kKeySampleRate, &mSampleRate));
+ CHECK(mChannelCount >= 1 && mChannelCount <= 2);
+
+ mSource = source;
+ return OK;
+}
+
+status_t AACWriter::start(MetaData *params) {
+ if (mInitCheck != OK) {
+ return mInitCheck;
+ }
+
+ if (mSource == NULL) {
+ return UNKNOWN_ERROR;
+ }
+
+ if (mStarted && mPaused) {
+ mPaused = false;
+ mResumed = true;
+ return OK;
+ } else if (mStarted) {
+ // Already started, does nothing
+ return OK;
+ }
+
+ mFrameDurationUs = (kSamplesPerFrame * 1000000LL + (mSampleRate >> 1))
+ / mSampleRate;
+
+ status_t err = mSource->start();
+
+ if (err != OK) {
+ return err;
+ }
+
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+
+ mReachedEOS = false;
+ mDone = false;
+
+ pthread_create(&mThread, &attr, ThreadWrapper, this);
+ pthread_attr_destroy(&attr);
+
+ mStarted = true;
+
+ return OK;
+}
+
+status_t AACWriter::pause() {
+ if (!mStarted) {
+ return OK;
+ }
+ mPaused = true;
+ return OK;
+}
+
+status_t AACWriter::stop() {
+ if (!mStarted) {
+ return OK;
+ }
+
+ mDone = true;
+
+ void *dummy;
+ pthread_join(mThread, &dummy);
+
+ status_t err = (status_t) dummy;
+ {
+ status_t status = mSource->stop();
+ if (err == OK &&
+ (status != OK && status != ERROR_END_OF_STREAM)) {
+ err = status;
+ }
+ }
+
+ mStarted = false;
+ return err;
+}
+
+bool AACWriter::exceedsFileSizeLimit() {
+ if (mMaxFileSizeLimitBytes == 0) {
+ return false;
+ }
+ return mEstimatedSizeBytes >= mMaxFileSizeLimitBytes;
+}
+
+bool AACWriter::exceedsFileDurationLimit() {
+ if (mMaxFileDurationLimitUs == 0) {
+ return false;
+ }
+ return mEstimatedDurationUs >= mMaxFileDurationLimitUs;
+}
+
+// static
+void *AACWriter::ThreadWrapper(void *me) {
+ return (void *) static_cast<AACWriter *>(me)->threadFunc();
+}
+
+/*
+* Returns an index into the sample rate table if the
+* given sample rate is found; otherwise, returns -1.
+*/
+static bool getSampleRateTableIndex(int sampleRate, uint8_t* tableIndex) {
+ static const int kSampleRateTable[] = {
+ 96000, 88200, 64000, 48000, 44100, 32000,
+ 24000, 22050, 16000, 12000, 11025, 8000
+ };
+ const int tableSize =
+ sizeof(kSampleRateTable) / sizeof(kSampleRateTable[0]);
+
+ *tableIndex = 0;
+ for (int index = 0; index < tableSize; ++index) {
+ if (sampleRate == kSampleRateTable[index]) {
+ LOGV("Sample rate: %d and index: %d",
+ sampleRate, index);
+ *tableIndex = index;
+ return true;
+ }
+ }
+
+ LOGE("Sampling rate %d bps is not supported", sampleRate);
+ return false;
+}
+
+/*
+ * ADTS (Audio data transport stream) header structure.
+ * It consists of 7 or 9 bytes (with or without CRC):
+ * 12 bits of syncword 0xFFF, all bits must be 1
+ * 1 bit of field ID. 0 for MPEG-4, and 1 for MPEG-2
+ * 2 bits of MPEG layer. If in MPEG-TS, set to 0
+ * 1 bit of protection absense. Set to 1 if no CRC.
+ * 2 bits of profile code. Set to 1 (The MPEG-4 Audio
+ * object type minus 1. We are using AAC-LC = 2)
+ * 4 bits of sampling frequency index code (15 is not allowed)
+ * 1 bit of private stream. Set to 0.
+ * 3 bits of channel configuration code. 0 resevered for inband PCM
+ * 1 bit of originality. Set to 0.
+ * 1 bit of home. Set to 0.
+ * 1 bit of copyrighted steam. Set to 0.
+ * 1 bit of copyright start. Set to 0.
+ * 13 bits of frame length. It included 7 ot 9 bytes header length.
+ * it is set to (protection absense? 7: 9) + size(AAC frame)
+ * 11 bits of buffer fullness. 0x7FF for VBR.
+ * 2 bits of frames count in one packet. Set to 0.
+ */
+status_t AACWriter::writeAdtsHeader(uint32_t frameLength) {
+ uint8_t data = 0xFF;
+ write(mFd, &data, 1);
+
+ const uint8_t kFieldId = 0;
+ const uint8_t kMpegLayer = 0;
+ const uint8_t kProtectionAbsense = 1; // 1: kAdtsHeaderLength = 7
+ data = 0xF0;
+ data |= (kFieldId << 3);
+ data |= (kMpegLayer << 1);
+ data |= kProtectionAbsense;
+ write(mFd, &data, 1);
+
+ const uint8_t kProfileCode = 1; // AAC-LC
+ uint8_t kSampleFreqIndex;
+ CHECK(getSampleRateTableIndex(mSampleRate, &kSampleFreqIndex));
+ const uint8_t kPrivateStream = 0;
+ const uint8_t kChannelConfigCode = mChannelCount;
+ data = (kProfileCode << 6);
+ data |= (kSampleFreqIndex << 2);
+ data |= (kPrivateStream << 1);
+ data |= (kChannelConfigCode >> 2);
+ write(mFd, &data, 1);
+
+ // 4 bits from originality to copyright start
+ const uint8_t kCopyright = 0;
+ const uint32_t kFrameLength = frameLength;
+ data = ((kChannelConfigCode & 3) << 6);
+ data |= (kCopyright << 2);
+ data |= ((kFrameLength & 0x1800) >> 11);
+ write(mFd, &data, 1);
+
+ data = ((kFrameLength & 0x07F8) >> 3);
+ write(mFd, &data, 1);
+
+ const uint32_t kBufferFullness = 0x7FF; // VBR
+ data = ((kFrameLength & 0x07) << 5);
+ data |= ((kBufferFullness & 0x07C0) >> 6);
+ write(mFd, &data, 1);
+
+ const uint8_t kFrameCount = 0;
+ data = ((kBufferFullness & 0x03F) << 2);
+ data |= kFrameCount;
+ write(mFd, &data, 1);
+
+ return OK;
+}
+
+status_t AACWriter::threadFunc() {
+ mEstimatedDurationUs = 0;
+ mEstimatedSizeBytes = 0;
+ int64_t previousPausedDurationUs = 0;
+ int64_t maxTimestampUs = 0;
+ status_t err = OK;
+
+ prctl(PR_SET_NAME, (unsigned long)"AACWriterThread", 0, 0, 0);
+
+ while (!mDone && err == OK) {
+ MediaBuffer *buffer;
+ err = mSource->read(&buffer);
+
+ if (err != OK) {
+ break;
+ }
+
+ if (mPaused) {
+ buffer->release();
+ buffer = NULL;
+ continue;
+ }
+
+ mEstimatedSizeBytes += kAdtsHeaderLength + buffer->range_length();
+ if (exceedsFileSizeLimit()) {
+ buffer->release();
+ buffer = NULL;
+ notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED, 0);
+ break;
+ }
+
+ int32_t isCodecSpecific = 0;
+ if (buffer->meta_data()->findInt32(kKeyIsCodecConfig, &isCodecSpecific) && isCodecSpecific) {
+ LOGV("Drop codec specific info buffer");
+ buffer->release();
+ buffer = NULL;
+ continue;
+ }
+
+ int64_t timestampUs;
+ CHECK(buffer->meta_data()->findInt64(kKeyTime, ×tampUs));
+ if (timestampUs > mEstimatedDurationUs) {
+ mEstimatedDurationUs = timestampUs;
+ }
+ if (mResumed) {
+ previousPausedDurationUs += (timestampUs - maxTimestampUs - mFrameDurationUs);
+ mResumed = false;
+ }
+ timestampUs -= previousPausedDurationUs;
+ LOGV("time stamp: %lld, previous paused duration: %lld",
+ timestampUs, previousPausedDurationUs);
+ if (timestampUs > maxTimestampUs) {
+ maxTimestampUs = timestampUs;
+ }
+
+ if (exceedsFileDurationLimit()) {
+ buffer->release();
+ buffer = NULL;
+ notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_DURATION_REACHED, 0);
+ break;
+ }
+
+ // Each output AAC audio frame to the file contains
+ // 1. an ADTS header, followed by
+ // 2. the compressed audio data.
+ ssize_t dataLength = buffer->range_length();
+ uint8_t *data = (uint8_t *)buffer->data() + buffer->range_offset();
+ if (writeAdtsHeader(kAdtsHeaderLength + dataLength) != OK ||
+ dataLength != write(mFd, data, dataLength)) {
+ err = ERROR_IO;
+ }
+
+ buffer->release();
+ buffer = NULL;
+ }
+
+ close(mFd);
+ mFd = -1;
+ mReachedEOS = true;
+ if (err == ERROR_END_OF_STREAM) {
+ return OK;
+ }
+ return err;
+}
+
+bool AACWriter::reachedEOS() {
+ return mReachedEOS;
+}
+
+} // namespace android
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 9928f44..174ec92 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -29,6 +29,7 @@
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/NativeWindowWrapper.h>
#include <media/stagefright/OMXClient.h>
+#include <media/stagefright/OMXCodec.h>
#include <surfaceflinger/Surface.h>
#include <gui/SurfaceTextureClient.h>
@@ -401,11 +402,22 @@
CHECK(mem.get() != NULL);
IOMX::buffer_id buffer;
-#if 0
- err = mOMX->allocateBufferWithBackup(mNode, portIndex, mem, &buffer);
-#else
- err = mOMX->useBuffer(mNode, portIndex, mem, &buffer);
-#endif
+
+ if (!strcasecmp(
+ mComponentName.c_str(), "OMX.TI.DUCATI1.VIDEO.DECODER")) {
+ if (portIndex == kPortIndexInput && i == 0) {
+ // Only log this warning once per allocation round.
+
+ LOGW("OMX.TI.DUCATI1.VIDEO.DECODER requires the use of "
+ "OMX_AllocateBuffer instead of the preferred "
+ "OMX_UseBuffer. Vendor must fix this.");
+ }
+
+ err = mOMX->allocateBufferWithBackup(
+ mNode, portIndex, mem, &buffer);
+ } else {
+ err = mOMX->useBuffer(mNode, portIndex, mem, &buffer);
+ }
if (err != OK) {
return err;
@@ -433,6 +445,13 @@
return err;
}
+ err = native_window_set_scaling_mode(mNativeWindow.get(),
+ NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
+
+ if (err != OK) {
+ return err;
+ }
+
err = native_window_set_buffers_geometry(
mNativeWindow.get(),
def.format.video.nFrameWidth,
@@ -505,7 +524,7 @@
// Dequeue buffers and send them to OMX
for (OMX_U32 i = 0; i < def.nBufferCountActual; i++) {
- android_native_buffer_t *buf;
+ ANativeWindowBuffer *buf;
err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf);
if (err != 0) {
LOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
@@ -574,7 +593,7 @@
}
ACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
- android_native_buffer_t *buf;
+ ANativeWindowBuffer *buf;
CHECK_EQ(mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf), 0);
for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
@@ -888,11 +907,10 @@
CHECK_EQ(err, (status_t)OK);
CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
- static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00;
-
CHECK(format.eColorFormat == OMX_COLOR_FormatYUV420Planar
|| format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
|| format.eColorFormat == OMX_COLOR_FormatCbYCrY
+ || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar
|| format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar);
return mOMX->setParameter(
@@ -909,6 +927,8 @@
compressionFormat = OMX_VIDEO_CodingMPEG4;
} else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
compressionFormat = OMX_VIDEO_CodingH263;
+ } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG2, mime)) {
+ compressionFormat = OMX_VIDEO_CodingMPEG2;
} else {
TRESPASS();
}
@@ -1177,6 +1197,17 @@
CHECK(msg->findInt32("data1", &data1));
CHECK(msg->findInt32("data2", &data2));
+ if (event == OMX_EventCmdComplete
+ && data1 == OMX_CommandFlush
+ && data2 == (int32_t)OMX_ALL) {
+ // Use of this notification is not consistent across
+ // implementations. We'll drop this notification and rely
+ // on flush-complete notifications on the individual port
+ // indices instead.
+
+ return true;
+ }
+
return onOMXEvent(
static_cast<OMX_EVENTTYPE>(event),
static_cast<OMX_U32>(data1),
@@ -1639,23 +1670,33 @@
AString mime;
CHECK(msg->findString("mime", &mime));
- AString componentName;
-
- if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) {
- componentName = "OMX.Nvidia.h264.decode";
- } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) {
- componentName = "OMX.Nvidia.aac.decoder";
- } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_MPEG)) {
- componentName = "OMX.Nvidia.mp3.decoder";
- } else {
- TRESPASS();
- }
+ Vector<String8> matchingCodecs;
+ OMXCodec::findMatchingCodecs(
+ mime.c_str(),
+ false, // createEncoder
+ NULL, // matchComponentName
+ 0, // flags
+ &matchingCodecs);
sp<CodecObserver> observer = new CodecObserver;
+ IOMX::node_id node = NULL;
- IOMX::node_id node;
- CHECK_EQ(omx->allocateNode(componentName.c_str(), observer, &node),
- (status_t)OK);
+ AString componentName;
+
+ for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
+ ++matchIndex) {
+ componentName = matchingCodecs.itemAt(matchIndex).string();
+
+ status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
+
+ if (err == OK) {
+ break;
+ }
+
+ node = NULL;
+ }
+
+ CHECK(node != NULL);
sp<AMessage> notify = new AMessage(kWhatOMXMessage, mCodec->id());
observer->setNotificationMessage(notify);
@@ -1670,7 +1711,8 @@
mCodec->configureCodec(mime.c_str(), msg);
sp<RefBase> obj;
- if (msg->findObject("native-window", &obj)) {
+ if (msg->findObject("native-window", &obj)
+ && strncmp("OMX.google.", componentName.c_str(), 11)) {
sp<NativeWindowWrapper> nativeWindow(
static_cast<NativeWindowWrapper *>(obj.get()));
CHECK(nativeWindow != NULL);
@@ -2095,6 +2137,7 @@
return BaseState::onOMXEvent(event, data1, data2);
}
}
+
void ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
if (mCodec->allYourBuffersAreBelongToUs()) {
CHECK_EQ(mCodec->mOMX->sendCommand(
@@ -2258,6 +2301,11 @@
if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
CHECK(!mFlushComplete[data2]);
mFlushComplete[data2] = true;
+
+ if (mFlushComplete[kPortIndexInput]
+ && mFlushComplete[kPortIndexOutput]) {
+ changeStateIfWeOwnAllBuffers();
+ }
} else {
CHECK_EQ(data2, OMX_ALL);
CHECK(mFlushComplete[kPortIndexInput]);
diff --git a/media/libstagefright/AMRWriter.cpp b/media/libstagefright/AMRWriter.cpp
index 0db3d1d..6436071 100644
--- a/media/libstagefright/AMRWriter.cpp
+++ b/media/libstagefright/AMRWriter.cpp
@@ -23,7 +23,6 @@
#include <media/stagefright/MetaData.h>
#include <media/mediarecorder.h>
#include <sys/prctl.h>
-#include <sys/resource.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -37,7 +36,7 @@
mPaused(false),
mResumed(false) {
- mFd = open(filename, O_CREAT | O_LARGEFILE | O_TRUNC);
+ mFd = open(filename, O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR);
if (mFd >= 0) {
mInitCheck = OK;
}
@@ -269,7 +268,7 @@
}
if (stoppedPrematurely) {
- notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_COMPLETION_STATUS, UNKNOWN_ERROR);
+ notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_TRACK_INFO_COMPLETION_STATUS, UNKNOWN_ERROR);
}
close(mFd);
diff --git a/media/libstagefright/AVIExtractor.cpp b/media/libstagefright/AVIExtractor.cpp
new file mode 100644
index 0000000..6313ca3
--- /dev/null
+++ b/media/libstagefright/AVIExtractor.cpp
@@ -0,0 +1,922 @@
+/*
+ * Copyright (C) 2011 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 "AVIExtractor"
+#include <utils/Log.h>
+
+#include "include/AVIExtractor.h"
+
+#include <binder/ProcessState.h>
+#include <media/stagefright/foundation/hexdump.h>
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/DataSource.h>
+#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/MediaBufferGroup.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/Utils.h>
+
+namespace android {
+
+struct AVIExtractor::AVISource : public MediaSource {
+ AVISource(const sp<AVIExtractor> &extractor, size_t trackIndex);
+
+ virtual status_t start(MetaData *params);
+ virtual status_t stop();
+
+ virtual sp<MetaData> getFormat();
+
+ virtual status_t read(
+ MediaBuffer **buffer, const ReadOptions *options);
+
+protected:
+ virtual ~AVISource();
+
+private:
+ sp<AVIExtractor> mExtractor;
+ size_t mTrackIndex;
+ const AVIExtractor::Track &mTrack;
+ MediaBufferGroup *mBufferGroup;
+ size_t mSampleIndex;
+
+ DISALLOW_EVIL_CONSTRUCTORS(AVISource);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+AVIExtractor::AVISource::AVISource(
+ const sp<AVIExtractor> &extractor, size_t trackIndex)
+ : mExtractor(extractor),
+ mTrackIndex(trackIndex),
+ mTrack(mExtractor->mTracks.itemAt(trackIndex)),
+ mBufferGroup(NULL) {
+}
+
+AVIExtractor::AVISource::~AVISource() {
+ if (mBufferGroup) {
+ stop();
+ }
+}
+
+status_t AVIExtractor::AVISource::start(MetaData *params) {
+ CHECK(!mBufferGroup);
+
+ mBufferGroup = new MediaBufferGroup;
+
+ mBufferGroup->add_buffer(new MediaBuffer(mTrack.mMaxSampleSize));
+ mBufferGroup->add_buffer(new MediaBuffer(mTrack.mMaxSampleSize));
+ mSampleIndex = 0;
+
+ return OK;
+}
+
+status_t AVIExtractor::AVISource::stop() {
+ CHECK(mBufferGroup);
+
+ delete mBufferGroup;
+ mBufferGroup = NULL;
+
+ return OK;
+}
+
+sp<MetaData> AVIExtractor::AVISource::getFormat() {
+ return mTrack.mMeta;
+}
+
+status_t AVIExtractor::AVISource::read(
+ MediaBuffer **buffer, const ReadOptions *options) {
+ CHECK(mBufferGroup);
+
+ *buffer = NULL;
+
+ int64_t seekTimeUs;
+ ReadOptions::SeekMode seekMode;
+ if (options && options->getSeekTo(&seekTimeUs, &seekMode)) {
+ status_t err =
+ mExtractor->getSampleIndexAtTime(
+ mTrackIndex, seekTimeUs, seekMode, &mSampleIndex);
+
+ if (err != OK) {
+ return ERROR_END_OF_STREAM;
+ }
+ }
+
+ int64_t timeUs =
+ (mSampleIndex * 1000000ll * mTrack.mRate) / mTrack.mScale;
+
+ off64_t offset;
+ size_t size;
+ bool isKey;
+ status_t err = mExtractor->getSampleInfo(
+ mTrackIndex, mSampleIndex, &offset, &size, &isKey);
+
+ ++mSampleIndex;
+
+ if (err != OK) {
+ return ERROR_END_OF_STREAM;
+ }
+
+ MediaBuffer *out;
+ CHECK_EQ(mBufferGroup->acquire_buffer(&out), (status_t)OK);
+
+ ssize_t n = mExtractor->mDataSource->readAt(offset, out->data(), size);
+
+ if (n < (ssize_t)size) {
+ return n < 0 ? (status_t)n : (status_t)ERROR_MALFORMED;
+ }
+
+ out->set_range(0, size);
+
+ out->meta_data()->setInt64(kKeyTime, timeUs);
+
+ if (isKey) {
+ out->meta_data()->setInt32(kKeyIsSyncFrame, 1);
+ }
+
+ *buffer = out;
+
+ return OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+AVIExtractor::AVIExtractor(const sp<DataSource> &dataSource)
+ : mDataSource(dataSource) {
+ mInitCheck = parseHeaders();
+
+ if (mInitCheck != OK) {
+ mTracks.clear();
+ }
+}
+
+AVIExtractor::~AVIExtractor() {
+}
+
+size_t AVIExtractor::countTracks() {
+ return mTracks.size();
+}
+
+sp<MediaSource> AVIExtractor::getTrack(size_t index) {
+ return index < mTracks.size() ? new AVISource(this, index) : NULL;
+}
+
+sp<MetaData> AVIExtractor::getTrackMetaData(
+ size_t index, uint32_t flags) {
+ return index < mTracks.size() ? mTracks.editItemAt(index).mMeta : NULL;
+}
+
+sp<MetaData> AVIExtractor::getMetaData() {
+ sp<MetaData> meta = new MetaData;
+
+ if (mInitCheck == OK) {
+ meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_AVI);
+ }
+
+ return meta;
+}
+
+status_t AVIExtractor::parseHeaders() {
+ mTracks.clear();
+ mMovieOffset = 0;
+ mFoundIndex = false;
+ mOffsetsAreAbsolute = false;
+
+ ssize_t res = parseChunk(0ll, -1ll);
+
+ if (res < 0) {
+ return (status_t)res;
+ }
+
+ if (mMovieOffset == 0ll || !mFoundIndex) {
+ return ERROR_MALFORMED;
+ }
+
+ return OK;
+}
+
+ssize_t AVIExtractor::parseChunk(off64_t offset, off64_t size, int depth) {
+ if (size >= 0 && size < 8) {
+ return ERROR_MALFORMED;
+ }
+
+ uint8_t tmp[12];
+ ssize_t n = mDataSource->readAt(offset, tmp, 8);
+
+ if (n < 8) {
+ return (n < 0) ? n : (ssize_t)ERROR_MALFORMED;
+ }
+
+ uint32_t fourcc = U32_AT(tmp);
+ uint32_t chunkSize = U32LE_AT(&tmp[4]);
+
+ if (size >= 0 && chunkSize + 8 > size) {
+ return ERROR_MALFORMED;
+ }
+
+ static const char kPrefix[] = " ";
+ const char *prefix = &kPrefix[strlen(kPrefix) - 2 * depth];
+
+ if (fourcc == FOURCC('L', 'I', 'S', 'T')
+ || fourcc == FOURCC('R', 'I', 'F', 'F')) {
+ // It's a list of chunks
+
+ if (size >= 0 && size < 12) {
+ return ERROR_MALFORMED;
+ }
+
+ n = mDataSource->readAt(offset + 8, &tmp[8], 4);
+
+ if (n < 4) {
+ return (n < 0) ? n : (ssize_t)ERROR_MALFORMED;
+ }
+
+ uint32_t subFourcc = U32_AT(&tmp[8]);
+
+ LOGV("%s offset 0x%08llx LIST of '%c%c%c%c', size %d",
+ prefix,
+ offset,
+ (char)(subFourcc >> 24),
+ (char)((subFourcc >> 16) & 0xff),
+ (char)((subFourcc >> 8) & 0xff),
+ (char)(subFourcc & 0xff),
+ chunkSize - 4);
+
+ if (subFourcc == FOURCC('m', 'o', 'v', 'i')) {
+ // We're not going to parse this, but will take note of the
+ // offset.
+
+ mMovieOffset = offset;
+ } else {
+ off64_t subOffset = offset + 12;
+ off64_t subOffsetLimit = subOffset + chunkSize - 4;
+ while (subOffset < subOffsetLimit) {
+ ssize_t res =
+ parseChunk(subOffset, subOffsetLimit - subOffset, depth + 1);
+
+ if (res < 0) {
+ return res;
+ }
+
+ subOffset += res;
+ }
+ }
+ } else {
+ LOGV("%s offset 0x%08llx CHUNK '%c%c%c%c'",
+ prefix,
+ offset,
+ (char)(fourcc >> 24),
+ (char)((fourcc >> 16) & 0xff),
+ (char)((fourcc >> 8) & 0xff),
+ (char)(fourcc & 0xff));
+
+ status_t err = OK;
+
+ switch (fourcc) {
+ case FOURCC('s', 't', 'r', 'h'):
+ {
+ err = parseStreamHeader(offset + 8, chunkSize);
+ break;
+ }
+
+ case FOURCC('s', 't', 'r', 'f'):
+ {
+ err = parseStreamFormat(offset + 8, chunkSize);
+ break;
+ }
+
+ case FOURCC('i', 'd', 'x', '1'):
+ {
+ err = parseIndex(offset + 8, chunkSize);
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ if (err != OK) {
+ return err;
+ }
+ }
+
+ if (chunkSize & 1) {
+ ++chunkSize;
+ }
+
+ return chunkSize + 8;
+}
+
+static const char *GetMIMETypeForHandler(uint32_t handler) {
+ switch (handler) {
+ // Wow... shamelessly copied from
+ // http://wiki.multimedia.cx/index.php?title=ISO_MPEG-4
+
+ case FOURCC('3', 'I', 'V', '2'):
+ case FOURCC('3', 'i', 'v', '2'):
+ case FOURCC('B', 'L', 'Z', '0'):
+ case FOURCC('D', 'I', 'G', 'I'):
+ case FOURCC('D', 'I', 'V', '1'):
+ case FOURCC('d', 'i', 'v', '1'):
+ case FOURCC('D', 'I', 'V', 'X'):
+ case FOURCC('d', 'i', 'v', 'x'):
+ case FOURCC('D', 'X', '5', '0'):
+ case FOURCC('d', 'x', '5', '0'):
+ case FOURCC('D', 'X', 'G', 'M'):
+ case FOURCC('E', 'M', '4', 'A'):
+ case FOURCC('E', 'P', 'H', 'V'):
+ case FOURCC('F', 'M', 'P', '4'):
+ case FOURCC('f', 'm', 'p', '4'):
+ case FOURCC('F', 'V', 'F', 'W'):
+ case FOURCC('H', 'D', 'X', '4'):
+ case FOURCC('h', 'd', 'x', '4'):
+ case FOURCC('M', '4', 'C', 'C'):
+ case FOURCC('M', '4', 'S', '2'):
+ case FOURCC('m', '4', 's', '2'):
+ case FOURCC('M', 'P', '4', 'S'):
+ case FOURCC('m', 'p', '4', 's'):
+ case FOURCC('M', 'P', '4', 'V'):
+ case FOURCC('m', 'p', '4', 'v'):
+ case FOURCC('M', 'V', 'X', 'M'):
+ case FOURCC('R', 'M', 'P', '4'):
+ case FOURCC('S', 'E', 'D', 'G'):
+ case FOURCC('S', 'M', 'P', '4'):
+ case FOURCC('U', 'M', 'P', '4'):
+ case FOURCC('W', 'V', '1', 'F'):
+ case FOURCC('X', 'V', 'I', 'D'):
+ case FOURCC('X', 'v', 'i', 'D'):
+ case FOURCC('x', 'v', 'i', 'd'):
+ case FOURCC('X', 'V', 'I', 'X'):
+ return MEDIA_MIMETYPE_VIDEO_MPEG4;
+
+ default:
+ return NULL;
+ }
+}
+
+status_t AVIExtractor::parseStreamHeader(off64_t offset, size_t size) {
+ if (size != 56) {
+ return ERROR_MALFORMED;
+ }
+
+ if (mTracks.size() > 99) {
+ return -ERANGE;
+ }
+
+ sp<ABuffer> buffer = new ABuffer(size);
+ ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size());
+
+ if (n < (ssize_t)size) {
+ return n < 0 ? (status_t)n : ERROR_MALFORMED;
+ }
+
+ const uint8_t *data = buffer->data();
+
+ uint32_t type = U32_AT(data);
+ uint32_t handler = U32_AT(&data[4]);
+ uint32_t flags = U32LE_AT(&data[8]);
+
+ sp<MetaData> meta = new MetaData;
+
+ uint32_t rate = U32LE_AT(&data[20]);
+ uint32_t scale = U32LE_AT(&data[24]);
+
+ const char *mime = NULL;
+ Track::Kind kind = Track::OTHER;
+
+ if (type == FOURCC('v', 'i', 'd', 's')) {
+ mime = GetMIMETypeForHandler(handler);
+
+ if (mime && strncasecmp(mime, "video/", 6)) {
+ return ERROR_MALFORMED;
+ }
+
+ kind = Track::VIDEO;
+ } else if (type == FOURCC('a', 'u', 'd', 's')) {
+ if (mime && strncasecmp(mime, "audio/", 6)) {
+ return ERROR_MALFORMED;
+ }
+
+ kind = Track::AUDIO;
+ }
+
+ if (!mime) {
+ mime = "application/octet-stream";
+ }
+
+ meta->setCString(kKeyMIMEType, mime);
+
+ mTracks.push();
+ Track *track = &mTracks.editItemAt(mTracks.size() - 1);
+
+ track->mMeta = meta;
+ track->mRate = rate;
+ track->mScale = scale;
+ track->mKind = kind;
+ track->mNumSyncSamples = 0;
+ track->mThumbnailSampleSize = 0;
+ track->mThumbnailSampleIndex = -1;
+ track->mMaxSampleSize = 0;
+
+ return OK;
+}
+
+status_t AVIExtractor::parseStreamFormat(off64_t offset, size_t size) {
+ if (mTracks.isEmpty()) {
+ return ERROR_MALFORMED;
+ }
+
+ Track *track = &mTracks.editItemAt(mTracks.size() - 1);
+
+ if (track->mKind == Track::OTHER) {
+ // We don't support this content, but that's not a parsing error.
+ return OK;
+ }
+
+ bool isVideo = (track->mKind == Track::VIDEO);
+
+ if ((isVideo && size < 40) || (!isVideo && size < 18)) {
+ // Expected a BITMAPINFO or WAVEFORMATEX structure, respectively.
+ return ERROR_MALFORMED;
+ }
+
+ sp<ABuffer> buffer = new ABuffer(size);
+ ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size());
+
+ if (n < (ssize_t)size) {
+ return n < 0 ? (status_t)n : ERROR_MALFORMED;
+ }
+
+ const uint8_t *data = buffer->data();
+
+ if (isVideo) {
+ uint32_t width = U32LE_AT(&data[4]);
+ uint32_t height = U32LE_AT(&data[8]);
+
+ track->mMeta->setInt32(kKeyWidth, width);
+ track->mMeta->setInt32(kKeyHeight, height);
+ } else {
+ uint32_t format = U16LE_AT(data);
+ if (format == 0x55) {
+ track->mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
+ }
+
+ uint32_t numChannels = U16LE_AT(&data[2]);
+ uint32_t sampleRate = U32LE_AT(&data[4]);
+
+ track->mMeta->setInt32(kKeyChannelCount, numChannels);
+ track->mMeta->setInt32(kKeySampleRate, sampleRate);
+ }
+
+ return OK;
+}
+
+// static
+bool AVIExtractor::IsCorrectChunkType(
+ ssize_t trackIndex, Track::Kind kind, uint32_t chunkType) {
+ uint32_t chunkBase = chunkType & 0xffff;
+
+ switch (kind) {
+ case Track::VIDEO:
+ {
+ if (chunkBase != FOURCC(0, 0, 'd', 'c')
+ && chunkBase != FOURCC(0, 0, 'd', 'b')) {
+ return false;
+ }
+ break;
+ }
+
+ case Track::AUDIO:
+ {
+ if (chunkBase != FOURCC(0, 0, 'w', 'b')) {
+ return false;
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ if (trackIndex < 0) {
+ return true;
+ }
+
+ uint8_t hi = chunkType >> 24;
+ uint8_t lo = (chunkType >> 16) & 0xff;
+
+ if (hi < '0' || hi > '9' || lo < '0' || lo > '9') {
+ return false;
+ }
+
+ if (trackIndex != (10 * (hi - '0') + (lo - '0'))) {
+ return false;
+ }
+
+ return true;
+}
+
+status_t AVIExtractor::parseIndex(off64_t offset, size_t size) {
+ if ((size % 16) != 0) {
+ return ERROR_MALFORMED;
+ }
+
+ sp<ABuffer> buffer = new ABuffer(size);
+ ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size());
+
+ if (n < (ssize_t)size) {
+ return n < 0 ? (status_t)n : ERROR_MALFORMED;
+ }
+
+ const uint8_t *data = buffer->data();
+
+ while (size > 0) {
+ uint32_t chunkType = U32_AT(data);
+
+ uint8_t hi = chunkType >> 24;
+ uint8_t lo = (chunkType >> 16) & 0xff;
+
+ if (hi < '0' || hi > '9' || lo < '0' || lo > '9') {
+ return ERROR_MALFORMED;
+ }
+
+ size_t trackIndex = 10 * (hi - '0') + (lo - '0');
+
+ if (trackIndex >= mTracks.size()) {
+ return ERROR_MALFORMED;
+ }
+
+ Track *track = &mTracks.editItemAt(trackIndex);
+
+ if (!IsCorrectChunkType(-1, track->mKind, chunkType)) {
+ return ERROR_MALFORMED;
+ }
+
+ if (track->mKind == Track::OTHER) {
+ data += 16;
+ size -= 16;
+ continue;
+ }
+
+ uint32_t flags = U32LE_AT(&data[4]);
+ uint32_t offset = U32LE_AT(&data[8]);
+ uint32_t chunkSize = U32LE_AT(&data[12]);
+
+ if (chunkSize > track->mMaxSampleSize) {
+ track->mMaxSampleSize = chunkSize;
+ }
+
+ track->mSamples.push();
+
+ SampleInfo *info =
+ &track->mSamples.editItemAt(track->mSamples.size() - 1);
+
+ info->mOffset = offset;
+ info->mIsKey = (flags & 0x10) != 0;
+
+ if (info->mIsKey) {
+ static const size_t kMaxNumSyncSamplesToScan = 20;
+
+ if (track->mNumSyncSamples < kMaxNumSyncSamplesToScan) {
+ if (chunkSize > track->mThumbnailSampleSize) {
+ track->mThumbnailSampleSize = chunkSize;
+
+ track->mThumbnailSampleIndex =
+ track->mSamples.size() - 1;
+ }
+ }
+
+ ++track->mNumSyncSamples;
+ }
+
+ data += 16;
+ size -= 16;
+ }
+
+ if (!mTracks.isEmpty()) {
+ off64_t offset;
+ size_t size;
+ bool isKey;
+ status_t err = getSampleInfo(0, 0, &offset, &size, &isKey);
+
+ if (err != OK) {
+ mOffsetsAreAbsolute = !mOffsetsAreAbsolute;
+ err = getSampleInfo(0, 0, &offset, &size, &isKey);
+
+ if (err != OK) {
+ return err;
+ }
+ }
+
+ LOGV("Chunk offsets are %s",
+ mOffsetsAreAbsolute ? "absolute" : "movie-chunk relative");
+ }
+
+ for (size_t i = 0; i < mTracks.size(); ++i) {
+ Track *track = &mTracks.editItemAt(i);
+
+ int64_t durationUs =
+ (track->mSamples.size() * 1000000ll * track->mRate) / track->mScale;
+
+ LOGV("track %d duration = %.2f secs", i, durationUs / 1E6);
+
+ track->mMeta->setInt64(kKeyDuration, durationUs);
+ track->mMeta->setInt32(kKeyMaxInputSize, track->mMaxSampleSize);
+
+ const char *tmp;
+ CHECK(track->mMeta->findCString(kKeyMIMEType, &tmp));
+
+ AString mime = tmp;
+
+ if (!strncasecmp("video/", mime.c_str(), 6)
+ && track->mThumbnailSampleIndex >= 0) {
+ int64_t thumbnailTimeUs =
+ (track->mThumbnailSampleIndex * 1000000ll * track->mRate)
+ / track->mScale;
+
+ track->mMeta->setInt64(kKeyThumbnailTime, thumbnailTimeUs);
+
+ if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_MPEG4)) {
+ status_t err = addMPEG4CodecSpecificData(i);
+
+ if (err != OK) {
+ return err;
+ }
+ }
+ }
+ }
+
+ mFoundIndex = true;
+
+ return OK;
+}
+
+static size_t GetSizeWidth(size_t x) {
+ size_t n = 1;
+ while (x > 127) {
+ ++n;
+ x >>= 7;
+ }
+ return n;
+}
+
+static uint8_t *EncodeSize(uint8_t *dst, size_t x) {
+ while (x > 127) {
+ *dst++ = (x & 0x7f) | 0x80;
+ x >>= 7;
+ }
+ *dst++ = x;
+ return dst;
+}
+
+sp<ABuffer> MakeMPEG4VideoCodecSpecificData(const sp<ABuffer> &config) {
+ size_t len1 = config->size() + GetSizeWidth(config->size()) + 1;
+ size_t len2 = len1 + GetSizeWidth(len1) + 1 + 13;
+ size_t len3 = len2 + GetSizeWidth(len2) + 1 + 3;
+
+ sp<ABuffer> csd = new ABuffer(len3);
+ uint8_t *dst = csd->data();
+ *dst++ = 0x03;
+ dst = EncodeSize(dst, len2 + 3);
+ *dst++ = 0x00; // ES_ID
+ *dst++ = 0x00;
+ *dst++ = 0x00; // streamDependenceFlag, URL_Flag, OCRstreamFlag
+
+ *dst++ = 0x04;
+ dst = EncodeSize(dst, len1 + 13);
+ *dst++ = 0x01; // Video ISO/IEC 14496-2 Simple Profile
+ for (size_t i = 0; i < 12; ++i) {
+ *dst++ = 0x00;
+ }
+
+ *dst++ = 0x05;
+ dst = EncodeSize(dst, config->size());
+ memcpy(dst, config->data(), config->size());
+ dst += config->size();
+
+ // hexdump(csd->data(), csd->size());
+
+ return csd;
+}
+
+status_t AVIExtractor::addMPEG4CodecSpecificData(size_t trackIndex) {
+ Track *track = &mTracks.editItemAt(trackIndex);
+
+ off64_t offset;
+ size_t size;
+ bool isKey;
+ status_t err = getSampleInfo(trackIndex, 0, &offset, &size, &isKey);
+
+ if (err != OK) {
+ return err;
+ }
+
+ sp<ABuffer> buffer = new ABuffer(size);
+ ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size());
+
+ if (n < (ssize_t)size) {
+ return n < 0 ? (status_t)n : ERROR_MALFORMED;
+ }
+
+ // Extract everything up to the first VOP start code from the first
+ // frame's encoded data and use it to construct an ESDS with the
+ // codec specific data.
+
+ size_t i = 0;
+ bool found = false;
+ while (i + 3 < buffer->size()) {
+ if (!memcmp("\x00\x00\x01\xb6", &buffer->data()[i], 4)) {
+ found = true;
+ break;
+ }
+
+ ++i;
+ }
+
+ if (!found) {
+ return ERROR_MALFORMED;
+ }
+
+ buffer->setRange(0, i);
+
+ sp<ABuffer> csd = MakeMPEG4VideoCodecSpecificData(buffer);
+ track->mMeta->setData(kKeyESDS, kTypeESDS, csd->data(), csd->size());
+
+ return OK;
+}
+
+status_t AVIExtractor::getSampleInfo(
+ size_t trackIndex, size_t sampleIndex,
+ off64_t *offset, size_t *size, bool *isKey) {
+ if (trackIndex >= mTracks.size()) {
+ return -ERANGE;
+ }
+
+ const Track &track = mTracks.itemAt(trackIndex);
+
+ if (sampleIndex >= track.mSamples.size()) {
+ return -ERANGE;
+ }
+
+ const SampleInfo &info = track.mSamples.itemAt(sampleIndex);
+
+ if (!mOffsetsAreAbsolute) {
+ *offset = info.mOffset + mMovieOffset + 8;
+ } else {
+ *offset = info.mOffset;
+ }
+
+ *size = 0;
+
+ uint8_t tmp[8];
+ ssize_t n = mDataSource->readAt(*offset, tmp, 8);
+
+ if (n < 8) {
+ return n < 0 ? (status_t)n : (status_t)ERROR_MALFORMED;
+ }
+
+ uint32_t chunkType = U32_AT(tmp);
+
+ if (!IsCorrectChunkType(trackIndex, track.mKind, chunkType)) {
+ return ERROR_MALFORMED;
+ }
+
+ *offset += 8;
+ *size = U32LE_AT(&tmp[4]);
+
+ *isKey = info.mIsKey;
+
+ return OK;
+}
+
+status_t AVIExtractor::getSampleIndexAtTime(
+ size_t trackIndex,
+ int64_t timeUs, MediaSource::ReadOptions::SeekMode mode,
+ size_t *sampleIndex) const {
+ if (trackIndex >= mTracks.size()) {
+ return -ERANGE;
+ }
+
+ const Track &track = mTracks.itemAt(trackIndex);
+
+ ssize_t closestSampleIndex =
+ timeUs / track.mRate * track.mScale / 1000000ll;
+
+ ssize_t numSamples = track.mSamples.size();
+
+ if (closestSampleIndex < 0) {
+ closestSampleIndex = 0;
+ } else if (closestSampleIndex >= numSamples) {
+ closestSampleIndex = numSamples - 1;
+ }
+
+ if (mode == MediaSource::ReadOptions::SEEK_CLOSEST) {
+ *sampleIndex = closestSampleIndex;
+
+ return OK;
+ }
+
+ ssize_t prevSyncSampleIndex = closestSampleIndex;
+ while (prevSyncSampleIndex >= 0) {
+ const SampleInfo &info =
+ track.mSamples.itemAt(prevSyncSampleIndex);
+
+ if (info.mIsKey) {
+ break;
+ }
+
+ --prevSyncSampleIndex;
+ }
+
+ ssize_t nextSyncSampleIndex = closestSampleIndex;
+ while (nextSyncSampleIndex < numSamples) {
+ const SampleInfo &info =
+ track.mSamples.itemAt(nextSyncSampleIndex);
+
+ if (info.mIsKey) {
+ break;
+ }
+
+ ++nextSyncSampleIndex;
+ }
+
+ switch (mode) {
+ case MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC:
+ {
+ *sampleIndex = prevSyncSampleIndex;
+
+ return prevSyncSampleIndex >= 0 ? OK : UNKNOWN_ERROR;
+ }
+
+ case MediaSource::ReadOptions::SEEK_NEXT_SYNC:
+ {
+ *sampleIndex = nextSyncSampleIndex;
+
+ return nextSyncSampleIndex < numSamples ? OK : UNKNOWN_ERROR;
+ }
+
+ case MediaSource::ReadOptions::SEEK_CLOSEST_SYNC:
+ {
+ if (prevSyncSampleIndex < 0 && nextSyncSampleIndex >= numSamples) {
+ return UNKNOWN_ERROR;
+ }
+
+ if (prevSyncSampleIndex < 0) {
+ *sampleIndex = nextSyncSampleIndex;
+ return OK;
+ }
+
+ if (nextSyncSampleIndex >= numSamples) {
+ *sampleIndex = prevSyncSampleIndex;
+ return OK;
+ }
+
+ size_t dist1 = closestSampleIndex - prevSyncSampleIndex;
+ size_t dist2 = nextSyncSampleIndex - closestSampleIndex;
+
+ *sampleIndex =
+ (dist1 < dist2) ? prevSyncSampleIndex : nextSyncSampleIndex;
+
+ return OK;
+ }
+
+ default:
+ TRESPASS();
+ break;
+ }
+}
+
+bool SniffAVI(
+ const sp<DataSource> &source, String8 *mimeType, float *confidence,
+ sp<AMessage> *) {
+ char tmp[12];
+ if (source->readAt(0, tmp, 12) < 12) {
+ return false;
+ }
+
+ if (!memcmp(tmp, "RIFF", 4) && !memcmp(&tmp[8], "AVI ", 4)) {
+ mimeType->setTo(MEDIA_MIMETYPE_CONTAINER_AVI);
+ *confidence = 0.2;
+
+ return true;
+ }
+
+ return false;
+}
+
+} // namespace android
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 88069e9..3f4dace 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -6,8 +6,10 @@
LOCAL_SRC_FILES:= \
ACodec.cpp \
AACExtractor.cpp \
+ AACWriter.cpp \
AMRExtractor.cpp \
AMRWriter.cpp \
+ AVIExtractor.cpp \
AudioPlayer.cpp \
AudioSource.cpp \
AwesomePlayer.cpp \
@@ -19,7 +21,7 @@
ESDS.cpp \
FileSource.cpp \
FLACExtractor.cpp \
- HTTPStream.cpp \
+ HTTPBase.cpp \
JPEGSource.cpp \
MP3Extractor.cpp \
MPEG2TSWriter.cpp \
@@ -33,16 +35,14 @@
MediaSourceSplitter.cpp \
MetaData.cpp \
NuCachedSource2.cpp \
- NuHTTPDataSource.cpp \
OMXClient.cpp \
OMXCodec.cpp \
OggExtractor.cpp \
SampleIterator.cpp \
SampleTable.cpp \
- ShoutcastSource.cpp \
StagefrightMediaScanner.cpp \
StagefrightMetadataRetriever.cpp \
- ThreadedSource.cpp \
+ SurfaceMediaSource.cpp \
ThrottledSource.cpp \
TimeSource.cpp \
TimedEventQueue.cpp \
@@ -69,57 +69,86 @@
libui \
libsonivox \
libvorbisidec \
- libsurfaceflinger_client \
libstagefright_yuv \
libcamera_client \
libdrmframework \
libcrypto \
libssl \
- libgui
+ libgui \
LOCAL_STATIC_LIBRARIES := \
libstagefright_color_conversion \
- libstagefright_aacdec \
libstagefright_aacenc \
- libstagefright_amrnbdec \
libstagefright_amrnbenc \
- libstagefright_amrwbdec \
libstagefright_amrwbenc \
- libstagefright_avcdec \
libstagefright_avcenc \
- libstagefright_m4vh263dec \
libstagefright_m4vh263enc \
- libstagefright_mp3dec \
- libstagefright_vorbisdec \
libstagefright_matroska \
- libstagefright_vpxdec \
+ libstagefright_timedtext \
libvpx \
libstagefright_mpeg2ts \
libstagefright_httplive \
libstagefright_rtsp \
libstagefright_id3 \
- libstagefright_g711dec \
libFLAC \
+################################################################################
+
+# The following was shamelessly copied from external/webkit/Android.mk and
+# currently must follow the same logic to determine how webkit was built and
+# if it's safe to link against libchromium.net
+
+# V8 also requires an ARMv7 CPU, and since we must use jsc, we cannot
+# use the Chrome http stack either.
+ifneq ($(strip $(ARCH_ARM_HAVE_ARMV7A)),true)
+ USE_ALT_HTTP := true
+endif
+
+# See if the user has specified a stack they want to use
+HTTP_STACK = $(HTTP)
+# We default to the Chrome HTTP stack.
+DEFAULT_HTTP = chrome
+ALT_HTTP = android
+
+ifneq ($(HTTP_STACK),chrome)
+ ifneq ($(HTTP_STACK),android)
+ # No HTTP stack is specified, pickup the one we want as default.
+ ifeq ($(USE_ALT_HTTP),true)
+ HTTP_STACK = $(ALT_HTTP)
+ else
+ HTTP_STACK = $(DEFAULT_HTTP)
+ endif
+ endif
+endif
+
+ifeq ($(HTTP_STACK),chrome)
+
+LOCAL_SHARED_LIBRARIES += \
+ liblog \
+ libicuuc \
+ libicui18n \
+ libz \
+ libdl \
+
+LOCAL_STATIC_LIBRARIES += \
+ libstagefright_chromium_http \
+ libwebcore \
+
+LOCAL_SHARED_LIBRARIES += libstlport libchromium_net
+include external/stlport/libstlport.mk
+
+LOCAL_CPPFLAGS += -DCHROMIUM_AVAILABLE=1
+
+endif # ifeq ($(HTTP_STACK),chrome)
+
+################################################################################
+
LOCAL_SHARED_LIBRARIES += \
libstagefright_amrnb_common \
libstagefright_enc_common \
libstagefright_avc_common \
libstagefright_foundation \
-
-ifeq ($(TARGET_OS)-$(TARGET_SIMULATOR),linux-true)
- LOCAL_LDLIBS += -lpthread -ldl
- LOCAL_SHARED_LIBRARIES += libdvm
- LOCAL_CPPFLAGS += -DANDROID_SIMULATOR
-endif
-
-ifneq ($(TARGET_SIMULATOR),true)
-LOCAL_SHARED_LIBRARIES += libdl
-endif
-
-ifeq ($(TARGET_OS)-$(TARGET_SIMULATOR),linux-true)
- LOCAL_LDLIBS += -lpthread
-endif
+ libdl
LOCAL_CFLAGS += -Wno-multichar
diff --git a/media/libstagefright/AudioPlayer.cpp b/media/libstagefright/AudioPlayer.cpp
index bd04a26..dd69e6b 100644
--- a/media/libstagefright/AudioPlayer.cpp
+++ b/media/libstagefright/AudioPlayer.cpp
@@ -84,7 +84,13 @@
CHECK(mFirstBuffer == NULL);
- mFirstBufferResult = mSource->read(&mFirstBuffer);
+ MediaSource::ReadOptions options;
+ if (mSeeking) {
+ options.setSeekTo(mSeekTimeUs);
+ mSeeking = false;
+ }
+
+ mFirstBufferResult = mSource->read(&mFirstBuffer, &options);
if (mFirstBufferResult == INFO_FORMAT_CHANGED) {
LOGV("INFO_FORMAT_CHANGED!!!");
@@ -110,7 +116,7 @@
if (mAudioSink.get() != NULL) {
status_t err = mAudioSink->open(
- mSampleRate, numChannels, AudioSystem::PCM_16_BIT,
+ mSampleRate, numChannels, AUDIO_FORMAT_PCM_16_BIT,
DEFAULT_AUDIOSINK_BUFFERCOUNT,
&AudioPlayer::AudioSinkCallback, this);
if (err != OK) {
@@ -132,10 +138,10 @@
mAudioSink->start();
} else {
mAudioTrack = new AudioTrack(
- AudioSystem::MUSIC, mSampleRate, AudioSystem::PCM_16_BIT,
+ AUDIO_STREAM_MUSIC, mSampleRate, AUDIO_FORMAT_PCM_16_BIT,
(numChannels == 2)
- ? AudioSystem::CHANNEL_OUT_STEREO
- : AudioSystem::CHANNEL_OUT_MONO,
+ ? AUDIO_CHANNEL_OUT_STEREO
+ : AUDIO_CHANNEL_OUT_MONO,
0, 0, &AudioCallback, this, 0);
if ((err = mAudioTrack->initCheck()) != OK) {
@@ -280,17 +286,39 @@
buffer->size = numBytesWritten;
}
+uint32_t AudioPlayer::getNumFramesPendingPlayout() const {
+ uint32_t numFramesPlayedOut;
+ status_t err;
+
+ if (mAudioSink != NULL) {
+ err = mAudioSink->getPosition(&numFramesPlayedOut);
+ } else {
+ err = mAudioTrack->getPosition(&numFramesPlayedOut);
+ }
+
+ if (err != OK || mNumFramesPlayed < numFramesPlayedOut) {
+ return 0;
+ }
+
+ // mNumFramesPlayed is the number of frames submitted
+ // to the audio sink for playback, but not all of them
+ // may have played out by now.
+ return mNumFramesPlayed - numFramesPlayedOut;
+}
+
size_t AudioPlayer::fillBuffer(void *data, size_t size) {
if (mNumFramesPlayed == 0) {
LOGV("AudioCallback");
}
if (mReachedEOS) {
- memset(data, 0, size);
-
- return size;
+ return 0;
}
+ bool postSeekComplete = false;
+ bool postEOS = false;
+ int64_t postEOSDelayUs = 0;
+
size_t size_done = 0;
size_t size_remaining = size;
while (size_remaining > 0) {
@@ -317,7 +345,7 @@
mSeeking = false;
if (mObserver) {
- mObserver->postAudioSeekComplete();
+ postSeekComplete = true;
}
}
}
@@ -342,7 +370,35 @@
if (err != OK) {
if (mObserver && !mReachedEOS) {
- mObserver->postAudioEOS();
+ // We don't want to post EOS right away but only
+ // after all frames have actually been played out.
+
+ // These are the number of frames submitted to the
+ // AudioTrack that you haven't heard yet.
+ uint32_t numFramesPendingPlayout =
+ getNumFramesPendingPlayout();
+
+ // These are the number of frames we're going to
+ // submit to the AudioTrack by returning from this
+ // callback.
+ uint32_t numAdditionalFrames = size_done / mFrameSize;
+
+ numFramesPendingPlayout += numAdditionalFrames;
+
+ int64_t timeToCompletionUs =
+ (1000000ll * numFramesPendingPlayout) / mSampleRate;
+
+ LOGV("total number of frames played: %lld (%lld us)",
+ (mNumFramesPlayed + numAdditionalFrames),
+ 1000000ll * (mNumFramesPlayed + numAdditionalFrames)
+ / mSampleRate);
+
+ LOGV("%d frames left to play, %lld us (%.2f secs)",
+ numFramesPendingPlayout,
+ timeToCompletionUs, timeToCompletionUs / 1E6);
+
+ postEOS = true;
+ postEOSDelayUs = timeToCompletionUs + mLatencyUs;
}
mReachedEOS = true;
@@ -386,8 +442,18 @@
size_remaining -= copy;
}
- Mutex::Autolock autoLock(mLock);
- mNumFramesPlayed += size_done / mFrameSize;
+ {
+ Mutex::Autolock autoLock(mLock);
+ mNumFramesPlayed += size_done / mFrameSize;
+ }
+
+ if (postEOS) {
+ mObserver->postAudioEOS(postEOSDelayUs);
+ }
+
+ if (postSeekComplete) {
+ mObserver->postAudioSeekComplete();
+ }
return size_done;
}
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index bbdec02..99c3682 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -60,8 +60,8 @@
AudioRecord::RECORD_NS_ENABLE |
AudioRecord::RECORD_IIR_ENABLE;
mRecord = new AudioRecord(
- inputSource, sampleRate, AudioSystem::PCM_16_BIT,
- channels > 1? AudioSystem::CHANNEL_IN_STEREO: AudioSystem::CHANNEL_IN_MONO,
+ inputSource, sampleRate, AUDIO_FORMAT_PCM_16_BIT,
+ channels > 1? AUDIO_CHANNEL_IN_STEREO: AUDIO_CHANNEL_IN_MONO,
4 * kMaxBufferSize / sizeof(int16_t), /* Enable ping-pong buffers */
flags,
AudioRecordCallbackFunction,
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 5962454..67f6c79 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -31,6 +31,8 @@
#include "include/MPEG2TSExtractor.h"
#include "include/WVMExtractor.h"
+#include "timedtext/TimedTextPlayer.h"
+
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <media/IMediaPlayerService.h>
@@ -57,7 +59,6 @@
#include <cutils/properties.h>
#define USE_SURFACE_ALLOC 1
-#define FRAME_DROP_FREQ 0
namespace android {
@@ -127,6 +128,9 @@
}
virtual void render(MediaBuffer *buffer) {
+ int64_t timeUs;
+ CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs));
+ native_window_set_buffers_timestamp(mNativeWindow.get(), timeUs * 1000);
status_t err = mNativeWindow->queueBuffer(
mNativeWindow.get(), buffer->graphicBuffer().get());
if (err != 0) {
@@ -179,6 +183,7 @@
////////////////////////////////////////////////////////////////////////////////
AwesomePlayer::AwesomePlayer()
: mQueueStarted(false),
+ mUIDValid(false),
mTimeSource(NULL),
mVideoRendererIsPreview(false),
mAudioPlayer(NULL),
@@ -187,7 +192,9 @@
mFlags(0),
mExtractorFlags(0),
mVideoBuffer(NULL),
- mDecryptHandle(NULL) {
+ mDecryptHandle(NULL),
+ mLastVideoTimeUs(-1),
+ mTextPlayer(NULL) {
CHECK_EQ(mClient.connect(), (status_t)OK);
DataSource::RegisterDefaultSniffers();
@@ -240,6 +247,13 @@
mListener = listener;
}
+void AwesomePlayer::setUID(uid_t uid) {
+ LOGI("AwesomePlayer running on behalf of uid %d", uid);
+
+ mUID = uid;
+ mUIDValid = true;
+}
+
status_t AwesomePlayer::setDataSource(
const char *uri, const KeyedVector<String8, String8> *headers) {
Mutex::Autolock autoLock(mLock);
@@ -262,7 +276,7 @@
// This isn't something that should be passed to the server.
mUriHeaders.removeItemsAt(index);
- mFlags |= INCOGNITO;
+ modifyFlags(INCOGNITO, SET);
}
}
@@ -276,6 +290,12 @@
// ::finishSetDataSource_l to avoid blocking the calling thread in
// setDataSource for any significant time.
+ {
+ Mutex::Autolock autoLock(mStatsLock);
+ mStats.mFd = -1;
+ mStats.mURI = mUri;
+ }
+
return OK;
}
@@ -295,6 +315,12 @@
mFileSource = dataSource;
+ {
+ Mutex::Autolock autoLock(mStatsLock);
+ mStats.mFd = fd;
+ mStats.mURI = String8();
+ }
+
return setDataSource_l(dataSource);
}
@@ -310,7 +336,7 @@
return UNKNOWN_ERROR;
}
- dataSource->getDrmInfo(&mDecryptHandle, &mDrmManagerClient);
+ dataSource->getDrmInfo(mDecryptHandle, &mDrmManagerClient);
if (mDecryptHandle != NULL) {
CHECK(mDrmManagerClient);
if (RightsStatus::RIGHTS_VALID != mDecryptHandle->status) {
@@ -333,6 +359,10 @@
int32_t bitrate;
if (!meta->findInt32(kKeyBitRate, &bitrate)) {
+ const char *mime;
+ CHECK(meta->findCString(kKeyMIMEType, &mime));
+ LOGW("track of type '%s' does not publish bitrate", mime);
+
totalBitRate = -1;
break;
}
@@ -344,6 +374,14 @@
LOGV("mBitrate = %lld bits/sec", mBitrate);
+ {
+ Mutex::Autolock autoLock(mStatsLock);
+ mStats.mBitrate = mBitrate;
+ mStats.mTracks.clear();
+ mStats.mAudioTrackIndex = -1;
+ mStats.mVideoTrackIndex = -1;
+ }
+
bool haveAudio = false;
bool haveVideo = false;
for (size_t i = 0; i < extractor->countTracks(); ++i) {
@@ -367,10 +405,27 @@
mDisplayHeight = displayHeight;
}
+ {
+ Mutex::Autolock autoLock(mStatsLock);
+ mStats.mVideoTrackIndex = mStats.mTracks.size();
+ mStats.mTracks.push();
+ TrackStat *stat =
+ &mStats.mTracks.editItemAt(mStats.mVideoTrackIndex);
+ stat->mMIME = mime;
+ }
} else if (!haveAudio && !strncasecmp(mime, "audio/", 6)) {
setAudioSource(extractor->getTrack(i));
haveAudio = true;
+ {
+ Mutex::Autolock autoLock(mStatsLock);
+ mStats.mAudioTrackIndex = mStats.mTracks.size();
+ mStats.mTracks.push();
+ TrackStat *stat =
+ &mStats.mTracks.editItemAt(mStats.mAudioTrackIndex);
+ stat->mMIME = mime;
+ }
+
if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) {
// Only do this for vorbis audio, none of the other audio
// formats even support this ringtone specific hack and
@@ -380,13 +435,11 @@
int32_t loop;
if (fileMeta != NULL
&& fileMeta->findInt32(kKeyAutoLoop, &loop) && loop != 0) {
- mFlags |= AUTO_LOOPING;
+ modifyFlags(AUTO_LOOPING, SET);
}
}
- }
-
- if (haveAudio && haveVideo) {
- break;
+ } else if (!strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP)) {
+ addTextSource(extractor->getTrack(i));
}
}
@@ -400,7 +453,6 @@
}
void AwesomePlayer::reset() {
- LOGI("reset");
Mutex::Autolock autoLock(mLock);
reset_l();
}
@@ -414,10 +466,8 @@
Playback::STOP, 0);
mDecryptHandle = NULL;
mDrmManagerClient = NULL;
- LOGI("DRM manager client stopped");
}
-
if (mFlags & PLAYING) {
uint32_t params = IMediaPlayerService::kBatteryDataTrackDecoder;
if ((mAudioSource != NULL) && (mAudioSource != mAudioTrack)) {
@@ -430,7 +480,7 @@
}
if (mFlags & PREPARING) {
- mFlags |= PREPARE_CANCELLED;
+ modifyFlags(PREPARE_CANCELLED, SET);
if (mConnectingDataSource != NULL) {
LOGI("interrupting the connection process");
mConnectingDataSource->disconnect();
@@ -450,7 +500,6 @@
mPreparedCondition.wait(mLock);
}
- LOGI("cancel player events");
cancelPlayerEvents();
mWVMExtractor.clear();
@@ -476,35 +525,24 @@
delete mAudioPlayer;
mAudioPlayer = NULL;
- mVideoRenderer.clear();
-
- if (mVideoBuffer) {
- mVideoBuffer->release();
- mVideoBuffer = NULL;
+ if (mTextPlayer != NULL) {
+ delete mTextPlayer;
+ mTextPlayer = NULL;
}
+ mVideoRenderer.clear();
+
if (mRTSPController != NULL) {
mRTSPController->disconnect();
mRTSPController.clear();
}
if (mVideoSource != NULL) {
- mVideoSource->stop();
-
- // The following hack is necessary to ensure that the OMX
- // component is completely released by the time we may try
- // to instantiate it again.
- wp<MediaSource> tmp = mVideoSource;
- mVideoSource.clear();
- while (tmp.promote() != NULL) {
- usleep(1000);
- }
- IPCThreadState::self()->flushCommands();
- LOGI("video decoder shutdown completed");
+ shutdownVideoDecoder_l();
}
mDurationUs = -1;
- mFlags = 0;
+ modifyFlags(0, ASSIGN);
mExtractorFlags = 0;
mTimeSourceDeltaUs = 0;
mVideoTimeUs = 0;
@@ -519,6 +557,23 @@
mFileSource.clear();
mBitrate = -1;
+ mLastVideoTimeUs = -1;
+
+ {
+ Mutex::Autolock autoLock(mStatsLock);
+ mStats.mFd = -1;
+ mStats.mURI = String8();
+ mStats.mBitrate = -1;
+ mStats.mAudioTrackIndex = -1;
+ mStats.mVideoTrackIndex = -1;
+ mStats.mNumVideoFramesDecoded = 0;
+ mStats.mNumVideoFramesDropped = 0;
+ mStats.mVideoWidth = -1;
+ mStats.mVideoHeight = -1;
+ mStats.mFlags = 0;
+ mStats.mTracks.clear();
+ }
+
}
void AwesomePlayer::notifyListener_l(int msg, int ext1, int ext2) {
@@ -640,15 +695,16 @@
&& (cachedDataRemaining < kLowWaterMarkBytes)) {
LOGI("cache is running low (< %d) , pausing.",
kLowWaterMarkBytes);
- mFlags |= CACHE_UNDERRUN;
+ modifyFlags(CACHE_UNDERRUN, SET);
pause_l();
ensureCacheIsFetching_l();
+ sendCacheStats();
notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_START);
} else if (eos || cachedDataRemaining > kHighWaterMarkBytes) {
if (mFlags & CACHE_UNDERRUN) {
LOGI("cache has filled up (> %d), resuming.",
kHighWaterMarkBytes);
- mFlags &= ~CACHE_UNDERRUN;
+ modifyFlags(CACHE_UNDERRUN, CLEAR);
play_l();
notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_END);
} else if (mFlags & PREPARING) {
@@ -698,15 +754,16 @@
&& (cachedDurationUs < kLowWaterMarkUs)) {
LOGI("cache is running low (%.2f secs) , pausing.",
cachedDurationUs / 1E6);
- mFlags |= CACHE_UNDERRUN;
+ modifyFlags(CACHE_UNDERRUN, SET);
pause_l();
ensureCacheIsFetching_l();
+ sendCacheStats();
notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_START);
} else if (eos || cachedDurationUs > highWaterMarkUs) {
if (mFlags & CACHE_UNDERRUN) {
LOGI("cache has filled up (%.2f secs), resuming.",
cachedDurationUs / 1E6);
- mFlags &= ~CACHE_UNDERRUN;
+ modifyFlags(CACHE_UNDERRUN, CLEAR);
play_l();
notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_END);
} else if (mFlags & PREPARING) {
@@ -720,6 +777,18 @@
postBufferingEvent_l();
}
+void AwesomePlayer::sendCacheStats() {
+ sp<MediaPlayerBase> listener = mListener.promote();
+ if (listener != NULL && mCachedSource != NULL) {
+ int32_t kbps = 0;
+ status_t err = mCachedSource->getEstimatedBandwidthKbps(&kbps);
+ if (err == OK) {
+ listener->sendEvent(
+ MEDIA_INFO, MEDIA_INFO_NETWORK_BANDWIDTH, kbps);
+ }
+ }
+}
+
void AwesomePlayer::onStreamDone() {
// Posted whenever any stream finishes playing.
@@ -737,7 +806,7 @@
pause_l(true /* at eos */);
- mFlags |= AT_EOS;
+ modifyFlags(AT_EOS, SET);
return;
}
@@ -761,20 +830,20 @@
pause_l(true /* at eos */);
- mFlags |= AT_EOS;
+ modifyFlags(AT_EOS, SET);
}
}
status_t AwesomePlayer::play() {
Mutex::Autolock autoLock(mLock);
- mFlags &= ~CACHE_UNDERRUN;
+ modifyFlags(CACHE_UNDERRUN, CLEAR);
return play_l();
}
status_t AwesomePlayer::play_l() {
- mFlags &= ~SEEK_PREVIEW;
+ modifyFlags(SEEK_PREVIEW, CLEAR);
if (mFlags & PLAYING) {
return OK;
@@ -788,8 +857,8 @@
}
}
- mFlags |= PLAYING;
- mFlags |= FIRST_FRAME;
+ modifyFlags(PLAYING, SET);
+ modifyFlags(FIRST_FRAME, SET);
if (mDecryptHandle != NULL) {
int64_t position;
@@ -817,13 +886,17 @@
CHECK(!(mFlags & AUDIO_RUNNING));
if (mVideoSource == NULL) {
- status_t err = startAudioPlayer_l();
+ // We don't want to post an error notification at this point,
+ // the error returned from MediaPlayer::start() will suffice.
+
+ status_t err = startAudioPlayer_l(
+ false /* sendErrorNotification */);
if (err != OK) {
delete mAudioPlayer;
mAudioPlayer = NULL;
- mFlags &= ~(PLAYING | FIRST_FRAME);
+ modifyFlags((PLAYING | FIRST_FRAME), CLEAR);
if (mDecryptHandle != NULL) {
mDrmManagerClient->setPlaybackStatus(
@@ -867,7 +940,7 @@
return OK;
}
-status_t AwesomePlayer::startAudioPlayer_l() {
+status_t AwesomePlayer::startAudioPlayer_l(bool sendErrorNotification) {
CHECK(!(mFlags & AUDIO_RUNNING));
if (mAudioSource == NULL || mAudioPlayer == NULL) {
@@ -875,7 +948,9 @@
}
if (!(mFlags & AUDIOPLAYER_STARTED)) {
- mFlags |= AUDIOPLAYER_STARTED;
+ modifyFlags(AUDIOPLAYER_STARTED, SET);
+
+ bool wasSeeking = mAudioPlayer->isSeeking();
// We've already started the MediaSource in order to enable
// the prefetcher to read its data.
@@ -883,14 +958,24 @@
true /* sourceAlreadyStarted */);
if (err != OK) {
- notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
+ if (sendErrorNotification) {
+ notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
+ }
+
return err;
}
+
+ if (wasSeeking) {
+ CHECK(!mAudioPlayer->isSeeking());
+
+ // We will have finished the seek while starting the audio player.
+ postAudioSeekComplete_l();
+ }
} else {
mAudioPlayer->resume();
}
- mFlags |= AUDIO_RUNNING;
+ modifyFlags(AUDIO_RUNNING, SET);
mWatchForAudioEOS = true;
@@ -917,6 +1002,17 @@
cropLeft, cropTop, cropRight, cropBottom);
}
+ int32_t displayWidth;
+ if (meta->findInt32(kKeyDisplayWidth, &displayWidth)) {
+ LOGV("Display width changed (%d=>%d)", mDisplayWidth, displayWidth);
+ mDisplayWidth = displayWidth;
+ }
+ int32_t displayHeight;
+ if (meta->findInt32(kKeyDisplayHeight, &displayHeight)) {
+ LOGV("Display height changed (%d=>%d)", mDisplayHeight, displayHeight);
+ mDisplayHeight = displayHeight;
+ }
+
int32_t usableWidth = cropRight - cropLeft + 1;
int32_t usableHeight = cropBottom - cropTop + 1;
if (mDisplayWidth != 0) {
@@ -926,6 +1022,12 @@
usableHeight = mDisplayHeight;
}
+ {
+ Mutex::Autolock autoLock(mStatsLock);
+ mStats.mVideoWidth = usableWidth;
+ mStats.mVideoHeight = usableHeight;
+ }
+
int32_t rotationDegrees;
if (!mVideoTrack->getFormat()->findInt32(
kKeyRotation, &rotationDegrees)) {
@@ -968,7 +1070,9 @@
// before creating a new one.
IPCThreadState::self()->flushCommands();
- if (USE_SURFACE_ALLOC && strncmp(component, "OMX.", 4) == 0) {
+ if (USE_SURFACE_ALLOC
+ && !strncmp(component, "OMX.", 4)
+ && strncmp(component, "OMX.google.", 11)) {
// Hardware decoders avoid the CPU color conversion by decoding
// directly to ANativeBuffers, so we must use a renderer that
// just pushes those buffers to the ANativeWindow.
@@ -986,7 +1090,7 @@
status_t AwesomePlayer::pause() {
Mutex::Autolock autoLock(mLock);
- mFlags &= ~CACHE_UNDERRUN;
+ modifyFlags(CACHE_UNDERRUN, CLEAR);
return pause_l();
}
@@ -1008,10 +1112,15 @@
mAudioPlayer->pause();
}
- mFlags &= ~AUDIO_RUNNING;
+ modifyFlags(AUDIO_RUNNING, CLEAR);
}
- mFlags &= ~PLAYING;
+ if (mFlags & TEXTPLAYER_STARTED) {
+ mTextPlayer->pause();
+ modifyFlags(TEXT_RUNNING, CLEAR);
+ }
+
+ modifyFlags(PLAYING, CLEAR);
if (mDecryptHandle != NULL) {
mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
@@ -1039,7 +1148,7 @@
Mutex::Autolock autoLock(mLock);
mSurface = surface;
- mNativeWindow = surface;
+ setNativeWindow_l(surface);
}
void AwesomePlayer::setSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture) {
@@ -1047,9 +1156,58 @@
mSurface.clear();
if (surfaceTexture != NULL) {
- mNativeWindow = new SurfaceTextureClient(surfaceTexture);
+ setNativeWindow_l(new SurfaceTextureClient(surfaceTexture));
+ }
+}
+
+void AwesomePlayer::shutdownVideoDecoder_l() {
+ if (mVideoBuffer) {
+ mVideoBuffer->release();
+ mVideoBuffer = NULL;
}
+ mVideoSource->stop();
+
+ // The following hack is necessary to ensure that the OMX
+ // component is completely released by the time we may try
+ // to instantiate it again.
+ wp<MediaSource> tmp = mVideoSource;
+ mVideoSource.clear();
+ while (tmp.promote() != NULL) {
+ usleep(1000);
+ }
+ IPCThreadState::self()->flushCommands();
+ LOGI("video decoder shutdown completed");
+}
+
+void AwesomePlayer::setNativeWindow_l(const sp<ANativeWindow> &native) {
+ mNativeWindow = native;
+
+ if (mVideoSource == NULL) {
+ return;
+ }
+
+ LOGI("attempting to reconfigure to use new surface");
+
+ bool wasPlaying = (mFlags & PLAYING) != 0;
+
+ pause_l();
+ mVideoRenderer.clear();
+
+ shutdownVideoDecoder_l();
+
+ CHECK_EQ(initVideoDecoder(), (status_t)OK);
+
+ if (mLastVideoTimeUs >= 0) {
+ mSeeking = SEEK;
+ mSeekNotificationSent = true;
+ mSeekTimeUs = mLastVideoTimeUs;
+ modifyFlags((AT_EOS | AUDIO_AT_EOS | VIDEO_AT_EOS), CLEAR);
+ }
+
+ if (wasPlaying) {
+ play_l();
+ }
}
void AwesomePlayer::setAudioSink(
@@ -1062,10 +1220,10 @@
status_t AwesomePlayer::setLooping(bool shouldLoop) {
Mutex::Autolock autoLock(mLock);
- mFlags = mFlags & ~LOOPING;
+ modifyFlags(LOOPING, CLEAR);
if (shouldLoop) {
- mFlags |= LOOPING;
+ modifyFlags(LOOPING, SET);
}
return OK;
@@ -1111,6 +1269,32 @@
return OK;
}
+status_t AwesomePlayer::setTimedTextTrackIndex(int32_t index) {
+ if (mTextPlayer != NULL) {
+ if (index >= 0) { // to turn on a text track
+ status_t err = mTextPlayer->setTimedTextTrackIndex(index);
+ if (err != OK) {
+ return err;
+ }
+
+ modifyFlags(TEXT_RUNNING, SET);
+ modifyFlags(TEXTPLAYER_STARTED, SET);
+ return OK;
+ } else { // to turn off the text track display
+ if (mFlags & TEXT_RUNNING) {
+ modifyFlags(TEXT_RUNNING, CLEAR);
+ }
+ if (mFlags & TEXTPLAYER_STARTED) {
+ modifyFlags(TEXTPLAYER_STARTED, CLEAR);
+ }
+
+ return mTextPlayer->setTimedTextTrackIndex(index);
+ }
+ } else {
+ return INVALID_OPERATION;
+ }
+}
+
// static
void AwesomePlayer::OnRTSPSeekDoneWrapper(void *cookie) {
static_cast<AwesomePlayer *>(cookie)->onRTSPSeekDone();
@@ -1128,7 +1312,7 @@
}
if (mFlags & CACHE_UNDERRUN) {
- mFlags &= ~CACHE_UNDERRUN;
+ modifyFlags(CACHE_UNDERRUN, CLEAR);
play_l();
}
@@ -1143,10 +1327,14 @@
mSeeking = SEEK;
mSeekNotificationSent = false;
mSeekTimeUs = timeUs;
- mFlags &= ~(AT_EOS | AUDIO_AT_EOS | VIDEO_AT_EOS);
+ modifyFlags((AT_EOS | AUDIO_AT_EOS | VIDEO_AT_EOS), CLEAR);
seekAudioIfNecessary_l();
+ if (mFlags & TEXTPLAYER_STARTED) {
+ mTextPlayer->seekTo(mSeekTimeUs);
+ }
+
if (!(mFlags & PLAYING)) {
LOGV("seeking while paused, sending SEEK_COMPLETE notification"
" immediately.");
@@ -1155,7 +1343,7 @@
mSeekNotificationSent = true;
if ((mFlags & PREPARED) && mVideoSource != NULL) {
- mFlags |= SEEK_PREVIEW;
+ modifyFlags(SEEK_PREVIEW, SET);
postVideoEvent_l();
}
}
@@ -1169,7 +1357,6 @@
mWatchForAudioSeekComplete = true;
mWatchForAudioEOS = true;
- mSeekNotificationSent = false;
if (mDecryptHandle != NULL) {
mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
@@ -1186,6 +1373,17 @@
mAudioTrack = source;
}
+void AwesomePlayer::addTextSource(sp<MediaSource> source) {
+ Mutex::Autolock autoLock(mTimedTextLock);
+ CHECK(source != NULL);
+
+ if (mTextPlayer == NULL) {
+ mTextPlayer = new TimedTextPlayer(this, mListener, &mQueue);
+ }
+
+ mTextPlayer->addTextSource(source);
+}
+
status_t AwesomePlayer::initAudioDecoder() {
sp<MetaData> meta = mAudioTrack->getFormat();
@@ -1223,6 +1421,19 @@
return OK;
}
+ if (mAudioSource != NULL) {
+ Mutex::Autolock autoLock(mStatsLock);
+ TrackStat *stat = &mStats.mTracks.editItemAt(mStats.mAudioTrackIndex);
+
+ const char *component;
+ if (!mAudioSource->getFormat()
+ ->findCString(kKeyDecoderComponent, &component)) {
+ component = "none";
+ }
+
+ stat->mDecoderName = component;
+ }
+
return mAudioSource != NULL ? OK : UNKNOWN_ERROR;
}
@@ -1302,6 +1513,17 @@
}
}
+ if (mVideoSource != NULL) {
+ Mutex::Autolock autoLock(mStatsLock);
+ TrackStat *stat = &mStats.mTracks.editItemAt(mStats.mVideoTrackIndex);
+
+ const char *component;
+ CHECK(mVideoSource->getFormat()
+ ->findCString(kKeyDecoderComponent, &component));
+
+ stat->mDecoderName = component;
+ }
+
return mVideoSource != NULL ? OK : UNKNOWN_ERROR;
}
@@ -1328,11 +1550,11 @@
// If we're playing video only, report seek complete now,
// otherwise audio player will notify us later.
notifyListener_l(MEDIA_SEEK_COMPLETE);
+ mSeekNotificationSent = true;
}
- mFlags |= FIRST_FRAME;
+ modifyFlags(FIRST_FRAME, SET);
mSeeking = NO_SEEK;
- mSeekNotificationSent = false;
if (mDecryptHandle != NULL) {
mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
@@ -1370,7 +1592,7 @@
if (mAudioPlayer != NULL && (mFlags & AUDIO_RUNNING)) {
mAudioPlayer->pause();
- mFlags &= ~AUDIO_RUNNING;
+ modifyFlags(AUDIO_RUNNING, CLEAR);
}
mAudioSource->pause();
}
@@ -1419,7 +1641,7 @@
startAudioPlayer_l();
}
- mFlags |= VIDEO_AT_EOS;
+ modifyFlags(VIDEO_AT_EOS, SET);
postStreamDoneEvent_l(err);
return;
}
@@ -1435,11 +1657,18 @@
break;
}
+
+ {
+ Mutex::Autolock autoLock(mStatsLock);
+ ++mStats.mNumVideoFramesDecoded;
+ }
}
int64_t timeUs;
CHECK(mVideoBuffer->meta_data()->findInt64(kKeyTime, &timeUs));
+ mLastVideoTimeUs = timeUs;
+
if (mSeeking == SEEK_VIDEO_ONLY) {
if (mSeekTimeUs > timeUs) {
LOGI("XXX mSeekTimeUs = %lld us, timeUs = %lld us",
@@ -1458,16 +1687,20 @@
if (mAudioPlayer != NULL && !(mFlags & (AUDIO_RUNNING | SEEK_PREVIEW))) {
status_t err = startAudioPlayer_l();
if (err != OK) {
- LOGE("Startung the audio player failed w/ err %d", err);
+ LOGE("Starting the audio player failed w/ err %d", err);
return;
}
}
+ if ((mFlags & TEXTPLAYER_STARTED) && !(mFlags & (TEXT_RUNNING | SEEK_PREVIEW))) {
+ mTextPlayer->resume();
+ modifyFlags(TEXT_RUNNING, SET);
+ }
+
TimeSource *ts = (mFlags & AUDIO_AT_EOS) ? &mSystemTimeSource : mTimeSource;
if (mFlags & FIRST_FRAME) {
- mFlags &= ~FIRST_FRAME;
- mSinceLastDropped = 0;
+ modifyFlags(FIRST_FRAME, CLEAR);
mTimeSourceDeltaUs = ts->getRealTimeUs() - timeUs;
}
@@ -1514,17 +1747,18 @@
if (latenessUs > 40000) {
// We're more than 40ms late.
- LOGV("we're late by %lld us (%.2f secs)", latenessUs, latenessUs / 1E6);
- if ( mSinceLastDropped > FRAME_DROP_FREQ)
- {
- LOGV("we're late by %lld us (%.2f secs) dropping one after %d frames", latenessUs, latenessUs / 1E6, mSinceLastDropped);
- mSinceLastDropped = 0;
- mVideoBuffer->release();
- mVideoBuffer = NULL;
+ LOGV("we're late by %lld us (%.2f secs), dropping frame",
+ latenessUs, latenessUs / 1E6);
+ mVideoBuffer->release();
+ mVideoBuffer = NULL;
- postVideoEvent_l();
- return;
+ {
+ Mutex::Autolock autoLock(mStatsLock);
+ ++mStats.mNumVideoFramesDropped;
}
+
+ postVideoEvent_l();
+ return;
}
if (latenessUs < -10000) {
@@ -1542,7 +1776,6 @@
}
if (mVideoRenderer != NULL) {
- mSinceLastDropped++;
mVideoRenderer->render(mVideoBuffer);
}
@@ -1550,7 +1783,7 @@
mVideoBuffer = NULL;
if (wasSeeking != NO_SEEK && (mFlags & SEEK_PREVIEW)) {
- mFlags &= ~SEEK_PREVIEW;
+ modifyFlags(SEEK_PREVIEW, CLEAR);
return;
}
@@ -1592,12 +1825,12 @@
mQueue.postEventWithDelay(mVideoLagEvent, 1000000ll);
}
-void AwesomePlayer::postCheckAudioStatusEvent_l() {
+void AwesomePlayer::postCheckAudioStatusEvent_l(int64_t delayUs) {
if (mAudioStatusEventPending) {
return;
}
mAudioStatusEventPending = true;
- mQueue.postEvent(mCheckAudioStatusEvent);
+ mQueue.postEventWithDelay(mCheckAudioStatusEvent, delayUs);
}
void AwesomePlayer::onCheckAudioStatus() {
@@ -1624,8 +1857,8 @@
status_t finalStatus;
if (mWatchForAudioEOS && mAudioPlayer->reachedEOS(&finalStatus)) {
mWatchForAudioEOS = false;
- mFlags |= AUDIO_AT_EOS;
- mFlags |= FIRST_FRAME;
+ modifyFlags(AUDIO_AT_EOS, SET);
+ modifyFlags(FIRST_FRAME, SET);
postStreamDoneEvent_l(finalStatus);
}
}
@@ -1679,7 +1912,7 @@
mQueueStarted = true;
}
- mFlags |= PREPARING;
+ modifyFlags(PREPARING, SET);
mAsyncPrepareEvent = new AwesomeEvent(
this, &AwesomePlayer::onPrepareAsyncEvent);
@@ -1704,8 +1937,14 @@
if (!strncasecmp("http://", mUri.string(), 7)
|| !strncasecmp("https://", mUri.string(), 8)
|| isWidevineStreaming) {
- mConnectingDataSource = new NuHTTPDataSource(
- (mFlags & INCOGNITO) ? NuHTTPDataSource::kFlagIncognito : 0);
+ mConnectingDataSource = HTTPBase::Create(
+ (mFlags & INCOGNITO)
+ ? HTTPBase::kFlagIncognito
+ : 0);
+
+ if (mUIDValid) {
+ mConnectingDataSource->setUID(mUID);
+ }
mLock.unlock();
status_t err = mConnectingDataSource->connect(mUri, &mUriHeaders);
@@ -1736,34 +1975,48 @@
mConnectingDataSource.clear();
- if (mCachedSource != NULL) {
+
+ String8 contentType = dataSource->getMIMEType();
+
+ if (strncasecmp(contentType.string(), "audio/", 6)) {
+ // We're not doing this for streams that appear to be audio-only
+ // streams to ensure that even low bandwidth streams start
+ // playing back fairly instantly.
+
// We're going to prefill the cache before trying to instantiate
// the extractor below, as the latter is an operation that otherwise
// could block on the datasource for a significant amount of time.
// During that time we'd be unable to abort the preparation phase
// without this prefill.
+ if (mCachedSource != NULL) {
+ // We're going to prefill the cache before trying to instantiate
+ // the extractor below, as the latter is an operation that otherwise
+ // could block on the datasource for a significant amount of time.
+ // During that time we'd be unable to abort the preparation phase
+ // without this prefill.
- mLock.unlock();
+ mLock.unlock();
- for (;;) {
- status_t finalStatus;
- size_t cachedDataRemaining =
- mCachedSource->approxDataRemaining(&finalStatus);
+ for (;;) {
+ status_t finalStatus;
+ size_t cachedDataRemaining =
+ mCachedSource->approxDataRemaining(&finalStatus);
- if (finalStatus != OK || cachedDataRemaining >= kHighWaterMarkBytes
- || (mFlags & PREPARE_CANCELLED)) {
- break;
+ if (finalStatus != OK || cachedDataRemaining >= kHighWaterMarkBytes
+ || (mFlags & PREPARE_CANCELLED)) {
+ break;
+ }
+
+ usleep(200000);
}
- usleep(200000);
+ mLock.lock();
}
- mLock.lock();
- }
-
- if (mFlags & PREPARE_CANCELLED) {
- LOGI("Prepare cancelled while waiting for initial cache fill.");
- return UNKNOWN_ERROR;
+ if (mFlags & PREPARE_CANCELLED) {
+ LOGI("Prepare cancelled while waiting for initial cache fill.");
+ return UNKNOWN_ERROR;
+ }
}
} else if (!strncasecmp("rtsp://", mUri.string(), 7)) {
if (mLooper == NULL) {
@@ -1774,6 +2027,10 @@
mRTSPController = new ARTSPController(mLooper);
mConnectingRTSPController = mRTSPController;
+ if (mUIDValid) {
+ mConnectingRTSPController->setUID(mUID);
+ }
+
mLock.unlock();
status_t err = mRTSPController->connect(mUri.string());
mLock.lock();
@@ -1822,7 +2079,8 @@
}
}
- dataSource->getDrmInfo(&mDecryptHandle, &mDrmManagerClient);
+ dataSource->getDrmInfo(mDecryptHandle, &mDrmManagerClient);
+
if (mDecryptHandle != NULL) {
CHECK(mDrmManagerClient);
if (RightsStatus::RIGHTS_VALID != mDecryptHandle->status) {
@@ -1849,7 +2107,7 @@
}
mPrepareResult = err;
- mFlags &= ~(PREPARING|PREPARE_CANCELLED|PREPARING_CONNECTED);
+ modifyFlags((PREPARING|PREPARE_CANCELLED|PREPARING_CONNECTED), CLEAR);
mAsyncPrepareEvent = NULL;
mPreparedCondition.broadcast();
}
@@ -1897,7 +2155,7 @@
}
}
- mFlags |= PREPARING_CONNECTED;
+ modifyFlags(PREPARING_CONNECTED, SET);
if (isStreamingHTTP() || mRTSPController != NULL) {
postBufferingEvent_l();
@@ -1918,8 +2176,8 @@
}
mPrepareResult = OK;
- mFlags &= ~(PREPARING|PREPARE_CANCELLED|PREPARING_CONNECTED);
- mFlags |= PREPARED;
+ modifyFlags((PREPARING|PREPARE_CANCELLED|PREPARING_CONNECTED), CLEAR);
+ modifyFlags(PREPARED, SET);
mAsyncPrepareEvent = NULL;
mPreparedCondition.broadcast();
}
@@ -1928,16 +2186,149 @@
return mExtractorFlags;
}
-void AwesomePlayer::postAudioEOS() {
- postCheckAudioStatusEvent_l();
+void AwesomePlayer::postAudioEOS(int64_t delayUs) {
+ Mutex::Autolock autoLock(mLock);
+ postCheckAudioStatusEvent_l(delayUs);
}
void AwesomePlayer::postAudioSeekComplete() {
- postCheckAudioStatusEvent_l();
+ Mutex::Autolock autoLock(mLock);
+ postAudioSeekComplete_l();
+}
+
+void AwesomePlayer::postAudioSeekComplete_l() {
+ postCheckAudioStatusEvent_l(0 /* delayUs */);
+}
+
+status_t AwesomePlayer::setParameter(int key, const Parcel &request) {
+ switch (key) {
+ case KEY_PARAMETER_TIMED_TEXT_TRACK_INDEX:
+ {
+ Mutex::Autolock autoLock(mTimedTextLock);
+ return setTimedTextTrackIndex(request.readInt32());
+ }
+ case KEY_PARAMETER_TIMED_TEXT_ADD_OUT_OF_BAND_SOURCE:
+ {
+ Mutex::Autolock autoLock(mTimedTextLock);
+ if (mTextPlayer == NULL) {
+ mTextPlayer = new TimedTextPlayer(this, mListener, &mQueue);
+ }
+
+ return mTextPlayer->setParameter(key, request);
+ }
+ case KEY_PARAMETER_CACHE_STAT_COLLECT_FREQ_MS:
+ {
+ return setCacheStatCollectFreq(request);
+ }
+ default:
+ {
+ return ERROR_UNSUPPORTED;
+ }
+ }
+}
+
+status_t AwesomePlayer::setCacheStatCollectFreq(const Parcel &request) {
+ if (mCachedSource != NULL) {
+ int32_t freqMs = request.readInt32();
+ LOGD("Request to keep cache stats in the past %d ms",
+ freqMs);
+ return mCachedSource->setCacheStatCollectFreq(freqMs);
+ }
+ return ERROR_UNSUPPORTED;
+}
+
+status_t AwesomePlayer::getParameter(int key, Parcel *reply) {
+ switch (key) {
+ case KEY_PARAMETER_AUDIO_CHANNEL_COUNT:
+ {
+ int32_t channelCount;
+ if (mAudioTrack == 0 ||
+ !mAudioTrack->getFormat()->findInt32(kKeyChannelCount, &channelCount)) {
+ channelCount = 0;
+ }
+ reply->writeInt32(channelCount);
+ }
+ return OK;
+ default:
+ {
+ return ERROR_UNSUPPORTED;
+ }
+ }
}
bool AwesomePlayer::isStreamingHTTP() const {
return mCachedSource != NULL || mWVMExtractor != NULL;
}
+status_t AwesomePlayer::dump(int fd, const Vector<String16> &args) const {
+ Mutex::Autolock autoLock(mStatsLock);
+
+ FILE *out = fdopen(dup(fd), "w");
+
+ fprintf(out, " AwesomePlayer\n");
+ if (mStats.mFd < 0) {
+ fprintf(out, " URI(%s)", mStats.mURI.string());
+ } else {
+ fprintf(out, " fd(%d)", mStats.mFd);
+ }
+
+ fprintf(out, ", flags(0x%08x)", mStats.mFlags);
+
+ if (mStats.mBitrate >= 0) {
+ fprintf(out, ", bitrate(%lld bps)", mStats.mBitrate);
+ }
+
+ fprintf(out, "\n");
+
+ for (size_t i = 0; i < mStats.mTracks.size(); ++i) {
+ const TrackStat &stat = mStats.mTracks.itemAt(i);
+
+ fprintf(out, " Track %d\n", i + 1);
+ fprintf(out, " MIME(%s)", stat.mMIME.string());
+
+ if (!stat.mDecoderName.isEmpty()) {
+ fprintf(out, ", decoder(%s)", stat.mDecoderName.string());
+ }
+
+ fprintf(out, "\n");
+
+ if ((ssize_t)i == mStats.mVideoTrackIndex) {
+ fprintf(out,
+ " videoDimensions(%d x %d), "
+ "numVideoFramesDecoded(%lld), "
+ "numVideoFramesDropped(%lld)\n",
+ mStats.mVideoWidth,
+ mStats.mVideoHeight,
+ mStats.mNumVideoFramesDecoded,
+ mStats.mNumVideoFramesDropped);
+ }
+ }
+
+ fclose(out);
+ out = NULL;
+
+ return OK;
+}
+
+void AwesomePlayer::modifyFlags(unsigned value, FlagMode mode) {
+ switch (mode) {
+ case SET:
+ mFlags |= value;
+ break;
+ case CLEAR:
+ mFlags &= ~value;
+ break;
+ case ASSIGN:
+ mFlags = value;
+ break;
+ default:
+ TRESPASS();
+ }
+
+ {
+ Mutex::Autolock autoLock(mStatsLock);
+ mStats.mFlags = mFlags;
+ }
+}
+
} // namespace android
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
old mode 100644
new mode 100755
index 8a24bc4..ea8eaa4
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -37,7 +37,8 @@
CameraSourceListener(const sp<CameraSource> &source);
virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2);
- virtual void postData(int32_t msgType, const sp<IMemory> &dataPtr);
+ virtual void postData(int32_t msgType, const sp<IMemory> &dataPtr,
+ camera_frame_metadata_t *metadata);
virtual void postDataTimestamp(
nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);
@@ -63,7 +64,8 @@
LOGV("notify(%d, %d, %d)", msgType, ext1, ext2);
}
-void CameraSourceListener::postData(int32_t msgType, const sp<IMemory> &dataPtr) {
+void CameraSourceListener::postData(int32_t msgType, const sp<IMemory> &dataPtr,
+ camera_frame_metadata_t *metadata) {
LOGV("postData(%d, ptr:%p, size:%d)",
msgType, dataPtr->pointer(), dataPtr->size());
@@ -103,6 +105,10 @@
return OMX_COLOR_Format16bitRGB565;
}
+ if (!strcmp(colorFormat, "OMX_TI_COLOR_FormatYUV420PackedSemiPlanar")) {
+ return OMX_TI_COLOR_FormatYUV420PackedSemiPlanar;
+ }
+
LOGE("Uknown color format (%s), please add it to "
"CameraSource::getColorFormat", colorFormat);
@@ -115,19 +121,20 @@
size.height = -1;
sp<ICamera> camera;
- return new CameraSource(camera, 0, size, -1, NULL, false);
+ return new CameraSource(camera, NULL, 0, size, -1, NULL, false);
}
// static
CameraSource *CameraSource::CreateFromCamera(
const sp<ICamera>& camera,
+ const sp<ICameraRecordingProxy>& proxy,
int32_t cameraId,
Size videoSize,
int32_t frameRate,
const sp<Surface>& surface,
bool storeMetaDataInVideoBuffers) {
- CameraSource *source = new CameraSource(camera, cameraId,
+ CameraSource *source = new CameraSource(camera, proxy, cameraId,
videoSize, frameRate, surface,
storeMetaDataInVideoBuffers);
return source;
@@ -135,6 +142,7 @@
CameraSource::CameraSource(
const sp<ICamera>& camera,
+ const sp<ICameraRecordingProxy>& proxy,
int32_t cameraId,
Size videoSize,
int32_t frameRate,
@@ -153,13 +161,13 @@
mNumGlitches(0),
mGlitchDurationThresholdUs(200000),
mCollectStats(false) {
-
mVideoSize.width = -1;
mVideoSize.height = -1;
- mInitCheck = init(camera, cameraId,
+ mInitCheck = init(camera, proxy, cameraId,
videoSize, frameRate,
storeMetaDataInVideoBuffers);
+ if (mInitCheck != OK) releaseCamera();
}
status_t CameraSource::initCheck() const {
@@ -167,24 +175,29 @@
}
status_t CameraSource::isCameraAvailable(
- const sp<ICamera>& camera, int32_t cameraId) {
+ const sp<ICamera>& camera, const sp<ICameraRecordingProxy>& proxy,
+ int32_t cameraId) {
if (camera == 0) {
mCamera = Camera::connect(cameraId);
+ if (mCamera == 0) return -EBUSY;
mCameraFlags &= ~FLAGS_HOT_CAMERA;
} else {
+ // We get the proxy from Camera, not ICamera. We need to get the proxy
+ // to the remote Camera owned by the application. Here mCamera is a
+ // local Camera object created by us. We cannot use the proxy from
+ // mCamera here.
mCamera = Camera::create(camera);
+ if (mCamera == 0) return -EBUSY;
+ mCameraRecordingProxy = proxy;
mCameraFlags |= FLAGS_HOT_CAMERA;
+ mDeathNotifier = new DeathNotifier();
+ // isBinderAlive needs linkToDeath to work.
+ mCameraRecordingProxy->asBinder()->linkToDeath(mDeathNotifier);
}
- // Is camera available?
- if (mCamera == 0) {
- LOGE("Camera connection could not be established.");
- return -EBUSY;
- }
- if (!(mCameraFlags & FLAGS_HOT_CAMERA)) {
- mCamera->lock();
- }
+ mCamera->lock();
+
return OK;
}
@@ -278,7 +291,7 @@
CameraParameters* params,
int32_t width, int32_t height,
int32_t frameRate) {
-
+ LOGV("configureCamera");
Vector<Size> sizes;
bool isSetVideoSizeSupportedByCamera = true;
getSupportedVideoSizes(*params, &isSetVideoSizeSupportedByCamera, sizes);
@@ -286,7 +299,6 @@
if (width != -1 && height != -1) {
if (!isVideoSizeSupported(width, height, sizes)) {
LOGE("Video dimension (%dx%d) is unsupported", width, height);
- releaseCamera();
return BAD_VALUE;
}
if (isSetVideoSizeSupportedByCamera) {
@@ -300,7 +312,6 @@
// If one and only one of the width and height is -1
// we reject such a request.
LOGE("Requested video size (%dx%d) is not supported", width, height);
- releaseCamera();
return BAD_VALUE;
} else { // width == -1 && height == -1
// Do not configure the camera.
@@ -318,7 +329,6 @@
if (strstr(supportedFrameRates, buf) == NULL) {
LOGE("Requested frame rate (%d) is not supported: %s",
frameRate, supportedFrameRates);
- releaseCamera();
return BAD_VALUE;
}
@@ -357,6 +367,7 @@
const CameraParameters& params,
int32_t width, int32_t height) {
+ LOGV("checkVideoSize");
// The actual video size is the same as the preview size
// if the camera hal does not support separate video and
// preview output. In this case, we retrieve the video
@@ -408,6 +419,7 @@
const CameraParameters& params,
int32_t frameRate) {
+ LOGV("checkFrameRate");
int32_t frameRateActual = params.getPreviewFrameRate();
if (frameRateActual < 0) {
LOGE("Failed to retrieve preview frame rate (%d)", frameRateActual);
@@ -447,15 +459,34 @@
*/
status_t CameraSource::init(
const sp<ICamera>& camera,
+ const sp<ICameraRecordingProxy>& proxy,
int32_t cameraId,
Size videoSize,
int32_t frameRate,
bool storeMetaDataInVideoBuffers) {
+ LOGV("init");
status_t err = OK;
int64_t token = IPCThreadState::self()->clearCallingIdentity();
+ err = initWithCameraAccess(camera, proxy, cameraId,
+ videoSize, frameRate,
+ storeMetaDataInVideoBuffers);
+ IPCThreadState::self()->restoreCallingIdentity(token);
+ return err;
+}
- if ((err = isCameraAvailable(camera, cameraId)) != OK) {
+status_t CameraSource::initWithCameraAccess(
+ const sp<ICamera>& camera,
+ const sp<ICameraRecordingProxy>& proxy,
+ int32_t cameraId,
+ Size videoSize,
+ int32_t frameRate,
+ bool storeMetaDataInVideoBuffers) {
+ LOGV("initWithCameraAccess");
+ status_t err = OK;
+
+ if ((err = isCameraAvailable(camera, proxy, cameraId)) != OK) {
+ LOGE("Camera connection could not be established.");
return err;
}
CameraParameters params(mCamera->getParameters());
@@ -494,8 +525,6 @@
}
}
- IPCThreadState::self()->restoreCallingIdentity(token);
-
int64_t glitchDurationUs = (1000000LL / mVideoFrameRate);
if (glitchDurationUs > mGlitchDurationThresholdUs) {
mGlitchDurationThresholdUs = glitchDurationUs;
@@ -517,15 +546,34 @@
CameraSource::~CameraSource() {
if (mStarted) {
stop();
+ } else if (mInitCheck == OK) {
+ // Camera is initialized but because start() is never called,
+ // the lock on Camera is never released(). This makes sure
+ // Camera's lock is released in this case.
+ releaseCamera();
}
}
void CameraSource::startCameraRecording() {
- CHECK_EQ(OK, mCamera->startRecording());
- CHECK(mCamera->recordingEnabled());
+ LOGV("startCameraRecording");
+ // Reset the identity to the current thread because media server owns the
+ // camera and recording is started by the applications. The applications
+ // will connect to the camera in ICameraRecordingProxy::startRecording.
+ int64_t token = IPCThreadState::self()->clearCallingIdentity();
+ if (mCameraFlags & FLAGS_HOT_CAMERA) {
+ mCamera->unlock();
+ mCamera.clear();
+ CHECK_EQ(OK, mCameraRecordingProxy->startRecording(new ProxyListener(this)));
+ } else {
+ mCamera->setListener(new CameraSourceListener(this));
+ mCamera->startRecording();
+ CHECK(mCamera->recordingEnabled());
+ }
+ IPCThreadState::self()->restoreCallingIdentity(token);
}
status_t CameraSource::start(MetaData *meta) {
+ LOGV("start");
CHECK(!mStarted);
if (mInitCheck != OK) {
LOGE("CameraSource is not initialized yet");
@@ -544,31 +592,40 @@
mStartTimeUs = startTimeUs;
}
- // Call setListener first before calling startCameraRecording()
- // to avoid recording frames being dropped.
- int64_t token = IPCThreadState::self()->clearCallingIdentity();
- mCamera->setListener(new CameraSourceListener(this));
startCameraRecording();
- IPCThreadState::self()->restoreCallingIdentity(token);
mStarted = true;
return OK;
}
void CameraSource::stopCameraRecording() {
- mCamera->setListener(NULL);
- mCamera->stopRecording();
+ LOGV("stopCameraRecording");
+ if (mCameraFlags & FLAGS_HOT_CAMERA) {
+ mCameraRecordingProxy->stopRecording();
+ } else {
+ mCamera->setListener(NULL);
+ mCamera->stopRecording();
+ }
}
void CameraSource::releaseCamera() {
LOGV("releaseCamera");
- if ((mCameraFlags & FLAGS_HOT_CAMERA) == 0) {
- LOGV("Camera was cold when we started, stopping preview");
- mCamera->stopPreview();
+ if (mCamera != 0) {
+ int64_t token = IPCThreadState::self()->clearCallingIdentity();
+ if ((mCameraFlags & FLAGS_HOT_CAMERA) == 0) {
+ LOGV("Camera was cold when we started, stopping preview");
+ mCamera->stopPreview();
+ mCamera->disconnect();
+ }
+ mCamera->unlock();
+ mCamera.clear();
+ mCamera = 0;
+ IPCThreadState::self()->restoreCallingIdentity(token);
}
- mCamera->unlock();
- mCamera.clear();
- mCamera = 0;
+ if (mCameraRecordingProxy != 0) {
+ mCameraRecordingProxy->asBinder()->unlinkToDeath(mDeathNotifier);
+ mCameraRecordingProxy.clear();
+ }
mCameraFlags = 0;
}
@@ -578,7 +635,6 @@
mStarted = false;
mFrameAvailableCondition.signal();
- int64_t token = IPCThreadState::self()->clearCallingIdentity();
releaseQueuedFrames();
while (!mFramesBeingEncoded.empty()) {
if (NO_ERROR !=
@@ -589,7 +645,6 @@
}
stopCameraRecording();
releaseCamera();
- IPCThreadState::self()->restoreCallingIdentity(token);
if (mCollectStats) {
LOGI("Frames received/encoded/dropped: %d/%d/%d in %lld us",
@@ -607,8 +662,13 @@
}
void CameraSource::releaseRecordingFrame(const sp<IMemory>& frame) {
- if (mCamera != NULL) {
+ LOGV("releaseRecordingFrame");
+ if (mCameraRecordingProxy != NULL) {
+ mCameraRecordingProxy->releaseRecordingFrame(frame);
+ } else {
+ int64_t token = IPCThreadState::self()->clearCallingIdentity();
mCamera->releaseRecordingFrame(frame);
+ IPCThreadState::self()->restoreCallingIdentity(token);
}
}
@@ -627,9 +687,7 @@
}
void CameraSource::releaseOneRecordingFrame(const sp<IMemory>& frame) {
- int64_t token = IPCThreadState::self()->clearCallingIdentity();
releaseRecordingFrame(frame);
- IPCThreadState::self()->restoreCallingIdentity(token);
}
void CameraSource::signalBufferReturned(MediaBuffer *buffer) {
@@ -669,7 +727,12 @@
Mutex::Autolock autoLock(mLock);
while (mStarted && mFramesReceived.empty()) {
if (NO_ERROR !=
- mFrameAvailableCondition.waitRelative(mLock, 3000000000LL)) {
+ mFrameAvailableCondition.waitRelative(mLock, 1000000000LL)) {
+ if (mCameraRecordingProxy != 0 &&
+ !mCameraRecordingProxy->asBinder()->isBinderAlive()) {
+ LOGW("camera recording proxy is gone");
+ return ERROR_END_OF_STREAM;
+ }
LOGW("Timed out waiting for incoming camera video frames: %lld us",
mLastFrameTimestampUs);
}
@@ -701,12 +764,11 @@
return;
}
- if (mNumFramesReceived > 0 &&
- timestampUs - mLastFrameTimestampUs > mGlitchDurationThresholdUs) {
- if (mNumGlitches % 10 == 0) { // Don't spam the log
- LOGV("Long delay detected in video recording");
+ if (mNumFramesReceived > 0) {
+ CHECK(timestampUs > mLastFrameTimestampUs);
+ if (timestampUs - mLastFrameTimestampUs > mGlitchDurationThresholdUs) {
+ ++mNumGlitches;
}
- ++mNumGlitches;
}
// May need to skip frame or modify timestamp. Currently implemented
@@ -732,6 +794,7 @@
}
++mNumFramesReceived;
+ CHECK(data != NULL && data->size() > 0);
mFramesReceived.push_back(data);
int64_t timeUs = mStartTimeUs + (timestampUs - mFirstFrameTimeUs);
mFrameTimes.push_back(timeUs);
@@ -740,31 +803,22 @@
mFrameAvailableCondition.signal();
}
-size_t CameraSource::getNumberOfVideoBuffers() const {
- LOGV("getNumberOfVideoBuffers");
- size_t nBuffers = 0;
- int64_t token = IPCThreadState::self()->clearCallingIdentity();
- if (mInitCheck == OK && mCamera != 0) {
- nBuffers = mCamera->getNumberOfVideoBuffers();
- }
- IPCThreadState::self()->restoreCallingIdentity(token);
- return nBuffers;
-}
-
-sp<IMemory> CameraSource::getVideoBuffer(size_t index) const {
- LOGV("getVideoBuffer: %d", index);
- sp<IMemory> buffer = 0;
- int64_t token = IPCThreadState::self()->clearCallingIdentity();
- if (mInitCheck == OK && mCamera != 0) {
- buffer = mCamera->getVideoBuffer(index);
- }
- IPCThreadState::self()->restoreCallingIdentity(token);
- return buffer;
-}
-
bool CameraSource::isMetaDataStoredInVideoBuffers() const {
LOGV("isMetaDataStoredInVideoBuffers");
return mIsMetaDataStoredInVideoBuffers;
}
+CameraSource::ProxyListener::ProxyListener(const sp<CameraSource>& source) {
+ mSource = source;
+}
+
+void CameraSource::ProxyListener::dataCallbackTimestamp(
+ nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) {
+ mSource->dataCallbackTimestamp(timestamp / 1000, msgType, dataPtr);
+}
+
+void CameraSource::DeathNotifier::binderDied(const wp<IBinder>& who) {
+ LOGI("Camera recording proxy died");
+}
+
} // namespace android
diff --git a/media/libstagefright/CameraSourceTimeLapse.cpp b/media/libstagefright/CameraSourceTimeLapse.cpp
index 3689557..1ba79e5 100644
--- a/media/libstagefright/CameraSourceTimeLapse.cpp
+++ b/media/libstagefright/CameraSourceTimeLapse.cpp
@@ -24,21 +24,17 @@
#include <media/stagefright/CameraSourceTimeLapse.h>
#include <media/stagefright/MediaDebug.h>
#include <media/stagefright/MetaData.h>
-#include <media/stagefright/YUVImage.h>
-#include <media/stagefright/YUVCanvas.h>
#include <camera/Camera.h>
#include <camera/CameraParameters.h>
-#include <ui/Rect.h>
#include <utils/String8.h>
#include <utils/Vector.h>
-#include "OMX_Video.h"
-#include <limits.h>
namespace android {
// static
CameraSourceTimeLapse *CameraSourceTimeLapse::CreateFromCamera(
const sp<ICamera> &camera,
+ const sp<ICameraRecordingProxy> &proxy,
int32_t cameraId,
Size videoSize,
int32_t videoFrameRate,
@@ -46,7 +42,7 @@
int64_t timeBetweenTimeLapseFrameCaptureUs) {
CameraSourceTimeLapse *source = new
- CameraSourceTimeLapse(camera, cameraId,
+ CameraSourceTimeLapse(camera, proxy, cameraId,
videoSize, videoFrameRate, surface,
timeBetweenTimeLapseFrameCaptureUs);
@@ -61,31 +57,26 @@
CameraSourceTimeLapse::CameraSourceTimeLapse(
const sp<ICamera>& camera,
+ const sp<ICameraRecordingProxy>& proxy,
int32_t cameraId,
Size videoSize,
int32_t videoFrameRate,
const sp<Surface>& surface,
int64_t timeBetweenTimeLapseFrameCaptureUs)
- : CameraSource(camera, cameraId, videoSize, videoFrameRate, surface, true),
+ : CameraSource(camera, proxy, cameraId, videoSize, videoFrameRate, surface, true),
mTimeBetweenTimeLapseFrameCaptureUs(timeBetweenTimeLapseFrameCaptureUs),
mTimeBetweenTimeLapseVideoFramesUs(1E6/videoFrameRate),
mLastTimeLapseFrameRealTimestampUs(0),
mSkipCurrentFrame(false) {
- LOGD("starting time lapse mode: %lld us", mTimeBetweenTimeLapseFrameCaptureUs);
+ LOGD("starting time lapse mode: %lld us",
+ mTimeBetweenTimeLapseFrameCaptureUs);
+
mVideoWidth = videoSize.width;
mVideoHeight = videoSize.height;
- if (trySettingVideoSize(videoSize.width, videoSize.height)) {
- mUseStillCameraForTimeLapse = false;
- } else {
- // TODO: Add a check to see that mTimeBetweenTimeLapseFrameCaptureUs is greater
- // than the fastest rate at which the still camera can take pictures.
- mUseStillCameraForTimeLapse = true;
- CHECK(setPictureSizeToClosestSupported(videoSize.width, videoSize.height));
- mNeedCropping = computeCropRectangleOffset();
- mMeta->setInt32(kKeyWidth, videoSize.width);
- mMeta->setInt32(kKeyHeight, videoSize.height);
+ if (!trySettingVideoSize(videoSize.width, videoSize.height)) {
+ mInitCheck = NO_INIT;
}
// Initialize quick stop variables.
@@ -99,24 +90,22 @@
}
void CameraSourceTimeLapse::startQuickReadReturns() {
+ LOGV("startQuickReadReturns");
Mutex::Autolock autoLock(mQuickStopLock);
- LOGV("Enabling quick read returns");
// Enable quick stop mode.
mQuickStop = true;
- if (mUseStillCameraForTimeLapse) {
- // wake up the thread right away.
- mTakePictureCondition.signal();
- } else {
- // Force dataCallbackTimestamp() coming from the video camera to not skip the
- // next frame as we want read() to get a get a frame right away.
- mForceRead = true;
- }
+ // Force dataCallbackTimestamp() coming from the video camera to
+ // not skip the next frame as we want read() to get a get a frame
+ // right away.
+ mForceRead = true;
}
-bool CameraSourceTimeLapse::trySettingVideoSize(int32_t width, int32_t height) {
- LOGV("trySettingVideoSize: %dx%d", width, height);
+bool CameraSourceTimeLapse::trySettingVideoSize(
+ int32_t width, int32_t height) {
+
+ LOGV("trySettingVideoSize");
int64_t token = IPCThreadState::self()->clearCallingIdentity();
String8 s = mCamera->getParameters();
@@ -160,53 +149,8 @@
return isSuccessful;
}
-bool CameraSourceTimeLapse::setPictureSizeToClosestSupported(int32_t width, int32_t height) {
- LOGV("setPictureSizeToClosestSupported: %dx%d", width, height);
- int64_t token = IPCThreadState::self()->clearCallingIdentity();
- String8 s = mCamera->getParameters();
- IPCThreadState::self()->restoreCallingIdentity(token);
-
- CameraParameters params(s);
- Vector<Size> supportedSizes;
- params.getSupportedPictureSizes(supportedSizes);
-
- int32_t minPictureSize = INT_MAX;
- for (uint32_t i = 0; i < supportedSizes.size(); ++i) {
- int32_t pictureWidth = supportedSizes[i].width;
- int32_t pictureHeight = supportedSizes[i].height;
-
- if ((pictureWidth >= width) && (pictureHeight >= height)) {
- int32_t pictureSize = pictureWidth*pictureHeight;
- if (pictureSize < minPictureSize) {
- minPictureSize = pictureSize;
- mPictureWidth = pictureWidth;
- mPictureHeight = pictureHeight;
- }
- }
- }
- LOGV("Picture size = (%d, %d)", mPictureWidth, mPictureHeight);
- return (minPictureSize != INT_MAX);
-}
-
-bool CameraSourceTimeLapse::computeCropRectangleOffset() {
- if ((mPictureWidth == mVideoWidth) && (mPictureHeight == mVideoHeight)) {
- return false;
- }
-
- CHECK((mPictureWidth > mVideoWidth) && (mPictureHeight > mVideoHeight));
-
- int32_t widthDifference = mPictureWidth - mVideoWidth;
- int32_t heightDifference = mPictureHeight - mVideoHeight;
-
- mCropRectStartX = widthDifference/2;
- mCropRectStartY = heightDifference/2;
-
- LOGV("setting crop rectangle offset to (%d, %d)", mCropRectStartX, mCropRectStartY);
-
- return true;
-}
-
void CameraSourceTimeLapse::signalBufferReturned(MediaBuffer* buffer) {
+ LOGV("signalBufferReturned");
Mutex::Autolock autoLock(mQuickStopLock);
if (mQuickStop && (buffer == mLastReadBufferCopy)) {
buffer->setObserver(NULL);
@@ -216,7 +160,12 @@
}
}
-void createMediaBufferCopy(const MediaBuffer& sourceBuffer, int64_t frameTime, MediaBuffer **newBuffer) {
+void createMediaBufferCopy(
+ const MediaBuffer& sourceBuffer,
+ int64_t frameTime,
+ MediaBuffer **newBuffer) {
+
+ LOGV("createMediaBufferCopy");
size_t sourceSize = sourceBuffer.size();
void* sourcePointer = sourceBuffer.data();
@@ -227,6 +176,7 @@
}
void CameraSourceTimeLapse::fillLastReadBufferCopy(MediaBuffer& sourceBuffer) {
+ LOGV("fillLastReadBufferCopy");
int64_t frameTime;
CHECK(sourceBuffer.meta_data()->findInt64(kKeyTime, &frameTime));
createMediaBufferCopy(sourceBuffer, frameTime, &mLastReadBufferCopy);
@@ -236,11 +186,12 @@
status_t CameraSourceTimeLapse::read(
MediaBuffer **buffer, const ReadOptions *options) {
+ LOGV("read");
if (mLastReadBufferCopy == NULL) {
mLastReadStatus = CameraSource::read(buffer, options);
- // mQuickStop may have turned to true while read was blocked. Make a copy of
- // the buffer in that case.
+ // mQuickStop may have turned to true while read was blocked.
+ // Make a copy of the buffer in that case.
Mutex::Autolock autoLock(mQuickStopLock);
if (mQuickStop && *buffer) {
fillLastReadBufferCopy(**buffer);
@@ -253,107 +204,19 @@
}
}
-// static
-void *CameraSourceTimeLapse::ThreadTimeLapseWrapper(void *me) {
- CameraSourceTimeLapse *source = static_cast<CameraSourceTimeLapse *>(me);
- source->threadTimeLapseEntry();
- return NULL;
-}
-
-void CameraSourceTimeLapse::threadTimeLapseEntry() {
- while (mStarted) {
- {
- Mutex::Autolock autoLock(mCameraIdleLock);
- if (!mCameraIdle) {
- mCameraIdleCondition.wait(mCameraIdleLock);
- }
- CHECK(mCameraIdle);
- mCameraIdle = false;
- }
-
- // Even if mQuickStop == true we need to take one more picture
- // as a read() may be blocked, waiting for a frame to get available.
- // After this takePicture, if mQuickStop == true, we can safely exit
- // this thread as read() will make a copy of this last frame and keep
- // returning it in the quick stop mode.
- Mutex::Autolock autoLock(mQuickStopLock);
- CHECK_EQ(OK, mCamera->takePicture(CAMERA_MSG_RAW_IMAGE));
- if (mQuickStop) {
- LOGV("threadTimeLapseEntry: Exiting due to mQuickStop = true");
- return;
- }
- mTakePictureCondition.waitRelative(mQuickStopLock,
- mTimeBetweenTimeLapseFrameCaptureUs * 1000);
- }
- LOGV("threadTimeLapseEntry: Exiting due to mStarted = false");
-}
-
-void CameraSourceTimeLapse::startCameraRecording() {
- if (mUseStillCameraForTimeLapse) {
- LOGV("start time lapse recording using still camera");
-
- int64_t token = IPCThreadState::self()->clearCallingIdentity();
- String8 s = mCamera->getParameters();
-
- CameraParameters params(s);
- params.setPictureSize(mPictureWidth, mPictureHeight);
- mCamera->setParameters(params.flatten());
- mCameraIdle = true;
- mStopWaitingForIdleCamera = false;
-
- // disable shutter sound and play the recording sound.
- mCamera->sendCommand(CAMERA_CMD_ENABLE_SHUTTER_SOUND, 0, 0);
- mCamera->sendCommand(CAMERA_CMD_PLAY_RECORDING_SOUND, 0, 0);
- IPCThreadState::self()->restoreCallingIdentity(token);
-
- // create a thread which takes pictures in a loop
- pthread_attr_t attr;
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-
- pthread_create(&mThreadTimeLapse, &attr, ThreadTimeLapseWrapper, this);
- pthread_attr_destroy(&attr);
- } else {
- LOGV("start time lapse recording using video camera");
- CHECK_EQ(OK, mCamera->startRecording());
- }
-}
-
void CameraSourceTimeLapse::stopCameraRecording() {
- if (mUseStillCameraForTimeLapse) {
- void *dummy;
- pthread_join(mThreadTimeLapse, &dummy);
-
- // Last takePicture may still be underway. Wait for the camera to get
- // idle.
- Mutex::Autolock autoLock(mCameraIdleLock);
- mStopWaitingForIdleCamera = true;
- if (!mCameraIdle) {
- mCameraIdleCondition.wait(mCameraIdleLock);
- }
- CHECK(mCameraIdle);
- mCamera->setListener(NULL);
-
- // play the recording sound.
- mCamera->sendCommand(CAMERA_CMD_PLAY_RECORDING_SOUND, 0, 0);
- } else {
- mCamera->setListener(NULL);
- mCamera->stopRecording();
- }
+ LOGV("stopCameraRecording");
+ CameraSource::stopCameraRecording();
if (mLastReadBufferCopy) {
mLastReadBufferCopy->release();
mLastReadBufferCopy = NULL;
}
}
-void CameraSourceTimeLapse::releaseRecordingFrame(const sp<IMemory>& frame) {
- if (!mUseStillCameraForTimeLapse &&
- mCamera != NULL) {
- mCamera->releaseRecordingFrame(frame);
- }
-}
+sp<IMemory> CameraSourceTimeLapse::createIMemoryCopy(
+ const sp<IMemory> &source_data) {
-sp<IMemory> CameraSourceTimeLapse::createIMemoryCopy(const sp<IMemory> &source_data) {
+ LOGV("createIMemoryCopy");
size_t source_size = source_data->size();
void* source_pointer = source_data->pointer();
@@ -363,102 +226,8 @@
return newMemory;
}
-// Allocates IMemory of final type MemoryBase with the given size.
-sp<IMemory> allocateIMemory(size_t size) {
- sp<MemoryHeapBase> newMemoryHeap = new MemoryHeapBase(size);
- sp<MemoryBase> newMemory = new MemoryBase(newMemoryHeap, 0, size);
- return newMemory;
-}
-
-// static
-void *CameraSourceTimeLapse::ThreadStartPreviewWrapper(void *me) {
- CameraSourceTimeLapse *source = static_cast<CameraSourceTimeLapse *>(me);
- source->threadStartPreview();
- return NULL;
-}
-
-void CameraSourceTimeLapse::threadStartPreview() {
- CHECK_EQ(OK, mCamera->startPreview());
- Mutex::Autolock autoLock(mCameraIdleLock);
- mCameraIdle = true;
- mCameraIdleCondition.signal();
-}
-
-void CameraSourceTimeLapse::restartPreview() {
- // Start this in a different thread, so that the dataCallback can return
- LOGV("restartPreview");
- pthread_attr_t attr;
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-
- pthread_t threadPreview;
- pthread_create(&threadPreview, &attr, ThreadStartPreviewWrapper, this);
- pthread_attr_destroy(&attr);
-}
-
-sp<IMemory> CameraSourceTimeLapse::cropYUVImage(const sp<IMemory> &source_data) {
- // find the YUV format
- int32_t srcFormat;
- CHECK(mMeta->findInt32(kKeyColorFormat, &srcFormat));
- YUVImage::YUVFormat yuvFormat;
- if (srcFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
- yuvFormat = YUVImage::YUV420SemiPlanar;
- } else {
- CHECK_EQ(srcFormat, OMX_COLOR_FormatYUV420Planar);
- yuvFormat = YUVImage::YUV420Planar;
- }
-
- // allocate memory for cropped image and setup a canvas using it.
- sp<IMemory> croppedImageMemory = allocateIMemory(
- YUVImage::bufferSize(yuvFormat, mVideoWidth, mVideoHeight));
- YUVImage yuvImageCropped(yuvFormat,
- mVideoWidth, mVideoHeight,
- (uint8_t *)croppedImageMemory->pointer());
- YUVCanvas yuvCanvasCrop(yuvImageCropped);
-
- YUVImage yuvImageSource(yuvFormat,
- mPictureWidth, mPictureHeight,
- (uint8_t *)source_data->pointer());
- yuvCanvasCrop.CopyImageRect(
- Rect(mCropRectStartX, mCropRectStartY,
- mCropRectStartX + mVideoWidth,
- mCropRectStartY + mVideoHeight),
- 0, 0,
- yuvImageSource);
-
- return croppedImageMemory;
-}
-
-void CameraSourceTimeLapse::dataCallback(int32_t msgType, const sp<IMemory> &data) {
- if (msgType == CAMERA_MSG_COMPRESSED_IMAGE) {
- // takePicture will complete after this callback, so restart preview.
- restartPreview();
- return;
- }
- if (msgType != CAMERA_MSG_RAW_IMAGE) {
- return;
- }
-
- LOGV("dataCallback for timelapse still frame");
- CHECK_EQ(true, mUseStillCameraForTimeLapse);
-
- int64_t timestampUs;
- if (mNumFramesReceived == 0) {
- timestampUs = mStartTimeUs;
- } else {
- timestampUs = mLastFrameTimestampUs + mTimeBetweenTimeLapseVideoFramesUs;
- }
-
- if (mNeedCropping) {
- sp<IMemory> croppedImageData = cropYUVImage(data);
- dataCallbackTimestamp(timestampUs, msgType, croppedImageData);
- } else {
- sp<IMemory> dataCopy = createIMemoryCopy(data);
- dataCallbackTimestamp(timestampUs, msgType, dataCopy);
- }
-}
-
bool CameraSourceTimeLapse::skipCurrentFrame(int64_t timestampUs) {
+ LOGV("skipCurrentFrame");
if (mSkipCurrentFrame) {
mSkipCurrentFrame = false;
return true;
@@ -468,71 +237,58 @@
}
bool CameraSourceTimeLapse::skipFrameAndModifyTimeStamp(int64_t *timestampUs) {
- if (!mUseStillCameraForTimeLapse) {
- if (mLastTimeLapseFrameRealTimestampUs == 0) {
- // First time lapse frame. Initialize mLastTimeLapseFrameRealTimestampUs
- // to current time (timestampUs) and save frame data.
- LOGV("dataCallbackTimestamp timelapse: initial frame");
+ LOGV("skipFrameAndModifyTimeStamp");
+ if (mLastTimeLapseFrameRealTimestampUs == 0) {
+ // First time lapse frame. Initialize mLastTimeLapseFrameRealTimestampUs
+ // to current time (timestampUs) and save frame data.
+ LOGV("dataCallbackTimestamp timelapse: initial frame");
- mLastTimeLapseFrameRealTimestampUs = *timestampUs;
+ mLastTimeLapseFrameRealTimestampUs = *timestampUs;
+ return false;
+ }
+
+ {
+ Mutex::Autolock autoLock(mQuickStopLock);
+
+ // mForceRead may be set to true by startQuickReadReturns(). In that
+ // case don't skip this frame.
+ if (mForceRead) {
+ LOGV("dataCallbackTimestamp timelapse: forced read");
+ mForceRead = false;
+ *timestampUs =
+ mLastFrameTimestampUs + mTimeBetweenTimeLapseVideoFramesUs;
return false;
}
+ }
- {
- Mutex::Autolock autoLock(mQuickStopLock);
+ // Workaround to bypass the first 2 input frames for skipping.
+ // The first 2 output frames from the encoder are: decoder specific info and
+ // the compressed video frame data for the first input video frame.
+ if (mNumFramesEncoded >= 1 && *timestampUs <
+ (mLastTimeLapseFrameRealTimestampUs + mTimeBetweenTimeLapseFrameCaptureUs)) {
+ // Skip all frames from last encoded frame until
+ // sufficient time (mTimeBetweenTimeLapseFrameCaptureUs) has passed.
+ // Tell the camera to release its recording frame and return.
+ LOGV("dataCallbackTimestamp timelapse: skipping intermediate frame");
+ return true;
+ } else {
+ // Desired frame has arrived after mTimeBetweenTimeLapseFrameCaptureUs time:
+ // - Reset mLastTimeLapseFrameRealTimestampUs to current time.
+ // - Artificially modify timestampUs to be one frame time (1/framerate) ahead
+ // of the last encoded frame's time stamp.
+ LOGV("dataCallbackTimestamp timelapse: got timelapse frame");
- // mForceRead may be set to true by startQuickReadReturns(). In that
- // case don't skip this frame.
- if (mForceRead) {
- LOGV("dataCallbackTimestamp timelapse: forced read");
- mForceRead = false;
- *timestampUs = mLastFrameTimestampUs;
- return false;
- }
- }
-
- // Workaround to bypass the first 2 input frames for skipping.
- // The first 2 output frames from the encoder are: decoder specific info and
- // the compressed video frame data for the first input video frame.
- if (mNumFramesEncoded >= 1 && *timestampUs <
- (mLastTimeLapseFrameRealTimestampUs + mTimeBetweenTimeLapseFrameCaptureUs)) {
- // Skip all frames from last encoded frame until
- // sufficient time (mTimeBetweenTimeLapseFrameCaptureUs) has passed.
- // Tell the camera to release its recording frame and return.
- LOGV("dataCallbackTimestamp timelapse: skipping intermediate frame");
- return true;
- } else {
- // Desired frame has arrived after mTimeBetweenTimeLapseFrameCaptureUs time:
- // - Reset mLastTimeLapseFrameRealTimestampUs to current time.
- // - Artificially modify timestampUs to be one frame time (1/framerate) ahead
- // of the last encoded frame's time stamp.
- LOGV("dataCallbackTimestamp timelapse: got timelapse frame");
-
- mLastTimeLapseFrameRealTimestampUs = *timestampUs;
- *timestampUs = mLastFrameTimestampUs + mTimeBetweenTimeLapseVideoFramesUs;
- return false;
- }
+ mLastTimeLapseFrameRealTimestampUs = *timestampUs;
+ *timestampUs = mLastFrameTimestampUs + mTimeBetweenTimeLapseVideoFramesUs;
+ return false;
}
return false;
}
void CameraSourceTimeLapse::dataCallbackTimestamp(int64_t timestampUs, int32_t msgType,
const sp<IMemory> &data) {
- if (!mUseStillCameraForTimeLapse) {
- mSkipCurrentFrame = skipFrameAndModifyTimeStamp(×tampUs);
- } else {
- Mutex::Autolock autoLock(mCameraIdleLock);
- // If we are using the still camera and stop() has been called, it may
- // be waiting for the camera to get idle. In that case return
- // immediately. Calling CameraSource::dataCallbackTimestamp() will lead
- // to a deadlock since it tries to access CameraSource::mLock which in
- // this case is held by CameraSource::stop() currently waiting for the
- // camera to get idle. And camera will not get idle until this call
- // returns.
- if (mStopWaitingForIdleCamera) {
- return;
- }
- }
+ LOGV("dataCallbackTimestamp");
+ mSkipCurrentFrame = skipFrameAndModifyTimeStamp(×tampUs);
CameraSource::dataCallbackTimestamp(timestampUs, msgType, data);
}
diff --git a/media/libstagefright/DRMExtractor.cpp b/media/libstagefright/DRMExtractor.cpp
index 6db922e..1f3d581 100644
--- a/media/libstagefright/DRMExtractor.cpp
+++ b/media/libstagefright/DRMExtractor.cpp
@@ -41,7 +41,7 @@
class DRMSource : public MediaSource {
public:
DRMSource(const sp<MediaSource> &mediaSource,
- DecryptHandle *decryptHandle,
+ const sp<DecryptHandle> &decryptHandle,
DrmManagerClient *managerClient,
int32_t trackId, DrmBuffer *ipmpBox);
@@ -56,7 +56,7 @@
private:
sp<MediaSource> mOriginalMediaSource;
- DecryptHandle* mDecryptHandle;
+ sp<DecryptHandle> mDecryptHandle;
DrmManagerClient* mDrmManagerClient;
size_t mTrackId;
mutable Mutex mDRMLock;
@@ -70,7 +70,7 @@
////////////////////////////////////////////////////////////////////////////////
DRMSource::DRMSource(const sp<MediaSource> &mediaSource,
- DecryptHandle *decryptHandle,
+ const sp<DecryptHandle> &decryptHandle,
DrmManagerClient *managerClient,
int32_t trackId, DrmBuffer *ipmpBox)
: mOriginalMediaSource(mediaSource),
@@ -241,7 +241,7 @@
mOriginalExtractor->setDrmFlag(true);
mOriginalExtractor->getMetaData()->setInt32(kKeyIsDRM, 1);
- source->getDrmInfo(&mDecryptHandle, &mDrmManagerClient);
+ source->getDrmInfo(mDecryptHandle, &mDrmManagerClient);
}
DRMExtractor::~DRMExtractor() {
@@ -277,7 +277,7 @@
bool SniffDRM(
const sp<DataSource> &source, String8 *mimeType, float *confidence,
sp<AMessage> *) {
- DecryptHandle *decryptHandle = source->DrmInitialization();
+ sp<DecryptHandle> decryptHandle = source->DrmInitialization();
if (decryptHandle != NULL) {
if (decryptHandle->decryptApiType == DecryptApiType::CONTAINER_BASED) {
diff --git a/media/libstagefright/DataSource.cpp b/media/libstagefright/DataSource.cpp
index 3b38208..c16b3b5 100644
--- a/media/libstagefright/DataSource.cpp
+++ b/media/libstagefright/DataSource.cpp
@@ -15,13 +15,14 @@
*/
#include "include/AMRExtractor.h"
+#include "include/AVIExtractor.h"
#include "include/MP3Extractor.h"
#include "include/MPEG4Extractor.h"
#include "include/WAVExtractor.h"
#include "include/OggExtractor.h"
#include "include/MPEG2TSExtractor.h"
#include "include/NuCachedSource2.h"
-#include "include/NuHTTPDataSource.h"
+#include "include/HTTPBase.h"
#include "include/DRMExtractor.h"
#include "include/FLACExtractor.h"
#include "include/AACExtractor.h"
@@ -111,6 +112,7 @@
RegisterSniffer(SniffMPEG2TS);
RegisterSniffer(SniffMP3);
RegisterSniffer(SniffAAC);
+ RegisterSniffer(SniffAVI);
char value[PROPERTY_VALUE_MAX];
if (property_get("drm.service.enabled", value, NULL)
@@ -127,7 +129,7 @@
source = new FileSource(uri + 7);
} else if (!strncasecmp("http://", uri, 7)
|| !strncasecmp("https://", uri, 8)) {
- sp<NuHTTPDataSource> httpSource = new NuHTTPDataSource;
+ sp<HTTPBase> httpSource = HTTPBase::Create();
if (httpSource->connect(uri, headers) != OK) {
return NULL;
}
@@ -144,4 +146,8 @@
return source;
}
+String8 DataSource::getMIMEType() const {
+ return String8("application/octet-stream");
+}
+
} // namespace android
diff --git a/media/libstagefright/ESDS.cpp b/media/libstagefright/ESDS.cpp
index b7c8e0c..1f7ee25 100644
--- a/media/libstagefright/ESDS.cpp
+++ b/media/libstagefright/ESDS.cpp
@@ -14,6 +14,10 @@
* limitations under the License.
*/
+//#define LOG_NDEBUG 0
+#define LOG_TAG "ESDS"
+#include <utils/Log.h>
+
#include "include/ESDS.h"
#include <string.h>
@@ -87,6 +91,8 @@
}
while (more);
+ LOGV("tag=0x%02x data_size=%d", *tag, *data_size);
+
if (*data_size > size) {
return ERROR_MALFORMED;
}
@@ -146,8 +152,20 @@
if (OCRstreamFlag) {
offset += 2;
size -= 2;
+
+ if ((offset >= size || mData[offset] != kTag_DecoderConfigDescriptor)
+ && offset - 2 < size
+ && mData[offset - 2] == kTag_DecoderConfigDescriptor) {
+ // Content found "in the wild" had OCRstreamFlag set but was
+ // missing OCR_ES_Id, the decoder config descriptor immediately
+ // followed instead.
+ offset -= 2;
+ size += 2;
+
+ LOGW("Found malformed 'esds' atom, ignoring missing OCR_ES_Id.");
+ }
}
-
+
if (offset >= size) {
return ERROR_MALFORMED;
}
diff --git a/media/libstagefright/FileSource.cpp b/media/libstagefright/FileSource.cpp
index 02a78c9..f2f3500 100644
--- a/media/libstagefright/FileSource.cpp
+++ b/media/libstagefright/FileSource.cpp
@@ -125,7 +125,7 @@
return OK;
}
-DecryptHandle* FileSource::DrmInitialization() {
+sp<DecryptHandle> FileSource::DrmInitialization() {
if (mDrmManagerClient == NULL) {
mDrmManagerClient = new DrmManagerClient();
}
@@ -147,8 +147,8 @@
return mDecryptHandle;
}
-void FileSource::getDrmInfo(DecryptHandle **handle, DrmManagerClient **client) {
- *handle = mDecryptHandle;
+void FileSource::getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client) {
+ handle = mDecryptHandle;
*client = mDrmManagerClient;
}
diff --git a/media/libstagefright/HTTPBase.cpp b/media/libstagefright/HTTPBase.cpp
new file mode 100644
index 0000000..f9d8501
--- /dev/null
+++ b/media/libstagefright/HTTPBase.cpp
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2011 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 "HTTPBase"
+#include <utils/Log.h>
+
+#include "include/HTTPBase.h"
+
+#if CHROMIUM_AVAILABLE
+#include "include/ChromiumHTTPDataSource.h"
+#endif
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/ALooper.h>
+
+#include <cutils/properties.h>
+#include <cutils/qtaguid.h>
+
+namespace android {
+
+HTTPBase::HTTPBase()
+ : mNumBandwidthHistoryItems(0),
+ mTotalTransferTimeUs(0),
+ mTotalTransferBytes(0),
+ mPrevBandwidthMeasureTimeUs(0),
+ mPrevEstimatedBandWidthKbps(0),
+ mBandWidthCollectFreqMs(5000),
+ mUIDValid(false) {
+}
+
+// static
+sp<HTTPBase> HTTPBase::Create(uint32_t flags) {
+#if CHROMIUM_AVAILABLE
+ return new ChromiumHTTPDataSource(flags);
+#endif
+ {
+ TRESPASS();
+
+ return NULL;
+ }
+}
+
+void HTTPBase::addBandwidthMeasurement(
+ size_t numBytes, int64_t delayUs) {
+ Mutex::Autolock autoLock(mLock);
+
+ BandwidthEntry entry;
+ entry.mDelayUs = delayUs;
+ entry.mNumBytes = numBytes;
+ mTotalTransferTimeUs += delayUs;
+ mTotalTransferBytes += numBytes;
+
+ mBandwidthHistory.push_back(entry);
+ if (++mNumBandwidthHistoryItems > 100) {
+ BandwidthEntry *entry = &*mBandwidthHistory.begin();
+ mTotalTransferTimeUs -= entry->mDelayUs;
+ mTotalTransferBytes -= entry->mNumBytes;
+ mBandwidthHistory.erase(mBandwidthHistory.begin());
+ --mNumBandwidthHistoryItems;
+
+ int64_t timeNowUs = ALooper::GetNowUs();
+ if (timeNowUs - mPrevBandwidthMeasureTimeUs >=
+ mBandWidthCollectFreqMs * 1000LL) {
+
+ if (mPrevBandwidthMeasureTimeUs != 0) {
+ mPrevEstimatedBandWidthKbps =
+ (mTotalTransferBytes * 8E3 / mTotalTransferTimeUs);
+ }
+ mPrevBandwidthMeasureTimeUs = timeNowUs;
+ }
+ }
+
+}
+
+bool HTTPBase::estimateBandwidth(int32_t *bandwidth_bps) {
+ Mutex::Autolock autoLock(mLock);
+
+ if (mNumBandwidthHistoryItems < 2) {
+ return false;
+ }
+
+ *bandwidth_bps = ((double)mTotalTransferBytes * 8E6 / mTotalTransferTimeUs);
+
+ return true;
+}
+
+status_t HTTPBase::getEstimatedBandwidthKbps(int32_t *kbps) {
+ Mutex::Autolock autoLock(mLock);
+ *kbps = mPrevEstimatedBandWidthKbps;
+ return OK;
+}
+
+status_t HTTPBase::setBandwidthStatCollectFreq(int32_t freqMs) {
+ Mutex::Autolock autoLock(mLock);
+
+ if (freqMs < kMinBandwidthCollectFreqMs
+ || freqMs > kMaxBandwidthCollectFreqMs) {
+
+ LOGE("frequency (%d ms) is out of range [1000, 60000]", freqMs);
+ return BAD_VALUE;
+ }
+
+ LOGI("frequency set to %d ms", freqMs);
+ mBandWidthCollectFreqMs = freqMs;
+ return OK;
+}
+
+void HTTPBase::setUID(uid_t uid) {
+ mUIDValid = true;
+ mUID = uid;
+}
+
+bool HTTPBase::getUID(uid_t *uid) const {
+ if (!mUIDValid) {
+ return false;
+ }
+
+ *uid = mUID;
+
+ return true;
+}
+
+// static
+void HTTPBase::RegisterSocketUser(int s, uid_t uid) {
+ static const uint32_t kTag = 0xdeadbeef;
+ set_qtaguid(s, kTag, uid);
+}
+
+} // namespace android
diff --git a/media/libstagefright/HTTPStream.cpp b/media/libstagefright/HTTPStream.cpp
deleted file mode 100644
index a156da6..0000000
--- a/media/libstagefright/HTTPStream.cpp
+++ /dev/null
@@ -1,600 +0,0 @@
-/*
- * 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 "HTTPStream"
-#include <utils/Log.h>
-
-#include "include/HTTPStream.h"
-
-#include <sys/socket.h>
-
-#include <arpa/inet.h>
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <media/stagefright/foundation/ADebug.h>
-
-#include <openssl/ssl.h>
-
-namespace android {
-
-// static
-const char *HTTPStream::kStatusKey = ":status:"; // MUST be lowercase.
-
-HTTPStream::HTTPStream()
- : mState(READY),
- mSocket(-1),
- mSSLContext(NULL),
- mSSL(NULL) {
-}
-
-HTTPStream::~HTTPStream() {
- disconnect();
-
- if (mSSLContext != NULL) {
- SSL_CTX_free((SSL_CTX *)mSSLContext);
- mSSLContext = NULL;
- }
-}
-
-static bool MakeSocketBlocking(int s, bool blocking) {
- // Make socket non-blocking.
- int flags = fcntl(s, F_GETFL, 0);
- if (flags == -1) {
- return false;
- }
-
- if (blocking) {
- flags &= ~O_NONBLOCK;
- } else {
- flags |= O_NONBLOCK;
- }
-
- return fcntl(s, F_SETFL, flags) != -1;
-}
-
-static status_t MyConnect(
- int s, const struct sockaddr *addr, socklen_t addrlen) {
- status_t result = UNKNOWN_ERROR;
-
- MakeSocketBlocking(s, false);
-
- if (connect(s, addr, addrlen) == 0) {
- result = OK;
- } else if (errno != EINPROGRESS) {
- result = -errno;
- } else {
- for (;;) {
- fd_set rs, ws;
- FD_ZERO(&rs);
- FD_ZERO(&ws);
- FD_SET(s, &rs);
- FD_SET(s, &ws);
-
- struct timeval tv;
- tv.tv_sec = 0;
- tv.tv_usec = 100000ll;
-
- int nfds = ::select(s + 1, &rs, &ws, NULL, &tv);
-
- if (nfds < 0) {
- if (errno == EINTR) {
- continue;
- }
-
- result = -errno;
- break;
- }
-
- if (FD_ISSET(s, &ws) && !FD_ISSET(s, &rs)) {
- result = OK;
- break;
- }
-
- if (FD_ISSET(s, &rs) || FD_ISSET(s, &ws)) {
- // Get the pending error.
- int error = 0;
- socklen_t errorLen = sizeof(error);
- if (getsockopt(s, SOL_SOCKET, SO_ERROR, &error, &errorLen) == -1) {
- // Couldn't get the real error, so report why not.
- result = -errno;
- } else {
- result = -error;
- }
- break;
- }
-
- // Timeout expired. Try again.
- }
- }
-
- MakeSocketBlocking(s, true);
-
- return result;
-}
-
-// Apparently under out linux closing a socket descriptor from one thread
-// will not unblock a pending send/recv on that socket on another thread.
-static ssize_t MySendReceive(
- int s, void *data, size_t size, int flags, bool sendData) {
- ssize_t result = 0;
-
- if (s < 0) {
- return -1;
- }
- while (size > 0) {
- fd_set rs, ws, es;
- FD_ZERO(&rs);
- FD_ZERO(&ws);
- FD_ZERO(&es);
- FD_SET(s, sendData ? &ws : &rs);
- FD_SET(s, &es);
-
- struct timeval tv;
- tv.tv_sec = 0;
- tv.tv_usec = 100000ll;
-
- int nfds = ::select(
- s + 1,
- sendData ? NULL : &rs,
- sendData ? &ws : NULL,
- &es,
- &tv);
-
- if (nfds < 0) {
- if (errno == EINTR) {
- continue;
- }
-
- result = -errno;
- break;
- } else if (nfds == 0) {
- // timeout
-
- continue;
- }
-
- CHECK_EQ(nfds, 1);
-
- ssize_t nbytes =
- sendData ? send(s, data, size, flags) : recv(s, data, size, flags);
-
- if (nbytes < 0) {
- if (errno == EINTR) {
- continue;
- }
-
- result = -errno;
- break;
- } else if (nbytes == 0) {
- result = 0;
- break;
- }
-
- data = (uint8_t *)data + nbytes;
- size -= nbytes;
-
- result = nbytes;
- break;
- }
-
- return result;
-}
-
-static ssize_t MySend(int s, const void *data, size_t size, int flags) {
- return MySendReceive(
- s, const_cast<void *>(data), size, flags, true /* sendData */);
-}
-
-static ssize_t MyReceive(int s, void *data, size_t size, int flags) {
- return MySendReceive(s, data, size, flags, false /* sendData */);
-}
-
-status_t HTTPStream::connect(const char *server, int port, bool https) {
- if (port < 0) {
- port = https ? 443 : 80;
- }
-
- Mutex::Autolock autoLock(mLock);
-
- status_t err = OK;
-
- if (mState == CONNECTED) {
- return ERROR_ALREADY_CONNECTED;
- }
-
- if (port < 0 || port > (int) USHRT_MAX) {
- return UNKNOWN_ERROR;
- }
-
- char service[sizeof("65536")];
- sprintf(service, "%d", port);
- struct addrinfo hints, *ai;
- memset(&hints, 0, sizeof(hints));
- hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV;
- hints.ai_socktype = SOCK_STREAM;
-
- int ret = getaddrinfo(server, service, &hints, &ai);
- if (ret) {
- return ERROR_UNKNOWN_HOST;
- }
-
- CHECK_EQ(mSocket, -1);
-
- mState = CONNECTING;
- status_t res = -1;
- struct addrinfo *tmp;
- for (tmp = ai; tmp; tmp = tmp->ai_next) {
- mSocket = socket(tmp->ai_family, tmp->ai_socktype, tmp->ai_protocol);
- if (mSocket < 0) {
- continue;
- }
-
- setReceiveTimeout(30); // Time out reads after 30 secs by default.
-
- int s = mSocket;
-
- mLock.unlock();
-
- res = MyConnect(s, tmp->ai_addr, tmp->ai_addrlen);
-
- mLock.lock();
-
- if (mState != CONNECTING) {
- close(s);
- freeaddrinfo(ai);
- return UNKNOWN_ERROR;
- }
-
- if (res == OK) {
- break;
- }
-
- close(s);
- }
-
- freeaddrinfo(ai);
-
- if (res != OK) {
- close(mSocket);
- mSocket = -1;
-
- mState = READY;
- return res;
- }
-
- if (https) {
- CHECK(mSSL == NULL);
-
- if (mSSLContext == NULL) {
- SSL_library_init();
-
- mSSLContext = SSL_CTX_new(TLSv1_client_method());
-
- if (mSSLContext == NULL) {
- LOGE("failed to create SSL context");
- mState = READY;
- return ERROR_IO;
- }
- }
-
- mSSL = SSL_new((SSL_CTX *)mSSLContext);
-
- if (mSSL == NULL) {
- LOGE("failed to create SSL session");
-
- mState = READY;
- return ERROR_IO;
- }
-
- int res = SSL_set_fd((SSL *)mSSL, mSocket);
-
- if (res == 1) {
- res = SSL_connect((SSL *)mSSL);
- }
-
- if (res != 1) {
- SSL_free((SSL *)mSSL);
- mSSL = NULL;
-
- LOGE("failed to connect over SSL");
- mState = READY;
-
- return ERROR_IO;
- }
- }
-
- mState = CONNECTED;
-
- return OK;
-}
-
-status_t HTTPStream::disconnect() {
- Mutex::Autolock autoLock(mLock);
-
- if (mState != CONNECTED && mState != CONNECTING) {
- return ERROR_NOT_CONNECTED;
- }
-
- if (mSSL != NULL) {
- SSL_shutdown((SSL *)mSSL);
-
- SSL_free((SSL *)mSSL);
- mSSL = NULL;
- }
-
- CHECK(mSocket >= 0);
- close(mSocket);
- mSocket = -1;
-
- mState = READY;
-
- return OK;
-}
-
-status_t HTTPStream::send(const char *data, size_t size) {
- if (mState != CONNECTED) {
- return ERROR_NOT_CONNECTED;
- }
-
- while (size > 0) {
- ssize_t n;
- if (mSSL != NULL) {
- n = SSL_write((SSL *)mSSL, data, size);
-
- if (n < 0) {
- n = -SSL_get_error((SSL *)mSSL, n);
- }
- } else {
- n = MySend(mSocket, data, size, 0);
- }
-
- if (n < 0) {
- disconnect();
-
- return n;
- } else if (n == 0) {
- disconnect();
-
- return ERROR_CONNECTION_LOST;
- }
-
- size -= (size_t)n;
- data += (size_t)n;
- }
-
- return OK;
-}
-
-status_t HTTPStream::send(const char *data) {
- return send(data, strlen(data));
-}
-
-// A certain application spawns a local webserver that sends invalid responses,
-// specifically it terminates header line with only a newline instead of the
-// CRLF (carriage-return followed by newline) required by the HTTP specs.
-// The workaround accepts both behaviours but could potentially break
-// legitimate responses that use a single newline to "fold" headers, which is
-// why it's not yet on by default.
-#define WORKAROUND_FOR_MISSING_CR 1
-
-status_t HTTPStream::receive_line(char *line, size_t size) {
- if (mState != CONNECTED) {
- return ERROR_NOT_CONNECTED;
- }
-
- bool saw_CR = false;
- size_t length = 0;
-
- for (;;) {
- char c;
- ssize_t n;
- if (mSSL != NULL) {
- n = SSL_read((SSL *)mSSL, &c, 1);
-
- if (n < 0) {
- n = -SSL_get_error((SSL *)mSSL, n);
- }
- } else {
- n = MyReceive(mSocket, &c, 1, 0);
- }
-
- if (n < 0) {
- disconnect();
-
- return ERROR_IO;
- } else if (n == 0) {
- disconnect();
-
- return ERROR_CONNECTION_LOST;
- }
-
-#if WORKAROUND_FOR_MISSING_CR
- if (c == '\n') {
- // We have a complete line.
-
- line[saw_CR ? length - 1 : length] = '\0';
- return OK;
- }
-#else
- if (saw_CR && c == '\n') {
- // We have a complete line.
-
- line[length - 1] = '\0';
- return OK;
- }
-#endif
-
- saw_CR = (c == '\r');
-
- if (length + 1 >= size) {
- return ERROR_MALFORMED;
- }
- line[length++] = c;
- }
-}
-
-status_t HTTPStream::receive_header(int *http_status) {
- *http_status = -1;
- mHeaders.clear();
-
- char line[2048];
- status_t err = receive_line(line, sizeof(line));
- if (err != OK) {
- return err;
- }
-
- mHeaders.add(AString(kStatusKey), AString(line));
-
- char *spacePos = strchr(line, ' ');
- if (spacePos == NULL) {
- // Malformed response?
- return UNKNOWN_ERROR;
- }
-
- char *status_start = spacePos + 1;
- char *status_end = status_start;
- while (isdigit(*status_end)) {
- ++status_end;
- }
-
- if (status_end == status_start) {
- // Malformed response, status missing?
- return UNKNOWN_ERROR;
- }
-
- memmove(line, status_start, status_end - status_start);
- line[status_end - status_start] = '\0';
-
- long tmp = strtol(line, NULL, 10);
- if (tmp < 0 || tmp > 999) {
- return UNKNOWN_ERROR;
- }
-
- *http_status = (int)tmp;
-
- for (;;) {
- err = receive_line(line, sizeof(line));
- if (err != OK) {
- return err;
- }
-
- if (*line == '\0') {
- // Empty line signals the end of the header.
- break;
- }
-
- // puts(line);
-
- char *colonPos = strchr(line, ':');
- if (colonPos == NULL) {
- AString key = line;
- key.tolower();
-
- mHeaders.add(key, AString());
- } else {
- char *end_of_key = colonPos;
- while (end_of_key > line && isspace(end_of_key[-1])) {
- --end_of_key;
- }
-
- char *start_of_value = colonPos + 1;
- while (isspace(*start_of_value)) {
- ++start_of_value;
- }
-
- *end_of_key = '\0';
-
- AString key = line;
- key.tolower();
-
- mHeaders.add(key, AString(start_of_value));
- }
- }
-
- return OK;
-}
-
-ssize_t HTTPStream::receive(void *data, size_t size) {
- size_t total = 0;
- while (total < size) {
- ssize_t n;
- if (mSSL != NULL) {
- n = SSL_read((SSL *)mSSL, (char *)data + total, size - total);
-
- if (n < 0) {
- n = -SSL_get_error((SSL *)mSSL, n);
- }
- } else {
- n = MyReceive(mSocket, (char *)data + total, size - total, 0);
- }
-
- if (n < 0) {
- LOGE("recv failed, errno = %d (%s)", (int)n, strerror(-n));
-
- disconnect();
- return (ssize_t)ERROR_IO;
- } else if (n == 0) {
- disconnect();
-
- LOGE("recv failed, server is gone, total received: %d bytes",
- total);
-
- return total == 0 ? (ssize_t)ERROR_CONNECTION_LOST : total;
- }
-
- total += (size_t)n;
- }
-
- return (ssize_t)total;
-}
-
-bool HTTPStream::find_header_value(const AString &key, AString *value) const {
- AString key_lower = key;
- key_lower.tolower();
-
- ssize_t index = mHeaders.indexOfKey(key_lower);
- if (index < 0) {
- value->clear();
- return false;
- }
-
- *value = mHeaders.valueAt(index);
-
- return true;
-}
-
-void HTTPStream::setReceiveTimeout(int seconds) {
- if (seconds < 0) {
- // Disable the timeout.
- seconds = 0;
- }
-
- struct timeval tv;
- tv.tv_usec = 0;
- tv.tv_sec = seconds;
- CHECK_EQ(0, setsockopt(mSocket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)));
-}
-
-} // namespace android
-
diff --git a/media/libstagefright/MP3Extractor.cpp b/media/libstagefright/MP3Extractor.cpp
index 03ce202..92e84c2 100644
--- a/media/libstagefright/MP3Extractor.cpp
+++ b/media/libstagefright/MP3Extractor.cpp
@@ -20,6 +20,7 @@
#include "include/MP3Extractor.h"
+#include "include/avc_utils.h"
#include "include/ID3.h"
#include "include/VBRISeeker.h"
#include "include/XINGSeeker.h"
@@ -44,143 +45,6 @@
// Yes ... there are things that must indeed match...
static const uint32_t kMask = 0xfffe0c00;
-// static
-bool MP3Extractor::get_mp3_frame_size(
- uint32_t header, size_t *frame_size,
- int *out_sampling_rate, int *out_channels,
- int *out_bitrate) {
- *frame_size = 0;
-
- if (out_sampling_rate) {
- *out_sampling_rate = 0;
- }
-
- if (out_channels) {
- *out_channels = 0;
- }
-
- if (out_bitrate) {
- *out_bitrate = 0;
- }
-
- if ((header & 0xffe00000) != 0xffe00000) {
- return false;
- }
-
- unsigned version = (header >> 19) & 3;
-
- if (version == 0x01) {
- return false;
- }
-
- unsigned layer = (header >> 17) & 3;
-
- if (layer == 0x00) {
- return false;
- }
-
- unsigned protection = (header >> 16) & 1;
-
- unsigned bitrate_index = (header >> 12) & 0x0f;
-
- if (bitrate_index == 0 || bitrate_index == 0x0f) {
- // Disallow "free" bitrate.
- return false;
- }
-
- unsigned sampling_rate_index = (header >> 10) & 3;
-
- if (sampling_rate_index == 3) {
- return false;
- }
-
- static const int kSamplingRateV1[] = { 44100, 48000, 32000 };
- int sampling_rate = kSamplingRateV1[sampling_rate_index];
- if (version == 2 /* V2 */) {
- sampling_rate /= 2;
- } else if (version == 0 /* V2.5 */) {
- sampling_rate /= 4;
- }
-
- unsigned padding = (header >> 9) & 1;
-
- if (layer == 3) {
- // layer I
-
- static const int kBitrateV1[] = {
- 32, 64, 96, 128, 160, 192, 224, 256,
- 288, 320, 352, 384, 416, 448
- };
-
- static const int kBitrateV2[] = {
- 32, 48, 56, 64, 80, 96, 112, 128,
- 144, 160, 176, 192, 224, 256
- };
-
- int bitrate =
- (version == 3 /* V1 */)
- ? kBitrateV1[bitrate_index - 1]
- : kBitrateV2[bitrate_index - 1];
-
- if (out_bitrate) {
- *out_bitrate = bitrate;
- }
-
- *frame_size = (12000 * bitrate / sampling_rate + padding) * 4;
- } else {
- // layer II or III
-
- static const int kBitrateV1L2[] = {
- 32, 48, 56, 64, 80, 96, 112, 128,
- 160, 192, 224, 256, 320, 384
- };
-
- static const int kBitrateV1L3[] = {
- 32, 40, 48, 56, 64, 80, 96, 112,
- 128, 160, 192, 224, 256, 320
- };
-
- static const int kBitrateV2[] = {
- 8, 16, 24, 32, 40, 48, 56, 64,
- 80, 96, 112, 128, 144, 160
- };
-
- int bitrate;
- if (version == 3 /* V1 */) {
- bitrate = (layer == 2 /* L2 */)
- ? kBitrateV1L2[bitrate_index - 1]
- : kBitrateV1L3[bitrate_index - 1];
- } else {
- // V2 (or 2.5)
-
- bitrate = kBitrateV2[bitrate_index - 1];
- }
-
- if (out_bitrate) {
- *out_bitrate = bitrate;
- }
-
- if (version == 3 /* V1 */) {
- *frame_size = 144000 * bitrate / sampling_rate + padding;
- } else {
- // V2 or V2.5
- *frame_size = 72000 * bitrate / sampling_rate + padding;
- }
- }
-
- if (out_sampling_rate) {
- *out_sampling_rate = sampling_rate;
- }
-
- if (out_channels) {
- int channel_mode = (header >> 6) & 3;
-
- *out_channels = (channel_mode == 3) ? 1 : 2;
- }
-
- return true;
-}
-
static bool Resync(
const sp<DataSource> &source, uint32_t match_header,
off64_t *inout_pos, off64_t *post_id3_pos, uint32_t *out_header) {
@@ -282,7 +146,7 @@
size_t frame_size;
int sample_rate, num_channels, bitrate;
- if (!MP3Extractor::get_mp3_frame_size(
+ if (!GetMPEGAudioFrameSize(
header, &frame_size,
&sample_rate, &num_channels, &bitrate)) {
++pos;
@@ -316,7 +180,7 @@
}
size_t test_frame_size;
- if (!MP3Extractor::get_mp3_frame_size(
+ if (!GetMPEGAudioFrameSize(
test_header, &test_frame_size)) {
valid = false;
break;
@@ -374,6 +238,9 @@
sp<MP3Seeker> mSeeker;
MediaBufferGroup *mGroup;
+ int64_t mBasisTimeUs;
+ int64_t mSamplesRead;
+
MP3Source(const MP3Source &);
MP3Source &operator=(const MP3Source &);
};
@@ -419,7 +286,7 @@
int sample_rate;
int num_channels;
int bitrate;
- get_mp3_frame_size(
+ GetMPEGAudioFrameSize(
header, &frame_size, &sample_rate, &num_channels, &bitrate);
mMeta = new MetaData;
@@ -489,7 +356,9 @@
mCurrentTimeUs(0),
mStarted(false),
mSeeker(seeker),
- mGroup(NULL) {
+ mGroup(NULL),
+ mBasisTimeUs(0),
+ mSamplesRead(0) {
}
MP3Source::~MP3Source() {
@@ -509,6 +378,9 @@
mCurrentPos = mFirstFramePos;
mCurrentTimeUs = 0;
+ mBasisTimeUs = mCurrentTimeUs;
+ mSamplesRead = 0;
+
mStarted = true;
return OK;
@@ -535,6 +407,8 @@
int64_t seekTimeUs;
ReadOptions::SeekMode mode;
+ bool seekCBR = false;
+
if (options != NULL && options->getSeekTo(&seekTimeUs, &mode)) {
int64_t actualSeekTimeUs = seekTimeUs;
if (mSeeker == NULL
@@ -549,9 +423,13 @@
mCurrentTimeUs = seekTimeUs;
mCurrentPos = mFirstFramePos + seekTimeUs * bitrate / 8000000;
+ seekCBR = true;
} else {
mCurrentTimeUs = actualSeekTimeUs;
}
+
+ mBasisTimeUs = mCurrentTimeUs;
+ mSamplesRead = 0;
}
MediaBuffer *buffer;
@@ -562,6 +440,8 @@
size_t frame_size;
int bitrate;
+ int num_samples;
+ int sample_rate;
for (;;) {
ssize_t n = mDataSource->readAt(mCurrentPos, buffer->data(), 4);
if (n < 4) {
@@ -574,8 +454,16 @@
uint32_t header = U32_AT((const uint8_t *)buffer->data());
if ((header & kMask) == (mFixedHeader & kMask)
- && MP3Extractor::get_mp3_frame_size(
- header, &frame_size, NULL, NULL, &bitrate)) {
+ && GetMPEGAudioFrameSize(
+ header, &frame_size, &sample_rate, NULL,
+ &bitrate, &num_samples)) {
+
+ // re-calculate mCurrentTimeUs because we might have called Resync()
+ if (seekCBR) {
+ mCurrentTimeUs = (mCurrentPos - mFirstFramePos) * 8000 / bitrate;
+ mBasisTimeUs = mCurrentTimeUs;
+ }
+
break;
}
@@ -613,7 +501,9 @@
buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
mCurrentPos += frame_size;
- mCurrentTimeUs += frame_size * 8000ll / bitrate;
+
+ mSamplesRead += num_samples;
+ mCurrentTimeUs = mBasisTimeUs + ((mSamplesRead * 1000000) / sample_rate);
*out = buffer;
diff --git a/media/libstagefright/MPEG2TSWriter.cpp b/media/libstagefright/MPEG2TSWriter.cpp
index 4e4f289..02eeb40 100644
--- a/media/libstagefright/MPEG2TSWriter.cpp
+++ b/media/libstagefright/MPEG2TSWriter.cpp
@@ -466,6 +466,8 @@
MPEG2TSWriter::MPEG2TSWriter(int fd)
: mFile(fdopen(dup(fd), "wb")),
+ mWriteCookie(NULL),
+ mWriteFunc(NULL),
mStarted(false),
mNumSourcesDone(0),
mNumTSPacketsWritten(0),
@@ -475,6 +477,21 @@
MPEG2TSWriter::MPEG2TSWriter(const char *filename)
: mFile(fopen(filename, "wb")),
+ mWriteCookie(NULL),
+ mWriteFunc(NULL),
+ mStarted(false),
+ mNumSourcesDone(0),
+ mNumTSPacketsWritten(0),
+ mNumTSPacketsBeforeMeta(0) {
+ init();
+}
+
+MPEG2TSWriter::MPEG2TSWriter(
+ void *cookie,
+ ssize_t (*write)(void *cookie, const void *data, size_t size))
+ : mFile(NULL),
+ mWriteCookie(cookie),
+ mWriteFunc(write),
mStarted(false),
mNumSourcesDone(0),
mNumTSPacketsWritten(0),
@@ -483,7 +500,7 @@
}
void MPEG2TSWriter::init() {
- CHECK(mFile != NULL);
+ CHECK(mFile != NULL || mWriteFunc != NULL);
mLooper = new ALooper;
mLooper->setName("MPEG2TSWriter");
@@ -502,8 +519,10 @@
mLooper->unregisterHandler(mReflector->id());
mLooper->stop();
- fclose(mFile);
- mFile = NULL;
+ if (mFile != NULL) {
+ fclose(mFile);
+ mFile = NULL;
+ }
}
status_t MPEG2TSWriter::addSource(const sp<MediaSource> &source) {
@@ -718,7 +737,7 @@
static const unsigned kContinuityCounter = 5;
buffer->data()[3] |= kContinuityCounter;
- CHECK_EQ(fwrite(buffer->data(), 1, buffer->size(), mFile), buffer->size());
+ CHECK_EQ(internalWrite(buffer->data(), buffer->size()), buffer->size());
}
void MPEG2TSWriter::writeProgramMap() {
@@ -794,7 +813,7 @@
*ptr++ = 0x00;
*ptr++ = 0x00;
- CHECK_EQ(fwrite(buffer->data(), 1, buffer->size(), mFile), buffer->size());
+ CHECK_EQ(internalWrite(buffer->data(), buffer->size()), buffer->size());
}
void MPEG2TSWriter::writeAccessUnit(
@@ -890,7 +909,7 @@
memcpy(ptr, accessUnit->data(), copy);
- CHECK_EQ(fwrite(buffer->data(), 1, buffer->size(), mFile), buffer->size());
+ CHECK_EQ(internalWrite(buffer->data(), buffer->size()), buffer->size());
size_t offset = copy;
while (offset < accessUnit->size()) {
@@ -923,7 +942,7 @@
}
memcpy(ptr, accessUnit->data() + offset, copy);
- CHECK_EQ(fwrite(buffer->data(), 1, buffer->size(), mFile),
+ CHECK_EQ(internalWrite(buffer->data(), buffer->size()),
buffer->size());
offset += copy;
@@ -939,5 +958,13 @@
}
}
+ssize_t MPEG2TSWriter::internalWrite(const void *data, size_t size) {
+ if (mFile != NULL) {
+ return fwrite(data, 1, size, mFile);
+ }
+
+ return (*mWriteFunc)(mWriteCookie, data, size);
+}
+
} // namespace android
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 7b96d01..73a05a5 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -19,6 +19,8 @@
#include "include/MPEG4Extractor.h"
#include "include/SampleTable.h"
+#include "include/ESDS.h"
+#include "timedtext/TimedTextPlayer.h"
#include <arpa/inet.h>
@@ -29,7 +31,6 @@
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/DataSource.h>
-#include "include/ESDS.h"
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MediaBufferGroup.h>
#include <media/stagefright/MediaDefs.h>
@@ -262,7 +263,7 @@
MPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source)
: mDataSource(source),
- mHaveMetadata(false),
+ mInitCheck(NO_INIT),
mHasVideo(false),
mFirstTrack(NULL),
mLastTrack(NULL),
@@ -361,8 +362,8 @@
}
status_t MPEG4Extractor::readMetaData() {
- if (mHaveMetadata) {
- return OK;
+ if (mInitCheck != NO_INIT) {
+ return mInitCheck;
}
off64_t offset = 0;
@@ -370,21 +371,20 @@
while ((err = parseChunk(&offset, 0)) == OK) {
}
- if (mHaveMetadata) {
+ if (mInitCheck == OK) {
if (mHasVideo) {
mFileMetaData->setCString(kKeyMIMEType, "video/mp4");
} else {
mFileMetaData->setCString(kKeyMIMEType, "audio/mp4");
}
- return OK;
+ mInitCheck = OK;
+ } else {
+ mInitCheck = err;
}
- return err;
-}
-
-void MPEG4Extractor::setDrmFlag(bool flag) {
- mIsDrm = flag;
+ CHECK_NE(err, (status_t)NO_INIT);
+ return mInitCheck;
}
char* MPEG4Extractor::getDrmTrackInfo(size_t trackID, int *len) {
@@ -649,6 +649,7 @@
off64_t chunk_data_size = *offset + chunk_size - data_offset;
if (chunk_type != FOURCC('c', 'p', 'r', 't')
+ && chunk_type != FOURCC('c', 'o', 'v', 'r')
&& mPath.size() == 5 && underMetaDataPath(mPath)) {
off64_t stop_offset = *offset + chunk_size;
*offset = data_offset;
@@ -755,7 +756,7 @@
return err;
}
} else if (chunk_type == FOURCC('m', 'o', 'o', 'v')) {
- mHaveMetadata = true;
+ mInitCheck = OK;
if (!mIsDrm) {
return UNKNOWN_ERROR; // Return a dummy error.
@@ -829,6 +830,33 @@
mLastTrack->meta->setInt64(
kKeyDuration, (duration * 1000000) / mLastTrack->timescale);
+ uint8_t lang[2];
+ off64_t lang_offset;
+ if (version == 1) {
+ lang_offset = timescale_offset + 4 + 8;
+ } else if (version == 0) {
+ lang_offset = timescale_offset + 4 + 4;
+ } else {
+ return ERROR_IO;
+ }
+
+ if (mDataSource->readAt(lang_offset, &lang, sizeof(lang))
+ < (ssize_t)sizeof(lang)) {
+ return ERROR_IO;
+ }
+
+ // To get the ISO-639-2/T three character language code
+ // 1 bit pad followed by 3 5-bits characters. Each character
+ // is packed as the difference between its ASCII value and 0x60.
+ char lang_code[4];
+ lang_code[0] = ((lang[0] >> 2) & 0x1f) + 0x60;
+ lang_code[1] = ((lang[0] & 0x3) << 3 | (lang[1] >> 5)) + 0x60;
+ lang_code[2] = (lang[1] & 0x1f) + 0x60;
+ lang_code[3] = '\0';
+
+ mLastTrack->meta->setCString(
+ kKeyMediaLanguage, lang_code);
+
*offset += chunk_size;
break;
}
@@ -857,11 +885,17 @@
uint32_t entry_count = U32_AT(&buffer[4]);
if (entry_count > 1) {
- // For now we only support a single type of media per track.
-
- mLastTrack->skipTrack = true;
- *offset += chunk_size;
- break;
+ // For 3GPP timed text, there could be multiple tx3g boxes contain
+ // multiple text display formats. These formats will be used to
+ // display the timed text.
+ const char *mime;
+ CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime));
+ if (strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP)) {
+ // For now we only support a single type of media per track.
+ mLastTrack->skipTrack = true;
+ *offset += chunk_size;
+ break;
+ }
}
off64_t stop_offset = *offset + chunk_size;
@@ -1292,6 +1326,81 @@
return parseDrmSINF(offset, data_offset);
}
+ case FOURCC('h', 'd', 'l', 'r'):
+ {
+ uint32_t buffer;
+ if (mDataSource->readAt(
+ data_offset + 8, &buffer, 4) < 4) {
+ return ERROR_IO;
+ }
+
+ uint32_t type = ntohl(buffer);
+ // For the 3GPP file format, the handler-type within the 'hdlr' box
+ // shall be 'text'
+ if (type == FOURCC('t', 'e', 'x', 't')) {
+ mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_TEXT_3GPP);
+ }
+
+ *offset += chunk_size;
+ break;
+ }
+
+ case FOURCC('t', 'x', '3', 'g'):
+ {
+ uint32_t type;
+ const void *data;
+ size_t size = 0;
+ if (!mLastTrack->meta->findData(
+ kKeyTextFormatData, &type, &data, &size)) {
+ size = 0;
+ }
+
+ uint8_t *buffer = new uint8_t[size + chunk_size];
+
+ if (size > 0) {
+ memcpy(buffer, data, size);
+ }
+
+ if ((size_t)(mDataSource->readAt(*offset, buffer + size, chunk_size))
+ < chunk_size) {
+ delete[] buffer;
+ buffer = NULL;
+
+ return ERROR_IO;
+ }
+
+ mLastTrack->meta->setData(
+ kKeyTextFormatData, 0, buffer, size + chunk_size);
+
+ delete[] buffer;
+
+ *offset += chunk_size;
+ break;
+ }
+
+ case FOURCC('c', 'o', 'v', 'r'):
+ {
+ if (mFileMetaData != NULL) {
+ LOGV("chunk_data_size = %lld and data_offset = %lld",
+ chunk_data_size, data_offset);
+ uint8_t *buffer = new uint8_t[chunk_data_size + 1];
+ if (mDataSource->readAt(
+ data_offset, buffer, chunk_data_size) != (ssize_t)chunk_data_size) {
+ delete[] buffer;
+ buffer = NULL;
+
+ return ERROR_IO;
+ }
+ const int kSkipBytesOfDataBox = 16;
+ mFileMetaData->setData(
+ kKeyAlbumArt, MetaData::TYPE_NONE,
+ buffer + kSkipBytesOfDataBox, chunk_data_size - kSkipBytesOfDataBox);
+ }
+
+ *offset += chunk_size;
+ break;
+ }
+
default:
{
*offset += chunk_size;
@@ -1901,7 +2010,7 @@
off64_t offset;
size_t size;
- uint32_t dts;
+ uint32_t cts;
bool isSyncSample;
bool newBuffer = false;
if (mBuffer == NULL) {
@@ -1909,7 +2018,7 @@
status_t err =
mSampleTable->getMetaDataForSample(
- mCurrentSampleIndex, &offset, &size, &dts, &isSyncSample);
+ mCurrentSampleIndex, &offset, &size, &cts, &isSyncSample);
if (err != OK) {
return err;
@@ -1939,7 +2048,7 @@
mBuffer->set_range(0, size);
mBuffer->meta_data()->clear();
mBuffer->meta_data()->setInt64(
- kKeyTime, ((int64_t)dts * 1000000) / mTimescale);
+ kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
if (targetSampleTimeUs >= 0) {
mBuffer->meta_data()->setInt64(
@@ -2025,14 +2134,18 @@
size_t dstOffset = 0;
while (srcOffset < size) {
- CHECK(srcOffset + mNALLengthSize <= size);
- size_t nalLength = parseNALSize(&mSrcBuffer[srcOffset]);
- srcOffset += mNALLengthSize;
+ bool isMalFormed = (srcOffset + mNALLengthSize > size);
+ size_t nalLength = 0;
+ if (!isMalFormed) {
+ nalLength = parseNALSize(&mSrcBuffer[srcOffset]);
+ srcOffset += mNALLengthSize;
+ isMalFormed = srcOffset + nalLength > size;
+ }
- if (srcOffset + nalLength > size) {
+ if (isMalFormed) {
+ LOGE("Video is malformed");
mBuffer->release();
mBuffer = NULL;
-
return ERROR_MALFORMED;
}
@@ -2057,7 +2170,7 @@
mBuffer->meta_data()->clear();
mBuffer->meta_data()->setInt64(
- kKeyTime, ((int64_t)dts * 1000000) / mTimescale);
+ kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
if (targetSampleTimeUs >= 0) {
mBuffer->meta_data()->setInt64(
@@ -2077,6 +2190,20 @@
}
}
+MPEG4Extractor::Track *MPEG4Extractor::findTrackByMimePrefix(
+ const char *mimePrefix) {
+ for (Track *track = mFirstTrack; track != NULL; track = track->next) {
+ const char *mime;
+ if (track->meta != NULL
+ && track->meta->findCString(kKeyMIMEType, &mime)
+ && !strncasecmp(mime, mimePrefix, strlen(mimePrefix))) {
+ return track;
+ }
+ }
+
+ return NULL;
+}
+
static bool LegacySniffMPEG4(
const sp<DataSource> &source, String8 *mimeType, float *confidence) {
uint8_t header[8];
@@ -2109,6 +2236,14 @@
FOURCC('3', 'g', 'p', '4'),
FOURCC('m', 'p', '4', '1'),
FOURCC('m', 'p', '4', '2'),
+
+ // Won't promise that the following file types can be played.
+ // Just give these file types a chance.
+ FOURCC('q', 't', ' ', ' '), // Apple's QuickTime
+ FOURCC('M', 'S', 'N', 'V'), // Sony's PSP
+
+ FOURCC('3', 'g', '2', 'a'), // 3GPP2
+ FOURCC('3', 'g', '2', 'b'),
};
for (size_t i = 0;
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
old mode 100644
new mode 100755
index 5d6ea7c..8c9ff87
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -22,7 +22,6 @@
#include <pthread.h>
#include <sys/prctl.h>
-#include <sys/resource.h>
#include <media/stagefright/MPEG4Writer.h>
#include <media/stagefright/MediaBuffer.h>
@@ -33,6 +32,7 @@
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/Utils.h>
#include <media/mediarecorder.h>
+#include <cutils/properties.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -45,14 +45,11 @@
static const int64_t kMax32BitFileSize = 0x007fffffffLL;
static const uint8_t kNalUnitTypeSeqParamSet = 0x07;
static const uint8_t kNalUnitTypePicParamSet = 0x08;
-
-// Using longer adjustment period to suppress fluctuations in
-// the audio encoding paths
-static const int64_t kVideoMediaTimeAdjustPeriodTimeUs = 600000000LL; // 10 minutes
+static const int64_t kInitialDelayTimeUs = 700000LL;
class MPEG4Writer::Track {
public:
- Track(MPEG4Writer *owner, const sp<MediaSource> &source);
+ Track(MPEG4Writer *owner, const sp<MediaSource> &source, size_t trackId);
~Track();
@@ -63,12 +60,13 @@
int64_t getDurationUs() const;
int64_t getEstimatedTrackSizeBytes() const;
- void writeTrackHeader(int32_t trackID, bool use32BitOffset = true);
+ void writeTrackHeader(bool use32BitOffset = true);
void bufferChunk(int64_t timestampUs);
bool isAvc() const { return mIsAvc; }
bool isAudio() const { return mIsAudio; }
bool isMPEG4() const { return mIsMPEG4; }
void addChunkOffset(off64_t offset);
+ int32_t getTrackId() const { return mTrackId; }
status_t dump(int fd, const Vector<String16>& args) const;
private:
@@ -82,10 +80,10 @@
bool mIsAvc;
bool mIsAudio;
bool mIsMPEG4;
+ int32_t mTrackId;
int64_t mTrackDurationUs;
+ int64_t mMaxChunkDurationUs;
- // For realtime applications, we need to adjust the media clock
- // for video track based on the audio media clock
bool mIsRealTimeRecording;
int64_t mMaxTimeStampUs;
int64_t mEstimatedTrackSizeBytes;
@@ -123,17 +121,28 @@
size_t mNumStssTableEntries;
List<int32_t> mStssTableEntries;
- size_t mNumSttsTableEntries;
struct SttsTableEntry {
- SttsTableEntry(uint32_t count, uint32_t durationUs)
- : sampleCount(count), sampleDurationUs(durationUs) {}
+ SttsTableEntry(uint32_t count, uint32_t duration)
+ : sampleCount(count), sampleDuration(duration) {}
uint32_t sampleCount;
- uint32_t sampleDurationUs;
+ uint32_t sampleDuration; // time scale based
};
+ size_t mNumSttsTableEntries;
List<SttsTableEntry> mSttsTableEntries;
+ struct CttsTableEntry {
+ CttsTableEntry(uint32_t count, int32_t timescaledDur)
+ : sampleCount(count), sampleDuration(timescaledDur) {}
+
+ uint32_t sampleCount;
+ int32_t sampleDuration; // time scale based
+ };
+ bool mHasNegativeCttsDeltaDuration;
+ size_t mNumCttsTableEntries;
+ List<CttsTableEntry> mCttsTableEntries;
+
// Sequence parameter set or picture parameter set
struct AVCParamSet {
AVCParamSet(uint16_t length, const uint8_t *data)
@@ -155,43 +164,23 @@
bool mReachedEOS;
int64_t mStartTimestampUs;
+ int64_t mStartTimeRealUs;
+ int64_t mFirstSampleTimeRealUs;
int64_t mPreviousTrackTimeUs;
int64_t mTrackEveryTimeDurationUs;
- // Has the media time adjustment for video started?
- bool mIsMediaTimeAdjustmentOn;
- // The time stamp when previous media time adjustment period starts
- int64_t mPrevMediaTimeAdjustTimestampUs;
- // Number of vidoe frames whose time stamp may be adjusted
- int64_t mMediaTimeAdjustNumFrames;
- // The sample number when previous meida time adjustmnet period starts
- int64_t mPrevMediaTimeAdjustSample;
- // The total accumulated drift time within a period of
- // kVideoMediaTimeAdjustPeriodTimeUs.
- int64_t mTotalDriftTimeToAdjustUs;
- // The total accumalated drift time since the start of the recording
- // excluding the current time adjustment period
- int64_t mPrevTotalAccumDriftTimeUs;
-
// Update the audio track's drift information.
void updateDriftTime(const sp<MetaData>& meta);
- // Adjust the time stamp of the video track according to
- // the drift time information from the audio track.
- void adjustMediaTime(int64_t *timestampUs);
-
static void *ThreadWrapper(void *me);
status_t threadEntry();
const uint8_t *parseParamSet(
const uint8_t *data, size_t length, int type, size_t *paramSetLen);
- status_t makeAVCCodecSpecificData(
- const uint8_t *data, size_t size);
- status_t copyAVCCodecSpecificData(
- const uint8_t *data, size_t size);
- status_t parseAVCCodecSpecificData(
- const uint8_t *data, size_t size);
+ status_t makeAVCCodecSpecificData(const uint8_t *data, size_t size);
+ status_t copyAVCCodecSpecificData(const uint8_t *data, size_t size);
+ status_t parseAVCCodecSpecificData(const uint8_t *data, size_t size);
// Track authoring progress status
void trackProgressStatus(int64_t timeUs, status_t err = OK);
@@ -212,7 +201,38 @@
void updateTrackSizeEstimate();
void addOneStscTableEntry(size_t chunkId, size_t sampleId);
void addOneStssTableEntry(size_t sampleId);
- void addOneSttsTableEntry(size_t sampleCount, int64_t durationUs);
+
+ // Duration is time scale based
+ void addOneSttsTableEntry(size_t sampleCount, int32_t timescaledDur);
+ void addOneCttsTableEntry(size_t sampleCount, int32_t timescaledDur);
+
+ bool isTrackMalFormed() const;
+ void sendTrackSummary(bool hasMultipleTracks);
+
+ // Write the boxes
+ void writeStcoBox(bool use32BitOffset);
+ void writeStscBox();
+ void writeStszBox();
+ void writeStssBox();
+ void writeSttsBox();
+ void writeCttsBox();
+ void writeD263Box();
+ void writePaspBox();
+ void writeAvccBox();
+ void writeUrlBox();
+ void writeDrefBox();
+ void writeDinfBox();
+ void writeDamrBox();
+ void writeMdhdBox(time_t now);
+ void writeSmhdBox();
+ void writeVmhdBox();
+ void writeHdlrBox();
+ void writeTkhdBox(time_t now);
+ void writeMp4aEsdsBox();
+ void writeMp4vEsdsBox();
+ void writeAudioFourCCBox();
+ void writeVideoFourCCBox();
+ void writeStblBox(bool use32BitOffset);
Track(const Track &);
Track &operator=(const Track &);
@@ -226,12 +246,17 @@
mIsFileSizeLimitExplicitlyRequested(false),
mPaused(false),
mStarted(false),
+ mWriterThreadStarted(false),
mOffset(0),
mMdatOffset(0),
mEstimatedMoovBoxSize(0),
- mInterleaveDurationUs(1000000) {
+ mInterleaveDurationUs(1000000),
+ mLatitudex10000(0),
+ mLongitudex10000(0),
+ mAreGeoTagsAvailable(false),
+ mStartTimeOffsetMs(-1) {
- mFd = open(filename, O_CREAT | O_LARGEFILE | O_TRUNC);
+ mFd = open(filename, O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR);
if (mFd >= 0) {
mInitCheck = OK;
}
@@ -245,10 +270,15 @@
mIsFileSizeLimitExplicitlyRequested(false),
mPaused(false),
mStarted(false),
+ mWriterThreadStarted(false),
mOffset(0),
mMdatOffset(0),
mEstimatedMoovBoxSize(0),
- mInterleaveDurationUs(1000000) {
+ mInterleaveDurationUs(1000000),
+ mLatitudex10000(0),
+ mLongitudex10000(0),
+ mAreGeoTagsAvailable(false),
+ mStartTimeOffsetMs(-1) {
}
MPEG4Writer::~MPEG4Writer() {
@@ -295,7 +325,12 @@
}
status_t MPEG4Writer::addSource(const sp<MediaSource> &source) {
- Track *track = new Track(this, source);
+ Mutex::Autolock l(mLock);
+ if (mStarted) {
+ LOGE("Attempt to add source AFTER recording is started");
+ return UNKNOWN_ERROR;
+ }
+ Track *track = new Track(this, source, mTracks.size());
mTracks.push_back(track);
return OK;
@@ -444,20 +479,7 @@
mMoovBoxBuffer = NULL;
mMoovBoxBufferOffset = 0;
- beginBox("ftyp");
- {
- int32_t fileType;
- if (param && param->findInt32(kKeyFileType, &fileType) &&
- fileType != OUTPUT_FORMAT_MPEG_4) {
- writeFourcc("3gp4");
- } else {
- writeFourcc("isom");
- }
- }
- writeInt32(0);
- writeFourcc("isom");
- writeFourcc("3gp4");
- endBox();
+ writeFtypBox(param);
mFreeBoxOffset = mOffset;
@@ -518,6 +540,9 @@
void MPEG4Writer::stopWriterThread() {
LOGD("Stopping writer thread");
+ if (!mWriterThreadStarted) {
+ return;
+ }
{
Mutex::Autolock autolock(mLock);
@@ -528,6 +553,7 @@
void *dummy;
pthread_join(mThread, &dummy);
+ mWriterThreadStarted = false;
LOGD("Writer thread stopped");
}
@@ -583,10 +609,25 @@
writeInt32(0x40000000); // w
}
+void MPEG4Writer::release() {
+ close(mFd);
+ mFd = -1;
+ mInitCheck = NO_INIT;
+ mStarted = false;
+}
status_t MPEG4Writer::stop() {
if (mInitCheck != OK) {
return OK;
+ } else {
+ if (!mWriterThreadStarted ||
+ !mStarted) {
+ if (mWriterThreadStarted) {
+ stopWriterThread();
+ }
+ release();
+ return OK;
+ }
}
status_t err = OK;
@@ -617,10 +658,7 @@
// Do not write out movie header on error.
if (err != OK) {
- close(mFd);
- mFd = -1;
- mInitCheck = NO_INIT;
- mStarted = false;
+ release();
return err;
}
@@ -637,43 +675,12 @@
}
lseek64(mFd, mOffset, SEEK_SET);
- time_t now = time(NULL);
const off64_t moovOffset = mOffset;
mWriteMoovBoxToMemory = true;
mMoovBoxBuffer = (uint8_t *) malloc(mEstimatedMoovBoxSize);
mMoovBoxBufferOffset = 0;
CHECK(mMoovBoxBuffer != NULL);
- int32_t duration = (maxDurationUs * mTimeScale + 5E5) / 1E6;
-
- beginBox("moov");
-
- beginBox("mvhd");
- writeInt32(0); // version=0, flags=0
- writeInt32(now); // creation time
- writeInt32(now); // modification time
- writeInt32(mTimeScale); // mvhd timescale
- writeInt32(duration);
- writeInt32(0x10000); // rate: 1.0
- writeInt16(0x100); // volume
- writeInt16(0); // reserved
- writeInt32(0); // reserved
- writeInt32(0); // reserved
- writeCompositionMatrix(0); // matrix
- writeInt32(0); // predefined
- writeInt32(0); // predefined
- writeInt32(0); // predefined
- writeInt32(0); // predefined
- writeInt32(0); // predefined
- writeInt32(0); // predefined
- writeInt32(mTracks.size() + 1); // nextTrackID
- endBox(); // mvhd
-
- int32_t id = 1;
- for (List<Track *>::iterator it = mTracks.begin();
- it != mTracks.end(); ++it, ++id) {
- (*it)->writeTrackHeader(id, mUse32BitOffset);
- }
- endBox(); // moov
+ writeMoovBox(maxDurationUs);
mWriteMoovBoxToMemory = false;
if (mStreamableFile) {
@@ -699,13 +706,96 @@
CHECK(mBoxes.empty());
- close(mFd);
- mFd = -1;
- mInitCheck = NO_INIT;
- mStarted = false;
+ release();
return err;
}
+void MPEG4Writer::writeMvhdBox(int64_t durationUs) {
+ time_t now = time(NULL);
+ beginBox("mvhd");
+ writeInt32(0); // version=0, flags=0
+ writeInt32(now); // creation time
+ writeInt32(now); // modification time
+ writeInt32(mTimeScale); // mvhd timescale
+ int32_t duration = (durationUs * mTimeScale + 5E5) / 1E6;
+ writeInt32(duration);
+ writeInt32(0x10000); // rate: 1.0
+ writeInt16(0x100); // volume
+ writeInt16(0); // reserved
+ writeInt32(0); // reserved
+ writeInt32(0); // reserved
+ writeCompositionMatrix(0); // matrix
+ writeInt32(0); // predefined
+ writeInt32(0); // predefined
+ writeInt32(0); // predefined
+ writeInt32(0); // predefined
+ writeInt32(0); // predefined
+ writeInt32(0); // predefined
+ writeInt32(mTracks.size() + 1); // nextTrackID
+ endBox(); // mvhd
+}
+
+void MPEG4Writer::writeMoovBox(int64_t durationUs) {
+ beginBox("moov");
+ writeMvhdBox(durationUs);
+ if (mAreGeoTagsAvailable) {
+ writeUdtaBox();
+ }
+ int32_t id = 1;
+ for (List<Track *>::iterator it = mTracks.begin();
+ it != mTracks.end(); ++it, ++id) {
+ (*it)->writeTrackHeader(mUse32BitOffset);
+ }
+ endBox(); // moov
+}
+
+void MPEG4Writer::writeFtypBox(MetaData *param) {
+ beginBox("ftyp");
+
+ int32_t fileType;
+ if (param && param->findInt32(kKeyFileType, &fileType) &&
+ fileType != OUTPUT_FORMAT_MPEG_4) {
+ writeFourcc("3gp4");
+ } else {
+ writeFourcc("isom");
+ }
+
+ writeInt32(0);
+ writeFourcc("isom");
+ writeFourcc("3gp4");
+ endBox();
+}
+
+static bool isTestModeEnabled() {
+#if (PROPERTY_VALUE_MAX < 5)
+#error "PROPERTY_VALUE_MAX must be at least 5"
+#endif
+
+ // Test mode is enabled only if rw.media.record.test system
+ // property is enabled.
+ char value[PROPERTY_VALUE_MAX];
+ if (property_get("rw.media.record.test", value, NULL) &&
+ (!strcasecmp(value, "true") || !strcasecmp(value, "1"))) {
+ return true;
+ }
+ return false;
+}
+
+void MPEG4Writer::sendSessionSummary() {
+ // Send session summary only if test mode is enabled
+ if (!isTestModeEnabled()) {
+ return;
+ }
+
+ for (List<ChunkInfo>::iterator it = mChunkInfos.begin();
+ it != mChunkInfos.end(); ++it) {
+ int trackNum = it->mTrack->getTrackId() << 28;
+ notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
+ trackNum | MEDIA_RECORDER_TRACK_INTER_CHUNK_TIME_MS,
+ it->mMaxInterChunkDurUs);
+ }
+}
+
status_t MPEG4Writer::setInterleaveDuration(uint32_t durationUs) {
mInterleaveDurationUs = durationUs;
return OK;
@@ -868,6 +958,77 @@
write(s, 1, 4);
}
+
+// Written in +/-DD.DDDD format
+void MPEG4Writer::writeLatitude(int degreex10000) {
+ bool isNegative = (degreex10000 < 0);
+ char sign = isNegative? '-': '+';
+
+ // Handle the whole part
+ char str[9];
+ int wholePart = degreex10000 / 10000;
+ if (wholePart == 0) {
+ snprintf(str, 5, "%c%.2d.", sign, wholePart);
+ } else {
+ snprintf(str, 5, "%+.2d.", wholePart);
+ }
+
+ // Handle the fractional part
+ int fractionalPart = degreex10000 - (wholePart * 10000);
+ if (fractionalPart < 0) {
+ fractionalPart = -fractionalPart;
+ }
+ snprintf(&str[4], 5, "%.4d", fractionalPart);
+
+ // Do not write the null terminator
+ write(str, 1, 8);
+}
+
+// Written in +/- DDD.DDDD format
+void MPEG4Writer::writeLongitude(int degreex10000) {
+ bool isNegative = (degreex10000 < 0);
+ char sign = isNegative? '-': '+';
+
+ // Handle the whole part
+ char str[10];
+ int wholePart = degreex10000 / 10000;
+ if (wholePart == 0) {
+ snprintf(str, 6, "%c%.3d.", sign, wholePart);
+ } else {
+ snprintf(str, 6, "%+.3d.", wholePart);
+ }
+
+ // Handle the fractional part
+ int fractionalPart = degreex10000 - (wholePart * 10000);
+ if (fractionalPart < 0) {
+ fractionalPart = -fractionalPart;
+ }
+ snprintf(&str[5], 5, "%.4d", fractionalPart);
+
+ // Do not write the null terminator
+ write(str, 1, 9);
+}
+
+/*
+ * Geodata is stored according to ISO-6709 standard.
+ * latitudex10000 is latitude in degrees times 10000, and
+ * longitudex10000 is longitude in degrees times 10000.
+ * The range for the latitude is in [-90, +90], and
+ * The range for the longitude is in [-180, +180]
+ */
+status_t MPEG4Writer::setGeoData(int latitudex10000, int longitudex10000) {
+ // Is latitude or longitude out of range?
+ if (latitudex10000 < -900000 || latitudex10000 > 900000 ||
+ longitudex10000 < -1800000 || longitudex10000 > 1800000) {
+ return BAD_VALUE;
+ }
+
+ mLatitudex10000 = latitudex10000;
+ mLongitudex10000 = longitudex10000;
+ mAreGeoTagsAvailable = true;
+ return OK;
+}
+
void MPEG4Writer::write(const void *data, size_t size) {
write(data, 1, size);
}
@@ -945,7 +1106,7 @@
////////////////////////////////////////////////////////////////////////////////
MPEG4Writer::Track::Track(
- MPEG4Writer *owner, const sp<MediaSource> &source)
+ MPEG4Writer *owner, const sp<MediaSource> &source, size_t trackId)
: mOwner(owner),
mMeta(source->getFormat()),
mSource(source),
@@ -953,6 +1114,7 @@
mPaused(false),
mResumed(false),
mStarted(false),
+ mTrackId(trackId),
mTrackDurationUs(0),
mEstimatedTrackSizeBytes(0),
mSamplesHaveSameSize(true),
@@ -988,6 +1150,7 @@
mEstimatedTrackSizeBytes += mNumStscTableEntries * 12 + // stsc box size
mNumStssTableEntries * 4 + // stss box size
mNumSttsTableEntries * 8 + // stts box size
+ mNumCttsTableEntries * 8 + // ctts box size
stcoBoxSizeBytes + // stco box size
stszBoxSizeBytes; // stsz box size
}
@@ -1007,13 +1170,27 @@
}
void MPEG4Writer::Track::addOneSttsTableEntry(
- size_t sampleCount, int64_t durationUs) {
+ size_t sampleCount, int32_t duration) {
- SttsTableEntry sttsEntry(sampleCount, durationUs);
+ SttsTableEntry sttsEntry(sampleCount, duration);
mSttsTableEntries.push_back(sttsEntry);
++mNumSttsTableEntries;
}
+void MPEG4Writer::Track::addOneCttsTableEntry(
+ size_t sampleCount, int32_t duration) {
+
+ if (mIsAudio) {
+ return;
+ }
+ if (duration < 0 && !mHasNegativeCttsDeltaDuration) {
+ mHasNegativeCttsDeltaDuration = true;
+ }
+ CttsTableEntry cttsEntry(sampleCount, duration);
+ mCttsTableEntries.push_back(cttsEntry);
+ ++mNumCttsTableEntries;
+}
+
void MPEG4Writer::Track::addChunkOffset(off64_t offset) {
++mNumStcoTableEntries;
mChunkOffsets.push_back(offset);
@@ -1149,18 +1326,14 @@
void MPEG4Writer::writeAllChunks() {
LOGV("writeAllChunks");
size_t outstandingChunks = 0;
- while (!mChunkInfos.empty()) {
- List<ChunkInfo>::iterator it = mChunkInfos.begin();
- while (!it->mChunks.empty()) {
- Chunk chunk;
- if (findChunkToWrite(&chunk)) {
- writeChunkToFile(&chunk);
- ++outstandingChunks;
- }
- }
- it->mTrack = NULL;
- mChunkInfos.erase(it);
+ Chunk chunk;
+ while (findChunkToWrite(&chunk)) {
+ writeChunkToFile(&chunk);
+ ++outstandingChunks;
}
+
+ sendSessionSummary();
+
mChunkInfos.clear();
LOGD("%d chunks are written in the last batch", outstandingChunks);
}
@@ -1168,8 +1341,6 @@
bool MPEG4Writer::findChunkToWrite(Chunk *chunk) {
LOGV("findChunkToWrite");
- // Find the smallest timestamp, and write that chunk out
- // XXX: What if some track is just too slow?
int64_t minTimestampUs = 0x7FFFFFFFFFFFFFFFLL;
Track *track = NULL;
for (List<ChunkInfo>::iterator it = mChunkInfos.begin();
@@ -1198,6 +1369,13 @@
*chunk = *(it->mChunks.begin());
it->mChunks.erase(it->mChunks.begin());
CHECK_EQ(chunk->mTrack, track);
+
+ int64_t interChunkTimeUs =
+ chunk->mTimeStampUs - it->mPrevChunkTimestampUs;
+ if (interChunkTimeUs > it->mPrevChunkTimestampUs) {
+ it->mMaxInterChunkDurUs = interChunkTimeUs;
+ }
+
return true;
}
}
@@ -1241,6 +1419,8 @@
it != mTracks.end(); ++it) {
ChunkInfo info;
info.mTrack = *it;
+ info.mPrevChunkTimestampUs = 0;
+ info.mMaxInterChunkDurUs = 0;
mChunkInfos.push_back(info);
}
@@ -1249,6 +1429,7 @@
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
pthread_create(&mThread, &attr, ThreadWrapper, this);
pthread_attr_destroy(&attr);
+ mWriterThreadStarted = true;
return OK;
}
@@ -1264,6 +1445,7 @@
if (params == NULL || !params->findInt64(kKeyTime, &startTimeUs)) {
startTimeUs = 0;
}
+ mStartTimeRealUs = startTimeUs;
int32_t rotationDegrees;
if (!mIsAudio && params && params->findInt32(kKeyRotation, &rotationDegrees)) {
@@ -1288,10 +1470,15 @@
* session, and it also helps eliminate the "recording" sound for
* camcorder applications.
*
- * Ideally, this platform-specific value should be defined
- * in media_profiles.xml file
+ * If client does not set the start time offset, we fall back to
+ * use the default initial delay value.
*/
- startTimeUs += 700000;
+ int64_t startTimeOffsetUs = mOwner->getStartTimeOffsetMs() * 1000LL;
+ if (startTimeOffsetUs < 0) { // Start time offset was not set
+ startTimeOffsetUs = kInitialDelayTimeUs;
+ }
+ startTimeUs += startTimeOffsetUs;
+ LOGI("Start time offset: %lld us", startTimeOffsetUs);
}
meta->setInt64(kKeyTime, startTimeUs);
@@ -1315,13 +1502,11 @@
mNumStssTableEntries = 0;
mNumStscTableEntries = 0;
mNumSttsTableEntries = 0;
+ mNumCttsTableEntries = 0;
mMdatSizeBytes = 0;
- mIsMediaTimeAdjustmentOn = false;
- mPrevMediaTimeAdjustTimestampUs = 0;
- mMediaTimeAdjustNumFrames = 0;
- mPrevMediaTimeAdjustSample = 0;
- mTotalDriftTimeToAdjustUs = 0;
- mPrevTotalAccumDriftTimeUs = 0;
+
+ mMaxChunkDurationUs = 0;
+ mHasNegativeCttsDeltaDuration = false;
pthread_create(&mThread, &attr, ThreadWrapper, this);
pthread_attr_destroy(&attr);
@@ -1530,7 +1715,10 @@
return ERROR_MALFORMED;
}
}
-
+// FIXME:
+// Add chromat_format_idc, bit depth values, etc for AVC/h264 high profile and above
+// and remove #if 0
+#if 0
{
// Check on the profiles
// These profiles requires additional parameter set extensions
@@ -1540,7 +1728,7 @@
return BAD_VALUE;
}
}
-
+#endif
return OK;
}
@@ -1618,128 +1806,6 @@
}
/*
-* The video track's media time adjustment for real-time applications
-* is described as follows:
-*
-* First, the media time adjustment is done for every period of
-* kVideoMediaTimeAdjustPeriodTimeUs. kVideoMediaTimeAdjustPeriodTimeUs
-* is currently a fixed value chosen heuristically. The value of
-* kVideoMediaTimeAdjustPeriodTimeUs should not be very large or very small
-* for two considerations: on one hand, a relatively large value
-* helps reduce large fluctuation of drift time in the audio encoding
-* path; while on the other hand, a relatively small value helps keep
-* restoring synchronization in audio/video more frequently. Note for the
-* very first period of kVideoMediaTimeAdjustPeriodTimeUs, there is
-* no media time adjustment for the video track.
-*
-* Second, the total accumulated audio track time drift found
-* in a period of kVideoMediaTimeAdjustPeriodTimeUs is distributed
-* over a stream of incoming video frames. The number of video frames
-* affected is determined based on the number of recorded video frames
-* within the past kVideoMediaTimeAdjustPeriodTimeUs period.
-* We choose to distribute the drift time over only a portion
-* (rather than all) of the total number of recorded video frames
-* in order to make sure that the video track media time adjustment is
-* completed for the current period before the next video track media
-* time adjustment period starts. Currently, the portion chosen is a
-* half (0.5).
-*
-* Last, various additional checks are performed to ensure that
-* the actual audio encoding path does not have too much drift.
-* In particular, 1) we want to limit the average incremental time
-* adjustment for each video frame to be less than a threshold
-* for a single period of kVideoMediaTimeAdjustPeriodTimeUs.
-* Currently, the threshold is set to 5 ms. If the average incremental
-* media time adjustment for a video frame is larger than the
-* threshold, the audio encoding path has too much time drift.
-* 2) We also want to limit the total time drift in the audio
-* encoding path to be less than a threshold for a period of
-* kVideoMediaTimeAdjustPeriodTimeUs. Currently, the threshold
-* is 0.5% of kVideoMediaTimeAdjustPeriodTimeUs. If the time drift of
-* the audio encoding path is larger than the threshold, the audio
-* encoding path has too much time drift. We treat the large time
-* drift of the audio encoding path as errors, since there is no
-* way to keep audio/video in synchronization for real-time
-* applications if the time drift is too large unless we drop some
-* video frames, which has its own problems that we don't want
-* to get into for the time being.
-*/
-void MPEG4Writer::Track::adjustMediaTime(int64_t *timestampUs) {
- if (*timestampUs - mPrevMediaTimeAdjustTimestampUs >=
- kVideoMediaTimeAdjustPeriodTimeUs) {
-
- LOGV("New media time adjustment period at %lld us", *timestampUs);
- mIsMediaTimeAdjustmentOn = true;
- mMediaTimeAdjustNumFrames =
- (mNumSamples - mPrevMediaTimeAdjustSample) >> 1;
-
- mPrevMediaTimeAdjustTimestampUs = *timestampUs;
- mPrevMediaTimeAdjustSample = mNumSamples;
- int64_t totalAccumDriftTimeUs = mOwner->getDriftTimeUs();
- mTotalDriftTimeToAdjustUs =
- totalAccumDriftTimeUs - mPrevTotalAccumDriftTimeUs;
-
- mPrevTotalAccumDriftTimeUs = totalAccumDriftTimeUs;
-
- // Check on incremental adjusted time per frame
- int64_t adjustTimePerFrameUs =
- mTotalDriftTimeToAdjustUs / mMediaTimeAdjustNumFrames;
-
- if (adjustTimePerFrameUs < 0) {
- adjustTimePerFrameUs = -adjustTimePerFrameUs;
- }
- if (adjustTimePerFrameUs >= 5000) {
- LOGE("Adjusted time per video frame is %lld us",
- adjustTimePerFrameUs);
- CHECK(!"Video frame time adjustment is too large!");
- }
-
- // Check on total accumulated time drift within a period of
- // kVideoMediaTimeAdjustPeriodTimeUs.
- int64_t driftPercentage = (mTotalDriftTimeToAdjustUs * 1000)
- / kVideoMediaTimeAdjustPeriodTimeUs;
-
- if (driftPercentage < 0) {
- driftPercentage = -driftPercentage;
- }
- if (driftPercentage > 5) {
- LOGE("Audio track has time drift %lld us over %lld us",
- mTotalDriftTimeToAdjustUs,
- kVideoMediaTimeAdjustPeriodTimeUs);
-
- CHECK(!"The audio track media time drifts too much!");
- }
-
- }
-
- if (mIsMediaTimeAdjustmentOn) {
- if (mNumSamples - mPrevMediaTimeAdjustSample <=
- mMediaTimeAdjustNumFrames) {
-
- // Do media time incremental adjustment
- int64_t incrementalAdjustTimeUs =
- (mTotalDriftTimeToAdjustUs *
- (mNumSamples - mPrevMediaTimeAdjustSample))
- / mMediaTimeAdjustNumFrames;
-
- *timestampUs +=
- (incrementalAdjustTimeUs + mPrevTotalAccumDriftTimeUs);
-
- LOGV("Incremental video frame media time adjustment: %lld us",
- (incrementalAdjustTimeUs + mPrevTotalAccumDriftTimeUs));
- } else {
- // Within the remaining adjustment period,
- // no incremental adjustment is needed.
- *timestampUs +=
- (mTotalDriftTimeToAdjustUs + mPrevTotalAccumDriftTimeUs);
-
- LOGV("Fixed video frame media time adjustment: %lld us",
- (mTotalDriftTimeToAdjustUs + mPrevTotalAccumDriftTimeUs));
- }
- }
-}
-
-/*
* Updates the drift time from the audio track so that
* the video track can get the updated drift time information
* from the file writer. The fluctuation of the drift time of the audio
@@ -1759,24 +1825,40 @@
status_t MPEG4Writer::Track::threadEntry() {
int32_t count = 0;
const int64_t interleaveDurationUs = mOwner->interleaveDuration();
+ const bool hasMultipleTracks = (mOwner->numTracks() > 1);
int64_t chunkTimestampUs = 0;
int32_t nChunks = 0;
int32_t nZeroLengthFrames = 0;
- int64_t lastTimestampUs = 0; // Previous sample time stamp in ms
- int64_t lastDurationUs = 0; // Between the previous two samples in ms
- int64_t currDurationTicks = 0; // Timescale based ticks
- int64_t lastDurationTicks = 0; // Timescale based ticks
- int32_t sampleCount = 1; // Sample count in the current stts table entry
- uint32_t previousSampleSize = 0; // Size of the previous sample
+ int64_t lastTimestampUs = 0; // Previous sample time stamp
+ int64_t lastCttsTimeUs = 0; // Previous sample time stamp
+ int64_t lastDurationUs = 0; // Between the previous two samples
+ int64_t currDurationTicks = 0; // Timescale based ticks
+ int64_t lastDurationTicks = 0; // Timescale based ticks
+ int32_t sampleCount = 1; // Sample count in the current stts table entry
+ int64_t currCttsDurTicks = 0; // Timescale based ticks
+ int64_t lastCttsDurTicks = 0; // Timescale based ticks
+ int32_t cttsSampleCount = 1; // Sample count in the current ctts table entry
+ uint32_t previousSampleSize = 0; // Size of the previous sample
int64_t previousPausedDurationUs = 0;
- int64_t timestampUs;
+ int64_t timestampUs = 0;
+ int64_t cttsDeltaTimeUs = 0;
+ bool hasBFrames = false;
+#if 1
+ // XXX: Samsung's video encoder's output buffer timestamp
+ // is not correct. see bug 4724339
+ char value[PROPERTY_VALUE_MAX];
+ if (property_get("rw.media.record.hasb", value, NULL) &&
+ (!strcasecmp(value, "true") || !strcasecmp(value, "1"))) {
+ hasBFrames = true;
+ }
+#endif
if (mIsAudio) {
prctl(PR_SET_NAME, (unsigned long)"AudioTrackEncoding", 0, 0, 0);
} else {
prctl(PR_SET_NAME, (unsigned long)"VideoTrackEncoding", 0, 0, 0);
}
- setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_AUDIO);
+ androidSetThreadPriority(0, ANDROID_PRIORITY_AUDIO);
sp<MetaData> meta_data;
@@ -1866,37 +1948,11 @@
int32_t isSync = false;
meta_data->findInt32(kKeyIsSyncFrame, &isSync);
-
- /*
- * The original timestamp found in the data buffer will be modified as below:
- *
- * There is a playback offset into this track if the track's start time
- * is not the same as the movie start time, which will be recorded in edst
- * box of the output file. The playback offset is to make sure that the
- * starting time of the audio/video tracks are synchronized. Although the
- * track's media timestamp may be subject to various modifications
- * as outlined below, the track's playback offset time remains unchanged
- * once the first data buffer of the track is received.
- *
- * The media time stamp will be calculated by subtracting the playback offset
- * (and potential pause durations) from the original timestamp in the buffer.
- *
- * If this track is a video track for a real-time recording application with
- * both audio and video tracks, its media timestamp will subject to further
- * modification based on the media clock of the audio track. This modification
- * is needed for the purpose of maintaining good audio/video synchronization.
- *
- * If the recording session is paused and resumed multiple times, the track
- * media timestamp will be modified as if the recording session had never been
- * paused at all during playback of the recorded output file. In other words,
- * the output file will have no memory of pause/resume durations.
- *
- */
CHECK(meta_data->findInt64(kKeyTime, ×tampUs));
- LOGV("%s timestampUs: %lld", mIsAudio? "Audio": "Video", timestampUs);
////////////////////////////////////////////////////////////////////////////////
- if (mSampleSizes.empty()) {
+ if (mNumSamples == 0) {
+ mFirstSampleTimeRealUs = systemTime() / 1000;
mStartTimestampUs = timestampUs;
mOwner->setStartTimestampUs(mStartTimestampUs);
previousPausedDurationUs = mStartTimestampUs;
@@ -1913,33 +1969,32 @@
timestampUs -= previousPausedDurationUs;
CHECK(timestampUs >= 0);
+ if (!mIsAudio && hasBFrames) {
+ /*
+ * Composition time: timestampUs
+ * Decoding time: decodingTimeUs
+ * Composition time delta = composition time - decoding time
+ *
+ * We save picture decoding time stamp delta in stts table entries,
+ * and composition time delta duration in ctts table entries.
+ */
+ int64_t decodingTimeUs;
+ CHECK(meta_data->findInt64(kKeyDecodingTime, &decodingTimeUs));
+ decodingTimeUs -= previousPausedDurationUs;
+ int64_t timeUs = decodingTimeUs;
+ cttsDeltaTimeUs = timestampUs - decodingTimeUs;
+ timestampUs = decodingTimeUs;
+ LOGV("decoding time: %lld and ctts delta time: %lld",
+ timestampUs, cttsDeltaTimeUs);
+ }
- // Media time adjustment for real-time applications
if (mIsRealTimeRecording) {
if (mIsAudio) {
updateDriftTime(meta_data);
- } else {
- adjustMediaTime(×tampUs);
}
}
CHECK(timestampUs >= 0);
- if (mNumSamples > 1) {
- if (timestampUs <= lastTimestampUs) {
- LOGW("Frame arrives too late!");
- // Don't drop the late frame, since dropping a frame may cause
- // problems later during playback
-
- // The idea here is to avoid having two or more samples with the
- // same timestamp in the output file.
- if (mTimeScale >= 1000000LL) {
- timestampUs = lastTimestampUs + 1;
- } else {
- timestampUs = lastTimestampUs + (1000000LL + (mTimeScale >> 1)) / mTimeScale;
- }
- }
- }
-
LOGV("%s media time stamp: %lld and previous paused duration %lld",
mIsAudio? "Audio": "Video", timestampUs, previousPausedDurationUs);
if (timestampUs > mTrackDurationUs) {
@@ -1963,11 +2018,23 @@
if (mNumSamples == 3 || currDurationTicks != lastDurationTicks) {
LOGV("%s lastDurationUs: %lld us, currDurationTicks: %lld us",
mIsAudio? "Audio": "Video", lastDurationUs, currDurationTicks);
- addOneSttsTableEntry(sampleCount, lastDurationUs);
+ addOneSttsTableEntry(sampleCount, lastDurationTicks);
sampleCount = 1;
} else {
++sampleCount;
}
+
+ if (!mIsAudio) {
+ currCttsDurTicks =
+ ((cttsDeltaTimeUs * mTimeScale + 500000LL) / 1000000LL -
+ (lastCttsTimeUs * mTimeScale + 500000LL) / 1000000LL);
+ if (currCttsDurTicks != lastCttsDurTicks) {
+ addOneCttsTableEntry(cttsSampleCount, lastCttsDurTicks);
+ cttsSampleCount = 1;
+ } else {
+ ++cttsSampleCount;
+ }
+ }
}
if (mSamplesHaveSameSize) {
if (mNumSamples >= 2 && previousSampleSize != sampleSize) {
@@ -1981,6 +2048,11 @@
lastDurationTicks = currDurationTicks;
lastTimestampUs = timestampUs;
+ if (!mIsAudio) {
+ lastCttsDurTicks = currCttsDurTicks;
+ lastCttsTimeUs = cttsDeltaTimeUs;
+ }
+
if (isSync != 0) {
addOneStssTableEntry(mNumSamples);
}
@@ -1991,7 +2063,7 @@
}
trackProgressStatus(timestampUs);
}
- if (mOwner->numTracks() == 1) {
+ if (!hasMultipleTracks) {
off64_t offset = mIsAvc? mOwner->addLengthPrefixedSample_l(copy)
: mOwner->addSample_l(copy);
if (mChunkOffsets.empty()) {
@@ -2010,7 +2082,11 @@
if (chunkTimestampUs == 0) {
chunkTimestampUs = timestampUs;
} else {
- if (timestampUs - chunkTimestampUs > interleaveDurationUs) {
+ int64_t chunkDurationUs = timestampUs - chunkTimestampUs;
+ if (chunkDurationUs > interleaveDurationUs) {
+ if (chunkDurationUs > mMaxChunkDurationUs) {
+ mMaxChunkDurationUs = chunkDurationUs;
+ }
++nChunks;
if (nChunks == 1 || // First chunk
(--(mStscTableEntries.end()))->samplesPerChunk !=
@@ -2025,15 +2101,14 @@
}
- if (mSampleSizes.empty() || // no samples written
- (!mIsAudio && mNumStssTableEntries == 0) || // no sync frames for video
- (OK != checkCodecSpecificData())) { // no codec specific data
+ if (isTrackMalFormed()) {
err = ERROR_MALFORMED;
}
- mOwner->trackProgressStatus(this, -1, err);
+
+ mOwner->trackProgressStatus(mTrackId, -1, err);
// Last chunk
- if (mOwner->numTracks() == 1) {
+ if (!hasMultipleTracks) {
addOneStscTableEntry(1, mNumSamples);
} else if (!mChunkSamples.empty()) {
addOneStscTableEntry(++nChunks, mChunkSamples.size());
@@ -2045,21 +2120,28 @@
// frame's duration.
if (mNumSamples == 1) {
lastDurationUs = 0; // A single sample's duration
+ lastDurationTicks = 0;
+ lastCttsDurTicks = 0;
} else {
++sampleCount; // Count for the last sample
+ ++cttsSampleCount;
}
if (mNumSamples <= 2) {
- addOneSttsTableEntry(1, lastDurationUs);
+ addOneSttsTableEntry(1, lastDurationTicks);
if (sampleCount - 1 > 0) {
- addOneSttsTableEntry(sampleCount - 1, lastDurationUs);
+ addOneSttsTableEntry(sampleCount - 1, lastDurationTicks);
}
} else {
- addOneSttsTableEntry(sampleCount, lastDurationUs);
+ addOneSttsTableEntry(sampleCount, lastDurationTicks);
}
+ addOneCttsTableEntry(cttsSampleCount, lastCttsDurTicks);
mTrackDurationUs += lastDurationUs;
mReachedEOS = true;
+
+ sendTrackSummary(hasMultipleTracks);
+
LOGI("Received total/0-length (%d/%d) buffers and encoded %d frames. - %s",
count, nZeroLengthFrames, mNumSamples, mIsAudio? "audio": "video");
if (mIsAudio) {
@@ -2072,46 +2154,112 @@
return err;
}
+bool MPEG4Writer::Track::isTrackMalFormed() const {
+ if (mSampleSizes.empty()) { // no samples written
+ LOGE("The number of recorded samples is 0");
+ return true;
+ }
+
+ if (!mIsAudio && mNumStssTableEntries == 0) { // no sync frames for video
+ LOGE("There are no sync frames for video track");
+ return true;
+ }
+
+ if (OK != checkCodecSpecificData()) { // no codec specific data
+ return true;
+ }
+
+ return false;
+}
+
+void MPEG4Writer::Track::sendTrackSummary(bool hasMultipleTracks) {
+
+ // Send track summary only if test mode is enabled.
+ if (!isTestModeEnabled()) {
+ return;
+ }
+
+ int trackNum = (mTrackId << 28);
+
+ mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
+ trackNum | MEDIA_RECORDER_TRACK_INFO_TYPE,
+ mIsAudio? 0: 1);
+
+ mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
+ trackNum | MEDIA_RECORDER_TRACK_INFO_DURATION_MS,
+ mTrackDurationUs / 1000);
+
+ mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
+ trackNum | MEDIA_RECORDER_TRACK_INFO_ENCODED_FRAMES,
+ mNumSamples);
+
+ {
+ // The system delay time excluding the requested initial delay that
+ // is used to eliminate the recording sound.
+ int64_t startTimeOffsetUs = mOwner->getStartTimeOffsetMs() * 1000LL;
+ if (startTimeOffsetUs < 0) { // Start time offset was not set
+ startTimeOffsetUs = kInitialDelayTimeUs;
+ }
+ int64_t initialDelayUs =
+ mFirstSampleTimeRealUs - mStartTimeRealUs - startTimeOffsetUs;
+
+ mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
+ trackNum | MEDIA_RECORDER_TRACK_INFO_INITIAL_DELAY_MS,
+ (initialDelayUs) / 1000);
+ }
+
+ mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
+ trackNum | MEDIA_RECORDER_TRACK_INFO_DATA_KBYTES,
+ mMdatSizeBytes / 1024);
+
+ if (hasMultipleTracks) {
+ mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
+ trackNum | MEDIA_RECORDER_TRACK_INFO_MAX_CHUNK_DUR_MS,
+ mMaxChunkDurationUs / 1000);
+
+ int64_t moovStartTimeUs = mOwner->getStartTimestampUs();
+ if (mStartTimestampUs != moovStartTimeUs) {
+ int64_t startTimeOffsetUs = mStartTimestampUs - moovStartTimeUs;
+ mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
+ trackNum | MEDIA_RECORDER_TRACK_INFO_START_OFFSET_MS,
+ startTimeOffsetUs / 1000);
+ }
+ }
+}
+
void MPEG4Writer::Track::trackProgressStatus(int64_t timeUs, status_t err) {
LOGV("trackProgressStatus: %lld us", timeUs);
if (mTrackEveryTimeDurationUs > 0 &&
timeUs - mPreviousTrackTimeUs >= mTrackEveryTimeDurationUs) {
LOGV("Fire time tracking progress status at %lld us", timeUs);
- mOwner->trackProgressStatus(this, timeUs - mPreviousTrackTimeUs, err);
+ mOwner->trackProgressStatus(mTrackId, timeUs - mPreviousTrackTimeUs, err);
mPreviousTrackTimeUs = timeUs;
}
}
void MPEG4Writer::trackProgressStatus(
- const MPEG4Writer::Track* track, int64_t timeUs, status_t err) {
+ size_t trackId, int64_t timeUs, status_t err) {
Mutex::Autolock lock(mLock);
- int32_t nTracks = mTracks.size();
- CHECK(nTracks >= 1);
- CHECK(nTracks < 64); // Arbitrary number
-
- int32_t trackNum = 0;
- CHECK(trackNum < nTracks);
- trackNum <<= 16;
+ int32_t trackNum = (trackId << 28);
// Error notification
// Do not consider ERROR_END_OF_STREAM an error
if (err != OK && err != ERROR_END_OF_STREAM) {
- notify(MEDIA_RECORDER_EVENT_ERROR,
- trackNum | MEDIA_RECORDER_ERROR_UNKNOWN,
+ notify(MEDIA_RECORDER_TRACK_EVENT_ERROR,
+ trackNum | MEDIA_RECORDER_TRACK_ERROR_GENERAL,
err);
return;
}
if (timeUs == -1) {
// Send completion notification
- notify(MEDIA_RECORDER_EVENT_INFO,
- trackNum | MEDIA_RECORDER_INFO_COMPLETION_STATUS,
+ notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
+ trackNum | MEDIA_RECORDER_TRACK_INFO_COMPLETION_STATUS,
err);
- return;
} else {
// Send progress status
- notify(MEDIA_RECORDER_EVENT_INFO,
- trackNum | MEDIA_RECORDER_INFO_PROGRESS_TIME_STATUS,
+ notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
+ trackNum | MEDIA_RECORDER_TRACK_INFO_PROGRESS_IN_TIME,
timeUs / 1000);
}
}
@@ -2169,388 +2317,517 @@
return OK;
}
-void MPEG4Writer::Track::writeTrackHeader(
- int32_t trackID, bool use32BitOffset) {
- const char *mime;
- bool success = mMeta->findCString(kKeyMIMEType, &mime);
- CHECK(success);
+void MPEG4Writer::Track::writeTrackHeader(bool use32BitOffset) {
LOGV("%s track time scale: %d",
mIsAudio? "Audio": "Video", mTimeScale);
time_t now = time(NULL);
- int32_t mvhdTimeScale = mOwner->getTimeScale();
+ mOwner->beginBox("trak");
+ writeTkhdBox(now);
+ mOwner->beginBox("mdia");
+ writeMdhdBox(now);
+ writeHdlrBox();
+ mOwner->beginBox("minf");
+ if (mIsAudio) {
+ writeSmhdBox();
+ } else {
+ writeVmhdBox();
+ }
+ writeDinfBox();
+ writeStblBox(use32BitOffset);
+ mOwner->endBox(); // minf
+ mOwner->endBox(); // mdia
+ mOwner->endBox(); // trak
+}
+
+void MPEG4Writer::Track::writeStblBox(bool use32BitOffset) {
+ mOwner->beginBox("stbl");
+ mOwner->beginBox("stsd");
+ mOwner->writeInt32(0); // version=0, flags=0
+ mOwner->writeInt32(1); // entry count
+ if (mIsAudio) {
+ writeAudioFourCCBox();
+ } else {
+ writeVideoFourCCBox();
+ }
+ mOwner->endBox(); // stsd
+ writeSttsBox();
+ writeCttsBox();
+ if (!mIsAudio) {
+ writeStssBox();
+ }
+ writeStszBox();
+ writeStscBox();
+ writeStcoBox(use32BitOffset);
+ mOwner->endBox(); // stbl
+}
+
+void MPEG4Writer::Track::writeVideoFourCCBox() {
+ const char *mime;
+ bool success = mMeta->findCString(kKeyMIMEType, &mime);
+ CHECK(success);
+ if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
+ mOwner->beginBox("mp4v");
+ } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
+ mOwner->beginBox("s263");
+ } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
+ mOwner->beginBox("avc1");
+ } else {
+ LOGE("Unknown mime type '%s'.", mime);
+ CHECK(!"should not be here, unknown mime type.");
+ }
+
+ mOwner->writeInt32(0); // reserved
+ mOwner->writeInt16(0); // reserved
+ mOwner->writeInt16(1); // data ref index
+ mOwner->writeInt16(0); // predefined
+ mOwner->writeInt16(0); // reserved
+ mOwner->writeInt32(0); // predefined
+ mOwner->writeInt32(0); // predefined
+ mOwner->writeInt32(0); // predefined
+
+ int32_t width, height;
+ success = mMeta->findInt32(kKeyWidth, &width);
+ success = success && mMeta->findInt32(kKeyHeight, &height);
+ CHECK(success);
+
+ mOwner->writeInt16(width);
+ mOwner->writeInt16(height);
+ mOwner->writeInt32(0x480000); // horiz resolution
+ mOwner->writeInt32(0x480000); // vert resolution
+ mOwner->writeInt32(0); // reserved
+ mOwner->writeInt16(1); // frame count
+ mOwner->write(" ", 32);
+ mOwner->writeInt16(0x18); // depth
+ mOwner->writeInt16(-1); // predefined
+
+ CHECK(23 + mCodecSpecificDataSize < 128);
+
+ if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
+ writeMp4vEsdsBox();
+ } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
+ writeD263Box();
+ } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
+ writeAvccBox();
+ }
+
+ writePaspBox();
+ mOwner->endBox(); // mp4v, s263 or avc1
+}
+
+void MPEG4Writer::Track::writeAudioFourCCBox() {
+ const char *mime;
+ bool success = mMeta->findCString(kKeyMIMEType, &mime);
+ CHECK(success);
+ const char *fourcc = NULL;
+ if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mime)) {
+ fourcc = "samr";
+ } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime)) {
+ fourcc = "sawb";
+ } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) {
+ fourcc = "mp4a";
+ } else {
+ LOGE("Unknown mime type '%s'.", mime);
+ CHECK(!"should not be here, unknown mime type.");
+ }
+
+ mOwner->beginBox(fourcc); // audio format
+ mOwner->writeInt32(0); // reserved
+ mOwner->writeInt16(0); // reserved
+ mOwner->writeInt16(0x1); // data ref index
+ mOwner->writeInt32(0); // reserved
+ mOwner->writeInt32(0); // reserved
+ int32_t nChannels;
+ CHECK_EQ(true, mMeta->findInt32(kKeyChannelCount, &nChannels));
+ mOwner->writeInt16(nChannels); // channel count
+ mOwner->writeInt16(16); // sample size
+ mOwner->writeInt16(0); // predefined
+ mOwner->writeInt16(0); // reserved
+
+ int32_t samplerate;
+ success = mMeta->findInt32(kKeySampleRate, &samplerate);
+ CHECK(success);
+ mOwner->writeInt32(samplerate << 16);
+ if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) {
+ writeMp4aEsdsBox();
+ } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mime) ||
+ !strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime)) {
+ writeDamrBox();
+ }
+ mOwner->endBox();
+}
+
+void MPEG4Writer::Track::writeMp4aEsdsBox() {
+ mOwner->beginBox("esds");
+ CHECK(mCodecSpecificData);
+ CHECK(mCodecSpecificDataSize > 0);
+
+ // Make sure all sizes encode to a single byte.
+ CHECK(mCodecSpecificDataSize + 23 < 128);
+
+ mOwner->writeInt32(0); // version=0, flags=0
+ mOwner->writeInt8(0x03); // ES_DescrTag
+ mOwner->writeInt8(23 + mCodecSpecificDataSize);
+ mOwner->writeInt16(0x0000);// ES_ID
+ mOwner->writeInt8(0x00);
+
+ mOwner->writeInt8(0x04); // DecoderConfigDescrTag
+ mOwner->writeInt8(15 + mCodecSpecificDataSize);
+ mOwner->writeInt8(0x40); // objectTypeIndication ISO/IEC 14492-2
+ mOwner->writeInt8(0x15); // streamType AudioStream
+
+ mOwner->writeInt16(0x03); // XXX
+ mOwner->writeInt8(0x00); // buffer size 24-bit
+ mOwner->writeInt32(96000); // max bit rate
+ mOwner->writeInt32(96000); // avg bit rate
+
+ mOwner->writeInt8(0x05); // DecoderSpecificInfoTag
+ mOwner->writeInt8(mCodecSpecificDataSize);
+ mOwner->write(mCodecSpecificData, mCodecSpecificDataSize);
+
+ static const uint8_t kData2[] = {
+ 0x06, // SLConfigDescriptorTag
+ 0x01,
+ 0x02
+ };
+ mOwner->write(kData2, sizeof(kData2));
+
+ mOwner->endBox(); // esds
+}
+
+void MPEG4Writer::Track::writeMp4vEsdsBox() {
+ CHECK(mCodecSpecificData);
+ CHECK(mCodecSpecificDataSize > 0);
+ mOwner->beginBox("esds");
+
+ mOwner->writeInt32(0); // version=0, flags=0
+
+ mOwner->writeInt8(0x03); // ES_DescrTag
+ mOwner->writeInt8(23 + mCodecSpecificDataSize);
+ mOwner->writeInt16(0x0000); // ES_ID
+ mOwner->writeInt8(0x1f);
+
+ mOwner->writeInt8(0x04); // DecoderConfigDescrTag
+ mOwner->writeInt8(15 + mCodecSpecificDataSize);
+ mOwner->writeInt8(0x20); // objectTypeIndication ISO/IEC 14492-2
+ mOwner->writeInt8(0x11); // streamType VisualStream
+
+ static const uint8_t kData[] = {
+ 0x01, 0x77, 0x00,
+ 0x00, 0x03, 0xe8, 0x00,
+ 0x00, 0x03, 0xe8, 0x00
+ };
+ mOwner->write(kData, sizeof(kData));
+
+ mOwner->writeInt8(0x05); // DecoderSpecificInfoTag
+
+ mOwner->writeInt8(mCodecSpecificDataSize);
+ mOwner->write(mCodecSpecificData, mCodecSpecificDataSize);
+
+ static const uint8_t kData2[] = {
+ 0x06, // SLConfigDescriptorTag
+ 0x01,
+ 0x02
+ };
+ mOwner->write(kData2, sizeof(kData2));
+
+ mOwner->endBox(); // esds
+}
+
+void MPEG4Writer::Track::writeTkhdBox(time_t now) {
+ mOwner->beginBox("tkhd");
+ // Flags = 7 to indicate that the track is enabled, and
+ // part of the presentation
+ mOwner->writeInt32(0x07); // version=0, flags=7
+ mOwner->writeInt32(now); // creation time
+ mOwner->writeInt32(now); // modification time
+ mOwner->writeInt32(mTrackId + 1); // track id starts with 1
+ mOwner->writeInt32(0); // reserved
int64_t trakDurationUs = getDurationUs();
+ int32_t mvhdTimeScale = mOwner->getTimeScale();
+ int32_t tkhdDuration =
+ (trakDurationUs * mvhdTimeScale + 5E5) / 1E6;
+ mOwner->writeInt32(tkhdDuration); // in mvhd timescale
+ mOwner->writeInt32(0); // reserved
+ mOwner->writeInt32(0); // reserved
+ mOwner->writeInt16(0); // layer
+ mOwner->writeInt16(0); // alternate group
+ mOwner->writeInt16(mIsAudio ? 0x100 : 0); // volume
+ mOwner->writeInt16(0); // reserved
+
+ mOwner->writeCompositionMatrix(mRotation); // matrix
+
+ if (mIsAudio) {
+ mOwner->writeInt32(0);
+ mOwner->writeInt32(0);
+ } else {
+ int32_t width, height;
+ bool success = mMeta->findInt32(kKeyWidth, &width);
+ success = success && mMeta->findInt32(kKeyHeight, &height);
+ CHECK(success);
+
+ mOwner->writeInt32(width << 16); // 32-bit fixed-point value
+ mOwner->writeInt32(height << 16); // 32-bit fixed-point value
+ }
+ mOwner->endBox(); // tkhd
+}
+
+void MPEG4Writer::Track::writeVmhdBox() {
+ mOwner->beginBox("vmhd");
+ mOwner->writeInt32(0x01); // version=0, flags=1
+ mOwner->writeInt16(0); // graphics mode
+ mOwner->writeInt16(0); // opcolor
+ mOwner->writeInt16(0);
+ mOwner->writeInt16(0);
+ mOwner->endBox();
+}
+
+void MPEG4Writer::Track::writeSmhdBox() {
+ mOwner->beginBox("smhd");
+ mOwner->writeInt32(0); // version=0, flags=0
+ mOwner->writeInt16(0); // balance
+ mOwner->writeInt16(0); // reserved
+ mOwner->endBox();
+}
+
+void MPEG4Writer::Track::writeHdlrBox() {
+ mOwner->beginBox("hdlr");
+ mOwner->writeInt32(0); // version=0, flags=0
+ mOwner->writeInt32(0); // component type: should be mhlr
+ mOwner->writeFourcc(mIsAudio ? "soun" : "vide"); // component subtype
+ mOwner->writeInt32(0); // reserved
+ mOwner->writeInt32(0); // reserved
+ mOwner->writeInt32(0); // reserved
+ // Removing "r" for the name string just makes the string 4 byte aligned
+ mOwner->writeCString(mIsAudio ? "SoundHandle": "VideoHandle"); // name
+ mOwner->endBox();
+}
+
+void MPEG4Writer::Track::writeMdhdBox(time_t now) {
+ int64_t trakDurationUs = getDurationUs();
+ mOwner->beginBox("mdhd");
+ mOwner->writeInt32(0); // version=0, flags=0
+ mOwner->writeInt32(now); // creation time
+ mOwner->writeInt32(now); // modification time
+ mOwner->writeInt32(mTimeScale); // media timescale
+ int32_t mdhdDuration = (trakDurationUs * mTimeScale + 5E5) / 1E6;
+ mOwner->writeInt32(mdhdDuration); // use media timescale
+ // Language follows the three letter standard ISO-639-2/T
+ // 'e', 'n', 'g' for "English", for instance.
+ // Each character is packed as the difference between its ASCII value and 0x60.
+ // For "English", these are 00101, 01110, 00111.
+ // XXX: Where is the padding bit located: 0x15C7?
+ mOwner->writeInt16(0); // language code
+ mOwner->writeInt16(0); // predefined
+ mOwner->endBox();
+}
+
+void MPEG4Writer::Track::writeDamrBox() {
+ // 3gpp2 Spec AMRSampleEntry fields
+ mOwner->beginBox("damr");
+ mOwner->writeCString(" "); // vendor: 4 bytes
+ mOwner->writeInt8(0); // decoder version
+ mOwner->writeInt16(0x83FF); // mode set: all enabled
+ mOwner->writeInt8(0); // mode change period
+ mOwner->writeInt8(1); // frames per sample
+ mOwner->endBox();
+}
+
+void MPEG4Writer::Track::writeUrlBox() {
+ // The table index here refers to the sample description index
+ // in the sample table entries.
+ mOwner->beginBox("url ");
+ mOwner->writeInt32(1); // version=0, flags=1 (self-contained)
+ mOwner->endBox(); // url
+}
+
+void MPEG4Writer::Track::writeDrefBox() {
+ mOwner->beginBox("dref");
+ mOwner->writeInt32(0); // version=0, flags=0
+ mOwner->writeInt32(1); // entry count (either url or urn)
+ writeUrlBox();
+ mOwner->endBox(); // dref
+}
+
+void MPEG4Writer::Track::writeDinfBox() {
+ mOwner->beginBox("dinf");
+ writeDrefBox();
+ mOwner->endBox(); // dinf
+}
+
+void MPEG4Writer::Track::writeAvccBox() {
+ CHECK(mCodecSpecificData);
+ CHECK(mCodecSpecificDataSize >= 5);
+
+ // Patch avcc's lengthSize field to match the number
+ // of bytes we use to indicate the size of a nal unit.
+ uint8_t *ptr = (uint8_t *)mCodecSpecificData;
+ ptr[4] = (ptr[4] & 0xfc) | (mOwner->useNalLengthFour() ? 3 : 1);
+ mOwner->beginBox("avcC");
+ mOwner->write(mCodecSpecificData, mCodecSpecificDataSize);
+ mOwner->endBox(); // avcC
+}
+
+void MPEG4Writer::Track::writeD263Box() {
+ mOwner->beginBox("d263");
+ mOwner->writeInt32(0); // vendor
+ mOwner->writeInt8(0); // decoder version
+ mOwner->writeInt8(10); // level: 10
+ mOwner->writeInt8(0); // profile: 0
+ mOwner->endBox(); // d263
+}
+
+// This is useful if the pixel is not square
+void MPEG4Writer::Track::writePaspBox() {
+ mOwner->beginBox("pasp");
+ mOwner->writeInt32(1 << 16); // hspacing
+ mOwner->writeInt32(1 << 16); // vspacing
+ mOwner->endBox(); // pasp
+}
+
+void MPEG4Writer::Track::writeSttsBox() {
+ mOwner->beginBox("stts");
+ mOwner->writeInt32(0); // version=0, flags=0
+ mOwner->writeInt32(mNumSttsTableEntries);
// Compensate for small start time difference from different media tracks
int64_t trackStartTimeOffsetUs = 0;
+ int64_t moovStartTimeUs = mOwner->getStartTimestampUs();
+ if (mStartTimestampUs != moovStartTimeUs) {
+ CHECK(mStartTimestampUs > moovStartTimeUs);
+ trackStartTimeOffsetUs = mStartTimestampUs - moovStartTimeUs;
+ }
+ List<SttsTableEntry>::iterator it = mSttsTableEntries.begin();
+ CHECK(it != mSttsTableEntries.end() && it->sampleCount == 1);
+ mOwner->writeInt32(it->sampleCount);
+ int32_t dur = (trackStartTimeOffsetUs * mTimeScale + 500000LL) / 1000000LL;
+ mOwner->writeInt32(dur + it->sampleDuration);
- mOwner->beginBox("trak");
+ int64_t totalCount = 1;
+ while (++it != mSttsTableEntries.end()) {
+ mOwner->writeInt32(it->sampleCount);
+ mOwner->writeInt32(it->sampleDuration);
+ totalCount += it->sampleCount;
+ }
+ CHECK(totalCount == mNumSamples);
+ mOwner->endBox(); // stts
+}
- mOwner->beginBox("tkhd");
- // Flags = 7 to indicate that the track is enabled, and
- // part of the presentation
- mOwner->writeInt32(0x07); // version=0, flags=7
- mOwner->writeInt32(now); // creation time
- mOwner->writeInt32(now); // modification time
- mOwner->writeInt32(trackID);
- mOwner->writeInt32(0); // reserved
- int32_t tkhdDuration =
- (trakDurationUs * mvhdTimeScale + 5E5) / 1E6;
- mOwner->writeInt32(tkhdDuration); // in mvhd timescale
- mOwner->writeInt32(0); // reserved
- mOwner->writeInt32(0); // reserved
- mOwner->writeInt16(0); // layer
- mOwner->writeInt16(0); // alternate group
- mOwner->writeInt16(mIsAudio ? 0x100 : 0); // volume
- mOwner->writeInt16(0); // reserved
+void MPEG4Writer::Track::writeCttsBox() {
+ if (mIsAudio) { // ctts is not for audio
+ return;
+ }
- mOwner->writeCompositionMatrix(mRotation); // matrix
+ // Do not write ctts box when there is no need to have it.
+ if ((mNumCttsTableEntries == 1 &&
+ mCttsTableEntries.begin()->sampleDuration == 0) ||
+ mNumCttsTableEntries == 0) {
+ return;
+ }
- if (mIsAudio) {
- mOwner->writeInt32(0);
- mOwner->writeInt32(0);
- } else {
- int32_t width, height;
- bool success = mMeta->findInt32(kKeyWidth, &width);
- success = success && mMeta->findInt32(kKeyHeight, &height);
- CHECK(success);
+ LOGV("ctts box has %d entries", mNumCttsTableEntries);
- mOwner->writeInt32(width << 16); // 32-bit fixed-point value
- mOwner->writeInt32(height << 16); // 32-bit fixed-point value
+ mOwner->beginBox("ctts");
+ if (mHasNegativeCttsDeltaDuration) {
+ mOwner->writeInt32(0x00010000); // version=1, flags=0
+ } else {
+ mOwner->writeInt32(0); // version=0, flags=0
+ }
+ mOwner->writeInt32(mNumCttsTableEntries);
+
+ int64_t totalCount = 0;
+ for (List<CttsTableEntry>::iterator it = mCttsTableEntries.begin();
+ it != mCttsTableEntries.end(); ++it) {
+ mOwner->writeInt32(it->sampleCount);
+ mOwner->writeInt32(it->sampleDuration);
+ totalCount += it->sampleCount;
+ }
+ CHECK(totalCount == mNumSamples);
+ mOwner->endBox(); // ctts
+}
+
+void MPEG4Writer::Track::writeStssBox() {
+ mOwner->beginBox("stss");
+ mOwner->writeInt32(0); // version=0, flags=0
+ mOwner->writeInt32(mNumStssTableEntries); // number of sync frames
+ for (List<int32_t>::iterator it = mStssTableEntries.begin();
+ it != mStssTableEntries.end(); ++it) {
+ mOwner->writeInt32(*it);
+ }
+ mOwner->endBox(); // stss
+}
+
+void MPEG4Writer::Track::writeStszBox() {
+ mOwner->beginBox("stsz");
+ mOwner->writeInt32(0); // version=0, flags=0
+ if (mSamplesHaveSameSize) {
+ List<size_t>::iterator it = mSampleSizes.begin();
+ mOwner->writeInt32(*it); // default sample size
+ } else {
+ mOwner->writeInt32(0);
+ }
+ mOwner->writeInt32(mNumSamples);
+ if (!mSamplesHaveSameSize) {
+ for (List<size_t>::iterator it = mSampleSizes.begin();
+ it != mSampleSizes.end(); ++it) {
+ mOwner->writeInt32(*it);
}
- mOwner->endBox(); // tkhd
+ }
+ mOwner->endBox(); // stsz
+}
- int64_t moovStartTimeUs = mOwner->getStartTimestampUs();
- if (mStartTimestampUs != moovStartTimeUs) {
- CHECK(mStartTimestampUs > moovStartTimeUs);
- trackStartTimeOffsetUs = mStartTimestampUs - moovStartTimeUs;
- }
+void MPEG4Writer::Track::writeStscBox() {
+ mOwner->beginBox("stsc");
+ mOwner->writeInt32(0); // version=0, flags=0
+ mOwner->writeInt32(mNumStscTableEntries);
+ for (List<StscTableEntry>::iterator it = mStscTableEntries.begin();
+ it != mStscTableEntries.end(); ++it) {
+ mOwner->writeInt32(it->firstChunk);
+ mOwner->writeInt32(it->samplesPerChunk);
+ mOwner->writeInt32(it->sampleDescriptionId);
+ }
+ mOwner->endBox(); // stsc
+}
- mOwner->beginBox("mdia");
+void MPEG4Writer::Track::writeStcoBox(bool use32BitOffset) {
+ mOwner->beginBox(use32BitOffset? "stco": "co64");
+ mOwner->writeInt32(0); // version=0, flags=0
+ mOwner->writeInt32(mNumStcoTableEntries);
+ for (List<off64_t>::iterator it = mChunkOffsets.begin();
+ it != mChunkOffsets.end(); ++it) {
+ if (use32BitOffset) {
+ mOwner->writeInt32(static_cast<int32_t>(*it));
+ } else {
+ mOwner->writeInt64((*it));
+ }
+ }
+ mOwner->endBox(); // stco or co64
+}
- mOwner->beginBox("mdhd");
- mOwner->writeInt32(0); // version=0, flags=0
- mOwner->writeInt32(now); // creation time
- mOwner->writeInt32(now); // modification time
- mOwner->writeInt32(mTimeScale); // media timescale
- int32_t mdhdDuration = (trakDurationUs * mTimeScale + 5E5) / 1E6;
- mOwner->writeInt32(mdhdDuration); // use media timescale
- // Language follows the three letter standard ISO-639-2/T
- // 'e', 'n', 'g' for "English", for instance.
- // Each character is packed as the difference between its ASCII value and 0x60.
- // For "English", these are 00101, 01110, 00111.
- // XXX: Where is the padding bit located: 0x15C7?
- mOwner->writeInt16(0); // language code
- mOwner->writeInt16(0); // predefined
- mOwner->endBox();
+void MPEG4Writer::writeUdtaBox() {
+ beginBox("udta");
+ writeGeoDataBox();
+ endBox();
+}
- mOwner->beginBox("hdlr");
- mOwner->writeInt32(0); // version=0, flags=0
- mOwner->writeInt32(0); // component type: should be mhlr
- mOwner->writeFourcc(mIsAudio ? "soun" : "vide"); // component subtype
- mOwner->writeInt32(0); // reserved
- mOwner->writeInt32(0); // reserved
- mOwner->writeInt32(0); // reserved
- // Removing "r" for the name string just makes the string 4 byte aligned
- mOwner->writeCString(mIsAudio ? "SoundHandle": "VideoHandle"); // name
- mOwner->endBox();
-
- mOwner->beginBox("minf");
- if (mIsAudio) {
- mOwner->beginBox("smhd");
- mOwner->writeInt32(0); // version=0, flags=0
- mOwner->writeInt16(0); // balance
- mOwner->writeInt16(0); // reserved
- mOwner->endBox();
- } else {
- mOwner->beginBox("vmhd");
- mOwner->writeInt32(0x01); // version=0, flags=1
- mOwner->writeInt16(0); // graphics mode
- mOwner->writeInt16(0); // opcolor
- mOwner->writeInt16(0);
- mOwner->writeInt16(0);
- mOwner->endBox();
- }
-
- mOwner->beginBox("dinf");
- mOwner->beginBox("dref");
- mOwner->writeInt32(0); // version=0, flags=0
- mOwner->writeInt32(1); // entry count (either url or urn)
- // The table index here refers to the sample description index
- // in the sample table entries.
- mOwner->beginBox("url ");
- mOwner->writeInt32(1); // version=0, flags=1 (self-contained)
- mOwner->endBox(); // url
- mOwner->endBox(); // dref
- mOwner->endBox(); // dinf
-
- mOwner->beginBox("stbl");
-
- mOwner->beginBox("stsd");
- mOwner->writeInt32(0); // version=0, flags=0
- mOwner->writeInt32(1); // entry count
- if (mIsAudio) {
- const char *fourcc = NULL;
- if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mime)) {
- fourcc = "samr";
- } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime)) {
- fourcc = "sawb";
- } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) {
- fourcc = "mp4a";
- } else {
- LOGE("Unknown mime type '%s'.", mime);
- CHECK(!"should not be here, unknown mime type.");
- }
-
- mOwner->beginBox(fourcc); // audio format
- mOwner->writeInt32(0); // reserved
- mOwner->writeInt16(0); // reserved
- mOwner->writeInt16(0x1); // data ref index
- mOwner->writeInt32(0); // reserved
- mOwner->writeInt32(0); // reserved
- int32_t nChannels;
- CHECK_EQ(true, mMeta->findInt32(kKeyChannelCount, &nChannels));
- mOwner->writeInt16(nChannels); // channel count
- mOwner->writeInt16(16); // sample size
- mOwner->writeInt16(0); // predefined
- mOwner->writeInt16(0); // reserved
-
- int32_t samplerate;
- bool success = mMeta->findInt32(kKeySampleRate, &samplerate);
- CHECK(success);
- mOwner->writeInt32(samplerate << 16);
- if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) {
- mOwner->beginBox("esds");
- CHECK(mCodecSpecificData);
- CHECK(mCodecSpecificDataSize > 0);
-
- // Make sure all sizes encode to a single byte.
- CHECK(mCodecSpecificDataSize + 23 < 128);
-
- mOwner->writeInt32(0); // version=0, flags=0
- mOwner->writeInt8(0x03); // ES_DescrTag
- mOwner->writeInt8(23 + mCodecSpecificDataSize);
- mOwner->writeInt16(0x0000);// ES_ID
- mOwner->writeInt8(0x00);
-
- mOwner->writeInt8(0x04); // DecoderConfigDescrTag
- mOwner->writeInt8(15 + mCodecSpecificDataSize);
- mOwner->writeInt8(0x40); // objectTypeIndication ISO/IEC 14492-2
- mOwner->writeInt8(0x15); // streamType AudioStream
-
- mOwner->writeInt16(0x03); // XXX
- mOwner->writeInt8(0x00); // buffer size 24-bit
- mOwner->writeInt32(96000); // max bit rate
- mOwner->writeInt32(96000); // avg bit rate
-
- mOwner->writeInt8(0x05); // DecoderSpecificInfoTag
- mOwner->writeInt8(mCodecSpecificDataSize);
- mOwner->write(mCodecSpecificData, mCodecSpecificDataSize);
-
- static const uint8_t kData2[] = {
- 0x06, // SLConfigDescriptorTag
- 0x01,
- 0x02
- };
- mOwner->write(kData2, sizeof(kData2));
-
- mOwner->endBox(); // esds
- } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mime) ||
- !strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime)) {
- // 3gpp2 Spec AMRSampleEntry fields
- mOwner->beginBox("damr");
- mOwner->writeCString(" "); // vendor: 4 bytes
- mOwner->writeInt8(0); // decoder version
- mOwner->writeInt16(0x83FF); // mode set: all enabled
- mOwner->writeInt8(0); // mode change period
- mOwner->writeInt8(1); // frames per sample
- mOwner->endBox();
- }
- mOwner->endBox();
- } else {
- if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
- mOwner->beginBox("mp4v");
- } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
- mOwner->beginBox("s263");
- } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
- mOwner->beginBox("avc1");
- } else {
- LOGE("Unknown mime type '%s'.", mime);
- CHECK(!"should not be here, unknown mime type.");
- }
-
- mOwner->writeInt32(0); // reserved
- mOwner->writeInt16(0); // reserved
- mOwner->writeInt16(1); // data ref index
- mOwner->writeInt16(0); // predefined
- mOwner->writeInt16(0); // reserved
- mOwner->writeInt32(0); // predefined
- mOwner->writeInt32(0); // predefined
- mOwner->writeInt32(0); // predefined
-
- int32_t width, height;
- bool success = mMeta->findInt32(kKeyWidth, &width);
- success = success && mMeta->findInt32(kKeyHeight, &height);
- CHECK(success);
-
- mOwner->writeInt16(width);
- mOwner->writeInt16(height);
- mOwner->writeInt32(0x480000); // horiz resolution
- mOwner->writeInt32(0x480000); // vert resolution
- mOwner->writeInt32(0); // reserved
- mOwner->writeInt16(1); // frame count
- mOwner->write(" ", 32);
- mOwner->writeInt16(0x18); // depth
- mOwner->writeInt16(-1); // predefined
-
- CHECK(23 + mCodecSpecificDataSize < 128);
-
- if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
- CHECK(mCodecSpecificData);
- CHECK(mCodecSpecificDataSize > 0);
- mOwner->beginBox("esds");
-
- mOwner->writeInt32(0); // version=0, flags=0
-
- mOwner->writeInt8(0x03); // ES_DescrTag
- mOwner->writeInt8(23 + mCodecSpecificDataSize);
- mOwner->writeInt16(0x0000); // ES_ID
- mOwner->writeInt8(0x1f);
-
- mOwner->writeInt8(0x04); // DecoderConfigDescrTag
- mOwner->writeInt8(15 + mCodecSpecificDataSize);
- mOwner->writeInt8(0x20); // objectTypeIndication ISO/IEC 14492-2
- mOwner->writeInt8(0x11); // streamType VisualStream
-
- static const uint8_t kData[] = {
- 0x01, 0x77, 0x00,
- 0x00, 0x03, 0xe8, 0x00,
- 0x00, 0x03, 0xe8, 0x00
- };
- mOwner->write(kData, sizeof(kData));
-
- mOwner->writeInt8(0x05); // DecoderSpecificInfoTag
-
- mOwner->writeInt8(mCodecSpecificDataSize);
- mOwner->write(mCodecSpecificData, mCodecSpecificDataSize);
-
- static const uint8_t kData2[] = {
- 0x06, // SLConfigDescriptorTag
- 0x01,
- 0x02
- };
- mOwner->write(kData2, sizeof(kData2));
-
- mOwner->endBox(); // esds
- } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
- mOwner->beginBox("d263");
-
- mOwner->writeInt32(0); // vendor
- mOwner->writeInt8(0); // decoder version
- mOwner->writeInt8(10); // level: 10
- mOwner->writeInt8(0); // profile: 0
-
- mOwner->endBox(); // d263
- } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
- CHECK(mCodecSpecificData);
- CHECK(mCodecSpecificDataSize >= 5);
-
- // Patch avcc's lengthSize field to match the number
- // of bytes we use to indicate the size of a nal unit.
- uint8_t *ptr = (uint8_t *)mCodecSpecificData;
- ptr[4] =
- (ptr[4] & 0xfc)
- | (mOwner->useNalLengthFour() ? 3 : 1);
-
- mOwner->beginBox("avcC");
- mOwner->write(mCodecSpecificData, mCodecSpecificDataSize);
- mOwner->endBox(); // avcC
- }
-
- mOwner->beginBox("pasp");
- // This is useful if the pixel is not square
- mOwner->writeInt32(1 << 16); // hspacing
- mOwner->writeInt32(1 << 16); // vspacing
- mOwner->endBox(); // pasp
- mOwner->endBox(); // mp4v, s263 or avc1
- }
- mOwner->endBox(); // stsd
-
- mOwner->beginBox("stts");
- mOwner->writeInt32(0); // version=0, flags=0
- mOwner->writeInt32(mNumSttsTableEntries);
- int64_t prevTimestampUs = trackStartTimeOffsetUs;
- for (List<SttsTableEntry>::iterator it = mSttsTableEntries.begin();
- it != mSttsTableEntries.end(); ++it) {
- mOwner->writeInt32(it->sampleCount);
-
- // Make sure that we are calculating the sample duration the exactly
- // same way as we made decision on how to create stts entries.
- int64_t currTimestampUs = prevTimestampUs + it->sampleDurationUs;
- int32_t dur = ((currTimestampUs * mTimeScale + 500000LL) / 1000000LL -
- (prevTimestampUs * mTimeScale + 500000LL) / 1000000LL);
- prevTimestampUs += (it->sampleCount * it->sampleDurationUs);
-
- mOwner->writeInt32(dur);
- }
- mOwner->endBox(); // stts
-
- if (!mIsAudio) {
- mOwner->beginBox("stss");
- mOwner->writeInt32(0); // version=0, flags=0
- mOwner->writeInt32(mNumStssTableEntries); // number of sync frames
- for (List<int32_t>::iterator it = mStssTableEntries.begin();
- it != mStssTableEntries.end(); ++it) {
- mOwner->writeInt32(*it);
- }
- mOwner->endBox(); // stss
- }
-
- mOwner->beginBox("stsz");
- mOwner->writeInt32(0); // version=0, flags=0
- if (mSamplesHaveSameSize) {
- List<size_t>::iterator it = mSampleSizes.begin();
- mOwner->writeInt32(*it); // default sample size
- } else {
- mOwner->writeInt32(0);
- }
- mOwner->writeInt32(mNumSamples);
- if (!mSamplesHaveSameSize) {
- for (List<size_t>::iterator it = mSampleSizes.begin();
- it != mSampleSizes.end(); ++it) {
- mOwner->writeInt32(*it);
- }
- }
- mOwner->endBox(); // stsz
-
- mOwner->beginBox("stsc");
- mOwner->writeInt32(0); // version=0, flags=0
- mOwner->writeInt32(mNumStscTableEntries);
- for (List<StscTableEntry>::iterator it = mStscTableEntries.begin();
- it != mStscTableEntries.end(); ++it) {
- mOwner->writeInt32(it->firstChunk);
- mOwner->writeInt32(it->samplesPerChunk);
- mOwner->writeInt32(it->sampleDescriptionId);
- }
- mOwner->endBox(); // stsc
- mOwner->beginBox(use32BitOffset? "stco": "co64");
- mOwner->writeInt32(0); // version=0, flags=0
- mOwner->writeInt32(mNumStcoTableEntries);
- for (List<off64_t>::iterator it = mChunkOffsets.begin();
- it != mChunkOffsets.end(); ++it) {
- if (use32BitOffset) {
- mOwner->writeInt32(static_cast<int32_t>(*it));
- } else {
- mOwner->writeInt64((*it));
- }
- }
- mOwner->endBox(); // stco or co64
-
- mOwner->endBox(); // stbl
- mOwner->endBox(); // minf
- mOwner->endBox(); // mdia
- mOwner->endBox(); // trak
+/*
+ * Geodata is stored according to ISO-6709 standard.
+ */
+void MPEG4Writer::writeGeoDataBox() {
+ beginBox("\xA9xyz");
+ /*
+ * For historical reasons, any user data start
+ * with "\0xA9", must be followed by its assoicated
+ * language code.
+ * 0x0012: text string length
+ * 0x15c7: lang (locale) code: en
+ */
+ writeInt32(0x001215c7);
+ writeLatitude(mLatitudex10000);
+ writeLongitude(mLongitudex10000);
+ writeInt8(0x2F);
+ endBox();
}
} // namespace android
diff --git a/media/libstagefright/MediaDefs.cpp b/media/libstagefright/MediaDefs.cpp
index 0be7261..01f1fba 100644
--- a/media/libstagefright/MediaDefs.cpp
+++ b/media/libstagefright/MediaDefs.cpp
@@ -24,6 +24,7 @@
const char *MEDIA_MIMETYPE_VIDEO_AVC = "video/avc";
const char *MEDIA_MIMETYPE_VIDEO_MPEG4 = "video/mp4v-es";
const char *MEDIA_MIMETYPE_VIDEO_H263 = "video/3gpp";
+const char *MEDIA_MIMETYPE_VIDEO_MPEG2 = "video/mpeg2";
const char *MEDIA_MIMETYPE_VIDEO_RAW = "video/raw";
const char *MEDIA_MIMETYPE_AUDIO_AMR_NB = "audio/3gpp";
@@ -43,7 +44,10 @@
const char *MEDIA_MIMETYPE_CONTAINER_OGG = "application/ogg";
const char *MEDIA_MIMETYPE_CONTAINER_MATROSKA = "video/x-matroska";
const char *MEDIA_MIMETYPE_CONTAINER_MPEG2TS = "video/mp2ts";
+const char *MEDIA_MIMETYPE_CONTAINER_AVI = "video/avi";
const char *MEDIA_MIMETYPE_CONTAINER_WVM = "video/wvm";
+const char *MEDIA_MIMETYPE_TEXT_3GPP = "text/3gpp-tt";
+
} // namespace android
diff --git a/media/libstagefright/MediaExtractor.cpp b/media/libstagefright/MediaExtractor.cpp
index 23bad5b..a8023df 100644
--- a/media/libstagefright/MediaExtractor.cpp
+++ b/media/libstagefright/MediaExtractor.cpp
@@ -19,6 +19,7 @@
#include <utils/Log.h>
#include "include/AMRExtractor.h"
+#include "include/AVIExtractor.h"
#include "include/MP3Extractor.h"
#include "include/MPEG4Extractor.h"
#include "include/WAVExtractor.h"
@@ -108,13 +109,20 @@
ret = new MatroskaExtractor(source);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2TS)) {
ret = new MPEG2TSExtractor(source);
+ } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_AVI)) {
+ ret = new AVIExtractor(source);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_WVM)) {
ret = new WVMExtractor(source);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC_ADTS)) {
ret = new AACExtractor(source);
}
- if (ret != NULL && isDrm) {
- ret->getMetaData()->setInt32(kKeyIsDRM, 1);
+
+ if (ret != NULL) {
+ if (isDrm) {
+ ret->setDrmFlag(true);
+ } else {
+ ret->setDrmFlag(false);
+ }
}
return ret;
diff --git a/media/libstagefright/NuCachedSource2.cpp b/media/libstagefright/NuCachedSource2.cpp
index 248b678..4edb613 100644
--- a/media/libstagefright/NuCachedSource2.cpp
+++ b/media/libstagefright/NuCachedSource2.cpp
@@ -19,6 +19,7 @@
#include <utils/Log.h>
#include "include/NuCachedSource2.h"
+#include "include/HTTPBase.h"
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
@@ -184,7 +185,8 @@
mFinalStatus(OK),
mLastAccessPos(0),
mFetching(true),
- mLastFetchTimeUs(-1) {
+ mLastFetchTimeUs(-1),
+ mNumRetriesLeft(kMaxNumRetries) {
mLooper->setName("NuCachedSource2");
mLooper->registerHandler(mReflector);
mLooper->start();
@@ -201,6 +203,22 @@
mCache = NULL;
}
+status_t NuCachedSource2::getEstimatedBandwidthKbps(int32_t *kbps) {
+ if (mSource->flags() & kIsHTTPBasedSource) {
+ HTTPBase* source = static_cast<HTTPBase *>(mSource.get());
+ return source->getEstimatedBandwidthKbps(kbps);
+ }
+ return ERROR_UNSUPPORTED;
+}
+
+status_t NuCachedSource2::setCacheStatCollectFreq(int32_t freqMs) {
+ if (mSource->flags() & kIsHTTPBasedSource) {
+ HTTPBase *source = static_cast<HTTPBase *>(mSource.get());
+ return source->setBandwidthStatCollectFreq(freqMs);
+ }
+ return ERROR_UNSUPPORTED;
+}
+
status_t NuCachedSource2::initCheck() const {
return mSource->initCheck();
}
@@ -210,7 +228,9 @@
}
uint32_t NuCachedSource2::flags() {
- return (mSource->flags() & ~kWantsPrefetching) | kIsCachingDataSource;
+ // Remove HTTP related flags since NuCachedSource2 is not HTTP-based.
+ uint32_t flags = mSource->flags() & ~(kWantsPrefetching | kIsHTTPBasedSource);
+ return (flags | kIsCachingDataSource);
}
void NuCachedSource2::onMessageReceived(const sp<AMessage> &msg) {
@@ -235,7 +255,27 @@
void NuCachedSource2::fetchInternal() {
LOGV("fetchInternal");
- CHECK_EQ(mFinalStatus, (status_t)OK);
+ {
+ Mutex::Autolock autoLock(mLock);
+ CHECK(mFinalStatus == OK || mNumRetriesLeft > 0);
+
+ if (mFinalStatus != OK) {
+ --mNumRetriesLeft;
+
+ status_t err =
+ mSource->reconnectAtOffset(mCacheOffset + mCache->totalSize());
+
+ if (err == ERROR_UNSUPPORTED) {
+ mNumRetriesLeft = 0;
+ return;
+ } else if (err != OK) {
+ LOGI("The attempt to reconnect failed, %d retries remaining",
+ mNumRetriesLeft);
+
+ return;
+ }
+ }
+ }
PageCache::Page *page = mCache->acquirePage();
@@ -245,14 +285,23 @@
Mutex::Autolock autoLock(mLock);
if (n < 0) {
- LOGE("source returned error %ld", n);
+ LOGE("source returned error %ld, %d retries left", n, mNumRetriesLeft);
mFinalStatus = n;
mCache->releasePage(page);
} else if (n == 0) {
LOGI("ERROR_END_OF_STREAM");
+
+ mNumRetriesLeft = 0;
mFinalStatus = ERROR_END_OF_STREAM;
+
mCache->releasePage(page);
} else {
+ if (mFinalStatus != OK) {
+ LOGI("retrying a previously failed read succeeded.");
+ }
+ mNumRetriesLeft = kMaxNumRetries;
+ mFinalStatus = OK;
+
page->mSize = n;
mCache->appendPage(page);
}
@@ -261,7 +310,7 @@
void NuCachedSource2::onFetch() {
LOGV("onFetch");
- if (mFinalStatus != OK) {
+ if (mFinalStatus != OK && mNumRetriesLeft == 0) {
LOGV("EOS reached, done prefetching for now");
mFetching = false;
}
@@ -289,8 +338,19 @@
restartPrefetcherIfNecessary_l();
}
- (new AMessage(kWhatFetchMore, mReflector->id()))->post(
- mFetching ? 0 : 100000ll);
+ int64_t delayUs;
+ if (mFetching) {
+ if (mFinalStatus != OK && mNumRetriesLeft > 0) {
+ // We failed this time and will try again in 3 seconds.
+ delayUs = 3000000ll;
+ } else {
+ delayUs = 0;
+ }
+ } else {
+ delayUs = 100000ll;
+ }
+
+ (new AMessage(kWhatFetchMore, mReflector->id()))->post(delayUs);
}
void NuCachedSource2::onRead(const sp<AMessage> &msg) {
@@ -323,25 +383,28 @@
}
void NuCachedSource2::restartPrefetcherIfNecessary_l(
- bool ignoreLowWaterThreshold) {
+ bool ignoreLowWaterThreshold, bool force) {
static const size_t kGrayArea = 1024 * 1024;
- if (mFetching || mFinalStatus != OK) {
+ if (mFetching || (mFinalStatus != OK && mNumRetriesLeft == 0)) {
return;
}
- if (!ignoreLowWaterThreshold
+ if (!ignoreLowWaterThreshold && !force
&& mCacheOffset + mCache->totalSize() - mLastAccessPos
>= kLowWaterThreshold) {
return;
}
size_t maxBytes = mLastAccessPos - mCacheOffset;
- if (maxBytes < kGrayArea) {
- return;
- }
- maxBytes -= kGrayArea;
+ if (!force) {
+ if (maxBytes < kGrayArea) {
+ return;
+ }
+
+ maxBytes -= kGrayArea;
+ }
size_t actualBytes = mCache->releaseFromStart(maxBytes);
mCacheOffset += actualBytes;
@@ -405,6 +468,12 @@
size_t NuCachedSource2::approxDataRemaining_l(status_t *finalStatus) {
*finalStatus = mFinalStatus;
+
+ if (mFinalStatus != OK && mNumRetriesLeft > 0) {
+ // Pretend that everything is fine until we're out of retries.
+ *finalStatus = OK;
+ }
+
off64_t lastBytePosCached = mCacheOffset + mCache->totalSize();
if (mLastAccessPos < lastBytePosCached) {
return lastBytePosCached - mLastAccessPos;
@@ -413,10 +482,19 @@
}
ssize_t NuCachedSource2::readInternal(off64_t offset, void *data, size_t size) {
+ CHECK_LE(size, (size_t)kHighWaterThreshold);
+
LOGV("readInternal offset %lld size %d", offset, size);
Mutex::Autolock autoLock(mLock);
+ if (!mFetching) {
+ mLastAccessPos = offset;
+ restartPrefetcherIfNecessary_l(
+ false, // ignoreLowWaterThreshold
+ true); // force
+ }
+
if (offset < mCacheOffset
|| offset >= (off64_t)(mCacheOffset + mCache->totalSize())) {
static const off64_t kPadding = 256 * 1024;
@@ -438,6 +516,11 @@
}
size_t avail = mCache->totalSize() - delta;
+
+ if (avail > size) {
+ avail = size;
+ }
+
mCache->copy(delta, data, avail);
return avail;
@@ -481,11 +564,11 @@
restartPrefetcherIfNecessary_l(true /* ignore low water threshold */);
}
-DecryptHandle* NuCachedSource2::DrmInitialization() {
+sp<DecryptHandle> NuCachedSource2::DrmInitialization() {
return mSource->DrmInitialization();
}
-void NuCachedSource2::getDrmInfo(DecryptHandle **handle, DrmManagerClient **client) {
+void NuCachedSource2::getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client) {
mSource->getDrmInfo(handle, client);
}
@@ -493,4 +576,8 @@
return mSource->getUri();
}
+String8 NuCachedSource2::getMIMEType() const {
+ return mSource->getMIMEType();
+}
+
} // namespace android
diff --git a/media/libstagefright/NuHTTPDataSource.cpp b/media/libstagefright/NuHTTPDataSource.cpp
deleted file mode 100644
index bee0d5e..0000000
--- a/media/libstagefright/NuHTTPDataSource.cpp
+++ /dev/null
@@ -1,574 +0,0 @@
-/*
- * Copyright (C) 2010 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 "NuHTTPDataSource"
-#include <utils/Log.h>
-
-#include "include/NuHTTPDataSource.h"
-
-#include <cutils/properties.h>
-#include <media/stagefright/foundation/ALooper.h>
-#include <media/stagefright/MediaDebug.h>
-#include <media/stagefright/MediaErrors.h>
-
-namespace android {
-
-static bool ParseSingleUnsignedLong(
- const char *from, unsigned long *x) {
- char *end;
- *x = strtoul(from, &end, 10);
-
- if (end == from || *end != '\0') {
- return false;
- }
-
- return true;
-}
-
-static bool ParseURL(
- const char *url, String8 *host, unsigned *port,
- String8 *path, bool *https) {
- host->setTo("");
- *port = 0;
- path->setTo("");
-
- size_t hostStart;
- if (!strncasecmp("http://", url, 7)) {
- hostStart = 7;
- *https = false;
- } else if (!strncasecmp("https://", url, 8)) {
- hostStart = 8;
- *https = true;
- } else {
- return false;
- }
-
- const char *slashPos = strchr(&url[hostStart], '/');
-
- if (slashPos == NULL) {
- host->setTo(&url[hostStart]);
- path->setTo("/");
- } else {
- host->setTo(&url[hostStart], slashPos - &url[hostStart]);
- path->setTo(slashPos);
- }
-
- const char *colonPos = strchr(host->string(), ':');
-
- if (colonPos != NULL) {
- unsigned long x;
- if (!ParseSingleUnsignedLong(colonPos + 1, &x) || x >= 65536) {
- return false;
- }
-
- *port = x;
-
- size_t colonOffset = colonPos - host->string();
- String8 tmp(host->string(), colonOffset);
- *host = tmp;
- } else {
- *port = (*https) ? 443 : 80;
- }
-
- return true;
-}
-
-NuHTTPDataSource::NuHTTPDataSource(uint32_t flags)
- : mFlags(flags),
- mState(DISCONNECTED),
- mPort(0),
- mHTTPS(false),
- mOffset(0),
- mContentLength(0),
- mContentLengthValid(false),
- mHasChunkedTransferEncoding(false),
- mChunkDataBytesLeft(0),
- mNumBandwidthHistoryItems(0),
- mTotalTransferTimeUs(0),
- mTotalTransferBytes(0),
- mDecryptHandle(NULL),
- mDrmManagerClient(NULL) {
-}
-
-NuHTTPDataSource::~NuHTTPDataSource() {
- if (mDecryptHandle != NULL) {
- // To release mDecryptHandle
- CHECK(mDrmManagerClient);
- mDrmManagerClient->closeDecryptSession(mDecryptHandle);
- mDecryptHandle = NULL;
- }
-
- if (mDrmManagerClient != NULL) {
- delete mDrmManagerClient;
- mDrmManagerClient = NULL;
- }
-}
-
-status_t NuHTTPDataSource::connect(
- const char *uri,
- const KeyedVector<String8, String8> *overrides,
- off64_t offset) {
- String8 headers;
- MakeFullHeaders(overrides, &headers);
-
- return connect(uri, headers, offset);
-}
-
-status_t NuHTTPDataSource::connect(
- const char *uri,
- const String8 &headers,
- off64_t offset) {
- String8 host, path;
- unsigned port;
-
- mUri = uri;
-
- bool https;
- if (!ParseURL(uri, &host, &port, &path, &https)) {
- return ERROR_MALFORMED;
- }
-
- return connect(host, port, path, https, headers, offset);
-}
-
-static bool IsRedirectStatusCode(int httpStatus) {
- return httpStatus == 301 || httpStatus == 302
- || httpStatus == 303 || httpStatus == 307;
-}
-
-status_t NuHTTPDataSource::connect(
- const char *host, unsigned port, const char *path,
- bool https,
- const String8 &headers,
- off64_t offset) {
- if (!(mFlags & kFlagIncognito)) {
- LOGI("connect to %s:%u%s @%lld", host, port, path, offset);
- } else {
- LOGI("connect to <URL suppressed> @%lld", offset);
- }
-
- bool needsToReconnect = true;
-
- if (mState == CONNECTED && host == mHost && port == mPort
- && https == mHTTPS && offset == mOffset) {
- if (mContentLengthValid && mOffset == mContentLength) {
- LOGI("Didn't have to reconnect, old one's still good.");
- needsToReconnect = false;
- }
- }
-
- mHost = host;
- mPort = port;
- mPath = path;
- mHTTPS = https;
- mHeaders = headers;
-
- status_t err = OK;
-
- mState = CONNECTING;
-
- if (needsToReconnect) {
- mHTTP.disconnect();
- err = mHTTP.connect(host, port, https);
- }
-
- if (err != OK) {
- mState = DISCONNECTED;
- } else if (mState != CONNECTING) {
- err = UNKNOWN_ERROR;
- } else {
- mState = CONNECTED;
-
- mOffset = offset;
- mContentLength = 0;
- mContentLengthValid = false;
-
- String8 request("GET ");
- request.append(mPath);
- request.append(" HTTP/1.1\r\n");
- request.append("Host: ");
- request.append(mHost);
- if (mPort != 80) {
- request.append(StringPrintf(":%u", mPort).c_str());
- }
- request.append("\r\n");
-
- if (offset != 0) {
- char rangeHeader[128];
- sprintf(rangeHeader, "Range: bytes=%lld-\r\n", offset);
- request.append(rangeHeader);
- }
-
- request.append(mHeaders);
- request.append("\r\n");
-
- int httpStatus;
- if ((err = mHTTP.send(request.string(), request.size())) != OK
- || (err = mHTTP.receive_header(&httpStatus)) != OK) {
- mHTTP.disconnect();
- mState = DISCONNECTED;
- return err;
- }
-
- if (IsRedirectStatusCode(httpStatus)) {
- AString value;
- CHECK(mHTTP.find_header_value("Location", &value));
-
- mState = DISCONNECTED;
-
- mHTTP.disconnect();
-
- return connect(value.c_str(), headers, offset);
- }
-
- if (httpStatus < 200 || httpStatus >= 300) {
- mState = DISCONNECTED;
- mHTTP.disconnect();
-
- return ERROR_IO;
- }
-
- mHasChunkedTransferEncoding = false;
-
- {
- AString value;
- if (mHTTP.find_header_value("Transfer-Encoding", &value)) {
- // We don't currently support any transfer encodings but
- // chunked.
-
- if (!strcasecmp(value.c_str(), "chunked")) {
- LOGI("Chunked transfer encoding applied.");
- mHasChunkedTransferEncoding = true;
- mChunkDataBytesLeft = 0;
- } else {
- mState = DISCONNECTED;
- mHTTP.disconnect();
-
- LOGE("We don't support '%s' transfer encoding.", value.c_str());
-
- return ERROR_UNSUPPORTED;
- }
- }
- }
-
- applyTimeoutResponse();
-
- if (offset == 0) {
- AString value;
- unsigned long x;
- if (mHTTP.find_header_value(AString("Content-Length"), &value)
- && ParseSingleUnsignedLong(value.c_str(), &x)) {
- mContentLength = (off64_t)x;
- mContentLengthValid = true;
- } else {
- LOGW("Server did not give us the content length!");
- }
- } else {
- if (httpStatus != 206 /* Partial Content */) {
- // We requested a range but the server didn't support that.
- LOGE("We requested a range but the server didn't "
- "support that.");
- return ERROR_UNSUPPORTED;
- }
-
- AString value;
- unsigned long x;
- if (mHTTP.find_header_value(AString("Content-Range"), &value)) {
- const char *slashPos = strchr(value.c_str(), '/');
- if (slashPos != NULL
- && ParseSingleUnsignedLong(slashPos + 1, &x)) {
- mContentLength = x;
- mContentLengthValid = true;
- }
- }
- }
- }
-
- return err;
-}
-
-void NuHTTPDataSource::disconnect() {
- if (mState == CONNECTING || mState == CONNECTED) {
- mHTTP.disconnect();
- }
- mState = DISCONNECTED;
-}
-
-status_t NuHTTPDataSource::initCheck() const {
- return mState == CONNECTED ? OK : NO_INIT;
-}
-
-ssize_t NuHTTPDataSource::internalRead(void *data, size_t size) {
- if (!mHasChunkedTransferEncoding) {
- return mHTTP.receive(data, size);
- }
-
- if (mChunkDataBytesLeft < 0) {
- return 0;
- } else if (mChunkDataBytesLeft == 0) {
- char line[1024];
- status_t err = mHTTP.receive_line(line, sizeof(line));
-
- if (err != OK) {
- return err;
- }
-
- LOGV("line = '%s'", line);
-
- char *end;
- unsigned long n = strtoul(line, &end, 16);
-
- if (end == line || (*end != ';' && *end != '\0')) {
- LOGE("malformed HTTP chunk '%s'", line);
- return ERROR_MALFORMED;
- }
-
- mChunkDataBytesLeft = n;
- LOGV("chunk data size = %lu", n);
-
- if (mChunkDataBytesLeft == 0) {
- mChunkDataBytesLeft = -1;
- return 0;
- }
-
- // fall through
- }
-
- if (size > (size_t)mChunkDataBytesLeft) {
- size = mChunkDataBytesLeft;
- }
-
- ssize_t n = mHTTP.receive(data, size);
-
- if (n < 0) {
- return n;
- }
-
- mChunkDataBytesLeft -= (size_t)n;
-
- if (mChunkDataBytesLeft == 0) {
- char line[1024];
- status_t err = mHTTP.receive_line(line, sizeof(line));
-
- if (err != OK) {
- return err;
- }
-
- if (line[0] != '\0') {
- LOGE("missing HTTP chunk terminator.");
- return ERROR_MALFORMED;
- }
- }
-
- return n;
-}
-
-ssize_t NuHTTPDataSource::readAt(off64_t offset, void *data, size_t size) {
- LOGV("readAt offset %ld, size %d", offset, size);
-
- Mutex::Autolock autoLock(mLock);
-
- if (offset != mOffset) {
- String8 host = mHost;
- String8 path = mPath;
- String8 headers = mHeaders;
- status_t err = connect(host, mPort, path, mHTTPS, headers, offset);
-
- if (err != OK) {
- return err;
- }
- }
-
- if (mContentLengthValid) {
- size_t avail =
- (offset >= mContentLength) ? 0 : mContentLength - offset;
-
- if (size > avail) {
- size = avail;
- }
- }
-
- size_t numBytesRead = 0;
- while (numBytesRead < size) {
- int64_t startTimeUs = ALooper::GetNowUs();
-
- ssize_t n =
- internalRead((uint8_t *)data + numBytesRead, size - numBytesRead);
-
- if (n < 0) {
- if (numBytesRead == 0 || mContentLengthValid) {
- return n;
- }
-
- // If there was an error we want to at least return the data
- // we've already successfully read. The next call to read will
- // then return the error.
- n = 0;
- }
-
- int64_t delayUs = ALooper::GetNowUs() - startTimeUs;
- addBandwidthMeasurement_l(n, delayUs);
-
- numBytesRead += (size_t)n;
-
- if (n == 0) {
- if (mContentLengthValid) {
- // We know the content length and made sure not to read beyond
- // it and yet the server closed the connection on us.
- return ERROR_IO;
- }
-
- break;
- }
- }
-
- mOffset += numBytesRead;
-
- return numBytesRead;
-}
-
-status_t NuHTTPDataSource::getSize(off64_t *size) {
- *size = 0;
-
- if (mState != CONNECTED) {
- return ERROR_IO;
- }
-
- if (mContentLengthValid) {
- *size = mContentLength;
- return OK;
- }
-
- return ERROR_UNSUPPORTED;
-}
-
-uint32_t NuHTTPDataSource::flags() {
- return kWantsPrefetching;
-}
-
-// static
-void NuHTTPDataSource::MakeFullHeaders(
- const KeyedVector<String8, String8> *overrides, String8 *headers) {
- headers->setTo("");
-
- headers->append("User-Agent: stagefright/1.1 (Linux;Android ");
-
-#if (PROPERTY_VALUE_MAX < 8)
-#error "PROPERTY_VALUE_MAX must be at least 8"
-#endif
-
- char value[PROPERTY_VALUE_MAX];
- property_get("ro.build.version.release", value, "Unknown");
- headers->append(value);
- headers->append(")\r\n");
-
- if (overrides == NULL) {
- return;
- }
-
- for (size_t i = 0; i < overrides->size(); ++i) {
- String8 line;
- line.append(overrides->keyAt(i));
- line.append(": ");
- line.append(overrides->valueAt(i));
- line.append("\r\n");
-
- headers->append(line);
- }
-}
-
-void NuHTTPDataSource::applyTimeoutResponse() {
- AString timeout;
- if (mHTTP.find_header_value("X-SocketTimeout", &timeout)) {
- const char *s = timeout.c_str();
- char *end;
- long tmp = strtol(s, &end, 10);
- if (end == s || *end != '\0') {
- LOGW("Illegal X-SocketTimeout value given.");
- return;
- }
-
- LOGI("overriding default timeout, new timeout is %ld seconds", tmp);
- mHTTP.setReceiveTimeout(tmp);
- }
-}
-
-bool NuHTTPDataSource::estimateBandwidth(int32_t *bandwidth_bps) {
- Mutex::Autolock autoLock(mLock);
-
- if (mNumBandwidthHistoryItems < 2) {
- return false;
- }
-
- *bandwidth_bps = ((double)mTotalTransferBytes * 8E6 / mTotalTransferTimeUs);
-
- return true;
-}
-
-void NuHTTPDataSource::addBandwidthMeasurement_l(
- size_t numBytes, int64_t delayUs) {
- BandwidthEntry entry;
- entry.mDelayUs = delayUs;
- entry.mNumBytes = numBytes;
- mTotalTransferTimeUs += delayUs;
- mTotalTransferBytes += numBytes;
-
- mBandwidthHistory.push_back(entry);
- if (++mNumBandwidthHistoryItems > 100) {
- BandwidthEntry *entry = &*mBandwidthHistory.begin();
- mTotalTransferTimeUs -= entry->mDelayUs;
- mTotalTransferBytes -= entry->mNumBytes;
- mBandwidthHistory.erase(mBandwidthHistory.begin());
- --mNumBandwidthHistoryItems;
- }
-}
-
-DecryptHandle* NuHTTPDataSource::DrmInitialization() {
- if (mDrmManagerClient == NULL) {
- mDrmManagerClient = new DrmManagerClient();
- }
-
- if (mDrmManagerClient == NULL) {
- return NULL;
- }
-
- if (mDecryptHandle == NULL) {
- /* Note if redirect occurs, mUri is the redirect uri instead of the
- * original one
- */
- mDecryptHandle = mDrmManagerClient->openDecryptSession(mUri);
- }
-
- if (mDecryptHandle == NULL) {
- delete mDrmManagerClient;
- mDrmManagerClient = NULL;
- }
-
- return mDecryptHandle;
-}
-
-void NuHTTPDataSource::getDrmInfo(DecryptHandle **handle, DrmManagerClient **client) {
- *handle = mDecryptHandle;
-
- *client = mDrmManagerClient;
-}
-
-String8 NuHTTPDataSource::getUri() {
- return mUri;
-}
-
-} // namespace android
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
old mode 100644
new mode 100755
index e96ce28..a4f3922
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -18,20 +18,11 @@
#define LOG_TAG "OMXCodec"
#include <utils/Log.h>
-#include "include/AACDecoder.h"
#include "include/AACEncoder.h"
-#include "include/AMRNBDecoder.h"
#include "include/AMRNBEncoder.h"
-#include "include/AMRWBDecoder.h"
#include "include/AMRWBEncoder.h"
-#include "include/AVCDecoder.h"
#include "include/AVCEncoder.h"
-#include "include/G711Decoder.h"
-#include "include/M4vH263Decoder.h"
#include "include/M4vH263Encoder.h"
-#include "include/MP3Decoder.h"
-#include "include/VorbisDecoder.h"
-#include "include/VPXDecoder.h"
#include "include/ESDS.h"
@@ -53,23 +44,19 @@
#include <OMX_Audio.h>
#include <OMX_Component.h>
-#include "include/ThreadedSource.h"
#include "include/avc_utils.h"
namespace android {
-static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00;
+// Treat time out as an error if we have not received any output
+// buffers after 3 seconds.
+const static int64_t kBufferFilledEventTimeOutUs = 3000000000LL;
struct CodecInfo {
const char *mime;
const char *codec;
};
-#define FACTORY_CREATE(name) \
-static sp<MediaSource> Make##name(const sp<MediaSource> &source) { \
- return new name(source); \
-}
-
#define FACTORY_CREATE_ENCODER(name) \
static sp<MediaSource> Make##name(const sp<MediaSource> &source, const sp<MetaData> &meta) { \
return new name(source, meta); \
@@ -77,15 +64,6 @@
#define FACTORY_REF(name) { #name, Make##name },
-FACTORY_CREATE(MP3Decoder)
-FACTORY_CREATE(AMRNBDecoder)
-FACTORY_CREATE(AMRWBDecoder)
-FACTORY_CREATE(AACDecoder)
-FACTORY_CREATE(AVCDecoder)
-FACTORY_CREATE(G711Decoder)
-FACTORY_CREATE(M4vH263Decoder)
-FACTORY_CREATE(VorbisDecoder)
-FACTORY_CREATE(VPXDecoder)
FACTORY_CREATE_ENCODER(AMRNBEncoder)
FACTORY_CREATE_ENCODER(AMRWBEncoder)
FACTORY_CREATE_ENCODER(AACEncoder)
@@ -117,76 +95,48 @@
return NULL;
}
-static sp<MediaSource> InstantiateSoftwareCodec(
- const char *name, const sp<MediaSource> &source) {
- struct FactoryInfo {
- const char *name;
- sp<MediaSource> (*CreateFunc)(const sp<MediaSource> &);
- };
-
- static const FactoryInfo kFactoryInfo[] = {
- FACTORY_REF(MP3Decoder)
- FACTORY_REF(AMRNBDecoder)
- FACTORY_REF(AMRWBDecoder)
- FACTORY_REF(AACDecoder)
- FACTORY_REF(AVCDecoder)
- FACTORY_REF(G711Decoder)
- FACTORY_REF(M4vH263Decoder)
- FACTORY_REF(VorbisDecoder)
- FACTORY_REF(VPXDecoder)
- };
- for (size_t i = 0;
- i < sizeof(kFactoryInfo) / sizeof(kFactoryInfo[0]); ++i) {
- if (!strcmp(name, kFactoryInfo[i].name)) {
- if (!strcmp(name, "VPXDecoder")) {
- return new ThreadedSource(
- (*kFactoryInfo[i].CreateFunc)(source));
- }
- return (*kFactoryInfo[i].CreateFunc)(source);
- }
- }
-
- return NULL;
-}
-
#undef FACTORY_REF
#undef FACTORY_CREATE
static const CodecInfo kDecoderInfo[] = {
{ MEDIA_MIMETYPE_IMAGE_JPEG, "OMX.TI.JPEG.decode" },
-// { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.Nvidia.mp3.decoder" },
// { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.TI.MP3.decode" },
- { MEDIA_MIMETYPE_AUDIO_MPEG, "MP3Decoder" },
+ { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.google.mp3.decoder" },
// { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.decode" },
// { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.Nvidia.amr.decoder" },
- { MEDIA_MIMETYPE_AUDIO_AMR_NB, "AMRNBDecoder" },
+ { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.google.amrnb.decoder" },
// { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.Nvidia.amrwb.decoder" },
{ MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.decode" },
- { MEDIA_MIMETYPE_AUDIO_AMR_WB, "AMRWBDecoder" },
+ { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.google.amrwb.decoder" },
// { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.Nvidia.aac.decoder" },
{ MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.decode" },
- { MEDIA_MIMETYPE_AUDIO_AAC, "AACDecoder" },
- { MEDIA_MIMETYPE_AUDIO_G711_ALAW, "G711Decoder" },
- { MEDIA_MIMETYPE_AUDIO_G711_MLAW, "G711Decoder" },
+ { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.google.aac.decoder" },
+ { MEDIA_MIMETYPE_AUDIO_G711_ALAW, "OMX.google.g711.alaw.decoder" },
+ { MEDIA_MIMETYPE_AUDIO_G711_MLAW, "OMX.google.g711.mlaw.decoder" },
+ { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.DUCATI1.VIDEO.DECODER" },
{ MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.Nvidia.mp4.decode" },
{ MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.7x30.video.decoder.mpeg4" },
{ MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.decoder.mpeg4" },
{ MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.Decoder" },
{ MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.SEC.MPEG4.Decoder" },
- { MEDIA_MIMETYPE_VIDEO_MPEG4, "M4vH263Decoder" },
+ { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.google.mpeg4.decoder" },
+ { MEDIA_MIMETYPE_VIDEO_H263, "OMX.TI.DUCATI1.VIDEO.DECODER" },
{ MEDIA_MIMETYPE_VIDEO_H263, "OMX.Nvidia.h263.decode" },
{ MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.7x30.video.decoder.h263" },
{ MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.decoder.h263" },
{ MEDIA_MIMETYPE_VIDEO_H263, "OMX.SEC.H263.Decoder" },
- { MEDIA_MIMETYPE_VIDEO_H263, "M4vH263Decoder" },
+ { MEDIA_MIMETYPE_VIDEO_H263, "OMX.google.h263.decoder" },
+ { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.DUCATI1.VIDEO.DECODER" },
{ MEDIA_MIMETYPE_VIDEO_AVC, "OMX.Nvidia.h264.decode" },
{ MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.7x30.video.decoder.avc" },
{ MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.video.decoder.avc" },
{ MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.Decoder" },
{ MEDIA_MIMETYPE_VIDEO_AVC, "OMX.SEC.AVC.Decoder" },
- { MEDIA_MIMETYPE_VIDEO_AVC, "AVCDecoder" },
- { MEDIA_MIMETYPE_AUDIO_VORBIS, "VorbisDecoder" },
- { MEDIA_MIMETYPE_VIDEO_VPX, "VPXDecoder" },
+ { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.google.h264.decoder" },
+ { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.google.avc.decoder" },
+ { MEDIA_MIMETYPE_AUDIO_VORBIS, "OMX.google.vorbis.decoder" },
+ { MEDIA_MIMETYPE_VIDEO_VPX, "OMX.google.vpx.decoder" },
+ { MEDIA_MIMETYPE_VIDEO_MPEG2, "OMX.Nvidia.mpeg2v.decode" },
};
static const CodecInfo kEncoderInfo[] = {
@@ -196,18 +146,21 @@
{ MEDIA_MIMETYPE_AUDIO_AMR_WB, "AMRWBEncoder" },
{ MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.encode" },
{ MEDIA_MIMETYPE_AUDIO_AAC, "AACEncoder" },
+ { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.DUCATI1.VIDEO.MPEG4E" },
{ MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.7x30.video.encoder.mpeg4" },
{ MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.encoder.mpeg4" },
{ MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.encoder" },
{ MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.Nvidia.mp4.encoder" },
{ MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.SEC.MPEG4.Encoder" },
{ MEDIA_MIMETYPE_VIDEO_MPEG4, "M4vH263Encoder" },
+ { MEDIA_MIMETYPE_VIDEO_H263, "OMX.TI.DUCATI1.VIDEO.MPEG4E" },
{ MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.7x30.video.encoder.h263" },
{ MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.encoder.h263" },
{ MEDIA_MIMETYPE_VIDEO_H263, "OMX.TI.Video.encoder" },
{ MEDIA_MIMETYPE_VIDEO_H263, "OMX.Nvidia.h263.encoder" },
{ MEDIA_MIMETYPE_VIDEO_H263, "OMX.SEC.H263.Encoder" },
{ MEDIA_MIMETYPE_VIDEO_H263, "M4vH263Encoder" },
+ { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.DUCATI1.VIDEO.H264E" },
{ MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.7x30.video.encoder.avc" },
{ MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.video.encoder.avc" },
{ MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.encoder" },
@@ -277,6 +230,10 @@
}
static bool IsSoftwareCodec(const char *componentName) {
+ if (!strncmp("OMX.google.", componentName, 11)) {
+ return true;
+ }
+
if (!strncmp("OMX.", componentName, 4)) {
return false;
}
@@ -284,26 +241,29 @@
return true;
}
-// A sort order in which non-OMX components are first,
-// followed by software codecs, and followed by all the others.
+// A sort order in which OMX software codecs are first, followed
+// by other (non-OMX) software codecs, followed by everything else.
static int CompareSoftwareCodecsFirst(
const String8 *elem1, const String8 *elem2) {
- bool isNotOMX1 = strncmp(elem1->string(), "OMX.", 4);
- bool isNotOMX2 = strncmp(elem2->string(), "OMX.", 4);
-
- if (isNotOMX1) {
- if (isNotOMX2) { return 0; }
- return -1;
- }
- if (isNotOMX2) {
- return 1;
- }
+ bool isOMX1 = !strncmp(elem1->string(), "OMX.", 4);
+ bool isOMX2 = !strncmp(elem2->string(), "OMX.", 4);
bool isSoftwareCodec1 = IsSoftwareCodec(elem1->string());
bool isSoftwareCodec2 = IsSoftwareCodec(elem2->string());
if (isSoftwareCodec1) {
- if (isSoftwareCodec2) { return 0; }
+ if (!isSoftwareCodec2) { return -1; }
+
+ if (isOMX1) {
+ if (isOMX2) { return 0; }
+
+ return -1;
+ } else {
+ if (isOMX2) { return 0; }
+
+ return 1;
+ }
+
return -1;
}
@@ -361,7 +321,20 @@
quirks |= kDefersOutputBufferAllocation;
}
- if (!strncmp(componentName, "OMX.TI.", 7)) {
+ if (!strcmp(componentName, "OMX.TI.DUCATI1.VIDEO.DECODER")) {
+ quirks |= kRequiresAllocateBufferOnInputPorts;
+ quirks |= kRequiresAllocateBufferOnOutputPorts;
+ }
+
+ // FIXME:
+ // Remove the quirks after the work is done.
+ else if (!strcmp(componentName, "OMX.TI.DUCATI1.VIDEO.MPEG4E") ||
+ !strcmp(componentName, "OMX.TI.DUCATI1.VIDEO.H264E")) {
+
+ quirks |= kRequiresAllocateBufferOnInputPorts;
+ quirks |= kRequiresAllocateBufferOnOutputPorts;
+ }
+ else if (!strncmp(componentName, "OMX.TI.", 7)) {
// Apparently I must not use OMX_UseBuffer on either input or
// output ports on any of the TI components or quote:
// "(I) may have unexpected problem (sic) which can be timing related
@@ -445,6 +418,15 @@
const char *matchComponentName,
uint32_t flags,
const sp<ANativeWindow> &nativeWindow) {
+ int32_t requiresSecureBuffers;
+ if (source->getFormat()->findInt32(
+ kKeyRequiresSecureBuffers,
+ &requiresSecureBuffers)
+ && requiresSecureBuffers) {
+ flags |= kIgnoreCodecSpecificData;
+ flags |= kUseSecureInputBuffers;
+ }
+
const char *mime;
bool success = meta->findCString(kKeyMIMEType, &mime);
CHECK(success);
@@ -464,14 +446,15 @@
for (size_t i = 0; i < matchingCodecs.size(); ++i) {
componentName = matchingCodecs[i].string();
- sp<MediaSource> softwareCodec = createEncoder?
- InstantiateSoftwareEncoder(componentName, source, meta):
- InstantiateSoftwareCodec(componentName, source);
+ if (createEncoder) {
+ sp<MediaSource> softwareCodec =
+ InstantiateSoftwareEncoder(componentName, source, meta);
- if (softwareCodec != NULL) {
- LOGV("Successfully allocated software codec '%s'", componentName);
+ if (softwareCodec != NULL) {
+ LOGV("Successfully allocated software codec '%s'", componentName);
- return softwareCodec;
+ return softwareCodec;
+ }
}
LOGV("Attempting to allocate OMX node '%s'", componentName);
@@ -498,15 +481,19 @@
LOGV("Successfully allocated OMX node '%s'", componentName);
sp<OMXCodec> codec = new OMXCodec(
- omx, node, quirks,
+ omx, node, quirks, flags,
createEncoder, mime, componentName,
source, nativeWindow);
observer->setCodec(codec);
- err = codec->configureCodec(meta, flags);
+ err = codec->configureCodec(meta);
if (err == OK) {
+ if (!strcmp("OMX.Nvidia.mpeg2v.decode", componentName)) {
+ codec->mFlags |= kOnlySubmitOneInputBufferAtOneTime;
+ }
+
return codec;
}
@@ -517,24 +504,11 @@
return NULL;
}
-status_t OMXCodec::configureCodec(const sp<MetaData> &meta, uint32_t flags) {
- mIsMetaDataStoredInVideoBuffers = false;
- if (flags & kStoreMetaDataInVideoBuffers) {
- mIsMetaDataStoredInVideoBuffers = true;
- }
+status_t OMXCodec::configureCodec(const sp<MetaData> &meta) {
+ LOGV("configureCodec protected=%d",
+ (mFlags & kEnableGrallocUsageProtected) ? 1 : 0);
- mOnlySubmitOneBufferAtOneTime = false;
- if (flags & kOnlySubmitOneInputBufferAtOneTime) {
- mOnlySubmitOneBufferAtOneTime = true;
- }
-
- mEnableGrallocUsageProtected = false;
- if (flags & kEnableGrallocUsageProtected) {
- mEnableGrallocUsageProtected = true;
- }
- LOGV("configureCodec protected=%d", mEnableGrallocUsageProtected);
-
- if (!(flags & kIgnoreCodecSpecificData)) {
+ if (!(mFlags & kIgnoreCodecSpecificData)) {
uint32_t type;
const void *data;
size_t size;
@@ -622,6 +596,11 @@
LOGE("Profile and/or level exceed the decoder's capabilities.");
return ERROR_UNSUPPORTED;
}
+ } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) {
+ addCodecSpecificData(data, size);
+
+ CHECK(meta->findData(kKeyVorbisBooks, &type, &data, &size));
+ addCodecSpecificData(data, size);
}
}
@@ -631,16 +610,23 @@
}
if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mMIME)) {
setAMRFormat(false /* isWAMR */, bitRate);
- }
- if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mMIME)) {
+ } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mMIME)) {
setAMRFormat(true /* isWAMR */, bitRate);
- }
- if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mMIME)) {
+ } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mMIME)) {
int32_t numChannels, sampleRate;
CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
setAACFormat(numChannels, sampleRate, bitRate);
+ } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_G711_ALAW, mMIME)
+ || !strcasecmp(MEDIA_MIMETYPE_AUDIO_G711_MLAW, mMIME)) {
+ // These are PCM-like formats with a fixed sample rate but
+ // a variable number of channels.
+
+ int32_t numChannels;
+ CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
+
+ setG711Format(numChannels);
}
if (!strncasecmp(mMIME, "video/", 6)) {
@@ -697,7 +683,7 @@
initOutputFormat(meta);
- if ((flags & kClientNeedsFramebuffer)
+ if ((mFlags & kClientNeedsFramebuffer)
&& !strncmp(mComponentName, "OMX.SEC.", 8)) {
OMX_INDEXTYPE index;
@@ -843,6 +829,7 @@
case OMX_COLOR_FormatYUV420Planar:
case OMX_COLOR_FormatYUV420SemiPlanar:
+ case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar:
return (width * height * 3) / 2;
default:
@@ -866,6 +853,7 @@
}
}
+
// Check whether the target color format is supported.
return isColorFormatSupported(*colorFormat, kPortIndexInput);
}
@@ -1251,13 +1239,6 @@
h264type.nAllowedPictureTypes =
OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
- h264type.nSliceHeaderSpacing = 0;
- h264type.nBFrames = 0; // No B frames support yet
- h264type.nPFrames = setPFramesSpacing(iFramesInterval, frameRate);
- if (h264type.nPFrames == 0) {
- h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
- }
-
// Check profile and level parameters
CodecProfileLevel defaultProfileLevel, profileLevel;
defaultProfileLevel.mProfile = h264type.eProfile;
@@ -1267,9 +1248,21 @@
h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profileLevel.mProfile);
h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(profileLevel.mLevel);
+ // FIXME:
+ // Remove the workaround after the work in done.
+ if (!strncmp(mComponentName, "OMX.TI.DUCATI1", 14)) {
+ h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
+ }
+
if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
+ h264type.nSliceHeaderSpacing = 0;
h264type.bUseHadamard = OMX_TRUE;
h264type.nRefFrames = 1;
+ h264type.nBFrames = 0;
+ h264type.nPFrames = setPFramesSpacing(iFramesInterval, frameRate);
+ if (h264type.nPFrames == 0) {
+ h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
+ }
h264type.nRefIdx10ActiveMinus1 = 0;
h264type.nRefIdx11ActiveMinus1 = 0;
h264type.bEntropyCodingCABAC = OMX_FALSE;
@@ -1316,6 +1309,10 @@
compressionFormat = OMX_VIDEO_CodingMPEG4;
} else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
compressionFormat = OMX_VIDEO_CodingH263;
+ } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_VPX, mime)) {
+ compressionFormat = OMX_VIDEO_CodingVPX;
+ } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG2, mime)) {
+ compressionFormat = OMX_VIDEO_CodingMPEG2;
} else {
LOGE("Not a supported video mime type: %s", mime);
CHECK(!"Should not be here. Not a supported video mime type.");
@@ -1341,11 +1338,10 @@
CHECK_EQ(err, (status_t)OK);
CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
- static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00;
-
CHECK(format.eColorFormat == OMX_COLOR_FormatYUV420Planar
|| format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
|| format.eColorFormat == OMX_COLOR_FormatCbYCrY
+ || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar
|| format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar);
err = mOMX->setParameter(
@@ -1417,7 +1413,8 @@
}
OMXCodec::OMXCodec(
- const sp<IOMX> &omx, IOMX::node_id node, uint32_t quirks,
+ const sp<IOMX> &omx, IOMX::node_id node,
+ uint32_t quirks, uint32_t flags,
bool isEncoder,
const char *mime,
const char *componentName,
@@ -1427,6 +1424,7 @@
mOMXLivesLocally(omx->livesLocally(getpid())),
mNode(node),
mQuirks(quirks),
+ mFlags(flags),
mIsEncoder(isEncoder),
mMIME(strdup(mime)),
mComponentName(strdup(componentName)),
@@ -1443,7 +1441,8 @@
mOutputPortSettingsChangedPending(false),
mLeftOverBuffer(NULL),
mPaused(false),
- mNativeWindow(nativeWindow) {
+ mNativeWindow(!strncmp(componentName, "OMX.google.", 11)
+ ? NULL : nativeWindow) {
mPortStatus[kPortIndexInput] = ENABLED;
mPortStatus[kPortIndexOutput] = ENABLED;
@@ -1593,30 +1592,32 @@
return allocateOutputBuffersFromNativeWindow();
}
- if (mEnableGrallocUsageProtected && portIndex == kPortIndexOutput) {
+ if ((mFlags & kEnableGrallocUsageProtected) && portIndex == kPortIndexOutput) {
LOGE("protected output buffers must be stent to an ANativeWindow");
return PERMISSION_DENIED;
}
+ status_t err = OK;
+ if ((mFlags & kStoreMetaDataInVideoBuffers)
+ && portIndex == kPortIndexInput) {
+ err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
+ if (err != OK) {
+ LOGE("Storing meta data in video buffers is not supported");
+ return err;
+ }
+ }
+
OMX_PARAM_PORTDEFINITIONTYPE def;
InitOMXParams(&def);
def.nPortIndex = portIndex;
- status_t err = mOMX->getParameter(
+ err = mOMX->getParameter(
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
if (err != OK) {
return err;
}
- if (mIsMetaDataStoredInVideoBuffers && portIndex == kPortIndexInput) {
- err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
- if (err != OK) {
- LOGE("Storing meta data in video buffers is not supported");
- return err;
- }
- }
-
CODEC_LOGI("allocating %lu buffers of size %lu on %s port",
def.nBufferCountActual, def.nBufferSize,
portIndex == kPortIndexInput ? "input" : "output");
@@ -1634,7 +1635,8 @@
IOMX::buffer_id buffer;
if (portIndex == kPortIndexInput
- && (mQuirks & kRequiresAllocateBufferOnInputPorts)) {
+ && ((mQuirks & kRequiresAllocateBufferOnInputPorts)
+ || (mFlags & kUseSecureInputBuffers))) {
if (mOMXLivesLocally) {
mem.clear();
@@ -1695,6 +1697,31 @@
// dumpPortStatus(portIndex);
+ if (portIndex == kPortIndexInput && (mFlags & kUseSecureInputBuffers)) {
+ Vector<MediaBuffer *> buffers;
+ for (size_t i = 0; i < def.nBufferCountActual; ++i) {
+ const BufferInfo &info = mPortBuffers[kPortIndexInput].itemAt(i);
+
+ MediaBuffer *mbuf = new MediaBuffer(info.mData, info.mSize);
+ buffers.push(mbuf);
+ }
+
+ status_t err = mSource->setBuffers(buffers);
+
+ if (err != OK) {
+ for (size_t i = 0; i < def.nBufferCountActual; ++i) {
+ buffers.editItemAt(i)->release();
+ }
+ buffers.clear();
+
+ CODEC_LOGE(
+ "Codec requested to use secure input buffers but "
+ "upstream source didn't support that.");
+
+ return err;
+ }
+ }
+
return OK;
}
@@ -1737,6 +1764,13 @@
return err;
}
+ err = native_window_set_scaling_mode(mNativeWindow.get(),
+ NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
+
+ if (err != OK) {
+ return err;
+ }
+
err = native_window_set_buffers_geometry(
mNativeWindow.get(),
def.format.video.nFrameWidth,
@@ -1762,7 +1796,7 @@
// XXX: Currently this error is logged, but not fatal.
usage = 0;
}
- if (mEnableGrallocUsageProtected) {
+ if (mFlags & kEnableGrallocUsageProtected) {
usage |= GRALLOC_USAGE_PROTECTED;
}
@@ -1785,7 +1819,7 @@
}
}
- LOGV("native_window_set_usage usage=0x%x", usage);
+ LOGV("native_window_set_usage usage=0x%lx", usage);
err = native_window_set_usage(
mNativeWindow.get(), usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
if (err != 0) {
@@ -1830,7 +1864,7 @@
// Dequeue buffers and send them to OMX
for (OMX_U32 i = 0; i < def.nBufferCountActual; i++) {
- android_native_buffer_t* buf;
+ ANativeWindowBuffer* buf;
err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf);
if (err != 0) {
LOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
@@ -1900,7 +1934,7 @@
OMXCodec::BufferInfo* OMXCodec::dequeueBufferFromNativeWindow() {
// Dequeue the next buffer from the native window.
- android_native_buffer_t* buf;
+ ANativeWindowBuffer* buf;
int err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf);
if (err != 0) {
CODEC_LOGE("dequeueBuffer failed w/ error 0x%08x", err);
@@ -1935,7 +1969,33 @@
return bufInfo;
}
+int64_t OMXCodec::retrieveDecodingTimeUs(bool isCodecSpecific) {
+ CHECK(mIsEncoder);
+
+ if (mDecodingTimeList.empty()) {
+ CHECK(mNoMoreOutputData);
+ // No corresponding input frame available.
+ // This could happen when EOS is reached.
+ return 0;
+ }
+
+ List<int64_t>::iterator it = mDecodingTimeList.begin();
+ int64_t timeUs = *it;
+
+ // If the output buffer is codec specific configuration,
+ // do not remove the decoding time from the list.
+ if (!isCodecSpecific) {
+ mDecodingTimeList.erase(it);
+ }
+ return timeUs;
+}
+
void OMXCodec::on_message(const omx_message &msg) {
+ if (mState == ERROR) {
+ LOGW("Dropping OMX message - we're in ERROR state.");
+ return;
+ }
+
switch (msg.type) {
case omx_message::EVENT:
{
@@ -1988,7 +2048,12 @@
} else if (mState != ERROR
&& mPortStatus[kPortIndexInput] != SHUTTING_DOWN) {
CHECK_EQ((int)mPortStatus[kPortIndexInput], (int)ENABLED);
- drainInputBuffer(&buffers->editItemAt(i));
+
+ if (mFlags & kUseSecureInputBuffers) {
+ drainAnyInputBuffer();
+ } else {
+ drainInputBuffer(&buffers->editItemAt(i));
+ }
}
break;
}
@@ -2077,8 +2142,10 @@
if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_SYNCFRAME) {
buffer->meta_data()->setInt32(kKeyIsSyncFrame, true);
}
+ bool isCodecSpecific = false;
if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_CODECCONFIG) {
buffer->meta_data()->setInt32(kKeyIsCodecConfig, true);
+ isCodecSpecific = true;
}
if (isGraphicBuffer || mQuirks & kOutputBuffersAreUnreadable) {
@@ -2098,6 +2165,11 @@
mNoMoreOutputData = true;
}
+ if (mIsEncoder) {
+ int64_t decodingTimeUs = retrieveDecodingTimeUs(isCodecSpecific);
+ buffer->meta_data()->setInt64(kKeyDecodingTime, decodingTimeUs);
+ }
+
if (mTargetTimeUs >= 0) {
CHECK(msg.u.extended_buffer_data.timestamp <= mTargetTimeUs);
@@ -2239,13 +2311,15 @@
if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
onPortSettingsChanged(data1);
- } else if (data1 == kPortIndexOutput
- && data2 == OMX_IndexConfigCommonOutputCrop) {
+ } else if (data1 == kPortIndexOutput &&
+ (data2 == OMX_IndexConfigCommonOutputCrop ||
+ data2 == OMX_IndexConfigCommonScale)) {
sp<MetaData> oldOutputFormat = mOutputFormat;
initOutputFormat(mSource->getFormat());
- if (formatHasNotablyChanged(oldOutputFormat, mOutputFormat)) {
+ if (data2 == OMX_IndexConfigCommonOutputCrop &&
+ formatHasNotablyChanged(oldOutputFormat, mOutputFormat)) {
mOutputPortSettingsHaveChanged = true;
if (mNativeWindow != NULL) {
@@ -2264,6 +2338,39 @@
// already invalid, we'll know soon enough.
native_window_set_crop(mNativeWindow.get(), &crop);
}
+ } else if (data2 == OMX_IndexConfigCommonScale) {
+ OMX_CONFIG_SCALEFACTORTYPE scale;
+ InitOMXParams(&scale);
+ scale.nPortIndex = kPortIndexOutput;
+
+ // Change display dimension only when necessary.
+ if (OK == mOMX->getConfig(
+ mNode,
+ OMX_IndexConfigCommonScale,
+ &scale, sizeof(scale))) {
+ int32_t left, top, right, bottom;
+ CHECK(mOutputFormat->findRect(kKeyCropRect,
+ &left, &top,
+ &right, &bottom));
+
+ // The scale is in 16.16 format.
+ // scale 1.0 = 0x010000. When there is no
+ // need to change the display, skip it.
+ LOGV("Get OMX_IndexConfigScale: 0x%lx/0x%lx",
+ scale.xWidth, scale.xHeight);
+
+ if (scale.xWidth != 0x010000) {
+ mOutputFormat->setInt32(kKeyDisplayWidth,
+ ((right - left + 1) * scale.xWidth) >> 16);
+ mOutputPortSettingsHaveChanged = true;
+ }
+
+ if (scale.xHeight != 0x010000) {
+ mOutputFormat->setInt32(kKeyDisplayHeight,
+ ((bottom - top + 1) * scale.xHeight) >> 16);
+ mOutputPortSettingsHaveChanged = true;
+ }
+ }
}
}
break;
@@ -2683,32 +2790,81 @@
void OMXCodec::drainInputBuffers() {
CHECK(mState == EXECUTING || mState == RECONFIGURING);
- Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
- for (size_t i = 0; i < buffers->size(); ++i) {
- BufferInfo *info = &buffers->editItemAt(i);
-
- if (info->mStatus != OWNED_BY_US) {
- continue;
+ if (mFlags & kUseSecureInputBuffers) {
+ Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
+ for (size_t i = 0; i < buffers->size(); ++i) {
+ if (!drainAnyInputBuffer()
+ || (mFlags & kOnlySubmitOneInputBufferAtOneTime)) {
+ break;
+ }
}
+ } else {
+ Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
+ for (size_t i = 0; i < buffers->size(); ++i) {
+ BufferInfo *info = &buffers->editItemAt(i);
- if (!drainInputBuffer(info)) {
- break;
- }
+ if (info->mStatus != OWNED_BY_US) {
+ continue;
+ }
- if (mOnlySubmitOneBufferAtOneTime) {
- break;
+ if (!drainInputBuffer(info)) {
+ break;
+ }
+
+ if (mFlags & kOnlySubmitOneInputBufferAtOneTime) {
+ break;
+ }
}
}
}
+bool OMXCodec::drainAnyInputBuffer() {
+ return drainInputBuffer((BufferInfo *)NULL);
+}
+
+OMXCodec::BufferInfo *OMXCodec::findInputBufferByDataPointer(void *ptr) {
+ Vector<BufferInfo> *infos = &mPortBuffers[kPortIndexInput];
+ for (size_t i = 0; i < infos->size(); ++i) {
+ BufferInfo *info = &infos->editItemAt(i);
+
+ if (info->mData == ptr) {
+ CODEC_LOGV(
+ "input buffer data ptr = %p, buffer_id = %p",
+ ptr,
+ info->mBuffer);
+
+ return info;
+ }
+ }
+
+ TRESPASS();
+}
+
+OMXCodec::BufferInfo *OMXCodec::findEmptyInputBuffer() {
+ Vector<BufferInfo> *infos = &mPortBuffers[kPortIndexInput];
+ for (size_t i = 0; i < infos->size(); ++i) {
+ BufferInfo *info = &infos->editItemAt(i);
+
+ if (info->mStatus == OWNED_BY_US) {
+ return info;
+ }
+ }
+
+ TRESPASS();
+}
+
bool OMXCodec::drainInputBuffer(BufferInfo *info) {
- CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US);
+ if (info != NULL) {
+ CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US);
+ }
if (mSignalledEOS) {
return false;
}
if (mCodecSpecificDataIndex < mCodecSpecificData.size()) {
+ CHECK(!(mFlags & kUseSecureInputBuffers));
+
const CodecSpecificData *specific =
mCodecSpecificData[mCodecSpecificDataIndex];
@@ -2804,6 +2960,11 @@
break;
}
+ if (mFlags & kUseSecureInputBuffers) {
+ info = findInputBufferByDataPointer(srcBuffer->data());
+ CHECK(info != NULL);
+ }
+
size_t remainingBytes = info->mSize - offset;
if (srcBuffer->range_length() > remainingBytes) {
@@ -2839,19 +3000,32 @@
releaseBuffer = false;
info->mMediaBuffer = srcBuffer;
} else {
- if (mIsMetaDataStoredInVideoBuffers) {
+ if (mFlags & kStoreMetaDataInVideoBuffers) {
releaseBuffer = false;
info->mMediaBuffer = srcBuffer;
}
- memcpy((uint8_t *)info->mData + offset,
- (const uint8_t *)srcBuffer->data()
- + srcBuffer->range_offset(),
- srcBuffer->range_length());
+
+ if (mFlags & kUseSecureInputBuffers) {
+ // Data in "info" is already provided at this time.
+
+ releaseBuffer = false;
+
+ CHECK(info->mMediaBuffer == NULL);
+ info->mMediaBuffer = srcBuffer;
+ } else {
+ memcpy((uint8_t *)info->mData + offset,
+ (const uint8_t *)srcBuffer->data()
+ + srcBuffer->range_offset(),
+ srcBuffer->range_length());
+ }
}
int64_t lastBufferTimeUs;
CHECK(srcBuffer->meta_data()->findInt64(kKeyTime, &lastBufferTimeUs));
CHECK(lastBufferTimeUs >= 0);
+ if (mIsEncoder) {
+ mDecodingTimeList.push_back(lastBufferTimeUs);
+ }
if (offset == 0) {
timestampUs = lastBufferTimeUs;
@@ -2859,6 +3033,23 @@
offset += srcBuffer->range_length();
+ if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_VORBIS, mMIME)) {
+ CHECK(!(mQuirks & kSupportsMultipleFramesPerInputBuffer));
+ CHECK_GE(info->mSize, offset + sizeof(int32_t));
+
+ int32_t numPageSamples;
+ if (!srcBuffer->meta_data()->findInt32(
+ kKeyValidSamples, &numPageSamples)) {
+ numPageSamples = -1;
+ }
+
+ memcpy((uint8_t *)info->mData + offset,
+ &numPageSamples,
+ sizeof(numPageSamples));
+
+ offset += sizeof(numPageSamples);
+ }
+
if (releaseBuffer) {
srcBuffer->release();
srcBuffer = NULL;
@@ -2895,6 +3086,16 @@
info->mBuffer, offset,
timestampUs, timestampUs / 1E6);
+ if (info == NULL) {
+ CHECK(mFlags & kUseSecureInputBuffers);
+ CHECK(signalEOS);
+
+ // This is fishy, there's still a MediaBuffer corresponding to this
+ // info available to the source at this point even though we're going
+ // to use it to signal EOS to the codec.
+ info = findEmptyInputBuffer();
+ }
+
err = mOMX->emptyBuffer(
mNode, info->mBuffer, 0, offset,
flags, timestampUs);
@@ -2989,6 +3190,16 @@
mBufferFilled.signal();
}
+status_t OMXCodec::waitForBufferFilled_l() {
+ status_t err = mBufferFilled.waitRelative(mLock, kBufferFilledEventTimeOutUs);
+ if (err != OK) {
+ LOGE("Timed out waiting for buffers from video encoder: %d/%d",
+ countBuffersWeOwn(mPortBuffers[kPortIndexInput]),
+ countBuffersWeOwn(mPortBuffers[kPortIndexOutput]));
+ }
+ return err;
+}
+
void OMXCodec::setRawAudioFormat(
OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
@@ -3184,6 +3395,11 @@
}
}
+void OMXCodec::setG711Format(int32_t numChannels) {
+ CHECK(!mIsEncoder);
+ setRawAudioFormat(kPortIndexInput, 8000, numChannels);
+}
+
void OMXCodec::setImageOutputFormat(
OMX_COLOR_FORMATTYPE format, OMX_U32 width, OMX_U32 height) {
CODEC_LOGV("setImageOutputFormat(%ld, %ld)", width, height);
@@ -3339,7 +3555,7 @@
}
status_t OMXCodec::stop() {
- CODEC_LOGI("stop mState=%d", mState);
+ CODEC_LOGV("stop mState=%d", mState);
Mutex::Autolock autoLock(mLock);
@@ -3401,7 +3617,6 @@
mLeftOverBuffer = NULL;
}
- CODEC_LOGI("stopping video source");
mSource->stop();
CODEC_LOGI("stopped in state %d", mState);
@@ -3417,6 +3632,7 @@
status_t OMXCodec::read(
MediaBuffer **buffer, const ReadOptions *options) {
+ status_t err = OK;
*buffer = NULL;
Mutex::Autolock autoLock(mLock);
@@ -3457,7 +3673,9 @@
if (seeking) {
while (mState == RECONFIGURING) {
- mBufferFilled.wait(mLock);
+ if ((err = waitForBufferFilled_l()) != OK) {
+ return err;
+ }
}
if (mState != EXECUTING) {
@@ -3488,19 +3706,15 @@
}
while (mSeekTimeUs >= 0) {
- mBufferFilled.wait(mLock);
+ if ((err = waitForBufferFilled_l()) != OK) {
+ return err;
+ }
}
}
while (mState != ERROR && !mNoMoreOutputData && mFilledBuffers.empty()) {
- if (mIsEncoder) {
- if (NO_ERROR != mBufferFilled.waitRelative(mLock, 3000000000LL)) {
- LOGW("Timed out waiting for buffers from video encoder: %d/%d",
- countBuffersWeOwn(mPortBuffers[kPortIndexInput]),
- countBuffersWeOwn(mPortBuffers[kPortIndexOutput]));
- }
- } else {
- mBufferFilled.wait(mLock);
+ if ((err = waitForBufferFilled_l()) != OK) {
+ return err;
}
}
@@ -3650,7 +3864,9 @@
size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
- if (type == OMX_QCOM_COLOR_FormatYVU420SemiPlanar) {
+ if (type == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) {
+ return "OMX_TI_COLOR_FormatYUV420PackedSemiPlanar";
+ } else if (type == OMX_QCOM_COLOR_FormatYVU420SemiPlanar) {
return "OMX_QCOM_COLOR_FormatYVU420SemiPlanar";
} else if (type < 0 || (size_t)type >= numNames) {
return "UNKNOWN";
@@ -3974,6 +4190,13 @@
numChannels, params.nChannels);
}
+ if (sampleRate != (int32_t)params.nSamplingRate) {
+ LOGW("Codec outputs at different sampling rate than "
+ "what the input stream contains (contains data at "
+ "%d Hz, codec outputs %lu Hz)",
+ sampleRate, params.nSamplingRate);
+ }
+
mOutputFormat->setCString(
kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
@@ -3986,8 +4209,7 @@
(mQuirks & kDecoderLiesAboutNumberOfChannels)
? numChannels : params.nChannels);
- // The codec-reported sampleRate is not reliable...
- mOutputFormat->setInt32(kKeySampleRate, sampleRate);
+ mOutputFormat->setInt32(kKeySampleRate, params.nSamplingRate);
} else if (audio_def->eEncoding == OMX_AUDIO_CodingAMR) {
OMX_AUDIO_PARAM_AMRTYPE amr;
InitOMXParams(&amr);
@@ -4062,6 +4284,10 @@
mNode, OMX_IndexConfigCommonOutputCrop,
&rect, sizeof(rect));
+ CODEC_LOGI(
+ "video dimensions are %ld x %ld",
+ video_def->nFrameWidth, video_def->nFrameHeight);
+
if (err == OK) {
CHECK_GE(rect.nLeft, 0);
CHECK_GE(rect.nTop, 0);
@@ -4076,6 +4302,10 @@
rect.nTop,
rect.nLeft + rect.nWidth - 1,
rect.nTop + rect.nHeight - 1);
+
+ CODEC_LOGI(
+ "Crop rect is %ld x %ld @ (%ld, %ld)",
+ rect.nWidth, rect.nHeight, rect.nLeft, rect.nTop);
} else {
mOutputFormat->setRect(
kKeyCropRect,
@@ -4084,7 +4314,6 @@
video_def->nFrameHeight - 1);
}
}
-
break;
}
@@ -4094,6 +4323,14 @@
break;
}
}
+
+ // If the input format contains rotation information, flag the output
+ // format accordingly.
+
+ int32_t rotationDegrees;
+ if (mSource->getFormat()->findInt32(kKeyRotation, &rotationDegrees)) {
+ mOutputFormat->setInt32(kKeyRotation, rotationDegrees);
+ }
}
status_t OMXCodec::pause() {
@@ -4108,26 +4345,19 @@
status_t QueryCodecs(
const sp<IOMX> &omx,
- const char *mime, bool queryDecoders,
+ const char *mime, bool queryDecoders, bool hwCodecOnly,
Vector<CodecCapabilities> *results) {
+ Vector<String8> matchingCodecs;
results->clear();
- for (int index = 0;; ++index) {
- const char *componentName;
+ OMXCodec::findMatchingCodecs(mime,
+ !queryDecoders /*createEncoder*/,
+ NULL /*matchComponentName*/,
+ hwCodecOnly ? OMXCodec::kHardwareCodecsOnly : 0 /*flags*/,
+ &matchingCodecs);
- if (!queryDecoders) {
- componentName = GetCodec(
- kEncoderInfo, sizeof(kEncoderInfo) / sizeof(kEncoderInfo[0]),
- mime, index);
- } else {
- componentName = GetCodec(
- kDecoderInfo, sizeof(kDecoderInfo) / sizeof(kDecoderInfo[0]),
- mime, index);
- }
-
- if (!componentName) {
- return OK;
- }
+ for (size_t c = 0; c < matchingCodecs.size(); c++) {
+ const char *componentName = matchingCodecs.itemAt(c).string();
if (strncmp(componentName, "OMX.", 4)) {
// Not an OpenMax component but a software codec.
@@ -4135,7 +4365,6 @@
results->push();
CodecCapabilities *caps = &results->editItemAt(results->size() - 1);
caps->mComponentName = componentName;
-
continue;
}
@@ -4190,6 +4419,15 @@
CHECK_EQ(omx->freeNode(node), (status_t)OK);
}
+
+ return OK;
+}
+
+status_t QueryCodecs(
+ const sp<IOMX> &omx,
+ const char *mimeType, bool queryDecoders,
+ Vector<CodecCapabilities> *results) {
+ return QueryCodecs(omx, mimeType, queryDecoders, false /*hwCodecOnly*/, results);
}
void OMXCodec::restorePatchedDataPointer(BufferInfo *info) {
diff --git a/media/libstagefright/OggExtractor.cpp b/media/libstagefright/OggExtractor.cpp
index 6538a05..29e6907 100644
--- a/media/libstagefright/OggExtractor.cpp
+++ b/media/libstagefright/OggExtractor.cpp
@@ -378,12 +378,19 @@
ssize_t MyVorbisExtractor::readPage(off64_t offset, Page *page) {
uint8_t header[27];
- if (mSource->readAt(offset, header, sizeof(header))
+ ssize_t n;
+ if ((n = mSource->readAt(offset, header, sizeof(header)))
< (ssize_t)sizeof(header)) {
- LOGV("failed to read %d bytes at offset 0x%016llx",
- sizeof(header), offset);
+ LOGV("failed to read %d bytes at offset 0x%016llx, got %ld bytes",
+ sizeof(header), offset, n);
- return ERROR_IO;
+ if (n < 0) {
+ return n;
+ } else if (n == 0) {
+ return ERROR_END_OF_STREAM;
+ } else {
+ return ERROR_IO;
+ }
}
if (memcmp(header, "OggS", 4)) {
@@ -498,8 +505,8 @@
packetSize);
if (n < (ssize_t)packetSize) {
- LOGV("failed to read %d bytes at 0x%016llx",
- packetSize, dataOffset);
+ LOGV("failed to read %d bytes at 0x%016llx, got %ld bytes",
+ packetSize, dataOffset, n);
return ERROR_IO;
}
@@ -723,8 +730,9 @@
off64_t size;
if (mSource->getSize(&size) == OK) {
uint64_t bps = approxBitrate();
-
- mMeta->setInt64(kKeyDuration, size * 8000000ll / bps);
+ if (bps != 0) {
+ mMeta->setInt64(kKeyDuration, size * 8000000ll / bps);
+ }
}
break;
}
diff --git a/media/libstagefright/SampleTable.cpp b/media/libstagefright/SampleTable.cpp
index 423df70..a8a094e 100644
--- a/media/libstagefright/SampleTable.cpp
+++ b/media/libstagefright/SampleTable.cpp
@@ -53,6 +53,7 @@
mNumSampleSizes(0),
mTimeToSampleCount(0),
mTimeToSample(NULL),
+ mSampleTimeEntries(NULL),
mCompositionTimeDeltaEntries(NULL),
mNumCompositionTimeDeltaEntries(0),
mSyncSampleOffset(-1),
@@ -73,6 +74,9 @@
delete[] mCompositionTimeDeltaEntries;
mCompositionTimeDeltaEntries = NULL;
+ delete[] mSampleTimeEntries;
+ mSampleTimeEntries = NULL;
+
delete[] mTimeToSample;
mTimeToSample = NULL;
@@ -216,7 +220,7 @@
return ERROR_MALFORMED;
}
- mSampleSizeFieldSize = mDefaultSampleSize & 0xf;
+ mSampleSizeFieldSize = mDefaultSampleSize & 0xff;
mDefaultSampleSize = 0;
if (mSampleSizeFieldSize != 4 && mSampleSizeFieldSize != 8
@@ -381,67 +385,136 @@
return time1 > time2 ? time1 - time2 : time2 - time1;
}
-status_t SampleTable::findSampleAtTime(
- uint32_t req_time, uint32_t *sample_index, uint32_t flags) {
- // XXX this currently uses decoding time, instead of composition time.
+// static
+int SampleTable::CompareIncreasingTime(const void *_a, const void *_b) {
+ const SampleTimeEntry *a = (const SampleTimeEntry *)_a;
+ const SampleTimeEntry *b = (const SampleTimeEntry *)_b;
- *sample_index = 0;
+ if (a->mCompositionTime < b->mCompositionTime) {
+ return -1;
+ } else if (a->mCompositionTime > b->mCompositionTime) {
+ return 1;
+ }
+ return 0;
+}
+
+void SampleTable::buildSampleEntriesTable() {
Mutex::Autolock autoLock(mLock);
- uint32_t cur_sample = 0;
- uint32_t time = 0;
+ if (mSampleTimeEntries != NULL) {
+ return;
+ }
+
+ mSampleTimeEntries = new SampleTimeEntry[mNumSampleSizes];
+
+ uint32_t sampleIndex = 0;
+ uint32_t sampleTime = 0;
+
for (uint32_t i = 0; i < mTimeToSampleCount; ++i) {
uint32_t n = mTimeToSample[2 * i];
uint32_t delta = mTimeToSample[2 * i + 1];
- if (req_time < time + n * delta) {
- int j = (req_time - time) / delta;
+ for (uint32_t j = 0; j < n; ++j) {
+ if (sampleIndex < mNumSampleSizes) {
+ // Technically this should always be the case if the file
+ // is well-formed, but you know... there's (gasp) malformed
+ // content out there.
- uint32_t time1 = time + j * delta;
- uint32_t time2 = time1 + delta;
+ mSampleTimeEntries[sampleIndex].mSampleIndex = sampleIndex;
- uint32_t sampleTime;
- if (i+1 == mTimeToSampleCount
- || (abs_difference(req_time, time1)
- < abs_difference(req_time, time2))) {
- *sample_index = cur_sample + j;
- sampleTime = time1;
- } else {
- *sample_index = cur_sample + j + 1;
- sampleTime = time2;
+ mSampleTimeEntries[sampleIndex].mCompositionTime =
+ sampleTime + getCompositionTimeOffset(sampleIndex);
}
- switch (flags) {
- case kFlagBefore:
- {
- if (sampleTime > req_time && *sample_index > 0) {
- --*sample_index;
- }
- break;
- }
-
- case kFlagAfter:
- {
- if (sampleTime < req_time
- && *sample_index + 1 < mNumSampleSizes) {
- ++*sample_index;
- }
- break;
- }
-
- default:
- break;
- }
-
- return OK;
+ ++sampleIndex;
+ sampleTime += delta;
}
-
- time += delta * n;
- cur_sample += n;
}
- return ERROR_OUT_OF_RANGE;
+ qsort(mSampleTimeEntries, mNumSampleSizes, sizeof(SampleTimeEntry),
+ CompareIncreasingTime);
+}
+
+status_t SampleTable::findSampleAtTime(
+ uint32_t req_time, uint32_t *sample_index, uint32_t flags) {
+ buildSampleEntriesTable();
+
+ uint32_t left = 0;
+ uint32_t right = mNumSampleSizes;
+ while (left < right) {
+ uint32_t center = (left + right) / 2;
+ uint32_t centerTime = mSampleTimeEntries[center].mCompositionTime;
+
+ if (req_time < centerTime) {
+ right = center;
+ } else if (req_time > centerTime) {
+ left = center + 1;
+ } else {
+ left = center;
+ break;
+ }
+ }
+
+ if (left == mNumSampleSizes) {
+ if (flags == kFlagAfter) {
+ return ERROR_OUT_OF_RANGE;
+ }
+
+ --left;
+ }
+
+ uint32_t closestIndex = left;
+
+ switch (flags) {
+ case kFlagBefore:
+ {
+ while (closestIndex > 0
+ && mSampleTimeEntries[closestIndex].mCompositionTime
+ > req_time) {
+ --closestIndex;
+ }
+ break;
+ }
+
+ case kFlagAfter:
+ {
+ while (closestIndex + 1 < mNumSampleSizes
+ && mSampleTimeEntries[closestIndex].mCompositionTime
+ < req_time) {
+ ++closestIndex;
+ }
+ break;
+ }
+
+ default:
+ {
+ CHECK(flags == kFlagClosest);
+
+ if (closestIndex > 0) {
+ // Check left neighbour and pick closest.
+ uint32_t absdiff1 =
+ abs_difference(
+ mSampleTimeEntries[closestIndex].mCompositionTime,
+ req_time);
+
+ uint32_t absdiff2 =
+ abs_difference(
+ mSampleTimeEntries[closestIndex - 1].mCompositionTime,
+ req_time);
+
+ if (absdiff1 > absdiff2) {
+ closestIndex = closestIndex - 1;
+ }
+ }
+
+ break;
+ }
+ }
+
+ *sample_index = mSampleTimeEntries[closestIndex].mSampleIndex;
+
+ return OK;
}
status_t SampleTable::findSyncSampleNear(
@@ -613,7 +686,7 @@
uint32_t sampleIndex,
off64_t *offset,
size_t *size,
- uint32_t *decodingTime,
+ uint32_t *compositionTime,
bool *isSyncSample) {
Mutex::Autolock autoLock(mLock);
@@ -630,8 +703,8 @@
*size = mSampleIterator->getSampleSize();
}
- if (decodingTime) {
- *decodingTime = mSampleIterator->getSampleTime();
+ if (compositionTime) {
+ *compositionTime = mSampleIterator->getSampleTime();
}
if (isSyncSample) {
diff --git a/media/libstagefright/ShoutcastSource.cpp b/media/libstagefright/ShoutcastSource.cpp
deleted file mode 100644
index 783f2d0..0000000
--- a/media/libstagefright/ShoutcastSource.cpp
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * 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.
- */
-
-#include "include/HTTPStream.h"
-
-#include <stdlib.h>
-
-#include <media/stagefright/MediaBuffer.h>
-#include <media/stagefright/MediaBufferGroup.h>
-#include <media/stagefright/MediaDebug.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MetaData.h>
-#include <media/stagefright/ShoutcastSource.h>
-
-namespace android {
-
-ShoutcastSource::ShoutcastSource(HTTPStream *http)
- : mHttp(http),
- mMetaDataOffset(0),
- mBytesUntilMetaData(0),
- mGroup(NULL),
- mStarted(false) {
- AString metaint;
- if (mHttp->find_header_value("icy-metaint", &metaint)) {
- char *end;
- const char *start = metaint.c_str();
- mMetaDataOffset = strtol(start, &end, 10);
- CHECK(end > start && *end == '\0');
- CHECK(mMetaDataOffset > 0);
-
- mBytesUntilMetaData = mMetaDataOffset;
- }
-}
-
-ShoutcastSource::~ShoutcastSource() {
- if (mStarted) {
- stop();
- }
-
- delete mHttp;
- mHttp = NULL;
-}
-
-status_t ShoutcastSource::start(MetaData *) {
- CHECK(!mStarted);
-
- mGroup = new MediaBufferGroup;
- mGroup->add_buffer(new MediaBuffer(4096)); // XXX
-
- mStarted = true;
-
- return OK;
-}
-
-status_t ShoutcastSource::stop() {
- CHECK(mStarted);
-
- delete mGroup;
- mGroup = NULL;
-
- mStarted = false;
-
- return OK;
-}
-
-sp<MetaData> ShoutcastSource::getFormat() {
- sp<MetaData> meta = new MetaData;
- meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
- meta->setInt32(kKeySampleRate, 44100);
- meta->setInt32(kKeyChannelCount, 2); // XXX
-
- return meta;
-}
-
-status_t ShoutcastSource::read(
- MediaBuffer **out, const ReadOptions *options) {
- CHECK(mStarted);
-
- *out = NULL;
-
- int64_t seekTimeUs;
- ReadOptions::SeekMode mode;
- if (options && options->getSeekTo(&seekTimeUs, &mode)) {
- return ERROR_UNSUPPORTED;
- }
-
- MediaBuffer *buffer;
- status_t err = mGroup->acquire_buffer(&buffer);
- if (err != OK) {
- return err;
- }
-
- *out = buffer;
-
- size_t num_bytes = buffer->size();
- if (mMetaDataOffset > 0 && num_bytes > mBytesUntilMetaData) {
- num_bytes = mBytesUntilMetaData;
- }
-
- ssize_t n = mHttp->receive(buffer->data(), num_bytes);
-
- if (n <= 0) {
- return (status_t)n;
- }
-
- buffer->set_range(0, n);
-
- mBytesUntilMetaData -= (size_t)n;
-
- if (mBytesUntilMetaData == 0) {
- unsigned char num_16_byte_blocks = 0;
- n = mHttp->receive((char *)&num_16_byte_blocks, 1);
- CHECK_EQ(n, 1);
-
- char meta[255 * 16];
- size_t meta_size = num_16_byte_blocks * 16;
- size_t meta_length = 0;
- while (meta_length < meta_size) {
- n = mHttp->receive(&meta[meta_length], meta_size - meta_length);
- if (n <= 0) {
- return (status_t)n;
- }
-
- meta_length += (size_t) n;
- }
-
- while (meta_length > 0 && meta[meta_length - 1] == '\0') {
- --meta_length;
- }
-
- if (meta_length > 0) {
- // Technically we should probably attach this meta data to the
- // next buffer. XXX
- buffer->meta_data()->setData('shou', 'shou', meta, meta_length);
- }
-
- mBytesUntilMetaData = mMetaDataOffset;
- }
-
- return OK;
-}
-
-} // namespace android
-
diff --git a/media/libstagefright/StagefrightMediaScanner.cpp b/media/libstagefright/StagefrightMediaScanner.cpp
index 84f65ff..571e8be 100644
--- a/media/libstagefright/StagefrightMediaScanner.cpp
+++ b/media/libstagefright/StagefrightMediaScanner.cpp
@@ -37,7 +37,8 @@
".mp3", ".mp4", ".m4a", ".3gp", ".3gpp", ".3g2", ".3gpp2",
".mpeg", ".ogg", ".mid", ".smf", ".imy", ".wma", ".aac",
".wav", ".amr", ".midi", ".xmf", ".rtttl", ".rtx", ".ota",
- ".mkv", ".mka", ".webm", ".ts", ".fl", ".flac"
+ ".mkv", ".mka", ".webm", ".ts", ".fl", ".flac", ".mxmf",
+ ".avi",
};
static const size_t kNumValidExtensions =
sizeof(kValidExtensions) / sizeof(kValidExtensions[0]);
@@ -51,13 +52,13 @@
return false;
}
-static status_t HandleMIDI(
+static MediaScanResult HandleMIDI(
const char *filename, MediaScannerClient *client) {
// get the library configuration and do sanity check
const S_EAS_LIB_CONFIG* pLibConfig = EAS_Config();
if ((pLibConfig == NULL) || (LIB_VERSION != pLibConfig->libVersion)) {
LOGE("EAS library/header mismatch\n");
- return UNKNOWN_ERROR;
+ return MEDIA_SCAN_RESULT_ERROR;
}
EAS_I32 temp;
@@ -87,34 +88,41 @@
}
if (result != EAS_SUCCESS) {
- return UNKNOWN_ERROR;
+ return MEDIA_SCAN_RESULT_SKIPPED;
}
char buffer[20];
sprintf(buffer, "%ld", temp);
- if (!client->addStringTag("duration", buffer)) return UNKNOWN_ERROR;
-
- return OK;
+ status_t status = client->addStringTag("duration", buffer);
+ if (status) {
+ return MEDIA_SCAN_RESULT_ERROR;
+ }
+ return MEDIA_SCAN_RESULT_OK;
}
-status_t StagefrightMediaScanner::processFile(
+MediaScanResult StagefrightMediaScanner::processFile(
const char *path, const char *mimeType,
MediaScannerClient &client) {
LOGV("processFile '%s'.", path);
client.setLocale(locale());
client.beginFile();
+ MediaScanResult result = processFileInternal(path, mimeType, client);
+ client.endFile();
+ return result;
+}
+MediaScanResult StagefrightMediaScanner::processFileInternal(
+ const char *path, const char *mimeType,
+ MediaScannerClient &client) {
const char *extension = strrchr(path, '.');
if (!extension) {
- return UNKNOWN_ERROR;
+ return MEDIA_SCAN_RESULT_SKIPPED;
}
if (!FileHasAcceptableExtension(extension)) {
- client.endFile();
-
- return UNKNOWN_ERROR;
+ return MEDIA_SCAN_RESULT_SKIPPED;
}
if (!strcasecmp(extension, ".mid")
@@ -124,53 +132,59 @@
|| !strcasecmp(extension, ".xmf")
|| !strcasecmp(extension, ".rtttl")
|| !strcasecmp(extension, ".rtx")
- || !strcasecmp(extension, ".ota")) {
- status_t status = HandleMIDI(path, &client);
- if (status != OK) {
- return status;
+ || !strcasecmp(extension, ".ota")
+ || !strcasecmp(extension, ".mxmf")) {
+ return HandleMIDI(path, &client);
+ }
+
+ sp<MediaMetadataRetriever> mRetriever(new MediaMetadataRetriever);
+
+ status_t status = mRetriever->setDataSource(path);
+ if (status) {
+ return MEDIA_SCAN_RESULT_ERROR;
+ }
+
+ const char *value;
+ if ((value = mRetriever->extractMetadata(
+ METADATA_KEY_MIMETYPE)) != NULL) {
+ status = client.setMimeType(value);
+ if (status) {
+ return MEDIA_SCAN_RESULT_ERROR;
}
- } else {
- sp<MediaMetadataRetriever> mRetriever(new MediaMetadataRetriever);
+ }
- if (mRetriever->setDataSource(path) == OK) {
- const char *value;
- if ((value = mRetriever->extractMetadata(
- METADATA_KEY_MIMETYPE)) != NULL) {
- client.setMimeType(value);
- }
+ struct KeyMap {
+ const char *tag;
+ int key;
+ };
+ static const KeyMap kKeyMap[] = {
+ { "tracknumber", METADATA_KEY_CD_TRACK_NUMBER },
+ { "discnumber", METADATA_KEY_DISC_NUMBER },
+ { "album", METADATA_KEY_ALBUM },
+ { "artist", METADATA_KEY_ARTIST },
+ { "albumartist", METADATA_KEY_ALBUMARTIST },
+ { "composer", METADATA_KEY_COMPOSER },
+ { "genre", METADATA_KEY_GENRE },
+ { "title", METADATA_KEY_TITLE },
+ { "year", METADATA_KEY_YEAR },
+ { "duration", METADATA_KEY_DURATION },
+ { "writer", METADATA_KEY_WRITER },
+ { "compilation", METADATA_KEY_COMPILATION },
+ { "isdrm", METADATA_KEY_IS_DRM },
+ };
+ static const size_t kNumEntries = sizeof(kKeyMap) / sizeof(kKeyMap[0]);
- struct KeyMap {
- const char *tag;
- int key;
- };
- static const KeyMap kKeyMap[] = {
- { "tracknumber", METADATA_KEY_CD_TRACK_NUMBER },
- { "discnumber", METADATA_KEY_DISC_NUMBER },
- { "album", METADATA_KEY_ALBUM },
- { "artist", METADATA_KEY_ARTIST },
- { "albumartist", METADATA_KEY_ALBUMARTIST },
- { "composer", METADATA_KEY_COMPOSER },
- { "genre", METADATA_KEY_GENRE },
- { "title", METADATA_KEY_TITLE },
- { "year", METADATA_KEY_YEAR },
- { "duration", METADATA_KEY_DURATION },
- { "writer", METADATA_KEY_WRITER },
- { "compilation", METADATA_KEY_COMPILATION },
- };
- static const size_t kNumEntries = sizeof(kKeyMap) / sizeof(kKeyMap[0]);
-
- for (size_t i = 0; i < kNumEntries; ++i) {
- const char *value;
- if ((value = mRetriever->extractMetadata(kKeyMap[i].key)) != NULL) {
- client.addStringTag(kKeyMap[i].tag, value);
- }
+ for (size_t i = 0; i < kNumEntries; ++i) {
+ const char *value;
+ if ((value = mRetriever->extractMetadata(kKeyMap[i].key)) != NULL) {
+ status = client.addStringTag(kKeyMap[i].tag, value);
+ if (status) {
+ return MEDIA_SCAN_RESULT_ERROR;
}
}
}
- client.endFile();
-
- return OK;
+ return MEDIA_SCAN_RESULT_OK;
}
char *StagefrightMediaScanner::extractAlbumArt(int fd) {
diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp
index ea3b801..778c0b5 100644
--- a/media/libstagefright/StagefrightMetadataRetriever.cpp
+++ b/media/libstagefright/StagefrightMetadataRetriever.cpp
@@ -27,6 +27,7 @@
#include <media/stagefright/MediaExtractor.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/OMXCodec.h>
+#include <media/stagefright/MediaDefs.h>
namespace android {
@@ -48,7 +49,8 @@
mClient.disconnect();
}
-status_t StagefrightMetadataRetriever::setDataSource(const char *uri) {
+status_t StagefrightMetadataRetriever::setDataSource(
+ const char *uri, const KeyedVector<String8, String8> *headers) {
LOGV("setDataSource(%s)", uri);
mParsedMetaData = false;
@@ -56,7 +58,7 @@
delete mAlbumArt;
mAlbumArt = NULL;
- mSource = DataSource::CreateFromURI(uri);
+ mSource = DataSource::CreateFromURI(uri, headers);
if (mSource == NULL) {
return UNKNOWN_ERROR;
@@ -145,7 +147,8 @@
int64_t thumbNailTime;
if (frameTimeUs < 0) {
- if (!trackMeta->findInt64(kKeyThumbnailTime, &thumbNailTime)) {
+ if (!trackMeta->findInt64(kKeyThumbnailTime, &thumbNailTime)
+ || thumbNailTime < 0) {
thumbNailTime = 0;
}
options.setSeekTo(thumbNailTime, mode);
@@ -231,6 +234,14 @@
frame->mData = new uint8_t[frame->mSize];
frame->mRotationAngle = rotationAngle;
+ int32_t displayWidth, displayHeight;
+ if (meta->findInt32(kKeyDisplayWidth, &displayWidth)) {
+ frame->mDisplayWidth = displayWidth;
+ }
+ if (meta->findInt32(kKeyDisplayHeight, &displayHeight)) {
+ frame->mDisplayHeight = displayHeight;
+ }
+
int32_t srcFormat;
CHECK(meta->findInt32(kKeyColorFormat, &srcFormat));
@@ -306,6 +317,17 @@
return NULL;
}
+ const void *data;
+ uint32_t type;
+ size_t dataSize;
+ if (mExtractor->getMetaData()->findData(kKeyAlbumArt, &type, &data, &dataSize)
+ && mAlbumArt == NULL) {
+ mAlbumArt = new MediaAlbumArt;
+ mAlbumArt->mSize = dataSize;
+ mAlbumArt->mData = new uint8_t[dataSize];
+ memcpy(mAlbumArt->mData, data, dataSize);
+ }
+
VideoFrame *frame =
extractVideoFrameWithCodecFlags(
&mClient, trackMeta, source, OMXCodec::kPreferSoftwareCodecs,
@@ -397,7 +419,8 @@
const void *data;
uint32_t type;
size_t dataSize;
- if (meta->findData(kKeyAlbumArt, &type, &data, &dataSize)) {
+ if (meta->findData(kKeyAlbumArt, &type, &data, &dataSize)
+ && mAlbumArt == NULL) {
mAlbumArt = new MediaAlbumArt;
mAlbumArt->mSize = dataSize;
mAlbumArt->mData = new uint8_t[dataSize];
@@ -411,8 +434,15 @@
mMetaData.add(METADATA_KEY_NUM_TRACKS, String8(tmp));
+ bool hasAudio = false;
+ bool hasVideo = false;
+ int32_t videoWidth = -1;
+ int32_t videoHeight = -1;
+ int32_t audioBitrate = -1;
+
// The overall duration is the duration of the longest track.
int64_t maxDurationUs = 0;
+ String8 timedTextLang;
for (size_t i = 0; i < numTracks; ++i) {
sp<MetaData> trackMeta = mExtractor->getTrackMetaData(i);
@@ -422,12 +452,67 @@
maxDurationUs = durationUs;
}
}
+
+ const char *mime;
+ if (trackMeta->findCString(kKeyMIMEType, &mime)) {
+ if (!hasAudio && !strncasecmp("audio/", mime, 6)) {
+ hasAudio = true;
+
+ if (!trackMeta->findInt32(kKeyBitRate, &audioBitrate)) {
+ audioBitrate = -1;
+ }
+ } else if (!hasVideo && !strncasecmp("video/", mime, 6)) {
+ hasVideo = true;
+
+ CHECK(trackMeta->findInt32(kKeyWidth, &videoWidth));
+ CHECK(trackMeta->findInt32(kKeyHeight, &videoHeight));
+ } else if (!strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP)) {
+ const char *lang;
+ trackMeta->findCString(kKeyMediaLanguage, &lang);
+ timedTextLang.append(String8(lang));
+ timedTextLang.append(String8(":"));
+ }
+ }
+ }
+
+ // To save the language codes for all timed text tracks
+ // If multiple text tracks present, the format will look
+ // like "eng:chi"
+ if (!timedTextLang.isEmpty()) {
+ mMetaData.add(METADATA_KEY_TIMED_TEXT_LANGUAGES, timedTextLang);
}
// The duration value is a string representing the duration in ms.
sprintf(tmp, "%lld", (maxDurationUs + 500) / 1000);
mMetaData.add(METADATA_KEY_DURATION, String8(tmp));
+ if (hasAudio) {
+ mMetaData.add(METADATA_KEY_HAS_AUDIO, String8("yes"));
+ }
+
+ if (hasVideo) {
+ mMetaData.add(METADATA_KEY_HAS_VIDEO, String8("yes"));
+
+ sprintf(tmp, "%d", videoWidth);
+ mMetaData.add(METADATA_KEY_VIDEO_WIDTH, String8(tmp));
+
+ sprintf(tmp, "%d", videoHeight);
+ mMetaData.add(METADATA_KEY_VIDEO_HEIGHT, String8(tmp));
+ }
+
+ if (numTracks == 1 && hasAudio && audioBitrate >= 0) {
+ sprintf(tmp, "%d", audioBitrate);
+ mMetaData.add(METADATA_KEY_BITRATE, String8(tmp));
+ } else {
+ off64_t sourceSize;
+ if (mSource->getSize(&sourceSize) == OK) {
+ int64_t avgBitRate = (int64_t)(sourceSize * 8E6 / maxDurationUs);
+
+ sprintf(tmp, "%lld", avgBitRate);
+ mMetaData.add(METADATA_KEY_BITRATE, String8(tmp));
+ }
+ }
+
if (numTracks == 1) {
const char *fileMIME;
CHECK(meta->findCString(kKeyMIMEType, &fileMIME));
@@ -445,6 +530,11 @@
}
}
}
+
+ // To check whether the media file is drm-protected
+ if (mExtractor->getDrmFlag()) {
+ mMetaData.add(METADATA_KEY_IS_DRM, String8("1"));
+ }
}
} // namespace android
diff --git a/media/libstagefright/SurfaceMediaSource.cpp b/media/libstagefright/SurfaceMediaSource.cpp
new file mode 100644
index 0000000..3d8c56a
--- /dev/null
+++ b/media/libstagefright/SurfaceMediaSource.cpp
@@ -0,0 +1,792 @@
+/*
+ * Copyright (C) 2011 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 "SurfaceMediaSource"
+
+#include <media/stagefright/SurfaceMediaSource.h>
+#include <ui/GraphicBuffer.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/openmax/OMX_IVCommon.h>
+#include <media/stagefright/MetadataBufferType.h>
+
+#include <surfaceflinger/ISurfaceComposer.h>
+#include <surfaceflinger/SurfaceComposerClient.h>
+#include <surfaceflinger/IGraphicBufferAlloc.h>
+#include <OMX_Component.h>
+
+#include <utils/Log.h>
+#include <utils/String8.h>
+
+namespace android {
+
+SurfaceMediaSource::SurfaceMediaSource(uint32_t bufW, uint32_t bufH) :
+ mDefaultWidth(bufW),
+ mDefaultHeight(bufH),
+ mPixelFormat(0),
+ mBufferCount(MIN_ASYNC_BUFFER_SLOTS),
+ mClientBufferCount(0),
+ mServerBufferCount(MIN_ASYNC_BUFFER_SLOTS),
+ mCurrentSlot(INVALID_BUFFER_SLOT),
+ mCurrentTimestamp(0),
+ mSynchronousMode(true),
+ mConnectedApi(NO_CONNECTED_API),
+ mFrameRate(30),
+ mStarted(false) {
+ LOGV("SurfaceMediaSource::SurfaceMediaSource");
+ sp<ISurfaceComposer> composer(ComposerService::getComposerService());
+ mGraphicBufferAlloc = composer->createGraphicBufferAlloc();
+}
+
+SurfaceMediaSource::~SurfaceMediaSource() {
+ LOGV("SurfaceMediaSource::~SurfaceMediaSource");
+ if (mStarted) {
+ stop();
+ }
+ freeAllBuffers();
+}
+
+size_t SurfaceMediaSource::getQueuedCount() const {
+ Mutex::Autolock lock(mMutex);
+ return mQueue.size();
+}
+
+status_t SurfaceMediaSource::setBufferCountServerLocked(int bufferCount) {
+ if (bufferCount > NUM_BUFFER_SLOTS)
+ return BAD_VALUE;
+
+ // special-case, nothing to do
+ if (bufferCount == mBufferCount)
+ return OK;
+
+ if (!mClientBufferCount &&
+ bufferCount >= mBufferCount) {
+ // easy, we just have more buffers
+ mBufferCount = bufferCount;
+ mServerBufferCount = bufferCount;
+ mDequeueCondition.signal();
+ } else {
+ // we're here because we're either
+ // - reducing the number of available buffers
+ // - or there is a client-buffer-count in effect
+
+ // less than 2 buffers is never allowed
+ if (bufferCount < 2)
+ return BAD_VALUE;
+
+ // when there is non client-buffer-count in effect, the client is not
+ // allowed to dequeue more than one buffer at a time,
+ // so the next time they dequeue a buffer, we know that they don't
+ // own one. the actual resizing will happen during the next
+ // dequeueBuffer.
+
+ mServerBufferCount = bufferCount;
+ }
+ return OK;
+}
+
+// Called from the consumer side
+status_t SurfaceMediaSource::setBufferCountServer(int bufferCount) {
+ Mutex::Autolock lock(mMutex);
+ return setBufferCountServerLocked(bufferCount);
+}
+
+status_t SurfaceMediaSource::setBufferCount(int bufferCount) {
+ LOGV("SurfaceMediaSource::setBufferCount");
+ if (bufferCount > NUM_BUFFER_SLOTS) {
+ LOGE("setBufferCount: bufferCount is larger than the number of buffer slots");
+ return BAD_VALUE;
+ }
+
+ Mutex::Autolock lock(mMutex);
+ // Error out if the user has dequeued buffers
+ for (int i = 0 ; i < mBufferCount ; i++) {
+ if (mSlots[i].mBufferState == BufferSlot::DEQUEUED) {
+ LOGE("setBufferCount: client owns some buffers");
+ return INVALID_OPERATION;
+ }
+ }
+
+ if (bufferCount == 0) {
+ const int minBufferSlots = mSynchronousMode ?
+ MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS;
+ mClientBufferCount = 0;
+ bufferCount = (mServerBufferCount >= minBufferSlots) ?
+ mServerBufferCount : minBufferSlots;
+ return setBufferCountServerLocked(bufferCount);
+ }
+
+ // We don't allow the client to set a buffer-count less than
+ // MIN_ASYNC_BUFFER_SLOTS (3), there is no reason for it.
+ if (bufferCount < MIN_ASYNC_BUFFER_SLOTS) {
+ return BAD_VALUE;
+ }
+
+ // here we're guaranteed that the client doesn't have dequeued buffers
+ // and will release all of its buffer references.
+ freeAllBuffers();
+ mBufferCount = bufferCount;
+ mClientBufferCount = bufferCount;
+ mCurrentSlot = INVALID_BUFFER_SLOT;
+ mQueue.clear();
+ mDequeueCondition.signal();
+ return OK;
+}
+
+status_t SurfaceMediaSource::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
+ LOGV("SurfaceMediaSource::requestBuffer");
+ Mutex::Autolock lock(mMutex);
+ if (slot < 0 || mBufferCount <= slot) {
+ LOGE("requestBuffer: slot index out of range [0, %d]: %d",
+ mBufferCount, slot);
+ return BAD_VALUE;
+ }
+ mSlots[slot].mRequestBufferCalled = true;
+ *buf = mSlots[slot].mGraphicBuffer;
+ return NO_ERROR;
+}
+
+status_t SurfaceMediaSource::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
+ uint32_t format, uint32_t usage) {
+ LOGV("dequeueBuffer");
+
+
+ // Check for the buffer size- the client should just use the
+ // default width and height, and not try to set those.
+ // This is needed since
+ // the getFormat() returns mDefaultWidth/ Height for the OMX. It is
+ // queried by OMX in the beginning and not every time a frame comes.
+ // Not sure if there is a way to update the
+ // frame size while recording. So as of now, the client side
+ // sets the default values via the constructor, and the encoder is
+ // setup to encode frames of that size
+ // The design might need to change in the future.
+ // TODO: Currently just uses mDefaultWidth/Height. In the future
+ // we might declare mHeight and mWidth and check against those here.
+ if ((w != 0) || (h != 0)) {
+ LOGE("dequeuebuffer: invalid buffer size! Req: %dx%d, Found: %dx%d",
+ mDefaultWidth, mDefaultHeight, w, h);
+ return BAD_VALUE;
+ }
+
+ Mutex::Autolock lock(mMutex);
+
+ status_t returnFlags(OK);
+
+ int found, foundSync;
+ int dequeuedCount = 0;
+ bool tryAgain = true;
+ while (tryAgain) {
+ // We need to wait for the FIFO to drain if the number of buffer
+ // needs to change.
+ //
+ // The condition "number of buffer needs to change" is true if
+ // - the client doesn't care about how many buffers there are
+ // - AND the actual number of buffer is different from what was
+ // set in the last setBufferCountServer()
+ // - OR -
+ // setBufferCountServer() was set to a value incompatible with
+ // the synchronization mode (for instance because the sync mode
+ // changed since)
+ //
+ // As long as this condition is true AND the FIFO is not empty, we
+ // wait on mDequeueCondition.
+
+ int minBufferCountNeeded = mSynchronousMode ?
+ MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS;
+
+ if (!mClientBufferCount &&
+ ((mServerBufferCount != mBufferCount) ||
+ (mServerBufferCount < minBufferCountNeeded))) {
+ // wait for the FIFO to drain
+ while (!mQueue.isEmpty()) {
+ LOGV("Waiting for the FIFO to drain");
+ mDequeueCondition.wait(mMutex);
+ }
+ // need to check again since the mode could have changed
+ // while we were waiting
+ minBufferCountNeeded = mSynchronousMode ?
+ MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS;
+ }
+
+ if (!mClientBufferCount &&
+ ((mServerBufferCount != mBufferCount) ||
+ (mServerBufferCount < minBufferCountNeeded))) {
+ // here we're guaranteed that mQueue is empty
+ freeAllBuffers();
+ mBufferCount = mServerBufferCount;
+ if (mBufferCount < minBufferCountNeeded)
+ mBufferCount = minBufferCountNeeded;
+ mCurrentSlot = INVALID_BUFFER_SLOT;
+ returnFlags |= ISurfaceTexture::RELEASE_ALL_BUFFERS;
+ }
+
+ // look for a free buffer to give to the client
+ found = INVALID_BUFFER_SLOT;
+ foundSync = INVALID_BUFFER_SLOT;
+ dequeuedCount = 0;
+ for (int i = 0; i < mBufferCount; i++) {
+ const int state = mSlots[i].mBufferState;
+ if (state == BufferSlot::DEQUEUED) {
+ dequeuedCount++;
+ continue; // won't be continuing if could
+ // dequeue a non 'FREE' current slot like
+ // that in SurfaceTexture
+ }
+ // In case of Encoding, we do not deque the mCurrentSlot buffer
+ // since we follow synchronous mode (unlike possibly in
+ // SurfaceTexture that could be using the asynch mode
+ // or has some mechanism in GL to be able to wait till the
+ // currentslot is done using the data)
+ // Here, we have to wait for the MPEG4Writer(or equiv)
+ // to tell us when it's done using the current buffer
+ if (state == BufferSlot::FREE) {
+ foundSync = i;
+ // Unlike that in SurfaceTexture,
+ // We don't need to worry if it is the
+ // currentslot or not as it is in state FREE
+ found = i;
+ break;
+ }
+ }
+
+ // clients are not allowed to dequeue more than one buffer
+ // if they didn't set a buffer count.
+ if (!mClientBufferCount && dequeuedCount) {
+ return -EINVAL;
+ }
+
+ // See whether a buffer has been queued since the last setBufferCount so
+ // we know whether to perform the MIN_UNDEQUEUED_BUFFERS check below.
+ bool bufferHasBeenQueued = mCurrentSlot != INVALID_BUFFER_SLOT;
+ if (bufferHasBeenQueued) {
+ // make sure the client is not trying to dequeue more buffers
+ // than allowed.
+ const int avail = mBufferCount - (dequeuedCount+1);
+ if (avail < (MIN_UNDEQUEUED_BUFFERS-int(mSynchronousMode))) {
+ LOGE("dequeueBuffer: MIN_UNDEQUEUED_BUFFERS=%d exceeded (dequeued=%d)",
+ MIN_UNDEQUEUED_BUFFERS-int(mSynchronousMode),
+ dequeuedCount);
+ return -EBUSY;
+ }
+ }
+
+ // we're in synchronous mode and didn't find a buffer, we need to wait
+ // for for some buffers to be consumed
+ tryAgain = mSynchronousMode && (foundSync == INVALID_BUFFER_SLOT);
+ if (tryAgain) {
+ LOGW("Waiting..In synchronous mode and no buffer to dQ");
+ mDequeueCondition.wait(mMutex);
+ }
+ }
+
+ if (mSynchronousMode && found == INVALID_BUFFER_SLOT) {
+ // foundSync guaranteed to be != INVALID_BUFFER_SLOT
+ found = foundSync;
+ }
+
+ if (found == INVALID_BUFFER_SLOT) {
+ return -EBUSY;
+ }
+
+ const int buf = found;
+ *outBuf = found;
+
+ const bool useDefaultSize = !w && !h;
+ if (useDefaultSize) {
+ // use the default size
+ w = mDefaultWidth;
+ h = mDefaultHeight;
+ }
+
+ const bool updateFormat = (format != 0);
+ if (!updateFormat) {
+ // keep the current (or default) format
+ format = mPixelFormat;
+ }
+
+ // buffer is now in DEQUEUED (but can also be current at the same time,
+ // if we're in synchronous mode)
+ mSlots[buf].mBufferState = BufferSlot::DEQUEUED;
+
+ const sp<GraphicBuffer>& buffer(mSlots[buf].mGraphicBuffer);
+ if ((buffer == NULL) ||
+ (uint32_t(buffer->width) != w) ||
+ (uint32_t(buffer->height) != h) ||
+ (uint32_t(buffer->format) != format) ||
+ ((uint32_t(buffer->usage) & usage) != usage)) {
+ usage |= GraphicBuffer::USAGE_HW_TEXTURE;
+ status_t error;
+ sp<GraphicBuffer> graphicBuffer(
+ mGraphicBufferAlloc->createGraphicBuffer(
+ w, h, format, usage, &error));
+ if (graphicBuffer == 0) {
+ LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer failed");
+ return error;
+ }
+ if (updateFormat) {
+ mPixelFormat = format;
+ }
+ mSlots[buf].mGraphicBuffer = graphicBuffer;
+ mSlots[buf].mRequestBufferCalled = false;
+ returnFlags |= ISurfaceTexture::BUFFER_NEEDS_REALLOCATION;
+ }
+ return returnFlags;
+}
+
+status_t SurfaceMediaSource::setSynchronousMode(bool enabled) {
+ Mutex::Autolock lock(mMutex);
+
+ status_t err = OK;
+ if (!enabled) {
+ // going to asynchronous mode, drain the queue
+ while (mSynchronousMode != enabled && !mQueue.isEmpty()) {
+ mDequeueCondition.wait(mMutex);
+ }
+ }
+
+ if (mSynchronousMode != enabled) {
+ // - if we're going to asynchronous mode, the queue is guaranteed to be
+ // empty here
+ // - if the client set the number of buffers, we're guaranteed that
+ // we have at least 3 (because we don't allow less)
+ mSynchronousMode = enabled;
+ mDequeueCondition.signal();
+ }
+ return err;
+}
+
+status_t SurfaceMediaSource::connect(int api) {
+ LOGV("SurfaceMediaSource::connect");
+ Mutex::Autolock lock(mMutex);
+ status_t err = NO_ERROR;
+ switch (api) {
+ case NATIVE_WINDOW_API_EGL:
+ case NATIVE_WINDOW_API_CPU:
+ case NATIVE_WINDOW_API_MEDIA:
+ case NATIVE_WINDOW_API_CAMERA:
+ if (mConnectedApi != NO_CONNECTED_API) {
+ err = -EINVAL;
+ } else {
+ mConnectedApi = api;
+ }
+ break;
+ default:
+ err = -EINVAL;
+ break;
+ }
+ return err;
+}
+
+status_t SurfaceMediaSource::disconnect(int api) {
+ LOGV("SurfaceMediaSource::disconnect");
+ Mutex::Autolock lock(mMutex);
+ status_t err = NO_ERROR;
+ switch (api) {
+ case NATIVE_WINDOW_API_EGL:
+ case NATIVE_WINDOW_API_CPU:
+ case NATIVE_WINDOW_API_MEDIA:
+ case NATIVE_WINDOW_API_CAMERA:
+ if (mConnectedApi == api) {
+ mConnectedApi = NO_CONNECTED_API;
+ } else {
+ err = -EINVAL;
+ }
+ break;
+ default:
+ err = -EINVAL;
+ break;
+ }
+ return err;
+}
+
+status_t SurfaceMediaSource::queueBuffer(int buf, int64_t timestamp,
+ uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
+ LOGV("queueBuffer");
+
+ Mutex::Autolock lock(mMutex);
+ if (buf < 0 || buf >= mBufferCount) {
+ LOGE("queueBuffer: slot index out of range [0, %d]: %d",
+ mBufferCount, buf);
+ return -EINVAL;
+ } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) {
+ LOGE("queueBuffer: slot %d is not owned by the client (state=%d)",
+ buf, mSlots[buf].mBufferState);
+ return -EINVAL;
+ } else if (!mSlots[buf].mRequestBufferCalled) {
+ LOGE("queueBuffer: slot %d was enqueued without requesting a "
+ "buffer", buf);
+ return -EINVAL;
+ }
+
+ if (mSynchronousMode) {
+ // in synchronous mode we queue all buffers in a FIFO
+ mQueue.push_back(buf);
+ LOGV("Client queued buffer on slot: %d, Q size = %d",
+ buf, mQueue.size());
+ } else {
+ // in asynchronous mode we only keep the most recent buffer
+ if (mQueue.empty()) {
+ mQueue.push_back(buf);
+ } else {
+ Fifo::iterator front(mQueue.begin());
+ // buffer currently queued is freed
+ mSlots[*front].mBufferState = BufferSlot::FREE;
+ // and we record the new buffer index in the queued list
+ *front = buf;
+ }
+ }
+
+ mSlots[buf].mBufferState = BufferSlot::QUEUED;
+ mSlots[buf].mTimestamp = timestamp;
+ // TODO: (Confirm) Don't want to signal dequeue here.
+ // May be just in asynchronous mode?
+ // mDequeueCondition.signal();
+
+ // Once the queuing is done, we need to let the listener
+ // and signal the buffer consumer (encoder) know that a
+ // buffer is available
+ onFrameReceivedLocked();
+
+ *outWidth = mDefaultWidth;
+ *outHeight = mDefaultHeight;
+ *outTransform = 0;
+
+ return OK;
+}
+
+
+// onFrameReceivedLocked informs the buffer consumers (StageFrightRecorder)
+// or listeners that a frame has been received
+// It is supposed to be called only from queuebuffer.
+// The buffer is NOT made available for dequeueing immediately. We need to
+// wait to hear from StageFrightRecorder to set the buffer FREE
+// Make sure this is called when the mutex is locked
+status_t SurfaceMediaSource::onFrameReceivedLocked() {
+ LOGV("On Frame Received");
+ // Signal the encoder that a new frame has arrived
+ mFrameAvailableCondition.signal();
+
+ // call back the listener
+ // TODO: The listener may not be needed in SurfaceMediaSource at all.
+ // This can be made a SurfaceTexture specific thing
+ sp<FrameAvailableListener> listener;
+ if (mSynchronousMode || mQueue.empty()) {
+ listener = mFrameAvailableListener;
+ }
+
+ if (listener != 0) {
+ listener->onFrameAvailable();
+ }
+ return OK;
+}
+
+
+void SurfaceMediaSource::cancelBuffer(int buf) {
+ LOGV("SurfaceMediaSource::cancelBuffer");
+ Mutex::Autolock lock(mMutex);
+ if (buf < 0 || buf >= mBufferCount) {
+ LOGE("cancelBuffer: slot index out of range [0, %d]: %d",
+ mBufferCount, buf);
+ return;
+ } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) {
+ LOGE("cancelBuffer: slot %d is not owned by the client (state=%d)",
+ buf, mSlots[buf].mBufferState);
+ return;
+ }
+ mSlots[buf].mBufferState = BufferSlot::FREE;
+ mDequeueCondition.signal();
+}
+
+nsecs_t SurfaceMediaSource::getTimestamp() {
+ LOGV("SurfaceMediaSource::getTimestamp");
+ Mutex::Autolock lock(mMutex);
+ return mCurrentTimestamp;
+}
+
+
+void SurfaceMediaSource::setFrameAvailableListener(
+ const sp<FrameAvailableListener>& listener) {
+ LOGV("SurfaceMediaSource::setFrameAvailableListener");
+ Mutex::Autolock lock(mMutex);
+ mFrameAvailableListener = listener;
+}
+
+void SurfaceMediaSource::freeAllBuffers() {
+ LOGV("freeAllBuffers");
+ for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
+ mSlots[i].mGraphicBuffer = 0;
+ mSlots[i].mBufferState = BufferSlot::FREE;
+ }
+}
+
+sp<GraphicBuffer> SurfaceMediaSource::getCurrentBuffer() const {
+ Mutex::Autolock lock(mMutex);
+ return mCurrentBuf;
+}
+
+int SurfaceMediaSource::query(int what, int* outValue)
+{
+ LOGV("query");
+ Mutex::Autolock lock(mMutex);
+ int value;
+ switch (what) {
+ case NATIVE_WINDOW_WIDTH:
+ value = mDefaultWidth;
+ if (!mDefaultWidth && !mDefaultHeight && mCurrentBuf != 0)
+ value = mCurrentBuf->width;
+ break;
+ case NATIVE_WINDOW_HEIGHT:
+ value = mDefaultHeight;
+ if (!mDefaultWidth && !mDefaultHeight && mCurrentBuf != 0)
+ value = mCurrentBuf->height;
+ break;
+ case NATIVE_WINDOW_FORMAT:
+ value = mPixelFormat;
+ break;
+ case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
+ value = mSynchronousMode ?
+ (MIN_UNDEQUEUED_BUFFERS-1) : MIN_UNDEQUEUED_BUFFERS;
+ break;
+ default:
+ return BAD_VALUE;
+ }
+ outValue[0] = value;
+ return NO_ERROR;
+}
+
+void SurfaceMediaSource::dump(String8& result) const
+{
+ char buffer[1024];
+ dump(result, "", buffer, 1024);
+}
+
+void SurfaceMediaSource::dump(String8& result, const char* prefix,
+ char* buffer, size_t SIZE) const
+{
+ Mutex::Autolock _l(mMutex);
+ snprintf(buffer, SIZE,
+ "%smBufferCount=%d, mSynchronousMode=%d, default-size=[%dx%d], "
+ "mPixelFormat=%d, \n",
+ prefix, mBufferCount, mSynchronousMode, mDefaultWidth, mDefaultHeight,
+ mPixelFormat);
+ result.append(buffer);
+
+ String8 fifo;
+ int fifoSize = 0;
+ Fifo::const_iterator i(mQueue.begin());
+ while (i != mQueue.end()) {
+ snprintf(buffer, SIZE, "%02d ", *i++);
+ fifoSize++;
+ fifo.append(buffer);
+ }
+
+ result.append(buffer);
+
+ struct {
+ const char * operator()(int state) const {
+ switch (state) {
+ case BufferSlot::DEQUEUED: return "DEQUEUED";
+ case BufferSlot::QUEUED: return "QUEUED";
+ case BufferSlot::FREE: return "FREE";
+ default: return "Unknown";
+ }
+ }
+ } stateName;
+
+ for (int i = 0; i < mBufferCount; i++) {
+ const BufferSlot& slot(mSlots[i]);
+ snprintf(buffer, SIZE,
+ "%s%s[%02d] state=%-8s, "
+ "timestamp=%lld\n",
+ prefix, (i==mCurrentSlot)?">":" ", i, stateName(slot.mBufferState),
+ slot.mTimestamp
+ );
+ result.append(buffer);
+ }
+}
+
+status_t SurfaceMediaSource::setFrameRate(int32_t fps)
+{
+ Mutex::Autolock lock(mMutex);
+ const int MAX_FRAME_RATE = 60;
+ if (fps < 0 || fps > MAX_FRAME_RATE) {
+ return BAD_VALUE;
+ }
+ mFrameRate = fps;
+ return OK;
+}
+
+bool SurfaceMediaSource::isMetaDataStoredInVideoBuffers() const {
+ LOGV("isMetaDataStoredInVideoBuffers");
+ return true;
+}
+
+int32_t SurfaceMediaSource::getFrameRate( ) const {
+ Mutex::Autolock lock(mMutex);
+ return mFrameRate;
+}
+
+status_t SurfaceMediaSource::start(MetaData *params)
+{
+ LOGV("start");
+ Mutex::Autolock lock(mMutex);
+ CHECK(!mStarted);
+ mStarted = true;
+ return OK;
+}
+
+
+status_t SurfaceMediaSource::stop()
+{
+ LOGV("Stop");
+
+ Mutex::Autolock lock(mMutex);
+ // TODO: Add waiting on mFrameCompletedCondition here?
+ mStarted = false;
+ mFrameAvailableCondition.signal();
+
+ return OK;
+}
+
+sp<MetaData> SurfaceMediaSource::getFormat()
+{
+ LOGV("getFormat");
+ Mutex::Autolock autoLock(mMutex);
+ sp<MetaData> meta = new MetaData;
+
+ meta->setInt32(kKeyWidth, mDefaultWidth);
+ meta->setInt32(kKeyHeight, mDefaultHeight);
+ // The encoder format is set as an opaque colorformat
+ // The encoder will later find out the actual colorformat
+ // from the GL Frames itself.
+ meta->setInt32(kKeyColorFormat, OMX_COLOR_FormatAndroidOpaque);
+ meta->setInt32(kKeyStride, mDefaultWidth);
+ meta->setInt32(kKeySliceHeight, mDefaultHeight);
+ meta->setInt32(kKeyFrameRate, mFrameRate);
+ meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
+ return meta;
+}
+
+status_t SurfaceMediaSource::read( MediaBuffer **buffer,
+ const ReadOptions *options)
+{
+ LOGV("Read. Size of queued buffer: %d", mQueue.size());
+ *buffer = NULL;
+
+ Mutex::Autolock autoLock(mMutex) ;
+ // If the recording has started and the queue is empty, then just
+ // wait here till the frames come in from the client side
+ while (mStarted && mQueue.empty()) {
+ LOGV("NO FRAMES! Recorder waiting for FrameAvailableCondition");
+ mFrameAvailableCondition.wait(mMutex);
+ }
+
+ // If the loop was exited as a result of stopping the recording,
+ // it is OK
+ if (!mStarted) {
+ return OK;
+ }
+
+ // Update the current buffer info
+ // TODO: mCurrentSlot can be made a bufferstate since there
+ // can be more than one "current" slots.
+ Fifo::iterator front(mQueue.begin());
+ mCurrentSlot = *front;
+ mCurrentBuf = mSlots[mCurrentSlot].mGraphicBuffer;
+ mCurrentTimestamp = mSlots[mCurrentSlot].mTimestamp;
+
+ // Pass the data to the MediaBuffer. Pass in only the metadata
+ passMetadataBufferLocked(buffer);
+
+ (*buffer)->setObserver(this);
+ (*buffer)->add_ref();
+ (*buffer)->meta_data()->setInt64(kKeyTime, mCurrentTimestamp);
+
+ return OK;
+}
+
+// Pass the data to the MediaBuffer. Pass in only the metadata
+// The metadata passed consists of two parts:
+// 1. First, there is an integer indicating that it is a GRAlloc
+// source (kMetadataBufferTypeGrallocSource)
+// 2. This is followed by the buffer_handle_t that is a handle to the
+// GRalloc buffer. The encoder needs to interpret this GRalloc handle
+// and encode the frames.
+// --------------------------------------------------------------
+// | kMetadataBufferTypeGrallocSource | sizeof(buffer_handle_t) |
+// --------------------------------------------------------------
+// Note: Call only when you have the lock
+void SurfaceMediaSource::passMetadataBufferLocked(MediaBuffer **buffer) {
+ LOGV("passMetadataBuffer");
+ // MediaBuffer allocates and owns this data
+ MediaBuffer *tempBuffer =
+ new MediaBuffer(4 + sizeof(buffer_handle_t));
+ char *data = (char *)tempBuffer->data();
+ if (data == NULL) {
+ LOGE("Cannot allocate memory for passing buffer metadata!");
+ return;
+ }
+ OMX_U32 type = kMetadataBufferTypeGrallocSource;
+ memcpy(data, &type, 4);
+ memcpy(data + 4, &(mCurrentBuf->handle), sizeof(buffer_handle_t));
+ *buffer = tempBuffer;
+}
+
+
+void SurfaceMediaSource::signalBufferReturned(MediaBuffer *buffer) {
+ LOGV("signalBufferReturned");
+
+ bool foundBuffer = false;
+ Mutex::Autolock autoLock(mMutex);
+
+ if (!mStarted) {
+ LOGW("signalBufferReturned: mStarted = false! Nothing to do!");
+ return;
+ }
+
+ for (Fifo::iterator it = mQueue.begin(); it != mQueue.end(); ++it) {
+ CHECK(mSlots[*it].mGraphicBuffer != NULL);
+ if (checkBufferMatchesSlot(*it, buffer)) {
+ mSlots[*it].mBufferState = BufferSlot::FREE;
+ mQueue.erase(it);
+ buffer->setObserver(0);
+ buffer->release();
+ mDequeueCondition.signal();
+ mFrameCompleteCondition.signal();
+ foundBuffer = true;
+ break;
+ }
+ }
+
+ if (!foundBuffer) {
+ CHECK_EQ(0, "signalBufferReturned: bogus buffer");
+ }
+}
+
+bool SurfaceMediaSource::checkBufferMatchesSlot(int slot, MediaBuffer *buffer) {
+ LOGV("Check if Buffer matches slot");
+ // need to convert to char* for pointer arithmetic and then
+ // copy the byte stream into our handle
+ buffer_handle_t bufferHandle ;
+ memcpy( &bufferHandle, (char *)(buffer->data()) + 4, sizeof(buffer_handle_t));
+ return mSlots[slot].mGraphicBuffer->handle == bufferHandle;
+}
+
+
+} // end of namespace android
diff --git a/media/libstagefright/ThreadedSource.cpp b/media/libstagefright/ThreadedSource.cpp
deleted file mode 100644
index 38c6e2d..0000000
--- a/media/libstagefright/ThreadedSource.cpp
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright (C) 2010 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_TAG "ThreadedSource"
-//#define LOG_NDEBUG 0
-#include <utils/Log.h>
-
-#include "include/ThreadedSource.h"
-
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/MediaBuffer.h>
-#include <media/stagefright/MetaData.h>
-
-namespace android {
-
-static const size_t kMaxQueueSize = 2;
-
-ThreadedSource::ThreadedSource(const sp<MediaSource> &source)
- : mSource(source),
- mReflector(new AHandlerReflector<ThreadedSource>(this)),
- mLooper(new ALooper),
- mStarted(false) {
- mLooper->registerHandler(mReflector);
-}
-
-ThreadedSource::~ThreadedSource() {
- if (mStarted) {
- stop();
- }
-}
-
-status_t ThreadedSource::start(MetaData *params) {
- CHECK(!mStarted);
-
- status_t err = mSource->start(params);
-
- if (err != OK) {
- return err;
- }
-
- mFinalResult = OK;
- mSeekTimeUs = -1;
- mDecodePending = false;
-
- Mutex::Autolock autoLock(mLock);
- postDecodeMore_l();
-
- CHECK_EQ(mLooper->start(), (status_t)OK);
-
- mStarted = true;
-
- return OK;
-}
-
-status_t ThreadedSource::stop() {
- CHECK(mStarted);
-
- CHECK_EQ(mLooper->stop(), (status_t)OK);
-
- Mutex::Autolock autoLock(mLock);
- clearQueue_l();
-
- status_t err = mSource->stop();
-
- mStarted = false;
-
- return err;
-}
-
-sp<MetaData> ThreadedSource::getFormat() {
- return mSource->getFormat();
-}
-
-status_t ThreadedSource::read(
- MediaBuffer **buffer, const ReadOptions *options) {
- *buffer = NULL;
-
- Mutex::Autolock autoLock(mLock);
-
- int64_t seekTimeUs;
- ReadOptions::SeekMode seekMode;
- if (options && options->getSeekTo(&seekTimeUs, &seekMode)) {
- int32_t seekComplete = 0;
-
- sp<AMessage> msg = new AMessage(kWhatSeek, mReflector->id());
- msg->setInt64("timeUs", seekTimeUs);
- msg->setInt32("mode", seekMode);
- msg->setPointer("complete", &seekComplete);
- msg->post();
-
- while (!seekComplete) {
- mCondition.wait(mLock);
- }
- }
-
- while (mQueue.empty() && mFinalResult == OK) {
- mCondition.wait(mLock);
- }
-
- if (!mQueue.empty()) {
- *buffer = *mQueue.begin();
- mQueue.erase(mQueue.begin());
-
- if (mFinalResult == OK) {
- postDecodeMore_l();
- }
-
- return OK;
- }
-
- return mFinalResult;
-}
-
-void ThreadedSource::onMessageReceived(const sp<AMessage> &msg) {
- switch (msg->what()) {
- case kWhatSeek:
- {
- CHECK(msg->findInt64("timeUs", &mSeekTimeUs));
- CHECK_GE(mSeekTimeUs, 0ll);
-
- int32_t x;
- CHECK(msg->findInt32("mode", &x));
- mSeekMode = (ReadOptions::SeekMode)x;
-
- int32_t *seekComplete;
- CHECK(msg->findPointer("complete", (void **)&seekComplete));
-
- Mutex::Autolock autoLock(mLock);
- clearQueue_l();
- mFinalResult = OK;
-
- *seekComplete = 1;
- mCondition.signal();
-
- postDecodeMore_l();
- break;
- }
-
- case kWhatDecodeMore:
- {
- {
- Mutex::Autolock autoLock(mLock);
- mDecodePending = false;
-
- if (mQueue.size() == kMaxQueueSize) {
- break;
- }
- }
-
- MediaBuffer *buffer;
- ReadOptions options;
- if (mSeekTimeUs >= 0) {
- options.setSeekTo(mSeekTimeUs, mSeekMode);
- mSeekTimeUs = -1ll;
- }
- status_t err = mSource->read(&buffer, &options);
-
- Mutex::Autolock autoLock(mLock);
-
- if (err != OK) {
- mFinalResult = err;
- } else {
- mQueue.push_back(buffer);
-
- if (mQueue.size() < kMaxQueueSize) {
- postDecodeMore_l();
- }
- }
-
- mCondition.signal();
- break;
- }
-
- default:
- TRESPASS();
- break;
- }
-}
-
-void ThreadedSource::postDecodeMore_l() {
- if (mDecodePending) {
- return;
- }
-
- mDecodePending = true;
- (new AMessage(kWhatDecodeMore, mReflector->id()))->post();
-}
-
-void ThreadedSource::clearQueue_l() {
- while (!mQueue.empty()) {
- MediaBuffer *buffer = *mQueue.begin();
- mQueue.erase(mQueue.begin());
-
- buffer->release();
- buffer = NULL;
- }
-}
-
-} // namespace android
diff --git a/media/libstagefright/TimedEventQueue.cpp b/media/libstagefright/TimedEventQueue.cpp
index 5a453e9..100d8a3 100644
--- a/media/libstagefright/TimedEventQueue.cpp
+++ b/media/libstagefright/TimedEventQueue.cpp
@@ -30,7 +30,6 @@
#include <sys/prctl.h>
#include <sys/time.h>
-#include <sys/resource.h>
#include <media/stagefright/MediaDebug.h>
@@ -210,8 +209,7 @@
vm->AttachCurrentThread(&env, NULL);
#endif
- setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_FOREGROUND);
- set_sched_policy(androidGetTid(), SP_FOREGROUND);
+ androidSetThreadPriority(0, ANDROID_PRIORITY_FOREGROUND);
static_cast<TimedEventQueue *>(me)->threadEntry();
diff --git a/media/libstagefright/VBRISeeker.cpp b/media/libstagefright/VBRISeeker.cpp
index 48bddc2..6f968be 100644
--- a/media/libstagefright/VBRISeeker.cpp
+++ b/media/libstagefright/VBRISeeker.cpp
@@ -20,6 +20,7 @@
#include "include/VBRISeeker.h"
+#include "include/avc_utils.h"
#include "include/MP3Extractor.h"
#include <media/stagefright/foundation/ADebug.h>
@@ -46,7 +47,7 @@
uint32_t tmp = U32_AT(&header[0]);
size_t frameSize;
int sampleRate;
- if (!MP3Extractor::get_mp3_frame_size(tmp, &frameSize, &sampleRate)) {
+ if (!GetMPEGAudioFrameSize(tmp, &frameSize, &sampleRate)) {
return NULL;
}
diff --git a/media/libstagefright/WAVExtractor.cpp b/media/libstagefright/WAVExtractor.cpp
index 9332120..c406964 100644
--- a/media/libstagefright/WAVExtractor.cpp
+++ b/media/libstagefright/WAVExtractor.cpp
@@ -264,6 +264,8 @@
mGroup(NULL) {
CHECK(mMeta->findInt32(kKeySampleRate, &mSampleRate));
CHECK(mMeta->findInt32(kKeyChannelCount, &mNumChannels));
+
+ mMeta->setInt32(kKeyMaxInputSize, kMaxFrameSize);
}
WAVSource::~WAVSource() {
@@ -353,8 +355,6 @@
return ERROR_END_OF_STREAM;
}
- mCurrentPos += n;
-
buffer->set_range(0, n);
if (mWaveFormat == WAVE_FORMAT_PCM) {
@@ -370,7 +370,9 @@
int16_t *dst = (int16_t *)tmp->data();
const uint8_t *src = (const uint8_t *)buffer->data();
- while (n-- > 0) {
+ ssize_t numBytes = n;
+
+ while (numBytes-- > 0) {
*dst++ = ((int16_t)(*src) - 128) * 256;
++src;
}
@@ -406,6 +408,7 @@
/ (mNumChannels * bytesPerSample) / mSampleRate);
buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
+ mCurrentPos += n;
*out = buffer;
@@ -426,6 +429,11 @@
return false;
}
+ sp<MediaExtractor> extractor = new WAVExtractor(source);
+ if (extractor->countTracks() == 0) {
+ return false;
+ }
+
*mimeType = MEDIA_MIMETYPE_CONTAINER_WAV;
*confidence = 0.3f;
diff --git a/media/libstagefright/XINGSeeker.cpp b/media/libstagefright/XINGSeeker.cpp
index 616836c..2091381 100644
--- a/media/libstagefright/XINGSeeker.cpp
+++ b/media/libstagefright/XINGSeeker.cpp
@@ -24,8 +24,8 @@
static bool parse_xing_header(
const sp<DataSource> &source, off64_t first_frame_pos,
int32_t *frame_number = NULL, int32_t *byte_number = NULL,
- char *table_of_contents = NULL, int32_t *quality_indicator = NULL,
- int64_t *duration = NULL);
+ unsigned char *table_of_contents = NULL,
+ int32_t *quality_indicator = NULL, int64_t *duration = NULL);
// static
sp<XINGSeeker> XINGSeeker::CreateFromSource(
@@ -41,8 +41,6 @@
return NULL;
}
- LOGI("Found XING header.");
-
return seeker;
}
@@ -96,7 +94,7 @@
static bool parse_xing_header(
const sp<DataSource> &source, off64_t first_frame_pos,
int32_t *frame_number, int32_t *byte_number,
- char *table_of_contents, int32_t *quality_indicator,
+ unsigned char *table_of_contents, int32_t *quality_indicator,
int64_t *duration) {
if (frame_number) {
*frame_number = 0;
diff --git a/media/libstagefright/avc_utils.cpp b/media/libstagefright/avc_utils.cpp
index 95cf2d3..8a42e8b 100644
--- a/media/libstagefright/avc_utils.cpp
+++ b/media/libstagefright/avc_utils.cpp
@@ -188,7 +188,7 @@
}
size_t endOffset = offset - 2;
- while (data[endOffset - 1] == 0x00) {
+ while (endOffset > startOffset + 1 && data[endOffset - 1] == 0x00) {
--endOffset;
}
@@ -376,5 +376,236 @@
return meta;
}
+bool ExtractDimensionsFromVOLHeader(
+ const uint8_t *data, size_t size, int32_t *width, int32_t *height) {
+ ABitReader br(&data[4], size - 4);
+ br.skipBits(1); // random_accessible_vol
+ unsigned video_object_type_indication = br.getBits(8);
+
+ CHECK_NE(video_object_type_indication,
+ 0x21u /* Fine Granularity Scalable */);
+
+ unsigned video_object_layer_verid;
+ unsigned video_object_layer_priority;
+ if (br.getBits(1)) {
+ video_object_layer_verid = br.getBits(4);
+ video_object_layer_priority = br.getBits(3);
+ }
+ unsigned aspect_ratio_info = br.getBits(4);
+ if (aspect_ratio_info == 0x0f /* extended PAR */) {
+ br.skipBits(8); // par_width
+ br.skipBits(8); // par_height
+ }
+ if (br.getBits(1)) { // vol_control_parameters
+ br.skipBits(2); // chroma_format
+ br.skipBits(1); // low_delay
+ if (br.getBits(1)) { // vbv_parameters
+ br.skipBits(15); // first_half_bit_rate
+ CHECK(br.getBits(1)); // marker_bit
+ br.skipBits(15); // latter_half_bit_rate
+ CHECK(br.getBits(1)); // marker_bit
+ br.skipBits(15); // first_half_vbv_buffer_size
+ CHECK(br.getBits(1)); // marker_bit
+ br.skipBits(3); // latter_half_vbv_buffer_size
+ br.skipBits(11); // first_half_vbv_occupancy
+ CHECK(br.getBits(1)); // marker_bit
+ br.skipBits(15); // latter_half_vbv_occupancy
+ CHECK(br.getBits(1)); // marker_bit
+ }
+ }
+ unsigned video_object_layer_shape = br.getBits(2);
+ CHECK_EQ(video_object_layer_shape, 0x00u /* rectangular */);
+
+ CHECK(br.getBits(1)); // marker_bit
+ unsigned vop_time_increment_resolution = br.getBits(16);
+ CHECK(br.getBits(1)); // marker_bit
+
+ if (br.getBits(1)) { // fixed_vop_rate
+ // range [0..vop_time_increment_resolution)
+
+ // vop_time_increment_resolution
+ // 2 => 0..1, 1 bit
+ // 3 => 0..2, 2 bits
+ // 4 => 0..3, 2 bits
+ // 5 => 0..4, 3 bits
+ // ...
+
+ CHECK_GT(vop_time_increment_resolution, 0u);
+ --vop_time_increment_resolution;
+
+ unsigned numBits = 0;
+ while (vop_time_increment_resolution > 0) {
+ ++numBits;
+ vop_time_increment_resolution >>= 1;
+ }
+
+ br.skipBits(numBits); // fixed_vop_time_increment
+ }
+
+ CHECK(br.getBits(1)); // marker_bit
+ unsigned video_object_layer_width = br.getBits(13);
+ CHECK(br.getBits(1)); // marker_bit
+ unsigned video_object_layer_height = br.getBits(13);
+ CHECK(br.getBits(1)); // marker_bit
+
+ unsigned interlaced = br.getBits(1);
+
+ *width = video_object_layer_width;
+ *height = video_object_layer_height;
+
+ return true;
+}
+
+bool GetMPEGAudioFrameSize(
+ uint32_t header, size_t *frame_size,
+ int *out_sampling_rate, int *out_channels,
+ int *out_bitrate, int *out_num_samples) {
+ *frame_size = 0;
+
+ if (out_sampling_rate) {
+ *out_sampling_rate = 0;
+ }
+
+ if (out_channels) {
+ *out_channels = 0;
+ }
+
+ if (out_bitrate) {
+ *out_bitrate = 0;
+ }
+
+ if (out_num_samples) {
+ *out_num_samples = 1152;
+ }
+
+ if ((header & 0xffe00000) != 0xffe00000) {
+ return false;
+ }
+
+ unsigned version = (header >> 19) & 3;
+
+ if (version == 0x01) {
+ return false;
+ }
+
+ unsigned layer = (header >> 17) & 3;
+
+ if (layer == 0x00) {
+ return false;
+ }
+
+ unsigned protection = (header >> 16) & 1;
+
+ unsigned bitrate_index = (header >> 12) & 0x0f;
+
+ if (bitrate_index == 0 || bitrate_index == 0x0f) {
+ // Disallow "free" bitrate.
+ return false;
+ }
+
+ unsigned sampling_rate_index = (header >> 10) & 3;
+
+ if (sampling_rate_index == 3) {
+ return false;
+ }
+
+ static const int kSamplingRateV1[] = { 44100, 48000, 32000 };
+ int sampling_rate = kSamplingRateV1[sampling_rate_index];
+ if (version == 2 /* V2 */) {
+ sampling_rate /= 2;
+ } else if (version == 0 /* V2.5 */) {
+ sampling_rate /= 4;
+ }
+
+ unsigned padding = (header >> 9) & 1;
+
+ if (layer == 3) {
+ // layer I
+
+ static const int kBitrateV1[] = {
+ 32, 64, 96, 128, 160, 192, 224, 256,
+ 288, 320, 352, 384, 416, 448
+ };
+
+ static const int kBitrateV2[] = {
+ 32, 48, 56, 64, 80, 96, 112, 128,
+ 144, 160, 176, 192, 224, 256
+ };
+
+ int bitrate =
+ (version == 3 /* V1 */)
+ ? kBitrateV1[bitrate_index - 1]
+ : kBitrateV2[bitrate_index - 1];
+
+ if (out_bitrate) {
+ *out_bitrate = bitrate;
+ }
+
+ *frame_size = (12000 * bitrate / sampling_rate + padding) * 4;
+
+ if (out_num_samples) {
+ *out_num_samples = 384;
+ }
+ } else {
+ // layer II or III
+
+ static const int kBitrateV1L2[] = {
+ 32, 48, 56, 64, 80, 96, 112, 128,
+ 160, 192, 224, 256, 320, 384
+ };
+
+ static const int kBitrateV1L3[] = {
+ 32, 40, 48, 56, 64, 80, 96, 112,
+ 128, 160, 192, 224, 256, 320
+ };
+
+ static const int kBitrateV2[] = {
+ 8, 16, 24, 32, 40, 48, 56, 64,
+ 80, 96, 112, 128, 144, 160
+ };
+
+ int bitrate;
+ if (version == 3 /* V1 */) {
+ bitrate = (layer == 2 /* L2 */)
+ ? kBitrateV1L2[bitrate_index - 1]
+ : kBitrateV1L3[bitrate_index - 1];
+
+ if (out_num_samples) {
+ *out_num_samples = 1152;
+ }
+ } else {
+ // V2 (or 2.5)
+
+ bitrate = kBitrateV2[bitrate_index - 1];
+ if (out_num_samples) {
+ *out_num_samples = 576;
+ }
+ }
+
+ if (out_bitrate) {
+ *out_bitrate = bitrate;
+ }
+
+ if (version == 3 /* V1 */) {
+ *frame_size = 144000 * bitrate / sampling_rate + padding;
+ } else {
+ // V2 or V2.5
+ *frame_size = 72000 * bitrate / sampling_rate + padding;
+ }
+ }
+
+ if (out_sampling_rate) {
+ *out_sampling_rate = sampling_rate;
+ }
+
+ if (out_channels) {
+ int channel_mode = (header >> 6) & 3;
+
+ *out_channels = (channel_mode == 3) ? 1 : 2;
+ }
+
+ return true;
+}
+
} // namespace android
diff --git a/media/libstagefright/chromium_http/Android.mk b/media/libstagefright/chromium_http/Android.mk
new file mode 100644
index 0000000..6573e3c
--- /dev/null
+++ b/media/libstagefright/chromium_http/Android.mk
@@ -0,0 +1,23 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ ChromiumHTTPDataSource.cpp \
+ support.cpp \
+
+LOCAL_C_INCLUDES:= \
+ $(JNI_H_INCLUDE) \
+ frameworks/base/media/libstagefright \
+ $(TOP)/frameworks/base/include/media/stagefright/openmax \
+ external/chromium \
+ external/chromium/android
+
+LOCAL_CFLAGS += -Wno-multichar
+
+LOCAL_SHARED_LIBRARIES += libstlport
+include external/stlport/libstlport.mk
+
+LOCAL_MODULE:= libstagefright_chromium_http
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp b/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp
new file mode 100644
index 0000000..07a9eb8
--- /dev/null
+++ b/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp
@@ -0,0 +1,331 @@
+/*
+ * Copyright (C) 2011 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 "ChromiumHTTPDataSource"
+#include <media/stagefright/foundation/ADebug.h>
+
+#include "include/ChromiumHTTPDataSource.h"
+
+#include <media/stagefright/foundation/ALooper.h>
+#include <media/stagefright/MediaErrors.h>
+
+#include "support.h"
+
+#include <cutils/properties.h> // for property_get
+
+namespace android {
+
+ChromiumHTTPDataSource::ChromiumHTTPDataSource(uint32_t flags)
+ : mFlags(flags),
+ mState(DISCONNECTED),
+ mDelegate(new SfDelegate),
+ mCurrentOffset(0),
+ mIOResult(OK),
+ mContentSize(-1),
+ mDecryptHandle(NULL),
+ mDrmManagerClient(NULL) {
+ mDelegate->setOwner(this);
+}
+
+ChromiumHTTPDataSource::~ChromiumHTTPDataSource() {
+ disconnect();
+
+ delete mDelegate;
+ mDelegate = NULL;
+
+ if (mDrmManagerClient != NULL) {
+ delete mDrmManagerClient;
+ mDrmManagerClient = NULL;
+ }
+}
+
+status_t ChromiumHTTPDataSource::connect(
+ const char *uri,
+ const KeyedVector<String8, String8> *headers,
+ off64_t offset) {
+ Mutex::Autolock autoLock(mLock);
+
+ return connect_l(uri, headers, offset);
+}
+
+status_t ChromiumHTTPDataSource::connect_l(
+ const char *uri,
+ const KeyedVector<String8, String8> *headers,
+ off64_t offset) {
+ if (mState != DISCONNECTED) {
+ disconnect_l();
+ }
+
+ if (!(mFlags & kFlagIncognito)) {
+ LOG_PRI(ANDROID_LOG_INFO, LOG_TAG, "connect to %s @%lld", uri, offset);
+ } else {
+ LOG_PRI(ANDROID_LOG_INFO, LOG_TAG,
+ "connect to <URL suppressed> @%lld", offset);
+ }
+
+ mURI = uri;
+ mContentType = String8("application/octet-stream");
+
+ if (headers != NULL) {
+ mHeaders = *headers;
+ } else {
+ mHeaders.clear();
+ }
+
+ mState = CONNECTING;
+ mContentSize = -1;
+ mCurrentOffset = offset;
+
+ mDelegate->initiateConnection(mURI.c_str(), &mHeaders, offset);
+
+ while (mState == CONNECTING) {
+ mCondition.wait(mLock);
+ }
+
+ return mState == CONNECTED ? OK : mIOResult;
+}
+
+void ChromiumHTTPDataSource::onConnectionEstablished(
+ int64_t contentSize, const char *contentType) {
+ Mutex::Autolock autoLock(mLock);
+ mState = CONNECTED;
+ mContentSize = (contentSize < 0) ? -1 : contentSize + mCurrentOffset;
+ mContentType = String8(contentType);
+ mCondition.broadcast();
+}
+
+void ChromiumHTTPDataSource::onConnectionFailed(status_t err) {
+ Mutex::Autolock autoLock(mLock);
+ mState = DISCONNECTED;
+ mCondition.broadcast();
+
+ // mURI.clear();
+
+ mIOResult = err;
+
+ clearDRMState_l();
+}
+
+void ChromiumHTTPDataSource::disconnect() {
+ Mutex::Autolock autoLock(mLock);
+ disconnect_l();
+}
+
+void ChromiumHTTPDataSource::disconnect_l() {
+ if (mState == DISCONNECTED) {
+ return;
+ }
+
+ mState = DISCONNECTING;
+ mIOResult = -EINTR;
+
+ mDelegate->initiateDisconnect();
+
+ while (mState == DISCONNECTING) {
+ mCondition.wait(mLock);
+ }
+
+ CHECK_EQ((int)mState, (int)DISCONNECTED);
+}
+
+status_t ChromiumHTTPDataSource::initCheck() const {
+ Mutex::Autolock autoLock(mLock);
+
+ return mState == CONNECTED ? OK : NO_INIT;
+}
+
+ssize_t ChromiumHTTPDataSource::readAt(off64_t offset, void *data, size_t size) {
+ Mutex::Autolock autoLock(mLock);
+
+ if (mState != CONNECTED) {
+ return INVALID_OPERATION;
+ }
+
+#if 0
+ char value[PROPERTY_VALUE_MAX];
+ if (property_get("media.stagefright.disable-net", value, 0)
+ && (!strcasecmp(value, "true") || !strcmp(value, "1"))) {
+ LOG_PRI(ANDROID_LOG_INFO, LOG_TAG, "Simulating that the network is down.");
+ disconnect_l();
+ return ERROR_IO;
+ }
+#endif
+
+ if (offset != mCurrentOffset) {
+ AString tmp = mURI;
+ KeyedVector<String8, String8> tmpHeaders = mHeaders;
+
+ disconnect_l();
+
+ status_t err = connect_l(tmp.c_str(), &tmpHeaders, offset);
+
+ if (err != OK) {
+ return err;
+ }
+ }
+
+ mState = READING;
+
+ int64_t startTimeUs = ALooper::GetNowUs();
+
+ mDelegate->initiateRead(data, size);
+
+ while (mState == READING) {
+ mCondition.wait(mLock);
+ }
+
+ if (mIOResult < OK) {
+ return mIOResult;
+ }
+
+ if (mState == CONNECTED) {
+ int64_t delayUs = ALooper::GetNowUs() - startTimeUs;
+
+ // The read operation was successful, mIOResult contains
+ // the number of bytes read.
+ addBandwidthMeasurement(mIOResult, delayUs);
+
+ mCurrentOffset += mIOResult;
+ return mIOResult;
+ }
+
+ return ERROR_IO;
+}
+
+void ChromiumHTTPDataSource::onReadCompleted(ssize_t size) {
+ Mutex::Autolock autoLock(mLock);
+
+ mIOResult = size;
+
+ if (mState == READING) {
+ mState = CONNECTED;
+ mCondition.broadcast();
+ }
+}
+
+status_t ChromiumHTTPDataSource::getSize(off64_t *size) {
+ Mutex::Autolock autoLock(mLock);
+
+ if (mContentSize < 0) {
+ return ERROR_UNSUPPORTED;
+ }
+
+ *size = mContentSize;
+
+ return OK;
+}
+
+uint32_t ChromiumHTTPDataSource::flags() {
+ return kWantsPrefetching | kIsHTTPBasedSource;
+}
+
+// static
+void ChromiumHTTPDataSource::InitiateRead(
+ ChromiumHTTPDataSource *me, void *data, size_t size) {
+ me->initiateRead(data, size);
+}
+
+void ChromiumHTTPDataSource::initiateRead(void *data, size_t size) {
+ mDelegate->initiateRead(data, size);
+}
+
+void ChromiumHTTPDataSource::onDisconnectComplete() {
+ Mutex::Autolock autoLock(mLock);
+ CHECK_EQ((int)mState, (int)DISCONNECTING);
+
+ mState = DISCONNECTED;
+ // mURI.clear();
+
+ mCondition.broadcast();
+
+ clearDRMState_l();
+}
+
+sp<DecryptHandle> ChromiumHTTPDataSource::DrmInitialization() {
+ Mutex::Autolock autoLock(mLock);
+
+ if (mDrmManagerClient == NULL) {
+ mDrmManagerClient = new DrmManagerClient();
+ }
+
+ if (mDrmManagerClient == NULL) {
+ return NULL;
+ }
+
+ if (mDecryptHandle == NULL) {
+ /* Note if redirect occurs, mUri is the redirect uri instead of the
+ * original one
+ */
+ mDecryptHandle = mDrmManagerClient->openDecryptSession(
+ String8(mURI.c_str()));
+ }
+
+ if (mDecryptHandle == NULL) {
+ delete mDrmManagerClient;
+ mDrmManagerClient = NULL;
+ }
+
+ return mDecryptHandle;
+}
+
+void ChromiumHTTPDataSource::getDrmInfo(
+ sp<DecryptHandle> &handle, DrmManagerClient **client) {
+ Mutex::Autolock autoLock(mLock);
+
+ handle = mDecryptHandle;
+ *client = mDrmManagerClient;
+}
+
+String8 ChromiumHTTPDataSource::getUri() {
+ Mutex::Autolock autoLock(mLock);
+
+ return String8(mURI.c_str());
+}
+
+String8 ChromiumHTTPDataSource::getMIMEType() const {
+ Mutex::Autolock autoLock(mLock);
+
+ return mContentType;
+}
+
+void ChromiumHTTPDataSource::clearDRMState_l() {
+ if (mDecryptHandle != NULL) {
+ // To release mDecryptHandle
+ CHECK(mDrmManagerClient);
+ mDrmManagerClient->closeDecryptSession(mDecryptHandle);
+ mDecryptHandle = NULL;
+ }
+}
+
+status_t ChromiumHTTPDataSource::reconnectAtOffset(off64_t offset) {
+ Mutex::Autolock autoLock(mLock);
+
+ if (mURI.empty()) {
+ return INVALID_OPERATION;
+ }
+
+ LOG_PRI(ANDROID_LOG_INFO, LOG_TAG, "Reconnecting...");
+ status_t err = connect_l(mURI.c_str(), &mHeaders, offset);
+ if (err != OK) {
+ LOG_PRI(ANDROID_LOG_INFO, LOG_TAG, "Reconnect failed w/ err 0x%08x", err);
+ }
+
+ return err;
+}
+
+} // namespace android
+
diff --git a/media/libstagefright/chromium_http/support.cpp b/media/libstagefright/chromium_http/support.cpp
new file mode 100644
index 0000000..26c3eda
--- /dev/null
+++ b/media/libstagefright/chromium_http/support.cpp
@@ -0,0 +1,469 @@
+/*
+ * Copyright (C) 2011 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 "ChromiumHTTPDataSourceSupport"
+#include <utils/Log.h>
+
+#include <media/stagefright/foundation/AString.h>
+
+#include "support.h"
+
+#include "android/net/android_network_library_impl.h"
+#include "base/threading/thread.h"
+#include "net/base/cert_verifier.h"
+#include "net/base/cookie_monster.h"
+#include "net/base/host_resolver.h"
+#include "net/base/ssl_config_service.h"
+#include "net/http/http_auth_handler_factory.h"
+#include "net/http/http_cache.h"
+#include "net/proxy/proxy_config_service_android.h"
+
+#include "include/ChromiumHTTPDataSource.h"
+
+#include <cutils/properties.h>
+#include <media/stagefright/MediaErrors.h>
+
+namespace android {
+
+static Mutex gNetworkThreadLock;
+static base::Thread *gNetworkThread = NULL;
+static scoped_refptr<net::URLRequestContext> gReqContext;
+static scoped_ptr<net::NetworkChangeNotifier> gNetworkChangeNotifier;
+
+static void InitializeNetworkThreadIfNecessary() {
+ Mutex::Autolock autoLock(gNetworkThreadLock);
+ if (gNetworkThread == NULL) {
+ gNetworkThread = new base::Thread("network");
+ base::Thread::Options options;
+ options.message_loop_type = MessageLoop::TYPE_IO;
+ CHECK(gNetworkThread->StartWithOptions(options));
+
+ gReqContext = new SfRequestContext;
+
+ gNetworkChangeNotifier.reset(net::NetworkChangeNotifier::Create());
+
+ net::AndroidNetworkLibrary::RegisterSharedInstance(
+ new SfNetworkLibrary);
+ }
+}
+
+static void MY_LOGI(const char *s) {
+ LOG_PRI(ANDROID_LOG_INFO, LOG_TAG, "%s", s);
+}
+
+static void MY_LOGV(const char *s) {
+#if !defined(LOG_NDEBUG) || LOG_NDEBUG == 0
+ LOG_PRI(ANDROID_LOG_VERBOSE, LOG_TAG, "%s", s);
+#endif
+}
+
+SfNetLog::SfNetLog()
+ : mNextID(1) {
+}
+
+void SfNetLog::AddEntry(
+ EventType type,
+ const base::TimeTicks &time,
+ const Source &source,
+ EventPhase phase,
+ EventParameters *params) {
+#if 0
+ MY_LOGI(StringPrintf(
+ "AddEntry time=%s type=%s source=%s phase=%s\n",
+ TickCountToString(time).c_str(),
+ EventTypeToString(type),
+ SourceTypeToString(source.type),
+ EventPhaseToString(phase)).c_str());
+#endif
+}
+
+uint32 SfNetLog::NextID() {
+ return mNextID++;
+}
+
+net::NetLog::LogLevel SfNetLog::GetLogLevel() const {
+ return LOG_ALL;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+SfRequestContext::SfRequestContext() {
+ AString ua;
+ ua.append("stagefright/1.2 (Linux;Android ");
+
+#if (PROPERTY_VALUE_MAX < 8)
+#error "PROPERTY_VALUE_MAX must be at least 8"
+#endif
+
+ char value[PROPERTY_VALUE_MAX];
+ property_get("ro.build.version.release", value, "Unknown");
+ ua.append(value);
+ ua.append(")");
+
+ mUserAgent = ua.c_str();
+
+ set_net_log(new SfNetLog());
+
+ set_host_resolver(
+ net::CreateSystemHostResolver(
+ net::HostResolver::kDefaultParallelism,
+ NULL /* resolver_proc */,
+ net_log()));
+
+ set_ssl_config_service(
+ net::SSLConfigService::CreateSystemSSLConfigService());
+
+ set_proxy_service(net::ProxyService::CreateWithoutProxyResolver(
+ new net::ProxyConfigServiceAndroid, net_log()));
+
+ set_http_transaction_factory(new net::HttpCache(
+ host_resolver(),
+ new net::CertVerifier(),
+ dnsrr_resolver(),
+ dns_cert_checker(),
+ proxy_service(),
+ ssl_config_service(),
+ net::HttpAuthHandlerFactory::CreateDefault(host_resolver()),
+ network_delegate(),
+ net_log(),
+ NULL)); // backend_factory
+
+ set_cookie_store(new net::CookieMonster(NULL, NULL));
+}
+
+const std::string &SfRequestContext::GetUserAgent(const GURL &url) const {
+ return mUserAgent;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+SfNetworkLibrary::SfNetworkLibrary() {}
+
+SfNetworkLibrary::VerifyResult SfNetworkLibrary::VerifyX509CertChain(
+ const std::vector<std::string>& cert_chain,
+ const std::string& hostname,
+ const std::string& auth_type) {
+ return VERIFY_OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+SfDelegate::SfDelegate()
+ : mOwner(NULL),
+ mURLRequest(NULL),
+ mReadBuffer(new net::IOBufferWithSize(8192)),
+ mNumBytesRead(0),
+ mNumBytesTotal(0),
+ mDataDestination(NULL),
+ mAtEOS(false) {
+ InitializeNetworkThreadIfNecessary();
+}
+
+SfDelegate::~SfDelegate() {
+ CHECK(mURLRequest == NULL);
+}
+
+void SfDelegate::setOwner(ChromiumHTTPDataSource *owner) {
+ mOwner = owner;
+}
+
+void SfDelegate::OnReceivedRedirect(
+ net::URLRequest *request, const GURL &new_url, bool *defer_redirect) {
+ MY_LOGV("OnReceivedRedirect");
+}
+
+void SfDelegate::OnAuthRequired(
+ net::URLRequest *request, net::AuthChallengeInfo *auth_info) {
+ MY_LOGV("OnAuthRequired");
+
+ inherited::OnAuthRequired(request, auth_info);
+}
+
+void SfDelegate::OnCertificateRequested(
+ net::URLRequest *request, net::SSLCertRequestInfo *cert_request_info) {
+ MY_LOGV("OnCertificateRequested");
+
+ inherited::OnCertificateRequested(request, cert_request_info);
+}
+
+void SfDelegate::OnSSLCertificateError(
+ net::URLRequest *request, int cert_error, net::X509Certificate *cert) {
+ fprintf(stderr, "OnSSLCertificateError cert_error=%d\n", cert_error);
+
+ inherited::OnSSLCertificateError(request, cert_error, cert);
+}
+
+void SfDelegate::OnGetCookies(net::URLRequest *request, bool blocked_by_policy) {
+ MY_LOGV("OnGetCookies");
+}
+
+void SfDelegate::OnSetCookie(
+ net::URLRequest *request,
+ const std::string &cookie_line,
+ const net::CookieOptions &options,
+ bool blocked_by_policy) {
+ MY_LOGV("OnSetCookie");
+}
+
+void SfDelegate::OnResponseStarted(net::URLRequest *request) {
+ if (request->status().status() != net::URLRequestStatus::SUCCESS) {
+ MY_LOGI(StringPrintf(
+ "Request failed with status %d and os_error %d",
+ request->status().status(),
+ request->status().os_error()).c_str());
+
+ delete mURLRequest;
+ mURLRequest = NULL;
+
+ mOwner->onConnectionFailed(ERROR_IO);
+ return;
+ } else if (mRangeRequested && request->GetResponseCode() != 206) {
+ MY_LOGI(StringPrintf(
+ "We requested a content range, but server didn't "
+ "support that. (responded with %d)",
+ request->GetResponseCode()).c_str());
+
+ delete mURLRequest;
+ mURLRequest = NULL;
+
+ mOwner->onConnectionFailed(-EPIPE);
+ return;
+ } else if ((request->GetResponseCode() / 100) != 2) {
+ MY_LOGI(StringPrintf(
+ "Server responded with http status %d",
+ request->GetResponseCode()).c_str());
+
+ delete mURLRequest;
+ mURLRequest = NULL;
+
+ mOwner->onConnectionFailed(ERROR_IO);
+ return;
+ }
+
+ MY_LOGV("OnResponseStarted");
+
+ std::string headers;
+ request->GetAllResponseHeaders(&headers);
+
+ MY_LOGV(StringPrintf("response headers: %s", headers.c_str()).c_str());
+
+ std::string contentType;
+ request->GetResponseHeaderByName("Content-Type", &contentType);
+
+ mOwner->onConnectionEstablished(
+ request->GetExpectedContentSize(), contentType.c_str());
+}
+
+void SfDelegate::OnReadCompleted(net::URLRequest *request, int bytes_read) {
+ if (bytes_read == -1) {
+ MY_LOGI(StringPrintf(
+ "OnReadCompleted, read failed, status %d",
+ request->status().status()).c_str());
+
+ mOwner->onReadCompleted(ERROR_IO);
+ return;
+ }
+
+ MY_LOGV(StringPrintf("OnReadCompleted, read %d bytes", bytes_read).c_str());
+
+ if (bytes_read < 0) {
+ MY_LOGI(StringPrintf(
+ "Read failed w/ status %d\n",
+ request->status().status()).c_str());
+
+ mOwner->onReadCompleted(ERROR_IO);
+ return;
+ } else if (bytes_read == 0) {
+ mAtEOS = true;
+ mOwner->onReadCompleted(mNumBytesRead);
+ return;
+ }
+
+ CHECK_GT(bytes_read, 0);
+ CHECK_LE(mNumBytesRead + bytes_read, mNumBytesTotal);
+
+ memcpy((uint8_t *)mDataDestination + mNumBytesRead,
+ mReadBuffer->data(),
+ bytes_read);
+
+ mNumBytesRead += bytes_read;
+
+ readMore(request);
+}
+
+void SfDelegate::readMore(net::URLRequest *request) {
+ while (mNumBytesRead < mNumBytesTotal) {
+ size_t copy = mNumBytesTotal - mNumBytesRead;
+ if (copy > mReadBuffer->size()) {
+ copy = mReadBuffer->size();
+ }
+
+ int n;
+ if (request->Read(mReadBuffer, copy, &n)) {
+ MY_LOGV(StringPrintf("Read %d bytes directly.", n).c_str());
+
+ CHECK_LE((size_t)n, copy);
+
+ memcpy((uint8_t *)mDataDestination + mNumBytesRead,
+ mReadBuffer->data(),
+ n);
+
+ mNumBytesRead += n;
+
+ if (n == 0) {
+ mAtEOS = true;
+ break;
+ }
+ } else {
+ MY_LOGV("readMore pending read");
+
+ if (request->status().status() != net::URLRequestStatus::IO_PENDING) {
+ MY_LOGI(StringPrintf(
+ "Direct read failed w/ status %d\n",
+ request->status().status()).c_str());
+
+ mOwner->onReadCompleted(ERROR_IO);
+ return;
+ }
+
+ return;
+ }
+ }
+
+ mOwner->onReadCompleted(mNumBytesRead);
+}
+
+void SfDelegate::initiateConnection(
+ const char *uri,
+ const KeyedVector<String8, String8> *headers,
+ off64_t offset) {
+ GURL url(uri);
+
+ MessageLoop *loop = gNetworkThread->message_loop();
+ loop->PostTask(
+ FROM_HERE,
+ NewRunnableFunction(
+ &SfDelegate::OnInitiateConnectionWrapper,
+ this,
+ url,
+ headers,
+ offset));
+
+}
+
+// static
+void SfDelegate::OnInitiateConnectionWrapper(
+ SfDelegate *me, GURL url,
+ const KeyedVector<String8, String8> *headers,
+ off64_t offset) {
+ me->onInitiateConnection(url, headers, offset);
+}
+
+void SfDelegate::onInitiateConnection(
+ const GURL &url,
+ const KeyedVector<String8, String8> *extra,
+ off64_t offset) {
+ CHECK(mURLRequest == NULL);
+
+ mURLRequest = new net::URLRequest(url, this);
+ mAtEOS = false;
+
+ mRangeRequested = false;
+
+ if (offset != 0 || extra != NULL) {
+ net::HttpRequestHeaders headers =
+ mURLRequest->extra_request_headers();
+
+ if (offset != 0) {
+ headers.AddHeaderFromString(
+ StringPrintf("Range: bytes=%lld-", offset).c_str());
+
+ mRangeRequested = true;
+ }
+
+ if (extra != NULL) {
+ for (size_t i = 0; i < extra->size(); ++i) {
+ AString s;
+ s.append(extra->keyAt(i).string());
+ s.append(": ");
+ s.append(extra->valueAt(i).string());
+
+ headers.AddHeaderFromString(s.c_str());
+ }
+ }
+
+ mURLRequest->SetExtraRequestHeaders(headers);
+ }
+
+ mURLRequest->set_context(gReqContext);
+
+ mURLRequest->Start();
+}
+
+void SfDelegate::initiateDisconnect() {
+ MessageLoop *loop = gNetworkThread->message_loop();
+ loop->PostTask(
+ FROM_HERE,
+ NewRunnableFunction(
+ &SfDelegate::OnInitiateDisconnectWrapper, this));
+}
+
+// static
+void SfDelegate::OnInitiateDisconnectWrapper(SfDelegate *me) {
+ me->onInitiateDisconnect();
+}
+
+void SfDelegate::onInitiateDisconnect() {
+ mURLRequest->Cancel();
+
+ delete mURLRequest;
+ mURLRequest = NULL;
+
+ mOwner->onDisconnectComplete();
+}
+
+void SfDelegate::initiateRead(void *data, size_t size) {
+ MessageLoop *loop = gNetworkThread->message_loop();
+ loop->PostTask(
+ FROM_HERE,
+ NewRunnableFunction(
+ &SfDelegate::OnInitiateReadWrapper, this, data, size));
+}
+
+// static
+void SfDelegate::OnInitiateReadWrapper(
+ SfDelegate *me, void *data, size_t size) {
+ me->onInitiateRead(data, size);
+}
+
+void SfDelegate::onInitiateRead(void *data, size_t size) {
+ CHECK(mURLRequest != NULL);
+
+ mNumBytesRead = 0;
+ mNumBytesTotal = size;
+ mDataDestination = data;
+
+ if (mAtEOS) {
+ mOwner->onReadCompleted(0);
+ return;
+ }
+
+ readMore(mURLRequest);
+}
+
+} // namespace android
+
diff --git a/media/libstagefright/chromium_http/support.h b/media/libstagefright/chromium_http/support.h
new file mode 100644
index 0000000..8fe8db1
--- /dev/null
+++ b/media/libstagefright/chromium_http/support.h
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2011 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 SUPPORT_H_
+
+#define SUPPORT_H_
+
+#include <assert.h>
+
+#include "net/base/net_log.h"
+#include "net/url_request/url_request.h"
+#include "net/url_request/url_request_context.h"
+#include "net/base/android_network_library.h"
+#include "net/base/io_buffer.h"
+
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
+
+namespace android {
+
+struct SfNetLog : public net::NetLog {
+ SfNetLog();
+
+ virtual void AddEntry(
+ EventType type,
+ const base::TimeTicks &time,
+ const Source &source,
+ EventPhase phase,
+ EventParameters *params);
+
+ virtual uint32 NextID();
+ virtual LogLevel GetLogLevel() const;
+
+private:
+ uint32 mNextID;
+
+ DISALLOW_EVIL_CONSTRUCTORS(SfNetLog);
+};
+
+struct SfRequestContext : public net::URLRequestContext {
+ SfRequestContext();
+
+ virtual const std::string &GetUserAgent(const GURL &url) const;
+
+private:
+ std::string mUserAgent;
+
+ DISALLOW_EVIL_CONSTRUCTORS(SfRequestContext);
+};
+
+// This is required for https support, we don't really verify certificates,
+// we accept anything...
+struct SfNetworkLibrary : public net::AndroidNetworkLibrary {
+ SfNetworkLibrary();
+
+ virtual VerifyResult VerifyX509CertChain(
+ const std::vector<std::string>& cert_chain,
+ const std::string& hostname,
+ const std::string& auth_type);
+
+private:
+ DISALLOW_EVIL_CONSTRUCTORS(SfNetworkLibrary);
+};
+
+struct ChromiumHTTPDataSource;
+
+struct SfDelegate : public net::URLRequest::Delegate {
+ SfDelegate();
+ virtual ~SfDelegate();
+
+ void initiateConnection(
+ const char *uri,
+ const KeyedVector<String8, String8> *headers,
+ off64_t offset);
+
+ void initiateDisconnect();
+ void initiateRead(void *data, size_t size);
+
+ void setOwner(ChromiumHTTPDataSource *mOwner);
+
+ virtual void OnReceivedRedirect(
+ net::URLRequest *request, const GURL &new_url, bool *defer_redirect);
+
+ virtual void OnAuthRequired(
+ net::URLRequest *request, net::AuthChallengeInfo *auth_info);
+
+ virtual void OnCertificateRequested(
+ net::URLRequest *request, net::SSLCertRequestInfo *cert_request_info);
+
+ virtual void OnSSLCertificateError(
+ net::URLRequest *request, int cert_error, net::X509Certificate *cert);
+
+ virtual void OnGetCookies(net::URLRequest *request, bool blocked_by_policy);
+
+ virtual void OnSetCookie(
+ net::URLRequest *request,
+ const std::string &cookie_line,
+ const net::CookieOptions &options,
+ bool blocked_by_policy);
+
+ virtual void OnResponseStarted(net::URLRequest *request);
+
+ virtual void OnReadCompleted(net::URLRequest *request, int bytes_read);
+
+private:
+ typedef Delegate inherited;
+
+ ChromiumHTTPDataSource *mOwner;
+
+ net::URLRequest *mURLRequest;
+ scoped_refptr<net::IOBufferWithSize> mReadBuffer;
+
+ size_t mNumBytesRead;
+ size_t mNumBytesTotal;
+ void *mDataDestination;
+
+ bool mRangeRequested;
+ bool mAtEOS;
+
+ void readMore(net::URLRequest *request);
+
+ static void OnInitiateConnectionWrapper(
+ SfDelegate *me,
+ GURL url,
+ const KeyedVector<String8, String8> *headers,
+ off64_t offset);
+
+ static void OnInitiateDisconnectWrapper(SfDelegate *me);
+
+ static void OnInitiateReadWrapper(
+ SfDelegate *me, void *data, size_t size);
+
+ void onInitiateConnection(
+ const GURL &url,
+ const KeyedVector<String8, String8> *headers,
+ off64_t offset);
+
+ void onInitiateDisconnect();
+ void onInitiateRead(void *data, size_t size);
+
+ DISALLOW_EVIL_CONSTRUCTORS(SfDelegate);
+};
+
+} // namespace android
+
+#endif // SUPPORT_H_
diff --git a/media/libstagefright/codecs/aacdec/AACDecoder.cpp b/media/libstagefright/codecs/aacdec/AACDecoder.cpp
deleted file mode 100644
index 208431c..0000000
--- a/media/libstagefright/codecs/aacdec/AACDecoder.cpp
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * 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.
- */
-
-#include "AACDecoder.h"
-#define LOG_TAG "AACDecoder"
-
-#include "../../include/ESDS.h"
-
-#include "pvmp4audiodecoder_api.h"
-
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/MediaBufferGroup.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MetaData.h>
-
-namespace android {
-
-AACDecoder::AACDecoder(const sp<MediaSource> &source)
- : mSource(source),
- mStarted(false),
- mBufferGroup(NULL),
- mConfig(new tPVMP4AudioDecoderExternal),
- mDecoderBuf(NULL),
- mAnchorTimeUs(0),
- mNumSamplesOutput(0),
- mInputBuffer(NULL) {
-
- sp<MetaData> srcFormat = mSource->getFormat();
-
- int32_t sampleRate;
- CHECK(srcFormat->findInt32(kKeySampleRate, &sampleRate));
-
- mMeta = new MetaData;
- mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
-
- // We'll always output stereo, regardless of how many channels are
- // present in the input due to decoder limitations.
- mMeta->setInt32(kKeyChannelCount, 2);
- mMeta->setInt32(kKeySampleRate, sampleRate);
-
- int64_t durationUs;
- if (srcFormat->findInt64(kKeyDuration, &durationUs)) {
- mMeta->setInt64(kKeyDuration, durationUs);
- }
- mMeta->setCString(kKeyDecoderComponent, "AACDecoder");
-
- mInitCheck = initCheck();
-}
-
-status_t AACDecoder::initCheck() {
- memset(mConfig, 0, sizeof(tPVMP4AudioDecoderExternal));
- mConfig->outputFormat = OUTPUTFORMAT_16PCM_INTERLEAVED;
- mConfig->aacPlusEnabled = 1;
-
- // The software decoder doesn't properly support mono output on
- // AACplus files. Always output stereo.
- mConfig->desiredChannels = 2;
-
- UInt32 memRequirements = PVMP4AudioDecoderGetMemRequirements();
- mDecoderBuf = malloc(memRequirements);
-
- status_t err = PVMP4AudioDecoderInitLibrary(mConfig, mDecoderBuf);
- if (err != MP4AUDEC_SUCCESS) {
- LOGE("Failed to initialize MP4 audio decoder");
- return UNKNOWN_ERROR;
- }
-
- uint32_t type;
- const void *data;
- size_t size;
- sp<MetaData> meta = mSource->getFormat();
- if (meta->findData(kKeyESDS, &type, &data, &size)) {
- ESDS esds((const char *)data, size);
- CHECK_EQ(esds.InitCheck(), (status_t)OK);
-
- const void *codec_specific_data;
- size_t codec_specific_data_size;
- esds.getCodecSpecificInfo(
- &codec_specific_data, &codec_specific_data_size);
-
- mConfig->pInputBuffer = (UChar *)codec_specific_data;
- mConfig->inputBufferCurrentLength = codec_specific_data_size;
- mConfig->inputBufferMaxLength = 0;
-
- if (PVMP4AudioDecoderConfig(mConfig, mDecoderBuf)
- != MP4AUDEC_SUCCESS) {
- return ERROR_UNSUPPORTED;
- }
- }
- return OK;
-}
-
-AACDecoder::~AACDecoder() {
- if (mStarted) {
- stop();
- }
-
- delete mConfig;
- mConfig = NULL;
-}
-
-status_t AACDecoder::start(MetaData *params) {
- CHECK(!mStarted);
-
- mBufferGroup = new MediaBufferGroup;
- mBufferGroup->add_buffer(new MediaBuffer(4096 * 2));
-
- mSource->start();
-
- mAnchorTimeUs = 0;
- mNumSamplesOutput = 0;
- mStarted = true;
- mNumDecodedBuffers = 0;
- mUpsamplingFactor = 2;
-
- return OK;
-}
-
-status_t AACDecoder::stop() {
- CHECK(mStarted);
-
- if (mInputBuffer) {
- mInputBuffer->release();
- mInputBuffer = NULL;
- }
-
- free(mDecoderBuf);
- mDecoderBuf = NULL;
-
- delete mBufferGroup;
- mBufferGroup = NULL;
-
- mSource->stop();
-
- mStarted = false;
-
- return OK;
-}
-
-sp<MetaData> AACDecoder::getFormat() {
- return mMeta;
-}
-
-status_t AACDecoder::read(
- MediaBuffer **out, const ReadOptions *options) {
- status_t err;
-
- *out = NULL;
-
- int64_t seekTimeUs;
- ReadOptions::SeekMode mode;
- if (options && options->getSeekTo(&seekTimeUs, &mode)) {
- CHECK(seekTimeUs >= 0);
-
- mNumSamplesOutput = 0;
-
- if (mInputBuffer) {
- mInputBuffer->release();
- mInputBuffer = NULL;
- }
-
- // Make sure that the next buffer output does not still
- // depend on fragments from the last one decoded.
- PVMP4AudioDecoderResetBuffer(mDecoderBuf);
- } else {
- seekTimeUs = -1;
- }
-
- if (mInputBuffer == NULL) {
- err = mSource->read(&mInputBuffer, options);
-
- if (err != OK) {
- return err;
- }
-
- int64_t timeUs;
- if (mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) {
- mAnchorTimeUs = timeUs;
- mNumSamplesOutput = 0;
- } else {
- // We must have a new timestamp after seeking.
- CHECK(seekTimeUs < 0);
- }
- }
-
- MediaBuffer *buffer;
- CHECK_EQ(mBufferGroup->acquire_buffer(&buffer), (status_t)OK);
-
- mConfig->pInputBuffer =
- (UChar *)mInputBuffer->data() + mInputBuffer->range_offset();
-
- mConfig->inputBufferCurrentLength = mInputBuffer->range_length();
- mConfig->inputBufferMaxLength = 0;
- mConfig->inputBufferUsedLength = 0;
- mConfig->remainderBits = 0;
-
- mConfig->pOutputBuffer = static_cast<Int16 *>(buffer->data());
- mConfig->pOutputBuffer_plus = &mConfig->pOutputBuffer[2048];
- mConfig->repositionFlag = false;
-
- Int decoderErr = PVMP4AudioDecodeFrame(mConfig, mDecoderBuf);
-
- /*
- * AAC+/eAAC+ streams can be signalled in two ways: either explicitly
- * or implicitly, according to MPEG4 spec. AAC+/eAAC+ is a dual
- * rate system and the sampling rate in the final output is actually
- * doubled compared with the core AAC decoder sampling rate.
- *
- * Explicit signalling is done by explicitly defining SBR audio object
- * type in the bitstream. Implicit signalling is done by embedding
- * SBR content in AAC extension payload specific to SBR, and hence
- * requires an AAC decoder to perform pre-checks on actual audio frames.
- *
- * Thus, we could not say for sure whether a stream is
- * AAC+/eAAC+ until the first data frame is decoded.
- */
- if (++mNumDecodedBuffers <= 2) {
- LOGV("audio/extended audio object type: %d + %d",
- mConfig->audioObjectType, mConfig->extendedAudioObjectType);
- LOGV("aac+ upsampling factor: %d desired channels: %d",
- mConfig->aacPlusUpsamplingFactor, mConfig->desiredChannels);
-
- CHECK(mNumDecodedBuffers > 0);
- if (mNumDecodedBuffers == 1) {
- mUpsamplingFactor = mConfig->aacPlusUpsamplingFactor;
- // Check on the sampling rate to see whether it is changed.
- int32_t sampleRate;
- CHECK(mMeta->findInt32(kKeySampleRate, &sampleRate));
- if (mConfig->samplingRate != sampleRate) {
- mMeta->setInt32(kKeySampleRate, mConfig->samplingRate);
- LOGW("Sample rate was %d Hz, but now is %d Hz",
- sampleRate, mConfig->samplingRate);
- buffer->release();
- mInputBuffer->release();
- mInputBuffer = NULL;
- return INFO_FORMAT_CHANGED;
- }
- } else { // mNumDecodedBuffers == 2
- if (mConfig->extendedAudioObjectType == MP4AUDIO_AAC_LC ||
- mConfig->extendedAudioObjectType == MP4AUDIO_LTP) {
- if (mUpsamplingFactor == 2) {
- // The stream turns out to be not aacPlus mode anyway
- LOGW("Disable AAC+/eAAC+ since extended audio object type is %d",
- mConfig->extendedAudioObjectType);
- mConfig->aacPlusEnabled = 0;
- }
- } else {
- if (mUpsamplingFactor == 1) {
- // aacPlus mode does not buy us anything, but to cause
- // 1. CPU load to increase, and
- // 2. a half speed of decoding
- LOGW("Disable AAC+/eAAC+ since upsampling factor is 1");
- mConfig->aacPlusEnabled = 0;
- }
- }
- }
- }
-
- size_t numOutBytes =
- mConfig->frameLength * sizeof(int16_t) * mConfig->desiredChannels;
- if (mUpsamplingFactor == 2) {
- if (mConfig->desiredChannels == 1) {
- memcpy(&mConfig->pOutputBuffer[1024], &mConfig->pOutputBuffer[2048], numOutBytes * 2);
- }
- numOutBytes *= 2;
- }
-
- if (decoderErr != MP4AUDEC_SUCCESS) {
- LOGW("AAC decoder returned error %d, substituting silence", decoderErr);
-
- memset(buffer->data(), 0, numOutBytes);
-
- // Discard input buffer.
- mInputBuffer->release();
- mInputBuffer = NULL;
-
- // fall through
- }
-
- buffer->set_range(0, numOutBytes);
-
- if (mInputBuffer != NULL) {
- mInputBuffer->set_range(
- mInputBuffer->range_offset() + mConfig->inputBufferUsedLength,
- mInputBuffer->range_length() - mConfig->inputBufferUsedLength);
-
- if (mInputBuffer->range_length() == 0) {
- mInputBuffer->release();
- mInputBuffer = NULL;
- }
- }
-
- buffer->meta_data()->setInt64(
- kKeyTime,
- mAnchorTimeUs
- + (mNumSamplesOutput * 1000000) / mConfig->samplingRate);
-
- mNumSamplesOutput += mConfig->frameLength * mUpsamplingFactor;
-
- *out = buffer;
-
- return OK;
-}
-
-} // namespace android
diff --git a/media/libstagefright/codecs/aacdec/Android.mk b/media/libstagefright/codecs/aacdec/Android.mk
index 69e331f..20c7bc0 100644
--- a/media/libstagefright/codecs/aacdec/Android.mk
+++ b/media/libstagefright/codecs/aacdec/Android.mk
@@ -143,14 +143,38 @@
unpack_idx.cpp \
window_tables_fxp.cpp \
pvmp4setaudioconfig.cpp \
- AACDecoder.cpp
LOCAL_CFLAGS := -DAAC_PLUS -DHQ_SBR -DPARAMETRICSTEREO -DOSCL_IMPORT_REF= -DOSCL_EXPORT_REF= -DOSCL_UNUSED_ARG=
-LOCAL_C_INCLUDES := frameworks/base/media/libstagefright/include
+LOCAL_C_INCLUDES := \
+ frameworks/base/media/libstagefright/include \
LOCAL_ARM_MODE := arm
LOCAL_MODULE := libstagefright_aacdec
include $(BUILD_STATIC_LIBRARY)
+
+################################################################################
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ SoftAAC.cpp
+
+LOCAL_C_INCLUDES := \
+ frameworks/base/media/libstagefright/include \
+ frameworks/base/include/media/stagefright/openmax \
+
+LOCAL_CFLAGS := -DOSCL_IMPORT_REF=
+
+LOCAL_STATIC_LIBRARIES := \
+ libstagefright_aacdec
+
+LOCAL_SHARED_LIBRARIES := \
+ libstagefright_omx libstagefright_foundation libutils
+
+LOCAL_MODULE := libstagefright_soft_aacdec
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC.cpp b/media/libstagefright/codecs/aacdec/SoftAAC.cpp
new file mode 100644
index 0000000..bbd6dbb
--- /dev/null
+++ b/media/libstagefright/codecs/aacdec/SoftAAC.cpp
@@ -0,0 +1,457 @@
+/*
+ * Copyright (C) 2011 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 "SoftAAC"
+#include <utils/Log.h>
+
+#include "SoftAAC.h"
+
+#include "pvmp4audiodecoder_api.h"
+
+#include <media/stagefright/foundation/ADebug.h>
+
+namespace android {
+
+template<class T>
+static void InitOMXParams(T *params) {
+ params->nSize = sizeof(T);
+ params->nVersion.s.nVersionMajor = 1;
+ params->nVersion.s.nVersionMinor = 0;
+ params->nVersion.s.nRevision = 0;
+ params->nVersion.s.nStep = 0;
+}
+
+SoftAAC::SoftAAC(
+ const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component)
+ : SimpleSoftOMXComponent(name, callbacks, appData, component),
+ mConfig(new tPVMP4AudioDecoderExternal),
+ mDecoderBuf(NULL),
+ mInputBufferCount(0),
+ mUpsamplingFactor(2),
+ mAnchorTimeUs(0),
+ mNumSamplesOutput(0),
+ mSignalledError(false),
+ mOutputPortSettingsChange(NONE) {
+ initPorts();
+ CHECK_EQ(initDecoder(), (status_t)OK);
+}
+
+SoftAAC::~SoftAAC() {
+ free(mDecoderBuf);
+ mDecoderBuf = NULL;
+
+ delete mConfig;
+ mConfig = NULL;
+}
+
+void SoftAAC::initPorts() {
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ InitOMXParams(&def);
+
+ def.nPortIndex = 0;
+ def.eDir = OMX_DirInput;
+ def.nBufferCountMin = kNumBuffers;
+ def.nBufferCountActual = def.nBufferCountMin;
+ def.nBufferSize = 8192;
+ def.bEnabled = OMX_TRUE;
+ def.bPopulated = OMX_FALSE;
+ def.eDomain = OMX_PortDomainAudio;
+ def.bBuffersContiguous = OMX_FALSE;
+ def.nBufferAlignment = 1;
+
+ def.format.audio.cMIMEType = const_cast<char *>("audio/aac");
+ def.format.audio.pNativeRender = NULL;
+ def.format.audio.bFlagErrorConcealment = OMX_FALSE;
+ def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
+
+ addPort(def);
+
+ def.nPortIndex = 1;
+ def.eDir = OMX_DirOutput;
+ def.nBufferCountMin = kNumBuffers;
+ def.nBufferCountActual = def.nBufferCountMin;
+ def.nBufferSize = 8192;
+ def.bEnabled = OMX_TRUE;
+ def.bPopulated = OMX_FALSE;
+ def.eDomain = OMX_PortDomainAudio;
+ def.bBuffersContiguous = OMX_FALSE;
+ def.nBufferAlignment = 2;
+
+ def.format.audio.cMIMEType = const_cast<char *>("audio/raw");
+ def.format.audio.pNativeRender = NULL;
+ def.format.audio.bFlagErrorConcealment = OMX_FALSE;
+ def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
+
+ addPort(def);
+}
+
+status_t SoftAAC::initDecoder() {
+ memset(mConfig, 0, sizeof(tPVMP4AudioDecoderExternal));
+ mConfig->outputFormat = OUTPUTFORMAT_16PCM_INTERLEAVED;
+ mConfig->aacPlusEnabled = 1;
+
+ // The software decoder doesn't properly support mono output on
+ // AACplus files. Always output stereo.
+ mConfig->desiredChannels = 2;
+
+ UInt32 memRequirements = PVMP4AudioDecoderGetMemRequirements();
+ mDecoderBuf = malloc(memRequirements);
+
+ Int err = PVMP4AudioDecoderInitLibrary(mConfig, mDecoderBuf);
+ if (err != MP4AUDEC_SUCCESS) {
+ LOGE("Failed to initialize MP4 audio decoder");
+ return UNKNOWN_ERROR;
+ }
+
+ return OK;
+}
+
+OMX_ERRORTYPE SoftAAC::internalGetParameter(
+ OMX_INDEXTYPE index, OMX_PTR params) {
+ switch (index) {
+ case OMX_IndexParamAudioAac:
+ {
+ OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams =
+ (OMX_AUDIO_PARAM_AACPROFILETYPE *)params;
+
+ if (aacParams->nPortIndex != 0) {
+ return OMX_ErrorUndefined;
+ }
+
+ aacParams->nBitRate = 0;
+ aacParams->nAudioBandWidth = 0;
+ aacParams->nAACtools = 0;
+ aacParams->nAACERtools = 0;
+ aacParams->eAACProfile = OMX_AUDIO_AACObjectMain;
+ aacParams->eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
+ aacParams->eChannelMode = OMX_AUDIO_ChannelModeStereo;
+
+ if (!isConfigured()) {
+ aacParams->nChannels = 1;
+ aacParams->nSampleRate = 44100;
+ aacParams->nFrameLength = 0;
+ } else {
+ aacParams->nChannels = mConfig->encodedChannels;
+ aacParams->nSampleRate = mConfig->samplingRate;
+ aacParams->nFrameLength = mConfig->frameLength;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ case OMX_IndexParamAudioPcm:
+ {
+ OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
+ (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
+
+ if (pcmParams->nPortIndex != 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ pcmParams->eNumData = OMX_NumericalDataSigned;
+ pcmParams->eEndian = OMX_EndianBig;
+ pcmParams->bInterleaved = OMX_TRUE;
+ pcmParams->nBitPerSample = 16;
+ pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
+ pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
+ pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
+
+ if (!isConfigured()) {
+ pcmParams->nChannels = 1;
+ pcmParams->nSamplingRate = 44100;
+ } else {
+ pcmParams->nChannels = mConfig->desiredChannels;
+ pcmParams->nSamplingRate = mConfig->samplingRate;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ default:
+ return SimpleSoftOMXComponent::internalGetParameter(index, params);
+ }
+}
+
+OMX_ERRORTYPE SoftAAC::internalSetParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params) {
+ switch (index) {
+ case OMX_IndexParamStandardComponentRole:
+ {
+ const OMX_PARAM_COMPONENTROLETYPE *roleParams =
+ (const OMX_PARAM_COMPONENTROLETYPE *)params;
+
+ if (strncmp((const char *)roleParams->cRole,
+ "audio_decoder.aac",
+ OMX_MAX_STRINGNAME_SIZE - 1)) {
+ return OMX_ErrorUndefined;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ case OMX_IndexParamAudioAac:
+ {
+ const OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams =
+ (const OMX_AUDIO_PARAM_AACPROFILETYPE *)params;
+
+ if (aacParams->nPortIndex != 0) {
+ return OMX_ErrorUndefined;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ default:
+ return SimpleSoftOMXComponent::internalSetParameter(index, params);
+ }
+}
+
+bool SoftAAC::isConfigured() const {
+ return mInputBufferCount > 0;
+}
+
+void SoftAAC::onQueueFilled(OMX_U32 portIndex) {
+ if (mSignalledError || mOutputPortSettingsChange != NONE) {
+ return;
+ }
+
+ List<BufferInfo *> &inQueue = getPortQueue(0);
+ List<BufferInfo *> &outQueue = getPortQueue(1);
+
+ if (portIndex == 0 && mInputBufferCount == 0) {
+ ++mInputBufferCount;
+
+ BufferInfo *info = *inQueue.begin();
+ OMX_BUFFERHEADERTYPE *header = info->mHeader;
+
+ mConfig->pInputBuffer = header->pBuffer + header->nOffset;
+ mConfig->inputBufferCurrentLength = header->nFilledLen;
+ mConfig->inputBufferMaxLength = 0;
+
+ Int err = PVMP4AudioDecoderConfig(mConfig, mDecoderBuf);
+ if (err != MP4AUDEC_SUCCESS) {
+ mSignalledError = true;
+ notify(OMX_EventError, OMX_ErrorUndefined, err, NULL);
+ return;
+ }
+
+ inQueue.erase(inQueue.begin());
+ info->mOwnedByUs = false;
+ notifyEmptyBufferDone(header);
+
+ notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
+ mOutputPortSettingsChange = AWAITING_DISABLED;
+ return;
+ }
+
+ while (!inQueue.empty() && !outQueue.empty()) {
+ BufferInfo *inInfo = *inQueue.begin();
+ OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
+
+ BufferInfo *outInfo = *outQueue.begin();
+ OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
+
+ if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
+ inQueue.erase(inQueue.begin());
+ inInfo->mOwnedByUs = false;
+ notifyEmptyBufferDone(inHeader);
+
+ outHeader->nFilledLen = 0;
+ outHeader->nFlags = OMX_BUFFERFLAG_EOS;
+
+ outQueue.erase(outQueue.begin());
+ outInfo->mOwnedByUs = false;
+ notifyFillBufferDone(outHeader);
+ return;
+ }
+
+ if (inHeader->nOffset == 0) {
+ mAnchorTimeUs = inHeader->nTimeStamp;
+ mNumSamplesOutput = 0;
+ }
+
+ mConfig->pInputBuffer = inHeader->pBuffer + inHeader->nOffset;
+ mConfig->inputBufferCurrentLength = inHeader->nFilledLen;
+ mConfig->inputBufferMaxLength = 0;
+ mConfig->inputBufferUsedLength = 0;
+ mConfig->remainderBits = 0;
+
+ mConfig->pOutputBuffer =
+ reinterpret_cast<Int16 *>(outHeader->pBuffer + outHeader->nOffset);
+
+ mConfig->pOutputBuffer_plus = &mConfig->pOutputBuffer[2048];
+ mConfig->repositionFlag = false;
+
+ Int32 prevSamplingRate = mConfig->samplingRate;
+ Int decoderErr = PVMP4AudioDecodeFrame(mConfig, mDecoderBuf);
+
+ /*
+ * AAC+/eAAC+ streams can be signalled in two ways: either explicitly
+ * or implicitly, according to MPEG4 spec. AAC+/eAAC+ is a dual
+ * rate system and the sampling rate in the final output is actually
+ * doubled compared with the core AAC decoder sampling rate.
+ *
+ * Explicit signalling is done by explicitly defining SBR audio object
+ * type in the bitstream. Implicit signalling is done by embedding
+ * SBR content in AAC extension payload specific to SBR, and hence
+ * requires an AAC decoder to perform pre-checks on actual audio frames.
+ *
+ * Thus, we could not say for sure whether a stream is
+ * AAC+/eAAC+ until the first data frame is decoded.
+ */
+ if (mInputBufferCount <= 2) {
+ LOGV("audio/extended audio object type: %d + %d",
+ mConfig->audioObjectType, mConfig->extendedAudioObjectType);
+ LOGV("aac+ upsampling factor: %d desired channels: %d",
+ mConfig->aacPlusUpsamplingFactor, mConfig->desiredChannels);
+
+ if (mInputBufferCount == 1) {
+ mUpsamplingFactor = mConfig->aacPlusUpsamplingFactor;
+ // Check on the sampling rate to see whether it is changed.
+ if (mConfig->samplingRate != prevSamplingRate) {
+ LOGW("Sample rate was %d Hz, but now is %d Hz",
+ prevSamplingRate, mConfig->samplingRate);
+
+ // We'll hold onto the input buffer and will decode
+ // it again once the output port has been reconfigured.
+
+ notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
+ mOutputPortSettingsChange = AWAITING_DISABLED;
+ return;
+ }
+ } else { // mInputBufferCount == 2
+ if (mConfig->extendedAudioObjectType == MP4AUDIO_AAC_LC ||
+ mConfig->extendedAudioObjectType == MP4AUDIO_LTP) {
+ if (mUpsamplingFactor == 2) {
+ // The stream turns out to be not aacPlus mode anyway
+ LOGW("Disable AAC+/eAAC+ since extended audio object "
+ "type is %d",
+ mConfig->extendedAudioObjectType);
+ mConfig->aacPlusEnabled = 0;
+ }
+ } else {
+ if (mUpsamplingFactor == 1) {
+ // aacPlus mode does not buy us anything, but to cause
+ // 1. CPU load to increase, and
+ // 2. a half speed of decoding
+ LOGW("Disable AAC+/eAAC+ since upsampling factor is 1");
+ mConfig->aacPlusEnabled = 0;
+ }
+ }
+ }
+ }
+
+ size_t numOutBytes =
+ mConfig->frameLength * sizeof(int16_t) * mConfig->desiredChannels;
+
+ if (decoderErr == MP4AUDEC_SUCCESS) {
+ CHECK_LE(mConfig->inputBufferUsedLength, inHeader->nFilledLen);
+
+ inHeader->nFilledLen -= mConfig->inputBufferUsedLength;
+ inHeader->nOffset += mConfig->inputBufferUsedLength;
+ } else {
+ LOGW("AAC decoder returned error %d, substituting silence",
+ decoderErr);
+
+ memset(outHeader->pBuffer + outHeader->nOffset, 0, numOutBytes);
+
+ // Discard input buffer.
+ inHeader->nFilledLen = 0;
+
+ // fall through
+ }
+
+ if (mUpsamplingFactor == 2) {
+ if (mConfig->desiredChannels == 1) {
+ memcpy(&mConfig->pOutputBuffer[1024],
+ &mConfig->pOutputBuffer[2048],
+ numOutBytes * 2);
+ }
+ numOutBytes *= 2;
+ }
+
+ outHeader->nFilledLen = numOutBytes;
+ outHeader->nFlags = 0;
+
+ outHeader->nTimeStamp =
+ mAnchorTimeUs
+ + (mNumSamplesOutput * 1000000ll) / mConfig->samplingRate;
+
+ mNumSamplesOutput += mConfig->frameLength * mUpsamplingFactor;
+
+ if (inHeader->nFilledLen == 0) {
+ inInfo->mOwnedByUs = false;
+ inQueue.erase(inQueue.begin());
+ inInfo = NULL;
+ notifyEmptyBufferDone(inHeader);
+ inHeader = NULL;
+ }
+
+ outInfo->mOwnedByUs = false;
+ outQueue.erase(outQueue.begin());
+ outInfo = NULL;
+ notifyFillBufferDone(outHeader);
+ outHeader = NULL;
+
+ ++mInputBufferCount;
+ }
+}
+
+void SoftAAC::onPortFlushCompleted(OMX_U32 portIndex) {
+ if (portIndex == 0) {
+ // Make sure that the next buffer output does not still
+ // depend on fragments from the last one decoded.
+ PVMP4AudioDecoderResetBuffer(mDecoderBuf);
+ }
+}
+
+void SoftAAC::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
+ if (portIndex != 1) {
+ return;
+ }
+
+ switch (mOutputPortSettingsChange) {
+ case NONE:
+ break;
+
+ case AWAITING_DISABLED:
+ {
+ CHECK(!enabled);
+ mOutputPortSettingsChange = AWAITING_ENABLED;
+ break;
+ }
+
+ default:
+ {
+ CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED);
+ CHECK(enabled);
+ mOutputPortSettingsChange = NONE;
+ break;
+ }
+ }
+}
+
+} // namespace android
+
+android::SoftOMXComponent *createSoftOMXComponent(
+ const char *name, const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData, OMX_COMPONENTTYPE **component) {
+ return new android::SoftAAC(name, callbacks, appData, component);
+}
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC.h b/media/libstagefright/codecs/aacdec/SoftAAC.h
new file mode 100644
index 0000000..963fd27
--- /dev/null
+++ b/media/libstagefright/codecs/aacdec/SoftAAC.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2011 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 SOFT_AAC_H_
+
+#define SOFT_AAC_H_
+
+#include "SimpleSoftOMXComponent.h"
+
+struct tPVMP4AudioDecoderExternal;
+
+namespace android {
+
+struct SoftAAC : public SimpleSoftOMXComponent {
+ SoftAAC(const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component);
+
+protected:
+ virtual ~SoftAAC();
+
+ virtual OMX_ERRORTYPE internalGetParameter(
+ OMX_INDEXTYPE index, OMX_PTR params);
+
+ virtual OMX_ERRORTYPE internalSetParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params);
+
+ virtual void onQueueFilled(OMX_U32 portIndex);
+ virtual void onPortFlushCompleted(OMX_U32 portIndex);
+ virtual void onPortEnableCompleted(OMX_U32 portIndex, bool enabled);
+
+private:
+ enum {
+ kNumBuffers = 4
+ };
+
+ tPVMP4AudioDecoderExternal *mConfig;
+ void *mDecoderBuf;
+
+ size_t mInputBufferCount;
+ size_t mUpsamplingFactor;
+ int64_t mAnchorTimeUs;
+ int64_t mNumSamplesOutput;
+
+ bool mSignalledError;
+
+ enum {
+ NONE,
+ AWAITING_DISABLED,
+ AWAITING_ENABLED
+ } mOutputPortSettingsChange;
+
+ void initPorts();
+ status_t initDecoder();
+ bool isConfigured() const;
+
+ DISALLOW_EVIL_CONSTRUCTORS(SoftAAC);
+};
+
+} // namespace android
+
+#endif // SOFT_AAC_H_
diff --git a/media/libstagefright/codecs/aacdec/sbr_dec.cpp b/media/libstagefright/codecs/aacdec/sbr_dec.cpp
index 8fcc3ce..8519b17 100644
--- a/media/libstagefright/codecs/aacdec/sbr_dec.cpp
+++ b/media/libstagefright/codecs/aacdec/sbr_dec.cpp
@@ -1,5 +1,5 @@
/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
+ * Copyright (C) 1998-2010 PacketVideo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -447,7 +447,12 @@
if (xoverBand > sbrDec->highSubband)
{
- xoverBand = 32; /* error condition, default to upsampling mode */
+ /*
+ * error condition, default to upsampling mode
+ * and make sure that the number of bands for xover does
+ * not exceed the number of high freq bands.
+ */
+ xoverBand = (sbrDec->highSubband > 32)? 32: sbrDec->highSubband;
}
m = sbrDec->bufReadOffs + i; /* 2 + i */
@@ -558,18 +563,22 @@
/*
* Set Circular buffer for PS hybrid analysis
*/
+
+ int32_t *pt_temp = &scratch_mem[2][32];
+
for (i = 0, j = 0; i < 3; i++)
{
- pv_memmove(&scratch_mem[2][32 + j ],
+ pv_memmove(&pt_temp[ j],
hParametricStereoDec->hHybrid->mQmfBufferReal[i],
HYBRID_FILTER_LENGTH_m_1*sizeof(*hParametricStereoDec->hHybrid->mQmfBufferReal));
- pv_memmove(&scratch_mem[2][32 + j + 44],
+ pv_memmove(&pt_temp[ j + 44],
hParametricStereoDec->hHybrid->mQmfBufferImag[i],
HYBRID_FILTER_LENGTH_m_1*sizeof(*hParametricStereoDec->hHybrid->mQmfBufferImag));
j += 88;
}
+
pv_memset((void *)&qmf_PS_generated_Real[hParametricStereoDec->usb],
0,
(64 - hParametricStereoDec->usb)*sizeof(*qmf_PS_generated_Real));
@@ -626,19 +635,23 @@
* Save Circular buffer history used on PS hybrid analysis
*/
+
+ pt_temp = &scratch_mem[2][64];
+
for (i = 0, j = 0; i < 3; i++)
{
pv_memmove(hParametricStereoDec->hHybrid->mQmfBufferReal[i],
- &scratch_mem[2][ 64 + j ],
+ &pt_temp[ j],
HYBRID_FILTER_LENGTH_m_1*sizeof(*hParametricStereoDec->hHybrid->mQmfBufferReal));
pv_memmove(hParametricStereoDec->hHybrid->mQmfBufferImag[i],
- &scratch_mem[2][ 64 + j + 44],
+ &pt_temp[ j + 44],
HYBRID_FILTER_LENGTH_m_1*sizeof(*hParametricStereoDec->hHybrid->mQmfBufferImag));
j += 88;
}
+
pv_memmove(hFrameData->V, &circular_buffer_s[0], 1152*sizeof(*circular_buffer_s));
/*
@@ -746,7 +759,12 @@
if (xoverBand > sbrDec->highSubband)
{
- xoverBand = 32; /* error condition, default to upsampling mode */
+ /*
+ * error condition, default to upsampling mode
+ * and make sure that the number of bands for xover does
+ * not exceed the number of high freq bands.
+ */
+ xoverBand = (sbrDec->highSubband > 32)? 32: sbrDec->highSubband;
}
}
else
diff --git a/media/libstagefright/codecs/aacenc/AACEncoder.cpp b/media/libstagefright/codecs/aacenc/AACEncoder.cpp
index e4ff128..0bff52d 100644
--- a/media/libstagefright/codecs/aacenc/AACEncoder.cpp
+++ b/media/libstagefright/codecs/aacenc/AACEncoder.cpp
@@ -84,7 +84,7 @@
params.sampleRate = mSampleRate;
params.bitRate = mBitRate;
params.nChannels = mChannels;
- params.adtsUsed = 0; // For MP4 file, don't use adts format$
+ params.adtsUsed = 0; // We add adts header in the file writer if needed.
if (VO_ERR_NONE != mApiHandle->SetParam(mEncoderHandle, VO_PID_AAC_ENCPARAM, ¶ms)) {
LOGE("Failed to set AAC encoder parameters");
return UNKNOWN_ERROR;
diff --git a/media/libstagefright/codecs/aacenc/Android.mk b/media/libstagefright/codecs/aacenc/Android.mk
index 3782853..f9cc6a3 100644
--- a/media/libstagefright/codecs/aacenc/Android.mk
+++ b/media/libstagefright/codecs/aacenc/Android.mk
@@ -2,7 +2,7 @@
include $(CLEAR_VARS)
include frameworks/base/media/libstagefright/codecs/common/Config.mk
-LOCAL_PRELINK_MODULE := false
+
LOCAL_SRC_FILES := basic_op/basicop2.c basic_op/oper_32b.c
@@ -59,7 +59,7 @@
LOCAL_ARM_MODE := arm
-LOCAL_STATIC_LIBRARIES :=
+LOCAL_STATIC_LIBRARIES :=
LOCAL_SHARED_LIBRARIES :=
diff --git a/media/libstagefright/codecs/aacenc/SampleCode/AAC_E_SAMPLES.c b/media/libstagefright/codecs/aacenc/SampleCode/AAC_E_SAMPLES.c
index c7b2616..2ea9449 100644
--- a/media/libstagefright/codecs/aacenc/SampleCode/AAC_E_SAMPLES.c
+++ b/media/libstagefright/codecs/aacenc/SampleCode/AAC_E_SAMPLES.c
@@ -29,11 +29,11 @@
#include "cmnMemory.h"
#define VO_AAC_E_OUTPUT 1
-#define READ_SIZE (1024*8)
+#define READ_SIZE (1024*8)
unsigned char outBuf[1024*8];
unsigned char inBuf[READ_SIZE];
-const char* HelpString =
+const char* HelpString =
"VisualOn AAC encoder Usage:\n"
"voAACEncTest -if <inputfile.pcm> -of <outputfile.aac> -sr <samplerate> -ch <channel> -br <bitrate> -adts <adts> \n"
"-if input file name \n"
@@ -49,7 +49,7 @@
{
// notice that:
// bitRate/nChannels > 8000
- // bitRate/nChannels < 160000
+ // bitRate/nChannels < 160000
// bitRate/nChannels < sampleRate*6
param->adtsUsed = 1;
param->bitRate = 0;
@@ -69,7 +69,7 @@
{
argv++;
argc--;
- *input_filename = *argv;
+ *input_filename = *argv;
}
else if (!strcmp(*argv, "-of"))
{
@@ -188,7 +188,7 @@
useData.memflag = VO_IMF_USERMEMOPERATOR;
useData.memData = (VO_PTR)(&moper);
// open encoder dll;
- handle = dlopen("/data/local/tmp/libvoAACEncv7.so", RTLD_NOW);
+ handle = dlopen("libstagefright.so", RTLD_NOW);
if(handle == 0)
{
printf("open dll error......");
diff --git a/media/libstagefright/codecs/aacenc/SampleCode/Android.mk b/media/libstagefright/codecs/aacenc/SampleCode/Android.mk
index 9f168cb..ba3f4d2 100644
--- a/media/libstagefright/codecs/aacenc/SampleCode/Android.mk
+++ b/media/libstagefright/codecs/aacenc/SampleCode/Android.mk
@@ -1,24 +1,25 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_SRC_FILES := AAC_E_SAMPLES.c
+LOCAL_SRC_FILES := \
+ AAC_E_SAMPLES.c \
+ ../../common/cmnMemory.c
-LOCAL_SRC_FILES += \
- ../../../Common/cmnMemory.c
+LOCAL_CFLAGS += $(VO_CFLAGS)
-LOCAL_MODULE := TestvoAACEnc
+LOCAL_MODULE_TAGS := debug
+
+LOCAL_MODULE := AACEncTest
LOCAL_ARM_MODE := arm
-LOCAL_STATIC_LIBRARIES :=
-
-LOCAL_SHARED_LIBRARIES := libvoAACEnc
+LOCAL_SHARED_LIBRARIES := \
+ libstagefright \
+ libdl
LOCAL_C_INCLUDES := \
- $(LOCAL_PATH)/ \
- $(LOCAL_PATH)/../../../Common \
- $(LOCAL_PATH)/../../../Include \
-
-LOCAL_CFLAGS := $(VO_CFLAGS)
+ $(LOCAL_PATH)/ \
+ $(LOCAL_PATH)/../../common \
+ $(LOCAL_PATH)/../../common/include \
include $(BUILD_EXECUTABLE)
diff --git a/media/libstagefright/codecs/aacenc/SampleCode/eclair/Makefile b/media/libstagefright/codecs/aacenc/SampleCode/eclair/Makefile
deleted file mode 100644
index c6ec42f..0000000
--- a/media/libstagefright/codecs/aacenc/SampleCode/eclair/Makefile
+++ /dev/null
@@ -1,55 +0,0 @@
-#/*
-#** Copyright 2003-2010, VisualOn, Inc.
-#**
-#** 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.
-#*/
-
-# target6
-# available: pc, v4(armv4), v5(armv5), v5x(armv5 xscale), v6(armv6), v7(cortex-a8 neon)
-VOTT:= v7
-
-
-# module type
-# please specify the type of your module: lib or exe
-VOMT:= exe
-
-
-# module macros
-# please append the additional macro definitions here for your module if necessary.
-# e.g. -DVISUALON, macro VISUALON defined for your module
-VOMM:= #ARMV5E
-
-
-
-# please specify the name of your module
-VOTARGET:= voAACEncTestv7
-
-
-# please modify here to be sure to see the g1.mk
-include ../../../../Tools/eclair.mk
-
-# dependent libraries.
-VODEPLIBS:=-ldl
-
-# module source
-# please modify here to be sure to see the ms.mk which specifies all source info of your module
-include ../ms.mk
-
-
-# please specify where is the voRelease on your PC, relative path is suggested
-VORELDIR:=../../../../../Release/
-
-
-# please modify here to be sure to see the doit.mk
-include ../../../../Tools/doit.mk
-
diff --git a/media/libstagefright/codecs/aacenc/SampleCode/ms.mk b/media/libstagefright/codecs/aacenc/SampleCode/ms.mk
deleted file mode 100644
index b6255e8..0000000
--- a/media/libstagefright/codecs/aacenc/SampleCode/ms.mk
+++ /dev/null
@@ -1,23 +0,0 @@
-#/*
-#** Copyright 2003-2010, VisualOn, Inc.
-#**
-#** 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.
-#*/
-
-# please list all objects needed by your target here
-OBJS:=AAC_E_SAMPLES.o cmnMemory.o
-
-# please list all directories that all source files relative with your module(.h .c .cpp) locate
-VOSRCDIR:=../ ../../../../include ../../../../Common
-
-
diff --git a/media/libstagefright/codecs/aacenc/Tools/doit.mk b/media/libstagefright/codecs/aacenc/Tools/doit.mk
deleted file mode 100644
index 4924341..0000000
--- a/media/libstagefright/codecs/aacenc/Tools/doit.mk
+++ /dev/null
@@ -1,133 +0,0 @@
-#/*
-# ** Copyright 2003-2010, VisualOn, Inc.
-# **
-# ** 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.
-# */
-
-VERBOSE:=@
-
-
-VOMT ?= lib
-
-ifeq ($(VOMT), lib)
-LIB_STATIC=$(VOTARGET).a
-LIB_DYNAMIC=$(VOTARGET).so
-endif
-
-ifeq ($(VOMT), exe)
-TARGET=$(VOTARGET)
-endif
-
-CFLAGS=$(VOCFLAGS) $(addprefix -I, $(VOSRCDIR))
-CPPFLAGS=$(VOCPPFLAGS) $(addprefix -I, $(VOSRCDIR))
-ifneq ($(VOTT), pc)
-ASFLAGS=$(VOASFLAGS) $(addprefix -I, $(VOSRCDIR))
-endif
-
-LDFLAGS:=$(VOLDFLAGS)
-VOTEDEPS+=$(VODEPLIBS)
-VOTLDEPS+=$(VODEPLIBS)
-VOSTCLIBS ?=
-
-vpath %.c $(VOSRCDIR)
-vpath %.cpp $(VOSRCDIR)
-ifneq ($(VOTT), pc)
-vpath %.s $(VOSRCDIR)
-endif
-
-ifeq ($(VOTT), pc)
-BLTDIRS=$(VORELDIR)/Linux/static
-BLTDIRD=$(VORELDIR)/Linux/shared
-else
-BLTDIRS=$(VORELDIR)/Google/$(VONJ)/lib/$(VOTT)
-BLTDIRD=$(VORELDIR)/Google/$(VONJ)/so/$(VOTT)
-endif
-
-
-.PRECIOUS: $(OBJDIR)/%.o
-
-ifeq ($(VOMT), lib)
-all: mkdirs $(LIB_STATIC) $(LIB_DYNAMIC)
-mkdirs: $(OBJDIR) $(BLTDIRS) $(BLTDIRD)
-else
-all: mkdirs $(TARGET)
-mkdirs: $(OBJDIR)
-endif
-
-$(OBJDIR):
- @if test ! -d $@; then \
- mkdir -p $@; \
- fi;
-
-ifeq ($(VOMT), lib)
-$(BLTDIRS):
- @if test ! -d $@; then \
- mkdir -p $@; \
- fi;
-$(BLTDIRD):
- @if test ! -d $@; then \
- mkdir -p $@; \
- fi;
-endif
-
-
-ifeq ($(VOMT), lib)
-$(LIB_STATIC):$(OBJS)
- $(AR) cr $@ $(OBJDIR)/*.o $(VOSTCLIBS)
- $(RANLIB) $@
-ifneq ($(VODBG), yes)
- #$(STRIP) $@
-endif
-
-$(LIB_DYNAMIC):$(OBJS)
- $(GG) $(LDFLAGS) -o $@ $(OBJDIR)/*.o -Wl,--whole-archive $(VOSTCLIBS) -Wl,--no-whole-archive $(VOTLDEPS)
-ifneq ($(VODBG), yes)
- $(STRIP) $@
-endif
-
-else
-
-$(TARGET):$(OBJS)
- $(GG) $(LDFLAGS) -o $@ $(OBJDIR)/*.o -Wl,--whole-archive $(VOSTCLIBS) -Wl,--no-whole-archive $(VOTEDEPS)
-ifneq ($(VODBG), yes)
- $(STRIP) $@
-endif
-
-endif
-
-
-.SUFFIXES: .c .cpp .s .o
-.c.o:
- $(VERBOSE) $(CC) $(CFLAGS) -o $(OBJDIR)/$@ -c $<
-#%.c:$(OBJDIR)/%.o
-# $(VERBOSE) $(CC) $(CFLAGS) -o $@ -c $<
-.cpp.o:
- $(VERBOSE) $(GG) $(CPPFLAGS) -o $(OBJDIR)/$@ -c $<
-ifneq ($(VOTT), pc)
-.s.o:
- $(VERBOSE) $(AS) $(ASFLAGS) -o $(OBJDIR)/$@ $<
-endif
-
-
-.PHONY: clean devel
-clean:
-ifeq ($(VOMT), lib)
- -rm -fr $(OBJDIR) .*.sw* $(VOTARGET).*
-else
- -rm -fr $(OBJDIR) .*.sw* $(VOTARGET)
-endif
-
-devel:
- cp -a $(LIB_STATIC) $(BLTDIRS)
- cp -a $(LIB_DYNAMIC) $(BLTDIRD)
-
diff --git a/media/libstagefright/codecs/aacenc/Tools/eclair.mk b/media/libstagefright/codecs/aacenc/Tools/eclair.mk
deleted file mode 100644
index 41dd9c1..0000000
--- a/media/libstagefright/codecs/aacenc/Tools/eclair.mk
+++ /dev/null
@@ -1,172 +0,0 @@
-#/*
-# ** Copyright 2003-2010, VisualOn, Inc.
-# **
-# ** 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.
-# */
-
-# special macro definitions for building
-VOPREDEF=-DLINUX -D_LINUX
-
-VOPRJ ?=
-VONJ ?= eclair
-VOTT ?= v6
-# control the version to release out
-# available: eva(evaluation), rel(release)
-VOVER=
-ifeq ($(VOVER), eva)
-VOPREDEF+=-D__VOVER_EVA__
-endif
-
-# for debug or not: yes for debug, any other for release
-VODBG?=ye
-
-# for detecting memory leak
-VODML=
-ifeq ($(VODML), yes)
-VOPREDEF+=-DDMEMLEAK
-endif
-
-VOPREDEF+=-D__VOTT_ARM__ -D__VONJ_ECLAIR__
-TCROOTPATH:=/opt/eclair
-GCCVER:=4.4.0
-TCPATH:=$(TCROOTPATH)/prebuilt/linux-x86/toolchain/arm-eabi-$(GCCVER)
-CCTPRE:=$(TCPATH)/bin/arm-eabi-
-AS:=$(CCTPRE)as
-AR:=$(CCTPRE)ar
-NM:=$(CCTPRE)nm
-CC:=$(CCTPRE)gcc
-GG:=$(CCTPRE)g++
-LD:=$(CCTPRE)ld
-SIZE:=$(CCTPRE)size
-STRIP:=$(CCTPRE)strip
-RANLIB:=$(CCTPRE)ranlib
-OBJCOPY:=$(CCTPRE)objcopy
-OBJDUMP:=$(CCTPRE)objdump
-READELF:=$(CCTPRE)readelf
-STRINGS:=$(CCTPRE)strings
-
-# target product dependcy
-# available: dream, generic
-VOTP:=sapphire-open
-CCTLIB:=$(TCROOTPATH)/out/target/product/$(VOTP)/obj/lib
-CCTINC:=-I$(TCROOTPATH)/system/core/include \
- -I$(TCROOTPATH)/hardware/libhardware/include \
- -I$(TCROOTPATH)/hardware/ril/include \
- -I$(TCROOTPATH)/hardware/libhardware_legacy/include \
- -I$(TCROOTPATH)/dalvik/libnativehelper/include \
- -I$(TCROOTPATH)/dalvik/libnativehelper/include/nativehelper \
- -I$(TCROOTPATH)/frameworks/base/include \
- -I$(TCROOTPATH)/frameworks/base/core/jni \
- -I$(TCROOTPATH)/frameworks/base/libs/audioflinger \
- -I$(TCROOTPATH)/external/skia/include \
- -I$(TCROOTPATH)/out/target/product/$(VOTP)/obj/include \
- -I$(TCROOTPATH)/bionic/libc/arch-arm/include \
- -I$(TCROOTPATH)/bionic/libc/include \
- -I$(TCROOTPATH)/bionic/libstdc++/include \
- -I$(TCROOTPATH)/bionic/libc/kernel/common \
- -I$(TCROOTPATH)/bionic/libc/kernel/arch-arm \
- -I$(TCROOTPATH)/bionic/libm/include \
- -I$(TCROOTPATH)/bionic/libm/include/arm \
- -I$(TCROOTPATH)/bionic/libthread_db/include \
- -I$(TCROOTPATH)/bionic/libm/arm \
- -I$(TCROOTPATH)/bionic/libm \
- -I$(TCROOTPATH)/frameworks/base/include/android_runtime
- #-I$(TCROOTPATH)/out/target/product/$(VOTP)/obj/SHARED_LIBRARIES/libm_intermediates
-
-CCTCFLAGS:=-msoft-float -mthumb-interwork -fno-exceptions -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -fmessage-length=0 -finline-functions -finline-limit=600 -fno-inline-functions-called-once -fgcse-after-reload -frerun-cse-after-loop -frename-registers -fstrict-aliasing -funswitch-loops
-#-fwide-exec-charset=charset=UTF-32
-
-# for target exe
-TELDFLAGS:=-nostdlib -Bdynamic -Wl,-T,$(TCROOTPATH)/build/core/armelf.x -Wl,-dynamic-linker,/system/bin/linker -Wl,--gc-sections -Wl,-z,nocopyreloc -Wl,--no-undefined -Wl,-rpath-link=$(CCTLIB) -L$(CCTLIB)
-
-VOTEDEPS:=$(CCTLIB)/crtbegin_dynamic.o $(CCTLIB)/crtend_android.o $(TCPATH)/lib/gcc/arm-eabi/$(GCCVER)/interwork/libgcc.a -lc -lm
-
-# for target lib
-TLLDFLAGS:=-nostdlib -Wl,-T,$(TCROOTPATH)/build/core/armelf.xsc -Wl,--gc-sections -Wl,-shared,-Bsymbolic -L$(CCTLIB) -Wl,--no-whole-archive -Wl,--no-undefined $(TCPATH)/lib/gcc/arm-eabi/$(GCCVER)/interwork/libgcc.a
-
-VOTLDEPS:=-lm -lc
-
-
-ifeq ($(VOTT), v4)
-VOCFLAGS:=-mtune=arm9tdmi -march=armv4t
-VOASFLAGS:=-march=armv4t -mfpu=softfpa
-endif
-
-ifeq ($(VOTT), v5)
-VOCFLAGS:=-march=armv5te
-VOASFLAGS:=-march=armv5te -mfpu=vfp
-endif
-
-ifeq ($(VOTT), v5x)
-VOCFLAGS:=-march=armv5te -mtune=xscale
-VOASFLAGS:=-march=armv5te -mfpu=vfp
-endif
-
-ifeq ($(VOTT), v6)
-#VOCFLAGS:=-march=armv6 -mtune=arm1136jf-s
-#VOASFLAGS:=-march=armv6
-VOCFLAGS:=-march=armv6j -mtune=arm1136jf-s -mfpu=vfp -mfloat-abi=softfp -mapcs -mtpcs-leaf-frame -mlong-calls
-VOASFLAGS:=-march=armv6j -mcpu=arm1136jf-s -mfpu=arm1136jf-s -mfloat-abi=softfp -mapcs-float -mapcs-reentrant
-endif
-
-#
-# global link options
-VOLDFLAGS:=-Wl,-x,-X,--as-needed
-
-
-ifeq ($(VOTT), v7)
-VOCFLAGS+=-march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=softfp
-VOASFLAGS+=-march=armv7-a -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp
-VOLDFLAGS+=-Wl,--fix-cortex-a8
-endif
-
-#global compiling options for ARM target
-ifneq ($(VOTT), pc)
-VOASFLAGS+=--strip-local-absolute -R
-endif
-
-
-ifeq ($(VODBG), yes)
-VOCFLAGS+=-D_DEBUG -g
-else
-VOCFLAGS+=-DNDEBUG -O3
-endif
-
-VOCFLAGS+=$(VOPREDEF) $(VOMM) -Wall -fsigned-char -fomit-frame-pointer -fno-leading-underscore -fpic -fPIC -pipe -ftracer -fforce-addr -fno-bounds-check #-fvisibility=hidden #-fvisibility-inlines-hidden ##-ftree-loop-linear -mthumb -nostdinc -dD -fprefetch-loop-arrays
-
-
-ifneq ($(VOTT), pc)
-VOCFLAGS+=$(CCTCFLAGS) $(CCTINC)
-VOCPPFLAGS:=-fno-rtti $(VOCFLAGS)
-
-ifeq ($(VOMT), exe)
-VOLDFLAGS+=$(TELDFLAGS)
-endif
-
-ifeq ($(VOMT), lib)
-VOLDFLAGS+=$(TLLDFLAGS)
-endif
-else
-VOCPPFLAGS:=$(VOCFLAGS)
-ifeq ($(VOMT), lib)
-VOLDFLAGS+=-shared
-endif
-endif
-
-ifeq ($(VODBG), yes)
-#VOLDFLAGS:=
-endif
-
-# where to place object files
-OBJDIR=obj
-
diff --git a/media/libstagefright/codecs/aacenc/basic_op/basic_op.h b/media/libstagefright/codecs/aacenc/basic_op/basic_op.h
index ef3c31b..8291684 100644
--- a/media/libstagefright/codecs/aacenc/basic_op/basic_op.h
+++ b/media/libstagefright/codecs/aacenc/basic_op/basic_op.h
@@ -91,7 +91,7 @@
#else
Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2);
#endif
-
+
/* Long sub, 2 */
#if (L_SUB_IS_INLINE)
__inline Word32 L_sub(Word32 L_var1, Word32 L_var2);
@@ -119,7 +119,7 @@
#else
Word16 add (Word16 var1, Word16 var2);
#endif
-
+
/* Short sub, 1 */
#if (SUB_IS_INLINE)
__inline Word16 sub(Word16 var1, Word16 var2);
@@ -227,48 +227,48 @@
#if ARMV4_INASM
__inline Word32 ASM_L_shr(Word32 L_var1, Word16 var2)
{
- Word32 result;
- asm volatile(
- "MOV %[result], %[L_var1], ASR %[var2] \n"
+ Word32 result;
+ asm volatile(
+ "MOV %[result], %[L_var1], ASR %[var2] \n"
:[result]"=r"(result)
:[L_var1]"r"(L_var1), [var2]"r"(var2)
- );
- return result;
+ );
+ return result;
}
-
+
__inline Word32 ASM_L_shl(Word32 L_var1, Word16 var2)
{
- Word32 result;
- asm volatile(
+ Word32 result;
+ asm volatile(
"MOV r2, %[L_var1] \n"
"MOV r3, #0x7fffffff\n"
- "MOV %[result], %[L_var1], ASL %[var2] \n"
+ "MOV %[result], %[L_var1], ASL %[var2] \n"
"TEQ r2, %[result], ASR %[var2]\n"
"EORNE %[result],r3,r2,ASR#31\n"
:[result]"+r"(result)
:[L_var1]"r"(L_var1), [var2]"r"(var2)
:"r2", "r3"
- );
- return result;
+ );
+ return result;
}
__inline Word32 ASM_shr(Word32 L_var1, Word16 var2)
{
- Word32 result;
- asm volatile(
+ Word32 result;
+ asm volatile(
"CMP %[var2], #15\n"
"MOVGE %[var2], #15\n"
"MOV %[result], %[L_var1], ASR %[var2]\n"
:[result]"=r"(result)
- :[L_var1]"r"(L_var1), [var2]"r"(var2)
- );
- return result;
-}
+ :[L_var1]"r"(L_var1), [var2]"r"(var2)
+ );
+ return result;
+}
__inline Word32 ASM_shl(Word32 L_var1, Word16 var2)
{
- Word32 result;
- asm volatile(
+ Word32 result;
+ asm volatile(
"CMP %[var2], #16\n"
"MOVGE %[var2], #16\n"
"MOV %[result], %[L_var1], ASL %[var2]\n"
@@ -280,9 +280,9 @@
:[result]"+r"(result)
:[L_var1]"r"(L_var1), [var2]"r"(var2)
:"r2", "r3"
- );
- return result;
-}
+ );
+ return result;
+}
#endif
/*___________________________________________________________________________
@@ -300,17 +300,17 @@
"MOV r3, #1\n"
"MOV r2,%[L_var1],ASR#15\n"
"RSB r3, r3, r3, LSL #15\n"
- "TEQ r2,%[L_var1],ASR#31\n"
+ "TEQ r2,%[L_var1],ASR#31\n"
"EORNE %[result],r3,%[L_var1],ASR#31\n"
:[result]"+r"(result)
:[L_var1]"r"(L_var1)
- :"r2", "r3"
+ :"r2", "r3"
);
return result;
#else
Word16 var_out;
-
+
//var_out = (L_var1 > (Word32)0X00007fffL) ? (MAX_16) : ((L_var1 < (Word32)0xffff8000L) ? (MIN_16) : ((Word16)L_var1));
if (L_var1 > 0X00007fffL)
@@ -419,13 +419,13 @@
__inline Word32 L_mult(Word16 var1, Word16 var2)
{
#if ARMV5TE_L_MULT
- Word32 result;
- asm volatile(
- "SMULBB %[result], %[var1], %[var2] \n"
- "QADD %[result], %[result], %[result] \n"
+ Word32 result;
+ asm volatile(
+ "SMULBB %[result], %[var1], %[var2] \n"
+ "QADD %[result], %[result], %[result] \n"
:[result]"+r"(result)
:[var1]"r"(var1), [var2]"r"(var2)
- );
+ );
return result;
#else
Word32 L_var_out;
@@ -449,14 +449,14 @@
__inline Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2)
{
#if ARMV5TE_L_MSU
- Word32 result;
- asm volatile(
- "SMULBB %[result], %[var1], %[var2] \n"
+ Word32 result;
+ asm volatile(
+ "SMULBB %[result], %[var1], %[var2] \n"
"QADD %[result], %[result], %[result] \n"
"QSUB %[result], %[L_var3], %[result]\n"
:[result]"+r"(result)
:[L_var3]"r"(L_var3), [var1]"r"(var1), [var2]"r"(var2)
- );
+ );
return result;
#else
Word32 L_var_out;
@@ -473,12 +473,12 @@
__inline Word32 L_sub(Word32 L_var1, Word32 L_var2)
{
#if ARMV5TE_L_SUB
- Word32 result;
- asm volatile(
+ Word32 result;
+ asm volatile(
"QSUB %[result], %[L_var1], %[L_var2]\n"
:[result]"+r"(result)
:[L_var1]"r"(L_var1), [L_var2]"r"(L_var2)
- );
+ );
return result;
#else
Word32 L_var_out;
@@ -588,9 +588,9 @@
__inline Word16 add (Word16 var1, Word16 var2)
{
#if ARMV5TE_ADD
- Word32 result;
- asm volatile(
- "ADD %[result], %[var1], %[var2] \n"
+ Word32 result;
+ asm volatile(
+ "ADD %[result], %[var1], %[var2] \n"
"MOV r3, #0x1\n"
"MOV r2, %[result], ASR #15\n"
"RSB r3, r3, r3, LSL, #15\n"
@@ -599,7 +599,7 @@
:[result]"+r"(result)
:[var1]"r"(var1), [var2]"r"(var2)
:"r2", "r3"
- );
+ );
return result;
#else
Word16 var_out;
@@ -618,18 +618,18 @@
__inline Word16 sub(Word16 var1, Word16 var2)
{
#if ARMV5TE_SUB
- Word32 result;
- asm volatile(
+ Word32 result;
+ asm volatile(
"MOV r3, #1\n"
- "SUB %[result], %[var1], %[var2] \n"
+ "SUB %[result], %[var1], %[var2] \n"
"RSB r3,r3,r3,LSL#15\n"
- "MOV r2, %[var1], ASR #15 \n"
+ "MOV r2, %[var1], ASR #15 \n"
"TEQ r2, %[var1], ASR #31 \n"
"EORNE %[result], r3, %[result], ASR #31 \n"
:[result]"+r"(result)
:[var1]"r"(var1), [var2]"r"(var2)
:"r2", "r3"
- );
+ );
return result;
#else
Word16 var_out;
@@ -637,7 +637,7 @@
L_diff = (Word32) var1 - var2;
var_out = saturate(L_diff);
-
+
return (var_out);
#endif
}
@@ -657,16 +657,16 @@
{
var_out = 0;
L_num = (Word32) var1;
-
+
L_denom = (Word32) var2;
-
+
//return (L_num<<15)/var2;
for (iteration = 0; iteration < 15; iteration++)
{
var_out <<= 1;
L_num <<= 1;
-
+
if (L_num >= L_denom)
{
L_num -= L_denom;
@@ -683,8 +683,8 @@
__inline Word16 mult (Word16 var1, Word16 var2)
{
#if ARMV5TE_MULT
- Word32 result;
- asm volatile(
+ Word32 result;
+ asm volatile(
"SMULBB r2, %[var1], %[var2] \n"
"MOV r3, #1\n"
"MOV %[result], r2, ASR #15\n"
@@ -695,7 +695,7 @@
:[result]"+r"(result)
:[var1]"r"(var1), [var2]"r"(var2)
:"r2", "r3"
- );
+ );
return result;
#else
Word16 var_out;
@@ -718,8 +718,8 @@
__inline Word16 norm_s (Word16 var1)
{
#if ARMV5TE_NORM_S
- Word16 result;
- asm volatile(
+ Word16 result;
+ asm volatile(
"MOV r2,%[var1] \n"
"CMP r2, #0\n"
"RSBLT %[var1], %[var1], #0 \n"
@@ -727,11 +727,11 @@
"SUBNE %[result], %[result], #17\n"
"MOVEQ %[result], #0\n"
"CMP r2, #-1\n"
- "MOVEQ %[result], #15\n"
+ "MOVEQ %[result], #15\n"
:[result]"+r"(result)
:[var1]"r"(var1)
:"r2"
- );
+ );
return result;
#else
Word16 var_out;
@@ -768,15 +768,15 @@
__inline Word16 norm_l (Word32 L_var1)
{
#if ARMV5TE_NORM_L
- Word16 result;
- asm volatile(
+ Word16 result;
+ asm volatile(
"CMP %[L_var1], #0\n"
"CLZNE %[result], %[L_var1]\n"
- "SUBNE %[result], %[result], #1\n"
+ "SUBNE %[result], %[result], #1\n"
"MOVEQ %[result], #0\n"
:[result]"+r"(result)
:[L_var1]"r"(L_var1)
- );
+ );
return result;
#else
//Word16 var_out;
@@ -805,84 +805,84 @@
//}
//return (var_out);
Word16 a16;
- Word16 r = 0 ;
+ Word16 r = 0 ;
-
+
if ( L_var1 < 0 ) {
- L_var1 = ~L_var1;
+ L_var1 = ~L_var1;
}
if (0 == (L_var1 & 0x7fff8000)) {
a16 = extract_l(L_var1);
r += 16;
-
+
if (0 == (a16 & 0x7f80)) {
r += 8;
-
+
if (0 == (a16 & 0x0078)) {
r += 4;
-
+
if (0 == (a16 & 0x0006)) {
r += 2;
-
+
if (0 == (a16 & 0x0001)) {
r += 1;
}
}
else {
-
+
if (0 == (a16 & 0x0004)) {
r += 1;
}
}
}
else {
-
+
if (0 == (a16 & 0x0060)) {
r += 2;
-
+
if (0 == (a16 & 0x0010)) {
r += 1;
}
}
else {
-
+
if (0 == (a16 & 0x0040)) {
r += 1;
}
}
}
- }
- else {
-
+ }
+ else {
+
if (0 == (a16 & 0x7800)) {
r += 4;
-
+
if (0 == (a16 & 0x0600)) {
r += 2;
-
+
if (0 == (a16 & 0x0100)) {
r += 1;
}
}
else {
-
+
if (0 == (a16 & 0x0400)) {
r += 1;
}
}
}
else {
-
+
if (0 == (a16 & 0x6000)) {
r += 2;
-
+
if (0 == (a16 & 0x1000)) {
r += 1;
}
}
else {
-
+
if (0 == (a16 & 0x4000)) {
r += 1;
}
@@ -892,38 +892,38 @@
}
else {
a16 = extract_h(L_var1);
-
+
if (0 == (a16 & 0x7f80)) {
r += 8;
-
+
if (0 == (a16 & 0x0078)) {
r += 4 ;
-
+
if (0 == (a16 & 0x0006)) {
r += 2;
-
+
if (0 == (a16 & 0x0001)) {
r += 1;
}
}
else {
-
+
if (0 == (a16 & 0x0004)) {
r += 1;
}
}
}
else {
-
+
if (0 == (a16 & 0x0060)) {
r += 2;
-
+
if (0 == (a16 & 0x0010)) {
r += 1;
}
}
else {
-
+
if (0 == (a16 & 0x0040)) {
r += 1;
}
@@ -931,35 +931,35 @@
}
}
else {
-
+
if (0 == (a16 & 0x7800)) {
r += 4;
-
+
if (0 == (a16 & 0x0600)) {
r += 2;
-
+
if (0 == (a16 & 0x0100)) {
r += 1;
}
}
else {
-
+
if (0 == (a16 & 0x0400)) {
r += 1;
}
}
}
else {
-
+
if (0 == (a16 & 0x6000)) {
r += 2;
-
+
if (0 == (a16 & 0x1000)) {
r += 1;
}
}
else {
-
+
if (0 == (a16 & 0x4000)) {
return 1;
}
@@ -967,7 +967,7 @@
}
}
}
-
+
return r ;
#endif
}
@@ -978,17 +978,17 @@
__inline Word16 round16(Word32 L_var1)
{
#if ARMV5TE_ROUND
- Word16 result;
- asm volatile(
+ Word16 result;
+ asm volatile(
"MOV r1,#0x00008000\n"
"QADD %[result], %[L_var1], r1\n"
- "MOV %[result], %[result], ASR #16 \n"
+ "MOV %[result], %[result], ASR #16 \n"
:[result]"+r"(result)
:[L_var1]"r"(L_var1)
:"r1"
- );
+ );
return result;
-#else
+#else
Word16 var_out;
Word32 L_rounded;
@@ -1004,14 +1004,14 @@
__inline Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2)
{
#if ARMV5TE_L_MAC
- Word32 result;
- asm volatile(
+ Word32 result;
+ asm volatile(
"SMULBB %[result], %[var1], %[var2]\n"
"QADD %[result], %[result], %[result]\n"
"QADD %[result], %[result], %[L_var3]\n"
:[result]"+r"(result)
: [L_var3]"r"(L_var3), [var1]"r"(var1), [var2]"r"(var2)
- );
+ );
return result;
#else
Word32 L_var_out;
@@ -1028,12 +1028,12 @@
__inline Word32 L_add (Word32 L_var1, Word32 L_var2)
{
#if ARMV5TE_L_ADD
- Word32 result;
- asm volatile(
+ Word32 result;
+ asm volatile(
"QADD %[result], %[L_var1], %[L_var2]\n"
:[result]"+r"(result)
:[L_var1]"r"(L_var1), [L_var2]"r"(L_var2)
- );
+ );
return result;
#else
Word32 L_var_out;
@@ -1114,7 +1114,7 @@
L_var3 = L_msu (L_var3, var1, var2);
var_out = (Word16)((L_var3 + 0x8000L) >> 16);
-
+
return (var_out);
}
#endif
diff --git a/media/libstagefright/codecs/aacenc/basic_op/basicop2.c b/media/libstagefright/codecs/aacenc/basic_op/basicop2.c
index d43bbd9..82d3f38 100644
--- a/media/libstagefright/codecs/aacenc/basic_op/basicop2.c
+++ b/media/libstagefright/codecs/aacenc/basic_op/basicop2.c
@@ -16,7 +16,7 @@
/*******************************************************************************
File: basicop2.c
- Content: Basic arithmetic operators.
+ Content: Basic arithmetic operators.
*******************************************************************************/
@@ -462,7 +462,7 @@
{
L_var_out = MAX_32;
}
-
+
return (L_var_out);
}
#endif
diff --git a/media/libstagefright/codecs/aacenc/basic_op/oper_32b.c b/media/libstagefright/codecs/aacenc/basic_op/oper_32b.c
index e48af9d..0ad82f0 100644
--- a/media/libstagefright/codecs/aacenc/basic_op/oper_32b.c
+++ b/media/libstagefright/codecs/aacenc/basic_op/oper_32b.c
@@ -17,7 +17,7 @@
File: oper_32b.c
Content: This file contains operations in double precision.
-
+
*******************************************************************************/
#include "typedef.h"
@@ -200,12 +200,12 @@
}
/*!
-
- \brief calculates the log dualis times 4 of argument
+
+ \brief calculates the log dualis times 4 of argument
iLog4(x) = (Word32)(4 * log(value)/log(2.0))
\return ilog4 value
-
+
*/
Word16 iLog4(Word32 value)
{
@@ -225,7 +225,7 @@
iLog4 = (-(iLog4 << 2) - norm_s(tmp16)) - 1;
}
else {
- iLog4 = -128; /* -(INT_BITS*4); */
+ iLog4 = -128; /* -(INT_BITS*4); */
}
return iLog4;
@@ -268,79 +268,79 @@
}
static const Word32 pow2Table[POW2_TABLE_SIZE] = {
-0x7fffffff, 0x7fa765ad, 0x7f4f08ae, 0x7ef6e8da,
-0x7e9f0606, 0x7e476009, 0x7deff6b6, 0x7d98c9e6,
-0x7d41d96e, 0x7ceb2523, 0x7c94acde, 0x7c3e7073,
-0x7be86fb9, 0x7b92aa88, 0x7b3d20b6, 0x7ae7d21a,
-0x7a92be8b, 0x7a3de5df, 0x79e947ef, 0x7994e492,
-0x7940bb9e, 0x78ecccec, 0x78991854, 0x78459dac,
-0x77f25cce, 0x779f5591, 0x774c87cc, 0x76f9f359,
-0x76a7980f, 0x765575c8, 0x76038c5b, 0x75b1dba2,
-0x75606374, 0x750f23ab, 0x74be1c20, 0x746d4cac,
-0x741cb528, 0x73cc556d, 0x737c2d55, 0x732c3cba,
-0x72dc8374, 0x728d015d, 0x723db650, 0x71eea226,
-0x719fc4b9, 0x71511de4, 0x7102ad80, 0x70b47368,
-0x70666f76, 0x7018a185, 0x6fcb096f, 0x6f7da710,
-0x6f307a41, 0x6ee382de, 0x6e96c0c3, 0x6e4a33c9,
-0x6dfddbcc, 0x6db1b8a8, 0x6d65ca38, 0x6d1a1057,
-0x6cce8ae1, 0x6c8339b2, 0x6c381ca6, 0x6bed3398,
-0x6ba27e66, 0x6b57fce9, 0x6b0daeff, 0x6ac39485,
-0x6a79ad56, 0x6a2ff94f, 0x69e6784d, 0x699d2a2c,
-0x69540ec9, 0x690b2601, 0x68c26fb1, 0x6879ebb6,
-0x683199ed, 0x67e97a34, 0x67a18c68, 0x6759d065,
-0x6712460b, 0x66caed35, 0x6683c5c3, 0x663ccf92,
-0x65f60a80, 0x65af766a, 0x6569132f, 0x6522e0ad,
-0x64dcdec3, 0x64970d4f, 0x64516c2e, 0x640bfb41,
-0x63c6ba64, 0x6381a978, 0x633cc85b, 0x62f816eb,
-0x62b39509, 0x626f4292, 0x622b1f66, 0x61e72b65,
-0x61a3666d, 0x615fd05f, 0x611c6919, 0x60d9307b,
-0x60962665, 0x60534ab7, 0x60109d51, 0x5fce1e12,
-0x5f8bccdb, 0x5f49a98c, 0x5f07b405, 0x5ec5ec26,
-0x5e8451d0, 0x5e42e4e3, 0x5e01a540, 0x5dc092c7,
-0x5d7fad59, 0x5d3ef4d7, 0x5cfe6923, 0x5cbe0a1c,
-0x5c7dd7a4, 0x5c3dd19c, 0x5bfdf7e5, 0x5bbe4a61,
-0x5b7ec8f2, 0x5b3f7377, 0x5b0049d4, 0x5ac14bea,
-0x5a82799a, 0x5a43d2c6, 0x5a055751, 0x59c7071c,
-0x5988e209, 0x594ae7fb, 0x590d18d3, 0x58cf7474,
-0x5891fac1, 0x5854ab9b, 0x581786e6, 0x57da8c83,
-0x579dbc57, 0x57611642, 0x57249a29, 0x56e847ef,
-0x56ac1f75, 0x567020a0, 0x56344b52, 0x55f89f70,
-0x55bd1cdb, 0x5581c378, 0x55469329, 0x550b8bd4,
-0x54d0ad5b, 0x5495f7a1, 0x545b6a8b, 0x542105fd,
-0x53e6c9db, 0x53acb607, 0x5372ca68, 0x533906e0,
-0x52ff6b55, 0x52c5f7aa, 0x528cabc3, 0x52538786,
-0x521a8ad7, 0x51e1b59a, 0x51a907b4, 0x5170810b,
-0x51382182, 0x50ffe8fe, 0x50c7d765, 0x508fec9c,
-0x50582888, 0x50208b0e, 0x4fe91413, 0x4fb1c37c,
-0x4f7a9930, 0x4f439514, 0x4f0cb70c, 0x4ed5ff00,
-0x4e9f6cd4, 0x4e69006e, 0x4e32b9b4, 0x4dfc988c,
-0x4dc69cdd, 0x4d90c68b, 0x4d5b157e, 0x4d25899c,
-0x4cf022ca, 0x4cbae0ef, 0x4c85c3f1, 0x4c50cbb8,
-0x4c1bf829, 0x4be7492b, 0x4bb2bea5, 0x4b7e587d,
-0x4b4a169c, 0x4b15f8e6, 0x4ae1ff43, 0x4aae299b,
-0x4a7a77d5, 0x4a46e9d6, 0x4a137f88, 0x49e038d0,
-0x49ad1598, 0x497a15c4, 0x4947393f, 0x49147fee,
-0x48e1e9ba, 0x48af768a, 0x487d2646, 0x484af8d6,
-0x4818ee22, 0x47e70611, 0x47b5408c, 0x47839d7b,
-0x47521cc6, 0x4720be55, 0x46ef8210, 0x46be67e0,
-0x468d6fae, 0x465c9961, 0x462be4e2, 0x45fb521a,
-0x45cae0f2, 0x459a9152, 0x456a6323, 0x453a564d,
-0x450a6abb, 0x44daa054, 0x44aaf702, 0x447b6ead,
-0x444c0740, 0x441cc0a3, 0x43ed9ac0, 0x43be9580,
-0x438fb0cb, 0x4360ec8d, 0x433248ae, 0x4303c517,
-0x42d561b4, 0x42a71e6c, 0x4278fb2b, 0x424af7da,
-0x421d1462, 0x41ef50ae, 0x41c1aca8, 0x41942839,
-0x4166c34c, 0x41397dcc, 0x410c57a2, 0x40df50b8,
-0x40b268fa, 0x4085a051, 0x4058f6a8, 0x402c6be9
+0x7fffffff, 0x7fa765ad, 0x7f4f08ae, 0x7ef6e8da,
+0x7e9f0606, 0x7e476009, 0x7deff6b6, 0x7d98c9e6,
+0x7d41d96e, 0x7ceb2523, 0x7c94acde, 0x7c3e7073,
+0x7be86fb9, 0x7b92aa88, 0x7b3d20b6, 0x7ae7d21a,
+0x7a92be8b, 0x7a3de5df, 0x79e947ef, 0x7994e492,
+0x7940bb9e, 0x78ecccec, 0x78991854, 0x78459dac,
+0x77f25cce, 0x779f5591, 0x774c87cc, 0x76f9f359,
+0x76a7980f, 0x765575c8, 0x76038c5b, 0x75b1dba2,
+0x75606374, 0x750f23ab, 0x74be1c20, 0x746d4cac,
+0x741cb528, 0x73cc556d, 0x737c2d55, 0x732c3cba,
+0x72dc8374, 0x728d015d, 0x723db650, 0x71eea226,
+0x719fc4b9, 0x71511de4, 0x7102ad80, 0x70b47368,
+0x70666f76, 0x7018a185, 0x6fcb096f, 0x6f7da710,
+0x6f307a41, 0x6ee382de, 0x6e96c0c3, 0x6e4a33c9,
+0x6dfddbcc, 0x6db1b8a8, 0x6d65ca38, 0x6d1a1057,
+0x6cce8ae1, 0x6c8339b2, 0x6c381ca6, 0x6bed3398,
+0x6ba27e66, 0x6b57fce9, 0x6b0daeff, 0x6ac39485,
+0x6a79ad56, 0x6a2ff94f, 0x69e6784d, 0x699d2a2c,
+0x69540ec9, 0x690b2601, 0x68c26fb1, 0x6879ebb6,
+0x683199ed, 0x67e97a34, 0x67a18c68, 0x6759d065,
+0x6712460b, 0x66caed35, 0x6683c5c3, 0x663ccf92,
+0x65f60a80, 0x65af766a, 0x6569132f, 0x6522e0ad,
+0x64dcdec3, 0x64970d4f, 0x64516c2e, 0x640bfb41,
+0x63c6ba64, 0x6381a978, 0x633cc85b, 0x62f816eb,
+0x62b39509, 0x626f4292, 0x622b1f66, 0x61e72b65,
+0x61a3666d, 0x615fd05f, 0x611c6919, 0x60d9307b,
+0x60962665, 0x60534ab7, 0x60109d51, 0x5fce1e12,
+0x5f8bccdb, 0x5f49a98c, 0x5f07b405, 0x5ec5ec26,
+0x5e8451d0, 0x5e42e4e3, 0x5e01a540, 0x5dc092c7,
+0x5d7fad59, 0x5d3ef4d7, 0x5cfe6923, 0x5cbe0a1c,
+0x5c7dd7a4, 0x5c3dd19c, 0x5bfdf7e5, 0x5bbe4a61,
+0x5b7ec8f2, 0x5b3f7377, 0x5b0049d4, 0x5ac14bea,
+0x5a82799a, 0x5a43d2c6, 0x5a055751, 0x59c7071c,
+0x5988e209, 0x594ae7fb, 0x590d18d3, 0x58cf7474,
+0x5891fac1, 0x5854ab9b, 0x581786e6, 0x57da8c83,
+0x579dbc57, 0x57611642, 0x57249a29, 0x56e847ef,
+0x56ac1f75, 0x567020a0, 0x56344b52, 0x55f89f70,
+0x55bd1cdb, 0x5581c378, 0x55469329, 0x550b8bd4,
+0x54d0ad5b, 0x5495f7a1, 0x545b6a8b, 0x542105fd,
+0x53e6c9db, 0x53acb607, 0x5372ca68, 0x533906e0,
+0x52ff6b55, 0x52c5f7aa, 0x528cabc3, 0x52538786,
+0x521a8ad7, 0x51e1b59a, 0x51a907b4, 0x5170810b,
+0x51382182, 0x50ffe8fe, 0x50c7d765, 0x508fec9c,
+0x50582888, 0x50208b0e, 0x4fe91413, 0x4fb1c37c,
+0x4f7a9930, 0x4f439514, 0x4f0cb70c, 0x4ed5ff00,
+0x4e9f6cd4, 0x4e69006e, 0x4e32b9b4, 0x4dfc988c,
+0x4dc69cdd, 0x4d90c68b, 0x4d5b157e, 0x4d25899c,
+0x4cf022ca, 0x4cbae0ef, 0x4c85c3f1, 0x4c50cbb8,
+0x4c1bf829, 0x4be7492b, 0x4bb2bea5, 0x4b7e587d,
+0x4b4a169c, 0x4b15f8e6, 0x4ae1ff43, 0x4aae299b,
+0x4a7a77d5, 0x4a46e9d6, 0x4a137f88, 0x49e038d0,
+0x49ad1598, 0x497a15c4, 0x4947393f, 0x49147fee,
+0x48e1e9ba, 0x48af768a, 0x487d2646, 0x484af8d6,
+0x4818ee22, 0x47e70611, 0x47b5408c, 0x47839d7b,
+0x47521cc6, 0x4720be55, 0x46ef8210, 0x46be67e0,
+0x468d6fae, 0x465c9961, 0x462be4e2, 0x45fb521a,
+0x45cae0f2, 0x459a9152, 0x456a6323, 0x453a564d,
+0x450a6abb, 0x44daa054, 0x44aaf702, 0x447b6ead,
+0x444c0740, 0x441cc0a3, 0x43ed9ac0, 0x43be9580,
+0x438fb0cb, 0x4360ec8d, 0x433248ae, 0x4303c517,
+0x42d561b4, 0x42a71e6c, 0x4278fb2b, 0x424af7da,
+0x421d1462, 0x41ef50ae, 0x41c1aca8, 0x41942839,
+0x4166c34c, 0x41397dcc, 0x410c57a2, 0x40df50b8,
+0x40b268fa, 0x4085a051, 0x4058f6a8, 0x402c6be9
};
/*!
-
- \brief calculates 2 ^ (x/y) for x<=0, y > 0, x <= 32768 * y
-
+
+ \brief calculates 2 ^ (x/y) for x<=0, y > 0, x <= 32768 * y
+
avoids integer division
-
- \return
+
+ \return
*/
Word32 pow2_xy(Word32 x, Word32 y)
{
@@ -355,7 +355,7 @@
fPart = tmp2 - iPart*y;
iPart = min(iPart,INT_BITS-1);
- res = pow2Table[(POW2_TABLE_SIZE*fPart)/y] >> iPart;
-
+ res = pow2Table[(POW2_TABLE_SIZE*fPart)/y] >> iPart;
+
return(res);
}
\ No newline at end of file
diff --git a/media/libstagefright/codecs/aacenc/basic_op/oper_32b.h b/media/libstagefright/codecs/aacenc/basic_op/oper_32b.h
index 9ebd1c2..1d35e5e 100644
--- a/media/libstagefright/codecs/aacenc/basic_op/oper_32b.h
+++ b/media/libstagefright/codecs/aacenc/basic_op/oper_32b.h
@@ -51,21 +51,21 @@
swHigh1 = (Word16)(L_var2 >> 16);
l_var_out = (long)swLow1 * (long)var1 >> 15;
-
+
l_var_out += swHigh1 * var1 << 1;
-
+
return(l_var_out);
}
__inline Word32 L_mpy_wx(Word32 L_var2, Word16 var1)
{
#if ARMV5TE_L_MPY_LS
- Word32 result;
- asm volatile(
- "SMULWB %[result], %[L_var2], %[var1] \n"
+ Word32 result;
+ asm volatile(
+ "SMULWB %[result], %[L_var2], %[var1] \n"
:[result]"+r"(result)
:[L_var2]"r"(L_var2), [var1]"r"(var1)
- );
+ );
return result;
#else
unsigned short swLow1;
@@ -75,9 +75,9 @@
swLow1 = (unsigned short)(L_var2);
swHigh1 = (Word16)(L_var2 >> 16);
- l_var_out = (long)swLow1 * (long)var1 >> 16;
+ l_var_out = (long)swLow1 * (long)var1 >> 16;
l_var_out += swHigh1 * var1;
-
+
return(l_var_out);
#endif
}
diff --git a/media/libstagefright/codecs/aacenc/basic_op/typedef.h b/media/libstagefright/codecs/aacenc/basic_op/typedef.h
index b1f8225..1030803 100644
--- a/media/libstagefright/codecs/aacenc/basic_op/typedef.h
+++ b/media/libstagefright/codecs/aacenc/basic_op/typedef.h
@@ -30,7 +30,7 @@
/*
* this is the original code from the ETSI file typedef.h
*/
-
+
#if defined(__BORLANDC__) || defined(__WATCOMC__) || defined(_MSC_VER) || defined(__ZTC__)
typedef signed char Word8;
typedef short Word16;
diff --git a/media/libstagefright/codecs/aacenc/basic_op/typedefs.h b/media/libstagefright/codecs/aacenc/basic_op/typedefs.h
index c924e2c..c7e774b 100644
--- a/media/libstagefright/codecs/aacenc/basic_op/typedefs.h
+++ b/media/libstagefright/codecs/aacenc/basic_op/typedefs.h
@@ -55,7 +55,7 @@
#define INT_BITS 32
/*
********************************************************************************
-* DEFINITION OF CONSTANTS
+* DEFINITION OF CONSTANTS
********************************************************************************
*/
/*
@@ -120,12 +120,12 @@
#define ARMV5TE_L_MULT 1
#define ARMV5TE_L_MAC 1
#define ARMV5TE_L_MSU 1
-
-
+
+
#define ARMV5TE_DIV_S 1
#define ARMV5TE_ROUND 1
#define ARMV5TE_MULT 1
-
+
#define ARMV5TE_NORM_S 1
#define ARMV5TE_NORM_L 1
#define ARMV5TE_L_MPY_LS 1
@@ -149,7 +149,7 @@
#define ROUND_IS_INLINE 1 //define round as inline function
#define L_MAC_IS_INLINE 1 //define L_mac as inline function
#define L_ADD_IS_INLINE 1 //define L_add as inline function
-#define EXTRACT_H_IS_INLINE 1 //define extract_h as inline function
+#define EXTRACT_H_IS_INLINE 1 //define extract_h as inline function
#define EXTRACT_L_IS_INLINE 1 //define extract_l as inline function //???
#define MULT_R_IS_INLINE 1 //define mult_r as inline function
#define SHR_R_IS_INLINE 1 //define shr_r as inline function
diff --git a/media/libstagefright/codecs/aacenc/build/eclair/ARMV5E/Makefile b/media/libstagefright/codecs/aacenc/build/eclair/ARMV5E/Makefile
deleted file mode 100644
index 79be7da..0000000
--- a/media/libstagefright/codecs/aacenc/build/eclair/ARMV5E/Makefile
+++ /dev/null
@@ -1,55 +0,0 @@
-#/*
-#** Copyright 2003-2010, VisualOn, Inc.
-#**
-#** 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.
-#*/
-
-# target6
-# available: pc, v4(armv4), v5(armv5), v5x(armv5 xscale), v6(armv6), v7(cortex-a8 neon)
-VOTT:= v5
-
-
-# module type
-# please specify the type of your module: lib or exe
-VOMT:= lib
-
-
-# module macros
-# please append the additional macro definitions here for your module if necessary.
-# e.g. -DVISUALON, macro VISUALON defined for your module
-VOMM:= -DARMV5E -DARM_INASM -DARMV5_INASM
-
-
-
-# please specify the name of your module
-VOTARGET:=libvoAACEncv5
-
-
-# please modify here to be sure to see the g1.mk
-include ../../../../../Tools/eclair.mk
-
-# dependent libraries.
-VODEPLIBS:=#-ldl -lstdc++
-
-# module source
-# please modify here to be sure to see the ms.mk which specifies all source info of your module
-include ../../ms.mk
-
-
-# please specify where is the voRelease on your PC, relative path is suggested
-VORELDIR:=../../../../../../Release
-
-
-# please modify here to be sure to see the doit.mk
-include ../../../../../Tools/doit.mk
-
diff --git a/media/libstagefright/codecs/aacenc/build/eclair/ARMV7/Makefile b/media/libstagefright/codecs/aacenc/build/eclair/ARMV7/Makefile
deleted file mode 100644
index a72c850..0000000
--- a/media/libstagefright/codecs/aacenc/build/eclair/ARMV7/Makefile
+++ /dev/null
@@ -1,55 +0,0 @@
-#/*
-#** Copyright 2003-2010, VisualOn, Inc.
-#**
-#** 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.
-#*/
-
-# target6
-# available: pc, v4(armv4), v5(armv5), v5x(armv5 xscale), v6(armv6), v7(cortex-a8 neon)
-VOTT:= v7
-
-
-# module type
-# please specify the type of your module: lib or exe
-VOMT:= lib
-
-
-# module macros
-# please append the additional macro definitions here for your module if necessary.
-# e.g. -DVISUALON, macro VISUALON defined for your module
-VOMM:= -DARMV5E -DARMV7Neon -DARM_INASM -DARMV5_INASM
-
-
-
-# please specify the name of your module
-VOTARGET:=libvoAACEncv7
-
-
-# please modify here to be sure to see the g1.mk
-include ../../../../../Tools/eclair.mk
-
-# dependent libraries.
-VODEPLIBS:=#-ldl -lstdc++
-
-# module source
-# please modify here to be sure to see the ms.mk which specifies all source info of your module
-include ../../ms.mk
-
-
-# please specify where is the voRelease on your PC, relative path is suggested
-VORELDIR:=../../../../../../Release
-
-
-# please modify here to be sure to see the doit.mk
-include ../../../../../Tools/doit.mk
-
diff --git a/media/libstagefright/codecs/aacenc/build/eclair/makefile b/media/libstagefright/codecs/aacenc/build/eclair/makefile
deleted file mode 100644
index 5824d17..0000000
--- a/media/libstagefright/codecs/aacenc/build/eclair/makefile
+++ /dev/null
@@ -1,40 +0,0 @@
-#/*
-#** Copyright 2003-2010, VisualOn, Inc.
-#**
-#** 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.
-#*/
-
-# Just acting as Father Makefile of Modules
-# please keep the name 'makefile' unchanged
-
-# Module Subdirs
-VOMSD:=$(dir $(shell find . -name 'Makefile'))
-
-all:
- for dir in $(VOMSD); \
- do \
- $(MAKE) -C $$dir; \
- done
-
-.PHONY:clean devel
-clean:
- for dir in $(VOMSD); \
- do \
- $(MAKE) -C $$dir clean; \
- done
-
-devel:
- for dir in $(VOMSD); \
- do \
- $(MAKE) -C $$dir devel; \
- done
diff --git a/media/libstagefright/codecs/aacenc/build/ms.mk b/media/libstagefright/codecs/aacenc/build/ms.mk
deleted file mode 100644
index 85adba1..0000000
--- a/media/libstagefright/codecs/aacenc/build/ms.mk
+++ /dev/null
@@ -1,42 +0,0 @@
-#/*
-#** Copyright 2003-2010, VisualOn, Inc.
-#**
-#** 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.
-#*/
-
-
-# please list all objects needed by your target here
-OBJS:=basicop2.o oper_32b.o aac_rom.o aacenc.o aacenc_core.o adj_thr.o \
- band_nrg.o bit_cnt.o bitbuffer.o bitenc.o block_switch.o channel_map.o \
- dyn_bits.o grp_data.o interface.o line_pe.o memalign.o ms_stereo.o \
- pre_echo_control.o psy_configuration.o psy_main.o qc_main.o quantize.o sf_estim.o \
- spreading.o stat_bits.o tns.o transform.o
-
-# please list all directories that all source files relative with your module(.h .c .cpp) locate
-VOSRCDIR:=../../../src \
- ../../../inc \
- ../../../basic_op\
- ../../../../../Include
-
-ifeq ($(VOTT), v5)
-OBJS+= AutoCorrelation_v5.o band_nrg_v5.o CalcWindowEnergy_v5.o \
- PrePostMDCT_v5.o R4R8First_v5.o Radix4FFT_v5.o
-VOSRCDIR+= ../../../src/asm/ARMV5E/
-endif
-
-ifeq ($(VOTT), v7)
-OBJS+= AutoCorrelation_v5.o band_nrg_v5.o CalcWindowEnergy_v5.o \
- PrePostMDCT_v7.o R4R8First_v7.o Radix4FFT_v7.o
-VOSRCDIR+= ../../../src/asm/ARMV5E/
-VOSRCDIR+= ../../../src/asm/ARMV7/
-endif
diff --git a/media/libstagefright/codecs/aacenc/inc/aac_rom.h b/media/libstagefright/codecs/aacenc/inc/aac_rom.h
index 8e206b7..784bb70 100644
--- a/media/libstagefright/codecs/aacenc/inc/aac_rom.h
+++ b/media/libstagefright/codecs/aacenc/inc/aac_rom.h
@@ -16,7 +16,7 @@
/*******************************************************************************
File: aac_rom.h
- Content: constant tables
+ Content: constant tables
*******************************************************************************/
diff --git a/media/libstagefright/codecs/aacenc/inc/aacenc_core.h b/media/libstagefright/codecs/aacenc/inc/aacenc_core.h
index 1acdbbc..41ba756 100644
--- a/media/libstagefright/codecs/aacenc/inc/aacenc_core.h
+++ b/media/libstagefright/codecs/aacenc/inc/aacenc_core.h
@@ -47,7 +47,7 @@
typedef struct {
-
+
AACENC_CONFIG config; /* Word16 size: 8 */
ELEMENT_INFO elInfo; /* Word16 size: 4 */
diff --git a/media/libstagefright/codecs/aacenc/inc/adj_thr.h b/media/libstagefright/codecs/aacenc/inc/adj_thr.h
index 0f4bb5e..f7cb888 100644
--- a/media/libstagefright/codecs/aacenc/inc/adj_thr.h
+++ b/media/libstagefright/codecs/aacenc/inc/adj_thr.h
@@ -16,7 +16,7 @@
/*******************************************************************************
File: adj_thr.h
- Content: Threshold compensation function
+ Content: Threshold compensation function
*******************************************************************************/
@@ -44,7 +44,7 @@
PSY_OUT_ELEMENT *psyOutElement,
Word16 *chBitDistribution,
Word16 logSfbEnergy[MAX_CHANNELS][MAX_GROUPED_SFB],
- Word16 sfbNRelevantLines[MAX_CHANNELS][MAX_GROUPED_SFB],
+ Word16 sfbNRelevantLines[MAX_CHANNELS][MAX_GROUPED_SFB],
QC_OUT_ELEMENT* qcOE,
ELEMENT_BITS* elBits,
const Word16 nChannels,
diff --git a/media/libstagefright/codecs/aacenc/inc/adj_thr_data.h b/media/libstagefright/codecs/aacenc/inc/adj_thr_data.h
index 30132d8..9ac4664 100644
--- a/media/libstagefright/codecs/aacenc/inc/adj_thr_data.h
+++ b/media/libstagefright/codecs/aacenc/inc/adj_thr_data.h
@@ -16,7 +16,7 @@
/*******************************************************************************
File: adj_thr_data.h
- Content: Threshold compensation parameter
+ Content: Threshold compensation parameter
*******************************************************************************/
diff --git a/media/libstagefright/codecs/aacenc/inc/bitenc.h b/media/libstagefright/codecs/aacenc/inc/bitenc.h
index 6a58aeb..6ded3c6 100644
--- a/media/libstagefright/codecs/aacenc/inc/bitenc.h
+++ b/media/libstagefright/codecs/aacenc/inc/bitenc.h
@@ -26,7 +26,7 @@
#include "qc_data.h"
#include "tns.h"
#include "channel_map.h"
-#include "interface.h"
+#include "interface.h"
struct BITSTREAMENCODER_INIT
{
diff --git a/media/libstagefright/codecs/aacenc/inc/interface.h b/media/libstagefright/codecs/aacenc/inc/interface.h
index a42e6a9..966ac99 100644
--- a/media/libstagefright/codecs/aacenc/inc/interface.h
+++ b/media/libstagefright/codecs/aacenc/inc/interface.h
@@ -55,11 +55,11 @@
Word16 windowShape;
Word16 groupingMask;
Word16 sfbOffsets[MAX_GROUPED_SFB+1];
- Word16 mdctScale;
- Word32 *sfbEnergy;
+ Word16 mdctScale;
+ Word32 *sfbEnergy;
Word32 *sfbSpreadedEnergy;
- Word32 *sfbThreshold;
- Word32 *mdctSpectrum;
+ Word32 *sfbThreshold;
+ Word32 *mdctSpectrum;
Word32 sfbEnSumLR;
Word32 sfbEnSumMS;
Word32 sfbDist[MAX_GROUPED_SFB];
diff --git a/media/libstagefright/codecs/aacenc/inc/line_pe.h b/media/libstagefright/codecs/aacenc/inc/line_pe.h
index 116d5a8..038d5a3 100644
--- a/media/libstagefright/codecs/aacenc/inc/line_pe.h
+++ b/media/libstagefright/codecs/aacenc/inc/line_pe.h
@@ -24,8 +24,8 @@
#define __LINE_PE_H
-#include "psy_const.h"
-#include "interface.h"
+#include "psy_const.h"
+#include "interface.h"
typedef struct {
@@ -72,4 +72,4 @@
-#endif
+#endif
diff --git a/media/libstagefright/codecs/aacenc/inc/psy_const.h b/media/libstagefright/codecs/aacenc/inc/psy_const.h
index 19fb9b2..b05d683 100644
--- a/media/libstagefright/codecs/aacenc/inc/psy_const.h
+++ b/media/libstagefright/codecs/aacenc/inc/psy_const.h
@@ -69,7 +69,7 @@
#define BLOCK_SWITCHING_OFFSET (1*1024+3*128+64+128)
#define BLOCK_SWITCHING_DATA_SIZE FRAME_LEN_LONG
-
+
#define TRANSFORM_OFFSET_LONG 0
#define TRANSFORM_OFFSET_SHORT 448
diff --git a/media/libstagefright/codecs/aacenc/inc/psy_main.h b/media/libstagefright/codecs/aacenc/inc/psy_main.h
index 2ccac60..5fcbe13 100644
--- a/media/libstagefright/codecs/aacenc/inc/psy_main.h
+++ b/media/libstagefright/codecs/aacenc/inc/psy_main.h
@@ -54,9 +54,9 @@
Word16 bandwidth);
-Word16 psyMain(Word16 nChannels, /*!< total number of channels */
+Word16 psyMain(Word16 nChannels, /*!< total number of channels */
ELEMENT_INFO *elemInfo,
- Word16 *timeSignal, /*!< interleaved time signal */
+ Word16 *timeSignal, /*!< interleaved time signal */
PSY_DATA psyData[MAX_CHANNELS],
TNS_DATA tnsData[MAX_CHANNELS],
PSY_CONFIGURATION_LONG* psyConfLong,
diff --git a/media/libstagefright/codecs/aacenc/inc/qc_main.h b/media/libstagefright/codecs/aacenc/inc/qc_main.h
index 8f83973..924a06d 100644
--- a/media/libstagefright/codecs/aacenc/inc/qc_main.h
+++ b/media/libstagefright/codecs/aacenc/inc/qc_main.h
@@ -35,7 +35,7 @@
Word16 QCNew(QC_STATE *hQC, VO_MEM_OPERATOR *pMemOP);
-Word16 QCInit(QC_STATE *hQC,
+Word16 QCInit(QC_STATE *hQC,
struct QC_INIT *init);
void QCDelete(QC_STATE *hQC, VO_MEM_OPERATOR *pMemOP);
diff --git a/media/libstagefright/codecs/aacenc/inc/quantize.h b/media/libstagefright/codecs/aacenc/inc/quantize.h
index 1cafef6..7dac2bf 100644
--- a/media/libstagefright/codecs/aacenc/inc/quantize.h
+++ b/media/libstagefright/codecs/aacenc/inc/quantize.h
@@ -28,7 +28,7 @@
#define MAX_QUANT 8191
-void QuantizeSpectrum(Word16 sfbCnt,
+void QuantizeSpectrum(Word16 sfbCnt,
Word16 maxSfbPerGroup,
Word16 sfbPerGroup,
Word16 *sfbOffset, Word32 *mdctSpectrum,
diff --git a/media/libstagefright/codecs/aacenc/inc/sf_estim.h b/media/libstagefright/codecs/aacenc/inc/sf_estim.h
index 9039f25..11436a2 100644
--- a/media/libstagefright/codecs/aacenc/inc/sf_estim.h
+++ b/media/libstagefright/codecs/aacenc/inc/sf_estim.h
@@ -23,7 +23,7 @@
#ifndef __SF_ESTIM_H__
#define __SF_ESTIM_H__
/*
- Scale factor estimation
+ Scale factor estimation
*/
#include "psy_const.h"
#include "interface.h"
diff --git a/media/libstagefright/codecs/aacenc/inc/stat_bits.h b/media/libstagefright/codecs/aacenc/inc/stat_bits.h
index 9cddc1d..fff3d14 100644
--- a/media/libstagefright/codecs/aacenc/inc/stat_bits.h
+++ b/media/libstagefright/codecs/aacenc/inc/stat_bits.h
@@ -28,7 +28,7 @@
Word16 countStaticBitdemand(PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
PSY_OUT_ELEMENT *psyOutElement,
- Word16 nChannels,
+ Word16 nChannels,
Word16 adtsUsed);
#endif /* __STAT_BITS_H */
diff --git a/media/libstagefright/codecs/aacenc/inc/tns_param.h b/media/libstagefright/codecs/aacenc/inc/tns_param.h
index 0aa33c3..78265bb 100644
--- a/media/libstagefright/codecs/aacenc/inc/tns_param.h
+++ b/media/libstagefright/codecs/aacenc/inc/tns_param.h
@@ -44,7 +44,7 @@
}TNS_INFO_TAB;
-void GetTnsParam(TNS_CONFIG_TABULATED *tnsConfigTab,
+void GetTnsParam(TNS_CONFIG_TABULATED *tnsConfigTab,
Word32 bitRate, Word16 channels, Word16 blockType);
void GetTnsMaxBands(Word32 samplingRate, Word16 blockType, Word16* tnsMaxSfb);
diff --git a/media/libstagefright/codecs/aacenc/inc/transform.h b/media/libstagefright/codecs/aacenc/inc/transform.h
index fbac7aa..93d5ffe 100644
--- a/media/libstagefright/codecs/aacenc/inc/transform.h
+++ b/media/libstagefright/codecs/aacenc/inc/transform.h
@@ -24,7 +24,7 @@
#define __TRANSFORM_H__
#include "typedef.h"
-
+
void Transform_Real(Word16 *mdctDelayBuffer,
Word16 *timeSignal,
Word16 chIncrement, /*! channel increment */
diff --git a/media/libstagefright/codecs/aacenc/src/aac_rom.c b/media/libstagefright/codecs/aacenc/src/aac_rom.c
index 08792e8..16b44e0 100644
--- a/media/libstagefright/codecs/aacenc/src/aac_rom.c
+++ b/media/libstagefright/codecs/aacenc/src/aac_rom.c
@@ -24,14 +24,14 @@
#if defined (ARMV5E) && !defined (ARMV7Neon)
-/*
- * Q30 for 128 and 1024
+/*
+ * Q30 for 128 and 1024
*
* for (i = 0; i < num/4; i++) {
* angle = (i + 0.125) * M_PI / num;
* x = cos(angle) * (1 << 30);
* x = sin(angle) * (1 << 30);
- *
+ *
* angle = (num/2 - 1 - i + 0.125) * M_PI / num;
* x = cos(angle) * (1 << 30);
* x = sin(angle) * (1 << 30);
@@ -39,313 +39,313 @@
*/
const int cossintab[128 + 1024] = {
/* 128 */
- 0x3fffec43, 0x003243f1, 0x015fd4d2, 0x3ffc38d1, 0x3ff9c13a, 0x01c454f5, 0x02f1b755, 0x3feea776,
- 0x3fe9b8a9, 0x03562038, 0x0483259d, 0x3fd73a4a, 0x3fcfd50b, 0x04e767c5, 0x0613e1c5, 0x3fb5f4ea,
- 0x3fac1a5b, 0x0677edbb, 0x07a3adff, 0x3f8adc77, 0x3f7e8e1e, 0x08077457, 0x09324ca7, 0x3f55f796,
- 0x3f473759, 0x0995bdfd, 0x0abf8043, 0x3f174e70, 0x3f061e95, 0x0b228d42, 0x0c4b0b94, 0x3eceeaad,
- 0x3ebb4ddb, 0x0cada4f5, 0x0dd4b19a, 0x3e7cd778, 0x3e66d0b4, 0x0e36c82a, 0x0f5c35a3, 0x3e212179,
- 0x3e08b42a, 0x0fbdba40, 0x10e15b4e, 0x3dbbd6d4, 0x3da106bd, 0x11423ef0, 0x1263e699, 0x3d4d0728,
- 0x3d2fd86c, 0x12c41a4f, 0x13e39be9, 0x3cd4c38b, 0x3cb53aaa, 0x144310dd, 0x15604013, 0x3c531e88,
- 0x3c314060, 0x15bee78c, 0x16d99864, 0x3bc82c1f, 0x3ba3fde7, 0x173763c9, 0x184f6aab, 0x3b3401bb,
- 0x3b0d8909, 0x18ac4b87, 0x19c17d44, 0x3a96b636, 0x3a6df8f8, 0x1a1d6544, 0x1b2f971e, 0x39f061d2,
- 0x39c5664f, 0x1b8a7815, 0x1c997fc4, 0x39411e33, 0x3913eb0e, 0x1cf34baf, 0x1dfeff67, 0x38890663,
- 0x3859a292, 0x1e57a86d, 0x1f5fdee6, 0x37c836c2, 0x3796a996, 0x1fb7575c, 0x20bbe7d8, 0x36fecd0e,
- 0x36cb1e2a, 0x21122240, 0x2212e492, 0x362ce855, 0x35f71fb1, 0x2267d3a0, 0x2364a02e, 0x3552a8f4,
- 0x351acedd, 0x23b836ca, 0x24b0e699, 0x34703095, 0x34364da6, 0x250317df, 0x25f78497, 0x3385a222,
- 0x3349bf48, 0x264843d9, 0x273847c8, 0x329321c7, 0x32554840, 0x27878893, 0x2872feb6, 0x3198d4ea,
- 0x31590e3e, 0x28c0b4d2, 0x29a778db, 0x3096e223, 0x30553828, 0x29f3984c, 0x2ad586a3, 0x2f8d713a,
- 0x2f49ee0f, 0x2b2003ac, 0x2bfcf97c, 0x2e7cab1c, 0x2e37592c, 0x2c45c8a0, 0x2d1da3d5, 0x2d64b9da,
+ 0x3fffec43, 0x003243f1, 0x015fd4d2, 0x3ffc38d1, 0x3ff9c13a, 0x01c454f5, 0x02f1b755, 0x3feea776,
+ 0x3fe9b8a9, 0x03562038, 0x0483259d, 0x3fd73a4a, 0x3fcfd50b, 0x04e767c5, 0x0613e1c5, 0x3fb5f4ea,
+ 0x3fac1a5b, 0x0677edbb, 0x07a3adff, 0x3f8adc77, 0x3f7e8e1e, 0x08077457, 0x09324ca7, 0x3f55f796,
+ 0x3f473759, 0x0995bdfd, 0x0abf8043, 0x3f174e70, 0x3f061e95, 0x0b228d42, 0x0c4b0b94, 0x3eceeaad,
+ 0x3ebb4ddb, 0x0cada4f5, 0x0dd4b19a, 0x3e7cd778, 0x3e66d0b4, 0x0e36c82a, 0x0f5c35a3, 0x3e212179,
+ 0x3e08b42a, 0x0fbdba40, 0x10e15b4e, 0x3dbbd6d4, 0x3da106bd, 0x11423ef0, 0x1263e699, 0x3d4d0728,
+ 0x3d2fd86c, 0x12c41a4f, 0x13e39be9, 0x3cd4c38b, 0x3cb53aaa, 0x144310dd, 0x15604013, 0x3c531e88,
+ 0x3c314060, 0x15bee78c, 0x16d99864, 0x3bc82c1f, 0x3ba3fde7, 0x173763c9, 0x184f6aab, 0x3b3401bb,
+ 0x3b0d8909, 0x18ac4b87, 0x19c17d44, 0x3a96b636, 0x3a6df8f8, 0x1a1d6544, 0x1b2f971e, 0x39f061d2,
+ 0x39c5664f, 0x1b8a7815, 0x1c997fc4, 0x39411e33, 0x3913eb0e, 0x1cf34baf, 0x1dfeff67, 0x38890663,
+ 0x3859a292, 0x1e57a86d, 0x1f5fdee6, 0x37c836c2, 0x3796a996, 0x1fb7575c, 0x20bbe7d8, 0x36fecd0e,
+ 0x36cb1e2a, 0x21122240, 0x2212e492, 0x362ce855, 0x35f71fb1, 0x2267d3a0, 0x2364a02e, 0x3552a8f4,
+ 0x351acedd, 0x23b836ca, 0x24b0e699, 0x34703095, 0x34364da6, 0x250317df, 0x25f78497, 0x3385a222,
+ 0x3349bf48, 0x264843d9, 0x273847c8, 0x329321c7, 0x32554840, 0x27878893, 0x2872feb6, 0x3198d4ea,
+ 0x31590e3e, 0x28c0b4d2, 0x29a778db, 0x3096e223, 0x30553828, 0x29f3984c, 0x2ad586a3, 0x2f8d713a,
+ 0x2f49ee0f, 0x2b2003ac, 0x2bfcf97c, 0x2e7cab1c, 0x2e37592c, 0x2c45c8a0, 0x2d1da3d5, 0x2d64b9da,
/* 1024 */
- 0x3fffffb1, 0x0006487f, 0x002bfb74, 0x3ffff0e3, 0x3fffe705, 0x00388c6e, 0x005e3f4c, 0x3fffba9b,
- 0x3fffa6de, 0x006ad03b, 0x009082ea, 0x3fff5cd8, 0x3fff3f3c, 0x009d13c5, 0x00c2c62f, 0x3ffed79b,
- 0x3ffeb021, 0x00cf56ef, 0x00f508fc, 0x3ffe2ae5, 0x3ffdf98c, 0x01019998, 0x01274b31, 0x3ffd56b5,
- 0x3ffd1b7e, 0x0133dba3, 0x01598cb1, 0x3ffc5b0c, 0x3ffc15f7, 0x01661cf0, 0x018bcd5b, 0x3ffb37ec,
- 0x3ffae8f9, 0x01985d60, 0x01be0d11, 0x3ff9ed53, 0x3ff99483, 0x01ca9cd4, 0x01f04bb4, 0x3ff87b44,
- 0x3ff81896, 0x01fcdb2e, 0x02228924, 0x3ff6e1bf, 0x3ff67534, 0x022f184d, 0x0254c544, 0x3ff520c5,
- 0x3ff4aa5d, 0x02615414, 0x0286fff3, 0x3ff33858, 0x3ff2b813, 0x02938e62, 0x02b93914, 0x3ff12878,
- 0x3ff09e56, 0x02c5c71a, 0x02eb7086, 0x3feef126, 0x3fee5d28, 0x02f7fe1c, 0x031da62b, 0x3fec9265,
- 0x3febf48b, 0x032a3349, 0x034fd9e5, 0x3fea0c35, 0x3fe96480, 0x035c6682, 0x03820b93, 0x3fe75e98,
- 0x3fe6ad08, 0x038e97a9, 0x03b43b17, 0x3fe48990, 0x3fe3ce26, 0x03c0c69e, 0x03e66852, 0x3fe18d1f,
- 0x3fe0c7da, 0x03f2f342, 0x04189326, 0x3fde6945, 0x3fdd9a27, 0x04251d77, 0x044abb73, 0x3fdb1e06,
- 0x3fda450f, 0x0457451d, 0x047ce11a, 0x3fd7ab64, 0x3fd6c894, 0x04896a16, 0x04af03fc, 0x3fd4115f,
- 0x3fd324b7, 0x04bb8c42, 0x04e123fa, 0x3fd04ffc, 0x3fcf597c, 0x04edab83, 0x051340f6, 0x3fcc673b,
- 0x3fcb66e4, 0x051fc7b9, 0x05455ad1, 0x3fc8571f, 0x3fc74cf3, 0x0551e0c7, 0x0577716b, 0x3fc41fac,
- 0x3fc30baa, 0x0583f68c, 0x05a984a6, 0x3fbfc0e3, 0x3fbea30c, 0x05b608eb, 0x05db9463, 0x3fbb3ac7,
- 0x3fba131b, 0x05e817c3, 0x060da083, 0x3fb68d5b, 0x3fb55bdc, 0x061a22f7, 0x063fa8e7, 0x3fb1b8a2,
- 0x3fb07d50, 0x064c2a67, 0x0671ad71, 0x3facbc9f, 0x3fab777b, 0x067e2df5, 0x06a3ae00, 0x3fa79954,
- 0x3fa64a5f, 0x06b02d81, 0x06d5aa77, 0x3fa24ec6, 0x3fa0f600, 0x06e228ee, 0x0707a2b7, 0x3f9cdcf7,
- 0x3f9b7a62, 0x0714201b, 0x073996a1, 0x3f9743eb, 0x3f95d787, 0x074612eb, 0x076b8616, 0x3f9183a5,
- 0x3f900d72, 0x0778013d, 0x079d70f7, 0x3f8b9c28, 0x3f8a1c29, 0x07a9eaf5, 0x07cf5726, 0x3f858d79,
- 0x3f8403ae, 0x07dbcff2, 0x08013883, 0x3f7f579b, 0x3f7dc405, 0x080db016, 0x083314f1, 0x3f78fa92,
- 0x3f775d31, 0x083f8b43, 0x0864ec4f, 0x3f727661, 0x3f70cf38, 0x08716159, 0x0896be80, 0x3f6bcb0e,
- 0x3f6a1a1c, 0x08a3323a, 0x08c88b65, 0x3f64f89b, 0x3f633de2, 0x08d4fdc6, 0x08fa52de, 0x3f5dff0e,
- 0x3f5c3a8f, 0x0906c3e0, 0x092c14ce, 0x3f56de6a, 0x3f551026, 0x09388469, 0x095dd116, 0x3f4f96b4,
- 0x3f4dbeac, 0x096a3f42, 0x098f8796, 0x3f4827f0, 0x3f464626, 0x099bf44c, 0x09c13831, 0x3f409223,
- 0x3f3ea697, 0x09cda368, 0x09f2e2c7, 0x3f38d552, 0x3f36e006, 0x09ff4c78, 0x0a24873a, 0x3f30f181,
- 0x3f2ef276, 0x0a30ef5e, 0x0a56256c, 0x3f28e6b6, 0x3f26ddec, 0x0a628bfa, 0x0a87bd3d, 0x3f20b4f5,
- 0x3f1ea26e, 0x0a94222f, 0x0ab94e8f, 0x3f185c43, 0x3f164001, 0x0ac5b1dc, 0x0aead944, 0x3f0fdca5,
- 0x3f0db6a9, 0x0af73ae5, 0x0b1c5d3d, 0x3f073621, 0x3f05066d, 0x0b28bd2a, 0x0b4dda5c, 0x3efe68bc,
- 0x3efc2f50, 0x0b5a388d, 0x0b7f5081, 0x3ef5747b, 0x3ef3315a, 0x0b8bacf0, 0x0bb0bf8f, 0x3eec5965,
- 0x3eea0c8e, 0x0bbd1a33, 0x0be22766, 0x3ee3177e, 0x3ee0c0f4, 0x0bee8038, 0x0c1387e9, 0x3ed9aecc,
- 0x3ed74e91, 0x0c1fdee1, 0x0c44e0f9, 0x3ed01f55, 0x3ecdb56a, 0x0c513610, 0x0c763278, 0x3ec66920,
- 0x3ec3f585, 0x0c8285a5, 0x0ca77c47, 0x3ebc8c31, 0x3eba0ee9, 0x0cb3cd84, 0x0cd8be47, 0x3eb2888f,
- 0x3eb0019c, 0x0ce50d8c, 0x0d09f85b, 0x3ea85e41, 0x3ea5cda3, 0x0d1645a0, 0x0d3b2a64, 0x3e9e0d4c,
- 0x3e9b7306, 0x0d4775a1, 0x0d6c5443, 0x3e9395b7, 0x3e90f1ca, 0x0d789d71, 0x0d9d75db, 0x3e88f788,
- 0x3e8649f5, 0x0da9bcf2, 0x0dce8f0d, 0x3e7e32c6, 0x3e7b7b90, 0x0ddad406, 0x0dff9fba, 0x3e734778,
- 0x3e70869f, 0x0e0be28e, 0x0e30a7c5, 0x3e6835a4, 0x3e656b2b, 0x0e3ce86b, 0x0e61a70f, 0x3e5cfd51,
- 0x3e5a2939, 0x0e6de580, 0x0e929d7a, 0x3e519e86, 0x3e4ec0d1, 0x0e9ed9af, 0x0ec38ae8, 0x3e46194a,
- 0x3e4331fa, 0x0ecfc4d9, 0x0ef46f3b, 0x3e3a6da4, 0x3e377cbb, 0x0f00a6df, 0x0f254a53, 0x3e2e9b9c,
- 0x3e2ba11b, 0x0f317fa5, 0x0f561c15, 0x3e22a338, 0x3e1f9f21, 0x0f624f0c, 0x0f86e460, 0x3e168480,
- 0x3e1376d5, 0x0f9314f5, 0x0fb7a317, 0x3e0a3f7b, 0x3e07283f, 0x0fc3d143, 0x0fe8581d, 0x3dfdd432,
- 0x3dfab365, 0x0ff483d7, 0x10190352, 0x3df142ab, 0x3dee1851, 0x10252c94, 0x1049a49a, 0x3de48aef,
- 0x3de15708, 0x1055cb5b, 0x107a3bd5, 0x3dd7ad05, 0x3dd46f94, 0x1086600e, 0x10aac8e6, 0x3dcaa8f5,
- 0x3dc761fc, 0x10b6ea90, 0x10db4baf, 0x3dbd7ec7, 0x3dba2e48, 0x10e76ac3, 0x110bc413, 0x3db02e84,
- 0x3dacd481, 0x1117e088, 0x113c31f3, 0x3da2b834, 0x3d9f54af, 0x11484bc2, 0x116c9531, 0x3d951bde,
- 0x3d91aed9, 0x1178ac53, 0x119cedaf, 0x3d87598c, 0x3d83e309, 0x11a9021d, 0x11cd3b50, 0x3d797145,
- 0x3d75f147, 0x11d94d02, 0x11fd7df6, 0x3d6b6313, 0x3d67d99b, 0x12098ce5, 0x122db583, 0x3d5d2efe,
- 0x3d599c0e, 0x1239c1a7, 0x125de1da, 0x3d4ed50f, 0x3d4b38aa, 0x1269eb2b, 0x128e02dc, 0x3d40554e,
- 0x3d3caf76, 0x129a0954, 0x12be186c, 0x3d31afc5, 0x3d2e007c, 0x12ca1c03, 0x12ee226c, 0x3d22e47c,
- 0x3d1f2bc5, 0x12fa231b, 0x131e20c0, 0x3d13f37e, 0x3d10315a, 0x132a1e7e, 0x134e1348, 0x3d04dcd2,
- 0x3d011145, 0x135a0e0e, 0x137df9e7, 0x3cf5a082, 0x3cf1cb8e, 0x1389f1af, 0x13add481, 0x3ce63e98,
- 0x3ce2603f, 0x13b9c943, 0x13dda2f7, 0x3cd6b71e, 0x3cd2cf62, 0x13e994ab, 0x140d652c, 0x3cc70a1c,
- 0x3cc318ff, 0x141953cb, 0x143d1b02, 0x3cb7379c, 0x3cb33d22, 0x14490685, 0x146cc45c, 0x3ca73fa9,
- 0x3ca33bd3, 0x1478acbc, 0x149c611d, 0x3c97224c, 0x3c93151d, 0x14a84652, 0x14cbf127, 0x3c86df8e,
- 0x3c82c909, 0x14d7d32a, 0x14fb745e, 0x3c76777b, 0x3c7257a2, 0x15075327, 0x152aeaa3, 0x3c65ea1c,
- 0x3c61c0f1, 0x1536c62b, 0x155a53d9, 0x3c55377b, 0x3c510501, 0x15662c18, 0x1589afe3, 0x3c445fa2,
- 0x3c4023dd, 0x159584d3, 0x15b8fea4, 0x3c33629d, 0x3c2f1d8e, 0x15c4d03e, 0x15e83fff, 0x3c224075,
- 0x3c1df21f, 0x15f40e3a, 0x161773d6, 0x3c10f935, 0x3c0ca19b, 0x16233eac, 0x16469a0d, 0x3bff8ce8,
- 0x3bfb2c0c, 0x16526176, 0x1675b286, 0x3bedfb99, 0x3be9917e, 0x1681767c, 0x16a4bd25, 0x3bdc4552,
- 0x3bd7d1fa, 0x16b07d9f, 0x16d3b9cc, 0x3bca6a1d, 0x3bc5ed8d, 0x16df76c3, 0x1702a85e, 0x3bb86a08,
- 0x3bb3e440, 0x170e61cc, 0x173188be, 0x3ba6451b, 0x3ba1b620, 0x173d3e9b, 0x17605ad0, 0x3b93fb63,
- 0x3b8f6337, 0x176c0d15, 0x178f1e76, 0x3b818ceb, 0x3b7ceb90, 0x179acd1c, 0x17bdd394, 0x3b6ef9be,
- 0x3b6a4f38, 0x17c97e93, 0x17ec7a0d, 0x3b5c41e8, 0x3b578e39, 0x17f8215e, 0x181b11c4, 0x3b496574,
- 0x3b44a8a0, 0x1826b561, 0x18499a9d, 0x3b36646e, 0x3b319e77, 0x18553a7d, 0x1878147a, 0x3b233ee1,
- 0x3b1e6fca, 0x1883b097, 0x18a67f3f, 0x3b0ff4d9, 0x3b0b1ca6, 0x18b21791, 0x18d4dad0, 0x3afc8663,
- 0x3af7a516, 0x18e06f50, 0x1903270f, 0x3ae8f38b, 0x3ae40926, 0x190eb7b7, 0x193163e1, 0x3ad53c5b,
- 0x3ad048e3, 0x193cf0a9, 0x195f9128, 0x3ac160e1, 0x3abc6458, 0x196b1a09, 0x198daec8, 0x3aad6129,
- 0x3aa85b92, 0x199933bb, 0x19bbbca6, 0x3a993d3e, 0x3a942e9d, 0x19c73da3, 0x19e9baa3, 0x3a84f52f,
- 0x3a7fdd86, 0x19f537a4, 0x1a17a8a5, 0x3a708906, 0x3a6b6859, 0x1a2321a2, 0x1a45868e, 0x3a5bf8d1,
- 0x3a56cf23, 0x1a50fb81, 0x1a735442, 0x3a47449c, 0x3a4211f0, 0x1a7ec524, 0x1aa111a6, 0x3a326c74,
- 0x3a2d30cd, 0x1aac7e6f, 0x1acebe9d, 0x3a1d7066, 0x3a182bc8, 0x1ada2746, 0x1afc5b0a, 0x3a08507f,
- 0x3a0302ed, 0x1b07bf8c, 0x1b29e6d2, 0x39f30ccc, 0x39edb649, 0x1b354727, 0x1b5761d8, 0x39dda55a,
- 0x39d845e9, 0x1b62bdf8, 0x1b84cc01, 0x39c81a36, 0x39c2b1da, 0x1b9023e5, 0x1bb22530, 0x39b26b6d,
- 0x39acfa2b, 0x1bbd78d2, 0x1bdf6d4a, 0x399c990d, 0x39971ee7, 0x1beabca1, 0x1c0ca432, 0x3986a324,
- 0x3981201e, 0x1c17ef39, 0x1c39c9cd, 0x397089bf, 0x396afddc, 0x1c45107c, 0x1c66ddfe, 0x395a4ceb,
- 0x3954b82e, 0x1c72204f, 0x1c93e0ab, 0x3943ecb6, 0x393e4f23, 0x1c9f1e96, 0x1cc0d1b6, 0x392d692f,
- 0x3927c2c9, 0x1ccc0b35, 0x1cedb106, 0x3916c262, 0x3911132d, 0x1cf8e611, 0x1d1a7e7d, 0x38fff85e,
- 0x38fa405e, 0x1d25af0d, 0x1d473a00, 0x38e90b31, 0x38e34a69, 0x1d52660f, 0x1d73e374, 0x38d1fae9,
- 0x38cc315d, 0x1d7f0afb, 0x1da07abc, 0x38bac795, 0x38b4f547, 0x1dab9db5, 0x1dccffbf, 0x38a37142,
- 0x389d9637, 0x1dd81e21, 0x1df9725f, 0x388bf7ff, 0x3886143b, 0x1e048c24, 0x1e25d282, 0x38745bdb,
- 0x386e6f60, 0x1e30e7a4, 0x1e52200c, 0x385c9ce3, 0x3856a7b6, 0x1e5d3084, 0x1e7e5ae2, 0x3844bb28,
- 0x383ebd4c, 0x1e8966a8, 0x1eaa82e9, 0x382cb6b7, 0x3826b030, 0x1eb589f7, 0x1ed69805, 0x38148f9f,
- 0x380e8071, 0x1ee19a54, 0x1f029a1c, 0x37fc45ef, 0x37f62e1d, 0x1f0d97a5, 0x1f2e8911, 0x37e3d9b7,
- 0x37ddb945, 0x1f3981ce, 0x1f5a64cb, 0x37cb4b04, 0x37c521f6, 0x1f6558b5, 0x1f862d2d, 0x37b299e7,
- 0x37ac6841, 0x1f911c3d, 0x1fb1e21d, 0x3799c66f, 0x37938c34, 0x1fbccc4d, 0x1fdd8381, 0x3780d0aa,
- 0x377a8ddf, 0x1fe868c8, 0x2009113c, 0x3767b8a9, 0x37616d51, 0x2013f196, 0x20348b35, 0x374e7e7b,
- 0x37482a9a, 0x203f6699, 0x205ff14f, 0x3735222f, 0x372ec5c9, 0x206ac7b8, 0x208b4372, 0x371ba3d4,
- 0x37153eee, 0x209614d9, 0x20b68181, 0x3702037c, 0x36fb9618, 0x20c14ddf, 0x20e1ab63, 0x36e84135,
- 0x36e1cb58, 0x20ec72b1, 0x210cc0fc, 0x36ce5d10, 0x36c7debd, 0x21178334, 0x2137c232, 0x36b4571b,
- 0x36add058, 0x21427f4d, 0x2162aeea, 0x369a2f69, 0x3693a038, 0x216d66e2, 0x218d870b, 0x367fe608,
- 0x36794e6e, 0x219839d8, 0x21b84a79, 0x36657b08, 0x365edb09, 0x21c2f815, 0x21e2f91a, 0x364aee7b,
- 0x3644461b, 0x21eda17f, 0x220d92d4, 0x36304070, 0x36298fb4, 0x221835fb, 0x2238178d, 0x361570f8,
- 0x360eb7e3, 0x2242b56f, 0x22628729, 0x35fa8023, 0x35f3beba, 0x226d1fc1, 0x228ce191, 0x35df6e03,
- 0x35d8a449, 0x229774d7, 0x22b726a8, 0x35c43aa7, 0x35bd68a1, 0x22c1b496, 0x22e15655, 0x35a8e621,
- 0x35a20bd3, 0x22ebdee5, 0x230b707e, 0x358d7081, 0x35868def, 0x2315f3a8, 0x23357509, 0x3571d9d9,
- 0x356aef08, 0x233ff2c8, 0x235f63dc, 0x35562239, 0x354f2f2c, 0x2369dc29, 0x23893cdd, 0x353a49b2,
- 0x35334e6f, 0x2393afb2, 0x23b2fff3, 0x351e5056, 0x35174ce0, 0x23bd6d48, 0x23dcad03, 0x35023636,
- 0x34fb2a92, 0x23e714d3, 0x240643f4, 0x34e5fb63, 0x34dee795, 0x2410a639, 0x242fc4ad, 0x34c99fef,
- 0x34c283fb, 0x243a215f, 0x24592f13, 0x34ad23eb, 0x34a5ffd5, 0x2463862c, 0x2482830d, 0x34908768,
- 0x34895b36, 0x248cd487, 0x24abc082, 0x3473ca79, 0x346c962f, 0x24b60c57, 0x24d4e757, 0x3456ed2f,
- 0x344fb0d1, 0x24df2d81, 0x24fdf775, 0x3439ef9c, 0x3432ab2e, 0x250837ed, 0x2526f0c1, 0x341cd1d2,
- 0x34158559, 0x25312b81, 0x254fd323, 0x33ff93e2, 0x33f83f62, 0x255a0823, 0x25789e80, 0x33e235df,
- 0x33dad95e, 0x2582cdbc, 0x25a152c0, 0x33c4b7db, 0x33bd535c, 0x25ab7c30, 0x25c9efca, 0x33a719e8,
- 0x339fad70, 0x25d41369, 0x25f27584, 0x33895c18, 0x3381e7ac, 0x25fc934b, 0x261ae3d6, 0x336b7e7e,
- 0x33640223, 0x2624fbbf, 0x26433aa7, 0x334d812d, 0x3345fce6, 0x264d4cac, 0x266b79dd, 0x332f6435,
- 0x3327d808, 0x267585f8, 0x2693a161, 0x331127ab, 0x3309939c, 0x269da78b, 0x26bbb119, 0x32f2cba1,
- 0x32eb2fb5, 0x26c5b14c, 0x26e3a8ec, 0x32d45029, 0x32ccac64, 0x26eda322, 0x270b88c2, 0x32b5b557,
- 0x32ae09be, 0x27157cf5, 0x27335082, 0x3296fb3d, 0x328f47d5, 0x273d3eac, 0x275b0014, 0x327821ee,
- 0x327066bc, 0x2764e82f, 0x27829760, 0x3259297d, 0x32516686, 0x278c7965, 0x27aa164c, 0x323a11fe,
- 0x32324746, 0x27b3f235, 0x27d17cc1, 0x321adb83, 0x3213090f, 0x27db5288, 0x27f8caa5, 0x31fb8620,
- 0x31f3abf5, 0x28029a45, 0x281fffe2, 0x31dc11e8, 0x31d4300b, 0x2829c954, 0x28471c5e, 0x31bc7eee,
- 0x31b49564, 0x2850df9d, 0x286e2002, 0x319ccd46, 0x3194dc14, 0x2877dd07, 0x28950ab6, 0x317cfd04,
- 0x3175042e, 0x289ec17a, 0x28bbdc61, 0x315d0e3b, 0x31550dc6, 0x28c58cdf, 0x28e294eb, 0x313d00ff,
- 0x3134f8f1, 0x28ec3f1e, 0x2909343e, 0x311cd564, 0x3114c5c0, 0x2912d81f, 0x292fba40, 0x30fc8b7d,
- 0x30f47449, 0x293957c9, 0x295626da, 0x30dc235e, 0x30d404a0, 0x295fbe06, 0x297c79f5, 0x30bb9d1c,
- 0x30b376d8, 0x29860abd, 0x29a2b378, 0x309af8ca, 0x3092cb05, 0x29ac3dd7, 0x29c8d34d, 0x307a367c,
- 0x3072013c, 0x29d2573c, 0x29eed95b, 0x30595648, 0x30511991, 0x29f856d5, 0x2a14c58b, 0x30385840,
- 0x30301418, 0x2a1e3c8a, 0x2a3a97c7, 0x30173c7a, 0x300ef0e5, 0x2a440844, 0x2a604ff5, 0x2ff6030a,
- 0x2fedb00d, 0x2a69b9ec, 0x2a85ee00, 0x2fd4ac04, 0x2fcc51a5, 0x2a8f516b, 0x2aab71d0, 0x2fb3377c,
- 0x2faad5c1, 0x2ab4cea9, 0x2ad0db4e, 0x2f91a589, 0x2f893c75, 0x2ada318e, 0x2af62a63, 0x2f6ff63d,
- 0x2f6785d7, 0x2aff7a05, 0x2b1b5ef8, 0x2f4e29af, 0x2f45b1fb, 0x2b24a7f6, 0x2b4078f5, 0x2f2c3ff2,
- 0x2f23c0f6, 0x2b49bb4a, 0x2b657844, 0x2f0a391d, 0x2f01b2de, 0x2b6eb3ea, 0x2b8a5cce, 0x2ee81543,
- 0x2edf87c6, 0x2b9391c0, 0x2baf267d, 0x2ec5d479, 0x2ebd3fc4, 0x2bb854b4, 0x2bd3d53a, 0x2ea376d6,
- 0x2e9adaee, 0x2bdcfcb0, 0x2bf868ed, 0x2e80fc6e, 0x2e785958, 0x2c01899e, 0x2c1ce181, 0x2e5e6556,
- 0x2e55bb17, 0x2c25fb66, 0x2c413edf, 0x2e3bb1a4, 0x2e330042, 0x2c4a51f3, 0x2c6580f1, 0x2e18e16d,
- 0x2e1028ed, 0x2c6e8d2e, 0x2c89a79f, 0x2df5f4c7, 0x2ded352f, 0x2c92ad01, 0x2cadb2d5, 0x2dd2ebc7,
- 0x2dca251c, 0x2cb6b155, 0x2cd1a27b, 0x2dafc683, 0x2da6f8ca, 0x2cda9a14, 0x2cf5767c, 0x2d8c8510,
+ 0x3fffffb1, 0x0006487f, 0x002bfb74, 0x3ffff0e3, 0x3fffe705, 0x00388c6e, 0x005e3f4c, 0x3fffba9b,
+ 0x3fffa6de, 0x006ad03b, 0x009082ea, 0x3fff5cd8, 0x3fff3f3c, 0x009d13c5, 0x00c2c62f, 0x3ffed79b,
+ 0x3ffeb021, 0x00cf56ef, 0x00f508fc, 0x3ffe2ae5, 0x3ffdf98c, 0x01019998, 0x01274b31, 0x3ffd56b5,
+ 0x3ffd1b7e, 0x0133dba3, 0x01598cb1, 0x3ffc5b0c, 0x3ffc15f7, 0x01661cf0, 0x018bcd5b, 0x3ffb37ec,
+ 0x3ffae8f9, 0x01985d60, 0x01be0d11, 0x3ff9ed53, 0x3ff99483, 0x01ca9cd4, 0x01f04bb4, 0x3ff87b44,
+ 0x3ff81896, 0x01fcdb2e, 0x02228924, 0x3ff6e1bf, 0x3ff67534, 0x022f184d, 0x0254c544, 0x3ff520c5,
+ 0x3ff4aa5d, 0x02615414, 0x0286fff3, 0x3ff33858, 0x3ff2b813, 0x02938e62, 0x02b93914, 0x3ff12878,
+ 0x3ff09e56, 0x02c5c71a, 0x02eb7086, 0x3feef126, 0x3fee5d28, 0x02f7fe1c, 0x031da62b, 0x3fec9265,
+ 0x3febf48b, 0x032a3349, 0x034fd9e5, 0x3fea0c35, 0x3fe96480, 0x035c6682, 0x03820b93, 0x3fe75e98,
+ 0x3fe6ad08, 0x038e97a9, 0x03b43b17, 0x3fe48990, 0x3fe3ce26, 0x03c0c69e, 0x03e66852, 0x3fe18d1f,
+ 0x3fe0c7da, 0x03f2f342, 0x04189326, 0x3fde6945, 0x3fdd9a27, 0x04251d77, 0x044abb73, 0x3fdb1e06,
+ 0x3fda450f, 0x0457451d, 0x047ce11a, 0x3fd7ab64, 0x3fd6c894, 0x04896a16, 0x04af03fc, 0x3fd4115f,
+ 0x3fd324b7, 0x04bb8c42, 0x04e123fa, 0x3fd04ffc, 0x3fcf597c, 0x04edab83, 0x051340f6, 0x3fcc673b,
+ 0x3fcb66e4, 0x051fc7b9, 0x05455ad1, 0x3fc8571f, 0x3fc74cf3, 0x0551e0c7, 0x0577716b, 0x3fc41fac,
+ 0x3fc30baa, 0x0583f68c, 0x05a984a6, 0x3fbfc0e3, 0x3fbea30c, 0x05b608eb, 0x05db9463, 0x3fbb3ac7,
+ 0x3fba131b, 0x05e817c3, 0x060da083, 0x3fb68d5b, 0x3fb55bdc, 0x061a22f7, 0x063fa8e7, 0x3fb1b8a2,
+ 0x3fb07d50, 0x064c2a67, 0x0671ad71, 0x3facbc9f, 0x3fab777b, 0x067e2df5, 0x06a3ae00, 0x3fa79954,
+ 0x3fa64a5f, 0x06b02d81, 0x06d5aa77, 0x3fa24ec6, 0x3fa0f600, 0x06e228ee, 0x0707a2b7, 0x3f9cdcf7,
+ 0x3f9b7a62, 0x0714201b, 0x073996a1, 0x3f9743eb, 0x3f95d787, 0x074612eb, 0x076b8616, 0x3f9183a5,
+ 0x3f900d72, 0x0778013d, 0x079d70f7, 0x3f8b9c28, 0x3f8a1c29, 0x07a9eaf5, 0x07cf5726, 0x3f858d79,
+ 0x3f8403ae, 0x07dbcff2, 0x08013883, 0x3f7f579b, 0x3f7dc405, 0x080db016, 0x083314f1, 0x3f78fa92,
+ 0x3f775d31, 0x083f8b43, 0x0864ec4f, 0x3f727661, 0x3f70cf38, 0x08716159, 0x0896be80, 0x3f6bcb0e,
+ 0x3f6a1a1c, 0x08a3323a, 0x08c88b65, 0x3f64f89b, 0x3f633de2, 0x08d4fdc6, 0x08fa52de, 0x3f5dff0e,
+ 0x3f5c3a8f, 0x0906c3e0, 0x092c14ce, 0x3f56de6a, 0x3f551026, 0x09388469, 0x095dd116, 0x3f4f96b4,
+ 0x3f4dbeac, 0x096a3f42, 0x098f8796, 0x3f4827f0, 0x3f464626, 0x099bf44c, 0x09c13831, 0x3f409223,
+ 0x3f3ea697, 0x09cda368, 0x09f2e2c7, 0x3f38d552, 0x3f36e006, 0x09ff4c78, 0x0a24873a, 0x3f30f181,
+ 0x3f2ef276, 0x0a30ef5e, 0x0a56256c, 0x3f28e6b6, 0x3f26ddec, 0x0a628bfa, 0x0a87bd3d, 0x3f20b4f5,
+ 0x3f1ea26e, 0x0a94222f, 0x0ab94e8f, 0x3f185c43, 0x3f164001, 0x0ac5b1dc, 0x0aead944, 0x3f0fdca5,
+ 0x3f0db6a9, 0x0af73ae5, 0x0b1c5d3d, 0x3f073621, 0x3f05066d, 0x0b28bd2a, 0x0b4dda5c, 0x3efe68bc,
+ 0x3efc2f50, 0x0b5a388d, 0x0b7f5081, 0x3ef5747b, 0x3ef3315a, 0x0b8bacf0, 0x0bb0bf8f, 0x3eec5965,
+ 0x3eea0c8e, 0x0bbd1a33, 0x0be22766, 0x3ee3177e, 0x3ee0c0f4, 0x0bee8038, 0x0c1387e9, 0x3ed9aecc,
+ 0x3ed74e91, 0x0c1fdee1, 0x0c44e0f9, 0x3ed01f55, 0x3ecdb56a, 0x0c513610, 0x0c763278, 0x3ec66920,
+ 0x3ec3f585, 0x0c8285a5, 0x0ca77c47, 0x3ebc8c31, 0x3eba0ee9, 0x0cb3cd84, 0x0cd8be47, 0x3eb2888f,
+ 0x3eb0019c, 0x0ce50d8c, 0x0d09f85b, 0x3ea85e41, 0x3ea5cda3, 0x0d1645a0, 0x0d3b2a64, 0x3e9e0d4c,
+ 0x3e9b7306, 0x0d4775a1, 0x0d6c5443, 0x3e9395b7, 0x3e90f1ca, 0x0d789d71, 0x0d9d75db, 0x3e88f788,
+ 0x3e8649f5, 0x0da9bcf2, 0x0dce8f0d, 0x3e7e32c6, 0x3e7b7b90, 0x0ddad406, 0x0dff9fba, 0x3e734778,
+ 0x3e70869f, 0x0e0be28e, 0x0e30a7c5, 0x3e6835a4, 0x3e656b2b, 0x0e3ce86b, 0x0e61a70f, 0x3e5cfd51,
+ 0x3e5a2939, 0x0e6de580, 0x0e929d7a, 0x3e519e86, 0x3e4ec0d1, 0x0e9ed9af, 0x0ec38ae8, 0x3e46194a,
+ 0x3e4331fa, 0x0ecfc4d9, 0x0ef46f3b, 0x3e3a6da4, 0x3e377cbb, 0x0f00a6df, 0x0f254a53, 0x3e2e9b9c,
+ 0x3e2ba11b, 0x0f317fa5, 0x0f561c15, 0x3e22a338, 0x3e1f9f21, 0x0f624f0c, 0x0f86e460, 0x3e168480,
+ 0x3e1376d5, 0x0f9314f5, 0x0fb7a317, 0x3e0a3f7b, 0x3e07283f, 0x0fc3d143, 0x0fe8581d, 0x3dfdd432,
+ 0x3dfab365, 0x0ff483d7, 0x10190352, 0x3df142ab, 0x3dee1851, 0x10252c94, 0x1049a49a, 0x3de48aef,
+ 0x3de15708, 0x1055cb5b, 0x107a3bd5, 0x3dd7ad05, 0x3dd46f94, 0x1086600e, 0x10aac8e6, 0x3dcaa8f5,
+ 0x3dc761fc, 0x10b6ea90, 0x10db4baf, 0x3dbd7ec7, 0x3dba2e48, 0x10e76ac3, 0x110bc413, 0x3db02e84,
+ 0x3dacd481, 0x1117e088, 0x113c31f3, 0x3da2b834, 0x3d9f54af, 0x11484bc2, 0x116c9531, 0x3d951bde,
+ 0x3d91aed9, 0x1178ac53, 0x119cedaf, 0x3d87598c, 0x3d83e309, 0x11a9021d, 0x11cd3b50, 0x3d797145,
+ 0x3d75f147, 0x11d94d02, 0x11fd7df6, 0x3d6b6313, 0x3d67d99b, 0x12098ce5, 0x122db583, 0x3d5d2efe,
+ 0x3d599c0e, 0x1239c1a7, 0x125de1da, 0x3d4ed50f, 0x3d4b38aa, 0x1269eb2b, 0x128e02dc, 0x3d40554e,
+ 0x3d3caf76, 0x129a0954, 0x12be186c, 0x3d31afc5, 0x3d2e007c, 0x12ca1c03, 0x12ee226c, 0x3d22e47c,
+ 0x3d1f2bc5, 0x12fa231b, 0x131e20c0, 0x3d13f37e, 0x3d10315a, 0x132a1e7e, 0x134e1348, 0x3d04dcd2,
+ 0x3d011145, 0x135a0e0e, 0x137df9e7, 0x3cf5a082, 0x3cf1cb8e, 0x1389f1af, 0x13add481, 0x3ce63e98,
+ 0x3ce2603f, 0x13b9c943, 0x13dda2f7, 0x3cd6b71e, 0x3cd2cf62, 0x13e994ab, 0x140d652c, 0x3cc70a1c,
+ 0x3cc318ff, 0x141953cb, 0x143d1b02, 0x3cb7379c, 0x3cb33d22, 0x14490685, 0x146cc45c, 0x3ca73fa9,
+ 0x3ca33bd3, 0x1478acbc, 0x149c611d, 0x3c97224c, 0x3c93151d, 0x14a84652, 0x14cbf127, 0x3c86df8e,
+ 0x3c82c909, 0x14d7d32a, 0x14fb745e, 0x3c76777b, 0x3c7257a2, 0x15075327, 0x152aeaa3, 0x3c65ea1c,
+ 0x3c61c0f1, 0x1536c62b, 0x155a53d9, 0x3c55377b, 0x3c510501, 0x15662c18, 0x1589afe3, 0x3c445fa2,
+ 0x3c4023dd, 0x159584d3, 0x15b8fea4, 0x3c33629d, 0x3c2f1d8e, 0x15c4d03e, 0x15e83fff, 0x3c224075,
+ 0x3c1df21f, 0x15f40e3a, 0x161773d6, 0x3c10f935, 0x3c0ca19b, 0x16233eac, 0x16469a0d, 0x3bff8ce8,
+ 0x3bfb2c0c, 0x16526176, 0x1675b286, 0x3bedfb99, 0x3be9917e, 0x1681767c, 0x16a4bd25, 0x3bdc4552,
+ 0x3bd7d1fa, 0x16b07d9f, 0x16d3b9cc, 0x3bca6a1d, 0x3bc5ed8d, 0x16df76c3, 0x1702a85e, 0x3bb86a08,
+ 0x3bb3e440, 0x170e61cc, 0x173188be, 0x3ba6451b, 0x3ba1b620, 0x173d3e9b, 0x17605ad0, 0x3b93fb63,
+ 0x3b8f6337, 0x176c0d15, 0x178f1e76, 0x3b818ceb, 0x3b7ceb90, 0x179acd1c, 0x17bdd394, 0x3b6ef9be,
+ 0x3b6a4f38, 0x17c97e93, 0x17ec7a0d, 0x3b5c41e8, 0x3b578e39, 0x17f8215e, 0x181b11c4, 0x3b496574,
+ 0x3b44a8a0, 0x1826b561, 0x18499a9d, 0x3b36646e, 0x3b319e77, 0x18553a7d, 0x1878147a, 0x3b233ee1,
+ 0x3b1e6fca, 0x1883b097, 0x18a67f3f, 0x3b0ff4d9, 0x3b0b1ca6, 0x18b21791, 0x18d4dad0, 0x3afc8663,
+ 0x3af7a516, 0x18e06f50, 0x1903270f, 0x3ae8f38b, 0x3ae40926, 0x190eb7b7, 0x193163e1, 0x3ad53c5b,
+ 0x3ad048e3, 0x193cf0a9, 0x195f9128, 0x3ac160e1, 0x3abc6458, 0x196b1a09, 0x198daec8, 0x3aad6129,
+ 0x3aa85b92, 0x199933bb, 0x19bbbca6, 0x3a993d3e, 0x3a942e9d, 0x19c73da3, 0x19e9baa3, 0x3a84f52f,
+ 0x3a7fdd86, 0x19f537a4, 0x1a17a8a5, 0x3a708906, 0x3a6b6859, 0x1a2321a2, 0x1a45868e, 0x3a5bf8d1,
+ 0x3a56cf23, 0x1a50fb81, 0x1a735442, 0x3a47449c, 0x3a4211f0, 0x1a7ec524, 0x1aa111a6, 0x3a326c74,
+ 0x3a2d30cd, 0x1aac7e6f, 0x1acebe9d, 0x3a1d7066, 0x3a182bc8, 0x1ada2746, 0x1afc5b0a, 0x3a08507f,
+ 0x3a0302ed, 0x1b07bf8c, 0x1b29e6d2, 0x39f30ccc, 0x39edb649, 0x1b354727, 0x1b5761d8, 0x39dda55a,
+ 0x39d845e9, 0x1b62bdf8, 0x1b84cc01, 0x39c81a36, 0x39c2b1da, 0x1b9023e5, 0x1bb22530, 0x39b26b6d,
+ 0x39acfa2b, 0x1bbd78d2, 0x1bdf6d4a, 0x399c990d, 0x39971ee7, 0x1beabca1, 0x1c0ca432, 0x3986a324,
+ 0x3981201e, 0x1c17ef39, 0x1c39c9cd, 0x397089bf, 0x396afddc, 0x1c45107c, 0x1c66ddfe, 0x395a4ceb,
+ 0x3954b82e, 0x1c72204f, 0x1c93e0ab, 0x3943ecb6, 0x393e4f23, 0x1c9f1e96, 0x1cc0d1b6, 0x392d692f,
+ 0x3927c2c9, 0x1ccc0b35, 0x1cedb106, 0x3916c262, 0x3911132d, 0x1cf8e611, 0x1d1a7e7d, 0x38fff85e,
+ 0x38fa405e, 0x1d25af0d, 0x1d473a00, 0x38e90b31, 0x38e34a69, 0x1d52660f, 0x1d73e374, 0x38d1fae9,
+ 0x38cc315d, 0x1d7f0afb, 0x1da07abc, 0x38bac795, 0x38b4f547, 0x1dab9db5, 0x1dccffbf, 0x38a37142,
+ 0x389d9637, 0x1dd81e21, 0x1df9725f, 0x388bf7ff, 0x3886143b, 0x1e048c24, 0x1e25d282, 0x38745bdb,
+ 0x386e6f60, 0x1e30e7a4, 0x1e52200c, 0x385c9ce3, 0x3856a7b6, 0x1e5d3084, 0x1e7e5ae2, 0x3844bb28,
+ 0x383ebd4c, 0x1e8966a8, 0x1eaa82e9, 0x382cb6b7, 0x3826b030, 0x1eb589f7, 0x1ed69805, 0x38148f9f,
+ 0x380e8071, 0x1ee19a54, 0x1f029a1c, 0x37fc45ef, 0x37f62e1d, 0x1f0d97a5, 0x1f2e8911, 0x37e3d9b7,
+ 0x37ddb945, 0x1f3981ce, 0x1f5a64cb, 0x37cb4b04, 0x37c521f6, 0x1f6558b5, 0x1f862d2d, 0x37b299e7,
+ 0x37ac6841, 0x1f911c3d, 0x1fb1e21d, 0x3799c66f, 0x37938c34, 0x1fbccc4d, 0x1fdd8381, 0x3780d0aa,
+ 0x377a8ddf, 0x1fe868c8, 0x2009113c, 0x3767b8a9, 0x37616d51, 0x2013f196, 0x20348b35, 0x374e7e7b,
+ 0x37482a9a, 0x203f6699, 0x205ff14f, 0x3735222f, 0x372ec5c9, 0x206ac7b8, 0x208b4372, 0x371ba3d4,
+ 0x37153eee, 0x209614d9, 0x20b68181, 0x3702037c, 0x36fb9618, 0x20c14ddf, 0x20e1ab63, 0x36e84135,
+ 0x36e1cb58, 0x20ec72b1, 0x210cc0fc, 0x36ce5d10, 0x36c7debd, 0x21178334, 0x2137c232, 0x36b4571b,
+ 0x36add058, 0x21427f4d, 0x2162aeea, 0x369a2f69, 0x3693a038, 0x216d66e2, 0x218d870b, 0x367fe608,
+ 0x36794e6e, 0x219839d8, 0x21b84a79, 0x36657b08, 0x365edb09, 0x21c2f815, 0x21e2f91a, 0x364aee7b,
+ 0x3644461b, 0x21eda17f, 0x220d92d4, 0x36304070, 0x36298fb4, 0x221835fb, 0x2238178d, 0x361570f8,
+ 0x360eb7e3, 0x2242b56f, 0x22628729, 0x35fa8023, 0x35f3beba, 0x226d1fc1, 0x228ce191, 0x35df6e03,
+ 0x35d8a449, 0x229774d7, 0x22b726a8, 0x35c43aa7, 0x35bd68a1, 0x22c1b496, 0x22e15655, 0x35a8e621,
+ 0x35a20bd3, 0x22ebdee5, 0x230b707e, 0x358d7081, 0x35868def, 0x2315f3a8, 0x23357509, 0x3571d9d9,
+ 0x356aef08, 0x233ff2c8, 0x235f63dc, 0x35562239, 0x354f2f2c, 0x2369dc29, 0x23893cdd, 0x353a49b2,
+ 0x35334e6f, 0x2393afb2, 0x23b2fff3, 0x351e5056, 0x35174ce0, 0x23bd6d48, 0x23dcad03, 0x35023636,
+ 0x34fb2a92, 0x23e714d3, 0x240643f4, 0x34e5fb63, 0x34dee795, 0x2410a639, 0x242fc4ad, 0x34c99fef,
+ 0x34c283fb, 0x243a215f, 0x24592f13, 0x34ad23eb, 0x34a5ffd5, 0x2463862c, 0x2482830d, 0x34908768,
+ 0x34895b36, 0x248cd487, 0x24abc082, 0x3473ca79, 0x346c962f, 0x24b60c57, 0x24d4e757, 0x3456ed2f,
+ 0x344fb0d1, 0x24df2d81, 0x24fdf775, 0x3439ef9c, 0x3432ab2e, 0x250837ed, 0x2526f0c1, 0x341cd1d2,
+ 0x34158559, 0x25312b81, 0x254fd323, 0x33ff93e2, 0x33f83f62, 0x255a0823, 0x25789e80, 0x33e235df,
+ 0x33dad95e, 0x2582cdbc, 0x25a152c0, 0x33c4b7db, 0x33bd535c, 0x25ab7c30, 0x25c9efca, 0x33a719e8,
+ 0x339fad70, 0x25d41369, 0x25f27584, 0x33895c18, 0x3381e7ac, 0x25fc934b, 0x261ae3d6, 0x336b7e7e,
+ 0x33640223, 0x2624fbbf, 0x26433aa7, 0x334d812d, 0x3345fce6, 0x264d4cac, 0x266b79dd, 0x332f6435,
+ 0x3327d808, 0x267585f8, 0x2693a161, 0x331127ab, 0x3309939c, 0x269da78b, 0x26bbb119, 0x32f2cba1,
+ 0x32eb2fb5, 0x26c5b14c, 0x26e3a8ec, 0x32d45029, 0x32ccac64, 0x26eda322, 0x270b88c2, 0x32b5b557,
+ 0x32ae09be, 0x27157cf5, 0x27335082, 0x3296fb3d, 0x328f47d5, 0x273d3eac, 0x275b0014, 0x327821ee,
+ 0x327066bc, 0x2764e82f, 0x27829760, 0x3259297d, 0x32516686, 0x278c7965, 0x27aa164c, 0x323a11fe,
+ 0x32324746, 0x27b3f235, 0x27d17cc1, 0x321adb83, 0x3213090f, 0x27db5288, 0x27f8caa5, 0x31fb8620,
+ 0x31f3abf5, 0x28029a45, 0x281fffe2, 0x31dc11e8, 0x31d4300b, 0x2829c954, 0x28471c5e, 0x31bc7eee,
+ 0x31b49564, 0x2850df9d, 0x286e2002, 0x319ccd46, 0x3194dc14, 0x2877dd07, 0x28950ab6, 0x317cfd04,
+ 0x3175042e, 0x289ec17a, 0x28bbdc61, 0x315d0e3b, 0x31550dc6, 0x28c58cdf, 0x28e294eb, 0x313d00ff,
+ 0x3134f8f1, 0x28ec3f1e, 0x2909343e, 0x311cd564, 0x3114c5c0, 0x2912d81f, 0x292fba40, 0x30fc8b7d,
+ 0x30f47449, 0x293957c9, 0x295626da, 0x30dc235e, 0x30d404a0, 0x295fbe06, 0x297c79f5, 0x30bb9d1c,
+ 0x30b376d8, 0x29860abd, 0x29a2b378, 0x309af8ca, 0x3092cb05, 0x29ac3dd7, 0x29c8d34d, 0x307a367c,
+ 0x3072013c, 0x29d2573c, 0x29eed95b, 0x30595648, 0x30511991, 0x29f856d5, 0x2a14c58b, 0x30385840,
+ 0x30301418, 0x2a1e3c8a, 0x2a3a97c7, 0x30173c7a, 0x300ef0e5, 0x2a440844, 0x2a604ff5, 0x2ff6030a,
+ 0x2fedb00d, 0x2a69b9ec, 0x2a85ee00, 0x2fd4ac04, 0x2fcc51a5, 0x2a8f516b, 0x2aab71d0, 0x2fb3377c,
+ 0x2faad5c1, 0x2ab4cea9, 0x2ad0db4e, 0x2f91a589, 0x2f893c75, 0x2ada318e, 0x2af62a63, 0x2f6ff63d,
+ 0x2f6785d7, 0x2aff7a05, 0x2b1b5ef8, 0x2f4e29af, 0x2f45b1fb, 0x2b24a7f6, 0x2b4078f5, 0x2f2c3ff2,
+ 0x2f23c0f6, 0x2b49bb4a, 0x2b657844, 0x2f0a391d, 0x2f01b2de, 0x2b6eb3ea, 0x2b8a5cce, 0x2ee81543,
+ 0x2edf87c6, 0x2b9391c0, 0x2baf267d, 0x2ec5d479, 0x2ebd3fc4, 0x2bb854b4, 0x2bd3d53a, 0x2ea376d6,
+ 0x2e9adaee, 0x2bdcfcb0, 0x2bf868ed, 0x2e80fc6e, 0x2e785958, 0x2c01899e, 0x2c1ce181, 0x2e5e6556,
+ 0x2e55bb17, 0x2c25fb66, 0x2c413edf, 0x2e3bb1a4, 0x2e330042, 0x2c4a51f3, 0x2c6580f1, 0x2e18e16d,
+ 0x2e1028ed, 0x2c6e8d2e, 0x2c89a79f, 0x2df5f4c7, 0x2ded352f, 0x2c92ad01, 0x2cadb2d5, 0x2dd2ebc7,
+ 0x2dca251c, 0x2cb6b155, 0x2cd1a27b, 0x2dafc683, 0x2da6f8ca, 0x2cda9a14, 0x2cf5767c, 0x2d8c8510,
0x2d83b04f, 0x2cfe6728, 0x2d192ec1, 0x2d692784, 0x2d604bc0, 0x2d22187a, 0x2d3ccb34, 0x2d45adf6
};
const int twidTab512[(8*6 + 32*6 + 128*6)/2] = {
- 0x40000000, 0x40000000, 0x40000000, 0x3b20187d,
- 0x3ec50c7c, 0x3536238e, 0x2d412d41, 0x3b20187d,
- 0x187d3b20, 0x187d3b20, 0x3536238e, 0xf3843ec5,
- 0x00004000, 0x2d412d41, 0xd2bf2d41, 0xe7833b20,
- 0x238e3536, 0xc13b0c7c, 0xd2bf2d41, 0x187d3b20,
- 0xc4e0e783, 0xc4e0187d, 0x0c7c3ec5, 0xdc72caca,
+ 0x40000000, 0x40000000, 0x40000000, 0x3b20187d,
+ 0x3ec50c7c, 0x3536238e, 0x2d412d41, 0x3b20187d,
+ 0x187d3b20, 0x187d3b20, 0x3536238e, 0xf3843ec5,
+ 0x00004000, 0x2d412d41, 0xd2bf2d41, 0xe7833b20,
+ 0x238e3536, 0xc13b0c7c, 0xd2bf2d41, 0x187d3b20,
+ 0xc4e0e783, 0xc4e0187d, 0x0c7c3ec5, 0xdc72caca,
- 0x40000000, 0x40000000, 0x40000000, 0x3fb10645,
- 0x3fec0323, 0x3f4e0964, 0x3ec50c7c, 0x3fb10645,
- 0x3d3e1294, 0x3d3e1294, 0x3f4e0964, 0x39da1b5d,
- 0x3b20187d, 0x3ec50c7c, 0x3536238e, 0x38711e2b,
- 0x3e140f8c, 0x2f6b2afa, 0x3536238e, 0x3d3e1294,
- 0x28993179, 0x31792899, 0x3c42158f, 0x20e736e5,
- 0x2d412d41, 0x3b20187d, 0x187d3b20, 0x28993179,
- 0x39da1b5d, 0x0f8c3e14, 0x238e3536, 0x38711e2b,
- 0x06453fb1, 0x1e2b3871, 0x36e520e7, 0xfcdd3fec,
- 0x187d3b20, 0x3536238e, 0xf3843ec5, 0x12943d3e,
- 0x3367261f, 0xea713c42, 0x0c7c3ec5, 0x31792899,
- 0xe1d53871, 0x06453fb1, 0x2f6b2afa, 0xd9e13367,
- 0x00004000, 0x2d412d41, 0xd2bf2d41, 0xf9bb3fb1,
- 0x2afa2f6b, 0xcc99261f, 0xf3843ec5, 0x28993179,
- 0xc78f1e2b, 0xed6c3d3e, 0x261f3367, 0xc3be158f,
- 0xe7833b20, 0x238e3536, 0xc13b0c7c, 0xe1d53871,
- 0x20e736e5, 0xc0140323, 0xdc723536, 0x1e2b3871,
- 0xc04ff9bb, 0xd7673179, 0x1b5d39da, 0xc1ecf074,
- 0xd2bf2d41, 0x187d3b20, 0xc4e0e783, 0xce872899,
- 0x158f3c42, 0xc91bdf19, 0xcaca238e, 0x12943d3e,
- 0xce87d767, 0xc78f1e2b, 0x0f8c3e14, 0xd506d095,
- 0xc4e0187d, 0x0c7c3ec5, 0xdc72caca, 0xc2c21294,
- 0x09643f4e, 0xe4a3c626, 0xc13b0c7c, 0x06453fb1,
- 0xed6cc2c2, 0xc04f0645, 0x03233fec, 0xf69cc0b2,
+ 0x40000000, 0x40000000, 0x40000000, 0x3fb10645,
+ 0x3fec0323, 0x3f4e0964, 0x3ec50c7c, 0x3fb10645,
+ 0x3d3e1294, 0x3d3e1294, 0x3f4e0964, 0x39da1b5d,
+ 0x3b20187d, 0x3ec50c7c, 0x3536238e, 0x38711e2b,
+ 0x3e140f8c, 0x2f6b2afa, 0x3536238e, 0x3d3e1294,
+ 0x28993179, 0x31792899, 0x3c42158f, 0x20e736e5,
+ 0x2d412d41, 0x3b20187d, 0x187d3b20, 0x28993179,
+ 0x39da1b5d, 0x0f8c3e14, 0x238e3536, 0x38711e2b,
+ 0x06453fb1, 0x1e2b3871, 0x36e520e7, 0xfcdd3fec,
+ 0x187d3b20, 0x3536238e, 0xf3843ec5, 0x12943d3e,
+ 0x3367261f, 0xea713c42, 0x0c7c3ec5, 0x31792899,
+ 0xe1d53871, 0x06453fb1, 0x2f6b2afa, 0xd9e13367,
+ 0x00004000, 0x2d412d41, 0xd2bf2d41, 0xf9bb3fb1,
+ 0x2afa2f6b, 0xcc99261f, 0xf3843ec5, 0x28993179,
+ 0xc78f1e2b, 0xed6c3d3e, 0x261f3367, 0xc3be158f,
+ 0xe7833b20, 0x238e3536, 0xc13b0c7c, 0xe1d53871,
+ 0x20e736e5, 0xc0140323, 0xdc723536, 0x1e2b3871,
+ 0xc04ff9bb, 0xd7673179, 0x1b5d39da, 0xc1ecf074,
+ 0xd2bf2d41, 0x187d3b20, 0xc4e0e783, 0xce872899,
+ 0x158f3c42, 0xc91bdf19, 0xcaca238e, 0x12943d3e,
+ 0xce87d767, 0xc78f1e2b, 0x0f8c3e14, 0xd506d095,
+ 0xc4e0187d, 0x0c7c3ec5, 0xdc72caca, 0xc2c21294,
+ 0x09643f4e, 0xe4a3c626, 0xc13b0c7c, 0x06453fb1,
+ 0xed6cc2c2, 0xc04f0645, 0x03233fec, 0xf69cc0b2,
- 0x40000000, 0x40000000, 0x40000000, 0x3ffb0192,
- 0x3ffe00c9, 0x3ff4025b, 0x3fec0323, 0x3ffb0192,
- 0x3fd304b5, 0x3fd304b5, 0x3ff4025b, 0x3f9c070d,
- 0x3fb10645, 0x3fec0323, 0x3f4e0964, 0x3f8407d5,
- 0x3fe103ec, 0x3eeb0bb6, 0x3f4e0964, 0x3fd304b5,
- 0x3e710e05, 0x3f0e0af1, 0x3fc3057d, 0x3de2104f,
- 0x3ec50c7c, 0x3fb10645, 0x3d3e1294, 0x3e710e05,
- 0x3f9c070d, 0x3c8414d1, 0x3e140f8c, 0x3f8407d5,
- 0x3bb61708, 0x3dae1111, 0x3f6a089c, 0x3ad21937,
- 0x3d3e1294, 0x3f4e0964, 0x39da1b5d, 0x3cc51413,
- 0x3f2f0a2a, 0x38cf1d79, 0x3c42158f, 0x3f0e0af1,
- 0x37af1f8b, 0x3bb61708, 0x3eeb0bb6, 0x367c2192,
- 0x3b20187d, 0x3ec50c7c, 0x3536238e, 0x3a8219ef,
- 0x3e9c0d41, 0x33de257d, 0x39da1b5d, 0x3e710e05,
- 0x3274275f, 0x392a1cc6, 0x3e440ec9, 0x30f82934,
- 0x38711e2b, 0x3e140f8c, 0x2f6b2afa, 0x37af1f8b,
- 0x3de2104f, 0x2dce2cb2, 0x36e520e7, 0x3dae1111,
- 0x2c212e5a, 0x3612223d, 0x3d7711d3, 0x2a652ff1,
- 0x3536238e, 0x3d3e1294, 0x28993179, 0x345324da,
- 0x3d021354, 0x26c032ee, 0x3367261f, 0x3cc51413,
- 0x24da3453, 0x3274275f, 0x3c8414d1, 0x22e635a5,
- 0x31792899, 0x3c42158f, 0x20e736e5, 0x307629cd,
- 0x3bfd164c, 0x1edc3811, 0x2f6b2afa, 0x3bb61708,
- 0x1cc6392a, 0x2e5a2c21, 0x3b6c17c3, 0x1aa63a2f,
- 0x2d412d41, 0x3b20187d, 0x187d3b20, 0x2c212e5a,
- 0x3ad21937, 0x164c3bfd, 0x2afa2f6b, 0x3a8219ef,
- 0x14133cc5, 0x29cd3076, 0x3a2f1aa6, 0x11d33d77,
- 0x28993179, 0x39da1b5d, 0x0f8c3e14, 0x275f3274,
- 0x39831c12, 0x0d413e9c, 0x261f3367, 0x392a1cc6,
- 0x0af13f0e, 0x24da3453, 0x38cf1d79, 0x089c3f6a,
- 0x238e3536, 0x38711e2b, 0x06453fb1, 0x223d3612,
- 0x38111edc, 0x03ec3fe1, 0x20e736e5, 0x37af1f8b,
- 0x01923ffb, 0x1f8b37af, 0x374b2039, 0xff373ffe,
- 0x1e2b3871, 0x36e520e7, 0xfcdd3fec, 0x1cc6392a,
- 0x367c2192, 0xfa833fc3, 0x1b5d39da, 0x3612223d,
- 0xf82b3f84, 0x19ef3a82, 0x35a522e6, 0xf5d63f2f,
- 0x187d3b20, 0x3536238e, 0xf3843ec5, 0x17083bb6,
- 0x34c62434, 0xf1373e44, 0x158f3c42, 0x345324da,
- 0xeeef3dae, 0x14133cc5, 0x33de257d, 0xecac3d02,
- 0x12943d3e, 0x3367261f, 0xea713c42, 0x11113dae,
- 0x32ee26c0, 0xe83d3b6c, 0x0f8c3e14, 0x3274275f,
- 0xe6113a82, 0x0e053e71, 0x31f727fd, 0xe3ee3983,
- 0x0c7c3ec5, 0x31792899, 0xe1d53871, 0x0af13f0e,
- 0x30f82934, 0xdfc7374b, 0x09643f4e, 0x307629cd,
- 0xddc33612, 0x07d53f84, 0x2ff12a65, 0xdbcc34c6,
- 0x06453fb1, 0x2f6b2afa, 0xd9e13367, 0x04b53fd3,
- 0x2ee32b8e, 0xd80331f7, 0x03233fec, 0x2e5a2c21,
- 0xd6333076, 0x01923ffb, 0x2dce2cb2, 0xd4722ee3,
- 0x00004000, 0x2d412d41, 0xd2bf2d41, 0xfe6e3ffb,
- 0x2cb22dce, 0xd11d2b8e, 0xfcdd3fec, 0x2c212e5a,
- 0xcf8a29cd, 0xfb4b3fd3, 0x2b8e2ee3, 0xce0927fd,
- 0xf9bb3fb1, 0x2afa2f6b, 0xcc99261f, 0xf82b3f84,
- 0x2a652ff1, 0xcb3a2434, 0xf69c3f4e, 0x29cd3076,
- 0xc9ee223d, 0xf50f3f0e, 0x293430f8, 0xc8b52039,
- 0xf3843ec5, 0x28993179, 0xc78f1e2b, 0xf1fb3e71,
- 0x27fd31f7, 0xc67d1c12, 0xf0743e14, 0x275f3274,
- 0xc57e19ef, 0xeeef3dae, 0x26c032ee, 0xc49417c3,
- 0xed6c3d3e, 0x261f3367, 0xc3be158f, 0xebed3cc5,
- 0x257d33de, 0xc2fe1354, 0xea713c42, 0x24da3453,
- 0xc2521111, 0xe8f83bb6, 0x243434c6, 0xc1bc0ec9,
- 0xe7833b20, 0x238e3536, 0xc13b0c7c, 0xe6113a82,
- 0x22e635a5, 0xc0d10a2a, 0xe4a339da, 0x223d3612,
- 0xc07c07d5, 0xe33a392a, 0x2192367c, 0xc03d057d,
- 0xe1d53871, 0x20e736e5, 0xc0140323, 0xe07537af,
- 0x2039374b, 0xc00200c9, 0xdf1936e5, 0x1f8b37af,
- 0xc005fe6e, 0xddc33612, 0x1edc3811, 0xc01ffc14,
- 0xdc723536, 0x1e2b3871, 0xc04ff9bb, 0xdb263453,
- 0x1d7938cf, 0xc096f764, 0xd9e13367, 0x1cc6392a,
- 0xc0f2f50f, 0xd8a13274, 0x1c123983, 0xc164f2bf,
- 0xd7673179, 0x1b5d39da, 0xc1ecf074, 0xd6333076,
- 0x1aa63a2f, 0xc289ee2d, 0xd5062f6b, 0x19ef3a82,
- 0xc33bebed, 0xd3df2e5a, 0x19373ad2, 0xc403e9b4,
- 0xd2bf2d41, 0x187d3b20, 0xc4e0e783, 0xd1a62c21,
- 0x17c33b6c, 0xc5d1e55a, 0xd0952afa, 0x17083bb6,
- 0xc6d6e33a, 0xcf8a29cd, 0x164c3bfd, 0xc7efe124,
- 0xce872899, 0x158f3c42, 0xc91bdf19, 0xcd8c275f,
- 0x14d13c84, 0xca5bdd1a, 0xcc99261f, 0x14133cc5,
- 0xcbaddb26, 0xcbad24da, 0x13543d02, 0xcd12d940,
- 0xcaca238e, 0x12943d3e, 0xce87d767, 0xc9ee223d,
- 0x11d33d77, 0xd00fd59b, 0xc91b20e7, 0x11113dae,
- 0xd1a6d3df, 0xc8511f8b, 0x104f3de2, 0xd34ed232,
- 0xc78f1e2b, 0x0f8c3e14, 0xd506d095, 0xc6d61cc6,
- 0x0ec93e44, 0xd6cccf08, 0xc6261b5d, 0x0e053e71,
- 0xd8a1cd8c, 0xc57e19ef, 0x0d413e9c, 0xda83cc22,
- 0xc4e0187d, 0x0c7c3ec5, 0xdc72caca, 0xc44a1708,
- 0x0bb63eeb, 0xde6ec984, 0xc3be158f, 0x0af13f0e,
- 0xe075c851, 0xc33b1413, 0x0a2a3f2f, 0xe287c731,
- 0xc2c21294, 0x09643f4e, 0xe4a3c626, 0xc2521111,
- 0x089c3f6a, 0xe6c9c52e, 0xc1ec0f8c, 0x07d53f84,
- 0xe8f8c44a, 0xc18f0e05, 0x070d3f9c, 0xeb2fc37c,
- 0xc13b0c7c, 0x06453fb1, 0xed6cc2c2, 0xc0f20af1,
- 0x057d3fc3, 0xefb1c21e, 0xc0b20964, 0x04b53fd3,
- 0xf1fbc18f, 0xc07c07d5, 0x03ec3fe1, 0xf44ac115,
- 0xc04f0645, 0x03233fec, 0xf69cc0b2, 0xc02d04b5,
- 0x025b3ff4, 0xf8f3c064, 0xc0140323, 0x01923ffb,
- 0xfb4bc02d, 0xc0050192, 0x00c93ffe, 0xfda5c00c
+ 0x40000000, 0x40000000, 0x40000000, 0x3ffb0192,
+ 0x3ffe00c9, 0x3ff4025b, 0x3fec0323, 0x3ffb0192,
+ 0x3fd304b5, 0x3fd304b5, 0x3ff4025b, 0x3f9c070d,
+ 0x3fb10645, 0x3fec0323, 0x3f4e0964, 0x3f8407d5,
+ 0x3fe103ec, 0x3eeb0bb6, 0x3f4e0964, 0x3fd304b5,
+ 0x3e710e05, 0x3f0e0af1, 0x3fc3057d, 0x3de2104f,
+ 0x3ec50c7c, 0x3fb10645, 0x3d3e1294, 0x3e710e05,
+ 0x3f9c070d, 0x3c8414d1, 0x3e140f8c, 0x3f8407d5,
+ 0x3bb61708, 0x3dae1111, 0x3f6a089c, 0x3ad21937,
+ 0x3d3e1294, 0x3f4e0964, 0x39da1b5d, 0x3cc51413,
+ 0x3f2f0a2a, 0x38cf1d79, 0x3c42158f, 0x3f0e0af1,
+ 0x37af1f8b, 0x3bb61708, 0x3eeb0bb6, 0x367c2192,
+ 0x3b20187d, 0x3ec50c7c, 0x3536238e, 0x3a8219ef,
+ 0x3e9c0d41, 0x33de257d, 0x39da1b5d, 0x3e710e05,
+ 0x3274275f, 0x392a1cc6, 0x3e440ec9, 0x30f82934,
+ 0x38711e2b, 0x3e140f8c, 0x2f6b2afa, 0x37af1f8b,
+ 0x3de2104f, 0x2dce2cb2, 0x36e520e7, 0x3dae1111,
+ 0x2c212e5a, 0x3612223d, 0x3d7711d3, 0x2a652ff1,
+ 0x3536238e, 0x3d3e1294, 0x28993179, 0x345324da,
+ 0x3d021354, 0x26c032ee, 0x3367261f, 0x3cc51413,
+ 0x24da3453, 0x3274275f, 0x3c8414d1, 0x22e635a5,
+ 0x31792899, 0x3c42158f, 0x20e736e5, 0x307629cd,
+ 0x3bfd164c, 0x1edc3811, 0x2f6b2afa, 0x3bb61708,
+ 0x1cc6392a, 0x2e5a2c21, 0x3b6c17c3, 0x1aa63a2f,
+ 0x2d412d41, 0x3b20187d, 0x187d3b20, 0x2c212e5a,
+ 0x3ad21937, 0x164c3bfd, 0x2afa2f6b, 0x3a8219ef,
+ 0x14133cc5, 0x29cd3076, 0x3a2f1aa6, 0x11d33d77,
+ 0x28993179, 0x39da1b5d, 0x0f8c3e14, 0x275f3274,
+ 0x39831c12, 0x0d413e9c, 0x261f3367, 0x392a1cc6,
+ 0x0af13f0e, 0x24da3453, 0x38cf1d79, 0x089c3f6a,
+ 0x238e3536, 0x38711e2b, 0x06453fb1, 0x223d3612,
+ 0x38111edc, 0x03ec3fe1, 0x20e736e5, 0x37af1f8b,
+ 0x01923ffb, 0x1f8b37af, 0x374b2039, 0xff373ffe,
+ 0x1e2b3871, 0x36e520e7, 0xfcdd3fec, 0x1cc6392a,
+ 0x367c2192, 0xfa833fc3, 0x1b5d39da, 0x3612223d,
+ 0xf82b3f84, 0x19ef3a82, 0x35a522e6, 0xf5d63f2f,
+ 0x187d3b20, 0x3536238e, 0xf3843ec5, 0x17083bb6,
+ 0x34c62434, 0xf1373e44, 0x158f3c42, 0x345324da,
+ 0xeeef3dae, 0x14133cc5, 0x33de257d, 0xecac3d02,
+ 0x12943d3e, 0x3367261f, 0xea713c42, 0x11113dae,
+ 0x32ee26c0, 0xe83d3b6c, 0x0f8c3e14, 0x3274275f,
+ 0xe6113a82, 0x0e053e71, 0x31f727fd, 0xe3ee3983,
+ 0x0c7c3ec5, 0x31792899, 0xe1d53871, 0x0af13f0e,
+ 0x30f82934, 0xdfc7374b, 0x09643f4e, 0x307629cd,
+ 0xddc33612, 0x07d53f84, 0x2ff12a65, 0xdbcc34c6,
+ 0x06453fb1, 0x2f6b2afa, 0xd9e13367, 0x04b53fd3,
+ 0x2ee32b8e, 0xd80331f7, 0x03233fec, 0x2e5a2c21,
+ 0xd6333076, 0x01923ffb, 0x2dce2cb2, 0xd4722ee3,
+ 0x00004000, 0x2d412d41, 0xd2bf2d41, 0xfe6e3ffb,
+ 0x2cb22dce, 0xd11d2b8e, 0xfcdd3fec, 0x2c212e5a,
+ 0xcf8a29cd, 0xfb4b3fd3, 0x2b8e2ee3, 0xce0927fd,
+ 0xf9bb3fb1, 0x2afa2f6b, 0xcc99261f, 0xf82b3f84,
+ 0x2a652ff1, 0xcb3a2434, 0xf69c3f4e, 0x29cd3076,
+ 0xc9ee223d, 0xf50f3f0e, 0x293430f8, 0xc8b52039,
+ 0xf3843ec5, 0x28993179, 0xc78f1e2b, 0xf1fb3e71,
+ 0x27fd31f7, 0xc67d1c12, 0xf0743e14, 0x275f3274,
+ 0xc57e19ef, 0xeeef3dae, 0x26c032ee, 0xc49417c3,
+ 0xed6c3d3e, 0x261f3367, 0xc3be158f, 0xebed3cc5,
+ 0x257d33de, 0xc2fe1354, 0xea713c42, 0x24da3453,
+ 0xc2521111, 0xe8f83bb6, 0x243434c6, 0xc1bc0ec9,
+ 0xe7833b20, 0x238e3536, 0xc13b0c7c, 0xe6113a82,
+ 0x22e635a5, 0xc0d10a2a, 0xe4a339da, 0x223d3612,
+ 0xc07c07d5, 0xe33a392a, 0x2192367c, 0xc03d057d,
+ 0xe1d53871, 0x20e736e5, 0xc0140323, 0xe07537af,
+ 0x2039374b, 0xc00200c9, 0xdf1936e5, 0x1f8b37af,
+ 0xc005fe6e, 0xddc33612, 0x1edc3811, 0xc01ffc14,
+ 0xdc723536, 0x1e2b3871, 0xc04ff9bb, 0xdb263453,
+ 0x1d7938cf, 0xc096f764, 0xd9e13367, 0x1cc6392a,
+ 0xc0f2f50f, 0xd8a13274, 0x1c123983, 0xc164f2bf,
+ 0xd7673179, 0x1b5d39da, 0xc1ecf074, 0xd6333076,
+ 0x1aa63a2f, 0xc289ee2d, 0xd5062f6b, 0x19ef3a82,
+ 0xc33bebed, 0xd3df2e5a, 0x19373ad2, 0xc403e9b4,
+ 0xd2bf2d41, 0x187d3b20, 0xc4e0e783, 0xd1a62c21,
+ 0x17c33b6c, 0xc5d1e55a, 0xd0952afa, 0x17083bb6,
+ 0xc6d6e33a, 0xcf8a29cd, 0x164c3bfd, 0xc7efe124,
+ 0xce872899, 0x158f3c42, 0xc91bdf19, 0xcd8c275f,
+ 0x14d13c84, 0xca5bdd1a, 0xcc99261f, 0x14133cc5,
+ 0xcbaddb26, 0xcbad24da, 0x13543d02, 0xcd12d940,
+ 0xcaca238e, 0x12943d3e, 0xce87d767, 0xc9ee223d,
+ 0x11d33d77, 0xd00fd59b, 0xc91b20e7, 0x11113dae,
+ 0xd1a6d3df, 0xc8511f8b, 0x104f3de2, 0xd34ed232,
+ 0xc78f1e2b, 0x0f8c3e14, 0xd506d095, 0xc6d61cc6,
+ 0x0ec93e44, 0xd6cccf08, 0xc6261b5d, 0x0e053e71,
+ 0xd8a1cd8c, 0xc57e19ef, 0x0d413e9c, 0xda83cc22,
+ 0xc4e0187d, 0x0c7c3ec5, 0xdc72caca, 0xc44a1708,
+ 0x0bb63eeb, 0xde6ec984, 0xc3be158f, 0x0af13f0e,
+ 0xe075c851, 0xc33b1413, 0x0a2a3f2f, 0xe287c731,
+ 0xc2c21294, 0x09643f4e, 0xe4a3c626, 0xc2521111,
+ 0x089c3f6a, 0xe6c9c52e, 0xc1ec0f8c, 0x07d53f84,
+ 0xe8f8c44a, 0xc18f0e05, 0x070d3f9c, 0xeb2fc37c,
+ 0xc13b0c7c, 0x06453fb1, 0xed6cc2c2, 0xc0f20af1,
+ 0x057d3fc3, 0xefb1c21e, 0xc0b20964, 0x04b53fd3,
+ 0xf1fbc18f, 0xc07c07d5, 0x03ec3fe1, 0xf44ac115,
+ 0xc04f0645, 0x03233fec, 0xf69cc0b2, 0xc02d04b5,
+ 0x025b3ff4, 0xf8f3c064, 0xc0140323, 0x01923ffb,
+ 0xfb4bc02d, 0xc0050192, 0x00c93ffe, 0xfda5c00c
};
const int twidTab64[(4*6 + 16*6)/2] = {
- 0x40000000, 0x40000000, 0x40000000, 0x2d412d41,
- 0x3b20187d, 0x187d3b20, 0x00004000, 0x2d412d41,
- 0xd2bf2d41, 0xd2bf2d41, 0x187d3b20, 0xc4e0e783,
+ 0x40000000, 0x40000000, 0x40000000, 0x2d412d41,
+ 0x3b20187d, 0x187d3b20, 0x00004000, 0x2d412d41,
+ 0xd2bf2d41, 0xd2bf2d41, 0x187d3b20, 0xc4e0e783,
- 0x40000000, 0x40000000, 0x40000000, 0x3ec50c7c,
- 0x3fb10645, 0x3d3e1294, 0x3b20187d, 0x3ec50c7c,
- 0x3536238e, 0x3536238e, 0x3d3e1294, 0x28993179,
- 0x2d412d41, 0x3b20187d, 0x187d3b20, 0x238e3536,
- 0x38711e2b, 0x06453fb1, 0x187d3b20, 0x3536238e,
- 0xf3843ec5, 0x0c7c3ec5, 0x31792899, 0xe1d53871,
- 0x00004000, 0x2d412d41, 0xd2bf2d41, 0xf3843ec5,
- 0x28993179, 0xc78f1e2b, 0xe7833b20, 0x238e3536,
- 0xc13b0c7c, 0xdc723536, 0x1e2b3871, 0xc04ff9bb,
- 0xd2bf2d41, 0x187d3b20, 0xc4e0e783, 0xcaca238e,
- 0x12943d3e, 0xce87d767, 0xc4e0187d, 0x0c7c3ec5,
- 0xdc72caca, 0xc13b0c7c, 0x06453fb1, 0xed6cc2c2
+ 0x40000000, 0x40000000, 0x40000000, 0x3ec50c7c,
+ 0x3fb10645, 0x3d3e1294, 0x3b20187d, 0x3ec50c7c,
+ 0x3536238e, 0x3536238e, 0x3d3e1294, 0x28993179,
+ 0x2d412d41, 0x3b20187d, 0x187d3b20, 0x238e3536,
+ 0x38711e2b, 0x06453fb1, 0x187d3b20, 0x3536238e,
+ 0xf3843ec5, 0x0c7c3ec5, 0x31792899, 0xe1d53871,
+ 0x00004000, 0x2d412d41, 0xd2bf2d41, 0xf3843ec5,
+ 0x28993179, 0xc78f1e2b, 0xe7833b20, 0x238e3536,
+ 0xc13b0c7c, 0xdc723536, 0x1e2b3871, 0xc04ff9bb,
+ 0xd2bf2d41, 0x187d3b20, 0xc4e0e783, 0xcaca238e,
+ 0x12943d3e, 0xce87d767, 0xc4e0187d, 0x0c7c3ec5,
+ 0xdc72caca, 0xc13b0c7c, 0x06453fb1, 0xed6cc2c2
};
#elif defined ARMV7Neon
-/*
- * Q29 for 128 and 1024
+/*
+ * Q29 for 128 and 1024
*
* for (i = 0; i < num/4; i++) {
* angle = (i + 0.125) * M_PI / num;
* x = cos(angle) * (1 << 29);
* x = sin(angle) * (1 << 29);
- *
+ *
* angle = (num/2 - 1 - i + 0.125) * M_PI / num;
* x = cos(angle) * (1 << 29);
* x = sin(angle) * (1 << 29);
@@ -353,313 +353,313 @@
*/
const int cossintab[128 + 1024] = {
/* 128 */
- 0x1ffff621, 0x001921f9, 0x00afea69, 0x1ffe1c68, 0x1ffce09d, 0x00e22a7a, 0x0178dbaa, 0x1ff753bb,
- 0x1ff4dc55, 0x01ab101c, 0x024192cf, 0x1feb9d25, 0x1fe7ea85, 0x0273b3e2, 0x0309f0e2, 0x1fdafa75,
- 0x1fd60d2e, 0x033bf6dd, 0x03d1d700, 0x1fc56e3b, 0x1fbf470f, 0x0403ba2b, 0x04992653, 0x1faafbcb,
- 0x1fa39bac, 0x04cadefe, 0x055fc022, 0x1f8ba738, 0x1f830f4a, 0x059146a1, 0x062585ca, 0x1f677557,
- 0x1f5da6ed, 0x0656d27a, 0x06ea58cd, 0x1f3e6bbc, 0x1f33685a, 0x071b6415, 0x07ae1ad2, 0x1f1090bd,
- 0x1f045a15, 0x07dedd20, 0x0870ada7, 0x1eddeb6a, 0x1ed0835f, 0x08a11f78, 0x0931f34d, 0x1ea68394,
- 0x1e97ec36, 0x09620d27, 0x09f1cdf5, 0x1e6a61c5, 0x1e5a9d55, 0x0a21886e, 0x0ab02009, 0x1e298f44,
- 0x1e18a030, 0x0adf73c6, 0x0b6ccc32, 0x1de4160f, 0x1dd1fef4, 0x0b9bb1e5, 0x0c27b555, 0x1d9a00de,
- 0x1d86c484, 0x0c5625c3, 0x0ce0bea2, 0x1d4b5b1b, 0x1d36fc7c, 0x0d0eb2a2, 0x0d97cb8f, 0x1cf830e9,
- 0x1ce2b328, 0x0dc53c0a, 0x0e4cbfe2, 0x1ca08f1a, 0x1c89f587, 0x0e79a5d7, 0x0eff7fb3, 0x1c448331,
- 0x1c2cd149, 0x0f2bd437, 0x0fafef73, 0x1be41b61, 0x1bcb54cb, 0x0fdbabae, 0x105df3ec, 0x1b7f6687,
- 0x1b658f15, 0x10891120, 0x11097249, 0x1b16742a, 0x1afb8fd9, 0x1133e9d0, 0x11b25017, 0x1aa9547a,
- 0x1a8d676e, 0x11dc1b65, 0x1258734d, 0x1a38184a, 0x1a1b26d3, 0x12818bef, 0x12fbc24b, 0x19c2d111,
- 0x19a4dfa4, 0x132421ec, 0x139c23e4, 0x194990e4, 0x192aa420, 0x13c3c44a, 0x14397f5b, 0x18cc6a75,
- 0x18ac871f, 0x14605a69, 0x14d3bc6d, 0x184b7112, 0x182a9c14, 0x14f9cc26, 0x156ac352, 0x17c6b89d,
+ 0x1ffff621, 0x001921f9, 0x00afea69, 0x1ffe1c68, 0x1ffce09d, 0x00e22a7a, 0x0178dbaa, 0x1ff753bb,
+ 0x1ff4dc55, 0x01ab101c, 0x024192cf, 0x1feb9d25, 0x1fe7ea85, 0x0273b3e2, 0x0309f0e2, 0x1fdafa75,
+ 0x1fd60d2e, 0x033bf6dd, 0x03d1d700, 0x1fc56e3b, 0x1fbf470f, 0x0403ba2b, 0x04992653, 0x1faafbcb,
+ 0x1fa39bac, 0x04cadefe, 0x055fc022, 0x1f8ba738, 0x1f830f4a, 0x059146a1, 0x062585ca, 0x1f677557,
+ 0x1f5da6ed, 0x0656d27a, 0x06ea58cd, 0x1f3e6bbc, 0x1f33685a, 0x071b6415, 0x07ae1ad2, 0x1f1090bd,
+ 0x1f045a15, 0x07dedd20, 0x0870ada7, 0x1eddeb6a, 0x1ed0835f, 0x08a11f78, 0x0931f34d, 0x1ea68394,
+ 0x1e97ec36, 0x09620d27, 0x09f1cdf5, 0x1e6a61c5, 0x1e5a9d55, 0x0a21886e, 0x0ab02009, 0x1e298f44,
+ 0x1e18a030, 0x0adf73c6, 0x0b6ccc32, 0x1de4160f, 0x1dd1fef4, 0x0b9bb1e5, 0x0c27b555, 0x1d9a00de,
+ 0x1d86c484, 0x0c5625c3, 0x0ce0bea2, 0x1d4b5b1b, 0x1d36fc7c, 0x0d0eb2a2, 0x0d97cb8f, 0x1cf830e9,
+ 0x1ce2b328, 0x0dc53c0a, 0x0e4cbfe2, 0x1ca08f1a, 0x1c89f587, 0x0e79a5d7, 0x0eff7fb3, 0x1c448331,
+ 0x1c2cd149, 0x0f2bd437, 0x0fafef73, 0x1be41b61, 0x1bcb54cb, 0x0fdbabae, 0x105df3ec, 0x1b7f6687,
+ 0x1b658f15, 0x10891120, 0x11097249, 0x1b16742a, 0x1afb8fd9, 0x1133e9d0, 0x11b25017, 0x1aa9547a,
+ 0x1a8d676e, 0x11dc1b65, 0x1258734d, 0x1a38184a, 0x1a1b26d3, 0x12818bef, 0x12fbc24b, 0x19c2d111,
+ 0x19a4dfa4, 0x132421ec, 0x139c23e4, 0x194990e4, 0x192aa420, 0x13c3c44a, 0x14397f5b, 0x18cc6a75,
+ 0x18ac871f, 0x14605a69, 0x14d3bc6d, 0x184b7112, 0x182a9c14, 0x14f9cc26, 0x156ac352, 0x17c6b89d,
0x17a4f708, 0x159001d6, 0x15fe7cbe, 0x173e558e, 0x171bac96, 0x1622e450, 0x168ed1eb, 0x16b25ced,
/* 1024 */
- 0x1fffffd9, 0x0003243f, 0x0015fdba, 0x1ffff872, 0x1ffff382, 0x001c4637, 0x002f1fa6, 0x1fffdd4d,
- 0x1fffd36f, 0x0035681d, 0x00484175, 0x1fffae6c, 0x1fff9f9e, 0x004e89e3, 0x00616318, 0x1fff6bce,
- 0x1fff5811, 0x0067ab77, 0x007a847e, 0x1fff1572, 0x1ffefcc6, 0x0080cccc, 0x0093a599, 0x1ffeab5b,
- 0x1ffe8dbf, 0x0099edd2, 0x00acc658, 0x1ffe2d86, 0x1ffe0afc, 0x00b30e78, 0x00c5e6ad, 0x1ffd9bf6,
- 0x1ffd747c, 0x00cc2eb0, 0x00df0688, 0x1ffcf6aa, 0x1ffcca41, 0x00e54e6a, 0x00f825da, 0x1ffc3da2,
- 0x1ffc0c4b, 0x00fe6d97, 0x01114492, 0x1ffb70e0, 0x1ffb3a9a, 0x01178c27, 0x012a62a2, 0x1ffa9063,
- 0x1ffa552e, 0x0130aa0a, 0x01437ffa, 0x1ff99c2c, 0x1ff95c09, 0x0149c731, 0x015c9c8a, 0x1ff8943c,
- 0x1ff84f2b, 0x0162e38d, 0x0175b843, 0x1ff77893, 0x1ff72e94, 0x017bff0e, 0x018ed316, 0x1ff64932,
- 0x1ff5fa46, 0x019519a5, 0x01a7ecf2, 0x1ff5061b, 0x1ff4b240, 0x01ae3341, 0x01c105c9, 0x1ff3af4c,
- 0x1ff35684, 0x01c74bd5, 0x01da1d8c, 0x1ff244c8, 0x1ff1e713, 0x01e0634f, 0x01f33429, 0x1ff0c68f,
- 0x1ff063ed, 0x01f979a1, 0x020c4993, 0x1fef34a3, 0x1feecd14, 0x02128ebb, 0x02255db9, 0x1fed8f03,
- 0x1fed2287, 0x022ba28f, 0x023e708d, 0x1febd5b2, 0x1feb644a, 0x0244b50b, 0x025781fe, 0x1fea08b0,
- 0x1fe9925c, 0x025dc621, 0x027091fd, 0x1fe827fe, 0x1fe7acbe, 0x0276d5c1, 0x0289a07b, 0x1fe6339d,
- 0x1fe5b372, 0x028fe3dd, 0x02a2ad69, 0x1fe42b90, 0x1fe3a679, 0x02a8f063, 0x02bbb8b6, 0x1fe20fd6,
- 0x1fe185d5, 0x02c1fb46, 0x02d4c253, 0x1fdfe071, 0x1fdf5186, 0x02db0475, 0x02edca32, 0x1fdd9d64,
- 0x1fdd098e, 0x02f40be2, 0x0306d042, 0x1fdb46ae, 0x1fdaadee, 0x030d117c, 0x031fd474, 0x1fd8dc51,
- 0x1fd83ea8, 0x03261534, 0x0338d6b8, 0x1fd65e4f, 0x1fd5bbbd, 0x033f16fb, 0x0351d700, 0x1fd3ccaa,
- 0x1fd32530, 0x035816c1, 0x036ad53c, 0x1fd12763, 0x1fd07b00, 0x03711477, 0x0383d15c, 0x1fce6e7c,
- 0x1fcdbd31, 0x038a100e, 0x039ccb51, 0x1fcba1f5, 0x1fcaebc3, 0x03a30975, 0x03b5c30b, 0x1fc8c1d2,
- 0x1fc806b9, 0x03bc009f, 0x03ceb87c, 0x1fc5ce14, 0x1fc50e14, 0x03d4f57a, 0x03e7ab93, 0x1fc2c6bd,
- 0x1fc201d7, 0x03ede7f9, 0x04009c42, 0x1fbfabcd, 0x1fbee202, 0x0406d80b, 0x04198a78, 0x1fbc7d49,
- 0x1fbbae99, 0x041fc5a1, 0x04327628, 0x1fb93b31, 0x1fb8679c, 0x0438b0ac, 0x044b5f40, 0x1fb5e587,
- 0x1fb50d0e, 0x0451991d, 0x046445b2, 0x1fb27c4e, 0x1fb19ef1, 0x046a7ee3, 0x047d296f, 0x1faeff87,
- 0x1fae1d47, 0x048361f0, 0x04960a67, 0x1fab6f35, 0x1faa8813, 0x049c4235, 0x04aee88b, 0x1fa7cb5a,
- 0x1fa6df56, 0x04b51fa1, 0x04c7c3cb, 0x1fa413f8, 0x1fa32313, 0x04cdfa26, 0x04e09c18, 0x1fa04912,
- 0x1f9f534c, 0x04e6d1b4, 0x04f97163, 0x1f9c6aa9, 0x1f9b7003, 0x04ffa63c, 0x0512439d, 0x1f9878c1,
- 0x1f97793b, 0x051877af, 0x052b12b6, 0x1f94735b, 0x1f936ef6, 0x053145fd, 0x0543de9e, 0x1f905a7a,
- 0x1f8f5137, 0x054a1117, 0x055ca748, 0x1f8c2e21, 0x1f8b2000, 0x0562d8ee, 0x05756ca2, 0x1f87ee52,
- 0x1f86db55, 0x057b9d73, 0x058e2e9f, 0x1f839b10, 0x1f828336, 0x05945e95, 0x05a6ed2e, 0x1f7f345e,
- 0x1f7e17a8, 0x05ad1c47, 0x05bfa840, 0x1f7aba3e, 0x1f7998ad, 0x05c5d678, 0x05d85fc7, 0x1f762cb2,
- 0x1f750647, 0x05de8d19, 0x05f113b3, 0x1f718bbf, 0x1f70607a, 0x05f7401c, 0x0609c3f5, 0x1f6cd766,
- 0x1f6ba748, 0x060fef71, 0x0622707d, 0x1f680fab, 0x1f66dab5, 0x06289b08, 0x063b193c, 0x1f633490,
- 0x1f61fac3, 0x064142d3, 0x0653be23, 0x1f5e4619, 0x1f5d0775, 0x0659e6c2, 0x066c5f24, 0x1f594448,
- 0x1f5800ce, 0x067286c6, 0x0684fc2e, 0x1f542f21, 0x1f52e6d2, 0x068b22d0, 0x069d9532, 0x1f4f06a6,
- 0x1f4db983, 0x06a3bad0, 0x06b62a22, 0x1f49cadc, 0x1f4878e5, 0x06bc4eb9, 0x06cebaee, 0x1f447bc4,
- 0x1f4324fb, 0x06d4de79, 0x06e74786, 0x1f3f1963, 0x1f3dbdc8, 0x06ed6a03, 0x06ffcfdd, 0x1f39a3bc,
- 0x1f384350, 0x0705f147, 0x071853e3, 0x1f341ad2, 0x1f32b595, 0x071e7436, 0x0730d388, 0x1f2e7ea9,
- 0x1f2d149d, 0x0736f2c0, 0x07494ebd, 0x1f28cf43, 0x1f276069, 0x074f6cd7, 0x0761c574, 0x1f230ca5,
- 0x1f2198fd, 0x0767e26c, 0x077a379d, 0x1f1d36d2, 0x1f1bbe5d, 0x07805370, 0x0792a52a, 0x1f174dce,
- 0x1f15d08d, 0x0798bfd3, 0x07ab0e0a, 0x1f11519c, 0x1f0fcf91, 0x07b12786, 0x07c37230, 0x1f0b4240,
- 0x1f09bb6b, 0x07c98a7a, 0x07dbd18c, 0x1f051fbe, 0x1f03941f, 0x07e1e8a1, 0x07f42c0e, 0x1efeea19,
- 0x1efd59b3, 0x07fa41eb, 0x080c81a9, 0x1ef8a155, 0x1ef70c28, 0x0812964a, 0x0824d24d, 0x1ef24577,
- 0x1ef0ab84, 0x082ae5ad, 0x083d1dea, 0x1eebd682, 0x1eea37ca, 0x08433007, 0x08556473, 0x1ee5547a,
- 0x1ee3b0fe, 0x085b7548, 0x086da5d8, 0x1edebf64, 0x1edd1724, 0x0873b562, 0x0885e209, 0x1ed81742,
- 0x1ed66a41, 0x088bf044, 0x089e18f9, 0x1ed15c1a, 0x1ecfaa57, 0x08a425e1, 0x08b64a98, 0x1eca8def,
- 0x1ec8d76c, 0x08bc562a, 0x08ce76d8, 0x1ec3acc6, 0x1ec1f184, 0x08d4810f, 0x08e69da8, 0x1ebcb8a3,
- 0x1ebaf8a3, 0x08eca681, 0x08febefb, 0x1eb5b18a, 0x1eb3eccd, 0x0904c673, 0x0916dac2, 0x1eae977f,
- 0x1eacce07, 0x091ce0d4, 0x092ef0ed, 0x1ea76a87, 0x1ea59c55, 0x0934f596, 0x0947016e, 0x1ea02aa7,
- 0x1e9e57bb, 0x094d04aa, 0x095f0c36, 0x1e98d7e2, 0x1e97003e, 0x09650e01, 0x09771136, 0x1e91723e,
- 0x1e8f95e3, 0x097d118d, 0x098f1060, 0x1e89f9bf, 0x1e8818ad, 0x09950f3f, 0x09a709a4, 0x1e826e69,
- 0x1e8088a2, 0x09ad0707, 0x09befcf4, 0x1e7ad041, 0x1e78e5c7, 0x09c4f8d8, 0x09d6ea40, 0x1e731f4c,
- 0x1e71301f, 0x09dce4a1, 0x09eed17b, 0x1e6b5b8f, 0x1e6967b1, 0x09f4ca56, 0x0a06b296, 0x1e63850e,
- 0x1e618c80, 0x0a0ca9e6, 0x0a1e8d81, 0x1e5b9bce, 0x1e599e91, 0x0a248343, 0x0a36622e, 0x1e539fd4,
- 0x1e519dea, 0x0a3c565e, 0x0a4e308f, 0x1e4b9126, 0x1e498a8e, 0x0a542329, 0x0a65f894, 0x1e436fc7,
- 0x1e416485, 0x0a6be995, 0x0a7dba2f, 0x1e3b3bbd, 0x1e392bd1, 0x0a83a993, 0x0a957551, 0x1e32f50e,
- 0x1e30e079, 0x0a9b6315, 0x0aad29ec, 0x1e2a9bbd, 0x1e288281, 0x0ab3160c, 0x0ac4d7f1, 0x1e222fd1,
- 0x1e2011ee, 0x0acac26a, 0x0adc7f52, 0x1e19b14f, 0x1e178ec7, 0x0ae2681f, 0x0af41fff, 0x1e11203b,
- 0x1e0ef910, 0x0afa071d, 0x0b0bb9eb, 0x1e087c9b, 0x1e0650ce, 0x0b119f56, 0x0b234d07, 0x1dffc674,
- 0x1dfd9606, 0x0b2930bb, 0x0b3ad943, 0x1df6fdcc, 0x1df4c8bf, 0x0b40bb3e, 0x0b525e92, 0x1dee22a9,
- 0x1debe8fd, 0x0b583ecf, 0x0b69dce6, 0x1de5350f, 0x1de2f6c6, 0x0b6fbb62, 0x0b81542f, 0x1ddc3504,
- 0x1dd9f220, 0x0b8730e6, 0x0b98c45f, 0x1dd3228e, 0x1dd0db10, 0x0b9e9f4d, 0x0bb02d68, 0x1dc9fdb2,
- 0x1dc7b19b, 0x0bb6068a, 0x0bc78f3b, 0x1dc0c676, 0x1dbe75c8, 0x0bcd668e, 0x0bdee9ca, 0x1db77cdf,
- 0x1db5279c, 0x0be4bf4a, 0x0bf63d07, 0x1dae20f4, 0x1dabc71d, 0x0bfc10af, 0x0c0d88e2, 0x1da4b2ba,
- 0x1da25450, 0x0c135ab0, 0x0c24cd4e, 0x1d9b3237, 0x1d98cf3b, 0x0c2a9d3e, 0x0c3c0a3d, 0x1d919f70,
- 0x1d8f37e5, 0x0c41d84b, 0x0c533fa0, 0x1d87fa6d, 0x1d858e53, 0x0c590bc9, 0x0c6a6d68, 0x1d7e4332,
- 0x1d7bd28b, 0x0c7037a8, 0x0c819388, 0x1d7479c5, 0x1d720493, 0x0c875bdb, 0x0c98b1f0, 0x1d6a9e2e,
- 0x1d682472, 0x0c9e7854, 0x0cafc894, 0x1d60b070, 0x1d5e322c, 0x0cb58d04, 0x0cc6d764, 0x1d56b094,
- 0x1d542dc9, 0x0ccc99de, 0x0cddde53, 0x1d4c9e9f, 0x1d4a174f, 0x0ce39ed2, 0x0cf4dd52, 0x1d427a97,
- 0x1d3feec3, 0x0cfa9bd2, 0x0d0bd452, 0x1d384483, 0x1d35b42d, 0x0d1190d1, 0x0d22c347, 0x1d2dfc68,
- 0x1d2b6791, 0x0d287dc1, 0x0d39aa21, 0x1d23a24e, 0x1d2108f8, 0x0d3f6292, 0x0d5088d3, 0x1d19363a,
- 0x1d169867, 0x0d563f38, 0x0d675f4e, 0x1d0eb833, 0x1d0c15e4, 0x0d6d13a3, 0x0d7e2d85, 0x1d04283f,
- 0x1d018176, 0x0d83dfc6, 0x0d94f369, 0x1cf98666, 0x1cf6db24, 0x0d9aa393, 0x0dabb0ec, 0x1ceed2ad,
- 0x1cec22f4, 0x0db15efc, 0x0dc26600, 0x1ce40d1b, 0x1ce158ed, 0x0dc811f3, 0x0dd91298, 0x1cd935b7,
- 0x1cd67d15, 0x0ddebc69, 0x0defb6a5, 0x1cce4c87, 0x1ccb8f74, 0x0df55e51, 0x0e065219, 0x1cc35192,
- 0x1cc0900f, 0x0e0bf79c, 0x0e1ce4e6, 0x1cb844df, 0x1cb57eee, 0x0e22883e, 0x0e336eff, 0x1cad2675,
- 0x1caa5c17, 0x0e391027, 0x0e49f055, 0x1ca1f65b, 0x1c9f2792, 0x0e4f8f4b, 0x0e6068db, 0x1c96b497,
- 0x1c93e165, 0x0e66059a, 0x0e76d883, 0x1c8b6131, 0x1c888997, 0x0e7c7308, 0x0e8d3f3e, 0x1c7ffc2f,
- 0x1c7d202f, 0x0e92d787, 0x0ea39d00, 0x1c748599, 0x1c71a535, 0x0ea93308, 0x0eb9f1ba, 0x1c68fd75,
- 0x1c6618ae, 0x0ebf857d, 0x0ed03d5e, 0x1c5d63ca, 0x1c5a7aa4, 0x0ed5ceda, 0x0ee67fdf, 0x1c51b8a1,
- 0x1c4ecb1c, 0x0eec0f10, 0x0efcb92f, 0x1c45fc00, 0x1c430a1d, 0x0f024612, 0x0f12e941, 0x1c3a2ded,
- 0x1c3737b0, 0x0f1873d2, 0x0f291006, 0x1c2e4e72, 0x1c2b53db, 0x0f2e9842, 0x0f3f2d71, 0x1c225d94,
- 0x1c1f5ea6, 0x0f44b354, 0x0f554175, 0x1c165b5b, 0x1c135818, 0x0f5ac4fc, 0x0f6b4c03, 0x1c0a47cf,
- 0x1c074038, 0x0f70cd2a, 0x0f814d0e, 0x1bfe22f8, 0x1bfb170f, 0x0f86cbd3, 0x0f974489, 0x1bf1ecdb,
- 0x1beedca2, 0x0f9cc0e7, 0x0fad3265, 0x1be5a582, 0x1be290fb, 0x0fb2ac5a, 0x0fc31697, 0x1bd94cf4,
- 0x1bd63421, 0x0fc88e1e, 0x0fd8f10f, 0x1bcce337, 0x1bc9c61a, 0x0fde6626, 0x0feec1c0, 0x1bc06855,
- 0x1bbd46f0, 0x0ff43464, 0x1004889e, 0x1bb3dc55, 0x1bb0b6a9, 0x1009f8cb, 0x101a459a, 0x1ba73f3d,
- 0x1ba4154d, 0x101fb34d, 0x102ff8a8, 0x1b9a9117, 0x1b9762e4, 0x103563dc, 0x1045a1b9, 0x1b8dd1ea,
- 0x1b8a9f77, 0x104b0a6c, 0x105b40c1, 0x1b8101be, 0x1b7dcb0c, 0x1060a6ef, 0x1070d5b1, 0x1b74209b,
- 0x1b70e5ac, 0x10763958, 0x1086607e, 0x1b672e88, 0x1b63ef5f, 0x108bc19a, 0x109be119, 0x1b5a2b8e,
- 0x1b56e82c, 0x10a13fa6, 0x10b15775, 0x1b4d17b4, 0x1b49d01c, 0x10b6b371, 0x10c6c385, 0x1b3ff304,
- 0x1b3ca737, 0x10cc1cec, 0x10dc253c, 0x1b32bd84, 0x1b2f6d85, 0x10e17c0b, 0x10f17c8d, 0x1b25773d,
- 0x1b22230e, 0x10f6d0c0, 0x1106c96a, 0x1b182038, 0x1b14c7da, 0x110c1afe, 0x111c0bc6, 0x1b0ab87c,
- 0x1b075bf1, 0x11215ab8, 0x11314395, 0x1afd4012, 0x1af9df5d, 0x11368fe1, 0x114670c8, 0x1aefb702,
- 0x1aec5225, 0x114bba6b, 0x115b9354, 0x1ae21d54, 0x1adeb451, 0x1160da4b, 0x1170ab2a, 0x1ad47311,
- 0x1ad105e9, 0x1175ef72, 0x1185b83f, 0x1ac6b841, 0x1ac346f8, 0x118af9d4, 0x119aba84, 0x1ab8ecec,
- 0x1ab57784, 0x119ff964, 0x11afb1ee, 0x1aab111c, 0x1aa79796, 0x11b4ee14, 0x11c49e6f, 0x1a9d24d9,
- 0x1a99a737, 0x11c9d7d9, 0x11d97ff9, 0x1a8f282b, 0x1a8ba670, 0x11deb6a4, 0x11ee5682, 0x1a811b1b,
- 0x1a7d9549, 0x11f38a6a, 0x120321fa, 0x1a72fdb2, 0x1a6f73ca, 0x1208531c, 0x1217e256, 0x1a64cff8,
- 0x1a6141fd, 0x121d10af, 0x122c9789, 0x1a5691f5, 0x1a52ffeb, 0x1231c316, 0x12414186, 0x1a4843b4,
- 0x1a44ad9b, 0x12466a44, 0x1255e041, 0x1a39e53d, 0x1a364b17, 0x125b062b, 0x126a73ac, 0x1a2b7698,
- 0x1a27d868, 0x126f96c1, 0x127efbbb, 0x1a1cf7ce, 0x1a195597, 0x12841bf6, 0x12937861, 0x1a0e68e9,
- 0x1a0ac2ac, 0x129895c0, 0x12a7e991, 0x19ffc9f1, 0x19fc1fb1, 0x12ad0412, 0x12bc4f40, 0x19f11af0,
- 0x19ed6caf, 0x12c166de, 0x12d0a960, 0x19e25bee, 0x19dea9ae, 0x12d5be18, 0x12e4f7e5, 0x19d38cf4,
- 0x19cfd6b8, 0x12ea09b4, 0x12f93ac2, 0x19c4ae0c, 0x19c0f3d6, 0x12fe49a6, 0x130d71eb, 0x19b5bf3f,
- 0x19b20111, 0x13127de0, 0x13219d53, 0x19a6c096, 0x19a2fe73, 0x1326a656, 0x1335bcef, 0x1997b21b,
- 0x1993ec04, 0x133ac2fc, 0x1349d0b0, 0x198893d6, 0x1984c9ce, 0x134ed3c5, 0x135dd88c, 0x197965d0,
- 0x197597da, 0x1362d8a6, 0x1371d476, 0x196a2815, 0x19665632, 0x1376d191, 0x1385c461, 0x195adaab,
- 0x195704df, 0x138abe7b, 0x1399a841, 0x194b7d9e, 0x1947a3eb, 0x139e9f56, 0x13ad800a, 0x193c10f7,
- 0x1938335e, 0x13b27417, 0x13c14bb0, 0x192c94bf, 0x1928b343, 0x13c63cb2, 0x13d50b26, 0x191d08ff,
- 0x191923a3, 0x13d9f91b, 0x13e8be60, 0x190d6dc1, 0x19098488, 0x13eda944, 0x13fc6553, 0x18fdc310,
- 0x18f9d5fa, 0x14014d23, 0x140ffff1, 0x18ee08f4, 0x18ea1805, 0x1414e4aa, 0x14238e2f, 0x18de3f77,
- 0x18da4ab2, 0x14286fce, 0x14371001, 0x18ce66a3, 0x18ca6e0a, 0x143bee83, 0x144a855b, 0x18be7e82,
- 0x18ba8217, 0x144f60bd, 0x145dee30, 0x18ae871e, 0x18aa86e3, 0x1462c670, 0x14714a76, 0x189e8080,
- 0x189a7c78, 0x14761f8f, 0x14849a1f, 0x188e6ab2, 0x188a62e0, 0x14896c0f, 0x1497dd20, 0x187e45be,
- 0x187a3a25, 0x149cabe4, 0x14ab136d, 0x186e11af, 0x186a0250, 0x14afdf03, 0x14be3cfa, 0x185dce8e,
- 0x1859bb6c, 0x14c3055e, 0x14d159bc, 0x184d7c65, 0x18496583, 0x14d61eeb, 0x14e469a6, 0x183d1b3e,
- 0x1839009e, 0x14e92b9e, 0x14f76cad, 0x182cab24, 0x18288cc8, 0x14fc2b6a, 0x150a62c6, 0x181c2c20,
- 0x18180a0c, 0x150f1e45, 0x151d4be3, 0x180b9e3d, 0x18077873, 0x15220422, 0x153027fb, 0x17fb0185,
- 0x17f6d807, 0x1534dcf6, 0x1542f700, 0x17ea5602, 0x17e628d3, 0x1547a8b5, 0x1555b8e8, 0x17d99bbe,
- 0x17d56ae0, 0x155a6754, 0x15686da7, 0x17c8d2c4, 0x17c49e3b, 0x156d18c7, 0x157b1532, 0x17b7fb1f,
- 0x17b3c2ec, 0x157fbd03, 0x158daf7c, 0x17a714d7, 0x17a2d8fe, 0x159253fb, 0x15a03c7a, 0x17961ff9,
- 0x1791e07b, 0x15a4dda5, 0x15b2bc22, 0x17851c8e, 0x1780d96f, 0x15b759f5, 0x15c52e67, 0x17740aa1,
- 0x176fc3e3, 0x15c9c8e0, 0x15d7933f, 0x1762ea3d, 0x175e9fe2, 0x15dc2a5a, 0x15e9ea9d, 0x1751bb6b,
- 0x174d6d77, 0x15ee7e58, 0x15fc3477, 0x17407e37, 0x173c2cac, 0x1600c4cf, 0x160e70c1, 0x172f32ab,
- 0x172add8c, 0x1612fdb3, 0x16209f70, 0x171dd8d2, 0x17198021, 0x162528fa, 0x1632c078, 0x170c70b7,
- 0x17081477, 0x16374697, 0x1644d3d0, 0x16fafa64, 0x16f69a97, 0x16495680, 0x1656d96a, 0x16e975e4,
- 0x16e5128e, 0x165b58aa, 0x1668d13e, 0x16d7e341, 0x16d37c65, 0x166d4d0a, 0x167abb3e, 0x16c64288,
+ 0x1fffffd9, 0x0003243f, 0x0015fdba, 0x1ffff872, 0x1ffff382, 0x001c4637, 0x002f1fa6, 0x1fffdd4d,
+ 0x1fffd36f, 0x0035681d, 0x00484175, 0x1fffae6c, 0x1fff9f9e, 0x004e89e3, 0x00616318, 0x1fff6bce,
+ 0x1fff5811, 0x0067ab77, 0x007a847e, 0x1fff1572, 0x1ffefcc6, 0x0080cccc, 0x0093a599, 0x1ffeab5b,
+ 0x1ffe8dbf, 0x0099edd2, 0x00acc658, 0x1ffe2d86, 0x1ffe0afc, 0x00b30e78, 0x00c5e6ad, 0x1ffd9bf6,
+ 0x1ffd747c, 0x00cc2eb0, 0x00df0688, 0x1ffcf6aa, 0x1ffcca41, 0x00e54e6a, 0x00f825da, 0x1ffc3da2,
+ 0x1ffc0c4b, 0x00fe6d97, 0x01114492, 0x1ffb70e0, 0x1ffb3a9a, 0x01178c27, 0x012a62a2, 0x1ffa9063,
+ 0x1ffa552e, 0x0130aa0a, 0x01437ffa, 0x1ff99c2c, 0x1ff95c09, 0x0149c731, 0x015c9c8a, 0x1ff8943c,
+ 0x1ff84f2b, 0x0162e38d, 0x0175b843, 0x1ff77893, 0x1ff72e94, 0x017bff0e, 0x018ed316, 0x1ff64932,
+ 0x1ff5fa46, 0x019519a5, 0x01a7ecf2, 0x1ff5061b, 0x1ff4b240, 0x01ae3341, 0x01c105c9, 0x1ff3af4c,
+ 0x1ff35684, 0x01c74bd5, 0x01da1d8c, 0x1ff244c8, 0x1ff1e713, 0x01e0634f, 0x01f33429, 0x1ff0c68f,
+ 0x1ff063ed, 0x01f979a1, 0x020c4993, 0x1fef34a3, 0x1feecd14, 0x02128ebb, 0x02255db9, 0x1fed8f03,
+ 0x1fed2287, 0x022ba28f, 0x023e708d, 0x1febd5b2, 0x1feb644a, 0x0244b50b, 0x025781fe, 0x1fea08b0,
+ 0x1fe9925c, 0x025dc621, 0x027091fd, 0x1fe827fe, 0x1fe7acbe, 0x0276d5c1, 0x0289a07b, 0x1fe6339d,
+ 0x1fe5b372, 0x028fe3dd, 0x02a2ad69, 0x1fe42b90, 0x1fe3a679, 0x02a8f063, 0x02bbb8b6, 0x1fe20fd6,
+ 0x1fe185d5, 0x02c1fb46, 0x02d4c253, 0x1fdfe071, 0x1fdf5186, 0x02db0475, 0x02edca32, 0x1fdd9d64,
+ 0x1fdd098e, 0x02f40be2, 0x0306d042, 0x1fdb46ae, 0x1fdaadee, 0x030d117c, 0x031fd474, 0x1fd8dc51,
+ 0x1fd83ea8, 0x03261534, 0x0338d6b8, 0x1fd65e4f, 0x1fd5bbbd, 0x033f16fb, 0x0351d700, 0x1fd3ccaa,
+ 0x1fd32530, 0x035816c1, 0x036ad53c, 0x1fd12763, 0x1fd07b00, 0x03711477, 0x0383d15c, 0x1fce6e7c,
+ 0x1fcdbd31, 0x038a100e, 0x039ccb51, 0x1fcba1f5, 0x1fcaebc3, 0x03a30975, 0x03b5c30b, 0x1fc8c1d2,
+ 0x1fc806b9, 0x03bc009f, 0x03ceb87c, 0x1fc5ce14, 0x1fc50e14, 0x03d4f57a, 0x03e7ab93, 0x1fc2c6bd,
+ 0x1fc201d7, 0x03ede7f9, 0x04009c42, 0x1fbfabcd, 0x1fbee202, 0x0406d80b, 0x04198a78, 0x1fbc7d49,
+ 0x1fbbae99, 0x041fc5a1, 0x04327628, 0x1fb93b31, 0x1fb8679c, 0x0438b0ac, 0x044b5f40, 0x1fb5e587,
+ 0x1fb50d0e, 0x0451991d, 0x046445b2, 0x1fb27c4e, 0x1fb19ef1, 0x046a7ee3, 0x047d296f, 0x1faeff87,
+ 0x1fae1d47, 0x048361f0, 0x04960a67, 0x1fab6f35, 0x1faa8813, 0x049c4235, 0x04aee88b, 0x1fa7cb5a,
+ 0x1fa6df56, 0x04b51fa1, 0x04c7c3cb, 0x1fa413f8, 0x1fa32313, 0x04cdfa26, 0x04e09c18, 0x1fa04912,
+ 0x1f9f534c, 0x04e6d1b4, 0x04f97163, 0x1f9c6aa9, 0x1f9b7003, 0x04ffa63c, 0x0512439d, 0x1f9878c1,
+ 0x1f97793b, 0x051877af, 0x052b12b6, 0x1f94735b, 0x1f936ef6, 0x053145fd, 0x0543de9e, 0x1f905a7a,
+ 0x1f8f5137, 0x054a1117, 0x055ca748, 0x1f8c2e21, 0x1f8b2000, 0x0562d8ee, 0x05756ca2, 0x1f87ee52,
+ 0x1f86db55, 0x057b9d73, 0x058e2e9f, 0x1f839b10, 0x1f828336, 0x05945e95, 0x05a6ed2e, 0x1f7f345e,
+ 0x1f7e17a8, 0x05ad1c47, 0x05bfa840, 0x1f7aba3e, 0x1f7998ad, 0x05c5d678, 0x05d85fc7, 0x1f762cb2,
+ 0x1f750647, 0x05de8d19, 0x05f113b3, 0x1f718bbf, 0x1f70607a, 0x05f7401c, 0x0609c3f5, 0x1f6cd766,
+ 0x1f6ba748, 0x060fef71, 0x0622707d, 0x1f680fab, 0x1f66dab5, 0x06289b08, 0x063b193c, 0x1f633490,
+ 0x1f61fac3, 0x064142d3, 0x0653be23, 0x1f5e4619, 0x1f5d0775, 0x0659e6c2, 0x066c5f24, 0x1f594448,
+ 0x1f5800ce, 0x067286c6, 0x0684fc2e, 0x1f542f21, 0x1f52e6d2, 0x068b22d0, 0x069d9532, 0x1f4f06a6,
+ 0x1f4db983, 0x06a3bad0, 0x06b62a22, 0x1f49cadc, 0x1f4878e5, 0x06bc4eb9, 0x06cebaee, 0x1f447bc4,
+ 0x1f4324fb, 0x06d4de79, 0x06e74786, 0x1f3f1963, 0x1f3dbdc8, 0x06ed6a03, 0x06ffcfdd, 0x1f39a3bc,
+ 0x1f384350, 0x0705f147, 0x071853e3, 0x1f341ad2, 0x1f32b595, 0x071e7436, 0x0730d388, 0x1f2e7ea9,
+ 0x1f2d149d, 0x0736f2c0, 0x07494ebd, 0x1f28cf43, 0x1f276069, 0x074f6cd7, 0x0761c574, 0x1f230ca5,
+ 0x1f2198fd, 0x0767e26c, 0x077a379d, 0x1f1d36d2, 0x1f1bbe5d, 0x07805370, 0x0792a52a, 0x1f174dce,
+ 0x1f15d08d, 0x0798bfd3, 0x07ab0e0a, 0x1f11519c, 0x1f0fcf91, 0x07b12786, 0x07c37230, 0x1f0b4240,
+ 0x1f09bb6b, 0x07c98a7a, 0x07dbd18c, 0x1f051fbe, 0x1f03941f, 0x07e1e8a1, 0x07f42c0e, 0x1efeea19,
+ 0x1efd59b3, 0x07fa41eb, 0x080c81a9, 0x1ef8a155, 0x1ef70c28, 0x0812964a, 0x0824d24d, 0x1ef24577,
+ 0x1ef0ab84, 0x082ae5ad, 0x083d1dea, 0x1eebd682, 0x1eea37ca, 0x08433007, 0x08556473, 0x1ee5547a,
+ 0x1ee3b0fe, 0x085b7548, 0x086da5d8, 0x1edebf64, 0x1edd1724, 0x0873b562, 0x0885e209, 0x1ed81742,
+ 0x1ed66a41, 0x088bf044, 0x089e18f9, 0x1ed15c1a, 0x1ecfaa57, 0x08a425e1, 0x08b64a98, 0x1eca8def,
+ 0x1ec8d76c, 0x08bc562a, 0x08ce76d8, 0x1ec3acc6, 0x1ec1f184, 0x08d4810f, 0x08e69da8, 0x1ebcb8a3,
+ 0x1ebaf8a3, 0x08eca681, 0x08febefb, 0x1eb5b18a, 0x1eb3eccd, 0x0904c673, 0x0916dac2, 0x1eae977f,
+ 0x1eacce07, 0x091ce0d4, 0x092ef0ed, 0x1ea76a87, 0x1ea59c55, 0x0934f596, 0x0947016e, 0x1ea02aa7,
+ 0x1e9e57bb, 0x094d04aa, 0x095f0c36, 0x1e98d7e2, 0x1e97003e, 0x09650e01, 0x09771136, 0x1e91723e,
+ 0x1e8f95e3, 0x097d118d, 0x098f1060, 0x1e89f9bf, 0x1e8818ad, 0x09950f3f, 0x09a709a4, 0x1e826e69,
+ 0x1e8088a2, 0x09ad0707, 0x09befcf4, 0x1e7ad041, 0x1e78e5c7, 0x09c4f8d8, 0x09d6ea40, 0x1e731f4c,
+ 0x1e71301f, 0x09dce4a1, 0x09eed17b, 0x1e6b5b8f, 0x1e6967b1, 0x09f4ca56, 0x0a06b296, 0x1e63850e,
+ 0x1e618c80, 0x0a0ca9e6, 0x0a1e8d81, 0x1e5b9bce, 0x1e599e91, 0x0a248343, 0x0a36622e, 0x1e539fd4,
+ 0x1e519dea, 0x0a3c565e, 0x0a4e308f, 0x1e4b9126, 0x1e498a8e, 0x0a542329, 0x0a65f894, 0x1e436fc7,
+ 0x1e416485, 0x0a6be995, 0x0a7dba2f, 0x1e3b3bbd, 0x1e392bd1, 0x0a83a993, 0x0a957551, 0x1e32f50e,
+ 0x1e30e079, 0x0a9b6315, 0x0aad29ec, 0x1e2a9bbd, 0x1e288281, 0x0ab3160c, 0x0ac4d7f1, 0x1e222fd1,
+ 0x1e2011ee, 0x0acac26a, 0x0adc7f52, 0x1e19b14f, 0x1e178ec7, 0x0ae2681f, 0x0af41fff, 0x1e11203b,
+ 0x1e0ef910, 0x0afa071d, 0x0b0bb9eb, 0x1e087c9b, 0x1e0650ce, 0x0b119f56, 0x0b234d07, 0x1dffc674,
+ 0x1dfd9606, 0x0b2930bb, 0x0b3ad943, 0x1df6fdcc, 0x1df4c8bf, 0x0b40bb3e, 0x0b525e92, 0x1dee22a9,
+ 0x1debe8fd, 0x0b583ecf, 0x0b69dce6, 0x1de5350f, 0x1de2f6c6, 0x0b6fbb62, 0x0b81542f, 0x1ddc3504,
+ 0x1dd9f220, 0x0b8730e6, 0x0b98c45f, 0x1dd3228e, 0x1dd0db10, 0x0b9e9f4d, 0x0bb02d68, 0x1dc9fdb2,
+ 0x1dc7b19b, 0x0bb6068a, 0x0bc78f3b, 0x1dc0c676, 0x1dbe75c8, 0x0bcd668e, 0x0bdee9ca, 0x1db77cdf,
+ 0x1db5279c, 0x0be4bf4a, 0x0bf63d07, 0x1dae20f4, 0x1dabc71d, 0x0bfc10af, 0x0c0d88e2, 0x1da4b2ba,
+ 0x1da25450, 0x0c135ab0, 0x0c24cd4e, 0x1d9b3237, 0x1d98cf3b, 0x0c2a9d3e, 0x0c3c0a3d, 0x1d919f70,
+ 0x1d8f37e5, 0x0c41d84b, 0x0c533fa0, 0x1d87fa6d, 0x1d858e53, 0x0c590bc9, 0x0c6a6d68, 0x1d7e4332,
+ 0x1d7bd28b, 0x0c7037a8, 0x0c819388, 0x1d7479c5, 0x1d720493, 0x0c875bdb, 0x0c98b1f0, 0x1d6a9e2e,
+ 0x1d682472, 0x0c9e7854, 0x0cafc894, 0x1d60b070, 0x1d5e322c, 0x0cb58d04, 0x0cc6d764, 0x1d56b094,
+ 0x1d542dc9, 0x0ccc99de, 0x0cddde53, 0x1d4c9e9f, 0x1d4a174f, 0x0ce39ed2, 0x0cf4dd52, 0x1d427a97,
+ 0x1d3feec3, 0x0cfa9bd2, 0x0d0bd452, 0x1d384483, 0x1d35b42d, 0x0d1190d1, 0x0d22c347, 0x1d2dfc68,
+ 0x1d2b6791, 0x0d287dc1, 0x0d39aa21, 0x1d23a24e, 0x1d2108f8, 0x0d3f6292, 0x0d5088d3, 0x1d19363a,
+ 0x1d169867, 0x0d563f38, 0x0d675f4e, 0x1d0eb833, 0x1d0c15e4, 0x0d6d13a3, 0x0d7e2d85, 0x1d04283f,
+ 0x1d018176, 0x0d83dfc6, 0x0d94f369, 0x1cf98666, 0x1cf6db24, 0x0d9aa393, 0x0dabb0ec, 0x1ceed2ad,
+ 0x1cec22f4, 0x0db15efc, 0x0dc26600, 0x1ce40d1b, 0x1ce158ed, 0x0dc811f3, 0x0dd91298, 0x1cd935b7,
+ 0x1cd67d15, 0x0ddebc69, 0x0defb6a5, 0x1cce4c87, 0x1ccb8f74, 0x0df55e51, 0x0e065219, 0x1cc35192,
+ 0x1cc0900f, 0x0e0bf79c, 0x0e1ce4e6, 0x1cb844df, 0x1cb57eee, 0x0e22883e, 0x0e336eff, 0x1cad2675,
+ 0x1caa5c17, 0x0e391027, 0x0e49f055, 0x1ca1f65b, 0x1c9f2792, 0x0e4f8f4b, 0x0e6068db, 0x1c96b497,
+ 0x1c93e165, 0x0e66059a, 0x0e76d883, 0x1c8b6131, 0x1c888997, 0x0e7c7308, 0x0e8d3f3e, 0x1c7ffc2f,
+ 0x1c7d202f, 0x0e92d787, 0x0ea39d00, 0x1c748599, 0x1c71a535, 0x0ea93308, 0x0eb9f1ba, 0x1c68fd75,
+ 0x1c6618ae, 0x0ebf857d, 0x0ed03d5e, 0x1c5d63ca, 0x1c5a7aa4, 0x0ed5ceda, 0x0ee67fdf, 0x1c51b8a1,
+ 0x1c4ecb1c, 0x0eec0f10, 0x0efcb92f, 0x1c45fc00, 0x1c430a1d, 0x0f024612, 0x0f12e941, 0x1c3a2ded,
+ 0x1c3737b0, 0x0f1873d2, 0x0f291006, 0x1c2e4e72, 0x1c2b53db, 0x0f2e9842, 0x0f3f2d71, 0x1c225d94,
+ 0x1c1f5ea6, 0x0f44b354, 0x0f554175, 0x1c165b5b, 0x1c135818, 0x0f5ac4fc, 0x0f6b4c03, 0x1c0a47cf,
+ 0x1c074038, 0x0f70cd2a, 0x0f814d0e, 0x1bfe22f8, 0x1bfb170f, 0x0f86cbd3, 0x0f974489, 0x1bf1ecdb,
+ 0x1beedca2, 0x0f9cc0e7, 0x0fad3265, 0x1be5a582, 0x1be290fb, 0x0fb2ac5a, 0x0fc31697, 0x1bd94cf4,
+ 0x1bd63421, 0x0fc88e1e, 0x0fd8f10f, 0x1bcce337, 0x1bc9c61a, 0x0fde6626, 0x0feec1c0, 0x1bc06855,
+ 0x1bbd46f0, 0x0ff43464, 0x1004889e, 0x1bb3dc55, 0x1bb0b6a9, 0x1009f8cb, 0x101a459a, 0x1ba73f3d,
+ 0x1ba4154d, 0x101fb34d, 0x102ff8a8, 0x1b9a9117, 0x1b9762e4, 0x103563dc, 0x1045a1b9, 0x1b8dd1ea,
+ 0x1b8a9f77, 0x104b0a6c, 0x105b40c1, 0x1b8101be, 0x1b7dcb0c, 0x1060a6ef, 0x1070d5b1, 0x1b74209b,
+ 0x1b70e5ac, 0x10763958, 0x1086607e, 0x1b672e88, 0x1b63ef5f, 0x108bc19a, 0x109be119, 0x1b5a2b8e,
+ 0x1b56e82c, 0x10a13fa6, 0x10b15775, 0x1b4d17b4, 0x1b49d01c, 0x10b6b371, 0x10c6c385, 0x1b3ff304,
+ 0x1b3ca737, 0x10cc1cec, 0x10dc253c, 0x1b32bd84, 0x1b2f6d85, 0x10e17c0b, 0x10f17c8d, 0x1b25773d,
+ 0x1b22230e, 0x10f6d0c0, 0x1106c96a, 0x1b182038, 0x1b14c7da, 0x110c1afe, 0x111c0bc6, 0x1b0ab87c,
+ 0x1b075bf1, 0x11215ab8, 0x11314395, 0x1afd4012, 0x1af9df5d, 0x11368fe1, 0x114670c8, 0x1aefb702,
+ 0x1aec5225, 0x114bba6b, 0x115b9354, 0x1ae21d54, 0x1adeb451, 0x1160da4b, 0x1170ab2a, 0x1ad47311,
+ 0x1ad105e9, 0x1175ef72, 0x1185b83f, 0x1ac6b841, 0x1ac346f8, 0x118af9d4, 0x119aba84, 0x1ab8ecec,
+ 0x1ab57784, 0x119ff964, 0x11afb1ee, 0x1aab111c, 0x1aa79796, 0x11b4ee14, 0x11c49e6f, 0x1a9d24d9,
+ 0x1a99a737, 0x11c9d7d9, 0x11d97ff9, 0x1a8f282b, 0x1a8ba670, 0x11deb6a4, 0x11ee5682, 0x1a811b1b,
+ 0x1a7d9549, 0x11f38a6a, 0x120321fa, 0x1a72fdb2, 0x1a6f73ca, 0x1208531c, 0x1217e256, 0x1a64cff8,
+ 0x1a6141fd, 0x121d10af, 0x122c9789, 0x1a5691f5, 0x1a52ffeb, 0x1231c316, 0x12414186, 0x1a4843b4,
+ 0x1a44ad9b, 0x12466a44, 0x1255e041, 0x1a39e53d, 0x1a364b17, 0x125b062b, 0x126a73ac, 0x1a2b7698,
+ 0x1a27d868, 0x126f96c1, 0x127efbbb, 0x1a1cf7ce, 0x1a195597, 0x12841bf6, 0x12937861, 0x1a0e68e9,
+ 0x1a0ac2ac, 0x129895c0, 0x12a7e991, 0x19ffc9f1, 0x19fc1fb1, 0x12ad0412, 0x12bc4f40, 0x19f11af0,
+ 0x19ed6caf, 0x12c166de, 0x12d0a960, 0x19e25bee, 0x19dea9ae, 0x12d5be18, 0x12e4f7e5, 0x19d38cf4,
+ 0x19cfd6b8, 0x12ea09b4, 0x12f93ac2, 0x19c4ae0c, 0x19c0f3d6, 0x12fe49a6, 0x130d71eb, 0x19b5bf3f,
+ 0x19b20111, 0x13127de0, 0x13219d53, 0x19a6c096, 0x19a2fe73, 0x1326a656, 0x1335bcef, 0x1997b21b,
+ 0x1993ec04, 0x133ac2fc, 0x1349d0b0, 0x198893d6, 0x1984c9ce, 0x134ed3c5, 0x135dd88c, 0x197965d0,
+ 0x197597da, 0x1362d8a6, 0x1371d476, 0x196a2815, 0x19665632, 0x1376d191, 0x1385c461, 0x195adaab,
+ 0x195704df, 0x138abe7b, 0x1399a841, 0x194b7d9e, 0x1947a3eb, 0x139e9f56, 0x13ad800a, 0x193c10f7,
+ 0x1938335e, 0x13b27417, 0x13c14bb0, 0x192c94bf, 0x1928b343, 0x13c63cb2, 0x13d50b26, 0x191d08ff,
+ 0x191923a3, 0x13d9f91b, 0x13e8be60, 0x190d6dc1, 0x19098488, 0x13eda944, 0x13fc6553, 0x18fdc310,
+ 0x18f9d5fa, 0x14014d23, 0x140ffff1, 0x18ee08f4, 0x18ea1805, 0x1414e4aa, 0x14238e2f, 0x18de3f77,
+ 0x18da4ab2, 0x14286fce, 0x14371001, 0x18ce66a3, 0x18ca6e0a, 0x143bee83, 0x144a855b, 0x18be7e82,
+ 0x18ba8217, 0x144f60bd, 0x145dee30, 0x18ae871e, 0x18aa86e3, 0x1462c670, 0x14714a76, 0x189e8080,
+ 0x189a7c78, 0x14761f8f, 0x14849a1f, 0x188e6ab2, 0x188a62e0, 0x14896c0f, 0x1497dd20, 0x187e45be,
+ 0x187a3a25, 0x149cabe4, 0x14ab136d, 0x186e11af, 0x186a0250, 0x14afdf03, 0x14be3cfa, 0x185dce8e,
+ 0x1859bb6c, 0x14c3055e, 0x14d159bc, 0x184d7c65, 0x18496583, 0x14d61eeb, 0x14e469a6, 0x183d1b3e,
+ 0x1839009e, 0x14e92b9e, 0x14f76cad, 0x182cab24, 0x18288cc8, 0x14fc2b6a, 0x150a62c6, 0x181c2c20,
+ 0x18180a0c, 0x150f1e45, 0x151d4be3, 0x180b9e3d, 0x18077873, 0x15220422, 0x153027fb, 0x17fb0185,
+ 0x17f6d807, 0x1534dcf6, 0x1542f700, 0x17ea5602, 0x17e628d3, 0x1547a8b5, 0x1555b8e8, 0x17d99bbe,
+ 0x17d56ae0, 0x155a6754, 0x15686da7, 0x17c8d2c4, 0x17c49e3b, 0x156d18c7, 0x157b1532, 0x17b7fb1f,
+ 0x17b3c2ec, 0x157fbd03, 0x158daf7c, 0x17a714d7, 0x17a2d8fe, 0x159253fb, 0x15a03c7a, 0x17961ff9,
+ 0x1791e07b, 0x15a4dda5, 0x15b2bc22, 0x17851c8e, 0x1780d96f, 0x15b759f5, 0x15c52e67, 0x17740aa1,
+ 0x176fc3e3, 0x15c9c8e0, 0x15d7933f, 0x1762ea3d, 0x175e9fe2, 0x15dc2a5a, 0x15e9ea9d, 0x1751bb6b,
+ 0x174d6d77, 0x15ee7e58, 0x15fc3477, 0x17407e37, 0x173c2cac, 0x1600c4cf, 0x160e70c1, 0x172f32ab,
+ 0x172add8c, 0x1612fdb3, 0x16209f70, 0x171dd8d2, 0x17198021, 0x162528fa, 0x1632c078, 0x170c70b7,
+ 0x17081477, 0x16374697, 0x1644d3d0, 0x16fafa64, 0x16f69a97, 0x16495680, 0x1656d96a, 0x16e975e4,
+ 0x16e5128e, 0x165b58aa, 0x1668d13e, 0x16d7e341, 0x16d37c65, 0x166d4d0a, 0x167abb3e, 0x16c64288,
0x16c1d827, 0x167f3394, 0x168c9760, 0x16b493c2, 0x16b025e0, 0x16910c3d, 0x169e659a, 0x16a2d6fb
};
const int twidTab512[8*6 + 32*6 + 128*6] = {
- 0x20000000, 0x00000000, 0x1d906bcf, 0x0c3ef153, 0x16a09e66, 0x16a09e66, 0x0c3ef153, 0x1d906bcf,
- 0x20000000, 0x00000000, 0x1f6297d0, 0x063e2e0f, 0x1d906bcf, 0x0c3ef153, 0x1a9b6629, 0x11c73b3a,
- 0x20000000, 0x00000000, 0x1a9b6629, 0x11c73b3a, 0x0c3ef153, 0x1d906bcf, 0xf9c1d1f1, 0x1f6297d0,
- 0x00000000, 0x20000000, 0xf3c10ead, 0x1d906bcf, 0xe95f619a, 0x16a09e66, 0xe26f9431, 0x0c3ef153,
- 0x16a09e66, 0x16a09e66, 0x11c73b3a, 0x1a9b6629, 0x0c3ef153, 0x1d906bcf, 0x063e2e0f, 0x1f6297d0,
- 0xe95f619a, 0x16a09e66, 0xe09d6830, 0x063e2e0f, 0xe26f9431, 0xf3c10ead, 0xee38c4c6, 0xe56499d7,
+ 0x20000000, 0x00000000, 0x1d906bcf, 0x0c3ef153, 0x16a09e66, 0x16a09e66, 0x0c3ef153, 0x1d906bcf,
+ 0x20000000, 0x00000000, 0x1f6297d0, 0x063e2e0f, 0x1d906bcf, 0x0c3ef153, 0x1a9b6629, 0x11c73b3a,
+ 0x20000000, 0x00000000, 0x1a9b6629, 0x11c73b3a, 0x0c3ef153, 0x1d906bcf, 0xf9c1d1f1, 0x1f6297d0,
+ 0x00000000, 0x20000000, 0xf3c10ead, 0x1d906bcf, 0xe95f619a, 0x16a09e66, 0xe26f9431, 0x0c3ef153,
+ 0x16a09e66, 0x16a09e66, 0x11c73b3a, 0x1a9b6629, 0x0c3ef153, 0x1d906bcf, 0x063e2e0f, 0x1f6297d0,
+ 0xe95f619a, 0x16a09e66, 0xe09d6830, 0x063e2e0f, 0xe26f9431, 0xf3c10ead, 0xee38c4c6, 0xe56499d7,
- 0x20000000, 0x00000000, 0x1fd88da4, 0x0322f4d8, 0x1f6297d0, 0x063e2e0f, 0x1e9f4157, 0x094a0317,
- 0x20000000, 0x00000000, 0x1ff621e3, 0x0191f65f, 0x1fd88da4, 0x0322f4d8, 0x1fa7557f, 0x04b2041c,
- 0x20000000, 0x00000000, 0x1fa7557f, 0x04b2041c, 0x1e9f4157, 0x094a0317, 0x1ced7af4, 0x0dae8805,
- 0x1d906bcf, 0x0c3ef153, 0x1c38b2f2, 0x0f15ae9c, 0x1a9b6629, 0x11c73b3a, 0x18bc806b, 0x144cf325,
- 0x1f6297d0, 0x063e2e0f, 0x1f0a7efc, 0x07c67e5f, 0x1e9f4157, 0x094a0317, 0x1e212105, 0x0ac7cd3b,
- 0x1a9b6629, 0x11c73b3a, 0x17b5df22, 0x157d6935, 0x144cf325, 0x18bc806b, 0x10738799, 0x1b728345,
- 0x16a09e66, 0x16a09e66, 0x144cf325, 0x18bc806b, 0x11c73b3a, 0x1a9b6629, 0x0f15ae9c, 0x1c38b2f2,
- 0x1d906bcf, 0x0c3ef153, 0x1ced7af4, 0x0dae8805, 0x1c38b2f2, 0x0f15ae9c, 0x1b728345, 0x10738799,
- 0x0c3ef153, 0x1d906bcf, 0x07c67e5f, 0x1f0a7efc, 0x0322f4d8, 0x1fd88da4, 0xfe6e09a1, 0x1ff621e3,
- 0x0c3ef153, 0x1d906bcf, 0x094a0317, 0x1e9f4157, 0x063e2e0f, 0x1f6297d0, 0x0322f4d8, 0x1fd88da4,
- 0x1a9b6629, 0x11c73b3a, 0x19b3e048, 0x130ff7fd, 0x18bc806b, 0x144cf325, 0x17b5df22, 0x157d6935,
- 0xf9c1d1f1, 0x1f6297d0, 0xf53832c5, 0x1e212105, 0xf0ea5164, 0x1c38b2f2, 0xecf00803, 0x19b3e048,
- 0x00000000, 0x20000000, 0xfcdd0b28, 0x1fd88da4, 0xf9c1d1f1, 0x1f6297d0, 0xf6b5fce9, 0x1e9f4157,
- 0x16a09e66, 0x16a09e66, 0x157d6935, 0x17b5df22, 0x144cf325, 0x18bc806b, 0x130ff7fd, 0x19b3e048,
- 0xe95f619a, 0x16a09e66, 0xe64c1fb8, 0x130ff7fd, 0xe3c74d0e, 0x0f15ae9c, 0xe1dedefb, 0x0ac7cd3b,
- 0xf3c10ead, 0x1d906bcf, 0xf0ea5164, 0x1c38b2f2, 0xee38c4c6, 0x1a9b6629, 0xebb30cdb, 0x18bc806b,
- 0x11c73b3a, 0x1a9b6629, 0x10738799, 0x1b728345, 0x0f15ae9c, 0x1c38b2f2, 0x0dae8805, 0x1ced7af4,
- 0xe09d6830, 0x063e2e0f, 0xe009de1d, 0x0191f65f, 0xe027725c, 0xfcdd0b28, 0xe0f58104, 0xf83981a1,
- 0xe95f619a, 0x16a09e66, 0xe7437f95, 0x144cf325, 0xe56499d7, 0x11c73b3a, 0xe3c74d0e, 0x0f15ae9c,
- 0x0c3ef153, 0x1d906bcf, 0x0ac7cd3b, 0x1e212105, 0x094a0317, 0x1e9f4157, 0x07c67e5f, 0x1f0a7efc,
- 0xe26f9431, 0xf3c10ead, 0xe48d7cbb, 0xef8c7867, 0xe7437f95, 0xebb30cdb, 0xea8296cb, 0xe84a20de,
- 0xe26f9431, 0x0c3ef153, 0xe160bea9, 0x094a0317, 0xe09d6830, 0x063e2e0f, 0xe027725c, 0x0322f4d8,
- 0x063e2e0f, 0x1f6297d0, 0x04b2041c, 0x1fa7557f, 0x0322f4d8, 0x1fd88da4, 0x0191f65f, 0x1ff621e3,
- 0xee38c4c6, 0xe56499d7, 0xf25177fb, 0xe312850c, 0xf6b5fce9, 0xe160bea9, 0xfb4dfbe4, 0xe058aa81,
+ 0x20000000, 0x00000000, 0x1fd88da4, 0x0322f4d8, 0x1f6297d0, 0x063e2e0f, 0x1e9f4157, 0x094a0317,
+ 0x20000000, 0x00000000, 0x1ff621e3, 0x0191f65f, 0x1fd88da4, 0x0322f4d8, 0x1fa7557f, 0x04b2041c,
+ 0x20000000, 0x00000000, 0x1fa7557f, 0x04b2041c, 0x1e9f4157, 0x094a0317, 0x1ced7af4, 0x0dae8805,
+ 0x1d906bcf, 0x0c3ef153, 0x1c38b2f2, 0x0f15ae9c, 0x1a9b6629, 0x11c73b3a, 0x18bc806b, 0x144cf325,
+ 0x1f6297d0, 0x063e2e0f, 0x1f0a7efc, 0x07c67e5f, 0x1e9f4157, 0x094a0317, 0x1e212105, 0x0ac7cd3b,
+ 0x1a9b6629, 0x11c73b3a, 0x17b5df22, 0x157d6935, 0x144cf325, 0x18bc806b, 0x10738799, 0x1b728345,
+ 0x16a09e66, 0x16a09e66, 0x144cf325, 0x18bc806b, 0x11c73b3a, 0x1a9b6629, 0x0f15ae9c, 0x1c38b2f2,
+ 0x1d906bcf, 0x0c3ef153, 0x1ced7af4, 0x0dae8805, 0x1c38b2f2, 0x0f15ae9c, 0x1b728345, 0x10738799,
+ 0x0c3ef153, 0x1d906bcf, 0x07c67e5f, 0x1f0a7efc, 0x0322f4d8, 0x1fd88da4, 0xfe6e09a1, 0x1ff621e3,
+ 0x0c3ef153, 0x1d906bcf, 0x094a0317, 0x1e9f4157, 0x063e2e0f, 0x1f6297d0, 0x0322f4d8, 0x1fd88da4,
+ 0x1a9b6629, 0x11c73b3a, 0x19b3e048, 0x130ff7fd, 0x18bc806b, 0x144cf325, 0x17b5df22, 0x157d6935,
+ 0xf9c1d1f1, 0x1f6297d0, 0xf53832c5, 0x1e212105, 0xf0ea5164, 0x1c38b2f2, 0xecf00803, 0x19b3e048,
+ 0x00000000, 0x20000000, 0xfcdd0b28, 0x1fd88da4, 0xf9c1d1f1, 0x1f6297d0, 0xf6b5fce9, 0x1e9f4157,
+ 0x16a09e66, 0x16a09e66, 0x157d6935, 0x17b5df22, 0x144cf325, 0x18bc806b, 0x130ff7fd, 0x19b3e048,
+ 0xe95f619a, 0x16a09e66, 0xe64c1fb8, 0x130ff7fd, 0xe3c74d0e, 0x0f15ae9c, 0xe1dedefb, 0x0ac7cd3b,
+ 0xf3c10ead, 0x1d906bcf, 0xf0ea5164, 0x1c38b2f2, 0xee38c4c6, 0x1a9b6629, 0xebb30cdb, 0x18bc806b,
+ 0x11c73b3a, 0x1a9b6629, 0x10738799, 0x1b728345, 0x0f15ae9c, 0x1c38b2f2, 0x0dae8805, 0x1ced7af4,
+ 0xe09d6830, 0x063e2e0f, 0xe009de1d, 0x0191f65f, 0xe027725c, 0xfcdd0b28, 0xe0f58104, 0xf83981a1,
+ 0xe95f619a, 0x16a09e66, 0xe7437f95, 0x144cf325, 0xe56499d7, 0x11c73b3a, 0xe3c74d0e, 0x0f15ae9c,
+ 0x0c3ef153, 0x1d906bcf, 0x0ac7cd3b, 0x1e212105, 0x094a0317, 0x1e9f4157, 0x07c67e5f, 0x1f0a7efc,
+ 0xe26f9431, 0xf3c10ead, 0xe48d7cbb, 0xef8c7867, 0xe7437f95, 0xebb30cdb, 0xea8296cb, 0xe84a20de,
+ 0xe26f9431, 0x0c3ef153, 0xe160bea9, 0x094a0317, 0xe09d6830, 0x063e2e0f, 0xe027725c, 0x0322f4d8,
+ 0x063e2e0f, 0x1f6297d0, 0x04b2041c, 0x1fa7557f, 0x0322f4d8, 0x1fd88da4, 0x0191f65f, 0x1ff621e3,
+ 0xee38c4c6, 0xe56499d7, 0xf25177fb, 0xe312850c, 0xf6b5fce9, 0xe160bea9, 0xfb4dfbe4, 0xe058aa81,
- 0x20000000, 0x00000000, 0x1ffd8861, 0x00c90ab0, 0x1ff621e3, 0x0191f65f, 0x1fe9cdad, 0x025aa412,
- 0x20000000, 0x00000000, 0x1fff6217, 0x00648748, 0x1ffd8861, 0x00c90ab0, 0x1ffa72f0, 0x012d8657,
- 0x20000000, 0x00000000, 0x1ffa72f0, 0x012d8657, 0x1fe9cdad, 0x025aa412, 0x1fce15fd, 0x0386f0b9,
- 0x1fd88da4, 0x0322f4d8, 0x1fc26471, 0x03eac9cb, 0x1fa7557f, 0x04b2041c, 0x1f8764fa, 0x05788511,
- 0x1ff621e3, 0x0191f65f, 0x1ff09566, 0x01f656e8, 0x1fe9cdad, 0x025aa412, 0x1fe1cafd, 0x02beda01,
- 0x1fa7557f, 0x04b2041c, 0x1f7599a4, 0x05db7678, 0x1f38f3ac, 0x0702e09b, 0x1ef178a4, 0x0827dc07,
- 0x1f6297d0, 0x063e2e0f, 0x1f38f3ac, 0x0702e09b, 0x1f0a7efc, 0x07c67e5f, 0x1ed740e7, 0x0888e931,
- 0x1fd88da4, 0x0322f4d8, 0x1fce15fd, 0x0386f0b9, 0x1fc26471, 0x03eac9cb, 0x1fb57972, 0x044e7c34,
- 0x1e9f4157, 0x094a0317, 0x1e426a4b, 0x0a68f121, 0x1ddb13b7, 0x0b844298, 0x1d696174, 0x0c9b9532,
- 0x1e9f4157, 0x094a0317, 0x1e6288ec, 0x0a09ae4a, 0x1e212105, 0x0ac7cd3b, 0x1ddb13b7, 0x0b844298,
- 0x1fa7557f, 0x04b2041c, 0x1f97f925, 0x05155dac, 0x1f8764fa, 0x05788511, 0x1f7599a4, 0x05db7678,
- 0x1ced7af4, 0x0dae8805, 0x1c678b35, 0x0ebcbbae, 0x1bd7c0ac, 0x0fc5d26e, 0x1b3e4d3f, 0x10c9704d,
- 0x1d906bcf, 0x0c3ef153, 0x1d4134d1, 0x0cf7bca2, 0x1ced7af4, 0x0dae8805, 0x1c954b21, 0x0e63374d,
- 0x1f6297d0, 0x063e2e0f, 0x1f4e603b, 0x06a0a809, 0x1f38f3ac, 0x0702e09b, 0x1f2252f7, 0x0764d3f9,
- 0x1a9b6629, 0x11c73b3a, 0x19ef43ef, 0x12bedb26, 0x193a224a, 0x13affa29, 0x187c4010, 0x149a449c,
- 0x1c38b2f2, 0x0f15ae9c, 0x1bd7c0ac, 0x0fc5d26e, 0x1b728345, 0x10738799, 0x1b090a58, 0x111eb354,
- 0x1f0a7efc, 0x07c67e5f, 0x1ef178a4, 0x0827dc07, 0x1ed740e7, 0x0888e931, 0x1ebbd8c9, 0x08e9a220,
- 0x17b5df22, 0x157d6935, 0x16e74455, 0x16591926, 0x1610b755, 0x172d0838, 0x15328293, 0x17f8ece3,
- 0x1a9b6629, 0x11c73b3a, 0x1a29a7a0, 0x126d054d, 0x19b3e048, 0x130ff7fd, 0x193a224a, 0x13affa29,
- 0x1e9f4157, 0x094a0317, 0x1e817bab, 0x09aa0861, 0x1e6288ec, 0x0a09ae4a, 0x1e426a4b, 0x0a68f121,
- 0x144cf325, 0x18bc806b, 0x136058b1, 0x19777ef5, 0x126d054d, 0x1a29a7a0, 0x11734d64, 0x1ad2bc9e,
- 0x18bc806b, 0x144cf325, 0x183b0e0c, 0x14e6cabc, 0x17b5df22, 0x157d6935, 0x172d0838, 0x1610b755,
- 0x1e212105, 0x0ac7cd3b, 0x1dfeae62, 0x0b263eef, 0x1ddb13b7, 0x0b844298, 0x1db65262, 0x0be1d499,
- 0x10738799, 0x1b728345, 0x0f6e0ca9, 0x1c08c426, 0x0e63374d, 0x1c954b21, 0x0d536416, 0x1d17e774,
- 0x16a09e66, 0x16a09e66, 0x1610b755, 0x172d0838, 0x157d6935, 0x17b5df22, 0x14e6cabc, 0x183b0e0c,
- 0x1d906bcf, 0x0c3ef153, 0x1d696174, 0x0c9b9532, 0x1d4134d1, 0x0cf7bca2, 0x1d17e774, 0x0d536416,
- 0x0c3ef153, 0x1d906bcf, 0x0b263eef, 0x1dfeae62, 0x0a09ae4a, 0x1e6288ec, 0x08e9a220, 0x1ebbd8c9,
- 0x144cf325, 0x18bc806b, 0x13affa29, 0x193a224a, 0x130ff7fd, 0x19b3e048, 0x126d054d, 0x1a29a7a0,
- 0x1ced7af4, 0x0dae8805, 0x1cc1f0f4, 0x0e0924ec, 0x1c954b21, 0x0e63374d, 0x1c678b35, 0x0ebcbbae,
- 0x07c67e5f, 0x1f0a7efc, 0x06a0a809, 0x1f4e603b, 0x05788511, 0x1f8764fa, 0x044e7c34, 0x1fb57972,
- 0x11c73b3a, 0x1a9b6629, 0x111eb354, 0x1b090a58, 0x10738799, 0x1b728345, 0x0fc5d26e, 0x1bd7c0ac,
- 0x1c38b2f2, 0x0f15ae9c, 0x1c08c426, 0x0f6e0ca9, 0x1bd7c0ac, 0x0fc5d26e, 0x1ba5aa67, 0x101cfc87,
- 0x0322f4d8, 0x1fd88da4, 0x01f656e8, 0x1ff09566, 0x00c90ab0, 0x1ffd8861, 0xff9b78b8, 0x1fff6217,
- 0x0f15ae9c, 0x1c38b2f2, 0x0e63374d, 0x1c954b21, 0x0dae8805, 0x1ced7af4, 0x0cf7bca2, 0x1d4134d1,
- 0x1b728345, 0x10738799, 0x1b3e4d3f, 0x10c9704d, 0x1b090a58, 0x111eb354, 0x1ad2bc9e, 0x11734d64,
- 0xfe6e09a1, 0x1ff621e3, 0xfd4125ff, 0x1fe1cafd, 0xfc153635, 0x1fc26471, 0xfaeaa254, 0x1f97f925,
- 0x0c3ef153, 0x1d906bcf, 0x0b844298, 0x1ddb13b7, 0x0ac7cd3b, 0x1e212105, 0x0a09ae4a, 0x1e6288ec,
- 0x1a9b6629, 0x11c73b3a, 0x1a63091b, 0x121a7999, 0x1a29a7a0, 0x126d054d, 0x19ef43ef, 0x12bedb26,
- 0xf9c1d1f1, 0x1f6297d0, 0xf89b2c07, 0x1f2252f7, 0xf77716cf, 0x1ed740e7, 0xf655f79f, 0x1e817bab,
- 0x094a0317, 0x1e9f4157, 0x0888e931, 0x1ed740e7, 0x07c67e5f, 0x1f0a7efc, 0x0702e09b, 0x1f38f3ac,
- 0x19b3e048, 0x130ff7fd, 0x19777ef5, 0x136058b1, 0x193a224a, 0x13affa29, 0x18fbcca4, 0x13fed953,
- 0xf53832c5, 0x1e212105, 0xf41e2b67, 0x1db65262, 0xf308435e, 0x1d4134d1, 0xf1f6db14, 0x1cc1f0f4,
- 0x063e2e0f, 0x1f6297d0, 0x05788511, 0x1f8764fa, 0x04b2041c, 0x1fa7557f, 0x03eac9cb, 0x1fc26471,
- 0x18bc806b, 0x144cf325, 0x187c4010, 0x149a449c, 0x183b0e0c, 0x14e6cabc, 0x17f8ece3, 0x15328293,
- 0xf0ea5164, 0x1c38b2f2, 0xefe30379, 0x1ba5aa67, 0xeee14cac, 0x1b090a58, 0xede58667, 0x1a63091b,
- 0x0322f4d8, 0x1fd88da4, 0x025aa412, 0x1fe9cdad, 0x0191f65f, 0x1ff621e3, 0x00c90ab0, 0x1ffd8861,
- 0x17b5df22, 0x157d6935, 0x1771e75f, 0x15c77bbe, 0x172d0838, 0x1610b755, 0x16e74455, 0x16591926,
- 0xecf00803, 0x19b3e048, 0xec0126ad, 0x18fbcca4, 0xeb193544, 0x183b0e0c, 0xea388442, 0x1771e75f,
- 0x00000000, 0x20000000, 0xff36f550, 0x1ffd8861, 0xfe6e09a1, 0x1ff621e3, 0xfda55bee, 0x1fe9cdad,
- 0x16a09e66, 0x16a09e66, 0x16591926, 0x16e74455, 0x1610b755, 0x172d0838, 0x15c77bbe, 0x1771e75f,
- 0xe95f619a, 0x16a09e66, 0xe88e18a1, 0x15c77bbe, 0xe7c4f1f4, 0x14e6cabc, 0xe704335c, 0x13fed953,
- 0xfcdd0b28, 0x1fd88da4, 0xfc153635, 0x1fc26471, 0xfb4dfbe4, 0x1fa7557f, 0xfa877aef, 0x1f8764fa,
- 0x157d6935, 0x17b5df22, 0x15328293, 0x17f8ece3, 0x14e6cabc, 0x183b0e0c, 0x149a449c, 0x187c4010,
- 0xe64c1fb8, 0x130ff7fd, 0xe59cf6e5, 0x121a7999, 0xe4f6f5a8, 0x111eb354, 0xe45a5599, 0x101cfc87,
- 0xf9c1d1f1, 0x1f6297d0, 0xf8fd1f65, 0x1f38f3ac, 0xf83981a1, 0x1f0a7efc, 0xf77716cf, 0x1ed740e7,
- 0x144cf325, 0x18bc806b, 0x13fed953, 0x18fbcca4, 0x13affa29, 0x193a224a, 0x136058b1, 0x19777ef5,
- 0xe3c74d0e, 0x0f15ae9c, 0xe33e0f0c, 0x0e0924ec, 0xe2becb2f, 0x0cf7bca2, 0xe249ad9e, 0x0be1d499,
- 0xf6b5fce9, 0x1e9f4157, 0xf5f651b6, 0x1e6288ec, 0xf53832c5, 0x1e212105, 0xf47bbd68, 0x1ddb13b7,
- 0x130ff7fd, 0x19b3e048, 0x12bedb26, 0x19ef43ef, 0x126d054d, 0x1a29a7a0, 0x121a7999, 0x1a63091b,
- 0xe1dedefb, 0x0ac7cd3b, 0xe17e8455, 0x09aa0861, 0xe128bf19, 0x0888e931, 0xe0ddad09, 0x0764d3f9,
- 0xf3c10ead, 0x1d906bcf, 0xf308435e, 0x1d4134d1, 0xf25177fb, 0x1ced7af4, 0xf19cc8b3, 0x1c954b21,
- 0x11c73b3a, 0x1a9b6629, 0x11734d64, 0x1ad2bc9e, 0x111eb354, 0x1b090a58, 0x10c9704d, 0x1b3e4d3f,
- 0xe09d6830, 0x063e2e0f, 0xe06806db, 0x05155dac, 0xe03d9b8f, 0x03eac9cb, 0xe01e3503, 0x02beda01,
- 0xf0ea5164, 0x1c38b2f2, 0xf03a2d92, 0x1bd7c0ac, 0xef8c7867, 0x1b728345, 0xeee14cac, 0x1b090a58,
- 0x10738799, 0x1b728345, 0x101cfc87, 0x1ba5aa67, 0x0fc5d26e, 0x1bd7c0ac, 0x0f6e0ca9, 0x1c08c426,
- 0xe009de1d, 0x0191f65f, 0xe0009de9, 0x00648748, 0xe002779f, 0xff36f550, 0xe00f6a9a, 0xfe09a918,
- 0xee38c4c6, 0x1a9b6629, 0xed92fab3, 0x1a29a7a0, 0xecf00803, 0x19b3e048, 0xec5005d7, 0x193a224a,
- 0x0f15ae9c, 0x1c38b2f2, 0x0ebcbbae, 0x1c678b35, 0x0e63374d, 0x1c954b21, 0x0e0924ec, 0x1cc1f0f4,
- 0xe027725c, 0xfcdd0b28, 0xe04a868e, 0xfbb183cc, 0xe0789b06, 0xfa877aef, 0xe0b19fc5, 0xf95f57f7,
- 0xebb30cdb, 0x18bc806b, 0xeb193544, 0x183b0e0c, 0xea8296cb, 0x17b5df22, 0xe9ef48ab, 0x172d0838,
- 0x0dae8805, 0x1ced7af4, 0x0d536416, 0x1d17e774, 0x0cf7bca2, 0x1d4134d1, 0x0c9b9532, 0x1d696174,
- 0xe0f58104, 0xf83981a1, 0xe1442737, 0xf7165de0, 0xe19d7714, 0xf5f651b6, 0xe201519e, 0xf4d9c111,
- 0xe95f619a, 0x16a09e66, 0xe8d2f7c8, 0x1610b755, 0xe84a20de, 0x157d6935, 0xe7c4f1f4, 0x14e6cabc,
- 0x0c3ef153, 0x1d906bcf, 0x0be1d499, 0x1db65262, 0x0b844298, 0x1ddb13b7, 0x0b263eef, 0x1dfeae62,
- 0xe26f9431, 0xf3c10ead, 0xe2e8188c, 0xf2ac9bea, 0xe36ab4df, 0xf19cc8b3, 0xe3f73bda, 0xf091f357,
- 0xe7437f95, 0x144cf325, 0xe6c5ddb6, 0x13affa29, 0xe64c1fb8, 0x130ff7fd, 0xe5d65860, 0x126d054d,
- 0x0ac7cd3b, 0x1e212105, 0x0a68f121, 0x1e426a4b, 0x0a09ae4a, 0x1e6288ec, 0x09aa0861, 0x1e817bab,
- 0xe48d7cbb, 0xef8c7867, 0xe52d4362, 0xee8cb29c, 0xe5d65860, 0xed92fab3, 0xe688810b, 0xec9fa74f,
- 0xe56499d7, 0x11c73b3a, 0xe4f6f5a8, 0x111eb354, 0xe48d7cbb, 0x10738799, 0xe4283f54, 0x0fc5d26e,
- 0x094a0317, 0x1e9f4157, 0x08e9a220, 0x1ebbd8c9, 0x0888e931, 0x1ed740e7, 0x0827dc07, 0x1ef178a4,
- 0xe7437f95, 0xebb30cdb, 0xe807131d, 0xeacd7d6d, 0xe8d2f7c8, 0xe9ef48ab, 0xe9a6e6da, 0xe918bbab,
- 0xe3c74d0e, 0x0f15ae9c, 0xe36ab4df, 0x0e63374d, 0xe312850c, 0x0dae8805, 0xe2becb2f, 0x0cf7bca2,
- 0x07c67e5f, 0x1f0a7efc, 0x0764d3f9, 0x1f2252f7, 0x0702e09b, 0x1f38f3ac, 0x06a0a809, 0x1f4e603b,
- 0xea8296cb, 0xe84a20de, 0xeb65bb64, 0xe783bff0, 0xec5005d7, 0xe6c5ddb6, 0xed4124da, 0xe610bc11,
- 0xe26f9431, 0x0c3ef153, 0xe224ec49, 0x0b844298, 0xe1dedefb, 0x0ac7cd3b, 0xe19d7714, 0x0a09ae4a,
- 0x063e2e0f, 0x1f6297d0, 0x05db7678, 0x1f7599a4, 0x05788511, 0x1f8764fa, 0x05155dac, 0x1f97f925,
- 0xee38c4c6, 0xe56499d7, 0xef368fb3, 0xe4c1b2c1, 0xf03a2d92, 0xe4283f54, 0xf1434452, 0xe39874cb,
- 0xe160bea9, 0x094a0317, 0xe128bf19, 0x0888e931, 0xe0f58104, 0x07c67e5f, 0xe0c70c54, 0x0702e09b,
- 0x04b2041c, 0x1fa7557f, 0x044e7c34, 0x1fb57972, 0x03eac9cb, 0x1fc26471, 0x0386f0b9, 0x1fce15fd,
- 0xf25177fb, 0xe312850c, 0xf3646ace, 0xe2969e8c, 0xf47bbd68, 0xe224ec49, 0xf5970edf, 0xe1bd95b5,
- 0xe09d6830, 0x063e2e0f, 0xe0789b06, 0x05788511, 0xe058aa81, 0x04b2041c, 0xe03d9b8f, 0x03eac9cb,
- 0x0322f4d8, 0x1fd88da4, 0x02beda01, 0x1fe1cafd, 0x025aa412, 0x1fe9cdad, 0x01f656e8, 0x1ff09566,
- 0xf6b5fce9, 0xe160bea9, 0xf7d823f9, 0xe10e875c, 0xf8fd1f65, 0xe0c70c54, 0xfa248988, 0xe08a665c,
- 0xe027725c, 0x0322f4d8, 0xe0163253, 0x025aa412, 0xe009de1d, 0x0191f65f, 0xe002779f, 0x00c90ab0,
- 0x0191f65f, 0x1ff621e3, 0x012d8657, 0x1ffa72f0, 0x00c90ab0, 0x1ffd8861, 0x00648748, 0x1fff6217,
+ 0x20000000, 0x00000000, 0x1ffd8861, 0x00c90ab0, 0x1ff621e3, 0x0191f65f, 0x1fe9cdad, 0x025aa412,
+ 0x20000000, 0x00000000, 0x1fff6217, 0x00648748, 0x1ffd8861, 0x00c90ab0, 0x1ffa72f0, 0x012d8657,
+ 0x20000000, 0x00000000, 0x1ffa72f0, 0x012d8657, 0x1fe9cdad, 0x025aa412, 0x1fce15fd, 0x0386f0b9,
+ 0x1fd88da4, 0x0322f4d8, 0x1fc26471, 0x03eac9cb, 0x1fa7557f, 0x04b2041c, 0x1f8764fa, 0x05788511,
+ 0x1ff621e3, 0x0191f65f, 0x1ff09566, 0x01f656e8, 0x1fe9cdad, 0x025aa412, 0x1fe1cafd, 0x02beda01,
+ 0x1fa7557f, 0x04b2041c, 0x1f7599a4, 0x05db7678, 0x1f38f3ac, 0x0702e09b, 0x1ef178a4, 0x0827dc07,
+ 0x1f6297d0, 0x063e2e0f, 0x1f38f3ac, 0x0702e09b, 0x1f0a7efc, 0x07c67e5f, 0x1ed740e7, 0x0888e931,
+ 0x1fd88da4, 0x0322f4d8, 0x1fce15fd, 0x0386f0b9, 0x1fc26471, 0x03eac9cb, 0x1fb57972, 0x044e7c34,
+ 0x1e9f4157, 0x094a0317, 0x1e426a4b, 0x0a68f121, 0x1ddb13b7, 0x0b844298, 0x1d696174, 0x0c9b9532,
+ 0x1e9f4157, 0x094a0317, 0x1e6288ec, 0x0a09ae4a, 0x1e212105, 0x0ac7cd3b, 0x1ddb13b7, 0x0b844298,
+ 0x1fa7557f, 0x04b2041c, 0x1f97f925, 0x05155dac, 0x1f8764fa, 0x05788511, 0x1f7599a4, 0x05db7678,
+ 0x1ced7af4, 0x0dae8805, 0x1c678b35, 0x0ebcbbae, 0x1bd7c0ac, 0x0fc5d26e, 0x1b3e4d3f, 0x10c9704d,
+ 0x1d906bcf, 0x0c3ef153, 0x1d4134d1, 0x0cf7bca2, 0x1ced7af4, 0x0dae8805, 0x1c954b21, 0x0e63374d,
+ 0x1f6297d0, 0x063e2e0f, 0x1f4e603b, 0x06a0a809, 0x1f38f3ac, 0x0702e09b, 0x1f2252f7, 0x0764d3f9,
+ 0x1a9b6629, 0x11c73b3a, 0x19ef43ef, 0x12bedb26, 0x193a224a, 0x13affa29, 0x187c4010, 0x149a449c,
+ 0x1c38b2f2, 0x0f15ae9c, 0x1bd7c0ac, 0x0fc5d26e, 0x1b728345, 0x10738799, 0x1b090a58, 0x111eb354,
+ 0x1f0a7efc, 0x07c67e5f, 0x1ef178a4, 0x0827dc07, 0x1ed740e7, 0x0888e931, 0x1ebbd8c9, 0x08e9a220,
+ 0x17b5df22, 0x157d6935, 0x16e74455, 0x16591926, 0x1610b755, 0x172d0838, 0x15328293, 0x17f8ece3,
+ 0x1a9b6629, 0x11c73b3a, 0x1a29a7a0, 0x126d054d, 0x19b3e048, 0x130ff7fd, 0x193a224a, 0x13affa29,
+ 0x1e9f4157, 0x094a0317, 0x1e817bab, 0x09aa0861, 0x1e6288ec, 0x0a09ae4a, 0x1e426a4b, 0x0a68f121,
+ 0x144cf325, 0x18bc806b, 0x136058b1, 0x19777ef5, 0x126d054d, 0x1a29a7a0, 0x11734d64, 0x1ad2bc9e,
+ 0x18bc806b, 0x144cf325, 0x183b0e0c, 0x14e6cabc, 0x17b5df22, 0x157d6935, 0x172d0838, 0x1610b755,
+ 0x1e212105, 0x0ac7cd3b, 0x1dfeae62, 0x0b263eef, 0x1ddb13b7, 0x0b844298, 0x1db65262, 0x0be1d499,
+ 0x10738799, 0x1b728345, 0x0f6e0ca9, 0x1c08c426, 0x0e63374d, 0x1c954b21, 0x0d536416, 0x1d17e774,
+ 0x16a09e66, 0x16a09e66, 0x1610b755, 0x172d0838, 0x157d6935, 0x17b5df22, 0x14e6cabc, 0x183b0e0c,
+ 0x1d906bcf, 0x0c3ef153, 0x1d696174, 0x0c9b9532, 0x1d4134d1, 0x0cf7bca2, 0x1d17e774, 0x0d536416,
+ 0x0c3ef153, 0x1d906bcf, 0x0b263eef, 0x1dfeae62, 0x0a09ae4a, 0x1e6288ec, 0x08e9a220, 0x1ebbd8c9,
+ 0x144cf325, 0x18bc806b, 0x13affa29, 0x193a224a, 0x130ff7fd, 0x19b3e048, 0x126d054d, 0x1a29a7a0,
+ 0x1ced7af4, 0x0dae8805, 0x1cc1f0f4, 0x0e0924ec, 0x1c954b21, 0x0e63374d, 0x1c678b35, 0x0ebcbbae,
+ 0x07c67e5f, 0x1f0a7efc, 0x06a0a809, 0x1f4e603b, 0x05788511, 0x1f8764fa, 0x044e7c34, 0x1fb57972,
+ 0x11c73b3a, 0x1a9b6629, 0x111eb354, 0x1b090a58, 0x10738799, 0x1b728345, 0x0fc5d26e, 0x1bd7c0ac,
+ 0x1c38b2f2, 0x0f15ae9c, 0x1c08c426, 0x0f6e0ca9, 0x1bd7c0ac, 0x0fc5d26e, 0x1ba5aa67, 0x101cfc87,
+ 0x0322f4d8, 0x1fd88da4, 0x01f656e8, 0x1ff09566, 0x00c90ab0, 0x1ffd8861, 0xff9b78b8, 0x1fff6217,
+ 0x0f15ae9c, 0x1c38b2f2, 0x0e63374d, 0x1c954b21, 0x0dae8805, 0x1ced7af4, 0x0cf7bca2, 0x1d4134d1,
+ 0x1b728345, 0x10738799, 0x1b3e4d3f, 0x10c9704d, 0x1b090a58, 0x111eb354, 0x1ad2bc9e, 0x11734d64,
+ 0xfe6e09a1, 0x1ff621e3, 0xfd4125ff, 0x1fe1cafd, 0xfc153635, 0x1fc26471, 0xfaeaa254, 0x1f97f925,
+ 0x0c3ef153, 0x1d906bcf, 0x0b844298, 0x1ddb13b7, 0x0ac7cd3b, 0x1e212105, 0x0a09ae4a, 0x1e6288ec,
+ 0x1a9b6629, 0x11c73b3a, 0x1a63091b, 0x121a7999, 0x1a29a7a0, 0x126d054d, 0x19ef43ef, 0x12bedb26,
+ 0xf9c1d1f1, 0x1f6297d0, 0xf89b2c07, 0x1f2252f7, 0xf77716cf, 0x1ed740e7, 0xf655f79f, 0x1e817bab,
+ 0x094a0317, 0x1e9f4157, 0x0888e931, 0x1ed740e7, 0x07c67e5f, 0x1f0a7efc, 0x0702e09b, 0x1f38f3ac,
+ 0x19b3e048, 0x130ff7fd, 0x19777ef5, 0x136058b1, 0x193a224a, 0x13affa29, 0x18fbcca4, 0x13fed953,
+ 0xf53832c5, 0x1e212105, 0xf41e2b67, 0x1db65262, 0xf308435e, 0x1d4134d1, 0xf1f6db14, 0x1cc1f0f4,
+ 0x063e2e0f, 0x1f6297d0, 0x05788511, 0x1f8764fa, 0x04b2041c, 0x1fa7557f, 0x03eac9cb, 0x1fc26471,
+ 0x18bc806b, 0x144cf325, 0x187c4010, 0x149a449c, 0x183b0e0c, 0x14e6cabc, 0x17f8ece3, 0x15328293,
+ 0xf0ea5164, 0x1c38b2f2, 0xefe30379, 0x1ba5aa67, 0xeee14cac, 0x1b090a58, 0xede58667, 0x1a63091b,
+ 0x0322f4d8, 0x1fd88da4, 0x025aa412, 0x1fe9cdad, 0x0191f65f, 0x1ff621e3, 0x00c90ab0, 0x1ffd8861,
+ 0x17b5df22, 0x157d6935, 0x1771e75f, 0x15c77bbe, 0x172d0838, 0x1610b755, 0x16e74455, 0x16591926,
+ 0xecf00803, 0x19b3e048, 0xec0126ad, 0x18fbcca4, 0xeb193544, 0x183b0e0c, 0xea388442, 0x1771e75f,
+ 0x00000000, 0x20000000, 0xff36f550, 0x1ffd8861, 0xfe6e09a1, 0x1ff621e3, 0xfda55bee, 0x1fe9cdad,
+ 0x16a09e66, 0x16a09e66, 0x16591926, 0x16e74455, 0x1610b755, 0x172d0838, 0x15c77bbe, 0x1771e75f,
+ 0xe95f619a, 0x16a09e66, 0xe88e18a1, 0x15c77bbe, 0xe7c4f1f4, 0x14e6cabc, 0xe704335c, 0x13fed953,
+ 0xfcdd0b28, 0x1fd88da4, 0xfc153635, 0x1fc26471, 0xfb4dfbe4, 0x1fa7557f, 0xfa877aef, 0x1f8764fa,
+ 0x157d6935, 0x17b5df22, 0x15328293, 0x17f8ece3, 0x14e6cabc, 0x183b0e0c, 0x149a449c, 0x187c4010,
+ 0xe64c1fb8, 0x130ff7fd, 0xe59cf6e5, 0x121a7999, 0xe4f6f5a8, 0x111eb354, 0xe45a5599, 0x101cfc87,
+ 0xf9c1d1f1, 0x1f6297d0, 0xf8fd1f65, 0x1f38f3ac, 0xf83981a1, 0x1f0a7efc, 0xf77716cf, 0x1ed740e7,
+ 0x144cf325, 0x18bc806b, 0x13fed953, 0x18fbcca4, 0x13affa29, 0x193a224a, 0x136058b1, 0x19777ef5,
+ 0xe3c74d0e, 0x0f15ae9c, 0xe33e0f0c, 0x0e0924ec, 0xe2becb2f, 0x0cf7bca2, 0xe249ad9e, 0x0be1d499,
+ 0xf6b5fce9, 0x1e9f4157, 0xf5f651b6, 0x1e6288ec, 0xf53832c5, 0x1e212105, 0xf47bbd68, 0x1ddb13b7,
+ 0x130ff7fd, 0x19b3e048, 0x12bedb26, 0x19ef43ef, 0x126d054d, 0x1a29a7a0, 0x121a7999, 0x1a63091b,
+ 0xe1dedefb, 0x0ac7cd3b, 0xe17e8455, 0x09aa0861, 0xe128bf19, 0x0888e931, 0xe0ddad09, 0x0764d3f9,
+ 0xf3c10ead, 0x1d906bcf, 0xf308435e, 0x1d4134d1, 0xf25177fb, 0x1ced7af4, 0xf19cc8b3, 0x1c954b21,
+ 0x11c73b3a, 0x1a9b6629, 0x11734d64, 0x1ad2bc9e, 0x111eb354, 0x1b090a58, 0x10c9704d, 0x1b3e4d3f,
+ 0xe09d6830, 0x063e2e0f, 0xe06806db, 0x05155dac, 0xe03d9b8f, 0x03eac9cb, 0xe01e3503, 0x02beda01,
+ 0xf0ea5164, 0x1c38b2f2, 0xf03a2d92, 0x1bd7c0ac, 0xef8c7867, 0x1b728345, 0xeee14cac, 0x1b090a58,
+ 0x10738799, 0x1b728345, 0x101cfc87, 0x1ba5aa67, 0x0fc5d26e, 0x1bd7c0ac, 0x0f6e0ca9, 0x1c08c426,
+ 0xe009de1d, 0x0191f65f, 0xe0009de9, 0x00648748, 0xe002779f, 0xff36f550, 0xe00f6a9a, 0xfe09a918,
+ 0xee38c4c6, 0x1a9b6629, 0xed92fab3, 0x1a29a7a0, 0xecf00803, 0x19b3e048, 0xec5005d7, 0x193a224a,
+ 0x0f15ae9c, 0x1c38b2f2, 0x0ebcbbae, 0x1c678b35, 0x0e63374d, 0x1c954b21, 0x0e0924ec, 0x1cc1f0f4,
+ 0xe027725c, 0xfcdd0b28, 0xe04a868e, 0xfbb183cc, 0xe0789b06, 0xfa877aef, 0xe0b19fc5, 0xf95f57f7,
+ 0xebb30cdb, 0x18bc806b, 0xeb193544, 0x183b0e0c, 0xea8296cb, 0x17b5df22, 0xe9ef48ab, 0x172d0838,
+ 0x0dae8805, 0x1ced7af4, 0x0d536416, 0x1d17e774, 0x0cf7bca2, 0x1d4134d1, 0x0c9b9532, 0x1d696174,
+ 0xe0f58104, 0xf83981a1, 0xe1442737, 0xf7165de0, 0xe19d7714, 0xf5f651b6, 0xe201519e, 0xf4d9c111,
+ 0xe95f619a, 0x16a09e66, 0xe8d2f7c8, 0x1610b755, 0xe84a20de, 0x157d6935, 0xe7c4f1f4, 0x14e6cabc,
+ 0x0c3ef153, 0x1d906bcf, 0x0be1d499, 0x1db65262, 0x0b844298, 0x1ddb13b7, 0x0b263eef, 0x1dfeae62,
+ 0xe26f9431, 0xf3c10ead, 0xe2e8188c, 0xf2ac9bea, 0xe36ab4df, 0xf19cc8b3, 0xe3f73bda, 0xf091f357,
+ 0xe7437f95, 0x144cf325, 0xe6c5ddb6, 0x13affa29, 0xe64c1fb8, 0x130ff7fd, 0xe5d65860, 0x126d054d,
+ 0x0ac7cd3b, 0x1e212105, 0x0a68f121, 0x1e426a4b, 0x0a09ae4a, 0x1e6288ec, 0x09aa0861, 0x1e817bab,
+ 0xe48d7cbb, 0xef8c7867, 0xe52d4362, 0xee8cb29c, 0xe5d65860, 0xed92fab3, 0xe688810b, 0xec9fa74f,
+ 0xe56499d7, 0x11c73b3a, 0xe4f6f5a8, 0x111eb354, 0xe48d7cbb, 0x10738799, 0xe4283f54, 0x0fc5d26e,
+ 0x094a0317, 0x1e9f4157, 0x08e9a220, 0x1ebbd8c9, 0x0888e931, 0x1ed740e7, 0x0827dc07, 0x1ef178a4,
+ 0xe7437f95, 0xebb30cdb, 0xe807131d, 0xeacd7d6d, 0xe8d2f7c8, 0xe9ef48ab, 0xe9a6e6da, 0xe918bbab,
+ 0xe3c74d0e, 0x0f15ae9c, 0xe36ab4df, 0x0e63374d, 0xe312850c, 0x0dae8805, 0xe2becb2f, 0x0cf7bca2,
+ 0x07c67e5f, 0x1f0a7efc, 0x0764d3f9, 0x1f2252f7, 0x0702e09b, 0x1f38f3ac, 0x06a0a809, 0x1f4e603b,
+ 0xea8296cb, 0xe84a20de, 0xeb65bb64, 0xe783bff0, 0xec5005d7, 0xe6c5ddb6, 0xed4124da, 0xe610bc11,
+ 0xe26f9431, 0x0c3ef153, 0xe224ec49, 0x0b844298, 0xe1dedefb, 0x0ac7cd3b, 0xe19d7714, 0x0a09ae4a,
+ 0x063e2e0f, 0x1f6297d0, 0x05db7678, 0x1f7599a4, 0x05788511, 0x1f8764fa, 0x05155dac, 0x1f97f925,
+ 0xee38c4c6, 0xe56499d7, 0xef368fb3, 0xe4c1b2c1, 0xf03a2d92, 0xe4283f54, 0xf1434452, 0xe39874cb,
+ 0xe160bea9, 0x094a0317, 0xe128bf19, 0x0888e931, 0xe0f58104, 0x07c67e5f, 0xe0c70c54, 0x0702e09b,
+ 0x04b2041c, 0x1fa7557f, 0x044e7c34, 0x1fb57972, 0x03eac9cb, 0x1fc26471, 0x0386f0b9, 0x1fce15fd,
+ 0xf25177fb, 0xe312850c, 0xf3646ace, 0xe2969e8c, 0xf47bbd68, 0xe224ec49, 0xf5970edf, 0xe1bd95b5,
+ 0xe09d6830, 0x063e2e0f, 0xe0789b06, 0x05788511, 0xe058aa81, 0x04b2041c, 0xe03d9b8f, 0x03eac9cb,
+ 0x0322f4d8, 0x1fd88da4, 0x02beda01, 0x1fe1cafd, 0x025aa412, 0x1fe9cdad, 0x01f656e8, 0x1ff09566,
+ 0xf6b5fce9, 0xe160bea9, 0xf7d823f9, 0xe10e875c, 0xf8fd1f65, 0xe0c70c54, 0xfa248988, 0xe08a665c,
+ 0xe027725c, 0x0322f4d8, 0xe0163253, 0x025aa412, 0xe009de1d, 0x0191f65f, 0xe002779f, 0x00c90ab0,
+ 0x0191f65f, 0x1ff621e3, 0x012d8657, 0x1ffa72f0, 0x00c90ab0, 0x1ffd8861, 0x00648748, 0x1fff6217,
0xfb4dfbe4, 0xe058aa81, 0xfc790f47, 0xe031ea03, 0xfda55bee, 0xe0163253, 0xfed279a9, 0xe0058d10
};
const int twidTab64[4*6 + 16*6] = {
- 0x20000000, 0x00000000, 0x16a09e66, 0x16a09e66, 0x00000000, 0x20000000, 0xe95f619a, 0x16a09e66,
- 0x20000000, 0x00000000, 0x1d906bcf, 0x0c3ef153, 0x16a09e66, 0x16a09e66, 0x0c3ef153, 0x1d906bcf,
- 0x20000000, 0x00000000, 0x0c3ef153, 0x1d906bcf, 0xe95f619a, 0x16a09e66, 0xe26f9431, 0xf3c10ead,
+ 0x20000000, 0x00000000, 0x16a09e66, 0x16a09e66, 0x00000000, 0x20000000, 0xe95f619a, 0x16a09e66,
+ 0x20000000, 0x00000000, 0x1d906bcf, 0x0c3ef153, 0x16a09e66, 0x16a09e66, 0x0c3ef153, 0x1d906bcf,
+ 0x20000000, 0x00000000, 0x0c3ef153, 0x1d906bcf, 0xe95f619a, 0x16a09e66, 0xe26f9431, 0xf3c10ead,
- 0x20000000, 0x00000000, 0x1f6297d0, 0x063e2e0f, 0x1d906bcf, 0x0c3ef153, 0x1a9b6629, 0x11c73b3a,
- 0x20000000, 0x00000000, 0x1fd88da4, 0x0322f4d8, 0x1f6297d0, 0x063e2e0f, 0x1e9f4157, 0x094a0317,
- 0x20000000, 0x00000000, 0x1e9f4157, 0x094a0317, 0x1a9b6629, 0x11c73b3a, 0x144cf325, 0x18bc806b,
- 0x16a09e66, 0x16a09e66, 0x11c73b3a, 0x1a9b6629, 0x0c3ef153, 0x1d906bcf, 0x063e2e0f, 0x1f6297d0,
- 0x1d906bcf, 0x0c3ef153, 0x1c38b2f2, 0x0f15ae9c, 0x1a9b6629, 0x11c73b3a, 0x18bc806b, 0x144cf325,
- 0x0c3ef153, 0x1d906bcf, 0x0322f4d8, 0x1fd88da4, 0xf9c1d1f1, 0x1f6297d0, 0xf0ea5164, 0x1c38b2f2,
- 0x00000000, 0x20000000, 0xf9c1d1f1, 0x1f6297d0, 0xf3c10ead, 0x1d906bcf, 0xee38c4c6, 0x1a9b6629,
- 0x16a09e66, 0x16a09e66, 0x144cf325, 0x18bc806b, 0x11c73b3a, 0x1a9b6629, 0x0f15ae9c, 0x1c38b2f2,
- 0xe95f619a, 0x16a09e66, 0xe3c74d0e, 0x0f15ae9c, 0xe09d6830, 0x063e2e0f, 0xe027725c, 0xfcdd0b28,
- 0xe95f619a, 0x16a09e66, 0xe56499d7, 0x11c73b3a, 0xe26f9431, 0x0c3ef153, 0xe09d6830, 0x063e2e0f,
- 0x0c3ef153, 0x1d906bcf, 0x094a0317, 0x1e9f4157, 0x063e2e0f, 0x1f6297d0, 0x0322f4d8, 0x1fd88da4,
+ 0x20000000, 0x00000000, 0x1f6297d0, 0x063e2e0f, 0x1d906bcf, 0x0c3ef153, 0x1a9b6629, 0x11c73b3a,
+ 0x20000000, 0x00000000, 0x1fd88da4, 0x0322f4d8, 0x1f6297d0, 0x063e2e0f, 0x1e9f4157, 0x094a0317,
+ 0x20000000, 0x00000000, 0x1e9f4157, 0x094a0317, 0x1a9b6629, 0x11c73b3a, 0x144cf325, 0x18bc806b,
+ 0x16a09e66, 0x16a09e66, 0x11c73b3a, 0x1a9b6629, 0x0c3ef153, 0x1d906bcf, 0x063e2e0f, 0x1f6297d0,
+ 0x1d906bcf, 0x0c3ef153, 0x1c38b2f2, 0x0f15ae9c, 0x1a9b6629, 0x11c73b3a, 0x18bc806b, 0x144cf325,
+ 0x0c3ef153, 0x1d906bcf, 0x0322f4d8, 0x1fd88da4, 0xf9c1d1f1, 0x1f6297d0, 0xf0ea5164, 0x1c38b2f2,
+ 0x00000000, 0x20000000, 0xf9c1d1f1, 0x1f6297d0, 0xf3c10ead, 0x1d906bcf, 0xee38c4c6, 0x1a9b6629,
+ 0x16a09e66, 0x16a09e66, 0x144cf325, 0x18bc806b, 0x11c73b3a, 0x1a9b6629, 0x0f15ae9c, 0x1c38b2f2,
+ 0xe95f619a, 0x16a09e66, 0xe3c74d0e, 0x0f15ae9c, 0xe09d6830, 0x063e2e0f, 0xe027725c, 0xfcdd0b28,
+ 0xe95f619a, 0x16a09e66, 0xe56499d7, 0x11c73b3a, 0xe26f9431, 0x0c3ef153, 0xe09d6830, 0x063e2e0f,
+ 0x0c3ef153, 0x1d906bcf, 0x094a0317, 0x1e9f4157, 0x063e2e0f, 0x1f6297d0, 0x0322f4d8, 0x1fd88da4,
0xe26f9431, 0xf3c10ead, 0xe7437f95, 0xebb30cdb, 0xee38c4c6, 0xe56499d7, 0xf6b5fce9, 0xe160bea9
};
#else
-/*
- * Q30 for 128 and 1024
+/*
+ * Q30 for 128 and 1024
*
* for (i = 0; i < num/4; i++) {
* angle = (i + 0.125) * M_PI / num;
* x = cos(angle) * (1 << 30);
* x = sin(angle) * (1 << 30);
- *
+ *
* angle = (num/2 - 1 - i + 0.125) * M_PI / num;
* x = cos(angle) * (1 << 30);
* x = sin(angle) * (1 << 30);
@@ -667,379 +667,379 @@
*/
const int cossintab[128 + 1024] = {
/* 128 */
- 0x3fffec43, 0x003243f1, 0x015fd4d2, 0x3ffc38d1, 0x3ff9c13a, 0x01c454f5, 0x02f1b755, 0x3feea776,
- 0x3fe9b8a9, 0x03562038, 0x0483259d, 0x3fd73a4a, 0x3fcfd50b, 0x04e767c5, 0x0613e1c5, 0x3fb5f4ea,
- 0x3fac1a5b, 0x0677edbb, 0x07a3adff, 0x3f8adc77, 0x3f7e8e1e, 0x08077457, 0x09324ca7, 0x3f55f796,
- 0x3f473759, 0x0995bdfd, 0x0abf8043, 0x3f174e70, 0x3f061e95, 0x0b228d42, 0x0c4b0b94, 0x3eceeaad,
- 0x3ebb4ddb, 0x0cada4f5, 0x0dd4b19a, 0x3e7cd778, 0x3e66d0b4, 0x0e36c82a, 0x0f5c35a3, 0x3e212179,
- 0x3e08b42a, 0x0fbdba40, 0x10e15b4e, 0x3dbbd6d4, 0x3da106bd, 0x11423ef0, 0x1263e699, 0x3d4d0728,
- 0x3d2fd86c, 0x12c41a4f, 0x13e39be9, 0x3cd4c38b, 0x3cb53aaa, 0x144310dd, 0x15604013, 0x3c531e88,
- 0x3c314060, 0x15bee78c, 0x16d99864, 0x3bc82c1f, 0x3ba3fde7, 0x173763c9, 0x184f6aab, 0x3b3401bb,
- 0x3b0d8909, 0x18ac4b87, 0x19c17d44, 0x3a96b636, 0x3a6df8f8, 0x1a1d6544, 0x1b2f971e, 0x39f061d2,
- 0x39c5664f, 0x1b8a7815, 0x1c997fc4, 0x39411e33, 0x3913eb0e, 0x1cf34baf, 0x1dfeff67, 0x38890663,
- 0x3859a292, 0x1e57a86d, 0x1f5fdee6, 0x37c836c2, 0x3796a996, 0x1fb7575c, 0x20bbe7d8, 0x36fecd0e,
- 0x36cb1e2a, 0x21122240, 0x2212e492, 0x362ce855, 0x35f71fb1, 0x2267d3a0, 0x2364a02e, 0x3552a8f4,
- 0x351acedd, 0x23b836ca, 0x24b0e699, 0x34703095, 0x34364da6, 0x250317df, 0x25f78497, 0x3385a222,
- 0x3349bf48, 0x264843d9, 0x273847c8, 0x329321c7, 0x32554840, 0x27878893, 0x2872feb6, 0x3198d4ea,
- 0x31590e3e, 0x28c0b4d2, 0x29a778db, 0x3096e223, 0x30553828, 0x29f3984c, 0x2ad586a3, 0x2f8d713a,
- 0x2f49ee0f, 0x2b2003ac, 0x2bfcf97c, 0x2e7cab1c, 0x2e37592c, 0x2c45c8a0, 0x2d1da3d5, 0x2d64b9da,
+ 0x3fffec43, 0x003243f1, 0x015fd4d2, 0x3ffc38d1, 0x3ff9c13a, 0x01c454f5, 0x02f1b755, 0x3feea776,
+ 0x3fe9b8a9, 0x03562038, 0x0483259d, 0x3fd73a4a, 0x3fcfd50b, 0x04e767c5, 0x0613e1c5, 0x3fb5f4ea,
+ 0x3fac1a5b, 0x0677edbb, 0x07a3adff, 0x3f8adc77, 0x3f7e8e1e, 0x08077457, 0x09324ca7, 0x3f55f796,
+ 0x3f473759, 0x0995bdfd, 0x0abf8043, 0x3f174e70, 0x3f061e95, 0x0b228d42, 0x0c4b0b94, 0x3eceeaad,
+ 0x3ebb4ddb, 0x0cada4f5, 0x0dd4b19a, 0x3e7cd778, 0x3e66d0b4, 0x0e36c82a, 0x0f5c35a3, 0x3e212179,
+ 0x3e08b42a, 0x0fbdba40, 0x10e15b4e, 0x3dbbd6d4, 0x3da106bd, 0x11423ef0, 0x1263e699, 0x3d4d0728,
+ 0x3d2fd86c, 0x12c41a4f, 0x13e39be9, 0x3cd4c38b, 0x3cb53aaa, 0x144310dd, 0x15604013, 0x3c531e88,
+ 0x3c314060, 0x15bee78c, 0x16d99864, 0x3bc82c1f, 0x3ba3fde7, 0x173763c9, 0x184f6aab, 0x3b3401bb,
+ 0x3b0d8909, 0x18ac4b87, 0x19c17d44, 0x3a96b636, 0x3a6df8f8, 0x1a1d6544, 0x1b2f971e, 0x39f061d2,
+ 0x39c5664f, 0x1b8a7815, 0x1c997fc4, 0x39411e33, 0x3913eb0e, 0x1cf34baf, 0x1dfeff67, 0x38890663,
+ 0x3859a292, 0x1e57a86d, 0x1f5fdee6, 0x37c836c2, 0x3796a996, 0x1fb7575c, 0x20bbe7d8, 0x36fecd0e,
+ 0x36cb1e2a, 0x21122240, 0x2212e492, 0x362ce855, 0x35f71fb1, 0x2267d3a0, 0x2364a02e, 0x3552a8f4,
+ 0x351acedd, 0x23b836ca, 0x24b0e699, 0x34703095, 0x34364da6, 0x250317df, 0x25f78497, 0x3385a222,
+ 0x3349bf48, 0x264843d9, 0x273847c8, 0x329321c7, 0x32554840, 0x27878893, 0x2872feb6, 0x3198d4ea,
+ 0x31590e3e, 0x28c0b4d2, 0x29a778db, 0x3096e223, 0x30553828, 0x29f3984c, 0x2ad586a3, 0x2f8d713a,
+ 0x2f49ee0f, 0x2b2003ac, 0x2bfcf97c, 0x2e7cab1c, 0x2e37592c, 0x2c45c8a0, 0x2d1da3d5, 0x2d64b9da,
/* 1024 */
- 0x3fffffb1, 0x0006487f, 0x002bfb74, 0x3ffff0e3, 0x3fffe705, 0x00388c6e, 0x005e3f4c, 0x3fffba9b,
- 0x3fffa6de, 0x006ad03b, 0x009082ea, 0x3fff5cd8, 0x3fff3f3c, 0x009d13c5, 0x00c2c62f, 0x3ffed79b,
- 0x3ffeb021, 0x00cf56ef, 0x00f508fc, 0x3ffe2ae5, 0x3ffdf98c, 0x01019998, 0x01274b31, 0x3ffd56b5,
- 0x3ffd1b7e, 0x0133dba3, 0x01598cb1, 0x3ffc5b0c, 0x3ffc15f7, 0x01661cf0, 0x018bcd5b, 0x3ffb37ec,
- 0x3ffae8f9, 0x01985d60, 0x01be0d11, 0x3ff9ed53, 0x3ff99483, 0x01ca9cd4, 0x01f04bb4, 0x3ff87b44,
- 0x3ff81896, 0x01fcdb2e, 0x02228924, 0x3ff6e1bf, 0x3ff67534, 0x022f184d, 0x0254c544, 0x3ff520c5,
- 0x3ff4aa5d, 0x02615414, 0x0286fff3, 0x3ff33858, 0x3ff2b813, 0x02938e62, 0x02b93914, 0x3ff12878,
- 0x3ff09e56, 0x02c5c71a, 0x02eb7086, 0x3feef126, 0x3fee5d28, 0x02f7fe1c, 0x031da62b, 0x3fec9265,
- 0x3febf48b, 0x032a3349, 0x034fd9e5, 0x3fea0c35, 0x3fe96480, 0x035c6682, 0x03820b93, 0x3fe75e98,
- 0x3fe6ad08, 0x038e97a9, 0x03b43b17, 0x3fe48990, 0x3fe3ce26, 0x03c0c69e, 0x03e66852, 0x3fe18d1f,
- 0x3fe0c7da, 0x03f2f342, 0x04189326, 0x3fde6945, 0x3fdd9a27, 0x04251d77, 0x044abb73, 0x3fdb1e06,
- 0x3fda450f, 0x0457451d, 0x047ce11a, 0x3fd7ab64, 0x3fd6c894, 0x04896a16, 0x04af03fc, 0x3fd4115f,
- 0x3fd324b7, 0x04bb8c42, 0x04e123fa, 0x3fd04ffc, 0x3fcf597c, 0x04edab83, 0x051340f6, 0x3fcc673b,
- 0x3fcb66e4, 0x051fc7b9, 0x05455ad1, 0x3fc8571f, 0x3fc74cf3, 0x0551e0c7, 0x0577716b, 0x3fc41fac,
- 0x3fc30baa, 0x0583f68c, 0x05a984a6, 0x3fbfc0e3, 0x3fbea30c, 0x05b608eb, 0x05db9463, 0x3fbb3ac7,
- 0x3fba131b, 0x05e817c3, 0x060da083, 0x3fb68d5b, 0x3fb55bdc, 0x061a22f7, 0x063fa8e7, 0x3fb1b8a2,
- 0x3fb07d50, 0x064c2a67, 0x0671ad71, 0x3facbc9f, 0x3fab777b, 0x067e2df5, 0x06a3ae00, 0x3fa79954,
- 0x3fa64a5f, 0x06b02d81, 0x06d5aa77, 0x3fa24ec6, 0x3fa0f600, 0x06e228ee, 0x0707a2b7, 0x3f9cdcf7,
- 0x3f9b7a62, 0x0714201b, 0x073996a1, 0x3f9743eb, 0x3f95d787, 0x074612eb, 0x076b8616, 0x3f9183a5,
- 0x3f900d72, 0x0778013d, 0x079d70f7, 0x3f8b9c28, 0x3f8a1c29, 0x07a9eaf5, 0x07cf5726, 0x3f858d79,
- 0x3f8403ae, 0x07dbcff2, 0x08013883, 0x3f7f579b, 0x3f7dc405, 0x080db016, 0x083314f1, 0x3f78fa92,
- 0x3f775d31, 0x083f8b43, 0x0864ec4f, 0x3f727661, 0x3f70cf38, 0x08716159, 0x0896be80, 0x3f6bcb0e,
- 0x3f6a1a1c, 0x08a3323a, 0x08c88b65, 0x3f64f89b, 0x3f633de2, 0x08d4fdc6, 0x08fa52de, 0x3f5dff0e,
- 0x3f5c3a8f, 0x0906c3e0, 0x092c14ce, 0x3f56de6a, 0x3f551026, 0x09388469, 0x095dd116, 0x3f4f96b4,
- 0x3f4dbeac, 0x096a3f42, 0x098f8796, 0x3f4827f0, 0x3f464626, 0x099bf44c, 0x09c13831, 0x3f409223,
- 0x3f3ea697, 0x09cda368, 0x09f2e2c7, 0x3f38d552, 0x3f36e006, 0x09ff4c78, 0x0a24873a, 0x3f30f181,
- 0x3f2ef276, 0x0a30ef5e, 0x0a56256c, 0x3f28e6b6, 0x3f26ddec, 0x0a628bfa, 0x0a87bd3d, 0x3f20b4f5,
- 0x3f1ea26e, 0x0a94222f, 0x0ab94e8f, 0x3f185c43, 0x3f164001, 0x0ac5b1dc, 0x0aead944, 0x3f0fdca5,
- 0x3f0db6a9, 0x0af73ae5, 0x0b1c5d3d, 0x3f073621, 0x3f05066d, 0x0b28bd2a, 0x0b4dda5c, 0x3efe68bc,
- 0x3efc2f50, 0x0b5a388d, 0x0b7f5081, 0x3ef5747b, 0x3ef3315a, 0x0b8bacf0, 0x0bb0bf8f, 0x3eec5965,
- 0x3eea0c8e, 0x0bbd1a33, 0x0be22766, 0x3ee3177e, 0x3ee0c0f4, 0x0bee8038, 0x0c1387e9, 0x3ed9aecc,
- 0x3ed74e91, 0x0c1fdee1, 0x0c44e0f9, 0x3ed01f55, 0x3ecdb56a, 0x0c513610, 0x0c763278, 0x3ec66920,
- 0x3ec3f585, 0x0c8285a5, 0x0ca77c47, 0x3ebc8c31, 0x3eba0ee9, 0x0cb3cd84, 0x0cd8be47, 0x3eb2888f,
- 0x3eb0019c, 0x0ce50d8c, 0x0d09f85b, 0x3ea85e41, 0x3ea5cda3, 0x0d1645a0, 0x0d3b2a64, 0x3e9e0d4c,
- 0x3e9b7306, 0x0d4775a1, 0x0d6c5443, 0x3e9395b7, 0x3e90f1ca, 0x0d789d71, 0x0d9d75db, 0x3e88f788,
- 0x3e8649f5, 0x0da9bcf2, 0x0dce8f0d, 0x3e7e32c6, 0x3e7b7b90, 0x0ddad406, 0x0dff9fba, 0x3e734778,
- 0x3e70869f, 0x0e0be28e, 0x0e30a7c5, 0x3e6835a4, 0x3e656b2b, 0x0e3ce86b, 0x0e61a70f, 0x3e5cfd51,
- 0x3e5a2939, 0x0e6de580, 0x0e929d7a, 0x3e519e86, 0x3e4ec0d1, 0x0e9ed9af, 0x0ec38ae8, 0x3e46194a,
- 0x3e4331fa, 0x0ecfc4d9, 0x0ef46f3b, 0x3e3a6da4, 0x3e377cbb, 0x0f00a6df, 0x0f254a53, 0x3e2e9b9c,
- 0x3e2ba11b, 0x0f317fa5, 0x0f561c15, 0x3e22a338, 0x3e1f9f21, 0x0f624f0c, 0x0f86e460, 0x3e168480,
- 0x3e1376d5, 0x0f9314f5, 0x0fb7a317, 0x3e0a3f7b, 0x3e07283f, 0x0fc3d143, 0x0fe8581d, 0x3dfdd432,
- 0x3dfab365, 0x0ff483d7, 0x10190352, 0x3df142ab, 0x3dee1851, 0x10252c94, 0x1049a49a, 0x3de48aef,
- 0x3de15708, 0x1055cb5b, 0x107a3bd5, 0x3dd7ad05, 0x3dd46f94, 0x1086600e, 0x10aac8e6, 0x3dcaa8f5,
- 0x3dc761fc, 0x10b6ea90, 0x10db4baf, 0x3dbd7ec7, 0x3dba2e48, 0x10e76ac3, 0x110bc413, 0x3db02e84,
- 0x3dacd481, 0x1117e088, 0x113c31f3, 0x3da2b834, 0x3d9f54af, 0x11484bc2, 0x116c9531, 0x3d951bde,
- 0x3d91aed9, 0x1178ac53, 0x119cedaf, 0x3d87598c, 0x3d83e309, 0x11a9021d, 0x11cd3b50, 0x3d797145,
- 0x3d75f147, 0x11d94d02, 0x11fd7df6, 0x3d6b6313, 0x3d67d99b, 0x12098ce5, 0x122db583, 0x3d5d2efe,
- 0x3d599c0e, 0x1239c1a7, 0x125de1da, 0x3d4ed50f, 0x3d4b38aa, 0x1269eb2b, 0x128e02dc, 0x3d40554e,
- 0x3d3caf76, 0x129a0954, 0x12be186c, 0x3d31afc5, 0x3d2e007c, 0x12ca1c03, 0x12ee226c, 0x3d22e47c,
- 0x3d1f2bc5, 0x12fa231b, 0x131e20c0, 0x3d13f37e, 0x3d10315a, 0x132a1e7e, 0x134e1348, 0x3d04dcd2,
- 0x3d011145, 0x135a0e0e, 0x137df9e7, 0x3cf5a082, 0x3cf1cb8e, 0x1389f1af, 0x13add481, 0x3ce63e98,
- 0x3ce2603f, 0x13b9c943, 0x13dda2f7, 0x3cd6b71e, 0x3cd2cf62, 0x13e994ab, 0x140d652c, 0x3cc70a1c,
- 0x3cc318ff, 0x141953cb, 0x143d1b02, 0x3cb7379c, 0x3cb33d22, 0x14490685, 0x146cc45c, 0x3ca73fa9,
- 0x3ca33bd3, 0x1478acbc, 0x149c611d, 0x3c97224c, 0x3c93151d, 0x14a84652, 0x14cbf127, 0x3c86df8e,
- 0x3c82c909, 0x14d7d32a, 0x14fb745e, 0x3c76777b, 0x3c7257a2, 0x15075327, 0x152aeaa3, 0x3c65ea1c,
- 0x3c61c0f1, 0x1536c62b, 0x155a53d9, 0x3c55377b, 0x3c510501, 0x15662c18, 0x1589afe3, 0x3c445fa2,
- 0x3c4023dd, 0x159584d3, 0x15b8fea4, 0x3c33629d, 0x3c2f1d8e, 0x15c4d03e, 0x15e83fff, 0x3c224075,
- 0x3c1df21f, 0x15f40e3a, 0x161773d6, 0x3c10f935, 0x3c0ca19b, 0x16233eac, 0x16469a0d, 0x3bff8ce8,
- 0x3bfb2c0c, 0x16526176, 0x1675b286, 0x3bedfb99, 0x3be9917e, 0x1681767c, 0x16a4bd25, 0x3bdc4552,
- 0x3bd7d1fa, 0x16b07d9f, 0x16d3b9cc, 0x3bca6a1d, 0x3bc5ed8d, 0x16df76c3, 0x1702a85e, 0x3bb86a08,
- 0x3bb3e440, 0x170e61cc, 0x173188be, 0x3ba6451b, 0x3ba1b620, 0x173d3e9b, 0x17605ad0, 0x3b93fb63,
- 0x3b8f6337, 0x176c0d15, 0x178f1e76, 0x3b818ceb, 0x3b7ceb90, 0x179acd1c, 0x17bdd394, 0x3b6ef9be,
- 0x3b6a4f38, 0x17c97e93, 0x17ec7a0d, 0x3b5c41e8, 0x3b578e39, 0x17f8215e, 0x181b11c4, 0x3b496574,
- 0x3b44a8a0, 0x1826b561, 0x18499a9d, 0x3b36646e, 0x3b319e77, 0x18553a7d, 0x1878147a, 0x3b233ee1,
- 0x3b1e6fca, 0x1883b097, 0x18a67f3f, 0x3b0ff4d9, 0x3b0b1ca6, 0x18b21791, 0x18d4dad0, 0x3afc8663,
- 0x3af7a516, 0x18e06f50, 0x1903270f, 0x3ae8f38b, 0x3ae40926, 0x190eb7b7, 0x193163e1, 0x3ad53c5b,
- 0x3ad048e3, 0x193cf0a9, 0x195f9128, 0x3ac160e1, 0x3abc6458, 0x196b1a09, 0x198daec8, 0x3aad6129,
- 0x3aa85b92, 0x199933bb, 0x19bbbca6, 0x3a993d3e, 0x3a942e9d, 0x19c73da3, 0x19e9baa3, 0x3a84f52f,
- 0x3a7fdd86, 0x19f537a4, 0x1a17a8a5, 0x3a708906, 0x3a6b6859, 0x1a2321a2, 0x1a45868e, 0x3a5bf8d1,
- 0x3a56cf23, 0x1a50fb81, 0x1a735442, 0x3a47449c, 0x3a4211f0, 0x1a7ec524, 0x1aa111a6, 0x3a326c74,
- 0x3a2d30cd, 0x1aac7e6f, 0x1acebe9d, 0x3a1d7066, 0x3a182bc8, 0x1ada2746, 0x1afc5b0a, 0x3a08507f,
- 0x3a0302ed, 0x1b07bf8c, 0x1b29e6d2, 0x39f30ccc, 0x39edb649, 0x1b354727, 0x1b5761d8, 0x39dda55a,
- 0x39d845e9, 0x1b62bdf8, 0x1b84cc01, 0x39c81a36, 0x39c2b1da, 0x1b9023e5, 0x1bb22530, 0x39b26b6d,
- 0x39acfa2b, 0x1bbd78d2, 0x1bdf6d4a, 0x399c990d, 0x39971ee7, 0x1beabca1, 0x1c0ca432, 0x3986a324,
- 0x3981201e, 0x1c17ef39, 0x1c39c9cd, 0x397089bf, 0x396afddc, 0x1c45107c, 0x1c66ddfe, 0x395a4ceb,
- 0x3954b82e, 0x1c72204f, 0x1c93e0ab, 0x3943ecb6, 0x393e4f23, 0x1c9f1e96, 0x1cc0d1b6, 0x392d692f,
- 0x3927c2c9, 0x1ccc0b35, 0x1cedb106, 0x3916c262, 0x3911132d, 0x1cf8e611, 0x1d1a7e7d, 0x38fff85e,
- 0x38fa405e, 0x1d25af0d, 0x1d473a00, 0x38e90b31, 0x38e34a69, 0x1d52660f, 0x1d73e374, 0x38d1fae9,
- 0x38cc315d, 0x1d7f0afb, 0x1da07abc, 0x38bac795, 0x38b4f547, 0x1dab9db5, 0x1dccffbf, 0x38a37142,
- 0x389d9637, 0x1dd81e21, 0x1df9725f, 0x388bf7ff, 0x3886143b, 0x1e048c24, 0x1e25d282, 0x38745bdb,
- 0x386e6f60, 0x1e30e7a4, 0x1e52200c, 0x385c9ce3, 0x3856a7b6, 0x1e5d3084, 0x1e7e5ae2, 0x3844bb28,
- 0x383ebd4c, 0x1e8966a8, 0x1eaa82e9, 0x382cb6b7, 0x3826b030, 0x1eb589f7, 0x1ed69805, 0x38148f9f,
- 0x380e8071, 0x1ee19a54, 0x1f029a1c, 0x37fc45ef, 0x37f62e1d, 0x1f0d97a5, 0x1f2e8911, 0x37e3d9b7,
- 0x37ddb945, 0x1f3981ce, 0x1f5a64cb, 0x37cb4b04, 0x37c521f6, 0x1f6558b5, 0x1f862d2d, 0x37b299e7,
- 0x37ac6841, 0x1f911c3d, 0x1fb1e21d, 0x3799c66f, 0x37938c34, 0x1fbccc4d, 0x1fdd8381, 0x3780d0aa,
- 0x377a8ddf, 0x1fe868c8, 0x2009113c, 0x3767b8a9, 0x37616d51, 0x2013f196, 0x20348b35, 0x374e7e7b,
- 0x37482a9a, 0x203f6699, 0x205ff14f, 0x3735222f, 0x372ec5c9, 0x206ac7b8, 0x208b4372, 0x371ba3d4,
- 0x37153eee, 0x209614d9, 0x20b68181, 0x3702037c, 0x36fb9618, 0x20c14ddf, 0x20e1ab63, 0x36e84135,
- 0x36e1cb58, 0x20ec72b1, 0x210cc0fc, 0x36ce5d10, 0x36c7debd, 0x21178334, 0x2137c232, 0x36b4571b,
- 0x36add058, 0x21427f4d, 0x2162aeea, 0x369a2f69, 0x3693a038, 0x216d66e2, 0x218d870b, 0x367fe608,
- 0x36794e6e, 0x219839d8, 0x21b84a79, 0x36657b08, 0x365edb09, 0x21c2f815, 0x21e2f91a, 0x364aee7b,
- 0x3644461b, 0x21eda17f, 0x220d92d4, 0x36304070, 0x36298fb4, 0x221835fb, 0x2238178d, 0x361570f8,
- 0x360eb7e3, 0x2242b56f, 0x22628729, 0x35fa8023, 0x35f3beba, 0x226d1fc1, 0x228ce191, 0x35df6e03,
- 0x35d8a449, 0x229774d7, 0x22b726a8, 0x35c43aa7, 0x35bd68a1, 0x22c1b496, 0x22e15655, 0x35a8e621,
- 0x35a20bd3, 0x22ebdee5, 0x230b707e, 0x358d7081, 0x35868def, 0x2315f3a8, 0x23357509, 0x3571d9d9,
- 0x356aef08, 0x233ff2c8, 0x235f63dc, 0x35562239, 0x354f2f2c, 0x2369dc29, 0x23893cdd, 0x353a49b2,
- 0x35334e6f, 0x2393afb2, 0x23b2fff3, 0x351e5056, 0x35174ce0, 0x23bd6d48, 0x23dcad03, 0x35023636,
- 0x34fb2a92, 0x23e714d3, 0x240643f4, 0x34e5fb63, 0x34dee795, 0x2410a639, 0x242fc4ad, 0x34c99fef,
- 0x34c283fb, 0x243a215f, 0x24592f13, 0x34ad23eb, 0x34a5ffd5, 0x2463862c, 0x2482830d, 0x34908768,
- 0x34895b36, 0x248cd487, 0x24abc082, 0x3473ca79, 0x346c962f, 0x24b60c57, 0x24d4e757, 0x3456ed2f,
- 0x344fb0d1, 0x24df2d81, 0x24fdf775, 0x3439ef9c, 0x3432ab2e, 0x250837ed, 0x2526f0c1, 0x341cd1d2,
- 0x34158559, 0x25312b81, 0x254fd323, 0x33ff93e2, 0x33f83f62, 0x255a0823, 0x25789e80, 0x33e235df,
- 0x33dad95e, 0x2582cdbc, 0x25a152c0, 0x33c4b7db, 0x33bd535c, 0x25ab7c30, 0x25c9efca, 0x33a719e8,
- 0x339fad70, 0x25d41369, 0x25f27584, 0x33895c18, 0x3381e7ac, 0x25fc934b, 0x261ae3d6, 0x336b7e7e,
- 0x33640223, 0x2624fbbf, 0x26433aa7, 0x334d812d, 0x3345fce6, 0x264d4cac, 0x266b79dd, 0x332f6435,
- 0x3327d808, 0x267585f8, 0x2693a161, 0x331127ab, 0x3309939c, 0x269da78b, 0x26bbb119, 0x32f2cba1,
- 0x32eb2fb5, 0x26c5b14c, 0x26e3a8ec, 0x32d45029, 0x32ccac64, 0x26eda322, 0x270b88c2, 0x32b5b557,
- 0x32ae09be, 0x27157cf5, 0x27335082, 0x3296fb3d, 0x328f47d5, 0x273d3eac, 0x275b0014, 0x327821ee,
- 0x327066bc, 0x2764e82f, 0x27829760, 0x3259297d, 0x32516686, 0x278c7965, 0x27aa164c, 0x323a11fe,
- 0x32324746, 0x27b3f235, 0x27d17cc1, 0x321adb83, 0x3213090f, 0x27db5288, 0x27f8caa5, 0x31fb8620,
- 0x31f3abf5, 0x28029a45, 0x281fffe2, 0x31dc11e8, 0x31d4300b, 0x2829c954, 0x28471c5e, 0x31bc7eee,
- 0x31b49564, 0x2850df9d, 0x286e2002, 0x319ccd46, 0x3194dc14, 0x2877dd07, 0x28950ab6, 0x317cfd04,
- 0x3175042e, 0x289ec17a, 0x28bbdc61, 0x315d0e3b, 0x31550dc6, 0x28c58cdf, 0x28e294eb, 0x313d00ff,
- 0x3134f8f1, 0x28ec3f1e, 0x2909343e, 0x311cd564, 0x3114c5c0, 0x2912d81f, 0x292fba40, 0x30fc8b7d,
- 0x30f47449, 0x293957c9, 0x295626da, 0x30dc235e, 0x30d404a0, 0x295fbe06, 0x297c79f5, 0x30bb9d1c,
- 0x30b376d8, 0x29860abd, 0x29a2b378, 0x309af8ca, 0x3092cb05, 0x29ac3dd7, 0x29c8d34d, 0x307a367c,
- 0x3072013c, 0x29d2573c, 0x29eed95b, 0x30595648, 0x30511991, 0x29f856d5, 0x2a14c58b, 0x30385840,
- 0x30301418, 0x2a1e3c8a, 0x2a3a97c7, 0x30173c7a, 0x300ef0e5, 0x2a440844, 0x2a604ff5, 0x2ff6030a,
- 0x2fedb00d, 0x2a69b9ec, 0x2a85ee00, 0x2fd4ac04, 0x2fcc51a5, 0x2a8f516b, 0x2aab71d0, 0x2fb3377c,
- 0x2faad5c1, 0x2ab4cea9, 0x2ad0db4e, 0x2f91a589, 0x2f893c75, 0x2ada318e, 0x2af62a63, 0x2f6ff63d,
- 0x2f6785d7, 0x2aff7a05, 0x2b1b5ef8, 0x2f4e29af, 0x2f45b1fb, 0x2b24a7f6, 0x2b4078f5, 0x2f2c3ff2,
- 0x2f23c0f6, 0x2b49bb4a, 0x2b657844, 0x2f0a391d, 0x2f01b2de, 0x2b6eb3ea, 0x2b8a5cce, 0x2ee81543,
- 0x2edf87c6, 0x2b9391c0, 0x2baf267d, 0x2ec5d479, 0x2ebd3fc4, 0x2bb854b4, 0x2bd3d53a, 0x2ea376d6,
- 0x2e9adaee, 0x2bdcfcb0, 0x2bf868ed, 0x2e80fc6e, 0x2e785958, 0x2c01899e, 0x2c1ce181, 0x2e5e6556,
- 0x2e55bb17, 0x2c25fb66, 0x2c413edf, 0x2e3bb1a4, 0x2e330042, 0x2c4a51f3, 0x2c6580f1, 0x2e18e16d,
- 0x2e1028ed, 0x2c6e8d2e, 0x2c89a79f, 0x2df5f4c7, 0x2ded352f, 0x2c92ad01, 0x2cadb2d5, 0x2dd2ebc7,
- 0x2dca251c, 0x2cb6b155, 0x2cd1a27b, 0x2dafc683, 0x2da6f8ca, 0x2cda9a14, 0x2cf5767c, 0x2d8c8510,
+ 0x3fffffb1, 0x0006487f, 0x002bfb74, 0x3ffff0e3, 0x3fffe705, 0x00388c6e, 0x005e3f4c, 0x3fffba9b,
+ 0x3fffa6de, 0x006ad03b, 0x009082ea, 0x3fff5cd8, 0x3fff3f3c, 0x009d13c5, 0x00c2c62f, 0x3ffed79b,
+ 0x3ffeb021, 0x00cf56ef, 0x00f508fc, 0x3ffe2ae5, 0x3ffdf98c, 0x01019998, 0x01274b31, 0x3ffd56b5,
+ 0x3ffd1b7e, 0x0133dba3, 0x01598cb1, 0x3ffc5b0c, 0x3ffc15f7, 0x01661cf0, 0x018bcd5b, 0x3ffb37ec,
+ 0x3ffae8f9, 0x01985d60, 0x01be0d11, 0x3ff9ed53, 0x3ff99483, 0x01ca9cd4, 0x01f04bb4, 0x3ff87b44,
+ 0x3ff81896, 0x01fcdb2e, 0x02228924, 0x3ff6e1bf, 0x3ff67534, 0x022f184d, 0x0254c544, 0x3ff520c5,
+ 0x3ff4aa5d, 0x02615414, 0x0286fff3, 0x3ff33858, 0x3ff2b813, 0x02938e62, 0x02b93914, 0x3ff12878,
+ 0x3ff09e56, 0x02c5c71a, 0x02eb7086, 0x3feef126, 0x3fee5d28, 0x02f7fe1c, 0x031da62b, 0x3fec9265,
+ 0x3febf48b, 0x032a3349, 0x034fd9e5, 0x3fea0c35, 0x3fe96480, 0x035c6682, 0x03820b93, 0x3fe75e98,
+ 0x3fe6ad08, 0x038e97a9, 0x03b43b17, 0x3fe48990, 0x3fe3ce26, 0x03c0c69e, 0x03e66852, 0x3fe18d1f,
+ 0x3fe0c7da, 0x03f2f342, 0x04189326, 0x3fde6945, 0x3fdd9a27, 0x04251d77, 0x044abb73, 0x3fdb1e06,
+ 0x3fda450f, 0x0457451d, 0x047ce11a, 0x3fd7ab64, 0x3fd6c894, 0x04896a16, 0x04af03fc, 0x3fd4115f,
+ 0x3fd324b7, 0x04bb8c42, 0x04e123fa, 0x3fd04ffc, 0x3fcf597c, 0x04edab83, 0x051340f6, 0x3fcc673b,
+ 0x3fcb66e4, 0x051fc7b9, 0x05455ad1, 0x3fc8571f, 0x3fc74cf3, 0x0551e0c7, 0x0577716b, 0x3fc41fac,
+ 0x3fc30baa, 0x0583f68c, 0x05a984a6, 0x3fbfc0e3, 0x3fbea30c, 0x05b608eb, 0x05db9463, 0x3fbb3ac7,
+ 0x3fba131b, 0x05e817c3, 0x060da083, 0x3fb68d5b, 0x3fb55bdc, 0x061a22f7, 0x063fa8e7, 0x3fb1b8a2,
+ 0x3fb07d50, 0x064c2a67, 0x0671ad71, 0x3facbc9f, 0x3fab777b, 0x067e2df5, 0x06a3ae00, 0x3fa79954,
+ 0x3fa64a5f, 0x06b02d81, 0x06d5aa77, 0x3fa24ec6, 0x3fa0f600, 0x06e228ee, 0x0707a2b7, 0x3f9cdcf7,
+ 0x3f9b7a62, 0x0714201b, 0x073996a1, 0x3f9743eb, 0x3f95d787, 0x074612eb, 0x076b8616, 0x3f9183a5,
+ 0x3f900d72, 0x0778013d, 0x079d70f7, 0x3f8b9c28, 0x3f8a1c29, 0x07a9eaf5, 0x07cf5726, 0x3f858d79,
+ 0x3f8403ae, 0x07dbcff2, 0x08013883, 0x3f7f579b, 0x3f7dc405, 0x080db016, 0x083314f1, 0x3f78fa92,
+ 0x3f775d31, 0x083f8b43, 0x0864ec4f, 0x3f727661, 0x3f70cf38, 0x08716159, 0x0896be80, 0x3f6bcb0e,
+ 0x3f6a1a1c, 0x08a3323a, 0x08c88b65, 0x3f64f89b, 0x3f633de2, 0x08d4fdc6, 0x08fa52de, 0x3f5dff0e,
+ 0x3f5c3a8f, 0x0906c3e0, 0x092c14ce, 0x3f56de6a, 0x3f551026, 0x09388469, 0x095dd116, 0x3f4f96b4,
+ 0x3f4dbeac, 0x096a3f42, 0x098f8796, 0x3f4827f0, 0x3f464626, 0x099bf44c, 0x09c13831, 0x3f409223,
+ 0x3f3ea697, 0x09cda368, 0x09f2e2c7, 0x3f38d552, 0x3f36e006, 0x09ff4c78, 0x0a24873a, 0x3f30f181,
+ 0x3f2ef276, 0x0a30ef5e, 0x0a56256c, 0x3f28e6b6, 0x3f26ddec, 0x0a628bfa, 0x0a87bd3d, 0x3f20b4f5,
+ 0x3f1ea26e, 0x0a94222f, 0x0ab94e8f, 0x3f185c43, 0x3f164001, 0x0ac5b1dc, 0x0aead944, 0x3f0fdca5,
+ 0x3f0db6a9, 0x0af73ae5, 0x0b1c5d3d, 0x3f073621, 0x3f05066d, 0x0b28bd2a, 0x0b4dda5c, 0x3efe68bc,
+ 0x3efc2f50, 0x0b5a388d, 0x0b7f5081, 0x3ef5747b, 0x3ef3315a, 0x0b8bacf0, 0x0bb0bf8f, 0x3eec5965,
+ 0x3eea0c8e, 0x0bbd1a33, 0x0be22766, 0x3ee3177e, 0x3ee0c0f4, 0x0bee8038, 0x0c1387e9, 0x3ed9aecc,
+ 0x3ed74e91, 0x0c1fdee1, 0x0c44e0f9, 0x3ed01f55, 0x3ecdb56a, 0x0c513610, 0x0c763278, 0x3ec66920,
+ 0x3ec3f585, 0x0c8285a5, 0x0ca77c47, 0x3ebc8c31, 0x3eba0ee9, 0x0cb3cd84, 0x0cd8be47, 0x3eb2888f,
+ 0x3eb0019c, 0x0ce50d8c, 0x0d09f85b, 0x3ea85e41, 0x3ea5cda3, 0x0d1645a0, 0x0d3b2a64, 0x3e9e0d4c,
+ 0x3e9b7306, 0x0d4775a1, 0x0d6c5443, 0x3e9395b7, 0x3e90f1ca, 0x0d789d71, 0x0d9d75db, 0x3e88f788,
+ 0x3e8649f5, 0x0da9bcf2, 0x0dce8f0d, 0x3e7e32c6, 0x3e7b7b90, 0x0ddad406, 0x0dff9fba, 0x3e734778,
+ 0x3e70869f, 0x0e0be28e, 0x0e30a7c5, 0x3e6835a4, 0x3e656b2b, 0x0e3ce86b, 0x0e61a70f, 0x3e5cfd51,
+ 0x3e5a2939, 0x0e6de580, 0x0e929d7a, 0x3e519e86, 0x3e4ec0d1, 0x0e9ed9af, 0x0ec38ae8, 0x3e46194a,
+ 0x3e4331fa, 0x0ecfc4d9, 0x0ef46f3b, 0x3e3a6da4, 0x3e377cbb, 0x0f00a6df, 0x0f254a53, 0x3e2e9b9c,
+ 0x3e2ba11b, 0x0f317fa5, 0x0f561c15, 0x3e22a338, 0x3e1f9f21, 0x0f624f0c, 0x0f86e460, 0x3e168480,
+ 0x3e1376d5, 0x0f9314f5, 0x0fb7a317, 0x3e0a3f7b, 0x3e07283f, 0x0fc3d143, 0x0fe8581d, 0x3dfdd432,
+ 0x3dfab365, 0x0ff483d7, 0x10190352, 0x3df142ab, 0x3dee1851, 0x10252c94, 0x1049a49a, 0x3de48aef,
+ 0x3de15708, 0x1055cb5b, 0x107a3bd5, 0x3dd7ad05, 0x3dd46f94, 0x1086600e, 0x10aac8e6, 0x3dcaa8f5,
+ 0x3dc761fc, 0x10b6ea90, 0x10db4baf, 0x3dbd7ec7, 0x3dba2e48, 0x10e76ac3, 0x110bc413, 0x3db02e84,
+ 0x3dacd481, 0x1117e088, 0x113c31f3, 0x3da2b834, 0x3d9f54af, 0x11484bc2, 0x116c9531, 0x3d951bde,
+ 0x3d91aed9, 0x1178ac53, 0x119cedaf, 0x3d87598c, 0x3d83e309, 0x11a9021d, 0x11cd3b50, 0x3d797145,
+ 0x3d75f147, 0x11d94d02, 0x11fd7df6, 0x3d6b6313, 0x3d67d99b, 0x12098ce5, 0x122db583, 0x3d5d2efe,
+ 0x3d599c0e, 0x1239c1a7, 0x125de1da, 0x3d4ed50f, 0x3d4b38aa, 0x1269eb2b, 0x128e02dc, 0x3d40554e,
+ 0x3d3caf76, 0x129a0954, 0x12be186c, 0x3d31afc5, 0x3d2e007c, 0x12ca1c03, 0x12ee226c, 0x3d22e47c,
+ 0x3d1f2bc5, 0x12fa231b, 0x131e20c0, 0x3d13f37e, 0x3d10315a, 0x132a1e7e, 0x134e1348, 0x3d04dcd2,
+ 0x3d011145, 0x135a0e0e, 0x137df9e7, 0x3cf5a082, 0x3cf1cb8e, 0x1389f1af, 0x13add481, 0x3ce63e98,
+ 0x3ce2603f, 0x13b9c943, 0x13dda2f7, 0x3cd6b71e, 0x3cd2cf62, 0x13e994ab, 0x140d652c, 0x3cc70a1c,
+ 0x3cc318ff, 0x141953cb, 0x143d1b02, 0x3cb7379c, 0x3cb33d22, 0x14490685, 0x146cc45c, 0x3ca73fa9,
+ 0x3ca33bd3, 0x1478acbc, 0x149c611d, 0x3c97224c, 0x3c93151d, 0x14a84652, 0x14cbf127, 0x3c86df8e,
+ 0x3c82c909, 0x14d7d32a, 0x14fb745e, 0x3c76777b, 0x3c7257a2, 0x15075327, 0x152aeaa3, 0x3c65ea1c,
+ 0x3c61c0f1, 0x1536c62b, 0x155a53d9, 0x3c55377b, 0x3c510501, 0x15662c18, 0x1589afe3, 0x3c445fa2,
+ 0x3c4023dd, 0x159584d3, 0x15b8fea4, 0x3c33629d, 0x3c2f1d8e, 0x15c4d03e, 0x15e83fff, 0x3c224075,
+ 0x3c1df21f, 0x15f40e3a, 0x161773d6, 0x3c10f935, 0x3c0ca19b, 0x16233eac, 0x16469a0d, 0x3bff8ce8,
+ 0x3bfb2c0c, 0x16526176, 0x1675b286, 0x3bedfb99, 0x3be9917e, 0x1681767c, 0x16a4bd25, 0x3bdc4552,
+ 0x3bd7d1fa, 0x16b07d9f, 0x16d3b9cc, 0x3bca6a1d, 0x3bc5ed8d, 0x16df76c3, 0x1702a85e, 0x3bb86a08,
+ 0x3bb3e440, 0x170e61cc, 0x173188be, 0x3ba6451b, 0x3ba1b620, 0x173d3e9b, 0x17605ad0, 0x3b93fb63,
+ 0x3b8f6337, 0x176c0d15, 0x178f1e76, 0x3b818ceb, 0x3b7ceb90, 0x179acd1c, 0x17bdd394, 0x3b6ef9be,
+ 0x3b6a4f38, 0x17c97e93, 0x17ec7a0d, 0x3b5c41e8, 0x3b578e39, 0x17f8215e, 0x181b11c4, 0x3b496574,
+ 0x3b44a8a0, 0x1826b561, 0x18499a9d, 0x3b36646e, 0x3b319e77, 0x18553a7d, 0x1878147a, 0x3b233ee1,
+ 0x3b1e6fca, 0x1883b097, 0x18a67f3f, 0x3b0ff4d9, 0x3b0b1ca6, 0x18b21791, 0x18d4dad0, 0x3afc8663,
+ 0x3af7a516, 0x18e06f50, 0x1903270f, 0x3ae8f38b, 0x3ae40926, 0x190eb7b7, 0x193163e1, 0x3ad53c5b,
+ 0x3ad048e3, 0x193cf0a9, 0x195f9128, 0x3ac160e1, 0x3abc6458, 0x196b1a09, 0x198daec8, 0x3aad6129,
+ 0x3aa85b92, 0x199933bb, 0x19bbbca6, 0x3a993d3e, 0x3a942e9d, 0x19c73da3, 0x19e9baa3, 0x3a84f52f,
+ 0x3a7fdd86, 0x19f537a4, 0x1a17a8a5, 0x3a708906, 0x3a6b6859, 0x1a2321a2, 0x1a45868e, 0x3a5bf8d1,
+ 0x3a56cf23, 0x1a50fb81, 0x1a735442, 0x3a47449c, 0x3a4211f0, 0x1a7ec524, 0x1aa111a6, 0x3a326c74,
+ 0x3a2d30cd, 0x1aac7e6f, 0x1acebe9d, 0x3a1d7066, 0x3a182bc8, 0x1ada2746, 0x1afc5b0a, 0x3a08507f,
+ 0x3a0302ed, 0x1b07bf8c, 0x1b29e6d2, 0x39f30ccc, 0x39edb649, 0x1b354727, 0x1b5761d8, 0x39dda55a,
+ 0x39d845e9, 0x1b62bdf8, 0x1b84cc01, 0x39c81a36, 0x39c2b1da, 0x1b9023e5, 0x1bb22530, 0x39b26b6d,
+ 0x39acfa2b, 0x1bbd78d2, 0x1bdf6d4a, 0x399c990d, 0x39971ee7, 0x1beabca1, 0x1c0ca432, 0x3986a324,
+ 0x3981201e, 0x1c17ef39, 0x1c39c9cd, 0x397089bf, 0x396afddc, 0x1c45107c, 0x1c66ddfe, 0x395a4ceb,
+ 0x3954b82e, 0x1c72204f, 0x1c93e0ab, 0x3943ecb6, 0x393e4f23, 0x1c9f1e96, 0x1cc0d1b6, 0x392d692f,
+ 0x3927c2c9, 0x1ccc0b35, 0x1cedb106, 0x3916c262, 0x3911132d, 0x1cf8e611, 0x1d1a7e7d, 0x38fff85e,
+ 0x38fa405e, 0x1d25af0d, 0x1d473a00, 0x38e90b31, 0x38e34a69, 0x1d52660f, 0x1d73e374, 0x38d1fae9,
+ 0x38cc315d, 0x1d7f0afb, 0x1da07abc, 0x38bac795, 0x38b4f547, 0x1dab9db5, 0x1dccffbf, 0x38a37142,
+ 0x389d9637, 0x1dd81e21, 0x1df9725f, 0x388bf7ff, 0x3886143b, 0x1e048c24, 0x1e25d282, 0x38745bdb,
+ 0x386e6f60, 0x1e30e7a4, 0x1e52200c, 0x385c9ce3, 0x3856a7b6, 0x1e5d3084, 0x1e7e5ae2, 0x3844bb28,
+ 0x383ebd4c, 0x1e8966a8, 0x1eaa82e9, 0x382cb6b7, 0x3826b030, 0x1eb589f7, 0x1ed69805, 0x38148f9f,
+ 0x380e8071, 0x1ee19a54, 0x1f029a1c, 0x37fc45ef, 0x37f62e1d, 0x1f0d97a5, 0x1f2e8911, 0x37e3d9b7,
+ 0x37ddb945, 0x1f3981ce, 0x1f5a64cb, 0x37cb4b04, 0x37c521f6, 0x1f6558b5, 0x1f862d2d, 0x37b299e7,
+ 0x37ac6841, 0x1f911c3d, 0x1fb1e21d, 0x3799c66f, 0x37938c34, 0x1fbccc4d, 0x1fdd8381, 0x3780d0aa,
+ 0x377a8ddf, 0x1fe868c8, 0x2009113c, 0x3767b8a9, 0x37616d51, 0x2013f196, 0x20348b35, 0x374e7e7b,
+ 0x37482a9a, 0x203f6699, 0x205ff14f, 0x3735222f, 0x372ec5c9, 0x206ac7b8, 0x208b4372, 0x371ba3d4,
+ 0x37153eee, 0x209614d9, 0x20b68181, 0x3702037c, 0x36fb9618, 0x20c14ddf, 0x20e1ab63, 0x36e84135,
+ 0x36e1cb58, 0x20ec72b1, 0x210cc0fc, 0x36ce5d10, 0x36c7debd, 0x21178334, 0x2137c232, 0x36b4571b,
+ 0x36add058, 0x21427f4d, 0x2162aeea, 0x369a2f69, 0x3693a038, 0x216d66e2, 0x218d870b, 0x367fe608,
+ 0x36794e6e, 0x219839d8, 0x21b84a79, 0x36657b08, 0x365edb09, 0x21c2f815, 0x21e2f91a, 0x364aee7b,
+ 0x3644461b, 0x21eda17f, 0x220d92d4, 0x36304070, 0x36298fb4, 0x221835fb, 0x2238178d, 0x361570f8,
+ 0x360eb7e3, 0x2242b56f, 0x22628729, 0x35fa8023, 0x35f3beba, 0x226d1fc1, 0x228ce191, 0x35df6e03,
+ 0x35d8a449, 0x229774d7, 0x22b726a8, 0x35c43aa7, 0x35bd68a1, 0x22c1b496, 0x22e15655, 0x35a8e621,
+ 0x35a20bd3, 0x22ebdee5, 0x230b707e, 0x358d7081, 0x35868def, 0x2315f3a8, 0x23357509, 0x3571d9d9,
+ 0x356aef08, 0x233ff2c8, 0x235f63dc, 0x35562239, 0x354f2f2c, 0x2369dc29, 0x23893cdd, 0x353a49b2,
+ 0x35334e6f, 0x2393afb2, 0x23b2fff3, 0x351e5056, 0x35174ce0, 0x23bd6d48, 0x23dcad03, 0x35023636,
+ 0x34fb2a92, 0x23e714d3, 0x240643f4, 0x34e5fb63, 0x34dee795, 0x2410a639, 0x242fc4ad, 0x34c99fef,
+ 0x34c283fb, 0x243a215f, 0x24592f13, 0x34ad23eb, 0x34a5ffd5, 0x2463862c, 0x2482830d, 0x34908768,
+ 0x34895b36, 0x248cd487, 0x24abc082, 0x3473ca79, 0x346c962f, 0x24b60c57, 0x24d4e757, 0x3456ed2f,
+ 0x344fb0d1, 0x24df2d81, 0x24fdf775, 0x3439ef9c, 0x3432ab2e, 0x250837ed, 0x2526f0c1, 0x341cd1d2,
+ 0x34158559, 0x25312b81, 0x254fd323, 0x33ff93e2, 0x33f83f62, 0x255a0823, 0x25789e80, 0x33e235df,
+ 0x33dad95e, 0x2582cdbc, 0x25a152c0, 0x33c4b7db, 0x33bd535c, 0x25ab7c30, 0x25c9efca, 0x33a719e8,
+ 0x339fad70, 0x25d41369, 0x25f27584, 0x33895c18, 0x3381e7ac, 0x25fc934b, 0x261ae3d6, 0x336b7e7e,
+ 0x33640223, 0x2624fbbf, 0x26433aa7, 0x334d812d, 0x3345fce6, 0x264d4cac, 0x266b79dd, 0x332f6435,
+ 0x3327d808, 0x267585f8, 0x2693a161, 0x331127ab, 0x3309939c, 0x269da78b, 0x26bbb119, 0x32f2cba1,
+ 0x32eb2fb5, 0x26c5b14c, 0x26e3a8ec, 0x32d45029, 0x32ccac64, 0x26eda322, 0x270b88c2, 0x32b5b557,
+ 0x32ae09be, 0x27157cf5, 0x27335082, 0x3296fb3d, 0x328f47d5, 0x273d3eac, 0x275b0014, 0x327821ee,
+ 0x327066bc, 0x2764e82f, 0x27829760, 0x3259297d, 0x32516686, 0x278c7965, 0x27aa164c, 0x323a11fe,
+ 0x32324746, 0x27b3f235, 0x27d17cc1, 0x321adb83, 0x3213090f, 0x27db5288, 0x27f8caa5, 0x31fb8620,
+ 0x31f3abf5, 0x28029a45, 0x281fffe2, 0x31dc11e8, 0x31d4300b, 0x2829c954, 0x28471c5e, 0x31bc7eee,
+ 0x31b49564, 0x2850df9d, 0x286e2002, 0x319ccd46, 0x3194dc14, 0x2877dd07, 0x28950ab6, 0x317cfd04,
+ 0x3175042e, 0x289ec17a, 0x28bbdc61, 0x315d0e3b, 0x31550dc6, 0x28c58cdf, 0x28e294eb, 0x313d00ff,
+ 0x3134f8f1, 0x28ec3f1e, 0x2909343e, 0x311cd564, 0x3114c5c0, 0x2912d81f, 0x292fba40, 0x30fc8b7d,
+ 0x30f47449, 0x293957c9, 0x295626da, 0x30dc235e, 0x30d404a0, 0x295fbe06, 0x297c79f5, 0x30bb9d1c,
+ 0x30b376d8, 0x29860abd, 0x29a2b378, 0x309af8ca, 0x3092cb05, 0x29ac3dd7, 0x29c8d34d, 0x307a367c,
+ 0x3072013c, 0x29d2573c, 0x29eed95b, 0x30595648, 0x30511991, 0x29f856d5, 0x2a14c58b, 0x30385840,
+ 0x30301418, 0x2a1e3c8a, 0x2a3a97c7, 0x30173c7a, 0x300ef0e5, 0x2a440844, 0x2a604ff5, 0x2ff6030a,
+ 0x2fedb00d, 0x2a69b9ec, 0x2a85ee00, 0x2fd4ac04, 0x2fcc51a5, 0x2a8f516b, 0x2aab71d0, 0x2fb3377c,
+ 0x2faad5c1, 0x2ab4cea9, 0x2ad0db4e, 0x2f91a589, 0x2f893c75, 0x2ada318e, 0x2af62a63, 0x2f6ff63d,
+ 0x2f6785d7, 0x2aff7a05, 0x2b1b5ef8, 0x2f4e29af, 0x2f45b1fb, 0x2b24a7f6, 0x2b4078f5, 0x2f2c3ff2,
+ 0x2f23c0f6, 0x2b49bb4a, 0x2b657844, 0x2f0a391d, 0x2f01b2de, 0x2b6eb3ea, 0x2b8a5cce, 0x2ee81543,
+ 0x2edf87c6, 0x2b9391c0, 0x2baf267d, 0x2ec5d479, 0x2ebd3fc4, 0x2bb854b4, 0x2bd3d53a, 0x2ea376d6,
+ 0x2e9adaee, 0x2bdcfcb0, 0x2bf868ed, 0x2e80fc6e, 0x2e785958, 0x2c01899e, 0x2c1ce181, 0x2e5e6556,
+ 0x2e55bb17, 0x2c25fb66, 0x2c413edf, 0x2e3bb1a4, 0x2e330042, 0x2c4a51f3, 0x2c6580f1, 0x2e18e16d,
+ 0x2e1028ed, 0x2c6e8d2e, 0x2c89a79f, 0x2df5f4c7, 0x2ded352f, 0x2c92ad01, 0x2cadb2d5, 0x2dd2ebc7,
+ 0x2dca251c, 0x2cb6b155, 0x2cd1a27b, 0x2dafc683, 0x2da6f8ca, 0x2cda9a14, 0x2cf5767c, 0x2d8c8510,
0x2d83b04f, 0x2cfe6728, 0x2d192ec1, 0x2d692784, 0x2d604bc0, 0x2d22187a, 0x2d3ccb34, 0x2d45adf6
};
const int twidTab512[8*6 + 32*6 + 128*6] = {
- 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x3b20d79e, 0x187de2a6,
- 0x3ec52f9f, 0x0c7c5c1e, 0x3536cc52, 0x238e7673, 0x2d413ccc, 0x2d413ccc, 0x3b20d79e, 0x187de2a6,
- 0x187de2a6, 0x3b20d79e, 0x187de2a6, 0x3b20d79e, 0x3536cc52, 0x238e7673, 0xf383a3e2, 0x3ec52f9f,
- 0x00000000, 0x40000000, 0x2d413ccc, 0x2d413ccc, 0xd2bec334, 0x2d413ccc, 0xe7821d5a, 0x3b20d79e,
- 0x238e7673, 0x3536cc52, 0xc13ad061, 0x0c7c5c1e, 0xd2bec334, 0x2d413ccc, 0x187de2a6, 0x3b20d79e,
- 0xc4df2862, 0xe7821d5a, 0xc4df2862, 0x187de2a6, 0x0c7c5c1e, 0x3ec52f9f, 0xdc71898d, 0xcac933ae,
+ 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x3b20d79e, 0x187de2a6,
+ 0x3ec52f9f, 0x0c7c5c1e, 0x3536cc52, 0x238e7673, 0x2d413ccc, 0x2d413ccc, 0x3b20d79e, 0x187de2a6,
+ 0x187de2a6, 0x3b20d79e, 0x187de2a6, 0x3b20d79e, 0x3536cc52, 0x238e7673, 0xf383a3e2, 0x3ec52f9f,
+ 0x00000000, 0x40000000, 0x2d413ccc, 0x2d413ccc, 0xd2bec334, 0x2d413ccc, 0xe7821d5a, 0x3b20d79e,
+ 0x238e7673, 0x3536cc52, 0xc13ad061, 0x0c7c5c1e, 0xd2bec334, 0x2d413ccc, 0x187de2a6, 0x3b20d79e,
+ 0xc4df2862, 0xe7821d5a, 0xc4df2862, 0x187de2a6, 0x0c7c5c1e, 0x3ec52f9f, 0xdc71898d, 0xcac933ae,
- 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x3fb11b47, 0x0645e9af,
- 0x3fec43c6, 0x0323ecbe, 0x3f4eaafe, 0x09640837, 0x3ec52f9f, 0x0c7c5c1e, 0x3fb11b47, 0x0645e9af,
- 0x3d3e82ad, 0x1294062e, 0x3d3e82ad, 0x1294062e, 0x3f4eaafe, 0x09640837, 0x39daf5e8, 0x1b5d1009,
- 0x3b20d79e, 0x187de2a6, 0x3ec52f9f, 0x0c7c5c1e, 0x3536cc52, 0x238e7673, 0x387165e3, 0x1e2b5d38,
- 0x3e14fdf7, 0x0f8cfcbd, 0x2f6bbe44, 0x2afad269, 0x3536cc52, 0x238e7673, 0x3d3e82ad, 0x1294062e,
- 0x2899e64a, 0x317900d6, 0x317900d6, 0x2899e64a, 0x3c424209, 0x158f9a75, 0x20e70f32, 0x36e5068a,
- 0x2d413ccc, 0x2d413ccc, 0x3b20d79e, 0x187de2a6, 0x187de2a6, 0x3b20d79e, 0x2899e64a, 0x317900d6,
- 0x39daf5e8, 0x1b5d1009, 0x0f8cfcbd, 0x3e14fdf7, 0x238e7673, 0x3536cc52, 0x387165e3, 0x1e2b5d38,
- 0x0645e9af, 0x3fb11b47, 0x1e2b5d38, 0x387165e3, 0x36e5068a, 0x20e70f32, 0xfcdc1342, 0x3fec43c6,
- 0x187de2a6, 0x3b20d79e, 0x3536cc52, 0x238e7673, 0xf383a3e2, 0x3ec52f9f, 0x1294062e, 0x3d3e82ad,
- 0x3367c08f, 0x261feff9, 0xea70658b, 0x3c424209, 0x0c7c5c1e, 0x3ec52f9f, 0x317900d6, 0x2899e64a,
- 0xe1d4a2c8, 0x387165e3, 0x0645e9af, 0x3fb11b47, 0x2f6bbe44, 0x2afad269, 0xd9e01007, 0x3367c08f,
- 0x00000000, 0x40000000, 0x2d413ccc, 0x2d413ccc, 0xd2bec334, 0x2d413ccc, 0xf9ba1651, 0x3fb11b47,
- 0x2afad269, 0x2f6bbe44, 0xcc983f71, 0x261feff9, 0xf383a3e2, 0x3ec52f9f, 0x2899e64a, 0x317900d6,
- 0xc78e9a1d, 0x1e2b5d38, 0xed6bf9d2, 0x3d3e82ad, 0x261feff9, 0x3367c08f, 0xc3bdbdf7, 0x158f9a75,
- 0xe7821d5a, 0x3b20d79e, 0x238e7673, 0x3536cc52, 0xc13ad061, 0x0c7c5c1e, 0xe1d4a2c8, 0x387165e3,
- 0x20e70f32, 0x36e5068a, 0xc013bc3a, 0x0323ecbe, 0xdc71898d, 0x3536cc52, 0x1e2b5d38, 0x387165e3,
- 0xc04ee4b9, 0xf9ba1651, 0xd76619b6, 0x317900d6, 0x1b5d1009, 0x39daf5e8, 0xc1eb0209, 0xf0730343,
- 0xd2bec334, 0x2d413ccc, 0x187de2a6, 0x3b20d79e, 0xc4df2862, 0xe7821d5a, 0xce86ff2a, 0x2899e64a,
- 0x158f9a75, 0x3c424209, 0xc91af976, 0xdf18f0ce, 0xcac933ae, 0x238e7673, 0x1294062e, 0x3d3e82ad,
- 0xce86ff2a, 0xd76619b6, 0xc78e9a1d, 0x1e2b5d38, 0x0f8cfcbd, 0x3e14fdf7, 0xd5052d97, 0xd09441bc,
- 0xc4df2862, 0x187de2a6, 0x0c7c5c1e, 0x3ec52f9f, 0xdc71898d, 0xcac933ae, 0xc2c17d53, 0x1294062e,
- 0x09640837, 0x3f4eaafe, 0xe4a2eff7, 0xc6250a18, 0xc13ad061, 0x0c7c5c1e, 0x0645e9af, 0x3fb11b47,
- 0xed6bf9d2, 0xc2c17d53, 0xc04ee4b9, 0x0645e9af, 0x0323ecbe, 0x3fec43c6, 0xf69bf7c9, 0xc0b15502,
+ 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x3fb11b47, 0x0645e9af,
+ 0x3fec43c6, 0x0323ecbe, 0x3f4eaafe, 0x09640837, 0x3ec52f9f, 0x0c7c5c1e, 0x3fb11b47, 0x0645e9af,
+ 0x3d3e82ad, 0x1294062e, 0x3d3e82ad, 0x1294062e, 0x3f4eaafe, 0x09640837, 0x39daf5e8, 0x1b5d1009,
+ 0x3b20d79e, 0x187de2a6, 0x3ec52f9f, 0x0c7c5c1e, 0x3536cc52, 0x238e7673, 0x387165e3, 0x1e2b5d38,
+ 0x3e14fdf7, 0x0f8cfcbd, 0x2f6bbe44, 0x2afad269, 0x3536cc52, 0x238e7673, 0x3d3e82ad, 0x1294062e,
+ 0x2899e64a, 0x317900d6, 0x317900d6, 0x2899e64a, 0x3c424209, 0x158f9a75, 0x20e70f32, 0x36e5068a,
+ 0x2d413ccc, 0x2d413ccc, 0x3b20d79e, 0x187de2a6, 0x187de2a6, 0x3b20d79e, 0x2899e64a, 0x317900d6,
+ 0x39daf5e8, 0x1b5d1009, 0x0f8cfcbd, 0x3e14fdf7, 0x238e7673, 0x3536cc52, 0x387165e3, 0x1e2b5d38,
+ 0x0645e9af, 0x3fb11b47, 0x1e2b5d38, 0x387165e3, 0x36e5068a, 0x20e70f32, 0xfcdc1342, 0x3fec43c6,
+ 0x187de2a6, 0x3b20d79e, 0x3536cc52, 0x238e7673, 0xf383a3e2, 0x3ec52f9f, 0x1294062e, 0x3d3e82ad,
+ 0x3367c08f, 0x261feff9, 0xea70658b, 0x3c424209, 0x0c7c5c1e, 0x3ec52f9f, 0x317900d6, 0x2899e64a,
+ 0xe1d4a2c8, 0x387165e3, 0x0645e9af, 0x3fb11b47, 0x2f6bbe44, 0x2afad269, 0xd9e01007, 0x3367c08f,
+ 0x00000000, 0x40000000, 0x2d413ccc, 0x2d413ccc, 0xd2bec334, 0x2d413ccc, 0xf9ba1651, 0x3fb11b47,
+ 0x2afad269, 0x2f6bbe44, 0xcc983f71, 0x261feff9, 0xf383a3e2, 0x3ec52f9f, 0x2899e64a, 0x317900d6,
+ 0xc78e9a1d, 0x1e2b5d38, 0xed6bf9d2, 0x3d3e82ad, 0x261feff9, 0x3367c08f, 0xc3bdbdf7, 0x158f9a75,
+ 0xe7821d5a, 0x3b20d79e, 0x238e7673, 0x3536cc52, 0xc13ad061, 0x0c7c5c1e, 0xe1d4a2c8, 0x387165e3,
+ 0x20e70f32, 0x36e5068a, 0xc013bc3a, 0x0323ecbe, 0xdc71898d, 0x3536cc52, 0x1e2b5d38, 0x387165e3,
+ 0xc04ee4b9, 0xf9ba1651, 0xd76619b6, 0x317900d6, 0x1b5d1009, 0x39daf5e8, 0xc1eb0209, 0xf0730343,
+ 0xd2bec334, 0x2d413ccc, 0x187de2a6, 0x3b20d79e, 0xc4df2862, 0xe7821d5a, 0xce86ff2a, 0x2899e64a,
+ 0x158f9a75, 0x3c424209, 0xc91af976, 0xdf18f0ce, 0xcac933ae, 0x238e7673, 0x1294062e, 0x3d3e82ad,
+ 0xce86ff2a, 0xd76619b6, 0xc78e9a1d, 0x1e2b5d38, 0x0f8cfcbd, 0x3e14fdf7, 0xd5052d97, 0xd09441bc,
+ 0xc4df2862, 0x187de2a6, 0x0c7c5c1e, 0x3ec52f9f, 0xdc71898d, 0xcac933ae, 0xc2c17d53, 0x1294062e,
+ 0x09640837, 0x3f4eaafe, 0xe4a2eff7, 0xc6250a18, 0xc13ad061, 0x0c7c5c1e, 0x0645e9af, 0x3fb11b47,
+ 0xed6bf9d2, 0xc2c17d53, 0xc04ee4b9, 0x0645e9af, 0x0323ecbe, 0x3fec43c6, 0xf69bf7c9, 0xc0b15502,
- 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x3ffb10c1, 0x0192155f,
- 0x3ffec42d, 0x00c90e8f, 0x3ff4e5df, 0x025b0cae, 0x3fec43c6, 0x0323ecbe, 0x3ffb10c1, 0x0192155f,
- 0x3fd39b5a, 0x04b54824, 0x3fd39b5a, 0x04b54824, 0x3ff4e5df, 0x025b0cae, 0x3f9c2bfa, 0x070de171,
- 0x3fb11b47, 0x0645e9af, 0x3fec43c6, 0x0323ecbe, 0x3f4eaafe, 0x09640837, 0x3f84c8e1, 0x07d59395,
- 0x3fe12acb, 0x03ecadcf, 0x3eeb3347, 0x0bb6ecef, 0x3f4eaafe, 0x09640837, 0x3fd39b5a, 0x04b54824,
- 0x3e71e758, 0x0e05c135, 0x3f0ec9f4, 0x0af10a22, 0x3fc395f9, 0x057db402, 0x3de2f147, 0x104fb80e,
- 0x3ec52f9f, 0x0c7c5c1e, 0x3fb11b47, 0x0645e9af, 0x3d3e82ad, 0x1294062e, 0x3e71e758, 0x0e05c135,
- 0x3f9c2bfa, 0x070de171, 0x3c84d496, 0x14d1e242, 0x3e14fdf7, 0x0f8cfcbd, 0x3f84c8e1, 0x07d59395,
- 0x3bb6276d, 0x17088530, 0x3dae81ce, 0x1111d262, 0x3f6af2e3, 0x089cf867, 0x3ad2c2e7, 0x19372a63,
- 0x3d3e82ad, 0x1294062e, 0x3f4eaafe, 0x09640837, 0x39daf5e8, 0x1b5d1009, 0x3cc511d8, 0x14135c94,
- 0x3f2ff249, 0x0a2abb58, 0x38cf1669, 0x1d79775b, 0x3c424209, 0x158f9a75, 0x3f0ec9f4, 0x0af10a22,
- 0x37af8158, 0x1f8ba4db, 0x3bb6276d, 0x17088530, 0x3eeb3347, 0x0bb6ecef, 0x367c9a7d, 0x2192e09a,
- 0x3b20d79e, 0x187de2a6, 0x3ec52f9f, 0x0c7c5c1e, 0x3536cc52, 0x238e7673, 0x3a8269a2, 0x19ef7943,
- 0x3e9cc076, 0x0d415012, 0x33de87de, 0x257db64b, 0x39daf5e8, 0x1b5d1009, 0x3e71e758, 0x0e05c135,
- 0x32744493, 0x275ff452, 0x392a9642, 0x1cc66e99, 0x3e44a5ee, 0x0ec9a7f2, 0x30f8801f, 0x29348937,
- 0x387165e3, 0x1e2b5d38, 0x3e14fdf7, 0x0f8cfcbd, 0x2f6bbe44, 0x2afad269, 0x37af8158, 0x1f8ba4db,
- 0x3de2f147, 0x104fb80e, 0x2dce88a9, 0x2cb2324b, 0x36e5068a, 0x20e70f32, 0x3dae81ce, 0x1111d262,
- 0x2c216eaa, 0x2e5a106f, 0x361214b0, 0x223d66a8, 0x3d77b191, 0x11d3443f, 0x2a650525, 0x2ff1d9c6,
- 0x3536cc52, 0x238e7673, 0x3d3e82ad, 0x1294062e, 0x2899e64a, 0x317900d6, 0x34534f40, 0x24da0a99,
- 0x3d02f756, 0x135410c2, 0x26c0b162, 0x32eefde9, 0x3367c08f, 0x261feff9, 0x3cc511d8, 0x14135c94,
- 0x24da0a99, 0x34534f40, 0x32744493, 0x275ff452, 0x3c84d496, 0x14d1e242, 0x22e69ac7, 0x35a5793c,
- 0x317900d6, 0x2899e64a, 0x3c424209, 0x158f9a75, 0x20e70f32, 0x36e5068a, 0x30761c17, 0x29cd9577,
- 0x3bfd5cc4, 0x164c7ddd, 0x1edc1952, 0x3811884c, 0x2f6bbe44, 0x2afad269, 0x3bb6276d, 0x17088530,
- 0x1cc66e99, 0x392a9642, 0x2e5a106f, 0x2c216eaa, 0x3b6ca4c4, 0x17c3a931, 0x1aa6c82b, 0x3a2fcee8,
- 0x2d413ccc, 0x2d413ccc, 0x3b20d79e, 0x187de2a6, 0x187de2a6, 0x3b20d79e, 0x2c216eaa, 0x2e5a106f,
- 0x3ad2c2e7, 0x19372a63, 0x164c7ddd, 0x3bfd5cc4, 0x2afad269, 0x2f6bbe44, 0x3a8269a2, 0x19ef7943,
- 0x14135c94, 0x3cc511d8, 0x29cd9577, 0x30761c17, 0x3a2fcee8, 0x1aa6c82b, 0x11d3443f, 0x3d77b191,
- 0x2899e64a, 0x317900d6, 0x39daf5e8, 0x1b5d1009, 0x0f8cfcbd, 0x3e14fdf7, 0x275ff452, 0x32744493,
- 0x3983e1e7, 0x1c1249d8, 0x0d415012, 0x3e9cc076, 0x261feff9, 0x3367c08f, 0x392a9642, 0x1cc66e99,
- 0x0af10a22, 0x3f0ec9f4, 0x24da0a99, 0x34534f40, 0x38cf1669, 0x1d79775b, 0x089cf867, 0x3f6af2e3,
- 0x238e7673, 0x3536cc52, 0x387165e3, 0x1e2b5d38, 0x0645e9af, 0x3fb11b47, 0x223d66a8, 0x361214b0,
- 0x3811884c, 0x1edc1952, 0x03ecadcf, 0x3fe12acb, 0x20e70f32, 0x36e5068a, 0x37af8158, 0x1f8ba4db,
- 0x0192155f, 0x3ffb10c1, 0x1f8ba4db, 0x37af8158, 0x374b54ce, 0x2039f90e, 0xff36f171, 0x3ffec42d,
- 0x1e2b5d38, 0x387165e3, 0x36e5068a, 0x20e70f32, 0xfcdc1342, 0x3fec43c6, 0x1cc66e99, 0x392a9642,
- 0x367c9a7d, 0x2192e09a, 0xfa824bfe, 0x3fc395f9, 0x1b5d1009, 0x39daf5e8, 0x361214b0, 0x223d66a8,
- 0xf82a6c6b, 0x3f84c8e1, 0x19ef7943, 0x3a8269a2, 0x35a5793c, 0x22e69ac7, 0xf5d544a8, 0x3f2ff249,
- 0x187de2a6, 0x3b20d79e, 0x3536cc52, 0x238e7673, 0xf383a3e2, 0x3ec52f9f, 0x17088530, 0x3bb6276d,
- 0x34c61236, 0x2434f332, 0xf136580e, 0x3e44a5ee, 0x158f9a75, 0x3c424209, 0x34534f40, 0x24da0a99,
- 0xeeee2d9e, 0x3dae81ce, 0x14135c94, 0x3cc511d8, 0x33de87de, 0x257db64b, 0xecabef3e, 0x3d02f756,
- 0x1294062e, 0x3d3e82ad, 0x3367c08f, 0x261feff9, 0xea70658b, 0x3c424209, 0x1111d262, 0x3dae81ce,
- 0x32eefde9, 0x26c0b162, 0xe83c56cf, 0x3b6ca4c4, 0x0f8cfcbd, 0x3e14fdf7, 0x32744493, 0x275ff452,
- 0xe61086bd, 0x3a8269a2, 0x0e05c135, 0x3e71e758, 0x31f79947, 0x27fdb2a6, 0xe3edb628, 0x3983e1e7,
- 0x0c7c5c1e, 0x3ec52f9f, 0x317900d6, 0x2899e64a, 0xe1d4a2c8, 0x387165e3, 0x0af10a22, 0x3f0ec9f4,
- 0x30f8801f, 0x29348937, 0xdfc606f2, 0x374b54ce, 0x09640837, 0x3f4eaafe, 0x30761c17, 0x29cd9577,
- 0xddc29958, 0x361214b0, 0x07d59395, 0x3f84c8e1, 0x2ff1d9c6, 0x2a650525, 0xdbcb0cce, 0x34c61236,
- 0x0645e9af, 0x3fb11b47, 0x2f6bbe44, 0x2afad269, 0xd9e01007, 0x3367c08f, 0x04b54824, 0x3fd39b5a,
- 0x2ee3cebe, 0x2b8ef77c, 0xd8024d5a, 0x31f79947, 0x0323ecbe, 0x3fec43c6, 0x2e5a106f, 0x2c216eaa,
- 0xd6326a89, 0x30761c17, 0x0192155f, 0x3ffb10c1, 0x2dce88a9, 0x2cb2324b, 0xd4710884, 0x2ee3cebe,
- 0x00000000, 0x40000000, 0x2d413ccc, 0x2d413ccc, 0xd2bec334, 0x2d413ccc, 0xfe6deaa1, 0x3ffb10c1,
- 0x2cb2324b, 0x2dce88a9, 0xd11c3142, 0x2b8ef77c, 0xfcdc1342, 0x3fec43c6, 0x2c216eaa, 0x2e5a106f,
- 0xcf89e3e9, 0x29cd9577, 0xfb4ab7dc, 0x3fd39b5a, 0x2b8ef77c, 0x2ee3cebe, 0xce0866b9, 0x27fdb2a6,
- 0xf9ba1651, 0x3fb11b47, 0x2afad269, 0x2f6bbe44, 0xcc983f71, 0x261feff9, 0xf82a6c6b, 0x3f84c8e1,
- 0x2a650525, 0x2ff1d9c6, 0xcb39edca, 0x2434f332, 0xf69bf7c9, 0x3f4eaafe, 0x29cd9577, 0x30761c17,
- 0xc9edeb50, 0x223d66a8, 0xf50ef5de, 0x3f0ec9f4, 0x29348937, 0x30f8801f, 0xc8b4ab32, 0x2039f90e,
- 0xf383a3e2, 0x3ec52f9f, 0x2899e64a, 0x317900d6, 0xc78e9a1d, 0x1e2b5d38, 0xf1fa3ecb, 0x3e71e758,
- 0x27fdb2a6, 0x31f79947, 0xc67c1e19, 0x1c1249d8, 0xf0730343, 0x3e14fdf7, 0x275ff452, 0x32744493,
- 0xc57d965e, 0x19ef7943, 0xeeee2d9e, 0x3dae81ce, 0x26c0b162, 0x32eefde9, 0xc4935b3c, 0x17c3a931,
- 0xed6bf9d2, 0x3d3e82ad, 0x261feff9, 0x3367c08f, 0xc3bdbdf7, 0x158f9a75, 0xebeca36c, 0x3cc511d8,
- 0x257db64b, 0x33de87de, 0xc2fd08aa, 0x135410c2, 0xea70658b, 0x3c424209, 0x24da0a99, 0x34534f40,
- 0xc2517e32, 0x1111d262, 0xe8f77ad0, 0x3bb6276d, 0x2434f332, 0x34c61236, 0xc1bb5a12, 0x0ec9a7f2,
- 0xe7821d5a, 0x3b20d79e, 0x238e7673, 0x3536cc52, 0xc13ad061, 0x0c7c5c1e, 0xe61086bd, 0x3a8269a2,
- 0x22e69ac7, 0x35a5793c, 0xc0d00db7, 0x0a2abb58, 0xe4a2eff7, 0x39daf5e8, 0x223d66a8, 0x361214b0,
- 0xc07b371f, 0x07d59395, 0xe3399167, 0x392a9642, 0x2192e09a, 0x367c9a7d, 0xc03c6a07, 0x057db402,
- 0xe1d4a2c8, 0x387165e3, 0x20e70f32, 0x36e5068a, 0xc013bc3a, 0x0323ecbe, 0xe0745b25, 0x37af8158,
- 0x2039f90e, 0x374b54ce, 0xc0013bd3, 0x00c90e8f, 0xdf18f0ce, 0x36e5068a, 0x1f8ba4db, 0x37af8158,
- 0xc004ef3f, 0xfe6deaa1, 0xddc29958, 0x361214b0, 0x1edc1952, 0x3811884c, 0xc01ed535, 0xfc135231,
- 0xdc71898d, 0x3536cc52, 0x1e2b5d38, 0x387165e3, 0xc04ee4b9, 0xf9ba1651, 0xdb25f567, 0x34534f40,
- 0x1d79775b, 0x38cf1669, 0xc0950d1d, 0xf7630799, 0xd9e01007, 0x3367c08f, 0x1cc66e99, 0x392a9642,
- 0xc0f1360c, 0xf50ef5de, 0xd8a00bae, 0x32744493, 0x1c1249d8, 0x3983e1e7, 0xc1633f8a, 0xf2beafee,
- 0xd76619b6, 0x317900d6, 0x1b5d1009, 0x39daf5e8, 0xc1eb0209, 0xf0730343, 0xd6326a89, 0x30761c17,
- 0x1aa6c82b, 0x3a2fcee8, 0xc2884e6f, 0xee2cbbc1, 0xd5052d97, 0x2f6bbe44, 0x19ef7943, 0x3a8269a2,
- 0xc33aee28, 0xebeca36c, 0xd3de9156, 0x2e5a106f, 0x19372a63, 0x3ad2c2e7, 0xc402a33c, 0xe9b38223,
- 0xd2bec334, 0x2d413ccc, 0x187de2a6, 0x3b20d79e, 0xc4df2862, 0xe7821d5a, 0xd1a5ef91, 0x2c216eaa,
- 0x17c3a931, 0x3b6ca4c4, 0xc5d03118, 0xe55937d5, 0xd09441bc, 0x2afad269, 0x17088530, 0x3bb6276d,
- 0xc6d569be, 0xe3399167, 0xcf89e3e9, 0x29cd9577, 0x164c7ddd, 0x3bfd5cc4, 0xc7ee77b4, 0xe123e6ae,
- 0xce86ff2a, 0x2899e64a, 0x158f9a75, 0x3c424209, 0xc91af976, 0xdf18f0ce, 0xcd8bbb6d, 0x275ff452,
- 0x14d1e242, 0x3c84d496, 0xca5a86c4, 0xdd196539, 0xcc983f71, 0x261feff9, 0x14135c94, 0x3cc511d8,
- 0xcbacb0c0, 0xdb25f567, 0xcbacb0c0, 0x24da0a99, 0x135410c2, 0x3d02f756, 0xcd110217, 0xd93f4e9e,
- 0xcac933ae, 0x238e7673, 0x1294062e, 0x3d3e82ad, 0xce86ff2a, 0xd76619b6, 0xc9edeb50, 0x223d66a8,
- 0x11d3443f, 0x3d77b191, 0xd00e263a, 0xd59afadb, 0xc91af976, 0x20e70f32, 0x1111d262, 0x3dae81ce,
- 0xd1a5ef91, 0xd3de9156, 0xc8507ea8, 0x1f8ba4db, 0x104fb80e, 0x3de2f147, 0xd34dcdb5, 0xd2317757,
- 0xc78e9a1d, 0x1e2b5d38, 0x0f8cfcbd, 0x3e14fdf7, 0xd5052d97, 0xd09441bc, 0xc6d569be, 0x1cc66e99,
- 0x0ec9a7f2, 0x3e44a5ee, 0xd6cb76c9, 0xcf077fe1, 0xc6250a18, 0x1b5d1009, 0x0e05c135, 0x3e71e758,
- 0xd8a00bae, 0xcd8bbb6d, 0xc57d965e, 0x19ef7943, 0x0d415012, 0x3e9cc076, 0xda8249b5, 0xcc217822,
- 0xc4df2862, 0x187de2a6, 0x0c7c5c1e, 0x3ec52f9f, 0xdc71898d, 0xcac933ae, 0xc449d893, 0x17088530,
- 0x0bb6ecef, 0x3eeb3347, 0xde6d1f66, 0xc9836583, 0xc3bdbdf7, 0x158f9a75, 0x0af10a22, 0x3f0ec9f4,
- 0xe0745b25, 0xc8507ea8, 0xc33aee28, 0x14135c94, 0x0a2abb58, 0x3f2ff249, 0xe28688a5, 0xc730e997,
- 0xc2c17d53, 0x1294062e, 0x09640837, 0x3f4eaafe, 0xe4a2eff7, 0xc6250a18, 0xc2517e32, 0x1111d262,
- 0x089cf867, 0x3f6af2e3, 0xe6c8d59d, 0xc52d3d19, 0xc1eb0209, 0x0f8cfcbd, 0x07d59395, 0x3f84c8e1,
- 0xe8f77ad0, 0xc449d893, 0xc18e18a8, 0x0e05c135, 0x070de171, 0x3f9c2bfa, 0xeb2e1dbe, 0xc37b2b6a,
- 0xc13ad061, 0x0c7c5c1e, 0x0645e9af, 0x3fb11b47, 0xed6bf9d2, 0xc2c17d53, 0xc0f1360c, 0x0af10a22,
- 0x057db402, 0x3fc395f9, 0xefb047f2, 0xc21d0eb9, 0xc0b15502, 0x09640837, 0x04b54824, 0x3fd39b5a,
- 0xf1fa3ecb, 0xc18e18a8, 0xc07b371f, 0x07d59395, 0x03ecadcf, 0x3fe12acb, 0xf4491311, 0xc114ccb9,
- 0xc04ee4b9, 0x0645e9af, 0x0323ecbe, 0x3fec43c6, 0xf69bf7c9, 0xc0b15502, 0xc02c64a6, 0x04b54824,
- 0x025b0cae, 0x3ff4e5df, 0xf8f21e8f, 0xc063d406, 0xc013bc3a, 0x0323ecbe, 0x0192155f, 0x3ffb10c1,
+ 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x3ffb10c1, 0x0192155f,
+ 0x3ffec42d, 0x00c90e8f, 0x3ff4e5df, 0x025b0cae, 0x3fec43c6, 0x0323ecbe, 0x3ffb10c1, 0x0192155f,
+ 0x3fd39b5a, 0x04b54824, 0x3fd39b5a, 0x04b54824, 0x3ff4e5df, 0x025b0cae, 0x3f9c2bfa, 0x070de171,
+ 0x3fb11b47, 0x0645e9af, 0x3fec43c6, 0x0323ecbe, 0x3f4eaafe, 0x09640837, 0x3f84c8e1, 0x07d59395,
+ 0x3fe12acb, 0x03ecadcf, 0x3eeb3347, 0x0bb6ecef, 0x3f4eaafe, 0x09640837, 0x3fd39b5a, 0x04b54824,
+ 0x3e71e758, 0x0e05c135, 0x3f0ec9f4, 0x0af10a22, 0x3fc395f9, 0x057db402, 0x3de2f147, 0x104fb80e,
+ 0x3ec52f9f, 0x0c7c5c1e, 0x3fb11b47, 0x0645e9af, 0x3d3e82ad, 0x1294062e, 0x3e71e758, 0x0e05c135,
+ 0x3f9c2bfa, 0x070de171, 0x3c84d496, 0x14d1e242, 0x3e14fdf7, 0x0f8cfcbd, 0x3f84c8e1, 0x07d59395,
+ 0x3bb6276d, 0x17088530, 0x3dae81ce, 0x1111d262, 0x3f6af2e3, 0x089cf867, 0x3ad2c2e7, 0x19372a63,
+ 0x3d3e82ad, 0x1294062e, 0x3f4eaafe, 0x09640837, 0x39daf5e8, 0x1b5d1009, 0x3cc511d8, 0x14135c94,
+ 0x3f2ff249, 0x0a2abb58, 0x38cf1669, 0x1d79775b, 0x3c424209, 0x158f9a75, 0x3f0ec9f4, 0x0af10a22,
+ 0x37af8158, 0x1f8ba4db, 0x3bb6276d, 0x17088530, 0x3eeb3347, 0x0bb6ecef, 0x367c9a7d, 0x2192e09a,
+ 0x3b20d79e, 0x187de2a6, 0x3ec52f9f, 0x0c7c5c1e, 0x3536cc52, 0x238e7673, 0x3a8269a2, 0x19ef7943,
+ 0x3e9cc076, 0x0d415012, 0x33de87de, 0x257db64b, 0x39daf5e8, 0x1b5d1009, 0x3e71e758, 0x0e05c135,
+ 0x32744493, 0x275ff452, 0x392a9642, 0x1cc66e99, 0x3e44a5ee, 0x0ec9a7f2, 0x30f8801f, 0x29348937,
+ 0x387165e3, 0x1e2b5d38, 0x3e14fdf7, 0x0f8cfcbd, 0x2f6bbe44, 0x2afad269, 0x37af8158, 0x1f8ba4db,
+ 0x3de2f147, 0x104fb80e, 0x2dce88a9, 0x2cb2324b, 0x36e5068a, 0x20e70f32, 0x3dae81ce, 0x1111d262,
+ 0x2c216eaa, 0x2e5a106f, 0x361214b0, 0x223d66a8, 0x3d77b191, 0x11d3443f, 0x2a650525, 0x2ff1d9c6,
+ 0x3536cc52, 0x238e7673, 0x3d3e82ad, 0x1294062e, 0x2899e64a, 0x317900d6, 0x34534f40, 0x24da0a99,
+ 0x3d02f756, 0x135410c2, 0x26c0b162, 0x32eefde9, 0x3367c08f, 0x261feff9, 0x3cc511d8, 0x14135c94,
+ 0x24da0a99, 0x34534f40, 0x32744493, 0x275ff452, 0x3c84d496, 0x14d1e242, 0x22e69ac7, 0x35a5793c,
+ 0x317900d6, 0x2899e64a, 0x3c424209, 0x158f9a75, 0x20e70f32, 0x36e5068a, 0x30761c17, 0x29cd9577,
+ 0x3bfd5cc4, 0x164c7ddd, 0x1edc1952, 0x3811884c, 0x2f6bbe44, 0x2afad269, 0x3bb6276d, 0x17088530,
+ 0x1cc66e99, 0x392a9642, 0x2e5a106f, 0x2c216eaa, 0x3b6ca4c4, 0x17c3a931, 0x1aa6c82b, 0x3a2fcee8,
+ 0x2d413ccc, 0x2d413ccc, 0x3b20d79e, 0x187de2a6, 0x187de2a6, 0x3b20d79e, 0x2c216eaa, 0x2e5a106f,
+ 0x3ad2c2e7, 0x19372a63, 0x164c7ddd, 0x3bfd5cc4, 0x2afad269, 0x2f6bbe44, 0x3a8269a2, 0x19ef7943,
+ 0x14135c94, 0x3cc511d8, 0x29cd9577, 0x30761c17, 0x3a2fcee8, 0x1aa6c82b, 0x11d3443f, 0x3d77b191,
+ 0x2899e64a, 0x317900d6, 0x39daf5e8, 0x1b5d1009, 0x0f8cfcbd, 0x3e14fdf7, 0x275ff452, 0x32744493,
+ 0x3983e1e7, 0x1c1249d8, 0x0d415012, 0x3e9cc076, 0x261feff9, 0x3367c08f, 0x392a9642, 0x1cc66e99,
+ 0x0af10a22, 0x3f0ec9f4, 0x24da0a99, 0x34534f40, 0x38cf1669, 0x1d79775b, 0x089cf867, 0x3f6af2e3,
+ 0x238e7673, 0x3536cc52, 0x387165e3, 0x1e2b5d38, 0x0645e9af, 0x3fb11b47, 0x223d66a8, 0x361214b0,
+ 0x3811884c, 0x1edc1952, 0x03ecadcf, 0x3fe12acb, 0x20e70f32, 0x36e5068a, 0x37af8158, 0x1f8ba4db,
+ 0x0192155f, 0x3ffb10c1, 0x1f8ba4db, 0x37af8158, 0x374b54ce, 0x2039f90e, 0xff36f171, 0x3ffec42d,
+ 0x1e2b5d38, 0x387165e3, 0x36e5068a, 0x20e70f32, 0xfcdc1342, 0x3fec43c6, 0x1cc66e99, 0x392a9642,
+ 0x367c9a7d, 0x2192e09a, 0xfa824bfe, 0x3fc395f9, 0x1b5d1009, 0x39daf5e8, 0x361214b0, 0x223d66a8,
+ 0xf82a6c6b, 0x3f84c8e1, 0x19ef7943, 0x3a8269a2, 0x35a5793c, 0x22e69ac7, 0xf5d544a8, 0x3f2ff249,
+ 0x187de2a6, 0x3b20d79e, 0x3536cc52, 0x238e7673, 0xf383a3e2, 0x3ec52f9f, 0x17088530, 0x3bb6276d,
+ 0x34c61236, 0x2434f332, 0xf136580e, 0x3e44a5ee, 0x158f9a75, 0x3c424209, 0x34534f40, 0x24da0a99,
+ 0xeeee2d9e, 0x3dae81ce, 0x14135c94, 0x3cc511d8, 0x33de87de, 0x257db64b, 0xecabef3e, 0x3d02f756,
+ 0x1294062e, 0x3d3e82ad, 0x3367c08f, 0x261feff9, 0xea70658b, 0x3c424209, 0x1111d262, 0x3dae81ce,
+ 0x32eefde9, 0x26c0b162, 0xe83c56cf, 0x3b6ca4c4, 0x0f8cfcbd, 0x3e14fdf7, 0x32744493, 0x275ff452,
+ 0xe61086bd, 0x3a8269a2, 0x0e05c135, 0x3e71e758, 0x31f79947, 0x27fdb2a6, 0xe3edb628, 0x3983e1e7,
+ 0x0c7c5c1e, 0x3ec52f9f, 0x317900d6, 0x2899e64a, 0xe1d4a2c8, 0x387165e3, 0x0af10a22, 0x3f0ec9f4,
+ 0x30f8801f, 0x29348937, 0xdfc606f2, 0x374b54ce, 0x09640837, 0x3f4eaafe, 0x30761c17, 0x29cd9577,
+ 0xddc29958, 0x361214b0, 0x07d59395, 0x3f84c8e1, 0x2ff1d9c6, 0x2a650525, 0xdbcb0cce, 0x34c61236,
+ 0x0645e9af, 0x3fb11b47, 0x2f6bbe44, 0x2afad269, 0xd9e01007, 0x3367c08f, 0x04b54824, 0x3fd39b5a,
+ 0x2ee3cebe, 0x2b8ef77c, 0xd8024d5a, 0x31f79947, 0x0323ecbe, 0x3fec43c6, 0x2e5a106f, 0x2c216eaa,
+ 0xd6326a89, 0x30761c17, 0x0192155f, 0x3ffb10c1, 0x2dce88a9, 0x2cb2324b, 0xd4710884, 0x2ee3cebe,
+ 0x00000000, 0x40000000, 0x2d413ccc, 0x2d413ccc, 0xd2bec334, 0x2d413ccc, 0xfe6deaa1, 0x3ffb10c1,
+ 0x2cb2324b, 0x2dce88a9, 0xd11c3142, 0x2b8ef77c, 0xfcdc1342, 0x3fec43c6, 0x2c216eaa, 0x2e5a106f,
+ 0xcf89e3e9, 0x29cd9577, 0xfb4ab7dc, 0x3fd39b5a, 0x2b8ef77c, 0x2ee3cebe, 0xce0866b9, 0x27fdb2a6,
+ 0xf9ba1651, 0x3fb11b47, 0x2afad269, 0x2f6bbe44, 0xcc983f71, 0x261feff9, 0xf82a6c6b, 0x3f84c8e1,
+ 0x2a650525, 0x2ff1d9c6, 0xcb39edca, 0x2434f332, 0xf69bf7c9, 0x3f4eaafe, 0x29cd9577, 0x30761c17,
+ 0xc9edeb50, 0x223d66a8, 0xf50ef5de, 0x3f0ec9f4, 0x29348937, 0x30f8801f, 0xc8b4ab32, 0x2039f90e,
+ 0xf383a3e2, 0x3ec52f9f, 0x2899e64a, 0x317900d6, 0xc78e9a1d, 0x1e2b5d38, 0xf1fa3ecb, 0x3e71e758,
+ 0x27fdb2a6, 0x31f79947, 0xc67c1e19, 0x1c1249d8, 0xf0730343, 0x3e14fdf7, 0x275ff452, 0x32744493,
+ 0xc57d965e, 0x19ef7943, 0xeeee2d9e, 0x3dae81ce, 0x26c0b162, 0x32eefde9, 0xc4935b3c, 0x17c3a931,
+ 0xed6bf9d2, 0x3d3e82ad, 0x261feff9, 0x3367c08f, 0xc3bdbdf7, 0x158f9a75, 0xebeca36c, 0x3cc511d8,
+ 0x257db64b, 0x33de87de, 0xc2fd08aa, 0x135410c2, 0xea70658b, 0x3c424209, 0x24da0a99, 0x34534f40,
+ 0xc2517e32, 0x1111d262, 0xe8f77ad0, 0x3bb6276d, 0x2434f332, 0x34c61236, 0xc1bb5a12, 0x0ec9a7f2,
+ 0xe7821d5a, 0x3b20d79e, 0x238e7673, 0x3536cc52, 0xc13ad061, 0x0c7c5c1e, 0xe61086bd, 0x3a8269a2,
+ 0x22e69ac7, 0x35a5793c, 0xc0d00db7, 0x0a2abb58, 0xe4a2eff7, 0x39daf5e8, 0x223d66a8, 0x361214b0,
+ 0xc07b371f, 0x07d59395, 0xe3399167, 0x392a9642, 0x2192e09a, 0x367c9a7d, 0xc03c6a07, 0x057db402,
+ 0xe1d4a2c8, 0x387165e3, 0x20e70f32, 0x36e5068a, 0xc013bc3a, 0x0323ecbe, 0xe0745b25, 0x37af8158,
+ 0x2039f90e, 0x374b54ce, 0xc0013bd3, 0x00c90e8f, 0xdf18f0ce, 0x36e5068a, 0x1f8ba4db, 0x37af8158,
+ 0xc004ef3f, 0xfe6deaa1, 0xddc29958, 0x361214b0, 0x1edc1952, 0x3811884c, 0xc01ed535, 0xfc135231,
+ 0xdc71898d, 0x3536cc52, 0x1e2b5d38, 0x387165e3, 0xc04ee4b9, 0xf9ba1651, 0xdb25f567, 0x34534f40,
+ 0x1d79775b, 0x38cf1669, 0xc0950d1d, 0xf7630799, 0xd9e01007, 0x3367c08f, 0x1cc66e99, 0x392a9642,
+ 0xc0f1360c, 0xf50ef5de, 0xd8a00bae, 0x32744493, 0x1c1249d8, 0x3983e1e7, 0xc1633f8a, 0xf2beafee,
+ 0xd76619b6, 0x317900d6, 0x1b5d1009, 0x39daf5e8, 0xc1eb0209, 0xf0730343, 0xd6326a89, 0x30761c17,
+ 0x1aa6c82b, 0x3a2fcee8, 0xc2884e6f, 0xee2cbbc1, 0xd5052d97, 0x2f6bbe44, 0x19ef7943, 0x3a8269a2,
+ 0xc33aee28, 0xebeca36c, 0xd3de9156, 0x2e5a106f, 0x19372a63, 0x3ad2c2e7, 0xc402a33c, 0xe9b38223,
+ 0xd2bec334, 0x2d413ccc, 0x187de2a6, 0x3b20d79e, 0xc4df2862, 0xe7821d5a, 0xd1a5ef91, 0x2c216eaa,
+ 0x17c3a931, 0x3b6ca4c4, 0xc5d03118, 0xe55937d5, 0xd09441bc, 0x2afad269, 0x17088530, 0x3bb6276d,
+ 0xc6d569be, 0xe3399167, 0xcf89e3e9, 0x29cd9577, 0x164c7ddd, 0x3bfd5cc4, 0xc7ee77b4, 0xe123e6ae,
+ 0xce86ff2a, 0x2899e64a, 0x158f9a75, 0x3c424209, 0xc91af976, 0xdf18f0ce, 0xcd8bbb6d, 0x275ff452,
+ 0x14d1e242, 0x3c84d496, 0xca5a86c4, 0xdd196539, 0xcc983f71, 0x261feff9, 0x14135c94, 0x3cc511d8,
+ 0xcbacb0c0, 0xdb25f567, 0xcbacb0c0, 0x24da0a99, 0x135410c2, 0x3d02f756, 0xcd110217, 0xd93f4e9e,
+ 0xcac933ae, 0x238e7673, 0x1294062e, 0x3d3e82ad, 0xce86ff2a, 0xd76619b6, 0xc9edeb50, 0x223d66a8,
+ 0x11d3443f, 0x3d77b191, 0xd00e263a, 0xd59afadb, 0xc91af976, 0x20e70f32, 0x1111d262, 0x3dae81ce,
+ 0xd1a5ef91, 0xd3de9156, 0xc8507ea8, 0x1f8ba4db, 0x104fb80e, 0x3de2f147, 0xd34dcdb5, 0xd2317757,
+ 0xc78e9a1d, 0x1e2b5d38, 0x0f8cfcbd, 0x3e14fdf7, 0xd5052d97, 0xd09441bc, 0xc6d569be, 0x1cc66e99,
+ 0x0ec9a7f2, 0x3e44a5ee, 0xd6cb76c9, 0xcf077fe1, 0xc6250a18, 0x1b5d1009, 0x0e05c135, 0x3e71e758,
+ 0xd8a00bae, 0xcd8bbb6d, 0xc57d965e, 0x19ef7943, 0x0d415012, 0x3e9cc076, 0xda8249b5, 0xcc217822,
+ 0xc4df2862, 0x187de2a6, 0x0c7c5c1e, 0x3ec52f9f, 0xdc71898d, 0xcac933ae, 0xc449d893, 0x17088530,
+ 0x0bb6ecef, 0x3eeb3347, 0xde6d1f66, 0xc9836583, 0xc3bdbdf7, 0x158f9a75, 0x0af10a22, 0x3f0ec9f4,
+ 0xe0745b25, 0xc8507ea8, 0xc33aee28, 0x14135c94, 0x0a2abb58, 0x3f2ff249, 0xe28688a5, 0xc730e997,
+ 0xc2c17d53, 0x1294062e, 0x09640837, 0x3f4eaafe, 0xe4a2eff7, 0xc6250a18, 0xc2517e32, 0x1111d262,
+ 0x089cf867, 0x3f6af2e3, 0xe6c8d59d, 0xc52d3d19, 0xc1eb0209, 0x0f8cfcbd, 0x07d59395, 0x3f84c8e1,
+ 0xe8f77ad0, 0xc449d893, 0xc18e18a8, 0x0e05c135, 0x070de171, 0x3f9c2bfa, 0xeb2e1dbe, 0xc37b2b6a,
+ 0xc13ad061, 0x0c7c5c1e, 0x0645e9af, 0x3fb11b47, 0xed6bf9d2, 0xc2c17d53, 0xc0f1360c, 0x0af10a22,
+ 0x057db402, 0x3fc395f9, 0xefb047f2, 0xc21d0eb9, 0xc0b15502, 0x09640837, 0x04b54824, 0x3fd39b5a,
+ 0xf1fa3ecb, 0xc18e18a8, 0xc07b371f, 0x07d59395, 0x03ecadcf, 0x3fe12acb, 0xf4491311, 0xc114ccb9,
+ 0xc04ee4b9, 0x0645e9af, 0x0323ecbe, 0x3fec43c6, 0xf69bf7c9, 0xc0b15502, 0xc02c64a6, 0x04b54824,
+ 0x025b0cae, 0x3ff4e5df, 0xf8f21e8f, 0xc063d406, 0xc013bc3a, 0x0323ecbe, 0x0192155f, 0x3ffb10c1,
0xfb4ab7dc, 0xc02c64a6, 0xc004ef3f, 0x0192155f, 0x00c90e8f, 0x3ffec42d, 0xfda4f352, 0xc00b1a21
};
const int twidTab64[4*6 + 16*6] = {
- 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x2d413ccc, 0x2d413ccc,
- 0x3b20d79e, 0x187de2a6, 0x187de2a6, 0x3b20d79e, 0x00000000, 0x40000000, 0x2d413ccc, 0x2d413ccc,
- 0xd2bec334, 0x2d413ccc, 0xd2bec334, 0x2d413ccc, 0x187de2a6, 0x3b20d79e, 0xc4df2862, 0xe7821d5a,
+ 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x2d413ccc, 0x2d413ccc,
+ 0x3b20d79e, 0x187de2a6, 0x187de2a6, 0x3b20d79e, 0x00000000, 0x40000000, 0x2d413ccc, 0x2d413ccc,
+ 0xd2bec334, 0x2d413ccc, 0xd2bec334, 0x2d413ccc, 0x187de2a6, 0x3b20d79e, 0xc4df2862, 0xe7821d5a,
- 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x3ec52f9f, 0x0c7c5c1e,
- 0x3fb11b47, 0x0645e9af, 0x3d3e82ad, 0x1294062e, 0x3b20d79e, 0x187de2a6, 0x3ec52f9f, 0x0c7c5c1e,
- 0x3536cc52, 0x238e7673, 0x3536cc52, 0x238e7673, 0x3d3e82ad, 0x1294062e, 0x2899e64a, 0x317900d6,
- 0x2d413ccc, 0x2d413ccc, 0x3b20d79e, 0x187de2a6, 0x187de2a6, 0x3b20d79e, 0x238e7673, 0x3536cc52,
- 0x387165e3, 0x1e2b5d38, 0x0645e9af, 0x3fb11b47, 0x187de2a6, 0x3b20d79e, 0x3536cc52, 0x238e7673,
- 0xf383a3e2, 0x3ec52f9f, 0x0c7c5c1e, 0x3ec52f9f, 0x317900d6, 0x2899e64a, 0xe1d4a2c8, 0x387165e3,
- 0x00000000, 0x40000000, 0x2d413ccc, 0x2d413ccc, 0xd2bec334, 0x2d413ccc, 0xf383a3e2, 0x3ec52f9f,
- 0x2899e64a, 0x317900d6, 0xc78e9a1d, 0x1e2b5d38, 0xe7821d5a, 0x3b20d79e, 0x238e7673, 0x3536cc52,
- 0xc13ad061, 0x0c7c5c1e, 0xdc71898d, 0x3536cc52, 0x1e2b5d38, 0x387165e3, 0xc04ee4b9, 0xf9ba1651,
- 0xd2bec334, 0x2d413ccc, 0x187de2a6, 0x3b20d79e, 0xc4df2862, 0xe7821d5a, 0xcac933ae, 0x238e7673,
- 0x1294062e, 0x3d3e82ad, 0xce86ff2a, 0xd76619b6, 0xc4df2862, 0x187de2a6, 0x0c7c5c1e, 0x3ec52f9f,
- 0xdc71898d, 0xcac933ae, 0xc13ad061, 0x0c7c5c1e, 0x0645e9af, 0x3fb11b47, 0xed6bf9d2, 0xc2c17d53
+ 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x3ec52f9f, 0x0c7c5c1e,
+ 0x3fb11b47, 0x0645e9af, 0x3d3e82ad, 0x1294062e, 0x3b20d79e, 0x187de2a6, 0x3ec52f9f, 0x0c7c5c1e,
+ 0x3536cc52, 0x238e7673, 0x3536cc52, 0x238e7673, 0x3d3e82ad, 0x1294062e, 0x2899e64a, 0x317900d6,
+ 0x2d413ccc, 0x2d413ccc, 0x3b20d79e, 0x187de2a6, 0x187de2a6, 0x3b20d79e, 0x238e7673, 0x3536cc52,
+ 0x387165e3, 0x1e2b5d38, 0x0645e9af, 0x3fb11b47, 0x187de2a6, 0x3b20d79e, 0x3536cc52, 0x238e7673,
+ 0xf383a3e2, 0x3ec52f9f, 0x0c7c5c1e, 0x3ec52f9f, 0x317900d6, 0x2899e64a, 0xe1d4a2c8, 0x387165e3,
+ 0x00000000, 0x40000000, 0x2d413ccc, 0x2d413ccc, 0xd2bec334, 0x2d413ccc, 0xf383a3e2, 0x3ec52f9f,
+ 0x2899e64a, 0x317900d6, 0xc78e9a1d, 0x1e2b5d38, 0xe7821d5a, 0x3b20d79e, 0x238e7673, 0x3536cc52,
+ 0xc13ad061, 0x0c7c5c1e, 0xdc71898d, 0x3536cc52, 0x1e2b5d38, 0x387165e3, 0xc04ee4b9, 0xf9ba1651,
+ 0xd2bec334, 0x2d413ccc, 0x187de2a6, 0x3b20d79e, 0xc4df2862, 0xe7821d5a, 0xcac933ae, 0x238e7673,
+ 0x1294062e, 0x3d3e82ad, 0xce86ff2a, 0xd76619b6, 0xc4df2862, 0x187de2a6, 0x0c7c5c1e, 0x3ec52f9f,
+ 0xdc71898d, 0xcac933ae, 0xc13ad061, 0x0c7c5c1e, 0x0645e9af, 0x3fb11b47, 0xed6bf9d2, 0xc2c17d53
};
#endif //ARMV5E
-const int ShortWindowSine[FRAME_LEN_SHORT/2] ={
- 0x00c97fff, 0x025b7ffa, 0x03ed7ff1, 0x057f7fe2, 0x07117fce, 0x08a27fb5, 0x0a337f98, 0x0bc47f75,
- 0x0d547f4e, 0x0ee47f22, 0x10737ef0, 0x12017eba, 0x138f7e7f, 0x151c7e3f, 0x16a87dfb, 0x18337db1,
- 0x19be7d63, 0x1b477d0f, 0x1cd07cb7, 0x1e577c5a, 0x1fdd7bf9, 0x21627b92, 0x22e57b27, 0x24677ab7,
- 0x25e87a42, 0x276879c9, 0x28e5794a, 0x2a6278c8, 0x2bdc7840, 0x2d5577b4, 0x2ecc7723, 0x3042768e,
- 0x31b575f4, 0x33277556, 0x349774b3, 0x3604740b, 0x3770735f, 0x38d972af, 0x3a4071fa, 0x3ba57141,
- 0x3d087083, 0x3e686fc2, 0x3fc66efb, 0x41216e31, 0x427a6d62, 0x43d16c8f, 0x45246bb8, 0x46756add,
- 0x47c469fd, 0x490f691a, 0x4a586832, 0x4b9e6747, 0x4ce16657, 0x4e216564, 0x4f5e646c, 0x50986371,
+const int ShortWindowSine[FRAME_LEN_SHORT/2] ={
+ 0x00c97fff, 0x025b7ffa, 0x03ed7ff1, 0x057f7fe2, 0x07117fce, 0x08a27fb5, 0x0a337f98, 0x0bc47f75,
+ 0x0d547f4e, 0x0ee47f22, 0x10737ef0, 0x12017eba, 0x138f7e7f, 0x151c7e3f, 0x16a87dfb, 0x18337db1,
+ 0x19be7d63, 0x1b477d0f, 0x1cd07cb7, 0x1e577c5a, 0x1fdd7bf9, 0x21627b92, 0x22e57b27, 0x24677ab7,
+ 0x25e87a42, 0x276879c9, 0x28e5794a, 0x2a6278c8, 0x2bdc7840, 0x2d5577b4, 0x2ecc7723, 0x3042768e,
+ 0x31b575f4, 0x33277556, 0x349774b3, 0x3604740b, 0x3770735f, 0x38d972af, 0x3a4071fa, 0x3ba57141,
+ 0x3d087083, 0x3e686fc2, 0x3fc66efb, 0x41216e31, 0x427a6d62, 0x43d16c8f, 0x45246bb8, 0x46756add,
+ 0x47c469fd, 0x490f691a, 0x4a586832, 0x4b9e6747, 0x4ce16657, 0x4e216564, 0x4f5e646c, 0x50986371,
0x51cf6272, 0x5303616f, 0x54336068, 0x55605f5e, 0x568a5e50, 0x57b15d3e, 0x58d45c29, 0x59f45b10
};
-const int LongWindowKBD[FRAME_LEN_LONG/2]={
- 0x000a7fff, 0x000e7fff, 0x00127fff, 0x00157fff, 0x00197fff, 0x001c7fff, 0x00207fff, 0x00237fff,
- 0x00267fff, 0x002a7fff, 0x002d7fff, 0x00307fff, 0x00347fff, 0x00387fff, 0x003b7fff, 0x003f7fff,
- 0x00437fff, 0x00477fff, 0x004b7fff, 0x004f7fff, 0x00537fff, 0x00577fff, 0x005b7fff, 0x00607fff,
- 0x00647fff, 0x00697fff, 0x006d7fff, 0x00727fff, 0x00777fff, 0x007c7fff, 0x00817fff, 0x00867fff,
- 0x008b7fff, 0x00917fff, 0x00967fff, 0x009c7fff, 0x00a17fff, 0x00a77fff, 0x00ad7fff, 0x00b37fff,
- 0x00b97fff, 0x00bf7fff, 0x00c67fff, 0x00cc7fff, 0x00d37fff, 0x00da7fff, 0x00e07fff, 0x00e77fff,
- 0x00ee7fff, 0x00f57fff, 0x00fd7fff, 0x01047fff, 0x010c7fff, 0x01137fff, 0x011b7fff, 0x01237fff,
- 0x012b7fff, 0x01337fff, 0x013c7ffe, 0x01447ffe, 0x014d7ffe, 0x01567ffe, 0x015f7ffe, 0x01687ffe,
- 0x01717ffe, 0x017a7ffe, 0x01837ffe, 0x018d7ffe, 0x01977ffd, 0x01a17ffd, 0x01ab7ffd, 0x01b57ffd,
- 0x01bf7ffd, 0x01ca7ffd, 0x01d47ffd, 0x01df7ffc, 0x01ea7ffc, 0x01f57ffc, 0x02007ffc, 0x020c7ffc,
- 0x02177ffc, 0x02237ffb, 0x022f7ffb, 0x023b7ffb, 0x02477ffb, 0x02537ffb, 0x02607ffa, 0x026d7ffa,
- 0x027a7ffa, 0x02877ffa, 0x02947ff9, 0x02a17ff9, 0x02af7ff9, 0x02bc7ff9, 0x02ca7ff8, 0x02d87ff8,
- 0x02e77ff8, 0x02f57ff7, 0x03047ff7, 0x03127ff7, 0x03217ff6, 0x03317ff6, 0x03407ff5, 0x034f7ff5,
- 0x035f7ff5, 0x036f7ff4, 0x037f7ff4, 0x038f7ff3, 0x03a07ff3, 0x03b07ff2, 0x03c17ff2, 0x03d27ff1,
- 0x03e37ff1, 0x03f57ff0, 0x04067ff0, 0x04187fef, 0x042a7fef, 0x043c7fee, 0x044f7fed, 0x04617fed,
- 0x04747fec, 0x04877feb, 0x049a7feb, 0x04ae7fea, 0x04c17fe9, 0x04d57fe9, 0x04e97fe8, 0x04fd7fe7,
- 0x05127fe6, 0x05277fe5, 0x053b7fe5, 0x05507fe4, 0x05667fe3, 0x057b7fe2, 0x05917fe1, 0x05a77fe0,
- 0x05bd7fdf, 0x05d37fde, 0x05ea7fdd, 0x06017fdc, 0x06187fdb, 0x062f7fda, 0x06467fd9, 0x065e7fd7,
- 0x06767fd6, 0x068e7fd5, 0x06a67fd4, 0x06bf7fd2, 0x06d87fd1, 0x06f17fd0, 0x070a7fce, 0x07237fcd,
- 0x073d7fcc, 0x07577fca, 0x07717fc9, 0x078c7fc7, 0x07a67fc5, 0x07c17fc4, 0x07dc7fc2, 0x07f77fc0,
- 0x08137fbf, 0x082f7fbd, 0x084b7fbb, 0x08677fb9, 0x08847fb7, 0x08a07fb6, 0x08bd7fb4, 0x08da7fb2,
- 0x08f87faf, 0x09167fad, 0x09347fab, 0x09527fa9, 0x09707fa7, 0x098f7fa5, 0x09ae7fa2, 0x09cd7fa0,
- 0x09ec7f9d, 0x0a0c7f9b, 0x0a2c7f98, 0x0a4c7f96, 0x0a6c7f93, 0x0a8d7f91, 0x0aae7f8e, 0x0acf7f8b,
- 0x0af07f88, 0x0b127f85, 0x0b337f82, 0x0b557f7f, 0x0b787f7c, 0x0b9a7f79, 0x0bbd7f76, 0x0be07f73,
- 0x0c047f6f, 0x0c277f6c, 0x0c4b7f69, 0x0c6f7f65, 0x0c937f61, 0x0cb87f5e, 0x0cdd7f5a, 0x0d027f56,
- 0x0d277f53, 0x0d4d7f4f, 0x0d737f4b, 0x0d997f47, 0x0dbf7f43, 0x0de67f3e, 0x0e0c7f3a, 0x0e347f36,
- 0x0e5b7f31, 0x0e837f2d, 0x0eaa7f28, 0x0ed37f24, 0x0efb7f1f, 0x0f237f1a, 0x0f4c7f15, 0x0f757f10,
- 0x0f9f7f0b, 0x0fc87f06, 0x0ff27f01, 0x101c7efb, 0x10477ef6, 0x10717ef0, 0x109c7eeb, 0x10c87ee5,
- 0x10f37edf, 0x111f7eda, 0x114a7ed4, 0x11777ece, 0x11a37ec7, 0x11d07ec1, 0x11fd7ebb, 0x122a7eb4,
- 0x12577eae, 0x12857ea7, 0x12b37ea0, 0x12e17e9a, 0x130f7e93, 0x133e7e8c, 0x136d7e84, 0x139c7e7d,
- 0x13cc7e76, 0x13fb7e6e, 0x142b7e67, 0x145b7e5f, 0x148c7e57, 0x14bc7e4f, 0x14ed7e47, 0x151e7e3f,
- 0x15507e37, 0x15817e2e, 0x15b37e26, 0x15e57e1d, 0x16187e14, 0x164a7e0b, 0x167d7e02, 0x16b07df9,
- 0x16e47df0, 0x17177de6, 0x174b7ddd, 0x177f7dd3, 0x17b37dc9, 0x17e87dbf, 0x181d7db5, 0x18527dab,
- 0x18877da1, 0x18bc7d96, 0x18f27d8c, 0x19287d81, 0x195e7d76, 0x19957d6b, 0x19cb7d60, 0x1a027d54,
- 0x1a397d49, 0x1a717d3d, 0x1aa87d31, 0x1ae07d26, 0x1b187d19, 0x1b507d0d, 0x1b897d01, 0x1bc27cf4,
- 0x1bfb7ce8, 0x1c347cdb, 0x1c6d7cce, 0x1ca77cc1, 0x1ce17cb3, 0x1d1b7ca6, 0x1d557c98, 0x1d8f7c8a,
- 0x1dca7c7c, 0x1e057c6e, 0x1e407c60, 0x1e7b7c51, 0x1eb77c43, 0x1ef37c34, 0x1f2f7c25, 0x1f6b7c16,
- 0x1fa77c06, 0x1fe47bf7, 0x20217be7, 0x205e7bd7, 0x209b7bc7, 0x20d87bb7, 0x21167ba6, 0x21547b96,
- 0x21927b85, 0x21d07b74, 0x220e7b63, 0x224d7b52, 0x228c7b40, 0x22cb7b2e, 0x230a7b1c, 0x23497b0a,
- 0x23897af8, 0x23c87ae6, 0x24087ad3, 0x24487ac0, 0x24897aad, 0x24c97a9a, 0x250a7a86, 0x254b7a73,
- 0x258c7a5f, 0x25cd7a4b, 0x260e7a36, 0x26507a22, 0x26917a0d, 0x26d379f8, 0x271579e3, 0x275779ce,
- 0x279a79b8, 0x27dc79a3, 0x281f798d, 0x28627977, 0x28a57960, 0x28e8794a, 0x292b7933, 0x296f791c,
- 0x29b27905, 0x29f678ed, 0x2a3a78d6, 0x2a7e78be, 0x2ac278a6, 0x2b07788d, 0x2b4b7875, 0x2b90785c,
- 0x2bd47843, 0x2c19782a, 0x2c5e7810, 0x2ca477f7, 0x2ce977dd, 0x2d2e77c3, 0x2d7477a8, 0x2dba778e,
- 0x2dff7773, 0x2e457758, 0x2e8b773d, 0x2ed27721, 0x2f187706, 0x2f5e76ea, 0x2fa576cd, 0x2fec76b1,
- 0x30327694, 0x30797677, 0x30c0765a, 0x3107763d, 0x314e761f, 0x31967601, 0x31dd75e3, 0x322575c5,
- 0x326c75a6, 0x32b47588, 0x32fc7569, 0x33447549, 0x338c752a, 0x33d4750a, 0x341c74ea, 0x346474ca,
- 0x34ac74a9, 0x34f57488, 0x353d7467, 0x35857446, 0x35ce7424, 0x36177403, 0x365f73e1, 0x36a873be,
- 0x36f1739c, 0x373a7379, 0x37837356, 0x37cc7333, 0x3815730f, 0x385e72ec, 0x38a772c8, 0x38f172a3,
- 0x393a727f, 0x3983725a, 0x39cd7235, 0x3a167210, 0x3a6071ea, 0x3aa971c4, 0x3af3719e, 0x3b3c7178,
- 0x3b867151, 0x3bd0712b, 0x3c197104, 0x3c6370dc, 0x3cad70b5, 0x3cf7708d, 0x3d407065, 0x3d8a703c,
- 0x3dd47014, 0x3e1e6feb, 0x3e686fc2, 0x3eb16f98, 0x3efb6f6f, 0x3f456f45, 0x3f8f6f1b, 0x3fd96ef0,
- 0x40236ec6, 0x406d6e9b, 0x40b66e70, 0x41006e44, 0x414a6e19, 0x41946ded, 0x41de6dc1, 0x42286d94,
- 0x42716d68, 0x42bb6d3b, 0x43056d0d, 0x434f6ce0, 0x43986cb2, 0x43e26c84, 0x442c6c56, 0x44756c28,
- 0x44bf6bf9, 0x45086bca, 0x45526b9b, 0x459b6b6b, 0x45e56b3c, 0x462e6b0c, 0x46786adb, 0x46c16aab,
- 0x470a6a7a, 0x47536a49, 0x479c6a18, 0x47e569e7, 0x482e69b5, 0x48776983, 0x48c06951, 0x4909691e,
- 0x495268ec, 0x499b68b9, 0x49e36885, 0x4a2c6852, 0x4a74681e, 0x4abd67ea, 0x4b0567b6, 0x4b4d6782,
- 0x4b95674d, 0x4bde6718, 0x4c2666e3, 0x4c6d66ae, 0x4cb56678, 0x4cfd6642, 0x4d45660c, 0x4d8c65d6,
- 0x4dd4659f, 0x4e1b6568, 0x4e626531, 0x4ea964fa, 0x4ef064c3, 0x4f37648b, 0x4f7e6453, 0x4fc5641b,
- 0x500b63e2, 0x505263aa, 0x50986371, 0x50df6338, 0x512562fe, 0x516b62c5, 0x51b1628b, 0x51f66251,
- 0x523c6217, 0x528161dc, 0x52c761a2, 0x530c6167, 0x5351612c, 0x539660f1, 0x53db60b5, 0x54206079,
- 0x5464603d, 0x54a96001, 0x54ed5fc5, 0x55315f88, 0x55755f4b, 0x55b95f0e, 0x55fc5ed1, 0x56405e94,
- 0x56835e56, 0x56c75e18, 0x570a5dda, 0x574d5d9c, 0x578f5d5e, 0x57d25d1f, 0x58145ce0, 0x58565ca1,
+const int LongWindowKBD[FRAME_LEN_LONG/2]={
+ 0x000a7fff, 0x000e7fff, 0x00127fff, 0x00157fff, 0x00197fff, 0x001c7fff, 0x00207fff, 0x00237fff,
+ 0x00267fff, 0x002a7fff, 0x002d7fff, 0x00307fff, 0x00347fff, 0x00387fff, 0x003b7fff, 0x003f7fff,
+ 0x00437fff, 0x00477fff, 0x004b7fff, 0x004f7fff, 0x00537fff, 0x00577fff, 0x005b7fff, 0x00607fff,
+ 0x00647fff, 0x00697fff, 0x006d7fff, 0x00727fff, 0x00777fff, 0x007c7fff, 0x00817fff, 0x00867fff,
+ 0x008b7fff, 0x00917fff, 0x00967fff, 0x009c7fff, 0x00a17fff, 0x00a77fff, 0x00ad7fff, 0x00b37fff,
+ 0x00b97fff, 0x00bf7fff, 0x00c67fff, 0x00cc7fff, 0x00d37fff, 0x00da7fff, 0x00e07fff, 0x00e77fff,
+ 0x00ee7fff, 0x00f57fff, 0x00fd7fff, 0x01047fff, 0x010c7fff, 0x01137fff, 0x011b7fff, 0x01237fff,
+ 0x012b7fff, 0x01337fff, 0x013c7ffe, 0x01447ffe, 0x014d7ffe, 0x01567ffe, 0x015f7ffe, 0x01687ffe,
+ 0x01717ffe, 0x017a7ffe, 0x01837ffe, 0x018d7ffe, 0x01977ffd, 0x01a17ffd, 0x01ab7ffd, 0x01b57ffd,
+ 0x01bf7ffd, 0x01ca7ffd, 0x01d47ffd, 0x01df7ffc, 0x01ea7ffc, 0x01f57ffc, 0x02007ffc, 0x020c7ffc,
+ 0x02177ffc, 0x02237ffb, 0x022f7ffb, 0x023b7ffb, 0x02477ffb, 0x02537ffb, 0x02607ffa, 0x026d7ffa,
+ 0x027a7ffa, 0x02877ffa, 0x02947ff9, 0x02a17ff9, 0x02af7ff9, 0x02bc7ff9, 0x02ca7ff8, 0x02d87ff8,
+ 0x02e77ff8, 0x02f57ff7, 0x03047ff7, 0x03127ff7, 0x03217ff6, 0x03317ff6, 0x03407ff5, 0x034f7ff5,
+ 0x035f7ff5, 0x036f7ff4, 0x037f7ff4, 0x038f7ff3, 0x03a07ff3, 0x03b07ff2, 0x03c17ff2, 0x03d27ff1,
+ 0x03e37ff1, 0x03f57ff0, 0x04067ff0, 0x04187fef, 0x042a7fef, 0x043c7fee, 0x044f7fed, 0x04617fed,
+ 0x04747fec, 0x04877feb, 0x049a7feb, 0x04ae7fea, 0x04c17fe9, 0x04d57fe9, 0x04e97fe8, 0x04fd7fe7,
+ 0x05127fe6, 0x05277fe5, 0x053b7fe5, 0x05507fe4, 0x05667fe3, 0x057b7fe2, 0x05917fe1, 0x05a77fe0,
+ 0x05bd7fdf, 0x05d37fde, 0x05ea7fdd, 0x06017fdc, 0x06187fdb, 0x062f7fda, 0x06467fd9, 0x065e7fd7,
+ 0x06767fd6, 0x068e7fd5, 0x06a67fd4, 0x06bf7fd2, 0x06d87fd1, 0x06f17fd0, 0x070a7fce, 0x07237fcd,
+ 0x073d7fcc, 0x07577fca, 0x07717fc9, 0x078c7fc7, 0x07a67fc5, 0x07c17fc4, 0x07dc7fc2, 0x07f77fc0,
+ 0x08137fbf, 0x082f7fbd, 0x084b7fbb, 0x08677fb9, 0x08847fb7, 0x08a07fb6, 0x08bd7fb4, 0x08da7fb2,
+ 0x08f87faf, 0x09167fad, 0x09347fab, 0x09527fa9, 0x09707fa7, 0x098f7fa5, 0x09ae7fa2, 0x09cd7fa0,
+ 0x09ec7f9d, 0x0a0c7f9b, 0x0a2c7f98, 0x0a4c7f96, 0x0a6c7f93, 0x0a8d7f91, 0x0aae7f8e, 0x0acf7f8b,
+ 0x0af07f88, 0x0b127f85, 0x0b337f82, 0x0b557f7f, 0x0b787f7c, 0x0b9a7f79, 0x0bbd7f76, 0x0be07f73,
+ 0x0c047f6f, 0x0c277f6c, 0x0c4b7f69, 0x0c6f7f65, 0x0c937f61, 0x0cb87f5e, 0x0cdd7f5a, 0x0d027f56,
+ 0x0d277f53, 0x0d4d7f4f, 0x0d737f4b, 0x0d997f47, 0x0dbf7f43, 0x0de67f3e, 0x0e0c7f3a, 0x0e347f36,
+ 0x0e5b7f31, 0x0e837f2d, 0x0eaa7f28, 0x0ed37f24, 0x0efb7f1f, 0x0f237f1a, 0x0f4c7f15, 0x0f757f10,
+ 0x0f9f7f0b, 0x0fc87f06, 0x0ff27f01, 0x101c7efb, 0x10477ef6, 0x10717ef0, 0x109c7eeb, 0x10c87ee5,
+ 0x10f37edf, 0x111f7eda, 0x114a7ed4, 0x11777ece, 0x11a37ec7, 0x11d07ec1, 0x11fd7ebb, 0x122a7eb4,
+ 0x12577eae, 0x12857ea7, 0x12b37ea0, 0x12e17e9a, 0x130f7e93, 0x133e7e8c, 0x136d7e84, 0x139c7e7d,
+ 0x13cc7e76, 0x13fb7e6e, 0x142b7e67, 0x145b7e5f, 0x148c7e57, 0x14bc7e4f, 0x14ed7e47, 0x151e7e3f,
+ 0x15507e37, 0x15817e2e, 0x15b37e26, 0x15e57e1d, 0x16187e14, 0x164a7e0b, 0x167d7e02, 0x16b07df9,
+ 0x16e47df0, 0x17177de6, 0x174b7ddd, 0x177f7dd3, 0x17b37dc9, 0x17e87dbf, 0x181d7db5, 0x18527dab,
+ 0x18877da1, 0x18bc7d96, 0x18f27d8c, 0x19287d81, 0x195e7d76, 0x19957d6b, 0x19cb7d60, 0x1a027d54,
+ 0x1a397d49, 0x1a717d3d, 0x1aa87d31, 0x1ae07d26, 0x1b187d19, 0x1b507d0d, 0x1b897d01, 0x1bc27cf4,
+ 0x1bfb7ce8, 0x1c347cdb, 0x1c6d7cce, 0x1ca77cc1, 0x1ce17cb3, 0x1d1b7ca6, 0x1d557c98, 0x1d8f7c8a,
+ 0x1dca7c7c, 0x1e057c6e, 0x1e407c60, 0x1e7b7c51, 0x1eb77c43, 0x1ef37c34, 0x1f2f7c25, 0x1f6b7c16,
+ 0x1fa77c06, 0x1fe47bf7, 0x20217be7, 0x205e7bd7, 0x209b7bc7, 0x20d87bb7, 0x21167ba6, 0x21547b96,
+ 0x21927b85, 0x21d07b74, 0x220e7b63, 0x224d7b52, 0x228c7b40, 0x22cb7b2e, 0x230a7b1c, 0x23497b0a,
+ 0x23897af8, 0x23c87ae6, 0x24087ad3, 0x24487ac0, 0x24897aad, 0x24c97a9a, 0x250a7a86, 0x254b7a73,
+ 0x258c7a5f, 0x25cd7a4b, 0x260e7a36, 0x26507a22, 0x26917a0d, 0x26d379f8, 0x271579e3, 0x275779ce,
+ 0x279a79b8, 0x27dc79a3, 0x281f798d, 0x28627977, 0x28a57960, 0x28e8794a, 0x292b7933, 0x296f791c,
+ 0x29b27905, 0x29f678ed, 0x2a3a78d6, 0x2a7e78be, 0x2ac278a6, 0x2b07788d, 0x2b4b7875, 0x2b90785c,
+ 0x2bd47843, 0x2c19782a, 0x2c5e7810, 0x2ca477f7, 0x2ce977dd, 0x2d2e77c3, 0x2d7477a8, 0x2dba778e,
+ 0x2dff7773, 0x2e457758, 0x2e8b773d, 0x2ed27721, 0x2f187706, 0x2f5e76ea, 0x2fa576cd, 0x2fec76b1,
+ 0x30327694, 0x30797677, 0x30c0765a, 0x3107763d, 0x314e761f, 0x31967601, 0x31dd75e3, 0x322575c5,
+ 0x326c75a6, 0x32b47588, 0x32fc7569, 0x33447549, 0x338c752a, 0x33d4750a, 0x341c74ea, 0x346474ca,
+ 0x34ac74a9, 0x34f57488, 0x353d7467, 0x35857446, 0x35ce7424, 0x36177403, 0x365f73e1, 0x36a873be,
+ 0x36f1739c, 0x373a7379, 0x37837356, 0x37cc7333, 0x3815730f, 0x385e72ec, 0x38a772c8, 0x38f172a3,
+ 0x393a727f, 0x3983725a, 0x39cd7235, 0x3a167210, 0x3a6071ea, 0x3aa971c4, 0x3af3719e, 0x3b3c7178,
+ 0x3b867151, 0x3bd0712b, 0x3c197104, 0x3c6370dc, 0x3cad70b5, 0x3cf7708d, 0x3d407065, 0x3d8a703c,
+ 0x3dd47014, 0x3e1e6feb, 0x3e686fc2, 0x3eb16f98, 0x3efb6f6f, 0x3f456f45, 0x3f8f6f1b, 0x3fd96ef0,
+ 0x40236ec6, 0x406d6e9b, 0x40b66e70, 0x41006e44, 0x414a6e19, 0x41946ded, 0x41de6dc1, 0x42286d94,
+ 0x42716d68, 0x42bb6d3b, 0x43056d0d, 0x434f6ce0, 0x43986cb2, 0x43e26c84, 0x442c6c56, 0x44756c28,
+ 0x44bf6bf9, 0x45086bca, 0x45526b9b, 0x459b6b6b, 0x45e56b3c, 0x462e6b0c, 0x46786adb, 0x46c16aab,
+ 0x470a6a7a, 0x47536a49, 0x479c6a18, 0x47e569e7, 0x482e69b5, 0x48776983, 0x48c06951, 0x4909691e,
+ 0x495268ec, 0x499b68b9, 0x49e36885, 0x4a2c6852, 0x4a74681e, 0x4abd67ea, 0x4b0567b6, 0x4b4d6782,
+ 0x4b95674d, 0x4bde6718, 0x4c2666e3, 0x4c6d66ae, 0x4cb56678, 0x4cfd6642, 0x4d45660c, 0x4d8c65d6,
+ 0x4dd4659f, 0x4e1b6568, 0x4e626531, 0x4ea964fa, 0x4ef064c3, 0x4f37648b, 0x4f7e6453, 0x4fc5641b,
+ 0x500b63e2, 0x505263aa, 0x50986371, 0x50df6338, 0x512562fe, 0x516b62c5, 0x51b1628b, 0x51f66251,
+ 0x523c6217, 0x528161dc, 0x52c761a2, 0x530c6167, 0x5351612c, 0x539660f1, 0x53db60b5, 0x54206079,
+ 0x5464603d, 0x54a96001, 0x54ed5fc5, 0x55315f88, 0x55755f4b, 0x55b95f0e, 0x55fc5ed1, 0x56405e94,
+ 0x56835e56, 0x56c75e18, 0x570a5dda, 0x574d5d9c, 0x578f5d5e, 0x57d25d1f, 0x58145ce0, 0x58565ca1,
0x58995c62, 0x58da5c23, 0x591c5be3, 0x595e5ba4, 0x599f5b64, 0x59e05b24, 0x5a215ae3, 0x5a625aa3
};
@@ -1070,277 +1070,277 @@
\brief these tables are used for the non
linear quantizer and inverse quantizer
-
+
*/
const Word32 mTab_3_4[512] = {
- 0x4c1bf829, 0x4c3880de, 0x4c550603, 0x4c71879c,
- 0x4c8e05aa, 0x4caa8030, 0x4cc6f72f, 0x4ce36aab,
- 0x4cffdaa4, 0x4d1c471d, 0x4d38b019, 0x4d55159a,
- 0x4d7177a1, 0x4d8dd631, 0x4daa314b, 0x4dc688f3,
- 0x4de2dd2a, 0x4dff2df2, 0x4e1b7b4d, 0x4e37c53d,
- 0x4e540bc5, 0x4e704ee6, 0x4e8c8ea3, 0x4ea8cafd,
- 0x4ec503f7, 0x4ee13992, 0x4efd6bd0, 0x4f199ab4,
- 0x4f35c640, 0x4f51ee75, 0x4f6e1356, 0x4f8a34e4,
- 0x4fa65321, 0x4fc26e10, 0x4fde85b2, 0x4ffa9a0a,
- 0x5016ab18, 0x5032b8e0, 0x504ec362, 0x506acaa1,
- 0x5086cea0, 0x50a2cf5e, 0x50becce0, 0x50dac725,
- 0x50f6be31, 0x5112b205, 0x512ea2a3, 0x514a900d,
- 0x51667a45, 0x5182614c, 0x519e4524, 0x51ba25cf,
- 0x51d60350, 0x51f1dda7, 0x520db4d6, 0x522988e0,
- 0x524559c6, 0x52612789, 0x527cf22d, 0x5298b9b1,
- 0x52b47e19, 0x52d03f65, 0x52ebfd98, 0x5307b8b4,
- 0x532370b9, 0x533f25aa, 0x535ad789, 0x53768656,
- 0x53923215, 0x53addac6, 0x53c9806b, 0x53e52306,
- 0x5400c298, 0x541c5f24, 0x5437f8ab, 0x54538f2e,
- 0x546f22af, 0x548ab330, 0x54a640b3, 0x54c1cb38,
- 0x54dd52c2, 0x54f8d753, 0x551458eb, 0x552fd78d,
- 0x554b5339, 0x5566cbf3, 0x558241bb, 0x559db492,
- 0x55b9247b, 0x55d49177, 0x55effb87, 0x560b62ad,
- 0x5626c6eb, 0x56422842, 0x565d86b4, 0x5678e242,
- 0x56943aee, 0x56af90b9, 0x56cae3a4, 0x56e633b2,
- 0x570180e4, 0x571ccb3b, 0x573812b8, 0x5753575e,
- 0x576e992e, 0x5789d829, 0x57a51450, 0x57c04da6,
- 0x57db842b, 0x57f6b7e1, 0x5811e8c9, 0x582d16e6,
- 0x58484238, 0x58636ac0, 0x587e9081, 0x5899b37c,
- 0x58b4d3b1, 0x58cff123, 0x58eb0bd3, 0x590623c2,
- 0x592138f2, 0x593c4b63, 0x59575b19, 0x59726812,
- 0x598d7253, 0x59a879da, 0x59c37eab, 0x59de80c6,
- 0x59f9802d, 0x5a147ce0, 0x5a2f76e2, 0x5a4a6e34,
- 0x5a6562d6, 0x5a8054cb, 0x5a9b4414, 0x5ab630b2,
- 0x5ad11aa6, 0x5aec01f1, 0x5b06e696, 0x5b21c895,
- 0x5b3ca7ef, 0x5b5784a6, 0x5b725ebc, 0x5b8d3631,
- 0x5ba80b06, 0x5bc2dd3e, 0x5bddacd9, 0x5bf879d8,
- 0x5c13443d, 0x5c2e0c09, 0x5c48d13e, 0x5c6393dc,
- 0x5c7e53e5, 0x5c99115a, 0x5cb3cc3c, 0x5cce848d,
- 0x5ce93a4e, 0x5d03ed80, 0x5d1e9e24, 0x5d394c3b,
- 0x5d53f7c7, 0x5d6ea0c9, 0x5d894742, 0x5da3eb33,
- 0x5dbe8c9e, 0x5dd92b84, 0x5df3c7e5, 0x5e0e61c3,
- 0x5e28f920, 0x5e438dfc, 0x5e5e2059, 0x5e78b037,
- 0x5e933d99, 0x5eadc87e, 0x5ec850e9, 0x5ee2d6da,
- 0x5efd5a53, 0x5f17db54, 0x5f3259e0, 0x5f4cd5f6,
- 0x5f674f99, 0x5f81c6c8, 0x5f9c3b87, 0x5fb6add4,
- 0x5fd11db3, 0x5feb8b23, 0x6005f626, 0x60205ebd,
- 0x603ac4e9, 0x605528ac, 0x606f8a05, 0x6089e8f7,
- 0x60a44583, 0x60be9fa9, 0x60d8f76b, 0x60f34cca,
- 0x610d9fc7, 0x6127f062, 0x61423e9e, 0x615c8a7a,
- 0x6176d3f9, 0x61911b1b, 0x61ab5fe1, 0x61c5a24d,
- 0x61dfe25f, 0x61fa2018, 0x62145b7a, 0x622e9485,
- 0x6248cb3b, 0x6262ff9d, 0x627d31ab, 0x62976167,
- 0x62b18ed1, 0x62cbb9eb, 0x62e5e2b6, 0x63000933,
- 0x631a2d62, 0x63344f45, 0x634e6edd, 0x63688c2b,
- 0x6382a730, 0x639cbfec, 0x63b6d661, 0x63d0ea90,
- 0x63eafc7a, 0x64050c1f, 0x641f1982, 0x643924a2,
- 0x64532d80, 0x646d341f, 0x6487387e, 0x64a13a9e,
- 0x64bb3a81, 0x64d53828, 0x64ef3393, 0x65092cc4,
- 0x652323bb, 0x653d1879, 0x65570b00, 0x6570fb50,
- 0x658ae96b, 0x65a4d550, 0x65bebf01, 0x65d8a680,
- 0x65f28bcc, 0x660c6ee8, 0x66264fd3, 0x66402e8f,
- 0x665a0b1c, 0x6673e57d, 0x668dbdb0, 0x66a793b8,
- 0x66c16795, 0x66db3949, 0x66f508d4, 0x670ed636,
- 0x6728a172, 0x67426a87, 0x675c3177, 0x6775f643,
- 0x678fb8eb, 0x67a97971, 0x67c337d5, 0x67dcf418,
- 0x67f6ae3b, 0x6810663f, 0x682a1c25, 0x6843cfed,
- 0x685d8199, 0x68773129, 0x6890de9f, 0x68aa89fa,
- 0x68c4333d, 0x68ddda67, 0x68f77f7a, 0x69112277,
- 0x692ac35e, 0x69446230, 0x695dfeee, 0x6977999a,
- 0x69913232, 0x69aac8ba, 0x69c45d31, 0x69ddef98,
- 0x69f77ff0, 0x6a110e3a, 0x6a2a9a77, 0x6a4424a8,
- 0x6a5daccc, 0x6a7732e6, 0x6a90b6f6, 0x6aaa38fd,
- 0x6ac3b8fb, 0x6add36f2, 0x6af6b2e2, 0x6b102ccd,
- 0x6b29a4b2, 0x6b431a92, 0x6b5c8e6f, 0x6b76004a,
- 0x6b8f7022, 0x6ba8ddf9, 0x6bc249d0, 0x6bdbb3a7,
- 0x6bf51b80, 0x6c0e815a, 0x6c27e537, 0x6c414718,
- 0x6c5aa6fd, 0x6c7404e7, 0x6c8d60d7, 0x6ca6bace,
- 0x6cc012cc, 0x6cd968d2, 0x6cf2bce1, 0x6d0c0ef9,
- 0x6d255f1d, 0x6d3ead4b, 0x6d57f985, 0x6d7143cc,
- 0x6d8a8c21, 0x6da3d283, 0x6dbd16f5, 0x6dd65976,
- 0x6def9a08, 0x6e08d8ab, 0x6e221560, 0x6e3b5027,
- 0x6e548902, 0x6e6dbff1, 0x6e86f4f5, 0x6ea0280e,
- 0x6eb9593e, 0x6ed28885, 0x6eebb5e3, 0x6f04e15a,
- 0x6f1e0aea, 0x6f373294, 0x6f505859, 0x6f697c39,
- 0x6f829e35, 0x6f9bbe4e, 0x6fb4dc85, 0x6fcdf8d9,
- 0x6fe7134d, 0x70002be0, 0x70194293, 0x70325767,
- 0x704b6a5d, 0x70647b76, 0x707d8ab1, 0x70969811,
- 0x70afa394, 0x70c8ad3d, 0x70e1b50c, 0x70fabb01,
- 0x7113bf1d, 0x712cc161, 0x7145c1ce, 0x715ec064,
- 0x7177bd24, 0x7190b80f, 0x71a9b124, 0x71c2a866,
- 0x71db9dd4, 0x71f49170, 0x720d8339, 0x72267331,
- 0x723f6159, 0x72584db0, 0x72713838, 0x728a20f1,
- 0x72a307db, 0x72bbecf9, 0x72d4d049, 0x72edb1ce,
- 0x73069187, 0x731f6f75, 0x73384b98, 0x735125f3,
- 0x7369fe84, 0x7382d54d, 0x739baa4e, 0x73b47d89,
- 0x73cd4efd, 0x73e61eab, 0x73feec94, 0x7417b8b8,
- 0x74308319, 0x74494bb6, 0x74621291, 0x747ad7aa,
- 0x74939b02, 0x74ac5c98, 0x74c51c6f, 0x74ddda86,
- 0x74f696de, 0x750f5178, 0x75280a54, 0x7540c174,
- 0x755976d7, 0x75722a7e, 0x758adc69, 0x75a38c9b,
- 0x75bc3b12, 0x75d4e7cf, 0x75ed92d4, 0x76063c21,
- 0x761ee3b6, 0x76378994, 0x76502dbc, 0x7668d02e,
- 0x768170eb, 0x769a0ff3, 0x76b2ad47, 0x76cb48e7,
- 0x76e3e2d5, 0x76fc7b10, 0x7715119a, 0x772da673,
- 0x7746399b, 0x775ecb13, 0x77775adc, 0x778fe8f6,
- 0x77a87561, 0x77c1001f, 0x77d98930, 0x77f21095,
- 0x780a964d, 0x78231a5b, 0x783b9cbd, 0x78541d75,
- 0x786c9c84, 0x788519e9, 0x789d95a6, 0x78b60fbb,
- 0x78ce8828, 0x78e6feef, 0x78ff740f, 0x7917e78a,
- 0x7930595f, 0x7948c990, 0x7961381d, 0x7979a506,
- 0x7992104c, 0x79aa79f0, 0x79c2e1f1, 0x79db4852,
- 0x79f3ad11, 0x7a0c1031, 0x7a2471b0, 0x7a3cd191,
- 0x7a552fd3, 0x7a6d8c76, 0x7a85e77d, 0x7a9e40e6,
- 0x7ab698b2, 0x7aceeee3, 0x7ae74378, 0x7aff9673,
- 0x7b17e7d2, 0x7b303799, 0x7b4885c5, 0x7b60d259,
- 0x7b791d55, 0x7b9166b9, 0x7ba9ae86, 0x7bc1f4bc,
- 0x7bda395c, 0x7bf27c66, 0x7c0abddb, 0x7c22fdbb,
- 0x7c3b3c07, 0x7c5378c0, 0x7c6bb3e5, 0x7c83ed78,
- 0x7c9c2579, 0x7cb45be9, 0x7ccc90c7, 0x7ce4c414,
- 0x7cfcf5d2, 0x7d152600, 0x7d2d549f, 0x7d4581b0,
- 0x7d5dad32, 0x7d75d727, 0x7d8dff8f, 0x7da6266a,
- 0x7dbe4bba, 0x7dd66f7d, 0x7dee91b6, 0x7e06b264,
- 0x7e1ed188, 0x7e36ef22, 0x7e4f0b34, 0x7e6725bd,
- 0x7e7f3ebd, 0x7e975636, 0x7eaf6c28, 0x7ec78093,
- 0x7edf9378, 0x7ef7a4d7, 0x7f0fb4b1, 0x7f27c307,
- 0x7f3fcfd8, 0x7f57db25, 0x7f6fe4ef, 0x7f87ed36,
+ 0x4c1bf829, 0x4c3880de, 0x4c550603, 0x4c71879c,
+ 0x4c8e05aa, 0x4caa8030, 0x4cc6f72f, 0x4ce36aab,
+ 0x4cffdaa4, 0x4d1c471d, 0x4d38b019, 0x4d55159a,
+ 0x4d7177a1, 0x4d8dd631, 0x4daa314b, 0x4dc688f3,
+ 0x4de2dd2a, 0x4dff2df2, 0x4e1b7b4d, 0x4e37c53d,
+ 0x4e540bc5, 0x4e704ee6, 0x4e8c8ea3, 0x4ea8cafd,
+ 0x4ec503f7, 0x4ee13992, 0x4efd6bd0, 0x4f199ab4,
+ 0x4f35c640, 0x4f51ee75, 0x4f6e1356, 0x4f8a34e4,
+ 0x4fa65321, 0x4fc26e10, 0x4fde85b2, 0x4ffa9a0a,
+ 0x5016ab18, 0x5032b8e0, 0x504ec362, 0x506acaa1,
+ 0x5086cea0, 0x50a2cf5e, 0x50becce0, 0x50dac725,
+ 0x50f6be31, 0x5112b205, 0x512ea2a3, 0x514a900d,
+ 0x51667a45, 0x5182614c, 0x519e4524, 0x51ba25cf,
+ 0x51d60350, 0x51f1dda7, 0x520db4d6, 0x522988e0,
+ 0x524559c6, 0x52612789, 0x527cf22d, 0x5298b9b1,
+ 0x52b47e19, 0x52d03f65, 0x52ebfd98, 0x5307b8b4,
+ 0x532370b9, 0x533f25aa, 0x535ad789, 0x53768656,
+ 0x53923215, 0x53addac6, 0x53c9806b, 0x53e52306,
+ 0x5400c298, 0x541c5f24, 0x5437f8ab, 0x54538f2e,
+ 0x546f22af, 0x548ab330, 0x54a640b3, 0x54c1cb38,
+ 0x54dd52c2, 0x54f8d753, 0x551458eb, 0x552fd78d,
+ 0x554b5339, 0x5566cbf3, 0x558241bb, 0x559db492,
+ 0x55b9247b, 0x55d49177, 0x55effb87, 0x560b62ad,
+ 0x5626c6eb, 0x56422842, 0x565d86b4, 0x5678e242,
+ 0x56943aee, 0x56af90b9, 0x56cae3a4, 0x56e633b2,
+ 0x570180e4, 0x571ccb3b, 0x573812b8, 0x5753575e,
+ 0x576e992e, 0x5789d829, 0x57a51450, 0x57c04da6,
+ 0x57db842b, 0x57f6b7e1, 0x5811e8c9, 0x582d16e6,
+ 0x58484238, 0x58636ac0, 0x587e9081, 0x5899b37c,
+ 0x58b4d3b1, 0x58cff123, 0x58eb0bd3, 0x590623c2,
+ 0x592138f2, 0x593c4b63, 0x59575b19, 0x59726812,
+ 0x598d7253, 0x59a879da, 0x59c37eab, 0x59de80c6,
+ 0x59f9802d, 0x5a147ce0, 0x5a2f76e2, 0x5a4a6e34,
+ 0x5a6562d6, 0x5a8054cb, 0x5a9b4414, 0x5ab630b2,
+ 0x5ad11aa6, 0x5aec01f1, 0x5b06e696, 0x5b21c895,
+ 0x5b3ca7ef, 0x5b5784a6, 0x5b725ebc, 0x5b8d3631,
+ 0x5ba80b06, 0x5bc2dd3e, 0x5bddacd9, 0x5bf879d8,
+ 0x5c13443d, 0x5c2e0c09, 0x5c48d13e, 0x5c6393dc,
+ 0x5c7e53e5, 0x5c99115a, 0x5cb3cc3c, 0x5cce848d,
+ 0x5ce93a4e, 0x5d03ed80, 0x5d1e9e24, 0x5d394c3b,
+ 0x5d53f7c7, 0x5d6ea0c9, 0x5d894742, 0x5da3eb33,
+ 0x5dbe8c9e, 0x5dd92b84, 0x5df3c7e5, 0x5e0e61c3,
+ 0x5e28f920, 0x5e438dfc, 0x5e5e2059, 0x5e78b037,
+ 0x5e933d99, 0x5eadc87e, 0x5ec850e9, 0x5ee2d6da,
+ 0x5efd5a53, 0x5f17db54, 0x5f3259e0, 0x5f4cd5f6,
+ 0x5f674f99, 0x5f81c6c8, 0x5f9c3b87, 0x5fb6add4,
+ 0x5fd11db3, 0x5feb8b23, 0x6005f626, 0x60205ebd,
+ 0x603ac4e9, 0x605528ac, 0x606f8a05, 0x6089e8f7,
+ 0x60a44583, 0x60be9fa9, 0x60d8f76b, 0x60f34cca,
+ 0x610d9fc7, 0x6127f062, 0x61423e9e, 0x615c8a7a,
+ 0x6176d3f9, 0x61911b1b, 0x61ab5fe1, 0x61c5a24d,
+ 0x61dfe25f, 0x61fa2018, 0x62145b7a, 0x622e9485,
+ 0x6248cb3b, 0x6262ff9d, 0x627d31ab, 0x62976167,
+ 0x62b18ed1, 0x62cbb9eb, 0x62e5e2b6, 0x63000933,
+ 0x631a2d62, 0x63344f45, 0x634e6edd, 0x63688c2b,
+ 0x6382a730, 0x639cbfec, 0x63b6d661, 0x63d0ea90,
+ 0x63eafc7a, 0x64050c1f, 0x641f1982, 0x643924a2,
+ 0x64532d80, 0x646d341f, 0x6487387e, 0x64a13a9e,
+ 0x64bb3a81, 0x64d53828, 0x64ef3393, 0x65092cc4,
+ 0x652323bb, 0x653d1879, 0x65570b00, 0x6570fb50,
+ 0x658ae96b, 0x65a4d550, 0x65bebf01, 0x65d8a680,
+ 0x65f28bcc, 0x660c6ee8, 0x66264fd3, 0x66402e8f,
+ 0x665a0b1c, 0x6673e57d, 0x668dbdb0, 0x66a793b8,
+ 0x66c16795, 0x66db3949, 0x66f508d4, 0x670ed636,
+ 0x6728a172, 0x67426a87, 0x675c3177, 0x6775f643,
+ 0x678fb8eb, 0x67a97971, 0x67c337d5, 0x67dcf418,
+ 0x67f6ae3b, 0x6810663f, 0x682a1c25, 0x6843cfed,
+ 0x685d8199, 0x68773129, 0x6890de9f, 0x68aa89fa,
+ 0x68c4333d, 0x68ddda67, 0x68f77f7a, 0x69112277,
+ 0x692ac35e, 0x69446230, 0x695dfeee, 0x6977999a,
+ 0x69913232, 0x69aac8ba, 0x69c45d31, 0x69ddef98,
+ 0x69f77ff0, 0x6a110e3a, 0x6a2a9a77, 0x6a4424a8,
+ 0x6a5daccc, 0x6a7732e6, 0x6a90b6f6, 0x6aaa38fd,
+ 0x6ac3b8fb, 0x6add36f2, 0x6af6b2e2, 0x6b102ccd,
+ 0x6b29a4b2, 0x6b431a92, 0x6b5c8e6f, 0x6b76004a,
+ 0x6b8f7022, 0x6ba8ddf9, 0x6bc249d0, 0x6bdbb3a7,
+ 0x6bf51b80, 0x6c0e815a, 0x6c27e537, 0x6c414718,
+ 0x6c5aa6fd, 0x6c7404e7, 0x6c8d60d7, 0x6ca6bace,
+ 0x6cc012cc, 0x6cd968d2, 0x6cf2bce1, 0x6d0c0ef9,
+ 0x6d255f1d, 0x6d3ead4b, 0x6d57f985, 0x6d7143cc,
+ 0x6d8a8c21, 0x6da3d283, 0x6dbd16f5, 0x6dd65976,
+ 0x6def9a08, 0x6e08d8ab, 0x6e221560, 0x6e3b5027,
+ 0x6e548902, 0x6e6dbff1, 0x6e86f4f5, 0x6ea0280e,
+ 0x6eb9593e, 0x6ed28885, 0x6eebb5e3, 0x6f04e15a,
+ 0x6f1e0aea, 0x6f373294, 0x6f505859, 0x6f697c39,
+ 0x6f829e35, 0x6f9bbe4e, 0x6fb4dc85, 0x6fcdf8d9,
+ 0x6fe7134d, 0x70002be0, 0x70194293, 0x70325767,
+ 0x704b6a5d, 0x70647b76, 0x707d8ab1, 0x70969811,
+ 0x70afa394, 0x70c8ad3d, 0x70e1b50c, 0x70fabb01,
+ 0x7113bf1d, 0x712cc161, 0x7145c1ce, 0x715ec064,
+ 0x7177bd24, 0x7190b80f, 0x71a9b124, 0x71c2a866,
+ 0x71db9dd4, 0x71f49170, 0x720d8339, 0x72267331,
+ 0x723f6159, 0x72584db0, 0x72713838, 0x728a20f1,
+ 0x72a307db, 0x72bbecf9, 0x72d4d049, 0x72edb1ce,
+ 0x73069187, 0x731f6f75, 0x73384b98, 0x735125f3,
+ 0x7369fe84, 0x7382d54d, 0x739baa4e, 0x73b47d89,
+ 0x73cd4efd, 0x73e61eab, 0x73feec94, 0x7417b8b8,
+ 0x74308319, 0x74494bb6, 0x74621291, 0x747ad7aa,
+ 0x74939b02, 0x74ac5c98, 0x74c51c6f, 0x74ddda86,
+ 0x74f696de, 0x750f5178, 0x75280a54, 0x7540c174,
+ 0x755976d7, 0x75722a7e, 0x758adc69, 0x75a38c9b,
+ 0x75bc3b12, 0x75d4e7cf, 0x75ed92d4, 0x76063c21,
+ 0x761ee3b6, 0x76378994, 0x76502dbc, 0x7668d02e,
+ 0x768170eb, 0x769a0ff3, 0x76b2ad47, 0x76cb48e7,
+ 0x76e3e2d5, 0x76fc7b10, 0x7715119a, 0x772da673,
+ 0x7746399b, 0x775ecb13, 0x77775adc, 0x778fe8f6,
+ 0x77a87561, 0x77c1001f, 0x77d98930, 0x77f21095,
+ 0x780a964d, 0x78231a5b, 0x783b9cbd, 0x78541d75,
+ 0x786c9c84, 0x788519e9, 0x789d95a6, 0x78b60fbb,
+ 0x78ce8828, 0x78e6feef, 0x78ff740f, 0x7917e78a,
+ 0x7930595f, 0x7948c990, 0x7961381d, 0x7979a506,
+ 0x7992104c, 0x79aa79f0, 0x79c2e1f1, 0x79db4852,
+ 0x79f3ad11, 0x7a0c1031, 0x7a2471b0, 0x7a3cd191,
+ 0x7a552fd3, 0x7a6d8c76, 0x7a85e77d, 0x7a9e40e6,
+ 0x7ab698b2, 0x7aceeee3, 0x7ae74378, 0x7aff9673,
+ 0x7b17e7d2, 0x7b303799, 0x7b4885c5, 0x7b60d259,
+ 0x7b791d55, 0x7b9166b9, 0x7ba9ae86, 0x7bc1f4bc,
+ 0x7bda395c, 0x7bf27c66, 0x7c0abddb, 0x7c22fdbb,
+ 0x7c3b3c07, 0x7c5378c0, 0x7c6bb3e5, 0x7c83ed78,
+ 0x7c9c2579, 0x7cb45be9, 0x7ccc90c7, 0x7ce4c414,
+ 0x7cfcf5d2, 0x7d152600, 0x7d2d549f, 0x7d4581b0,
+ 0x7d5dad32, 0x7d75d727, 0x7d8dff8f, 0x7da6266a,
+ 0x7dbe4bba, 0x7dd66f7d, 0x7dee91b6, 0x7e06b264,
+ 0x7e1ed188, 0x7e36ef22, 0x7e4f0b34, 0x7e6725bd,
+ 0x7e7f3ebd, 0x7e975636, 0x7eaf6c28, 0x7ec78093,
+ 0x7edf9378, 0x7ef7a4d7, 0x7f0fb4b1, 0x7f27c307,
+ 0x7f3fcfd8, 0x7f57db25, 0x7f6fe4ef, 0x7f87ed36,
0x7f9ff3fb, 0x7fb7f93e, 0x7fcffcff, 0x7fe7ff40
};
const Word32 mTab_4_3[512]={
- 0x32cbfd4a, 0x32eddd70, 0x330fc339, 0x3331aea3,
- 0x33539fac, 0x33759652, 0x33979294, 0x33b99470,
- 0x33db9be4, 0x33fda8ed, 0x341fbb8b, 0x3441d3bb,
- 0x3463f17c, 0x348614cc, 0x34a83da8, 0x34ca6c10,
- 0x34eca001, 0x350ed979, 0x35311877, 0x35535cfa,
- 0x3575a6fe, 0x3597f683, 0x35ba4b87, 0x35dca607,
- 0x35ff0603, 0x36216b78, 0x3643d665, 0x366646c7,
- 0x3688bc9e, 0x36ab37e8, 0x36cdb8a2, 0x36f03ecb,
- 0x3712ca62, 0x37355b64, 0x3757f1d1, 0x377a8da5,
- 0x379d2ee0, 0x37bfd580, 0x37e28184, 0x380532e8,
- 0x3827e9ad, 0x384aa5d0, 0x386d674f, 0x38902e2a,
- 0x38b2fa5d, 0x38d5cbe9, 0x38f8a2ca, 0x391b7eff,
- 0x393e6088, 0x39614761, 0x3984338a, 0x39a72501,
- 0x39ca1bc4, 0x39ed17d1, 0x3a101928, 0x3a331fc6,
- 0x3a562baa, 0x3a793cd2, 0x3a9c533d, 0x3abf6ee9,
- 0x3ae28fd5, 0x3b05b5ff, 0x3b28e165, 0x3b4c1206,
- 0x3b6f47e0, 0x3b9282f2, 0x3bb5c33a, 0x3bd908b7,
- 0x3bfc5368, 0x3c1fa349, 0x3c42f85b, 0x3c66529c,
- 0x3c89b209, 0x3cad16a2, 0x3cd08065, 0x3cf3ef51,
- 0x3d176364, 0x3d3adc9c, 0x3d5e5af8, 0x3d81de77,
- 0x3da56717, 0x3dc8f4d6, 0x3dec87b4, 0x3e101fae,
- 0x3e33bcc3, 0x3e575ef2, 0x3e7b063a, 0x3e9eb298,
- 0x3ec2640c, 0x3ee61a93, 0x3f09d62d, 0x3f2d96d8,
- 0x3f515c93, 0x3f75275b, 0x3f98f731, 0x3fbccc11,
- 0x3fe0a5fc, 0x400484ef, 0x402868ea, 0x404c51e9,
- 0x40703fee, 0x409432f5, 0x40b82afd, 0x40dc2806,
- 0x41002a0d, 0x41243111, 0x41483d12, 0x416c4e0d,
- 0x41906401, 0x41b47eed, 0x41d89ecf, 0x41fcc3a7,
- 0x4220ed72, 0x42451c30, 0x42694fde, 0x428d887d,
- 0x42b1c609, 0x42d60883, 0x42fa4fe8, 0x431e9c37,
- 0x4342ed70, 0x43674390, 0x438b9e96, 0x43affe82,
- 0x43d46351, 0x43f8cd03, 0x441d3b95, 0x4441af08,
- 0x44662758, 0x448aa487, 0x44af2690, 0x44d3ad75,
- 0x44f83933, 0x451cc9c8, 0x45415f35, 0x4565f977,
- 0x458a988d, 0x45af3c76, 0x45d3e531, 0x45f892bc,
- 0x461d4516, 0x4641fc3e, 0x4666b832, 0x468b78f2,
- 0x46b03e7c, 0x46d508cf, 0x46f9d7e9, 0x471eabca,
- 0x47438470, 0x476861d9, 0x478d4406, 0x47b22af3,
- 0x47d716a1, 0x47fc070e, 0x4820fc39, 0x4845f620,
- 0x486af4c3, 0x488ff820, 0x48b50035, 0x48da0d03,
- 0x48ff1e87, 0x492434c0, 0x49494fad, 0x496e6f4d,
- 0x4993939f, 0x49b8bca2, 0x49ddea54, 0x4a031cb4,
- 0x4a2853c1, 0x4a4d8f7a, 0x4a72cfde, 0x4a9814eb,
- 0x4abd5ea1, 0x4ae2acfd, 0x4b080000, 0x4b2d57a8,
- 0x4b52b3f3, 0x4b7814e1, 0x4b9d7a70, 0x4bc2e49f,
- 0x4be8536e, 0x4c0dc6db, 0x4c333ee4, 0x4c58bb89,
- 0x4c7e3cc9, 0x4ca3c2a2, 0x4cc94d14, 0x4ceedc1c,
- 0x4d146fbb, 0x4d3a07ef, 0x4d5fa4b6, 0x4d854611,
- 0x4daaebfd, 0x4dd09679, 0x4df64585, 0x4e1bf91f,
- 0x4e41b146, 0x4e676dfa, 0x4e8d2f38, 0x4eb2f501,
- 0x4ed8bf52, 0x4efe8e2b, 0x4f24618a, 0x4f4a3970,
- 0x4f7015d9, 0x4f95f6c6, 0x4fbbdc36, 0x4fe1c626,
- 0x5007b497, 0x502da787, 0x50539ef5, 0x50799ae1,
- 0x509f9b48, 0x50c5a02a, 0x50eba985, 0x5111b75a,
- 0x5137c9a6, 0x515de069, 0x5183fba2, 0x51aa1b4f,
- 0x51d03f70, 0x51f66803, 0x521c9508, 0x5242c67d,
- 0x5268fc62, 0x528f36b5, 0x52b57575, 0x52dbb8a2,
- 0x5302003a, 0x53284c3c, 0x534e9ca8, 0x5374f17c,
- 0x539b4ab7, 0x53c1a858, 0x53e80a5f, 0x540e70ca,
- 0x5434db98, 0x545b4ac8, 0x5481be5a, 0x54a8364b,
- 0x54ceb29c, 0x54f5334c, 0x551bb858, 0x554241c1,
- 0x5568cf85, 0x558f61a3, 0x55b5f81b, 0x55dc92eb,
- 0x56033212, 0x5629d590, 0x56507d63, 0x5677298a,
- 0x569dda05, 0x56c48ed3, 0x56eb47f2, 0x57120562,
- 0x5738c721, 0x575f8d2f, 0x5786578a, 0x57ad2633,
- 0x57d3f927, 0x57fad066, 0x5821abef, 0x58488bc0,
- 0x586f6fda, 0x5896583b, 0x58bd44e2, 0x58e435ce,
- 0x590b2aff, 0x59322473, 0x59592229, 0x59802420,
- 0x59a72a59, 0x59ce34d0, 0x59f54387, 0x5a1c567b,
- 0x5a436dac, 0x5a6a8919, 0x5a91a8c1, 0x5ab8cca3,
- 0x5adff4be, 0x5b072111, 0x5b2e519c, 0x5b55865e,
- 0x5b7cbf54, 0x5ba3fc80, 0x5bcb3ddf, 0x5bf28371,
- 0x5c19cd35, 0x5c411b2a, 0x5c686d4f, 0x5c8fc3a4,
- 0x5cb71e27, 0x5cde7cd7, 0x5d05dfb4, 0x5d2d46bd,
- 0x5d54b1f0, 0x5d7c214e, 0x5da394d4, 0x5dcb0c83,
- 0x5df28859, 0x5e1a0856, 0x5e418c78, 0x5e6914be,
- 0x5e90a129, 0x5eb831b7, 0x5edfc667, 0x5f075f38,
- 0x5f2efc29, 0x5f569d3a, 0x5f7e426a, 0x5fa5ebb7,
- 0x5fcd9921, 0x5ff54aa8, 0x601d004a, 0x6044ba06,
- 0x606c77dc, 0x609439ca, 0x60bbffd0, 0x60e3c9ee,
- 0x610b9821, 0x61336a6a, 0x615b40c8, 0x61831b39,
- 0x61aaf9bd, 0x61d2dc53, 0x61fac2fa, 0x6222adb2,
- 0x624a9c79, 0x62728f4f, 0x629a8633, 0x62c28123,
- 0x62ea8020, 0x63128329, 0x633a8a3c, 0x63629559,
- 0x638aa47f, 0x63b2b7ad, 0x63dacee2, 0x6402ea1e,
- 0x642b0960, 0x64532ca6, 0x647b53f1, 0x64a37f3f,
- 0x64cbae8f, 0x64f3e1e2, 0x651c1935, 0x65445488,
- 0x656c93db, 0x6594d72c, 0x65bd1e7b, 0x65e569c7,
- 0x660db90f, 0x66360c53, 0x665e6391, 0x6686bec9,
- 0x66af1dfa, 0x66d78123, 0x66ffe844, 0x6728535b,
- 0x6750c268, 0x6779356b, 0x67a1ac62, 0x67ca274c,
- 0x67f2a629, 0x681b28f9, 0x6843afb9, 0x686c3a6a,
- 0x6894c90b, 0x68bd5b9b, 0x68e5f219, 0x690e8c84,
- 0x69372add, 0x695fcd21, 0x69887350, 0x69b11d6a,
- 0x69d9cb6d, 0x6a027d5a, 0x6a2b332f, 0x6a53eceb,
- 0x6a7caa8d, 0x6aa56c16, 0x6ace3184, 0x6af6fad6,
- 0x6b1fc80c, 0x6b489925, 0x6b716e20, 0x6b9a46fd,
- 0x6bc323bb, 0x6bec0458, 0x6c14e8d5, 0x6c3dd130,
- 0x6c66bd69, 0x6c8fad80, 0x6cb8a172, 0x6ce19940,
- 0x6d0a94e9, 0x6d33946d, 0x6d5c97ca, 0x6d859eff,
- 0x6daeaa0d, 0x6dd7b8f1, 0x6e00cbad, 0x6e29e23e,
- 0x6e52fca4, 0x6e7c1adf, 0x6ea53cee, 0x6ece62cf,
- 0x6ef78c83, 0x6f20ba09, 0x6f49eb5f, 0x6f732085,
- 0x6f9c597b, 0x6fc59640, 0x6feed6d3, 0x70181b33,
- 0x70416360, 0x706aaf59, 0x7093ff1d, 0x70bd52ab,
- 0x70e6aa04, 0x71100525, 0x7139640f, 0x7162c6c1,
- 0x718c2d3a, 0x71b5977a, 0x71df057f, 0x72087749,
- 0x7231ecd8, 0x725b662a, 0x7284e33f, 0x72ae6417,
- 0x72d7e8b0, 0x7301710a, 0x732afd24, 0x73548cfe,
- 0x737e2097, 0x73a7b7ee, 0x73d15303, 0x73faf1d5,
- 0x74249462, 0x744e3aac, 0x7477e4b0, 0x74a1926e,
- 0x74cb43e6, 0x74f4f917, 0x751eb201, 0x75486ea1,
- 0x75722ef9, 0x759bf307, 0x75c5baca, 0x75ef8642,
- 0x7619556f, 0x7643284f, 0x766cfee2, 0x7696d928,
- 0x76c0b71f, 0x76ea98c7, 0x77147e20, 0x773e6728,
- 0x776853df, 0x77924445, 0x77bc3858, 0x77e63019,
- 0x78102b85, 0x783a2a9e, 0x78642d62, 0x788e33d1,
- 0x78b83de9, 0x78e24bab, 0x790c5d15, 0x79367228,
- 0x79608ae1, 0x798aa742, 0x79b4c748, 0x79deeaf4,
- 0x7a091245, 0x7a333d3a, 0x7a5d6bd2, 0x7a879e0e,
- 0x7ab1d3ec, 0x7adc0d6b, 0x7b064a8c, 0x7b308b4d,
- 0x7b5acfae, 0x7b8517ae, 0x7baf634c, 0x7bd9b289,
- 0x7c040563, 0x7c2e5bda, 0x7c58b5ec, 0x7c83139b,
- 0x7cad74e4, 0x7cd7d9c7, 0x7d024244, 0x7d2cae5a,
- 0x7d571e09, 0x7d81914f, 0x7dac082d, 0x7dd682a1,
- 0x7e0100ac, 0x7e2b824b, 0x7e560780, 0x7e809048,
- 0x7eab1ca5, 0x7ed5ac94, 0x7f004015, 0x7f2ad729,
+ 0x32cbfd4a, 0x32eddd70, 0x330fc339, 0x3331aea3,
+ 0x33539fac, 0x33759652, 0x33979294, 0x33b99470,
+ 0x33db9be4, 0x33fda8ed, 0x341fbb8b, 0x3441d3bb,
+ 0x3463f17c, 0x348614cc, 0x34a83da8, 0x34ca6c10,
+ 0x34eca001, 0x350ed979, 0x35311877, 0x35535cfa,
+ 0x3575a6fe, 0x3597f683, 0x35ba4b87, 0x35dca607,
+ 0x35ff0603, 0x36216b78, 0x3643d665, 0x366646c7,
+ 0x3688bc9e, 0x36ab37e8, 0x36cdb8a2, 0x36f03ecb,
+ 0x3712ca62, 0x37355b64, 0x3757f1d1, 0x377a8da5,
+ 0x379d2ee0, 0x37bfd580, 0x37e28184, 0x380532e8,
+ 0x3827e9ad, 0x384aa5d0, 0x386d674f, 0x38902e2a,
+ 0x38b2fa5d, 0x38d5cbe9, 0x38f8a2ca, 0x391b7eff,
+ 0x393e6088, 0x39614761, 0x3984338a, 0x39a72501,
+ 0x39ca1bc4, 0x39ed17d1, 0x3a101928, 0x3a331fc6,
+ 0x3a562baa, 0x3a793cd2, 0x3a9c533d, 0x3abf6ee9,
+ 0x3ae28fd5, 0x3b05b5ff, 0x3b28e165, 0x3b4c1206,
+ 0x3b6f47e0, 0x3b9282f2, 0x3bb5c33a, 0x3bd908b7,
+ 0x3bfc5368, 0x3c1fa349, 0x3c42f85b, 0x3c66529c,
+ 0x3c89b209, 0x3cad16a2, 0x3cd08065, 0x3cf3ef51,
+ 0x3d176364, 0x3d3adc9c, 0x3d5e5af8, 0x3d81de77,
+ 0x3da56717, 0x3dc8f4d6, 0x3dec87b4, 0x3e101fae,
+ 0x3e33bcc3, 0x3e575ef2, 0x3e7b063a, 0x3e9eb298,
+ 0x3ec2640c, 0x3ee61a93, 0x3f09d62d, 0x3f2d96d8,
+ 0x3f515c93, 0x3f75275b, 0x3f98f731, 0x3fbccc11,
+ 0x3fe0a5fc, 0x400484ef, 0x402868ea, 0x404c51e9,
+ 0x40703fee, 0x409432f5, 0x40b82afd, 0x40dc2806,
+ 0x41002a0d, 0x41243111, 0x41483d12, 0x416c4e0d,
+ 0x41906401, 0x41b47eed, 0x41d89ecf, 0x41fcc3a7,
+ 0x4220ed72, 0x42451c30, 0x42694fde, 0x428d887d,
+ 0x42b1c609, 0x42d60883, 0x42fa4fe8, 0x431e9c37,
+ 0x4342ed70, 0x43674390, 0x438b9e96, 0x43affe82,
+ 0x43d46351, 0x43f8cd03, 0x441d3b95, 0x4441af08,
+ 0x44662758, 0x448aa487, 0x44af2690, 0x44d3ad75,
+ 0x44f83933, 0x451cc9c8, 0x45415f35, 0x4565f977,
+ 0x458a988d, 0x45af3c76, 0x45d3e531, 0x45f892bc,
+ 0x461d4516, 0x4641fc3e, 0x4666b832, 0x468b78f2,
+ 0x46b03e7c, 0x46d508cf, 0x46f9d7e9, 0x471eabca,
+ 0x47438470, 0x476861d9, 0x478d4406, 0x47b22af3,
+ 0x47d716a1, 0x47fc070e, 0x4820fc39, 0x4845f620,
+ 0x486af4c3, 0x488ff820, 0x48b50035, 0x48da0d03,
+ 0x48ff1e87, 0x492434c0, 0x49494fad, 0x496e6f4d,
+ 0x4993939f, 0x49b8bca2, 0x49ddea54, 0x4a031cb4,
+ 0x4a2853c1, 0x4a4d8f7a, 0x4a72cfde, 0x4a9814eb,
+ 0x4abd5ea1, 0x4ae2acfd, 0x4b080000, 0x4b2d57a8,
+ 0x4b52b3f3, 0x4b7814e1, 0x4b9d7a70, 0x4bc2e49f,
+ 0x4be8536e, 0x4c0dc6db, 0x4c333ee4, 0x4c58bb89,
+ 0x4c7e3cc9, 0x4ca3c2a2, 0x4cc94d14, 0x4ceedc1c,
+ 0x4d146fbb, 0x4d3a07ef, 0x4d5fa4b6, 0x4d854611,
+ 0x4daaebfd, 0x4dd09679, 0x4df64585, 0x4e1bf91f,
+ 0x4e41b146, 0x4e676dfa, 0x4e8d2f38, 0x4eb2f501,
+ 0x4ed8bf52, 0x4efe8e2b, 0x4f24618a, 0x4f4a3970,
+ 0x4f7015d9, 0x4f95f6c6, 0x4fbbdc36, 0x4fe1c626,
+ 0x5007b497, 0x502da787, 0x50539ef5, 0x50799ae1,
+ 0x509f9b48, 0x50c5a02a, 0x50eba985, 0x5111b75a,
+ 0x5137c9a6, 0x515de069, 0x5183fba2, 0x51aa1b4f,
+ 0x51d03f70, 0x51f66803, 0x521c9508, 0x5242c67d,
+ 0x5268fc62, 0x528f36b5, 0x52b57575, 0x52dbb8a2,
+ 0x5302003a, 0x53284c3c, 0x534e9ca8, 0x5374f17c,
+ 0x539b4ab7, 0x53c1a858, 0x53e80a5f, 0x540e70ca,
+ 0x5434db98, 0x545b4ac8, 0x5481be5a, 0x54a8364b,
+ 0x54ceb29c, 0x54f5334c, 0x551bb858, 0x554241c1,
+ 0x5568cf85, 0x558f61a3, 0x55b5f81b, 0x55dc92eb,
+ 0x56033212, 0x5629d590, 0x56507d63, 0x5677298a,
+ 0x569dda05, 0x56c48ed3, 0x56eb47f2, 0x57120562,
+ 0x5738c721, 0x575f8d2f, 0x5786578a, 0x57ad2633,
+ 0x57d3f927, 0x57fad066, 0x5821abef, 0x58488bc0,
+ 0x586f6fda, 0x5896583b, 0x58bd44e2, 0x58e435ce,
+ 0x590b2aff, 0x59322473, 0x59592229, 0x59802420,
+ 0x59a72a59, 0x59ce34d0, 0x59f54387, 0x5a1c567b,
+ 0x5a436dac, 0x5a6a8919, 0x5a91a8c1, 0x5ab8cca3,
+ 0x5adff4be, 0x5b072111, 0x5b2e519c, 0x5b55865e,
+ 0x5b7cbf54, 0x5ba3fc80, 0x5bcb3ddf, 0x5bf28371,
+ 0x5c19cd35, 0x5c411b2a, 0x5c686d4f, 0x5c8fc3a4,
+ 0x5cb71e27, 0x5cde7cd7, 0x5d05dfb4, 0x5d2d46bd,
+ 0x5d54b1f0, 0x5d7c214e, 0x5da394d4, 0x5dcb0c83,
+ 0x5df28859, 0x5e1a0856, 0x5e418c78, 0x5e6914be,
+ 0x5e90a129, 0x5eb831b7, 0x5edfc667, 0x5f075f38,
+ 0x5f2efc29, 0x5f569d3a, 0x5f7e426a, 0x5fa5ebb7,
+ 0x5fcd9921, 0x5ff54aa8, 0x601d004a, 0x6044ba06,
+ 0x606c77dc, 0x609439ca, 0x60bbffd0, 0x60e3c9ee,
+ 0x610b9821, 0x61336a6a, 0x615b40c8, 0x61831b39,
+ 0x61aaf9bd, 0x61d2dc53, 0x61fac2fa, 0x6222adb2,
+ 0x624a9c79, 0x62728f4f, 0x629a8633, 0x62c28123,
+ 0x62ea8020, 0x63128329, 0x633a8a3c, 0x63629559,
+ 0x638aa47f, 0x63b2b7ad, 0x63dacee2, 0x6402ea1e,
+ 0x642b0960, 0x64532ca6, 0x647b53f1, 0x64a37f3f,
+ 0x64cbae8f, 0x64f3e1e2, 0x651c1935, 0x65445488,
+ 0x656c93db, 0x6594d72c, 0x65bd1e7b, 0x65e569c7,
+ 0x660db90f, 0x66360c53, 0x665e6391, 0x6686bec9,
+ 0x66af1dfa, 0x66d78123, 0x66ffe844, 0x6728535b,
+ 0x6750c268, 0x6779356b, 0x67a1ac62, 0x67ca274c,
+ 0x67f2a629, 0x681b28f9, 0x6843afb9, 0x686c3a6a,
+ 0x6894c90b, 0x68bd5b9b, 0x68e5f219, 0x690e8c84,
+ 0x69372add, 0x695fcd21, 0x69887350, 0x69b11d6a,
+ 0x69d9cb6d, 0x6a027d5a, 0x6a2b332f, 0x6a53eceb,
+ 0x6a7caa8d, 0x6aa56c16, 0x6ace3184, 0x6af6fad6,
+ 0x6b1fc80c, 0x6b489925, 0x6b716e20, 0x6b9a46fd,
+ 0x6bc323bb, 0x6bec0458, 0x6c14e8d5, 0x6c3dd130,
+ 0x6c66bd69, 0x6c8fad80, 0x6cb8a172, 0x6ce19940,
+ 0x6d0a94e9, 0x6d33946d, 0x6d5c97ca, 0x6d859eff,
+ 0x6daeaa0d, 0x6dd7b8f1, 0x6e00cbad, 0x6e29e23e,
+ 0x6e52fca4, 0x6e7c1adf, 0x6ea53cee, 0x6ece62cf,
+ 0x6ef78c83, 0x6f20ba09, 0x6f49eb5f, 0x6f732085,
+ 0x6f9c597b, 0x6fc59640, 0x6feed6d3, 0x70181b33,
+ 0x70416360, 0x706aaf59, 0x7093ff1d, 0x70bd52ab,
+ 0x70e6aa04, 0x71100525, 0x7139640f, 0x7162c6c1,
+ 0x718c2d3a, 0x71b5977a, 0x71df057f, 0x72087749,
+ 0x7231ecd8, 0x725b662a, 0x7284e33f, 0x72ae6417,
+ 0x72d7e8b0, 0x7301710a, 0x732afd24, 0x73548cfe,
+ 0x737e2097, 0x73a7b7ee, 0x73d15303, 0x73faf1d5,
+ 0x74249462, 0x744e3aac, 0x7477e4b0, 0x74a1926e,
+ 0x74cb43e6, 0x74f4f917, 0x751eb201, 0x75486ea1,
+ 0x75722ef9, 0x759bf307, 0x75c5baca, 0x75ef8642,
+ 0x7619556f, 0x7643284f, 0x766cfee2, 0x7696d928,
+ 0x76c0b71f, 0x76ea98c7, 0x77147e20, 0x773e6728,
+ 0x776853df, 0x77924445, 0x77bc3858, 0x77e63019,
+ 0x78102b85, 0x783a2a9e, 0x78642d62, 0x788e33d1,
+ 0x78b83de9, 0x78e24bab, 0x790c5d15, 0x79367228,
+ 0x79608ae1, 0x798aa742, 0x79b4c748, 0x79deeaf4,
+ 0x7a091245, 0x7a333d3a, 0x7a5d6bd2, 0x7a879e0e,
+ 0x7ab1d3ec, 0x7adc0d6b, 0x7b064a8c, 0x7b308b4d,
+ 0x7b5acfae, 0x7b8517ae, 0x7baf634c, 0x7bd9b289,
+ 0x7c040563, 0x7c2e5bda, 0x7c58b5ec, 0x7c83139b,
+ 0x7cad74e4, 0x7cd7d9c7, 0x7d024244, 0x7d2cae5a,
+ 0x7d571e09, 0x7d81914f, 0x7dac082d, 0x7dd682a1,
+ 0x7e0100ac, 0x7e2b824b, 0x7e560780, 0x7e809048,
+ 0x7eab1ca5, 0x7ed5ac94, 0x7f004015, 0x7f2ad729,
0x7f5571cd, 0x7f801003, 0x7faab1c8, 0x7fd5571d
};
const Word32 invSBF[24] = {
- 0x3FFD34FC, 0x2D3F8000, 0x24F18C7E, 0x1FFE9A7E,
- 0x1C9DF10C, 0x1A1F851A, 0x182FE994, 0x169FC000,
- 0x15542AAA, 0x143C31C2, 0x134B1B6C, 0x127920BE,
- 0x11BF2FCC, 0x111A749E, 0x1085FC42, 0x0FFFA7BE,
- 0x0F855818, 0x0F14EE56, 0x0EAE6A78, 0x0E4EF886,
+ 0x3FFD34FC, 0x2D3F8000, 0x24F18C7E, 0x1FFE9A7E,
+ 0x1C9DF10C, 0x1A1F851A, 0x182FE994, 0x169FC000,
+ 0x15542AAA, 0x143C31C2, 0x134B1B6C, 0x127920BE,
+ 0x11BF2FCC, 0x111A749E, 0x1085FC42, 0x0FFFA7BE,
+ 0x0F855818, 0x0F14EE56, 0x0EAE6A78, 0x0E4EF886,
0x0DF69880, 0x0DA49568, 0x0D578542, 0x0D101D0C
};
@@ -1353,40 +1353,40 @@
};
const Word16 sideInfoTabLong[MAX_SFB_LONG + 1] = {
- 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14,
14, 14, 14
};
const Word16 sideInfoTabShort[MAX_SFB_SHORT + 1] = {
- 7, 7, 7, 7, 7, 7, 7, 10, 10,
+ 7, 7, 7, 7, 7, 7, 7, 10, 10,
10, 10, 10, 10, 10, 13, 13
};
Word32 specExpMantTableComb_enc[4][14] =
{
- {0x40000000, 0x50a28be6, 0x6597fa95, 0x40000000,
- 0x50a28be6, 0x6597fa95, 0x40000000, 0x50a28be6,
- 0x6597fa95, 0x40000000, 0x50a28be6, 0x6597fa95,
- 0x40000000, 0x50a28be6},
+ {0x40000000, 0x50a28be6, 0x6597fa95, 0x40000000,
+ 0x50a28be6, 0x6597fa95, 0x40000000, 0x50a28be6,
+ 0x6597fa95, 0x40000000, 0x50a28be6, 0x6597fa95,
+ 0x40000000, 0x50a28be6},
- {0x4c1bf829, 0x5fe4435e, 0x78d0df9c, 0x4c1bf829,
- 0x5fe4435e, 0x78d0df9c, 0x4c1bf829, 0x5fe4435e,
- 0x78d0df9c, 0x4c1bf829, 0x5fe4435e, 0x78d0df9c,
- 0x4c1bf829, 0x5fe4435e},
+ {0x4c1bf829, 0x5fe4435e, 0x78d0df9c, 0x4c1bf829,
+ 0x5fe4435e, 0x78d0df9c, 0x4c1bf829, 0x5fe4435e,
+ 0x78d0df9c, 0x4c1bf829, 0x5fe4435e, 0x78d0df9c,
+ 0x4c1bf829, 0x5fe4435e},
- {0x5a82799a, 0x7208f81d, 0x47d66b0f, 0x5a82799a,
- 0x7208f81d, 0x47d66b0f, 0x5a82799a, 0x7208f81d,
- 0x47d66b0f, 0x5a82799a, 0x7208f81d, 0x47d66b0f,
- 0x5a82799a, 0x7208f81d},
+ {0x5a82799a, 0x7208f81d, 0x47d66b0f, 0x5a82799a,
+ 0x7208f81d, 0x47d66b0f, 0x5a82799a, 0x7208f81d,
+ 0x47d66b0f, 0x5a82799a, 0x7208f81d, 0x47d66b0f,
+ 0x5a82799a, 0x7208f81d},
- {0x6ba27e65, 0x43ce3e4b, 0x556e0424, 0x6ba27e65,
- 0x43ce3e4b, 0x556e0424, 0x6ba27e65, 0x43ce3e4b,
- 0x556e0424, 0x6ba27e65, 0x43ce3e4b, 0x556e0424,
+ {0x6ba27e65, 0x43ce3e4b, 0x556e0424, 0x6ba27e65,
+ 0x43ce3e4b, 0x556e0424, 0x6ba27e65, 0x43ce3e4b,
+ 0x556e0424, 0x6ba27e65, 0x43ce3e4b, 0x556e0424,
0x6ba27e65, 0x43ce3e4b}
};
@@ -1417,12 +1417,12 @@
};
const int sampRateTab[NUM_SAMPLE_RATES] = {
- 96000, 88200, 64000, 48000, 44100, 32000,
+ 96000, 88200, 64000, 48000, 44100, 32000,
24000, 22050, 16000, 12000, 11025, 8000
};
-const int rates[8] = {
+const int rates[8] = {
160, 240, 320, 400, 480, 560, 640, 0
};
@@ -1507,7 +1507,7 @@
};
/*
- these tables are used only for counting and
+ these tables are used only for counting and
are stored in packed format
*/
const UWord16 huff_ltab1_2[3][3][3][3]=
@@ -2260,12 +2260,12 @@
};
const Word32 m_log2_table[INT_BITS] = {
- 0x00000000,0x4ae00d00,0x2934f080,0x15c01a3f,
- 0x0b31fb80,0x05aeb4e0,0x02dcf2d0,0x016fe50c,
+ 0x00000000,0x4ae00d00,0x2934f080,0x15c01a3f,
+ 0x0b31fb80,0x05aeb4e0,0x02dcf2d0,0x016fe50c,
0x00b84e23,0x005c3e10,0x002e24ca,0x001713d6,
0x000b8a47,0x0005c53b,0x0002e2a3,0x00017153,
0x0000b8aa,0x00005c55,0x00002e2b,0x00001715,
- 0x00000b8b,0x000005c5,0x000002e3,0x00000171,
+ 0x00000b8b,0x000005c5,0x000002e3,0x00000171,
0x000000b9,0x0000005c,0x0000002e,0x00000017,
0x0000000c,0x00000006,0x00000003,0x00000001
};
@@ -2344,7 +2344,7 @@
};
-const unsigned char bitrevTab[17 + 129] =
+const unsigned char bitrevTab[17 + 129] =
{
/* 64 */
0x01, 0x08, 0x02, 0x04, 0x03, 0x0c, 0x05, 0x0a, 0x07, 0x0e, 0x0b, 0x0d, 0x00, 0x06, 0x09, 0x0f,
diff --git a/media/libstagefright/codecs/aacenc/src/aacenc.c b/media/libstagefright/codecs/aacenc/src/aacenc.c
index b5e8a9c..975f598 100644
--- a/media/libstagefright/codecs/aacenc/src/aacenc.c
+++ b/media/libstagefright/codecs/aacenc/src/aacenc.c
@@ -48,7 +48,7 @@
interMem = 0;
error = 0;
-
+
/* init the memory operator */
if(pUserData == NULL || pUserData->memflag != VO_IMF_USERMEMOPERATOR || pUserData->memData == NULL )
{
@@ -113,7 +113,7 @@
{
mem_free(pMemOP, hAacEnc, VO_INDEX_ENC_AAC);
hAacEnc = NULL;
- }
+ }
*phCodec = NULL;
return VO_ERR_OUTOF_MEMORY;
}
@@ -168,9 +168,9 @@
{
return VO_ERR_INVALID_ARG;
}
-
+
hAacEnc = (AAC_ENCODER *)hCodec;
-
+
/* init input pcm buffer and length*/
hAacEnc->inbuf = (short *)pInput->Buffer;
hAacEnc->inlen = pInput->Length / sizeof(short);
@@ -178,12 +178,12 @@
hAacEnc->encbuf = hAacEnc->inbuf;
hAacEnc->enclen = hAacEnc->inlen;
-
+
/* rebuild intra pcm buffer and length*/
if(hAacEnc->intlen)
{
length = min(hAacEnc->config.nChannelsIn*AACENC_BLOCKSIZE - hAacEnc->intlen, hAacEnc->inlen);
- hAacEnc->voMemop->Copy(VO_INDEX_ENC_AAC, hAacEnc->intbuf + hAacEnc->intlen,
+ hAacEnc->voMemop->Copy(VO_INDEX_ENC_AAC, hAacEnc->intbuf + hAacEnc->intlen,
hAacEnc->inbuf, length*sizeof(short));
hAacEnc->encbuf = hAacEnc->intbuf;
@@ -192,7 +192,7 @@
hAacEnc->inbuf += length;
hAacEnc->inlen -= length;
}
-
+
return VO_ERR_NONE;
}
@@ -219,11 +219,11 @@
/* check the input pcm buffer and length*/
if(NULL == hAacEnc->encbuf || hAacEnc->enclen < inbuflen)
{
- length = hAacEnc->enclen;
+ length = hAacEnc->enclen;
if(hAacEnc->intlen == 0)
- {
- hAacEnc->voMemop->Copy(VO_INDEX_ENC_AAC, hAacEnc->intbuf,
- hAacEnc->encbuf, length*sizeof(short));
+ {
+ hAacEnc->voMemop->Copy(VO_INDEX_ENC_AAC, hAacEnc->intbuf,
+ hAacEnc->encbuf, length*sizeof(short));
hAacEnc->uselength += length*sizeof(short);
}
else
@@ -236,7 +236,7 @@
pOutput->Length = 0;
if(pOutInfo)
pOutInfo->InputUsed = hAacEnc->uselength;
- return VO_ERR_INPUT_BUFFER_SMALL;
+ return VO_ERR_INPUT_BUFFER_SMALL;
}
/* check the output aac buffer and length*/
@@ -254,7 +254,7 @@
/* update the input pcm buffer and length*/
if(hAacEnc->intlen)
{
- length = inbuflen - hAacEnc->intlen;
+ length = inbuflen - hAacEnc->intlen;
hAacEnc->encbuf = hAacEnc->inbuf;
hAacEnc->enclen = hAacEnc->inlen;
hAacEnc->uselength += length*sizeof(short);
@@ -265,7 +265,7 @@
hAacEnc->encbuf = hAacEnc->encbuf + inbuflen;
hAacEnc->enclen = hAacEnc->enclen - inbuflen;
hAacEnc->uselength += inbuflen*sizeof(short);
- }
+ }
/* update the output aac information */
if(pOutInfo)
@@ -287,7 +287,7 @@
VO_U32 VO_API voAACEncUninit(VO_HANDLE hCodec)
{
AAC_ENCODER* hAacEnc = (AAC_ENCODER*)hCodec;
-
+
if(NULL != hAacEnc)
{
/* close the aac encoder */
@@ -296,7 +296,7 @@
/* free the aac encoder handle*/
mem_free(hAacEnc->voMemop, hAacEnc, VO_INDEX_ENC_AAC);
hAacEnc = NULL;
- }
+ }
return VO_ERR_NONE;
}
@@ -319,7 +319,7 @@
if(NULL == hAacEnc)
return VO_ERR_INVALID_ARG;
-
+
switch(uParamID)
{
case VO_PID_AAC_ENCPARAM: /* init aac encoder parameter*/
@@ -354,11 +354,11 @@
SampleRateIdx = i;
tmp = 441;
- if(config.sampleRate%8000 == 0)
+ if(config.sampleRate%8000 == 0)
tmp =480;
/* check the bitrate */
if(config.bitRate!=0 && (config.bitRate/config.nChannelsOut < 4000) ||
- (config.bitRate/config.nChannelsOut > 160000) ||
+ (config.bitRate/config.nChannelsOut > 160000) ||
(config.bitRate > config.sampleRate*6*config.nChannelsOut))
{
config.bitRate = 640*config.sampleRate/tmp*config.nChannelsOut;
@@ -385,7 +385,7 @@
/* init aac encoder core */
ret = AacEncOpen(hAacEnc, config);
- if(ret)
+ if(ret)
return VO_ERR_AUDIO_UNSFEATURE;
break;
case VO_PID_AUDIO_FORMAT: /* init pcm channel and samplerate*/
@@ -426,7 +426,7 @@
/* update the bitrates */
tmp = 441;
- if(config.sampleRate%8000 == 0)
+ if(config.sampleRate%8000 == 0)
tmp =480;
config.bitRate = 640*config.sampleRate/tmp*config.nChannelsOut;
@@ -449,10 +449,10 @@
}
config.bandWidth = BandwithCoefTab[i][SampleRateIdx];
-
+
/* init aac encoder core */
ret = AacEncOpen(hAacEnc, config);
- if(ret)
+ if(ret)
return VO_ERR_AUDIO_UNSFEATURE;
break;
default:
@@ -483,7 +483,7 @@
{
if(pDecHandle == NULL)
return VO_ERR_INVALID_ARG;
-
+
pDecHandle->Init = voAACEncInit;
pDecHandle->SetInputData = voAACEncSetInputData;
pDecHandle->GetOutputData = voAACEncGetOutputData;
diff --git a/media/libstagefright/codecs/aacenc/src/aacenc_core.c b/media/libstagefright/codecs/aacenc/src/aacenc_core.c
index 2b3bd48..b69a017 100644
--- a/media/libstagefright/codecs/aacenc/src/aacenc_core.c
+++ b/media/libstagefright/codecs/aacenc/src/aacenc_core.c
@@ -43,8 +43,8 @@
config->adtsUsed = 1;
config->nChannelsIn = 2;
config->nChannelsOut = 2;
- config->bitRate = 128000;
- config->bandWidth = 0;
+ config->bitRate = 128000;
+ config->bandWidth = 0;
}
/********************************************************************************
@@ -63,11 +63,11 @@
Word16 profile = 1;
ELEMENT_INFO *elInfo = NULL;
-
+
if (hAacEnc==0) {
- error=1;
+ error=1;
}
-
+
if (!error) {
hAacEnc->config = config;
}
@@ -83,7 +83,7 @@
if (!error) {
/* use or not tns tool for long and short block */
- Word16 tnsMask=3;
+ Word16 tnsMask=3;
/* init encoder psychoacoustic */
error = psyMainInit(&hAacEnc->psyKernel,
@@ -107,10 +107,10 @@
qcInit.elInfo = &hAacEnc->elInfo;
qcInit.maxBits = (Word16) (MAXBITS_COEF*elInfo->nChannelsInEl);
- qcInit.bitRes = qcInit.maxBits;
+ qcInit.bitRes = qcInit.maxBits;
qcInit.averageBits = (Word16) ((config.bitRate * FRAME_LEN_LONG) / config.sampleRate);
- qcInit.padding.paddingRest = config.sampleRate;
+ qcInit.padding.paddingRest = config.sampleRate;
qcInit.meanPe = (Word16) ((10 * FRAME_LEN_LONG * hAacEnc->config.bandWidth) /
(config.sampleRate>>1));
@@ -118,17 +118,17 @@
qcInit.maxBitFac = (Word16) ((100 * (MAXBITS_COEF-MINBITS_COEF)* elInfo->nChannelsInEl)/
(qcInit.averageBits?qcInit.averageBits:1));
- qcInit.bitrate = config.bitRate;
+ qcInit.bitrate = config.bitRate;
error = QCInit(&hAacEnc->qcKernel, &qcInit);
}
/* init bitstream encoder */
if (!error) {
- hAacEnc->bseInit.nChannels = elInfo->nChannelsInEl;
- hAacEnc->bseInit.bitrate = config.bitRate;
- hAacEnc->bseInit.sampleRate = config.sampleRate;
- hAacEnc->bseInit.profile = profile;
+ hAacEnc->bseInit.nChannels = elInfo->nChannelsInEl;
+ hAacEnc->bseInit.bitrate = config.bitRate;
+ hAacEnc->bseInit.sampleRate = config.sampleRate;
+ hAacEnc->bseInit.profile = profile;
}
return error;
@@ -152,14 +152,14 @@
ELEMENT_INFO *elInfo = &aacEnc->elInfo;
Word16 globUsedBits;
Word16 ancDataBytes, ancDataBytesLeft;
-
- ancDataBytes = ancDataBytesLeft = *numAncBytes;
+
+ ancDataBytes = ancDataBytesLeft = *numAncBytes;
/* init output aac data buffer and length */
aacEnc->hBitStream = CreateBitBuffer(&aacEnc->bitStream, outBytes, *numOutBytes);
/* psychoacoustic process */
- psyMain(aacEnc->config.nChannelsOut,
+ psyMain(aacEnc->config.nChannelsOut,
elInfo,
timeSignal,
&aacEnc->psyKernel.psyData[elInfo->ChannelIndex[0]],
@@ -175,9 +175,9 @@
AdjustBitrate(&aacEnc->qcKernel,
aacEnc->config.bitRate,
aacEnc->config.sampleRate);
-
+
/* quantization and coding process */
- QCMain(&aacEnc->qcKernel,
+ QCMain(&aacEnc->qcKernel,
&aacEnc->qcKernel.elementBits,
&aacEnc->qcKernel.adjThr.adjThrStateElem,
&aacEnc->psyOut.psyOutChannel[elInfo->ChannelIndex[0]],
@@ -193,11 +193,11 @@
&aacEnc->qcOut);
/* write bitstream process */
- WriteBitstream(aacEnc->hBitStream,
+ WriteBitstream(aacEnc->hBitStream,
*elInfo,
&aacEnc->qcOut,
&aacEnc->psyOut,
- &globUsedBits,
+ &globUsedBits,
ancBytes,
aacEnc->psyKernel.sampleRateIdx);
@@ -219,7 +219,7 @@
**********************************************************************************/
void AacEncClose (AAC_ENCODER* hAacEnc, VO_MEM_OPERATOR *pMemOP)
{
- if (hAacEnc) {
+ if (hAacEnc) {
QCDelete(&hAacEnc->qcKernel, pMemOP);
QCOutDelete(&hAacEnc->qcOut, pMemOP);
diff --git a/media/libstagefright/codecs/aacenc/src/adj_thr.c b/media/libstagefright/codecs/aacenc/src/adj_thr.c
index c656f65..83b43a1 100644
--- a/media/libstagefright/codecs/aacenc/src/adj_thr.c
+++ b/media/libstagefright/codecs/aacenc/src/adj_thr.c
@@ -71,7 +71,7 @@
Word32 *pthrExp, *psfbThre;
for (ch=0; ch<nChannels; ch++) {
PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];
- for(sfbGrp = 0; sfbGrp < psyOutChan->sfbCnt; sfbGrp+= psyOutChan->sfbPerGroup)
+ for(sfbGrp = 0; sfbGrp < psyOutChan->sfbCnt; sfbGrp+= psyOutChan->sfbPerGroup)
pthrExp = &(thrExp[ch][sfbGrp]);
psfbThre = psyOutChan->sfbThreshold + sfbGrp;
for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
@@ -96,21 +96,21 @@
Word32 nSfb, avgEn;
Word16 log_avgEn = 0;
Word32 startRatio_x_avgEn = 0;
-
+
for (ch=0; ch<nChannels; ch++) {
PSY_OUT_CHANNEL* psyOutChan = &psyOutChannel[ch];
/* calc average energy per scalefactor band */
- avgEn = 0;
- nSfb = 0;
+ avgEn = 0;
+ nSfb = 0;
for (sfbOffs=0; sfbOffs<psyOutChan->sfbCnt; sfbOffs+=psyOutChan->sfbPerGroup) {
for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
avgEn = L_add(avgEn, psyOutChan->sfbEnergy[sfbOffs+sfb]);
nSfb = nSfb + 1;
}
}
-
+
if (nSfb > 0) {
avgEn = avgEn / nSfb;
@@ -118,7 +118,7 @@
startRatio_x_avgEn = fixmul(msaParam->startRatio, avgEn);
}
-
+
/* reduce minSnr requirement by minSnr^minSnrRed dependent on avgEn/sfbEn */
for (sfbOffs=0; sfbOffs<psyOutChan->sfbCnt; sfbOffs+=psyOutChan->sfbPerGroup) {
for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
@@ -126,22 +126,22 @@
Word16 dbRatio, minSnrRed;
Word32 snrRed;
Word16 newMinSnr;
-
+
dbRatio = log_avgEn - logSfbEnergy[ch][sfbOffs+sfb];
dbRatio = dbRatio + (dbRatio << 1);
minSnrRed = 110 - ((dbRatio + (dbRatio << 1)) >> 2);
- minSnrRed = max(minSnrRed, 20); /* 110: (0.375(redOffs)+1)*80,
+ minSnrRed = max(minSnrRed, 20); /* 110: (0.375(redOffs)+1)*80,
3: 0.00375(redRatioFac)*80
20: 0.25(maxRed) * 80 */
- snrRed = minSnrRed * iLog4((psyOutChan->sfbMinSnr[sfbOffs+sfb] << 16));
- /*
+ snrRed = minSnrRed * iLog4((psyOutChan->sfbMinSnr[sfbOffs+sfb] << 16));
+ /*
snrRedI si now scaled by 80 (minSnrRed) and 4 (ffr_iLog4)
*/
-
+
newMinSnr = round16(pow2_xy(snrRed,80*4));
-
+
psyOutChan->sfbMinSnr[sfbOffs+sfb] = min(newMinSnr, minSnrLimit);
}
}
@@ -169,7 +169,7 @@
for (ch=0; ch<nChannels; ch++) {
PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];
-
+
if (psyOutChan->windowSequence != SHORT_WINDOW) {
for(sfbGrp = 0;sfbGrp < psyOutChan->sfbCnt;sfbGrp+= psyOutChan->sfbPerGroup){
psfbSpreadEn = psyOutChan->sfbSpreadedEnergy + sfbGrp;
@@ -194,7 +194,7 @@
if (ahParam->modifyMinSnr) {
for(ch=0; ch<nChannels; ch++) {
PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];
-
+
if (psyOutChan->windowSequence != SHORT_WINDOW)
threshold = HOLE_THR_LONG;
else
@@ -204,39 +204,39 @@
Word16 *psfbMinSnr = psyOutChan->sfbMinSnr + sfbGrp;
for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
Word32 sfbEn, sfbEnm1, sfbEnp1, avgEn;
-
+
if (sfb > 0)
sfbEnm1 = psyOutChan->sfbEnergy[sfbGrp+sfb-1];
else
sfbEnm1 = psyOutChan->sfbEnergy[sfbGrp];
-
+
if (sfb < (psyOutChan->maxSfbPerGroup-1))
sfbEnp1 = psyOutChan->sfbEnergy[sfbGrp+sfb+1];
else
sfbEnp1 = psyOutChan->sfbEnergy[sfbGrp+sfb];
avgEn = (sfbEnm1 + sfbEnp1) >> 1;
- sfbEn = psyOutChan->sfbEnergy[sfbGrp+sfb];
-
+ sfbEn = psyOutChan->sfbEnergy[sfbGrp+sfb];
+
if (sfbEn > avgEn && avgEn > 0) {
Word32 tmpMinSnr;
shift = norm_l(sfbEn);
tmpMinSnr = Div_32(L_mpy_ls(avgEn, minSnrLimit) << shift, sfbEn << shift );
- tmpMinSnr = max(tmpMinSnr, HOLE_THR_LONG);
+ tmpMinSnr = max(tmpMinSnr, HOLE_THR_LONG);
tmpMinSnr = max(tmpMinSnr, threshold);
*psfbMinSnr = min(*psfbMinSnr, tmpMinSnr);
}
/* valley ? */
-
+
if ((sfbEn < (avgEn >> 1)) && (sfbEn > 0)) {
Word32 tmpMinSnr;
- Word32 minSnrEn = L_mpy_wx(avgEn, *psfbMinSnr);
-
+ Word32 minSnrEn = L_mpy_wx(avgEn, *psfbMinSnr);
+
if(minSnrEn < sfbEn) {
shift = norm_l(sfbEn);
tmpMinSnr = Div_32( minSnrEn << shift, sfbEn<<shift);
}
else {
- tmpMinSnr = MAX_16;
+ tmpMinSnr = MAX_16;
}
tmpMinSnr = min(minSnrLimit, tmpMinSnr);
@@ -251,7 +251,7 @@
/* stereo: adapt the minimum requirements sfbMinSnr of mid and
side channels */
-
+
if (nChannels == 2) {
PSY_OUT_CHANNEL *psyOutChanM = &psyOutChannel[0];
PSY_OUT_CHANNEL *psyOutChanS = &psyOutChannel[1];
@@ -260,30 +260,30 @@
Word32 sfbEnM = psyOutChanM->sfbEnergy[sfb];
Word32 sfbEnS = psyOutChanS->sfbEnergy[sfb];
Word32 maxSfbEn = max(sfbEnM, sfbEnS);
- Word32 maxThr = L_mpy_wx(maxSfbEn, psyOutChanM->sfbMinSnr[sfb]) >> 1;
-
+ Word32 maxThr = L_mpy_wx(maxSfbEn, psyOutChanM->sfbMinSnr[sfb]) >> 1;
+
if(maxThr >= sfbEnM) {
- psyOutChanM->sfbMinSnr[sfb] = MAX_16;
+ psyOutChanM->sfbMinSnr[sfb] = MAX_16;
}
else {
- shift = norm_l(sfbEnM);
- psyOutChanM->sfbMinSnr[sfb] = min(max(psyOutChanM->sfbMinSnr[sfb],
+ shift = norm_l(sfbEnM);
+ psyOutChanM->sfbMinSnr[sfb] = min(max(psyOutChanM->sfbMinSnr[sfb],
round16(Div_32(maxThr<<shift, sfbEnM << shift))), minSnrLimit);
}
-
+
if(maxThr >= sfbEnS) {
psyOutChanS->sfbMinSnr[sfb] = MAX_16;
}
else {
shift = norm_l(sfbEnS);
- psyOutChanS->sfbMinSnr[sfb] = min(max(psyOutChanS->sfbMinSnr[sfb],
+ psyOutChanS->sfbMinSnr[sfb] = min(max(psyOutChanS->sfbMinSnr[sfb],
round16(Div_32(maxThr << shift, sfbEnS << shift))), minSnrLimit);
}
-
+
if (sfbEnM > psyOutChanM->sfbSpreadedEnergy[sfb])
psyOutChanS->sfbSpreadedEnergy[sfb] = L_mpy_ls(sfbEnS, MS_THRSPREAD_COEF);
-
+
if (sfbEnS > psyOutChanS->sfbSpreadedEnergy[sfb])
psyOutChanM->sfbSpreadedEnergy[sfb] = L_mpy_ls(sfbEnM, MS_THRSPREAD_COEF);
}
@@ -297,7 +297,7 @@
for(sfbGrp = 0;sfbGrp < psyOutChan->sfbCnt;sfbGrp+= psyOutChan->sfbPerGroup){
Word16 *pahFlag = ahFlag[ch] + sfbGrp;
for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
-
+
if ((psyOutChan->sfbSpreadedEnergy[sfbGrp+sfb] > psyOutChan->sfbEnergy[sfbGrp+sfb]) ||
(psyOutChan->sfbEnergy[sfbGrp+sfb] <= psyOutChan->sfbThreshold[sfbGrp+sfb]) ||
(psyOutChan->sfbMinSnr[sfbGrp+sfb] == MAX_16)) {
@@ -308,7 +308,7 @@
}
}
for (sfb=psyOutChan->maxSfbPerGroup; sfb<psyOutChan->sfbPerGroup; sfb++) {
- *pahFlag++ = NO_AH;
+ *pahFlag++ = NO_AH;
}
}
}
@@ -331,15 +331,15 @@
Word16 ch, sfb, sfbGrp;
int ipe, iconstPart, inActiveLines;
- ipe = 0;
- iconstPart = 0;
- inActiveLines = 0;
+ ipe = 0;
+ iconstPart = 0;
+ inActiveLines = 0;
for(ch=0; ch<nChannels; ch++) {
PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];
PE_CHANNEL_DATA *peChanData = &peData->peChannelData[ch];
for(sfbGrp = 0;sfbGrp < psyOutChan->sfbCnt;sfbGrp+= psyOutChan->sfbPerGroup){
for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
-
+
if (ahFlag[ch][sfbGrp+sfb] < AH_ACTIVE) {
ipe = ipe + peChanData->sfbPe[sfbGrp+sfb];
iconstPart = iconstPart + peChanData->sfbConstPart[sfbGrp+sfb];
@@ -349,9 +349,9 @@
}
}
- *pe = saturate(ipe);
- *constPart = saturate(iconstPart);
- *nActiveLines = saturate(inActiveLines);
+ *pe = saturate(ipe);
+ *constPart = saturate(iconstPart);
+ *nActiveLines = saturate(inActiveLines);
}
/********************************************************************************
@@ -367,16 +367,16 @@
const Word32 redVal)
{
Word32 sfbThrReduced;
- Word32 *psfbEn, *psfbThr;
+ Word32 *psfbEn, *psfbThr;
Word16 ch, sfb, sfbGrp;
for(ch=0; ch<nChannels; ch++) {
PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];
for(sfbGrp=0; sfbGrp<psyOutChan->sfbCnt; sfbGrp+=psyOutChan->sfbPerGroup) {
- psfbEn = psyOutChan->sfbEnergy + sfbGrp;
+ psfbEn = psyOutChan->sfbEnergy + sfbGrp;
psfbThr = psyOutChan->sfbThreshold + sfbGrp;
for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
-
+
if (*psfbEn > *psfbThr) {
/* threshold reduction formula */
Word32 tmp = thrExp[ch][sfbGrp+sfb] + redVal;
@@ -384,11 +384,11 @@
sfbThrReduced = fixmul(tmp, tmp);
/* avoid holes */
tmp = L_mpy_ls(*psfbEn, psyOutChan->sfbMinSnr[sfbGrp+sfb]);
-
- if ((sfbThrReduced > tmp) &&
+
+ if ((sfbThrReduced > tmp) &&
(ahFlag[ch][sfbGrp+sfb] != NO_AH)){
sfbThrReduced = max(tmp, *psfbThr);
- ahFlag[ch][sfbGrp+sfb] = AH_ACTIVE;
+ ahFlag[ch][sfbGrp+sfb] = AH_ACTIVE;
}
*psfbThr = sfbThrReduced;
}
@@ -426,7 +426,7 @@
Word32 sfbThrReduced;
/* for each sfb calc relative factors for pe changes */
- normFactor = 1;
+ normFactor = 1;
for(ch=0; ch<nChannels; ch++) {
psyOutChan = &psyOutChannel[ch];
peChanData = &peData->peChannelData[ch];
@@ -436,22 +436,22 @@
pahFlag = ahFlag[ch] + sfbGrp;
for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
Word32 redThrExp = thrExp[ch][sfbGrp+sfb] + redVal;
-
+
if (((*pahFlag < AH_ACTIVE) || (deltaPe > 0)) && (redThrExp > 0) ) {
-
+
*psfbPeFactors = (*psfbNActiveLines) * (0x7fffffff / redThrExp);
normFactor = L_add(normFactor, *psfbPeFactors);
}
else {
- *psfbPeFactors = 0;
+ *psfbPeFactors = 0;
}
- psfbPeFactors++;
+ psfbPeFactors++;
pahFlag++; psfbNActiveLines++;
}
}
}
-
+
/* calculate new thresholds */
for(ch=0; ch<nChannels; ch++) {
psyOutChan = &psyOutChannel[ch];
@@ -464,7 +464,7 @@
/* pe difference for this sfb */
deltaSfbPe = *psfbPeFactors * deltaPe;
- /* thr3(n) = thr2(n)*2^deltaSfbPe/b(n) */
+ /* thr3(n) = thr2(n)*2^deltaSfbPe/b(n) */
if (*psfbNActiveLines > 0) {
/* new threshold */
Word32 thrFactor;
@@ -476,7 +476,7 @@
reduce threshold
*/
thrFactor = pow2_xy(L_negate(deltaSfbPe), (normFactor* (*psfbNActiveLines)));
-
+
sfbThrReduced = L_mpy_ls(sfbThr, round16(thrFactor));
}
else {
@@ -484,28 +484,28 @@
increase threshold
*/
thrFactor = pow2_xy(deltaSfbPe, (normFactor * (*psfbNActiveLines)));
-
-
+
+
if(thrFactor > sfbThr) {
shift = norm_l(thrFactor);
sfbThrReduced = Div_32( sfbThr << shift, thrFactor<<shift );
}
else {
- sfbThrReduced = MAX_32;
+ sfbThrReduced = MAX_32;
}
}
-
+
/* avoid hole */
sfbEn = L_mpy_ls(sfbEn, psyOutChan->sfbMinSnr[sfbGrp+sfb]);
-
+
if ((sfbThrReduced > sfbEn) &&
(*pahFlag == AH_INACTIVE)) {
sfbThrReduced = max(sfbEn, sfbThr);
- *pahFlag = AH_ACTIVE;
+ *pahFlag = AH_ACTIVE;
}
- psyOutChan->sfbThreshold[sfbGrp+sfb] = sfbThrReduced;
+ psyOutChan->sfbThreshold[sfbGrp+sfb] = sfbThrReduced;
}
pahFlag++; psfbNActiveLines++; psfbPeFactors++;
@@ -521,8 +521,8 @@
* description: if the desired pe can not be reached, reduce pe by reducing minSnr
*
**********************************************************************************/
-static void reduceMinSnr(PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
- PE_DATA *peData,
+static void reduceMinSnr(PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
+ PE_DATA *peData,
Word16 ahFlag[MAX_CHANNELS][MAX_GROUPED_SFB],
const Word16 nChannels,
const Word16 desiredPe)
@@ -531,9 +531,9 @@
Word16 deltaPe;
/* start at highest freq down to 0 */
- sfbSubWin = psyOutChannel[0].maxSfbPerGroup;
+ sfbSubWin = psyOutChannel[0].maxSfbPerGroup;
while (peData->pe > desiredPe && sfbSubWin > 0) {
-
+
sfbSubWin = sfbSubWin - 1;
/* loop over all subwindows */
for (sfb=sfbSubWin; sfb<psyOutChannel[0].sfbCnt;
@@ -541,10 +541,10 @@
/* loop over all channels */
PE_CHANNEL_DATA* peChan = peData->peChannelData;
PSY_OUT_CHANNEL* psyOutCh = psyOutChannel;
- for (ch=0; ch<nChannels; ch++) {
+ for (ch=0; ch<nChannels; ch++) {
if (ahFlag[ch][sfb] != NO_AH &&
psyOutCh->sfbMinSnr[sfb] < minSnrLimit) {
- psyOutCh->sfbMinSnr[sfb] = minSnrLimit;
+ psyOutCh->sfbMinSnr[sfb] = minSnrLimit;
psyOutCh->sfbThreshold[sfb] =
L_mpy_ls(psyOutCh->sfbEnergy[sfb], psyOutCh->sfbMinSnr[sfb]);
@@ -552,12 +552,12 @@
deltaPe = ((peChan->sfbNLines4[sfb] + (peChan->sfbNLines4[sfb] >> 1)) >> 2) -
peChan->sfbPe[sfb];
peData->pe = peData->pe + deltaPe;
- peChan->pe = peChan->pe + deltaPe;
+ peChan->pe = peChan->pe + deltaPe;
}
peChan += 1; psyOutCh += 1;
}
/* stop if enough has been saved */
-
+
if (peData->pe <= desiredPe)
break;
}
@@ -567,13 +567,13 @@
/********************************************************************************
*
* function name:allowMoreHoles
-* description: if the desired pe can not be reached, some more scalefactor bands
+* description: if the desired pe can not be reached, some more scalefactor bands
* have to be quantized to zero
*
**********************************************************************************/
-static void allowMoreHoles(PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
+static void allowMoreHoles(PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
PSY_OUT_ELEMENT *psyOutElement,
- PE_DATA *peData,
+ PE_DATA *peData,
Word16 ahFlag[MAX_CHANNELS][MAX_GROUPED_SFB],
const AH_PARAM *ahParam,
const Word16 nChannels,
@@ -582,46 +582,46 @@
Word16 ch, sfb;
Word16 actPe, shift;
- actPe = peData->pe;
+ actPe = peData->pe;
/* for MS allow hole in the channel with less energy */
-
+
if (nChannels==2 &&
psyOutChannel[0].windowSequence==psyOutChannel[1].windowSequence) {
PSY_OUT_CHANNEL *psyOutChanL = &psyOutChannel[0];
PSY_OUT_CHANNEL *psyOutChanR = &psyOutChannel[1];
for (sfb=0; sfb<psyOutChanL->sfbCnt; sfb++) {
Word32 minEn;
-
+
if (psyOutElement->toolsInfo.msMask[sfb]) {
/* allow hole in side channel ? */
minEn = L_mpy_ls(psyOutChanL->sfbEnergy[sfb], (minSnrLimit * psyOutChanL->sfbMinSnr[sfb]) >> 16);
-
+
if (ahFlag[1][sfb] != NO_AH &&
minEn > psyOutChanR->sfbEnergy[sfb]) {
- ahFlag[1][sfb] = NO_AH;
+ ahFlag[1][sfb] = NO_AH;
psyOutChanR->sfbThreshold[sfb] = L_add(psyOutChanR->sfbEnergy[sfb], psyOutChanR->sfbEnergy[sfb]);
actPe = actPe - peData->peChannelData[1].sfbPe[sfb];
}
/* allow hole in mid channel ? */
else {
minEn = L_mpy_ls(psyOutChanR->sfbEnergy[sfb], (minSnrLimit * psyOutChanR->sfbMinSnr[sfb]) >> 16);
-
+
if (ahFlag[0][sfb]!= NO_AH &&
minEn > psyOutChanL->sfbEnergy[sfb]) {
- ahFlag[0][sfb] = NO_AH;
+ ahFlag[0][sfb] = NO_AH;
psyOutChanL->sfbThreshold[sfb] = L_add(psyOutChanL->sfbEnergy[sfb], psyOutChanL->sfbEnergy[sfb]);
actPe = actPe - peData->peChannelData[0].sfbPe[sfb];
}
}
-
+
if (actPe < desiredPe)
break;
}
}
}
- /* subsequently erase bands */
+ /* subsequently erase bands */
if (actPe > desiredPe) {
Word16 startSfb[2];
Word32 avgEn, minEn;
@@ -634,20 +634,20 @@
/* do not go below startSfb */
for (ch=0; ch<nChannels; ch++) {
-
+
if (psyOutChannel[ch].windowSequence != SHORT_WINDOW)
startSfb[ch] = ahParam->startSfbL;
else
startSfb[ch] = ahParam->startSfbS;
}
- avgEn = 0;
- minEn = MAX_32;
- ahCnt = 0;
+ avgEn = 0;
+ minEn = MAX_32;
+ ahCnt = 0;
for (ch=0; ch<nChannels; ch++) {
PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];
for (sfb=startSfb[ch]; sfb<psyOutChan->sfbCnt; sfb++) {
-
+
if ((ahFlag[ch][sfb] != NO_AH) &&
(psyOutChan->sfbEnergy[sfb] > psyOutChan->sfbThreshold[sfb])) {
minEn = min(minEn, psyOutChan->sfbEnergy[sfb]);
@@ -656,7 +656,7 @@
}
}
}
-
+
if(ahCnt) {
Word32 iahCnt;
shift = norm_l(ahCnt);
@@ -674,46 +674,46 @@
/* start with lowest energy border at highest sfb */
maxSfb = psyOutChannel[0].sfbCnt - 1;
- minSfb = startSfb[0];
-
+ minSfb = startSfb[0];
+
if (nChannels == 2) {
maxSfb = max(maxSfb, (psyOutChannel[1].sfbCnt - 1));
minSfb = min(minSfb, startSfb[1]);
}
- sfb = maxSfb;
- enIdx = 0;
- done = 0;
+ sfb = maxSfb;
+ enIdx = 0;
+ done = 0;
while (!done) {
-
+
for (ch=0; ch<nChannels; ch++) {
PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];
-
+
if (sfb>=startSfb[ch] && sfb<psyOutChan->sfbCnt) {
/* sfb energy below border ? */
-
+
if (ahFlag[ch][sfb] != NO_AH && psyOutChan->sfbEnergy[sfb] < en[enIdx]){
/* allow hole */
- ahFlag[ch][sfb] = NO_AH;
+ ahFlag[ch][sfb] = NO_AH;
psyOutChan->sfbThreshold[sfb] = L_add(psyOutChan->sfbEnergy[sfb], psyOutChan->sfbEnergy[sfb]);
actPe = actPe - peData->peChannelData[ch].sfbPe[sfb];
}
-
+
if (actPe < desiredPe) {
- done = 1;
+ done = 1;
break;
}
}
}
sfb = sfb - 1;
-
+
if (sfb < minSfb) {
/* restart with next energy border */
- sfb = maxSfb;
+ sfb = maxSfb;
enIdx = enIdx + 1;
-
+
if (enIdx - 4 >= 0)
- done = 1;
+ done = 1;
}
}
}
@@ -748,13 +748,13 @@
initAvoidHoleFlag(peData->ahFlag, psyOutChannel, psyOutElement, nChannels, ahParam);
- noRedPe = peData->pe;
- constPart = peData->constPart;
- nActiveLines = peData->nActiveLines;
+ noRedPe = peData->pe;
+ constPart = peData->constPart;
+ nActiveLines = peData->nActiveLines;
/* first guess of reduction value t^0.25 = 2^((a-pen)/4*b) */
avgThrExp = pow2_xy((constPart - noRedPe), (nActiveLines << 2));
-
+
/* r1 = 2^((a-per)/4*b) - t^0.25 */
redVal = pow2_xy((constPart - desiredPe), (nActiveLines << 2)) - avgThrExp;
@@ -763,40 +763,40 @@
/* pe after first guess */
calcSfbPe(peData, psyOutChannel, nChannels);
- redPe = peData->pe;
+ redPe = peData->pe;
- iter = 0;
+ iter = 0;
do {
/* pe for bands where avoid hole is inactive */
calcPeNoAH(&redPeNoAH, &constPartNoAH, &nActiveLinesNoAH,
peData, peData->ahFlag, psyOutChannel, nChannels);
desiredPeNoAH = desiredPe -(redPe - redPeNoAH);
-
+
if (desiredPeNoAH < 0) {
- desiredPeNoAH = 0;
+ desiredPeNoAH = 0;
}
/* second guess */
-
+
if (nActiveLinesNoAH > 0) {
-
+
avgThrExp = pow2_xy((constPartNoAH - redPeNoAH), (nActiveLinesNoAH << 2));
-
+
redVal = (redVal + pow2_xy((constPartNoAH - desiredPeNoAH), (nActiveLinesNoAH << 2))) - avgThrExp;
-
+
/* reduce thresholds */
reduceThresholds(psyOutChannel, peData->ahFlag, peData->thrExp, nChannels, redVal);
}
calcSfbPe(peData, psyOutChannel, nChannels);
- redPe = peData->pe;
+ redPe = peData->pe;
iter = iter+1;
-
+
} while ((20 * abs_s(redPe - desiredPe) > desiredPe) && (iter < 2));
-
+
if ((100 * redPe < 115 * desiredPe)) {
correctThresh(psyOutChannel, peData->ahFlag, peData, peData->thrExp, redVal,
nChannels, desiredPe - redPe);
@@ -863,7 +863,7 @@
if(clipHigh-clipLow)
bitspend = (minBitSpend + ((maxBitSpend - minBitSpend)*(fillLevel - clipLow) /
(clipHigh-clipLow)));
-
+
return (bitspend);
}
@@ -884,19 +884,19 @@
Word16 minFacHi, maxFacHi, minFacLo, maxFacLo;
Word16 diff;
Word16 minDiff = extract_l(currPe / 6);
- minFacHi = 30;
- maxFacHi = 100;
- minFacLo = 14;
- maxFacLo = 7;
+ minFacHi = 30;
+ maxFacHi = 100;
+ minFacLo = 14;
+ maxFacLo = 7;
diff = currPe - *peMax ;
-
+
if (diff > 0) {
*peMin = *peMin + ((diff * minFacHi) / 100);
*peMax = *peMax + ((diff * maxFacHi) / 100);
} else {
diff = *peMin - currPe;
-
+
if (diff > 0) {
*peMin = *peMin - ((diff * minFacLo) / 100);
*peMax = *peMax - ((diff * maxFacLo) / 100);
@@ -906,7 +906,7 @@
}
}
-
+
if ((*peMax - *peMin) < minDiff) {
Word16 partLo, partHi;
@@ -969,7 +969,7 @@
(adjThrChan->peMax - adjThrChan->peMin));
else
bitresFac = 0x7fff;
-
+
bitresFac = min(bitresFac,
(100-30 + extract_l((100 * bitresBits) / avgBits)));
@@ -995,23 +995,23 @@
/* common for all elements: */
/* parameters for bitres control */
- hAdjThr->bresParamLong.clipSaveLow = 20;
- hAdjThr->bresParamLong.clipSaveHigh = 95;
- hAdjThr->bresParamLong.minBitSave = -5;
- hAdjThr->bresParamLong.maxBitSave = 30;
- hAdjThr->bresParamLong.clipSpendLow = 20;
- hAdjThr->bresParamLong.clipSpendHigh = 95;
- hAdjThr->bresParamLong.minBitSpend = -10;
- hAdjThr->bresParamLong.maxBitSpend = 40;
+ hAdjThr->bresParamLong.clipSaveLow = 20;
+ hAdjThr->bresParamLong.clipSaveHigh = 95;
+ hAdjThr->bresParamLong.minBitSave = -5;
+ hAdjThr->bresParamLong.maxBitSave = 30;
+ hAdjThr->bresParamLong.clipSpendLow = 20;
+ hAdjThr->bresParamLong.clipSpendHigh = 95;
+ hAdjThr->bresParamLong.minBitSpend = -10;
+ hAdjThr->bresParamLong.maxBitSpend = 40;
- hAdjThr->bresParamShort.clipSaveLow = 20;
- hAdjThr->bresParamShort.clipSaveHigh = 75;
- hAdjThr->bresParamShort.minBitSave = 0;
- hAdjThr->bresParamShort.maxBitSave = 20;
- hAdjThr->bresParamShort.clipSpendLow = 20;
- hAdjThr->bresParamShort.clipSpendHigh = 75;
- hAdjThr->bresParamShort.minBitSpend = -5;
- hAdjThr->bresParamShort.maxBitSpend = 50;
+ hAdjThr->bresParamShort.clipSaveLow = 20;
+ hAdjThr->bresParamShort.clipSaveHigh = 75;
+ hAdjThr->bresParamShort.minBitSave = 0;
+ hAdjThr->bresParamShort.maxBitSave = 20;
+ hAdjThr->bresParamShort.clipSpendLow = 20;
+ hAdjThr->bresParamShort.clipSpendHigh = 75;
+ hAdjThr->bresParamShort.minBitSpend = -5;
+ hAdjThr->bresParamShort.maxBitSpend = 50;
/* specific for each element: */
@@ -1020,7 +1020,7 @@
atsElem->peMax = extract_l(((120*meanPe) / 100));
/* additional pe offset to correct pe2bits for low bitrates */
- atsElem->peOffset = 0;
+ atsElem->peOffset = 0;
if (chBitrate < 32000) {
atsElem->peOffset = max(50, (100 - extract_l((100 * chBitrate) / 32000)));
}
@@ -1039,24 +1039,24 @@
/* minSnr adaptation */
/* maximum reduction of minSnr goes down to minSnr^maxRed */
- msaParam->maxRed = 0x20000000; /* *0.25f /
+ msaParam->maxRed = 0x20000000; /* *0.25f /
/* start adaptation of minSnr for avgEn/sfbEn > startRatio */
- msaParam->startRatio = 0x0ccccccd; /* 10 */
+ msaParam->startRatio = 0x0ccccccd; /* 10 */
/* maximum minSnr reduction to minSnr^maxRed is reached for
avgEn/sfbEn >= maxRatio */
- msaParam->maxRatio = 0x0020c49c; /* 1000 */
+ msaParam->maxRatio = 0x0020c49c; /* 1000 */
/* helper variables to interpolate minSnr reduction for
avgEn/sfbEn between startRatio and maxRatio */
- msaParam->redRatioFac = 0xfb333333; /* -0.75/20 */
+ msaParam->redRatioFac = 0xfb333333; /* -0.75/20 */
- msaParam->redOffs = 0x30000000; /* msaParam->redRatioFac * 10*log10(msaParam->startRatio) */
+ msaParam->redOffs = 0x30000000; /* msaParam->redRatioFac * 10*log10(msaParam->startRatio) */
-
+
/* pe correction */
- atsElem->peLast = 0;
- atsElem->dynBitsLast = 0;
- atsElem->peCorrectionFactor = 100; /* 1.0 */
+ atsElem->peLast = 0;
+ atsElem->dynBitsLast = 0;
+ atsElem->peCorrectionFactor = 100; /* 1.0 */
}
@@ -1069,20 +1069,20 @@
*****************************************************************************/
static void calcPeCorrection(Word16 *correctionFac,
const Word16 peAct,
- const Word16 peLast,
- const Word16 bitsLast)
+ const Word16 peLast,
+ const Word16 bitsLast)
{
Word32 peAct100 = 100 * peAct;
Word32 peLast100 = 100 * peLast;
Word16 peBitsLast = bits2pe(bitsLast);
-
+
if ((bitsLast > 0) &&
(peAct100 < (150 * peLast)) && (peAct100 > (70 * peLast)) &&
((120 * peBitsLast) > peLast100 ) && (( 65 * peBitsLast) < peLast100))
{
Word16 newFac = (100 * peLast) / peBitsLast;
/* dead zone */
-
+
if (newFac < 100) {
newFac = min(((110 * newFac) / 100), 100);
newFac = max(newFac, 85);
@@ -1091,13 +1091,13 @@
newFac = max(((90 * newFac) / 100), 100);
newFac = min(newFac, 115);
}
-
+
if ((newFac > 100 && *correctionFac < 100) ||
(newFac < 100 && *correctionFac > 100)) {
- *correctionFac = 100;
+ *correctionFac = 100;
}
/* faster adaptation towards 1.0, slower in the other direction */
-
+
if ((*correctionFac < 100 && newFac < *correctionFac) ||
(*correctionFac > 100 && newFac > *correctionFac))
*correctionFac = (85 * *correctionFac + 15 * newFac) / 100;
@@ -1107,7 +1107,7 @@
*correctionFac = max(*correctionFac, 85);
}
else {
- *correctionFac = 100;
+ *correctionFac = 100;
}
}
@@ -1123,40 +1123,40 @@
PSY_OUT_ELEMENT *psyOutElement,
Word16 *chBitDistribution,
Word16 logSfbEnergy[MAX_CHANNELS][MAX_GROUPED_SFB],
- Word16 sfbNRelevantLines[MAX_CHANNELS][MAX_GROUPED_SFB],
+ Word16 sfbNRelevantLines[MAX_CHANNELS][MAX_GROUPED_SFB],
QC_OUT_ELEMENT *qcOE,
ELEMENT_BITS *elBits,
const Word16 nChannels,
const Word16 maxBitFac)
{
- PE_DATA peData;
+ PE_DATA peData;
Word16 noRedPe, grantedPe, grantedPeCorr;
Word16 curWindowSequence;
Word16 bitFactor;
Word16 avgBits = (elBits->averageBits - (qcOE->staticBitsUsed + qcOE->ancBitsUsed));
- Word16 bitresBits = elBits->bitResLevel;
+ Word16 bitresBits = elBits->bitResLevel;
Word16 maxBitresBits = elBits->maxBits;
Word16 sideInfoBits = (qcOE->staticBitsUsed + qcOE->ancBitsUsed);
Word16 ch;
-
+
prepareSfbPe(&peData, psyOutChannel, logSfbEnergy, sfbNRelevantLines, nChannels, AdjThrStateElement->peOffset);
-
+
/* pe without reduction */
calcSfbPe(&peData, psyOutChannel, nChannels);
- noRedPe = peData.pe;
+ noRedPe = peData.pe;
- curWindowSequence = LONG_WINDOW;
-
+ curWindowSequence = LONG_WINDOW;
+
if (nChannels == 2) {
-
+
if ((psyOutChannel[0].windowSequence == SHORT_WINDOW) ||
(psyOutChannel[1].windowSequence == SHORT_WINDOW)) {
- curWindowSequence = SHORT_WINDOW;
+ curWindowSequence = SHORT_WINDOW;
}
}
else {
- curWindowSequence = psyOutChannel[0].windowSequence;
+ curWindowSequence = psyOutChannel[0].windowSequence;
}
@@ -1170,13 +1170,13 @@
grantedPe = ((bitFactor * bits2pe(avgBits)) / 100);
/* correction of pe value */
- calcPeCorrection(&(AdjThrStateElement->peCorrectionFactor),
+ calcPeCorrection(&(AdjThrStateElement->peCorrectionFactor),
min(grantedPe, noRedPe),
- AdjThrStateElement->peLast,
+ AdjThrStateElement->peLast,
AdjThrStateElement->dynBitsLast);
grantedPeCorr = (grantedPe * AdjThrStateElement->peCorrectionFactor) / 100;
-
+
if (grantedPeCorr < noRedPe && noRedPe > peData.offset) {
/* calc threshold necessary for desired pe */
adaptThresholdsToPe(psyOutChannel,
@@ -1192,8 +1192,8 @@
/* calculate relative distribution */
for (ch=0; ch<nChannels; ch++) {
Word16 peOffsDiff = peData.pe - peData.offset;
- chBitDistribution[ch] = 200;
-
+ chBitDistribution[ch] = 200;
+
if (peOffsDiff > 0) {
Word32 temp = 1000 - (nChannels * 200);
chBitDistribution[ch] = chBitDistribution[ch] +
@@ -1202,10 +1202,10 @@
}
/* store pe */
- qcOE->pe = noRedPe;
+ qcOE->pe = noRedPe;
/* update last pe */
- AdjThrStateElement->peLast = grantedPe;
+ AdjThrStateElement->peLast = grantedPe;
}
/********************************************************************************
@@ -1217,7 +1217,7 @@
void AdjThrUpdate(ATS_ELEMENT *AdjThrStateElement,
const Word16 dynBitsUsed)
{
- AdjThrStateElement->dynBitsLast = dynBitsUsed;
+ AdjThrStateElement->dynBitsLast = dynBitsUsed;
}
diff --git a/media/libstagefright/codecs/aacenc/src/asm/ARMV5E/AutoCorrelation_v5.s b/media/libstagefright/codecs/aacenc/src/asm/ARMV5E/AutoCorrelation_v5.s
index e705197..e0885f1 100644
--- a/media/libstagefright/codecs/aacenc/src/asm/ARMV5E/AutoCorrelation_v5.s
+++ b/media/libstagefright/codecs/aacenc/src/asm/ARMV5E/AutoCorrelation_v5.s
@@ -22,34 +22,34 @@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- .section .text
+ .section .text
.global AutoCorrelation
AutoCorrelation:
stmdb sp!, {r4 - r11, lr}
- sub r13, r13, #20
+ sub r13, r13, #20
- mov r5, r0
- mov r7, r1
- mov r9, r3
- mov r2, r2, lsl #16
- mov r0, #0
- mov r4, r2, asr #16
- mov r8, #0
- cmp r4, #0
- ble L136
+ mov r5, r0
+ mov r7, r1
+ mov r9, r3
+ mov r2, r2, lsl #16
+ mov r0, #0
+ mov r4, r2, asr #16
+ mov r8, #0
+ cmp r4, #0
+ ble L136
+
+ cmp r4, #8
+ mov r2, #0
+ blt L133
- cmp r4, #8
- mov r2, #0
- blt L133
-
- sub r12, r4, #8
-L132:
- ldr r6, [r5, r2]
+ sub r12, r4, #8
+L132:
+ ldr r6, [r5, r2]
add r2, r2, #4
smulbb r3, r6, r6
- ldr r1, [r5, r2]
+ ldr r1, [r5, r2]
smultt r10, r6, r6
mov r3, r3, asr #9
smulbb r6, r1, r1
@@ -72,95 +72,95 @@
add r8, r8, #6
qadd r0, r0, r6
- cmp r8, r12
- blt L132
-L133:
- ldrsh r6, [r5, r2]
- mul r10, r6, r6
- add r2, r2, #2
- mov r1, r10, asr #9
+ cmp r8, r12
+ blt L132
+L133:
+ ldrsh r6, [r5, r2]
+ mul r10, r6, r6
+ add r2, r2, #2
+ mov r1, r10, asr #9
qadd r0, r0, r1
-L134:
- add r8, r8, #1
- cmp r8, r4
- blt L133
-L135:
-L136:
- str r0, [r7, #0]
- cmp r0, #0
- beq L1320
-L137:
- mov r2, r9, lsl #16
- mov r8, #1
- mov r2, r2, asr #16
- cmp r2, #1
- ble L1319
-L138:
-L139:
- sub r4, r4, #1
- mov r14, #0
- mov r3, #0
- cmp r4, #0
- ble L1317
-L1310:
- cmp r4, #6
- addlt r6, r5, r8, lsl #1
- blt L1314
-L1311:
- add r6, r5, r8, lsl #1
- sub r12, r4, #6
- str r8, [r13, #8]
- str r7, [r13, #4]
-L1312:
- mov r1, r3, lsl #1
- ldrsh r7, [r6, r1]
- ldrsh r10, [r5, r1]
- add r8, r1, r6
- add r9, r5, r1
+L134:
+ add r8, r8, #1
+ cmp r8, r4
+ blt L133
+L135:
+L136:
+ str r0, [r7, #0]
+ cmp r0, #0
+ beq L1320
+L137:
+ mov r2, r9, lsl #16
+ mov r8, #1
+ mov r2, r2, asr #16
+ cmp r2, #1
+ ble L1319
+L138:
+L139:
+ sub r4, r4, #1
+ mov r14, #0
+ mov r3, #0
+ cmp r4, #0
+ ble L1317
+L1310:
+ cmp r4, #6
+ addlt r6, r5, r8, lsl #1
+ blt L1314
+L1311:
+ add r6, r5, r8, lsl #1
+ sub r12, r4, #6
+ str r8, [r13, #8]
+ str r7, [r13, #4]
+L1312:
+ mov r1, r3, lsl #1
+ ldrsh r7, [r6, r1]
+ ldrsh r10, [r5, r1]
+ add r8, r1, r6
+ add r9, r5, r1
mul r7, r10, r7
- ldrsh r1, [r8, #2]
- ldrsh r10, [r8, #4]
- add r7, r14, r7, asr #9
- ldrsh r0, [r9, #2]
- ldrsh r11, [r9, #4]
- mul r1, r0, r1
- ldrsh r14, [r8, #6]
- mul r10, r11, r10
- add r7, r7, r1, asr #9
- ldrsh r8, [r8, #8]
+ ldrsh r1, [r8, #2]
+ ldrsh r10, [r8, #4]
+ add r7, r14, r7, asr #9
+ ldrsh r0, [r9, #2]
+ ldrsh r11, [r9, #4]
+ mul r1, r0, r1
+ ldrsh r14, [r8, #6]
+ mul r10, r11, r10
+ add r7, r7, r1, asr #9
+ ldrsh r8, [r8, #8]
add r3, r3, #5
- ldrsh r11, [r9, #6]
- ldrsh r1, [r9, #8]
- mul r14, r11, r14
- add r7, r7, r10, asr #9
- mul r1, r1, r8
- add r14, r7, r14, asr #9
- cmp r3, r12
- add r14, r14, r1, asr #9
- ble L1312
-L1313:
- ldr r8, [r13, #8]
- ldr r7, [r13, #4]
-L1314:
-L1315:
- mov r12, r3, lsl #1
- ldrsh r9, [r6, r12]
- ldrsh r12, [r5, r12]
- add r3, r3, #1
- cmp r3, r4
- mul r12, r12, r9
- add r14, r14, r12, asr #9
- blt L1315
-L1316:
-L1317:
- str r14, [r7, +r8, lsl #2]
- add r8, r8, #1
- cmp r8, r2
- blt L139
-
+ ldrsh r11, [r9, #6]
+ ldrsh r1, [r9, #8]
+ mul r14, r11, r14
+ add r7, r7, r10, asr #9
+ mul r1, r1, r8
+ add r14, r7, r14, asr #9
+ cmp r3, r12
+ add r14, r14, r1, asr #9
+ ble L1312
+L1313:
+ ldr r8, [r13, #8]
+ ldr r7, [r13, #4]
+L1314:
+L1315:
+ mov r12, r3, lsl #1
+ ldrsh r9, [r6, r12]
+ ldrsh r12, [r5, r12]
+ add r3, r3, #1
+ cmp r3, r4
+ mul r12, r12, r9
+ add r14, r14, r12, asr #9
+ blt L1315
+L1316:
+L1317:
+ str r14, [r7, +r8, lsl #2]
+ add r8, r8, #1
+ cmp r8, r2
+ blt L139
+
L1319:
L1320:
- add r13, r13, #20
+ add r13, r13, #20
ldmia sp!, {r4 - r11, pc}
@ENDP @ |AutoCorrelation|
diff --git a/media/libstagefright/codecs/aacenc/src/asm/ARMV5E/CalcWindowEnergy_v5.s b/media/libstagefright/codecs/aacenc/src/asm/ARMV5E/CalcWindowEnergy_v5.s
index b30e8cb..75b916c 100644
--- a/media/libstagefright/codecs/aacenc/src/asm/ARMV5E/CalcWindowEnergy_v5.s
+++ b/media/libstagefright/codecs/aacenc/src/asm/ARMV5E/CalcWindowEnergy_v5.s
@@ -22,91 +22,91 @@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
.section .text
-
+
.global CalcWindowEnergy
CalcWindowEnergy:
stmdb sp!, {r4 - r11, lr}
- sub r13, r13, #20
+ sub r13, r13, #20
- mov r3, r3, lsl #16
+ mov r3, r3, lsl #16
ldr r10, [r0, #168] @ states0 = blockSwitchingControl->iirStates[0];
- mov r3, r3, asr #16
+ mov r3, r3, asr #16
ldr r11, [r0, #172] @ states1 = blockSwitchingControl->iirStates[1];
mov r2, r2, lsl #16
- ldr r12, hiPassCoeff @ Coeff0 = hiPassCoeff[0];
+ ldr r12, hiPassCoeff @ Coeff0 = hiPassCoeff[0];
mov r2, r2, asr #16
ldr r14, hiPassCoeff + 4 @ Coeff1 = hiPassCoeff[1];
-
+
mov r8, #0 @ w=0
mov r5, #0 @ wOffset = 0;
-
+
BLOCK_BEGIN:
- mov r6, #0 @ accuUE = 0;
- mov r7, #0 @ accuFE = 0;
+ mov r6, #0 @ accuUE = 0;
+ mov r7, #0 @ accuFE = 0;
mov r4, #0 @ i=0
-
- str r8, [r13, #4]
- str r0, [r13, #8]
+
+ str r8, [r13, #4]
+ str r0, [r13, #8]
str r3, [r13, #12]
-
-ENERGY_BEG:
- mov r9, r5, lsl #1
+
+ENERGY_BEG:
+ mov r9, r5, lsl #1
ldrsh r9, [r1, r9] @ tempUnfiltered = timeSignal[tidx];
add r5, r5, r2 @ tidx = tidx + chIncrement;
-
- smulwb r3, r14, r9 @ accu1 = L_mpy_ls(Coeff1, tempUnfiltered);
+
+ smulwb r3, r14, r9 @ accu1 = L_mpy_ls(Coeff1, tempUnfiltered);
smull r0, r8, r12, r11 @ accu2 = fixmul( Coeff0, states1 );
-
+
mov r3, r3, lsl #1
mov r8, r8, lsl #1
- sub r0, r3, r10 @ accu3 = accu1 - states0;
+ sub r0, r3, r10 @ accu3 = accu1 - states0;
sub r8, r0, r8 @ out = accu3 - accu2;
mov r10, r3 @ states0 = accu1;
- mov r11, r8 @ states1 = out;
-
- mul r3, r9, r9
+ mov r11, r8 @ states1 = out;
+
+ mul r3, r9, r9
mov r8, r8, asr #16
-
+
add r4, r4, #1
add r6, r6, r3, asr #7
- mul r9, r8, r8
+ mul r9, r8, r8
ldr r3, [r13, #12]
add r7, r7, r9, asr #7
-
- cmp r4, r3
- blt ENERGY_BEG
-
+
+ cmp r4, r3
+ blt ENERGY_BEG
+
ldr r0, [r13, #8]
ldr r8, [r13, #4]
-
+
ENERGY_END:
add r4, r0, r8, lsl #2
- str r6, [r4, #72]
- add r8, r8, #1
- str r7, [r4, #136]
+ str r6, [r4, #72]
+ add r8, r8, #1
+ str r7, [r4, #136]
cmp r8, #8
- blt BLOCK_BEGIN
+ blt BLOCK_BEGIN
BLOCK_END:
- str r10, [r0, #168]
- str r11, [r0, #172]
- mov r0, #1
-
- add r13, r13, #20
- ldmia sp!, {r4 - r11, pc}
+ str r10, [r0, #168]
+ str r11, [r0, #172]
+ mov r0, #1
+
+ add r13, r13, #20
+ ldmia sp!, {r4 - r11, pc}
hiPassCoeff:
.word 0xbec8b439
.word 0x609d4952
-
+
@ENDP
.end
diff --git a/media/libstagefright/codecs/aacenc/src/asm/ARMV5E/PrePostMDCT_v5.s b/media/libstagefright/codecs/aacenc/src/asm/ARMV5E/PrePostMDCT_v5.s
index 103cc91..38fe092 100644
--- a/media/libstagefright/codecs/aacenc/src/asm/ARMV5E/PrePostMDCT_v5.s
+++ b/media/libstagefright/codecs/aacenc/src/asm/ARMV5E/PrePostMDCT_v5.s
@@ -26,46 +26,46 @@
PreMDCT:
stmdb sp!, {r4 - r11, lr}
-
+
add r9, r0, r1, lsl #2
sub r3, r9, #8
movs r1, r1, asr #2
beq PreMDCT_END
-
+
PreMDCT_LOOP:
ldr r8, [r2], #4
ldr r9, [r2], #4
-
+
ldrd r4, [r0]
ldrd r6, [r3]
-
+
smull r14, r11, r4, r8 @ MULHIGH(tr1, cosa)
smull r10, r12, r7, r8 @ MULHIGH(ti1, cosa)
-
+
smull r14, r8, r7, r9 @ MULHIGH(ti1, sina)
- smull r7, r10, r4, r9 @ MULHIGH(tr1, sina)
-
- add r11, r11, r8 @ MULHIGH(cosa, tr1) + MULHIGH(sina, ti1)@
+ smull r7, r10, r4, r9 @ MULHIGH(tr1, sina)
+
+ add r11, r11, r8 @ MULHIGH(cosa, tr1) + MULHIGH(sina, ti1)@
sub r7, r12, r10 @ MULHIGH(ti1, cosa) - MULHIGH(tr1, sina)
-
+
ldr r8, [r2], #4
ldr r9, [r2], #4
-
+
smull r14, r4, r6, r8 @ MULHIGH(tr2, cosa)
smull r10, r12, r5, r8 @ MULHIGH(ti2, cosa)
-
+
smull r14, r8, r5, r9 @ MULHIGH(ti2, sina)
smull r5, r10, r6, r9 @ MULHIGH(tr2, sina)
-
+
add r8, r8, r4
sub r9, r12, r10
+
+ mov r6, r11
- mov r6, r11
-
- strd r6, [r0]
+ strd r6, [r0]
strd r8, [r3]
-
+
subs r1, r1, #1
sub r3, r3, #8
add r0, r0, #8
@@ -74,52 +74,52 @@
PreMDCT_END:
ldmia sp!, {r4 - r11, pc}
@ENDP @ |PreMDCT|
-
+
.section .text
.global PostMDCT
PostMDCT:
stmdb sp!, {r4 - r11, lr}
-
+
add r9, r0, r1, lsl #2
sub r3, r9, #8
movs r1, r1, asr #2
beq PostMDCT_END
-
+
PostMDCT_LOOP:
- ldr r8, [r2], #4
+ ldr r8, [r2], #4
ldr r9, [r2], #4
-
+
ldrd r4, [r0]
ldrd r6, [r3]
-
+
smull r14, r11, r4, r8 @ MULHIGH(tr1, cosa)
smull r10, r12, r5, r8 @ MULHIGH(ti1, cosa)
-
+
smull r14, r8, r5, r9 @ MULHIGH(ti1, sina)
- smull r5, r10, r4, r9 @ MULHIGH(tr1, sina)
-
- add r4, r11, r8 @ MULHIGH(cosa, tr1) + MULHIGH(sina, ti1)@
+ smull r5, r10, r4, r9 @ MULHIGH(tr1, sina)
+
+ add r4, r11, r8 @ MULHIGH(cosa, tr1) + MULHIGH(sina, ti1)@
sub r11, r10, r12 @ MULHIGH(ti1, cosa) - MULHIGH(tr1, sina)@
-
+
ldr r8, [r2], #4 @
ldr r9, [r2], #4
-
+
smull r14, r5, r6, r8 @ MULHIGH(tr2, cosa)
smull r10, r12, r7, r8 @ MULHIGH(ti2, cosa)
-
+
smull r14, r8, r7, r9 @ MULHIGH(ti2, sina)
smull r7, r10, r6, r9 @ MULHIGH(tr2, sina)
-
+
add r6, r8, r5 @ MULHIGH(cosb, tr2) + MULHIGH(sinb, ti2)@
sub r5, r10, r12 @ MULHIGH(sinb, tr2) - MULHIGH(cosb, ti2)@
-
- mov r7, r11
+
+ mov r7, r11
strd r4, [r0]
strd r6, [r3]
-
+
subs r1, r1, #1
sub r3, r3, #8
add r0, r0, #8
diff --git a/media/libstagefright/codecs/aacenc/src/asm/ARMV5E/R4R8First_v5.s b/media/libstagefright/codecs/aacenc/src/asm/ARMV5E/R4R8First_v5.s
index 72cb9a3..b30881a 100644
--- a/media/libstagefright/codecs/aacenc/src/asm/ARMV5E/R4R8First_v5.s
+++ b/media/libstagefright/codecs/aacenc/src/asm/ARMV5E/R4R8First_v5.s
@@ -26,46 +26,46 @@
Radix4First:
stmdb sp!, {r4 - r11, lr}
-
+
movs r10, r1
mov r11, r0
beq Radix4First_END
-
+
Radix4First_LOOP:
ldrd r0, [r11]
ldrd r2, [r11, #8]
ldrd r4, [r11, #16]
ldrd r6, [r11, #24]
-
+
add r8, r0, r2
add r9, r1, r3
-
+
sub r0, r0, r2
sub r1, r1, r3
-
+
add r2, r4, r6
add r3, r5, r7
-
+
sub r4, r4, r6
sub r5, r5, r7
-
+
add r6, r8, r2
add r7, r9, r3
-
+
sub r8, r8, r2
sub r9, r9, r3
-
+
add r2, r0, r5
sub r3, r1, r4
-
+
sub r0, r0, r5
add r1, r1, r4
-
+
strd r6, [r11]
strd r2, [r11, #8]
strd r8, [r11, #16]
strd r0, [r11, #24]
-
+
subs r10, r10, #1
add r11, r11, #32
bne Radix4First_LOOP
@@ -73,180 +73,180 @@
Radix4First_END:
ldmia sp!, {r4 - r11, pc}
@ENDP @ |Radix4First|
-
+
.section .text
.global Radix8First
Radix8First:
stmdb sp!, {r4 - r11, lr}
sub sp, sp, #0x24
-
+
mov r12, r1
mov r14, r0
cmp r12, #0
beq Radix8First_END
-
+
Radix8First_LOOP:
- ldrd r0, [r14]
+ ldrd r0, [r14]
ldrd r2, [r14, #8]
ldrd r4, [r14, #16]
ldrd r6, [r14, #24]
-
+
add r8, r0, r2 @ r0 = buf[0] + buf[2]@
add r9, r1, r3 @ i0 = buf[1] + buf[3]@
-
+
sub r0, r0, r2 @ r1 = buf[0] - buf[2]@
sub r1, r1, r3 @ i1 = buf[1] - buf[3]@
-
+
add r2, r4, r6 @ r2 = buf[4] + buf[6]@
add r3, r5, r7 @ i2 = buf[5] + buf[7]@
-
+
sub r4, r4, r6 @ r3 = buf[4] - buf[6]@
sub r5, r5, r7 @ i3 = buf[5] - buf[7]@
-
+
add r6, r8, r2 @ r4 = (r0 + r2) >> 1@
add r7, r9, r3 @ i4 = (i0 + i2) >> 1@
-
+
sub r8, r8, r2 @ r5 = (r0 - r2) >> 1@
sub r9, r9, r3 @ i5 = (i0 - i2) >> 1@
-
+
sub r2, r0, r5 @ r6 = (r1 - i3) >> 1@
add r3, r1, r4 @ i6 = (i1 + r3) >> 1@
-
+
add r0, r0, r5 @ r7 = (r1 + i3) >> 1@
sub r1, r1, r4 @ i7 = (i1 - r3) >> 1@
-
+
mov r6, r6, asr #1 @
mov r7, r7, asr #1 @
-
+
mov r8, r8, asr #1
mov r9, r9, asr #1
-
+
mov r2, r2, asr #1
mov r3, r3, asr #1
-
+
mov r0, r0, asr #1
- mov r1, r1, asr #1
-
+ mov r1, r1, asr #1
+
str r6, [sp]
str r7, [sp, #4]
-
+
str r8, [sp, #8]
str r9, [sp, #12]
-
+
str r2, [sp, #16]
- str r3, [sp, #20]
-
+ str r3, [sp, #20]
+
str r0, [sp, #24]
- str r1, [sp, #28]
-
- ldrd r2, [r14, #32]
+ str r1, [sp, #28]
+
+ ldrd r2, [r14, #32]
ldrd r4, [r14, #40]
ldrd r6, [r14, #48]
ldrd r8, [r14, #56]
-
+
add r0, r2, r4 @ r0 = buf[ 8] + buf[10]@
add r1, r3, r5 @ i0 = buf[ 9] + buf[11]@
-
+
sub r2, r2, r4 @ r1 = buf[ 8] - buf[10]@
sub r3, r3, r5 @ i1 = buf[ 9] - buf[11]@
-
+
add r4, r6, r8 @ r2 = buf[12] + buf[14]@
add r5, r7, r9 @ i2 = buf[13] + buf[15]@
-
+
sub r6, r6, r8 @ r3 = buf[12] - buf[14]@
sub r7, r7, r9 @ i3 = buf[13] - buf[15]@
-
+
add r8, r0, r4 @ t0 = (r0 + r2)
add r9, r1, r5 @ t1 = (i0 + i2)
-
+
sub r0, r0, r4 @ t2 = (r0 - r2)
sub r1, r1, r5 @ t3 = (i0 - i2)
-
+
mov r8, r8, asr #1
ldr r4, [sp]
-
+
mov r9, r9, asr #1
ldr r5, [sp, #4]
-
- mov r0, r0, asr #1
+
+ mov r0, r0, asr #1
mov r1, r1, asr #1
-
+
add r10, r4, r8 @ buf[ 0] = r4 + t0@
add r11, r5, r9 @ buf[ 1] = i4 + t1@
-
+
sub r4, r4, r8 @ buf[ 8] = r4 - t0@
sub r5, r5, r9 @ buf[ 9] = i4 - t1@
-
+
strd r10, [r14]
strd r4, [r14, #32]
-
+
ldr r10, [sp, #8]
ldr r11, [sp, #12]
-
+
add r4, r10, r1 @ buf[ 4] = r5 + t3@
sub r5, r11, r0 @ buf[ 5] = i5 - t2@
-
+
sub r10, r10, r1 @ buf[12] = r5 - t3@
add r11, r11, r0 @ buf[13] = i5 + t2@
-
+
strd r4, [r14, #16]
strd r10, [r14, #48]
-
+
sub r0, r2, r7 @ r0 = r1 - i3@
add r1, r3, r6 @ i0 = i1 + r3@
-
+
ldr r11, DATATab
-
+
add r2, r2, r7 @ r2 = r1 + i3@
sub r3, r3, r6 @ i2 = i1 - r3@
-
+
sub r4, r0, r1 @ r0 - i0
add r5, r0, r1 @ r0 + i0
-
+
sub r0, r2, r3 @ r2 - i2
add r1, r2, r3 @ r2 + i2
-
- smull r8, r6, r4, r11
- smull r9, r7, r5, r11
-
+
+ smull r8, r6, r4, r11
+ smull r9, r7, r5, r11
+
ldr r2, [sp, #16]
ldr r3, [sp, #20]
-
- smull r8, r4, r0, r11
- smull r9, r5, r1, r11
-
+
+ smull r8, r4, r0, r11
+ smull r9, r5, r1, r11
+
ldr r10, [sp, #24]
ldr r11, [sp, #28]
-
+
sub r8, r2, r6
sub r9, r3, r7
-
+
add r2, r2, r6
add r3, r3, r7
-
+
add r6, r10, r5
sub r7, r11, r4
-
+
sub r0, r10, r5
add r1, r11, r4
-
+
strd r6, [r14, #8]
strd r8, [r14, #24]
strd r0, [r14, #40]
strd r2, [r14, #56]
-
+
subs r12, r12, #1
add r14, r14, #64
-
+
bne Radix8First_LOOP
-
+
Radix8First_END:
add sp, sp, #0x24
ldmia sp!, {r4 - r11, pc}
-
+
DATATab:
.word 0x5a82799a
-
+
@ENDP @ |Radix8First|
.end
\ No newline at end of file
diff --git a/media/libstagefright/codecs/aacenc/src/asm/ARMV5E/Radix4FFT_v5.s b/media/libstagefright/codecs/aacenc/src/asm/ARMV5E/Radix4FFT_v5.s
index e81c82e..bc069b4 100644
--- a/media/libstagefright/codecs/aacenc/src/asm/ARMV5E/Radix4FFT_v5.s
+++ b/media/libstagefright/codecs/aacenc/src/asm/ARMV5E/Radix4FFT_v5.s
@@ -25,145 +25,145 @@
Radix4FFT:
stmdb sp!, {r4 - r11, lr}
- sub sp, sp, #32
+ sub sp, sp, #32
mov r1, r1, asr #2
- cmp r1, #0
- beq Radix4FFT_END
-
-Radix4FFT_LOOP1:
- mov r14, r0 @ xptr = buf@
+ cmp r1, #0
+ beq Radix4FFT_END
+
+Radix4FFT_LOOP1:
+ mov r14, r0 @ xptr = buf@
mov r10, r1 @ i = num@
mov r9, r2, lsl #3 @ step = 2*bgn@
- cmp r10, #0
- str r0, [sp]
- str r1, [sp, #4]
+ cmp r10, #0
+ str r0, [sp]
+ str r1, [sp, #4]
str r2, [sp, #8]
- str r3, [sp, #12]
- beq Radix4FFT_LOOP1_END
-
-Radix4FFT_LOOP2:
+ str r3, [sp, #12]
+ beq Radix4FFT_LOOP1_END
+
+Radix4FFT_LOOP2:
mov r12, r3 @ csptr = twidTab@
mov r11, r2 @ j = bgn
- cmp r11, #0
+ cmp r11, #0
str r10, [sp, #16]
- beq Radix4FFT_LOOP2_END
-
-Radix4FFT_LOOP3:
- str r11, [sp, #20]
-
+ beq Radix4FFT_LOOP2_END
+
+Radix4FFT_LOOP3:
+ str r11, [sp, #20]
+
ldrd r0, [r14, #0] @ r0 = xptr[0]@ r1 = xptr[1]@
add r14, r14, r9 @ xptr += step@
-
- ldrd r10, [r14, #0] @ r2 = xptr[0]@ r3 = xptr[1]@
+
+ ldrd r10, [r14, #0] @ r2 = xptr[0]@ r3 = xptr[1]@
ldr r8, [r12], #4 @ cosxsinx = csptr[0]@
-
+
smulwt r4, r10, r8 @ L_mpy_wx(cosx, t0)
smulwt r3, r11, r8 @ L_mpy_wx(cosx, t1)
-
+
smlawb r2, r11, r8, r4 @ r2 = L_mpy_wx(cosx, t0) + L_mpy_wx(sinx, t1)@
smulwb r5, r10, r8 @ L_mpy_wx(sinx, t0)
-
+
mov r10, r0, asr #2 @ t0 = r0 >> 2@
mov r11, r1, asr #2 @ t1 = r1 >> 2@
-
+
sub r3, r3, r5 @ r3 = L_mpy_wx(cosx, t1) - L_mpy_wx(sinx, t0)@
add r14, r14, r9 @ xptr += step@
-
+
sub r0, r10, r2 @ r0 = t0 - r2@
sub r1, r11, r3 @ r1 = t1 - r3@
-
+
add r2, r10, r2 @ r2 = t0 + r2@
add r3, r11, r3 @ r3 = t1 + r3@
-
+
str r2, [sp, #24]
str r3, [sp, #28]
-
+
ldrd r10, [r14, #0] @ r4 = xptr[0]@ r5 = xptr[1]@
ldr r8, [r12], #4 @ cosxsinx = csptr[1]@
-
+
smulwt r6, r10, r8 @ L_mpy_wx(cosx, t0)
smulwt r5, r11, r8 @ L_mpy_wx(cosx, t1)
-
+
smlawb r4, r11, r8, r6 @ r4 = L_mpy_wx(cosx, t0) + L_mpy_wx(sinx, t1)@
smulwb r7, r10, r8 @ L_mpy_wx(sinx, t0)
-
+
add r14, r14, r9 @ xptr += step@
sub r5, r5, r7 @ r5 = L_mpy_wx(cosx, t1) - L_mpy_wx(sinx, t0)@
-
+
ldrd r10, [r14] @ r6 = xptr[0]@ r7 = xptr[1]@
ldr r8, [r12], #4 @ cosxsinx = csptr[1]@
-
+
smulwt r2, r10, r8 @ L_mpy_wx(cosx, t0)
smulwt r7, r11, r8 @ L_mpy_wx(cosx, t1)
-
+
smlawb r6, r11, r8, r2 @ r4 = L_mpy_wx(cosx, t0) + L_mpy_wx(sinx, t1)@
smulwb r3, r10, r8 @ L_mpy_wx(sinx, t0)
-
+
mov r10, r4 @ t0 = r4@
- mov r11, r5 @ t1 = r5@
-
+ mov r11, r5 @ t1 = r5@
+
sub r7, r7, r3 @ r5 = L_mpy_wx(cosx, t1) - L_mpy_wx(sinx, t0)@
+
-
- add r4, r10, r6 @ r4 = t0 + r6@
+ add r4, r10, r6 @ r4 = t0 + r6@
sub r5, r7, r11 @ r5 = r7 - t1@
-
+
sub r6, r10, r6 @ r6 = t0 - r6@
add r7, r7, r11 @ r7 = r7 + t1@
-
+
ldr r2, [sp, #24]
ldr r3, [sp, #28]
-
+
add r10, r0, r5 @ xptr[0] = r0 + r5@
add r11, r1, r6 @ xptr[0] = r1 + r6
-
- strd r10, [r14]
+
+ strd r10, [r14]
sub r14, r14, r9 @ xptr -= step@
-
+
sub r10, r2, r4 @ xptr[0] = r2 - r4@
sub r11, r3, r7 @ xptr[1] = r3 - r7@
-
- strd r10, [r14]
+
+ strd r10, [r14]
sub r14, r14, r9 @ xptr -= step@
-
+
sub r10, r0, r5 @ xptr[0] = r0 - r5@
sub r11, r1, r6 @ xptr[0] = r1 - r6
-
- strd r10, [r14]
+
+ strd r10, [r14]
sub r14, r14, r9 @ xptr -= step@
-
+
add r10, r2, r4 @ xptr[0] = r2 - r4@
add r11, r3, r7 @ xptr[1] = r3 - r7@
-
- strd r10, [r14]
+
+ strd r10, [r14]
add r14, r14, #8 @ xptr += 2@
-
+
ldr r11, [sp, #20]
subs r11, r11, #1
- bne Radix4FFT_LOOP3
-
-Radix4FFT_LOOP2_END:
+ bne Radix4FFT_LOOP3
+
+Radix4FFT_LOOP2_END:
ldr r10, [sp, #16]
ldr r3, [sp, #12]
ldr r2, [sp, #8]
- rsb r8, r9, r9, lsl #2
+ rsb r8, r9, r9, lsl #2
sub r10, r10, #1
- add r14, r14, r8
- cmp r10, #0
- bhi Radix4FFT_LOOP2
-
-Radix4FFT_LOOP1_END:
- ldr r0, [sp]
+ add r14, r14, r8
+ cmp r10, #0
+ bhi Radix4FFT_LOOP2
+
+Radix4FFT_LOOP1_END:
+ ldr r0, [sp]
ldr r1, [sp, #4]
add r3, r3, r8, asr #1
- mov r2, r2, lsl #2
- movs r1, r1, asr #2
- bne Radix4FFT_LOOP1
-
-Radix4FFT_END:
- add sp, sp, #32
+ mov r2, r2, lsl #2
+ movs r1, r1, asr #2
+ bne Radix4FFT_LOOP1
+
+Radix4FFT_END:
+ add sp, sp, #32
ldmia sp!, {r4 - r11, pc}
-
+
@ENDP @ |Radix4FFT|
.end
\ No newline at end of file
diff --git a/media/libstagefright/codecs/aacenc/src/asm/ARMV5E/band_nrg_v5.s b/media/libstagefright/codecs/aacenc/src/asm/ARMV5E/band_nrg_v5.s
index 4789f6d..3b88810 100644
--- a/media/libstagefright/codecs/aacenc/src/asm/ARMV5E/band_nrg_v5.s
+++ b/media/libstagefright/codecs/aacenc/src/asm/ARMV5E/band_nrg_v5.s
@@ -26,31 +26,31 @@
.global CalcBandEnergy
CalcBandEnergy:
- stmdb sp!, {r4 - r11, lr}
-
- mov r2, r2, lsl #16
+ stmdb sp!, {r4 - r11, lr}
+
+ mov r2, r2, lsl #16
ldr r12, [r13, #36]
mov r9, #0
- mov r5, r2, asr #16
- mov r4, #0
- cmp r5, #0
- ble L212
+ mov r5, r2, asr #16
+ mov r4, #0
+ cmp r5, #0
+ ble L212
L22:
- mov r2, r4, lsl #1
- ldrsh r10, [r1, r2]
- add r11, r1, r2
- ldrsh r2, [r11, #2]
- mov r14, #0
- cmp r10, r2
- bge L28
-
+ mov r2, r4, lsl #1
+ ldrsh r10, [r1, r2]
+ add r11, r1, r2
+ ldrsh r2, [r11, #2]
+ mov r14, #0
+ cmp r10, r2
+ bge L28
+
L23:
- ldr r11, [r0, +r10, lsl #2]
- add r10, r10, #1
- ldr r6, [r0, +r10, lsl #2]
+ ldr r11, [r0, +r10, lsl #2]
+ add r10, r10, #1
+ ldr r6, [r0, +r10, lsl #2]
smull r11, r7, r11, r11
- add r10, r10, #1
+ add r10, r10, #1
smull r6, r8, r6, r6
ldr r11, [r0, +r10, lsl #2]
qadd r14, r14, r7
@@ -59,71 +59,71 @@
ldr r6, [r0, +r10, lsl #2]
qadd r14, r14, r8
smull r6, r8, r6, r6
- add r10, r10, #1
+ add r10, r10, #1
qadd r14, r14, r7
cmp r10, r2
qadd r14, r14, r8
- blt L23
+ blt L23
-L28:
+L28:
qadd r14, r14, r14
str r14, [r3, +r4, lsl #2]
- add r4, r4, #1
+ add r4, r4, #1
qadd r9, r9, r14
- cmp r4, r5
+ cmp r4, r5
- blt L22
+ blt L22
-L212:
- str r9, [r12, #0]
+L212:
+ str r9, [r12, #0]
ldmia sp!, {r4 - r11, pc}
-
+
@ENDP ; |CalcBandEnergy|
-
+
.global CalcBandEnergyMS
CalcBandEnergyMS:
stmdb sp!, {r4 - r11, lr}
sub r13, r13, #24
-
- mov r12, #0
- mov r3, r3, lsl #16
- mov r14, #0
- mov r3, r3, asr #16
- cmp r3, #0
- mov r4, #0
- ble L315
-
-L32:
+
+ mov r12, #0
+ mov r3, r3, lsl #16
+ mov r14, #0
+ mov r3, r3, asr #16
+ cmp r3, #0
+ mov r4, #0
+ ble L315
+
+L32:
mov r5, r4, lsl #1
mov r6, #0
ldrsh r10, [r2, r5]
add r5, r2, r5
mov r7, #0
- ldrsh r11, [r5, #2]
- cmp r10, r11
- bge L39
+ ldrsh r11, [r5, #2]
+ cmp r10, r11
+ bge L39
str r3, [r13, #4]
str r4, [r13, #8]
str r12, [r13, #12]
str r14, [r13, #16]
-L33:
- ldr r8, [r0, +r10, lsl #2]
+L33:
+ ldr r8, [r0, +r10, lsl #2]
ldr r9, [r1, +r10, lsl #2]
mov r8, r8, asr #1
add r10, r10, #1
mov r9, r9, asr #1
- ldr r12, [r0, +r10, lsl #2]
- add r5, r8, r9
+ ldr r12, [r0, +r10, lsl #2]
+ add r5, r8, r9
ldr r14, [r1, +r10, lsl #2]
sub r8, r8, r9
- smull r5, r3, r5, r5
+ smull r5, r3, r5, r5
mov r12, r12, asr #1
- smull r8, r4, r8, r8
+ smull r8, r4, r8, r8
mov r14, r14, asr #1
qadd r6, r6, r3
@@ -131,27 +131,27 @@
qadd r7, r7, r4
sub r8, r12, r14
- smull r5, r3, r5, r5
+ smull r5, r3, r5, r5
add r10, r10, #1
- smull r8, r4, r8, r8
-
+ smull r8, r4, r8, r8
+
qadd r6, r6, r3
qadd r7, r7, r4
- ldr r8, [r0, +r10, lsl #2]
+ ldr r8, [r0, +r10, lsl #2]
ldr r9, [r1, +r10, lsl #2]
mov r8, r8, asr #1
add r10, r10, #1
mov r9, r9, asr #1
- ldr r12, [r0, +r10, lsl #2]
- add r5, r8, r9
+ ldr r12, [r0, +r10, lsl #2]
+ add r5, r8, r9
ldr r14, [r1, +r10, lsl #2]
sub r8, r8, r9
- smull r5, r3, r5, r5
+ smull r5, r3, r5, r5
mov r12, r12, asr #1
- smull r8, r4, r8, r8
+ smull r8, r4, r8, r8
mov r14, r14, asr #1
qadd r6, r6, r3
@@ -159,37 +159,37 @@
qadd r7, r7, r4
sub r8, r12, r14
- smull r5, r3, r5, r5
+ smull r5, r3, r5, r5
add r10, r10, #1
- smull r8, r4, r8, r8
-
+ smull r8, r4, r8, r8
+
qadd r6, r6, r3
qadd r7, r7, r4
cmp r10, r11
-
+
blt L33
ldr r3, [r13, #4]
- ldr r4, [r13, #8]
+ ldr r4, [r13, #8]
ldr r12, [r13, #12]
ldr r14, [r13, #16]
-L39:
+L39:
qadd r6, r6, r6
- qadd r7, r7, r7
-
+ qadd r7, r7, r7
+
ldr r8, [r13, #60]
ldr r9, [r13, #68]
qadd r12, r12, r6
qadd r14, r14, r7
-
- str r6, [r8, +r4, lsl #2]
- str r7, [r9, +r4, lsl #2]
-
+
+ str r6, [r8, +r4, lsl #2]
+ str r7, [r9, +r4, lsl #2]
+
add r4, r4, #1
cmp r4, r3
- blt L32
+ blt L32
L315:
ldr r8, [r13, #64]
diff --git a/media/libstagefright/codecs/aacenc/src/asm/ARMV7/PrePostMDCT_v7.s b/media/libstagefright/codecs/aacenc/src/asm/ARMV7/PrePostMDCT_v7.s
index 64d767a..a04c105 100644
--- a/media/libstagefright/codecs/aacenc/src/asm/ARMV7/PrePostMDCT_v7.s
+++ b/media/libstagefright/codecs/aacenc/src/asm/ARMV7/PrePostMDCT_v7.s
@@ -26,53 +26,53 @@
PreMDCT:
stmdb sp!, {r4 - r11, lr}
-
+
add r9, r0, r1, lsl #2
sub r3, r9, #32
movs r1, r1, asr #2
- beq PreMDCT_END
-
+ beq PreMDCT_END
+
PreMDCT_LOOP:
VLD4.I32 {d0, d2, d4, d6}, [r2]! @ cosa = *csptr++@ sina = *csptr++@
VLD4.I32 {d1, d3, d5, d7}, [r2]! @ cosb = *csptr++@ sinb = *csptr++@
VLD2.I32 {d8, d9, d10, d11}, [r0] @ tr1 = *(buf0 + 0)@ ti2 = *(buf0 + 1)@
VLD2.I32 {d13, d15}, [r3]! @ tr2 = *(buf1 - 1)@ ti1 = *(buf1 + 0)@
VLD2.I32 {d12, d14}, [r3]! @ tr2 = *(buf1 - 1)@ ti1 = *(buf1 + 0)@
-
- VREV64.32 Q8, Q7
+
+ VREV64.32 Q8, Q7
VREV64.32 Q9, Q6
-
+
VQDMULH.S32 Q10, Q0, Q4 @ MULHIGH(cosa, tr1)
VQDMULH.S32 Q11, Q1, Q8 @ MULHIGH(sina, ti1)
VQDMULH.S32 Q12, Q0, Q8 @ MULHIGH(cosa, ti1)
VQDMULH.S32 Q13, Q1, Q4 @ MULHIGH(sina, tr1)
-
+
VADD.S32 Q0, Q10, Q11 @ *buf0++ = MULHIGH(cosa, tr1) + MULHIGH(sina, ti1)@
VSUB.S32 Q1, Q12, Q13 @ *buf0++ = MULHIGH(cosa, ti1) - MULHIGH(sina, tr1)@
-
+
VST2.I32 {d0, d1, d2, d3}, [r0]!
sub r3, r3, #32
-
+
VQDMULH.S32 Q10, Q2, Q9 @ MULHIGH(cosb, tr2)
VQDMULH.S32 Q11, Q3, Q5 @ MULHIGH(sinb, ti2)
VQDMULH.S32 Q12, Q2, Q5 @ MULHIGH(cosb, ti2)
VQDMULH.S32 Q13, Q3, Q9 @ MULHIGH(sinb, tr2)
-
+
VADD.S32 Q0, Q10, Q11 @ MULHIGH(cosa, tr2) + MULHIGH(sina, ti2)@
VSUB.S32 Q1, Q12, Q13 @ MULHIGH(cosa, ti2) - MULHIGH(sina, tr2)@
-
+
VREV64.32 Q3, Q1
VREV64.32 Q2, Q0
-
- VST2.I32 {d5, d7}, [r3]!
- VST2.I32 {d4, d6}, [r3]!
-
+
+ VST2.I32 {d5, d7}, [r3]!
+ VST2.I32 {d4, d6}, [r3]!
+
subs r1, r1, #4
- sub r3, r3, #64
+ sub r3, r3, #64
bne PreMDCT_LOOP
-
+
PreMDCT_END:
ldmia sp!, {r4 - r11, pc}
@ENDP @ |PreMDCT|
@@ -82,50 +82,50 @@
PostMDCT:
stmdb sp!, {r4 - r11, lr}
-
+
add r9, r0, r1, lsl #2
sub r3, r9, #32
movs r1, r1, asr #2
beq PostMDCT_END
-
+
PostMDCT_LOOP:
VLD4.I32 {d0, d2, d4, d6}, [r2]! @ cosa = *csptr++@ sina = *csptr++@
VLD4.I32 {d1, d3, d5, d7}, [r2]! @ cosb = *csptr++@ sinb = *csptr++@
VLD2.I32 {d8, d9, d10, d11}, [r0] @ tr1 = *(zbuf1 + 0)@ ti1 = *(zbuf1 + 1)@
VLD2.I32 {d13, d15}, [r3]! @ tr2 = *(zbuf2 - 1)@ ti2 = *(zbuf2 + 0)@
- VLD2.I32 {d12, d14}, [r3]! @ tr2 = *(zbuf2 - 1)@ ti2 = *(zbuf2 + 0)@
+ VLD2.I32 {d12, d14}, [r3]! @ tr2 = *(zbuf2 - 1)@ ti2 = *(zbuf2 + 0)@
- VREV64.32 Q8, Q6
- VREV64.32 Q9, Q7
-
+ VREV64.32 Q8, Q6
+ VREV64.32 Q9, Q7
+
VQDMULH.S32 Q10, Q0, Q4 @ MULHIGH(cosa, tr1)
VQDMULH.S32 Q11, Q1, Q5 @ MULHIGH(sina, ti1)
VQDMULH.S32 Q12, Q0, Q5 @ MULHIGH(cosa, ti1)
VQDMULH.S32 Q13, Q1, Q4 @ MULHIGH(sina, tr1)
-
+
VADD.S32 Q0, Q10, Q11 @ *buf0++ = MULHIGH(cosa, tr1) + MULHIGH(sina, ti1)@
VSUB.S32 Q5, Q13, Q12 @ *buf1-- = MULHIGH(sina, tr1) - MULHIGH(cosa, ti1)@
-
+
VQDMULH.S32 Q10, Q2, Q8 @ MULHIGH(cosb, tr2)
VQDMULH.S32 Q11, Q3, Q9 @ MULHIGH(sinb, ti2)
VQDMULH.S32 Q12, Q2, Q9 @ MULHIGH(cosb, ti2)
VQDMULH.S32 Q13, Q3, Q8 @ MULHIGH(sinb, tr2)
-
+
VADD.S32 Q4, Q10, Q11 @ *buf1-- = MULHIGH(cosa, tr2) + MULHIGH(sina, ti2)@
- VSUB.S32 Q1, Q13, Q12 @ *buf0++ = MULHIGH(sina, tr2) - MULHIGH(cosa, ti2)@
-
+ VSUB.S32 Q1, Q13, Q12 @ *buf0++ = MULHIGH(sina, tr2) - MULHIGH(cosa, ti2)@
+
VREV64.32 Q2, Q4
- VREV64.32 Q3, Q5
-
- sub r3, r3, #32
+ VREV64.32 Q3, Q5
+
+ sub r3, r3, #32
VST2.I32 {d0, d1, d2, d3}, [r0]!
-
- VST2.I32 {d5, d7}, [r3]!
- VST2.I32 {d4, d6}, [r3]!
-
+
+ VST2.I32 {d5, d7}, [r3]!
+ VST2.I32 {d4, d6}, [r3]!
+
subs r1, r1, #4
- sub r3, r3, #64
+ sub r3, r3, #64
bne PostMDCT_LOOP
PostMDCT_END:
diff --git a/media/libstagefright/codecs/aacenc/src/asm/ARMV7/R4R8First_v7.s b/media/libstagefright/codecs/aacenc/src/asm/ARMV7/R4R8First_v7.s
index 7fc5520..defd45d 100644
--- a/media/libstagefright/codecs/aacenc/src/asm/ARMV7/R4R8First_v7.s
+++ b/media/libstagefright/codecs/aacenc/src/asm/ARMV7/R4R8First_v7.s
@@ -29,86 +29,86 @@
ldr r3, SQRT1_2
cmp r1, #0
-
- VDUP.I32 Q15, r3
+
+ VDUP.I32 Q15, r3
beq Radix8First_END
-
+
Radix8First_LOOP:
VLD1.I32 {d0, d1, d2, d3}, [r0]!
VLD1.I32 {d8, d9, d10, d11}, [r0]!
-
+
VADD.S32 d4, d0, d1 @ r0 = buf[0] + buf[2]@i0 = buf[1] + buf[3]@
- VSUB.S32 d5, d0, d1 @ r1 = buf[0] - buf[2]@i1 = buf[1] - buf[3]@
- VSUB.S32 d7, d2, d3 @ r2 = buf[4] - buf[6]@i2 = buf[5] - buf[7]@
+ VSUB.S32 d5, d0, d1 @ r1 = buf[0] - buf[2]@i1 = buf[1] - buf[3]@
+ VSUB.S32 d7, d2, d3 @ r2 = buf[4] - buf[6]@i2 = buf[5] - buf[7]@
VADD.S32 d6, d2, d3 @ r3 = buf[4] + buf[6]@i3 = buf[5] + buf[7]@
- VREV64.I32 d7, d7
-
+ VREV64.I32 d7, d7
+
VADD.S32 Q0, Q2, Q3 @ r4 = (r0 + r2)@i4 = (i0 + i2)@i6 = (i1 + r3)@r7 = (r1 + i3)
VSUB.S32 Q1, Q2, Q3 @ r5 = (r0 - r2)@i5 = (i0 - i2)@r6 = (r1 - i3)@i7 = (i1 - r3)@
- VREV64.I32 d3, d3
+ VREV64.I32 d3, d3
VADD.S32 d4, d8, d9 @ r0 = buf[ 8] + buf[10]@i0 = buf[ 9] + buf[11]@
- VSUB.S32 d7, d10, d11 @ r1 = buf[12] - buf[14]@i1 = buf[13] - buf[15]@
+ VSUB.S32 d7, d10, d11 @ r1 = buf[12] - buf[14]@i1 = buf[13] - buf[15]@
VADD.S32 d6, d10, d11 @ r2 = buf[12] + buf[14]@i2 = buf[13] + buf[15]@
- VREV64.I32 d7, d7
+ VREV64.I32 d7, d7
VSUB.S32 d5, d8, d9 @ r3 = buf[ 8] - buf[10]@i3 = buf[ 9] - buf[11]@
-
- VTRN.32 d1, d3
-
+
+ VTRN.32 d1, d3
+
VADD.S32 Q4, Q2, Q3 @ t0 = (r0 + r2) >> 1@t1 = (i0 + i2) >> 1@i0 = i1 + r3@r2 = r1 + i3@
VSUB.S32 Q5, Q2, Q3 @ t2 = (r0 - r2) >> 1@t3 = (i0 - i2) >> 1@r0 = r1 - i3@i2 = i1 - r3@
-
+
VREV64.I32 d3, d3
-
- VSHR.S32 d8, d8, #1
+
+ VSHR.S32 d8, d8, #1
VSHR.S32 Q0, Q0, #1
VREV64.I32 d10, d10
VTRN.32 d11, d9
VSHR.S32 Q1, Q1, #1
VSHR.S32 d10, d10, #1
VREV64.I32 d9, d9
-
+
sub r0, r0, #0x40
-
+
VADD.S32 d12, d0, d8
- VSUB.S32 d16, d0, d8
+ VSUB.S32 d16, d0, d8
VADD.S32 d14, d2, d10
VSUB.S32 d18, d2, d10
-
+
VSUB.S32 d4, d11, d9
VADD.S32 d5, d11, d9
-
+
VREV64.I32 d18, d18
-
+
VQDMULH.S32 Q3, Q2, Q15
VTRN.32 d14, d18
VTRN.32 d6, d7
- VREV64.I32 d18, d18
-
+ VREV64.I32 d18, d18
+
VSUB.S32 d15, d3, d6
VREV64.I32 d7, d7
VADD.S32 d19, d3, d6
VADD.S32 d13, d1, d7
VSUB.S32 d17, d1, d7
-
+
VREV64.I32 d17, d17
VTRN.32 d13, d17
VREV64.I32 d17, d17
-
- subs r1, r1, #1
-
+
+ subs r1, r1, #1
+
VST1.I32 {d12, d13, d14, d15}, [r0]!
- VST1.I32 {d16, d17, d18, d19}, [r0]!
+ VST1.I32 {d16, d17, d18, d19}, [r0]!
bne Radix8First_LOOP
-
+
Radix8First_END:
- ldmia sp!, {r4 - r11, pc}
+ ldmia sp!, {r4 - r11, pc}
SQRT1_2:
.word 0x2d413ccd
-
+
@ENDP @ |Radix8First|
-
+
.section .text
.global Radix4First
@@ -117,28 +117,28 @@
cmp r1, #0
beq Radix4First_END
-
+
Radix4First_LOOP:
- VLD1.I32 {d0, d1, d2, d3}, [r0]
-
- VADD.S32 d4, d0, d1 @ r0 = buf[0] + buf[2]@ r1 = buf[1] + buf[3]@
+ VLD1.I32 {d0, d1, d2, d3}, [r0]
+
+ VADD.S32 d4, d0, d1 @ r0 = buf[0] + buf[2]@ r1 = buf[1] + buf[3]@
VSUB.S32 d5, d0, d1 @ r2 = buf[0] - buf[2]@ r3 = buf[1] - buf[3]@
VSUB.S32 d7, d2, d3 @ r4 = buf[4] + buf[6]@ r5 = buf[5] + buf[7]@
VADD.S32 d6, d2, d3 @ r6 = buf[4] - buf[6]@ r7 = buf[5] - buf[7]@
-
- VREV64.I32 d7, d7 @
-
+
+ VREV64.I32 d7, d7 @
+
VADD.S32 Q4, Q2, Q3
VSUB.S32 Q5, Q2, Q3
-
+
VREV64.I32 d11, d11
VTRN.32 d9, d11
- subs r1, r1, #1
+ subs r1, r1, #1
VREV64.I32 d11, d11
VST1.I32 {d8, d9, d10, d11}, [r0]!
bne Radix4First_LOOP
-
+
Radix4First_END:
ldmia sp!, {r4 - r11, pc}
diff --git a/media/libstagefright/codecs/aacenc/src/asm/ARMV7/Radix4FFT_v7.s b/media/libstagefright/codecs/aacenc/src/asm/ARMV7/Radix4FFT_v7.s
index b8655ae..84a4a80 100644
--- a/media/libstagefright/codecs/aacenc/src/asm/ARMV7/Radix4FFT_v7.s
+++ b/media/libstagefright/codecs/aacenc/src/asm/ARMV7/Radix4FFT_v7.s
@@ -28,116 +28,116 @@
stmdb sp!, {r4 - r11, lr}
mov r1, r1, asr #2
- cmp r1, #0
- beq Radix4FFT_END
-
-Radix4FFT_LOOP1:
- mov r5, r2, lsl #1
- mov r8, r0
- mov r7, r1
- mov r5, r5, lsl #2
- cmp r1, #0
- rsbeq r12, r5, r5, lsl #2
- beq Radix4FFT_LOOP1_END
-
- rsb r12, r5, r5, lsl #2
-
-Radix4FFT_LOOP2:
- mov r6, r3
- mov r4, r2
- cmp r2, #0
- beq Radix4FFT_LOOP2_END
-
-Radix4FFT_LOOP3:
+ cmp r1, #0
+ beq Radix4FFT_END
+
+Radix4FFT_LOOP1:
+ mov r5, r2, lsl #1
+ mov r8, r0
+ mov r7, r1
+ mov r5, r5, lsl #2
+ cmp r1, #0
+ rsbeq r12, r5, r5, lsl #2
+ beq Radix4FFT_LOOP1_END
+
+ rsb r12, r5, r5, lsl #2
+
+Radix4FFT_LOOP2:
+ mov r6, r3
+ mov r4, r2
+ cmp r2, #0
+ beq Radix4FFT_LOOP2_END
+
+Radix4FFT_LOOP3:
@r0 = xptr[0]@
@r1 = xptr[1]@
- VLD2.I32 {D0, D1, D2, D3}, [r8]
+ VLD2.I32 {D0, D1, D2, D3}, [r8]
VLD2.I32 {D28, D29, D30, D31}, [r6]! @ cosx = csptr[0]@ sinx = csptr[1]@
-
- add r8, r8, r5 @ xptr += step@
+
+ add r8, r8, r5 @ xptr += step@
VLD2.I32 {D4, D5, D6,D7}, [r8] @ r2 = xptr[0]@ r3 = xptr[1]@
-
+
VQDMULH.S32 Q10, Q2, Q14 @ MULHIGH(cosx, t0)
VQDMULH.S32 Q11, Q3, Q15 @ MULHIGH(sinx, t1)
VQDMULH.S32 Q12, Q3, Q14 @ MULHIGH(cosx, t1)
VQDMULH.S32 Q13, Q2, Q15 @ MULHIGH(sinx, t0)
-
+
VADD.S32 Q2, Q10, Q11 @ MULHIGH(cosx, t0) + MULHIGH(sinx, t1)
VSUB.S32 Q3, Q12, Q13 @ MULHIGH(cosx, t1) - MULHIGH(sinx, t0)
-
+
add r8, r8, r5 @ xptr += step@
VSHR.S32 Q10, Q0, #2 @ t0 = r0 >> 2@
VSHR.S32 Q11, Q1, #2 @ t1 = r1 >> 2@
-
+
VSUB.S32 Q0, Q10, Q2 @ r0 = t0 - r2@
VSUB.S32 Q1, Q11, Q3 @ r1 = t1 - r3@
VADD.S32 Q2, Q10, Q2 @ r2 = t0 + r2@
VADD.S32 Q3, Q11, Q3 @ r3 = t1 + r3@
-
- VLD2.I32 {D8, D9, D10, D11}, [r8]
- VLD2.I32 {D28, D29, D30, D31}, [r6]!
+
+ VLD2.I32 {D8, D9, D10, D11}, [r8]
+ VLD2.I32 {D28, D29, D30, D31}, [r6]!
add r8, r8, r5
VQDMULH.S32 Q10, Q4, Q14 @ MULHIGH(cosx, t0)
VQDMULH.S32 Q11, Q5, Q15 @ MULHIGH(sinx, t1)
VQDMULH.S32 Q12, Q5, Q14 @ MULHIGH(cosx, t1)
VQDMULH.S32 Q13, Q4, Q15 @ MULHIGH(sinx, t0)
-
+
VADD.S32 Q8, Q10, Q11 @ MULHIGH(cosx, t0) + MULHIGH(sinx, t1)
- VSUB.S32 Q9, Q12, Q13 @ MULHIGH(cosx, t1) - MULHIGH(sinx, t0)
-
- VLD2.I32 {D12, D13, D14, D15}, [r8]
+ VSUB.S32 Q9, Q12, Q13 @ MULHIGH(cosx, t1) - MULHIGH(sinx, t0)
+
+ VLD2.I32 {D12, D13, D14, D15}, [r8]
VLD2.I32 {D28, D29, D30, D31}, [r6]!
-
+
VQDMULH.S32 Q10, Q6, Q14 @ MULHIGH(cosx, t0)
VQDMULH.S32 Q11, Q7, Q15 @ MULHIGH(sinx, t1)
VQDMULH.S32 Q12, Q7, Q14 @ MULHIGH(cosx, t1)
VQDMULH.S32 Q13, Q6, Q15 @ MULHIGH(sinx, t0)
-
+
VADD.S32 Q6, Q10, Q11 @ MULHIGH(cosx, t0) + MULHIGH(sinx, t1)
- VSUB.S32 Q7, Q12, Q13 @ MULHIGH(cosx, t1) - MULHIGH(sinx, t0)
-
+ VSUB.S32 Q7, Q12, Q13 @ MULHIGH(cosx, t1) - MULHIGH(sinx, t0)
+
VADD.S32 Q4, Q8, Q6 @ r4 = t0 + r6@
VSUB.S32 Q5, Q7, Q9 @ r5 = r7 - t1@
VSUB.S32 Q6, Q8, Q6 @ r6 = t0 - r6@
VADD.S32 Q7, Q7, Q9 @ r7 = r7 + t1@
-
+
VADD.S32 Q8, Q0, Q5 @ xptr[0] = r0 + r5@
VADD.S32 Q9, Q1, Q6 @ xptr[1] = r1 + r6@
VST2.I32 {D16, D17, D18, D19}, [r8]
-
+
VSUB.S32 Q10, Q2, Q4 @ xptr[0] = r2 - r4@
sub r8, r8, r5 @ xptr -= step@
VSUB.S32 Q11, Q3, Q7 @ xptr[1] = r3 - r7@
VST2.I32 {D20, D21, D22, D23}, [r8]
-
+
VSUB.S32 Q8, Q0, Q5 @ xptr[0] = r0 - r5@
sub r8, r8, r5 @ xptr -= step@
VSUB.S32 Q9, Q1, Q6 @ xptr[1] = r1 - r6@
VST2.I32 {D16, D17, D18, D19}, [r8]
-
+
VADD.S32 Q10, Q2, Q4 @ xptr[0] = r2 + r4@
sub r8, r8, r5 @ xptr -= step@
VADD.S32 Q11, Q3, Q7 @ xptr[1] = r3 + r7@
VST2.I32 {D20, D21, D22, D23}, [r8]!
-
- subs r4, r4, #4
- bne Radix4FFT_LOOP3
-
-Radix4FFT_LOOP2_END:
- add r8, r8, r12
- sub r7, r7, #1
+
+ subs r4, r4, #4
+ bne Radix4FFT_LOOP3
+
+Radix4FFT_LOOP2_END:
+ add r8, r8, r12
+ sub r7, r7, #1
cmp r7, #0
- bhi Radix4FFT_LOOP2
-
-Radix4FFT_LOOP1_END:
- add r3, r12, r3
- mov r2, r2, lsl #2
- movs r1, r1, asr #2
- bne Radix4FFT_LOOP1
-
-Radix4FFT_END:
+ bhi Radix4FFT_LOOP2
+
+Radix4FFT_LOOP1_END:
+ add r3, r12, r3
+ mov r2, r2, lsl #2
+ movs r1, r1, asr #2
+ bne Radix4FFT_LOOP1
+
+Radix4FFT_END:
ldmia sp!, {r4 - r11, pc}
-
+
@ENDP @ |Radix4FFT|
.end
\ No newline at end of file
diff --git a/media/libstagefright/codecs/aacenc/src/band_nrg.c b/media/libstagefright/codecs/aacenc/src/band_nrg.c
index 7501af1..89c39b6 100644
--- a/media/libstagefright/codecs/aacenc/src/band_nrg.c
+++ b/media/libstagefright/codecs/aacenc/src/band_nrg.c
@@ -37,18 +37,18 @@
Word32 *bandEnergySum)
{
Word32 i, j;
- Word32 accuSum = 0;
+ Word32 accuSum = 0;
for (i=0; i<numBands; i++) {
- Word32 accu = 0;
+ Word32 accu = 0;
for (j=bandOffset[i]; j<bandOffset[i+1]; j++)
accu = L_add(accu, MULHIGH(mdctSpectrum[j], mdctSpectrum[j]));
accu = L_add(accu, accu);
accuSum = L_add(accuSum, accu);
- bandEnergy[i] = accu;
+ bandEnergy[i] = accu;
}
- *bandEnergySum = accuSum;
+ *bandEnergySum = accuSum;
}
/********************************************************************************
@@ -68,15 +68,15 @@
{
Word32 i, j;
- Word32 accuMidSum = 0;
- Word32 accuSideSum = 0;
-
+ Word32 accuMidSum = 0;
+ Word32 accuSideSum = 0;
+
for(i=0; i<numBands; i++) {
Word32 accuMid = 0;
- Word32 accuSide = 0;
+ Word32 accuSide = 0;
for (j=bandOffset[i]; j<bandOffset[i+1]; j++) {
- Word32 specm, specs;
+ Word32 specm, specs;
Word32 l, r;
l = mdctSpectrumLeft[j] >> 1;
@@ -86,17 +86,17 @@
accuMid = L_add(accuMid, MULHIGH(specm, specm));
accuSide = L_add(accuSide, MULHIGH(specs, specs));
}
-
+
accuMid = L_add(accuMid, accuMid);
accuSide = L_add(accuSide, accuSide);
- bandEnergyMid[i] = accuMid;
+ bandEnergyMid[i] = accuMid;
accuMidSum = L_add(accuMidSum, accuMid);
- bandEnergySide[i] = accuSide;
+ bandEnergySide[i] = accuSide;
accuSideSum = L_add(accuSideSum, accuSide);
-
+
}
- *bandEnergyMidSum = accuMidSum;
- *bandEnergySideSum = accuSideSum;
+ *bandEnergyMidSum = accuMidSum;
+ *bandEnergySideSum = accuSideSum;
}
#endif
\ No newline at end of file
diff --git a/media/libstagefright/codecs/aacenc/src/bit_cnt.c b/media/libstagefright/codecs/aacenc/src/bit_cnt.c
index 9fe511c..8853efc 100644
--- a/media/libstagefright/codecs/aacenc/src/bit_cnt.c
+++ b/media/libstagefright/codecs/aacenc/src/bit_cnt.c
@@ -26,14 +26,14 @@
#define HI_LTAB(a) (a>>8)
#define LO_LTAB(a) (a & 0xff)
-#define EXPAND(a) ((((Word32)(a&0xff00)) << 8)|(Word32)(a&0xff))
+#define EXPAND(a) ((((Word32)(a&0xff00)) << 8)|(Word32)(a&0xff))
/*****************************************************************************
*
* function name: count1_2_3_4_5_6_7_8_9_10_11
-* description: counts tables 1-11
-* returns:
+* description: counts tables 1-11
+* returns:
* input: quantized spectrum
* output: bitCount for tables 1-11
*
@@ -46,51 +46,51 @@
Word32 t0,t1,t2,t3,i;
Word32 bc1_2,bc3_4,bc5_6,bc7_8,bc9_10;
Word16 bc11,sc;
-
- bc1_2=0;
- bc3_4=0;
- bc5_6=0;
- bc7_8=0;
- bc9_10=0;
- bc11=0;
- sc=0;
+
+ bc1_2=0;
+ bc3_4=0;
+ bc5_6=0;
+ bc7_8=0;
+ bc9_10=0;
+ bc11=0;
+ sc=0;
for(i=0;i<width;i+=4){
-
- t0= values[i+0];
- t1= values[i+1];
- t2= values[i+2];
- t3= values[i+3];
-
+
+ t0= values[i+0];
+ t1= values[i+1];
+ t2= values[i+2];
+ t3= values[i+3];
+
/* 1,2 */
- bc1_2 = bc1_2 + EXPAND(huff_ltab1_2[t0+1][t1+1][t2+1][t3+1]);
+ bc1_2 = bc1_2 + EXPAND(huff_ltab1_2[t0+1][t1+1][t2+1][t3+1]);
/* 5,6 */
- bc5_6 = bc5_6 + EXPAND(huff_ltab5_6[t0+4][t1+4]);
- bc5_6 = bc5_6 + EXPAND(huff_ltab5_6[t2+4][t3+4]);
+ bc5_6 = bc5_6 + EXPAND(huff_ltab5_6[t0+4][t1+4]);
+ bc5_6 = bc5_6 + EXPAND(huff_ltab5_6[t2+4][t3+4]);
t0=ABS(t0);
t1=ABS(t1);
t2=ABS(t2);
t3=ABS(t3);
-
- bc3_4 = bc3_4 + EXPAND(huff_ltab3_4[t0][t1][t2][t3]);
-
- bc7_8 = bc7_8 + EXPAND(huff_ltab7_8[t0][t1]);
- bc7_8 = bc7_8 + EXPAND(huff_ltab7_8[t2][t3]);
-
- bc9_10 = bc9_10 + EXPAND(huff_ltab9_10[t0][t1]);
- bc9_10 = bc9_10 + EXPAND(huff_ltab9_10[t2][t3]);
-
+
+ bc3_4 = bc3_4 + EXPAND(huff_ltab3_4[t0][t1][t2][t3]);
+
+ bc7_8 = bc7_8 + EXPAND(huff_ltab7_8[t0][t1]);
+ bc7_8 = bc7_8 + EXPAND(huff_ltab7_8[t2][t3]);
+
+ bc9_10 = bc9_10 + EXPAND(huff_ltab9_10[t0][t1]);
+ bc9_10 = bc9_10 + EXPAND(huff_ltab9_10[t2][t3]);
+
bc11 = bc11 + huff_ltab11[t0][t1];
bc11 = bc11 + huff_ltab11[t2][t3];
-
-
+
+
sc = sc + (t0>0) + (t1>0) + (t2>0) + (t3>0);
}
-
+
bitCount[1]=extract_h(bc1_2);
bitCount[2]=extract_l(bc1_2);
bitCount[3]=extract_h(bc3_4) + sc;
@@ -108,8 +108,8 @@
/*****************************************************************************
*
* function name: count3_4_5_6_7_8_9_10_11
-* description: counts tables 3-11
-* returns:
+* description: counts tables 3-11
+* returns:
* input: quantized spectrum
* output: bitCount for tables 3-11
*
@@ -122,26 +122,26 @@
Word32 t0,t1,t2,t3, i;
Word32 bc3_4,bc5_6,bc7_8,bc9_10;
Word16 bc11,sc;
-
- bc3_4=0;
- bc5_6=0;
- bc7_8=0;
- bc9_10=0;
- bc11=0;
- sc=0;
+
+ bc3_4=0;
+ bc5_6=0;
+ bc7_8=0;
+ bc9_10=0;
+ bc11=0;
+ sc=0;
for(i=0;i<width;i+=4){
- t0= values[i+0];
- t1= values[i+1];
- t2= values[i+2];
- t3= values[i+3];
-
+ t0= values[i+0];
+ t1= values[i+1];
+ t2= values[i+2];
+ t3= values[i+3];
+
/*
5,6
*/
- bc5_6 = bc5_6 + EXPAND(huff_ltab5_6[t0+4][t1+4]);
- bc5_6 = bc5_6 + EXPAND(huff_ltab5_6[t2+4][t3+4]);
+ bc5_6 = bc5_6 + EXPAND(huff_ltab5_6[t0+4][t1+4]);
+ bc5_6 = bc5_6 + EXPAND(huff_ltab5_6[t2+4][t3+4]);
t0=ABS(t0);
t1=ABS(t1);
@@ -149,23 +149,23 @@
t3=ABS(t3);
- bc3_4 = bc3_4 + EXPAND(huff_ltab3_4[t0][t1][t2][t3]);
-
- bc7_8 = bc7_8 + EXPAND(huff_ltab7_8[t0][t1]);
- bc7_8 = bc7_8 + EXPAND(huff_ltab7_8[t2][t3]);
-
- bc9_10 = bc9_10 + EXPAND(huff_ltab9_10[t0][t1]);
- bc9_10 = bc9_10 + EXPAND(huff_ltab9_10[t2][t3]);
-
+ bc3_4 = bc3_4 + EXPAND(huff_ltab3_4[t0][t1][t2][t3]);
+
+ bc7_8 = bc7_8 + EXPAND(huff_ltab7_8[t0][t1]);
+ bc7_8 = bc7_8 + EXPAND(huff_ltab7_8[t2][t3]);
+
+ bc9_10 = bc9_10 + EXPAND(huff_ltab9_10[t0][t1]);
+ bc9_10 = bc9_10 + EXPAND(huff_ltab9_10[t2][t3]);
+
bc11 = bc11 + huff_ltab11[t0][t1];
bc11 = bc11 + huff_ltab11[t2][t3];
-
- sc = sc + (t0>0) + (t1>0) + (t2>0) + (t3>0);
+
+ sc = sc + (t0>0) + (t1>0) + (t2>0) + (t3>0);
}
-
- bitCount[1]=INVALID_BITCOUNT;
- bitCount[2]=INVALID_BITCOUNT;
+
+ bitCount[1]=INVALID_BITCOUNT;
+ bitCount[2]=INVALID_BITCOUNT;
bitCount[3]=extract_h(bc3_4) + sc;
bitCount[4]=extract_l(bc3_4) + sc;
bitCount[5]=extract_h(bc5_6);
@@ -175,7 +175,7 @@
bitCount[9]=extract_h(bc9_10) + sc;
bitCount[10]=extract_l(bc9_10) + sc;
bitCount[11]=bc11 + sc;
-
+
}
@@ -183,8 +183,8 @@
/*****************************************************************************
*
* function name: count5_6_7_8_9_10_11
-* description: counts tables 5-11
-* returns:
+* description: counts tables 5-11
+* returns:
* input: quantized spectrum
* output: bitCount for tables 5-11
*
@@ -198,33 +198,33 @@
Word32 bc5_6,bc7_8,bc9_10;
Word16 bc11,sc;
- bc5_6=0;
- bc7_8=0;
- bc9_10=0;
- bc11=0;
- sc=0;
+ bc5_6=0;
+ bc7_8=0;
+ bc9_10=0;
+ bc11=0;
+ sc=0;
for(i=0;i<width;i+=2){
- t0 = values[i+0];
- t1 = values[i+1];
+ t0 = values[i+0];
+ t1 = values[i+1];
- bc5_6 = bc5_6 + EXPAND(huff_ltab5_6[t0+4][t1+4]);
+ bc5_6 = bc5_6 + EXPAND(huff_ltab5_6[t0+4][t1+4]);
t0=ABS(t0);
t1=ABS(t1);
-
- bc7_8 = bc7_8 + EXPAND(huff_ltab7_8[t0][t1]);
- bc9_10 = bc9_10 + EXPAND(huff_ltab9_10[t0][t1]);
+
+ bc7_8 = bc7_8 + EXPAND(huff_ltab7_8[t0][t1]);
+ bc9_10 = bc9_10 + EXPAND(huff_ltab9_10[t0][t1]);
bc11 = bc11 + huff_ltab11[t0][t1];
-
-
+
+
sc = sc + (t0>0) + (t1>0);
}
- bitCount[1]=INVALID_BITCOUNT;
- bitCount[2]=INVALID_BITCOUNT;
- bitCount[3]=INVALID_BITCOUNT;
- bitCount[4]=INVALID_BITCOUNT;
+ bitCount[1]=INVALID_BITCOUNT;
+ bitCount[2]=INVALID_BITCOUNT;
+ bitCount[3]=INVALID_BITCOUNT;
+ bitCount[4]=INVALID_BITCOUNT;
bitCount[5]=extract_h(bc5_6);
bitCount[6]=extract_l(bc5_6);
bitCount[7]=extract_h(bc7_8) + sc;
@@ -232,15 +232,15 @@
bitCount[9]=extract_h(bc9_10) + sc;
bitCount[10]=extract_l(bc9_10) + sc;
bitCount[11]=bc11 + sc;
-
+
}
/*****************************************************************************
*
* function name: count7_8_9_10_11
-* description: counts tables 7-11
-* returns:
+* description: counts tables 7-11
+* returns:
* input: quantized spectrum
* output: bitCount for tables 7-11
*
@@ -253,43 +253,43 @@
Word32 t0,t1, i;
Word32 bc7_8,bc9_10;
Word16 bc11,sc;
-
- bc7_8=0;
- bc9_10=0;
- bc11=0;
- sc=0;
+
+ bc7_8=0;
+ bc9_10=0;
+ bc11=0;
+ sc=0;
for(i=0;i<width;i+=2){
t0=ABS(values[i+0]);
t1=ABS(values[i+1]);
- bc7_8 = bc7_8 + EXPAND(huff_ltab7_8[t0][t1]);
- bc9_10 = bc9_10 + EXPAND(huff_ltab9_10[t0][t1]);
+ bc7_8 = bc7_8 + EXPAND(huff_ltab7_8[t0][t1]);
+ bc9_10 = bc9_10 + EXPAND(huff_ltab9_10[t0][t1]);
bc11 = bc11 + huff_ltab11[t0][t1];
-
-
+
+
sc = sc + (t0>0) + (t1>0);
}
- bitCount[1]=INVALID_BITCOUNT;
- bitCount[2]=INVALID_BITCOUNT;
- bitCount[3]=INVALID_BITCOUNT;
- bitCount[4]=INVALID_BITCOUNT;
- bitCount[5]=INVALID_BITCOUNT;
- bitCount[6]=INVALID_BITCOUNT;
+ bitCount[1]=INVALID_BITCOUNT;
+ bitCount[2]=INVALID_BITCOUNT;
+ bitCount[3]=INVALID_BITCOUNT;
+ bitCount[4]=INVALID_BITCOUNT;
+ bitCount[5]=INVALID_BITCOUNT;
+ bitCount[6]=INVALID_BITCOUNT;
bitCount[7]=extract_h(bc7_8) + sc;
bitCount[8]=extract_l(bc7_8) + sc;
bitCount[9]=extract_h(bc9_10) + sc;
bitCount[10]=extract_l(bc9_10) + sc;
bitCount[11]=bc11 + sc;
-
+
}
/*****************************************************************************
*
* function name: count9_10_11
-* description: counts tables 9-11
-* returns:
+* description: counts tables 9-11
+* returns:
* input: quantized spectrum
* output: bitCount for tables 9-11
*
@@ -299,45 +299,45 @@
Word16 *bitCount)
{
- Word32 t0,t1,i;
+ Word32 t0,t1,i;
Word32 bc9_10;
Word16 bc11,sc;
- bc9_10=0;
- bc11=0;
- sc=0;
+ bc9_10=0;
+ bc11=0;
+ sc=0;
for(i=0;i<width;i+=2){
t0=ABS(values[i+0]);
t1=ABS(values[i+1]);
+
-
- bc9_10 += EXPAND(huff_ltab9_10[t0][t1]);
+ bc9_10 += EXPAND(huff_ltab9_10[t0][t1]);
bc11 = bc11 + huff_ltab11[t0][t1];
-
+
sc = sc + (t0>0) + (t1>0);
}
- bitCount[1]=INVALID_BITCOUNT;
- bitCount[2]=INVALID_BITCOUNT;
- bitCount[3]=INVALID_BITCOUNT;
- bitCount[4]=INVALID_BITCOUNT;
- bitCount[5]=INVALID_BITCOUNT;
- bitCount[6]=INVALID_BITCOUNT;
- bitCount[7]=INVALID_BITCOUNT;
- bitCount[8]=INVALID_BITCOUNT;
+ bitCount[1]=INVALID_BITCOUNT;
+ bitCount[2]=INVALID_BITCOUNT;
+ bitCount[3]=INVALID_BITCOUNT;
+ bitCount[4]=INVALID_BITCOUNT;
+ bitCount[5]=INVALID_BITCOUNT;
+ bitCount[6]=INVALID_BITCOUNT;
+ bitCount[7]=INVALID_BITCOUNT;
+ bitCount[8]=INVALID_BITCOUNT;
bitCount[9]=extract_h(bc9_10) + sc;
bitCount[10]=extract_l(bc9_10) + sc;
bitCount[11]=bc11 + sc;
-
+
}
-
+
/*****************************************************************************
*
* function name: count11
-* description: counts table 11
-* returns:
+* description: counts table 11
+* returns:
* input: quantized spectrum
* output: bitCount for table 11
*
@@ -347,37 +347,37 @@
Word16 *bitCount)
{
Word32 t0,t1,i;
- Word16 bc11,sc;
+ Word16 bc11,sc;
- bc11=0;
- sc=0;
+ bc11=0;
+ sc=0;
for(i=0;i<width;i+=2){
t0=ABS(values[i+0]);
t1=ABS(values[i+1]);
bc11 = bc11 + huff_ltab11[t0][t1];
-
+
sc = sc + (t0>0) + (t1>0);
}
- bitCount[1]=INVALID_BITCOUNT;
- bitCount[2]=INVALID_BITCOUNT;
- bitCount[3]=INVALID_BITCOUNT;
- bitCount[4]=INVALID_BITCOUNT;
- bitCount[5]=INVALID_BITCOUNT;
- bitCount[6]=INVALID_BITCOUNT;
- bitCount[7]=INVALID_BITCOUNT;
- bitCount[8]=INVALID_BITCOUNT;
- bitCount[9]=INVALID_BITCOUNT;
- bitCount[10]=INVALID_BITCOUNT;
+ bitCount[1]=INVALID_BITCOUNT;
+ bitCount[2]=INVALID_BITCOUNT;
+ bitCount[3]=INVALID_BITCOUNT;
+ bitCount[4]=INVALID_BITCOUNT;
+ bitCount[5]=INVALID_BITCOUNT;
+ bitCount[6]=INVALID_BITCOUNT;
+ bitCount[7]=INVALID_BITCOUNT;
+ bitCount[8]=INVALID_BITCOUNT;
+ bitCount[9]=INVALID_BITCOUNT;
+ bitCount[10]=INVALID_BITCOUNT;
bitCount[11]=bc11 + sc;
}
/*****************************************************************************
*
* function name: countEsc
-* description: counts table 11 (with Esc)
-* returns:
+* description: counts table 11 (with Esc)
+* returns:
* input: quantized spectrum
* output: bitCount for tables 11 (with Esc)
*
@@ -388,31 +388,31 @@
Word16 *bitCount)
{
Word32 t0,t1,t00,t01,i;
- Word16 bc11,ec,sc;
+ Word16 bc11,ec,sc;
- bc11=0;
- sc=0;
- ec=0;
+ bc11=0;
+ sc=0;
+ ec=0;
for(i=0;i<width;i+=2){
t0=ABS(values[i+0]);
t1=ABS(values[i+1]);
-
-
+
+
sc = sc + (t0>0) + (t1>0);
t00 = min(t0,16);
t01 = min(t1,16);
bc11 = bc11 + huff_ltab11[t00][t01];
-
-
+
+
if(t0 >= 16){
ec = ec + 5;
while(sub(t0=(t0 >> 1), 16) >= 0) {
ec = ec + 2;
}
}
-
-
+
+
if(t1 >= 16){
ec = ec + 5;
while(sub(t1=(t1 >> 1), 16) >= 0) {
@@ -420,16 +420,16 @@
}
}
}
- bitCount[1]=INVALID_BITCOUNT;
- bitCount[2]=INVALID_BITCOUNT;
- bitCount[3]=INVALID_BITCOUNT;
- bitCount[4]=INVALID_BITCOUNT;
- bitCount[5]=INVALID_BITCOUNT;
- bitCount[6]=INVALID_BITCOUNT;
- bitCount[7]=INVALID_BITCOUNT;
- bitCount[8]=INVALID_BITCOUNT;
- bitCount[9]=INVALID_BITCOUNT;
- bitCount[10]=INVALID_BITCOUNT;
+ bitCount[1]=INVALID_BITCOUNT;
+ bitCount[2]=INVALID_BITCOUNT;
+ bitCount[3]=INVALID_BITCOUNT;
+ bitCount[4]=INVALID_BITCOUNT;
+ bitCount[5]=INVALID_BITCOUNT;
+ bitCount[6]=INVALID_BITCOUNT;
+ bitCount[7]=INVALID_BITCOUNT;
+ bitCount[8]=INVALID_BITCOUNT;
+ bitCount[9]=INVALID_BITCOUNT;
+ bitCount[10]=INVALID_BITCOUNT;
bitCount[11]=bc11 + sc + ec;
}
@@ -463,7 +463,7 @@
/*****************************************************************************
*
* function name: bitCount
-* description: count bits
+* description: count bits
*
*****************************************************************************/
Word16 bitCount(const Word16 *values,
@@ -474,7 +474,7 @@
/*
check if we can use codebook 0
*/
-
+
if(maxVal == 0)
bitCount[0] = 0;
else
@@ -489,7 +489,7 @@
/*****************************************************************************
*
* function name: codeValues
-* description: write huffum bits
+* description: write huffum bits
*
*****************************************************************************/
Word16 codeValues(Word16 *values, Word16 width, Word16 codeBook, HANDLE_BIT_BUF hBitstream)
@@ -499,85 +499,85 @@
UWord16 codeWord, codeLength;
Word16 sign, signLength;
-
+
switch (codeBook) {
case CODE_BOOK_ZERO_NO:
break;
case CODE_BOOK_1_NO:
for(i=0; i<width; i+=4) {
- t0 = values[i+0];
- t1 = values[i+1];
- t2 = values[i+2];
- t3 = values[i+3];
- codeWord = huff_ctab1[t0+1][t1+1][t2+1][t3+1];
- codeLength = HI_LTAB(huff_ltab1_2[t0+1][t1+1][t2+1][t3+1]);
- WriteBits(hBitstream, codeWord, codeLength);
+ t0 = values[i+0];
+ t1 = values[i+1];
+ t2 = values[i+2];
+ t3 = values[i+3];
+ codeWord = huff_ctab1[t0+1][t1+1][t2+1][t3+1];
+ codeLength = HI_LTAB(huff_ltab1_2[t0+1][t1+1][t2+1][t3+1]);
+ WriteBits(hBitstream, codeWord, codeLength);
}
break;
case CODE_BOOK_2_NO:
for(i=0; i<width; i+=4) {
- t0 = values[i+0];
- t1 = values[i+1];
- t2 = values[i+2];
- t3 = values[i+3];
- codeWord = huff_ctab2[t0+1][t1+1][t2+1][t3+1];
- codeLength = LO_LTAB(huff_ltab1_2[t0+1][t1+1][t2+1][t3+1]);
+ t0 = values[i+0];
+ t1 = values[i+1];
+ t2 = values[i+2];
+ t3 = values[i+3];
+ codeWord = huff_ctab2[t0+1][t1+1][t2+1][t3+1];
+ codeLength = LO_LTAB(huff_ltab1_2[t0+1][t1+1][t2+1][t3+1]);
WriteBits(hBitstream,codeWord,codeLength);
}
break;
case CODE_BOOK_3_NO:
for(i=0; i<width; i+=4) {
- sign=0;
- signLength=0;
- t0 = values[i+0];
-
+ sign=0;
+ signLength=0;
+ t0 = values[i+0];
+
if(t0 != 0){
signLength = signLength + 1;
- sign = sign << 1;
-
+ sign = sign << 1;
+
if(t0 < 0){
- sign|=1;
+ sign|=1;
t0=-t0;
}
}
- t1 = values[i+1];
-
+ t1 = values[i+1];
+
if(t1 != 0){
signLength = signLength + 1;
- sign = sign << 1;
-
+ sign = sign << 1;
+
if(t1 < 0){
- sign|=1;
+ sign|=1;
t1=-t1;
}
}
- t2 = values[i+2];
-
+ t2 = values[i+2];
+
if(t2 != 0){
signLength = signLength + 1;
- sign = sign << 1;
-
+ sign = sign << 1;
+
if(t2 < 0){
- sign|=1;
+ sign|=1;
t2=-t2;
}
}
- t3 = values[i+3];
+ t3 = values[i+3];
if(t3 != 0){
signLength = signLength + 1;
- sign = sign << 1;
-
+ sign = sign << 1;
+
if(t3 < 0){
- sign|=1;
+ sign|=1;
t3=-t3;
}
}
- codeWord = huff_ctab3[t0][t1][t2][t3];
- codeLength = HI_LTAB(huff_ltab3_4[t0][t1][t2][t3]);
+ codeWord = huff_ctab3[t0][t1][t2][t3];
+ codeLength = HI_LTAB(huff_ltab3_4[t0][t1][t2][t3]);
WriteBits(hBitstream,codeWord,codeLength);
WriteBits(hBitstream,sign,signLength);
}
@@ -585,107 +585,107 @@
case CODE_BOOK_4_NO:
for(i=0; i<width; i+=4) {
- sign=0;
- signLength=0;
- t0 = values[i+0];
-
- if(t0 != 0){
+ sign=0;
+ signLength=0;
+ t0 = values[i+0];
+
+ if(t0 != 0){
signLength = signLength + 1;
- sign = sign << 1;
- if(t0 < 0){
- sign|=1;
- t0=-t0;
+ sign = sign << 1;
+ if(t0 < 0){
+ sign|=1;
+ t0=-t0;
}
- }
- t1 = values[i+1];
-
- if(t1 != 0){
+ }
+ t1 = values[i+1];
+
+ if(t1 != 0){
signLength = signLength + 1;
- sign = sign << 1;
-
- if(t1 < 0){
- sign|=1;
- t1=-t1;
- }
- }
- t2 = values[i+2];
-
- if(t2 != 0){
+ sign = sign << 1;
+
+ if(t1 < 0){
+ sign|=1;
+ t1=-t1;
+ }
+ }
+ t2 = values[i+2];
+
+ if(t2 != 0){
signLength = signLength + 1;
- sign = sign << 1;
-
- if(t2 < 0){
- sign|=1;
- t2=-t2;
- }
- }
- t3 = values[i+3];
-
- if(t3 != 0){
+ sign = sign << 1;
+
+ if(t2 < 0){
+ sign|=1;
+ t2=-t2;
+ }
+ }
+ t3 = values[i+3];
+
+ if(t3 != 0){
signLength = signLength + 1;
- sign = sign << 1;
-
- if(t3 < 0){
- sign|=1;
- t3=-t3;
- }
- }
- codeWord = huff_ctab4[t0][t1][t2][t3];
- codeLength = LO_LTAB(huff_ltab3_4[t0][t1][t2][t3]);
- WriteBits(hBitstream,codeWord,codeLength);
- WriteBits(hBitstream,sign,signLength);
- }
- break;
-
- case CODE_BOOK_5_NO:
- for(i=0; i<width; i+=2) {
- t0 = values[i+0];
- t1 = values[i+1];
- codeWord = huff_ctab5[t0+4][t1+4];
- codeLength = HI_LTAB(huff_ltab5_6[t0+4][t1+4]);
+ sign = sign << 1;
+
+ if(t3 < 0){
+ sign|=1;
+ t3=-t3;
+ }
+ }
+ codeWord = huff_ctab4[t0][t1][t2][t3];
+ codeLength = LO_LTAB(huff_ltab3_4[t0][t1][t2][t3]);
+ WriteBits(hBitstream,codeWord,codeLength);
+ WriteBits(hBitstream,sign,signLength);
+ }
+ break;
+
+ case CODE_BOOK_5_NO:
+ for(i=0; i<width; i+=2) {
+ t0 = values[i+0];
+ t1 = values[i+1];
+ codeWord = huff_ctab5[t0+4][t1+4];
+ codeLength = HI_LTAB(huff_ltab5_6[t0+4][t1+4]);
WriteBits(hBitstream,codeWord,codeLength);
}
break;
case CODE_BOOK_6_NO:
for(i=0; i<width; i+=2) {
- t0 = values[i+0];
- t1 = values[i+1];
- codeWord = huff_ctab6[t0+4][t1+4];
- codeLength = LO_LTAB(huff_ltab5_6[t0+4][t1+4]);
+ t0 = values[i+0];
+ t1 = values[i+1];
+ codeWord = huff_ctab6[t0+4][t1+4];
+ codeLength = LO_LTAB(huff_ltab5_6[t0+4][t1+4]);
WriteBits(hBitstream,codeWord,codeLength);
}
break;
case CODE_BOOK_7_NO:
for(i=0; i<width; i+=2){
- sign=0;
- signLength=0;
- t0 = values[i+0];
-
+ sign=0;
+ signLength=0;
+ t0 = values[i+0];
+
if(t0 != 0){
signLength = signLength + 1;
- sign = sign << 1;
-
+ sign = sign << 1;
+
if(t0 < 0){
- sign|=1;
+ sign|=1;
t0=-t0;
}
}
- t1 = values[i+1];
-
+ t1 = values[i+1];
+
if(t1 != 0){
signLength = signLength + 1;
- sign = sign << 1;
-
+ sign = sign << 1;
+
if(t1 < 0){
- sign|=1;
+ sign|=1;
t1=-t1;
}
}
- codeWord = huff_ctab7[t0][t1];
- codeLength = HI_LTAB(huff_ltab7_8[t0][t1]);
+ codeWord = huff_ctab7[t0][t1];
+ codeLength = HI_LTAB(huff_ltab7_8[t0][t1]);
WriteBits(hBitstream,codeWord,codeLength);
WriteBits(hBitstream,sign,signLength);
}
@@ -693,33 +693,33 @@
case CODE_BOOK_8_NO:
for(i=0; i<width; i+=2) {
- sign=0;
- signLength=0;
- t0 = values[i+0];
-
- if(t0 != 0){
- signLength = signLength + 1;
- sign = sign << 1;
-
- if(t0 < 0){
- sign|=1;
- t0=-t0;
- }
- }
-
- t1 = values[i+1];
-
- if(t1 != 0){
- signLength = signLength + 1;
- sign = sign << 1;
-
- if(t1 < 0){
- sign|=1;
- t1=-t1;
- }
- }
- codeWord = huff_ctab8[t0][t1];
- codeLength = LO_LTAB(huff_ltab7_8[t0][t1]);
+ sign=0;
+ signLength=0;
+ t0 = values[i+0];
+
+ if(t0 != 0){
+ signLength = signLength + 1;
+ sign = sign << 1;
+
+ if(t0 < 0){
+ sign|=1;
+ t0=-t0;
+ }
+ }
+
+ t1 = values[i+1];
+
+ if(t1 != 0){
+ signLength = signLength + 1;
+ sign = sign << 1;
+
+ if(t1 < 0){
+ sign|=1;
+ t1=-t1;
+ }
+ }
+ codeWord = huff_ctab8[t0][t1];
+ codeLength = LO_LTAB(huff_ltab7_8[t0][t1]);
WriteBits(hBitstream,codeWord,codeLength);
WriteBits(hBitstream,sign,signLength);
}
@@ -727,33 +727,33 @@
case CODE_BOOK_9_NO:
for(i=0; i<width; i+=2) {
- sign=0;
- signLength=0;
- t0 = values[i+0];
-
- if(t0 != 0){
- signLength = signLength + 1;
- sign = sign << 1;
-
- if(t0 < 0){
- sign|=1;
- t0=-t0;
- }
- }
-
- t1 = values[i+1];
-
- if(t1 != 0){
- signLength = signLength + 1;
- sign = sign << 1;
-
- if(t1 < 0){
- sign|=1;
- t1=-t1;
- }
- }
- codeWord = huff_ctab9[t0][t1];
- codeLength = HI_LTAB(huff_ltab9_10[t0][t1]);
+ sign=0;
+ signLength=0;
+ t0 = values[i+0];
+
+ if(t0 != 0){
+ signLength = signLength + 1;
+ sign = sign << 1;
+
+ if(t0 < 0){
+ sign|=1;
+ t0=-t0;
+ }
+ }
+
+ t1 = values[i+1];
+
+ if(t1 != 0){
+ signLength = signLength + 1;
+ sign = sign << 1;
+
+ if(t1 < 0){
+ sign|=1;
+ t1=-t1;
+ }
+ }
+ codeWord = huff_ctab9[t0][t1];
+ codeLength = HI_LTAB(huff_ltab9_10[t0][t1]);
WriteBits(hBitstream,codeWord,codeLength);
WriteBits(hBitstream,sign,signLength);
}
@@ -761,33 +761,33 @@
case CODE_BOOK_10_NO:
for(i=0; i<width; i+=2) {
- sign=0;
- signLength=0;
- t0 = values[i+0];
-
- if(t0 != 0){
- signLength = signLength + 1;
- sign = sign << 1;
-
- if(t0 < 0){
- sign|=1;
- t0=-t0;
- }
- }
-
- t1 = values[i+1];
-
- if(t1 != 0){
- signLength = signLength + 1;
- sign = sign << 1;
-
- if(t1 < 0){
- sign|=1;
- t1=-t1;
- }
- }
- codeWord = huff_ctab10[t0][t1];
- codeLength = LO_LTAB(huff_ltab9_10[t0][t1]);
+ sign=0;
+ signLength=0;
+ t0 = values[i+0];
+
+ if(t0 != 0){
+ signLength = signLength + 1;
+ sign = sign << 1;
+
+ if(t0 < 0){
+ sign|=1;
+ t0=-t0;
+ }
+ }
+
+ t1 = values[i+1];
+
+ if(t1 != 0){
+ signLength = signLength + 1;
+ sign = sign << 1;
+
+ if(t1 < 0){
+ sign|=1;
+ t1=-t1;
+ }
+ }
+ codeWord = huff_ctab10[t0][t1];
+ codeLength = LO_LTAB(huff_ltab9_10[t0][t1]);
WriteBits(hBitstream,codeWord,codeLength);
WriteBits(hBitstream,sign,signLength);
}
@@ -795,45 +795,45 @@
case CODE_BOOK_ESC_NO:
for(i=0; i<width; i+=2) {
- sign=0;
- signLength=0;
- t0 = values[i+0];
-
- if(t0 != 0){
- signLength = signLength + 1;
- sign = sign << 1;
-
- if(t0 < 0){
- sign|=1;
- t0=-t0;
- }
- }
-
- t1 = values[i+1];
-
- if(t1 != 0){
- signLength = signLength + 1;
- sign = sign << 1;
-
- if(t1 < 0){
- sign|=1;
- t1=-t1;
- }
- }
+ sign=0;
+ signLength=0;
+ t0 = values[i+0];
+
+ if(t0 != 0){
+ signLength = signLength + 1;
+ sign = sign << 1;
+
+ if(t0 < 0){
+ sign|=1;
+ t0=-t0;
+ }
+ }
+
+ t1 = values[i+1];
+
+ if(t1 != 0){
+ signLength = signLength + 1;
+ sign = sign << 1;
+
+ if(t1 < 0){
+ sign|=1;
+ t1=-t1;
+ }
+ }
t00 = min(t0,16);
t01 = min(t1,16);
- codeWord = huff_ctab11[t00][t01];
- codeLength = huff_ltab11[t00][t01];
+ codeWord = huff_ctab11[t00][t01];
+ codeLength = huff_ltab11[t00][t01];
WriteBits(hBitstream,codeWord,codeLength);
WriteBits(hBitstream,sign,signLength);
-
+
if(t0 >= 16){
Word16 n, p;
- n=0;
- p=t0;
+ n=0;
+ p=t0;
while(sub(p=(p >> 1), 16) >= 0){
-
+
WriteBits(hBitstream,1,1);
n = n + 1;
}
@@ -841,13 +841,13 @@
n = n + 4;
WriteBits(hBitstream,(t0 - (1 << n)),n);
}
-
+
if(t1 >= 16){
Word16 n, p;
- n=0;
- p=t1;
+ n=0;
+ p=t1;
while(sub(p=(p >> 1), 16) >= 0){
-
+
WriteBits(hBitstream,1,1);
n = n + 1;
}
@@ -871,15 +871,15 @@
Word16 codeScalefactorDelta(Word16 delta, HANDLE_BIT_BUF hBitstream)
{
- Word32 codeWord;
+ Word32 codeWord;
Word16 codeLength;
-
-
+
+
if(delta > CODE_BOOK_SCF_LAV || delta < -CODE_BOOK_SCF_LAV)
return(1);
-
- codeWord = huff_ctabscf[delta + CODE_BOOK_SCF_LAV];
- codeLength = huff_ltabscf[delta + CODE_BOOK_SCF_LAV];
+
+ codeWord = huff_ctabscf[delta + CODE_BOOK_SCF_LAV];
+ codeLength = huff_ltabscf[delta + CODE_BOOK_SCF_LAV];
WriteBits(hBitstream,codeWord,codeLength);
return(0);
}
diff --git a/media/libstagefright/codecs/aacenc/src/bitbuffer.c b/media/libstagefright/codecs/aacenc/src/bitbuffer.c
index 5615ac3..ef13c13 100644
--- a/media/libstagefright/codecs/aacenc/src/bitbuffer.c
+++ b/media/libstagefright/codecs/aacenc/src/bitbuffer.c
@@ -32,15 +32,15 @@
UWord8 **pBitBufWord,
Word16 cnt)
{
- *pBitBufWord += cnt;
+ *pBitBufWord += cnt;
-
+
if(*pBitBufWord > hBitBuf->pBitBufEnd) {
- *pBitBufWord -= (hBitBuf->pBitBufEnd - hBitBuf->pBitBufBase + 1);
+ *pBitBufWord -= (hBitBuf->pBitBufEnd - hBitBuf->pBitBufBase + 1);
}
-
+
if(*pBitBufWord < hBitBuf->pBitBufBase) {
- *pBitBufWord += (hBitBuf->pBitBufEnd - hBitBuf->pBitBufBase + 1);
+ *pBitBufWord += (hBitBuf->pBitBufEnd - hBitBuf->pBitBufBase + 1);
}
}
@@ -57,18 +57,18 @@
{
assert(bitBufSize*8 <= 32768);
- hBitBuf->pBitBufBase = pBitBufBase;
- hBitBuf->pBitBufEnd = pBitBufBase + bitBufSize - 1;
+ hBitBuf->pBitBufBase = pBitBufBase;
+ hBitBuf->pBitBufEnd = pBitBufBase + bitBufSize - 1;
- hBitBuf->pWriteNext = pBitBufBase;
+ hBitBuf->pWriteNext = pBitBufBase;
hBitBuf->cache = 0;
-
- hBitBuf->wBitPos = 0;
- hBitBuf->cntBits = 0;
-
- hBitBuf->size = (bitBufSize << 3);
- hBitBuf->isValid = 1;
+
+ hBitBuf->wBitPos = 0;
+ hBitBuf->cntBits = 0;
+
+ hBitBuf->size = (bitBufSize << 3);
+ hBitBuf->isValid = 1;
return hBitBuf;
}
@@ -82,8 +82,8 @@
void DeleteBitBuffer(HANDLE_BIT_BUF *hBitBuf)
{
if(*hBitBuf)
- (*hBitBuf)->isValid = 0;
- *hBitBuf = NULL;
+ (*hBitBuf)->isValid = 0;
+ *hBitBuf = NULL;
}
/*****************************************************************************
@@ -96,15 +96,15 @@
UWord8 *pBitBufBase,
Word16 bitBufSize)
{
- hBitBuf->pBitBufBase = pBitBufBase;
- hBitBuf->pBitBufEnd = pBitBufBase + bitBufSize - 1;
+ hBitBuf->pBitBufBase = pBitBufBase;
+ hBitBuf->pBitBufEnd = pBitBufBase + bitBufSize - 1;
+
+ hBitBuf->pWriteNext = pBitBufBase;
- hBitBuf->pWriteNext = pBitBufBase;
-
- hBitBuf->wBitPos = 0;
- hBitBuf->cntBits = 0;
-
+ hBitBuf->wBitPos = 0;
+ hBitBuf->cntBits = 0;
+
hBitBuf->cache = 0;
}
@@ -117,7 +117,7 @@
void CopyBitBuf(HANDLE_BIT_BUF hBitBufSrc,
HANDLE_BIT_BUF hBitBufDst)
{
- *hBitBufDst = *hBitBufSrc;
+ *hBitBufDst = *hBitBufSrc;
}
/*****************************************************************************
@@ -148,25 +148,25 @@
if(noBitsToWrite == 0)
return noBitsToWrite;
- hBitBuf->cntBits += noBitsToWrite;
+ hBitBuf->cntBits += noBitsToWrite;
wBitPos = hBitBuf->wBitPos;
wBitPos += noBitsToWrite;
- writeValue <<= 32 - wBitPos;
+ writeValue <<= 32 - wBitPos;
writeValue |= hBitBuf->cache;
-
- while (wBitPos >= 8)
+
+ while (wBitPos >= 8)
{
UWord8 tmp;
tmp = (UWord8)((writeValue >> 24) & 0xFF);
-
- *hBitBuf->pWriteNext++ = tmp;
+
+ *hBitBuf->pWriteNext++ = tmp;
writeValue <<= 8;
wBitPos -= 8;
}
-
+
hBitBuf->wBitPos = wBitPos;
hBitBuf->cache = writeValue;
-
+
return noBitsToWrite;
}
diff --git a/media/libstagefright/codecs/aacenc/src/bitenc.c b/media/libstagefright/codecs/aacenc/src/bitenc.c
index fcc12dd..ea34407 100644
--- a/media/libstagefright/codecs/aacenc/src/bitenc.c
+++ b/media/libstagefright/codecs/aacenc/src/bitenc.c
@@ -46,7 +46,7 @@
Word16 i,sfb;
Word16 dbgVal;
SECTION_INFO* psectioninfo;
- dbgVal = GetBitsAvail(hBitStream);
+ dbgVal = GetBitsAvail(hBitStream);
for(i=0; i<sectionData->noOfSections; i++) {
psectioninfo = &(sectionData->sectionInfo[i]);
@@ -100,7 +100,7 @@
WriteBits(hBitStream,blockType,2);
WriteBits(hBitStream,windowShape,1);
-
+
switch(blockType){
case LONG_WINDOW:
case START_WINDOW:
@@ -137,30 +137,30 @@
Word16 sectLen;
Word16 i;
Word16 dbgVal=GetBitsAvail(hBitStream);
+
-
-
+
switch(sectionData->blockType)
{
case LONG_WINDOW:
case START_WINDOW:
case STOP_WINDOW:
- sectEscapeVal = SECT_ESC_VAL_LONG;
- sectLenBits = SECT_BITS_LONG;
+ sectEscapeVal = SECT_ESC_VAL_LONG;
+ sectLenBits = SECT_BITS_LONG;
break;
case SHORT_WINDOW:
- sectEscapeVal = SECT_ESC_VAL_SHORT;
- sectLenBits = SECT_BITS_SHORT;
+ sectEscapeVal = SECT_ESC_VAL_SHORT;
+ sectLenBits = SECT_BITS_SHORT;
break;
}
for(i=0;i<sectionData->noOfSections;i++) {
WriteBits(hBitStream,sectionData->sectionInfo[i].codeBook,4);
- sectLen = sectionData->sectionInfo[i].sfbCnt;
+ sectLen = sectionData->sectionInfo[i].sfbCnt;
while(sectLen >= sectEscapeVal) {
-
+
WriteBits(hBitStream,sectEscapeVal,sectLenBits);
sectLen = sectLen - sectEscapeVal;
}
@@ -183,24 +183,24 @@
{
Word16 i,j,lastValScf,deltaScf;
Word16 dbgVal = GetBitsAvail(hBitStream);
- SECTION_INFO* psectioninfo;
+ SECTION_INFO* psectioninfo;
- lastValScf=scalefac[sectionData->firstScf];
+ lastValScf=scalefac[sectionData->firstScf];
for(i=0;i<sectionData->noOfSections;i++){
- psectioninfo = &(sectionData->sectionInfo[i]);
+ psectioninfo = &(sectionData->sectionInfo[i]);
if (psectioninfo->codeBook != CODE_BOOK_ZERO_NO){
for (j=psectioninfo->sfbStart;
j<psectioninfo->sfbStart+psectioninfo->sfbCnt; j++){
-
+
if(maxValueInSfb[j] == 0) {
- deltaScf = 0;
+ deltaScf = 0;
}
else {
deltaScf = lastValScf - scalefac[j];
- lastValScf = scalefac[j];
+ lastValScf = scalefac[j];
}
-
+
if(codeScalefactorDelta(deltaScf,hBitStream)){
return(1);
}
@@ -227,7 +227,7 @@
{
Word16 sfb, sfbOff;
-
+
switch(msDigest)
{
case MS_NONE:
@@ -242,7 +242,7 @@
WriteBits(hBitStream,SI_MS_MASK_SOME,2);
for(sfbOff = 0; sfbOff < sfbCnt; sfbOff+=grpSfb) {
for(sfb=0; sfb<maxSfb; sfb++) {
-
+
if(jsFlags[sfbOff+sfb] & MS_ON) {
WriteBits(hBitStream,1,1);
}
@@ -272,7 +272,7 @@
Word16 coefBits;
Flag isShort;
-
+
if (blockType==2) {
isShort = 1;
numOfWindows = TRANS_FAC;
@@ -282,52 +282,52 @@
numOfWindows = 1;
}
- tnsPresent=0;
+ tnsPresent=0;
for (i=0; i<numOfWindows; i++) {
-
+
if (tnsInfo.tnsActive[i]) {
- tnsPresent=1;
+ tnsPresent=1;
}
}
-
+
if (tnsPresent==0) {
WriteBits(hBitStream,0,1);
}
else{ /* there is data to be written*/
WriteBits(hBitStream,1,1); /*data_present */
for (i=0; i<numOfWindows; i++) {
-
+
WriteBits(hBitStream,tnsInfo.tnsActive[i],(isShort?1:2));
-
+
if (tnsInfo.tnsActive[i]) {
-
+
WriteBits(hBitStream,((tnsInfo.coefRes[i] - 4)==0?1:0),1);
-
+
WriteBits(hBitStream,tnsInfo.length[i],(isShort?4:6));
-
+
WriteBits(hBitStream,tnsInfo.order[i],(isShort?3:5));
-
+
if (tnsInfo.order[i]){
WriteBits(hBitStream, FILTER_DIRECTION, 1);
-
+
if(tnsInfo.coefRes[i] == 4) {
- coefBits = 3;
+ coefBits = 3;
for(k=0; k<tnsInfo.order[i]; k++) {
-
+
if (tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] > 3 ||
tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] < -4) {
- coefBits = 4;
+ coefBits = 4;
break;
}
}
}
else {
- coefBits = 2;
+ coefBits = 2;
for(k=0; k<tnsInfo.order[i]; k++) {
-
+
if (tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] > 1 ||
tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] < -2) {
- coefBits = 3;
+ coefBits = 3;
break;
}
}
@@ -335,7 +335,7 @@
WriteBits(hBitStream, tnsInfo.coefRes[i] - coefBits, 1); /*coef_compres*/
for (k=0; k<tnsInfo.order[i]; k++ ) {
static const Word16 rmask[] = {0,1,3,7,15};
-
+
WriteBits(hBitStream,tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] & rmask[coefBits],coefBits);
}
}
@@ -397,7 +397,7 @@
encodeGlobalGain(globalGain, logNorm,scf[sectionData->firstScf], hBitStream);
-
+
if(!commonWindow) {
encodeIcsInfo(sectionData->blockType, windowShape, groupingMask, sectionData, hBitStream);
}
@@ -536,7 +536,7 @@
Write fill Element(s):
amount of a fill element can be 7+X*8 Bits, X element of [0..270]
*/
-
+
while(totFillBits >= (3+4)) {
cnt = min(((totFillBits - (3+4)) >> 3), ((1<<4)-1));
@@ -545,7 +545,7 @@
totFillBits = totFillBits - (3+4);
-
+
if ((cnt == (1<<4)-1)) {
esc_count = min( ((totFillBits >> 3) - ((1<<4)-1)), (1<<8)-1);
@@ -555,7 +555,7 @@
}
for(i=0;i<cnt;i++) {
-
+
if(ancBytes)
WriteBits(hBitStream, *ancBytes++,8);
else
@@ -576,7 +576,7 @@
ELEMENT_INFO elInfo,
QC_OUT *qcOut,
PSY_OUT *psyOut,
- Word16 *globUsedBits,
+ Word16 *globUsedBits,
const UWord8 *ancBytes,
Word16 sampindex
) /* returns error code */
@@ -586,7 +586,7 @@
Word16 frameBits=0;
/* struct bitbuffer bsWriteCopy; */
- bitMarkUp = GetBitsAvail(hBitStream);
+ bitMarkUp = GetBitsAvail(hBitStream);
if(qcOut->qcElement.adtsUsed) /* write adts header*/
{
WriteBits(hBitStream, 0xFFF, 12); /* 12 bit Syncword */
@@ -601,23 +601,23 @@
6 channels or less, else a channel
configuration should be written */
WriteBits(hBitStream, 0, 1); /* original/copy */
- WriteBits(hBitStream, 0, 1); /* home */
-
+ WriteBits(hBitStream, 0, 1); /* home */
+
/* Variable ADTS header */
WriteBits(hBitStream, 0, 1); /* copyr. id. bit */
WriteBits(hBitStream, 0, 1); /* copyr. id. start */
WriteBits(hBitStream, *globUsedBits >> 3, 13);
WriteBits(hBitStream, 0x7FF, 11); /* buffer fullness (0x7FF for VBR) */
- WriteBits(hBitStream, 0, 2); /* raw data blocks (0+1=1) */
+ WriteBits(hBitStream, 0, 2); /* raw data blocks (0+1=1) */
}
- *globUsedBits=0;
+ *globUsedBits=0;
{
Word16 *sfbOffset[2];
TNS_INFO tnsInfo[2];
- elementUsedBits = 0;
+ elementUsedBits = 0;
switch (elInfo.elType) {
@@ -636,7 +636,7 @@
{
Word16 msDigest;
Word16 *msFlags = psyOut->psyOutElement.toolsInfo.msMask;
- msDigest = psyOut->psyOutElement.toolsInfo.msDigest;
+ msDigest = psyOut->psyOutElement.toolsInfo.msDigest;
sfbOffset[0] =
psyOut->psyOutChannel[elInfo.ChannelIndex[0]].sfbOffsets;
sfbOffset[1] =
@@ -668,20 +668,20 @@
}
writeFillElement(NULL,
- qcOut->totFillBits,
+ qcOut->totFillBits,
hBitStream);
WriteBits(hBitStream,ID_END,3);
/* byte alignement */
- WriteBits(hBitStream,0, (8 - (hBitStream->cntBits & 7)) & 7);
-
+ WriteBits(hBitStream,0, (8 - (hBitStream->cntBits & 7)) & 7);
+
*globUsedBits = *globUsedBits- bitMarkUp;
- bitMarkUp = GetBitsAvail(hBitStream);
+ bitMarkUp = GetBitsAvail(hBitStream);
*globUsedBits = *globUsedBits + bitMarkUp;
frameBits = frameBits + *globUsedBits;
-
+
if (frameBits != (qcOut->totStaticBitsUsed+qcOut->totDynBitsUsed + qcOut->totAncBitsUsed +
qcOut->totFillBits + qcOut->alignBits)) {
return(-1);
diff --git a/media/libstagefright/codecs/aacenc/src/block_switch.c b/media/libstagefright/codecs/aacenc/src/block_switch.c
index 47fd15e..d54e32f 100644
--- a/media/libstagefright/codecs/aacenc/src/block_switch.c
+++ b/media/libstagefright/codecs/aacenc/src/block_switch.c
@@ -52,7 +52,7 @@
IIR high pass coeffs
*/
Word32 hiPassCoeff[BLOCK_SWITCHING_IIR_LEN] = {
- 0xbec8b439, 0x609d4952 /* -0.5095f, 0.7548f */
+ 0xbec8b439, 0x609d4952 /* -0.5095f, 0.7548f */
};
static const Word32 accWindowNrgFac = 0x26666666; /* factor for accumulating filtered window energies 0.3 */
@@ -76,8 +76,8 @@
const Word32 bitRate, const Word16 nChannels)
{
/* select attackRatio */
-
- if ((sub(nChannels,1)==0 && L_sub(bitRate, 24000) > 0) ||
+
+ if ((sub(nChannels,1)==0 && L_sub(bitRate, 24000) > 0) ||
(sub(nChannels,1)>0 && bitRate > (nChannels * 16000))) {
blockSwitchingControl->invAttackRatio = invAttackRatioHighBr;
}
@@ -116,7 +116,7 @@
/* Reset grouping info */
for (i=0; i<TRANS_FAC; i++) {
- blockSwitchingControl->groupLen[i] = 0;
+ blockSwitchingControl->groupLen[i] = 0;
}
@@ -125,21 +125,21 @@
&blockSwitchingControl->attackIndex,
BLOCK_SWITCH_WINDOWS);
- blockSwitchingControl->attackIndex = blockSwitchingControl->lastAttackIndex;
+ blockSwitchingControl->attackIndex = blockSwitchingControl->lastAttackIndex;
/* Set grouping info */
- blockSwitchingControl->noOfGroups = MAX_NO_OF_GROUPS;
+ blockSwitchingControl->noOfGroups = MAX_NO_OF_GROUPS;
for (i=0; i<MAX_NO_OF_GROUPS; i++) {
- blockSwitchingControl->groupLen[i] = suggestedGroupingTable[blockSwitchingControl->attackIndex][i];
+ blockSwitchingControl->groupLen[i] = suggestedGroupingTable[blockSwitchingControl->attackIndex][i];
}
-
+
/* if the samplerate is less than 16000, it should be all the short block, avoid pre&post echo */
if(sampleRate >= 16000) {
/* Save current window energy as last window energy */
for (w=0; w<BLOCK_SWITCH_WINDOWS; w++) {
- blockSwitchingControl->windowNrg[0][w] = blockSwitchingControl->windowNrg[1][w];
- blockSwitchingControl->windowNrgF[0][w] = blockSwitchingControl->windowNrgF[1][w];
+ blockSwitchingControl->windowNrg[0][w] = blockSwitchingControl->windowNrg[1][w];
+ blockSwitchingControl->windowNrgF[0][w] = blockSwitchingControl->windowNrgF[1][w];
}
@@ -147,10 +147,10 @@
CalcWindowEnergy(blockSwitchingControl, timeSignal, chIncrement, BLOCK_SWITCH_WINDOW_LEN);
/* reset attack */
- blockSwitchingControl->attack = FALSE;
+ blockSwitchingControl->attack = FALSE;
- enMax = 0;
- enM1 = blockSwitchingControl->windowNrgF[0][BLOCK_SWITCH_WINDOWS-1];
+ enMax = 0;
+ enM1 = blockSwitchingControl->windowNrgF[0][BLOCK_SWITCH_WINDOWS-1];
for (w=0; w<BLOCK_SWITCH_WINDOWS; w++) {
Word32 enM1_Tmp, accWindowNrg_Tmp, windowNrgF_Tmp;
@@ -172,15 +172,15 @@
/* if the energy with the ratio is bigger than the average, and the attack and short block */
if ((fixmul(windowNrgF_Tmp, blockSwitchingControl->invAttackRatio) >> windowNrgF_Shf) >
blockSwitchingControl->accWindowNrg ) {
- blockSwitchingControl->attack = TRUE;
- blockSwitchingControl->lastAttackIndex = w;
+ blockSwitchingControl->attack = TRUE;
+ blockSwitchingControl->lastAttackIndex = w;
}
- enM1 = blockSwitchingControl->windowNrgF[1][w];
+ enM1 = blockSwitchingControl->windowNrgF[1][w];
enMax = max(enMax, enM1);
}
if (enMax < minAttackNrg) {
- blockSwitchingControl->attack = FALSE;
+ blockSwitchingControl->attack = FALSE;
}
}
else
@@ -188,22 +188,22 @@
blockSwitchingControl->attack = TRUE;
}
- /* Check if attack spreads over frame border */
+ /* Check if attack spreads over frame border */
if ((!blockSwitchingControl->attack) && (blockSwitchingControl->lastattack)) {
-
+
if (blockSwitchingControl->attackIndex == TRANS_FAC-1) {
- blockSwitchingControl->attack = TRUE;
+ blockSwitchingControl->attack = TRUE;
}
- blockSwitchingControl->lastattack = FALSE;
+ blockSwitchingControl->lastattack = FALSE;
}
else {
- blockSwitchingControl->lastattack = blockSwitchingControl->attack;
+ blockSwitchingControl->lastattack = blockSwitchingControl->attack;
}
- blockSwitchingControl->windowSequence = blockSwitchingControl->nextwindowSequence;
+ blockSwitchingControl->windowSequence = blockSwitchingControl->nextwindowSequence;
-
+
if (blockSwitchingControl->attack) {
blockSwitchingControl->nextwindowSequence = SHORT_WINDOW;
}
@@ -211,27 +211,27 @@
blockSwitchingControl->nextwindowSequence = LONG_WINDOW;
}
- /* update short block group */
+ /* update short block group */
if (blockSwitchingControl->nextwindowSequence == SHORT_WINDOW) {
-
+
if (blockSwitchingControl->windowSequence== LONG_WINDOW) {
- blockSwitchingControl->windowSequence = START_WINDOW;
+ blockSwitchingControl->windowSequence = START_WINDOW;
}
-
+
if (blockSwitchingControl->windowSequence == STOP_WINDOW) {
- blockSwitchingControl->windowSequence = SHORT_WINDOW;
- blockSwitchingControl->noOfGroups = 3;
- blockSwitchingControl->groupLen[0] = 3;
- blockSwitchingControl->groupLen[1] = 3;
- blockSwitchingControl->groupLen[2] = 2;
+ blockSwitchingControl->windowSequence = SHORT_WINDOW;
+ blockSwitchingControl->noOfGroups = 3;
+ blockSwitchingControl->groupLen[0] = 3;
+ blockSwitchingControl->groupLen[1] = 3;
+ blockSwitchingControl->groupLen[2] = 2;
}
}
- /* update block type */
+ /* update block type */
if (blockSwitchingControl->nextwindowSequence == LONG_WINDOW) {
-
+
if (blockSwitchingControl->windowSequence == SHORT_WINDOW) {
- blockSwitchingControl->nextwindowSequence = STOP_WINDOW;
+ blockSwitchingControl->nextwindowSequence = STOP_WINDOW;
}
}
@@ -252,17 +252,17 @@
Word32 i, idx;
/* Search maximum value in array and return index and value */
- max = 0;
- idx = 0;
+ max = 0;
+ idx = 0;
for (i = 0; i < n; i++) {
-
+
if (in[i+1] > max) {
- max = in[i+1];
- idx = i;
+ max = in[i+1];
+ idx = i;
}
}
- *index = idx;
+ *index = idx;
return(max);
}
@@ -292,11 +292,11 @@
states1 = blockSwitchingControl->iirStates[1];
Coeff0 = hiPassCoeff[0];
Coeff1 = hiPassCoeff[1];
- tidx = 0;
+ tidx = 0;
for (w=0; w < BLOCK_SWITCH_WINDOWS; w++) {
- accuUE = 0;
- accuFE = 0;
+ accuUE = 0;
+ accuFE = 0;
for(i=0; i<windowLen; i++) {
Word32 accu1, accu2, accu3;
@@ -309,16 +309,16 @@
accu3 = accu1 - states0;
out = accu3 - accu2;
- states0 = accu1;
- states1 = out;
+ states0 = accu1;
+ states1 = out;
- tempFiltered = extract_h(out);
+ tempFiltered = extract_h(out);
accuUE += (tempUnfiltered * tempUnfiltered) >> ENERGY_SHIFT;
accuFE += (tempFiltered * tempFiltered) >> ENERGY_SHIFT;
}
- blockSwitchingControl->windowNrg[1][w] = accuUE;
- blockSwitchingControl->windowNrgF[1][w] = accuFE;
+ blockSwitchingControl->windowNrg[1][w] = accuUE;
+ blockSwitchingControl->windowNrgF[1][w] = accuFE;
}
@@ -346,8 +346,8 @@
accu2 = fixmul( coeff[0], states[1] );
out = accu3 - accu2;
- states[0] = accu1;
- states[1] = out;
+ states[0] = accu1;
+ states[1] = out;
return round16(out);
}
@@ -374,54 +374,54 @@
const Word16 nChannels)
{
Word16 i;
- Word16 patchType = LONG_WINDOW;
+ Word16 patchType = LONG_WINDOW;
-
+
if (nChannels == 1) { /* Mono */
if (blockSwitchingControlLeft->windowSequence != SHORT_WINDOW) {
- blockSwitchingControlLeft->noOfGroups = 1;
- blockSwitchingControlLeft->groupLen[0] = 1;
+ blockSwitchingControlLeft->noOfGroups = 1;
+ blockSwitchingControlLeft->groupLen[0] = 1;
for (i=1; i<TRANS_FAC; i++) {
- blockSwitchingControlLeft->groupLen[i] = 0;
+ blockSwitchingControlLeft->groupLen[i] = 0;
}
}
}
else { /* Stereo common Window */
- patchType = synchronizedBlockTypeTable[patchType][blockSwitchingControlLeft->windowSequence];
- patchType = synchronizedBlockTypeTable[patchType][blockSwitchingControlRight->windowSequence];
+ patchType = synchronizedBlockTypeTable[patchType][blockSwitchingControlLeft->windowSequence];
+ patchType = synchronizedBlockTypeTable[patchType][blockSwitchingControlRight->windowSequence];
/* Set synchronized Blocktype */
- blockSwitchingControlLeft->windowSequence = patchType;
- blockSwitchingControlRight->windowSequence = patchType;
+ blockSwitchingControlLeft->windowSequence = patchType;
+ blockSwitchingControlRight->windowSequence = patchType;
- /* Synchronize grouping info */
+ /* Synchronize grouping info */
if(patchType != SHORT_WINDOW) { /* Long Blocks */
/* Set grouping info */
- blockSwitchingControlLeft->noOfGroups = 1;
- blockSwitchingControlRight->noOfGroups = 1;
- blockSwitchingControlLeft->groupLen[0] = 1;
- blockSwitchingControlRight->groupLen[0] = 1;
+ blockSwitchingControlLeft->noOfGroups = 1;
+ blockSwitchingControlRight->noOfGroups = 1;
+ blockSwitchingControlLeft->groupLen[0] = 1;
+ blockSwitchingControlRight->groupLen[0] = 1;
for (i=1; i<TRANS_FAC; i++) {
- blockSwitchingControlLeft->groupLen[i] = 0;
- blockSwitchingControlRight->groupLen[i] = 0;
+ blockSwitchingControlLeft->groupLen[i] = 0;
+ blockSwitchingControlRight->groupLen[i] = 0;
}
}
else {
-
+
if (blockSwitchingControlLeft->maxWindowNrg > blockSwitchingControlRight->maxWindowNrg) {
/* Left Channel wins */
- blockSwitchingControlRight->noOfGroups = blockSwitchingControlLeft->noOfGroups;
+ blockSwitchingControlRight->noOfGroups = blockSwitchingControlLeft->noOfGroups;
for (i=0; i<TRANS_FAC; i++) {
- blockSwitchingControlRight->groupLen[i] = blockSwitchingControlLeft->groupLen[i];
+ blockSwitchingControlRight->groupLen[i] = blockSwitchingControlLeft->groupLen[i];
}
}
else {
/* Right Channel wins */
- blockSwitchingControlLeft->noOfGroups = blockSwitchingControlRight->noOfGroups;
+ blockSwitchingControlLeft->noOfGroups = blockSwitchingControlRight->noOfGroups;
for (i=0; i<TRANS_FAC; i++) {
- blockSwitchingControlLeft->groupLen[i] = blockSwitchingControlRight->groupLen[i];
+ blockSwitchingControlLeft->groupLen[i] = blockSwitchingControlRight->groupLen[i];
}
}
}
diff --git a/media/libstagefright/codecs/aacenc/src/channel_map.c b/media/libstagefright/codecs/aacenc/src/channel_map.c
index f6552ed..2d41f8c 100644
--- a/media/libstagefright/codecs/aacenc/src/channel_map.c
+++ b/media/libstagefright/codecs/aacenc/src/channel_map.c
@@ -29,32 +29,32 @@
static Word16 initElement(ELEMENT_INFO* elInfo, ELEMENT_TYPE elType)
{
- Word16 error=0;
+ Word16 error=0;
- elInfo->elType=elType;
+ elInfo->elType=elType;
switch(elInfo->elType) {
case ID_SCE:
- elInfo->nChannelsInEl=1;
+ elInfo->nChannelsInEl=1;
- elInfo->ChannelIndex[0]=0;
+ elInfo->ChannelIndex[0]=0;
- elInfo->instanceTag=0;
+ elInfo->instanceTag=0;
break;
case ID_CPE:
- elInfo->nChannelsInEl=2;
+ elInfo->nChannelsInEl=2;
- elInfo->ChannelIndex[0]=0;
- elInfo->ChannelIndex[1]=1;
+ elInfo->ChannelIndex[0]=0;
+ elInfo->ChannelIndex[1]=1;
- elInfo->instanceTag=0;
+ elInfo->instanceTag=0;
break;
default:
- error=1;
+ error=1;
}
return error;
@@ -64,11 +64,11 @@
Word16 InitElementInfo (Word16 nChannels, ELEMENT_INFO* elInfo)
{
Word16 error;
- error = 0;
+ error = 0;
switch(nChannels) {
- case 1:
+ case 1:
initElement(elInfo, ID_SCE);
break;
@@ -77,7 +77,7 @@
break;
default:
- error=4;
+ error=4;
}
return error;
@@ -91,18 +91,18 @@
Word16 staticBitsTot)
{
Word16 error;
- error = 0;
+ error = 0;
switch(elInfo.nChannelsInEl) {
case 1:
- elementBits->chBitrate = bitrateTot;
+ elementBits->chBitrate = bitrateTot;
elementBits->averageBits = averageBitsTot - staticBitsTot;
- elementBits->maxBits = maxChannelBits;
+ elementBits->maxBits = maxChannelBits;
elementBits->maxBitResBits = maxChannelBits - averageBitsTot;
- elementBits->maxBitResBits = elementBits->maxBitResBits - (elementBits->maxBitResBits & 7);
- elementBits->bitResLevel = elementBits->maxBitResBits;
- elementBits->relativeBits = 0x4000; /* 1.0f/2 */
+ elementBits->maxBitResBits = elementBits->maxBitResBits - (elementBits->maxBitResBits & 7);
+ elementBits->bitResLevel = elementBits->maxBitResBits;
+ elementBits->relativeBits = 0x4000; /* 1.0f/2 */
break;
case 2:
@@ -111,13 +111,13 @@
elementBits->maxBits = maxChannelBits << 1;
elementBits->maxBitResBits = (maxChannelBits << 1) - averageBitsTot;
- elementBits->maxBitResBits = elementBits->maxBitResBits - (elementBits->maxBitResBits & 7);
- elementBits->bitResLevel = elementBits->maxBitResBits;
- elementBits->relativeBits = 0x4000; /* 1.0f/2 */
+ elementBits->maxBitResBits = elementBits->maxBitResBits - (elementBits->maxBitResBits & 7);
+ elementBits->bitResLevel = elementBits->maxBitResBits;
+ elementBits->relativeBits = 0x4000; /* 1.0f/2 */
break;
default:
- error = 1;
+ error = 1;
}
return error;
}
diff --git a/media/libstagefright/codecs/aacenc/src/dyn_bits.c b/media/libstagefright/codecs/aacenc/src/dyn_bits.c
index 3d2efdc..f3b3e02 100644
--- a/media/libstagefright/codecs/aacenc/src/dyn_bits.c
+++ b/media/libstagefright/codecs/aacenc/src/dyn_bits.c
@@ -45,12 +45,12 @@
for (i=0; i<maxSfb; i++) {
Word16 sfbWidth, maxVal;
- sectionInfo[i].sfbCnt = 1;
- sectionInfo[i].sfbStart = i;
- sectionInfo[i].sectionBits = INVALID_BITCOUNT;
- sectionInfo[i].codeBook = -1;
- sfbWidth = sfbOffset[i + 1] - sfbOffset[i];
- maxVal = sfbMax[i];
+ sectionInfo[i].sfbCnt = 1;
+ sectionInfo[i].sfbStart = i;
+ sectionInfo[i].sectionBits = INVALID_BITCOUNT;
+ sectionInfo[i].codeBook = -1;
+ sfbWidth = sfbOffset[i + 1] - sfbOffset[i];
+ maxVal = sfbMax[i];
bitCount(quantSpectrum + sfbOffset[i], sfbWidth, maxVal, bitLookUp[i]);
}
}
@@ -66,13 +66,13 @@
findBestBook(const Word16 *bc, Word16 *book)
{
Word32 minBits, j;
- minBits = INVALID_BITCOUNT;
+ minBits = INVALID_BITCOUNT;
for (j=0; j<=CODE_BOOK_ESC_NDX; j++) {
-
+
if (bc[j] < minBits) {
- minBits = bc[j];
- *book = j;
+ minBits = bc[j];
+ *book = j;
}
}
return extract_l(minBits);
@@ -82,12 +82,12 @@
findMinMergeBits(const Word16 *bc1, const Word16 *bc2)
{
Word32 minBits, j, sum;
- minBits = INVALID_BITCOUNT;
+ minBits = INVALID_BITCOUNT;
for (j=0; j<=CODE_BOOK_ESC_NDX; j++) {
sum = bc1[j] + bc2[j];
if (sum < minBits) {
- minBits = sum;
+ minBits = sum;
}
}
return extract_l(minBits);
@@ -109,13 +109,13 @@
const Word16 maxSfb, Word16 *maxNdx)
{
Word32 i, maxMergeGain;
- maxMergeGain = 0;
+ maxMergeGain = 0;
for (i=0; i+sectionInfo[i].sfbCnt < maxSfb; i += sectionInfo[i].sfbCnt) {
-
+
if (mergeGainLookUp[i] > maxMergeGain) {
- maxMergeGain = mergeGainLookUp[i];
- *maxNdx = i;
+ maxMergeGain = mergeGainLookUp[i];
+ *maxNdx = i;
}
}
return extract_l(maxMergeGain);
@@ -159,7 +159,7 @@
for (i=0; i<maxSfb; i++) {
/* Side-Info bits will be calculated in Stage 1! */
-
+
if (sectionInfo[i].sectionBits == INVALID_BITCOUNT) {
sectionInfo[i].sectionBits = findBestBook(bitLookUp[i], &(sectionInfo[i].codeBook));
}
@@ -180,13 +180,13 @@
SECTION_INFO * sectionInfo_s;
SECTION_INFO * sectionInfo_e;
Word32 mergeStart, mergeEnd;
- mergeStart = 0;
+ mergeStart = 0;
do {
sectionInfo_s = sectionInfo + mergeStart;
for (mergeEnd=mergeStart+1; mergeEnd<maxSfb; mergeEnd++) {
- sectionInfo_e = sectionInfo + mergeEnd;
+ sectionInfo_e = sectionInfo + mergeEnd;
if (sectionInfo_s->codeBook != sectionInfo_e->codeBook)
break;
sectionInfo_s->sfbCnt += 1;
@@ -196,11 +196,11 @@
}
sectionInfo_s->sectionBits += sideInfoTab[sectionInfo_s->sfbCnt];
- sectionInfo[mergeEnd - 1].sfbStart = sectionInfo_s->sfbStart; /* speed up prev search */
+ sectionInfo[mergeEnd - 1].sfbStart = sectionInfo_s->sfbStart; /* speed up prev search */
- mergeStart = mergeEnd;
+ mergeStart = mergeEnd;
-
+
} while (mergeStart - maxSfb < 0);
}
@@ -230,7 +230,7 @@
maxMergeGain = findMaxMerge(mergeGainLookUp, sectionInfo, maxSfb, &maxNdx);
-
+
if (maxMergeGain <= 0)
break;
@@ -244,7 +244,7 @@
mergeBitLookUp(bitLookUp[maxNdx], bitLookUp[maxNdxNext]);
-
+
if (maxNdx != 0) {
maxNdxLast = sectionInfo[maxNdx - 1].sfbStart;
mergeGainLookUp[maxNdxLast] = CalcMergeGain(sectionInfo,
@@ -255,9 +255,9 @@
}
maxNdxNext = maxNdx + sectionInfo[maxNdx].sfbCnt;
- sectionInfo[maxNdxNext - 1].sfbStart = sectionInfo[maxNdx].sfbStart;
+ sectionInfo[maxNdxNext - 1].sfbStart = sectionInfo[maxNdx].sfbStart;
-
+
if (maxNdxNext - maxSfb < 0) {
mergeGainLookUp[maxNdx] = CalcMergeGain(sectionInfo,
bitLookUp,
@@ -286,7 +286,7 @@
/*
use appropriate side info table
- */
+ */
switch (blockType)
{
case LONG_WINDOW:
@@ -300,11 +300,11 @@
}
- sectionData->noOfSections = 0;
- sectionData->huffmanBits = 0;
- sectionData->sideInfoBits = 0;
+ sectionData->noOfSections = 0;
+ sectionData->huffmanBits = 0;
+ sectionData->sideInfoBits = 0;
-
+
if (sectionData->maxSfbPerGroup == 0)
return;
@@ -353,7 +353,7 @@
sectionData->huffmanBits = (sectionData->huffmanBits +
(sectionInfo[i].sectionBits - sideInfoTab[sectionInfo[i].sfbCnt]));
sectionData->sideInfoBits = (sectionData->sideInfoBits + sideInfoTab[sectionInfo[i].sfbCnt]);
- sectionData->sectionInfo[sectionData->noOfSections] = sectionInfo[i];
+ sectionData->sectionInfo[sectionData->noOfSections] = sectionInfo[i];
sectionData->noOfSections = sectionData->noOfSections + 1;
}
}
@@ -386,25 +386,25 @@
Word32 lastValScf = 0;
Word32 deltaScf = 0;
Flag found = 0;
- Word32 scfSkipCounter = 0;
+ Word32 scfSkipCounter = 0;
+
+ sectionData->scalefacBits = 0;
- sectionData->scalefacBits = 0;
-
-
+
if (scalefacGain == NULL) {
return;
}
- lastValScf = 0;
- sectionData->firstScf = 0;
-
+ lastValScf = 0;
+ sectionData->firstScf = 0;
+
psectionInfo = sectionData->sectionInfo;
for (i=0; i<sectionData->noOfSections; i++) {
-
+
if (psectionInfo->codeBook != CODE_BOOK_ZERO_NO) {
- sectionData->firstScf = psectionInfo->sfbStart;
- lastValScf = scalefacGain[sectionData->firstScf];
+ sectionData->firstScf = psectionInfo->sfbStart;
+ lastValScf = scalefacGain[sectionData->firstScf];
break;
}
psectionInfo += 1;
@@ -412,38 +412,38 @@
psectionInfo = sectionData->sectionInfo;
for (i=0; i<sectionData->noOfSections; i++, psectionInfo += 1) {
-
+
if (psectionInfo->codeBook != CODE_BOOK_ZERO_NO
&& psectionInfo->codeBook != CODE_BOOK_PNS_NO) {
for (j = psectionInfo->sfbStart;
j < (psectionInfo->sfbStart + psectionInfo->sfbCnt); j++) {
/* check if we can repeat the last value to save bits */
-
+
if (maxValueInSfb[j] == 0) {
- found = 0;
-
+ found = 0;
+
if (scfSkipCounter == 0) {
/* end of section */
-
+
if (j - ((psectionInfo->sfbStart + psectionInfo->sfbCnt) - 1) == 0) {
- found = 0;
+ found = 0;
}
else {
for (k = j + 1; k < psectionInfo->sfbStart + psectionInfo->sfbCnt; k++) {
-
+
if (maxValueInSfb[k] != 0) {
int tmp = L_abs(scalefacGain[k] - lastValScf);
- found = 1;
-
+ found = 1;
+
if ( tmp < CODE_BOOK_SCF_LAV) {
/* save bits */
- deltaScf = 0;
+ deltaScf = 0;
}
else {
/* do not save bits */
deltaScf = lastValScf - scalefacGain[j];
- lastValScf = scalefacGain[j];
- scfSkipCounter = 0;
+ lastValScf = scalefacGain[j];
+ scfSkipCounter = 0;
}
break;
}
@@ -451,26 +451,26 @@
scfSkipCounter = scfSkipCounter + 1;
}
}
-
+
psectionInfom = psectionInfo + 1;
/* search for the next maxValueInSfb[] != 0 in all other sections */
for (m = i + 1; (m < sectionData->noOfSections) && (found == 0); m++) {
-
+
if ((psectionInfom->codeBook != CODE_BOOK_ZERO_NO) &&
(psectionInfom->codeBook != CODE_BOOK_PNS_NO)) {
for (n = psectionInfom->sfbStart;
n < (psectionInfom->sfbStart + psectionInfom->sfbCnt); n++) {
-
+
if (maxValueInSfb[n] != 0) {
- found = 1;
-
+ found = 1;
+
if ( (abs_s(scalefacGain[n] - lastValScf) < CODE_BOOK_SCF_LAV)) {
- deltaScf = 0;
+ deltaScf = 0;
}
else {
deltaScf = (lastValScf - scalefacGain[j]);
- lastValScf = scalefacGain[j];
- scfSkipCounter = 0;
+ lastValScf = scalefacGain[j];
+ scfSkipCounter = 0;
}
break;
}
@@ -481,20 +481,20 @@
psectionInfom += 1;
}
-
+
if (found == 0) {
- deltaScf = 0;
- scfSkipCounter = 0;
+ deltaScf = 0;
+ scfSkipCounter = 0;
}
}
else {
- deltaScf = 0;
+ deltaScf = 0;
scfSkipCounter = scfSkipCounter - 1;
}
}
else {
deltaScf = lastValScf - scalefacGain[j];
- lastValScf = scalefacGain[j];
+ lastValScf = scalefacGain[j];
}
sectionData->scalefacBits += bitCountScalefactorDelta(deltaScf);
}
@@ -517,14 +517,14 @@
const Word16 *sfbOffset,
SECTION_DATA *sectionData)
{
- sectionData->blockType = blockType;
- sectionData->sfbCnt = sfbCnt;
- sectionData->sfbPerGroup = sfbPerGroup;
+ sectionData->blockType = blockType;
+ sectionData->sfbCnt = sfbCnt;
+ sectionData->sfbPerGroup = sfbPerGroup;
if(sfbPerGroup)
- sectionData->noOfGroups = sfbCnt/sfbPerGroup;
+ sectionData->noOfGroups = sfbCnt/sfbPerGroup;
else
sectionData->noOfGroups = 0x7fff;
- sectionData->maxSfbPerGroup = maxSfbPerGroup;
+ sectionData->maxSfbPerGroup = maxSfbPerGroup;
noiselessCounter(sectionData,
sectionData->mergeGainLookUp,
@@ -539,7 +539,7 @@
sectionData);
- return (sectionData->huffmanBits + sectionData->sideInfoBits +
+ return (sectionData->huffmanBits + sectionData->sideInfoBits +
sectionData->scalefacBits);
}
diff --git a/media/libstagefright/codecs/aacenc/src/grp_data.c b/media/libstagefright/codecs/aacenc/src/grp_data.c
index 7861e1c..fb88654 100644
--- a/media/libstagefright/codecs/aacenc/src/grp_data.c
+++ b/media/libstagefright/codecs/aacenc/src/grp_data.c
@@ -57,29 +57,29 @@
/* for short: regroup and */
/* cumulate energies und thresholds group-wise . */
-
+
/* calculate sfbCnt */
- highestSfb = 0;
+ highestSfb = 0;
for (wnd=0; wnd<TRANS_FAC; wnd++) {
for (sfb=sfbCnt - 1; sfb>=highestSfb; sfb--) {
for (line=(sfbOffset[sfb + 1] - 1); line>=sfbOffset[sfb]; line--) {
-
- if (mdctSpectrum[wnd*FRAME_LEN_SHORT+line] != 0) break;
+
+ if (mdctSpectrum[wnd*FRAME_LEN_SHORT+line] != 0) break;
}
-
+
if (line >= sfbOffset[sfb]) break;
}
highestSfb = max(highestSfb, sfb);
}
-
+
if (highestSfb < 0) {
- highestSfb = 0;
+ highestSfb = 0;
}
*maxSfbPerGroup = highestSfb + 1;
/* calculate sfbOffset */
- i = 0;
- offset = 0;
+ i = 0;
+ offset = 0;
for (grp = 0; grp < noOfGroups; grp++) {
for (sfb = 0; sfb < sfbCnt; sfb++) {
groupedSfbOffset[i] = offset + sfbOffset[sfb] * groupLen[grp];
@@ -87,15 +87,15 @@
}
offset += groupLen[grp] * FRAME_LEN_SHORT;
}
- groupedSfbOffset[i] = FRAME_LEN_LONG;
+ groupedSfbOffset[i] = FRAME_LEN_LONG;
i += 1;
/* calculate minSnr */
- i = 0;
- offset = 0;
+ i = 0;
+ offset = 0;
for (grp = 0; grp < noOfGroups; grp++) {
for (sfb = 0; sfb < sfbCnt; sfb++) {
- groupedSfbMinSnr[i] = sfbMinSnr[sfb];
+ groupedSfbMinSnr[i] = sfbMinSnr[sfb];
i += 1;
}
offset += groupLen[grp] * FRAME_LEN_SHORT;
@@ -103,74 +103,74 @@
/* sum up sfbThresholds */
- wnd = 0;
- i = 0;
+ wnd = 0;
+ i = 0;
for (grp = 0; grp < noOfGroups; grp++) {
for (sfb = 0; sfb < sfbCnt; sfb++) {
- Word32 thresh = sfbThreshold->sfbShort[wnd][sfb];
+ Word32 thresh = sfbThreshold->sfbShort[wnd][sfb];
for (j=1; j<groupLen[grp]; j++) {
thresh = L_add(thresh, sfbThreshold->sfbShort[wnd+j][sfb]);
}
- sfbThreshold->sfbLong[i] = thresh;
+ sfbThreshold->sfbLong[i] = thresh;
i += 1;
}
wnd += groupLen[grp];
}
/* sum up sfbEnergies left/right */
- wnd = 0;
- i = 0;
+ wnd = 0;
+ i = 0;
for (grp = 0; grp < noOfGroups; grp++) {
for (sfb = 0; sfb < sfbCnt; sfb++) {
- Word32 energy = sfbEnergy->sfbShort[wnd][sfb];
+ Word32 energy = sfbEnergy->sfbShort[wnd][sfb];
for (j=1; j<groupLen[grp]; j++) {
energy = L_add(energy, sfbEnergy->sfbShort[wnd+j][sfb]);
}
- sfbEnergy->sfbLong[i] = energy;
+ sfbEnergy->sfbLong[i] = energy;
i += 1;
}
wnd += groupLen[grp];
}
/* sum up sfbEnergies mid/side */
- wnd = 0;
- i = 0;
+ wnd = 0;
+ i = 0;
for (grp = 0; grp < noOfGroups; grp++) {
for (sfb = 0; sfb < sfbCnt; sfb++) {
- Word32 energy = sfbEnergyMS->sfbShort[wnd][sfb];
+ Word32 energy = sfbEnergyMS->sfbShort[wnd][sfb];
for (j=1; j<groupLen[grp]; j++) {
energy = L_add(energy, sfbEnergyMS->sfbShort[wnd+j][sfb]);
}
- sfbEnergyMS->sfbLong[i] = energy;
+ sfbEnergyMS->sfbLong[i] = energy;
i += 1;
}
wnd += groupLen[grp];
}
/* sum up sfbSpreadedEnergies */
- wnd = 0;
- i = 0;
+ wnd = 0;
+ i = 0;
for (grp = 0; grp < noOfGroups; grp++) {
for (sfb = 0; sfb < sfbCnt; sfb++) {
- Word32 energy = sfbSpreadedEnergy->sfbShort[wnd][sfb];
+ Word32 energy = sfbSpreadedEnergy->sfbShort[wnd][sfb];
for (j=1; j<groupLen[grp]; j++) {
energy = L_add(energy, sfbSpreadedEnergy->sfbShort[wnd+j][sfb]);
}
- sfbSpreadedEnergy->sfbLong[i] = energy;
+ sfbSpreadedEnergy->sfbLong[i] = energy;
i += 1;
}
wnd += groupLen[grp];
}
/* re-group spectrum */
- wnd = 0;
- i = 0;
+ wnd = 0;
+ i = 0;
for (grp = 0; grp < noOfGroups; grp++) {
for (sfb = 0; sfb < sfbCnt; sfb++) {
for (j = 0; j < groupLen[grp]; j++) {
Word16 lineOffset = FRAME_LEN_SHORT * (wnd + j);
for (line = lineOffset + sfbOffset[sfb]; line < lineOffset + sfbOffset[sfb+1]; line++) {
- tmpSpectrum[i] = mdctSpectrum[line];
+ tmpSpectrum[i] = mdctSpectrum[line];
i = i + 1;
}
}
@@ -179,10 +179,10 @@
}
for(i=0;i<FRAME_LEN_LONG;i+=4) {
- mdctSpectrum[i] = tmpSpectrum[i];
- mdctSpectrum[i+1] = tmpSpectrum[i+1];
- mdctSpectrum[i+2] = tmpSpectrum[i+2];
- mdctSpectrum[i+3] = tmpSpectrum[i+3];
+ mdctSpectrum[i] = tmpSpectrum[i];
+ mdctSpectrum[i+1] = tmpSpectrum[i+1];
+ mdctSpectrum[i+2] = tmpSpectrum[i+2];
+ mdctSpectrum[i+3] = tmpSpectrum[i+3];
}
}
diff --git a/media/libstagefright/codecs/aacenc/src/interface.c b/media/libstagefright/codecs/aacenc/src/interface.c
index f2472d8..34fee00 100644
--- a/media/libstagefright/codecs/aacenc/src/interface.c
+++ b/media/libstagefright/codecs/aacenc/src/interface.c
@@ -49,56 +49,56 @@
PSY_OUT_CHANNEL *psyOutCh)
{
Word32 j;
- Word32 grp;
+ Word32 grp;
Word32 mask;
Word16 *tmpV;
/*
copy values to psyOut
*/
- psyOutCh->maxSfbPerGroup = maxSfbPerGroup;
- psyOutCh->sfbCnt = groupedSfbCnt;
+ psyOutCh->maxSfbPerGroup = maxSfbPerGroup;
+ psyOutCh->sfbCnt = groupedSfbCnt;
if(noOfGroups)
psyOutCh->sfbPerGroup = groupedSfbCnt/ noOfGroups;
else
psyOutCh->sfbPerGroup = 0x7fff;
- psyOutCh->windowSequence = windowSequence;
- psyOutCh->windowShape = windowShape;
- psyOutCh->mdctScale = mdctScale;
+ psyOutCh->windowSequence = windowSequence;
+ psyOutCh->windowShape = windowShape;
+ psyOutCh->mdctScale = mdctScale;
psyOutCh->mdctSpectrum = groupedMdctSpectrum;
psyOutCh->sfbEnergy = groupedSfbEnergy->sfbLong;
psyOutCh->sfbThreshold = groupedSfbThreshold->sfbLong;
psyOutCh->sfbSpreadedEnergy = groupedSfbSpreadedEnergy->sfbLong;
-
+
tmpV = psyOutCh->sfbOffsets;
for(j=0; j<groupedSfbCnt + 1; j++) {
*tmpV++ = groupedSfbOffset[j];
}
-
+
tmpV = psyOutCh->sfbMinSnr;
for(j=0;j<groupedSfbCnt; j++) {
*tmpV++ = groupedSfbMinSnr[j];
}
-
+
/* generate grouping mask */
- mask = 0;
+ mask = 0;
for (grp = 0; grp < noOfGroups; grp++) {
mask = mask << 1;
for (j=1; j<groupLen[grp]; j++) {
mask = mask << 1;
- mask |= 1;
+ mask |= 1;
}
}
- psyOutCh->groupingMask = mask;
-
+ psyOutCh->groupingMask = mask;
+
if (windowSequence != SHORT_WINDOW) {
- psyOutCh->sfbEnSumLR = sfbEnergySumLR.sfbLong;
- psyOutCh->sfbEnSumMS = sfbEnergySumMS.sfbLong;
+ psyOutCh->sfbEnSumLR = sfbEnergySumLR.sfbLong;
+ psyOutCh->sfbEnSumMS = sfbEnergySumMS.sfbLong;
}
else {
Word32 i;
Word32 accuSumMS=0;
- Word32 accuSumLR=0;
+ Word32 accuSumLR=0;
Word32 *pSumMS = sfbEnergySumMS.sfbShort;
Word32 *pSumLR = sfbEnergySumLR.sfbShort;
@@ -106,7 +106,7 @@
accuSumLR = L_add(accuSumLR, *pSumLR); pSumLR++;
accuSumMS = L_add(accuSumMS, *pSumMS); pSumMS++;
}
- psyOutCh->sfbEnSumMS = accuSumMS;
- psyOutCh->sfbEnSumLR = accuSumLR;
+ psyOutCh->sfbEnSumMS = accuSumMS;
+ psyOutCh->sfbEnSumLR = accuSumLR;
}
}
diff --git a/media/libstagefright/codecs/aacenc/src/line_pe.c b/media/libstagefright/codecs/aacenc/src/line_pe.c
index 480dc28..5e93cd0 100644
--- a/media/libstagefright/codecs/aacenc/src/line_pe.c
+++ b/media/libstagefright/codecs/aacenc/src/line_pe.c
@@ -45,20 +45,20 @@
const Word16 peOffset)
{
Word32 sfbGrp, sfb;
- Word32 ch;
+ Word32 ch;
for(ch=0; ch<nChannels; ch++) {
PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];
PE_CHANNEL_DATA *peChanData=&peData->peChannelData[ch];
for(sfbGrp=0;sfbGrp<psyOutChan->sfbCnt; sfbGrp+=psyOutChan->sfbPerGroup){
for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
- peChanData->sfbNLines4[sfbGrp+sfb] = sfbNRelevantLines[ch][sfbGrp+sfb];
- sfbNRelevantLines[ch][sfbGrp+sfb] = sfbNRelevantLines[ch][sfbGrp+sfb] >> 2;
- peChanData->sfbLdEnergy[sfbGrp+sfb] = logSfbEnergy[ch][sfbGrp+sfb];
+ peChanData->sfbNLines4[sfbGrp+sfb] = sfbNRelevantLines[ch][sfbGrp+sfb];
+ sfbNRelevantLines[ch][sfbGrp+sfb] = sfbNRelevantLines[ch][sfbGrp+sfb] >> 2;
+ peChanData->sfbLdEnergy[sfbGrp+sfb] = logSfbEnergy[ch][sfbGrp+sfb];
}
}
}
- peData->offset = peOffset;
+ peData->offset = peOffset;
}
@@ -78,23 +78,23 @@
Word32 ldThr, ldRatio;
Word32 pe, constPart, nActiveLines;
- peData->pe = peData->offset;
- peData->constPart = 0;
- peData->nActiveLines = 0;
+ peData->pe = peData->offset;
+ peData->constPart = 0;
+ peData->nActiveLines = 0;
for(ch=0; ch<nChannels; ch++) {
PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];
PE_CHANNEL_DATA *peChanData = &peData->peChannelData[ch];
const Word32 *sfbEnergy = psyOutChan->sfbEnergy;
const Word32 *sfbThreshold = psyOutChan->sfbThreshold;
- pe = 0;
- constPart = 0;
- nActiveLines = 0;
+ pe = 0;
+ constPart = 0;
+ nActiveLines = 0;
for(sfbGrp=0; sfbGrp<psyOutChan->sfbCnt; sfbGrp+=psyOutChan->sfbPerGroup) {
for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
- Word32 nrg = sfbEnergy[sfbGrp+sfb];
- Word32 thres = sfbThreshold[sfbGrp+sfb];
+ Word32 nrg = sfbEnergy[sfbGrp+sfb];
+ Word32 thres = sfbThreshold[sfbGrp+sfb];
Word32 sfbLDEn = peChanData->sfbLdEnergy[sfbGrp+sfb];
if (nrg > thres) {
@@ -102,8 +102,8 @@
ldRatio = sfbLDEn - ldThr;
- nLines4 = peChanData->sfbNLines4[sfbGrp+sfb];
-
+ nLines4 = peChanData->sfbNLines4[sfbGrp+sfb];
+
/* sfbPe = nl*log2(en/thr)*/
if (ldRatio >= C1_I) {
peChanData->sfbPe[sfbGrp+sfb] = (nLines4*ldRatio + 8) >> 4;
@@ -120,26 +120,26 @@
peChanData->sfbNActiveLines[sfbGrp+sfb] = nLines4 >> 2;
}
else {
- peChanData->sfbPe[sfbGrp+sfb] = 0;
- peChanData->sfbConstPart[sfbGrp+sfb] = 0;
- peChanData->sfbNActiveLines[sfbGrp+sfb] = 0;
+ peChanData->sfbPe[sfbGrp+sfb] = 0;
+ peChanData->sfbConstPart[sfbGrp+sfb] = 0;
+ peChanData->sfbNActiveLines[sfbGrp+sfb] = 0;
}
pe = pe + peChanData->sfbPe[sfbGrp+sfb];
constPart = constPart + peChanData->sfbConstPart[sfbGrp+sfb];
nActiveLines = nActiveLines + peChanData->sfbNActiveLines[sfbGrp+sfb];
}
}
+
+ peChanData->pe = saturate(pe);
+ peChanData->constPart = saturate(constPart);
+ peChanData->nActiveLines = saturate(nActiveLines);
- peChanData->pe = saturate(pe);
- peChanData->constPart = saturate(constPart);
- peChanData->nActiveLines = saturate(nActiveLines);
-
-
+
pe += peData->pe;
- peData->pe = saturate(pe);
+ peData->pe = saturate(pe);
constPart += peData->constPart;
- peData->constPart = saturate(constPart);
+ peData->constPart = saturate(constPart);
nActiveLines += peData->nActiveLines;
peData->nActiveLines = saturate(nActiveLines);
- }
+ }
}
diff --git a/media/libstagefright/codecs/aacenc/src/memalign.c b/media/libstagefright/codecs/aacenc/src/memalign.c
index bb266dc..44dd4ba 100644
--- a/media/libstagefright/codecs/aacenc/src/memalign.c
+++ b/media/libstagefright/codecs/aacenc/src/memalign.c
@@ -32,7 +32,7 @@
/*****************************************************************************
*
* function name: mem_malloc
-* description: malloc the alignments memory
+* description: malloc the alignments memory
* returns: the point of the memory
*
**********************************************************************************/
diff --git a/media/libstagefright/codecs/aacenc/src/ms_stereo.c b/media/libstagefright/codecs/aacenc/src/ms_stereo.c
index 2e34f14..44d45cc 100644
--- a/media/libstagefright/codecs/aacenc/src/ms_stereo.c
+++ b/media/libstagefright/codecs/aacenc/src/ms_stereo.c
@@ -30,7 +30,7 @@
*
* function name: MsStereoProcessing
* description: detect use ms stereo or not
-* if ((min(thrLn, thrRn)*min(thrLn, thrRn))/(enMn*enSn))
+* if ((min(thrLn, thrRn)*min(thrLn, thrRn))/(enMn*enSn))
* >= ((thrLn *thrRn)/(enLn*enRn)) then ms stereo
*
**********************************************************************************/
@@ -51,7 +51,7 @@
const Word16 maxSfbPerGroup,
const Word16 *sfbOffset) {
Word32 temp;
- Word32 sfb,sfboffs, j;
+ Word32 sfb,sfboffs, j;
Word32 msMaskTrueSomewhere = 0;
Word32 msMaskFalseSomewhere = 0;
@@ -64,12 +64,12 @@
Word32 thrL, thrR, nrgL, nrgR;
Word32 idx, shift;
- idx = sfb + sfboffs;
+ idx = sfb + sfboffs;
- thrL = sfbThresholdLeft[idx];
- thrR = sfbThresholdRight[idx];
- nrgL = sfbEnergyLeft[idx];
- nrgR = sfbEnergyRight[idx];
+ thrL = sfbThresholdLeft[idx];
+ thrR = sfbThresholdRight[idx];
+ nrgL = sfbEnergyLeft[idx];
+ nrgR = sfbEnergyRight[idx];
minThreshold = min(thrL, thrR);
@@ -82,8 +82,8 @@
pnlr = fixmul(nrgL, nrgR);
- nrgL = sfbEnergyMid[idx];
- nrgR = sfbEnergySide[idx];
+ nrgL = sfbEnergyMid[idx];
+ nrgR = sfbEnergySide[idx];
nrgL = max(nrgL,minThreshold) + 1;
shift = norm_l(nrgL);
@@ -97,42 +97,42 @@
temp = (pnlr + 1) / ((pnms >> 8) + 1);
- temp = pnms - pnlr;
+ temp = pnms - pnlr;
if( temp > 0 ){
- msMask[idx] = 1;
- msMaskTrueSomewhere = 1;
+ msMask[idx] = 1;
+ msMaskTrueSomewhere = 1;
for (j=sfbOffset[idx]; j<sfbOffset[idx+1]; j++) {
Word32 left, right;
left = (mdctSpectrumLeft[j] >> 1);
right = (mdctSpectrumRight[j] >> 1);
- mdctSpectrumLeft[j] = left + right;
- mdctSpectrumRight[j] = left - right;
+ mdctSpectrumLeft[j] = left + right;
+ mdctSpectrumRight[j] = left - right;
}
+
+ sfbThresholdLeft[idx] = minThreshold;
+ sfbThresholdRight[idx] = minThreshold;
+ sfbEnergyLeft[idx] = sfbEnergyMid[idx];
+ sfbEnergyRight[idx] = sfbEnergySide[idx];
- sfbThresholdLeft[idx] = minThreshold;
- sfbThresholdRight[idx] = minThreshold;
- sfbEnergyLeft[idx] = sfbEnergyMid[idx];
- sfbEnergyRight[idx] = sfbEnergySide[idx];
-
- sfbSpreadedEnRight[idx] = min(sfbSpreadedEnLeft[idx],sfbSpreadedEnRight[idx]) >> 1;
- sfbSpreadedEnLeft[idx] = sfbSpreadedEnRight[idx];
-
+ sfbSpreadedEnRight[idx] = min(sfbSpreadedEnLeft[idx],sfbSpreadedEnRight[idx]) >> 1;
+ sfbSpreadedEnLeft[idx] = sfbSpreadedEnRight[idx];
+
}
else {
- msMask[idx] = 0;
- msMaskFalseSomewhere = 1;
+ msMask[idx] = 0;
+ msMaskFalseSomewhere = 1;
}
- }
- if ( msMaskTrueSomewhere ) {
+ }
+ if ( msMaskTrueSomewhere ) {
if(msMaskFalseSomewhere ) {
- *msDigest = SI_MS_MASK_SOME;
+ *msDigest = SI_MS_MASK_SOME;
} else {
- *msDigest = SI_MS_MASK_ALL;
+ *msDigest = SI_MS_MASK_ALL;
}
} else {
- *msDigest = SI_MS_MASK_NONE;
+ *msDigest = SI_MS_MASK_NONE;
}
}
diff --git a/media/libstagefright/codecs/aacenc/src/pre_echo_control.c b/media/libstagefright/codecs/aacenc/src/pre_echo_control.c
index 1406e11..1e818a2 100644
--- a/media/libstagefright/codecs/aacenc/src/pre_echo_control.c
+++ b/media/libstagefright/codecs/aacenc/src/pre_echo_control.c
@@ -29,7 +29,7 @@
/*****************************************************************************
*
-* function name:InitPreEchoControl
+* function name:InitPreEchoControl
* description: init pre echo control parameter
*
*****************************************************************************/
@@ -40,13 +40,13 @@
Word16 pb;
for(pb=0; pb<numPb; pb++) {
- pbThresholdNm1[pb] = pbThresholdQuiet[pb];
+ pbThresholdNm1[pb] = pbThresholdQuiet[pb];
}
}
/*****************************************************************************
*
-* function name:PreEchoControl
+* function name:PreEchoControl
* description: update shreshold to avoid pre echo
* thr(n) = max(rpmin*thrq(n), min(thrq(n), rpelev*thrq1(n)))
*
@@ -68,22 +68,22 @@
(void)maxAllowedIncreaseFactor;
scaling = ((mdctScale - mdctScalenm1) << 1);
-
+
if ( scaling > 0 ) {
for(i = 0; i < numPb; i++) {
tmpThreshold1 = pbThresholdNm1[i] >> (scaling-1);
tmpThreshold2 = L_mpy_ls(pbThreshold[i], minRemainingThresholdFactor);
/* copy thresholds to internal memory */
- pbThresholdNm1[i] = pbThreshold[i];
+ pbThresholdNm1[i] = pbThreshold[i];
-
+
if(pbThreshold[i] > tmpThreshold1) {
- pbThreshold[i] = tmpThreshold1;
+ pbThreshold[i] = tmpThreshold1;
}
-
+
if(tmpThreshold2 > pbThreshold[i]) {
- pbThreshold[i] = tmpThreshold2;
+ pbThreshold[i] = tmpThreshold2;
}
}
@@ -96,15 +96,15 @@
tmpThreshold2 = L_mpy_ls(pbThreshold[i], minRemainingThresholdFactor);
/* copy thresholds to internal memory */
- pbThresholdNm1[i] = pbThreshold[i];
+ pbThresholdNm1[i] = pbThreshold[i];
-
+
if(((pbThreshold[i] >> scaling) > tmpThreshold1)) {
pbThreshold[i] = tmpThreshold1 << scaling;
}
-
+
if(tmpThreshold2 > pbThreshold[i]) {
- pbThreshold[i] = tmpThreshold2;
+ pbThreshold[i] = tmpThreshold2;
}
}
diff --git a/media/libstagefright/codecs/aacenc/src/psy_configuration.c b/media/libstagefright/codecs/aacenc/src/psy_configuration.c
index 02d92ab..8e599b0 100644
--- a/media/libstagefright/codecs/aacenc/src/psy_configuration.c
+++ b/media/libstagefright/codecs/aacenc/src/psy_configuration.c
@@ -88,17 +88,17 @@
*
* function name: atan_1000
* description: calculates 1000*atan(x/1000)
-* based on atan approx for x > 0
+* based on atan approx for x > 0
* atan(x) = x/((float)1.0f+(float)0.280872f*x*x) if x < 1
* = pi/2 - x/((float)0.280872f +x*x) if x >= 1
* return: 1000*atan(x/1000)
*
**********************************************************************************/
-static Word16 atan_1000(Word32 val)
+static Word16 atan_1000(Word32 val)
{
Word32 y;
-
+
if(L_sub(val, 1000) < 0) {
y = extract_l(((1000 * val) / (1000 + ((val * val) / ATAN_COEF1))));
}
@@ -126,9 +126,9 @@
/* center frequency of fft line */
center_freq = (fftLine * samplingFreq) / (noOfLines << 1);
temp = atan_1000((center_freq << 2) / (3*10));
- bvalFFTLine =
+ bvalFFTLine =
(26600 * atan_1000((center_freq*76) / 100) + 7*temp*temp) / (2*1000*1000 / BARC_SCALE);
-
+
return saturate(bvalFFTLine);
}
@@ -148,17 +148,17 @@
for(i=0; i<numPb; i++) {
Word16 bv1, bv2;
-
+
if (i>0)
bv1 = (pbBarcVal[i] + pbBarcVal[i-1]) >> 1;
else
bv1 = pbBarcVal[i] >> 1;
-
+
if (i < (numPb - 1))
bv2 = (pbBarcVal[i] + pbBarcVal[i+1]) >> 1;
else {
- bv2 = pbBarcVal[i];
+ bv2 = pbBarcVal[i];
}
bv1 = min((bv1 / BARC_SCALE), max_bark);
@@ -166,9 +166,9 @@
barcThrQuiet = min(BARC_THR_QUIET[bv1], BARC_THR_QUIET[bv2]);
-
+
/*
- we calculate
+ we calculate
pow(10.0f,(float)(barcThrQuiet - ABS_LEV)*0.1)*(float)ABS_LOW*(pbOffset[i+1] - pbOffset[i]);
*/
@@ -196,47 +196,47 @@
Word16 i;
Word16 maskLowSprEn, maskHighSprEn;
-
+
if (sub(blockType, SHORT_WINDOW) != 0) {
- maskLowSprEn = maskLowSprEnLong;
-
+ maskLowSprEn = maskLowSprEnLong;
+
if (bitrate > 22000)
maskHighSprEn = maskHighSprEnLong;
else
maskHighSprEn = maskHighSprEnLongLowBr;
}
else {
- maskLowSprEn = maskLowSprEnShort;
- maskHighSprEn = maskHighSprEnShort;
+ maskLowSprEn = maskLowSprEnShort;
+ maskHighSprEn = maskHighSprEnShort;
}
for(i=0; i<numPb; i++) {
-
+
if (i > 0) {
Word32 dbVal;
Word16 dbark = pbBarcValue[i] - pbBarcValue[i-1];
/*
- we calulate pow(10.0f, -0.1*dbVal/BARC_SCALE)
+ we calulate pow(10.0f, -0.1*dbVal/BARC_SCALE)
*/
dbVal = (maskHigh * dbark);
pbMaskHiFactor[i] = round16(pow2_xy(L_negate(dbVal), (Word32)LOG2_1000)); /* 0.301 log10(2) */
-
+
dbVal = (maskLow * dbark);
- pbMaskLoFactor[i-1] = round16(pow2_xy(L_negate(dbVal),(Word32)LOG2_1000));
-
-
+ pbMaskLoFactor[i-1] = round16(pow2_xy(L_negate(dbVal),(Word32)LOG2_1000));
+
+
dbVal = (maskHighSprEn * dbark);
- pbMaskHiFactorSprEn[i] = round16(pow2_xy(L_negate(dbVal),(Word32)LOG2_1000));
+ pbMaskHiFactorSprEn[i] = round16(pow2_xy(L_negate(dbVal),(Word32)LOG2_1000));
dbVal = (maskLowSprEn * dbark);
pbMaskLoFactorSprEn[i-1] = round16(pow2_xy(L_negate(dbVal),(Word32)LOG2_1000));
}
else {
- pbMaskHiFactor[i] = 0;
- pbMaskLoFactor[numPb-1] = 0;
+ pbMaskHiFactor[i] = 0;
+ pbMaskLoFactor[numPb-1] = 0;
- pbMaskHiFactorSprEn[i] = 0;
- pbMaskLoFactorSprEn[numPb-1] = 0;
+ pbMaskHiFactorSprEn[i] = 0;
+ pbMaskLoFactorSprEn[numPb-1] = 0;
}
}
@@ -258,12 +258,12 @@
Word16 i;
Word16 pbBval0, pbBval1;
- pbBval0 = 0;
+ pbBval0 = 0;
for(i=0; i<numPb; i++){
pbBval1 = BarcLineValue(numLines, pbOffset[i+1], samplingFrequency);
pbBval[i] = (pbBval0 + pbBval1) >> 1;
- pbBval0 = pbBval1;
+ pbBval0 = pbBval1;
}
}
@@ -295,38 +295,38 @@
pePerWindow = bits2pe(extract_l((bitrate * numLines) / samplerate));
- pbVal0 = 0;
+ pbVal0 = 0;
for (sfb=0; sfb<sfbActive; sfb++) {
pbVal1 = (pbBarcVal[sfb] << 1) - pbVal0;
barcWidth = pbVal1 - pbVal0;
- pbVal0 = pbVal1;
+ pbVal0 = pbVal1;
/* allow at least 2.4% of pe for each active barc */
pePart = ((pePerWindow * 24) * (max_bark * barcWidth)) /
(pbBarcVal[sfbActive-1] * (sfbOffset[sfb+1] - sfbOffset[sfb]));
-
-
- pePart = min(pePart, 8400);
+
+
+ pePart = min(pePart, 8400);
pePart = max(pePart, 1400);
/* minSnr(n) = 1/(2^sfbPemin(n)/w(n) - 1.5)*/
/* we add an offset of 2^16 to the pow functions */
/* 0xc000 = 1.5*(1 << 15)*/
-
+
snr = pow2_xy((pePart - 16*1000),1000) - 0x0000c000;
-
+
if(snr > 0x00008000)
{
shift = norm_l(snr);
- snr = Div_32(0x00008000 << shift, snr << shift);
+ snr = Div_32(0x00008000 << shift, snr << shift);
}
else
{
snr = 0x7fffffff;
}
-
+
/* upper limit is -1 dB */
snr = min(snr, c_maxsnr);
/* lower limit is -25 dB */
@@ -354,7 +354,7 @@
/*
init sfb table
*/
- samplerateindex = GetSRIndex(samplerate);
+ samplerateindex = GetSRIndex(samplerate);
psyConf->sfbCnt = sfBandTotalLong[samplerateindex];
psyConf->sfbOffset = sfBandTabLong + sfBandTabLongOffset[samplerateindex];
psyConf->sampRateIdx = samplerateindex;
@@ -391,19 +391,19 @@
/*
init ratio
*/
- psyConf->ratio = c_ratio;
+ psyConf->ratio = c_ratio;
- psyConf->maxAllowedIncreaseFactor = 2;
- psyConf->minRemainingThresholdFactor = c_minRemainingThresholdFactor; /* 0.01 *(1 << 15)*/
+ psyConf->maxAllowedIncreaseFactor = 2;
+ psyConf->minRemainingThresholdFactor = c_minRemainingThresholdFactor; /* 0.01 *(1 << 15)*/
- psyConf->clipEnergy = c_maxClipEnergyLong;
+ psyConf->clipEnergy = c_maxClipEnergyLong;
psyConf->lowpassLine = extract_l((bandwidth<<1) * FRAME_LEN_LONG / samplerate);
for (sfb = 0; sfb < psyConf->sfbCnt; sfb++) {
if (sub(psyConf->sfbOffset[sfb], psyConf->lowpassLine) >= 0)
break;
}
- psyConf->sfbActive = sfb;
+ psyConf->sfbActive = sfb;
/*
calculate minSnr
@@ -429,7 +429,7 @@
Word16 InitPsyConfigurationShort(Word32 bitrate,
Word32 samplerate,
Word16 bandwidth,
- PSY_CONFIGURATION_SHORT *psyConf)
+ PSY_CONFIGURATION_SHORT *psyConf)
{
Word32 samplerateindex;
Word16 sfbBarcVal[MAX_SFB_SHORT];
@@ -437,7 +437,7 @@
/*
init sfb table
*/
- samplerateindex = GetSRIndex(samplerate);
+ samplerateindex = GetSRIndex(samplerate);
psyConf->sfbCnt = sfBandTotalShort[samplerateindex];
psyConf->sfbOffset = sfBandTabShort + sfBandTabShortOffset[samplerateindex];
psyConf->sampRateIdx = samplerateindex;
@@ -473,21 +473,21 @@
/*
init ratio
*/
- psyConf->ratio = c_ratio;
+ psyConf->ratio = c_ratio;
- psyConf->maxAllowedIncreaseFactor = 2;
- psyConf->minRemainingThresholdFactor = c_minRemainingThresholdFactor;
+ psyConf->maxAllowedIncreaseFactor = 2;
+ psyConf->minRemainingThresholdFactor = c_minRemainingThresholdFactor;
- psyConf->clipEnergy = c_maxClipEnergyShort;
+ psyConf->clipEnergy = c_maxClipEnergyShort;
psyConf->lowpassLine = extract_l(((bandwidth << 1) * FRAME_LEN_SHORT) / samplerate);
-
+
for (sfb = 0; sfb < psyConf->sfbCnt; sfb++) {
-
+
if (psyConf->sfbOffset[sfb] >= psyConf->lowpassLine)
break;
}
- psyConf->sfbActive = sfb;
+ psyConf->sfbActive = sfb;
/*
calculate minSnr
diff --git a/media/libstagefright/codecs/aacenc/src/psy_main.c b/media/libstagefright/codecs/aacenc/src/psy_main.c
index 085acb8..3d0a355 100644
--- a/media/libstagefright/codecs/aacenc/src/psy_main.c
+++ b/media/libstagefright/codecs/aacenc/src/psy_main.c
@@ -81,7 +81,7 @@
Word32 *mdctSpectrum;
Word32 *scratchTNS;
Word16 *mdctDelayBuffer;
-
+
mdctSpectrum = (Word32 *)mem_malloc(pMemOP, nChan * FRAME_LEN_LONG * sizeof(Word32), 32, VO_INDEX_ENC_AAC);
if(NULL == mdctSpectrum)
return 1;
@@ -99,7 +99,7 @@
}
for (i=0; i<nChan; i++){
- hPsy->psyData[i].mdctDelayBuffer = mdctDelayBuffer + i*BLOCK_SWITCHING_OFFSET;
+ hPsy->psyData[i].mdctDelayBuffer = mdctDelayBuffer + i*BLOCK_SWITCHING_OFFSET;
hPsy->psyData[i].mdctSpectrum = mdctSpectrum + i*FRAME_LEN_LONG;
}
@@ -124,12 +124,12 @@
{
if(hPsy->psyData[0].mdctDelayBuffer)
mem_free(pMemOP, hPsy->psyData[0].mdctDelayBuffer, VO_INDEX_ENC_AAC);
-
+
if(hPsy->psyData[0].mdctSpectrum)
mem_free(pMemOP, hPsy->psyData[0].mdctSpectrum, VO_INDEX_ENC_AAC);
for (nch=0; nch<MAX_CHANNELS; nch++){
- hPsy->psyData[nch].mdctDelayBuffer = NULL;
+ hPsy->psyData[nch].mdctDelayBuffer = NULL;
hPsy->psyData[nch].mdctSpectrum = NULL;
}
@@ -216,14 +216,14 @@
if (!err)
for(ch=0;ch < channels;ch++){
-
+
InitBlockSwitching(&hPsy->psyData[ch].blockSwitchingControl,
bitRate, channels);
InitPreEchoControl(hPsy->psyData[ch].sfbThresholdnm1,
hPsy->psyConfLong.sfbCnt,
hPsy->psyConfLong.sfbThresholdQuiet);
- hPsy->psyData[ch].mdctScalenm1 = 0;
+ hPsy->psyData[ch].mdctScalenm1 = 0;
}
return(err);
@@ -241,7 +241,7 @@
Word16 psyMain(Word16 nChannels,
ELEMENT_INFO *elemInfo,
- Word16 *timeSignal,
+ Word16 *timeSignal,
PSY_DATA psyData[MAX_CHANNELS],
TNS_DATA tnsData[MAX_CHANNELS],
PSY_CONFIGURATION_LONG *hPsyConfLong,
@@ -260,8 +260,8 @@
Word16 channels;
Word16 maxScale;
- channels = elemInfo->nChannelsInEl;
- maxScale = 0;
+ channels = elemInfo->nChannelsInEl;
+ maxScale = 0;
/* block switching */
for(ch = 0; ch < channels; ch++) {
@@ -291,7 +291,7 @@
/* common scaling for all channels */
for (ch=0; ch<channels; ch++) {
Word16 scaleDiff = maxScale - mdctScalingArray[ch];
-
+
if (scaleDiff > 0) {
Word32 *Spectrum = psyData[ch].mdctSpectrum;
for(line=0; line<FRAME_LEN_LONG; line++) {
@@ -299,11 +299,11 @@
Spectrum++;
}
}
- psyData[ch].mdctScale = maxScale;
+ psyData[ch].mdctScale = maxScale;
}
for (ch=0; ch<channels; ch++) {
-
+
if(psyData[ch].blockSwitchingControl.windowSequence != SHORT_WINDOW) {
/* update long block parameter */
advancePsychLong(&psyData[ch],
@@ -317,7 +317,7 @@
/* determine maxSfb */
for (sfb=hPsyConfLong->sfbCnt-1; sfb>=0; sfb--) {
for (line=hPsyConfLong->sfbOffset[sfb+1] - 1; line>=hPsyConfLong->sfbOffset[sfb]; line--) {
-
+
if (psyData[ch].mdctSpectrum[line] != 0) break;
}
if (line >= hPsyConfLong->sfbOffset[sfb]) break;
@@ -326,7 +326,7 @@
/* Calc bandwise energies for mid and side channel
Do it only if 2 channels exist */
-
+
if (ch == 1)
advancePsychLongMS(psyData, hPsyConfLong);
}
@@ -341,7 +341,7 @@
/* Calc bandwise energies for mid and side channel
Do it only if 2 channels exist */
-
+
if (ch == 1)
advancePsychShortMS (psyData, hPsyConfShort);
}
@@ -349,7 +349,7 @@
/* group short data */
for(ch=0; ch<channels; ch++) {
-
+
if (psyData[ch].blockSwitchingControl.windowSequence == SHORT_WINDOW) {
groupShortData(psyData[ch].mdctSpectrum,
pScratchTns,
@@ -374,10 +374,10 @@
stereo Processing
*/
if (channels == 2) {
- psyOutElement->toolsInfo.msDigest = MS_NONE;
+ psyOutElement->toolsInfo.msDigest = MS_NONE;
maxSfbPerGroup[0] = maxSfbPerGroup[1] = max(maxSfbPerGroup[0], maxSfbPerGroup[1]);
-
+
if (psyData[0].blockSwitchingControl.windowSequence != SHORT_WINDOW)
MsStereoProcessing(psyData[0].sfbEnergy.sfbLong,
psyData[1].sfbEnergy.sfbLong,
@@ -420,7 +420,7 @@
build output
*/
for(ch=0;ch<channels;ch++) {
-
+
if (psyData[ch].blockSwitchingControl.windowSequence != SHORT_WINDOW)
BuildInterface(psyData[ch].mdctSpectrum,
psyData[ch].mdctScale,
@@ -483,7 +483,7 @@
/* low pass */
data0 = psyData->mdctSpectrum + hPsyConfLong->lowpassLine;
for(i=hPsyConfLong->lowpassLine; i<FRAME_LEN_LONG; i++) {
- *data0++ = 0;
+ *data0++ = 0;
}
/* Calc sfb-bandwise mdct-energies for left and right channel */
@@ -505,7 +505,7 @@
psyData->blockSwitchingControl.windowSequence,
psyData->sfbEnergy.sfbLong);
- /* TnsSync */
+ /* TnsSync */
if (ch == 1) {
TnsSync(tnsData,
tnsData2,
@@ -514,7 +514,7 @@
psyData->blockSwitchingControl.windowSequence);
}
- /* Tns Encoder */
+ /* Tns Encoder */
TnsEncode(&psyOutChannel->tnsInfo,
tnsData,
hPsyConfLong->sfbCnt,
@@ -532,15 +532,15 @@
*data1++ = min(tdata, clipEnergy);
}
- /* Calc sfb-bandwise mdct-energies for left and right channel again */
+ /* Calc sfb-bandwise mdct-energies for left and right channel again */
if (tnsData->dataRaw.tnsLong.subBlockInfo.tnsActive!=0) {
- Word16 tnsStartBand = hPsyConfLong->tnsConf.tnsStartBand;
+ Word16 tnsStartBand = hPsyConfLong->tnsConf.tnsStartBand;
CalcBandEnergy( psyData->mdctSpectrum,
hPsyConfLong->sfbOffset+tnsStartBand,
hPsyConfLong->sfbActive - tnsStartBand,
psyData->sfbEnergy.sfbLong+tnsStartBand,
&psyData->sfbEnergySum.sfbLong);
-
+
data0 = psyData->sfbEnergy.sfbLong;
tdata = psyData->sfbEnergySum.sfbLong;
for (i=0; i<tnsStartBand; i++)
@@ -565,13 +565,13 @@
data0++; data1++;
}
- /* preecho control */
+ /* preecho control */
if (psyData->blockSwitchingControl.windowSequence == STOP_WINDOW) {
data0 = psyData->sfbThresholdnm1;
for (i=hPsyConfLong->sfbCnt; i; i--) {
- *data0++ = MAX_32;
+ *data0++ = MAX_32;
}
- psyData->mdctScalenm1 = 0;
+ psyData->mdctScalenm1 = 0;
}
PreEchoControl( psyData->sfbThresholdnm1,
@@ -581,15 +581,15 @@
psyData->sfbThreshold.sfbLong,
psyData->mdctScale,
psyData->mdctScalenm1);
- psyData->mdctScalenm1 = psyData->mdctScale;
+ psyData->mdctScalenm1 = psyData->mdctScale;
-
+
if (psyData->blockSwitchingControl.windowSequence== START_WINDOW) {
data0 = psyData->sfbThresholdnm1;
for (i=hPsyConfLong->sfbCnt; i; i--) {
- *data0++ = MAX_32;
+ *data0++ = MAX_32;
}
- psyData->mdctScalenm1 = 0;
+ psyData->mdctScalenm1 = 0;
}
/* apply tns mult table on cb thresholds */
@@ -603,13 +603,13 @@
data0 = psyData->sfbSpreadedEnergy.sfbLong;
data1 = psyData->sfbEnergy.sfbLong;
for (i=hPsyConfLong->sfbCnt; i; i--) {
- //psyData->sfbSpreadedEnergy.sfbLong[i] = psyData->sfbEnergy.sfbLong[i];
+ //psyData->sfbSpreadedEnergy.sfbLong[i] = psyData->sfbEnergy.sfbLong[i];
*data0++ = *data1++;
}
/* spreading energy */
SpreadingMax(hPsyConfLong->sfbCnt,
- hPsyConfLong->sfbMaskLowFactorSprEn,
+ hPsyConfLong->sfbMaskLowFactorSprEn,
hPsyConfLong->sfbMaskHighFactorSprEn,
psyData->sfbSpreadedEnergy.sfbLong);
@@ -619,7 +619,7 @@
/*****************************************************************************
*
* function name: advancePsychLongMS
-* description: update mdct-energies for left add or minus right channel
+* description: update mdct-energies for left add or minus right channel
* for long block
*
*****************************************************************************/
@@ -657,7 +657,7 @@
Word32 w;
Word32 normEnergyShift = (psyData->mdctScale + 1) << 1; /* in reference code, mdct spectrum must be multipied with 2, so +1 */
Word32 clipEnergy = hPsyConfShort->clipEnergy >> normEnergyShift;
- Word32 wOffset = 0;
+ Word32 wOffset = 0;
Word32 *data0, *data1;
for(w = 0; w < TRANS_FAC; w++) {
@@ -666,7 +666,7 @@
/* low pass */
data0 = psyData->mdctSpectrum + wOffset + hPsyConfShort->lowpassLine;
for(i=hPsyConfShort->lowpassLine; i<FRAME_LEN_SHORT; i++){
- *data0++ = 0;
+ *data0++ = 0;
}
/* Calc sfb-bandwise mdct-energies for left and right channel */
@@ -713,9 +713,9 @@
*data0++ = min(tdata, clipEnergy);
}
- /* Calc sfb-bandwise mdct-energies for left and right channel again */
+ /* Calc sfb-bandwise mdct-energies for left and right channel again */
if (tnsData->dataRaw.tnsShort.subBlockInfo[w].tnsActive != 0) {
- Word16 tnsStartBand = hPsyConfShort->tnsConf.tnsStartBand;
+ Word16 tnsStartBand = hPsyConfShort->tnsConf.tnsStartBand;
CalcBandEnergy( psyData->mdctSpectrum+wOffset,
hPsyConfShort->sfbOffset+tnsStartBand,
(hPsyConfShort->sfbActive - tnsStartBand),
@@ -748,7 +748,7 @@
}
- /* preecho */
+ /* preecho */
PreEchoControl( psyData->sfbThresholdnm1,
hPsyConfShort->sfbCnt,
hPsyConfShort->maxAllowedIncreaseFactor,
@@ -770,14 +770,14 @@
*data0++ = *data1++;
}
SpreadingMax(hPsyConfShort->sfbCnt,
- hPsyConfShort->sfbMaskLowFactorSprEn,
+ hPsyConfShort->sfbMaskLowFactorSprEn,
hPsyConfShort->sfbMaskHighFactorSprEn,
psyData->sfbSpreadedEnergy.sfbShort[w]);
wOffset += FRAME_LEN_SHORT;
} /* for TRANS_FAC */
- psyData->mdctScalenm1 = psyData->mdctScale;
+ psyData->mdctScalenm1 = psyData->mdctScale;
return 0;
}
@@ -785,7 +785,7 @@
/*****************************************************************************
*
* function name: advancePsychShortMS
-* description: update mdct-energies for left add or minus right channel
+* description: update mdct-energies for left add or minus right channel
* for short block
*
*****************************************************************************/
@@ -793,7 +793,7 @@
const PSY_CONFIGURATION_SHORT *hPsyConfShort)
{
Word32 w, wOffset;
- wOffset = 0;
+ wOffset = 0;
for(w=0; w<TRANS_FAC; w++) {
CalcBandEnergyMS(psyData[0].mdctSpectrum+wOffset,
psyData[1].mdctSpectrum+wOffset,
diff --git a/media/libstagefright/codecs/aacenc/src/qc_main.c b/media/libstagefright/codecs/aacenc/src/qc_main.c
index df6d46e..e8c39e4 100644
--- a/media/libstagefright/codecs/aacenc/src/qc_main.c
+++ b/media/libstagefright/codecs/aacenc/src/qc_main.c
@@ -68,12 +68,12 @@
result = (FRAME_LEN_LONG >> 3) * bitRate;
quot = result / sampleRate;
-
+
if (mode == FRAME_LEN_BYTES_MODULO) {
result -= quot * sampleRate;
}
else { /* FRAME_LEN_BYTES_INT */
- result = quot;
+ result = quot;
}
return result;
@@ -83,7 +83,7 @@
*
* function name:framePadding
* description: Calculates if padding is needed for actual frame
-* returns: paddingOn or not
+* returns: paddingOn or not
*
*****************************************************************************/
static Word16 framePadding(Word32 bitRate,
@@ -93,16 +93,16 @@
Word16 paddingOn;
Word16 difference;
- paddingOn = 0;
+ paddingOn = 0;
difference = calcFrameLen( bitRate,
sampleRate,
FRAME_LEN_BYTES_MODULO );
*paddingRest = *paddingRest - difference;
-
+
if (*paddingRest <= 0 ) {
- paddingOn = 1;
+ paddingOn = 1;
*paddingRest = *paddingRest + sampleRate;
}
@@ -123,12 +123,12 @@
Word32 i;
Word16 *quantSpec;
Word16 *scf;
- UWord16 *maxValueInSfb;
-
+ UWord16 *maxValueInSfb;
+
quantSpec = (Word16 *)mem_malloc(pMemOP, nChannels * FRAME_LEN_LONG * sizeof(Word16), 32, VO_INDEX_ENC_AAC);
if(NULL == quantSpec)
return 1;
- scf = (Word16 *)mem_malloc(pMemOP, nChannels * MAX_GROUPED_SFB * sizeof(Word16), 32, VO_INDEX_ENC_AAC);
+ scf = (Word16 *)mem_malloc(pMemOP, nChannels * MAX_GROUPED_SFB * sizeof(Word16), 32, VO_INDEX_ENC_AAC);
if(NULL == scf)
{
return 1;
@@ -141,12 +141,12 @@
for (i=0; i<nChannels; i++) {
hQC->qcChannel[i].quantSpec = quantSpec + i*FRAME_LEN_LONG;
-
+
hQC->qcChannel[i].maxValueInSfb = maxValueInSfb + i*MAX_GROUPED_SFB;
-
+
hQC->qcChannel[i].scf = scf + i*MAX_GROUPED_SFB;
}
-
+
return 0;
}
@@ -165,21 +165,21 @@
{
if(hQC->qcChannel[0].quantSpec);
mem_free(pMemOP, hQC->qcChannel[0].quantSpec, VO_INDEX_ENC_AAC);
-
+
if(hQC->qcChannel[0].maxValueInSfb)
mem_free(pMemOP, hQC->qcChannel[0].maxValueInSfb, VO_INDEX_ENC_AAC);
-
+
if(hQC->qcChannel[0].scf)
mem_free(pMemOP, hQC->qcChannel[0].scf, VO_INDEX_ENC_AAC);
for (i=0; i<MAX_CHANNELS; i++) {
hQC->qcChannel[i].quantSpec = NULL;
-
+
hQC->qcChannel[i].maxValueInSfb = NULL;
-
+
hQC->qcChannel[i].scf = NULL;
}
- }
+ }
}
/*********************************************************************************
@@ -204,8 +204,8 @@
**********************************************************************************/
void QCDelete(QC_STATE *hQC, VO_MEM_OPERATOR *pMemOP)
{
-
- /*
+
+ /*
nothing to do
*/
hQC=NULL;
@@ -221,15 +221,15 @@
Word16 QCInit(QC_STATE *hQC,
struct QC_INIT *init)
{
- hQC->nChannels = init->elInfo->nChannelsInEl;
- hQC->maxBitsTot = init->maxBits;
+ hQC->nChannels = init->elInfo->nChannelsInEl;
+ hQC->maxBitsTot = init->maxBits;
hQC->bitResTot = sub(init->bitRes, init->averageBits);
- hQC->averageBitsTot = init->averageBits;
- hQC->maxBitFac = init->maxBitFac;
+ hQC->averageBitsTot = init->averageBits;
+ hQC->maxBitFac = init->maxBitFac;
- hQC->padding.paddingRest = init->padding.paddingRest;
+ hQC->padding.paddingRest = init->padding.paddingRest;
- hQC->globStatBits = 3; /* for ID_END */
+ hQC->globStatBits = 3; /* for ID_END */
/* channel elements init */
InitElementBits(&hQC->elementBits,
@@ -248,13 +248,13 @@
/*********************************************************************************
-*
+*
* function name: QCMain
* description: quantization and coding the spectrum
* returns: 0 if success
*
**********************************************************************************/
-Word16 QCMain(QC_STATE* hQC,
+Word16 QCMain(QC_STATE* hQC,
ELEMENT_BITS* elBits,
ATS_ELEMENT* adjThrStateElement,
PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS], /* may be modified in-place */
@@ -262,34 +262,34 @@
QC_OUT_CHANNEL qcOutChannel[MAX_CHANNELS], /* out */
QC_OUT_ELEMENT* qcOutElement,
Word16 nChannels,
- Word16 ancillaryDataBytes)
+ Word16 ancillaryDataBytes)
{
Word16 maxChDynBits[MAX_CHANNELS];
- Word16 chBitDistribution[MAX_CHANNELS];
+ Word16 chBitDistribution[MAX_CHANNELS];
Word32 ch;
-
+
if (elBits->bitResLevel < 0) {
return -1;
}
-
+
if (elBits->bitResLevel > elBits->maxBitResBits) {
return -1;
}
qcOutElement->staticBitsUsed = countStaticBitdemand(psyOutChannel,
psyOutElement,
- nChannels,
+ nChannels,
qcOutElement->adtsUsed);
-
+
if (ancillaryDataBytes) {
qcOutElement->ancBitsUsed = 7 + (ancillaryDataBytes << 3);
-
+
if (ancillaryDataBytes >= 15)
qcOutElement->ancBitsUsed = qcOutElement->ancBitsUsed + 8;
}
else {
- qcOutElement->ancBitsUsed = 0;
+ qcOutElement->ancBitsUsed = 0;
}
CalcFormFactor(hQC->logSfbFormFactor, hQC->sfbNRelevantLines, hQC->logSfbEnergy, psyOutChannel, nChannels);
@@ -301,7 +301,7 @@
psyOutElement,
chBitDistribution,
hQC->logSfbEnergy,
- hQC->sfbNRelevantLines,
+ hQC->sfbNRelevantLines,
qcOutElement,
elBits,
nChannels,
@@ -323,14 +323,14 @@
maxChDynBits[ch] = extract_l(chBitDistribution[ch] * maxDynBits / 1000);
}
- qcOutElement->dynBitsUsed = 0;
+ qcOutElement->dynBitsUsed = 0;
for (ch = 0; ch < nChannels; ch++) {
Word32 chDynBits;
Flag constraintsFulfilled;
Word32 iter;
- iter = 0;
+ iter = 0;
do {
- constraintsFulfilled = 1;
+ constraintsFulfilled = 1;
QuantizeSpectrum(psyOutChannel[ch].sfbCnt,
psyOutChannel[ch].maxSfbPerGroup,
@@ -340,14 +340,14 @@
qcOutChannel[ch].globalGain,
qcOutChannel[ch].scf,
qcOutChannel[ch].quantSpec);
-
+
if (calcMaxValueInSfb(psyOutChannel[ch].sfbCnt,
psyOutChannel[ch].maxSfbPerGroup,
psyOutChannel[ch].sfbPerGroup,
psyOutChannel[ch].sfbOffsets,
qcOutChannel[ch].quantSpec,
qcOutChannel[ch].maxValueInSfb) > MAX_QUANT) {
- constraintsFulfilled = 0;
+ constraintsFulfilled = 0;
}
chDynBits = dynBitCount(qcOutChannel[ch].quantSpec,
@@ -359,24 +359,24 @@
psyOutChannel[ch].sfbPerGroup,
psyOutChannel[ch].sfbOffsets,
&qcOutChannel[ch].sectionData);
-
+
if (chDynBits >= maxChDynBits[ch]) {
- constraintsFulfilled = 0;
+ constraintsFulfilled = 0;
}
-
+
if (!constraintsFulfilled) {
qcOutChannel[ch].globalGain = qcOutChannel[ch].globalGain + 1;
}
iter = iter + 1;
-
+
} while(!constraintsFulfilled);
qcOutElement->dynBitsUsed = qcOutElement->dynBitsUsed + chDynBits;
- qcOutChannel[ch].mdctScale = psyOutChannel[ch].mdctScale;
- qcOutChannel[ch].groupingMask = psyOutChannel[ch].groupingMask;
- qcOutChannel[ch].windowShape = psyOutChannel[ch].windowShape;
+ qcOutChannel[ch].mdctScale = psyOutChannel[ch].mdctScale;
+ qcOutChannel[ch].groupingMask = psyOutChannel[ch].groupingMask;
+ qcOutChannel[ch].windowShape = psyOutChannel[ch].windowShape;
}
/* save dynBitsUsed for correction of bits2pe relation */
@@ -411,13 +411,13 @@
Word16 sfbOffs, sfb;
Word16 maxValueAll;
- maxValueAll = 0;
+ maxValueAll = 0;
for(sfbOffs=0;sfbOffs<sfbCnt;sfbOffs+=sfbPerGroup) {
for (sfb = 0; sfb < maxSfbPerGroup; sfb++) {
Word16 line;
Word16 maxThisSfb;
- maxThisSfb = 0;
+ maxThisSfb = 0;
for (line = sfbOffset[sfbOffs+sfb]; line < sfbOffset[sfbOffs+sfb+1]; line++) {
Word16 absVal;
@@ -425,7 +425,7 @@
maxThisSfb = max(maxThisSfb, absVal);
}
- maxValue[sfbOffs+sfb] = maxThisSfb;
+ maxValue[sfbOffs+sfb] = maxThisSfb;
maxValueAll = max(maxValueAll, maxThisSfb);
}
}
@@ -441,15 +441,15 @@
**********************************************************************************/
void updateBitres(QC_STATE* qcKernel,
QC_OUT* qcOut)
-
+
{
ELEMENT_BITS *elBits;
-
- qcKernel->bitResTot = 0;
+
+ qcKernel->bitResTot = 0;
elBits = &qcKernel->elementBits;
-
+
if (elBits->averageBits > 0) {
/* constant bitrate */
Word16 bitsUsed;
@@ -460,8 +460,8 @@
}
else {
/* variable bitrate */
- elBits->bitResLevel = elBits->maxBits;
- qcKernel->bitResTot = qcKernel->maxBitsTot;
+ elBits->bitResLevel = elBits->maxBits;
+ qcKernel->bitResTot = qcKernel->maxBitsTot;
}
}
@@ -476,55 +476,55 @@
{
Word32 nFullFillElem;
Word32 totFillBits;
- Word16 diffBits;
+ Word16 diffBits;
Word16 bitsUsed;
- totFillBits = 0;
+ totFillBits = 0;
- qcOut->totStaticBitsUsed = qcKernel->globStatBits;
+ qcOut->totStaticBitsUsed = qcKernel->globStatBits;
qcOut->totStaticBitsUsed += qcOut->qcElement.staticBitsUsed;
qcOut->totDynBitsUsed = qcOut->qcElement.dynBitsUsed;
qcOut->totAncBitsUsed = qcOut->qcElement.ancBitsUsed;
qcOut->totFillBits = qcOut->qcElement.fillBits;
-
+
if (qcOut->qcElement.fillBits) {
totFillBits += qcOut->qcElement.fillBits;
}
nFullFillElem = (max((qcOut->totFillBits - 1), 0) / maxFillElemBits) * maxFillElemBits;
-
+
qcOut->totFillBits = qcOut->totFillBits - nFullFillElem;
/* check fill elements */
-
+
if (qcOut->totFillBits > 0) {
/* minimum Fillelement contains 7 (TAG + byte cnt) bits */
qcOut->totFillBits = max(7, qcOut->totFillBits);
/* fill element size equals n*8 + 7 */
- qcOut->totFillBits = qcOut->totFillBits + ((8 - ((qcOut->totFillBits - 7) & 0x0007)) & 0x0007);
+ qcOut->totFillBits = qcOut->totFillBits + ((8 - ((qcOut->totFillBits - 7) & 0x0007)) & 0x0007);
}
qcOut->totFillBits = qcOut->totFillBits + nFullFillElem;
/* now distribute extra fillbits and alignbits over channel elements */
qcOut->alignBits = 7 - ((qcOut->totDynBitsUsed + qcOut->totStaticBitsUsed +
- qcOut->totAncBitsUsed + qcOut->totFillBits - 1) & 0x0007);
+ qcOut->totAncBitsUsed + qcOut->totFillBits - 1) & 0x0007);
-
+
if ( (qcOut->alignBits + qcOut->totFillBits - totFillBits == 8) &&
(qcOut->totFillBits > 8))
qcOut->totFillBits = qcOut->totFillBits - 8;
-
+
diffBits = qcOut->alignBits + qcOut->totFillBits - totFillBits;
-
+
if(diffBits>=0) {
qcOut->qcElement.fillBits += diffBits;
}
bitsUsed = qcOut->totDynBitsUsed + qcOut->totStaticBitsUsed + qcOut->totAncBitsUsed;
bitsUsed = bitsUsed + qcOut->totFillBits + qcOut->alignBits;
-
+
if (bitsUsed > qcKernel->maxBitsTot) {
return -1;
}
@@ -564,9 +564,9 @@
codeBitsLast = hQC->averageBitsTot - hQC->globStatBits;
codeBits = frameLen - hQC->globStatBits;
- /* calculate bits for every channel element */
+ /* calculate bits for every channel element */
if (codeBits != codeBitsLast) {
- Word16 totalBits = 0;
+ Word16 totalBits = 0;
hQC->elementBits.averageBits = (hQC->elementBits.relativeBits * codeBits) >> 16; /* relativeBits was scaled down by 2 */
totalBits += hQC->elementBits.averageBits;
@@ -574,7 +574,7 @@
hQC->elementBits.averageBits = hQC->elementBits.averageBits + (codeBits - totalBits);
}
- hQC->averageBitsTot = frameLen;
+ hQC->averageBitsTot = frameLen;
return 0;
}
diff --git a/media/libstagefright/codecs/aacenc/src/quantize.c b/media/libstagefright/codecs/aacenc/src/quantize.c
index 54add2f..973554e 100644
--- a/media/libstagefright/codecs/aacenc/src/quantize.c
+++ b/media/libstagefright/codecs/aacenc/src/quantize.c
@@ -34,32 +34,32 @@
/*****************************************************************************
*
-* function name:pow34
-* description: calculate $x^{\frac{3}{4}}, for 0.5 < x < 1.0$.
+* function name:pow34
+* description: calculate $x^{\frac{3}{4}}, for 0.5 < x < 1.0$.
*
*****************************************************************************/
__inline Word32 pow34(Word32 x)
{
/* index table using MANT_DIGITS bits, but mask out the sign bit and the MSB
- which is always one */
+ which is always one */
return mTab_3_4[(x >> (INT_BITS-2-MANT_DIGITS)) & (MANT_SIZE-1)];
}
/*****************************************************************************
*
-* function name:quantizeSingleLine
-* description: quantizes spectrum
-* quaSpectrum = mdctSpectrum^3/4*2^(-(3/16)*gain)
+* function name:quantizeSingleLine
+* description: quantizes spectrum
+* quaSpectrum = mdctSpectrum^3/4*2^(-(3/16)*gain)
*
*****************************************************************************/
static Word16 quantizeSingleLine(const Word16 gain, const Word32 absSpectrum)
{
Word32 e, minusFinalExp, finalShift;
Word32 x;
- Word16 qua = 0;
+ Word16 qua = 0;
-
+
if (absSpectrum) {
e = norm_l(absSpectrum);
x = pow34(absSpectrum << e);
@@ -71,7 +71,7 @@
/* separate the exponent into a shift, and a multiply */
finalShift = minusFinalExp >> 4;
-
+
if (finalShift < INT_BITS) {
x = L_mpy_wx(x, pow2tominusNover16[minusFinalExp & 15]);
@@ -84,7 +84,7 @@
x >>= finalShift;
else
x <<= (-finalShift);
-
+
qua = saturate(x);
}
}
@@ -94,10 +94,10 @@
/*****************************************************************************
*
-* function name:quantizeLines
-* description: quantizes spectrum lines
-* quaSpectrum = mdctSpectrum^3/4*2^(-(3/16)*gain)
-* input: global gain, number of lines to process, spectral data
+* function name:quantizeLines
+* description: quantizes spectrum lines
+* quaSpectrum = mdctSpectrum^3/4*2^(-(3/16)*gain)
+* input: global gain, number of lines to process, spectral data
* output: quantized spectrum
*
*****************************************************************************/
@@ -116,15 +116,15 @@
pquat = quantBorders[m];
g += 16;
-
+
if(g >= 0)
{
for (line=0; line<noOfLines; line++) {
Word32 qua;
- qua = 0;
-
+ qua = 0;
+
mdctSpeL = mdctSpectrum[line];
-
+
if (mdctSpeL) {
Word32 sa;
Word32 saShft;
@@ -134,27 +134,27 @@
saShft = sa >> g;
if (saShft > pquat[0]) {
-
+
if (saShft < pquat[1]) {
-
+
qua = mdctSpeL>0 ? 1 : -1;
}
else {
-
+
if (saShft < pquat[2]) {
-
+
qua = mdctSpeL>0 ? 2 : -2;
}
else {
-
+
if (saShft < pquat[3]) {
-
+
qua = mdctSpeL>0 ? 3 : -3;
}
else {
qua = quantizeSingleLine(gain, sa);
/* adjust the sign. Since 0 < qua < 1, this cannot overflow. */
-
+
if (mdctSpeL < 0)
qua = -qua;
}
@@ -162,17 +162,17 @@
}
}
}
- quaSpectrum[line] = qua ;
+ quaSpectrum[line] = qua ;
}
}
else
{
for (line=0; line<noOfLines; line++) {
Word32 qua;
- qua = 0;
-
+ qua = 0;
+
mdctSpeL = mdctSpectrum[line];
-
+
if (mdctSpeL) {
Word32 sa;
Word32 saShft;
@@ -181,27 +181,27 @@
saShft = sa << g;
if (saShft > pquat[0]) {
-
+
if (saShft < pquat[1]) {
-
+
qua = mdctSpeL>0 ? 1 : -1;
}
else {
-
+
if (saShft < pquat[2]) {
-
+
qua = mdctSpeL>0 ? 2 : -2;
}
else {
-
+
if (saShft < pquat[3]) {
-
+
qua = mdctSpeL>0 ? 3 : -3;
}
else {
qua = quantizeSingleLine(gain, sa);
/* adjust the sign. Since 0 < qua < 1, this cannot overflow. */
-
+
if (mdctSpeL < 0)
qua = -qua;
}
@@ -209,8 +209,8 @@
}
}
}
- quaSpectrum[line] = qua ;
- }
+ quaSpectrum[line] = qua ;
+ }
}
}
@@ -218,10 +218,10 @@
/*****************************************************************************
*
-* function name:iquantizeLines
+* function name:iquantizeLines
* description: iquantizes spectrum lines without sign
-* mdctSpectrum = iquaSpectrum^4/3 *2^(0.25*gain)
-* input: global gain, number of lines to process,quantized spectrum
+* mdctSpectrum = iquaSpectrum^4/3 *2^(0.25*gain)
+* input: global gain, number of lines to process,quantized spectrum
* output: spectral data
*
*****************************************************************************/
@@ -234,11 +234,11 @@
Word32 iquantizershift;
Word32 line;
- iquantizermod = gain & 3;
+ iquantizermod = gain & 3;
iquantizershift = gain >> 2;
for (line=0; line<noOfLines; line++) {
-
+
if( quantSpectrum[line] != 0 ) {
Word32 accu;
Word32 ex;
@@ -252,19 +252,19 @@
accu = accu << ex;
specExp = INT_BITS-1 - ex;
- tabIndex = (accu >> (INT_BITS-2-MANT_DIGITS)) & (~MANT_SIZE);
+ tabIndex = (accu >> (INT_BITS-2-MANT_DIGITS)) & (~MANT_SIZE);
/* calculate "mantissa" ^4/3 */
- s = mTab_4_3[tabIndex];
+ s = mTab_4_3[tabIndex];
/* get approperiate exponent multiplier for specExp^3/4 combined with scfMod */
- t = specExpMantTableComb_enc[iquantizermod][specExp];
+ t = specExpMantTableComb_enc[iquantizermod][specExp];
/* multiply "mantissa" ^4/3 with exponent multiplier */
accu = MULHIGH(s, t);
/* get approperiate exponent shifter */
- specExp = specExpTableComb_enc[iquantizermod][specExp];
+ specExp = specExpTableComb_enc[iquantizermod][specExp];
specExp += iquantizershift + 1;
if(specExp >= 0)
@@ -273,7 +273,7 @@
mdctSpectrum[line] = accu >> (-specExp);
}
else {
- mdctSpectrum[line] = 0;
+ mdctSpectrum[line] = 0;
}
}
}
@@ -301,7 +301,7 @@
for(sfbOffs=0;sfbOffs<sfbCnt;sfbOffs+=sfbPerGroup) {
Word32 sfbNext ;
for (sfb = 0; sfb < maxSfbPerGroup; sfb = sfbNext) {
- Word16 scalefactor = scalefactors[sfbOffs+sfb];
+ Word16 scalefactor = scalefactors[sfbOffs+sfb];
/* coalesce sfbs with the same scalefactor */
for (sfbNext = sfb+1;
sfbNext < maxSfbPerGroup && scalefactor == scalefactors[sfbOffs+sfbNext];
@@ -318,7 +318,7 @@
/*****************************************************************************
*
-* function name:calcSfbDist
+* function name:calcSfbDist
* description: quantizes and requantizes lines to calculate distortion
* input: number of lines to be quantized, ...
* output: distortion
@@ -338,14 +338,14 @@
pquat = quantBorders[m];
repquat = quantRecon[m];
-
- dist = 0;
+
+ dist = 0;
g += 16;
if(g2 < 0 && g >= 0)
- {
+ {
g2 = -g2;
- for(line=0; line<sfbWidth; line++) {
- if (spec[line]) {
+ for(line=0; line<sfbWidth; line++) {
+ if (spec[line]) {
Word32 diff;
Word32 distSingle;
Word32 sa;
@@ -359,19 +359,19 @@
distSingle = (saShft * saShft) >> g2;
}
else {
-
+
if (saShft < pquat[1]) {
diff = saShft - repquat[0];
distSingle = (diff * diff) >> g2;
}
else {
-
+
if (saShft < pquat[2]) {
diff = saShft - repquat[1];
distSingle = (diff * diff) >> g2;
}
else {
-
+
if (saShft < pquat[3]) {
diff = saShft - repquat[2];
distSingle = (diff * diff) >> g2;
@@ -387,15 +387,15 @@
}
}
}
-
+
dist = L_add(dist, distSingle);
}
}
}
else
{
- for(line=0; line<sfbWidth; line++) {
- if (spec[line]) {
+ for(line=0; line<sfbWidth; line++) {
+ if (spec[line]) {
Word32 diff;
Word32 distSingle;
Word32 sa;
@@ -408,19 +408,19 @@
distSingle = L_shl((saShft * saShft), g2);
}
else {
-
+
if (saShft < pquat[1]) {
diff = saShft - repquat[0];
distSingle = L_shl((diff * diff), g2);
}
else {
-
+
if (saShft < pquat[2]) {
diff = saShft - repquat[1];
distSingle = L_shl((diff * diff), g2);
}
else {
-
+
if (saShft < pquat[3]) {
diff = saShft - repquat[2];
distSingle = L_shl((diff * diff), g2);
@@ -438,7 +438,7 @@
}
dist = L_add(dist, distSingle);
}
- }
+ }
}
return dist;
diff --git a/media/libstagefright/codecs/aacenc/src/sf_estim.c b/media/libstagefright/codecs/aacenc/src/sf_estim.c
index fe40137..ffe2e83 100644
--- a/media/libstagefright/codecs/aacenc/src/sf_estim.c
+++ b/media/libstagefright/codecs/aacenc/src/sf_estim.c
@@ -30,17 +30,17 @@
static const Word16 MAX_SCF_DELTA = 60;
/*!
-constants reference in comments
+constants reference in comments
C0 = 6.75f;
- C1 = -69.33295f; -16/3*log(MAX_QUANT+0.5-logCon)/log(2)
+ C1 = -69.33295f; -16/3*log(MAX_QUANT+0.5-logCon)/log(2)
C2 = 4.0f;
C3 = 2.66666666f;
-
- PE_C1 = 3.0f; log(8.0)/log(2)
- PE_C2 = 1.3219281f; log(2.5)/log(2)
- PE_C3 = 0.5593573f; 1-C2/C1
-
+
+ PE_C1 = 3.0f; log(8.0)/log(2)
+ PE_C2 = 1.3219281f; log(2.5)/log(2)
+ PE_C3 = 0.5593573f; 1-C2/C1
+
*/
#define FF_SQRT_BITS 7
@@ -55,15 +55,15 @@
/*********************************************************************************
*
* function name: formfac_sqrt
-* description: calculates sqrt(x)/256
+* description: calculates sqrt(x)/256
*
**********************************************************************************/
__inline Word32 formfac_sqrt(Word32 x)
{
Word32 y;
Word32 preshift, postshift;
-
-
+
+
if (x==0) return 0;
preshift = norm_l(x) - (INT_BITS-1-FF_SQRT_BITS);
postshift = preshift >> 1;
@@ -74,12 +74,12 @@
else
y = x >> (-preshift);
y = formfac_sqrttable[y-32];
-
+
if(postshift >= 0)
y = y >> postshift;
else
y = y << (-postshift);
-
+
return y;
}
@@ -100,19 +100,19 @@
Word32 sfbw, sfbw1;
Word32 i, j;
Word32 sfbOffs, sfb, shift;
-
+
sfbw = sfbw1 = 0;
for (sfbOffs=0; sfbOffs<psyOutChan->sfbCnt; sfbOffs+=psyOutChan->sfbPerGroup){
for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
- i = sfbOffs+sfb;
-
+ i = sfbOffs+sfb;
+
if (psyOutChan->sfbEnergy[i] > psyOutChan->sfbThreshold[i]) {
Word32 accu, avgFormFactor,iSfbWidth;
Word32 *mdctSpec;
sfbw = psyOutChan->sfbOffsets[i+1] - psyOutChan->sfbOffsets[i];
iSfbWidth = invSBF[(sfbw >> 2) - 1];
mdctSpec = psyOutChan->mdctSpectrum + psyOutChan->sfbOffsets[i];
- accu = 0;
+ accu = 0;
/* calc sum of sqrt(spec) */
for (j=sfbw; j; j--) {
accu += formfac_sqrt(L_abs(*mdctSpec)); mdctSpec++;
@@ -129,7 +129,7 @@
}
else {
/* set number of lines to zero */
- sfbNRelevantLines[i] = 0;
+ sfbNRelevantLines[i] = 0;
}
}
}
@@ -141,68 +141,68 @@
* description: find better scalefactor with analysis by synthesis
*
**********************************************************************************/
-static Word16 improveScf(Word32 *spec,
- Word16 sfbWidth,
- Word32 thresh,
+static Word16 improveScf(Word32 *spec,
+ Word16 sfbWidth,
+ Word32 thresh,
Word16 scf,
Word16 minScf,
- Word32 *dist,
+ Word32 *dist,
Word16 *minScfCalculated)
{
Word32 cnt;
Word32 sfbDist;
Word32 scfBest;
Word32 thresh125 = L_add(thresh, (thresh >> 2));
-
- scfBest = scf;
-
+
+ scfBest = scf;
+
/* calc real distortion */
sfbDist = calcSfbDist(spec, sfbWidth, scf);
- *minScfCalculated = scf;
+ *minScfCalculated = scf;
if(!sfbDist)
return scfBest;
-
+
if (sfbDist > thresh125) {
Word32 scfEstimated;
Word32 sfbDistBest;
- scfEstimated = scf;
- sfbDistBest = sfbDist;
-
- cnt = 0;
+ scfEstimated = scf;
+ sfbDistBest = sfbDist;
+
+ cnt = 0;
while (sfbDist > thresh125 && (cnt < 3)) {
-
+
scf = scf + 1;
sfbDist = calcSfbDist(spec, sfbWidth, scf);
-
+
if (sfbDist < sfbDistBest) {
- scfBest = scf;
- sfbDistBest = sfbDist;
+ scfBest = scf;
+ sfbDistBest = sfbDist;
}
cnt = cnt + 1;
}
- cnt = 0;
- scf = scfEstimated;
- sfbDist = sfbDistBest;
+ cnt = 0;
+ scf = scfEstimated;
+ sfbDist = sfbDistBest;
while ((sfbDist > thresh125) && (cnt < 1) && (scf > minScf)) {
-
+
scf = scf - 1;
sfbDist = calcSfbDist(spec, sfbWidth, scf);
-
+
if (sfbDist < sfbDistBest) {
- scfBest = scf;
- sfbDistBest = sfbDist;
+ scfBest = scf;
+ sfbDistBest = sfbDist;
}
- *minScfCalculated = scf;
+ *minScfCalculated = scf;
cnt = cnt + 1;
}
- *dist = sfbDistBest;
+ *dist = sfbDistBest;
}
else {
- Word32 sfbDistBest;
+ Word32 sfbDistBest;
Word32 sfbDistAllowed;
Word32 thresh08 = fixmul(COEF08_31, thresh);
- sfbDistBest = sfbDist;
-
+ sfbDistBest = sfbDist;
+
if (sfbDist < thresh08)
sfbDistAllowed = sfbDist;
else
@@ -210,16 +210,16 @@
for (cnt=0; cnt<3; cnt++) {
scf = scf + 1;
sfbDist = calcSfbDist(spec, sfbWidth, scf);
-
+
if (fixmul(COEF08_31,sfbDist) < sfbDistAllowed) {
*minScfCalculated = scfBest + 1;
- scfBest = scf;
- sfbDistBest = sfbDist;
+ scfBest = scf;
+ sfbDistBest = sfbDist;
}
}
- *dist = sfbDistBest;
+ *dist = sfbDistBest;
}
-
+
/* return best scalefactor */
return scfBest;
}
@@ -233,10 +233,10 @@
static Word16 countSingleScfBits(Word16 scf, Word16 scfLeft, Word16 scfRight)
{
Word16 scfBits;
-
+
scfBits = bitCountScalefactorDelta(scfLeft - scf) +
bitCountScalefactorDelta(scf - scfRight);
-
+
return scfBits;
}
@@ -245,7 +245,7 @@
* function name: calcSingleSpecPe
* description: ldRatio = log2(en(n)) - 0,375*scfGain(n)
* nbits = 0.7*nLines*ldRation for ldRation >= c1
-* nbits = 0.7*nLines*(c2 + c3*ldRatio) for ldRation < c1
+* nbits = 0.7*nLines*(c2 + c3*ldRatio) for ldRation < c1
*
**********************************************************************************/
static Word16 calcSingleSpecPe(Word16 scf, Word16 sfbConstPePart, Word16 nLines)
@@ -253,18 +253,18 @@
Word32 specPe;
Word32 ldRatio;
Word32 scf3;
-
+
ldRatio = sfbConstPePart << 3; /* (sfbConstPePart -0.375*scf)*8 */
scf3 = scf + scf + scf;
ldRatio = ldRatio - scf3;
-
+
if (ldRatio < PE_C1_8) {
- /* 21 : 2*8*PE_C2, 2*PE_C3 ~ 1*/
+ /* 21 : 2*8*PE_C2, 2*PE_C3 ~ 1*/
ldRatio = (ldRatio + PE_C2_16) >> 1;
}
specPe = nLines * ldRatio;
specPe = (specPe * PE_SCALE) >> 14;
-
+
return saturate(specPe);
}
@@ -275,53 +275,53 @@
* description: count different scf bits used
*
**********************************************************************************/
-static Word16 countScfBitsDiff(Word16 *scfOld, Word16 *scfNew,
+static Word16 countScfBitsDiff(Word16 *scfOld, Word16 *scfNew,
Word16 sfbCnt, Word16 startSfb, Word16 stopSfb)
{
Word32 scfBitsDiff;
Word32 sfb, sfbLast;
Word32 sfbPrev, sfbNext;
-
- scfBitsDiff = 0;
- sfb = 0;
-
+
+ scfBitsDiff = 0;
+ sfb = 0;
+
/* search for first relevant sfb */
- sfbLast = startSfb;
+ sfbLast = startSfb;
while (sfbLast < stopSfb && scfOld[sfbLast] == VOAAC_SHRT_MIN) {
-
+
sfbLast = sfbLast + 1;
}
/* search for previous relevant sfb and count diff */
sfbPrev = startSfb - 1;
while ((sfbPrev>=0) && scfOld[sfbPrev] == VOAAC_SHRT_MIN) {
-
+
sfbPrev = sfbPrev - 1;
}
-
+
if (sfbPrev>=0) {
scfBitsDiff += bitCountScalefactorDelta(scfNew[sfbPrev] - scfNew[sfbLast]) -
bitCountScalefactorDelta(scfOld[sfbPrev] - scfOld[sfbLast]);
}
/* now loop through all sfbs and count diffs of relevant sfbs */
for (sfb=sfbLast+1; sfb<stopSfb; sfb++) {
-
+
if (scfOld[sfb] != VOAAC_SHRT_MIN) {
scfBitsDiff += bitCountScalefactorDelta(scfNew[sfbLast] - scfNew[sfb]) -
bitCountScalefactorDelta(scfOld[sfbLast] - scfOld[sfb]);
- sfbLast = sfb;
+ sfbLast = sfb;
}
}
/* search for next relevant sfb and count diff */
- sfbNext = stopSfb;
+ sfbNext = stopSfb;
while (sfbNext < sfbCnt && scfOld[sfbNext] == VOAAC_SHRT_MIN) {
-
+
sfbNext = sfbNext + 1;
}
-
+
if (sfbNext < sfbCnt)
scfBitsDiff += bitCountScalefactorDelta(scfNew[sfbLast] - scfNew[sfbNext]) -
bitCountScalefactorDelta(scfOld[sfbLast] - scfOld[sfbNext]);
-
+
return saturate(scfBitsDiff);
}
@@ -331,52 +331,52 @@
Word16 *logSfbEnergy,
Word16 *logSfbFormFactor,
Word16 *sfbNRelevantLines,
- Word16 startSfb,
+ Word16 startSfb,
Word16 stopSfb)
{
Word32 specPeDiff;
Word32 sfb;
-
- specPeDiff = 0;
-
+
+ specPeDiff = 0;
+
/* loop through all sfbs and count pe difference */
for (sfb=startSfb; sfb<stopSfb; sfb++) {
-
-
+
+
if (scfOld[sfb] != VOAAC_SHRT_MIN) {
Word32 ldRatioOld, ldRatioNew;
Word32 scf3;
-
-
+
+
if (sfbConstPePart[sfb] == MIN_16) {
sfbConstPePart[sfb] = ((logSfbEnergy[sfb] -
logSfbFormFactor[sfb]) + 11-8*4+3) >> 2;
}
-
-
+
+
ldRatioOld = sfbConstPePart[sfb] << 3;
scf3 = scfOld[sfb] + scfOld[sfb] + scfOld[sfb];
ldRatioOld = ldRatioOld - scf3;
ldRatioNew = sfbConstPePart[sfb] << 3;
scf3 = scfNew[sfb] + scfNew[sfb] + scfNew[sfb];
ldRatioNew = ldRatioNew - scf3;
-
+
if (ldRatioOld < PE_C1_8) {
/* 21 : 2*8*PE_C2, 2*PE_C3 ~ 1*/
ldRatioOld = (ldRatioOld + PE_C2_16) >> 1;
}
-
+
if (ldRatioNew < PE_C1_8) {
/* 21 : 2*8*PE_C2, 2*PE_C3 ~ 1*/
ldRatioNew = (ldRatioNew + PE_C2_16) >> 1;
}
-
+
specPeDiff += sfbNRelevantLines[sfb] * (ldRatioNew - ldRatioOld);
}
}
-
+
specPeDiff = (specPeDiff * PE_SCALE) >> 14;
-
+
return saturate(specPeDiff);
}
@@ -390,9 +390,9 @@
*
**********************************************************************************/
static void assimilateSingleScf(PSY_OUT_CHANNEL *psyOutChan,
- Word16 *scf,
+ Word16 *scf,
Word16 *minScf,
- Word32 *sfbDist,
+ Word32 *sfbDist,
Word16 *sfbConstPePart,
Word16 *logSfbEnergy,
Word16 *logSfbFormFactor,
@@ -411,94 +411,94 @@
Word16 *prevScfNext = psyOutChan->prevScfNext;
Word16 *deltaPeLast = psyOutChan->deltaPeLast;
Flag updateMinScfCalculated;
-
- success = 0;
- deltaPe = 0;
-
+
+ success = 0;
+ deltaPe = 0;
+
for(j=0;j<psyOutChan->sfbCnt;j++){
- prevScfLast[j] = MAX_16;
- prevScfNext[j] = MAX_16;
- deltaPeLast[j] = MAX_16;
+ prevScfLast[j] = MAX_16;
+ prevScfNext[j] = MAX_16;
+ deltaPeLast[j] = MAX_16;
}
-
- sfbLast = -1;
- sfbAct = -1;
- sfbNext = -1;
+
+ sfbLast = -1;
+ sfbAct = -1;
+ sfbNext = -1;
scfLast = 0;
scfNext = 0;
- scfMin = MAX_16;
+ scfMin = MAX_16;
do {
/* search for new relevant sfb */
sfbNext = sfbNext + 1;
while (sfbNext < psyOutChan->sfbCnt && scf[sfbNext] == MIN_16) {
-
+
sfbNext = sfbNext + 1;
}
-
+
if ((sfbLast>=0) && (sfbAct>=0) && sfbNext < psyOutChan->sfbCnt) {
/* relevant scfs to the left and to the right */
- scfAct = scf[sfbAct];
+ scfAct = scf[sfbAct];
scfLast = scf + sfbLast;
scfNext = scf + sfbNext;
scfMin = min(*scfLast, *scfNext);
}
else {
-
+
if (sfbLast == -1 && (sfbAct>=0) && sfbNext < psyOutChan->sfbCnt) {
/* first relevant scf */
- scfAct = scf[sfbAct];
+ scfAct = scf[sfbAct];
scfLast = &scfAct;
scfNext = scf + sfbNext;
- scfMin = *scfNext;
+ scfMin = *scfNext;
}
else {
-
+
if ((sfbLast>=0) && (sfbAct>=0) && sfbNext == psyOutChan->sfbCnt) {
/* last relevant scf */
- scfAct = scf[sfbAct];
+ scfAct = scf[sfbAct];
scfLast = scf + sfbLast;
scfNext = &scfAct;
- scfMin = *scfLast;
+ scfMin = *scfLast;
}
}
}
-
+
if (sfbAct>=0)
scfMin = max(scfMin, minScf[sfbAct]);
-
- if ((sfbAct >= 0) &&
- (sfbLast>=0 || sfbNext < psyOutChan->sfbCnt) &&
- scfAct > scfMin &&
- (*scfLast != prevScfLast[sfbAct] ||
- *scfNext != prevScfNext[sfbAct] ||
+
+ if ((sfbAct >= 0) &&
+ (sfbLast>=0 || sfbNext < psyOutChan->sfbCnt) &&
+ scfAct > scfMin &&
+ (*scfLast != prevScfLast[sfbAct] ||
+ *scfNext != prevScfNext[sfbAct] ||
deltaPe < deltaPeLast[sfbAct])) {
- success = 0;
-
- /* estimate required bits for actual scf */
+ success = 0;
+
+ /* estimate required bits for actual scf */
if (sfbConstPePart[sfbAct] == MIN_16) {
sfbConstPePart[sfbAct] = logSfbEnergy[sfbAct] -
logSfbFormFactor[sfbAct] + 11-8*4; /* 4*log2(6.75) - 32 */
-
+
if (sfbConstPePart[sfbAct] < 0)
sfbConstPePart[sfbAct] = sfbConstPePart[sfbAct] + 3;
sfbConstPePart[sfbAct] = sfbConstPePart[sfbAct] >> 2;
}
-
+
sfbPeOld = calcSingleSpecPe(scfAct, sfbConstPePart[sfbAct], sfbNRelevantLines[sfbAct]) +
countSingleScfBits(scfAct, *scfLast, *scfNext);
- deltaPeNew = deltaPe;
- updateMinScfCalculated = 1;
+ deltaPeNew = deltaPe;
+ updateMinScfCalculated = 1;
do {
scfAct = scfAct - 1;
/* check only if the same check was not done before */
-
+
if (scfAct < minScfCalculated[sfbAct]) {
sfbPeNew = calcSingleSpecPe(scfAct, sfbConstPePart[sfbAct], sfbNRelevantLines[sfbAct]) +
countSingleScfBits(scfAct, *scfLast, *scfNext);
- /* use new scf if no increase in pe and
+ /* use new scf if no increase in pe and
quantization error is smaller */
deltaPeTmp = deltaPe + sfbPeNew - sfbPeOld;
-
+
if (deltaPeTmp < 10) {
sfbDistNew = calcSfbDist(psyOutChan->mdctSpectrum+
psyOutChan->sfbOffsets[sfbAct],
@@ -506,46 +506,46 @@
scfAct);
if (sfbDistNew < sfbDist[sfbAct]) {
/* success, replace scf by new one */
- scf[sfbAct] = scfAct;
- sfbDist[sfbAct] = sfbDistNew;
- deltaPeNew = deltaPeTmp;
- success = 1;
+ scf[sfbAct] = scfAct;
+ sfbDist[sfbAct] = sfbDistNew;
+ deltaPeNew = deltaPeTmp;
+ success = 1;
}
/* mark as already checked */
-
+
if (updateMinScfCalculated) {
- minScfCalculated[sfbAct] = scfAct;
+ minScfCalculated[sfbAct] = scfAct;
}
}
else {
- updateMinScfCalculated = 0;
+ updateMinScfCalculated = 0;
}
}
-
+
} while (scfAct > scfMin);
- deltaPe = deltaPeNew;
+ deltaPe = deltaPeNew;
/* save parameters to avoid multiple computations of the same sfb */
- prevScfLast[sfbAct] = *scfLast;
- prevScfNext[sfbAct] = *scfNext;
- deltaPeLast[sfbAct] = deltaPe;
+ prevScfLast[sfbAct] = *scfLast;
+ prevScfNext[sfbAct] = *scfNext;
+ deltaPeLast[sfbAct] = deltaPe;
}
-
+
if (success && restartOnSuccess) {
/* start again at first sfb */
- sfbLast = -1;
- sfbAct = -1;
- sfbNext = -1;
+ sfbLast = -1;
+ sfbAct = -1;
+ sfbNext = -1;
scfLast = 0;
scfNext = 0;
- scfMin = MAX_16;
- success = 0;
+ scfMin = MAX_16;
+ success = 0;
}
else {
/* shift sfbs for next band */
- sfbLast = sfbAct;
- sfbAct = sfbNext;
+ sfbLast = sfbAct;
+ sfbAct = sfbNext;
}
-
+
} while (sfbNext < psyOutChan->sfbCnt);
}
@@ -557,9 +557,9 @@
*
**********************************************************************************/
static void assimilateMultipleScf(PSY_OUT_CHANNEL *psyOutChan,
- Word16 *scf,
+ Word16 *scf,
Word16 *minScf,
- Word32 *sfbDist,
+ Word32 *sfbDist,
Word16 *sfbConstPePart,
Word16 *logSfbEnergy,
Word16 *logSfbFormFactor,
@@ -574,95 +574,95 @@
Word32 *sfbDistNew = psyOutChan->sfbDistNew;
Word16 *scfTmp = psyOutChan->prevScfLast;
- deltaPe = 0;
- sfbCnt = psyOutChan->sfbCnt;
-
+ deltaPe = 0;
+ sfbCnt = psyOutChan->sfbCnt;
+
/* calc min and max scalfactors */
- scfMin = MAX_16;
- scfMax = MIN_16;
+ scfMin = MAX_16;
+ scfMax = MIN_16;
for (sfb=0; sfb<sfbCnt; sfb++) {
-
+
if (scf[sfb] != MIN_16) {
scfMin = min(scfMin, scf[sfb]);
scfMax = max(scfMax, scf[sfb]);
}
}
-
+
if (scfMax != MIN_16) {
-
- scfAct = scfMax;
-
+
+ scfAct = scfMax;
+
do {
scfAct = scfAct - 1;
for (sfb=0; sfb<sfbCnt; sfb++) {
- scfTmp[sfb] = scf[sfb];
+ scfTmp[sfb] = scf[sfb];
}
- stopSfb = 0;
+ stopSfb = 0;
do {
- sfb = stopSfb;
-
+ sfb = stopSfb;
+
while (sfb < sfbCnt && (scf[sfb] == MIN_16 || scf[sfb] <= scfAct)) {
sfb = sfb + 1;
}
- startSfb = sfb;
+ startSfb = sfb;
sfb = sfb + 1;
-
+
while (sfb < sfbCnt && (scf[sfb] == MIN_16 || scf[sfb] > scfAct)) {
sfb = sfb + 1;
}
- stopSfb = sfb;
-
- possibleRegionFound = 0;
-
+ stopSfb = sfb;
+
+ possibleRegionFound = 0;
+
if (startSfb < sfbCnt) {
- possibleRegionFound = 1;
+ possibleRegionFound = 1;
for (sfb=startSfb; sfb<stopSfb; sfb++) {
-
+
if (scf[sfb]!=MIN_16) {
-
+
if (scfAct < minScf[sfb]) {
- possibleRegionFound = 0;
+ possibleRegionFound = 0;
break;
}
}
}
}
-
-
+
+
if (possibleRegionFound) { /* region found */
-
+
/* replace scfs in region by scfAct */
for (sfb=startSfb; sfb<stopSfb; sfb++) {
-
+
if (scfTmp[sfb]!=MIN_16)
- scfTmp[sfb] = scfAct;
+ scfTmp[sfb] = scfAct;
}
-
+
/* estimate change in bit demand for new scfs */
deltaScfBits = countScfBitsDiff(scf,scfTmp,sfbCnt,startSfb,stopSfb);
deltaSpecPe = calcSpecPeDiff(scf, scfTmp, sfbConstPePart,
- logSfbEnergy, logSfbFormFactor, sfbNRelevantLines,
+ logSfbEnergy, logSfbFormFactor, sfbNRelevantLines,
startSfb, stopSfb);
deltaPeNew = deltaPe + deltaScfBits + deltaSpecPe;
-
-
+
+
if (deltaPeNew < 10) {
Word32 distOldSum, distNewSum;
-
+
/* quantize and calc sum of new distortion */
- distOldSum = 0;
- distNewSum = 0;
+ distOldSum = 0;
+ distNewSum = 0;
for (sfb=startSfb; sfb<stopSfb; sfb++) {
-
+
if (scfTmp[sfb] != MIN_16) {
distOldSum = L_add(distOldSum, sfbDist[sfb]);
-
+
sfbDistNew[sfb] = calcSfbDist(psyOutChan->mdctSpectrum +
- psyOutChan->sfbOffsets[sfb],
+ psyOutChan->sfbOffsets[sfb],
(psyOutChan->sfbOffsets[sfb+1] - psyOutChan->sfbOffsets[sfb]),
scfAct);
-
-
+
+
if (sfbDistNew[sfb] > psyOutChan->sfbThreshold[sfb]) {
distNewSum = distOldSum << 1;
break;
@@ -670,20 +670,20 @@
distNewSum = L_add(distNewSum, sfbDistNew[sfb]);
}
}
-
+
if (distNewSum < distOldSum) {
- deltaPe = deltaPeNew;
+ deltaPe = deltaPeNew;
for (sfb=startSfb; sfb<stopSfb; sfb++) {
-
+
if (scf[sfb]!=MIN_16) {
- scf[sfb] = scfAct;
- sfbDist[sfb] = sfbDistNew[sfb];
+ scf[sfb] = scfAct;
+ sfbDist[sfb] = sfbDistNew[sfb];
}
}
}
}
- }
- } while (stopSfb <= sfbCnt);
+ }
+ } while (stopSfb <= sfbCnt);
} while (scfAct > scfMin);
}
}
@@ -710,125 +710,125 @@
Word32 *sfbDist = psyOutChan->sfbDist;
Word16 *minSfMaxQuant = psyOutChan->minSfMaxQuant;
Word16 *minScfCalculated = psyOutChan->minScfCalculated;
-
-
+
+
for (i=0; i<psyOutChan->sfbCnt; i++) {
Word32 sbfwith, sbfStart;
Word32 *mdctSpec;
- thresh = psyOutChan->sfbThreshold[i];
- energy = psyOutChan->sfbEnergy[i];
-
+ thresh = psyOutChan->sfbThreshold[i];
+ energy = psyOutChan->sfbEnergy[i];
+
sbfStart = psyOutChan->sfbOffsets[i];
sbfwith = psyOutChan->sfbOffsets[i+1] - sbfStart;
mdctSpec = psyOutChan->mdctSpectrum+sbfStart;
-
- maxSpec = 0;
+
+ maxSpec = 0;
/* maximum of spectrum */
for (j=sbfwith; j; j-- ) {
Word32 absSpec = L_abs(*mdctSpec); mdctSpec++;
- maxSpec |= absSpec;
+ maxSpec |= absSpec;
}
-
+
/* scfs without energy or with thresh>energy are marked with MIN_16 */
- scf[i] = MIN_16;
- minSfMaxQuant[i] = MIN_16;
-
+ scf[i] = MIN_16;
+ minSfMaxQuant[i] = MIN_16;
+
if ((maxSpec > 0) && (energy > thresh)) {
-
- energyPart = logSfbFormFactor[i];
- thresholdPart = iLog4(thresh);
+
+ energyPart = logSfbFormFactor[i];
+ thresholdPart = iLog4(thresh);
/* -20 = 4*log2(6.75) - 32 */
scfInt = ((thresholdPart - energyPart - 20) * SCALE_ESTIMATE_COEF) >> 15;
-
+
minSfMaxQuant[i] = iLog4(maxSpec) - 68; /* 68 -16/3*log(MAX_QUANT+0.5-logCon)/log(2) + 1 */
-
-
+
+
if (minSfMaxQuant[i] > scfInt) {
- scfInt = minSfMaxQuant[i];
+ scfInt = minSfMaxQuant[i];
}
-
+
/* find better scalefactor with analysis by synthesis */
scfInt = improveScf(psyOutChan->mdctSpectrum+sbfStart,
sbfwith,
- thresh, scfInt, minSfMaxQuant[i],
+ thresh, scfInt, minSfMaxQuant[i],
&sfbDist[i], &minScfCalculated[i]);
-
- scf[i] = scfInt;
+
+ scf[i] = scfInt;
}
}
-
-
+
+
/* scalefactor differece reduction */
{
Word16 sfbConstPePart[MAX_GROUPED_SFB];
for(i=0;i<psyOutChan->sfbCnt;i++) {
- sfbConstPePart[i] = MIN_16;
+ sfbConstPePart[i] = MIN_16;
}
-
- assimilateSingleScf(psyOutChan, scf,
+
+ assimilateSingleScf(psyOutChan, scf,
minSfMaxQuant, sfbDist, sfbConstPePart, logSfbEnergy,
logSfbFormFactor, sfbNRelevantLines, minScfCalculated, 1);
-
- assimilateMultipleScf(psyOutChan, scf,
+
+ assimilateMultipleScf(psyOutChan, scf,
minSfMaxQuant, sfbDist, sfbConstPePart, logSfbEnergy,
logSfbFormFactor, sfbNRelevantLines);
}
/* get max scalefac for global gain */
- maxScf = MIN_16;
- minScf = MAX_16;
+ maxScf = MIN_16;
+ minScf = MAX_16;
for (i=0; i<psyOutChan->sfbCnt; i++) {
-
+
if (maxScf < scf[i]) {
- maxScf = scf[i];
+ maxScf = scf[i];
}
-
+
if ((scf[i] != MIN_16) && (minScf > scf[i])) {
- minScf = scf[i];
+ minScf = scf[i];
}
}
/* limit scf delta */
maxAllowedScf = minScf + MAX_SCF_DELTA;
for(i=0; i<psyOutChan->sfbCnt; i++) {
-
+
if ((scf[i] != MIN_16) && (maxAllowedScf < scf[i])) {
- scf[i] = maxAllowedScf;
+ scf[i] = maxAllowedScf;
}
}
/* new maxScf if any scf has been limited */
-
+
if (maxAllowedScf < maxScf) {
- maxScf = maxAllowedScf;
+ maxScf = maxAllowedScf;
}
-
+
/* calc loop scalefactors */
-
+
if (maxScf > MIN_16) {
- *globalGain = maxScf;
- lastSf = 0;
-
+ *globalGain = maxScf;
+ lastSf = 0;
+
for(i=0; i<psyOutChan->sfbCnt; i++) {
-
+
if (scf[i] == MIN_16) {
- scf[i] = lastSf;
+ scf[i] = lastSf;
/* set band explicitely to zero */
for (j=psyOutChan->sfbOffsets[i]; j<psyOutChan->sfbOffsets[i+1]; j++) {
- psyOutChan->mdctSpectrum[j] = 0;
+ psyOutChan->mdctSpectrum[j] = 0;
}
}
else {
scf[i] = maxScf - scf[i];
- lastSf = scf[i];
+ lastSf = scf[i];
}
}
}
else{
- *globalGain = 0;
+ *globalGain = 0;
/* set spectrum explicitely to zero */
for(i=0; i<psyOutChan->sfbCnt; i++) {
- scf[i] = 0;
+ scf[i] = 0;
for (j=psyOutChan->sfbOffsets[i]; j<psyOutChan->sfbOffsets[i+1]; j++) {
- psyOutChan->mdctSpectrum[j] = 0;
+ psyOutChan->mdctSpectrum[j] = 0;
}
}
}
@@ -848,7 +848,7 @@
const Word16 nChannels)
{
Word16 j;
-
+
for (j=0; j<nChannels; j++) {
CalcFormFactorChannel(logSfbFormFactor[j], sfbNRelevantLines[j], logSfbEnergy[j], &psyOutChannel[j]);
}
@@ -869,7 +869,7 @@
const Word16 nChannels)
{
Word16 j;
-
+
for (j=0; j<nChannels; j++) {
EstimateScaleFactorsChannel(&psyOutChannel[j],
qcOutChannel[j].scf,
diff --git a/media/libstagefright/codecs/aacenc/src/stat_bits.c b/media/libstagefright/codecs/aacenc/src/stat_bits.c
index c2bd8bd..baa289c 100644
--- a/media/libstagefright/codecs/aacenc/src/stat_bits.c
+++ b/media/libstagefright/codecs/aacenc/src/stat_bits.c
@@ -52,9 +52,9 @@
struct TOOLSINFO *toolsInfo)
{
Word16 msBits, sfbOff, sfb;
- msBits = 0;
+ msBits = 0;
-
+
switch(toolsInfo->msDigest) {
case MS_NONE:
case MS_ALL:
@@ -85,34 +85,34 @@
Word32 coefBits;
Word16 *ptcoef;
- count = 0;
-
+ count = 0;
+
if (blockType == 2)
numOfWindows = 8;
else
numOfWindows = 1;
- tnsPresent = 0;
+ tnsPresent = 0;
for (i=0; i<numOfWindows; i++) {
-
+
if (tnsInfo->tnsActive[i]!=0) {
- tnsPresent = 1;
+ tnsPresent = 1;
}
}
-
+
if (tnsPresent) {
/* there is data to be written*/
/*count += 1; */
for (i=0; i<numOfWindows; i++) {
-
+
if (blockType == 2)
count += 1;
else
count += 2;
-
+
if (tnsInfo->tnsActive[i]) {
count += 1;
-
+
if (blockType == 2) {
count += 4;
count += 3;
@@ -121,29 +121,29 @@
count += 6;
count += 5;
}
-
+
if (tnsInfo->order[i]) {
count += 1; /*direction*/
- count += 1; /*coef_compression */
-
+ count += 1; /*coef_compression */
+
if (tnsInfo->coefRes[i] == 4) {
ptcoef = tnsInfo->coef + i*TNS_MAX_ORDER_SHORT;
- coefBits = 3;
+ coefBits = 3;
for(k=0; k<tnsInfo->order[i]; k++) {
-
+
if ((ptcoef[k] > 3) || (ptcoef[k] < -4)) {
- coefBits = 4;
+ coefBits = 4;
break;
}
}
}
else {
- coefBits = 2;
+ coefBits = 2;
ptcoef = tnsInfo->coef + i*TNS_MAX_ORDER_SHORT;
for(k=0; k<tnsInfo->order[i]; k++) {
-
+
if ((ptcoef[k] > 1) || (ptcoef[k] < -2)) {
- coefBits = 3;
+ coefBits = 3;
break;
}
}
@@ -155,14 +155,14 @@
}
}
}
-
+
return count;
}
/**********************************************************************************
*
* function name: countTnsBits
-* description: count tns bit demand
+* description: count tns bit demand
*
**********************************************************************************/
static Word16 countTnsBits(TNS_INFO *tnsInfo,Word16 blockType)
@@ -173,29 +173,29 @@
/*********************************************************************************
*
* function name: countStaticBitdemand
-* description: count static bit demand include tns
+* description: count static bit demand include tns
*
**********************************************************************************/
Word16 countStaticBitdemand(PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
PSY_OUT_ELEMENT *psyOutElement,
- Word16 channels,
+ Word16 channels,
Word16 adtsUsed)
{
Word32 statBits;
Word32 ch;
-
- statBits = 0;
+
+ statBits = 0;
/* if adts used, add 56 bits */
if(adtsUsed) statBits += 56;
-
+
switch (channels) {
case 1:
statBits += SI_ID_BITS+SI_SCE_BITS+SI_ICS_BITS;
statBits += countTnsBits(&(psyOutChannel[0].tnsInfo),
psyOutChannel[0].windowSequence);
-
+
switch(psyOutChannel[0].windowSequence){
case LONG_WINDOW:
case START_WINDOW:
@@ -215,7 +215,7 @@
psyOutChannel[0].sfbPerGroup,
psyOutChannel[0].maxSfbPerGroup,
&psyOutElement->toolsInfo);
-
+
switch (psyOutChannel[0].windowSequence) {
case LONG_WINDOW:
case START_WINDOW:
diff --git a/media/libstagefright/codecs/aacenc/src/tns.c b/media/libstagefright/codecs/aacenc/src/tns.c
index 455a864..473e0a0 100644
--- a/media/libstagefright/codecs/aacenc/src/tns.c
+++ b/media/libstagefright/codecs/aacenc/src/tns.c
@@ -100,20 +100,20 @@
/* assert(freq >= 0); */
shift = norm_l(fs);
lineNumber = (extract_l(fixmul((bandStartOffset[numOfBands] << 2),Div_32(freq << shift,fs << shift))) + 1) >> 1;
-
+
/* freq > fs/2 */
- temp = lineNumber - bandStartOffset[numOfBands] ;
+ temp = lineNumber - bandStartOffset[numOfBands] ;
if (temp >= 0)
return numOfBands;
/* find band the line number lies in */
for (band=0; band<numOfBands; band++) {
- temp = bandStartOffset[band + 1] - lineNumber;
+ temp = bandStartOffset[band + 1] - lineNumber;
if (temp > 0) break;
}
temp = (lineNumber - bandStartOffset[band]);
- temp = (temp - (bandStartOffset[band + 1] - lineNumber));
+ temp = (temp - (bandStartOffset[band + 1] - lineNumber));
if ( temp > 0 )
{
band = band + 1;
@@ -139,25 +139,25 @@
{
Word32 bitratePerChannel;
- tC->maxOrder = TNS_MAX_ORDER;
+ tC->maxOrder = TNS_MAX_ORDER;
tC->tnsStartFreq = 1275;
- tC->coefRes = 4;
-
+ tC->coefRes = 4;
+
/* to avoid integer division */
- if ( sub(channels,2) == 0 ) {
- bitratePerChannel = bitRate >> 1;
+ if ( sub(channels,2) == 0 ) {
+ bitratePerChannel = bitRate >> 1;
}
else {
- bitratePerChannel = bitRate;
+ bitratePerChannel = bitRate;
}
tC->tnsMaxSfb = tnsMaxBandsLongMainLow[pC->sampRateIdx];
- tC->tnsActive = active;
+ tC->tnsActive = active;
/* now calc band and line borders */
tC->tnsStopBand = min(pC->sfbCnt, tC->tnsMaxSfb);
- tC->tnsStopLine = pC->sfbOffset[tC->tnsStopBand];
+ tC->tnsStopLine = pC->sfbOffset[tC->tnsStopBand];
tC->tnsStartBand = FreqToBandWithRounding(tC->tnsStartFreq, sampleRate,
pC->sfbCnt, (const Word16*)pC->sfbOffset);
@@ -173,18 +173,18 @@
(const Word16*)pC->sfbOffset);
- tC->tnsStartLine = pC->sfbOffset[tC->tnsStartBand];
+ tC->tnsStartLine = pC->sfbOffset[tC->tnsStartBand];
tC->lpcStopBand = tnsMaxBandsLongMainLow[pC->sampRateIdx];
tC->lpcStopBand = min(tC->lpcStopBand, pC->sfbActive);
- tC->lpcStopLine = pC->sfbOffset[tC->lpcStopBand];
-
+ tC->lpcStopLine = pC->sfbOffset[tC->lpcStopBand];
+
tC->lpcStartBand = tnsMinBandNumberLong[pC->sampRateIdx];
- tC->lpcStartLine = pC->sfbOffset[tC->lpcStartBand];
+ tC->lpcStartLine = pC->sfbOffset[tC->lpcStartBand];
- tC->threshold = TNS_GAIN_THRESH;
+ tC->threshold = TNS_GAIN_THRESH;
return(0);
@@ -207,23 +207,23 @@
Word32 bitratePerChannel;
tC->maxOrder = TNS_MAX_ORDER_SHORT;
tC->tnsStartFreq = 2750;
- tC->coefRes = 3;
-
+ tC->coefRes = 3;
+
/* to avoid integer division */
if ( sub(channels,2) == 0 ) {
- bitratePerChannel = L_shr(bitRate,1);
+ bitratePerChannel = L_shr(bitRate,1);
}
else {
- bitratePerChannel = bitRate;
+ bitratePerChannel = bitRate;
}
tC->tnsMaxSfb = tnsMaxBandsShortMainLow[pC->sampRateIdx];
- tC->tnsActive = active;
+ tC->tnsActive = active;
/* now calc band and line borders */
tC->tnsStopBand = min(pC->sfbCnt, tC->tnsMaxSfb);
- tC->tnsStopLine = pC->sfbOffset[tC->tnsStopBand];
+ tC->tnsStopLine = pC->sfbOffset[tC->tnsStopBand];
tC->tnsStartBand=FreqToBandWithRounding(tC->tnsStartFreq, sampleRate,
pC->sfbCnt, (const Word16*)pC->sfbOffset);
@@ -239,19 +239,19 @@
(const Word16*)pC->sfbOffset);
- tC->tnsStartLine = pC->sfbOffset[tC->tnsStartBand];
+ tC->tnsStartLine = pC->sfbOffset[tC->tnsStartBand];
tC->lpcStopBand = tnsMaxBandsShortMainLow[pC->sampRateIdx];
tC->lpcStopBand = min(tC->lpcStopBand, pC->sfbActive);
- tC->lpcStopLine = pC->sfbOffset[tC->lpcStopBand];
+ tC->lpcStopLine = pC->sfbOffset[tC->lpcStopBand];
tC->lpcStartBand = tnsMinBandNumberShort[pC->sampRateIdx];
- tC->lpcStartLine = pC->sfbOffset[tC->lpcStartBand];
+ tC->lpcStartLine = pC->sfbOffset[tC->lpcStartBand];
- tC->threshold = TNS_GAIN_THRESH;
+ tC->threshold = TNS_GAIN_THRESH;
return(0);
}
@@ -259,7 +259,7 @@
/**
*
* function name: TnsDetect
-* description: Calculate TNS filter and decide on TNS usage
+* description: Calculate TNS filter and decide on TNS usage
* returns: 0 if success
*
*/
@@ -278,7 +278,7 @@
Word32* pWork32 = &pScratchTns[subBlockNumber >> 8];
Word16* pWeightedSpectrum = (Word16 *)&pScratchTns[subBlockNumber >> 8];
-
+
if (tC.tnsActive) {
CalcWeightedSpectrum(spectrum,
pWeightedSpectrum,
@@ -290,7 +290,7 @@
tC.lpcStopBand,
pWork32);
- temp = blockType - SHORT_WINDOW;
+ temp = blockType - SHORT_WINDOW;
if ( temp != 0 ) {
predictionGain = CalcTnsFilter( &pWeightedSpectrum[tC.lpcStartLine],
tC.acfWindow,
@@ -299,15 +299,15 @@
tnsData->dataRaw.tnsLong.subBlockInfo.parcor);
- temp = predictionGain - tC.threshold;
+ temp = predictionGain - tC.threshold;
if ( temp > 0 ) {
- tnsData->dataRaw.tnsLong.subBlockInfo.tnsActive = 1;
+ tnsData->dataRaw.tnsLong.subBlockInfo.tnsActive = 1;
}
else {
- tnsData->dataRaw.tnsLong.subBlockInfo.tnsActive = 0;
+ tnsData->dataRaw.tnsLong.subBlockInfo.tnsActive = 0;
}
- tnsData->dataRaw.tnsLong.subBlockInfo.predictionGain = predictionGain;
+ tnsData->dataRaw.tnsLong.subBlockInfo.predictionGain = predictionGain;
}
else{
@@ -317,28 +317,28 @@
tC.maxOrder,
tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].parcor);
- temp = predictionGain - tC.threshold;
+ temp = predictionGain - tC.threshold;
if ( temp > 0 ) {
- tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].tnsActive = 1;
+ tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].tnsActive = 1;
}
else {
- tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].tnsActive = 0;
+ tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].tnsActive = 0;
}
- tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].predictionGain = predictionGain;
+ tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].predictionGain = predictionGain;
}
}
else{
- temp = blockType - SHORT_WINDOW;
+ temp = blockType - SHORT_WINDOW;
if ( temp != 0 ) {
- tnsData->dataRaw.tnsLong.subBlockInfo.tnsActive = 0;
- tnsData->dataRaw.tnsLong.subBlockInfo.predictionGain = 0;
+ tnsData->dataRaw.tnsLong.subBlockInfo.tnsActive = 0;
+ tnsData->dataRaw.tnsLong.subBlockInfo.predictionGain = 0;
}
else {
- tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].tnsActive = 0;
- tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].predictionGain = 0;
+ tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].tnsActive = 0;
+ tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].predictionGain = 0;
}
}
@@ -362,21 +362,21 @@
const TNS_SUBBLOCK_INFO *sbInfoSrc;
Word32 i, temp;
- temp = blockType - SHORT_WINDOW;
+ temp = blockType - SHORT_WINDOW;
if ( temp != 0 ) {
- sbInfoDest = &tnsDataDest->dataRaw.tnsLong.subBlockInfo;
- sbInfoSrc = &tnsDataSrc->dataRaw.tnsLong.subBlockInfo;
+ sbInfoDest = &tnsDataDest->dataRaw.tnsLong.subBlockInfo;
+ sbInfoSrc = &tnsDataSrc->dataRaw.tnsLong.subBlockInfo;
}
else {
- sbInfoDest = &tnsDataDest->dataRaw.tnsShort.subBlockInfo[subBlockNumber];
- sbInfoSrc = &tnsDataSrc->dataRaw.tnsShort.subBlockInfo[subBlockNumber];
+ sbInfoDest = &tnsDataDest->dataRaw.tnsShort.subBlockInfo[subBlockNumber];
+ sbInfoSrc = &tnsDataSrc->dataRaw.tnsShort.subBlockInfo[subBlockNumber];
}
if (100*abs_s(sbInfoDest->predictionGain - sbInfoSrc->predictionGain) <
(3 * sbInfoDest->predictionGain)) {
- sbInfoDest->tnsActive = sbInfoSrc->tnsActive;
+ sbInfoDest->tnsActive = sbInfoSrc->tnsActive;
for ( i=0; i< tC.maxOrder; i++) {
- sbInfoDest->parcor[i] = sbInfoSrc->parcor[i];
+ sbInfoDest->parcor[i] = sbInfoSrc->parcor[i];
}
}
}
@@ -402,11 +402,11 @@
Word32 temp;
TNS_SUBBLOCK_INFO *psubBlockInfo;
- temp_s = blockType - SHORT_WINDOW;
- if ( temp_s != 0) {
+ temp_s = blockType - SHORT_WINDOW;
+ if ( temp_s != 0) {
psubBlockInfo = &tnsData->dataRaw.tnsLong.subBlockInfo;
if (psubBlockInfo->tnsActive == 0) {
- tnsInfo->tnsActive[subBlockNumber] = 0;
+ tnsInfo->tnsActive[subBlockNumber] = 0;
return(0);
}
else {
@@ -422,22 +422,22 @@
tC.coefRes);
for (i=tC.maxOrder - 1; i>=0; i--) {
- temp = psubBlockInfo->parcor[i] - TNS_PARCOR_THRESH;
+ temp = psubBlockInfo->parcor[i] - TNS_PARCOR_THRESH;
if ( temp > 0 )
break;
- temp = psubBlockInfo->parcor[i] + TNS_PARCOR_THRESH;
+ temp = psubBlockInfo->parcor[i] + TNS_PARCOR_THRESH;
if ( temp < 0 )
break;
}
- tnsInfo->order[subBlockNumber] = i + 1;
+ tnsInfo->order[subBlockNumber] = i + 1;
- tnsInfo->tnsActive[subBlockNumber] = 1;
+ tnsInfo->tnsActive[subBlockNumber] = 1;
for (i=subBlockNumber+1; i<TRANS_FAC; i++) {
- tnsInfo->tnsActive[i] = 0;
+ tnsInfo->tnsActive[i] = 0;
}
- tnsInfo->coefRes[subBlockNumber] = tC.coefRes;
- tnsInfo->length[subBlockNumber] = numOfSfb - tC.tnsStartBand;
+ tnsInfo->coefRes[subBlockNumber] = tC.coefRes;
+ tnsInfo->length[subBlockNumber] = numOfSfb - tC.tnsStartBand;
AnalysisFilterLattice(&(spectrum[tC.tnsStartLine]),
@@ -448,10 +448,10 @@
}
} /* if (blockType!=SHORT_WINDOW) */
- else /*short block*/ {
+ else /*short block*/ {
psubBlockInfo = &tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber];
if (psubBlockInfo->tnsActive == 0) {
- tnsInfo->tnsActive[subBlockNumber] = 0;
+ tnsInfo->tnsActive[subBlockNumber] = 0;
return(0);
}
else {
@@ -466,19 +466,19 @@
tC.maxOrder,
tC.coefRes);
for (i=(tC.maxOrder - 1); i>=0; i--) {
- temp = psubBlockInfo->parcor[i] - TNS_PARCOR_THRESH;
+ temp = psubBlockInfo->parcor[i] - TNS_PARCOR_THRESH;
if ( temp > 0 )
break;
- temp = psubBlockInfo->parcor[i] + TNS_PARCOR_THRESH;
+ temp = psubBlockInfo->parcor[i] + TNS_PARCOR_THRESH;
if ( temp < 0 )
break;
}
- tnsInfo->order[subBlockNumber] = i + 1;
+ tnsInfo->order[subBlockNumber] = i + 1;
- tnsInfo->tnsActive[subBlockNumber] = 1;
- tnsInfo->coefRes[subBlockNumber] = tC.coefRes;
- tnsInfo->length[subBlockNumber] = numOfSfb - tC.tnsStartBand;
+ tnsInfo->tnsActive[subBlockNumber] = 1;
+ tnsInfo->coefRes[subBlockNumber] = tC.coefRes;
+ tnsInfo->length[subBlockNumber] = numOfSfb - tC.tnsStartBand;
AnalysisFilterLattice(&(spectrum[tC.tnsStartLine]), (tC.tnsStopLine - tC.tnsStartLine),
@@ -507,14 +507,14 @@
{
Word32 k;
- Word32 accu_y = 0x40000000;
+ Word32 accu_y = 0x40000000;
accu_y = L_shr(accu_y,scale);
for(k=1; k<INT_BITS; k++) {
- const Word32 z = m_log2_table[k];
+ const Word32 z = m_log2_table[k];
while(L_sub(x,z) >= 0) {
-
+
x = L_sub(x, z);
accu_y = L_add(accu_y, (accu_y >> k));
}
@@ -548,43 +548,43 @@
Word32 maxWS;
Word32 tnsSfbMean[MAX_SFB]; /* length [lpcStopBand-lpcStartBand] should be sufficient here */
- maxWS = 0;
-
+ maxWS = 0;
+
/* calc 1.0*2^-INT_BITS/2/sqrt(en) */
for( sfb = lpcStartBand; sfb < lpcStopBand; sfb++) {
- tmp2 = sfbEnergy[sfb] - 2;
+ tmp2 = sfbEnergy[sfb] - 2;
if( tmp2 > 0) {
tmp = rsqrt(sfbEnergy[sfb], INT_BITS);
- if(tmp > INT_BITS_SCAL)
+ if(tmp > INT_BITS_SCAL)
{
shift = norm_l(tmp);
- tmp = Div_32( INT_BITS_SCAL << shift, tmp << shift );
+ tmp = Div_32( INT_BITS_SCAL << shift, tmp << shift );
}
else
{
- tmp = 0x7fffffff;
+ tmp = 0x7fffffff;
}
}
else {
- tmp = 0x7fffffff;
- }
- tnsSfbMean[sfb] = tmp;
+ tmp = 0x7fffffff;
+ }
+ tnsSfbMean[sfb] = tmp;
}
/* spread normalized values from sfbs to lines */
- sfb = lpcStartBand;
- tmp = tnsSfbMean[sfb];
+ sfb = lpcStartBand;
+ tmp = tnsSfbMean[sfb];
for ( i=lpcStartLine; i<lpcStopLine; i++){
- tmp_s = sfbOffset[sfb + 1] - i;
+ tmp_s = sfbOffset[sfb + 1] - i;
if ( tmp_s == 0 ) {
sfb = sfb + 1;
- tmp2_s = sfb + 1 - lpcStopBand;
+ tmp2_s = sfb + 1 - lpcStopBand;
if (tmp2_s <= 0) {
- tmp = tnsSfbMean[sfb];
+ tmp = tnsSfbMean[sfb];
}
}
- pWork32[i] = tmp;
+ pWork32[i] = tmp;
}
/*filter down*/
for (i=(lpcStopLine - 2); i>=lpcStartLine; i--){
@@ -597,8 +597,8 @@
/* weight and normalize */
for (i=lpcStartLine; i<lpcStopLine; i++){
- pWork32[i] = MULHIGH(pWork32[i], spectrum[i]);
- maxWS |= L_abs(pWork32[i]);
+ pWork32[i] = MULHIGH(pWork32[i], spectrum[i]);
+ maxWS |= L_abs(pWork32[i]);
}
maxShift = norm_l(maxWS);
@@ -646,7 +646,7 @@
assert(tnsOrder <= TNS_MAX_ORDER); /* remove asserts later? (btg) */
for(i=0;i<tnsOrder;i++) {
- parcor[i] = 0;
+ parcor[i] = 0;
}
AutoCorrelation(signal, parcorWorkBuffer, numOfLines, tnsOrderPlus1);
@@ -678,15 +678,15 @@
Word32 accu;
Word32 scf;
- scf = 10 - 1;
+ scf = 10 - 1;
isamples = samples;
/* calc first corrCoef: R[0] = sum { t[i] * t[i] } ; i = 0..N-1 */
- accu = 0;
+ accu = 0;
for(j=0; j<isamples; j++) {
accu = L_add(accu, ((input[j] * input[j]) >> scf));
}
- corr[0] = accu;
+ corr[0] = accu;
/* early termination if all corr coeffs are likely going to be zero */
if(corr[0] == 0) return ;
@@ -694,13 +694,13 @@
/* calc all other corrCoef: R[j] = sum { t[i] * t[i+j] } ; i = 0..(N-j-1), j=1..p */
for(i=1; i<corrCoeff; i++) {
isamples = isamples - 1;
- accu = 0;
+ accu = 0;
for(j=0; j<isamples; j++) {
accu = L_add(accu, ((input[j] * input[j+i]) >> scf));
}
- corr[i] = accu;
+ corr[i] = accu;
}
-}
+}
#endif
/*****************************************************************************
@@ -720,20 +720,20 @@
Word32 predictionGain = 0;
Word32 num, denom;
Word32 temp, workBuffer0;
+
-
- num = workBuffer[0];
- temp = workBuffer[numOfCoeff];
+ num = workBuffer[0];
+ temp = workBuffer[numOfCoeff];
for(i=0; i<numOfCoeff-1; i++) {
- workBuffer[i + numOfCoeff] = workBuffer[i + 1];
+ workBuffer[i + numOfCoeff] = workBuffer[i + 1];
}
- workBuffer[i + numOfCoeff] = temp;
-
+ workBuffer[i + numOfCoeff] = temp;
+
for(i=0; i<numOfCoeff; i++) {
Word32 refc;
-
+
if (workBuffer[0] < L_abs(workBuffer[i + numOfCoeff])) {
return 0 ;
}
@@ -742,21 +742,21 @@
/* calculate refc = -workBuffer[numOfCoeff+i] / workBuffer[0]; -1 <= refc < 1 */
refc = L_negate(fixmul(workBuffer[numOfCoeff + i], workBuffer0));
- reflCoeff[i] = refc;
+ reflCoeff[i] = refc;
- pWorkBuffer = &(workBuffer[numOfCoeff]);
+ pWorkBuffer = &(workBuffer[numOfCoeff]);
for(j=i; j<numOfCoeff; j++) {
Word32 accu1, accu2;
accu1 = L_add(pWorkBuffer[j], fixmul(refc, workBuffer[j - i]));
accu2 = L_add(workBuffer[j - i], fixmul(refc, pWorkBuffer[j]));
- pWorkBuffer[j] = accu1;
- workBuffer[j - i] = accu2;
+ pWorkBuffer[j] = accu1;
+ workBuffer[j - i] = accu2;
}
}
denom = MULHIGH(workBuffer[0], NORM_COEF);
-
+
if (denom != 0) {
Word32 temp;
shift = norm_l(denom);
@@ -774,11 +774,11 @@
Word32 index = 0;
Word32 i;
Word32 temp;
-
+
for (i=0;i<8;i++) {
- temp = L_sub( parcor, tnsCoeff3Borders[i]);
+ temp = L_sub( parcor, tnsCoeff3Borders[i]);
if (temp > 0)
- index=i;
+ index=i;
}
return extract_l(index - 4);
}
@@ -788,12 +788,12 @@
Word32 index = 0;
Word32 i;
Word32 temp;
-
+
for (i=0;i<16;i++) {
- temp = L_sub(parcor, tnsCoeff4Borders[i]);
+ temp = L_sub(parcor, tnsCoeff4Borders[i]);
if (temp > 0)
- index=i;
+ index=i;
}
return extract_l(index - 8);
}
@@ -814,12 +814,12 @@
Word32 temp;
for(i=0; i<order; i++) {
- temp = bitsPerCoeff - 3;
+ temp = bitsPerCoeff - 3;
if (temp == 0) {
- index[i] = Search3(parcor[i]);
- }
+ index[i] = Search3(parcor[i]);
+ }
else {
- index[i] = Search4(parcor[i]);
+ index[i] = Search4(parcor[i]);
}
}
}
@@ -839,12 +839,12 @@
Word32 temp;
for (i=0; i<order; i++) {
- temp = bitsPerCoeff - 4;
+ temp = bitsPerCoeff - 4;
if ( temp == 0 ) {
- parcor[i] = tnsCoeff4[index[i] + 8];
+ parcor[i] = tnsCoeff4[index[i] + 8];
}
else {
- parcor[i] = tnsCoeff3[index[i] + 4];
+ parcor[i] = tnsCoeff3[index[i] + 4];
}
}
}
@@ -865,20 +865,20 @@
Word32 accu,tmp,tmpSave;
x = x >> 1;
- tmpSave = x;
+ tmpSave = x;
for (i=0; i<(order - 1); i++) {
tmp = L_add(fixmul(coef_par[i], x), state_par[i]);
x = L_add(fixmul(coef_par[i], state_par[i]), x);
- state_par[i] = tmpSave;
- tmpSave = tmp;
+ state_par[i] = tmpSave;
+ tmpSave = tmp;
}
/* last stage: only need half operations */
accu = fixmul(state_par[order - 1], coef_par[(order - 1)]);
- state_par[(order - 1)] = tmpSave;
+ state_par[(order - 1)] = tmpSave;
x = L_add(accu, x);
x = L_add(x, x);
@@ -903,11 +903,11 @@
Word32 j;
for ( j=0; j<TNS_MAX_ORDER; j++ ) {
- state_par[j] = 0;
+ state_par[j] = 0;
}
for(j=0; j<numOfLines; j++) {
- output[j] = FIRLattice(order,signal[j],state_par,parCoeff);
+ output[j] = FIRLattice(order,signal[j],state_par,parCoeff);
}
}
@@ -922,11 +922,11 @@
TNS_SUBBLOCK_INFO subInfo, /*!< TNS subblock info */
Word32 *thresholds) /*!< thresholds (modified) */
{
- Word32 i;
+ Word32 i;
if (subInfo.tnsActive) {
for(i=startCb; i<stopCb; i++) {
/* thresholds[i] * 0.25 */
- thresholds[i] = (thresholds[i] >> 2);
+ thresholds[i] = (thresholds[i] >> 2);
}
}
}
diff --git a/media/libstagefright/codecs/aacenc/src/transform.c b/media/libstagefright/codecs/aacenc/src/transform.c
index a154a2f..4d11f78 100644
--- a/media/libstagefright/codecs/aacenc/src/transform.c
+++ b/media/libstagefright/codecs/aacenc/src/transform.c
@@ -31,7 +31,7 @@
#define swap2(p0,p1) \
t = p0; t1 = *(&(p0)+1); \
p0 = p1; *(&(p0)+1) = *(&(p1)+1); \
- p1 = t; *(&(p1)+1) = t1
+ p1 = t; *(&(p1)+1) = t1
/*********************************************************************************
*
@@ -47,18 +47,18 @@
part0 = buf;
part1 = buf + num;
-
+
while ((i = *bitTab++) != 0) {
j = *bitTab++;
- swap2(part0[4*i+0], part0[4*j+0]);
- swap2(part0[4*i+2], part1[4*j+0]);
- swap2(part1[4*i+0], part0[4*j+2]);
- swap2(part1[4*i+2], part1[4*j+2]);
+ swap2(part0[4*i+0], part0[4*j+0]);
+ swap2(part0[4*i+2], part1[4*j+0]);
+ swap2(part1[4*i+0], part0[4*j+2]);
+ swap2(part1[4*i+2], part1[4*j+2]);
}
do {
- swap2(part0[4*i+2], part1[4*i+0]);
+ swap2(part0[4*i+2], part1[4*i+0]);
} while ((i = *bitTab++) != 0);
}
@@ -74,8 +74,8 @@
{
int r0, r1, r2, r3;
int r4, r5, r6, r7;
-
- for (; num != 0; num--)
+
+ for (; num != 0; num--)
{
r0 = buf[0] + buf[2];
r1 = buf[1] + buf[3];
@@ -113,7 +113,7 @@
int i4, i5, i6, i7;
int t0, t1, t2, t3;
- for ( ; num != 0; num--)
+ for ( ; num != 0; num--)
{
r0 = buf[0] + buf[2];
i0 = buf[1] + buf[3];
@@ -194,23 +194,23 @@
int i, j, step;
int *xptr, *csptr;
- for (num >>= 2; num != 0; num >>= 2)
+ for (num >>= 2; num != 0; num >>= 2)
{
step = 2*bgn;
xptr = buf;
- for (i = num; i != 0; i--)
+ for (i = num; i != 0; i--)
{
csptr = twidTab;
- for (j = bgn; j != 0; j--)
+ for (j = bgn; j != 0; j--)
{
r0 = xptr[0];
r1 = xptr[1];
xptr += step;
-
+
t0 = xptr[0];
- t1 = xptr[1];
+ t1 = xptr[1];
cosx = csptr[0];
sinx = csptr[1];
r2 = MULHIGH(cosx, t0) + MULHIGH(sinx, t1); /* cos*br + sin*bi */
@@ -223,7 +223,7 @@
r1 = t1 - r3;
r2 = t0 + r2;
r3 = t1 + r3;
-
+
t0 = xptr[0];
t1 = xptr[1];
cosx = csptr[2];
@@ -231,7 +231,7 @@
r4 = MULHIGH(cosx, t0) + MULHIGH(sinx, t1); /* cos*cr + sin*ci */
r5 = MULHIGH(cosx, t1) - MULHIGH(sinx, t0); /* cos*ci - sin*cr */
xptr += step;
-
+
t0 = xptr[0];
t1 = xptr[1];
cosx = csptr[4];
@@ -282,25 +282,25 @@
int tr1, ti1, tr2, ti2;
int cosa, sina, cosb, sinb;
int *buf1;
-
+
buf1 = buf0 + num - 1;
for(i = num >> 2; i != 0; i--)
{
- cosa = *csptr++;
- sina = *csptr++;
- cosb = *csptr++;
- sinb = *csptr++;
+ cosa = *csptr++;
+ sina = *csptr++;
+ cosb = *csptr++;
+ sinb = *csptr++;
tr1 = *(buf0 + 0);
ti2 = *(buf0 + 1);
tr2 = *(buf1 - 1);
ti1 = *(buf1 + 0);
-
+
*buf0++ = MULHIGH(cosa, tr1) + MULHIGH(sina, ti1);
- *buf0++ = MULHIGH(cosa, ti1) - MULHIGH(sina, tr1);
-
- *buf1-- = MULHIGH(cosb, ti2) - MULHIGH(sinb, tr2);
+ *buf0++ = MULHIGH(cosa, ti1) - MULHIGH(sina, tr1);
+
+ *buf1-- = MULHIGH(cosb, ti2) - MULHIGH(sinb, tr2);
*buf1-- = MULHIGH(cosb, tr2) + MULHIGH(sinb, ti2);
}
}
@@ -319,12 +319,12 @@
int *buf1;
buf1 = buf0 + num - 1;
-
+
for(i = num >> 2; i != 0; i--)
{
- cosa = *csptr++;
- sina = *csptr++;
- cosb = *csptr++;
+ cosa = *csptr++;
+ sina = *csptr++;
+ cosb = *csptr++;
sinb = *csptr++;
tr1 = *(buf0 + 0);
@@ -333,10 +333,10 @@
tr2 = *(buf1 - 1);
*buf0++ = MULHIGH(cosa, tr1) + MULHIGH(sina, ti1);
- *buf1-- = MULHIGH(sina, tr1) - MULHIGH(cosa, ti1);
-
+ *buf1-- = MULHIGH(sina, tr1) - MULHIGH(cosa, ti1);
+
*buf0++ = MULHIGH(sinb, tr2) - MULHIGH(cosb, ti2);
- *buf1-- = MULHIGH(cosb, tr2) + MULHIGH(sinb, ti2);
+ *buf1-- = MULHIGH(cosb, tr2) + MULHIGH(sinb, ti2);
}
}
#endif
@@ -353,17 +353,17 @@
PreMDCT(buf, 1024, cossintab + 128);
Shuffle(buf, 512, bitrevTab + 17);
- Radix8First(buf, 512 >> 3);
+ Radix8First(buf, 512 >> 3);
Radix4FFT(buf, 512 >> 3, 8, (int *)twidTab512);
- PostMDCT(buf, 1024, cossintab + 128);
+ PostMDCT(buf, 1024, cossintab + 128);
}
/**********************************************************************************
*
* function name: Mdct_Short
-* description: the short block mdct
+* description: the short block mdct
*
**********************************************************************************/
void Mdct_Short(int *buf)
@@ -371,10 +371,10 @@
PreMDCT(buf, 128, cossintab);
Shuffle(buf, 64, bitrevTab);
- Radix4First(buf, 64 >> 2);
- Radix4FFT(buf, 64 >> 2, 4, (int *)twidTab64);
+ Radix4First(buf, 64 >> 2);
+ Radix4FFT(buf, 64 >> 2, 4, (int *)twidTab64);
- PostMDCT(buf, 128, cossintab);
+ PostMDCT(buf, 128, cossintab);
}
@@ -382,7 +382,7 @@
*
* function name: shiftMdctDelayBuffer
* description: the mdct delay buffer has a size of 1600,
-* so the calculation of LONG,STOP must be spilt in two
+* so the calculation of LONG,STOP must be spilt in two
* passes with 1024 samples and a mid shift,
* the SHORT transforms can be completed in the delay buffer,
* and afterwards a shift
@@ -409,7 +409,7 @@
dsBuf = timeSignal;
for(i=0; i<FRAME_LEN_LONG; i+=8)
- {
+ {
*srBuf++ = *dsBuf; dsBuf += chIncrement;
*srBuf++ = *dsBuf; dsBuf += chIncrement;
*srBuf++ = *dsBuf; dsBuf += chIncrement;
@@ -470,10 +470,10 @@
Word32 delayBufferSf,timeSignalSf,minSf;
Word32 headRoom=0;
-
+
switch(blockType){
-
-
+
+
case LONG_WINDOW:
/*
we access BLOCK_SWITCHING_OFFSET (1600 ) delay buffer samples + 448 new timeSignal samples
@@ -483,15 +483,15 @@
timeSignalSf = getScalefactorOfShortVectorStride(timeSignal,2*FRAME_LEN_LONG-BLOCK_SWITCHING_OFFSET,chIncrement);
minSf = min(delayBufferSf,timeSignalSf);
minSf = min(minSf,14);
-
+
dctIn0 = mdctDelayBuffer;
dctIn1 = mdctDelayBuffer + FRAME_LEN_LONG - 1;
outData0 = realOut + FRAME_LEN_LONG/2;
-
+
/* add windows and pre add for mdct to last buffer*/
winPtr = (int *)LongWindowKBD;
for(i=0;i<FRAME_LEN_LONG/2;i++){
- timeSignalSample = (*dctIn0++) << minSf;
+ timeSignalSample = (*dctIn0++) << minSf;
ws1 = timeSignalSample * (*winPtr >> 16);
timeSignalSample = (*dctIn1--) << minSf;
ws2 = timeSignalSample * (*winPtr & 0xffff);
@@ -499,30 +499,30 @@
/* shift 2 to avoid overflow next */
*outData0++ = (ws1 >> 2) - (ws2 >> 2);
}
-
+
shiftMdctDelayBuffer(mdctDelayBuffer,timeSignal,chIncrement);
-
+
/* add windows and pre add for mdct to new buffer*/
dctIn0 = mdctDelayBuffer;
dctIn1 = mdctDelayBuffer + FRAME_LEN_LONG - 1;
- outData0 = realOut + FRAME_LEN_LONG/2 - 1;
+ outData0 = realOut + FRAME_LEN_LONG/2 - 1;
winPtr = (int *)LongWindowKBD;
- for(i=0;i<FRAME_LEN_LONG/2;i++){
+ for(i=0;i<FRAME_LEN_LONG/2;i++){
timeSignalSample = (*dctIn0++) << minSf;
ws1 = timeSignalSample * (*winPtr & 0xffff);
timeSignalSample = (*dctIn1--) << minSf;
ws2 = timeSignalSample * (*winPtr >> 16);
winPtr++;
/* shift 2 to avoid overflow next */
- *outData0-- = -((ws1 >> 2) + (ws2 >> 2));
+ *outData0-- = -((ws1 >> 2) + (ws2 >> 2));
}
Mdct_Long(realOut);
/* update scale factor */
minSf = 14 - minSf;
- *mdctScale=minSf;
+ *mdctScale=minSf;
break;
-
+
case START_WINDOW:
/*
we access BLOCK_SWITCHING_OFFSET (1600 ) delay buffer samples + no timeSignal samples
@@ -533,7 +533,7 @@
dctIn0 = mdctDelayBuffer;
dctIn1 = mdctDelayBuffer + FRAME_LEN_LONG - 1;
- outData0 = realOut + FRAME_LEN_LONG/2;
+ outData0 = realOut + FRAME_LEN_LONG/2;
winPtr = (int *)LongWindowKBD;
/* add windows and pre add for mdct to last buffer*/
@@ -545,18 +545,18 @@
winPtr ++;
*outData0++ = (ws1 >> 2) - (ws2 >> 2); /* shift 2 to avoid overflow next */
}
-
+
shiftMdctDelayBuffer(mdctDelayBuffer,timeSignal,chIncrement);
-
- outData0 = realOut + FRAME_LEN_LONG/2 - 1;
+
+ outData0 = realOut + FRAME_LEN_LONG/2 - 1;
for(i=0;i<LS_TRANS;i++){
- *outData0-- = -mdctDelayBuffer[i] << (15 - 2 + minSf);
+ *outData0-- = -mdctDelayBuffer[i] << (15 - 2 + minSf);
}
-
+
/* add windows and pre add for mdct to new buffer*/
dctIn0 = mdctDelayBuffer + LS_TRANS;
dctIn1 = mdctDelayBuffer + FRAME_LEN_LONG - 1 - LS_TRANS;
- outData0 = realOut + FRAME_LEN_LONG/2 - 1 -LS_TRANS;
+ outData0 = realOut + FRAME_LEN_LONG/2 - 1 -LS_TRANS;
winPtr = (int *)ShortWindowSine;
for(i=0;i<FRAME_LEN_SHORT/2;i++){
timeSignalSample= (*dctIn0++) << minSf;
@@ -572,7 +572,7 @@
minSf = 14 - minSf;
*mdctScale= minSf;
break;
-
+
case STOP_WINDOW:
/*
we access BLOCK_SWITCHING_OFFSET-LS_TRANS (1600-448 ) delay buffer samples + 448 new timeSignal samples
@@ -580,19 +580,19 @@
*/
delayBufferSf = getScalefactorOfShortVectorStride(mdctDelayBuffer+LS_TRANS,BLOCK_SWITCHING_OFFSET-LS_TRANS,1);
timeSignalSf = getScalefactorOfShortVectorStride(timeSignal,2*FRAME_LEN_LONG-BLOCK_SWITCHING_OFFSET,chIncrement);
- minSf = min(delayBufferSf,timeSignalSf);
+ minSf = min(delayBufferSf,timeSignalSf);
minSf = min(minSf,13);
-
+
outData0 = realOut + FRAME_LEN_LONG/2;
dctIn1 = mdctDelayBuffer + FRAME_LEN_LONG - 1;
for(i=0;i<LS_TRANS;i++){
- *outData0++ = -(*dctIn1--) << (15 - 2 + minSf);
+ *outData0++ = -(*dctIn1--) << (15 - 2 + minSf);
}
-
+
/* add windows and pre add for mdct to last buffer*/
dctIn0 = mdctDelayBuffer + LS_TRANS;
dctIn1 = mdctDelayBuffer + FRAME_LEN_LONG - 1 - LS_TRANS;
- outData0 = realOut + FRAME_LEN_LONG/2 + LS_TRANS;
+ outData0 = realOut + FRAME_LEN_LONG/2 + LS_TRANS;
winPtr = (int *)ShortWindowSine;
for(i=0;i<FRAME_LEN_SHORT/2;i++){
timeSignalSample = (*dctIn0++) << minSf;
@@ -602,13 +602,13 @@
winPtr++;
*outData0++ = (ws1 >> 2) - (ws2 >> 2); /* shift 2 to avoid overflow next */
}
-
+
shiftMdctDelayBuffer(mdctDelayBuffer,timeSignal,chIncrement);
-
+
/* add windows and pre add for mdct to new buffer*/
dctIn0 = mdctDelayBuffer;
dctIn1 = mdctDelayBuffer + FRAME_LEN_LONG - 1;
- outData0 = realOut + FRAME_LEN_LONG/2 - 1;
+ outData0 = realOut + FRAME_LEN_LONG/2 - 1;
winPtr = (int *)LongWindowKBD;
for(i=0;i<FRAME_LEN_LONG/2;i++){
timeSignalSample= (*dctIn0++) << minSf;
@@ -618,26 +618,26 @@
*outData0-- = -((ws1 >> 2) + (ws2 >> 2)); /* shift 2 to avoid overflow next */
winPtr++;
}
-
+
Mdct_Long(realOut);
minSf = 14 - minSf;
*mdctScale= minSf; /* update scale factor */
break;
-
+
case SHORT_WINDOW:
/*
we access BLOCK_SWITCHING_OFFSET (1600 ) delay buffer samples + no new timeSignal samples
and get the biggest scale factor for next calculate more precise
- */
+ */
minSf = getScalefactorOfShortVectorStride(mdctDelayBuffer+TRANSFORM_OFFSET_SHORT,9*FRAME_LEN_SHORT,1);
minSf = min(minSf,10);
-
-
+
+
for(w=0;w<TRANS_FAC;w++){
dctIn0 = mdctDelayBuffer+w*FRAME_LEN_SHORT+TRANSFORM_OFFSET_SHORT;
dctIn1 = mdctDelayBuffer+w*FRAME_LEN_SHORT+TRANSFORM_OFFSET_SHORT + FRAME_LEN_SHORT-1;
- outData0 = realOut + FRAME_LEN_SHORT/2;
- outData1 = realOut + FRAME_LEN_SHORT/2 - 1;
+ outData0 = realOut + FRAME_LEN_SHORT/2;
+ outData1 = realOut + FRAME_LEN_SHORT/2 - 1;
winPtr = (int *)ShortWindowSine;
for(i=0;i<FRAME_LEN_SHORT/2;i++){
@@ -646,7 +646,7 @@
timeSignalSample= *dctIn1 << minSf;
ws2 = timeSignalSample * (*winPtr & 0xffff);
*outData0++ = (ws1 >> 2) - (ws2 >> 2); /* shift 2 to avoid overflow next */
-
+
timeSignalSample= *(dctIn0 + FRAME_LEN_SHORT) << minSf;
ws1 = timeSignalSample * (*winPtr & 0xffff);
timeSignalSample= *(dctIn1 + FRAME_LEN_SHORT) << minSf;
@@ -661,10 +661,10 @@
Mdct_Short(realOut);
realOut += FRAME_LEN_SHORT;
}
-
+
minSf = 11 - minSf;
*mdctScale = minSf; /* update scale factor */
-
+
shiftMdctDelayBuffer(mdctDelayBuffer,timeSignal,chIncrement);
break;
}
diff --git a/media/libstagefright/codecs/amrnb/dec/AMRNBDecoder.cpp b/media/libstagefright/codecs/amrnb/dec/AMRNBDecoder.cpp
deleted file mode 100644
index fb300da..0000000
--- a/media/libstagefright/codecs/amrnb/dec/AMRNBDecoder.cpp
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * 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.
- */
-
-#include "AMRNBDecoder.h"
-
-#include "gsmamr_dec.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>
-
-namespace android {
-
-static const int32_t kNumSamplesPerFrame = 160;
-static const int32_t kSampleRate = 8000;
-
-AMRNBDecoder::AMRNBDecoder(const sp<MediaSource> &source)
- : mSource(source),
- mStarted(false),
- mBufferGroup(NULL),
- mState(NULL),
- mAnchorTimeUs(0),
- mNumSamplesOutput(0),
- mInputBuffer(NULL) {
-}
-
-AMRNBDecoder::~AMRNBDecoder() {
- if (mStarted) {
- stop();
- }
-}
-
-status_t AMRNBDecoder::start(MetaData *params) {
- CHECK(!mStarted);
-
- mBufferGroup = new MediaBufferGroup;
- mBufferGroup->add_buffer(
- new MediaBuffer(kNumSamplesPerFrame * sizeof(int16_t)));
-
- CHECK_EQ(GSMInitDecode(&mState, (Word8 *)"AMRNBDecoder"), 0);
-
- mSource->start();
-
- mAnchorTimeUs = 0;
- mNumSamplesOutput = 0;
- mStarted = true;
-
- return OK;
-}
-
-status_t AMRNBDecoder::stop() {
- CHECK(mStarted);
-
- if (mInputBuffer) {
- mInputBuffer->release();
- mInputBuffer = NULL;
- }
-
- delete mBufferGroup;
- mBufferGroup = NULL;
-
- GSMDecodeFrameExit(&mState);
-
- mSource->stop();
-
- mStarted = false;
-
- return OK;
-}
-
-sp<MetaData> AMRNBDecoder::getFormat() {
- sp<MetaData> srcFormat = mSource->getFormat();
-
- int32_t numChannels;
- int32_t sampleRate;
-
- CHECK(srcFormat->findInt32(kKeyChannelCount, &numChannels));
- CHECK_EQ(numChannels, 1);
-
- CHECK(srcFormat->findInt32(kKeySampleRate, &sampleRate));
- CHECK_EQ(sampleRate, kSampleRate);
-
- sp<MetaData> meta = new MetaData;
- meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
- meta->setInt32(kKeyChannelCount, numChannels);
- meta->setInt32(kKeySampleRate, sampleRate);
-
- int64_t durationUs;
- if (srcFormat->findInt64(kKeyDuration, &durationUs)) {
- meta->setInt64(kKeyDuration, durationUs);
- }
-
- meta->setCString(kKeyDecoderComponent, "AMRNBDecoder");
-
- return meta;
-}
-
-status_t AMRNBDecoder::read(
- MediaBuffer **out, const ReadOptions *options) {
- status_t err;
-
- *out = NULL;
-
- int64_t seekTimeUs;
- ReadOptions::SeekMode mode;
- if (options && options->getSeekTo(&seekTimeUs, &mode)) {
- CHECK(seekTimeUs >= 0);
-
- mNumSamplesOutput = 0;
-
- if (mInputBuffer) {
- mInputBuffer->release();
- mInputBuffer = NULL;
- }
- } else {
- seekTimeUs = -1;
- }
-
- if (mInputBuffer == NULL) {
- err = mSource->read(&mInputBuffer, options);
-
- if (err != OK) {
- return err;
- }
-
- int64_t timeUs;
- if (mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) {
- mAnchorTimeUs = timeUs;
- mNumSamplesOutput = 0;
- } else {
- // We must have a new timestamp after seeking.
- CHECK(seekTimeUs < 0);
- }
- }
-
- MediaBuffer *buffer;
- CHECK_EQ(mBufferGroup->acquire_buffer(&buffer), OK);
-
- const uint8_t *inputPtr =
- (const uint8_t *)mInputBuffer->data() + mInputBuffer->range_offset();
-
- size_t numBytesRead =
- AMRDecode(mState,
- (Frame_Type_3GPP)((inputPtr[0] >> 3) & 0x0f),
- (UWord8 *)&inputPtr[1],
- static_cast<int16_t *>(buffer->data()),
- MIME_IETF);
-
- ++numBytesRead; // Include the frame type header byte.
-
- buffer->set_range(0, kNumSamplesPerFrame * sizeof(int16_t));
-
- if (numBytesRead > mInputBuffer->range_length()) {
- // This is bad, should never have happened, but did. Abort now.
-
- buffer->release();
- buffer = NULL;
-
- return ERROR_MALFORMED;
- }
-
- mInputBuffer->set_range(
- mInputBuffer->range_offset() + numBytesRead,
- mInputBuffer->range_length() - numBytesRead);
-
- if (mInputBuffer->range_length() == 0) {
- mInputBuffer->release();
- mInputBuffer = NULL;
- }
-
- buffer->meta_data()->setInt64(
- kKeyTime,
- mAnchorTimeUs
- + (mNumSamplesOutput * 1000000) / kSampleRate);
-
- mNumSamplesOutput += kNumSamplesPerFrame;
-
- *out = buffer;
-
- return OK;
-}
-
-} // namespace android
diff --git a/media/libstagefright/codecs/amrnb/dec/Android.mk b/media/libstagefright/codecs/amrnb/dec/Android.mk
index a545762..23a22ef 100644
--- a/media/libstagefright/codecs/amrnb/dec/Android.mk
+++ b/media/libstagefright/codecs/amrnb/dec/Android.mk
@@ -2,7 +2,6 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
- AMRNBDecoder.cpp \
src/a_refl.cpp \
src/agc.cpp \
src/amrdecode.cpp \
@@ -52,3 +51,33 @@
LOCAL_MODULE := libstagefright_amrnbdec
include $(BUILD_STATIC_LIBRARY)
+
+################################################################################
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ SoftAMR.cpp
+
+LOCAL_C_INCLUDES := \
+ frameworks/base/media/libstagefright/include \
+ frameworks/base/include/media/stagefright/openmax \
+ $(LOCAL_PATH)/src \
+ $(LOCAL_PATH)/include \
+ $(LOCAL_PATH)/../common/include \
+ $(LOCAL_PATH)/../common \
+ frameworks/base/media/libstagefright/codecs/amrwb/src \
+
+LOCAL_CFLAGS := -DOSCL_IMPORT_REF=
+
+LOCAL_STATIC_LIBRARIES := \
+ libstagefright_amrnbdec libstagefright_amrwbdec
+
+LOCAL_SHARED_LIBRARIES := \
+ libstagefright_omx libstagefright_foundation libutils \
+ libstagefright_amrnb_common
+
+LOCAL_MODULE := libstagefright_soft_amrdec
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp
new file mode 100644
index 0000000..c0a588f
--- /dev/null
+++ b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp
@@ -0,0 +1,434 @@
+/*
+ * Copyright (C) 2011 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 "SoftAMR"
+#include <utils/Log.h>
+
+#include "SoftAMR.h"
+
+#include "gsmamr_dec.h"
+#include "pvamrwbdecoder.h"
+
+#include <media/stagefright/foundation/ADebug.h>
+
+namespace android {
+
+template<class T>
+static void InitOMXParams(T *params) {
+ params->nSize = sizeof(T);
+ params->nVersion.s.nVersionMajor = 1;
+ params->nVersion.s.nVersionMinor = 0;
+ params->nVersion.s.nRevision = 0;
+ params->nVersion.s.nStep = 0;
+}
+
+SoftAMR::SoftAMR(
+ const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component)
+ : SimpleSoftOMXComponent(name, callbacks, appData, component),
+ mMode(MODE_NARROW),
+ mState(NULL),
+ mDecoderBuf(NULL),
+ mDecoderCookie(NULL),
+ mInputBufferCount(0),
+ mAnchorTimeUs(0),
+ mNumSamplesOutput(0),
+ mSignalledError(false),
+ mOutputPortSettingsChange(NONE) {
+ if (!strcmp(name, "OMX.google.amrwb.decoder")) {
+ mMode = MODE_WIDE;
+ } else {
+ CHECK(!strcmp(name, "OMX.google.amrnb.decoder"));
+ }
+
+ initPorts();
+ CHECK_EQ(initDecoder(), (status_t)OK);
+}
+
+SoftAMR::~SoftAMR() {
+ if (mMode == MODE_NARROW) {
+ GSMDecodeFrameExit(&mState);
+ mState = NULL;
+ } else {
+ free(mDecoderBuf);
+ mDecoderBuf = NULL;
+
+ mState = NULL;
+ mDecoderCookie = NULL;
+ }
+}
+
+void SoftAMR::initPorts() {
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ InitOMXParams(&def);
+
+ def.nPortIndex = 0;
+ def.eDir = OMX_DirInput;
+ def.nBufferCountMin = kNumBuffers;
+ def.nBufferCountActual = def.nBufferCountMin;
+ def.nBufferSize = 8192;
+ def.bEnabled = OMX_TRUE;
+ def.bPopulated = OMX_FALSE;
+ def.eDomain = OMX_PortDomainAudio;
+ def.bBuffersContiguous = OMX_FALSE;
+ def.nBufferAlignment = 1;
+
+ def.format.audio.cMIMEType =
+ mMode == MODE_NARROW
+ ? const_cast<char *>("audio/amr")
+ : const_cast<char *>("audio/amrwb");
+
+ def.format.audio.pNativeRender = NULL;
+ def.format.audio.bFlagErrorConcealment = OMX_FALSE;
+ def.format.audio.eEncoding = OMX_AUDIO_CodingAMR;
+
+ addPort(def);
+
+ def.nPortIndex = 1;
+ def.eDir = OMX_DirOutput;
+ def.nBufferCountMin = kNumBuffers;
+ def.nBufferCountActual = def.nBufferCountMin;
+
+ def.nBufferSize =
+ (mMode == MODE_NARROW ? kNumSamplesPerFrameNB : kNumSamplesPerFrameWB)
+ * sizeof(int16_t);
+
+ def.bEnabled = OMX_TRUE;
+ def.bPopulated = OMX_FALSE;
+ def.eDomain = OMX_PortDomainAudio;
+ def.bBuffersContiguous = OMX_FALSE;
+ def.nBufferAlignment = 2;
+
+ def.format.audio.cMIMEType = const_cast<char *>("audio/raw");
+ def.format.audio.pNativeRender = NULL;
+ def.format.audio.bFlagErrorConcealment = OMX_FALSE;
+ def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
+
+ addPort(def);
+}
+
+status_t SoftAMR::initDecoder() {
+ if (mMode == MODE_NARROW) {
+ Word16 err = GSMInitDecode(&mState, (Word8 *)"AMRNBDecoder");
+
+ if (err != 0) {
+ return UNKNOWN_ERROR;
+ }
+ } else {
+ int32_t memReq = pvDecoder_AmrWbMemRequirements();
+ mDecoderBuf = malloc(memReq);
+
+ pvDecoder_AmrWb_Init(&mState, mDecoderBuf, &mDecoderCookie);
+ }
+
+ return OK;
+}
+
+OMX_ERRORTYPE SoftAMR::internalGetParameter(
+ OMX_INDEXTYPE index, OMX_PTR params) {
+ switch (index) {
+ case OMX_IndexParamAudioAmr:
+ {
+ OMX_AUDIO_PARAM_AMRTYPE *amrParams =
+ (OMX_AUDIO_PARAM_AMRTYPE *)params;
+
+ if (amrParams->nPortIndex != 0) {
+ return OMX_ErrorUndefined;
+ }
+
+ amrParams->nChannels = 1;
+ amrParams->eAMRDTXMode = OMX_AUDIO_AMRDTXModeOff;
+ amrParams->eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatConformance;
+
+ if (!isConfigured()) {
+ amrParams->nBitRate = 0;
+ amrParams->eAMRBandMode = OMX_AUDIO_AMRBandModeUnused;
+ } else {
+ amrParams->nBitRate = 0;
+ amrParams->eAMRBandMode =
+ mMode == MODE_NARROW
+ ? OMX_AUDIO_AMRBandModeNB0 : OMX_AUDIO_AMRBandModeWB0;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ case OMX_IndexParamAudioPcm:
+ {
+ OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
+ (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
+
+ if (pcmParams->nPortIndex != 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ pcmParams->nChannels = 1;
+ pcmParams->eNumData = OMX_NumericalDataSigned;
+ pcmParams->eEndian = OMX_EndianBig;
+ pcmParams->bInterleaved = OMX_TRUE;
+ pcmParams->nBitPerSample = 16;
+
+ pcmParams->nSamplingRate =
+ (mMode == MODE_NARROW) ? kSampleRateNB : kSampleRateWB;
+
+ pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
+ pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
+ pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
+
+ return OMX_ErrorNone;
+ }
+
+ default:
+ return SimpleSoftOMXComponent::internalGetParameter(index, params);
+ }
+}
+
+OMX_ERRORTYPE SoftAMR::internalSetParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params) {
+ switch (index) {
+ case OMX_IndexParamStandardComponentRole:
+ {
+ const OMX_PARAM_COMPONENTROLETYPE *roleParams =
+ (const OMX_PARAM_COMPONENTROLETYPE *)params;
+
+ if (mMode == MODE_NARROW) {
+ if (strncmp((const char *)roleParams->cRole,
+ "audio_decoder.amrnb",
+ OMX_MAX_STRINGNAME_SIZE - 1)) {
+ return OMX_ErrorUndefined;
+ }
+ } else {
+ if (strncmp((const char *)roleParams->cRole,
+ "audio_decoder.amrwb",
+ OMX_MAX_STRINGNAME_SIZE - 1)) {
+ return OMX_ErrorUndefined;
+ }
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ case OMX_IndexParamAudioAmr:
+ {
+ const OMX_AUDIO_PARAM_AMRTYPE *aacParams =
+ (const OMX_AUDIO_PARAM_AMRTYPE *)params;
+
+ if (aacParams->nPortIndex != 0) {
+ return OMX_ErrorUndefined;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ default:
+ return SimpleSoftOMXComponent::internalSetParameter(index, params);
+ }
+}
+
+bool SoftAMR::isConfigured() const {
+ return mInputBufferCount > 0;
+}
+
+static size_t getFrameSize(unsigned FT) {
+ static const size_t kFrameSizeWB[9] = {
+ 132, 177, 253, 285, 317, 365, 397, 461, 477
+ };
+
+ size_t frameSize = kFrameSizeWB[FT];
+
+ // Round up bits to bytes and add 1 for the header byte.
+ frameSize = (frameSize + 7) / 8 + 1;
+
+ return frameSize;
+}
+
+void SoftAMR::onQueueFilled(OMX_U32 portIndex) {
+ List<BufferInfo *> &inQueue = getPortQueue(0);
+ List<BufferInfo *> &outQueue = getPortQueue(1);
+
+ if (mSignalledError || mOutputPortSettingsChange != NONE) {
+ return;
+ }
+
+ while (!inQueue.empty() && !outQueue.empty()) {
+ BufferInfo *inInfo = *inQueue.begin();
+ OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
+
+ BufferInfo *outInfo = *outQueue.begin();
+ OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
+
+ if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
+ inQueue.erase(inQueue.begin());
+ inInfo->mOwnedByUs = false;
+ notifyEmptyBufferDone(inHeader);
+
+ outHeader->nFilledLen = 0;
+ outHeader->nFlags = OMX_BUFFERFLAG_EOS;
+
+ outQueue.erase(outQueue.begin());
+ outInfo->mOwnedByUs = false;
+ notifyFillBufferDone(outHeader);
+ return;
+ }
+
+ if (inHeader->nOffset == 0) {
+ mAnchorTimeUs = inHeader->nTimeStamp;
+ mNumSamplesOutput = 0;
+ }
+
+ const uint8_t *inputPtr = inHeader->pBuffer + inHeader->nOffset;
+ int32_t numBytesRead;
+
+ if (mMode == MODE_NARROW) {
+ numBytesRead =
+ AMRDecode(mState,
+ (Frame_Type_3GPP)((inputPtr[0] >> 3) & 0x0f),
+ (UWord8 *)&inputPtr[1],
+ reinterpret_cast<int16_t *>(outHeader->pBuffer),
+ MIME_IETF);
+
+ if (numBytesRead == -1) {
+ LOGE("PV AMR decoder AMRDecode() call failed");
+
+ notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+ mSignalledError = true;
+
+ return;
+ }
+
+ ++numBytesRead; // Include the frame type header byte.
+
+ if (static_cast<size_t>(numBytesRead) > inHeader->nFilledLen) {
+ // This is bad, should never have happened, but did. Abort now.
+
+ notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+ mSignalledError = true;
+
+ return;
+ }
+ } else {
+ int16 mode = ((inputPtr[0] >> 3) & 0x0f);
+ size_t frameSize = getFrameSize(mode);
+ CHECK_GE(inHeader->nFilledLen, frameSize);
+
+ int16 frameType;
+ RX_State_wb rx_state;
+ mime_unsorting(
+ const_cast<uint8_t *>(&inputPtr[1]),
+ mInputSampleBuffer,
+ &frameType, &mode, 1, &rx_state);
+
+ int16_t *outPtr = (int16_t *)outHeader->pBuffer;
+
+ int16_t numSamplesOutput;
+ pvDecoder_AmrWb(
+ mode, mInputSampleBuffer,
+ outPtr,
+ &numSamplesOutput,
+ mDecoderBuf, frameType, mDecoderCookie);
+
+ CHECK_EQ((int)numSamplesOutput, (int)kNumSamplesPerFrameWB);
+
+ for (int i = 0; i < kNumSamplesPerFrameWB; ++i) {
+ /* Delete the 2 LSBs (14-bit output) */
+ outPtr[i] &= 0xfffC;
+ }
+
+ numBytesRead = frameSize;
+ }
+
+ inHeader->nOffset += numBytesRead;
+ inHeader->nFilledLen -= numBytesRead;
+
+ outHeader->nFlags = 0;
+ outHeader->nOffset = 0;
+
+ if (mMode == MODE_NARROW) {
+ outHeader->nFilledLen = kNumSamplesPerFrameNB * sizeof(int16_t);
+
+ outHeader->nTimeStamp =
+ mAnchorTimeUs
+ + (mNumSamplesOutput * 1000000ll) / kSampleRateNB;
+
+ mNumSamplesOutput += kNumSamplesPerFrameNB;
+ } else {
+ outHeader->nFilledLen = kNumSamplesPerFrameWB * sizeof(int16_t);
+
+ outHeader->nTimeStamp =
+ mAnchorTimeUs
+ + (mNumSamplesOutput * 1000000ll) / kSampleRateWB;
+
+ mNumSamplesOutput += kNumSamplesPerFrameWB;
+ }
+
+ if (inHeader->nFilledLen == 0) {
+ inInfo->mOwnedByUs = false;
+ inQueue.erase(inQueue.begin());
+ inInfo = NULL;
+ notifyEmptyBufferDone(inHeader);
+ inHeader = NULL;
+ }
+
+ outInfo->mOwnedByUs = false;
+ outQueue.erase(outQueue.begin());
+ outInfo = NULL;
+ notifyFillBufferDone(outHeader);
+ outHeader = NULL;
+
+ ++mInputBufferCount;
+ }
+}
+
+void SoftAMR::onPortFlushCompleted(OMX_U32 portIndex) {
+}
+
+void SoftAMR::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
+ if (portIndex != 1) {
+ return;
+ }
+
+ switch (mOutputPortSettingsChange) {
+ case NONE:
+ break;
+
+ case AWAITING_DISABLED:
+ {
+ CHECK(!enabled);
+ mOutputPortSettingsChange = AWAITING_ENABLED;
+ break;
+ }
+
+ default:
+ {
+ CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED);
+ CHECK(enabled);
+ mOutputPortSettingsChange = NONE;
+ break;
+ }
+ }
+}
+
+} // namespace android
+
+android::SoftOMXComponent *createSoftOMXComponent(
+ const char *name, const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData, OMX_COMPONENTTYPE **component) {
+ return new android::SoftAMR(name, callbacks, appData, component);
+}
+
diff --git a/media/libstagefright/codecs/amrnb/dec/SoftAMR.h b/media/libstagefright/codecs/amrnb/dec/SoftAMR.h
new file mode 100644
index 0000000..9a596e5
--- /dev/null
+++ b/media/libstagefright/codecs/amrnb/dec/SoftAMR.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2011 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 SOFT_AMR_H_
+
+#define SOFT_AMR_H_
+
+#include "SimpleSoftOMXComponent.h"
+
+namespace android {
+
+struct SoftAMR : public SimpleSoftOMXComponent {
+ SoftAMR(const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component);
+
+protected:
+ virtual ~SoftAMR();
+
+ virtual OMX_ERRORTYPE internalGetParameter(
+ OMX_INDEXTYPE index, OMX_PTR params);
+
+ virtual OMX_ERRORTYPE internalSetParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params);
+
+ virtual void onQueueFilled(OMX_U32 portIndex);
+ virtual void onPortFlushCompleted(OMX_U32 portIndex);
+ virtual void onPortEnableCompleted(OMX_U32 portIndex, bool enabled);
+
+private:
+ enum {
+ kNumBuffers = 4,
+ kSampleRateNB = 8000,
+ kSampleRateWB = 16000,
+ kNumSamplesPerFrameNB = 160,
+ kNumSamplesPerFrameWB = 320,
+ };
+
+ enum {
+ MODE_NARROW,
+ MODE_WIDE
+
+ } mMode;
+
+ void *mState;
+ void *mDecoderBuf;
+ int16_t *mDecoderCookie;
+
+ size_t mInputBufferCount;
+ int64_t mAnchorTimeUs;
+ int64_t mNumSamplesOutput;
+
+ bool mSignalledError;
+
+ enum {
+ NONE,
+ AWAITING_DISABLED,
+ AWAITING_ENABLED
+ } mOutputPortSettingsChange;
+
+ int16_t mInputSampleBuffer[477];
+
+ void initPorts();
+ status_t initDecoder();
+ bool isConfigured() const;
+
+ DISALLOW_EVIL_CONSTRUCTORS(SoftAMR);
+};
+
+} // namespace android
+
+#endif // SOFT_AMR_H_
+
diff --git a/media/libstagefright/codecs/amrwb/AMRWBDecoder.cpp b/media/libstagefright/codecs/amrwb/AMRWBDecoder.cpp
deleted file mode 100644
index 2a21472..0000000
--- a/media/libstagefright/codecs/amrwb/AMRWBDecoder.cpp
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * 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.
- */
-
-#include "AMRWBDecoder.h"
-
-#include "pvamrwbdecoder.h"
-
-#include <media/stagefright/MediaBufferGroup.h>
-#include <media/stagefright/MediaDebug.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MetaData.h>
-
-namespace android {
-
-static const int32_t kNumSamplesPerFrame = 320;
-static const int32_t kSampleRate = 16000;
-
-AMRWBDecoder::AMRWBDecoder(const sp<MediaSource> &source)
- : mSource(source),
- mStarted(false),
- mBufferGroup(NULL),
- mState(NULL),
- mDecoderBuf(NULL),
- mDecoderCookie(NULL),
- mAnchorTimeUs(0),
- mNumSamplesOutput(0),
- mInputBuffer(NULL) {
-}
-
-AMRWBDecoder::~AMRWBDecoder() {
- if (mStarted) {
- stop();
- }
-}
-
-status_t AMRWBDecoder::start(MetaData *params) {
- CHECK(!mStarted);
-
- mBufferGroup = new MediaBufferGroup;
- mBufferGroup->add_buffer(
- new MediaBuffer(kNumSamplesPerFrame * sizeof(int16_t)));
-
- int32_t memReq = pvDecoder_AmrWbMemRequirements();
- mDecoderBuf = malloc(memReq);
-
- pvDecoder_AmrWb_Init(&mState, mDecoderBuf, &mDecoderCookie);
-
- mSource->start();
-
- mAnchorTimeUs = 0;
- mNumSamplesOutput = 0;
- mStarted = true;
-
- return OK;
-}
-
-status_t AMRWBDecoder::stop() {
- CHECK(mStarted);
-
- if (mInputBuffer) {
- mInputBuffer->release();
- mInputBuffer = NULL;
- }
-
- delete mBufferGroup;
- mBufferGroup = NULL;
-
- free(mDecoderBuf);
- mDecoderBuf = NULL;
-
- mSource->stop();
-
- mStarted = false;
-
- return OK;
-}
-
-sp<MetaData> AMRWBDecoder::getFormat() {
- sp<MetaData> srcFormat = mSource->getFormat();
-
- int32_t numChannels;
- int32_t sampleRate;
-
- CHECK(srcFormat->findInt32(kKeyChannelCount, &numChannels));
- CHECK_EQ(numChannels, 1);
-
- CHECK(srcFormat->findInt32(kKeySampleRate, &sampleRate));
- CHECK_EQ(sampleRate, kSampleRate);
-
- sp<MetaData> meta = new MetaData;
- meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
- meta->setInt32(kKeyChannelCount, numChannels);
- meta->setInt32(kKeySampleRate, sampleRate);
-
- int64_t durationUs;
- if (srcFormat->findInt64(kKeyDuration, &durationUs)) {
- meta->setInt64(kKeyDuration, durationUs);
- }
-
- meta->setCString(kKeyDecoderComponent, "AMRWBDecoder");
-
- return meta;
-}
-
-static size_t getFrameSize(unsigned FT) {
- static const size_t kFrameSizeWB[9] = {
- 132, 177, 253, 285, 317, 365, 397, 461, 477
- };
-
- size_t frameSize = kFrameSizeWB[FT];
-
- // Round up bits to bytes and add 1 for the header byte.
- frameSize = (frameSize + 7) / 8 + 1;
-
- return frameSize;
-}
-
-status_t AMRWBDecoder::read(
- MediaBuffer **out, const ReadOptions *options) {
- status_t err;
-
- *out = NULL;
-
- int64_t seekTimeUs;
- ReadOptions::SeekMode seekMode;
- if (options && options->getSeekTo(&seekTimeUs, &seekMode)) {
- CHECK(seekTimeUs >= 0);
-
- mNumSamplesOutput = 0;
-
- if (mInputBuffer) {
- mInputBuffer->release();
- mInputBuffer = NULL;
- }
- } else {
- seekTimeUs = -1;
- }
-
- if (mInputBuffer == NULL) {
- err = mSource->read(&mInputBuffer, options);
-
- if (err != OK) {
- return err;
- }
-
- int64_t timeUs;
- if (mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) {
- mAnchorTimeUs = timeUs;
- mNumSamplesOutput = 0;
- } else {
- // We must have a new timestamp after seeking.
- CHECK(seekTimeUs < 0);
- }
- }
-
- MediaBuffer *buffer;
- CHECK_EQ(mBufferGroup->acquire_buffer(&buffer), OK);
-
- const uint8_t *inputPtr =
- (const uint8_t *)mInputBuffer->data() + mInputBuffer->range_offset();
-
- int16 mode = ((inputPtr[0] >> 3) & 0x0f);
- size_t frameSize = getFrameSize(mode);
- CHECK(mInputBuffer->range_length() >= frameSize);
-
- int16 frameType;
- RX_State rx_state;
- mime_unsorting(
- const_cast<uint8_t *>(&inputPtr[1]),
- mInputSampleBuffer,
- &frameType, &mode, 1, &rx_state);
-
- int16_t *outPtr = (int16_t *)buffer->data();
-
- int16_t numSamplesOutput;
- pvDecoder_AmrWb(
- mode, mInputSampleBuffer,
- outPtr,
- &numSamplesOutput,
- mDecoderBuf, frameType, mDecoderCookie);
-
- CHECK_EQ(numSamplesOutput, kNumSamplesPerFrame);
-
- for (int i = 0; i < kNumSamplesPerFrame; ++i) {
- /* Delete the 2 LSBs (14-bit output) */
- outPtr[i] &= 0xfffC;
- }
-
- buffer->set_range(0, numSamplesOutput * sizeof(int16_t));
-
- mInputBuffer->set_range(
- mInputBuffer->range_offset() + frameSize,
- mInputBuffer->range_length() - frameSize);
-
- if (mInputBuffer->range_length() == 0) {
- mInputBuffer->release();
- mInputBuffer = NULL;
- }
-
- buffer->meta_data()->setInt64(
- kKeyTime,
- mAnchorTimeUs
- + (mNumSamplesOutput * 1000000) / kSampleRate);
-
- mNumSamplesOutput += kNumSamplesPerFrame;
-
- *out = buffer;
-
- return OK;
-}
-
-} // namespace android
diff --git a/media/libstagefright/codecs/amrwb/Android.mk b/media/libstagefright/codecs/amrwb/Android.mk
index ab591d7..c9e1c25 100644
--- a/media/libstagefright/codecs/amrwb/Android.mk
+++ b/media/libstagefright/codecs/amrwb/Android.mk
@@ -2,7 +2,6 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
- AMRWBDecoder.cpp \
src/agc2_amr_wb.cpp \
src/band_pass_6k_7k.cpp \
src/dec_acelp_2p_in_64.cpp \
diff --git a/media/libstagefright/codecs/amrwb/src/mime_io.cpp b/media/libstagefright/codecs/amrwb/src/mime_io.cpp
index 9ff8816..e1966c6 100644
--- a/media/libstagefright/codecs/amrwb/src/mime_io.cpp
+++ b/media/libstagefright/codecs/amrwb/src/mime_io.cpp
@@ -531,7 +531,7 @@
int16 * frame_type,
int16 * mode,
uint8 quality,
- RX_State *st)
+ RX_State_wb *st)
{
int16 i;
diff --git a/media/libstagefright/codecs/amrwb/src/pvamrwbdecoder.h b/media/libstagefright/codecs/amrwb/src/pvamrwbdecoder.h
index 433fc92..c40bc10 100644
--- a/media/libstagefright/codecs/amrwb/src/pvamrwbdecoder.h
+++ b/media/libstagefright/codecs/amrwb/src/pvamrwbdecoder.h
@@ -101,7 +101,7 @@
{
int16 prev_ft;
int16 prev_mode;
-} RX_State;
+} RX_State_wb;
/*----------------------------------------------------------------------------
; ENUMERATED TYPEDEF'S
@@ -141,7 +141,7 @@
int16 *frame_type,
int16 *mode,
uint8 q,
- RX_State *st);
+ RX_State_wb *st);
/*----------------------------------------------------------------------------
diff --git a/media/libstagefright/codecs/amrwbenc/Android.mk b/media/libstagefright/codecs/amrwbenc/Android.mk
index 7141cba..5179380 100644
--- a/media/libstagefright/codecs/amrwbenc/Android.mk
+++ b/media/libstagefright/codecs/amrwbenc/Android.mk
@@ -2,8 +2,8 @@
include $(CLEAR_VARS)
include frameworks/base/media/libstagefright/codecs/common/Config.mk
-LOCAL_PRELINK_MODULE := false
+
LOCAL_SRC_FILES := \
AMRWBEncoder.cpp \
src/autocorr.c \
@@ -91,7 +91,7 @@
LOCAL_ARM_MODE := arm
-LOCAL_STATIC_LIBRARIES :=
+LOCAL_STATIC_LIBRARIES :=
LOCAL_SHARED_LIBRARIES :=
diff --git a/media/libstagefright/codecs/amrwbenc/SampleCode/AMRWB_E_SAMPLE.c b/media/libstagefright/codecs/amrwbenc/SampleCode/AMRWB_E_SAMPLE.c
index c094d41..4ff5f10 100644
--- a/media/libstagefright/codecs/amrwbenc/SampleCode/AMRWB_E_SAMPLE.c
+++ b/media/libstagefright/codecs/amrwbenc/SampleCode/AMRWB_E_SAMPLE.c
@@ -129,7 +129,7 @@
useData.memData = (VO_PTR)(&moper);
#ifdef LINUX
- handle = dlopen("/data/local/tmp/voAMRWBEnc.so", RTLD_NOW);
+ handle = dlopen("libstagefright.so", RTLD_NOW);
if(handle == 0)
{
printf("open dll error......");
diff --git a/media/libstagefright/codecs/amrwbenc/SampleCode/Android.mk b/media/libstagefright/codecs/amrwbenc/SampleCode/Android.mk
index 149e591..85ddceb 100644
--- a/media/libstagefright/codecs/amrwbenc/SampleCode/Android.mk
+++ b/media/libstagefright/codecs/amrwbenc/SampleCode/Android.mk
@@ -1,25 +1,25 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_SRC_FILES := AMRWB_E_SAMPLE.c
+LOCAL_SRC_FILES := \
+ AMRWB_E_SAMPLE.c \
+ ../../common/cmnMemory.c
-LOCAL_SRC_FILES += \
- ../../../Common/cmnMemory.c
-
-LOCAL_MODULE := TestvoAMRWBEnc
+LOCAL_MODULE_TAGS := debug
+LOCAL_MODULE := AMRWBEncTest
LOCAL_ARM_MODE := arm
-LOCAL_STATIC_LIBRARIES :=
+LOCAL_CFLAGS := $(VO_CFLAGS)
-LOCAL_SHARED_LIBRARIES := libvoAMRWBEnc
+LOCAL_SHARED_LIBRARIES := \
+ libstagefright \
+ libdl
LOCAL_C_INCLUDES := \
- $(LOCAL_PATH)/ \
- $(LOCAL_PATH)/../../../Common \
- $(LOCAL_PATH)/../../../Include \
-
-LOCAL_CFLAGS := $(VO_CFLAGS)
+ $(LOCAL_PATH)/ \
+ $(LOCAL_PATH)/../../common \
+ $(LOCAL_PATH)/../../common/include
include $(BUILD_EXECUTABLE)
diff --git a/media/libstagefright/codecs/amrwbenc/SampleCode/eclair/Makefile b/media/libstagefright/codecs/amrwbenc/SampleCode/eclair/Makefile
deleted file mode 100644
index 148b941..0000000
--- a/media/libstagefright/codecs/amrwbenc/SampleCode/eclair/Makefile
+++ /dev/null
@@ -1,56 +0,0 @@
-#/*
-# ** Copyright 2003-2010, VisualOn, Inc.
-# **
-# ** 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.
-# */
-
-# target6
-# available: pc, v4(armv4), v5(armv5), v5x(armv5 xscale), v6(armv6), v7(cortex-a8 neon)
-VOTT:= v6
-
-
-# module type
-# please specify the type of your module: lib or exe
-VOMT:= exe
-
-
-# module macros
-# please append the additional macro definitions here for your module if necessary.
-# e.g. -DVISUALON, macro VISUALON defined for your module
-VOMM:= #ARMV5E
-
-
-
-# please specify the name of your module
-VOTARGET:= voAMRWBEnc_Test
-
-
-# please modify here to be sure to see the g1.mk
-include ../../../../Tools/eclair.mk
-
-# dependent libraries.
-VODEPLIBS:=-ldl
-
-
-# module source
-# please modify here to be sure to see the ms.mk which specifies all source info of your module
-include ../ms.mk
-
-
-# please specify where is the voRelease on your PC, relative path is suggested
-VORELDIR:=../
-
-
-# please modify here to be sure to see the doit.mk
-include ../../../../Tools/doit.mk
-
diff --git a/media/libstagefright/codecs/amrwbenc/SampleCode/ms.mk b/media/libstagefright/codecs/amrwbenc/SampleCode/ms.mk
deleted file mode 100644
index a550cee..0000000
--- a/media/libstagefright/codecs/amrwbenc/SampleCode/ms.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-#/*
-# ** Copyright 2003-2010, VisualOn, Inc.
-# **
-# ** 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.
-# */
-# please list all objects needed by your target here
-OBJS:=AMRWB_E_SAMPLE.o cmnMemory.o
-
-# please list all directories that all source files relative with your module(.h .c .cpp) locate
-VOSRCDIR:=../ \
- ../../../../Common \
- ../../../../Include
-
-
diff --git a/media/libstagefright/codecs/amrwbenc/build/eclair/ARMV5E/Makefile b/media/libstagefright/codecs/amrwbenc/build/eclair/ARMV5E/Makefile
deleted file mode 100644
index 67ec74e..0000000
--- a/media/libstagefright/codecs/amrwbenc/build/eclair/ARMV5E/Makefile
+++ /dev/null
@@ -1,53 +0,0 @@
-#/*
-# ** Copyright 2003-2010, VisualOn, Inc.
-# **
-# ** 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.
-# */
-
-# target type
-# available: pc, v4(armv4), v5(armv5), v5x(armv5 xscale), v6(armv6), v7(cortex-a8 neon)
-VOTT:= v5
-
-
-# module type
-# please specify the type of your module: lib or exe
-VOMT:= lib
-
-
-# module macros
-# please append the additional macro definitions here for your module if necessary.
-ifeq ($(VOTT), v5)
-VOMM:=-DARM -DASM_OPT
-endif
-
-# please specify the name of your module
-VOTARGET:= libvoAMRWBEncv5
-
-
-# please modify here to be sure to see the g1.mk
-include ../../../../../Tools/eclair.mk
-
-# dependent libraries.
-VODEPLIBS:=-ldl -lstdc++ -lcutils
-
-# module source
-# please modify here to be sure to see the ms.mk which specifies all source info of your module
-include ../ms.mk
-
-
-# please specify where is the voRelease on your PC, relative path is suggested
-VORELDIR:=../../../../../../Release
-
-# please modify here to be sure to see the doit.mk
-include ../../../../../Tools/doit.mk
-
diff --git a/media/libstagefright/codecs/amrwbenc/build/eclair/ARMV7/Makefile b/media/libstagefright/codecs/amrwbenc/build/eclair/ARMV7/Makefile
deleted file mode 100644
index 9a036a5..0000000
--- a/media/libstagefright/codecs/amrwbenc/build/eclair/ARMV7/Makefile
+++ /dev/null
@@ -1,53 +0,0 @@
-#/*
-# ** Copyright 2003-2010, VisualOn, Inc.
-# **
-# ** 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.
-# */
-
-# target type
-# available: pc, v4(armv4), v5(armv5), v5x(armv5 xscale), v6(armv6), v7(cortex-a8 neon)
-VOTT:= v7
-
-
-# module type
-# please specify the type of your module: lib or exe
-VOMT:= lib
-
-
-# module macros
-# please append the additional macro definitions here for your module if necessary.
-ifeq ($(VOTT), v7)
-VOMM:=-DARM -DARMV7 -DASM_OPT
-endif
-
-# please specify the name of your module
-VOTARGET:= libvoAMRWBEncv7
-
-
-# please modify here to be sure to see the g1.mk
-include ../../../../../Tools/eclair.mk
-
-# dependent libraries.
-VODEPLIBS:=-ldl -lstdc++ -lcutils
-
-# module source
-# please modify here to be sure to see the ms.mk which specifies all source info of your module
-include ../ms.mk
-
-
-# please specify where is the voRelease on your PC, relative path is suggested
-VORELDIR:=../../../../../../Release
-
-# please modify here to be sure to see the doit.mk
-include ../../../../../Tools/doit.mk
-
diff --git a/media/libstagefright/codecs/amrwbenc/build/eclair/makefile b/media/libstagefright/codecs/amrwbenc/build/eclair/makefile
deleted file mode 100644
index 34981fb..0000000
--- a/media/libstagefright/codecs/amrwbenc/build/eclair/makefile
+++ /dev/null
@@ -1,39 +0,0 @@
-#/*
-# ** Copyright 2003-2010, VisualOn, Inc.
-# **
-# ** 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.
-# */
-# Just acting as Father Makefile of Modules
-# please keep the name 'makefile' unchanged
-
-# Module Subdirs
-VOMSD:=$(dir $(shell find . -name 'Makefile'))
-
-all:
- for dir in $(VOMSD); \
- do \
- $(MAKE) -C $$dir; \
- done
-
-.PHONY:clean devel
-clean:
- for dir in $(VOMSD); \
- do \
- $(MAKE) -C $$dir clean; \
- done
-
-devel:
- for dir in $(VOMSD); \
- do \
- $(MAKE) -C $$dir devel; \
- done
diff --git a/media/libstagefright/codecs/amrwbenc/build/eclair/ms.mk b/media/libstagefright/codecs/amrwbenc/build/eclair/ms.mk
deleted file mode 100644
index 942ec9a..0000000
--- a/media/libstagefright/codecs/amrwbenc/build/eclair/ms.mk
+++ /dev/null
@@ -1,43 +0,0 @@
-#/*
-# ** Copyright 2003-2010, VisualOn, Inc.
-# **
-# ** 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.
-# */
-# please list all directories that all source files relative with your module(.h .c .cpp) locate
-VOSRCDIR:=../../../inc \
- ../../../src \
- ../../../../../Include
-
-# please list all objects needed by your target here
-OBJS:= autocorr.o az_isp.o bits.o c2t64fx.o c4t64fx.o convolve.o cor_h_x.o decim54.o \
- deemph.o dtx.o g_pitch.o gpclip.o homing.o hp400.o hp50.o hp6k.o hp_wsp.o \
- int_lpc.o isp_az.o isp_isf.o lag_wind.o levinson.o log2.o lp_dec2.o math_op.o mem_align.o \
- oper_32b.o p_med_ol.o pit_shrp.o pitch_f4.o pred_lt4.o preemph.o q_gain2.o q_pulse.o \
- qisf_ns.o qpisf_2s.o random.o residu.o scale.o stream.o syn_filt.o updt_tar.o util.o \
- voAMRWBEnc.o voicefac.o wb_vad.o weight_a.o
-
-
-ifeq ($(VOTT), v5)
-OBJS += cor_h_vec_opt.o Deemph_32_opt.o Dot_p_opt.o Filt_6k_7k_opt.o residu_asm_opt.o \
- scale_sig_opt.o Syn_filt_32_opt.o syn_filt_opt.o pred_lt4_1_opt.o convolve_opt.o \
- Norm_Corr_opt.o
-VOSRCDIR+= ../../../src/asm/ARMV5E
-endif
-
-ifeq ($(VOTT), v7)
-OBJS+= cor_h_vec_neon.o Deemph_32_neon.o Dot_p_neon.o Filt_6k_7k_neon.o residu_asm_neon.o \
- scale_sig_neon.o Syn_filt_32_neon.o syn_filt_neon.o pred_lt4_1_neon.o convolve_neon.o \
- Norm_Corr_neon.o
-VOSRCDIR+= ../../../src/asm/ARMV7
-endif
-
diff --git a/media/libstagefright/codecs/amrwbenc/inc/basic_op.h b/media/libstagefright/codecs/amrwbenc/inc/basic_op.h
index c23dce6..7734913 100644
--- a/media/libstagefright/codecs/amrwbenc/inc/basic_op.h
+++ b/media/libstagefright/codecs/amrwbenc/inc/basic_op.h
@@ -33,7 +33,7 @@
#define static_vo static __inline__
#else
#define static_vo static __inline
-#endif
+#endif
#define saturate(L_var1) (((L_var1) > 0X00007fffL) ? (MAX_16): (((L_var1) < (Word32) 0xffff8000L) ? (MIN_16): ((L_var1) & 0xffff)))
@@ -87,7 +87,7 @@
static_vo Word32 L_shr_r (Word32 L_var1, Word16 var2); /* Long shift right with round, 3 */
static_vo Word16 norm_s (Word16 var1); /* Short norm, 15 */
static_vo Word16 div_s (Word16 var1, Word16 var2); /* Short division, 18 */
-static_vo Word16 norm_l (Word32 L_var1); /* Long norm, 30 */
+static_vo Word16 norm_l (Word32 L_var1); /* Long norm, 30 */
/*___________________________________________________________________________
| |
@@ -1030,8 +1030,8 @@
L_num <<= 1;
if (L_num >= L_denom)
{
- L_num -= L_denom;
- var_out += 1;
+ L_num -= L_denom;
+ var_out += 1;
}
}
}
diff --git a/media/libstagefright/codecs/amrwbenc/inc/homing.tab b/media/libstagefright/codecs/amrwbenc/inc/homing.tab
index e399fb8..edcccdd 100644
--- a/media/libstagefright/codecs/amrwbenc/inc/homing.tab
+++ b/media/libstagefright/codecs/amrwbenc/inc/homing.tab
@@ -33,89 +33,89 @@
static const Word16 dfh_M7k[PRMN_7k] =
{
- 3168, 29954, 29213, 16121,
- 64, 13440, 30624, 16430,
+ 3168, 29954, 29213, 16121,
+ 64, 13440, 30624, 16430,
19008
};
static const Word16 dfh_M9k[PRMN_9k] =
{
- 3168, 31665, 9943, 9123,
- 15599, 4358, 20248, 2048,
+ 3168, 31665, 9943, 9123,
+ 15599, 4358, 20248, 2048,
17040, 27787, 16816, 13888
};
static const Word16 dfh_M12k[PRMN_12k] =
{
- 3168, 31665, 9943, 9128,
- 3647, 8129, 30930, 27926,
- 18880, 12319, 496, 1042,
- 4061, 20446, 25629, 28069,
+ 3168, 31665, 9943, 9128,
+ 3647, 8129, 30930, 27926,
+ 18880, 12319, 496, 1042,
+ 4061, 20446, 25629, 28069,
13948
};
static const Word16 dfh_M14k[PRMN_14k] =
{
- 3168, 31665, 9943, 9131,
- 24815, 655, 26616, 26764,
- 7238, 19136, 6144, 88,
- 4158, 25733, 30567, 30494,
+ 3168, 31665, 9943, 9131,
+ 24815, 655, 26616, 26764,
+ 7238, 19136, 6144, 88,
+ 4158, 25733, 30567, 30494,
221, 20321, 17823
};
static const Word16 dfh_M16k[PRMN_16k] =
{
- 3168, 31665, 9943, 9131,
- 24815, 700, 3824, 7271,
- 26400, 9528, 6594, 26112,
- 108, 2068, 12867, 16317,
- 23035, 24632, 7528, 1752,
+ 3168, 31665, 9943, 9131,
+ 24815, 700, 3824, 7271,
+ 26400, 9528, 6594, 26112,
+ 108, 2068, 12867, 16317,
+ 23035, 24632, 7528, 1752,
6759, 24576
};
static const Word16 dfh_M18k[PRMN_18k] =
{
- 3168, 31665, 9943, 9135,
- 14787, 14423, 30477, 24927,
- 25345, 30154, 916, 5728,
- 18978, 2048, 528, 16449,
- 2436, 3581, 23527, 29479,
- 8237, 16810, 27091, 19052,
+ 3168, 31665, 9943, 9135,
+ 14787, 14423, 30477, 24927,
+ 25345, 30154, 916, 5728,
+ 18978, 2048, 528, 16449,
+ 2436, 3581, 23527, 29479,
+ 8237, 16810, 27091, 19052,
0
};
static const Word16 dfh_M20k[PRMN_20k] =
{
- 3168, 31665, 9943, 9129,
- 8637, 31807, 24646, 736,
- 28643, 2977, 2566, 25564,
- 12930, 13960, 2048, 834,
- 3270, 4100, 26920, 16237,
- 31227, 17667, 15059, 20589,
+ 3168, 31665, 9943, 9129,
+ 8637, 31807, 24646, 736,
+ 28643, 2977, 2566, 25564,
+ 12930, 13960, 2048, 834,
+ 3270, 4100, 26920, 16237,
+ 31227, 17667, 15059, 20589,
30249, 29123, 0
};
static const Word16 dfh_M23k[PRMN_23k] =
{
- 3168, 31665, 9943, 9132,
- 16748, 3202, 28179, 16317,
- 30590, 15857, 19960, 8818,
- 21711, 21538, 4260, 16690,
- 20224, 3666, 4194, 9497,
- 16320, 15388, 5755, 31551,
- 14080, 3574, 15932, 50,
+ 3168, 31665, 9943, 9132,
+ 16748, 3202, 28179, 16317,
+ 30590, 15857, 19960, 8818,
+ 21711, 21538, 4260, 16690,
+ 20224, 3666, 4194, 9497,
+ 16320, 15388, 5755, 31551,
+ 14080, 3574, 15932, 50,
23392, 26053, 31216
};
static const Word16 dfh_M24k[PRMN_24k] =
{
- 3168, 31665, 9943, 9134,
- 24776, 5857, 18475, 28535,
- 29662, 14321, 16725, 4396,
- 29353, 10003, 17068, 20504,
- 720, 0, 8465, 12581,
- 28863, 24774, 9709, 26043,
- 7941, 27649, 13965, 15236,
+ 3168, 31665, 9943, 9134,
+ 24776, 5857, 18475, 28535,
+ 29662, 14321, 16725, 4396,
+ 29353, 10003, 17068, 20504,
+ 720, 0, 8465, 12581,
+ 28863, 24774, 9709, 26043,
+ 7941, 27649, 13965, 15236,
18026, 22047, 16681, 3968
};
diff --git a/media/libstagefright/codecs/amrwbenc/inc/isp_isf.tab b/media/libstagefright/codecs/amrwbenc/inc/isp_isf.tab
index 97c3b68..2322845 100644
--- a/media/libstagefright/codecs/amrwbenc/inc/isp_isf.tab
+++ b/media/libstagefright/codecs/amrwbenc/inc/isp_isf.tab
@@ -42,7 +42,7 @@
/* slope in Q11 used to compute y = acos(x) */
-const static Word16 slope[128] = {
+const static Word16 slope[128] = {
-26214, -9039, -5243, -3799, -2979, -2405, -2064, -1771,
-1579, -1409, -1279, -1170, -1079, -1004, -933, -880,
-827, -783, -743, -708, -676, -647, -621, -599,
diff --git a/media/libstagefright/codecs/amrwbenc/inc/log2.h b/media/libstagefright/codecs/amrwbenc/inc/log2.h
index b065eb4..6a35019 100644
--- a/media/libstagefright/codecs/amrwbenc/inc/log2.h
+++ b/media/libstagefright/codecs/amrwbenc/inc/log2.h
@@ -25,20 +25,20 @@
*/
#ifndef __LOG2_H__
#define __LOG2_H__
-
+
/*
********************************************************************************
* INCLUDE FILES
********************************************************************************
*/
#include "typedef.h"
-
+
/*
********************************************************************************
* DEFINITION OF DATA TYPES
********************************************************************************
*/
-
+
/*
********************************************************************************
* DECLARATION OF PROTOTYPES
diff --git a/media/libstagefright/codecs/amrwbenc/inc/mime_io.tab b/media/libstagefright/codecs/amrwbenc/inc/mime_io.tab
index 7b485ea..5f85dd0 100644
--- a/media/libstagefright/codecs/amrwbenc/inc/mime_io.tab
+++ b/media/libstagefright/codecs/amrwbenc/inc/mime_io.tab
@@ -98,7 +98,7 @@
244, 61, 111, 164, 214, 65, 115, 168, 218, 70,
120, 173, 223, 74, 124, 177, 227, 79, 129, 182,
232, 83, 133, 186, 236, 88, 138, 191, 241, 92,
- 142, 195, 245
+ 142, 195, 245
};
static Word16 sort_1425[285] = {
@@ -205,7 +205,7 @@
257, 243, 229, 356, 159, 119, 67, 187, 173, 145,
240, 77, 304, 332, 314, 342, 109, 254, 81, 278,
105, 91, 346, 318, 183, 250, 197, 328, 95, 155,
- 169, 268, 226, 236, 264
+ 169, 268, 226, 236, 264
};
static Word16 sort_1985[397] = {
@@ -248,7 +248,7 @@
128, 118, 303, 104, 379, 182, 114, 375, 200, 96,
293, 172, 214, 365, 279, 86, 289, 351, 347, 357,
261, 186, 176, 271, 90, 100, 147, 322, 275, 361,
- 71, 332, 61, 265, 157, 246, 236
+ 71, 332, 61, 265, 157, 246, 236
};
static Word16 sort_2305[461] = {
@@ -349,7 +349,7 @@
132, 453, 336, 425, 325, 347, 126, 104, 137, 458,
352, 243, 447, 115, 341, 210, 330, 221, 232, 436,
465, 319, 359, 111, 454, 228, 217, 122, 443, 348,
- 239, 250, 133, 144, 432, 337, 326
+ 239, 250, 133, 144, 432, 337, 326
};
static Word16 sort_SID[35] = {
diff --git a/media/libstagefright/codecs/amrwbenc/inc/stream.h b/media/libstagefright/codecs/amrwbenc/inc/stream.h
index 4c1d0f0..3e5336a 100644
--- a/media/libstagefright/codecs/amrwbenc/inc/stream.h
+++ b/media/libstagefright/codecs/amrwbenc/inc/stream.h
@@ -26,7 +26,7 @@
#define __STREAM_H__
#include "voMem.h"
-#define Frame_Maxsize 1024 * 2 //Work Buffer 10K
+#define Frame_Maxsize 1024 * 2 //Work Buffer 10K
#define Frame_MaxByte 640 //AMR_WB Encoder one frame 320 samples = 640 Bytes
#define MIN(a,b) ((a) < (b)? (a) : (b))
@@ -35,7 +35,7 @@
unsigned char *frame_ptr;
unsigned char *frame_ptr_bk;
int set_len;
- int framebuffer_len;
+ int framebuffer_len;
int frame_storelen;
int used_len;
}FrameStream;
diff --git a/media/libstagefright/codecs/amrwbenc/inc/typedef.h b/media/libstagefright/codecs/amrwbenc/inc/typedef.h
index f08a678..533e68b 100644
--- a/media/libstagefright/codecs/amrwbenc/inc/typedef.h
+++ b/media/libstagefright/codecs/amrwbenc/inc/typedef.h
@@ -31,7 +31,7 @@
/*
* this is the original code from the ETSI file typedef.h
*/
-
+
#if defined(__BORLANDC__) || defined(__WATCOMC__) || defined(_MSC_VER) || defined(__ZTC__)
typedef signed char Word8;
typedef short Word16;
diff --git a/media/libstagefright/codecs/amrwbenc/inc/typedefs.h b/media/libstagefright/codecs/amrwbenc/inc/typedefs.h
index 0062584..f30d255 100644
--- a/media/libstagefright/codecs/amrwbenc/inc/typedefs.h
+++ b/media/libstagefright/codecs/amrwbenc/inc/typedefs.h
@@ -45,7 +45,7 @@
* OSF only defined if the current platform is an Alpha
* PC only defined if the current platform is a PC
* SUN only defined if the current platform is a Sun
-*
+*
* LSBFIRST is defined if the byte order on this platform is
* "least significant byte first" -> defined on DEC Alpha
* and PC, undefined on Sun
@@ -68,7 +68,7 @@
/*
********************************************************************************
-* DEFINITION OF CONSTANTS
+* DEFINITION OF CONSTANTS
********************************************************************************
*/
/*
@@ -197,7 +197,7 @@
#define Syn_filt_32 voAWB_Syn_filt_32
#define Isf_isp voAWB_Isf_isp
#define Levinson voAWB_Levinson
-#define median5 voAWB_median5
+#define median5 voAWB_median5
#define Pred_lt4 voAWB_Pred_lt4
#define Reorder_isf voAWB_Reorder_isf
#define Dpisf_2s_36b voAWB_Dpisf_2s_36b
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Deemph_32_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Deemph_32_opt.s
index 282db92..c1c74e6 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Deemph_32_opt.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Deemph_32_opt.s
@@ -30,10 +30,10 @@
.section .text
.global Deemph_32_asm
-
+
Deemph_32_asm:
- STMFD r13!, {r4 - r12, r14}
+ STMFD r13!, {r4 - r12, r14}
MOV r4, #2 @i=0
LDRSH r6, [r0], #2 @load x_hi[0]
LDRSH r7, [r1], #2 @load x_lo[0]
@@ -47,9 +47,9 @@
ADD r12, r10, r7, LSL #4 @L_tmp += x_lo[0] << 4
MOV r10, r12, LSL #3 @L_tmp <<= 3
MUL r9, r5, r8
- LDRSH r6, [r0], #2 @load x_hi[1]
+ LDRSH r6, [r0], #2 @load x_hi[1]
QDADD r10, r10, r9
- LDRSH r7, [r1], #2 @load x_lo[1]
+ LDRSH r7, [r1], #2 @load x_lo[1]
MOV r12, r10, LSL #1 @L_tmp = L_mac(L_tmp, *mem, fac)
QADD r10, r12, r11
MOV r14, r10, ASR #16 @y[0] = round(L_tmp)
@@ -94,9 +94,9 @@
BLT LOOP
STR r14, [r3]
- STRH r14, [r2]
+ STRH r14, [r2]
- LDMFD r13!, {r4 - r12, r15}
+ LDMFD r13!, {r4 - r12, r15}
@ENDP
.END
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Dot_p_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Dot_p_opt.s
index 4aa317e..02bdcab 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Dot_p_opt.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Dot_p_opt.s
@@ -31,7 +31,7 @@
Dot_product12_asm:
- STMFD r13!, {r4 - r12, r14}
+ STMFD r13!, {r4 - r12, r14}
MOV r4, #0 @ L_sum = 0
MOV r5, #0 @ i = 0
@@ -41,13 +41,13 @@
LDR r8, [r0], #4
SMLABB r4, r6, r7, r4
LDR r9, [r1], #4
- SMLATT r4, r6, r7, r4
+ SMLATT r4, r6, r7, r4
LDR r6, [r0], #4
SMLABB r4, r8, r9, r4
LDR r7, [r1], #4
- SMLATT r4, r8, r9, r4
+ SMLATT r4, r8, r9, r4
LDR r8, [r0], #4
SMLABB r4, r6, r7, r4
@@ -58,7 +58,7 @@
CMP r5, r2
SMLATT r4, r8, r9, r4
BLT LOOP
-
+
MOV r12, r4, LSL #1
ADD r12, r12, #1 @ L_sum = (L_sum << 1) + 1
MOV r4, r12
@@ -69,12 +69,12 @@
SUB r10, r10, #1 @ sft = norm_l(L_sum)
MOV r0, r12, LSL r10 @ L_sum = L_sum << sft
RSB r11, r10, #30 @ *exp = 30 - sft
- STRH r11, [r3]
+ STRH r11, [r3]
Dot_product12_end:
-
- LDMFD r13!, {r4 - r12, r15}
+
+ LDMFD r13!, {r4 - r12, r15}
@ENDFUNC
.END
-
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Filt_6k_7k_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Filt_6k_7k_opt.s
index 856ada8..1ce2a85 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Filt_6k_7k_opt.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Filt_6k_7k_opt.s
@@ -23,7 +23,7 @@
@******************************************************************
@ r0 --- signal[]
@ r1 --- lg
-@ r2 --- mem[]
+@ r2 --- mem[]
.section .text
.global Filt_6k_7k_asm
@@ -32,7 +32,7 @@
Filt_6k_7k_asm:
- STMFD r13!, {r4 - r12, r14}
+ STMFD r13!, {r4 - r12, r14}
SUB r13, r13, #240 @ x[L_SUBFR16k + (L_FIR - 1)]
MOV r8, r0 @ copy signal[] address
MOV r4, r1 @ copy lg address
@@ -43,9 +43,9 @@
MOV r2, #30 @ L_FIR - 1
BL voAWB_Copy @ memcpy(x, mem, (L_FIR - 1)<<1)
- LDR r10, Lable1 @ get fir_7k address
+ LDR r10, Lable1 @ get fir_7k address
- MOV r14, #0
+ MOV r14, #0
MOV r3, r8 @ change myMemCopy to Copy, due to Copy will change r3 content
ADD r6, r13, #60 @ get x[L_FIR - 1] address
MOV r7, r3 @ get signal[i]
@@ -76,14 +76,14 @@
STRH r12, [r6], #2
ADD r14, r14, #8
CMP r14, #80
- BLT LOOP1
+ BLT LOOP1
STR r5, [sp, #-4] @ PUSH r5 to stack
@ not use registers: r4, r10, r12, r14, r5
- MOV r4, r13
- MOV r5, #0 @ i = 0
+ MOV r4, r13
+ MOV r5, #0 @ i = 0
LOOP2:
LDR r0, [r10]
@@ -111,13 +111,13 @@
LDRSH r8, [r4, #10] @ load x[i+5]
LDRSH r9, [r4, #50] @ load x[i+25]
SMLABT r14, r1, r0, r14 @ (x[i+3] + x[i+27]) * fir_7k[3]
- ADD r8, r8, r9 @ x[i+5] + x[i+25]
-
+ ADD r8, r8, r9 @ x[i+5] + x[i+25]
+
LDR r0, [r10, #8]
LDRSH r1, [r4, #12] @ x[i+6]
LDRSH r2, [r4, #48] @ x[i+24]
SMLABB r14, r6, r0, r14 @ (x[i+4] + x[i+26]) * fir_7k[4]
- LDRSH r6, [r4, #14] @ x[i+7]
+ LDRSH r6, [r4, #14] @ x[i+7]
LDRSH r7, [r4, #46] @ x[i+23]
SMLABT r14, r8, r0, r14 @ (x[i+5] + x[i+25]) * fir_7k[5]
LDR r0, [r10, #12]
@@ -125,8 +125,8 @@
ADD r6, r6, r7 @ (x[i+7] + x[i+23])
SMLABB r14, r1, r0, r14 @ (x[i+6] + x[i+24]) * fir_7k[6]
LDRSH r8, [r4, #16] @ x[i+8]
- LDRSH r9, [r4, #44] @ x[i+22]
- SMLABT r14, r6, r0, r14 @ (x[i+7] + x[i+23]) * fir_7k[7]
+ LDRSH r9, [r4, #44] @ x[i+22]
+ SMLABT r14, r6, r0, r14 @ (x[i+7] + x[i+23]) * fir_7k[7]
LDR r0, [r10, #16]
LDRSH r1, [r4, #18] @ x[i+9]
LDRSH r2, [r4, #42] @ x[i+21]
@@ -144,7 +144,7 @@
LDRSH r2, [r4, #36] @ x[i+18]
SMLABB r14, r6, r0, r14 @ (x[i+10] + x[i+20]) * fir_7k[10]
LDRSH r6, [r4, #26] @ x[i+13]
- ADD r8, r8, r9 @ (x[i+11] + x[i+19])
+ ADD r8, r8, r9 @ (x[i+11] + x[i+19])
LDRSH r7, [r4, #34] @ x[i+17]
SMLABT r14, r8, r0, r14 @ (x[i+11] + x[i+19]) * fir_7k[11]
LDR r0, [r10, #24]
@@ -152,31 +152,31 @@
LDRSH r8, [r4, #28] @ x[i+14]
SMLABB r14, r1, r0, r14 @ (x[i+12] + x[i+18]) * fir_7k[12]
ADD r6, r6, r7 @ (x[i+13] + x[i+17])
- LDRSH r9, [r4, #32] @ x[i+16]
+ LDRSH r9, [r4, #32] @ x[i+16]
SMLABT r14, r6, r0, r14 @ (x[i+13] + x[i+17]) * fir_7k[13]
- LDR r0, [r10, #28]
+ LDR r0, [r10, #28]
ADD r8, r8, r9 @ (x[i+14] + x[i+16])
LDRSH r1, [r4, #30] @ x[i+15]
SMLABB r14, r8, r0, r14 @ (x[i+14] + x[i+16]) * fir_7k[14]
- SMLABT r14, r1, r0, r14 @ x[i+15] * fir_7k[15]
+ SMLABT r14, r1, r0, r14 @ x[i+15] * fir_7k[15]
ADD r5, r5, #1
ADD r14, r14, #0x4000
- ADD r4, r4, #2
+ ADD r4, r4, #2
MOV r1, r14, ASR #15
CMP r5, #80
STRH r1, [r3], #2 @signal[i] = (L_tmp + 0x4000) >> 15
- BLT LOOP2
-
+ BLT LOOP2
+
LDR r1, [sp, #-4] @mem address
ADD r0, r13, #160 @x + lg
MOV r2, #30
BL voAWB_Copy
-
+
Filt_6k_7k_end:
- ADD r13, r13, #240
- LDMFD r13!, {r4 - r12, r15}
-
+ ADD r13, r13, #240
+ LDMFD r13!, {r4 - r12, r15}
+
Lable1:
.word fir_6k_7k
@ENDFUNC
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Norm_Corr_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Norm_Corr_opt.s
index 49bdc2b..b440a31 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Norm_Corr_opt.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Norm_Corr_opt.s
@@ -32,8 +32,8 @@
@ r6 --- corr_norm[]
- .section .text
- .global Norm_corr_asm
+ .section .text
+ .global Norm_corr_asm
.extern Convolve_asm
.extern Isqrt_n
@******************************
@@ -47,17 +47,17 @@
.equ T_MIN , 212
.equ T_MAX , 216
.equ CORR_NORM , 220
-
+
Norm_corr_asm:
- STMFD r13!, {r4 - r12, r14}
+ STMFD r13!, {r4 - r12, r14}
SUB r13, r13, #voSTACK
-
+
ADD r8, r13, #20 @get the excf[L_SUBFR]
LDR r4, [r13, #T_MIN] @get t_min
RSB r11, r4, #0 @k = -t_min
- ADD r5, r0, r11, LSL #1 @get the &exc[k]
-
+ ADD r5, r0, r11, LSL #1 @get the &exc[k]
+
@transfer Convolve function
STMFD sp!, {r0 - r3}
MOV r0, r5
@@ -68,7 +68,7 @@
@ r8 --- excf[]
- MOV r14, r1 @copy xn[] address
+ MOV r14, r1 @copy xn[] address
MOV r5, #64
MOV r6, #0 @L_tmp = 0
MOV r7, #1
@@ -93,21 +93,21 @@
CLZ r7, r9
SUB r6, r7, #1 @exp = norm_l(L_tmp)
RSB r7, r6, #32 @exp = 32 - exp
- MOV r6, r7, ASR #1
+ MOV r6, r7, ASR #1
RSB r7, r6, #0 @scale = -(exp >> 1)
-
+
@loop for every possible period
@for(t = t_min@ t <= t_max@ t++)
@r7 --- scale r4 --- t_min r8 --- excf[]
-LOOPFOR:
+LOOPFOR:
MOV r5, #0 @L_tmp = 0
MOV r6, #0 @L_tmp1 = 0
- MOV r9, #64
+ MOV r9, #64
MOV r12, r1 @copy of xn[]
ADD r14, r13, #20 @copy of excf[]
MOV r8, #0x8000
-
+
LOOPi:
LDR r11, [r14], #4 @load excf[i], excf[i+1]
LDR r10, [r12], #4 @load xn[i], xn[i+1]
@@ -128,13 +128,13 @@
MOV r10, #1
ADD r5, r10, r5, LSL #1 @L_tmp = (L_tmp << 1) + 1
ADD r6, r10, r6, LSL #1 @L_tmp1 = (L_tmp1 << 1) + 1
-
- CLZ r10, r5
+
+ CLZ r10, r5
CMP r5, #0
RSBLT r11, r5, #0
CLZLT r10, r11
SUB r10, r10, #1 @exp = norm_l(L_tmp)
-
+
MOV r5, r5, LSL r10 @L_tmp = (L_tmp << exp)
RSB r10, r10, #30 @exp_corr = 30 - exp
MOV r11, r5, ASR #16 @corr = extract_h(L_tmp)
@@ -150,7 +150,7 @@
@Isqrt_n(&L_tmp, &exp_norm)
MOV r14, r0
- MOV r12, r1
+ MOV r12, r1
STMFD sp!, {r0 - r4, r7 - r12, r14}
ADD r1, sp, #4
@@ -168,7 +168,7 @@
MOV r6, r6, ASR #16 @norm = extract_h(L_tmp)
MUL r12, r6, r11
ADD r12, r12, r12 @L_tmp = vo_L_mult(corr, norm)
-
+
ADD r6, r10, r5
ADD r6, r6, r7 @exp_corr + exp_norm + scale
@@ -187,9 +187,9 @@
CMP r4, r6
BEQ Norm_corr_asm_end
-
+
ADD r4, r4, #1 @ t_min ++
-
+
RSB r5, r4, #0 @ k
MOV r6, #63 @ i = 63
@@ -216,16 +216,16 @@
MUL r14, r11, r8
LDR r6, [r13, #T_MAX] @ get t_max
MOV r8, r14, ASR #15
- STRH r8, [r10]
+ STRH r8, [r10]
CMP r4, r6
BLE LOOPFOR
-Norm_corr_asm_end:
-
- ADD r13, r13, #voSTACK
+Norm_corr_asm_end:
+
+ ADD r13, r13, #voSTACK
LDMFD r13!, {r4 - r12, r15}
-
+
.END
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Syn_filt_32_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Syn_filt_32_opt.s
index 3f4930c..70464e4 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Syn_filt_32_opt.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Syn_filt_32_opt.s
@@ -38,7 +38,7 @@
Syn_filt_32_asm:
- STMFD r13!, {r4 - r12, r14}
+ STMFD r13!, {r4 - r12, r14}
LDR r4, [r13, #40] @ get sig_hi[] address
LDR r5, [r13, #44] @ get sig_lo[] address
@@ -55,7 +55,7 @@
AND r8, r8, r14
ORR r10, r6, r7, LSL #16 @ Aq[2] -- Aq[1]
ORR r11, r8, r9, LSL #16 @ Aq[4] -- Aq[3]
- STR r10, [r13, #-4]
+ STR r10, [r13, #-4]
STR r11, [r13, #-8]
LDRSH r6, [r0, #10] @ load Aq[5]
@@ -73,12 +73,12 @@
LDRSH r7, [r0, #20] @ load Aq[10]
LDRSH r8, [r0, #22] @ load Aq[11]
LDRSH r9, [r0, #24] @ load Aq[12]
- AND r6, r6, r14
+ AND r6, r6, r14
AND r8, r8, r14
ORR r10, r6, r7, LSL #16 @ Aq[10] -- Aq[9]
ORR r11, r8, r9, LSL #16 @ Aq[12] -- Aq[11]
STR r10, [r13, #-20]
- STR r11, [r13, #-24]
+ STR r11, [r13, #-24]
LDRSH r6, [r0, #26] @ load Aq[13]
LDRSH r7, [r0, #28] @ load Aq[14]
@@ -90,14 +90,14 @@
ORR r11, r8, r9, LSL #16 @ Aq[16] -- Aq[15]
STR r10, [r13, #-28]
STR r11, [r13, #-32]
-
+
MOV r8, #0 @ i = 0
-
-LOOP:
+
+LOOP:
LDRSH r6, [r5, #-2] @ load sig_lo[i-1]
LDRSH r7, [r5, #-4] @ load sig_lo[i-2]
- LDR r11, [r13, #-4] @ Aq[2] -- Aq[1]
+ LDR r11, [r13, #-4] @ Aq[2] -- Aq[1]
LDRSH r9, [r5, #-6] @ load sig_lo[i-3]
LDRSH r10, [r5, #-8] @ load sig_lo[i-4]
@@ -135,12 +135,12 @@
LDRSH r10, [r5, #-32] @ load sig_lo[i-16]
SMLABB r12, r6, r11, r12 @ sig_lo[i-13] * Aq[13]
SMLABT r12, r7, r11, r12 @ sig_lo[i-14] * Aq[14]
-
+
LDR r11, [r13, #-32] @ Aq[16] -- Aq[15]
- LDRSH r6, [r2],#2 @ load exc[i]
+ LDRSH r6, [r2],#2 @ load exc[i]
SMLABB r12, r9, r11, r12 @ sig_lo[i-15] * Aq[15]
SMLABT r12, r10, r11, r12 @ sig_lo[i-16] * Aq[16]
- MUL r7, r6, r3 @ exc[i] * a0
+ MUL r7, r6, r3 @ exc[i] * a0
RSB r14, r12, #0 @ L_tmp
MOV r14, r14, ASR #11 @ L_tmp >>= 11
ADD r14, r14, r7, LSL #1 @ L_tmp += (exc[i] * a0) << 1
@@ -149,7 +149,7 @@
LDRSH r6, [r4, #-2] @ load sig_hi[i-1]
LDRSH r7, [r4, #-4] @ load sig_hi[i-2]
- LDR r11, [r13, #-4] @ Aq[2] -- Aq[1]
+ LDR r11, [r13, #-4] @ Aq[2] -- Aq[1]
LDRSH r9, [r4, #-6] @ load sig_hi[i-3]
LDRSH r10, [r4, #-8] @ load sig_hi[i-4]
SMULBB r12, r6, r11 @ sig_hi[i-1] * Aq[1]
@@ -198,14 +198,14 @@
LDRSH r10, [r4, #-32] @ load sig_hi[i-16]
SMLABB r12, r6, r11, r12 @ sig_hi[i-13] * Aq[13]
SMLABT r12, r7, r11, r12 @ sig_hi[i-14] * Aq[14]
-
+
LDR r11, [r13, #-32] @ Aq[16] -- Aq[15]
SMLABB r12, r9, r11, r12 @ sig_hi[i-15] * Aq[15]
- SMLABT r12, r10, r11, r12 @ sig_hi[i-16] * Aq[16]
+ SMLABT r12, r10, r11, r12 @ sig_hi[i-16] * Aq[16]
ADD r6, r12, r12 @ r12 << 1
- SUB r14, r14, r6
+ SUB r14, r14, r6
MOV r14, r14, LSL #3 @ L_tmp <<=3
-
+
MOV r7, r14, ASR #16 @ L_tmp >> 16
MOV r14, r14, ASR #4 @ L_tmp >>=4
@@ -213,14 +213,14 @@
SUB r9, r14, r7, LSL #12 @ sig_lo[i] = L_tmp - (sig_hi[i] << 12)
ADD r8, r8, #1
- STRH r9, [r5], #2
+ STRH r9, [r5], #2
CMP r8, #64
- BLT LOOP
-
+ BLT LOOP
+
Syn_filt_32_end:
-
- LDMFD r13!, {r4 - r12, r15}
+
+ LDMFD r13!, {r4 - r12, r15}
@ENDFUNC
.END
-
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/convolve_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/convolve_opt.s
index 71bb532..0228bda 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/convolve_opt.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/convolve_opt.s
@@ -27,24 +27,24 @@
@ r3 --- L
.section .text
- .global Convolve_asm
+ .global Convolve_asm
Convolve_asm:
- STMFD r13!, {r4 - r12, r14}
+ STMFD r13!, {r4 - r12, r14}
MOV r3, #0 @ n
MOV r11, #0x8000
-
-LOOP:
+
+LOOP:
ADD r4, r1, r3, LSL #1 @ tmpH address
ADD r5, r3, #1 @ i = n + 1
MOV r6, r0 @ tmpX = x
LDRSH r9, [r6], #2 @ *tmpX++
LDRSH r10, [r4], #-2 @ *tmpH--
SUB r5, r5, #1
- MUL r8, r9, r10
+ MUL r8, r9, r10
-LOOP1:
+LOOP1:
CMP r5, #0
BLE L1
LDRSH r9, [r6], #2 @ *tmpX++
@@ -58,12 +58,12 @@
LDRSH r12, [r6], #2 @ *tmpX++
LDRSH r14, [r4], #-2 @ *tmpH--
MLA r8, r9, r10, r8
- SUBS r5, r5, #4
+ SUBS r5, r5, #4
MLA r8, r12, r14, r8
+
+ B LOOP1
- B LOOP1
-
-L1:
+L1:
ADD r5, r11, r8, LSL #1
MOV r5, r5, LSR #16 @extract_h(s)
@@ -75,14 +75,14 @@
ADD r5, r3, #1
MOV r6, r0
LDRSH r9, [r6], #2 @ *tmpX++
- LDRSH r10, [r4], #-2
+ LDRSH r10, [r4], #-2
LDRSH r12, [r6], #2
LDRSH r14, [r4], #-2
MUL r8, r9, r10
SUB r5, r5, #2
MLA r8, r12, r14, r8
-
+
LOOP2:
CMP r5, #0
BLE L2
@@ -97,14 +97,14 @@
LDRSH r12, [r6], #2 @ *tmpX++
LDRSH r14, [r4], #-2 @ *tmpH--
MLA r8, r9, r10, r8
- SUBS r5, r5, #4
+ SUBS r5, r5, #4
MLA r8, r12, r14, r8
B LOOP2
L2:
ADD r8, r11, r8, LSL #1
MOV r8, r8, LSR #16 @extract_h(s)
- ADD r3, r3, #1
+ ADD r3, r3, #1
STRH r8, [r2], #2 @y[n]
ADD r4, r1, r3, LSL #1
@@ -117,7 +117,7 @@
MUL r8, r9, r10
LDRSH r9, [r6], #2
LDRSH r10, [r4], #-2
- MLA r8, r12, r14, r8
+ MLA r8, r12, r14, r8
SUB r5, r5, #3
MLA r8, r9, r10, r8
@@ -135,9 +135,9 @@
LDRSH r12, [r6], #2 @ *tmpX++
LDRSH r14, [r4], #-2 @ *tmpH--
MLA r8, r9, r10, r8
- SUBS r5, r5, #4
- MLA r8, r12, r14, r8
- B LOOP3
+ SUBS r5, r5, #4
+ MLA r8, r12, r14, r8
+ B LOOP3
L3:
ADD r8, r11, r8, LSL #1
@@ -150,7 +150,7 @@
MOV r6, r0
MOV r8, #0
-LOOP4:
+LOOP4:
CMP r5, #0
BLE L4
LDRSH r9, [r6], #2 @ *tmpX++
@@ -164,22 +164,22 @@
LDRSH r12, [r6], #2 @ *tmpX++
LDRSH r14, [r4], #-2 @ *tmpH--
MLA r8, r9, r10, r8
- SUBS r5, r5, #4
- MLA r8, r12, r14, r8
- B LOOP4
-L4:
+ SUBS r5, r5, #4
+ MLA r8, r12, r14, r8
+ B LOOP4
+L4:
ADD r5, r11, r8, LSL #1
MOV r5, r5, LSR #16 @extract_h(s)
ADD r3, r3, #1
STRH r5, [r2], #2 @y[n]
-
+
CMP r3, #64
BLT LOOP
-
-Convolve_asm_end:
-
+
+Convolve_asm_end:
+
LDMFD r13!, {r4 - r12, r15}
-
+
@ENDFUNC
.END
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/cor_h_vec_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/cor_h_vec_opt.s
index 2d4c7cc..8f32733 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/cor_h_vec_opt.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/cor_h_vec_opt.s
@@ -51,12 +51,12 @@
RSB r11, r2, #62 @j=62-pos
LOOPj1:
- LDRSH r12, [r10], #2
+ LDRSH r12, [r10], #2
LDRSH r8, [r9], #2
LDRSH r14, [r9]
SUBS r11, r11, #1
MLA r5, r12, r8, r5
- MLA r6, r12, r14, r6
+ MLA r6, r12, r14, r6
BGE LOOPj1
LDRSH r12, [r10], #2 @*p1++
@@ -64,7 +64,7 @@
MLA r5, r12, r14, r5
MOV r14, #0x8000
MOV r5, r5, LSL #2 @L_sum1 = (L_sum1 << 2)
- ADD r10, r6, r14
+ ADD r10, r6, r14
ADD r9, r5, r14
MOV r5, r9, ASR #16
MOV r6, r10, ASR #16
@@ -76,7 +76,7 @@
MUL r14, r6, r11
MOV r5, r12, ASR #15
MOV r6, r14, ASR #15
- LDR r9, [r13, #44]
+ LDR r9, [r13, #44]
LDR r12, [r13, #48]
LDRSH r10, [r7], #2 @*p0++
LDRSH r11, [r8] @*p3++
@@ -88,7 +88,7 @@
STRH r6, [r12]
ADD r2, r2, #4
-
+
MOV r5, #0 @L_sum1 = 0
MOV r6, #0 @L_sum2 = 0
ADD r9, r1, r2, LSL #1 @p2 = &vec[pos]
@@ -97,12 +97,12 @@
ADD r4, r4, #1 @i++
LOOPj2:
- LDRSH r12, [r10], #2
+ LDRSH r12, [r10], #2
LDRSH r8, [r9], #2
LDRSH r14, [r9]
SUBS r11, r11, #1
MLA r5, r12, r8, r5
- MLA r6, r12, r14, r6
+ MLA r6, r12, r14, r6
BGE LOOPj2
LDRSH r12, [r10], #2 @*p1++
@@ -110,7 +110,7 @@
MLA r5, r12, r14, r5
MOV r14, #0x8000
MOV r5, r5, LSL #2 @L_sum1 = (L_sum1 << 2)
- ADD r10, r6, r14
+ ADD r10, r6, r14
ADD r9, r5, r14
MOV r5, r9, ASR #16
@@ -123,7 +123,7 @@
MUL r14, r6, r11
MOV r5, r12, ASR #15
MOV r6, r14, ASR #15
- LDR r9, [r13, #44]
+ LDR r9, [r13, #44]
LDR r12, [r13, #48]
LDRSH r10, [r7], #2 @*p0++
LDRSH r11, [r8] @*p3++
@@ -136,16 +136,16 @@
ADD r4, r4, #1 @i+1
ADD r2, r2, #4 @pos += STEP
CMP r4, #16
-
+
BLT LOOPi
-
+
the_end:
LDMFD r13!, {r4 - r12, r15}
-
+
@ENDFUNC
- .END
-
-
-
+ .END
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/pred_lt4_1_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/pred_lt4_1_opt.s
index e0b338d..d7b4509 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/pred_lt4_1_opt.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/pred_lt4_1_opt.s
@@ -35,7 +35,7 @@
pred_lt4_asm:
- STMFD r13!, {r4 - r12, r14}
+ STMFD r13!, {r4 - r12, r14}
RSB r4, r1, #0 @-T0
RSB r2, r2, #0 @frac = -frac
ADD r5, r0, r4, LSL #1 @x = exc - T0
@@ -45,7 +45,7 @@
SUB r5, r5, #30 @x -= 15
RSB r4, r2, #3 @k = 3 - frac
LDR r6, Table
- MOV r8, r4, LSL #6
+ MOV r8, r4, LSL #6
@MOV r7, #0 @j = 0
ADD r8, r6, r8 @ptr2 = &(inter4_2[k][0])
@@ -63,7 +63,7 @@
LDRSH r6, [r1], #2 @x[1]
LDRSH r9, [r1], #2 @x[2]
- SMULBB r10, r4, r3 @x[0] * h[0]
+ SMULBB r10, r4, r3 @x[0] * h[0]
SMULBB r11, r6, r3 @x[1] * h[0]
SMULBB r12, r9, r3 @x[2] * h[0]
@@ -285,7 +285,7 @@
SMLABB r10, r9, r3, r10 @x[2] * h[2]
SMLABB r11, r4, r3, r11 @x[3] * h[2]
-
+
SMLABT r10, r4, r3, r10 @x[3] * h[3]
SMLABT r11, r6, r3, r11 @x[4] * h[3]
@@ -435,7 +435,7 @@
MOV r11, r11, LSL #1
QADD r10, r10, r10
- QADD r11, r11, r11
+ QADD r11, r11, r11
QADD r10, r10, r5
QADD r11, r11, r5
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/residu_asm_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/residu_asm_opt.s
index 5ff0964..86b3bd6 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/residu_asm_opt.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/residu_asm_opt.s
@@ -34,12 +34,12 @@
LDRH r5, [r0], #2
LDRH r6, [r0], #2
- ORR r5, r6, r5, LSL #16 @r5 --- a0, a1
+ ORR r5, r6, r5, LSL #16 @r5 --- a0, a1
LDRH r6, [r0], #2
LDRH r7, [r0], #2
ORR r6, r7, r6, LSL #16 @r6 --- a2, a3
-
+
LDRH r7, [r0], #2
LDRH r8, [r0], #2
ORR r7, r8, r7, LSL #16 @r7 --- a4, a5
@@ -59,13 +59,13 @@
LDRH r11, [r0], #2
LDRH r12, [r0], #2
ORR r11, r12, r11, LSL #16 @r11 --- a12, a13
-
+
LDRH r12, [r0], #2
LDRH r4, [r0], #2
ORR r12, r4, r12, LSL #16 @r12 --- a14, a15
+
-
- STMFD r13!, {r8 - r12} @store r8-r12
+ STMFD r13!, {r8 - r12} @store r8-r12
LDRH r4, [r0], #2 @load a16
MOV r14, r3, ASR #2 @one loop get 4 outputs
ADD r1, r1, #4
@@ -78,7 +78,7 @@
LDR r2, [r1], #-4 @r2 --- x[1], x[0]
SMULTB r3, r5, r2 @i1(0) --- r3 = x[0] * a0
- SMULTT r4, r5, r2 @i2(0) --- r4 = x[1] * a0
+ SMULTT r4, r5, r2 @i2(0) --- r4 = x[1] * a0
SMULTB r11, r5, r10 @i3(0) --- r11 = x[2] * a0
SMULTT r12, r5, r10 @i4(0) --- r12 = x[3] * a0
@@ -88,20 +88,20 @@
SMLATB r11, r6, r2, r11 @i3(2) --- r11 += x[0] * a2
SMLATT r12, r6, r2, r12 @i4(2) --- r12 += x[1] * a2
- SMLABB r12, r6, r2, r12 @i4(3) --- r12 += x[0] * a3
-
+ SMLABB r12, r6, r2, r12 @i4(3) --- r12 += x[0] * a3
+
LDR r2, [r1], #-4 @r2 ---- x[-1], x[-2]
SMLABT r3, r5, r2, r3 @i1(1) --- r3 += x[-1] * a1
SMLATT r4, r6, r2, r4 @i2(2) --- r4 += x[-1] * a2
SMLABT r11, r6, r2, r11 @i3(3) --- r11 += x[-1] * a3
SMLATT r12, r7, r2, r12 @i4(4) --- r12 += x[-1] * a4
- SMLATB r3, r6, r2, r3 @i1(2) --- r3 += x[-2] * a2
+ SMLATB r3, r6, r2, r3 @i1(2) --- r3 += x[-2] * a2
SMLABB r4, r6, r2, r4 @ i2 (3)
SMLATB r11,r7, r2, r11 @ i3 (4)
SMLABB r12,r7, r2, r12 @ i4 (5)
-
+
LDR r2,[r1],#-4
SMLABT r3, r6, r2, r3 @ i1 (3)
SMLATT r4, r7, r2, r4 @ i2 (4)
@@ -111,7 +111,7 @@
SMLABB r4, r7, r2, r4 @ i2 (5)
SMLATB r11,r8, r2, r11 @ i3 (6)
SMLABB r12,r8, r2, r12 @ i4 (7)
-
+
LDR r2,[r1],#-4
SMLABT r3, r7, r2, r3 @ i1 (5)
SMLATT r4, r8, r2, r4 @ i2 (6)
@@ -122,7 +122,7 @@
SMLATB r11,r9, r2, r11 @ i3 (8)
SMLABB r12,r9, r2, r12 @ i4 (9)
LDR r10, [r13, #8] @ [ a10 | a11]
-
+
LDR r2,[r1],#-4
SMLABT r3, r8, r2, r3 @ i1 (7)
SMLATT r4, r9, r2, r4 @ i2 (8)
@@ -133,7 +133,7 @@
SMLATB r11,r10, r2, r11 @ i3 (10)
SMLABB r12,r10, r2, r12 @ i4 (11)
LDR r8, [r13, #12] @ [ a12 | a13 ]
-
+
LDR r2,[r1],#-4
SMLABT r3, r9, r2, r3 @ i1 (9)
SMLATT r4, r10, r2, r4 @ i2 (10)
@@ -144,7 +144,7 @@
SMLATB r11,r8, r2, r11 @ i3 (12)
SMLABB r12,r8, r2, r12 @ i4 (13)
LDR r9, [r13, #16] @ [ a14 | a15 ]
-
+
LDR r2,[r1],#-4
SMLABT r3, r10, r2, r3 @ i1 (11)
SMLATT r4, r8, r2, r4 @ i2 (12)
@@ -154,7 +154,7 @@
SMLABB r4, r8, r2, r4 @ i2 (13)
SMLATB r11,r9, r2, r11 @ i3 (14)
SMLABB r12,r9, r2, r12 @ i4 (15)
-
+
LDR r2,[r1],#-4
SMLABT r3, r8, r2, r3 @ i1 (13)
@@ -165,64 +165,64 @@
SMLABB r4, r9, r2, r4 @ i2 (15)
SMLABB r11,r14, r2, r11 @ i3 (16)
LDR r8, [r13] @ [ a6 | a7 ]
-
+
LDR r2,[r1],#44 @ Change
SMLABT r3, r9, r2, r3
SMLABB r3, r14, r2, r3
SMLABT r4, r14, r2, r4
LDR r9, [r13, #4] @ [ a8 | a9 ]
+
-
- QADD r3,r3,r3
- QADD r4,r4,r4
- QADD r11,r11,r11
- QADD r12,r12,r12
-
- QADD r3,r3,r3
- QADD r4,r4,r4
- QADD r11,r11,r11
- QADD r12,r12,r12
-
- QADD r3,r3,r3
- QADD r4,r4,r4
- QADD r11,r11,r11
- QADD r12,r12,r12
-
- QADD r3,r3,r3
- QADD r4,r4,r4
- QADD r11,r11,r11
- QADD r12,r12,r12
-
- MOV r2,#32768
-
- QDADD r3,r2,r3
- QDADD r4,r2,r4
- QDADD r11,r2,r11
- QDADD r12,r2,r12
-
-
+ QADD r3,r3,r3
+ QADD r4,r4,r4
+ QADD r11,r11,r11
+ QADD r12,r12,r12
+
+ QADD r3,r3,r3
+ QADD r4,r4,r4
+ QADD r11,r11,r11
+ QADD r12,r12,r12
+
+ QADD r3,r3,r3
+ QADD r4,r4,r4
+ QADD r11,r11,r11
+ QADD r12,r12,r12
+
+ QADD r3,r3,r3
+ QADD r4,r4,r4
+ QADD r11,r11,r11
+ QADD r12,r12,r12
+
+ MOV r2,#32768
+
+ QDADD r3,r2,r3
+ QDADD r4,r2,r4
+ QDADD r11,r2,r11
+ QDADD r12,r2,r12
+
+
MOV r3,r3,asr #16
MOV r4,r4,asr #16
MOV r11,r11,asr #16
MOV r12,r12,asr #16
-
+
STRH r3,[r0],#2
STRH r4,[r0],#2
STRH r11,[r0],#2
STRH r12,[r0],#2
-
+
MOV r2,r14,asr #16
SUB r14, r14, #0x10000
SUBS r2,r2,#1
- BNE residu_loop
+ BNE residu_loop
end:
- LDMFD r13!, {r8 -r12}
+ LDMFD r13!, {r8 -r12}
LDMFD r13!, {r4 -r12,pc}
@ENDFUNC
- .END
-
-
-
+ .END
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/scale_sig_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/scale_sig_opt.s
index b300224..f83e688 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/scale_sig_opt.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/scale_sig_opt.s
@@ -38,7 +38,7 @@
MOV r8, #0x7fffffff
MOV r9, #0x8000
BLE LOOP2
-
+
LOOP1:
LDRSH r5, [r4] @load x[i]
@@ -65,11 +65,11 @@
The_end:
LDMFD r13!, {r4 - r12, r15}
-
+
@ENDFUNC
- .END
-
-
-
+ .END
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/syn_filt_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/syn_filt_opt.s
index 0c287a4..f4700cd 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/syn_filt_opt.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/syn_filt_opt.s
@@ -33,18 +33,18 @@
Syn_filt_asm:
- STMFD r13!, {r4 - r12, r14}
+ STMFD r13!, {r4 - r12, r14}
SUB r13, r13, #700 @ y_buf[L_FRAME16k + M16k]
-
+
MOV r4, r3 @ copy mem[] address
MOV r5, r13 @ copy yy = y_buf address
@ for(i = 0@ i < m@ i++)
@{
@ *yy++ = mem[i]@
- @}
+ @}
- LDRH r6, [r4], #2
+ LDRH r6, [r4], #2
LDRH r7, [r4], #2
LDRH r8, [r4], #2
LDRH r9, [r4], #2
@@ -62,7 +62,7 @@
STRH r12, [r5], #2
STRH r14, [r5], #2
- LDRH r6, [r4], #2
+ LDRH r6, [r4], #2
LDRH r7, [r4], #2
LDRH r8, [r4], #2
LDRH r9, [r4], #2
@@ -92,45 +92,45 @@
LDRSH r9, [r0, #6] @ load a[3]
LDRSH r11,[r0, #8] @ load a[4]
AND r6, r6, r14
- AND r9, r9, r14
+ AND r9, r9, r14
ORR r10, r6, r7, LSL #16 @ -a[2] -- -a[1]
ORR r12, r9, r11, LSL #16 @ -a[4] -- -a[3]
STR r10, [r13, #-4]
STR r12, [r13, #-8]
-
+
LDRSH r6, [r0, #10] @ load a[5]
LDRSH r7, [r0, #12] @ load a[6]
LDRSH r9, [r0, #14] @ load a[7]
LDRSH r11,[r0, #16] @ load a[8]
AND r6, r6, r14
- AND r9, r9, r14
+ AND r9, r9, r14
ORR r10, r6, r7, LSL #16 @ -a[6] -- -a[5]
ORR r12, r9, r11, LSL #16 @ -a[8] -- -a[7]
STR r10, [r13, #-12]
- STR r12, [r13, #-16]
-
+ STR r12, [r13, #-16]
+
LDRSH r6, [r0, #18] @ load a[9]
LDRSH r7, [r0, #20] @ load a[10]
LDRSH r9, [r0, #22] @ load a[11]
LDRSH r11,[r0, #24] @ load a[12]
AND r6, r6, r14
- AND r9, r9, r14
+ AND r9, r9, r14
ORR r10, r6, r7, LSL #16 @ -a[10] -- -a[9]
ORR r12, r9, r11, LSL #16 @ -a[12] -- -a[11]
STR r10, [r13, #-20]
- STR r12, [r13, #-24]
+ STR r12, [r13, #-24]
LDRSH r6, [r0, #26] @ load a[13]
LDRSH r7, [r0, #28] @ load a[14]
LDRSH r9, [r0, #30] @ load a[15]
LDRSH r11,[r0, #32] @ load a[16]
AND r6, r6, r14
- AND r9, r9, r14
+ AND r9, r9, r14
ORR r10, r6, r7, LSL #16 @ -a[14] -- -a[13]
ORR r12, r9, r11, LSL #16 @ -a[16] -- -a[15]
STR r10, [r13, #-28]
- STR r12, [r13, #-32]
-
+ STR r12, [r13, #-32]
+
ADD r4, r13, #32
LOOP:
LDRSH r6, [r1], #2 @ load x[i]
@@ -155,8 +155,8 @@
SMLABB r14, r6, r7, r14 @ -a[3] * (*(temp_p -3))
LDRSH r9, [r10, #-10] @ *(temp_p - 5)
-
- SMLABT r14, r11, r7, r14 @ -a[4] * (*(temp_p -4))
+
+ SMLABT r14, r11, r7, r14 @ -a[4] * (*(temp_p -4))
LDR r7, [r13, #-12] @ -a[6] -a[5]
LDRSH r12, [r10, #-12] @ *(temp_p - 6)
@@ -169,13 +169,13 @@
LDR r7, [r13, #-16] @ -a[8] -a[7]
LDRSH r11, [r10, #-16] @ *(temp_p - 8)
-
+
SMLABB r14, r6, r7, r14 @ -a[7] * (*(temp_p -7))
LDRSH r9, [r10, #-18] @ *(temp_p - 9)
- SMLABT r14, r11, r7, r14 @ -a[8] * (*(temp_p -8))
-
+ SMLABT r14, r11, r7, r14 @ -a[8] * (*(temp_p -8))
+
LDR r7, [r13, #-20] @ -a[10] -a[9]
LDRSH r12, [r10, #-20] @ *(temp_p - 10)
@@ -192,11 +192,11 @@
LDRSH r9, [r10, #-26] @ *(temp_p - 13)
- SMLABT r14, r11, r7, r14 @ -a[12] * (*(temp_p -12))
+ SMLABT r14, r11, r7, r14 @ -a[12] * (*(temp_p -12))
LDR r7, [r13, #-28] @ -a[14] -a[13]
LDRSH r12, [r10, #-28] @ *(temp_p - 14)
-
+
SMLABB r14, r9, r7, r14 @ -a[13] * (*(temp_p -13))
LDRSH r6, [r10, #-30] @ *(temp_p - 15)
@@ -211,28 +211,28 @@
SMLABT r14, r11, r7, r14 @ -a[16] * (*(temp_p -16))
RSB r14, r14, r0
-
+
MOV r7, r14, LSL #4 @ L_tmp <<=4
ADD r8, r8, #1
- ADD r14, r7, #0x8000
+ ADD r14, r7, #0x8000
MOV r7, r14, ASR #16 @ (L_tmp + 0x8000) >> 16
CMP r8, #80
STRH r7, [r10] @ yy[i]
STRH r7, [r2], #2 @ y[i]
BLT LOOP
-
+
@ update mem[]
ADD r5, r13, #160 @ yy[64] address
MOV r1, r3
MOV r0, r5
MOV r2, #16
- BL voAWB_Copy
+ BL voAWB_Copy
Syn_filt_asm_end:
-
- ADD r13, r13, #700
- LDMFD r13!, {r4 - r12, r15}
+
+ ADD r13, r13, #700
+ LDMFD r13!, {r4 - r12, r15}
@ENDFUNC
.END
-
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Deemph_32_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Deemph_32_neon.s
index 1d5893f..2afc146 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Deemph_32_neon.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Deemph_32_neon.s
@@ -30,10 +30,10 @@
.section .text
.global Deemph_32_asm
-
+
Deemph_32_asm:
- STMFD r13!, {r4 - r12, r14}
+ STMFD r13!, {r4 - r12, r14}
MOV r4, #2 @i=0
LDRSH r6, [r0], #2 @load x_hi[0]
LDRSH r7, [r1], #2 @load x_lo[0]
@@ -47,9 +47,9 @@
ADD r12, r10, r7, LSL #4 @L_tmp += x_lo[0] << 4
MOV r10, r12, LSL #3 @L_tmp <<= 3
MUL r9, r5, r8
- LDRSH r6, [r0], #2 @load x_hi[1]
+ LDRSH r6, [r0], #2 @load x_hi[1]
QDADD r10, r10, r9
- LDRSH r7, [r1], #2 @load x_lo[1]
+ LDRSH r7, [r1], #2 @load x_lo[1]
MOV r12, r10, LSL #1 @L_tmp = L_mac(L_tmp, *mem, fac)
QADD r10, r12, r11
MOV r14, r10, ASR #16 @y[0] = round(L_tmp)
@@ -94,9 +94,9 @@
BLT LOOP
STR r14, [r3]
- STRH r14, [r2]
+ STRH r14, [r2]
- LDMFD r13!, {r4 - r12, r15}
+ LDMFD r13!, {r4 - r12, r15}
.END
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Dot_p_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Dot_p_neon.s
index 8230944..678f1d0 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Dot_p_neon.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Dot_p_neon.s
@@ -45,14 +45,14 @@
VLD1.S16 {Q12, Q13}, [r1]! @load 16 Word16 y[]
VMULL.S16 Q15, D16, D0
- VMLAL.S16 Q15, D17, D1
+ VMLAL.S16 Q15, D17, D1
VMLAL.S16 Q15, D18, D2
VMLAL.S16 Q15, D19, D3
- VLD1.S16 {Q0, Q1}, [r1]! @load 16 Word16 y[]
- VMLAL.S16 Q15, D20, D4
+ VLD1.S16 {Q0, Q1}, [r1]! @load 16 Word16 y[]
+ VMLAL.S16 Q15, D20, D4
VMLAL.S16 Q15, D21, D5
VMLAL.S16 Q15, D22, D6
- VMLAL.S16 Q15, D23, D7
+ VMLAL.S16 Q15, D23, D7
VMLAL.S16 Q15, D24, D8
VMLAL.S16 Q15, D25, D9
VMLAL.S16 Q15, D26, D10
@@ -64,9 +64,9 @@
CMP r2, #64
BEQ Lable1
- VLD1.S16 {Q0, Q1}, [r0]! @load 16 Word16 x[]
- VLD1.S16 {Q2, Q3}, [r1]!
- VMLAL.S16 Q15, D4, D0
+ VLD1.S16 {Q0, Q1}, [r0]! @load 16 Word16 x[]
+ VLD1.S16 {Q2, Q3}, [r1]!
+ VMLAL.S16 Q15, D4, D0
VMLAL.S16 Q15, D5, D1
VMLAL.S16 Q15, D6, D2
VMLAL.S16 Q15, D7, D3
@@ -102,11 +102,11 @@
VMLAL.S16 Q15, D2, D2
VMLAL.S16 Q15, D3, D3
-Lable1:
+Lable1:
VQADD.S32 D30, D30, D31
VPADD.S32 D30, D30, D30
- VMOV.S32 r12, D30[0]
+ VMOV.S32 r12, D30[0]
ADD r12, r12, r12
ADD r12, r12, #1 @ L_sum = (L_sum << 1) + 1
@@ -117,11 +117,11 @@
SUB r10, r10, #1 @ sft = norm_l(L_sum)
MOV r0, r12, LSL r10 @ L_sum = L_sum << sft
RSB r11, r10, #30 @ *exp = 30 - sft
- STRH r11, [r3]
+ STRH r11, [r3]
Dot_product12_end:
-
- LDMFD r13!, {r4 - r12, r15}
+
+ LDMFD r13!, {r4 - r12, r15}
.END
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Filt_6k_7k_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Filt_6k_7k_neon.s
index 14ba828..5389a1c 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Filt_6k_7k_neon.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Filt_6k_7k_neon.s
@@ -13,7 +13,7 @@
@ ** See the License for the specific language governing permissions and
@ ** limitations under the License.
@ */
-@
+@
@**********************************************************************/
@void Filt_6k_7k(
@ Word16 signal[], /* input: signal */
@@ -23,7 +23,7 @@
@***********************************************************************
@ r0 --- signal[]
@ r1 --- lg
-@ r2 --- mem[]
+@ r2 --- mem[]
.section .text
.global Filt_6k_7k_asm
@@ -31,7 +31,7 @@
Filt_6k_7k_asm:
- STMFD r13!, {r0 - r12, r14}
+ STMFD r13!, {r0 - r12, r14}
SUB r13, r13, #240 @ x[L_SUBFR16k + (L_FIR - 1)]
MOV r8, r0 @ copy signal[] address
MOV r5, r2 @ copy mem[] address
@@ -49,7 +49,7 @@
- LDR r10, Lable1 @ get fir_7k address
+ LDR r10, Lable1 @ get fir_7k address
MOV r3, r8 @ change myMemCopy to Copy, due to Copy will change r3 content
ADD r6, r13, #60 @ get x[L_FIR - 1] address
MOV r7, r3 @ get signal[i]
@@ -81,9 +81,9 @@
MOV r12, r5
@STR r5, [sp, #-4] @ PUSH r5 to stack
@ not use registers: r4, r10, r12, r14, r5
- MOV r4, r13
- MOV r5, #0 @ i = 0
-
+ MOV r4, r13
+ MOV r5, #0 @ i = 0
+
@ r4 --- x[i], r10 ---- fir_6k_7k
VLD1.S16 {Q0, Q1}, [r10]! @fir_6k_7k[0] ~ fir_6k_7k[15]
VLD1.S16 {Q2, Q3}, [r10]! @fir_6k_7k[16] ~ fir_6k_7k[31]
@@ -91,20 +91,20 @@
VLD1.S16 {Q4, Q5}, [r4]! @x[0] ~ x[15]
VLD1.S16 {Q6, Q7}, [r4]! @x[16] ~ X[31]
- VLD1.S16 {Q8}, [r4]!
- VMOV.S16 Q15, #0
-
+ VLD1.S16 {Q8}, [r4]!
+ VMOV.S16 Q15, #0
+
LOOP_6K7K:
- VMULL.S16 Q9,D8,D0[0]
- VMULL.S16 Q10,D9,D1[0]
- VMULL.S16 Q11,D9,D0[0]
+ VMULL.S16 Q9,D8,D0[0]
+ VMULL.S16 Q10,D9,D1[0]
+ VMULL.S16 Q11,D9,D0[0]
VMULL.S16 Q12,D10,D1[0]
VEXT.8 Q4,Q4,Q5,#2
VMLAL.S16 Q9,D10,D2[0]
VMLAL.S16 Q10,D11,D3[0]
VMLAL.S16 Q11,D11,D2[0]
- VMLAL.S16 Q12,D12,D3[0]
+ VMLAL.S16 Q12,D12,D3[0]
VEXT.8 Q5,Q5,Q6,#2
VMLAL.S16 Q9,D12,D4[0]
VMLAL.S16 Q10,D13,D5[0]
@@ -115,18 +115,18 @@
VMLAL.S16 Q10,D15,D7[0]
VMLAL.S16 Q11,D15,D6[0]
VMLAL.S16 Q12,D16,D7[0]
- VEXT.8 Q7,Q7,Q8,#2
+ VEXT.8 Q7,Q7,Q8,#2
- VMLAL.S16 Q9,D8,D0[1]
+ VMLAL.S16 Q9,D8,D0[1]
VMLAL.S16 Q10,D9,D1[1]
- VEXT.8 Q8,Q8,Q15,#2
- VMLAL.S16 Q11,D9,D0[1]
+ VEXT.8 Q8,Q8,Q15,#2
+ VMLAL.S16 Q11,D9,D0[1]
VMLAL.S16 Q12,D10,D1[1]
VEXT.8 Q4,Q4,Q5,#2
VMLAL.S16 Q9,D10,D2[1]
VMLAL.S16 Q10,D11,D3[1]
VMLAL.S16 Q11,D11,D2[1]
- VMLAL.S16 Q12,D12,D3[1]
+ VMLAL.S16 Q12,D12,D3[1]
VEXT.8 Q5,Q5,Q6,#2
VMLAL.S16 Q9,D12,D4[1]
VMLAL.S16 Q10,D13,D5[1]
@@ -137,18 +137,18 @@
VMLAL.S16 Q10,D15,D7[1]
VMLAL.S16 Q11,D15,D6[1]
VMLAL.S16 Q12,D16,D7[1]
- VEXT.8 Q7,Q7,Q8,#2
+ VEXT.8 Q7,Q7,Q8,#2
- VMLAL.S16 Q9,D8,D0[2]
+ VMLAL.S16 Q9,D8,D0[2]
VMLAL.S16 Q10,D9,D1[2]
- VEXT.8 Q8,Q8,Q15,#2
- VMLAL.S16 Q11,D9,D0[2]
+ VEXT.8 Q8,Q8,Q15,#2
+ VMLAL.S16 Q11,D9,D0[2]
VMLAL.S16 Q12,D10,D1[2]
VEXT.8 Q4,Q4,Q5,#2
VMLAL.S16 Q9,D10,D2[2]
VMLAL.S16 Q10,D11,D3[2]
VMLAL.S16 Q11,D11,D2[2]
- VMLAL.S16 Q12,D12,D3[2]
+ VMLAL.S16 Q12,D12,D3[2]
VEXT.8 Q5,Q5,Q6,#2
VMLAL.S16 Q9,D12,D4[2]
VMLAL.S16 Q10,D13,D5[2]
@@ -159,18 +159,18 @@
VMLAL.S16 Q10,D15,D7[2]
VMLAL.S16 Q11,D15,D6[2]
VMLAL.S16 Q12,D16,D7[2]
- VEXT.8 Q7,Q7,Q8,#2
+ VEXT.8 Q7,Q7,Q8,#2
- VMLAL.S16 Q9,D8,D0[3]
+ VMLAL.S16 Q9,D8,D0[3]
VMLAL.S16 Q10,D9,D1[3]
- VEXT.8 Q8,Q8,Q15,#2
- VMLAL.S16 Q11,D9,D0[3]
+ VEXT.8 Q8,Q8,Q15,#2
+ VMLAL.S16 Q11,D9,D0[3]
VMLAL.S16 Q12,D10,D1[3]
VEXT.8 Q4,Q4,Q5,#2
VMLAL.S16 Q9,D10,D2[3]
VMLAL.S16 Q10,D11,D3[3]
VMLAL.S16 Q11,D11,D2[3]
- VMLAL.S16 Q12,D12,D3[3]
+ VMLAL.S16 Q12,D12,D3[3]
VEXT.8 Q5,Q5,Q6,#2
VMLAL.S16 Q9,D12,D4[3]
VMLAL.S16 Q10,D13,D5[3]
@@ -181,10 +181,10 @@
VMLAL.S16 Q10,D15,D7[3]
VMLAL.S16 Q11,D15,D6[3]
VMLAL.S16 Q12,D16,D7[3]
- VEXT.8 Q7,Q7,Q8,#2
+ VEXT.8 Q7,Q7,Q8,#2
VMOV.S16 D8,D9
- VEXT.8 Q8,Q8,Q15,#2
+ VEXT.8 Q8,Q8,Q15,#2
VMOV.S16 D9,D10
VADD.S32 Q9,Q9,Q10
VMOV.S16 D10,D11
@@ -214,12 +214,12 @@
VST1.S16 {D4, D5, D6}, [r1]!
VST1.S16 D7[0], [r1]!
VST1.S16 D7[1], [r1]!
-
+
Filt_6k_7k_end:
- ADD r13, r13, #240
- LDMFD r13!, {r0 - r12, r15}
-
+ ADD r13, r13, #240
+ LDMFD r13!, {r0 - r12, r15}
+
Lable1:
.word fir_6k_7k
@ENDFUNC
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Norm_Corr_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Norm_Corr_neon.s
index 4263cd4..60e9ade 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Norm_Corr_neon.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Norm_Corr_neon.s
@@ -33,7 +33,7 @@
.section .text
- .global Norm_corr_asm
+ .global Norm_corr_asm
.extern Convolve_asm
.extern Isqrt_n
@******************************
@@ -47,17 +47,17 @@
.equ T_MIN , 212
.equ T_MAX , 216
.equ CORR_NORM , 220
-
+
Norm_corr_asm:
- STMFD r13!, {r4 - r12, r14}
+ STMFD r13!, {r4 - r12, r14}
SUB r13, r13, #voSTACK
-
+
ADD r8, r13, #20 @get the excf[L_SUBFR]
LDR r4, [r13, #T_MIN] @get t_min
RSB r11, r4, #0 @k = -t_min
- ADD r5, r0, r11, LSL #1 @get the &exc[k]
-
+ ADD r5, r0, r11, LSL #1 @get the &exc[k]
+
@transfer Convolve function
STMFD sp!, {r0 - r3}
MOV r0, r5
@@ -68,7 +68,7 @@
@ r8 --- excf[]
- MOV r14, r1 @copy xn[] address
+ MOV r14, r1 @copy xn[] address
MOV r7, #1
VLD1.S16 {Q0, Q1}, [r14]!
VLD1.S16 {Q2, Q3}, [r14]!
@@ -95,34 +95,34 @@
VQADD.S32 D20, D20, D21
VMOV.S32 r9, D20[0]
VMOV.S32 r10, D20[1]
- QADD r6, r9, r10
+ QADD r6, r9, r10
QADD r6, r6, r6
QADD r9, r6, r7 @L_tmp = (L_tmp << 1) + 1;
CLZ r7, r9
SUB r6, r7, #1 @exp = norm_l(L_tmp)
RSB r7, r6, #32 @exp = 32 - exp
- MOV r6, r7, ASR #1
+ MOV r6, r7, ASR #1
RSB r7, r6, #0 @scale = -(exp >> 1)
-
+
@loop for every possible period
@for(t = t_min@ t <= t_max@ t++)
@r7 --- scale r4 --- t_min r8 --- excf[]
-LOOPFOR:
+LOOPFOR:
ADD r14, r13, #20 @copy of excf[]
MOV r12, r1 @copy of xn[]
MOV r8, #0x8000
VLD1.S16 {Q0, Q1}, [r14]! @ load 16 excf[]
- VLD1.S16 {Q2, Q3}, [r14]! @ load 16 excf[]
+ VLD1.S16 {Q2, Q3}, [r14]! @ load 16 excf[]
VLD1.S16 {Q4, Q5}, [r12]! @ load 16 x[]
VLD1.S16 {Q6, Q7}, [r12]! @ load 16 x[]
VMULL.S16 Q10, D0, D0 @L_tmp1 += excf[] * excf[]
- VMULL.S16 Q11, D0, D8 @L_tmp += x[] * excf[]
+ VMULL.S16 Q11, D0, D8 @L_tmp += x[] * excf[]
VMLAL.S16 Q10, D1, D1
VMLAL.S16 Q11, D1, D9
VMLAL.S16 Q10, D2, D2
- VMLAL.S16 Q11, D2, D10
+ VMLAL.S16 Q11, D2, D10
VMLAL.S16 Q10, D3, D3
VMLAL.S16 Q11, D3, D11
VMLAL.S16 Q10, D4, D4
@@ -143,7 +143,7 @@
VMLAL.S16 Q10, D1, D1
VMLAL.S16 Q11, D1, D9
VMLAL.S16 Q10, D2, D2
- VMLAL.S16 Q11, D2, D10
+ VMLAL.S16 Q11, D2, D10
VMLAL.S16 Q10, D3, D3
VMLAL.S16 Q11, D3, D11
VMLAL.S16 Q10, D4, D4
@@ -162,19 +162,19 @@
VPADD.S32 D22, D22, D22 @D22[0] --- L_tmp << 1
VMOV.S32 r6, D20[0]
- VMOV.S32 r5, D22[0]
+ VMOV.S32 r5, D22[0]
@r5 --- L_tmp, r6 --- L_tmp1
MOV r10, #1
ADD r5, r10, r5, LSL #1 @L_tmp = (L_tmp << 1) + 1
ADD r6, r10, r6, LSL #1 @L_tmp1 = (L_tmp1 << 1) + 1
-
- CLZ r10, r5
+
+ CLZ r10, r5
CMP r5, #0
RSBLT r11, r5, #0
CLZLT r10, r11
SUB r10, r10, #1 @exp = norm_l(L_tmp)
-
+
MOV r5, r5, LSL r10 @L_tmp = (L_tmp << exp)
RSB r10, r10, #30 @exp_corr = 30 - exp
MOV r11, r5, ASR #16 @corr = extract_h(L_tmp)
@@ -190,7 +190,7 @@
@Isqrt_n(&L_tmp, &exp_norm)
MOV r14, r0
- MOV r12, r1
+ MOV r12, r1
STMFD sp!, {r0 - r4, r7 - r12, r14}
ADD r1, sp, #4
@@ -208,7 +208,7 @@
MOV r6, r6, ASR #16 @norm = extract_h(L_tmp)
MUL r12, r6, r11
ADD r12, r12, r12 @L_tmp = vo_L_mult(corr, norm)
-
+
ADD r6, r10, r5
ADD r6, r6, r7 @exp_corr + exp_norm + scale
@@ -227,8 +227,8 @@
CMP r4, r6
BEQ Norm_corr_asm_end
-
- ADD r4, r4, #1 @ t_min ++
+
+ ADD r4, r4, #1 @ t_min ++
RSB r5, r4, #0 @ k
MOV r6, #63 @ i = 63
@@ -255,16 +255,16 @@
MUL r14, r11, r8
LDR r6, [r13, #T_MAX] @ get t_max
MOV r8, r14, ASR #15
- STRH r8, [r10]
+ STRH r8, [r10]
CMP r4, r6
BLE LOOPFOR
-Norm_corr_asm_end:
-
- ADD r13, r13, #voSTACK
+Norm_corr_asm_end:
+
+ ADD r13, r13, #voSTACK
LDMFD r13!, {r4 - r12, r15}
-
+
.END
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Syn_filt_32_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Syn_filt_32_neon.s
index e786dde..1e65efa 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Syn_filt_32_neon.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Syn_filt_32_neon.s
@@ -33,12 +33,12 @@
@ sig_lo[] --- r5
@ lg --- r6
- .section .text
+ .section .text
.global Syn_filt_32_asm
Syn_filt_32_asm:
- STMFD r13!, {r4 - r12, r14}
+ STMFD r13!, {r4 - r12, r14}
LDR r4, [r13, #40] @ get sig_hi[] address
LDR r5, [r13, #44] @ get sig_lo[] address
@@ -49,8 +49,8 @@
SUB r10, r4, #32 @ sig_hi[-16] address
SUB r11, r5, #32 @ sig_lo[-16] address
- VLD1.S16 {D0, D1, D2, D3}, [r0]! @a[1] ~ a[16]
-
+ VLD1.S16 {D0, D1, D2, D3}, [r0]! @a[1] ~ a[16]
+
MOV r8, #0 @ i = 0
VLD1.S16 {D4, D5, D6, D7}, [r10]! @ sig_hi[-16] ~ sig_hi[-1]
@@ -58,9 +58,9 @@
VREV64.16 D1, D1
VLD1.S16 {D8, D9, D10, D11}, [r11]! @ sig_lo[-16] ~ sig_lo[-1]
VREV64.16 D2, D2
- VREV64.16 D3, D3
+ VREV64.16 D3, D3
VDUP.S32 Q15, r8
-
+
SYN_LOOP:
LDRSH r6, [r2], #2 @exc[i]
@@ -73,12 +73,12 @@
VEXT.8 D9, D9, D10, #2
VEXT.8 D10, D10, D11, #2
-
+
VPADD.S32 D28, D20, D21
MUL r12, r6, r3 @exc[i] * a0
VPADD.S32 D29, D28, D28
VDUP.S32 Q10, D29[0] @result1
-
+
VMULL.S16 Q11, D4, D3
VMLAL.S16 Q11, D5, D2
VSUB.S32 Q10, Q15, Q10
@@ -101,7 +101,7 @@
VSHR.S32 Q10, Q10, #11 @result1 >>= 11
VSHL.S32 Q11, Q11, #1 @result2 <<= 1
- VDUP.S32 Q12, r14
+ VDUP.S32 Q12, r14
VADD.S32 Q12, Q12, Q10 @L_tmp = L_tmp - (result1 >>= 11) - (result2 <<= 1)
VSUB.S32 Q12, Q12, Q11
@@ -122,12 +122,12 @@
STRH r12, [r5], #2 @stroe sig_lo[i]
CMP r8, #64
- BLT SYN_LOOP
-
+ BLT SYN_LOOP
+
Syn_filt_32_end:
-
- LDMFD r13!, {r4 - r12, r15}
+
+ LDMFD r13!, {r4 - r12, r15}
@ENDFUNC
.END
-
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/convolve_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/convolve_neon.s
index 8efa9fb..189e33b 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/convolve_neon.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/convolve_neon.s
@@ -20,22 +20,22 @@
@* Word16 y[], /* (o) : output vector */
@* Word16 L /* (i) : vector size */
@*)
-@
+@
@ r0 --- x[]
@ r1 --- h[]
@ r2 --- y[]
@ r3 --- L
- .section .text
- .global Convolve_asm
+ .section .text
+ .global Convolve_asm
Convolve_asm:
- STMFD r13!, {r4 - r12, r14}
- MOV r3, #0
+ STMFD r13!, {r4 - r12, r14}
+ MOV r3, #0
MOV r11, #0x8000
-
-LOOP:
+
+LOOP:
@MOV r8, #0 @ s = 0
ADD r4, r1, r3, LSL #1 @ tmpH address
ADD r5, r3, #1 @ i = n + 1
@@ -43,21 +43,21 @@
LDRSH r9, [r6], #2 @ *tmpX++
LDRSH r10, [r4] @ *tmpH--
SUB r5, r5, #1
- VMOV.S32 Q10, #0
- MUL r8, r9, r10
+ VMOV.S32 Q10, #0
+ MUL r8, r9, r10
-LOOP1:
+LOOP1:
CMP r5, #0
BLE L1
SUB r4, r4, #8
MOV r9, r4
- VLD1.S16 D0, [r6]!
+ VLD1.S16 D0, [r6]!
VLD1.S16 D1, [r9]!
VREV64.16 D1, D1
- SUBS r5, r5, #4
- VMLAL.S16 Q10, D0, D1
- B LOOP1
-L1:
+ SUBS r5, r5, #4
+ VMLAL.S16 Q10, D0, D1
+ B LOOP1
+L1:
VADD.S32 D20, D20, D21
VPADD.S32 D20, D20, D20
VMOV.S32 r5, D20[0]
@@ -73,25 +73,25 @@
ADD r5, r3, #1
MOV r6, r0
LDRSH r9, [r6], #2 @ *tmpX++
- LDRSH r10, [r4], #-2
+ LDRSH r10, [r4], #-2
LDRSH r12, [r6], #2
LDRSH r14, [r4]
MUL r8, r9, r10
SUB r5, r5, #2
MLA r8, r12, r14, r8
-
+
VMOV.S32 Q10, #0
LOOP2:
CMP r5, #0
BLE L2
SUB r4, r4, #8
MOV r9, r4
- VLD1.S16 D0, [r6]!
+ VLD1.S16 D0, [r6]!
VLD1.S16 D1, [r9]!
SUBS r5, r5, #4
VREV64.16 D1, D1
- VMLAL.S16 Q10, D0, D1
+ VMLAL.S16 Q10, D0, D1
B LOOP2
L2:
VADD.S32 D20, D20, D21
@@ -100,7 +100,7 @@
ADD r8, r8, r5
ADD r8, r11, r8, LSL #1
MOV r8, r8, LSR #16 @extract_h(s)
- ADD r3, r3, #1
+ ADD r3, r3, #1
STRH r8, [r2], #2 @y[n]
@@ -115,7 +115,7 @@
MUL r8, r9, r10
LDRSH r9, [r6], #2
LDRSH r10, [r4]
- MLA r8, r12, r14, r8
+ MLA r8, r12, r14, r8
SUB r5, r5, #3
MLA r8, r9, r10, r8
@@ -125,12 +125,12 @@
BLE L3
SUB r4, r4, #8
MOV r9, r4
- VLD1.S16 D0, [r6]!
+ VLD1.S16 D0, [r6]!
VLD1.S16 D1, [r9]!
VREV64.16 D1, D1
SUBS r5, r5, #4
- VMLAL.S16 Q10, D0, D1
- B LOOP3
+ VMLAL.S16 Q10, D0, D1
+ B LOOP3
L3:
VADD.S32 D20, D20, D21
@@ -146,18 +146,18 @@
ADD r4, r1, r5, LSL #1 @ tmpH address
MOV r6, r0
VMOV.S32 Q10, #0
-LOOP4:
+LOOP4:
CMP r5, #0
BLE L4
SUB r4, r4, #8
MOV r9, r4
- VLD1.S16 D0, [r6]!
+ VLD1.S16 D0, [r6]!
VLD1.S16 D1, [r9]!
VREV64.16 D1, D1
- SUBS r5, r5, #4
- VMLAL.S16 Q10, D0, D1
- B LOOP4
-L4:
+ SUBS r5, r5, #4
+ VMLAL.S16 Q10, D0, D1
+ B LOOP4
+L4:
VADD.S32 D20, D20, D21
VPADD.S32 D20, D20, D20
VMOV.S32 r5, D20[0]
@@ -165,14 +165,14 @@
MOV r5, r5, LSR #16 @extract_h(s)
ADD r3, r3, #1
STRH r5, [r2], #2 @y[n]
-
+
CMP r3, #64
BLT LOOP
-
-Convolve_asm_end:
-
+
+Convolve_asm_end:
+
LDMFD r13!, {r4 - r12, r15}
-
+
@ENDFUNC
.END
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/cor_h_vec_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/cor_h_vec_neon.s
index 8904289..c314a88 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/cor_h_vec_neon.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/cor_h_vec_neon.s
@@ -31,7 +31,7 @@
@r5 ---- cor_1[]
@r6 ---- cor_2[]
- .section .text
+ .section .text
.global cor_h_vec_012_asm
cor_h_vec_012_asm:
@@ -52,12 +52,12 @@
RSB r11, r2, #62 @j=62-pos
LOOPj1:
- LDRSH r12, [r10], #2
+ LDRSH r12, [r10], #2
LDRSH r8, [r9], #2
LDRSH r14, [r9]
SUBS r11, r11, #1
MLA r5, r12, r8, r5
- MLA r6, r12, r14, r6
+ MLA r6, r12, r14, r6
BGE LOOPj1
LDRSH r12, [r10], #2 @*p1++
@@ -65,7 +65,7 @@
MLA r5, r12, r14, r5
MOV r14, #0x8000
MOV r5, r5, LSL #2 @L_sum1 = (L_sum1 << 2)
- ADD r10, r6, r14
+ ADD r10, r6, r14
ADD r9, r5, r14
MOV r5, r9, ASR #16
MOV r6, r10, ASR #16
@@ -77,7 +77,7 @@
MUL r14, r6, r11
MOV r5, r12, ASR #15
MOV r6, r14, ASR #15
- LDR r9, [r13, #44]
+ LDR r9, [r13, #44]
LDR r12, [r13, #48]
LDRSH r10, [r7], #2 @*p0++
LDRSH r11, [r8] @*p3++
@@ -89,7 +89,7 @@
STRH r6, [r12]
ADD r2, r2, #4
-
+
MOV r5, #0 @L_sum1 = 0
MOV r6, #0 @L_sum2 = 0
ADD r9, r1, r2, LSL #1 @p2 = &vec[pos]
@@ -98,12 +98,12 @@
ADD r4, r4, #1 @i++
LOOPj2:
- LDRSH r12, [r10], #2
+ LDRSH r12, [r10], #2
LDRSH r8, [r9], #2
LDRSH r14, [r9]
SUBS r11, r11, #1
MLA r5, r12, r8, r5
- MLA r6, r12, r14, r6
+ MLA r6, r12, r14, r6
BGE LOOPj2
LDRSH r12, [r10], #2 @*p1++
@@ -111,7 +111,7 @@
MLA r5, r12, r14, r5
MOV r14, #0x8000
MOV r5, r5, LSL #2 @L_sum1 = (L_sum1 << 2)
- ADD r10, r6, r14
+ ADD r10, r6, r14
ADD r9, r5, r14
MOV r5, r9, ASR #16
@@ -124,7 +124,7 @@
MUL r14, r6, r11
MOV r5, r12, ASR #15
MOV r6, r14, ASR #15
- LDR r9, [r13, #44]
+ LDR r9, [r13, #44]
LDR r12, [r13, #48]
LDRSH r10, [r7], #2 @*p0++
LDRSH r11, [r8] @*p3++
@@ -137,15 +137,15 @@
ADD r4, r4, #1 @i+1
ADD r2, r2, #4 @pos += STEP
CMP r4, #16
-
+
BLT LOOPi
-
+
the_end:
LDMFD r13!, {r4 - r12, r15}
-
- .END
-
-
-
+
+ .END
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/pred_lt4_1_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/pred_lt4_1_neon.s
index 6b782cb..dffb750 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/pred_lt4_1_neon.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/pred_lt4_1_neon.s
@@ -25,14 +25,14 @@
@ r1 --- T0
@ r2 --- frac
@ r3 --- L_subfr
-
- .section .text
+
+ .section .text
.global pred_lt4_asm
.extern inter4_2
pred_lt4_asm:
- STMFD r13!, {r4 - r12, r14}
+ STMFD r13!, {r4 - r12, r14}
SUB r4, r0, r1, LSL #1 @ x = exc - T0
RSB r2, r2, #0 @ frac = - frac
SUB r4, r4, #30 @ x -= L_INTERPOL2 - 1
@@ -47,8 +47,8 @@
VLD1.S16 {Q0, Q1}, [r11]!
VLD1.S16 {Q2, Q3}, [r11]!
-
- MOV r6, #0x8000
+
+ MOV r6, #0x8000
VLD1.S16 {Q4, Q5}, [r4]! @load 16 x[]
VLD1.S16 {Q6, Q7}, [r4]! @load 16 x[]
@@ -58,14 +58,14 @@
VQDMLAL.S16 Q15, D9, D1
VQDMLAL.S16 Q15, D10, D2
VQDMLAL.S16 Q15, D11, D3
-
+
VQDMLAL.S16 Q15, D12, D4
VQDMLAL.S16 Q15, D13, D5
VQDMLAL.S16 Q15, D14, D6
VQDMLAL.S16 Q15, D15, D7
- LDRSH r12, [r4], #2
-
+ LDRSH r12, [r4], #2
+
VEXT.S16 D8, D8, D9, #1
VEXT.S16 D9, D9, D10, #1
VEXT.S16 D10, D10, D11, #1
@@ -73,26 +73,26 @@
VDUP.S16 D24, r12
VEXT.S16 D12, D12, D13, #1
VEXT.S16 D13, D13, D14, #1
-
+
VQADD.S32 D30, D30, D31
- MOV r11, #0x8000
+ MOV r11, #0x8000
VPADD.S32 D30, D30, D30
ADD r8, r8, #1
VMOV.S32 r12, D30[0]
- VEXT.S16 D14, D14, D15, #1
+ VEXT.S16 D14, D14, D15, #1
QADD r1, r12, r12 @ L_sum = (L_sum << 2)
VEXT.S16 D15, D15, D24, #1
- QADD r5, r1, r6
+ QADD r5, r1, r6
MOV r1, r5, ASR #16
CMP r8, r3
STRH r1, [r0], #2 @ exc[j] = (L_sum + 0x8000) >> 16
BLT LOOP
-
+
pred_lt4_end:
-
- LDMFD r13!, {r4 - r12, r15}
-
+
+ LDMFD r13!, {r4 - r12, r15}
+
Lable1:
.word inter4_2
@ENDFUNC
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/residu_asm_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/residu_asm_neon.s
index 394fa83..b9e6b23 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/residu_asm_neon.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/residu_asm_neon.s
@@ -26,17 +26,17 @@
@lg RN r3
.section .text
- .global Residu_opt
+ .global Residu_opt
Residu_opt:
- STMFD r13!, {r4 - r12, r14}
+ STMFD r13!, {r4 - r12, r14}
SUB r7, r3, #4 @i = lg - 4
-
- VLD1.S16 {D0, D1, D2, D3}, [r0]! @get all a[]
+
+ VLD1.S16 {D0, D1, D2, D3}, [r0]! @get all a[]
VLD1.S16 {D4}, [r0]!
VMOV.S32 Q8, #0x8000
-
+
LOOP1:
ADD r9, r1, r7, LSL #1 @copy the address
ADD r10, r2, r7, LSL #1
@@ -45,7 +45,7 @@
VQDMULL.S16 Q10, D5, D0[0] @finish the first L_mult
SUB r8, r9, #2 @get the x[i-1] address
- VLD1.S16 D5, [r8]!
+ VLD1.S16 D5, [r8]!
VQDMLAL.S16 Q10, D5, D0[1]
SUB r8, r9, #4 @load the x[i-2] address
@@ -53,36 +53,36 @@
VQDMLAL.S16 Q10, D5, D0[2]
SUB r8, r9, #6 @load the x[i-3] address
- VLD1.S16 D5, [r8]!
- VQDMLAL.S16 Q10, D5, D0[3]
+ VLD1.S16 D5, [r8]!
+ VQDMLAL.S16 Q10, D5, D0[3]
SUB r8, r9, #8 @load the x[i-4] address
- VLD1.S16 D5, [r8]!
- VQDMLAL.S16 Q10, D5, D1[0]
+ VLD1.S16 D5, [r8]!
+ VQDMLAL.S16 Q10, D5, D1[0]
SUB r8, r9, #10 @load the x[i-5] address
- VLD1.S16 D5, [r8]!
- VQDMLAL.S16 Q10, D5, D1[1]
+ VLD1.S16 D5, [r8]!
+ VQDMLAL.S16 Q10, D5, D1[1]
SUB r8, r9, #12 @load the x[i-6] address
- VLD1.S16 D5, [r8]!
- VQDMLAL.S16 Q10, D5, D1[2]
+ VLD1.S16 D5, [r8]!
+ VQDMLAL.S16 Q10, D5, D1[2]
SUB r8, r9, #14 @load the x[i-7] address
- VLD1.S16 D5, [r8]!
- VQDMLAL.S16 Q10, D5, D1[3]
+ VLD1.S16 D5, [r8]!
+ VQDMLAL.S16 Q10, D5, D1[3]
SUB r8, r9, #16 @load the x[i-8] address
- VLD1.S16 D5, [r8]!
- VQDMLAL.S16 Q10, D5, D2[0]
+ VLD1.S16 D5, [r8]!
+ VQDMLAL.S16 Q10, D5, D2[0]
SUB r8, r9, #18 @load the x[i-9] address
- VLD1.S16 D5, [r8]!
- VQDMLAL.S16 Q10, D5, D2[1]
-
+ VLD1.S16 D5, [r8]!
+ VQDMLAL.S16 Q10, D5, D2[1]
+
SUB r8, r9, #20 @load the x[i-10] address
- VLD1.S16 D5, [r8]!
- VQDMLAL.S16 Q10, D5, D2[2]
+ VLD1.S16 D5, [r8]!
+ VQDMLAL.S16 Q10, D5, D2[2]
SUB r8, r9, #22 @load the x[i-11] address
VLD1.S16 D5, [r8]!
@@ -117,10 +117,10 @@
BGE LOOP1
-Residu_asm_end:
-
+Residu_asm_end:
+
LDMFD r13!, {r4 - r12, r15}
-
+
@ENDFUNC
.END
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/scale_sig_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/scale_sig_neon.s
index e45daac..bbd354d 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/scale_sig_neon.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/scale_sig_neon.s
@@ -13,7 +13,7 @@
@ ** See the License for the specific language governing permissions and
@ ** limitations under the License.
@ */
-@
+@
@**********************************************************************/
@void Scale_sig(
@ Word16 x[], /* (i/o) : signal to scale */
@@ -25,16 +25,16 @@
@ lg --- r1
@ exp --- r2
- .section .text
+ .section .text
.global Scale_sig_opt
Scale_sig_opt:
- STMFD r13!, {r4 - r12, r14}
+ STMFD r13!, {r4 - r12, r14}
MOV r4, #4
- VMOV.S32 Q15, #0x8000
- VDUP.S32 Q14, r2
- MOV r5, r0 @ copy x[] address
+ VMOV.S32 Q15, #0x8000
+ VDUP.S32 Q14, r2
+ MOV r5, r0 @ copy x[] address
CMP r1, #64
MOVEQ r4, #1
BEQ LOOP
@@ -48,7 +48,7 @@
BEQ LOOP1
LOOP1:
- VLD1.S16 {Q0, Q1}, [r5]! @load 16 Word16 x[]
+ VLD1.S16 {Q0, Q1}, [r5]! @load 16 Word16 x[]
VSHLL.S16 Q10, D0, #16
VSHLL.S16 Q11, D1, #16
VSHLL.S16 Q12, D2, #16
@@ -63,7 +63,7 @@
VADDHN.S32 D19, Q13, Q15
VST1.S16 {Q8, Q9}, [r0]! @store 16 Word16 x[]
-LOOP:
+LOOP:
VLD1.S16 {Q0, Q1}, [r5]! @load 16 Word16 x[]
VLD1.S16 {Q2, Q3}, [r5]! @load 16 Word16 x[]
VLD1.S16 {Q4, Q5}, [r5]! @load 16 Word16 x[]
@@ -72,7 +72,7 @@
VSHLL.S16 Q8, D0, #16
VSHLL.S16 Q9, D1, #16
VSHLL.S16 Q10, D2, #16
- VSHLL.S16 Q11, D3, #16
+ VSHLL.S16 Q11, D3, #16
VSHL.S32 Q8, Q8, Q14
VSHL.S32 Q9, Q9, Q14
VSHL.S32 Q10, Q10, Q14
@@ -83,7 +83,7 @@
VADDHN.S32 D19, Q11, Q15
VST1.S16 {Q8, Q9}, [r0]! @store 16 Word16 x[]
-
+
VSHLL.S16 Q12, D4, #16
VSHLL.S16 Q13, D5, #16
VSHLL.S16 Q10, D6, #16
@@ -112,7 +112,7 @@
VADDHN.S32 D19, Q13, Q15
VST1.S16 {Q8, Q9}, [r0]! @store 16 Word16 x[]
- VSHLL.S16 Q10, D12, #16
+ VSHLL.S16 Q10, D12, #16
VSHLL.S16 Q11, D13, #16
VSHLL.S16 Q12, D14, #16
VSHLL.S16 Q13, D15, #16
@@ -123,16 +123,16 @@
VADDHN.S32 D16, Q10, Q15
VADDHN.S32 D17, Q11, Q15
VADDHN.S32 D18, Q12, Q15
- VADDHN.S32 D19, Q13, Q15
- VST1.S16 {Q8, Q9}, [r0]! @store 16 Word16 x[]
+ VADDHN.S32 D19, Q13, Q15
+ VST1.S16 {Q8, Q9}, [r0]! @store 16 Word16 x[]
SUBS r4, r4, #1
- BGT LOOP
-
-
+ BGT LOOP
+
+
Scale_sig_asm_end:
- LDMFD r13!, {r4 - r12, r15}
+ LDMFD r13!, {r4 - r12, r15}
@ENDFUNC
.END
-
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/syn_filt_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/syn_filt_neon.s
index 5731bdb..db4559c 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/syn_filt_neon.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/syn_filt_neon.s
@@ -27,21 +27,21 @@
@ mem[] --- r3
@ m --- 16 lg --- 80 update --- 1
- .section .text
+ .section .text
.global Syn_filt_asm
Syn_filt_asm:
- STMFD r13!, {r4 - r12, r14}
+ STMFD r13!, {r4 - r12, r14}
SUB r13, r13, #700 @ y_buf[L_FRAME16k + M16k]
-
+
MOV r4, r3 @ copy mem[] address
MOV r5, r13 @ copy yy = y_buf address
@ for(i = 0@ i < m@ i++)
@{
@ *yy++ = mem[i]@
- @}
+ @}
VLD1.S16 {D0, D1, D2, D3}, [r4]! @load 16 mems
VST1.S16 {D0, D1, D2, D3}, [r5]! @store 16 mem[] to *yy
@@ -54,7 +54,7 @@
VREV64.16 D0, D0
VREV64.16 D1, D1
VREV64.16 D2, D2
- VREV64.16 D3, D3
+ VREV64.16 D3, D3
MOV r8, #0 @ loop times
MOV r10, r13 @ temp = y_buf
ADD r4, r13, #32 @ yy[i] address
@@ -68,7 +68,7 @@
ADD r10, r4, r8, LSL #1 @ y[i], yy[i] address
VDUP.S32 Q10, r12
- VMULL.S16 Q5, D3, D4
+ VMULL.S16 Q5, D3, D4
VMLAL.S16 Q5, D2, D5
VMLAL.S16 Q5, D1, D6
VMLAL.S16 Q5, D0, D7
@@ -82,25 +82,25 @@
VDUP.S32 Q7, D10[0]
VSUB.S32 Q9, Q10, Q7
- VQRSHRN.S32 D20, Q9, #12
+ VQRSHRN.S32 D20, Q9, #12
VMOV.S16 r9, D20[0]
VEXT.8 D7, D7, D20, #2
CMP r8, #80
STRH r9, [r10] @ yy[i]
- STRH r9, [r2], #2 @ y[i]
-
+ STRH r9, [r2], #2 @ y[i]
+
BLT SYN_LOOP
-
+
@ update mem[]
ADD r5, r13, #160 @ yy[64] address
VLD1.S16 {D0, D1, D2, D3}, [r5]!
- VST1.S16 {D0, D1, D2, D3}, [r3]!
+ VST1.S16 {D0, D1, D2, D3}, [r3]!
Syn_filt_asm_end:
-
- ADD r13, r13, #700
- LDMFD r13!, {r4 - r12, r15}
+
+ ADD r13, r13, #700
+ LDMFD r13!, {r4 - r12, r15}
@ENDFUNC
.END
-
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/autocorr.c b/media/libstagefright/codecs/amrwbenc/src/autocorr.c
index 8c477ca..9baa937 100644
--- a/media/libstagefright/codecs/amrwbenc/src/autocorr.c
+++ b/media/libstagefright/codecs/amrwbenc/src/autocorr.c
@@ -70,19 +70,19 @@
p1 = y;
for (i = 0; i < L_WINDOW; i+=4)
{
- *p1 = vo_shr_r(*p1, shift);
+ *p1 = vo_shr_r(*p1, shift);
+ p1++;
+ *p1 = vo_shr_r(*p1, shift);
p1++;
*p1 = vo_shr_r(*p1, shift);
p1++;
- *p1 = vo_shr_r(*p1, shift);
- p1++;
- *p1 = vo_shr_r(*p1, shift);
+ *p1 = vo_shr_r(*p1, shift);
p1++;
}
}
/* Compute and normalize r[0] */
- L_sum = 1;
+ L_sum = 1;
for (i = 0; i < L_WINDOW; i+=4)
{
L_sum += vo_L_mult(y[i], y[i]);
diff --git a/media/libstagefright/codecs/amrwbenc/src/az_isp.c b/media/libstagefright/codecs/amrwbenc/src/az_isp.c
index 43db27a..9333d19 100644
--- a/media/libstagefright/codecs/amrwbenc/src/az_isp.c
+++ b/media/libstagefright/codecs/amrwbenc/src/az_isp.c
@@ -90,9 +90,9 @@
f1[i] = vo_round(t0 + (a[M - i] << 15)); /* =(a[i]+a[M-i])/2 */
f2[i] = vo_round(t0 - (a[M - i] << 15)); /* =(a[i]-a[M-i])/2 */
}
- f1[NC] = a[NC];
+ f1[NC] = a[NC];
for (i = 2; i < NC; i++) /* Divide by (1-z^-2) */
- f2[i] = add1(f2[i], f2[i - 2]);
+ f2[i] = add1(f2[i], f2[i - 2]);
/*---------------------------------------------------------------------*
* Find the ISPs (roots of F1(z) and F2(z) ) using the *
@@ -107,17 +107,17 @@
*---------------------------------------------------------------------*/
nf = 0; /* number of found frequencies */
ip = 0; /* indicator for f1 or f2 */
- coef = f1;
- order = NC;
- xlow = vogrid[0];
+ coef = f1;
+ order = NC;
+ xlow = vogrid[0];
ylow = Chebps2(xlow, coef, order);
j = 0;
while ((nf < M - 1) && (j < GRID_POINTS))
{
j ++;
- xhigh = xlow;
- yhigh = ylow;
- xlow = vogrid[j];
+ xhigh = xlow;
+ yhigh = ylow;
+ xlow = vogrid[j];
ylow = Chebps2(xlow, coef, order);
if ((ylow * yhigh) <= (Word32) 0)
{
@@ -128,12 +128,12 @@
ymid = Chebps2(xmid, coef, order);
if ((ylow * ymid) <= (Word32) 0)
{
- yhigh = ymid;
- xhigh = xmid;
+ yhigh = ymid;
+ xhigh = xmid;
} else
{
- ylow = ymid;
- xlow = xmid;
+ ylow = ymid;
+ xlow = xmid;
}
}
/*-------------------------------------------------------------*
@@ -144,10 +144,10 @@
y = yhigh - ylow;
if (y == 0)
{
- xint = xlow;
+ xint = xlow;
} else
{
- sign = y;
+ sign = y;
y = abs_s(y);
exp = norm_s(y);
y = y << exp;
@@ -161,19 +161,19 @@
t0 = (t0 >> 10); /* result in Q15 */
xint = vo_sub(xlow, vo_extract_l(t0)); /* xint = xlow - ylow*y */
}
- isp[nf] = xint;
- xlow = xint;
- nf++;
+ isp[nf] = xint;
+ xlow = xint;
+ nf++;
if (ip == 0)
{
- ip = 1;
- coef = f2;
- order = NC - 1;
+ ip = 1;
+ coef = f2;
+ order = NC - 1;
} else
{
- ip = 0;
- coef = f1;
- order = NC;
+ ip = 0;
+ coef = f1;
+ order = NC;
}
ylow = Chebps2(xlow, coef, order);
}
@@ -183,7 +183,7 @@
{
for (i = 0; i < M; i++)
{
- isp[i] = old_isp[i];
+ isp[i] = old_isp[i];
}
} else
{
@@ -243,9 +243,9 @@
b0_l = (t0 & 0xffff) >> 1;
b2_l = b1_l; /* b2 = b1; */
- b2_h = b1_h;
+ b2_h = b1_h;
b1_l = b0_l; /* b1 = b0; */
- b1_h = b0_h;
+ b1_h = b0_h;
}
t0 = ((b1_h * x)<<1) + (((b1_l * x)>>15)<<1);
diff --git a/media/libstagefright/codecs/amrwbenc/src/bits.c b/media/libstagefright/codecs/amrwbenc/src/bits.c
index e78dc1f..61cac3d 100644
--- a/media/libstagefright/codecs/amrwbenc/src/bits.c
+++ b/media/libstagefright/codecs/amrwbenc/src/bits.c
@@ -34,8 +34,8 @@
int PackBits(Word16 prms[], /* i: analysis parameters */
Word16 coding_mode, /* i: coding bit-stream ratio mode */
- Word16 mode, /* i: coding bit-stream ratio mode*/
- Coder_State *st /*i/o: coder global parameters struct */
+ Word16 mode, /* i: coding bit-stream ratio mode*/
+ Coder_State *st /*i/o: coder global parameters struct */
)
{
Word16 i, frame_type;
@@ -46,7 +46,7 @@
unsigned short* dataOut = st->outputStream;
if (coding_mode == MRDTX)
- {
+ {
st->sid_update_counter--;
if (st->prev_ft == TX_SPEECH)
@@ -92,7 +92,7 @@
} else
{
if (bitstreamformat == 1) /* ITU file format */
- {
+ {
*(dataOut) = 0x6b21;
if(frame_type != TX_NO_DATA && frame_type != TX_SID_FIRST)
{
@@ -100,17 +100,17 @@
for (i = 0; i < nb_of_bits[coding_mode]; i++)
{
if(prms[i] == BIT_0){
- *(dataOut + 2 + i) = BIT_0_ITU;
+ *(dataOut + 2 + i) = BIT_0_ITU;
}
else{
*(dataOut + 2 + i) = BIT_1_ITU;
}
}
- return (2 + nb_of_bits[coding_mode])<<1;
+ return (2 + nb_of_bits[coding_mode])<<1;
} else
{
*(dataOut + 1) = 0;
- return 2<<1;
+ return 2<<1;
}
} else /* MIME/storage file format */
{
@@ -191,7 +191,7 @@
)
{
Word16 i, bit;
- *prms += no_of_bits;
+ *prms += no_of_bits;
for (i = 0; i < no_of_bits; i++)
{
bit = (Word16) (value & 0x0001); /* get lsb */
@@ -199,9 +199,9 @@
*--(*prms) = BIT_0;
else
*--(*prms) = BIT_1;
- value >>= 1;
+ value >>= 1;
}
- *prms += no_of_bits;
+ *prms += no_of_bits;
return;
}
diff --git a/media/libstagefright/codecs/amrwbenc/src/c2t64fx.c b/media/libstagefright/codecs/amrwbenc/src/c2t64fx.c
index 18698e2..80990d9 100644
--- a/media/libstagefright/codecs/amrwbenc/src/c2t64fx.c
+++ b/media/libstagefright/codecs/amrwbenc/src/c2t64fx.c
@@ -79,7 +79,7 @@
#endif
Isqrt_n(&s, &exp);
- s = L_shl(s, add1(exp, 5));
+ s = L_shl(s, add1(exp, 5));
k_cn = vo_round(s);
/* set k_dn = 32..512 (ener_dn = 2^30..2^22) */
@@ -107,22 +107,22 @@
s = (k_cn* (*p0++))+(k_dn * (*p1++));
*p2++ = s >> 7;
s = (k_cn* (*p0++))+(k_dn * (*p1++));
- *p2++ = s >> 7;
+ *p2++ = s >> 7;
}
/* set sign according to dn2[] = k_cn*cn[] + k_dn*dn[] */
for (i = 0; i < L_SUBFR; i ++)
{
- val = dn[i];
- ps = dn2[i];
+ val = dn[i];
+ ps = dn2[i];
if (ps >= 0)
{
sign[i] = 32767; /* sign = +1 (Q12) */
- vec[i] = -32768;
+ vec[i] = -32768;
} else
{
sign[i] = -32768; /* sign = -1 (Q12) */
- vec[i] = 32767;
+ vec[i] = 32767;
dn[i] = -val;
}
}
@@ -130,13 +130,13 @@
* Compute h_inv[i]. *
*------------------------------------------------------------*/
/* impulse response buffer for fast computation */
- h = h_buf + L_SUBFR;
- h_inv = h + (L_SUBFR<<1);
+ h = h_buf + L_SUBFR;
+ h_inv = h + (L_SUBFR<<1);
for (i = 0; i < L_SUBFR; i++)
{
- h[i] = H[i];
- h_inv[i] = vo_negate(h[i]);
+ h[i] = H[i];
+ h_inv[i] = vo_negate(h[i]);
}
/*------------------------------------------------------------*
@@ -144,46 +144,46 @@
* Result is multiplied by 0.5 *
*------------------------------------------------------------*/
/* Init pointers to last position of rrixix[] */
- p0 = &rrixix[0][NB_POS - 1];
- p1 = &rrixix[1][NB_POS - 1];
+ p0 = &rrixix[0][NB_POS - 1];
+ p1 = &rrixix[1][NB_POS - 1];
- ptr_h1 = h;
+ ptr_h1 = h;
cor = 0x00010000L; /* for rounding */
for (i = 0; i < NB_POS; i++)
{
cor += ((*ptr_h1) * (*ptr_h1) << 1);
ptr_h1++;
- *p1-- = (extract_h(cor) >> 1);
+ *p1-- = (extract_h(cor) >> 1);
cor += ((*ptr_h1) * (*ptr_h1) << 1);
ptr_h1++;
- *p0-- = (extract_h(cor) >> 1);
+ *p0-- = (extract_h(cor) >> 1);
}
/*------------------------------------------------------------*
* Compute rrixiy[][] needed for the codebook search. *
*------------------------------------------------------------*/
- pos = MSIZE - 1;
- pos2 = MSIZE - 2;
- ptr_hf = h + 1;
+ pos = MSIZE - 1;
+ pos2 = MSIZE - 2;
+ ptr_hf = h + 1;
for (k = 0; k < NB_POS; k++)
{
- p1 = &rrixiy[pos];
- p0 = &rrixiy[pos2];
+ p1 = &rrixiy[pos];
+ p0 = &rrixiy[pos2];
cor = 0x00008000L; /* for rounding */
- ptr_h1 = h;
- ptr_h2 = ptr_hf;
+ ptr_h1 = h;
+ ptr_h2 = ptr_hf;
for (i = (k + 1); i < NB_POS; i++)
{
cor += ((*ptr_h1) * (*ptr_h2))<<1;
ptr_h1++;
ptr_h2++;
- *p1 = extract_h(cor);
+ *p1 = extract_h(cor);
cor += ((*ptr_h1) * (*ptr_h2))<<1;
ptr_h1++;
ptr_h2++;
- *p0 = extract_h(cor);
+ *p0 = extract_h(cor);
p1 -= (NB_POS + 1);
p0 -= (NB_POS + 1);
@@ -191,7 +191,7 @@
cor += ((*ptr_h1) * (*ptr_h2))<<1;
ptr_h1++;
ptr_h2++;
- *p1 = extract_h(cor);
+ *p1 = extract_h(cor);
pos -= NB_POS;
pos2--;
@@ -201,17 +201,17 @@
/*------------------------------------------------------------*
* Modification of rrixiy[][] to take signs into account. *
*------------------------------------------------------------*/
- p0 = rrixiy;
+ p0 = rrixiy;
for (i = 0; i < L_SUBFR; i += STEP)
{
- psign = sign;
+ psign = sign;
if (psign[i] < 0)
{
- psign = vec;
+ psign = vec;
}
for (j = 1; j < L_SUBFR; j += STEP)
{
- *p0 = vo_mult(*p0, psign[j]);
+ *p0 = vo_mult(*p0, psign[j]);
p0++;
}
}
@@ -220,20 +220,20 @@
* ~@~~~~~~~~~~~~~~ *
* 32 pos x 32 pos = 1024 tests (all combinaisons is tested) *
*-------------------------------------------------------------------*/
- p0 = rrixix[0];
- p1 = rrixix[1];
- p2 = rrixiy;
+ p0 = rrixix[0];
+ p1 = rrixix[1];
+ p2 = rrixiy;
- psk = -1;
- alpk = 1;
- ix = 0;
- iy = 1;
+ psk = -1;
+ alpk = 1;
+ ix = 0;
+ iy = 1;
for (i0 = 0; i0 < L_SUBFR; i0 += STEP)
{
- ps1 = dn[i0];
- alp1 = (*p0++);
- pos = -1;
+ ps1 = dn[i0];
+ alp1 = (*p0++);
+ pos = -1;
for (i1 = 1; i1 < L_SUBFR; i1 += STEP)
{
ps2 = add1(ps1, dn[i1]);
@@ -242,16 +242,16 @@
s = vo_L_mult(alpk, sq) - ((psk * alp2)<<1);
if (s > 0)
{
- psk = sq;
- alpk = alp2;
- pos = i1;
+ psk = sq;
+ alpk = alp2;
+ pos = i1;
}
}
p1 -= NB_POS;
if (pos >= 0)
{
- ix = i0;
- iy = pos;
+ ix = i0;
+ iy = pos;
}
}
/*-------------------------------------------------------------------*
@@ -260,7 +260,7 @@
for (i = 0; i < L_SUBFR; i++)
{
- code[i] = 0;
+ code[i] = 0;
}
i0 = (ix >> 1); /* pos of pulse 1 (0..31) */
@@ -268,24 +268,24 @@
if (sign[ix] > 0)
{
code[ix] = 512; /* codeword in Q9 format */
- p0 = h - ix;
+ p0 = h - ix;
} else
{
- code[ix] = -512;
- i0 += NB_POS;
- p0 = h_inv - ix;
+ code[ix] = -512;
+ i0 += NB_POS;
+ p0 = h_inv - ix;
}
if (sign[iy] > 0)
{
- code[iy] = 512;
- p1 = h - iy;
+ code[iy] = 512;
+ p1 = h - iy;
} else
{
- code[iy] = -512;
- i1 += NB_POS;
- p1 = h_inv - iy;
+ code[iy] = -512;
+ i1 += NB_POS;
+ p1 = h_inv - iy;
}
- *index = add1((i0 << 6), i1);
+ *index = add1((i0 << 6), i1);
for (i = 0; i < L_SUBFR; i++)
{
y[i] = vo_shr_r(add1((*p0++), (*p1++)), 3);
diff --git a/media/libstagefright/codecs/amrwbenc/src/c4t64fx.c b/media/libstagefright/codecs/amrwbenc/src/c4t64fx.c
index 1ecc11f..17f3d47 100644
--- a/media/libstagefright/codecs/amrwbenc/src/c4t64fx.c
+++ b/media/libstagefright/codecs/amrwbenc/src/c4t64fx.c
@@ -151,58 +151,58 @@
case 20: /* 20 bits, 4 pulses, 4 tracks */
nbiter = 4; /* 4x16x16=1024 loop */
alp = 8192; /* alp = 2.0 (Q12) */
- nb_pulse = 4;
- nbpos[0] = 4;
- nbpos[1] = 8;
+ nb_pulse = 4;
+ nbpos[0] = 4;
+ nbpos[1] = 8;
break;
case 36: /* 36 bits, 8 pulses, 4 tracks */
nbiter = 4; /* 4x20x16=1280 loop */
alp = 4096; /* alp = 1.0 (Q12) */
- nb_pulse = 8;
- nbpos[0] = 4;
- nbpos[1] = 8;
- nbpos[2] = 8;
+ nb_pulse = 8;
+ nbpos[0] = 4;
+ nbpos[1] = 8;
+ nbpos[2] = 8;
break;
case 44: /* 44 bits, 10 pulses, 4 tracks */
nbiter = 4; /* 4x26x16=1664 loop */
alp = 4096; /* alp = 1.0 (Q12) */
- nb_pulse = 10;
- nbpos[0] = 4;
- nbpos[1] = 6;
- nbpos[2] = 8;
- nbpos[3] = 8;
+ nb_pulse = 10;
+ nbpos[0] = 4;
+ nbpos[1] = 6;
+ nbpos[2] = 8;
+ nbpos[3] = 8;
break;
case 52: /* 52 bits, 12 pulses, 4 tracks */
nbiter = 4; /* 4x26x16=1664 loop */
alp = 4096; /* alp = 1.0 (Q12) */
- nb_pulse = 12;
- nbpos[0] = 4;
- nbpos[1] = 6;
- nbpos[2] = 8;
- nbpos[3] = 8;
+ nb_pulse = 12;
+ nbpos[0] = 4;
+ nbpos[1] = 6;
+ nbpos[2] = 8;
+ nbpos[3] = 8;
break;
case 64: /* 64 bits, 16 pulses, 4 tracks */
nbiter = 3; /* 3x36x16=1728 loop */
alp = 3277; /* alp = 0.8 (Q12) */
- nb_pulse = 16;
- nbpos[0] = 4;
- nbpos[1] = 4;
- nbpos[2] = 6;
- nbpos[3] = 6;
- nbpos[4] = 8;
- nbpos[5] = 8;
+ nb_pulse = 16;
+ nbpos[0] = 4;
+ nbpos[1] = 4;
+ nbpos[2] = 6;
+ nbpos[3] = 6;
+ nbpos[4] = 8;
+ nbpos[5] = 8;
break;
case 72: /* 72 bits, 18 pulses, 4 tracks */
nbiter = 3; /* 3x35x16=1680 loop */
alp = 3072; /* alp = 0.75 (Q12) */
- nb_pulse = 18;
- nbpos[0] = 2;
- nbpos[1] = 3;
- nbpos[2] = 4;
- nbpos[3] = 5;
- nbpos[4] = 6;
- nbpos[5] = 7;
- nbpos[6] = 8;
+ nb_pulse = 18;
+ nbpos[0] = 2;
+ nbpos[1] = 3;
+ nbpos[2] = 4;
+ nbpos[3] = 5;
+ nbpos[4] = 6;
+ nbpos[5] = 7;
+ nbpos[6] = 8;
break;
case 88: /* 88 bits, 24 pulses, 4 tracks */
if(ser_size > 462)
@@ -211,17 +211,17 @@
nbiter = 2; /* 2x53x16=1696 loop */
alp = 2048; /* alp = 0.5 (Q12) */
- nb_pulse = 24;
- nbpos[0] = 2;
- nbpos[1] = 2;
- nbpos[2] = 3;
- nbpos[3] = 4;
- nbpos[4] = 5;
- nbpos[5] = 6;
- nbpos[6] = 7;
- nbpos[7] = 8;
- nbpos[8] = 8;
- nbpos[9] = 8;
+ nb_pulse = 24;
+ nbpos[0] = 2;
+ nbpos[1] = 2;
+ nbpos[2] = 3;
+ nbpos[3] = 4;
+ nbpos[4] = 5;
+ nbpos[5] = 6;
+ nbpos[6] = 7;
+ nbpos[7] = 8;
+ nbpos[8] = 8;
+ nbpos[9] = 8;
break;
default:
nbiter = 0;
@@ -231,7 +231,7 @@
for (i = 0; i < nb_pulse; i++)
{
- codvec[i] = i;
+ codvec[i] = i;
}
/*----------------------------------------------------------------*
@@ -246,7 +246,7 @@
#endif
Isqrt_n(&s, &exp);
- s = L_shl(s, (exp + 5));
+ s = L_shl(s, (exp + 5));
k_cn = extract_h(L_add(s, 0x8000));
/* set k_dn = 32..512 (ener_dn = 2^30..2^22) */
@@ -274,22 +274,22 @@
s = (k_cn* (*p0++))+(k_dn * (*p1++));
*p2++ = s >> 7;
s = (k_cn* (*p0++))+(k_dn * (*p1++));
- *p2++ = s >> 7;
+ *p2++ = s >> 7;
}
/* set sign according to dn2[] = k_cn*cn[] + k_dn*dn[] */
for(i = 0; i < L_SUBFR; i++)
{
- val = dn[i];
- ps = dn2[i];
+ val = dn[i];
+ ps = dn2[i];
if (ps >= 0)
{
sign[i] = 32767; /* sign = +1 (Q12) */
- vec[i] = -32768;
+ vec[i] = -32768;
} else
{
sign[i] = -32768; /* sign = -1 (Q12) */
- vec[i] = 32767;
+ vec[i] = 32767;
dn[i] = -val;
dn2[i] = -ps;
}
@@ -302,19 +302,19 @@
{
for (k = 0; k < NB_MAX; k++)
{
- ps = -1;
+ ps = -1;
for (j = i; j < L_SUBFR; j += STEP)
{
if(dn2[j] > ps)
{
- ps = dn2[j];
- pos = j;
+ ps = dn2[j];
+ pos = j;
}
}
dn2[pos] = (k - NB_MAX); /* dn2 < 0 when position is selected */
if (k == 0)
{
- pos_max[i] = pos;
+ pos_max[i] = pos;
}
}
}
@@ -335,22 +335,22 @@
/* impulse response buffer for fast computation */
- h = h_buf;
- h_inv = h_buf + (2 * L_SUBFR);
+ h = h_buf;
+ h_inv = h_buf + (2 * L_SUBFR);
L_tmp = 0;
for (i = 0; i < L_SUBFR; i++)
{
- *h++ = 0;
- *h_inv++ = 0;
+ *h++ = 0;
+ *h_inv++ = 0;
L_tmp += (H[i] * H[i]) << 1;
}
/* scale h[] down (/2) when energy of h[] is high with many pulses used */
val = extract_h(L_tmp);
- h_shift = 0;
+ h_shift = 0;
if ((nb_pulse >= 12) && (val > 1024))
{
- h_shift = 1;
+ h_shift = 1;
}
p0 = H;
p1 = h;
@@ -358,14 +358,14 @@
for (i = 0; i < L_SUBFR/4; i++)
{
- *p1 = *p0++ >> h_shift;
- *p2++ = -(*p1++);
- *p1 = *p0++ >> h_shift;
- *p2++ = -(*p1++);
- *p1 = *p0++ >> h_shift;
- *p2++ = -(*p1++);
- *p1 = *p0++ >> h_shift;
- *p2++ = -(*p1++);
+ *p1 = *p0++ >> h_shift;
+ *p2++ = -(*p1++);
+ *p1 = *p0++ >> h_shift;
+ *p2++ = -(*p1++);
+ *p1 = *p0++ >> h_shift;
+ *p2++ = -(*p1++);
+ *p1 = *p0++ >> h_shift;
+ *p2++ = -(*p1++);
}
/*------------------------------------------------------------*
@@ -377,27 +377,27 @@
/* storage order --> i3i3, i2i2, i1i1, i0i0 */
/* Init pointers to last position of rrixix[] */
- p0 = &rrixix[0][NB_POS - 1];
- p1 = &rrixix[1][NB_POS - 1];
- p2 = &rrixix[2][NB_POS - 1];
- p3 = &rrixix[3][NB_POS - 1];
+ p0 = &rrixix[0][NB_POS - 1];
+ p1 = &rrixix[1][NB_POS - 1];
+ p2 = &rrixix[2][NB_POS - 1];
+ p3 = &rrixix[3][NB_POS - 1];
- ptr_h1 = h;
+ ptr_h1 = h;
cor = 0x00008000L; /* for rounding */
for (i = 0; i < NB_POS; i++)
{
cor += vo_L_mult((*ptr_h1), (*ptr_h1));
ptr_h1++;
- *p3-- = extract_h(cor);
+ *p3-- = extract_h(cor);
cor += vo_L_mult((*ptr_h1), (*ptr_h1));
ptr_h1++;
- *p2-- = extract_h(cor);
+ *p2-- = extract_h(cor);
cor += vo_L_mult((*ptr_h1), (*ptr_h1));
ptr_h1++;
- *p1-- = extract_h(cor);
+ *p1-- = extract_h(cor);
cor += vo_L_mult((*ptr_h1), (*ptr_h1));
ptr_h1++;
- *p0-- = extract_h(cor);
+ *p0-- = extract_h(cor);
}
/*------------------------------------------------------------*
@@ -409,38 +409,38 @@
/* storage order --> i2i3, i1i2, i0i1, i3i0 */
- pos = MSIZE - 1;
- ptr_hf = h + 1;
+ pos = MSIZE - 1;
+ ptr_hf = h + 1;
for (k = 0; k < NB_POS; k++)
{
- p3 = &rrixiy[2][pos];
- p2 = &rrixiy[1][pos];
- p1 = &rrixiy[0][pos];
- p0 = &rrixiy[3][pos - NB_POS];
+ p3 = &rrixiy[2][pos];
+ p2 = &rrixiy[1][pos];
+ p1 = &rrixiy[0][pos];
+ p0 = &rrixiy[3][pos - NB_POS];
cor = 0x00008000L; /* for rounding */
- ptr_h1 = h;
- ptr_h2 = ptr_hf;
+ ptr_h1 = h;
+ ptr_h2 = ptr_hf;
for (i = k + 1; i < NB_POS; i++)
{
cor += vo_L_mult((*ptr_h1), (*ptr_h2));
ptr_h1++;
ptr_h2++;
- *p3 = extract_h(cor);
+ *p3 = extract_h(cor);
cor += vo_L_mult((*ptr_h1), (*ptr_h2));
ptr_h1++;
ptr_h2++;
- *p2 = extract_h(cor);
+ *p2 = extract_h(cor);
cor += vo_L_mult((*ptr_h1), (*ptr_h2));
ptr_h1++;
ptr_h2++;
- *p1 = extract_h(cor);
+ *p1 = extract_h(cor);
cor += vo_L_mult((*ptr_h1), (*ptr_h2));
ptr_h1++;
ptr_h2++;
- *p0 = extract_h(cor);
+ *p0 = extract_h(cor);
p3 -= (NB_POS + 1);
p2 -= (NB_POS + 1);
@@ -450,15 +450,15 @@
cor += vo_L_mult((*ptr_h1), (*ptr_h2));
ptr_h1++;
ptr_h2++;
- *p3 = extract_h(cor);
+ *p3 = extract_h(cor);
cor += vo_L_mult((*ptr_h1), (*ptr_h2));
ptr_h1++;
ptr_h2++;
- *p2 = extract_h(cor);
+ *p2 = extract_h(cor);
cor += vo_L_mult((*ptr_h1), (*ptr_h2));
ptr_h1++;
ptr_h2++;
- *p1 = extract_h(cor);
+ *p1 = extract_h(cor);
pos -= NB_POS;
ptr_hf += STEP;
@@ -466,38 +466,38 @@
/* storage order --> i3i0, i2i3, i1i2, i0i1 */
- pos = MSIZE - 1;
- ptr_hf = h + 3;
+ pos = MSIZE - 1;
+ ptr_hf = h + 3;
for (k = 0; k < NB_POS; k++)
{
- p3 = &rrixiy[3][pos];
- p2 = &rrixiy[2][pos - 1];
- p1 = &rrixiy[1][pos - 1];
- p0 = &rrixiy[0][pos - 1];
+ p3 = &rrixiy[3][pos];
+ p2 = &rrixiy[2][pos - 1];
+ p1 = &rrixiy[1][pos - 1];
+ p0 = &rrixiy[0][pos - 1];
cor = 0x00008000L; /* for rounding */
- ptr_h1 = h;
- ptr_h2 = ptr_hf;
+ ptr_h1 = h;
+ ptr_h2 = ptr_hf;
for (i = k + 1; i < NB_POS; i++)
{
cor += vo_L_mult((*ptr_h1), (*ptr_h2));
ptr_h1++;
ptr_h2++;
- *p3 = extract_h(cor);
+ *p3 = extract_h(cor);
cor += vo_L_mult((*ptr_h1), (*ptr_h2));
ptr_h1++;
ptr_h2++;
- *p2 = extract_h(cor);
+ *p2 = extract_h(cor);
cor += vo_L_mult((*ptr_h1), (*ptr_h2));
ptr_h1++;
ptr_h2++;
- *p1 = extract_h(cor);
+ *p1 = extract_h(cor);
cor += vo_L_mult((*ptr_h1), (*ptr_h2));
ptr_h1++;
ptr_h2++;
- *p0 = extract_h(cor);
+ *p0 = extract_h(cor);
p3 -= (NB_POS + 1);
p2 -= (NB_POS + 1);
@@ -507,7 +507,7 @@
cor += vo_L_mult((*ptr_h1), (*ptr_h2));
ptr_h1++;
ptr_h2++;
- *p3 = extract_h(cor);
+ *p3 = extract_h(cor);
pos--;
ptr_hf += STEP;
@@ -517,22 +517,22 @@
* Modification of rrixiy[][] to take signs into account. *
*------------------------------------------------------------*/
- p0 = &rrixiy[0][0];
+ p0 = &rrixiy[0][0];
for (k = 0; k < NB_TRACK; k++)
{
j_temp = (k + 1)&0x03;
for (i = k; i < L_SUBFR; i += STEP)
{
- psign = sign;
+ psign = sign;
if (psign[i] < 0)
{
- psign = vec;
+ psign = vec;
}
j = j_temp;
for (; j < L_SUBFR; j += STEP)
{
- *p0 = vo_mult(*p0, psign[j]);
+ *p0 = vo_mult(*p0, psign[j]);
p0++;
}
}
@@ -542,8 +542,8 @@
* Deep first search *
*-------------------------------------------------------------------*/
- psk = -1;
- alpk = 1;
+ psk = -1;
+ alpk = 1;
for (k = 0; k < nbiter; k++)
{
@@ -553,12 +553,12 @@
if(nbbits == 20)
{
- pos = 0;
- ps = 0;
- alp = 0;
+ pos = 0;
+ ps = 0;
+ alp = 0;
for (i = 0; i < L_SUBFR; i++)
{
- vec[i] = 0;
+ vec[i] = 0;
}
} else if ((nbbits == 36) || (nbbits == 44))
{
@@ -591,18 +591,18 @@
if(nbbits == 44)
{
- ipos[8] = 0;
- ipos[9] = 1;
+ ipos[8] = 0;
+ ipos[9] = 1;
}
} else
{
/* first stage: fix 4 pulses */
pos = 4;
- ix = ind[0] = pos_max[ipos[0]];
- iy = ind[1] = pos_max[ipos[1]];
- i = ind[2] = pos_max[ipos[2]];
- j = ind[3] = pos_max[ipos[3]];
+ ix = ind[0] = pos_max[ipos[0]];
+ iy = ind[1] = pos_max[ipos[1]];
+ i = ind[2] = pos_max[ipos[2]];
+ j = ind[3] = pos_max[ipos[3]];
ps = add1(add1(add1(dn[ix], dn[iy]), dn[i]), dn[j]);
if (sign[ix] < 0)
@@ -636,8 +636,8 @@
if(nbbits == 72)
{
- ipos[16] = 0;
- ipos[17] = 1;
+ ipos[16] = 0;
+ ipos[17] = 1;
}
}
@@ -668,8 +668,8 @@
search_ixiy(nbpos[st], ipos[j], ipos[j + 1], &ps, &alp,
&ix, &iy, dn, dn2, cor_x, cor_y, rrixiy);
- ind[j] = ix;
- ind[j + 1] = iy;
+ ind[j] = ix;
+ ind[j + 1] = iy;
if (sign[ix] < 0)
p0 = h_inv - ix;
@@ -682,10 +682,10 @@
for (i = 0; i < L_SUBFR; i+=4)
{
- vec[i] += add1((*p0++), (*p1++));
- vec[i+1] += add1((*p0++), (*p1++));
- vec[i+2] += add1((*p0++), (*p1++));
- vec[i+3] += add1((*p0++), (*p1++));
+ vec[i] += add1((*p0++), (*p1++));
+ vec[i+1] += add1((*p0++), (*p1++));
+ vec[i+2] += add1((*p0++), (*p1++));
+ vec[i+3] += add1((*p0++), (*p1++));
}
}
/* memorise the best codevector */
@@ -693,15 +693,15 @@
s = vo_L_msu(vo_L_mult(alpk, ps), psk, alp);
if (s > 0)
{
- psk = ps;
- alpk = alp;
+ psk = ps;
+ alpk = alp;
for (i = 0; i < nb_pulse; i++)
{
- codvec[i] = ind[i];
+ codvec[i] = ind[i];
}
for (i = 0; i < L_SUBFR; i++)
{
- y[i] = vec[i];
+ y[i] = vec[i];
}
}
}
@@ -710,11 +710,11 @@
*-------------------------------------------------------------------*/
for (i = 0; i < NPMAXPT * NB_TRACK; i++)
{
- ind[i] = -1;
+ ind[i] = -1;
}
for (i = 0; i < L_SUBFR; i++)
{
- code[i] = 0;
+ code[i] = 0;
y[i] = vo_shr_r(y[i], 3); /* Q12 to Q9 */
}
val = (512 >> h_shift); /* codeword in Q9 format */
@@ -727,12 +727,12 @@
if (j > 0)
{
- code[i] += val;
- codvec[k] += 128;
+ code[i] += val;
+ codvec[k] += 128;
} else
{
- code[i] -= val;
- index += NB_POS;
+ code[i] -= val;
+ index += NB_POS;
}
i = (Word16)((vo_L_mult(track, NPMAXPT) >> 1));
@@ -741,10 +741,10 @@
{
i += 1;
}
- ind[i] = index;
+ ind[i] = index;
}
- k = 0;
+ k = 0;
/* Build index of codevector */
if(nbbits == 20)
{
@@ -849,20 +849,20 @@
p2 = &vec[pos];
for (j=pos;j < L_SUBFR; j++)
{
- L_sum1 += *p1 * *p2;
+ L_sum1 += *p1 * *p2;
p2-=3;
- L_sum2 += *p1++ * *p2;
+ L_sum2 += *p1++ * *p2;
p2+=4;
}
p2-=3;
- L_sum2 += *p1++ * *p2++;
- L_sum2 += *p1++ * *p2++;
- L_sum2 += *p1++ * *p2++;
+ L_sum2 += *p1++ * *p2++;
+ L_sum2 += *p1++ * *p2++;
+ L_sum2 += *p1++ * *p2++;
L_sum1 = (L_sum1 << 2);
L_sum2 = (L_sum2 << 2);
- corr = vo_round(L_sum1);
+ corr = vo_round(L_sum1);
*cor_x++ = vo_mult(corr, sign[pos]) + (*p0++);
corr = vo_round(L_sum2);
*cor_y++ = vo_mult(corr, sign[pos-3]) + (*p3++);
@@ -873,20 +873,20 @@
p2 = &vec[pos];
for (j=pos;j < L_SUBFR; j++)
{
- L_sum1 += *p1 * *p2;
+ L_sum1 += *p1 * *p2;
p2-=3;
- L_sum2 += *p1++ * *p2;
+ L_sum2 += *p1++ * *p2;
p2+=4;
}
p2-=3;
- L_sum2 += *p1++ * *p2++;
- L_sum2 += *p1++ * *p2++;
- L_sum2 += *p1++ * *p2++;
+ L_sum2 += *p1++ * *p2++;
+ L_sum2 += *p1++ * *p2++;
+ L_sum2 += *p1++ * *p2++;
L_sum1 = (L_sum1 << 2);
L_sum2 = (L_sum2 << 2);
- corr = vo_round(L_sum1);
+ corr = vo_round(L_sum1);
*cor_x++ = vo_mult(corr, sign[pos]) + (*p0++);
corr = vo_round(L_sum2);
*cor_y++ = vo_mult(corr, sign[pos-3]) + (*p3++);
@@ -982,17 +982,17 @@
Word16 *p0, *p1, *p2;
Word32 s, alp0, alp1, alp2;
- p0 = cor_x;
- p1 = cor_y;
- p2 = rrixiy[track_x];
+ p0 = cor_x;
+ p1 = cor_y;
+ p2 = rrixiy[track_x];
thres_ix = nb_pos_ix - NB_MAX;
alp0 = L_deposit_h(*alp);
alp0 = (alp0 + 0x00008000L); /* for rounding */
- sqk = -1;
- alpk = 1;
+ sqk = -1;
+ alpk = 1;
for (x = track_x; x < L_SUBFR; x += STEP)
{
@@ -1014,17 +1014,17 @@
if (s > 0)
{
- sqk = sq;
- alpk = alp_16;
- pos = y;
+ sqk = sq;
+ alpk = alp_16;
+ pos = y;
}
}
p1 -= NB_POS;
if (pos >= 0)
{
- *ix = x;
- *iy = pos;
+ *ix = x;
+ *iy = pos;
}
} else
{
@@ -1032,8 +1032,8 @@
}
}
- *ps = add1(*ps, add1(dn[*ix], dn[*iy]));
- *alp = alpk;
+ *ps = add1(*ps, add1(dn[*ix], dn[*iy]));
+ *alp = alpk;
return;
}
diff --git a/media/libstagefright/codecs/amrwbenc/src/convolve.c b/media/libstagefright/codecs/amrwbenc/src/convolve.c
index acba532..4f7fd8a 100644
--- a/media/libstagefright/codecs/amrwbenc/src/convolve.c
+++ b/media/libstagefright/codecs/amrwbenc/src/convolve.c
@@ -49,7 +49,7 @@
s += vo_mult32((*tmpX++), (*tmpH--));
i -= 4;
}
- y[n] = ((s<<1) + 0x8000)>>16;
+ y[n] = ((s<<1) + 0x8000)>>16;
n++;
tmpH = h+n;
@@ -66,7 +66,7 @@
s += vo_mult32((*tmpX++), (*tmpH--));
i -= 4;
}
- y[n] = ((s<<1) + 0x8000)>>16;
+ y[n] = ((s<<1) + 0x8000)>>16;
n++;
tmpH = h+n;
@@ -84,7 +84,7 @@
s += vo_mult32((*tmpX++), (*tmpH--));
i -= 4;
}
- y[n] = ((s<<1) + 0x8000)>>16;
+ y[n] = ((s<<1) + 0x8000)>>16;
n++;
s = 0;
@@ -99,8 +99,8 @@
s += vo_mult32((*tmpX++), (*tmpH--));
i -= 4;
}
- y[n] = ((s<<1) + 0x8000)>>16;
- n++;
+ y[n] = ((s<<1) + 0x8000)>>16;
+ n++;
}
return;
}
diff --git a/media/libstagefright/codecs/amrwbenc/src/cor_h_x.c b/media/libstagefright/codecs/amrwbenc/src/cor_h_x.c
index d9245ed..b645fa3 100644
--- a/media/libstagefright/codecs/amrwbenc/src/cor_h_x.c
+++ b/media/libstagefright/codecs/amrwbenc/src/cor_h_x.c
@@ -18,7 +18,7 @@
* File: cor_h_x.c *
* *
* Description:Compute correlation between target "x[]" and "h[]" *
-* Designed for codebook search (24 pulses, 4 tracks, *
+* Designed for codebook search (24 pulses, 4 tracks, *
* 4 pulses per track, 16 positions in each track) to *
* avoid saturation. *
* *
@@ -44,8 +44,8 @@
Word32 *p3;
Word32 L_max, L_max1, L_max2, L_max3;
/* first keep the result on 32 bits and find absolute maximum */
- L_tot = 1;
- L_max = 0;
+ L_tot = 1;
+ L_max = 0;
L_max1 = 0;
L_max2 = 0;
L_max3 = 0;
@@ -57,11 +57,11 @@
for (j = i; j < L_SUBFR; j++)
L_tmp += vo_L_mult(*p1++, *p2++);
- y32[i] = L_tmp;
+ y32[i] = L_tmp;
L_tmp = (L_tmp > 0)? L_tmp:-L_tmp;
if(L_tmp > L_max)
{
- L_max = L_tmp;
+ L_max = L_tmp;
}
L_tmp = 1L;
@@ -70,11 +70,11 @@
for (j = i+1; j < L_SUBFR; j++)
L_tmp += vo_L_mult(*p1++, *p2++);
- y32[i+1] = L_tmp;
+ y32[i+1] = L_tmp;
L_tmp = (L_tmp > 0)? L_tmp:-L_tmp;
if(L_tmp > L_max1)
{
- L_max1 = L_tmp;
+ L_max1 = L_tmp;
}
L_tmp = 1;
@@ -83,11 +83,11 @@
for (j = i+2; j < L_SUBFR; j++)
L_tmp += vo_L_mult(*p1++, *p2++);
- y32[i+2] = L_tmp;
+ y32[i+2] = L_tmp;
L_tmp = (L_tmp > 0)? L_tmp:-L_tmp;
if(L_tmp > L_max2)
{
- L_max2 = L_tmp;
+ L_max2 = L_tmp;
}
L_tmp = 1;
@@ -96,11 +96,11 @@
for (j = i+3; j < L_SUBFR; j++)
L_tmp += vo_L_mult(*p1++, *p2++);
- y32[i+3] = L_tmp;
+ y32[i+3] = L_tmp;
L_tmp = (L_tmp > 0)? L_tmp:-L_tmp;
if(L_tmp > L_max3)
{
- L_max3 = L_tmp;
+ L_max3 = L_tmp;
}
}
/* tot += 3*max / 8 */
diff --git a/media/libstagefright/codecs/amrwbenc/src/decim54.c b/media/libstagefright/codecs/amrwbenc/src/decim54.c
index 3b88514..7bc5576 100644
--- a/media/libstagefright/codecs/amrwbenc/src/decim54.c
+++ b/media/libstagefright/codecs/amrwbenc/src/decim54.c
@@ -136,8 +136,8 @@
L_sum += vo_mult32((*x++),(*y++));
L_sum += vo_mult32((*x),(*y));
- L_sum = L_shl2(L_sum, 2);
- sig_d[j] = extract_h(L_add(L_sum, 0x8000));
+ L_sum = L_shl2(L_sum, 2);
+ sig_d[j] = extract_h(L_add(L_sum, 0x8000));
pos += FAC5; /* pos + 5/4 */
}
return;
diff --git a/media/libstagefright/codecs/amrwbenc/src/deemph.c b/media/libstagefright/codecs/amrwbenc/src/deemph.c
index 0c49d6b..4ee1449 100644
--- a/media/libstagefright/codecs/amrwbenc/src/deemph.c
+++ b/media/libstagefright/codecs/amrwbenc/src/deemph.c
@@ -39,16 +39,16 @@
L_tmp = L_deposit_h(x[0]);
L_tmp = L_mac(L_tmp, *mem, mu);
- x[0] = vo_round(L_tmp);
+ x[0] = vo_round(L_tmp);
for (i = 1; i < L; i++)
{
L_tmp = L_deposit_h(x[i]);
L_tmp = L_mac(L_tmp, x[i - 1], mu);
- x[i] = voround(L_tmp);
+ x[i] = voround(L_tmp);
}
- *mem = x[L - 1];
+ *mem = x[L - 1];
return;
}
@@ -65,14 +65,14 @@
Word32 L_tmp;
L_tmp = x[0] << 15;
L_tmp += ((*mem) * mu)<<1;
- x[0] = (L_tmp + 0x8000)>>16;
+ x[0] = (L_tmp + 0x8000)>>16;
for (i = 1; i < L; i++)
{
L_tmp = x[i] << 15;
L_tmp += (x[i - 1] * mu)<<1;
- x[i] = (L_tmp + 0x8000)>>16;
+ x[i] = (L_tmp + 0x8000)>>16;
}
- *mem = x[L - 1];
+ *mem = x[L - 1];
return;
}
@@ -95,8 +95,8 @@
L_tmp += (x_lo[0] * 8)<<1;
L_tmp = (L_tmp << 3);
L_tmp += ((*mem) * fac)<<1;
- L_tmp = (L_tmp << 1);
- y[0] = (L_tmp + 0x8000)>>16;
+ L_tmp = (L_tmp << 1);
+ y[0] = (L_tmp + 0x8000)>>16;
for (i = 1; i < L; i++)
{
@@ -104,11 +104,11 @@
L_tmp += (x_lo[i] * 8)<<1;
L_tmp = (L_tmp << 3);
L_tmp += (y[i - 1] * fac)<<1;
- L_tmp = (L_tmp << 1);
- y[i] = (L_tmp + 0x8000)>>16;
+ L_tmp = (L_tmp << 1);
+ y[i] = (L_tmp + 0x8000)>>16;
}
- *mem = y[L - 1];
+ *mem = y[L - 1];
return;
}
diff --git a/media/libstagefright/codecs/amrwbenc/src/dtx.c b/media/libstagefright/codecs/amrwbenc/src/dtx.c
index 2cfaced..df53131 100644
--- a/media/libstagefright/codecs/amrwbenc/src/dtx.c
+++ b/media/libstagefright/codecs/amrwbenc/src/dtx.c
@@ -105,30 +105,30 @@
fprintf(stderr, "dtx_enc_reset: invalid parameter\n");
return -1;
}
- st->hist_ptr = 0;
- st->log_en_index = 0;
+ st->hist_ptr = 0;
+ st->log_en_index = 0;
/* Init isf_hist[] */
for (i = 0; i < DTX_HIST_SIZE; i++)
{
Copy(isf_init, &st->isf_hist[i * M], M);
}
- st->cng_seed = RANDOM_INITSEED;
+ st->cng_seed = RANDOM_INITSEED;
/* Reset energy history */
Set_zero(st->log_en_hist, DTX_HIST_SIZE);
- st->dtxHangoverCount = DTX_HANG_CONST;
- st->decAnaElapsedCount = 32767;
+ st->dtxHangoverCount = DTX_HANG_CONST;
+ st->decAnaElapsedCount = 32767;
for (i = 0; i < 28; i++)
{
- st->D[i] = 0;
+ st->D[i] = 0;
}
for (i = 0; i < DTX_HIST_SIZE - 1; i++)
{
- st->sumD[i] = 0;
+ st->sumD[i] = 0;
}
return 1;
@@ -279,7 +279,7 @@
for (i = 0; i < L_FRAME; i++)
{
tmp = mult(exc2[i], gain); /* Q0 * Q15 */
- exc2[i] = shl(tmp, exp);
+ exc2[i] = shl(tmp, exp);
}
return 0;
@@ -301,7 +301,7 @@
Word16 log_en_e;
Word16 log_en_m;
- st->hist_ptr = add(st->hist_ptr, 1);
+ st->hist_ptr = add(st->hist_ptr, 1);
if(st->hist_ptr == DTX_HIST_SIZE)
{
st->hist_ptr = 0;
@@ -345,7 +345,7 @@
{
/* this state machine is in synch with the GSMEFR txDtx machine */
- st->decAnaElapsedCount = add(st->decAnaElapsedCount, 1);
+ st->decAnaElapsedCount = add(st->decAnaElapsedCount, 1);
if (vad_flag != 0)
{
@@ -354,8 +354,8 @@
{ /* non-speech */
if (st->dtxHangoverCount == 0)
{ /* out of decoder analysis hangover */
- st->decAnaElapsedCount = 0;
- *usedMode = MRDTX;
+ st->decAnaElapsedCount = 0;
+ *usedMode = MRDTX;
} else
{ /* in possible analysis hangover */
st->dtxHangoverCount = sub(st->dtxHangoverCount, 1);
@@ -394,8 +394,8 @@
{
for (i = 0; i < M; i++)
{
- isf_tmp[k * M + i] = isf_old[indices[k] * M + i];
- isf_old[indices[k] * M + i] = isf_old[indices[2] * M + i];
+ isf_tmp[k * M + i] = isf_old[indices[k] * M + i];
+ isf_old[indices[k] * M + i] = isf_old[indices[2] * M + i];
}
}
}
@@ -403,13 +403,13 @@
/* Perform the ISF averaging */
for (j = 0; j < M; j++)
{
- L_tmp = 0;
+ L_tmp = 0;
for (i = 0; i < DTX_HIST_SIZE; i++)
{
L_tmp = L_add(L_tmp, L_deposit_l(isf_old[i * M + j]));
}
- isf_aver[j] = L_tmp;
+ isf_aver[j] = L_tmp;
}
/* Retrieve from isf_tmp[][] the ISF vectors saved prior to averaging */
@@ -441,12 +441,12 @@
/* sum sumD[0..DTX_HIST_SIZE-1]. sumD[DTX_HIST_SIZE] is */
/* not updated since it will be removed later. */
- tmp = DTX_HIST_SIZE_MIN_ONE;
- j = -1;
+ tmp = DTX_HIST_SIZE_MIN_ONE;
+ j = -1;
for (i = 0; i < DTX_HIST_SIZE_MIN_ONE; i++)
{
j = add(j, tmp);
- st->sumD[i] = L_sub(st->sumD[i], st->D[j]);
+ st->sumD[i] = L_sub(st->sumD[i], st->D[j]);
tmp = sub(tmp, 1);
}
@@ -458,86 +458,86 @@
for (i = DTX_HIST_SIZE_MIN_ONE; i > 0; i--)
{
- st->sumD[i] = st->sumD[i - 1];
+ st->sumD[i] = st->sumD[i - 1];
}
- st->sumD[0] = 0;
+ st->sumD[0] = 0;
/* Remove the oldest frame from the distance matrix. */
/* Note that the distance matrix is replaced by a one- */
/* dimensional array to save static memory. */
- tmp = 0;
+ tmp = 0;
for (i = 27; i >= 12; i = (Word16) (i - tmp))
{
tmp = add(tmp, 1);
for (j = tmp; j > 0; j--)
{
- st->D[i - j + 1] = st->D[i - j - tmp];
+ st->D[i - j + 1] = st->D[i - j - tmp];
}
}
/* Compute the first column of the distance matrix D */
/* (squared Euclidean distances from isf1[] to isf_old_tx[][]). */
- ptr = st->hist_ptr;
+ ptr = st->hist_ptr;
for (i = 1; i < DTX_HIST_SIZE; i++)
{
/* Compute the distance between the latest isf and the other isfs. */
ptr = sub(ptr, 1);
if (ptr < 0)
{
- ptr = DTX_HIST_SIZE_MIN_ONE;
+ ptr = DTX_HIST_SIZE_MIN_ONE;
}
- L_tmp = 0;
+ L_tmp = 0;
for (j = 0; j < M; j++)
{
tmp = sub(isf_old_tx[st->hist_ptr * M + j], isf_old_tx[ptr * M + j]);
L_tmp = L_mac(L_tmp, tmp, tmp);
}
- st->D[i - 1] = L_tmp;
+ st->D[i - 1] = L_tmp;
/* Update also the column sums. */
- st->sumD[0] = L_add(st->sumD[0], st->D[i - 1]);
- st->sumD[i] = L_add(st->sumD[i], st->D[i - 1]);
+ st->sumD[0] = L_add(st->sumD[0], st->D[i - 1]);
+ st->sumD[i] = L_add(st->sumD[i], st->D[i - 1]);
}
/* Find the minimum and maximum distances */
- summax = st->sumD[0];
- summin = st->sumD[0];
- indices[0] = 0;
- indices[2] = 0;
+ summax = st->sumD[0];
+ summin = st->sumD[0];
+ indices[0] = 0;
+ indices[2] = 0;
for (i = 1; i < DTX_HIST_SIZE; i++)
{
if (L_sub(st->sumD[i], summax) > 0)
{
- indices[0] = i;
- summax = st->sumD[i];
+ indices[0] = i;
+ summax = st->sumD[i];
}
if (L_sub(st->sumD[i], summin) < 0)
{
- indices[2] = i;
- summin = st->sumD[i];
+ indices[2] = i;
+ summin = st->sumD[i];
}
}
/* Find the second largest distance */
- summax2nd = -2147483647L;
- indices[1] = -1;
+ summax2nd = -2147483647L;
+ indices[1] = -1;
for (i = 0; i < DTX_HIST_SIZE; i++)
{
if ((L_sub(st->sumD[i], summax2nd) > 0) && (sub(i, indices[0]) != 0))
{
- indices[1] = i;
- summax2nd = st->sumD[i];
+ indices[1] = i;
+ summax2nd = st->sumD[i];
}
}
for (i = 0; i < 3; i++)
{
- indices[i] = sub(st->hist_ptr, indices[i]);
+ indices[i] = sub(st->hist_ptr, indices[i]);
if (indices[i] < 0)
{
- indices[i] = add(indices[i], DTX_HIST_SIZE);
+ indices[i] = add(indices[i], DTX_HIST_SIZE);
}
}
@@ -549,7 +549,7 @@
L_tmp = L_mult(voround(summax), INV_MED_THRESH);
if(L_tmp <= summin)
{
- indices[0] = -1;
+ indices[0] = -1;
}
/* If second largest distance/MED_THRESH is smaller than */
/* minimum distance then the median ISF vector replacement is */
@@ -558,7 +558,7 @@
L_tmp = L_mult(voround(summax2nd), INV_MED_THRESH);
if(L_tmp <= summin)
{
- indices[1] = -1;
+ indices[1] = -1;
}
return;
}
diff --git a/media/libstagefright/codecs/amrwbenc/src/g_pitch.c b/media/libstagefright/codecs/amrwbenc/src/g_pitch.c
index d681f2e..f5112c5 100644
--- a/media/libstagefright/codecs/amrwbenc/src/g_pitch.c
+++ b/media/libstagefright/codecs/amrwbenc/src/g_pitch.c
@@ -48,10 +48,10 @@
#endif
- g_coeff[0] = yy;
- g_coeff[1] = exp_yy;
- g_coeff[2] = xy;
- g_coeff[3] = exp_xy;
+ g_coeff[0] = yy;
+ g_coeff[1] = exp_yy;
+ g_coeff[2] = xy;
+ g_coeff[3] = exp_xy;
/* If (xy < 0) gain = 0 */
if (xy < 0)
@@ -65,12 +65,12 @@
i = exp_xy;
i -= exp_yy;
- gain = shl(gain, i);
+ gain = shl(gain, i);
/* if (gain > 1.2) gain = 1.2 in Q14 */
if(gain > 19661)
{
- gain = 19661;
+ gain = 19661;
}
return (gain);
}
diff --git a/media/libstagefright/codecs/amrwbenc/src/gpclip.c b/media/libstagefright/codecs/amrwbenc/src/gpclip.c
index 800b3f9..24158e3 100644
--- a/media/libstagefright/codecs/amrwbenc/src/gpclip.c
+++ b/media/libstagefright/codecs/amrwbenc/src/gpclip.c
@@ -22,7 +22,7 @@
* case occurs *
* a resonance on LPC filter(lp_disp < 60Hz) *
* a good pitch prediction (lp_gp > 0.95) *
-* *
+* *
***************************************************************************/
#include "typedef.h"
#include "basic_op.h"
@@ -38,8 +38,8 @@
Word16 mem[] /* (o) : memory of gain of pitch clipping algorithm */
)
{
- mem[0] = DIST_ISF_MAX;
- mem[1] = GAIN_PIT_MIN;
+ mem[0] = DIST_ISF_MAX;
+ mem[1] = GAIN_PIT_MIN;
}
@@ -49,7 +49,7 @@
{
Word16 clip = 0;
if ((mem[0] < DIST_ISF_THRES) && (mem[1] > GAIN_PIT_THRES))
- clip = 1;
+ clip = 1;
return (clip);
}
@@ -70,7 +70,7 @@
dist = vo_sub(isf[i], isf[i - 1]);
if(dist < dist_min)
{
- dist_min = dist;
+ dist_min = dist;
}
}
@@ -78,9 +78,9 @@
if (dist > DIST_ISF_MAX)
{
- dist = DIST_ISF_MAX;
+ dist = DIST_ISF_MAX;
}
- mem[0] = dist;
+ mem[0] = dist;
return;
}
@@ -100,9 +100,9 @@
if(gain < GAIN_PIT_MIN)
{
- gain = GAIN_PIT_MIN;
+ gain = GAIN_PIT_MIN;
}
- mem[1] = gain;
+ mem[1] = gain;
return;
}
diff --git a/media/libstagefright/codecs/amrwbenc/src/hp400.c b/media/libstagefright/codecs/amrwbenc/src/hp400.c
index a6f9701..fa66f1a 100644
--- a/media/libstagefright/codecs/amrwbenc/src/hp400.c
+++ b/media/libstagefright/codecs/amrwbenc/src/hp400.c
@@ -68,8 +68,8 @@
y2_lo = *mem++;
y1_hi = *mem++;
y1_lo = *mem++;
- x0 = *mem++;
- x1 = *mem;
+ x0 = *mem++;
+ x1 = *mem;
num = (Word32)lg;
do
{
@@ -98,7 +98,7 @@
*mem-- = y1_lo;
*mem-- = y1_hi;
*mem-- = y2_lo;
- *mem = y2_hi;
+ *mem = y2_hi;
return;
}
diff --git a/media/libstagefright/codecs/amrwbenc/src/hp50.c b/media/libstagefright/codecs/amrwbenc/src/hp50.c
index c1c7b83..36dd1f1 100644
--- a/media/libstagefright/codecs/amrwbenc/src/hp50.c
+++ b/media/libstagefright/codecs/amrwbenc/src/hp50.c
@@ -70,7 +70,7 @@
y2_lo = *mem++;
y1_hi = *mem++;
y1_lo = *mem++;
- x0 = *mem++;
+ x0 = *mem++;
x1 = *mem;
num = (Word32)lg;
do
@@ -98,7 +98,7 @@
*mem-- = y1_lo;
*mem-- = y1_hi;
*mem-- = y2_lo;
- *mem-- = y2_hi;
+ *mem-- = y2_hi;
return;
}
diff --git a/media/libstagefright/codecs/amrwbenc/src/hp6k.c b/media/libstagefright/codecs/amrwbenc/src/hp6k.c
index 8e66eb0..578633a 100644
--- a/media/libstagefright/codecs/amrwbenc/src/hp6k.c
+++ b/media/libstagefright/codecs/amrwbenc/src/hp6k.c
@@ -20,7 +20,7 @@
* Description:15th order band pass 6kHz to 7kHz FIR filter *
* frequency: 4kHz 5kHz 5.5kHz 6kHz 6.5kHz 7kHz 7.5kHz 8kHz *
* dB loss: -60dB -45dB -13dB -3dB 0dB -3dB -13dB -45dB *
-* *
+* *
************************************************************************/
#include "typedef.h"
@@ -63,7 +63,7 @@
for (i = lg - 1; i >= 0; i--)
{
x[i + L_FIR - 1] = signal[i] >> 2; /* gain of filter = 4 */
- }
+ }
for (i = 0; i < lg; i++)
{
L_tmp = (x[i] + x[i+ 30]) * fir_6k_7k[0];
diff --git a/media/libstagefright/codecs/amrwbenc/src/hp_wsp.c b/media/libstagefright/codecs/amrwbenc/src/hp_wsp.c
index bc1ec49..3510272 100644
--- a/media/libstagefright/codecs/amrwbenc/src/hp_wsp.c
+++ b/media/libstagefright/codecs/amrwbenc/src/hp_wsp.c
@@ -88,22 +88,22 @@
Word16 y3_hi, y3_lo, y2_hi, y2_lo, y1_hi, y1_lo;
Word32 i, L_tmp;
- y3_hi = mem[0];
- y3_lo = mem[1];
- y2_hi = mem[2];
- y2_lo = mem[3];
- y1_hi = mem[4];
- y1_lo = mem[5];
- x0 = mem[6];
- x1 = mem[7];
- x2 = mem[8];
+ y3_hi = mem[0];
+ y3_lo = mem[1];
+ y2_hi = mem[2];
+ y2_lo = mem[3];
+ y1_hi = mem[4];
+ y1_lo = mem[5];
+ x0 = mem[6];
+ x1 = mem[7];
+ x2 = mem[8];
for (i = 0; i < lg; i++)
{
- x3 = x2;
- x2 = x1;
- x1 = x0;
- x0 = wsp[i];
+ x3 = x2;
+ x2 = x1;
+ x1 = x0;
+ x0 = wsp[i];
/* y[i] = b[0]*x[i] + b[1]*x[i-1] + b140[2]*x[i-2] + b[3]*x[i-3] */
/* + a[1]*y[i-1] + a[2] * y[i-2] + a[3]*y[i-3] */
@@ -122,25 +122,25 @@
L_tmp = L_tmp << 2;
- y3_hi = y2_hi;
- y3_lo = y2_lo;
- y2_hi = y1_hi;
- y2_lo = y1_lo;
+ y3_hi = y2_hi;
+ y3_lo = y2_lo;
+ y2_hi = y1_hi;
+ y2_lo = y1_lo;
y1_hi = L_tmp >> 16;
y1_lo = (L_tmp & 0xffff) >>1;
- hp_wsp[i] = (L_tmp + 0x4000)>>15;
+ hp_wsp[i] = (L_tmp + 0x4000)>>15;
}
- mem[0] = y3_hi;
- mem[1] = y3_lo;
- mem[2] = y2_hi;
- mem[3] = y2_lo;
- mem[4] = y1_hi;
- mem[5] = y1_lo;
- mem[6] = x0;
- mem[7] = x1;
- mem[8] = x2;
+ mem[0] = y3_hi;
+ mem[1] = y3_lo;
+ mem[2] = y2_hi;
+ mem[3] = y2_lo;
+ mem[4] = y1_hi;
+ mem[5] = y1_lo;
+ mem[6] = x0;
+ mem[7] = x1;
+ mem[8] = x2;
return;
}
diff --git a/media/libstagefright/codecs/amrwbenc/src/int_lpc.c b/media/libstagefright/codecs/amrwbenc/src/int_lpc.c
index 1119bc7..88285e8 100644
--- a/media/libstagefright/codecs/amrwbenc/src/int_lpc.c
+++ b/media/libstagefright/codecs/amrwbenc/src/int_lpc.c
@@ -36,21 +36,21 @@
Word16 Az[] /* output: LP coefficients in 4 subframes */
)
{
- Word32 i, k;
+ Word32 i, k;
Word16 fac_old, fac_new;
Word16 isp[M];
Word32 L_tmp;
for (k = 0; k < 3; k++)
{
- fac_new = frac[k];
+ fac_new = frac[k];
fac_old = (32767 - fac_new) + 1; /* 1.0 - fac_new */
for (i = 0; i < M; i++)
{
L_tmp = (isp_old[i] * fac_old)<<1;
L_tmp += (isp_new[i] * fac_new)<<1;
- isp[i] = (L_tmp + 0x8000)>>16;
+ isp[i] = (L_tmp + 0x8000)>>16;
}
Isp_Az(isp, Az, M, 0);
Az += MP1;
diff --git a/media/libstagefright/codecs/amrwbenc/src/isp_az.c b/media/libstagefright/codecs/amrwbenc/src/isp_az.c
index 30a8bbd..c235c5d 100644
--- a/media/libstagefright/codecs/amrwbenc/src/isp_az.c
+++ b/media/libstagefright/codecs/amrwbenc/src/isp_az.c
@@ -42,7 +42,7 @@
/* 1 : adaptive scaling enabled */
)
{
- Word32 i, j;
+ Word32 i, j;
Word16 hi, lo;
Word32 f1[NC16k + 1], f2[NC16k];
Word16 nc;
@@ -92,14 +92,14 @@
lo = (f1[i] & 0xffff)>>1;
t0 = Mpy_32_16(hi, lo, isp[m - 1]);
- f1[i] = vo_L_add(f1[i], t0);
+ f1[i] = vo_L_add(f1[i], t0);
/* f2[i] *= (1.0 - isp[M-1]); */
hi = f2[i] >> 16;
lo = (f2[i] & 0xffff)>>1;
t0 = Mpy_32_16(hi, lo, isp[m - 1]);
- f2[i] = vo_L_sub(f2[i], t0);
+ f2[i] = vo_L_sub(f2[i], t0);
}
/*-----------------------------------------------------*
@@ -108,20 +108,20 @@
*-----------------------------------------------------*/
/* a[0] = 1.0; */
- a[0] = 4096;
- tmax = 1;
+ a[0] = 4096;
+ tmax = 1;
for (i = 1, j = m - 1; i < nc; i++, j--)
{
/* a[i] = 0.5*(f1[i] + f2[i]); */
t0 = vo_L_add(f1[i], f2[i]); /* f1[i] + f2[i] */
- tmax |= L_abs(t0);
+ tmax |= L_abs(t0);
a[i] = (Word16)(vo_L_shr_r(t0, 12)); /* from Q23 to Q12 and * 0.5 */
/* a[j] = 0.5*(f1[i] - f2[i]); */
t0 = vo_L_sub(f1[i], f2[i]); /* f1[i] - f2[i] */
- tmax |= L_abs(t0);
+ tmax |= L_abs(t0);
a[j] = (Word16)(vo_L_shr_r(t0, 12)); /* from Q23 to Q12 and * 0.5 */
}
@@ -144,12 +144,12 @@
t0 = vo_L_sub(f1[i], f2[i]); /* f1[i] - f2[i] */
a[j] = (Word16)(vo_L_shr_r(t0, q_sug)); /* from Q23 to Q12 and * 0.5 */
}
- a[0] = shr(a[0], q);
+ a[0] = shr(a[0], q);
}
else
{
- q_sug = 12;
- q = 0;
+ q_sug = 12;
+ q = 0;
}
/* a[NC] = 0.5*f1[NC]*(1.0 + isp[M-1]); */
hi = f1[nc] >> 16;
@@ -196,7 +196,7 @@
isp += 2; /* Advance isp pointer */
for (i = 2; i <= n; i++)
{
- *f = f[-2];
+ *f = f[-2];
for (j = 1; j < i; j++, f--)
{
hi = f[-1]>>16;
@@ -228,7 +228,7 @@
for (i = 2; i <= n; i++)
{
- *f = f[-2];
+ *f = f[-2];
for (j = 1; j < i; j++, f--)
{
VO_L_Extract(f[-1], &hi, &lo);
diff --git a/media/libstagefright/codecs/amrwbenc/src/isp_isf.c b/media/libstagefright/codecs/amrwbenc/src/isp_isf.c
index b4ba408..fbe80eb 100644
--- a/media/libstagefright/codecs/amrwbenc/src/isp_isf.c
+++ b/media/libstagefright/codecs/amrwbenc/src/isp_isf.c
@@ -51,9 +51,9 @@
/* acos(isp[i])= ind*128 + ( ( isp[i]-table[ind] ) * slope[ind] )/2048 */
L_tmp = vo_L_mult(vo_sub(isp[i], table[ind]), slope[ind]);
isf[i] = vo_round((L_tmp << 4)); /* (isp[i]-table[ind])*slope[ind])>>11 */
- isf[i] = add1(isf[i], (ind << 7));
+ isf[i] = add1(isf[i], (ind << 7));
}
- isf[m - 1] = (isf[m - 1] >> 1);
+ isf[m - 1] = (isf[m - 1] >> 1);
return;
}
@@ -69,7 +69,7 @@
for (i = 0; i < m - 1; i++)
{
- isp[i] = isf[i];
+ isp[i] = isf[i];
}
isp[m - 1] = (isf[m - 1] << 1);
@@ -80,7 +80,7 @@
/* isp[i] = table[ind]+ ((table[ind+1]-table[ind])*offset) / 128 */
L_tmp = vo_L_mult(vo_sub(table[ind + 1], table[ind]), offset);
- isp[i] = add1(table[ind], (Word16)((L_tmp >> 8)));
+ isp[i] = add1(table[ind], (Word16)((L_tmp >> 8)));
}
return;
diff --git a/media/libstagefright/codecs/amrwbenc/src/levinson.c b/media/libstagefright/codecs/amrwbenc/src/levinson.c
index 4b2f8ed..a68845f 100644
--- a/media/libstagefright/codecs/amrwbenc/src/levinson.c
+++ b/media/libstagefright/codecs/amrwbenc/src/levinson.c
@@ -122,8 +122,8 @@
Word16 *old_A, *old_rc;
/* Last A(z) for case of unstable filter */
- old_A = mem;
- old_rc = mem + M;
+ old_A = mem;
+ old_rc = mem + M;
/* K = A[1] = -R[1] / R[0] */
@@ -135,7 +135,7 @@
Kh = t0 >> 16;
Kl = (t0 & 0xffff)>>1;
- rc[0] = Kh;
+ rc[0] = Kh;
t0 = (t0 >> 4); /* A[1] in Q27 */
Ah[1] = t0 >> 16;
@@ -163,7 +163,7 @@
for (i = 2; i <= M; i++)
{
/* t0 = SUM ( R[j]*A[i-j] ,j=1,i-1 ) + R[i] */
- t0 = 0;
+ t0 = 0;
for (j = 1; j < i; j++)
t0 = vo_L_add(t0, Mpy_32(Rh[j], Rl[j], Ah[i - j], Al[i - j]));
@@ -182,14 +182,14 @@
Kh = t2 >> 16;
Kl = (t2 & 0xffff)>>1;
- rc[i - 1] = Kh;
+ rc[i - 1] = Kh;
/* Test for unstable filter. If unstable keep old A(z) */
if (abs_s(Kh) > 32750)
{
A[0] = 4096; /* Ai[0] not stored (always 1.0) */
for (j = 0; j < M; j++)
{
- A[j + 1] = old_A[j];
+ A[j + 1] = old_A[j];
}
rc[0] = old_rc[0]; /* only two rc coefficients are needed */
rc[1] = old_rc[1];
@@ -229,19 +229,19 @@
/* A[j] = An[j] */
for (j = 1; j <= i; j++)
{
- Ah[j] = Anh[j];
- Al[j] = Anl[j];
+ Ah[j] = Anh[j];
+ Al[j] = Anl[j];
}
}
/* Truncate A[i] in Q27 to Q12 with rounding */
- A[0] = 4096;
+ A[0] = 4096;
for (i = 1; i <= M; i++)
{
t0 = (Ah[i] << 16) + (Al[i] << 1);
- old_A[i - 1] = A[i] = vo_round((t0 << 1));
+ old_A[i - 1] = A[i] = vo_round((t0 << 1));
}
- old_rc[0] = rc[0];
- old_rc[1] = rc[1];
+ old_rc[0] = rc[0];
+ old_rc[1] = rc[1];
return;
}
diff --git a/media/libstagefright/codecs/amrwbenc/src/log2.c b/media/libstagefright/codecs/amrwbenc/src/log2.c
index 0f65541..646d6af 100644
--- a/media/libstagefright/codecs/amrwbenc/src/log2.c
+++ b/media/libstagefright/codecs/amrwbenc/src/log2.c
@@ -64,11 +64,11 @@
Word32 L_y;
if (L_x <= (Word32) 0)
{
- *exponent = 0;
- *fraction = 0;
+ *exponent = 0;
+ *fraction = 0;
return;
}
- *exponent = (30 - exp);
+ *exponent = (30 - exp);
L_x = (L_x >> 9);
i = extract_h (L_x); /* Extract b25-b31 */
L_x = (L_x >> 1);
@@ -78,7 +78,7 @@
L_y = L_deposit_h (table[i]); /* table[i] << 16 */
tmp = vo_sub(table[i], table[i + 1]); /* table[i] - table[i+1] */
L_y = vo_L_msu (L_y, tmp, a); /* L_y -= tmp*a*2 */
- *fraction = extract_h (L_y);
+ *fraction = extract_h (L_y);
return;
}
diff --git a/media/libstagefright/codecs/amrwbenc/src/lp_dec2.c b/media/libstagefright/codecs/amrwbenc/src/lp_dec2.c
index 1d5d076..29bd46b 100644
--- a/media/libstagefright/codecs/amrwbenc/src/lp_dec2.c
+++ b/media/libstagefright/codecs/amrwbenc/src/lp_dec2.c
@@ -42,25 +42,25 @@
Word32 i, j;
Word32 L_tmp;
/* copy initial filter states into buffer */
- p_x = x_buf;
+ p_x = x_buf;
for (i = 0; i < L_MEM; i++)
{
- *p_x++ = mem[i];
- mem[i] = x[l - L_MEM + i];
+ *p_x++ = mem[i];
+ mem[i] = x[l - L_MEM + i];
}
for (i = 0; i < l; i++)
{
- *p_x++ = x[i];
+ *p_x++ = x[i];
}
for (i = 0, j = 0; i < l; i += 2, j++)
{
- p_x = &x_buf[i];
+ p_x = &x_buf[i];
L_tmp = ((*p_x++) * h_fir[0]);
L_tmp += ((*p_x++) * h_fir[1]);
L_tmp += ((*p_x++) * h_fir[2]);
L_tmp += ((*p_x++) * h_fir[3]);
L_tmp += ((*p_x++) * h_fir[4]);
- x[j] = (L_tmp + 0x4000)>>15;
+ x[j] = (L_tmp + 0x4000)>>15;
}
return;
}
diff --git a/media/libstagefright/codecs/amrwbenc/src/math_op.c b/media/libstagefright/codecs/amrwbenc/src/math_op.c
index 7affbb2..1a7b513 100644
--- a/media/libstagefright/codecs/amrwbenc/src/math_op.c
+++ b/media/libstagefright/codecs/amrwbenc/src/math_op.c
@@ -106,21 +106,21 @@
if (*frac <= (Word32) 0)
{
- *exp = 0;
- *frac = 0x7fffffffL;
+ *exp = 0;
+ *frac = 0x7fffffffL;
return;
}
if((*exp & 1) == 1) /*If exponant odd -> shift right */
*frac = (*frac) >> 1;
- *exp = negate((*exp - 1) >> 1);
+ *exp = negate((*exp - 1) >> 1);
- *frac = (*frac >> 9);
+ *frac = (*frac >> 9);
i = extract_h(*frac); /* Extract b25-b31 */
- *frac = (*frac >> 1);
+ *frac = (*frac >> 1);
a = (Word16)(*frac); /* Extract b10-b24 */
- a = (Word16) (a & (Word16) 0x7fff);
+ a = (Word16) (a & (Word16) 0x7fff);
i -= 16;
*frac = L_deposit_h(table_isqrt[i]); /* table[i] << 16 */
tmp = vo_sub(table_isqrt[i], table_isqrt[i + 1]); /* table[i] - table[i+1]) */
@@ -167,7 +167,7 @@
i = extract_h(L_x); /* Extract b10-b16 of fraction */
L_x =L_x >> 1;
a = (Word16)(L_x); /* Extract b0-b9 of fraction */
- a = (Word16) (a & (Word16) 0x7fff);
+ a = (Word16) (a & (Word16) 0x7fff);
L_x = L_deposit_h(table_pow2[i]); /* table[i] << 16 */
tmp = vo_sub(table_pow2[i], table_pow2[i + 1]); /* table[i] - table[i+1] */
diff --git a/media/libstagefright/codecs/amrwbenc/src/mem_align.c b/media/libstagefright/codecs/amrwbenc/src/mem_align.c
index a29baf3..e58915a 100644
--- a/media/libstagefright/codecs/amrwbenc/src/mem_align.c
+++ b/media/libstagefright/codecs/amrwbenc/src/mem_align.c
@@ -27,7 +27,7 @@
/*****************************************************************************
*
* function name: mem_malloc
-* description: malloc the alignments memory
+* description: malloc the alignments memory
* returns: the point of the memory
*
**********************************************************************************/
diff --git a/media/libstagefright/codecs/amrwbenc/src/p_med_ol.c b/media/libstagefright/codecs/amrwbenc/src/p_med_ol.c
index b8174b9..08f430f 100644
--- a/media/libstagefright/codecs/amrwbenc/src/p_med_ol.c
+++ b/media/libstagefright/codecs/amrwbenc/src/p_med_ol.c
@@ -18,7 +18,7 @@
* File: p_med_ol.c *
* *
* Description: Compute the open loop pitch lag *
-* output: open loop pitch lag *
+* output: open loop pitch lag *
************************************************************************/
#include "typedef.h"
@@ -29,7 +29,7 @@
#include "p_med_ol.tab"
Word16 Pitch_med_ol(
- Word16 wsp[], /* i: signal used to compute the open loop pitch*/
+ Word16 wsp[], /* i: signal used to compute the open loop pitch*/
/* wsp[-pit_max] to wsp[-1] should be known */
Coder_State *st, /* i/o: codec global structure */
Word16 L_frame /* i: length of frame to compute pitch */
@@ -52,8 +52,8 @@
ww = &corrweight[198];
we = &corrweight[98 + L_max - L_0];
- max = MIN_32;
- Tm = 0;
+ max = MIN_32;
+ Tm = 0;
for (i = L_max; i > L_min; i--)
{
/* Compute the correlation */
@@ -65,7 +65,7 @@
R0 += vo_L_mult((*p1++), (*p2++));
R0 += vo_L_mult((*p1++), (*p2++));
R0 += vo_L_mult((*p1++), (*p2++));
- R0 += vo_L_mult((*p1++), (*p2++));
+ R0 += vo_L_mult((*p1++), (*p2++));
}
/* Weighting of the correlation function. */
hi = R0>>16;
@@ -90,13 +90,13 @@
}
/* Hypass the wsp[] vector */
- hp_wsp = old_hp_wsp + L_max;
+ hp_wsp = old_hp_wsp + L_max;
Hp_wsp(wsp, hp_wsp, L_frame, hp_wsp_mem);
/* Compute normalize correlation at delay Tm */
- R0 = 0;
- R1 = 0;
- R2 = 0;
+ R0 = 0;
+ R1 = 0;
+ R2 = 0;
p1 = hp_wsp;
p2 = hp_wsp - Tm;
for (j = 0; j < L_frame; j+=4)
@@ -174,57 +174,57 @@
Word16 x1, x2, x3, x4, x5;
Word16 tmp;
- x1 = x[-2];
- x2 = x[-1];
- x3 = x[0];
- x4 = x[1];
- x5 = x[2];
+ x1 = x[-2];
+ x2 = x[-1];
+ x3 = x[0];
+ x4 = x[1];
+ x5 = x[2];
if (x2 < x1)
{
tmp = x1;
x1 = x2;
- x2 = tmp;
+ x2 = tmp;
}
if (x3 < x1)
{
tmp = x1;
x1 = x3;
- x3 = tmp;
+ x3 = tmp;
}
if (x4 < x1)
{
tmp = x1;
x1 = x4;
- x4 = tmp;
+ x4 = tmp;
}
if (x5 < x1)
{
- x5 = x1;
+ x5 = x1;
}
if (x3 < x2)
{
tmp = x2;
x2 = x3;
- x3 = tmp;
+ x3 = tmp;
}
if (x4 < x2)
{
tmp = x2;
x2 = x4;
- x4 = tmp;
+ x4 = tmp;
}
if (x5 < x2)
{
- x5 = x2;
+ x5 = x2;
}
if (x4 < x3)
{
- x3 = x4;
+ x3 = x4;
}
if (x5 < x3)
{
- x3 = x5;
+ x3 = x5;
}
return (x3);
}
@@ -241,10 +241,10 @@
for (i = 4; i > 0; i--)
{
- old_ol_lag[i] = old_ol_lag[i - 1];
+ old_ol_lag[i] = old_ol_lag[i - 1];
}
- old_ol_lag[0] = prev_ol_lag;
+ old_ol_lag[0] = prev_ol_lag;
i = median5(&old_ol_lag[2]);
diff --git a/media/libstagefright/codecs/amrwbenc/src/pitch_f4.c b/media/libstagefright/codecs/amrwbenc/src/pitch_f4.c
index 0d66c31..41d7413 100644
--- a/media/libstagefright/codecs/amrwbenc/src/pitch_f4.c
+++ b/media/libstagefright/codecs/amrwbenc/src/pitch_f4.c
@@ -90,7 +90,7 @@
Norm_corr_asm(exc, xn, h, L_subfr, t_min, t_max, corr);
#else
Norm_Corr(exc, xn, h, L_subfr, t_min, t_max, corr);
-#endif
+#endif
/* Find integer pitch */
@@ -100,8 +100,8 @@
{
if (corr[i] >= max)
{
- max = corr[i];
- t0 = i;
+ max = corr[i];
+ t0 = i;
}
}
/* If first subframe and t0 >= t0_fr1, do not search fractionnal pitch */
@@ -182,7 +182,7 @@
#endif
/* Compute rounded down 1/sqrt(energy of xn[]) */
- L_tmp = 0;
+ L_tmp = 0;
for (i = 0; i < 64; i+=4)
{
L_tmp += (xn[i] * xn[i]);
@@ -202,7 +202,7 @@
for (t = t_min; t <= t_max; t++)
{
/* Compute correlation between xn[] and excf[] */
- L_tmp = 0;
+ L_tmp = 0;
L_tmp1 = 0;
for (i = 0; i < 64; i+=4)
{
@@ -246,7 +246,7 @@
L_tmp = L_tmp << L_tmp2;
}
- corr_norm[t] = vo_round(L_tmp);
+ corr_norm[t] = vo_round(L_tmp);
/* modify the filtered excitation excf[] for the next iteration */
if(t != t_max)
@@ -310,10 +310,10 @@
L_sum += vo_mult32(x[1], (*ptr++));
L_sum += vo_mult32(x[2], (*ptr++));
L_sum += vo_mult32(x[3], (*ptr++));
- L_sum += vo_mult32(x[4], (*ptr++));
+ L_sum += vo_mult32(x[4], (*ptr++));
L_sum += vo_mult32(x[5], (*ptr++));
L_sum += vo_mult32(x[6], (*ptr++));
- L_sum += vo_mult32(x[7], (*ptr++));
+ L_sum += vo_mult32(x[7], (*ptr++));
sum = extract_h(L_add(L_shl2(L_sum, 2), 0x8000));
return (sum);
diff --git a/media/libstagefright/codecs/amrwbenc/src/pred_lt4.c b/media/libstagefright/codecs/amrwbenc/src/pred_lt4.c
index 8404cf9..b359651 100644
--- a/media/libstagefright/codecs/amrwbenc/src/pred_lt4.c
+++ b/media/libstagefright/codecs/amrwbenc/src/pred_lt4.c
@@ -60,13 +60,13 @@
Word16 *ptr, *ptr1;
Word16 *ptr2;
- x = exc - T0;
+ x = exc - T0;
frac = -frac;
if (frac < 0)
{
frac += UP_SAMP;
x--;
- }
+ }
x -= 15; /* x = L_INTERPOL2 - 1 */
k = 3 - frac; /* k = UP_SAMP - 1 - frac */
diff --git a/media/libstagefright/codecs/amrwbenc/src/preemph.c b/media/libstagefright/codecs/amrwbenc/src/preemph.c
index c867bf7..5408617 100644
--- a/media/libstagefright/codecs/amrwbenc/src/preemph.c
+++ b/media/libstagefright/codecs/amrwbenc/src/preemph.c
@@ -35,20 +35,20 @@
Word16 temp;
Word32 i, L_tmp;
- temp = x[lg - 1];
+ temp = x[lg - 1];
for (i = lg - 1; i > 0; i--)
{
L_tmp = L_deposit_h(x[i]);
L_tmp -= (x[i - 1] * mu)<<1;
- x[i] = (L_tmp + 0x8000)>>16;
+ x[i] = (L_tmp + 0x8000)>>16;
}
L_tmp = L_deposit_h(x[0]);
L_tmp -= ((*mem) * mu)<<1;
- x[0] = (L_tmp + 0x8000)>>16;
+ x[0] = (L_tmp + 0x8000)>>16;
- *mem = temp;
+ *mem = temp;
return;
}
@@ -64,22 +64,22 @@
Word16 temp;
Word32 i, L_tmp;
- temp = x[lg - 1];
+ temp = x[lg - 1];
for (i = (Word16) (lg - 1); i > 0; i--)
{
L_tmp = L_deposit_h(x[i]);
L_tmp -= (x[i - 1] * mu)<<1;
L_tmp = (L_tmp << 1);
- x[i] = (L_tmp + 0x8000)>>16;
+ x[i] = (L_tmp + 0x8000)>>16;
}
L_tmp = L_deposit_h(x[0]);
L_tmp -= ((*mem) * mu)<<1;
L_tmp = (L_tmp << 1);
- x[0] = (L_tmp + 0x8000)>>16;
+ x[0] = (L_tmp + 0x8000)>>16;
- *mem = temp;
+ *mem = temp;
return;
}
diff --git a/media/libstagefright/codecs/amrwbenc/src/q_gain2.c b/media/libstagefright/codecs/amrwbenc/src/q_gain2.c
index e8ca043..7bc299f 100644
--- a/media/libstagefright/codecs/amrwbenc/src/q_gain2.c
+++ b/media/libstagefright/codecs/amrwbenc/src/q_gain2.c
@@ -83,7 +83,7 @@
Word32 i, j, L_tmp, dist_min;
Word16 *past_qua_en, *t_qua_gain;
- past_qua_en = mem;
+ past_qua_en = mem;
/*-----------------------------------------------------------------*
* - Find the initial quantization pitch index *
@@ -91,9 +91,9 @@
*-----------------------------------------------------------------*/
if (nbits == 6)
{
- t_qua_gain = t_qua_gain6b;
- min_ind = 0;
- size = RANGE;
+ t_qua_gain = t_qua_gain6b;
+ min_ind = 0;
+ size = RANGE;
if(gp_clip == 1)
{
@@ -101,18 +101,18 @@
}
} else
{
- t_qua_gain = t_qua_gain7b;
+ t_qua_gain = t_qua_gain7b;
p = t_qua_gain7b + RANGE; /* pt at 1/4th of table */
- j = nb_qua_gain7b - RANGE;
+ j = nb_qua_gain7b - RANGE;
if (gp_clip == 1)
{
j = j - 27; /* limit gain pitch to 1.0 */
}
- min_ind = 0;
- g_pitch = *gain_pit;
+ min_ind = 0;
+ g_pitch = *gain_pit;
for (i = 0; i < j; i++, p += 2)
{
@@ -121,7 +121,7 @@
min_ind = min_ind + 1;
}
}
- size = RANGE;
+ size = RANGE;
}
/*------------------------------------------------------------------*
@@ -137,10 +137,10 @@
* are in vector g_coeff[]. *
*------------------------------------------------------------------*/
- coeff[0] = g_coeff[0];
- exp_coeff[0] = g_coeff[1];
+ coeff[0] = g_coeff[0];
+ exp_coeff[0] = g_coeff[1];
coeff[1] = negate(g_coeff[2]); /* coeff[1] = -2 xn y1 */
- exp_coeff[1] = g_coeff[3] + 1;
+ exp_coeff[1] = g_coeff[3] + 1;
/* Compute scalar product <y2[],y2[]> */
#ifdef ASM_OPT /* asm optimization branch */
@@ -242,20 +242,20 @@
*-------------------------------------------------------------------------*/
exp_code = (exp_gcode0 + 4);
- exp_max[0] = (exp_coeff[0] - 13);
- exp_max[1] = (exp_coeff[1] - 14);
- exp_max[2] = (exp_coeff[2] + (15 + (exp_code << 1)));
- exp_max[3] = (exp_coeff[3] + exp_code);
- exp_max[4] = (exp_coeff[4] + (1 + exp_code));
+ exp_max[0] = (exp_coeff[0] - 13);
+ exp_max[1] = (exp_coeff[1] - 14);
+ exp_max[2] = (exp_coeff[2] + (15 + (exp_code << 1)));
+ exp_max[3] = (exp_coeff[3] + exp_code);
+ exp_max[4] = (exp_coeff[4] + (1 + exp_code));
/* Find maximum exponant */
- e_max = exp_max[0];
+ e_max = exp_max[0];
for (i = 1; i < 5; i++)
{
if(exp_max[i] > e_max)
{
- e_max = exp_max[i];
+ e_max = exp_max[i];
}
}
@@ -271,14 +271,14 @@
}
/* Codebook search */
- dist_min = MAX_32;
- p = &t_qua_gain[min_ind << 1];
+ dist_min = MAX_32;
+ p = &t_qua_gain[min_ind << 1];
- index = 0;
+ index = 0;
for (i = 0; i < size; i++)
{
- g_pitch = *p++;
- g_code = *p++;
+ g_pitch = *p++;
+ g_code = *p++;
g_code = ((g_code * gcode0) + 0x4000)>>15;
g2_pitch = ((g_pitch * g_pitch) + 0x4000)>>15;
@@ -302,14 +302,14 @@
if(L_tmp < dist_min)
{
- dist_min = L_tmp;
- index = i;
+ dist_min = L_tmp;
+ index = i;
}
}
/* Read the quantized gains */
index = index + min_ind;
- p = &t_qua_gain[(index + index)];
+ p = &t_qua_gain[(index + index)];
*gain_pit = *p++; /* selected pitch gain in Q14 */
g_code = *p++; /* selected code gain in Q11 */
@@ -333,10 +333,10 @@
/* update table of past quantized energies */
- past_qua_en[3] = past_qua_en[2];
- past_qua_en[2] = past_qua_en[1];
- past_qua_en[1] = past_qua_en[0];
- past_qua_en[0] = qua_ener;
+ past_qua_en[3] = past_qua_en[2];
+ past_qua_en[2] = past_qua_en[1];
+ past_qua_en[1] = past_qua_en[0];
+ past_qua_en[0] = qua_ener;
return (index);
}
diff --git a/media/libstagefright/codecs/amrwbenc/src/q_pulse.c b/media/libstagefright/codecs/amrwbenc/src/q_pulse.c
index 80a0b73..496ca80 100644
--- a/media/libstagefright/codecs/amrwbenc/src/q_pulse.c
+++ b/media/libstagefright/codecs/amrwbenc/src/q_pulse.c
@@ -82,7 +82,7 @@
if (vo_sub((Word16) (pos1 & mask), (Word16) (pos2 & mask)) <= 0)
{
/* index = ((pos2 & mask) << N) + (pos1 & mask); */
- index = L_deposit_l(add1((((Word16) (pos2 & mask)) << N), ((Word16) (pos1 & mask))));
+ index = L_deposit_l(add1((((Word16) (pos2 & mask)) << N), ((Word16) (pos1 & mask))));
if ((pos2 & NB_POS) != 0)
{
tmp = (N << 1); /* index += 1 << (2*N); */
@@ -91,7 +91,7 @@
} else
{
/* index = ((pos1 & mask) << N) + (pos2 & mask); */
- index = L_deposit_l(add1((((Word16) (pos1 & mask)) << N), ((Word16) (pos2 & mask))));
+ index = L_deposit_l(add1((((Word16) (pos1 & mask)) << N), ((Word16) (pos2 & mask))));
if ((pos1 & NB_POS) != 0)
{
tmp = (N << 1);
@@ -120,14 +120,14 @@
{
index = quant_2p_2N1(pos1, pos2, sub(N, 1)); /* index = quant_2p_2N1(pos1, pos2, (N-1)); */
/* index += (pos1 & nb_pos) << N; */
- index = vo_L_add(index, (L_deposit_l((Word16) (pos1 & nb_pos)) << N));
+ index = vo_L_add(index, (L_deposit_l((Word16) (pos1 & nb_pos)) << N));
/* index += quant_1p_N1(pos3, N) << (2*N); */
index = vo_L_add(index, (quant_1p_N1(pos3, N)<<(N << 1)));
} else if (((pos1 ^ pos3) & nb_pos) == 0)
{
index = quant_2p_2N1(pos1, pos3, sub(N, 1)); /* index = quant_2p_2N1(pos1, pos3, (N-1)); */
- index = vo_L_add(index, (L_deposit_l((Word16) (pos1 & nb_pos)) << N));
+ index = vo_L_add(index, (L_deposit_l((Word16) (pos1 & nb_pos)) << N));
/* index += (pos1 & nb_pos) << N; */
index = vo_L_add(index, (quant_1p_N1(pos2, N) << (N << 1)));
/* index += quant_1p_N1(pos2, N) <<
@@ -136,7 +136,7 @@
{
index = quant_2p_2N1(pos2, pos3, (N - 1)); /* index = quant_2p_2N1(pos2, pos3, (N-1)); */
/* index += (pos2 & nb_pos) << N; */
- index = vo_L_add(index, (L_deposit_l((Word16) (pos2 & nb_pos)) << N));
+ index = vo_L_add(index, (L_deposit_l((Word16) (pos2 & nb_pos)) << N));
/* index += quant_1p_N1(pos1, N) << (2*N); */
index = vo_L_add(index, (quant_1p_N1(pos1, N) << (N << 1)));
}
@@ -162,21 +162,21 @@
{
index = quant_2p_2N1(pos1, pos2, sub(N, 1)); /* index = quant_2p_2N1(pos1, pos2, (N-1)); */
/* index += (pos1 & nb_pos) << N; */
- index = vo_L_add(index, (L_deposit_l((Word16) (pos1 & nb_pos)) << N));
+ index = vo_L_add(index, (L_deposit_l((Word16) (pos1 & nb_pos)) << N));
/* index += quant_2p_2N1(pos3, pos4, N) << (2*N); */
index = vo_L_add(index, (quant_2p_2N1(pos3, pos4, N) << (N << 1)));
} else if (((pos1 ^ pos3) & nb_pos) == 0)
{
index = quant_2p_2N1(pos1, pos3, (N - 1));
/* index += (pos1 & nb_pos) << N; */
- index = vo_L_add(index, (L_deposit_l((Word16) (pos1 & nb_pos)) << N));
+ index = vo_L_add(index, (L_deposit_l((Word16) (pos1 & nb_pos)) << N));
/* index += quant_2p_2N1(pos2, pos4, N) << (2*N); */
index = vo_L_add(index, (quant_2p_2N1(pos2, pos4, N) << (N << 1)));
} else
{
index = quant_2p_2N1(pos2, pos3, (N - 1));
/* index += (pos2 & nb_pos) << N; */
- index = vo_L_add(index, (L_deposit_l((Word16) (pos2 & nb_pos)) << N));
+ index = vo_L_add(index, (L_deposit_l((Word16) (pos2 & nb_pos)) << N));
/* index += quant_2p_2N1(pos1, pos4, N) << (2*N); */
index = vo_L_add(index, (quant_2p_2N1(pos1, pos4, N) << (N << 1)));
}
@@ -192,20 +192,20 @@
Word16 posA[4], posB[4];
Word32 i, j, k, index;
- n_1 = (Word16) (N - 1);
+ n_1 = (Word16) (N - 1);
nb_pos = (1 << n_1); /* nb_pos = (1<<n_1); */
mask = vo_sub((1 << N), 1); /* mask = ((1<<N)-1); */
- i = 0;
- j = 0;
+ i = 0;
+ j = 0;
for (k = 0; k < 4; k++)
{
if ((pos[k] & nb_pos) == 0)
{
- posA[i++] = pos[k];
+ posA[i++] = pos[k];
} else
{
- posB[j++] = pos[k];
+ posB[j++] = pos[k];
}
}
@@ -258,19 +258,19 @@
Word16 posA[5], posB[5];
Word32 i, j, k, index, tmp2;
- n_1 = (Word16) (N - 1);
+ n_1 = (Word16) (N - 1);
nb_pos = (1 << n_1); /* nb_pos = (1<<n_1); */
- i = 0;
- j = 0;
+ i = 0;
+ j = 0;
for (k = 0; k < 5; k++)
{
if ((pos[k] & nb_pos) == 0)
{
- posA[i++] = pos[k];
+ posA[i++] = pos[k];
} else
{
- posB[j++] = pos[k];
+ posB[j++] = pos[k];
}
}
@@ -333,19 +333,19 @@
Word32 i, j, k, index;
/* !! N and n_1 are constants -> it doesn't need to be operated by Basic Operators */
- n_1 = (Word16) (N - 1);
+ n_1 = (Word16) (N - 1);
nb_pos = (1 << n_1); /* nb_pos = (1<<n_1); */
- i = 0;
- j = 0;
+ i = 0;
+ j = 0;
for (k = 0; k < 6; k++)
{
if ((pos[k] & nb_pos) == 0)
{
- posA[i++] = pos[k];
+ posA[i++] = pos[k];
} else
{
- posB[j++] = pos[k];
+ posB[j++] = pos[k];
}
}
@@ -368,23 +368,23 @@
index = vo_L_add(index, quant_2p_2N1(posA[0], posA[1], n_1)); /* index += quant_2p_2N1(posA[0], posA[1], n_1); */
break;
case 3:
- index = (quant_3p_3N1(posA[0], posA[1], posA[2], n_1) << (Word16) (3 * n_1 + 1));
+ index = (quant_3p_3N1(posA[0], posA[1], posA[2], n_1) << (Word16) (3 * n_1 + 1));
/* index = quant_3p_3N1(posA[0], posA[1], posA[2], n_1) << ((3*n_1)+1); */
- index =vo_L_add(index, quant_3p_3N1(posB[0], posB[1], posB[2], n_1));
+ index =vo_L_add(index, quant_3p_3N1(posB[0], posB[1], posB[2], n_1));
/* index += quant_3p_3N1(posB[0], posB[1], posB[2], n_1); */
break;
case 4:
- i = 2;
+ i = 2;
index = (quant_4p_4N(posA, n_1) << (Word16) (2 * n_1 + 1)); /* index = quant_4p_4N(posA, n_1) << ((2*n_1)+1); */
index = vo_L_add(index, quant_2p_2N1(posB[0], posB[1], n_1)); /* index += quant_2p_2N1(posB[0], posB[1], n_1); */
break;
case 5:
- i = 1;
+ i = 1;
index = (quant_5p_5N(posA, n_1) << N); /* index = quant_5p_5N(posA, n_1) << N; */
index = vo_L_add(index, quant_1p_N1(posB[0], n_1)); /* index += quant_1p_N1(posB[0], n_1); */
break;
case 6:
- i = 0;
+ i = 0;
index = (quant_5p_5N(posA, n_1) << N); /* index = quant_5p_5N(posA, n_1) << N; */
index = vo_L_add(index, quant_1p_N1(posA[5], n_1)); /* index += quant_1p_N1(posA[5], n_1); */
break;
diff --git a/media/libstagefright/codecs/amrwbenc/src/qisf_ns.c b/media/libstagefright/codecs/amrwbenc/src/qisf_ns.c
index fc2f00d..f6d53de 100644
--- a/media/libstagefright/codecs/amrwbenc/src/qisf_ns.c
+++ b/media/libstagefright/codecs/amrwbenc/src/qisf_ns.c
@@ -43,14 +43,14 @@
for (i = 0; i < ORDER; i++)
{
- isf_q[i] = sub(isf1[i], mean_isf_noise[i]);
+ isf_q[i] = sub(isf1[i], mean_isf_noise[i]);
}
- indice[0] = Sub_VQ(&isf_q[0], dico1_isf_noise, 2, SIZE_BK_NOISE1, &tmp);
- indice[1] = Sub_VQ(&isf_q[2], dico2_isf_noise, 3, SIZE_BK_NOISE2, &tmp);
- indice[2] = Sub_VQ(&isf_q[5], dico3_isf_noise, 3, SIZE_BK_NOISE3, &tmp);
- indice[3] = Sub_VQ(&isf_q[8], dico4_isf_noise, 4, SIZE_BK_NOISE4, &tmp);
- indice[4] = Sub_VQ(&isf_q[12], dico5_isf_noise, 4, SIZE_BK_NOISE5, &tmp);
+ indice[0] = Sub_VQ(&isf_q[0], dico1_isf_noise, 2, SIZE_BK_NOISE1, &tmp);
+ indice[1] = Sub_VQ(&isf_q[2], dico2_isf_noise, 3, SIZE_BK_NOISE2, &tmp);
+ indice[2] = Sub_VQ(&isf_q[5], dico3_isf_noise, 3, SIZE_BK_NOISE3, &tmp);
+ indice[3] = Sub_VQ(&isf_q[8], dico4_isf_noise, 4, SIZE_BK_NOISE4, &tmp);
+ indice[4] = Sub_VQ(&isf_q[12], dico5_isf_noise, 4, SIZE_BK_NOISE5, &tmp);
/* decoding the ISFs */
@@ -78,28 +78,28 @@
for (i = 0; i < 2; i++)
{
- isf_q[i] = dico1_isf_noise[indice[0] * 2 + i];
+ isf_q[i] = dico1_isf_noise[indice[0] * 2 + i];
}
for (i = 0; i < 3; i++)
{
- isf_q[i + 2] = dico2_isf_noise[indice[1] * 3 + i];
+ isf_q[i + 2] = dico2_isf_noise[indice[1] * 3 + i];
}
for (i = 0; i < 3; i++)
{
- isf_q[i + 5] = dico3_isf_noise[indice[2] * 3 + i];
+ isf_q[i + 5] = dico3_isf_noise[indice[2] * 3 + i];
}
for (i = 0; i < 4; i++)
{
- isf_q[i + 8] = dico4_isf_noise[indice[3] * 4 + i];
+ isf_q[i + 8] = dico4_isf_noise[indice[3] * 4 + i];
}
for (i = 0; i < 4; i++)
{
- isf_q[i + 12] = dico5_isf_noise[indice[4] * 4 + i];
+ isf_q[i + 12] = dico5_isf_noise[indice[4] * 4 + i];
}
for (i = 0; i < ORDER; i++)
{
- isf_q[i] = add(isf_q[i], mean_isf_noise[i]);
+ isf_q[i] = add(isf_q[i], mean_isf_noise[i]);
}
Reorder_isf(isf_q, ISF_GAP, ORDER);
diff --git a/media/libstagefright/codecs/amrwbenc/src/qpisf_2s.c b/media/libstagefright/codecs/amrwbenc/src/qpisf_2s.c
index c711cd0..ac13a67 100644
--- a/media/libstagefright/codecs/amrwbenc/src/qpisf_2s.c
+++ b/media/libstagefright/codecs/amrwbenc/src/qpisf_2s.c
@@ -70,30 +70,30 @@
for (i = 0; i < ORDER; i++)
{
isf[i] = vo_sub(isf1[i], mean_isf[i]);
- isf[i] = vo_sub(isf[i], vo_mult(MU, past_isfq[i]));
+ isf[i] = vo_sub(isf[i], vo_mult(MU, past_isfq[i]));
}
VQ_stage1(&isf[0], dico1_isf, 9, SIZE_BK1, surv1, nb_surv);
- distance = MAX_32;
+ distance = MAX_32;
for (k = 0; k < nb_surv; k++)
{
for (i = 0; i < 9; i++)
{
- isf_stage2[i] = vo_sub(isf[i], dico1_isf[i + surv1[k] * 9]);
+ isf_stage2[i] = vo_sub(isf[i], dico1_isf[i + surv1[k] * 9]);
}
- tmp_ind[0] = Sub_VQ(&isf_stage2[0], dico21_isf, 3, SIZE_BK21, &min_err);
+ tmp_ind[0] = Sub_VQ(&isf_stage2[0], dico21_isf, 3, SIZE_BK21, &min_err);
temp = min_err;
- tmp_ind[1] = Sub_VQ(&isf_stage2[3], dico22_isf, 3, SIZE_BK22, &min_err);
+ tmp_ind[1] = Sub_VQ(&isf_stage2[3], dico22_isf, 3, SIZE_BK22, &min_err);
temp = vo_L_add(temp, min_err);
- tmp_ind[2] = Sub_VQ(&isf_stage2[6], dico23_isf, 3, SIZE_BK23, &min_err);
+ tmp_ind[2] = Sub_VQ(&isf_stage2[6], dico23_isf, 3, SIZE_BK23, &min_err);
temp = vo_L_add(temp, min_err);
if(temp < distance)
{
- distance = temp;
- indice[0] = surv1[k];
+ distance = temp;
+ indice[0] = surv1[k];
for (i = 0; i < 3; i++)
{
indice[i + 2] = tmp_ind[i];
@@ -104,24 +104,24 @@
VQ_stage1(&isf[9], dico2_isf, 7, SIZE_BK2, surv1, nb_surv);
- distance = MAX_32;
+ distance = MAX_32;
for (k = 0; k < nb_surv; k++)
{
for (i = 0; i < 7; i++)
{
- isf_stage2[i] = vo_sub(isf[9 + i], dico2_isf[i + surv1[k] * 7]);
+ isf_stage2[i] = vo_sub(isf[9 + i], dico2_isf[i + surv1[k] * 7]);
}
tmp_ind[0] = Sub_VQ(&isf_stage2[0], dico24_isf, 3, SIZE_BK24, &min_err);
- temp = min_err;
+ temp = min_err;
tmp_ind[1] = Sub_VQ(&isf_stage2[3], dico25_isf, 4, SIZE_BK25, &min_err);
temp = vo_L_add(temp, min_err);
if(temp < distance)
{
- distance = temp;
- indice[1] = surv1[k];
+ distance = temp;
+ indice[1] = surv1[k];
for (i = 0; i < 2; i++)
{
indice[i + 5] = tmp_ind[i];
@@ -165,24 +165,24 @@
VQ_stage1(&isf[0], dico1_isf, 9, SIZE_BK1, surv1, nb_surv);
- distance = MAX_32;
+ distance = MAX_32;
for (k = 0; k < nb_surv; k++)
{
for (i = 0; i < 9; i++)
{
- isf_stage2[i] = vo_sub(isf[i], dico1_isf[i + surv1[k] * 9]);
+ isf_stage2[i] = vo_sub(isf[i], dico1_isf[i + surv1[k] * 9]);
}
- tmp_ind[0] = Sub_VQ(&isf_stage2[0], dico21_isf_36b, 5, SIZE_BK21_36b, &min_err);
- temp = min_err;
- tmp_ind[1] = Sub_VQ(&isf_stage2[5], dico22_isf_36b, 4, SIZE_BK22_36b, &min_err);
+ tmp_ind[0] = Sub_VQ(&isf_stage2[0], dico21_isf_36b, 5, SIZE_BK21_36b, &min_err);
+ temp = min_err;
+ tmp_ind[1] = Sub_VQ(&isf_stage2[5], dico22_isf_36b, 4, SIZE_BK22_36b, &min_err);
temp = vo_L_add(temp, min_err);
if(temp < distance)
{
- distance = temp;
- indice[0] = surv1[k];
+ distance = temp;
+ indice[0] = surv1[k];
for (i = 0; i < 2; i++)
{
indice[i + 2] = tmp_ind[i];
@@ -191,23 +191,23 @@
}
VQ_stage1(&isf[9], dico2_isf, 7, SIZE_BK2, surv1, nb_surv);
- distance = MAX_32;
+ distance = MAX_32;
for (k = 0; k < nb_surv; k++)
{
for (i = 0; i < 7; i++)
{
- isf_stage2[i] = vo_sub(isf[9 + i], dico2_isf[i + surv1[k] * 7]);
+ isf_stage2[i] = vo_sub(isf[9 + i], dico2_isf[i + surv1[k] * 7]);
}
- tmp_ind[0] = Sub_VQ(&isf_stage2[0], dico23_isf_36b, 7, SIZE_BK23_36b, &min_err);
- temp = min_err;
+ tmp_ind[0] = Sub_VQ(&isf_stage2[0], dico23_isf_36b, 7, SIZE_BK23_36b, &min_err);
+ temp = min_err;
if(temp < distance)
{
- distance = temp;
- indice[1] = surv1[k];
- indice[4] = tmp_ind[0];
+ distance = temp;
+ indice[1] = surv1[k];
+ indice[4] = tmp_ind[0];
}
}
@@ -239,32 +239,32 @@
{
for (i = 0; i < 9; i++)
{
- isf_q[i] = dico1_isf[indice[0] * 9 + i];
+ isf_q[i] = dico1_isf[indice[0] * 9 + i];
}
for (i = 0; i < 7; i++)
{
- isf_q[i + 9] = dico2_isf[indice[1] * 7 + i];
+ isf_q[i + 9] = dico2_isf[indice[1] * 7 + i];
}
for (i = 0; i < 3; i++)
{
- isf_q[i] = add1(isf_q[i], dico21_isf[indice[2] * 3 + i]);
- isf_q[i + 3] = add1(isf_q[i + 3], dico22_isf[indice[3] * 3 + i]);
- isf_q[i + 6] = add1(isf_q[i + 6], dico23_isf[indice[4] * 3 + i]);
- isf_q[i + 9] = add1(isf_q[i + 9], dico24_isf[indice[5] * 3 + i]);
+ isf_q[i] = add1(isf_q[i], dico21_isf[indice[2] * 3 + i]);
+ isf_q[i + 3] = add1(isf_q[i + 3], dico22_isf[indice[3] * 3 + i]);
+ isf_q[i + 6] = add1(isf_q[i + 6], dico23_isf[indice[4] * 3 + i]);
+ isf_q[i + 9] = add1(isf_q[i + 9], dico24_isf[indice[5] * 3 + i]);
}
for (i = 0; i < 4; i++)
{
- isf_q[i + 12] = add1(isf_q[i + 12], dico25_isf[indice[6] * 4 + i]);
+ isf_q[i + 12] = add1(isf_q[i + 12], dico25_isf[indice[6] * 4 + i]);
}
for (i = 0; i < ORDER; i++)
{
- tmp = isf_q[i];
- isf_q[i] = add1(tmp, mean_isf[i]);
+ tmp = isf_q[i];
+ isf_q[i] = add1(tmp, mean_isf[i]);
isf_q[i] = add1(isf_q[i], vo_mult(MU, past_isfq[i]));
- past_isfq[i] = tmp;
+ past_isfq[i] = tmp;
}
if (enc_dec)
@@ -273,9 +273,9 @@
{
for (j = (L_MEANBUF - 1); j > 0; j--)
{
- isf_buf[j * M + i] = isf_buf[(j - 1) * M + i];
+ isf_buf[j * M + i] = isf_buf[(j - 1) * M + i];
}
- isf_buf[i] = isf_q[i];
+ isf_buf[i] = isf_q[i];
}
}
} else
@@ -293,14 +293,14 @@
/* use the past ISFs slightly shifted towards their mean */
for (i = 0; i < ORDER; i++)
{
- isf_q[i] = add1(vo_mult(ALPHA, isfold[i]), vo_mult(ONE_ALPHA, ref_isf[i]));
+ isf_q[i] = add1(vo_mult(ALPHA, isfold[i]), vo_mult(ONE_ALPHA, ref_isf[i]));
}
/* estimate past quantized residual to be used in next frame */
for (i = 0; i < ORDER; i++)
{
tmp = add1(ref_isf[i], vo_mult(past_isfq[i], MU)); /* predicted ISF */
- past_isfq[i] = vo_sub(isf_q[i], tmp);
+ past_isfq[i] = vo_sub(isf_q[i], tmp);
past_isfq[i] = (past_isfq[i] >> 1); /* past_isfq[i] *= 0.5 */
}
}
@@ -332,32 +332,32 @@
{
for (i = 0; i < 9; i++)
{
- isf_q[i] = dico1_isf[indice[0] * 9 + i];
+ isf_q[i] = dico1_isf[indice[0] * 9 + i];
}
for (i = 0; i < 7; i++)
{
- isf_q[i + 9] = dico2_isf[indice[1] * 7 + i];
+ isf_q[i + 9] = dico2_isf[indice[1] * 7 + i];
}
for (i = 0; i < 5; i++)
{
- isf_q[i] = add1(isf_q[i], dico21_isf_36b[indice[2] * 5 + i]);
+ isf_q[i] = add1(isf_q[i], dico21_isf_36b[indice[2] * 5 + i]);
}
for (i = 0; i < 4; i++)
{
- isf_q[i + 5] = add1(isf_q[i + 5], dico22_isf_36b[indice[3] * 4 + i]);
+ isf_q[i + 5] = add1(isf_q[i + 5], dico22_isf_36b[indice[3] * 4 + i]);
}
for (i = 0; i < 7; i++)
{
- isf_q[i + 9] = add1(isf_q[i + 9], dico23_isf_36b[indice[4] * 7 + i]);
+ isf_q[i + 9] = add1(isf_q[i + 9], dico23_isf_36b[indice[4] * 7 + i]);
}
for (i = 0; i < ORDER; i++)
{
tmp = isf_q[i];
- isf_q[i] = add1(tmp, mean_isf[i]);
- isf_q[i] = add1(isf_q[i], vo_mult(MU, past_isfq[i]));
- past_isfq[i] = tmp;
+ isf_q[i] = add1(tmp, mean_isf[i]);
+ isf_q[i] = add1(isf_q[i], vo_mult(MU, past_isfq[i]));
+ past_isfq[i] = tmp;
}
@@ -367,9 +367,9 @@
{
for (j = (L_MEANBUF - 1); j > 0; j--)
{
- isf_buf[j * M + i] = isf_buf[(j - 1) * M + i];
+ isf_buf[j * M + i] = isf_buf[(j - 1) * M + i];
}
- isf_buf[i] = isf_q[i];
+ isf_buf[i] = isf_q[i];
}
}
} else
@@ -381,20 +381,20 @@
{
L_tmp += (isf_buf[j * M + i] << 14);
}
- ref_isf[i] = vo_round(L_tmp);
+ ref_isf[i] = vo_round(L_tmp);
}
/* use the past ISFs slightly shifted towards their mean */
for (i = 0; i < ORDER; i++)
{
- isf_q[i] = add1(vo_mult(ALPHA, isfold[i]), vo_mult(ONE_ALPHA, ref_isf[i]));
+ isf_q[i] = add1(vo_mult(ALPHA, isfold[i]), vo_mult(ONE_ALPHA, ref_isf[i]));
}
/* estimate past quantized residual to be used in next frame */
for (i = 0; i < ORDER; i++)
{
tmp = add1(ref_isf[i], vo_mult(past_isfq[i], MU)); /* predicted ISF */
- past_isfq[i] = vo_sub(isf_q[i], tmp);
+ past_isfq[i] = vo_sub(isf_q[i], tmp);
past_isfq[i] = past_isfq[i] >> 1; /* past_isfq[i] *= 0.5 */
}
}
@@ -424,15 +424,15 @@
Word16 n /* (i) : number of ISF */
)
{
- Word32 i;
+ Word32 i;
Word16 isf_min;
- isf_min = min_dist;
+ isf_min = min_dist;
for (i = 0; i < n - 1; i++)
{
if(isf[i] < isf_min)
{
- isf[i] = isf_min;
+ isf[i] = isf_min;
}
isf_min = (isf[i] + min_dist);
}
@@ -452,13 +452,13 @@
Word32 i, j, index;
Word32 dist_min, dist;
- dist_min = MAX_32;
- p_dico = dico;
+ dist_min = MAX_32;
+ p_dico = dico;
- index = 0;
+ index = 0;
for (i = 0; i < dico_size; i++)
{
- dist = 0;
+ dist = 0;
for (j = 0; j < dim; j++)
{
@@ -468,18 +468,18 @@
if(dist < dist_min)
{
- dist_min = dist;
- index = i;
+ dist_min = dist;
+ index = i;
}
}
- *distance = dist_min;
+ *distance = dist_min;
/* Reading the selected vector */
- p_dico = &dico[index * dim];
+ p_dico = &dico[index * dim];
for (j = 0; j < dim; j++)
{
- x[j] = *p_dico++;
+ x[j] = *p_dico++;
}
return index;
@@ -508,11 +508,11 @@
index[2] = 2;
index[3] = 3;
- p_dico = dico;
+ p_dico = dico;
for (i = 0; i < dico_size; i++)
{
- dist = 0;
+ dist = 0;
for (j = 0; j < dim; j++)
{
temp = x[j] - (*p_dico++);
@@ -525,11 +525,11 @@
{
for (l = surv - 1; l > k; l--)
{
- dist_min[l] = dist_min[l - 1];
- index[l] = index[l - 1];
+ dist_min[l] = dist_min[l - 1];
+ index[l] = index[l - 1];
}
- dist_min[k] = dist;
- index[k] = i;
+ dist_min[k] = dist;
+ index[k] = i;
break;
}
}
diff --git a/media/libstagefright/codecs/amrwbenc/src/residu.c b/media/libstagefright/codecs/amrwbenc/src/residu.c
index b0c04b5..328aed2 100644
--- a/media/libstagefright/codecs/amrwbenc/src/residu.c
+++ b/media/libstagefright/codecs/amrwbenc/src/residu.c
@@ -56,7 +56,7 @@
s += vo_mult32((*p1++), (*p2--));
s += vo_mult32((*p1), (*p2));
- s = L_shl2(s, 5);
+ s = L_shl2(s, 5);
y[i] = extract_h(L_add(s, 0x8000));
}
diff --git a/media/libstagefright/codecs/amrwbenc/src/scale.c b/media/libstagefright/codecs/amrwbenc/src/scale.c
index 418cc06..b203bec 100644
--- a/media/libstagefright/codecs/amrwbenc/src/scale.c
+++ b/media/libstagefright/codecs/amrwbenc/src/scale.c
@@ -36,8 +36,8 @@
{
for (i = lg - 1 ; i >= 0; i--)
{
- L_tmp = L_shl2(x[i], 16 + exp);
- x[i] = extract_h(L_add(L_tmp, 0x8000));
+ L_tmp = L_shl2(x[i], 16 + exp);
+ x[i] = extract_h(L_add(L_tmp, 0x8000));
}
}
else
@@ -46,8 +46,8 @@
for (i = lg - 1; i >= 0; i--)
{
L_tmp = x[i] << 16;
- L_tmp >>= exp;
- x[i] = (L_tmp + 0x8000)>>16;
+ L_tmp >>= exp;
+ x[i] = (L_tmp + 0x8000)>>16;
}
}
return;
diff --git a/media/libstagefright/codecs/amrwbenc/src/stream.c b/media/libstagefright/codecs/amrwbenc/src/stream.c
index 780f009..bdf0d46 100644
--- a/media/libstagefright/codecs/amrwbenc/src/stream.c
+++ b/media/libstagefright/codecs/amrwbenc/src/stream.c
@@ -29,11 +29,11 @@
stream->frame_ptr_bk = stream->frame_ptr;
stream->set_len = 0;
stream->framebuffer_len = 0;
- stream->frame_storelen = 0;
+ stream->frame_storelen = 0;
}
void voAWB_UpdateFrameBuffer(
- FrameStream *stream,
+ FrameStream *stream,
VO_MEM_OPERATOR *pMemOP
)
{
@@ -53,6 +53,6 @@
stream->frame_ptr_bk = stream->frame_ptr;
stream->set_len = 0;
stream->framebuffer_len = 0;
- stream->frame_storelen = 0;
+ stream->frame_storelen = 0;
}
diff --git a/media/libstagefright/codecs/amrwbenc/src/syn_filt.c b/media/libstagefright/codecs/amrwbenc/src/syn_filt.c
index 1bda05a..90fafb0 100644
--- a/media/libstagefright/codecs/amrwbenc/src/syn_filt.c
+++ b/media/libstagefright/codecs/amrwbenc/src/syn_filt.c
@@ -39,11 +39,11 @@
Word16 y_buf[L_SUBFR16k + M16k];
Word32 L_tmp;
Word16 *yy, *p1, *p2;
- yy = &y_buf[0];
+ yy = &y_buf[0];
/* copy initial filter states into synthesis buffer */
for (i = 0; i < 16; i++)
{
- *yy++ = mem[i];
+ *yy++ = mem[i];
}
a0 = (a[0] >> 1); /* input / 2 */
/* Do the filtering. */
@@ -70,7 +70,7 @@
L_tmp -= vo_mult32((*p1), (*p2));
L_tmp = L_shl2(L_tmp, 4);
- y[i] = yy[i] = extract_h(L_add(L_tmp, 0x8000));
+ y[i] = yy[i] = extract_h(L_add(L_tmp, 0x8000));
}
/* Update memory if required */
if (update)
@@ -99,7 +99,7 @@
/* Do the filtering. */
for (i = 0; i < lg; i++)
{
- L_tmp = 0;
+ L_tmp = 0;
L_tmp1 = 0;
p1 = a;
p2 = &sig_lo[i - 1];
@@ -138,18 +138,18 @@
L_tmp -= vo_mult32((*p2--), (*p1));
L_tmp1 -= vo_mult32((*p3--), (*p1++));
- L_tmp = L_tmp >> 11;
+ L_tmp = L_tmp >> 11;
L_tmp += vo_L_mult(exc[i], a0);
/* sig_hi = bit16 to bit31 of synthesis */
L_tmp = L_tmp - (L_tmp1<<1);
L_tmp = L_tmp >> 3; /* ai in Q12 */
- sig_hi[i] = extract_h(L_tmp);
+ sig_hi[i] = extract_h(L_tmp);
/* sig_lo = bit4 to bit15 of synthesis */
L_tmp >>= 4; /* 4 : sig_lo[i] >> 4 */
- sig_lo[i] = (Word16)((L_tmp - (sig_hi[i] << 13)));
+ sig_lo[i] = (Word16)((L_tmp - (sig_hi[i] << 13)));
}
return;
diff --git a/media/libstagefright/codecs/amrwbenc/src/updt_tar.c b/media/libstagefright/codecs/amrwbenc/src/updt_tar.c
index 96779fd..eda2b1c 100644
--- a/media/libstagefright/codecs/amrwbenc/src/updt_tar.c
+++ b/media/libstagefright/codecs/amrwbenc/src/updt_tar.c
@@ -39,7 +39,7 @@
{
L_tmp = x[i] << 15;
L_tmp -= (y[i] * gain)<<1;
- x2[i] = extract_h(L_shl2(L_tmp, 1));
+ x2[i] = extract_h(L_shl2(L_tmp, 1));
}
return;
diff --git a/media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c b/media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c
index 0f4d689..bac00dd 100644
--- a/media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c
+++ b/media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c
@@ -84,11 +84,11 @@
Set_zero(cod_state->old_exc, PIT_MAX + L_INTERPOL);
Set_zero(cod_state->mem_syn, M);
Set_zero(cod_state->past_isfq, M);
- cod_state->mem_w0 = 0;
- cod_state->tilt_code = 0;
- cod_state->first_frame = 1;
+ cod_state->mem_w0 = 0;
+ cod_state->tilt_code = 0;
+ cod_state->first_frame = 1;
Init_gp_clip(cod_state->gp_clip);
- cod_state->L_gc_thres = 0;
+ cod_state->L_gc_thres = 0;
if (reset_all != 0)
{
/* Static vectors to zero */
@@ -105,21 +105,21 @@
Copy(isp_init, cod_state->ispold, M);
Copy(isp_init, cod_state->ispold_q, M);
/* variable initialization */
- cod_state->mem_preemph = 0;
- cod_state->mem_wsp = 0;
- cod_state->Q_old = 15;
- cod_state->Q_max[0] = 15;
- cod_state->Q_max[1] = 15;
- cod_state->old_wsp_max = 0;
- cod_state->old_wsp_shift = 0;
+ cod_state->mem_preemph = 0;
+ cod_state->mem_wsp = 0;
+ cod_state->Q_old = 15;
+ cod_state->Q_max[0] = 15;
+ cod_state->Q_max[1] = 15;
+ cod_state->old_wsp_max = 0;
+ cod_state->old_wsp_shift = 0;
/* pitch ol initialization */
- cod_state->old_T0_med = 40;
- cod_state->ol_gain = 0;
- cod_state->ada_w = 0;
- cod_state->ol_wght_flg = 0;
+ cod_state->old_T0_med = 40;
+ cod_state->ol_gain = 0;
+ cod_state->ada_w = 0;
+ cod_state->ol_wght_flg = 0;
for (i = 0; i < 5; i++)
{
- cod_state->old_ol_lag[i] = 40;
+ cod_state->old_ol_lag[i] = 40;
}
Set_zero(cod_state->old_hp_wsp, (L_FRAME / 2) / OPL_DECIM + (PIT_MAX / OPL_DECIM));
Set_zero(cod_state->mem_syn_hf, M);
@@ -129,10 +129,10 @@
Init_Filt_6k_7k(cod_state->mem_hf);
Init_HP400_12k8(cod_state->mem_hp400);
Copy(isf_init, cod_state->isfold, M);
- cod_state->mem_deemph = 0;
- cod_state->seed2 = 21845;
+ cod_state->mem_deemph = 0;
+ cod_state->seed2 = 21845;
Init_Filt_6k_7k(cod_state->mem_hf2);
- cod_state->gain_alpha = 32767;
+ cod_state->gain_alpha = 32767;
cod_state->vad_hist = 0;
wb_vad_reset(cod_state->vadSt);
dtx_enc_reset(cod_state->dtx_encSt, isf_init);
@@ -212,8 +212,8 @@
st = (Coder_State *) spe_state;
- *ser_size = nb_of_bits[*mode];
- codec_mode = *mode;
+ *ser_size = nb_of_bits[*mode];
+ codec_mode = *mode;
/*--------------------------------------------------------------------------*
* Initialize pointers to speech vector. *
@@ -233,10 +233,10 @@
new_speech = old_speech + L_TOTAL - L_FRAME - L_FILT; /* New speech */
speech = old_speech + L_TOTAL - L_FRAME - L_NEXT; /* Present frame */
- p_window = old_speech + L_TOTAL - L_WINDOW;
+ p_window = old_speech + L_TOTAL - L_WINDOW;
- exc = old_exc + PIT_MAX + L_INTERPOL;
- wsp = old_wsp + (PIT_MAX / OPL_DECIM);
+ exc = old_exc + PIT_MAX + L_INTERPOL;
+ wsp = old_wsp + (PIT_MAX / OPL_DECIM);
/* copy coder memory state into working space */
Copy(st->old_speech, old_speech, L_TOTAL - L_FRAME);
@@ -287,7 +287,7 @@
L_tmp = L_abs(L_tmp);
if(L_tmp > L_max)
{
- L_max = L_tmp;
+ L_max = L_tmp;
}
}
@@ -297,50 +297,50 @@
tmp = extract_h(L_max);
if (tmp == 0)
{
- shift = Q_MAX;
+ shift = Q_MAX;
} else
{
shift = norm_s(tmp) - 1;
if (shift < 0)
{
- shift = 0;
+ shift = 0;
}
if (shift > Q_MAX)
{
- shift = Q_MAX;
+ shift = Q_MAX;
}
}
- Q_new = shift;
+ Q_new = shift;
if (Q_new > st->Q_max[0])
{
- Q_new = st->Q_max[0];
+ Q_new = st->Q_max[0];
}
if (Q_new > st->Q_max[1])
{
- Q_new = st->Q_max[1];
+ Q_new = st->Q_max[1];
}
exp = (Q_new - st->Q_old);
- st->Q_old = Q_new;
- st->Q_max[1] = st->Q_max[0];
- st->Q_max[0] = shift;
+ st->Q_old = Q_new;
+ st->Q_max[1] = st->Q_max[0];
+ st->Q_max[0] = shift;
/* preemphasis with scaling (L_FRAME+L_FILT) */
- tmp = new_speech[L_FRAME - 1];
+ tmp = new_speech[L_FRAME - 1];
for (i = L_FRAME + L_FILT - 1; i > 0; i--)
{
L_tmp = new_speech[i] << 15;
L_tmp -= (new_speech[i - 1] * mu)<<1;
L_tmp = (L_tmp << Q_new);
- new_speech[i] = vo_round(L_tmp);
+ new_speech[i] = vo_round(L_tmp);
}
L_tmp = new_speech[0] << 15;
L_tmp -= (st->mem_preemph * mu)<<1;
L_tmp = (L_tmp << Q_new);
- new_speech[0] = vo_round(L_tmp);
+ new_speech[0] = vo_round(L_tmp);
- st->mem_preemph = tmp;
+ st->mem_preemph = tmp;
/* scale previous samples and memory */
@@ -364,13 +364,13 @@
Scale_sig(buf, L_FRAME, 1 - Q_new);
#endif
- vad_flag = wb_vad(st->vadSt, buf); /* Voice Activity Detection */
+ vad_flag = wb_vad(st->vadSt, buf); /* Voice Activity Detection */
if (vad_flag == 0)
{
- st->vad_hist = (st->vad_hist + 1);
+ st->vad_hist = (st->vad_hist + 1);
} else
{
- st->vad_hist = 0;
+ st->vad_hist = 0;
}
/* DTX processing */
@@ -378,7 +378,7 @@
{
/* Note that mode may change here */
tx_dtx_handler(st->dtx_encSt, vad_flag, mode);
- *ser_size = nb_of_bits[*mode];
+ *ser_size = nb_of_bits[*mode];
}
if(*mode != MRDTX)
@@ -423,7 +423,7 @@
* - scale wsp[] to avoid overflow in pitch estimation *
* - Find open loop pitch lag for whole speech frame *
*----------------------------------------------------------------------*/
- p_A = A;
+ p_A = A;
for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR)
{
/* Weighting of LPC coefficients */
@@ -435,27 +435,27 @@
Residu(Ap, &speech[i_subfr], &wsp[i_subfr], L_SUBFR);
#endif
- p_A += (M + 1);
+ p_A += (M + 1);
}
Deemph2(wsp, TILT_FAC, L_FRAME, &(st->mem_wsp));
/* find maximum value on wsp[] for 12 bits scaling */
- max = 0;
+ max = 0;
for (i = 0; i < L_FRAME; i++)
{
tmp = abs_s(wsp[i]);
if(tmp > max)
{
- max = tmp;
+ max = tmp;
}
}
- tmp = st->old_wsp_max;
+ tmp = st->old_wsp_max;
if(max > tmp)
{
tmp = max; /* tmp = max(wsp_max, old_wsp_max) */
}
- st->old_wsp_max = max;
+ st->old_wsp_max = max;
shift = norm_s(tmp) - 3;
if (shift > 0)
@@ -494,8 +494,8 @@
if(st->ol_gain > 19661) /* 0.6 in Q15 */
{
- st->old_T0_med = Med_olag(T_op, st->old_ol_lag);
- st->ada_w = 32767;
+ st->old_T0_med = Med_olag(T_op, st->old_ol_lag);
+ st->ada_w = 32767;
} else
{
st->ada_w = vo_mult(st->ada_w, 29491);
@@ -507,7 +507,7 @@
st->ol_wght_flg = 1;
wb_vad_tone_detection(st->vadSt, st->ol_gain);
- T_op *= OPL_DECIM;
+ T_op *= OPL_DECIM;
if(*ser_size != NBBITS_7k)
{
@@ -516,11 +516,11 @@
if(st->ol_gain > 19661) /* 0.6 in Q15 */
{
- st->old_T0_med = Med_olag(T_op2, st->old_ol_lag);
- st->ada_w = 32767;
+ st->old_T0_med = Med_olag(T_op2, st->old_ol_lag);
+ st->ada_w = 32767;
} else
{
- st->ada_w = mult(st->ada_w, 29491);
+ st->ada_w = mult(st->ada_w, 29491);
}
if(st->ada_w < 26214)
@@ -530,11 +530,11 @@
wb_vad_tone_detection(st->vadSt, st->ol_gain);
- T_op2 *= OPL_DECIM;
+ T_op2 *= OPL_DECIM;
} else
{
- T_op2 = T_op;
+ T_op2 = T_op;
}
/*----------------------------------------------------------------------*
* DTX-CNG *
@@ -550,10 +550,10 @@
for (i = 0; i < L_FRAME; i++)
{
- exc2[i] = shr(exc[i], Q_new);
+ exc2[i] = shr(exc[i], Q_new);
}
- L_tmp = 0;
+ L_tmp = 0;
for (i = 0; i < L_FRAME; i++)
L_tmp += (exc2[i] * exc2[i])<<1;
@@ -617,23 +617,23 @@
/* Check stability on isf : distance between old isf and current isf */
- L_tmp = 0;
+ L_tmp = 0;
for (i = 0; i < M - 1; i++)
{
tmp = vo_sub(isf[i], st->isfold[i]);
L_tmp += (tmp * tmp)<<1;
}
- tmp = extract_h(L_shl2(L_tmp, 8));
+ tmp = extract_h(L_shl2(L_tmp, 8));
tmp = vo_mult(tmp, 26214); /* tmp = L_tmp*0.8/256 */
tmp = vo_sub(20480, tmp); /* 1.25 - tmp (in Q14) */
- stab_fac = shl(tmp, 1);
+ stab_fac = shl(tmp, 1);
if (stab_fac < 0)
{
- stab_fac = 0;
+ stab_fac = 0;
}
Copy(isf, st->isfold, M);
@@ -642,7 +642,7 @@
if (st->first_frame != 0)
{
- st->first_frame = 0;
+ st->first_frame = 0;
Copy(ispnew_q, st->ispold_q, M);
}
/* Find the interpolated ISPs and convert to a[] for all subframes */
@@ -660,7 +660,7 @@
#else
Residu(p_Aq, &speech[i_subfr], &exc[i_subfr], L_SUBFR);
#endif
- p_Aq += (M + 1);
+ p_Aq += (M + 1);
}
/* Buffer isf's and energy for dtx on non-speech frame */
@@ -670,7 +670,7 @@
{
exc2[i] = exc[i] >> Q_new;
}
- L_tmp = 0;
+ L_tmp = 0;
for (i = 0; i < L_FRAME; i++)
L_tmp += (exc2[i] * exc2[i])<<1;
L_tmp >>= 1;
@@ -682,14 +682,14 @@
T0_min = T_op - 8;
if (T0_min < PIT_MIN)
{
- T0_min = PIT_MIN;
+ T0_min = PIT_MIN;
}
T0_max = (T0_min + 15);
if(T0_max > PIT_MAX)
{
- T0_max = PIT_MAX;
- T0_min = T0_max - 15;
+ T0_max = PIT_MAX;
+ T0_min = T0_max - 15;
}
/*------------------------------------------------------------------------*
* Loop for every subframe in the analysis frame *
@@ -711,25 +711,25 @@
* - update states of weighting filter *
* - find excitation and synthesis speech *
*------------------------------------------------------------------------*/
- p_A = A;
- p_Aq = Aq;
+ p_A = A;
+ p_Aq = Aq;
for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR)
{
- pit_flag = i_subfr;
+ pit_flag = i_subfr;
if ((i_subfr == 2 * L_SUBFR) && (*ser_size > NBBITS_7k))
{
- pit_flag = 0;
+ pit_flag = 0;
/* range for closed loop pitch search in 3rd subframe */
T0_min = (T_op2 - 8);
if (T0_min < PIT_MIN)
{
- T0_min = PIT_MIN;
+ T0_min = PIT_MIN;
}
T0_max = (T0_min + 15);
if (T0_max > PIT_MAX)
{
- T0_max = PIT_MAX;
+ T0_max = PIT_MAX;
T0_min = (T0_max - 15);
}
}
@@ -776,7 +776,7 @@
/* first half: xn[] --> cn[] */
Set_zero(code, M);
Copy(xn, code + M, L_SUBFR / 2);
- tmp = 0;
+ tmp = 0;
Preemph2(code + M, TILT_FAC, L_SUBFR / 2, &tmp);
Weight_a(p_A, Ap, GAMMA1, M);
Syn_filt(Ap,code + M, code + M, L_SUBFR / 2, code, 0);
@@ -791,7 +791,7 @@
Copy(&exc[i_subfr + (L_SUBFR / 2)], cn + (L_SUBFR / 2), L_SUBFR / 2);
/*---------------------------------------------------------------*
- * Compute impulse response, h1[], of weighted synthesis filter *
+ * Compute impulse response, h1[], of weighted synthesis filter *
*---------------------------------------------------------------*/
Set_zero(error, M + L_SUBFR);
@@ -814,7 +814,7 @@
*vo_p3++ = *vo_p0++ = vo_round((L_tmp <<4));
}
/* deemph without division by 2 -> Q14 to Q15 */
- tmp = 0;
+ tmp = 0;
Deemph2(h1, TILT_FAC, L_SUBFR, &tmp); /* h1 in Q14 */
/* h2 in Q12 for codebook search */
@@ -917,7 +917,7 @@
T0_min = (T0 - 8);
if (T0_min < PIT_MIN)
{
- T0_min = PIT_MIN;
+ T0_min = PIT_MIN;
}
T0_max = T0_min + 15;
@@ -964,18 +964,18 @@
Convolve_asm(&exc[i_subfr], h1, y1, L_SUBFR);
#else
Convolve(&exc[i_subfr], h1, y1, L_SUBFR);
-#endif
+#endif
gain1 = G_pitch(xn, y1, g_coeff, L_SUBFR);
/* clip gain if necessary to avoid problem at decoder */
if ((clip_gain != 0) && (gain1 > GP_CLIP))
{
- gain1 = GP_CLIP;
+ gain1 = GP_CLIP;
}
/* find energy of new target xn2[] */
Updt_tar(xn, dn, y1, gain1, L_SUBFR); /* dn used temporary */
} else
{
- gain1 = 0;
+ gain1 = 0;
}
/*-----------------------------------------------------------------*
* - find pitch excitation filtered by 1st order LP filter. *
@@ -1002,7 +1002,7 @@
Convolve_asm(code, h1, y2, L_SUBFR);
#else
Convolve(code, h1, y2, L_SUBFR);
-#endif
+#endif
gain2 = G_pitch(xn, y2, g_coeff2, L_SUBFR);
@@ -1016,7 +1016,7 @@
/*-----------------------------------------------------------------*
* use the best prediction (minimise quadratic error). *
*-----------------------------------------------------------------*/
- select = 0;
+ select = 0;
if(*ser_size > NBBITS_9k)
{
L_tmp = 0L;
@@ -1036,7 +1036,7 @@
if (L_tmp <= 0)
{
- select = 1;
+ select = 1;
}
Parm_serial(select, 1, &prms);
}
@@ -1154,7 +1154,7 @@
/*-------------------------------------------------------*
* - Add the fixed-gain pitch contribution to code[]. *
*-------------------------------------------------------*/
- tmp = 0;
+ tmp = 0;
Preemph(code, st->tilt_code, L_SUBFR, &tmp);
Pit_shrp(code, T0, PIT_SHARP, L_SUBFR);
/*----------------------------------------------------------*
@@ -1175,7 +1175,7 @@
/* test quantized gain of pitch for pitch clipping algorithm */
Gp_clip_test_gain_pit(gain_pit, st->gp_clip);
- L_tmp = L_shl(L_gain_code, Q_new);
+ L_tmp = L_shl(L_gain_code, Q_new);
gain_code = extract_h(L_add(L_tmp, 0x8000));
/*----------------------------------------------------------*
@@ -1218,7 +1218,7 @@
L_tmp = (gain_code * code[i])<<1;
L_tmp = (L_tmp << 5);
L_tmp += (exc[i + i_subfr] * gain_pit)<<1;
- L_tmp = L_shl2(L_tmp, 1);
+ L_tmp = L_shl2(L_tmp, 1);
exc[i + i_subfr] = extract_h(L_add(L_tmp, 0x8000));
}
@@ -1242,7 +1242,7 @@
*------------------------------------------------------------*/
tmp = (16384 - (voice_fac >> 1)); /* 1=unvoiced, 0=voiced */
fac = vo_mult(stab_fac, tmp);
- L_tmp = L_gain_code;
+ L_tmp = L_gain_code;
if(L_tmp < st->L_gc_thres)
{
L_tmp = vo_L_add(L_tmp, Mpy_32_16(gain_code, gain_code_lo, 6226));
@@ -1276,19 +1276,19 @@
L_tmp = L_deposit_h(code[0]);
L_tmp -= (code[1] * tmp)<<1;
- code2[0] = vo_round(L_tmp);
+ code2[0] = vo_round(L_tmp);
for (i = 1; i < L_SUBFR - 1; i++)
{
L_tmp = L_deposit_h(code[i]);
L_tmp -= (code[i + 1] * tmp)<<1;
L_tmp -= (code[i - 1] * tmp)<<1;
- code2[i] = vo_round(L_tmp);
+ code2[i] = vo_round(L_tmp);
}
L_tmp = L_deposit_h(code[L_SUBFR - 1]);
L_tmp -= (code[L_SUBFR - 2] * tmp)<<1;
- code2[L_SUBFR - 1] = vo_round(L_tmp);
+ code2[L_SUBFR - 1] = vo_round(L_tmp);
/* build excitation */
gain_code = vo_round(L_shl(L_gain_code, Q_new));
@@ -1381,7 +1381,7 @@
/* Original speech signal as reference for high band gain quantisation */
for (i = 0; i < L_SUBFR16k; i++)
{
- HF_SP[i] = synth16k[i];
+ HF_SP[i] = synth16k[i];
}
/*------------------------------------------------------*
@@ -1454,7 +1454,7 @@
fac = div_s(tmp, ener);
} else
{
- fac = 0;
+ fac = 0;
}
/* modify energy of white noise according to synthesis tilt */
@@ -1550,7 +1550,7 @@
/*************************************************
*
-* Breif: Codec main function
+* Breif: Codec main function
*
**************************************************/
@@ -1622,7 +1622,7 @@
else
{
pMemOP = (VO_MEM_OPERATOR *)pUserData->memData;
- }
+ }
/*-------------------------------------------------------------------------*
* Memory allocation for coder state. *
*-------------------------------------------------------------------------*/
@@ -1631,8 +1631,8 @@
return VO_ERR_OUTOF_MEMORY;
}
- st->vadSt = NULL;
- st->dtx_encSt = NULL;
+ st->vadSt = NULL;
+ st->dtx_encSt = NULL;
st->sid_update_counter = 3;
st->sid_handover_debt = 0;
st->prev_ft = TX_SPEECH;
@@ -1764,7 +1764,7 @@
{
pAudioFormat->Format.Channels = 1;
pAudioFormat->Format.SampleRate = 8000;
- pAudioFormat->Format.SampleBits = 16;
+ pAudioFormat->Format.SampleBits = 16;
pAudioFormat->InputUsed = stream->used_len;
}
return VO_ERR_NONE;
@@ -1792,14 +1792,14 @@
/* setting AMR-WB frame type*/
case VO_PID_AMRWB_FRAMETYPE:
if(*lValue < VOAMRWB_DEFAULT || *lValue > VOAMRWB_RFC3267)
- return VO_ERR_WRONG_PARAM_ID;
+ return VO_ERR_WRONG_PARAM_ID;
gData->frameType = *lValue;
break;
/* setting AMR-WB bit rate */
case VO_PID_AMRWB_MODE:
{
if(*lValue < VOAMRWB_MD66 || *lValue > VOAMRWB_MD2385)
- return VO_ERR_WRONG_PARAM_ID;
+ return VO_ERR_WRONG_PARAM_ID;
gData->mode = *lValue;
}
break;
@@ -1839,7 +1839,7 @@
int temp;
Coder_State* gData = (Coder_State*)hCodec;
- if (gData==NULL)
+ if (gData==NULL)
return VO_ERR_INVALID_ARG;
switch(uParamID)
{
diff --git a/media/libstagefright/codecs/amrwbenc/src/voicefac.c b/media/libstagefright/codecs/amrwbenc/src/voicefac.c
index d890044..17e4e55 100644
--- a/media/libstagefright/codecs/amrwbenc/src/voicefac.c
+++ b/media/libstagefright/codecs/amrwbenc/src/voicefac.c
@@ -18,7 +18,7 @@
* File: voicefac.c *
* *
* Description: Find the voicing factors (1 = voice to -1 = unvoiced) *
-* *
+* *
************************************************************************/
#include "typedef.h"
diff --git a/media/libstagefright/codecs/amrwbenc/src/wb_vad.c b/media/libstagefright/codecs/amrwbenc/src/wb_vad.c
index 13dd2aa..7e1d673 100644
--- a/media/libstagefright/codecs/amrwbenc/src/wb_vad.c
+++ b/media/libstagefright/codecs/amrwbenc/src/wb_vad.c
@@ -52,7 +52,7 @@
if (mant <= 0)
{
- mant = 1;
+ mant = 1;
}
ex = norm_s(mant);
mant = mant << ex;
@@ -88,14 +88,14 @@
temp0 = vo_sub(*in0, vo_mult(COEFF5_1, data[0]));
temp1 = add1(data[0], vo_mult(COEFF5_1, temp0));
- data[0] = temp0;
+ data[0] = temp0;
temp0 = vo_sub(*in1, vo_mult(COEFF5_2, data[1]));
temp2 = add1(data[1], vo_mult(COEFF5_2, temp0));
- data[1] = temp0;
+ data[1] = temp0;
- *in0 = extract_h((vo_L_add(temp1, temp2) << 15));
- *in1 = extract_h((vo_L_sub(temp1, temp2) << 15));
+ *in0 = extract_h((vo_L_add(temp1, temp2) << 15));
+ *in1 = extract_h((vo_L_sub(temp1, temp2) << 15));
}
/******************************************************************************
@@ -116,10 +116,10 @@
temp1 = vo_sub(*in1, vo_mult(COEFF3, *data));
temp2 = add1(*data, vo_mult(COEFF3, temp1));
- *data = temp1;
+ *data = temp1;
- *in1 = extract_h((vo_L_sub(*in0, temp2) << 15));
- *in0 = extract_h((vo_L_add(*in0, temp2) << 15));
+ *in1 = extract_h((vo_L_sub(*in0, temp2) << 15));
+ *in0 = extract_h((vo_L_add(*in0, temp2) << 15));
}
/******************************************************************************
@@ -149,14 +149,14 @@
Word32 i, l_temp1, l_temp2;
Word16 level;
- l_temp1 = 0L;
+ l_temp1 = 0L;
for (i = count1; i < count2; i++)
{
l_temp1 += (abs_s(data[ind_m * i + ind_a])<<1);
}
l_temp2 = vo_L_add(l_temp1, L_shl(*sub_level, 16 - scale));
- *sub_level = extract_h(L_shl(l_temp1, scale));
+ *sub_level = extract_h(L_shl(l_temp1, scale));
for (i = 0; i < count1; i++)
{
@@ -187,7 +187,7 @@
/* shift input 1 bit down for safe scaling */
for (i = 0; i < FRAME_LEN; i++)
{
- tmp_buf[i] = in[i] >> 1;
+ tmp_buf[i] = in[i] >> 1;
}
/* run the filter bank */
@@ -222,29 +222,29 @@
/* calculate levels in each frequency band */
/* 4800 - 6400 Hz */
- level[11] = level_calculation(tmp_buf, &st->sub_level[11], 16, 64, 4, 1, 14);
+ level[11] = level_calculation(tmp_buf, &st->sub_level[11], 16, 64, 4, 1, 14);
/* 4000 - 4800 Hz */
- level[10] = level_calculation(tmp_buf, &st->sub_level[10], 8, 32, 8, 7, 15);
+ level[10] = level_calculation(tmp_buf, &st->sub_level[10], 8, 32, 8, 7, 15);
/* 3200 - 4000 Hz */
- level[9] = level_calculation(tmp_buf, &st->sub_level[9],8, 32, 8, 3, 15);
+ level[9] = level_calculation(tmp_buf, &st->sub_level[9],8, 32, 8, 3, 15);
/* 2400 - 3200 Hz */
- level[8] = level_calculation(tmp_buf, &st->sub_level[8],8, 32, 8, 2, 15);
+ level[8] = level_calculation(tmp_buf, &st->sub_level[8],8, 32, 8, 2, 15);
/* 2000 - 2400 Hz */
- level[7] = level_calculation(tmp_buf, &st->sub_level[7],4, 16, 16, 14, 16);
+ level[7] = level_calculation(tmp_buf, &st->sub_level[7],4, 16, 16, 14, 16);
/* 1600 - 2000 Hz */
- level[6] = level_calculation(tmp_buf, &st->sub_level[6],4, 16, 16, 6, 16);
+ level[6] = level_calculation(tmp_buf, &st->sub_level[6],4, 16, 16, 6, 16);
/* 1200 - 1600 Hz */
- level[5] = level_calculation(tmp_buf, &st->sub_level[5],4, 16, 16, 4, 16);
+ level[5] = level_calculation(tmp_buf, &st->sub_level[5],4, 16, 16, 4, 16);
/* 800 - 1200 Hz */
- level[4] = level_calculation(tmp_buf, &st->sub_level[4],4, 16, 16, 12, 16);
+ level[4] = level_calculation(tmp_buf, &st->sub_level[4],4, 16, 16, 12, 16);
/* 600 - 800 Hz */
- level[3] = level_calculation(tmp_buf, &st->sub_level[3],2, 8, 32, 8, 17);
+ level[3] = level_calculation(tmp_buf, &st->sub_level[3],2, 8, 32, 8, 17);
/* 400 - 600 Hz */
- level[2] = level_calculation(tmp_buf, &st->sub_level[2],2, 8, 32, 24, 17);
+ level[2] = level_calculation(tmp_buf, &st->sub_level[2],2, 8, 32, 24, 17);
/* 200 - 400 Hz */
- level[1] = level_calculation(tmp_buf, &st->sub_level[1],2, 8, 32, 16, 17);
+ level[1] = level_calculation(tmp_buf, &st->sub_level[1],2, 8, 32, 16, 17);
/* 0 - 200 Hz */
- level[0] = level_calculation(tmp_buf, &st->sub_level[0],2, 8, 32, 0, 17);
+ level[0] = level_calculation(tmp_buf, &st->sub_level[0],2, 8, 32, 0, 17);
}
/******************************************************************************
@@ -266,31 +266,31 @@
/* if a tone has been detected for a while, initialize stat_count */
if (sub((Word16) (st->tone_flag & 0x7c00), 0x7c00) == 0)
{
- st->stat_count = STAT_COUNT;
+ st->stat_count = STAT_COUNT;
} else
{
/* if 8 last vad-decisions have been "0", reinitialize stat_count */
if ((st->vadreg & 0x7f80) == 0)
{
- st->stat_count = STAT_COUNT;
+ st->stat_count = STAT_COUNT;
} else
{
- stat_rat = 0;
+ stat_rat = 0;
for (i = 0; i < COMPLEN; i++)
{
if(level[i] > st->ave_level[i])
{
- num = level[i];
- denom = st->ave_level[i];
+ num = level[i];
+ denom = st->ave_level[i];
} else
{
num = st->ave_level[i];
- denom = level[i];
+ denom = level[i];
}
/* Limit nimimum value of num and denom to STAT_THR_LEVEL */
if(num < STAT_THR_LEVEL)
{
- num = STAT_THR_LEVEL;
+ num = STAT_THR_LEVEL;
}
if(denom < STAT_THR_LEVEL)
{
@@ -307,7 +307,7 @@
/* compare stat_rat with a threshold and update stat_count */
if(stat_rat > STAT_THR)
{
- st->stat_count = STAT_COUNT;
+ st->stat_count = STAT_COUNT;
} else
{
if ((st->vadreg & 0x4000) != 0)
@@ -315,7 +315,7 @@
if (st->stat_count != 0)
{
- st->stat_count = st->stat_count - 1;
+ st->stat_count = st->stat_count - 1;
}
}
}
@@ -323,17 +323,17 @@
}
/* Update average amplitude estimate for stationarity estimation */
- alpha = ALPHA4;
+ alpha = ALPHA4;
if(st->stat_count == STAT_COUNT)
{
- alpha = 32767;
+ alpha = 32767;
} else if ((st->vadreg & 0x4000) == 0)
{
- alpha = ALPHA5;
+ alpha = ALPHA5;
}
for (i = 0; i < COMPLEN; i++)
{
- st->ave_level[i] = add1(st->ave_level[i], vo_mult_r(alpha, vo_sub(level[i], st->ave_level[i])));
+ st->ave_level[i] = add1(st->ave_level[i], vo_mult_r(alpha, vo_sub(level[i], st->ave_level[i])));
}
}
@@ -354,25 +354,25 @@
/* if the input power (pow_sum) is lower than a threshold, clear counters and set VAD_flag to "0" */
if (low_power != 0)
{
- st->burst_count = 0;
- st->hang_count = 0;
+ st->burst_count = 0;
+ st->hang_count = 0;
return 0;
}
/* update the counters (hang_count, burst_count) */
if ((st->vadreg & 0x4000) != 0)
{
- st->burst_count = st->burst_count + 1;
+ st->burst_count = st->burst_count + 1;
if(st->burst_count >= burst_len)
{
- st->hang_count = hang_len;
+ st->hang_count = hang_len;
}
return 1;
} else
{
- st->burst_count = 0;
+ st->burst_count = 0;
if (st->hang_count > 0)
{
- st->hang_count = st->hang_count - 1;
+ st->hang_count = st->hang_count - 1;
return 1;
}
}
@@ -391,7 +391,7 @@
Word16 level[] /* i : sub-band levels of the input frame */
)
{
- Word32 i;
+ Word32 i;
Word16 alpha_up, alpha_down, bckr_add = 2;
/* Control update of bckr_est[] */
@@ -400,19 +400,19 @@
/* Choose update speed */
if ((0x7800 & st->vadreg) == 0)
{
- alpha_up = ALPHA_UP1;
- alpha_down = ALPHA_DOWN1;
+ alpha_up = ALPHA_UP1;
+ alpha_down = ALPHA_DOWN1;
} else
{
if ((st->stat_count == 0))
{
- alpha_up = ALPHA_UP2;
- alpha_down = ALPHA_DOWN2;
+ alpha_up = ALPHA_UP2;
+ alpha_down = ALPHA_DOWN2;
} else
{
- alpha_up = 0;
- alpha_down = ALPHA3;
- bckr_add = 0;
+ alpha_up = 0;
+ alpha_down = ALPHA3;
+ bckr_add = 0;
}
}
@@ -424,20 +424,20 @@
if (temp < 0)
{ /* update downwards */
- st->bckr_est[i] = add1(-2, add(st->bckr_est[i],vo_mult_r(alpha_down, temp)));
+ st->bckr_est[i] = add1(-2, add(st->bckr_est[i],vo_mult_r(alpha_down, temp)));
/* limit minimum value of the noise estimate to NOISE_MIN */
if(st->bckr_est[i] < NOISE_MIN)
{
- st->bckr_est[i] = NOISE_MIN;
+ st->bckr_est[i] = NOISE_MIN;
}
} else
{ /* update upwards */
- st->bckr_est[i] = add1(bckr_add, add1(st->bckr_est[i],vo_mult_r(alpha_up, temp)));
+ st->bckr_est[i] = add1(bckr_add, add1(st->bckr_est[i],vo_mult_r(alpha_up, temp)));
/* limit maximum value of the noise estimate to NOISE_MAX */
if(st->bckr_est[i] > NOISE_MAX)
{
- st->bckr_est[i] = NOISE_MAX;
+ st->bckr_est[i] = NOISE_MAX;
}
}
}
@@ -445,7 +445,7 @@
/* Update signal levels of the previous frame (old_level) */
for (i = 0; i < COMPLEN; i++)
{
- st->old_level[i] = level[i];
+ st->old_level[i] = level[i];
}
}
@@ -473,7 +473,7 @@
/* Calculate squared sum of the input levels (level) divided by the background noise components
* (bckr_est). */
- L_snr_sum = 0;
+ L_snr_sum = 0;
for (i = 0; i < COMPLEN; i++)
{
Word16 exp;
@@ -486,7 +486,7 @@
}
/* Calculate average level of estimated background noise */
- L_temp = 0;
+ L_temp = 0;
for (i = 1; i < COMPLEN; i++) /* ignore lowest band */
{
L_temp = vo_L_add(L_temp, st->bckr_est[i]);
@@ -498,7 +498,7 @@
if(st->speech_level < temp)
{
- st->speech_level = temp;
+ st->speech_level = temp;
}
ilog2_noise_level = ilog2(noise_level);
@@ -511,33 +511,33 @@
temp2 = add1(SP_CH_MIN, vo_mult(SP_SLOPE, (ilog2_speech_level - SP_P1)));
if (temp2 < SP_CH_MIN)
{
- temp2 = SP_CH_MIN;
+ temp2 = SP_CH_MIN;
}
if (temp2 > SP_CH_MAX)
{
- temp2 = SP_CH_MAX;
+ temp2 = SP_CH_MAX;
}
vad_thr = temp + temp2;
if(vad_thr < THR_MIN)
{
- vad_thr = THR_MIN;
+ vad_thr = THR_MIN;
}
/* Shift VAD decision register */
- st->vadreg = (st->vadreg >> 1);
+ st->vadreg = (st->vadreg >> 1);
/* Make intermediate VAD decision */
if(L_snr_sum > vo_L_mult(vad_thr, (512 * COMPLEN)))
{
- st->vadreg = (Word16) (st->vadreg | 0x4000);
+ st->vadreg = (Word16) (st->vadreg | 0x4000);
}
/* check if the input power (pow_sum) is lower than a threshold" */
if(pow_sum < VAD_POW_LOW)
{
- low_power_flag = 1;
+ low_power_flag = 1;
} else
{
- low_power_flag = 0;
+ low_power_flag = 0;
}
/* Update background noise estimates */
noise_estimate_update(st, level);
@@ -546,7 +546,7 @@
hang_len = add1(vo_mult(HANG_SLOPE, (vad_thr - HANG_P1)), HANG_HIGH);
if(hang_len < HANG_LOW)
{
- hang_len = HANG_LOW;
+ hang_len = HANG_LOW;
}
burst_len = add1(vo_mult(BURST_SLOPE, (vad_thr - BURST_P1)), BURST_HIGH);
@@ -575,20 +575,20 @@
/* if the required activity count cannot be achieved, reset counters */
if((st->sp_est_cnt - st->sp_max_cnt) > (SP_EST_COUNT - SP_ACTIVITY_COUNT))
{
- st->sp_est_cnt = 0;
- st->sp_max = 0;
- st->sp_max_cnt = 0;
+ st->sp_est_cnt = 0;
+ st->sp_max = 0;
+ st->sp_max_cnt = 0;
}
- st->sp_est_cnt += 1;
+ st->sp_est_cnt += 1;
if (((st->vadreg & 0x4000)||(in_level > st->speech_level)) && (in_level > MIN_SPEECH_LEVEL1))
{
/* update sp_max */
if(in_level > st->sp_max)
{
- st->sp_max = in_level;
+ st->sp_max = in_level;
}
- st->sp_max_cnt += 1;
+ st->sp_max_cnt += 1;
if(st->sp_max_cnt >= SP_ACTIVITY_COUNT)
{
@@ -599,19 +599,19 @@
/* select update speed */
if(tmp > st->speech_level)
{
- alpha = ALPHA_SP_UP;
+ alpha = ALPHA_SP_UP;
} else
{
- alpha = ALPHA_SP_DOWN;
+ alpha = ALPHA_SP_DOWN;
}
if(tmp > MIN_SPEECH_LEVEL2)
{
- st->speech_level = add1(st->speech_level, vo_mult_r(alpha, vo_sub(tmp, st->speech_level)));
+ st->speech_level = add1(st->speech_level, vo_mult_r(alpha, vo_sub(tmp, st->speech_level)));
}
/* clear all counters used for speech estimation */
- st->sp_max = 0;
- st->sp_max_cnt = 0;
- st->sp_est_cnt = 0;
+ st->sp_max = 0;
+ st->sp_max_cnt = 0;
+ st->sp_est_cnt = 0;
}
}
}
@@ -767,22 +767,22 @@
Word32 L_temp, pow_sum;
/* Calculate power of the input frame. */
- L_temp = 0L;
+ L_temp = 0L;
for (i = 0; i < FRAME_LEN; i++)
{
L_temp = L_mac(L_temp, in_buf[i], in_buf[i]);
}
/* pow_sum = power of current frame and previous frame */
- pow_sum = L_add(L_temp, st->prev_pow_sum);
+ pow_sum = L_add(L_temp, st->prev_pow_sum);
/* save power of current frame for next call */
- st->prev_pow_sum = L_temp;
+ st->prev_pow_sum = L_temp;
/* If input power is very low, clear tone flag */
if (pow_sum < POW_TONE_THR)
{
- st->tone_flag = (Word16) (st->tone_flag & 0x1fff);
+ st->tone_flag = (Word16) (st->tone_flag & 0x1fff);
}
/* Run the filter bank and calculate signal levels at each band */
filter_bank(st, in_buf, level);
@@ -791,7 +791,7 @@
VAD_flag = vad_decision(st, level, pow_sum);
/* Calculate input level */
- L_temp = 0;
+ L_temp = 0;
for (i = 1; i < COMPLEN; i++) /* ignore lowest band */
{
L_temp = vo_L_add(L_temp, level[i]);
diff --git a/media/libstagefright/codecs/amrwbenc/src/weight_a.c b/media/libstagefright/codecs/amrwbenc/src/weight_a.c
index a02b48d..8f0fb39 100644
--- a/media/libstagefright/codecs/amrwbenc/src/weight_a.c
+++ b/media/libstagefright/codecs/amrwbenc/src/weight_a.c
@@ -19,7 +19,7 @@
* *
* Description:Weighting of LPC coefficients *
* ap[i] = a[i] * (gamma ** i) *
-* *
+* *
************************************************************************/
#include "typedef.h"
diff --git a/media/libstagefright/codecs/avc/dec/AVCDecoder.cpp b/media/libstagefright/codecs/avc/dec/AVCDecoder.cpp
deleted file mode 100644
index 5bbba35..0000000
--- a/media/libstagefright/codecs/avc/dec/AVCDecoder.cpp
+++ /dev/null
@@ -1,621 +0,0 @@
-/*
- * 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 "AVCDecoder"
-#include <utils/Log.h>
-
-#include "AVCDecoder.h"
-
-#include "avcdec_api.h"
-#include "avcdec_int.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>
-#include <media/stagefright/foundation/hexdump.h>
-
-namespace android {
-
-static const char kStartCode[4] = { 0x00, 0x00, 0x00, 0x01 };
-
-static int32_t Malloc(void *userData, int32_t size, int32_t attrs) {
- return reinterpret_cast<int32_t>(malloc(size));
-}
-
-static void Free(void *userData, int32_t ptr) {
- free(reinterpret_cast<void *>(ptr));
-}
-
-AVCDecoder::AVCDecoder(const sp<MediaSource> &source)
- : mSource(source),
- mStarted(false),
- mHandle(new tagAVCHandle),
- mInputBuffer(NULL),
- mAnchorTimeUs(0),
- mNumSamplesOutput(0),
- mPendingSeekTimeUs(-1),
- mPendingSeekMode(MediaSource::ReadOptions::SEEK_CLOSEST_SYNC),
- mTargetTimeUs(-1),
- mSPSSeen(false),
- mPPSSeen(false) {
- memset(mHandle, 0, sizeof(tagAVCHandle));
- mHandle->AVCObject = NULL;
- mHandle->userData = this;
- mHandle->CBAVC_DPBAlloc = ActivateSPSWrapper;
- mHandle->CBAVC_FrameBind = BindFrameWrapper;
- mHandle->CBAVC_FrameUnbind = UnbindFrame;
- mHandle->CBAVC_Malloc = Malloc;
- mHandle->CBAVC_Free = Free;
-
- mFormat = new MetaData;
- mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
- int32_t width, height;
- CHECK(mSource->getFormat()->findInt32(kKeyWidth, &width));
- CHECK(mSource->getFormat()->findInt32(kKeyHeight, &height));
- mFormat->setInt32(kKeyWidth, width);
- mFormat->setInt32(kKeyHeight, height);
- mFormat->setRect(kKeyCropRect, 0, 0, width - 1, height - 1);
- mFormat->setInt32(kKeyColorFormat, OMX_COLOR_FormatYUV420Planar);
- mFormat->setCString(kKeyDecoderComponent, "AVCDecoder");
-
- int64_t durationUs;
- if (mSource->getFormat()->findInt64(kKeyDuration, &durationUs)) {
- mFormat->setInt64(kKeyDuration, durationUs);
- }
-}
-
-AVCDecoder::~AVCDecoder() {
- if (mStarted) {
- stop();
- }
-
- PVAVCCleanUpDecoder(mHandle);
-
- delete mHandle;
- mHandle = NULL;
-}
-
-status_t AVCDecoder::start(MetaData *) {
- CHECK(!mStarted);
-
- uint32_t type;
- const void *data;
- size_t size;
- sp<MetaData> meta = mSource->getFormat();
- if (meta->findData(kKeyAVCC, &type, &data, &size)) {
- // Parse the AVCDecoderConfigurationRecord
-
- const uint8_t *ptr = (const uint8_t *)data;
-
- CHECK(size >= 7);
- CHECK_EQ(ptr[0], 1); // configurationVersion == 1
- uint8_t profile = ptr[1];
- uint8_t level = ptr[3];
-
- // There is decodable content out there that fails the following
- // assertion, let's be lenient for now...
- // CHECK((ptr[4] >> 2) == 0x3f); // reserved
-
- size_t lengthSize = 1 + (ptr[4] & 3);
-
- // commented out check below as H264_QVGA_500_NO_AUDIO.3gp
- // violates it...
- // CHECK((ptr[5] >> 5) == 7); // reserved
-
- size_t numSeqParameterSets = ptr[5] & 31;
-
- ptr += 6;
- size -= 6;
-
- for (size_t i = 0; i < numSeqParameterSets; ++i) {
- CHECK(size >= 2);
- size_t length = U16_AT(ptr);
-
- ptr += 2;
- size -= 2;
-
- CHECK(size >= length);
-
- addCodecSpecificData(ptr, length);
-
- ptr += length;
- size -= length;
- }
-
- CHECK(size >= 1);
- size_t numPictureParameterSets = *ptr;
- ++ptr;
- --size;
-
- for (size_t i = 0; i < numPictureParameterSets; ++i) {
- CHECK(size >= 2);
- size_t length = U16_AT(ptr);
-
- ptr += 2;
- size -= 2;
-
- CHECK(size >= length);
-
- addCodecSpecificData(ptr, length);
-
- ptr += length;
- size -= length;
- }
- }
-
- mSource->start();
-
- mAnchorTimeUs = 0;
- mNumSamplesOutput = 0;
- mPendingSeekTimeUs = -1;
- mPendingSeekMode = ReadOptions::SEEK_CLOSEST_SYNC;
- mTargetTimeUs = -1;
- mSPSSeen = false;
- mPPSSeen = false;
- mStarted = true;
-
- return OK;
-}
-
-void AVCDecoder::addCodecSpecificData(const uint8_t *data, size_t size) {
- MediaBuffer *buffer = new MediaBuffer(size + 4);
- memcpy(buffer->data(), kStartCode, 4);
- memcpy((uint8_t *)buffer->data() + 4, data, size);
- buffer->set_range(0, size + 4);
-
- mCodecSpecificData.push(buffer);
-}
-
-status_t AVCDecoder::stop() {
- CHECK(mStarted);
-
- for (size_t i = 0; i < mCodecSpecificData.size(); ++i) {
- (*mCodecSpecificData.editItemAt(i)).release();
- }
- mCodecSpecificData.clear();
-
- if (mInputBuffer) {
- mInputBuffer->release();
- mInputBuffer = NULL;
- }
-
- mSource->stop();
-
- releaseFrames();
-
- mStarted = false;
-
- return OK;
-}
-
-sp<MetaData> AVCDecoder::getFormat() {
- return mFormat;
-}
-
-static void findNALFragment(
- const MediaBuffer *buffer, const uint8_t **fragPtr, size_t *fragSize) {
- const uint8_t *data =
- (const uint8_t *)buffer->data() + buffer->range_offset();
-
- size_t size = buffer->range_length();
-
- CHECK(size >= 4);
- CHECK(!memcmp(kStartCode, data, 4));
-
- size_t offset = 4;
- while (offset + 3 < size && memcmp(kStartCode, &data[offset], 4)) {
- ++offset;
- }
-
- *fragPtr = &data[4];
- if (offset + 3 >= size) {
- *fragSize = size - 4;
- } else {
- *fragSize = offset - 4;
- }
-}
-
-MediaBuffer *AVCDecoder::drainOutputBuffer() {
- int32_t index;
- int32_t Release;
- AVCFrameIO Output;
- Output.YCbCr[0] = Output.YCbCr[1] = Output.YCbCr[2] = NULL;
- AVCDec_Status status = PVAVCDecGetOutput(mHandle, &index, &Release, &Output);
-
- if (status != AVCDEC_SUCCESS) {
- LOGV("PVAVCDecGetOutput returned error %d", status);
- return NULL;
- }
-
- CHECK(index >= 0);
- CHECK(index < (int32_t)mFrames.size());
-
- MediaBuffer *mbuf = mFrames.editItemAt(index);
-
- bool skipFrame = false;
-
- if (mTargetTimeUs >= 0) {
- int64_t timeUs;
- CHECK(mbuf->meta_data()->findInt64(kKeyTime, &timeUs));
- CHECK(timeUs <= mTargetTimeUs);
-
- if (timeUs < mTargetTimeUs) {
- // We're still waiting for the frame with the matching
- // timestamp and we won't return the current one.
- skipFrame = true;
-
- LOGV("skipping frame at %lld us", timeUs);
- } else {
- LOGV("found target frame at %lld us", timeUs);
-
- mTargetTimeUs = -1;
- }
- }
-
- if (!skipFrame) {
- mbuf->set_range(0, mbuf->size());
- mbuf->add_ref();
-
- return mbuf;
- }
-
- return new MediaBuffer(0);
-}
-
-status_t AVCDecoder::read(
- MediaBuffer **out, const ReadOptions *options) {
- *out = NULL;
-
- int64_t seekTimeUs;
- ReadOptions::SeekMode mode;
- if (options && options->getSeekTo(&seekTimeUs, &mode)) {
- LOGV("seek requested to %lld us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6);
-
- CHECK(seekTimeUs >= 0);
- mPendingSeekTimeUs = seekTimeUs;
- mPendingSeekMode = mode;
-
- if (mInputBuffer) {
- mInputBuffer->release();
- mInputBuffer = NULL;
- }
-
- PVAVCDecReset(mHandle);
- }
-
- if (mInputBuffer == NULL) {
- LOGV("fetching new input buffer.");
-
- bool seeking = false;
-
- if (!mCodecSpecificData.isEmpty()) {
- mInputBuffer = mCodecSpecificData.editItemAt(0);
- mCodecSpecificData.removeAt(0);
- } else {
- for (;;) {
- if (mPendingSeekTimeUs >= 0) {
- LOGV("reading data from timestamp %lld (%.2f secs)",
- mPendingSeekTimeUs, mPendingSeekTimeUs / 1E6);
- }
-
- ReadOptions seekOptions;
- if (mPendingSeekTimeUs >= 0) {
- seeking = true;
-
- seekOptions.setSeekTo(mPendingSeekTimeUs, mPendingSeekMode);
- mPendingSeekTimeUs = -1;
- }
- status_t err = mSource->read(&mInputBuffer, &seekOptions);
- seekOptions.clearSeekTo();
-
- if (err != OK) {
- *out = drainOutputBuffer();
- return (*out == NULL) ? err : (status_t)OK;
- }
-
- if (mInputBuffer->range_length() > 0) {
- break;
- }
-
- mInputBuffer->release();
- mInputBuffer = NULL;
- }
- }
-
- if (seeking) {
- int64_t targetTimeUs;
- if (mInputBuffer->meta_data()->findInt64(kKeyTargetTime, &targetTimeUs)
- && targetTimeUs >= 0) {
- mTargetTimeUs = targetTimeUs;
- } else {
- mTargetTimeUs = -1;
- }
- }
- }
-
- const uint8_t *fragPtr;
- size_t fragSize;
- findNALFragment(mInputBuffer, &fragPtr, &fragSize);
-
- bool releaseFragment = true;
- status_t err = UNKNOWN_ERROR;
-
- int nalType;
- int nalRefIdc;
- AVCDec_Status res =
- PVAVCDecGetNALType(
- const_cast<uint8_t *>(fragPtr), fragSize,
- &nalType, &nalRefIdc);
-
- if (res != AVCDEC_SUCCESS) {
- LOGV("cannot determine nal type");
- } else if (nalType == AVC_NALTYPE_SPS || nalType == AVC_NALTYPE_PPS
- || (mSPSSeen && mPPSSeen)) {
- switch (nalType) {
- case AVC_NALTYPE_SPS:
- {
- mSPSSeen = true;
-
- res = PVAVCDecSeqParamSet(
- mHandle, const_cast<uint8_t *>(fragPtr),
- fragSize);
-
- if (res != AVCDEC_SUCCESS) {
- LOGV("PVAVCDecSeqParamSet returned error %d", res);
- break;
- }
-
- AVCDecObject *pDecVid = (AVCDecObject *)mHandle->AVCObject;
-
- int32_t width =
- (pDecVid->seqParams[0]->pic_width_in_mbs_minus1 + 1) * 16;
-
- int32_t height =
- (pDecVid->seqParams[0]->pic_height_in_map_units_minus1 + 1) * 16;
-
- int32_t crop_left, crop_right, crop_top, crop_bottom;
- if (pDecVid->seqParams[0]->frame_cropping_flag)
- {
- crop_left = 2 * pDecVid->seqParams[0]->frame_crop_left_offset;
- crop_right =
- width - (2 * pDecVid->seqParams[0]->frame_crop_right_offset + 1);
-
- if (pDecVid->seqParams[0]->frame_mbs_only_flag)
- {
- crop_top = 2 * pDecVid->seqParams[0]->frame_crop_top_offset;
- crop_bottom =
- height -
- (2 * pDecVid->seqParams[0]->frame_crop_bottom_offset + 1);
- }
- else
- {
- crop_top = 4 * pDecVid->seqParams[0]->frame_crop_top_offset;
- crop_bottom =
- height -
- (4 * pDecVid->seqParams[0]->frame_crop_bottom_offset + 1);
- }
- } else {
- crop_bottom = height - 1;
- crop_right = width - 1;
- crop_top = crop_left = 0;
- }
-
- int32_t prevCropLeft, prevCropTop;
- int32_t prevCropRight, prevCropBottom;
- if (!mFormat->findRect(
- kKeyCropRect,
- &prevCropLeft, &prevCropTop,
- &prevCropRight, &prevCropBottom)) {
- prevCropLeft = prevCropTop = 0;
- prevCropRight = width - 1;
- prevCropBottom = height - 1;
- }
-
- int32_t oldWidth, oldHeight;
- CHECK(mFormat->findInt32(kKeyWidth, &oldWidth));
- CHECK(mFormat->findInt32(kKeyHeight, &oldHeight));
-
- if (oldWidth != width || oldHeight != height
- || prevCropLeft != crop_left
- || prevCropTop != crop_top
- || prevCropRight != crop_right
- || prevCropBottom != crop_bottom) {
- mFormat->setRect(
- kKeyCropRect,
- crop_left, crop_top, crop_right, crop_bottom);
-
- mFormat->setInt32(kKeyWidth, width);
- mFormat->setInt32(kKeyHeight, height);
-
- err = INFO_FORMAT_CHANGED;
- } else {
- *out = new MediaBuffer(0);
- err = OK;
- }
- break;
- }
-
- case AVC_NALTYPE_PPS:
- {
- mPPSSeen = true;
-
- res = PVAVCDecPicParamSet(
- mHandle, const_cast<uint8_t *>(fragPtr),
- fragSize);
-
- if (res != AVCDEC_SUCCESS) {
- LOGV("PVAVCDecPicParamSet returned error %d", res);
- break;
- }
-
- *out = new MediaBuffer(0);
-
- err = OK;
- break;
- }
-
- case AVC_NALTYPE_SLICE:
- case AVC_NALTYPE_IDR:
- {
- res = PVAVCDecodeSlice(
- mHandle, const_cast<uint8_t *>(fragPtr),
- fragSize);
-
- if (res == AVCDEC_PICTURE_OUTPUT_READY) {
- MediaBuffer *mbuf = drainOutputBuffer();
- if (mbuf == NULL) {
- break;
- }
-
- *out = mbuf;
-
- // Do _not_ release input buffer yet.
-
- releaseFragment = false;
- err = OK;
- break;
- }
-
- if (res == AVCDEC_PICTURE_READY || res == AVCDEC_SUCCESS) {
- *out = new MediaBuffer(0);
-
- err = OK;
- } else {
- LOGV("PVAVCDecodeSlice returned error %d", res);
- }
- break;
- }
-
- case AVC_NALTYPE_SEI:
- {
- res = PVAVCDecSEI(
- mHandle, const_cast<uint8_t *>(fragPtr),
- fragSize);
-
- if (res != AVCDEC_SUCCESS) {
- break;
- }
-
- *out = new MediaBuffer(0);
-
- err = OK;
- break;
- }
-
- case AVC_NALTYPE_AUD:
- case AVC_NALTYPE_FILL:
- case AVC_NALTYPE_EOSEQ:
- {
- *out = new MediaBuffer(0);
-
- err = OK;
- break;
- }
-
- default:
- {
- LOGE("Should not be here, unknown nalType %d", nalType);
- CHECK(!"Should not be here");
- break;
- }
- }
- } else {
- // We haven't seen SPS or PPS yet.
-
- *out = new MediaBuffer(0);
- err = OK;
- }
-
- if (releaseFragment) {
- size_t offset = mInputBuffer->range_offset();
- if (fragSize + 4 == mInputBuffer->range_length()) {
- mInputBuffer->release();
- mInputBuffer = NULL;
- } else {
- mInputBuffer->set_range(
- offset + fragSize + 4,
- mInputBuffer->range_length() - fragSize - 4);
- }
- }
-
- return err;
-}
-
-// static
-int32_t AVCDecoder::ActivateSPSWrapper(
- void *userData, unsigned int sizeInMbs, unsigned int numBuffers) {
- return static_cast<AVCDecoder *>(userData)->activateSPS(sizeInMbs, numBuffers);
-}
-
-// static
-int32_t AVCDecoder::BindFrameWrapper(
- void *userData, int32_t index, uint8_t **yuv) {
- return static_cast<AVCDecoder *>(userData)->bindFrame(index, yuv);
-}
-
-// static
-void AVCDecoder::UnbindFrame(void *userData, int32_t index) {
-}
-
-int32_t AVCDecoder::activateSPS(
- unsigned int sizeInMbs, unsigned int numBuffers) {
- CHECK(mFrames.isEmpty());
-
- size_t frameSize = (sizeInMbs << 7) * 3;
- for (unsigned int i = 0; i < numBuffers; ++i) {
- MediaBuffer *buffer = new MediaBuffer(frameSize);
- buffer->setObserver(this);
-
- mFrames.push(buffer);
- }
-
- return 1;
-}
-
-int32_t AVCDecoder::bindFrame(int32_t index, uint8_t **yuv) {
- CHECK(index >= 0);
- CHECK(index < (int32_t)mFrames.size());
-
- CHECK(mInputBuffer != NULL);
- int64_t timeUs;
- CHECK(mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs));
- mFrames[index]->meta_data()->setInt64(kKeyTime, timeUs);
-
- *yuv = (uint8_t *)mFrames[index]->data();
-
- return 1;
-}
-
-void AVCDecoder::releaseFrames() {
- for (size_t i = 0; i < mFrames.size(); ++i) {
- MediaBuffer *buffer = mFrames.editItemAt(i);
-
- buffer->setObserver(NULL);
- buffer->release();
- }
- mFrames.clear();
-}
-
-void AVCDecoder::signalBufferReturned(MediaBuffer *buffer) {
-}
-
-} // namespace android
diff --git a/media/libstagefright/codecs/avc/dec/Android.mk b/media/libstagefright/codecs/avc/dec/Android.mk
deleted file mode 100644
index 1b00347..0000000
--- a/media/libstagefright/codecs/avc/dec/Android.mk
+++ /dev/null
@@ -1,27 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
- AVCDecoder.cpp \
- src/avcdec_api.cpp \
- src/avc_bitstream.cpp \
- src/header.cpp \
- src/itrans.cpp \
- src/pred_inter.cpp \
- src/pred_intra.cpp \
- src/residual.cpp \
- src/slice.cpp \
- src/vlc.cpp
-
-LOCAL_MODULE := libstagefright_avcdec
-
-LOCAL_C_INCLUDES := \
- $(LOCAL_PATH)/src \
- $(LOCAL_PATH)/include \
- $(LOCAL_PATH)/../common/include \
- $(TOP)/frameworks/base/media/libstagefright/include \
- $(TOP)/frameworks/base/include/media/stagefright/openmax
-
-LOCAL_CFLAGS := -DOSCL_IMPORT_REF= -DOSCL_UNUSED_ARG= -DOSCL_EXPORT_REF=
-
-include $(BUILD_STATIC_LIBRARY)
diff --git a/media/libstagefright/codecs/avc/dec/include/avcdec_api.h b/media/libstagefright/codecs/avc/dec/include/avcdec_api.h
deleted file mode 100644
index f6a14b7..0000000
--- a/media/libstagefright/codecs/avc/dec/include/avcdec_api.h
+++ /dev/null
@@ -1,200 +0,0 @@
-/* ------------------------------------------------------------------
- * 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.
- * -------------------------------------------------------------------
- */
-/**
-This file contains application function interfaces to the AVC decoder library
-and necessary type defitionitions and enumerations.
-@publishedAll
-*/
-
-#ifndef _AVCDEC_API_H_
-#define _AVCDEC_API_H_
-
-#include "avcapi_common.h"
-
-/**
- This enumeration is used for the status returned from the library interface.
-*/
-typedef enum
-{
- /**
- The followings are fail with details. Their values are negative.
- */
- AVCDEC_NO_DATA = -4,
- AVCDEC_PACKET_LOSS = -3,
- /**
- Fail information
- */
- AVCDEC_NO_BUFFER = -2, /* no output picture buffer available */
- AVCDEC_MEMORY_FAIL = -1, /* memory allocation failed */
- AVCDEC_FAIL = 0,
- /**
- Generic success value
- */
- AVCDEC_SUCCESS = 1,
- AVCDEC_PICTURE_OUTPUT_READY = 2,
- AVCDEC_PICTURE_READY = 3,
-
- /**
- The followings are success with warnings. Their values are positive integers.
- */
- AVCDEC_NO_NEXT_SC = 4,
- AVCDEC_REDUNDANT_FRAME = 5,
- AVCDEC_CONCEALED_FRAME = 6 /* detect and conceal the error */
-} AVCDec_Status;
-
-
-/**
-This structure contains sequence parameters information.
-*/
-typedef struct tagAVCDecSPSInfo
-{
- int FrameWidth;
- int FrameHeight;
- uint frame_only_flag;
- int frame_crop_left;
- int frame_crop_right;
- int frame_crop_top;
- int frame_crop_bottom;
-
-} AVCDecSPSInfo;
-
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
- /** THE FOLLOWINGS ARE APIS */
- /**
- This function parses one NAL unit from byte stream format input according to Annex B.
- \param "bitstream" "Pointer to the bitstream buffer."
- \param "nal_unit" "Point to pointer and the location of the start of the first NAL unit
- found in bitstream."
- \param "size" "As input, the pointer to the size of bitstream in bytes. As output,
- the value is changed to be the size of the found NAL unit."
- \return "AVCDEC_SUCCESS if success, AVCDEC_FAIL if no first start code is found, AVCDEC_NO_NEX_SC if
- the first start code is found, but the second start code is missing (potential partial NAL)."
- */
- OSCL_IMPORT_REF AVCDec_Status PVAVCAnnexBGetNALUnit(uint8 *bitstream, uint8 **nal_unit, int *size);
-
- /**
- This function sniffs the nal_unit_type such that users can call corresponding APIs.
- \param "bitstream" "Pointer to the beginning of a NAL unit (start with forbidden_zero_bit, etc.)."
- \param "size" "size of the bitstream (NumBytesInNALunit + 1)."
- \param "nal_unit_type" "Pointer to the return value of nal unit type."
- \return "AVCDEC_SUCCESS if success, AVCDEC_FAIL otherwise."
- */
- OSCL_IMPORT_REF AVCDec_Status PVAVCDecGetNALType(uint8 *bitstream, int size, int *nal_type, int *nal_ref_idc);
-
- /**
- This function decodes the sequence parameters set, initializes related parameters and
- allocates memory (reference frames list), must also be compliant with Annex A.
- It is equivalent to decode VOL header of MPEG4.
- \param "avcHandle" "Handle to the AVC decoder library object."
- \param "nal_unit" "Pointer to the buffer containing single NAL unit.
- The content will change due to EBSP-to-RBSP conversion."
- \param "nal_size" "size of the bitstream NumBytesInNALunit."
- \return "AVCDEC_SUCCESS if success,
- AVCDEC_FAIL if profile and level is not supported,
- AVCDEC_MEMORY_FAIL if memory allocations return null."
- */
- OSCL_IMPORT_REF AVCDec_Status PVAVCDecSeqParamSet(AVCHandle *avcHandle, uint8 *nal_unit, int nal_size);
-
- /**
- This function returns sequence parameters such as dimension and field flag of the most recently
- decoded SPS. More can be added later or grouped together into a structure. This API can be called
- after PVAVCInitSequence. If no sequence parameter has been decoded yet, it will return AVCDEC_FAIL.
-
- \param "avcHandle" "Handle to the AVC decoder library object."
- \param "seqInfo" "Pointer to the AVCDecSeqParamInfo structure."
- \return "AVCDEC_SUCCESS if success and AVCDEC_FAIL if fail."
- \note "This API can be combined with PVAVCInitSequence if wanted to be consistent with m4vdec lib."
- */
- OSCL_IMPORT_REF AVCDec_Status PVAVCDecGetSeqInfo(AVCHandle *avcHandle, AVCDecSPSInfo *seqInfo);
-
- /**
- This function decodes the picture parameters set and initializes related parameters. Note thate
- the PPS may not be present for every picture.
- \param "avcHandle" "Handle to the AVC decoder library object."
- \param "nal_unit" "Pointer to the buffer containing single NAL unit.
- The content will change due to EBSP-to-RBSP conversion."
- \param "nal_size" "size of the bitstream NumBytesInNALunit."
- \return "AVCDEC_SUCCESS if success, AVCDEC_FAIL if profile and level is not supported."
- */
- OSCL_IMPORT_REF AVCDec_Status PVAVCDecPicParamSet(AVCHandle *avcHandle, uint8 *nal_unit, int nal_size);
-
- /**
- This function decodes one NAL unit of bitstream. The type of nal unit is one of the
- followings, 1, 5. (for now, no data partitioning, type 2,3,4).
- \param "avcHandle" "Handle to the AVC decoder library object."
- \param "nal_unit" "Pointer to the buffer containing a single or partial NAL unit.
- The content will change due to EBSP-to-RBSP conversion."
- \param "buf_size" "Size of the buffer (less than or equal nal_size)."
- \param "nal_size" "size of the current NAL unit NumBytesInNALunit."
- \return "AVCDEC_PICTURE_READY for success and an output is ready,
- AVCDEC_SUCCESS for success but no output is ready,
- AVCDEC_PACKET_LOSS is GetData returns AVCDEC_PACKET_LOSS,
- AVCDEC_FAIL if syntax error is detected,
- AVCDEC_MEMORY_FAIL if memory is corrupted.
- AVCDEC_NO_PICTURE if no frame memory to write to (users need to get output and/or return picture).
- AVCDEC_REDUNDANT_PICTURE if error has been detected in the primary picture and redundant picture is available,
- AVCDEC_CONCEALED_PICTURE if error has been detected and decoder has concealed it."
- */
- OSCL_IMPORT_REF AVCDec_Status PVAVCDecSEI(AVCHandle *avcHandle, uint8 *nal_unit, int nal_size);
-
- OSCL_IMPORT_REF AVCDec_Status PVAVCDecodeSlice(AVCHandle *avcHandle, uint8 *buffer, int buf_size);
-
- /**
- Check the availability of the decoded picture in decoding order (frame_num).
- The AVCFrameIO also provide displaying order information such that the application
- can re-order the frame for display. A picture can be retrieved only once.
- \param "avcHandle" "Handle to the AVC decoder library object."
- \param "output" "Pointer to the AVCOutput structure. Note that decoder library will
- not re-used the pixel memory in this structure until it has been returned
- thru PVAVCReleaseOutput API."
- \return "AVCDEC_SUCCESS for success, AVCDEC_FAIL if no picture is available to be displayed,
- AVCDEC_PICTURE_READY if there is another picture to be displayed."
- */
- OSCL_IMPORT_REF AVCDec_Status PVAVCDecGetOutput(AVCHandle *avcHandle, int *indx, int *release_flag, AVCFrameIO *output);
-
- /**
- This function resets the decoder and expects to see the next IDR slice.
- \param "avcHandle" "Handle to the AVC decoder library object."
- */
- OSCL_IMPORT_REF void PVAVCDecReset(AVCHandle *avcHandle);
-
- /**
- This function performs clean up operation including memory deallocation.
- \param "avcHandle" "Handle to the AVC decoder library object."
- */
- OSCL_IMPORT_REF void PVAVCCleanUpDecoder(AVCHandle *avcHandle);
-//AVCDec_Status EBSPtoRBSP(uint8 *nal_unit,int *size);
-
-
-
- /** CALLBACK FUNCTION TO BE IMPLEMENTED BY APPLICATION */
- /** In AVCHandle structure, userData is a pointer to an object with the following
- member functions.
- */
- AVCDec_Status CBAVCDec_GetData(uint32 *userData, unsigned char **buffer, unsigned int *size);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _AVCDEC_API_H_ */
-
diff --git a/media/libstagefright/codecs/avc/dec/include/pvavcdecoder.h b/media/libstagefright/codecs/avc/dec/include/pvavcdecoder.h
deleted file mode 100644
index 6b196de..0000000
--- a/media/libstagefright/codecs/avc/dec/include/pvavcdecoder.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* ------------------------------------------------------------------
- * 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 PVAVCDECODER_H_INCLUDED
-#define PVAVCDECODER_H_INCLUDED
-
-#ifndef PVAVCDECODERINTERFACE_H_INCLUDED
-#include "pvavcdecoderinterface.h"
-#endif
-
-// AVC video decoder
-class PVAVCDecoder : public PVAVCDecoderInterface
-{
- public:
- virtual ~PVAVCDecoder();
- static PVAVCDecoder* New(void);
- virtual bool InitAVCDecoder(FunctionType_SPS, FunctionType_Alloc, FunctionType_Unbind,
- FunctionType_Malloc, FunctionType_Free, void *);
- virtual void CleanUpAVCDecoder(void);
- virtual void ResetAVCDecoder(void);
- virtual int32 DecodeSPS(uint8 *bitstream, int32 buffer_size);
- virtual int32 DecodePPS(uint8 *bitstream, int32 buffer_size);
- virtual int32 DecodeAVCSlice(uint8 *bitstream, int32 *buffer_size);
- virtual bool GetDecOutput(int *indx, int *release);
- virtual void GetVideoDimensions(int32 *width, int32 *height, int32 *top, int32 *left, int32 *bottom, int32 *right);
- int AVC_Malloc(int32 size, int attribute);
- void AVC_Free(int mem);
-
- private:
- PVAVCDecoder();
- bool Construct(void);
- void *iAVCHandle;
-};
-
-#endif
diff --git a/media/libstagefright/codecs/avc/dec/include/pvavcdecoderinterface.h b/media/libstagefright/codecs/avc/dec/include/pvavcdecoderinterface.h
deleted file mode 100644
index 027212d..0000000
--- a/media/libstagefright/codecs/avc/dec/include/pvavcdecoderinterface.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* ------------------------------------------------------------------
- * 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 PVAVCDECODERINTERFACE_H_INCLUDED
-#define PVAVCDECODERINTERFACE_H_INCLUDED
-
-typedef void (*FunctionType_Unbind)(void *, int);
-typedef int (*FunctionType_Alloc)(void *, int, uint8 **);
-typedef int (*FunctionType_SPS)(void *, uint, uint);
-typedef int (*FunctionType_Malloc)(void *, int32, int);
-typedef void(*FunctionType_Free)(void *, int);
-
-
-// PVAVCDecoderInterface pure virtual interface class
-class PVAVCDecoderInterface
-{
- public:
- virtual ~PVAVCDecoderInterface() {};
- virtual bool InitAVCDecoder(FunctionType_SPS, FunctionType_Alloc, FunctionType_Unbind,
- FunctionType_Malloc, FunctionType_Free, void *) = 0;
- virtual void CleanUpAVCDecoder(void) = 0;
- virtual void ResetAVCDecoder(void) = 0;
- virtual int32 DecodeSPS(uint8 *bitstream, int32 buffer_size) = 0;
- virtual int32 DecodePPS(uint8 *bitstream, int32 buffer_size) = 0;
- virtual int32 DecodeAVCSlice(uint8 *bitstream, int32 *buffer_size) = 0;
- virtual bool GetDecOutput(int *indx, int *release) = 0;
- virtual void GetVideoDimensions(int32 *width, int32 *height, int32 *top, int32 *left, int32 *bottom, int32 *right) = 0;
-// virtual int AVC_Malloc(int32 size, int attribute);
-// virtual void AVC_Free(int mem);
-};
-
-#endif // PVAVCDECODERINTERFACE_H_INCLUDED
-
-
diff --git a/media/libstagefright/codecs/avc/dec/src/avc_bitstream.cpp b/media/libstagefright/codecs/avc/dec/src/avc_bitstream.cpp
deleted file mode 100644
index 270b664..0000000
--- a/media/libstagefright/codecs/avc/dec/src/avc_bitstream.cpp
+++ /dev/null
@@ -1,276 +0,0 @@
-/* ------------------------------------------------------------------
- * 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 "avcdec_bitstream.h"
-
-/* Swapping may not be needed anymore since we read one byte at a time and perform
-EBSP to RBSP conversion in bitstream. */
-#ifdef LITTLE_ENDIAN
-#if (WORD_SIZE==32) /* this can be replaced with assembly instructions */
-#define SWAP_BYTES(x) ((((x)&0xFF)<<24) | (((x)&0xFF00)<<8) | (((x)&0xFF0000)>>8) | (((x)&0xFF000000)>>24))
-#else /* for 16-bit */
-#define SWAP_BYTES(x) ((((x)&0xFF)<<8) | (((x)&0xFF00)>>8))
-#endif
-#else
-#define SWAP_BYTES(x) (x)
-#endif
-
-
-/* array for trailing bit pattern as function of number of bits */
-/* the first one is unused. */
-const static uint8 trailing_bits[9] = {0, 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80};
-
-/* ======================================================================== */
-/* Function : BitstreamInit() */
-/* Date : 11/4/2003 */
-/* Purpose : Populate bitstream structure with bitstream buffer and size */
-/* it also initializes internal data */
-/* In/out : */
-/* Return : AVCDEC_SUCCESS if successed, AVCDEC_FAIL if failed. */
-/* Modified : */
-/* ======================================================================== */
-/* |--------|--------|----~~~~~-----|---------|---------|---------|
- ^ ^read_pos ^data_end_pos
- bitstreamBuffer <--------->
- current_word
-
- |xxxxxxxxxxxxx----| = current_word 32 or 16 bits
- <------------>
- bit_left
- ======================================================================== */
-
-
-/* ======================================================================== */
-/* Function : BitstreamNextWord() */
-/* Date : 12/4/2003 */
-/* Purpose : Read up to machine word. */
-/* In/out : */
-/* Return : Next word with emulation prevention code removed. Everything
- in the bitstream structure got modified except current_word */
-/* Modified : */
-/* ======================================================================== */
-
-AVCDec_Status BitstreamInit(AVCDecBitstream *stream, uint8 *buffer, int size)
-{
- EBSPtoRBSP(buffer, &size);
-
- stream->incnt = 0;
- stream->incnt_next = 0;
- stream->bitcnt = 0;
- stream->curr_word = stream->next_word = 0;
- stream->read_pos = 0;
-
- stream->bitstreamBuffer = buffer;
-
- stream->data_end_pos = size;
-
- stream->nal_size = size;
-
- return AVCDEC_SUCCESS;
-}
-/* ======================================================================== */
-/* Function : AVC_BitstreamFillCache() */
-/* Date : 1/1/2005 */
-/* Purpose : Read up to machine word. */
-/* In/out : */
-/* Return : Read in 4 bytes of input data */
-/* Modified : */
-/* ======================================================================== */
-
-AVCDec_Status AVC_BitstreamFillCache(AVCDecBitstream *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 AVCDEC_SUCCESS;
- }
- /* this check can be removed if there is additional extra 4 bytes at the end of the bitstream */
- v = bitstreamBuffer + stream->read_pos;
-
- if (stream->read_pos > stream->data_end_pos - 4)
- {
- if (stream->data_end_pos <= stream->read_pos)
- {
- stream->incnt = num_bits;
- stream->incnt_next = 0;
- return AVCDEC_SUCCESS;
- }
-
- stream->next_word = 0;
-
- for (i = 0; i < stream->data_end_pos - stream->read_pos; i++)
- {
- stream->next_word |= (v[i] << ((3 - i) << 3));
- }
-
- stream->read_pos = 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 AVCDEC_SUCCESS;
- }
-
- stream->next_word = ((uint32)v[0] << 24) | (v[1] << 16) | (v[2] << 8) | v[3];
- stream->read_pos += 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 AVCDEC_SUCCESS;
-
-}
-/* ======================================================================== */
-/* Function : BitstreamReadBits() */
-/* Date : 11/4/2003 */
-/* Purpose : Read up to machine word. */
-/* In/out : */
-/* Return : AVCDEC_SUCCESS if successed, AVCDEC_FAIL if number of bits */
-/* is greater than the word-size, AVCDEC_PACKET_LOSS or */
-/* AVCDEC_NO_DATA if callback to get data fails. */
-/* Modified : */
-/* ======================================================================== */
-AVCDec_Status BitstreamReadBits(AVCDecBitstream *stream, int nBits, uint *code)
-{
- if (stream->incnt < nBits)
- {
- /* frame-based decoding */
- AVC_BitstreamFillCache(stream);
- }
- *code = stream->curr_word >> (32 - nBits);
- BitstreamFlushBits(stream, nBits);
- return AVCDEC_SUCCESS;
-}
-
-
-
-/* ======================================================================== */
-/* Function : BitstreamShowBits() */
-/* Date : 11/4/2003 */
-/* Purpose : Show up to machine word without advancing the pointer. */
-/* In/out : */
-/* Return : AVCDEC_SUCCESS if successed, AVCDEC_FAIL if number of bits */
-/* is greater than the word-size, AVCDEC_NO_DATA if it needs */
-/* to callback to get data. */
-/* Modified : */
-/* ======================================================================== */
-AVCDec_Status BitstreamShowBits(AVCDecBitstream *stream, int nBits, uint *code)
-{
- if (stream->incnt < nBits)
- {
- /* frame-based decoding */
- AVC_BitstreamFillCache(stream);
- }
-
- *code = stream->curr_word >> (32 - nBits);
-
- return AVCDEC_SUCCESS;
-}
-
-/* ======================================================================== */
-/* Function : BitstreamRead1Bit() */
-/* Date : 11/4/2003 */
-/* Purpose : Read 1 bit from the bitstream. */
-/* In/out : */
-/* Return : AVCDEC_SUCCESS if successed, AVCDEC_FAIL if number of bits */
-/* is greater than the word-size, AVCDEC_PACKET_LOSS or */
-/* AVCDEC_NO_DATA if callback to get data fails. */
-/* Modified : */
-/* ======================================================================== */
-
-AVCDec_Status BitstreamRead1Bit(AVCDecBitstream *stream, uint *code)
-{
- if (stream->incnt < 1)
- {
- /* frame-based decoding */
- AVC_BitstreamFillCache(stream);
- }
- *code = stream->curr_word >> 31;
- BitstreamFlushBits(stream, 1);
- return AVCDEC_SUCCESS;
-}
-
-
-
-AVCDec_Status BitstreamByteAlign(AVCDecBitstream *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 AVCDEC_SUCCESS;
-}
-
-/* check whether there are more RBSP data. */
-/* ignore the emulation prevention code, assume it has been taken out. */
-bool more_rbsp_data(AVCDecBitstream *stream)
-{
- int total_bit_left;
- uint code;
-
- if (stream->read_pos >= stream->nal_size)
- {
- total_bit_left = stream->incnt_next + stream->incnt;
- if (total_bit_left <= 0)
- {
- return FALSE;
- }
- else if (total_bit_left <= 8)
- {
- BitstreamShowBits(stream, total_bit_left, &code);
- if (code == trailing_bits[total_bit_left])
- {
- return FALSE;
- }
- }
- }
-
- return TRUE;
-}
-
diff --git a/media/libstagefright/codecs/avc/dec/src/avcdec_api.cpp b/media/libstagefright/codecs/avc/dec/src/avcdec_api.cpp
deleted file mode 100644
index 0a75f17..0000000
--- a/media/libstagefright/codecs/avc/dec/src/avcdec_api.cpp
+++ /dev/null
@@ -1,1036 +0,0 @@
-/* ------------------------------------------------------------------
- * 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.
- * -------------------------------------------------------------------
- */
-/**
-This file contains application function interfaces to the AVC decoder library.
-@publishedAll
-*/
-
-#include <string.h>
-
-#include "avcdec_api.h"
-#include "avcdec_lib.h"
-#include "avcdec_bitstream.h"
-
-/* ======================================================================== */
-/* Function : EBSPtoRBSP() */
-/* Date : 11/4/2003 */
-/* Purpose : Convert EBSP to RBSP and overwrite it. */
-/* Assuming that forbidden_zero, nal_ref_idc and nal_unit_type */
-/* (first byte), has been taken out of the nal_unit. */
-/* In/out : */
-/* Return : */
-/* Modified : */
-/* ======================================================================== */
-/**
-@pseudocode "
- NumBytesInRBSP = 0;
- for(i=0:i< *size; i++){
- if(i+2 < *size && next_bits(24)==0x000003){
- rbsp_byte[NumBytesInRBSP++];
- rbsp_byte[NumBytesInRBSP++];
- i+=2;
- emulation_prevention_three_byte (0x03)
- }
- else
- rbsp_byte[NumBytesInRBSP++];
- }"
-*/
-AVCDec_Status EBSPtoRBSP(uint8 *nal_unit, int *size)
-{
- int i, j;
- int count = 0;
-
- /* This code is based on EBSPtoRBSP of JM */
- j = 0;
-
- for (i = 0; i < *size; i++)
- {
- if (count == 2 && nal_unit[i] == 0x03)
- {
- i++;
- count = 0;
- }
- nal_unit[j] = nal_unit[i];
- if (nal_unit[i] == 0x00)
- count++;
- else
- count = 0;
- j++;
- }
-
- *size = j;
-
- return AVCDEC_SUCCESS;
-}
-
-/* ======================================================================== */
-/* Function : PVAVCAnnexBGetNALUnit() */
-/* Date : 11/3/2003 */
-/* Purpose : Parse a NAL from byte stream format. */
-/* In/out : */
-/* Return : AVCDEC_SUCCESS if succeed, AVC_FAIL if fail. */
-/* Modified : */
-/* ======================================================================== */
-/**
-@pseudocode "
- byte_stream_nal_unit(NumBytesInNalunit){
- while(next_bits(24) != 0x000001)
- zero_byte
- if(more_data_in_byte_stream()){
- start_code_prefix_one_3bytes // equal 0x000001
- nal_unit(NumBytesInNALunit)
- }
- }"
-*/
-OSCL_EXPORT_REF AVCDec_Status PVAVCAnnexBGetNALUnit(uint8 *bitstream, uint8 **nal_unit,
- int *size)
-{
- int i, j, FoundStartCode = 0;
- int end;
-
- i = 0;
- while (bitstream[i] == 0 && i < *size)
- {
- i++;
- }
- if (i >= *size)
- {
- *nal_unit = bitstream;
- return AVCDEC_FAIL; /* cannot find any start_code_prefix. */
- }
- else if (bitstream[i] != 0x1)
- {
- i = -1; /* start_code_prefix is not at the beginning, continue */
- }
-
- i++;
- *nal_unit = bitstream + i; /* point to the beginning of the NAL unit */
-
- j = end = i;
- while (!FoundStartCode)
- {
- while ((j + 1 < *size) && (bitstream[j] != 0 || bitstream[j+1] != 0)) /* see 2 consecutive zero bytes */
- {
- j++;
- }
- end = j; /* stop and check for start code */
- while (j + 2 < *size && bitstream[j+2] == 0) /* keep reading for zero byte */
- {
- j++;
- }
- if (j + 2 >= *size)
- {
- *size -= i;
- return AVCDEC_NO_NEXT_SC; /* cannot find the second start_code_prefix */
- }
- if (bitstream[j+2] == 0x1)
- {
- FoundStartCode = 1;
- }
- else
- {
- /* could be emulation code 0x3 */
- j += 2; /* continue the search */
- }
- }
-
- *size = end - i;
-
- return AVCDEC_SUCCESS;
-}
-
-/* ======================================================================== */
-/* Function : PVAVCGetNALType() */
-/* Date : 11/4/2003 */
-/* Purpose : Sniff NAL type from the bitstream */
-/* In/out : */
-/* Return : AVCDEC_SUCCESS if succeed, AVC_FAIL if fail. */
-/* Modified : */
-/* ======================================================================== */
-OSCL_EXPORT_REF AVCDec_Status PVAVCDecGetNALType(uint8 *bitstream, int size,
- int *nal_type, int *nal_ref_idc)
-{
- int forbidden_zero_bit;
- if (size > 0)
- {
- forbidden_zero_bit = bitstream[0] >> 7;
- if (forbidden_zero_bit != 0)
- return AVCDEC_FAIL;
- *nal_ref_idc = (bitstream[0] & 0x60) >> 5;
- *nal_type = bitstream[0] & 0x1F;
- return AVCDEC_SUCCESS;
- }
-
- return AVCDEC_FAIL;
-}
-
-/* ======================================================================== */
-/* Function : PVAVCDecSeqParamSet() */
-/* Date : 11/4/2003 */
-/* Purpose : Initialize sequence, memory allocation if necessary. */
-/* In/out : */
-/* Return : AVCDEC_SUCCESS if succeed, AVC_FAIL if fail. */
-/* Modified : */
-/* ======================================================================== */
-
-OSCL_EXPORT_REF AVCDec_Status PVAVCDecSeqParamSet(AVCHandle *avcHandle, uint8 *nal_unit,
- int nal_size)
-{
- AVCDec_Status status;
- AVCDecObject *decvid;
- AVCCommonObj *video;
- AVCDecBitstream *bitstream;
- void *userData = avcHandle->userData;
- bool first_seq = FALSE;
- int i;
-
-
- DEBUG_LOG(userData, AVC_LOGTYPE_INFO, "PVAVCDecSeqParamSet", -1, -1);
-
- if (avcHandle->AVCObject == NULL)
- {
- first_seq = TRUE;
-
- //avcHandle->memory_usage = 0;
- /* allocate AVCDecObject */
- avcHandle->AVCObject = (void*)avcHandle->CBAVC_Malloc(userData, sizeof(AVCDecObject), 0/*DEFAULT_ATTR*/);
- if (avcHandle->AVCObject == NULL)
- {
- return AVCDEC_MEMORY_FAIL;
- }
-
- decvid = (AVCDecObject*) avcHandle->AVCObject;
-
- memset(decvid, 0, sizeof(AVCDecObject));
-
- decvid->common = (AVCCommonObj*)avcHandle->CBAVC_Malloc(userData, sizeof(AVCCommonObj), 0);
- if (decvid->common == NULL)
- {
- return AVCDEC_MEMORY_FAIL;
- }
-
- video = decvid->common;
- memset(video, 0, sizeof(AVCCommonObj));
-
- video->seq_parameter_set_id = 9999; /* set it to some illegal value */
-
- decvid->bitstream = (AVCDecBitstream *) avcHandle->CBAVC_Malloc(userData, sizeof(AVCDecBitstream), 1/*DEFAULT_ATTR*/);
- if (decvid->bitstream == NULL)
- {
- return AVCDEC_MEMORY_FAIL;
- }
-
- decvid->bitstream->userData = avcHandle->userData; /* callback for more data */
- decvid->avcHandle = avcHandle;
- decvid->debugEnable = avcHandle->debugEnable;
- }
-
- decvid = (AVCDecObject*) avcHandle->AVCObject;
- video = decvid->common;
- bitstream = decvid->bitstream;
-
- /* check if we can reuse the memory without re-allocating it. */
- /* always check if(first_seq==TRUE) */
-
- /* Conversion from EBSP to RBSP */
- video->forbidden_bit = nal_unit[0] >> 7;
- if (video->forbidden_bit) return AVCDEC_FAIL;
- video->nal_ref_idc = (nal_unit[0] & 0x60) >> 5;
- video->nal_unit_type = (AVCNalUnitType)(nal_unit[0] & 0x1F);
-
- if (video->nal_unit_type != AVC_NALTYPE_SPS) /* not a SPS NAL */
- {
- return AVCDEC_FAIL;
- }
-
- /* Initialize bitstream structure*/
- BitstreamInit(bitstream, nal_unit + 1, nal_size - 1);
-
- /* if first_seq == TRUE, allocate the following memory */
- if (first_seq == TRUE)
- {
- video->currSeqParams = NULL; /* initialize it to NULL */
- video->currPicParams = NULL;
-
- /* There are 32 pointers to sequence param set, seqParams.
- There are 255 pointers to picture param set, picParams.*/
- for (i = 0; i < 32; i++)
- decvid->seqParams[i] = NULL;
-
- for (i = 0; i < 256; i++)
- decvid->picParams[i] = NULL;
-
- video->MbToSliceGroupMap = NULL;
-
- video->mem_mgr_ctrl_eq_5 = FALSE;
- video->newPic = TRUE;
- video->newSlice = TRUE;
- video->currPic = NULL;
- video->currFS = NULL;
- video->prevRefPic = NULL;
-
- video->mbNum = 0; // MC_Conceal
- /* Allocate sliceHdr. */
-
- video->sliceHdr = (AVCSliceHeader*) avcHandle->CBAVC_Malloc(userData, sizeof(AVCSliceHeader), 5/*DEFAULT_ATTR*/);
- if (video->sliceHdr == NULL)
- {
- return AVCDEC_MEMORY_FAIL;
- }
-
- video->decPicBuf = (AVCDecPicBuffer*) avcHandle->CBAVC_Malloc(userData, sizeof(AVCDecPicBuffer), 3/*DEFAULT_ATTR*/);
- if (video->decPicBuf == NULL)
- {
- return AVCDEC_MEMORY_FAIL;
- }
- memset(video->decPicBuf, 0, sizeof(AVCDecPicBuffer));
- }
-
- /* Decode SPS, allocate video->seqParams[i] and assign video->currSeqParams */
- status = DecodeSPS(decvid, bitstream);
-
- if (status != AVCDEC_SUCCESS)
- {
- return status;
- }
- return AVCDEC_SUCCESS;
-}
-
-/* ======================================================================== */
-/* Function : PVAVCDecGetSeqInfo() */
-/* Date : 11/4/2003 */
-/* Purpose : Get sequence parameter info. after SPS NAL is decoded. */
-/* In/out : */
-/* Return : AVCDEC_SUCCESS if succeed, AVC_FAIL if fail. */
-/* Modified : */
-/* 12/20/03: change input argument, use structure instead. */
-/* ======================================================================== */
-
-OSCL_EXPORT_REF AVCDec_Status PVAVCDecGetSeqInfo(AVCHandle *avcHandle, AVCDecSPSInfo *seqInfo)
-{
- AVCDecObject *decvid = (AVCDecObject*) avcHandle->AVCObject;
- AVCCommonObj *video;
- int PicWidthInMbs, PicHeightInMapUnits, FrameHeightInMbs;
-
- if (decvid == NULL || decvid->seqParams[0] == NULL)
- {
- return AVCDEC_FAIL;
- }
-
- video = decvid->common;
-
- PicWidthInMbs = decvid->seqParams[0]->pic_width_in_mbs_minus1 + 1;
- PicHeightInMapUnits = decvid->seqParams[0]->pic_height_in_map_units_minus1 + 1 ;
- FrameHeightInMbs = (2 - decvid->seqParams[0]->frame_mbs_only_flag) * PicHeightInMapUnits ;
-
- seqInfo->FrameWidth = PicWidthInMbs << 4;
- seqInfo->FrameHeight = FrameHeightInMbs << 4;
-
- seqInfo->frame_only_flag = decvid->seqParams[0]->frame_mbs_only_flag;
-
- if (decvid->seqParams[0]->frame_cropping_flag)
- {
- seqInfo->frame_crop_left = 2 * decvid->seqParams[0]->frame_crop_left_offset;
- seqInfo->frame_crop_right = seqInfo->FrameWidth - (2 * decvid->seqParams[0]->frame_crop_right_offset + 1);
-
- if (seqInfo->frame_only_flag)
- {
- seqInfo->frame_crop_top = 2 * decvid->seqParams[0]->frame_crop_top_offset;
- seqInfo->frame_crop_bottom = seqInfo->FrameHeight - (2 * decvid->seqParams[0]->frame_crop_bottom_offset + 1);
- /* Note in 7.4.2.1, there is a contraint on the value of frame_crop_left and frame_crop_top
- such that they have to be less than or equal to frame_crop_right/2 and frame_crop_bottom/2, respectively. */
- }
- else
- {
- seqInfo->frame_crop_top = 4 * decvid->seqParams[0]->frame_crop_top_offset;
- seqInfo->frame_crop_bottom = seqInfo->FrameHeight - (4 * decvid->seqParams[0]->frame_crop_bottom_offset + 1);
- /* Note in 7.4.2.1, there is a contraint on the value of frame_crop_left and frame_crop_top
- such that they have to be less than or equal to frame_crop_right/2 and frame_crop_bottom/4, respectively. */
- }
- }
- else /* no cropping flag, just give the first and last pixel */
- {
- seqInfo->frame_crop_bottom = seqInfo->FrameHeight - 1;
- seqInfo->frame_crop_right = seqInfo->FrameWidth - 1;
- seqInfo->frame_crop_top = seqInfo->frame_crop_left = 0;
- }
-
- return AVCDEC_SUCCESS;
-}
-
-/* ======================================================================== */
-/* Function : PVAVCDecPicParamSet() */
-/* Date : 11/4/2003 */
-/* Purpose : Initialize picture */
-/* create reference picture list. */
-/* In/out : */
-/* Return : AVCDEC_SUCCESS if succeed, AVC_FAIL if fail. */
-/* Modified : */
-/* ======================================================================== */
-/**
-Since PPS doesn't contain much data, most of the picture initialization will
-be done after decoding the slice header in PVAVCDecodeSlice. */
-OSCL_EXPORT_REF AVCDec_Status PVAVCDecPicParamSet(AVCHandle *avcHandle, uint8 *nal_unit,
- int nal_size)
-{
- AVCDec_Status status;
- AVCDecObject *decvid = (AVCDecObject*) avcHandle->AVCObject;
- AVCCommonObj *video;
- AVCDecBitstream *bitstream;
-
- if (decvid == NULL)
- {
- return AVCDEC_FAIL;
- }
-
- video = decvid->common;
- bitstream = decvid->bitstream;
- /* 1. Convert EBSP to RBSP. Create bitstream structure */
- video->forbidden_bit = nal_unit[0] >> 7;
- video->nal_ref_idc = (nal_unit[0] & 0x60) >> 5;
- video->nal_unit_type = (AVCNalUnitType)(nal_unit[0] & 0x1F);
-
- if (video->nal_unit_type != AVC_NALTYPE_PPS) /* not a PPS NAL */
- {
- return AVCDEC_FAIL;
- }
-
-
- /* 2. Initialize bitstream structure*/
- BitstreamInit(bitstream, nal_unit + 1, nal_size - 1);
-
- /* 2. Decode pic_parameter_set_rbsp syntax. Allocate video->picParams[i] and assign to currPicParams */
- status = DecodePPS(decvid, video, bitstream);
- if (status != AVCDEC_SUCCESS)
- {
- return status;
- }
-
- video->SliceGroupChangeRate = video->currPicParams->slice_group_change_rate_minus1 + 1 ;
-
- return AVCDEC_SUCCESS;
-}
-
-OSCL_EXPORT_REF AVCDec_Status PVAVCDecSEI(AVCHandle *avcHandle, uint8 *nal_unit,
- int nal_size)
-{
- OSCL_UNUSED_ARG(avcHandle);
- OSCL_UNUSED_ARG(nal_unit);
- OSCL_UNUSED_ARG(nal_size);
-
- return AVCDEC_SUCCESS;
-}
-/* ======================================================================== */
-/* Function : PVAVCDecodeSlice() */
-/* Date : 11/4/2003 */
-/* Purpose : Decode one NAL unit. */
-/* In/out : */
-/* Return : See enum AVCDec_Status for return values. */
-/* Modified : */
-/* ======================================================================== */
-OSCL_EXPORT_REF AVCDec_Status PVAVCDecodeSlice(AVCHandle *avcHandle, uint8 *buffer,
- int buf_size)
-{
- AVCDecObject *decvid = (AVCDecObject*) avcHandle->AVCObject;
- AVCCommonObj *video;
- AVCDecBitstream *bitstream;
- AVCDec_Status status;
-
- if (decvid == NULL)
- {
- return AVCDEC_FAIL;
- }
-
- video = decvid->common;
- bitstream = decvid->bitstream;
-
- if (video->mem_mgr_ctrl_eq_5)
- {
- return AVCDEC_PICTURE_OUTPUT_READY; // to flushout frame buffers
- }
-
- if (video->newSlice)
- {
- /* 2. Check NAL type */
- if (buffer == NULL)
- {
- return AVCDEC_FAIL;
- }
- video->prev_nal_unit_type = video->nal_unit_type;
- video->forbidden_bit = buffer[0] >> 7;
- video->nal_ref_idc = (buffer[0] & 0x60) >> 5;
- video->nal_unit_type = (AVCNalUnitType)(buffer[0] & 0x1F);
-
-
- if (video->nal_unit_type == AVC_NALTYPE_AUD)
- {
- return AVCDEC_SUCCESS;
- }
-
- if (video->nal_unit_type != AVC_NALTYPE_SLICE &&
- video->nal_unit_type != AVC_NALTYPE_IDR)
- {
- return AVCDEC_FAIL; /* not supported */
- }
-
-
-
- if (video->nal_unit_type >= 2 && video->nal_unit_type <= 4)
- {
- return AVCDEC_FAIL; /* not supported */
- }
- else
- {
- video->slice_data_partitioning = FALSE;
- }
-
- video->newSlice = FALSE;
- /* Initialize bitstream structure*/
- BitstreamInit(bitstream, buffer + 1, buf_size - 1);
-
-
- /* 2.1 Decode Slice Header (separate function)*/
- status = DecodeSliceHeader(decvid, video, bitstream);
- if (status != AVCDEC_SUCCESS)
- {
- video->newSlice = TRUE;
- return status;
- }
-
- if (video->sliceHdr->frame_num != video->prevFrameNum || (video->sliceHdr->first_mb_in_slice < (uint)video->mbNum && video->currSeqParams->constrained_set1_flag == 1))
- {
- video->newPic = TRUE;
- if (video->numMBs > 0)
- {
- // Conceal missing MBs of previously decoded frame
- ConcealSlice(decvid, video->PicSizeInMbs - video->numMBs, video->PicSizeInMbs); // Conceal
- video->numMBs = 0;
-
- // DeblockPicture(video); // No need to deblock
-
- /* 3.2 Decoded frame reference marking. */
- /* 3.3 Put the decoded picture in output buffers */
- /* set video->mem_mge_ctrl_eq_5 */
- AVCNalUnitType temp = video->nal_unit_type;
- video->nal_unit_type = video->prev_nal_unit_type;
- StorePictureInDPB(avcHandle, video);
- video->nal_unit_type = temp;
- video->mbNum = 0; // MC_Conceal
- return AVCDEC_PICTURE_OUTPUT_READY;
- }
- }
-
- if (video->nal_unit_type == AVC_NALTYPE_IDR)
- {
- video->prevFrameNum = 0;
- video->PrevRefFrameNum = 0;
- }
-
- if (!video->currSeqParams->gaps_in_frame_num_value_allowed_flag)
- { /* no gaps allowed, frame_num has to increase by one only */
- /* if(sliceHdr->frame_num != (video->PrevRefFrameNum + 1)%video->MaxFrameNum) */
- if (video->sliceHdr->frame_num != video->PrevRefFrameNum && video->sliceHdr->frame_num != (video->PrevRefFrameNum + 1) % video->MaxFrameNum)
- {
- // Conceal missing MBs of previously decoded frame
- video->numMBs = 0;
- video->newPic = TRUE;
- video->prevFrameNum++; // FIX
- video->PrevRefFrameNum++;
- AVCNalUnitType temp = video->nal_unit_type;
- video->nal_unit_type = AVC_NALTYPE_SLICE; //video->prev_nal_unit_type;
- status = (AVCDec_Status)DPBInitBuffer(avcHandle, video);
- if (status != AVCDEC_SUCCESS)
- {
- return status;
- }
- video->currFS->IsOutputted = 0x01;
- video->currFS->IsReference = 3;
- video->currFS->IsLongTerm = 0;
-
- DecodePOC(video);
- /* find an empty memory from DPB and assigned to currPic */
- DPBInitPic(video, video->PrevRefFrameNum % video->MaxFrameNum);
- RefListInit(video);
- ConcealSlice(decvid, 0, video->PicSizeInMbs); // Conceal
- video->currFS->IsOutputted |= 0x02;
- //conceal frame
- /* 3.2 Decoded frame reference marking. */
- /* 3.3 Put the decoded picture in output buffers */
- /* set video->mem_mge_ctrl_eq_5 */
- video->mbNum = 0; // Conceal
- StorePictureInDPB(avcHandle, video);
- video->nal_unit_type = temp;
-
- return AVCDEC_PICTURE_OUTPUT_READY;
- }
- }
- }
-
- if (video->newPic == TRUE)
- {
- status = (AVCDec_Status)DPBInitBuffer(avcHandle, video);
- if (status != AVCDEC_SUCCESS)
- {
- return status;
- }
- }
-
- video->newSlice = TRUE;
-
- /* function pointer setting at slice-level */
- // OPTIMIZE
- decvid->residual_block = &residual_block_cavlc;
-
- /* derive picture order count */
- if (video->newPic == TRUE)
- {
- video->numMBs = video->PicSizeInMbs;
-
- if (video->nal_unit_type != AVC_NALTYPE_IDR && video->currSeqParams->gaps_in_frame_num_value_allowed_flag)
- {
- if (video->sliceHdr->frame_num != (video->PrevRefFrameNum + 1) % video->MaxFrameNum)
- {
- status = fill_frame_num_gap(avcHandle, video);
- if (status != AVCDEC_SUCCESS)
- {
- video->numMBs = 0;
- return status;
- }
-
- status = (AVCDec_Status)DPBInitBuffer(avcHandle, video);
- if (status != AVCDEC_SUCCESS)
- {
- video->numMBs = 0;
- return status;
- }
-
-
- }
- }
- /* if there's gap in the frame_num, we have to fill in the gap with
- imaginary frames that won't get used for short-term ref. */
- /* see fill_frame_num_gap() in JM */
-
-
- DecodePOC(video);
- /* find an empty memory from DPB and assigned to currPic */
- DPBInitPic(video, video->CurrPicNum);
-
- video->currPic->isReference = TRUE; // FIX
-
- if (video->nal_ref_idc == 0)
- {
- video->currPic->isReference = FALSE;
- video->currFS->IsOutputted |= 0x02; /* The MASK 0x02 means not needed for reference, or returned */
- /* node need to check for freeing of this buffer */
- }
-
- FMOInit(video);
-
- if (video->currPic->isReference)
- {
- video->PrevRefFrameNum = video->sliceHdr->frame_num;
- }
-
-
- video->prevFrameNum = video->sliceHdr->frame_num;
- }
-
- video->newPic = FALSE;
-
-
- /* Initialize refListIdx for this picture */
- RefListInit(video);
-
- /* Re-order the reference list according to the ref_pic_list_reordering() */
- status = (AVCDec_Status)ReOrderList(video);
- if (status != AVCDEC_SUCCESS)
- {
- return AVCDEC_FAIL;
- }
-
- /* 2.2 Decode Slice. */
- status = (AVCDec_Status)DecodeSlice(decvid);
-
- video->slice_id++; // slice
-
- if (status == AVCDEC_PICTURE_READY)
- {
- /* 3. Check complete picture */
-#ifndef MB_BASED_DEBLOCK
- /* 3.1 Deblock */
- DeblockPicture(video);
-#endif
- /* 3.2 Decoded frame reference marking. */
- /* 3.3 Put the decoded picture in output buffers */
- /* set video->mem_mge_ctrl_eq_5 */
- status = (AVCDec_Status)StorePictureInDPB(avcHandle, video); // CHECK check the retunr status
- if (status != AVCDEC_SUCCESS)
- {
- return AVCDEC_FAIL;
- }
-
- if (video->mem_mgr_ctrl_eq_5)
- {
- video->PrevRefFrameNum = 0;
- video->prevFrameNum = 0;
- video->prevPicOrderCntMsb = 0;
- video->prevPicOrderCntLsb = video->TopFieldOrderCnt;
- video->prevFrameNumOffset = 0;
- }
- else
- {
- video->prevPicOrderCntMsb = video->PicOrderCntMsb;
- video->prevPicOrderCntLsb = video->sliceHdr->pic_order_cnt_lsb;
- video->prevFrameNumOffset = video->FrameNumOffset;
- }
-
- return AVCDEC_PICTURE_READY;
- }
- else if (status != AVCDEC_SUCCESS)
- {
- return AVCDEC_FAIL;
- }
-
- return AVCDEC_SUCCESS;
-}
-
-/* ======================================================================== */
-/* Function : PVAVCDecGetOutput() */
-/* Date : 11/3/2003 */
-/* Purpose : Get the next picture according to PicOrderCnt. */
-/* In/out : */
-/* Return : AVCFrameIO structure */
-/* Modified : */
-/* ======================================================================== */
-
-OSCL_EXPORT_REF AVCDec_Status PVAVCDecGetOutput(AVCHandle *avcHandle, int *indx, int *release, AVCFrameIO *output)
-{
- AVCDecObject *decvid = (AVCDecObject*) avcHandle->AVCObject;
- AVCCommonObj *video;
- AVCDecPicBuffer *dpb;
- AVCFrameStore *oldestFrame = NULL;
- int i, first = 1;
- int count_frame = 0;
- int index = 0;
- int min_poc = 0;
-
- if (decvid == NULL)
- {
- return AVCDEC_FAIL;
- }
-
- video = decvid->common;
- dpb = video->decPicBuf;
-
- if (dpb->num_fs == 0)
- {
- return AVCDEC_FAIL;
- }
-
- /* search for the oldest frame_num in dpb */
- /* extension to field decoding, we have to search for every top_field/bottom_field within
- each frame in the dpb. This code only works for frame based.*/
-
- if (video->mem_mgr_ctrl_eq_5 == FALSE)
- {
- for (i = 0; i < dpb->num_fs; i++)
- {
- if ((dpb->fs[i]->IsOutputted & 0x01) == 0)
- {
- count_frame++;
- if (first)
- {
- min_poc = dpb->fs[i]->PicOrderCnt;
- first = 0;
- oldestFrame = dpb->fs[i];
- index = i;
- }
- if (dpb->fs[i]->PicOrderCnt < min_poc)
- {
- min_poc = dpb->fs[i]->PicOrderCnt;
- oldestFrame = dpb->fs[i];
- index = i;
- }
- }
- }
- }
- else
- {
- for (i = 0; i < dpb->num_fs; i++)
- {
- if ((dpb->fs[i]->IsOutputted & 0x01) == 0 && dpb->fs[i] != video->currFS)
- {
- count_frame++;
- if (first)
- {
- min_poc = dpb->fs[i]->PicOrderCnt;
- first = 0;
- oldestFrame = dpb->fs[i];
- index = i;
- }
- if (dpb->fs[i]->PicOrderCnt < min_poc)
- {
- min_poc = dpb->fs[i]->PicOrderCnt;
- oldestFrame = dpb->fs[i];
- index = i;
- }
- }
- }
-
- if (count_frame < 2 && video->nal_unit_type != AVC_NALTYPE_IDR)
- {
- video->mem_mgr_ctrl_eq_5 = FALSE; // FIX
- }
- else if (count_frame < 1 && video->nal_unit_type == AVC_NALTYPE_IDR)
- {
- for (i = 0; i < dpb->num_fs; i++)
- {
- if (dpb->fs[i] == video->currFS && (dpb->fs[i]->IsOutputted & 0x01) == 0)
- {
- oldestFrame = dpb->fs[i];
- index = i;
- break;
- }
- }
- video->mem_mgr_ctrl_eq_5 = FALSE;
- }
- }
-
- if (oldestFrame == NULL)
- {
-
- /* Check for Mem_mgmt_operation_5 based forced output */
- for (i = 0; i < dpb->num_fs; i++)
- {
- /* looking for the one not used or not reference and has been outputted */
- if (dpb->fs[i]->IsReference == 0 && dpb->fs[i]->IsOutputted == 3)
- {
- break;
- }
- }
- if (i < dpb->num_fs)
- {
- /* there are frames available for decoding */
- return AVCDEC_FAIL; /* no frame to be outputted */
- }
-
-
- /* no free frame available, we have to release one to continue decoding */
- int MinIdx = 0;
- int32 MinFrameNumWrap = 0x7FFFFFFF;
-
- for (i = 0; i < dpb->num_fs; i++)
- {
- if (dpb->fs[i]->IsReference && !dpb->fs[i]->IsLongTerm)
- {
- if (dpb->fs[i]->FrameNumWrap < MinFrameNumWrap)
- {
- MinFrameNumWrap = dpb->fs[i]->FrameNumWrap;
- MinIdx = i;
- }
- }
- }
- /* mark the frame with smallest PicOrderCnt to be unused for reference */
- dpb->fs[MinIdx]->IsReference = 0;
- dpb->fs[MinIdx]->IsLongTerm = 0;
- dpb->fs[MinIdx]->frame.isReference = FALSE;
- dpb->fs[MinIdx]->frame.isLongTerm = FALSE;
- dpb->fs[MinIdx]->IsOutputted |= 0x02;
-#ifdef PV_MEMORY_POOL
- if (dpb->fs[MinIdx]->IsOutputted == 3)
- {
- avcHandle->CBAVC_FrameUnbind(avcHandle->userData, MinIdx);
- }
-#endif
- return AVCDEC_FAIL;
- }
- /* MASK 0x01 means the frame is outputted (for display). A frame gets freed when it is
- outputted (0x01) and not needed for reference (0x02) */
- oldestFrame->IsOutputted |= 0x01;
-
- if (oldestFrame->IsOutputted == 3)
- {
- *release = 1; /* flag to release the buffer */
- }
- else
- {
- *release = 0;
- }
- /* do not release buffer here, release it after it is sent to the sink node */
-
- output->YCbCr[0] = oldestFrame->frame.Sl;
- output->YCbCr[1] = oldestFrame->frame.Scb;
- output->YCbCr[2] = oldestFrame->frame.Scr;
- output->height = oldestFrame->frame.height;
- output->pitch = oldestFrame->frame.width;
- output->disp_order = oldestFrame->PicOrderCnt;
- output->coding_order = oldestFrame->FrameNum;
- output->id = (uint32) oldestFrame->base_dpb; /* use the pointer as the id */
- *indx = index;
-
-
-
- return AVCDEC_SUCCESS;
-}
-
-
-/* ======================================================================== */
-/* Function : PVAVCDecReset() */
-/* Date : 03/04/2004 */
-/* Purpose : Reset decoder, prepare it for a new IDR frame. */
-/* In/out : */
-/* Return : void */
-/* Modified : */
-/* ======================================================================== */
-OSCL_EXPORT_REF void PVAVCDecReset(AVCHandle *avcHandle)
-{
- AVCDecObject *decvid = (AVCDecObject*) avcHandle->AVCObject;
- AVCCommonObj *video;
- AVCDecPicBuffer *dpb;
- int i;
-
- if (decvid == NULL)
- {
- return;
- }
-
- video = decvid->common;
- dpb = video->decPicBuf;
-
- /* reset the DPB */
-
-
- for (i = 0; i < dpb->num_fs; i++)
- {
- dpb->fs[i]->IsLongTerm = 0;
- dpb->fs[i]->IsReference = 0;
- dpb->fs[i]->IsOutputted = 3;
- dpb->fs[i]->frame.isReference = 0;
- dpb->fs[i]->frame.isLongTerm = 0;
- }
-
- video->mem_mgr_ctrl_eq_5 = FALSE;
- video->newPic = TRUE;
- video->newSlice = TRUE;
- video->currPic = NULL;
- video->currFS = NULL;
- video->prevRefPic = NULL;
- video->prevFrameNum = 0;
- video->PrevRefFrameNum = 0;
- video->prevFrameNumOffset = 0;
- video->FrameNumOffset = 0;
- video->mbNum = 0;
- video->numMBs = 0;
-
- return ;
-}
-
-
-/* ======================================================================== */
-/* Function : PVAVCCleanUpDecoder() */
-/* Date : 11/4/2003 */
-/* Purpose : Clean up the decoder, free all memories allocated. */
-/* In/out : */
-/* Return : void */
-/* Modified : */
-/* ======================================================================== */
-
-OSCL_EXPORT_REF void PVAVCCleanUpDecoder(AVCHandle *avcHandle)
-{
- AVCDecObject *decvid = (AVCDecObject*) avcHandle->AVCObject;
- AVCCommonObj *video;
- void *userData = avcHandle->userData;
- int i;
-
- DEBUG_LOG(userData, AVC_LOGTYPE_INFO, "PVAVCCleanUpDecoder", -1, -1);
-
- if (decvid != NULL)
- {
- video = decvid->common;
- if (video != NULL)
- {
- if (video->MbToSliceGroupMap != NULL)
- {
- avcHandle->CBAVC_Free(userData, (int)video->MbToSliceGroupMap);
- }
-
-#ifdef MB_BASED_DEBLOCK
- if (video->intra_pred_top != NULL)
- {
- avcHandle->CBAVC_Free(userData, (int)video->intra_pred_top);
- }
- if (video->intra_pred_top_cb != NULL)
- {
- avcHandle->CBAVC_Free(userData, (int)video->intra_pred_top_cb);
- }
- if (video->intra_pred_top_cr != NULL)
- {
- avcHandle->CBAVC_Free(userData, (int)video->intra_pred_top_cr);
- }
-#endif
- if (video->mblock != NULL)
- {
- avcHandle->CBAVC_Free(userData, (int)video->mblock);
- }
-
- if (video->decPicBuf != NULL)
- {
- CleanUpDPB(avcHandle, video);
- avcHandle->CBAVC_Free(userData, (int)video->decPicBuf);
- }
-
- if (video->sliceHdr != NULL)
- {
- avcHandle->CBAVC_Free(userData, (int)video->sliceHdr);
- }
-
- avcHandle->CBAVC_Free(userData, (int)video); /* last thing to do */
-
- }
-
- for (i = 0; i < 256; i++)
- {
- if (decvid->picParams[i] != NULL)
- {
- if (decvid->picParams[i]->slice_group_id != NULL)
- {
- avcHandle->CBAVC_Free(userData, (int)decvid->picParams[i]->slice_group_id);
- }
- avcHandle->CBAVC_Free(userData, (int)decvid->picParams[i]);
- }
- }
- for (i = 0; i < 32; i++)
- {
- if (decvid->seqParams[i] != NULL)
- {
- avcHandle->CBAVC_Free(userData, (int)decvid->seqParams[i]);
- }
- }
- if (decvid->bitstream != NULL)
- {
- avcHandle->CBAVC_Free(userData, (int)decvid->bitstream);
- }
-
-
- avcHandle->CBAVC_Free(userData, (int)decvid);
- }
-
-
- return ;
-}
diff --git a/media/libstagefright/codecs/avc/dec/src/avcdec_bitstream.h b/media/libstagefright/codecs/avc/dec/src/avcdec_bitstream.h
deleted file mode 100644
index bd1bc59..0000000
--- a/media/libstagefright/codecs/avc/dec/src/avcdec_bitstream.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/* ------------------------------------------------------------------
- * 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.
- * -------------------------------------------------------------------
- */
-/**
-This file contains bitstream related functions.
-@publishedAll
-*/
-
-#ifndef _AVCDEC_BITSTREAM_H_
-#define _AVCDEC_BITSTREAM_H_
-
-#include "avcdec_lib.h"
-
-#define WORD_SIZE 32 /* this can vary, default to 32 bit for now */
-
-#ifndef __cplusplus
-
-#define AVC_GETDATA(x,y) userData->AVC_GetData(x,y)
-
-#endif
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-#define BitstreamFlushBits(A,B) {(A)->bitcnt += (B); (A)->incnt -= (B); (A)->curr_word <<= (B);}
-
- AVCDec_Status AVC_BitstreamFillCache(AVCDecBitstream *stream);
- /**
- This function populates bitstream structure.
- \param "stream" "Pointer to bitstream structure."
- \param "buffer" "Pointer to the bitstream buffer."
- \param "size" "Size of the buffer."
- \param "nal_size" "Size of the NAL unit."
- \param "resetall" "Flag for reset everything."
- \return "AVCDEC_SUCCESS for success and AVCDEC_FAIL for fail."
- */
- AVCDec_Status BitstreamInit(AVCDecBitstream *stream, uint8 *buffer, int size);
-
- /**
- This function reads next aligned word and remove the emulation prevention code
- if necessary.
- \param "stream" "Pointer to bitstream structure."
- \return "Next word."
- */
- uint BitstreamNextWord(AVCDecBitstream *stream);
-
- /**
- This function reads nBits bits from the current position and advance the pointer.
- \param "stream" "Pointer to bitstream structure."
- \param "nBits" "Number of bits to be read."
- \param "code" "Point to the read value."
- \return "AVCDEC_SUCCESS if successed, AVCDEC_FAIL if number of bits
- is greater than the word-size, AVCDEC_PACKET_LOSS or
- AVCDEC_NO_DATA if callback to get data fails."
- */
- AVCDec_Status BitstreamReadBits(AVCDecBitstream *stream, int nBits, uint *code);
-
- /**
- This function shows nBits bits from the current position without advancing the pointer.
- \param "stream" "Pointer to bitstream structure."
- \param "nBits" "Number of bits to be read."
- \param "code" "Point to the read value."
- \return "AVCDEC_SUCCESS if successed, AVCDEC_FAIL if number of bits
- is greater than the word-size, AVCDEC_NO_DATA if it needs
- to callback to get data."
- */
- AVCDec_Status BitstreamShowBits(AVCDecBitstream *stream, int nBits, uint *code);
-
-
- /**
- This function flushes nBits bits from the current position.
- \param "stream" "Pointer to bitstream structure."
- \param "nBits" "Number of bits to be read."
- \return "AVCDEC_SUCCESS if successed, AVCDEC_FAIL if number of bits
- is greater than the word-size It will not call back to get
- more data. Users should call BitstreamShowBits to determine
- how much they want to flush."
- */
-
- /**
- This function read 1 bit from the current position and advance the pointer.
- \param "stream" "Pointer to bitstream structure."
- \param "nBits" "Number of bits to be read."
- \param "code" "Point to the read value."
- \return "AVCDEC_SUCCESS if successed, AVCDEC_FAIL if number of bits
- is greater than the word-size, AVCDEC_PACKET_LOSS or
- AVCDEC_NO_DATA if callback to get data fails."
- */
- AVCDec_Status BitstreamRead1Bit(AVCDecBitstream *stream, uint *code);
-
- /**
- This function checks whether the current bit position is byte-aligned or not.
- \param "stream" "Pointer to the bitstream structure."
- \return "TRUE if byte-aligned, FALSE otherwise."
- */
- bool byte_aligned(AVCDecBitstream *stream);
- AVCDec_Status BitstreamByteAlign(AVCDecBitstream *stream);
- /**
- This function checks whether there are more RBSP data before the trailing bits.
- \param "stream" "Pointer to the bitstream structure."
- \return "TRUE if yes, FALSE otherwise."
- */
- bool more_rbsp_data(AVCDecBitstream *stream);
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* _AVCDEC_BITSTREAM_H_ */
diff --git a/media/libstagefright/codecs/avc/dec/src/avcdec_int.h b/media/libstagefright/codecs/avc/dec/src/avcdec_int.h
deleted file mode 100644
index 878f9b3..0000000
--- a/media/libstagefright/codecs/avc/dec/src/avcdec_int.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/* ------------------------------------------------------------------
- * 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.
- * -------------------------------------------------------------------
- */
-/**
-This file contains application function interfaces to the AVC decoder library
-and necessary type defitionitions and enumerations.
-Naming convention for variables:
-lower_case_with_under_line is syntax element in subclause 7.2 and 7.3
-noUnderLine or NoUnderLine is derived variables defined somewhere else in the draft
- or introduced by this decoder library.
-@publishedAll
-*/
-
-#ifndef _AVCDEC_INT_H_
-#define _AVCDEC_INT_H_
-
-#include "avcint_common.h"
-#include "avcdec_api.h"
-
-
-/**
-Bitstream structure contains bitstream related parameters such as the pointer
-to the buffer, the current byte position and bit position.
-@publishedAll
-*/
-typedef struct tagDecBitstream
-{
- uint8 *bitstreamBuffer; /* pointer to buffer memory */
- int nal_size; /* size of the current NAL unit */
- int data_end_pos; /* bitstreamBuffer size in bytes */
- int read_pos; /* next position to read from bitstreamBuffer */
- uint curr_word; /* byte-swapped (MSB left) current word read from buffer */
- int bit_left; /* number of bit left in current_word */
- uint next_word; /* in case for old data in previous buffer hasn't been flushed. */
- int incnt; /* bit left in the prev_word */
- int incnt_next;
- int bitcnt;
- void *userData;
-} AVCDecBitstream;
-
-/**
-This structure is the main object for AVC decoder library providing access to all
-global variables. It is allocated at PVAVCInitDecoder and freed at PVAVCCleanUpDecoder.
-@publishedAll
-*/
-typedef struct tagDecObject
-{
-
- AVCCommonObj *common;
-
- AVCDecBitstream *bitstream; /* for current NAL */
-
- /* sequence parameter set */
- AVCSeqParamSet *seqParams[32]; /* Array of pointers, get allocated at arrival of new seq_id */
-
- /* picture parameter set */
- AVCPicParamSet *picParams[256]; /* Array of pointers to picture param set structures */
-
- /* For internal operation, scratch memory for MV, prediction, transform, etc.*/
- uint ref_idx_l0[4]; /* [mbPartIdx], te(v) */
- uint ref_idx_l1[4];
-
- /* function pointers */
- AVCDec_Status(*residual_block)(struct tagDecObject*, int, int,
- int *, int *, int *);
- /* Application control data */
- AVCHandle *avcHandle;
- void (*AVC_DebugLog)(AVCLogType type, char *string1, char *string2);
- /*bool*/
- uint debugEnable;
-
-} AVCDecObject;
-
-#endif /* _AVCDEC_INT_H_ */
diff --git a/media/libstagefright/codecs/avc/dec/src/avcdec_lib.h b/media/libstagefright/codecs/avc/dec/src/avcdec_lib.h
deleted file mode 100644
index fdead05..0000000
--- a/media/libstagefright/codecs/avc/dec/src/avcdec_lib.h
+++ /dev/null
@@ -1,555 +0,0 @@
-/* ------------------------------------------------------------------
- * 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.
- * -------------------------------------------------------------------
- */
-/**
-This file contains declarations of internal functions for AVC decoder library.
-@publishedAll
-*/
-#ifndef _AVCDEC_LIB_H_
-#define _AVCDEC_LIB_H_
-
-#include "avclib_common.h"
-#include "avcdec_int.h"
-
-/*----------- avcdec_api.c -------------*/
-/**
-This function takes out the emulation prevention bytes from the input to creat RBSP.
-The result is written over the input bitstream.
-\param "nal_unit" "(I/O) Pointer to the input buffer."
-\param "size" "(I/O) Pointer to the size of the input/output buffer."
-\return "AVCDEC_SUCCESS for success and AVCDEC_FAIL otherwise."
-*/
-AVCDec_Status EBSPtoRBSP(uint8 *nal_unit, int *size);
-
-/*------------- pred_intra.c ---------------*/
-/**
-This function is the main entry point to intra prediction operation on a
-macroblock.
-\param "video" "Pointer to AVCCommonObj."
-*/
-AVCStatus IntraMBPrediction(AVCCommonObj *video);
-
-void SaveNeighborForIntraPred(AVCCommonObj *video, int offset);
-
-AVCStatus Intra_4x4(AVCCommonObj *video, int component, int SubBlock_indx, uint8 *comp);
-void Intra_4x4_Vertical(AVCCommonObj *video, int block_offset);
-void Intra_4x4_Horizontal(AVCCommonObj *video, int pitch, int block_offset);
-void Intra_4x4_DC(AVCCommonObj *video, int pitch, int block_offset, AVCNeighborAvailability *availability);
-void Intra_4x4_Down_Left(AVCCommonObj *video, int block_offset, AVCNeighborAvailability *availability);
-void Intra_4x4_Diagonal_Down_Right(AVCCommonObj *video, int pitch, int block_offset);
-void Intra_4x4_Diagonal_Vertical_Right(AVCCommonObj *video, int pitch, int block_offset);
-void Intra_4x4_Diagonal_Horizontal_Down(AVCCommonObj *video, int pitch, int block_offset);
-void Intra_4x4_Vertical_Left(AVCCommonObj *video, int block_offset, AVCNeighborAvailability *availability);
-void Intra_4x4_Horizontal_Up(AVCCommonObj *video, int pitch, int block_offset);
-void Intra_16x16_Vertical(AVCCommonObj *video);
-void Intra_16x16_Horizontal(AVCCommonObj *video, int pitch);
-void Intra_16x16_DC(AVCCommonObj *video, int pitch);
-void Intra_16x16_Plane(AVCCommonObj *video, int pitch);
-void Intra_Chroma_DC(AVCCommonObj *video, int pitch, uint8 *predCb, uint8 *predCr);
-void Intra_Chroma_Horizontal(AVCCommonObj *video, int pitch, uint8 *predCb, uint8 *predCr);
-void Intra_Chroma_Vertical(AVCCommonObj *video, uint8 *predCb, uint8 *predCr);
-void Intra_Chroma_Plane(AVCCommonObj *video, int pitch, uint8 *predCb, uint8 *predCr);
-
-/*------------ pred_inter.c ---------------*/
-/**
-This function is the main entrance to inter prediction operation for
-a macroblock. For decoding, this function also calls inverse transform and
-compensation.
-\param "video" "Pointer to AVCCommonObj."
-\return "void"
-*/
-void InterMBPrediction(AVCCommonObj *video);
-
-/**
-This function is called for luma motion compensation.
-\param "ref" "Pointer to the origin of a reference luma."
-\param "picwidth" "Width of the picture."
-\param "picheight" "Height of the picture."
-\param "x_pos" "X-coordinate of the predicted block in quarter pel resolution."
-\param "y_pos" "Y-coordinate of the predicted block in quarter pel resolution."
-\param "pred" "Pointer to the output predicted block."
-\param "pred_pitch" "Width of pred."
-\param "blkwidth" "Width of the current partition."
-\param "blkheight" "Height of the current partition."
-\return "void"
-*/
-void LumaMotionComp(uint8 *ref, int picwidth, int picheight,
- int x_pos, int y_pos,
- uint8 *pred, int pred_pitch,
- int blkwidth, int blkheight);
-
-/**
-Functions below are special cases for luma motion compensation.
-LumaFullPelMC is for full pixel motion compensation.
-LumaBorderMC is for interpolation in only one dimension.
-LumaCrossMC is for interpolation in one dimension and half point in the other dimension.
-LumaDiagonalMC is for interpolation in diagonal direction.
-
-\param "ref" "Pointer to the origin of a reference luma."
-\param "picwidth" "Width of the picture."
-\param "picheight" "Height of the picture."
-\param "x_pos" "X-coordinate of the predicted block in full pel resolution."
-\param "y_pos" "Y-coordinate of the predicted block in full pel resolution."
-\param "dx" "Fraction of x_pos in quarter pel."
-\param "dy" "Fraction of y_pos in quarter pel."
-\param "curr" "Pointer to the current partition in the current picture."
-\param "residue" "Pointer to the current partition for the residue block."
-\param "blkwidth" "Width of the current partition."
-\param "blkheight" "Height of the current partition."
-\return "void"
-*/
-void CreatePad(uint8 *ref, int picwidth, int picheight, int x_pos, int y_pos,
- uint8 *out, int blkwidth, int blkheight);
-
-void FullPelMC(uint8 *in, int inwidth, uint8 *out, int outpitch,
- int blkwidth, int blkheight);
-
-void HorzInterp1MC(uint8 *in, int inpitch, uint8 *out, int outpitch,
- int blkwidth, int blkheight, int dx);
-
-void HorzInterp2MC(int *in, int inpitch, uint8 *out, int outpitch,
- int blkwidth, int blkheight, int dx);
-
-void HorzInterp3MC(uint8 *in, int inpitch, int *out, int outpitch,
- int blkwidth, int blkheight);
-
-void VertInterp1MC(uint8 *in, int inpitch, uint8 *out, int outpitch,
- int blkwidth, int blkheight, int dy);
-
-void VertInterp2MC(uint8 *in, int inpitch, int *out, int outpitch,
- int blkwidth, int blkheight);
-
-void VertInterp3MC(int *in, int inpitch, uint8 *out, int outpitch,
- int blkwidth, int blkheight, int dy);
-
-void DiagonalInterpMC(uint8 *in1, uint8 *in2, int inpitch,
- uint8 *out, int outpitch,
- int blkwidth, int blkheight);
-
-
-void ChromaMotionComp(uint8 *ref, int picwidth, int picheight,
- int x_pos, int y_pos, uint8 *pred, int pred_pitch,
- int blkwidth, int blkheight);
-
-void ChromaFullPelMC(uint8 *in, int inpitch, uint8 *out, int outpitch,
- int blkwidth, int blkheight) ;
-void ChromaBorderMC(uint8 *ref, int picwidth, int dx, int dy,
- uint8 *pred, int pred_pitch, int blkwidth, int blkheight);
-void ChromaDiagonalMC(uint8 *ref, int picwidth, int dx, int dy,
- uint8 *pred, int pred_pitch, int blkwidth, int blkheight);
-
-void ChromaFullPelMCOutside(uint8 *ref, uint8 *pred, int pred_pitch,
- int blkwidth, int blkheight, int x_inc,
- int y_inc0, int y_inc1, int x_mid, int y_mid);
-void ChromaBorderMCOutside(uint8 *ref, int picwidth, int dx, int dy,
- uint8 *pred, int pred_pitch, int blkwidth, int blkheight,
- int x_inc, int z_inc, int y_inc0, int y_inc1, int x_mid, int y_mid);
-void ChromaDiagonalMCOutside(uint8 *ref, int picwidth,
- int dx, int dy, uint8 *pred, int pred_pitch,
- int blkwidth, int blkheight, int x_inc, int z_inc,
- int y_inc0, int y_inc1, int x_mid, int y_mid);
-
-void ChromaDiagonalMC_SIMD(uint8 *pRef, int srcPitch, int dx, int dy,
- uint8 *pOut, int predPitch, int blkwidth, int blkheight);
-
-void ChromaHorizontalMC_SIMD(uint8 *pRef, int srcPitch, int dx, int dy,
- uint8 *pOut, int predPitch, int blkwidth, int blkheight);
-
-void ChromaVerticalMC_SIMD(uint8 *pRef, int srcPitch, int dx, int dy,
- uint8 *pOut, int predPitch, int blkwidth, int blkheight);
-
-void ChromaFullMC_SIMD(uint8 *pRef, int srcPitch, int dx, int dy,
- uint8 *pOut, int predPitch, int blkwidth, int blkheight);
-
-void ChromaVerticalMC2_SIMD(uint8 *pRef, int srcPitch, int dx, int dy,
- uint8 *pOut, int predPitch, int blkwidth, int blkheight);
-
-void ChromaHorizontalMC2_SIMD(uint8 *pRef, int srcPitch, int dx, int dy,
- uint8 *pOut, int predPitch, int blkwidth, int blkheight);
-
-void ChromaDiagonalMC2_SIMD(uint8 *pRef, int srcPitch, int dx, int dy,
- uint8 *pOut, int predPitch, int blkwidth, int blkheight);
-
-
-/*----------- slice.c ---------------*/
-/**
-This function performs the main decoding loop for slice data including
-INTRA/INTER prediction, transform and quantization and compensation.
-See decode_frame_slice() in JM.
-\param "video" "Pointer to AVCDecObject."
-\return "AVCDEC_SUCCESS for success, AVCDEC_PICTURE_READY for end-of-picture and AVCDEC_FAIL otherwise."
-*/
-AVCDec_Status DecodeSlice(AVCDecObject *video);
-AVCDec_Status ConcealSlice(AVCDecObject *decvid, int mbnum_start, int mbnum_end);
-/**
-This function performs the decoding of one macroblock.
-\param "video" "Pointer to AVCDecObject."
-\param "prevMbSkipped" "A value derived in 7.3.4."
-\return "AVCDEC_SUCCESS for success or AVCDEC_FAIL otherwise."
-*/
-AVCDec_Status DecodeMB(AVCDecObject *video);
-
-/**
-This function performs macroblock prediction type decoding as in subclause 7.3.5.1.
-\param "video" "Pointer to AVCCommonObj."
-\param "currMB" "Pointer to the current macroblock."
-\param "stream" "Pointer to AVCDecBitstream."
-\return "AVCDEC_SUCCESS for success or AVCDEC_FAIL otherwise."
-*/
-AVCDec_Status mb_pred(AVCCommonObj *video, AVCMacroblock *currMB, AVCDecBitstream *stream);
-
-/**
-This function performs sub-macroblock prediction type decoding as in subclause 7.3.5.2.
-\param "video" "Pointer to AVCCommonObj."
-\param "currMB" "Pointer to the current macroblock."
-\param "stream" "Pointer to AVCDecBitstream."
-\return "AVCDEC_SUCCESS for success or AVCDEC_FAIL otherwise."
-*/
-AVCDec_Status sub_mb_pred(AVCCommonObj *video, AVCMacroblock *currMB, AVCDecBitstream *stream);
-
-/**
-This function interprets the mb_type and sets necessary information
-when the slice type is AVC_I_SLICE.
-in the macroblock structure.
-\param "mblock" "Pointer to current AVCMacroblock."
-\param "mb_type" "From the syntax bitstream."
-\return "void"
-*/
-void InterpretMBModeI(AVCMacroblock *mblock, uint mb_type);
-
-/**
-This function interprets the mb_type and sets necessary information
-when the slice type is AVC_P_SLICE.
-in the macroblock structure.
-\param "mblock" "Pointer to current AVCMacroblock."
-\param "mb_type" "From the syntax bitstream."
-\return "void"
-*/
-void InterpretMBModeP(AVCMacroblock *mblock, uint mb_type);
-
-/**
-This function interprets the mb_type and sets necessary information
-when the slice type is AVC_B_SLICE.
-in the macroblock structure.
-\param "mblock" "Pointer to current AVCMacroblock."
-\param "mb_type" "From the syntax bitstream."
-\return "void"
-*/
-void InterpretMBModeB(AVCMacroblock *mblock, uint mb_type);
-
-/**
-This function interprets the mb_type and sets necessary information
-when the slice type is AVC_SI_SLICE.
-in the macroblock structure.
-\param "mblock" "Pointer to current AVCMacroblock."
-\param "mb_type" "From the syntax bitstream."
-\return "void"
-*/
-void InterpretMBModeSI(AVCMacroblock *mblock, uint mb_type);
-
-/**
-This function interprets the sub_mb_type and sets necessary information
-when the slice type is AVC_P_SLICE.
-in the macroblock structure.
-\param "mblock" "Pointer to current AVCMacroblock."
-\param "sub_mb_type" "From the syntax bitstream."
-\return "void"
-*/
-void InterpretSubMBModeP(AVCMacroblock *mblock, uint *sub_mb_type);
-
-/**
-This function interprets the sub_mb_type and sets necessary information
-when the slice type is AVC_B_SLICE.
-in the macroblock structure.
-\param "mblock" "Pointer to current AVCMacroblock."
-\param "sub_mb_type" "From the syntax bitstream."
-\return "void"
-*/
-void InterpretSubMBModeB(AVCMacroblock *mblock, uint *sub_mb_type);
-
-/**
-This function decodes the Intra4x4 prediction mode from neighboring information
-and from the decoded syntax.
-\param "video" "Pointer to AVCCommonObj."
-\param "currMB" "Pointer to current macroblock."
-\param "stream" "Pointer to AVCDecBitstream."
-\return "AVCDEC_SUCCESS or AVCDEC_FAIL."
-*/
-AVCDec_Status DecodeIntra4x4Mode(AVCCommonObj *video, AVCMacroblock *currMB, AVCDecBitstream *stream);
-
-/*----------- vlc.c -------------------*/
-/**
-This function reads and decodes Exp-Golomb codes.
-\param "bitstream" "Pointer to AVCDecBitstream."
-\param "codeNum" "Pointer to the value of the codeNum."
-\return "AVCDEC_SUCCESS or AVCDEC_FAIL."
-*/
-AVCDec_Status ue_v(AVCDecBitstream *bitstream, uint *codeNum);
-
-/**
-This function reads and decodes signed Exp-Golomb codes.
-\param "bitstream" "Pointer to AVCDecBitstream."
-\param "value" "Pointer to syntax element value."
-\return "AVCDEC_SUCCESS or AVCDEC_FAIL."
-*/
-AVCDec_Status se_v(AVCDecBitstream *bitstream, int *value);
-
-/**
-This function reads and decodes signed Exp-Golomb codes for
-32 bit codeword.
-\param "bitstream" "Pointer to AVCDecBitstream."
-\param "value" "Pointer to syntax element value."
-\return "AVCDEC_SUCCESS or AVCDEC_FAIL."
-*/
-AVCDec_Status se_v32bit(AVCDecBitstream *bitstream, int32 *value);
-
-/**
-This function reads and decodes truncated Exp-Golomb codes.
-\param "bitstream" "Pointer to AVCDecBitstream."
-\param "value" "Pointer to syntax element value."
-\param "range" "Range of the value as input to determine the algorithm."
-\return "AVCDEC_SUCCESS or AVCDEC_FAIL."
-*/
-AVCDec_Status te_v(AVCDecBitstream *bitstream, uint *value, uint range);
-
-/**
-This function parse Exp-Golomb code from the bitstream.
-\param "bitstream" "Pointer to AVCDecBitstream."
-\param "leadingZeros" "Pointer to the number of leading zeros."
-\param "infobits" "Pointer to the value after leading zeros and the first one.
- The total number of bits read is 2*leadingZeros + 1."
-\return "AVCDEC_SUCCESS or AVCDEC_FAIL."
-*/
-AVCDec_Status GetEGBitstring(AVCDecBitstream *bitstream, int *leadingZeros, int *infobits);
-
-/**
-This function parse Exp-Golomb code from the bitstream for 32 bit codewords.
-\param "bitstream" "Pointer to AVCDecBitstream."
-\param "leadingZeros" "Pointer to the number of leading zeros."
-\param "infobits" "Pointer to the value after leading zeros and the first one.
- The total number of bits read is 2*leadingZeros + 1."
-\return "AVCDEC_SUCCESS or AVCDEC_FAIL."
-*/
-AVCDec_Status GetEGBitstring32bit(AVCDecBitstream *bitstream, int *leadingZeros, uint32 *infobits);
-
-/**
-This function performs CAVLC decoding of the CBP (coded block pattern) of a macroblock
-by calling ue_v() and then mapping the codeNum to the corresponding CBP value.
-\param "currMB" "Pointer to the current AVCMacroblock structure."
-\param "stream" "Pointer to the AVCDecBitstream."
-\return "void"
-*/
-AVCDec_Status DecodeCBP(AVCMacroblock *currMB, AVCDecBitstream *stream);
-
-/**
-This function decodes the syntax for trailing ones and total coefficient.
-Subject to optimization.
-\param "stream" "Pointer to the AVCDecBitstream."
-\param "TrailingOnes" "Pointer to the trailing one variable output."
-\param "TotalCoeff" "Pointer to the total coefficient variable output."
-\param "nC" "Context for number of nonzero coefficient (prediction context)."
-\return "AVCDEC_SUCCESS for success."
-*/
-AVCDec_Status ce_TotalCoeffTrailingOnes(AVCDecBitstream *stream, int *TrailingOnes, int *TotalCoeff, int nC);
-
-/**
-This function decodes the syntax for trailing ones and total coefficient for
-chroma DC block. Subject to optimization.
-\param "stream" "Pointer to the AVCDecBitstream."
-\param "TrailingOnes" "Pointer to the trailing one variable output."
-\param "TotalCoeff" "Pointer to the total coefficient variable output."
-\return "AVCDEC_SUCCESS for success."
-*/
-AVCDec_Status ce_TotalCoeffTrailingOnesChromaDC(AVCDecBitstream *stream, int *TrailingOnes, int *TotalCoeff);
-
-/**
-This function decode a VLC table with 2 output.
-\param "stream" "Pointer to the AVCDecBitstream."
-\param "lentab" "Table for code length."
-\param "codtab" "Table for code value."
-\param "tabwidth" "Width of the table or alphabet size of the first output."
-\param "tabheight" "Height of the table or alphabet size of the second output."
-\param "code1" "Pointer to the first output."
-\param "code2" "Pointer to the second output."
-\return "AVCDEC_SUCCESS for success."
-*/
-AVCDec_Status code_from_bitstream_2d(AVCDecBitstream *stream, int *lentab, int *codtab, int tabwidth,
- int tabheight, int *code1, int *code2);
-
-/**
-This function decodes the level_prefix VLC value as in Table 9-6.
-\param "stream" "Pointer to the AVCDecBitstream."
-\param "code" "Pointer to the output."
-\return "AVCDEC_SUCCESS for success."
-*/
-AVCDec_Status ce_LevelPrefix(AVCDecBitstream *stream, uint *code);
-
-/**
-This function decodes total_zeros VLC syntax as in Table 9-7 and 9-8.
-\param "stream" "Pointer to the AVCDecBitstream."
-\param "code" "Pointer to the output."
-\param "TotalCoeff" "Context parameter."
-\return "AVCDEC_SUCCESS for success."
-*/
-AVCDec_Status ce_TotalZeros(AVCDecBitstream *stream, int *code, int TotalCoeff);
-
-/**
-This function decodes total_zeros VLC syntax for chroma DC as in Table 9-9.
-\param "stream" "Pointer to the AVCDecBitstream."
-\param "code" "Pointer to the output."
-\param "TotalCoeff" "Context parameter."
-\return "AVCDEC_SUCCESS for success."
-*/
-AVCDec_Status ce_TotalZerosChromaDC(AVCDecBitstream *stream, int *code, int TotalCoeff);
-
-/**
-This function decodes run_before VLC syntax as in Table 9-10.
-\param "stream" "Pointer to the AVCDecBitstream."
-\param "code" "Pointer to the output."
-\param "zeroLeft" "Context parameter."
-\return "AVCDEC_SUCCESS for success."
-*/
-AVCDec_Status ce_RunBefore(AVCDecBitstream *stream, int *code, int zeroLeft);
-
-/*----------- header.c -------------------*/
-/**
-This function parses vui_parameters.
-\param "decvid" "Pointer to AVCDecObject."
-\param "stream" "Pointer to AVCDecBitstream."
-\return "AVCDEC_SUCCESS or AVCDEC_FAIL."
-*/
-AVCDec_Status vui_parameters(AVCDecObject *decvid, AVCDecBitstream *stream, AVCSeqParamSet *currSPS);
-AVCDec_Status sei_payload(AVCDecObject *decvid, AVCDecBitstream *stream, uint payloadType, uint payloadSize);
-
-AVCDec_Status buffering_period(AVCDecObject *decvid, AVCDecBitstream *stream);
-AVCDec_Status pic_timing(AVCDecObject *decvid, AVCDecBitstream *stream);
-AVCDec_Status recovery_point(AVCDecObject *decvid, AVCDecBitstream *stream);
-AVCDec_Status dec_ref_pic_marking_repetition(AVCDecObject *decvid, AVCDecBitstream *stream);
-AVCDec_Status motion_constrained_slice_group_set(AVCDecObject *decvid, AVCDecBitstream *stream);
-
-
-/**
-This function parses hrd_parameters.
-\param "decvid" "Pointer to AVCDecObject."
-\param "stream" "Pointer to AVCDecBitstream."
-\return "AVCDEC_SUCCESS or AVCDEC_FAIL."
-*/
-AVCDec_Status hrd_parameters(AVCDecObject *decvid, AVCDecBitstream *stream, AVCHRDParams *HRDParam);
-
-/**
-This function decodes the syntax in sequence parameter set slice and fill up the AVCSeqParamSet
-structure.
-\param "decvid" "Pointer to AVCDecObject."
-\param "video" "Pointer to AVCCommonObj."
-\param "stream" "Pointer to AVCDecBitstream."
-\return "AVCDEC_SUCCESS or AVCDEC_FAIL."
-*/
-AVCDec_Status DecodeSPS(AVCDecObject *decvid, AVCDecBitstream *stream);
-
-/**
-This function decodes the syntax in picture parameter set and fill up the AVCPicParamSet
-structure.
-\param "decvid" "Pointer to AVCDecObject."
-\param "video" "Pointer to AVCCommonObj."
-\param "stream" "Pointer to AVCDecBitstream."
-\return "AVCDEC_SUCCESS or AVCDEC_FAIL."
-*/
-AVCDec_Status DecodePPS(AVCDecObject *decvid, AVCCommonObj *video, AVCDecBitstream *stream);
-AVCDec_Status DecodeSEI(AVCDecObject *decvid, AVCDecBitstream *stream);
-
-/**
-This function decodes slice header, calls related functions such as
-reference picture list reordering, prediction weight table, decode ref marking.
-See FirstPartOfSliceHeader() and RestOfSliceHeader() in JM.
-\param "decvid" "Pointer to AVCDecObject."
-\param "video" "Pointer to AVCCommonObj."
-\param "stream" "Pointer to AVCDecBitstream."
-\return "AVCDEC_SUCCESS for success and AVCDEC_FAIL otherwise."
-*/
-AVCDec_Status DecodeSliceHeader(AVCDecObject *decvid, AVCCommonObj *video, AVCDecBitstream *stream);
-
-/**
-This function performes necessary operations to create dummy frames when
-there is a gap in frame_num.
-\param "video" "Pointer to AVCCommonObj."
-\return "AVCDEC_SUCCESS for success and AVCDEC_FAIL otherwise."
-*/
-AVCDec_Status fill_frame_num_gap(AVCHandle *avcHandle, AVCCommonObj *video);
-
-/**
-This function decodes ref_pic_list_reordering related syntax and fill up the AVCSliceHeader
-structure.
-\param "video" "Pointer to AVCCommonObj."
-\param "stream" "Pointer to AVCDecBitstream."
-\param "sliceHdr" "Pointer to AVCSliceHdr."
-\param "slice_type" "Value of slice_type - 5 if greater than 5."
-\return "AVCDEC_SUCCESS for success and AVCDEC_FAIL otherwise."
-*/
-AVCDec_Status ref_pic_list_reordering(AVCCommonObj *video, AVCDecBitstream *stream, AVCSliceHeader *sliceHdr, int slice_type);
-
-/**
-This function decodes dec_ref_pic_marking related syntax and fill up the AVCSliceHeader
-structure.
-\param "video" "Pointer to AVCCommonObj."
-\param "stream" "Pointer to AVCDecBitstream."
-\param "sliceHdr" "Pointer to AVCSliceHdr."
-\return "AVCDEC_SUCCESS for success and AVCDEC_FAIL otherwise."
-*/
-AVCDec_Status dec_ref_pic_marking(AVCCommonObj *video, AVCDecBitstream *stream, AVCSliceHeader *sliceHdr);
-
-/**
-This function performs POC related operation prior to decoding a picture
-\param "video" "Pointer to AVCCommonObj."
-\return "AVCDEC_SUCCESS for success and AVCDEC_FAIL otherwise."
-See also PostPOC() for initialization of some variables.
-*/
-AVCDec_Status DecodePOC(AVCCommonObj *video);
-
-
-
-/*------------ residual.c ------------------*/
-/**
-This function decodes the intra pcm data and fill it in the corresponding location
-on the current picture.
-\param "video" "Pointer to AVCCommonObj."
-\param "stream" "Pointer to AVCDecBitstream."
-*/
-AVCDec_Status DecodeIntraPCM(AVCCommonObj *video, AVCDecBitstream *stream);
-
-/**
-This function performs residual syntax decoding as well as quantization and transformation of
-the decoded coefficients. See subclause 7.3.5.3.
-\param "video" "Pointer to AVCDecObject."
-\param "currMB" "Pointer to current macroblock."
-*/
-AVCDec_Status residual(AVCDecObject *video, AVCMacroblock *currMB);
-
-/**
-This function performs CAVLC syntax decoding to get the run and level information of the coefficients.
-\param "video" "Pointer to AVCDecObject."
-\param "type" "One of AVCResidualType for a particular 4x4 block."
-\param "bx" "Horizontal block index."
-\param "by" "Vertical block index."
-\param "level" "Pointer to array of level for output."
-\param "run" "Pointer to array of run for output."
-\param "numcoeff" "Pointer to the total number of nonzero coefficients."
-\return "AVCDEC_SUCCESS for success."
-*/
-AVCDec_Status residual_block_cavlc(AVCDecObject *video, int nC, int maxNumCoeff,
- int *level, int *run, int *numcoeff);
-
-#endif /* _AVCDEC_LIB_H_ */
diff --git a/media/libstagefright/codecs/avc/dec/src/header.cpp b/media/libstagefright/codecs/avc/dec/src/header.cpp
deleted file mode 100644
index 8681e2b..0000000
--- a/media/libstagefright/codecs/avc/dec/src/header.cpp
+++ /dev/null
@@ -1,1391 +0,0 @@
-/* ------------------------------------------------------------------
- * 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 "avcdec_lib.h"
-#include "avcdec_bitstream.h"
-#include "avcdec_api.h"
-
-/** see subclause 7.4.2.1 */
-AVCDec_Status DecodeSPS(AVCDecObject *decvid, AVCDecBitstream *stream)
-{
- AVCDec_Status status = AVCDEC_SUCCESS;
- AVCSeqParamSet *seqParam;
- uint temp;
- int i;
- uint profile_idc, constrained_set0_flag, constrained_set1_flag, constrained_set2_flag;
- uint level_idc, seq_parameter_set_id;
- void *userData = decvid->avcHandle->userData;
- AVCHandle *avcHandle = decvid->avcHandle;
-
- DEBUG_LOG(userData, AVC_LOGTYPE_INFO, "DecodeSPS", -1, -1);
-
- BitstreamReadBits(stream, 8, &profile_idc);
- BitstreamRead1Bit(stream, &constrained_set0_flag);
-// if (profile_idc != 66 && constrained_set0_flag != 1)
-// {
-// return AVCDEC_FAIL;
-// }
- BitstreamRead1Bit(stream, &constrained_set1_flag);
- BitstreamRead1Bit(stream, &constrained_set2_flag);
- BitstreamReadBits(stream, 5, &temp);
- BitstreamReadBits(stream, 8, &level_idc);
- if (level_idc > 51)
- {
- return AVCDEC_FAIL;
- }
- if (mapLev2Idx[level_idc] == 255)
- {
- return AVCDEC_FAIL;
- }
- ue_v(stream, &seq_parameter_set_id);
-
- if (seq_parameter_set_id > 31)
- {
- return AVCDEC_FAIL;
- }
-
- /* Allocate sequence param set for seqParams[seq_parameter_set_id]. */
- if (decvid->seqParams[seq_parameter_set_id] == NULL) /* allocate seqParams[id] */
- {
- decvid->seqParams[seq_parameter_set_id] =
- (AVCSeqParamSet*) avcHandle->CBAVC_Malloc(userData, sizeof(AVCSeqParamSet), DEFAULT_ATTR);
-
- if (decvid->seqParams[seq_parameter_set_id] == NULL)
- {
- return AVCDEC_MEMORY_FAIL;
- }
- }
-
- DEBUG_LOG(userData, AVC_LOGTYPE_INFO, "done alloc seqParams", -1, -1);
-
- seqParam = decvid->seqParams[seq_parameter_set_id];
-
- seqParam->profile_idc = profile_idc;
- seqParam->constrained_set0_flag = constrained_set0_flag;
- seqParam->constrained_set1_flag = constrained_set1_flag;
- seqParam->constrained_set2_flag = constrained_set2_flag;
- seqParam->level_idc = level_idc;
- seqParam->seq_parameter_set_id = seq_parameter_set_id;
-
- /* continue decoding SPS */
- ue_v(stream, &(seqParam->log2_max_frame_num_minus4));
-
- if (seqParam->log2_max_frame_num_minus4 > 12)
- {
- return AVCDEC_FAIL;
- }
-
- ue_v(stream, &(seqParam->pic_order_cnt_type));
-
- DEBUG_LOG(userData, AVC_LOGTYPE_INFO, "check point 1", seqParam->log2_max_frame_num_minus4, seqParam->pic_order_cnt_type);
-
- if (seqParam->pic_order_cnt_type == 0)
- {
- ue_v(stream, &(seqParam->log2_max_pic_order_cnt_lsb_minus4));
- }
- else if (seqParam->pic_order_cnt_type == 1)
- { // MC_CHECK
- BitstreamRead1Bit(stream, (uint*)&(seqParam->delta_pic_order_always_zero_flag));
- se_v32bit(stream, &(seqParam->offset_for_non_ref_pic));
- se_v32bit(stream, &(seqParam->offset_for_top_to_bottom_field));
- ue_v(stream, &(seqParam->num_ref_frames_in_pic_order_cnt_cycle));
-
- for (i = 0; i < (int)(seqParam->num_ref_frames_in_pic_order_cnt_cycle); i++)
- {
- se_v32bit(stream, &(seqParam->offset_for_ref_frame[i]));
- }
- }
-
- ue_v(stream, &(seqParam->num_ref_frames));
-
- if (seqParam->num_ref_frames > 16)
- {
- return AVCDEC_FAIL;
- }
-
- DEBUG_LOG(userData, AVC_LOGTYPE_INFO, "check point 2", seqParam->num_ref_frames, -1);
-
- BitstreamRead1Bit(stream, (uint*)&(seqParam->gaps_in_frame_num_value_allowed_flag));
- ue_v(stream, &(seqParam->pic_width_in_mbs_minus1));
-
- DEBUG_LOG(userData, AVC_LOGTYPE_INFO, "picwidth", seqParam->pic_width_in_mbs_minus1, -1);
-
- ue_v(stream, &(seqParam->pic_height_in_map_units_minus1));
-
- DEBUG_LOG(userData, AVC_LOGTYPE_INFO, "picwidth", seqParam->pic_height_in_map_units_minus1, -1);
-
- BitstreamRead1Bit(stream, (uint*)&(seqParam->frame_mbs_only_flag));
-
- seqParam->mb_adaptive_frame_field_flag = 0; /* default value */
- if (!seqParam->frame_mbs_only_flag)
- {
- BitstreamRead1Bit(stream, (uint*)&(seqParam->mb_adaptive_frame_field_flag));
- }
-
- DEBUG_LOG(userData, AVC_LOGTYPE_INFO, "check point 3", seqParam->frame_mbs_only_flag, -1);
-
- BitstreamRead1Bit(stream, (uint*)&(seqParam->direct_8x8_inference_flag));
-
- DEBUG_LOG(userData, AVC_LOGTYPE_INFO, "check point 4", seqParam->direct_8x8_inference_flag, -1);
-
- BitstreamRead1Bit(stream, (uint*)&(seqParam->frame_cropping_flag));
- seqParam->frame_crop_left_offset = 0; /* default value */
- seqParam->frame_crop_right_offset = 0;/* default value */
- seqParam->frame_crop_top_offset = 0;/* default value */
- seqParam->frame_crop_bottom_offset = 0;/* default value */
- if (seqParam->frame_cropping_flag)
- {
- ue_v(stream, &(seqParam->frame_crop_left_offset));
- ue_v(stream, &(seqParam->frame_crop_right_offset));
- ue_v(stream, &(seqParam->frame_crop_top_offset));
- ue_v(stream, &(seqParam->frame_crop_bottom_offset));
- }
-
- DEBUG_LOG(userData, AVC_LOGTYPE_INFO, "check point 5", seqParam->frame_cropping_flag, -1);
-
- BitstreamRead1Bit(stream, (uint*)&(seqParam->vui_parameters_present_flag));
- if (seqParam->vui_parameters_present_flag)
- {
- status = vui_parameters(decvid, stream, seqParam);
- if (status != AVCDEC_SUCCESS)
- {
- return AVCDEC_FAIL;
- }
- }
-
- return status;
-}
-
-
-AVCDec_Status vui_parameters(AVCDecObject *decvid, AVCDecBitstream *stream, AVCSeqParamSet *currSPS)
-{
- uint temp;
- uint temp32;
- uint aspect_ratio_idc, overscan_appopriate_flag, video_format, video_full_range_flag;
- /* aspect_ratio_info_present_flag */
- BitstreamRead1Bit(stream, &temp);
- if (temp)
- {
- BitstreamReadBits(stream, 8, &aspect_ratio_idc);
- if (aspect_ratio_idc == 255)
- {
- /* sar_width */
- BitstreamReadBits(stream, 16, &temp);
- /* sar_height */
- BitstreamReadBits(stream, 16, &temp);
- }
- }
- /* overscan_info_present */
- BitstreamRead1Bit(stream, &temp);
- if (temp)
- {
- BitstreamRead1Bit(stream, &overscan_appopriate_flag);
- }
- /* video_signal_type_present_flag */
- BitstreamRead1Bit(stream, &temp);
- if (temp)
- {
- BitstreamReadBits(stream, 3, &video_format);
- BitstreamRead1Bit(stream, &video_full_range_flag);
- /* colour_description_present_flag */
- BitstreamRead1Bit(stream, &temp);
- if (temp)
- {
- /* colour_primaries */
- BitstreamReadBits(stream, 8, &temp);
- /* transfer_characteristics */
- BitstreamReadBits(stream, 8, &temp);
- /* matrix coefficients */
- BitstreamReadBits(stream, 8, &temp);
- }
- }
- /* chroma_loc_info_present_flag */
- BitstreamRead1Bit(stream, &temp);
- if (temp)
- {
- /* chroma_sample_loc_type_top_field */
- ue_v(stream, &temp);
- /* chroma_sample_loc_type_bottom_field */
- ue_v(stream, &temp);
- }
-
- /* timing_info_present_flag*/
- BitstreamRead1Bit(stream, &temp);
- if (temp)
- {
- /* num_unit_in_tick*/
- BitstreamReadBits(stream, 32, &temp32);
- /* time_scale */
- BitstreamReadBits(stream, 32, &temp32);
- /* fixed_frame_rate_flag */
- BitstreamRead1Bit(stream, &temp);
- }
-
- /* nal_hrd_parameters_present_flag */
- BitstreamRead1Bit(stream, &temp);
- currSPS->vui_parameters.nal_hrd_parameters_present_flag = temp;
- if (temp)
- {
- hrd_parameters(decvid, stream, &(currSPS->vui_parameters.nal_hrd_parameters));
- }
- /* vcl_hrd_parameters_present_flag*/
- BitstreamRead1Bit(stream, &temp);
- currSPS->vui_parameters.vcl_hrd_parameters_present_flag = temp;
- if (temp)
- {
- hrd_parameters(decvid, stream, &(currSPS->vui_parameters.vcl_hrd_parameters));
- }
- if (currSPS->vui_parameters.nal_hrd_parameters_present_flag || currSPS->vui_parameters.vcl_hrd_parameters_present_flag)
- {
- /* low_delay_hrd_flag */
- BitstreamRead1Bit(stream, &temp);
- }
- /* pic_struct_present_flag */
- BitstreamRead1Bit(stream, &temp);
- currSPS->vui_parameters.pic_struct_present_flag = temp;
- /* bitstream_restriction_flag */
- BitstreamRead1Bit(stream, &temp);
- if (temp)
- {
- /* motion_vectors_over_pic_boundaries_flag */
- BitstreamRead1Bit(stream, &temp);
- /* max_bytes_per_pic_denom */
- ue_v(stream, &temp);
- /* max_bits_per_mb_denom */
- ue_v(stream, &temp);
- /* log2_max_mv_length_horizontal */
- ue_v(stream, &temp);
- /* log2_max_mv_length_vertical */
- ue_v(stream, &temp);
- /* num_reorder_frames */
- ue_v(stream, &temp);
- /* max_dec_frame_buffering */
- ue_v(stream, &temp);
- }
- return AVCDEC_SUCCESS;
-}
-AVCDec_Status hrd_parameters(AVCDecObject *decvid, AVCDecBitstream *stream, AVCHRDParams *HRDParam)
-{
- OSCL_UNUSED_ARG(decvid);
- uint temp;
- uint cpb_cnt_minus1;
- uint i;
- ue_v(stream, &cpb_cnt_minus1);
- HRDParam->cpb_cnt_minus1 = cpb_cnt_minus1;
- /* bit_rate_scale */
- BitstreamReadBits(stream, 4, &temp);
- /* cpb_size_scale */
- BitstreamReadBits(stream, 4, &temp);
- for (i = 0; i <= cpb_cnt_minus1; i++)
- {
- /* bit_rate_value_minus1[i] */
- ue_v(stream, &temp);
- /* cpb_size_value_minus1[i] */
- ue_v(stream, &temp);
- /* cbr_flag[i] */
- ue_v(stream, &temp);
- }
- /* initial_cpb_removal_delay_length_minus1 */
- BitstreamReadBits(stream, 5, &temp);
- /* cpb_removal_delay_length_minus1 */
- BitstreamReadBits(stream, 5, &temp);
- HRDParam->cpb_removal_delay_length_minus1 = temp;
- /* dpb_output_delay_length_minus1 */
- BitstreamReadBits(stream, 5, &temp);
- HRDParam->dpb_output_delay_length_minus1 = temp;
- /* time_offset_length */
- BitstreamReadBits(stream, 5, &temp);
- HRDParam->time_offset_length = temp;
- return AVCDEC_SUCCESS;
-}
-
-
-/** see subclause 7.4.2.2 */
-AVCDec_Status DecodePPS(AVCDecObject *decvid, AVCCommonObj *video, AVCDecBitstream *stream)
-{
- AVCPicParamSet *picParam;
- AVCDec_Status status;
- int i, iGroup, numBits;
- int PicWidthInMbs, PicHeightInMapUnits, PicSizeInMapUnits;
- uint pic_parameter_set_id, seq_parameter_set_id;
- void *userData = decvid->avcHandle->userData;
- AVCHandle *avcHandle = decvid->avcHandle;
-
- ue_v(stream, &pic_parameter_set_id);
- if (pic_parameter_set_id > 255)
- {
- return AVCDEC_FAIL;
- }
-
- ue_v(stream, &seq_parameter_set_id);
-
- if (seq_parameter_set_id > 31)
- {
- return AVCDEC_FAIL;
- }
-
- /* 2.1 if picParams[pic_param_set_id] is NULL, allocate it. */
- if (decvid->picParams[pic_parameter_set_id] == NULL)
- {
- decvid->picParams[pic_parameter_set_id] =
- (AVCPicParamSet*)avcHandle->CBAVC_Malloc(userData, sizeof(AVCPicParamSet), DEFAULT_ATTR);
- if (decvid->picParams[pic_parameter_set_id] == NULL)
- {
- return AVCDEC_MEMORY_FAIL;
- }
-
- decvid->picParams[pic_parameter_set_id]->slice_group_id = NULL;
- }
-
- video->currPicParams = picParam = decvid->picParams[pic_parameter_set_id];
- picParam->seq_parameter_set_id = seq_parameter_set_id;
- picParam->pic_parameter_set_id = pic_parameter_set_id;
-
- BitstreamRead1Bit(stream, (uint*)&(picParam->entropy_coding_mode_flag));
- if (picParam->entropy_coding_mode_flag)
- {
- status = AVCDEC_FAIL;
- goto clean_up;
- }
- BitstreamRead1Bit(stream, (uint*)&(picParam->pic_order_present_flag));
- ue_v(stream, &(picParam->num_slice_groups_minus1));
-
- if (picParam->num_slice_groups_minus1 > MAX_NUM_SLICE_GROUP - 1)
- {
- status = AVCDEC_FAIL;
- goto clean_up;
- }
-
- picParam->slice_group_change_rate_minus1 = 0; /* default value */
- if (picParam->num_slice_groups_minus1 > 0)
- {
- ue_v(stream, &(picParam->slice_group_map_type));
- if (picParam->slice_group_map_type == 0)
- {
- for (iGroup = 0; iGroup <= (int)picParam->num_slice_groups_minus1; iGroup++)
- {
- ue_v(stream, &(picParam->run_length_minus1[iGroup]));
- }
- }
- else if (picParam->slice_group_map_type == 2)
- { // MC_CHECK <= or <
- for (iGroup = 0; iGroup < (int)picParam->num_slice_groups_minus1; iGroup++)
- {
- ue_v(stream, &(picParam->top_left[iGroup]));
- ue_v(stream, &(picParam->bottom_right[iGroup]));
- }
- }
- else if (picParam->slice_group_map_type == 3 ||
- picParam->slice_group_map_type == 4 ||
- picParam->slice_group_map_type == 5)
- {
- BitstreamRead1Bit(stream, (uint*)&(picParam->slice_group_change_direction_flag));
- ue_v(stream, &(picParam->slice_group_change_rate_minus1));
- }
- else if (picParam->slice_group_map_type == 6)
- {
- ue_v(stream, &(picParam->pic_size_in_map_units_minus1));
-
- numBits = 0;/* ceil(log2(num_slice_groups_minus1+1)) bits */
- i = picParam->num_slice_groups_minus1;
- while (i > 0)
- {
- numBits++;
- i >>= 1;
- }
-
- i = picParam->seq_parameter_set_id;
- if (decvid->seqParams[i] == NULL)
- {
- status = AVCDEC_FAIL;
- goto clean_up;
- }
-
-
- PicWidthInMbs = decvid->seqParams[i]->pic_width_in_mbs_minus1 + 1;
- PicHeightInMapUnits = decvid->seqParams[i]->pic_height_in_map_units_minus1 + 1 ;
- PicSizeInMapUnits = PicWidthInMbs * PicHeightInMapUnits ;
-
- /* information has to be consistent with the seq_param */
- if ((int)picParam->pic_size_in_map_units_minus1 != PicSizeInMapUnits - 1)
- {
- status = AVCDEC_FAIL;
- goto clean_up;
- }
-
- if (picParam->slice_group_id)
- {
- avcHandle->CBAVC_Free(userData, (int)picParam->slice_group_id);
- }
- picParam->slice_group_id = (uint*)avcHandle->CBAVC_Malloc(userData, sizeof(uint) * PicSizeInMapUnits, DEFAULT_ATTR);
- if (picParam->slice_group_id == NULL)
- {
- status = AVCDEC_MEMORY_FAIL;
- goto clean_up;
- }
-
- for (i = 0; i < PicSizeInMapUnits; i++)
- {
- BitstreamReadBits(stream, numBits, &(picParam->slice_group_id[i]));
- }
- }
-
- }
-
- ue_v(stream, &(picParam->num_ref_idx_l0_active_minus1));
- if (picParam->num_ref_idx_l0_active_minus1 > 31)
- {
- status = AVCDEC_FAIL; /* out of range */
- goto clean_up;
- }
-
- ue_v(stream, &(picParam->num_ref_idx_l1_active_minus1));
- if (picParam->num_ref_idx_l1_active_minus1 > 31)
- {
- status = AVCDEC_FAIL; /* out of range */
- goto clean_up;
- }
-
- BitstreamRead1Bit(stream, (uint*)&(picParam->weighted_pred_flag));
- BitstreamReadBits(stream, 2, &(picParam->weighted_bipred_idc));
- if (picParam->weighted_bipred_idc > 2)
- {
- status = AVCDEC_FAIL; /* out of range */
- goto clean_up;
- }
-
- se_v(stream, &(picParam->pic_init_qp_minus26));
- if (picParam->pic_init_qp_minus26 < -26 || picParam->pic_init_qp_minus26 > 25)
- {
- status = AVCDEC_FAIL; /* out of range */
- goto clean_up;
- }
-
- se_v(stream, &(picParam->pic_init_qs_minus26));
- if (picParam->pic_init_qs_minus26 < -26 || picParam->pic_init_qs_minus26 > 25)
- {
- status = AVCDEC_FAIL; /* out of range */
- goto clean_up;
- }
-
- se_v(stream, &(picParam->chroma_qp_index_offset));
- if (picParam->chroma_qp_index_offset < -12 || picParam->chroma_qp_index_offset > 12)
- {
- status = AVCDEC_FAIL; /* out of range */
- status = AVCDEC_FAIL; /* out of range */
- goto clean_up;
- }
-
- BitstreamReadBits(stream, 3, &pic_parameter_set_id);
- picParam->deblocking_filter_control_present_flag = pic_parameter_set_id >> 2;
- picParam->constrained_intra_pred_flag = (pic_parameter_set_id >> 1) & 1;
- picParam->redundant_pic_cnt_present_flag = pic_parameter_set_id & 1;
-
- return AVCDEC_SUCCESS;
-clean_up:
- if (decvid->picParams[pic_parameter_set_id])
- {
- if (picParam->slice_group_id)
- {
- avcHandle->CBAVC_Free(userData, (int)picParam->slice_group_id);
- }
- decvid->picParams[pic_parameter_set_id]->slice_group_id = NULL;
- avcHandle->CBAVC_Free(userData, (int)decvid->picParams[pic_parameter_set_id]);
- decvid->picParams[pic_parameter_set_id] = NULL;
- return status;
- }
- return AVCDEC_SUCCESS;
-}
-
-
-/* FirstPartOfSliceHeader();
- RestOfSliceHeader() */
-/** see subclause 7.4.3 */
-AVCDec_Status DecodeSliceHeader(AVCDecObject *decvid, AVCCommonObj *video, AVCDecBitstream *stream)
-{
- AVCSliceHeader *sliceHdr = video->sliceHdr;
- AVCPicParamSet *currPPS;
- AVCSeqParamSet *currSPS;
- AVCDec_Status status;
- uint idr_pic_id;
- int slice_type, temp, i;
-
- ue_v(stream, &(sliceHdr->first_mb_in_slice));
- ue_v(stream, (uint*)&slice_type);
-
- if (sliceHdr->first_mb_in_slice != 0)
- {
- if ((int)sliceHdr->slice_type >= 5 && slice_type != (int)sliceHdr->slice_type - 5)
- {
- return AVCDEC_FAIL; /* slice type doesn't follow the first slice in the picture */
- }
- }
- sliceHdr->slice_type = (AVCSliceType) slice_type;
- if (slice_type > 4)
- {
- slice_type -= 5;
- }
-
- if (slice_type == 1 || slice_type > 2)
- {
- return AVCDEC_FAIL;
- }
-
- video->slice_type = (AVCSliceType) slice_type;
-
- ue_v(stream, &(sliceHdr->pic_parameter_set_id));
- /* end FirstPartSliceHeader() */
- /* begin RestOfSliceHeader() */
- /* after getting pic_parameter_set_id, we have to load corresponding SPS and PPS */
- if (sliceHdr->pic_parameter_set_id > 255)
- {
- return AVCDEC_FAIL;
- }
-
- if (decvid->picParams[sliceHdr->pic_parameter_set_id] == NULL)
- return AVCDEC_FAIL; /* PPS doesn't exist */
-
- currPPS = video->currPicParams = decvid->picParams[sliceHdr->pic_parameter_set_id];
-
- if (decvid->seqParams[currPPS->seq_parameter_set_id] == NULL)
- return AVCDEC_FAIL; /* SPS doesn't exist */
-
- currSPS = video->currSeqParams = decvid->seqParams[currPPS->seq_parameter_set_id];
-
- if (currPPS->seq_parameter_set_id != video->seq_parameter_set_id)
- {
- video->seq_parameter_set_id = currPPS->seq_parameter_set_id;
- status = (AVCDec_Status)AVCConfigureSequence(decvid->avcHandle, video, false);
- if (status != AVCDEC_SUCCESS)
- return status;
- video->level_idc = currSPS->level_idc;
- }
-
- /* derived variables from SPS */
- video->MaxFrameNum = 1 << (currSPS->log2_max_frame_num_minus4 + 4);
- // MC_OPTIMIZE
- video->PicWidthInMbs = currSPS->pic_width_in_mbs_minus1 + 1;
- video->PicWidthInSamplesL = video->PicWidthInMbs * 16 ;
- video->PicWidthInSamplesC = video->PicWidthInMbs * 8 ;
- video->PicHeightInMapUnits = currSPS->pic_height_in_map_units_minus1 + 1 ;
- video->PicSizeInMapUnits = video->PicWidthInMbs * video->PicHeightInMapUnits ;
- video->FrameHeightInMbs = (2 - currSPS->frame_mbs_only_flag) * video->PicHeightInMapUnits ;
-
- /* derived from PPS */
- video->SliceGroupChangeRate = currPPS->slice_group_change_rate_minus1 + 1;
-
- /* then we can continue decoding slice header */
-
- BitstreamReadBits(stream, currSPS->log2_max_frame_num_minus4 + 4, &(sliceHdr->frame_num));
-
- if (video->currFS == NULL && sliceHdr->frame_num != 0)
- {
- video->prevFrameNum = video->PrevRefFrameNum = sliceHdr->frame_num - 1;
- }
-
- if (!currSPS->frame_mbs_only_flag)
- {
- BitstreamRead1Bit(stream, &(sliceHdr->field_pic_flag));
- if (sliceHdr->field_pic_flag)
- {
- return AVCDEC_FAIL;
- }
- }
-
- /* derived variables from slice header*/
- video->PicHeightInMbs = video->FrameHeightInMbs;
- video->PicHeightInSamplesL = video->PicHeightInMbs * 16;
- video->PicHeightInSamplesC = video->PicHeightInMbs * 8;
- video->PicSizeInMbs = video->PicWidthInMbs * video->PicHeightInMbs;
-
- if (sliceHdr->first_mb_in_slice >= video->PicSizeInMbs)
- {
- return AVCDEC_FAIL;
- }
- video->MaxPicNum = video->MaxFrameNum;
- video->CurrPicNum = sliceHdr->frame_num;
-
-
- if (video->nal_unit_type == AVC_NALTYPE_IDR)
- {
- if (sliceHdr->frame_num != 0)
- {
- return AVCDEC_FAIL;
- }
- ue_v(stream, &idr_pic_id);
- }
-
- sliceHdr->delta_pic_order_cnt_bottom = 0; /* default value */
- sliceHdr->delta_pic_order_cnt[0] = 0; /* default value */
- sliceHdr->delta_pic_order_cnt[1] = 0; /* default value */
- if (currSPS->pic_order_cnt_type == 0)
- {
- BitstreamReadBits(stream, currSPS->log2_max_pic_order_cnt_lsb_minus4 + 4,
- &(sliceHdr->pic_order_cnt_lsb));
- video->MaxPicOrderCntLsb = 1 << (currSPS->log2_max_pic_order_cnt_lsb_minus4 + 4);
- if (sliceHdr->pic_order_cnt_lsb > video->MaxPicOrderCntLsb - 1)
- return AVCDEC_FAIL; /* out of range */
-
- if (currPPS->pic_order_present_flag)
- {
- se_v32bit(stream, &(sliceHdr->delta_pic_order_cnt_bottom));
- }
- }
- if (currSPS->pic_order_cnt_type == 1 && !currSPS->delta_pic_order_always_zero_flag)
- {
- se_v32bit(stream, &(sliceHdr->delta_pic_order_cnt[0]));
- if (currPPS->pic_order_present_flag)
- {
- se_v32bit(stream, &(sliceHdr->delta_pic_order_cnt[1]));
- }
- }
-
- sliceHdr->redundant_pic_cnt = 0; /* default value */
- if (currPPS->redundant_pic_cnt_present_flag)
- {
- // MC_CHECK
- ue_v(stream, &(sliceHdr->redundant_pic_cnt));
- if (sliceHdr->redundant_pic_cnt > 127) /* out of range */
- return AVCDEC_FAIL;
-
- if (sliceHdr->redundant_pic_cnt > 0) /* redundant picture */
- return AVCDEC_FAIL; /* not supported */
- }
- sliceHdr->num_ref_idx_l0_active_minus1 = currPPS->num_ref_idx_l0_active_minus1;
- sliceHdr->num_ref_idx_l1_active_minus1 = currPPS->num_ref_idx_l1_active_minus1;
-
- if (slice_type == AVC_P_SLICE)
- {
- BitstreamRead1Bit(stream, &(sliceHdr->num_ref_idx_active_override_flag));
- if (sliceHdr->num_ref_idx_active_override_flag)
- {
- ue_v(stream, &(sliceHdr->num_ref_idx_l0_active_minus1));
- }
- else /* the following condition is not allowed if the flag is zero */
- {
- if ((slice_type == AVC_P_SLICE) && currPPS->num_ref_idx_l0_active_minus1 > 15)
- {
- return AVCDEC_FAIL; /* not allowed */
- }
- }
- }
-
-
- if (sliceHdr->num_ref_idx_l0_active_minus1 > 15 ||
- sliceHdr->num_ref_idx_l1_active_minus1 > 15)
- {
- return AVCDEC_FAIL; /* not allowed */
- }
- /* if MbaffFrameFlag =1,
- max value of index is num_ref_idx_l0_active_minus1 for frame MBs and
- 2*sliceHdr->num_ref_idx_l0_active_minus1 + 1 for field MBs */
-
- /* ref_pic_list_reordering() */
- status = ref_pic_list_reordering(video, stream, sliceHdr, slice_type);
- if (status != AVCDEC_SUCCESS)
- {
- return status;
- }
-
-
- if (video->nal_ref_idc != 0)
- {
- dec_ref_pic_marking(video, stream, sliceHdr);
- }
- se_v(stream, &(sliceHdr->slice_qp_delta));
-
- video->QPy = 26 + currPPS->pic_init_qp_minus26 + sliceHdr->slice_qp_delta;
- if (video->QPy > 51 || video->QPy < 0)
- {
- video->QPy = AVC_CLIP3(0, 51, video->QPy);
-// return AVCDEC_FAIL;
- }
- video->QPc = mapQPi2QPc[AVC_CLIP3(0, 51, video->QPy + video->currPicParams->chroma_qp_index_offset)];
-
- video->QPy_div_6 = (video->QPy * 43) >> 8;
- video->QPy_mod_6 = video->QPy - 6 * video->QPy_div_6;
-
- video->QPc_div_6 = (video->QPc * 43) >> 8;
- video->QPc_mod_6 = video->QPc - 6 * video->QPc_div_6;
-
- sliceHdr->slice_alpha_c0_offset_div2 = 0;
- sliceHdr->slice_beta_offset_div_2 = 0;
- sliceHdr->disable_deblocking_filter_idc = 0;
- video->FilterOffsetA = video->FilterOffsetB = 0;
-
- if (currPPS->deblocking_filter_control_present_flag)
- {
- ue_v(stream, &(sliceHdr->disable_deblocking_filter_idc));
- if (sliceHdr->disable_deblocking_filter_idc > 2)
- {
- return AVCDEC_FAIL; /* out of range */
- }
- if (sliceHdr->disable_deblocking_filter_idc != 1)
- {
- se_v(stream, &(sliceHdr->slice_alpha_c0_offset_div2));
- if (sliceHdr->slice_alpha_c0_offset_div2 < -6 ||
- sliceHdr->slice_alpha_c0_offset_div2 > 6)
- {
- return AVCDEC_FAIL;
- }
- video->FilterOffsetA = sliceHdr->slice_alpha_c0_offset_div2 << 1;
-
- se_v(stream, &(sliceHdr->slice_beta_offset_div_2));
- if (sliceHdr->slice_beta_offset_div_2 < -6 ||
- sliceHdr->slice_beta_offset_div_2 > 6)
- {
- return AVCDEC_FAIL;
- }
- video->FilterOffsetB = sliceHdr->slice_beta_offset_div_2 << 1;
- }
- }
-
- if (currPPS->num_slice_groups_minus1 > 0 && currPPS->slice_group_map_type >= 3
- && currPPS->slice_group_map_type <= 5)
- {
- /* Ceil(Log2(PicSizeInMapUnits/(float)SliceGroupChangeRate + 1)) */
- temp = video->PicSizeInMapUnits / video->SliceGroupChangeRate;
- if (video->PicSizeInMapUnits % video->SliceGroupChangeRate)
- {
- temp++;
- }
- i = 0;
- temp++;
- while (temp)
- {
- temp >>= 1;
- i++;
- }
-
- BitstreamReadBits(stream, i, &(sliceHdr->slice_group_change_cycle));
- video->MapUnitsInSliceGroup0 =
- AVC_MIN(sliceHdr->slice_group_change_cycle * video->SliceGroupChangeRate, video->PicSizeInMapUnits);
- }
-
- return AVCDEC_SUCCESS;
-}
-
-
-AVCDec_Status fill_frame_num_gap(AVCHandle *avcHandle, AVCCommonObj *video)
-{
- AVCDec_Status status;
- int CurrFrameNum;
- int UnusedShortTermFrameNum;
- int tmp1 = video->sliceHdr->delta_pic_order_cnt[0];
- int tmp2 = video->sliceHdr->delta_pic_order_cnt[1];
- int tmp3 = video->CurrPicNum;
- int tmp4 = video->sliceHdr->adaptive_ref_pic_marking_mode_flag;
- UnusedShortTermFrameNum = (video->prevFrameNum + 1) % video->MaxFrameNum;
- CurrFrameNum = video->sliceHdr->frame_num;
-
- video->sliceHdr->delta_pic_order_cnt[0] = 0;
- video->sliceHdr->delta_pic_order_cnt[1] = 0;
- while (CurrFrameNum != UnusedShortTermFrameNum)
- {
- video->CurrPicNum = UnusedShortTermFrameNum;
- video->sliceHdr->frame_num = UnusedShortTermFrameNum;
-
- status = (AVCDec_Status)DPBInitBuffer(avcHandle, video);
- if (status != AVCDEC_SUCCESS) /* no buffer available */
- {
- return status;
- }
- DecodePOC(video);
- DPBInitPic(video, UnusedShortTermFrameNum);
-
-
- video->currFS->PicOrderCnt = video->PicOrderCnt;
- video->currFS->FrameNum = video->sliceHdr->frame_num;
-
- /* initialize everything to zero */
- video->currFS->IsOutputted = 0x01;
- video->currFS->IsReference = 3;
- video->currFS->IsLongTerm = 0;
- video->currFS->frame.isReference = TRUE;
- video->currFS->frame.isLongTerm = FALSE;
-
- video->sliceHdr->adaptive_ref_pic_marking_mode_flag = 0;
-
- status = (AVCDec_Status)StorePictureInDPB(avcHandle, video); // MC_CHECK check the return status
- if (status != AVCDEC_SUCCESS)
- {
- return AVCDEC_FAIL;
- }
- video->prevFrameNum = UnusedShortTermFrameNum;
- UnusedShortTermFrameNum = (UnusedShortTermFrameNum + 1) % video->MaxFrameNum;
- }
- video->sliceHdr->frame_num = CurrFrameNum;
- video->CurrPicNum = tmp3;
- video->sliceHdr->delta_pic_order_cnt[0] = tmp1;
- video->sliceHdr->delta_pic_order_cnt[1] = tmp2;
- video->sliceHdr->adaptive_ref_pic_marking_mode_flag = tmp4;
- return AVCDEC_SUCCESS;
-}
-
-/** see subclause 7.4.3.1 */
-AVCDec_Status ref_pic_list_reordering(AVCCommonObj *video, AVCDecBitstream *stream, AVCSliceHeader *sliceHdr, int slice_type)
-{
- int i;
-
- if (slice_type != AVC_I_SLICE)
- {
- BitstreamRead1Bit(stream, &(sliceHdr->ref_pic_list_reordering_flag_l0));
- if (sliceHdr->ref_pic_list_reordering_flag_l0)
- {
- i = 0;
- do
- {
- ue_v(stream, &(sliceHdr->reordering_of_pic_nums_idc_l0[i]));
- if (sliceHdr->reordering_of_pic_nums_idc_l0[i] == 0 ||
- sliceHdr->reordering_of_pic_nums_idc_l0[i] == 1)
- {
- ue_v(stream, &(sliceHdr->abs_diff_pic_num_minus1_l0[i]));
- if (sliceHdr->reordering_of_pic_nums_idc_l0[i] == 0 &&
- sliceHdr->abs_diff_pic_num_minus1_l0[i] > video->MaxPicNum / 2 - 1)
- {
- return AVCDEC_FAIL; /* out of range */
- }
- if (sliceHdr->reordering_of_pic_nums_idc_l0[i] == 1 &&
- sliceHdr->abs_diff_pic_num_minus1_l0[i] > video->MaxPicNum / 2 - 2)
- {
- return AVCDEC_FAIL; /* out of range */
- }
- }
- else if (sliceHdr->reordering_of_pic_nums_idc_l0[i] == 2)
- {
- ue_v(stream, &(sliceHdr->long_term_pic_num_l0[i]));
- }
- i++;
- }
- while (sliceHdr->reordering_of_pic_nums_idc_l0[i-1] != 3
- && i <= (int)sliceHdr->num_ref_idx_l0_active_minus1 + 1) ;
- }
- }
- return AVCDEC_SUCCESS;
-}
-
-/** see subclause 7.4.3.3 */
-AVCDec_Status dec_ref_pic_marking(AVCCommonObj *video, AVCDecBitstream *stream, AVCSliceHeader *sliceHdr)
-{
- int i;
- if (video->nal_unit_type == AVC_NALTYPE_IDR)
- {
- BitstreamRead1Bit(stream, &(sliceHdr->no_output_of_prior_pics_flag));
- BitstreamRead1Bit(stream, &(sliceHdr->long_term_reference_flag));
- if (sliceHdr->long_term_reference_flag == 0) /* used for short-term */
- {
- video->MaxLongTermFrameIdx = -1; /* no long-term frame indx */
- }
- else /* used for long-term */
- {
- video->MaxLongTermFrameIdx = 0;
- video->LongTermFrameIdx = 0;
- }
- }
- else
- {
- BitstreamRead1Bit(stream, &(sliceHdr->adaptive_ref_pic_marking_mode_flag));
- if (sliceHdr->adaptive_ref_pic_marking_mode_flag)
- {
- i = 0;
- do
- {
- ue_v(stream, &(sliceHdr->memory_management_control_operation[i]));
- if (sliceHdr->memory_management_control_operation[i] == 1 ||
- sliceHdr->memory_management_control_operation[i] == 3)
- {
- ue_v(stream, &(sliceHdr->difference_of_pic_nums_minus1[i]));
- }
- if (sliceHdr->memory_management_control_operation[i] == 2)
- {
- ue_v(stream, &(sliceHdr->long_term_pic_num[i]));
- }
- if (sliceHdr->memory_management_control_operation[i] == 3 ||
- sliceHdr->memory_management_control_operation[i] == 6)
- {
- ue_v(stream, &(sliceHdr->long_term_frame_idx[i]));
- }
- if (sliceHdr->memory_management_control_operation[i] == 4)
- {
- ue_v(stream, &(sliceHdr->max_long_term_frame_idx_plus1[i]));
- }
- i++;
- }
- while (sliceHdr->memory_management_control_operation[i-1] != 0 && i < MAX_DEC_REF_PIC_MARKING);
- if (i >= MAX_DEC_REF_PIC_MARKING)
- {
- return AVCDEC_FAIL; /* we're screwed!!, not enough memory */
- }
- }
- }
-
- return AVCDEC_SUCCESS;
-}
-
-/* see subclause 8.2.1 Decoding process for picture order count. */
-AVCDec_Status DecodePOC(AVCCommonObj *video)
-{
- AVCSeqParamSet *currSPS = video->currSeqParams;
- AVCSliceHeader *sliceHdr = video->sliceHdr;
- int i;
-
- switch (currSPS->pic_order_cnt_type)
- {
- case 0: /* POC MODE 0 , subclause 8.2.1.1 */
- if (video->nal_unit_type == AVC_NALTYPE_IDR)
- {
- video->prevPicOrderCntMsb = 0;
- video->prevPicOrderCntLsb = 0;
- }
-
- /* Calculate the MSBs of current picture */
- if (sliceHdr->pic_order_cnt_lsb < video->prevPicOrderCntLsb &&
- (video->prevPicOrderCntLsb - sliceHdr->pic_order_cnt_lsb) >= (video->MaxPicOrderCntLsb / 2))
- video->PicOrderCntMsb = video->prevPicOrderCntMsb + video->MaxPicOrderCntLsb;
- else if (sliceHdr->pic_order_cnt_lsb > video->prevPicOrderCntLsb &&
- (sliceHdr->pic_order_cnt_lsb - video->prevPicOrderCntLsb) > (video->MaxPicOrderCntLsb / 2))
- video->PicOrderCntMsb = video->prevPicOrderCntMsb - video->MaxPicOrderCntLsb;
- else
- video->PicOrderCntMsb = video->prevPicOrderCntMsb;
-
- /* JVT-I010 page 81 is different from JM7.3 */
-
-
- video->PicOrderCnt = video->TopFieldOrderCnt = video->PicOrderCntMsb + sliceHdr->pic_order_cnt_lsb;
- video->BottomFieldOrderCnt = video->TopFieldOrderCnt + sliceHdr->delta_pic_order_cnt_bottom;
-
- break;
-
-
- case 1: /* POC MODE 1, subclause 8.2.1.2 */
- /* calculate FrameNumOffset */
- if (video->nal_unit_type == AVC_NALTYPE_IDR)
- {
- video->prevFrameNumOffset = 0;
- video->FrameNumOffset = 0;
- }
- else if (video->prevFrameNum > sliceHdr->frame_num)
- {
- video->FrameNumOffset = video->prevFrameNumOffset + video->MaxFrameNum;
- }
- else
- {
- video->FrameNumOffset = video->prevFrameNumOffset;
- }
- /* calculate absFrameNum */
- if (currSPS->num_ref_frames_in_pic_order_cnt_cycle)
- {
- video->absFrameNum = video->FrameNumOffset + sliceHdr->frame_num;
- }
- else
- {
- video->absFrameNum = 0;
- }
-
- if (video->absFrameNum > 0 && video->nal_ref_idc == 0)
- {
- video->absFrameNum--;
- }
-
- /* derive picOrderCntCycleCnt and frameNumInPicOrderCntCycle */
- if (video->absFrameNum > 0)
- {
- video->picOrderCntCycleCnt = (video->absFrameNum - 1) / currSPS->num_ref_frames_in_pic_order_cnt_cycle;
- video->frameNumInPicOrderCntCycle = (video->absFrameNum - 1) % currSPS->num_ref_frames_in_pic_order_cnt_cycle;
- }
- /* derive expectedDeltaPerPicOrderCntCycle */
- video->expectedDeltaPerPicOrderCntCycle = 0;
- for (i = 0; i < (int)currSPS->num_ref_frames_in_pic_order_cnt_cycle; i++)
- {
- video->expectedDeltaPerPicOrderCntCycle += currSPS->offset_for_ref_frame[i];
- }
- /* derive expectedPicOrderCnt */
- if (video->absFrameNum)
- {
- video->expectedPicOrderCnt = video->picOrderCntCycleCnt * video->expectedDeltaPerPicOrderCntCycle;
- for (i = 0; i <= video->frameNumInPicOrderCntCycle; i++)
- {
- video->expectedPicOrderCnt += currSPS->offset_for_ref_frame[i];
- }
- }
- else
- {
- video->expectedPicOrderCnt = 0;
- }
-
- if (video->nal_ref_idc == 0)
- {
- video->expectedPicOrderCnt += currSPS->offset_for_non_ref_pic;
- }
- /* derive TopFieldOrderCnt and BottomFieldOrderCnt */
-
- video->TopFieldOrderCnt = video->expectedPicOrderCnt + sliceHdr->delta_pic_order_cnt[0];
- video->BottomFieldOrderCnt = video->TopFieldOrderCnt + currSPS->offset_for_top_to_bottom_field + sliceHdr->delta_pic_order_cnt[1];
-
- video->PicOrderCnt = AVC_MIN(video->TopFieldOrderCnt, video->BottomFieldOrderCnt);
-
-
- break;
-
-
- case 2: /* POC MODE 2, subclause 8.2.1.3 */
- if (video->nal_unit_type == AVC_NALTYPE_IDR)
- {
- video->FrameNumOffset = 0;
- }
- else if (video->prevFrameNum > sliceHdr->frame_num)
- {
- video->FrameNumOffset = video->prevFrameNumOffset + video->MaxFrameNum;
- }
- else
- {
- video->FrameNumOffset = video->prevFrameNumOffset;
- }
- /* derive tempPicOrderCnt, we just use PicOrderCnt */
- if (video->nal_unit_type == AVC_NALTYPE_IDR)
- {
- video->PicOrderCnt = 0;
- }
- else if (video->nal_ref_idc == 0)
- {
- video->PicOrderCnt = 2 * (video->FrameNumOffset + sliceHdr->frame_num) - 1;
- }
- else
- {
- video->PicOrderCnt = 2 * (video->FrameNumOffset + sliceHdr->frame_num);
- }
- video->TopFieldOrderCnt = video->BottomFieldOrderCnt = video->PicOrderCnt;
- break;
- default:
- return AVCDEC_FAIL;
- }
-
- return AVCDEC_SUCCESS;
-}
-
-
-AVCDec_Status DecodeSEI(AVCDecObject *decvid, AVCDecBitstream *stream)
-{
- OSCL_UNUSED_ARG(decvid);
- OSCL_UNUSED_ARG(stream);
- return AVCDEC_SUCCESS;
-}
-
-AVCDec_Status sei_payload(AVCDecObject *decvid, AVCDecBitstream *stream, uint payloadType, uint payloadSize)
-{
- AVCDec_Status status = AVCDEC_SUCCESS;
- uint i;
- switch (payloadType)
- {
- case 0:
- /* buffering period SEI */
- status = buffering_period(decvid, stream);
- break;
- case 1:
- /* picture timing SEI */
- status = pic_timing(decvid, stream);
- break;
- case 2:
-
- case 3:
-
- case 4:
-
- case 5:
-
- case 8:
-
- case 9:
-
- case 10:
-
- case 11:
-
- case 12:
-
- case 13:
-
- case 14:
-
- case 15:
-
- case 16:
-
- case 17:
- for (i = 0; i < payloadSize; i++)
- {
- BitstreamFlushBits(stream, 8);
- }
- break;
- case 6:
- /* recovery point SEI */
- status = recovery_point(decvid, stream);
- break;
- case 7:
- /* decoded reference picture marking repetition SEI */
- status = dec_ref_pic_marking_repetition(decvid, stream);
- break;
-
- case 18:
- /* motion-constrained slice group set SEI */
- status = motion_constrained_slice_group_set(decvid, stream);
- break;
- default:
- /* reserved_sei_message */
- for (i = 0; i < payloadSize; i++)
- {
- BitstreamFlushBits(stream, 8);
- }
- break;
- }
- BitstreamByteAlign(stream);
- return status;
-}
-
-AVCDec_Status buffering_period(AVCDecObject *decvid, AVCDecBitstream *stream)
-{
- AVCSeqParamSet *currSPS;
- uint seq_parameter_set_id;
- uint temp;
- uint i;
- ue_v(stream, &seq_parameter_set_id);
- if (seq_parameter_set_id > 31)
- {
- return AVCDEC_FAIL;
- }
-
-// decvid->common->seq_parameter_set_id = seq_parameter_set_id;
-
- currSPS = decvid->seqParams[seq_parameter_set_id];
- if (currSPS->vui_parameters.nal_hrd_parameters_present_flag)
- {
- for (i = 0; i <= currSPS->vui_parameters.nal_hrd_parameters.cpb_cnt_minus1; i++)
- {
- /* initial_cpb_removal_delay[i] */
- BitstreamReadBits(stream, currSPS->vui_parameters.nal_hrd_parameters.cpb_removal_delay_length_minus1 + 1, &temp);
- /*initial _cpb_removal_delay_offset[i] */
- BitstreamReadBits(stream, currSPS->vui_parameters.nal_hrd_parameters.cpb_removal_delay_length_minus1 + 1, &temp);
- }
- }
-
- if (currSPS->vui_parameters.vcl_hrd_parameters_present_flag)
- {
- for (i = 0; i <= currSPS->vui_parameters.vcl_hrd_parameters.cpb_cnt_minus1; i++)
- {
- /* initial_cpb_removal_delay[i] */
- BitstreamReadBits(stream, currSPS->vui_parameters.vcl_hrd_parameters.cpb_removal_delay_length_minus1 + 1, &temp);
- /*initial _cpb_removal_delay_offset[i] */
- BitstreamReadBits(stream, currSPS->vui_parameters.vcl_hrd_parameters.cpb_removal_delay_length_minus1 + 1, &temp);
- }
- }
-
- return AVCDEC_SUCCESS;
-}
-AVCDec_Status pic_timing(AVCDecObject *decvid, AVCDecBitstream *stream)
-{
- AVCSeqParamSet *currSPS;
- uint temp, NumClockTs = 0, time_offset_length = 24, full_timestamp_flag;
- uint i;
-
- currSPS = decvid->seqParams[decvid->common->seq_parameter_set_id];
-
- if (currSPS->vui_parameters.nal_hrd_parameters_present_flag)
- {
- BitstreamReadBits(stream, currSPS->vui_parameters.nal_hrd_parameters.cpb_removal_delay_length_minus1 + 1, &temp);
- BitstreamReadBits(stream, currSPS->vui_parameters.nal_hrd_parameters.dpb_output_delay_length_minus1 + 1, &temp);
- time_offset_length = currSPS->vui_parameters.nal_hrd_parameters.time_offset_length;
- }
- else if (currSPS->vui_parameters.vcl_hrd_parameters_present_flag)
- {
- BitstreamReadBits(stream, currSPS->vui_parameters.vcl_hrd_parameters.cpb_removal_delay_length_minus1 + 1, &temp);
- BitstreamReadBits(stream, currSPS->vui_parameters.vcl_hrd_parameters.dpb_output_delay_length_minus1 + 1, &temp);
- time_offset_length = currSPS->vui_parameters.vcl_hrd_parameters.time_offset_length;
- }
-
- if (currSPS->vui_parameters.pic_struct_present_flag)
- {
- /* pic_struct */
- BitstreamReadBits(stream, 4, &temp);
-
- switch (temp)
- {
- case 0:
- case 1:
- case 2:
- NumClockTs = 1;
- break;
- case 3:
- case 4:
- case 7:
- NumClockTs = 2;
- break;
- case 5:
- case 6:
- case 8:
- NumClockTs = 3;
- break;
- default:
- NumClockTs = 0;
- break;
- }
-
- for (i = 0; i < NumClockTs; i++)
- {
- /* clock_timestamp_flag[i] */
- BitstreamRead1Bit(stream, &temp);
- if (temp)
- {
- /* ct_type */
- BitstreamReadBits(stream, 2, &temp);
- /* nuit_field_based_flag */
- BitstreamRead1Bit(stream, &temp);
- /* counting_type */
- BitstreamReadBits(stream, 5, &temp);
- /* full_timestamp_flag */
- BitstreamRead1Bit(stream, &temp);
- full_timestamp_flag = temp;
- /* discontinuity_flag */
- BitstreamRead1Bit(stream, &temp);
- /* cnt_dropped_flag */
- BitstreamRead1Bit(stream, &temp);
- /* n_frames */
- BitstreamReadBits(stream, 8, &temp);
-
-
- if (full_timestamp_flag)
- {
- /* seconds_value */
- BitstreamReadBits(stream, 6, &temp);
- /* minutes_value */
- BitstreamReadBits(stream, 6, &temp);
- /* hours_value */
- BitstreamReadBits(stream, 5, &temp);
- }
- else
- {
- /* seconds_flag */
- BitstreamRead1Bit(stream, &temp);
- if (temp)
- {
- /* seconds_value */
- BitstreamReadBits(stream, 6, &temp);
- /* minutes_flag */
- BitstreamRead1Bit(stream, &temp);
- if (temp)
- {
- /* minutes_value */
- BitstreamReadBits(stream, 6, &temp);
-
- /* hourss_flag */
- BitstreamRead1Bit(stream, &temp);
-
- if (temp)
- {
- /* hours_value */
- BitstreamReadBits(stream, 5, &temp);
- }
-
- }
- }
- }
-
- if (time_offset_length)
- {
- /* time_offset */
- BitstreamReadBits(stream, time_offset_length, &temp);
- }
- else
- {
- /* time_offset */
- temp = 0;
- }
- }
- }
- }
- return AVCDEC_SUCCESS;
-}
-AVCDec_Status recovery_point(AVCDecObject *decvid, AVCDecBitstream *stream)
-{
- OSCL_UNUSED_ARG(decvid);
- uint temp;
- /* recover_frame_cnt */
- ue_v(stream, &temp);
- /* exact_match_flag */
- BitstreamRead1Bit(stream, &temp);
- /* broken_link_flag */
- BitstreamRead1Bit(stream, &temp);
- /* changing slic_group_idc */
- BitstreamReadBits(stream, 2, &temp);
- return AVCDEC_SUCCESS;
-}
-AVCDec_Status dec_ref_pic_marking_repetition(AVCDecObject *decvid, AVCDecBitstream *stream)
-{
- AVCSeqParamSet *currSPS;
- uint temp;
- currSPS = decvid->seqParams[decvid->common->seq_parameter_set_id];
- /* original_idr_flag */
- BitstreamRead1Bit(stream, &temp);
- /* original_frame_num */
- ue_v(stream, &temp);
- if (currSPS->frame_mbs_only_flag == 0)
- {
- /* original_field_pic_flag */
- BitstreamRead1Bit(stream, &temp);
- if (temp)
- {
- /* original_bottom_field_flag */
- BitstreamRead1Bit(stream, &temp);
- }
- }
-
- /* dec_ref_pic_marking(video,stream,sliceHdr); */
-
-
- return AVCDEC_SUCCESS;
-}
-AVCDec_Status motion_constrained_slice_group_set(AVCDecObject *decvid, AVCDecBitstream *stream)
-{
- OSCL_UNUSED_ARG(decvid);
- uint temp, i, numBits;
- /* num_slice_groups_in_set_minus1 */
- ue_v(stream, &temp);
-
- numBits = 0;/* ceil(log2(num_slice_groups_minus1+1)) bits */
- i = temp;
- while (i > 0)
- {
- numBits++;
- i >>= 1;
- }
- for (i = 0; i <= temp; i++)
- {
- /* slice_group_id */
- BitstreamReadBits(stream, numBits, &temp);
- }
- /* exact_sample_value_match_flag */
- BitstreamRead1Bit(stream, &temp);
- /* pan_scan_rect_flag */
- BitstreamRead1Bit(stream, &temp);
- if (temp)
- {
- /* pan_scan_rect_id */
- ue_v(stream, &temp);
- }
-
- return AVCDEC_SUCCESS;
-}
-
diff --git a/media/libstagefright/codecs/avc/dec/src/itrans.cpp b/media/libstagefright/codecs/avc/dec/src/itrans.cpp
deleted file mode 100644
index 02c550d..0000000
--- a/media/libstagefright/codecs/avc/dec/src/itrans.cpp
+++ /dev/null
@@ -1,307 +0,0 @@
-/* ------------------------------------------------------------------
- * 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 "avclib_common.h"
-
-/* input are in the first 16 elements of block,
- output must be in the location specified in Figure 8-6. */
-/* subclause 8.5.6 */
-void Intra16DCTrans(int16 *block, int Qq, int Rq)
-{
- int m0, m1, m2, m3;
- int j, offset;
- int16 *inout;
- int scale = dequant_coefres[Rq][0];
-
- inout = block;
- for (j = 0; j < 4; j++)
- {
- m0 = inout[0] + inout[4];
- m1 = inout[0] - inout[4];
- m2 = inout[8] + inout[12];
- m3 = inout[8] - inout[12];
-
-
- inout[0] = m0 + m2;
- inout[4] = m0 - m2;
- inout[8] = m1 - m3;
- inout[12] = m1 + m3;
- inout += 64;
- }
-
- inout = block;
-
- if (Qq >= 2) /* this way should be faster than JM */
- { /* they use (((m4*scale)<<(QPy/6))+2)>>2 for both cases. */
- Qq -= 2;
- for (j = 0; j < 4; j++)
- {
- m0 = inout[0] + inout[64];
- m1 = inout[0] - inout[64];
- m2 = inout[128] + inout[192];
- m3 = inout[128] - inout[192];
-
- inout[0] = ((m0 + m2) * scale) << Qq;
- inout[64] = ((m0 - m2) * scale) << Qq;
- inout[128] = ((m1 - m3) * scale) << Qq;
- inout[192] = ((m1 + m3) * scale) << Qq;
- inout += 4;
- }
- }
- else
- {
- Qq = 2 - Qq;
- offset = 1 << (Qq - 1);
-
- for (j = 0; j < 4; j++)
- {
- m0 = inout[0] + inout[64];
- m1 = inout[0] - inout[64];
- m2 = inout[128] + inout[192];
- m3 = inout[128] - inout[192];
-
- inout[0] = (((m0 + m2) * scale + offset) >> Qq);
- inout[64] = (((m0 - m2) * scale + offset) >> Qq);
- inout[128] = (((m1 - m3) * scale + offset) >> Qq);
- inout[192] = (((m1 + m3) * scale + offset) >> Qq);
- inout += 4;
- }
- }
-
- return ;
-}
-
-/* see subclase 8.5.8 */
-void itrans(int16 *block, uint8 *pred, uint8 *cur, int width)
-{
- int e0, e1, e2, e3; /* note, at every step of the calculation, these values */
- /* shall never exceed 16bit sign value, but we don't check */
- int i; /* to save the cycles. */
- int16 *inout;
-
- inout = block;
-
- for (i = 4; i > 0; i--)
- {
- e0 = inout[0] + inout[2];
- e1 = inout[0] - inout[2];
- e2 = (inout[1] >> 1) - inout[3];
- e3 = inout[1] + (inout[3] >> 1);
-
- inout[0] = e0 + e3;
- inout[1] = e1 + e2;
- inout[2] = e1 - e2;
- inout[3] = e0 - e3;
-
- inout += 16;
- }
-
- for (i = 4; i > 0; i--)
- {
- e0 = block[0] + block[32];
- e1 = block[0] - block[32];
- e2 = (block[16] >> 1) - block[48];
- e3 = block[16] + (block[48] >> 1);
-
- e0 += e3;
- e3 = (e0 - (e3 << 1)); /* e0-e3 */
- e1 += e2;
- e2 = (e1 - (e2 << 1)); /* e1-e2 */
- e0 += 32;
- e1 += 32;
- e2 += 32;
- e3 += 32;
-#ifdef USE_PRED_BLOCK
- e0 = pred[0] + (e0 >> 6);
- if ((uint)e0 > 0xFF) e0 = 0xFF & (~(e0 >> 31)); /* clip */
- e1 = pred[20] + (e1 >> 6);
- if ((uint)e1 > 0xFF) e1 = 0xFF & (~(e1 >> 31)); /* clip */
- e2 = pred[40] + (e2 >> 6);
- if ((uint)e2 > 0xFF) e2 = 0xFF & (~(e2 >> 31)); /* clip */
- e3 = pred[60] + (e3 >> 6);
- if ((uint)e3 > 0xFF) e3 = 0xFF & (~(e3 >> 31)); /* clip */
- *cur = e0;
- *(cur += width) = e1;
- *(cur += width) = e2;
- cur[width] = e3;
- cur -= (width << 1);
- cur++;
- pred++;
-#else
- OSCL_UNUSED_ARG(pred);
-
- e0 = *cur + (e0 >> 6);
- if ((uint)e0 > 0xFF) e0 = 0xFF & (~(e0 >> 31)); /* clip */
- *cur = e0;
- e1 = *(cur += width) + (e1 >> 6);
- if ((uint)e1 > 0xFF) e1 = 0xFF & (~(e1 >> 31)); /* clip */
- *cur = e1;
- e2 = *(cur += width) + (e2 >> 6);
- if ((uint)e2 > 0xFF) e2 = 0xFF & (~(e2 >> 31)); /* clip */
- *cur = e2;
- e3 = cur[width] + (e3 >> 6);
- if ((uint)e3 > 0xFF) e3 = 0xFF & (~(e3 >> 31)); /* clip */
- cur[width] = e3;
- cur -= (width << 1);
- cur++;
-#endif
- block++;
- }
-
- return ;
-}
-
-/* see subclase 8.5.8 */
-void ictrans(int16 *block, uint8 *pred, uint8 *cur, int width)
-{
- int e0, e1, e2, e3; /* note, at every step of the calculation, these values */
- /* shall never exceed 16bit sign value, but we don't check */
- int i; /* to save the cycles. */
- int16 *inout;
-
- inout = block;
-
- for (i = 4; i > 0; i--)
- {
- e0 = inout[0] + inout[2];
- e1 = inout[0] - inout[2];
- e2 = (inout[1] >> 1) - inout[3];
- e3 = inout[1] + (inout[3] >> 1);
-
- inout[0] = e0 + e3;
- inout[1] = e1 + e2;
- inout[2] = e1 - e2;
- inout[3] = e0 - e3;
-
- inout += 16;
- }
-
- for (i = 4; i > 0; i--)
- {
- e0 = block[0] + block[32];
- e1 = block[0] - block[32];
- e2 = (block[16] >> 1) - block[48];
- e3 = block[16] + (block[48] >> 1);
-
- e0 += e3;
- e3 = (e0 - (e3 << 1)); /* e0-e3 */
- e1 += e2;
- e2 = (e1 - (e2 << 1)); /* e1-e2 */
- e0 += 32;
- e1 += 32;
- e2 += 32;
- e3 += 32;
-#ifdef USE_PRED_BLOCK
- e0 = pred[0] + (e0 >> 6);
- if ((uint)e0 > 0xFF) e0 = 0xFF & (~(e0 >> 31)); /* clip */
- e1 = pred[12] + (e1 >> 6);
- if ((uint)e1 > 0xFF) e1 = 0xFF & (~(e1 >> 31)); /* clip */
- e2 = pred[24] + (e2 >> 6);
- if ((uint)e2 > 0xFF) e2 = 0xFF & (~(e2 >> 31)); /* clip */
- e3 = pred[36] + (e3 >> 6);
- if ((uint)e3 > 0xFF) e3 = 0xFF & (~(e3 >> 31)); /* clip */
- *cur = e0;
- *(cur += width) = e1;
- *(cur += width) = e2;
- cur[width] = e3;
- cur -= (width << 1);
- cur++;
- pred++;
-#else
- OSCL_UNUSED_ARG(pred);
-
- e0 = *cur + (e0 >> 6);
- if ((uint)e0 > 0xFF) e0 = 0xFF & (~(e0 >> 31)); /* clip */
- *cur = e0;
- e1 = *(cur += width) + (e1 >> 6);
- if ((uint)e1 > 0xFF) e1 = 0xFF & (~(e1 >> 31)); /* clip */
- *cur = e1;
- e2 = *(cur += width) + (e2 >> 6);
- if ((uint)e2 > 0xFF) e2 = 0xFF & (~(e2 >> 31)); /* clip */
- *cur = e2;
- e3 = cur[width] + (e3 >> 6);
- if ((uint)e3 > 0xFF) e3 = 0xFF & (~(e3 >> 31)); /* clip */
- cur[width] = e3;
- cur -= (width << 1);
- cur++;
-#endif
- block++;
- }
-
- return ;
-}
-
-/* see subclause 8.5.7 */
-void ChromaDCTrans(int16 *block, int Qq, int Rq)
-{
- int c00, c01, c10, c11;
- int f0, f1, f2, f3;
- int scale = dequant_coefres[Rq][0];
-
- c00 = block[0] + block[4];
- c01 = block[0] - block[4];
- c10 = block[64] + block[68];
- c11 = block[64] - block[68];
-
- f0 = c00 + c10;
- f1 = c01 + c11;
- f2 = c00 - c10;
- f3 = c01 - c11;
-
- if (Qq >= 1)
- {
- Qq -= 1;
- block[0] = (f0 * scale) << Qq;
- block[4] = (f1 * scale) << Qq;
- block[64] = (f2 * scale) << Qq;
- block[68] = (f3 * scale) << Qq;
- }
- else
- {
- block[0] = (f0 * scale) >> 1;
- block[4] = (f1 * scale) >> 1;
- block[64] = (f2 * scale) >> 1;
- block[68] = (f3 * scale) >> 1;
- }
-
- return ;
-}
-
-
-void copy_block(uint8 *pred, uint8 *cur, int width, int pred_pitch)
-{
- uint32 temp;
-
- temp = *((uint32*)pred);
- pred += pred_pitch;
- *((uint32*)cur) = temp;
- cur += width;
- temp = *((uint32*)pred);
- pred += pred_pitch;
- *((uint32*)cur) = temp;
- cur += width;
- temp = *((uint32*)pred);
- pred += pred_pitch;
- *((uint32*)cur) = temp;
- cur += width;
- temp = *((uint32*)pred);
- *((uint32*)cur) = temp;
-
- return ;
-}
-
-
diff --git a/media/libstagefright/codecs/avc/dec/src/pred_inter.cpp b/media/libstagefright/codecs/avc/dec/src/pred_inter.cpp
deleted file mode 100644
index ba36c37..0000000
--- a/media/libstagefright/codecs/avc/dec/src/pred_inter.cpp
+++ /dev/null
@@ -1,2329 +0,0 @@
-/* ------------------------------------------------------------------
- * 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 "avcdec_lib.h"
-
-
-#define CLIP_RESULT(x) if((uint)x > 0xFF){ \
- x = 0xFF & (~(x>>31));}
-
-/* (blkwidth << 2) + (dy << 1) + dx */
-static void (*const ChromaMC_SIMD[8])(uint8 *, int , int , int , uint8 *, int, int , int) =
-{
- &ChromaFullMC_SIMD,
- &ChromaHorizontalMC_SIMD,
- &ChromaVerticalMC_SIMD,
- &ChromaDiagonalMC_SIMD,
- &ChromaFullMC_SIMD,
- &ChromaHorizontalMC2_SIMD,
- &ChromaVerticalMC2_SIMD,
- &ChromaDiagonalMC2_SIMD
-};
-/* Perform motion prediction and compensation with residue if exist. */
-void InterMBPrediction(AVCCommonObj *video)
-{
- AVCMacroblock *currMB = video->currMB;
- AVCPictureData *currPic = video->currPic;
- int mbPartIdx, subMbPartIdx;
- int ref_idx;
- int offset_MbPart_indx = 0;
- int16 *mv;
- uint32 x_pos, y_pos;
- uint8 *curL, *curCb, *curCr;
- uint8 *ref_l, *ref_Cb, *ref_Cr;
- uint8 *predBlock, *predCb, *predCr;
- int block_x, block_y, offset_x, offset_y, offsetP, offset;
- int x_position = (video->mb_x << 4);
- int y_position = (video->mb_y << 4);
- int MbHeight, MbWidth, mbPartIdx_X, mbPartIdx_Y, offset_indx;
- int picWidth = currPic->pitch;
- int picHeight = currPic->height;
- int16 *dataBlock;
- uint32 cbp4x4;
- uint32 tmp_word;
-
- tmp_word = y_position * picWidth;
- curL = currPic->Sl + tmp_word + x_position;
- offset = (tmp_word >> 2) + (x_position >> 1);
- curCb = currPic->Scb + offset;
- curCr = currPic->Scr + offset;
-
-#ifdef USE_PRED_BLOCK
- predBlock = video->pred + 84;
- predCb = video->pred + 452;
- predCr = video->pred + 596;
-#else
- predBlock = curL;
- predCb = curCb;
- predCr = curCr;
-#endif
-
- GetMotionVectorPredictor(video, false);
-
- for (mbPartIdx = 0; mbPartIdx < currMB->NumMbPart; mbPartIdx++)
- {
- MbHeight = currMB->SubMbPartHeight[mbPartIdx];
- MbWidth = currMB->SubMbPartWidth[mbPartIdx];
- mbPartIdx_X = ((mbPartIdx + offset_MbPart_indx) & 1);
- mbPartIdx_Y = (mbPartIdx + offset_MbPart_indx) >> 1;
- ref_idx = currMB->ref_idx_L0[(mbPartIdx_Y << 1) + mbPartIdx_X];
- offset_indx = 0;
-
- ref_l = video->RefPicList0[ref_idx]->Sl;
- ref_Cb = video->RefPicList0[ref_idx]->Scb;
- ref_Cr = video->RefPicList0[ref_idx]->Scr;
-
- for (subMbPartIdx = 0; subMbPartIdx < currMB->NumSubMbPart[mbPartIdx]; subMbPartIdx++)
- {
- block_x = (mbPartIdx_X << 1) + ((subMbPartIdx + offset_indx) & 1); // check this
- block_y = (mbPartIdx_Y << 1) + (((subMbPartIdx + offset_indx) >> 1) & 1);
- mv = (int16*)(currMB->mvL0 + block_x + (block_y << 2));
- offset_x = x_position + (block_x << 2);
- offset_y = y_position + (block_y << 2);
- x_pos = (offset_x << 2) + *mv++; /*quarter pel */
- y_pos = (offset_y << 2) + *mv; /*quarter pel */
-
- //offset = offset_y * currPic->width;
- //offsetC = (offset >> 2) + (offset_x >> 1);
-#ifdef USE_PRED_BLOCK
- offsetP = (block_y * 80) + (block_x << 2);
- LumaMotionComp(ref_l, picWidth, picHeight, x_pos, y_pos,
- /*comp_Sl + offset + offset_x,*/
- predBlock + offsetP, 20, MbWidth, MbHeight);
-#else
- offsetP = (block_y << 2) * picWidth + (block_x << 2);
- LumaMotionComp(ref_l, picWidth, picHeight, x_pos, y_pos,
- /*comp_Sl + offset + offset_x,*/
- predBlock + offsetP, picWidth, MbWidth, MbHeight);
-#endif
-
-#ifdef USE_PRED_BLOCK
- offsetP = (block_y * 24) + (block_x << 1);
- ChromaMotionComp(ref_Cb, picWidth >> 1, picHeight >> 1, x_pos, y_pos,
- /*comp_Scb + offsetC,*/
- predCb + offsetP, 12, MbWidth >> 1, MbHeight >> 1);
- ChromaMotionComp(ref_Cr, picWidth >> 1, picHeight >> 1, x_pos, y_pos,
- /*comp_Scr + offsetC,*/
- predCr + offsetP, 12, MbWidth >> 1, MbHeight >> 1);
-#else
- offsetP = (block_y * picWidth) + (block_x << 1);
- ChromaMotionComp(ref_Cb, picWidth >> 1, picHeight >> 1, x_pos, y_pos,
- /*comp_Scb + offsetC,*/
- predCb + offsetP, picWidth >> 1, MbWidth >> 1, MbHeight >> 1);
- ChromaMotionComp(ref_Cr, picWidth >> 1, picHeight >> 1, x_pos, y_pos,
- /*comp_Scr + offsetC,*/
- predCr + offsetP, picWidth >> 1, MbWidth >> 1, MbHeight >> 1);
-#endif
-
- offset_indx = currMB->SubMbPartWidth[mbPartIdx] >> 3;
- }
- offset_MbPart_indx = currMB->MbPartWidth >> 4;
- }
-
- /* used in decoder, used to be if(!encFlag) */
-
- /* transform in raster scan order */
- dataBlock = video->block;
- cbp4x4 = video->cbp4x4;
- /* luma */
- for (block_y = 4; block_y > 0; block_y--)
- {
- for (block_x = 4; block_x > 0; block_x--)
- {
-#ifdef USE_PRED_BLOCK
- if (cbp4x4&1)
- {
- itrans(dataBlock, predBlock, predBlock, 20);
- }
-#else
- if (cbp4x4&1)
- {
- itrans(dataBlock, curL, curL, picWidth);
- }
-#endif
- cbp4x4 >>= 1;
- dataBlock += 4;
-#ifdef USE_PRED_BLOCK
- predBlock += 4;
-#else
- curL += 4;
-#endif
- }
- dataBlock += 48;
-#ifdef USE_PRED_BLOCK
- predBlock += 64;
-#else
- curL += ((picWidth << 2) - 16);
-#endif
- }
-
- /* chroma */
- picWidth = (picWidth >> 1);
- for (block_y = 2; block_y > 0; block_y--)
- {
- for (block_x = 2; block_x > 0; block_x--)
- {
-#ifdef USE_PRED_BLOCK
- if (cbp4x4&1)
- {
- ictrans(dataBlock, predCb, predCb, 12);
- }
-#else
- if (cbp4x4&1)
- {
- ictrans(dataBlock, curCb, curCb, picWidth);
- }
-#endif
- cbp4x4 >>= 1;
- dataBlock += 4;
-#ifdef USE_PRED_BLOCK
- predCb += 4;
-#else
- curCb += 4;
-#endif
- }
- for (block_x = 2; block_x > 0; block_x--)
- {
-#ifdef USE_PRED_BLOCK
- if (cbp4x4&1)
- {
- ictrans(dataBlock, predCr, predCr, 12);
- }
-#else
- if (cbp4x4&1)
- {
- ictrans(dataBlock, curCr, curCr, picWidth);
- }
-#endif
- cbp4x4 >>= 1;
- dataBlock += 4;
-#ifdef USE_PRED_BLOCK
- predCr += 4;
-#else
- curCr += 4;
-#endif
- }
- dataBlock += 48;
-#ifdef USE_PRED_BLOCK
- predCb += 40;
- predCr += 40;
-#else
- curCb += ((picWidth << 2) - 8);
- curCr += ((picWidth << 2) - 8);
-#endif
- }
-
-#ifdef MB_BASED_DEBLOCK
- SaveNeighborForIntraPred(video, offset);
-#endif
-
- return ;
-}
-
-
-/* preform the actual motion comp here */
-void LumaMotionComp(uint8 *ref, int picwidth, int picheight,
- int x_pos, int y_pos,
- uint8 *pred, int pred_pitch,
- int blkwidth, int blkheight)
-{
- int dx, dy;
- uint8 temp[24][24]; /* for padding, make the size multiple of 4 for packing */
- int temp2[21][21]; /* for intermediate results */
- uint8 *ref2;
-
- dx = x_pos & 3;
- dy = y_pos & 3;
- x_pos = x_pos >> 2; /* round it to full-pel resolution */
- y_pos = y_pos >> 2;
-
- /* perform actual motion compensation */
- if (dx == 0 && dy == 0)
- { /* fullpel position *//* G */
- if (x_pos >= 0 && x_pos + blkwidth <= picwidth && y_pos >= 0 && y_pos + blkheight <= picheight)
- {
- ref += y_pos * picwidth + x_pos;
- FullPelMC(ref, picwidth, pred, pred_pitch, blkwidth, blkheight);
- }
- else
- {
- CreatePad(ref, picwidth, picheight, x_pos, y_pos, &temp[0][0], blkwidth, blkheight);
- FullPelMC(&temp[0][0], 24, pred, pred_pitch, blkwidth, blkheight);
- }
-
- } /* other positions */
- else if (dy == 0)
- { /* no vertical interpolation *//* a,b,c*/
-
- if (x_pos - 2 >= 0 && x_pos + 3 + blkwidth <= picwidth && y_pos >= 0 && y_pos + blkheight <= picheight)
- {
- ref += y_pos * picwidth + x_pos;
-
- HorzInterp1MC(ref, picwidth, pred, pred_pitch, blkwidth, blkheight, dx);
- }
- else /* need padding */
- {
- CreatePad(ref, picwidth, picheight, x_pos - 2, y_pos, &temp[0][0], blkwidth + 5, blkheight);
-
- HorzInterp1MC(&temp[0][2], 24, pred, pred_pitch, blkwidth, blkheight, dx);
- }
- }
- else if (dx == 0)
- { /*no horizontal interpolation *//* d,h,n */
-
- if (x_pos >= 0 && x_pos + blkwidth <= picwidth && y_pos - 2 >= 0 && y_pos + 3 + blkheight <= picheight)
- {
- ref += y_pos * picwidth + x_pos;
-
- VertInterp1MC(ref, picwidth, pred, pred_pitch, blkwidth, blkheight, dy);
- }
- else /* need padding */
- {
- CreatePad(ref, picwidth, picheight, x_pos, y_pos - 2, &temp[0][0], blkwidth, blkheight + 5);
-
- VertInterp1MC(&temp[2][0], 24, pred, pred_pitch, blkwidth, blkheight, dy);
- }
- }
- else if (dy == 2)
- { /* horizontal cross *//* i, j, k */
-
- if (x_pos - 2 >= 0 && x_pos + 3 + blkwidth <= picwidth && y_pos - 2 >= 0 && y_pos + 3 + blkheight <= picheight)
- {
- ref += y_pos * picwidth + x_pos - 2; /* move to the left 2 pixels */
-
- VertInterp2MC(ref, picwidth, &temp2[0][0], 21, blkwidth + 5, blkheight);
-
- HorzInterp2MC(&temp2[0][2], 21, pred, pred_pitch, blkwidth, blkheight, dx);
- }
- else /* need padding */
- {
- CreatePad(ref, picwidth, picheight, x_pos - 2, y_pos - 2, &temp[0][0], blkwidth + 5, blkheight + 5);
-
- VertInterp2MC(&temp[2][0], 24, &temp2[0][0], 21, blkwidth + 5, blkheight);
-
- HorzInterp2MC(&temp2[0][2], 21, pred, pred_pitch, blkwidth, blkheight, dx);
- }
- }
- else if (dx == 2)
- { /* vertical cross */ /* f,q */
-
- if (x_pos - 2 >= 0 && x_pos + 3 + blkwidth <= picwidth && y_pos - 2 >= 0 && y_pos + 3 + blkheight <= picheight)
- {
- ref += (y_pos - 2) * picwidth + x_pos; /* move to up 2 lines */
-
- HorzInterp3MC(ref, picwidth, &temp2[0][0], 21, blkwidth, blkheight + 5);
- VertInterp3MC(&temp2[2][0], 21, pred, pred_pitch, blkwidth, blkheight, dy);
- }
- else /* need padding */
- {
- CreatePad(ref, picwidth, picheight, x_pos - 2, y_pos - 2, &temp[0][0], blkwidth + 5, blkheight + 5);
- HorzInterp3MC(&temp[0][2], 24, &temp2[0][0], 21, blkwidth, blkheight + 5);
- VertInterp3MC(&temp2[2][0], 21, pred, pred_pitch, blkwidth, blkheight, dy);
- }
- }
- else
- { /* diagonal *//* e,g,p,r */
-
- if (x_pos - 2 >= 0 && x_pos + 3 + (dx / 2) + blkwidth <= picwidth &&
- y_pos - 2 >= 0 && y_pos + 3 + blkheight + (dy / 2) <= picheight)
- {
- ref2 = ref + (y_pos + (dy / 2)) * picwidth + x_pos;
-
- ref += (y_pos * picwidth) + x_pos + (dx / 2);
-
- DiagonalInterpMC(ref2, ref, picwidth, pred, pred_pitch, blkwidth, blkheight);
- }
- else /* need padding */
- {
- CreatePad(ref, picwidth, picheight, x_pos - 2, y_pos - 2, &temp[0][0], blkwidth + 5 + (dx / 2), blkheight + 5 + (dy / 2));
-
- ref2 = &temp[2 + (dy/2)][2];
-
- ref = &temp[2][2 + (dx/2)];
-
- DiagonalInterpMC(ref2, ref, 24, pred, pred_pitch, blkwidth, blkheight);
- }
- }
-
- return ;
-}
-
-void CreateAlign(uint8 *ref, int picwidth, int y_pos,
- uint8 *out, int blkwidth, int blkheight)
-{
- int i, j;
- int offset, out_offset;
- uint32 prev_pix, result, pix1, pix2, pix4;
-
- out_offset = 24 - blkwidth;
-
- //switch(x_pos&0x3){
- switch (((uint32)ref)&0x3)
- {
- case 1:
- ref += y_pos * picwidth;
- offset = picwidth - blkwidth - 3;
- for (j = 0; j < blkheight; j++)
- {
- pix1 = *ref++;
- pix2 = *((uint16*)ref);
- ref += 2;
- result = (pix2 << 8) | pix1;
-
- for (i = 3; i < blkwidth; i += 4)
- {
- pix4 = *((uint32*)ref);
- ref += 4;
- prev_pix = (pix4 << 24) & 0xFF000000; /* mask out byte belong to previous word */
- result |= prev_pix;
- *((uint32*)out) = result; /* write 4 bytes */
- out += 4;
- result = pix4 >> 8; /* for the next loop */
- }
- ref += offset;
- out += out_offset;
- }
- break;
- case 2:
- ref += y_pos * picwidth;
- offset = picwidth - blkwidth - 2;
- for (j = 0; j < blkheight; j++)
- {
- result = *((uint16*)ref);
- ref += 2;
- for (i = 2; i < blkwidth; i += 4)
- {
- pix4 = *((uint32*)ref);
- ref += 4;
- prev_pix = (pix4 << 16) & 0xFFFF0000; /* mask out byte belong to previous word */
- result |= prev_pix;
- *((uint32*)out) = result; /* write 4 bytes */
- out += 4;
- result = pix4 >> 16; /* for the next loop */
- }
- ref += offset;
- out += out_offset;
- }
- break;
- case 3:
- ref += y_pos * picwidth;
- offset = picwidth - blkwidth - 1;
- for (j = 0; j < blkheight; j++)
- {
- result = *ref++;
- for (i = 1; i < blkwidth; i += 4)
- {
- pix4 = *((uint32*)ref);
- ref += 4;
- prev_pix = (pix4 << 8) & 0xFFFFFF00; /* mask out byte belong to previous word */
- result |= prev_pix;
- *((uint32*)out) = result; /* write 4 bytes */
- out += 4;
- result = pix4 >> 24; /* for the next loop */
- }
- ref += offset;
- out += out_offset;
- }
- break;
- }
-}
-
-void CreatePad(uint8 *ref, int picwidth, int picheight, int x_pos, int y_pos,
- uint8 *out, int blkwidth, int blkheight)
-{
- int x_inc0, x_mid;
- int y_inc, y_inc0, y_inc1, y_mid;
- int i, j;
- int offset;
-
- if (x_pos < 0)
- {
- x_inc0 = 0; /* increment for the first part */
- x_mid = ((blkwidth + x_pos > 0) ? -x_pos : blkwidth); /* stopping point */
- x_pos = 0;
- }
- else if (x_pos + blkwidth > picwidth)
- {
- x_inc0 = 1; /* increasing */
- x_mid = ((picwidth > x_pos) ? picwidth - x_pos - 1 : 0); /* clip negative to zero, encode fool proof! */
- }
- else /* normal case */
- {
- x_inc0 = 1;
- x_mid = blkwidth; /* just one run */
- }
-
-
- /* boundary for y_pos, taking the result from x_pos into account */
- if (y_pos < 0)
- {
- y_inc0 = (x_inc0 ? - x_mid : -blkwidth + x_mid); /* offset depending on x_inc1 and x_inc0 */
- y_inc1 = picwidth + y_inc0;
- y_mid = ((blkheight + y_pos > 0) ? -y_pos : blkheight); /* clip to prevent memory corruption */
- y_pos = 0;
- }
- else if (y_pos + blkheight > picheight)
- {
- y_inc1 = (x_inc0 ? - x_mid : -blkwidth + x_mid); /* saturate */
- y_inc0 = picwidth + y_inc1; /* increasing */
- y_mid = ((picheight > y_pos) ? picheight - 1 - y_pos : 0);
- }
- else /* normal case */
- {
- y_inc1 = (x_inc0 ? - x_mid : -blkwidth + x_mid);
- y_inc0 = picwidth + y_inc1;
- y_mid = blkheight;
- }
-
- /* clip y_pos and x_pos */
- if (y_pos > picheight - 1) y_pos = picheight - 1;
- if (x_pos > picwidth - 1) x_pos = picwidth - 1;
-
- ref += y_pos * picwidth + x_pos;
-
- y_inc = y_inc0; /* start with top half */
-
- offset = 24 - blkwidth; /* to use in offset out */
- blkwidth -= x_mid; /* to use in the loop limit */
-
- if (x_inc0 == 0)
- {
- for (j = 0; j < blkheight; j++)
- {
- if (j == y_mid) /* put a check here to reduce the code size (for unrolling the loop) */
- {
- y_inc = y_inc1; /* switch to lower half */
- }
- for (i = x_mid; i > 0; i--) /* first or third quarter */
- {
- *out++ = *ref;
- }
- for (i = blkwidth; i > 0; i--) /* second or fourth quarter */
- {
- *out++ = *ref++;
- }
- out += offset;
- ref += y_inc;
- }
- }
- else
- {
- for (j = 0; j < blkheight; j++)
- {
- if (j == y_mid) /* put a check here to reduce the code size (for unrolling the loop) */
- {
- y_inc = y_inc1; /* switch to lower half */
- }
- for (i = x_mid; i > 0; i--) /* first or third quarter */
- {
- *out++ = *ref++;
- }
- for (i = blkwidth; i > 0; i--) /* second or fourth quarter */
- {
- *out++ = *ref;
- }
- out += offset;
- ref += y_inc;
- }
- }
-
- return ;
-}
-
-void HorzInterp1MC(uint8 *in, int inpitch, uint8 *out, int outpitch,
- int blkwidth, int blkheight, int dx)
-{
- uint8 *p_ref;
- uint32 *p_cur;
- uint32 tmp, pkres;
- int result, curr_offset, ref_offset;
- int j;
- int32 r0, r1, r2, r3, r4, r5;
- int32 r13, r6;
-
- p_cur = (uint32*)out; /* assume it's word aligned */
- curr_offset = (outpitch - blkwidth) >> 2;
- p_ref = in;
- ref_offset = inpitch - blkwidth;
-
- if (dx&1)
- {
- dx = ((dx >> 1) ? -3 : -4); /* use in 3/4 pel */
- p_ref -= 2;
- r13 = 0;
- for (j = blkheight; j > 0; j--)
- {
- tmp = (uint32)(p_ref + blkwidth);
- r0 = p_ref[0];
- r1 = p_ref[2];
- r0 |= (r1 << 16); /* 0,c,0,a */
- r1 = p_ref[1];
- r2 = p_ref[3];
- r1 |= (r2 << 16); /* 0,d,0,b */
- while ((uint32)p_ref < tmp)
- {
- r2 = *(p_ref += 4); /* move pointer to e */
- r3 = p_ref[2];
- r2 |= (r3 << 16); /* 0,g,0,e */
- r3 = p_ref[1];
- r4 = p_ref[3];
- r3 |= (r4 << 16); /* 0,h,0,f */
-
- r4 = r0 + r3; /* c+h, a+f */
- r5 = r0 + r1; /* c+d, a+b */
- r6 = r2 + r3; /* g+h, e+f */
- r5 >>= 16;
- r5 |= (r6 << 16); /* e+f, c+d */
- r4 += r5 * 20; /* c+20*e+20*f+h, a+20*c+20*d+f */
- r4 += 0x100010; /* +16, +16 */
- r5 = r1 + r2; /* d+g, b+e */
- r4 -= r5 * 5; /* c-5*d+20*e+20*f-5*g+h, a-5*b+20*c+20*d-5*e+f */
- r4 >>= 5;
- r13 |= r4; /* check clipping */
-
- r5 = p_ref[dx+2];
- r6 = p_ref[dx+4];
- r5 |= (r6 << 16);
- r4 += r5;
- r4 += 0x10001;
- r4 = (r4 >> 1) & 0xFF00FF;
-
- r5 = p_ref[4]; /* i */
- r6 = (r5 << 16);
- r5 = r6 | (r2 >> 16);/* 0,i,0,g */
- r5 += r1; /* d+i, b+g */ /* r5 not free */
- r1 >>= 16;
- r1 |= (r3 << 16); /* 0,f,0,d */ /* r1 has changed */
- r1 += r2; /* f+g, d+e */
- r5 += 20 * r1; /* d+20f+20g+i, b+20d+20e+g */
- r0 >>= 16;
- r0 |= (r2 << 16); /* 0,e,0,c */ /* r0 has changed */
- r0 += r3; /* e+h, c+f */
- r5 += 0x100010; /* 16,16 */
- r5 -= r0 * 5; /* d-5e+20f+20g-5h+i, b-5c+20d+20e-5f+g */
- r5 >>= 5;
- r13 |= r5; /* check clipping */
-
- r0 = p_ref[dx+3];
- r1 = p_ref[dx+5];
- r0 |= (r1 << 16);
- r5 += r0;
- r5 += 0x10001;
- r5 = (r5 >> 1) & 0xFF00FF;
-
- r4 |= (r5 << 8); /* pack them together */
- *p_cur++ = r4;
- r1 = r3;
- r0 = r2;
- }
- p_cur += curr_offset; /* move to the next line */
- p_ref += ref_offset; /* ref_offset = inpitch-blkwidth; */
-
- if (r13&0xFF000700) /* need clipping */
- {
- /* move back to the beginning of the line */
- p_ref -= (ref_offset + blkwidth); /* input */
- p_cur -= (outpitch >> 2);
-
- tmp = (uint32)(p_ref + blkwidth);
- for (; (uint32)p_ref < tmp;)
- {
-
- r0 = *p_ref++;
- r1 = *p_ref++;
- r2 = *p_ref++;
- r3 = *p_ref++;
- r4 = *p_ref++;
- /* first pixel */
- r5 = *p_ref++;
- result = (r0 + r5);
- r0 = (r1 + r4);
- result -= (r0 * 5);//result -= r0; result -= (r0<<2);
- r0 = (r2 + r3);
- result += (r0 * 20);//result += (r0<<4); result += (r0<<2);
- result = (result + 16) >> 5;
- CLIP_RESULT(result)
- /* 3/4 pel, no need to clip */
- result = (result + p_ref[dx] + 1);
- pkres = (result >> 1) ;
- /* second pixel */
- r0 = *p_ref++;
- result = (r1 + r0);
- r1 = (r2 + r5);
- result -= (r1 * 5);//result -= r1; result -= (r1<<2);
- r1 = (r3 + r4);
- result += (r1 * 20);//result += (r1<<4); result += (r1<<2);
- result = (result + 16) >> 5;
- CLIP_RESULT(result)
- /* 3/4 pel, no need to clip */
- result = (result + p_ref[dx] + 1);
- result = (result >> 1);
- pkres |= (result << 8);
- /* third pixel */
- r1 = *p_ref++;
- result = (r2 + r1);
- r2 = (r3 + r0);
- result -= (r2 * 5);//result -= r2; result -= (r2<<2);
- r2 = (r4 + r5);
- result += (r2 * 20);//result += (r2<<4); result += (r2<<2);
- result = (result + 16) >> 5;
- CLIP_RESULT(result)
- /* 3/4 pel, no need to clip */
- result = (result + p_ref[dx] + 1);
- result = (result >> 1);
- pkres |= (result << 16);
- /* fourth pixel */
- r2 = *p_ref++;
- result = (r3 + r2);
- r3 = (r4 + r1);
- result -= (r3 * 5);//result -= r3; result -= (r3<<2);
- r3 = (r5 + r0);
- result += (r3 * 20);//result += (r3<<4); result += (r3<<2);
- result = (result + 16) >> 5;
- CLIP_RESULT(result)
- /* 3/4 pel, no need to clip */
- result = (result + p_ref[dx] + 1);
- result = (result >> 1);
- pkres |= (result << 24);
- *p_cur++ = pkres; /* write 4 pixels */
- p_ref -= 5; /* offset back to the middle of filter */
- }
- p_cur += curr_offset; /* move to the next line */
- p_ref += ref_offset; /* move to the next line */
- }
- }
- }
- else
- {
- p_ref -= 2;
- r13 = 0;
- for (j = blkheight; j > 0; j--)
- {
- tmp = (uint32)(p_ref + blkwidth);
- r0 = p_ref[0];
- r1 = p_ref[2];
- r0 |= (r1 << 16); /* 0,c,0,a */
- r1 = p_ref[1];
- r2 = p_ref[3];
- r1 |= (r2 << 16); /* 0,d,0,b */
- while ((uint32)p_ref < tmp)
- {
- r2 = *(p_ref += 4); /* move pointer to e */
- r3 = p_ref[2];
- r2 |= (r3 << 16); /* 0,g,0,e */
- r3 = p_ref[1];
- r4 = p_ref[3];
- r3 |= (r4 << 16); /* 0,h,0,f */
-
- r4 = r0 + r3; /* c+h, a+f */
- r5 = r0 + r1; /* c+d, a+b */
- r6 = r2 + r3; /* g+h, e+f */
- r5 >>= 16;
- r5 |= (r6 << 16); /* e+f, c+d */
- r4 += r5 * 20; /* c+20*e+20*f+h, a+20*c+20*d+f */
- r4 += 0x100010; /* +16, +16 */
- r5 = r1 + r2; /* d+g, b+e */
- r4 -= r5 * 5; /* c-5*d+20*e+20*f-5*g+h, a-5*b+20*c+20*d-5*e+f */
- r4 >>= 5;
- r13 |= r4; /* check clipping */
- r4 &= 0xFF00FF; /* mask */
-
- r5 = p_ref[4]; /* i */
- r6 = (r5 << 16);
- r5 = r6 | (r2 >> 16);/* 0,i,0,g */
- r5 += r1; /* d+i, b+g */ /* r5 not free */
- r1 >>= 16;
- r1 |= (r3 << 16); /* 0,f,0,d */ /* r1 has changed */
- r1 += r2; /* f+g, d+e */
- r5 += 20 * r1; /* d+20f+20g+i, b+20d+20e+g */
- r0 >>= 16;
- r0 |= (r2 << 16); /* 0,e,0,c */ /* r0 has changed */
- r0 += r3; /* e+h, c+f */
- r5 += 0x100010; /* 16,16 */
- r5 -= r0 * 5; /* d-5e+20f+20g-5h+i, b-5c+20d+20e-5f+g */
- r5 >>= 5;
- r13 |= r5; /* check clipping */
- r5 &= 0xFF00FF; /* mask */
-
- r4 |= (r5 << 8); /* pack them together */
- *p_cur++ = r4;
- r1 = r3;
- r0 = r2;
- }
- p_cur += curr_offset; /* move to the next line */
- p_ref += ref_offset; /* ref_offset = inpitch-blkwidth; */
-
- if (r13&0xFF000700) /* need clipping */
- {
- /* move back to the beginning of the line */
- p_ref -= (ref_offset + blkwidth); /* input */
- p_cur -= (outpitch >> 2);
-
- tmp = (uint32)(p_ref + blkwidth);
- for (; (uint32)p_ref < tmp;)
- {
-
- r0 = *p_ref++;
- r1 = *p_ref++;
- r2 = *p_ref++;
- r3 = *p_ref++;
- r4 = *p_ref++;
- /* first pixel */
- r5 = *p_ref++;
- result = (r0 + r5);
- r0 = (r1 + r4);
- result -= (r0 * 5);//result -= r0; result -= (r0<<2);
- r0 = (r2 + r3);
- result += (r0 * 20);//result += (r0<<4); result += (r0<<2);
- result = (result + 16) >> 5;
- CLIP_RESULT(result)
- pkres = result;
- /* second pixel */
- r0 = *p_ref++;
- result = (r1 + r0);
- r1 = (r2 + r5);
- result -= (r1 * 5);//result -= r1; result -= (r1<<2);
- r1 = (r3 + r4);
- result += (r1 * 20);//result += (r1<<4); result += (r1<<2);
- result = (result + 16) >> 5;
- CLIP_RESULT(result)
- pkres |= (result << 8);
- /* third pixel */
- r1 = *p_ref++;
- result = (r2 + r1);
- r2 = (r3 + r0);
- result -= (r2 * 5);//result -= r2; result -= (r2<<2);
- r2 = (r4 + r5);
- result += (r2 * 20);//result += (r2<<4); result += (r2<<2);
- result = (result + 16) >> 5;
- CLIP_RESULT(result)
- pkres |= (result << 16);
- /* fourth pixel */
- r2 = *p_ref++;
- result = (r3 + r2);
- r3 = (r4 + r1);
- result -= (r3 * 5);//result -= r3; result -= (r3<<2);
- r3 = (r5 + r0);
- result += (r3 * 20);//result += (r3<<4); result += (r3<<2);
- result = (result + 16) >> 5;
- CLIP_RESULT(result)
- pkres |= (result << 24);
- *p_cur++ = pkres; /* write 4 pixels */
- p_ref -= 5;
- }
- p_cur += curr_offset; /* move to the next line */
- p_ref += ref_offset;
- }
- }
- }
-
- return ;
-}
-
-void HorzInterp2MC(int *in, int inpitch, uint8 *out, int outpitch,
- int blkwidth, int blkheight, int dx)
-{
- int *p_ref;
- uint32 *p_cur;
- uint32 tmp, pkres;
- int result, result2, curr_offset, ref_offset;
- int j, r0, r1, r2, r3, r4, r5;
-
- p_cur = (uint32*)out; /* assume it's word aligned */
- curr_offset = (outpitch - blkwidth) >> 2;
- p_ref = in;
- ref_offset = inpitch - blkwidth;
-
- if (dx&1)
- {
- dx = ((dx >> 1) ? -3 : -4); /* use in 3/4 pel */
-
- for (j = blkheight; j > 0 ; j--)
- {
- tmp = (uint32)(p_ref + blkwidth);
- for (; (uint32)p_ref < tmp;)
- {
-
- r0 = p_ref[-2];
- r1 = p_ref[-1];
- r2 = *p_ref++;
- r3 = *p_ref++;
- r4 = *p_ref++;
- /* first pixel */
- r5 = *p_ref++;
- result = (r0 + r5);
- r0 = (r1 + r4);
- result -= (r0 * 5);//result -= r0; result -= (r0<<2);
- r0 = (r2 + r3);
- result += (r0 * 20);//result += (r0<<4); result += (r0<<2);
- result = (result + 512) >> 10;
- CLIP_RESULT(result)
- result2 = ((p_ref[dx] + 16) >> 5);
- CLIP_RESULT(result2)
- /* 3/4 pel, no need to clip */
- result = (result + result2 + 1);
- pkres = (result >> 1);
- /* second pixel */
- r0 = *p_ref++;
- result = (r1 + r0);
- r1 = (r2 + r5);
- result -= (r1 * 5);//result -= r1; result -= (r1<<2);
- r1 = (r3 + r4);
- result += (r1 * 20);//result += (r1<<4); result += (r1<<2);
- result = (result + 512) >> 10;
- CLIP_RESULT(result)
- result2 = ((p_ref[dx] + 16) >> 5);
- CLIP_RESULT(result2)
- /* 3/4 pel, no need to clip */
- result = (result + result2 + 1);
- result = (result >> 1);
- pkres |= (result << 8);
- /* third pixel */
- r1 = *p_ref++;
- result = (r2 + r1);
- r2 = (r3 + r0);
- result -= (r2 * 5);//result -= r2; result -= (r2<<2);
- r2 = (r4 + r5);
- result += (r2 * 20);//result += (r2<<4); result += (r2<<2);
- result = (result + 512) >> 10;
- CLIP_RESULT(result)
- result2 = ((p_ref[dx] + 16) >> 5);
- CLIP_RESULT(result2)
- /* 3/4 pel, no need to clip */
- result = (result + result2 + 1);
- result = (result >> 1);
- pkres |= (result << 16);
- /* fourth pixel */
- r2 = *p_ref++;
- result = (r3 + r2);
- r3 = (r4 + r1);
- result -= (r3 * 5);//result -= r3; result -= (r3<<2);
- r3 = (r5 + r0);
- result += (r3 * 20);//result += (r3<<4); result += (r3<<2);
- result = (result + 512) >> 10;
- CLIP_RESULT(result)
- result2 = ((p_ref[dx] + 16) >> 5);
- CLIP_RESULT(result2)
- /* 3/4 pel, no need to clip */
- result = (result + result2 + 1);
- result = (result >> 1);
- pkres |= (result << 24);
- *p_cur++ = pkres; /* write 4 pixels */
- p_ref -= 3; /* offset back to the middle of filter */
- }
- p_cur += curr_offset; /* move to the next line */
- p_ref += ref_offset; /* move to the next line */
- }
- }
- else
- {
- for (j = blkheight; j > 0 ; j--)
- {
- tmp = (uint32)(p_ref + blkwidth);
- for (; (uint32)p_ref < tmp;)
- {
-
- r0 = p_ref[-2];
- r1 = p_ref[-1];
- r2 = *p_ref++;
- r3 = *p_ref++;
- r4 = *p_ref++;
- /* first pixel */
- r5 = *p_ref++;
- result = (r0 + r5);
- r0 = (r1 + r4);
- result -= (r0 * 5);//result -= r0; result -= (r0<<2);
- r0 = (r2 + r3);
- result += (r0 * 20);//result += (r0<<4); result += (r0<<2);
- result = (result + 512) >> 10;
- CLIP_RESULT(result)
- pkres = result;
- /* second pixel */
- r0 = *p_ref++;
- result = (r1 + r0);
- r1 = (r2 + r5);
- result -= (r1 * 5);//result -= r1; result -= (r1<<2);
- r1 = (r3 + r4);
- result += (r1 * 20);//result += (r1<<4); result += (r1<<2);
- result = (result + 512) >> 10;
- CLIP_RESULT(result)
- pkres |= (result << 8);
- /* third pixel */
- r1 = *p_ref++;
- result = (r2 + r1);
- r2 = (r3 + r0);
- result -= (r2 * 5);//result -= r2; result -= (r2<<2);
- r2 = (r4 + r5);
- result += (r2 * 20);//result += (r2<<4); result += (r2<<2);
- result = (result + 512) >> 10;
- CLIP_RESULT(result)
- pkres |= (result << 16);
- /* fourth pixel */
- r2 = *p_ref++;
- result = (r3 + r2);
- r3 = (r4 + r1);
- result -= (r3 * 5);//result -= r3; result -= (r3<<2);
- r3 = (r5 + r0);
- result += (r3 * 20);//result += (r3<<4); result += (r3<<2);
- result = (result + 512) >> 10;
- CLIP_RESULT(result)
- pkres |= (result << 24);
- *p_cur++ = pkres; /* write 4 pixels */
- p_ref -= 3; /* offset back to the middle of filter */
- }
- p_cur += curr_offset; /* move to the next line */
- p_ref += ref_offset; /* move to the next line */
- }
- }
-
- return ;
-}
-
-void HorzInterp3MC(uint8 *in, int inpitch, int *out, int outpitch,
- int blkwidth, int blkheight)
-{
- uint8 *p_ref;
- int *p_cur;
- uint32 tmp;
- int result, curr_offset, ref_offset;
- int j, r0, r1, r2, r3, r4, r5;
-
- p_cur = out;
- curr_offset = (outpitch - blkwidth);
- p_ref = in;
- ref_offset = inpitch - blkwidth;
-
- for (j = blkheight; j > 0 ; j--)
- {
- tmp = (uint32)(p_ref + blkwidth);
- for (; (uint32)p_ref < tmp;)
- {
-
- r0 = p_ref[-2];
- r1 = p_ref[-1];
- r2 = *p_ref++;
- r3 = *p_ref++;
- r4 = *p_ref++;
- /* first pixel */
- r5 = *p_ref++;
- result = (r0 + r5);
- r0 = (r1 + r4);
- result -= (r0 * 5);//result -= r0; result -= (r0<<2);
- r0 = (r2 + r3);
- result += (r0 * 20);//result += (r0<<4); result += (r0<<2);
- *p_cur++ = result;
- /* second pixel */
- r0 = *p_ref++;
- result = (r1 + r0);
- r1 = (r2 + r5);
- result -= (r1 * 5);//result -= r1; result -= (r1<<2);
- r1 = (r3 + r4);
- result += (r1 * 20);//result += (r1<<4); result += (r1<<2);
- *p_cur++ = result;
- /* third pixel */
- r1 = *p_ref++;
- result = (r2 + r1);
- r2 = (r3 + r0);
- result -= (r2 * 5);//result -= r2; result -= (r2<<2);
- r2 = (r4 + r5);
- result += (r2 * 20);//result += (r2<<4); result += (r2<<2);
- *p_cur++ = result;
- /* fourth pixel */
- r2 = *p_ref++;
- result = (r3 + r2);
- r3 = (r4 + r1);
- result -= (r3 * 5);//result -= r3; result -= (r3<<2);
- r3 = (r5 + r0);
- result += (r3 * 20);//result += (r3<<4); result += (r3<<2);
- *p_cur++ = result;
- p_ref -= 3; /* move back to the middle of the filter */
- }
- p_cur += curr_offset; /* move to the next line */
- p_ref += ref_offset;
- }
-
- return ;
-}
-void VertInterp1MC(uint8 *in, int inpitch, uint8 *out, int outpitch,
- int blkwidth, int blkheight, int dy)
-{
- uint8 *p_cur, *p_ref;
- uint32 tmp;
- int result, curr_offset, ref_offset;
- int j, i;
- int32 r0, r1, r2, r3, r4, r5, r6, r7, r8, r13;
- uint8 tmp_in[24][24];
-
- /* not word-aligned */
- if (((uint32)in)&0x3)
- {
- CreateAlign(in, inpitch, -2, &tmp_in[0][0], blkwidth, blkheight + 5);
- in = &tmp_in[2][0];
- inpitch = 24;
- }
- p_cur = out;
- curr_offset = 1 - outpitch * (blkheight - 1); /* offset vertically back up and one pixel to right */
- ref_offset = blkheight * inpitch; /* for limit */
-
- curr_offset += 3;
-
- if (dy&1)
- {
- dy = (dy >> 1) ? 0 : -inpitch;
-
- for (j = 0; j < blkwidth; j += 4, in += 4)
- {
- r13 = 0;
- p_ref = in;
- p_cur -= outpitch; /* compensate for the first offset */
- tmp = (uint32)(p_ref + ref_offset); /* limit */
- while ((uint32)p_ref < tmp) /* the loop un-rolled */
- {
- r0 = *((uint32*)(p_ref - (inpitch << 1))); /* load 4 bytes */
- p_ref += inpitch;
- r6 = (r0 >> 8) & 0xFF00FF; /* second and fourth byte */
- r0 &= 0xFF00FF;
-
- r1 = *((uint32*)(p_ref + (inpitch << 1))); /* r1, r7, ref[3] */
- r7 = (r1 >> 8) & 0xFF00FF;
- r1 &= 0xFF00FF;
-
- r0 += r1;
- r6 += r7;
-
- r2 = *((uint32*)p_ref); /* r2, r8, ref[1] */
- r8 = (r2 >> 8) & 0xFF00FF;
- r2 &= 0xFF00FF;
-
- r1 = *((uint32*)(p_ref - inpitch)); /* r1, r7, ref[0] */
- r7 = (r1 >> 8) & 0xFF00FF;
- r1 &= 0xFF00FF;
- r1 += r2;
-
- r7 += r8;
-
- r0 += 20 * r1;
- r6 += 20 * r7;
- r0 += 0x100010;
- r6 += 0x100010;
-
- r2 = *((uint32*)(p_ref - (inpitch << 1))); /* r2, r8, ref[-1] */
- r8 = (r2 >> 8) & 0xFF00FF;
- r2 &= 0xFF00FF;
-
- r1 = *((uint32*)(p_ref + inpitch)); /* r1, r7, ref[2] */
- r7 = (r1 >> 8) & 0xFF00FF;
- r1 &= 0xFF00FF;
- r1 += r2;
-
- r7 += r8;
-
- r0 -= 5 * r1;
- r6 -= 5 * r7;
-
- r0 >>= 5;
- r6 >>= 5;
- /* clip */
- r13 |= r6;
- r13 |= r0;
- //CLIPPACK(r6,result)
-
- r1 = *((uint32*)(p_ref + dy));
- r2 = (r1 >> 8) & 0xFF00FF;
- r1 &= 0xFF00FF;
- r0 += r1;
- r6 += r2;
- r0 += 0x10001;
- r6 += 0x10001;
- r0 = (r0 >> 1) & 0xFF00FF;
- r6 = (r6 >> 1) & 0xFF00FF;
-
- r0 |= (r6 << 8); /* pack it back */
- *((uint32*)(p_cur += outpitch)) = r0;
- }
- p_cur += curr_offset; /* offset to the next pixel */
- if (r13 & 0xFF000700) /* this column need clipping */
- {
- p_cur -= 4;
- for (i = 0; i < 4; i++)
- {
- p_ref = in + i;
- p_cur -= outpitch; /* compensate for the first offset */
-
- tmp = (uint32)(p_ref + ref_offset); /* limit */
- while ((uint32)p_ref < tmp)
- { /* loop un-rolled */
- r0 = *(p_ref - (inpitch << 1));
- r1 = *(p_ref - inpitch);
- r2 = *p_ref;
- r3 = *(p_ref += inpitch); /* modify pointer before loading */
- r4 = *(p_ref += inpitch);
- /* first pixel */
- r5 = *(p_ref += inpitch);
- result = (r0 + r5);
- r0 = (r1 + r4);
- result -= (r0 * 5);//result -= r0; result -= (r0<<2);
- r0 = (r2 + r3);
- result += (r0 * 20);//result += (r0<<4); result += (r0<<2);
- result = (result + 16) >> 5;
- CLIP_RESULT(result)
- /* 3/4 pel, no need to clip */
- result = (result + p_ref[dy-(inpitch<<1)] + 1);
- result = (result >> 1);
- *(p_cur += outpitch) = result;
- /* second pixel */
- r0 = *(p_ref += inpitch);
- result = (r1 + r0);
- r1 = (r2 + r5);
- result -= (r1 * 5);//result -= r1; result -= (r1<<2);
- r1 = (r3 + r4);
- result += (r1 * 20);//result += (r1<<4); result += (r1<<2);
- result = (result + 16) >> 5;
- CLIP_RESULT(result)
- /* 3/4 pel, no need to clip */
- result = (result + p_ref[dy-(inpitch<<1)] + 1);
- result = (result >> 1);
- *(p_cur += outpitch) = result;
- /* third pixel */
- r1 = *(p_ref += inpitch);
- result = (r2 + r1);
- r2 = (r3 + r0);
- result -= (r2 * 5);//result -= r2; result -= (r2<<2);
- r2 = (r4 + r5);
- result += (r2 * 20);//result += (r2<<4); result += (r2<<2);
- result = (result + 16) >> 5;
- CLIP_RESULT(result)
- /* 3/4 pel, no need to clip */
- result = (result + p_ref[dy-(inpitch<<1)] + 1);
- result = (result >> 1);
- *(p_cur += outpitch) = result;
- /* fourth pixel */
- r2 = *(p_ref += inpitch);
- result = (r3 + r2);
- r3 = (r4 + r1);
- result -= (r3 * 5);//result -= r3; result -= (r3<<2);
- r3 = (r5 + r0);
- result += (r3 * 20);//result += (r3<<4); result += (r3<<2);
- result = (result + 16) >> 5;
- CLIP_RESULT(result)
- /* 3/4 pel, no need to clip */
- result = (result + p_ref[dy-(inpitch<<1)] + 1);
- result = (result >> 1);
- *(p_cur += outpitch) = result;
- p_ref -= (inpitch << 1); /* move back to center of the filter of the next one */
- }
- p_cur += (curr_offset - 3);
- }
- }
- }
- }
- else
- {
- for (j = 0; j < blkwidth; j += 4, in += 4)
- {
- r13 = 0;
- p_ref = in;
- p_cur -= outpitch; /* compensate for the first offset */
- tmp = (uint32)(p_ref + ref_offset); /* limit */
- while ((uint32)p_ref < tmp) /* the loop un-rolled */
- {
- r0 = *((uint32*)(p_ref - (inpitch << 1))); /* load 4 bytes */
- p_ref += inpitch;
- r6 = (r0 >> 8) & 0xFF00FF; /* second and fourth byte */
- r0 &= 0xFF00FF;
-
- r1 = *((uint32*)(p_ref + (inpitch << 1))); /* r1, r7, ref[3] */
- r7 = (r1 >> 8) & 0xFF00FF;
- r1 &= 0xFF00FF;
-
- r0 += r1;
- r6 += r7;
-
- r2 = *((uint32*)p_ref); /* r2, r8, ref[1] */
- r8 = (r2 >> 8) & 0xFF00FF;
- r2 &= 0xFF00FF;
-
- r1 = *((uint32*)(p_ref - inpitch)); /* r1, r7, ref[0] */
- r7 = (r1 >> 8) & 0xFF00FF;
- r1 &= 0xFF00FF;
- r1 += r2;
-
- r7 += r8;
-
- r0 += 20 * r1;
- r6 += 20 * r7;
- r0 += 0x100010;
- r6 += 0x100010;
-
- r2 = *((uint32*)(p_ref - (inpitch << 1))); /* r2, r8, ref[-1] */
- r8 = (r2 >> 8) & 0xFF00FF;
- r2 &= 0xFF00FF;
-
- r1 = *((uint32*)(p_ref + inpitch)); /* r1, r7, ref[2] */
- r7 = (r1 >> 8) & 0xFF00FF;
- r1 &= 0xFF00FF;
- r1 += r2;
-
- r7 += r8;
-
- r0 -= 5 * r1;
- r6 -= 5 * r7;
-
- r0 >>= 5;
- r6 >>= 5;
- /* clip */
- r13 |= r6;
- r13 |= r0;
- //CLIPPACK(r6,result)
- r0 &= 0xFF00FF;
- r6 &= 0xFF00FF;
- r0 |= (r6 << 8); /* pack it back */
- *((uint32*)(p_cur += outpitch)) = r0;
- }
- p_cur += curr_offset; /* offset to the next pixel */
- if (r13 & 0xFF000700) /* this column need clipping */
- {
- p_cur -= 4;
- for (i = 0; i < 4; i++)
- {
- p_ref = in + i;
- p_cur -= outpitch; /* compensate for the first offset */
- tmp = (uint32)(p_ref + ref_offset); /* limit */
- while ((uint32)p_ref < tmp)
- { /* loop un-rolled */
- r0 = *(p_ref - (inpitch << 1));
- r1 = *(p_ref - inpitch);
- r2 = *p_ref;
- r3 = *(p_ref += inpitch); /* modify pointer before loading */
- r4 = *(p_ref += inpitch);
- /* first pixel */
- r5 = *(p_ref += inpitch);
- result = (r0 + r5);
- r0 = (r1 + r4);
- result -= (r0 * 5);//result -= r0; result -= (r0<<2);
- r0 = (r2 + r3);
- result += (r0 * 20);//result += (r0<<4); result += (r0<<2);
- result = (result + 16) >> 5;
- CLIP_RESULT(result)
- *(p_cur += outpitch) = result;
- /* second pixel */
- r0 = *(p_ref += inpitch);
- result = (r1 + r0);
- r1 = (r2 + r5);
- result -= (r1 * 5);//result -= r1; result -= (r1<<2);
- r1 = (r3 + r4);
- result += (r1 * 20);//result += (r1<<4); result += (r1<<2);
- result = (result + 16) >> 5;
- CLIP_RESULT(result)
- *(p_cur += outpitch) = result;
- /* third pixel */
- r1 = *(p_ref += inpitch);
- result = (r2 + r1);
- r2 = (r3 + r0);
- result -= (r2 * 5);//result -= r2; result -= (r2<<2);
- r2 = (r4 + r5);
- result += (r2 * 20);//result += (r2<<4); result += (r2<<2);
- result = (result + 16) >> 5;
- CLIP_RESULT(result)
- *(p_cur += outpitch) = result;
- /* fourth pixel */
- r2 = *(p_ref += inpitch);
- result = (r3 + r2);
- r3 = (r4 + r1);
- result -= (r3 * 5);//result -= r3; result -= (r3<<2);
- r3 = (r5 + r0);
- result += (r3 * 20);//result += (r3<<4); result += (r3<<2);
- result = (result + 16) >> 5;
- CLIP_RESULT(result)
- *(p_cur += outpitch) = result;
- p_ref -= (inpitch << 1); /* move back to center of the filter of the next one */
- }
- p_cur += (curr_offset - 3);
- }
- }
- }
- }
-
- return ;
-}
-
-void VertInterp2MC(uint8 *in, int inpitch, int *out, int outpitch,
- int blkwidth, int blkheight)
-{
- int *p_cur;
- uint8 *p_ref;
- uint32 tmp;
- int result, curr_offset, ref_offset;
- int j, r0, r1, r2, r3, r4, r5;
-
- p_cur = out;
- curr_offset = 1 - outpitch * (blkheight - 1); /* offset vertically back up and one pixel to right */
- ref_offset = blkheight * inpitch; /* for limit */
-
- for (j = 0; j < blkwidth; j++)
- {
- p_cur -= outpitch; /* compensate for the first offset */
- p_ref = in++;
-
- tmp = (uint32)(p_ref + ref_offset); /* limit */
- while ((uint32)p_ref < tmp)
- { /* loop un-rolled */
- r0 = *(p_ref - (inpitch << 1));
- r1 = *(p_ref - inpitch);
- r2 = *p_ref;
- r3 = *(p_ref += inpitch); /* modify pointer before loading */
- r4 = *(p_ref += inpitch);
- /* first pixel */
- r5 = *(p_ref += inpitch);
- result = (r0 + r5);
- r0 = (r1 + r4);
- result -= (r0 * 5);//result -= r0; result -= (r0<<2);
- r0 = (r2 + r3);
- result += (r0 * 20);//result += (r0<<4); result += (r0<<2);
- *(p_cur += outpitch) = result;
- /* second pixel */
- r0 = *(p_ref += inpitch);
- result = (r1 + r0);
- r1 = (r2 + r5);
- result -= (r1 * 5);//result -= r1; result -= (r1<<2);
- r1 = (r3 + r4);
- result += (r1 * 20);//result += (r1<<4); result += (r1<<2);
- *(p_cur += outpitch) = result;
- /* third pixel */
- r1 = *(p_ref += inpitch);
- result = (r2 + r1);
- r2 = (r3 + r0);
- result -= (r2 * 5);//result -= r2; result -= (r2<<2);
- r2 = (r4 + r5);
- result += (r2 * 20);//result += (r2<<4); result += (r2<<2);
- *(p_cur += outpitch) = result;
- /* fourth pixel */
- r2 = *(p_ref += inpitch);
- result = (r3 + r2);
- r3 = (r4 + r1);
- result -= (r3 * 5);//result -= r3; result -= (r3<<2);
- r3 = (r5 + r0);
- result += (r3 * 20);//result += (r3<<4); result += (r3<<2);
- *(p_cur += outpitch) = result;
- p_ref -= (inpitch << 1); /* move back to center of the filter of the next one */
- }
- p_cur += curr_offset;
- }
-
- return ;
-}
-
-void VertInterp3MC(int *in, int inpitch, uint8 *out, int outpitch,
- int blkwidth, int blkheight, int dy)
-{
- uint8 *p_cur;
- int *p_ref;
- uint32 tmp;
- int result, result2, curr_offset, ref_offset;
- int j, r0, r1, r2, r3, r4, r5;
-
- p_cur = out;
- curr_offset = 1 - outpitch * (blkheight - 1); /* offset vertically back up and one pixel to right */
- ref_offset = blkheight * inpitch; /* for limit */
-
- if (dy&1)
- {
- dy = (dy >> 1) ? -(inpitch << 1) : -(inpitch << 1) - inpitch;
-
- for (j = 0; j < blkwidth; j++)
- {
- p_cur -= outpitch; /* compensate for the first offset */
- p_ref = in++;
-
- tmp = (uint32)(p_ref + ref_offset); /* limit */
- while ((uint32)p_ref < tmp)
- { /* loop un-rolled */
- r0 = *(p_ref - (inpitch << 1));
- r1 = *(p_ref - inpitch);
- r2 = *p_ref;
- r3 = *(p_ref += inpitch); /* modify pointer before loading */
- r4 = *(p_ref += inpitch);
- /* first pixel */
- r5 = *(p_ref += inpitch);
- result = (r0 + r5);
- r0 = (r1 + r4);
- result -= (r0 * 5);//result -= r0; result -= (r0<<2);
- r0 = (r2 + r3);
- result += (r0 * 20);//result += (r0<<4); result += (r0<<2);
- result = (result + 512) >> 10;
- CLIP_RESULT(result)
- result2 = ((p_ref[dy] + 16) >> 5);
- CLIP_RESULT(result2)
- /* 3/4 pel, no need to clip */
- result = (result + result2 + 1);
- result = (result >> 1);
- *(p_cur += outpitch) = result;
- /* second pixel */
- r0 = *(p_ref += inpitch);
- result = (r1 + r0);
- r1 = (r2 + r5);
- result -= (r1 * 5);//result -= r1; result -= (r1<<2);
- r1 = (r3 + r4);
- result += (r1 * 20);//result += (r1<<4); result += (r1<<2);
- result = (result + 512) >> 10;
- CLIP_RESULT(result)
- result2 = ((p_ref[dy] + 16) >> 5);
- CLIP_RESULT(result2)
- /* 3/4 pel, no need to clip */
- result = (result + result2 + 1);
- result = (result >> 1);
- *(p_cur += outpitch) = result;
- /* third pixel */
- r1 = *(p_ref += inpitch);
- result = (r2 + r1);
- r2 = (r3 + r0);
- result -= (r2 * 5);//result -= r2; result -= (r2<<2);
- r2 = (r4 + r5);
- result += (r2 * 20);//result += (r2<<4); result += (r2<<2);
- result = (result + 512) >> 10;
- CLIP_RESULT(result)
- result2 = ((p_ref[dy] + 16) >> 5);
- CLIP_RESULT(result2)
- /* 3/4 pel, no need to clip */
- result = (result + result2 + 1);
- result = (result >> 1);
- *(p_cur += outpitch) = result;
- /* fourth pixel */
- r2 = *(p_ref += inpitch);
- result = (r3 + r2);
- r3 = (r4 + r1);
- result -= (r3 * 5);//result -= r3; result -= (r3<<2);
- r3 = (r5 + r0);
- result += (r3 * 20);//result += (r3<<4); result += (r3<<2);
- result = (result + 512) >> 10;
- CLIP_RESULT(result)
- result2 = ((p_ref[dy] + 16) >> 5);
- CLIP_RESULT(result2)
- /* 3/4 pel, no need to clip */
- result = (result + result2 + 1);
- result = (result >> 1);
- *(p_cur += outpitch) = result;
- p_ref -= (inpitch << 1); /* move back to center of the filter of the next one */
- }
- p_cur += curr_offset;
- }
- }
- else
- {
- for (j = 0; j < blkwidth; j++)
- {
- p_cur -= outpitch; /* compensate for the first offset */
- p_ref = in++;
-
- tmp = (uint32)(p_ref + ref_offset); /* limit */
- while ((uint32)p_ref < tmp)
- { /* loop un-rolled */
- r0 = *(p_ref - (inpitch << 1));
- r1 = *(p_ref - inpitch);
- r2 = *p_ref;
- r3 = *(p_ref += inpitch); /* modify pointer before loading */
- r4 = *(p_ref += inpitch);
- /* first pixel */
- r5 = *(p_ref += inpitch);
- result = (r0 + r5);
- r0 = (r1 + r4);
- result -= (r0 * 5);//result -= r0; result -= (r0<<2);
- r0 = (r2 + r3);
- result += (r0 * 20);//result += (r0<<4); result += (r0<<2);
- result = (result + 512) >> 10;
- CLIP_RESULT(result)
- *(p_cur += outpitch) = result;
- /* second pixel */
- r0 = *(p_ref += inpitch);
- result = (r1 + r0);
- r1 = (r2 + r5);
- result -= (r1 * 5);//result -= r1; result -= (r1<<2);
- r1 = (r3 + r4);
- result += (r1 * 20);//result += (r1<<4); result += (r1<<2);
- result = (result + 512) >> 10;
- CLIP_RESULT(result)
- *(p_cur += outpitch) = result;
- /* third pixel */
- r1 = *(p_ref += inpitch);
- result = (r2 + r1);
- r2 = (r3 + r0);
- result -= (r2 * 5);//result -= r2; result -= (r2<<2);
- r2 = (r4 + r5);
- result += (r2 * 20);//result += (r2<<4); result += (r2<<2);
- result = (result + 512) >> 10;
- CLIP_RESULT(result)
- *(p_cur += outpitch) = result;
- /* fourth pixel */
- r2 = *(p_ref += inpitch);
- result = (r3 + r2);
- r3 = (r4 + r1);
- result -= (r3 * 5);//result -= r3; result -= (r3<<2);
- r3 = (r5 + r0);
- result += (r3 * 20);//result += (r3<<4); result += (r3<<2);
- result = (result + 512) >> 10;
- CLIP_RESULT(result)
- *(p_cur += outpitch) = result;
- p_ref -= (inpitch << 1); /* move back to center of the filter of the next one */
- }
- p_cur += curr_offset;
- }
- }
-
- return ;
-}
-
-void DiagonalInterpMC(uint8 *in1, uint8 *in2, int inpitch,
- uint8 *out, int outpitch,
- int blkwidth, int blkheight)
-{
- int j, i;
- int result;
- uint8 *p_cur, *p_ref, *p_tmp8;
- int curr_offset, ref_offset;
- uint8 tmp_res[24][24], tmp_in[24][24];
- uint32 *p_tmp;
- uint32 tmp, pkres, tmp_result;
- int32 r0, r1, r2, r3, r4, r5;
- int32 r6, r7, r8, r9, r10, r13;
-
- ref_offset = inpitch - blkwidth;
- p_ref = in1 - 2;
- /* perform horizontal interpolation */
- /* not word-aligned */
- /* It is faster to read 1 byte at time to avoid calling CreateAlign */
- /* if(((uint32)p_ref)&0x3)
- {
- CreateAlign(p_ref,inpitch,0,&tmp_in[0][0],blkwidth+8,blkheight);
- p_ref = &tmp_in[0][0];
- ref_offset = 24-blkwidth;
- }*/
-
- p_tmp = (uint32*) & (tmp_res[0][0]);
- for (j = blkheight; j > 0; j--)
- {
- r13 = 0;
- tmp = (uint32)(p_ref + blkwidth);
-
- //r0 = *((uint32*)p_ref); /* d,c,b,a */
- //r1 = (r0>>8)&0xFF00FF; /* 0,d,0,b */
- //r0 &= 0xFF00FF; /* 0,c,0,a */
- /* It is faster to read 1 byte at a time, */
- r0 = p_ref[0];
- r1 = p_ref[2];
- r0 |= (r1 << 16); /* 0,c,0,a */
- r1 = p_ref[1];
- r2 = p_ref[3];
- r1 |= (r2 << 16); /* 0,d,0,b */
-
- while ((uint32)p_ref < tmp)
- {
- //r2 = *((uint32*)(p_ref+=4));/* h,g,f,e */
- //r3 = (r2>>8)&0xFF00FF; /* 0,h,0,f */
- //r2 &= 0xFF00FF; /* 0,g,0,e */
- /* It is faster to read 1 byte at a time, */
- r2 = *(p_ref += 4);
- r3 = p_ref[2];
- r2 |= (r3 << 16); /* 0,g,0,e */
- r3 = p_ref[1];
- r4 = p_ref[3];
- r3 |= (r4 << 16); /* 0,h,0,f */
-
- r4 = r0 + r3; /* c+h, a+f */
- r5 = r0 + r1; /* c+d, a+b */
- r6 = r2 + r3; /* g+h, e+f */
- r5 >>= 16;
- r5 |= (r6 << 16); /* e+f, c+d */
- r4 += r5 * 20; /* c+20*e+20*f+h, a+20*c+20*d+f */
- r4 += 0x100010; /* +16, +16 */
- r5 = r1 + r2; /* d+g, b+e */
- r4 -= r5 * 5; /* c-5*d+20*e+20*f-5*g+h, a-5*b+20*c+20*d-5*e+f */
- r4 >>= 5;
- r13 |= r4; /* check clipping */
- r4 &= 0xFF00FF; /* mask */
-
- r5 = p_ref[4]; /* i */
- r6 = (r5 << 16);
- r5 = r6 | (r2 >> 16);/* 0,i,0,g */
- r5 += r1; /* d+i, b+g */ /* r5 not free */
- r1 >>= 16;
- r1 |= (r3 << 16); /* 0,f,0,d */ /* r1 has changed */
- r1 += r2; /* f+g, d+e */
- r5 += 20 * r1; /* d+20f+20g+i, b+20d+20e+g */
- r0 >>= 16;
- r0 |= (r2 << 16); /* 0,e,0,c */ /* r0 has changed */
- r0 += r3; /* e+h, c+f */
- r5 += 0x100010; /* 16,16 */
- r5 -= r0 * 5; /* d-5e+20f+20g-5h+i, b-5c+20d+20e-5f+g */
- r5 >>= 5;
- r13 |= r5; /* check clipping */
- r5 &= 0xFF00FF; /* mask */
-
- r4 |= (r5 << 8); /* pack them together */
- *p_tmp++ = r4;
- r1 = r3;
- r0 = r2;
- }
- p_tmp += ((24 - blkwidth) >> 2); /* move to the next line */
- p_ref += ref_offset; /* ref_offset = inpitch-blkwidth; */
-
- if (r13&0xFF000700) /* need clipping */
- {
- /* move back to the beginning of the line */
- p_ref -= (ref_offset + blkwidth); /* input */
- p_tmp -= 6; /* intermediate output */
- tmp = (uint32)(p_ref + blkwidth);
- while ((uint32)p_ref < tmp)
- {
- r0 = *p_ref++;
- r1 = *p_ref++;
- r2 = *p_ref++;
- r3 = *p_ref++;
- r4 = *p_ref++;
- /* first pixel */
- r5 = *p_ref++;
- result = (r0 + r5);
- r0 = (r1 + r4);
- result -= (r0 * 5);//result -= r0; result -= (r0<<2);
- r0 = (r2 + r3);
- result += (r0 * 20);//result += (r0<<4); result += (r0<<2);
- result = (result + 16) >> 5;
- CLIP_RESULT(result)
- pkres = result;
- /* second pixel */
- r0 = *p_ref++;
- result = (r1 + r0);
- r1 = (r2 + r5);
- result -= (r1 * 5);//result -= r1; result -= (r1<<2);
- r1 = (r3 + r4);
- result += (r1 * 20);//result += (r1<<4); result += (r1<<2);
- result = (result + 16) >> 5;
- CLIP_RESULT(result)
- pkres |= (result << 8);
- /* third pixel */
- r1 = *p_ref++;
- result = (r2 + r1);
- r2 = (r3 + r0);
- result -= (r2 * 5);//result -= r2; result -= (r2<<2);
- r2 = (r4 + r5);
- result += (r2 * 20);//result += (r2<<4); result += (r2<<2);
- result = (result + 16) >> 5;
- CLIP_RESULT(result)
- pkres |= (result << 16);
- /* fourth pixel */
- r2 = *p_ref++;
- result = (r3 + r2);
- r3 = (r4 + r1);
- result -= (r3 * 5);//result -= r3; result -= (r3<<2);
- r3 = (r5 + r0);
- result += (r3 * 20);//result += (r3<<4); result += (r3<<2);
- result = (result + 16) >> 5;
- CLIP_RESULT(result)
- pkres |= (result << 24);
-
- *p_tmp++ = pkres; /* write 4 pixel */
- p_ref -= 5;
- }
- p_tmp += ((24 - blkwidth) >> 2); /* move to the next line */
- p_ref += ref_offset; /* ref_offset = inpitch-blkwidth; */
- }
- }
-
- /* perform vertical interpolation */
- /* not word-aligned */
- if (((uint32)in2)&0x3)
- {
- CreateAlign(in2, inpitch, -2, &tmp_in[0][0], blkwidth, blkheight + 5);
- in2 = &tmp_in[2][0];
- inpitch = 24;
- }
-
- p_cur = out;
- curr_offset = 1 - outpitch * (blkheight - 1); /* offset vertically up and one pixel right */
- pkres = blkheight * inpitch; /* reuse it for limit */
-
- curr_offset += 3;
-
- for (j = 0; j < blkwidth; j += 4, in2 += 4)
- {
- r13 = 0;
- p_ref = in2;
- p_tmp8 = &(tmp_res[0][j]); /* intermediate result */
- p_tmp8 -= 24; /* compensate for the first offset */
- p_cur -= outpitch; /* compensate for the first offset */
- tmp = (uint32)(p_ref + pkres); /* limit */
- while ((uint32)p_ref < tmp) /* the loop un-rolled */
- {
- /* Read 1 byte at a time is too slow, too many read and pack ops, need to call CreateAlign, */
- /*p_ref8 = p_ref-(inpitch<<1); r0 = p_ref8[0]; r1 = p_ref8[2];
- r0 |= (r1<<16); r6 = p_ref8[1]; r1 = p_ref8[3];
- r6 |= (r1<<16); p_ref+=inpitch; */
- r0 = *((uint32*)(p_ref - (inpitch << 1))); /* load 4 bytes */
- p_ref += inpitch;
- r6 = (r0 >> 8) & 0xFF00FF; /* second and fourth byte */
- r0 &= 0xFF00FF;
-
- /*p_ref8 = p_ref+(inpitch<<1);
- r1 = p_ref8[0]; r7 = p_ref8[2]; r1 |= (r7<<16);
- r7 = p_ref8[1]; r2 = p_ref8[3]; r7 |= (r2<<16);*/
- r1 = *((uint32*)(p_ref + (inpitch << 1))); /* r1, r7, ref[3] */
- r7 = (r1 >> 8) & 0xFF00FF;
- r1 &= 0xFF00FF;
-
- r0 += r1;
- r6 += r7;
-
- /*r2 = p_ref[0]; r8 = p_ref[2]; r2 |= (r8<<16);
- r8 = p_ref[1]; r1 = p_ref[3]; r8 |= (r1<<16);*/
- r2 = *((uint32*)p_ref); /* r2, r8, ref[1] */
- r8 = (r2 >> 8) & 0xFF00FF;
- r2 &= 0xFF00FF;
-
- /*p_ref8 = p_ref-inpitch; r1 = p_ref8[0]; r7 = p_ref8[2];
- r1 |= (r7<<16); r1 += r2; r7 = p_ref8[1];
- r2 = p_ref8[3]; r7 |= (r2<<16);*/
- r1 = *((uint32*)(p_ref - inpitch)); /* r1, r7, ref[0] */
- r7 = (r1 >> 8) & 0xFF00FF;
- r1 &= 0xFF00FF;
- r1 += r2;
-
- r7 += r8;
-
- r0 += 20 * r1;
- r6 += 20 * r7;
- r0 += 0x100010;
- r6 += 0x100010;
-
- /*p_ref8 = p_ref-(inpitch<<1); r2 = p_ref8[0]; r8 = p_ref8[2];
- r2 |= (r8<<16); r8 = p_ref8[1]; r1 = p_ref8[3]; r8 |= (r1<<16);*/
- r2 = *((uint32*)(p_ref - (inpitch << 1))); /* r2, r8, ref[-1] */
- r8 = (r2 >> 8) & 0xFF00FF;
- r2 &= 0xFF00FF;
-
- /*p_ref8 = p_ref+inpitch; r1 = p_ref8[0]; r7 = p_ref8[2];
- r1 |= (r7<<16); r1 += r2; r7 = p_ref8[1];
- r2 = p_ref8[3]; r7 |= (r2<<16);*/
- r1 = *((uint32*)(p_ref + inpitch)); /* r1, r7, ref[2] */
- r7 = (r1 >> 8) & 0xFF00FF;
- r1 &= 0xFF00FF;
- r1 += r2;
-
- r7 += r8;
-
- r0 -= 5 * r1;
- r6 -= 5 * r7;
-
- r0 >>= 5;
- r6 >>= 5;
- /* clip */
- r13 |= r6;
- r13 |= r0;
- //CLIPPACK(r6,result)
- /* add with horizontal results */
- r10 = *((uint32*)(p_tmp8 += 24));
- r9 = (r10 >> 8) & 0xFF00FF;
- r10 &= 0xFF00FF;
-
- r0 += r10;
- r0 += 0x10001;
- r0 = (r0 >> 1) & 0xFF00FF; /* mask to 8 bytes */
-
- r6 += r9;
- r6 += 0x10001;
- r6 = (r6 >> 1) & 0xFF00FF; /* mask to 8 bytes */
-
- r0 |= (r6 << 8); /* pack it back */
- *((uint32*)(p_cur += outpitch)) = r0;
- }
- p_cur += curr_offset; /* offset to the next pixel */
- if (r13 & 0xFF000700) /* this column need clipping */
- {
- p_cur -= 4;
- for (i = 0; i < 4; i++)
- {
- p_ref = in2 + i;
- p_tmp8 = &(tmp_res[0][j+i]); /* intermediate result */
- p_tmp8 -= 24; /* compensate for the first offset */
- p_cur -= outpitch; /* compensate for the first offset */
- tmp = (uint32)(p_ref + pkres); /* limit */
- while ((uint32)p_ref < tmp) /* the loop un-rolled */
- {
- r0 = *(p_ref - (inpitch << 1));
- r1 = *(p_ref - inpitch);
- r2 = *p_ref;
- r3 = *(p_ref += inpitch); /* modify pointer before loading */
- r4 = *(p_ref += inpitch);
- /* first pixel */
- r5 = *(p_ref += inpitch);
- result = (r0 + r5);
- r0 = (r1 + r4);
- result -= (r0 * 5);//result -= r0; result -= (r0<<2);
- r0 = (r2 + r3);
- result += (r0 * 20);//result += (r0<<4); result += (r0<<2);
- result = (result + 16) >> 5;
- CLIP_RESULT(result)
- tmp_result = *(p_tmp8 += 24); /* modify pointer before loading */
- result = (result + tmp_result + 1); /* no clip */
- result = (result >> 1);
- *(p_cur += outpitch) = result;
- /* second pixel */
- r0 = *(p_ref += inpitch);
- result = (r1 + r0);
- r1 = (r2 + r5);
- result -= (r1 * 5);//result -= r1; result -= (r1<<2);
- r1 = (r3 + r4);
- result += (r1 * 20);//result += (r1<<4); result += (r1<<2);
- result = (result + 16) >> 5;
- CLIP_RESULT(result)
- tmp_result = *(p_tmp8 += 24); /* intermediate result */
- result = (result + tmp_result + 1); /* no clip */
- result = (result >> 1);
- *(p_cur += outpitch) = result;
- /* third pixel */
- r1 = *(p_ref += inpitch);
- result = (r2 + r1);
- r2 = (r3 + r0);
- result -= (r2 * 5);//result -= r2; result -= (r2<<2);
- r2 = (r4 + r5);
- result += (r2 * 20);//result += (r2<<4); result += (r2<<2);
- result = (result + 16) >> 5;
- CLIP_RESULT(result)
- tmp_result = *(p_tmp8 += 24); /* intermediate result */
- result = (result + tmp_result + 1); /* no clip */
- result = (result >> 1);
- *(p_cur += outpitch) = result;
- /* fourth pixel */
- r2 = *(p_ref += inpitch);
- result = (r3 + r2);
- r3 = (r4 + r1);
- result -= (r3 * 5);//result -= r3; result -= (r3<<2);
- r3 = (r5 + r0);
- result += (r3 * 20);//result += (r3<<4); result += (r3<<2);
- result = (result + 16) >> 5;
- CLIP_RESULT(result)
- tmp_result = *(p_tmp8 += 24); /* intermediate result */
- result = (result + tmp_result + 1); /* no clip */
- result = (result >> 1);
- *(p_cur += outpitch) = result;
- p_ref -= (inpitch << 1); /* move back to center of the filter of the next one */
- }
- p_cur += (curr_offset - 3);
- }
- }
- }
-
- return ;
-}
-
-/* position G */
-void FullPelMC(uint8 *in, int inpitch, uint8 *out, int outpitch,
- int blkwidth, int blkheight)
-{
- int i, j;
- int offset_in = inpitch - blkwidth;
- int offset_out = outpitch - blkwidth;
- uint32 temp;
- uint8 byte;
-
- if (((uint32)in)&3)
- {
- for (j = blkheight; j > 0; j--)
- {
- for (i = blkwidth; i > 0; i -= 4)
- {
- temp = *in++;
- byte = *in++;
- temp |= (byte << 8);
- byte = *in++;
- temp |= (byte << 16);
- byte = *in++;
- temp |= (byte << 24);
-
- *((uint32*)out) = temp; /* write 4 bytes */
- out += 4;
- }
- out += offset_out;
- in += offset_in;
- }
- }
- else
- {
- for (j = blkheight; j > 0; j--)
- {
- for (i = blkwidth; i > 0; i -= 4)
- {
- temp = *((uint32*)in);
- *((uint32*)out) = temp;
- in += 4;
- out += 4;
- }
- out += offset_out;
- in += offset_in;
- }
- }
- return ;
-}
-
-void ChromaMotionComp(uint8 *ref, int picwidth, int picheight,
- int x_pos, int y_pos,
- uint8 *pred, int pred_pitch,
- int blkwidth, int blkheight)
-{
- int dx, dy;
- int offset_dx, offset_dy;
- int index;
- uint8 temp[24][24];
-
- dx = x_pos & 7;
- dy = y_pos & 7;
- offset_dx = (dx + 7) >> 3;
- offset_dy = (dy + 7) >> 3;
- x_pos = x_pos >> 3; /* round it to full-pel resolution */
- y_pos = y_pos >> 3;
-
- if ((x_pos >= 0 && x_pos + blkwidth + offset_dx <= picwidth) && (y_pos >= 0 && y_pos + blkheight + offset_dy <= picheight))
- {
- ref += y_pos * picwidth + x_pos;
- }
- else
- {
- CreatePad(ref, picwidth, picheight, x_pos, y_pos, &temp[0][0], blkwidth + offset_dx, blkheight + offset_dy);
- ref = &temp[0][0];
- picwidth = 24;
- }
-
- index = offset_dx + (offset_dy << 1) + ((blkwidth << 1) & 0x7);
-
- (*(ChromaMC_SIMD[index]))(ref, picwidth , dx, dy, pred, pred_pitch, blkwidth, blkheight);
- return ;
-}
-
-
-/* SIMD routines, unroll the loops in vertical direction, decreasing loops (things to be done) */
-void ChromaDiagonalMC_SIMD(uint8 *pRef, int srcPitch, int dx, int dy,
- uint8 *pOut, int predPitch, int blkwidth, int blkheight)
-{
- int32 r0, r1, r2, r3, result0, result1;
- uint8 temp[288];
- uint8 *ref, *out;
- int i, j;
- int dx_8 = 8 - dx;
- int dy_8 = 8 - dy;
-
- /* horizontal first */
- out = temp;
- for (i = 0; i < blkheight + 1; i++)
- {
- ref = pRef;
- r0 = ref[0];
- for (j = 0; j < blkwidth; j += 4)
- {
- r0 |= (ref[2] << 16);
- result0 = dx_8 * r0;
-
- r1 = ref[1] | (ref[3] << 16);
- result0 += dx * r1;
- *(int32 *)out = result0;
-
- result0 = dx_8 * r1;
-
- r2 = ref[4];
- r0 = r0 >> 16;
- r1 = r0 | (r2 << 16);
- result0 += dx * r1;
- *(int32 *)(out + 16) = result0;
-
- ref += 4;
- out += 4;
- r0 = r2;
- }
- pRef += srcPitch;
- out += (32 - blkwidth);
- }
-
-// pRef -= srcPitch*(blkheight+1);
- ref = temp;
-
- for (j = 0; j < blkwidth; j += 4)
- {
- r0 = *(int32 *)ref;
- r1 = *(int32 *)(ref + 16);
- ref += 32;
- out = pOut;
- for (i = 0; i < (blkheight >> 1); i++)
- {
- result0 = dy_8 * r0 + 0x00200020;
- r2 = *(int32 *)ref;
- result0 += dy * r2;
- result0 >>= 6;
- result0 &= 0x00FF00FF;
- r0 = r2;
-
- result1 = dy_8 * r1 + 0x00200020;
- r3 = *(int32 *)(ref + 16);
- result1 += dy * r3;
- result1 >>= 6;
- result1 &= 0x00FF00FF;
- r1 = r3;
- *(int32 *)out = result0 | (result1 << 8);
- out += predPitch;
- ref += 32;
-
- result0 = dy_8 * r0 + 0x00200020;
- r2 = *(int32 *)ref;
- result0 += dy * r2;
- result0 >>= 6;
- result0 &= 0x00FF00FF;
- r0 = r2;
-
- result1 = dy_8 * r1 + 0x00200020;
- r3 = *(int32 *)(ref + 16);
- result1 += dy * r3;
- result1 >>= 6;
- result1 &= 0x00FF00FF;
- r1 = r3;
- *(int32 *)out = result0 | (result1 << 8);
- out += predPitch;
- ref += 32;
- }
- pOut += 4;
- ref = temp + 4; /* since it can only iterate twice max */
- }
- return;
-}
-
-void ChromaHorizontalMC_SIMD(uint8 *pRef, int srcPitch, int dx, int dy,
- uint8 *pOut, int predPitch, int blkwidth, int blkheight)
-{
- OSCL_UNUSED_ARG(dy);
- int32 r0, r1, r2, result0, result1;
- uint8 *ref, *out;
- int i, j;
- int dx_8 = 8 - dx;
-
- /* horizontal first */
- for (i = 0; i < blkheight; i++)
- {
- ref = pRef;
- out = pOut;
-
- r0 = ref[0];
- for (j = 0; j < blkwidth; j += 4)
- {
- r0 |= (ref[2] << 16);
- result0 = dx_8 * r0 + 0x00040004;
-
- r1 = ref[1] | (ref[3] << 16);
- result0 += dx * r1;
- result0 >>= 3;
- result0 &= 0x00FF00FF;
-
- result1 = dx_8 * r1 + 0x00040004;
-
- r2 = ref[4];
- r0 = r0 >> 16;
- r1 = r0 | (r2 << 16);
- result1 += dx * r1;
- result1 >>= 3;
- result1 &= 0x00FF00FF;
-
- *(int32 *)out = result0 | (result1 << 8);
-
- ref += 4;
- out += 4;
- r0 = r2;
- }
-
- pRef += srcPitch;
- pOut += predPitch;
- }
- return;
-}
-
-void ChromaVerticalMC_SIMD(uint8 *pRef, int srcPitch, int dx, int dy,
- uint8 *pOut, int predPitch, int blkwidth, int blkheight)
-{
- OSCL_UNUSED_ARG(dx);
- int32 r0, r1, r2, r3, result0, result1;
- int i, j;
- uint8 *ref, *out;
- int dy_8 = 8 - dy;
- /* vertical first */
- for (i = 0; i < blkwidth; i += 4)
- {
- ref = pRef;
- out = pOut;
-
- r0 = ref[0] | (ref[2] << 16);
- r1 = ref[1] | (ref[3] << 16);
- ref += srcPitch;
- for (j = 0; j < blkheight; j++)
- {
- result0 = dy_8 * r0 + 0x00040004;
- r2 = ref[0] | (ref[2] << 16);
- result0 += dy * r2;
- result0 >>= 3;
- result0 &= 0x00FF00FF;
- r0 = r2;
-
- result1 = dy_8 * r1 + 0x00040004;
- r3 = ref[1] | (ref[3] << 16);
- result1 += dy * r3;
- result1 >>= 3;
- result1 &= 0x00FF00FF;
- r1 = r3;
- *(int32 *)out = result0 | (result1 << 8);
- ref += srcPitch;
- out += predPitch;
- }
- pOut += 4;
- pRef += 4;
- }
- return;
-}
-
-void ChromaDiagonalMC2_SIMD(uint8 *pRef, int srcPitch, int dx, int dy,
- uint8 *pOut, int predPitch, int blkwidth, int blkheight)
-{
- OSCL_UNUSED_ARG(blkwidth);
- int32 r0, r1, temp0, temp1, result;
- int32 temp[9];
- int32 *out;
- int i, r_temp;
- int dy_8 = 8 - dy;
-
- /* horizontal first */
- out = temp;
- for (i = 0; i < blkheight + 1; i++)
- {
- r_temp = pRef[1];
- temp0 = (pRef[0] << 3) + dx * (r_temp - pRef[0]);
- temp1 = (r_temp << 3) + dx * (pRef[2] - r_temp);
- r0 = temp0 | (temp1 << 16);
- *out++ = r0;
- pRef += srcPitch;
- }
-
- pRef -= srcPitch * (blkheight + 1);
-
- out = temp;
-
- r0 = *out++;
-
- for (i = 0; i < blkheight; i++)
- {
- result = dy_8 * r0 + 0x00200020;
- r1 = *out++;
- result += dy * r1;
- result >>= 6;
- result &= 0x00FF00FF;
- *(int16 *)pOut = (result >> 8) | (result & 0xFF);
- r0 = r1;
- pOut += predPitch;
- }
- return;
-}
-
-void ChromaHorizontalMC2_SIMD(uint8 *pRef, int srcPitch, int dx, int dy,
- uint8 *pOut, int predPitch, int blkwidth, int blkheight)
-{
- OSCL_UNUSED_ARG(dy);
- OSCL_UNUSED_ARG(blkwidth);
- int i, temp, temp0, temp1;
-
- /* horizontal first */
- for (i = 0; i < blkheight; i++)
- {
- temp = pRef[1];
- temp0 = ((pRef[0] << 3) + dx * (temp - pRef[0]) + 4) >> 3;
- temp1 = ((temp << 3) + dx * (pRef[2] - temp) + 4) >> 3;
-
- *(int16 *)pOut = temp0 | (temp1 << 8);
- pRef += srcPitch;
- pOut += predPitch;
-
- }
- return;
-}
-void ChromaVerticalMC2_SIMD(uint8 *pRef, int srcPitch, int dx, int dy,
- uint8 *pOut, int predPitch, int blkwidth, int blkheight)
-{
- OSCL_UNUSED_ARG(dx);
- OSCL_UNUSED_ARG(blkwidth);
- int32 r0, r1, result;
- int i;
- int dy_8 = 8 - dy;
- r0 = pRef[0] | (pRef[1] << 16);
- pRef += srcPitch;
- for (i = 0; i < blkheight; i++)
- {
- result = dy_8 * r0 + 0x00040004;
- r1 = pRef[0] | (pRef[1] << 16);
- result += dy * r1;
- result >>= 3;
- result &= 0x00FF00FF;
- *(int16 *)pOut = (result >> 8) | (result & 0xFF);
- r0 = r1;
- pRef += srcPitch;
- pOut += predPitch;
- }
- return;
-}
-
-void ChromaFullMC_SIMD(uint8 *pRef, int srcPitch, int dx, int dy,
- uint8 *pOut, int predPitch, int blkwidth, int blkheight)
-{
- OSCL_UNUSED_ARG(dx);
- OSCL_UNUSED_ARG(dy);
- int i, j;
- int offset_in = srcPitch - blkwidth;
- int offset_out = predPitch - blkwidth;
- uint16 temp;
- uint8 byte;
-
- if (((uint32)pRef)&1)
- {
- for (j = blkheight; j > 0; j--)
- {
- for (i = blkwidth; i > 0; i -= 2)
- {
- temp = *pRef++;
- byte = *pRef++;
- temp |= (byte << 8);
- *((uint16*)pOut) = temp; /* write 2 bytes */
- pOut += 2;
- }
- pOut += offset_out;
- pRef += offset_in;
- }
- }
- else
- {
- for (j = blkheight; j > 0; j--)
- {
- for (i = blkwidth; i > 0; i -= 2)
- {
- temp = *((uint16*)pRef);
- *((uint16*)pOut) = temp;
- pRef += 2;
- pOut += 2;
- }
- pOut += offset_out;
- pRef += offset_in;
- }
- }
- return ;
-}
diff --git a/media/libstagefright/codecs/avc/dec/src/pred_intra.cpp b/media/libstagefright/codecs/avc/dec/src/pred_intra.cpp
deleted file mode 100644
index 0b613a4..0000000
--- a/media/libstagefright/codecs/avc/dec/src/pred_intra.cpp
+++ /dev/null
@@ -1,1786 +0,0 @@
-/* ------------------------------------------------------------------
- * 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 "avcdec_lib.h"
-
-#define CLIP_COMP *comp++ = (uint8)(((uint)temp>0xFF)? 0xFF&(~(temp>>31)): temp)
-#define CLIP_RESULT(x) if((uint)x > 0xFF){ \
- x = 0xFF & (~(x>>31));}
-
-
-/* We should combine the Intra4x4 functions with residual decoding and compensation */
-AVCStatus IntraMBPrediction(AVCCommonObj *video)
-{
- int component, SubBlock_indx, temp;
- AVCStatus status;
- AVCMacroblock *currMB = video->currMB;
- AVCPictureData *currPic = video->currPic;
- uint8 *curL, *curCb, *curCr;
- uint8 *comp;
- int block_x, block_y, offset;
- int16 *dataBlock = video->block;
- uint8 *predCb, *predCr;
-#ifdef USE_PRED_BLOCK
- uint8 *pred;
-#endif
- int pitch = currPic->pitch;
- uint32 cbp4x4 = video->cbp4x4;
-
- offset = (video->mb_y << 4) * pitch + (video->mb_x << 4);
- curL = currPic->Sl + offset;
-
-#ifdef USE_PRED_BLOCK
- video->pred_block = video->pred + 84; /* point to separate prediction memory */
- pred = video->pred_block;
- video->pred_pitch = 20;
-#else
- video->pred_block = curL; /* point directly to the frame buffer */
- video->pred_pitch = pitch;
-#endif
-
- if (currMB->mbMode == AVC_I4)
- {
- /* luminance first */
- block_x = block_y = 0;
- for (component = 0; component < 4; component++)
- {
- block_x = ((component & 1) << 1);
- block_y = ((component >> 1) << 1);
- comp = curL;// + (block_x<<2) + (block_y<<2)*currPic->pitch;
-
- for (SubBlock_indx = 0; SubBlock_indx < 4; SubBlock_indx++)
- {
- status = Intra_4x4(video, block_x, block_y, comp);
- if (status != AVC_SUCCESS)
- {
- return status;
- }
- /* transform following the 4x4 prediction, can't be SIMD
- with other blocks. */
-#ifdef USE_PRED_BLOCK
- if (cbp4x4&(1 << ((block_y << 2) + block_x)))
- {
- itrans(dataBlock, pred, pred, 20);
- }
-#else
- if (cbp4x4&(1 << ((block_y << 2) + block_x)))
- {
- itrans(dataBlock, comp, comp, pitch);
- }
-#endif
- temp = SubBlock_indx & 1;
- if (temp)
- {
- block_y++;
- block_x--;
- dataBlock += 60;
-#ifdef USE_PRED_BLOCK
- pred += 76;
-#else
- comp += ((pitch << 2) - 4);
-#endif
- }
- else
- {
- block_x++;
- dataBlock += 4;
-#ifdef USE_PRED_BLOCK
- pred += 4;
-#else
- comp += 4;
-#endif
- }
- }
- if (component&1)
- {
-#ifdef USE_PRED_BLOCK
- pred -= 8;
-#else
- curL += (pitch << 3) - 8;
-#endif
- dataBlock -= 8;
- }
- else
- {
-#ifdef USE_PRED_BLOCK
- pred -= 152;
-#else
- curL += 8;
-#endif
- dataBlock -= 120;
- }
- }
- cbp4x4 >>= 16;
- }
- else /* AVC_I16 */
- {
-#ifdef MB_BASED_DEBLOCK
- video->pintra_pred_top = video->intra_pred_top + (video->mb_x << 4);
- video->pintra_pred_left = video->intra_pred_left + 1;
- video->intra_pred_topleft = video->intra_pred_left[0];
- pitch = 1;
-#else
- video->pintra_pred_top = curL - pitch;
- video->pintra_pred_left = curL - 1;
- if (video->mb_y)
- {
- video->intra_pred_topleft = *(curL - pitch - 1);
- }
-#endif
- switch (currMB->i16Mode)
- {
- case AVC_I16_Vertical: /* Intra_16x16_Vertical */
- /* check availability of top */
- if (video->intraAvailB)
- {
- Intra_16x16_Vertical(video);
- }
- else
- {
- return AVC_FAIL;
- }
- break;
- case AVC_I16_Horizontal: /* Intra_16x16_Horizontal */
- /* check availability of left */
- if (video->intraAvailA)
- {
- Intra_16x16_Horizontal(video, pitch);
- }
- else
- {
- return AVC_FAIL;
- }
- break;
- case AVC_I16_DC: /* Intra_16x16_DC */
- Intra_16x16_DC(video, pitch);
- break;
- case AVC_I16_Plane: /* Intra_16x16_Plane */
- if (video->intraAvailA && video->intraAvailB && video->intraAvailD)
- {
- Intra_16x16_Plane(video, pitch);
- }
- else
- {
- return AVC_FAIL;
- }
- break;
- default:
- break;
- }
-
- pitch = currPic->pitch;
-
- /* transform */
- /* can go in raster scan order now */
- /* can be done in SIMD, */
- for (block_y = 4; block_y > 0; block_y--)
- {
- for (block_x = 4; block_x > 0; block_x--)
- {
-#ifdef USE_PRED_BLOCK
- if (cbp4x4&1)
- {
- itrans(dataBlock, pred, pred, 20);
- }
-#else
- if (cbp4x4&1)
- {
- itrans(dataBlock, curL, curL, pitch);
- }
-#endif
- cbp4x4 >>= 1;
- dataBlock += 4;
-#ifdef USE_PRED_BLOCK
- pred += 4;
-#else
- curL += 4;
-#endif
- }
- dataBlock += 48;
-#ifdef USE_PRED_BLOCK
- pred += 64;
-#else
- curL += ((pitch << 2) - 16);
-#endif
- }
- }
-
- offset = (offset >> 2) + (video->mb_x << 2); //((video->mb_y << 3)* pitch + (video->mb_x << 3));
- curCb = currPic->Scb + offset;
- curCr = currPic->Scr + offset;
-
-#ifdef MB_BASED_DEBLOCK
- video->pintra_pred_top_cb = video->intra_pred_top_cb + (video->mb_x << 3);
- video->pintra_pred_left_cb = video->intra_pred_left_cb + 1;
- video->intra_pred_topleft_cb = video->intra_pred_left_cb[0];
- video->pintra_pred_top_cr = video->intra_pred_top_cr + (video->mb_x << 3);
- video->pintra_pred_left_cr = video->intra_pred_left_cr + 1;
- video->intra_pred_topleft_cr = video->intra_pred_left_cr[0];
- pitch = 1;
-#else
- pitch >>= 1;
- video->pintra_pred_top_cb = curCb - pitch;
- video->pintra_pred_left_cb = curCb - 1;
- video->pintra_pred_top_cr = curCr - pitch;
- video->pintra_pred_left_cr = curCr - 1;
-
- if (video->mb_y)
- {
- video->intra_pred_topleft_cb = *(curCb - pitch - 1);
- video->intra_pred_topleft_cr = *(curCr - pitch - 1);
- }
-#endif
-
-#ifdef USE_PRED_BLOCK
- predCb = video->pred + 452;
- predCr = predCb + 144;
- video->pred_pitch = 12;
-#else
- predCb = curCb;
- predCr = curCr;
- video->pred_pitch = currPic->pitch >> 1;
-#endif
- /* chrominance */
- switch (currMB->intra_chroma_pred_mode)
- {
- case AVC_IC_DC: /* Intra_Chroma_DC */
- Intra_Chroma_DC(video, pitch, predCb, predCr);
- break;
- case AVC_IC_Horizontal: /* Intra_Chroma_Horizontal */
- if (video->intraAvailA)
- {
- /* check availability of left */
- Intra_Chroma_Horizontal(video, pitch, predCb, predCr);
- }
- else
- {
- return AVC_FAIL;
- }
- break;
- case AVC_IC_Vertical: /* Intra_Chroma_Vertical */
- if (video->intraAvailB)
- {
- /* check availability of top */
- Intra_Chroma_Vertical(video, predCb, predCr);
- }
- else
- {
- return AVC_FAIL;
- }
- break;
- case AVC_IC_Plane: /* Intra_Chroma_Plane */
- if (video->intraAvailA && video->intraAvailB && video->intraAvailD)
- {
- /* check availability of top and left */
- Intra_Chroma_Plane(video, pitch, predCb, predCr);
- }
- else
- {
- return AVC_FAIL;
- }
- break;
- default:
- break;
- }
-
- /* transform, done in raster scan manner */
- pitch = currPic->pitch >> 1;
-
- for (block_y = 2; block_y > 0; block_y--)
- {
- for (block_x = 2; block_x > 0; block_x--)
- {
-#ifdef USE_PRED_BLOCK
- if (cbp4x4&1)
- {
- ictrans(dataBlock, predCb, predCb, 12);
- }
-#else
- if (cbp4x4&1)
- {
- ictrans(dataBlock, curCb, curCb, pitch);
- }
-#endif
- cbp4x4 >>= 1;
- dataBlock += 4;
-#ifdef USE_PRED_BLOCK
- predCb += 4;
-#else
- curCb += 4;
-#endif
- }
- for (block_x = 2; block_x > 0; block_x--)
- {
-#ifdef USE_PRED_BLOCK
- if (cbp4x4&1)
- {
- ictrans(dataBlock, predCr, predCr, 12);
- }
-#else
- if (cbp4x4&1)
- {
- ictrans(dataBlock, curCr, curCr, pitch);
- }
-#endif
- cbp4x4 >>= 1;
- dataBlock += 4;
-#ifdef USE_PRED_BLOCK
- predCr += 4;
-#else
- curCr += 4;
-#endif
- }
- dataBlock += 48;
-#ifdef USE_PRED_BLOCK
- predCb += 40;
- predCr += 40;
-#else
- curCb += ((pitch << 2) - 8);
- curCr += ((pitch << 2) - 8);
-#endif
- }
-
-#ifdef MB_BASED_DEBLOCK
- SaveNeighborForIntraPred(video, offset);
-#endif
- return AVC_SUCCESS;
-}
-
-#ifdef MB_BASED_DEBLOCK
-void SaveNeighborForIntraPred(AVCCommonObj *video, int offset)
-{
- AVCPictureData *currPic = video->currPic;
- int pitch;
- uint8 *pred, *predCb, *predCr;
- uint8 *tmp_ptr, tmp_byte;
- uint32 tmp_word;
- int mb_x = video->mb_x;
-
- /* save the value for intra prediction */
-#ifdef USE_PRED_BLOCK
- pitch = 20;
- pred = video->pred + 384; /* bottom line for Y */
- predCb = pred + 152; /* bottom line for Cb */
- predCr = predCb + 144; /* bottom line for Cr */
-#else
- pitch = currPic->pitch;
- tmp_word = offset + (pitch << 2) - (pitch >> 1);
- predCb = currPic->Scb + tmp_word;/* bottom line for Cb */
- predCr = currPic->Scr + tmp_word;/* bottom line for Cr */
-
- offset = (offset << 2) - (mb_x << 4);
- pred = currPic->Sl + offset + (pitch << 4) - pitch;/* bottom line for Y */
-
-#endif
-
- video->intra_pred_topleft = video->intra_pred_top[(mb_x<<4)+15];
- video->intra_pred_topleft_cb = video->intra_pred_top_cb[(mb_x<<3)+7];
- video->intra_pred_topleft_cr = video->intra_pred_top_cr[(mb_x<<3)+7];
-
- /* then copy to video->intra_pred_top, intra_pred_top_cb, intra_pred_top_cr */
- /*memcpy(video->intra_pred_top + (mb_x<<4), pred, 16);
- memcpy(video->intra_pred_top_cb + (mb_x<<3), predCb, 8);
- memcpy(video->intra_pred_top_cr + (mb_x<<3), predCr, 8);*/
- tmp_ptr = video->intra_pred_top + (mb_x << 4);
- *((uint32*)tmp_ptr) = *((uint32*)pred);
- *((uint32*)(tmp_ptr + 4)) = *((uint32*)(pred + 4));
- *((uint32*)(tmp_ptr + 8)) = *((uint32*)(pred + 8));
- *((uint32*)(tmp_ptr + 12)) = *((uint32*)(pred + 12));
- tmp_ptr = video->intra_pred_top_cb + (mb_x << 3);
- *((uint32*)tmp_ptr) = *((uint32*)predCb);
- *((uint32*)(tmp_ptr + 4)) = *((uint32*)(predCb + 4));
- tmp_ptr = video->intra_pred_top_cr + (mb_x << 3);
- *((uint32*)tmp_ptr) = *((uint32*)predCr);
- *((uint32*)(tmp_ptr + 4)) = *((uint32*)(predCr + 4));
-
-
- /* now save last column */
-#ifdef USE_PRED_BLOCK
- pred = video->pred + 99; /* last column*/
-#else
- pred -= ((pitch << 4) - pitch - 15); /* last column */
-#endif
- tmp_ptr = video->intra_pred_left;
- tmp_word = video->intra_pred_topleft;
- tmp_byte = *(pred);
- tmp_word |= (tmp_byte << 8);
- tmp_byte = *(pred += pitch);
- tmp_word |= (tmp_byte << 16);
- tmp_byte = *(pred += pitch);
- tmp_word |= (tmp_byte << 24);
- *((uint32*)tmp_ptr) = tmp_word;
- tmp_word = *(pred += pitch);
- tmp_byte = *(pred += pitch);
- tmp_word |= (tmp_byte << 8);
- tmp_byte = *(pred += pitch);
- tmp_word |= (tmp_byte << 16);
- tmp_byte = *(pred += pitch);
- tmp_word |= (tmp_byte << 24);
- *((uint32*)(tmp_ptr += 4)) = tmp_word;
- tmp_word = *(pred += pitch);
- tmp_byte = *(pred += pitch);
- tmp_word |= (tmp_byte << 8);
- tmp_byte = *(pred += pitch);
- tmp_word |= (tmp_byte << 16);
- tmp_byte = *(pred += pitch);
- tmp_word |= (tmp_byte << 24);
- *((uint32*)(tmp_ptr += 4)) = tmp_word;
- tmp_word = *(pred += pitch);
- tmp_byte = *(pred += pitch);
- tmp_word |= (tmp_byte << 8);
- tmp_byte = *(pred += pitch);
- tmp_word |= (tmp_byte << 16);
- tmp_byte = *(pred += pitch);
- tmp_word |= (tmp_byte << 24);
- *((uint32*)(tmp_ptr += 4)) = tmp_word;
- *(tmp_ptr += 4) = *(pred += pitch);
-
- /* now for Cb */
-#ifdef USE_PRED_BLOCK
- predCb = video->pred + 459;
- pitch = 12;
-#else
- pitch >>= 1;
- predCb -= (7 * pitch - 7);
-#endif
- tmp_ptr = video->intra_pred_left_cb;
- tmp_word = video->intra_pred_topleft_cb;
- tmp_byte = *(predCb);
- tmp_word |= (tmp_byte << 8);
- tmp_byte = *(predCb += pitch);
- tmp_word |= (tmp_byte << 16);
- tmp_byte = *(predCb += pitch);
- tmp_word |= (tmp_byte << 24);
- *((uint32*)tmp_ptr) = tmp_word;
- tmp_word = *(predCb += pitch);
- tmp_byte = *(predCb += pitch);
- tmp_word |= (tmp_byte << 8);
- tmp_byte = *(predCb += pitch);
- tmp_word |= (tmp_byte << 16);
- tmp_byte = *(predCb += pitch);
- tmp_word |= (tmp_byte << 24);
- *((uint32*)(tmp_ptr += 4)) = tmp_word;
- *(tmp_ptr += 4) = *(predCb += pitch);
-
- /* now for Cr */
-#ifdef USE_PRED_BLOCK
- predCr = video->pred + 603;
-#else
- predCr -= (7 * pitch - 7);
-#endif
- tmp_ptr = video->intra_pred_left_cr;
- tmp_word = video->intra_pred_topleft_cr;
- tmp_byte = *(predCr);
- tmp_word |= (tmp_byte << 8);
- tmp_byte = *(predCr += pitch);
- tmp_word |= (tmp_byte << 16);
- tmp_byte = *(predCr += pitch);
- tmp_word |= (tmp_byte << 24);
- *((uint32*)tmp_ptr) = tmp_word;
- tmp_word = *(predCr += pitch);
- tmp_byte = *(predCr += pitch);
- tmp_word |= (tmp_byte << 8);
- tmp_byte = *(predCr += pitch);
- tmp_word |= (tmp_byte << 16);
- tmp_byte = *(predCr += pitch);
- tmp_word |= (tmp_byte << 24);
- *((uint32*)(tmp_ptr += 4)) = tmp_word;
- *(tmp_ptr += 4) = *(predCr += pitch);
-
- return ;
-}
-#endif /* MB_BASED_DEBLOCK */
-
-AVCStatus Intra_4x4(AVCCommonObj *video, int block_x, int block_y, uint8 *comp)
-{
- AVCMacroblock *currMB = video->currMB;
- int block_offset;
- AVCNeighborAvailability availability;
- int pitch = video->currPic->pitch;
-
-#ifdef USE_PRED_BLOCK
- block_offset = (block_y * 80) + (block_x << 2);
-#else
- block_offset = (block_y << 2) * pitch + (block_x << 2);
-#endif
-
-#ifdef MB_BASED_DEBLOCK
- /* boundary blocks use video->pred_intra_top, pred_intra_left, pred_intra_topleft */
- if (!block_x)
- {
- video->pintra_pred_left = video->intra_pred_left + 1 + (block_y << 2);
- pitch = 1;
- }
- else
- {
- video->pintra_pred_left = video->pred_block + block_offset - 1;
- pitch = video->pred_pitch;
- }
-
- if (!block_y)
- {
- video->pintra_pred_top = video->intra_pred_top + (block_x << 2) + (video->mb_x << 4);
- }
- else
- {
- video->pintra_pred_top = video->pred_block + block_offset - video->pred_pitch;
- }
-
- if (!block_x)
- {
- video->intra_pred_topleft = video->intra_pred_left[block_y<<2];
- }
- else if (!block_y)
- {
- video->intra_pred_topleft = video->intra_pred_top[(video->mb_x<<4)+(block_x<<2)-1];
- }
- else
- {
- video->intra_pred_topleft = video->pred_block[block_offset - video->pred_pitch - 1];
- }
-
-#else
- /* normal case */
- video->pintra_pred_top = comp - pitch;
- video->pintra_pred_left = comp - 1;
- if (video->mb_y || block_y)
- {
- video->intra_pred_topleft = *(comp - pitch - 1);
- }
-#endif
-
- switch (currMB->i4Mode[(block_y << 2) + block_x])
- {
- case AVC_I4_Vertical: /* Intra_4x4_Vertical */
- if (block_y > 0 || video->intraAvailB)/* to prevent out-of-bound access*/
- {
- Intra_4x4_Vertical(video, block_offset);
- }
- else
- {
- return AVC_FAIL;
- }
- break;
-
- case AVC_I4_Horizontal: /* Intra_4x4_Horizontal */
- if (block_x || video->intraAvailA) /* to prevent out-of-bound access */
- {
- Intra_4x4_Horizontal(video, pitch, block_offset);
- }
- else
- {
- return AVC_FAIL;
- }
- break;
-
- case AVC_I4_DC: /* Intra_4x4_DC */
- availability.left = TRUE;
- availability.top = TRUE;
- if (!block_y)
- { /* check availability up */
- availability.top = video->intraAvailB ;
- }
- if (!block_x)
- { /* check availability left */
- availability.left = video->intraAvailA ;
- }
- Intra_4x4_DC(video, pitch, block_offset, &availability);
- break;
-
- case AVC_I4_Diagonal_Down_Left: /* Intra_4x4_Diagonal_Down_Left */
- /* lookup table will be more appropriate for this case */
- if (block_y == 0 && !video->intraAvailB)
- {
- return AVC_FAIL;
- }
-
- availability.top_right = BlkTopRight[(block_y<<2) + block_x];
-
- if (availability.top_right == 2)
- {
- availability.top_right = video->intraAvailB;
- }
- else if (availability.top_right == 3)
- {
- availability.top_right = video->intraAvailC;
- }
-
- Intra_4x4_Down_Left(video, block_offset, &availability);
- break;
-
- case AVC_I4_Diagonal_Down_Right: /* Intra_4x4_Diagonal_Down_Right */
- if ((block_y && block_x) /* to prevent out-of-bound access */
- || (block_y && video->intraAvailA)
- || (block_x && video->intraAvailB)
- || (video->intraAvailA && video->intraAvailD && video->intraAvailB))
- {
- Intra_4x4_Diagonal_Down_Right(video, pitch, block_offset);
- }
- else
- {
- return AVC_FAIL;
- }
- break;
-
- case AVC_I4_Vertical_Right: /* Intra_4x4_Vertical_Right */
- if ((block_y && block_x) /* to prevent out-of-bound access */
- || (block_y && video->intraAvailA)
- || (block_x && video->intraAvailB)
- || (video->intraAvailA && video->intraAvailD && video->intraAvailB))
- {
- Intra_4x4_Diagonal_Vertical_Right(video, pitch, block_offset);
- }
- else
- {
- return AVC_FAIL;
- }
- break;
-
- case AVC_I4_Horizontal_Down: /* Intra_4x4_Horizontal_Down */
- if ((block_y && block_x) /* to prevent out-of-bound access */
- || (block_y && video->intraAvailA)
- || (block_x && video->intraAvailB)
- || (video->intraAvailA && video->intraAvailD && video->intraAvailB))
- {
- Intra_4x4_Diagonal_Horizontal_Down(video, pitch, block_offset);
- }
- else
- {
- return AVC_FAIL;
- }
- break;
-
- case AVC_I4_Vertical_Left: /* Intra_4x4_Vertical_Left */
- /* lookup table may be more appropriate for this case */
- if (block_y == 0 && !video->intraAvailB)
- {
- return AVC_FAIL;
- }
-
- availability.top_right = BlkTopRight[(block_y<<2) + block_x];
-
- if (availability.top_right == 2)
- {
- availability.top_right = video->intraAvailB;
- }
- else if (availability.top_right == 3)
- {
- availability.top_right = video->intraAvailC;
- }
-
- Intra_4x4_Vertical_Left(video, block_offset, &availability);
- break;
-
- case AVC_I4_Horizontal_Up: /* Intra_4x4_Horizontal_Up */
- if (block_x || video->intraAvailA)
- {
- Intra_4x4_Horizontal_Up(video, pitch, block_offset);
- }
- else
- {
- return AVC_FAIL;
- }
- break;
-
-
- default:
-
- break;
- }
-
- return AVC_SUCCESS;
-}
-
-
-/* =============================== BEGIN 4x4
-MODES======================================*/
-void Intra_4x4_Vertical(AVCCommonObj *video, int block_offset)
-{
- uint8 *comp_ref = video->pintra_pred_top;
- uint32 temp;
- uint8 *pred = video->pred_block + block_offset;
- int pred_pitch = video->pred_pitch;
-
- /*P = (int) *comp_ref++;
- Q = (int) *comp_ref++;
- R = (int) *comp_ref++;
- S = (int) *comp_ref++;
- temp = S|(R<<8)|(Q<<16)|(P<<24);*/
- temp = *((uint32*)comp_ref);
-
- *((uint32*)pred) = temp; /* write 4 at a time */
- pred += pred_pitch;
- *((uint32*)pred) = temp;
- pred += pred_pitch;
- *((uint32*)pred) = temp;
- pred += pred_pitch;
- *((uint32*)pred) = temp;
-
- return ;
-}
-
-void Intra_4x4_Horizontal(AVCCommonObj *video, int pitch, int block_offset)
-{
- uint8 *comp_ref = video->pintra_pred_left;
- uint32 temp;
- int P;
- uint8 *pred = video->pred_block + block_offset;
- int pred_pitch = video->pred_pitch;
-
- P = *comp_ref;
- temp = P | (P << 8);
- temp = temp | (temp << 16);
- *((uint32*)pred) = temp;
- pred += pred_pitch;
- comp_ref += pitch;
- P = *comp_ref;
- temp = P | (P << 8);
- temp = temp | (temp << 16);
- *((uint32*)pred) = temp;
- pred += pred_pitch;
- comp_ref += pitch;
- P = *comp_ref;
- temp = P | (P << 8);
- temp = temp | (temp << 16);
- *((uint32*)pred) = temp;
- pred += pred_pitch;
- comp_ref += pitch;
- P = *comp_ref;
- temp = P | (P << 8);
- temp = temp | (temp << 16);
- *((uint32*)pred) = temp;
-
- return ;
-}
-
-void Intra_4x4_DC(AVCCommonObj *video, int pitch, int block_offset,
- AVCNeighborAvailability *availability)
-{
- uint8 *comp_ref = video->pintra_pred_left;
- uint32 temp;
- int DC;
- uint8 *pred = video->pred_block + block_offset;
- int pred_pitch = video->pred_pitch;
-
- if (availability->left)
- {
- DC = *comp_ref;
- comp_ref += pitch;
- DC += *comp_ref;
- comp_ref += pitch;
- DC += *comp_ref;
- comp_ref += pitch;
- DC += *comp_ref;
- comp_ref = video->pintra_pred_top;
-
- if (availability->top)
- {
- DC = (comp_ref[0] + comp_ref[1] + comp_ref[2] + comp_ref[3] + DC + 4) >> 3;
- }
- else
- {
- DC = (DC + 2) >> 2;
-
- }
- }
- else if (availability->top)
- {
- comp_ref = video->pintra_pred_top;
- DC = (comp_ref[0] + comp_ref[1] + comp_ref[2] + comp_ref[3] + 2) >> 2;
-
- }
- else
- {
- DC = 128;
- }
-
- temp = DC | (DC << 8);
- temp = temp | (temp << 16);
- *((uint32*)pred) = temp;
- pred += pred_pitch;
- *((uint32*)pred) = temp;
- pred += pred_pitch;
- *((uint32*)pred) = temp;
- pred += pred_pitch;
- *((uint32*)pred) = temp;
-
- return ;
-}
-
-void Intra_4x4_Down_Left(AVCCommonObj *video, int block_offset,
- AVCNeighborAvailability *availability)
-{
- uint8 *comp_refx = video->pintra_pred_top;
- uint32 temp;
- int r0, r1, r2, r3, r4, r5, r6, r7;
- uint8 *pred = video->pred_block + block_offset;
- int pred_pitch = video->pred_pitch;
-
- r0 = *comp_refx++;
- r1 = *comp_refx++;
- r2 = *comp_refx++;
- r3 = *comp_refx++;
- if (availability->top_right)
- {
- r4 = *comp_refx++;
- r5 = *comp_refx++;
- r6 = *comp_refx++;
- r7 = *comp_refx++;
- }
- else
- {
- r4 = r3;
- r5 = r3;
- r6 = r3;
- r7 = r3;
- }
-
- r0 += (r1 << 1);
- r0 += r2;
- r0 += 2;
- r0 >>= 2;
- r1 += (r2 << 1);
- r1 += r3;
- r1 += 2;
- r1 >>= 2;
- r2 += (r3 << 1);
- r2 += r4;
- r2 += 2;
- r2 >>= 2;
- r3 += (r4 << 1);
- r3 += r5;
- r3 += 2;
- r3 >>= 2;
- r4 += (r5 << 1);
- r4 += r6;
- r4 += 2;
- r4 >>= 2;
- r5 += (r6 << 1);
- r5 += r7;
- r5 += 2;
- r5 >>= 2;
- r6 += (3 * r7);
- r6 += 2;
- r6 >>= 2;
-
- temp = r0 | (r1 << 8);
- temp |= (r2 << 16);
- temp |= (r3 << 24);
- *((uint32*)pred) = temp;
- pred += pred_pitch;
-
- temp = (temp >> 8) | (r4 << 24);
- *((uint32*)pred) = temp;
- pred += pred_pitch;
-
- temp = (temp >> 8) | (r5 << 24);
- *((uint32*)pred) = temp;
- pred += pred_pitch;
-
- temp = (temp >> 8) | (r6 << 24);
- *((uint32*)pred) = temp;
-
- return ;
-}
-
-void Intra_4x4_Diagonal_Down_Right(AVCCommonObj *video, int pitch, int
- block_offset)
-{
- uint8 *comp_refx = video->pintra_pred_top;
- uint8 *comp_refy = video->pintra_pred_left;
- uint32 temp;
- int P_x, Q_x, R_x, P_y, Q_y, R_y, D;
- int x0, x1, x2;
- uint8 *pred = video->pred_block + block_offset;
- int pred_pitch = video->pred_pitch;
-
- temp = *((uint32*)comp_refx); /* read 4 bytes */
- x0 = temp & 0xFF;
- x1 = (temp >> 8) & 0xFF;
- x2 = (temp >> 16) & 0xFF;
-
- Q_x = (x0 + 2 * x1 + x2 + 2) >> 2;
- R_x = (x1 + 2 * x2 + (temp >> 24) + 2) >> 2;
-
- x2 = video->intra_pred_topleft; /* re-use x2 instead of y0 */
- P_x = (x2 + 2 * x0 + x1 + 2) >> 2;
-
- x1 = *comp_refy;
- comp_refy += pitch; /* re-use x1 instead of y1 */
- D = (x0 + 2 * x2 + x1 + 2) >> 2;
-
- x0 = *comp_refy;
- comp_refy += pitch; /* re-use x0 instead of y2 */
- P_y = (x2 + 2 * x1 + x0 + 2) >> 2;
-
- x2 = *comp_refy;
- comp_refy += pitch; /* re-use x2 instead of y3 */
- Q_y = (x1 + 2 * x0 + x2 + 2) >> 2;
-
- x1 = *comp_refy; /* re-use x1 instead of y4 */
- R_y = (x0 + 2 * x2 + x1 + 2) >> 2;
-
- /* we can pack these */
- temp = D | (P_x << 8); //[D P_x Q_x R_x]
- //[P_y D P_x Q_x]
- temp |= (Q_x << 16); //[Q_y P_y D P_x]
- temp |= (R_x << 24); //[R_y Q_y P_y D ]
- *((uint32*)pred) = temp;
- pred += pred_pitch;
-
- temp = P_y | (D << 8);
- temp |= (P_x << 16);
- temp |= (Q_x << 24);
- *((uint32*)pred) = temp;
- pred += pred_pitch;
-
- temp = Q_y | (P_y << 8);
- temp |= (D << 16);
- temp |= (P_x << 24);
- *((uint32*)pred) = temp;
- pred += pred_pitch;
-
- temp = R_y | (Q_y << 8);
- temp |= (P_y << 16);
- temp |= (D << 24);
- *((uint32*)pred) = temp;
-
- return ;
-}
-
-void Intra_4x4_Diagonal_Vertical_Right(AVCCommonObj *video, int pitch, int block_offset)
-{
- uint8 *comp_refx = video->pintra_pred_top;
- uint8 *comp_refy = video->pintra_pred_left;
- uint32 temp;
- int P0, Q0, R0, S0, P1, Q1, R1, P2, Q2, D;
- int x0, x1, x2;
- uint8 *pred = video->pred_block + block_offset;
- int pred_pitch = video->pred_pitch;
-
- x0 = *comp_refx++;
- x1 = *comp_refx++;
- Q0 = x0 + x1 + 1;
-
- x2 = *comp_refx++;
- R0 = x1 + x2 + 1;
-
- x1 = *comp_refx++; /* reuse x1 instead of x3 */
- S0 = x2 + x1 + 1;
-
- x1 = video->intra_pred_topleft; /* reuse x1 instead of y0 */
- P0 = x1 + x0 + 1;
-
- x2 = *comp_refy;
- comp_refy += pitch; /* reuse x2 instead of y1 */
- D = (x2 + 2 * x1 + x0 + 2) >> 2;
-
- P1 = (P0 + Q0) >> 2;
- Q1 = (Q0 + R0) >> 2;
- R1 = (R0 + S0) >> 2;
-
- P0 >>= 1;
- Q0 >>= 1;
- R0 >>= 1;
- S0 >>= 1;
-
- x0 = *comp_refy;
- comp_refy += pitch; /* reuse x0 instead of y2 */
- P2 = (x1 + 2 * x2 + x0 + 2) >> 2;
- x1 = *comp_refy;
- comp_refy += pitch; /* reuse x1 instead of y3 */
- Q2 = (x2 + 2 * x0 + x1 + 2) >> 2;
-
- temp = P0 | (Q0 << 8); //[P0 Q0 R0 S0]
- //[D P1 Q1 R1]
- temp |= (R0 << 16); //[P2 P0 Q0 R0]
- temp |= (S0 << 24); //[Q2 D P1 Q1]
- *((uint32*)pred) = temp;
- pred += pred_pitch;
-
- temp = D | (P1 << 8);
- temp |= (Q1 << 16);
- temp |= (R1 << 24);
- *((uint32*)pred) = temp;
- pred += pred_pitch;
-
- temp = P2 | (P0 << 8);
- temp |= (Q0 << 16);
- temp |= (R0 << 24);
- *((uint32*)pred) = temp;
- pred += pred_pitch;
-
- temp = Q2 | (D << 8);
- temp |= (P1 << 16);
- temp |= (Q1 << 24);
- *((uint32*)pred) = temp;
-
- return ;
-}
-
-void Intra_4x4_Diagonal_Horizontal_Down(AVCCommonObj *video, int pitch,
- int block_offset)
-{
- uint8 *comp_refx = video->pintra_pred_top;
- uint8 *comp_refy = video->pintra_pred_left;
- uint32 temp;
- int P0, Q0, R0, S0, P1, Q1, R1, P2, Q2, D;
- int x0, x1, x2;
- uint8 *pred = video->pred_block + block_offset;
- int pred_pitch = video->pred_pitch;
-
- x0 = *comp_refx++;
- x1 = *comp_refx++;
- x2 = *comp_refx++;
- Q2 = (x0 + 2 * x1 + x2 + 2) >> 2;
-
- x2 = video->intra_pred_topleft; /* reuse x2 instead of y0 */
- P2 = (x2 + 2 * x0 + x1 + 2) >> 2;
-
- x1 = *comp_refy;
- comp_refy += pitch; /* reuse x1 instead of y1 */
- D = (x1 + 2 * x2 + x0 + 2) >> 2;
- P0 = x2 + x1 + 1;
-
- x0 = *comp_refy;
- comp_refy += pitch; /* reuse x0 instead of y2 */
- Q0 = x1 + x0 + 1;
-
- x1 = *comp_refy;
- comp_refy += pitch; /* reuse x1 instead of y3 */
- R0 = x0 + x1 + 1;
-
- x2 = *comp_refy; /* reuse x2 instead of y4 */
- S0 = x1 + x2 + 1;
-
- P1 = (P0 + Q0) >> 2;
- Q1 = (Q0 + R0) >> 2;
- R1 = (R0 + S0) >> 2;
-
- P0 >>= 1;
- Q0 >>= 1;
- R0 >>= 1;
- S0 >>= 1;
-
-
- /* we can pack these */
- temp = P0 | (D << 8); //[P0 D P2 Q2]
- //[Q0 P1 P0 D ]
- temp |= (P2 << 16); //[R0 Q1 Q0 P1]
- temp |= (Q2 << 24); //[S0 R1 R0 Q1]
- *((uint32*)pred) = temp;
- pred += pred_pitch;
-
- temp = Q0 | (P1 << 8);
- temp |= (P0 << 16);
- temp |= (D << 24);
- *((uint32*)pred) = temp;
- pred += pred_pitch;
-
- temp = R0 | (Q1 << 8);
- temp |= (Q0 << 16);
- temp |= (P1 << 24);
- *((uint32*)pred) = temp;
- pred += pred_pitch;
-
- temp = S0 | (R1 << 8);
- temp |= (R0 << 16);
- temp |= (Q1 << 24);
- *((uint32*)pred) = temp;
-
- return ;
-}
-
-void Intra_4x4_Vertical_Left(AVCCommonObj *video, int block_offset, AVCNeighborAvailability *availability)
-{
- uint8 *comp_refx = video->pintra_pred_top;
- uint32 temp1, temp2;
- int x0, x1, x2, x3, x4, x5, x6;
- uint8 *pred = video->pred_block + block_offset;
- int pred_pitch = video->pred_pitch;
-
- x0 = *comp_refx++;
- x1 = *comp_refx++;
- x2 = *comp_refx++;
- x3 = *comp_refx++;
- if (availability->top_right)
- {
- x4 = *comp_refx++;
- x5 = *comp_refx++;
- x6 = *comp_refx++;
- }
- else
- {
- x4 = x3;
- x5 = x3;
- x6 = x3;
- }
-
- x0 += x1 + 1;
- x1 += x2 + 1;
- x2 += x3 + 1;
- x3 += x4 + 1;
- x4 += x5 + 1;
- x5 += x6 + 1;
-
- temp1 = (x0 >> 1);
- temp1 |= ((x1 >> 1) << 8);
- temp1 |= ((x2 >> 1) << 16);
- temp1 |= ((x3 >> 1) << 24);
-
- *((uint32*)pred) = temp1;
- pred += pred_pitch;
-
- temp2 = ((x0 + x1) >> 2);
- temp2 |= (((x1 + x2) >> 2) << 8);
- temp2 |= (((x2 + x3) >> 2) << 16);
- temp2 |= (((x3 + x4) >> 2) << 24);
-
- *((uint32*)pred) = temp2;
- pred += pred_pitch;
-
- temp1 = (temp1 >> 8) | ((x4 >> 1) << 24); /* rotate out old value */
- *((uint32*)pred) = temp1;
- pred += pred_pitch;
-
- temp2 = (temp2 >> 8) | (((x4 + x5) >> 2) << 24); /* rotate out old value */
- *((uint32*)pred) = temp2;
- pred += pred_pitch;
-
- return ;
-}
-
-void Intra_4x4_Horizontal_Up(AVCCommonObj *video, int pitch, int block_offset)
-{
- uint8 *comp_refy = video->pintra_pred_left;
- uint32 temp;
- int Q0, R0, Q1, D0, D1, P0, P1;
- int y0, y1, y2, y3;
- uint8 *pred = video->pred_block + block_offset;
- int pred_pitch = video->pred_pitch;
-
- y0 = *comp_refy;
- comp_refy += pitch;
- y1 = *comp_refy;
- comp_refy += pitch;
- y2 = *comp_refy;
- comp_refy += pitch;
- y3 = *comp_refy;
-
- Q0 = (y1 + y2 + 1) >> 1;
- Q1 = (y1 + (y2 << 1) + y3 + 2) >> 2;
- P0 = ((y0 + y1 + 1) >> 1);
- P1 = ((y0 + (y1 << 1) + y2 + 2) >> 2);
-
- temp = P0 | (P1 << 8); // [P0 P1 Q0 Q1]
- temp |= (Q0 << 16); // [Q0 Q1 R0 DO]
- temp |= (Q1 << 24); // [R0 D0 D1 D1]
- *((uint32*)pred) = temp; // [D1 D1 D1 D1]
- pred += pred_pitch;
-
- D0 = (y2 + 3 * y3 + 2) >> 2;
- R0 = (y2 + y3 + 1) >> 1;
-
- temp = Q0 | (Q1 << 8);
- temp |= (R0 << 16);
- temp |= (D0 << 24);
- *((uint32*)pred) = temp;
- pred += pred_pitch;
-
- D1 = y3;
-
- temp = R0 | (D0 << 8);
- temp |= (D1 << 16);
- temp |= (D1 << 24);
- *((uint32*)pred) = temp;
- pred += pred_pitch;
-
- temp = D1 | (D1 << 8);
- temp |= (temp << 16);
- *((uint32*)pred) = temp;
-
- return ;
-}
-/* =============================== END 4x4 MODES======================================*/
-void Intra_16x16_Vertical(AVCCommonObj *video)
-{
- int i;
- uint32 temp1, temp2, temp3, temp4;
- uint8 *comp_ref = video->pintra_pred_top;
- uint8 *pred = video->pred_block;
- int pred_pitch = video->pred_pitch;
-
- temp1 = *((uint32*)comp_ref);
- comp_ref += 4;
-
- temp2 = *((uint32*)comp_ref);
- comp_ref += 4;
-
- temp3 = *((uint32*)comp_ref);
- comp_ref += 4;
-
- temp4 = *((uint32*)comp_ref);
- comp_ref += 4;
-
- i = 16;
- while (i > 0)
- {
- *((uint32*)pred) = temp1;
- *((uint32*)(pred + 4)) = temp2;
- *((uint32*)(pred + 8)) = temp3;
- *((uint32*)(pred + 12)) = temp4;
- pred += pred_pitch;
- i--;
- }
-
- return ;
-}
-
-void Intra_16x16_Horizontal(AVCCommonObj *video, int pitch)
-{
- int i;
- uint32 temp;
- uint8 *comp_ref = video->pintra_pred_left;
- uint8 *pred = video->pred_block;
- int pred_pitch = video->pred_pitch;
-
- for (i = 0; i < 16; i++)
- {
- temp = *comp_ref;
- temp |= (temp << 8);
- temp |= (temp << 16);
- *((uint32*)pred) = temp;
- *((uint32*)(pred + 4)) = temp;
- *((uint32*)(pred + 8)) = temp;
- *((uint32*)(pred + 12)) = temp;
- pred += pred_pitch;
- comp_ref += pitch;
- }
-}
-
-
-void Intra_16x16_DC(AVCCommonObj *video, int pitch)
-{
- int i;
- uint32 temp, temp2;
- uint8 *comp_ref_x = video->pintra_pred_top;
- uint8 *comp_ref_y = video->pintra_pred_left;
- int sum = 0;
- uint8 *pred = video->pred_block;
- int pred_pitch = video->pred_pitch;
-
- if (video->intraAvailB)
- {
- temp = *((uint32*)comp_ref_x);
- comp_ref_x += 4;
- temp2 = (temp >> 8) & 0xFF00FF;
- temp &= 0xFF00FF;
- temp += temp2;
- sum = temp + (temp >> 16);
- temp = *((uint32*)comp_ref_x);
- comp_ref_x += 4;
- temp2 = (temp >> 8) & 0xFF00FF;
- temp &= 0xFF00FF;
- temp += temp2;
- sum += temp + (temp >> 16);
- temp = *((uint32*)comp_ref_x);
- comp_ref_x += 4;
- temp2 = (temp >> 8) & 0xFF00FF;
- temp &= 0xFF00FF;
- temp += temp2;
- sum += temp + (temp >> 16);
- temp = *((uint32*)comp_ref_x);
- comp_ref_x += 4;
- temp2 = (temp >> 8) & 0xFF00FF;
- temp &= 0xFF00FF;
- temp += temp2;
- sum += temp + (temp >> 16);
- sum &= 0xFFFF;
-
- if (video->intraAvailA)
- {
- for (i = 0; i < 16; i++)
- {
- sum += (*comp_ref_y);
- comp_ref_y += pitch;
- }
- sum = (sum + 16) >> 5;
- }
- else
- {
- sum = (sum + 8) >> 4;
- }
- }
- else if (video->intraAvailA)
- {
- for (i = 0; i < 16; i++)
- {
- sum += *comp_ref_y;
- comp_ref_y += pitch;
- }
- sum = (sum + 8) >> 4;
- }
- else
- {
- sum = 128;
- }
-
- temp = sum | (sum << 8);
- temp |= (temp << 16);
-
- for (i = 0; i < 16; i++)
- {
- *((uint32*)pred) = temp;
- *((uint32*)(pred + 4)) = temp;
- *((uint32*)(pred + 8)) = temp;
- *((uint32*)(pred + 12)) = temp;
- pred += pred_pitch;
- }
-
-}
-
-void Intra_16x16_Plane(AVCCommonObj *video, int pitch)
-{
- int i, a_16, b, c, factor_c;
- uint8 *comp_ref_x = video->pintra_pred_top;
- uint8 *comp_ref_y = video->pintra_pred_left;
- uint8 *comp_ref_x0, *comp_ref_x1, *comp_ref_y0, *comp_ref_y1;
- int H = 0, V = 0 , tmp;
- uint8 *pred = video->pred_block;
- uint32 temp;
- uint8 byte1, byte2, byte3;
- int value;
- int pred_pitch = video->pred_pitch;
-
- comp_ref_x0 = comp_ref_x + 8;
- comp_ref_x1 = comp_ref_x + 6;
- comp_ref_y0 = comp_ref_y + (pitch << 3);
- comp_ref_y1 = comp_ref_y + 6 * pitch;
-
- for (i = 1; i < 8; i++)
- {
- H += i * (*comp_ref_x0++ - *comp_ref_x1--);
- V += i * (*comp_ref_y0 - *comp_ref_y1);
- comp_ref_y0 += pitch;
- comp_ref_y1 -= pitch;
- }
-
- H += i * (*comp_ref_x0++ - video->intra_pred_topleft);
- V += i * (*comp_ref_y0 - *comp_ref_y1);
-
-
- a_16 = ((*(comp_ref_x + 15) + *(comp_ref_y + 15 * pitch)) << 4) + 16;;
- b = (5 * H + 32) >> 6;
- c = (5 * V + 32) >> 6;
-
- tmp = 0;
-
- for (i = 0; i < 16; i++)
- {
- factor_c = a_16 + c * (tmp++ - 7);
-
- factor_c -= 7 * b;
-
- value = factor_c >> 5;
- factor_c += b;
- CLIP_RESULT(value)
- byte1 = value;
- value = factor_c >> 5;
- factor_c += b;
- CLIP_RESULT(value)
- byte2 = value;
- value = factor_c >> 5;
- factor_c += b;
- CLIP_RESULT(value)
- byte3 = value;
- value = factor_c >> 5;
- factor_c += b;
- CLIP_RESULT(value)
- temp = byte1 | (byte2 << 8);
- temp |= (byte3 << 16);
- temp |= (value << 24);
- *((uint32*)pred) = temp;
-
- value = factor_c >> 5;
- factor_c += b;
- CLIP_RESULT(value)
- byte1 = value;
- value = factor_c >> 5;
- factor_c += b;
- CLIP_RESULT(value)
- byte2 = value;
- value = factor_c >> 5;
- factor_c += b;
- CLIP_RESULT(value)
- byte3 = value;
- value = factor_c >> 5;
- factor_c += b;
- CLIP_RESULT(value)
- temp = byte1 | (byte2 << 8);
- temp |= (byte3 << 16);
- temp |= (value << 24);
- *((uint32*)(pred + 4)) = temp;
-
- value = factor_c >> 5;
- factor_c += b;
- CLIP_RESULT(value)
- byte1 = value;
- value = factor_c >> 5;
- factor_c += b;
- CLIP_RESULT(value)
- byte2 = value;
- value = factor_c >> 5;
- factor_c += b;
- CLIP_RESULT(value)
- byte3 = value;
- value = factor_c >> 5;
- factor_c += b;
- CLIP_RESULT(value)
- temp = byte1 | (byte2 << 8);
- temp |= (byte3 << 16);
- temp |= (value << 24);
- *((uint32*)(pred + 8)) = temp;
-
- value = factor_c >> 5;
- factor_c += b;
- CLIP_RESULT(value)
- byte1 = value;
- value = factor_c >> 5;
- factor_c += b;
- CLIP_RESULT(value)
- byte2 = value;
- value = factor_c >> 5;
- factor_c += b;
- CLIP_RESULT(value)
- byte3 = value;
- value = factor_c >> 5;
- CLIP_RESULT(value)
- temp = byte1 | (byte2 << 8);
- temp |= (byte3 << 16);
- temp |= (value << 24);
- *((uint32*)(pred + 12)) = temp;
- pred += pred_pitch;
- }
-}
-
-/************** Chroma intra prediction *********************/
-
-void Intra_Chroma_DC(AVCCommonObj *video, int pitch, uint8 *predCb, uint8 *predCr)
-{
- int i;
- uint32 temp, temp2, pred_a, pred_b;
- uint8 *comp_ref_x, *comp_ref_y;
- uint8 *comp_ref_cb_x = video->pintra_pred_top_cb;
- uint8 *comp_ref_cb_y = video->pintra_pred_left_cb;
- uint8 *comp_ref_cr_x = video->pintra_pred_top_cr;
- uint8 *comp_ref_cr_y = video->pintra_pred_left_cr;
- int component, j;
- int sum_x0, sum_x1, sum_y0, sum_y1;
- int pred_0[2], pred_1[2], pred_2[2], pred_3[2];
- int pred_pitch = video->pred_pitch;
- uint8 *pred;
-
- if (video->intraAvailB & video->intraAvailA)
- {
- comp_ref_x = comp_ref_cb_x;
- comp_ref_y = comp_ref_cb_y;
- for (i = 0; i < 2; i++)
- {
- temp = *((uint32*)comp_ref_x);
- comp_ref_x += 4;
- temp2 = (temp >> 8) & 0xFF00FF;
- temp &= 0xFF00FF;
- temp += temp2;
- temp += (temp >> 16);
- sum_x0 = temp & 0xFFFF;
-
- temp = *((uint32*)comp_ref_x);
- temp2 = (temp >> 8) & 0xFF00FF;
- temp &= 0xFF00FF;
- temp += temp2;
- temp += (temp >> 16);
- sum_x1 = temp & 0xFFFF;
-
- pred_1[i] = (sum_x1 + 2) >> 2;
-
- sum_y0 = *comp_ref_y;
- sum_y0 += *(comp_ref_y += pitch);
- sum_y0 += *(comp_ref_y += pitch);
- sum_y0 += *(comp_ref_y += pitch);
-
- sum_y1 = *(comp_ref_y += pitch);
- sum_y1 += *(comp_ref_y += pitch);
- sum_y1 += *(comp_ref_y += pitch);
- sum_y1 += *(comp_ref_y += pitch);
-
- pred_2[i] = (sum_y1 + 2) >> 2;
-
- pred_0[i] = (sum_y0 + sum_x0 + 4) >> 3;
- pred_3[i] = (sum_y1 + sum_x1 + 4) >> 3;
-
- comp_ref_x = comp_ref_cr_x;
- comp_ref_y = comp_ref_cr_y;
- }
- }
-
- else if (video->intraAvailA)
- {
- comp_ref_y = comp_ref_cb_y;
- for (i = 0; i < 2; i++)
- {
- sum_y0 = *comp_ref_y;
- sum_y0 += *(comp_ref_y += pitch);
- sum_y0 += *(comp_ref_y += pitch);
- sum_y0 += *(comp_ref_y += pitch);
-
- sum_y1 = *(comp_ref_y += pitch);
- sum_y1 += *(comp_ref_y += pitch);
- sum_y1 += *(comp_ref_y += pitch);
- sum_y1 += *(comp_ref_y += pitch);
-
- pred_0[i] = pred_1[i] = (sum_y0 + 2) >> 2;
- pred_2[i] = pred_3[i] = (sum_y1 + 2) >> 2;
- comp_ref_y = comp_ref_cr_y;
- }
- }
- else if (video->intraAvailB)
- {
- comp_ref_x = comp_ref_cb_x;
- for (i = 0; i < 2; i++)
- {
- temp = *((uint32*)comp_ref_x);
- comp_ref_x += 4;
- temp2 = (temp >> 8) & 0xFF00FF;
- temp &= 0xFF00FF;
- temp += temp2;
- temp += (temp >> 16);
- sum_x0 = temp & 0xFFFF;
-
- temp = *((uint32*)comp_ref_x);
- temp2 = (temp >> 8) & 0xFF00FF;
- temp &= 0xFF00FF;
- temp += temp2;
- temp += (temp >> 16);
- sum_x1 = temp & 0xFFFF;
-
- pred_0[i] = pred_2[i] = (sum_x0 + 2) >> 2;
- pred_1[i] = pred_3[i] = (sum_x1 + 2) >> 2;
- comp_ref_x = comp_ref_cr_x;
- }
- }
- else
- {
- pred_0[0] = pred_0[1] = pred_1[0] = pred_1[1] =
- pred_2[0] = pred_2[1] = pred_3[0] = pred_3[1] = 128;
- }
-
- pred = predCb;
- for (component = 0; component < 2; component++)
- {
- pred_a = pred_0[component];
- pred_b = pred_1[component];
- pred_a |= (pred_a << 8);
- pred_a |= (pred_a << 16);
- pred_b |= (pred_b << 8);
- pred_b |= (pred_b << 16);
-
- for (i = 4; i < 6; i++)
- {
- for (j = 0; j < 4; j++) /* 4 lines */
- {
- *((uint32*)pred) = pred_a;
- *((uint32*)(pred + 4)) = pred_b;
- pred += pred_pitch; /* move to the next line */
- }
- pred_a = pred_2[component];
- pred_b = pred_3[component];
- pred_a |= (pred_a << 8);
- pred_a |= (pred_a << 16);
- pred_b |= (pred_b << 8);
- pred_b |= (pred_b << 16);
- }
- pred = predCr; /* point to cr */
- }
-}
-
-void Intra_Chroma_Horizontal(AVCCommonObj *video, int pitch, uint8 *predCb, uint8 *predCr)
-{
- int i;
- uint32 temp;
- uint8 *comp_ref_cb_y = video->pintra_pred_left_cb;
- uint8 *comp_ref_cr_y = video->pintra_pred_left_cr;
- uint8 *comp;
- int component, j;
- int pred_pitch = video->pred_pitch;
- uint8 *pred;
-
- comp = comp_ref_cb_y;
- pred = predCb;
- for (component = 0; component < 2; component++)
- {
- for (i = 4; i < 6; i++)
- {
- for (j = 0; j < 4; j++)
- {
- temp = *comp;
- comp += pitch;
- temp |= (temp << 8);
- temp |= (temp << 16);
- *((uint32*)pred) = temp;
- *((uint32*)(pred + 4)) = temp;
- pred += pred_pitch;
- }
- }
- comp = comp_ref_cr_y;
- pred = predCr; /* point to cr */
- }
-
-}
-
-void Intra_Chroma_Vertical(AVCCommonObj *video, uint8 *predCb, uint8 *predCr)
-{
- uint32 temp1, temp2;
- uint8 *comp_ref_cb_x = video->pintra_pred_top_cb;
- uint8 *comp_ref_cr_x = video->pintra_pred_top_cr;
- uint8 *comp_ref;
- int component, j;
- int pred_pitch = video->pred_pitch;
- uint8 *pred;
-
- comp_ref = comp_ref_cb_x;
- pred = predCb;
- for (component = 0; component < 2; component++)
- {
- temp1 = *((uint32*)comp_ref);
- temp2 = *((uint32*)(comp_ref + 4));
- for (j = 0; j < 8; j++)
- {
- *((uint32*)pred) = temp1;
- *((uint32*)(pred + 4)) = temp2;
- pred += pred_pitch;
- }
- comp_ref = comp_ref_cr_x;
- pred = predCr; /* point to cr */
- }
-
-}
-
-void Intra_Chroma_Plane(AVCCommonObj *video, int pitch, uint8 *predCb, uint8 *predCr)
-{
- int i;
- int a_16_C[2], b_C[2], c_C[2], a_16, b, c, factor_c;
- uint8 *comp_ref_x, *comp_ref_y, *comp_ref_x0, *comp_ref_x1, *comp_ref_y0, *comp_ref_y1;
- int component, j;
- int H, V, tmp;
- uint32 temp;
- uint8 byte1, byte2, byte3;
- int value;
- uint8 topleft;
- int pred_pitch = video->pred_pitch;
- uint8 *pred;
-
- comp_ref_x = video->pintra_pred_top_cb;
- comp_ref_y = video->pintra_pred_left_cb;
- topleft = video->intra_pred_topleft_cb;
-
- for (component = 0; component < 2; component++)
- {
- H = V = 0;
- comp_ref_x0 = comp_ref_x + 4;
- comp_ref_x1 = comp_ref_x + 2;
- comp_ref_y0 = comp_ref_y + (pitch << 2);
- comp_ref_y1 = comp_ref_y + (pitch << 1);
- for (i = 1; i < 4; i++)
- {
- H += i * (*comp_ref_x0++ - *comp_ref_x1--);
- V += i * (*comp_ref_y0 - *comp_ref_y1);
- comp_ref_y0 += pitch;
- comp_ref_y1 -= pitch;
- }
- H += i * (*comp_ref_x0++ - topleft);
- V += i * (*comp_ref_y0 - *comp_ref_y1);
-
- a_16_C[component] = ((*(comp_ref_x + 7) + *(comp_ref_y + 7 * pitch)) << 4) + 16;
- b_C[component] = (17 * H + 16) >> 5;
- c_C[component] = (17 * V + 16) >> 5;
-
- comp_ref_x = video->pintra_pred_top_cr;
- comp_ref_y = video->pintra_pred_left_cr;
- topleft = video->intra_pred_topleft_cr;
- }
-
- pred = predCb;
- for (component = 0; component < 2; component++)
- {
- a_16 = a_16_C[component];
- b = b_C[component];
- c = c_C[component];
- tmp = 0;
- for (i = 4; i < 6; i++)
- {
- for (j = 0; j < 4; j++)
- {
- factor_c = a_16 + c * (tmp++ - 3);
-
- factor_c -= 3 * b;
-
- value = factor_c >> 5;
- factor_c += b;
- CLIP_RESULT(value)
- byte1 = value;
- value = factor_c >> 5;
- factor_c += b;
- CLIP_RESULT(value)
- byte2 = value;
- value = factor_c >> 5;
- factor_c += b;
- CLIP_RESULT(value)
- byte3 = value;
- value = factor_c >> 5;
- factor_c += b;
- CLIP_RESULT(value)
- temp = byte1 | (byte2 << 8);
- temp |= (byte3 << 16);
- temp |= (value << 24);
- *((uint32*)pred) = temp;
-
- value = factor_c >> 5;
- factor_c += b;
- CLIP_RESULT(value)
- byte1 = value;
- value = factor_c >> 5;
- factor_c += b;
- CLIP_RESULT(value)
- byte2 = value;
- value = factor_c >> 5;
- factor_c += b;
- CLIP_RESULT(value)
- byte3 = value;
- value = factor_c >> 5;
- factor_c += b;
- CLIP_RESULT(value)
- temp = byte1 | (byte2 << 8);
- temp |= (byte3 << 16);
- temp |= (value << 24);
- *((uint32*)(pred + 4)) = temp;
- pred += pred_pitch;
- }
- }
- pred = predCr; /* point to cr */
- }
-}
-
diff --git a/media/libstagefright/codecs/avc/dec/src/residual.cpp b/media/libstagefright/codecs/avc/dec/src/residual.cpp
deleted file mode 100644
index c68550d..0000000
--- a/media/libstagefright/codecs/avc/dec/src/residual.cpp
+++ /dev/null
@@ -1,523 +0,0 @@
-/* ------------------------------------------------------------------
- * 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 <string.h>
-
-#include "avcdec_lib.h"
-#include "avcdec_bitstream.h"
-
-AVCDec_Status DecodeIntraPCM(AVCCommonObj *video, AVCDecBitstream *stream)
-{
- AVCDec_Status status;
- int j;
- int mb_x, mb_y, offset1;
- uint8 *pDst;
- uint32 byte0, byte1;
- int pitch;
-
- mb_x = video->mb_x;
- mb_y = video->mb_y;
-
-#ifdef USE_PRED_BLOCK
- pDst = video->pred_block + 84;
- pitch = 20;
-#else
- offset1 = (mb_x << 4) + (mb_y << 4) * video->PicWidthInSamplesL;
- pDst = video->currPic->Sl + offset1;
- pitch = video->currPic->pitch;
-#endif
-
- /* at this point bitstream is byte-aligned */
- j = 16;
- while (j > 0)
- {
- status = BitstreamReadBits(stream, 8, (uint*) & byte0);
- status = BitstreamReadBits(stream, 8, (uint*) & byte1);
- byte0 |= (byte1 << 8);
- status = BitstreamReadBits(stream, 8, (uint*) & byte1);
- byte0 |= (byte1 << 16);
- status = BitstreamReadBits(stream, 8, (uint*) & byte1);
- byte0 |= (byte1 << 24);
- *((uint32*)pDst) = byte0;
-
- status = BitstreamReadBits(stream, 8, (uint*) & byte0);
- status = BitstreamReadBits(stream, 8, (uint*) & byte1);
- byte0 |= (byte1 << 8);
- status = BitstreamReadBits(stream, 8, (uint*) & byte1);
- byte0 |= (byte1 << 16);
- status = BitstreamReadBits(stream, 8, (uint*) & byte1);
- byte0 |= (byte1 << 24);
- *((uint32*)(pDst + 4)) = byte0;
-
- status = BitstreamReadBits(stream, 8, (uint*) & byte0);
- status = BitstreamReadBits(stream, 8, (uint*) & byte1);
- byte0 |= (byte1 << 8);
- status = BitstreamReadBits(stream, 8, (uint*) & byte1);
- byte0 |= (byte1 << 16);
- status = BitstreamReadBits(stream, 8, (uint*) & byte1);
- byte0 |= (byte1 << 24);
- *((uint32*)(pDst + 8)) = byte0;
-
- status = BitstreamReadBits(stream, 8, (uint*) & byte0);
- status = BitstreamReadBits(stream, 8, (uint*) & byte1);
- byte0 |= (byte1 << 8);
- status = BitstreamReadBits(stream, 8, (uint*) & byte1);
- byte0 |= (byte1 << 16);
- status = BitstreamReadBits(stream, 8, (uint*) & byte1);
- byte0 |= (byte1 << 24);
- *((uint32*)(pDst + 12)) = byte0;
- j--;
- pDst += pitch;
-
- if (status != AVCDEC_SUCCESS) /* check only once per line */
- return status;
- }
-
-#ifdef USE_PRED_BLOCK
- pDst = video->pred_block + 452;
- pitch = 12;
-#else
- offset1 = (offset1 >> 2) + (mb_x << 2);
- pDst = video->currPic->Scb + offset1;
- pitch >>= 1;
-#endif
-
- j = 8;
- while (j > 0)
- {
- status = BitstreamReadBits(stream, 8, (uint*) & byte0);
- status = BitstreamReadBits(stream, 8, (uint*) & byte1);
- byte0 |= (byte1 << 8);
- status = BitstreamReadBits(stream, 8, (uint*) & byte1);
- byte0 |= (byte1 << 16);
- status = BitstreamReadBits(stream, 8, (uint*) & byte1);
- byte0 |= (byte1 << 24);
- *((uint32*)pDst) = byte0;
-
- status = BitstreamReadBits(stream, 8, (uint*) & byte0);
- status = BitstreamReadBits(stream, 8, (uint*) & byte1);
- byte0 |= (byte1 << 8);
- status = BitstreamReadBits(stream, 8, (uint*) & byte1);
- byte0 |= (byte1 << 16);
- status = BitstreamReadBits(stream, 8, (uint*) & byte1);
- byte0 |= (byte1 << 24);
- *((uint32*)(pDst + 4)) = byte0;
-
- j--;
- pDst += pitch;
-
- if (status != AVCDEC_SUCCESS) /* check only once per line */
- return status;
- }
-
-#ifdef USE_PRED_BLOCK
- pDst = video->pred_block + 596;
- pitch = 12;
-#else
- pDst = video->currPic->Scr + offset1;
-#endif
- j = 8;
- while (j > 0)
- {
- status = BitstreamReadBits(stream, 8, (uint*) & byte0);
- status = BitstreamReadBits(stream, 8, (uint*) & byte1);
- byte0 |= (byte1 << 8);
- status = BitstreamReadBits(stream, 8, (uint*) & byte1);
- byte0 |= (byte1 << 16);
- status = BitstreamReadBits(stream, 8, (uint*) & byte1);
- byte0 |= (byte1 << 24);
- *((uint32*)pDst) = byte0;
-
- status = BitstreamReadBits(stream, 8, (uint*) & byte0);
- status = BitstreamReadBits(stream, 8, (uint*) & byte1);
- byte0 |= (byte1 << 8);
- status = BitstreamReadBits(stream, 8, (uint*) & byte1);
- byte0 |= (byte1 << 16);
- status = BitstreamReadBits(stream, 8, (uint*) & byte1);
- byte0 |= (byte1 << 24);
- *((uint32*)(pDst + 4)) = byte0;
-
- j--;
- pDst += pitch;
-
- if (status != AVCDEC_SUCCESS) /* check only once per line */
- return status;
- }
-
-#ifdef MB_BASED_DEBLOCK
- SaveNeighborForIntraPred(video, offset1);
-#endif
-
- return AVCDEC_SUCCESS;
-}
-
-
-
-/* see subclause 7.3.5.3 and readCBPandCoeffsFromNAL() in JM*/
-AVCDec_Status residual(AVCDecObject *decvid, AVCMacroblock *currMB)
-{
- AVCCommonObj *video = decvid->common;
- int16 *block;
- int level[16], run[16], numcoeff; /* output from residual_block_cavlc */
- int block_x, i, j, k, idx, iCbCr;
- int mbPartIdx, subMbPartIdx, mbPartIdx_X, mbPartIdx_Y;
- int nC, maxNumCoeff = 16;
- int coeffNum, start_scan = 0;
- uint8 *zz_scan;
- int Rq, Qq;
- uint32 cbp4x4 = 0;
-
- /* in 8.5.4, it only says if it's field macroblock. */
-
- zz_scan = (uint8*) ZZ_SCAN_BLOCK;
-
-
- /* see 8.5.8 for the initialization of these values */
- Qq = video->QPy_div_6;
- Rq = video->QPy_mod_6;
-
- memset(video->block, 0, sizeof(int16)*NUM_PIXELS_IN_MB);
-
- if (currMB->mbMode == AVC_I16)
- {
- nC = predict_nnz(video, 0, 0);
- decvid->residual_block(decvid, nC, 16, level, run, &numcoeff);
- /* then performs zigzag and transform */
- block = video->block;
- coeffNum = -1;
- for (i = numcoeff - 1; i >= 0; i--)
- {
- coeffNum += run[i] + 1;
- if (coeffNum > 15)
- {
- return AVCDEC_FAIL;
- }
- idx = zz_scan[coeffNum] << 2;
- /* idx = ((idx>>2)<<6) + ((idx&3)<<2); */
- block[idx] = level[i];
- }
-
- /* inverse transform on Intra16x16DCLevel */
- if (numcoeff)
- {
- Intra16DCTrans(block, Qq, Rq);
- cbp4x4 = 0xFFFF;
- }
- maxNumCoeff = 15;
- start_scan = 1;
- }
-
- memset(currMB->nz_coeff, 0, sizeof(uint8)*24);
-
- for (mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++)
- {
- mbPartIdx_X = (mbPartIdx & 1) << 1;
- mbPartIdx_Y = mbPartIdx & -2;
-
- if (currMB->CBP&(1 << mbPartIdx))
- {
- for (subMbPartIdx = 0; subMbPartIdx < 4; subMbPartIdx++)
- {
- i = mbPartIdx_X + (subMbPartIdx & 1); // check this
- j = mbPartIdx_Y + (subMbPartIdx >> 1);
- block = video->block + (j << 6) + (i << 2); //
- nC = predict_nnz(video, i, j);
- decvid->residual_block(decvid, nC, maxNumCoeff, level, run, &numcoeff);
-
- /* convert to raster scan and quantize*/
- /* Note: for P mb in SP slice and SI mb in SI slice,
- the quantization cannot be done here.
- block[idx] should be assigned with level[k].
- itrans will be done after the prediction.
- There will be transformation on the predicted value,
- then addition with block[idx], then this quantization
- and transform.*/
-
- coeffNum = -1 + start_scan;
- for (k = numcoeff - 1; k >= 0; k--)
- {
- coeffNum += run[k] + 1;
- if (coeffNum > 15)
- {
- return AVCDEC_FAIL;
- }
- idx = zz_scan[coeffNum];
- block[idx] = (level[k] * dequant_coefres[Rq][coeffNum]) << Qq ;
- }
-
- currMB->nz_coeff[(j<<2)+i] = numcoeff;
- if (numcoeff)
- {
- cbp4x4 |= (1 << ((j << 2) + i));
- }
- }
- }
- }
-
- Qq = video->QPc_div_6;
- Rq = video->QPc_mod_6;
-
- if (currMB->CBP & (3 << 4)) /* chroma DC residual present */
- {
- for (iCbCr = 0; iCbCr < 2; iCbCr++)
- {
- decvid->residual_block(decvid, -1, 4, level, run, &numcoeff);
- block = video->block + 256 + (iCbCr << 3);
- coeffNum = -1;
- for (i = numcoeff - 1; i >= 0; i--)
- {
- coeffNum += run[i] + 1;
- if (coeffNum > 3)
- {
- return AVCDEC_FAIL;
- }
- block[(coeffNum>>1)*64 + (coeffNum&1)*4] = level[i];
- }
- /* inverse transform on chroma DC */
- /* for P in SP and SI in SI, this function can't be done here,
- must do prediction transform/quant first. */
- if (numcoeff)
- {
- ChromaDCTrans(block, Qq, Rq);
- cbp4x4 |= (iCbCr ? 0xcc0000 : 0x330000);
- }
- }
- }
-
- if (currMB->CBP & (2 << 4))
- {
- for (block_x = 0; block_x < 4; block_x += 2) /* for iCbCr */
- {
- for (j = 4; j < 6; j++) /* for each block inside Cb or Cr */
- {
- for (i = block_x; i < block_x + 2; i++)
- {
-
- block = video->block + (j << 6) + (i << 2);
-
- nC = predict_nnz_chroma(video, i, j);
- decvid->residual_block(decvid, nC, 15, level, run, &numcoeff);
-
- /* convert to raster scan and quantize */
- /* for P MB in SP slice and SI MB in SI slice,
- the dequant and transform cannot be done here.
- It needs the prediction values. */
- coeffNum = 0;
- for (k = numcoeff - 1; k >= 0; k--)
- {
- coeffNum += run[k] + 1;
- if (coeffNum > 15)
- {
- return AVCDEC_FAIL;
- }
- idx = zz_scan[coeffNum];
- block[idx] = (level[k] * dequant_coefres[Rq][coeffNum]) << Qq;
- }
-
-
- /* then transform */
- // itrans(block); /* transform */
- currMB->nz_coeff[(j<<2)+i] = numcoeff; //
- if (numcoeff)
- {
- cbp4x4 |= (1 << ((j << 2) + i));
- }
- }
-
- }
- }
- }
-
- video->cbp4x4 = cbp4x4;
-
- return AVCDEC_SUCCESS;
-}
-
-/* see subclause 7.3.5.3.1 and 9.2 and readCoeff4x4_CAVLC() in JM */
-AVCDec_Status residual_block_cavlc(AVCDecObject *decvid, int nC, int maxNumCoeff,
- int *level, int *run, int *numcoeff)
-{
- int i, j;
- int TrailingOnes, TotalCoeff;
- AVCDecBitstream *stream = decvid->bitstream;
- int suffixLength;
- uint trailing_ones_sign_flag, level_prefix, level_suffix;
- int levelCode, levelSuffixSize, zerosLeft;
- int run_before;
-
-
- if (nC >= 0)
- {
- ce_TotalCoeffTrailingOnes(stream, &TrailingOnes, &TotalCoeff, nC);
- }
- else
- {
- ce_TotalCoeffTrailingOnesChromaDC(stream, &TrailingOnes, &TotalCoeff);
- }
-
- *numcoeff = TotalCoeff;
-
- /* This part is done quite differently in ReadCoef4x4_CAVLC() */
- if (TotalCoeff == 0)
- {
- return AVCDEC_SUCCESS;
- }
-
- if (TrailingOnes) /* keep reading the sign of those trailing ones */
- {
- /* instead of reading one bit at a time, read the whole thing at once */
- BitstreamReadBits(stream, TrailingOnes, &trailing_ones_sign_flag);
- trailing_ones_sign_flag <<= 1;
- for (i = 0; i < TrailingOnes; i++)
- {
- level[i] = 1 - ((trailing_ones_sign_flag >> (TrailingOnes - i - 1)) & 2);
- }
- }
-
- i = TrailingOnes;
- suffixLength = 1;
- if (TotalCoeff > TrailingOnes)
- {
- ce_LevelPrefix(stream, &level_prefix);
- if (TotalCoeff < 11 || TrailingOnes == 3)
- {
- if (level_prefix < 14)
- {
-// levelSuffixSize = 0;
- levelCode = level_prefix;
- }
- else if (level_prefix == 14)
- {
-// levelSuffixSize = 4;
- BitstreamReadBits(stream, 4, &level_suffix);
- levelCode = 14 + level_suffix;
- }
- else /* if (level_prefix == 15) */
- {
-// levelSuffixSize = 12;
- BitstreamReadBits(stream, 12, &level_suffix);
- levelCode = 30 + level_suffix;
- }
- }
- else
- {
- /* suffixLength = 1; */
- if (level_prefix < 15)
- {
- levelSuffixSize = suffixLength;
- }
- else
- {
- levelSuffixSize = 12;
- }
- BitstreamReadBits(stream, levelSuffixSize, &level_suffix);
-
- levelCode = (level_prefix << 1) + level_suffix;
- }
-
- if (TrailingOnes < 3)
- {
- levelCode += 2;
- }
-
- level[i] = (levelCode + 2) >> 1;
- if (level[i] > 3)
- {
- suffixLength = 2;
- }
-
- if (levelCode & 1)
- {
- level[i] = -level[i];
- }
- i++;
-
- }
-
- for (j = TotalCoeff - i; j > 0 ; j--)
- {
- ce_LevelPrefix(stream, &level_prefix);
- if (level_prefix < 15)
- {
- levelSuffixSize = suffixLength;
- }
- else
- {
- levelSuffixSize = 12;
- }
- BitstreamReadBits(stream, levelSuffixSize, &level_suffix);
-
- levelCode = (level_prefix << suffixLength) + level_suffix;
- level[i] = (levelCode >> 1) + 1;
- if (level[i] > (3 << (suffixLength - 1)) && suffixLength < 6)
- {
- suffixLength++;
- }
- if (levelCode & 1)
- {
- level[i] = -level[i];
- }
- i++;
- }
-
-
- if (TotalCoeff < maxNumCoeff)
- {
- if (nC >= 0)
- {
- ce_TotalZeros(stream, &zerosLeft, TotalCoeff);
- }
- else
- {
- ce_TotalZerosChromaDC(stream, &zerosLeft, TotalCoeff);
- }
- }
- else
- {
- zerosLeft = 0;
- }
-
- for (i = 0; i < TotalCoeff - 1; i++)
- {
- if (zerosLeft > 0)
- {
- ce_RunBefore(stream, &run_before, zerosLeft);
- run[i] = run_before;
- }
- else
- {
- run[i] = 0;
- zerosLeft = 0; // could be negative under error conditions
- }
-
- zerosLeft = zerosLeft - run[i];
- }
-
- if (zerosLeft < 0)
- {
- zerosLeft = 0;
-// return AVCDEC_FAIL;
- }
-
- run[TotalCoeff-1] = zerosLeft;
-
- /* leave the inverse zigzag scan part for the caller */
-
-
- return AVCDEC_SUCCESS;
-}
diff --git a/media/libstagefright/codecs/avc/dec/src/slice.cpp b/media/libstagefright/codecs/avc/dec/src/slice.cpp
deleted file mode 100644
index 7a2ef3d..0000000
--- a/media/libstagefright/codecs/avc/dec/src/slice.cpp
+++ /dev/null
@@ -1,772 +0,0 @@
-/* ------------------------------------------------------------------
- * 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.
- * -------------------------------------------------------------------
- */
-/* Note for optimization: syntax decoding or operations related to B_SLICE should be
-commented out by macro definition or function pointers. */
-
-#include <string.h>
-
-#include "avcdec_lib.h"
-#include "avcdec_bitstream.h"
-
-const static int mbPart2raster[3][4] = {{0, 0, 0, 0}, {1, 1, 0, 0}, {1, 0, 1, 0}};
-/* decode_frame_slice() */
-/* decode_one_slice() */
-AVCDec_Status DecodeSlice(AVCDecObject *decvid)
-{
- AVCDec_Status status;
- AVCCommonObj *video = decvid->common;
- AVCSliceHeader *sliceHdr = video->sliceHdr;
- AVCMacroblock *currMB ;
- AVCDecBitstream *stream = decvid->bitstream;
- uint slice_group_id;
- uint CurrMbAddr, moreDataFlag;
-
- /* set the first mb in slice */
- CurrMbAddr = sliceHdr->first_mb_in_slice;
- slice_group_id = video->MbToSliceGroupMap[CurrMbAddr];
-
- if ((CurrMbAddr && (CurrMbAddr != (uint)(video->mbNum + 1))) && video->currSeqParams->constrained_set1_flag == 1)
- {
- ConcealSlice(decvid, video->mbNum, CurrMbAddr);
- }
-
- moreDataFlag = 1;
- video->mb_skip_run = -1;
-
-
- /* while loop , see subclause 7.3.4 */
- do
- {
- if (CurrMbAddr >= video->PicSizeInMbs)
- {
- return AVCDEC_FAIL;
- }
-
- currMB = video->currMB = &(video->mblock[CurrMbAddr]);
- video->mbNum = CurrMbAddr;
- currMB->slice_id = video->slice_id; // slice
-
- /* we can remove this check if we don't support Mbaff. */
- /* we can wrap below into an initMB() function which will also
- do necessary reset of macroblock related parameters. */
-
- video->mb_x = CurrMbAddr % video->PicWidthInMbs;
- video->mb_y = CurrMbAddr / video->PicWidthInMbs;
-
- /* check the availability of neighboring macroblocks */
- InitNeighborAvailability(video, CurrMbAddr);
-
- /* read_macroblock and decode_one_macroblock() */
- status = DecodeMB(decvid);
- if (status != AVCDEC_SUCCESS)
- {
- return status;
- }
-#ifdef MB_BASED_DEBLOCK
- if (video->currPicParams->num_slice_groups_minus1 == 0)
- {
- MBInLoopDeblock(video); /* MB-based deblocking */
- }
- else /* this mode cannot be used if the number of slice group is not one. */
- {
- return AVCDEC_FAIL;
- }
-#endif
- video->numMBs--;
-
- moreDataFlag = more_rbsp_data(stream);
-
-
- /* go to next MB */
- while (++CurrMbAddr < video->PicSizeInMbs && video->MbToSliceGroupMap[CurrMbAddr] != (int)slice_group_id)
- {
- }
-
- }
- while ((moreDataFlag && video->numMBs > 0) || video->mb_skip_run > 0); /* even if no more data, but last few MBs are skipped */
-
- if (video->numMBs == 0)
- {
- video->newPic = TRUE;
- video->mbNum = 0; // _Conceal
- return AVCDEC_PICTURE_READY;
- }
-
- return AVCDEC_SUCCESS;
-}
-
-/* read MB mode and motion vectors */
-/* perform Intra/Inter prediction and residue */
-/* update video->mb_skip_run */
-AVCDec_Status DecodeMB(AVCDecObject *decvid)
-{
- AVCDec_Status status;
- AVCCommonObj *video = decvid->common;
- AVCDecBitstream *stream = decvid->bitstream;
- AVCMacroblock *currMB = video->currMB;
- uint mb_type;
- int slice_type = video->slice_type;
- int temp;
-
- currMB->QPy = video->QPy;
- currMB->QPc = video->QPc;
-
- if (slice_type == AVC_P_SLICE)
- {
- if (video->mb_skip_run < 0)
- {
- ue_v(stream, (uint *)&(video->mb_skip_run));
- }
-
- if (video->mb_skip_run == 0)
- {
- /* this will not handle the case where the slice ends with a mb_skip_run == 0 and no following MB data */
- ue_v(stream, &mb_type);
- if (mb_type > 30)
- {
- return AVCDEC_FAIL;
- }
- InterpretMBModeP(currMB, mb_type);
- video->mb_skip_run = -1;
- }
- else
- {
- /* see subclause 7.4.4 for more details on how
- mb_field_decoding_flag is derived in case of skipped MB */
-
- currMB->mb_intra = FALSE;
-
- currMB->mbMode = AVC_SKIP;
- currMB->MbPartWidth = currMB->MbPartHeight = 16;
- currMB->NumMbPart = 1;
- currMB->NumSubMbPart[0] = currMB->NumSubMbPart[1] =
- currMB->NumSubMbPart[2] = currMB->NumSubMbPart[3] = 1; //
- currMB->SubMbPartWidth[0] = currMB->SubMbPartWidth[1] =
- currMB->SubMbPartWidth[2] = currMB->SubMbPartWidth[3] = currMB->MbPartWidth;
- currMB->SubMbPartHeight[0] = currMB->SubMbPartHeight[1] =
- currMB->SubMbPartHeight[2] = currMB->SubMbPartHeight[3] = currMB->MbPartHeight;
-
- memset(currMB->nz_coeff, 0, sizeof(uint8)*NUM_BLKS_IN_MB);
-
- currMB->CBP = 0;
- video->cbp4x4 = 0;
- /* for skipped MB, always look at the first entry in RefPicList */
- currMB->RefIdx[0] = currMB->RefIdx[1] =
- currMB->RefIdx[2] = currMB->RefIdx[3] = video->RefPicList0[0]->RefIdx;
- InterMBPrediction(video);
- video->mb_skip_run--;
- return AVCDEC_SUCCESS;
- }
-
- }
- else
- {
- /* Then decode mode and MV */
- ue_v(stream, &mb_type);
- if (mb_type > 25)
- {
- return AVCDEC_FAIL;
- }
- InterpretMBModeI(currMB, mb_type);
- }
-
-
- if (currMB->mbMode != AVC_I_PCM)
- {
-
- if (currMB->mbMode == AVC_P8 || currMB->mbMode == AVC_P8ref0)
- {
- status = sub_mb_pred(video, currMB, stream);
- }
- else
- {
- status = mb_pred(video, currMB, stream) ;
- }
-
- if (status != AVCDEC_SUCCESS)
- {
- return status;
- }
-
- if (currMB->mbMode != AVC_I16)
- {
- /* decode coded_block_pattern */
- status = DecodeCBP(currMB, stream);
- if (status != AVCDEC_SUCCESS)
- {
- return status;
- }
- }
-
- if (currMB->CBP > 0 || currMB->mbMode == AVC_I16)
- {
- se_v(stream, &temp);
- if (temp)
- {
- temp += (video->QPy + 52);
- currMB->QPy = video->QPy = temp - 52 * (temp * 79 >> 12);
- if (currMB->QPy > 51 || currMB->QPy < 0)
- {
- video->QPy = AVC_CLIP3(0, 51, video->QPy);
-// return AVCDEC_FAIL;
- }
- video->QPy_div_6 = (video->QPy * 43) >> 8;
- video->QPy_mod_6 = video->QPy - 6 * video->QPy_div_6;
- currMB->QPc = video->QPc = mapQPi2QPc[AVC_CLIP3(0, 51, video->QPy + video->currPicParams->chroma_qp_index_offset)];
- video->QPc_div_6 = (video->QPc * 43) >> 8;
- video->QPc_mod_6 = video->QPc - 6 * video->QPc_div_6;
- }
- }
- /* decode residue and inverse transform */
- status = residual(decvid, currMB);
- if (status != AVCDEC_SUCCESS)
- {
- return status;
- }
- }
- else
- {
- if (stream->bitcnt & 7)
- {
- BitstreamByteAlign(stream);
- }
- /* decode pcm_byte[i] */
- DecodeIntraPCM(video, stream);
-
- currMB->QPy = 0; /* necessary for deblocking */ // _OPTIMIZE
- currMB->QPc = mapQPi2QPc[AVC_CLIP3(0, 51, video->currPicParams->chroma_qp_index_offset)];
-
- /* default values, don't know if really needed */
- currMB->CBP = 0x3F;
- video->cbp4x4 = 0xFFFF;
- currMB->mb_intra = TRUE;
- memset(currMB->nz_coeff, 16, sizeof(uint8)*NUM_BLKS_IN_MB);
- return AVCDEC_SUCCESS;
- }
-
-
- /* do Intra/Inter prediction, together with the residue compensation */
- /* This part should be common between the skip and no-skip */
- if (currMB->mbMode == AVC_I4 || currMB->mbMode == AVC_I16)
- {
- IntraMBPrediction(video);
- }
- else
- {
- InterMBPrediction(video);
- }
-
-
-
- return AVCDEC_SUCCESS;
-}
-
-/* see subclause 7.3.5.1 */
-AVCDec_Status mb_pred(AVCCommonObj *video, AVCMacroblock *currMB, AVCDecBitstream *stream)
-{
- int mbPartIdx;
- AVCSliceHeader *sliceHdr = video->sliceHdr;
- uint max_ref_idx;
- const int *temp_0;
- int16 *temp_1;
- uint code;
-
- if (currMB->mbMode == AVC_I4 || currMB->mbMode == AVC_I16)
- {
-
- video->intraAvailA = video->intraAvailB = video->intraAvailC = video->intraAvailD = 0;
-
- if (!video->currPicParams->constrained_intra_pred_flag)
- {
- video->intraAvailA = video->mbAvailA;
- video->intraAvailB = video->mbAvailB;
- video->intraAvailC = video->mbAvailC;
- video->intraAvailD = video->mbAvailD;
- }
- else
- {
- if (video->mbAvailA)
- {
- video->intraAvailA = video->mblock[video->mbAddrA].mb_intra;
- }
- if (video->mbAvailB)
- {
- video->intraAvailB = video->mblock[video->mbAddrB].mb_intra ;
- }
- if (video->mbAvailC)
- {
- video->intraAvailC = video->mblock[video->mbAddrC].mb_intra;
- }
- if (video->mbAvailD)
- {
- video->intraAvailD = video->mblock[video->mbAddrD].mb_intra;
- }
- }
-
-
- if (currMB->mbMode == AVC_I4)
- {
- /* perform prediction to get the actual intra 4x4 pred mode */
- DecodeIntra4x4Mode(video, currMB, stream);
- /* output will be in currMB->i4Mode[4][4] */
- }
-
- ue_v(stream, &code);
-
- if (code > 3)
- {
- return AVCDEC_FAIL; /* out of range */
- }
- currMB->intra_chroma_pred_mode = (AVCIntraChromaPredMode)code;
- }
- else
- {
-
- memset(currMB->ref_idx_L0, 0, sizeof(int16)*4);
-
- /* see subclause 7.4.5.1 for the range of ref_idx_lX */
-// max_ref_idx = sliceHdr->num_ref_idx_l0_active_minus1;
- max_ref_idx = video->refList0Size - 1;
-
- /* decode ref index for L0 */
- if (sliceHdr->num_ref_idx_l0_active_minus1 > 0)
- {
- for (mbPartIdx = 0; mbPartIdx < currMB->NumMbPart; mbPartIdx++)
- {
- te_v(stream, &code, max_ref_idx);
- if (code > (uint)max_ref_idx)
- {
- return AVCDEC_FAIL;
- }
- currMB->ref_idx_L0[mbPartIdx] = code;
- }
- }
-
- /* populate ref_idx_L0 */
- temp_0 = &mbPart2raster[currMB->mbMode-AVC_P16][0];
- temp_1 = &currMB->ref_idx_L0[3];
-
- *temp_1-- = currMB->ref_idx_L0[*temp_0++];
- *temp_1-- = currMB->ref_idx_L0[*temp_0++];
- *temp_1-- = currMB->ref_idx_L0[*temp_0++];
- *temp_1-- = currMB->ref_idx_L0[*temp_0++];
-
- /* Global reference index, these values are used in deblock */
- currMB->RefIdx[0] = video->RefPicList0[currMB->ref_idx_L0[0]]->RefIdx;
- currMB->RefIdx[1] = video->RefPicList0[currMB->ref_idx_L0[1]]->RefIdx;
- currMB->RefIdx[2] = video->RefPicList0[currMB->ref_idx_L0[2]]->RefIdx;
- currMB->RefIdx[3] = video->RefPicList0[currMB->ref_idx_L0[3]]->RefIdx;
-
- /* see subclause 7.4.5.1 for the range of ref_idx_lX */
- max_ref_idx = sliceHdr->num_ref_idx_l1_active_minus1;
- /* decode mvd_l0 */
- for (mbPartIdx = 0; mbPartIdx < currMB->NumMbPart; mbPartIdx++)
- {
- se_v(stream, &(video->mvd_l0[mbPartIdx][0][0]));
- se_v(stream, &(video->mvd_l0[mbPartIdx][0][1]));
- }
- }
-
- return AVCDEC_SUCCESS;
-}
-
-/* see subclause 7.3.5.2 */
-AVCDec_Status sub_mb_pred(AVCCommonObj *video, AVCMacroblock *currMB, AVCDecBitstream *stream)
-{
- int mbPartIdx, subMbPartIdx;
- AVCSliceHeader *sliceHdr = video->sliceHdr;
- uint max_ref_idx;
- uint sub_mb_type[4];
- uint code;
-
- memset(currMB->ref_idx_L0, 0, sizeof(int16)*4);
-
- for (mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++)
- {
- ue_v(stream, &(sub_mb_type[mbPartIdx]));
- if (sub_mb_type[mbPartIdx] > 3)
- {
- return AVCDEC_FAIL;
- }
-
- }
- /* we have to check the values to make sure they are valid */
- /* assign values to currMB->sub_mb_type[], currMB->MBPartPredMode[][x] */
-
- InterpretSubMBModeP(currMB, sub_mb_type);
-
-
- /* see subclause 7.4.5.1 for the range of ref_idx_lX */
-// max_ref_idx = sliceHdr->num_ref_idx_l0_active_minus1;
- max_ref_idx = video->refList0Size - 1;
-
- if (sliceHdr->num_ref_idx_l0_active_minus1 > 0 && currMB->mbMode != AVC_P8ref0)
- {
- for (mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++)
- {
- te_v(stream, (uint*)&code, max_ref_idx);
- if (code > max_ref_idx)
- {
- return AVCDEC_FAIL;
- }
- currMB->ref_idx_L0[mbPartIdx] = code;
- }
- }
- /* see subclause 7.4.5.1 for the range of ref_idx_lX */
-
- max_ref_idx = sliceHdr->num_ref_idx_l1_active_minus1;
- /* if(video->MbaffFrameFlag && currMB->mb_field_decoding_flag)
- max_ref_idx = 2*sliceHdr->num_ref_idx_l1_active_minus1 + 1;*/
- for (mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++)
- {
- for (subMbPartIdx = 0; subMbPartIdx < currMB->NumSubMbPart[mbPartIdx]; subMbPartIdx++)
- {
- se_v(stream, &(video->mvd_l0[mbPartIdx][subMbPartIdx][0]));
- se_v(stream, &(video->mvd_l0[mbPartIdx][subMbPartIdx][1]));
- }
- /* used in deblocking */
- currMB->RefIdx[mbPartIdx] = video->RefPicList0[currMB->ref_idx_L0[mbPartIdx]]->RefIdx;
- }
- return AVCDEC_SUCCESS;
-}
-
-void InterpretMBModeI(AVCMacroblock *mblock, uint mb_type)
-{
- mblock->NumMbPart = 1;
-
- mblock->mb_intra = TRUE;
-
- if (mb_type == 0) /* I_4x4 */
- {
- mblock->mbMode = AVC_I4;
- }
- else if (mb_type < 25) /* I_PCM */
- {
- mblock->mbMode = AVC_I16;
- mblock->i16Mode = (AVCIntra16x16PredMode)((mb_type - 1) & 0x3);
- if (mb_type > 12)
- {
- mblock->CBP = (((mb_type - 13) >> 2) << 4) + 0x0F;
- }
- else
- {
- mblock->CBP = ((mb_type - 1) >> 2) << 4;
- }
- }
- else
- {
- mblock->mbMode = AVC_I_PCM;
- }
-
- return ;
-}
-
-void InterpretMBModeP(AVCMacroblock *mblock, uint mb_type)
-{
- const static int map2PartWidth[5] = {16, 16, 8, 8, 8};
- const static int map2PartHeight[5] = {16, 8, 16, 8, 8};
- const static int map2NumPart[5] = {1, 2, 2, 4, 4};
- const static AVCMBMode map2mbMode[5] = {AVC_P16, AVC_P16x8, AVC_P8x16, AVC_P8, AVC_P8ref0};
-
- mblock->mb_intra = FALSE;
- if (mb_type < 5)
- {
- mblock->mbMode = map2mbMode[mb_type];
- mblock->MbPartWidth = map2PartWidth[mb_type];
- mblock->MbPartHeight = map2PartHeight[mb_type];
- mblock->NumMbPart = map2NumPart[mb_type];
- mblock->NumSubMbPart[0] = mblock->NumSubMbPart[1] =
- mblock->NumSubMbPart[2] = mblock->NumSubMbPart[3] = 1;
- mblock->SubMbPartWidth[0] = mblock->SubMbPartWidth[1] =
- mblock->SubMbPartWidth[2] = mblock->SubMbPartWidth[3] = mblock->MbPartWidth;
- mblock->SubMbPartHeight[0] = mblock->SubMbPartHeight[1] =
- mblock->SubMbPartHeight[2] = mblock->SubMbPartHeight[3] = mblock->MbPartHeight;
- }
- else
- {
- InterpretMBModeI(mblock, mb_type - 5);
- /* set MV and Ref_Idx codes of Intra blocks in P-slices */
- memset(mblock->mvL0, 0, sizeof(int32)*16);
- mblock->ref_idx_L0[0] = mblock->ref_idx_L0[1] = mblock->ref_idx_L0[2] = mblock->ref_idx_L0[3] = -1;
- }
- return ;
-}
-
-void InterpretMBModeB(AVCMacroblock *mblock, uint mb_type)
-{
- const static int map2PartWidth[23] = {8, 16, 16, 16, 16, 8, 16, 8, 16, 8,
- 16, 8, 16, 8, 16, 8, 16, 8, 16, 8, 16, 8, 8
- };
- const static int map2PartHeight[23] = {8, 16, 16, 16, 8, 16, 8, 16, 8,
- 16, 8, 16, 8, 16, 8, 16, 8, 16, 8, 16, 8, 16, 8
- };
- /* see enum AVCMBType declaration */
- const static AVCMBMode map2mbMode[23] = {AVC_BDirect16, AVC_P16, AVC_P16, AVC_P16,
- AVC_P16x8, AVC_P8x16, AVC_P16x8, AVC_P8x16, AVC_P16x8, AVC_P8x16,
- AVC_P16x8, AVC_P8x16, AVC_P16x8, AVC_P8x16, AVC_P16x8, AVC_P8x16,
- AVC_P16x8, AVC_P8x16, AVC_P16x8, AVC_P8x16, AVC_P16x8, AVC_P8x16, AVC_P8
- };
- const static int map2PredMode1[23] = {3, 0, 1, 2, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 2, 2, 2, 2, 2, 2, -1};
- const static int map2PredMode2[23] = { -1, -1, -1, -1, 0, 0, 1, 1, 1, 1, 0, 0, 2, 2, 2, 2, 0, 0, 1, 1, 2, 2, -1};
- const static int map2NumPart[23] = { -1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4};
-
- mblock->mb_intra = FALSE;
-
- if (mb_type < 23)
- {
- mblock->mbMode = map2mbMode[mb_type];
- mblock->NumMbPart = map2NumPart[mb_type];
- mblock->MBPartPredMode[0][0] = (AVCPredMode)map2PredMode1[mb_type];
- if (mblock->NumMbPart > 1)
- {
- mblock->MBPartPredMode[1][0] = (AVCPredMode)map2PredMode2[mb_type];
- }
- mblock->MbPartWidth = map2PartWidth[mb_type];
- mblock->MbPartHeight = map2PartHeight[mb_type];
- }
- else
- {
- InterpretMBModeI(mblock, mb_type - 23);
- }
-
- return ;
-}
-
-void InterpretMBModeSI(AVCMacroblock *mblock, uint mb_type)
-{
- mblock->mb_intra = TRUE;
-
- if (mb_type == 0)
- {
- mblock->mbMode = AVC_SI4;
- /* other values are N/A */
- }
- else
- {
- InterpretMBModeI(mblock, mb_type - 1);
- }
- return ;
-}
-
-/* input is mblock->sub_mb_type[] */
-void InterpretSubMBModeP(AVCMacroblock *mblock, uint *sub_mb_type)
-{
- int i, sub_type;
- /* see enum AVCMBType declaration */
-// const static AVCSubMBMode map2subMbMode[4] = {AVC_8x8,AVC_8x4,AVC_4x8,AVC_4x4};
- const static int map2subPartWidth[4] = {8, 8, 4, 4};
- const static int map2subPartHeight[4] = {8, 4, 8, 4};
- const static int map2numSubPart[4] = {1, 2, 2, 4};
-
- for (i = 0; i < 4 ; i++)
- {
- sub_type = (int) sub_mb_type[i];
- // mblock->subMbMode[i] = map2subMbMode[sub_type];
- mblock->NumSubMbPart[i] = map2numSubPart[sub_type];
- mblock->SubMbPartWidth[i] = map2subPartWidth[sub_type];
- mblock->SubMbPartHeight[i] = map2subPartHeight[sub_type];
- }
-
- return ;
-}
-
-void InterpretSubMBModeB(AVCMacroblock *mblock, uint *sub_mb_type)
-{
- int i, j, sub_type;
- /* see enum AVCMBType declaration */
- const static AVCSubMBMode map2subMbMode[13] = {AVC_BDirect8, AVC_8x8, AVC_8x8,
- AVC_8x8, AVC_8x4, AVC_4x8, AVC_8x4, AVC_4x8, AVC_8x4, AVC_4x8, AVC_4x4, AVC_4x4, AVC_4x4
- };
- const static int map2subPartWidth[13] = {4, 8, 8, 8, 8, 4, 8, 4, 8, 4, 4, 4, 4};
- const static int map2subPartHeight[13] = {4, 8, 8, 8, 4, 8, 4, 8, 4, 8, 4, 4, 4};
- const static int map2numSubPart[13] = {1, 1, 1, 2, 2, 2, 2, 2, 2, 4, 4, 4};
- const static int map2predMode[13] = {3, 0, 1, 2, 0, 0, 1, 1, 2, 2, 0, 1, 2};
-
- for (i = 0; i < 4 ; i++)
- {
- sub_type = (int) sub_mb_type[i];
- mblock->subMbMode[i] = map2subMbMode[sub_type];
- mblock->NumSubMbPart[i] = map2numSubPart[sub_type];
- mblock->SubMbPartWidth[i] = map2subPartWidth[sub_type];
- mblock->SubMbPartHeight[i] = map2subPartHeight[sub_type];
- for (j = 0; j < 4; j++)
- {
- mblock->MBPartPredMode[i][j] = (AVCPredMode)map2predMode[sub_type];
- }
- }
-
- return ;
-}
-
-/* see subclause 8.3.1 */
-AVCDec_Status DecodeIntra4x4Mode(AVCCommonObj *video, AVCMacroblock *currMB, AVCDecBitstream *stream)
-{
- int intra4x4PredModeA = 0, intra4x4PredModeB = 0, predIntra4x4PredMode = 0;
- int component, SubBlock_indx, block_x, block_y;
- int dcOnlyPredictionFlag;
- uint prev_intra4x4_pred_mode_flag[16];
- int rem_intra4x4_pred_mode[16];
- int bindx = 0;
-
- for (component = 0; component < 4; component++) /* partition index */
- {
- block_x = ((component & 1) << 1);
- block_y = ((component >> 1) << 1);
-
- for (SubBlock_indx = 0; SubBlock_indx < 4; SubBlock_indx++) /* sub-partition index */
- {
- BitstreamRead1Bit(stream, &(prev_intra4x4_pred_mode_flag[bindx]));
-
- if (!prev_intra4x4_pred_mode_flag[bindx])
- {
- BitstreamReadBits(stream, 3, (uint*)&(rem_intra4x4_pred_mode[bindx]));
- }
-
- dcOnlyPredictionFlag = 0;
- if (block_x > 0)
- {
- intra4x4PredModeA = currMB->i4Mode[(block_y << 2) + block_x - 1 ];
- }
- else
- {
- if (video->intraAvailA)
- {
- if (video->mblock[video->mbAddrA].mbMode == AVC_I4)
- {
- intra4x4PredModeA = video->mblock[video->mbAddrA].i4Mode[(block_y << 2) + 3];
- }
- else
- {
- intra4x4PredModeA = AVC_I4_DC;
- }
- }
- else
- {
- dcOnlyPredictionFlag = 1;
- }
- }
-
- if (block_y > 0)
- {
- intra4x4PredModeB = currMB->i4Mode[((block_y-1) << 2) + block_x];
- }
- else
- {
- if (video->intraAvailB)
- {
- if (video->mblock[video->mbAddrB].mbMode == AVC_I4)
- {
- intra4x4PredModeB = video->mblock[video->mbAddrB].i4Mode[(3 << 2) + block_x];
- }
- else
- {
- intra4x4PredModeB = AVC_I4_DC;
- }
- }
- else
- {
- dcOnlyPredictionFlag = 1;
- }
- }
-
- if (dcOnlyPredictionFlag)
- {
- intra4x4PredModeA = intra4x4PredModeB = AVC_I4_DC;
- }
-
- predIntra4x4PredMode = AVC_MIN(intra4x4PredModeA, intra4x4PredModeB);
- if (prev_intra4x4_pred_mode_flag[bindx])
- {
- currMB->i4Mode[(block_y<<2)+block_x] = (AVCIntra4x4PredMode)predIntra4x4PredMode;
- }
- else
- {
- if (rem_intra4x4_pred_mode[bindx] < predIntra4x4PredMode)
- {
- currMB->i4Mode[(block_y<<2)+block_x] = (AVCIntra4x4PredMode)rem_intra4x4_pred_mode[bindx];
- }
- else
- {
- currMB->i4Mode[(block_y<<2)+block_x] = (AVCIntra4x4PredMode)(rem_intra4x4_pred_mode[bindx] + 1);
- }
- }
- bindx++;
- block_y += (SubBlock_indx & 1) ;
- block_x += (1 - 2 * (SubBlock_indx & 1)) ;
- }
- }
- return AVCDEC_SUCCESS;
-}
-AVCDec_Status ConcealSlice(AVCDecObject *decvid, int mbnum_start, int mbnum_end)
-{
- AVCCommonObj *video = decvid->common;
- AVCMacroblock *currMB ;
-
- int CurrMbAddr;
-
- if (video->RefPicList0[0] == NULL)
- {
- return AVCDEC_FAIL;
- }
-
- for (CurrMbAddr = mbnum_start; CurrMbAddr < mbnum_end; CurrMbAddr++)
- {
- currMB = video->currMB = &(video->mblock[CurrMbAddr]);
- video->mbNum = CurrMbAddr;
- currMB->slice_id = video->slice_id++; // slice
-
- /* we can remove this check if we don't support Mbaff. */
- /* we can wrap below into an initMB() function which will also
- do necessary reset of macroblock related parameters. */
-
- video->mb_x = CurrMbAddr % video->PicWidthInMbs;
- video->mb_y = CurrMbAddr / video->PicWidthInMbs;
-
- /* check the availability of neighboring macroblocks */
- InitNeighborAvailability(video, CurrMbAddr);
-
- currMB->mb_intra = FALSE;
-
- currMB->mbMode = AVC_SKIP;
- currMB->MbPartWidth = currMB->MbPartHeight = 16;
-
- currMB->NumMbPart = 1;
- currMB->NumSubMbPart[0] = currMB->NumSubMbPart[1] =
- currMB->NumSubMbPart[2] = currMB->NumSubMbPart[3] = 1;
- currMB->SubMbPartWidth[0] = currMB->SubMbPartWidth[1] =
- currMB->SubMbPartWidth[2] = currMB->SubMbPartWidth[3] = currMB->MbPartWidth;
- currMB->SubMbPartHeight[0] = currMB->SubMbPartHeight[1] =
- currMB->SubMbPartHeight[2] = currMB->SubMbPartHeight[3] = currMB->MbPartHeight;
- currMB->QPy = 26;
- currMB->QPc = 26;
- memset(currMB->nz_coeff, 0, sizeof(uint8)*NUM_BLKS_IN_MB);
-
- currMB->CBP = 0;
- video->cbp4x4 = 0;
- /* for skipped MB, always look at the first entry in RefPicList */
- currMB->RefIdx[0] = currMB->RefIdx[1] =
- currMB->RefIdx[2] = currMB->RefIdx[3] = video->RefPicList0[0]->RefIdx;
- InterMBPrediction(video);
-
- video->numMBs--;
-
- }
-
- return AVCDEC_SUCCESS;
-}
-
diff --git a/media/libstagefright/codecs/avc/dec/src/vlc.cpp b/media/libstagefright/codecs/avc/dec/src/vlc.cpp
deleted file mode 100644
index f531249..0000000
--- a/media/libstagefright/codecs/avc/dec/src/vlc.cpp
+++ /dev/null
@@ -1,815 +0,0 @@
-/* ------------------------------------------------------------------
- * 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 "avcdec_lib.h"
-#include "avcdec_bitstream.h"
-
-//#define PV_ARM_V5
-#ifdef PV_ARM_V5
-#define PV_CLZ(A,B) __asm{CLZ (A),(B)} \
- A -= 16;
-#else
-#define PV_CLZ(A,B) while (((B) & 0x8000) == 0) {(B) <<=1; A++;}
-#endif
-
-
-#define PV_NO_CLZ
-
-#ifndef PV_NO_CLZ
-typedef struct tagVLCNumCoeffTrail
-{
- int trailing;
- int total_coeff;
- int length;
-} VLCNumCoeffTrail;
-
-typedef struct tagShiftOffset
-{
- int shift;
- int offset;
-} ShiftOffset;
-
-const VLCNumCoeffTrail NumCoeffTrailOnes[3][67] =
-{
- {{0, 0, 1}, {1, 1, 2}, {2, 2, 3}, {1, 2, 6}, {0, 1, 6}, {3, 3, 5}, {3, 3, 5}, {3, 5, 7},
- {2, 3, 7}, {3, 4, 6}, {3, 4, 6}, {3, 6, 8}, {2, 4, 8}, {1, 3, 8}, {0, 2, 8}, {3, 7, 9},
- {2, 5, 9}, {1, 4, 9}, {0, 3, 9}, {3, 8, 10}, {2, 6, 10}, {1, 5, 10}, {0, 4, 10}, {3, 9, 11},
- {2, 7, 11}, {1, 6, 11}, {0, 5, 11}, {0, 8, 13}, {2, 9, 13}, {1, 8, 13}, {0, 7, 13}, {3, 10, 13},
- {2, 8, 13}, {1, 7, 13}, {0, 6, 13}, {3, 12, 14}, {2, 11, 14}, {1, 10, 14}, {0, 10, 14}, {3, 11, 14},
- {2, 10, 14}, {1, 9, 14}, {0, 9, 14}, {3, 14, 15}, {2, 13, 15}, {1, 12, 15}, {0, 12, 15}, {3, 13, 15},
- {2, 12, 15}, {1, 11, 15}, {0, 11, 15}, {3, 16, 16}, {2, 15, 16}, {1, 15, 16}, {0, 14, 16}, {3, 15, 16},
- {2, 14, 16}, {1, 14, 16}, {0, 13, 16}, {0, 16, 16}, {2, 16, 16}, {1, 16, 16}, {0, 15, 16}, {1, 13, 15},
- { -1, -1, -1}, { -1, -1, -1}, { -1, -1, -1}},
-
- {{1, 1, 2}, {0, 0, 2}, {3, 4, 4}, {3, 3, 4}, {2, 2, 3}, {2, 2, 3}, {3, 6, 6}, {2, 3, 6},
- {1, 3, 6}, {0, 1, 6}, {3, 5, 5}, {3, 5, 5}, {1, 2, 5}, {1, 2, 5}, {3, 7, 6}, {2, 4, 6},
- {1, 4, 6}, {0, 2, 6}, {3, 8, 7}, {2, 5, 7}, {1, 5, 7}, {0, 3, 7}, {0, 5, 8}, {2, 6, 8},
- {1, 6, 8}, {0, 4, 8}, {3, 9, 9}, {2, 7, 9}, {1, 7, 9}, {0, 6, 9}, {3, 11, 11}, {2, 9, 11},
- {1, 9, 11}, {0, 8, 11}, {3, 10, 11}, {2, 8, 11}, {1, 8, 11}, {0, 7, 11}, {0, 11, 12}, {2, 11, 12},
- {1, 11, 12}, {0, 10, 12}, {3, 12, 12}, {2, 10, 12}, {1, 10, 12}, {0, 9, 12}, {3, 14, 13}, {2, 13, 13},
- {1, 13, 13}, {0, 13, 13}, {3, 13, 13}, {2, 12, 13}, {1, 12, 13}, {0, 12, 13}, {1, 15, 14}, {0, 15, 14},
- {2, 15, 14}, {1, 14, 14}, {2, 14, 13}, {2, 14, 13}, {0, 14, 13}, {0, 14, 13}, {3, 16, 14}, {2, 16, 14},
- {1, 16, 14}, {0, 16, 14}, {3, 15, 13}},
-
- {{3, 7, 4}, {3, 6, 4}, {3, 5, 4}, {3, 4, 4}, {3, 3, 4}, {2, 2, 4}, {1, 1, 4}, {0, 0, 4},
- {1, 5, 5}, {2, 5, 5}, {1, 4, 5}, {2, 4, 5}, {1, 3, 5}, {3, 8, 5}, {2, 3, 5}, {1, 2, 5},
- {0, 3, 6}, {2, 7, 6}, {1, 7, 6}, {0, 2, 6}, {3, 9, 6}, {2, 6, 6}, {1, 6, 6}, {0, 1, 6},
- {0, 7, 7}, {0, 6, 7}, {2, 9, 7}, {0, 5, 7}, {3, 10, 7}, {2, 8, 7}, {1, 8, 7}, {0, 4, 7},
- {3, 12, 8}, {2, 11, 8}, {1, 10, 8}, {0, 9, 8}, {3, 11, 8}, {2, 10, 8}, {1, 9, 8}, {0, 8, 8},
- {0, 12, 9}, {2, 13, 9}, {1, 12, 9}, {0, 11, 9}, {3, 13, 9}, {2, 12, 9}, {1, 11, 9}, {0, 10, 9},
- {1, 15, 10}, {0, 14, 10}, {3, 14, 10}, {2, 14, 10}, {1, 14, 10}, {0, 13, 10}, {1, 13, 9}, {1, 13, 9},
- {1, 16, 10}, {0, 15, 10}, {3, 15, 10}, {2, 15, 10}, {3, 16, 10}, {2, 16, 10}, {0, 16, 10}, { -1, -1, -1},
- { -1, -1, -1}, { -1, -1, -1}, { -1, -1, -1}}
-};
-
-
-const ShiftOffset NumCoeffTrailOnes_indx[3][15] =
-{
- {{15, -1}, {14, 0}, {13, 1}, {10, -1}, {9, 3}, {8, 7}, {7, 11}, {6, 15},
- {5, 19}, {3, 19}, {2, 27}, {1, 35}, {0, 43}, {0, 55}, {1, 62}},
-
- {{14, -2}, {12, -2}, {10, -2}, {10, 10}, {9, 14}, {8, 18}, {7, 22}, {5, 22},
- {4, 30}, {3, 38}, {2, 46}, {2, 58}, {3, 65}, {16, 0}, {16, 0}},
-
- {{12, -8}, {11, 0}, {10, 8}, {9, 16}, {8, 24}, {7, 32}, {6, 40}, {6, 52},
- {6, 58}, {6, 61}, {16, 0}, {16, 0}, {16, 0}, {16, 0}, {16, 0}}
-};
-
-const static int nC_table[8] = {0, 0, 1, 1, 2, 2, 2, 2};
-
-#endif
-/**
-See algorithm in subclause 9.1, Table 9-1, Table 9-2. */
-AVCDec_Status ue_v(AVCDecBitstream *bitstream, uint *codeNum)
-{
- uint temp, tmp_cnt;
- int leading_zeros = 0;
- BitstreamShowBits(bitstream, 16, &temp);
- tmp_cnt = temp | 0x1;
-
- PV_CLZ(leading_zeros, tmp_cnt)
-
- if (leading_zeros < 8)
- {
- *codeNum = (temp >> (15 - (leading_zeros << 1))) - 1;
- BitstreamFlushBits(bitstream, (leading_zeros << 1) + 1);
- }
- else
- {
- BitstreamReadBits(bitstream, (leading_zeros << 1) + 1, &temp);
- *codeNum = temp - 1;
- }
-
- return AVCDEC_SUCCESS;
-}
-
-/**
-See subclause 9.1.1, Table 9-3 */
-AVCDec_Status se_v(AVCDecBitstream *bitstream, int *value)
-{
- uint temp, tmp_cnt;
- int leading_zeros = 0;
- BitstreamShowBits(bitstream, 16, &temp);
- tmp_cnt = temp | 0x1;
-
- PV_CLZ(leading_zeros, tmp_cnt)
-
- if (leading_zeros < 8)
- {
- temp >>= (15 - (leading_zeros << 1));
- BitstreamFlushBits(bitstream, (leading_zeros << 1) + 1);
- }
- else
- {
- BitstreamReadBits(bitstream, (leading_zeros << 1) + 1, &temp);
- }
-
- *value = temp >> 1;
-
- if (temp & 0x01) // lsb is signed bit
- *value = -(*value);
-
-// leading_zeros = temp >> 1;
-// *value = leading_zeros - (leading_zeros*2*(temp&1));
-
- return AVCDEC_SUCCESS;
-}
-
-AVCDec_Status se_v32bit(AVCDecBitstream *bitstream, int32 *value)
-{
- int leadingZeros;
- uint32 infobits;
- uint32 codeNum;
-
- if (AVCDEC_SUCCESS != GetEGBitstring32bit(bitstream, &leadingZeros, &infobits))
- return AVCDEC_FAIL;
-
- codeNum = (1 << leadingZeros) - 1 + infobits;
-
- *value = (codeNum + 1) / 2;
-
- if ((codeNum & 0x01) == 0) // lsb is signed bit
- *value = -(*value);
-
- return AVCDEC_SUCCESS;
-}
-
-
-AVCDec_Status te_v(AVCDecBitstream *bitstream, uint *value, uint range)
-{
- if (range > 1)
- {
- ue_v(bitstream, value);
- }
- else
- {
- BitstreamRead1Bit(bitstream, value);
- *value = 1 - (*value);
- }
- return AVCDEC_SUCCESS;
-}
-
-
-
-/* This function is only used for syntax with range from -2^31 to 2^31-1 */
-/* only a few of them in the SPS and PPS */
-AVCDec_Status GetEGBitstring32bit(AVCDecBitstream *bitstream, int *leadingZeros, uint32 *infobits)
-{
- int bit_value;
- uint info_temp;
-
- *leadingZeros = 0;
-
- BitstreamRead1Bit(bitstream, (uint*)&bit_value);
-
- while (!bit_value)
- {
- (*leadingZeros)++;
- BitstreamRead1Bit(bitstream, (uint*)&bit_value);
- }
-
- if (*leadingZeros > 0)
- {
- if (sizeof(uint) == 4) /* 32 bit machine */
- {
- BitstreamReadBits(bitstream, *leadingZeros, (uint*)&info_temp);
- *infobits = (uint32)info_temp;
- }
- else if (sizeof(uint) == 2) /* 16 bit machine */
- {
- *infobits = 0;
- if (*leadingZeros > 16)
- {
- BitstreamReadBits(bitstream, 16, (uint*)&info_temp);
- (*leadingZeros) -= 16;
- *infobits = ((uint32)info_temp) << (*leadingZeros);
- }
-
- BitstreamReadBits(bitstream, *leadingZeros, (uint*)&info_temp);
- *infobits |= (uint32)info_temp ;
- }
- }
- else
- *infobits = 0;
-
- return AVCDEC_SUCCESS;
-}
-
-/* see Table 9-4 assignment of codeNum to values of coded_block_pattern. */
-const static uint8 MapCBP[48][2] =
-{
- {47, 0}, {31, 16}, {15, 1}, { 0, 2}, {23, 4}, {27, 8}, {29, 32}, {30, 3}, { 7, 5}, {11, 10}, {13, 12}, {14, 15},
- {39, 47}, {43, 7}, {45, 11}, {46, 13}, {16, 14}, { 3, 6}, { 5, 9}, {10, 31}, {12, 35}, {19, 37}, {21, 42}, {26, 44},
- {28, 33}, {35, 34}, {37, 36}, {42, 40}, {44, 39}, { 1, 43}, { 2, 45}, { 4, 46}, { 8, 17}, {17, 18}, {18, 20}, {20, 24},
- {24, 19}, { 6, 21}, { 9, 26}, {22, 28}, {25, 23}, {32, 27}, {33, 29}, {34, 30}, {36, 22}, {40, 25}, {38, 38}, {41, 41},
-};
-
-AVCDec_Status DecodeCBP(AVCMacroblock *currMB, AVCDecBitstream *stream)
-{
- uint codeNum;
- uint coded_block_pattern;
-
- ue_v(stream, &codeNum);
-
- if (codeNum > 47)
- {
- return AVCDEC_FAIL;
- }
-
- /* can get rid of the if _OPTIMIZE */
- if (currMB->mbMode == AVC_I4)
- {
- coded_block_pattern = MapCBP[codeNum][0];
- }
- else
- {
- coded_block_pattern = MapCBP[codeNum][1];
- }
-
-// currMB->cbpL = coded_block_pattern&0xF; /* modulo 16 */
-// currMB->cbpC = coded_block_pattern>>4; /* divide 16 */
- currMB->CBP = coded_block_pattern;
-
- return AVCDEC_SUCCESS;
-}
-
-
-/* TO BE OPTIMIZED !!!!! */
-AVCDec_Status ce_TotalCoeffTrailingOnes(AVCDecBitstream *stream, int *TrailingOnes, int *TotalCoeff, int nC)
-{
-#ifdef PV_NO_CLZ
- const static uint8 TotCofNTrail1[75][3] = {{0, 0, 16}/*error */, {0, 0, 16}/*error */, {1, 13, 15}, {1, 13, 15}, {0, 16, 16}, {2, 16, 16}, {1, 16, 16}, {0, 15, 16},
- {3, 16, 16}, {2, 15, 16}, {1, 15, 16}, {0, 14, 16}, {3, 15, 16}, {2, 14, 16}, {1, 14, 16}, {0, 13, 16},
- {3, 14, 15}, {2, 13, 15}, {1, 12, 15}, {0, 12, 15}, {3, 13, 15}, {2, 12, 15}, {1, 11, 15}, {0, 11, 15},
- {3, 12, 14}, {2, 11, 14}, {1, 10, 14}, {0, 10, 14}, {3, 11, 14}, {2, 10, 14}, {1, 9, 14}, {0, 9, 14},
- {0, 8, 13}, {2, 9, 13}, {1, 8, 13}, {0, 7, 13}, {3, 10, 13}, {2, 8, 13}, {1, 7, 13}, {0, 6, 13},
- {3, 9, 11}, {2, 7, 11}, {1, 6, 11}, {0, 5, 11}, {3, 8, 10},
- {2, 6, 10}, {1, 5, 10}, {0, 4, 10}, {3, 7, 9}, {2, 5, 9}, {1, 4, 9}, {0, 3, 9}, {3, 6, 8},
- {2, 4, 8}, {1, 3, 8}, {0, 2, 8}, {3, 5, 7}, {2, 3, 7}, {3, 4, 6}, {3, 4, 6}, {1, 2, 6},
- {1, 2, 6}, {0, 1, 6}, {0, 1, 6}, {3, 3, 5}, {3, 3, 5}, {3, 3, 5}, {3, 3, 5}, {2, 2, 3},
- {1, 1, 2}, {1, 1, 2}, {0, 0, 1}, {0, 0, 1}, {0, 0, 1}, {0, 0, 1}
- };
-
- const static uint8 TotCofNTrail2[84][3] = {{0, 0, 14 /* error */}, {0, 0, 14/*error */}, {3, 15, 13}, {3, 15, 13}, {3, 16, 14}, {2, 16, 14}, {1, 16, 14}, {0, 16, 14},
- {1, 15, 14}, {0, 15, 14}, {2, 15, 14}, {1, 14, 14}, {2, 14, 13}, {2, 14, 13}, {0, 14, 13}, {0, 14, 13},
- {3, 14, 13}, {2, 13, 13}, {1, 13, 13}, {0, 13, 13}, {3, 13, 13}, {2, 12, 13}, {1, 12, 13}, {0, 12, 13},
- {0, 11, 12}, {2, 11, 12}, {1, 11, 12}, {0, 10, 12}, {3, 12, 12}, {2, 10, 12}, {1, 10, 12}, {0, 9, 12},
- {3, 11, 11}, {2, 9, 11}, {1, 9, 11}, {0, 8, 11}, {3, 10, 11}, {2, 8, 11}, {1, 8, 11}, {0, 7, 11},
- {3, 9, 9}, {2, 7, 9}, {1, 7, 9}, {0, 6, 9}, {0, 5, 8}, {0, 5, 8}, {2, 6, 8}, {2, 6, 8},
- {1, 6, 8}, {1, 6, 8}, {0, 4, 8}, {0, 4, 8}, {3, 8, 7}, {2, 5, 7}, {1, 5, 7}, {0, 3, 7},
- {3, 7, 6}, {3, 7, 6}, {2, 4, 6}, {2, 4, 6}, {1, 4, 6}, {1, 4, 6}, {0, 2, 6}, {0, 2, 6},
- {3, 6, 6}, {2, 3, 6}, {1, 3, 6}, {0, 1, 6}, {3, 5, 5}, {3, 5, 5}, {1, 2, 5}, {1, 2, 5},
- {3, 4, 4}, {3, 3, 4}, {2, 2, 3}, {2, 2, 3}, {1, 1, 2}, {1, 1, 2}, {1, 1, 2}, {1, 1, 2},
- {0, 0, 2}, {0, 0, 2}, {0, 0, 2}, {0, 0, 2}
- };
-
- const static uint8 TotCofNTrail3[64][3] = {{0, 0, 10/*error*/}, {0, 16, 10}, {3, 16, 10}, {2, 16, 10}, {1, 16, 10}, {0, 15, 10}, {3, 15, 10},
- {2, 15, 10}, {1, 15, 10}, {0, 14, 10}, {3, 14, 10}, {2, 14, 10}, {1, 14, 10}, {0, 13, 10}, {1, 13, 9},
- {1, 13, 9}, {0, 12, 9}, {2, 13, 9}, {1, 12, 9}, {0, 11, 9}, {3, 13, 9}, {2, 12, 9}, {1, 11, 9},
- {0, 10, 9}, {3, 12, 8}, {2, 11, 8}, {1, 10, 8}, {0, 9, 8}, {3, 11, 8}, {2, 10, 8}, {1, 9, 8},
- {0, 8, 8}, {0, 7, 7}, {0, 6, 7}, {2, 9, 7}, {0, 5, 7}, {3, 10, 7}, {2, 8, 7}, {1, 8, 7},
- {0, 4, 7}, {0, 3, 6}, {2, 7, 6}, {1, 7, 6}, {0, 2, 6}, {3, 9, 6}, {2, 6, 6}, {1, 6, 6},
- {0, 1, 6}, {1, 5, 5}, {2, 5, 5}, {1, 4, 5}, {2, 4, 5}, {1, 3, 5}, {3, 8, 5}, {2, 3, 5},
- {1, 2, 5}, {3, 7, 4}, {3, 6, 4}, {3, 5, 4}, {3, 4, 4}, {3, 3, 4}, {2, 2, 4}, {1, 1, 4},
- {0, 0, 4}
- };
-#endif
- uint code;
-
-#ifdef PV_NO_CLZ
- uint8 *pcode;
- if (nC < 2)
- {
- BitstreamShowBits(stream, 16, &code);
-
- if (code >= 8192)
- {
- pcode = (uint8*) & (TotCofNTrail1[(code>>13)+65+2][0]);
- }
- else if (code >= 2048)
- {
- pcode = (uint8*) & (TotCofNTrail1[(code>>9)+50+2][0]);
- }
- else if (code >= 1024)
- {
- pcode = (uint8*) & (TotCofNTrail1[(code>>8)+46+2][0]);
- }
- else if (code >= 512)
- {
- pcode = (uint8*) & (TotCofNTrail1[(code>>7)+42+2][0]);
- }
- else if (code >= 256)
- {
- pcode = (uint8*) & (TotCofNTrail1[(code>>6)+38+2][0]);
- }
- else if (code >= 128)
- {
- pcode = (uint8*) & (TotCofNTrail1[(code>>5)+34+2][0]);
- }
- else if (code >= 64)
- {
- pcode = (uint8*) & (TotCofNTrail1[(code>>3)+22+2][0]);
- }
- else if (code >= 32)
- {
- pcode = (uint8*) & (TotCofNTrail1[(code>>2)+14+2][0]);
- }
- else if (code >= 16)
- {
- pcode = (uint8*) & (TotCofNTrail1[(code>>1)+6+2][0]);
- }
- else
- {
- pcode = (uint8*) & (TotCofNTrail1[(code-2)+2][0]);
- }
-
- *TrailingOnes = pcode[0];
- *TotalCoeff = pcode[1];
-
- BitstreamFlushBits(stream, pcode[2]);
- }
- else if (nC < 4)
- {
- BitstreamShowBits(stream, 14, &code);
-
- if (code >= 4096)
- {
- pcode = (uint8*) & (TotCofNTrail2[(code>>10)+66+2][0]);
- }
- else if (code >= 2048)
- {
- pcode = (uint8*) & (TotCofNTrail2[(code>>8)+54+2][0]);
- }
- else if (code >= 512)
- {
- pcode = (uint8*) & (TotCofNTrail2[(code>>7)+46+2][0]);
- }
- else if (code >= 128)
- {
- pcode = (uint8*) & (TotCofNTrail2[(code>>5)+34+2][0]);
- }
- else if (code >= 64)
- {
- pcode = (uint8*) & (TotCofNTrail2[(code>>3)+22+2][0]);
- }
- else if (code >= 32)
- {
- pcode = (uint8*) & (TotCofNTrail2[(code>>2)+14+2][0]);
- }
- else if (code >= 16)
- {
- pcode = (uint8*) & (TotCofNTrail2[(code>>1)+6+2][0]);
- }
- else
- {
- pcode = (uint8*) & (TotCofNTrail2[code-2+2][0]);
- }
- *TrailingOnes = pcode[0];
- *TotalCoeff = pcode[1];
-
- BitstreamFlushBits(stream, pcode[2]);
- }
- else if (nC < 8)
- {
- BitstreamShowBits(stream, 10, &code);
-
- if (code >= 512)
- {
- pcode = (uint8*) & (TotCofNTrail3[(code>>6)+47+1][0]);
- }
- else if (code >= 256)
- {
- pcode = (uint8*) & (TotCofNTrail3[(code>>5)+39+1][0]);
- }
- else if (code >= 128)
- {
- pcode = (uint8*) & (TotCofNTrail3[(code>>4)+31+1][0]);
- }
- else if (code >= 64)
- {
- pcode = (uint8*) & (TotCofNTrail3[(code>>3)+23+1][0]);
- }
- else if (code >= 32)
- {
- pcode = (uint8*) & (TotCofNTrail3[(code>>2)+15+1][0]);
- }
- else if (code >= 16)
- {
- pcode = (uint8*) & (TotCofNTrail3[(code>>1)+7+1][0]);
- }
- else
- {
- pcode = (uint8*) & (TotCofNTrail3[code-1+1][0]);
- }
- *TrailingOnes = pcode[0];
- *TotalCoeff = pcode[1];
-
- BitstreamFlushBits(stream, pcode[2]);
- }
- else
- {
- /* read 6 bit FLC */
- BitstreamReadBits(stream, 6, &code);
-
-
- *TrailingOnes = code & 3;
- *TotalCoeff = (code >> 2) + 1;
-
- if (*TotalCoeff > 16)
- {
- *TotalCoeff = 16; // _ERROR
- }
-
- if (code == 3)
- {
- *TrailingOnes = 0;
- (*TotalCoeff)--;
- }
- }
-#else
- const VLCNumCoeffTrail *ptr;
- const ShiftOffset *ptr_indx;
- uint temp, leading_zeros = 0;
-
- if (nC < 8)
- {
-
- BitstreamShowBits(stream, 16, &code);
- temp = code | 1;
-
- PV_CLZ(leading_zeros, temp)
-
- temp = nC_table[nC];
- ptr_indx = &NumCoeffTrailOnes_indx[temp][leading_zeros];
- ptr = &NumCoeffTrailOnes[temp][(code >> ptr_indx->shift) + ptr_indx->offset];
- *TrailingOnes = ptr->trailing;
- *TotalCoeff = ptr->total_coeff;
- BitstreamFlushBits(stream, ptr->length);
- }
- else
- {
- /* read 6 bit FLC */
- BitstreamReadBits(stream, 6, &code);
-
-
- *TrailingOnes = code & 3;
- *TotalCoeff = (code >> 2) + 1;
-
- if (*TotalCoeff > 16)
- {
- *TotalCoeff = 16; // _ERROR
- }
-
- if (code == 3)
- {
- *TrailingOnes = 0;
- (*TotalCoeff)--;
- }
- }
-#endif
- return AVCDEC_SUCCESS;
-}
-
-/* TO BE OPTIMIZED !!!!! */
-AVCDec_Status ce_TotalCoeffTrailingOnesChromaDC(AVCDecBitstream *stream, int *TrailingOnes, int *TotalCoeff)
-{
- AVCDec_Status status;
-
- const static uint8 TotCofNTrail5[21][3] =
- {
- {3, 4, 7}, {3, 4, 7}, {2, 4, 8}, {1, 4, 8}, {2, 3, 7}, {2, 3, 7}, {1, 3, 7},
- {1, 3, 7}, {0, 4, 6}, {0, 3, 6}, {0, 2, 6}, {3, 3, 6}, {1, 2, 6}, {0, 1, 6},
- {2, 2, 3}, {0, 0, 2}, {0, 0, 2}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}
- };
-
- uint code;
- uint8 *pcode;
-
- status = BitstreamShowBits(stream, 8, &code);
-
- if (code >= 32)
- {
- pcode = (uint8*) & (TotCofNTrail5[(code>>5)+13][0]);
- }
- else if (code >= 8)
- {
- pcode = (uint8*) & (TotCofNTrail5[(code>>2)+6][0]);
- }
- else
- {
- pcode = (uint8*) & (TotCofNTrail5[code][0]);
- }
-
- *TrailingOnes = pcode[0];
- *TotalCoeff = pcode[1];
-
- BitstreamFlushBits(stream, pcode[2]);
-
- return status;
-}
-
-/* see Table 9-6 */
-AVCDec_Status ce_LevelPrefix(AVCDecBitstream *stream, uint *code)
-{
- uint temp;
- uint leading_zeros = 0;
- BitstreamShowBits(stream, 16, &temp);
- temp |= 1 ;
-
- PV_CLZ(leading_zeros, temp)
-
- BitstreamFlushBits(stream, leading_zeros + 1);
- *code = leading_zeros;
- return AVCDEC_SUCCESS;
-}
-
-/* see Table 9-7 and 9-8 */
-AVCDec_Status ce_TotalZeros(AVCDecBitstream *stream, int *code, int TotalCoeff)
-{
- const static uint8 TotZero1[28][2] = {{15, 9}, {14, 9}, {13, 9}, {12, 8},
- {12, 8}, {11, 8}, {11, 8}, {10, 7}, {9, 7}, {8, 6}, {8, 6}, {7, 6}, {7, 6}, {6, 5}, {6, 5},
- {6, 5}, {6, 5}, {5, 5}, {5, 5}, {5, 5}, {5, 5}, {4, 4}, {3, 4},
- {2, 3}, {2, 3}, {1, 3}, {1, 3}, {0, 1}
- };
-
- const static uint8 TotZero2n3[2][18][2] = {{{14, 6}, {13, 6}, {12, 6}, {11, 6},
- {10, 5}, {10, 5}, {9, 5}, {9, 5}, {8, 4}, {7, 4}, {6, 4}, {5, 4}, {4, 3}, {4, 3},
- {3, 3}, {2, 3}, {1, 3}, {0, 3}},
-
- /*const static uint8 TotZero3[18][2]=*/{{13, 6}, {11, 6}, {12, 5}, {12, 5}, {10, 5},
- {10, 5}, {9, 5}, {9, 5}, {8, 4}, {5, 4}, {4, 4}, {0, 4}, {7, 3}, {7, 3}, {6, 3}, {3, 3},
- {2, 3}, {1, 3}}
- };
-
- const static uint8 TotZero4[17][2] = {{12, 5}, {11, 5}, {10, 5}, {0, 5}, {9, 4},
- {9, 4}, {7, 4}, {7, 4}, {3, 4}, {3, 4}, {2, 4}, {2, 4}, {8, 3}, {6, 3}, {5, 3}, {4, 3}, {1, 3}
- };
-
- const static uint8 TotZero5[13][2] = {{11, 5}, {9, 5}, {10, 4}, {8, 4}, {2, 4},
- {1, 4}, {0, 4}, {7, 3}, {7, 3}, {6, 3}, {5, 3}, {4, 3}, {3, 3}
- };
-
- const static uint8 TotZero6to10[5][15][2] = {{{10, 6}, {0, 6}, {1, 5}, {1, 5}, {8, 4},
- {8, 4}, {8, 4}, {8, 4}, {9, 3}, {7, 3}, {6, 3}, {5, 3}, {4, 3}, {3, 3}, {2, 3}},
-
- /*const static uint8 TotZero7[15][2]=*/{{9, 6}, {0, 6}, {1, 5}, {1, 5}, {7, 4},
- {7, 4}, {7, 4}, {7, 4}, {8, 3}, {6, 3}, {4, 3}, {3, 3}, {2, 3}, {5, 2}, {5, 2}},
-
- /*const static uint8 TotZero8[15][2]=*/{{8, 6}, {0, 6}, {2, 5}, {2, 5}, {1, 4},
- {1, 4}, {1, 4}, {1, 4}, {7, 3}, {6, 3}, {3, 3}, {5, 2}, {5, 2}, {4, 2}, {4, 2}},
-
- /*const static uint8 TotZero9[15][2]=*/{{1, 6}, {0, 6}, {7, 5}, {7, 5}, {2, 4},
- {2, 4}, {2, 4}, {2, 4}, {5, 3}, {6, 2}, {6, 2}, {4, 2}, {4, 2}, {3, 2}, {3, 2}},
-
- /*const static uint8 TotZero10[11][2]=*/{{1, 5}, {0, 5}, {6, 4}, {6, 4}, {2, 3},
- {2, 3}, {2, 3}, {2, 3}, {5, 2}, {4, 2}, {3, 2}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}
- };
-
- const static uint8 TotZero11[7][2] = {{0, 4}, {1, 4}, {2, 3}, {2, 3}, {3, 3}, {5, 3}, {4, 1}};
-
- const static uint8 TotZero12to15[4][5][2] =
- {
- {{3, 1}, {2, 2}, {4, 3}, {1, 4}, {0, 4}},
- {{2, 1}, {3, 2}, {1, 3}, {0, 3}, {0, 0}},
- {{2, 1}, {1, 2}, {0, 2}, {0, 0}, {0, 0}},
- {{1, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}}
- };
-
- uint temp, mask;
- int indx;
- uint8 *pcode;
-
- if (TotalCoeff == 1)
- {
- BitstreamShowBits(stream, 9, &temp);
-
- if (temp >= 256)
- {
- pcode = (uint8*) & (TotZero1[27][0]);
- }
- else if (temp >= 64)
- {
- pcode = (uint8*) & (TotZero1[(temp>>5)+19][0]);
- }
- else if (temp >= 8)
- {
- pcode = (uint8*) & (TotZero1[(temp>>2)+5][0]);
- }
- else
- {
- pcode = (uint8*) & (TotZero1[temp-1][0]);
- }
-
- }
- else if (TotalCoeff == 2 || TotalCoeff == 3)
- {
- BitstreamShowBits(stream, 6, &temp);
-
- if (temp >= 32)
- {
- pcode = (uint8*) & (TotZero2n3[TotalCoeff-2][(temp>>3)+10][0]);
- }
- else if (temp >= 8)
- {
- pcode = (uint8*) & (TotZero2n3[TotalCoeff-2][(temp>>2)+6][0]);
- }
- else
- {
- pcode = (uint8*) & (TotZero2n3[TotalCoeff-2][temp][0]);
- }
- }
- else if (TotalCoeff == 4)
- {
- BitstreamShowBits(stream, 5, &temp);
-
- if (temp >= 12)
- {
- pcode = (uint8*) & (TotZero4[(temp>>2)+9][0]);
- }
- else
- {
- pcode = (uint8*) & (TotZero4[temp][0]);
- }
- }
- else if (TotalCoeff == 5)
- {
- BitstreamShowBits(stream, 5, &temp);
-
- if (temp >= 16)
- {
- pcode = (uint8*) & (TotZero5[(temp>>2)+5][0]);
- }
- else if (temp >= 2)
- {
- pcode = (uint8*) & (TotZero5[(temp>>1)+1][0]);
- }
- else
- {
- pcode = (uint8*) & (TotZero5[temp][0]);
- }
- }
- else if (TotalCoeff >= 6 && TotalCoeff <= 10)
- {
- if (TotalCoeff == 10)
- {
- BitstreamShowBits(stream, 5, &temp);
- }
- else
- {
- BitstreamShowBits(stream, 6, &temp);
- }
-
-
- if (temp >= 8)
- {
- pcode = (uint8*) & (TotZero6to10[TotalCoeff-6][(temp>>3)+7][0]);
- }
- else
- {
- pcode = (uint8*) & (TotZero6to10[TotalCoeff-6][temp][0]);
- }
- }
- else if (TotalCoeff == 11)
- {
- BitstreamShowBits(stream, 4, &temp);
-
-
- if (temp >= 8)
- {
- pcode = (uint8*) & (TotZero11[6][0]);
- }
- else if (temp >= 4)
- {
- pcode = (uint8*) & (TotZero11[(temp>>1)+2][0]);
- }
- else
- {
- pcode = (uint8*) & (TotZero11[temp][0]);
- }
- }
- else
- {
- BitstreamShowBits(stream, (16 - TotalCoeff), &temp);
- mask = 1 << (15 - TotalCoeff);
- indx = 0;
- while ((temp&mask) == 0 && indx < (16 - TotalCoeff)) /* search location of 1 bit */
- {
- mask >>= 1;
- indx++;
- }
-
- pcode = (uint8*) & (TotZero12to15[TotalCoeff-12][indx]);
- }
-
- *code = pcode[0];
- BitstreamFlushBits(stream, pcode[1]);
-
- return AVCDEC_SUCCESS;
-}
-
-/* see Table 9-9 */
-AVCDec_Status ce_TotalZerosChromaDC(AVCDecBitstream *stream, int *code, int TotalCoeff)
-{
- const static uint8 TotZeroChrom1to3[3][8][2] =
- {
- {{3, 3}, {2, 3}, {1, 2}, {1, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}},
- {{2, 2}, {2, 2}, {1, 2}, {1, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}},
- {{1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}},
- };
-
-
- uint temp;
- uint8 *pcode;
-
- BitstreamShowBits(stream, 3, &temp);
- pcode = (uint8*) & (TotZeroChrom1to3[TotalCoeff-1][temp]);
-
- *code = pcode[0];
-
- BitstreamFlushBits(stream, pcode[1]);
-
- return AVCDEC_SUCCESS;
-}
-
-/* see Table 9-10 */
-AVCDec_Status ce_RunBefore(AVCDecBitstream *stream, int *code, int zerosLeft)
-{
- const static int codlen[6] = {1, 2, 2, 3, 3, 3}; /* num bits to read */
- const static uint8 RunBeforeTab[6][8][2] = {{{1, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}},
- /*const static int RunBefore2[4][2]=*/{{2, 2}, {1, 2}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}},
- /*const static int RunBefore3[4][2]=*/{{3, 2}, {2, 2}, {1, 2}, {0, 2}, {0, 0}, {0, 0}, {0, 0}, {0, 0}},
- /*const static int RunBefore4[7][2]=*/{{4, 3}, {3, 3}, {2, 2}, {2, 2}, {1, 2}, {1, 2}, {0, 2}, {0, 2}},
- /*const static int RunBefore5[7][2]=*/{{5, 3}, {4, 3}, {3, 3}, {2, 3}, {1, 2}, {1, 2}, {0, 2}, {0, 2}},
- /*const static int RunBefore6[7][2]=*/{{1, 3}, {2, 3}, {4, 3}, {3, 3}, {6, 3}, {5, 3}, {0, 2}, {0, 2}}
- };
-
- uint temp;
- uint8 *pcode;
- int indx;
-
- if (zerosLeft <= 6)
- {
- BitstreamShowBits(stream, codlen[zerosLeft-1], &temp);
-
- pcode = (uint8*) & (RunBeforeTab[zerosLeft-1][temp][0]);
-
- *code = pcode[0];
-
- BitstreamFlushBits(stream, pcode[1]);
- }
- else
- {
- BitstreamReadBits(stream, 3, &temp);
- if (temp)
- {
- *code = 7 - temp;
- }
- else
- {
- BitstreamShowBits(stream, 9, &temp);
- temp <<= 7;
- temp |= 1;
- indx = 0;
- PV_CLZ(indx, temp)
- *code = 7 + indx;
- BitstreamFlushBits(stream, indx + 1);
- }
- }
-
-
- return AVCDEC_SUCCESS;
-}
diff --git a/media/libstagefright/codecs/avc/enc/AVCEncoder.cpp b/media/libstagefright/codecs/avc/enc/AVCEncoder.cpp
index e3292e6..0096760 100644
--- a/media/libstagefright/codecs/avc/enc/AVCEncoder.cpp
+++ b/media/libstagefright/codecs/avc/enc/AVCEncoder.cpp
@@ -475,7 +475,9 @@
}
status_t err = mSource->read(&mInputBuffer, options);
if (err != OK) {
- LOGE("Failed to read input video frame: %d", err);
+ if (err != ERROR_END_OF_STREAM) {
+ LOGE("Failed to read input video frame: %d", err);
+ }
outputBuffer->release();
return err;
}
diff --git a/media/libstagefright/codecs/common/Android.mk b/media/libstagefright/codecs/common/Android.mk
index fffb2ad..af8795a 100644
--- a/media/libstagefright/codecs/common/Android.mk
+++ b/media/libstagefright/codecs/common/Android.mk
@@ -1,7 +1,7 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_PRELINK_MODULE := false
+
LOCAL_SRC_FILES := cmnMemory.c
diff --git a/media/libstagefright/codecs/common/Config.mk b/media/libstagefright/codecs/common/Config.mk
index 187f25c..3d754e7 100644
--- a/media/libstagefright/codecs/common/Config.mk
+++ b/media/libstagefright/codecs/common/Config.mk
@@ -1,8 +1,8 @@
-#
+#
# This configure file is just for Linux projects against Android
#
-VOPRJ :=
+VOPRJ :=
VONJ :=
# WARNING:
@@ -20,5 +20,5 @@
VOTEST := 0
-VO_CFLAGS:=-DLINUX
+VO_CFLAGS:=-DLINUX
diff --git a/media/libstagefright/codecs/common/include/voAMRWB.h b/media/libstagefright/codecs/common/include/voAMRWB.h
index d3eb537..13290c7 100644
--- a/media/libstagefright/codecs/common/include/voAMRWB.h
+++ b/media/libstagefright/codecs/common/include/voAMRWB.h
@@ -29,20 +29,20 @@
#pragma pack(push, 4)
/*!* the bit rate the codec supports*/
-typedef enum {
+typedef enum {
VOAMRWB_MDNONE = -1, /*!< Invalid mode */
VOAMRWB_MD66 = 0, /*!< 6.60kbps */
- VOAMRWB_MD885 = 1, /*!< 8.85kbps */
+ VOAMRWB_MD885 = 1, /*!< 8.85kbps */
VOAMRWB_MD1265 = 2, /*!< 12.65kbps */
VOAMRWB_MD1425 = 3, /*!< 14.25kbps */
VOAMRWB_MD1585 = 4, /*!< 15.85bps */
VOAMRWB_MD1825 = 5, /*!< 18.25bps */
VOAMRWB_MD1985 = 6, /*!< 19.85kbps */
VOAMRWB_MD2305 = 7, /*!< 23.05kbps */
- VOAMRWB_MD2385 = 8, /*!< 23.85kbps> */
+ VOAMRWB_MD2385 = 8, /*!< 23.85kbps> */
VOAMRWB_N_MODES = 9, /*!< Invalid mode */
VOAMRWB_MODE_MAX = VO_MAX_ENUM_VALUE
-
+
}VOAMRWBMODE;
/*!* the frame format the codec supports*/
@@ -51,17 +51,17 @@
/*One word (2-byte) for sync word (0x6b21)*/
/*One word (2-byte) for frame length N.*/
/*N words (2-byte) containing N bits (bit 0 = 0x007f, bit 1 = 0x0081).*/
- VOAMRWB_ITU = 1,
+ VOAMRWB_ITU = 1,
/*One word (2-byte) for sync word (0x6b21).*/
- /*One word (2-byte) to indicate the frame type.*/
+ /*One word (2-byte) to indicate the frame type.*/
/*One word (2-byte) to indicate the mode.*/
/*N words (2-byte) containing N bits (bit 0 = 0xff81, bit 1 = 0x007f).*/
- VOAMRWB_RFC3267 = 2, /* see RFC 3267 */
- VOAMRWB_TMAX = VO_MAX_ENUM_VALUE
+ VOAMRWB_RFC3267 = 2, /* see RFC 3267 */
+ VOAMRWB_TMAX = VO_MAX_ENUM_VALUE
}VOAMRWBFRAMETYPE;
-#define VO_PID_AMRWB_Module 0x42261000
+#define VO_PID_AMRWB_Module 0x42261000
#define VO_PID_AMRWB_FORMAT (VO_PID_AMRWB_Module | 0x0002)
#define VO_PID_AMRWB_CHANNELS (VO_PID_AMRWB_Module | 0x0003)
#define VO_PID_AMRWB_SAMPLERATE (VO_PID_AMRWB_Module | 0x0004)
diff --git a/media/libstagefright/codecs/common/include/voAudio.h b/media/libstagefright/codecs/common/include/voAudio.h
index d8628ee..21d0cf6 100644
--- a/media/libstagefright/codecs/common/include/voAudio.h
+++ b/media/libstagefright/codecs/common/include/voAudio.h
@@ -135,7 +135,7 @@
* \param pOutInfo [OUT] The codec fills audio format and the input data size used in current call.
* pOutInfo->InputUsed is total used input data size in byte.
* \retval VO_ERR_NONE Succeeded.
- * VO_ERR_INPUT_BUFFER_SMALL. The input was finished or the input data was not enought. Continue to input
+ * VO_ERR_INPUT_BUFFER_SMALL. The input was finished or the input data was not enought. Continue to input
* data before next call.
*/
VO_U32 (VO_API * GetOutputData) (VO_HANDLE hCodec, VO_CODECBUFFER * pOutBuffer, VO_AUDIO_OUTPUTINFO * pOutInfo);
diff --git a/media/libstagefright/codecs/common/include/voIndex.h b/media/libstagefright/codecs/common/include/voIndex.h
index 320a2f8..a409a6e 100644
--- a/media/libstagefright/codecs/common/include/voIndex.h
+++ b/media/libstagefright/codecs/common/include/voIndex.h
@@ -173,7 +173,7 @@
// Module own error ID
#define VO_ERR_Module 0x8xxx0X00
*/
-
+
#define VO_PID_COMMON_BASE 0x40000000 /*!< The base of common param ID */
#define VO_PID_COMMON_QUERYMEM (VO_PID_COMMON_BASE | 0X0001) /*!< Query the memory needed; Reserved. */
#define VO_PID_COMMON_INPUTTYPE (VO_PID_COMMON_BASE | 0X0002) /*!< Set or get the input buffer type. VO_INPUT_TYPE */
diff --git a/media/libstagefright/codecs/g711/dec/Android.mk b/media/libstagefright/codecs/g711/dec/Android.mk
index cfb9fe4..6692533 100644
--- a/media/libstagefright/codecs/g711/dec/Android.mk
+++ b/media/libstagefright/codecs/g711/dec/Android.mk
@@ -2,11 +2,16 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
- G711Decoder.cpp
+ SoftG711.cpp
LOCAL_C_INCLUDES := \
frameworks/base/media/libstagefright/include \
+ frameworks/base/include/media/stagefright/openmax \
-LOCAL_MODULE := libstagefright_g711dec
+LOCAL_SHARED_LIBRARIES := \
+ libstagefright libstagefright_omx libstagefright_foundation libutils
-include $(BUILD_STATIC_LIBRARY)
+LOCAL_MODULE := libstagefright_soft_g711dec
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libstagefright/codecs/g711/dec/G711Decoder.cpp b/media/libstagefright/codecs/g711/dec/G711Decoder.cpp
deleted file mode 100644
index 4414e4e..0000000
--- a/media/libstagefright/codecs/g711/dec/G711Decoder.cpp
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright (C) 2010 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 "G711Decoder"
-#include <utils/Log.h>
-
-#include "G711Decoder.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>
-
-static const size_t kMaxNumSamplesPerFrame = 16384;
-
-namespace android {
-
-G711Decoder::G711Decoder(const sp<MediaSource> &source)
- : mSource(source),
- mStarted(false),
- mBufferGroup(NULL) {
-}
-
-G711Decoder::~G711Decoder() {
- if (mStarted) {
- stop();
- }
-}
-
-status_t G711Decoder::start(MetaData *params) {
- CHECK(!mStarted);
-
- const char *mime;
- CHECK(mSource->getFormat()->findCString(kKeyMIMEType, &mime));
-
- mIsMLaw = false;
- if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
- mIsMLaw = true;
- } else if (strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)) {
- return ERROR_UNSUPPORTED;
- }
-
- mBufferGroup = new MediaBufferGroup;
- mBufferGroup->add_buffer(
- new MediaBuffer(kMaxNumSamplesPerFrame * sizeof(int16_t)));
-
- mSource->start();
-
- mStarted = true;
-
- return OK;
-}
-
-status_t G711Decoder::stop() {
- CHECK(mStarted);
-
- delete mBufferGroup;
- mBufferGroup = NULL;
-
- mSource->stop();
-
- mStarted = false;
-
- return OK;
-}
-
-sp<MetaData> G711Decoder::getFormat() {
- sp<MetaData> srcFormat = mSource->getFormat();
-
- int32_t numChannels;
- int32_t sampleRate;
-
- CHECK(srcFormat->findInt32(kKeyChannelCount, &numChannels));
- CHECK(srcFormat->findInt32(kKeySampleRate, &sampleRate));
-
- sp<MetaData> meta = new MetaData;
- meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
- meta->setInt32(kKeyChannelCount, numChannels);
- meta->setInt32(kKeySampleRate, sampleRate);
-
- int64_t durationUs;
- if (srcFormat->findInt64(kKeyDuration, &durationUs)) {
- meta->setInt64(kKeyDuration, durationUs);
- }
-
- meta->setCString(kKeyDecoderComponent, "G711Decoder");
-
- return meta;
-}
-
-status_t G711Decoder::read(
- MediaBuffer **out, const ReadOptions *options) {
- status_t err;
-
- *out = NULL;
-
- int64_t seekTimeUs;
- ReadOptions::SeekMode mode;
- if (options && options->getSeekTo(&seekTimeUs, &mode)) {
- CHECK(seekTimeUs >= 0);
- } else {
- seekTimeUs = -1;
- }
-
- MediaBuffer *inBuffer;
- err = mSource->read(&inBuffer, options);
-
- if (err != OK) {
- return err;
- }
-
- if (inBuffer->range_length() > kMaxNumSamplesPerFrame) {
- LOGE("input buffer too large (%d).", inBuffer->range_length());
-
- inBuffer->release();
- inBuffer = NULL;
-
- return ERROR_UNSUPPORTED;
- }
-
- int64_t timeUs;
- CHECK(inBuffer->meta_data()->findInt64(kKeyTime, &timeUs));
-
- const uint8_t *inputPtr =
- (const uint8_t *)inBuffer->data() + inBuffer->range_offset();
-
- MediaBuffer *outBuffer;
- CHECK_EQ(mBufferGroup->acquire_buffer(&outBuffer), OK);
-
- if (mIsMLaw) {
- DecodeMLaw(
- static_cast<int16_t *>(outBuffer->data()),
- inputPtr, inBuffer->range_length());
- } else {
- DecodeALaw(
- static_cast<int16_t *>(outBuffer->data()),
- inputPtr, inBuffer->range_length());
- }
-
- // Each 8-bit byte is converted into a 16-bit sample.
- outBuffer->set_range(0, inBuffer->range_length() * 2);
-
- outBuffer->meta_data()->setInt64(kKeyTime, timeUs);
-
- inBuffer->release();
- inBuffer = NULL;
-
- *out = outBuffer;
-
- return OK;
-}
-
-// static
-void G711Decoder::DecodeALaw(
- int16_t *out, const uint8_t *in, size_t inSize) {
- while (inSize-- > 0) {
- int32_t x = *in++;
-
- int32_t ix = x ^ 0x55;
- ix &= 0x7f;
-
- int32_t iexp = ix >> 4;
- int32_t mant = ix & 0x0f;
-
- if (iexp > 0) {
- mant += 16;
- }
-
- mant = (mant << 4) + 8;
-
- if (iexp > 1) {
- mant = mant << (iexp - 1);
- }
-
- *out++ = (x > 127) ? mant : -mant;
- }
-}
-
-// static
-void G711Decoder::DecodeMLaw(
- int16_t *out, const uint8_t *in, size_t inSize) {
- while (inSize-- > 0) {
- int32_t x = *in++;
-
- int32_t mantissa = ~x;
- int32_t exponent = (mantissa >> 4) & 7;
- int32_t segment = exponent + 1;
- mantissa &= 0x0f;
-
- int32_t step = 4 << segment;
-
- int32_t abs = (0x80l << exponent) + step * mantissa + step / 2 - 4 * 33;
-
- *out++ = (x < 0x80) ? -abs : abs;
- }
-}
-
-} // namespace android
diff --git a/media/libstagefright/codecs/g711/dec/SoftG711.cpp b/media/libstagefright/codecs/g711/dec/SoftG711.cpp
new file mode 100644
index 0000000..15e2c26
--- /dev/null
+++ b/media/libstagefright/codecs/g711/dec/SoftG711.cpp
@@ -0,0 +1,302 @@
+/*
+ * Copyright (C) 2011 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 "SoftG711"
+#include <utils/Log.h>
+
+#include "SoftG711.h"
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/MediaDefs.h>
+
+namespace android {
+
+template<class T>
+static void InitOMXParams(T *params) {
+ params->nSize = sizeof(T);
+ params->nVersion.s.nVersionMajor = 1;
+ params->nVersion.s.nVersionMinor = 0;
+ params->nVersion.s.nRevision = 0;
+ params->nVersion.s.nStep = 0;
+}
+
+SoftG711::SoftG711(
+ const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component)
+ : SimpleSoftOMXComponent(name, callbacks, appData, component),
+ mIsMLaw(true),
+ mNumChannels(1),
+ mSignalledError(false) {
+ if (!strcmp(name, "OMX.google.g711.alaw.decoder")) {
+ mIsMLaw = false;
+ } else {
+ CHECK(!strcmp(name, "OMX.google.g711.mlaw.decoder"));
+ }
+
+ initPorts();
+}
+
+SoftG711::~SoftG711() {
+}
+
+void SoftG711::initPorts() {
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ InitOMXParams(&def);
+
+ def.nPortIndex = 0;
+ def.eDir = OMX_DirInput;
+ def.nBufferCountMin = kNumBuffers;
+ def.nBufferCountActual = def.nBufferCountMin;
+ def.nBufferSize = 8192;
+ def.bEnabled = OMX_TRUE;
+ def.bPopulated = OMX_FALSE;
+ def.eDomain = OMX_PortDomainAudio;
+ def.bBuffersContiguous = OMX_FALSE;
+ def.nBufferAlignment = 1;
+
+ def.format.audio.cMIMEType =
+ const_cast<char *>(
+ mIsMLaw
+ ? MEDIA_MIMETYPE_AUDIO_G711_MLAW
+ : MEDIA_MIMETYPE_AUDIO_G711_ALAW);
+
+ def.format.audio.pNativeRender = NULL;
+ def.format.audio.bFlagErrorConcealment = OMX_FALSE;
+ def.format.audio.eEncoding = OMX_AUDIO_CodingG711;
+
+ addPort(def);
+
+ def.nPortIndex = 1;
+ def.eDir = OMX_DirOutput;
+ def.nBufferCountMin = kNumBuffers;
+ def.nBufferCountActual = def.nBufferCountMin;
+ def.nBufferSize = kMaxNumSamplesPerFrame * sizeof(int16_t);
+ def.bEnabled = OMX_TRUE;
+ def.bPopulated = OMX_FALSE;
+ def.eDomain = OMX_PortDomainAudio;
+ def.bBuffersContiguous = OMX_FALSE;
+ def.nBufferAlignment = 2;
+
+ def.format.audio.cMIMEType = const_cast<char *>("audio/raw");
+ def.format.audio.pNativeRender = NULL;
+ def.format.audio.bFlagErrorConcealment = OMX_FALSE;
+ def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
+
+ addPort(def);
+}
+
+OMX_ERRORTYPE SoftG711::internalGetParameter(
+ OMX_INDEXTYPE index, OMX_PTR params) {
+ switch (index) {
+ case OMX_IndexParamAudioPcm:
+ {
+ OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
+ (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
+
+ if (pcmParams->nPortIndex > 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ pcmParams->eNumData = OMX_NumericalDataSigned;
+ pcmParams->eEndian = OMX_EndianBig;
+ pcmParams->bInterleaved = OMX_TRUE;
+ pcmParams->nBitPerSample = 16;
+ pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
+ pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
+ pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
+
+ pcmParams->nChannels = mNumChannels;
+ pcmParams->nSamplingRate = 8000;
+
+ return OMX_ErrorNone;
+ }
+
+ default:
+ return SimpleSoftOMXComponent::internalGetParameter(index, params);
+ }
+}
+
+OMX_ERRORTYPE SoftG711::internalSetParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params) {
+ switch (index) {
+ case OMX_IndexParamAudioPcm:
+ {
+ OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
+ (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
+
+ if (pcmParams->nPortIndex != 0) {
+ return OMX_ErrorUndefined;
+ }
+
+ if (pcmParams->nChannels < 1 || pcmParams->nChannels > 2) {
+ return OMX_ErrorUndefined;
+ }
+
+ mNumChannels = pcmParams->nChannels;
+
+ return OMX_ErrorNone;
+ }
+
+ case OMX_IndexParamStandardComponentRole:
+ {
+ const OMX_PARAM_COMPONENTROLETYPE *roleParams =
+ (const OMX_PARAM_COMPONENTROLETYPE *)params;
+
+ if (mIsMLaw) {
+ if (strncmp((const char *)roleParams->cRole,
+ "audio_decoder.g711mlaw",
+ OMX_MAX_STRINGNAME_SIZE - 1)) {
+ return OMX_ErrorUndefined;
+ }
+ } else {
+ if (strncmp((const char *)roleParams->cRole,
+ "audio_decoder.g711alaw",
+ OMX_MAX_STRINGNAME_SIZE - 1)) {
+ return OMX_ErrorUndefined;
+ }
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ default:
+ return SimpleSoftOMXComponent::internalSetParameter(index, params);
+ }
+}
+
+void SoftG711::onQueueFilled(OMX_U32 portIndex) {
+ if (mSignalledError) {
+ return;
+ }
+
+ List<BufferInfo *> &inQueue = getPortQueue(0);
+ List<BufferInfo *> &outQueue = getPortQueue(1);
+
+ while (!inQueue.empty() && !outQueue.empty()) {
+ BufferInfo *inInfo = *inQueue.begin();
+ OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
+
+ BufferInfo *outInfo = *outQueue.begin();
+ OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
+
+ if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
+ inQueue.erase(inQueue.begin());
+ inInfo->mOwnedByUs = false;
+ notifyEmptyBufferDone(inHeader);
+
+ outHeader->nFilledLen = 0;
+ outHeader->nFlags = OMX_BUFFERFLAG_EOS;
+
+ outQueue.erase(outQueue.begin());
+ outInfo->mOwnedByUs = false;
+ notifyFillBufferDone(outHeader);
+ return;
+ }
+
+ if (inHeader->nFilledLen > kMaxNumSamplesPerFrame) {
+ LOGE("input buffer too large (%ld).", inHeader->nFilledLen);
+
+ notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+ mSignalledError = true;
+ }
+
+ const uint8_t *inputptr = inHeader->pBuffer + inHeader->nOffset;
+
+ if (mIsMLaw) {
+ DecodeMLaw(
+ reinterpret_cast<int16_t *>(outHeader->pBuffer),
+ inputptr, inHeader->nFilledLen);
+ } else {
+ DecodeALaw(
+ reinterpret_cast<int16_t *>(outHeader->pBuffer),
+ inputptr, inHeader->nFilledLen);
+ }
+
+ outHeader->nTimeStamp = inHeader->nTimeStamp;
+ outHeader->nOffset = 0;
+ outHeader->nFilledLen = inHeader->nFilledLen * sizeof(int16_t);
+ outHeader->nFlags = 0;
+
+ inInfo->mOwnedByUs = false;
+ inQueue.erase(inQueue.begin());
+ inInfo = NULL;
+ notifyEmptyBufferDone(inHeader);
+ inHeader = NULL;
+
+ outInfo->mOwnedByUs = false;
+ outQueue.erase(outQueue.begin());
+ outInfo = NULL;
+ notifyFillBufferDone(outHeader);
+ outHeader = NULL;
+ }
+}
+
+// static
+void SoftG711::DecodeALaw(
+ int16_t *out, const uint8_t *in, size_t inSize) {
+ while (inSize-- > 0) {
+ int32_t x = *in++;
+
+ int32_t ix = x ^ 0x55;
+ ix &= 0x7f;
+
+ int32_t iexp = ix >> 4;
+ int32_t mant = ix & 0x0f;
+
+ if (iexp > 0) {
+ mant += 16;
+ }
+
+ mant = (mant << 4) + 8;
+
+ if (iexp > 1) {
+ mant = mant << (iexp - 1);
+ }
+
+ *out++ = (x > 127) ? mant : -mant;
+ }
+}
+
+// static
+void SoftG711::DecodeMLaw(
+ int16_t *out, const uint8_t *in, size_t inSize) {
+ while (inSize-- > 0) {
+ int32_t x = *in++;
+
+ int32_t mantissa = ~x;
+ int32_t exponent = (mantissa >> 4) & 7;
+ int32_t segment = exponent + 1;
+ mantissa &= 0x0f;
+
+ int32_t step = 4 << segment;
+
+ int32_t abs = (0x80l << exponent) + step * mantissa + step / 2 - 4 * 33;
+
+ *out++ = (x < 0x80) ? -abs : abs;
+ }
+}
+
+} // namespace android
+
+android::SoftOMXComponent *createSoftOMXComponent(
+ const char *name, const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData, OMX_COMPONENTTYPE **component) {
+ return new android::SoftG711(name, callbacks, appData, component);
+}
+
diff --git a/media/libstagefright/codecs/g711/dec/SoftG711.h b/media/libstagefright/codecs/g711/dec/SoftG711.h
new file mode 100644
index 0000000..bff0c68
--- /dev/null
+++ b/media/libstagefright/codecs/g711/dec/SoftG711.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2011 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 SOFT_G711_H_
+
+#define SOFT_G711_H_
+
+#include "SimpleSoftOMXComponent.h"
+
+namespace android {
+
+struct SoftG711 : public SimpleSoftOMXComponent {
+ SoftG711(const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component);
+
+protected:
+ virtual ~SoftG711();
+
+ virtual OMX_ERRORTYPE internalGetParameter(
+ OMX_INDEXTYPE index, OMX_PTR params);
+
+ virtual OMX_ERRORTYPE internalSetParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params);
+
+ virtual void onQueueFilled(OMX_U32 portIndex);
+
+private:
+ enum {
+ kNumBuffers = 4,
+ kMaxNumSamplesPerFrame = 16384,
+ };
+
+ bool mIsMLaw;
+ OMX_U32 mNumChannels;
+ bool mSignalledError;
+
+ void initPorts();
+
+ static void DecodeALaw(int16_t *out, const uint8_t *in, size_t inSize);
+ static void DecodeMLaw(int16_t *out, const uint8_t *in, size_t inSize);
+
+ DISALLOW_EVIL_CONSTRUCTORS(SoftG711);
+};
+
+} // namespace android
+
+#endif // SOFT_G711_H_
+
diff --git a/media/libstagefright/codecs/m4v_h263/dec/Android.mk b/media/libstagefright/codecs/m4v_h263/dec/Android.mk
index 2d9bcc6..2ffa5f2 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/Android.mk
+++ b/media/libstagefright/codecs/m4v_h263/dec/Android.mk
@@ -2,7 +2,6 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
- M4vH263Decoder.cpp \
src/adaptive_smooth_no_mmx.cpp \
src/bitstream.cpp \
src/block_idct.cpp \
@@ -48,3 +47,29 @@
LOCAL_CFLAGS := -DOSCL_EXPORT_REF= -DOSCL_IMPORT_REF=
include $(BUILD_STATIC_LIBRARY)
+
+################################################################################
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ SoftMPEG4.cpp
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/src \
+ $(LOCAL_PATH)/include \
+ frameworks/base/media/libstagefright/include \
+ frameworks/base/include/media/stagefright/openmax \
+
+LOCAL_CFLAGS := -DOSCL_EXPORT_REF= -DOSCL_IMPORT_REF=
+
+LOCAL_STATIC_LIBRARIES := \
+ libstagefright_m4vh263dec
+
+LOCAL_SHARED_LIBRARIES := \
+ libstagefright libstagefright_omx libstagefright_foundation libutils
+
+LOCAL_MODULE := libstagefright_soft_mpeg4dec
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libstagefright/codecs/m4v_h263/dec/M4vH263Decoder.cpp b/media/libstagefright/codecs/m4v_h263/dec/M4vH263Decoder.cpp
deleted file mode 100644
index 2bdb3ef..0000000
--- a/media/libstagefright/codecs/m4v_h263/dec/M4vH263Decoder.cpp
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * 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 <utils/Log.h>
-#include <stdlib.h> // for free
-#include "ESDS.h"
-#include "M4vH263Decoder.h"
-
-#include "mp4dec_api.h"
-
-#include <OMX_Component.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/MediaBufferGroup.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),
- mTargetTimeUs(-1) {
-
- LOGV("M4vH263Decoder");
- 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));
-
- // We'll ignore the dimension advertised by the source, the decoder
- // appears to require us to always start with the default dimensions
- // of 352 x 288 to operate correctly and later react to changes in
- // the dimensions as needed.
- mWidth = 352;
- mHeight = 288;
-
- 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;
-}
-
-void M4vH263Decoder::allocateFrames(int32_t width, int32_t height) {
- size_t frameSize =
- (((width + 15) & - 16) * ((height + 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());
-}
-
-status_t M4vH263Decoder::start(MetaData *) {
- CHECK(!mStarted);
-
- const char *mime = NULL;
- sp<MetaData> meta = mSource->getFormat();
- CHECK(meta->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[1] = {0};
- int32_t vol_size = 0;
- if (meta->findData(kKeyESDS, &type, &data, &size)) {
- ESDS esds((const uint8_t *)data, size);
- CHECK_EQ(esds.InitCheck(), (status_t)OK);
-
- const void *codec_specific_data;
- size_t codec_specific_data_size;
- esds.getCodecSpecificInfo(
- &codec_specific_data, &codec_specific_data_size);
-
- vol_data[0] = (uint8_t *) malloc(codec_specific_data_size);
- memcpy(vol_data[0], codec_specific_data, codec_specific_data_size);
- vol_size = codec_specific_data_size;
- } else {
- vol_data[0] = NULL;
- vol_size = 0;
-
- }
-
- Bool success = PVInitVideoDecoder(
- mHandle, vol_data, &vol_size, 1, mWidth, mHeight, mode);
- if (vol_data[0]) free(vol_data[0]);
-
- if (success != PV_TRUE) {
- LOGW("PVInitVideoDecoder failed. Unsupported content?");
- return ERROR_UNSUPPORTED;
- }
-
- MP4DecodingMode actualMode = PVGetDecBitstreamMode(mHandle);
- if (mode != actualMode) {
- PVCleanUpVideoDecoder(mHandle);
- return UNKNOWN_ERROR;
- }
-
- PVSetPostProcType((VideoDecControls *) mHandle, 0);
-
- int32_t width, height;
- PVGetVideoDimensions(mHandle, &width, &height);
- if (mode == H263_MODE && (width == 0 || height == 0)) {
- width = 352;
- height = 288;
- }
- allocateFrames(width, height);
-
- mSource->start();
-
- mNumSamplesOutput = 0;
- mTargetTimeUs = -1;
- 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;
-
- bool seeking = false;
- int64_t seekTimeUs;
- ReadOptions::SeekMode mode;
- if (options && options->getSeekTo(&seekTimeUs, &mode)) {
- seeking = true;
- CHECK_EQ((int)PVResetVideoDecoder(mHandle), PV_TRUE);
- }
-
- MediaBuffer *inputBuffer = NULL;
- status_t err = mSource->read(&inputBuffer, options);
- if (err != OK) {
- return err;
- }
-
- if (seeking) {
- int64_t targetTimeUs;
- if (inputBuffer->meta_data()->findInt64(kKeyTargetTime, &targetTimeUs)
- && targetTimeUs >= 0) {
- mTargetTimeUs = targetTimeUs;
- } else {
- mTargetTimeUs = -1;
- }
- }
-
- uint8_t *bitstream =
- (uint8_t *) inputBuffer->data() + inputBuffer->range_offset();
-
- uint32_t timestamp = 0xFFFFFFFF;
- int32_t bufferSize = inputBuffer->range_length();
- uint32_t useExtTimestamp = 0;
- if (PVDecodeVideoFrame(
- mHandle, &bitstream, ×tamp, &bufferSize,
- &useExtTimestamp,
- (uint8_t *)mFrames[mNumSamplesOutput & 0x01]->data())
- != PV_TRUE) {
- LOGE("failed to decode video frame.");
-
- inputBuffer->release();
- inputBuffer = NULL;
-
- return UNKNOWN_ERROR;
- }
-
- int32_t disp_width, disp_height;
- PVGetVideoDimensions(mHandle, &disp_width, &disp_height);
-
- int32_t buf_width, buf_height;
- PVGetBufferDimensions(mHandle, &buf_width, &buf_height);
-
- if (buf_width != mWidth || buf_height != mHeight) {
- ++mNumSamplesOutput; // The client will never get to see this frame.
-
- inputBuffer->release();
- inputBuffer = NULL;
-
- mWidth = buf_width;
- mHeight = buf_height;
- mFormat->setInt32(kKeyWidth, mWidth);
- mFormat->setInt32(kKeyHeight, mHeight);
-
- CHECK_LE(disp_width, buf_width);
- CHECK_LE(disp_height, buf_height);
-
- mFormat->setRect(kKeyCropRect, 0, 0, disp_width - 1, disp_height - 1);
-
- return INFO_FORMAT_CHANGED;
- }
-
- int64_t timeUs;
- CHECK(inputBuffer->meta_data()->findInt64(kKeyTime, &timeUs));
-
- inputBuffer->release();
- inputBuffer = NULL;
-
- bool skipFrame = false;
-
- if (mTargetTimeUs >= 0) {
- CHECK(timeUs <= mTargetTimeUs);
-
- if (timeUs < mTargetTimeUs) {
- // We're still waiting for the frame with the matching
- // timestamp and we won't return the current one.
- skipFrame = true;
-
- LOGV("skipping frame at %lld us", timeUs);
- } else {
- LOGV("found target frame at %lld us", timeUs);
-
- mTargetTimeUs = -1;
- }
- }
-
- if (skipFrame) {
- *out = new MediaBuffer(0);
- } else {
- *out = mFrames[mNumSamplesOutput & 0x01];
- (*out)->add_ref();
- (*out)->meta_data()->setInt64(kKeyTime, timeUs);
- }
-
- ++mNumSamplesOutput;
-
- 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/SoftMPEG4.cpp b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
new file mode 100644
index 0000000..ddced5f
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
@@ -0,0 +1,592 @@
+/*
+ * Copyright (C) 2011 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 "SoftMPEG4"
+#include <utils/Log.h>
+
+#include "SoftMPEG4.h"
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/IOMX.h>
+
+#include "mp4dec_api.h"
+
+namespace android {
+
+static const CodecProfileLevel kM4VProfileLevels[] = {
+ { OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level0 },
+ { OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level0b },
+ { OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level1 },
+ { OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level2 },
+ { OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level3 },
+};
+
+static const CodecProfileLevel kH263ProfileLevels[] = {
+ { OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level10 },
+ { OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level20 },
+ { OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level30 },
+ { OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level45 },
+ { OMX_VIDEO_H263ProfileISWV2, OMX_VIDEO_H263Level10 },
+ { OMX_VIDEO_H263ProfileISWV2, OMX_VIDEO_H263Level20 },
+ { OMX_VIDEO_H263ProfileISWV2, OMX_VIDEO_H263Level30 },
+ { OMX_VIDEO_H263ProfileISWV2, OMX_VIDEO_H263Level45 },
+};
+
+template<class T>
+static void InitOMXParams(T *params) {
+ params->nSize = sizeof(T);
+ params->nVersion.s.nVersionMajor = 1;
+ params->nVersion.s.nVersionMinor = 0;
+ params->nVersion.s.nRevision = 0;
+ params->nVersion.s.nStep = 0;
+}
+
+SoftMPEG4::SoftMPEG4(
+ const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component)
+ : SimpleSoftOMXComponent(name, callbacks, appData, component),
+ mMode(MODE_MPEG4),
+ mHandle(new tagvideoDecControls),
+ mInputBufferCount(0),
+ mWidth(352),
+ mHeight(288),
+ mCropLeft(0),
+ mCropTop(0),
+ mCropRight(mWidth - 1),
+ mCropBottom(mHeight - 1),
+ mSignalledError(false),
+ mInitialized(false),
+ mFramesConfigured(false),
+ mNumSamplesOutput(0),
+ mOutputPortSettingsChange(NONE) {
+ if (!strcmp(name, "OMX.google.h263.decoder")) {
+ mMode = MODE_H263;
+ } else {
+ CHECK(!strcmp(name, "OMX.google.mpeg4.decoder"));
+ }
+
+ initPorts();
+ CHECK_EQ(initDecoder(), (status_t)OK);
+}
+
+SoftMPEG4::~SoftMPEG4() {
+ if (mInitialized) {
+ PVCleanUpVideoDecoder(mHandle);
+ }
+
+ delete mHandle;
+ mHandle = NULL;
+}
+
+void SoftMPEG4::initPorts() {
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ InitOMXParams(&def);
+
+ def.nPortIndex = 0;
+ def.eDir = OMX_DirInput;
+ def.nBufferCountMin = kNumInputBuffers;
+ def.nBufferCountActual = def.nBufferCountMin;
+ def.nBufferSize = 8192;
+ def.bEnabled = OMX_TRUE;
+ def.bPopulated = OMX_FALSE;
+ def.eDomain = OMX_PortDomainVideo;
+ def.bBuffersContiguous = OMX_FALSE;
+ def.nBufferAlignment = 1;
+
+ def.format.video.cMIMEType =
+ (mMode == MODE_MPEG4)
+ ? const_cast<char *>(MEDIA_MIMETYPE_VIDEO_MPEG4)
+ : const_cast<char *>(MEDIA_MIMETYPE_VIDEO_H263);
+
+ def.format.video.pNativeRender = NULL;
+ def.format.video.nFrameWidth = mWidth;
+ def.format.video.nFrameHeight = mHeight;
+ def.format.video.nStride = def.format.video.nFrameWidth;
+ def.format.video.nSliceHeight = def.format.video.nFrameHeight;
+ def.format.video.nBitrate = 0;
+ def.format.video.xFramerate = 0;
+ def.format.video.bFlagErrorConcealment = OMX_FALSE;
+
+ def.format.video.eCompressionFormat =
+ mMode == MODE_MPEG4 ? OMX_VIDEO_CodingMPEG4 : OMX_VIDEO_CodingH263;
+
+ def.format.video.eColorFormat = OMX_COLOR_FormatUnused;
+ def.format.video.pNativeWindow = NULL;
+
+ addPort(def);
+
+ def.nPortIndex = 1;
+ def.eDir = OMX_DirOutput;
+ def.nBufferCountMin = kNumOutputBuffers;
+ def.nBufferCountActual = def.nBufferCountMin;
+ def.bEnabled = OMX_TRUE;
+ def.bPopulated = OMX_FALSE;
+ def.eDomain = OMX_PortDomainVideo;
+ def.bBuffersContiguous = OMX_FALSE;
+ def.nBufferAlignment = 2;
+
+ def.format.video.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_VIDEO_RAW);
+ def.format.video.pNativeRender = NULL;
+ def.format.video.nFrameWidth = mWidth;
+ def.format.video.nFrameHeight = mHeight;
+ def.format.video.nStride = def.format.video.nFrameWidth;
+ def.format.video.nSliceHeight = def.format.video.nFrameHeight;
+ def.format.video.nBitrate = 0;
+ def.format.video.xFramerate = 0;
+ def.format.video.bFlagErrorConcealment = OMX_FALSE;
+ def.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
+ def.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
+ def.format.video.pNativeWindow = NULL;
+
+ def.nBufferSize =
+ (def.format.video.nFrameWidth * def.format.video.nFrameHeight * 3) / 2;
+
+ addPort(def);
+}
+
+status_t SoftMPEG4::initDecoder() {
+ memset(mHandle, 0, sizeof(tagvideoDecControls));
+ return OK;
+}
+
+OMX_ERRORTYPE SoftMPEG4::internalGetParameter(
+ OMX_INDEXTYPE index, OMX_PTR params) {
+ switch (index) {
+ case OMX_IndexParamVideoPortFormat:
+ {
+ OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams =
+ (OMX_VIDEO_PARAM_PORTFORMATTYPE *)params;
+
+ if (formatParams->nPortIndex > 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ if (formatParams->nIndex != 0) {
+ return OMX_ErrorNoMore;
+ }
+
+ if (formatParams->nPortIndex == 0) {
+ formatParams->eCompressionFormat =
+ (mMode == MODE_MPEG4)
+ ? OMX_VIDEO_CodingMPEG4 : OMX_VIDEO_CodingH263;
+
+ formatParams->eColorFormat = OMX_COLOR_FormatUnused;
+ formatParams->xFramerate = 0;
+ } else {
+ CHECK_EQ(formatParams->nPortIndex, 1u);
+
+ formatParams->eCompressionFormat = OMX_VIDEO_CodingUnused;
+ formatParams->eColorFormat = OMX_COLOR_FormatYUV420Planar;
+ formatParams->xFramerate = 0;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ case OMX_IndexParamVideoProfileLevelQuerySupported:
+ {
+ OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevel =
+ (OMX_VIDEO_PARAM_PROFILELEVELTYPE *) params;
+
+ if (profileLevel->nPortIndex != 0) { // Input port only
+ LOGE("Invalid port index: %ld", profileLevel->nPortIndex);
+ return OMX_ErrorUnsupportedIndex;
+ }
+
+ size_t index = profileLevel->nProfileIndex;
+ if (mMode == MODE_H263) {
+ size_t nProfileLevels =
+ sizeof(kH263ProfileLevels) / sizeof(kH263ProfileLevels[0]);
+ if (index >= nProfileLevels) {
+ return OMX_ErrorNoMore;
+ }
+
+ profileLevel->eProfile = kH263ProfileLevels[index].mProfile;
+ profileLevel->eLevel = kH263ProfileLevels[index].mLevel;
+ } else {
+ size_t nProfileLevels =
+ sizeof(kM4VProfileLevels) / sizeof(kM4VProfileLevels[0]);
+ if (index >= nProfileLevels) {
+ return OMX_ErrorNoMore;
+ }
+
+ profileLevel->eProfile = kM4VProfileLevels[index].mProfile;
+ profileLevel->eLevel = kM4VProfileLevels[index].mLevel;
+ }
+ return OMX_ErrorNone;
+ }
+
+ default:
+ return SimpleSoftOMXComponent::internalGetParameter(index, params);
+ }
+}
+
+OMX_ERRORTYPE SoftMPEG4::internalSetParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params) {
+ switch (index) {
+ case OMX_IndexParamStandardComponentRole:
+ {
+ const OMX_PARAM_COMPONENTROLETYPE *roleParams =
+ (const OMX_PARAM_COMPONENTROLETYPE *)params;
+
+ if (mMode == MODE_MPEG4) {
+ if (strncmp((const char *)roleParams->cRole,
+ "video_decoder.mpeg4",
+ OMX_MAX_STRINGNAME_SIZE - 1)) {
+ return OMX_ErrorUndefined;
+ }
+ } else {
+ if (strncmp((const char *)roleParams->cRole,
+ "video_decoder.h263",
+ OMX_MAX_STRINGNAME_SIZE - 1)) {
+ return OMX_ErrorUndefined;
+ }
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ case OMX_IndexParamVideoPortFormat:
+ {
+ OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams =
+ (OMX_VIDEO_PARAM_PORTFORMATTYPE *)params;
+
+ if (formatParams->nPortIndex > 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ if (formatParams->nIndex != 0) {
+ return OMX_ErrorNoMore;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ default:
+ return SimpleSoftOMXComponent::internalSetParameter(index, params);
+ }
+}
+
+OMX_ERRORTYPE SoftMPEG4::getConfig(
+ OMX_INDEXTYPE index, OMX_PTR params) {
+ switch (index) {
+ case OMX_IndexConfigCommonOutputCrop:
+ {
+ OMX_CONFIG_RECTTYPE *rectParams = (OMX_CONFIG_RECTTYPE *)params;
+
+ if (rectParams->nPortIndex != 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ rectParams->nLeft = mCropLeft;
+ rectParams->nTop = mCropTop;
+ rectParams->nWidth = mCropRight - mCropLeft + 1;
+ rectParams->nHeight = mCropBottom - mCropTop + 1;
+
+ return OMX_ErrorNone;
+ }
+
+ default:
+ return OMX_ErrorUnsupportedIndex;
+ }
+}
+
+void SoftMPEG4::onQueueFilled(OMX_U32 portIndex) {
+ if (mSignalledError || mOutputPortSettingsChange != NONE) {
+ return;
+ }
+
+ List<BufferInfo *> &inQueue = getPortQueue(0);
+ List<BufferInfo *> &outQueue = getPortQueue(1);
+
+ while (!inQueue.empty() && outQueue.size() == kNumOutputBuffers) {
+ BufferInfo *inInfo = *inQueue.begin();
+ OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
+
+ PortInfo *port = editPortInfo(1);
+
+ OMX_BUFFERHEADERTYPE *outHeader =
+ port->mBuffers.editItemAt(mNumSamplesOutput & 1).mHeader;
+
+ if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
+ inQueue.erase(inQueue.begin());
+ inInfo->mOwnedByUs = false;
+ notifyEmptyBufferDone(inHeader);
+
+ ++mInputBufferCount;
+
+ outHeader->nFilledLen = 0;
+ outHeader->nFlags = OMX_BUFFERFLAG_EOS;
+
+ List<BufferInfo *>::iterator it = outQueue.begin();
+ while ((*it)->mHeader != outHeader) {
+ ++it;
+ }
+
+ BufferInfo *outInfo = *it;
+ outInfo->mOwnedByUs = false;
+ outQueue.erase(it);
+ outInfo = NULL;
+
+ notifyFillBufferDone(outHeader);
+ outHeader = NULL;
+ return;
+ }
+
+ uint8_t *bitstream = inHeader->pBuffer + inHeader->nOffset;
+
+ if (!mInitialized) {
+ uint8_t *vol_data[1];
+ int32_t vol_size = 0;
+
+ vol_data[0] = NULL;
+
+ if (inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
+ vol_data[0] = bitstream;
+ vol_size = inHeader->nFilledLen;
+ }
+
+ MP4DecodingMode mode =
+ (mMode == MODE_MPEG4) ? MPEG4_MODE : H263_MODE;
+
+ Bool success = PVInitVideoDecoder(
+ mHandle, vol_data, &vol_size, 1, mWidth, mHeight, mode);
+
+ if (!success) {
+ LOGW("PVInitVideoDecoder failed. Unsupported content?");
+
+ notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+ mSignalledError = true;
+ return;
+ }
+
+ MP4DecodingMode actualMode = PVGetDecBitstreamMode(mHandle);
+ if (mode != actualMode) {
+ notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+ mSignalledError = true;
+ return;
+ }
+
+ PVSetPostProcType((VideoDecControls *) mHandle, 0);
+
+ if (inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
+ inInfo->mOwnedByUs = false;
+ inQueue.erase(inQueue.begin());
+ inInfo = NULL;
+ notifyEmptyBufferDone(inHeader);
+ inHeader = NULL;
+ }
+
+ mInitialized = true;
+
+ if (mode == MPEG4_MODE && portSettingsChanged()) {
+ return;
+ }
+
+ continue;
+ }
+
+ if (!mFramesConfigured) {
+ PortInfo *port = editPortInfo(1);
+ OMX_BUFFERHEADERTYPE *outHeader = port->mBuffers.editItemAt(1).mHeader;
+
+ PVSetReferenceYUV(mHandle, outHeader->pBuffer);
+
+ mFramesConfigured = true;
+ }
+
+ uint32_t useExtTimestamp = (inHeader->nOffset == 0);
+
+ // decoder deals in ms, OMX in us.
+ uint32_t timestamp =
+ useExtTimestamp ? (inHeader->nTimeStamp + 500) / 1000 : 0xFFFFFFFF;
+
+ int32_t bufferSize = inHeader->nFilledLen;
+
+ if (PVDecodeVideoFrame(
+ mHandle, &bitstream, ×tamp, &bufferSize,
+ &useExtTimestamp,
+ outHeader->pBuffer) != PV_TRUE) {
+ LOGE("failed to decode video frame.");
+
+ notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+ mSignalledError = true;
+ return;
+ }
+
+ if (portSettingsChanged()) {
+ return;
+ }
+
+ // decoder deals in ms, OMX in us.
+ outHeader->nTimeStamp = timestamp * 1000;
+
+ CHECK_LE(bufferSize, inHeader->nFilledLen);
+ inHeader->nOffset += inHeader->nFilledLen - bufferSize;
+ inHeader->nFilledLen = bufferSize;
+
+ if (inHeader->nFilledLen == 0) {
+ inInfo->mOwnedByUs = false;
+ inQueue.erase(inQueue.begin());
+ inInfo = NULL;
+ notifyEmptyBufferDone(inHeader);
+ inHeader = NULL;
+ }
+
+ ++mInputBufferCount;
+
+ outHeader->nOffset = 0;
+ outHeader->nFilledLen = (mWidth * mHeight * 3) / 2;
+ outHeader->nFlags = 0;
+
+ List<BufferInfo *>::iterator it = outQueue.begin();
+ while ((*it)->mHeader != outHeader) {
+ ++it;
+ }
+
+ BufferInfo *outInfo = *it;
+ outInfo->mOwnedByUs = false;
+ outQueue.erase(it);
+ outInfo = NULL;
+
+ notifyFillBufferDone(outHeader);
+ outHeader = NULL;
+
+ ++mNumSamplesOutput;
+ }
+}
+
+bool SoftMPEG4::portSettingsChanged() {
+ int32_t disp_width, disp_height;
+ PVGetVideoDimensions(mHandle, &disp_width, &disp_height);
+
+ int32_t buf_width, buf_height;
+ PVGetBufferDimensions(mHandle, &buf_width, &buf_height);
+
+ CHECK_LE(disp_width, buf_width);
+ CHECK_LE(disp_height, buf_height);
+
+ LOGV("disp_width = %d, disp_height = %d, buf_width = %d, buf_height = %d",
+ disp_width, disp_height, buf_width, buf_height);
+
+ if (mCropRight != disp_width - 1
+ || mCropBottom != disp_height - 1) {
+ mCropLeft = 0;
+ mCropTop = 0;
+ mCropRight = disp_width - 1;
+ mCropBottom = disp_height - 1;
+
+ notify(OMX_EventPortSettingsChanged,
+ 1,
+ OMX_IndexConfigCommonOutputCrop,
+ NULL);
+ }
+
+ if (buf_width != mWidth || buf_height != mHeight) {
+ mWidth = buf_width;
+ mHeight = buf_height;
+
+ updatePortDefinitions();
+
+ if (mMode == MODE_H263) {
+ PVCleanUpVideoDecoder(mHandle);
+
+ uint8_t *vol_data[1];
+ int32_t vol_size = 0;
+
+ vol_data[0] = NULL;
+ if (!PVInitVideoDecoder(
+ mHandle, vol_data, &vol_size, 1, mWidth, mHeight,
+ H263_MODE)) {
+ notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+ mSignalledError = true;
+ return true;
+ }
+ }
+
+ mFramesConfigured = false;
+
+ notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
+ mOutputPortSettingsChange = AWAITING_DISABLED;
+ return true;
+ }
+
+ return false;
+}
+
+void SoftMPEG4::onPortFlushCompleted(OMX_U32 portIndex) {
+ if (portIndex == 0 && mInitialized) {
+ CHECK_EQ((int)PVResetVideoDecoder(mHandle), (int)PV_TRUE);
+ }
+}
+
+void SoftMPEG4::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
+ if (portIndex != 1) {
+ return;
+ }
+
+ switch (mOutputPortSettingsChange) {
+ case NONE:
+ break;
+
+ case AWAITING_DISABLED:
+ {
+ CHECK(!enabled);
+ mOutputPortSettingsChange = AWAITING_ENABLED;
+ break;
+ }
+
+ default:
+ {
+ CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED);
+ CHECK(enabled);
+ mOutputPortSettingsChange = NONE;
+ break;
+ }
+ }
+}
+
+void SoftMPEG4::updatePortDefinitions() {
+ OMX_PARAM_PORTDEFINITIONTYPE *def = &editPortInfo(0)->mDef;
+ def->format.video.nFrameWidth = mWidth;
+ def->format.video.nFrameHeight = mHeight;
+ def->format.video.nStride = def->format.video.nFrameWidth;
+ def->format.video.nSliceHeight = def->format.video.nFrameHeight;
+
+ def = &editPortInfo(1)->mDef;
+ def->format.video.nFrameWidth = mWidth;
+ def->format.video.nFrameHeight = mHeight;
+ def->format.video.nStride = def->format.video.nFrameWidth;
+ def->format.video.nSliceHeight = def->format.video.nFrameHeight;
+
+ def->nBufferSize =
+ (((def->format.video.nFrameWidth + 15) & -16)
+ * ((def->format.video.nFrameHeight + 15) & -16) * 3) / 2;
+}
+
+} // namespace android
+
+android::SoftOMXComponent *createSoftOMXComponent(
+ const char *name, const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData, OMX_COMPONENTTYPE **component) {
+ return new android::SoftMPEG4(name, callbacks, appData, component);
+}
+
diff --git a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.h b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.h
new file mode 100644
index 0000000..dff08a7
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2011 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 SOFT_MPEG4_H_
+
+#define SOFT_MPEG4_H_
+
+#include "SimpleSoftOMXComponent.h"
+
+struct tagvideoDecControls;
+
+namespace android {
+
+struct SoftMPEG4 : public SimpleSoftOMXComponent {
+ SoftMPEG4(const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component);
+
+protected:
+ virtual ~SoftMPEG4();
+
+ virtual OMX_ERRORTYPE internalGetParameter(
+ OMX_INDEXTYPE index, OMX_PTR params);
+
+ virtual OMX_ERRORTYPE internalSetParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params);
+
+ virtual OMX_ERRORTYPE getConfig(OMX_INDEXTYPE index, OMX_PTR params);
+
+ virtual void onQueueFilled(OMX_U32 portIndex);
+ virtual void onPortFlushCompleted(OMX_U32 portIndex);
+ virtual void onPortEnableCompleted(OMX_U32 portIndex, bool enabled);
+
+private:
+ enum {
+ kNumInputBuffers = 4,
+ kNumOutputBuffers = 2,
+ };
+
+ enum {
+ MODE_MPEG4,
+ MODE_H263,
+
+ } mMode;
+
+ tagvideoDecControls *mHandle;
+
+ size_t mInputBufferCount;
+
+ int32_t mWidth, mHeight;
+ int32_t mCropLeft, mCropTop, mCropRight, mCropBottom;
+
+ bool mSignalledError;
+ bool mInitialized;
+ bool mFramesConfigured;
+
+ int32_t mNumSamplesOutput;
+
+ enum {
+ NONE,
+ AWAITING_DISABLED,
+ AWAITING_ENABLED
+ } mOutputPortSettingsChange;
+
+ void initPorts();
+ status_t initDecoder();
+
+ void updatePortDefinitions();
+ bool portSettingsChanged();
+
+ DISALLOW_EVIL_CONSTRUCTORS(SoftMPEG4);
+};
+
+} // namespace android
+
+#endif // SOFT_MPEG4_H_
+
+
diff --git a/media/libstagefright/codecs/m4v_h263/enc/M4vH263Encoder.cpp b/media/libstagefright/codecs/m4v_h263/enc/M4vH263Encoder.cpp
index 15ed219..d7249c1 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/M4vH263Encoder.cpp
+++ b/media/libstagefright/codecs/m4v_h263/enc/M4vH263Encoder.cpp
@@ -398,10 +398,13 @@
}
// Ready for accepting an input video frame
- if (OK != mSource->read(&mInputBuffer, options)) {
- LOGE("Failed to read from data source");
+ status_t err = mSource->read(&mInputBuffer, options);
+ if (OK != err) {
+ if (err != ERROR_END_OF_STREAM) {
+ LOGE("Failed to read from data source");
+ }
outputBuffer->release();
- return UNKNOWN_ERROR;
+ return err;
}
if (mInputBuffer->size() - ((mVideoWidth * mVideoHeight * 3) >> 1) != 0) {
diff --git a/media/libstagefright/codecs/mp3dec/Android.mk b/media/libstagefright/codecs/mp3dec/Android.mk
index 753500e..a08c9f0 100644
--- a/media/libstagefright/codecs/mp3dec/Android.mk
+++ b/media/libstagefright/codecs/mp3dec/Android.mk
@@ -2,7 +2,6 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
- MP3Decoder.cpp \
src/pvmp3_normalize.cpp \
src/pvmp3_alias_reduction.cpp \
src/pvmp3_crc.cpp \
@@ -57,3 +56,26 @@
include $(BUILD_STATIC_LIBRARY)
+################################################################################
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ SoftMP3.cpp
+
+LOCAL_C_INCLUDES := \
+ frameworks/base/media/libstagefright/include \
+ frameworks/base/include/media/stagefright/openmax \
+ $(LOCAL_PATH)/src \
+ $(LOCAL_PATH)/include
+
+LOCAL_SHARED_LIBRARIES := \
+ libstagefright libstagefright_omx libstagefright_foundation libutils
+
+LOCAL_STATIC_LIBRARIES := \
+ libstagefright_mp3dec
+
+LOCAL_MODULE := libstagefright_soft_mp3dec
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libstagefright/codecs/mp3dec/MP3Decoder.cpp b/media/libstagefright/codecs/mp3dec/MP3Decoder.cpp
deleted file mode 100644
index 59dd740..0000000
--- a/media/libstagefright/codecs/mp3dec/MP3Decoder.cpp
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * 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.
- */
-
-#include "MP3Decoder.h"
-
-#include "include/pvmp3decoder_api.h"
-
-#include <media/stagefright/MediaBufferGroup.h>
-#include <media/stagefright/MediaDebug.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MetaData.h>
-
-namespace android {
-
-MP3Decoder::MP3Decoder(const sp<MediaSource> &source)
- : mSource(source),
- mNumChannels(0),
- mStarted(false),
- mBufferGroup(NULL),
- mConfig(new tPVMP3DecoderExternal),
- mDecoderBuf(NULL),
- mAnchorTimeUs(0),
- mNumFramesOutput(0),
- mInputBuffer(NULL) {
- init();
-}
-
-void MP3Decoder::init() {
- sp<MetaData> srcFormat = mSource->getFormat();
-
- int32_t sampleRate;
- CHECK(srcFormat->findInt32(kKeyChannelCount, &mNumChannels));
- CHECK(srcFormat->findInt32(kKeySampleRate, &sampleRate));
-
- mMeta = new MetaData;
- mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
- mMeta->setInt32(kKeyChannelCount, mNumChannels);
- mMeta->setInt32(kKeySampleRate, sampleRate);
-
- int64_t durationUs;
- if (srcFormat->findInt64(kKeyDuration, &durationUs)) {
- mMeta->setInt64(kKeyDuration, durationUs);
- }
-
- mMeta->setCString(kKeyDecoderComponent, "MP3Decoder");
-}
-
-MP3Decoder::~MP3Decoder() {
- if (mStarted) {
- stop();
- }
-
- delete mConfig;
- mConfig = NULL;
-}
-
-status_t MP3Decoder::start(MetaData *params) {
- CHECK(!mStarted);
-
- mBufferGroup = new MediaBufferGroup;
- mBufferGroup->add_buffer(new MediaBuffer(4608 * 2));
-
- mConfig->equalizerType = flat;
- mConfig->crcEnabled = false;
-
- uint32_t memRequirements = pvmp3_decoderMemRequirements();
- mDecoderBuf = malloc(memRequirements);
-
- pvmp3_InitDecoder(mConfig, mDecoderBuf);
-
- mSource->start();
-
- mAnchorTimeUs = 0;
- mNumFramesOutput = 0;
- mStarted = true;
-
- return OK;
-}
-
-status_t MP3Decoder::stop() {
- CHECK(mStarted);
-
- if (mInputBuffer) {
- mInputBuffer->release();
- mInputBuffer = NULL;
- }
-
- free(mDecoderBuf);
- mDecoderBuf = NULL;
-
- delete mBufferGroup;
- mBufferGroup = NULL;
-
- mSource->stop();
-
- mStarted = false;
-
- return OK;
-}
-
-sp<MetaData> MP3Decoder::getFormat() {
- return mMeta;
-}
-
-status_t MP3Decoder::read(
- MediaBuffer **out, const ReadOptions *options) {
- status_t err;
-
- *out = NULL;
-
- int64_t seekTimeUs;
- ReadOptions::SeekMode mode;
- if (options && options->getSeekTo(&seekTimeUs, &mode)) {
- CHECK(seekTimeUs >= 0);
-
- mNumFramesOutput = 0;
-
- if (mInputBuffer) {
- mInputBuffer->release();
- mInputBuffer = NULL;
- }
-
- // Make sure that the next buffer output does not still
- // depend on fragments from the last one decoded.
- pvmp3_InitDecoder(mConfig, mDecoderBuf);
- } else {
- seekTimeUs = -1;
- }
-
- if (mInputBuffer == NULL) {
- err = mSource->read(&mInputBuffer, options);
-
- if (err != OK) {
- return err;
- }
-
- int64_t timeUs;
- if (mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) {
- mAnchorTimeUs = timeUs;
- mNumFramesOutput = 0;
- } else {
- // We must have a new timestamp after seeking.
- CHECK(seekTimeUs < 0);
- }
- }
-
- MediaBuffer *buffer;
- CHECK_EQ(mBufferGroup->acquire_buffer(&buffer), OK);
-
- mConfig->pInputBuffer =
- (uint8_t *)mInputBuffer->data() + mInputBuffer->range_offset();
-
- mConfig->inputBufferCurrentLength = mInputBuffer->range_length();
- mConfig->inputBufferMaxLength = 0;
- mConfig->inputBufferUsedLength = 0;
-
- mConfig->outputFrameSize = buffer->size() / sizeof(int16_t);
- mConfig->pOutputBuffer = static_cast<int16_t *>(buffer->data());
-
- ERROR_CODE decoderErr;
- if ((decoderErr = pvmp3_framedecoder(mConfig, mDecoderBuf))
- != NO_DECODING_ERROR) {
- LOGV("mp3 decoder returned error %d", decoderErr);
-
- if (decoderErr != NO_ENOUGH_MAIN_DATA_ERROR) {
- buffer->release();
- buffer = NULL;
-
- mInputBuffer->release();
- mInputBuffer = NULL;
-
- return UNKNOWN_ERROR;
- }
-
- // This is recoverable, just ignore the current frame and
- // play silence instead.
- memset(buffer->data(), 0, mConfig->outputFrameSize * sizeof(int16_t));
- mConfig->inputBufferUsedLength = mInputBuffer->range_length();
- }
-
- buffer->set_range(
- 0, mConfig->outputFrameSize * sizeof(int16_t));
-
- mInputBuffer->set_range(
- mInputBuffer->range_offset() + mConfig->inputBufferUsedLength,
- mInputBuffer->range_length() - mConfig->inputBufferUsedLength);
-
- if (mInputBuffer->range_length() == 0) {
- mInputBuffer->release();
- mInputBuffer = NULL;
- }
-
- buffer->meta_data()->setInt64(
- kKeyTime,
- mAnchorTimeUs
- + (mNumFramesOutput * 1000000) / mConfig->samplingRate);
-
- mNumFramesOutput += mConfig->outputFrameSize / mNumChannels;
-
- *out = buffer;
-
- return OK;
-}
-
-} // namespace android
diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
new file mode 100644
index 0000000..066c88e
--- /dev/null
+++ b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2011 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 "SoftMP3"
+#include <utils/Log.h>
+
+#include "SoftMP3.h"
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/MediaDefs.h>
+
+#include "include/pvmp3decoder_api.h"
+
+namespace android {
+
+template<class T>
+static void InitOMXParams(T *params) {
+ params->nSize = sizeof(T);
+ params->nVersion.s.nVersionMajor = 1;
+ params->nVersion.s.nVersionMinor = 0;
+ params->nVersion.s.nRevision = 0;
+ params->nVersion.s.nStep = 0;
+}
+
+SoftMP3::SoftMP3(
+ const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component)
+ : SimpleSoftOMXComponent(name, callbacks, appData, component),
+ mConfig(new tPVMP3DecoderExternal),
+ mDecoderBuf(NULL),
+ mAnchorTimeUs(0),
+ mNumFramesOutput(0),
+ mNumChannels(2),
+ mSamplingRate(44100),
+ mSignalledError(false),
+ mOutputPortSettingsChange(NONE) {
+ initPorts();
+ initDecoder();
+}
+
+SoftMP3::~SoftMP3() {
+ if (mDecoderBuf != NULL) {
+ free(mDecoderBuf);
+ mDecoderBuf = NULL;
+ }
+
+ delete mConfig;
+ mConfig = NULL;
+}
+
+void SoftMP3::initPorts() {
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ InitOMXParams(&def);
+
+ def.nPortIndex = 0;
+ def.eDir = OMX_DirInput;
+ def.nBufferCountMin = kNumBuffers;
+ def.nBufferCountActual = def.nBufferCountMin;
+ def.nBufferSize = 8192;
+ def.bEnabled = OMX_TRUE;
+ def.bPopulated = OMX_FALSE;
+ def.eDomain = OMX_PortDomainAudio;
+ def.bBuffersContiguous = OMX_FALSE;
+ def.nBufferAlignment = 1;
+
+ def.format.audio.cMIMEType =
+ const_cast<char *>(MEDIA_MIMETYPE_AUDIO_MPEG);
+
+ def.format.audio.pNativeRender = NULL;
+ def.format.audio.bFlagErrorConcealment = OMX_FALSE;
+ def.format.audio.eEncoding = OMX_AUDIO_CodingMP3;
+
+ addPort(def);
+
+ def.nPortIndex = 1;
+ def.eDir = OMX_DirOutput;
+ def.nBufferCountMin = kNumBuffers;
+ def.nBufferCountActual = def.nBufferCountMin;
+ def.nBufferSize = kOutputBufferSize;
+ def.bEnabled = OMX_TRUE;
+ def.bPopulated = OMX_FALSE;
+ def.eDomain = OMX_PortDomainAudio;
+ def.bBuffersContiguous = OMX_FALSE;
+ def.nBufferAlignment = 2;
+
+ def.format.audio.cMIMEType = const_cast<char *>("audio/raw");
+ def.format.audio.pNativeRender = NULL;
+ def.format.audio.bFlagErrorConcealment = OMX_FALSE;
+ def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
+
+ addPort(def);
+}
+
+void SoftMP3::initDecoder() {
+ mConfig->equalizerType = flat;
+ mConfig->crcEnabled = false;
+
+ uint32_t memRequirements = pvmp3_decoderMemRequirements();
+ mDecoderBuf = malloc(memRequirements);
+
+ pvmp3_InitDecoder(mConfig, mDecoderBuf);
+}
+
+OMX_ERRORTYPE SoftMP3::internalGetParameter(
+ OMX_INDEXTYPE index, OMX_PTR params) {
+ switch (index) {
+ case OMX_IndexParamAudioPcm:
+ {
+ OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
+ (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
+
+ if (pcmParams->nPortIndex > 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ pcmParams->eNumData = OMX_NumericalDataSigned;
+ pcmParams->eEndian = OMX_EndianBig;
+ pcmParams->bInterleaved = OMX_TRUE;
+ pcmParams->nBitPerSample = 16;
+ pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
+ pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
+ pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
+
+ pcmParams->nChannels = mNumChannels;
+ pcmParams->nSamplingRate = mSamplingRate;
+
+ return OMX_ErrorNone;
+ }
+
+ default:
+ return SimpleSoftOMXComponent::internalGetParameter(index, params);
+ }
+}
+
+OMX_ERRORTYPE SoftMP3::internalSetParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params) {
+ switch (index) {
+ case OMX_IndexParamStandardComponentRole:
+ {
+ const OMX_PARAM_COMPONENTROLETYPE *roleParams =
+ (const OMX_PARAM_COMPONENTROLETYPE *)params;
+
+ if (strncmp((const char *)roleParams->cRole,
+ "audio_decoder.mp3",
+ OMX_MAX_STRINGNAME_SIZE - 1)) {
+ return OMX_ErrorUndefined;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ default:
+ return SimpleSoftOMXComponent::internalSetParameter(index, params);
+ }
+}
+
+void SoftMP3::onQueueFilled(OMX_U32 portIndex) {
+ if (mSignalledError || mOutputPortSettingsChange != NONE) {
+ return;
+ }
+
+ List<BufferInfo *> &inQueue = getPortQueue(0);
+ List<BufferInfo *> &outQueue = getPortQueue(1);
+
+ while (!inQueue.empty() && !outQueue.empty()) {
+ BufferInfo *inInfo = *inQueue.begin();
+ OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
+
+ BufferInfo *outInfo = *outQueue.begin();
+ OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
+
+ if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
+ inQueue.erase(inQueue.begin());
+ inInfo->mOwnedByUs = false;
+ notifyEmptyBufferDone(inHeader);
+
+ outHeader->nFilledLen = 0;
+ outHeader->nFlags = OMX_BUFFERFLAG_EOS;
+
+ outQueue.erase(outQueue.begin());
+ outInfo->mOwnedByUs = false;
+ notifyFillBufferDone(outHeader);
+ return;
+ }
+
+ if (inHeader->nOffset == 0) {
+ mAnchorTimeUs = inHeader->nTimeStamp;
+ mNumFramesOutput = 0;
+ }
+
+ mConfig->pInputBuffer =
+ inHeader->pBuffer + inHeader->nOffset;
+
+ mConfig->inputBufferCurrentLength = inHeader->nFilledLen;
+ mConfig->inputBufferMaxLength = 0;
+ mConfig->inputBufferUsedLength = 0;
+
+ mConfig->outputFrameSize = kOutputBufferSize / sizeof(int16_t);
+
+ mConfig->pOutputBuffer =
+ reinterpret_cast<int16_t *>(outHeader->pBuffer);
+
+ ERROR_CODE decoderErr;
+ if ((decoderErr = pvmp3_framedecoder(mConfig, mDecoderBuf))
+ != NO_DECODING_ERROR) {
+ LOGV("mp3 decoder returned error %d", decoderErr);
+
+ if (decoderErr != NO_ENOUGH_MAIN_DATA_ERROR ||
+ mConfig->outputFrameSize == 0) {
+ LOGE("mp3 decoder returned error %d", decoderErr);
+
+ if (mConfig->outputFrameSize == 0) {
+ LOGE("Output frame size is 0");
+ }
+
+ notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
+ mSignalledError = true;
+ return;
+ }
+
+ // This is recoverable, just ignore the current frame and
+ // play silence instead.
+ memset(outHeader->pBuffer,
+ 0,
+ mConfig->outputFrameSize * sizeof(int16_t));
+
+ mConfig->inputBufferUsedLength = inHeader->nFilledLen;
+ } else if (mConfig->samplingRate != mSamplingRate
+ || mConfig->num_channels != mNumChannels) {
+ mSamplingRate = mConfig->samplingRate;
+ mNumChannels = mConfig->num_channels;
+
+ notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
+ mOutputPortSettingsChange = AWAITING_DISABLED;
+ return;
+ }
+
+ outHeader->nOffset = 0;
+ outHeader->nFilledLen = mConfig->outputFrameSize * sizeof(int16_t);
+
+ outHeader->nTimeStamp =
+ mAnchorTimeUs
+ + (mNumFramesOutput * 1000000ll) / mConfig->samplingRate;
+
+ outHeader->nFlags = 0;
+
+ CHECK_GE(inHeader->nFilledLen, mConfig->inputBufferUsedLength);
+
+ inHeader->nOffset += mConfig->inputBufferUsedLength;
+ inHeader->nFilledLen -= mConfig->inputBufferUsedLength;
+
+ mNumFramesOutput += mConfig->outputFrameSize / mNumChannels;
+
+ if (inHeader->nFilledLen == 0) {
+ inInfo->mOwnedByUs = false;
+ inQueue.erase(inQueue.begin());
+ inInfo = NULL;
+ notifyEmptyBufferDone(inHeader);
+ inHeader = NULL;
+ }
+
+ outInfo->mOwnedByUs = false;
+ outQueue.erase(outQueue.begin());
+ outInfo = NULL;
+ notifyFillBufferDone(outHeader);
+ outHeader = NULL;
+ }
+}
+
+void SoftMP3::onPortFlushCompleted(OMX_U32 portIndex) {
+ if (portIndex == 0) {
+ // Make sure that the next buffer output does not still
+ // depend on fragments from the last one decoded.
+ pvmp3_InitDecoder(mConfig, mDecoderBuf);
+ }
+}
+
+void SoftMP3::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
+ if (portIndex != 1) {
+ return;
+ }
+
+ switch (mOutputPortSettingsChange) {
+ case NONE:
+ break;
+
+ case AWAITING_DISABLED:
+ {
+ CHECK(!enabled);
+ mOutputPortSettingsChange = AWAITING_ENABLED;
+ break;
+ }
+
+ default:
+ {
+ CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED);
+ CHECK(enabled);
+ mOutputPortSettingsChange = NONE;
+ break;
+ }
+ }
+}
+
+} // namespace android
+
+android::SoftOMXComponent *createSoftOMXComponent(
+ const char *name, const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData, OMX_COMPONENTTYPE **component) {
+ return new android::SoftMP3(name, callbacks, appData, component);
+}
diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.h b/media/libstagefright/codecs/mp3dec/SoftMP3.h
new file mode 100644
index 0000000..70d0682
--- /dev/null
+++ b/media/libstagefright/codecs/mp3dec/SoftMP3.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2011 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 SOFT_MP3_H_
+
+#define SOFT_MP3_H_
+
+#include "SimpleSoftOMXComponent.h"
+
+struct tPVMP3DecoderExternal;
+
+namespace android {
+
+struct SoftMP3 : public SimpleSoftOMXComponent {
+ SoftMP3(const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component);
+
+protected:
+ virtual ~SoftMP3();
+
+ virtual OMX_ERRORTYPE internalGetParameter(
+ OMX_INDEXTYPE index, OMX_PTR params);
+
+ virtual OMX_ERRORTYPE internalSetParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params);
+
+ virtual void onQueueFilled(OMX_U32 portIndex);
+ virtual void onPortFlushCompleted(OMX_U32 portIndex);
+ virtual void onPortEnableCompleted(OMX_U32 portIndex, bool enabled);
+
+private:
+ enum {
+ kNumBuffers = 4,
+ kOutputBufferSize = 4608 * 2
+ };
+
+ tPVMP3DecoderExternal *mConfig;
+ void *mDecoderBuf;
+ int64_t mAnchorTimeUs;
+ int64_t mNumFramesOutput;
+
+ int32_t mNumChannels;
+ int32_t mSamplingRate;
+
+ bool mConfigured;
+
+ bool mSignalledError;
+
+ enum {
+ NONE,
+ AWAITING_DISABLED,
+ AWAITING_ENABLED
+ } mOutputPortSettingsChange;
+
+ void initPorts();
+ void initDecoder();
+
+ DISALLOW_EVIL_CONSTRUCTORS(SoftMP3);
+};
+
+} // namespace android
+
+#endif // SOFT_MP3_H_
+
+
diff --git a/media/libstagefright/codecs/on2/dec/Android.mk b/media/libstagefright/codecs/on2/dec/Android.mk
index b769f0d..32bbd6b 100644
--- a/media/libstagefright/codecs/on2/dec/Android.mk
+++ b/media/libstagefright/codecs/on2/dec/Android.mk
@@ -2,15 +2,23 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
- VPXDecoder.cpp
-
-LOCAL_MODULE := libstagefright_vpxdec
+ SoftVPX.cpp
LOCAL_C_INCLUDES := \
- $(TOP)/frameworks/base/media/libstagefright/include \
- $(TOP)/frameworks/base/include/media/stagefright/openmax \
$(TOP)/external/libvpx \
$(TOP)/external/libvpx/vpx_codec \
- $(TOP)/external/libvpx/vpx_ports
+ $(TOP)/external/libvpx/vpx_ports \
+ frameworks/base/media/libstagefright/include \
+ frameworks/base/include/media/stagefright/openmax \
-include $(BUILD_STATIC_LIBRARY)
+LOCAL_STATIC_LIBRARIES := \
+ libvpx
+
+LOCAL_SHARED_LIBRARIES := \
+ libstagefright libstagefright_omx libstagefright_foundation libutils
+
+LOCAL_MODULE := libstagefright_soft_vpxdec
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_SHARED_LIBRARY)
+
diff --git a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp
new file mode 100644
index 0000000..7e83163
--- /dev/null
+++ b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp
@@ -0,0 +1,382 @@
+/*
+ * Copyright (C) 2011 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 "SoftVPX"
+#include <utils/Log.h>
+
+#include "SoftVPX.h"
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/MediaDefs.h>
+
+#include "vpx/vpx_decoder.h"
+#include "vpx/vpx_codec.h"
+#include "vpx/vp8dx.h"
+
+namespace android {
+
+template<class T>
+static void InitOMXParams(T *params) {
+ params->nSize = sizeof(T);
+ params->nVersion.s.nVersionMajor = 1;
+ params->nVersion.s.nVersionMinor = 0;
+ params->nVersion.s.nRevision = 0;
+ params->nVersion.s.nStep = 0;
+}
+
+SoftVPX::SoftVPX(
+ const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component)
+ : SimpleSoftOMXComponent(name, callbacks, appData, component),
+ mCtx(NULL),
+ mWidth(320),
+ mHeight(240),
+ mOutputPortSettingsChange(NONE) {
+ initPorts();
+ CHECK_EQ(initDecoder(), (status_t)OK);
+}
+
+SoftVPX::~SoftVPX() {
+ vpx_codec_destroy((vpx_codec_ctx_t *)mCtx);
+ delete (vpx_codec_ctx_t *)mCtx;
+ mCtx = NULL;
+}
+
+void SoftVPX::initPorts() {
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ InitOMXParams(&def);
+
+ def.nPortIndex = 0;
+ def.eDir = OMX_DirInput;
+ def.nBufferCountMin = kNumBuffers;
+ def.nBufferCountActual = def.nBufferCountMin;
+ def.nBufferSize = 8192;
+ def.bEnabled = OMX_TRUE;
+ def.bPopulated = OMX_FALSE;
+ def.eDomain = OMX_PortDomainVideo;
+ def.bBuffersContiguous = OMX_FALSE;
+ def.nBufferAlignment = 1;
+
+ def.format.video.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_VIDEO_VPX);
+ def.format.video.pNativeRender = NULL;
+ def.format.video.nFrameWidth = mWidth;
+ def.format.video.nFrameHeight = mHeight;
+ def.format.video.nStride = def.format.video.nFrameWidth;
+ def.format.video.nSliceHeight = def.format.video.nFrameHeight;
+ def.format.video.nBitrate = 0;
+ def.format.video.xFramerate = 0;
+ def.format.video.bFlagErrorConcealment = OMX_FALSE;
+ def.format.video.eCompressionFormat = OMX_VIDEO_CodingVPX;
+ def.format.video.eColorFormat = OMX_COLOR_FormatUnused;
+ def.format.video.pNativeWindow = NULL;
+
+ addPort(def);
+
+ def.nPortIndex = 1;
+ def.eDir = OMX_DirOutput;
+ def.nBufferCountMin = kNumBuffers;
+ def.nBufferCountActual = def.nBufferCountMin;
+ def.bEnabled = OMX_TRUE;
+ def.bPopulated = OMX_FALSE;
+ def.eDomain = OMX_PortDomainVideo;
+ def.bBuffersContiguous = OMX_FALSE;
+ def.nBufferAlignment = 2;
+
+ def.format.video.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_VIDEO_RAW);
+ def.format.video.pNativeRender = NULL;
+ def.format.video.nFrameWidth = mWidth;
+ def.format.video.nFrameHeight = mHeight;
+ def.format.video.nStride = def.format.video.nFrameWidth;
+ def.format.video.nSliceHeight = def.format.video.nFrameHeight;
+ def.format.video.nBitrate = 0;
+ def.format.video.xFramerate = 0;
+ def.format.video.bFlagErrorConcealment = OMX_FALSE;
+ def.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
+ def.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
+ def.format.video.pNativeWindow = NULL;
+
+ def.nBufferSize =
+ (def.format.video.nFrameWidth * def.format.video.nFrameHeight * 3) / 2;
+
+ addPort(def);
+}
+
+static int GetCPUCoreCount() {
+ int cpuCoreCount = 1;
+#if defined(_SC_NPROCESSORS_ONLN)
+ cpuCoreCount = sysconf(_SC_NPROCESSORS_ONLN);
+#else
+ // _SC_NPROC_ONLN must be defined...
+ cpuCoreCount = sysconf(_SC_NPROC_ONLN);
+#endif
+ CHECK(cpuCoreCount >= 1);
+ LOGV("Number of CPU cores: %d", cpuCoreCount);
+ return cpuCoreCount;
+}
+
+status_t SoftVPX::initDecoder() {
+ mCtx = new vpx_codec_ctx_t;
+ vpx_codec_err_t vpx_err;
+ vpx_codec_dec_cfg_t cfg;
+ memset(&cfg, 0, sizeof(vpx_codec_dec_cfg_t));
+ cfg.threads = GetCPUCoreCount();
+ if ((vpx_err = vpx_codec_dec_init(
+ (vpx_codec_ctx_t *)mCtx, &vpx_codec_vp8_dx_algo, &cfg, 0))) {
+ LOGE("on2 decoder failed to initialize. (%d)", vpx_err);
+ return UNKNOWN_ERROR;
+ }
+
+ return OK;
+}
+
+OMX_ERRORTYPE SoftVPX::internalGetParameter(
+ OMX_INDEXTYPE index, OMX_PTR params) {
+ switch (index) {
+ case OMX_IndexParamVideoPortFormat:
+ {
+ OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams =
+ (OMX_VIDEO_PARAM_PORTFORMATTYPE *)params;
+
+ if (formatParams->nPortIndex > 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ if (formatParams->nIndex != 0) {
+ return OMX_ErrorNoMore;
+ }
+
+ if (formatParams->nPortIndex == 0) {
+ formatParams->eCompressionFormat = OMX_VIDEO_CodingVPX;
+ formatParams->eColorFormat = OMX_COLOR_FormatUnused;
+ formatParams->xFramerate = 0;
+ } else {
+ CHECK_EQ(formatParams->nPortIndex, 1u);
+
+ formatParams->eCompressionFormat = OMX_VIDEO_CodingUnused;
+ formatParams->eColorFormat = OMX_COLOR_FormatYUV420Planar;
+ formatParams->xFramerate = 0;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ default:
+ return SimpleSoftOMXComponent::internalGetParameter(index, params);
+ }
+}
+
+OMX_ERRORTYPE SoftVPX::internalSetParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params) {
+ switch (index) {
+ case OMX_IndexParamStandardComponentRole:
+ {
+ const OMX_PARAM_COMPONENTROLETYPE *roleParams =
+ (const OMX_PARAM_COMPONENTROLETYPE *)params;
+
+ if (strncmp((const char *)roleParams->cRole,
+ "video_decoder.vpx",
+ OMX_MAX_STRINGNAME_SIZE - 1)) {
+ return OMX_ErrorUndefined;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ case OMX_IndexParamVideoPortFormat:
+ {
+ OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams =
+ (OMX_VIDEO_PARAM_PORTFORMATTYPE *)params;
+
+ if (formatParams->nPortIndex > 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ if (formatParams->nIndex != 0) {
+ return OMX_ErrorNoMore;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ default:
+ return SimpleSoftOMXComponent::internalSetParameter(index, params);
+ }
+}
+
+void SoftVPX::onQueueFilled(OMX_U32 portIndex) {
+ if (mOutputPortSettingsChange != NONE) {
+ return;
+ }
+
+ List<BufferInfo *> &inQueue = getPortQueue(0);
+ List<BufferInfo *> &outQueue = getPortQueue(1);
+
+ while (!inQueue.empty() && !outQueue.empty()) {
+ BufferInfo *inInfo = *inQueue.begin();
+ OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
+
+ BufferInfo *outInfo = *outQueue.begin();
+ OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
+
+ if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
+ inQueue.erase(inQueue.begin());
+ inInfo->mOwnedByUs = false;
+ notifyEmptyBufferDone(inHeader);
+
+ outHeader->nFilledLen = 0;
+ outHeader->nFlags = OMX_BUFFERFLAG_EOS;
+
+ outQueue.erase(outQueue.begin());
+ outInfo->mOwnedByUs = false;
+ notifyFillBufferDone(outHeader);
+ return;
+ }
+
+ if (vpx_codec_decode(
+ (vpx_codec_ctx_t *)mCtx,
+ inHeader->pBuffer + inHeader->nOffset,
+ inHeader->nFilledLen,
+ NULL,
+ 0)) {
+ LOGE("on2 decoder failed to decode frame.");
+
+ notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+ return;
+ }
+
+ vpx_codec_iter_t iter = NULL;
+ vpx_image_t *img = vpx_codec_get_frame((vpx_codec_ctx_t *)mCtx, &iter);
+
+ if (img != NULL) {
+ CHECK_EQ(img->fmt, IMG_FMT_I420);
+
+ int32_t width = img->d_w;
+ int32_t height = img->d_h;
+
+ if (width != mWidth || height != mHeight) {
+ mWidth = width;
+ mHeight = height;
+
+ updatePortDefinitions();
+
+ notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
+ mOutputPortSettingsChange = AWAITING_DISABLED;
+ return;
+ }
+
+ outHeader->nOffset = 0;
+ outHeader->nFilledLen = (width * height * 3) / 2;
+ outHeader->nFlags = 0;
+ outHeader->nTimeStamp = inHeader->nTimeStamp;
+
+ const uint8_t *srcLine = (const uint8_t *)img->planes[PLANE_Y];
+ uint8_t *dst = outHeader->pBuffer;
+ for (size_t i = 0; i < img->d_h; ++i) {
+ memcpy(dst, srcLine, img->d_w);
+
+ srcLine += img->stride[PLANE_Y];
+ dst += img->d_w;
+ }
+
+ srcLine = (const uint8_t *)img->planes[PLANE_U];
+ for (size_t i = 0; i < img->d_h / 2; ++i) {
+ memcpy(dst, srcLine, img->d_w / 2);
+
+ srcLine += img->stride[PLANE_U];
+ dst += img->d_w / 2;
+ }
+
+ srcLine = (const uint8_t *)img->planes[PLANE_V];
+ for (size_t i = 0; i < img->d_h / 2; ++i) {
+ memcpy(dst, srcLine, img->d_w / 2);
+
+ srcLine += img->stride[PLANE_V];
+ dst += img->d_w / 2;
+ }
+
+ outInfo->mOwnedByUs = false;
+ outQueue.erase(outQueue.begin());
+ outInfo = NULL;
+ notifyFillBufferDone(outHeader);
+ outHeader = NULL;
+ }
+
+ inInfo->mOwnedByUs = false;
+ inQueue.erase(inQueue.begin());
+ inInfo = NULL;
+ notifyEmptyBufferDone(inHeader);
+ inHeader = NULL;
+ }
+}
+
+void SoftVPX::onPortFlushCompleted(OMX_U32 portIndex) {
+}
+
+void SoftVPX::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
+ if (portIndex != 1) {
+ return;
+ }
+
+ switch (mOutputPortSettingsChange) {
+ case NONE:
+ break;
+
+ case AWAITING_DISABLED:
+ {
+ CHECK(!enabled);
+ mOutputPortSettingsChange = AWAITING_ENABLED;
+ break;
+ }
+
+ default:
+ {
+ CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED);
+ CHECK(enabled);
+ mOutputPortSettingsChange = NONE;
+ break;
+ }
+ }
+}
+
+void SoftVPX::updatePortDefinitions() {
+ OMX_PARAM_PORTDEFINITIONTYPE *def = &editPortInfo(0)->mDef;
+ def->format.video.nFrameWidth = mWidth;
+ def->format.video.nFrameHeight = mHeight;
+ def->format.video.nStride = def->format.video.nFrameWidth;
+ def->format.video.nSliceHeight = def->format.video.nFrameHeight;
+
+ def = &editPortInfo(1)->mDef;
+ def->format.video.nFrameWidth = mWidth;
+ def->format.video.nFrameHeight = mHeight;
+ def->format.video.nStride = def->format.video.nFrameWidth;
+ def->format.video.nSliceHeight = def->format.video.nFrameHeight;
+
+ def->nBufferSize =
+ (def->format.video.nFrameWidth
+ * def->format.video.nFrameHeight * 3) / 2;
+}
+
+} // namespace android
+
+android::SoftOMXComponent *createSoftOMXComponent(
+ const char *name, const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData, OMX_COMPONENTTYPE **component) {
+ return new android::SoftVPX(name, callbacks, appData, component);
+}
+
diff --git a/media/libstagefright/codecs/on2/dec/SoftVPX.h b/media/libstagefright/codecs/on2/dec/SoftVPX.h
new file mode 100644
index 0000000..3e814a2
--- /dev/null
+++ b/media/libstagefright/codecs/on2/dec/SoftVPX.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2011 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 SOFT_VPX_H_
+
+#define SOFT_VPX_H_
+
+#include "SimpleSoftOMXComponent.h"
+
+namespace android {
+
+struct SoftVPX : public SimpleSoftOMXComponent {
+ SoftVPX(const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component);
+
+protected:
+ virtual ~SoftVPX();
+
+ virtual OMX_ERRORTYPE internalGetParameter(
+ OMX_INDEXTYPE index, OMX_PTR params);
+
+ virtual OMX_ERRORTYPE internalSetParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params);
+
+ virtual void onQueueFilled(OMX_U32 portIndex);
+ virtual void onPortFlushCompleted(OMX_U32 portIndex);
+ virtual void onPortEnableCompleted(OMX_U32 portIndex, bool enabled);
+
+private:
+ enum {
+ kNumBuffers = 4
+ };
+
+ void *mCtx;
+
+ int32_t mWidth;
+ int32_t mHeight;
+
+ enum {
+ NONE,
+ AWAITING_DISABLED,
+ AWAITING_ENABLED
+ } mOutputPortSettingsChange;
+
+ void initPorts();
+ status_t initDecoder();
+
+ void updatePortDefinitions();
+
+ DISALLOW_EVIL_CONSTRUCTORS(SoftVPX);
+};
+
+} // namespace android
+
+#endif // SOFT_VPX_H_
diff --git a/media/libstagefright/codecs/on2/dec/VPXDecoder.cpp b/media/libstagefright/codecs/on2/dec/VPXDecoder.cpp
deleted file mode 100644
index 489e5ad..0000000
--- a/media/libstagefright/codecs/on2/dec/VPXDecoder.cpp
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * Copyright (C) 2010 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 "VPXDecoder"
-#include <utils/Log.h>
-
-#include "VPXDecoder.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>
-
-#include "vpx/vpx_decoder.h"
-#include "vpx/vpx_codec.h"
-#include "vpx/vp8dx.h"
-
-namespace android {
-
-VPXDecoder::VPXDecoder(const sp<MediaSource> &source)
- : mSource(source),
- mStarted(false),
- mBufferSize(0),
- mCtx(NULL),
- mBufferGroup(NULL),
- mTargetTimeUs(-1) {
- sp<MetaData> inputFormat = source->getFormat();
- const char *mime;
- CHECK(inputFormat->findCString(kKeyMIMEType, &mime));
- CHECK(!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_VPX));
-
- CHECK(inputFormat->findInt32(kKeyWidth, &mWidth));
- CHECK(inputFormat->findInt32(kKeyHeight, &mHeight));
-
- mBufferSize = (mWidth * mHeight * 3) / 2;
-
- mFormat = new MetaData;
- mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
- mFormat->setInt32(kKeyWidth, mWidth);
- mFormat->setInt32(kKeyHeight, mHeight);
- mFormat->setInt32(kKeyColorFormat, OMX_COLOR_FormatYUV420Planar);
- mFormat->setCString(kKeyDecoderComponent, "VPXDecoder");
-
- int64_t durationUs;
- if (inputFormat->findInt64(kKeyDuration, &durationUs)) {
- mFormat->setInt64(kKeyDuration, durationUs);
- }
-}
-
-VPXDecoder::~VPXDecoder() {
- if (mStarted) {
- stop();
- }
-}
-
-status_t VPXDecoder::start(MetaData *) {
- if (mStarted) {
- return UNKNOWN_ERROR;
- }
-
- status_t err = mSource->start();
-
- if (err != OK) {
- return err;
- }
-
- mCtx = new vpx_codec_ctx_t;
- vpx_codec_err_t vpx_err;
- if ((vpx_err = vpx_codec_dec_init(
- (vpx_codec_ctx_t *)mCtx, &vpx_codec_vp8_dx_algo, NULL, 0))) {
- LOGE("on2 decoder failed to initialize. (%d)", vpx_err);
-
- mSource->stop();
-
- return UNKNOWN_ERROR;
- }
-
- mBufferGroup = new MediaBufferGroup;
- mBufferGroup->add_buffer(new MediaBuffer(mBufferSize));
- mBufferGroup->add_buffer(new MediaBuffer(mBufferSize));
-
- mTargetTimeUs = -1;
-
- mStarted = true;
-
- return OK;
-}
-
-status_t VPXDecoder::stop() {
- if (!mStarted) {
- return UNKNOWN_ERROR;
- }
-
- delete mBufferGroup;
- mBufferGroup = NULL;
-
- vpx_codec_destroy((vpx_codec_ctx_t *)mCtx);
- delete (vpx_codec_ctx_t *)mCtx;
- mCtx = NULL;
-
- mSource->stop();
-
- mStarted = false;
-
- return OK;
-}
-
-sp<MetaData> VPXDecoder::getFormat() {
- return mFormat;
-}
-
-status_t VPXDecoder::read(
- MediaBuffer **out, const ReadOptions *options) {
- *out = NULL;
-
- bool seeking = false;
- int64_t seekTimeUs;
- ReadOptions::SeekMode seekMode;
- if (options && options->getSeekTo(&seekTimeUs, &seekMode)) {
- seeking = true;
- }
-
- MediaBuffer *input;
- status_t err = mSource->read(&input, options);
-
- if (err != OK) {
- return err;
- }
-
- LOGV("read %d bytes from source\n", input->range_length());
-
- if (seeking) {
- int64_t targetTimeUs;
- if (input->meta_data()->findInt64(kKeyTargetTime, &targetTimeUs)
- && targetTimeUs >= 0) {
- mTargetTimeUs = targetTimeUs;
- } else {
- mTargetTimeUs = -1;
- }
- }
-
- if (vpx_codec_decode(
- (vpx_codec_ctx_t *)mCtx,
- (uint8_t *)input->data() + input->range_offset(),
- input->range_length(),
- NULL,
- 0)) {
- LOGE("on2 decoder failed to decode frame.");
- input->release();
- input = NULL;
-
- return UNKNOWN_ERROR;
- }
-
- LOGV("successfully decoded 1 or more frames.");
-
- int64_t timeUs;
- CHECK(input->meta_data()->findInt64(kKeyTime, &timeUs));
-
- input->release();
- input = NULL;
-
- bool skipFrame = false;
-
- if (mTargetTimeUs >= 0) {
- CHECK(timeUs <= mTargetTimeUs);
-
- if (timeUs < mTargetTimeUs) {
- // We're still waiting for the frame with the matching
- // timestamp and we won't return the current one.
- skipFrame = true;
-
- LOGV("skipping frame at %lld us", timeUs);
- } else {
- LOGV("found target frame at %lld us", timeUs);
-
- mTargetTimeUs = -1;
- }
- }
-
- if (skipFrame) {
- *out = new MediaBuffer(0);
- return OK;
- }
-
- vpx_codec_iter_t iter = NULL;
- vpx_image_t *img = vpx_codec_get_frame((vpx_codec_ctx_t *)mCtx, &iter);
-
- if (img == NULL) {
- // The VPX format supports "internal-only" frames that are
- // referenced by future content but never actually displayed, so
- // this is a perfectly valid scenario.
-
- *out = new MediaBuffer(0);
- return OK;
- }
-
- CHECK_EQ(img->fmt, IMG_FMT_I420);
-
- int32_t width = img->d_w;
- int32_t height = img->d_h;
-
- if (width != mWidth || height != mHeight) {
- LOGI("Image dimensions changed, width = %d, height = %d",
- width, height);
-
- mWidth = width;
- mHeight = height;
- mFormat->setInt32(kKeyWidth, width);
- mFormat->setInt32(kKeyHeight, height);
-
- mBufferSize = (mWidth * mHeight * 3) / 2;
- delete mBufferGroup;
- mBufferGroup = new MediaBufferGroup;
- mBufferGroup->add_buffer(new MediaBuffer(mBufferSize));
- mBufferGroup->add_buffer(new MediaBuffer(mBufferSize));
-
- return INFO_FORMAT_CHANGED;
- }
-
- MediaBuffer *output;
- CHECK_EQ(mBufferGroup->acquire_buffer(&output), OK);
-
- const uint8_t *srcLine = (const uint8_t *)img->planes[PLANE_Y];
- uint8_t *dst = (uint8_t *)output->data();
- for (size_t i = 0; i < img->d_h; ++i) {
- memcpy(dst, srcLine, img->d_w);
-
- srcLine += img->stride[PLANE_Y];
- dst += img->d_w;
- }
-
- srcLine = (const uint8_t *)img->planes[PLANE_U];
- for (size_t i = 0; i < img->d_h / 2; ++i) {
- memcpy(dst, srcLine, img->d_w / 2);
-
- srcLine += img->stride[PLANE_U];
- dst += img->d_w / 2;
- }
-
- srcLine = (const uint8_t *)img->planes[PLANE_V];
- for (size_t i = 0; i < img->d_h / 2; ++i) {
- memcpy(dst, srcLine, img->d_w / 2);
-
- srcLine += img->stride[PLANE_V];
- dst += img->d_w / 2;
- }
-
- output->set_range(0, (width * height * 3) / 2);
-
- output->meta_data()->setInt64(kKeyTime, timeUs);
-
- *out = output;
-
- return OK;
-}
-
-} // namespace android
-
diff --git a/media/libstagefright/codecs/on2/h264dec/Android.mk b/media/libstagefright/codecs/on2/h264dec/Android.mk
new file mode 100644
index 0000000..5b3c876
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/Android.mk
@@ -0,0 +1,127 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_SRC_FILES := \
+ ./source/h264bsd_transform.c \
+ ./source/h264bsd_util.c \
+ ./source/h264bsd_byte_stream.c \
+ ./source/h264bsd_seq_param_set.c \
+ ./source/h264bsd_pic_param_set.c \
+ ./source/h264bsd_slice_header.c \
+ ./source/h264bsd_slice_data.c \
+ ./source/h264bsd_macroblock_layer.c \
+ ./source/h264bsd_stream.c \
+ ./source/h264bsd_vlc.c \
+ ./source/h264bsd_cavlc.c \
+ ./source/h264bsd_nal_unit.c \
+ ./source/h264bsd_neighbour.c \
+ ./source/h264bsd_storage.c \
+ ./source/h264bsd_slice_group_map.c \
+ ./source/h264bsd_intra_prediction.c \
+ ./source/h264bsd_inter_prediction.c \
+ ./source/h264bsd_reconstruct.c \
+ ./source/h264bsd_dpb.c \
+ ./source/h264bsd_image.c \
+ ./source/h264bsd_deblocking.c \
+ ./source/h264bsd_conceal.c \
+ ./source/h264bsd_vui.c \
+ ./source/h264bsd_pic_order_cnt.c \
+ ./source/h264bsd_decoder.c \
+ ./source/H264SwDecApi.c \
+ SoftAVC.cpp \
+
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/./inc \
+ frameworks/base/media/libstagefright/include \
+ frameworks/base/include/media/stagefright/openmax \
+
+MY_ASM := \
+ ./source/arm_neon_asm_gcc/h264bsdWriteMacroblock.S \
+ ./source/arm_neon_asm_gcc/h264bsdClearMbLayer.S \
+ ./source/arm_neon_asm_gcc/h264bsdFillRow7.S \
+ ./source/arm_neon_asm_gcc/h264bsdCountLeadingZeros.S \
+ ./source/arm_neon_asm_gcc/h264bsdFlushBits.S
+
+
+MY_OMXDL_C_SRC := \
+ ./omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DeblockChroma_I.c \
+ ./omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DeblockLuma_I.c \
+ ./omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_InterpolateChroma.c \
+ ./omxdl/arm_neon/vc/m4p10/src/armVCM4P10_CAVLCTables.c \
+ ./omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c \
+ ./omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DecodeCoeffsToPairCAVLC.c \
+ ./omxdl/arm_neon/src/armCOMM_Bitstream.c \
+ ./omxdl/arm_neon/src/armCOMM.c
+
+MY_OMXDL_ASM_SRC := \
+ ./omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DeblockingChroma_unsafe_s.S \
+ ./omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DeblockingLuma_unsafe_s.S \
+ ./omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_Interpolate_Chroma_s.S \
+ ./omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_Align_unsafe_s.S \
+ ./omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_Copy_unsafe_s.S \
+ ./omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_DiagCopy_unsafe_s.S \
+ ./omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe_s.S \
+ ./omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe_s.S \
+ ./omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe_s.S \
+ ./omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe_s.S \
+ ./omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_FilterDeblockingChroma_HorEdge_I_s.S \
+ ./omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_FilterDeblockingChroma_VerEdge_I_s.S \
+ ./omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_FilterDeblockingLuma_HorEdge_I_s.S \
+ ./omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_FilterDeblockingLuma_VerEdge_I_s.S \
+ ./omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_InterpolateLuma_s.S \
+ ./omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_Average_4x_Align_unsafe_s.S \
+ ./omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DecodeCoeffsToPair_s.S \
+ ./omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DequantTables_s.S \
+ ./omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_QuantTables_s.S \
+ ./omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_TransformResidual4x4_s.S \
+ ./omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_UnpackBlock4x4_s.S \
+ ./omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_TransformDequantLumaDCFromPair_s.S \
+ ./omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_PredictIntra_16x16_s.S \
+ ./omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_PredictIntra_4x4_s.S \
+ ./omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_PredictIntraChroma_8x8_s.S \
+ ./omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_DequantTransformResidualFromPairAndAdd_s.S \
+ ./omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_TransformDequantChromaDCFromPair_s.S \
+
+
+ifeq ($(ARCH_ARM_HAVE_NEON),true)
+ LOCAL_ARM_NEON := true
+# LOCAL_CFLAGS := -std=c99 -D._NEON -D._OMXDL
+ LOCAL_CFLAGS := -DH264DEC_NEON -DH264DEC_OMXDL
+ LOCAL_SRC_FILES += $(MY_ASM) $(MY_OMXDL_C_SRC) $(MY_OMXDL_ASM_SRC)
+ LOCAL_C_INCLUDES += $(LOCAL_PATH)/./source/arm_neon_asm_gcc
+ LOCAL_C_INCLUDES += $(LOCAL_PATH)/./omxdl/arm_neon/api \
+ $(LOCAL_PATH)/./omxdl/arm_neon/vc/api \
+ $(LOCAL_PATH)/./omxdl/arm_neon/vc/m4p10/api
+endif
+
+LOCAL_SHARED_LIBRARIES := \
+ libstagefright libstagefright_omx libstagefright_foundation libutils \
+
+LOCAL_MODULE := libstagefright_soft_h264dec
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_SHARED_LIBRARY)
+
+#####################################################################
+# test utility: decoder
+#####################################################################
+##
+## Test application
+##
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ./source/DecTestBench.c
+
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/inc
+
+LOCAL_SHARED_LIBRARIES := libstagefright_soft_h264dec
+
+LOCAL_MODULE_TAGS := debug
+
+LOCAL_MODULE := decoder
+
+include $(BUILD_EXECUTABLE)
+
diff --git a/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp b/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp
new file mode 100644
index 0000000..740c957
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp
@@ -0,0 +1,560 @@
+/*
+ * Copyright (C) 2011 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 "SoftAVC"
+#include <utils/Log.h>
+
+#include "SoftAVC.h"
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/IOMX.h>
+
+
+namespace android {
+
+static const CodecProfileLevel kProfileLevels[] = {
+ { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1 },
+ { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1b },
+ { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel11 },
+ { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel12 },
+ { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel13 },
+ { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel2 },
+ { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel21 },
+ { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel22 },
+ { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel3 },
+ { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel31 },
+ { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel32 },
+ { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel4 },
+ { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel41 },
+ { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel42 },
+ { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel5 },
+ { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel51 },
+};
+
+template<class T>
+static void InitOMXParams(T *params) {
+ params->nSize = sizeof(T);
+ params->nVersion.s.nVersionMajor = 1;
+ params->nVersion.s.nVersionMinor = 0;
+ params->nVersion.s.nRevision = 0;
+ params->nVersion.s.nStep = 0;
+}
+
+SoftAVC::SoftAVC(
+ const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component)
+ : SimpleSoftOMXComponent(name, callbacks, appData, component),
+ mHandle(NULL),
+ mInputBufferCount(0),
+ mWidth(320),
+ mHeight(240),
+ mPictureSize(mWidth * mHeight * 3 / 2),
+ mCropLeft(0),
+ mCropTop(0),
+ mCropWidth(mWidth),
+ mCropHeight(mHeight),
+ mFirstPicture(NULL),
+ mFirstPictureId(-1),
+ mPicId(0),
+ mHeadersDecoded(false),
+ mEOSStatus(INPUT_DATA_AVAILABLE),
+ mOutputPortSettingsChange(NONE) {
+ initPorts();
+ CHECK_EQ(initDecoder(), (status_t)OK);
+}
+
+SoftAVC::~SoftAVC() {
+ H264SwDecRelease(mHandle);
+ mHandle = NULL;
+
+ while (mPicToHeaderMap.size() != 0) {
+ OMX_BUFFERHEADERTYPE *header = mPicToHeaderMap.editValueAt(0);
+ mPicToHeaderMap.removeItemsAt(0);
+ delete header;
+ header = NULL;
+ }
+ List<BufferInfo *> &outQueue = getPortQueue(kOutputPortIndex);
+ List<BufferInfo *> &inQueue = getPortQueue(kInputPortIndex);
+ CHECK(outQueue.empty());
+ CHECK(inQueue.empty());
+
+ delete[] mFirstPicture;
+}
+
+void SoftAVC::initPorts() {
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ InitOMXParams(&def);
+
+ def.nPortIndex = kInputPortIndex;
+ def.eDir = OMX_DirInput;
+ def.nBufferCountMin = kNumInputBuffers;
+ def.nBufferCountActual = def.nBufferCountMin;
+ def.nBufferSize = 8192;
+ def.bEnabled = OMX_TRUE;
+ def.bPopulated = OMX_FALSE;
+ def.eDomain = OMX_PortDomainVideo;
+ def.bBuffersContiguous = OMX_FALSE;
+ def.nBufferAlignment = 1;
+
+ def.format.video.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_VIDEO_AVC);
+ def.format.video.pNativeRender = NULL;
+ def.format.video.nFrameWidth = mWidth;
+ def.format.video.nFrameHeight = mHeight;
+ def.format.video.nStride = def.format.video.nFrameWidth;
+ def.format.video.nSliceHeight = def.format.video.nFrameHeight;
+ def.format.video.nBitrate = 0;
+ def.format.video.xFramerate = 0;
+ def.format.video.bFlagErrorConcealment = OMX_FALSE;
+ def.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
+ def.format.video.eColorFormat = OMX_COLOR_FormatUnused;
+ def.format.video.pNativeWindow = NULL;
+
+ addPort(def);
+
+ def.nPortIndex = kOutputPortIndex;
+ def.eDir = OMX_DirOutput;
+ def.nBufferCountMin = kNumOutputBuffers;
+ def.nBufferCountActual = def.nBufferCountMin;
+ def.bEnabled = OMX_TRUE;
+ def.bPopulated = OMX_FALSE;
+ def.eDomain = OMX_PortDomainVideo;
+ def.bBuffersContiguous = OMX_FALSE;
+ def.nBufferAlignment = 2;
+
+ def.format.video.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_VIDEO_RAW);
+ def.format.video.pNativeRender = NULL;
+ def.format.video.nFrameWidth = mWidth;
+ def.format.video.nFrameHeight = mHeight;
+ def.format.video.nStride = def.format.video.nFrameWidth;
+ def.format.video.nSliceHeight = def.format.video.nFrameHeight;
+ def.format.video.nBitrate = 0;
+ def.format.video.xFramerate = 0;
+ def.format.video.bFlagErrorConcealment = OMX_FALSE;
+ def.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
+ def.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
+ def.format.video.pNativeWindow = NULL;
+
+ def.nBufferSize =
+ (def.format.video.nFrameWidth * def.format.video.nFrameHeight * 3) / 2;
+
+ addPort(def);
+}
+
+status_t SoftAVC::initDecoder() {
+ // Force decoder to output buffers in display order.
+ if (H264SwDecInit(&mHandle, 0) == H264SWDEC_OK) {
+ return OK;
+ }
+ return UNKNOWN_ERROR;
+}
+
+OMX_ERRORTYPE SoftAVC::internalGetParameter(
+ OMX_INDEXTYPE index, OMX_PTR params) {
+ switch (index) {
+ case OMX_IndexParamVideoPortFormat:
+ {
+ OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams =
+ (OMX_VIDEO_PARAM_PORTFORMATTYPE *)params;
+
+ if (formatParams->nPortIndex > kOutputPortIndex) {
+ return OMX_ErrorUndefined;
+ }
+
+ if (formatParams->nIndex != 0) {
+ return OMX_ErrorNoMore;
+ }
+
+ if (formatParams->nPortIndex == kInputPortIndex) {
+ formatParams->eCompressionFormat = OMX_VIDEO_CodingAVC;
+ formatParams->eColorFormat = OMX_COLOR_FormatUnused;
+ formatParams->xFramerate = 0;
+ } else {
+ CHECK(formatParams->nPortIndex == kOutputPortIndex);
+
+ formatParams->eCompressionFormat = OMX_VIDEO_CodingUnused;
+ formatParams->eColorFormat = OMX_COLOR_FormatYUV420Planar;
+ formatParams->xFramerate = 0;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ case OMX_IndexParamVideoProfileLevelQuerySupported:
+ {
+ OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevel =
+ (OMX_VIDEO_PARAM_PROFILELEVELTYPE *) params;
+
+ if (profileLevel->nPortIndex != kInputPortIndex) {
+ LOGE("Invalid port index: %ld", profileLevel->nPortIndex);
+ return OMX_ErrorUnsupportedIndex;
+ }
+
+ size_t index = profileLevel->nProfileIndex;
+ size_t nProfileLevels =
+ sizeof(kProfileLevels) / sizeof(kProfileLevels[0]);
+ if (index >= nProfileLevels) {
+ return OMX_ErrorNoMore;
+ }
+
+ profileLevel->eProfile = kProfileLevels[index].mProfile;
+ profileLevel->eLevel = kProfileLevels[index].mLevel;
+ return OMX_ErrorNone;
+ }
+
+ default:
+ return SimpleSoftOMXComponent::internalGetParameter(index, params);
+ }
+}
+
+OMX_ERRORTYPE SoftAVC::internalSetParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params) {
+ switch (index) {
+ case OMX_IndexParamStandardComponentRole:
+ {
+ const OMX_PARAM_COMPONENTROLETYPE *roleParams =
+ (const OMX_PARAM_COMPONENTROLETYPE *)params;
+
+ if (strncmp((const char *)roleParams->cRole,
+ "video_decoder.avc",
+ OMX_MAX_STRINGNAME_SIZE - 1)) {
+ return OMX_ErrorUndefined;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ case OMX_IndexParamVideoPortFormat:
+ {
+ OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams =
+ (OMX_VIDEO_PARAM_PORTFORMATTYPE *)params;
+
+ if (formatParams->nPortIndex > kOutputPortIndex) {
+ return OMX_ErrorUndefined;
+ }
+
+ if (formatParams->nIndex != 0) {
+ return OMX_ErrorNoMore;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ default:
+ return SimpleSoftOMXComponent::internalSetParameter(index, params);
+ }
+}
+
+OMX_ERRORTYPE SoftAVC::getConfig(
+ OMX_INDEXTYPE index, OMX_PTR params) {
+ switch (index) {
+ case OMX_IndexConfigCommonOutputCrop:
+ {
+ OMX_CONFIG_RECTTYPE *rectParams = (OMX_CONFIG_RECTTYPE *)params;
+
+ if (rectParams->nPortIndex != 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ rectParams->nLeft = mCropLeft;
+ rectParams->nTop = mCropTop;
+ rectParams->nWidth = mCropWidth;
+ rectParams->nHeight = mCropHeight;
+
+ return OMX_ErrorNone;
+ }
+
+ default:
+ return OMX_ErrorUnsupportedIndex;
+ }
+}
+
+void SoftAVC::onQueueFilled(OMX_U32 portIndex) {
+ if (mOutputPortSettingsChange != NONE) {
+ return;
+ }
+
+ if (mEOSStatus == OUTPUT_FRAMES_FLUSHED) {
+ return;
+ }
+
+ List<BufferInfo *> &inQueue = getPortQueue(kInputPortIndex);
+ List<BufferInfo *> &outQueue = getPortQueue(kOutputPortIndex);
+ H264SwDecRet ret = H264SWDEC_PIC_RDY;
+ status_t err = OK;
+ bool portSettingsChanged = false;
+ while ((mEOSStatus != INPUT_DATA_AVAILABLE || !inQueue.empty())
+ && outQueue.size() == kNumOutputBuffers) {
+
+ if (mEOSStatus == INPUT_EOS_SEEN) {
+ drainAllOutputBuffers();
+ return;
+ }
+
+ BufferInfo *inInfo = *inQueue.begin();
+ OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
+ ++mPicId;
+ if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
+ inQueue.erase(inQueue.begin());
+ inInfo->mOwnedByUs = false;
+ notifyEmptyBufferDone(inHeader);
+ mEOSStatus = INPUT_EOS_SEEN;
+ continue;
+ }
+
+ OMX_BUFFERHEADERTYPE *header = new OMX_BUFFERHEADERTYPE;
+ memset(header, 0, sizeof(OMX_BUFFERHEADERTYPE));
+ header->nTimeStamp = inHeader->nTimeStamp;
+ header->nFlags = inHeader->nFlags;
+ mPicToHeaderMap.add(mPicId, header);
+ inQueue.erase(inQueue.begin());
+
+ H264SwDecInput inPicture;
+ H264SwDecOutput outPicture;
+ memset(&inPicture, 0, sizeof(inPicture));
+ inPicture.dataLen = inHeader->nFilledLen;
+ inPicture.pStream = inHeader->pBuffer + inHeader->nOffset;
+ inPicture.picId = mPicId;
+ inPicture.intraConcealmentMethod = 1;
+ H264SwDecPicture decodedPicture;
+
+ while (inPicture.dataLen > 0) {
+ ret = H264SwDecDecode(mHandle, &inPicture, &outPicture);
+ if (ret == H264SWDEC_HDRS_RDY_BUFF_NOT_EMPTY ||
+ ret == H264SWDEC_PIC_RDY_BUFF_NOT_EMPTY) {
+ inPicture.dataLen -= (u32)(outPicture.pStrmCurrPos - inPicture.pStream);
+ inPicture.pStream = outPicture.pStrmCurrPos;
+ if (ret == H264SWDEC_HDRS_RDY_BUFF_NOT_EMPTY) {
+ mHeadersDecoded = true;
+ H264SwDecInfo decoderInfo;
+ CHECK(H264SwDecGetInfo(mHandle, &decoderInfo) == H264SWDEC_OK);
+
+ if (handlePortSettingChangeEvent(&decoderInfo)) {
+ portSettingsChanged = true;
+ }
+
+ if (decoderInfo.croppingFlag &&
+ handleCropRectEvent(&decoderInfo.cropParams)) {
+ portSettingsChanged = true;
+ }
+ }
+ } else {
+ if (portSettingsChanged) {
+ if (H264SwDecNextPicture(mHandle, &decodedPicture, 0)
+ == H264SWDEC_PIC_RDY) {
+
+ // Save this output buffer; otherwise, it will be
+ // lost during dynamic port reconfiguration because
+ // OpenMAX client will delete _all_ output buffers
+ // in the process.
+ saveFirstOutputBuffer(
+ decodedPicture.picId,
+ (uint8_t *)decodedPicture.pOutputPicture);
+ }
+ }
+ inPicture.dataLen = 0;
+ if (ret < 0) {
+ LOGE("Decoder failed: %d", ret);
+ err = ERROR_MALFORMED;
+ }
+ }
+ }
+ inInfo->mOwnedByUs = false;
+ notifyEmptyBufferDone(inHeader);
+
+ if (portSettingsChanged) {
+ portSettingsChanged = false;
+ return;
+ }
+
+ if (mFirstPicture && !outQueue.empty()) {
+ drainOneOutputBuffer(mFirstPictureId, mFirstPicture);
+ delete[] mFirstPicture;
+ mFirstPicture = NULL;
+ mFirstPictureId = -1;
+ }
+
+ while (!outQueue.empty() &&
+ mHeadersDecoded &&
+ H264SwDecNextPicture(mHandle, &decodedPicture, 0)
+ == H264SWDEC_PIC_RDY) {
+
+ int32_t picId = decodedPicture.picId;
+ uint8_t *data = (uint8_t *) decodedPicture.pOutputPicture;
+ drainOneOutputBuffer(picId, data);
+ }
+
+ if (err != OK) {
+ notify(OMX_EventError, OMX_ErrorUndefined, err, NULL);
+ }
+ }
+}
+
+bool SoftAVC::handlePortSettingChangeEvent(const H264SwDecInfo *info) {
+ if (mWidth != info->picWidth || mHeight != info->picHeight) {
+ mWidth = info->picWidth;
+ mHeight = info->picHeight;
+ mPictureSize = mWidth * mHeight * 3 / 2;
+ mCropWidth = mWidth;
+ mCropHeight = mHeight;
+ updatePortDefinitions();
+ notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
+ mOutputPortSettingsChange = AWAITING_DISABLED;
+ return true;
+ }
+
+ return false;
+}
+
+bool SoftAVC::handleCropRectEvent(const CropParams *crop) {
+ if (mCropLeft != crop->cropLeftOffset ||
+ mCropTop != crop->cropTopOffset ||
+ mCropWidth != crop->cropOutWidth ||
+ mCropHeight != crop->cropOutHeight) {
+ mCropLeft = crop->cropLeftOffset;
+ mCropTop = crop->cropTopOffset;
+ mCropWidth = crop->cropOutWidth;
+ mCropHeight = crop->cropOutHeight;
+
+ notify(OMX_EventPortSettingsChanged, 1,
+ OMX_IndexConfigCommonOutputCrop, NULL);
+
+ return true;
+ }
+ return false;
+}
+
+void SoftAVC::saveFirstOutputBuffer(int32_t picId, uint8_t *data) {
+ CHECK(mFirstPicture == NULL);
+ mFirstPictureId = picId;
+
+ mFirstPicture = new uint8_t[mPictureSize];
+ memcpy(mFirstPicture, data, mPictureSize);
+}
+
+void SoftAVC::drainOneOutputBuffer(int32_t picId, uint8_t* data) {
+ List<BufferInfo *> &outQueue = getPortQueue(kOutputPortIndex);
+ BufferInfo *outInfo = *outQueue.begin();
+ outQueue.erase(outQueue.begin());
+ OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
+ OMX_BUFFERHEADERTYPE *header = mPicToHeaderMap.valueFor(picId);
+ outHeader->nTimeStamp = header->nTimeStamp;
+ outHeader->nFlags = header->nFlags;
+ outHeader->nFilledLen = mPictureSize;
+ memcpy(outHeader->pBuffer + outHeader->nOffset,
+ data, mPictureSize);
+ mPicToHeaderMap.removeItem(picId);
+ delete header;
+ outInfo->mOwnedByUs = false;
+ notifyFillBufferDone(outHeader);
+}
+
+bool SoftAVC::drainAllOutputBuffers() {
+ List<BufferInfo *> &outQueue = getPortQueue(kOutputPortIndex);
+ H264SwDecPicture decodedPicture;
+
+ while (!outQueue.empty()) {
+ BufferInfo *outInfo = *outQueue.begin();
+ outQueue.erase(outQueue.begin());
+ OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
+ if (mHeadersDecoded &&
+ H264SWDEC_PIC_RDY ==
+ H264SwDecNextPicture(mHandle, &decodedPicture, 1 /* flush */)) {
+
+ int32_t picId = decodedPicture.picId;
+ CHECK(mPicToHeaderMap.indexOfKey(picId) >= 0);
+
+ memcpy(outHeader->pBuffer + outHeader->nOffset,
+ decodedPicture.pOutputPicture,
+ mPictureSize);
+
+ OMX_BUFFERHEADERTYPE *header = mPicToHeaderMap.valueFor(picId);
+ outHeader->nTimeStamp = header->nTimeStamp;
+ outHeader->nFlags = header->nFlags;
+ outHeader->nFilledLen = mPictureSize;
+ mPicToHeaderMap.removeItem(picId);
+ delete header;
+ } else {
+ outHeader->nTimeStamp = 0;
+ outHeader->nFilledLen = 0;
+ outHeader->nFlags = OMX_BUFFERFLAG_EOS;
+ mEOSStatus = OUTPUT_FRAMES_FLUSHED;
+ }
+
+ outInfo->mOwnedByUs = false;
+ notifyFillBufferDone(outHeader);
+ }
+
+ return true;
+}
+
+void SoftAVC::onPortFlushCompleted(OMX_U32 portIndex) {
+ if (portIndex == kInputPortIndex) {
+ mEOSStatus = INPUT_DATA_AVAILABLE;
+ }
+}
+
+void SoftAVC::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
+ switch (mOutputPortSettingsChange) {
+ case NONE:
+ break;
+
+ case AWAITING_DISABLED:
+ {
+ CHECK(!enabled);
+ mOutputPortSettingsChange = AWAITING_ENABLED;
+ break;
+ }
+
+ default:
+ {
+ CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED);
+ CHECK(enabled);
+ mOutputPortSettingsChange = NONE;
+ break;
+ }
+ }
+}
+
+void SoftAVC::updatePortDefinitions() {
+ OMX_PARAM_PORTDEFINITIONTYPE *def = &editPortInfo(0)->mDef;
+ def->format.video.nFrameWidth = mWidth;
+ def->format.video.nFrameHeight = mHeight;
+ def->format.video.nStride = def->format.video.nFrameWidth;
+ def->format.video.nSliceHeight = def->format.video.nFrameHeight;
+
+ def = &editPortInfo(1)->mDef;
+ def->format.video.nFrameWidth = mWidth;
+ def->format.video.nFrameHeight = mHeight;
+ def->format.video.nStride = def->format.video.nFrameWidth;
+ def->format.video.nSliceHeight = def->format.video.nFrameHeight;
+
+ def->nBufferSize =
+ (def->format.video.nFrameWidth
+ * def->format.video.nFrameHeight * 3) / 2;
+}
+
+} // namespace android
+
+android::SoftOMXComponent *createSoftOMXComponent(
+ const char *name, const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData, OMX_COMPONENTTYPE **component) {
+ return new android::SoftAVC(name, callbacks, appData, component);
+}
diff --git a/media/libstagefright/codecs/on2/h264dec/SoftAVC.h b/media/libstagefright/codecs/on2/h264dec/SoftAVC.h
new file mode 100644
index 0000000..1cc85e8
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/SoftAVC.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2011 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 SOFT_AVC_H_
+
+#define SOFT_AVC_H_
+
+#include "SimpleSoftOMXComponent.h"
+#include <utils/KeyedVector.h>
+
+#include "H264SwDecApi.h"
+#include "basetype.h"
+
+namespace android {
+
+struct SoftAVC : public SimpleSoftOMXComponent {
+ SoftAVC(const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component);
+
+protected:
+ virtual ~SoftAVC();
+
+ virtual OMX_ERRORTYPE internalGetParameter(
+ OMX_INDEXTYPE index, OMX_PTR params);
+
+ virtual OMX_ERRORTYPE internalSetParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params);
+
+ virtual OMX_ERRORTYPE getConfig(OMX_INDEXTYPE index, OMX_PTR params);
+
+ virtual void onQueueFilled(OMX_U32 portIndex);
+ virtual void onPortFlushCompleted(OMX_U32 portIndex);
+ virtual void onPortEnableCompleted(OMX_U32 portIndex, bool enabled);
+
+private:
+ enum {
+ kInputPortIndex = 0,
+ kOutputPortIndex = 1,
+ kNumInputBuffers = 8,
+ kNumOutputBuffers = 2,
+ };
+
+ enum EOSStatus {
+ INPUT_DATA_AVAILABLE,
+ INPUT_EOS_SEEN,
+ OUTPUT_FRAMES_FLUSHED,
+ };
+
+ void *mHandle;
+
+ size_t mInputBufferCount;
+
+ uint32_t mWidth, mHeight, mPictureSize;
+ uint32_t mCropLeft, mCropTop;
+ uint32_t mCropWidth, mCropHeight;
+
+ uint8_t *mFirstPicture;
+ int32_t mFirstPictureId;
+
+ int32_t mPicId; // Which output picture is for which input buffer?
+
+ // OMX_BUFFERHEADERTYPE may be overkill, but it is convenient
+ // for tracking the following fields: nFlags, nTimeStamp, etc.
+ KeyedVector<int32_t, OMX_BUFFERHEADERTYPE *> mPicToHeaderMap;
+ bool mHeadersDecoded;
+
+ EOSStatus mEOSStatus;
+
+ enum OutputPortSettingChange {
+ NONE,
+ AWAITING_DISABLED,
+ AWAITING_ENABLED
+ };
+ OutputPortSettingChange mOutputPortSettingsChange;
+
+ void initPorts();
+ status_t initDecoder();
+ void updatePortDefinitions();
+ bool drainAllOutputBuffers();
+ void drainOneOutputBuffer(int32_t picId, uint8_t *data);
+ void saveFirstOutputBuffer(int32_t pidId, uint8_t *data);
+ bool handleCropRectEvent(const CropParams* crop);
+ bool handlePortSettingChangeEvent(const H264SwDecInfo *info);
+
+ DISALLOW_EVIL_CONSTRUCTORS(SoftAVC);
+};
+
+} // namespace android
+
+#endif // SOFT_AVC_H_
+
diff --git a/media/libstagefright/codecs/on2/h264dec/inc/H264SwDecApi.h b/media/libstagefright/codecs/on2/h264dec/inc/H264SwDecApi.h
new file mode 100755
index 0000000..fe112bc
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/inc/H264SwDecApi.h
@@ -0,0 +1,192 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include Headers
+
+ 2. Enumerations used as a return value or a parameter.
+ 2.1. API's return value enumerations.
+
+ 3. User Structures
+ 3.1. Structures for H264SwDecDecode() parameters.
+ 3.2. Structures for information interchange with
+ DEC API and user application.
+
+ 4. Prototypes of Decoder API functions
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDECAPI_H
+#define H264SWDECAPI_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*------------------------------------------------------------------------------
+ 1. Include Headers
+------------------------------------------------------------------------------*/
+
+ #include "basetype.h"
+
+/*------------------------------------------------------------------------------
+ 2.1. API's return value enumerations.
+------------------------------------------------------------------------------*/
+
+ typedef enum
+ {
+ H264SWDEC_OK = 0,
+ H264SWDEC_STRM_PROCESSED = 1,
+ H264SWDEC_PIC_RDY,
+ H264SWDEC_PIC_RDY_BUFF_NOT_EMPTY,
+ H264SWDEC_HDRS_RDY_BUFF_NOT_EMPTY,
+ H264SWDEC_PARAM_ERR = -1,
+ H264SWDEC_STRM_ERR = -2,
+ H264SWDEC_NOT_INITIALIZED = -3,
+ H264SWDEC_MEMFAIL = -4,
+ H264SWDEC_INITFAIL = -5,
+ H264SWDEC_HDRS_NOT_RDY = -6,
+ H264SWDEC_EVALUATION_LIMIT_EXCEEDED = -7
+ } H264SwDecRet;
+
+/*------------------------------------------------------------------------------
+ 3.1. Structures for H264SwDecDecode() parameters.
+------------------------------------------------------------------------------*/
+
+ /* typedef of the Decoder instance */
+ typedef void *H264SwDecInst;
+
+ /* Input structure */
+ typedef struct
+ {
+ u8 *pStream; /* Pointer to stream to be decoded */
+ u32 dataLen; /* Number of bytes to be decoded */
+ u32 picId; /* Identifier for the picture to be decoded */
+ u32 intraConcealmentMethod; /* 0 = Gray concealment for intra
+ 1 = Reference concealment for intra */
+
+ } H264SwDecInput;
+
+
+ /* Output structure */
+ typedef struct
+ {
+ u8 *pStrmCurrPos; /* Pointer to stream position where decoder
+ ended up */
+ } H264SwDecOutput;
+
+ /* Output structure for H264SwDecNextPicture */
+ typedef struct
+ {
+ u32 *pOutputPicture; /* Pointer to the picture, YUV format */
+ u32 picId; /* Identifier of the picture to be displayed*/
+ u32 isIdrPicture; /* Flag to indicate if the picture is an
+ IDR picture */
+ u32 nbrOfErrMBs; /* Number of concealed MB's in the picture */
+ } H264SwDecPicture;
+
+/*------------------------------------------------------------------------------
+ 3.2. Structures for information interchange with DEC API
+ and user application.
+------------------------------------------------------------------------------*/
+
+ typedef struct
+ {
+ u32 cropLeftOffset;
+ u32 cropOutWidth;
+ u32 cropTopOffset;
+ u32 cropOutHeight;
+ } CropParams;
+
+ typedef struct
+ {
+ u32 profile;
+ u32 picWidth;
+ u32 picHeight;
+ u32 videoRange;
+ u32 matrixCoefficients;
+ u32 parWidth;
+ u32 parHeight;
+ u32 croppingFlag;
+ CropParams cropParams;
+ } H264SwDecInfo;
+
+ /* Version information */
+ typedef struct
+ {
+ u32 major; /* Decoder API major version */
+ u32 minor; /* Dncoder API minor version */
+ } H264SwDecApiVersion;
+
+/*------------------------------------------------------------------------------
+ 4. Prototypes of Decoder API functions
+------------------------------------------------------------------------------*/
+
+ H264SwDecRet H264SwDecDecode(H264SwDecInst decInst,
+ H264SwDecInput *pInput,
+ H264SwDecOutput *pOutput);
+
+ H264SwDecRet H264SwDecInit(H264SwDecInst *decInst,
+ u32 noOutputReordering);
+
+ H264SwDecRet H264SwDecNextPicture(H264SwDecInst decInst,
+ H264SwDecPicture *pOutput,
+ u32 endOfStream);
+
+ H264SwDecRet H264SwDecGetInfo(H264SwDecInst decInst,
+ H264SwDecInfo *pDecInfo);
+
+ void H264SwDecRelease(H264SwDecInst decInst);
+
+ H264SwDecApiVersion H264SwDecGetAPIVersion(void);
+
+ /* function prototype for API trace */
+ void H264SwDecTrace(char *);
+
+ /* function prototype for memory allocation */
+ void* H264SwDecMalloc(u32 size);
+
+ /* function prototype for memory free */
+ void H264SwDecFree(void *ptr);
+
+ /* function prototype for memory copy */
+ void H264SwDecMemcpy(void *dest, void *src, u32 count);
+
+ /* function prototype for memset */
+ void H264SwDecMemset(void *ptr, i32 value, u32 count);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* H264SWDECAPI_H */
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/inc/basetype.h b/media/libstagefright/codecs/on2/h264dec/inc/basetype.h
new file mode 100755
index 0000000..63d5653
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/inc/basetype.h
@@ -0,0 +1,52 @@
+/*
+ * 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 BASETYPE_H_INCLUDED
+#define BASETYPE_H_INCLUDED
+
+
+#ifdef __arm
+#define VOLATILE volatile
+#else
+#define VOLATILE
+#endif
+
+typedef unsigned char u8;
+typedef signed char i8;
+typedef unsigned short u16;
+typedef signed short i16;
+typedef unsigned int u32;
+typedef signed int i32;
+
+#if defined(VC1SWDEC_16BIT) || defined(MP4ENC_ARM11)
+typedef unsigned short u16x;
+typedef signed short i16x;
+#else
+typedef unsigned int u16x;
+typedef signed int i16x;
+#endif
+
+
+#ifndef NULL
+#ifdef __cplusplus
+#define NULL 0
+#else
+#define NULL ((void *)0)
+#endif
+#endif
+
+#endif /* BASETYPE_H_INCLUDED */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/ARM_DELIVERY.TXT b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/ARM_DELIVERY.TXT
new file mode 100644
index 0000000..5ce70ca
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/ARM_DELIVERY.TXT
@@ -0,0 +1,63 @@
+The contents of this transaction was created by Hedley Francis
+of ARM on 19-Feb-2008.
+
+It contains the ARM data versions listed below.
+
+This data, unless otherwise stated, is ARM Proprietary and access to it
+is subject to the agreements indicated below.
+
+If you experience problems with this data, please contact ARM support
+quoting transaction reference <97413>.
+
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+- OX001-SW-98010-r0p0-00bet1
+ Video codecs - optimised code
+ V6 optimized code release for Hantro (Ver 1.0.2)
+ internal access
+
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+This transaction contains deliverables which are designated as being of
+beta release status (BET).
+
+Beta release status has a particular meaning to ARM of which the recipient
+must be aware. Beta is a pre-release status indicating that the deliverable
+so described is believed to robustly demonstrate specified behaviour, to be
+consistent across its included aspects and be ready for general deployment.
+But Beta also indicates that pre-release reliability trials are ongoing and
+that it is possible residual defects or errors in operation, consistency
+and documentation may still be encountered. The recipient should consider
+this position when using this Beta material supplied. ARM will normally
+attempt to provide fixes or a work-around for defects identified by the
+recipient, but the provision or timeliness of this support cannot be
+guaranteed. ARM shall not be responsible for direct or consequential
+damages as a result of encountering one or more of these residual defects.
+By accepting a Beta release, the recipient agrees to these constraints and
+to providing reasonable information to ARM to enable the replication of the
+defects identified by the recipient. The specific Beta version supplied
+will not be supported after release of a later or higher status version.
+It should be noted that Support for the Beta release of the deliverable
+will only be provided by ARM to a recipient who has a current support and
+maintenance contract for the deliverable.
+
+
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+In addition to the data versions listed above, this transaction contains
+two additional files at the top level.
+
+The first is this file, ARM_DELIVERY_97413.TXT, which is the delivery
+note.
+
+The second is ARM_MANIFEST_97413.TXT which contains a manifest of all the
+files included in this transaction, together with their checksums.
+
+The checksums provided are calculated using the RSA Data Security, Inc.
+MD5 Message-Digest Algorithm.
+
+The checksums can be used to verify the integrity of this data using the
+"md5sum" tool (which is part of the GNU "textutils" package) by running:
+
+ % md5sum --check ARM_MANIFEST_97413.TXT
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/ARM_MANIFEST.TXT b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/ARM_MANIFEST.TXT
new file mode 100644
index 0000000..9b2238b
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/ARM_MANIFEST.TXT
@@ -0,0 +1,91 @@
+ OX001-SW-98010-r0p0-00bet1/
+ OX001-SW-98010-r0p0-00bet1/api/
+e049791cfab6060a08cbac7b3ad767d6 OX001-SW-98010-r0p0-00bet1/api/armCOMM_s.h
+ed798face25497b2703ede736d6d52b6 OX001-SW-98010-r0p0-00bet1/api/omxtypes_s.h
+4eebd63af087376811d6749f0646b864 OX001-SW-98010-r0p0-00bet1/api/armCOMM_BitDec_s.h
+43cf46c2cf2fe1f93c615b57bcbe4809 OX001-SW-98010-r0p0-00bet1/api/armCOMM.h
+8f248ceaac8f602e277a521b679dcbbe OX001-SW-98010-r0p0-00bet1/api/armCOMM_IDCTTable.h
+53f2ae8a98495f05e26a4cf862a7f750 OX001-SW-98010-r0p0-00bet1/api/armCOMM_Version.h
+3a2f420ddf6a1b950470bd0f5ebd5c62 OX001-SW-98010-r0p0-00bet1/api/armCOMM_IDCT_s.h
+511c0bb534fe223599e2c84eff24c9ed OX001-SW-98010-r0p0-00bet1/api/armCOMM_MaskTable.h
+8971932d56eed6b1ad1ba507f0bff5f0 OX001-SW-98010-r0p0-00bet1/api/armCOMM_Bitstream.h
+f87fedd9ca432fefa757008176864ef8 OX001-SW-98010-r0p0-00bet1/api/armOMX.h
+8e49899a428822c36ef9dd94e0e05f18 OX001-SW-98010-r0p0-00bet1/api/omxtypes.h
+694281d11af52f88e6f9d4cb226ac8a7 OX001-SW-98010-r0p0-00bet1/build_vc.pl
+e72d96c0a415459748df9807f3dae72f OX001-SW-98010-r0p0-00bet1/filelist_vc.txt
+ OX001-SW-98010-r0p0-00bet1/src/
+5eeae659a29477f5c52296d24afffd3c OX001-SW-98010-r0p0-00bet1/src/armCOMM_IDCTTable.c
+d64cdcf38f7749dc7f77465e5b7d356d OX001-SW-98010-r0p0-00bet1/src/armCOMM_MaskTable.c
+ OX001-SW-98010-r0p0-00bet1/vc/
+ OX001-SW-98010-r0p0-00bet1/vc/m4p10/
+ OX001-SW-98010-r0p0-00bet1/vc/m4p10/src/
+e7e0c320978564a7c9b2c723749a98d6 OX001-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_CAVLCTables.c
+4adcd0df081990bdfc4729041a2a9152 OX001-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_InterpolateChroma.c
+852e0404142965dc1f3aa7f00ee5127b OX001-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_UnpackBlock4x4_s.s
+7054151c5bfea6b5e74feee86b2d7b01 OX001-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_DecodeCoeffsToPairCAVLC.c
+38944c5e0bba01e32ff349c2c87c71b2 OX001-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_DequantTables_s.s
+32ff4b8be62e2f0f3e764b83c1e5e2fd OX001-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_DeblockChroma_I.c
+90b0e6a04e764902c0a0903640c10b32 OX001-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_DeblockingLuma_unsafe_s.s
+28a19ae4fe2258628080d6a89bb54b91 OX001-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_DeblockingChroma_unsafe_s.s
+98e196b9e1ffebaf91f62ea9d17fb97d OX001-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_InterpolateLuma_s.s
+01ba60eff66ea49a4f833ce6279f8e2f OX001-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_DeblockLuma_I.c
+f301d5a95e07354f593ea5747c01cb0a OX001-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe_s.s
+44c9ef21e840a100301f7d7a4189957c OX001-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe_s.s
+a33b03bbd3352d24ed744769e12bb87d OX001-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe_s.s
+00c20bfda67bb86096b615fc17c94b35 OX001-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_TransformDequantChromaDCFromPair_s.s
+2ddcaf60a8ea1e6e6b77737f768bfb9d OX001-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_QuantTables_s.s
+c3002aad5600f872b70a5d7fe3915846 OX001-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_InterpolateLuma_Align_unsafe_s.s
+a2900f2c47f1c61d20bd6c1eda33d6d4 OX001-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_InterpolateLuma_Copy_unsafe_s.s
+e4fecd66bc47f07539bc308935e84a1f OX001-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_PredictIntra_4x4_s.s
+78815c9df50ba53131bb22d2b829e3c3 OX001-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_TransformDequantLumaDCFromPair_s.s
+1909ae312ac79a03a5fac1d1e8bc0291 OX001-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_HorEdge_I_s.s
+3d2c48580655928065de7839866d9bc4 OX001-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe_s.s
+23aa2fdf155d4fa6ff745eab6e01f32b OX001-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_PredictIntra_16x16_s.s
+97f20a93c481d7f6173d919f41e415bd OX001-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_VerEdge_I_s.s
+becd512da202436286811b6aec061f47 OX001-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_HorEdge_I_s.s
+dd24a99ae3cd842dcacaf31d47de88b3 OX001-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_VerEdge_I_s.s
+c2d995f787b6f44ef10c751c12d1935f OX001-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_InterpolateLuma_DiagCopy_unsafe_s.s
+3628fbdf0cd217c287b6ccc94135d06e OX001-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_PredictIntraChroma_8x8_s.s
+4a52b3e9e268b8a8f07829bf500d03af OX001-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_DecodeCoeffsToPair_s.s
+11249f8a98c5d4b84cb5575b0e37ca9c OX001-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_Average_4x_Align_unsafe_s.s
+3599b1074330965c8ca285d164efccff OX001-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_Interpolate_Chroma_s.s
+3339e026c7de655d9400949eb5e51451 OX001-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_TransformResidual4x4_s.s
+cc4a6f32db0b72a91d3f278f6855df69 OX001-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c
+ OX001-SW-98010-r0p0-00bet1/vc/m4p10/api/
+6e530ddaa7c2b57ffe88162c020cb662 OX001-SW-98010-r0p0-00bet1/vc/m4p10/api/armVCM4P10_CAVLCTables.h
+ OX001-SW-98010-r0p0-00bet1/vc/m4p2/
+ OX001-SW-98010-r0p0-00bet1/vc/m4p2/src/
+cdf412920c2037a725d0420002b6752e OX001-SW-98010-r0p0-00bet1/vc/m4p2/src/armVCM4P2_Clip8_s.s
+dba9824e959b21d401cac925e68a11a6 OX001-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_Inter_s.s
+b559b71d5c94627f10e616fb72c0cefc OX001-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_QuantInvIntra_I_s.s
+4fba4c431a783a78a2eb6497a94ac967 OX001-SW-98010-r0p0-00bet1/vc/m4p2/src/armVCM4P2_Zigzag_Tables.c
+1e4c3be8c5eddc00c9f05e83bcf315ef OX001-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_MCReconBlock_s.s
+1b0b2990c2669dfb87cf6b810611c01b OX001-SW-98010-r0p0-00bet1/vc/m4p2/src/armVCM4P2_Huff_Tables_VLC.c
+1c9b87abf3283e957816b3937c680701 OX001-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_DecodePadMV_PVOP_s.s
+4fe1afca659a9055fc1172e58f78a506 OX001-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Intra.c
+2ea067f0436f91ba1351edaf411cb4ea OX001-SW-98010-r0p0-00bet1/vc/m4p2/src/armVCM4P2_Lookup_Tables.c
+acb92be1dbcdb3ebe824cbe9e28d03bf OX001-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_IDCT8x8blk_s.s
+a6b41f01b1df7dd656ebdba3084bfa2a OX001-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_FindMVpred_s.s
+293a48a648a3085456e6665bb7366fad OX001-SW-98010-r0p0-00bet1/vc/m4p2/src/armVCM4P2_SetPredDir_s.s
+ffe6b96c74d4881f4d3c8de8cc737797 OX001-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_QuantInvInter_I_s.s
+437dfa204508850d61d4b87091446e9f OX001-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraACVLC_s.s
+ff5915d181bfd2cd2f0bd588bd2300dc OX001-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraDCVLC_s.s
+6775eb0c561dbab965c60f85b08c96fd OX001-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_PredictReconCoefIntra_s.s
+a0d85f4f517c945a4c9317ac021f2d08 OX001-SW-98010-r0p0-00bet1/vc/m4p2/src/armVCM4P2_DecodeVLCZigzag_AC_unsafe_s.s
+386020dee8b725c7fe2526f1fc211d7d OX001-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Inter.c
+ OX001-SW-98010-r0p0-00bet1/vc/m4p2/api/
+4624e7c838e10a249abcc3d3f4f40748 OX001-SW-98010-r0p0-00bet1/vc/m4p2/api/armVCM4P2_Huff_Tables_VLC.h
+65e1057d04e2cb844559dc9f6e09795a OX001-SW-98010-r0p0-00bet1/vc/m4p2/api/armVCM4P2_ZigZag_Tables.h
+ OX001-SW-98010-r0p0-00bet1/vc/src/
+e627b3346b0dc9aff14446005ce0fa43 OX001-SW-98010-r0p0-00bet1/vc/src/armVC_Version.c
+ OX001-SW-98010-r0p0-00bet1/vc/api/
+7ca94b1c33ac0211e17d38baadd7d1dd OX001-SW-98010-r0p0-00bet1/vc/api/armVC.h
+12cf7596edbbf6048b626d15e8d0ed48 OX001-SW-98010-r0p0-00bet1/vc/api/omxVC.h
+11726e286a81257cb45f5547fb4d374c OX001-SW-98010-r0p0-00bet1/vc/api/omxVC_s.h
+a5b2af605c319cd2491319e430741377 OX001-SW-98010-r0p0-00bet1/vc/api/armVCCOMM_s.h
+ OX001-SW-98010-r0p0-00bet1/vc/comm/
+ OX001-SW-98010-r0p0-00bet1/vc/comm/src/
+50cca6954c447b012ab39ca7872e5e8f OX001-SW-98010-r0p0-00bet1/vc/comm/src/omxVCCOMM_Copy16x16_s.s
+d1c3bce77fc5774c899b447d13f02cd0 OX001-SW-98010-r0p0-00bet1/vc/comm/src/omxVCCOMM_Copy8x8_s.s
+fdac1d1bad3fd23c880beb39bc2e89aa OX001-SW-98010-r0p0-00bet1/vc/comm/src/omxVCCOMM_ExpandFrame_I_s.s
+6d9adc2be5bd0311591030d0c6df771c ARM_DELIVERY_97413.TXT
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM.h
new file mode 100644
index 0000000..2ed86a4
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM.h
@@ -0,0 +1,785 @@
+/**
+ *
+ * File Name: armCOMM.h
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * File: armCOMM.h
+ * Brief: Declares Common APIs/Data Types used across OpenMAX API's
+ *
+ */
+
+
+#ifndef _armCommon_H_
+#define _armCommon_H_
+
+#include "omxtypes.h"
+
+typedef struct
+{
+ OMX_F32 Re; /** Real part */
+ OMX_F32 Im; /** Imaginary part */
+
+} OMX_FC32; /** single precision floating point complex number */
+
+typedef struct
+{
+ OMX_F64 Re; /** Real part */
+ OMX_F64 Im; /** Imaginary part */
+
+} OMX_FC64; /** double precision floating point complex number */
+
+
+/* Used by both IP and IC domains for 8x8 JPEG blocks. */
+typedef OMX_S16 ARM_BLOCK8x8[64];
+
+
+#include "armOMX.h"
+
+#define armPI (OMX_F64)(3.1415926535897932384626433832795)
+
+/***********************************************************************/
+
+/* Compiler extensions */
+#ifdef ARM_DEBUG
+/* debug version */
+#include <stdlib.h>
+#include <assert.h>
+#include <stdio.h>
+#define armError(str) {printf((str)); printf("\n"); exit(-1);}
+#define armWarn(str) {printf((str)); printf("\n");}
+#define armIgnore(a) ((void)a)
+#define armAssert(a) assert(a)
+#else
+/* release version */
+#define armError(str) ((void) (str))
+#define armWarn(str) ((void) (str))
+#define armIgnore(a) ((void) (a))
+#define armAssert(a) ((void) (a))
+#endif /* ARM_DEBUG */
+
+/* Arithmetic operations */
+
+#define armMin(a,b) ( (a) > (b) ? (b):(a) )
+#define armMax(a,b) ( (a) > (b) ? (a):(b) )
+#define armAbs(a) ( (a) < 0 ? -(a):(a) )
+
+/* Alignment operation */
+
+#define armAlignToBytes(Ptr,N) (Ptr + ( ((N-(int)Ptr)&(N-1)) / sizeof(*Ptr) ))
+#define armAlignTo2Bytes(Ptr) armAlignToBytes(Ptr,2)
+#define armAlignTo4Bytes(Ptr) armAlignToBytes(Ptr,4)
+#define armAlignTo8Bytes(Ptr) armAlignToBytes(Ptr,8)
+#define armAlignTo16Bytes(Ptr) armAlignToBytes(Ptr,16)
+
+/* Error and Alignment check */
+
+#define armRetArgErrIf(condition, code) if(condition) { return (code); }
+#define armRetDataErrIf(condition, code) if(condition) { return (code); }
+
+#ifndef ALIGNMENT_DOESNT_MATTER
+#define armIsByteAligned(Ptr,N) ((((int)(Ptr)) % N)==0)
+#define armNotByteAligned(Ptr,N) ((((int)(Ptr)) % N)!=0)
+#else
+#define armIsByteAligned(Ptr,N) (1)
+#define armNotByteAligned(Ptr,N) (0)
+#endif
+
+#define armIs2ByteAligned(Ptr) armIsByteAligned(Ptr,2)
+#define armIs4ByteAligned(Ptr) armIsByteAligned(Ptr,4)
+#define armIs8ByteAligned(Ptr) armIsByteAligned(Ptr,8)
+#define armIs16ByteAligned(Ptr) armIsByteAligned(Ptr,16)
+
+#define armNot2ByteAligned(Ptr) armNotByteAligned(Ptr,2)
+#define armNot4ByteAligned(Ptr) armNotByteAligned(Ptr,4)
+#define armNot8ByteAligned(Ptr) armNotByteAligned(Ptr,8)
+#define armNot16ByteAligned(Ptr) armNotByteAligned(Ptr,16)
+#define armNot32ByteAligned(Ptr) armNotByteAligned(Ptr,32)
+
+/**
+ * Function: armRoundFloatToS16_ref/armRoundFloatToS32_ref/armRoundFloatToS64
+ *
+ * Description:
+ * Converts a double precision value into a short int/int after rounding
+ *
+ * Parameters:
+ * [in] Value Float value to be converted
+ *
+ * Return Value:
+ * [out] converted value in OMX_S16/OMX_S32 format
+ *
+ */
+
+OMX_S16 armRoundFloatToS16 (OMX_F64 Value);
+OMX_S32 armRoundFloatToS32 (OMX_F64 Value);
+OMX_S64 armRoundFloatToS64 (OMX_F64 Value);
+
+/**
+ * Function: armSatRoundFloatToS16_ref/armSatRoundFloatToS32
+ *
+ * Description:
+ * Converts a double precision value into a short int/int after rounding and saturation
+ *
+ * Parameters:
+ * [in] Value Float value to be converted
+ *
+ * Return Value:
+ * [out] converted value in OMX_S16/OMX_S32 format
+ *
+ */
+
+OMX_S16 armSatRoundFloatToS16 (OMX_F64 Value);
+OMX_S32 armSatRoundFloatToS32 (OMX_F64 Value);
+
+/**
+ * Function: armSatRoundFloatToU16_ref/armSatRoundFloatToU32
+ *
+ * Description:
+ * Converts a double precision value into a unsigned short int/int after rounding and saturation
+ *
+ * Parameters:
+ * [in] Value Float value to be converted
+ *
+ * Return Value:
+ * [out] converted value in OMX_U16/OMX_U32 format
+ *
+ */
+
+OMX_U16 armSatRoundFloatToU16 (OMX_F64 Value);
+OMX_U32 armSatRoundFloatToU32 (OMX_F64 Value);
+
+/**
+ * Function: armSignCheck
+ *
+ * Description:
+ * Checks the sign of a variable:
+ * returns 1 if it is Positive
+ * returns 0 if it is 0
+ * returns -1 if it is Negative
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] var Variable to be checked
+ *
+ * Return Value:
+ * OMX_INT -- returns 1 if it is Positive
+ * returns 0 if it is 0
+ * returns -1 if it is Negative
+ */
+
+OMX_INT armSignCheck (OMX_S16 var);
+
+/**
+ * Function: armClip
+ *
+ * Description: Clips the input between MAX and MIN value
+ *
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] Min lower bound
+ * [in] Max upper bound
+ * [in] src variable to the clipped
+ *
+ * Return Value:
+ * OMX_S32 -- returns clipped value
+ */
+
+OMX_S32 armClip (
+ OMX_INT min,
+ OMX_INT max,
+ OMX_S32 src
+ );
+
+/**
+ * Function: armClip_F32
+ *
+ * Description: Clips the input between MAX and MIN value
+ *
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] Min lower bound
+ * [in] Max upper bound
+ * [in] src variable to the clipped
+ *
+ * Return Value:
+ * OMX_F32 -- returns clipped value
+ */
+
+OMX_F32 armClip_F32 (
+ OMX_F32 min,
+ OMX_F32 max,
+ OMX_F32 src
+ );
+
+/**
+ * Function: armShiftSat_F32
+ *
+ * Description: Divides a float value by 2^shift and
+ * saturates it for unsigned value range for satBits.
+ * Second parameter is like "shifting" the corresponding
+ * integer value. Takes care of rounding while clipping the final
+ * value.
+ *
+ * Parameters:
+ * [in] v Number to be operated upon
+ * [in] shift Divides the input "v" by "2^shift"
+ * [in] satBits Final range is [0, 2^satBits)
+ *
+ * Return Value:
+ * OMX_S32 -- returns "shifted" saturated value
+ */
+
+OMX_U32 armShiftSat_F32(
+ OMX_F32 v,
+ OMX_INT shift,
+ OMX_INT satBits
+ );
+
+/**
+ * Functions: armSwapElem
+ *
+ * Description:
+ * This function swaps two elements at the specified pointer locations.
+ * The size of each element could be anything as specified by <elemSize>
+ *
+ * Return Value:
+ * OMXResult -- Error status from the function
+ */
+OMXResult armSwapElem(OMX_U8 *pBuf1, OMX_U8 *pBuf2, OMX_INT elemSize);
+
+
+/**
+ * Function: armMedianOf3
+ *
+ * Description: Finds the median of three numbers
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] fEntry First entry
+ * [in] sEntry second entry
+ * [in] tEntry Third entry
+ *
+ * Return Value:
+ * OMX_S32 -- returns the median value
+ */
+
+OMX_S32 armMedianOf3 (
+ OMX_S32 fEntry,
+ OMX_S32 sEntry,
+ OMX_S32 tEntry
+ );
+
+/**
+ * Function: armLogSize
+ *
+ * Description: Finds the size of a positive value and returns the same
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] value Positive value
+ *
+ * Return Value:
+ * OMX_U8 -- returns the size of the positive value
+ */
+
+OMX_U8 armLogSize (
+ OMX_U16 value
+ );
+
+/***********************************************************************/
+ /* Saturating Arithmetic operations */
+
+/**
+ * Function :armSatAdd_S32()
+ *
+ * Description :
+ * Returns the result of saturated addition of the two inputs Value1, Value2
+ *
+ * Parametrs:
+ * [in] Value1 First Operand
+ * [in] Value2 Second Operand
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ *
+ **/
+
+OMX_S32 armSatAdd_S32(
+ OMX_S32 Value1,
+ OMX_S32 Value2
+ );
+
+/**
+ * Function :armSatAdd_S64()
+ *
+ * Description :
+ * Returns the result of saturated addition of the two inputs Value1, Value2
+ *
+ * Parametrs:
+ * [in] Value1 First Operand
+ * [in] Value2 Second Operand
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ *
+ **/
+
+OMX_S64 armSatAdd_S64(
+ OMX_S64 Value1,
+ OMX_S64 Value2
+ );
+
+/** Function :armSatSub_S32()
+ *
+ * Description :
+ * Returns the result of saturated substraction of the two inputs Value1, Value2
+ *
+ * Parametrs:
+ * [in] Value1 First Operand
+ * [in] Value2 Second Operand
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ **/
+
+OMX_S32 armSatSub_S32(
+ OMX_S32 Value1,
+ OMX_S32 Value2
+ );
+
+/**
+ * Function :armSatMac_S32()
+ *
+ * Description :
+ * Returns the result of Multiplication of Value1 and Value2 and subesquent saturated
+ * accumulation with Mac
+ *
+ * Parametrs:
+ * [in] Value1 First Operand
+ * [in] Value2 Second Operand
+ * [in] Mac Accumulator
+ *
+ * Return:
+ * [out] Result of operation
+ **/
+
+OMX_S32 armSatMac_S32(
+ OMX_S32 Mac,
+ OMX_S16 Value1,
+ OMX_S16 Value2
+ );
+
+/**
+ * Function :armSatMac_S16S32_S32
+ *
+ * Description :
+ * Returns the result of saturated MAC operation of the three inputs delayElem, filTap , mac
+ *
+ * mac = mac + Saturate_in_32Bits(delayElem * filTap)
+ *
+ * Parametrs:
+ * [in] delayElem First 32 bit Operand
+ * [in] filTap Second 16 bit Operand
+ * [in] mac Result of MAC operation
+ *
+ * Return:
+ * [out] mac Result of operation
+ *
+ **/
+
+OMX_S32 armSatMac_S16S32_S32(
+ OMX_S32 mac,
+ OMX_S32 delayElem,
+ OMX_S16 filTap );
+
+/**
+ * Function :armSatRoundRightShift_S32_S16
+ *
+ * Description :
+ * Returns the result of rounded right shift operation of input by the scalefactor
+ *
+ * output = Saturate_in_16Bits( ( RightShift( (Round(input) , scaleFactor ) )
+ *
+ * Parametrs:
+ * [in] input The input to be operated on
+ * [in] scaleFactor The shift number
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ **/
+
+
+OMX_S16 armSatRoundRightShift_S32_S16(
+ OMX_S32 input,
+ OMX_INT scaleFactor);
+
+/**
+ * Function :armSatRoundLeftShift_S32()
+ *
+ * Description :
+ * Returns the result of saturating left-shift operation on input
+ * Or rounded Right shift if the input Shift is negative.
+ *
+ * Parametrs:
+ * [in] Value Operand
+ * [in] shift Operand for shift operation
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ **/
+
+OMX_S32 armSatRoundLeftShift_S32(
+ OMX_S32 Value,
+ OMX_INT shift
+ );
+
+/**
+ * Function :armSatRoundLeftShift_S64()
+ *
+ * Description :
+ * Returns the result of saturating left-shift operation on input
+ * Or rounded Right shift if the input Shift is negative.
+ *
+ * Parametrs:
+ * [in] Value Operand
+ * [in] shift Operand for shift operation
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ **/
+
+OMX_S64 armSatRoundLeftShift_S64(
+ OMX_S64 Value,
+ OMX_INT shift
+ );
+
+/**
+ * Function :armSatMulS16S32_S32()
+ *
+ * Description :
+ * Returns the result of a S16 data type multiplied with an S32 data type
+ * in a S32 container
+ *
+ * Parametrs:
+ * [in] input1 Operand 1
+ * [in] input2 Operand 2
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ **/
+
+
+OMX_S32 armSatMulS16S32_S32(
+ OMX_S16 input1,
+ OMX_S32 input2);
+
+/**
+ * Function :armSatMulS32S32_S32()
+ *
+ * Description :
+ * Returns the result of a S32 data type multiplied with an S32 data type
+ * in a S32 container
+ *
+ * Parametrs:
+ * [in] input1 Operand 1
+ * [in] input2 Operand 2
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ **/
+
+OMX_S32 armSatMulS32S32_S32(
+ OMX_S32 input1,
+ OMX_S32 input2);
+
+
+/**
+ * Function :armIntDivAwayFromZero()
+ *
+ * Description : Integer division with rounding to the nearest integer.
+ * Half-integer values are rounded away from zero
+ * unless otherwise specified. For example 3//2 is rounded
+ * to 2, and -3//2 is rounded to -2.
+ *
+ * Parametrs:
+ * [in] Num Operand 1
+ * [in] Deno Operand 2
+ *
+ * Return:
+ * [out] Result of operation input1//input2
+ *
+ **/
+
+OMX_S32 armIntDivAwayFromZero (OMX_S32 Num, OMX_S32 Deno);
+
+
+/***********************************************************************/
+/*
+ * Debugging macros
+ *
+ */
+
+
+/*
+ * Definition of output stream - change to stderr if necessary
+ */
+#define DEBUG_STREAM stdout
+
+/*
+ * Debug printf macros, one for each argument count.
+ * Add more if needed.
+ */
+#ifdef DEBUG_ON
+#include <stdio.h>
+
+#define DEBUG_PRINTF_0(a) fprintf(DEBUG_STREAM, a)
+#define DEBUG_PRINTF_1(a, b) fprintf(DEBUG_STREAM, a, b)
+#define DEBUG_PRINTF_2(a, b, c) fprintf(DEBUG_STREAM, a, b, c)
+#define DEBUG_PRINTF_3(a, b, c, d) fprintf(DEBUG_STREAM, a, b, c, d)
+#define DEBUG_PRINTF_4(a, b, c, d, e) fprintf(DEBUG_STREAM, a, b, c, d, e)
+#define DEBUG_PRINTF_5(a, b, c, d, e, f) fprintf(DEBUG_STREAM, a, b, c, d, e, f)
+#define DEBUG_PRINTF_6(a, b, c, d, e, f, g) fprintf(DEBUG_STREAM, a, b, c, d, e, f, g)
+#define DEBUG_PRINTF_7(a, b, c, d, e, f, g, h) fprintf(DEBUG_STREAM, a, b, c, d, e, f, g, h)
+#define DEBUG_PRINTF_8(a, b, c, d, e, f, g, h, i) fprintf(DEBUG_STREAM, a, b, c, d, e, f, g, h, i)
+#define DEBUG_PRINTF_9(a, b, c, d, e, f, g, h, i, j) fprintf(DEBUG_STREAM, a, b, c, d, e, f, g, h, i, j)
+#define DEBUG_PRINTF_10(a, b, c, d, e, f, g, h, i, j, k) fprintf(DEBUG_STREAM, a, b, c, d, e, f, g, h, i, j, k)
+#define DEBUG_PRINTF_11(a, b, c, d, e, f, g, h, i, j, k, l) fprintf(DEBUG_STREAM, a, b, c, d, e, f, g, h, i, j, k, l)
+#define DEBUG_PRINTF_12(a, b, c, d, e, f, g, h, i, j, k, l, m) fprintf(DEBUG_STREAM, a, b, c, d, e, f, g, h, i, j, k, l, m)
+#define DEBUG_PRINTF_13(a, b, c, d, e, f, g, h, i, j, k, l, m, n) fprintf(DEBUG_STREAM, a, b, c, d, e, f, g, h, i, j, k, l, m, n)
+#define DEBUG_PRINTF_14(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) fprintf(DEBUG_STREAM, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)
+#else /* DEBUG_ON */
+#define DEBUG_PRINTF_0(a)
+#define DEBUG_PRINTF_1(a, b)
+#define DEBUG_PRINTF_2(a, b, c)
+#define DEBUG_PRINTF_3(a, b, c, d)
+#define DEBUG_PRINTF_4(a, b, c, d, e)
+#define DEBUG_PRINTF_5(a, b, c, d, e, f)
+#define DEBUG_PRINTF_6(a, b, c, d, e, f, g)
+#define DEBUG_PRINTF_7(a, b, c, d, e, f, g, h)
+#define DEBUG_PRINTF_8(a, b, c, d, e, f, g, h, i)
+#define DEBUG_PRINTF_9(a, b, c, d, e, f, g, h, i, j)
+#define DEBUG_PRINTF_10(a, b, c, d, e, f, g, h, i, j, k)
+#define DEBUG_PRINTF_11(a, b, c, d, e, f, g, h, i, j, k, l)
+#define DEBUG_PRINTF_12(a, b, c, d, e, f, g, h, i, j, k, l, m)
+#define DEBUG_PRINTF_13(a, b, c, d, e, f, g, h, i, j, k, l, m, n)
+#define DEBUG_PRINTF_14(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)
+#endif /* DEBUG_ON */
+
+
+/*
+ * Domain and sub domain definitions
+ *
+ * In order to turn on debug for an entire domain or sub-domain
+ * at compile time, one of the DEBUG_DOMAIN_* below may be defined,
+ * which will activate debug in all of the defines it contains.
+ */
+
+#ifdef DEBUG_DOMAIN_AC
+#define DEBUG_OMXACAAC_DECODECHANPAIRELT_MPEG4
+#define DEBUG_OMXACAAC_DECODECHANPAIRELT
+#define DEBUG_OMXACAAC_DECODEDATSTRELT
+#define DEBUG_OMXACAAC_DECODEFILLELT
+#define DEBUG_OMXACAAC_DECODEISSTEREO_S32
+#define DEBUG_OMXACAAC_DECODEMSPNS_S32
+#define DEBUG_OMXACAAC_DECODEMSSTEREO_S32_I
+#define DEBUG_OMXACAAC_DECODEPRGCFGELT
+#define DEBUG_OMXACAAC_DECODETNS_S32_I
+#define DEBUG_OMXACAAC_DEINTERLEAVESPECTRUM_S32
+#define DEBUG_OMXACAAC_ENCODETNS_S32_I
+#define DEBUG_OMXACAAC_LONGTERMPREDICT_S32
+#define DEBUG_OMXACAAC_LONGTERMRECONSTRUCT_S32
+#define DEBUG_OMXACAAC_MDCTFWD_S32
+#define DEBUG_OMXACAAC_MDCTINV_S32_S16
+#define DEBUG_OMXACAAC_NOISELESSDECODE
+#define DEBUG_OMXACAAC_QUANTINV_S32_I
+#define DEBUG_OMXACAAC_UNPACKADIFHEADER
+#define DEBUG_OMXACAAC_UNPACKADTSFRAMEHEADER
+#define DEBUG_OMXACMP3_HUFFMANDECODESFBMBP_S32
+#define DEBUG_OMXACMP3_HUFFMANDECODESFB_S32
+#define DEBUG_OMXACMP3_HUFFMANDECODE_S32
+#define DEBUG_OMXACMP3_MDCTINV_S32
+#define DEBUG_OMXACMP3_REQUANTIZESFB_S32_I
+#define DEBUG_OMXACMP3_REQUANTIZE_S32_I
+#define DEBUG_OMXACMP3_SYNTHPQMF_S32_S16
+#define DEBUG_OMXACMP3_UNPACKFRAMEHEADER
+#define DEBUG_OMXACMP3_UNPACKSCALEFACTORS_S8
+#define DEBUG_OMXACMP3_UNPACKSIDEINFO
+#endif /* DEBUG_DOMAIN_AC */
+
+
+#ifdef DEBUG_DOMAIN_VC
+#define DEBUG_OMXVCM4P10_AVERAGE_16X
+#define DEBUG_OMXVCM4P10_AVERAGE_4X
+#define DEBUG_OMXVCM4P10_AVERAGE_8X
+#define DEBUG_OMXVCM4P10_DEBLOCKCHROMA_U8_C1IR
+#define DEBUG_OMXVCM4P10_DEBLOCKLUMA_U8_C1IR
+#define DEBUG_OMXVCM4P10_DECODECHROMADCCOEFFSTOPAIRCAVLC_U8
+#define DEBUG_OMXVCM4P10_DECODECOEFFSTOPAIRCAVLC_U8
+#define DEBUG_OMXVCM4P10_DEQUANTTRANSFORMACFROMPAIR_U8_S16_C1_DLX
+#define DEBUG_OMXVCM4P10_EXPANDFRAME
+#define DEBUG_OMXVCM4P10_FILTERDEBLOCKINGCHROMA_HOREDGE_U8_C1IR
+#define DEBUG_OMXVCM4P10_FILTERDEBLOCKINGCHROMA_VEREDGE_U8_C1IR
+#define DEBUG_OMXVCM4P10_FILTERDEBLOCKINGLUMA_HOREDGE_U8_C1IR
+#define DEBUG_OMXVCM4P10_FILTERDEBLOCKINGLUMA_VEREDGE_U8_C1IR
+#define DEBUG_OMXVCM4P10_PREDICTINTRACHROMA8X8_U8_C1R
+#define DEBUG_OMXVCM4P10_PREDICTINTRA_16X16_U8_C1R
+#define DEBUG_OMXVCM4P10_PREDICTINTRA_4X4_U8_C1R
+#define DEBUG_OMXVCM4P10_SADQUAR_16X
+#define DEBUG_OMXVCM4P10_SADQUAR_4X
+#define DEBUG_OMXVCM4P10_SADQUAR_8X
+#define DEBUG_OMXVCM4P10_SAD_16X
+#define DEBUG_OMXVCM4P10_SAD_4X
+#define DEBUG_OMXVCM4P10_SAD_8X
+#define DEBUG_OMXVCM4P10_SATD_4X4
+#define DEBUG_OMXVCM4P10_TRANSFORMDEQUANTCHROMADCFROMPAIR_U8_S16_C1
+#define DEBUG_OMXVCM4P10_TRANSFORMDEQUANTLUMADCFROMPAIR_U8_S16_C1
+#define DEBUG_OMXVCM4P10_TRANSFORMQUANT_CHROMADC
+#define DEBUG_OMXVCM4P10_TRANSFORMQUANT_LUMADC
+#define DEBUG_OMXVCM4P2_BLOCKMATCH_HALF_16X16
+#define DEBUG_OMXVCM4P2_BLOCKMATCH_HALF_8X8
+#define DEBUG_OMXVCM4P2_BLOCKMATCH_INTEGER_16X16
+#define DEBUG_OMXVCM4P2_BLOCKMATCH_INTEGER_8X8
+#define DEBUG_OMXVCM4P2_COMPUTETEXTUREERRORBLOCK_SAD_U8_S16
+#define DEBUG_OMXVCM4P2_COMPUTETEXTUREERRORBLOCK_U8_S16
+#define DEBUG_OMXVCM4P2_DCT8X8BLKDLX
+#define DEBUG_OMXVCM4P2_DECODEBLOCKCOEF_INTER_S16
+#define DEBUG_OMXVCM4P2_DECODEPADMV_PVOP
+#define DEBUG_OMXVCM4P2_DECODEVLCZIGZAG_INTER_S16
+#define DEBUG_OMXVCM4P2_DECODEVLCZIGZAG_INTRAACVLC_S16
+#define DEBUG_OMXVCM4P2_DECODEVLCZIGZAG_INTRADCVLC_S16
+#define DEBUG_OMXVCM4P2_ENCODEMV_U8_S16
+#define DEBUG_OMXVCM4P2_ENCODEVLCZIGZAG_INTER_S16
+#define DEBUG_OMXVCM4P2_ENCODEVLCZIGZAG_INTRAACVLC_S16
+#define DEBUG_OMXVCM4P2_ENCODEVLCZIGZAG_INTRADCVLC_S16
+#define DEBUG_OMXVCM4P2_FINDMVPRED
+#define DEBUG_OMXVCM4P2_IDCT8X8BLKDLX
+#define DEBUG_OMXVCM4P2_LIMITMVTORECT
+#define DEBUG_OMXVCM4P2_MOTIONESTIMATIONMB
+#define DEBUG_OMXVCM4P2_PADMBGRAY_U8
+#define DEBUG_OMXVCM4P2_PADMBHORIZONTAL_U8
+#define DEBUG_OMXVCM4P2_PADMBVERTICAL_U8
+#define DEBUG_OMXVCM4P2_PADMV
+#define DEBUG_OMXVCM4P2_QUANTINTER_S16_I
+#define DEBUG_OMXVCM4P2_QUANTINTRA_S16_I
+#define DEBUG_OMXVCM4P2_QUANTINVINTER_S16_I
+#define DEBUG_OMXVCM4P2_QUANTINVINTRA_S16_I
+#define DEBUG_OMXVCM4P2_TRANSRECBLOCKCEOF_INTER
+#define DEBUG_OMXVCM4P2_TRANSRECBLOCKCEOF_INTRA
+#endif /* DEBUG_DOMAIN_VC */
+
+
+#ifdef DEBUG_DOMAIN_IC
+/* To be filled in */
+#endif /* DEBUG_DOMAIN_IC */
+
+
+#ifdef DEBUG_DOMAIN_SP
+#define DEBUG_OMXACSP_DOTPROD_S16
+#define DEBUG_OMXACSP_BLOCKEXP_S16
+#define DEBUG_OMXACSP_BLOCKEXP_S32
+#define DEBUG_OMXACSP_COPY_S16
+#define DEBUG_OMXACSP_DOTPROD_S16
+#define DEBUG_OMXACSP_DOTPROD_S16_SFS
+#define DEBUG_OMXACSP_FFTFWD_CTOC_SC16_SFS
+#define DEBUG_OMXACSP_FFTFWD_CTOC_SC32_SFS
+#define DEBUG_OMXACSP_FFTFWD_RTOCCS_S16S32_SFS
+#define DEBUG_OMXACSP_FFTFWD_RTOCCS_S32_SFS
+#define DEBUG_OMXACSP_FFTGETBUFSIZE_C_SC16
+#define DEBUG_OMXACSP_FFTGETBUFSIZE_C_SC32
+#define DEBUG_OMXACSP_FFTGETBUFSIZE_R_S16_S32
+#define DEBUG_OMXACSP_FFTGETBUFSIZE_R_S32
+#define DEBUG_OMXACSP_FFTINIT_C_SC16
+#define DEBUG_OMXACSP_FFTINIT_C_SC32
+#define DEBUG_OMXACSP_FFTINIT_R_S16_S32
+#define DEBUG_OMXACSP_FFTINIT_R_S32
+#define DEBUG_OMXACSP_FFTINV_CCSTOR_S32S16_SFS
+#define DEBUG_OMXACSP_FFTINV_CCSTOR_S32_SFS
+#define DEBUG_OMXACSP_FFTINV_CTOC_SC16_SFS
+#define DEBUG_OMXACSP_FFTINV_CTOC_SC32_SFS
+#define DEBUG_OMXACSP_FILTERMEDIAN_S32_I
+#define DEBUG_OMXACSP_FILTERMEDIAN_S32
+#define DEBUG_OMXACSP_FIRONE_DIRECT_S16_ISFS
+#define DEBUG_OMXACSP_FIRONE_DIRECT_S16_I
+#define DEBUG_OMXACSP_FIRONE_DIRECT_S16
+#define DEBUG_OMXACSP_FIRONE_DIRECT_S16_SFS
+#define DEBUG_OMXACSP_FIR_DIRECT_S16_ISFS
+#define DEBUG_OMXACSP_FIR_DIRECT_S16_I
+#define DEBUG_OMXACSP_FIR_DIRECT_S16
+#define DEBUG_OMXACSP_FIR_DIRECT_S16_SFS
+#define DEBUG_OMXACSP_IIRONE_BIQUADDIRECT_S16_I
+#define DEBUG_OMXACSP_IIRONE_BIQUADDIRECT_S16
+#define DEBUG_OMXACSP_IIRONE_DIRECT_S16_I
+#define DEBUG_OMXACSP_IIRONE_DIRECT_S16
+#define DEBUG_OMXACSP_IIR_BIQUADDIRECT_S16_I
+#define DEBUG_OMXACSP_IIR_BIQUADDIRECT_S16
+#define DEBUG_OMXACSP_IIR_DIRECT_S16_I
+#define DEBUG_OMXACSP_IIR_DIRECT_S16
+#endif /* DEBUG_DOMAIN_SP */
+
+
+#ifdef DEBUG_DOMAIN_IP
+#define DEBUG_OMXIPBM_ADDC_U8_C1R_SFS
+#define DEBUG_OMXIPBM_COPY_U8_C1R
+#define DEBUG_OMXIPBM_COPY_U8_C3R
+#define DEBUG_OMXIPBM_MIRROR_U8_C1R
+#define DEBUG_OMXIPBM_MULC_U8_C1R_SFS
+#define DEBUG_OMXIPCS_COLORTWISTQ14_U8_C3R
+#define DEBUG_OMXIPCS_RGB565TOYCBCR420LS_MCU_U16_S16_C3P3R
+#define DEBUG_OMXIPCS_RGB565TOYCBCR422LS_MCU_U16_S16_C3P3R
+#define DEBUG_OMXIPCS_RGB565TOYCBCR444LS_MCU_U16_S16_C3P3R
+#define DEBUG_OMXIPCS_RGBTOYCBCR420LS_MCU_U8_S16_C3P3R
+#define DEBUG_OMXIPCS_RGBTOYCBCR422LS_MCU_U8_S16_C3P3R
+#define DEBUG_OMXIPCS_RGBTOYCBCR444LS_MCU_U8_S16_C3P3R
+#define DEBUG_OMXIPCS_YCBCR420RSZROT_U8_P3R
+#define DEBUG_OMXIPCS_YCBCR420TORGB565LS_MCU_S16_U16_P3C3R
+#define DEBUG_OMXIPCS_YCBCR420TORGB565_U8_U16_P3C3R
+#define DEBUG_OMXIPCS_YCBCR420TORGBLS_MCU_S16_U8_P3C3R
+#define DEBUG_OMXIPCS_YCBCR422RSZCSCROTRGB_U8_C2R
+#define DEBUG_OMXIPCS_YCBCR422RSZROT_U8_P3R
+#define DEBUG_OMXIPCS_YCBCR422TORGB565LS_MCU_S16_U16_P3C3R
+#define DEBUG_OMXIPCS_YCBCR422TORGB565_U8_U16_C2C3R
+#define DEBUG_OMXIPCS_YCBCR422TORGBLS_MCU_S16_U8_P3C3R
+#define DEBUG_OMXIPCS_YCBCR422TORGB_U8_C2C3R
+#define DEBUG_OMXIPCS_YCBCR422TOYCBCR420ROTATE_U8_C2P3R
+#define DEBUG_OMXIPCS_YCBCR422TOYCBCR420ROTATE_U8_P3R
+#define DEBUG_OMXIPCS_YCBCR444TORGB565LS_MCU_S16_U16_P3C3R
+#define DEBUG_OMXIPCS_YCBCR444TORGBLS_MCU_S16_U8_P3C3R
+#define DEBUG_OMXIPCS_YCBCRTORGB565_U8_U16_C3R
+#define DEBUG_OMXIPCS_YCBCRTORGB565_U8_U16_P3C3R
+#define DEBUG_OMXIPCS_YCBCRTORGB_U8_C3R
+#define DEBUG_OMXIPPP_GETCENTRALMOMENT_S64
+#define DEBUG_OMXIPPP_GETSPATIALMOMENT_S64
+#define DEBUG_OMXIPPP_MOMENTGETSTATESIZE_S64
+#define DEBUG_OMXIPPP_MOMENTINIT_S64
+#define DEBUG_OMXIPPP_MOMENTS64S_U8_C1R
+#define DEBUG_OMXIPPP_MOMENTS64S_U8_C3R
+#endif /* DEBUG_DOMAIN_IP */
+
+
+#endif /* _armCommon_H_ */
+
+/*End of File*/
+
+
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_BitDec_s.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_BitDec_s.h
new file mode 100644
index 0000000..abb98fc
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_BitDec_s.h
@@ -0,0 +1,670 @@
+;//
+;//
+;// File Name: armCOMM_BitDec_s.h
+;// OpenMAX DL: v1.0.2
+;// Revision: 9641
+;// Date: Thursday, February 7, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+;// OpenMAX optimized bitstream decode module
+;//
+;// You must include armCOMM_s.h before including this file
+;//
+;// This module provides macros to perform assembly optimized fixed and
+;// variable length decoding from a read-only bitstream. The variable
+;// length decode modules take as input a pointer to a table of 16-bit
+;// entries of the following format.
+;//
+;// VLD Table Entry format
+;//
+;// 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
+;// +------------------------------------------------+
+;// | Len | Symbol | 1 |
+;// +------------------------------------------------+
+;// | Offset | 0 |
+;// +------------------------------------------------+
+;//
+;// If the table entry is a leaf entry then bit 0 set:
+;// Len = Number of bits overread (0 to 7)
+;// Symbol = Symbol payload (unsigned 12 bits)
+;//
+;// If the table entry is an internal node then bit 0 is clear:
+;// Offset = Number of (16-bit) half words from the table
+;// start to the next table node
+;//
+;// The table is accessed by successive lookup up on the
+;// next Step bits of the input bitstream until a leaf node
+;// is obtained. The Step sizes are supplied to the VLD macro.
+;//
+;// USAGE:
+;//
+;// To use any of the macros in this package, first call:
+;//
+;// M_BD_INIT ppBitStream, pBitOffset, pBitStream, RBitBuffer, RBitCount, Tmp
+;//
+;// This caches the current bitstream position and next available
+;// bits in registers pBitStream, RBitBuffer, RBitCount. These registers
+;// are reserved for use by the bitstream decode package until you
+;// call M_BD_FINI.
+;//
+;// Next call the following macro(s) as many times as you need:
+;//
+;// M_BD_LOOK8 - Look ahead constant 1<=N<=8 bits into the bitstream
+;// M_BD_LOOK16 - Look ahead constant 1<=N<=16 bits into the bitstream
+;// M_BD_READ8 - Read constant 1<=N<=8 bits from the bitstream
+;// M_BD_READ16 - Read constant 1<=N<=16 bits from the bitstream
+;// M_BD_VREAD8 - Read variable 1<=N<=8 bits from the bitstream
+;// M_BD_VREAD16 - Read variable 1<=N<=16 bits from the bitstream
+;// M_BD_VLD - Perform variable length decode using lookup table
+;//
+;// Finally call the macro:
+;//
+;// M_BD_FINI ppBitStream, pBitOffset
+;//
+;// This writes the bitstream state back to memory.
+;//
+;// The three bitstream cache register names are assigned to the following global
+;// variables:
+;//
+
+ GBLS pBitStream ;// Register name for pBitStream
+ GBLS BitBuffer ;// Register name for BitBuffer
+ GBLS BitCount ;// Register name for BitCount
+
+;//
+;// These register variables must have a certain defined state on entry to every bitstream
+;// macro (except M_BD_INIT) and on exit from every bitstream macro (except M_BD_FINI).
+;// The state may depend on implementation.
+;//
+;// For the default (ARM11) implementation the following hold:
+;// pBitStream - points to the first byte not held in the BitBuffer
+;// BitBuffer - is a cache of (4 bytes) 32 bits, bit 31 the first bit
+;// BitCount - is offset (from the top bit) to the next unused bitstream bit
+;// 0<=BitCount<=15 (so BitBuffer holds at least 17 unused bits)
+;//
+;//
+
+ ;// Bitstream Decode initialise
+ ;//
+ ;// Initialises the bitstream decode global registers from
+ ;// bitstream pointers. This macro is split into 3 parts to enable
+ ;// scheduling.
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// $ppBitStream - pointer to pointer to the next bitstream byte
+ ;// $pBitOffset - pointer to the number of bits used in the current byte (0..7)
+ ;// $RBitStream - register to use for pBitStream (can be $ppBitStream)
+ ;// $RBitBuffer - register to use for BitBuffer
+ ;// $RBitCount - register to use for BitCount (can be $pBitOffset)
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// $T1,$T2,$T3 - registers that must be preserved between calls to
+ ;// M_BD_INIT1 and M_BD_INIT2
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ MACRO
+ M_BD_INIT0 $ppBitStream, $pBitOffset, $RBitStream, $RBitBuffer, $RBitCount
+
+pBitStream SETS "$RBitStream"
+BitBuffer SETS "$RBitBuffer"
+BitCount SETS "$RBitCount"
+
+ ;// load inputs
+ LDR $pBitStream, [$ppBitStream]
+ LDR $BitCount, [$pBitOffset]
+ MEND
+
+ MACRO
+ M_BD_INIT1 $T1, $T2, $T3
+ LDRB $T2, [$pBitStream, #2]
+ LDRB $T1, [$pBitStream, #1]
+ LDRB $BitBuffer, [$pBitStream], #3
+ ADD $BitCount, $BitCount, #8
+ MEND
+
+ MACRO
+ M_BD_INIT2 $T1, $T2, $T3
+ ORR $T2, $T2, $T1, LSL #8
+ ORR $BitBuffer, $T2, $BitBuffer, LSL #16
+ MEND
+
+ ;//
+ ;// Look ahead fixed 1<=N<=8 bits without consuming any bits
+ ;// The next bits will be placed at bit 31..24 of destination register
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// $N - number of bits to look
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// $Symbol - the next N bits of the bitstream
+ ;// $T1 - corrupted temp/scratch register
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ MACRO
+ M_BD_LOOK8 $Symbol, $N
+ ASSERT ($N>=1):LAND:($N<=8)
+ MOV $Symbol, $BitBuffer, LSL $BitCount
+ MEND
+
+ ;//
+ ;// Look ahead fixed 1<=N<=16 bits without consuming any bits
+ ;// The next bits will be placed at bit 31..16 of destination register
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// $N - number of bits to look
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// $Symbol - the next N bits of the bitstream
+ ;// $T1 - corrupted temp/scratch register
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ MACRO
+ M_BD_LOOK16 $Symbol, $N, $T1
+ ASSERT ($N >= 1):LAND:($N <= 16)
+ MOV $Symbol, $BitBuffer, LSL $BitCount
+ MEND
+
+ ;//
+ ;// Skips fixed 1<=N<=8 bits from the bitstream, advancing the bitstream pointer
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// $N - number of bits
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// $T1 - corrupted temp/scratch register
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ MACRO
+ M_BD_SKIP8 $N, $T1
+ ASSERT ($N>=1):LAND:($N<=8)
+ SUBS $BitCount, $BitCount, #(8-$N)
+ LDRCSB $T1, [$pBitStream], #1
+ ADDCC $BitCount, $BitCount, #8
+ ORRCS $BitBuffer, $T1, $BitBuffer, LSL #8
+ MEND
+
+
+ ;//
+ ;// Read fixed 1<=N<=8 bits from the bitstream, advancing the bitstream pointer
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// $N - number of bits to read
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// $Symbol - the next N bits of the bitstream
+ ;// $T1 - corrupted temp/scratch register
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ MACRO
+ M_BD_READ8 $Symbol, $N, $T1
+ ASSERT ($N>=1):LAND:($N<=8)
+ MOVS $Symbol, $BitBuffer, LSL $BitCount
+ SUBS $BitCount, $BitCount, #(8-$N)
+ LDRCSB $T1, [$pBitStream], #1
+ ADDCC $BitCount, $BitCount, #8
+ MOV $Symbol, $Symbol, LSR #(32-$N)
+ ORRCS $BitBuffer, $T1, $BitBuffer, LSL #8
+ MEND
+
+ ;//
+ ;// Read fixed 1<=N<=16 bits from the bitstream, advancing the bitstream pointer
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// $N - number of bits to read
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// $Symbol - the next N bits of the bitstream
+ ;// $T1 - corrupted temp/scratch register
+ ;// $T2 - corrupted temp/scratch register
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ MACRO
+ M_BD_READ16 $Symbol, $N, $T1, $T2
+ ASSERT ($N>=1):LAND:($N<=16)
+ ASSERT $Symbol<>$T1
+ IF ($N<=8)
+ M_BD_READ8 $Symbol, $N, $T1
+ ELSE
+ ;// N>8 so we will be able to refill at least one byte
+ LDRB $T1, [$pBitStream], #1
+ MOVS $Symbol, $BitBuffer, LSL $BitCount
+ ORR $BitBuffer, $T1, $BitBuffer, LSL #8
+ SUBS $BitCount, $BitCount, #(16-$N)
+ LDRCSB $T1, [$pBitStream], #1
+ MOV $Symbol, $Symbol, LSR #(32-$N)
+ ADDCC $BitCount, $BitCount, #8
+ ORRCS $BitBuffer, $T1, $BitBuffer, LSL #8
+ ENDIF
+ MEND
+
+ ;//
+ ;// Skip variable 1<=N<=8 bits from the bitstream, advancing the bitstream pointer.
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// $N - number of bits. 1<=N<=8
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// $T1 - corrupted temp/scratch register
+ ;// $T2 - corrupted temp/scratch register
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ MACRO
+ M_BD_VSKIP8 $N, $T1
+ ADD $BitCount, $BitCount, $N
+ SUBS $BitCount, $BitCount, #8
+ LDRCSB $T1, [$pBitStream], #1
+ ADDCC $BitCount, $BitCount, #8
+ ORRCS $BitBuffer, $T1, $BitBuffer, LSL #8
+ MEND
+
+ ;//
+ ;// Skip variable 1<=N<=16 bits from the bitstream, advancing the bitstream pointer.
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// $N - number of bits. 1<=N<=16
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// $T1 - corrupted temp/scratch register
+ ;// $T2 - corrupted temp/scratch register
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ MACRO
+ M_BD_VSKIP16 $N, $T1, $T2
+ ADD $BitCount, $BitCount, $N
+ SUBS $BitCount, $BitCount, #8
+ LDRCSB $T1, [$pBitStream], #1
+ ORRCS $BitBuffer, $T1, $BitBuffer, LSL #8
+ SUBCSS $BitCount, $BitCount, #8
+ LDRCSB $T1, [$pBitStream], #1
+ ADDCC $BitCount, $BitCount, #8
+ ORRCS $BitBuffer, $T1, $BitBuffer, LSL #8
+ MEND
+
+ ;//
+ ;// Read variable 1<=N<=8 bits from the bitstream, advancing the bitstream pointer.
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// $N - number of bits to read. 1<=N<=8
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// $Symbol - the next N bits of the bitstream
+ ;// $T1 - corrupted temp/scratch register
+ ;// $T2 - corrupted temp/scratch register
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ MACRO
+ M_BD_VREAD8 $Symbol, $N, $T1, $T2
+ MOV $Symbol, $BitBuffer, LSL $BitCount
+ ADD $BitCount, $BitCount, $N
+ SUBS $BitCount, $BitCount, #8
+ LDRCSB $T1, [$pBitStream], #1
+ RSB $T2, $N, #32
+ ADDCC $BitCount, $BitCount, #8
+ MOV $Symbol, $Symbol, LSR $T2
+ ORRCS $BitBuffer, $T1, $BitBuffer, LSL #8
+ MEND
+
+
+ ;//
+ ;// Read variable 1<=N<=16 bits from the bitstream, advancing the bitstream pointer.
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// $N - number of bits to read. 1<=N<=16
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// $Symbol - the next N bits of the bitstream
+ ;// $T1 - corrupted temp/scratch register
+ ;// $T2 - corrupted temp/scratch register
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ MACRO
+ M_BD_VREAD16 $Symbol, $N, $T1, $T2
+ MOV $Symbol, $BitBuffer, LSL $BitCount
+ ADD $BitCount, $BitCount, $N
+ SUBS $BitCount, $BitCount, #8
+ LDRCSB $T1, [$pBitStream], #1
+ RSB $T2, $N, #32
+ ORRCS $BitBuffer, $T1, $BitBuffer, LSL #8
+ SUBCSS $BitCount, $BitCount, #8
+ LDRCSB $T1, [$pBitStream], #1
+ ADDCC $BitCount, $BitCount, #8
+ MOV $Symbol, $Symbol, LSR $T2
+ ORRCS $BitBuffer, $T1, $BitBuffer, LSL #8
+ MEND
+
+
+ ;//
+ ;// Decode a code of the form 0000...001 where there
+ ;// are N zeros before the 1 and N<=15 (code length<=16)
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// $Symbol - the number of zeros before the next 1
+ ;// >=16 is an illegal code
+ ;// $T1 - corrupted temp/scratch register
+ ;// $T2 - corrupted temp/scratch register
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ MACRO
+ M_BD_CLZ16 $Symbol, $T1, $T2
+ MOVS $Symbol, $BitBuffer, LSL $BitCount
+ CLZ $Symbol, $Symbol
+ ADD $BitCount, $BitCount, $Symbol
+ SUBS $BitCount, $BitCount, #7 ;// length is Symbol+1
+ LDRCSB $T1, [$pBitStream], #1
+ ORRCS $BitBuffer, $T1, $BitBuffer, LSL #8
+ SUBCSS $BitCount, $BitCount, #8
+ LDRCSB $T1, [$pBitStream], #1
+ ADDCC $BitCount, $BitCount, #8
+ ORRCS $BitBuffer, $T1, $BitBuffer, LSL #8
+ MEND
+
+ ;//
+ ;// Decode a code of the form 1111...110 where there
+ ;// are N ones before the 0 and N<=15 (code length<=16)
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// $Symbol - the number of zeros before the next 1
+ ;// >=16 is an illegal code
+ ;// $T1 - corrupted temp/scratch register
+ ;// $T2 - corrupted temp/scratch register
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ MACRO
+ M_BD_CLO16 $Symbol, $T1, $T2
+ MOV $Symbol, $BitBuffer, LSL $BitCount
+ MVN $Symbol, $Symbol
+ CLZ $Symbol, $Symbol
+ ADD $BitCount, $BitCount, $Symbol
+ SUBS $BitCount, $BitCount, #7 ;// length is Symbol+1
+ LDRCSB $T1, [$pBitStream], #1
+ ORRCS $BitBuffer, $T1, $BitBuffer, LSL #8
+ SUBCSS $BitCount, $BitCount, #8
+ LDRCSB $T1, [$pBitStream], #1
+ ADDCC $BitCount, $BitCount, #8
+ ORRCS $BitBuffer, $T1, $BitBuffer, LSL #8
+ MEND
+
+
+ ;//
+ ;// Variable Length Decode module
+ ;//
+ ;// Decodes one VLD Symbol from a bitstream and refill the bitstream
+ ;// buffer.
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// $pVLDTable - pointer to VLD decode table of 16-bit entries.
+ ;// The format is described above at the start of
+ ;// this file.
+ ;// $S0 - The number of bits to look up for the first step
+ ;// 1<=$S0<=8
+ ;// $S1 - The number of bits to look up for each subsequent
+ ;// step 1<=$S1<=$S0.
+ ;//
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// $Symbol - decoded VLD symbol value
+ ;// $T1 - corrupted temp/scratch register
+ ;// $T2 - corrupted temp/scratch register
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ MACRO
+ M_BD_VLD $Symbol, $T1, $T2, $pVLDTable, $S0, $S1
+ ASSERT (1<=$S0):LAND:($S0<=8)
+ ASSERT (1<=$S1):LAND:($S1<=$S0)
+
+ ;// Note 0<=BitCount<=15 on entry and exit
+
+ MOVS $T1, $BitBuffer, LSL $BitCount ;// left align next bits
+ MOVS $Symbol, #(2<<$S0)-2 ;// create mask
+ AND $Symbol, $Symbol, $T1, LSR #(31-$S0) ;// 2*(next $S0 bits)
+ SUBS $BitCount, $BitCount, #8 ;// CS if buffer can be filled
+01
+ LDRCSB $T1, [$pBitStream], #1 ;// load refill byte
+ LDRH $Symbol, [$pVLDTable, $Symbol] ;// load table entry
+ ADDCC $BitCount, $BitCount, #8 ;// refill not possible
+ ADD $BitCount, $BitCount, #$S0 ;// assume $S0 bits used
+ ORRCS $BitBuffer, $T1, $BitBuffer, LSL #8 ;// merge in refill byte
+ MOVS $T1, $Symbol, LSR #1 ;// CS=leaf entry
+ BCS %FT02
+
+ MOVS $T1, $BitBuffer, LSL $BitCount ;// left align next bit
+ IF (2*$S0-$S1<=8)
+ ;// Can combine refill check and -S0+S1 and keep $BitCount<=15
+ SUBS $BitCount, $BitCount, #8+($S0-$S1)
+ ELSE
+ ;// Separate refill check and -S0+S1 offset
+ SUBS $BitCount, $BitCount, #8
+ SUB $BitCount, $BitCount, #($S0-$S1)
+ ENDIF
+ ADD $Symbol, $Symbol, $T1, LSR #(31-$S1) ;// add 2*(next $S1 bits) to
+ BIC $Symbol, $Symbol, #1 ;// table offset
+ B %BT01 ;// load next table entry
+02
+ ;// BitCount range now depend on the route here
+ ;// if (first step) S0 <= BitCount <= 7+S0 <=15
+ ;// else if (2*S0-S1<=8) S0 <= BitCount <= 7+(2*S0-S1) <=15
+ ;// else S1 <= BitCount <= 7+S1 <=15
+
+ SUB $BitCount, $BitCount, $Symbol, LSR#13
+ BIC $Symbol, $T1, #0xF000
+ MEND
+
+
+ ;// Add an offset number of bits
+ ;//
+ ;// Outputs destination byte and bit index values which corresponds to an offset number of bits
+ ;// from the current location. This is used to compare bitstream positions using. M_BD_CMP.
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// $Offset - Offset to be added in bits.
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// $ByteIndex - Destination pBitStream pointer after adding the Offset.
+ ;// This value will be 4 byte ahead and needs to subtract by 4 to get exact
+ ;// pointer (as in M_BD_FINI). But for using with M_BD_CMP subtract is not needed.
+ ;// $BitIndex - Destination BitCount after the addition of Offset number of bits
+ ;//
+ MACRO
+ M_BD_ADD $ByteIndex, $BitIndex, $Offset
+
+ ;// ($ByteIndex,$BitIndex) = Current position + $Offset bits
+ ADD $Offset, $Offset, $BitCount
+ AND $BitIndex, $Offset, #7
+ ADD $ByteIndex, $pBitStream, $Offset, ASR #3
+ MEND
+
+ ;// Move bitstream pointers to the location given
+ ;//
+ ;// Outputs destination byte and bit index values which corresponds to
+ ;// the current location given (calculated using M_BD_ADD).
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;// $ByteIndex - Destination pBitStream pointer after move.
+ ;// This value will be 4 byte ahead and needs to subtract by 4 to get exact
+ ;// pointer (as in M_BD_FINI).
+ ;// $BitIndex - Destination BitCount after the move
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// $pBitStream \
+ ;// } See description above.
+ ;// $BitCount /
+ ;//
+ MACRO
+ M_BD_MOV $ByteIndex, $BitIndex
+
+ ;// ($pBitStream, $Offset) = ($ByteIndex,$BitIndex)
+ MOV $BitCount, $BitIndex
+ MOV $pBitStream, $ByteIndex
+ MEND
+
+ ;// Bitstream Compare
+ ;//
+ ;// Compares bitstream position with that of a destination position. Destination position
+ ;// is held in two input registers which are calculated using M_BD_ADD macro
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// $ByteIndex - Destination pBitStream pointer, (4 byte ahead as described in M_BD_ADD)
+ ;// $BitIndex - Destination BitCount
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// FLAGS - GE if destination is reached, LT = is destination is ahead
+ ;// $T1 - corrupted temp/scratch register
+ ;//
+ MACRO
+ M_BD_CMP $ByteIndex, $BitIndex, $T1
+
+ ;// Return flags set by (current positon)-($ByteIndex,$BitIndex)
+ ;// so GE means that we have reached the indicated position
+
+ ADD $T1, $pBitStream, $BitCount, LSR #3
+ CMP $T1, $ByteIndex
+ AND $T1, $BitCount, #7
+ CMPEQ $T1, $BitIndex
+ MEND
+
+
+ ;// Bitstream Decode finalise
+ ;//
+ ;// Writes back the bitstream state to the bitstream pointers
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// $ppBitStream - pointer to pointer to the next bitstream byte
+ ;// $pBitOffset - pointer to the number of bits used in the current byte (0..7)
+ ;// $pBitStream \
+ ;// $BitBuffer } these register are corrupted
+ ;// $BitCount /
+ ;//
+ MACRO
+ M_BD_FINI $ppBitStream, $pBitOffset
+
+ ;// Advance pointer by the number of free bits in the buffer
+ ADD $pBitStream, $pBitStream, $BitCount, LSR#3
+ AND $BitCount, $BitCount, #7
+
+ ;// Now move back 32 bits to reach the first usued bit
+ SUB $pBitStream, $pBitStream, #4
+
+ ;// Store out bitstream state
+ STR $BitCount, [$pBitOffset]
+ STR $pBitStream, [$ppBitStream]
+ MEND
+
+ END
+
\ No newline at end of file
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_Bitstream.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_Bitstream.h
new file mode 100644
index 0000000..4f9bc3b
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_Bitstream.h
@@ -0,0 +1,212 @@
+/**
+ *
+ * File Name: armCOMM_Bitstream.h
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * File: armCOMM_Bitstream.h
+ * Brief: Declares common API's/Data types used across the OpenMax Encoders/Decoders.
+ *
+ */
+
+#ifndef _armCodec_H_
+#define _armCodec_H_
+
+#include "omxtypes.h"
+
+typedef struct {
+ OMX_U8 codeLen;
+ OMX_U32 codeWord;
+} ARM_VLC32;
+
+/* The above should be renamed as "ARM_VLC32" */
+
+/**
+ * Function: armLookAheadBits()
+ *
+ * Description:
+ * Get the next N bits from the bitstream without advancing the bitstream pointer
+ *
+ * Parameters:
+ * [in] **ppBitStream
+ * [in] *pOffset
+ * [in] N=1...32
+ *
+ * Returns Value
+ */
+
+OMX_U32 armLookAheadBits(const OMX_U8 **ppBitStream, OMX_INT *pOffset, OMX_INT N);
+
+/**
+ * Function: armGetBits()
+ *
+ * Description:
+ * Read N bits from the bitstream
+ *
+ * Parameters:
+ * [in] *ppBitStream
+ * [in] *pOffset
+ * [in] N=1..32
+ *
+ * [out] *ppBitStream
+ * [out] *pOffset
+ * Returns Value
+ */
+
+OMX_U32 armGetBits(const OMX_U8 **ppBitStream, OMX_INT *pOffset, OMX_INT N);
+
+/**
+ * Function: armByteAlign()
+ *
+ * Description:
+ * Align the pointer *ppBitStream to the next byte boundary
+ *
+ * Parameters:
+ * [in] *ppBitStream
+ * [in] *pOffset
+ *
+ * [out] *ppBitStream
+ * [out] *pOffset
+ *
+ **/
+
+OMXVoid armByteAlign(const OMX_U8 **ppBitStream,OMX_INT *pOffset);
+
+/**
+ * Function: armSkipBits()
+ *
+ * Description:
+ * Skip N bits from the value at *ppBitStream
+ *
+ * Parameters:
+ * [in] *ppBitStream
+ * [in] *pOffset
+ * [in] N
+ *
+ * [out] *ppBitStream
+ * [out] *pOffset
+ *
+ **/
+
+OMXVoid armSkipBits(const OMX_U8 **ppBitStream,OMX_INT *pOffset,OMX_INT N);
+
+/***************************************
+ * Variable bit length Decode
+ ***************************************/
+
+/**
+ * Function: armUnPackVLC32()
+ *
+ * Description:
+ * Variable length decode of variable length symbol (max size 32 bits) read from
+ * the bit stream pointed by *ppBitStream at *pOffset by using the table
+ * pointed by pCodeBook
+ *
+ * Parameters:
+ * [in] **ppBitStream
+ * [in] *pOffset
+ * [in] pCodeBook
+ *
+ * [out] **ppBitStream
+ * [out] *pOffset
+ *
+ * Returns : Code Book Index if successfull.
+ * : "ARM_NO_CODEBOOK_INDEX = 0xFFFF" if search fails.
+ **/
+
+#define ARM_NO_CODEBOOK_INDEX (OMX_U16)(0xFFFF)
+
+OMX_U16 armUnPackVLC32(
+ const OMX_U8 **ppBitStream,
+ OMX_INT *pOffset,
+ const ARM_VLC32 *pCodeBook
+);
+
+/***************************************
+ * Fixed bit length Encode
+ ***************************************/
+
+/**
+ * Function: armPackBits
+ *
+ * Description:
+ * Pack a VLC code word into the bitstream
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream pointer to the pointer to the current byte
+ * in the bit stream.
+ * [in] pOffset pointer to the bit position in the byte
+ * pointed by *ppBitStream. Valid within 0
+ * to 7.
+ * [in] codeWord Code word that need to be inserted in to the
+ * bitstream
+ * [in] codeLength Length of the code word valid range 1...32
+ *
+ * [out] ppBitStream *ppBitStream is updated after the block is encoded,
+ * so that it points to the current byte in the bit
+ * stream buffer.
+ * [out] pBitOffset *pBitOffset is updated so that it points to the
+ * current bit position in the byte pointed by
+ * *ppBitStream.
+ *
+ * Return Value:
+ * Standard OMX_RESULT result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armPackBits (
+ OMX_U8 **ppBitStream,
+ OMX_INT *pOffset,
+ OMX_U32 codeWord,
+ OMX_INT codeLength
+);
+
+/***************************************
+ * Variable bit length Encode
+ ***************************************/
+
+/**
+ * Function: armPackVLC32
+ *
+ * Description:
+ * Pack a VLC code word into the bitstream
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream pointer to the pointer to the current byte
+ * in the bit stream.
+ * [in] pBitOffset pointer to the bit position in the byte
+ * pointed by *ppBitStream. Valid within 0
+ * to 7.
+ * [in] code VLC code word that need to be inserted in to the
+ * bitstream
+ *
+ * [out] ppBitStream *ppBitStream is updated after the block is encoded,
+ * so that it points to the current byte in the bit
+ * stream buffer.
+ * [out] pBitOffset *pBitOffset is updated so that it points to the
+ * current bit position in the byte pointed by
+ * *ppBitStream.
+ *
+ * Return Value:
+ * Standard OMX_RESULT result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armPackVLC32 (
+ OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ ARM_VLC32 code
+);
+
+#endif /*_armCodec_H_*/
+
+/*End of File*/
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_IDCTTable.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_IDCTTable.h
new file mode 100644
index 0000000..d5db32f
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_IDCTTable.h
@@ -0,0 +1,40 @@
+/**
+ *
+ *
+ * File Name: armCOMM_IDCTTable.h
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * File : armCOMM_IDCTTable.h
+ * Description : Contains declarations of tables for IDCT calculation.
+ *
+ */
+
+#ifndef _armCOMM_IDCTTable_H_
+#define _armCOMM_IDCTTable_H_
+
+#include "omxtypes.h"
+
+ /* Table of s(u)*A(u)*A(v)/16 at Q15
+ * s(u)=1.0 0 <= u <= 5
+ * s(6)=2.0
+ * s(7)=4.0
+ * A(0) = 2*sqrt(2)
+ * A(u) = 4*cos(u*pi/16) for (u!=0)
+ */
+extern const OMX_U16 armCOMM_IDCTPreScale [64];
+extern const OMX_U16 armCOMM_IDCTCoef [4];
+
+#endif /* _armCOMM_IDCTTable_H_ */
+
+
+/* End of File */
+
+
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_IDCT_s.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_IDCT_s.h
new file mode 100644
index 0000000..03f7137
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_IDCT_s.h
@@ -0,0 +1,1445 @@
+;//
+;// This confidential and proprietary software may be used only as
+;// authorised by a licensing agreement from ARM Limited
+;// (C) COPYRIGHT 2004 ARM Limited
+;// ALL RIGHTS RESERVED
+;// The entire notice above must be reproduced on all authorised
+;// copies and copies may only be made to the extent permitted
+;// by a licensing agreement from ARM Limited.
+;//
+;// IDCT_s.s
+;//
+;// Inverse DCT module
+;//
+;//
+;// ALGORITHM DESCRIPTION
+;//
+;// The 8x8 2D IDCT is performed by calculating a 1D IDCT for each
+;// column and then a 1D IDCT for each row.
+;//
+;// The 8-point 1D IDCT is defined by
+;// f(x) = (C(0)*T(0)*c(0,x) + ... + C(7)*T(7)*c(7,x))/2
+;//
+;// C(u) = 1/sqrt(2) if u=0 or 1 if u!=0
+;// c(u,x) = cos( (2x+1)*u*pi/16 )
+;//
+;// We compute the 8-point 1D IDCT using the reverse of
+;// the Arai-Agui-Nakajima flow graph which we split into
+;// 5 stages named in reverse order to identify with the
+;// forward DCT. Direct inversion of the forward formulae
+;// in file FDCT_s.s gives:
+;//
+;// IStage 5: j(u) = T(u)*A(u) [ A(u)=4*C(u)*c(u,0) ]
+;// [ A(0) = 2*sqrt(2)
+;// A(u) = 4*cos(u*pi/16) for (u!=0) ]
+;//
+;// IStage 4: i0 = j0 i1 = j4
+;// i3 = (j2+j6)/2 i2 = (j2-j6)/2
+;// i7 = (j5+j3)/2 i4 = (j5-j3)/2
+;// i5 = (j1+j7)/2 i6 = (j1-j7)/2
+;//
+;// IStage 3: h0 = (i0+i1)/2 h1 = (i0-i1)/2
+;// h2 = (i2*sqrt2)-i3 h3 = i3
+;// h4 = cos(pi/8)*i4 + sin(pi/8)*i6
+;// h6 = -sin(pi/8)*i4 + cos(pi/8)*i6
+;// [ The above two lines rotate by -(pi/8) ]
+;// h5 = (i5-i7)/sqrt2 h7 = (i5+i7)/2
+;//
+;// IStage 2: g0 = (h0+h3)/2 g3 = (h0-h3)/2
+;// g1 = (h1+h2)/2 g2 = (h1-h2)/2
+;// g7 = h7 g6 = h6 - h7
+;// g5 = h5 - g6 g4 = h4 - g5
+;//
+;// IStage 1: f0 = (g0+g7)/2 f7 = (g0-g7)/2
+;// f1 = (g1+g6)/2 f6 = (g1-g6)/2
+;// f2 = (g2+g5)/2 f5 = (g2-g5)/2
+;// f3 = (g3+g4)/2 f4 = (g3-g4)/2
+;//
+;// Note that most coefficients are halved 3 times during the
+;// above calculation. We can rescale the algorithm dividing
+;// the input by 8 to remove the halvings.
+;//
+;// IStage 5: j(u) = T(u)*A(u)/8
+;//
+;// IStage 4: i0 = j0 i1 = j4
+;// i3 = j2 + j6 i2 = j2 - j6
+;// i7 = j5 + j3 i4 = j5 - j3
+;// i5 = j1 + j7 i6 = j1 - j7
+;//
+;// IStage 3: h0 = i0 + i1 h1 = i0 - i1
+;// h2 = (i2*sqrt2)-i3 h3 = i3
+;// h4 = 2*( cos(pi/8)*i4 + sin(pi/8)*i6)
+;// h6 = 2*(-sin(pi/8)*i4 + cos(pi/8)*i6)
+;// h5 = (i5-i7)*sqrt2 h7 = i5 + i7
+;//
+;// IStage 2: g0 = h0 + h3 g3 = h0 - h3
+;// g1 = h1 + h2 g2 = h1 - h2
+;// g7 = h7 g6 = h6 - h7
+;// g5 = h5 - g6 g4 = h4 - g5
+;//
+;// IStage 1: f0 = g0 + g7 f7 = g0 - g7
+;// f1 = g1 + g6 f6 = g1 - g6
+;// f2 = g2 + g5 f5 = g2 - g5
+;// f3 = g3 + g4 f4 = g3 - g4
+;//
+;// Note:
+;// 1. The scaling by A(u)/8 can often be combined with inverse
+;// quantization. The column and row scalings can be combined.
+;// 2. The flowgraph in the AAN paper has h4,g6 negated compared
+;// to the above code but is otherwise identical.
+;// 3. The rotation by -pi/8 can be peformed using three multiplies
+;// Eg c*i4+s*i6 = (i6-i4)*s + (c+s)*i4
+;// -s*i4+c*i6 = (i6-i4)*s + (c-s)*i6
+;// 4. If |T(u)|<=1 then from the IDCT definition,
+;// |f(x)| <= ((1/sqrt2) + |c(1,x)| + .. + |c(7,x)|)/2
+;// = ((1/sqrt2) + cos(pi/16) + ... + cos(7*pi/16))/2
+;// = ((1/sqrt2) + (cot(pi/32)-1)/2)/2
+;// = (1 + cos(pi/16) + cos(2pi/16) + cos(3pi/16))/sqrt(2)
+;// = (approx)2.64
+;// So the max gain of the 2D IDCT is ~x7.0 = 3 bits.
+;// The table below shows input patterns generating the maximum
+;// value of |f(u)| for input in the range |T(x)|<=1. M=-1, P=+1
+;// InputPattern Max |f(x)|
+;// PPPPPPPP |f0| = 2.64
+;// PPPMMMMM |f1| = 2.64
+;// PPMMMPPP |f2| = 2.64
+;// PPMMPPMM |f3| = 2.64
+;// PMMPPMMP |f4| = 2.64
+;// PMMPMMPM |f5| = 2.64
+;// PMPPMPMP |f6| = 2.64
+;// PMPMPMPM |f7| = 2.64
+;// Note that this input pattern is the transpose of the
+;// corresponding max input patter for the FDCT.
+
+;// Arguments
+
+pSrc RN 0 ;// source data buffer
+Stride RN 1 ;// destination stride in bytes
+pDest RN 2 ;// destination data buffer
+pScale RN 3 ;// pointer to scaling table
+
+
+ ;// DCT Inverse Macro
+ ;// The DCT code should be parametrized according
+ ;// to the following inputs:
+ ;// $outsize = "u8" : 8-bit unsigned data saturated (0 to +255)
+ ;// "s9" : 16-bit signed data saturated to 9-bit (-256 to +255)
+ ;// "s16" : 16-bit signed data not saturated (max size ~+/-14273)
+ ;// $inscale = "s16" : signed 16-bit aan-scale table, Q15 format, with 4 byte alignment
+ ;// "s32" : signed 32-bit aan-scale table, Q23 format, with 4 byte alignment
+ ;//
+ ;// Inputs:
+ ;// pSrc = r0 = Pointer to input data
+ ;// Range is -256 to +255 (9-bit)
+ ;// Stride = r1 = Stride between input lines
+ ;// pDest = r2 = Pointer to output data
+ ;// pScale = r3 = Pointer to aan-scale table in the format defined by $inscale
+
+
+
+ MACRO
+ M_IDCT $outsize, $inscale, $stride
+ LCLA SHIFT
+
+
+ IF ARM1136JS
+
+;// REGISTER ALLOCATION
+;// This is hard since we have 8 values, 9 free registers and each
+;// butterfly requires a temporary register. We also want to
+;// maintain register order so we can use LDM/STM. The table below
+;// summarises the register allocation that meets all these criteria.
+;// a=1stcol, b=2ndcol, f,g,h,i are dataflow points described above.
+;//
+;// r1 a01 g0 h0
+;// r4 b01 f0 g1 h1 i0
+;// r5 a23 f1 g2 i1
+;// r6 b23 f2 g3 h2 i2
+;// r7 a45 f3 h3 i3
+;// r8 b45 f4 g4 h4 i4
+;// r9 a67 f5 g5 h5 i5
+;// r10 b67 f6 g6 h6 i6
+;// r11 f7 g7 h7 i7
+;//
+ra01 RN 1
+rb01 RN 4
+ra23 RN 5
+rb23 RN 6
+ra45 RN 7
+rb45 RN 8
+ra67 RN 9
+rb67 RN 10
+rtmp RN 11
+csPiBy8 RN 12 ;// [ (Sin(pi/8)@Q15), (Cos(pi/8)@Q15) ]
+LoopRR2 RN 14 ;// [ LoopNumber<<13 , (1/Sqrt(2))@Q15 ]
+;// Transpose allocation
+xft RN ra01
+xf0 RN rb01
+xf1 RN ra23
+xf2 RN rb23
+xf3 RN ra45
+xf4 RN rb45
+xf5 RN ra67
+xf6 RN rb67
+xf7 RN rtmp
+;// IStage 1 allocation
+xg0 RN xft
+xg1 RN xf0
+xg2 RN xf1
+xg3 RN xf2
+xgt RN xf3
+xg4 RN xf4
+xg5 RN xf5
+xg6 RN xf6
+xg7 RN xf7
+;// IStage 2 allocation
+xh0 RN xg0
+xh1 RN xg1
+xht RN xg2
+xh2 RN xg3
+xh3 RN xgt
+xh4 RN xg4
+xh5 RN xg5
+xh6 RN xg6
+xh7 RN xg7
+;// IStage 3,4 allocation
+xit RN xh0
+xi0 RN xh1
+xi1 RN xht
+xi2 RN xh2
+xi3 RN xh3
+xi4 RN xh4
+xi5 RN xh5
+xi6 RN xh6
+xi7 RN xh7
+
+ M_STR pDest, ppDest
+ IF "$stride"="s"
+ M_STR Stride, pStride
+ ENDIF
+ M_ADR pDest, pBlk
+ LDR csPiBy8, =0x30fc7642
+ LDR LoopRR2, =0x00005a82
+
+v6_idct_col$_F
+ ;// Load even values
+ LDR xi4, [pSrc], #4 ;// j0
+ LDR xi5, [pSrc, #4*16-4] ;// j4
+ LDR xi6, [pSrc, #2*16-4] ;// j2
+ LDR xi7, [pSrc, #6*16-4] ;// j6
+
+ ;// Scale Even Values
+ IF "$inscale"="s16" ;// 16x16 mul
+SHIFT SETA 12
+ LDR xi0, [pScale], #4
+ LDR xi1, [pScale, #4*16-4]
+ LDR xi2, [pScale, #2*16-4]
+ MOV xit, #1<<(SHIFT-1)
+ SMLABB xi3, xi0, xi4, xit
+ SMLATT xi4, xi0, xi4, xit
+ SMLABB xi0, xi1, xi5, xit
+ SMLATT xi5, xi1, xi5, xit
+ MOV xi3, xi3, ASR #SHIFT
+ PKHBT xi4, xi3, xi4, LSL #(16-SHIFT)
+ LDR xi3, [pScale, #6*16-4]
+ SMLABB xi1, xi2, xi6, xit
+ SMLATT xi6, xi2, xi6, xit
+ MOV xi0, xi0, ASR #SHIFT
+ PKHBT xi5, xi0, xi5, LSL #(16-SHIFT)
+ SMLABB xi2, xi3, xi7, xit
+ SMLATT xi7, xi3, xi7, xit
+ MOV xi1, xi1, ASR #SHIFT
+ PKHBT xi6, xi1, xi6, LSL #(16-SHIFT)
+ MOV xi2, xi2, ASR #SHIFT
+ PKHBT xi7, xi2, xi7, LSL #(16-SHIFT)
+ ENDIF
+ IF "$inscale"="s32" ;// 32x16 mul
+SHIFT SETA (12+8-16)
+ MOV xit, #1<<(SHIFT-1)
+ LDR xi0, [pScale], #8
+ LDR xi1, [pScale, #0*32+4-8]
+ LDR xi2, [pScale, #4*32-8]
+ LDR xi3, [pScale, #4*32+4-8]
+ SMLAWB xi0, xi0, xi4, xit
+ SMLAWT xi1, xi1, xi4, xit
+ SMLAWB xi2, xi2, xi5, xit
+ SMLAWT xi3, xi3, xi5, xit
+ MOV xi0, xi0, ASR #SHIFT
+ PKHBT xi4, xi0, xi1, LSL #(16-SHIFT)
+ MOV xi2, xi2, ASR #SHIFT
+ PKHBT xi5, xi2, xi3, LSL #(16-SHIFT)
+ LDR xi0, [pScale, #2*32-8]
+ LDR xi1, [pScale, #2*32+4-8]
+ LDR xi2, [pScale, #6*32-8]
+ LDR xi3, [pScale, #6*32+4-8]
+ SMLAWB xi0, xi0, xi6, xit
+ SMLAWT xi1, xi1, xi6, xit
+ SMLAWB xi2, xi2, xi7, xit
+ SMLAWT xi3, xi3, xi7, xit
+ MOV xi0, xi0, ASR #SHIFT
+ PKHBT xi6, xi0, xi1, LSL #(16-SHIFT)
+ MOV xi2, xi2, ASR #SHIFT
+ PKHBT xi7, xi2, xi3, LSL #(16-SHIFT)
+ ENDIF
+
+ ;// Load odd values
+ LDR xi0, [pSrc, #1*16-4] ;// j1
+ LDR xi1, [pSrc, #7*16-4] ;// j7
+ LDR xi2, [pSrc, #5*16-4] ;// j5
+ LDR xi3, [pSrc, #3*16-4] ;// j3
+
+ IF {TRUE}
+ ;// shortcut if odd values 0
+ TEQ xi0, #0
+ TEQEQ xi1, #0
+ TEQEQ xi2, #0
+ TEQEQ xi3, #0
+ BEQ v6OddZero$_F
+ ENDIF
+
+ ;// Store scaled even values
+ STMIA pDest, {xi4, xi5, xi6, xi7}
+
+ ;// Scale odd values
+ IF "$inscale"="s16"
+ ;// Perform AAN Scale
+ LDR xi4, [pScale, #1*16-4]
+ LDR xi5, [pScale, #7*16-4]
+ LDR xi6, [pScale, #5*16-4]
+ SMLABB xi7, xi0, xi4, xit
+ SMLATT xi0, xi0, xi4, xit
+ SMLABB xi4, xi1, xi5, xit
+ SMLATT xi1, xi1, xi5, xit
+ MOV xi7, xi7, ASR #SHIFT
+ PKHBT xi0, xi7, xi0, LSL #(16-SHIFT)
+ LDR xi7, [pScale, #3*16-4]
+ SMLABB xi5, xi2, xi6, xit
+ SMLATT xi2, xi2, xi6, xit
+ MOV xi4, xi4, ASR #SHIFT
+ PKHBT xi1, xi4, xi1, LSL #(16-SHIFT)
+ SMLABB xi6, xi3, xi7, xit
+ SMLATT xi3, xi3, xi7, xit
+ MOV xi5, xi5, ASR #SHIFT
+ PKHBT xi2, xi5, xi2, LSL #(16-SHIFT)
+ MOV xi6, xi6, ASR #SHIFT
+ PKHBT xi3, xi6, xi3, LSL #(16-SHIFT)
+ ENDIF
+ IF "$inscale"="s32" ;// 32x16 mul
+ LDR xi4, [pScale, #1*32-8]
+ LDR xi5, [pScale, #1*32+4-8]
+ LDR xi6, [pScale, #7*32-8]
+ LDR xi7, [pScale, #7*32+4-8]
+ SMLAWB xi4, xi4, xi0, xit
+ SMLAWT xi5, xi5, xi0, xit
+ SMLAWB xi6, xi6, xi1, xit
+ SMLAWT xi7, xi7, xi1, xit
+ MOV xi4, xi4, ASR #SHIFT
+ PKHBT xi0, xi4, xi5, LSL #(16-SHIFT)
+ MOV xi6, xi6, ASR #SHIFT
+ PKHBT xi1, xi6, xi7, LSL #(16-SHIFT)
+ LDR xi4, [pScale, #5*32-8]
+ LDR xi5, [pScale, #5*32+4-8]
+ LDR xi6, [pScale, #3*32-8]
+ LDR xi7, [pScale, #3*32+4-8]
+ SMLAWB xi4, xi4, xi2, xit
+ SMLAWT xi5, xi5, xi2, xit
+ SMLAWB xi6, xi6, xi3, xit
+ SMLAWT xi7, xi7, xi3, xit
+ MOV xi4, xi4, ASR #SHIFT
+ PKHBT xi2, xi4, xi5, LSL #(16-SHIFT)
+ MOV xi6, xi6, ASR #SHIFT
+ PKHBT xi3, xi6, xi7, LSL #(16-SHIFT)
+ ENDIF
+
+ SHADD16 xi5, xi0, xi1 ;// (j1+j7)/2
+ SSUB16 xi6, xi0, xi1 ;// j1-j7
+ SHADD16 xi7, xi2, xi3 ;// (j5+j3)/2
+ SSUB16 xi4, xi2, xi3 ;// j5-j3
+
+ SSUB16 xi3, xi5, xi7 ;// (i5-i7)/2
+
+ PKHBT xi0, xi6, xi4, LSL#16 ;// [i4,i6] row a
+ PKHTB xi1, xi4, xi6, ASR#16 ;// [i4,i6] row b
+
+ SMUADX xi2, xi0, csPiBy8 ;// rowa by [c,s]
+ SMUADX xi4, xi1, csPiBy8 ;// rowb by [c,s]
+ SMUSD xi0, xi0, csPiBy8 ;// rowa by [-s,c]
+ SMUSD xi6, xi1, csPiBy8 ;// rowb by [-s,c]
+
+ SMULBB xi1, xi3, LoopRR2
+ SMULTB xi3, xi3, LoopRR2
+
+ PKHTB xh4, xi4, xi2, ASR#16 ;// h4/4
+ PKHTB xh6, xi6, xi0, ASR#16 ;// h6/4
+ SHADD16 xh7, xi5, xi7 ;// (i5+i7)/4
+
+ ;// xi0,xi1,xi2,xi3 now free
+ ;// IStage 4,3, rows 2to3 x1/2
+
+ MOV xi3, xi3, LSL #1
+ PKHTB xh5, xi3, xi1, ASR#15 ;// h5/4
+ LDRD xi0, [pDest, #8] ;// j2,j6 scaled
+
+ ;// IStage 2, rows4to7
+ SSUB16 xg6, xh6, xh7
+ SSUB16 xg5, xh5, xg6
+ SSUB16 xg4, xh4, xg5
+
+ SSUB16 xi2, xi0, xi1 ;// (j2-j6)
+ SHADD16 xi3, xi0, xi1 ;// (j2+j6)/2
+
+ SMULBB xi0, xi2, LoopRR2
+ SMULTB xi2, xi2, LoopRR2
+
+ MOV xi2, xi2, LSL #1
+ PKHTB xh2, xi2, xi0, ASR#15 ;// i2*sqrt(2)/4
+
+ ;// xi0, xi1 now free
+ ;// IStage 4,3 rows 0to1 x 1/2
+ LDRD xi0, [pDest] ;// j0, j4 scaled
+ SSUB16 xh2, xh2, xi3
+ ADDS LoopRR2, LoopRR2, #2<<29 ;// done two rows
+
+ SHADD16 xh0, xi0, xi1
+ SHSUB16 xh1, xi0, xi1
+
+ ;// IStage 2 rows 0to3 x 1/2
+ SHSUB16 xg2, xh1, xh2
+ SHADD16 xg1, xh1, xh2
+ SHSUB16 xg3, xh0, xh3
+ SHADD16 xg0, xh0, xh3
+
+ ;// IStage 1 all rows
+ SADD16 xf3, xg3, xg4
+ SSUB16 xf4, xg3, xg4
+ SADD16 xf2, xg2, xg5
+ SSUB16 xf5, xg2, xg5
+ SADD16 xf1, xg1, xg6
+ SSUB16 xf6, xg1, xg6
+ SADD16 xf0, xg0, xg7
+ SSUB16 xf7, xg0, xg7
+
+ ;// Transpose, store and loop
+ PKHBT ra01, xf0, xf1, LSL #16
+ PKHTB rb01, xf1, xf0, ASR #16
+
+ PKHBT ra23, xf2, xf3, LSL #16
+ PKHTB rb23, xf3, xf2, ASR #16
+
+ PKHBT ra45, xf4, xf5, LSL #16
+ PKHTB rb45, xf5, xf4, ASR #16
+
+ PKHBT ra67, xf6, xf7, LSL #16
+ STMIA pDest!, {ra01, ra23, ra45, ra67}
+ PKHTB rb67, xf7, xf6, ASR #16
+ STMIA pDest!, {rb01, rb23, rb45, rb67}
+ BCC v6_idct_col$_F
+
+ SUB pSrc, pDest, #(64*2)
+ M_LDR pDest, ppDest
+ IF "$stride"="s"
+ M_LDR pScale, pStride
+ ENDIF
+ B v6_idct_row$_F
+
+v6OddZero$_F
+ SSUB16 xi2, xi6, xi7 ;// (j2-j6)
+ SHADD16 xi3, xi6, xi7 ;// (j2+j6)/2
+
+ SMULBB xi0, xi2, LoopRR2
+ SMULTB xi2, xi2, LoopRR2
+
+ MOV xi2, xi2, LSL #1
+ PKHTB xh2, xi2, xi0, ASR#15 ;// i2*sqrt(2)/4
+ SSUB16 xh2, xh2, xi3
+
+ ;// xi0, xi1 now free
+ ;// IStage 4,3 rows 0to1 x 1/2
+
+ SHADD16 xh0, xi4, xi5
+ SHSUB16 xh1, xi4, xi5
+
+ ;// IStage 2 rows 0to3 x 1/2
+ SHSUB16 xg2, xh1, xh2
+ SHADD16 xg1, xh1, xh2
+ SHSUB16 xg3, xh0, xh3
+ SHADD16 xg0, xh0, xh3
+
+ ;// IStage 1 all rows
+ MOV xf3, xg3
+ MOV xf4, xg3
+ MOV xf2, xg2
+ MOV xf5, xg2
+ MOV xf1, xg1
+ MOV xf6, xg1
+ MOV xf0, xg0
+ MOV xf7, xg0
+
+ ;// Transpose
+ PKHBT ra01, xf0, xf1, LSL #16
+ PKHTB rb01, xf1, xf0, ASR #16
+
+ PKHBT ra23, xf2, xf3, LSL #16
+ PKHTB rb23, xf3, xf2, ASR #16
+
+ PKHBT ra45, xf4, xf5, LSL #16
+ PKHTB rb45, xf5, xf4, ASR #16
+
+ PKHBT ra67, xf6, xf7, LSL #16
+ PKHTB rb67, xf7, xf6, ASR #16
+
+ STMIA pDest!, {ra01, ra23, ra45, ra67}
+ ADDS LoopRR2, LoopRR2, #2<<29 ;// done two rows
+ STMIA pDest!, {rb01, rb23, rb45, rb67}
+
+ BCC v6_idct_col$_F
+ SUB pSrc, pDest, #(64*2)
+ M_LDR pDest, ppDest
+ IF "$stride"="s"
+ M_LDR pScale, pStride
+ ENDIF
+
+
+v6_idct_row$_F
+ ;// IStage 4,3, rows4to7 x1/4
+ LDR xit, =0x00010001 ;// rounding constant
+ LDR xi0, [pSrc, #1*16] ;// j1
+ LDR xi1, [pSrc, #7*16] ;// 4*j7
+ LDR xi2, [pSrc, #5*16] ;// j5
+ LDR xi3, [pSrc, #3*16] ;// j3
+
+ SHADD16 xi1, xi1, xit ;// 2*j7
+ SHADD16 xi1, xi1, xit ;// j7
+
+ SHADD16 xi5, xi0, xi1 ;// (j1+j7)/2
+ SSUB16 xi6, xi0, xi1 ;// j1-j7
+ SHADD16 xi7, xi2, xi3 ;// (j5+j3)/2
+ SSUB16 xi4, xi2, xi3 ;// j5-j3
+
+ SSUB16 xi3, xi5, xi7 ;// (i5-i7)/2
+
+ PKHBT xi0, xi6, xi4, LSL#16 ;// [i4,i6] row a
+ PKHTB xi1, xi4, xi6, ASR#16 ;// [i4,i6] row b
+
+ SMUADX xi2, xi0, csPiBy8 ;// rowa by [c,s]
+ SMUADX xi4, xi1, csPiBy8 ;// rowb by [c,s]
+ SMUSD xi0, xi0, csPiBy8 ;// rowa by [-s,c]
+ SMUSD xi6, xi1, csPiBy8 ;// rowb by [-s,c]
+
+ SMULBB xi1, xi3, LoopRR2
+ SMULTB xi3, xi3, LoopRR2
+
+ PKHTB xh4, xi4, xi2, ASR#16 ;// h4/4
+ PKHTB xh6, xi6, xi0, ASR#16 ;// h6/4
+ SHADD16 xh7, xi5, xi7 ;// (i5+i7)/4
+
+ MOV xi3, xi3, LSL #1
+ PKHTB xh5, xi3, xi1, ASR#15 ;// h5/4
+
+ ;// xi0,xi1,xi2,xi3 now free
+ ;// IStage 4,3, rows 2to3 x1/2
+
+ LDR xi0, [pSrc, #2*16] ;// j2
+ LDR xi1, [pSrc, #6*16] ;// 2*j6
+
+ ;// IStage 2, rows4to7
+ SSUB16 xg6, xh6, xh7
+ SSUB16 xg5, xh5, xg6
+ SSUB16 xg4, xh4, xg5
+
+ SHADD16 xi1, xi1, xit ;// j6
+ SSUB16 xi2, xi0, xi1 ;// (j2-j6)
+ SHADD16 xi3, xi0, xi1 ;// (j2+j6)/2
+
+ SMULBB xi0, xi2, LoopRR2
+ SMULTB xi2, xi2, LoopRR2
+
+ MOV xi2, xi2, LSL #1
+
+ PKHTB xh2, xi2, xi0, ASR#15 ;// i2*sqrt(2)/4
+
+ ;// xi0, xi1 now free
+ ;// IStage 4,3 rows 0to1 x 1/2
+ LDR xi1, [pSrc, #4*16] ;// j4
+ LDR xi0, [pSrc], #4 ;// j0
+
+ SSUB16 xh2, xh2, xi3
+ ADDS LoopRR2, LoopRR2, #2<<29 ;// done two rows
+
+ ADD xi0, xi0, xit, LSL #2 ;// ensure correct round
+ SHADD16 xh0, xi0, xi1 ;// of DC result
+ SHSUB16 xh1, xi0, xi1
+
+ ;// IStage 2 rows 0to3 x 1/2
+ SHSUB16 xg2, xh1, xh2
+ SHADD16 xg1, xh1, xh2
+ SHSUB16 xg3, xh0, xh3
+ SHADD16 xg0, xh0, xh3
+
+ ;// IStage 1 all rows
+ SHADD16 xf3, xg3, xg4
+ SHSUB16 xf4, xg3, xg4
+ SHADD16 xf2, xg2, xg5
+ SHSUB16 xf5, xg2, xg5
+ SHADD16 xf1, xg1, xg6
+ SHSUB16 xf6, xg1, xg6
+ SHADD16 xf0, xg0, xg7
+ SHSUB16 xf7, xg0, xg7
+
+ ;// Saturate
+ IF ("$outsize"="u8")
+ USAT16 xf0, #8, xf0
+ USAT16 xf1, #8, xf1
+ USAT16 xf2, #8, xf2
+ USAT16 xf3, #8, xf3
+ USAT16 xf4, #8, xf4
+ USAT16 xf5, #8, xf5
+ USAT16 xf6, #8, xf6
+ USAT16 xf7, #8, xf7
+ ENDIF
+ IF ("$outsize"="s9")
+ SSAT16 xf0, #9, xf0
+ SSAT16 xf1, #9, xf1
+ SSAT16 xf2, #9, xf2
+ SSAT16 xf3, #9, xf3
+ SSAT16 xf4, #9, xf4
+ SSAT16 xf5, #9, xf5
+ SSAT16 xf6, #9, xf6
+ SSAT16 xf7, #9, xf7
+ ENDIF
+
+ ;// Transpose to Row, Pack and store
+ IF ("$outsize"="u8")
+ ORR xf0, xf0, xf1, LSL #8 ;// [ b1 b0 a1 a0 ]
+ ORR xf2, xf2, xf3, LSL #8 ;// [ b3 b2 a3 a2 ]
+ ORR xf4, xf4, xf5, LSL #8 ;// [ b5 b4 a5 a4 ]
+ ORR xf6, xf6, xf7, LSL #8 ;// [ b7 b6 a7 a6 ]
+ PKHBT ra01, xf0, xf2, LSL #16
+ PKHTB rb01, xf2, xf0, ASR #16
+ PKHBT ra23, xf4, xf6, LSL #16
+ PKHTB rb23, xf6, xf4, ASR #16
+ STMIA pDest, {ra01, ra23}
+ IF "$stride"="s"
+ ADD pDest, pDest, pScale
+ STMIA pDest, {rb01, rb23}
+ ADD pDest, pDest, pScale
+ ELSE
+ ADD pDest, pDest, #($stride)
+ STMIA pDest, {rb01, rb23}
+ ADD pDest, pDest, #($stride)
+ ENDIF
+ ENDIF
+ IF ("$outsize"="s9"):LOR:("$outsize"="s16")
+ PKHBT ra01, xf0, xf1, LSL #16
+ PKHTB rb01, xf1, xf0, ASR #16
+
+ PKHBT ra23, xf2, xf3, LSL #16
+ PKHTB rb23, xf3, xf2, ASR #16
+
+ PKHBT ra45, xf4, xf5, LSL #16
+ PKHTB rb45, xf5, xf4, ASR #16
+
+ PKHBT ra67, xf6, xf7, LSL #16
+ PKHTB rb67, xf7, xf6, ASR #16
+
+ STMIA pDest, {ra01, ra23, ra45, ra67}
+ IF "$stride"="s"
+ ADD pDest, pDest, pScale
+ STMIA pDest, {rb01, rb23, rb45, rb67}
+ ADD pDest, pDest, pScale
+ ELSE
+ ADD pDest, pDest, #($stride)
+ STMIA pDest, {rb01, rb23, rb45, rb67}
+ ADD pDest, pDest, #($stride)
+ ENDIF
+ ENDIF
+
+ BCC v6_idct_row$_F
+ ENDIF ;// ARM1136JS
+
+
+ IF CortexA8
+
+Src0 EQU 7
+Src1 EQU 8
+Src2 EQU 9
+Src3 EQU 10
+Src4 EQU 11
+Src5 EQU 12
+Src6 EQU 13
+Src7 EQU 14
+Tmp EQU 15
+
+qXj0 QN Src0.S16
+qXj1 QN Src1.S16
+qXj2 QN Src2.S16
+qXj3 QN Src3.S16
+qXj4 QN Src4.S16
+qXj5 QN Src5.S16
+qXj6 QN Src6.S16
+qXj7 QN Src7.S16
+qXjt QN Tmp.S16
+
+dXj0lo DN (Src0*2).S16
+dXj0hi DN (Src0*2+1).S16
+dXj1lo DN (Src1*2).S16
+dXj1hi DN (Src1*2+1).S16
+dXj2lo DN (Src2*2).S16
+dXj2hi DN (Src2*2+1).S16
+dXj3lo DN (Src3*2).S16
+dXj3hi DN (Src3*2+1).S16
+dXj4lo DN (Src4*2).S16
+dXj4hi DN (Src4*2+1).S16
+dXj5lo DN (Src5*2).S16
+dXj5hi DN (Src5*2+1).S16
+dXj6lo DN (Src6*2).S16
+dXj6hi DN (Src6*2+1).S16
+dXj7lo DN (Src7*2).S16
+dXj7hi DN (Src7*2+1).S16
+dXjtlo DN (Tmp*2).S16
+dXjthi DN (Tmp*2+1).S16
+
+qXi0 QN qXj0
+qXi1 QN qXj4
+qXi2 QN qXj2
+qXi3 QN qXj7
+qXi4 QN qXj5
+qXi5 QN qXjt
+qXi6 QN qXj1
+qXi7 QN qXj6
+qXit QN qXj3
+
+dXi0lo DN dXj0lo
+dXi0hi DN dXj0hi
+dXi1lo DN dXj4lo
+dXi1hi DN dXj4hi
+dXi2lo DN dXj2lo
+dXi2hi DN dXj2hi
+dXi3lo DN dXj7lo
+dXi3hi DN dXj7hi
+dXi4lo DN dXj5lo
+dXi4hi DN dXj5hi
+dXi5lo DN dXjtlo
+dXi5hi DN dXjthi
+dXi6lo DN dXj1lo
+dXi6hi DN dXj1hi
+dXi7lo DN dXj6lo
+dXi7hi DN dXj6hi
+dXitlo DN dXj3lo
+dXithi DN dXj3hi
+
+qXh0 QN qXit
+qXh1 QN qXi0
+qXh2 QN qXi2
+qXh3 QN qXi3
+qXh4 QN qXi7
+qXh5 QN qXi5
+qXh6 QN qXi4
+qXh7 QN qXi1
+qXht QN qXi6
+
+dXh0lo DN dXitlo
+dXh0hi DN dXithi
+dXh1lo DN dXi0lo
+dXh1hi DN dXi0hi
+dXh2lo DN dXi2lo
+dXh2hi DN dXi2hi
+dXh3lo DN dXi3lo
+dXh3hi DN dXi3hi
+dXh4lo DN dXi7lo
+dXh4hi DN dXi7hi
+dXh5lo DN dXi5lo
+dXh5hi DN dXi5hi
+dXh6lo DN dXi4lo
+dXh6hi DN dXi4hi
+dXh7lo DN dXi1lo
+dXh7hi DN dXi1hi
+dXhtlo DN dXi6lo
+dXhthi DN dXi6hi
+
+qXg0 QN qXh2
+qXg1 QN qXht
+qXg2 QN qXh1
+qXg3 QN qXh0
+qXg4 QN qXh4
+qXg5 QN qXh5
+qXg6 QN qXh6
+qXg7 QN qXh7
+qXgt QN qXh3
+
+qXf0 QN qXg6
+qXf1 QN qXg5
+qXf2 QN qXg4
+qXf3 QN qXgt
+qXf4 QN qXg3
+qXf5 QN qXg2
+qXf6 QN qXg1
+qXf7 QN qXg0
+qXft QN qXg7
+
+
+qXt0 QN 1.S32
+qXt1 QN 2.S32
+qT0lo QN 1.S32
+qT0hi QN 2.S32
+qT1lo QN 3.S32
+qT1hi QN 4.S32
+qScalelo QN 5.S32 ;// used to read post scale values
+qScalehi QN 6.S32
+qTemp0 QN 5.S32
+qTemp1 QN 6.S32
+
+
+Scale1 EQU 6
+Scale2 EQU 15
+qScale1 QN Scale1.S16
+qScale2 QN Scale2.S16
+dScale1lo DN (Scale1*2).S16
+dScale1hi DN (Scale1*2+1).S16
+dScale2lo DN (Scale2*2).S16
+dScale2hi DN (Scale2*2+1).S16
+
+dCoefs DN 0.S16 ;// Scale coefficients in format {[0] [C] [S] [InvSqrt2]}
+InvSqrt2 DN dCoefs[0] ;// 1/sqrt(2) in Q15
+S DN dCoefs[1] ;// Sin(PI/8) in Q15
+C DN dCoefs[2] ;// Cos(PI/8) in Q15
+
+pTemp RN 12
+
+
+ IMPORT armCOMM_IDCTCoef
+
+ VLD1 {qXj0,qXj1}, [pSrc @64]!
+ VLD1 {qXj2,qXj3}, [pSrc @64]!
+ VLD1 {qXj4,qXj5}, [pSrc @64]!
+ VLD1 {qXj6,qXj7}, [pSrc @64]!
+
+ ;// Load PreScale and multiply with Src
+ ;// IStage 4
+
+ IF "$inscale"="s16" ;// 16X16 Mul
+ M_IDCT_PRESCALE16
+ ENDIF
+
+ IF "$inscale"="s32" ;// 32X32 ,ul
+ M_IDCT_PRESCALE32
+ ENDIF
+
+ ;// IStage 3
+ VQRDMULH qXi2, qXi2, InvSqrt2 ;// i2/sqrt(2)
+ VHADD qXh0, qXi0, qXi1 ;// (i0+i1)/2
+ VHSUB qXh1, qXi0, qXi1 ;// (i0-i1)/2
+ VHADD qXh7, qXi5, qXi7 ;// (i5+i7)/4
+ VSUB qXh5, qXi5, qXi7 ;// (i5-i7)/2
+ VQRDMULH qXh5, qXh5, InvSqrt2 ;// h5/sqrt(2)
+ VSUB qXh2, qXi2, qXi3 ;// h2, h3
+
+ VMULL qXt0, dXi4lo, C ;// c*i4
+ VMLAL qXt0, dXi6lo, S ;// c*i4+s*i6
+ VMULL qXt1, dXi4hi, C
+ VMLAL qXt1, dXi6hi, S
+ VSHRN dXh4lo, qXt0, #16 ;// h4
+ VSHRN dXh4hi, qXt1, #16
+
+ VMULL qXt0, dXi6lo, C ;// c*i6
+ VMLSL qXt0, dXi4lo, S ;// -s*i4 + c*h6
+ VMULL qXt1, dXi6hi, C
+ VMLSL qXt1, dXi4hi, S
+ VSHRN dXh6lo, qXt0, #16 ;// h6
+ VSHRN dXh6hi, qXt1, #16
+
+ ;// IStage 2
+ VSUB qXg6, qXh6, qXh7
+ VSUB qXg5, qXh5, qXg6
+ VSUB qXg4, qXh4, qXg5
+ VHADD qXg1, qXh1, qXh2 ;// (h1+h2)/2
+ VHSUB qXg2, qXh1, qXh2 ;// (h1-h2)/2
+ VHADD qXg0, qXh0, qXh3 ;// (h0+h3)/2
+ VHSUB qXg3, qXh0, qXh3 ;// (h0-h3)/2
+
+ ;// IStage 1 all rows
+ VADD qXf3, qXg3, qXg4
+ VSUB qXf4, qXg3, qXg4
+ VADD qXf2, qXg2, qXg5
+ VSUB qXf5, qXg2, qXg5
+ VADD qXf1, qXg1, qXg6
+ VSUB qXf6, qXg1, qXg6
+ VADD qXf0, qXg0, qXg7
+ VSUB qXf7, qXg0, qXg7
+
+ ;// Transpose, store and loop
+XTR0 EQU Src5
+XTR1 EQU Tmp
+XTR2 EQU Src6
+XTR3 EQU Src7
+XTR4 EQU Src3
+XTR5 EQU Src0
+XTR6 EQU Src1
+XTR7 EQU Src2
+XTRt EQU Src4
+
+qA0 QN XTR0.S32 ;// for XTRpose
+qA1 QN XTR1.S32
+qA2 QN XTR2.S32
+qA3 QN XTR3.S32
+qA4 QN XTR4.S32
+qA5 QN XTR5.S32
+qA6 QN XTR6.S32
+qA7 QN XTR7.S32
+
+dB0 DN XTR0*2+1 ;// for using VSWP
+dB1 DN XTR1*2+1
+dB2 DN XTR2*2+1
+dB3 DN XTR3*2+1
+dB4 DN XTR4*2
+dB5 DN XTR5*2
+dB6 DN XTR6*2
+dB7 DN XTR7*2
+
+
+ VTRN qXf0, qXf1
+ VTRN qXf2, qXf3
+ VTRN qXf4, qXf5
+ VTRN qXf6, qXf7
+ VTRN qA0, qA2
+ VTRN qA1, qA3
+ VTRN qA4, qA6
+ VTRN qA5, qA7
+ VSWP dB0, dB4
+ VSWP dB1, dB5
+ VSWP dB2, dB6
+ VSWP dB3, dB7
+
+
+qYj0 QN qXf0
+qYj1 QN qXf1
+qYj2 QN qXf2
+qYj3 QN qXf3
+qYj4 QN qXf4
+qYj5 QN qXf5
+qYj6 QN qXf6
+qYj7 QN qXf7
+qYjt QN qXft
+
+dYj0lo DN (XTR0*2).S16
+dYj0hi DN (XTR0*2+1).S16
+dYj1lo DN (XTR1*2).S16
+dYj1hi DN (XTR1*2+1).S16
+dYj2lo DN (XTR2*2).S16
+dYj2hi DN (XTR2*2+1).S16
+dYj3lo DN (XTR3*2).S16
+dYj3hi DN (XTR3*2+1).S16
+dYj4lo DN (XTR4*2).S16
+dYj4hi DN (XTR4*2+1).S16
+dYj5lo DN (XTR5*2).S16
+dYj5hi DN (XTR5*2+1).S16
+dYj6lo DN (XTR6*2).S16
+dYj6hi DN (XTR6*2+1).S16
+dYj7lo DN (XTR7*2).S16
+dYj7hi DN (XTR7*2+1).S16
+dYjtlo DN (XTRt*2).S16
+dYjthi DN (XTRt*2+1).S16
+
+qYi0 QN qYj0
+qYi1 QN qYj4
+qYi2 QN qYj2
+qYi3 QN qYj7
+qYi4 QN qYj5
+qYi5 QN qYjt
+qYi6 QN qYj1
+qYi7 QN qYj6
+qYit QN qYj3
+
+dYi0lo DN dYj0lo
+dYi0hi DN dYj0hi
+dYi1lo DN dYj4lo
+dYi1hi DN dYj4hi
+dYi2lo DN dYj2lo
+dYi2hi DN dYj2hi
+dYi3lo DN dYj7lo
+dYi3hi DN dYj7hi
+dYi4lo DN dYj5lo
+dYi4hi DN dYj5hi
+dYi5lo DN dYjtlo
+dYi5hi DN dYjthi
+dYi6lo DN dYj1lo
+dYi6hi DN dYj1hi
+dYi7lo DN dYj6lo
+dYi7hi DN dYj6hi
+dYitlo DN dYj3lo
+dYithi DN dYj3hi
+
+qYh0 QN qYit
+qYh1 QN qYi0
+qYh2 QN qYi2
+qYh3 QN qYi3
+qYh4 QN qYi7
+qYh5 QN qYi5
+qYh6 QN qYi4
+qYh7 QN qYi1
+qYht QN qYi6
+
+dYh0lo DN dYitlo
+dYh0hi DN dYithi
+dYh1lo DN dYi0lo
+dYh1hi DN dYi0hi
+dYh2lo DN dYi2lo
+dYh2hi DN dYi2hi
+dYh3lo DN dYi3lo
+dYh3hi DN dYi3hi
+dYh4lo DN dYi7lo
+dYh4hi DN dYi7hi
+dYh5lo DN dYi5lo
+dYh5hi DN dYi5hi
+dYh6lo DN dYi4lo
+dYh6hi DN dYi4hi
+dYh7lo DN dYi1lo
+dYh7hi DN dYi1hi
+dYhtlo DN dYi6lo
+dYhthi DN dYi6hi
+
+qYg0 QN qYh2
+qYg1 QN qYht
+qYg2 QN qYh1
+qYg3 QN qYh0
+qYg4 QN qYh4
+qYg5 QN qYh5
+qYg6 QN qYh6
+qYg7 QN qYh7
+qYgt QN qYh3
+
+qYf0 QN qYg6
+qYf1 QN qYg5
+qYf2 QN qYg4
+qYf3 QN qYgt
+qYf4 QN qYg3
+qYf5 QN qYg2
+qYf6 QN qYg1
+qYf7 QN qYg0
+qYft QN qYg7
+
+ VRSHR qYj7, qYj7, #2
+ VRSHR qYj6, qYj6, #1
+
+ VHADD qYi5, qYj1, qYj7 ;// i5 = (j1+j7)/2
+ VSUB qYi6, qYj1, qYj7 ;// i6 = j1-j7
+ VHADD qYi3, qYj2, qYj6 ;// i3 = (j2+j6)/2
+ VSUB qYi2, qYj2, qYj6 ;// i2 = j2-j6
+ VHADD qYi7, qYj5, qYj3 ;// i7 = (j5+j3)/2
+ VSUB qYi4, qYj5, qYj3 ;// i4 = j5-j3
+
+ VQRDMULH qYi2, qYi2, InvSqrt2 ;// i2/sqrt(2)
+ ;// IStage 4,3 rows 0to1 x 1/2
+
+ MOV pTemp, #0x4 ;// ensure correct round
+ VDUP qScale1, pTemp ;// of DC result
+ VADD qYi0, qYi0, qScale1
+
+ VHADD qYh0, qYi0, qYi1 ;// (i0+i1)/2
+ VHSUB qYh1, qYi0, qYi1 ;// (i0-i1)/2
+
+ VHADD qYh7, qYi5, qYi7 ;// (i5+i7)/4
+ VSUB qYh5, qYi5, qYi7 ;// (i5-i7)/2
+ VSUB qYh2, qYi2, qYi3 ;// h2, h3
+ VQRDMULH qYh5, qYh5, InvSqrt2 ;// h5/sqrt(2)
+
+ VMULL qXt0, dYi4lo, C ;// c*i4
+ VMLAL qXt0, dYi6lo, S ;// c*i4+s*i6
+ VMULL qXt1, dYi4hi, C
+ VMLAL qXt1, dYi6hi, S
+ VSHRN dYh4lo, qXt0, #16 ;// h4
+ VSHRN dYh4hi, qXt1, #16
+
+ VMULL qXt0, dYi6lo, C ;// c*i6
+ VMLSL qXt0, dYi4lo, S ;// -s*i4 + c*h6
+ VMULL qXt1, dYi6hi, C
+ VMLSL qXt1, dYi4hi, S
+ VSHRN dYh6lo, qXt0, #16 ;// h6
+ VSHRN dYh6hi, qXt1, #16
+
+ VSUB qYg6, qYh6, qYh7
+ VSUB qYg5, qYh5, qYg6
+ VSUB qYg4, qYh4, qYg5
+
+ ;// IStage 2 rows 0to3 x 1/2
+ VHADD qYg1, qYh1, qYh2 ;// (h1+h2)/2
+ VHSUB qYg2, qYh1, qYh2 ;// (h1-h2)/2
+ VHADD qYg0, qYh0, qYh3 ;// (h0+h3)/2
+ VHSUB qYg3, qYh0, qYh3 ;// (h0-h3)/2
+
+
+ ;// IStage 1 all rows
+ VHADD qYf3, qYg3, qYg4
+ VHSUB qYf4, qYg3, qYg4
+ VHADD qYf2, qYg2, qYg5
+ VHSUB qYf5, qYg2, qYg5
+ VHADD qYf1, qYg1, qYg6
+ VHSUB qYf6, qYg1, qYg6
+ VHADD qYf0, qYg0, qYg7
+ VHSUB qYf7, qYg0, qYg7
+
+YTR0 EQU Src0
+YTR1 EQU Src4
+YTR2 EQU Src1
+YTR3 EQU Src2
+YTR4 EQU Src7
+YTR5 EQU Src5
+YTR6 EQU Tmp
+YTR7 EQU Src6
+YTRt EQU Src3
+
+qC0 QN YTR0.S32 ;// for YTRpose
+qC1 QN YTR1.S32
+qC2 QN YTR2.S32
+qC3 QN YTR3.S32
+qC4 QN YTR4.S32
+qC5 QN YTR5.S32
+qC6 QN YTR6.S32
+qC7 QN YTR7.S32
+
+dD0 DN YTR0*2+1 ;// for using VSWP
+dD1 DN YTR1*2+1
+dD2 DN YTR2*2+1
+dD3 DN YTR3*2+1
+dD4 DN YTR4*2
+dD5 DN YTR5*2
+dD6 DN YTR6*2
+dD7 DN YTR7*2
+
+ VTRN qYf0, qYf1
+ VTRN qYf2, qYf3
+ VTRN qYf4, qYf5
+ VTRN qYf6, qYf7
+ VTRN qC0, qC2
+ VTRN qC1, qC3
+ VTRN qC4, qC6
+ VTRN qC5, qC7
+ VSWP dD0, dD4
+ VSWP dD1, dD5
+ VSWP dD2, dD6
+ VSWP dD3, dD7
+
+
+dYf0U8 DN YTR0*2.U8
+dYf1U8 DN YTR1*2.U8
+dYf2U8 DN YTR2*2.U8
+dYf3U8 DN YTR3*2.U8
+dYf4U8 DN YTR4*2.U8
+dYf5U8 DN YTR5*2.U8
+dYf6U8 DN YTR6*2.U8
+dYf7U8 DN YTR7*2.U8
+
+ ;//
+ ;// Do saturation if outsize is other than S16
+ ;//
+
+ IF ("$outsize"="u8")
+ ;// Output range [0-255]
+ VQMOVN dYf0U8, qYf0
+ VQMOVN dYf1U8, qYf1
+ VQMOVN dYf2U8, qYf2
+ VQMOVN dYf3U8, qYf3
+ VQMOVN dYf4U8, qYf4
+ VQMOVN dYf5U8, qYf5
+ VQMOVN dYf6U8, qYf6
+ VQMOVN dYf7U8, qYf7
+ ENDIF
+
+ IF ("$outsize"="s9")
+ ;// Output range [-256 to +255]
+ VQSHL qYf0, qYf0, #16-9
+ VQSHL qYf1, qYf1, #16-9
+ VQSHL qYf2, qYf2, #16-9
+ VQSHL qYf3, qYf3, #16-9
+ VQSHL qYf4, qYf4, #16-9
+ VQSHL qYf5, qYf5, #16-9
+ VQSHL qYf6, qYf6, #16-9
+ VQSHL qYf7, qYf7, #16-9
+
+ VSHR qYf0, qYf0, #16-9
+ VSHR qYf1, qYf1, #16-9
+ VSHR qYf2, qYf2, #16-9
+ VSHR qYf3, qYf3, #16-9
+ VSHR qYf4, qYf4, #16-9
+ VSHR qYf5, qYf5, #16-9
+ VSHR qYf6, qYf6, #16-9
+ VSHR qYf7, qYf7, #16-9
+ ENDIF
+
+ ;// Store output depending on the Stride size
+ IF "$stride"="s"
+ VST1 qYf0, [pDest @64], Stride
+ VST1 qYf1, [pDest @64], Stride
+ VST1 qYf2, [pDest @64], Stride
+ VST1 qYf3, [pDest @64], Stride
+ VST1 qYf4, [pDest @64], Stride
+ VST1 qYf5, [pDest @64], Stride
+ VST1 qYf6, [pDest @64], Stride
+ VST1 qYf7, [pDest @64]
+ ELSE
+ IF ("$outsize"="u8")
+ VST1 dYf0U8, [pDest @64], #8
+ VST1 dYf1U8, [pDest @64], #8
+ VST1 dYf2U8, [pDest @64], #8
+ VST1 dYf3U8, [pDest @64], #8
+ VST1 dYf4U8, [pDest @64], #8
+ VST1 dYf5U8, [pDest @64], #8
+ VST1 dYf6U8, [pDest @64], #8
+ VST1 dYf7U8, [pDest @64]
+ ELSE
+ ;// ("$outsize"="s9") or ("$outsize"="s16")
+ VST1 qYf0, [pDest @64], #16
+ VST1 qYf1, [pDest @64], #16
+ VST1 qYf2, [pDest @64], #16
+ VST1 qYf3, [pDest @64], #16
+ VST1 qYf4, [pDest @64], #16
+ VST1 qYf5, [pDest @64], #16
+ VST1 qYf6, [pDest @64], #16
+ VST1 qYf7, [pDest @64]
+ ENDIF
+
+ ENDIF
+
+
+
+ ENDIF ;// CortexA8
+
+
+
+ MEND
+
+ ;// Scale TWO input rows with TWO rows of 16 bit scale values
+ ;//
+ ;// This macro is used by M_IDCT_PRESCALE16 to pre-scale one row
+ ;// input (Eight input values) with one row of scale values. Also
+ ;// Loads next scale values from pScale, if $LastRow flag is not set.
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// $dAlo - Input D register with first four S16 values of row n
+ ;// $dAhi - Input D register with next four S16 values of row n
+ ;// $dBlo - Input D register with first four S16 values of row n+1
+ ;// $dBhi - Input D register with next four S16 values of row n+1
+ ;// pScale - Pointer to next row of scale values
+ ;// qT0lo - Temporary scratch register
+ ;// qT0hi - Temporary scratch register
+ ;// qT1lo - Temporary scratch register
+ ;// qT1hi - Temporary scratch register
+ ;// dScale1lo - Scale value of row n
+ ;// dScale1hi - Scale value of row n
+ ;// dScale2lo - Scale value of row n+1
+ ;// dScale2hi - Scale value of row n+1
+ ;//
+ ;// Input Flag
+ ;//
+ ;// $LastRow - Flag to indicate whether current row is last row
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// $dAlo - Scaled output values (first four S16 of row n)
+ ;// $dAhi - Scaled output values (next four S16 of row n)
+ ;// $dBlo - Scaled output values (first four S16 of row n+1)
+ ;// $dBhi - Scaled output values (next four S16 of row n+1)
+ ;// qScale1 - Scale values for next row
+ ;// qScale2 - Scale values for next row+1
+ ;// pScale - Pointer to next row of scale values
+ ;//
+ MACRO
+ M_IDCT_SCALE16 $dAlo, $dAhi, $dBlo, $dBhi, $LastRow
+ VMULL qT0lo, $dAlo, dScale1lo
+ VMULL qT0hi, $dAhi, dScale1hi
+ VMULL qT1lo, $dBlo, dScale2lo
+ VMULL qT1hi, $dBhi, dScale2hi
+ IF "$LastRow"="0"
+ VLD1 qScale1, [pScale], #16 ;// Load scale for row n+1
+ VLD1 qScale2, [pScale], #16 ;// Load scale for row n+2
+ ENDIF
+ VQRSHRN $dAlo, qT0lo, #12
+ VQRSHRN $dAhi, qT0hi, #12
+ VQRSHRN $dBlo, qT1lo, #12
+ VQRSHRN $dBhi, qT1hi, #12
+ MEND
+
+ ;// Scale 8x8 block input values with 16 bit scale values
+ ;//
+ ;// This macro is used to pre-scale block of 8x8 input.
+ ;// This also do the Ist stage transformations of IDCT.
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// dXjnlo - n th input D register with first four S16 values
+ ;// dXjnhi - n th input D register with next four S16 values
+ ;// qXjn - n th input Q register with eight S16 values
+ ;// pScale - Pointer to scale values
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// qXin - n th output Q register with eight S16 output values of 1st stage
+ ;//
+ MACRO
+ M_IDCT_PRESCALE16
+ VLD1 qScale1, [pScale], #16 ;// Load Pre scale for row 0
+ VLD1 qScale2, [pScale], #16 ;// Load Pre scale for row 0
+ M_IDCT_SCALE16 dXj0lo, dXj0hi, dXj1lo, dXj1hi, 0 ;// Pre scale row 0 & 1
+ M_IDCT_SCALE16 dXj2lo, dXj2hi, dXj3lo, dXj3hi, 0
+ M_IDCT_SCALE16 dXj4lo, dXj4hi, dXj5lo, dXj5hi, 0
+ M_IDCT_SCALE16 dXj6lo, dXj6hi, dXj7lo, dXj7hi, 1
+ VHADD qXi5, qXj1, qXj7 ;// (j1+j7)/2
+ VSUB qXi6, qXj1, qXj7 ;// j1-j7
+ LDR pSrc, =armCOMM_IDCTCoef ;// Address of DCT inverse AAN constants
+ VHADD qXi3, qXj2, qXj6 ;// (j2+j6)/2
+ VSUB qXi2, qXj2, qXj6 ;// j2-j6
+ VLDR dCoefs, [pSrc] ;// Load DCT inverse AAN constants
+ VHADD qXi7, qXj5, qXj3 ;// (j5+j3)/2
+ VSUB qXi4, qXj5, qXj3 ;// j5-j3
+ MEND
+
+
+ ;// Scale 8x8 block input values with 32 bit scale values
+ ;//
+ ;// This macro is used to pre-scale block of 8x8 input.
+ ;// This also do the Ist stage transformations of IDCT.
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// dXjnlo - n th input D register with first four S16 values
+ ;// dXjnhi - n th input D register with next four S16 values
+ ;// qXjn - n th input Q register with eight S16 values
+ ;// pScale - Pointer to 32bit scale values in Q23 format
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// dXinlo - n th output D register with first four S16 output values of 1st stage
+ ;// dXinhi - n th output D register with next four S16 output values of 1st stage
+ ;//
+ MACRO
+ M_IDCT_PRESCALE32
+qScale0lo QN 0.S32
+qScale0hi QN 1.S32
+qScale1lo QN 2.S32
+qScale1hi QN 3.S32
+qScale2lo QN qScale1lo
+qScale2hi QN qScale1hi
+qScale3lo QN qScale1lo
+qScale3hi QN qScale1hi
+qScale4lo QN qScale1lo
+qScale4hi QN qScale1hi
+qScale5lo QN qScale0lo
+qScale5hi QN qScale0hi
+qScale6lo QN qScale0lo
+qScale6hi QN qScale0hi
+qScale7lo QN qScale0lo
+qScale7hi QN qScale0hi
+
+qSrc0lo QN 4.S32
+qSrc0hi QN 5.S32
+qSrc1lo QN 6.S32
+qSrc1hi QN Src4.S32
+qSrc2lo QN qSrc0lo
+qSrc2hi QN qSrc0hi
+qSrc3lo QN qSrc0lo
+qSrc3hi QN qSrc0hi
+qSrc4lo QN qSrc0lo
+qSrc4hi QN qSrc0hi
+qSrc5lo QN qSrc1lo
+qSrc5hi QN qSrc1hi
+qSrc6lo QN qSrc1lo
+qSrc6hi QN qSrc1hi
+qSrc7lo QN qSrc0lo
+qSrc7hi QN qSrc0hi
+
+qRes17lo QN qScale0lo
+qRes17hi QN qScale0hi
+qRes26lo QN qScale0lo
+qRes26hi QN qScale0hi
+qRes53lo QN qScale0lo
+qRes53hi QN qScale0hi
+
+ ADD pTemp, pScale, #4*8*7 ;// Address of pScale[7]
+
+ ;// Row 0
+ VLD1 {qScale0lo, qScale0hi}, [pScale]!
+ VSHLL qSrc0lo, dXj0lo, #(12-1)
+ VSHLL qSrc0hi, dXj0hi, #(12-1)
+ VLD1 {qScale1lo, qScale1hi}, [pScale]!
+ VQRDMULH qSrc0lo, qScale0lo, qSrc0lo
+ VQRDMULH qSrc0hi, qScale0hi, qSrc0hi
+ VLD1 {qScale7lo, qScale7hi}, [pTemp]!
+ VSHLL qSrc1lo, dXj1lo, #(12-1)
+ VSHLL qSrc1hi, dXj1hi, #(12-1)
+ VMOVN dXi0lo, qSrc0lo ;// Output i0
+ VMOVN dXi0hi, qSrc0hi
+ VSHLL qSrc7lo, dXj7lo, #(12-1)
+ VSHLL qSrc7hi, dXj7hi, #(12-1)
+ SUB pTemp, pTemp, #((16*2)+(4*8*1))
+ VQRDMULH qSrc1lo, qScale1lo, qSrc1lo
+ VQRDMULH qSrc1hi, qScale1hi, qSrc1hi
+ VQRDMULH qSrc7lo, qScale7lo, qSrc7lo
+ VQRDMULH qSrc7hi, qScale7hi, qSrc7hi
+ VLD1 {qScale2lo, qScale2hi}, [pScale]!
+
+ ;// Row 1 & 7
+ VHADD qRes17lo, qSrc1lo, qSrc7lo ;// (j1+j7)/2
+ VHADD qRes17hi, qSrc1hi, qSrc7hi ;// (j1+j7)/2
+ VMOVN dXi5lo, qRes17lo ;// Output i5
+ VMOVN dXi5hi, qRes17hi
+ VSUB qRes17lo, qSrc1lo, qSrc7lo ;// j1-j7
+ VSUB qRes17hi, qSrc1hi, qSrc7hi ;// j1-j7
+ VMOVN dXi6lo, qRes17lo ;// Output i6
+ VMOVN dXi6hi, qRes17hi
+ VSHLL qSrc2lo, dXj2lo, #(12-1)
+ VSHLL qSrc2hi, dXj2hi, #(12-1)
+ VLD1 {qScale6lo, qScale6hi}, [pTemp]!
+ VSHLL qSrc6lo, dXj6lo, #(12-1)
+ VSHLL qSrc6hi, dXj6hi, #(12-1)
+ SUB pTemp, pTemp, #((16*2)+(4*8*1))
+ VQRDMULH qSrc2lo, qScale2lo, qSrc2lo
+ VQRDMULH qSrc2hi, qScale2hi, qSrc2hi
+ VQRDMULH qSrc6lo, qScale6lo, qSrc6lo
+ VQRDMULH qSrc6hi, qScale6hi, qSrc6hi
+ VLD1 {qScale3lo, qScale3hi}, [pScale]!
+
+ ;// Row 2 & 6
+ VHADD qRes26lo, qSrc2lo, qSrc6lo ;// (j2+j6)/2
+ VHADD qRes26hi, qSrc2hi, qSrc6hi ;// (j2+j6)/2
+ VMOVN dXi3lo, qRes26lo ;// Output i3
+ VMOVN dXi3hi, qRes26hi
+ VSUB qRes26lo, qSrc2lo, qSrc6lo ;// j2-j6
+ VSUB qRes26hi, qSrc2hi, qSrc6hi ;// j2-j6
+ VMOVN dXi2lo, qRes26lo ;// Output i2
+ VMOVN dXi2hi, qRes26hi
+ VSHLL qSrc3lo, dXj3lo, #(12-1)
+ VSHLL qSrc3hi, dXj3hi, #(12-1)
+ VLD1 {qScale5lo, qScale5hi}, [pTemp]!
+ VSHLL qSrc5lo, dXj5lo, #(12-1)
+ VSHLL qSrc5hi, dXj5hi, #(12-1)
+ VQRDMULH qSrc3lo, qScale3lo, qSrc3lo
+ VQRDMULH qSrc3hi, qScale3hi, qSrc3hi
+ VQRDMULH qSrc5lo, qScale5lo, qSrc5lo
+ VQRDMULH qSrc5hi, qScale5hi, qSrc5hi
+
+ ;// Row 3 & 5
+ VHADD qRes53lo, qSrc5lo, qSrc3lo ;// (j5+j3)/2
+ VHADD qRes53hi, qSrc5hi, qSrc3hi ;// (j5+j3)/2
+ SUB pSrc, pSrc, #16*2*2
+ VMOVN dXi7lo, qRes53lo ;// Output i7
+ VMOVN dXi7hi, qRes53hi
+ VSUB qRes53lo, qSrc5lo, qSrc3lo ;// j5-j3
+ VSUB qRes53hi, qSrc5hi, qSrc3hi ;// j5-j3
+ VLD1 qXj4, [pSrc @64]
+ VMOVN dXi4lo, qRes53lo ;// Output i4
+ VMOVN dXi4hi, qRes53hi
+ VSHLL qSrc4lo, dXj4lo, #(12-1)
+ VSHLL qSrc4hi, dXj4hi, #(12-1)
+ VLD1 {qScale4lo, qScale4hi}, [pScale]
+ LDR pSrc, =armCOMM_IDCTCoef ;// Address of DCT inverse AAN constants
+ VQRDMULH qSrc4lo, qScale4lo, qSrc4lo
+ VQRDMULH qSrc4hi, qScale4hi, qSrc4hi
+ VLDR dCoefs, [pSrc] ;// Load DCT inverse AAN constants
+ ;// Row 4
+ VMOVN dXi1lo, qSrc4lo ;// Output i1
+ VMOVN dXi1hi, qSrc4hi
+
+ MEND
+
+ END
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_MaskTable.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_MaskTable.h
new file mode 100644
index 0000000..b5da9dc
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_MaskTable.h
@@ -0,0 +1,27 @@
+/**
+ *
+ * File Name: armCOMM_MaskTable.h
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Mask Table to mask the end of array
+ */
+
+
+
+#ifndef _ARMCOMM_MASKTABLE_H_
+#define _ARMCOMM_MASKTABLE_H_
+
+#define MaskTableSize 72
+
+/* Mask table */
+
+extern const OMX_U16 armCOMM_qMaskTable16[MaskTableSize];
+extern const OMX_U8 armCOMM_qMaskTable8[MaskTableSize];
+
+#endif
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_Version.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_Version.h
new file mode 100644
index 0000000..13e5b2b
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_Version.h
@@ -0,0 +1,43 @@
+/* Guard the header against multiple inclusion. */
+#ifndef __ARM_COMM_VERSION_H__
+#define __ARM_COMM_VERSION_H__
+
+
+/* The following line should be in omxtypes.h but hasn't been approved by OpenMAX yet */
+#define OMX_VERSION 102
+
+/* We need to define these macros in order to convert a #define number into a #define string. */
+#define ARM_QUOTE(a) #a
+#define ARM_INDIRECT(A) ARM_QUOTE(A)
+
+/* Convert the OMX_VERSION number into a string that can be used, for example, to print it out. */
+#define ARM_VERSION_STRING ARM_INDIRECT(OMX_VERSION)
+
+
+/* Define this in order to turn on ARM version/release/build strings in each domain */
+#define ARM_INCLUDE_VERSION_DESCRIPTIONS
+
+#ifdef ARM_INCLUDE_VERSION_DESCRIPTIONS
+ extern const char * const omxAC_VersionDescription;
+ extern const char * const omxIC_VersionDescription;
+ extern const char * const omxIP_VersionDescription;
+ extern const char * const omxSP_VersionDescription;
+ extern const char * const omxVC_VersionDescription;
+#endif /* ARM_INCLUDE_VERSION_DESCRIPTIONS */
+
+
+/* The following entries should be automatically updated by the release script */
+/* They are used in the ARM version strings defined for each domain. */
+
+/* The release tag associated with this release of the library. - used for source and object releases */
+#define OMX_ARM_RELEASE_TAG "r0p0-00bet1"
+
+/* The ARM architecture used to build any objects or executables in this release. */
+#define OMX_ARM_BUILD_ARCHITECTURE "ARM Architecture V6"
+
+/* The ARM Toolchain used to build any objects or executables in this release. */
+#define OMX_ARM_BUILD_TOOLCHAIN "ARM RVCT 3.1"
+
+
+#endif /* __ARM_COMM_VERSION_H__ */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_s.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_s.h
new file mode 100644
index 0000000..2df1fc8
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_s.h
@@ -0,0 +1,1154 @@
+;//
+;//
+;// File Name: armCOMM_s.h
+;// OpenMAX DL: v1.0.2
+;// Revision: 9641
+;// Date: Thursday, February 7, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+;// ARM optimized OpenMAX common header file
+;//
+
+;// Protect against multiple inclusion
+ IF :LNOT::DEF:ARMCOMM_S_H
+ GBLL ARMCOMM_S_H
+
+ REQUIRE8 ;// Requires 8-byte stack alignment
+ PRESERVE8 ;// Preserves 8-byte stack alignment
+
+ GBLL ARM_ERRORCHECK
+ARM_ERRORCHECK SETL {FALSE}
+
+;// Globals
+
+ GBLS _RRegList ;// R saved register list
+ GBLS _DRegList ;// D saved register list
+ GBLS _Variant ;// Selected processor variant
+ GBLS _CPU ;// CPU name
+ GBLS _Struct ;// Structure name
+
+ GBLL _InFunc ;// Inside function assembly flag
+ GBLL _SwLong ;// Long switch flag
+
+ GBLA _RBytes ;// Number of register bytes on stack
+ GBLA _SBytes ;// Number of scratch bytes on stack
+ GBLA _ABytes ;// Stack offset of next argument
+ GBLA _Workspace ;// Stack offset of scratch workspace
+ GBLA _F ;// Function number
+ GBLA _StOff ;// Struct offset
+ GBLA _SwNum ;// Switch number
+ GBLS _32 ;// Suffix for 32 byte alignmnet
+ GBLS _16 ;// Suffix for 16 byte alignmnet
+
+_InFunc SETL {FALSE}
+_SBytes SETA 0
+_F SETA 0
+_SwNum SETA 0
+_32 SETS "ALIGN32"
+_16 SETS "ALIGN16"
+
+;/////////////////////////////////////////////////////////
+;// Override the tools settings of the CPU if the #define
+;// USECPU is set, otherwise use the CPU defined by the
+;// assembler settings.
+;/////////////////////////////////////////////////////////
+
+ IF :DEF: OVERRIDECPU
+_CPU SETS OVERRIDECPU
+ ELSE
+_CPU SETS {CPU}
+ ENDIF
+
+
+
+;/////////////////////////////////////////////////////////
+;// Work out which code to build
+;/////////////////////////////////////////////////////////
+
+ IF :DEF:ARM1136JS:LOR::DEF:CortexA8:LOR::DEF:ARM_GENERIC
+ INFO 1,"Please switch to using M_VARIANTS"
+ ENDIF
+
+ ;// Define and reset all officially recongnised variants
+ MACRO
+ _M_DEF_VARIANTS
+ _M_DEF_VARIANT ARM926EJS
+ _M_DEF_VARIANT ARM1136JS
+ _M_DEF_VARIANT ARM1136JS_U
+ _M_DEF_VARIANT CortexA8
+ _M_DEF_VARIANT ARM7TDMI
+ MEND
+
+ MACRO
+ _M_DEF_VARIANT $var
+ GBLL $var
+ GBLL _ok$var
+$var SETL {FALSE}
+ MEND
+
+
+ ;// Variant declaration
+ ;//
+ ;// Define a list of code variants supported by this
+ ;// source file. This macro then chooses the most
+ ;// appropriate variant to build for the currently configured
+ ;// core.
+ ;//
+ MACRO
+ M_VARIANTS $v0,$v1,$v2,$v3,$v4,$v5,$v6,$v7
+ ;// Set to TRUE variants that are supported
+ _M_DEF_VARIANTS
+ _M_VARIANT $v0
+ _M_VARIANT $v1
+ _M_VARIANT $v2
+ _M_VARIANT $v3
+ _M_VARIANT $v4
+ _M_VARIANT $v5
+ _M_VARIANT $v6
+ _M_VARIANT $v7
+
+ ;// Look for first available variant to match a CPU
+ ;// _M_TRY cpu, variant fall back list
+_Variant SETS ""
+ _M_TRY ARM926EJ-S, ARM926EJS
+ _M_TRY ARM1176JZ-S, ARM1136JS
+ _M_TRY ARM1176JZF-S, ARM1136JS
+ _M_TRY ARM1156T2-S, ARM1136JS
+ _M_TRY ARM1156T2F-S, ARM1136JS
+ _M_TRY ARM1136J-S, ARM1136JS
+ _M_TRY ARM1136JF-S, ARM1136JS
+ _M_TRY MPCore, ARM1136JS
+ _M_TRY Cortex-A8, CortexA8, ARM1136JS
+ _M_TRY Cortex-R4, ARM1136JS
+ _M_TRY ARM7TDMI
+
+ ;// Select the correct variant
+ _M_DEF_VARIANTS
+ IF _Variant=""
+ INFO 1, "No match found for CPU '$_CPU'"
+ ELSE
+$_Variant SETL {TRUE}
+ ENDIF
+ MEND
+
+ ;// Register a variant as available
+ MACRO
+ _M_VARIANT $var
+ IF "$var"=""
+ MEXIT
+ ENDIF
+ IF :LNOT::DEF:_ok$var
+ INFO 1, "Unrecognized variant '$var'"
+ ENDIF
+$var SETL {TRUE}
+ MEND
+
+ ;// For a given CPU, see if any of the variants supporting
+ ;// this CPU are available. The first available variant is
+ ;// chosen
+ MACRO
+ _M_TRY $cpu, $v0,$v1,$v2,$v3,$v4,$v5,$v6,$v7
+ IF "$cpu"<>_CPU
+ MEXIT
+ ENDIF
+ _M_TRY1 $v0
+ _M_TRY1 $v1
+ _M_TRY1 $v2
+ _M_TRY1 $v3
+ _M_TRY1 $v4
+ _M_TRY1 $v5
+ _M_TRY1 $v6
+ _M_TRY1 $v7
+ ;// Check a match was found
+ IF _Variant=""
+ INFO 1, "No variant match found for CPU '$_CPU'"
+ ENDIF
+ MEND
+
+ MACRO
+ _M_TRY1 $var
+ IF "$var"=""
+ MEXIT
+ ENDIF
+ IF (_Variant=""):LAND:$var
+_Variant SETS "$var"
+ ENDIF
+ MEND
+
+;////////////////////////////////////////////////////////
+;// Structure definition
+;////////////////////////////////////////////////////////
+
+ ;// Declare a structure of given name
+ MACRO
+ M_STRUCT $sname
+_Struct SETS "$sname"
+_StOff SETA 0
+ MEND
+
+ ;// Declare a structure field
+ ;// The field is called $sname_$fname
+ ;// $size = the size of each entry, must be power of 2
+ ;// $number = (if provided) the number of entries for an array
+ MACRO
+ M_FIELD $fname, $size, $number
+ IF (_StOff:AND:($size-1))!=0
+_StOff SETA _StOff + ($size - (_StOff:AND:($size-1)))
+ ENDIF
+$_Struct._$fname EQU _StOff
+ IF "$number"<>""
+_StOff SETA _StOff + $size*$number
+ ELSE
+_StOff SETA _StOff + $size
+ ENDIF
+ MEND
+
+
+ MACRO
+ M_ENDSTRUCT
+sizeof_$_Struct EQU _StOff
+_Struct SETS ""
+ MEND
+
+;//////////////////////////////////////////////////////////
+;// Switch and table macros
+;//////////////////////////////////////////////////////////
+
+ ;// Start a relative switch table with register to switch on
+ ;//
+ ;// $v = the register to switch on
+ ;// $s = if specified must be "L" to indicate long
+ ;// this allows a greater range to the case code
+ MACRO
+ M_SWITCH $v, $s
+ ASSERT "$s"="":LOR:"$s"="L"
+_SwLong SETL {FALSE}
+ IF "$s"="L"
+_SwLong SETL {TRUE}
+ ENDIF
+_SwNum SETA _SwNum+1
+ IF {CONFIG}=16
+ ;// Thumb
+ IF _SwLong
+ TBH [pc, $v, LSL#1]
+ ELSE
+ TBB [pc, $v]
+ ENDIF
+_Switch$_SwNum
+ ELSE
+ ;// ARM
+ ADD pc, pc, $v, LSL #2
+ NOP
+ ENDIF
+ MEND
+
+ ;// Add a case to the switch statement
+ MACRO
+ M_CASE $label
+ IF {CONFIG}=16
+ ;// Thumb
+ IF _SwLong
+ DCW ($label - _Switch$_SwNum)/2
+ ELSE
+ DCB ($label - _Switch$_SwNum)/2
+ ENDIF
+ ELSE
+ ;// ARM
+ B $label
+ ENDIF
+ MEND
+
+ ;// End of switch statement
+ MACRO
+ M_ENDSWITCH
+ ALIGN 2
+ MEND
+
+
+;////////////////////////////////////////////////////////
+;// Data area allocation
+;////////////////////////////////////////////////////////
+
+ ;// Constant table allocator macro
+ ;//
+ ;// Creates a new section for each constant table
+ ;// $name is symbol through which the table can be accessed.
+ ;// $align is the optional alignment of the table, log2 of
+ ;// the byte alignment - $align=4 is 16 byte aligned
+ MACRO
+ M_TABLE $name, $align
+ ASSERT :LNOT:_InFunc
+ IF "$align"=""
+ AREA |.constdata|, READONLY, DATA
+ ELSE
+ ;// AREAs inherit the alignment of the first declaration.
+ ;// Therefore for each alignment size we must have an area
+ ;// of a different name.
+ AREA constdata_a$align, READONLY, DATA, ALIGN=$align
+
+ ;// We also force alignment incase we are tagging onto
+ ;// an already started area.
+ ALIGN (1<<$align)
+ ENDIF
+$name
+ MEND
+
+;/////////////////////////////////////////////////////
+;// Macros to allocate space on the stack
+;//
+;// These all assume that the stack is 8-byte aligned
+;// at entry to the function, which means that the
+;// 32-byte alignment macro needs to work in a
+;// bit more of a special way...
+;/////////////////////////////////////////////////////
+
+
+
+
+ ;// Allocate 1-byte aligned area of name
+ ;// $name size $size bytes.
+ MACRO
+ M_ALLOC1 $name, $size
+ ASSERT :LNOT:_InFunc
+$name$_F EQU _SBytes
+_SBytes SETA _SBytes + ($size)
+ MEND
+
+ ;// Allocate 2-byte aligned area of name
+ ;// $name size $size bytes.
+ MACRO
+ M_ALLOC2 $name, $size
+ ASSERT :LNOT:_InFunc
+ IF (_SBytes:AND:1)!=0
+_SBytes SETA _SBytes + (2 - (_SBytes:AND:1))
+ ENDIF
+$name$_F EQU _SBytes
+_SBytes SETA _SBytes + ($size)
+ MEND
+
+ ;// Allocate 4-byte aligned area of name
+ ;// $name size $size bytes.
+ MACRO
+ M_ALLOC4 $name, $size
+ ASSERT :LNOT:_InFunc
+ IF (_SBytes:AND:3)!=0
+_SBytes SETA _SBytes + (4 - (_SBytes:AND:3))
+ ENDIF
+$name$_F EQU _SBytes
+_SBytes SETA _SBytes + ($size)
+ MEND
+
+ ;// Allocate 8-byte aligned area of name
+ ;// $name size $size bytes.
+ MACRO
+ M_ALLOC8 $name, $size
+ ASSERT :LNOT:_InFunc
+ IF (_SBytes:AND:7)!=0
+_SBytes SETA _SBytes + (8 - (_SBytes:AND:7))
+ ENDIF
+$name$_F EQU _SBytes
+_SBytes SETA _SBytes + ($size)
+ MEND
+
+
+ ;// Allocate 8-byte aligned area of name
+ ;// $name size ($size+16) bytes.
+ ;// The extra 16 bytes are later used to align the pointer to 16 bytes
+
+ MACRO
+ M_ALLOC16 $name, $size
+ ASSERT :LNOT:_InFunc
+ IF (_SBytes:AND:7)!=0
+_SBytes SETA _SBytes + (8 - (_SBytes:AND:7))
+ ENDIF
+$name$_F$_16 EQU (_SBytes + 8)
+_SBytes SETA _SBytes + ($size) + 8
+ MEND
+
+ ;// Allocate 8-byte aligned area of name
+ ;// $name size ($size+32) bytes.
+ ;// The extra 32 bytes are later used to align the pointer to 32 bytes
+
+ MACRO
+ M_ALLOC32 $name, $size
+ ASSERT :LNOT:_InFunc
+ IF (_SBytes:AND:7)!=0
+_SBytes SETA _SBytes + (8 - (_SBytes:AND:7))
+ ENDIF
+$name$_F$_32 EQU (_SBytes + 24)
+_SBytes SETA _SBytes + ($size) + 24
+ MEND
+
+
+
+
+ ;// Argument Declaration Macro
+ ;//
+ ;// Allocate an argument name $name
+ ;// size $size bytes
+ MACRO
+ M_ARG $name, $size
+ ASSERT _InFunc
+$name$_F EQU _ABytes
+_ABytes SETA _ABytes + ($size)
+ MEND
+
+;///////////////////////////////////////////////
+;// Macros to access stacked variables
+;///////////////////////////////////////////////
+
+ ;// Macro to perform a data processing operation
+ ;// with a constant second operand
+ MACRO
+ _M_OPC $op,$rd,$rn,$const
+ LCLA _sh
+ LCLA _cst
+_sh SETA 0
+_cst SETA $const
+ IF _cst=0
+ $op $rd, $rn, #_cst
+ MEXIT
+ ENDIF
+ WHILE (_cst:AND:3)=0
+_cst SETA _cst>>2
+_sh SETA _sh+2
+ WEND
+ $op $rd, $rn, #(_cst:AND:0x000000FF)<<_sh
+ IF _cst>=256
+ $op $rd, $rd, #(_cst:AND:0xFFFFFF00)<<_sh
+ ENDIF
+ MEND
+
+ ;// Macro to perform a data access operation
+ ;// Such as LDR or STR
+ ;// The addressing mode is modified such that
+ ;// 1. If no address is given then the name is taken
+ ;// as a stack offset
+ ;// 2. If the addressing mode is not available for the
+ ;// state being assembled for (eg Thumb) then a suitable
+ ;// addressing mode is substituted.
+ ;//
+ ;// On Entry:
+ ;// $i = Instruction to perform (eg "LDRB")
+ ;// $a = Required byte alignment
+ ;// $r = Register(s) to transfer (eg "r1")
+ ;// $a0,$a1,$a2. Addressing mode and condition. One of:
+ ;// label {,cc}
+ ;// [base] {,,,cc}
+ ;// [base, offset]{!} {,,cc}
+ ;// [base, offset, shift]{!} {,cc}
+ ;// [base], offset {,,cc}
+ ;// [base], offset, shift {,cc}
+ MACRO
+ _M_DATA $i,$a,$r,$a0,$a1,$a2,$a3
+ IF "$a0":LEFT:1="["
+ IF "$a1"=""
+ $i$a3 $r, $a0
+ ELSE
+ IF "$a0":RIGHT:1="]"
+ IF "$a2"=""
+ _M_POSTIND $i$a3, "$r", $a0, $a1
+ ELSE
+ _M_POSTIND $i$a3, "$r", $a0, "$a1,$a2"
+ ENDIF
+ ELSE
+ IF "$a2"=""
+ _M_PREIND $i$a3, "$r", $a0, $a1
+ ELSE
+ _M_PREIND $i$a3, "$r", $a0, "$a1,$a2"
+ ENDIF
+ ENDIF
+ ENDIF
+ ELSE
+ LCLA _Offset
+_Offset SETA _Workspace + $a0$_F
+ ASSERT (_Offset:AND:($a-1))=0
+ $i$a1 $r, [sp, #_Offset]
+ ENDIF
+ MEND
+
+ ;// Handle post indexed load/stores
+ ;// op reg, [base], offset
+ MACRO
+ _M_POSTIND $i,$r,$a0,$a1
+ LCLS _base
+ LCLS _offset
+ IF {CONFIG}=16 ;// Thumb
+_base SETS ("$a0":LEFT:(:LEN:"$a0"-1)):RIGHT:(:LEN:"$a0"-2) ;// remove []
+_offset SETS "$a1"
+ IF _offset:LEFT:1="+"
+_offset SETS _offset:RIGHT:(:LEN:_offset-1)
+ ENDIF
+ $i $r, $a0
+ IF _offset:LEFT:1="-"
+_offset SETS _offset:RIGHT:(:LEN:_offset-1)
+ SUB $_base, $_base, $_offset
+ ELSE
+ ADD $_base, $_base, $_offset
+ ENDIF
+ ELSE ;// ARM
+ $i $r, $a0, $a1
+ ENDIF
+ MEND
+
+ ;// Handle pre indexed load/store
+ ;// op reg, [base, offset]{!}
+ MACRO
+ _M_PREIND $i,$r,$a0,$a1
+ LCLS _base
+ LCLS _offset
+ IF ({CONFIG}=16):LAND:(("$a1":RIGHT:2)="]!")
+_base SETS "$a0":RIGHT:(:LEN:("$a0")-1)
+_offset SETS "$a1":LEFT:(:LEN:("$a1")-2)
+ $i $r, [$_base, $_offset]
+ ADD $_base, $_base, $_offset
+ ELSE
+ $i $r, $a0, $a1
+ ENDIF
+ MEND
+
+ ;// Load unsigned byte from stack
+ MACRO
+ M_LDRB $r,$a0,$a1,$a2,$a3
+ _M_DATA "LDRB",1,$r,$a0,$a1,$a2,$a3
+ MEND
+
+ ;// Load signed byte from stack
+ MACRO
+ M_LDRSB $r,$a0,$a1,$a2,$a3
+ _M_DATA "LDRSB",1,$r,$a0,$a1,$a2,$a3
+ MEND
+
+ ;// Store byte to stack
+ MACRO
+ M_STRB $r,$a0,$a1,$a2,$a3
+ _M_DATA "STRB",1,$r,$a0,$a1,$a2,$a3
+ MEND
+
+ ;// Load unsigned half word from stack
+ MACRO
+ M_LDRH $r,$a0,$a1,$a2,$a3
+ _M_DATA "LDRH",2,$r,$a0,$a1,$a2,$a3
+ MEND
+
+ ;// Load signed half word from stack
+ MACRO
+ M_LDRSH $r,$a0,$a1,$a2,$a3
+ _M_DATA "LDRSH",2,$r,$a0,$a1,$a2,$a3
+ MEND
+
+ ;// Store half word to stack
+ MACRO
+ M_STRH $r,$a0,$a1,$a2,$a3
+ _M_DATA "STRH",2,$r,$a0,$a1,$a2,$a3
+ MEND
+
+ ;// Load word from stack
+ MACRO
+ M_LDR $r,$a0,$a1,$a2,$a3
+ _M_DATA "LDR",4,$r,$a0,$a1,$a2,$a3
+ MEND
+
+ ;// Store word to stack
+ MACRO
+ M_STR $r,$a0,$a1,$a2,$a3
+ _M_DATA "STR",4,$r,$a0,$a1,$a2,$a3
+ MEND
+
+ ;// Load double word from stack
+ MACRO
+ M_LDRD $r0,$r1,$a0,$a1,$a2,$a3
+ _M_DATA "LDRD",8,"$r0,$r1",$a0,$a1,$a2,$a3
+ MEND
+
+ ;// Store double word to stack
+ MACRO
+ M_STRD $r0,$r1,$a0,$a1,$a2,$a3
+ _M_DATA "STRD",8,"$r0,$r1",$a0,$a1,$a2,$a3
+ MEND
+
+ ;// Get absolute address of stack allocated location
+ MACRO
+ M_ADR $a, $b, $cc
+ _M_OPC ADD$cc, $a, sp, (_Workspace + $b$_F)
+ MEND
+
+ ;// Get absolute address of stack allocated location and align the address to 16 bytes
+ MACRO
+ M_ADR16 $a, $b, $cc
+ _M_OPC ADD$cc, $a, sp, (_Workspace + $b$_F$_16)
+
+ ;// Now align $a to 16 bytes
+ BIC$cc $a,$a,#0x0F
+ MEND
+
+ ;// Get absolute address of stack allocated location and align the address to 32 bytes
+ MACRO
+ M_ADR32 $a, $b, $cc
+ _M_OPC ADD$cc, $a, sp, (_Workspace + $b$_F$_32)
+
+ ;// Now align $a to 32 bytes
+ BIC$cc $a,$a,#0x1F
+ MEND
+
+;//////////////////////////////////////////////////////////
+;// Function header and footer macros
+;//////////////////////////////////////////////////////////
+
+ ;// Function Header Macro
+ ;// Generates the function prologue
+ ;// Note that functions should all be "stack-moves-once"
+ ;// The FNSTART and FNEND macros should be the only places
+ ;// where the stack moves.
+ ;//
+ ;// $name = function name
+ ;// $rreg = "" don't stack any registers
+ ;// "lr" stack "lr" only
+ ;// "rN" stack registers "r4-rN,lr"
+ ;// $dreg = "" don't stack any D registers
+ ;// "dN" stack registers "d8-dN"
+ ;//
+ ;// Note: ARM Archicture procedure call standard AAPCS
+ ;// states that r4-r11, sp, d8-d15 must be preserved by
+ ;// a compliant function.
+ MACRO
+ M_START $name, $rreg, $dreg
+ ASSERT :LNOT:_InFunc
+ ASSERT "$name"!=""
+_InFunc SETL {TRUE}
+_RBytes SETA 0
+_Workspace SETA 0
+
+ ;// Create an area for the function
+ AREA |.text|, CODE
+ EXPORT $name
+$name FUNCTION
+
+ ;// Save R registers
+ _M_GETRREGLIST $rreg
+ IF _RRegList<>""
+ STMFD sp!, {$_RRegList, lr}
+ ENDIF
+
+ ;// Save D registers
+ _M_GETDREGLIST $dreg
+ IF _DRegList<>""
+ VSTMFD sp!, {$_DRegList}
+ ENDIF
+
+
+ ;// Ensure size claimed on stack is 8-byte aligned
+ IF ((_SBytes:AND:7)!=0)
+_SBytes SETA _SBytes + (8 - (_SBytes:AND:7))
+ ENDIF
+
+ IF (_SBytes!=0)
+ _M_OPC SUB, sp, sp, _SBytes
+ ENDIF
+
+
+_ABytes SETA _SBytes + _RBytes - _Workspace
+
+
+ ;// Print function name if debug enabled
+ M_PRINTF "$name\n",
+ MEND
+
+ ;// Work out a list of R saved registers
+ MACRO
+ _M_GETRREGLIST $rreg
+ IF "$rreg"=""
+_RRegList SETS ""
+ MEXIT
+ ENDIF
+ IF "$rreg"="lr":LOR:"$rreg"="r4"
+_RRegList SETS "r4"
+_RBytes SETA _RBytes+8
+ MEXIT
+ ENDIF
+ IF "$rreg"="r5":LOR:"$rreg"="r6"
+_RRegList SETS "r4-r6"
+_RBytes SETA _RBytes+16
+ MEXIT
+ ENDIF
+ IF "$rreg"="r7":LOR:"$rreg"="r8"
+_RRegList SETS "r4-r8"
+_RBytes SETA _RBytes+24
+ MEXIT
+ ENDIF
+ IF "$rreg"="r9":LOR:"$rreg"="r10"
+_RRegList SETS "r4-r10"
+_RBytes SETA _RBytes+32
+ MEXIT
+ ENDIF
+ IF "$rreg"="r11":LOR:"$rreg"="r12"
+_RRegList SETS "r4-r12"
+_RBytes SETA _RBytes+40
+ MEXIT
+ ENDIF
+ INFO 1, "Unrecognized saved r register limit '$rreg'"
+ MEND
+
+ ;// Work out a list of D saved registers
+ MACRO
+ _M_GETDREGLIST $dreg
+ IF "$dreg"=""
+_DRegList SETS ""
+ MEXIT
+ ENDIF
+ IF "$dreg"="d8"
+_DRegList SETS "d8"
+_RBytes SETA _RBytes+8
+ MEXIT
+ ENDIF
+ IF "$dreg"="d9"
+_DRegList SETS "d8-d9"
+_RBytes SETA _RBytes+16
+ MEXIT
+ ENDIF
+ IF "$dreg"="d10"
+_DRegList SETS "d8-d10"
+_RBytes SETA _RBytes+24
+ MEXIT
+ ENDIF
+ IF "$dreg"="d11"
+_DRegList SETS "d8-d11"
+_RBytes SETA _RBytes+32
+ MEXIT
+ ENDIF
+ IF "$dreg"="d12"
+_DRegList SETS "d8-d12"
+_RBytes SETA _RBytes+40
+ MEXIT
+ ENDIF
+ IF "$dreg"="d13"
+_DRegList SETS "d8-d13"
+_RBytes SETA _RBytes+48
+ MEXIT
+ ENDIF
+ IF "$dreg"="d14"
+_DRegList SETS "d8-d14"
+_RBytes SETA _RBytes+56
+ MEXIT
+ ENDIF
+ IF "$dreg"="d15"
+_DRegList SETS "d8-d15"
+_RBytes SETA _RBytes+64
+ MEXIT
+ ENDIF
+ INFO 1, "Unrecognized saved d register limit '$dreg'"
+ MEND
+
+ ;// Produce function return instructions
+ MACRO
+ _M_RET $cc
+ IF _DRegList<>""
+ VPOP$cc {$_DRegList}
+ ENDIF
+ IF _RRegList=""
+ BX$cc lr
+ ELSE
+ LDM$cc.FD sp!, {$_RRegList, pc}
+ ENDIF
+ MEND
+
+ ;// Early Function Exit Macro
+ ;// $cc = condition to exit with
+ ;// (Example: M_EXIT EQ)
+ MACRO
+ M_EXIT $cc
+ ASSERT _InFunc
+ IF _SBytes!=0
+ ;// Restore stack frame and exit
+ B$cc _End$_F
+ ELSE
+ ;// Can return directly
+ _M_RET $cc
+ ENDIF
+ MEND
+
+ ;// Function Footer Macro
+ ;// Generates the function epilogue
+ MACRO
+ M_END
+ ASSERT _InFunc
+_InFunc SETL {FALSE}
+_End$_F
+
+ ;// Restore the stack pointer to its original value on function entry
+ IF _SBytes!=0
+ _M_OPC ADD, sp, sp, _SBytes
+ ENDIF
+ _M_RET
+ ENDFUNC
+
+ ;// Reset the global stack tracking variables back to their
+ ;// initial values, and increment the function count
+_SBytes SETA 0
+_F SETA _F+1
+ MEND
+
+
+;//==========================================================================
+;// Debug Macros
+;//==========================================================================
+
+ GBLL DEBUG_ON
+DEBUG_ON SETL {FALSE}
+ GBLL DEBUG_STALLS_ON
+DEBUG_STALLS_ON SETL {FALSE}
+
+ ;//==========================================================================
+ ;// Debug call to printf
+ ;// M_PRINTF $format, $val0, $val1, $val2
+ ;//
+ ;// Examples:
+ ;// M_PRINTF "x=%08x\n", r0
+ ;//
+ ;// This macro preserves the value of all registers including the
+ ;// flags.
+ ;//==========================================================================
+
+ MACRO
+ M_PRINTF $format, $val0, $val1, $val2
+ IF DEBUG_ON
+
+ IMPORT printf
+ LCLA nArgs
+nArgs SETA 0
+
+ ;// save registers so we don't corrupt them
+ STMFD sp!, {r0-r12, lr}
+
+ ;// Drop stack to give us some workspace
+ SUB sp, sp, #16
+
+ ;// Save registers we need to print to the stack
+ IF "$val2" <> ""
+ ASSERT "$val1" <> ""
+ STR $val2, [sp, #8]
+nArgs SETA nArgs+1
+ ENDIF
+ IF "$val1" <> ""
+ ASSERT "$val0" <> ""
+ STR $val1, [sp, #4]
+nArgs SETA nArgs+1
+ ENDIF
+ IF "$val0"<>""
+ STR $val0, [sp]
+nArgs SETA nArgs+1
+ ENDIF
+
+ ;// Now we are safe to corrupt registers
+ ADR r0, %FT00
+ IF nArgs=1
+ LDR r1, [sp]
+ ENDIF
+ IF nArgs=2
+ LDMIA sp, {r1,r2}
+ ENDIF
+ IF nArgs=3
+ LDMIA sp, {r1,r2,r3}
+ ENDIF
+
+ ;// print the values
+ MRS r4, cpsr ;// preserve flags
+ BL printf
+ MSR cpsr_f, r4 ;// restore flags
+ B %FT01
+00 ;// string to print
+ DCB "$format", 0
+ ALIGN
+01 ;// Finished
+ ADD sp, sp, #16
+ ;// Restore registers
+ LDMFD sp!, {r0-r12,lr}
+
+ ENDIF ;// DEBUG_ON
+ MEND
+
+
+ ;// Stall Simulation Macro
+ ;// Inserts a given number of NOPs for the currently
+ ;// defined platform
+ MACRO
+ M_STALL $plat1stall, $plat2stall, $plat3stall, $plat4stall, $plat5stall, $plat6stall
+ IF DEBUG_STALLS_ON
+ _M_STALL_SUB $plat1stall
+ _M_STALL_SUB $plat2stall
+ _M_STALL_SUB $plat3stall
+ _M_STALL_SUB $plat4stall
+ _M_STALL_SUB $plat5stall
+ _M_STALL_SUB $plat6stall
+ ENDIF
+ MEND
+
+ MACRO
+ _M_STALL_SUB $platstall
+ IF "$platstall"!=""
+ LCLA _pllen
+ LCLS _pl
+ LCLL _pllog
+_pllen SETA :LEN:"$platstall"
+_pl SETS "$platstall":LEFT:(_pllen - 2)
+ IF :DEF:$_pl
+ IF $_pl
+ LCLS _st
+ LCLA _stnum
+_st SETS "$platstall":RIGHT:1
+_stnum SETA $_st
+ WHILE _stnum>0
+ MOV sp, sp
+_stnum SETA _stnum - 1
+ WEND
+ ENDIF
+ ENDIF
+ ENDIF
+ MEND
+
+
+
+;//==========================================================================
+;// Endian Invarience Macros
+;//
+;// The idea behind these macros is that if an array is
+;// loaded as words then the SMUL00 macro will multiply
+;// array elements 0 regardless of the endianess of the
+;// system. For little endian SMUL00=SMULBB, for big
+;// endian SMUL00=SMULTT and similarly for other packed operations.
+;//
+;//==========================================================================
+
+ MACRO
+ LIBI4 $comli, $combi, $a, $b, $c, $d, $cc
+ IF {ENDIAN}="big"
+ $combi.$cc $a, $b, $c, $d
+ ELSE
+ $comli.$cc $a, $b, $c, $d
+ ENDIF
+ MEND
+
+ MACRO
+ LIBI3 $comli, $combi, $a, $b, $c, $cc
+ IF {ENDIAN}="big"
+ $combi.$cc $a, $b, $c
+ ELSE
+ $comli.$cc $a, $b, $c
+ ENDIF
+ MEND
+
+ ;// SMLAxy macros
+
+ MACRO
+ SMLA00 $a, $b, $c, $d, $cc
+ LIBI4 SMLABB, SMLATT, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLA01 $a, $b, $c, $d, $cc
+ LIBI4 SMLABT, SMLATB, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLA0B $a, $b, $c, $d, $cc
+ LIBI4 SMLABB, SMLATB, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLA0T $a, $b, $c, $d, $cc
+ LIBI4 SMLABT, SMLATT, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLA10 $a, $b, $c, $d, $cc
+ LIBI4 SMLATB, SMLABT, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLA11 $a, $b, $c, $d, $cc
+ LIBI4 SMLATT, SMLABB, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLA1B $a, $b, $c, $d, $cc
+ LIBI4 SMLATB, SMLABB, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLA1T $a, $b, $c, $d, $cc
+ LIBI4 SMLATT, SMLABT, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLAB0 $a, $b, $c, $d, $cc
+ LIBI4 SMLABB, SMLABT, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLAB1 $a, $b, $c, $d, $cc
+ LIBI4 SMLABT, SMLABB, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLAT0 $a, $b, $c, $d, $cc
+ LIBI4 SMLATB, SMLATT, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLAT1 $a, $b, $c, $d, $cc
+ LIBI4 SMLATT, SMLATB, $a, $b, $c, $d, $cc
+ MEND
+
+ ;// SMULxy macros
+
+ MACRO
+ SMUL00 $a, $b, $c, $cc
+ LIBI3 SMULBB, SMULTT, $a, $b, $c, $cc
+ MEND
+
+ MACRO
+ SMUL01 $a, $b, $c, $cc
+ LIBI3 SMULBT, SMULTB, $a, $b, $c, $cc
+ MEND
+
+ MACRO
+ SMUL0B $a, $b, $c, $cc
+ LIBI3 SMULBB, SMULTB, $a, $b, $c, $cc
+ MEND
+
+ MACRO
+ SMUL0T $a, $b, $c, $cc
+ LIBI3 SMULBT, SMULTT, $a, $b, $c, $cc
+ MEND
+
+ MACRO
+ SMUL10 $a, $b, $c, $cc
+ LIBI3 SMULTB, SMULBT, $a, $b, $c, $cc
+ MEND
+
+ MACRO
+ SMUL11 $a, $b, $c, $cc
+ LIBI3 SMULTT, SMULBB, $a, $b, $c, $cc
+ MEND
+
+ MACRO
+ SMUL1B $a, $b, $c, $cc
+ LIBI3 SMULTB, SMULBB, $a, $b, $c, $cc
+ MEND
+
+ MACRO
+ SMUL1T $a, $b, $c, $cc
+ LIBI3 SMULTT, SMULBT, $a, $b, $c, $cc
+ MEND
+
+ MACRO
+ SMULB0 $a, $b, $c, $cc
+ LIBI3 SMULBB, SMULBT, $a, $b, $c, $cc
+ MEND
+
+ MACRO
+ SMULB1 $a, $b, $c, $cc
+ LIBI3 SMULBT, SMULBB, $a, $b, $c, $cc
+ MEND
+
+ MACRO
+ SMULT0 $a, $b, $c, $cc
+ LIBI3 SMULTB, SMULTT, $a, $b, $c, $cc
+ MEND
+
+ MACRO
+ SMULT1 $a, $b, $c, $cc
+ LIBI3 SMULTT, SMULTB, $a, $b, $c, $cc
+ MEND
+
+ ;// SMLAWx, SMULWx macros
+
+ MACRO
+ SMLAW0 $a, $b, $c, $d, $cc
+ LIBI4 SMLAWB, SMLAWT, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLAW1 $a, $b, $c, $d, $cc
+ LIBI4 SMLAWT, SMLAWB, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMULW0 $a, $b, $c, $cc
+ LIBI3 SMULWB, SMULWT, $a, $b, $c, $cc
+ MEND
+
+ MACRO
+ SMULW1 $a, $b, $c, $cc
+ LIBI3 SMULWT, SMULWB, $a, $b, $c, $cc
+ MEND
+
+ ;// SMLALxy macros
+
+
+ MACRO
+ SMLAL00 $a, $b, $c, $d, $cc
+ LIBI4 SMLALBB, SMLALTT, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLAL01 $a, $b, $c, $d, $cc
+ LIBI4 SMLALBT, SMLALTB, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLAL0B $a, $b, $c, $d, $cc
+ LIBI4 SMLALBB, SMLALTB, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLAL0T $a, $b, $c, $d, $cc
+ LIBI4 SMLALBT, SMLALTT, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLAL10 $a, $b, $c, $d, $cc
+ LIBI4 SMLALTB, SMLALBT, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLAL11 $a, $b, $c, $d, $cc
+ LIBI4 SMLALTT, SMLALBB, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLAL1B $a, $b, $c, $d, $cc
+ LIBI4 SMLALTB, SMLALBB, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLAL1T $a, $b, $c, $d, $cc
+ LIBI4 SMLALTT, SMLALBT, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLALB0 $a, $b, $c, $d, $cc
+ LIBI4 SMLALBB, SMLALBT, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLALB1 $a, $b, $c, $d, $cc
+ LIBI4 SMLALBT, SMLALBB, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLALT0 $a, $b, $c, $d, $cc
+ LIBI4 SMLALTB, SMLALTT, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLALT1 $a, $b, $c, $d, $cc
+ LIBI4 SMLALTT, SMLALTB, $a, $b, $c, $d, $cc
+ MEND
+
+ ENDIF ;// ARMCOMM_S_H
+
+ END
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armOMX.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armOMX.h
new file mode 100644
index 0000000..f629f72
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armOMX.h
@@ -0,0 +1,274 @@
+/*
+ *
+ * File Name: armOMX_ReleaseVersion.h
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * This file allows a version of the OMX DL libraries to be built where some or
+ * all of the function names can be given a user specified suffix.
+ *
+ * You might want to use it where:
+ *
+ * - you want to rename a function "out of the way" so that you could replace
+ * a function with a different version (the original version would still be
+ * in the library just with a different name - so you could debug the new
+ * version by comparing it to the output of the old)
+ *
+ * - you want to rename all the functions to versions with a suffix so that
+ * you can include two versions of the library and choose between functions
+ * at runtime.
+ *
+ * e.g. omxIPBM_Copy_U8_C1R could be renamed omxIPBM_Copy_U8_C1R_CortexA8
+ *
+ */
+
+
+#ifndef _armOMX_H_
+#define _armOMX_H_
+
+
+/* We need to define these two macros in order to expand and concatenate the names */
+#define OMXCAT2BAR(A, B) omx ## A ## B
+#define OMXCATBAR(A, B) OMXCAT2BAR(A, B)
+
+/* Define the suffix to add to all functions - the default is no suffix */
+#define BARE_SUFFIX
+
+
+
+/* Define what happens to the bare suffix-less functions, down to the sub-domain accuracy */
+#define OMXACAAC_SUFFIX BARE_SUFFIX
+#define OMXACMP3_SUFFIX BARE_SUFFIX
+#define OMXICJP_SUFFIX BARE_SUFFIX
+#define OMXIPBM_SUFFIX BARE_SUFFIX
+#define OMXIPCS_SUFFIX BARE_SUFFIX
+#define OMXIPPP_SUFFIX BARE_SUFFIX
+#define OMXSP_SUFFIX BARE_SUFFIX
+#define OMXVCCOMM_SUFFIX BARE_SUFFIX
+#define OMXVCM4P10_SUFFIX BARE_SUFFIX
+#define OMXVCM4P2_SUFFIX BARE_SUFFIX
+
+
+
+
+/* Define what the each bare, un-suffixed OpenMAX API function names is to be renamed */
+#define omxACAAC_DecodeChanPairElt OMXCATBAR(ACAAC_DecodeChanPairElt, OMXACAAC_SUFFIX)
+#define omxACAAC_DecodeDatStrElt OMXCATBAR(ACAAC_DecodeDatStrElt, OMXACAAC_SUFFIX)
+#define omxACAAC_DecodeFillElt OMXCATBAR(ACAAC_DecodeFillElt, OMXACAAC_SUFFIX)
+#define omxACAAC_DecodeIsStereo_S32 OMXCATBAR(ACAAC_DecodeIsStereo_S32, OMXACAAC_SUFFIX)
+#define omxACAAC_DecodeMsPNS_S32_I OMXCATBAR(ACAAC_DecodeMsPNS_S32_I, OMXACAAC_SUFFIX)
+#define omxACAAC_DecodeMsStereo_S32_I OMXCATBAR(ACAAC_DecodeMsStereo_S32_I, OMXACAAC_SUFFIX)
+#define omxACAAC_DecodePrgCfgElt OMXCATBAR(ACAAC_DecodePrgCfgElt, OMXACAAC_SUFFIX)
+#define omxACAAC_DecodeTNS_S32_I OMXCATBAR(ACAAC_DecodeTNS_S32_I, OMXACAAC_SUFFIX)
+#define omxACAAC_DeinterleaveSpectrum_S32 OMXCATBAR(ACAAC_DeinterleaveSpectrum_S32, OMXACAAC_SUFFIX)
+#define omxACAAC_EncodeTNS_S32_I OMXCATBAR(ACAAC_EncodeTNS_S32_I, OMXACAAC_SUFFIX)
+#define omxACAAC_LongTermPredict_S32 OMXCATBAR(ACAAC_LongTermPredict_S32, OMXACAAC_SUFFIX)
+#define omxACAAC_LongTermReconstruct_S32_I OMXCATBAR(ACAAC_LongTermReconstruct_S32_I, OMXACAAC_SUFFIX)
+#define omxACAAC_MDCTFwd_S32 OMXCATBAR(ACAAC_MDCTFwd_S32, OMXACAAC_SUFFIX)
+#define omxACAAC_MDCTInv_S32_S16 OMXCATBAR(ACAAC_MDCTInv_S32_S16, OMXACAAC_SUFFIX)
+#define omxACAAC_NoiselessDecode OMXCATBAR(ACAAC_NoiselessDecode, OMXACAAC_SUFFIX)
+#define omxACAAC_QuantInv_S32_I OMXCATBAR(ACAAC_QuantInv_S32_I, OMXACAAC_SUFFIX)
+#define omxACAAC_UnpackADIFHeader OMXCATBAR(ACAAC_UnpackADIFHeader, OMXACAAC_SUFFIX)
+#define omxACAAC_UnpackADTSFrameHeader OMXCATBAR(ACAAC_UnpackADTSFrameHeader, OMXACAAC_SUFFIX)
+
+
+#define omxACMP3_HuffmanDecode_S32 OMXCATBAR(ACMP3_HuffmanDecode_S32, OMXACMP3_SUFFIX)
+#define omxACMP3_HuffmanDecodeSfb_S32 OMXCATBAR(ACMP3_HuffmanDecodeSfb_S32, OMXACMP3_SUFFIX)
+#define omxACMP3_HuffmanDecodeSfbMbp_S32 OMXCATBAR(ACMP3_HuffmanDecodeSfbMbp_S32, OMXACMP3_SUFFIX)
+#define omxACMP3_MDCTInv_S32 OMXCATBAR(ACMP3_MDCTInv_S32, OMXACMP3_SUFFIX)
+#define omxACMP3_ReQuantize_S32_I OMXCATBAR(ACMP3_ReQuantize_S32_I, OMXACMP3_SUFFIX)
+#define omxACMP3_ReQuantizeSfb_S32_I OMXCATBAR(ACMP3_ReQuantizeSfb_S32_I, OMXACMP3_SUFFIX)
+#define omxACMP3_SynthPQMF_S32_S16 OMXCATBAR(ACMP3_SynthPQMF_S32_S16, OMXACMP3_SUFFIX)
+#define omxACMP3_UnpackFrameHeader OMXCATBAR(ACMP3_UnpackFrameHeader, OMXACMP3_SUFFIX)
+#define omxACMP3_UnpackScaleFactors_S8 OMXCATBAR(ACMP3_UnpackScaleFactors_S8, OMXACMP3_SUFFIX)
+#define omxACMP3_UnpackSideInfo OMXCATBAR(ACMP3_UnpackSideInfo, OMXACMP3_SUFFIX)
+
+#define omxICJP_CopyExpand_U8_C3 OMXCATBAR(ICJP_CopyExpand_U8_C3, OMXICJP_SUFFIX)
+#define omxICJP_DCTFwd_S16 OMXCATBAR(ICJP_DCTFwd_S16, OMXICJP_SUFFIX)
+#define omxICJP_DCTFwd_S16_I OMXCATBAR(ICJP_DCTFwd_S16_I, OMXICJP_SUFFIX)
+#define omxICJP_DCTInv_S16 OMXCATBAR(ICJP_DCTInv_S16, OMXICJP_SUFFIX)
+#define omxICJP_DCTInv_S16_I OMXCATBAR(ICJP_DCTInv_S16_I, OMXICJP_SUFFIX)
+#define omxICJP_DCTQuantFwd_Multiple_S16 OMXCATBAR(ICJP_DCTQuantFwd_Multiple_S16, OMXICJP_SUFFIX)
+#define omxICJP_DCTQuantFwd_S16 OMXCATBAR(ICJP_DCTQuantFwd_S16, OMXICJP_SUFFIX)
+#define omxICJP_DCTQuantFwd_S16_I OMXCATBAR(ICJP_DCTQuantFwd_S16_I, OMXICJP_SUFFIX)
+#define omxICJP_DCTQuantFwdTableInit OMXCATBAR(ICJP_DCTQuantFwdTableInit, OMXICJP_SUFFIX)
+#define omxICJP_DCTQuantInv_Multiple_S16 OMXCATBAR(ICJP_DCTQuantInv_Multiple_S16, OMXICJP_SUFFIX)
+#define omxICJP_DCTQuantInv_S16 OMXCATBAR(ICJP_DCTQuantInv_S16, OMXICJP_SUFFIX)
+#define omxICJP_DCTQuantInv_S16_I OMXCATBAR(ICJP_DCTQuantInv_S16_I, OMXICJP_SUFFIX)
+#define omxICJP_DCTQuantInvTableInit OMXCATBAR(ICJP_DCTQuantInvTableInit, OMXICJP_SUFFIX)
+#define omxICJP_DecodeHuffman8x8_Direct_S16_C1 OMXCATBAR(ICJP_DecodeHuffman8x8_Direct_S16_C1, OMXICJP_SUFFIX)
+#define omxICJP_DecodeHuffmanSpecGetBufSize_U8 OMXCATBAR(ICJP_DecodeHuffmanSpecGetBufSize_U8, OMXICJP_SUFFIX)
+#define omxICJP_DecodeHuffmanSpecInit_U8 OMXCATBAR(ICJP_DecodeHuffmanSpecInit_U8, OMXICJP_SUFFIX)
+#define omxICJP_EncodeHuffman8x8_Direct_S16_U1_C1 OMXCATBAR(ICJP_EncodeHuffman8x8_Direct_S16_U1_C1, OMXICJP_SUFFIX)
+#define omxICJP_EncodeHuffmanSpecGetBufSize_U8 OMXCATBAR(ICJP_EncodeHuffmanSpecGetBufSize_U8, OMXICJP_SUFFIX)
+#define omxICJP_EncodeHuffmanSpecInit_U8 OMXCATBAR(ICJP_EncodeHuffmanSpecInit_U8, OMXICJP_SUFFIX)
+
+#define omxIPBM_AddC_U8_C1R_Sfs OMXCATBAR(IPBM_AddC_U8_C1R_Sfs, OMXIPBM_SUFFIX)
+#define omxIPBM_Copy_U8_C1R OMXCATBAR(IPBM_Copy_U8_C1R, OMXIPBM_SUFFIX)
+#define omxIPBM_Copy_U8_C3R OMXCATBAR(IPBM_Copy_U8_C3R, OMXIPBM_SUFFIX)
+#define omxIPBM_Mirror_U8_C1R OMXCATBAR(IPBM_Mirror_U8_C1R, OMXIPBM_SUFFIX)
+#define omxIPBM_MulC_U8_C1R_Sfs OMXCATBAR(IPBM_MulC_U8_C1R_Sfs, OMXIPBM_SUFFIX)
+
+#define omxIPCS_ColorTwistQ14_U8_C3R OMXCATBAR(IPCS_ColorTwistQ14_U8_C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_BGR565ToYCbCr420LS_MCU_U16_S16_C3P3R OMXCATBAR(IPCS_BGR565ToYCbCr420LS_MCU_U16_S16_C3P3R, OMXIPCS_SUFFIX)
+#define omxIPCS_BGR565ToYCbCr422LS_MCU_U16_S16_C3P3R OMXCATBAR(IPCS_BGR565ToYCbCr422LS_MCU_U16_S16_C3P3R, OMXIPCS_SUFFIX)
+#define omxIPCS_BGR565ToYCbCr444LS_MCU_U16_S16_C3P3R OMXCATBAR(IPCS_BGR565ToYCbCr444LS_MCU_U16_S16_C3P3R, OMXIPCS_SUFFIX)
+#define omxIPCS_BGR888ToYCbCr420LS_MCU_U8_S16_C3P3R OMXCATBAR(IPCS_BGR888ToYCbCr420LS_MCU_U8_S16_C3P3R, OMXIPCS_SUFFIX)
+#define omxIPCS_BGR888ToYCbCr422LS_MCU_U8_S16_C3P3R OMXCATBAR(IPCS_BGR888ToYCbCr422LS_MCU_U8_S16_C3P3R, OMXIPCS_SUFFIX)
+#define omxIPCS_BGR888ToYCbCr444LS_MCU_U8_S16_C3P3R OMXCATBAR(IPCS_BGR888ToYCbCr444LS_MCU_U8_S16_C3P3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr420RszCscRotBGR_U8_P3C3R OMXCATBAR(IPCS_YCbCr420RszCscRotBGR_U8_P3C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr420RszRot_U8_P3R OMXCATBAR(IPCS_YCbCr420RszRot_U8_P3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr420ToBGR565_U8_U16_P3C3R OMXCATBAR(IPCS_YCbCr420ToBGR565_U8_U16_P3C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr420ToBGR565LS_MCU_S16_U16_P3C3R OMXCATBAR(IPCS_YCbCr420ToBGR565LS_MCU_S16_U16_P3C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr420ToBGR888LS_MCU_S16_U8_P3C3R OMXCATBAR(IPCS_YCbCr420ToBGR888LS_MCU_S16_U8_P3C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr422RszCscRotBGR_U8_P3C3R OMXCATBAR(IPCS_YCbCr422RszCscRotBGR_U8_P3C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_CbYCrY422RszCscRotBGR_U8_U16_C2R OMXCATBAR(IPCS_CbYCrY422RszCscRotBGR_U8_U16_C2R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr422RszRot_U8_P3R OMXCATBAR(IPCS_YCbCr422RszRot_U8_P3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbYCr422ToBGR565_U8_U16_C2C3R OMXCATBAR(IPCS_YCbYCr422ToBGR565_U8_U16_C2C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr422ToBGR565LS_MCU_S16_U16_P3C3R OMXCATBAR(IPCS_YCbCr422ToBGR565LS_MCU_S16_U16_P3C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbYCr422ToBGR888_U8_C2C3R OMXCATBAR(IPCS_YCbYCr422ToBGR888_U8_C2C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr422ToBGR888LS_MCU_S16_U8_P3C3R OMXCATBAR(IPCS_YCbCr422ToBGR888LS_MCU_S16_U8_P3C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr422ToBGR888LS_MCU_S16_U8_P3C3R OMXCATBAR(IPCS_YCbCr422ToBGR888LS_MCU_S16_U8_P3C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_CbYCrY422ToYCbCr420Rotate_U8_C2P3R OMXCATBAR(IPCS_CbYCrY422ToYCbCr420Rotate_U8_C2P3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr422ToYCbCr420Rotate_U8_P3R OMXCATBAR(IPCS_YCbCr422ToYCbCr420Rotate_U8_P3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr444ToBGR565_U8_U16_C3R OMXCATBAR(IPCS_YCbCr444ToBGR565_U8_U16_C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr444ToBGR565_U8_U16_P3C3R OMXCATBAR(IPCS_YCbCr444ToBGR565_U8_U16_P3C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr444ToBGR565LS_MCU_S16_U16_P3C3R OMXCATBAR(IPCS_YCbCr444ToBGR565LS_MCU_S16_U16_P3C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr444ToBGR888_U8_C3R OMXCATBAR(IPCS_YCbCr444ToBGR888_U8_C3R, OMXIPCS_SUFFIX)
+
+#define omxIPPP_Deblock_HorEdge_U8_I OMXCATBAR(IPPP_Deblock_HorEdge_U8_I, OMXIPPP_SUFFIX)
+#define omxIPPP_Deblock_VerEdge_U8_I OMXCATBAR(IPPP_Deblock_VerEdge_U8_I, OMXIPPP_SUFFIX)
+#define omxIPPP_FilterFIR_U8_C1R OMXCATBAR(IPPP_FilterFIR_U8_C1R, OMXIPPP_SUFFIX)
+#define omxIPPP_FilterMedian_U8_C1R OMXCATBAR(IPPP_FilterMedian_U8_C1R, OMXIPPP_SUFFIX)
+#define omxIPPP_GetCentralMoment_S64 OMXCATBAR(IPPP_GetCentralMoment_S64, OMXIPPP_SUFFIX)
+#define omxIPPP_GetSpatialMoment_S64 OMXCATBAR(IPPP_GetSpatialMoment_S64, OMXIPPP_SUFFIX)
+#define omxIPPP_MomentGetStateSize OMXCATBAR(IPPP_MomentGetStateSize, OMXIPPP_SUFFIX)
+#define omxIPPP_MomentInit OMXCATBAR(IPPP_MomentInit, OMXIPPP_SUFFIX)
+#define omxIPPP_Moments_U8_C1R OMXCATBAR(IPPP_Moments_U8_C1R, OMXIPPP_SUFFIX)
+#define omxIPPP_Moments_U8_C3R OMXCATBAR(IPPP_Moments_U8_C3R, OMXIPPP_SUFFIX)
+
+#define omxSP_BlockExp_S16 OMXCATBAR(SP_BlockExp_S16, OMXSP_SUFFIX)
+#define omxSP_BlockExp_S32 OMXCATBAR(SP_BlockExp_S32, OMXSP_SUFFIX)
+#define omxSP_Copy_S16 OMXCATBAR(SP_Copy_S16, OMXSP_SUFFIX)
+#define omxSP_DotProd_S16 OMXCATBAR(SP_DotProd_S16, OMXSP_SUFFIX)
+#define omxSP_DotProd_S16_Sfs OMXCATBAR(SP_DotProd_S16_Sfs, OMXSP_SUFFIX)
+#define omxSP_FFTFwd_CToC_SC16_Sfs OMXCATBAR(SP_FFTFwd_CToC_SC16_Sfs, OMXSP_SUFFIX)
+#define omxSP_FFTFwd_CToC_SC32_Sfs OMXCATBAR(SP_FFTFwd_CToC_SC32_Sfs, OMXSP_SUFFIX)
+#define omxSP_FFTFwd_RToCCS_S16S32_Sfs OMXCATBAR(SP_FFTFwd_RToCCS_S16S32_Sfs, OMXSP_SUFFIX)
+#define omxSP_FFTFwd_RToCCS_S32_Sfs OMXCATBAR(SP_FFTFwd_RToCCS_S32_Sfs, OMXSP_SUFFIX)
+#define omxSP_FFTGetBufSize_C_SC16 OMXCATBAR(SP_FFTGetBufSize_C_SC16, OMXSP_SUFFIX)
+#define omxSP_FFTGetBufSize_C_SC32 OMXCATBAR(SP_FFTGetBufSize_C_SC32, OMXSP_SUFFIX)
+#define omxSP_FFTGetBufSize_R_S16S32 OMXCATBAR(SP_FFTGetBufSize_R_S16S32, OMXSP_SUFFIX)
+#define omxSP_FFTGetBufSize_R_S32 OMXCATBAR(SP_FFTGetBufSize_R_S32, OMXSP_SUFFIX)
+#define omxSP_FFTInit_C_SC16 OMXCATBAR(SP_FFTInit_C_SC16, OMXSP_SUFFIX)
+#define omxSP_FFTInit_C_SC32 OMXCATBAR(SP_FFTInit_C_SC32, OMXSP_SUFFIX)
+#define omxSP_FFTInit_R_S16S32 OMXCATBAR(SP_FFTInit_R_S16S32, OMXSP_SUFFIX)
+#define omxSP_FFTInit_R_S32 OMXCATBAR(SP_FFTInit_R_S32, OMXSP_SUFFIX)
+#define omxSP_FFTInv_CCSToR_S32_Sfs OMXCATBAR(SP_FFTInv_CCSToR_S32_Sfs, OMXSP_SUFFIX)
+#define omxSP_FFTInv_CCSToR_S32S16_Sfs OMXCATBAR(SP_FFTInv_CCSToR_S32S16_Sfs, OMXSP_SUFFIX)
+#define omxSP_FFTInv_CToC_SC16_Sfs OMXCATBAR(SP_FFTInv_CToC_SC16_Sfs, OMXSP_SUFFIX)
+#define omxSP_FFTInv_CToC_SC32_Sfs OMXCATBAR(SP_FFTInv_CToC_SC32_Sfs, OMXSP_SUFFIX)
+#define omxSP_FilterMedian_S32 OMXCATBAR(SP_FilterMedian_S32, OMXSP_SUFFIX)
+#define omxSP_FilterMedian_S32_I OMXCATBAR(SP_FilterMedian_S32_I, OMXSP_SUFFIX)
+#define omxSP_FIR_Direct_S16 OMXCATBAR(SP_FIR_Direct_S16, OMXSP_SUFFIX)
+#define omxSP_FIR_Direct_S16_I OMXCATBAR(SP_FIR_Direct_S16_I, OMXSP_SUFFIX)
+#define omxSP_FIR_Direct_S16_ISfs OMXCATBAR(SP_FIR_Direct_S16_ISfs, OMXSP_SUFFIX)
+#define omxSP_FIR_Direct_S16_Sfs OMXCATBAR(SP_FIR_Direct_S16_Sfs, OMXSP_SUFFIX)
+#define omxSP_FIROne_Direct_S16 OMXCATBAR(SP_FIROne_Direct_S16, OMXSP_SUFFIX)
+#define omxSP_FIROne_Direct_S16_I OMXCATBAR(SP_FIROne_Direct_S16_I, OMXSP_SUFFIX)
+#define omxSP_FIROne_Direct_S16_ISfs OMXCATBAR(SP_FIROne_Direct_S16_ISfs, OMXSP_SUFFIX)
+#define omxSP_FIROne_Direct_S16_Sfs OMXCATBAR(SP_FIROne_Direct_S16_Sfs, OMXSP_SUFFIX)
+#define omxSP_IIR_BiQuadDirect_S16 OMXCATBAR(SP_IIR_BiQuadDirect_S16, OMXSP_SUFFIX)
+#define omxSP_IIR_BiQuadDirect_S16_I OMXCATBAR(SP_IIR_BiQuadDirect_S16_I, OMXSP_SUFFIX)
+#define omxSP_IIR_Direct_S16 OMXCATBAR(SP_IIR_Direct_S16, OMXSP_SUFFIX)
+#define omxSP_IIR_Direct_S16_I OMXCATBAR(SP_IIR_Direct_S16_I, OMXSP_SUFFIX)
+#define omxSP_IIROne_BiQuadDirect_S16 OMXCATBAR(SP_IIROne_BiQuadDirect_S16, OMXSP_SUFFIX)
+#define omxSP_IIROne_BiQuadDirect_S16_I OMXCATBAR(SP_IIROne_BiQuadDirect_S16_I, OMXSP_SUFFIX)
+#define omxSP_IIROne_Direct_S16 OMXCATBAR(SP_IIROne_Direct_S16, OMXSP_SUFFIX)
+#define omxSP_IIROne_Direct_S16_I OMXCATBAR(SP_IIROne_Direct_S16_I, OMXSP_SUFFIX)
+
+#define omxVCCOMM_Average_16x OMXCATBAR(VCCOMM_Average_16x, OMXVCCOMM_SUFFIX)
+#define omxVCCOMM_Average_8x OMXCATBAR(VCCOMM_Average_8x, OMXVCCOMM_SUFFIX)
+#define omxVCCOMM_ComputeTextureErrorBlock OMXCATBAR(VCCOMM_ComputeTextureErrorBlock, OMXVCCOMM_SUFFIX)
+#define omxVCCOMM_ComputeTextureErrorBlock_SAD OMXCATBAR(VCCOMM_ComputeTextureErrorBlock_SAD, OMXVCCOMM_SUFFIX)
+#define omxVCCOMM_Copy16x16 OMXCATBAR(VCCOMM_Copy16x16, OMXVCCOMM_SUFFIX)
+#define omxVCCOMM_Copy8x8 OMXCATBAR(VCCOMM_Copy8x8, OMXVCCOMM_SUFFIX)
+#define omxVCCOMM_ExpandFrame_I OMXCATBAR(VCCOMM_ExpandFrame_I, OMXVCCOMM_SUFFIX)
+#define omxVCCOMM_LimitMVToRect OMXCATBAR(VCCOMM_LimitMVToRect, OMXVCCOMM_SUFFIX)
+#define omxVCCOMM_SAD_16x OMXCATBAR(VCCOMM_SAD_16x, OMXVCCOMM_SUFFIX)
+#define omxVCCOMM_SAD_8x OMXCATBAR(VCCOMM_SAD_8x, OMXVCCOMM_SUFFIX)
+
+#define omxVCM4P10_Average_4x OMXCATBAR(VCM4P10_Average_4x, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_BlockMatch_Half OMXCATBAR(VCM4P10_BlockMatch_Half, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_BlockMatch_Integer OMXCATBAR(VCM4P10_BlockMatch_Integer, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_BlockMatch_Quarter OMXCATBAR(VCM4P10_BlockMatch_Quarter, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_DeblockChroma_I OMXCATBAR(VCM4P10_DeblockChroma_I, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_DeblockLuma_I OMXCATBAR(VCM4P10_DeblockLuma_I, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC OMXCATBAR(VCM4P10_DecodeChromaDcCoeffsToPairCAVLC, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_DecodeCoeffsToPairCAVLC OMXCATBAR(VCM4P10_DecodeCoeffsToPairCAVLC, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_DequantTransformResidualFromPairAndAdd OMXCATBAR(VCM4P10_DequantTransformResidualFromPairAndAdd, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_FilterDeblockingChroma_HorEdge_I OMXCATBAR(VCM4P10_FilterDeblockingChroma_HorEdge_I, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_FilterDeblockingChroma_VerEdge_I OMXCATBAR(VCM4P10_FilterDeblockingChroma_VerEdge_I, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_FilterDeblockingLuma_HorEdge_I OMXCATBAR(VCM4P10_FilterDeblockingLuma_HorEdge_I, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_FilterDeblockingLuma_VerEdge_I OMXCATBAR(VCM4P10_FilterDeblockingLuma_VerEdge_I, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_GetVLCInfo OMXCATBAR(VCM4P10_GetVLCInfo, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_InterpolateChroma OMXCATBAR(VCM4P10_InterpolateChroma, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_InterpolateHalfHor_Luma OMXCATBAR(VCM4P10_InterpolateHalfHor_Luma, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_InterpolateHalfVer_Luma OMXCATBAR(VCM4P10_InterpolateHalfVer_Luma, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_InterpolateLuma OMXCATBAR(VCM4P10_InterpolateLuma, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_InvTransformDequant_ChromaDC OMXCATBAR(VCM4P10_InvTransformDequant_ChromaDC, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_InvTransformDequant_LumaDC OMXCATBAR(VCM4P10_InvTransformDequant_LumaDC, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_InvTransformResidualAndAdd OMXCATBAR(VCM4P10_InvTransformResidualAndAdd, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_MEGetBufSize OMXCATBAR(VCM4P10_MEGetBufSize, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_MEInit OMXCATBAR(VCM4P10_MEInit, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_MotionEstimationMB OMXCATBAR(VCM4P10_MotionEstimationMB, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_PredictIntra_16x16 OMXCATBAR(VCM4P10_PredictIntra_16x16, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_PredictIntra_4x4 OMXCATBAR(VCM4P10_PredictIntra_4x4, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_PredictIntraChroma_8x8 OMXCATBAR(VCM4P10_PredictIntraChroma_8x8, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_SAD_4x OMXCATBAR(VCM4P10_SAD_4x, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_SADQuar_16x OMXCATBAR(VCM4P10_SADQuar_16x, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_SADQuar_4x OMXCATBAR(VCM4P10_SADQuar_4x, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_SADQuar_8x OMXCATBAR(VCM4P10_SADQuar_8x, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_SATD_4x4 OMXCATBAR(VCM4P10_SATD_4x4, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_SubAndTransformQDQResidual OMXCATBAR(VCM4P10_SubAndTransformQDQResidual, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_TransformDequantChromaDCFromPair OMXCATBAR(VCM4P10_TransformDequantChromaDCFromPair, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_TransformDequantLumaDCFromPair OMXCATBAR(VCM4P10_TransformDequantLumaDCFromPair, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_TransformQuant_ChromaDC OMXCATBAR(VCM4P10_TransformQuant_ChromaDC, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_TransformQuant_LumaDC OMXCATBAR(VCM4P10_TransformQuant_LumaDC, OMXVCM4P10_SUFFIX)
+
+#define omxVCM4P2_BlockMatch_Half_16x16 OMXCATBAR(VCM4P2_BlockMatch_Half_16x16, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_BlockMatch_Half_8x8 OMXCATBAR(VCM4P2_BlockMatch_Half_8x8, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_BlockMatch_Integer_16x16 OMXCATBAR(VCM4P2_BlockMatch_Integer_16x16, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_BlockMatch_Integer_8x8 OMXCATBAR(VCM4P2_BlockMatch_Integer_8x8, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_DCT8x8blk OMXCATBAR(VCM4P2_DCT8x8blk, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_DecodeBlockCoef_Inter OMXCATBAR(VCM4P2_DecodeBlockCoef_Inter, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_DecodeBlockCoef_Intra OMXCATBAR(VCM4P2_DecodeBlockCoef_Intra, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_DecodePadMV_PVOP OMXCATBAR(VCM4P2_DecodePadMV_PVOP, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_DecodeVLCZigzag_Inter OMXCATBAR(VCM4P2_DecodeVLCZigzag_Inter, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_DecodeVLCZigzag_IntraACVLC OMXCATBAR(VCM4P2_DecodeVLCZigzag_IntraACVLC, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_DecodeVLCZigzag_IntraDCVLC OMXCATBAR(VCM4P2_DecodeVLCZigzag_IntraDCVLC, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_EncodeMV OMXCATBAR(VCM4P2_EncodeMV, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_EncodeVLCZigzag_Inter OMXCATBAR(VCM4P2_EncodeVLCZigzag_Inter, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_EncodeVLCZigzag_IntraACVLC OMXCATBAR(VCM4P2_EncodeVLCZigzag_IntraACVLC, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_EncodeVLCZigzag_IntraDCVLC OMXCATBAR(VCM4P2_EncodeVLCZigzag_IntraDCVLC, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_FindMVpred OMXCATBAR(VCM4P2_FindMVpred, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_IDCT8x8blk OMXCATBAR(VCM4P2_IDCT8x8blk, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_MCReconBlock OMXCATBAR(VCM4P2_MCReconBlock, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_MEGetBufSize OMXCATBAR(VCM4P2_MEGetBufSize, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_MEInit OMXCATBAR(VCM4P2_MEInit, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_MotionEstimationMB OMXCATBAR(VCM4P2_MotionEstimationMB, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_PredictReconCoefIntra OMXCATBAR(VCM4P2_PredictReconCoefIntra, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_QuantInter_I OMXCATBAR(VCM4P2_QuantInter_I, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_QuantIntra_I OMXCATBAR(VCM4P2_QuantIntra_I, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_QuantInvInter_I OMXCATBAR(VCM4P2_QuantInvInter_I, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_QuantInvIntra_I OMXCATBAR(VCM4P2_QuantInvIntra_I, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_TransRecBlockCoef_inter OMXCATBAR(VCM4P2_TransRecBlockCoef_inter, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_TransRecBlockCoef_intra OMXCATBAR(VCM4P2_TransRecBlockCoef_intra, OMXVCM4P2_SUFFIX)
+
+
+#endif /* _armOMX_h_ */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/omxtypes.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/omxtypes.h
new file mode 100644
index 0000000..8b295a6
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/omxtypes.h
@@ -0,0 +1,252 @@
+/**
+ * File: omxtypes.h
+ * Brief: Defines basic Data types used in OpenMAX v1.0.2 header files.
+ *
+ * Copyright © 2005-2008 The Khronos Group Inc. All Rights Reserved.
+ *
+ * These materials are protected by copyright laws and contain material
+ * proprietary to the Khronos Group, Inc. You may use these materials
+ * for implementing Khronos specifications, without altering or removing
+ * any trademark, copyright or other notice from the specification.
+ *
+ * Khronos Group makes no, and expressly disclaims any, representations
+ * or warranties, express or implied, regarding these materials, including,
+ * without limitation, any implied warranties of merchantability or fitness
+ * for a particular purpose or non-infringement of any intellectual property.
+ * Khronos Group makes no, and expressly disclaims any, warranties, express
+ * or implied, regarding the correctness, accuracy, completeness, timeliness,
+ * and reliability of these materials.
+ *
+ * Under no circumstances will the Khronos Group, or any of its Promoters,
+ * Contributors or Members or their respective partners, officers, directors,
+ * employees, agents or representatives be liable for any damages, whether
+ * direct, indirect, special or consequential damages for lost revenues,
+ * lost profits, or otherwise, arising from or in connection with these
+ * materials.
+ *
+ * Khronos and OpenMAX are trademarks of the Khronos Group Inc.
+ *
+ */
+
+#ifndef _OMXTYPES_H_
+#define _OMXTYPES_H_
+
+#include <limits.h>
+
+#define OMX_IN
+#define OMX_OUT
+#define OMX_INOUT
+
+
+typedef enum {
+
+ /* Mandatory return codes - use cases are explicitly described for each function */
+ OMX_Sts_NoErr = 0, /* No error, the function completed successfully */
+ OMX_Sts_Err = -2, /* Unknown/unspecified error */
+ OMX_Sts_InvalidBitstreamValErr = -182, /* Invalid value detected during bitstream processing */
+ OMX_Sts_MemAllocErr = -9, /* Not enough memory allocated for the operation */
+ OMX_StsACAAC_GainCtrErr = -159, /* AAC: Unsupported gain control data detected */
+ OMX_StsACAAC_PrgNumErr = -167, /* AAC: Invalid number of elements for one program */
+ OMX_StsACAAC_CoefValErr = -163, /* AAC: Invalid quantized coefficient value */
+ OMX_StsACAAC_MaxSfbErr = -162, /* AAC: Invalid maxSfb value in relation to numSwb */
+ OMX_StsACAAC_PlsDataErr = -160, /* AAC: pulse escape sequence data error */
+
+ /* Optional return codes - use cases are explicitly described for each function*/
+ OMX_Sts_BadArgErr = -5, /* Bad Arguments */
+
+ OMX_StsACAAC_TnsNumFiltErr = -157, /* AAC: Invalid number of TNS filters */
+ OMX_StsACAAC_TnsLenErr = -156, /* AAC: Invalid TNS region length */
+ OMX_StsACAAC_TnsOrderErr = -155, /* AAC: Invalid order of TNS filter */
+ OMX_StsACAAC_TnsCoefResErr = -154, /* AAC: Invalid bit-resolution for TNS filter coefficients */
+ OMX_StsACAAC_TnsCoefErr = -153, /* AAC: Invalid TNS filter coefficients */
+ OMX_StsACAAC_TnsDirectErr = -152, /* AAC: Invalid TNS filter direction */
+
+ OMX_StsICJP_JPEGMarkerErr = -183, /* JPEG marker encountered within an entropy-coded block; */
+ /* Huffman decoding operation terminated early. */
+ OMX_StsICJP_JPEGMarker = -181, /* JPEG marker encountered; Huffman decoding */
+ /* operation terminated early. */
+ OMX_StsIPPP_ContextMatchErr = -17, /* Context parameter doesn't match to the operation */
+
+ OMX_StsSP_EvenMedianMaskSizeErr = -180, /* Even size of the Median Filter mask was replaced by the odd one */
+
+ OMX_Sts_MaximumEnumeration = INT_MAX /*Placeholder, forces enum of size OMX_INT*/
+
+ } OMXResult; /** Return value or error value returned from a function. Identical to OMX_INT */
+
+
+/* OMX_U8 */
+#if UCHAR_MAX == 0xff
+typedef unsigned char OMX_U8;
+#elif USHRT_MAX == 0xff
+typedef unsigned short int OMX_U8;
+#else
+#error OMX_U8 undefined
+#endif
+
+
+/* OMX_S8 */
+#if SCHAR_MAX == 0x7f
+typedef signed char OMX_S8;
+#elif SHRT_MAX == 0x7f
+typedef signed short int OMX_S8;
+#else
+#error OMX_S8 undefined
+#endif
+
+
+/* OMX_U16 */
+#if USHRT_MAX == 0xffff
+typedef unsigned short int OMX_U16;
+#elif UINT_MAX == 0xffff
+typedef unsigned int OMX_U16;
+#else
+#error OMX_U16 undefined
+#endif
+
+
+/* OMX_S16 */
+#if SHRT_MAX == 0x7fff
+typedef signed short int OMX_S16;
+#elif INT_MAX == 0x7fff
+typedef signed int OMX_S16;
+#else
+#error OMX_S16 undefined
+#endif
+
+
+/* OMX_U32 */
+#if UINT_MAX == 0xffffffff
+typedef unsigned int OMX_U32;
+#elif LONG_MAX == 0xffffffff
+typedef unsigned long int OMX_U32;
+#else
+#error OMX_U32 undefined
+#endif
+
+
+/* OMX_S32 */
+#if INT_MAX == 0x7fffffff
+typedef signed int OMX_S32;
+#elif LONG_MAX == 0x7fffffff
+typedef long signed int OMX_S32;
+#else
+#error OMX_S32 undefined
+#endif
+
+
+/* OMX_U64 & OMX_S64 */
+#if defined( _WIN32 ) || defined ( _WIN64 )
+ typedef __int64 OMX_S64; /** Signed 64-bit integer */
+ typedef unsigned __int64 OMX_U64; /** Unsigned 64-bit integer */
+ #define OMX_MIN_S64 (0x8000000000000000i64)
+ #define OMX_MIN_U64 (0x0000000000000000i64)
+ #define OMX_MAX_S64 (0x7FFFFFFFFFFFFFFFi64)
+ #define OMX_MAX_U64 (0xFFFFFFFFFFFFFFFFi64)
+#else
+ typedef long long OMX_S64; /** Signed 64-bit integer */
+ typedef unsigned long long OMX_U64; /** Unsigned 64-bit integer */
+ #define OMX_MIN_S64 (0x8000000000000000LL)
+ #define OMX_MIN_U64 (0x0000000000000000LL)
+ #define OMX_MAX_S64 (0x7FFFFFFFFFFFFFFFLL)
+ #define OMX_MAX_U64 (0xFFFFFFFFFFFFFFFFLL)
+#endif
+
+
+/* OMX_SC8 */
+typedef struct
+{
+ OMX_S8 Re; /** Real part */
+ OMX_S8 Im; /** Imaginary part */
+
+} OMX_SC8; /** Signed 8-bit complex number */
+
+
+/* OMX_SC16 */
+typedef struct
+{
+ OMX_S16 Re; /** Real part */
+ OMX_S16 Im; /** Imaginary part */
+
+} OMX_SC16; /** Signed 16-bit complex number */
+
+
+/* OMX_SC32 */
+typedef struct
+{
+ OMX_S32 Re; /** Real part */
+ OMX_S32 Im; /** Imaginary part */
+
+} OMX_SC32; /** Signed 32-bit complex number */
+
+
+/* OMX_SC64 */
+typedef struct
+{
+ OMX_S64 Re; /** Real part */
+ OMX_S64 Im; /** Imaginary part */
+
+} OMX_SC64; /** Signed 64-bit complex number */
+
+
+/* OMX_F32 */
+typedef float OMX_F32; /** Single precision floating point,IEEE 754 */
+
+
+/* OMX_F64 */
+typedef double OMX_F64; /** Double precision floating point,IEEE 754 */
+
+
+/* OMX_INT */
+typedef int OMX_INT; /** signed integer corresponding to machine word length, has maximum signed value INT_MAX*/
+
+
+#define OMX_MIN_S8 (-128)
+#define OMX_MIN_U8 0
+#define OMX_MIN_S16 (-32768)
+#define OMX_MIN_U16 0
+#define OMX_MIN_S32 (-2147483647-1)
+#define OMX_MIN_U32 0
+
+#define OMX_MAX_S8 (127)
+#define OMX_MAX_U8 (255)
+#define OMX_MAX_S16 (32767)
+#define OMX_MAX_U16 (0xFFFF)
+#define OMX_MAX_S32 (2147483647)
+#define OMX_MAX_U32 (0xFFFFFFFF)
+
+typedef void OMXVoid;
+
+#ifndef NULL
+#define NULL ((void*)0)
+#endif
+
+/** Defines the geometric position and size of a rectangle,
+ * where x,y defines the coordinates of the top left corner
+ * of the rectangle, with dimensions width in the x-direction
+ * and height in the y-direction */
+typedef struct {
+ OMX_INT x; /** x-coordinate of top left corner of rectangle */
+ OMX_INT y; /** y-coordinate of top left corner of rectangle */
+ OMX_INT width; /** Width in the x-direction. */
+ OMX_INT height; /** Height in the y-direction. */
+}OMXRect;
+
+
+/** Defines the geometric position of a point, */
+typedef struct
+{
+ OMX_INT x; /** x-coordinate */
+ OMX_INT y; /** y-coordinate */
+
+} OMXPoint;
+
+
+/** Defines the dimensions of a rectangle, or region of interest in an image */
+typedef struct
+{
+ OMX_INT width; /** Width of the rectangle, in the x-direction */
+ OMX_INT height; /** Height of the rectangle, in the y-direction */
+
+} OMXSize;
+
+#endif /* _OMXTYPES_H_ */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/omxtypes_s.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/omxtypes_s.h
new file mode 100644
index 0000000..8d24b65
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/omxtypes_s.h
@@ -0,0 +1,77 @@
+;//
+;//
+;// File Name: omxtypes_s.h
+;// OpenMAX DL: v1.0.2
+;// Revision: 9641
+;// Date: Thursday, February 7, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+;// Mandatory return codes - use cases are explicitly described for each function
+OMX_Sts_NoErr EQU 0 ;// No error the function completed successfully
+OMX_Sts_Err EQU -2 ;// Unknown/unspecified error
+OMX_Sts_InvalidBitstreamValErr EQU -182 ;// Invalid value detected during bitstream processing
+OMX_Sts_MemAllocErr EQU -9 ;// Not enough memory allocated for the operation
+OMX_StsACAAC_GainCtrErr EQU -159 ;// AAC: Unsupported gain control data detected
+OMX_StsACAAC_PrgNumErr EQU -167 ;// AAC: Invalid number of elements for one program
+OMX_StsACAAC_CoefValErr EQU -163 ;// AAC: Invalid quantized coefficient value
+OMX_StsACAAC_MaxSfbErr EQU -162 ;// AAC: Invalid maxSfb value in relation to numSwb
+OMX_StsACAAC_PlsDataErr EQU -160 ;// AAC: pulse escape sequence data error
+
+;// Optional return codes - use cases are explicitly described for each function
+OMX_Sts_BadArgErr EQU -5 ;// Bad Arguments
+
+OMX_StsACAAC_TnsNumFiltErr EQU -157 ;// AAC: Invalid number of TNS filters
+OMX_StsACAAC_TnsLenErr EQU -156 ;// AAC: Invalid TNS region length
+OMX_StsACAAC_TnsOrderErr EQU -155 ;// AAC: Invalid order of TNS filter
+OMX_StsACAAC_TnsCoefResErr EQU -154 ;// AAC: Invalid bit-resolution for TNS filter coefficients
+OMX_StsACAAC_TnsCoefErr EQU -153 ;// AAC: Invalid TNS filter coefficients
+OMX_StsACAAC_TnsDirectErr EQU -152 ;// AAC: Invalid TNS filter direction
+
+OMX_StsICJP_JPEGMarkerErr EQU -183 ;// JPEG marker encountered within an entropy-coded block;
+ ;// Huffman decoding operation terminated early.
+OMX_StsICJP_JPEGMarker EQU -181 ;// JPEG marker encountered; Huffman decoding
+ ;// operation terminated early.
+OMX_StsIPPP_ContextMatchErr EQU -17 ;// Context parameter doesn't match to the operation
+
+OMX_StsSP_EvenMedianMaskSizeErr EQU -180 ;// Even size of the Median Filter mask was replaced by the odd one
+
+OMX_Sts_MaximumEnumeration EQU 0x7FFFFFFF
+
+
+
+OMX_MIN_S8 EQU (-128)
+OMX_MIN_U8 EQU 0
+OMX_MIN_S16 EQU (-32768)
+OMX_MIN_U16 EQU 0
+
+
+OMX_MIN_S32 EQU (-2147483647-1)
+OMX_MIN_U32 EQU 0
+
+OMX_MAX_S8 EQU (127)
+OMX_MAX_U8 EQU (255)
+OMX_MAX_S16 EQU (32767)
+OMX_MAX_U16 EQU (0xFFFF)
+OMX_MAX_S32 EQU (2147483647)
+OMX_MAX_U32 EQU (0xFFFFFFFF)
+
+OMX_VC_UPPER EQU 0x1 ;// Used by the PredictIntra functions
+OMX_VC_LEFT EQU 0x2 ;// Used by the PredictIntra functions
+OMX_VC_UPPER_RIGHT EQU 0x40 ;// Used by the PredictIntra functions
+
+NULL EQU 0
+
+;// Structures
+
+ INCLUDE armCOMM_s.h
+
+ M_STRUCT OMXPoint
+ M_FIELD x, 4
+ M_FIELD y, 4
+ M_ENDSTRUCT
+
+ END
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/build_vc.pl b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/build_vc.pl
new file mode 100755
index 0000000..1ae7005
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/build_vc.pl
@@ -0,0 +1,111 @@
+#!/usr/bin/perl
+#
+#
+# File Name: build_vc.pl
+# OpenMAX DL: v1.0.2
+# Revision: 9641
+# Date: Thursday, February 7, 2008
+#
+# (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+#
+#
+#
+# This file builds the OpenMAX DL vc domain library omxVC.o.
+#
+
+use File::Spec;
+use strict;
+
+my ($CC, $CC_OPTS, $AS, $AS_OPTS, $LIB, $LIB_OPTS, $LIB_TYPE);
+
+$CC = 'armcc';
+$CC_OPTS = '--no_unaligned_access --cpu ARM1136J-S -c';
+$AS = 'armasm';
+$AS_OPTS = '--no_unaligned_access --cpu ARM1136J-S';
+# $LIB = 'armlink';
+# $LIB_OPTS = '--partial -o';
+# $LIB_TYPE = '.o';
+$LIB = 'armar';
+$LIB_OPTS = '--create -r';
+$LIB_TYPE = '.a';
+
+#------------------------
+
+my (@headerlist, @filelist, $hd, $file, $ofile, $command, $objlist, $libfile, $h);
+
+# Define the list of directories containing included header files.
+@headerlist = qw(api vc/api vc/m4p2/api vc/m4p10/api);
+
+# Define the list of source files to compile.
+open(FILES, '<filelist_vc.txt') or die("Can't open source file list\n");
+@filelist = <FILES>;
+close(FILES);
+
+# Fix the file separators in the header paths
+foreach $h (@headerlist)
+{
+ $h = File::Spec->canonpath($h);
+}
+
+# Create the include path to be passed to the compiler
+$hd = '-I' . join(' -I', @headerlist);
+
+# Create the build directories "/lib/" and "/obj/" (if they are not there already)
+mkdir "obj", 0777 if (! -d "obj");
+mkdir "lib", 0777 if (! -d "lib");
+
+$objlist = '';
+
+# Compile each file
+foreach $file (@filelist)
+{
+ my $f;
+ my $base;
+ my $ext;
+ my $objfile;
+
+ chomp($file);
+ $file = File::Spec->canonpath($file);
+
+ (undef, undef, $f) = File::Spec->splitpath($file);
+ if(($base, $ext) = $f =~ /(.+)\.(\w)$/)
+ {
+ $objfile = File::Spec->catfile('obj', $base.'.o');
+
+ if($ext eq 'c')
+ {
+ $objlist .= "$objfile ";
+ $command = $CC.' '.$CC_OPTS.' '.$hd.' -o '.$objfile.' '.$file;
+ print "$command\n";
+ system($command);
+ }
+ elsif($ext eq 's')
+ {
+ $objlist .= "$objfile ";
+ $command = $AS.' '.$AS_OPTS.' '.$hd.' -o '.$objfile.' '.$file;
+ print "$command\n";
+ system($command);
+ }
+ else
+ {
+ print "Ignoring file: $f\n";
+ }
+ }
+ else
+ {
+ die "No file extension found: $f\n";
+ }
+}
+
+# Do the final link stage to create the libraries.
+$libfile = File::Spec->catfile('lib', 'omxVC'.$LIB_TYPE);
+$command = $LIB.' '.$LIB_OPTS.' '.$libfile.' '.$objlist;
+print "$command\n";
+(system($command) == 0) and print "Build successful\n";
+
+
+
+
+
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/filelist_vc.txt b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/filelist_vc.txt
new file mode 100644
index 0000000..0f1623f
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/filelist_vc.txt
@@ -0,0 +1,74 @@
+./api/armCOMM.h
+./api/armCOMM_BitDec_s.h
+./api/armCOMM_Bitstream.h
+./api/armCOMM_IDCT_s.h
+./api/armCOMM_IDCTTable.h
+./api/armCOMM_MaskTable.h
+./api/armCOMM_s.h
+./api/armCOMM_Version.h
+./api/armOMX_ReleaseVersion.h
+./api/omxtypes.h
+./api/omxtypes_s.h
+./src/armCOMM_IDCTTable.c
+./src/armCOMM_MaskTable.c
+./vc/api/armVC.h
+./vc/api/armVCCOMM_s.h
+./vc/api/omxVC.h
+./vc/api/omxVC_s.h
+./vc/comm/src/omxVCCOMM_Copy16x16_s.s
+./vc/comm/src/omxVCCOMM_Copy8x8_s.s
+./vc/comm/src/omxVCCOMM_ExpandFrame_I_s.s
+./vc/m4p10/api/armVCM4P10_CAVLCTables.h
+./vc/m4p10/src/armVCM4P10_Average_4x_Align_unsafe_s.s
+./vc/m4p10/src/armVCM4P10_CAVLCTables.c
+./vc/m4p10/src/armVCM4P10_DeblockingChroma_unsafe_s.s
+./vc/m4p10/src/armVCM4P10_DeblockingLuma_unsafe_s.s
+./vc/m4p10/src/armVCM4P10_DecodeCoeffsToPair_s.s
+./vc/m4p10/src/armVCM4P10_DequantTables_s.s
+./vc/m4p10/src/armVCM4P10_Interpolate_Chroma_s.s
+./vc/m4p10/src/armVCM4P10_InterpolateLuma_Align_unsafe_s.s
+./vc/m4p10/src/armVCM4P10_InterpolateLuma_Copy_unsafe_s.s
+./vc/m4p10/src/armVCM4P10_InterpolateLuma_DiagCopy_unsafe_s.s
+./vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe_s.s
+./vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe_s.s
+./vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe_s.s
+./vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe_s.s
+./vc/m4p10/src/armVCM4P10_QuantTables_s.s
+./vc/m4p10/src/armVCM4P10_TransformResidual4x4_s.s
+./vc/m4p10/src/armVCM4P10_UnpackBlock4x4_s.s
+./vc/m4p10/src/omxVCM4P10_DeblockChroma_I.c
+./vc/m4p10/src/omxVCM4P10_DeblockLuma_I.c
+./vc/m4p10/src/omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c
+./vc/m4p10/src/omxVCM4P10_DecodeCoeffsToPairCAVLC.c
+./vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_HorEdge_I_s.s
+./vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_VerEdge_I_s.s
+./vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_HorEdge_I_s.s
+./vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_VerEdge_I_s.s
+./vc/m4p10/src/omxVCM4P10_InterpolateChroma.c
+./vc/m4p10/src/omxVCM4P10_InterpolateLuma_s.s
+./vc/m4p10/src/omxVCM4P10_PredictIntra_16x16_s.s
+./vc/m4p10/src/omxVCM4P10_PredictIntra_4x4_s.s
+./vc/m4p10/src/omxVCM4P10_PredictIntraChroma_8x8_s.s
+./vc/m4p10/src/omxVCM4P10_TransformDequantChromaDCFromPair_s.s
+./vc/m4p10/src/omxVCM4P10_TransformDequantLumaDCFromPair_s.s
+./vc/m4p2/api/armVCM4P2_Huff_Tables_VLC.h
+./vc/m4p2/api/armVCM4P2_ZigZag_Tables.h
+./vc/m4p2/src/armVCM4P2_Clip8_s.s
+./vc/m4p2/src/armVCM4P2_DecodeVLCZigzag_AC_unsafe_s.s
+./vc/m4p2/src/armVCM4P2_Huff_Tables_VLC.c
+./vc/m4p2/src/armVCM4P2_Lookup_Tables.c
+./vc/m4p2/src/armVCM4P2_SetPredDir_s.s
+./vc/m4p2/src/armVCM4P2_Zigzag_Tables.c
+./vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Inter.c
+./vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Intra.c
+./vc/m4p2/src/omxVCM4P2_DecodePadMV_PVOP_s.s
+./vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_Inter_s.s
+./vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraACVLC_s.s
+./vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraDCVLC_s.s
+./vc/m4p2/src/omxVCM4P2_FindMVpred_s.s
+./vc/m4p2/src/omxVCM4P2_IDCT8x8blk_s.s
+./vc/m4p2/src/omxVCM4P2_MCReconBlock_s.s
+./vc/m4p2/src/omxVCM4P2_PredictReconCoefIntra_s.s
+./vc/m4p2/src/omxVCM4P2_QuantInvInter_I_s.s
+./vc/m4p2/src/omxVCM4P2_QuantInvIntra_I_s.s
+./vc/src/armVC_Version.c
\ No newline at end of file
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/src/armCOMM.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/src/armCOMM.c
new file mode 100644
index 0000000..e572a89
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/src/armCOMM.c
@@ -0,0 +1,936 @@
+/**
+ *
+ * File Name: armCOMM.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Defines Common APIs used across OpenMAX API's
+ */
+
+#include "omxtypes.h"
+#include "armCOMM.h"
+
+/***********************************************************************/
+ /* Miscellaneous Arithmetic operations */
+
+/**
+ * Function: armRoundFloatToS16
+ *
+ * Description:
+ * Converts a double precision value into a short int after rounding
+ *
+ * Parameters:
+ * [in] Value Float value to be converted
+ *
+ * Return Value:
+ * [out] converted value in OMX_S16 format
+ *
+ */
+
+OMX_S16 armRoundFloatToS16 (OMX_F64 Value)
+{
+ if (Value > 0)
+ {
+ return (OMX_S16)(Value + .5);
+ }
+ else
+ {
+ return (OMX_S16)(Value - .5);
+ }
+}
+
+/**
+ * Function: armRoundFloatToS32
+ *
+ * Description:
+ * Converts a double precision value into a int after rounding
+ *
+ * Parameters:
+ * [in] Value Float value to be converted
+ *
+ * Return Value:
+ * [out] converted value in OMX_S32 format
+ *
+ */
+
+OMX_S32 armRoundFloatToS32 (OMX_F64 Value)
+{
+ if (Value > 0)
+ {
+ return (OMX_S32)(Value + .5);
+ }
+ else
+ {
+ return (OMX_S32)(Value - .5);
+ }
+}
+/**
+ * Function: armSatRoundFloatToS16
+ *
+ * Description:
+ * Converts a double precision value into a short int after rounding and saturation
+ *
+ * Parameters:
+ * [in] Value Float value to be converted
+ *
+ * Return Value:
+ * [out] converted value in OMX_S16 format
+ *
+ */
+
+OMX_S16 armSatRoundFloatToS16 (OMX_F64 Value)
+{
+ if (Value > 0)
+ {
+ Value += 0.5;
+
+ if(Value > (OMX_S16)OMX_MAX_S16 )
+ {
+ return (OMX_S16)OMX_MAX_S16;
+ }
+ else
+ {
+ return (OMX_S16)Value;
+ }
+ }
+ else
+ {
+ Value -= 0.5;
+
+ if(Value < (OMX_S16)OMX_MIN_S16 )
+ {
+ return (OMX_S16)OMX_MIN_S16;
+ }
+ else
+ {
+ return (OMX_S16)Value;
+ }
+ }
+}
+
+/**
+ * Function: armSatRoundFloatToS32
+ *
+ * Description:
+ * Converts a double precision value into a int after rounding and saturation
+ *
+ * Parameters:
+ * [in] Value Float value to be converted
+ *
+ * Return Value:
+ * [out] converted value in OMX_S32 format
+ *
+ */
+
+OMX_S32 armSatRoundFloatToS32 (OMX_F64 Value)
+{
+ if (Value > 0)
+ {
+ Value += 0.5;
+
+ if(Value > (OMX_S32)OMX_MAX_S32 )
+ {
+ return (OMX_S32)OMX_MAX_S32;
+ }
+ else
+ {
+ return (OMX_S32)Value;
+ }
+ }
+ else
+ {
+ Value -= 0.5;
+
+ if(Value < (OMX_S32)OMX_MIN_S32 )
+ {
+ return (OMX_S32)OMX_MIN_S32;
+ }
+ else
+ {
+ return (OMX_S32)Value;
+ }
+ }
+}
+
+/**
+ * Function: armSatRoundFloatToU16
+ *
+ * Description:
+ * Converts a double precision value into a unsigned short int after rounding and saturation
+ *
+ * Parameters:
+ * [in] Value Float value to be converted
+ *
+ * Return Value:
+ * [out] converted value in OMX_U16 format
+ *
+ */
+
+OMX_U16 armSatRoundFloatToU16 (OMX_F64 Value)
+{
+ Value += 0.5;
+
+ if(Value > (OMX_U16)OMX_MAX_U16 )
+ {
+ return (OMX_U16)OMX_MAX_U16;
+ }
+ else
+ {
+ return (OMX_U16)Value;
+ }
+}
+
+/**
+ * Function: armSatRoundFloatToU32
+ *
+ * Description:
+ * Converts a double precision value into a unsigned int after rounding and saturation
+ *
+ * Parameters:
+ * [in] Value Float value to be converted
+ *
+ * Return Value:
+ * [out] converted value in OMX_U32 format
+ *
+ */
+
+OMX_U32 armSatRoundFloatToU32 (OMX_F64 Value)
+{
+ Value += 0.5;
+
+ if(Value > (OMX_U32)OMX_MAX_U32 )
+ {
+ return (OMX_U32)OMX_MAX_U32;
+ }
+ else
+ {
+ return (OMX_U32)Value;
+ }
+}
+
+/**
+ * Function: armRoundFloatToS64
+ *
+ * Description:
+ * Converts a double precision value into a 64 bit int after rounding
+ *
+ * Parameters:
+ * [in] Value Float value to be converted
+ *
+ * Return Value:
+ * [out] converted value in OMX_S64 format
+ *
+ */
+
+OMX_S64 armRoundFloatToS64 (OMX_F64 Value)
+{
+ if (Value > 0)
+ {
+ return (OMX_S64)(Value + .5);
+ }
+ else
+ {
+ return (OMX_S64)(Value - .5);
+ }
+}
+
+/**
+ * Function: armSignCheck
+ *
+ * Description:
+ * Checks the sign of a variable:
+ * returns 1 if it is Positive
+ * returns 0 if it is 0
+ * returns -1 if it is Negative
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] var Variable to be checked
+ *
+ * Return Value:
+ * OMX_INT -- returns 1 if it is Positive
+ * returns 0 if it is 0
+ * returns -1 if it is Negative
+ */
+
+OMX_INT armSignCheck (
+ OMX_S16 var
+)
+
+{
+ OMX_INT Sign;
+
+ if (var < 0)
+ {
+ Sign = -1;
+ }
+ else if ( var > 0)
+ {
+ Sign = 1;
+ }
+ else
+ {
+ Sign = 0;
+ }
+
+ return Sign;
+}
+
+/**
+ * Function: armClip
+ *
+ * Description: Clips the input between MAX and MIN value
+ *
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] Min lower bound
+ * [in] Max upper bound
+ * [in] src variable to the clipped
+ *
+ * Return Value:
+ * OMX_S32 -- returns clipped value
+ */
+
+OMX_S32 armClip (
+ OMX_INT min,
+ OMX_INT max,
+ OMX_S32 src
+)
+
+{
+ if (src > max)
+ {
+ src = max;
+ }
+ else if (src < min)
+ {
+ src = min;
+ }
+
+ return src;
+}
+
+/**
+ * Function: armClip_F32
+ *
+ * Description: Clips the input between MAX and MIN value
+ *
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] Min lower bound
+ * [in] Max upper bound
+ * [in] src variable to the clipped
+ *
+ * Return Value:
+ * OMX_F32 -- returns clipped value
+ */
+
+OMX_F32 armClip_F32 (
+ OMX_F32 min,
+ OMX_F32 max,
+ OMX_F32 src
+)
+
+{
+ if (src > max)
+ {
+ src = max;
+ }
+ else if (src < min)
+ {
+ src = min;
+ }
+
+ return src;
+}
+
+/**
+ * Function: armShiftSat_F32
+ *
+ * Description: Divides a float value by 2^shift and
+ * saturates it for unsigned value range for satBits.
+ * Second parameter is like "shifting" the corresponding
+ * integer value. Takes care of rounding while clipping the final
+ * value.
+ *
+ * Parameters:
+ * [in] v Number to be operated upon
+ * [in] shift Divides the input "v" by "2^shift"
+ * [in] satBits Final range is [0, 2^satBits)
+ *
+ * Return Value:
+ * OMX_S32 -- returns "shifted" saturated value
+ */
+
+OMX_U32 armShiftSat_F32(OMX_F32 v, OMX_INT shift, OMX_INT satBits)
+{
+ OMX_U32 allOnes = (OMX_U32)(-1);
+ OMX_U32 maxV = allOnes >> (32-satBits);
+ OMX_F32 vShifted, vRounded, shiftDiv = (OMX_F32)(1 << shift);
+ OMX_U32 vInt;
+ OMX_U32 vIntSat;
+
+ if(v <= 0)
+ return 0;
+
+ vShifted = v / shiftDiv;
+ vRounded = (OMX_F32)(vShifted + 0.5);
+ vInt = (OMX_U32)vRounded;
+ vIntSat = vInt;
+ if(vIntSat > maxV)
+ vIntSat = maxV;
+ return vIntSat;
+}
+
+/**
+ * Functions: armSwapElem
+ *
+ * Description:
+ * These function swaps two elements at the specified pointer locations.
+ * The size of each element could be anything as specified by <elemSize>
+ *
+ * Return Value:
+ * OMXResult -- Error status from the function
+ */
+OMXResult armSwapElem(
+ OMX_U8 *pBuf1,
+ OMX_U8 *pBuf2,
+ OMX_INT elemSize
+ )
+{
+ OMX_INT i;
+ OMX_U8 temp;
+ armRetArgErrIf(!pBuf1 || !pBuf2, OMX_Sts_BadArgErr);
+
+ for(i = 0; i < elemSize; i++)
+ {
+ temp = *(pBuf1 + i);
+ *(pBuf1 + i) = *(pBuf2 + i);
+ *(pBuf2 + i) = temp;
+ }
+ return OMX_Sts_NoErr;
+}
+
+/**
+ * Function: armMedianOf3
+ *
+ * Description: Finds the median of three numbers
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] fEntry First entry
+ * [in] sEntry second entry
+ * [in] tEntry Third entry
+ *
+ * Return Value:
+ * OMX_S32 -- returns the median value
+ */
+
+OMX_S32 armMedianOf3 (
+ OMX_S32 fEntry,
+ OMX_S32 sEntry,
+ OMX_S32 tEntry
+)
+{
+ OMX_S32 a, b, c;
+
+ a = armMin (fEntry, sEntry);
+ b = armMax (fEntry, sEntry);
+ c = armMin (b, tEntry);
+ return (armMax (a, c));
+}
+
+/**
+ * Function: armLogSize
+ *
+ * Description: Finds the size of a positive value and returns the same
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] value Positive value
+ *
+ * Return Value:
+ * OMX_U8 -- Returns the minimum number of bits required to represent the positive value.
+ This is the smallest k>=0 such that that value is less than (1<<k).
+ */
+
+OMX_U8 armLogSize (
+ OMX_U16 value
+)
+{
+ OMX_U8 i;
+ for ( i = 0; value > 0; value = value >> 1)
+ {
+ i++;
+ }
+ return i;
+}
+
+/***********************************************************************/
+ /* Saturating Arithmetic operations */
+
+/**
+ * Function :armSatAdd_S32()
+ *
+ * Description :
+ * Returns the result of saturated addition of the two inputs Value1, Value2
+ *
+ * Parametrs:
+ * [in] Value1 First Operand
+ * [in] Value2 Second Operand
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ *
+ **/
+
+OMX_S32 armSatAdd_S32(OMX_S32 Value1,OMX_S32 Value2)
+{
+ OMX_S32 Result;
+
+ Result = Value1 + Value2;
+
+ if( (Value1^Value2) >= 0)
+ {
+ /*Same sign*/
+ if( (Result^Value1) >= 0)
+ {
+ /*Result has not saturated*/
+ return Result;
+ }
+ else
+ {
+ if(Value1 >= 0)
+ {
+ /*Result has saturated in positive side*/
+ return OMX_MAX_S32;
+ }
+ else
+ {
+ /*Result has saturated in negative side*/
+ return OMX_MIN_S32;
+ }
+
+ }
+
+ }
+ else
+ {
+ return Result;
+ }
+
+}
+
+/**
+ * Function :armSatAdd_S64()
+ *
+ * Description :
+ * Returns the result of saturated addition of the two inputs Value1, Value2
+ *
+ * Parametrs:
+ * [in] Value1 First Operand
+ * [in] Value2 Second Operand
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ *
+ **/
+
+OMX_S64 armSatAdd_S64(OMX_S64 Value1,OMX_S64 Value2)
+{
+ OMX_S64 Result;
+
+ Result = Value1 + Value2;
+
+ if( (Value1^Value2) >= 0)
+ {
+ /*Same sign*/
+ if( (Result^Value1) >= 0)
+ {
+ /*Result has not saturated*/
+ return Result;
+ }
+ else
+ {
+ if(Value1 >= 0)
+ {
+ /*Result has saturated in positive side*/
+ Result = OMX_MAX_S64;
+ return Result;
+ }
+ else
+ {
+ /*Result has saturated in negative side*/
+ return OMX_MIN_S64;
+ }
+
+ }
+
+ }
+ else
+ {
+ return Result;
+ }
+
+}
+
+/** Function :armSatSub_S32()
+ *
+ * Description :
+ * Returns the result of saturated substraction of the two inputs Value1, Value2
+ *
+ * Parametrs:
+ * [in] Value1 First Operand
+ * [in] Value2 Second Operand
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ **/
+
+OMX_S32 armSatSub_S32(OMX_S32 Value1,OMX_S32 Value2)
+{
+ OMX_S32 Result;
+
+ Result = Value1 - Value2;
+
+ if( (Value1^Value2) < 0)
+ {
+ /*Opposite sign*/
+ if( (Result^Value1) >= 0)
+ {
+ /*Result has not saturated*/
+ return Result;
+ }
+ else
+ {
+ if(Value1 >= 0)
+ {
+ /*Result has saturated in positive side*/
+ return OMX_MAX_S32;
+ }
+ else
+ {
+ /*Result has saturated in negative side*/
+ return OMX_MIN_S32;
+ }
+
+ }
+
+ }
+ else
+ {
+ return Result;
+ }
+
+}
+
+/**
+ * Function :armSatMac_S32()
+ *
+ * Description :
+ * Returns the result of Multiplication of Value1 and Value2 and subesquent saturated
+ * accumulation with Mac
+ *
+ * Parametrs:
+ * [in] Value1 First Operand
+ * [in] Value2 Second Operand
+ * [in] Mac Accumulator
+ *
+ * Return:
+ * [out] Result of operation
+ **/
+
+OMX_S32 armSatMac_S32(OMX_S32 Mac,OMX_S16 Value1,OMX_S16 Value2)
+{
+ OMX_S32 Result;
+
+ Result = (OMX_S32)(Value1*Value2);
+ Result = armSatAdd_S32( Mac , Result );
+
+ return Result;
+}
+
+/**
+ * Function :armSatMac_S16S32_S32
+ *
+ * Description :
+ * Returns the result of saturated MAC operation of the three inputs delayElem, filTap , mac
+ *
+ * mac = mac + Saturate_in_32Bits(delayElem * filTap)
+ *
+ * Parametrs:
+ * [in] delayElem First 32 bit Operand
+ * [in] filTap Second 16 bit Operand
+ * [in] mac Result of MAC operation
+ *
+ * Return:
+ * [out] mac Result of operation
+ *
+ **/
+
+OMX_S32 armSatMac_S16S32_S32(OMX_S32 mac, OMX_S32 delayElem, OMX_S16 filTap )
+{
+
+ OMX_S32 result;
+
+ result = armSatMulS16S32_S32(filTap,delayElem);
+
+ if ( result > OMX_MAX_S16 )
+ {
+ result = OMX_MAX_S32;
+ }
+ else if( result < OMX_MIN_S16 )
+ {
+ result = OMX_MIN_S32;
+ }
+ else
+ {
+ result = delayElem * filTap;
+ }
+
+ mac = armSatAdd_S32(mac,result);
+
+ return mac;
+}
+
+
+/**
+ * Function :armSatRoundRightShift_S32_S16
+ *
+ * Description :
+ * Returns the result of rounded right shift operation of input by the scalefactor
+ *
+ * output = Saturate_in_16Bits( ( Right/LeftShift( (Round(input) , shift ) )
+ *
+ * Parametrs:
+ * [in] input The input to be operated on
+ * [in] shift The shift number
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ **/
+
+
+OMX_S16 armSatRoundRightShift_S32_S16(OMX_S32 input, OMX_INT shift)
+{
+ input = armSatRoundLeftShift_S32(input,-shift);
+
+ if ( input > OMX_MAX_S16 )
+ {
+ return (OMX_S16)OMX_MAX_S16;
+ }
+ else if (input < OMX_MIN_S16)
+ {
+ return (OMX_S16)OMX_MIN_S16;
+ }
+ else
+ {
+ return (OMX_S16)input;
+ }
+
+}
+
+/**
+ * Function :armSatRoundLeftShift_S32()
+ *
+ * Description :
+ * Returns the result of saturating left-shift operation on input
+ * Or rounded Right shift if the input Shift is negative.
+ *
+ * Parametrs:
+ * [in] Value Operand
+ * [in] Shift Operand for shift operation
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ **/
+
+OMX_S32 armSatRoundLeftShift_S32(OMX_S32 Value, OMX_INT Shift)
+{
+ OMX_INT i;
+
+ if (Shift < 0)
+ {
+ Shift = -Shift;
+ Value = armSatAdd_S32(Value, (1 << (Shift - 1)));
+ Value = Value >> Shift;
+ }
+ else
+ {
+ for (i = 0; i < Shift; i++)
+ {
+ Value = armSatAdd_S32(Value, Value);
+ }
+ }
+ return Value;
+}
+
+/**
+ * Function :armSatRoundLeftShift_S64()
+ *
+ * Description :
+ * Returns the result of saturating left-shift operation on input
+ * Or rounded Right shift if the input Shift is negative.
+ *
+ * Parametrs:
+ * [in] Value Operand
+ * [in] shift Operand for shift operation
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ **/
+
+OMX_S64 armSatRoundLeftShift_S64(OMX_S64 Value, OMX_INT Shift)
+{
+ OMX_INT i;
+
+ if (Shift < 0)
+ {
+ Shift = -Shift;
+ Value = armSatAdd_S64(Value, ((OMX_S64)1 << (Shift - 1)));
+ Value = Value >> Shift;
+ }
+ else
+ {
+ for (i = 0; i < Shift; i++)
+ {
+ Value = armSatAdd_S64(Value, Value);
+ }
+ }
+ return Value;
+}
+
+/**
+ * Function :armSatMulS16S32_S32()
+ *
+ * Description :
+ * Returns the result of a S16 data type multiplied with an S32 data type
+ * in a S32 container
+ *
+ * Parametrs:
+ * [in] input1 Operand 1
+ * [in] input2 Operand 2
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ **/
+
+
+OMX_S32 armSatMulS16S32_S32(OMX_S16 input1,OMX_S32 input2)
+{
+ OMX_S16 hi2,lo1;
+ OMX_U16 lo2;
+
+ OMX_S32 temp1,temp2;
+ OMX_S32 result;
+
+ lo1 = input1;
+
+ hi2 = ( input2 >> 16 );
+ lo2 = ( (OMX_U32)( input2 << 16 ) >> 16 );
+
+ temp1 = hi2 * lo1;
+ temp2 = ( lo2* lo1 ) >> 16;
+
+ result = armSatAdd_S32(temp1,temp2);
+
+ return result;
+}
+
+/**
+ * Function :armSatMulS32S32_S32()
+ *
+ * Description :
+ * Returns the result of a S32 data type multiplied with an S32 data type
+ * in a S32 container
+ *
+ * Parametrs:
+ * [in] input1 Operand 1
+ * [in] input2 Operand 2
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ **/
+
+OMX_S32 armSatMulS32S32_S32(OMX_S32 input1,OMX_S32 input2)
+{
+ OMX_S16 hi1,hi2;
+ OMX_U16 lo1,lo2;
+
+ OMX_S32 temp1,temp2,temp3;
+ OMX_S32 result;
+
+ hi1 = ( input1 >> 16 );
+ lo1 = ( (OMX_U32)( input1 << 16 ) >> 16 );
+
+ hi2 = ( input2 >> 16 );
+ lo2 = ( (OMX_U32)( input2 << 16 ) >> 16 );
+
+ temp1 = hi1 * hi2;
+ temp2 = ( hi1* lo2 ) >> 16;
+ temp3 = ( hi2* lo1 ) >> 16;
+
+ result = armSatAdd_S32(temp1,temp2);
+ result = armSatAdd_S32(result,temp3);
+
+ return result;
+}
+
+/**
+ * Function :armIntDivAwayFromZero()
+ *
+ * Description : Integer division with rounding to the nearest integer.
+ * Half-integer values are rounded away from zero
+ * unless otherwise specified. For example 3//2 is rounded
+ * to 2, and -3//2 is rounded to -2.
+ *
+ * Parametrs:
+ * [in] Num Operand 1
+ * [in] Deno Operand 2
+ *
+ * Return:
+ * [out] Result of operation input1//input2
+ *
+ **/
+
+OMX_S32 armIntDivAwayFromZero (OMX_S32 Num, OMX_S32 Deno)
+{
+ OMX_F64 result;
+
+ result = ((OMX_F64)Num)/((OMX_F64)Deno);
+
+ if (result >= 0)
+ {
+ result += 0.5;
+ }
+ else
+ {
+ result -= 0.5;
+ }
+
+ return (OMX_S32)(result);
+}
+
+
+/*End of File*/
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/src/armCOMM_Bitstream.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/src/armCOMM_Bitstream.c
new file mode 100644
index 0000000..9ef9319
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/src/armCOMM_Bitstream.c
@@ -0,0 +1,329 @@
+/**
+ *
+ * File Name: armCOMM_Bitstream.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Defines bitstream encode and decode functions common to all codecs
+ */
+
+#include "omxtypes.h"
+#include "armCOMM.h"
+#include "armCOMM_Bitstream.h"
+
+/***************************************
+ * Fixed bit length Decode
+ ***************************************/
+
+/**
+ * Function: armLookAheadBits()
+ *
+ * Description:
+ * Get the next N bits from the bitstream without advancing the bitstream pointer
+ *
+ * Parameters:
+ * [in] **ppBitStream
+ * [in] *pOffset
+ * [in] N=1...32
+ *
+ * Returns Value
+ */
+
+OMX_U32 armLookAheadBits(const OMX_U8 **ppBitStream, OMX_INT *pOffset, OMX_INT N)
+{
+ const OMX_U8 *pBitStream = *ppBitStream;
+ OMX_INT Offset = *pOffset;
+ OMX_U32 Value;
+
+ armAssert(Offset>=0 && Offset<=7);
+ armAssert(N>=1 && N<=32);
+
+ /* Read next 32 bits from stream */
+ Value = (pBitStream[0] << 24 ) | ( pBitStream[1] << 16) | (pBitStream[2] << 8 ) | (pBitStream[3]) ;
+ Value = (Value << Offset ) | (pBitStream[4] >> (8-Offset));
+
+ /* Return N bits */
+ return Value >> (32-N);
+}
+
+
+/**
+ * Function: armGetBits()
+ *
+ * Description:
+ * Read N bits from the bitstream
+ *
+ * Parameters:
+ * [in] *ppBitStream
+ * [in] *pOffset
+ * [in] N=1..32
+ *
+ * [out] *ppBitStream
+ * [out] *pOffset
+ * Returns Value
+ */
+
+
+OMX_U32 armGetBits(const OMX_U8 **ppBitStream, OMX_INT *pOffset, OMX_INT N)
+{
+ const OMX_U8 *pBitStream = *ppBitStream;
+ OMX_INT Offset = *pOffset;
+ OMX_U32 Value;
+
+ if(N == 0)
+ {
+ return 0;
+ }
+
+ armAssert(Offset>=0 && Offset<=7);
+ armAssert(N>=1 && N<=32);
+
+ /* Read next 32 bits from stream */
+ Value = (pBitStream[0] << 24 ) | ( pBitStream[1] << 16) | (pBitStream[2] << 8 ) | (pBitStream[3]) ;
+ Value = (Value << Offset ) | (pBitStream[4] >> (8-Offset));
+
+ /* Advance bitstream pointer by N bits */
+ Offset += N;
+ *ppBitStream = pBitStream + (Offset>>3);
+ *pOffset = Offset & 7;
+
+ /* Return N bits */
+ return Value >> (32-N);
+}
+
+/**
+ * Function: armByteAlign()
+ *
+ * Description:
+ * Align the pointer *ppBitStream to the next byte boundary
+ *
+ * Parameters:
+ * [in] *ppBitStream
+ * [in] *pOffset
+ *
+ * [out] *ppBitStream
+ * [out] *pOffset
+ *
+ **/
+
+OMXVoid armByteAlign(const OMX_U8 **ppBitStream,OMX_INT *pOffset)
+{
+ if(*pOffset > 0)
+ {
+ *ppBitStream += 1;
+ *pOffset = 0;
+ }
+}
+
+/**
+ * Function: armSkipBits()
+ *
+ * Description:
+ * Skip N bits from the value at *ppBitStream
+ *
+ * Parameters:
+ * [in] *ppBitStream
+ * [in] *pOffset
+ * [in] N
+ *
+ * [out] *ppBitStream
+ * [out] *pOffset
+ *
+ **/
+
+
+OMXVoid armSkipBits(const OMX_U8 **ppBitStream,OMX_INT *pOffset,OMX_INT N)
+{
+ OMX_INT Offset = *pOffset;
+ const OMX_U8 *pBitStream = *ppBitStream;
+
+ /* Advance bitstream pointer by N bits */
+ Offset += N;
+ *ppBitStream = pBitStream + (Offset>>3);
+ *pOffset = Offset & 7;
+}
+
+/***************************************
+ * Variable bit length Decode
+ ***************************************/
+
+/**
+ * Function: armUnPackVLC32()
+ *
+ * Description:
+ * Variable length decode of variable length symbol (max size 32 bits) read from
+ * the bit stream pointed by *ppBitStream at *pOffset by using the table
+ * pointed by pCodeBook
+ *
+ * Parameters:
+ * [in] *pBitStream
+ * [in] *pOffset
+ * [in] pCodeBook
+ *
+ * [out] *pBitStream
+ * [out] *pOffset
+ *
+ * Returns : Code Book Index if successfull.
+ * : ARM_NO_CODEBOOK_INDEX = -1 if search fails.
+ **/
+#ifndef C_OPTIMIZED_IMPLEMENTATION
+
+OMX_U16 armUnPackVLC32(
+ const OMX_U8 **ppBitStream,
+ OMX_INT *pOffset,
+ const ARM_VLC32 *pCodeBook
+)
+{
+ const OMX_U8 *pBitStream = *ppBitStream;
+ OMX_INT Offset = *pOffset;
+ OMX_U32 Value;
+ OMX_INT Index;
+
+ armAssert(Offset>=0 && Offset<=7);
+
+ /* Read next 32 bits from stream */
+ Value = (pBitStream[0] << 24 ) | ( pBitStream[1] << 16) | (pBitStream[2] << 8 ) | (pBitStream[3]) ;
+ Value = (Value << Offset ) | (pBitStream[4] >> (8-Offset));
+
+ /* Search through the codebook */
+ for (Index=0; pCodeBook->codeLen != 0; Index++)
+ {
+ if (pCodeBook->codeWord == (Value >> (32 - pCodeBook->codeLen)))
+ {
+ Offset = Offset + pCodeBook->codeLen;
+ *ppBitStream = pBitStream + (Offset >> 3) ;
+ *pOffset = Offset & 7;
+
+ return Index;
+ }
+ pCodeBook++;
+ }
+
+ /* No code match found */
+ return ARM_NO_CODEBOOK_INDEX;
+}
+
+#endif
+
+/***************************************
+ * Fixed bit length Encode
+ ***************************************/
+
+/**
+ * Function: armPackBits
+ *
+ * Description:
+ * Pack a VLC code word into the bitstream
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream pointer to the pointer to the current byte
+ * in the bit stream.
+ * [in] pOffset pointer to the bit position in the byte
+ * pointed by *ppBitStream. Valid within 0
+ * to 7.
+ * [in] codeWord Code word that need to be inserted in to the
+ * bitstream
+ * [in] codeLength Length of the code word valid range 1...32
+ *
+ * [out] ppBitStream *ppBitStream is updated after the block is encoded,
+ * so that it points to the current byte in the bit
+ * stream buffer.
+ * [out] pBitOffset *pBitOffset is updated so that it points to the
+ * current bit position in the byte pointed by
+ * *ppBitStream.
+ *
+ * Return Value:
+ * Standard OMX_RESULT result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armPackBits (
+ OMX_U8 **ppBitStream,
+ OMX_INT *pOffset,
+ OMX_U32 codeWord,
+ OMX_INT codeLength
+)
+{
+ OMX_U8 *pBitStream = *ppBitStream;
+ OMX_INT Offset = *pOffset;
+ OMX_U32 Value;
+
+ /* checking argument validity */
+ armRetArgErrIf(Offset < 0, OMX_Sts_BadArgErr);
+ armRetArgErrIf(Offset > 7, OMX_Sts_BadArgErr);
+ armRetArgErrIf(codeLength < 1, OMX_Sts_BadArgErr);
+ armRetArgErrIf(codeLength > 32, OMX_Sts_BadArgErr);
+
+ /* Prepare the first byte */
+ codeWord = codeWord << (32-codeLength);
+ Value = (pBitStream[0] >> (8-Offset)) << (8-Offset);
+ Value = Value | (codeWord >> (24+Offset));
+
+ /* Write out whole bytes */
+ while (8-Offset <= codeLength)
+ {
+ *pBitStream++ = (OMX_U8)Value;
+ codeWord = codeWord << (8-Offset);
+ codeLength = codeLength - (8-Offset);
+ Offset = 0;
+ Value = codeWord >> 24;
+ }
+
+ /* Write out final partial byte */
+ *pBitStream = (OMX_U8)Value;
+ *ppBitStream = pBitStream;
+ *pOffset = Offset + codeLength;
+
+ return OMX_Sts_NoErr;
+}
+
+/***************************************
+ * Variable bit length Encode
+ ***************************************/
+
+/**
+ * Function: armPackVLC32
+ *
+ * Description:
+ * Pack a VLC code word into the bitstream
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream pointer to the pointer to the current byte
+ * in the bit stream.
+ * [in] pBitOffset pointer to the bit position in the byte
+ * pointed by *ppBitStream. Valid within 0
+ * to 7.
+ * [in] code VLC code word that need to be inserted in to the
+ * bitstream
+ *
+ * [out] ppBitStream *ppBitStream is updated after the block is encoded,
+ * so that it points to the current byte in the bit
+ * stream buffer.
+ * [out] pBitOffset *pBitOffset is updated so that it points to the
+ * current bit position in the byte pointed by
+ * *ppBitStream.
+ *
+ * Return Value:
+ * Standard OMX_RESULT result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armPackVLC32 (
+ OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ ARM_VLC32 code
+)
+{
+ return (armPackBits(ppBitStream, pBitOffset, code.codeWord, code.codeLen));
+}
+
+/*End of File*/
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/src/armCOMM_IDCTTable.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/src/armCOMM_IDCTTable.c
new file mode 100644
index 0000000..9e4679c
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/src/armCOMM_IDCTTable.c
@@ -0,0 +1,60 @@
+/**
+ *
+ * File Name: armCOMM_IDCTTable.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * File: armCOMM_IDCTTable.c
+ * Brief: Defines Tables used in IDCT computation
+ *
+ */
+
+#include "armCOMM_IDCTTable.h"
+
+ /* Table of s(u)*A(u)*A(v)/16 at Q15
+ * s(u)=1.0 0 <= u <= 5
+ * s(6)=2.0
+ * s(7)=4.0
+ * A(0) = 2*sqrt(2)
+ * A(u) = 4*cos(u*pi/16) for (u!=0)
+ */
+
+__align(4) const OMX_U16 armCOMM_IDCTPreScale [64] =
+{
+ 0x4000, 0x58c5, 0x539f, 0x4b42, 0x4000, 0x3249, 0x4546, 0x46a1,
+ 0x58c5, 0x7b21, 0x73fc, 0x6862, 0x58c5, 0x45bf, 0x6016, 0x61f8,
+ 0x539f, 0x73fc, 0x6d41, 0x6254, 0x539f, 0x41b3, 0x5a82, 0x5c48,
+ 0x4b42, 0x6862, 0x6254, 0x587e, 0x4b42, 0x3b21, 0x5175, 0x530d,
+ 0x4000, 0x58c5, 0x539f, 0x4b42, 0x4000, 0x3249, 0x4546, 0x46a1,
+ 0x3249, 0x45bf, 0x41b3, 0x3b21, 0x3249, 0x2782, 0x366d, 0x377e,
+ 0x22a3, 0x300b, 0x2d41, 0x28ba, 0x22a3, 0x1b37, 0x257e, 0x263a,
+ 0x11a8, 0x187e, 0x1712, 0x14c3, 0x11a8, 0x0de0, 0x131d, 0x137d
+};
+ /* Above array armCOMM_IDCTPreScale, in Q23 format */
+const OMX_U32 armCOMM_IDCTPreScaleU32 [64] =
+{
+ 0x400000, 0x58c543, 0x539eba, 0x4b418c, 0x400000, 0x3248d4, 0x4545ea, 0x46a157,
+ 0x58c543, 0x7b20d8, 0x73fbfc, 0x686214, 0x58c543, 0x45bf1f, 0x6015a5, 0x61f78b,
+ 0x539eba, 0x73fbfc, 0x6d413d, 0x6253a6, 0x539eba, 0x41b328, 0x5a827a, 0x5c4869,
+ 0x4b418c, 0x686214, 0x6253a6, 0x587de3, 0x4b418c, 0x3b20d8, 0x5174e0, 0x530d69,
+ 0x400000, 0x58c543, 0x539eba, 0x4b418c, 0x400000, 0x3248d4, 0x4545ea, 0x46a157,
+ 0x3248d4, 0x45bf1f, 0x41b328, 0x3b20d8, 0x3248d4, 0x27821d, 0x366d72, 0x377e6b,
+ 0x22a2f5, 0x300ad3, 0x2d413d, 0x28ba70, 0x22a2f5, 0x1b36b9, 0x257d86, 0x26398d,
+ 0x11a856, 0x187de3, 0x17121a, 0x14c35a, 0x11a856, 0x0ddf9b, 0x131cc7, 0x137ca2
+};
+
+const OMX_U16 armCOMM_IDCTCoef [4] =
+{
+ 0x5a82, /* InvSqrt2 */
+ 0x30fc, /* SinPIBy8 */
+ 0x7642, /* CosPIBy8 */
+ 0x0000
+};
+
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/src/armCOMM_MaskTable.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/src/armCOMM_MaskTable.c
new file mode 100644
index 0000000..3241db2
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/src/armCOMM_MaskTable.c
@@ -0,0 +1,45 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: armCOMM_MaskTable.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Mask Table to mask the end of array.
+ *
+ */
+
+#include "omxtypes.h"
+
+#define MaskTableSize 72
+
+const OMX_U16 armCOMM_qMaskTable16[MaskTableSize] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000,
+ 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000,
+ 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000,
+ 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF
+};
+
+const OMX_U8 armCOMM_qMaskTable8[MaskTableSize] =
+{
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/api/armVC.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/api/armVC.h
new file mode 100644
index 0000000..7fa7716
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/api/armVC.h
@@ -0,0 +1,1153 @@
+/**
+ *
+ * File Name: armVC.h
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * File: armVideo.h
+ * Brief: Declares API's/Basic Data types used across the OpenMAX Video domain
+ *
+ */
+
+
+#ifndef _armVideo_H_
+#define _armVideo_H_
+
+#include "omxVC.h"
+#include "armCOMM_Bitstream.h"
+
+/**
+ * ARM specific state structure to hold Motion Estimation information.
+ */
+
+struct m4p2_MESpec
+{
+ OMXVCM4P2MEParams MEParams;
+ OMXVCM4P2MEMode MEMode;
+};
+
+struct m4p10_MESpec
+{
+ OMXVCM4P10MEParams MEParams;
+ OMXVCM4P10MEMode MEMode;
+};
+
+typedef struct m4p2_MESpec ARMVCM4P2_MESpec;
+typedef struct m4p10_MESpec ARMVCM4P10_MESpec;
+
+/**
+ * Function: armVCM4P2_CompareMV
+ *
+ * Description:
+ * Performs comparision of motion vectors and SAD's to decide the
+ * best MV and SAD
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] mvX x coordinate of the candidate motion vector
+ * [in] mvY y coordinate of the candidate motion vector
+ * [in] candSAD Candidate SAD
+ * [in] bestMVX x coordinate of the best motion vector
+ * [in] bestMVY y coordinate of the best motion vector
+ * [in] bestSAD best SAD
+ *
+ * Return Value:
+ * OMX_INT -- 1 to indicate that the current sad is the best
+ * 0 to indicate that it is NOT the best SAD
+ */
+
+OMX_INT armVCM4P2_CompareMV (
+ OMX_S16 mvX,
+ OMX_S16 mvY,
+ OMX_INT candSAD,
+ OMX_S16 bestMVX,
+ OMX_S16 bestMVY,
+ OMX_INT bestSAD);
+
+/**
+ * Function: armVCM4P2_ACDCPredict
+ *
+ * Description:
+ * Performs adaptive DC/AC coefficient prediction for an intra block. Prior
+ * to the function call, prediction direction (predDir) should be selected
+ * as specified in subclause 7.4.3.1 of ISO/IEC 14496-2.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] pSrcDst pointer to the coefficient buffer which contains
+ * the quantized coefficient residuals (PQF) of the
+ * current block
+ * [in] pPredBufRow pointer to the coefficient row buffer
+ * [in] pPredBufCol pointer to the coefficient column buffer
+ * [in] curQP quantization parameter of the current block. curQP
+ * may equal to predQP especially when the current
+ * block and the predictor block are in the same
+ * macroblock.
+ * [in] predQP quantization parameter of the predictor block
+ * [in] predDir indicates the prediction direction which takes one
+ * of the following values:
+ * OMX_VIDEO_HORIZONTAL predict horizontally
+ * OMX_VIDEO_VERTICAL predict vertically
+ * [in] ACPredFlag a flag indicating if AC prediction should be
+ * performed. It is equal to ac_pred_flag in the bit
+ * stream syntax of MPEG-4
+ * [in] videoComp video component type (luminance, chrominance or
+ * alpha) of the current block
+ * [in] flag This flag defines the if one wants to use this functions to
+ * calculate PQF (set 1, prediction) or QF (set 0, reconstruction)
+ * [out] pPreACPredict pointer to the predicted coefficients buffer.
+ * Filled ONLY if it is not NULL
+ * [out] pSrcDst pointer to the coefficient buffer which contains
+ * the quantized coefficients (QF) of the current
+ * block
+ * [out] pPredBufRow pointer to the updated coefficient row buffer
+ * [out] pPredBufCol pointer to the updated coefficient column buffer
+ * [out] pSumErr pointer to the updated sum of the difference
+ * between predicted and unpredicted coefficients
+ * If this is NULL, do not update
+ *
+ * Return Value:
+ * Standard OMXResult result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armVCM4P2_ACDCPredict(
+ OMX_S16 * pSrcDst,
+ OMX_S16 * pPreACPredict,
+ OMX_S16 * pPredBufRow,
+ OMX_S16 * pPredBufCol,
+ OMX_INT curQP,
+ OMX_INT predQP,
+ OMX_INT predDir,
+ OMX_INT ACPredFlag,
+ OMXVCM4P2VideoComponent videoComp,
+ OMX_U8 flag,
+ OMX_INT *pSumErr
+);
+
+/**
+ * Function: armVCM4P2_SetPredDir
+ *
+ * Description:
+ * Performs detecting the prediction direction
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] blockIndex block index indicating the component type and
+ * position as defined in subclause 6.1.3.8, of ISO/IEC
+ * 14496-2. Furthermore, indexes 6 to 9 indicate the
+ * alpha blocks spatially corresponding to luminance
+ * blocks 0 to 3 in the same macroblock.
+ * [in] pCoefBufRow pointer to the coefficient row buffer
+ * [in] pQpBuf pointer to the quantization parameter buffer
+ * [out] predQP quantization parameter of the predictor block
+ * [out] predDir indicates the prediction direction which takes one
+ * of the following values:
+ * OMX_VIDEO_HORIZONTAL predict horizontally
+ * OMX_VIDEO_VERTICAL predict vertically
+ *
+ * Return Value:
+ * Standard OMXResult result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armVCM4P2_SetPredDir(
+ OMX_INT blockIndex,
+ OMX_S16 *pCoefBufRow,
+ OMX_S16 *pCoefBufCol,
+ OMX_INT *predDir,
+ OMX_INT *predQP,
+ const OMX_U8 *pQpBuf
+);
+
+/**
+ * Function: armVCM4P2_EncodeVLCZigzag_Intra
+ *
+ * Description:
+ * Performs zigzag scanning and VLC encoding for one intra block.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream pointer to the pointer to the current byte in
+ * the bit stream
+ * [in] pBitOffset pointer to the bit position in the byte pointed
+ * by *ppBitStream. Valid within 0 to 7.
+ * [in] pQDctBlkCoef pointer to the quantized DCT coefficient
+ * [in] predDir AC prediction direction, which is used to decide
+ * the zigzag scan pattern. This takes one of the
+ * following values:
+ * OMX_VIDEO_NONE AC prediction not used.
+ * Performs classical zigzag
+ * scan.
+ * OMX_VIDEO_HORIZONTAL Horizontal prediction.
+ * Performs alternate-vertical
+ * zigzag scan.
+ * OMX_VIDEO_VERTICAL Vertical prediction.
+ * Performs alternate-horizontal
+ * zigzag scan.
+ * [in] pattern block pattern which is used to decide whether
+ * this block is encoded
+ * [in] start start indicates whether the encoding begins with 0th element
+ * or 1st.
+ * [out] ppBitStream *ppBitStream is updated after the block is encoded,
+ * so that it points to the current byte in the bit
+ * stream buffer.
+ * [out] pBitOffset *pBitOffset is updated so that it points to the
+ * current bit position in the byte pointed by
+ * *ppBitStream.
+ *
+ * Return Value:
+ * Standard OMXResult result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armVCM4P2_EncodeVLCZigzag_Intra(
+ OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ const OMX_S16 *pQDctBlkCoef,
+ OMX_U8 predDir,
+ OMX_U8 pattern,
+ OMX_INT shortVideoHeader,
+ OMX_U8 start
+);
+
+/**
+ * Function: armVCM4P2_DecodeVLCZigzag_Intra
+ *
+ * Description:
+ * Performs VLC decoding and inverse zigzag scan for one intra coded block.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream pointer to the pointer to the current byte in
+ * the bitstream buffer
+ * [in] pBitOffset pointer to the bit position in the byte pointed
+ * to by *ppBitStream. *pBitOffset is valid within
+ * [0-7].
+ * [in] predDir AC prediction direction which is used to decide
+ * the zigzag scan pattern. It takes one of the
+ * following values:
+ * OMX_VIDEO_NONE AC prediction not used;
+ * perform classical zigzag scan;
+ * OMX_VIDEO_HORIZONTAL Horizontal prediction;
+ * perform alternate-vertical
+ * zigzag scan;
+ * OMX_VIDEO_VERTICAL Vertical prediction;
+ * thus perform
+ * alternate-horizontal
+ * zigzag scan.
+ * [in] videoComp video component type (luminance, chrominance or
+ * alpha) of the current block
+ * [in] shortVideoHeader binary flag indicating presence of short_video_header; escape modes 0-3 are used if shortVideoHeader==0,
+ * and escape mode 4 is used when shortVideoHeader==1.
+ * [in] start start indicates whether the encoding begins with 0th element
+ * or 1st.
+ * [out] ppBitStream *ppBitStream is updated after the block is
+ * decoded, so that it points to the current byte
+ * in the bit stream buffer
+ * [out] pBitOffset *pBitOffset is updated so that it points to the
+ * current bit position in the byte pointed by
+ * *ppBitStream
+ * [out] pDst pointer to the coefficient buffer of current
+ * block. Should be 32-bit aligned
+ *
+ * Return Value:
+ * Standard OMXResult result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armVCM4P2_DecodeVLCZigzag_Intra(
+ const OMX_U8 ** ppBitStream,
+ OMX_INT * pBitOffset,
+ OMX_S16 * pDst,
+ OMX_U8 predDir,
+ OMX_INT shortVideoHeader,
+ OMX_U8 start
+);
+
+/**
+ * Function: armVCM4P2_FillVLDBuffer
+ *
+ * Description:
+ * Performs filling of the coefficient buffer according to the run, level
+ * and sign, also updates the index
+ *
+ * Parameters:
+ * [in] storeRun Stored Run value (count of zeros)
+ * [in] storeLevel Stored Level value (non-zero value)
+ * [in] sign Flag indicating the sign of level
+ * [in] last status of the last flag
+ * [in] pIndex pointer to coefficient index in 8x8 matrix
+ * [out] pIndex pointer to updated coefficient index in 8x8
+ * matrix
+ * [in] pZigzagTable pointer to the zigzag tables
+ * [out] pDst pointer to the coefficient buffer of current
+ * block. Should be 32-bit aligned
+ * Return Value:
+ * Standard OMXResult result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armVCM4P2_FillVLDBuffer(
+ OMX_U32 storeRun,
+ OMX_S16 * pDst,
+ OMX_S16 storeLevel,
+ OMX_U8 sign,
+ OMX_U8 last,
+ OMX_U8 * index,
+ const OMX_U8 * pZigzagTable
+);
+
+/**
+ * Function: armVCM4P2_GetVLCBits
+ *
+ * Description:
+ * Performs escape mode decision based on the run, run+, level, level+ and
+ * last combinations.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream pointer to the pointer to the current byte in
+ * the bit stream
+ * [in] pBitOffset pointer to the bit position in the byte pointed
+ * by *ppBitStream. Valid within 0 to 7
+ * [in] shortVideoHeader binary flag indicating presence of short_video_header; escape modes 0-3 are used if shortVideoHeader==0,
+ * and escape mode 4 is used when shortVideoHeader==1.
+ * [in] start start indicates whether the encoding begins with
+ * 0th element or 1st.
+ * [in/out] pLast pointer to last status flag
+ * [in] runBeginSingleLevelEntriesL0 The run value from which level
+ * will be equal to 1: last == 0
+ * [in] IndexBeginSingleLevelEntriesL0 Array index in the VLC table
+ * pointing to the
+ * runBeginSingleLevelEntriesL0
+ * [in] runBeginSingleLevelEntriesL1 The run value from which level
+ * will be equal to 1: last == 1
+ * [in] IndexBeginSingleLevelEntriesL1 Array index in the VLC table
+ * pointing to the
+ * runBeginSingleLevelEntriesL0
+ * [in] pRunIndexTableL0 Run Index table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 0
+ * [in] pVlcTableL0 VLC table for last == 0
+ * [in] pRunIndexTableL1 Run Index table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 1
+ * [in] pVlcTableL1 VLC table for last == 1
+ * [in] pLMAXTableL0 Level MAX table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 0
+ * [in] pLMAXTableL1 Level MAX table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 1
+ * [in] pRMAXTableL0 Run MAX table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 0
+ * [in] pRMAXTableL1 Run MAX table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 1
+ * [out]pDst pointer to the coefficient buffer of current
+ * block. Should be 32-bit aligned
+ *
+ * Return Value:
+ * Standard OMXResult result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armVCM4P2_GetVLCBits (
+ const OMX_U8 **ppBitStream,
+ OMX_INT * pBitOffset,
+ OMX_S16 * pDst,
+ OMX_INT shortVideoHeader,
+ OMX_U8 start,
+ OMX_U8 * pLast,
+ OMX_U8 runBeginSingleLevelEntriesL0,
+ OMX_U8 maxIndexForMultipleEntriesL0,
+ OMX_U8 maxRunForMultipleEntriesL1,
+ OMX_U8 maxIndexForMultipleEntriesL1,
+ const OMX_U8 * pRunIndexTableL0,
+ const ARM_VLC32 *pVlcTableL0,
+ const OMX_U8 * pRunIndexTableL1,
+ const ARM_VLC32 *pVlcTableL1,
+ const OMX_U8 * pLMAXTableL0,
+ const OMX_U8 * pLMAXTableL1,
+ const OMX_U8 * pRMAXTableL0,
+ const OMX_U8 * pRMAXTableL1,
+ const OMX_U8 * pZigzagTable
+);
+
+/**
+ * Function: armVCM4P2_PutVLCBits
+ *
+ * Description:
+ * Checks the type of Escape Mode and put encoded bits for
+ * quantized DCT coefficients.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream pointer to the pointer to the current byte in
+ * the bit stream
+ * [in] pBitOffset pointer to the bit position in the byte pointed
+ * by *ppBitStream. Valid within 0 to 7
+ * [in] shortVideoHeader binary flag indicating presence of short_video_header; escape modes 0-3 are used if shortVideoHeader==0,
+ * and escape mode 4 is used when shortVideoHeader==1.
+ * [in] start start indicates whether the encoding begins with
+ * 0th element or 1st.
+ * [in] maxStoreRunL0 Max store possible (considering last and inter/intra)
+ * for last = 0
+ * [in] maxStoreRunL1 Max store possible (considering last and inter/intra)
+ * for last = 1
+ * [in] maxRunForMultipleEntriesL0
+ * The run value after which level
+ * will be equal to 1:
+ * (considering last and inter/intra status) for last = 0
+ * [in] maxRunForMultipleEntriesL1
+ * The run value after which level
+ * will be equal to 1:
+ * (considering last and inter/intra status) for last = 1
+ * [in] pRunIndexTableL0 Run Index table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 0
+ * [in] pVlcTableL0 VLC table for last == 0
+ * [in] pRunIndexTableL1 Run Index table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 1
+ * [in] pVlcTableL1 VLC table for last == 1
+ * [in] pLMAXTableL0 Level MAX table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 0
+ * [in] pLMAXTableL1 Level MAX table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 1
+ * [in] pRMAXTableL0 Run MAX table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 0
+ * [in] pRMAXTableL1 Run MAX table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 1
+ * [out] pQDctBlkCoef pointer to the quantized DCT coefficient
+ * [out] ppBitStream *ppBitStream is updated after the block is encoded
+ * so that it points to the current byte in the bit
+ * stream buffer.
+ * [out] pBitOffset *pBitOffset is updated so that it points to the
+ * current bit position in the byte pointed by
+ * *ppBitStream.
+ *
+ * Return Value:
+ * Standard OMXResult result. See enumeration for possible result codes.
+ *
+ */
+
+
+OMXResult armVCM4P2_PutVLCBits (
+ OMX_U8 **ppBitStream,
+ OMX_INT * pBitOffset,
+ const OMX_S16 *pQDctBlkCoef,
+ OMX_INT shortVideoHeader,
+ OMX_U8 start,
+ OMX_U8 maxStoreRunL0,
+ OMX_U8 maxStoreRunL1,
+ OMX_U8 maxRunForMultipleEntriesL0,
+ OMX_U8 maxRunForMultipleEntriesL1,
+ const OMX_U8 * pRunIndexTableL0,
+ const ARM_VLC32 *pVlcTableL0,
+ const OMX_U8 * pRunIndexTableL1,
+ const ARM_VLC32 *pVlcTableL1,
+ const OMX_U8 * pLMAXTableL0,
+ const OMX_U8 * pLMAXTableL1,
+ const OMX_U8 * pRMAXTableL0,
+ const OMX_U8 * pRMAXTableL1,
+ const OMX_U8 * pZigzagTable
+);
+/**
+ * Function: armVCM4P2_FillVLCBuffer
+ *
+ * Description:
+ * Performs calculating the VLC bits depending on the escape type and insert
+ * the same in the bitstream
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream pointer to the pointer to the current byte in
+ * the bit stream
+ * [in] pBitOffset pointer to the bit position in the byte pointed
+ * by *ppBitStream. Valid within 0 to 7
+ * [in] run Run value (count of zeros) to be encoded
+ * [in] level Level value (non-zero value) to be encoded
+ * [in] runPlus Calculated as runPlus = run - (RMAX + 1)
+ * [in] levelPlus Calculated as
+ * levelPlus = sign(level)*[abs(level) - LMAX]
+ * [in] fMode Flag indicating the escape modes
+ * [in] last status of the last flag
+ * [in] maxRunForMultipleEntries
+ * The run value after which level will be equal to 1:
+ * (considering last and inter/intra status)
+ * [in] pRunIndexTable Run Index table defined in
+ * armVCM4P2_Huff_tables_VLC.h
+ * [in] pVlcTable VLC table defined in armVCM4P2_Huff_tables_VLC.h
+ * [out] ppBitStream *ppBitStream is updated after the block is encoded
+ * so that it points to the current byte in the bit
+ * stream buffer.
+ * [out] pBitOffset *pBitOffset is updated so that it points to the
+ * current bit position in the byte pointed by
+ * *ppBitStream.
+ *
+ * Return Value:
+ * Standard OMXResult result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armVCM4P2_FillVLCBuffer (
+ OMX_U8 **ppBitStream,
+ OMX_INT * pBitOffset,
+ OMX_U32 run,
+ OMX_S16 level,
+ OMX_U32 runPlus,
+ OMX_S16 levelPlus,
+ OMX_U8 fMode,
+ OMX_U8 last,
+ OMX_U8 maxRunForMultipleEntries,
+ const OMX_U8 *pRunIndexTable,
+ const ARM_VLC32 *pVlcTable
+);
+
+/**
+ * Function: armVCM4P2_CheckVLCEscapeMode
+ *
+ * Description:
+ * Performs escape mode decision based on the run, run+, level, level+ and
+ * last combinations.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] run Run value (count of zeros) to be encoded
+ * [in] level Level value (non-zero value) to be encoded
+ * [in] runPlus Calculated as runPlus = run - (RMAX + 1)
+ * [in] levelPlus Calculated as
+ * levelPlus = sign(level)*[abs(level) - LMAX]
+ * [in] maxStoreRun Max store possible (considering last and inter/intra)
+ * [in] maxRunForMultipleEntries
+ * The run value after which level
+ * will be equal to 1:
+ * (considering last and inter/intra status)
+ * [in] shortVideoHeader binary flag indicating presence of short_video_header; escape modes 0-3 are used if shortVideoHeader==0,
+ * and escape mode 4 is used when shortVideoHeader==1.
+ * [in] pRunIndexTable Run Index table defined in
+ * armVCM4P2_Huff_Tables_VLC.c
+ * (considering last and inter/intra status)
+ *
+ *
+ * Return Value:
+ * Returns an Escape mode which can take values from 0 to 3
+ * 0 --> no escape mode, 1 --> escape type 1,
+ * 1 --> escape type 2, 3 --> escape type 3, check section 7.4.1.3
+ * in the MPEG ISO standard.
+ *
+ */
+
+OMX_U8 armVCM4P2_CheckVLCEscapeMode(
+ OMX_U32 run,
+ OMX_U32 runPlus,
+ OMX_S16 level,
+ OMX_S16 levelPlus,
+ OMX_U8 maxStoreRun,
+ OMX_U8 maxRunForMultipleEntries,
+ OMX_INT shortVideoHeader,
+ const OMX_U8 *pRunIndexTable
+);
+
+
+/**
+ * Function: armVCM4P2_BlockMatch_Integer
+ *
+ * Description:
+ * Performs a 16x16 block search; estimates motion vector and associated minimum SAD.
+ * Both the input and output motion vectors are represented using half-pixel units, and
+ * therefore a shift left or right by 1 bit may be required, respectively, to match the
+ * input or output MVs with other functions that either generate output MVs or expect
+ * input MVs represented using integer pixel units.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] pSrcRefBuf pointer to the reference Y plane; points to the reference MB that
+ * corresponds to the location of the current macroblock in the current
+ * plane.
+ * [in] refWidth width of the reference plane
+ * [in] pRefRect pointer to the valid rectangular in reference plane. Relative to image origin.
+ * It's not limited to the image boundary, but depended on the padding. For example,
+ * if you pad 4 pixels outside the image border, then the value for left border
+ * can be -4
+ * [in] pSrcCurrBuf pointer to the current macroblock extracted from original plane (linear array,
+ * 256 entries); must be aligned on an 8-byte boundary.
+ * [in] pCurrPointPos position of the current macroblock in the current plane
+ * [in] pSrcPreMV pointer to predicted motion vector; NULL indicates no predicted MV
+ * [in] pSrcPreSAD pointer to SAD associated with the predicted MV (referenced by pSrcPreMV)
+ * [in] searchRange search range for 16X16 integer block,the units of it is full pixel,the search range
+ * is the same in all directions.It is in inclusive of the boundary and specified in
+ * terms of integer pixel units.
+ * [in] pMESpec vendor-specific motion estimation specification structure; must have been allocated
+ * and then initialized using omxVCM4P2_MEInit prior to calling the block matching
+ * function.
+ * [in] BlockSize MacroBlock Size i.e either 16x16 or 8x8.
+ * [out] pDstMV pointer to estimated MV
+ * [out] pDstSAD pointer to minimum SAD
+ *
+ * Return Value:
+ * OMX_Sts_NoErr ¨C no error.
+ * OMX_Sts_BadArgErr ¨C bad arguments
+ *
+ */
+
+OMXResult armVCM4P2_BlockMatch_Integer(
+ const OMX_U8 *pSrcRefBuf,
+ OMX_INT refWidth,
+ const OMXRect *pRefRect,
+ const OMX_U8 *pSrcCurrBuf,
+ const OMXVCM4P2Coordinate *pCurrPointPos,
+ const OMXVCMotionVector *pSrcPreMV,
+ const OMX_INT *pSrcPreSAD,
+ void *pMESpec,
+ OMXVCMotionVector *pDstMV,
+ OMX_INT *pDstSAD,
+ OMX_U8 BlockSize
+);
+
+/**
+ * Function: armVCM4P2_BlockMatch_Half
+ *
+ * Description:
+ * Performs a 16x16 block match with half-pixel resolution. Returns the estimated
+ * motion vector and associated minimum SAD. This function estimates the half-pixel
+ * motion vector by interpolating the integer resolution motion vector referenced
+ * by the input parameter pSrcDstMV, i.e., the initial integer MV is generated
+ * externally. The input parameters pSrcRefBuf and pSearchPointRefPos should be
+ * shifted by the winning MV of 16x16 integer search prior to calling BlockMatch_Half_16x16.
+ * The function BlockMatch_Integer_16x16 may be used for integer motion estimation.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] pSrcRefBuf pointer to the reference Y plane; points to the reference MB
+ * that corresponds to the location of the current macroblock in
+ * the current plane.
+ * [in] refWidth width of the reference plane
+ * [in] pRefRect reference plane valid region rectangle
+ * [in] pSrcCurrBuf pointer to the current macroblock extracted from original plane
+ * (linear array, 256 entries); must be aligned on an 8-byte boundary.
+ * [in] pSearchPointRefPos position of the starting point for half pixel search (specified
+ * in terms of integer pixel units) in the reference plane.
+ * [in] rndVal rounding control bit for half pixel motion estimation;
+ * 0=rounding control disabled; 1=rounding control enabled
+ * [in] pSrcDstMV pointer to the initial MV estimate; typically generated during a prior
+ * 16X16 integer search and its unit is half pixel.
+ * [in] BlockSize MacroBlock Size i.e either 16x16 or 8x8.
+ * [out]pSrcDstMV pointer to estimated MV
+ * [out]pDstSAD pointer to minimum SAD
+ *
+ * Return Value:
+ * OMX_Sts_NoErr ¨C no error
+ * OMX_Sts_BadArgErr ¨C bad arguments
+ *
+ */
+
+OMXResult armVCM4P2_BlockMatch_Half(
+ const OMX_U8 *pSrcRefBuf,
+ OMX_INT refWidth,
+ const OMXRect *pRefRect,
+ const OMX_U8 *pSrcCurrBuf,
+ const OMXVCM4P2Coordinate *pSearchPointRefPos,
+ OMX_INT rndVal,
+ OMXVCMotionVector *pSrcDstMV,
+ OMX_INT *pDstSAD,
+ OMX_U8 BlockSize
+);
+/**
+ * Function: armVCM4P2_PadMV
+ *
+ * Description:
+ * Performs motion vector padding for a macroblock.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] pSrcDstMV pointer to motion vector buffer of the current
+ * macroblock
+ * [in] pTransp pointer to transparent status buffer of the
+ * current macroblock
+ * [out] pSrcDstMV pointer to motion vector buffer in which the
+ * motion vectors have been padded
+ * Return Value:
+ * Standard OMXResult result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armVCM4P2_PadMV(
+ OMXVCMotionVector * pSrcDstMV,
+ OMX_U8 * pTransp
+);
+
+/*
+ * H.264 Specific Declarations
+ */
+/* Defines */
+#define ARM_M4P10_Q_OFFSET (15)
+
+
+/* Dequant tables */
+
+extern const OMX_U8 armVCM4P10_PosToVCol4x4[16];
+extern const OMX_U8 armVCM4P10_PosToVCol2x2[4];
+extern const OMX_U8 armVCM4P10_VMatrix[6][3];
+extern const OMX_U32 armVCM4P10_MFMatrix[6][3];
+
+
+/*
+ * Description:
+ * This function perform the work required by the OpenMAX
+ * DecodeCoeffsToPair function and DecodeChromaDCCoeffsToPair.
+ * Since most of the code is common we share it here.
+ *
+ * Parameters:
+ * [in] ppBitStream Double pointer to current byte in bit stream buffer
+ * [in] pOffset Pointer to current bit position in the byte pointed
+ * to by *ppBitStream
+ * [in] sMaxNumCoeff Maximum number of non-zero coefficients in current
+ * block (4,15 or 16)
+ * [in] nTable Table number (0 to 4) according to the five columns
+ * of Table 9-5 in the H.264 spec
+ * [out] ppBitStream *ppBitStream is updated after each block is decoded
+ * [out] pOffset *pOffset is updated after each block is decoded
+ * [out] pNumCoeff Pointer to the number of nonzero coefficients in
+ * this block
+ * [out] ppPosCoefbuf Double pointer to destination residual
+ * coefficient-position pair buffer
+ * Return Value:
+ * Standard omxError result. See enumeration for possible result codes.
+
+ */
+
+OMXResult armVCM4P10_DecodeCoeffsToPair(
+ const OMX_U8** ppBitStream,
+ OMX_S32* pOffset,
+ OMX_U8* pNumCoeff,
+ OMX_U8**ppPosCoefbuf,
+ OMX_INT nTable,
+ OMX_INT sMaxNumCoeff
+ );
+
+/*
+ * Description:
+ * Perform DC style intra prediction, averaging upper and left block
+ *
+ * Parameters:
+ * [in] pSrcLeft Pointer to the buffer of 16 left coefficients:
+ * p[x, y] (x = -1, y = 0..3)
+ * [in] pSrcAbove Pointer to the buffer of 16 above coefficients:
+ * p[x,y] (x = 0..3, y = -1)
+ * [in] leftStep Step of left coefficient buffer
+ * [in] dstStep Step of the destination buffer
+ * [in] availability Neighboring 16x16 MB availability flag
+ * [out] pDst Pointer to the destination buffer
+ *
+ * Return Value:
+ * None
+ */
+
+void armVCM4P10_PredictIntraDC4x4(
+ const OMX_U8* pSrcLeft,
+ const OMX_U8 *pSrcAbove,
+ OMX_U8* pDst,
+ OMX_INT leftStep,
+ OMX_INT dstStep,
+ OMX_S32 availability
+);
+
+/*
+ * Description
+ * Unpack a 4x4 block of coefficient-residual pair values
+ *
+ * Parameters:
+ * [in] ppSrc Double pointer to residual coefficient-position pair
+ * buffer output by CALVC decoding
+ * [out] ppSrc *ppSrc is updated to the start of next non empty block
+ * [out] pDst Pointer to unpacked 4x4 block
+ */
+
+void armVCM4P10_UnpackBlock4x4(
+ const OMX_U8 **ppSrc,
+ OMX_S16* pDst
+);
+
+/*
+ * Description
+ * Unpack a 2x2 block of coefficient-residual pair values
+ *
+ * Parameters:
+ * [in] ppSrc Double pointer to residual coefficient-position pair
+ * buffer output by CALVC decoding
+ * [out] ppSrc *ppSrc is updated to the start of next non empty block
+ * [out] pDst Pointer to unpacked 4x4 block
+ */
+
+void armVCM4P10_UnpackBlock2x2(
+ const OMX_U8 **ppSrc,
+ OMX_S16* pDst
+);
+
+/*
+ * Description
+ * Deblock one boundary pixel
+ *
+ * Parameters:
+ * [in] pQ0 Pointer to pixel q0
+ * [in] Step Step between pixels q0 and q1
+ * [in] tC0 Edge threshold value
+ * [in] alpha alpha threshold value
+ * [in] beta beta threshold value
+ * [in] bS deblocking strength
+ * [in] ChromaFlag True for chroma blocks
+ * [out] pQ0 Deblocked pixels
+ *
+ */
+
+void armVCM4P10_DeBlockPixel(
+ OMX_U8 *pQ0, /* pointer to the pixel q0 */
+ int Step, /* step between pixels q0 and q1 */
+ int tC0, /* edge threshold value */
+ int alpha, /* alpha */
+ int beta, /* beta */
+ int bS, /* deblocking strength */
+ int ChromaFlag
+);
+
+/**
+ * Function: armVCM4P10_InterpolateHalfHor_Luma
+ *
+ * Description:
+ * This function performs interpolation for horizontal 1/2-pel positions
+ *
+ * Remarks:
+ *
+ * [in] pSrc Pointer to top-left corner of block used to interpolate
+ in the reconstructed frame plane
+ * [in] iSrcStep Step of the source buffer.
+ * [in] iDstStep Step of the destination(interpolation) buffer.
+ * [in] iWidth Width of the current block
+ * [in] iHeight Height of the current block
+ * [out] pDst Pointer to the interpolation buffer of the 1/2-pel
+ *
+ * Return Value:
+ * Standard OMXResult value.
+ *
+ */
+
+OMXResult armVCM4P10_InterpolateHalfHor_Luma(
+ const OMX_U8* pSrc,
+ OMX_U32 iSrcStep,
+ OMX_U8* pDst,
+ OMX_U32 iDstStep,
+ OMX_U32 iWidth,
+ OMX_U32 iHeight
+);
+
+/**
+ * Function: armVCM4P10_InterpolateHalfVer_Luma
+ *
+ * Description:
+ * This function performs interpolation for vertical 1/2-pel positions
+ * around a full-pel position.
+ *
+ * Remarks:
+ *
+ * [in] pSrc Pointer to top-left corner of block used to interpolate
+ * in the reconstructed frame plane
+ * [in] iSrcStep Step of the source buffer.
+ * [in] iDstStep Step of the destination(interpolation) buffer.
+ * [in] iWidth Width of the current block
+ * [in] iHeight Height of the current block
+ * [out] pDst Pointer to the interpolation buffer of the 1/2-pel
+ *
+ * Return Value:
+ * Standard OMXResult value.
+ *
+ */
+
+OMXResult armVCM4P10_InterpolateHalfVer_Luma(
+ const OMX_U8* pSrc,
+ OMX_U32 iSrcStep,
+ OMX_U8* pDst,
+ OMX_U32 iDstStep,
+ OMX_U32 iWidth,
+ OMX_U32 iHeight
+);
+
+/**
+ * Function: armVCM4P10_InterpolateHalfDiag_Luma
+ *
+ * Description:
+ * This function performs interpolation for (1/2, 1/2) positions
+ * around a full-pel position.
+ *
+ * Remarks:
+ *
+ * [in] pSrc Pointer to top-left corner of block used to interpolate
+ * in the reconstructed frame plane
+ * [in] iSrcStep Step of the source buffer.
+ * [in] iDstStep Step of the destination(interpolation) buffer.
+ * [in] iWidth Width of the current block
+ * [in] iHeight Height of the current block
+ * [out] pDst Pointer to the interpolation buffer of the (1/2,1/2)-pel
+ *
+ * Return Value:
+ * Standard OMXResult value.
+ *
+ */
+
+OMXResult armVCM4P10_InterpolateHalfDiag_Luma(
+ const OMX_U8* pSrc,
+ OMX_U32 iSrcStep,
+ OMX_U8* pDst,
+ OMX_U32 iDstStep,
+ OMX_U32 iWidth,
+ OMX_U32 iHeight
+);
+
+/*
+ * Description:
+ * Transform Residual 4x4 Coefficients
+ *
+ * Parameters:
+ * [in] pSrc Source 4x4 block
+ * [out] pDst Destination 4x4 block
+ *
+ */
+
+void armVCM4P10_TransformResidual4x4(OMX_S16* pDst, OMX_S16 *pSrc);
+
+/*
+ * Description:
+ * Forward Transform Residual 4x4 Coefficients
+ *
+ * Parameters:
+ * [in] pSrc Source 4x4 block
+ * [out] pDst Destination 4x4 block
+ *
+ */
+
+void armVCM4P10_FwdTransformResidual4x4(OMX_S16* pDst, OMX_S16 *pSrc);
+
+OMX_INT armVCM4P10_CompareMotionCostToMV (
+ OMX_S16 mvX,
+ OMX_S16 mvY,
+ OMXVCMotionVector diffMV,
+ OMX_INT candSAD,
+ OMXVCMotionVector *bestMV,
+ OMX_U32 nLamda,
+ OMX_S32 *pBestCost);
+
+/**
+ * Function: armVCCOMM_SAD
+ *
+ * Description:
+ * This function calculate the SAD for NxM blocks.
+ *
+ * Remarks:
+ *
+ * [in] pSrcOrg Pointer to the original block
+ * [in] iStepOrg Step of the original block buffer
+ * [in] pSrcRef Pointer to the reference block
+ * [in] iStepRef Step of the reference block buffer
+ * [in] iHeight Height of the block
+ * [in] iWidth Width of the block
+ * [out] pDstSAD Pointer of result SAD
+ *
+ * Return Value:
+ * Standard OMXResult value.
+ *
+ */
+OMXResult armVCCOMM_SAD(
+ const OMX_U8* pSrcOrg,
+ OMX_U32 iStepOrg,
+ const OMX_U8* pSrcRef,
+ OMX_U32 iStepRef,
+ OMX_S32* pDstSAD,
+ OMX_U32 iHeight,
+ OMX_U32 iWidth);
+
+/**
+ * Function: armVCCOMM_Average
+ *
+ * Description:
+ * This function calculates the average of two blocks and stores the result.
+ *
+ * Remarks:
+ *
+ * [in] pPred0 Pointer to the top-left corner of reference block 0
+ * [in] pPred1 Pointer to the top-left corner of reference block 1
+ * [in] iPredStep0 Step of reference block 0
+ * [in] iPredStep1 Step of reference block 1
+ * [in] iDstStep Step of the destination buffer
+ * [in] iWidth Width of the blocks
+ * [in] iHeight Height of the blocks
+ * [out] pDstPred Pointer to the destination buffer
+ *
+ * Return Value:
+ * Standard OMXResult value.
+ *
+ */
+ OMXResult armVCCOMM_Average (
+ const OMX_U8* pPred0,
+ const OMX_U8* pPred1,
+ OMX_U32 iPredStep0,
+ OMX_U32 iPredStep1,
+ OMX_U8* pDstPred,
+ OMX_U32 iDstStep,
+ OMX_U32 iWidth,
+ OMX_U32 iHeight
+);
+
+/**
+ * Function: armVCM4P10_SADQuar
+ *
+ * Description:
+ * This function calculates the SAD between one block (pSrc) and the
+ * average of the other two (pSrcRef0 and pSrcRef1)
+ *
+ * Remarks:
+ *
+ * [in] pSrc Pointer to the original block
+ * [in] pSrcRef0 Pointer to reference block 0
+ * [in] pSrcRef1 Pointer to reference block 1
+ * [in] iSrcStep Step of the original block buffer
+ * [in] iRefStep0 Step of reference block 0
+ * [in] iRefStep1 Step of reference block 1
+ * [in] iHeight Height of the block
+ * [in] iWidth Width of the block
+ * [out] pDstSAD Pointer of result SAD
+ *
+ * Return Value:
+ * Standard OMXResult value.
+ *
+ */
+OMXResult armVCM4P10_SADQuar(
+ const OMX_U8* pSrc,
+ const OMX_U8* pSrcRef0,
+ const OMX_U8* pSrcRef1,
+ OMX_U32 iSrcStep,
+ OMX_U32 iRefStep0,
+ OMX_U32 iRefStep1,
+ OMX_U32* pDstSAD,
+ OMX_U32 iHeight,
+ OMX_U32 iWidth
+);
+
+/**
+ * Function: armVCM4P10_Interpolate_Chroma
+ *
+ * Description:
+ * This function performs interpolation for chroma components.
+ *
+ * Remarks:
+ *
+ * [in] pSrc Pointer to top-left corner of block used to
+ * interpolate in the reconstructed frame plane
+ * [in] iSrcStep Step of the source buffer.
+ * [in] iDstStep Step of the destination(interpolation) buffer.
+ * [in] iWidth Width of the current block
+ * [in] iHeight Height of the current block
+ * [in] dx Fractional part of horizontal motion vector
+ * component in 1/8 pixel unit (0~7)
+ * [in] dy Fractional part of vertical motion vector
+ * component in 1/8 pixel unit (0~7)
+ * [out] pDst Pointer to the interpolation buffer
+ *
+ * Return Value:
+ * Standard OMXResult value.
+ *
+ */
+ OMXResult armVCM4P10_Interpolate_Chroma(
+ OMX_U8 *pSrc,
+ OMX_U32 iSrcStep,
+ OMX_U8 *pDst,
+ OMX_U32 iDstStep,
+ OMX_U32 iWidth,
+ OMX_U32 iHeight,
+ OMX_U32 dx,
+ OMX_U32 dy
+);
+
+/**
+ * Function: armVCM4P10_Interpolate_Luma
+ *
+ * Description:
+ * This function performs interpolation for luma components.
+ *
+ * Remarks:
+ *
+ * [in] pSrc Pointer to top-left corner of block used to
+ * interpolate in the reconstructed frame plane
+ * [in] iSrcStep Step of the source buffer.
+ * [in] iDstStep Step of the destination(interpolation) buffer.
+ * [in] iWidth Width of the current block
+ * [in] iHeight Height of the current block
+ * [in] dx Fractional part of horizontal motion vector
+ * component in 1/4 pixel unit (0~3)
+ * [in] dy Fractional part of vertical motion vector
+ * component in 1/4 pixel unit (0~3)
+ * [out] pDst Pointer to the interpolation buffer
+ *
+ * Return Value:
+ * Standard OMXResult value.
+ *
+ */
+
+ OMXResult armVCM4P10_Interpolate_Luma(
+ const OMX_U8 *pSrc,
+ OMX_U32 iSrcStep,
+ OMX_U8 *pDst,
+ OMX_U32 iDstStep,
+ OMX_U32 iWidth,
+ OMX_U32 iHeight,
+ OMX_U32 dx,
+ OMX_U32 dy
+);
+
+/**
+ * Function: omxVCH264_DequantTransformACFromPair_U8_S16_C1_DLx
+ *
+ * Description:
+ * Reconstruct the 4x4 residual block from coefficient-position pair buffer,
+ * perform dequantisation and integer inverse transformation for 4x4 block of
+ * residuals and update the pair buffer pointer to next non-empty block.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppSrc Double pointer to residual coefficient-position
+ * pair buffer output by CALVC decoding
+ * [in] pDC Pointer to the DC coefficient of this block, NULL
+ * if it doesn't exist
+ * [in] QP Quantization parameter
+ * [in] AC Flag indicating if at least one non-zero coefficient exists
+ * [out] pDst pointer to the reconstructed 4x4 block data
+ *
+ * Return Value:
+ * Standard omxError result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armVCM4P10_DequantTransformACFromPair_U8_S16_C1_DLx(
+ OMX_U8 **ppSrc,
+ OMX_S16 *pDst,
+ OMX_INT QP,
+ OMX_S16* pDC,
+ int AC
+);
+
+#endif /*_armVideo_H_*/
+
+/*End of File*/
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/api/armVCCOMM_s.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/api/armVCCOMM_s.h
new file mode 100644
index 0000000..7f0a9b8
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/api/armVCCOMM_s.h
@@ -0,0 +1,72 @@
+;//
+;//
+;// File Name: armVCCOMM_s.h
+;// OpenMAX DL: v1.0.2
+;// Revision: 9641
+;// Date: Thursday, February 7, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+;// ARM optimized OpenMAX AC header file
+;//
+;// Formula used:
+;// MACRO for calculating median for three values.
+
+
+
+ IF :LNOT::DEF:ARMVCCOMM_S_H
+ INCLUDE armCOMM_s.h
+ M_VARIANTS CortexA8, ARM1136JS
+
+ IF ARM1136JS :LOR: CortexA8
+
+ ;///*
+ ;// * Macro: M_MEDIAN3
+ ;// *
+ ;// * Description: Finds the median of three numbers
+ ;// *
+ ;// * Remarks:
+ ;// *
+ ;// * Parameters:
+ ;// * [in] x First entry for the list of three numbers.
+ ;// * [in] y Second entry for the list of three numbers.
+ ;// * Input value may be corrupted at the end of
+ ;// * the execution of this macro.
+ ;// * [in] z Third entry of the list of three numbers.
+ ;// * Input value corrupted at the end of the
+ ;// * execution of this macro.
+ ;// * [in] t Temporary scratch register.
+ ;// * [out]z Median of the three numbers.
+ ;// */
+
+ MACRO
+
+ M_MEDIAN3 $x, $y, $z, $t
+
+ SUBS $t, $y, $z; // if (y < z)
+ ADDLT $z, $z, $t; // swap y and z
+ SUBLT $y, $y, $t;
+
+ ;// Now z' <= y', so there are three cases for the
+ ;// median value, depending on x.
+
+ ;// 1) x <= z' <= y' : median value is z'
+ ;// 2) z' <= x <= y' : median value is x
+ ;// 3) z' <= y' <= x : median value is y'
+
+ CMP $z, $x; // if ( x > min(y,z) )
+ MOVLT $z, $x; // ans = x
+
+ CMP $x, $y; // if ( x > max(y,z) )
+ MOVGT $z, $y; // ans = max(y,z)
+
+ MEND
+ ENDIF
+
+
+
+ ENDIF ;// ARMACCOMM_S_H
+
+ END
\ No newline at end of file
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/api/omxVC.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/api/omxVC.h
new file mode 100644
index 0000000..7b3cc72
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/api/omxVC.h
@@ -0,0 +1,4381 @@
+/**
+ * File: omxVC.h
+ * Brief: OpenMAX DL v1.0.2 - Video Coding library
+ *
+ * Copyright © 2005-2008 The Khronos Group Inc. All Rights Reserved.
+ *
+ * These materials are protected by copyright laws and contain material
+ * proprietary to the Khronos Group, Inc. You may use these materials
+ * for implementing Khronos specifications, without altering or removing
+ * any trademark, copyright or other notice from the specification.
+ *
+ * Khronos Group makes no, and expressly disclaims any, representations
+ * or warranties, express or implied, regarding these materials, including,
+ * without limitation, any implied warranties of merchantability or fitness
+ * for a particular purpose or non-infringement of any intellectual property.
+ * Khronos Group makes no, and expressly disclaims any, warranties, express
+ * or implied, regarding the correctness, accuracy, completeness, timeliness,
+ * and reliability of these materials.
+ *
+ * Under no circumstances will the Khronos Group, or any of its Promoters,
+ * Contributors or Members or their respective partners, officers, directors,
+ * employees, agents or representatives be liable for any damages, whether
+ * direct, indirect, special or consequential damages for lost revenues,
+ * lost profits, or otherwise, arising from or in connection with these
+ * materials.
+ *
+ * Khronos and OpenMAX are trademarks of the Khronos Group Inc.
+ *
+ */
+
+/* *****************************************************************************************/
+
+#ifndef _OMXVC_H_
+#define _OMXVC_H_
+
+#include "omxtypes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* 6.1.1.1 Motion Vectors */
+/* In omxVC, motion vectors are represented as follows: */
+
+typedef struct {
+ OMX_S16 dx;
+ OMX_S16 dy;
+} OMXVCMotionVector;
+
+
+
+/**
+ * Function: omxVCCOMM_Average_8x (6.1.3.1.1)
+ *
+ * Description:
+ * This function calculates the average of two 8x4, 8x8, or 8x16 blocks. The
+ * result is rounded according to (a+b+1)/2. The block average function can
+ * be used in conjunction with half-pixel interpolation to obtain quarter
+ * pixel motion estimates, as described in [ISO14496-10], subclause 8.4.2.2.1.
+ *
+ * Input Arguments:
+ *
+ * pPred0 - Pointer to the top-left corner of reference block 0
+ * pPred1 - Pointer to the top-left corner of reference block 1
+ * iPredStep0 - Step of reference block 0
+ * iPredStep1 - Step of reference block 1
+ * iDstStep - Step of the destination buffer.
+ * iHeight - Height of the blocks
+ *
+ * Output Arguments:
+ *
+ * pDstPred - Pointer to the destination buffer. 8-byte aligned.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned under any of the following
+ * conditions:
+ * - one or more of the following pointers is NULL: pPred0, pPred1, or
+ * pDstPred.
+ * - pDstPred is not aligned on an 8-byte boundary.
+ * - iPredStep0 <= 0 or iPredStep0 is not a multiple of 8.
+ * - iPredStep1 <= 0 or iPredStep1 is not a multiple of 8.
+ * - iDstStep <= 0 or iDstStep is not a multiple of 8.
+ * - iHeight is not 4, 8, or 16.
+ *
+ */
+OMXResult omxVCCOMM_Average_8x (
+ const OMX_U8 *pPred0,
+ const OMX_U8 *pPred1,
+ OMX_U32 iPredStep0,
+ OMX_U32 iPredStep1,
+ OMX_U8 *pDstPred,
+ OMX_U32 iDstStep,
+ OMX_U32 iHeight
+);
+
+
+
+/**
+ * Function: omxVCCOMM_Average_16x (6.1.3.1.2)
+ *
+ * Description:
+ * This function calculates the average of two 16x16 or 16x8 blocks. The
+ * result is rounded according to (a+b+1)/2. The block average function can
+ * be used in conjunction with half-pixel interpolation to obtain quarter
+ * pixel motion estimates, as described in [ISO14496-10], subclause 8.4.2.2.1.
+ *
+ * Input Arguments:
+ *
+ * pPred0 - Pointer to the top-left corner of reference block 0
+ * pPred1 - Pointer to the top-left corner of reference block 1
+ * iPredStep0 - Step of reference block 0
+ * iPredStep1 - Step of reference block 1
+ * iDstStep - Step of the destination buffer
+ * iHeight - Height of the blocks
+ *
+ * Output Arguments:
+ *
+ * pDstPred - Pointer to the destination buffer. 16-byte aligned.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned under any of the following
+ * conditions:
+ * - one or more of the following pointers is NULL: pPred0, pPred1, or
+ * pDstPred.
+ * - pDstPred is not aligned on a 16-byte boundary.
+ * - iPredStep0 <= 0 or iPredStep0 is not a multiple of 16.
+ * - iPredStep1 <= 0 or iPredStep1 is not a multiple of 16.
+ * - iDstStep <= 0 or iDstStep is not a multiple of 16.
+ * - iHeight is not 8 or 16.
+ *
+ */
+OMXResult omxVCCOMM_Average_16x (
+ const OMX_U8 *pPred0,
+ const OMX_U8 *pPred1,
+ OMX_U32 iPredStep0,
+ OMX_U32 iPredStep1,
+ OMX_U8 *pDstPred,
+ OMX_U32 iDstStep,
+ OMX_U32 iHeight
+);
+
+
+
+/**
+ * Function: omxVCCOMM_ExpandFrame_I (6.1.3.2.1)
+ *
+ * Description:
+ * This function expands a reconstructed frame in-place. The unexpanded
+ * source frame should be stored in a plane buffer with sufficient space
+ * pre-allocated for edge expansion, and the input frame should be located in
+ * the plane buffer center. This function executes the pixel expansion by
+ * replicating source frame edge pixel intensities in the empty pixel
+ * locations (expansion region) between the source frame edge and the plane
+ * buffer edge. The width/height of the expansion regions on the
+ * horizontal/vertical edges is controlled by the parameter iExpandPels.
+ *
+ * Input Arguments:
+ *
+ * pSrcDstPlane - pointer to the top-left corner of the frame to be
+ * expanded; must be aligned on an 8-byte boundary.
+ * iFrameWidth - frame width; must be a multiple of 8.
+ * iFrameHeight -frame height; must be a multiple of 8.
+ * iExpandPels - number of pixels to be expanded in the horizontal and
+ * vertical directions; must be a multiple of 8.
+ * iPlaneStep - distance, in bytes, between the start of consecutive lines
+ * in the plane buffer; must be larger than or equal to
+ * (iFrameWidth + 2 * iExpandPels).
+ *
+ * Output Arguments:
+ *
+ * pSrcDstPlane -Pointer to the top-left corner of the frame (NOT the
+ * top-left corner of the plane); must be aligned on an 8-byte
+ * boundary.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned under any of the following
+ * conditions:
+ * - pSrcDstPlane is NULL.
+ * - pSrcDstPlane is not aligned on an 8-byte boundary.
+ * - one of the following parameters is either equal to zero or is a
+ * non-multiple of 8: iFrameHeight, iFrameWidth, iPlaneStep, or
+ * iExpandPels.
+ * - iPlaneStep < (iFrameWidth + 2 * iExpandPels).
+ *
+ */
+OMXResult omxVCCOMM_ExpandFrame_I (
+ OMX_U8 *pSrcDstPlane,
+ OMX_U32 iFrameWidth,
+ OMX_U32 iFrameHeight,
+ OMX_U32 iExpandPels,
+ OMX_U32 iPlaneStep
+);
+
+
+
+/**
+ * Function: omxVCCOMM_Copy8x8 (6.1.3.3.1)
+ *
+ * Description:
+ * Copies the reference 8x8 block to the current block.
+ *
+ * Input Arguments:
+ *
+ * pSrc - pointer to the reference block in the source frame; must be
+ * aligned on an 8-byte boundary.
+ * step - distance between the starts of consecutive lines in the reference
+ * frame, in bytes; must be a multiple of 8 and must be larger than
+ * or equal to 8.
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the destination block; must be aligned on an 8-byte
+ * boundary.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned under any of the following
+ * conditions:
+ * - one or more of the following pointers is NULL: pSrc, pDst
+ * - one or more of the following pointers is not aligned on an 8-byte
+ * boundary: pSrc, pDst
+ * - step <8 or step is not a multiple of 8.
+ *
+ */
+OMXResult omxVCCOMM_Copy8x8 (
+ const OMX_U8 *pSrc,
+ OMX_U8 *pDst,
+ OMX_INT step
+);
+
+
+
+/**
+ * Function: omxVCCOMM_Copy16x16 (6.1.3.3.2)
+ *
+ * Description:
+ * Copies the reference 16x16 macroblock to the current macroblock.
+ *
+ * Input Arguments:
+ *
+ * pSrc - pointer to the reference macroblock in the source frame; must be
+ * aligned on a 16-byte boundary.
+ * step - distance between the starts of consecutive lines in the reference
+ * frame, in bytes; must be a multiple of 16 and must be larger
+ * than or equal to 16.
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the destination macroblock; must be aligned on a
+ * 16-byte boundary.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned under any of the following
+ * conditions:
+ * - one or more of the following pointers is NULL: pSrc, pDst
+ * - one or more of the following pointers is not aligned on a 16-byte
+ * boundary: pSrc, pDst
+ * - step <16 or step is not a multiple of 16.
+ *
+ */
+OMXResult omxVCCOMM_Copy16x16 (
+ const OMX_U8 *pSrc,
+ OMX_U8 *pDst,
+ OMX_INT step
+);
+
+
+
+/**
+ * Function: omxVCCOMM_ComputeTextureErrorBlock_SAD (6.1.4.1.1)
+ *
+ * Description:
+ * Computes texture error of the block; also returns SAD.
+ *
+ * Input Arguments:
+ *
+ * pSrc - pointer to the source plane; must be aligned on an 8-byte
+ * boundary.
+ * srcStep - step of the source plane
+ * pSrcRef - pointer to the reference buffer, an 8x8 block; must be aligned
+ * on an 8-byte boundary.
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the destination buffer, an 8x8 block; must be aligned
+ * on an 8-byte boundary.
+ * pDstSAD - pointer to the Sum of Absolute Differences (SAD) value
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments
+ * - At least one of the following
+ * pointers is NULL: pSrc, pSrcRef, pDst and pDstSAD.
+ * - pSrc is not 8-byte aligned.
+ * - SrcStep <= 0 or srcStep is not a multiple of 8.
+ * - pSrcRef is not 8-byte aligned.
+ * - pDst is not 8-byte aligned.
+ *
+ */
+OMXResult omxVCCOMM_ComputeTextureErrorBlock_SAD (
+ const OMX_U8 *pSrc,
+ OMX_INT srcStep,
+ const OMX_U8 *pSrcRef,
+ OMX_S16 *pDst,
+ OMX_INT *pDstSAD
+);
+
+
+
+/**
+ * Function: omxVCCOMM_ComputeTextureErrorBlock (6.1.4.1.2)
+ *
+ * Description:
+ * Computes the texture error of the block.
+ *
+ * Input Arguments:
+ *
+ * pSrc - pointer to the source plane. This should be aligned on an 8-byte
+ * boundary.
+ * srcStep - step of the source plane
+ * pSrcRef - pointer to the reference buffer, an 8x8 block. This should be
+ * aligned on an 8-byte boundary.
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the destination buffer, an 8x8 block. This should be
+ * aligned on an 8-byte boundary.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments:
+ * - At least one of the following pointers is NULL:
+ * pSrc, pSrcRef, pDst.
+ * - pSrc is not 8-byte aligned.
+ * - SrcStep <= 0 or srcStep is not a multiple of 8.
+ * - pSrcRef is not 8-byte aligned.
+ * - pDst is not 8-byte aligned
+ *
+ */
+OMXResult omxVCCOMM_ComputeTextureErrorBlock (
+ const OMX_U8 *pSrc,
+ OMX_INT srcStep,
+ const OMX_U8 *pSrcRef,
+ OMX_S16 *pDst
+);
+
+
+
+/**
+ * Function: omxVCCOMM_LimitMVToRect (6.1.4.1.3)
+ *
+ * Description:
+ * Limits the motion vector associated with the current block/macroblock to
+ * prevent the motion compensated block/macroblock from moving outside a
+ * bounding rectangle as shown in Figure 6-1.
+ *
+ * Input Arguments:
+ *
+ * pSrcMV - pointer to the motion vector associated with the current block
+ * or macroblock
+ * pRectVOPRef - pointer to the bounding rectangle
+ * Xcoord, Ycoord - coordinates of the current block or macroblock
+ * size - size of the current block or macroblock; must be equal to 8 or
+ * 16.
+ *
+ * Output Arguments:
+ *
+ * pDstMV - pointer to the limited motion vector
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments. Returned if one or more of the
+ * following conditions is true:
+ * - at least one of the following pointers is NULL:
+ * pSrcMV, pDstMV, or pRectVOPRef.
+ * - size is not equal to either 8 or 16.
+ * - the width or height of the bounding rectangle is less than
+ * twice the block size.
+ */
+OMXResult omxVCCOMM_LimitMVToRect (
+ const OMXVCMotionVector *pSrcMV,
+ OMXVCMotionVector *pDstMV,
+ const OMXRect *pRectVOPRef,
+ OMX_INT Xcoord,
+ OMX_INT Ycoord,
+ OMX_INT size
+);
+
+
+
+/**
+ * Function: omxVCCOMM_SAD_16x (6.1.4.1.4)
+ *
+ * Description:
+ * This function calculates the SAD for 16x16 and 16x8 blocks.
+ *
+ * Input Arguments:
+ *
+ * pSrcOrg - Pointer to the original block; must be aligned on a 16-byte
+ * boundary.
+ * iStepOrg - Step of the original block buffer
+ * pSrcRef - Pointer to the reference block
+ * iStepRef - Step of the reference block buffer
+ * iHeight - Height of the block
+ *
+ * Output Arguments:
+ *
+ * pDstSAD - Pointer of result SAD
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments. Returned if one or more of the
+ * following conditions is true:
+ * - at least one of the following pointers is NULL:
+ * pSrcOrg, pDstSAD, or pSrcRef
+ * - pSrcOrg is not 16-byte aligned.
+ * - iStepOrg <= 0 or iStepOrg is not a multiple of 16
+ * - iStepRef <= 0 or iStepRef is not a multiple of 16
+ * - iHeight is not 8 or 16
+ *
+ */
+OMXResult omxVCCOMM_SAD_16x (
+ const OMX_U8 *pSrcOrg,
+ OMX_U32 iStepOrg,
+ const OMX_U8 *pSrcRef,
+ OMX_U32 iStepRef,
+ OMX_S32 *pDstSAD,
+ OMX_U32 iHeight
+);
+
+
+
+/**
+ * Function: omxVCCOMM_SAD_8x (6.1.4.1.5)
+ *
+ * Description:
+ * This function calculates the SAD for 8x16, 8x8, 8x4 blocks.
+ *
+ * Input Arguments:
+ *
+ * pSrcOrg - Pointer to the original block; must be aligned on a 8-byte
+ * boundary.
+ * iStepOrg - Step of the original block buffer
+ * pSrcRef - Pointer to the reference block
+ * iStepRef - Step of the reference block buffer
+ * iHeight - Height of the block
+ *
+ * Output Arguments:
+ *
+ * pDstSAD -Pointer of result SAD
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments. Returned if one or more of the
+ * following conditions is true:
+ * - at least one of the following pointers is NULL:
+ * pSrcOrg, pDstSAD, or pSrcRef
+ * - pSrcOrg is not 8-byte aligned.
+ * - iStepOrg <= 0 or iStepOrg is not a multiple of 8
+ * - iStepRef <= 0 or iStepRef is not a multiple of 8
+ * - iHeight is not 4, 8 or 16
+ *
+ */
+OMXResult omxVCCOMM_SAD_8x (
+ const OMX_U8 *pSrcOrg,
+ OMX_U32 iStepOrg,
+ const OMX_U8 *pSrcRef,
+ OMX_U32 iStepRef,
+ OMX_S32*pDstSAD,
+ OMX_U32 iHeight
+);
+
+
+
+/* 6.2.1.1 Direction */
+/* The direction enumerator is used with functions that perform AC/DC prediction and zig-zag scan. */
+
+enum {
+ OMX_VC_NONE = 0,
+ OMX_VC_HORIZONTAL = 1,
+ OMX_VC_VERTICAL = 2
+};
+
+
+
+/* 6.2.1.2 Bilinear Interpolation */
+/* The bilinear interpolation enumerator is used with motion estimation, motion compensation, and reconstruction functions. */
+
+enum {
+ OMX_VC_INTEGER_PIXEL = 0, /* case a */
+ OMX_VC_HALF_PIXEL_X = 1, /* case b */
+ OMX_VC_HALF_PIXEL_Y = 2, /* case c */
+ OMX_VC_HALF_PIXEL_XY = 3 /* case d */
+};
+
+
+
+/* 6.2.1.3 Neighboring Macroblock Availability */
+/* Neighboring macroblock availability is indicated using the following flags: */
+
+enum {
+ OMX_VC_UPPER = 1, /** above macroblock is available */
+ OMX_VC_LEFT = 2, /** left macroblock is available */
+ OMX_VC_CENTER = 4,
+ OMX_VC_RIGHT = 8,
+ OMX_VC_LOWER = 16,
+ OMX_VC_UPPER_LEFT = 32, /** above-left macroblock is available */
+ OMX_VC_UPPER_RIGHT = 64, /** above-right macroblock is available */
+ OMX_VC_LOWER_LEFT = 128,
+ OMX_VC_LOWER_RIGHT = 256
+};
+
+
+
+/* 6.2.1.4 Video Components */
+/* A data type that enumerates video components is defined as follows: */
+
+typedef enum {
+ OMX_VC_LUMINANCE, /** Luminance component */
+ OMX_VC_CHROMINANCE /** chrominance component */
+} OMXVCM4P2VideoComponent;
+
+
+
+/* 6.2.1.5 MacroblockTypes */
+/* A data type that enumerates macroblock types is defined as follows: */
+
+typedef enum {
+ OMX_VC_INTER = 0, /** P picture or P-VOP */
+ OMX_VC_INTER_Q = 1, /** P picture or P-VOP */
+ OMX_VC_INTER4V = 2, /** P picture or P-VOP */
+ OMX_VC_INTRA = 3, /** I and P picture, I- and P-VOP */
+ OMX_VC_INTRA_Q = 4, /** I and P picture, I- and P-VOP */
+ OMX_VC_INTER4V_Q = 5 /** P picture or P-VOP (H.263)*/
+} OMXVCM4P2MacroblockType;
+
+
+
+/* 6.2.1.6 Coordinates */
+/* Coordinates are represented as follows: */
+
+typedef struct {
+ OMX_INT x;
+ OMX_INT y;
+} OMXVCM4P2Coordinate;
+
+
+
+/* 6.2.1.7 Motion Estimation Algorithms */
+/* A data type that enumerates motion estimation search methods is defined as follows: */
+
+typedef enum {
+ OMX_VC_M4P2_FAST_SEARCH = 0, /** Fast motion search */
+ OMX_VC_M4P2_FULL_SEARCH = 1 /** Full motion search */
+} OMXVCM4P2MEMode;
+
+
+
+/* 6.2.1.8 Motion Estimation Parameters */
+/* A data structure containing control parameters for
+ * motion estimation functions is defined as follows:
+ */
+
+typedef struct {
+ OMX_INT searchEnable8x8; /** enables 8x8 search */
+ OMX_INT halfPelSearchEnable; /** enables half-pel resolution */
+ OMX_INT searchRange; /** search range */
+ OMX_INT rndVal; /** rounding control; 0-disabled, 1-enabled*/
+} OMXVCM4P2MEParams;
+
+
+
+/* 6.2.1.9 Macroblock Information */
+/* A data structure containing macroblock parameters for
+ * motion estimation functions is defined as follows:
+ */
+
+typedef struct {
+ OMX_S32 sliceId; /* slice number */
+ OMXVCM4P2MacroblockType mbType; /* MB type: OMX_VC_INTRA, OMX_VC_INTER, or OMX_VC_INTER4 */
+ OMX_S32 qp; /* quantization parameter*/
+ OMX_U32 cbpy; /* CBP Luma */
+ OMX_U32 cbpc; /* CBP Chroma */
+ OMXVCMotionVector pMV0[2][2]; /* motion vector, represented using 1/2-pel units,
+ * pMV0[blocky][blockx] (blocky = 0~1, blockx =0~1)
+ */
+ OMXVCMotionVector pMVPred[2][2]; /* motion vector prediction, represented using 1/2-pel units,
+ * pMVPred[blocky][blockx] (blocky = 0~1, blockx = 0~1)
+ */
+ OMX_U8 pPredDir[2][2]; /* AC prediction direction:
+ * OMX_VC_NONE, OMX_VC_VERTICAL, OMX_VC_HORIZONTAL
+ */
+} OMXVCM4P2MBInfo, *OMXVCM4P2MBInfoPtr;
+
+
+
+/**
+ * Function: omxVCM4P2_FindMVpred (6.2.3.1.1)
+ *
+ * Description:
+ * Predicts a motion vector for the current block using the procedure
+ * specified in [ISO14496-2], subclause 7.6.5. The resulting predicted MV is
+ * returned in pDstMVPred. If the parameter pDstMVPredME if is not NULL then
+ * the set of three MV candidates used for prediction is also returned,
+ * otherwise pDstMVPredMEis NULL upon return.
+ *
+ * Input Arguments:
+ *
+ * pSrcMVCurMB - pointer to the MV buffer associated with the current Y
+ * macroblock; a value of NULL indicates unavailability.
+ * pSrcCandMV1 - pointer to the MV buffer containing the 4 MVs associated
+ * with the MB located to the left of the current MB; set to NULL
+ * if there is no MB to the left.
+ * pSrcCandMV2 - pointer to the MV buffer containing the 4 MVs associated
+ * with the MB located above the current MB; set to NULL if there
+ * is no MB located above the current MB.
+ * pSrcCandMV3 - pointer to the MV buffer containing the 4 MVs associated
+ * with the MB located to the right and above the current MB; set
+ * to NULL if there is no MB located to the above-right.
+ * iBlk - the index of block in the current macroblock
+ * pDstMVPredME - MV candidate return buffer; if set to NULL then
+ * prediction candidate MVs are not returned and pDstMVPredME will
+ * be NULL upon function return; if pDstMVPredME is non-NULL then it
+ * must point to a buffer containing sufficient space for three
+ * return MVs.
+ *
+ * Output Arguments:
+ *
+ * pDstMVPred - pointer to the predicted motion vector
+ * pDstMVPredME - if non-NULL upon input then pDstMVPredME points upon
+ * return to a buffer containing the three motion vector candidates
+ * used for prediction as specified in [ISO14496-2], subclause
+ * 7.6.5, otherwise if NULL upon input then pDstMVPredME is NULL
+ * upon output.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned under any of the following
+ * conditions:
+ * - the pointer pDstMVPred is NULL
+ * - the parameter iBlk does not fall into the range 0 <= iBlk<=3
+ *
+ */
+OMXResult omxVCM4P2_FindMVpred (
+ const OMXVCMotionVector *pSrcMVCurMB,
+ const OMXVCMotionVector *pSrcCandMV1,
+ const OMXVCMotionVector *pSrcCandMV2,
+ const OMXVCMotionVector *pSrcCandMV3,
+ OMXVCMotionVector *pDstMVPred,
+ OMXVCMotionVector *pDstMVPredME,
+ OMX_INT iBlk
+);
+
+
+
+/**
+ * Function: omxVCM4P2_IDCT8x8blk (6.2.3.2.1)
+ *
+ * Description:
+ * Computes a 2D inverse DCT for a single 8x8 block, as defined in
+ * [ISO14496-2].
+ *
+ * Input Arguments:
+ *
+ * pSrc - pointer to the start of the linearly arranged IDCT input buffer;
+ * must be aligned on a 16-byte boundary. According to
+ * [ISO14496-2], the input coefficient values should lie within the
+ * range [-2048, 2047].
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the start of the linearly arranged IDCT output buffer;
+ * must be aligned on a 16-byte boundary.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments:
+ * - pSrc or pDst is NULL.
+ * - pSrc or pDst is not 16-byte aligned.
+ *
+ */
+OMXResult omxVCM4P2_IDCT8x8blk (
+ const OMX_S16 *pSrc,
+ OMX_S16 *pDst
+);
+
+
+
+/**
+ * Function: omxVCM4P2_MEGetBufSize (6.2.4.1.1)
+ *
+ * Description:
+ * Computes the size, in bytes, of the vendor-specific specification
+ * structure for the following motion estimation functions:
+ * BlockMatch_Integer_8x8, BlockMatch_Integer_16x16, and MotionEstimationMB.
+ *
+ * Input Arguments:
+ *
+ * MEmode - motion estimation mode; available modes are defined by the
+ * enumerated type OMXVCM4P2MEMode
+ * pMEParams - motion estimation parameters
+ *
+ * Output Arguments:
+ *
+ * pSize - pointer to the number of bytes required for the specification
+ * structure
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - one or more of the following is true:
+ * - an invalid value was specified for the parameter MEmode
+ * - a negative or zero value was specified for the
+ * parameter pMEParams->searchRange
+ *
+ */
+OMXResult omxVCM4P2_MEGetBufSize (
+ OMXVCM4P2MEMode MEmode,
+ const OMXVCM4P2MEParams *pMEParams,
+ OMX_U32 *pSize
+);
+
+
+
+/**
+ * Function: omxVCM4P2_MEInit (6.2.4.1.2)
+ *
+ * Description:
+ * Initializes the vendor-specific specification structure required for the
+ * following motion estimation functions: BlockMatch_Integer_8x8,
+ * BlockMatch_Integer_16x16, and MotionEstimationMB. Memory for the
+ * specification structure *pMESpec must be allocated prior to calling the
+ * function, and should be aligned on a 4-byte boundary. Following
+ * initialization by this function, the vendor-specific structure *pMESpec
+ * should contain an implementation-specific representation of all motion
+ * estimation parameters received via the structure pMEParams, for example
+ * rndVal, searchRange, etc. The number of bytes required for the
+ * specification structure can be determined using the function
+ * omxVCM4P2_MEGetBufSize.
+ *
+ * Input Arguments:
+ *
+ * MEmode - motion estimation mode; available modes are defined by the
+ * enumerated type OMXVCM4P2MEMode
+ * pMEParams - motion estimation parameters
+ * pMESpec - pointer to the uninitialized ME specification structure
+ *
+ * Output Arguments:
+ *
+ * pMESpec - pointer to the initialized ME specification structure
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - one or more of the following is true:
+ * - an invalid value was specified for the parameter MEmode
+ * - a negative or zero value was specified for the
+ * parameter pMEParams->searchRange
+ *
+ */
+OMXResult omxVCM4P2_MEInit (
+ OMXVCM4P2MEMode MEmode,
+ const OMXVCM4P2MEParams*pMEParams,
+ void *pMESpec
+);
+
+
+
+/**
+ * Function: omxVCM4P2_BlockMatch_Integer_16x16 (6.2.4.2.1)
+ *
+ * Description:
+ * Performs a 16x16 block search; estimates motion vector and associated
+ * minimum SAD. Both the input and output motion vectors are represented using
+ * half-pixel units, and therefore a shift left or right by 1 bit may be
+ * required, respectively, to match the input or output MVs with other
+ * functions that either generate output MVs or expect input MVs represented
+ * using integer pixel units.
+ *
+ * Input Arguments:
+ *
+ * pSrcRefBuf - pointer to the reference Y plane; points to the reference
+ * MB that corresponds to the location of the current macroblock in
+ * the current plane.
+ * refWidth - width of the reference plane
+ * pRefRect - pointer to the valid reference plane rectangle; coordinates
+ * are specified relative to the image origin. Rectangle
+ * boundaries may extend beyond image boundaries if the image has
+ * been padded. For example, if padding extends 4 pixels beyond
+ * frame border, then the value for the left border could be set to
+ * -4.
+ * pSrcCurrBuf - pointer to the current block in the current macroblock
+ * buffer extracted from the original plane (linear array, 256
+ * entries); must be aligned on a 16-byte boundary. The number of
+ * bytes between lines (step) is 16.
+ * pCurrPointPos - position of the current macroblock in the current plane
+ * pSrcPreMV - pointer to predicted motion vector; NULL indicates no
+ * predicted MV
+ * pSrcPreSAD - pointer to SAD associated with the predicted MV (referenced
+ * by pSrcPreMV); may be set to NULL if unavailable.
+ * pMESpec - vendor-specific motion estimation specification structure;
+ * must have been allocated and then initialized using
+ * omxVCM4P2_MEInit prior to calling the block matching function.
+ *
+ * Output Arguments:
+ *
+ * pDstMV - pointer to estimated MV
+ * pDstSAD - pointer to minimum SAD
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments. Returned if one of the following
+ * conditions is true:
+ * - at least one of the following pointers is NULL: pSrcRefBuf,
+ * pRefRect, pSrcCurrBuff, pCurrPointPos, pDstMV, pDstSAD or
+ * pMESpec, or
+ * - pSrcCurrBuf is not 16-byte aligned
+ *
+ */
+OMXResult omxVCM4P2_BlockMatch_Integer_16x16 (
+ const OMX_U8 *pSrcRefBuf,
+ OMX_INT refWidth,
+ const OMXRect *pRefRect,
+ const OMX_U8 *pSrcCurrBuf,
+ const OMXVCM4P2Coordinate *pCurrPointPos,
+ const OMXVCMotionVector*pSrcPreMV,
+ const OMX_INT *pSrcPreSAD,
+ void *pMESpec,
+ OMXVCMotionVector*pDstMV,
+ OMX_INT *pDstSAD
+);
+
+
+
+/**
+ * Function: omxVCM4P2_BlockMatch_Integer_8x8 (6.2.4.2.2)
+ *
+ * Description:
+ * Performs an 8x8 block search; estimates motion vector and associated
+ * minimum SAD. Both the input and output motion vectors are represented
+ * using half-pixel units, and therefore a shift left or right by 1 bit may be
+ * required, respectively, to match the input or output MVs with other
+ * functions that either generate output MVs or expect input MVs represented
+ * using integer pixel units.
+ *
+ * Input Arguments:
+ *
+ * pSrcRefBuf - pointer to the reference Y plane; points to the reference
+ * block that corresponds to the location of the current 8x8 block
+ * in the current plane.
+ * refWidth - width of the reference plane
+ * pRefRect - pointer to the valid reference plane rectangle; coordinates
+ * are specified relative to the image origin. Rectangle
+ * boundaries may extend beyond image boundaries if the image has
+ * been padded.
+ * pSrcCurrBuf - pointer to the current block in the current macroblock
+ * buffer extracted from the original plane (linear array, 128
+ * entries); must be aligned on an 8-byte boundary. The number of
+ * bytes between lines (step) is 16 bytes.
+ * pCurrPointPos - position of the current block in the current plane
+ * pSrcPreMV - pointer to predicted motion vector; NULL indicates no
+ * predicted MV
+ * pSrcPreSAD - pointer to SAD associated with the predicted MV (referenced
+ * by pSrcPreMV); may be set to NULL if unavailable.
+ * pMESpec - vendor-specific motion estimation specification structure;
+ * must have been allocated and then initialized using
+ * omxVCM4P2_MEInit prior to calling the block matching function.
+ *
+ * Output Arguments:
+ *
+ * pDstMV - pointer to estimated MV
+ * pDstSAD - pointer to minimum SAD
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments. Returned if one of the following
+ * conditions is true:
+ * - at least one of the following pointers is NULL: pSrcRefBuf,
+ * pRefRect, pSrcCurrBuff, pCurrPointPos, pDstMV, pDstSAD or
+ * pMESpec, or
+ * - pSrcCurrBuf is not 8-byte aligned
+ *
+ */
+OMXResult omxVCM4P2_BlockMatch_Integer_8x8 (
+ const OMX_U8 *pSrcRefBuf,
+ OMX_INT refWidth,
+ const OMXRect *pRefRect,
+ const OMX_U8 *pSrcCurrBuf,
+ const OMXVCM4P2Coordinate *pCurrPointPos,
+ const OMXVCMotionVector *pSrcPreMV,
+ const OMX_INT *pSrcPreSAD,
+ void *pMESpec,
+ OMXVCMotionVector *pDstMV,
+ OMX_INT *pDstSAD
+);
+
+
+
+/**
+ * Function: omxVCM4P2_BlockMatch_Half_16x16 (6.2.4.2.3)
+ *
+ * Description:
+ * Performs a 16x16 block match with half-pixel resolution. Returns the
+ * estimated motion vector and associated minimum SAD. This function
+ * estimates the half-pixel motion vector by interpolating the integer
+ * resolution motion vector referenced by the input parameter pSrcDstMV, i.e.,
+ * the initial integer MV is generated externally. The input parameters
+ * pSrcRefBuf and pSearchPointRefPos should be shifted by the winning MV of
+ * 16x16 integer search prior to calling BlockMatch_Half_16x16. The function
+ * BlockMatch_Integer_16x16 may be used for integer motion estimation.
+ *
+ * Input Arguments:
+ *
+ * pSrcRefBuf - pointer to the reference Y plane; points to the reference
+ * macroblock that corresponds to the location of the current
+ * macroblock in the current plane.
+ * refWidth - width of the reference plane
+ * pRefRect - reference plane valid region rectangle
+ * pSrcCurrBuf - pointer to the current block in the current macroblock
+ * buffer extracted from the original plane (linear array, 256
+ * entries); must be aligned on a 16-byte boundary. The number of
+ * bytes between lines (step) is 16.
+ * pSearchPointRefPos - position of the starting point for half pixel
+ * search (specified in terms of integer pixel units) in the
+ * reference plane, i.e., the reference position pointed to by the
+ * predicted motion vector.
+ * rndVal - rounding control parameter: 0 - disabled; 1 - enabled.
+ * pSrcDstMV - pointer to the initial MV estimate; typically generated
+ * during a prior 16X16 integer search; specified in terms of
+ * half-pixel units.
+ *
+ * Output Arguments:
+ *
+ * pSrcDstMV - pointer to estimated MV
+ * pDstSAD - pointer to minimum SAD
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments. Returned if one of the following
+ * conditions is true:
+ * - at least one of the following pointers is NULL: pSrcRefBuf,
+ * pRefRect, pSrcCurrBuff, pSearchPointRefPos, pSrcDstMV.
+ * - pSrcCurrBuf is not 16-byte aligned, or
+ *
+ */
+OMXResult omxVCM4P2_BlockMatch_Half_16x16 (
+ const OMX_U8 *pSrcRefBuf,
+ OMX_INT refWidth,
+ const OMXRect *pRefRect,
+ const OMX_U8 *pSrcCurrBuf,
+ const OMXVCM4P2Coordinate *pSearchPointRefPos,
+ OMX_INT rndVal,
+ OMXVCMotionVector *pSrcDstMV,
+ OMX_INT *pDstSAD
+);
+
+
+
+/**
+ * Function: omxVCM4P2_BlockMatch_Half_8x8 (6.2.4.2.4)
+ *
+ * Description:
+ * Performs an 8x8 block match with half-pixel resolution. Returns the
+ * estimated motion vector and associated minimum SAD. This function
+ * estimates the half-pixel motion vector by interpolating the integer
+ * resolution motion vector referenced by the input parameter pSrcDstMV, i.e.,
+ * the initial integer MV is generated externally. The input parameters
+ * pSrcRefBuf and pSearchPointRefPos should be shifted by the winning MV of
+ * 8x8 integer search prior to calling BlockMatch_Half_8x8. The function
+ * BlockMatch_Integer_8x8 may be used for integer motion estimation.
+ *
+ * Input Arguments:
+ *
+ * pSrcRefBuf - pointer to the reference Y plane; points to the reference
+ * block that corresponds to the location of the current 8x8 block
+ * in the current plane.
+ * refWidth - width of the reference plane
+ * pRefRect - reference plane valid region rectangle
+ * pSrcCurrBuf - pointer to the current block in the current macroblock
+ * buffer extracted from the original plane (linear array, 128
+ * entries); must be aligned on a 8-byte boundary. The number of
+ * bytes between lines (step) is 16.
+ * pSearchPointRefPos - position of the starting point for half pixel
+ * search (specified in terms of integer pixel units) in the
+ * reference plane.
+ * rndVal - rounding control parameter: 0 - disabled; 1 - enabled.
+ * pSrcDstMV - pointer to the initial MV estimate; typically generated
+ * during a prior 8x8 integer search, specified in terms of
+ * half-pixel units.
+ *
+ * Output Arguments:
+ *
+ * pSrcDstMV - pointer to estimated MV
+ * pDstSAD - pointer to minimum SAD
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments. Returned if one of the following
+ * conditions is true:
+ * - at least one of the following pointers is NULL:
+ * pSrcRefBuf, pRefRect, pSrcCurrBuff, pSearchPointRefPos, pSrcDstMV
+ * - pSrcCurrBuf is not 8-byte aligned
+ *
+ */
+OMXResult omxVCM4P2_BlockMatch_Half_8x8 (
+ const OMX_U8 *pSrcRefBuf,
+ OMX_INT refWidth,
+ const OMXRect *pRefRect,
+ const OMX_U8 *pSrcCurrBuf,
+ const OMXVCM4P2Coordinate *pSearchPointRefPos,
+ OMX_INT rndVal,
+ OMXVCMotionVector *pSrcDstMV,
+ OMX_INT *pDstSAD
+);
+
+
+
+/**
+ * Function: omxVCM4P2_MotionEstimationMB (6.2.4.3.1)
+ *
+ * Description:
+ * Performs motion search for a 16x16 macroblock. Selects best motion search
+ * strategy from among inter-1MV, inter-4MV, and intra modes. Supports
+ * integer and half pixel resolution.
+ *
+ * Input Arguments:
+ *
+ * pSrcCurrBuf - pointer to the top-left corner of the current MB in the
+ * original picture plane; must be aligned on a 16-byte boundary.
+ * The function does not expect source data outside the region
+ * bounded by the MB to be available; for example it is not
+ * necessary for the caller to guarantee the availability of
+ * pSrcCurrBuf[-SrcCurrStep], i.e., the row of pixels above the MB
+ * to be processed.
+ * srcCurrStep - width of the original picture plane, in terms of full
+ * pixels; must be a multiple of 16.
+ * pSrcRefBuf - pointer to the reference Y plane; points to the reference
+ * plane location corresponding to the location of the current
+ * macroblock in the current plane; must be aligned on a 16-byte
+ * boundary.
+ * srcRefStep - width of the reference picture plane, in terms of full
+ * pixels; must be a multiple of 16.
+ * pRefRect - reference plane valid region rectangle, specified relative to
+ * the image origin
+ * pCurrPointPos - position of the current macroblock in the current plane
+ * pMESpec - pointer to the vendor-specific motion estimation specification
+ * structure; must be allocated and then initialized using
+ * omxVCM4P2_MEInit prior to calling this function.
+ * pMBInfo - array, of dimension four, containing pointers to information
+ * associated with four nearby MBs:
+ * - pMBInfo[0] - pointer to left MB information
+ * - pMBInfo[1] - pointer to top MB information
+ * - pMBInfo[2] - pointer to top-left MB information
+ * - pMBInfo[3] - pointer to top-right MB information
+ * Any pointer in the array may be set equal to NULL if the
+ * corresponding MB doesn't exist. For each MB, the following structure
+ * members are used:
+ * - mbType - macroblock type, either OMX_VC_INTRA, OMX_VC_INTER, or
+ * OMX_VC_INTER4V
+ * - pMV0[2][2] - estimated motion vectors; represented
+ * in 1/2 pixel units
+ * - sliceID - number of the slice to which the MB belongs
+ * pSrcDstMBCurr - pointer to information structure for the current MB.
+ * The following entries should be set prior to calling the
+ * function: sliceID - the number of the slice the to which the
+ * current MB belongs. The structure elements cbpy and cbpc are
+ * ignored.
+ *
+ * Output Arguments:
+ *
+ * pSrcDstMBCurr - pointer to updated information structure for the current
+ * MB after MB-level motion estimation has been completed. The
+ * following structure members are updated by the ME function:
+ * - mbType - macroblock type: OMX_VC_INTRA, OMX_VC_INTER, or
+ * OMX_VC_INTER4V.
+ * - pMV0[2][2] - estimated motion vectors; represented in
+ * terms of 1/2 pel units.
+ * - pMVPred[2][2] - predicted motion vectors; represented
+ * in terms of 1/2 pel units.
+ * The structure members cbpy and cbpc are not updated by the function.
+ * pDstSAD - pointer to the minimum SAD for INTER1V, or sum of minimum SADs
+ * for INTER4V
+ * pDstBlockSAD - pointer to an array of SAD values for each of the four
+ * 8x8 luma blocks in the MB. The block SADs are in scan order for
+ * each MB.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments. Returned if one or more of the
+ * following conditions is true:
+ * - at least one of the following pointers is NULL: pSrcCurrBuf,
+ * pSrcRefBuf, pRefRect, pCurrPointPos, pMBInter, pMBIntra,
+ * pSrcDstMBCurr, or pDstSAD.
+ *
+ */
+OMXResult omxVCM4P2_MotionEstimationMB (
+ const OMX_U8 *pSrcCurrBuf,
+ OMX_S32 srcCurrStep,
+ const OMX_U8 *pSrcRefBuf,
+ OMX_S32 srcRefStep,
+ const OMXRect*pRefRect,
+ const OMXVCM4P2Coordinate *pCurrPointPos,
+ void *pMESpec,
+ const OMXVCM4P2MBInfoPtr *pMBInfo,
+ OMXVCM4P2MBInfo *pSrcDstMBCurr,
+ OMX_U16 *pDstSAD,
+ OMX_U16 *pDstBlockSAD
+);
+
+
+
+/**
+ * Function: omxVCM4P2_DCT8x8blk (6.2.4.4.1)
+ *
+ * Description:
+ * Computes a 2D forward DCT for a single 8x8 block, as defined in
+ * [ISO14496-2].
+ *
+ * Input Arguments:
+ *
+ * pSrc - pointer to the start of the linearly arranged input buffer; must
+ * be aligned on a 16-byte boundary. Input values (pixel
+ * intensities) are valid in the range [-255,255].
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the start of the linearly arranged output buffer; must
+ * be aligned on a 16-byte boundary.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments, returned if:
+ * - pSrc or pDst is NULL.
+ * - pSrc or pDst is not 16-byte aligned.
+ *
+ */
+OMXResult omxVCM4P2_DCT8x8blk (
+ const OMX_S16 *pSrc,
+ OMX_S16 *pDst
+);
+
+
+
+/**
+ * Function: omxVCM4P2_QuantIntra_I (6.2.4.4.2)
+ *
+ * Description:
+ * Performs quantization on intra block coefficients. This function supports
+ * bits_per_pixel == 8.
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - pointer to the input intra block coefficients; must be aligned
+ * on a 16-byte boundary.
+ * QP - quantization parameter (quantizer_scale).
+ * blockIndex - block index indicating the component type and position,
+ * valid in the range 0 to 5, as defined in [ISO14496-2], subclause
+ * 6.1.3.8.
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; shortVideoHeader==1 selects linear intra DC
+ * mode, and shortVideoHeader==0 selects non linear intra DC mode.
+ *
+ * Output Arguments:
+ *
+ * pSrcDst - pointer to the output (quantized) interblock coefficients.
+ * When shortVideoHeader==1, AC coefficients are saturated on the
+ * interval [-127, 127], and DC coefficients are saturated on the
+ * interval [1, 254]. When shortVideoHeader==0, AC coefficients
+ * are saturated on the interval [-2047, 2047].
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments:
+ * - pSrcDst is NULL.
+ * - blockIndex < 0 or blockIndex >= 10
+ * - QP <= 0 or QP >= 32.
+ *
+ */
+OMXResult omxVCM4P2_QuantIntra_I (
+ OMX_S16 *pSrcDst,
+ OMX_U8 QP,
+ OMX_INT blockIndex,
+ OMX_INT shortVideoHeader
+);
+
+
+
+/**
+ * Function: omxVCM4P2_QuantInter_I (6.2.4.4.3)
+ *
+ * Description:
+ * Performs quantization on an inter coefficient block; supports
+ * bits_per_pixel == 8.
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - pointer to the input inter block coefficients; must be aligned
+ * on a 16-byte boundary.
+ * QP - quantization parameter (quantizer_scale)
+ * shortVideoHeader - binary flag indicating presence of short_video_header;
+ * shortVideoHeader==1 selects linear intra DC mode, and
+ * shortVideoHeader==0 selects non linear intra DC mode.
+ *
+ * Output Arguments:
+ *
+ * pSrcDst - pointer to the output (quantized) interblock coefficients.
+ * When shortVideoHeader==1, AC coefficients are saturated on the
+ * interval [-127, 127], and DC coefficients are saturated on the
+ * interval [1, 254]. When shortVideoHeader==0, AC coefficients
+ * are saturated on the interval [-2047, 2047].
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments:
+ * - pSrcDst is NULL.
+ * - QP <= 0 or QP >= 32.
+ *
+ */
+OMXResult omxVCM4P2_QuantInter_I (
+ OMX_S16 *pSrcDst,
+ OMX_U8 QP,
+ OMX_INT shortVideoHeader
+);
+
+
+
+/**
+ * Function: omxVCM4P2_TransRecBlockCoef_intra (6.2.4.4.4)
+ *
+ * Description:
+ * Quantizes the DCT coefficients, implements intra block AC/DC coefficient
+ * prediction, and reconstructs the current intra block texture for prediction
+ * on the next frame. Quantized row and column coefficients are returned in
+ * the updated coefficient buffers.
+ *
+ * Input Arguments:
+ *
+ * pSrc - pointer to the pixels of current intra block; must be aligned on
+ * an 8-byte boundary.
+ * pPredBufRow - pointer to the coefficient row buffer containing
+ * ((num_mb_per_row * 2 + 1) * 8) elements of type OMX_S16.
+ * Coefficients are organized into blocks of eight as described
+ * below (Internal Prediction Coefficient Update Procedures). The
+ * DC coefficient is first, and the remaining buffer locations
+ * contain the quantized AC coefficients. Each group of eight row
+ * buffer elements combined with one element eight elements ahead
+ * contains the coefficient predictors of the neighboring block
+ * that is spatially above or to the left of the block currently to
+ * be decoded. A negative-valued DC coefficient indicates that this
+ * neighboring block is not INTRA-coded or out of bounds, and
+ * therefore the AC and DC coefficients are invalid. Pointer must
+ * be aligned on an 8-byte boundary.
+ * pPredBufCol - pointer to the prediction coefficient column buffer
+ * containing 16 elements of type OMX_S16. Coefficients are
+ * organized as described in section 6.2.2.5. Pointer must be
+ * aligned on an 8-byte boundary.
+ * pSumErr - pointer to a flag indicating whether or not AC prediction is
+ * required; AC prediction is enabled if *pSumErr >=0, but the
+ * value is not used for coefficient prediction, i.e., the sum of
+ * absolute differences starts from 0 for each call to this
+ * function. Otherwise AC prediction is disabled if *pSumErr < 0 .
+ * blockIndex - block index indicating the component type and position, as
+ * defined in [ISO14496-2], subclause 6.1.3.8.
+ * curQp - quantization parameter of the macroblock to which the current
+ * block belongs
+ * pQpBuf - pointer to a 2-element quantization parameter buffer; pQpBuf[0]
+ * contains the quantization parameter associated with the 8x8
+ * block left of the current block (QPa), and pQpBuf[1] contains
+ * the quantization parameter associated with the 8x8 block above
+ * the current block (QPc). In the event that the corresponding
+ * block is outside of the VOP bound, the Qp value will not affect
+ * the intra prediction process, as described in [ISO14496-2],
+ * sub-clause 7.4.3.3, Adaptive AC Coefficient Prediction.
+ * srcStep - width of the source buffer; must be a multiple of 8.
+ * dstStep - width of the reconstructed destination buffer; must be a
+ * multiple of 16.
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; shortVideoHeader==1 selects linear intra DC
+ * mode, and shortVideoHeader==0 selects non linear intra DC mode.
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the quantized DCT coefficient buffer; pDst[0] contains
+ * the predicted DC coefficient; the remaining entries contain the
+ * quantized AC coefficients (without prediction). The pointer
+ * pDstmust be aligned on a 16-byte boundary.
+ * pRec - pointer to the reconstructed texture; must be aligned on an
+ * 8-byte boundary.
+ * pPredBufRow - pointer to the updated coefficient row buffer
+ * pPredBufCol - pointer to the updated coefficient column buffer
+ * pPreACPredict - if prediction is enabled, the parameter points to the
+ * start of the buffer containing the coefficient differences for
+ * VLC encoding. The entry pPreACPredict[0]indicates prediction
+ * direction for the current block and takes one of the following
+ * values: OMX_VC_NONE (prediction disabled), OMX_VC_HORIZONTAL, or
+ * OMX_VC_VERTICAL. The entries
+ * pPreACPredict[1]-pPreACPredict[7]contain predicted AC
+ * coefficients. If prediction is disabled (*pSumErr<0) then the
+ * contents of this buffer are undefined upon return from the
+ * function
+ * pSumErr - pointer to the value of the accumulated AC coefficient errors,
+ * i.e., sum of the absolute differences between predicted and
+ * unpredicted AC coefficients
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - Bad arguments:
+ * - At least one of the following pointers is NULL: pSrc, pDst, pRec,
+ * pCoefBufRow, pCoefBufCol, pQpBuf, pPreACPredict, pSumErr.
+ * - blockIndex < 0 or blockIndex >= 10;
+ * - curQP <= 0 or curQP >= 32.
+ * - srcStep, or dstStep <= 0 or not a multiple of 8.
+ * - pDst is not 16-byte aligned: .
+ * - At least one of the following pointers is not 8-byte aligned:
+ * pSrc, pRec.
+ *
+ * Note: The coefficient buffers must be updated in accordance with the
+ * update procedures defined in section in 6.2.2.
+ *
+ */
+OMXResult omxVCM4P2_TransRecBlockCoef_intra (
+ const OMX_U8 *pSrc,
+ OMX_S16 *pDst,
+ OMX_U8 *pRec,
+ OMX_S16 *pPredBufRow,
+ OMX_S16 *pPredBufCol,
+ OMX_S16 *pPreACPredict,
+ OMX_INT *pSumErr,
+ OMX_INT blockIndex,
+ OMX_U8 curQp,
+ const OMX_U8 *pQpBuf,
+ OMX_INT srcStep,
+ OMX_INT dstStep,
+ OMX_INT shortVideoHeader
+);
+
+
+
+/**
+ * Function: omxVCM4P2_TransRecBlockCoef_inter (6.2.4.4.5)
+ *
+ * Description:
+ * Implements DCT, and quantizes the DCT coefficients of the inter block
+ * while reconstructing the texture residual. There is no boundary check for
+ * the bit stream buffer.
+ *
+ * Input Arguments:
+ *
+ * pSrc -pointer to the residuals to be encoded; must be aligned on an
+ * 16-byte boundary.
+ * QP - quantization parameter.
+ * shortVideoHeader - binary flag indicating presence of short_video_header;
+ * shortVideoHeader==1 selects linear intra DC mode, and
+ * shortVideoHeader==0 selects non linear intra DC mode.
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the quantized DCT coefficients buffer; must be aligned
+ * on a 16-byte boundary.
+ * pRec - pointer to the reconstructed texture residuals; must be aligned
+ * on a 16-byte boundary.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments:
+ * - At least one of the following pointers is either NULL or
+ * not 16-byte aligned:
+ * - pSrc
+ * - pDst
+ * - pRec
+ * - QP <= 0 or QP >= 32.
+ *
+ */
+OMXResult omxVCM4P2_TransRecBlockCoef_inter (
+ const OMX_S16 *pSrc,
+ OMX_S16 *pDst,
+ OMX_S16 *pRec,
+ OMX_U8 QP,
+ OMX_INT shortVideoHeader
+);
+
+
+
+/**
+ * Function: omxVCM4P2_EncodeVLCZigzag_IntraDCVLC (6.2.4.5.2)
+ *
+ * Description:
+ * Performs zigzag scan and VLC encoding of AC and DC coefficients for one
+ * intra block. Two versions of the function (DCVLC and ACVLC) are provided
+ * in order to support the two different methods of processing DC
+ * coefficients, as described in [ISO14496-2], subclause 7.4.1.4, "Intra DC
+ * Coefficient Decoding for the Case of Switched VLC Encoding".
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - double pointer to the current byte in the bitstream
+ * pBitOffset - pointer to the bit position in the byte pointed by
+ * *ppBitStream. Valid within 0 to 7.
+ * pQDctBlkCoef - pointer to the quantized DCT coefficient
+ * predDir - AC prediction direction, which is used to decide the zigzag
+ * scan pattern; takes one of the following values:
+ * - OMX_VC_NONE - AC prediction not used.
+ * Performs classical zigzag scan.
+ * - OMX_VC_HORIZONTAL - Horizontal prediction.
+ * Performs alternate-vertical zigzag scan.
+ * - OMX_VC_VERTICAL - Vertical prediction.
+ * Performs alternate-horizontal zigzag scan.
+ * pattern - block pattern which is used to decide whether this block is
+ * encoded
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; escape modes 0-3 are used if
+ * shortVideoHeader==0, and escape mode 4 is used when
+ * shortVideoHeader==1.
+ * videoComp - video component type (luminance, chrominance) of the current
+ * block
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after the block is encoded, so
+ * that it points to the current byte in the bit stream buffer.
+ * pBitOffset - *pBitOffset is updated so that it points to the current bit
+ * position in the byte pointed by *ppBitStream.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - Bad arguments:
+ * - At least one of the following pointers is NULL: ppBitStream,
+ * *ppBitStream, pBitOffset, pQDctBlkCoef.
+ * - *pBitOffset < 0, or *pBitOffset >7.
+ * - PredDir is not one of: OMX_VC_NONE, OMX_VC_HORIZONTAL, or
+ * OMX_VC_VERTICAL.
+ * - VideoComp is not one component of enum OMXVCM4P2VideoComponent.
+ *
+ */
+OMXResult omxVCM4P2_EncodeVLCZigzag_IntraDCVLC (
+ OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ const OMX_S16 *pQDctBlkCoef,
+ OMX_U8 predDir,
+ OMX_U8 pattern,
+ OMX_INT shortVideoHeader,
+ OMXVCM4P2VideoComponent videoComp
+);
+
+
+
+/**
+ * Function: omxVCM4P2_EncodeVLCZigzag_IntraACVLC (6.2.4.5.2)
+ *
+ * Description:
+ * Performs zigzag scan and VLC encoding of AC and DC coefficients for one
+ * intra block. Two versions of the function (DCVLC and ACVLC) are provided
+ * in order to support the two different methods of processing DC
+ * coefficients, as described in [ISO14496-2], subclause 7.4.1.4, Intra DC
+ * Coefficient Decoding for the Case of Switched VLC Encoding.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - double pointer to the current byte in the bitstream
+ * pBitOffset - pointer to the bit position in the byte pointed by
+ * *ppBitStream. Valid within 0 to 7.
+ * pQDctBlkCoef - pointer to the quantized DCT coefficient
+ * predDir - AC prediction direction, which is used to decide the zigzag
+ * scan pattern; takes one of the following values:
+ * - OMX_VC_NONE - AC prediction not used.
+ * Performs classical zigzag scan.
+ * - OMX_VC_HORIZONTAL - Horizontal prediction.
+ * Performs alternate-vertical zigzag scan.
+ * - OMX_VC_VERTICAL - Vertical prediction.
+ * Performs alternate-horizontal zigzag scan.
+ * pattern - block pattern which is used to decide whether this block is
+ * encoded
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; escape modes 0-3 are used if
+ * shortVideoHeader==0, and escape mode 4 is used when
+ * shortVideoHeader==1.
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after the block is encoded, so
+ * that it points to the current byte in the bit stream buffer.
+ * pBitOffset - *pBitOffset is updated so that it points to the current bit
+ * position in the byte pointed by *ppBitStream.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - Bad arguments:
+ * - At least one of the following pointers is NULL: ppBitStream,
+ * *ppBitStream, pBitOffset, pQDctBlkCoef.
+ * - *pBitOffset < 0, or *pBitOffset >7.
+ * - PredDir is not one of: OMX_VC_NONE, OMX_VC_HORIZONTAL, or
+ * OMX_VC_VERTICAL.
+ * - VideoComp is not one component of enum OMXVCM4P2VideoComponent.
+ *
+ */
+OMXResult omxVCM4P2_EncodeVLCZigzag_IntraACVLC (
+ OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ const OMX_S16 *pQDctBlkCoef,
+ OMX_U8 predDir,
+ OMX_U8 pattern,
+ OMX_INT shortVideoHeader
+);
+
+
+
+/**
+ * Function: omxVCM4P2_EncodeVLCZigzag_Inter (6.2.4.5.3)
+ *
+ * Description:
+ * Performs classical zigzag scanning and VLC encoding for one inter block.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - pointer to the pointer to the current byte in the bit
+ * stream
+ * pBitOffset - pointer to the bit position in the byte pointed by
+ * *ppBitStream. Valid within 0 to 7
+ * pQDctBlkCoef - pointer to the quantized DCT coefficient
+ * pattern - block pattern which is used to decide whether this block is
+ * encoded
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; escape modes 0-3 are used if
+ * shortVideoHeader==0, and escape mode 4 is used when
+ * shortVideoHeader==1.
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after the block is encoded so that
+ * it points to the current byte in the bit stream buffer.
+ * pBitOffset - *pBitOffset is updated so that it points to the current bit
+ * position in the byte pointed by *ppBitStream.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - Bad arguments
+ * - At least one of the pointers: is NULL: ppBitStream, *ppBitStream,
+ * pBitOffset, pQDctBlkCoef
+ * - *pBitOffset < 0, or *pBitOffset >7.
+ *
+ */
+OMXResult omxVCM4P2_EncodeVLCZigzag_Inter (
+ OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ const OMX_S16 *pQDctBlkCoef,
+ OMX_U8 pattern,
+ OMX_INT shortVideoHeader
+);
+
+
+
+/**
+ * Function: omxVCM4P2_EncodeMV (6.2.4.5.4)
+ *
+ * Description:
+ * Predicts a motion vector for the current macroblock, encodes the
+ * difference, and writes the output to the stream buffer. The input MVs
+ * pMVCurMB, pSrcMVLeftMB, pSrcMVUpperMB, and pSrcMVUpperRightMB should lie
+ * within the ranges associated with the input parameter fcodeForward, as
+ * described in [ISO14496-2], subclause 7.6.3. This function provides a
+ * superset of the functionality associated with the function
+ * omxVCM4P2_FindMVpred.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - double pointer to the current byte in the bitstream buffer
+ * pBitOffset - index of the first free (next available) bit in the stream
+ * buffer referenced by *ppBitStream, valid in the range 0 to 7.
+ * pMVCurMB - pointer to the current macroblock motion vector; a value of
+ * NULL indicates unavailability.
+ * pSrcMVLeftMB - pointer to the source left macroblock motion vector; a
+ * value of NULLindicates unavailability.
+ * pSrcMVUpperMB - pointer to source upper macroblock motion vector; a
+ * value of NULL indicates unavailability.
+ * pSrcMVUpperRightMB - pointer to source upper right MB motion vector; a
+ * value of NULL indicates unavailability.
+ * fcodeForward - an integer with values from 1 to 7; used in encoding
+ * motion vectors related to search range, as described in
+ * [ISO14496-2], subclause 7.6.3.
+ * MBType - macro block type, valid in the range 0 to 5
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - updated pointer to the current byte in the bit stream
+ * buffer
+ * pBitOffset - updated index of the next available bit position in stream
+ * buffer referenced by *ppBitStream
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments
+ * - At least one of the following pointers is NULL: ppBitStream,
+ * *ppBitStream, pBitOffset, pMVCurMB
+ * - *pBitOffset < 0, or *pBitOffset >7.
+ * - fcodeForward <= 0, or fcodeForward > 7, or MBType < 0.
+ *
+ */
+OMXResult omxVCM4P2_EncodeMV (
+ OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ const OMXVCMotionVector *pMVCurMB,
+ const OMXVCMotionVector*pSrcMVLeftMB,
+ const OMXVCMotionVector *pSrcMVUpperMB,
+ const OMXVCMotionVector *pSrcMVUpperRightMB,
+ OMX_INT fcodeForward,
+ OMXVCM4P2MacroblockType MBType
+);
+
+
+
+/**
+ * Function: omxVCM4P2_DecodePadMV_PVOP (6.2.5.1.1)
+ *
+ * Description:
+ * Decodes and pads the four motion vectors associated with a non-intra P-VOP
+ * macroblock. For macroblocks of type OMX_VC_INTER4V, the output MV is
+ * padded as specified in [ISO14496-2], subclause 7.6.1.6. Otherwise, for
+ * macroblocks of types other than OMX_VC_INTER4V, the decoded MV is copied to
+ * all four output MV buffer entries.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - pointer to the pointer to the current byte in the bit
+ * stream buffer
+ * pBitOffset - pointer to the bit position in the byte pointed to by
+ * *ppBitStream. *pBitOffset is valid within [0-7].
+ * pSrcMVLeftMB, pSrcMVUpperMB, and pSrcMVUpperRightMB - pointers to the
+ * motion vector buffers of the macroblocks specially at the left,
+ * upper, and upper-right side of the current macroblock,
+ * respectively; a value of NULL indicates unavailability. Note:
+ * Any neighborhood macroblock outside the current VOP or video
+ * packet or outside the current GOB (when short_video_header is
+ * 1 ) for which gob_header_empty is 0 is treated as
+ * transparent, according to [ISO14496-2], subclause 7.6.5.
+ * fcodeForward - a code equal to vop_fcode_forward in MPEG-4 bit stream
+ * syntax
+ * MBType - the type of the current macroblock. If MBType is not equal to
+ * OMX_VC_INTER4V, the destination motion vector buffer is still
+ * filled with the same decoded vector.
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after the block is decoded, so
+ * that it points to the current byte in the bit stream buffer
+ * pBitOffset - *pBitOffset is updated so that it points to the current bit
+ * position in the byte pointed by *ppBitStream
+ * pDstMVCurMB - pointer to the motion vector buffer for the current
+ * macroblock; contains four decoded motion vectors
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments:
+ * - At least one of the following pointers is NULL:
+ * ppBitStream, *ppBitStream, pBitOffset, pDstMVCurMB
+ * - *pBitOffset exceeds [0,7]
+ * - fcodeForward exceeds (0,7]
+ * - MBType less than zero
+ * - motion vector buffer is not 4-byte aligned.
+ * OMX_Sts_Err - status error
+ *
+ */
+OMXResult omxVCM4P2_DecodePadMV_PVOP (
+ const OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ OMXVCMotionVector *pSrcMVLeftMB,
+ OMXVCMotionVector*pSrcMVUpperMB,
+ OMXVCMotionVector *pSrcMVUpperRightMB,
+ OMXVCMotionVector*pDstMVCurMB,
+ OMX_INT fcodeForward,
+ OMXVCM4P2MacroblockType MBType
+);
+
+
+
+/**
+ * Function: omxVCM4P2_DecodeVLCZigzag_IntraDCVLC (6.2.5.2.2)
+ *
+ * Description:
+ * Performs VLC decoding and inverse zigzag scan of AC and DC coefficients
+ * for one intra block. Two versions of the function (DCVLC and ACVLC) are
+ * provided in order to support the two different methods of processing DC
+ * coefficients, as described in [ISO14496-2], subclause 7.4.1.4, Intra DC
+ * Coefficient Decoding for the Case of Switched VLC Encoding.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - pointer to the pointer to the current byte in the
+ * bitstream buffer
+ * pBitOffset - pointer to the bit position in the current byte referenced
+ * by *ppBitStream. The parameter *pBitOffset is valid in the
+ * range [0-7].
+ * Bit Position in one byte: |Most Least|
+ * *pBitOffset |0 1 2 3 4 5 6 7|
+ * predDir - AC prediction direction; used to select the zigzag scan
+ * pattern; takes one of the following values:
+ * - OMX_VC_NONE - AC prediction not used;
+ * performs classical zigzag scan.
+ * - OMX_VC_HORIZONTAL - Horizontal prediction;
+ * performs alternate-vertical zigzag scan;
+ * - OMX_VC_VERTICAL - Vertical prediction;
+ * performs alternate-horizontal zigzag scan.
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; escape modes 0-3 are used if
+ * shortVideoHeader==0, and escape mode 4 is used when
+ * shortVideoHeader==1.
+ * videoComp - video component type (luminance or chrominance) of the
+ * current block
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after the block is decoded such
+ * that it points to the current byte in the bit stream buffer
+ * pBitOffset - *pBitOffset is updated such that it points to the current
+ * bit position in the byte pointed by *ppBitStream
+ * pDst - pointer to the coefficient buffer of current block; must be
+ * 4-byte aligned.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments, if:
+ * - At least one of the following pointers is NULL:
+ * ppBitStream, *ppBitStream, pBitOffset, pDst
+ * - *pBitOffset exceeds [0,7]
+ * - preDir exceeds [0,2]
+ * - pDst is not 4-byte aligned
+ * OMX_Sts_Err - if:
+ * - In DecodeVLCZigzag_IntraDCVLC, dc_size > 12
+ * - At least one of mark bits equals zero
+ * - Illegal stream encountered; code cannot be located in VLC table
+ * - Forbidden code encountered in the VLC FLC table.
+ * - The number of coefficients is greater than 64
+ *
+ */
+OMXResult omxVCM4P2_DecodeVLCZigzag_IntraDCVLC (
+ const OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ OMX_S16 *pDst,
+ OMX_U8 predDir,
+ OMX_INT shortVideoHeader,
+ OMXVCM4P2VideoComponent videoComp
+);
+
+
+
+/**
+ * Function: omxVCM4P2_DecodeVLCZigzag_IntraACVLC (6.2.5.2.2)
+ *
+ * Description:
+ * Performs VLC decoding and inverse zigzag scan of AC and DC coefficients
+ * for one intra block. Two versions of the function (DCVLC and ACVLC) are
+ * provided in order to support the two different methods of processing DC
+ * coefficients, as described in [ISO14496-2], subclause 7.4.1.4, Intra DC
+ * Coefficient Decoding for the Case of Switched VLC Encoding.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - pointer to the pointer to the current byte in the
+ * bitstream buffer
+ * pBitOffset - pointer to the bit position in the current byte referenced
+ * by *ppBitStream. The parameter *pBitOffset is valid in the
+ * range [0-7]. Bit Position in one byte: |Most Least| *pBitOffset
+ * |0 1 2 3 4 5 6 7|
+ * predDir - AC prediction direction; used to select the zigzag scan
+ * pattern; takes one of the following values: OMX_VC_NONE - AC
+ * prediction not used; performs classical zigzag scan.
+ * OMX_VC_HORIZONTAL - Horizontal prediction; performs
+ * alternate-vertical zigzag scan; OMX_VC_VERTICAL - Vertical
+ * prediction; performs alternate-horizontal zigzag scan.
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; escape modes 0-3 are used if
+ * shortVideoHeader==0, and escape mode 4 is used when
+ * shortVideoHeader==1.
+ * videoComp - video component type (luminance or chrominance) of the
+ * current block
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after the block is decoded such
+ * that it points to the current byte in the bit stream buffer
+ * pBitOffset - *pBitOffset is updated such that it points to the current
+ * bit position in the byte pointed by *ppBitStream
+ * pDst - pointer to the coefficient buffer of current block; must be
+ * 4-byte aligned.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments At least one of the following
+ * pointers is NULL: ppBitStream, *ppBitStream, pBitOffset, pDst,
+ * or At least one of the following conditions is true:
+ * *pBitOffset exceeds [0,7], preDir exceeds [0,2], or pDst is
+ * not 4-byte aligned
+ * OMX_Sts_Err In DecodeVLCZigzag_IntraDCVLC, dc_size > 12 At least one of
+ * mark bits equals zero Illegal stream encountered; code cannot
+ * be located in VLC table Forbidden code encountered in the VLC
+ * FLC table The number of coefficients is greater than 64
+ *
+ */
+OMXResult omxVCM4P2_DecodeVLCZigzag_IntraACVLC (
+ const OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ OMX_S16 *pDst,
+ OMX_U8 predDir,
+ OMX_INT shortVideoHeader
+);
+
+
+
+/**
+ * Function: omxVCM4P2_DecodeVLCZigzag_Inter (6.2.5.2.3)
+ *
+ * Description:
+ * Performs VLC decoding and inverse zigzag scan for one inter-coded block.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - double pointer to the current byte in the stream buffer
+ * pBitOffset - pointer to the next available bit in the current stream
+ * byte referenced by *ppBitStream. The parameter *pBitOffset is
+ * valid within the range [0-7].
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; escape modes 0-3 are used if
+ * shortVideoHeader==0, and escape mode 4 is used when
+ * shortVideoHeader==1.
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after the block is decoded such
+ * that it points to the current byte in the stream buffer
+ * pBitOffset - *pBitOffset is updated after decoding such that it points
+ * to the next available bit in the stream byte referenced by
+ * *ppBitStream
+ * pDst - pointer to the coefficient buffer of current block; must be
+ * 4-byte aligned.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_BadArgErr - bad arguments:
+ * - At least one of the following pointers is NULL:
+ * ppBitStream, *ppBitStream, pBitOffset, pDst
+ * - pDst is not 4-byte aligned
+ * - *pBitOffset exceeds [0,7]
+ * OMX_Sts_Err - status error, if:
+ * - At least one mark bit is equal to zero
+ * - Encountered an illegal stream code that cannot be found in the VLC table
+ * - Encountered an illegal code in the VLC FLC table
+ * - The number of coefficients is greater than 64
+ *
+ */
+OMXResult omxVCM4P2_DecodeVLCZigzag_Inter (
+ const OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ OMX_S16 *pDst,
+ OMX_INT shortVideoHeader
+);
+
+
+
+/**
+ * Function: omxVCM4P2_QuantInvIntra_I (6.2.5.3.2)
+ *
+ * Description:
+ * Performs the second inverse quantization mode on an intra/inter coded
+ * block. Supports bits_per_pixel = 8. The output coefficients are clipped to
+ * the range [-2048, 2047].
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - pointer to the input (quantized) intra/inter block; must be
+ * aligned on a 16-byte boundary.
+ * QP - quantization parameter (quantizer_scale)
+ * videoComp - video component type of the current block. Takes one of the
+ * following flags: OMX_VC_LUMINANCE, OMX_VC_CHROMINANCE (intra
+ * version only).
+ * shortVideoHeader - binary flag indicating presence of short_video_header
+ * (intra version only).
+ *
+ * Output Arguments:
+ *
+ * pSrcDst - pointer to the output (dequantized) intra/inter block
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; one or more of the following is
+ * true:
+ * - pSrcDst is NULL
+ * - QP <= 0 or QP >=31
+ * - videoComp is neither OMX_VC_LUMINANCE nor OMX_VC_CHROMINANCE.
+ *
+ */
+OMXResult omxVCM4P2_QuantInvIntra_I (
+ OMX_S16 *pSrcDst,
+ OMX_INT QP,
+ OMXVCM4P2VideoComponent videoComp,
+ OMX_INT shortVideoHeader
+);
+
+
+
+/**
+ * Function: omxVCM4P2_QuantInvInter_I (6.2.5.3.2)
+ *
+ * Description:
+ * Performs the second inverse quantization mode on an intra/inter coded
+ * block. Supports bits_per_pixel = 8. The output coefficients are clipped to
+ * the range [-2048, 2047].
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - pointer to the input (quantized) intra/inter block; must be
+ * aligned on a 16-byte boundary.
+ * QP - quantization parameter (quantizer_scale)
+ * videoComp - video component type of the current block. Takes one of the
+ * following flags: OMX_VC_LUMINANCE, OMX_VC_CHROMINANCE (intra
+ * version only).
+ * shortVideoHeader - binary flag indicating presence of short_video_header
+ * (intra version only).
+ *
+ * Output Arguments:
+ *
+ * pSrcDst - pointer to the output (dequantized) intra/inter block
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; one or more of the following is
+ * true:
+ * - pSrcDst is NULL
+ * - QP <= 0 or QP >=31
+ * - videoComp is neither OMX_VC_LUMINANCE nor OMX_VC_CHROMINANCE.
+ *
+ */
+OMXResult omxVCM4P2_QuantInvInter_I (
+ OMX_S16 *pSrcDst,
+ OMX_INT QP
+);
+
+
+
+/**
+ * Function: omxVCM4P2_DecodeBlockCoef_Intra (6.2.5.4.1)
+ *
+ * Description:
+ * Decodes the INTRA block coefficients. Inverse quantization, inversely
+ * zigzag positioning, and IDCT, with appropriate clipping on each step, are
+ * performed on the coefficients. The results are then placed in the output
+ * frame/plane on a pixel basis. Note: This function will be used only when
+ * at least one non-zero AC coefficient of current block exists in the bit
+ * stream. The DC only condition will be handled in another function.
+ *
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - pointer to the pointer to the current byte in the bit
+ * stream buffer. There is no boundary check for the bit stream
+ * buffer.
+ * pBitOffset - pointer to the bit position in the byte pointed to by
+ * *ppBitStream. *pBitOffset is valid within [0-7].
+ * step - width of the destination plane
+ * pCoefBufRow - pointer to the coefficient row buffer; must be aligned on
+ * an 8-byte boundary.
+ * pCoefBufCol - pointer to the coefficient column buffer; must be aligned
+ * on an 8-byte boundary.
+ * curQP - quantization parameter of the macroblock which the current block
+ * belongs to
+ * pQPBuf - pointer to the quantization parameter buffer
+ * blockIndex - block index indicating the component type and position as
+ * defined in [ISO14496-2], subclause 6.1.3.8, Figure 6-5.
+ * intraDCVLC - a code determined by intra_dc_vlc_thr and QP. This allows a
+ * mechanism to switch between two VLC for coding of Intra DC
+ * coefficients as per [ISO14496-2], Table 6-21.
+ * ACPredFlag - a flag equal to ac_pred_flag (of luminance) indicating if
+ * the ac coefficients of the first row or first column are
+ * differentially coded for intra coded macroblock.
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; shortVideoHeader==1 selects linear intra DC
+ * mode, and shortVideoHeader==0 selects non linear intra DC mode.
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after the block is decoded, so
+ * that it points to the current byte in the bit stream buffer
+ * pBitOffset - *pBitOffset is updated so that it points to the current bit
+ * position in the byte pointed by *ppBitStream
+ * pDst - pointer to the block in the destination plane; must be aligned on
+ * an 8-byte boundary.
+ * pCoefBufRow - pointer to the updated coefficient row buffer.
+ * pCoefBufCol - pointer to the updated coefficient column buffer Note:
+ * The coefficient buffers must be updated in accordance with the
+ * update procedure defined in section 6.2.2.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments, if:
+ * - At least one of the following pointers is NULL:
+ * ppBitStream, *ppBitStream, pBitOffset, pCoefBufRow, pCoefBufCol,
+ * pQPBuf, pDst.
+ * - *pBitOffset exceeds [0,7]
+ * - curQP exceeds (1, 31)
+ * - blockIndex exceeds [0,5]
+ * - step is not the multiple of 8
+ * - a pointer alignment requirement was violated.
+ * OMX_Sts_Err - status error. Refer to OMX_Sts_Err of DecodeVLCZigzag_Intra.
+ *
+ */
+OMXResult omxVCM4P2_DecodeBlockCoef_Intra (
+ const OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ OMX_U8 *pDst,
+ OMX_INT step,
+ OMX_S16 *pCoefBufRow,
+ OMX_S16 *pCoefBufCol,
+ OMX_U8 curQP,
+ const OMX_U8 *pQPBuf,
+ OMX_INT blockIndex,
+ OMX_INT intraDCVLC,
+ OMX_INT ACPredFlag,
+ OMX_INT shortVideoHeader
+);
+
+
+
+/**
+ * Function: omxVCM4P2_DecodeBlockCoef_Inter (6.2.5.4.2)
+ *
+ * Description:
+ * Decodes the INTER block coefficients. This function performs inverse
+ * quantization, inverse zigzag positioning, and IDCT (with appropriate
+ * clipping on each step) on the coefficients. The results (residuals) are
+ * placed in a contiguous array of 64 elements. For INTER block, the output
+ * buffer holds the residuals for further reconstruction.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - pointer to the pointer to the current byte in the bit
+ * stream buffer. There is no boundary check for the bit stream
+ * buffer.
+ * pBitOffset - pointer to the bit position in the byte pointed to by
+ * *ppBitStream. *pBitOffset is valid within [0-7]
+ * QP - quantization parameter
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; shortVideoHeader==1 selects linear intra DC
+ * mode, and shortVideoHeader==0 selects non linear intra DC mode.
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after the block is decoded, so
+ * that it points to the current byte in the bit stream buffer
+ * pBitOffset - *pBitOffset is updated so that it points to the current bit
+ * position in the byte pointed by *ppBitStream
+ * pDst - pointer to the decoded residual buffer (a contiguous array of 64
+ * elements of OMX_S16 data type); must be aligned on a 16-byte
+ * boundary.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments, if:
+ * - At least one of the following pointers is Null:
+ * ppBitStream, *ppBitStream, pBitOffset , pDst
+ * - *pBitOffset exceeds [0,7]
+ * - QP <= 0.
+ * - pDst is not 16-byte aligned
+ * OMX_Sts_Err - status error. Refer to OMX_Sts_Err of DecodeVLCZigzag_Inter .
+ *
+ */
+OMXResult omxVCM4P2_DecodeBlockCoef_Inter (
+ const OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ OMX_S16 *pDst,
+ OMX_INT QP,
+ OMX_INT shortVideoHeader
+);
+
+
+
+/**
+ * Function: omxVCM4P2_PredictReconCoefIntra (6.2.5.4.3)
+ *
+ * Description:
+ * Performs adaptive DC/AC coefficient prediction for an intra block. Prior
+ * to the function call, prediction direction (predDir) should be selected as
+ * specified in [ISO14496-2], subclause 7.4.3.1.
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - pointer to the coefficient buffer which contains the quantized
+ * coefficient residuals (PQF) of the current block; must be
+ * aligned on a 4-byte boundary. The output coefficients are
+ * saturated to the range [-2048, 2047].
+ * pPredBufRow - pointer to the coefficient row buffer; must be aligned on
+ * a 4-byte boundary.
+ * pPredBufCol - pointer to the coefficient column buffer; must be aligned
+ * on a 4-byte boundary.
+ * curQP - quantization parameter of the current block. curQP may equal to
+ * predQP especially when the current block and the predictor block
+ * are in the same macroblock.
+ * predQP - quantization parameter of the predictor block
+ * predDir - indicates the prediction direction which takes one of the
+ * following values: OMX_VC_HORIZONTAL - predict horizontally
+ * OMX_VC_VERTICAL - predict vertically
+ * ACPredFlag - a flag indicating if AC prediction should be performed. It
+ * is equal to ac_pred_flag in the bit stream syntax of MPEG-4
+ * videoComp - video component type (luminance or chrominance) of the
+ * current block
+ *
+ * Output Arguments:
+ *
+ * pSrcDst - pointer to the coefficient buffer which contains the quantized
+ * coefficients (QF) of the current block
+ * pPredBufRow - pointer to the updated coefficient row buffer
+ * pPredBufCol - pointer to the updated coefficient column buffer Note:
+ * Buffer update: Update the AC prediction buffer (both row and
+ * column buffer).
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments, if:
+ * - At least one of the pointers is NULL:
+ * pSrcDst, pPredBufRow, or pPredBufCol.
+ * - curQP <= 0,
+ * - predQP <= 0,
+ * - curQP >31,
+ * - predQP > 31,
+ * - preDir exceeds [1,2]
+ * - pSrcDst, pPredBufRow, or pPredBufCol is not 4-byte aligned.
+ *
+ */
+OMXResult omxVCM4P2_PredictReconCoefIntra (
+ OMX_S16 *pSrcDst,
+ OMX_S16 *pPredBufRow,
+ OMX_S16 *pPredBufCol,
+ OMX_INT curQP,
+ OMX_INT predQP,
+ OMX_INT predDir,
+ OMX_INT ACPredFlag,
+ OMXVCM4P2VideoComponent videoComp
+);
+
+
+
+/**
+ * Function: omxVCM4P2_MCReconBlock (6.2.5.5.1)
+ *
+ * Description:
+ * Performs motion compensation prediction for an 8x8 block using
+ * interpolation described in [ISO14496-2], subclause 7.6.2.
+ *
+ * Input Arguments:
+ *
+ * pSrc - pointer to the block in the reference plane.
+ * srcStep - distance between the start of consecutive lines in the
+ * reference plane, in bytes; must be a multiple of 8.
+ * dstStep - distance between the start of consecutive lines in the
+ * destination plane, in bytes; must be a multiple of 8.
+ * pSrcResidue - pointer to a buffer containing the 16-bit prediction
+ * residuals; must be 16-byte aligned. If the pointer is NULL, then
+ * no prediction is done, only motion compensation, i.e., the block
+ * is moved with interpolation.
+ * predictType - bilinear interpolation type, as defined in section
+ * 6.2.1.2.
+ * rndVal - rounding control parameter: 0 - disabled; 1 - enabled.
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the destination buffer; must be 8-byte aligned. If
+ * prediction residuals are added then output intensities are
+ * clipped to the range [0,255].
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned under any of the following
+ * conditions:
+ * - pDst is not 8-byte aligned.
+ * - pSrcResidue is not 16-byte aligned.
+ * - one or more of the following pointers is NULL: pSrc or pDst.
+ * - either srcStep or dstStep is not a multiple of 8.
+ * - invalid type specified for the parameter predictType.
+ * - the parameter rndVal is not equal either to 0 or 1.
+ *
+ */
+OMXResult omxVCM4P2_MCReconBlock (
+ const OMX_U8 *pSrc,
+ OMX_INT srcStep,
+ const OMX_S16 *pSrcResidue,
+ OMX_U8 *pDst,
+ OMX_INT dstStep,
+ OMX_INT predictType,
+ OMX_INT rndVal
+);
+
+
+
+/* 6.3.1.1 Intra 16x16 Prediction Modes */
+/* A data type that enumerates intra_16x16 macroblock prediction modes is defined as follows: */
+
+typedef enum {
+ OMX_VC_16X16_VERT = 0, /** Intra_16x16_Vertical */
+ OMX_VC_16X16_HOR = 1, /** Intra_16x16_Horizontal */
+ OMX_VC_16X16_DC = 2, /** Intra_16x16_DC */
+ OMX_VC_16X16_PLANE = 3 /** Intra_16x16_Plane */
+} OMXVCM4P10Intra16x16PredMode;
+
+
+
+/* 6.3.1.2 Intra 4x4 Prediction Modes */
+/* A data type that enumerates intra_4x4 macroblock prediction modes is defined as follows: */
+
+typedef enum {
+ OMX_VC_4X4_VERT = 0, /** Intra_4x4_Vertical */
+ OMX_VC_4X4_HOR = 1, /** Intra_4x4_Horizontal */
+ OMX_VC_4X4_DC = 2, /** Intra_4x4_DC */
+ OMX_VC_4X4_DIAG_DL = 3, /** Intra_4x4_Diagonal_Down_Left */
+ OMX_VC_4X4_DIAG_DR = 4, /** Intra_4x4_Diagonal_Down_Right */
+ OMX_VC_4X4_VR = 5, /** Intra_4x4_Vertical_Right */
+ OMX_VC_4X4_HD = 6, /** Intra_4x4_Horizontal_Down */
+ OMX_VC_4X4_VL = 7, /** Intra_4x4_Vertical_Left */
+ OMX_VC_4X4_HU = 8 /** Intra_4x4_Horizontal_Up */
+} OMXVCM4P10Intra4x4PredMode;
+
+
+
+/* 6.3.1.3 Chroma Prediction Modes */
+/* A data type that enumerates intra chroma prediction modes is defined as follows: */
+
+typedef enum {
+ OMX_VC_CHROMA_DC = 0, /** Intra_Chroma_DC */
+ OMX_VC_CHROMA_HOR = 1, /** Intra_Chroma_Horizontal */
+ OMX_VC_CHROMA_VERT = 2, /** Intra_Chroma_Vertical */
+ OMX_VC_CHROMA_PLANE = 3 /** Intra_Chroma_Plane */
+} OMXVCM4P10IntraChromaPredMode;
+
+
+
+/* 6.3.1.4 Motion Estimation Modes */
+/* A data type that enumerates H.264 motion estimation modes is defined as follows: */
+
+typedef enum {
+ OMX_VC_M4P10_FAST_SEARCH = 0, /** Fast motion search */
+ OMX_VC_M4P10_FULL_SEARCH = 1 /** Full motion search */
+} OMXVCM4P10MEMode;
+
+
+
+/* 6.3.1.5 Macroblock Types */
+/* A data type that enumerates H.264 macroblock types is defined as follows: */
+
+typedef enum {
+ OMX_VC_P_16x16 = 0, /* defined by [ISO14496-10] */
+ OMX_VC_P_16x8 = 1,
+ OMX_VC_P_8x16 = 2,
+ OMX_VC_P_8x8 = 3,
+ OMX_VC_PREF0_8x8 = 4,
+ OMX_VC_INTER_SKIP = 5,
+ OMX_VC_INTRA_4x4 = 8,
+ OMX_VC_INTRA_16x16 = 9,
+ OMX_VC_INTRA_PCM = 10
+} OMXVCM4P10MacroblockType;
+
+
+
+/* 6.3.1.6 Sub-Macroblock Types */
+/* A data type that enumerates H.264 sub-macroblock types is defined as follows: */
+
+typedef enum {
+ OMX_VC_SUB_P_8x8 = 0, /* defined by [ISO14496-10] */
+ OMX_VC_SUB_P_8x4 = 1,
+ OMX_VC_SUB_P_4x8 = 2,
+ OMX_VC_SUB_P_4x4 = 3
+} OMXVCM4P10SubMacroblockType;
+
+
+
+/* 6.3.1.7 Variable Length Coding (VLC) Information */
+
+typedef struct {
+ OMX_U8 uTrailing_Ones; /* Trailing ones; 3 at most */
+ OMX_U8 uTrailing_One_Signs; /* Trailing ones signal */
+ OMX_U8 uNumCoeffs; /* Total number of non-zero coefs, including trailing ones */
+ OMX_U8 uTotalZeros; /* Total number of zero coefs */
+ OMX_S16 iLevels[16]; /* Levels of non-zero coefs, in reverse zig-zag order */
+ OMX_U8 uRuns[16]; /* Runs for levels and trailing ones, in reverse zig-zag order */
+} OMXVCM4P10VLCInfo;
+
+
+
+/* 6.3.1.8 Macroblock Information */
+
+typedef struct {
+ OMX_S32 sliceId; /* slice number */
+ OMXVCM4P10MacroblockType mbType; /* MB type */
+ OMXVCM4P10SubMacroblockType subMBType[4]; /* sub-block type */
+ OMX_S32 qpy; /* qp for luma */
+ OMX_S32 qpc; /* qp for chroma */
+ OMX_U32 cbpy; /* CBP Luma */
+ OMX_U32 cbpc; /* CBP Chroma */
+ OMXVCMotionVector pMV0[4][4]; /* motion vector, represented using 1/4-pel units, pMV0[blocky][blockx] (blocky = 0~3, blockx =0~3) */
+ OMXVCMotionVector pMVPred[4][4]; /* motion vector prediction, Represented using 1/4-pel units, pMVPred[blocky][blockx] (blocky = 0~3, blockx = 0~3) */
+ OMX_U8 pRefL0Idx[4]; /* reference picture indices */
+ OMXVCM4P10Intra16x16PredMode Intra16x16PredMode; /* best intra 16x16 prediction mode */
+ OMXVCM4P10Intra4x4PredMode pIntra4x4PredMode[16]; /* best intra 4x4 prediction mode for each block, pMV0 indexed as above */
+} OMXVCM4P10MBInfo, *OMXVCM4P10MBInfoPtr;
+
+
+
+/* 6.3.1.9 Motion Estimation Parameters */
+
+typedef struct {
+ OMX_S32 blockSplitEnable8x8; /* enables 16x8, 8x16, 8x8 */
+ OMX_S32 blockSplitEnable4x4; /* enable splitting of 8x4, 4x8, 4x4 blocks */
+ OMX_S32 halfSearchEnable;
+ OMX_S32 quarterSearchEnable;
+ OMX_S32 intraEnable4x4; /* 1=enable, 0=disable */
+ OMX_S32 searchRange16x16; /* integer pixel units */
+ OMX_S32 searchRange8x8;
+ OMX_S32 searchRange4x4;
+} OMXVCM4P10MEParams;
+
+
+
+/**
+ * Function: omxVCM4P10_PredictIntra_4x4 (6.3.3.1.1)
+ *
+ * Description:
+ * Perform Intra_4x4 prediction for luma samples. If the upper-right block is
+ * not available, then duplication work should be handled inside the function.
+ * Users need not define them outside.
+ *
+ * Input Arguments:
+ *
+ * pSrcLeft - Pointer to the buffer of 4 left pixels:
+ * p[x, y] (x = -1, y = 0..3)
+ * pSrcAbove - Pointer to the buffer of 8 above pixels:
+ * p[x,y] (x = 0..7, y =-1);
+ * must be aligned on a 4-byte boundary.
+ * pSrcAboveLeft - Pointer to the above left pixels: p[x,y] (x = -1, y = -1)
+ * leftStep - Step of left pixel buffer; must be a multiple of 4.
+ * dstStep - Step of the destination buffer; must be a multiple of 4.
+ * predMode - Intra_4x4 prediction mode.
+ * availability - Neighboring 4x4 block availability flag, refer to
+ * "Neighboring Macroblock Availability" .
+ *
+ * Output Arguments:
+ *
+ * pDst - Pointer to the destination buffer; must be aligned on a 4-byte
+ * boundary.
+ *
+ * Return Value:
+ * If the function runs without error, it returns OMX_Sts_NoErr.
+ * If one of the following cases occurs, the function returns
+ * OMX_Sts_BadArgErr:
+ * pDst is NULL.
+ * dstStep < 4, or dstStep is not a multiple of 4.
+ * leftStep is not a multiple of 4.
+ * predMode is not in the valid range of enumeration
+ * OMXVCM4P10Intra4x4PredMode.
+ * predMode is OMX_VC_4x4_VERT, but availability doesn't set OMX_VC_UPPER
+ * indicating p[x,-1] (x = 0..3) is not available.
+ * predMode is OMX_VC_4x4_HOR, but availability doesn't set OMX_VC_LEFT
+ * indicating p[-1,y] (y = 0..3) is not available.
+ * predMode is OMX_VC_4x4_DIAG_DL, but availability doesn't set
+ * OMX_VC_UPPER indicating p[x, -1] (x = 0..3) is not available.
+ * predMode is OMX_VC_4x4_DIAG_DR, but availability doesn't set
+ * OMX_VC_UPPER_LEFT or OMX_VC_UPPER or OMX_VC_LEFT indicating
+ * p[x,-1] (x = 0..3), or p[-1,y] (y = 0..3) or p[-1,-1] is not
+ * available.
+ * predMode is OMX_VC_4x4_VR, but availability doesn't set
+ * OMX_VC_UPPER_LEFT or OMX_VC_UPPER or OMX_VC_LEFT indicating
+ * p[x,-1] (x = 0..3), or p[-1,y] (y = 0..3) or p[-1,-1] is not
+ * available.
+ * predMode is OMX_VC_4x4_HD, but availability doesn't set
+ * OMX_VC_UPPER_LEFT or OMX_VC_UPPER or OMX_VC_LEFT indicating
+ * p[x,-1] (x = 0..3), or p[-1,y] (y = 0..3) or p[-1,-1] is not
+ * available.
+ * predMode is OMX_VC_4x4_VL, but availability doesn't set OMX_VC_UPPER
+ * indicating p[x,-1] (x = 0..3) is not available.
+ * predMode is OMX_VC_4x4_HU, but availability doesn't set OMX_VC_LEFT
+ * indicating p[-1,y] (y = 0..3) is not available.
+ * availability sets OMX_VC_UPPER, but pSrcAbove is NULL.
+ * availability sets OMX_VC_LEFT, but pSrcLeft is NULL.
+ * availability sets OMX_VC_UPPER_LEFT, but pSrcAboveLeft is NULL.
+ * either pSrcAbove or pDst is not aligned on a 4-byte boundary.
+ *
+ * Note:
+ * pSrcAbove, pSrcAbove, pSrcAboveLeft may be invalid pointers if
+ * they are not used by intra prediction as implied in predMode.
+ *
+ */
+OMXResult omxVCM4P10_PredictIntra_4x4 (
+ const OMX_U8 *pSrcLeft,
+ const OMX_U8 *pSrcAbove,
+ const OMX_U8 *pSrcAboveLeft,
+ OMX_U8 *pDst,
+ OMX_INT leftStep,
+ OMX_INT dstStep,
+ OMXVCM4P10Intra4x4PredMode predMode,
+ OMX_S32 availability
+);
+
+
+
+/**
+ * Function: omxVCM4P10_PredictIntra_16x16 (6.3.3.1.2)
+ *
+ * Description:
+ * Perform Intra_16x16 prediction for luma samples. If the upper-right block
+ * is not available, then duplication work should be handled inside the
+ * function. Users need not define them outside.
+ *
+ * Input Arguments:
+ *
+ * pSrcLeft - Pointer to the buffer of 16 left pixels: p[x, y] (x = -1, y =
+ * 0..15)
+ * pSrcAbove - Pointer to the buffer of 16 above pixels: p[x,y] (x = 0..15,
+ * y= -1); must be aligned on a 16-byte boundary.
+ * pSrcAboveLeft - Pointer to the above left pixels: p[x,y] (x = -1, y = -1)
+ * leftStep - Step of left pixel buffer; must be a multiple of 16.
+ * dstStep - Step of the destination buffer; must be a multiple of 16.
+ * predMode - Intra_16x16 prediction mode, please refer to section 3.4.1.
+ * availability - Neighboring 16x16 MB availability flag. Refer to
+ * section 3.4.4.
+ *
+ * Output Arguments:
+ *
+ * pDst -Pointer to the destination buffer; must be aligned on a 16-byte
+ * boundary.
+ *
+ * Return Value:
+ * If the function runs without error, it returns OMX_Sts_NoErr.
+ * If one of the following cases occurs, the function returns
+ * OMX_Sts_BadArgErr:
+ * pDst is NULL.
+ * dstStep < 16. or dstStep is not a multiple of 16.
+ * leftStep is not a multiple of 16.
+ * predMode is not in the valid range of enumeration
+ * OMXVCM4P10Intra16x16PredMode
+ * predMode is OMX_VC_16X16_VERT, but availability doesn't set
+ * OMX_VC_UPPER indicating p[x,-1] (x = 0..15) is not available.
+ * predMode is OMX_VC_16X16_HOR, but availability doesn't set OMX_VC_LEFT
+ * indicating p[-1,y] (y = 0..15) is not available.
+ * predMode is OMX_VC_16X16_PLANE, but availability doesn't set
+ * OMX_VC_UPPER_LEFT or OMX_VC_UPPER or OMX_VC_LEFT indicating
+ * p[x,-1](x = 0..15), or p[-1,y] (y = 0..15), or p[-1,-1] is not
+ * available.
+ * availability sets OMX_VC_UPPER, but pSrcAbove is NULL.
+ * availability sets OMX_VC_LEFT, but pSrcLeft is NULL.
+ * availability sets OMX_VC_UPPER_LEFT, but pSrcAboveLeft is NULL.
+ * either pSrcAbove or pDst is not aligned on a 16-byte boundary.
+ *
+ * Note:
+ * pSrcAbove, pSrcAbove, pSrcAboveLeft may be invalid pointers if
+ * they are not used by intra prediction implied in predMode.
+ * Note:
+ * OMX_VC_UPPER_RIGHT is not used in intra_16x16 luma prediction.
+ *
+ */
+OMXResult omxVCM4P10_PredictIntra_16x16 (
+ const OMX_U8 *pSrcLeft,
+ const OMX_U8 *pSrcAbove,
+ const OMX_U8 *pSrcAboveLeft,
+ OMX_U8 *pDst,
+ OMX_INT leftStep,
+ OMX_INT dstStep,
+ OMXVCM4P10Intra16x16PredMode predMode,
+ OMX_S32 availability
+);
+
+
+
+/**
+ * Function: omxVCM4P10_PredictIntraChroma_8x8 (6.3.3.1.3)
+ *
+ * Description:
+ * Performs intra prediction for chroma samples.
+ *
+ * Input Arguments:
+ *
+ * pSrcLeft - Pointer to the buffer of 8 left pixels: p[x, y] (x = -1, y=
+ * 0..7).
+ * pSrcAbove - Pointer to the buffer of 8 above pixels: p[x,y] (x = 0..7, y
+ * = -1); must be aligned on an 8-byte boundary.
+ * pSrcAboveLeft - Pointer to the above left pixels: p[x,y] (x = -1, y = -1)
+ * leftStep - Step of left pixel buffer; must be a multiple of 8.
+ * dstStep - Step of the destination buffer; must be a multiple of 8.
+ * predMode - Intra chroma prediction mode, please refer to section 3.4.3.
+ * availability - Neighboring chroma block availability flag, please refer
+ * to "Neighboring Macroblock Availability".
+ *
+ * Output Arguments:
+ *
+ * pDst - Pointer to the destination buffer; must be aligned on an 8-byte
+ * boundary.
+ *
+ * Return Value:
+ * If the function runs without error, it returns OMX_Sts_NoErr.
+ * If any of the following cases occurs, the function returns
+ * OMX_Sts_BadArgErr:
+ * pDst is NULL.
+ * dstStep < 8 or dstStep is not a multiple of 8.
+ * leftStep is not a multiple of 8.
+ * predMode is not in the valid range of enumeration
+ * OMXVCM4P10IntraChromaPredMode.
+ * predMode is OMX_VC_CHROMA_VERT, but availability doesn't set
+ * OMX_VC_UPPER indicating p[x,-1] (x = 0..7) is not available.
+ * predMode is OMX_VC_CHROMA_HOR, but availability doesn't set OMX_VC_LEFT
+ * indicating p[-1,y] (y = 0..7) is not available.
+ * predMode is OMX_VC_CHROMA_PLANE, but availability doesn't set
+ * OMX_VC_UPPER_LEFT or OMX_VC_UPPER or OMX_VC_LEFT indicating
+ * p[x,-1](x = 0..7), or p[-1,y] (y = 0..7), or p[-1,-1] is not
+ * available.
+ * availability sets OMX_VC_UPPER, but pSrcAbove is NULL.
+ * availability sets OMX_VC_LEFT, but pSrcLeft is NULL.
+ * availability sets OMX_VC_UPPER_LEFT, but pSrcAboveLeft is NULL.
+ * either pSrcAbove or pDst is not aligned on a 8-byte boundary.
+ *
+ * Note: pSrcAbove, pSrcAbove, pSrcAboveLeft may be invalid pointer if
+ * they are not used by intra prediction implied in predMode.
+ *
+ * Note: OMX_VC_UPPER_RIGHT is not used in intra chroma prediction.
+ *
+ */
+OMXResult omxVCM4P10_PredictIntraChroma_8x8 (
+ const OMX_U8 *pSrcLeft,
+ const OMX_U8 *pSrcAbove,
+ const OMX_U8 *pSrcAboveLeft,
+ OMX_U8 *pDst,
+ OMX_INT leftStep,
+ OMX_INT dstStep,
+ OMXVCM4P10IntraChromaPredMode predMode,
+ OMX_S32 availability
+);
+
+
+
+/**
+ * Function: omxVCM4P10_InterpolateLuma (6.3.3.2.1)
+ *
+ * Description:
+ * Performs quarter-pixel interpolation for inter luma MB. It is assumed that
+ * the frame is already padded when calling this function.
+ *
+ * Input Arguments:
+ *
+ * pSrc - Pointer to the source reference frame buffer
+ * srcStep - reference frame step, in bytes; must be a multiple of roi.width
+ * dstStep - destination frame step, in bytes; must be a multiple of
+ * roi.width
+ * dx - Fractional part of horizontal motion vector component in 1/4 pixel
+ * unit; valid in the range [0,3]
+ * dy - Fractional part of vertical motion vector y component in 1/4 pixel
+ * unit; valid in the range [0,3]
+ * roi - Dimension of the interpolation region; the parameters roi.width and
+ * roi.height must be equal to either 4, 8, or 16.
+ *
+ * Output Arguments:
+ *
+ * pDst - Pointer to the destination frame buffer:
+ * if roi.width==4, 4-byte alignment required
+ * if roi.width==8, 8-byte alignment required
+ * if roi.width==16, 16-byte alignment required
+ *
+ * Return Value:
+ * If the function runs without error, it returns OMX_Sts_NoErr.
+ * If one of the following cases occurs, the function returns
+ * OMX_Sts_BadArgErr:
+ * pSrc or pDst is NULL.
+ * srcStep or dstStep < roi.width.
+ * dx or dy is out of range [0,3].
+ * roi.width or roi.height is out of range {4, 8, 16}.
+ * roi.width is equal to 4, but pDst is not 4 byte aligned.
+ * roi.width is equal to 8 or 16, but pDst is not 8 byte aligned.
+ * srcStep or dstStep is not a multiple of 8.
+ *
+ */
+OMXResult omxVCM4P10_InterpolateLuma (
+ const OMX_U8 *pSrc,
+ OMX_S32 srcStep,
+ OMX_U8 *pDst,
+ OMX_S32 dstStep,
+ OMX_S32 dx,
+ OMX_S32 dy,
+ OMXSize roi
+);
+
+
+
+/**
+ * Function: omxVCM4P10_InterpolateChroma (6.3.3.2.2)
+ *
+ * Description:
+ * Performs 1/8-pixel interpolation for inter chroma MB.
+ *
+ * Input Arguments:
+ *
+ * pSrc -Pointer to the source reference frame buffer
+ * srcStep -Reference frame step in bytes
+ * dstStep -Destination frame step in bytes; must be a multiple of
+ * roi.width.
+ * dx -Fractional part of horizontal motion vector component in 1/8 pixel
+ * unit; valid in the range [0,7]
+ * dy -Fractional part of vertical motion vector component in 1/8 pixel
+ * unit; valid in the range [0,7]
+ * roi -Dimension of the interpolation region; the parameters roi.width and
+ * roi.height must be equal to either 2, 4, or 8.
+ *
+ * Output Arguments:
+ *
+ * pDst -Pointer to the destination frame buffer:
+ * if roi.width==2, 2-byte alignment required
+ * if roi.width==4, 4-byte alignment required
+ * if roi.width==8, 8-byte alignment required
+ *
+ * Return Value:
+ * If the function runs without error, it returns OMX_Sts_NoErr.
+ * If one of the following cases occurs, the function returns
+ * OMX_Sts_BadArgErr:
+ * pSrc or pDst is NULL.
+ * srcStep or dstStep < 8.
+ * dx or dy is out of range [0-7].
+ * roi.width or roi.height is out of range {2,4,8}.
+ * roi.width is equal to 2, but pDst is not 2-byte aligned.
+ * roi.width is equal to 4, but pDst is not 4-byte aligned.
+ * roi.width is equal to 8, but pDst is not 8 byte aligned.
+ * srcStep or dstStep is not a multiple of 8.
+ *
+ */
+OMXResult omxVCM4P10_InterpolateChroma (
+ const OMX_U8 *pSrc,
+ OMX_S32 srcStep,
+ OMX_U8 *pDst,
+ OMX_S32 dstStep,
+ OMX_S32 dx,
+ OMX_S32 dy,
+ OMXSize roi
+);
+
+
+
+/**
+ * Function: omxVCM4P10_FilterDeblockingLuma_VerEdge_I (6.3.3.3.1)
+ *
+ * Description:
+ * Performs in-place deblock filtering on four vertical edges of the luma
+ * macroblock (16x16).
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - Pointer to the input macroblock; must be 16-byte aligned.
+ * srcdstStep -Step of the arrays; must be a multiple of 16.
+ * pAlpha -Array of size 2 of alpha thresholds (the first item is the alpha
+ * threshold for the external vertical edge, and the second item is
+ * for the internal vertical edge); per [ISO14496-10] alpha values
+ * must be in the range [0,255].
+ * pBeta -Array of size 2 of beta thresholds (the first item is the beta
+ * threshold for the external vertical edge, and the second item is
+ * for the internal vertical edge); per [ISO14496-10] beta values
+ * must be in the range [0,18].
+ * pThresholds -Array of size 16 of Thresholds (TC0) (values for the left
+ * edge of each 4x4 block, arranged in vertical block order); must
+ * be aligned on a 4-byte boundary.. Per [ISO14496-10] values must
+ * be in the range [0,25].
+ * pBS -Array of size 16 of BS parameters (arranged in vertical block
+ * order); valid in the range [0,4] with the following
+ * restrictions: i) pBS[i]== 4 may occur only for 0<=i<=3, ii)
+ * pBS[i]== 4 if and only if pBS[i^3]== 4. Must be 4-byte aligned.
+ *
+ * Output Arguments:
+ *
+ * pSrcDst -Pointer to filtered output macroblock.
+ *
+ * Return Value:
+ * If the function runs without error, it returns OMX_Sts_NoErr.
+ * If one of the following cases occurs, the function returns
+ * OMX_Sts_BadArgErr:
+ * Either of the pointers in pSrcDst, pAlpha, pBeta, pThresholds, or pBS
+ * is NULL.
+ * Either pThresholds or pBS is not aligned on a 4-byte boundary.
+ * pSrcDst is not 16-byte aligned.
+ * srcdstStep is not a multiple of 16.
+ * pAlpha[0] and/or pAlpha[1] is outside the range [0,255].
+ * pBeta[0] and/or pBeta[1] is outside the range [0,18].
+ * One or more entries in the table pThresholds[0..15]is outside of the
+ * range [0,25].
+ * pBS is out of range, i.e., one of the following conditions is true:
+ * pBS[i]<0, pBS[i]>4, pBS[i]==4 for i>=4, or (pBS[i]==4 &&
+ * pBS[i^3]!=4) for 0<=i<=3.
+ *
+ */
+OMXResult omxVCM4P10_FilterDeblockingLuma_VerEdge_I (
+ OMX_U8 *pSrcDst,
+ OMX_S32 srcdstStep,
+ const OMX_U8 *pAlpha,
+ const OMX_U8 *pBeta,
+ const OMX_U8 *pThresholds,
+ const OMX_U8 *pBS
+);
+
+
+
+/**
+ * Function: omxVCM4P10_FilterDeblockingLuma_HorEdge_I (6.3.3.3.2)
+ *
+ * Description:
+ * Performs in-place deblock filtering on four horizontal edges of the luma
+ * macroblock (16x16).
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - pointer to the input macroblock; must be 16-byte aligned.
+ * srcdstStep - step of the arrays; must be a multiple of 16.
+ * pAlpha - array of size 2 of alpha thresholds (the first item is the alpha
+ * threshold for the external vertical edge, and the second item is
+ * for the internal horizontal edge); per [ISO14496-10] alpha
+ * values must be in the range [0,255].
+ * pBeta - array of size 2 of beta thresholds (the first item is the beta
+ * threshold for the external horizontal edge, and the second item
+ * is for the internal horizontal edge). Per [ISO14496-10] beta
+ * values must be in the range [0,18].
+ * pThresholds - array of size 16 containing thresholds, TC0, for the top
+ * horizontal edge of each 4x4 block, arranged in horizontal block
+ * order; must be aligned on a 4-byte boundary. Per [ISO14496 10]
+ * values must be in the range [0,25].
+ * pBS - array of size 16 of BS parameters (arranged in horizontal block
+ * order); valid in the range [0,4] with the following
+ * restrictions: i) pBS[i]== 4 may occur only for 0<=i<=3, ii)
+ * pBS[i]== 4 if and only if pBS[i^3]== 4. Must be 4-byte aligned.
+ *
+ * Output Arguments:
+ *
+ * pSrcDst -Pointer to filtered output macroblock.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr, if the function runs without error.
+ *
+ * OMX_Sts_BadArgErr, if one of the following cases occurs:
+ * - one or more of the following pointers is NULL: pSrcDst, pAlpha,
+ * pBeta, pThresholds, or pBS.
+ * - either pThresholds or pBS is not aligned on a 4-byte boundary.
+ * - pSrcDst is not 16-byte aligned.
+ * - srcdstStep is not a multiple of 16.
+ * - pAlpha[0] and/or pAlpha[1] is outside the range [0,255].
+ * - pBeta[0] and/or pBeta[1] is outside the range [0,18].
+ * - One or more entries in the table pThresholds[0..15] is
+ * outside of the range [0,25].
+ * - pBS is out of range, i.e., one of the following conditions is true:
+ * pBS[i]<0, pBS[i]>4, pBS[i]==4 for i>=4, or
+ * (pBS[i]==4 && pBS[i^3]!=4) for 0<=i<=3.
+ *
+ */
+OMXResult omxVCM4P10_FilterDeblockingLuma_HorEdge_I (
+ OMX_U8 *pSrcDst,
+ OMX_S32 srcdstStep,
+ const OMX_U8 *pAlpha,
+ const OMX_U8 *pBeta,
+ const OMX_U8 *pThresholds,
+ const OMX_U8 *pBS
+);
+
+
+
+/**
+ * Function: omxVCM4P10_FilterDeblockingChroma_VerEdge_I (6.3.3.3.3)
+ *
+ * Description:
+ * Performs in-place deblock filtering on four vertical edges of the chroma
+ * macroblock (8x8).
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - Pointer to the input macroblock; must be 8-byte aligned.
+ * srcdstStep - Step of the arrays; must be a multiple of 8.
+ * pAlpha - Array of size 2 of alpha thresholds (the first item is alpha
+ * threshold for external vertical edge, and the second item is for
+ * internal vertical edge); per [ISO14496-10] alpha values must be
+ * in the range [0,255].
+ * pBeta - Array of size 2 of beta thresholds (the first item is the beta
+ * threshold for the external vertical edge, and the second item is
+ * for the internal vertical edge); per [ISO14496-10] beta values
+ * must be in the range [0,18].
+ * pThresholds - Array of size 8 containing thresholds, TC0, for the left
+ * vertical edge of each 4x2 chroma block, arranged in vertical
+ * block order; must be aligned on a 4-byte boundary. Per
+ * [ISO14496-10] values must be in the range [0,25].
+ * pBS - Array of size 16 of BS parameters (values for each 2x2 chroma
+ * block, arranged in vertical block order). This parameter is the
+ * same as the pBS parameter passed into FilterDeblockLuma_VerEdge;
+ * valid in the range [0,4] with the following restrictions: i)
+ * pBS[i]== 4 may occur only for 0<=i<=3, ii) pBS[i]== 4 if and
+ * only if pBS[i^3]== 4. Must be 4 byte aligned.
+ *
+ * Output Arguments:
+ *
+ * pSrcDst -Pointer to filtered output macroblock.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr, if the function runs without error.
+ *
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - one or more of the following pointers is NULL: pSrcDst, pAlpha,
+ * pBeta, pThresholds, or pBS.
+ * - pSrcDst is not 8-byte aligned.
+ * - srcdstStep is not a multiple of 8.
+ * - pThresholds is not 4-byte aligned.
+ * - pAlpha[0] and/or pAlpha[1] is outside the range [0,255].
+ * - pBeta[0] and/or pBeta[1] is outside the range [0,18].
+ * - One or more entries in the table pThresholds[0..7] is outside
+ * of the range [0,25].
+ * - pBS is out of range, i.e., one of the following conditions is true:
+ * pBS[i]<0, pBS[i]>4, pBS[i]==4 for i>=4, or
+ * (pBS[i]==4 && pBS[i^3]!=4) for 0<=i<=3.
+ * - pBS is not 4-byte aligned.
+ *
+ */
+OMXResult omxVCM4P10_FilterDeblockingChroma_VerEdge_I (
+ OMX_U8 *pSrcDst,
+ OMX_S32 srcdstStep,
+ const OMX_U8 *pAlpha,
+ const OMX_U8 *pBeta,
+ const OMX_U8 *pThresholds,
+ const OMX_U8 *pBS
+);
+
+
+
+/**
+ * Function: omxVCM4P10_FilterDeblockingChroma_HorEdge_I (6.3.3.3.4)
+ *
+ * Description:
+ * Performs in-place deblock filtering on the horizontal edges of the chroma
+ * macroblock (8x8).
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - pointer to the input macroblock; must be 8-byte aligned.
+ * srcdstStep - array step; must be a multiple of 8.
+ * pAlpha - array of size 2 containing alpha thresholds; the first element
+ * contains the threshold for the external horizontal edge, and the
+ * second element contains the threshold for internal horizontal
+ * edge. Per [ISO14496-10] alpha values must be in the range
+ * [0,255].
+ * pBeta - array of size 2 containing beta thresholds; the first element
+ * contains the threshold for the external horizontal edge, and the
+ * second element contains the threshold for the internal
+ * horizontal edge. Per [ISO14496-10] beta values must be in the
+ * range [0,18].
+ * pThresholds - array of size 8 containing thresholds, TC0, for the top
+ * horizontal edge of each 2x4 chroma block, arranged in horizontal
+ * block order; must be aligned on a 4-byte boundary. Per
+ * [ISO14496-10] values must be in the range [0,25].
+ * pBS - array of size 16 containing BS parameters for each 2x2 chroma
+ * block, arranged in horizontal block order; valid in the range
+ * [0,4] with the following restrictions: i) pBS[i]== 4 may occur
+ * only for 0<=i<=3, ii) pBS[i]== 4 if and only if pBS[i^3]== 4.
+ * Must be 4-byte aligned.
+ *
+ * Output Arguments:
+ *
+ * pSrcDst -Pointer to filtered output macroblock.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr, if the function runs without error.
+ *
+ * OMX_Sts_BadArgErr, if one of the following cases occurs:
+ * - any of the following pointers is NULL:
+ * pSrcDst, pAlpha, pBeta, pThresholds, or pBS.
+ * - pSrcDst is not 8-byte aligned.
+ * - srcdstStep is not a multiple of 8.
+ * - pThresholds is not 4-byte aligned.
+ * - pAlpha[0] and/or pAlpha[1] is outside the range [0,255].
+ * - pBeta[0] and/or pBeta[1] is outside the range [0,18].
+ * - One or more entries in the table pThresholds[0..7] is outside
+ * of the range [0,25].
+ * - pBS is out of range, i.e., one of the following conditions is true:
+ * pBS[i]<0, pBS[i]>4, pBS[i]==4 for i>=4, or
+ * (pBS[i]==4 && pBS[i^3]!=4) for 0<=i<=3.
+ * - pBS is not 4-byte aligned.
+ *
+ */
+OMXResult omxVCM4P10_FilterDeblockingChroma_HorEdge_I (
+ OMX_U8 *pSrcDst,
+ OMX_S32 srcdstStep,
+ const OMX_U8 *pAlpha,
+ const OMX_U8 *pBeta,
+ const OMX_U8 *pThresholds,
+ const OMX_U8 *pBS
+);
+
+
+
+/**
+ * Function: omxVCM4P10_DeblockLuma_I (6.3.3.3.5)
+ *
+ * Description:
+ * This function performs in-place deblock filtering the horizontal and
+ * vertical edges of a luma macroblock (16x16).
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - pointer to the input macroblock; must be 16-byte aligned.
+ * srcdstStep - image width; must be a multiple of 16.
+ * pAlpha - pointer to a 2x2 table of alpha thresholds, organized as
+ * follows: {external vertical edge, internal vertical edge,
+ * external horizontal edge, internal horizontal edge }. Per
+ * [ISO14496-10] alpha values must be in the range [0,255].
+ * pBeta - pointer to a 2x2 table of beta thresholds, organized as follows:
+ * {external vertical edge, internal vertical edge, external
+ * horizontal edge, internal horizontal edge }. Per [ISO14496-10]
+ * beta values must be in the range [0,18].
+ * pThresholds - pointer to a 16x2 table of threshold (TC0), organized as
+ * follows: {values for the left or above edge of each 4x4 block,
+ * arranged in vertical block order and then in horizontal block
+ * order}; must be aligned on a 4-byte boundary. Per [ISO14496-10]
+ * values must be in the range [0,25].
+ * pBS - pointer to a 16x2 table of BS parameters arranged in scan block
+ * order for vertical edges and then horizontal edges; valid in the
+ * range [0,4] with the following restrictions: i) pBS[i]== 4 may
+ * occur only for 0<=i<=3, ii) pBS[i]== 4 if and only if pBS[i^3]==
+ * 4. Must be 4-byte aligned.
+ *
+ * Output Arguments:
+ *
+ * pSrcDst - pointer to filtered output macroblock.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments
+ * - one or more of the following pointers is NULL: pSrcDst, pAlpha,
+ * pBeta, pThresholds or pBS.
+ * - pSrcDst is not 16-byte aligned.
+ * - either pThresholds or pBS is not aligned on a 4-byte boundary.
+ * - one or more entries in the table pAlpha[0..3] is outside the range
+ * [0,255].
+ * - one or more entries in the table pBeta[0..3] is outside the range
+ * [0,18].
+ * - one or more entries in the table pThresholds[0..31]is outside of
+ * the range [0,25].
+ * - pBS is out of range, i.e., one of the following conditions is true:
+ * pBS[i]<0, pBS[i]>4, pBS[i]==4 for i>=4, or
+ * (pBS[i]==4 && pBS[i^3]!=4) for 0<=i<=3.
+ * - srcdstStep is not a multiple of 16.
+ *
+ */
+OMXResult omxVCM4P10_DeblockLuma_I (
+ OMX_U8 *pSrcDst,
+ OMX_S32 srcdstStep,
+ const OMX_U8 *pAlpha,
+ const OMX_U8 *pBeta,
+ const OMX_U8 *pThresholds,
+ const OMX_U8 *pBS
+);
+
+
+
+/**
+ * Function: omxVCM4P10_DeblockChroma_I (6.3.3.3.6)
+ *
+ * Description:
+ * Performs in-place deblocking filtering on all edges of the chroma
+ * macroblock (16x16).
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - pointer to the input macroblock; must be 8-byte aligned.
+ * srcdstStep - step of the arrays; must be a multiple of 8.
+ * pAlpha - pointer to a 2x2 array of alpha thresholds, organized as
+ * follows: {external vertical edge, internal vertical edge,
+ * external horizontal edge, internal horizontal edge }. Per
+ * [ISO14496-10] alpha values must be in the range [0,255].
+ * pBeta - pointer to a 2x2 array of Beta Thresholds, organized as follows:
+ * { external vertical edge, internal vertical edge, external
+ * horizontal edge, internal horizontal edge }. Per [ISO14496-10]
+ * beta values must be in the range [0,18].
+ * pThresholds - array of size 8x2 of Thresholds (TC0) (values for the left
+ * or above edge of each 4x2 or 2x4 block, arranged in vertical
+ * block order and then in horizontal block order); must be aligned
+ * on a 4-byte boundary. Per [ISO14496-10] values must be in the
+ * range [0,25].
+ * pBS - array of size 16x2 of BS parameters (arranged in scan block order
+ * for vertical edges and then horizontal edges); valid in the
+ * range [0,4] with the following restrictions: i) pBS[i]== 4 may
+ * occur only for 0<=i<=3, ii) pBS[i]== 4 if and only if pBS[i^3]==
+ * 4. Must be 4-byte aligned.
+ *
+ * Output Arguments:
+ *
+ * pSrcDst - pointer to filtered output macroblock.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments
+ * - one or more of the following pointers is NULL: pSrcDst, pAlpha,
+ * pBeta, pThresholds, or pBS.
+ * - pSrcDst is not 8-byte aligned.
+ * - either pThresholds or pBS is not 4-byte aligned.
+ * - one or more entries in the table pAlpha[0..3] is outside the range
+ * [0,255].
+ * - one or more entries in the table pBeta[0..3] is outside the range
+ * [0,18].
+ * - one or more entries in the table pThresholds[0..15]is outside of
+ * the range [0,25].
+ * - pBS is out of range, i.e., one of the following conditions is true:
+ * pBS[i]<0, pBS[i]>4, pBS[i]==4 for i>=4, or
+ * (pBS[i]==4 && pBS[i^3]!=4) for 0<=i<=3.
+ * - srcdstStep is not a multiple of 8.
+ *
+ */
+OMXResult omxVCM4P10_DeblockChroma_I (
+ OMX_U8 *pSrcDst,
+ OMX_S32 srcdstStep,
+ const OMX_U8 *pAlpha,
+ const OMX_U8 *pBeta,
+ const OMX_U8 *pThresholds,
+ const OMX_U8 *pBS
+);
+
+
+
+/**
+ * Function: omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC (6.3.4.1.1)
+ *
+ * Description:
+ * Performs CAVLC decoding and inverse raster scan for a 2x2 block of
+ * ChromaDCLevel. The decoded coefficients in the packed position-coefficient
+ * buffer are stored in reverse zig-zag order, i.e., the first buffer element
+ * contains the last non-zero postion-coefficient pair of the block. Within
+ * each position-coefficient pair, the position entry indicates the
+ * raster-scan position of the coefficient, while the coefficient entry
+ * contains the coefficient value.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - Double pointer to current byte in bit stream buffer
+ * pOffset - Pointer to current bit position in the byte pointed to by
+ * *ppBitStream; valid in the range [0,7].
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after each block is decoded
+ * pOffset - *pOffset is updated after each block is decoded
+ * pNumCoeff - Pointer to the number of nonzero coefficients in this block
+ * ppPosCoefBuf - Double pointer to destination residual
+ * coefficient-position pair buffer. Buffer position
+ * (*ppPosCoefBuf) is updated upon return, unless there are only
+ * zero coefficients in the currently decoded block. In this case
+ * the caller is expected to bypass the transform/dequantization of
+ * the empty blocks.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr, if the function runs without error.
+ *
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - ppBitStream or pOffset is NULL.
+ * - ppPosCoefBuf or pNumCoeff is NULL.
+ * OMX_Sts_Err - if one of the following is true:
+ * - an illegal code is encountered in the bitstream
+ *
+ */
+OMXResult omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC (
+ const OMX_U8 **ppBitStream,
+ OMX_S32*pOffset,
+ OMX_U8 *pNumCoeff,
+ OMX_U8 **ppPosCoefbuf
+);
+
+
+
+/**
+ * Function: omxVCM4P10_DecodeCoeffsToPairCAVLC (6.3.4.1.2)
+ *
+ * Description:
+ * Performs CAVLC decoding and inverse zigzag scan for 4x4 block of
+ * Intra16x16DCLevel, Intra16x16ACLevel, LumaLevel, and ChromaACLevel. Inverse
+ * field scan is not supported. The decoded coefficients in the packed
+ * position-coefficient buffer are stored in reverse zig-zag order, i.e., the
+ * first buffer element contains the last non-zero postion-coefficient pair of
+ * the block. Within each position-coefficient pair, the position entry
+ * indicates the raster-scan position of the coefficient, while the
+ * coefficient entry contains the coefficient value.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream -Double pointer to current byte in bit stream buffer
+ * pOffset - Pointer to current bit position in the byte pointed to by
+ * *ppBitStream; valid in the range [0,7].
+ * sMaxNumCoeff - Maximum the number of non-zero coefficients in current
+ * block
+ * sVLCSelect - VLC table selector, obtained from the number of non-zero
+ * coefficients contained in the above and left 4x4 blocks. It is
+ * equivalent to the variable nC described in H.264 standard table
+ * 9 5, except its value can t be less than zero.
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after each block is decoded.
+ * Buffer position (*ppPosCoefBuf) is updated upon return, unless
+ * there are only zero coefficients in the currently decoded block.
+ * In this case the caller is expected to bypass the
+ * transform/dequantization of the empty blocks.
+ * pOffset - *pOffset is updated after each block is decoded
+ * pNumCoeff - Pointer to the number of nonzero coefficients in this block
+ * ppPosCoefBuf - Double pointer to destination residual
+ * coefficient-position pair buffer
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ *
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - ppBitStream or pOffset is NULL.
+ * - ppPosCoefBuf or pNumCoeff is NULL.
+ * - sMaxNumCoeff is not equal to either 15 or 16.
+ * - sVLCSelect is less than 0.
+ *
+ * OMX_Sts_Err - if one of the following is true:
+ * - an illegal code is encountered in the bitstream
+ *
+ */
+OMXResult omxVCM4P10_DecodeCoeffsToPairCAVLC (
+ const OMX_U8 **ppBitStream,
+ OMX_S32 *pOffset,
+ OMX_U8 *pNumCoeff,
+ OMX_U8 **ppPosCoefbuf,
+ OMX_INT sVLCSelect,
+ OMX_INT sMaxNumCoeff
+);
+
+
+
+/**
+ * Function: omxVCM4P10_TransformDequantLumaDCFromPair (6.3.4.2.1)
+ *
+ * Description:
+ * Reconstructs the 4x4 LumaDC block from the coefficient-position pair
+ * buffer, performs integer inverse, and dequantization for 4x4 LumaDC
+ * coefficients, and updates the pair buffer pointer to the next non-empty
+ * block.
+ *
+ * Input Arguments:
+ *
+ * ppSrc - Double pointer to residual coefficient-position pair buffer
+ * output by CALVC decoding
+ * QP - Quantization parameter QpY
+ *
+ * Output Arguments:
+ *
+ * ppSrc - *ppSrc is updated to the start of next non empty block
+ * pDst - Pointer to the reconstructed 4x4 LumaDC coefficients buffer; must
+ * be aligned on a 8-byte boundary.
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - ppSrc or pDst is NULL.
+ * - pDst is not 8 byte aligned.
+ * - QP is not in the range of [0-51].
+ *
+ */
+OMXResult omxVCM4P10_TransformDequantLumaDCFromPair (
+ const OMX_U8 **ppSrc,
+ OMX_S16 *pDst,
+ OMX_INT QP
+);
+
+
+
+/**
+ * Function: omxVCM4P10_TransformDequantChromaDCFromPair (6.3.4.2.2)
+ *
+ * Description:
+ * Reconstruct the 2x2 ChromaDC block from coefficient-position pair buffer,
+ * perform integer inverse transformation, and dequantization for 2x2 chroma
+ * DC coefficients, and update the pair buffer pointer to next non-empty
+ * block.
+ *
+ * Input Arguments:
+ *
+ * ppSrc - Double pointer to residual coefficient-position pair buffer
+ * output by CALVC decoding
+ * QP - Quantization parameter QpC
+ *
+ * Output Arguments:
+ *
+ * ppSrc - *ppSrc is updated to the start of next non empty block
+ * pDst - Pointer to the reconstructed 2x2 ChromaDC coefficients buffer;
+ * must be aligned on a 4-byte boundary.
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - ppSrc or pDst is NULL.
+ * - pDst is not 4-byte aligned.
+ * - QP is not in the range of [0-51].
+ *
+ */
+OMXResult omxVCM4P10_TransformDequantChromaDCFromPair (
+ const OMX_U8 **ppSrc,
+ OMX_S16 *pDst,
+ OMX_INT QP
+);
+
+
+
+/**
+ * Function: omxVCM4P10_DequantTransformResidualFromPairAndAdd (6.3.4.2.3)
+ *
+ * Description:
+ * Reconstruct the 4x4 residual block from coefficient-position pair buffer,
+ * perform dequantization and integer inverse transformation for 4x4 block of
+ * residuals with previous intra prediction or motion compensation data, and
+ * update the pair buffer pointer to next non-empty block. If pDC == NULL,
+ * there re 16 non-zero AC coefficients at most in the packed buffer starting
+ * from 4x4 block position 0; If pDC != NULL, there re 15 non-zero AC
+ * coefficients at most in the packet buffer starting from 4x4 block position
+ * 1.
+ *
+ * Input Arguments:
+ *
+ * ppSrc - Double pointer to residual coefficient-position pair buffer
+ * output by CALVC decoding
+ * pPred - Pointer to the predicted 4x4 block; must be aligned on a 4-byte
+ * boundary
+ * predStep - Predicted frame step size in bytes; must be a multiple of 4
+ * dstStep - Destination frame step in bytes; must be a multiple of 4
+ * pDC - Pointer to the DC coefficient of this block, NULL if it doesn't
+ * exist
+ * QP - QP Quantization parameter. It should be QpC in chroma 4x4 block
+ * decoding, otherwise it should be QpY.
+ * AC - Flag indicating if at least one non-zero AC coefficient exists
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the reconstructed 4x4 block data; must be aligned on a
+ * 4-byte boundary
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - pPred or pDst is NULL.
+ * - pPred or pDst is not 4-byte aligned.
+ * - predStep or dstStep is not a multiple of 4.
+ * - AC !=0 and Qp is not in the range of [0-51] or ppSrc == NULL.
+ * - AC ==0 && pDC ==NULL.
+ *
+ */
+OMXResult omxVCM4P10_DequantTransformResidualFromPairAndAdd (
+ const OMX_U8 **ppSrc,
+ const OMX_U8 *pPred,
+ const OMX_S16 *pDC,
+ OMX_U8 *pDst,
+ OMX_INT predStep,
+ OMX_INT dstStep,
+ OMX_INT QP,
+ OMX_INT AC
+);
+
+
+
+/**
+ * Function: omxVCM4P10_MEGetBufSize (6.3.5.1.1)
+ *
+ * Description:
+ * Computes the size, in bytes, of the vendor-specific specification
+ * structure for the omxVCM4P10 motion estimation functions BlockMatch_Integer
+ * and MotionEstimationMB.
+ *
+ * Input Arguments:
+ *
+ * MEmode - motion estimation mode; available modes are defined by the
+ * enumerated type OMXVCM4P10MEMode
+ * pMEParams -motion estimation parameters
+ *
+ * Output Arguments:
+ *
+ * pSize - pointer to the number of bytes required for the motion
+ * estimation specification structure
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - pMEParams or pSize is NULL.
+ * - an invalid MEMode is specified.
+ *
+ */
+OMXResult omxVCM4P10_MEGetBufSize (
+ OMXVCM4P10MEMode MEmode,
+ const OMXVCM4P10MEParams *pMEParams,
+ OMX_U32 *pSize
+);
+
+
+
+/**
+ * Function: omxVCM4P10_MEInit (6.3.5.1.2)
+ *
+ * Description:
+ * Initializes the vendor-specific specification structure required for the
+ * omxVCM4P10 motion estimation functions: BlockMatch_Integer and
+ * MotionEstimationMB. Memory for the specification structure *pMESpec must be
+ * allocated prior to calling the function, and should be aligned on a 4-byte
+ * boundary. The number of bytes required for the specification structure can
+ * be determined using the function omxVCM4P10_MEGetBufSize. Following
+ * initialization by this function, the vendor-specific structure *pMESpec
+ * should contain an implementation-specific representation of all motion
+ * estimation parameters received via the structure pMEParams, for example
+ * searchRange16x16, searchRange8x8, etc.
+ *
+ * Input Arguments:
+ *
+ * MEmode - motion estimation mode; available modes are defined by the
+ * enumerated type OMXVCM4P10MEMode
+ * pMEParams - motion estimation parameters
+ * pMESpec - pointer to the uninitialized ME specification structure
+ *
+ * Output Arguments:
+ *
+ * pMESpec - pointer to the initialized ME specification structure
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - pMEParams or pSize is NULL.
+ * - an invalid value was specified for the parameter MEmode
+ * - a negative or zero value was specified for one of the search ranges
+ * (e.g., pMBParams >searchRange8x8, pMEParams->searchRange16x16, etc.)
+ * - either in isolation or in combination, one or more of the enables or
+ * search ranges in the structure *pMEParams were configured such
+ * that the requested behavior fails to comply with [ISO14496-10].
+ *
+ */
+OMXResult omxVCM4P10_MEInit (
+ OMXVCM4P10MEMode MEmode,
+ const OMXVCM4P10MEParams *pMEParams,
+ void *pMESpec
+);
+
+
+
+/**
+ * Function: omxVCM4P10_BlockMatch_Integer (6.3.5.2.1)
+ *
+ * Description:
+ * Performs integer block match. Returns best MV and associated cost.
+ *
+ * Input Arguments:
+ *
+ * pSrcOrgY - Pointer to the top-left corner of the current block:
+ * If iBlockWidth==4, 4-byte alignment required.
+ * If iBlockWidth==8, 8-byte alignment required.
+ * If iBlockWidth==16, 16-byte alignment required.
+ * pSrcRefY - Pointer to the top-left corner of the co-located block in the
+ * reference picture:
+ * If iBlockWidth==4, 4-byte alignment required.
+ * If iBlockWidth==8, 8-byte alignment required.
+ * If iBlockWidth==16, 16-byte alignment required.
+ * nSrcOrgStep - Stride of the original picture plane, expressed in terms
+ * of integer pixels; must be a multiple of iBlockWidth.
+ * nSrcRefStep - Stride of the reference picture plane, expressed in terms
+ * of integer pixels
+ * pRefRect - pointer to the valid reference rectangle inside the reference
+ * picture plane
+ * nCurrPointPos - position of the current block in the current plane
+ * iBlockWidth - Width of the current block, expressed in terms of integer
+ * pixels; must be equal to either 4, 8, or 16.
+ * iBlockHeight - Height of the current block, expressed in terms of
+ * integer pixels; must be equal to either 4, 8, or 16.
+ * nLamda - Lamda factor; used to compute motion cost
+ * pMVPred - Predicted MV; used to compute motion cost, expressed in terms
+ * of 1/4-pel units
+ * pMVCandidate - Candidate MV; used to initialize the motion search,
+ * expressed in terms of integer pixels
+ * pMESpec - pointer to the ME specification structure
+ *
+ * Output Arguments:
+ *
+ * pDstBestMV - Best MV resulting from integer search, expressed in terms
+ * of 1/4-pel units
+ * pBestCost - Motion cost associated with the best MV; computed as
+ * SAD+Lamda*BitsUsedByMV
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - any of the following pointers are NULL:
+ * pSrcOrgY, pSrcRefY, pRefRect, pMVPred, pMVCandidate, or pMESpec.
+ * - Either iBlockWidth or iBlockHeight are values other than 4, 8, or 16.
+ * - Any alignment restrictions are violated
+ *
+ */
+OMXResult omxVCM4P10_BlockMatch_Integer (
+ const OMX_U8 *pSrcOrgY,
+ OMX_S32 nSrcOrgStep,
+ const OMX_U8 *pSrcRefY,
+ OMX_S32 nSrcRefStep,
+ const OMXRect *pRefRect,
+ const OMXVCM4P2Coordinate *pCurrPointPos,
+ OMX_U8 iBlockWidth,
+ OMX_U8 iBlockHeight,
+ OMX_U32 nLamda,
+ const OMXVCMotionVector *pMVPred,
+ const OMXVCMotionVector *pMVCandidate,
+ OMXVCMotionVector *pBestMV,
+ OMX_S32 *pBestCost,
+ void *pMESpec
+);
+
+
+
+/**
+ * Function: omxVCM4P10_BlockMatch_Half (6.3.5.2.2)
+ *
+ * Description:
+ * Performs a half-pel block match using results from a prior integer search.
+ * Returns the best MV and associated cost. This function estimates the
+ * half-pixel motion vector by interpolating the integer resolution motion
+ * vector referenced by the input parameter pSrcDstBestMV, i.e., the initial
+ * integer MV is generated externally. The function
+ * omxVCM4P10_BlockMatch_Integer may be used for integer motion estimation.
+ *
+ * Input Arguments:
+ *
+ * pSrcOrgY - Pointer to the current position in original picture plane:
+ * If iBlockWidth==4, 4-byte alignment required.
+ * If iBlockWidth==8, 8-byte alignment required.
+ * If iBlockWidth==16, 16-byte alignment required.
+ * pSrcRefY - Pointer to the top-left corner of the co-located block in the
+ * reference picture:
+ * If iBlockWidth==4, 4-byte alignment required.
+ * If iBlockWidth==8, 8-byte alignment required.
+ * If iBlockWidth==16, 16-byte alignment required.
+ * nSrcOrgStep - Stride of the original picture plane in terms of full
+ * pixels; must be a multiple of iBlockWidth.
+ * nSrcRefStep - Stride of the reference picture plane in terms of full
+ * pixels
+ * iBlockWidth - Width of the current block in terms of full pixels; must
+ * be equal to either 4, 8, or 16.
+ * iBlockHeight - Height of the current block in terms of full pixels; must
+ * be equal to either 4, 8, or 16.
+ * nLamda - Lamda factor, used to compute motion cost
+ * pMVPred - Predicted MV, represented in terms of 1/4-pel units; used to
+ * compute motion cost
+ * pSrcDstBestMV - The best MV resulting from a prior integer search,
+ * represented in terms of 1/4-pel units
+ *
+ * Output Arguments:
+ *
+ * pSrcDstBestMV - Best MV resulting from the half-pel search, expressed in
+ * terms of 1/4-pel units
+ * pBestCost - Motion cost associated with the best MV; computed as
+ * SAD+Lamda*BitsUsedByMV
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - any of the following pointers is NULL: pSrcOrgY, pSrcRefY,
+ * pSrcDstBestMV, pMVPred, pBestCost
+ * - iBlockWidth or iBlockHeight are equal to values other than 4, 8, or 16.
+ * - Any alignment restrictions are violated
+ *
+ */
+OMXResult omxVCM4P10_BlockMatch_Half (
+ const OMX_U8 *pSrcOrgY,
+ OMX_S32 nSrcOrgStep,
+ const OMX_U8 *pSrcRefY,
+ OMX_S32 nSrcRefStep,
+ OMX_U8 iBlockWidth,
+ OMX_U8 iBlockHeight,
+ OMX_U32 nLamda,
+ const OMXVCMotionVector *pMVPred,
+ OMXVCMotionVector *pSrcDstBestMV,
+ OMX_S32 *pBestCost
+);
+
+
+
+/**
+ * Function: omxVCM4P10_BlockMatch_Quarter (6.3.5.2.3)
+ *
+ * Description:
+ * Performs a quarter-pel block match using results from a prior half-pel
+ * search. Returns the best MV and associated cost. This function estimates
+ * the quarter-pixel motion vector by interpolating the half-pel resolution
+ * motion vector referenced by the input parameter pSrcDstBestMV, i.e., the
+ * initial half-pel MV is generated externally. The function
+ * omxVCM4P10_BlockMatch_Half may be used for half-pel motion estimation.
+ *
+ * Input Arguments:
+ *
+ * pSrcOrgY - Pointer to the current position in original picture plane:
+ * If iBlockWidth==4, 4-byte alignment required.
+ * If iBlockWidth==8, 8-byte alignment required.
+ * If iBlockWidth==16, 16-byte alignment required.
+ * pSrcRefY - Pointer to the top-left corner of the co-located block in the
+ * reference picture:
+ * If iBlockWidth==4, 4-byte alignment required.
+ * If iBlockWidth==8, 8-byte alignment required.
+ * If iBlockWidth==16, 16-byte alignment required.
+ * nSrcOrgStep - Stride of the original picture plane in terms of full
+ * pixels; must be a multiple of iBlockWidth.
+ * nSrcRefStep - Stride of the reference picture plane in terms of full
+ * pixels
+ * iBlockWidth - Width of the current block in terms of full pixels; must
+ * be equal to either 4, 8, or 16.
+ * iBlockHeight - Height of the current block in terms of full pixels; must
+ * be equal to either 4, 8, or 16.
+ * nLamda - Lamda factor, used to compute motion cost
+ * pMVPred - Predicted MV, represented in terms of 1/4-pel units; used to
+ * compute motion cost
+ * pSrcDstBestMV - The best MV resulting from a prior half-pel search,
+ * represented in terms of 1/4 pel units
+ *
+ * Output Arguments:
+ *
+ * pSrcDstBestMV - Best MV resulting from the quarter-pel search, expressed
+ * in terms of 1/4-pel units
+ * pBestCost - Motion cost associated with the best MV; computed as
+ * SAD+Lamda*BitsUsedByMV
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - One or more of the following pointers is NULL:
+ * pSrcOrgY, pSrcRefY, pSrcDstBestMV, pMVPred, pBestCost
+ * - iBlockWidth or iBlockHeight are equal to values other than 4, 8, or 16.
+ * - Any alignment restrictions are violated
+ *
+ */
+OMXResult omxVCM4P10_BlockMatch_Quarter (
+ const OMX_U8 *pSrcOrgY,
+ OMX_S32 nSrcOrgStep,
+ const OMX_U8 *pSrcRefY,
+ OMX_S32 nSrcRefStep,
+ OMX_U8 iBlockWidth,
+ OMX_U8 iBlockHeight,
+ OMX_U32 nLamda,
+ const OMXVCMotionVector *pMVPred,
+ OMXVCMotionVector *pSrcDstBestMV,
+ OMX_S32 *pBestCost
+);
+
+
+
+/**
+ * Function: omxVCM4P10_MotionEstimationMB (6.3.5.3.1)
+ *
+ * Description:
+ * Performs MB-level motion estimation and selects best motion estimation
+ * strategy from the set of modes supported in baseline profile [ISO14496-10].
+ *
+ * Input Arguments:
+ *
+ * pSrcCurrBuf - Pointer to the current position in original picture plane;
+ * 16-byte alignment required
+ * pSrcRefBufList - Pointer to an array with 16 entries. Each entry points
+ * to the top-left corner of the co-located MB in a reference
+ * picture. The array is filled from low-to-high with valid
+ * reference frame pointers; the unused high entries should be set
+ * to NULL. Ordering of the reference frames should follow
+ * [ISO14496-10] subclause 8.2.4 Decoding Process for Reference
+ * Picture Lists. The entries must be 16-byte aligned.
+ * pSrcRecBuf - Pointer to the top-left corner of the co-located MB in the
+ * reconstructed picture; must be 16-byte aligned.
+ * SrcCurrStep - Width of the original picture plane in terms of full
+ * pixels; must be a multiple of 16.
+ * SrcRefStep - Width of the reference picture plane in terms of full
+ * pixels; must be a multiple of 16.
+ * SrcRecStep - Width of the reconstructed picture plane in terms of full
+ * pixels; must be a multiple of 16.
+ * pRefRect - Pointer to the valid reference rectangle; relative to the
+ * image origin.
+ * pCurrPointPos - Position of the current macroblock in the current plane.
+ * Lambda - Lagrange factor for computing the cost function
+ * pMESpec - Pointer to the motion estimation specification structure; must
+ * have been allocated and initialized prior to calling this
+ * function.
+ * pMBInter - Array, of dimension four, containing pointers to information
+ * associated with four adjacent type INTER MBs (Left, Top,
+ * Top-Left, Top-Right). Any pointer in the array may be set equal
+ * to NULL if the corresponding MB doesn t exist or is not of type
+ * INTER.
+ * - pMBInter[0] - Pointer to left MB information
+ * - pMBInter[1] - Pointer to top MB information
+ * - pMBInter[2] - Pointer to top-left MB information
+ * - pMBInter[3] - Pointer to top-right MB information
+ * pMBIntra - Array, of dimension four, containing pointers to information
+ * associated with four adjacent type INTRA MBs (Left, Top,
+ * Top-Left, Top-Right). Any pointer in the array may be set equal
+ * to NULL if the corresponding MB doesn t exist or is not of type
+ * INTRA.
+ * - pMBIntra[0] - Pointer to left MB information
+ * - pMBIntra[1] - Pointer to top MB information
+ * - pMBIntra[2] - Pointer to top-left MB information
+ * - pMBIntra[3] - Pointer to top-right MB information
+ * pSrcDstMBCurr - Pointer to information structure for the current MB.
+ * The following entries should be set prior to calling the
+ * function: sliceID - the number of the slice the to which the
+ * current MB belongs.
+ *
+ * Output Arguments:
+ *
+ * pDstCost - Pointer to the minimum motion cost for the current MB.
+ * pDstBlockSAD - Pointer to the array of SADs for each of the sixteen luma
+ * 4x4 blocks in each MB. The block SADs are in scan order for
+ * each MB. For implementations that cannot compute the SAD values
+ * individually, the maximum possible value (0xffff) is returned
+ * for each of the 16 block SAD entries.
+ * pSrcDstMBCurr - Pointer to updated information structure for the current
+ * MB after MB-level motion estimation has been completed. The
+ * following fields are updated by the ME function. The following
+ * parameter set quantifies the MB-level ME search results:
+ * - MbType
+ * - subMBType[4]
+ * - pMV0[4][4]
+ * - pMVPred[4][4]
+ * - pRefL0Idx[4]
+ * - Intra16x16PredMode
+ * - pIntra4x4PredMode[4][4]
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - One or more of the following pointers is NULL: pSrcCurrBuf,
+ * pSrcRefBufList, pSrcRecBuf, pRefRect, pCurrPointPos, pMESpec,
+ * pMBInter, pMBIntra,pSrcDstMBCurr, pDstCost, pSrcRefBufList[0]
+ * - SrcRefStep, SrcRecStep are not multiples of 16
+ * - iBlockWidth or iBlockHeight are values other than 4, 8, or 16.
+ * - Any alignment restrictions are violated
+ *
+ */
+OMXResult omxVCM4P10_MotionEstimationMB (
+ const OMX_U8 *pSrcCurrBuf,
+ OMX_S32 SrcCurrStep,
+ const OMX_U8 *pSrcRefBufList[15],
+ OMX_S32 SrcRefStep,
+ const OMX_U8 *pSrcRecBuf,
+ OMX_S32 SrcRecStep,
+ const OMXRect *pRefRect,
+ const OMXVCM4P2Coordinate *pCurrPointPos,
+ OMX_U32 Lambda,
+ void *pMESpec,
+ const OMXVCM4P10MBInfoPtr *pMBInter,
+ const OMXVCM4P10MBInfoPtr *pMBIntra,
+ OMXVCM4P10MBInfoPtr pSrcDstMBCurr,
+ OMX_INT *pDstCost,
+ OMX_U16 *pDstBlockSAD
+);
+
+
+
+/**
+ * Function: omxVCM4P10_SAD_4x (6.3.5.4.1)
+ *
+ * Description:
+ * This function calculates the SAD for 4x8 and 4x4 blocks.
+ *
+ * Input Arguments:
+ *
+ * pSrcOrg -Pointer to the original block; must be aligned on a 4-byte
+ * boundary.
+ * iStepOrg -Step of the original block buffer; must be a multiple of 4.
+ * pSrcRef -Pointer to the reference block
+ * iStepRef -Step of the reference block buffer
+ * iHeight -Height of the block; must be equal to either 4 or 8.
+ *
+ * Output Arguments:
+ *
+ * pDstSAD -Pointer of result SAD
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - One or more of the following pointers is NULL:
+ * pSrcOrg, pSrcRef, or pDstSAD
+ * - iHeight is not equal to either 4 or 8.
+ * - iStepOrg is not a multiple of 4
+ * - Any alignment restrictions are violated
+ *
+ */
+OMXResult omxVCM4P10_SAD_4x (
+ const OMX_U8 *pSrcOrg,
+ OMX_U32 iStepOrg,
+ const OMX_U8 *pSrcRef,
+ OMX_U32 iStepRef,
+ OMX_S32 *pDstSAD,
+ OMX_U32 iHeight
+);
+
+
+
+/**
+ * Function: omxVCM4P10_SADQuar_4x (6.3.5.4.2)
+ *
+ * Description:
+ * This function calculates the SAD between one block (pSrc) and the average
+ * of the other two (pSrcRef0 and pSrcRef1) for 4x8 or 4x4 blocks. Rounding
+ * is applied according to the convention (a+b+1)>>1.
+ *
+ * Input Arguments:
+ *
+ * pSrc - Pointer to the original block; must be aligned on a 4-byte
+ * boundary.
+ * pSrcRef0 - Pointer to reference block 0
+ * pSrcRef1 - Pointer to reference block 1
+ * iSrcStep - Step of the original block buffer; must be a multiple of 4.
+ * iRefStep0 - Step of reference block 0
+ * iRefStep1 - Step of reference block 1
+ * iHeight - Height of the block; must be equal to either 4 or 8.
+ *
+ * Output Arguments:
+ *
+ * pDstSAD - Pointer of result SAD
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - iHeight is not equal to either 4 or 8.
+ * - One or more of the following pointers is NULL: pSrc, pSrcRef0,
+ * pSrcRef1, pDstSAD.
+ * - iSrcStep is not a multiple of 4
+ * - Any alignment restrictions are violated
+ *
+ */
+OMXResult omxVCM4P10_SADQuar_4x (
+ const OMX_U8 *pSrc,
+ const OMX_U8 *pSrcRef0,
+ const OMX_U8 *pSrcRef1,
+ OMX_U32 iSrcStep,
+ OMX_U32 iRefStep0,
+ OMX_U32 iRefStep1,
+ OMX_U32 *pDstSAD,
+ OMX_U32 iHeight
+);
+
+
+
+/**
+ * Function: omxVCM4P10_SADQuar_8x (6.3.5.4.3)
+ *
+ * Description:
+ * This function calculates the SAD between one block (pSrc) and the average
+ * of the other two (pSrcRef0 and pSrcRef1) for 8x16, 8x8, or 8x4 blocks.
+ * Rounding is applied according to the convention (a+b+1)>>1.
+ *
+ * Input Arguments:
+ *
+ * pSrc - Pointer to the original block; must be aligned on an 8-byte
+ * boundary.
+ * pSrcRef0 - Pointer to reference block 0
+ * pSrcRef1 - Pointer to reference block 1
+ * iSrcStep - Step of the original block buffer; must be a multiple of 8.
+ * iRefStep0 - Step of reference block 0
+ * iRefStep1 - Step of reference block 1
+ * iHeight - Height of the block; must be equal either 4, 8, or 16.
+ *
+ * Output Arguments:
+ *
+ * pDstSAD - Pointer of result SAD
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - iHeight is not equal to either 4, 8, or 16.
+ * - One or more of the following pointers is NULL: pSrc, pSrcRef0,
+ * pSrcRef1, pDstSAD.
+ * - iSrcStep is not a multiple of 8
+ * - Any alignment restrictions are violated
+ *
+ */
+OMXResult omxVCM4P10_SADQuar_8x (
+ const OMX_U8 *pSrc,
+ const OMX_U8 *pSrcRef0,
+ const OMX_U8 *pSrcRef1,
+ OMX_U32 iSrcStep,
+ OMX_U32 iRefStep0,
+ OMX_U32 iRefStep1,
+ OMX_U32 *pDstSAD,
+ OMX_U32 iHeight
+);
+
+
+
+/**
+ * Function: omxVCM4P10_SADQuar_16x (6.3.5.4.4)
+ *
+ * Description:
+ * This function calculates the SAD between one block (pSrc) and the average
+ * of the other two (pSrcRef0 and pSrcRef1) for 16x16 or 16x8 blocks.
+ * Rounding is applied according to the convention (a+b+1)>>1.
+ *
+ * Input Arguments:
+ *
+ * pSrc - Pointer to the original block; must be aligned on a 16-byte
+ * boundary.
+ * pSrcRef0 - Pointer to reference block 0
+ * pSrcRef1 - Pointer to reference block 1
+ * iSrcStep - Step of the original block buffer; must be a multiple of 16
+ * iRefStep0 - Step of reference block 0
+ * iRefStep1 - Step of reference block 1
+ * iHeight - Height of the block; must be equal to either 8 or 16
+ *
+ * Output Arguments:
+ *
+ * pDstSAD -Pointer of result SAD
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - iHeight is not equal to either 8 or 16.
+ * - One or more of the following pointers is NULL: pSrc, pSrcRef0,
+ * pSrcRef1, pDstSAD.
+ * - iSrcStep is not a multiple of 16
+ * - Any alignment restrictions are violated
+ *
+ */
+OMXResult omxVCM4P10_SADQuar_16x (
+ const OMX_U8 *pSrc,
+ const OMX_U8 *pSrcRef0,
+ const OMX_U8 *pSrcRef1,
+ OMX_U32 iSrcStep,
+ OMX_U32 iRefStep0,
+ OMX_U32 iRefStep1,
+ OMX_U32 *pDstSAD,
+ OMX_U32 iHeight
+);
+
+
+
+/**
+ * Function: omxVCM4P10_SATD_4x4 (6.3.5.4.5)
+ *
+ * Description:
+ * This function calculates the sum of absolute transform differences (SATD)
+ * for a 4x4 block by applying a Hadamard transform to the difference block
+ * and then calculating the sum of absolute coefficient values.
+ *
+ * Input Arguments:
+ *
+ * pSrcOrg - Pointer to the original block; must be aligned on a 4-byte
+ * boundary
+ * iStepOrg - Step of the original block buffer; must be a multiple of 4
+ * pSrcRef - Pointer to the reference block; must be aligned on a 4-byte
+ * boundary
+ * iStepRef - Step of the reference block buffer; must be a multiple of 4
+ *
+ * Output Arguments:
+ *
+ * pDstSAD - pointer to the resulting SAD
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL:
+ * pSrcOrg, pSrcRef, or pDstSAD either pSrcOrg
+ * - pSrcRef is not aligned on a 4-byte boundary
+ * - iStepOrg <= 0 or iStepOrg is not a multiple of 4
+ * - iStepRef <= 0 or iStepRef is not a multiple of 4
+ *
+ */
+OMXResult omxVCM4P10_SATD_4x4 (
+ const OMX_U8 *pSrcOrg,
+ OMX_U32 iStepOrg,
+ const OMX_U8 *pSrcRef,
+ OMX_U32 iStepRef,
+ OMX_U32 *pDstSAD
+);
+
+
+
+/**
+ * Function: omxVCM4P10_InterpolateHalfHor_Luma (6.3.5.5.1)
+ *
+ * Description:
+ * This function performs interpolation for two horizontal 1/2-pel positions
+ * (-1/2,0) and (1/2, 0) - around a full-pel position.
+ *
+ * Input Arguments:
+ *
+ * pSrc - Pointer to the top-left corner of the block used to interpolate in
+ * the reconstruction frame plane.
+ * iSrcStep - Step of the source buffer.
+ * iDstStep - Step of the destination(interpolation) buffer; must be a
+ * multiple of iWidth.
+ * iWidth - Width of the current block; must be equal to either 4, 8, or 16
+ * iHeight - Height of the current block; must be equal to 4, 8, or 16
+ *
+ * Output Arguments:
+ *
+ * pDstLeft -Pointer to the interpolation buffer of the left -pel position
+ * (-1/2, 0)
+ * If iWidth==4, 4-byte alignment required.
+ * If iWidth==8, 8-byte alignment required.
+ * If iWidth==16, 16-byte alignment required.
+ * pDstRight -Pointer to the interpolation buffer of the right -pel
+ * position (1/2, 0)
+ * If iWidth==4, 4-byte alignment required.
+ * If iWidth==8, 8-byte alignment required.
+ * If iWidth==16, 16-byte alignment required.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL:
+ * pSrc, pDstLeft, or pDstRight
+ * - iWidth or iHeight have values other than 4, 8, or 16
+ * - iWidth==4 but pDstLeft and/or pDstRight is/are not aligned on a 4-byte boundary
+ * - iWidth==8 but pDstLeft and/or pDstRight is/are not aligned on a 8-byte boundary
+ * - iWidth==16 but pDstLeft and/or pDstRight is/are not aligned on a 16-byte boundary
+ * - any alignment restrictions are violated
+ *
+ */
+OMXResult omxVCM4P10_InterpolateHalfHor_Luma (
+ const OMX_U8 *pSrc,
+ OMX_U32 iSrcStep,
+ OMX_U8 *pDstLeft,
+ OMX_U8 *pDstRight,
+ OMX_U32 iDstStep,
+ OMX_U32 iWidth,
+ OMX_U32 iHeight
+);
+
+
+
+/**
+ * Function: omxVCM4P10_InterpolateHalfVer_Luma (6.3.5.5.2)
+ *
+ * Description:
+ * This function performs interpolation for two vertical 1/2-pel positions -
+ * (0, -1/2) and (0, 1/2) - around a full-pel position.
+ *
+ * Input Arguments:
+ *
+ * pSrc - Pointer to top-left corner of block used to interpolate in the
+ * reconstructed frame plane
+ * iSrcStep - Step of the source buffer.
+ * iDstStep - Step of the destination (interpolation) buffer; must be a
+ * multiple of iWidth.
+ * iWidth - Width of the current block; must be equal to either 4, 8, or 16
+ * iHeight - Height of the current block; must be equal to either 4, 8, or 16
+ *
+ * Output Arguments:
+ *
+ * pDstUp -Pointer to the interpolation buffer of the -pel position above
+ * the current full-pel position (0, -1/2)
+ * If iWidth==4, 4-byte alignment required.
+ * If iWidth==8, 8-byte alignment required.
+ * If iWidth==16, 16-byte alignment required.
+ * pDstDown -Pointer to the interpolation buffer of the -pel position below
+ * the current full-pel position (0, 1/2)
+ * If iWidth==4, 4-byte alignment required.
+ * If iWidth==8, 8-byte alignment required.
+ * If iWidth==16, 16-byte alignment required.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL:
+ * pSrc, pDstUp, or pDstDown
+ * - iWidth or iHeight have values other than 4, 8, or 16
+ * - iWidth==4 but pDstUp and/or pDstDown is/are not aligned on a 4-byte boundary
+ * - iWidth==8 but pDstUp and/or pDstDown is/are not aligned on a 8-byte boundary
+ * - iWidth==16 but pDstUp and/or pDstDown is/are not aligned on a 16-byte boundary
+ *
+ */
+OMXResult omxVCM4P10_InterpolateHalfVer_Luma (
+ const OMX_U8 *pSrc,
+ OMX_U32 iSrcStep,
+ OMX_U8 *pDstUp,
+ OMX_U8 *pDstDown,
+ OMX_U32 iDstStep,
+ OMX_U32 iWidth,
+ OMX_U32 iHeight
+);
+
+
+
+/**
+ * Function: omxVCM4P10_Average_4x (6.3.5.5.3)
+ *
+ * Description:
+ * This function calculates the average of two 4x4, 4x8 blocks. The result
+ * is rounded according to (a+b+1)/2.
+ *
+ * Input Arguments:
+ *
+ * pPred0 - Pointer to the top-left corner of reference block 0
+ * pPred1 - Pointer to the top-left corner of reference block 1
+ * iPredStep0 - Step of reference block 0; must be a multiple of 4.
+ * iPredStep1 - Step of reference block 1; must be a multiple of 4.
+ * iDstStep - Step of the destination buffer; must be a multiple of 4.
+ * iHeight - Height of the blocks; must be either 4 or 8.
+ *
+ * Output Arguments:
+ *
+ * pDstPred - Pointer to the destination buffer. 4-byte alignment required.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL:
+ * pPred0, pPred1, or pDstPred
+ * - pDstPred is not aligned on a 4-byte boundary
+ * - iPredStep0 <= 0 or iPredStep0 is not a multiple of 4
+ * - iPredStep1 <= 0 or iPredStep1 is not a multiple of 4
+ * - iDstStep <= 0 or iDstStep is not a multiple of 4
+ * - iHeight is not equal to either 4 or 8
+ *
+ */
+OMXResult omxVCM4P10_Average_4x (
+ const OMX_U8 *pPred0,
+ const OMX_U8 *pPred1,
+ OMX_U32 iPredStep0,
+ OMX_U32 iPredStep1,
+ OMX_U8 *pDstPred,
+ OMX_U32 iDstStep,
+ OMX_U32 iHeight
+);
+
+
+
+/**
+ * Function: omxVCM4P10_TransformQuant_ChromaDC (6.3.5.6.1)
+ *
+ * Description:
+ * This function performs 2x2 Hadamard transform of chroma DC coefficients
+ * and then quantizes the coefficients.
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - Pointer to the 2x2 array of chroma DC coefficients. 8-byte
+ * alignment required.
+ * iQP - Quantization parameter; must be in the range [0,51].
+ * bIntra - Indicate whether this is an INTRA block. 1-INTRA, 0-INTER
+ *
+ * Output Arguments:
+ *
+ * pSrcDst - Pointer to transformed and quantized coefficients. 8-byte
+ * alignment required.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL:
+ * pSrcDst
+ * - pSrcDst is not aligned on an 8-byte boundary
+ *
+ */
+OMXResult omxVCM4P10_TransformQuant_ChromaDC (
+ OMX_S16 *pSrcDst,
+ OMX_U32 iQP,
+ OMX_U8 bIntra
+);
+
+
+
+/**
+ * Function: omxVCM4P10_TransformQuant_LumaDC (6.3.5.6.2)
+ *
+ * Description:
+ * This function performs a 4x4 Hadamard transform of luma DC coefficients
+ * and then quantizes the coefficients.
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - Pointer to the 4x4 array of luma DC coefficients. 16-byte
+ * alignment required.
+ * iQP - Quantization parameter; must be in the range [0,51].
+ *
+ * Output Arguments:
+ *
+ * pSrcDst - Pointer to transformed and quantized coefficients. 16-byte
+ * alignment required.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL: pSrcDst
+ * - pSrcDst is not aligned on an 16-byte boundary
+ *
+ */
+OMXResult omxVCM4P10_TransformQuant_LumaDC (
+ OMX_S16 *pSrcDst,
+ OMX_U32 iQP
+);
+
+
+
+/**
+ * Function: omxVCM4P10_InvTransformDequant_LumaDC (6.3.5.6.3)
+ *
+ * Description:
+ * This function performs inverse 4x4 Hadamard transform and then dequantizes
+ * the coefficients.
+ *
+ * Input Arguments:
+ *
+ * pSrc - Pointer to the 4x4 array of the 4x4 Hadamard-transformed and
+ * quantized coefficients. 16 byte alignment required.
+ * iQP - Quantization parameter; must be in the range [0,51].
+ *
+ * Output Arguments:
+ *
+ * pDst - Pointer to inverse-transformed and dequantized coefficients.
+ * 16-byte alignment required.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL: pSrc
+ * - pSrc or pDst is not aligned on a 16-byte boundary
+ *
+ */
+OMXResult omxVCM4P10_InvTransformDequant_LumaDC (
+ const OMX_S16 *pSrc,
+ OMX_S16 *pDst,
+ OMX_U32 iQP
+);
+
+
+
+/**
+ * Function: omxVCM4P10_InvTransformDequant_ChromaDC (6.3.5.6.4)
+ *
+ * Description:
+ * This function performs inverse 2x2 Hadamard transform and then dequantizes
+ * the coefficients.
+ *
+ * Input Arguments:
+ *
+ * pSrc - Pointer to the 2x2 array of the 2x2 Hadamard-transformed and
+ * quantized coefficients. 8 byte alignment required.
+ * iQP - Quantization parameter; must be in the range [0,51].
+ *
+ * Output Arguments:
+ *
+ * pDst - Pointer to inverse-transformed and dequantized coefficients.
+ * 8-byte alignment required.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL: pSrc
+ * - pSrc or pDst is not aligned on an 8-byte boundary
+ *
+ */
+OMXResult omxVCM4P10_InvTransformDequant_ChromaDC (
+ const OMX_S16 *pSrc,
+ OMX_S16 *pDst,
+ OMX_U32 iQP
+);
+
+
+
+/**
+ * Function: omxVCM4P10_InvTransformResidualAndAdd (6.3.5.7.1)
+ *
+ * Description:
+ * This function performs inverse an 4x4 integer transformation to produce
+ * the difference signal and then adds the difference to the prediction to get
+ * the reconstructed signal.
+ *
+ * Input Arguments:
+ *
+ * pSrcPred - Pointer to prediction signal. 4-byte alignment required.
+ * pDequantCoeff - Pointer to the transformed coefficients. 8-byte
+ * alignment required.
+ * iSrcPredStep - Step of the prediction buffer; must be a multiple of 4.
+ * iDstReconStep - Step of the destination reconstruction buffer; must be a
+ * multiple of 4.
+ * bAC - Indicate whether there is AC coefficients in the coefficients
+ * matrix.
+ *
+ * Output Arguments:
+ *
+ * pDstRecon -Pointer to the destination reconstruction buffer. 4-byte
+ * alignment required.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL:
+ * pSrcPred, pDequantCoeff, pDstRecon
+ * - pSrcPred is not aligned on a 4-byte boundary
+ * - iSrcPredStep or iDstReconStep is not a multiple of 4.
+ * - pDequantCoeff is not aligned on an 8-byte boundary
+ *
+ */
+OMXResult omxVCM4P10_InvTransformResidualAndAdd (
+ const OMX_U8 *pSrcPred,
+ const OMX_S16 *pDequantCoeff,
+ OMX_U8 *pDstRecon,
+ OMX_U32 iSrcPredStep,
+ OMX_U32 iDstReconStep,
+ OMX_U8 bAC
+);
+
+
+
+/**
+ * Function: omxVCM4P10_SubAndTransformQDQResidual (6.3.5.8.1)
+ *
+ * Description:
+ * This function subtracts the prediction signal from the original signal to
+ * produce the difference signal and then performs a 4x4 integer transform and
+ * quantization. The quantized transformed coefficients are stored as
+ * pDstQuantCoeff. This function can also output dequantized coefficients or
+ * unquantized DC coefficients optionally by setting the pointers
+ * pDstDeQuantCoeff, pDCCoeff.
+ *
+ * Input Arguments:
+ *
+ * pSrcOrg - Pointer to original signal. 4-byte alignment required.
+ * pSrcPred - Pointer to prediction signal. 4-byte alignment required.
+ * iSrcOrgStep - Step of the original signal buffer; must be a multiple of
+ * 4.
+ * iSrcPredStep - Step of the prediction signal buffer; must be a multiple
+ * of 4.
+ * pNumCoeff -Number of non-zero coefficients after quantization. If this
+ * parameter is not required, it is set to NULL.
+ * nThreshSAD - Zero-block early detection threshold. If this parameter is
+ * not required, it is set to 0.
+ * iQP - Quantization parameter; must be in the range [0,51].
+ * bIntra - Indicates whether this is an INTRA block, either 1-INTRA or
+ * 0-INTER
+ *
+ * Output Arguments:
+ *
+ * pDstQuantCoeff - Pointer to the quantized transformed coefficients.
+ * 8-byte alignment required.
+ * pDstDeQuantCoeff - Pointer to the dequantized transformed coefficients
+ * if this parameter is not equal to NULL. 8-byte alignment
+ * required.
+ * pDCCoeff - Pointer to the unquantized DC coefficient if this parameter
+ * is not equal to NULL.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL:
+ * pSrcOrg, pSrcPred, pNumCoeff, pDstQuantCoeff,
+ * pDstDeQuantCoeff, pDCCoeff
+ * - pSrcOrg is not aligned on a 4-byte boundary
+ * - pSrcPred is not aligned on a 4-byte boundary
+ * - iSrcOrgStep is not a multiple of 4
+ * - iSrcPredStep is not a multiple of 4
+ * - pDstQuantCoeff or pDstDeQuantCoeff is not aligned on an 8-byte boundary
+ *
+ */
+OMXResult omxVCM4P10_SubAndTransformQDQResidual (
+ const OMX_U8 *pSrcOrg,
+ const OMX_U8 *pSrcPred,
+ OMX_U32 iSrcOrgStep,
+ OMX_U32 iSrcPredStep,
+ OMX_S16 *pDstQuantCoeff,
+ OMX_S16 *pDstDeQuantCoeff,
+ OMX_S16 *pDCCoeff,
+ OMX_S8 *pNumCoeff,
+ OMX_U32 nThreshSAD,
+ OMX_U32 iQP,
+ OMX_U8 bIntra
+);
+
+
+
+/**
+ * Function: omxVCM4P10_GetVLCInfo (6.3.5.9.1)
+ *
+ * Description:
+ * This function extracts run-length encoding (RLE) information from the
+ * coefficient matrix. The results are returned in an OMXVCM4P10VLCInfo
+ * structure.
+ *
+ * Input Arguments:
+ *
+ * pSrcCoeff - pointer to the transform coefficient matrix. 8-byte
+ * alignment required.
+ * pScanMatrix - pointer to the scan order definition matrix. For a luma
+ * block the scan matrix should follow [ISO14496-10] section 8.5.4,
+ * and should contain the values 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13,
+ * 10, 7, 11, 14, 15. For a chroma block, the scan matrix should
+ * contain the values 0, 1, 2, 3.
+ * bAC - indicates presence of a DC coefficient; 0 = DC coefficient
+ * present, 1= DC coefficient absent.
+ * MaxNumCoef - specifies the number of coefficients contained in the
+ * transform coefficient matrix, pSrcCoeff. The value should be 16
+ * for blocks of type LUMADC, LUMAAC, LUMALEVEL, and CHROMAAC. The
+ * value should be 4 for blocks of type CHROMADC.
+ *
+ * Output Arguments:
+ *
+ * pDstVLCInfo - pointer to structure that stores information for
+ * run-length coding.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL:
+ * pSrcCoeff, pScanMatrix, pDstVLCInfo
+ * - pSrcCoeff is not aligned on an 8-byte boundary
+ *
+ */
+OMXResult omxVCM4P10_GetVLCInfo (
+ const OMX_S16 *pSrcCoeff,
+ const OMX_U8 *pScanMatrix,
+ OMX_U8 bAC,
+ OMX_U32 MaxNumCoef,
+ OMXVCM4P10VLCInfo*pDstVLCInfo
+);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /** end of #define _OMXVC_H_ */
+
+/** EOF */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/api/omxVC_s.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/api/omxVC_s.h
new file mode 100644
index 0000000..be974d5
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/api/omxVC_s.h
@@ -0,0 +1,129 @@
+;/******************************************************************************
+;// Copyright (c) 1999-2005 The Khronos Group Inc. All Rights Reserved
+;//
+;//
+;//
+;//
+;//
+;//
+;//
+;//
+;******************************************************************************/
+
+;/** =============== Structure Definition for Sample Generation ============== */
+;/** transparent status */
+
+;enum {
+OMX_VIDEO_TRANSPARENT EQU 0; /** Wholly transparent */
+OMX_VIDEO_PARTIAL EQU 1; /** Partially transparent */
+OMX_VIDEO_OPAQUE EQU 2; /** Opaque */
+;}
+
+;/** direction */
+;enum {
+OMX_VIDEO_NONE EQU 0;
+OMX_VIDEO_HORIZONTAL EQU 1;
+OMX_VIDEO_VERTICAL EQU 2;
+;}
+
+;/** bilinear interpolation type */
+;enum {
+OMX_VIDEO_INTEGER_PIXEL EQU 0; /** case ¡°a¡± */
+OMX_VIDEO_HALF_PIXEL_X EQU 1; /** case ¡°b¡± */
+OMX_VIDEO_HALF_PIXEL_Y EQU 2; /** case ¡°c¡± */
+OMX_VIDEO_HALF_PIXEL_XY EQU 3; /** case ¡°d¡± */
+;}
+
+;enum {
+OMX_UPPER EQU 1; /** set if the above macroblock is available */
+OMX_LEFT EQU 2; /** set if the left macroblock is available */
+OMX_CENTER EQU 4;
+OMX_RIGHT EQU 8;
+OMX_LOWER EQU 16;
+OMX_UPPER_LEFT EQU 32; /** set if the above-left macroblock is available */
+OMX_UPPER_RIGHT EQU 64; /** set if the above-right macroblock is available */
+OMX_LOWER_LEFT EQU 128;
+OMX_LOWER_RIGHT EQU 256
+;}
+
+;enum {
+OMX_VIDEO_LUMINANCE EQU 0; /** Luminance component */
+OMX_VIDEO_CHROMINANCE EQU 1; /** chrominance component */
+OMX_VIDEO_ALPHA EQU 2; /** Alpha component */
+;}
+
+;enum {
+OMX_VIDEO_INTER EQU 0; /** P picture or P-VOP */
+OMX_VIDEO_INTER_Q EQU 1; /** P picture or P-VOP */
+OMX_VIDEO_INTER4V EQU 2; /** P picture or P-VOP */
+OMX_VIDEO_INTRA EQU 3; /** I and P picture; I- and P-VOP */
+OMX_VIDEO_INTRA_Q EQU 4; /** I and P picture; I- and P-VOP */
+OMX_VIDEO_INTER4V_Q EQU 5; /** P picture or P-VOP (H.263)*/
+OMX_VIDEO_DIRECT EQU 6; /** B picture or B-VOP (MPEG-4 only) */
+OMX_VIDEO_INTERPOLATE EQU 7; /** B picture or B-VOP */
+OMX_VIDEO_BACKWARD EQU 8; /** B picture or B-VOP */
+OMX_VIDEO_FORWARD EQU 9; /** B picture or B-VOP */
+OMX_VIDEO_NOTCODED EQU 10; /** B picture or B-VOP */
+;}
+
+;enum {
+OMX_16X16_VERT EQU 0; /** Intra_16x16_Vertical (prediction mode) */
+OMX_16X16_HOR EQU 1; /** Intra_16x16_Horizontal (prediction mode) */
+OMX_16X16_DC EQU 2; /** Intra_16x16_DC (prediction mode) */
+OMX_16X16_PLANE EQU 3; /** Intra_16x16_Plane (prediction mode) */
+;}
+
+;enum {
+OMX_4x4_VERT EQU 0; /** Intra_4x4_Vertical (prediction mode) */
+OMX_4x4_HOR EQU 1; /** Intra_4x4_Horizontal (prediction mode) */
+OMX_4x4_DC EQU 2; /** Intra_4x4_DC (prediction mode) */
+OMX_4x4_DIAG_DL EQU 3; /** Intra_4x4_Diagonal_Down_Left (prediction mode) */
+OMX_4x4_DIAG_DR EQU 4; /** Intra_4x4_Diagonal_Down_Right (prediction mode) */
+OMX_4x4_VR EQU 5; /** Intra_4x4_Vertical_Right (prediction mode) */
+OMX_4x4_HD EQU 6; /** Intra_4x4_Horizontal_Down (prediction mode) */
+OMX_4x4_VL EQU 7; /** Intra_4x4_Vertical_Left (prediction mode) */
+OMX_4x4_HU EQU 8; /** Intra_4x4_Horizontal_Up (prediction mode) */
+;}
+
+;enum {
+OMX_CHROMA_DC EQU 0; /** Intra_Chroma_DC (prediction mode) */
+OMX_CHROMA_HOR EQU 1; /** Intra_Chroma_Horizontal (prediction mode) */
+OMX_CHROMA_VERT EQU 2; /** Intra_Chroma_Vertical (prediction mode) */
+OMX_CHROMA_PLANE EQU 3; /** Intra_Chroma_Plane (prediction mode) */
+;}
+
+;typedef struct {
+x EQU 0;
+y EQU 4;
+;}OMXCoordinate;
+
+;typedef struct {
+dx EQU 0;
+dy EQU 2;
+;}OMXMotionVector;
+
+;typedef struct {
+xx EQU 0;
+yy EQU 4;
+width EQU 8;
+height EQU 12;
+;}OMXiRect;
+
+;typedef enum {
+OMX_VC_INTER EQU 0; /** P picture or P-VOP */
+OMX_VC_INTER_Q EQU 1; /** P picture or P-VOP */
+OMX_VC_INTER4V EQU 2; /** P picture or P-VOP */
+OMX_VC_INTRA EQU 3; /** I and P picture, I- and P-VOP */
+OMX_VC_INTRA_Q EQU 4; /** I and P picture, I- and P-VOP */
+OMX_VC_INTER4V_Q EQU 5; /** P picture or P-VOP (H.263)*/
+;} OMXVCM4P2MacroblockType;
+
+;enum {
+OMX_VC_NONE EQU 0
+OMX_VC_HORIZONTAL EQU 1
+OMX_VC_VERTICAL EQU 2
+;};
+
+
+ END
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/comm/src/omxVCCOMM_Copy16x16_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/comm/src/omxVCCOMM_Copy16x16_s.s
new file mode 100644
index 0000000..2663a70
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/comm/src/omxVCCOMM_Copy16x16_s.s
@@ -0,0 +1,148 @@
+ ;/**
+ ; * Function: omxVCCOMM_Copy16x16
+ ; *
+ ; * Description:
+ ; * Copies the reference 16x16 block to the current block.
+ ; * Parameters:
+ ; * [in] pSrc - pointer to the reference block in the source frame; must be aligned on an 16-byte boundary.
+ ; * [in] step - distance between the starts of consecutive lines in the reference frame, in bytes;
+ ; * must be a multiple of 16 and must be larger than or equal to 16.
+ ; * [out] pDst - pointer to the destination block; must be aligned on an 8-byte boundary.
+ ; * Return Value:
+ ; * OMX_Sts_NoErr - no error
+ ; * OMX_Sts_BadArgErr - bad arguments; returned under any of the following conditions:
+ ; * - one or more of the following pointers is NULL: pSrc, pDst
+ ; * - one or more of the following pointers is not aligned on an 16-byte boundary: pSrc, pDst
+ ; * - step <16 or step is not a multiple of 16.
+ ; */
+
+ INCLUDE omxtypes_s.h
+
+
+ M_VARIANTS ARM1136JS
+
+
+
+
+ IF ARM1136JS
+
+;//Input Arguments
+pSrc RN 0
+pDst RN 1
+step RN 2
+
+;//Local Variables
+Count RN 14
+X0 RN 2
+X1 RN 4
+
+Return RN 0
+
+ M_START omxVCCOMM_Copy16x16,r5
+
+
+
+ SUB Count,step,#8 ;//Count=step-8
+ LDRD X0,[pSrc],#8 ;//pSrc after loading pSrc=pSrc+8
+ LDRD X1,[pSrc],Count ;//pSrc after loading pSrc=pSrc+step
+
+ ;// loading 16 bytes and storing
+ STRD X0,[pDst],#8
+ LDRD X0,[pSrc],#8
+ STRD X1,[pDst],#8
+ LDRD X1,[pSrc],Count
+
+ ;// loading 16 bytes and storing
+ STRD X0,[pDst],#8
+ LDRD X0,[pSrc],#8
+ STRD X1,[pDst],#8
+ LDRD X1,[pSrc],Count
+
+ ;// loading 16 bytes and storing
+ STRD X0,[pDst],#8
+ LDRD X0,[pSrc],#8
+ STRD X1,[pDst],#8
+ LDRD X1,[pSrc],Count
+
+ ;// loading 16 bytes and storing
+ STRD X0,[pDst],#8
+ LDRD X0,[pSrc],#8
+ STRD X1,[pDst],#8
+ LDRD X1,[pSrc],Count
+
+ ;// loading 16 bytes and storing
+ STRD X0,[pDst],#8
+ LDRD X0,[pSrc],#8
+ STRD X1,[pDst],#8
+ LDRD X1,[pSrc],Count
+
+ ;// loading 16 bytes and storing
+ STRD X0,[pDst],#8
+ LDRD X0,[pSrc],#8
+ STRD X1,[pDst],#8
+ LDRD X1,[pSrc],Count
+
+ ;// loading 16 bytes and storing
+ STRD X0,[pDst],#8
+ LDRD X0,[pSrc],#8
+ STRD X1,[pDst],#8
+ LDRD X1,[pSrc],Count
+
+ ;// loading 16 bytes and storing
+ STRD X0,[pDst],#8
+ LDRD X0,[pSrc],#8
+ STRD X1,[pDst],#8
+ LDRD X1,[pSrc],Count
+
+ ;// loading 16 bytes and storing
+ STRD X0,[pDst],#8
+ LDRD X0,[pSrc],#8
+ STRD X1,[pDst],#8
+ LDRD X1,[pSrc],Count
+
+ ;// loading 16 bytes and storing
+ STRD X0,[pDst],#8
+ LDRD X0,[pSrc],#8
+ STRD X1,[pDst],#8
+ LDRD X1,[pSrc],Count
+
+ ;// loading 16 bytes and storing
+ STRD X0,[pDst],#8
+ LDRD X0,[pSrc],#8
+ STRD X1,[pDst],#8
+ LDRD X1,[pSrc],Count
+
+ ;// loading 16 bytes and storing
+ STRD X0,[pDst],#8
+ LDRD X0,[pSrc],#8
+ STRD X1,[pDst],#8
+ LDRD X1,[pSrc],Count
+
+ ;// loading 16 bytes and storing
+ STRD X0,[pDst],#8
+ LDRD X0,[pSrc],#8
+ STRD X1,[pDst],#8
+ LDRD X1,[pSrc],Count
+
+ ;// loading 16 bytes and storing
+ STRD X0,[pDst],#8
+ LDRD X0,[pSrc],#8
+ STRD X1,[pDst],#8
+ LDRD X1,[pSrc],Count
+
+ ;// loading 16 bytes and storing
+ STRD X0,[pDst],#8
+ LDRD X0,[pSrc],#8
+ STRD X1,[pDst],#8
+ LDRD X1,[pSrc],Count
+
+ STRD X0,[pDst],#8
+ MOV Return,#OMX_Sts_NoErr
+ STRD X1,[pDst],#8
+
+
+ M_END
+ ENDIF
+
+ END
+
\ No newline at end of file
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/comm/src/omxVCCOMM_Copy8x8_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/comm/src/omxVCCOMM_Copy8x8_s.s
new file mode 100644
index 0000000..993873c
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/comm/src/omxVCCOMM_Copy8x8_s.s
@@ -0,0 +1,72 @@
+ ;/**
+ ; * Function: omxVCCOMM_Copy8x8
+ ; *
+ ; * Description:
+ ; * Copies the reference 8x8 block to the current block.
+ ; * Parameters:
+ ; * [in] pSrc - pointer to the reference block in the source frame; must be aligned on an 8-byte boundary.
+ ; * [in] step - distance between the starts of consecutive lines in the reference frame, in bytes;
+ ; * must be a multiple of 8 and must be larger than or equal to 8.
+ ; * [out] pDst - pointer to the destination block; must be aligned on an 8-byte boundary.
+ ; * Return Value:
+ ; * OMX_Sts_NoErr - no error
+ ; * OMX_Sts_BadArgErr - bad arguments; returned under any of the following conditions:
+ ; * - one or more of the following pointers is NULL: pSrc, pDst
+ ; * - one or more of the following pointers is not aligned on an 8-byte boundary: pSrc, pDst
+ ; * - step <8 or step is not a multiple of 8.
+ ; */
+
+ INCLUDE omxtypes_s.h
+
+
+ M_VARIANTS ARM1136JS
+
+
+
+
+ IF ARM1136JS
+
+;//Input Arguments
+pSrc RN 0
+pDst RN 1
+step RN 2
+
+;//Local Variables
+Count RN 14
+X0 RN 2
+X1 RN 4
+Return RN 0
+ M_START omxVCCOMM_Copy8x8,r5
+
+
+
+ MOV Count,step ;//Count=step
+
+ LDRD X0,[pSrc],Count ;//pSrc after loading : pSrc=pSrc+step
+ LDRD X1,[pSrc],Count
+
+ STRD X0,[pDst],#8
+ LDRD X0,[pSrc],Count
+ STRD X1,[pDst],#8
+ LDRD X1,[pSrc],Count
+
+ STRD X0,[pDst],#8
+ LDRD X0,[pSrc],Count
+ STRD X1,[pDst],#8
+ LDRD X1,[pSrc],Count
+
+ STRD X0,[pDst],#8
+ LDRD X0,[pSrc],Count
+ STRD X1,[pDst],#8
+ LDRD X1,[pSrc],Count
+
+ STRD X0,[pDst],#8
+ MOV Return,#OMX_Sts_NoErr
+ STRD X1,[pDst],#8
+
+
+ M_END
+ ENDIF
+
+ END
+
\ No newline at end of file
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/comm/src/omxVCCOMM_ExpandFrame_I_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/comm/src/omxVCCOMM_ExpandFrame_I_s.s
new file mode 100644
index 0000000..02b4b08
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/comm/src/omxVCCOMM_ExpandFrame_I_s.s
@@ -0,0 +1,189 @@
+;//
+;//
+;// File Name: omxVCCOMM_ExpandFrame_I_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 9641
+;// Date: Thursday, February 7, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+;// Description:
+;// This function will Expand Frame boundary pixels into Plane
+;//
+;//
+
+;// Include standard headers
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS ARM1136JS
+
+;// Import symbols required from other files
+;// (For example tables)
+
+
+;// Set debugging level
+DEBUG_ON SETL {FALSE}
+
+
+
+
+
+
+
+;// Guarding implementation by the processor name
+
+ IF ARM1136JS
+
+;//Input Registers
+
+pSrcDstPlane RN 0
+iFrameWidth RN 1
+iFrameHeight RN 2
+iExpandPels RN 3
+
+
+;//Output Registers
+
+result RN 0
+
+;//Local Scratch Registers
+
+iPlaneStep RN 4
+pTop RN 5
+pBottom RN 6
+pBottomIndex RN 7
+x RN 8
+y RN 9
+tempTop RN 10
+tempBot RN 11
+ColStep RN 12
+pLeft RN 5
+pRight RN 6
+pRightIndex RN 7
+tempLeft1 RN 10
+tempRight1 RN 11
+tempLeft2 RN 14
+tempRight2 RN 2
+indexY RN 14
+RowStep RN 12
+expandTo4bytes RN 1 ;// copy a byte to 4 bytes of a word
+
+ ;// Allocate stack memory required by the function
+
+
+ ;// Write function header
+ M_START omxVCCOMM_ExpandFrame_I,r11
+
+ ;// Define stack arguments
+ M_ARG iPlaneStepOnStack, 4
+
+ ;// Load argument from the stack
+ M_LDR iPlaneStep, iPlaneStepOnStack
+
+ MUL pTop,iExpandPels,iPlaneStep
+ MLA pBottom,iFrameHeight,iPlaneStep,pSrcDstPlane
+ SUB x,iFrameWidth,#4
+ MOV indexY,pTop
+ ADD ColStep,indexY,#4
+ SUB pBottomIndex,pBottom,iPlaneStep
+ SUB pTop,pSrcDstPlane,pTop
+
+
+ ADD pTop,pTop,x
+ ADD pBottom,pBottom,x
+
+ ;//------------------------------------------------------------------------
+ ;// The following improves upon the C implmentation
+ ;// The x and y loops are interchanged: This ensures that the values of
+ ;// pSrcDstPlane [x] and pSrcDstPlane [(iFrameHeight - 1) * iPlaneStep + x]
+ ;// which depend only on loop variable 'x' are loaded once and used in
+ ;// multiple stores in the 'Y' loop
+ ;//------------------------------------------------------------------------
+
+ ;// xloop
+ExpandFrameTopBotXloop
+
+ LDR tempTop,[pSrcDstPlane,x]
+ ;//------------------------------------------------------------------------
+ ;// pSrcDstPlane [(iFrameHeight - 1) * iPlaneStep + x] is simplified as:
+ ;// pSrcDstPlane + (iFrameHeight * iPlaneStep) - iPlaneStep + x ==
+ ;// pBottom - iPlaneStep + x == pBottomIndex [x]
+ ;// The value of pBottomIndex is calculated above this 'x' loop
+ ;//------------------------------------------------------------------------
+ LDR tempBot,[pBottomIndex,x]
+
+ ;// yloop
+ MOV y,iExpandPels
+
+ExpandFrameTopBotYloop
+ SUBS y,y,#1
+ M_STR tempTop,[pTop],iPlaneStep
+ M_STR tempBot,[pBottom],iPlaneStep
+ BGT ExpandFrameTopBotYloop
+
+ SUBS x,x,#4
+ SUB pTop,pTop,ColStep
+ SUB pBottom,pBottom,ColStep
+ BGE ExpandFrameTopBotXloop
+
+
+ ;// y loop
+ ;// The product is already calculated above : Reuse
+ ;//MUL indexY,iExpandPels,iPlaneStep
+
+ SUB pSrcDstPlane,pSrcDstPlane,indexY
+ SUB pLeft,pSrcDstPlane,iExpandPels ;// pLeft->points to the top left of the expanded block
+ ADD pRight,pSrcDstPlane,iFrameWidth
+ SUB pRightIndex,pRight,#1
+
+ ADD y,iFrameHeight,iExpandPels,LSL #1
+ LDR expandTo4bytes,=0x01010101
+
+ RSB RowStep,iExpandPels,iPlaneStep,LSL #1
+
+ ;// The Y Loop is unrolled twice
+ExpandFrameLeftRightYloop
+ LDRB tempLeft2,[pSrcDstPlane,iPlaneStep] ;// PreLoad the values
+ LDRB tempRight2,[pRightIndex,iPlaneStep]
+ M_LDRB tempLeft1,[pSrcDstPlane],iPlaneStep,LSL #1 ;// PreLoad the values
+ M_LDRB tempRight1,[pRightIndex],iPlaneStep,LSL #1
+
+ SUB x,iExpandPels,#4
+ MUL tempLeft2,tempLeft2,expandTo4bytes ;// Copy the single byte to 4 bytes
+ MUL tempRight2,tempRight2,expandTo4bytes
+ MUL tempLeft1,tempLeft1,expandTo4bytes ;// Copy the single byte to 4 bytes
+ MUL tempRight1,tempRight1,expandTo4bytes
+
+
+ ;// x loop
+ExpandFrameLeftRightXloop
+ SUBS x,x,#4
+ STR tempLeft2,[pLeft,iPlaneStep] ;// Store the 4 bytes at one go
+ STR tempRight2,[pRight,iPlaneStep]
+ STR tempLeft1,[pLeft],#4 ;// Store the 4 bytes at one go
+ STR tempRight1,[pRight],#4
+ BGE ExpandFrameLeftRightXloop
+
+ SUBS y,y,#2
+ ADD pLeft,pLeft,RowStep
+ ADD pRight,pRight,RowStep
+ BGT ExpandFrameLeftRightYloop
+
+
+ ;// Set return value
+
+ MOV result,#OMX_Sts_NoErr
+End
+
+ ;// Write function tail
+
+ M_END
+
+ ENDIF ;//ARM1136JS
+
+
+ END
\ No newline at end of file
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/api/armVCM4P10_CAVLCTables.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/api/armVCM4P10_CAVLCTables.h
new file mode 100644
index 0000000..4340f2a
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/api/armVCM4P10_CAVLCTables.h
@@ -0,0 +1,30 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: armVCM4P10_CAVLCTables.h
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Header file for optimized H.264 CALVC tables
+ *
+ */
+
+#ifndef ARMVCM4P10_CAVLCTABLES_H
+#define ARMVCM4P10_CAVLCTABLES_H
+
+/* CAVLC tables */
+
+extern const OMX_U16 *armVCM4P10_CAVLCCoeffTokenTables[18];
+extern const OMX_U16 *armVCM4P10_CAVLCTotalZeroTables[15];
+extern const OMX_U16 *armVCM4P10_CAVLCTotalZeros2x2Tables[3];
+extern const OMX_U16 *armVCM4P10_CAVLCRunBeforeTables[15];
+extern const OMX_U8 armVCM4P10_ZigZag_4x4[16];
+extern const OMX_U8 armVCM4P10_ZigZag_2x2[4];
+extern const OMX_S8 armVCM4P10_SuffixToLevel[7];
+
+#endif
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_Average_4x_Align_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_Average_4x_Align_unsafe_s.s
new file mode 100644
index 0000000..b2cd9d1
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_Average_4x_Align_unsafe_s.s
@@ -0,0 +1,222 @@
+;//
+;//
+;// File Name: armVCM4P10_Average_4x_Align_unsafe_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 9641
+;// Date: Thursday, February 7, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+
+;// Functions:
+;// armVCM4P10_Average_4x4_Align<ALIGNMENT>_unsafe
+;//
+;// Implements Average of 4x4 with equation c = (a+b+1)>>1.
+;// First operand will be at offset ALIGNMENT from aligned address
+;// Second operand will be at aligned location and will be used as output.
+;// destination pointed by (pDst) for vertical interpolation.
+;// This function needs to copy 4 bytes in horizontal direction
+;//
+;// Registers used as input for this function
+;// r0,r1,r2,r3 where r2 containings aligned memory pointer and r3 step size
+;//
+;// Registers preserved for top level function
+;// r4,r5,r6,r8,r9,r14
+;//
+;// Registers modified by the function
+;// r7,r10,r11,r12
+;//
+;// Output registers
+;// r2 - pointer to the aligned location
+;// r3 - step size to this aligned location
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS ARM1136JS
+
+ EXPORT armVCM4P10_Average_4x4_Align0_unsafe
+ EXPORT armVCM4P10_Average_4x4_Align2_unsafe
+ EXPORT armVCM4P10_Average_4x4_Align3_unsafe
+
+DEBUG_ON SETL {FALSE}
+
+;// Declare input registers
+pPred0 RN 0
+iPredStep0 RN 1
+pPred1 RN 2
+iPredStep1 RN 3
+pDstPred RN 2
+iDstStep RN 3
+
+;// Declare other intermediate registers
+iPredA0 RN 10
+iPredA1 RN 11
+iPredB0 RN 12
+iPredB1 RN 14
+Temp1 RN 4
+Temp2 RN 5
+ResultA RN 5
+ResultB RN 4
+r0x80808080 RN 7
+
+ IF ARM1136JS
+
+ ;// This function calculates average of 4x4 block
+ ;// pPred0 is at alignment offset 0 and pPred1 is alignment 4
+
+ ;// Function header
+ M_START armVCM4P10_Average_4x4_Align0_unsafe, r6
+
+ ;// Code start
+ LDR r0x80808080, =0x80808080
+
+ ;// 1st load
+ M_LDR iPredB0, [pPred1]
+ M_LDR iPredA0, [pPred0], iPredStep0
+ M_LDR iPredB1, [pPred1, iPredStep1]
+ M_LDR iPredA1, [pPred0], iPredStep0
+
+ ;// (a+b+1)/2 = (a+256-(255-b))/2 = (a-(255-b))/2 + 128
+ MVN iPredB0, iPredB0
+ MVN iPredB1, iPredB1
+ UHSUB8 ResultA, iPredA0, iPredB0
+ UHSUB8 ResultB, iPredA1, iPredB1
+ EOR ResultA, ResultA, r0x80808080
+ M_STR ResultA, [pDstPred], iDstStep
+ EOR ResultB, ResultB, r0x80808080
+ M_STR ResultB, [pDstPred], iDstStep
+
+ ;// 2nd load
+ M_LDR iPredA0, [pPred0], iPredStep0
+ M_LDR iPredB0, [pPred1]
+ M_LDR iPredA1, [pPred0], iPredStep0
+ M_LDR iPredB1, [pPred1, iPredStep1]
+
+ MVN iPredB0, iPredB0
+ UHSUB8 ResultA, iPredA0, iPredB0
+ MVN iPredB1, iPredB1
+ UHSUB8 ResultB, iPredA1, iPredB1
+ EOR ResultA, ResultA, r0x80808080
+ M_STR ResultA, [pDstPred], iDstStep
+ EOR ResultB, ResultB, r0x80808080
+ M_STR ResultB, [pDstPred], iDstStep
+End0
+ M_END
+
+ ;// This function calculates average of 4x4 block
+ ;// pPred0 is at alignment offset 2 and pPred1 is alignment 4
+
+ ;// Function header
+ M_START armVCM4P10_Average_4x4_Align2_unsafe, r6
+
+ ;// Code start
+ LDR r0x80808080, =0x80808080
+
+ ;// 1st load
+ LDR Temp1, [pPred0, #4]
+ M_LDR iPredA0, [pPred0], iPredStep0
+ M_LDR iPredB0, [pPred1]
+ M_LDR iPredB1, [pPred1, iPredStep1]
+ M_LDR Temp2, [pPred0, #4]
+ M_LDR iPredA1, [pPred0], iPredStep0
+ MVN iPredB0, iPredB0
+ MVN iPredB1, iPredB1
+ MOV iPredA0, iPredA0, LSR #16
+ ORR iPredA0, iPredA0, Temp1, LSL #16
+ MOV iPredA1, iPredA1, LSR #16
+ ORR iPredA1, iPredA1, Temp2, LSL #16
+
+ ;// (a+b+1)/2 = (a+256-(255-b))/2 = (a-(255-b))/2 + 128
+ UHSUB8 ResultA, iPredA0, iPredB0
+ UHSUB8 ResultB, iPredA1, iPredB1
+ EOR ResultA, ResultA, r0x80808080
+ M_STR ResultA, [pDstPred], iDstStep
+ EOR ResultB, ResultB, r0x80808080
+ M_STR ResultB, [pDstPred], iDstStep
+
+ ;// 2nd load
+ LDR Temp1, [pPred0, #4]
+ M_LDR iPredA0, [pPred0], iPredStep0
+ LDR iPredB0, [pPred1]
+ LDR iPredB1, [pPred1, iPredStep1]
+ LDR Temp2, [pPred0, #4]
+ M_LDR iPredA1, [pPred0], iPredStep0
+ MVN iPredB0, iPredB0
+ MVN iPredB1, iPredB1
+ MOV iPredA0, iPredA0, LSR #16
+ ORR iPredA0, iPredA0, Temp1, LSL #16
+ MOV iPredA1, iPredA1, LSR #16
+ ORR iPredA1, iPredA1, Temp2, LSL #16
+
+ UHSUB8 ResultA, iPredA0, iPredB0
+ UHSUB8 ResultB, iPredA1, iPredB1
+ EOR ResultA, ResultA, r0x80808080
+ M_STR ResultA, [pDstPred], iDstStep
+ EOR ResultB, ResultB, r0x80808080
+ M_STR ResultB, [pDstPred], iDstStep
+End2
+ M_END
+
+
+ ;// This function calculates average of 4x4 block
+ ;// pPred0 is at alignment offset 3 and pPred1 is alignment 4
+
+ ;// Function header
+ M_START armVCM4P10_Average_4x4_Align3_unsafe, r6
+
+ ;// Code start
+ LDR r0x80808080, =0x80808080
+
+ ;// 1st load
+ LDR Temp1, [pPred0, #4]
+ M_LDR iPredA0, [pPred0], iPredStep0
+ LDR iPredB0, [pPred1]
+ LDR iPredB1, [pPred1, iPredStep1]
+ LDR Temp2, [pPred0, #4]
+ M_LDR iPredA1, [pPred0], iPredStep0
+
+ MVN iPredB0, iPredB0
+ MVN iPredB1, iPredB1
+ MOV iPredA0, iPredA0, LSR #24
+ ORR iPredA0, iPredA0, Temp1, LSL #8
+ MOV iPredA1, iPredA1, LSR #24
+ ORR iPredA1, iPredA1, Temp2, LSL #8
+ UHSUB8 ResultA, iPredA0, iPredB0
+ UHSUB8 ResultB, iPredA1, iPredB1
+ EOR ResultA, ResultA, r0x80808080
+ M_STR ResultA, [pDstPred], iDstStep
+ EOR ResultB, ResultB, r0x80808080
+ M_STR ResultB, [pDstPred], iDstStep
+
+ ;// 2nd load
+ LDR Temp1, [pPred0, #4]
+ M_LDR iPredA0, [pPred0], iPredStep0
+ LDR iPredB0, [pPred1]
+ LDR iPredB1, [pPred1, iPredStep1]
+ LDR Temp2, [pPred0, #4]
+ M_LDR iPredA1, [pPred0], iPredStep0
+
+ MVN iPredB0, iPredB0
+ MVN iPredB1, iPredB1
+ MOV iPredA0, iPredA0, LSR #24
+ ORR iPredA0, iPredA0, Temp1, LSL #8
+ MOV iPredA1, iPredA1, LSR #24
+ ORR iPredA1, iPredA1, Temp2, LSL #8
+
+ UHSUB8 ResultA, iPredA0, iPredB0
+ UHSUB8 ResultB, iPredA1, iPredB1
+ EOR ResultA, ResultA, r0x80808080
+ M_STR ResultA, [pDstPred], iDstStep
+ EOR ResultB, ResultB, r0x80808080
+ M_STR ResultB, [pDstPred], iDstStep
+End3
+ M_END
+
+ ENDIF
+
+ END
+
\ No newline at end of file
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_CAVLCTables.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_CAVLCTables.c
new file mode 100644
index 0000000..17fe518
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_CAVLCTables.c
@@ -0,0 +1,327 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: armVCM4P10_CAVLCTables.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Optimized CAVLC tables for H.264
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+
+#include "armVCM4P10_CAVLCTables.h"
+
+/* 4x4 DeZigZag table */
+
+const OMX_U8 armVCM4P10_ZigZag_4x4[16] =
+{
+ 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15
+};
+
+/* 2x2 DeZigZag table */
+
+const OMX_U8 armVCM4P10_ZigZag_2x2[4] =
+{
+ 0, 1, 2, 3
+};
+
+
+/*
+ * Suffix To Level table
+ * We increment the suffix length if
+ * ((LevelCode>>1)+1)>(3<<(SuffixLength-1)) && SuffixLength<6
+ * (LevelCode>>1)>=(3<<(SuffixLength-1)) && SuffixLength<6
+ * LevelCode >= 3<<SuffixLength && SuffixLength<6
+ * (LevelCode+2) >= (3<<SuffixLength)+2 && SuffixLength<6
+ */
+const OMX_S8 armVCM4P10_SuffixToLevel[7] =
+{
+ (3<<1)+2, /* SuffixLength=1 */
+ (3<<1)+2, /* SuffixLength=1 */
+ (3<<2)+2, /* SuffixLength=2 */
+ (3<<3)+2, /* SuffixLength=3 */
+ (3<<4)+2, /* SuffixLength=4 */
+ (3<<5)+2, /* SuffixLength=5 */
+ -1 /* SuffixLength=6 - never increment */
+};
+
+static const OMX_U16 armVCM4P10_CAVLCCoeffTokenTables_0[132] = {
+ 0x0020, 0x0100, 0x2015, 0x2015, 0x400b, 0x400b, 0x400b, 0x400b,
+ 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001,
+ 0x0028, 0x00f0, 0x00f8, 0x0027, 0x0030, 0x00d8, 0x00e0, 0x00e8,
+ 0x0038, 0x00a0, 0x00c8, 0x00d0, 0x0040, 0x0068, 0x0090, 0x0098,
+ 0x0048, 0x0050, 0x0058, 0x0060, 0x27ff, 0x27ff, 0x206b, 0x206b,
+ 0x0081, 0x0085, 0x0083, 0x0079, 0x0087, 0x007d, 0x007b, 0x0071,
+ 0x007f, 0x0075, 0x0073, 0x0069, 0x0070, 0x0078, 0x0080, 0x0088,
+ 0x2077, 0x2077, 0x206d, 0x206d, 0x2063, 0x2063, 0x2061, 0x2061,
+ 0x206f, 0x206f, 0x2065, 0x2065, 0x205b, 0x205b, 0x2059, 0x2059,
+ 0x0067, 0x005d, 0x0053, 0x0051, 0x005f, 0x0055, 0x004b, 0x0049,
+ 0x00a8, 0x00b0, 0x00b8, 0x00c0, 0x2041, 0x2041, 0x204d, 0x204d,
+ 0x2043, 0x2043, 0x2039, 0x2039, 0x2057, 0x2057, 0x2045, 0x2045,
+ 0x203b, 0x203b, 0x2031, 0x2031, 0x204f, 0x204f, 0x203d, 0x203d,
+ 0x2033, 0x2033, 0x2029, 0x2029, 0x0047, 0x0035, 0x002b, 0x0021,
+ 0x203f, 0x203f, 0x202d, 0x202d, 0x2023, 0x2023, 0x2019, 0x2019,
+ 0x0037, 0x0025, 0x001b, 0x0011, 0x202f, 0x202f, 0x201d, 0x201d,
+ 0x0013, 0x0009, 0x201f, 0x201f
+};
+
+static const OMX_U16 armVCM4P10_CAVLCCoeffTokenTables_1[128] = {
+ 0x0020, 0x00e8, 0x00f0, 0x00f8, 0x0027, 0x001f, 0x2015, 0x2015,
+ 0x400b, 0x400b, 0x400b, 0x400b, 0x4001, 0x4001, 0x4001, 0x4001,
+ 0x0028, 0x00d0, 0x00d8, 0x00e0, 0x0030, 0x0098, 0x00c0, 0x00c8,
+ 0x0038, 0x0060, 0x0088, 0x0090, 0x0040, 0x0048, 0x0050, 0x0058,
+ 0x27ff, 0x27ff, 0x207f, 0x207f, 0x0087, 0x0085, 0x0083, 0x0081,
+ 0x007b, 0x0079, 0x007d, 0x0073, 0x2075, 0x2075, 0x2071, 0x2071,
+ 0x0068, 0x0070, 0x0078, 0x0080, 0x2077, 0x2077, 0x206d, 0x206d,
+ 0x206b, 0x206b, 0x2069, 0x2069, 0x206f, 0x206f, 0x2065, 0x2065,
+ 0x2063, 0x2063, 0x2061, 0x2061, 0x0059, 0x005d, 0x005b, 0x0051,
+ 0x0067, 0x0055, 0x0053, 0x0049, 0x00a0, 0x00a8, 0x00b0, 0x00b8,
+ 0x205f, 0x205f, 0x204d, 0x204d, 0x204b, 0x204b, 0x2041, 0x2041,
+ 0x2057, 0x2057, 0x2045, 0x2045, 0x2043, 0x2043, 0x2039, 0x2039,
+ 0x204f, 0x204f, 0x203d, 0x203d, 0x203b, 0x203b, 0x2031, 0x2031,
+ 0x0029, 0x0035, 0x0033, 0x0021, 0x2047, 0x2047, 0x202d, 0x202d,
+ 0x202b, 0x202b, 0x2019, 0x2019, 0x003f, 0x0025, 0x0023, 0x0011,
+ 0x0037, 0x001d, 0x001b, 0x0009, 0x202f, 0x202f, 0x2013, 0x2013
+};
+
+static const OMX_U16 armVCM4P10_CAVLCCoeffTokenTables_2[112] = {
+ 0x0020, 0x0088, 0x00b0, 0x00b8, 0x00c0, 0x00c8, 0x00d0, 0x00d8,
+ 0x003f, 0x0037, 0x002f, 0x0027, 0x001f, 0x0015, 0x000b, 0x0001,
+ 0x0028, 0x0050, 0x0078, 0x0080, 0x0030, 0x0038, 0x0040, 0x0048,
+ 0x07ff, 0x0081, 0x0087, 0x0085, 0x0083, 0x0079, 0x007f, 0x007d,
+ 0x007b, 0x0071, 0x0077, 0x0075, 0x0073, 0x0069, 0x206b, 0x206b,
+ 0x0058, 0x0060, 0x0068, 0x0070, 0x2061, 0x2061, 0x206d, 0x206d,
+ 0x2063, 0x2063, 0x2059, 0x2059, 0x206f, 0x206f, 0x2065, 0x2065,
+ 0x205b, 0x205b, 0x2051, 0x2051, 0x0067, 0x005d, 0x0053, 0x0049,
+ 0x005f, 0x0055, 0x004b, 0x0041, 0x0090, 0x0098, 0x00a0, 0x00a8,
+ 0x2039, 0x2039, 0x2031, 0x2031, 0x204d, 0x204d, 0x2029, 0x2029,
+ 0x2057, 0x2057, 0x2045, 0x2045, 0x2043, 0x2043, 0x2021, 0x2021,
+ 0x0019, 0x003d, 0x003b, 0x0011, 0x004f, 0x0035, 0x0033, 0x0009,
+ 0x202b, 0x202b, 0x202d, 0x202d, 0x2023, 0x2023, 0x2025, 0x2025,
+ 0x201b, 0x201b, 0x2047, 0x2047, 0x201d, 0x201d, 0x2013, 0x2013
+};
+
+static const OMX_U16 armVCM4P10_CAVLCCoeffTokenTables_3[80] = {
+ 0x0020, 0x0028, 0x0030, 0x0038, 0x0040, 0x0048, 0x0050, 0x0058,
+ 0x0060, 0x0068, 0x0070, 0x0078, 0x0080, 0x0088, 0x0090, 0x0098,
+ 0x0009, 0x000b, 0x07ff, 0x0001, 0x0011, 0x0013, 0x0015, 0x07ff,
+ 0x0019, 0x001b, 0x001d, 0x001f, 0x0021, 0x0023, 0x0025, 0x0027,
+ 0x0029, 0x002b, 0x002d, 0x002f, 0x0031, 0x0033, 0x0035, 0x0037,
+ 0x0039, 0x003b, 0x003d, 0x003f, 0x0041, 0x0043, 0x0045, 0x0047,
+ 0x0049, 0x004b, 0x004d, 0x004f, 0x0051, 0x0053, 0x0055, 0x0057,
+ 0x0059, 0x005b, 0x005d, 0x005f, 0x0061, 0x0063, 0x0065, 0x0067,
+ 0x0069, 0x006b, 0x006d, 0x006f, 0x0071, 0x0073, 0x0075, 0x0077,
+ 0x0079, 0x007b, 0x007d, 0x007f, 0x0081, 0x0083, 0x0085, 0x0087
+};
+
+static const OMX_U16 armVCM4P10_CAVLCCoeffTokenTables_4[32] = {
+ 0x0020, 0x0038, 0x2015, 0x2015, 0x4001, 0x4001, 0x4001, 0x4001,
+ 0x600b, 0x600b, 0x600b, 0x600b, 0x600b, 0x600b, 0x600b, 0x600b,
+ 0x0028, 0x0030, 0x0021, 0x0019, 0x2027, 0x2027, 0x0025, 0x0023,
+ 0x201d, 0x201d, 0x201b, 0x201b, 0x0011, 0x001f, 0x0013, 0x0009
+};
+
+const OMX_U16 * armVCM4P10_CAVLCCoeffTokenTables[18] = {
+ armVCM4P10_CAVLCCoeffTokenTables_0, /* nC=0 */
+ armVCM4P10_CAVLCCoeffTokenTables_0, /* nC=1 */
+ armVCM4P10_CAVLCCoeffTokenTables_1, /* nC=2 */
+ armVCM4P10_CAVLCCoeffTokenTables_1, /* nC=3 */
+ armVCM4P10_CAVLCCoeffTokenTables_2, /* nC=4 */
+ armVCM4P10_CAVLCCoeffTokenTables_2, /* nC=5 */
+ armVCM4P10_CAVLCCoeffTokenTables_2, /* nC=6 */
+ armVCM4P10_CAVLCCoeffTokenTables_2, /* nC=7 */
+ armVCM4P10_CAVLCCoeffTokenTables_3, /* nC=8 */
+ armVCM4P10_CAVLCCoeffTokenTables_3, /* nC=9 */
+ armVCM4P10_CAVLCCoeffTokenTables_3, /* nC=10 */
+ armVCM4P10_CAVLCCoeffTokenTables_3, /* nC=11 */
+ armVCM4P10_CAVLCCoeffTokenTables_3, /* nC=12 */
+ armVCM4P10_CAVLCCoeffTokenTables_3, /* nC=13 */
+ armVCM4P10_CAVLCCoeffTokenTables_3, /* nC=14 */
+ armVCM4P10_CAVLCCoeffTokenTables_3, /* nC=15 */
+ armVCM4P10_CAVLCCoeffTokenTables_3, /* nC=16 */
+ armVCM4P10_CAVLCCoeffTokenTables_4 /* nC=-1 */
+};
+
+static const OMX_U16 armVCM4P10_CAVLCTotalZeroTables_0[40] = {
+ 0x0020, 0x0048, 0x0009, 0x0007, 0x2005, 0x2005, 0x2003, 0x2003,
+ 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001,
+ 0x0028, 0x0040, 0x0011, 0x000f, 0x0030, 0x0038, 0x0019, 0x0017,
+ 0x27ff, 0x27ff, 0x201f, 0x201f, 0x201d, 0x201d, 0x201b, 0x201b,
+ 0x2015, 0x2015, 0x2013, 0x2013, 0x200d, 0x200d, 0x200b, 0x200b
+};
+
+static const OMX_U16 armVCM4P10_CAVLCTotalZeroTables_1[24] = {
+ 0x0020, 0x0028, 0x0011, 0x000f, 0x000d, 0x000b, 0x2009, 0x2009,
+ 0x2007, 0x2007, 0x2005, 0x2005, 0x2003, 0x2003, 0x2001, 0x2001,
+ 0x001d, 0x001b, 0x0019, 0x0017, 0x2015, 0x2015, 0x2013, 0x2013
+};
+
+static const OMX_U16 armVCM4P10_CAVLCTotalZeroTables_2[24] = {
+ 0x0020, 0x0028, 0x0011, 0x000b, 0x0009, 0x0001, 0x200f, 0x200f,
+ 0x200d, 0x200d, 0x2007, 0x2007, 0x2005, 0x2005, 0x2003, 0x2003,
+ 0x001b, 0x0017, 0x2019, 0x2019, 0x2015, 0x2015, 0x2013, 0x2013
+};
+
+static const OMX_U16 armVCM4P10_CAVLCTotalZeroTables_3[24] = {
+ 0x0020, 0x0028, 0x0013, 0x000f, 0x0007, 0x0005, 0x2011, 0x2011,
+ 0x200d, 0x200d, 0x200b, 0x200b, 0x2009, 0x2009, 0x2003, 0x2003,
+ 0x2019, 0x2019, 0x2017, 0x2017, 0x2015, 0x2015, 0x2001, 0x2001
+};
+
+static const OMX_U16 armVCM4P10_CAVLCTotalZeroTables_4[20] = {
+ 0x0020, 0x0015, 0x0011, 0x0005, 0x0003, 0x0001, 0x200f, 0x200f,
+ 0x200d, 0x200d, 0x200b, 0x200b, 0x2009, 0x2009, 0x2007, 0x2007,
+ 0x2017, 0x2017, 0x2013, 0x2013
+};
+
+static const OMX_U16 armVCM4P10_CAVLCTotalZeroTables_5[20] = {
+ 0x0020, 0x0011, 0x2013, 0x2013, 0x200f, 0x200f, 0x200d, 0x200d,
+ 0x200b, 0x200b, 0x2009, 0x2009, 0x2007, 0x2007, 0x2005, 0x2005,
+ 0x0015, 0x0001, 0x2003, 0x2003
+};
+
+static const OMX_U16 armVCM4P10_CAVLCTotalZeroTables_6[20] = {
+ 0x0020, 0x000f, 0x2011, 0x2011, 0x200d, 0x200d, 0x2009, 0x2009,
+ 0x2007, 0x2007, 0x2005, 0x2005, 0x400b, 0x400b, 0x400b, 0x400b,
+ 0x0013, 0x0001, 0x2003, 0x2003
+};
+
+static const OMX_U16 armVCM4P10_CAVLCTotalZeroTables_7[20] = {
+ 0x0020, 0x0003, 0x200f, 0x200f, 0x200d, 0x200d, 0x2007, 0x2007,
+ 0x400b, 0x400b, 0x400b, 0x400b, 0x4009, 0x4009, 0x4009, 0x4009,
+ 0x0011, 0x0001, 0x2005, 0x2005
+};
+
+static const OMX_U16 armVCM4P10_CAVLCTotalZeroTables_8[20] = {
+ 0x0020, 0x0005, 0x200b, 0x200b, 0x400d, 0x400d, 0x400d, 0x400d,
+ 0x4009, 0x4009, 0x4009, 0x4009, 0x4007, 0x4007, 0x4007, 0x4007,
+ 0x0003, 0x0001, 0x200f, 0x200f
+};
+
+static const OMX_U16 armVCM4P10_CAVLCTotalZeroTables_9[20] = {
+ 0x0020, 0x000d, 0x2005, 0x2005, 0x400b, 0x400b, 0x400b, 0x400b,
+ 0x4009, 0x4009, 0x4009, 0x4009, 0x4007, 0x4007, 0x4007, 0x4007,
+ 0x2003, 0x2003, 0x2001, 0x2001
+};
+
+static const OMX_U16 armVCM4P10_CAVLCTotalZeroTables_10[16] = {
+ 0x0001, 0x0003, 0x2005, 0x2005, 0x2007, 0x2007, 0x200b, 0x200b,
+ 0x6009, 0x6009, 0x6009, 0x6009, 0x6009, 0x6009, 0x6009, 0x6009
+};
+
+static const OMX_U16 armVCM4P10_CAVLCTotalZeroTables_11[16] = {
+ 0x0001, 0x0003, 0x2009, 0x2009, 0x4005, 0x4005, 0x4005, 0x4005,
+ 0x6007, 0x6007, 0x6007, 0x6007, 0x6007, 0x6007, 0x6007, 0x6007
+};
+
+static const OMX_U16 armVCM4P10_CAVLCTotalZeroTables_12[16] = {
+ 0x2001, 0x2001, 0x2003, 0x2003, 0x4007, 0x4007, 0x4007, 0x4007,
+ 0x6005, 0x6005, 0x6005, 0x6005, 0x6005, 0x6005, 0x6005, 0x6005
+};
+
+static const OMX_U16 armVCM4P10_CAVLCTotalZeroTables_13[16] = {
+ 0x4001, 0x4001, 0x4001, 0x4001, 0x4003, 0x4003, 0x4003, 0x4003,
+ 0x6005, 0x6005, 0x6005, 0x6005, 0x6005, 0x6005, 0x6005, 0x6005
+};
+
+static const OMX_U16 armVCM4P10_CAVLCTotalZeroTables_14[16] = {
+ 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001,
+ 0x6003, 0x6003, 0x6003, 0x6003, 0x6003, 0x6003, 0x6003, 0x6003
+};
+
+const OMX_U16 * armVCM4P10_CAVLCTotalZeroTables[15] = {
+ armVCM4P10_CAVLCTotalZeroTables_0,
+ armVCM4P10_CAVLCTotalZeroTables_1,
+ armVCM4P10_CAVLCTotalZeroTables_2,
+ armVCM4P10_CAVLCTotalZeroTables_3,
+ armVCM4P10_CAVLCTotalZeroTables_4,
+ armVCM4P10_CAVLCTotalZeroTables_5,
+ armVCM4P10_CAVLCTotalZeroTables_6,
+ armVCM4P10_CAVLCTotalZeroTables_7,
+ armVCM4P10_CAVLCTotalZeroTables_8,
+ armVCM4P10_CAVLCTotalZeroTables_9,
+ armVCM4P10_CAVLCTotalZeroTables_10,
+ armVCM4P10_CAVLCTotalZeroTables_11,
+ armVCM4P10_CAVLCTotalZeroTables_12,
+ armVCM4P10_CAVLCTotalZeroTables_13,
+ armVCM4P10_CAVLCTotalZeroTables_14
+};
+
+static const OMX_U16 armVCM4P10_CAVLCTotalZeros2x2Tables_0[16] = {
+ 0x2007, 0x2007, 0x2005, 0x2005, 0x4003, 0x4003, 0x4003, 0x4003,
+ 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001
+};
+
+static const OMX_U16 armVCM4P10_CAVLCTotalZeros2x2Tables_1[16] = {
+ 0x4005, 0x4005, 0x4005, 0x4005, 0x4003, 0x4003, 0x4003, 0x4003,
+ 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001
+};
+
+static const OMX_U16 armVCM4P10_CAVLCTotalZeros2x2Tables_2[16] = {
+ 0x6003, 0x6003, 0x6003, 0x6003, 0x6003, 0x6003, 0x6003, 0x6003,
+ 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001
+};
+
+const OMX_U16 * armVCM4P10_CAVLCTotalZeros2x2Tables[3] = {
+ armVCM4P10_CAVLCTotalZeros2x2Tables_0,
+ armVCM4P10_CAVLCTotalZeros2x2Tables_1,
+ armVCM4P10_CAVLCTotalZeros2x2Tables_2
+};
+
+static const OMX_U16 armVCM4P10_CAVLCRunBeforeTables_0[8] = {
+ 0x4003, 0x4003, 0x4003, 0x4003, 0x4001, 0x4001, 0x4001, 0x4001
+};
+
+static const OMX_U16 armVCM4P10_CAVLCRunBeforeTables_1[8] = {
+ 0x2005, 0x2005, 0x2003, 0x2003, 0x4001, 0x4001, 0x4001, 0x4001
+};
+
+static const OMX_U16 armVCM4P10_CAVLCRunBeforeTables_2[8] = {
+ 0x2007, 0x2007, 0x2005, 0x2005, 0x2003, 0x2003, 0x2001, 0x2001
+};
+
+static const OMX_U16 armVCM4P10_CAVLCRunBeforeTables_3[8] = {
+ 0x0009, 0x0007, 0x2005, 0x2005, 0x2003, 0x2003, 0x2001, 0x2001
+};
+
+static const OMX_U16 armVCM4P10_CAVLCRunBeforeTables_4[8] = {
+ 0x000b, 0x0009, 0x0007, 0x0005, 0x2003, 0x2003, 0x2001, 0x2001
+};
+
+static const OMX_U16 armVCM4P10_CAVLCRunBeforeTables_5[8] = {
+ 0x0003, 0x0005, 0x0009, 0x0007, 0x000d, 0x000b, 0x2001, 0x2001
+};
+
+static const OMX_U16 armVCM4P10_CAVLCRunBeforeTables_6[24] = {
+ 0x0010, 0x000d, 0x000b, 0x0009, 0x0007, 0x0005, 0x0003, 0x0001,
+ 0x0018, 0x0011, 0x200f, 0x200f, 0x0020, 0x0015, 0x2013, 0x2013,
+ 0x0028, 0x0019, 0x2017, 0x2017, 0x07ff, 0x001d, 0x201b, 0x201b
+};
+
+/* Tables 7 to 14 are duplicates of table 6 */
+
+const OMX_U16 * armVCM4P10_CAVLCRunBeforeTables[15] = {
+ armVCM4P10_CAVLCRunBeforeTables_0, /* ZerosLeft=1 */
+ armVCM4P10_CAVLCRunBeforeTables_1,
+ armVCM4P10_CAVLCRunBeforeTables_2,
+ armVCM4P10_CAVLCRunBeforeTables_3,
+ armVCM4P10_CAVLCRunBeforeTables_4,
+ armVCM4P10_CAVLCRunBeforeTables_5, /* ZerosLeft=6 */
+ armVCM4P10_CAVLCRunBeforeTables_6, /* ZerosLeft=7 */
+ armVCM4P10_CAVLCRunBeforeTables_6, /* ZerosLeft=8 */
+ armVCM4P10_CAVLCRunBeforeTables_6, /* ZerosLeft=9 */
+ armVCM4P10_CAVLCRunBeforeTables_6, /* ZerosLeft=10 */
+ armVCM4P10_CAVLCRunBeforeTables_6, /* ZerosLeft=11 */
+ armVCM4P10_CAVLCRunBeforeTables_6, /* ZerosLeft=12 */
+ armVCM4P10_CAVLCRunBeforeTables_6, /* ZerosLeft=13 */
+ armVCM4P10_CAVLCRunBeforeTables_6, /* ZerosLeft=14 */
+ armVCM4P10_CAVLCRunBeforeTables_6 /* ZerosLeft=15 */
+};
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_DeblockingChroma_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_DeblockingChroma_unsafe_s.s
new file mode 100644
index 0000000..dcbcd00
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_DeblockingChroma_unsafe_s.s
@@ -0,0 +1,20 @@
+;//
+;//
+;// File Name: armVCM4P10_DeblockingChroma_unsafe_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 9641
+;// Date: Thursday, February 7, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS ARM1136JS
+
+
+
+ END
\ No newline at end of file
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_DeblockingLuma_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_DeblockingLuma_unsafe_s.s
new file mode 100644
index 0000000..14b37fe
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_DeblockingLuma_unsafe_s.s
@@ -0,0 +1,366 @@
+;//
+;//
+;// File Name: armVCM4P10_DeblockingLuma_unsafe_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 9641
+;// Date: Thursday, February 7, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS ARM1136JS
+
+
+
+ IF ARM1136JS
+
+MASK_1 EQU 0x01010101
+
+;// Declare input registers
+
+pQ0 RN 0
+StepArg RN 1
+tC0Arg RN 2
+alpha RN 6
+
+beta RN 14
+bS RN 14
+tC0 RN 14
+ptC0 RN 1
+
+;// Declare Local/Temporary variables
+
+;// Pixels
+p_0 RN 3
+p_1 RN 5
+p_2 RN 4
+p_3 RN 2
+q_0 RN 8
+q_1 RN 9
+q_2 RN 10
+q_3 RN 12
+
+
+;// Filtering
+
+ap0q0 RN 1
+filt RN 2
+
+m00 RN 7
+m01 RN 11
+
+apflg RN 0
+aqflg RN 6
+
+tC RN 1
+
+
+;//Declarations for bSLT4 kernel
+
+pos RN 7
+neg RN 12
+
+P0a RN 1
+P1a RN 8
+Q0a RN 7
+Q1a RN 4
+
+u1 RN 3
+max RN 12
+min RN 2
+
+
+
+;//Declarations for bSGE4 kernel
+
+q_3b RN 9
+p_3b RN 0
+apqflg RN 12
+
+P0b RN 6
+P1b RN 7
+P2b RN 1
+
+Q0b RN 9
+Q1b RN 0
+Q2b RN 2
+
+;// Miscellanous
+
+a RN 0
+t0 RN 3
+t1 RN 12
+t2 RN 7
+t3 RN 11
+t4 RN 4
+t5 RN 1
+t8 RN 6
+t9 RN 14
+t10 RN 5
+t11 RN 9
+
+;// Register usage for - armVCM4P10_DeblockingLumabSLT4_unsafe()
+;//
+;// Inputs - 3,4,5,8,9,10 - Input Pixels (p0-p2,q0-q2)
+;// - 2 - filt, 0 - apflg, 6 - aqflg
+;// - 11 - m01, 7 - tC0
+;//
+;// Outputs - 1,8,7,11 - Output Pixels(P0a,P1a,Q0a,Q1a)
+;//
+;// Registers Corrupted - 0-3,5-12,14
+
+
+ M_START armVCM4P10_DeblockingLumabSLT4_unsafe, lr
+
+ ;// Since beta <= 18 and alpha <= 255 we know
+ ;// -254 <= p0-q0 <= 254
+ ;// -17 <= q1-q0 <= 17
+ ;// -17 <= p1-p0 <= 17
+
+ ;// delta = Clip3( -tC, tC, ((((q0-p0)<<2) + (p1-q1) + 4)>>3))
+ ;//
+ ;// Calculate A = (((q0-p0)<<2) + (p1-q1) + 4)>>3
+ ;// = (4*q0 - 4*p0 + p1 - q1 + 4)>>3
+ ;// = ((p1-p0) - (q1-q0) - 3*(p0-q0) + 4)>>3
+
+ USUB8 t1, p_1, p_0
+ MUL tC0, t2, m01
+
+ USUB8 t2, q_1, q_0
+ SSUB8 t1, t1, t2
+
+ USUB8 t2, p_0, q_0
+ AND t2, t2, m01
+ SHSUB8 t1, t1, t2
+ UHSUB8 t5, p_0, q_0
+ SSUB8 t1, t1, t2
+ SHSUB8 t1, t1, t5
+ MOV m00, #0
+ SADD8 t1, t1, m01
+ SHSUB8 t1, t1, t5
+
+ ;// tC = tC0
+ ;// if (ap < beta) tC++;
+ ;// if (aq < beta) tC++;
+ USUB8 t5, filt, m01
+ SEL tC0, tC0, m00
+ UQADD8 tC, tC0, apflg
+ SSUB8 t1, t1, m00
+ UQADD8 tC, tC, aqflg
+
+ ;// Split into positive and negative part and clip
+ SEL pos, t1, m00
+ USUB8 neg, pos, t1
+ USUB8 t3, pos, tC
+ SEL pos, tC, pos
+ USUB8 t3, neg, tC
+ SEL neg, tC, neg
+
+ ;//Reload m01
+ LDR m01,=MASK_1
+
+ UQADD8 P0a, p_0, pos
+ UQSUB8 Q0a, q_0, pos
+ UQSUB8 P0a, P0a, neg
+ UQADD8 Q0a, Q0a, neg
+
+ ;// Choose to store the filtered
+ ;// value or the original pixel
+ USUB8 t1, filt, m01
+ SEL P0a, P0a, p_0
+ SEL Q0a, Q0a, q_0
+
+ ;// delta = (p2 + ((p0+q0+1)>>1) - (p1<<1))>>1;
+ ;// u1 = (p0 + q0 + 1)>>1
+ ;// u1 = ( (q_0 - p_0')>>1 ) ^ 0x80
+ MVN p_0, p_0
+ UHSUB8 u1, q_0, p_0
+ UQADD8 max, p_1, tC0
+ EOR u1, u1, m01 ,LSL #7
+
+ ;// Calculate A = (p2+u1)>>1
+ ;// Then delta = Clip3( -tC0, tC0, A - p1)
+
+ ;// Clip P1
+ UHADD8 P1a, p_2, u1
+ UQSUB8 min, p_1, tC0
+ USUB8 t4, P1a, max
+ SEL P1a, max, P1a
+ USUB8 t4, P1a, min
+ SEL P1a, P1a, min
+
+ ;// Clip Q1
+ UHADD8 Q1a, q_2, u1
+ UQADD8 max, q_1, tC0
+ UQSUB8 min, q_1, tC0
+ USUB8 t0, Q1a, max
+ SEL Q1a, max, Q1a
+ USUB8 t0, Q1a, min
+ SEL Q1a, Q1a, min
+
+ ;// Choose to store the filtered
+ ;// value or the original pixel
+ USUB8 t0, apflg, m01
+ SEL P1a, P1a, p_1
+ USUB8 t0, aqflg, m01
+ SEL t3, Q1a, q_1
+
+ M_END
+
+;// Register usage for - armVCM4P10_DeblockingLumabSGE4_unsafe()
+;//
+;// Inputs - 3,4,5,8,9,10 - Input Pixels (p0-p2,q0-q2)
+;// - 2 - filt, 0 - apflg,aqflg
+;// - 1 - ap0q0, 6 - alpha
+;// - 7 - m00, 11 - m01
+;//
+;// Outputs - 6,7,1,9,0,2 - Output Pixels(P0b,P1b,P2b, Q0b,Q1b,Q2b)
+;//
+;// Registers Corrupted - 0-3,5-12,14
+
+ M_START armVCM4P10_DeblockingLumabSGE4_unsafe, lr
+
+ ;// apflg = apflg && |p0-q0|<((alpha>>2)+2)
+ ;// apflg = aqflg && |p0-q0|<((alpha>>2)+2)
+
+ M_ARG pDummy,4
+ M_ARG pQ_3,4
+ M_ARG pP_3,4
+
+ UHADD8 alpha, alpha, m00
+ USUB8 t9, p_2, p_0 ;//t9 = dp2p0
+ UHADD8 alpha, alpha, m00
+ ADD alpha, alpha, m01, LSL #1
+ USUB8 ap0q0, ap0q0, alpha
+ SEL apqflg, m00, apflg
+
+ ;// P0 = (p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4)>>3
+ ;// = ((p2-p0) + 2*(p1-p0) + (q1-q0) + 3*(q0-p0) + 8*p0 + 4)>>3
+ ;// = p0 + (((p2-p0) + 2*(p1-p0) + (q1-q0) - 3*(p0-q0) + 4)>>3)
+
+ ;// P1 = (p2 + p1 + q0 + p0 + 2)>>2
+ ;// = p0 + (((p2-p0) + (p1-p0) - (p0-q0) + 2)>>2)
+
+ ;// P2 = (2*p3 + 3*p2 + p1 + p0 + q0 + 4)>>3
+ ;// = (2*(p3-p0) + 3*(p2-p0) + (p1-p0) - (p0-q0) + 8*p0 + 4)>>3
+ ;// = p0 + (((p3-p0) + (p2-p0) + t2 + 2)>>2)
+
+ ;// Compute P0b
+ USUB8 t2, p_0, q_0
+ SSUB8 t5, t9, t2
+
+ USUB8 t8, q_1, q_0
+ SHADD8 t8, t5, t8
+
+ USUB8 t9, p_1, p_0
+ SADD8 t8, t8, t9
+ SHSUB8 t8, t8, t2
+ SHADD8 t5, t5, t9
+ SHADD8 t8, t8, m01
+ SHADD8 t9, t5, m01
+ SADD8 P0b, p_0, t8
+ ;// P0b ready
+
+ ;// Compute P1b
+ M_LDR p_3b, pP_3
+ SADD8 P1b, p_0, t9
+ ;// P1b ready
+
+ ;// Compute P2b
+ USUB8 t9, p_2, p_0
+ SADD8 t5, t5, t9
+ UHSUB8 t9, p_3b, p_0
+ EOR a, p_3b, p_0
+ AND a, a, m01
+ SHADD8 t5, t5, a
+ UHADD8 a, p_0, q_1
+ SADD8 t5, t5, m01
+ SHADD8 t5, t5, t9
+ MVN t9, p_1
+ SADD8 P2b, p_0, t5
+ ;// P2b ready
+
+ UHSUB8 a, a, t9
+ ORR t9, apqflg, m01
+ USUB8 t9, apqflg, t9
+
+ EOR a, a, m01, LSL #7
+ SEL P0b, P0b, a
+ SEL P1b, P1b, p_1
+ SEL P2b, P2b, p_2
+
+ USUB8 t4, filt, m01
+ SEL P0b, P0b, p_0
+
+
+ ;// Q0 = (q2 + 2*q1 + 2*q0 + 2*p0 + p1 + 4)>>3
+ ;// = ((q2-q0) + 2*(q1-q0) + (p1-p0) + 3*(p0-q0) + 8*q0 + 4)>>3
+ ;// = q0 + (((q2-q0) + 2*(q1-q0) + (p1-p0) + 3*(p0-q0) + 4)>>3)
+
+ ;// Q1 = (q2 + q1 + p0 + q0 + 2)>>2
+ ;// = q0 + (((q2-q0) + (q1-q0) + (p0-q0) + 2)>>2)
+
+ ;// Q2 = (2*q3 + 3*q2 + q1 + q0 + p0 + 4)>>3
+ ;// = (2*(q3-q0) + 3*(q2-q0) + (q1-q0) + (p0-q0) + 8*q0 + 4)>>3
+ ;// = q0 + (((q3-q0) + (q2-q0) + t2 + 2)>>2)
+
+
+ ;// Compute Q0b Q1b
+ USUB8 t4, q_2, q_0
+ USUB8 a, p_0, q_0
+ USUB8 t9, p_1, p_0
+ SADD8 t0, t4, a
+ SHADD8 t9, t0, t9
+ UHADD8 t10, q_0, p_1
+ SADD8 t9, t9, a
+ USUB8 a, q_1, q_0
+ SHADD8 t9, t9, a
+ SHADD8 t0, t0, a
+ SHADD8 t9, t9, m01
+ SHADD8 a, t0, m01
+ SADD8 t9, q_0, t9
+ ;// Q0b ready - t9
+
+ MOV t4, #0
+ UHADD8 apqflg, apqflg, t4
+
+ SADD8 Q1b, q_0, a
+ ;// Q1b ready
+
+ USUB8 t4, apqflg, m01
+ SEL Q1b, Q1b, q_1
+ MVN t11, q_1
+ UHSUB8 t10, t10, t11
+ M_LDR q_3b, pQ_3
+ EOR t10, t10, m01, LSL #7
+ SEL t9, t9, t10
+
+ ;// Compute Q2b
+ USUB8 t4, q_2, q_0
+ SADD8 t4, t0, t4
+ EOR t0, q_3b, q_0
+ AND t0, t0, m01
+ SHADD8 t4, t4, t0
+ UHSUB8 t10, q_3b, q_0
+ SADD8 t4, t4, m01
+ SHADD8 t4, t4, t10
+
+ USUB8 t10, filt, m01
+ SEL Q0b, t9, q_0
+
+ SADD8 t4, q_0, t4
+ ;// Q2b ready - t4
+
+ USUB8 t10, apqflg, m01
+ SEL Q2b, t4, q_2
+
+ M_END
+
+ ENDIF
+
+ END
\ No newline at end of file
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_DecodeCoeffsToPair_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_DecodeCoeffsToPair_s.s
new file mode 100644
index 0000000..ac448a0
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_DecodeCoeffsToPair_s.s
@@ -0,0 +1,325 @@
+;//
+;//
+;// File Name: armVCM4P10_DecodeCoeffsToPair_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 9641
+;// Date: Thursday, February 7, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+ INCLUDE armCOMM_BitDec_s.h
+
+ IMPORT armVCM4P10_CAVLCCoeffTokenTables
+ IMPORT armVCM4P10_CAVLCTotalZeroTables
+ IMPORT armVCM4P10_CAVLCTotalZeros2x2Tables
+ IMPORT armVCM4P10_CAVLCRunBeforeTables
+ IMPORT armVCM4P10_SuffixToLevel
+ IMPORT armVCM4P10_ZigZag_4x4
+ IMPORT armVCM4P10_ZigZag_2x2
+
+ M_VARIANTS ARM1136JS
+
+;//DEBUG_ON SETL {TRUE}
+
+LAST_COEFF EQU 0x20 ;// End of block flag
+TWO_BYTE_COEFF EQU 0x10
+
+;// Declare input registers
+
+ppBitStream RN 0
+pOffset RN 1
+pNumCoeff RN 2
+ppPosCoefbuf RN 3
+nC RN 4 ;// number of coeffs or 17 for chroma
+sMaxNumCoeff RN 5
+
+;// Declare inner loop registers
+
+;// Level loop
+Count RN 0
+TrailingOnes RN 1
+pLevel RN 2
+LevelSuffix RN 3
+SuffixLength RN 4
+TotalCoeff RN 5
+
+pVLDTable RN 6
+Symbol RN 7
+T1 RN 8
+T2 RN 9
+RBitStream RN 10
+RBitBuffer RN 11
+RBitCount RN 12
+lr RN 14
+
+;// Run loop
+Count RN 0
+ZerosLeft RN 1
+pLevel RN 2
+ppRunTable RN 3
+pRun RN 4
+TotalCoeff RN 5
+
+pVLDTable RN 6
+Symbol RN 7
+T1 RN 8
+T2 RN 9
+RBitStream RN 10
+RBitBuffer RN 11
+RBitCount RN 12
+lr RN 14
+
+;// Fill in coefficients loop
+pPosCoefbuf RN 0
+temp RN 1
+pLevel RN 2
+ppPosCoefbuf RN 3
+pRun RN 4
+TotalCoeff RN 5
+pZigZag RN 6
+
+T1 RN 8
+T2 RN 9
+RBitStream RN 10
+RBitBuffer RN 11
+RBitCount RN 12
+CoeffNum RN 14
+
+
+
+ IF ARM1136JS
+
+ ;// Allocate stack memory required by the function
+ M_ALLOC4 pppBitStream, 4
+ M_ALLOC4 ppOffset, 4
+ M_ALLOC4 pppPosCoefbuf, 4
+ M_ALLOC4 ppLevel, 16*2
+ M_ALLOC4 ppRun, 16
+
+ ;// Write function header
+ M_START armVCM4P10_DecodeCoeffsToPair, r11
+
+ ;// Define stack arguments
+ M_ARG pNC, 4
+ M_ARG pSMaxNumCoeff,4
+
+ ;// Code start
+ M_BD_INIT0 ppBitStream, pOffset, RBitStream, RBitBuffer, RBitCount
+ LDR pVLDTable, =armVCM4P10_CAVLCCoeffTokenTables
+ M_LDR nC, pNC
+
+ M_BD_INIT1 T1, T2, lr
+ LDR pVLDTable, [pVLDTable, nC, LSL #2] ;// Find VLD table
+
+ M_BD_INIT2 T1, T2, lr
+
+ ;// Decode Symbol = TotalCoeff*4 + TrailingOnes
+ M_BD_VLD Symbol, T1, T2, pVLDTable, 4, 2
+
+ MOVS TotalCoeff, Symbol, LSR #2
+ STRB TotalCoeff, [pNumCoeff]
+ M_PRINTF "TotalCoeff=%d\n", TotalCoeff
+ BEQ.W EndNoError ;// Finished if no coefficients
+
+ CMP Symbol, #17*4
+ BGE.W EndBadSymbol ;// Error if bad symbol
+
+ ;// Save bitstream pointers
+ M_STR ppBitStream, pppBitStream
+ M_STR pOffset, ppOffset
+ M_STR ppPosCoefbuf, pppPosCoefbuf
+
+ ;// Decode Trailing Ones
+ ANDS TrailingOnes, Symbol, #3
+ M_ADR pLevel, ppLevel
+ M_PRINTF "TrailingOnes=%d\n", TrailingOnes
+ BEQ TrailingOnesDone
+ MOV Count, TrailingOnes
+TrailingOnesLoop
+ M_BD_READ8 Symbol, 1, T1
+ SUBS Count, Count, #1
+ MOV T1, #1
+ SUB T1, T1, Symbol, LSL #1
+ M_PRINTF "Level=%d\n", T1
+ STRH T1, [pLevel], #2
+ BGT TrailingOnesLoop
+TrailingOnesDone
+
+ ;// Decode level values
+ SUBS Count, TotalCoeff, TrailingOnes ;// Number of levels to read
+ BEQ DecodeRuns ;// None left
+
+ MOV SuffixLength, #1
+ CMP TotalCoeff, #10
+ MOVLE SuffixLength, #0
+ CMP TrailingOnes, #3 ;// if (TrailingOnes<3)
+ MOVLT TrailingOnes, #4 ;// then TrailingOnes = +4
+ MOVGE TrailingOnes, #2 ;// else TrailingOnes = +2
+ MOVGE SuffixLength, #0 ;// SuffixLength = 0
+
+LevelLoop
+ M_BD_CLZ16 Symbol, T1, T2 ;// Symbol=LevelPrefix
+ CMP Symbol,#16
+ BGE EndBadSymbol
+
+ MOVS lr, SuffixLength ;// if LevelSuffixSize==0
+ TEQEQ Symbol, #14 ;// and LevelPrefix==14
+ MOVEQ lr, #4 ;// then LevelSuffixSize=4
+ TEQ Symbol, #15 ;// if LevelSuffixSize==15
+ MOVEQ lr, #12 ;// then LevelSuffixSize=12
+
+ TEQEQ SuffixLength,#0
+ ADDEQ Symbol,Symbol,#15
+
+ TEQ lr, #0 ;// if LevelSuffixSize==0
+ BEQ LevelCodeRead ;// LevelCode = LevelPrefix
+
+ M_BD_VREAD16 LevelSuffix, lr, T1, T2 ;// Read Level Suffix
+
+ MOV Symbol, Symbol, LSL SuffixLength
+ ADD Symbol, LevelSuffix, Symbol
+
+LevelCodeRead
+ ;// Symbol = LevelCode
+ ADD Symbol, Symbol, TrailingOnes ;// +4 if level cannot be +/-1, +2 o/w
+ MOV TrailingOnes, #2
+ MOVS T1, Symbol, LSR #1
+ RSBCS T1, T1, #0 ;// If Symbol odd then negate
+ M_PRINTF "Level=%d\n", T1
+ STRH T1, [pLevel], #2 ;// Store level.
+
+ LDR T2, =armVCM4P10_SuffixToLevel
+ LDRSB T1, [T2, SuffixLength] ;// Find increment level
+ TEQ SuffixLength, #0
+ MOVEQ SuffixLength, #1
+ CMP Symbol, T1
+ ADDCS SuffixLength, SuffixLength, #1
+ SUBS Count, Count, #1
+ BGT LevelLoop
+
+DecodeRuns
+ ;// Find number of zeros
+ M_LDR T1, pSMaxNumCoeff ;// sMaxNumCoeff
+ SUB Count, TotalCoeff, #1 ;// Number of runs excluding last
+ SUBS ZerosLeft, T1, TotalCoeff ;// Maximum number of zeros there could be
+ M_ADR pRun, ppRun
+ MOV CoeffNum,TotalCoeff
+ SUB CoeffNum,CoeffNum,#1
+ BEQ NoZerosLeft
+
+ ;// Unpack number of zeros from bitstream
+ TEQ T1, #4
+ LDREQ pVLDTable, =(armVCM4P10_CAVLCTotalZeros2x2Tables-4)
+ LDRNE pVLDTable, =(armVCM4P10_CAVLCTotalZeroTables-4)
+ LDR pVLDTable, [pVLDTable, TotalCoeff, LSL #2]
+
+ M_BD_VLD Symbol, T1, T2, pVLDTable, 4, 2 ;// Symbol = ZerosLeft
+ CMP Symbol,#16
+ BGE EndBadSymbol
+
+ LDR ppRunTable, =(armVCM4P10_CAVLCRunBeforeTables-4)
+ M_ADR pRun, ppRun
+ MOVS ZerosLeft, Symbol
+
+ ADD CoeffNum,CoeffNum,ZerosLeft
+
+ BEQ NoZerosLeft
+
+ ;// Decode runs while zeros are left and more than one coefficient
+RunLoop
+ SUBS Count, Count, #1
+ LDR pVLDTable, [ppRunTable, ZerosLeft, LSL#2]
+ BLT LastRun
+ M_BD_VLD Symbol, T1, T2, pVLDTable, 3, 2 ;// Symbol = Run
+ CMP Symbol,#15
+ BGE EndBadSymbol
+
+ SUBS ZerosLeft, ZerosLeft, Symbol
+ M_PRINTF "Run=%d\n", Symbol
+ STRB Symbol, [pRun], #1
+ BGT RunLoop
+
+ ;// Decode runs while no zeros are left
+NoZerosLeft
+ SUBS Count, Count, #1
+ M_PRINTF "Run=%d\n", ZerosLeft
+ STRGEB ZerosLeft, [pRun], #1
+ BGT NoZerosLeft
+
+LastRun
+ ;// Final run length is remaining zeros
+ M_PRINTF "LastRun=%d\n", ZerosLeft
+ STRB ZerosLeft, [pRun], #1
+
+ ;// Write coefficients to output array
+ M_LDR T1, pSMaxNumCoeff ;// sMaxNumCoeff
+ TEQ T1, #15
+ ADDEQ CoeffNum,CoeffNum,#1
+
+
+ SUB pRun,pRun,TotalCoeff
+ SUB pLevel,pLevel,TotalCoeff
+ SUB pLevel,pLevel,TotalCoeff
+
+ M_LDR ppPosCoefbuf, pppPosCoefbuf
+ LDR pPosCoefbuf, [ppPosCoefbuf]
+ TEQ T1, #4
+ LDREQ pZigZag, =armVCM4P10_ZigZag_2x2
+ LDRNE pZigZag, =armVCM4P10_ZigZag_4x4
+
+
+
+OutputLoop
+
+ LDRB T2, [pRun],#1
+ LDRB T1, [pZigZag, CoeffNum]
+ SUB CoeffNum, CoeffNum, #1 ;// Skip Non zero
+ SUB CoeffNum, CoeffNum, T2 ;// Skip Zero run
+
+ LDRSH T2, [pLevel],#2
+
+ SUBS TotalCoeff, TotalCoeff, #1
+ ORREQ T1, T1, #LAST_COEFF
+
+ ADD temp, T2, #128
+ CMP temp, #256
+ ORRCS T1, T1, #TWO_BYTE_COEFF
+
+
+ TEQ TotalCoeff, #0 ;// Preserves carry
+
+ M_PRINTF "Output=%02x %04x\n", T1, T2
+ STRB T1, [pPosCoefbuf], #1
+ STRB T2, [pPosCoefbuf], #1
+ MOV T2, T2, LSR #8
+ STRCSB T2, [pPosCoefbuf], #1
+ BNE OutputLoop
+
+ ;// Finished
+ STR pPosCoefbuf, [ppPosCoefbuf]
+ M_LDR ppBitStream, pppBitStream
+ M_LDR pOffset, ppOffset
+ B EndNoError
+
+EndBadSymbol
+ MOV r0, #OMX_Sts_Err
+ B End
+
+EndNoError
+ ;// Finished reading from the bitstream
+ M_BD_FINI ppBitStream, pOffset
+
+ ;// Set return value
+ MOV r0, #OMX_Sts_NoErr
+End
+ M_END
+
+ ENDIF
+
+ END
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_DequantTables_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_DequantTables_s.s
new file mode 100644
index 0000000..b16f188
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_DequantTables_s.s
@@ -0,0 +1,123 @@
+;//
+;//
+;// File Name: armVCM4P10_DequantTables_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 9641
+;// Date: Thursday, February 7, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ EXPORT armVCM4P10_QPDivTable
+ EXPORT armVCM4P10_VMatrixQPModTable
+ EXPORT armVCM4P10_PosToVCol4x4
+ EXPORT armVCM4P10_PosToVCol2x2
+ EXPORT armVCM4P10_VMatrix
+ EXPORT armVCM4P10_QPModuloTable
+ EXPORT armVCM4P10_VMatrixU16
+
+;// Define the processor variants supported by this file
+
+ M_VARIANTS ARM1136JS
+
+
+;// Guarding implementation by the processor name
+
+
+ IF ARM1136JS :LOR: CortexA8
+
+
+ M_TABLE armVCM4P10_PosToVCol4x4
+ DCB 0, 2, 0, 2
+ DCB 2, 1, 2, 1
+ DCB 0, 2, 0, 2
+ DCB 2, 1, 2, 1
+
+
+ M_TABLE armVCM4P10_PosToVCol2x2
+ DCB 0, 2
+ DCB 2, 1
+
+
+ M_TABLE armVCM4P10_VMatrix
+ DCB 10, 16, 13
+ DCB 11, 18, 14
+ DCB 13, 20, 16
+ DCB 14, 23, 18
+ DCB 16, 25, 20
+ DCB 18, 29, 23
+
+;//-------------------------------------------------------
+;// This table evaluates the expression [(INT)(QP/6)],
+;// for values of QP from 0 to 51 (inclusive).
+;//-------------------------------------------------------
+
+ M_TABLE armVCM4P10_QPDivTable
+ DCB 0, 0, 0, 0, 0, 0
+ DCB 1, 1, 1, 1, 1, 1
+ DCB 2, 2, 2, 2, 2, 2
+ DCB 3, 3, 3, 3, 3, 3
+ DCB 4, 4, 4, 4, 4, 4
+ DCB 5, 5, 5, 5, 5, 5
+ DCB 6, 6, 6, 6, 6, 6
+ DCB 7, 7, 7, 7, 7, 7
+ DCB 8, 8, 8, 8, 8, 8
+
+;//----------------------------------------------------
+;// This table contains armVCM4P10_VMatrix[QP%6][0] entires,
+;// for values of QP from 0 to 51 (inclusive).
+;//----------------------------------------------------
+
+ M_TABLE armVCM4P10_VMatrixQPModTable
+ DCB 10, 11, 13, 14, 16, 18
+ DCB 10, 11, 13, 14, 16, 18
+ DCB 10, 11, 13, 14, 16, 18
+ DCB 10, 11, 13, 14, 16, 18
+ DCB 10, 11, 13, 14, 16, 18
+ DCB 10, 11, 13, 14, 16, 18
+ DCB 10, 11, 13, 14, 16, 18
+ DCB 10, 11, 13, 14, 16, 18
+ DCB 10, 11, 13, 14, 16, 18
+
+;//-------------------------------------------------------
+;// This table evaluates the modulus expression [QP%6]*6,
+;// for values of QP from 0 to 51 (inclusive).
+;//-------------------------------------------------------
+
+ M_TABLE armVCM4P10_QPModuloTable
+ DCB 0, 6, 12, 18, 24, 30
+ DCB 0, 6, 12, 18, 24, 30
+ DCB 0, 6, 12, 18, 24, 30
+ DCB 0, 6, 12, 18, 24, 30
+ DCB 0, 6, 12, 18, 24, 30
+ DCB 0, 6, 12, 18, 24, 30
+ DCB 0, 6, 12, 18, 24, 30
+ DCB 0, 6, 12, 18, 24, 30
+ DCB 0, 6, 12, 18, 24, 30
+
+;//-------------------------------------------------------
+;// This table contains the invidual byte values stored as
+;// halfwords. This avoids unpacking inside the function
+;//-------------------------------------------------------
+
+ M_TABLE armVCM4P10_VMatrixU16
+ DCW 10, 16, 13
+ DCW 11, 18, 14
+ DCW 13, 20, 16
+ DCW 14, 23, 18
+ DCW 16, 25, 20
+ DCW 18, 29, 23
+
+ ENDIF ;//ARM1136JS
+
+
+
+
+ END
\ No newline at end of file
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_Align_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_Align_unsafe_s.s
new file mode 100644
index 0000000..82b9542
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_Align_unsafe_s.s
@@ -0,0 +1,236 @@
+;//
+;//
+;// File Name: armVCM4P10_InterpolateLuma_Align_unsafe_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 9641
+;// Date: Thursday, February 7, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS ARM1136JS
+
+ EXPORT armVCM4P10_InterpolateLuma_HorAlign9x_unsafe
+ EXPORT armVCM4P10_InterpolateLuma_VerAlign4x_unsafe
+
+DEBUG_ON SETL {FALSE}
+
+ IF ARM1136JS
+
+;// Declare input registers
+pSrc RN 0
+srcStep RN 1
+pDst RN 8
+iHeight RN 9
+
+;// Declare inner loop registers
+x RN 7
+x0 RN 7
+x1 RN 10
+x2 RN 11
+Scratch RN 12
+
+;// Function:
+;// armVCM4P10_InterpolateLuma_HorAlign9x_unsafe
+;//
+;// Implements copy from an arbitrary aligned source memory location (pSrc) to a 4 byte aligned
+;// destination pointed by (pDst) for horizontal interpolation.
+;// This function needs to copy 9 bytes in horizontal direction.
+;//
+;// Registers used as input for this function
+;// r0,r1,r8,r9 where r8 containings aligned memory pointer and r9 no rows to copy
+;//
+;// Registers preserved for top level function
+;// r2,r3,r4,r5,r6
+;//
+;// Registers modified by the function
+;// r7,r8,r9,r10,r11,r12
+;//
+;// Output registers
+;// r0 - pointer to the new aligned location which will be used as pSrc
+;// r1 - step size to this aligned location
+
+ ;// Function header
+ M_START armVCM4P10_InterpolateLuma_HorAlign9x_unsafe
+
+ ;// Copy pDst to scratch
+ MOV Scratch, pDst
+
+StartAlignedStackCopy
+ AND x, pSrc, #3
+ BIC pSrc, pSrc, #3
+
+ M_SWITCH x
+ M_CASE Copy0toAligned
+ M_CASE Copy1toAligned
+ M_CASE Copy2toAligned
+ M_CASE Copy3toAligned
+ M_ENDSWITCH
+
+Copy0toAligned
+ LDM pSrc, {x0, x1, x2}
+ SUBS iHeight, iHeight, #1
+ ADD pSrc, pSrc, srcStep
+
+ ;// One cycle stall
+
+ STM pDst!, {x0, x1, x2} ;// Store aligned output row
+ BGT Copy0toAligned
+ B CopyEnd
+
+Copy1toAligned
+ LDM pSrc, {x0, x1, x2}
+ SUBS iHeight, iHeight, #1
+ ADD pSrc, pSrc, srcStep
+
+ ;// One cycle stall
+
+ MOV x0, x0, LSR #8
+ ORR x0, x0, x1, LSL #24
+ MOV x1, x1, LSR #8
+ ORR x1, x1, x2, LSL #24
+ MOV x2, x2, LSR #8
+ STM pDst!, {x0, x1, x2} ;// Store aligned output row
+ BGT Copy1toAligned
+ B CopyEnd
+
+Copy2toAligned
+ LDM pSrc, {x0, x1, x2}
+ SUBS iHeight, iHeight, #1
+ ADD pSrc, pSrc, srcStep
+
+ ;// One cycle stall
+
+ MOV x0, x0, LSR #16
+ ORR x0, x0, x1, LSL #16
+ MOV x1, x1, LSR #16
+ ORR x1, x1, x2, LSL #16
+ MOV x2, x2, LSR #16
+ STM pDst!, {x0, x1, x2} ;// Store aligned output row
+ BGT Copy2toAligned
+ B CopyEnd
+
+Copy3toAligned
+ LDM pSrc, {x0, x1, x2}
+ SUBS iHeight, iHeight, #1
+ ADD pSrc, pSrc, srcStep
+
+ ;// One cycle stall
+
+ MOV x0, x0, LSR #24
+ ORR x0, x0, x1, LSL #8
+ MOV x1, x1, LSR #24
+ ORR x1, x1, x2, LSL #8
+ MOV x2, x2, LSR #24
+ STM pDst!, {x0, x1, x2} ;// Store aligned output row
+ BGT Copy3toAligned
+
+CopyEnd
+
+ MOV pSrc, Scratch
+ MOV srcStep, #12
+
+ M_END
+
+
+;// Function:
+;// armVCM4P10_InterpolateLuma_VerAlign4x_unsafe
+;//
+;// Implements copy from an arbitrary aligned source memory location (pSrc) to an aligned
+;// destination pointed by (pDst) for vertical interpolation.
+;// This function needs to copy 4 bytes in horizontal direction
+;//
+;// Registers used as input for this function
+;// r0,r1,r8,r9 where r8 containings aligned memory pointer and r9 no of rows to copy
+;//
+;// Registers preserved for top level function
+;// r2,r3,r4,r5,r6
+;//
+;// Registers modified by the function
+;// r7,r8,r9,r10,r11,r12
+;//
+;// Output registers
+;// r0 - pointer to the new aligned location which will be used as pSrc
+;// r1 - step size to this aligned location
+
+ ;// Function header
+ M_START armVCM4P10_InterpolateLuma_VerAlign4x_unsafe
+
+ ;// Copy pSrc to stack
+StartVAlignedStackCopy
+ AND x, pSrc, #3
+ BIC pSrc, pSrc, #3
+
+
+ M_SWITCH x
+ M_CASE Copy0toVAligned
+ M_CASE Copy1toVAligned
+ M_CASE Copy2toVAligned
+ M_CASE Copy3toVAligned
+ M_ENDSWITCH
+
+Copy0toVAligned
+ M_LDR x0, [pSrc], srcStep
+ SUBS iHeight, iHeight, #1
+
+ ;// One cycle stall
+
+ STR x0, [pDst], #4 ;// Store aligned output row
+ BGT Copy0toVAligned
+ B CopyVEnd
+
+Copy1toVAligned
+ LDR x1, [pSrc, #4]
+ M_LDR x0, [pSrc], srcStep
+ SUBS iHeight, iHeight, #1
+
+ ;// One cycle stall
+
+ MOV x1, x1, LSL #24
+ ORR x0, x1, x0, LSR #8
+ STR x0, [pDst], #4 ;// Store aligned output row
+ BGT Copy1toVAligned
+ B CopyVEnd
+
+Copy2toVAligned
+ LDR x1, [pSrc, #4]
+ M_LDR x0, [pSrc], srcStep
+ SUBS iHeight, iHeight, #1
+
+ ;// One cycle stall
+
+ MOV x1, x1, LSL #16
+ ORR x0, x1, x0, LSR #16
+ STR x0, [pDst], #4 ;// Store aligned output row
+ BGT Copy2toVAligned
+ B CopyVEnd
+
+Copy3toVAligned
+ LDR x1, [pSrc, #4]
+ M_LDR x0, [pSrc], srcStep
+ SUBS iHeight, iHeight, #1
+
+ ;// One cycle stall
+
+ MOV x1, x1, LSL #8
+ ORR x0, x1, x0, LSR #24
+ STR x0, [pDst], #4 ;// Store aligned output row
+ BGT Copy3toVAligned
+
+CopyVEnd
+
+ SUB pSrc, pDst, #28
+ MOV srcStep, #4
+
+ M_END
+
+
+ ENDIF
+
+ END
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_Copy_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_Copy_unsafe_s.s
new file mode 100644
index 0000000..bc0b6ec
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_Copy_unsafe_s.s
@@ -0,0 +1,149 @@
+;//
+;//
+;// File Name: armVCM4P10_InterpolateLuma_Copy_unsafe_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 9641
+;// Date: Thursday, February 7, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+;// Function:
+;// armVCM4P10_InterpolateLuma_Copy4x4_unsafe
+;//
+;// Implements copy from an arbitrary aligned source memory location (pSrc) to an aligned
+;// destination pointed by (pDst)
+;//
+;// Registers preserved for top level function
+;// r1,r3,r4,r5,r6,r7,r10,r11,r14
+;//
+;// Registers modified by the function
+;// r0,r2,r8,r9,r12
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS ARM1136JS
+
+ EXPORT armVCM4P10_InterpolateLuma_Copy4x4_unsafe
+
+;// Declare input registers
+pSrc RN 0
+srcStep RN 1
+pDst RN 2
+dstStep RN 3
+
+;// Declare other intermediate registers
+x0 RN 4
+x1 RN 5
+x2 RN 8
+x3 RN 9
+Temp RN 12
+
+ IF ARM1136JS
+
+ M_START armVCM4P10_InterpolateLuma_Copy4x4_unsafe, r6
+
+Copy4x4Start
+ ;// Do Copy and branch to EndOfInterpolation
+ AND Temp, pSrc, #3
+ BIC pSrc, pSrc, #3
+
+ M_SWITCH Temp
+ M_CASE Copy4x4Align0
+ M_CASE Copy4x4Align1
+ M_CASE Copy4x4Align2
+ M_CASE Copy4x4Align3
+ M_ENDSWITCH
+
+Copy4x4Align0
+ M_LDR x0, [pSrc], srcStep
+ M_LDR x1, [pSrc], srcStep
+ M_STR x0, [pDst], dstStep
+ M_LDR x2, [pSrc], srcStep
+ M_STR x1, [pDst], dstStep
+ M_LDR x3, [pSrc], srcStep
+ M_STR x2, [pDst], dstStep
+ M_STR x3, [pDst], dstStep
+ B Copy4x4End
+
+Copy4x4Align1
+ LDR x1, [pSrc, #4]
+ M_LDR x0, [pSrc], srcStep
+ LDR x3, [pSrc, #4]
+ M_LDR x2, [pSrc], srcStep
+ MOV x0, x0, LSR #8
+ ORR x0, x0, x1, LSL #24
+ M_STR x0, [pDst], dstStep
+ MOV x2, x2, LSR #8
+ ORR x2, x2, x3, LSL #24
+ LDR x1, [pSrc, #4]
+ M_LDR x0, [pSrc], srcStep
+ M_STR x2, [pDst], dstStep
+ LDR x3, [pSrc, #4]
+ M_LDR x2, [pSrc], srcStep
+ MOV x0, x0, LSR #8
+ ORR x0, x0, x1, LSL #24
+ M_STR x0, [pDst], dstStep
+ MOV x2, x2, LSR #8
+ ORR x2, x2, x3, LSL #24
+ M_STR x2, [pDst], dstStep
+ B Copy4x4End
+
+Copy4x4Align2
+ LDR x1, [pSrc, #4]
+ M_LDR x0, [pSrc], srcStep
+ LDR x3, [pSrc, #4]
+ M_LDR x2, [pSrc], srcStep
+ MOV x0, x0, LSR #16
+ ORR x0, x0, x1, LSL #16
+ M_STR x0, [pDst], dstStep
+ MOV x2, x2, LSR #16
+ ORR x2, x2, x3, LSL #16
+ M_STR x2, [pDst], dstStep
+
+ LDR x1, [pSrc, #4]
+ M_LDR x0, [pSrc], srcStep
+ LDR x3, [pSrc, #4]
+ M_LDR x2, [pSrc], srcStep
+ MOV x0, x0, LSR #16
+ ORR x0, x0, x1, LSL #16
+ M_STR x0, [pDst], dstStep
+ MOV x2, x2, LSR #16
+ ORR x2, x2, x3, LSL #16
+ M_STR x2, [pDst], dstStep
+ B Copy4x4End
+
+Copy4x4Align3
+ LDR x1, [pSrc, #4]
+ M_LDR x0, [pSrc], srcStep
+ LDR x3, [pSrc, #4]
+ M_LDR x2, [pSrc], srcStep
+ MOV x0, x0, LSR #24
+ ORR x0, x0, x1, LSL #8
+ M_STR x0, [pDst], dstStep
+ MOV x2, x2, LSR #24
+ ORR x2, x2, x3, LSL #8
+ M_STR x2, [pDst], dstStep
+
+ LDR x1, [pSrc, #4]
+ M_LDR x0, [pSrc], srcStep
+ LDR x3, [pSrc, #4]
+ M_LDR x2, [pSrc], srcStep
+ MOV x0, x0, LSR #24
+ ORR x0, x0, x1, LSL #8
+ M_STR x0, [pDst], dstStep
+ MOV x2, x2, LSR #24
+ ORR x2, x2, x3, LSL #8
+ M_STR x2, [pDst], dstStep
+ B Copy4x4End
+
+Copy4x4End
+ M_END
+
+ ENDIF
+
+ END
+
\ No newline at end of file
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_DiagCopy_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_DiagCopy_unsafe_s.s
new file mode 100644
index 0000000..66cfe5e
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_DiagCopy_unsafe_s.s
@@ -0,0 +1,178 @@
+;//
+;//
+;// File Name: armVCM4P10_InterpolateLuma_DiagCopy_unsafe_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 9641
+;// Date: Thursday, February 7, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS ARM1136JS
+
+ EXPORT armVCM4P10_InterpolateLuma_HorDiagCopy_unsafe
+ EXPORT armVCM4P10_InterpolateLuma_VerDiagCopy_unsafe
+
+;// Functions:
+;// armVCM4P10_InterpolateLuma_HorDiagCopy_unsafe and
+;// armVCM4P10_InterpolateLuma_VerDiagCopy_unsafe
+;//
+;// Implements re-arrangement of data from temporary buffer to a buffer pointed by pBuf.
+;// This will do the convertion of data from 16 bit to 8 bit and it also
+;// remove offset and check for saturation.
+;//
+;// Registers used as input for this function
+;// r0,r1,r7 where r0 is input pointer and r2 its step size, r7 is output pointer
+;//
+;// Registers preserved for top level function
+;// r4,r5,r6,r8,r9,r14
+;//
+;// Registers modified by the function
+;// r7,r10,r11,r12
+;//
+;// Output registers
+;// r0 - pointer to the destination location
+;// r1 - step size to this destination location
+
+
+DEBUG_ON SETL {FALSE}
+
+MASK EQU 0x80808080 ;// Mask is used to implement (a+b+1)/2
+
+;// Declare input registers
+
+pSrc0 RN 0
+srcStep0 RN 1
+
+;// Declare other intermediate registers
+Temp1 RN 4
+Temp2 RN 5
+Temp3 RN 10
+Temp4 RN 11
+pBuf RN 7
+r0x0fe00fe0 RN 6
+r0x00ff00ff RN 12
+Count RN 14
+ValueA0 RN 10
+ValueA1 RN 11
+
+ IF ARM1136JS
+
+
+ ;// Function header
+ M_START armVCM4P10_InterpolateLuma_HorDiagCopy_unsafe, r6
+
+ ;// Code start
+ MOV Count, #4
+ LDR r0x0fe00fe0, =0x0fe00fe0
+ LDR r0x00ff00ff, =0x00ff00ff
+LoopStart1
+ LDR Temp4, [pSrc0, #12]
+ LDR Temp3, [pSrc0, #8]
+ LDR Temp2, [pSrc0, #4]
+ M_LDR Temp1, [pSrc0], srcStep0
+ UQSUB16 Temp4, Temp4, r0x0fe00fe0
+ UQSUB16 Temp3, Temp3, r0x0fe00fe0
+ UQSUB16 Temp2, Temp2, r0x0fe00fe0
+ UQSUB16 Temp1, Temp1, r0x0fe00fe0
+ USAT16 Temp4, #13, Temp4
+ USAT16 Temp3, #13, Temp3
+ USAT16 Temp2, #13, Temp2
+ USAT16 Temp1, #13, Temp1
+ AND Temp4, r0x00ff00ff, Temp4, LSR #5
+ AND Temp3, r0x00ff00ff, Temp3, LSR #5
+ AND Temp2, r0x00ff00ff, Temp2, LSR #5
+ AND Temp1, r0x00ff00ff, Temp1, LSR #5
+ ORR ValueA1, Temp3, Temp4, LSL #8
+ ORR ValueA0, Temp1, Temp2, LSL #8
+ SUBS Count, Count, #1
+ STRD ValueA0, [pBuf], #8
+ BGT LoopStart1
+End1
+ SUB pSrc0, pBuf, #32
+ MOV srcStep0, #8
+
+ M_END
+
+
+ ;// Function header
+ M_START armVCM4P10_InterpolateLuma_VerDiagCopy_unsafe, r6
+
+ ;// Code start
+ LDR r0x0fe00fe0, =0x0fe00fe0
+ LDR r0x00ff00ff, =0x00ff00ff
+ MOV Count, #2
+
+LoopStart
+ LDR Temp4, [pSrc0, #12]
+ LDR Temp3, [pSrc0, #8]
+ LDR Temp2, [pSrc0, #4]
+ M_LDR Temp1, [pSrc0], srcStep0
+
+ UQSUB16 Temp4, Temp4, r0x0fe00fe0
+ UQSUB16 Temp3, Temp3, r0x0fe00fe0
+ UQSUB16 Temp2, Temp2, r0x0fe00fe0
+ UQSUB16 Temp1, Temp1, r0x0fe00fe0
+
+ USAT16 Temp4, #13, Temp4
+ USAT16 Temp3, #13, Temp3
+ USAT16 Temp2, #13, Temp2
+ USAT16 Temp1, #13, Temp1
+
+ AND Temp4, r0x00ff00ff, Temp4, LSR #5
+ AND Temp3, r0x00ff00ff, Temp3, LSR #5
+ AND Temp2, r0x00ff00ff, Temp2, LSR #5
+ AND Temp1, r0x00ff00ff, Temp1, LSR #5
+ ORR ValueA1, Temp3, Temp4, LSL #8 ;// [d2 c2 d0 c0]
+ ORR ValueA0, Temp1, Temp2, LSL #8 ;// [b2 a2 b0 a0]
+
+ PKHBT Temp1, ValueA0, ValueA1, LSL #16 ;// [d0 c0 b0 a0]
+
+ STR Temp1, [pBuf], #8
+ PKHTB Temp2, ValueA1, ValueA0, ASR #16 ;// [d2 c2 b2 a2]
+ STR Temp2, [pBuf], #-4
+
+ LDR Temp4, [pSrc0, #12]
+ LDR Temp3, [pSrc0, #8]
+ LDR Temp2, [pSrc0, #4]
+ M_LDR Temp1, [pSrc0], srcStep0
+
+ UQSUB16 Temp4, Temp4, r0x0fe00fe0
+ UQSUB16 Temp3, Temp3, r0x0fe00fe0
+ UQSUB16 Temp2, Temp2, r0x0fe00fe0
+ UQSUB16 Temp1, Temp1, r0x0fe00fe0
+
+ USAT16 Temp4, #13, Temp4
+ USAT16 Temp3, #13, Temp3
+ USAT16 Temp2, #13, Temp2
+ USAT16 Temp1, #13, Temp1
+
+ AND Temp4, r0x00ff00ff, Temp4, LSR #5
+ AND Temp3, r0x00ff00ff, Temp3, LSR #5
+ AND Temp2, r0x00ff00ff, Temp2, LSR #5
+ AND Temp1, r0x00ff00ff, Temp1, LSR #5
+ ORR ValueA1, Temp3, Temp4, LSL #8 ;// [d2 c2 d0 c0]
+ ORR ValueA0, Temp1, Temp2, LSL #8 ;// [b2 a2 b0 a0]
+
+ PKHBT Temp1, ValueA0, ValueA1, LSL #16 ;// [d0 c0 b0 a0]
+ SUBS Count, Count, #1
+ STR Temp1, [pBuf], #8
+ PKHTB Temp2, ValueA1, ValueA0, ASR #16 ;// [d2 c2 b2 a2]
+ STR Temp2, [pBuf], #4
+
+ BGT LoopStart
+End2
+ SUB pSrc0, pBuf, #32-8
+ MOV srcStep0, #4
+
+ M_END
+
+ ENDIF
+
+ END
+
\ No newline at end of file
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe_s.s
new file mode 100644
index 0000000..851ff6a
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe_s.s
@@ -0,0 +1,296 @@
+;//
+;//
+;// File Name: armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 9641
+;// Date: Thursday, February 7, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ EXPORT armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe
+
+ M_VARIANTS ARM1136JS
+
+
+
+ IF ARM1136JS
+
+
+ M_ALLOC8 ppDstArgs, 8
+ M_ALLOC8 pTempResult1, 8
+ M_ALLOC8 pTempResult2, 8
+ M_ALLOC4 ppSrc, 4
+ M_ALLOC4 ppDst, 4
+ M_ALLOC4 pDstStep, 4
+ M_ALLOC4 pSrcStep, 4
+ M_ALLOC4 pCounter, 4
+
+ ;// Function header
+ ;// Function:
+ ;// armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe
+ ;//
+ ;// Implements diagonal interpolation for a block of size 4x4. Input and output should
+ ;// be aligned.
+ ;//
+ ;// Registers used as input for this function
+ ;// r0,r1,r2,r3, r8 where r0,r2 input pointer and r1,r3 step size, r8 intermediate-buf pointer
+ ;//
+ ;// Registers preserved for top level function
+ ;// r0,r1,r2,r3,r4,r5,r6,r14
+ ;//
+ ;// Registers modified by the function
+ ;// r7,r8,r9,r10,r11,r12
+ ;//
+ ;// Output registers
+ ;// None. Function will preserve r0-r3
+
+ M_START armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe, r6
+
+;// Declare input registers
+pSrc RN 0
+srcStep RN 1
+pDst RN 2
+dstStep RN 3
+
+;// Declare inner loop registers
+Acc0 RN 4
+Acc1 RN 5
+Acc2 RN 6
+Acc3 RN 7
+
+ValA RN 4
+ValB RN 5
+ValC RN 6
+ValD RN 7
+ValE RN 8
+ValF RN 9
+ValG RN 12
+ValH RN 14
+ValI RN 1
+
+Temp1 RN 3
+Temp2 RN 1
+Temp3 RN 12
+Temp4 RN 7
+Temp5 RN 5
+r0x0fe00fe0 RN 3 ;// [0 (16*255 - 16) 0 (16*255 - 16)]
+r0x00ff00ff RN 10 ;// [0 255 0 255] where 255 is offset
+Counter RN 11
+pInterBuf RN 8
+
+ValCA RN 8
+ValDB RN 9
+ValGE RN 10
+ValHF RN 11
+r0x00140001 RN 12
+r0x0014fffb RN 14
+
+r0x0001fc00 RN 11
+
+Accx RN 8
+Accy RN 9
+Temp6 RN 14
+
+ M_STRD pDst, dstStep, ppDstArgs
+
+ MOV pDst, pInterBuf
+ MOV dstStep, #16
+
+ ;// Set up counter of format, [0] [0] [1 (height)] [8 (width)]
+ MOV Counter, #4
+ M_STR dstStep, pDstStep
+ M_STR srcStep, pSrcStep
+ LDR r0x00ff00ff, =0x00ff00ff ;// [0 255 0 255] 255 is offset to avoid negative results
+
+HeightLoop
+NextTwoRowsLoop
+ LDR ValD, [pSrc, srcStep] ;// Load row 1 [d1 c1 b1 a1]
+ LDR ValA, [pSrc], #4 ;// Load row 0 [d0 c0 b0 a0]
+ LDR ValH, [pSrc, srcStep] ;// Load [h1 g1 f1 e1]
+ LDR ValE, [pSrc], #4 ;// Load [h0 g0 f0 e0]
+ LDRB Temp2, [pSrc, srcStep] ;// Load row 1 [l1 k1 j1 i1]
+ LDRB Temp1, [pSrc], #-8 ;// Load row 0 [l0 k0 j0 i0]
+
+ PKHBT ValB, ValA, ValD, LSL #16 ;// [b1 a1 b0 a0]
+ PKHTB ValD, ValD, ValA, ASR #16 ;// [d1 c1 d0 c0]
+ UXTAB16 ValA, r0x00ff00ff, ValB ;// [00 a1 00 a0] + [0 255 0 255]
+ UXTAB16 ValC, r0x00ff00ff, ValD ;// [00 c1 00 c0] + [0 255 0 255]
+ PKHBT ValI, Temp1, Temp2, LSL #16 ;// [00 i1 00 i0]
+ PKHBT ValF, ValE, ValH, LSL #16 ;// [f1 e1 f0 e0]
+ PKHTB ValH, ValH, ValE, ASR #16 ;// [h1 g1 h0 g0]
+ UXTAB16 ValE, r0x00ff00ff, ValF ;// [00 e1 00 e0] + [0 255 0 255]
+
+ ;// Calculate Acc0
+ ;// Acc0 = a - 5*b + 20*c + 20*d - 5*e + f
+ UXTAB16 Temp1, ValC, ValD, ROR #8
+ UXTAB16 Temp3, ValE, ValB, ROR #8
+ RSB Temp1, Temp3, Temp1, LSL #2
+ UXTAB16 Acc0, ValA, ValF, ROR #8
+ ADD Temp1, Temp1, Temp1, LSL #2
+ ADD Acc0, Acc0, Temp1
+
+ ;// Calculate Acc1
+ ;// Acc1 = b - 5*c + 20*d + 20*e - 5*f + g
+ UXTAB16 Temp1, ValE, ValD, ROR #8
+ UXTAB16 Temp3, ValC, ValF, ROR #8
+ RSB Temp1, Temp3, Temp1, LSL #2
+ UXTAB16 ValG, r0x00ff00ff, ValH ;// [00 g1 00 g0] + [0 255 0 255]
+ ADD Temp1, Temp1, Temp1, LSL #2
+ UXTAB16 Acc1, ValG, ValB, ROR #8
+ ADD Acc1, Acc1, Temp1
+
+ UXTAB16 Acc2, ValC, ValH, ROR #8
+ ADD ValI, r0x00ff00ff, ValI ;// [00 i1 00 i0] + [0 255 0 255]
+
+ ;// Calculate Acc2
+ ;// Acc2 = c - 5*d + 20*e + 20*f - 5*g + h
+ UXTAB16 Temp1, ValG, ValD, ROR #8
+ UXTAB16 Acc3, ValI, ValD, ROR #8
+ UXTAB16 Temp2, ValE, ValF, ROR #8
+
+ RSB Temp1, Temp1, Temp2, LSL #2
+ UXTAB16 Temp2, ValG, ValF, ROR #8
+ ADD Temp1, Temp1, Temp1, LSL #2
+ ADD Acc2, Acc2, Temp1
+
+ ;// Calculate Acc3
+ ;// Acc3 = d - 5*e + 20*f + 20*g - 5*h + i
+ UXTAB16 Temp1, ValE, ValH, ROR #8
+ RSB Temp1, Temp1, Temp2, LSL #2
+ ADD Temp1, Temp1, Temp1, LSL #2
+ ADD Acc3, Acc3, Temp1
+
+ M_LDR dstStep, pDstStep
+ M_LDR srcStep, pSrcStep
+
+ ;// If Counter is even store Acc0-Acc3 in a temporary buffer
+ ;// If Counter is off store Acc0-Acc3 and previous Acc0-Acc3 in a intermediate buf
+ ANDS Temp3, Counter, #1
+ BEQ NoProcessing
+
+ ;// Packing previous and current Acc0-Acc3 values
+ M_LDRD Accx, Accy, pTempResult1
+ PKHBT Temp6, Accx, Acc0, LSL #16 ;//[0 a2 0 a0] = [0 a3 0 a2] [0 a1 0 a0]
+ PKHTB Acc0, Acc0, Accx, ASR #16 ;//[0 a3 0 a1] = [0 a1 0 a0] [0 a3 0 a2]
+ STR Acc0, [pDst, dstStep]
+ STR Temp6, [pDst], #4
+ PKHBT Temp6, Accy, Acc1, LSL #16 ;//[0 b2 0 b0] = [0 b3 0 b2] [0 b1 0 b0]
+ PKHTB Acc1, Acc1, Accy, ASR #16 ;//[0 b3 0 b1] = [0 b1 0 b0] [0 b3 0 b2]
+ M_LDRD Accx, Accy, pTempResult2
+ STR Acc1, [pDst, dstStep]
+ STR Temp6, [pDst], #4
+
+ PKHBT Temp6, Accx, Acc2, LSL #16 ;//[0 c2 0 c0] = [0 c3 0 c2] [0 c1 0 c0]
+ PKHTB Acc2, Acc2, Accx, ASR #16 ;//[0 c3 0 c1] = [0 c1 0 c0] [0 c3 0 c2]
+ STR Acc2, [pDst, dstStep]
+ STR Temp6, [pDst], #4
+ PKHBT Temp6, Accy, Acc3, LSL #16 ;//[0 d2 0 d0] = [0 d3 0 d2] [0 d1 0 d0]
+ PKHTB Acc3, Acc3, Accy, ASR #16 ;//[0 d3 0 d1] = [0 d1 0 d0] [0 d3 0 d2]
+ STR Acc3, [pDst, dstStep]
+ STR Temp6, [pDst], #-12
+ ADD pDst, pDst, dstStep, LSL #1
+ B AfterStore
+
+NoProcessing
+ M_STRD Acc0, Acc1, pTempResult1
+ M_STRD Acc2, Acc3, pTempResult2
+AfterStore
+ SUBS Counter, Counter, #1 ;// Loop till height is 10
+ ADD pSrc, pSrc, srcStep, LSL #1
+ BPL HeightLoop
+
+ STR Acc0, [pDst], #4 ;//[0 a1 0 a0]
+ STR Acc1, [pDst], #4
+ STR Acc2, [pDst], #4
+ STR Acc3, [pDst], #-12
+
+ ;//
+ ;// Horizontal interpolation using multiplication
+ ;//
+
+ SUB pSrc, pDst, dstStep, LSL #2
+ MOV srcStep, #16
+ M_LDRD pDst, dstStep, ppDstArgs
+
+ MOV Counter, #4
+ LDR r0x0014fffb, =0x0014fffb
+ LDR r0x00140001, =0x00140001
+
+HeightLoop1
+ M_STR Counter, pCounter
+
+ M_LDR ValCA, [pSrc], srcStep ;// Load [0 c 0 a]
+ M_LDR ValDB, [pSrc], srcStep ;// Load [0 d 0 b]
+ M_LDR ValGE, [pSrc], srcStep ;// Load [0 g 0 e]
+ M_LDR ValHF, [pSrc], srcStep ;// Load [0 h 0 f]
+
+
+ ;// Acc0 = smuad ([0 20 0 1], add([0 c 0 a] + [0 d 0 f])) - (5 * (b + e))
+ ;// Acc1 = smuad ([0 20 0 1], add([0 e 0 g] + [0 d 0 b])) - (5 * (c + f))
+ ;// Acc2 = smuad ([0 1 0 20], add([0 c 0 e] + [0 h 0 f])) - (5 * (d + g))
+ ;// Acc3 = smuad ([0 20 0 1], add([0 d 0 f] + [0 i 0 g])) - (5 * (e + h))
+
+ SMUAD Acc0, ValCA, r0x00140001 ;// Acc0 = [0 c 0 a] * [0 20 0 1]
+ SMUAD Acc1, ValDB, r0x00140001 ;// Acc1 = [0 c 0 a] * [0 20 0 1]
+ SMUADX Acc2, ValGE, r0x0014fffb ;// Acc2 = [0 g 0 e] * [0 20 0 -5]
+ SMUAD Acc3, ValGE, r0x0014fffb ;// Acc3 = [0 g 0 e] * [0 20 0 -5]
+
+ SMLAD Acc0, ValDB, r0x0014fffb, Acc0 ;// Acc0 += [0 d 0 b] * [0 20 0 -5]
+ SMLADX Acc1, ValGE, r0x00140001, Acc1 ;// Acc1 += [0 g 0 e] * [0 20 0 1]
+ SMLADX Acc2, ValHF, r0x00140001, Acc2 ;// Acc2 += [0 h 0 f] * [0 20 0 1]
+ SMLADX Acc3, ValHF, r0x0014fffb, Acc3 ;// Acc3 += [0 h 0 f] * [0 20 0 -5]
+
+ SMLABB Acc0, ValGE, r0x0014fffb, Acc0 ;// Acc0 += [0 g 0 e] * [0 0 0 -5]
+ SMLATB Acc1, ValCA, r0x0014fffb, Acc1 ;// Acc1 += [0 d 0 b] * [0 0 0 -5]
+ SMLATB Acc2, ValCA, r0x00140001, Acc2 ;// Acc2 += [0 c 0 a] * [0 0 0 1]
+ SMLATB Acc3, ValDB, r0x00140001, Acc3 ;// Acc3 += [0 c 0 a] * [0 0 0 1]
+
+ LDRH ValCA, [pSrc], #4 ;// 8 = srcStep - 16
+ SMLABB Acc0, ValHF, r0x00140001, Acc0 ;// Acc0 += [0 h 0 f] * [0 0 0 1]
+ SMLABB Acc1, ValHF, r0x0014fffb, Acc1 ;// Acc1 += [0 h 0 f] * [0 0 0 -5]
+ SMLATB Acc2, ValDB, r0x0014fffb, Acc2 ;// Acc2 += [0 d 0 b] * [0 0 0 -5]
+ SMLABB Acc3, ValCA, r0x00140001, Acc3 ;// Acc3 += [0 d 0 b] * [0 0 0 1]
+
+ LDR r0x0001fc00, =0x0001fc00 ;// (0xff * 16 * 32) - 512
+ SUB Acc0, Acc0, r0x0001fc00
+ SUB Acc1, Acc1, r0x0001fc00
+ SUB Acc2, Acc2, r0x0001fc00
+ SUB Acc3, Acc3, r0x0001fc00
+
+ USAT Acc0, #18, Acc0
+ USAT Acc1, #18, Acc1
+ USAT Acc2, #18, Acc2
+ USAT Acc3, #18, Acc3
+
+ MOV Acc0, Acc0, LSR #10
+ M_STRB Acc0, [pDst], dstStep
+ MOV Acc1, Acc1, LSR #10
+ M_STRB Acc1, [pDst], dstStep
+ MOV Acc2, Acc2, LSR #10
+ M_STRB Acc2, [pDst], dstStep
+ MOV Acc3, Acc3, LSR #10
+ M_STRB Acc3, [pDst], dstStep
+
+
+ M_LDR Counter, pCounter
+ SUB pDst, pDst, dstStep, LSL #2
+ SUB pSrc, pSrc, srcStep, LSL #2
+ ADD pDst, pDst, #1
+ SUBS Counter, Counter, #1
+ BGT HeightLoop1
+End
+ SUB pDst, pDst, #4
+ SUB pSrc, pSrc, #16
+
+ M_END
+
+ ENDIF
+
+ END
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe_s.s
new file mode 100644
index 0000000..2f48e13
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe_s.s
@@ -0,0 +1,276 @@
+;//
+;//
+;// File Name: armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 9641
+;// Date: Thursday, February 7, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ EXPORT armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe
+
+ M_VARIANTS ARM1136JS
+
+
+
+
+
+ IF ARM1136JS
+
+ M_ALLOC8 ppDstArgs, 8
+ M_ALLOC4 ppSrc, 4
+ M_ALLOC4 ppDst, 4
+ M_ALLOC4 pCounter, 4
+
+ ;// Function header
+ ;// Function:
+ ;// armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe
+ ;//
+ ;// Implements diagonal interpolation for a block of size 4x4. Input and output should
+ ;// be aligned.
+ ;//
+ ;// Registers used as input for this function
+ ;// r0,r1,r2,r3, r8 where r0,r2 input pointer and r1,r3 step size, r8 intermediate-buf pointer
+ ;//
+ ;// Registers preserved for top level function
+ ;// r0,r1,r2,r3,r4,r5,r6,r14
+ ;//
+ ;// Registers modified by the function
+ ;// r7,r8,r9,r10,r11,r12
+ ;//
+ ;// Output registers
+ ;// None. Function will preserve r0-r3
+
+ M_START armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe, r6
+
+;// Declare input registers
+pSrc RN 0
+srcStep RN 1
+pDst RN 2
+dstStep RN 3
+
+;// Declare inner loop registers
+ValA RN 5
+ValA0 RN 4
+ValA1 RN 5
+ValAF0 RN 4
+ValAF1 RN 5
+
+ValB RN 11
+
+ValC RN 5
+ValC0 RN 4
+ValC1 RN 5
+ValCD0 RN 12
+ValCD1 RN 14
+ValCF0 RN 4
+ValCF1 RN 5
+
+ValD RN 10
+
+ValE RN 7
+ValE0 RN 6
+ValE1 RN 7
+ValEB0 RN 10
+ValEB1 RN 11
+ValED0 RN 6
+ValED1 RN 7
+
+ValF RN 10
+
+ValG RN 14
+ValG0 RN 12
+ValG1 RN 14
+ValGB0 RN 12
+ValGB1 RN 14
+
+Acc0 RN 4
+Acc1 RN 5
+Acc2 RN 6
+Acc3 RN 7
+
+Temp RN 7
+Step RN 6
+
+pInterBuf RN 8
+Counter RN 8
+r0x00ff00ff RN 9 ;// [0 255 0 255] where 255 is offset
+r0x0001fc00 RN 10 ;// [0 (16*255 - 16) 0 (16*255 - 16)]
+
+
+;// Declare inner loop registers
+ValCA RN 8
+ValDB RN 9
+ValGE RN 10
+ValHF RN 11
+r0x00140001 RN 12
+r0x0014fffb RN 14
+
+r0x00000200 RN 12
+r0x000000ff RN 12
+
+ M_STRD pDst, dstStep, ppDstArgs
+ MOV pDst, pInterBuf
+ MOV dstStep, #24
+
+ ;// Set up counter of format, [0] [0] [1 (height)] [8 (width)]
+ MOV Counter, #1
+ MOV Temp, #8
+ ADD Counter, Temp, Counter, LSL #8 ;// [0 0 H W]
+
+ LDR r0x00ff00ff, =0x00ff00ff ;// [0 255 0 255] 255 is offset to avoid negative results
+WidthLoop
+ M_STR pSrc, ppSrc
+ M_STR pDst, ppDst
+HeightLoop
+TwoRowsLoop
+ M_LDR ValC, [pSrc], srcStep ;// Load [c3 c2 c1 c0]
+ M_LDR ValD, [pSrc], srcStep ;// Load [d3 d2 d1 d0]
+ M_LDR ValE, [pSrc], srcStep ;// Load [e3 e2 e1 e0]
+ SUB pSrc, pSrc, srcStep, LSL #2
+ UXTAB16 ValC0, r0x00ff00ff, ValC ;// [0 c2 0 c0] + [0 255 0 255]
+ UXTAB16 ValC1, r0x00ff00ff, ValC, ROR #8 ;// [0 c3 0 c1] + [0 255 0 255]
+ LDR ValB, [pSrc] ;// Load [b3 b2 b1 b0]
+ UXTAB16 ValE0, r0x00ff00ff, ValE ;// [0 e2 0 e0] + [0 255 0 255]
+ UXTAB16 ValE1, r0x00ff00ff, ValE, ROR #8 ;// [0 e3 0 e1] + [0 255 0 255]
+ UXTAB16 ValCD0, ValC0, ValD ;// [0 c2 0 c0] + [0 255 0 255] + [0 d2 0 d0]
+ UXTAB16 ValCD1, ValC1, ValD, ROR #8 ;// [0 c3 0 c1] + [0 255 0 255] + [0 d3 0 d1]
+ UXTAB16 ValEB0, ValE0, ValB ;// [0 e2 0 e0] + [0 255 0 255] + [0 b2 0 b0]
+ RSB ValCD0, ValEB0, ValCD0, LSL #2 ;// 4*(Off+C+D) - (Off+B+E)
+
+ LDR ValD, [pSrc, srcStep, LSL #1] ;// Load [d3 d2 d1 d0]
+ UXTAB16 ValEB1, ValE1, ValB, ROR #8 ;// [0 e3 0 e1] + [0 255 0 255] + [0 b3 0 b1]
+ RSB ValCD1, ValEB1, ValCD1, LSL #2
+
+ UXTAB16 ValED0, ValE0, ValD ;// [0 e2 0 e0] + [0 255 0 255] + [0 d2 0 d0]
+ UXTAB16 ValED1, ValE1, ValD, ROR #8 ;// [0 e3 0 e1] + [0 255 0 255] + [0 d3 0 d1]
+ LDR ValF, [pSrc, srcStep, LSL #2] ;// Load [f3 f2 f1 f0]
+ M_LDR ValB, [pSrc], srcStep ;// Load [b3 b2 b1 b0]
+ ADD ValCD0, ValCD0, ValCD0, LSL #2 ;// 5 * [4*(Off+C+D) - (Off+B+E)]
+ ADD ValCD1, ValCD1, ValCD1, LSL #2
+ UXTAB16 ValCF1, ValC1, ValF, ROR #8 ;// [0 c3 0 c1] + [0 255 0 255] + [0 f3 0 f1]
+ UXTAB16 ValCF0, ValC0, ValF ;// [0 c2 0 c0] + [0 255 0 255] + [0 f2 0 f0]
+ RSB ValED1, ValCF1, ValED1, LSL #2
+
+ SUB ValA, pSrc, srcStep, LSL #1
+ LDR ValA, [ValA] ;// Load [a3 a2 a1 a0]
+ RSB ValED0, ValCF0, ValED0, LSL #2 ;// 4*(Off+E+D) - (Off+C+F)
+ ADD ValED1, ValED1, ValED1, LSL #2
+ ADD ValED0, ValED0, ValED0, LSL #2 ;// 5 * [4*(Off+E+D) - (Off+C+F)]
+ UXTAB16 ValA0, r0x00ff00ff, ValA ;// [0 a2 0 a0] + [0 255 0 255]
+ UXTAB16 ValA1, r0x00ff00ff, ValA, ROR #8 ;// [0 a3 0 a1] + [0 255 0 255]
+ UXTAB16 ValAF0, ValA0, ValF ;// [0 a2 0 a0] + [0 255 0 255] + [0 f2 0 f0]
+ UXTAB16 ValAF1, ValA1, ValF, ROR #8 ;// [0 a3 0 a1] + [0 255 0 255] + [0 f3 0 f1]
+ ADD Acc1, ValCD1, ValAF1
+
+ LDR ValG, [pSrc, srcStep, LSL #2] ;// Load [g3 g2 g1 g0]
+ ADD Acc0, ValCD0, ValAF0 ;// Acc0 = 16*Off + (A+F) + 20*(C+D) - 5*(B+E)
+ STR Acc1, [pDst, #4] ;// Store result & adjust pointer
+ M_STR Acc0, [pDst], dstStep ;// Store result & adjust pointer
+ UXTAB16 ValG0, r0x00ff00ff, ValG ;// [0 g2 0 g0] + [0 255 0 255]
+ UXTAB16 ValG1, r0x00ff00ff, ValG, ROR #8 ;// [0 g3 0 g1] + [0 255 0 255]
+ UXTAB16 ValGB0, ValG0, ValB ;// [0 g2 0 g0] + [0 255 0 255] + [0 b2 0 b0]
+ UXTAB16 ValGB1, ValG1, ValB, ROR #8 ;// [0 g3 0 g1] + [0 255 0 255] + [0 b3 0 b1]
+ ADD Acc2, ValED0, ValGB0 ;// Acc2 = 16*Off + (B+G) + 20*(D+E) - 5*(C+F)
+ ADD Acc3, ValED1, ValGB1
+
+ STR Acc3, [pDst, #4] ;// Store result & adjust pointer
+ M_STR Acc2, [pDst], dstStep ;// Store result & adjust pointer
+
+ SUBS Counter, Counter, #1 << 8 ;// Loop till height is 10
+ ADD pSrc, pSrc, srcStep, LSL #1
+ BPL HeightLoop
+
+ M_LDR pSrc, ppSrc
+ M_LDR pDst, ppDst
+ ADDS Counter, Counter, #(1 << 8)-4 ;// Loop till width is 12
+ ADD pSrc, pSrc, #4
+ ADD pDst, pDst, #8
+ ADD Counter, Counter, #1<<8
+ BPL WidthLoop
+
+ ;//
+ ;// Horizontal interpolation using multiplication
+ ;//
+
+ SUB pSrc, pDst, #24
+ MOV srcStep, #24
+ M_LDRD pDst, dstStep, ppDstArgs
+
+ MOV Counter, #4
+ LDR r0x0014fffb, =0x0014fffb
+ LDR r0x00140001, =0x00140001
+
+HeightLoop1
+ M_STR Counter, pCounter
+
+
+ LDR ValCA, [pSrc], #4 ;// Load [0 c 0 a]
+ LDR ValDB, [pSrc], #4 ;// Load [0 d 0 b]
+ LDR ValGE, [pSrc], #4 ;// Load [0 g 0 e]
+ LDR ValHF, [pSrc], #4 ;// Load [0 h 0 f]
+
+ ;// Acc0 = smuad ([0 20 0 1], add([0 c 0 a] + [0 d 0 f])) - (5 * (b + e))
+ ;// Acc1 = smuad ([0 20 0 1], add([0 e 0 g] + [0 d 0 b])) - (5 * (c + f))
+ ;// Acc2 = smuad ([0 1 0 20], add([0 c 0 e] + [0 h 0 f])) - (5 * (d + g))
+ ;// Acc3 = smuad ([0 20 0 1], add([0 d 0 f] + [0 i 0 g])) - (5 * (e + h))
+ SMUAD Acc0, ValCA, r0x00140001 ;// Acc0 = [0 c 0 a] * [0 20 0 1]
+ SMUAD Acc1, ValDB, r0x00140001 ;// Acc1 = [0 c 0 a] * [0 20 0 1]
+ SMUADX Acc2, ValGE, r0x0014fffb ;// Acc2 = [0 g 0 e] * [0 20 0 -5]
+ SMUAD Acc3, ValGE, r0x0014fffb ;// Acc3 = [0 g 0 e] * [0 20 0 -5]
+
+ SMLAD Acc0, ValDB, r0x0014fffb, Acc0 ;// Acc0 += [0 d 0 b] * [0 20 0 -5]
+ SMLADX Acc1, ValGE, r0x00140001, Acc1 ;// Acc1 += [0 g 0 e] * [0 20 0 1]
+ SMLADX Acc2, ValHF, r0x00140001, Acc2 ;// Acc2 += [0 h 0 f] * [0 20 0 1]
+ SMLADX Acc3, ValHF, r0x0014fffb, Acc3 ;// Acc3 += [0 h 0 f] * [0 20 0 -5]
+
+ SMLABB Acc0, ValGE, r0x0014fffb, Acc0 ;// Acc0 += [0 g 0 e] * [0 0 0 -5]
+ SMLATB Acc1, ValCA, r0x0014fffb, Acc1 ;// Acc1 += [0 d 0 b] * [0 0 0 -5]
+ SMLATB Acc2, ValCA, r0x00140001, Acc2 ;// Acc2 += [0 c 0 a] * [0 0 0 1]
+ SMLATB Acc3, ValDB, r0x00140001, Acc3 ;// Acc3 += [0 c 0 a] * [0 0 0 1]
+
+ LDRH ValCA, [pSrc], #8 ;// 8 = srcStep - 16
+ SMLABB Acc0, ValHF, r0x00140001, Acc0 ;// Acc0 += [0 h 0 f] * [0 0 0 1]
+ SMLABB Acc1, ValHF, r0x0014fffb, Acc1 ;// Acc1 += [0 h 0 f] * [0 0 0 -5]
+ SMLATB Acc2, ValDB, r0x0014fffb, Acc2 ;// Acc2 += [0 d 0 b] * [0 0 0 -5]
+ SMLABB Acc3, ValCA, r0x00140001, Acc3 ;// Acc3 += [0 d 0 b] * [0 0 0 1]
+
+ LDR r0x0001fc00, =0x0001fc00 ;// (0xff * 16 * 32) - 512
+ SUB Acc0, Acc0, r0x0001fc00
+ SUB Acc1, Acc1, r0x0001fc00
+ SUB Acc2, Acc2, r0x0001fc00
+ SUB Acc3, Acc3, r0x0001fc00
+
+ USAT Acc0, #18, Acc0
+ USAT Acc1, #18, Acc1
+ USAT Acc2, #18, Acc2
+ USAT Acc3, #18, Acc3
+
+ MOV Acc0, Acc0, LSR #10
+ MOV Acc1, Acc1, LSR #10
+ MOV Acc2, Acc2, LSR #10
+ MOV Acc3, Acc3, LSR #10
+
+ M_LDR Counter, pCounter
+ ORR Acc0, Acc0, Acc1, LSL #8
+ ORR Acc2, Acc2, Acc3, LSL #8
+ SUBS Counter, Counter, #1
+ ORR Acc0, Acc0, Acc2, LSL #16
+ M_STR Acc0, [pDst], dstStep
+ BGT HeightLoop1
+End
+ SUB pDst, pDst, dstStep, LSL #2
+ SUB pSrc, pSrc, srcStep, LSL #2
+
+ M_END
+
+ ENDIF
+
+ END
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe_s.s
new file mode 100644
index 0000000..6690ced
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe_s.s
@@ -0,0 +1,239 @@
+;//
+;//
+;// File Name: armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 9641
+;// Date: Thursday, February 7, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS ARM1136JS
+
+ EXPORT armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe
+
+DEBUG_ON SETL {FALSE}
+
+
+ IF ARM1136JS
+
+;// Function:
+;// armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe
+;//
+;// Implements horizontal interpolation for a block of size 4x4. Input and output should
+;// be aligned.
+;//
+;// Registers used as input for this function
+;// r0,r1,r2,r3 where r0,r2 input pointer and r1,r3 corresponding step size
+;//
+;// Registers preserved for top level function
+;// r0,r1,r2,r3,r4,r5,r6,r14
+;//
+;// Registers modified by the function
+;// r7,r8,r9,r10,r11,r12
+;//
+;// Output registers
+;// None. Function will preserve r0-r3
+
+
+;// Declare input registers
+pSrc RN 0
+srcStep RN 1
+pDst RN 2
+dstStep RN 3
+
+;// Declare inner loop registers
+Acc0 RN 4
+Acc1 RN 5
+Acc2 RN 6
+Acc3 RN 7
+
+ValA RN 4
+ValB RN 5
+ValC RN 6
+ValD RN 7
+ValE RN 8
+ValF RN 9
+ValG RN 12
+ValH RN 14
+ValI RN 1
+
+Temp1 RN 3
+Temp2 RN 1
+Temp3 RN 12
+Temp4 RN 7
+Temp5 RN 5
+r0x0fe00fe0 RN 3 ;// [0 (16*255 - 16) 0 (16*255 - 16)]
+r0x00ff00ff RN 10 ;// [0 255 0 255] where 255 is offset
+Counter RN 11
+
+Height RN 3
+
+ M_ALLOC4 pDstStep, 4
+ M_ALLOC4 pSrcStep, 4
+
+ ;// Function header
+ M_START armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe, r6
+
+ MOV Counter, #2
+ M_STR dstStep, pDstStep
+ M_STR srcStep, pSrcStep
+ LDR r0x00ff00ff, =0x00ff00ff ;// [0 255 0 255] 255 is offset to avoid negative results
+
+NextTwoRowsLoop
+ LDR ValD, [pSrc, srcStep] ;// Load row 1 [d1 c1 b1 a1]
+ LDR ValA, [pSrc], #4 ;// Load row 0 [d0 c0 b0 a0]
+ LDR ValH, [pSrc, srcStep] ;// Load [h1 g1 f1 e1]
+ LDR ValE, [pSrc], #4 ;// Load [h0 g0 f0 e0]
+ LDRB Temp2, [pSrc, srcStep] ;// Load row 1 [l1 k1 j1 i1]
+ LDRB Temp1, [pSrc], #-8 ;// Load row 0 [l0 k0 j0 i0]
+
+ PKHBT ValB, ValA, ValD, LSL #16 ;// [b1 a1 b0 a0]
+ PKHTB ValD, ValD, ValA, ASR #16 ;// [d1 c1 d0 c0]
+ UXTAB16 ValA, r0x00ff00ff, ValB ;// [00 a1 00 a0] + [0 255 0 255]
+ UXTAB16 ValC, r0x00ff00ff, ValD ;// [00 c1 00 c0] + [0 255 0 255]
+ PKHBT ValI, Temp1, Temp2, LSL #16 ;// [00 i1 00 i0]
+ PKHBT ValF, ValE, ValH, LSL #16 ;// [f1 e1 f0 e0]
+ PKHTB ValH, ValH, ValE, ASR #16 ;// [h1 g1 h0 g0]
+ UXTAB16 ValE, r0x00ff00ff, ValF ;// [00 e1 00 e0] + [0 255 0 255]
+
+ ;// Calculate Acc0
+ ;// Acc0 = a - 5*b + 20*c + 20*d - 5*e + f
+ UXTAB16 Temp1, ValC, ValD, ROR #8
+ UXTAB16 Temp3, ValE, ValB, ROR #8
+ RSB Temp1, Temp3, Temp1, LSL #2
+ UXTAB16 Acc0, ValA, ValF, ROR #8
+ ADD Temp1, Temp1, Temp1, LSL #2
+ ADD Acc0, Acc0, Temp1
+
+ ;// Calculate Acc1
+ ;// Acc1 = b - 5*c + 20*d + 20*e - 5*f + g
+ UXTAB16 Temp1, ValE, ValD, ROR #8
+ UXTAB16 Temp3, ValC, ValF, ROR #8
+ RSB Temp1, Temp3, Temp1, LSL #2
+ UXTAB16 ValG, r0x00ff00ff, ValH ;// [00 g1 00 g0] + [0 255 0 255]
+ ADD Temp1, Temp1, Temp1, LSL #2
+ UXTAB16 Acc1, ValG, ValB, ROR #8
+ ADD Acc1, Acc1, Temp1
+
+ LDR r0x0fe00fe0, =0x0fe00fe0 ;// 0x0fe00fe0 = (16 * Offset) - 16 where Offset is 255
+ UXTAB16 Acc2, ValC, ValH, ROR #8
+ ADD ValI, r0x00ff00ff, ValI ;// [00 i1 00 i0] + [0 255 0 255]
+ UQSUB16 Acc0, Acc0, r0x0fe00fe0
+ UQSUB16 Acc1, Acc1, r0x0fe00fe0
+ USAT16 Acc0, #13, Acc0
+ USAT16 Acc1, #13, Acc1
+
+ ;// Calculate Acc2
+ ;// Acc2 = c - 5*d + 20*e + 20*f - 5*g + h
+ UXTAB16 Temp1, ValG, ValD, ROR #8
+ UXTAB16 Acc3, ValI, ValD, ROR #8
+ UXTAB16 Temp2, ValE, ValF, ROR #8
+ AND Acc1, r0x00ff00ff, Acc1, LSR #5
+ AND Acc0, r0x00ff00ff, Acc0, LSR #5
+ ORR Acc0, Acc0, Acc1, LSL #8
+ RSB Temp5, Temp1, Temp2, LSL #2
+ UXTAB16 Temp2, ValG, ValF, ROR #8
+ ADD Temp5, Temp5, Temp5, LSL #2
+ ADD Acc2, Acc2, Temp5
+
+ ;// Calculate Acc3
+ ;// Acc3 = d - 5*e + 20*f + 20*g - 5*h + i
+ UXTAB16 Temp5, ValE, ValH, ROR #8
+ RSB Temp5, Temp5, Temp2, LSL #2
+ LDR r0x0fe00fe0, =0x0fe00fe0
+ ADD Temp5, Temp5, Temp5, LSL #2
+ ADD Acc3, Acc3, Temp5
+
+ UQSUB16 Acc3, Acc3, r0x0fe00fe0
+ UQSUB16 Acc2, Acc2, r0x0fe00fe0
+ USAT16 Acc3, #13, Acc3
+ USAT16 Acc2, #13, Acc2
+
+ M_LDR dstStep, pDstStep
+ AND Acc3, r0x00ff00ff, Acc3, LSR #5
+ AND Acc2, r0x00ff00ff, Acc2, LSR #5
+ ORR Acc2, Acc2, Acc3, LSL #8
+
+ SUBS Counter, Counter, #1
+ M_LDR srcStep, pSrcStep
+ PKHBT Acc1, Acc0, Acc2, LSL #16
+ M_STR Acc1, [pDst], dstStep ;// Store result1
+ PKHTB Acc2, Acc2, Acc0, ASR #16
+ M_STR Acc2, [pDst], dstStep ;// Store result2
+ ADD pSrc, pSrc, srcStep, LSL #1
+
+ BGT NextTwoRowsLoop
+End
+ SUB pDst, pDst, dstStep, LSL #2
+ SUB pSrc, pSrc, srcStep, LSL #2
+
+ M_END
+
+ ENDIF
+
+ END
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe_s.s
new file mode 100644
index 0000000..007cd0d
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe_s.s
@@ -0,0 +1,185 @@
+;//
+;//
+;// File Name: armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 9641
+;// Date: Thursday, February 7, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS ARM1136JS
+
+ EXPORT armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe
+
+
+
+ IF ARM1136JS
+
+ ;// Function header
+
+ ;// Function:
+ ;// armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe
+ ;//
+ ;// Implements vertical interpolation for a block of size 4x4. Input and output should
+ ;// be aligned.
+ ;//
+ ;// Registers used as input for this function
+ ;// r0,r1,r2,r3 where r0,r2 input pointer and r1,r3 corresponding step size
+ ;//
+ ;// Registers preserved for top level function
+ ;// r0,r1,r2,r3,r4,r5,r6,r14
+ ;//
+ ;// Registers modified by the function
+ ;// r7,r8,r9,r10,r11,r12
+ ;//
+ ;// Output registers
+ ;// None. Function will preserve r0-r3
+ M_START armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe, r6
+
+;// Declare input registers
+pSrc RN 0
+srcStep RN 1
+pDst RN 2
+dstStep RN 3
+
+;// Declare inner loop registers
+ValA RN 5
+ValA0 RN 4
+ValA1 RN 5
+ValAF0 RN 4
+ValAF1 RN 5
+
+ValB RN 11
+
+ValC RN 5
+ValC0 RN 4
+ValC1 RN 5
+ValCD0 RN 12
+ValCD1 RN 14
+ValCF0 RN 4
+ValCF1 RN 5
+
+ValD RN 10
+
+ValE RN 7
+ValE0 RN 6
+ValE1 RN 7
+ValEB0 RN 10
+ValEB1 RN 11
+ValED0 RN 6
+ValED1 RN 7
+
+ValF RN 10
+
+ValG RN 14
+ValG0 RN 12
+ValG1 RN 14
+ValGB0 RN 12
+ValGB1 RN 14
+
+Acc0 RN 4
+Acc1 RN 5
+Acc2 RN 6
+Acc3 RN 7
+
+Temp RN 7
+Height RN 3
+Step RN 6
+
+Counter RN 8
+r0x00ff00ff RN 9 ;// [0 255 0 255] where 255 is offset
+r0x0fe00fe0 RN 10 ;// [0 (16*255 - 16) 0 (16*255 - 16)]
+
+
+ LDR r0x00ff00ff, =0x00ff00ff ;// [0 255 0 255] 255 is offset to avoid negative results
+ MOV Counter, #2
+
+TwoRowsLoop
+ M_LDR ValC, [pSrc], srcStep ;// Load [c3 c2 c1 c0]
+ M_LDR ValD, [pSrc], srcStep ;// Load [d3 d2 d1 d0]
+ M_LDR ValE, [pSrc], srcStep ;// Load [e3 e2 e1 e0]
+ SUB pSrc, pSrc, srcStep, LSL #2
+ LDR ValB, [pSrc] ;// Load [b3 b2 b1 b0]
+ UXTAB16 ValC0, r0x00ff00ff, ValC ;// [0 c2 0 c0] + [0 255 0 255]
+ UXTAB16 ValC1, r0x00ff00ff, ValC, ROR #8 ;// [0 c3 0 c1] + [0 255 0 255]
+
+ UXTAB16 ValE0, r0x00ff00ff, ValE ;// [0 e2 0 e0] + [0 255 0 255]
+ UXTAB16 ValE1, r0x00ff00ff, ValE, ROR #8 ;// [0 e3 0 e1] + [0 255 0 255]
+ UXTAB16 ValCD0, ValC0, ValD ;// [0 c2 0 c0] + [0 255 0 255] + [0 d2 0 d0]
+ UXTAB16 ValCD1, ValC1, ValD, ROR #8 ;// [0 c3 0 c1] + [0 255 0 255] + [0 d3 0 d1]
+ UXTAB16 ValEB0, ValE0, ValB ;// [0 e2 0 e0] + [0 255 0 255] + [0 b2 0 b0]
+ RSB ValCD0, ValEB0, ValCD0, LSL #2 ;// 4*(Off+C+D) - (Off+B+E)
+
+ LDR ValD, [pSrc, srcStep, LSL #1] ;// Load [d3 d2 d1 d0]
+ UXTAB16 ValEB1, ValE1, ValB, ROR #8 ;// [0 e3 0 e1] + [0 255 0 255] + [0 b3 0 b1]
+ RSB ValCD1, ValEB1, ValCD1, LSL #2
+ ;// One cycle stall
+ UXTAB16 ValED0, ValE0, ValD ;// [0 e2 0 e0] + [0 255 0 255] + [0 d2 0 d0]
+ UXTAB16 ValED1, ValE1, ValD, ROR #8 ;// [0 e3 0 e1] + [0 255 0 255] + [0 d3 0 d1]
+
+ LDR ValF, [pSrc, srcStep, LSL #2] ;// Load [f3 f2 f1 f0]
+ M_LDR ValB, [pSrc], srcStep ;// Load [b3 b2 b1 b0]
+ ADD ValCD0, ValCD0, ValCD0, LSL #2 ;// 5 * [4*(Off+C+D) - (Off+B+E)]
+ ADD ValCD1, ValCD1, ValCD1, LSL #2
+ UXTAB16 ValCF1, ValC1, ValF, ROR #8 ;// [0 c3 0 c1] + [0 255 0 255] + [0 f3 0 f1]
+ UXTAB16 ValCF0, ValC0, ValF ;// [0 c2 0 c0] + [0 255 0 255] + [0 f2 0 f0]
+ RSB ValED1, ValCF1, ValED1, LSL #2
+
+ SUB ValA, pSrc, srcStep, LSL #1
+ LDR ValA, [ValA] ;// Load [a3 a2 a1 a0]
+ RSB ValED0, ValCF0, ValED0, LSL #2 ;// 4*(Off+E+D) - (Off+C+F)
+ ADD ValED1, ValED1, ValED1, LSL #2
+ ADD ValED0, ValED0, ValED0, LSL #2 ;// 5 * [4*(Off+E+D) - (Off+C+F)]
+ UXTAB16 ValA0, r0x00ff00ff, ValA ;// [0 a2 0 a0] + [0 255 0 255]
+ UXTAB16 ValA1, r0x00ff00ff, ValA, ROR #8 ;// [0 a3 0 a1] + [0 255 0 255]
+ UXTAB16 ValAF0, ValA0, ValF ;// [0 a2 0 a0] + [0 255 0 255] + [0 f2 0 f0]
+ UXTAB16 ValAF1, ValA1, ValF, ROR #8 ;// [0 a3 0 a1] + [0 255 0 255] + [0 f3 0 f1]
+
+ LDR r0x0fe00fe0, =0x0fe00fe0 ;// [0 255 0 255] 255 is offset to avoid negative results
+ ADD Acc1, ValCD1, ValAF1
+
+ LDR ValG, [pSrc, srcStep, LSL #2] ;// Load [g3 g2 g1 g0]
+ ADD Acc0, ValCD0, ValAF0 ;// Acc0 = 16*Off + (A+F) + 20*(C+D) - 5*(B+E)
+ UQSUB16 Acc1, Acc1, r0x0fe00fe0 ;// Acc1 -= (16*Off - 16)
+ UQSUB16 Acc0, Acc0, r0x0fe00fe0
+ UXTAB16 ValG0, r0x00ff00ff, ValG ;// [0 g2 0 g0] + [0 255 0 255]
+ UXTAB16 ValG1, r0x00ff00ff, ValG, ROR #8 ;// [0 g3 0 g1] + [0 255 0 255]
+ UXTAB16 ValGB0, ValG0, ValB ;// [0 g2 0 g0] + [0 255 0 255] + [0 b2 0 b0]
+ UXTAB16 ValGB1, ValG1, ValB, ROR #8 ;// [0 g3 0 g1] + [0 255 0 255] + [0 b3 0 b1]
+ ADD Acc2, ValED0, ValGB0 ;// Acc2 = 16*Off + (B+G) + 20*(D+E) - 5*(C+F)
+ ADD Acc3, ValED1, ValGB1
+ UQSUB16 Acc3, Acc3, r0x0fe00fe0 ;// Acc3 -= (16*Off - 16)
+ UQSUB16 Acc2, Acc2, r0x0fe00fe0
+ USAT16 Acc1, #13, Acc1 ;// Saturate to 8+5 = 13 bits
+ USAT16 Acc0, #13, Acc0
+ USAT16 Acc3, #13, Acc3
+ USAT16 Acc2, #13, Acc2
+ AND Acc1, r0x00ff00ff, Acc1, LSR #5 ;// [0 a3 0 a1]
+ AND Acc0, r0x00ff00ff, Acc0, LSR #5 ;// [0 a2 0 a0]
+ ORR Acc0, Acc0, Acc1, LSL #8 ;// [a3 a2 a1 a0]
+ AND Acc3, r0x00ff00ff, Acc3, LSR #5 ;// [0 b3 0 b1]
+ AND Acc2, r0x00ff00ff, Acc2, LSR #5 ;// [0 b2 0 b0]
+
+ M_STR Acc0, [pDst], dstStep ;// Store result & adjust pointer
+ ORR Acc2, Acc2, Acc3, LSL #8 ;// [b3 b2 b1 b0]
+ M_STR Acc2, [pDst], dstStep ;// Store result & adjust pointer
+ ADD pSrc, pSrc, srcStep, LSL #1
+
+ SUBS Counter, Counter, #1
+ BGT TwoRowsLoop
+End
+ SUB pDst, pDst, dstStep, LSL #2
+ SUB pSrc, pSrc, srcStep, LSL #2
+
+ M_END
+
+ ENDIF
+
+ END
+
\ No newline at end of file
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_Interpolate_Chroma_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_Interpolate_Chroma_s.s
new file mode 100644
index 0000000..b1ad17c
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_Interpolate_Chroma_s.s
@@ -0,0 +1,273 @@
+;//
+;//
+;// File Name: armVCM4P10_Interpolate_Chroma_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 9641
+;// Date: Thursday, February 7, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS ARM1136JS
+
+ IF ARM1136JS
+
+;// input registers
+
+pSrc RN 0
+iSrcStep RN 1
+pDst RN 2
+iDstStep RN 3
+iWidth RN 4
+iHeight RN 5
+dx RN 6
+dy RN 7
+
+
+;// local variable registers
+temp RN 11
+r0x20 RN 12
+tmp0x20 RN 14
+return RN 0
+dxPlusdy RN 10
+EightMinusdx RN 8
+EightMinusdy RN 9
+dxEightMinusdx RN 8
+BACoeff RN 6
+DCCoeff RN 7
+
+iDstStepx2MinusWidth RN 8
+iSrcStepx2MinusWidth RN 9
+iSrcStep1 RN 10
+
+pSrc1 RN 1
+pSrc2 RN 8
+pDst1 RN 8
+pDst2 RN 12
+
+pix00 RN 8
+pix01 RN 9
+pix10 RN 10
+pix11 RN 11
+
+Out0100 RN 8
+Out1110 RN 10
+
+x00 RN 8
+x01 RN 10
+x02 RN 12
+x10 RN 9
+x11 RN 11
+x12 RN 14
+x20 RN 10
+x21 RN 12
+x22 RN 14
+
+x01x00 RN 8
+x02x01 RN 10
+x11x10 RN 9
+x12x11 RN 11
+x21x20 RN 10
+x22x21 RN 12
+
+OutRow00 RN 12
+OutRow01 RN 14
+OutRow10 RN 10
+OutRow11 RN 12
+
+OutRow0100 RN 12
+OutRow1110 RN 12
+
+;//-----------------------------------------------------------------------------------------------
+;// armVCM4P10_Interpolate_Chroma_asm starts
+;//-----------------------------------------------------------------------------------------------
+
+ ;// Write function header
+ M_START armVCM4P10_Interpolate_Chroma, r11
+
+ ;// Define stack arguments
+ M_ARG Width, 4
+ M_ARG Height, 4
+ M_ARG Dx, 4
+ M_ARG Dy, 4
+
+ ;// Load argument from the stack
+ ;// M_STALL ARM1136JS=4
+
+ M_LDR iWidth, Width
+ M_LDR iHeight, Height
+ M_LDR dx, Dx
+ M_LDR dy, Dy
+
+ ;// EightMinusdx = 8 - dx
+ ;// EightMinusdy = 8 - dy
+
+ ;// ACoeff = EightMinusdx * EightMinusdy
+ ;// BCoeff = dx * EightMinusdy
+ ;// CCoeff = EightMinusdx * dy
+ ;// DCoeff = dx * dy
+
+ ADD pSrc1, pSrc, iSrcStep
+ SUB temp, iWidth, #1
+ RSB EightMinusdx, dx, #8
+ RSB EightMinusdy, dy, #8
+ CMN dx,dy
+ ADD dxEightMinusdx, EightMinusdx, dx, LSL #16
+ ORR iWidth, iWidth, temp, LSL #16
+
+ ;// Packed Coeffs.
+
+ MUL BACoeff, dxEightMinusdx, EightMinusdy
+ MUL DCCoeff, dxEightMinusdx, dy
+
+
+ ;// Checking either of dx and dy being non-zero
+
+ BEQ MVIsZero
+
+;// Pixel layout:
+;//
+;// x00 x01 x02
+;// x10 x11 x12
+;// x20 x21 x22
+
+;// If fractionl mv is not (0, 0)
+
+OuterLoopMVIsNotZero
+
+InnerLoopMVIsNotZero
+
+ LDRB x00, [pSrc, #+0]
+ LDRB x10, [pSrc1, #+0]
+ LDRB x01, [pSrc, #+1]
+ LDRB x11, [pSrc1, #+1]
+ LDRB x02, [pSrc, #+2]!
+ LDRB x12, [pSrc1, #+2]!
+
+ ORR x01x00, x00, x01, LSL #16
+ ;// M_STALL ARM1136JS=1
+ ORR x02x01, x01, x02, LSL #16
+ MOV r0x20, #32
+ ORR x11x10, x10, x11, LSL #16
+ ORR x12x11, x11, x12, LSL #16
+
+ SMLAD x01x00, x01x00, BACoeff, r0x20
+ SMLAD x02x01, x02x01, BACoeff, r0x20
+
+ ;// iWidth packed with MSB (top 16 bits)
+ ;// as inner loop counter value i.e
+ ;// (iWidth -1) and LSB (lower 16 bits)
+ ;// as original width
+
+ SUBS iWidth, iWidth, #1<<17
+
+ SMLAD OutRow00, x11x10, DCCoeff, x01x00
+ SMLAD OutRow01, x12x11, DCCoeff, x02x01
+
+ RSB pSrc2, pSrc, pSrc1, LSL #1
+
+ MOV OutRow00, OutRow00, LSR #6
+ MOV OutRow01, OutRow01, LSR #6
+
+ LDRB x20,[pSrc2, #-2]
+
+ ORR OutRow0100, OutRow00, OutRow01, LSL #8
+ STRH OutRow0100, [pDst], #2
+
+ LDRB x21,[pSrc2, #-1]
+ LDRB x22,[pSrc2, #+0]
+
+ ADD pDst1, pDst, iDstStep
+
+ ;// M_STALL ARM1136JS=1
+
+ ORR x21x20, x20, x21, LSL #16
+ ORR x22x21, x21, x22, LSL #16
+
+ MOV tmp0x20, #32
+
+ ;// Reusing the packed data x11x10 and x12x11
+
+ SMLAD x11x10, x11x10, BACoeff, tmp0x20
+ SMLAD x12x11, x12x11, BACoeff, tmp0x20
+ SMLAD OutRow10, x21x20, DCCoeff, x11x10
+ SMLAD OutRow11, x22x21, DCCoeff, x12x11
+
+ MOV OutRow10, OutRow10, LSR #6
+ MOV OutRow11, OutRow11, LSR #6
+
+ ;// M_STALL ARM1136JS=1
+
+ ORR OutRow1110, OutRow10, OutRow11, LSL #8
+
+ STRH OutRow1110, [pDst1, #-2]
+
+ BGT InnerLoopMVIsNotZero
+
+ SUBS iHeight, iHeight, #2
+ ADD iWidth, iWidth, #1<<16
+ RSB iDstStepx2MinusWidth, iWidth, iDstStep, LSL #1
+ SUB iSrcStep1, pSrc1, pSrc
+ SUB temp, iWidth, #1
+ RSB iSrcStepx2MinusWidth, iWidth, iSrcStep1, LSL #1
+ ADD pDst, pDst, iDstStepx2MinusWidth
+ ADD pSrc1, pSrc1, iSrcStepx2MinusWidth
+ ADD pSrc, pSrc, iSrcStepx2MinusWidth
+ ORR iWidth, iWidth, temp, LSL #16
+ BGT OuterLoopMVIsNotZero
+ MOV return, #OMX_Sts_NoErr
+ M_EXIT
+
+;// If fractionl mv is (0, 0)
+
+MVIsZero
+ ;// M_STALL ARM1136JS=4
+OuterLoopMVIsZero
+
+InnerLoopMVIsZero
+
+ LDRB pix00, [pSrc], #+1
+ LDRB pix01, [pSrc], #+1
+ LDRB pix10, [pSrc1], #+1
+ LDRB pix11, [pSrc1], #+1
+
+ ADD pDst2, pDst, iDstStep
+ SUBS iWidth, iWidth, #1<<17
+
+ ORR Out0100, pix00, pix01, LSL #8
+ ORR Out1110, pix10, pix11, LSL #8
+
+ STRH Out0100, [pDst], #2
+ STRH Out1110, [pDst2], #2
+
+ BGT InnerLoopMVIsZero
+
+ SUBS iHeight, iHeight, #2
+ ADD iWidth, iWidth, #1<<16
+ RSB iDstStepx2MinusWidth, iWidth, iDstStep, LSL #1
+ SUB iSrcStep1, pSrc1, pSrc
+ SUB temp, iWidth, #1
+ RSB iSrcStepx2MinusWidth, iWidth, iSrcStep1, LSL #1
+ ADD pDst, pDst, iDstStepx2MinusWidth
+ ADD pSrc1, pSrc1, iSrcStepx2MinusWidth
+ ADD pSrc, pSrc, iSrcStepx2MinusWidth
+ ORR iWidth, iWidth, temp, LSL #16
+ BGT OuterLoopMVIsZero
+ MOV return, #OMX_Sts_NoErr
+ M_END
+
+ ENDIF ;// ARM1136JS
+
+
+ END
+
+;//-----------------------------------------------------------------------------------------------
+;// armVCM4P10_Interpolate_Chroma_asm ends
+;//-----------------------------------------------------------------------------------------------
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_QuantTables_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_QuantTables_s.s
new file mode 100644
index 0000000..f962f70
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_QuantTables_s.s
@@ -0,0 +1,74 @@
+;//
+;//
+;// File Name: armVCM4P10_QuantTables_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 9641
+;// Date: Thursday, February 7, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;// Description:
+;// This file contains quantization tables
+;//
+;//
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+
+ EXPORT armVCM4P10_MFMatrixQPModTable
+ EXPORT armVCM4P10_QPDivIntraTable
+ EXPORT armVCM4P10_QPDivPlusOneTable
+
+;//--------------------------------------------------------------
+;// This table contains armVCM4P10_MFMatrix [iQP % 6][0] entires,
+;// for values of iQP from 0 to 51 (inclusive).
+;//--------------------------------------------------------------
+
+ M_TABLE armVCM4P10_MFMatrixQPModTable
+ DCW 13107, 11916, 10082, 9362, 8192, 7282
+ DCW 13107, 11916, 10082, 9362, 8192, 7282
+ DCW 13107, 11916, 10082, 9362, 8192, 7282
+ DCW 13107, 11916, 10082, 9362, 8192, 7282
+ DCW 13107, 11916, 10082, 9362, 8192, 7282
+ DCW 13107, 11916, 10082, 9362, 8192, 7282
+ DCW 13107, 11916, 10082, 9362, 8192, 7282
+ DCW 13107, 11916, 10082, 9362, 8192, 7282
+ DCW 13107, 11916, 10082, 9362, 8192, 7282
+
+;//---------------------------------------------------------------
+;// This table contains ARM_M4P10_Q_OFFSET + 1 + (iQP / 6) values,
+;// for values of iQP from 0 to 51 (inclusive).
+;//---------------------------------------------------------------
+
+ M_TABLE armVCM4P10_QPDivPlusOneTable
+ DCB 16, 16, 16, 16, 16, 16
+ DCB 17, 17, 17, 17, 17, 17
+ DCB 18, 18, 18, 18, 18, 18
+ DCB 19, 19, 19, 19, 19, 19
+ DCB 20, 20, 20, 20, 20, 20
+ DCB 21, 21, 21, 21, 21, 21
+ DCB 22, 22, 22, 22, 22, 22
+ DCB 23, 23, 23, 23, 23, 23
+ DCB 24, 24, 24, 24, 24, 24
+
+;//------------------------------------------------------------------
+;// This table contains (1 << QbitsPlusOne) / 3 Values (Intra case) ,
+;// for values of iQP from 0 to 51 (inclusive).
+;//------------------------------------------------------------------
+
+ M_TABLE armVCM4P10_QPDivIntraTable, 2
+ DCD 21845, 21845, 21845, 21845, 21845, 21845
+ DCD 43690, 43690, 43690, 43690, 43690, 43690
+ DCD 87381, 87381, 87381, 87381, 87381, 87381
+ DCD 174762, 174762, 174762, 174762, 174762, 174762
+ DCD 349525, 349525, 349525, 349525, 349525, 349525
+ DCD 699050, 699050, 699050, 699050, 699050, 699050
+ DCD 1398101, 1398101, 1398101, 1398101, 1398101, 1398101
+ DCD 2796202, 2796202, 2796202, 2796202, 2796202, 2796202
+ DCD 5592405, 5592405, 5592405, 5592405, 5592405, 5592405
+
+
+ END
+
\ No newline at end of file
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_TransformResidual4x4_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_TransformResidual4x4_s.s
new file mode 100644
index 0000000..241d188
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_TransformResidual4x4_s.s
@@ -0,0 +1,407 @@
+;//
+;//
+;// File Name: armVCM4P10_TransformResidual4x4_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 9641
+;// Date: Thursday, February 7, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+;// Description:
+;// Transform Residual 4x4 Coefficients
+;//
+;//
+
+
+;// Include standard headers
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS ARM1136JS
+
+;// Import symbols required from other files
+;// (For example tables)
+
+
+
+
+;// Set debugging level
+;//DEBUG_ON SETL {TRUE}
+
+
+
+;// Guarding implementation by the processor name
+
+ IF ARM1136JS
+
+;//Input Registers
+pDst RN 0
+pSrc RN 1
+
+;//Output Registers
+
+
+;//Local Scratch Registers
+
+;// Packed Input pixels
+in00 RN 2 ;// Src[0] & Src[1]
+in02 RN 3 ;// Src[2] & Src[3]
+in10 RN 4 ;// Src[4] & Src[5]
+in12 RN 5 ;// Src[6] & Src[7]
+in20 RN 6 ;// Src[8] & Src[9]
+in22 RN 7 ;// Src[10] & Src[11]
+in30 RN 8 ;// Src[12] & Src[13]
+in32 RN 9 ;// Src[14] & Src[15]
+
+;// Transpose for Row operations (Rows to cols)
+trRow00 RN 2
+trRow10 RN 10
+trRow02 RN 3
+trRow12 RN 5
+trRow20 RN 11
+trRow30 RN 12
+trRow32 RN 14
+trRow22 RN 7
+
+;// Intermediate calculations
+e0 RN 4
+e1 RN 6
+e2 RN 8
+e3 RN 9
+constZero RN 1
+
+;// Row operated pixels
+rowOp00 RN 2
+rowOp10 RN 10
+rowOp20 RN 11
+rowOp30 RN 12
+rowOp02 RN 3
+rowOp12 RN 5
+rowOp22 RN 7
+rowOp32 RN 14
+
+;// Transpose for colulmn operations
+trCol00 RN 2
+trCol02 RN 3
+trCol10 RN 4
+trCol12 RN 5
+trCol20 RN 6
+trCol22 RN 7
+trCol30 RN 8
+trCol32 RN 9
+
+;// Intermediate calculations
+g0 RN 10
+g1 RN 11
+g2 RN 12
+g3 RN 14
+
+;// Coloumn operated pixels
+colOp00 RN 2
+colOp02 RN 3
+colOp10 RN 4
+colOp12 RN 5
+colOp20 RN 6
+colOp22 RN 7
+colOp30 RN 8
+colOp32 RN 9
+
+
+temp1 RN 10 ;// Temporary scratch varaibles
+const1 RN 11
+const2 RN 12
+mask RN 14
+
+;// Output pixels
+out00 RN 2
+out02 RN 3
+out10 RN 4
+out12 RN 5
+out20 RN 6
+out22 RN 7
+out30 RN 8
+out32 RN 9
+
+
+
+ ;// Allocate stack memory required by the function
+
+
+ ;// Write function header
+ M_START armVCM4P10_TransformResidual4x4,r11
+
+ ;******************************************************************
+ ;// The strategy used in implementing the transform is as follows:*
+ ;// Load the 4x4 block into 8 registers *
+ ;// Transpose the 4x4 matrix *
+ ;// Perform the row operations (on columns) using SIMD *
+ ;// Transpose the 4x4 result matrix *
+ ;// Perform the coloumn operations *
+ ;// Store the 4x4 block at one go *
+ ;******************************************************************
+
+ ;// Load all the 4x4 pixels
+
+ LDMIA pSrc,{in00,in02,in10,in12,in20,in22,in30,in32}
+
+ MOV constZero,#0 ;// Used to right shift by 1
+ ;LDR constZero,=0x00000000
+
+ ;*****************************************************************
+ ;//
+ ;// Transpose the matrix inorder to perform row ops as coloumn ops
+ ;// Input: in[][] = original matrix
+ ;// Output: trRow[][]= transposed matrix
+ ;// Step1: Obtain the LL part of the transposed matrix
+ ;// Step2: Obtain the HL part
+ ;// step3: Obtain the LH part
+ ;// Step4: Obtain the HH part
+ ;//
+ ;*****************************************************************
+
+ ;// LL 2x2 transposed matrix
+ ;// d0 d1 - -
+ ;// d4 d5 - -
+ ;// - - - -
+ ;// - - - -
+
+ PKHTB trRow10,in10,in00,ASR #16 ;// [5 4] = [f5:f1]
+ PKHBT trRow00,in00,in10,LSL #16 ;// [1 0] = [f4:f0]
+
+ ;// HL 2x2 transposed matrix
+ ;// - - - -
+ ;// - - - -
+ ;// d8 d9 - -
+ ;// d12 d13 - -
+
+
+ PKHTB trRow30,in12,in02,ASR #16 ;// [13 12] = [7 3]
+ PKHBT trRow20,in02,in12,LSL #16 ;// [9 8] = [6 2]
+
+ ;// LH 2x2 transposed matrix
+ ;// - - d2 d3
+ ;// - - d6 d7
+ ;// - - - -
+ ;// - - - -
+
+ PKHBT trRow02,in20,in30,LSL #16 ;// [3 2] = [f12:f8]
+ PKHTB trRow12,in30,in20,ASR #16 ;// [7 6] = [f13:f9]
+
+
+
+
+ ;// HH 2x2 transposed matrix
+ ;// - - - -
+ ;// - - - -
+ ;// - - d10 d11
+ ;// - - d14 d15
+
+ PKHTB trRow32,in32,in22,ASR #16 ;// [15 14] = [15 11]
+ PKHBT trRow22,in22,in32,LSL #16 ;// [11 10] = [14 10]
+
+
+ ;****************************************
+ ;// Row Operations (Performed on columns)
+ ;****************************************
+
+
+ ;// SIMD operations on first two columns(two rows of the original matrix)
+
+
+ SADD16 e0, trRow00,trRow20 ;// e0 = d0 + d2
+ SSUB16 e1, trRow00,trRow20 ;// e1 = d0 - d2
+ SHADD16 e2, trRow10,constZero ;// (f1>>1) constZero is a register holding 0
+ SHADD16 e3, trRow30,constZero ;// avoid pipeline stalls for e2 and e3
+ SSUB16 e2, e2, trRow30 ;// e2 = (d1>>1) - d3
+ SADD16 e3, e3, trRow10 ;// e3 = d1 + (d3>>1)
+ SADD16 rowOp00, e0, e3 ;// f0 = e0 + e3
+ SADD16 rowOp10, e1, e2 ;// f1 = e1 + e2
+ SSUB16 rowOp20, e1, e2 ;// f2 = e1 - e2
+ SSUB16 rowOp30, e0, e3 ;// f3 = e0 - e3
+
+ ;// SIMD operations on next two columns(next two rows of the original matrix)
+
+ SADD16 e0, trRow02,trRow22
+ SSUB16 e1, trRow02,trRow22
+ SHADD16 e2, trRow12,constZero ;//(f1>>1) constZero is a register holding 0
+ SHADD16 e3, trRow32,constZero
+ SSUB16 e2, e2, trRow32
+ SADD16 e3, e3, trRow12
+ SADD16 rowOp02, e0, e3
+ SADD16 rowOp12, e1, e2
+ SSUB16 rowOp22, e1, e2
+ SSUB16 rowOp32, e0, e3
+
+
+ ;*****************************************************************
+ ;// Transpose the resultant matrix
+ ;// Input: rowOp[][]
+ ;// Output: trCol[][]
+ ;*****************************************************************
+
+ ;// LL 2x2 transposed matrix
+ ;// d0 d1 - -
+ ;// d4 d5 - -
+ ;// - - - -
+ ;// - - - -
+
+ PKHTB trCol10,rowOp10,rowOp00,ASR #16 ;// [5 4] = [f5:f1]
+ PKHBT trCol00,rowOp00,rowOp10,LSL #16 ;// [1 0] = [f4:f0]
+
+ ;// HL 2x2 transposed matrix
+ ;// - - - -
+ ;// - - - -
+ ;// d8 d9 - -
+ ;// d12 d13 - -
+
+
+ PKHTB trCol30,rowOp12,rowOp02,ASR #16 ;// [13 12] = [7 3]
+ PKHBT trCol20,rowOp02,rowOp12,LSL #16 ;// [9 8] = [6 2]
+
+ ;// LH 2x2 transposed matrix
+ ;// - - d2 d3
+ ;// - - d6 d7
+ ;// - - - -
+ ;// - - - -
+
+ PKHBT trCol02,rowOp20,rowOp30,LSL #16 ;// [3 2] = [f12:f8]
+ PKHTB trCol12,rowOp30,rowOp20,ASR #16 ;// [7 6] = [f13:f9]
+
+
+
+
+ ;// HH 2x2 transposed matrix
+ ;// - - - -
+ ;// - - - -
+ ;// - - d10 d11
+ ;// - - d14 d15
+
+ PKHTB trCol32,rowOp32,rowOp22,ASR #16 ;// [15 14] = [15 11]
+ PKHBT trCol22,rowOp22,rowOp32,LSL #16 ;// [11 10] = [14 10]
+
+
+ ;*******************************
+ ;// Coloumn Operations
+ ;*******************************
+
+
+ ;// SIMD operations on first two columns
+
+
+ SADD16 g0, trCol00,trCol20
+ SSUB16 g1, trCol00,trCol20
+ SHADD16 g2, trCol10,constZero ;// (f1>>1) constZero is a register holding 0
+ SHADD16 g3, trCol30,constZero
+ SSUB16 g2, g2, trCol30
+ SADD16 g3, g3, trCol10
+ SADD16 colOp00, g0, g3
+ SADD16 colOp10, g1, g2
+ SSUB16 colOp20, g1, g2
+ SSUB16 colOp30, g0, g3
+
+ ;// SIMD operations on next two columns
+
+ SADD16 g0, trCol02,trCol22
+ SSUB16 g1, trCol02,trCol22
+ SHADD16 g2, trCol12,constZero ;// (f1>>1) constZero is a register holding 0
+ SHADD16 g3, trCol32,constZero
+ SSUB16 g2, g2, trCol32
+ SADD16 g3, g3, trCol12
+ SADD16 colOp02, g0, g3
+ SADD16 colOp12, g1, g2
+ SSUB16 colOp22, g1, g2
+ SSUB16 colOp32, g0, g3
+
+
+
+
+
+ ;************************************************
+ ;// Calculate final value (colOp[i][j] + 32)>>6
+ ;************************************************
+
+ ;// const1: Serves dual purpose
+ ;// (1) Add #32 to both the lower and higher 16bits of the SIMD result
+ ;// (2) Convert the lower 16 bit value to an unsigned number (Add 32768)
+
+ LDR const1, =0x00208020
+
+ LDR mask, =0xffff03ff ;// Used to mask the down shifted 6 bits
+
+ ;// const2(#512): used to convert the lower 16bit number back to signed value
+
+ MOV const2,#0x200 ;// const2 = 2^9
+
+ ;// First Row
+
+ SADD16 colOp00, colOp00, const1
+ SADD16 colOp02, colOp02, const1
+ AND colOp00, mask, colOp00, ASR #6
+ AND colOp02, mask, colOp02, ASR #6
+ SSUB16 out00,colOp00,const2
+ SSUB16 out02,colOp02,const2
+
+
+ ;// Second Row
+
+ SADD16 colOp10, colOp10, const1
+ SADD16 colOp12, colOp12, const1
+ AND colOp10, mask, colOp10, ASR #6
+ AND colOp12, mask, colOp12, ASR #6
+ SSUB16 out10,colOp10,const2
+ SSUB16 out12,colOp12,const2
+
+
+ ;// Third Row
+
+ SADD16 colOp20, colOp20, const1
+ SADD16 colOp22, colOp22, const1
+ AND colOp20, mask, colOp20, ASR #6
+ AND colOp22, mask, colOp22, ASR #6
+ SSUB16 out20,colOp20,const2
+ SSUB16 out22,colOp22,const2
+
+
+ ;// Fourth Row
+
+ SADD16 colOp30, colOp30, const1
+ SADD16 colOp32, colOp32, const1
+ AND colOp30, mask, colOp30, ASR #6
+ AND colOp32, mask, colOp32, ASR #6
+ SSUB16 out30,colOp30,const2
+ SSUB16 out32,colOp32,const2
+
+
+
+
+ ;***************************
+ ;// Store all the 4x4 pixels
+ ;***************************
+
+ STMIA pDst,{out00,out02,out10,out12,out20,out22,out30,out32}
+
+
+
+ ;// Set return value
+
+End
+
+
+ ;// Write function tail
+ M_END
+
+ ENDIF ;//ARM1136JS
+
+
+
+
+
+
+
+;// Guarding implementation by the processor name
+
+
+ END
\ No newline at end of file
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_UnpackBlock4x4_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_UnpackBlock4x4_s.s
new file mode 100644
index 0000000..ad16d9c
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_UnpackBlock4x4_s.s
@@ -0,0 +1,92 @@
+;//
+;//
+;// File Name: armVCM4P10_UnpackBlock4x4_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 9641
+;// Date: Thursday, February 7, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+;// Define the processor variants supported by this file
+
+ M_VARIANTS ARM1136JS
+
+
+ IF ARM1136JS
+
+;//--------------------------------------
+;// Input Arguments and their scope/usage
+;//--------------------------------------
+ppSrc RN 0 ;// Persistent variable
+pDst RN 1 ;// Persistent variable
+
+;//--------------------------------
+;// Variables and their scope/usage
+;//--------------------------------
+pSrc RN 2 ;// Persistent variables
+Flag RN 3
+Value RN 4
+Value2 RN 5
+strOffset RN 6
+cstOffset RN 7
+
+
+ M_START armVCM4P10_UnpackBlock4x4, r7
+
+ LDR pSrc, [ppSrc] ;// Load pSrc
+ MOV cstOffset, #31 ;// To be used in the loop, to compute offset
+
+ ;//-----------------------------------------------------------------------
+ ; Firstly, fill all the coefficient values on the <pDst> buffer by zero
+ ;//-----------------------------------------------------------------------
+
+ MOV Value, #0 ;// Initialize the zero value
+ MOV Value2, #0 ;// Initialize the zero value
+ LDRB Flag, [pSrc], #1 ;// Preload <Flag> before <unpackLoop>
+
+ STRD Value, [pDst, #0] ;// pDst[0] = pDst[1] = pDst[2] = pDst[3] = 0
+ STRD Value, [pDst, #8] ;// pDst[4] = pDst[5] = pDst[6] = pDst[7] = 0
+ STRD Value, [pDst, #16] ;// pDst[8] = pDst[9] = pDst[10] = pDst[11] = 0
+ STRD Value, [pDst, #24] ;// pDst[12] = pDst[13] = pDst[14] = pDst[15] = 0
+
+ ;//----------------------------------------------------------------------------
+ ;// The loop below parses and unpacks the input stream. The C-model has
+ ;// a somewhat complicated logic for sign extension. But in the v6 version,
+ ;// that can be easily taken care by loading the data from <pSrc> stream as
+ ;// SIGNED byte/halfword. So, based on the first TST instruction, 8-bits or
+ ;// 16-bits are read.
+ ;//
+ ;// Next, to compute the offset, where the unpacked value needs to be stored,
+ ;// we modify the computation to perform [(Flag & 15) < 1] as [(Flag < 1) & 31]
+ ;// This results in a saving of one cycle.
+ ;//----------------------------------------------------------------------------
+
+unpackLoop
+ TST Flag, #0x10 ;// Computing (Flag & 0x10)
+ LDRSBNE Value2,[pSrc,#1] ;// Load byte wise to avoid unaligned access
+ LDRBNE Value, [pSrc], #2
+ AND strOffset, cstOffset, Flag, LSL #1 ;// strOffset = (Flag & 15) < 1;
+ LDRSBEQ Value, [pSrc], #1 ;// Value = (OMX_U8) *pSrc++
+ ORRNE Value,Value,Value2, LSL #8 ;// Value = (OMX_U16) *pSrc++
+
+ TST Flag, #0x20 ;// Computing (Flag & 0x20) to check, if we're done
+ LDRBEQ Flag, [pSrc], #1 ;// Flag = (OMX_U8) *pSrc++, for next iteration
+ STRH Value, [pDst, strOffset] ;// Store <Value> at offset <strOffset>
+ BEQ unpackLoop ;// Branch to the loop beginning
+
+ STR pSrc, [ppSrc] ;// Update the bitstream pointer
+ M_END
+
+ ENDIF
+
+
+
+ END
+
\ No newline at end of file
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_DeblockChroma_I.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_DeblockChroma_I.c
new file mode 100644
index 0000000..c2e6b60
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_DeblockChroma_I.c
@@ -0,0 +1,88 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: omxVCM4P10_DeblockChroma_I.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * H.264 intra chroma deblock
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/**
+ * Function: omxVCM4P10_DeblockChroma_I
+ *
+ * Description:
+ * Performs deblocking filtering on all edges of the chroma macroblock (16x16).
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] pSrcDst pointer to the input macroblock. Must be 8-byte aligned.
+ * [in] srcdstStep Step of the arrays
+ * [in] pAlpha pointer to a 2x2 array of alpha thresholds, organized as follows: { external
+ * vertical edge, internal vertical edge, external
+ * horizontal edge, internal horizontal edge }
+ * [in] pBeta pointer to a 2x2 array of beta thresholds, organized as follows: { external
+ * vertical edge, internal vertical edge, external horizontal edge,
+ * internal horizontal edge }
+ * [in] pThresholds AArray of size 8x2 of Thresholds (TC0) (values for the left or
+ * above edge of each 4x2 or 2x4 block, arranged in vertical block order
+ * and then in horizontal block order)
+ * [in] pBS array of size 16x2 of BS parameters (arranged in scan block order for vertical edges and then horizontal edges);
+ * valid in the range [0,4] with the following restrictions: i) pBS[i]== 4 may occur only for 0<=i<=3, ii) pBS[i]== 4 if and only if pBS[i^1]== 4. Must be 4-byte aligned.
+ * [out] pSrcDst pointer to filtered output macroblock
+ *
+ * Return Value:
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments
+ * - Either of the pointers in pSrcDst, pAlpha, pBeta, pTresholds, or pBS is NULL.
+ * - pSrcDst is not 8-byte aligned.
+ * - either pThresholds or pBS is not 4-byte aligned.
+ * - pBS is out of range, i.e., one of the following conditions is true: pBS[i]<0, pBS[i]>4, pBS[i]==4 for i>=4, or (pBS[i]==4 && pBS[i^1]!=4) for 0<=i<=3.
+ * - srcdstStep is not a multiple of 8.
+ *
+ */
+OMXResult omxVCM4P10_DeblockChroma_I(
+ OMX_U8* pSrcDst,
+ OMX_S32 srcdstStep,
+ const OMX_U8* pAlpha,
+ const OMX_U8* pBeta,
+ const OMX_U8* pThresholds,
+ const OMX_U8 *pBS
+)
+{
+ OMXResult errorCode;
+
+ armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot8ByteAligned(pSrcDst), OMX_Sts_BadArgErr);
+ armRetArgErrIf(srcdstStep & 7, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pAlpha == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pBeta == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pThresholds == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot4ByteAligned(pThresholds), OMX_Sts_BadArgErr);
+ armRetArgErrIf(pBS == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot4ByteAligned(pBS), OMX_Sts_BadArgErr);
+
+ errorCode = omxVCM4P10_FilterDeblockingChroma_VerEdge_I(
+ pSrcDst, srcdstStep, pAlpha, pBeta, pThresholds, pBS);
+
+ armRetArgErrIf(errorCode != OMX_Sts_NoErr, errorCode)
+
+ errorCode = omxVCM4P10_FilterDeblockingChroma_HorEdge_I(
+ pSrcDst, srcdstStep, pAlpha+2, pBeta+2, pThresholds+8, pBS+16);
+
+ return errorCode;
+}
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_DeblockLuma_I.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_DeblockLuma_I.c
new file mode 100644
index 0000000..6023862
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_DeblockLuma_I.c
@@ -0,0 +1,91 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: omxVCM4P10_DeblockLuma_I.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * H.264 luma deblock
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+
+/**
+ * Function: omxVCM4P10_DeblockLuma_I
+ *
+ * Description:
+ * This function performs deblock filtering the horizontal and vertical edges of a luma macroblock
+ *(16x16).
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] pSrcDst pointer to the input macroblock. Must be 8-byte aligned.
+ * [in] srcdstStep image width
+ * [in] pAlpha pointer to a 2x2 table of alpha thresholds, organized as follows: { external
+ * vertical edge, internal vertical edge, external horizontal
+ * edge, internal horizontal edge }
+ * [in] pBeta pointer to a 2x2 table of beta thresholds, organized as follows: { external
+ * vertical edge, internal vertical edge, external horizontal edge,
+ * internal horizontal edge }
+ * [in] pThresholds pointer to a 16x2 table of threshold (TC0), organized as follows: { values for
+ * the left or above edge of each 4x4 block, arranged in vertical block order
+ * and then in horizontal block order)
+ * [in] pBS pointer to a 16x2 table of BS parameters arranged in scan block order for vertical edges and then horizontal edges;
+ * valid in the range [0,4] with the following restrictions: i) pBS[i]== 4 may occur only for 0<=i<=3, ii) pBS[i]== 4 if and only if pBS[i^1]== 4. Must be 4-byte aligned.
+ * [out] pSrcDst pointer to filtered output macroblock.
+ *
+ * Return Value:
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments
+ * - Either of the pointers in pSrcDst, pAlpha, pBeta, pTresholds or pBS is NULL.
+ * - pSrcDst is not 8-byte aligned.
+ * - srcdstStep is not a multiple of 8
+ * - pBS is out of range, i.e., one of the following conditions is true: pBS[i]<0, pBS[i]>4, pBS[i]==4 for i>=4, or (pBS[i]==4 && pBS[i^1]!=4) for 0<=i<=3.
+.
+ *
+ */
+
+OMXResult omxVCM4P10_DeblockLuma_I(
+ OMX_U8* pSrcDst,
+ OMX_S32 srcdstStep,
+ const OMX_U8* pAlpha,
+ const OMX_U8* pBeta,
+ const OMX_U8* pThresholds,
+ const OMX_U8 *pBS
+)
+{
+ OMXResult errorCode;
+
+ armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot8ByteAligned(pSrcDst), OMX_Sts_BadArgErr);
+ armRetArgErrIf(srcdstStep & 7, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pAlpha == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pBeta == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pThresholds == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot4ByteAligned(pThresholds), OMX_Sts_BadArgErr);
+ armRetArgErrIf(pBS == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot4ByteAligned(pBS), OMX_Sts_BadArgErr);
+
+ errorCode = omxVCM4P10_FilterDeblockingLuma_VerEdge_I(
+ pSrcDst, srcdstStep, pAlpha, pBeta, pThresholds, pBS);
+
+ armRetArgErrIf(errorCode != OMX_Sts_NoErr, errorCode)
+
+ errorCode = omxVCM4P10_FilterDeblockingLuma_HorEdge_I(
+ pSrcDst, srcdstStep, pAlpha+2, pBeta+2, pThresholds+16, pBS+16);
+
+ return errorCode;
+}
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c
new file mode 100644
index 0000000..a19f277
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c
@@ -0,0 +1,62 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * H.264 decode coefficients module
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/**
+ * Function: omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC
+ *
+ * Description:
+ * Performs CAVLC decoding and inverse raster scan for 2x2 block of
+ * ChromaDCLevel. The decoded coefficients in packed position-coefficient
+ * buffer are stored in increasing raster scan order, namely position order.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream Double pointer to current byte in bit stream
+ * buffer
+ * [in] pOffset Pointer to current bit position in the byte
+ * pointed to by *ppBitStream
+ * [out] ppBitStream *ppBitStream is updated after each block is decoded
+ * [out] pOffset *pOffset is updated after each block is decoded
+ * [out] pNumCoeff Pointer to the number of nonzero coefficients
+ * in this block
+ * [out] ppPosCoefbuf Double pointer to destination residual
+ * coefficient-position pair buffer
+ *
+ * Return Value:
+ * Standard omxError result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC (
+ const OMX_U8** ppBitStream,
+ OMX_S32* pOffset,
+ OMX_U8* pNumCoeff,
+ OMX_U8** ppPosCoefbuf
+ )
+
+{
+ return armVCM4P10_DecodeCoeffsToPair(ppBitStream, pOffset, pNumCoeff,
+ ppPosCoefbuf, 17, 4);
+
+}
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_DecodeCoeffsToPairCAVLC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_DecodeCoeffsToPairCAVLC.c
new file mode 100644
index 0000000..99bb4ce
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_DecodeCoeffsToPairCAVLC.c
@@ -0,0 +1,68 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: omxVCM4P10_DecodeCoeffsToPairCAVLC.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * H.264 decode coefficients module
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/**
+ * Function: omxVCM4P10_DecodeCoeffsToPairCAVLC
+ *
+ * Description:
+ * Performs CAVLC decoding and inverse zigzag scan for 4x4 block of
+ * Intra16x16DCLevel, Intra16x16ACLevel,LumaLevel, and ChromaACLevel.
+ * Inverse field scan is not supported. The decoded coefficients in packed
+ * position-coefficient buffer are stored in increasing zigzag order instead
+ * of position order.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream Double pointer to current byte in bit stream buffer
+ * [in] pOffset Pointer to current bit position in the byte pointed
+ * to by *ppBitStream
+ * [in] sMaxNumCoeff Maximum number of non-zero coefficients in current
+ * block
+ * [in] sVLCSelect VLC table selector, obtained from number of non-zero
+ * AC coefficients of above and left 4x4 blocks. It is
+ * equivalent to the variable nC described in H.264 standard
+ * table 9-5, except its value can¡¯t be less than zero.
+ * [out] ppBitStream *ppBitStream is updated after each block is decoded
+ * [out] pOffset *pOffset is updated after each block is decoded
+ * [out] pNumCoeff Pointer to the number of nonzero coefficients in
+ * this block
+ * [out] ppPosCoefbuf Double pointer to destination residual
+ * coefficient-position pair buffer
+ * Return Value:
+ * Standard omxError result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult omxVCM4P10_DecodeCoeffsToPairCAVLC(
+ const OMX_U8** ppBitStream,
+ OMX_S32* pOffset,
+ OMX_U8* pNumCoeff,
+ OMX_U8**ppPosCoefbuf,
+ OMX_INT sVLCSelect,
+ OMX_INT sMaxNumCoeff
+ )
+{
+ return armVCM4P10_DecodeCoeffsToPair(ppBitStream, pOffset, pNumCoeff,
+ ppPosCoefbuf, sVLCSelect, sMaxNumCoeff);
+}
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_DequantTransformResidualFromPairAndAdd_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_DequantTransformResidualFromPairAndAdd_s.s
new file mode 100644
index 0000000..2b71486
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_DequantTransformResidualFromPairAndAdd_s.s
@@ -0,0 +1,480 @@
+;//
+;// (c) Copyright 2007 ARM Limited. All Rights Reserved.
+;//
+;// Description:
+;// H.264 inverse quantize and transform module
+;//
+;//
+
+
+
+;// Include standard headers
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+;// Import symbols required from other files
+;// (For example tables)
+
+ IMPORT armVCM4P10_UnpackBlock4x4
+ IMPORT armVCM4P10_TransformResidual4x4
+ IMPORT armVCM4P10_QPDivTable
+ IMPORT armVCM4P10_VMatrixU16
+ IMPORT armVCM4P10_QPModuloTable
+
+ M_VARIANTS ARM1136JS, ARM1136JS_U
+
+;// Set debugging level
+;//DEBUG_ON SETL {TRUE}
+
+
+;// Static Function: armVCM4P10_DequantLumaAC4x4
+
+;// Guarding implementation by the processor name
+
+ IF ARM1136JS
+
+;//Input Registers
+pSrcDst RN 0
+QP RN 1
+
+
+;//Output Registers
+
+
+;//Local Scratch Registers
+pQPdiv RN 4
+pQPmod RN 5
+pVRow RN 2
+QPmod RN 6
+shift RN 3
+rowLuma01 RN 1
+rowLuma23 RN 4
+
+SrcDst00 RN 5
+SrcDst02 RN 6
+SrcDst10 RN 7
+SrcDst12 RN 8
+SrcDst20 RN 9
+SrcDst22 RN 10
+SrcDst30 RN 11
+SrcDst32 RN 12
+
+temp1 RN 2
+temp2 RN 3
+temp3 RN 14
+
+
+ ;// Allocate stack memory required by the function
+
+ ;// Write function header
+ M_START armVCM4P10_DequantLumaAC4x4,r11
+
+ LDR pQPmod,=armVCM4P10_QPModuloTable
+ LDR pQPdiv,=armVCM4P10_QPDivTable
+ LDR pVRow,=armVCM4P10_VMatrixU16
+
+ LDRSB QPmod,[pQPmod,QP] ;// (QP%6) * 6
+ LDRSB shift,[pQPdiv,QP] ;// Shift = QP / 6
+
+ LDRH rowLuma01,[pVRow,QPmod]! ;// rowLuma01 = [00|0a]
+ LDRH temp3,[pVRow,#2] ;// temp3 = [00|0b]
+ LDRH rowLuma23,[pVRow,#4] ;// rowLuma23 = [00|0c]
+ ORR rowLuma01,rowLuma01,temp3,LSL #16 ;// rowLuma01 = [0b|0a]
+
+ ;// Load all the 16 'src' values
+ LDMIA pSrcDst,{SrcDst00,SrcDst02,SrcDst10,SrcDst12,SrcDst20,SrcDst22,SrcDst30,SrcDst32}
+
+
+ ;//*********************************************************************************************
+ ;//
+ ;// 'Shift' ranges between [0,8]
+ ;// So we can shift the packed rowLuma values [0b|0a] with a single LSL operation
+ ;//
+ ;//*********************************************************************************************
+
+ LSL rowLuma01,rowLuma01,shift
+ LSL rowLuma23,rowLuma23,shift
+
+
+ ;//**********************************************************************************************
+ ;//
+ ;// The idea is to unroll the Loop completely
+ ;// All the 16 src values are loaded at once into 8 registers : SrcDst<y><x> (above)
+ ;// 0<= armVCM4P10_PosToVCol4x4[i] <=2 for any 'i<16'
+ ;// So the only values of pVRow[i] that need to be loaded are for i=0,1,2
+ ;// These 3 values are loaded into rowLuma01 and rowLuma23 (above)
+ ;// We first calculate pVRow[armVCM4P10_PosToVCol4x4[i]]) << Shift which fits into 16 bits (above)
+ ;// Then the product pSrcDst[i] * (pVRow[armVCM4P10_PosToVCol4x4[i]] << Shift) is calculated
+ ;// Here we interleave the PKHBT operations for various rows to avoide pipeline stalls
+ ;//
+ ;// We then pack the two 16 bit multiplication result into a word and store at one go
+ ;//
+ ;//**********************************************************************************************
+
+
+ ;// Row 1
+
+
+ SMULTB temp1,SrcDst00,rowLuma23 ;// pSrcDst[1] * (pVRow[2]<<Shift)
+ SMULBB SrcDst00,SrcDst00,rowLuma01 ;// pSrcDst[0] * (pVRow[0]<<Shift)
+
+ SMULTB temp2,SrcDst02,rowLuma23 ;// pSrcDst[3] * (pVRow[2]<<Shift)
+ SMULBB SrcDst02,SrcDst02,rowLuma01 ;// pSrcDst[2] * (pVRow[0]<<Shift)
+
+ PKHBT SrcDst00,SrcDst00,temp1,LSL #16 ;// Pack the first two product values
+
+
+ ;// Row 2
+ SMULTT temp1,SrcDst10,rowLuma01 ;// pSrcDst[5] * (pVRow[1]<<Shift)
+ SMULBB SrcDst10,SrcDst10,rowLuma23 ;// pSrcDst[4] * (pVRow[2]<<Shift)
+
+ PKHBT SrcDst02,SrcDst02,temp2,LSL #16 ;// Pack the next two product values
+ SMULTT temp2,SrcDst12,rowLuma01 ;// pSrcDst[7] * (pVRow[1]<<Shift)
+ SMULBB SrcDst12,SrcDst12,rowLuma23 ;// pSrcDst[6] * (pVRow[2]<<Shift)
+
+ PKHBT SrcDst10,SrcDst10,temp1,LSL #16 ;// Pack the next two product values
+
+
+ ;// Row 3
+
+ SMULTB temp1,SrcDst20,rowLuma23 ;// pSrcDst[9] * (pVRow[2]<<Shift)
+ SMULBB SrcDst20,SrcDst20,rowLuma01 ;// pSrcDst[8] * (pVRow[0]<<Shift)
+
+ PKHBT SrcDst12,SrcDst12,temp2,LSL #16 ;// Pack the next two product values
+ SMULTB temp2,SrcDst22,rowLuma23 ;// pSrcDst[11] * (pVRow[2]<<Shift)
+ SMULBB SrcDst22,SrcDst22,rowLuma01 ;// pSrcDst[10] * (pVRow[0]<<Shift)
+
+ PKHBT SrcDst20,SrcDst20,temp1,LSL #16 ;// Pack the next two product values
+
+
+
+ ;// Row 4
+
+ SMULTT temp1,SrcDst30,rowLuma01 ;// pSrcDst[13] * (pVRow[1]<<Shift)
+ SMULBB SrcDst30,SrcDst30,rowLuma23 ;// pSrcDst[12] * (pVRow[2]<<Shift)
+
+ SMULTT temp3,SrcDst32,rowLuma01 ;// pSrcDst[15] * (pVRow[1]<<Shift)
+ SMULBB SrcDst32,SrcDst32,rowLuma23 ;// pSrcDst[14] * (pVRow[2]<<Shift)
+
+ PKHBT SrcDst22,SrcDst22,temp2,LSL #16 ;// Pack the remaining product values
+ PKHBT SrcDst30,SrcDst30,temp1,LSL #16
+ PKHBT SrcDst32,SrcDst32,temp3,LSL #16
+
+
+ STMIA pSrcDst,{SrcDst00,SrcDst02,SrcDst10,SrcDst12,SrcDst20,SrcDst22,SrcDst30,SrcDst32}
+
+
+ ;// Set return value
+
+
+
+ ;// Write function tail
+ M_END
+
+ ENDIF ;//ARM1136JS
+
+
+;// Guarding implementation by the processor name
+
+ IF ARM1136JS_U
+
+;//Input Registers
+pSrcDst RN 0
+QP RN 1
+
+
+;//Output Registers
+
+
+;//Local Scratch Registers
+pQPdiv RN 4
+pQPmod RN 5
+pVRow RN 2
+QPmod RN 6
+shift RN 3
+rowLuma01 RN 1
+rowLuma23 RN 4
+
+SrcDst00 RN 5
+SrcDst02 RN 6
+SrcDst10 RN 7
+SrcDst12 RN 8
+SrcDst20 RN 9
+SrcDst22 RN 10
+SrcDst30 RN 11
+SrcDst32 RN 12
+
+temp1 RN 2
+temp2 RN 3
+temp3 RN 14
+
+
+ ;// Allocate stack memory required by the function
+
+ ;// Write function header
+ M_START armVCM4P10_DequantLumaAC4x4,r11
+
+ LDR pQPmod,=armVCM4P10_QPModuloTable
+ LDR pQPdiv,=armVCM4P10_QPDivTable
+ LDR pVRow,=armVCM4P10_VMatrixU16
+
+ LDRSB QPmod,[pQPmod,QP] ;// (QP%6) * 6
+ LDRSB shift,[pQPdiv,QP] ;// Shift = QP / 6
+
+ LDR rowLuma01,[pVRow,QPmod]! ;// rowLuma01 = [0b|0a]
+ LDR rowLuma23,[pVRow,#4] ;// rowLuma23 = [0d|0c]
+
+ ;// Load all the 16 'src' values
+ LDMIA pSrcDst,{SrcDst00,SrcDst02,SrcDst10,SrcDst12,SrcDst20,SrcDst22,SrcDst30,SrcDst32}
+
+
+ ;//*********************************************************************************************
+ ;//
+ ;// 'Shift' ranges between [0,8]
+ ;// So we can shift the packed rowLuma values [0b|0a] with a single LSL operation
+ ;//
+ ;//*********************************************************************************************
+
+ LSL rowLuma01,rowLuma01,shift
+ LSL rowLuma23,rowLuma23,shift
+
+
+ ;//**********************************************************************************************
+ ;//
+ ;// The idea is to unroll the Loop completely
+ ;// All the 16 src values are loaded at once into 8 registers : SrcDst<y><x> (above)
+ ;// 0<= armVCM4P10_PosToVCol4x4[i] <=2 for any 'i<16'
+ ;// So the only values of pVRow[i] that need to be loaded are for i=0,1,2
+ ;// These 3 values are loaded into rowLuma01 and rowLuma23 (above)
+ ;// We first calculate pVRow[armVCM4P10_PosToVCol4x4[i]]) << Shift which fits into 16 bits (above)
+ ;// Then the product pSrcDst[i] * (pVRow[armVCM4P10_PosToVCol4x4[i]] << Shift) is calculated
+ ;// Here we interleave the PKHBT operations for various rows to avoide pipeline stalls
+ ;//
+ ;// We then pack the two 16 bit multiplication result into a word and store at one go
+ ;//
+ ;//**********************************************************************************************
+
+
+ ;// Row 1
+
+
+ SMULTB temp1,SrcDst00,rowLuma23 ;// pSrcDst[1] * (pVRow[2]<<Shift)
+ SMULBB SrcDst00,SrcDst00,rowLuma01 ;// pSrcDst[0] * (pVRow[0]<<Shift)
+
+ SMULTB temp2,SrcDst02,rowLuma23 ;// pSrcDst[3] * (pVRow[2]<<Shift)
+ SMULBB SrcDst02,SrcDst02,rowLuma01 ;// pSrcDst[2] * (pVRow[0]<<Shift)
+
+ PKHBT SrcDst00,SrcDst00,temp1,LSL #16 ;// Pack the first two product values
+
+
+ ;// Row 2
+ SMULTT temp1,SrcDst10,rowLuma01 ;// pSrcDst[5] * (pVRow[1]<<Shift)
+ SMULBB SrcDst10,SrcDst10,rowLuma23 ;// pSrcDst[4] * (pVRow[2]<<Shift)
+
+ PKHBT SrcDst02,SrcDst02,temp2,LSL #16 ;// Pack the next two product values
+ SMULTT temp2,SrcDst12,rowLuma01 ;// pSrcDst[7] * (pVRow[1]<<Shift)
+ SMULBB SrcDst12,SrcDst12,rowLuma23 ;// pSrcDst[6] * (pVRow[2]<<Shift)
+
+ PKHBT SrcDst10,SrcDst10,temp1,LSL #16 ;// Pack the next two product values
+
+
+ ;// Row 3
+
+ SMULTB temp1,SrcDst20,rowLuma23 ;// pSrcDst[9] * (pVRow[2]<<Shift)
+ SMULBB SrcDst20,SrcDst20,rowLuma01 ;// pSrcDst[8] * (pVRow[0]<<Shift)
+
+ PKHBT SrcDst12,SrcDst12,temp2,LSL #16 ;// Pack the next two product values
+ SMULTB temp2,SrcDst22,rowLuma23 ;// pSrcDst[11] * (pVRow[2]<<Shift)
+ SMULBB SrcDst22,SrcDst22,rowLuma01 ;// pSrcDst[10] * (pVRow[0]<<Shift)
+
+ PKHBT SrcDst20,SrcDst20,temp1,LSL #16 ;// Pack the next two product values
+
+
+
+ ;// Row 4
+
+ SMULTT temp1,SrcDst30,rowLuma01 ;// pSrcDst[13] * (pVRow[1]<<Shift)
+ SMULBB SrcDst30,SrcDst30,rowLuma23 ;// pSrcDst[12] * (pVRow[2]<<Shift)
+
+ SMULTT temp3,SrcDst32,rowLuma01 ;// pSrcDst[15] * (pVRow[1]<<Shift)
+ SMULBB SrcDst32,SrcDst32,rowLuma23 ;// pSrcDst[14] * (pVRow[2]<<Shift)
+
+ PKHBT SrcDst22,SrcDst22,temp2,LSL #16 ;// Pack the remaining product values
+ PKHBT SrcDst30,SrcDst30,temp1,LSL #16
+ PKHBT SrcDst32,SrcDst32,temp3,LSL #16
+
+
+ STMIA pSrcDst,{SrcDst00,SrcDst02,SrcDst10,SrcDst12,SrcDst20,SrcDst22,SrcDst30,SrcDst32}
+
+
+ ;// Set return value
+
+
+
+ ;// Write function tail
+ M_END
+
+ ENDIF ;//ARM1136JS_U
+
+
+
+
+
+;// Function: omxVCM4P10_DequantTransformResidualFromPairAndAdd
+
+;// Guarding implementation by the processor name
+
+ IF ARM1136JS
+
+;//Input Registers
+ppSrc RN 0
+pPred RN 1
+pDC RN 2
+pDst RN 3
+
+
+;//Output Registers
+result RN 0
+
+;//Local Scratch Registers
+pDelta RN 4
+pDeltaTmp RN 6
+AC RN 5 ;//Load from stack
+pPredTemp RN 7
+pDCTemp RN 8
+pDstTemp RN 9
+pDeltaArg1 RN 1
+pDeltaArg0 RN 0
+QP RN 1 ;//Load from stack
+DCval RN 10
+DCvalCopy RN 11
+predstep RN 1
+dstStep RN 10
+ycounter RN 0
+PredVal1 RN 3
+PredVal2 RN 5
+DeltaVal1 RN 2
+DeltaVal2 RN 11
+PredVal RN 8
+tmpDeltaVal RN 6
+sum1 RN 12
+sum2 RN 14
+
+
+
+ ;// Allocate stack memory required by the function
+ M_ALLOC8 pBuffer, 32
+
+
+ ;// Write function header
+ M_START omxVCM4P10_DequantTransformResidualFromPairAndAdd,r11
+
+ ;// Define stack arguments
+ M_ARG predStepOnStack, 4
+ M_ARG dstStepOnStack,4
+ M_ARG QPOnStack, 4
+ M_ARG ACOnStack,4
+
+
+ M_ADR pDelta,pBuffer
+ M_LDR AC,ACOnStack
+
+
+ ;// Save registers r1,r2,r3 before function call
+ MOV pPredTemp,pPred
+ MOV pDCTemp,pDC
+ MOV pDstTemp,pDst
+
+ CMP AC,#0
+ BEQ DCcase
+ MOV pDeltaArg1,pDelta ;// Set up r1 for armVCM4P10_UnpackBlock4x4
+
+ BL armVCM4P10_UnpackBlock4x4
+
+ M_LDR QP,QPOnStack ;// Set up r1 for DequantLumaAC4x4
+ MOV pDeltaArg0,pDelta ;// Set up r0 for DequantLumaAC4x4
+
+ BL armVCM4P10_DequantLumaAC4x4
+
+
+ CMP pDCTemp,#0
+ LDRSHNE DCval,[pDCTemp]
+ MOV pDeltaArg0,pDelta ;// Set up r0 for armVCM4P10_TransformResidual4x4
+ MOV pDeltaArg1,pDelta ;// Set up r1 for armVCM4P10_TransformResidual4x4
+ STRHNE DCval,[pDelta]
+
+ BL armVCM4P10_TransformResidual4x4
+ B OutDCcase
+
+
+DCcase
+ LDRSH DCval,[pDCTemp]
+ ADD DCval,DCval,#32
+ ASR DCval,DCval,#6
+ PKHBT DCval,DCval,DCval,LSL #16 ;// Duplicating the Lower halfword
+ MOV DCvalCopy, DCval ;// Needed for STRD
+ STRD DCval, [pDelta, #0] ;// pDelta[0] = pDelta[1] = pDelta[2] = pDelta[3] = DCval
+ STRD DCval, [pDelta, #8] ;// pDelta[4] = pDelta[5] = pDelta[6] = pDelta[7] = DCval
+ STRD DCval, [pDelta, #16] ;// pDelta[8] = pDelta[9] = pDelta[10] = pDelta[11] = DCval
+ STRD DCval, [pDelta, #24]
+
+
+OutDCcase
+ M_LDR predstep,predStepOnStack
+ M_LDR dstStep,dstStepOnStack
+
+ LDMIA pDelta!,{tmpDeltaVal,DeltaVal2} ;// Pre load
+ MOV ycounter,#4 ;// Counter for the PredPlusDeltaLoop
+ LDR PredVal,[pPredTemp] ;// Pre load
+
+PredPlusDeltaLoop
+
+
+ SUBS ycounter,ycounter,#1
+ ADD pPredTemp,pPredTemp,predstep ;// Increment pPred ptr
+
+ PKHBT DeltaVal1,tmpDeltaVal,DeltaVal2,LSL #16 ;// Deltaval1 = [C A]
+ PKHTB DeltaVal2,DeltaVal2,tmpDeltaVal,ASR #16 ;// DeltaVal2 = [D B]
+
+ UXTB16 PredVal1,PredVal ;// PredVal1 = [0c0a]
+ UXTB16 PredVal2,PredVal,ROR #8 ;// PredVal2 = [0d0b]
+
+ LDRGT PredVal,[pPredTemp] ;// Pre load
+
+ QADD16 sum2,DeltaVal2,PredVal2 ;// Add and saturate to 16 bits
+ QADD16 sum1,DeltaVal1,PredVal1
+
+ USAT16 sum2,#8,sum2 ;// armClip(0,255,sum2)
+ USAT16 sum1,#8,sum1
+
+ LDMGTIA pDelta!,{tmpDeltaVal,DeltaVal2} ;// Pre load
+
+ ORR sum1,sum1,sum2,LSL #8 ;// sum1 = [dcba]
+ STR sum1,[pDstTemp]
+
+ ADD pDstTemp,pDstTemp,dstStep ;// Increment pDst ptr
+ BGT PredPlusDeltaLoop
+
+
+ ;// Set return value
+ MOV result,#OMX_Sts_NoErr
+
+End
+
+
+ ;// Write function tail
+
+ M_END
+
+ ENDIF ;//ARM1136JS
+
+
+;// Function: omxVCM4P10_DequantTransformResidualFromPairAndAdd
+
+;// Guarding implementation by the processor name
+
+
+
+
+ END
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_HorEdge_I_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_HorEdge_I_s.s
new file mode 100644
index 0000000..6d960f0
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_HorEdge_I_s.s
@@ -0,0 +1,336 @@
+;//
+;//
+;// File Name: omxVCM4P10_FilterDeblockingChroma_HorEdge_I_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 9641
+;// Date: Thursday, February 7, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS ARM1136JS
+
+
+ IF ARM1136JS
+
+MASK_0 EQU 0x00000000
+MASK_1 EQU 0x01010101
+LOOP_COUNT EQU 0x50000000
+
+;// Declare input registers
+
+pSrcDst RN 0
+srcdstStep RN 1
+pAlphaArg RN 2
+pBetaArg RN 3
+
+pThresholds RN 6
+pBS RN 9
+pQ0 RN 0
+bS RN 10
+
+alpha RN 6
+alpha0 RN 6
+alpha1 RN 8
+
+beta RN 7
+beta0 RN 7
+beta1 RN 9
+
+;// Declare Local/Temporary variables
+
+;// Pixels
+p_0 RN 3
+p_1 RN 5
+q_0 RN 8
+q_1 RN 9
+
+;// Filtering
+
+dp0q0 RN 12
+dp1p0 RN 12
+dq1q0 RN 12
+
+ap0q0 RN 4
+filt RN 2
+
+m00 RN 14
+m01 RN 11
+
+pQ0 RN 0
+Step RN 1
+
+;// Output
+
+P_0 RN 6
+Q_0 RN 7
+
+;//Declarations for bSLT4 kernel
+
+tC RN 12
+tC0 RN 5
+tC1 RN 12
+pos RN 5
+neg RN 9
+
+;//Declarations for bSGE4 kernel
+
+
+;// Miscellanous
+XY RN 8
+
+a RN 10
+t1 RN 10
+t2 RN 12
+t3 RN 14
+t4 RN 6
+t5 RN 5
+
+
+ ;// Allocate stack memory
+ M_ALLOC4 ppThresholds,4
+ M_ALLOC8 pAlphaBeta0,8
+ M_ALLOC8 pAlphaBeta1,8
+ M_ALLOC8 pXYBS,4
+ M_ALLOC4 ppBS,4
+
+ ;// Function header
+ M_START omxVCM4P10_FilterDeblockingChroma_HorEdge_I, r11
+
+ ;//Input arguments on the stack
+ M_ARG ppThresholdsArg, 4
+ M_ARG ppBSArg, 4
+
+ LDRB alpha1, [pAlphaArg,#1]
+ LDRB beta1, [pBetaArg,#1]
+ M_LDR pThresholds, ppThresholdsArg
+ LDR a,=MASK_1
+ LDRB beta0, [pBetaArg]
+ M_STR pThresholds, ppThresholds
+ LDRB alpha0, [pAlphaArg]
+
+ MUL alpha1, alpha1, a
+ MUL beta1, beta1, a
+ MUL alpha0, alpha0, a
+ MUL beta0, beta0, a
+
+ M_STRD alpha1, beta1, pAlphaBeta1
+ M_LDR pBS, ppBSArg
+ M_STRD alpha0, beta0, pAlphaBeta0
+
+ LDR XY,=LOOP_COUNT
+ M_STRD XY, pBS, pXYBS
+
+ SUB pQ0, pQ0, srcdstStep, LSL #1
+LoopY
+LoopX
+;//---------------Load Pixels-------------------
+ LDRH bS, [pBS], #2
+
+ M_STR pBS, ppBS
+ M_LDR p_1, [pQ0],srcdstStep
+
+ CMP bS, #0
+
+ M_LDR p_0, [pQ0],srcdstStep
+ M_LDR q_0, [pQ0],srcdstStep
+ M_LDR q_1, [pQ0]
+ LDR m01, =MASK_1 ;// 01010101 mask
+ BEQ NoFilterBS0
+
+
+ ;// p_0 = [r3p0 r2p0 r1p0 r0p0]
+ ;// p_1 = [r3p1 r2p1 r1p1 r0p1]
+ ;// q_0 = [r3q0 r2q0 r1q0 r0q0]
+ ;// q_1 = [r3q1 r2q1 r1q1 r0q1]
+
+;//--------------Filtering Decision -------------------
+ MOV m00, #MASK_0 ;// 00000000 mask
+
+ MOV filt, m01
+ TST bS, #0xff00
+ MOVEQ filt, filt, LSR #16
+ TST bS, #0xff
+ MOVEQ filt, filt, LSL #16
+ TST bS, #4
+
+
+ ;// Check |p0-q0|<Alpha
+ USUB8 dp0q0, p_0, q_0
+ USUB8 a, q_0, p_0
+ SEL ap0q0, a, dp0q0
+ USUB8 a, ap0q0, alpha
+ SEL filt, m00, filt
+
+ ;// Check |p1-p0|<Beta
+ USUB8 dp1p0, p_1, p_0
+ USUB8 a, p_0, p_1
+ SEL a, a, dp1p0
+ USUB8 a, a, beta
+ SEL filt, m00, filt
+
+ ;// Check |q1-q0|<Beta
+ USUB8 dq1q0, q_1, q_0
+ USUB8 a, q_0, q_1
+ SEL a, a, dq1q0
+ USUB8 a, a, beta
+ SEL filt, m00, filt
+
+ BEQ bSLT4
+;//-------------------Filter--------------------
+bSGE4
+ ;//---------bSGE4 Execution---------------
+ CMP filt, #0
+
+ M_LDR pThresholds, ppThresholds
+
+ ;// Compute P0b
+ UHADD8 t1, p_0, q_1
+ BEQ NoFilterFilt0
+ MVN t2, p_1
+ UHSUB8 t1, t1, t2
+ USUB8 t2, filt, m01
+ EOR t1, t1, m01, LSL #7
+
+ ADD pThresholds,pThresholds, #2
+
+ ;// Compute Q0b
+ UHADD8 t2, q_0, p_1
+ MVN t3, q_1
+ UHSUB8 t2, t2, t3
+ M_STR pThresholds, ppThresholds
+ SEL P_0, t1, p_0
+ EOR t2, t2, m01, LSL #7
+ SEL Q_0, t2, q_0
+
+ SUB pQ0, pQ0, srcdstStep, LSL #1
+ B StoreResultAndExit
+
+;//---------- Exit of LoopX --------------
+;//---- for the case of no filtering -----
+
+NoFilterFilt0
+NoFilterBS0
+ M_LDR pThresholds, ppThresholds
+ SUB pQ0, pQ0, srcdstStep, LSL #1
+ SUB pQ0, pQ0, srcdstStep
+ ADD pQ0, pQ0, #4
+ ADD pThresholds, pThresholds, #2
+
+ ;// Load counter for LoopX
+ M_LDRD XY, pBS, pXYBS
+ M_STR pThresholds, ppThresholds
+ M_LDRD alpha, beta, pAlphaBeta0
+
+ ;// Align the pointer
+ ADDS XY, XY, XY
+ M_STR XY, pXYBS
+ BCC LoopY
+ B ExitLoopY
+
+bSLT4
+ ;//---------bSLT4 Execution---------------
+ M_LDR pThresholds, ppThresholds
+ CMP filt, #0
+
+ ;// Since beta <= 18 and alpha <= 255 we know
+ ;// -254 <= p0-q0 <= 254
+ ;// -17 <= q1-q0 <= 17
+ ;// -17 <= p1-p0 <= 17
+
+ ;// delta = Clip3( -tC, tC, ((((q0-p0)<<2) + (p1-q1) + 4)>>3))
+ ;//
+ ;// Calculate A = (((q0-p0)<<2) + (p1-q1) + 4)>>3
+ ;// = (4*q0 - 4*p0 + p1 - q1 + 4)>>3
+ ;// = ((p1-p0) - (q1-q0) - 3*(p0-q0) + 4)>>3
+
+ USUB8 t1, p_1, p_0
+ USUB8 t2, q_1, q_0
+ BEQ NoFilterFilt0
+
+ LDRB tC0, [pThresholds],#1
+ SSUB8 t1, t1, t2
+ LDRB tC1, [pThresholds],#1
+ M_STR pThresholds, ppThresholds
+ UHSUB8 t4, p_0, q_0
+ ORR tC, tC0, tC1, LSL #16
+ USUB8 t5, p_0, q_0
+ AND t5, t5, m01
+ SHSUB8 t1, t1, t5
+ ORR tC, tC, LSL #8
+ SSUB8 t1, t1, t5
+ SHSUB8 t1, t1, t4
+ UQADD8 tC, tC, m01
+ SADD8 t1, t1, m01
+ USUB8 t5, filt, m01
+ SHSUB8 t1, t1, t4
+ SEL tC, tC, m00
+
+ ;// Split into positive and negative part and clip
+
+ SSUB8 t1, t1, m00
+ SEL pos, t1, m00
+ USUB8 neg, pos, t1
+ USUB8 t3, pos, tC
+ SEL pos, tC, pos
+ USUB8 t3, neg, tC
+ SEL neg, tC, neg
+ UQADD8 P_0, p_0, pos
+ UQSUB8 Q_0, q_0, pos
+ UQSUB8 P_0, P_0, neg
+ UQADD8 Q_0, Q_0, neg
+
+ SUB pQ0, pQ0, srcdstStep, LSL #1
+
+ ;// Choose to store the filtered
+ ;// value or the original pixel
+ USUB8 t1, filt, m01
+ SEL P_0, P_0, p_0
+ SEL Q_0, Q_0, q_0
+
+StoreResultAndExit
+
+ ;//---------Store result---------------
+
+ ;// P_0 = [r0p0 r1p0 r2p0 r3p0]
+ ;// Q_0 = [r0q0 r1q0 r2q0 r3q0]
+
+ M_STR P_0, [pQ0], srcdstStep
+ STR Q_0, [pQ0], #4
+
+ M_LDRD XY, pBS, pXYBS
+ M_LDRD alpha, beta, pAlphaBeta0
+
+ SUB pQ0, pQ0, srcdstStep, LSL #1
+
+ ADDS XY, XY, XY
+ M_STR XY, pXYBS
+ BCC LoopX
+
+;//-------- Common Exit of LoopY -----------------
+ ;// Align the pointers
+
+ExitLoopY
+ ADD pBS, pBS, #4
+ M_LDRD alpha, beta, pAlphaBeta1
+ SUB pQ0, pQ0, #8
+ ADD pQ0, pQ0, srcdstStep, LSL #2
+ M_STRD alpha, beta, pAlphaBeta0
+
+ BNE LoopY
+ MOV r0, #OMX_Sts_NoErr
+
+;//-----------------End Filter--------------------
+ M_END
+
+ ENDIF
+
+ END
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_VerEdge_I_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_VerEdge_I_s.s
new file mode 100644
index 0000000..00c8354
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_VerEdge_I_s.s
@@ -0,0 +1,437 @@
+;//
+;//
+;// File Name: omxVCM4P10_FilterDeblockingChroma_VerEdge_I_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 9641
+;// Date: Thursday, February 7, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS ARM1136JS
+
+
+ IF ARM1136JS
+
+
+MASK_0 EQU 0x00000000
+MASK_1 EQU 0x01010101
+MASK_2 EQU 0x0000ff00
+LOOP_COUNT EQU 0x50000000
+
+;// Declare input registers
+
+pSrcDst RN 0
+srcdstStep RN 1
+pAlphaArg RN 2
+pBetaArg RN 3
+
+pThresholds RN 6
+pBS RN 9
+pQ0 RN 0
+bS RN 2
+bSTemp RN 10
+
+alpha RN 6
+alpha0 RN 6
+alpha1 RN 8
+
+beta RN 7
+beta0 RN 7
+beta1 RN 9
+
+;// Declare Local/Temporary variables
+
+;// Pixels
+p_0 RN 3
+p_1 RN 5
+q_0 RN 8
+q_1 RN 9
+
+;// Unpacking
+mask RN 11
+
+row0 RN 2
+row1 RN 4
+row2 RN 5
+row3 RN 3
+
+row4 RN 8
+row5 RN 9
+row6 RN 10
+row7 RN 12
+
+tunpk0 RN 2
+tunpk2 RN 10
+tunpk3 RN 12
+
+tunpk4 RN 4
+tunpk5 RN 5
+tunpk6 RN 14
+tunpk7 RN 2
+
+;// Filtering
+
+dp0q0 RN 12
+dp1p0 RN 12
+dq1q0 RN 12
+
+ap0q0 RN 4
+filt RN 2
+
+m00 RN 14
+m01 RN 11
+
+pQ0 RN 0
+Step RN 1
+
+;// Output
+
+P_0 RN 6
+Q_0 RN 7
+
+;//Declarations for bSLT4 kernel
+
+tC RN 12
+tC0 RN 5
+tC1 RN 12
+pos RN 5
+neg RN 9
+
+;//Declarations for bSGE4 kernel
+
+
+;// Miscellanous
+XY RN 8
+
+a RN 10
+t1 RN 10
+t2 RN 12
+t3 RN 14
+t4 RN 6
+t5 RN 5
+
+
+ ;// Allocate stack memory
+ M_ALLOC4 ppThresholds,4
+ M_ALLOC8 pAlphaBeta0,8
+ M_ALLOC8 pAlphaBeta1,8
+ M_ALLOC8 pXYBS,4
+ M_ALLOC4 ppBS,4
+
+ ;// Function header
+ M_START omxVCM4P10_FilterDeblockingChroma_VerEdge_I, r11
+
+ ;//Input arguments on the stack
+ M_ARG ppThresholdsArg, 4
+ M_ARG ppBSArg, 4
+
+ LDRB alpha1, [pAlphaArg,#1]
+ LDRB beta1, [pBetaArg,#1]
+ M_LDR pThresholds, ppThresholdsArg
+ LDR a,=MASK_1
+ LDRB beta0, [pBetaArg]
+ M_STR pThresholds, ppThresholds
+ LDRB alpha0, [pAlphaArg]
+
+ MUL alpha1, alpha1, a
+ MUL beta1, beta1, a
+ MUL alpha0, alpha0, a
+ MUL beta0, beta0, a
+
+ M_STRD alpha1, beta1, pAlphaBeta1
+ M_LDR pBS, ppBSArg
+ M_STRD alpha0, beta0, pAlphaBeta0
+
+ LDR XY,=LOOP_COUNT
+ M_STRD XY, pBS, pXYBS
+
+
+LoopY
+LoopX
+;//---------------Load Pixels-------------------
+
+;//----------------Pack q0-q1-----------------------
+ LDRH bS, [pBS], #8
+ LDR mask, =MASK_2
+
+ M_LDRH row4, [pQ0], srcdstStep
+ CMP bS, #0
+ M_STR pBS, ppBS
+ M_LDRH row5, [pQ0], srcdstStep
+ BEQ.W NoFilterBS0
+ LDRH row6, [pQ0]
+ LDRH row7, [pQ0, srcdstStep]
+
+ ;// row4 = [0 0 r0q0 r0q1]
+ ;// row5 = [0 0 r1q0 r1q1]
+ ;// row6 = [0 0 r2q0 r2q1]
+ ;// row7 = [0 0 r3q0 r3q1]
+
+ AND tunpk4, mask, row4
+ AND tunpk5, mask, row4, LSL#8
+ UXTAB tunpk4, tunpk4, row5, ROR#8
+ UXTAB tunpk5, tunpk5, row5
+ AND tunpk6, mask, row6
+ AND tunpk7, mask, row6, LSL#8
+ UXTAB tunpk6, tunpk6, row7, ROR#8
+ UXTAB tunpk7, tunpk7, row7
+
+ ;// tunpk4 = [0 0 r0q0 r1q0]
+ ;// tunpk5 = [0 0 r0q1 r1q1]
+ ;// tunpk6 = [0 0 r2q0 r3q0]
+ ;// tunpk7 = [0 0 r2q1 r3q1]
+
+ SUB pQ0, pQ0, srcdstStep, LSL #1
+ SUB pQ0, pQ0, #2
+
+ PKHBT q_1, tunpk6, tunpk4, LSL#16
+ PKHBT q_0, tunpk7, tunpk5, LSL#16
+
+ ;// q_0 = [r0q0 r1q0 r2q0 r3q0]
+ ;// q_1 = [r0q1 r1q1 r2q1 r3q1]
+
+
+;//----------------Pack p0-p1-----------------------
+
+ M_LDRH row0, [pQ0], srcdstStep
+ M_LDRH row1, [pQ0], srcdstStep
+ LDRH row2, [pQ0]
+ LDRH row3, [pQ0, srcdstStep]
+
+ ;// row0 = [0 0 r0p0 r0p1]
+ ;// row1 = [0 0 r1p0 r1p1]
+ ;// row2 = [0 0 r2p0 r2p1]
+ ;// row3 = [0 0 r3p0 r3p1]
+
+ AND tunpk2, mask, row0
+ AND tunpk6, mask, row0, LSL#8
+ UXTAB tunpk2, tunpk2, row1, ROR#8
+ UXTAB tunpk6, tunpk6, row1
+
+ AND tunpk0, mask, row2
+ AND tunpk3, mask, row2, LSL#8
+ UXTAB tunpk0, tunpk0, row3, ROR#8
+ UXTAB tunpk3, tunpk3, row3
+
+ ;// tunpk2 = [0 0 r0p0 r1p0]
+ ;// tunpk6 = [0 0 r0p1 r1p1]
+ ;// tunpk0 = [0 0 r2p0 r3p0]
+ ;// tunpk3 = [0 0 r2p1 r3p1]
+
+ PKHBT p_0, tunpk0, tunpk2, LSL#16
+ M_LDR bSTemp, ppBS
+ PKHBT p_1, tunpk3, tunpk6, LSL#16
+
+ ;// p_0 = [r0p0 r1p0 r2p0 r3p0]
+ ;// p_1 = [r0p1 r1p1 r2p1 r3p1]
+
+;//--------------Filtering Decision -------------------
+ USUB8 dp0q0, p_0, q_0
+ LDR m01, =MASK_1
+ LDRH bSTemp, [bSTemp ,#-8]
+ MOV m00, #MASK_0 ;// 00000000 mask
+
+ MOV filt, m01
+ TST bSTemp, #0xff00
+ MOVEQ filt, filt, LSL #16
+ TST bSTemp, #0xff
+ MOVEQ filt, filt, LSR #16
+ TST bSTemp, #4
+
+ ;// Check |p0-q0|<Alpha
+ USUB8 a, q_0, p_0
+ SEL ap0q0, a, dp0q0
+ USUB8 a, ap0q0, alpha
+ SEL filt, m00, filt
+
+ ;// Check |p1-p0|<Beta
+ USUB8 dp1p0, p_1, p_0
+ USUB8 a, p_0, p_1
+ SEL a, a, dp1p0
+ USUB8 a, a, beta
+ SEL filt, m00, filt
+
+ ;// Check |q1-q0|<Beta
+ USUB8 dq1q0, q_1, q_0
+ USUB8 a, q_0, q_1
+ SEL a, a, dq1q0
+ USUB8 a, a, beta
+ SEL filt, m00, filt
+
+ BEQ bSLT4
+;//-------------------Filter--------------------
+bSGE4
+ ;//---------bSGE4 Execution---------------
+ CMP filt, #0
+
+ M_LDR pThresholds, ppThresholds
+
+ ;// Compute P0b
+ UHADD8 t1, p_0, q_1
+ BEQ NoFilterFilt0
+ MVN t2, p_1
+ UHSUB8 t1, t1, t2
+ USUB8 t2, filt, m01
+ EOR t1, t1, m01, LSL #7
+
+ ADD pThresholds,pThresholds, #4
+
+ ;// Compute Q0b
+ UHADD8 t2, q_0, p_1
+ MVN t3, q_1
+ UHSUB8 t2, t2, t3
+ M_STR pThresholds, ppThresholds
+ SEL P_0, t1, p_0
+ EOR t2, t2, m01, LSL #7
+ SEL Q_0, t2, q_0
+
+ B StoreResultAndExit
+
+;//---------- Exit of LoopX --------------
+;//---- for the case of no filtering -----
+
+NoFilterFilt0
+ ADD pQ0, pQ0, #2
+NoFilterBS0
+ M_LDR pThresholds, ppThresholds
+ SUB pQ0, pQ0, srcdstStep, LSL #1
+ ADD pQ0, pQ0, #4
+ ADD pThresholds, pThresholds, #4
+ ;// Load counter for LoopX
+ M_LDRD XY, pBS, pXYBS
+ M_STR pThresholds, ppThresholds
+ M_LDRD alpha, beta, pAlphaBeta1
+
+ ;// Align the pointer
+ ADDS XY, XY, XY
+ M_STR XY, pXYBS
+ BCC LoopY
+ B ExitLoopY
+
+bSLT4
+ ;//---------bSLT4 Execution---------------
+ M_LDR pThresholds, ppThresholds
+ CMP filt, #0
+
+
+ ;// Since beta <= 18 and alpha <= 255 we know
+ ;// -254 <= p0-q0 <= 254
+ ;// -17 <= q1-q0 <= 17
+ ;// -17 <= p1-p0 <= 17
+
+ ;// delta = Clip3( -tC, tC, ((((q0-p0)<<2) + (p1-q1) + 4)>>3))
+ ;//
+ ;// Calculate A = (((q0-p0)<<2) + (p1-q1) + 4)>>3
+ ;// = (4*q0 - 4*p0 + p1 - q1 + 4)>>3
+ ;// = ((p1-p0) - (q1-q0) - 3*(p0-q0) + 4)>>3
+
+ USUB8 t1, p_1, p_0
+ USUB8 t2, q_1, q_0
+ BEQ NoFilterFilt0
+
+ LDRB tC0, [pThresholds], #1
+ SSUB8 t1, t1, t2
+ LDRB tC1, [pThresholds], #3
+ M_STR pThresholds, ppThresholds
+ UHSUB8 t4, p_0, q_0
+ ORR tC, tC1, tC0, LSL #16
+ USUB8 t5, p_0, q_0
+ AND t5, t5, m01
+ SHSUB8 t1, t1, t5
+ ORR tC, tC, LSL #8
+ SSUB8 t1, t1, t5
+ SHSUB8 t1, t1, t4
+ UQADD8 tC, tC, m01
+ SADD8 t1, t1, m01
+ USUB8 t5, filt, m01
+ SHSUB8 t1, t1, t4
+ SEL tC, tC, m00
+
+ ;// Split into positive and negative part and clip
+
+ SSUB8 t1, t1, m00
+ SEL pos, t1, m00
+ USUB8 neg, pos, t1
+ USUB8 t3, pos, tC
+ SEL pos, tC, pos
+ USUB8 t3, neg, tC
+ SEL neg, tC, neg
+ UQADD8 P_0, p_0, pos
+ UQSUB8 Q_0, q_0, pos
+ UQSUB8 P_0, P_0, neg
+ UQADD8 Q_0, Q_0, neg
+
+ ;// Choose to store the filtered
+ ;// value or the original pixel
+ USUB8 t1, filt, m01
+ SEL P_0, P_0, p_0
+ SEL Q_0, Q_0, q_0
+
+StoreResultAndExit
+
+ ;//---------Store result---------------
+
+ ;// P_0 = [r0p0 r1p0 r2p0 r3p0]
+ ;// Q_0 = [r0q0 r1q0 r2q0 r3q0]
+
+ SUB pQ0, pQ0, srcdstStep, LSL #1
+ ADD pQ0, pQ0, #1
+
+ MOV t1, Q_0, LSR #24
+ STRB t1, [pQ0, #1]
+ MOV t1, P_0, LSR #24
+ M_STRB t1, [pQ0], srcdstStep
+
+ MOV t1, Q_0, LSR #16
+ STRB t1, [pQ0, #1]
+ MOV t1, P_0, LSR #16
+ M_STRB t1, [pQ0], srcdstStep
+
+ MOV t1, P_0, LSR #8
+ STRB t1, [pQ0]
+ STRB P_0, [pQ0, srcdstStep]
+ MOV t1, Q_0, LSR #8
+ STRB t1, [pQ0, #1]!
+ STRB Q_0, [pQ0, srcdstStep]
+
+ M_LDRD XY, pBS, pXYBS
+ M_LDRD alpha, beta, pAlphaBeta1
+
+ SUB pQ0, pQ0, srcdstStep, LSL #1
+ ADD pQ0, pQ0, #4
+
+ ADDS XY, XY, XY
+ M_STR XY, pXYBS
+ BCC LoopX
+
+;//-------- Common Exit of LoopY -----------------
+ ;// Align the pointers
+
+ExitLoopY
+
+ M_LDR pThresholds, ppThresholds
+ SUB pQ0, pQ0, #8
+ ADD pQ0, pQ0, srcdstStep, LSL #2
+ SUB pBS, pBS, #14
+ SUB pThresholds, pThresholds, #6
+ M_STR pThresholds, ppThresholds
+
+ M_LDRD alpha, beta, pAlphaBeta0
+
+ BNE LoopY
+ MOV r0, #OMX_Sts_NoErr
+;//-----------------End Filter--------------------
+
+ M_END
+
+ ENDIF
+
+ END
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_HorEdge_I_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_HorEdge_I_s.s
new file mode 100644
index 0000000..1b84080
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_HorEdge_I_s.s
@@ -0,0 +1,331 @@
+;//
+;//
+;// File Name: omxVCM4P10_FilterDeblockingLuma_HorEdge_I_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 9641
+;// Date: Thursday, February 7, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS ARM1136JS
+
+ IMPORT armVCM4P10_DeblockingLumabSLT4_unsafe
+ IMPORT armVCM4P10_DeblockingLumabSGE4_unsafe
+
+
+
+ IF ARM1136JS
+
+
+MASK_0 EQU 0x00000000
+MASK_1 EQU 0x01010101
+MASK_2 EQU 0xff00ff00
+LOOP_COUNT EQU 0x11110000
+
+;// Declare input registers
+
+pSrcDst RN 0
+srcdstStep RN 1
+pAlphaArg RN 2
+pBetaArg RN 3
+
+pThresholds RN 14
+pBS RN 9
+pQ0 RN 0
+bS RN 2
+
+alpha RN 6
+alpha0 RN 6
+alpha1 RN 8
+
+beta RN 7
+beta0 RN 7
+beta1 RN 9
+
+;// Declare Local/Temporary variables
+
+;// Pixels
+p_0 RN 3
+p_1 RN 5
+p_2 RN 4
+p_3 RN 2
+q_0 RN 8
+q_1 RN 9
+q_2 RN 10
+q_3 RN 12
+
+;// Filtering
+
+dp0q0 RN 12
+dp1p0 RN 12
+dq1q0 RN 12
+dp2p0 RN 12
+dq2q0 RN 12
+
+ap0q0 RN 1
+filt RN 2
+
+m00 RN 14
+m01 RN 11
+
+apflg RN 0
+aqflg RN 6
+apqflg RN 0
+
+
+;//Declarations for bSLT4 kernel
+
+tC0 RN 7
+ptC0 RN 1
+
+pQ0a RN 0
+Stepa RN 1
+maska RN 14
+
+P0a RN 1
+P1a RN 8
+Q0a RN 7
+Q1a RN 11
+
+;//Declarations for bSGE4 kernel
+
+pQ0b RN 0
+Stepb RN 1
+maskb RN 14
+
+P0b RN 6
+P1b RN 7
+P2b RN 1
+P3b RN 3
+
+Q0b RN 9
+Q1b RN 0
+Q2b RN 2
+Q3b RN 3
+
+;// Miscellanous
+XY RN 8
+t0 RN 3
+t1 RN 12
+t2 RN 14
+t7 RN 7
+t4 RN 4
+t5 RN 1
+t8 RN 6
+a RN 0
+
+
+
+
+ ;// Allocate stack memory
+ M_ALLOC4 ppThresholds,4
+ M_ALLOC4 pQ_3,4
+ M_ALLOC4 pP_3,4
+ M_ALLOC8 pAlphaBeta0,8
+ M_ALLOC8 pAlphaBeta1,8
+ M_ALLOC8 pXYBS,4
+ M_ALLOC4 ppBS,4
+ M_ALLOC8 ppQ0Step,4
+ M_ALLOC4 pStep,4
+
+ ;// Function header
+ M_START omxVCM4P10_FilterDeblockingLuma_HorEdge_I, r11
+
+ ;//Input arguments on the stack
+ M_ARG ppThresholdsArg, 4
+ M_ARG ppBSArg, 4
+
+ LDR t4,=MASK_1
+
+ LDRB alpha0, [pAlphaArg]
+ LDRB beta0, [pBetaArg]
+ LDRB alpha1, [pAlphaArg,#1]
+ LDRB beta1, [pBetaArg,#1]
+
+ MUL alpha0, alpha0, t4
+ MUL beta0, beta0, t4
+ MUL alpha1, alpha1, t4
+ MUL beta1, beta1, t4
+
+ M_STRD alpha0, beta0, pAlphaBeta0
+ M_STRD alpha1, beta1, pAlphaBeta1
+
+ LDR XY,=LOOP_COUNT
+ M_LDR pBS, ppBSArg
+ M_LDR pThresholds, ppThresholdsArg
+ M_STR srcdstStep, pStep
+ M_STRD XY, pBS, pXYBS
+ SUB pQ0, pQ0, srcdstStep, LSL #2
+ M_STR pThresholds, ppThresholds
+LoopY
+LoopX
+;//---------------Load Pixels-------------------
+ M_STR pQ0, ppQ0Step
+ M_LDR p_3, [pQ0], srcdstStep
+ M_LDR p_2, [pQ0], srcdstStep
+ M_STR p_3, pP_3
+ LDRB bS, [pBS], #1
+ M_STR pBS, ppBS
+ M_LDR p_1, [pQ0], srcdstStep
+ CMP bS, #0
+ M_LDR p_0, [pQ0], srcdstStep
+ M_LDR q_0, [pQ0], srcdstStep
+ M_LDR q_1, [pQ0], srcdstStep
+ M_LDR q_2, [pQ0], srcdstStep
+ M_LDR q_3, [pQ0], srcdstStep
+ BEQ NoFilterBS0
+ CMP bS, #4
+ M_STR q_3, pQ_3
+
+;//--------------Filtering Decision -------------------
+ LDR m01, =MASK_1 ;// 01010101 mask
+ MOV m00, #MASK_0 ;// 00000000 mask
+
+ ;// Check |p0-q0|<Alpha
+ USUB8 dp0q0, p_0, q_0
+ USUB8 a, q_0, p_0
+ SEL ap0q0, a, dp0q0
+ USUB8 a, ap0q0, alpha
+ SEL filt, m00, m01
+
+ ;// Check |p1-p0|<Beta
+ USUB8 dp1p0, p_1, p_0
+ USUB8 a, p_0, p_1
+ SEL a, a, dp1p0
+ USUB8 a, a, beta
+ SEL filt, m00, filt
+
+ ;// Check |q1-q0|<Beta
+ USUB8 dq1q0, q_1, q_0
+ USUB8 a, q_0, q_1
+ SEL a, a, dq1q0
+ USUB8 a, a, beta
+ SEL filt, m00, filt
+
+ ;// Check ap<Beta
+ USUB8 dp2p0, p_2, p_0
+ USUB8 a, p_0, p_2
+ SEL a, a, dp2p0
+ USUB8 a, a, beta
+ SEL apflg, m00, filt ;// apflg = filt && (ap<beta)
+
+ ;// Check aq<Beta
+ USUB8 dq2q0, q_2, q_0
+ USUB8 t2, q_0, q_2
+ SEL t2, t2, dq2q0
+ USUB8 t2, t2, beta
+ MOV t7,#0
+
+ BLT bSLT4
+;//-------------------Filter--------------------
+bSGE4
+ ;//---------bSGE4 Execution---------------
+ SEL t1, t7, filt ;// aqflg = filt && (aq<beta)
+ CMP filt, #0
+ ORR apqflg, apflg, t1, LSL #1
+ M_LDRD pQ0, srcdstStep, ppQ0Step, EQ
+ BEQ NoFilterFilt0
+
+ BL armVCM4P10_DeblockingLumabSGE4_unsafe
+
+ ;//---------Store result---------------
+ M_LDR pThresholds, ppThresholds
+ MOV p_2, Q1b
+ MOV p_1, P2b
+ M_LDRD pQ0b, Stepb, ppQ0Step
+ ADD pThresholds, #1
+ M_STR pThresholds, ppThresholds
+ M_STR p_1, [pQ0b, Stepb]!
+ M_STR P1b, [pQ0b, Stepb]!
+ M_STR P0b, [pQ0b, Stepb]!
+ M_STR Q0b, [pQ0b, Stepb]!
+ STR p_2, [pQ0b, Stepb]
+ STR Q2b, [pQ0b, Stepb, LSL #1]
+
+
+ M_LDRD XY, pBS, pXYBS
+ SUB pQ0, pQ0b, Stepb, LSL #2
+ ADD pQ0, pQ0, #4
+ M_LDRD alpha, beta, pAlphaBeta0
+ ADDS XY, XY, XY
+ M_STR XY, pXYBS
+ BCC LoopX
+ B ExitLoopY
+
+;//---------- Exit of LoopX --------------
+;//---- for the case of no filtering -----
+
+NoFilterBS0
+ SUB pQ0, pQ0, srcdstStep, LSL #3
+NoFilterFilt0
+ ADD pQ0, pQ0, #4
+ ;// Load counter for LoopX
+ M_LDRD XY, pBS, pXYBS
+ M_LDR pThresholds, ppThresholds
+ M_LDRD alpha, beta, pAlphaBeta0
+
+ ;// Align the pointers
+ ADDS XY, XY, XY
+ ADD pThresholds, pThresholds, #1
+ M_STR pThresholds, ppThresholds
+ M_STR XY, pXYBS
+ BCC LoopX
+ B ExitLoopY
+
+bSLT4
+ ;//---------bSLT4 Execution---------------
+ SEL aqflg, t7, filt ;// aqflg = filt && (aq<beta)
+ M_LDR ptC0, ppThresholds
+ CMP filt, #0
+ M_LDRD pQ0, srcdstStep, ppQ0Step, EQ
+ BEQ NoFilterFilt0
+
+ LDRB tC0, [ptC0], #1
+ M_STR ptC0, ppThresholds
+
+ BL armVCM4P10_DeblockingLumabSLT4_unsafe
+
+ ;//---------Store result---------------
+ MOV p_2, P0a
+ M_LDRD pQ0a, Stepa, ppQ0Step
+ M_STR P1a, [pQ0a, Stepa, LSL #1]!
+ M_STR p_2, [pQ0a, Stepa]!
+ M_STR Q0a, [pQ0a, Stepa]!
+ STR Q1a, [pQ0a, Stepa]
+
+ ;// Load counter
+ M_LDRD XY, pBS, pXYBS
+ M_LDRD alpha, beta, pAlphaBeta0
+
+ SUB pQ0, pQ0a, Stepa, LSL #2
+ ADD pQ0, pQ0, #4
+
+ ADDS XY, XY, XY
+ M_STR XY, pXYBS
+ BCC LoopX
+
+;//-------- Common Exit of LoopY -----------------
+ ;// Align the pointers
+ExitLoopY
+ M_LDRD alpha, beta, pAlphaBeta1
+ SUB pQ0, pQ0, #16
+ ADD pQ0, pQ0, srcdstStep, LSL #2
+ M_STRD alpha, beta, pAlphaBeta0
+
+ BNE LoopY
+ MOV r0, #OMX_Sts_NoErr
+;//-----------------End Filter--------------------
+ M_END
+
+ ENDIF
+
+
+ END
+
+
\ No newline at end of file
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_VerEdge_I_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_VerEdge_I_s.s
new file mode 100644
index 0000000..417ddc2
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_VerEdge_I_s.s
@@ -0,0 +1,550 @@
+;//
+;//
+;// File Name: omxVCM4P10_FilterDeblockingLuma_VerEdge_I_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 9641
+;// Date: Thursday, February 7, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS ARM1136JS
+
+ IMPORT armVCM4P10_DeblockingLumabSLT4_unsafe
+ IMPORT armVCM4P10_DeblockingLumabSGE4_unsafe
+
+
+ IF ARM1136JS
+
+MASK_0 EQU 0x00000000
+MASK_1 EQU 0x01010101
+MASK_2 EQU 0xff00ff00
+LOOP_COUNT EQU 0x11110000
+
+;// Declare input registers
+
+pSrcDst RN 0
+srcdstStep RN 1
+pAlphaArg RN 2
+pBetaArg RN 3
+
+pThresholds RN 14
+pBS RN 9
+pQ0 RN 0
+bS RN 2
+
+alpha RN 6
+alpha0 RN 6
+alpha1 RN 8
+
+beta RN 7
+beta0 RN 7
+beta1 RN 9
+
+;// Declare Local/Temporary variables
+
+;// Pixels
+p_0 RN 3
+p_1 RN 5
+p_2 RN 4
+p_3 RN 2
+q_0 RN 8
+q_1 RN 9
+q_2 RN 10
+q_3 RN 12
+
+;// Unpacking
+mask RN 11
+
+row0 RN 2
+row1 RN 4
+row2 RN 5
+row3 RN 3
+
+row4 RN 8
+row5 RN 9
+row6 RN 10
+row7 RN 12
+row8 RN 14
+row9 RN 7
+
+tunpk0 RN 8
+tunpk1 RN 9
+tunpk2 RN 10
+tunpk3 RN 12
+tunpk4 RN 0
+
+tunpk5 RN 1
+tunpk6 RN 14
+tunpk7 RN 2
+tunpk8 RN 5
+tunpk9 RN 6
+
+
+;// Filtering
+
+dp0q0 RN 12
+dp1p0 RN 12
+dq1q0 RN 12
+dp2p0 RN 12
+dq2q0 RN 12
+
+ap0q0 RN 1
+filt RN 2
+
+m00 RN 14
+m01 RN 11
+
+apflg RN 0
+aqflg RN 6
+apqflg RN 0
+
+
+;//Declarations for bSLT4 kernel
+
+tC0 RN 7
+ptC0 RN 1
+
+pQ0a RN 0
+Stepa RN 1
+maska RN 14
+
+P0a RN 1
+P1a RN 8
+Q0a RN 7
+Q1a RN 11
+
+;//Declarations for bSGE4 kernel
+
+pQ0b RN 0
+Stepb RN 1
+maskb RN 14
+
+P0b RN 6
+P1b RN 7
+P2b RN 1
+P3b RN 3
+
+Q0b RN 9
+Q1b RN 0
+Q2b RN 2
+Q3b RN 3
+
+;// Miscellanous
+XY RN 8
+t0 RN 3
+t1 RN 12
+t2 RN 14
+t7 RN 7
+t4 RN 4
+t5 RN 1
+t8 RN 6
+a RN 0
+
+
+
+ ;// Allocate stack memory
+ M_ALLOC4 ppThresholds,4
+ M_ALLOC4 pQ_3,4
+ M_ALLOC4 pP_3,4
+ M_ALLOC8 pAlphaBeta0,8
+ M_ALLOC8 pAlphaBeta1,8
+ M_ALLOC8 pXYBS,4
+ M_ALLOC4 ppBS,4
+ M_ALLOC8 ppQ0Step,4
+ M_ALLOC4 pStep,4
+
+ ;// Function header
+ M_START omxVCM4P10_FilterDeblockingLuma_VerEdge_I, r11
+
+ ;//Input arguments on the stack
+ M_ARG ppThresholdsArg, 4
+ M_ARG ppBSArg, 4
+
+ LDR t4,=MASK_1
+
+ LDRB alpha0, [pAlphaArg]
+ LDRB beta0, [pBetaArg]
+ LDRB alpha1, [pAlphaArg,#1]
+ LDRB beta1, [pBetaArg,#1]
+
+ MUL alpha0, alpha0, t4
+ MUL beta0, beta0, t4
+ MUL alpha1, alpha1, t4
+ MUL beta1, beta1, t4
+
+ M_STRD alpha0, beta0, pAlphaBeta0
+ M_STRD alpha1, beta1, pAlphaBeta1
+
+ LDR XY,=LOOP_COUNT
+ M_LDR pBS, ppBSArg
+ M_LDR pThresholds, ppThresholdsArg
+ M_STR srcdstStep, pStep
+ M_STRD XY, pBS, pXYBS
+ M_STR pThresholds, ppThresholds
+
+ SUB pQ0, pQ0, #4
+LoopY
+;//---------------Load Pixels-------------------
+
+;//----------------Pack p0-p3-----------------------
+ LDR mask, =MASK_2
+
+ M_LDR row0, [pQ0], srcdstStep
+ M_LDR row1, [pQ0], srcdstStep
+ LDR row2, [pQ0]
+ LDR row3, [pQ0, srcdstStep]
+ SUB pQ0, pQ0, srcdstStep, LSL #1
+
+ ;// row0 = [r0p0 r0p1 r0p2 r0p3]
+ ;// row1 = [r1p0 r1p1 r1p2 r1p3]
+ ;// row2 = [r2p0 r2p1 r2p2 r2p3]
+ ;// row3 = [r3p0 r3p1 r3p2 r3p3]
+
+ AND tunpk0, mask, row0
+ AND tunpk6, mask, row0, LSL#8
+ UXTAB16 tunpk0, tunpk0, row1, ROR#8
+ UXTAB16 tunpk6, tunpk6, row1
+ AND tunpk2, mask, row2
+ AND tunpk3, mask, row2, LSL#8
+ UXTAB16 tunpk2, tunpk2, row3, ROR#8
+ UXTAB16 tunpk3, tunpk3, row3
+
+ ;// tunpk0 = [r0p0 r1p0 r0p2 r1p2]
+ ;// tunpk6 = [r0p1 r1p1 r0p3 r1p3]
+ ;// tunpk2 = [r2p0 r3p0 r2p2 r3p2]
+ ;// tunpk3 = [r2p1 r3p1 r2p3 r3p3]
+
+ PKHTB p_0, tunpk0, tunpk2, ASR#16
+ PKHTB p_1, tunpk6, tunpk3, ASR#16
+ PKHBT p_2, tunpk2, tunpk0, LSL#16
+ PKHBT p_3, tunpk3, tunpk6, LSL#16
+
+
+ ;// p_0 = [r0p0 r1p0 r2p0 r3p0]
+ ;// p_1 = [r0p1 r1p1 r2p1 r3p1]
+ ;// p_2 = [r0p2 r1p2 r2p1 r3p2]
+ ;// p_3 = [r0p3 r1p3 r2p3 r3p3]
+
+ M_STR p_3, pP_3
+
+;//----------------Pack q0-q3-----------------------
+LoopX
+ LDRB bS, [pBS], #4
+ M_STR pQ0, ppQ0Step
+ LDR mask, =MASK_2
+ CMP bS, #0
+ M_STR pBS, ppBS
+
+ LDR row4, [pQ0, #4]!
+ BEQ.W NoFilterBS0
+ M_LDR row5, [pQ0, srcdstStep]!
+ M_LDR row6, [pQ0, srcdstStep]!
+ M_LDR row7, [pQ0, srcdstStep]
+
+ ;// row4 = [r0q3 r0q2 r0q1 r0q0]
+ ;// row5 = [r1q3 r1q2 r1q1 r1q0]
+ ;// row6 = [r2q3 r2q2 r2q1 r2q0]
+ ;// row7 = [r3q3 r3q2 r3q1 r3q0]
+
+ AND tunpk4, mask, row4
+ CMP bS, #4
+ AND tunpk5, mask, row4, LSL#8
+ UXTAB16 tunpk4, tunpk4, row5, ROR#8
+ UXTAB16 tunpk5, tunpk5, row5
+ AND tunpk6, mask, row6
+ AND tunpk7, mask, row6, LSL#8
+ UXTAB16 tunpk6, tunpk6, row7, ROR#8
+ UXTAB16 tunpk7, tunpk7, row7
+
+ ;// tunpk4 = [r0q0 r1q0 r0q2 r1q2]
+ ;// tunpk5 = [r0q1 r1q1 r0q3 r1q3]
+ ;// tunpk6 = [r2q0 r3q0 r2q2 r3q2]
+ ;// tunpk7 = [r2q1 r3q1 r2q3 r3q3]
+
+ PKHTB q_3, tunpk4, tunpk6, ASR#16
+ PKHTB q_2, tunpk5, tunpk7, ASR#16
+ PKHBT q_1, tunpk6, tunpk4, LSL#16
+ M_STR q_3, pQ_3
+ PKHBT q_0, tunpk7, tunpk5, LSL#16
+
+
+ ;// q_0 = [r0q0 r1q0 r2q0 r3q0]
+ ;// q_1 = [r0q1 r1q1 r2q1 r3q1]
+ ;// q_2 = [r0q2 r1q2 r2q1 r3q2]
+ ;// q_3 = [r0q3 r1q3 r2q3 r3q3]
+
+
+;//--------------Filtering Decision -------------------
+ LDR m01, =MASK_1 ;// 01010101 mask
+ MOV m00, #MASK_0 ;// 00000000 mask
+
+ ;// Check |p0-q0|<Alpha
+ USUB8 dp0q0, p_0, q_0
+ USUB8 a, q_0, p_0
+ SEL ap0q0, a, dp0q0
+ USUB8 a, ap0q0, alpha
+ SEL filt, m00, m01
+
+ ;// Check |p1-p0|<Beta
+ USUB8 dp1p0, p_1, p_0
+ USUB8 a, p_0, p_1
+ SEL a, a, dp1p0
+ USUB8 a, a, beta
+ SEL filt, m00, filt
+
+ ;// Check |q1-q0|<Beta
+ USUB8 dq1q0, q_1, q_0
+ USUB8 a, q_0, q_1
+ SEL a, a, dq1q0
+ USUB8 a, a, beta
+ SEL filt, m00, filt
+
+ ;// Check ap<Beta
+ USUB8 dp2p0, p_2, p_0
+ USUB8 a, p_0, p_2
+ SEL a, a, dp2p0
+ USUB8 a, a, beta
+ SEL apflg, m00, filt ;// apflg = filt && (ap<beta)
+
+ ;// Check aq<Beta
+ USUB8 dq2q0, q_2, q_0
+ USUB8 t2, q_0, q_2
+ SEL t2, t2, dq2q0
+ USUB8 t2, t2, beta
+ MOV t7,#0
+
+
+ BLT bSLT4
+;//-------------------Filter--------------------
+bSGE4
+ ;//---------bSGE4 Execution---------------
+ SEL t1, t7, filt ;// aqflg = filt && (aq<beta)
+ CMP filt, #0
+ ORR apqflg, apflg, t1, LSL #1
+ M_LDRD pQ0, srcdstStep, ppQ0Step, EQ
+ BEQ NoFilterFilt0
+
+ BL armVCM4P10_DeblockingLumabSGE4_unsafe
+
+ ;//---------Store result---------------
+
+ LDR maskb,=MASK_2
+
+ ;// P0b = [r0p0 r1p0 r2p0 r3p0]
+ ;// P1b = [r0p1 r1p1 r2p1 r3p1]
+ ;// P2b = [r0p2 r1p2 r2p2 r3p2]
+ ;// P3b = [r0p3 r1p3 r2p3 r3p3]
+
+ M_LDR P3b, pP_3
+ M_STR Q0b, pP_3
+
+ ;//------Pack p0-p3------
+ AND tunpk0, maskb, P0b
+ AND tunpk2, maskb, P0b, LSL#8
+ UXTAB16 tunpk0, tunpk0, P1b, ROR#8
+ UXTAB16 tunpk2, tunpk2, P1b
+
+ AND tunpk3, maskb, P2b
+ AND tunpk8, maskb, P2b, LSL#8
+ UXTAB16 tunpk3, tunpk3, P3b, ROR#8
+ UXTAB16 tunpk8, tunpk8, P3b
+
+ ;// tunpk0 = [r0p0 r0p1 r2p0 r2p1]
+ ;// tunpk2 = [r1p0 r1p1 r3p0 r3p1]
+ ;// tunpk3 = [r0p2 r0p3 r2p2 r2p3]
+ ;// tunpk8 = [r1p2 r1p3 r3p2 r3p3]
+
+ MOV p_2, Q1b
+ M_LDRD pQ0b, Stepb, ppQ0Step
+
+ PKHTB row9, tunpk0, tunpk3, ASR#16
+ PKHBT row7, tunpk3, tunpk0, LSL#16
+ PKHTB row3, tunpk2, tunpk8, ASR#16
+ PKHBT row6, tunpk8, tunpk2, LSL#16
+
+ ;// row9 = [r0p0 r0p1 r0p2 r0p3]
+ ;// row3 = [r1p0 r1p1 r1p2 r1p3]
+ ;// row7 = [r2p0 r2p1 r2p2 r2p3]
+ ;// row6 = [r3p0 r3p1 r3p2 r3p3]
+
+ M_STR row9, [pQ0b], Stepb
+ STR row7, [pQ0b, Stepb]
+ STR row6, [pQ0b, Stepb, LSL #1]
+ STR row3, [pQ0b], #4
+
+ M_LDR Q3b, pQ_3
+
+ ;// Q0b = [r0q0 r1q0 r2q0 r3q0]
+ ;// Q1b = [r0q1 r1q1 r2q1 r3q1]
+ ;// Q2b = [r0q2 r1q2 r2q2 r3q2]
+ ;// Q3b = [r0q3 r1q3 r2q3 r3q3]
+
+ ;//------Pack q0-q3------
+ AND tunpk0, maskb, p_2
+ AND tunpk2, maskb, p_2, LSL#8
+ UXTAB16 tunpk0, tunpk0, Q0b, ROR#8
+ UXTAB16 tunpk2, tunpk2, Q0b
+
+ AND tunpk3, maskb, Q3b
+ AND tunpk8, maskb, Q3b, LSL#8
+ UXTAB16 tunpk3, tunpk3, Q2b, ROR#8
+ UXTAB16 tunpk8, tunpk8, Q2b
+
+ ;// tunpk0 = [r0q1 r0q0 r2q1 r2q0]
+ ;// tunpk2 = [r1q1 r1q0 r3q1 r3q0]
+ ;// tunpk3 = [r0q3 r0q2 r2q3 r2q2]
+ ;// tunpk8 = [r1q3 r1q2 r3q3 r3q2]
+
+ PKHTB row8, tunpk3, tunpk0, ASR#16
+ PKHBT row7, tunpk0, tunpk3, LSL#16
+ PKHTB row4, tunpk8, tunpk2, ASR#16
+ PKHBT row6, tunpk2, tunpk8, LSL#16
+
+ ;// row8 = [r0q0 r0q1 r0q2 r0q3]
+ ;// row4 = [r1q0 r1q1 r1q2 r1q3]
+ ;// row7 = [r2q0 r2q1 r2q2 r2q3]
+ ;// row6 = [r3q0 r3q1 r3q2 r3q3]
+
+ STR row4, [pQ0b]
+ STR row7, [pQ0b, Stepb]
+ STR row6, [pQ0b, Stepb, LSL #1]
+
+ SUB pQ0, pQ0b, Stepb
+ MOV p_1, Q2b
+
+ STR row8, [pQ0]
+
+ M_LDRD XY, pBS, pXYBS
+ M_LDR pThresholds, ppThresholds
+ M_LDRD alpha, beta, pAlphaBeta1
+
+ ADDS XY, XY, XY
+ ADD pThresholds, #4
+ M_STR pThresholds, ppThresholds
+ M_STR XY, pXYBS
+ BCC LoopX
+ B ExitLoopY
+
+;//---------- Exit of LoopX --------------
+;//---- for the case of no filtering -----
+
+NoFilterFilt0
+ ADD pQ0, pQ0, #4
+NoFilterBS0
+ ;// Load counter for LoopX
+ M_LDRD XY, pBS, pXYBS
+ M_LDR pThresholds, ppThresholds
+ M_LDRD alpha, beta, pAlphaBeta1
+
+ ;// Align the pointer
+ ADDS XY, XY, XY
+ ADD pThresholds, pThresholds, #4
+ M_STR pThresholds, ppThresholds
+ M_STR XY, pXYBS
+ BCC LoopY
+ B ExitLoopY
+
+bSLT4
+ ;//---------bSLT4 Execution---------------
+ SEL aqflg, t7, filt ;// aqflg = filt && (aq<beta)
+ M_LDR ptC0, ppThresholds
+ CMP filt, #0
+ M_LDRD pQ0, srcdstStep, ppQ0Step, EQ
+ BEQ NoFilterFilt0
+
+ LDRB tC0, [ptC0], #4
+ M_STR ptC0, ppThresholds
+
+ BL armVCM4P10_DeblockingLumabSLT4_unsafe
+
+ ;//---------Store result---------------
+ ;//--------Pack p1,p0,q1,q0------------
+
+ ;//Load destination pointer
+ LDR maska,=MASK_2
+ M_STR Q0a, pP_3
+ MOV p_1, q_2
+
+ ;// P1a = [r0p1 r1p1 r2p1 r3p1]
+ ;// P0a = [r0p0 r1p0 r2p0 r3p0]
+ ;// Q0a = [r0q0 r1q0 r2q0 r3q0]
+ ;// Q1a = [r0q1 r1q1 r2q1 r3q1]
+
+ AND tunpk1, maska, P0a
+ AND tunpk2, maska, P0a, LSL#8
+ UXTAB16 tunpk1, tunpk1, P1a, ROR#8
+ UXTAB16 tunpk2, tunpk2, P1a
+
+ M_LDRD pQ0a, Stepa, ppQ0Step
+
+ AND tunpk9, maska, Q1a
+ AND tunpk3, maska, Q1a, LSL#8
+ UXTAB16 tunpk9, tunpk9, Q0a, ROR#8
+ UXTAB16 tunpk3, tunpk3, Q0a
+
+ ;// tunpk1 = [r0p0 r0p1 r2p0 r2p1]
+ ;// tunpk2 = [r1p0 r1p1 r3p0 r3p1]
+ ;// tunpk9 = [r0q1 r0q0 r2q1 r2q0]
+ ;// tunpk3 = [r1q1 r1q0 r3q1 r3q0]
+
+ MOV t4, tunpk1, LSR #16
+ MOV t0, tunpk9, LSR #16
+
+ STRH t4,[pQ0a, #2]! ;//Stores [r0p0 r0p1]
+ STRH t0,[pQ0a, #2] ;//Stores [r0q0 r0q1]
+
+ MOV t4, tunpk2, LSR #16
+ MOV t0, tunpk3, LSR #16
+
+ M_STRH t4,[pQ0a, Stepa]! ;//Stores [r1p0 r1p1]
+ STRH t0,[pQ0a, #2] ;//Stores [r1q0 r1q1]
+
+ M_STRH tunpk1,[pQ0a, Stepa]! ;//Stores [r2p0 r2p1]
+ STRH tunpk2,[pQ0a, Stepa] ;//Stores [r3p0 r3p1]
+ STRH tunpk9,[pQ0a, #2]! ;//Stores [r2q0 r2q1]
+ STRH tunpk3,[pQ0a, Stepa] ;//Stores [r3q0 r3q1]
+
+ SUB pQ0, pQ0a, Stepa, LSL #1
+
+ ;// Load counter
+ M_LDRD XY, pBS, pXYBS
+
+ ;// Reload Pixels
+ M_LDR p_0, pQ_3
+ MOV p_2, Q1a
+
+ M_LDRD alpha, beta, pAlphaBeta1
+
+ ADDS XY, XY, XY
+ M_STR XY, pXYBS
+ BCC LoopX
+
+;//-------- Common Exit of LoopY -----------------
+ ;// Align the pointers
+ M_LDR pThresholds, ppThresholds
+ExitLoopY
+ SUB pQ0, pQ0, #16
+ ADD pQ0, pQ0, srcdstStep, LSL #2
+ SUB pBS, pBS, #15
+ SUB pThresholds, pThresholds, #15
+ M_STR pThresholds, ppThresholds
+
+ M_LDRD alpha, beta, pAlphaBeta0
+
+ BNE LoopY
+ MOV r0, #OMX_Sts_NoErr
+
+ M_END
+;//-----------------End Filter--------------------
+
+ ENDIF
+
+ END
+
+
\ No newline at end of file
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_InterpolateChroma.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_InterpolateChroma.c
new file mode 100644
index 0000000..de835bd
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_InterpolateChroma.c
@@ -0,0 +1,79 @@
+/**
+ *
+ * File Name: omxVCM4P10_InterpolateChroma.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ * Description:
+ * This function will calculate 1/8 Pixel interpolation for Chroma Block
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armVC.h"
+#include "armCOMM.h"
+
+
+/**
+ * Function: omxVCM4P10_InterpolateChroma,
+ *
+ * Description:
+ * Performs 1/8-pixel interpolation for inter chroma MB.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] pSrc Pointer to the source reference frame buffer
+ * [in] srcStep Reference frame step in byte
+ * [in] dstStep Destination frame step in byte. Must be multiple of roi.width.
+ * [in] dx Fractional part of horizontal motion vector component
+ * in 1/8 pixel unit;valid in the range [0,7]
+ * [in] dy Fractional part of vertical motion vector component
+ * in 1/8 pixel unit;valid in the range [0,7]
+ * [in] roi Dimension of the interpolation region;the parameters roi.width and roi.height must
+ * be equal to either 2, 4, or 8.
+ * [out] pDst Pointer to the destination frame buffer.
+ * if roi.width==2, 2-byte alignment required
+ * if roi.width==4, 4-byte alignment required
+ * if roi.width==8, 8-byte alignment required
+ *
+ * Return Value:
+ * If the function runs without error, it returns OMX_Sts_NoErr.
+ * If one of the following cases occurs, the function returns OMX_Sts_BadArgErr:
+ * pSrc or pDst is NULL.
+ * srcStep or dstStep < 8.
+ * dx or dy is out of range [0-7].
+ * roi.width or roi.height is out of range {2,4,8}.
+ * roi.width is equal to 2, but pDst is not 2-byte aligned.
+ * roi.width is equal to 4, but pDst is not 4-byte aligned.
+ * roi.width is equal to 8, but pDst is not 8 byte aligned.
+ * srcStep or dstStep is not a multiple of 8.
+ *
+ */
+
+OMXResult omxVCM4P10_InterpolateChroma (
+ const OMX_U8* pSrc,
+ OMX_S32 srcStep,
+ OMX_U8* pDst,
+ OMX_S32 dstStep,
+ OMX_S32 dx,
+ OMX_S32 dy,
+ OMXSize roi
+ )
+{
+ return armVCM4P10_Interpolate_Chroma
+ ((OMX_U8*)pSrc, srcStep, pDst, dstStep, roi.width, roi.height, dx, dy);
+}
+
+
+/*****************************************************************************
+ * END OF FILE
+ *****************************************************************************/
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_InterpolateLuma_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_InterpolateLuma_s.s
new file mode 100644
index 0000000..cf611a3
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_InterpolateLuma_s.s
@@ -0,0 +1,426 @@
+;//
+;//
+;// File Name: omxVCM4P10_InterpolateLuma_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 9641
+;// Date: Thursday, February 7, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+;// Function:
+;// omxVCM4P10_InterpolateLuma
+;//
+;// This function implements omxVCM4P10_InterpolateLuma in v6 assembly.
+;// Performs quarter pel interpolation of inter luma MB.
+;// It's assumed that the frame is already padded when calling this function.
+;// Parameters:
+;// [in] pSrc Pointer to the source reference frame buffer
+;// [in] srcStep Reference frame step in byte
+;// [in] dstStep Destination frame step in byte. Must be multiple of roi.width
+;// [in] dx Fractional part of horizontal motion vector
+;// component in 1/4 pixel unit; valid in the range [0,3]
+;// [in] dy Fractional part of vertical motion vector
+;// component in 1/4 pixel unit; valid in the range [0,3]
+;// [in] roi Dimension of the interpolation region;the parameters roi.width and roi.height must
+;// be equal to either 4, 8, or 16.
+;// [out] pDst Pointer to the destination frame buffer.
+;// if roi.width==4, 4-byte alignment required
+;// if roi.width==8, 8-byte alignment required
+;// if roi.width==16, 16-byte alignment required
+;//
+;// Return Value:
+;// If the function runs without error, it returns OMX_Sts_NoErr.
+;// It is assued that following cases are satisfied before calling this function:
+;// pSrc or pDst is not NULL.
+;// srcStep or dstStep >= roi.width.
+;// dx or dy is in the range [0-3].
+;// roi.width or roi.height is not out of range {4, 8, 16}.
+;// If roi.width is equal to 4, Dst is 4 byte aligned.
+;// If roi.width is equal to 8, pDst is 8 byte aligned.
+;// If roi.width is equal to 16, pDst is 16 byte aligned.
+;// srcStep and dstStep is multiple of 8.
+;//
+;//
+
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS ARM1136JS
+
+ EXPORT omxVCM4P10_InterpolateLuma
+
+ IF ARM1136JS
+ IMPORT armVCM4P10_InterpolateLuma_Copy4x4_unsafe
+ IMPORT armVCM4P10_InterpolateLuma_HorAlign9x_unsafe
+ IMPORT armVCM4P10_InterpolateLuma_VerAlign4x_unsafe
+ IMPORT armVCM4P10_Average_4x4_Align0_unsafe
+ IMPORT armVCM4P10_Average_4x4_Align2_unsafe
+ IMPORT armVCM4P10_Average_4x4_Align3_unsafe
+ IMPORT armVCM4P10_InterpolateLuma_HorDiagCopy_unsafe
+ IMPORT armVCM4P10_InterpolateLuma_VerDiagCopy_unsafe
+ ENDIF
+
+ IF ARM1136JS
+ IMPORT armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe
+ IMPORT armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe
+ IMPORT armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe
+ IMPORT armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe
+ ENDIF
+
+
+
+;// Declare input registers
+pSrc RN 0
+srcStep RN 1
+pDst RN 2
+dstStep RN 3
+iHeight RN 4
+iWidth RN 5
+
+;// Declare other intermediate registers
+idx RN 6
+idy RN 7
+index RN 6
+Temp RN 12
+pArgs RN 11
+
+
+ ;// End of CortexA8
+
+;//-------------------------------------------------------------------------------------------------------------------------
+;//-------------------------------------------------------------------------------------------------------------------------
+ IF ARM1136JS
+
+
+ M_ALLOC4 ppDst, 8
+ M_ALLOC4 ppSrc, 8
+ M_ALLOC4 ppArgs, 16
+ M_ALLOC4 pBuffer, 120 ;// 120 = 12x10
+ M_ALLOC8 pInterBuf, 120 ;// 120 = 12*5*2
+ M_ALLOC8 pTempBuf, 32 ;// 32 = 8*4
+
+ ;// Function header
+ ;// Interpolation of luma is implemented by processing block of pixels, size 4x4 at a time.
+ ;// Depending on the values of motion vector fractional parts (dx,dy), one out of 16 cases will be processed.
+ ;// Registers r4, r5, r6 to be preserved by internal unsafe functions
+ ;// r4 - iHeight
+ ;// r5 - iWidth
+ ;// r6 - index
+ M_START omxVCM4P10_InterpolateLuma, r11
+
+;// Declare other intermediate registers
+idx RN 6
+idy RN 7
+index RN 6
+Temp RN 12
+pArgs RN 11
+
+pBuf RN 8
+Height RN 9
+bufStep RN 9
+
+ ;// Define stack arguments
+ M_ARG ptridx, 4
+ M_ARG ptridy, 4
+ M_ARG ptrWidth, 4
+ M_ARG ptrHeight, 4
+
+ ;// Load structure elements of roi
+ M_LDR idx, ptridx
+ M_LDR idy, ptridy
+ M_LDR iWidth, ptrWidth
+ M_LDR iHeight, ptrHeight
+
+ M_PRINTF "roi.width %d\n", iWidth
+ M_PRINTF "roi.height %d\n", iHeight
+
+ ADD index, idx, idy, LSL #2 ;// [index] = [idy][idx]
+ M_ADR pArgs, ppArgs
+
+InterpolateLuma
+Block4x4WidthLoop
+Block4x4HeightLoop
+
+ STM pArgs, {pSrc,srcStep,pDst,dstStep}
+ M_ADR pBuf, pBuffer
+
+ ;// switch table using motion vector as index
+ M_SWITCH index, L
+ M_CASE Case_0
+ M_CASE Case_1
+ M_CASE Case_2
+ M_CASE Case_3
+ M_CASE Case_4
+ M_CASE Case_5
+ M_CASE Case_6
+ M_CASE Case_7
+ M_CASE Case_8
+ M_CASE Case_9
+ M_CASE Case_a
+ M_CASE Case_b
+ M_CASE Case_c
+ M_CASE Case_d
+ M_CASE Case_e
+ M_CASE Case_f
+ M_ENDSWITCH
+
+Case_0
+ ;// Case G
+ M_PRINTF "Case 0 \n"
+
+ BL armVCM4P10_InterpolateLuma_Copy4x4_unsafe
+ B Block4x4LoopEnd
+
+Case_1
+ ;// Case a
+ M_PRINTF "Case 1 \n"
+
+ SUB pSrc, pSrc, #2
+ MOV Height, #4
+ BL armVCM4P10_InterpolateLuma_HorAlign9x_unsafe
+ BL armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe
+ BL armVCM4P10_Average_4x4_Align2_unsafe
+ B Block4x4LoopEnd
+Case_2
+ ;// Case b
+ M_PRINTF "Case 2 \n"
+
+ SUB pSrc, pSrc, #2
+ MOV Height, #4
+ BL armVCM4P10_InterpolateLuma_HorAlign9x_unsafe
+ BL armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe
+ B Block4x4LoopEnd
+Case_3
+ ;// Case c
+ M_PRINTF "Case 3 \n"
+
+ SUB pSrc, pSrc, #2
+ MOV Height, #4
+ BL armVCM4P10_InterpolateLuma_HorAlign9x_unsafe
+ BL armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe
+ BL armVCM4P10_Average_4x4_Align3_unsafe
+ B Block4x4LoopEnd
+Case_4
+ ;// Case d
+ M_PRINTF "Case 4 \n"
+
+ SUB pSrc, pSrc, srcStep, LSL #1
+ MOV Height, #9
+ BL armVCM4P10_InterpolateLuma_VerAlign4x_unsafe
+ BL armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe
+ BL armVCM4P10_Average_4x4_Align0_unsafe
+
+ B Block4x4LoopEnd
+Case_5
+ ;// Case e
+ M_PRINTF "Case 5 \n"
+
+ SUB pSrc, pSrc, #2
+ MOV Height, #4
+ M_ADR pDst, pTempBuf
+ MOV dstStep, #4
+ BL armVCM4P10_InterpolateLuma_HorAlign9x_unsafe
+ BL armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe
+ M_ADR pArgs, ppArgs
+ LDM pArgs, {pSrc, srcStep, pDst, dstStep}
+ SUB pSrc, pSrc, srcStep, LSL #1
+ M_ADR pBuf, pBuffer
+ MOV Height, #9
+ BL armVCM4P10_InterpolateLuma_VerAlign4x_unsafe
+ BL armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe
+ M_ADR pSrc, pTempBuf
+ MOV srcStep, #4
+ BL armVCM4P10_Average_4x4_Align0_unsafe
+
+
+ B Block4x4LoopEnd
+Case_6
+ ;// Case f
+ M_PRINTF "Case 6 \n"
+
+ SUB pSrc, pSrc, #2
+ SUB pSrc, pSrc, srcStep, LSL #1
+ MOV Height, #9
+ BL armVCM4P10_InterpolateLuma_HorAlign9x_unsafe
+ M_ADR pBuf, pInterBuf
+ BL armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe
+ M_ADR idy, pTempBuf
+ BL armVCM4P10_InterpolateLuma_VerDiagCopy_unsafe
+ BL armVCM4P10_Average_4x4_Align0_unsafe
+ B Block4x4LoopEnd
+Case_7
+ ;// Case g
+ M_PRINTF "Case 7 \n"
+
+ SUB pSrc, pSrc, #2
+ MOV Height, #4
+ M_ADR pDst, pTempBuf
+ MOV dstStep, #4
+ BL armVCM4P10_InterpolateLuma_HorAlign9x_unsafe
+ BL armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe
+ M_ADR pArgs, ppArgs
+ LDM pArgs, {pSrc, srcStep, pDst, dstStep}
+ SUB pSrc, pSrc, srcStep, LSL #1
+ ADD pSrc, pSrc, #1
+ M_ADR pBuf, pBuffer
+ MOV Height, #9
+ BL armVCM4P10_InterpolateLuma_VerAlign4x_unsafe
+ BL armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe
+ M_ADR pSrc, pTempBuf
+ MOV srcStep, #4
+ BL armVCM4P10_Average_4x4_Align0_unsafe
+
+ B Block4x4LoopEnd
+Case_8
+ ;// Case h
+ M_PRINTF "Case 8 \n"
+
+ SUB pSrc, pSrc, srcStep, LSL #1
+ MOV Height, #9
+ BL armVCM4P10_InterpolateLuma_VerAlign4x_unsafe
+ BL armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe
+ B Block4x4LoopEnd
+Case_9
+ ;// Case i
+ M_PRINTF "Case 9 \n"
+
+ SUB pSrc, pSrc, #2
+ SUB pSrc, pSrc, srcStep, LSL #1
+ MOV Height, #9
+ BL armVCM4P10_InterpolateLuma_HorAlign9x_unsafe
+ ADD pSrc, pSrc, srcStep, LSL #1
+ M_ADR pBuf, pInterBuf
+ BL armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe
+ M_ADR idy, pTempBuf
+ BL armVCM4P10_InterpolateLuma_HorDiagCopy_unsafe
+ BL armVCM4P10_Average_4x4_Align2_unsafe
+ B Block4x4LoopEnd
+Case_a
+ ;// Case j
+ M_PRINTF "Case a \n"
+
+ SUB pSrc, pSrc, #2
+ SUB pSrc, pSrc, srcStep, LSL #1
+ MOV Height, #9
+ BL armVCM4P10_InterpolateLuma_HorAlign9x_unsafe
+ ADD pSrc, pSrc, srcStep, LSL #1
+ M_ADR pBuf, pInterBuf
+ BL armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe
+ B Block4x4LoopEnd
+Case_b
+ ;// Case k
+ M_PRINTF "Case b \n"
+ SUB pSrc, pSrc, #2
+ SUB pSrc, pSrc, srcStep, LSL #1
+ MOV Height, #9
+ BL armVCM4P10_InterpolateLuma_HorAlign9x_unsafe
+ ADD pSrc, pSrc, srcStep, LSL #1
+ M_ADR pBuf, pInterBuf
+ BL armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe
+ M_ADR idy, pTempBuf
+ BL armVCM4P10_InterpolateLuma_HorDiagCopy_unsafe
+ BL armVCM4P10_Average_4x4_Align3_unsafe
+ B Block4x4LoopEnd
+Case_c
+ ;// Case n
+ M_PRINTF "Case c \n"
+
+ SUB pSrc, pSrc, srcStep, LSL #1
+ MOV Height, #9
+ BL armVCM4P10_InterpolateLuma_VerAlign4x_unsafe
+ BL armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe
+ ADD pSrc, pSrc, srcStep ;// Update pSrc to one row down
+ BL armVCM4P10_Average_4x4_Align0_unsafe
+ B Block4x4LoopEnd
+Case_d
+ ;// Case p
+ M_PRINTF "Case d \n"
+ SUB pSrc, pSrc, #2
+ ADD pSrc, pSrc, srcStep
+ MOV Height, #4
+ M_ADR pDst, pTempBuf
+ MOV dstStep, #4
+ BL armVCM4P10_InterpolateLuma_HorAlign9x_unsafe
+ BL armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe
+ M_ADR pArgs, ppArgs
+ LDM pArgs, {pSrc, srcStep, pDst, dstStep}
+ SUB pSrc, pSrc, srcStep, LSL #1
+ M_ADR pBuf, pBuffer
+ MOV Height, #9
+ BL armVCM4P10_InterpolateLuma_VerAlign4x_unsafe
+ BL armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe
+ M_ADR pSrc, pTempBuf
+ MOV srcStep, #4
+ BL armVCM4P10_Average_4x4_Align0_unsafe
+ B Block4x4LoopEnd
+Case_e
+ ;// Case q
+ M_PRINTF "Case e \n"
+
+ SUB pSrc, pSrc, #2
+ SUB pSrc, pSrc, srcStep, LSL #1
+ MOV Height, #9
+ BL armVCM4P10_InterpolateLuma_HorAlign9x_unsafe
+ M_ADR pBuf, pInterBuf
+ BL armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe
+ M_ADR idy, pTempBuf
+ BL armVCM4P10_InterpolateLuma_VerDiagCopy_unsafe
+ ADD pSrc, pSrc, #4
+ BL armVCM4P10_Average_4x4_Align0_unsafe
+
+ B Block4x4LoopEnd
+Case_f
+ ;// Case r
+ M_PRINTF "Case f \n"
+ SUB pSrc, pSrc, #2
+ ADD pSrc, pSrc, srcStep
+ MOV Height, #4
+ M_ADR pDst, pTempBuf
+ MOV dstStep, #4
+ BL armVCM4P10_InterpolateLuma_HorAlign9x_unsafe
+ BL armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe
+ M_ADR pArgs, ppArgs
+ LDM pArgs, {pSrc, srcStep, pDst, dstStep}
+ SUB pSrc, pSrc, srcStep, LSL #1
+ ADD pSrc, pSrc, #1
+ M_ADR pBuf, pBuffer
+ MOV Height, #9
+ BL armVCM4P10_InterpolateLuma_VerAlign4x_unsafe
+ BL armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe
+ M_ADR pSrc, pTempBuf
+ MOV srcStep, #4
+ BL armVCM4P10_Average_4x4_Align0_unsafe
+
+Block4x4LoopEnd
+
+ ;// Width Loop
+ SUBS iWidth, iWidth, #4
+ M_ADR pArgs, ppArgs
+ LDM pArgs, {pSrc,srcStep,pDst,dstStep} ;// Load arguments
+ ADD pSrc, pSrc, #4
+ ADD pDst, pDst, #4
+ BGT Block4x4WidthLoop
+
+ ;// Height Loop
+ SUBS iHeight, iHeight, #4
+ M_LDR iWidth, ptrWidth
+ M_ADR pArgs, ppArgs
+ ADD pSrc, pSrc, srcStep, LSL #2
+ ADD pDst, pDst, dstStep, LSL #2
+ SUB pSrc, pSrc, iWidth
+ SUB pDst, pDst, iWidth
+ BGT Block4x4HeightLoop
+
+EndOfInterpolation
+ MOV r0, #0
+ M_END
+
+ ENDIF
+
+
+ END
+
\ No newline at end of file
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_PredictIntraChroma_8x8_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_PredictIntraChroma_8x8_s.s
new file mode 100644
index 0000000..34fedd8
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_PredictIntraChroma_8x8_s.s
@@ -0,0 +1,494 @@
+;//
+;//
+;// File Name: omxVCM4P10_PredictIntraChroma_8x8_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 9641
+;// Date: Thursday, February 7, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ EXPORT armVCM4P10_pIndexTable8x8
+
+;// Define the processor variants supported by this file
+
+ M_VARIANTS ARM1136JS
+
+ AREA table, DATA
+;//-------------------------------------------------------
+;// This table for implementing switch case of C in asm by
+;// the mehtod of two levels of indexing.
+;//-------------------------------------------------------
+
+ M_TABLE armVCM4P10_pIndexTable8x8
+ DCD OMX_VC_CHROMA_DC, OMX_VC_CHROMA_HOR
+ DCD OMX_VC_CHROMA_VERT, OMX_VC_CHROMA_PLANE
+
+ M_TABLE armVCM4P10_MultiplierTableChroma8x8,1
+ DCW 3, 2, 1,4
+ DCW -3,-2,-1,0
+ DCW 1, 2, 3,4
+
+ IF ARM1136JS
+
+;//--------------------------------------------
+;// Constants
+;//--------------------------------------------
+
+BLK_SIZE EQU 0x8
+MUL_CONST0 EQU 0x01010101
+MASK_CONST EQU 0x00FF00FF
+MUL_CONST1 EQU 0x80808080
+
+;//--------------------------------------------
+;// Scratch variable
+;//--------------------------------------------
+y RN 12
+pc RN 15
+return RN 0
+pSrcLeft2 RN 1
+pDst2 RN 2
+sum1 RN 6
+sum2 RN 7
+pTable RN 9
+dstStepx2 RN 11
+leftStepx2 RN 14
+outerCount RN 14
+r0x01010101 RN 10
+r0x00FF00FF RN 11
+
+tVal0 RN 0
+tVal1 RN 1
+tVal2 RN 2
+tVal3 RN 3
+tVal4 RN 4
+tVal5 RN 5
+tVal6 RN 6
+tVal7 RN 7
+tVal8 RN 8
+tVal9 RN 9
+tVal10 RN 10
+tVal11 RN 11
+tVal12 RN 12
+tVal14 RN 14
+
+b RN 14
+c RN 12
+
+p2p0 RN 0
+p3p1 RN 1
+p6p4 RN 2
+p7p5 RN 4
+
+pp2pp0 RN 6
+pp3pp1 RN 7
+pp6pp4 RN 8
+pp7pp5 RN 9
+
+p3210 RN 10
+p7654 RN 10
+
+;//--------------------------------------------
+;// Input Arguments
+;//--------------------------------------------
+pSrcLeft RN 0 ;// input pointer
+pSrcAbove RN 1 ;// input pointer
+pSrcAboveLeft RN 2 ;// input pointer
+pDst RN 3 ;// output pointer
+leftStep RN 4 ;// input variable
+dstStep RN 5 ;// input variable
+predMode RN 6 ;// input variable
+availability RN 7 ;// input variable
+
+;//-----------------------------------------------------------------------------------------------
+;// omxVCM4P10_PredictIntraChroma_8x8 starts
+;//-----------------------------------------------------------------------------------------------
+
+ ;// Write function header
+ M_START omxVCM4P10_PredictIntraChroma_8x8, r11
+
+ ;// Define stack arguments
+ M_ARG LeftStep, 4
+ M_ARG DstStep, 4
+ M_ARG PredMode, 4
+ M_ARG Availability, 4
+
+ ;// M_STALL ARM1136JS=4
+
+ LDR pTable,=armVCM4P10_pIndexTable8x8 ;// Load index table for switch case
+
+
+ ;// Load argument from the stack
+ M_LDR predMode, PredMode ;// Arg predMode loaded from stack to reg
+ M_LDR leftStep, LeftStep ;// Arg leftStep loaded from stack to reg
+ M_LDR dstStep, DstStep ;// Arg dstStep loaded from stack to reg
+ M_LDR availability, Availability ;// Arg availability loaded from stack to reg
+
+ MOV y, #BLK_SIZE ;// Outer Loop Count
+ LDR pc, [pTable, predMode, LSL #2] ;// Branch to the case based on preMode
+
+OMX_VC_CHROMA_DC
+ AND availability, availability,#(OMX_VC_UPPER + OMX_VC_LEFT)
+ CMP availability, #(OMX_VC_UPPER + OMX_VC_LEFT) ;// if(availability & (#OMX_VC_UPPER | #OMX_VC_LEFT))
+ LDR r0x01010101, =MUL_CONST0
+ BNE TST_UPPER ;// Jump to Upper if not both
+ LDM pSrcAbove,{tVal8,tVal9} ;// tVal 8 to 9 = pSrcAbove[0 to 7]
+
+ ADD leftStepx2, leftStep,leftStep ;// leftStepx2 = 2 * leftStep
+ ADD pSrcLeft2, pSrcLeft, leftStep ;// pSrcLeft2 = pSrcLeft + leftStep
+
+ ;// M_STALL ARM1136JS=1
+
+ UXTB16 tVal7, tVal8 ;// pSrcAbove[0, 2]
+ UXTB16 tVal8, tVal8, ROR #8 ;// pSrcAbove[1, 3]
+ UADD16 sum1, tVal7, tVal8 ;// pSrcAbove[0, 2] + pSrcAbove[1, 3]
+
+ UXTB16 tVal7, tVal9 ;// pSrcAbove[4, 6]
+ UXTB16 tVal9, tVal9, ROR #8 ;// pSrcAbove[5, 7]
+ UADD16 sum2, tVal7, tVal9 ;// pSrcAbove[0, 2] + pSrcAbove[4, 6]
+ ADD sum1, sum1, sum1, LSR #16 ;// sum(pSrcAbove[0] to pSrcAbove[3])
+ ADD sum2, sum2, sum2, LSR #16 ;// sum(pSrcAbove[4] to pSrcAbove[7])
+ UXTH sum1, sum1 ;// upsum1 (Clear the top junk bits)
+ UXTH sum2, sum2 ;// upsum2 (Clear the top junk bits)
+
+ M_LDRB tVal8, [pSrcLeft], +leftStepx2 ;// tVal8 = pSrcLeft[0]
+ M_LDRB tVal9, [pSrcLeft2], +leftStepx2 ;// tVal9 = pSrcLeft[1]
+ M_LDRB tVal4, [pSrcLeft], +leftStepx2 ;// tVal4 = pSrcLeft[2]
+ M_LDRB tVal12,[pSrcLeft2], +leftStepx2 ;// tVal12= pSrcLeft[3]
+ ADD tVal2, tVal8, tVal9 ;// tVal14 = tVal8 + tVal9
+
+ M_LDRB tVal8, [pSrcLeft], +leftStepx2 ;// tVal8 = pSrcLeft[4]
+ M_LDRB tVal9, [pSrcLeft2], +leftStepx2 ;// tVal9 = pSrcLeft[5]
+ ADD tVal14, tVal4, tVal12 ;// tVal14 = tVal4 + tVal12
+
+ LDRB tVal4, [pSrcLeft] ;// tVal4 = pSrcLeft[6]
+ LDRB tVal12,[pSrcLeft2] ;// tVal12= pSrcLeft[7]
+ ADD tVal8, tVal8, tVal9 ;// tVal8 = tVal8 + tVal9
+ ADD tVal2, tVal2, tVal14 ;// leftsum1 = sum(pSrcLeft[0] to pSrcLeft[3])
+ ADD tVal4, tVal4, tVal12 ;// tVal4 = tVal4 + tVal12
+ ADD tVal14, tVal8, tVal4 ;// leftsum2 = sum(pSrcLeft[4] to pSrcLeft[7])
+ ADD tVal8, tVal14, #2 ;// tVal8 = leftsum2 + 2
+ ADD tVal9, sum2, #2 ;// tVal8 = upsum2 + 2
+ ADD sum1, sum1, tVal2 ;// sum1 = upsum1 + leftsum1
+ ADD sum2, sum2, tVal14 ;// sum2 = upsum2 + leftsum2
+ ADD sum1, sum1, #4 ;// (sum1 + 4)
+ ADD sum2, sum2, #4 ;// (sum2 + 4)
+ MOV sum1, sum1, LSR #3 ;// (sum1 + 4)>>3
+ MOV tVal9, tVal9, LSR #2 ;// (tVal9 + 2)>>2
+ MOV tVal8, tVal8, LSR #2 ;// (tVal8 + 2)>>2
+ MOV sum2, sum2, LSR #3 ;// (sum2 + 4)>>3
+
+ MUL tVal0, sum1, r0x01010101 ;// replicate the val in all the bytes
+ MUL tVal1, tVal9,r0x01010101 ;// replicate the val in all the bytes
+ MUL tVal8, tVal8,r0x01010101 ;// replicate the val in all the bytes
+ MUL tVal9, sum2, r0x01010101 ;// replicate the val in all the bytes
+
+ M_STRD tVal0, tVal1, [pDst], dstStep ;// pDst[0 to 7] = tVal 0 to 1
+ M_STRD tVal0, tVal1, [pDst], dstStep ;// pDst[8 to 15] = tVal 0 to 1
+ M_STRD tVal0, tVal1, [pDst], dstStep ;// pDst[16 to 23] = tVal 0 to 1
+ M_STRD tVal0, tVal1, [pDst], dstStep ;// pDst[24 to 31] = tVal 0 to 1
+
+ M_STRD tVal8, tVal9, [pDst], dstStep ;// pDst[32 to 39] = tVal 8 to 9
+ M_STRD tVal8, tVal9, [pDst], dstStep ;// pDst[40 to 47] = tVal 8 to 9
+ M_STRD tVal8, tVal9, [pDst], dstStep ;// pDst[48 to 55] = tVal 8 to 9
+ M_STRD tVal8, tVal9, [pDst], dstStep ;// pDst[56 to 63] = tVal 8 to 9
+ MOV return, #OMX_Sts_NoErr
+ M_EXIT
+
+TST_UPPER
+
+ ;// M_STALL ARM1136JS=3
+
+ CMP availability, #OMX_VC_UPPER ;// if(availability & #OMX_VC_UPPER)
+
+ BNE TST_LEFT ;// Jump to Left if not upper
+ LDM pSrcAbove,{tVal8,tVal9} ;// tVal 8 to 9 = pSrcAbove[0 to 7]
+
+ ;// M_STALL ARM1136JS=3
+
+ UXTB16 tVal7, tVal8 ;// pSrcAbove[0, 2]
+ UXTB16 tVal8, tVal8, ROR #8 ;// pSrcAbove[1, 3]
+ UADD16 sum1, tVal7, tVal8 ;// pSrcAbove[0, 2] + pSrcAbove[1, 3]
+
+ UXTB16 tVal7, tVal9 ;// pSrcAbove[4, 6]
+ UXTB16 tVal9, tVal9, ROR #8 ;// pSrcAbove[5, 7]
+ UADD16 sum2, tVal7, tVal9 ;// pSrcAbove[0, 2] + pSrcAbove[4, 6]
+
+ ADD sum1, sum1, sum1, LSR #16 ;// sum(pSrcAbove[0] to pSrcAbove[3])
+ ADD sum2, sum2, sum2, LSR #16 ;// sum(pSrcAbove[4] to pSrcAbove[7])
+
+ UXTH sum1, sum1 ;// upsum1 (Clear the top junk bits)
+ UXTH sum2, sum2 ;// upsum2 (Clear the top junk bits)
+
+ ADD sum1, sum1, #2 ;// sum1 + 2
+ ADD sum2, sum2, #2 ;// sum2 + 2
+
+ MOV sum1, sum1, LSR #2 ;// (sum1 + 2)>>2
+ MOV sum2, sum2, LSR #2 ;// (sum2 + 2)>>2
+
+ MUL sum1, sum1,r0x01010101 ;// replicate the val in all the bytes
+ MUL sum2, sum2,r0x01010101 ;// replicate the val in all the bytes
+
+ M_STRD tVal6, tVal7, [pDst], dstStep ;// pDst[0 to 7] = tVal 6 to 7
+ M_STRD tVal6, tVal7, [pDst], dstStep ;// pDst[8 to 15] = tVal 6 to 7
+ M_STRD tVal6, tVal7, [pDst], dstStep ;// pDst[16 to 23] = tVal 6 to 7
+ M_STRD tVal6, tVal7, [pDst], dstStep ;// pDst[24 to 31] = tVal 6 to 7
+ M_STRD tVal6, tVal7, [pDst], dstStep ;// pDst[32 to 39] = tVal 6 to 7
+ M_STRD tVal6, tVal7, [pDst], dstStep ;// pDst[40 to 47] = tVal 6 to 7
+ M_STRD tVal6, tVal7, [pDst], dstStep ;// pDst[48 to 55] = tVal 6 to 7
+ M_STRD tVal6, tVal7, [pDst], dstStep ;// pDst[56 to 63] = tVal 6 to 7
+ MOV return, #OMX_Sts_NoErr
+ M_EXIT
+
+TST_LEFT
+ ;// M_STALL ARM1136JS=3
+
+ CMP availability, #OMX_VC_LEFT
+ BNE TST_COUNT0
+ ADD leftStepx2, leftStep,leftStep ;// leftStepx2 = 2 * leftStep
+ ADD pSrcLeft2, pSrcLeft, leftStep ;// pSrcLeft2 = pSrcLeft + leftStep
+
+ M_LDRB tVal8, [pSrcLeft], +leftStepx2 ;// tVal8 = pSrcLeft[0]
+ M_LDRB tVal9, [pSrcLeft2], +leftStepx2 ;// tVal9 = pSrcLeft[1]
+ M_LDRB tVal4, [pSrcLeft], +leftStepx2 ;// tVal4 = pSrcLeft[2]
+ M_LDRB tVal12,[pSrcLeft2], +leftStepx2 ;// tVal12= pSrcLeft[3]
+
+ ADD tVal6, tVal8, tVal9 ;// tVal6 = tVal8 + tVal9
+
+ M_LDRB tVal8, [pSrcLeft], +leftStepx2 ;// tVal8 = pSrcLeft[4]
+ ADD tVal7, tVal4, tVal12 ;// tVal7 = tVal4 + tVal12
+ M_LDRB tVal9, [pSrcLeft2], +leftStepx2 ;// tVal9 = pSrcLeft[5]
+ M_LDRB tVal4, [pSrcLeft], +leftStepx2 ;// tVal4 = pSrcLeft[6]
+ M_LDRB tVal12,[pSrcLeft2], +leftStepx2 ;// tVal12= pSrcLeft[7]
+
+ ADD tVal8, tVal8, tVal9 ;// tVal8 = tVal8 + tVal9
+ ADD sum1, tVal6, tVal7 ;// sum1 = sum(pSrcLeft[0] to pSrcLeft[3])
+ ADD tVal4, tVal4, tVal12 ;// tVal4 = tVal4 + tVal12
+ ADD sum2, tVal8, tVal4 ;// sum2 = sum(pSrcLeft[4] to pSrcLeft[7])
+
+ ADD sum1, sum1, #2 ;// sum1 + 2
+ ADD sum2, sum2, #2 ;// sum2 + 2
+
+ MOV sum1, sum1, LSR #2 ;// (sum1 + 2)>>2
+ MOV sum2, sum2, LSR #2 ;// (sum2 + 2)>>2
+
+ MUL tVal6, sum1,r0x01010101 ;// replicate the val in all the bytes
+ MUL tVal8, sum2,r0x01010101 ;// replicate the val in all the bytes
+
+ ;// M_STALL ARM1136JS=1
+ MOV tVal7,tVal6 ;// tVal7 = sum1
+ MOV tVal9,tVal8 ;// tVal9 = sum2
+
+ M_STRD tVal6, tVal7, [pDst], dstStep ;// pDst[0 to 7] = tVal 6 to 7
+ M_STRD tVal6, tVal7, [pDst], dstStep ;// pDst[8 to 15] = tVal 6 to 7
+ M_STRD tVal6, tVal7, [pDst], dstStep ;// pDst[16 to 23] = tVal 6 to 7
+ M_STRD tVal6, tVal7, [pDst], dstStep ;// pDst[24 to 31] = tVal 6 to 7
+
+ M_STRD tVal8, tVal9, [pDst], dstStep ;// pDst[32 to 39] = tVal 8 to 9
+ M_STRD tVal8, tVal9, [pDst], dstStep ;// pDst[40 to 47] = tVal 8 to 9
+ M_STRD tVal8, tVal9, [pDst], dstStep ;// pDst[48 to 55] = tVal 8 to 9
+ M_STRD tVal8, tVal9, [pDst], dstStep ;// pDst[56 to 63] = tVal 8 to 9
+
+ MOV return, #OMX_Sts_NoErr
+ M_EXIT ;// Macro to exit midway-break frm case
+
+TST_COUNT0
+ LDR sum1, =MUL_CONST1 ;// sum1 = 0x80808080 if(count == 0)
+
+ ;// M_STALL ARM1136JS=2
+
+ MOV tVal7, sum1 ;// tVal7 = sum1
+
+ M_STRD tVal6, tVal7, [pDst], dstStep ;// pDst[0 to 7] = tVal 6 to 7
+ M_STRD tVal6, tVal7, [pDst], dstStep ;// pDst[8 to 15] = tVal 6 to 7
+ M_STRD tVal6, tVal7, [pDst], dstStep ;// pDst[16 to 23] = tVal 6 to 7
+ M_STRD tVal6, tVal7, [pDst], dstStep ;// pDst[24 to 31] = tVal 6 to 7
+ M_STRD tVal6, tVal7, [pDst], dstStep ;// pDst[32 to 39] = tVal 6 to 7
+ M_STRD tVal6, tVal7, [pDst], dstStep ;// pDst[40 to 47] = tVal 6 to 7
+ M_STRD tVal6, tVal7, [pDst], dstStep ;// pDst[48 to 55] = tVal 6 to 7
+ M_STRD tVal6, tVal7, [pDst], dstStep ;// pDst[56 to 63] = tVal 6 to 7
+
+ MOV return, #OMX_Sts_NoErr
+ M_EXIT ;// Macro to exit midway-break frm case
+
+OMX_VC_CHROMA_HOR
+
+ ;// M_STALL ARM1136JS=2
+
+ ADD pSrcLeft2, pSrcLeft, leftStep ;// pSrcLeft2 = pSrcLeft + leftStep
+ ADD leftStepx2, leftStep, leftStep ;// leftStepx2 = leftStep * 2
+ ADD pDst2, pDst, dstStep ;// pDst2 = pDst + dstStep
+ ADD dstStepx2, dstStep, dstStep ;// double dstStep
+ SUB dstStepx2, dstStepx2, #4 ;// double dstStep minus 4
+ LDR r0x01010101, =MUL_CONST0 ;// Const to repeat the byte in reg 4 times
+ M_LDRB tVal6, [pSrcLeft], +leftStepx2 ;// tVal6 = pSrcLeft[0]
+ M_LDRB tVal7, [pSrcLeft2],+leftStepx2 ;// tVal7 = pSrcLeft[1]
+ M_LDRB tVal8, [pSrcLeft], +leftStepx2 ;// tVal8 = pSrcLeft[2]
+ M_LDRB tVal9, [pSrcLeft2],+leftStepx2 ;// tVal9 = pSrcLeft[3]
+ MUL tVal6, tVal6, r0x01010101 ;// replicate the val in all the bytes
+ MUL tVal7, tVal7, r0x01010101 ;// replicate the val in all the bytes
+ MUL tVal8, tVal8, r0x01010101 ;// replicate the val in all the bytes
+ MUL tVal9, tVal9, r0x01010101 ;// replicate the val in all the bytes
+ STR tVal6, [pDst], #+4 ;// store {tVal6} at pDst [0 to 3]
+ STR tVal7, [pDst2], #+4 ;// store {tVal7} at pDst2[0 to 3]
+ M_STR tVal6, [pDst], dstStepx2 ;// store {tVal6} at pDst [4 to 7]
+ M_STR tVal7, [pDst2], dstStepx2 ;// store {tVal7} at pDst2[4 to 7]
+ STR tVal8, [pDst], #+4 ;// store {tVal6} at pDst [0 to 3]
+ STR tVal9, [pDst2], #+4 ;// store {tVal7} at pDst2[0 to 3]
+ M_STR tVal8, [pDst], dstStepx2 ;// store {tVal6} at pDst [4 to 7]
+ M_STR tVal9, [pDst2], dstStepx2 ;// store {tVal7} at pDst2[4 to 7]
+ M_LDRB tVal6, [pSrcLeft], +leftStepx2 ;// tVal6 = pSrcLeft[4]
+ M_LDRB tVal7, [pSrcLeft2],+leftStepx2 ;// tVal7 = pSrcLeft[5]
+ M_LDRB tVal8, [pSrcLeft], +leftStepx2 ;// tVal8 = pSrcLeft[6]
+ M_LDRB tVal9, [pSrcLeft2],+leftStepx2 ;// tVal9 = pSrcLeft[7]
+ MUL tVal6, tVal6, r0x01010101 ;// replicate the val in all the bytes
+ MUL tVal7, tVal7, r0x01010101 ;// replicate the val in all the bytes
+ MUL tVal8, tVal8, r0x01010101 ;// replicate the val in all the bytes
+ MUL tVal9, tVal9, r0x01010101 ;// replicate the val in all the bytes
+ STR tVal6, [pDst], #+4 ;// store {tVal6} at pDst [0 to 3]
+ STR tVal7, [pDst2], #+4 ;// store {tVal7} at pDst2[0 to 3]
+ M_STR tVal6, [pDst], dstStepx2 ;// store {tVal6} at pDst [4 to 7]
+ M_STR tVal7, [pDst2], dstStepx2 ;// store {tVal7} at pDst2[4 to 7]
+ STR tVal8, [pDst], #+4 ;// store {tVal6} at pDst [0 to 3]
+ STR tVal9, [pDst2], #+4 ;// store {tVal7} at pDst2[0 to 3]
+ M_STR tVal8, [pDst], dstStepx2 ;// store {tVal6} at pDst [4 to 7]
+ M_STR tVal9, [pDst2], dstStepx2 ;// store {tVal7} at pDst2[4 to 7]
+ MOV return, #OMX_Sts_NoErr
+ M_EXIT
+
+OMX_VC_CHROMA_VERT
+
+ ;// M_STALL ARM1136JS=4
+
+ LDMIA pSrcAbove, {tVal6,tVal7} ;// tVal 6 to 7 = pSrcAbove[0 to 7]
+ MOV return, #OMX_Sts_NoErr
+
+ M_STRD tVal6, tVal7, [pDst], dstStep ;// pDst[0 to 7] = tVal 6 to 7
+ M_STRD tVal6, tVal7, [pDst], dstStep ;// pDst[8 to 15] = tVal 6 to 7
+ M_STRD tVal6, tVal7, [pDst], dstStep ;// pDst[16 to 23] = tVal 6 to 7
+ M_STRD tVal6, tVal7, [pDst], dstStep ;// pDst[24 to 31] = tVal 6 to 7
+ M_STRD tVal6, tVal7, [pDst], dstStep ;// pDst[32 to 39] = tVal 6 to 7
+ M_STRD tVal6, tVal7, [pDst], dstStep ;// pDst[40 to 47] = tVal 6 to 7
+ M_STRD tVal6, tVal7, [pDst], dstStep ;// pDst[48 to 55] = tVal 6 to 7
+ M_STRD tVal6, tVal7, [pDst], dstStep ;// pDst[56 to 63] = tVal 6 to 7
+
+ M_EXIT ;// Macro to exit midway-break frm case
+
+OMX_VC_CHROMA_PLANE
+
+ ;// M_STALL ARM1136JS=3
+
+ RSB tVal14, leftStep, leftStep, LSL #3 ;// 7*leftStep
+ LDRB tVal7, [pSrcAbove, #+7] ;// pSrcAbove[7]
+ LDRB tVal6, [pSrcLeft, +tVal14] ;// pSrcLeft[7*leftStep]
+ LDRB tVal8, [pSrcAboveLeft] ;// pSrcAboveLeft[0]
+ LDRB tVal9, [pSrcAbove, #+6 ] ;// pSrcAbove[6]
+ LDRB tVal10,[pSrcAbove] ;// pSrcAbove[0]
+ ADD tVal2, tVal7, tVal6 ;// pSrcAbove[7] + pSrcLeft[7*leftStep]
+ SUB tVal6, tVal6, tVal8 ;// V0 = pSrcLeft[7*leftStep] - pSrcAboveLeft[0]
+ SUB tVal7, tVal7, tVal8 ;// H0 = pSrcAbove[7] - pSrcAboveLeft[0]
+ LSL tVal2, tVal2, #4 ;// a = 16 * (pSrcAbove[15] + pSrcLeft[15*lS])
+ ADD tVal2, tVal2, #16 ;// a + 16
+ SUB tVal9, tVal9,tVal10 ;// pSrcAbove[6] - pSrcAbove[0]
+ LDRB tVal8, [pSrcAbove,#+5] ;// pSrcAbove[5]
+ LDRB tVal10,[pSrcAbove,#+1] ;// pSrcAbove[1]
+ ADD tVal9, tVal9, tVal9, LSL #1 ;// H1 = 3 * (pSrcAbove[6] - pSrcAbove[0])
+ ADD tVal7, tVal9, tVal7, LSL #2 ;// H = H1 + H0
+ SUB tVal8, tVal8, tVal10 ;// pSrcAbove[5] - pSrcAbove[1]
+ LDRB tVal9, [pSrcAbove,#+4] ;// pSrcAbove[4]
+ LDRB tVal10,[pSrcAbove,#+2] ;// pSrcAbove[2]
+ ADD tVal7, tVal7, tVal8, LSL #1 ;// H = H + H2
+ SUB tVal11, tVal14,leftStep ;// 6*leftStep
+ ADD tVal11, pSrcLeft, tVal11 ;// pSrcLeft + 6*leftStep
+ MOV tVal12, pSrcLeft ;// pSrcLeft
+ SUB tVal9, tVal9, tVal10 ;// pSrcAbove[4] - pSrcAbove[2]
+ ADD tVal7, tVal7, tVal9 ;// H = H + H3
+ M_LDRB tVal8, [tVal11],-leftStep ;// pSrcLeft[6*leftStep]
+ M_LDRB tVal10,[tVal12],+leftStep ;// pSrcLeft[0]
+ ADD tVal7, tVal7, tVal7, LSL #4 ;// 17 * H
+ ADD tVal7, tVal7, #16 ;// 17 * H + 16
+ SUB tVal8, tVal8, tVal10 ;// pSrcLeft[6*leftStep] - pSrcLeft[0]
+ ASR b, tVal7, #5 ;// b = (17 * H + 16) >> 5
+ ADD tVal8, tVal8, tVal8, LSL #1 ;// V1 = 3 * (pSrcLeft[6*leftStep] - pSrcLeft[0])
+ ADD tVal6, tVal8, tVal6, LSL #2 ;// V = V0 +V1
+ M_LDRB tVal8, [tVal11],-leftStep ;// pSrcLeft[5*leftStep]
+ M_LDRB tVal10,[tVal12],+leftStep ;// pSrcLeft[leftStep]
+ ADD tVal7, b, b, LSL #1 ;// 3*b
+ SUB tVal2, tVal2, tVal7 ;// a + 16 - 3*b
+ SUB tVal7, tVal8, tVal10 ;// pSrcLeft[5*leftStep] - pSrcLeft[leftStep]
+ M_LDRB tVal8, [tVal11],-leftStep ;// pSrcLeft[4*leftStep]
+ M_LDRB tVal10,[tVal12],+leftStep ;// pSrcLeft[2*leftStep]
+ ADD tVal6, tVal6, tVal7, LSL #1 ;// V = V + V2
+ LDR r0x00FF00FF, =MASK_CONST ;// r0x00FF00FF = 0x00FF00FF
+ SUB tVal7, tVal8, tVal10 ;// pSrcLeft[4*leftStep] - pSrcLeft[2*leftStep]
+ ADD tVal6, tVal6, tVal7 ;// V = V + V7
+ SUB dstStep, dstStep, #4 ;// dstStep - 4
+ ADD tVal6, tVal6, tVal6, LSL #4 ;// 17*V
+ ADD tVal6, tVal6, #16 ;// 17*V + 16
+
+ ;// M_STALL ARM1136JS=1
+
+ ASR c, tVal6, #5 ;// c = (17*V + 16)>>5
+
+ ;// M_STALL ARM1136JS=1
+
+ ADD tVal6, c, c, LSL #1 ;// 3*c
+ UXTH c, c ;// only in half word
+ SUB tVal6, tVal2, tVal6 ;// a - 3*b - 3*c + 16
+ ORR c, c, c, LSL #16 ;// c c
+ ADD tVal7, b, b ;// 2b
+ ADD tVal2, tVal6, tVal7 ;// pp2 = d + 2*b
+ ADD tVal7, tVal7, b ;// 3b
+ ORR p2p0, tVal6, tVal2, LSL #16 ;// p2p0 = pack {p2, p0}
+ UXTH b, b
+ UXTH tVal7, tVal7
+ ORR b, b, b, LSL #16 ;// {b,b}
+ ORR tVal7, tVal7, tVal7, LSL #16 ;// {3b,3b}
+ SADD16 p3p1, p2p0, b ;// p3p1 = p2p0 + {b,b}
+ SADD16 p6p4, p3p1, tVal7 ;// p6p4 = p3p1 + {3b,3b}
+ SADD16 p7p5, p6p4, b ;// p7p5 = p6p4 + {b,b}
+ MOV outerCount, #BLK_SIZE ;// Outer Loop Count
+
+LOOP_PLANE
+
+ USAT16 p7p5, #13, p7p5 ;// clip13(p7) clip13(p5)
+ USAT16 p6p4, #13, p6p4 ;// clip13(p6) clip13(p4)
+ USAT16 p3p1, #13, p3p1 ;// clip13(p3) clip13(p1)
+ USAT16 p2p0, #13, p2p0 ;// clip13(p2) clip13(p0)
+
+ AND pp7pp5, r0x00FF00FF, p7p5, ASR #5 ;// clip8(p7) clip8(p5)
+ AND pp6pp4, r0x00FF00FF, p6p4, ASR #5 ;// clip8(p6) clip8(p4)
+ AND pp3pp1, r0x00FF00FF, p3p1, ASR #5 ;// clip8(p3) clip8(p1)
+ AND pp2pp0, r0x00FF00FF, p2p0, ASR #5 ;// clip8(p2) clip8(p0)
+
+ SUBS outerCount, outerCount, #1 ;// outerCount--
+
+ ORR p3210, pp2pp0, pp3pp1, LSL #8 ;// pack {p3,p2, p1, p0}
+ STR p3210, [pDst], #4 ;// store {pDst[0] to pDst[3]}
+
+ ORR p7654, pp6pp4, pp7pp5, LSL #8 ;// pack {p7,p6, p5, p4}
+ M_STR p7654, [pDst], dstStep ;// store {pDst[4] to pDst[7]}
+
+ SADD16 p7p5, p7p5, c ;// {p7 + c}, {p5 + c}
+ SADD16 p6p4, p6p4, c ;// {p6 + c}, {p4 + c}
+ SADD16 p3p1, p3p1, c ;// {p3 + c}, {p1 + c}
+ SADD16 p2p0, p2p0, c ;// {p2 + c}, {p0 + c}
+
+ BNE LOOP_PLANE ;// Loop for 8 times
+ MOV return, #OMX_Sts_NoErr
+ M_END
+
+ ENDIF ;// ARM1136JS
+
+
+
+ END
+;//-----------------------------------------------------------------------------------------------
+;// omxVCM4P10_PredictIntraChroma_8x8 ends
+;//-----------------------------------------------------------------------------------------------
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_PredictIntra_16x16_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_PredictIntra_16x16_s.s
new file mode 100644
index 0000000..1557208
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_PredictIntra_16x16_s.s
@@ -0,0 +1,501 @@
+;//
+;//
+;// File Name: omxVCM4P10_PredictIntra_16x16_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 9641
+;// Date: Thursday, February 7, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS ARM1136JS
+
+;//-------------------------------------------------------
+;// This table for implementing switch case of C in asm by
+;// the mehtod of two levels of indexing.
+;//-------------------------------------------------------
+
+ M_TABLE armVCM4P10_pIndexTable16x16
+ DCD OMX_VC_16X16_VERT, OMX_VC_16X16_HOR
+ DCD OMX_VC_16X16_DC, OMX_VC_16X16_PLANE
+
+ IF ARM1136JS
+
+;//--------------------------------------------
+;// Constants
+;//--------------------------------------------
+BLK_SIZE EQU 0x10
+MUL_CONST0 EQU 0x01010101
+MUL_CONST1 EQU 0x00060004
+MUL_CONST2 EQU 0x00070005
+MUL_CONST3 EQU 0x00030001
+MASK_CONST EQU 0x00FF00FF
+
+;//--------------------------------------------
+;// Scratch variable
+;//--------------------------------------------
+y RN 12
+pc RN 15
+
+return RN 0
+innerCount RN 0
+outerCount RN 1
+pSrcLeft2 RN 1
+pDst2 RN 2
+sum RN 6
+pTable RN 9
+temp1 RN 10
+temp2 RN 12
+cMul1 RN 11
+cMul2 RN 12
+count RN 12
+dstStepx2 RN 11
+leftStepx2 RN 14
+r0x01010101 RN 10
+r0x00FF00FF RN 11
+
+tVal0 RN 0
+tVal1 RN 1
+tVal2 RN 2
+tVal3 RN 3
+tVal4 RN 4
+tVal5 RN 5
+tVal6 RN 6
+tVal7 RN 7
+tVal8 RN 8
+tVal9 RN 9
+tVal10 RN 10
+tVal11 RN 11
+tVal12 RN 12
+tVal14 RN 14
+
+b RN 12
+c RN 14
+
+p2p0 RN 0
+p3p1 RN 1
+p6p4 RN 2
+p7p5 RN 4
+p10p8 RN 6
+p11p9 RN 7
+p14p12 RN 8
+p15p13 RN 9
+
+p3210 RN 10
+p7654 RN 10
+p111098 RN 10
+p15141312 RN 10
+
+;//--------------------------------------------
+;// Declare input registers
+;//--------------------------------------------
+pSrcLeft RN 0 ;// input pointer
+pSrcAbove RN 1 ;// input pointer
+pSrcAboveLeft RN 2 ;// input pointer
+pDst RN 3 ;// output pointer
+leftStep RN 4 ;// input variable
+dstStep RN 5 ;// input variable
+predMode RN 6 ;// input variable
+availability RN 7 ;// input variable
+
+;//-----------------------------------------------------------------------------------------------
+;// omxVCM4P10_PredictIntra_16x16 starts
+;//-----------------------------------------------------------------------------------------------
+
+ ;// Write function header
+ M_START omxVCM4P10_PredictIntra_16x16, r11
+
+ ;// Define stack arguments
+ M_ARG LeftStep, 4
+ M_ARG DstStep, 4
+ M_ARG PredMode, 4
+ M_ARG Availability, 4
+
+ ;// M_STALL ARM1136JS=4
+
+ LDR pTable,=armVCM4P10_pIndexTable16x16 ;// Load index table for switch case
+
+ ;// Load argument from the stack
+ M_LDR predMode, PredMode ;// Arg predMode loaded from stack to reg
+ M_LDR leftStep, LeftStep ;// Arg leftStep loaded from stack to reg
+ M_LDR dstStep, DstStep ;// Arg dstStep loaded from stack to reg
+ M_LDR availability, Availability ;// Arg availability loaded from stack to reg
+
+ MOV y, #BLK_SIZE ;// Outer Loop Count
+ LDR pc, [pTable, predMode, LSL #2] ;// Branch to the case based on preMode
+
+OMX_VC_16X16_VERT
+ LDM pSrcAbove, {tVal6,tVal7,tVal8,tVal9};// tVal 6 to 9 = pSrcAbove[0 to 15]
+ ADD dstStepx2, dstStep, dstStep ;// double dstStep
+ ADD pDst2, pDst, dstStep ;// pDst2- pDst advanced by dstStep
+
+ ;// M_STALL ARM1136JS=2 ;// Stall outside the loop
+
+LOOP_VERT
+ STM pDst, {tVal6,tVal7,tVal8,tVal9} ;// pDst[0 to 15] = tVal 6 to 9
+ SUBS y, y, #2 ;// y--
+ ADD pDst, pDst, dstStepx2 ;// pDst advanced by dstStep
+ STM pDst2, {tVal6,tVal7,tVal8,tVal9} ;// pDst2[16 to 31] = tVal 6 to 9
+ ADD pDst2, pDst2, dstStepx2 ;// pDst advanced by dstStep
+ BNE LOOP_VERT ;// Loop for 8 times
+ MOV return, #OMX_Sts_NoErr
+ M_EXIT
+
+
+OMX_VC_16X16_HOR
+
+ ;// M_STALL ARM1136JS=6
+
+ LDR r0x01010101, =MUL_CONST0 ;// Const to repeat the byte in reg 4 times
+ MOV y, #4 ;// Outer Loop Count
+ M_LDRB tVal6, [pSrcLeft], +leftStep ;// tVal6 = pSrcLeft[0 to 3]
+ ADD pDst2, pDst, dstStep ;// pDst2- pDst advanced by dstStep
+ M_LDRB tVal7, [pSrcLeft], +leftStep ;// tVal1 = pSrcLeft[4 to 7]
+ ADD dstStepx2, dstStep, dstStep ;// double dstStep
+ SUB dstStepx2, dstStepx2, #12 ;// double dstStep minus 12
+
+LOOP_HOR
+ M_LDRB tVal8, [pSrcLeft], +leftStep ;// tVal8 = pSrcLeft[0 to 3]
+ MUL tVal6, tVal6, r0x01010101 ;// replicate the val in all the bytes
+ M_LDRB tVal9, [pSrcLeft], +leftStep ;// tVal9 = pSrcLeft[4 to 7]
+ MUL tVal7, tVal7, r0x01010101 ;// replicate the val in all the bytes
+ SUBS y, y, #1 ;// y--
+ STR tVal6, [pDst], #+4 ;// store {tVal6} at pDst[0 to 3]
+ STR tVal7, [pDst2], #+4 ;// store {tVal7} at pDst2[0 to 3]
+ STR tVal6, [pDst], #+4 ;// store {tVal6} at pDst[4 to 7]
+ STR tVal7, [pDst2], #+4 ;// store {tVal7} at pDst2[4 to 7]
+ MUL tVal8, tVal8, r0x01010101 ;// replicate the val in all the bytes
+ STR tVal6, [pDst], #+4 ;// store {tVal6} at pDst[8 to 11]
+ STR tVal7, [pDst2], #+4 ;// store {tVal7} at pDst2[8 to 11]
+ MUL tVal9, tVal9, r0x01010101 ;// replicate the val in all the bytes
+ M_STR tVal6, [pDst], dstStepx2 ;// store {tVal6} at pDst[12 to 15]
+ M_STR tVal7, [pDst2], dstStepx2 ;// store {tVal7} at pDst2[12 to 15]
+ STR tVal8, [pDst], #+4 ;// store {tVal6} at pDst[0 to 3]
+ STR tVal9, [pDst2], #+4 ;// store {tVal7} at pDst2[0 to 3]
+ STR tVal8, [pDst], #+4 ;// store {tVal6} at pDst[4 to 7]
+ STR tVal9, [pDst2], #+4 ;// store {tVal7} at pDst2[4 to 7]
+ STR tVal8, [pDst], #+4 ;// store {tVal6} at pDst[8 to 11]
+ STR tVal9, [pDst2], #+4 ;// store {tVal7} at pDst2[8 to 11]
+ M_STR tVal8, [pDst], dstStepx2 ;// store {tVal6} at pDst[12 to 15]
+ M_LDRB tVal6, [pSrcLeft], +leftStep ;// tVal6 = pSrcLeft[0 to 3]
+ M_STR tVal9, [pDst2], dstStepx2 ;// store {tVal7} at pDst2[12 to 15]
+ M_LDRB tVal7, [pSrcLeft], +leftStep ;// tVal7 = pSrcLeft[4 to 7]
+ BNE LOOP_HOR ;// Loop for 3 times
+ MOV return, #OMX_Sts_NoErr
+ M_EXIT
+
+OMX_VC_16X16_DC
+
+ ;// M_STALL ARM1136JS=2
+
+ MOV count, #0 ;// count = 0
+ TST availability, #OMX_VC_UPPER ;// if(availability & #OMX_VC_UPPER)
+ BEQ TST_LEFT ;// Jump to Left if not upper
+ LDM pSrcAbove,{tVal8,tVal9,tVal10,tVal11};// tVal 8 to 11 = pSrcAbove[0 to 15]
+ ADD count, count, #1 ;// if upper inc count by 1
+
+ ;// M_STALL ARM1136JS=2
+
+ UXTB16 tVal2, tVal8 ;// pSrcAbove[0, 2]
+ UXTB16 tVal6, tVal9 ;// pSrcAbove[4, 6]
+ UADD16 tVal2, tVal2, tVal6 ;// pSrcAbove[0, 2] + pSrcAbove[4, 6]
+ UXTB16 tVal8, tVal8, ROR #8 ;// pSrcAbove[1, 3]
+ UXTB16 tVal9, tVal9, ROR #8 ;// pSrcAbove[5, 7]
+ UADD16 tVal8, tVal8, tVal9 ;// pSrcAbove[1, 3] + pSrcAbove[5, 7]
+ UADD16 tVal2, tVal2, tVal8 ;// sum(pSrcAbove[0] to pSrcAbove[7])
+
+ UXTB16 tVal8, tVal10 ;// pSrcAbove[8, 10]
+ UXTB16 tVal9, tVal11 ;// pSrcAbove[12, 14]
+ UADD16 tVal8, tVal8, tVal9 ;// pSrcAbove[8, 10] + pSrcAbove[12, 14]
+ UXTB16 tVal10, tVal10, ROR #8 ;// pSrcAbove[9, 11]
+ UXTB16 tVal11, tVal11, ROR #8 ;// pSrcAbove[13, 15]
+ UADD16 tVal10, tVal10, tVal11 ;// pSrcAbove[9, 11] + pSrcAbove[13, 15]
+ UADD16 tVal8, tVal8, tVal10 ;// sum(pSrcAbove[8] to pSrcAbove[15])
+
+ UADD16 tVal2, tVal2, tVal8 ;// sum(pSrcAbove[0] to pSrcAbove[15])
+
+ ;// M_STALL ARM1136JS=1
+
+ ADD tVal2, tVal2, tVal2, LSR #16 ;// sum(pSrcAbove[0] to pSrcAbove[15])
+
+ ;// M_STALL ARM1136JS=1
+
+ UXTH sum, tVal2 ;// Extract the lower half for result
+
+TST_LEFT
+ TST availability, #OMX_VC_LEFT
+ BEQ TST_COUNT
+ ADD leftStepx2, leftStep,leftStep ;// leftStepx2 = 2 * leftStep
+ ADD pSrcLeft2, pSrcLeft, leftStep ;// pSrcLeft2 = pSrcLeft + leftStep
+
+ M_LDRB tVal8, [pSrcLeft], +leftStepx2 ;// tVal8 = pSrcLeft[0]
+ M_LDRB tVal9, [pSrcLeft2], +leftStepx2 ;// tVal9 = pSrcLeft[1]
+ M_LDRB tVal10, [pSrcLeft], +leftStepx2 ;// tVal10= pSrcLeft[2]
+ M_LDRB tVal11, [pSrcLeft2],+leftStepx2 ;// tVal11= pSrcLeft[3]
+ ADD tVal7, tVal8, tVal9 ;// tVal7 = tVal8 + tVal9
+ ADD count, count, #1 ;// Inc Counter if Left is available
+ ADD tVal6, tVal10, tVal11 ;// tVal6 = tVal10 + tVal11
+
+ M_LDRB tVal8, [pSrcLeft], +leftStepx2 ;// tVal8 = pSrcLeft[0]
+ M_LDRB tVal9, [pSrcLeft2], +leftStepx2 ;// tVal9 = pSrcLeft[1]
+ M_LDRB tVal10, [pSrcLeft], +leftStepx2 ;// tVal10= pSrcLeft[2]
+ M_LDRB tVal11, [pSrcLeft2],+leftStepx2 ;// tVal11= pSrcLeft[3]
+ ADD sum, tVal7, tVal6 ;// sum = tVal8 + tVal10
+ ADD tVal8, tVal8, tVal9 ;// tVal8 = tVal8 + tVal9
+ ADD tVal10, tVal10, tVal11 ;// tVal10= tVal10 + tVal11
+ ADD tVal7, tVal8, tVal10 ;// tVal7 = tVal8 + tVal10
+
+
+ M_LDRB tVal8, [pSrcLeft], +leftStepx2 ;// tVal8 = pSrcLeft[0]
+ M_LDRB tVal9, [pSrcLeft2], +leftStepx2 ;// tVal9 = pSrcLeft[1]
+ M_LDRB tVal10, [pSrcLeft], +leftStepx2 ;// tVal10= pSrcLeft[2]
+ M_LDRB tVal11, [pSrcLeft2],+leftStepx2 ;// tVal11= pSrcLeft[3]
+ ADD sum, sum, tVal7 ;// sum = sum + tVal7
+ ADD tVal8, tVal8, tVal9 ;// tVal8 = tVal8 + tVal9
+ ADD tVal10, tVal10, tVal11 ;// tVal10= tVal10 + tVal11
+ ADD tVal7, tVal8, tVal10 ;// tVal7 = tVal8 + tVal10
+
+
+ M_LDRB tVal8, [pSrcLeft], +leftStepx2 ;// tVal8 = pSrcLeft[0]
+ M_LDRB tVal9, [pSrcLeft2], +leftStepx2 ;// tVal9 = pSrcLeft[1]
+ M_LDRB tVal10, [pSrcLeft], +leftStepx2 ;// tVal10= pSrcLeft[2]
+ M_LDRB tVal11, [pSrcLeft2],+leftStepx2 ;// tVal11= pSrcLeft[3]
+ ADD sum, sum, tVal7 ;// sum = sum + tVal7
+ ADD tVal8, tVal8, tVal9 ;// tVal8 = tVal8 + tVal9
+ ADD tVal10, tVal10, tVal11 ;// tVal10= tVal10 + tVal11
+ ADD tVal7, tVal8, tVal10 ;// tVal7 = tVal8 + tVal10
+ ADD sum, sum, tVal7 ;// sum = sum + tVal7
+
+TST_COUNT
+ CMP count, #0 ;// if(count == 0)
+ MOVEQ sum, #128 ;// sum = 128 if(count == 0)
+ BEQ TST_COUNT0 ;// if(count == 0)
+ CMP count, #1 ;// if(count == 1)
+ ADDEQ sum, sum, #8 ;// sum += 8 if(count == 1)
+ ADDNE sum, sum, tVal2 ;// sum = sumleft + sumupper
+ ADDNE sum, sum, #16 ;// sum += 16 if(count == 2)
+
+ ;// M_STALL ARM1136JS=1
+
+ UXTH sum, sum ;// sum only byte rest cleared
+
+ ;// M_STALL ARM1136JS=1
+
+ LSREQ sum, sum, #4 ;// sum >> 4 if(count == 1)
+
+ ;// M_STALL ARM1136JS=1
+
+ LSRNE sum, sum, #5 ;// sum >> 5 if(count == 2)
+
+TST_COUNT0
+
+ ;// M_STALL ARM1136JS=1
+
+ ORR sum, sum, sum, LSL #8 ;// sum replicated in two halfword
+
+ ;// M_STALL ARM1136JS=1
+
+ ORR tVal6, sum, sum, LSL #16 ;// sum replicated in all bytes
+ CPY tVal7, tVal6 ;// tVal1 = tVal0
+ CPY tVal8, tVal6 ;// tVal2 = tVal0
+ CPY tVal9, tVal6 ;// tVal3 = tVal0
+ ADD dstStepx2, dstStep, dstStep ;// double dstStep
+ ADD pDst2, pDst, dstStep ;// pDst2- pDst advanced by dstStep
+ MOV y, #BLK_SIZE ;// Outer Loop Count
+
+LOOP_DC
+ STM pDst, {tVal6,tVal7,tVal8,tVal9} ;// pDst[0 to 15] = tVal 6 to 9
+ SUBS y, y, #2 ;// y--
+ ADD pDst, pDst, dstStepx2 ;// pDst advanced by dstStep
+ STM pDst2, {tVal6,tVal7,tVal8,tVal9} ;// pDst2[16 to 31] = tVal 6 to 9
+ ADD pDst2, pDst2, dstStepx2 ;// pDst advanced by dstStep
+ BNE LOOP_DC ;// Loop for 8 times
+
+ MOV return, #OMX_Sts_NoErr
+ M_EXIT
+
+OMX_VC_16X16_PLANE
+
+ ;// M_STALL ARM1136JS=3
+ RSB tVal14, leftStep, leftStep, LSL #4 ;// tVal14 = 15*leftStep
+
+ ;// M_STALL ARM1136JS=2
+ LDRB tVal10, [pSrcLeft, tVal14] ;// tVal10 = pSrcLeft[15*leftStep]
+ LDRB tVal11, [pSrcAboveLeft] ;// tVal11 = pSrcAboveLeft[0]
+ LDRB tVal12, [pSrcAbove, #15]
+
+ ADD tVal2, tVal12, tVal10 ;// tVal2 = pSrcAbove[15] + pSrcLeft[15*leftStep]
+ SUB tVal10, tVal10, tVal11 ;// tVal10 = V0 = pSrcLeft[15*leftStep] - pSrcAboveLeft[0]
+ SUB tVal11, tVal12, tVal11 ;// tVal11 = H0 = pSrcAbove[15] - pSrcAboveLeft[0]
+ MOV tVal2, tVal2, LSL #4 ;// tVal2 = a = 16 * (pSrcAbove[15] + pSrcLeft[15*leftStep])
+
+ MOV tVal11, tVal11, LSL #3 ;// 8*[15]-[-1]
+ LDRB tVal6, [pSrcAbove, #0]
+ LDRB tVal7, [pSrcAbove, #14]
+ SUB tVal8, tVal7, tVal6
+ RSB tVal8, tVal8, tVal8, LSL #3 ;// 7*[14]-[0]
+ ADD tVal11, tVal11, tVal8
+ LDRB tVal6, [pSrcAbove, #1]
+ LDRB tVal7, [pSrcAbove, #13]
+ SUB tVal8, tVal7, tVal6
+ ADD tVal8, tVal8, tVal8
+ ADD tVal8, tVal8, tVal8, LSL #1 ;// 6*[13]-[1]
+ ADD tVal11, tVal11, tVal8
+ LDRB tVal6, [pSrcAbove, #2]
+ LDRB tVal7, [pSrcAbove, #12]
+ SUB tVal8, tVal7, tVal6
+ ADD tVal8, tVal8, tVal8, LSL #2 ;// 5*[12]-[2]
+ ADD tVal11, tVal11, tVal8
+ LDRB tVal6, [pSrcAbove, #3]
+ LDRB tVal7, [pSrcAbove, #11]
+ SUB tVal8, tVal7, tVal6
+ ADD tVal11, tVal11, tVal8, LSL #2 ;// + 4*[11]-[3]
+ LDRB tVal6, [pSrcAbove, #4]
+ LDRB tVal7, [pSrcAbove, #10]
+ SUB tVal8, tVal7, tVal6
+ ADD tVal8, tVal8, tVal8, LSL #1 ;// 3*[10]-[4]
+ ADD tVal11, tVal11, tVal8
+ LDRB tVal6, [pSrcAbove, #5]
+ LDRB tVal7, [pSrcAbove, #9]
+ SUB tVal8, tVal7, tVal6
+ ADD tVal11, tVal11, tVal8, LSL #1 ;// + 2*[9]-[5]
+ LDRB tVal6, [pSrcAbove, #6]
+ LDRB tVal7, [pSrcAbove, #8]
+ SUB tVal8, tVal7, tVal6 ;// 1*[8]-[6]
+ ADD tVal7, tVal11, tVal8
+
+ ADD tVal2, tVal2, #16 ;// tVal2 = a + 16
+ MOV tVal1, pSrcLeft ;// tVal4 = pSrcLeft
+ SUB tVal9, tVal14, leftStep ;// tVal9 = 14*leftStep
+ ADD tVal9, pSrcLeft, tVal9 ;// tVal9 = pSrcLeft + 14*leftStep
+
+ M_LDRB tVal8, [tVal9], -leftStep ;// tVal8 = pSrcLeft[14*leftStep]
+ M_LDRB tVal11, [tVal1], +leftStep ;// tVal11 = pSrcLeft[0]
+ ADD tVal7, tVal7, tVal7, LSL #2 ;// tVal7 = 5 * H
+ ADD tVal7, tVal7, #32 ;// tVal7 = 5 * H + 32
+ SUB tVal8, tVal8, tVal11 ;// tVal8 = pSrcLeft[14*leftStep] - pSrcLeft[0]
+ ASR tVal12, tVal7, #6 ;// tVal12 = b = (5 * H + 32) >> 6
+
+ RSB tVal8, tVal8, tVal8, LSL #3 ;// tVal8 = V1 = 7* (pSrcLeft[14*leftStep]-pSrcLeft[0])
+ ADD tVal6, tVal8, tVal10, LSL #3 ;// tVal6 = V = V0 +V1
+ M_LDRB tVal8, [tVal9], -leftStep ;// tVal8 = pSrcLeft[13*leftStep]
+ M_LDRB tVal10, [tVal1], +leftStep ;// tVal10 = pSrcLeft[leftStep]
+ RSB tVal7, tVal12, tVal12, LSL #3 ;// tVal7 = 7*b
+ SUB tVal2, tVal2, tVal7 ;// tVal2 = a + 16 - 7*b
+ SUB tVal7, tVal8, tVal10 ;// tVal7 = pSrcLeft[13*leftStep] - pSrcLeft[leftStep]
+ M_LDRB tVal8, [tVal9], -leftStep ;// tVal8 = pSrcLeft[12*lS]
+ ADD tVal7, tVal7, tVal7 ;// tVal7 = 2 * (pSrcLeft[13*leftStep] - pSrcLeft[leftStep])
+ M_LDRB tVal10, [tVal1], +leftStep ;// tVal10 = pSrcLeft[2*leftStep]
+ ADD tVal7, tVal7, tVal7, LSL #1 ;// tVal7 = 6 * (pSrcLeft[13*leftStep] - pSrcLeft[leftStep])
+ ADD tVal6, tVal6, tVal7 ;// tVal6 = V = V + V2
+ SUB tVal7, tVal8, tVal10 ;// tVal7 = pSrcLeft[12*leftStep] - pSrcLeft[2*leftStep]
+ M_LDRB tVal8, [tVal9], -leftStep ;// tVal8 = pSrcLeft[11*leftStep]
+ M_LDRB tVal10, [tVal1], +leftStep ;// tVal10 = pSrcLeft[3*leftStep]
+ ADD tVal7, tVal7, tVal7, LSL #2 ;// tVal7 = 5 * (pSrcLeft[12*leftStep] - pSrcLeft[2*leftStep])
+ ADD tVal6, tVal6, tVal7 ;// tVal6 = V = V + V3
+ SUB tVal7, tVal8, tVal10 ;// tVal7 = pSrcLeft[11*leftStep] - pSrcLeft[3*leftStep]
+ M_LDRB tVal8, [tVal9], -leftStep ;// tVal8 = pSrcLeft[10*leftStep]
+ M_LDRB tVal10, [tVal1], +leftStep ;// tVal10 = pSrcLeft[4*leftStep]
+ ADD tVal6, tVal6, tVal7, LSL #2 ;// tVal6 = V = V + V4
+ SUB dstStep, dstStep, #16 ;// tVal5 = dstStep - 16
+ SUB tVal7, tVal8, tVal10 ;// tVal7 = pSrcLeft[10*leftStep] - pSrcLeft[4*leftStep]
+ M_LDRB tVal8, [tVal9], -leftStep ;// tVal8 = pSrcLeft[9*leftStep]
+ M_LDRB tVal10, [tVal1], +leftStep ;// tVal10 = pSrcLeft[5*leftStep]
+ ADD tVal7, tVal7, tVal7, LSL #1 ;// tVal7 = 3 * (pSrcLeft[10*leftStep] - pSrcLeft[4*leftStep])
+ ADD tVal6, tVal6, tVal7 ;// tVal6 = V = V + V5
+ SUB tVal7, tVal8, tVal10 ;// tVal7 = pSrcLeft[9*leftStep] - pSrcLeft[5*leftStep]
+ M_LDRB tVal8, [tVal9], -leftStep ;// tVal8 = pSrcLeft[8*leftStep]
+ M_LDRB tVal10, [tVal1], +leftStep ;// tVal10 = pSrcLeft[6*leftStep]
+ ADD tVal6, tVal6, tVal7, LSL #1 ;// tVal6 = V = V + V6
+
+ ;// M_STALL ARM1136JS=1
+ SUB tVal7, tVal8, tVal10 ;// tVal7 = pSrcLeft[8*leftStep] - pSrcLeft[6*leftStep]
+ ADD tVal6, tVal6, tVal7 ;// tVal6 = V = V + V7
+
+ ;// M_STALL ARM1136JS=1
+ ADD tVal6, tVal6, tVal6, LSL #2 ;// tVal6 = 5*V
+ ADD tVal6, tVal6, #32 ;// tVal6 = 5*V + 32
+
+ ;// M_STALL ARM1136JS=1
+ ASR tVal14, tVal6, #6 ;// tVal14 = c = (5*V + 32)>>6
+
+ ;// M_STALL ARM1136JS=1
+ RSB tVal6, tVal14, tVal14, LSL #3 ;// tVal6 = 7*c
+ UXTH tVal14, tVal14 ;// tVal14 = Cleared the upper half word
+ ADD tVal10, tVal12, tVal12 ;// tVal10 = 2*b
+ ORR tVal14, tVal14, tVal14, LSL #16 ;// tVal14 = {c , c}
+ SUB tVal6, tVal2, tVal6 ;// tVal6 = d = a - 7*b - 7*c + 16
+ ADD tVal1, tVal6, tVal10 ;// tVal1 = pp2 = d + 2*b
+ ADD tVal10, tVal10, tVal12 ;// tVal10 =3*b
+ ORR tVal0, tVal6, tVal1, LSL #16 ;// tval0 = p2p0 = pack {p2, p0}
+ UXTH tVal12, tVal12 ;// tVal12 = Cleared the upper half word
+ UXTH tVal10, tVal10 ;// tVal12 = Cleared the upper half word
+ ORR tVal12, tVal12, tVal12, LSL #16 ;// tVal12 = {b , b}
+ ORR tVal10, tVal10, tVal10, LSL #16 ;// tVal10 = {3b , 3b}
+ SADD16 tVal1, tVal0, tVal12 ;// tVal1 = p3p1 = p2p0 + {b,b}
+ SADD16 tVal2, tVal1, tVal10 ;// tVal2 = p6p4 = p3p1 + {3b,3b}
+ SADD16 tVal4, tVal2, tVal12 ;// tVal4 = p7p5 = p6p4 + {b,b}
+ SADD16 tVal6, tVal4, tVal10 ;// tVal6 = p10p8 = p7p5 + {3b,3b}
+ SADD16 tVal7, tVal6, tVal12 ;// tVal7 = p11p9 = p10p8 + {b,b}
+ SADD16 tVal8, tVal7, tVal10 ;// tVal8 = p14p12 = p11p9 + {3b,3b}
+ SADD16 tVal9, tVal8, tVal12 ;// tVal9 = p15p13 = p14p12 + {b,b}
+ LDR r0x00FF00FF, =MASK_CONST ;// r0x00FF00FF = 0x00FF00FF
+
+LOOP_PLANE
+
+ USAT16 temp2, #13, p3p1
+ USAT16 temp1, #13, p2p0
+ SADD16 p3p1, p3p1, c
+ SADD16 p2p0, p2p0, c
+ AND temp2, r0x00FF00FF, temp2, ASR #5
+ AND temp1, r0x00FF00FF, temp1, ASR #5
+ ORR temp1, temp1, temp2, LSL #8
+ STR temp1, [pDst], #4
+
+ USAT16 temp2, #13, p7p5
+ USAT16 temp1, #13, p6p4
+ SADD16 p7p5, p7p5, c
+ SADD16 p6p4, p6p4, c
+ AND temp2, r0x00FF00FF, temp2, ASR #5
+ AND temp1, r0x00FF00FF, temp1, ASR #5
+ ORR temp1, temp1, temp2, LSL #8
+ STR temp1, [pDst], #4
+
+ USAT16 temp2, #13, p11p9
+ USAT16 temp1, #13, p10p8
+ SADD16 p11p9, p11p9, c
+ SADD16 p10p8, p10p8, c
+ AND temp2, r0x00FF00FF, temp2, ASR #5
+ AND temp1, r0x00FF00FF, temp1, ASR #5
+ ORR temp1, temp1, temp2, LSL #8
+ STR temp1, [pDst], #4
+
+ USAT16 temp2, #13, p15p13
+ USAT16 temp1, #13, p14p12
+ SADD16 p15p13, p15p13, c
+ SADD16 p14p12, p14p12, c
+ AND temp2, r0x00FF00FF, temp2, ASR #5
+ AND temp1, r0x00FF00FF, temp1, ASR #5
+ ORR temp1, temp1, temp2, LSL #8
+ STR temp1, [pDst], #4
+
+ ADDS r0x00FF00FF, r0x00FF00FF, #1<<28 ;// Loop counter value in top 4 bits
+
+ ADD pDst, pDst, dstStep
+
+ BCC LOOP_PLANE ;// Loop for 16 times
+ MOV return, #OMX_Sts_NoErr
+ M_END
+
+ ENDIF ;// ARM1136JS
+
+
+ END
+;-----------------------------------------------------------------------------------------------
+; omxVCM4P10_PredictIntra_16x16 ends
+;-----------------------------------------------------------------------------------------------
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_PredictIntra_4x4_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_PredictIntra_4x4_s.s
new file mode 100644
index 0000000..a90f460
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_PredictIntra_4x4_s.s
@@ -0,0 +1,567 @@
+;//
+;//
+;// File Name: omxVCM4P10_PredictIntra_4x4_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 9641
+;// Date: Thursday, February 7, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+;// Define the processor variants supported by this file
+
+ M_VARIANTS ARM1136JS
+
+;//-------------------------------------------------------
+;// This table for implementing switch case of C in asm by
+;// the mehtod of two levels of indexing.
+;//-------------------------------------------------------
+
+ M_TABLE armVCM4P10_pSwitchTable4x4
+ DCD OMX_VC_4x4_VERT, OMX_VC_4x4_HOR
+ DCD OMX_VC_4x4_DC, OMX_VC_4x4_DIAG_DL
+ DCD OMX_VC_4x4_DIAG_DR, OMX_VC_4x4_VR
+ DCD OMX_VC_4x4_HD, OMX_VC_4x4_VL
+ DCD OMX_VC_4x4_HU
+
+ IF ARM1136JS
+
+;//--------------------------------------------
+;// Constants
+;//--------------------------------------------
+BLK_SIZE EQU 0x8
+MUL_CONST0 EQU 0x01010101
+ADD_CONST1 EQU 0x80808080
+
+;//--------------------------------------------
+;// Scratch variable
+;//--------------------------------------------
+return RN 0
+pTable RN 9
+pc RN 15
+r0x01010101 RN 1
+r0x80808080 RN 0
+
+tVal0 RN 0
+tVal1 RN 1
+tVal2 RN 2
+tVal4 RN 4
+tVal6 RN 6
+tVal7 RN 7
+tVal8 RN 8
+tVal9 RN 9
+tVal10 RN 10
+tVal11 RN 11
+tVal12 RN 12
+tVal14 RN 14
+
+Out0 RN 6
+Out1 RN 7
+Out2 RN 8
+Out3 RN 9
+
+Left0 RN 6
+Left1 RN 7
+Left2 RN 8
+Left3 RN 9
+
+Above0123 RN 12
+Above4567 RN 14
+
+AboveLeft RN 10
+
+;//--------------------------------------------
+;// Declare input registers
+;//--------------------------------------------
+pSrcLeft RN 0 ;// input pointer
+pSrcAbove RN 1 ;// input pointer
+pSrcAboveLeft RN 2 ;// input pointer
+pDst RN 3 ;// output pointer
+leftStep RN 4 ;// input variable
+dstStep RN 5 ;// input variable
+predMode RN 6 ;// input variable
+availability RN 7 ;// input variable
+
+;//-----------------------------------------------------------------------------------------------
+;// omxVCM4P10_PredictIntra_4x4 starts
+;//-----------------------------------------------------------------------------------------------
+
+ ;// Write function header
+ M_START omxVCM4P10_PredictIntra_4x4, r11
+
+ ;// Define stack arguments
+ M_ARG LeftStep, 4
+ M_ARG DstStep, 4
+ M_ARG PredMode, 4
+ M_ARG Availability, 4
+
+ ;// M_STALL ARM1136JS=4
+
+ LDR pTable,=armVCM4P10_pSwitchTable4x4 ;// Load index table for switch case
+
+ ;// Load argument from the stack
+ M_LDR predMode, PredMode ;// Arg predMode loaded from stack to reg
+ M_LDR leftStep, LeftStep ;// Arg leftStep loaded from stack to reg
+ M_LDR dstStep, DstStep ;// Arg dstStep loaded from stack to reg
+ M_LDR availability, Availability ;// Arg availability loaded from stack to reg
+
+ LDR pc, [pTable, predMode, LSL #2] ;// Branch to the case based on preMode
+
+OMX_VC_4x4_VERT
+
+ LDR Above0123, [pSrcAbove] ;// Above0123 = pSrcAbove[0 to 3]
+ M_STR Above0123, [pDst], dstStep ;// pDst[0 to 3] = Above0123
+ M_STR Above0123, [pDst], dstStep ;// pDst[4 to 7] = Above0123
+ M_STR Above0123, [pDst], dstStep ;// pDst[8 to 11] = Above0123
+ STR Above0123, [pDst] ;// pDst[12 to 15] = Above0123
+ MOV return, #OMX_Sts_NoErr
+ M_EXIT ;// Macro to exit midway-break frm case
+
+OMX_VC_4x4_HOR
+
+ ;// M_STALL ARM1136JS=6
+
+ LDR r0x01010101, =MUL_CONST0 ;// Const to repeat the byte in reg 4 times
+ M_LDRB Left0, [pSrcLeft], leftStep ;// Left0 = pSrcLeft[0]
+ M_LDRB Left1, [pSrcLeft], leftStep ;// Left1 = pSrcLeft[1]
+ M_LDRB Left2, [pSrcLeft], leftStep ;// Left2 = pSrcLeft[2]
+ LDRB Left3, [pSrcLeft] ;// Left3 = pSrcLeft[3]
+ MUL Out0, Left0, r0x01010101 ;// replicate the val in all the bytes
+ MUL Out1, Left1, r0x01010101 ;// replicate the val in all the bytes
+ MUL Out2, Left2, r0x01010101 ;// replicate the val in all the bytes
+ MUL Out3, Left3, r0x01010101 ;// replicate the val in all the bytes
+ M_STR Out0, [pDst], dstStep ;// store {Out0} at pDst [0 to 3 ]
+ M_STR Out1, [pDst], dstStep ;// store {Out1} at pDst [4 to 7 ]
+ M_STR Out2, [pDst], dstStep ;// store {Out2} at pDst [8 to 11]
+ STR Out3, [pDst] ;// store {Out3} at pDst [12 to 15]
+ MOV return, #OMX_Sts_NoErr
+ M_EXIT ;// Macro to exit midway-break frm case
+
+OMX_VC_4x4_DC
+
+ ;// M_STALL ARM1136JS=6
+
+ AND availability, availability, #(OMX_VC_UPPER + OMX_VC_LEFT)
+ CMP availability, #(OMX_VC_UPPER + OMX_VC_LEFT)
+ BNE UpperOrLeftOrNoneAvailable ;// Jump to Upper if not both
+ LDR Above0123, [pSrcAbove] ;// Above0123 = pSrcAbove[0 to 3]
+
+ ;// M_STALL ARM1136JS=1
+
+ UXTB16 tVal7, Above0123 ;// pSrcAbove[0, 2]
+ UXTB16 tVal6, Above0123, ROR #8 ;// pSrcAbove[1, 3]
+ UADD16 tVal11, tVal6, tVal7 ;// pSrcAbove[0, 2] + pSrcAbove[1, 3]
+ M_LDRB Left0, [pSrcLeft], leftStep ;// Left0 = pSrcLeft[0]
+ M_LDRB Left1, [pSrcLeft], leftStep ;// Left1 = pSrcLeft[1]
+ ADD tVal11, tVal11, LSR #16 ;// sum(pSrcAbove[0] to pSrcAbove[3])
+ M_LDRB Left2, [pSrcLeft], leftStep ;// Left2 = pSrcLeft[2]
+ LDRB Left3, [pSrcLeft] ;// Left3 = pSrcLeft[3]
+ UXTH tVal11, tVal11 ;// upsum1 (Clear the top junk bits)
+ ADD tVal6, Left0, Left1 ;// tVal6 = Left0 + Left1
+ ADD tVal7, Left2, Left3 ;// tVal7 = Left2 + Left3
+ ADD tVal6, tVal6, tVal7 ;// tVal6 = tVal6 + tVal7
+ ADD Out0, tVal6, tVal11 ;// Out0 = tVal6 + tVal11
+ ADD Out0, Out0, #4 ;// Out0 = Out0 + 4
+ LDR r0x01010101, =MUL_CONST0 ;// 0x01010101
+ MOV Out0, Out0, LSR #3 ;// Out0 = (Out0 + 4)>>3
+
+ ;// M_STALL ARM1136JS=1
+
+ MUL Out0, Out0, r0x01010101 ;// replicate the val in all the bytes
+
+ ;// M_STALL ARM1136JS=1
+
+ MOV return, #OMX_Sts_NoErr
+ M_STR Out0, [pDst], dstStep ;// store {Out0} at pDst [0 to 3 ]
+ M_STR Out0, [pDst], dstStep ;// store {Out0} at pDst [4 to 7 ]
+ M_STR Out0, [pDst], dstStep ;// store {Out0} at pDst [8 to 11]
+ STR Out0, [pDst] ;// store {Out0} at pDst [12 to 15]
+ M_EXIT ;// Macro to exit midway-break frm case
+
+UpperOrLeftOrNoneAvailable
+ ;// M_STALL ARM1136JS=3
+
+ CMP availability, #OMX_VC_UPPER ;// if(availability & #OMX_VC_UPPER)
+ BNE LeftOrNoneAvailable ;// Jump to Left if not upper
+ LDR Above0123, [pSrcAbove] ;// Above0123 = pSrcAbove[0 to 3]
+
+ ;// M_STALL ARM1136JS=3
+
+ UXTB16 tVal7, Above0123 ;// pSrcAbove[0, 2]
+ UXTB16 tVal6, Above0123, ROR #8 ;// pSrcAbove[1, 3]
+ UADD16 Out0, tVal6, tVal7 ;// pSrcAbove[0, 2] + pSrcAbove[1, 3]
+ LDR r0x01010101, =MUL_CONST0 ;// 0x01010101
+ ADD Out0, Out0, LSR #16 ;// sum(pSrcAbove[0] to pSrcAbove[3])
+
+ ;// M_STALL ARM1136JS=1
+
+ UXTH Out0, Out0 ;// upsum1 (Clear the top junk bits)
+ ADD Out0, Out0, #2 ;// Out0 = Out0 + 2
+
+ ;// M_STALL ARM1136JS=1
+
+ MOV Out0, Out0, LSR #2 ;// Out0 = (Out0 + 2)>>2
+
+ ;// M_STALL ARM1136JS=1
+
+ MUL Out0, Out0, r0x01010101 ;// replicate the val in all the bytes
+
+ ;// M_STALL ARM1136JS=1
+
+ MOV return, #OMX_Sts_NoErr
+ M_STR Out0, [pDst], dstStep ;// store {tVal6} at pDst [0 to 3 ]
+ M_STR Out0, [pDst], dstStep ;// store {tVal6} at pDst [4 to 7 ]
+ M_STR Out0, [pDst], dstStep ;// store {tVal6} at pDst [8 to 11]
+ STR Out0, [pDst] ;// store {tVal6} at pDst [12 to 15]
+
+ M_EXIT ;// Macro to exit midway-break frm case
+
+LeftOrNoneAvailable
+ ;// M_STALL ARM1136JS=3
+
+ LDR r0x01010101, =MUL_CONST0 ;// 0x01010101
+ CMP availability, #OMX_VC_LEFT
+ BNE NoneAvailable
+ M_LDRB Left0, [pSrcLeft], leftStep ;// Left0 = pSrcLeft[0]
+ M_LDRB Left1, [pSrcLeft], leftStep ;// Left1 = pSrcLeft[1]
+ M_LDRB Left2, [pSrcLeft], leftStep ;// Left2 = pSrcLeft[2]
+ LDRB Left3, [pSrcLeft] ;// Left3 = pSrcLeft[3]
+ ADD Out0, Left0, Left1 ;// Out0 = Left0 + Left1
+
+ ;// M_STALL ARM1136JS=1
+
+ ADD Out1, Left2, Left3 ;// Out1 = Left2 + Left3
+ ADD Out0, Out0, Out1 ;// Out0 = Out0 + Out1
+ ADD Out0, Out0, #2 ;// Out0 = Out0 + 2
+
+ ;// M_STALL ARM1136JS=1
+
+ MOV Out0, Out0, LSR #2 ;// Out0 = (Out0 + 2)>>2
+
+ ;// M_STALL ARM1136JS=1
+
+ MUL Out0, Out0, r0x01010101 ;// replicate the val in all the bytes
+
+ ;// M_STALL ARM1136JS=1
+
+ MOV return, #OMX_Sts_NoErr
+ M_STR Out0, [pDst], dstStep ;// store {Out0} at pDst [0 to 3 ]
+ M_STR Out0, [pDst], dstStep ;// store {Out0} at pDst [4 to 7 ]
+ M_STR Out0, [pDst], dstStep ;// store {Out0} at pDst [8 to 11]
+ STR Out0, [pDst] ;// store {Out0} at pDst [12 to 15]
+ M_EXIT ;// Macro to exit midway-break frm case
+
+NoneAvailable
+ MOV Out0, #128 ;// Out0 = 128 if(count == 0)
+
+ ;// M_STALL ARM1136JS=5
+
+ MUL Out0, Out0, r0x01010101 ;// replicate the val in all the bytes
+
+ ;// M_STALL ARM1136JS=1
+
+ MOV return, #OMX_Sts_NoErr
+ M_STR Out0, [pDst], dstStep ;// store {Out0} at pDst [0 to 3 ]
+ M_STR Out0, [pDst], dstStep ;// store {Out0} at pDst [4 to 7 ]
+ M_STR Out0, [pDst], dstStep ;// store {Out0} at pDst [8 to 11]
+ STR Out0, [pDst] ;// store {Out0} at pDst [12 to 15]
+ M_EXIT ;// Macro to exit midway-break frm case
+
+OMX_VC_4x4_DIAG_DL
+
+ ;//------------------------------------------------------------------
+ ;// f = (a+2*b+c+2)>>2
+ ;// Calculate as:
+ ;// d = (a + c )>>1
+ ;// e = (d - b')>>1
+ ;// f = e + 128
+ ;//------------------------------------------------------------------
+
+ ;// M_STALL ARM1136JS=3
+
+ TST availability, #OMX_VC_UPPER_RIGHT
+ LDMIA pSrcAbove, {Above0123, Above4567} ;// Above0123, Above4567 = pSrcAbove[0 to 7]
+ LDR r0x80808080, =ADD_CONST1 ;// 0x80808080
+ BNE DLUpperRightAvailable
+ LDR r0x01010101, =MUL_CONST0 ;// 0x01010101
+ MOV tVal7, Above0123, LSR #24 ;// {00, 00, 00, U3 }
+ MOV tVal11, tVal7, LSL #24 ;// {U3, 00, 00, 00 }
+ MUL Out3, tVal7, r0x01010101 ;// {U3, U3, U3, U3 }
+ MOV tVal8, Above0123, LSR #16 ;// {00, 00, U3, U2 }
+ MOV tVal10, Above0123, LSR #8 ;// {00, U3, U2, U1 }
+ MVN tVal10, tVal10 ;// {00', U3', U2', U1'}
+ UHADD8 tVal8, tVal8, Above0123 ;// {xx, xx, d1, d0 }
+ UHADD8 tVal6, Above0123, tVal9 ;// {xx, d2, xx, xx }
+ UHSUB8 tVal8, tVal8, tVal10 ;// {xx, xx, e1, e0 }
+ UHSUB8 tVal6, tVal6, tVal10 ;// {xx, e2, xx, xx }
+ UADD8 tVal8, tVal8, r0x80808080 ;// {xx, xx, f1, f0 }
+ UADD8 tVal6, tVal6, r0x80808080 ;// {xx, f2, xx, xx }
+
+ ;// M_STALL ARM1136JS=1
+
+ PKHBT tVal6, tVal8, tVal6 ;// {xx, f2, f1, f0 }
+ BIC tVal6, tVal6, #0xFF000000 ;// {00, f2, f1, f0 }
+ ORR Out0, tVal6, tVal11 ;// {U3, f2, f1, f0 }
+
+ ;// M_STALL ARM1136JS=1
+
+ PKHTB Out1, Out3, Out0, ASR #8 ;// {U3, U3, f2, f1 }
+ MOV return, #OMX_Sts_NoErr
+ PKHTB Out2, Out3, Out1, ASR #8 ;// {U3, U3, U3, f2 }
+
+ M_STR Out0, [pDst], dstStep ;// store {f3 to f0} at pDst[3 to 0 ]
+ M_STR Out1, [pDst], dstStep ;// store {f4 to f1} at pDst[7 to 4 ]
+ M_STR Out2, [pDst], dstStep ;// store {f5 to f2} at pDst[11 to 8 ]
+ STR Out3, [pDst] ;// store {f6 to f3} at pDSt[15 to 12]
+ M_EXIT ;// Macro to exit midway-break frm case
+
+DLUpperRightAvailable
+
+ MOV tVal8, Above0123, LSR #24 ;// {00, 00, 00, U3 }
+ MOV tVal9, Above0123, LSR #16 ;// {00, 00, U3, U2 }
+ MOV tVal10, Above0123, LSR #8 ;// {00, U3, U2, U1 }
+ ORR tVal8, tVal8, Above4567, LSL #8 ;// {U6, U5, U4, U3 }
+ ORR tVal10, tVal10, Above4567, LSL #24 ;// {U4, U3, U2, U1 }
+ PKHBT tVal9, tVal9, Above4567, LSL #16 ;// {U5, U4, U3, U2 }
+ MVN tVal1, tVal8 ;// {U6', U5', U4', U3'}
+ MVN tVal10, tVal10 ;// {U4', U3', U2', U1'}
+ MVN tVal2, Above4567 ;// {U7', U6', U5', U4'}
+ UHADD8 tVal6, Above0123, tVal9 ;// {d3, d2, d1, d0 }
+ UHADD8 tVal9, tVal9, Above4567 ;// {d5, d4, d3, d2 }
+ UHADD8 tVal8, Above4567, tVal8 ;// {d6, xx, xx, xx }
+ UHSUB8 tVal6, tVal6, tVal10 ;// {e3, e2, e1, e0 }
+ UHSUB8 tVal12, tVal9, tVal1 ;// {e5, e4, e3, e2 }
+ UHSUB8 tVal8, tVal8, tVal2 ;// {e6, xx, xx, xx }
+ UADD8 Out0, tVal6, r0x80808080 ;// {f3, f2, f1, f0 }
+ UADD8 tVal9, tVal8, r0x80808080 ;// {f6, xx, xx, xx }
+ UADD8 Out2, tVal12, r0x80808080 ;// {f5, f4, f3, f2 }
+ MOV tVal7, Out0, LSR #8 ;// {00, f3, f2, f1 }
+ AND tVal9, tVal9, #0xFF000000 ;// {f6, 00, 00, 00 }
+ PKHBT Out1, tVal7, Out2, LSL #8 ;// {f4, f3, f2, f1 }
+ ORR Out3, tVal9, Out2, LSR #8 ;// {f6, f5, f4, f3 }
+ M_STR Out0, [pDst], dstStep ;// store {f3 to f0} at pDst[3 to 0 ]
+ M_STR Out1, [pDst], dstStep ;// store {f4 to f1} at pDst[7 to 4 ]
+ M_STR Out2, [pDst], dstStep ;// store {f5 to f2} at pDst[11 to 8 ]
+ STR Out3, [pDst] ;// store {f6 to f3} at pDSt[15 to 12]
+ MOV return, #OMX_Sts_NoErr
+ M_EXIT ;// Macro to exit midway-break frm case
+
+
+OMX_VC_4x4_DIAG_DR
+
+ ;// M_STALL ARM1136JS=4
+
+ M_LDRB Left0, [pSrcLeft], leftStep ;// Left0 = pSrcLeft[0]
+ M_LDRB Left1, [pSrcLeft], leftStep ;// Left1 = pSrcLeft[1]
+ M_LDRB Left2, [pSrcLeft], leftStep ;// Left2 = pSrcLeft[2]
+ LDRB Left3, [pSrcLeft] ;// Left3 = pSrcLeft[3]
+ LDRB AboveLeft, [pSrcAboveLeft] ;// AboveLeft = pSrcAboveLeft[0]
+ ORR tVal7, Left1, Left0, LSL #8 ;// tVal7 = 00 00 L0 L1
+ LDR Above0123, [pSrcAbove] ;// Above0123 = U3 U2 U1 U0
+ LDR r0x80808080, =ADD_CONST1 ;// 0x80808080
+ ORR tVal8, Left3, Left2, LSL #8 ;// tVal8 = 00 00 L2 L3
+ PKHBT tVal7, tVal8, tVal7, LSL #16 ;// tVal7 = L0 L1 L2 L3
+ MOV tVal8, Above0123, LSL #8 ;// tVal8 = U2 U1 U0 00
+ MOV tVal9, tVal7, LSR #8 ;// tVal9 = 00 L0 L1 L2
+ ORR tVal8, tVal8, AboveLeft ;// tVal8 = U2 U1 U0 UL
+ ORR tVal9, tVal9, AboveLeft, LSL #24 ;// tVal9 = UL L0 L1 L2
+ MOV tVal10, Above0123, LSL #24 ;// tVal10= U0 00 00 00
+ UXTB tVal11, tVal7, ROR #24 ;// tVal11= 00 00 00 L0
+ ORR tVal10, tVal10, tVal9, LSR #8 ;// tVal10= U0 UL L0 L1
+ ORR tVal11, tVal11, tVal8, LSL #8 ;// tVal11= U1 U0 UL L0
+ UHADD8 tVal11, Above0123, tVal11 ;// tVal11= d1 d0 dL g0
+ UHADD8 tVal10, tVal7, tVal10 ;// tVal10= g0 g1 g2 g3
+ MVN tVal8, tVal8 ;// tVal8 = U2'U1'U0'UL'
+ MVN tVal9, tVal9 ;// tVal9 = UL'L0'L1'L2'
+ UHSUB8 tVal11, tVal11, tVal8 ;// tVal11= e1 e0 eL h0
+ UHSUB8 tVal10, tVal10, tVal9 ;// tVal10= h0 h1 h2 h3
+ UADD8 Out3, tVal10, r0x80808080 ;// Out3 = i0 i1 i2 i3
+ UADD8 Out0, tVal11, r0x80808080 ;// Out0 = f1 f0 fL i0
+ UXTH tVal11, Out3, ROR #8 ;// tVal11= 00 00 i1 i2
+ MOV tVal7, Out0, LSL #8 ;// tVal7 = f0 fL i0 00
+ ORR Out1, tVal7, tVal11, LSR #8 ;// Out1 = f0 fL i0 i1
+ PKHBT Out2, tVal11, Out0, LSL #16 ;// Out2 = fL i0 i1 i2
+ M_STR Out0, [pDst], dstStep ;// store {f1 to i0} at pDst[3 to 0 ]
+ M_STR Out1, [pDst], dstStep ;// store {f0 to i1} at pDst[7 to 4 ]
+ M_STR Out2, [pDst], dstStep ;// store {fL to i2} at pDst[11 to 8 ]
+ STR Out3, [pDst] ;// store {i0 to i3} at pDst[15 to 12]
+ MOV return, #OMX_Sts_NoErr
+ M_EXIT ;// Macro to exit midway-break frm case
+
+OMX_VC_4x4_VR
+
+ ;// M_STALL ARM1136JS=4
+
+ LDR Above0123, [pSrcAbove] ;// Above0123 = U3 U2 U1 U0
+ LDRB AboveLeft, [pSrcAboveLeft] ;// AboveLeft = 00 00 00 UL
+ M_LDRB Left0, [pSrcLeft], leftStep ;// Left0 = 00 00 00 L0
+ M_LDRB Left1, [pSrcLeft], leftStep ;// Left1 = 00 00 00 L1
+ LDRB Left2, [pSrcLeft] ;// Left2 = 00 00 00 L2
+ MOV tVal0, Above0123, LSL #8 ;// tVal0 = U2 U1 U0 00
+ MOV tVal9, Above0123 ;// tVal9 = U3 U2 U1 U0
+ ORR tVal14, tVal0, AboveLeft ;// tVal14 = U2 U1 U0 UL
+ MVN tVal11, tVal14 ;// tVal11 = U2'U1'U0'UL'
+ MOV tVal2, tVal14, LSL #8 ;// tVal2 = U1 U0 UL 00
+ UHSUB8 tVal1, Above0123, tVal11 ;// tVal1 = d2 d1 d0 dL
+ UHADD8 tVal10, AboveLeft, Left1 ;// tVal10 = 00 00 00 j1
+ MVN tVal4, Left0 ;// tVal4 = 00 00 00 L0'
+ UHSUB8 tVal4, tVal10, tVal4 ;// tVal4 = 00 00 00 k1
+ ORR tVal12, tVal0, Left0 ;// tVal12 = U2 U1 U0 L0
+ ORR tVal14, tVal2, Left0 ;// tVal14 = U1 U0 UL L0
+ LDR r0x80808080, =ADD_CONST1 ;// 0x80808080
+ UHADD8 tVal10, tVal9, tVal14 ;// tVal10 = g3 g2 g1 g0
+ UADD8 Out0, tVal1, r0x80808080 ;// Out0 = e2 e1 e0 eL
+ UHSUB8 tVal10, tVal10, tVal11 ;// tVal10 = h3 h2 h1 h0
+ M_STR Out0, [pDst], dstStep ;// store {e2 to eL} at pDst[3 to 0 ]
+ MOV tVal1, tVal14, LSL #8 ;// tVal1 = U0 UL L0 00
+ MOV tVal6, Out0, LSL #8 ;// tVal6 = e1 e0 eL 00
+ ORR tVal2, tVal2, Left1 ;// tVal2 = U1 U0 UL L1
+ UADD8 tVal4, tVal4, r0x80808080 ;// tVal4 = 00 00 00 l1
+ UADD8 Out1, tVal10, r0x80808080 ;// Out1 = i3 i2 i1 i0
+ MVN tVal2, tVal2 ;// tVal14 = U1'U0'UL'L1'
+ ORR tVal1, tVal1, Left2 ;// tVal1 = U0 UL L0 L2
+ ORR Out2, tVal6, tVal4 ;// Out2 = e1 e0 eL l1
+ UHADD8 tVal1, tVal1, tVal12 ;// tVal1 = g2 g1 g0 j2
+ M_STR Out1, [pDst], dstStep ;// store {i3 to i0} at pDst[7 to 4 ]
+ M_STR Out2, [pDst], dstStep ;// store {e1 to l1} at pDst[11 to 8 ]
+ UHSUB8 tVal9, tVal1, tVal2 ;// tVal9 = h2 h1 h0 k2
+ UADD8 Out3, tVal9, r0x80808080 ;// Out3 = i2 i1 i0 l2
+ STR Out3, [pDst] ;// store {i2 to l2} at pDst[15 to 12]
+ MOV return, #OMX_Sts_NoErr
+ M_EXIT ;// Macro to exit midway-break frm case
+
+OMX_VC_4x4_HD
+
+ ;// M_STALL ARM1136JS=4
+
+ LDR Above0123, [pSrcAbove] ;// Above0123 = U3 U2 U1 U0
+ LDRB AboveLeft, [pSrcAboveLeft] ;// AboveLeft = 00 00 00 UL
+ M_LDRB Left0, [pSrcLeft], leftStep ;// Left0 = 00 00 00 L0
+ M_LDRB Left1, [pSrcLeft], leftStep ;// Left1 = 00 00 00 L1
+ M_LDRB Left2, [pSrcLeft], leftStep ;// Left2 = 00 00 00 L2
+ LDRB Left3, [pSrcLeft] ;// Left3 = 00 00 00 L3
+ LDR r0x80808080, =ADD_CONST1 ;// 0x80808080
+ ORR tVal2, AboveLeft, Above0123, LSL #8;// tVal2 = U2 U1 U0 UL
+ MVN tVal1, Left0 ;// tVal1 = 00 00 00 L0'
+ ORR tVal4, Left0, tVal2, LSL #8 ;// tVal4 = U1 U0 UL L0
+ MVN tVal2, tVal2 ;// tVal2 = U2'U1'U0'UL'
+ UHADD8 tVal4, tVal4, Above0123 ;// tVal4 = g3 g2 g1 g0
+ UHSUB8 tVal1, AboveLeft, tVal1 ;// tVal1 = 00 00 00 dL
+ UHSUB8 tVal4, tVal4, tVal2 ;// tVal4 = h3 h2 h1 h0
+ UADD8 tVal1, tVal1, r0x80808080 ;// tVal1 = 00 00 00 eL
+ UADD8 tVal4, tVal4, r0x80808080 ;// tVal4 = i3 i2 i1 i0
+ ORR tVal2, Left0, AboveLeft, LSL #16 ;// tVal2 = 00 UL 00 L0
+ MOV tVal4, tVal4, LSL #8 ;// tVal4 = i2 i1 i0 00
+ ORR tVal11, Left1, Left0, LSL #16 ;// tVal11= 00 L0 00 L1
+ ORR tVal7, Left2, Left1, LSL #16 ;// tVal7 = 00 L1 00 L2
+ ORR tVal10, Left3, Left2, LSL #16 ;// tVal10= 00 L2 00 L3
+ ORR Out0, tVal4, tVal1 ;// Out0 = i2 i1 i0 eL
+ M_STR Out0, [pDst], dstStep ;// store {Out0} at pDst [0 to 3 ]
+ MOV tVal4, Out0, LSL #16 ;// tVal4 = i1 i0 00 00
+ UHADD8 tVal2, tVal2, tVal7 ;// tVal2 = 00 j1 00 j2
+ UHADD8 tVal6, tVal11, tVal10 ;// tVal11= 00 j2 00 j3
+ MVN tVal12, tVal11 ;// tVal12= 00 L0'00 L1'
+ MVN tVal14, tVal7 ;// tVal14= 00 L1'00 L2'
+ UHSUB8 tVal2, tVal2, tVal12 ;// tVal2 = 00 k1 00 k2
+ UHSUB8 tVal8, tVal7, tVal12 ;// tVal8 = 00 d1 00 d2
+ UHSUB8 tVal11, tVal6, tVal14 ;// tVal11= 00 k2 00 k3
+ UHSUB8 tVal9, tVal10, tVal14 ;// tVal9 = 00 d2 00 d3
+ UADD8 tVal2, tVal2, r0x80808080 ;// tVal2 = 00 l1 00 l2
+ UADD8 tVal8, tVal8, r0x80808080 ;// tVal8 = 00 e1 00 e2
+ UADD8 tVal11, tVal11, r0x80808080 ;// tVal11= 00 l2 00 l3
+ UADD8 tVal9, tVal9, r0x80808080 ;// tVal9 = 00 e2 00 e3
+ ORR Out2, tVal8, tVal2, LSL #8 ;// Out2 = l1 e1 l2 e2
+ ORR Out3, tVal9, tVal11, LSL #8 ;// Out3 = l2 e2 l3 e3
+ PKHTB Out1, tVal4, Out2, ASR #16 ;// Out1 = i1 i0 l1 e1
+ M_STR Out1, [pDst], dstStep ;// store {Out1} at pDst [4 to 7 ]
+ M_STR Out2, [pDst], dstStep ;// store {Out2} at pDst [8 to 11]
+ STR Out3, [pDst] ;// store {Out3} at pDst [12 to 15]
+ MOV return, #OMX_Sts_NoErr
+ M_EXIT ;// Macro to exit midway-break frm case
+
+OMX_VC_4x4_VL
+
+ ;// M_STALL ARM1136JS=3
+
+ LDMIA pSrcAbove, {Above0123, Above4567} ;// Above0123, Above4567 = pSrcAbove[0 to 7]
+ TST availability, #OMX_VC_UPPER_RIGHT
+ LDR r0x80808080, =ADD_CONST1 ;// 0x80808080
+ LDR r0x01010101, =MUL_CONST0 ;// 0x01010101
+ MOV tVal11, Above0123, LSR #24 ;// tVal11= 00 00 00 U3
+ MULEQ Above4567, tVal11, r0x01010101 ;// Above4567 = U3 U3 U3 U3
+ MOV tVal9, Above0123, LSR #8 ;// tVal9 = 00 U3 U2 U1
+ MVN tVal10, Above0123 ;// tVal10= U3'U2'U1'U0'
+ ORR tVal2, tVal9, Above4567, LSL #24 ;// tVal2 = U4 U3 U2 U1
+ UHSUB8 tVal8, tVal2, tVal10 ;// tVal8 = d4 d3 d2 d1
+ UADD8 Out0, tVal8, r0x80808080 ;// Out0 = e4 e3 e2 e1
+ M_STR Out0, [pDst], dstStep ;// store {Out0} at pDst [0 to 3 ]
+ MOV tVal9, tVal9, LSR #8 ;// tVal9 = 00 00 U3 U2
+ MOV tVal10, Above4567, LSL #8 ;// tVal10= U6 U5 U4 00
+ PKHBT tVal9, tVal9, Above4567, LSL #16 ;// tVal9 = U5 U4 U3 U2
+ ORR tVal10, tVal10, tVal11 ;// tVal10= U6 U5 U4 U3
+ UHADD8 tVal11, tVal9, Above0123 ;// tVal11= g5 g4 g3 g2
+ UHADD8 tVal14, tVal2, tVal10 ;// tVal14= g6 g5 g4 g3
+ MVN tVal8, tVal2 ;// tVal8 = U4'U3'U2'U1'
+ MVN tVal7, tVal9 ;// tVal7 = U5'U4'U3'U2'
+ UHSUB8 tVal12, tVal9, tVal8 ;// tVal12= d5 d4 d3 d2
+ UHSUB8 tVal11, tVal11, tVal8 ;// tVal11= h5 h4 h3 h2
+ UHSUB8 tVal2, tVal14, tVal7 ;// tVal2 = h6 h5 h4 h3
+ UADD8 Out1, tVal11, r0x80808080 ;// Out1 = i5 i4 i3 i2
+ UADD8 Out2, tVal12, r0x80808080 ;// Out2 = e5 e4 e3 e2
+ UADD8 Out3, tVal2, r0x80808080 ;// Out3 = i6 i5 i4 i3
+ M_STR Out1, [pDst], dstStep ;// store {Out1} at pDst [4 to 7 ]
+ M_STR Out2, [pDst], dstStep ;// store {Out2} at pDst [8 to 11]
+ M_STR Out3, [pDst], dstStep ;// store {Out3} at pDst [12 to 15]
+ MOV return, #OMX_Sts_NoErr
+ M_EXIT ;// Macro to exit midway-break frm case
+
+OMX_VC_4x4_HU
+
+ ;// M_STALL ARM1136JS=2
+
+ LDR r0x01010101, =MUL_CONST0 ;// 0x01010101
+ M_LDRB Left0, [pSrcLeft], leftStep ;// Left0 = pSrcLeft[0]
+ M_LDRB Left1, [pSrcLeft], leftStep ;// Left1 = pSrcLeft[1]
+ M_LDRB Left2, [pSrcLeft], leftStep ;// Left2 = pSrcLeft[2]
+ LDRB Left3, [pSrcLeft] ;// Left3 = pSrcLeft[3]
+ MOV r0x80808080, r0x01010101, LSL #7 ;// 0x80808080
+ ORR tVal6, Left0, Left1, LSL #16 ;// tVal6 = 00 L1 00 L0
+ ORR tVal7, Left1, Left2, LSL #16 ;// tVal7 = 00 L2 00 L1
+ ORR tVal11, Left2, Left3, LSL #16 ;// tVal11= 00 L3 00 L2
+ MUL Out3, Left3, r0x01010101 ;// Out3 = L3 L3 L3 L3
+ MVN tVal8, tVal7 ;// tVal8 = 00 L2'00 L1'
+ MVN tVal10, tVal11 ;// tVal10= 00 L3'00 L2'
+ UHADD8 tVal4, tVal6, tVal11 ;// tVal4 = 00 g3 00 g2
+ UXTB16 tVal12, Out3 ;// tVal12= 00 L3 00 L3
+ UHSUB8 tVal4, tVal4, tVal8 ;// tVal4 = 00 h3 00 h2
+ UHSUB8 tVal6, tVal6, tVal8 ;// tVal6 = 00 d2 00 d1
+ UHSUB8 tVal11, tVal11, tVal8 ;// tVal11= 00 d3 00 d2
+ UHADD8 tVal12, tVal12, tVal7 ;// tVal12= 00 g4 00 g3
+ UADD8 tVal4, tVal4, r0x80808080 ;// tVal4 = 00 i3 00 i2
+ UHSUB8 tVal12, tVal12, tVal10 ;// tVal12= 00 h4 00 h3
+ UADD8 tVal8, tVal6, r0x80808080 ;// tVal8 = 00 e2 00 e1
+ UADD8 tVal11, tVal11, r0x80808080 ;// tVal11= 00 e3 00 e2
+ UADD8 tVal12, tVal12, r0x80808080 ;// tVal12= 00 i4 00 i3
+ ORR Out0, tVal8, tVal4, LSL #8 ;// Out0 = i3 e2 i2 e1
+ ORR Out1, tVal11, tVal12, LSL #8 ;// Out1 = i4 e3 i3 e2
+ M_STR Out0, [pDst], dstStep ;// store {Out0} at pDst [0 to 3 ]
+ PKHTB Out2, Out3, Out1, ASR #16 ;// Out2 = L3 L3 i4 e3
+ M_STR Out1, [pDst], dstStep ;// store {Out1} at pDst [4 to 7 ]
+ M_STR Out2, [pDst], dstStep ;// store {Out2} at pDst [8 to 11]
+ STR Out3, [pDst] ;// store {Out3} at pDst [12 to 15]
+ MOV return, #OMX_Sts_NoErr
+ M_END
+
+ ENDIF ;// ARM1136JS
+
+
+ END
+;//-----------------------------------------------------------------------------------------------
+;// omxVCM4P10_PredictIntra_4x4 ends
+;//-----------------------------------------------------------------------------------------------
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_TransformDequantChromaDCFromPair_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_TransformDequantChromaDCFromPair_s.s
new file mode 100644
index 0000000..53597a8
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_TransformDequantChromaDCFromPair_s.s
@@ -0,0 +1,128 @@
+;//
+;//
+;// File Name: omxVCM4P10_TransformDequantChromaDCFromPair_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 9641
+;// Date: Thursday, February 7, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ IMPORT armVCM4P10_QPDivTable
+ IMPORT armVCM4P10_VMatrixQPModTable
+
+ M_VARIANTS ARM1136JS
+
+
+ IF ARM1136JS
+
+;//--------------------------------------
+;// Declare input registers
+;//--------------------------------------
+ppSrc RN 0
+pDst RN 1
+QP RN 2
+
+;//--------------------------------
+;// Scratch variable for Unpack2x2
+;//--------------------------------
+pSrc RN 9
+Value RN 4
+Value2 RN 5
+Flag RN 6
+strOffset RN 7
+cstOffset RN 8
+
+;//--------------------------------
+;// Scratch variable
+;//--------------------------------
+r0w0 RN 3
+r0w1 RN 4
+
+c0w0 RN 5
+c1w0 RN 6
+
+return RN 0
+pQPDivTable RN 5
+pQPModTable RN 6
+Shift RN 9
+Scale RN 2
+
+Temp1 RN 3
+Temp2 RN 4
+Temp3 RN 7
+Temp4 RN 8
+
+ ;// Write function header
+ M_START omxVCM4P10_TransformDequantChromaDCFromPair, r9
+
+
+ LDR pSrc, [ppSrc] ;// Load pSrc
+ MOV cstOffset, #31 ;// To be used in the loop, to compute offset
+
+ ;//-----------------------------------------------------------------------
+ ;// Firstly, fill all the coefficient values on the <pDst> buffer by zero
+ ;//-----------------------------------------------------------------------
+
+ MOV Value, #0 ;// Initialize the zero value
+ MOV Value2, #0 ;// Initialize the zero value
+ LDRB Flag, [pSrc], #1 ;// Preload <Flag> before <unpackLoop>
+ STRD Value, [pDst, #0] ;// pDst[0] = pDst[1] = pDst[2] = pDst[3] = 0
+
+
+unpackLoop
+ TST Flag, #0x10 ;// Computing (Flag & 0x10)
+ LDRSBNE Value2,[pSrc,#1]
+ LDRBNE Value, [pSrc], #2 ;// Load byte wise to avoid unaligned access
+ AND strOffset, cstOffset, Flag, LSL #1 ;// strOffset = (Flag & 15) < 1;
+ LDRSBEQ Value, [pSrc], #1 ;// Value = (OMX_U8) *pSrc++
+ ORRNE Value,Value,Value2, LSL #8 ;// Value = (OMX_U16) *pSrc++
+
+ TST Flag, #0x20 ;// Computing (Flag & 0x20) to check, if we're done
+ LDRBEQ Flag, [pSrc], #1 ;// Flag = (OMX_U8) *pSrc++, for next iteration
+ STRH Value, [pDst, strOffset] ;// Store <Value> at offset <strOffset>
+ BEQ unpackLoop ;// Branch to the loop beginning
+
+ LDMIA pDst, {r0w0, r0w1} ;// r0w0 = |c1|c0| & r0w1 = |c3|c2|
+
+
+ STR pSrc, [ppSrc] ;// Update the bitstream pointer
+
+ LDR pQPDivTable, =armVCM4P10_QPDivTable ;// QP Division look-up-table base pointer
+ LDR pQPModTable, =armVCM4P10_VMatrixQPModTable ;// QP Modulo look-up-table base pointer
+
+ SADDSUBX r0w0, r0w0, r0w0 ;// [ c00+c01, c00-c01 ]
+ SADDSUBX r0w1, r0w1, r0w1 ;// [ c10+c11, c10-c11 ]
+
+ LDRSB Shift, [pQPDivTable, QP] ;// Shift = pQPDivTable[QP]
+ LDRSB Scale, [pQPModTable, QP] ;// Scale = pQPModTable[QP]
+
+ SADD16 c0w0, r0w0, r0w1 ;// [ d00+d10, d01+d11 ]
+ SSUB16 c1w0, r0w0, r0w1 ;// [ d00-d10, d01-d11 ]
+
+ LSL Scale, Scale, Shift ;// Scale = Scale << Shift
+
+ SMULTB Temp2, c0w0, Scale ;// Temp2 = T(c0w0) * Scale
+ SMULTB Temp4, c1w0, Scale ;// Temp4 = T(c1w0) * Scale
+ SMULBB Temp1, c0w0, Scale ;// Temp1 = B(c0w0) * Scale
+ SMULBB Temp3, c1w0, Scale ;// Temp3 = B(c1w0) * Scale
+ MOV Temp2, Temp2, ASR #1 ;// Temp2 = Temp2 >> 1 & Temp1 = (Temp1 >> 1) << 16
+ MOV Temp4, Temp4, ASR #1 ;// Temp4 = Temp4 >> 1 & Temp3 = (Temp3 >> 1) << 16
+ PKHBT c0w0, Temp2, Temp1, LSL #15 ;// c0w0 = | Temp1 | Temp2 |
+ PKHBT c1w0, Temp4, Temp3, LSL #15 ;// c1w0 = | Temp3 | Temp4 |
+ STMIA pDst, {c0w0, c1w0} ;// Storing all the coefficients at once
+ MOV return, #OMX_Sts_NoErr
+ M_END
+
+ ENDIF ;// ARM1136JS
+
+
+
+
+ END
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_TransformDequantLumaDCFromPair_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_TransformDequantLumaDCFromPair_s.s
new file mode 100644
index 0000000..73caec2
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_TransformDequantLumaDCFromPair_s.s
@@ -0,0 +1,469 @@
+;//
+;//
+;// File Name: omxVCM4P10_TransformDequantLumaDCFromPair_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 9641
+;// Date: Thursday, February 7, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+;// Description:
+;// H.264 inverse quantize and transform module
+;//
+;//
+
+;// Include standard headers
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+;// Import/Export symbols required from/to other files
+;// (For example tables)
+
+ IMPORT armVCM4P10_UnpackBlock4x4
+ IMPORT armVCM4P10_QPDivTable
+ IMPORT armVCM4P10_VMatrixQPModTable
+
+ M_VARIANTS ARM1136JS
+
+;// Set debugging level
+;//DEBUG_ON SETL {TRUE}
+
+
+;// Static Function: armVCM4P10_InvTransformDequantLumaDC4x4
+
+
+;// Guarding implementation by the processor name
+
+ IF ARM1136JS
+
+
+;//Input Registers
+pData RN 0
+QP RN 1
+
+;//Output Registers
+
+
+;//Local Scratch Registers
+
+;// Packed Input pixels
+in00 RN 2 ;// Src[0] & Src[1]
+in02 RN 3 ;// Src[2] & Src[3]
+in10 RN 4 ;// Src[4] & Src[5]
+in12 RN 5 ;// Src[6] & Src[7]
+in20 RN 6 ;// Src[8] & Src[9]
+in22 RN 7 ;// Src[10] & Src[11]
+in30 RN 8 ;// Src[12] & Src[13]
+in32 RN 9 ;// Src[14] & Src[15]
+
+;// Transpose for Row operations (Rows to cols)
+trRow00 RN 2
+trRow10 RN 10
+trRow02 RN 3
+trRow12 RN 5
+trRow20 RN 11
+trRow30 RN 12
+trRow32 RN 14
+trRow22 RN 7
+
+;// Intermediate calculations
+rowSum1 RN 4
+rowSum2 RN 6
+rowDiff1 RN 8
+rowDiff2 RN 9
+
+
+;// Row operated pixels
+rowOp00 RN 2
+rowOp10 RN 10
+rowOp20 RN 11
+rowOp30 RN 12
+rowOp02 RN 3
+rowOp12 RN 5
+rowOp22 RN 7
+rowOp32 RN 14
+
+;// Transpose for colulmn operations
+trCol00 RN 2
+trCol02 RN 3
+trCol10 RN 4
+trCol12 RN 5
+trCol20 RN 6
+trCol22 RN 7
+trCol30 RN 8
+trCol32 RN 9
+
+;// Intermediate calculations
+colSum1 RN 10
+colSum2 RN 11
+colDiff1 RN 12
+colDiff2 RN 14
+
+
+;// Coloumn operated pixels
+colOp00 RN 2
+colOp02 RN 3
+colOp10 RN 4
+colOp12 RN 5
+colOp20 RN 6
+colOp22 RN 7
+colOp30 RN 8
+colOp32 RN 9
+
+;// Temporary scratch varaibles
+pQPDivTable RN 0
+pQPModTable RN 11
+Shift RN 10
+Scale RN 14
+Round RN 0
+
+temp1 RN 10
+temp2 RN 11
+temp3 RN 12
+temp4 RN 1
+
+
+
+;// InvTransformed and Dequantized pixels
+out00 RN 2
+out02 RN 3
+out10 RN 4
+out12 RN 5
+out20 RN 6
+out22 RN 7
+out30 RN 8
+out32 RN 9
+
+
+
+
+ ;// Allocate stack memory required by the function
+ M_ALLOC4 pDataOnStack, 4
+
+ ;// Write function header
+ M_START armVCM4P10_InvTransformDequantLumaDC4x4,r11
+
+ ;******************************************************************
+ ;// The strategy used in implementing the transform is as follows:*
+ ;// Load the 4x4 block into 8 registers *
+ ;// Transpose the 4x4 matrix *
+ ;// Perform the row operations (on columns) using SIMD *
+ ;// Transpose the 4x4 result matrix *
+ ;// Perform the coloumn operations *
+ ;// Store the 4x4 block at one go *
+ ;******************************************************************
+
+ ;// Load all the 4x4 pixels
+
+ LDMIA pData,{in00,in02,in10,in12,in20,in22,in30,in32}
+
+ ;//*****************************************************************
+ ;//
+ ;// Transpose the matrix inorder to perform row ops as coloumn ops
+ ;// Input: in[][] = original matrix
+ ;// Output: trRow[][]= transposed matrix
+ ;// Step1: Obtain the LL part of the transposed matrix
+ ;// Step2: Obtain the HL part
+ ;// step3: Obtain the LH part
+ ;// Step4: Obtain the HH part
+ ;//
+ ;//*****************************************************************
+
+ ;// LL 2x2 transposed matrix
+ ;// d0 d1 - -
+ ;// d4 d5 - -
+ ;// - - - -
+ ;// - - - -
+
+ PKHTB trRow10,in10,in00,ASR #16 ;// [5 4] = [f5:f1]
+ PKHBT trRow00,in00,in10,LSL #16 ;// [1 0] = [f4:f0]
+
+ ;// HL 2x2 transposed matrix
+ ;// - - - -
+ ;// - - - -
+ ;// d8 d9 - -
+ ;// d12 d13 - -
+
+
+ PKHTB trRow30,in12,in02,ASR #16 ;// [13 12] = [7 3]
+ PKHBT trRow20,in02,in12,LSL #16 ;// [9 8] = [6 2]
+
+ ;// LH 2x2 transposed matrix
+ ;// - - d2 d3
+ ;// - - d6 d7
+ ;// - - - -
+ ;// - - - -
+
+ PKHBT trRow02,in20,in30,LSL #16 ;// [3 2] = [f12:f8]
+ PKHTB trRow12,in30,in20,ASR #16 ;// [7 6] = [f13:f9]
+
+
+
+
+ ;// HH 2x2 transposed matrix
+ ;// - - - -
+ ;// - - - -
+ ;// - - d10 d11
+ ;// - - d14 d15
+
+ PKHTB trRow32,in32,in22,ASR #16 ;// [15 14] = [15 11]
+ PKHBT trRow22,in22,in32,LSL #16 ;// [11 10] = [14 10]
+
+
+ ;****************************************
+ ;// Row Operations (Performed on columns)
+ ;****************************************
+
+
+ ;// SIMD operations on first two columns(two rows of the original matrix)
+
+ SADD16 rowSum1,trRow00,trRow10 ;// (c0+c1)
+ SADD16 rowSum2,trRow20,trRow30 ;// (c2+c3)
+ SSUB16 rowDiff1,trRow00,trRow10 ;// (c0-c1)
+ SSUB16 rowDiff2,trRow20,trRow30 ;// (c2-c3)
+ SADD16 rowOp00,rowSum1,rowSum2 ;// (c0+c1+c2+c3)
+ SSUB16 rowOp10,rowSum1,rowSum2 ;// (c0+c1-c2-c3)
+ SSUB16 rowOp20,rowDiff1,rowDiff2 ;// (c0-c1-c2+c3)
+ SADD16 rowOp30,rowDiff1,rowDiff2 ;// (c0-c1+c2-c3)
+
+
+ ;// SIMD operations on next two columns(next two rows of the original matrix)
+
+ SADD16 rowSum1,trRow02,trRow12 ;// (c0+c1)
+ SADD16 rowSum2,trRow22,trRow32 ;// (c2+c3)
+ SSUB16 rowDiff1,trRow02,trRow12 ;// (c0-c1)
+ SSUB16 rowDiff2,trRow22,trRow32 ;// (c2-c3)
+ SADD16 rowOp02,rowSum1,rowSum2 ;// (c0+c1+c2+c3)
+ SSUB16 rowOp12,rowSum1,rowSum2 ;// (c0+c1-c2-c3)
+ SSUB16 rowOp22,rowDiff1,rowDiff2 ;// (c0-c1-c2+c3)
+ SADD16 rowOp32,rowDiff1,rowDiff2 ;// (c0-c1+c2-c3)
+
+
+
+ ;*****************************************************************
+ ;// Transpose the resultant matrix
+ ;// Input: rowOp[][]
+ ;// Output: trCol[][]
+ ;*****************************************************************
+
+ ;// LL 2x2 transposed matrix
+ ;// d0 d1 - -
+ ;// d4 d5 - -
+ ;// - - - -
+ ;// - - - -
+
+ PKHTB trCol10,rowOp10,rowOp00,ASR #16 ;// [5 4] = [f5:f1]
+ PKHBT trCol00,rowOp00,rowOp10,LSL #16 ;// [1 0] = [f4:f0]
+
+ ;// HL 2x2 transposed matrix
+ ;// - - - -
+ ;// - - - -
+ ;// d8 d9 - -
+ ;// d12 d13 - -
+
+
+ PKHTB trCol30,rowOp12,rowOp02,ASR #16 ;// [13 12] = [7 3]
+ PKHBT trCol20,rowOp02,rowOp12,LSL #16 ;// [9 8] = [6 2]
+
+ ;// LH 2x2 transposed matrix
+ ;// - - d2 d3
+ ;// - - d6 d7
+ ;// - - - -
+ ;// - - - -
+
+ PKHBT trCol02,rowOp20,rowOp30,LSL #16 ;// [3 2] = [f12:f8]
+ PKHTB trCol12,rowOp30,rowOp20,ASR #16 ;// [7 6] = [f13:f9]
+
+
+
+
+ ;// HH 2x2 transposed matrix
+ ;// - - - -
+ ;// - - - -
+ ;// - - d10 d11
+ ;// - - d14 d15
+
+ PKHTB trCol32,rowOp32,rowOp22,ASR #16 ;// [15 14] = [15 11]
+ PKHBT trCol22,rowOp22,rowOp32,LSL #16 ;// [11 10] = [14 10]
+
+
+ ;*******************************
+ ;// Coloumn Operations
+ ;*******************************
+
+ ;//--------------------------------------------------------------------------------------
+ ;// Store pData(RN0) on stack and restore it only at the final store back
+ ;// This frees up a register (RN0) which is used to reduce number of intermediate stalls
+ ;//--------------------------------------------------------------------------------------
+ M_STR pData,pDataOnStack
+
+
+ ;// SIMD operations on first two columns(two rows of the original matrix)
+
+ SADD16 colSum1,trCol00,trCol10 ;// (c0+c1)
+ SADD16 colSum2,trCol20,trCol30 ;// (c2+c3)
+ SSUB16 colDiff1,trCol00,trCol10 ;// (c0-c1)
+ SSUB16 colDiff2,trCol20,trCol30 ;// (c2-c3)
+ SADD16 colOp00,colSum1,colSum2 ;// (c0+c1+c2+c3)
+ SSUB16 colOp10,colSum1,colSum2 ;// (c0+c1-c2-c3)
+ SSUB16 colOp20,colDiff1,colDiff2 ;// (c0-c1-c2+c3)
+ SADD16 colOp30,colDiff1,colDiff2 ;// (c0-c1+c2-c3)
+
+
+ ;// SIMD operations on next two columns(next two rows of the original matrix)
+
+ LDR pQPDivTable, =armVCM4P10_QPDivTable ;// QP Division look-up-table base pointer
+ SADD16 colSum1,trCol02,trCol12 ;// (c0+c1)
+ SADD16 colSum2,trCol22,trCol32 ;// (c2+c3)
+ SSUB16 colDiff1,trCol02,trCol12 ;// (c0-c1)
+ SSUB16 colDiff2,trCol22,trCol32 ;// (c2-c3)
+ SADD16 colOp02,colSum1,colSum2 ;// (c0+c1+c2+c3)
+ SSUB16 colOp12,colSum1,colSum2 ;// (c0+c1-c2-c3)
+ LDR pQPModTable, =armVCM4P10_VMatrixQPModTable ;// QP Modulo look-up-table base pointer
+ LDRSB Shift, [pQPDivTable, QP] ;// Shift = pQPDivTable[QP]
+ SSUB16 colOp22,colDiff1,colDiff2 ;// (c0-c1-c2+c3)
+ SADD16 colOp32,colDiff1,colDiff2 ;// (c0-c1+c2-c3)
+
+
+ LDRSB Scale, [pQPModTable, QP] ;// Scale = pQPModTable[QP]
+
+ ;//----------------------------------------------------------------------
+ ;//
+ ;// <Dequantize> improves on the c-reference code
+ ;// Both the cases i.e., Shift>=0 and Shift<0 cases are covered together
+ ;// We do not subtract 2 from Shift as in C reference, instead perform a
+ ;// Scale << Shift once in the beginning and do a right shift by a
+ ;// constant 2 after the Multiplication. The value of Round would be 2
+ ;//
+ ;// By doing this we aviod the Branches required and also
+ ;// reduce the code size substantially
+ ;//
+ ;//----------------------------------------------------------------------
+
+ MOV Round, #2 ;// Round = 2
+ LSL Scale, Scale, Shift ;// Scale = Scale << Shift
+
+
+ ;// Row 1
+ SMLABB temp1, colOp00, Scale, Round ;// Temp1 = B(c0w0) * Scale + Round
+ SMLABB temp3, colOp02, Scale, Round ;// Temp3 = B(c1w0) * Scale + Round
+ SMLATB temp2, colOp00, Scale, Round ;// Temp2 = T(c0w0) * Scale + Round
+ SMLATB temp4, colOp02, Scale, Round ;// Temp4 = T(c1w0) * Scale + Round
+
+ ASR temp1, temp1, #2 ;// Temp1 = Temp1 >> 2
+ ASR temp3, temp3, #2 ;// Temp3 = Temp3 >> 2
+ PKHBT out00, temp1, temp2, LSL #14 ;// c0w0 = | Temp2 | Temp1 |
+ PKHBT out02, temp3, temp4, LSL #14 ;// c1w0 = | Temp2 | Temp1 |
+
+
+ ;// Row 2
+ SMLABB temp1, colOp10, Scale, Round ;// Temp1 = B(c0w0) * Scale + Round
+ SMLABB temp3, colOp12, Scale, Round ;// Temp3 = B(c1w0) * Scale + Round
+ SMLATB temp2, colOp10, Scale, Round ;// Temp2 = T(c0w0) * Scale + Round
+ SMLATB temp4, colOp12, Scale, Round ;// Temp4 = T(c1w0) * Scale + Round
+
+ ASR temp1, temp1, #2 ;// Temp1 = Temp1 >> 2
+ ASR temp3, temp3, #2 ;// Temp3 = Temp3 >> 2
+ PKHBT out10, temp1, temp2, LSL #14 ;// c0w0 = | Temp2 | Temp1 |
+ PKHBT out12, temp3, temp4, LSL #14 ;// c1w0 = | Temp2 | Temp1 |
+
+ ;// Row 3
+ SMLABB temp1, colOp20, Scale, Round ;// Temp1 = B(c0w0) * Scale + Round
+ SMLABB temp3, colOp22, Scale, Round ;// Temp3 = B(c1w0) * Scale + Round
+ SMLATB temp2, colOp20, Scale, Round ;// Temp2 = T(c0w0) * Scale + Round
+ SMLATB temp4, colOp22, Scale, Round ;// Temp4 = T(c1w0) * Scale + Round
+
+ ASR temp1, temp1, #2 ;// Temp1 = Temp1 >> 2
+ ASR temp3, temp3, #2 ;// Temp3 = Temp3 >> 2
+ PKHBT out20, temp1, temp2, LSL #14 ;// c0w0 = | Temp2 | Temp1 |
+ PKHBT out22, temp3, temp4, LSL #14 ;// c1w0 = | Temp2 | Temp1 |
+
+ ;// Row 4
+ SMLABB temp1, colOp30, Scale, Round ;// Temp1 = B(c0w0) * Scale + Round
+ SMLABB temp3, colOp32, Scale, Round ;// Temp3 = B(c1w0) * Scale + Round
+ SMLATB temp2, colOp30, Scale, Round ;// Temp2 = T(c0w0) * Scale + Round
+ SMLATB temp4, colOp32, Scale, Round ;// Temp4 = T(c1w0) * Scale + Round
+
+ M_LDR pData,pDataOnStack ;// Restore pData pointer from stack
+ ASR temp1, temp1, #2 ;// Temp1 = Temp1 >> 2
+ ASR temp3, temp3, #2 ;// Temp3 = Temp3 >> 2
+ PKHBT out30, temp1, temp2, LSL #14 ;// c0w0 = | Temp2 | Temp1 |
+ PKHBT out32, temp3, temp4, LSL #14 ;// c1w0 = | Temp2 | Temp1 |
+
+
+
+ ;***************************
+ ;// Store all the 4x4 pixels
+ ;***************************
+
+store_coeff
+
+ STMIA pData,{out00,out02,out10,out12,out20,out22,out30,out32}
+
+
+
+ ;// Set return value
+
+
+ ;// Write function tail
+ M_END
+
+ ENDIF ;//ARM1136JS
+
+
+;// Static Function: armVCM4P10_InvTransformDequantLumaDC4x4
+
+;// Guarding implementation by the processor name
+
+
+
+
+;// Function: omxVCM4P10_TransformDequantLumaDCFromPair
+
+;//Input Registers
+ppSrc RN 0
+pDst RN 1
+QPR2 RN 2
+
+;//Output Registers
+result RN 0
+
+;//Local Scratch Registers
+pDstR4 RN 4
+pDstR0 RN 0
+QPR1 RN 1
+QPR5 RN 5
+
+;// Guarding implementation by the processor name
+
+ IF ARM1136JS
+
+ ;// Allocate stack memory required by the function
+
+
+ ;// Write function header
+ M_START omxVCM4P10_TransformDequantLumaDCFromPair,r5
+
+ MOV pDstR4,pDst ;// Saving register r1
+ MOV QPR5,QPR2 ;// Saving register r2
+ BL armVCM4P10_UnpackBlock4x4
+
+ MOV pDstR0,pDstR4 ;// Setting up register r0
+ MOV QPR1,QPR5 ;// Setting up register r1
+ BL armVCM4P10_InvTransformDequantLumaDC4x4
+
+
+ ;// Set return value
+ MOV result,#OMX_Sts_NoErr
+
+ ;// Write function tail
+ M_END
+
+
+ ENDIF ;//ARM1136JS
+
+
+ END
\ No newline at end of file
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/api/armVCM4P2_Huff_Tables_VLC.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/api/armVCM4P2_Huff_Tables_VLC.h
new file mode 100644
index 0000000..22115d3
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/api/armVCM4P2_Huff_Tables_VLC.h
@@ -0,0 +1,37 @@
+/**
+ *
+ * File Name: armVCM4P2_Huff_Tables_VLC.h
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ *
+ * File: armVCM4P2_Huff_Tables.h
+ * Description: Declares Tables used for Hufffman coding and decoding
+ * in MP4P2 codec.
+ *
+ */
+
+#ifndef _OMXHUFFTAB_H_
+#define _OMXHUFFTAB_H_
+
+
+extern const OMX_U16 armVCM4P2_IntraVlcL0L1[200];
+
+
+extern const OMX_U16 armVCM4P2_InterVlcL0L1[200];
+
+extern const OMX_U16 armVCM4P2_aIntraDCLumaChromaIndex[64];
+//extern const OMX_U16 armVCM4P2_aIntraDCChromaIndex[32];
+extern const OMX_U16 armVCM4P2_aVlcMVD[124];
+
+extern const OMX_U8 armVCM4P2_InterL0L1LMAX[73];
+extern const OMX_U8 armVCM4P2_InterL0L1RMAX[35];
+extern const OMX_U8 armVCM4P2_IntraL0L1LMAX[53];
+extern const OMX_U8 armVCM4P2_IntraL0L1RMAX[40]
+
+#endif /* _OMXHUFFTAB_H_ */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/api/armVCM4P2_ZigZag_Tables.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/api/armVCM4P2_ZigZag_Tables.h
new file mode 100644
index 0000000..d5f865c
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/api/armVCM4P2_ZigZag_Tables.h
@@ -0,0 +1,25 @@
+/**
+ *
+ * File Name: armVCM4P2_ZigZag_Tables.h
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ *
+ * File: armVCM4P2_Zigzag_Tables.h
+ * Description: Declares Tables used for Zigzag scan in MP4P2 codec.
+ *
+ */
+
+#ifndef _OMXZIGZAGTAB_H
+#define _OMXZIGZAGTAB_H
+
+extern const OMX_U8 armVCM4P2_aClassicalZigzagScan [192];
+//extern const OMX_U8 armVCM4P2_aHorizontalZigzagScan [64];
+//extern const OMX_U8 armVCM4P2_aVerticalZigzagScan [64];
+
+#endif /* _OMXZIGZAGTAB_H_ */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_Clip8_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_Clip8_s.s
new file mode 100644
index 0000000..7801e57
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_Clip8_s.s
@@ -0,0 +1,75 @@
+; /**
+; *
+; * File Name: armVCM4P2_Clip8_s.s
+; * OpenMAX DL: v1.0.2
+; * Revision: 9641
+; * Date: Thursday, February 7, 2008
+; *
+; * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+; *
+; *
+; *
+; * Description:
+; * Contains module for Clipping 16 bit value to [0,255] Range
+; */
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+
+ M_VARIANTS ARM1136JS
+
+
+
+ IF ARM1136JS
+
+;//Input Arguments
+
+pSrc RN 0
+pDst RN 1
+step RN 2
+
+;// Local variables
+
+x0 RN 3
+x1 RN 4
+x2 RN 5
+x3 RN 6
+
+Count RN 14
+
+
+ M_START armVCM4P2_Clip8,r6
+
+
+ MOV Count,#8
+loop
+
+ LDMIA pSrc!,{x0, x1}
+ SUBS Count,Count, #1 ;// count down
+ LDMIA pSrc!,{x2, x3}
+ USAT16 x0, #8, x0 ;// clip two samples to [0,255]
+ USAT16 x1, #8, x1 ;// clip two samples to [0,255]
+ STRB x0, [pDst]
+ MOV x0, x0, LSR #16
+ STRB x0, [pDst,#1]
+ STRB x1, [pDst,#2]
+ MOV x1, x1, LSR #16
+ STRB x1, [pDst,#3]
+
+ USAT16 x2, #8, x2 ;// clip two samples to [0,255]
+ USAT16 x3, #8, x3 ;// clip two samples to [0,255]
+ STRB x2, [pDst,#4]
+ MOV x2, x2, LSR #16
+ STRB x2, [pDst,#5]
+ STRB x3, [pDst,#6]
+ MOV x3, x3, LSR #16
+ STRB x3, [pDst,#7]
+ ADD pDst,pDst,step ;// Increment pDst by step value
+
+ BGT loop ;// Continue loop until Count reaches 64
+
+ M_END
+ ENDIF
+
+ END
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_DecodeVLCZigzag_AC_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_DecodeVLCZigzag_AC_unsafe_s.s
new file mode 100644
index 0000000..9e30900
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_DecodeVLCZigzag_AC_unsafe_s.s
@@ -0,0 +1,398 @@
+;/**
+; *
+; * File Name: armVCM4P2_DecodeVLCZigzag_AC_unsafe_s.s
+; * OpenMAX DL: v1.0.2
+; * Revision: 9641
+; * Date: Thursday, February 7, 2008
+; *
+; * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+; *
+; *
+; *
+; * Description:
+; * Contains modules for zigzag scanning and VLC decoding
+; * for inter, intra block.
+; *
+; *
+; *
+; * Function: omxVCM4P2_DecodeVLCZigzag_AC_unsafe
+; *
+; * Description:
+; * Performs VLC decoding and inverse zigzag scan
+; *
+; *
+; *
+; *
+; */
+
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+ INCLUDE armCOMM_BitDec_s.h
+
+
+ M_VARIANTS ARM1136JS
+
+
+
+
+
+ IF ARM1136JS
+
+
+
+
+
+;//Input Arguments
+
+ppBitStream RN 0
+pBitOffset RN 1
+pDst RN 2
+shortVideoHeader RN 3
+
+
+;//Local Variables
+
+Return RN 0
+
+pVlcTableL0L1 RN 4
+pLMAXTableL0L1 RN 4
+pRMAXTableL0L1 RN 4
+pZigzagTable RN 4
+
+ftype RN 0
+temp3 RN 4
+temp RN 5
+Count RN 6
+Escape RN 5
+
+;// armVCM4P2_FillVLDBuffer
+zigzag RN 0
+storeLevel RN 1
+temp2 RN 4
+temp1 RN 5
+sign RN 5
+Last RN 7
+storeRun RN 14
+
+
+packRetIndex RN 5
+
+
+markerbit RN 5
+
+;// Scratch Registers
+
+RBitStream RN 8
+RBitBuffer RN 9
+RBitCount RN 10
+
+T1 RN 11
+T2 RN 12
+LR RN 14
+
+
+
+ M_ALLOC4 pppBitStream,4
+ M_ALLOC4 ppOffset,4
+ M_ALLOC4 pLinkRegister,4
+
+ M_START armVCM4P2_DecodeVLCZigzag_AC_unsafe
+
+ ;// get the table addresses from stack
+ M_ARG ppVlcTableL0L1,4
+ M_ARG ppLMAXTableL0L1,4
+ M_ARG ppRMAXTableL0L1,4
+ M_ARG ppZigzagTable,4
+
+ ;// Store ALL zeros at pDst
+
+ MOV temp1,#0 ;// Initialize Count to zero
+ MOV Last,#0
+ M_STR LR,pLinkRegister ;// Store Link Register on Stack
+ MOV temp2,#0
+ MOV LR,#0
+
+ ;// Initialize the Macro and Store all zeros to pDst
+
+ STM pDst!,{temp2,temp1,Last,LR}
+ M_BD_INIT0 ppBitStream, pBitOffset, RBitStream, RBitBuffer, RBitCount
+ STM pDst!,{temp2,temp1,Last,LR}
+ M_BD_INIT1 T1, T2, T2
+ STM pDst!,{temp2,temp1,Last,LR}
+ M_BD_INIT2 T1, T2, T2
+ STM pDst!,{temp2,temp1,Last,LR}
+ M_STR ppBitStream,pppBitStream ;// Store ppBitstream on stack
+ STM pDst!,{temp2,temp1,Last,LR}
+ M_STR pBitOffset,ppOffset ;// Store pBitOffset on stack
+ STM pDst!,{temp2,temp1,Last,LR}
+
+ STM pDst!,{temp2,temp1,Last,LR}
+ STM pDst!,{temp2,temp1,Last,LR}
+
+
+ SUB pDst,pDst,#128 ;// Restore pDst
+
+ ;// The armVCM4P2_GetVLCBits begins
+
+getVLCbits
+
+ M_BD_LOOK8 Escape,7 ;// Load Escape Value
+ LSR Escape,Escape,#25
+ CMP Escape,#3 ;// check for escape mode
+ MOVNE ftype,#0
+ BNE notEscapemode ;// Branch if not in Escape mode 3
+
+ M_BD_VSKIP8 #7,T1
+ CMP shortVideoHeader,#0 ;// Check shortVideoHeader flag to know the type of Escape mode
+ BEQ endFillVLD
+
+ ;// Escape Mode 4
+
+ M_BD_READ8 Last,1,T1
+ M_BD_READ8 storeRun,6,T1
+ M_BD_READ8 storeLevel,8,T1
+
+
+ ;// Check whether the Reserved values for Level are used and Exit with an Error Message if it is so
+
+ TEQ storeLevel,#0
+ TEQNE storeLevel,#128
+ BEQ ExitError
+
+ ADD temp2,storeRun,Count
+ CMP temp2,#64
+ BGE ExitError ;// error if Count+storeRun >= 64
+
+
+ ;// Load address of zigzagTable
+
+ M_LDR pZigzagTable,ppZigzagTable ;// Loading the Address of Zigzag table
+
+
+ ;// armVCM4P2_FillVLDBuffer
+
+ SXTB storeLevel,storeLevel ;// Sign Extend storeLevel to 32 bits
+
+
+ ;// To Reflect Runlength
+
+ ADD Count,Count,storeRun
+ LDRB zigzag,[pZigzagTable,Count]
+ ADD Count,Count,#1
+ STRH storeLevel,[pDst,zigzag] ;// store Level
+
+ B ExitOk
+
+
+
+endFillVLD
+
+
+ ;// Load Ftype( Escape Mode) value based on the two successive bits in the bitstream
+
+ M_BD_READ8 temp1,1,T1
+ CMP temp1,#0
+ MOVEQ ftype,#1
+ BEQ notEscapemode
+ M_BD_READ8 temp1,1,T1
+ CMP temp1,#1
+ MOVEQ ftype,#3
+ MOVNE ftype,#2
+
+
+notEscapemode
+
+ ;// Load optimized packed VLC table with last=0 and Last=1
+
+ M_LDR pVlcTableL0L1,ppVlcTableL0L1 ;// Load Combined VLC Table
+
+
+ CMP ftype,#3 ;// If ftype >=3 get perform Fixed Length Decoding (Escape Mode 3)
+ BGE EscapeMode3 ;// Else continue normal VLC Decoding
+
+ ;// Variable lengh decoding, "armUnPackVLC32"
+
+
+ M_BD_VLD packRetIndex,T1,T2,pVlcTableL0L1,4,2
+
+
+ LDR temp3,=0xFFF
+
+ CMP packRetIndex,temp3 ;// Check for invalid symbol
+ BEQ ExitError ;// if invalid symbol occurs exit with an error message
+
+ AND Last,packRetIndex,#2 ;// Get Last from packed Index
+
+
+
+
+ LSR storeRun,packRetIndex,#7 ;// Get Run Value from Packed index
+ AND storeLevel,packRetIndex,#0x7c ;// storeLevel=packRetIndex[2-6],storeLevel[0-1]=0
+
+
+ M_LDR pLMAXTableL0L1,ppLMAXTableL0L1 ;// Load LMAX table
+
+
+ LSR storeLevel,storeLevel,#2 ;// Level value
+
+ CMP ftype,#1
+ BNE ftype2
+
+ ;// ftype==1; Escape mode =1
+
+
+ ADD temp1, pLMAXTableL0L1, Last, LSL#4 ;// If the Last=1 add 32 to table address
+ LDRB temp1,[temp1,storeRun]
+
+
+ ADD storeLevel,temp1,storeLevel
+
+ftype2
+
+ ;// ftype =2; Escape mode =2
+
+ M_LDR pRMAXTableL0L1,ppRMAXTableL0L1 ;// Load RMAX Table
+
+ CMP ftype,#2
+ BNE FillVLDL1
+
+ ADD temp1, pRMAXTableL0L1, Last, LSL#4 ;// If Last=1 add 32 to table address
+ SUB temp2,storeLevel,#1
+ LDRB temp1,[temp1,temp2]
+
+
+ ADD storeRun,storeRun,#1
+ ADD storeRun,temp1
+
+FillVLDL1
+
+
+ ;// armVCM4P2_FillVLDBuffer
+
+ M_LDR pZigzagTable,ppZigzagTable ;// Load address of zigzagTable
+
+ M_BD_READ8 sign,1,T1
+
+ CMP sign,#1
+ RSBEQ storeLevel,storeLevel,#0
+
+ ADD temp1,storeRun,Count ;// Exit with an error message if Run + Count exceeds 63
+ CMP temp1,#64
+ BGE ExitError
+
+
+
+
+
+
+ ;// To Reflect Runlenght
+
+ ADD Count,Count,storeRun
+
+storeLevelL1
+
+ LDRB zigzag,[pZigzagTable,Count]
+ CMP Last,#2 ;// Check if the Level val is Last non zero val
+ ADD Count,Count,#1
+ LSR Last,Last,#1
+ STRH storeLevel,[pDst,zigzag]
+
+ BNE end
+
+ B ExitOk
+
+
+
+ ;// Fixed Lengh Decoding Escape Mode 3
+
+EscapeMode3
+
+ M_BD_READ8 Last,1,T1
+ M_BD_READ8 storeRun,6,T1
+
+ ADD temp2,storeRun,Count ;// Exit with an error message if Run + Count exceeds 63
+ CMP temp2,#64
+ BGE ExitError
+
+ M_BD_READ8 markerbit,1,T1
+ TEQ markerbit,#0 ;// Exit with an error message if marker bit is zero
+ BEQ ExitError
+
+ M_BD_READ16 storeLevel,12,T1
+
+ TST storeLevel,#0x800 ;// test if the level is negative
+ SUBNE storeLevel,storeLevel,#4096
+ CMP storeLevel,#0
+ CMPNE storeLevel,#-2048
+ BEQ ExitError ;// Exit with an error message if Level==0 or -2048
+
+ M_LDR pZigzagTable,ppZigzagTable ;// Load address of zigzagTable
+
+ M_BD_READ8 markerbit,1,T1
+
+
+ ;// armVCM4P2_FillVLDBuffer ( Sign not used as storeLevel is preprocessed)
+
+
+
+ ;// To Reflect Run Length
+
+ ADD Count,Count,storeRun
+
+
+
+storeLevelLast
+
+ LDRB zigzag,[pZigzagTable,Count]
+ CMP Last,#1
+ ADD Count,Count,#1
+ STRH storeLevel,[pDst,zigzag]
+
+ BNE end
+
+ B ExitOk
+
+end
+
+ CMP Count,#64 ;//Run the Loop untill Count reaches 64
+
+ BLT getVLCbits
+
+
+ExitOk
+ ;// Exit When VLC Decoding is done Successfully
+
+ ;// Loading ppBitStream and pBitOffset from stack
+
+ CMP Last,#1
+ M_LDR ppBitStream,pppBitStream
+ M_LDR pBitOffset,ppOffset
+
+ ;//Ending the macro
+
+ M_BD_FINI ppBitStream,pBitOffset
+
+ MOVEQ Return,#OMX_Sts_NoErr
+ MOVNE Return,#OMX_Sts_Err
+ M_LDR LR,pLinkRegister ;// Load the Link Register Back
+ B exit2
+
+ExitError
+ ;// Exit When an Error occurs
+
+ M_LDR ppBitStream,pppBitStream
+ M_LDR pBitOffset,ppOffset
+ ;//Ending the macro
+
+ M_BD_FINI ppBitStream,pBitOffset
+ M_LDR LR,pLinkRegister
+ MOV Return,#OMX_Sts_Err
+
+exit2
+
+
+ M_END
+ ENDIF
+
+ END
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_Huff_Tables_VLC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_Huff_Tables_VLC.c
new file mode 100644
index 0000000..ba4d058
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_Huff_Tables_VLC.c
@@ -0,0 +1,211 @@
+ /**
+ *
+ * File Name: armVCM4P2_Huff_Tables_VLC.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * File: armVCM4P2_Huff_Tables_VLC.c
+ * Description: Contains all the Huffman tables used in MPEG4 codec
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+
+#include "armCOMM_Bitstream.h"
+
+
+
+
+// Contains optimized and Packed VLC tables with Last=0 and Last=1
+
+// optimized Packed VLC table Entry Format
+// ---------------------------------------
+//
+// 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
+// +------------------------------------------------+
+// | Len | Run | Level |L | 1 |
+// +------------------------------------------------+
+// | Offset | 0 |
+// +------------------------------------------------+
+// If the table entry is a leaf entry then bit 0 set:
+// Len = Number of bits overread (0 to 7) 3 bits
+// Run = RunLength of the Symbol (0 to 63) 6 bits
+// Level = Level of the Symbol (0 to 31) 5 bits
+// L = Last Value of the Symbol (0 or 1) 1 bit
+//
+// If the table entry is an internal node then bit 0 is clear:
+// Offset = Number of (16-bit) half words from the table
+// start to the next table node
+//
+// The table is accessed by successive lookup up on the
+// next Step bits of the input bitstream until a leaf node
+// is obtained. The Step sizes are supplied to the VLD macro.
+
+// The VLC tables used for Intra and non inta coefficients in non Escape mode
+// contains symbols with both Last=0 and Last=1.
+// If a symbol is not found in the table it will be coded as 0xFFF
+
+
+const OMX_U16 armVCM4P2_InterVlcL0L1[200] = {
+ 0x0020, 0x0108, 0x0148, 0x0170, 0x0178, 0x0180, 0x0188, 0x1b09,
+ 0x4009, 0x4009, 0x4009, 0x4009, 0x2109, 0x2109, 0x0209, 0x0011,
+ 0x0028, 0x0060, 0x00b8, 0x00e0, 0x0030, 0x0048, 0x0050, 0x0058,
+ 0x3fff, 0x3fff, 0x0038, 0x0040, 0x2115, 0x2115, 0x201d, 0x201d,
+ 0x2059, 0x2059, 0x2051, 0x2051, 0x1c0d, 0x1b0d, 0x1a0d, 0x190d,
+ 0x0911, 0x0811, 0x0711, 0x0611, 0x0511, 0x0319, 0x0219, 0x0121,
+ 0x0068, 0x0090, 0x3fff, 0x3fff, 0x0070, 0x0078, 0x0080, 0x0088,
+ 0x2061, 0x2061, 0x2129, 0x2129, 0x3709, 0x3709, 0x3809, 0x3809,
+ 0x3d0d, 0x3d0d, 0x3e0d, 0x3e0d, 0x3f0d, 0x3f0d, 0x200d, 0x200d,
+ 0x0098, 0x00a0, 0x00a8, 0x00b0, 0x0131, 0x0221, 0x0419, 0x0519,
+ 0x0619, 0x0a11, 0x1909, 0x1a09, 0x210d, 0x220d, 0x230d, 0x240d,
+ 0x250d, 0x260d, 0x270d, 0x280d, 0x00c0, 0x00c8, 0x00d0, 0x00d8,
+ 0x0049, 0x0041, 0x380d, 0x380d, 0x370d, 0x370d, 0x360d, 0x360d,
+ 0x350d, 0x350d, 0x340d, 0x340d, 0x330d, 0x330d, 0x320d, 0x320d,
+ 0x00e8, 0x00f0, 0x00f8, 0x0100, 0x310d, 0x310d, 0x2015, 0x2015,
+ 0x3609, 0x3609, 0x3509, 0x3509, 0x3409, 0x3409, 0x3309, 0x3309,
+ 0x3209, 0x3209, 0x3109, 0x3109, 0x0110, 0x0130, 0x0138, 0x0140,
+ 0x0118, 0x0120, 0x0128, 0x100d, 0x3009, 0x3009, 0x2f09, 0x2f09,
+ 0x2411, 0x2411, 0x2311, 0x2311, 0x2039, 0x2039, 0x2031, 0x2031,
+ 0x0f0d, 0x0e0d, 0x0d0d, 0x0c0d, 0x0b0d, 0x0a0d, 0x090d, 0x0e09,
+ 0x0d09, 0x0211, 0x0119, 0x0029, 0x0150, 0x0158, 0x0160, 0x0168,
+ 0x280d, 0x280d, 0x270d, 0x270d, 0x260d, 0x260d, 0x250d, 0x250d,
+ 0x2c09, 0x2c09, 0xb759, 0xb759, 0x2a09, 0x2a09, 0x2021, 0x2021,
+ 0x040d, 0x030d, 0x0b35, 0x010d, 0x0909, 0x0809, 0x0709, 0x0609,
+ 0x0111, 0x0019, 0x2509, 0x2509, 0x2409, 0x2409, 0x2309, 0x2309
+};
+
+
+const OMX_U16 armVCM4P2_IntraVlcL0L1[200] = {
+ 0x0020, 0x0108, 0x0148, 0x0170, 0x0178, 0x0180, 0x0188, 0x0f09,
+ 0x4009, 0x4009, 0x4009, 0x4009, 0x2011, 0x2011, 0x0109, 0x0019,
+ 0x0028, 0x0060, 0x00b8, 0x00e0, 0x0030, 0x0048, 0x0050, 0x0058,
+ 0x3fff, 0x3fff, 0x0038, 0x0040, 0x203d, 0x203d, 0x2035, 0x2035,
+ 0x20b1, 0x20b1, 0x20a9, 0x20a9, 0x0215, 0x011d, 0x002d, 0x0d09,
+ 0x0519, 0x0811, 0x0419, 0x0321, 0x0221, 0x0139, 0x00a1, 0x0099,
+ 0x0068, 0x0090, 0x3fff, 0x3fff, 0x0070, 0x0078, 0x0080, 0x0088,
+ 0x20b9, 0x20b9, 0x20c1, 0x20c1, 0x2141, 0x2141, 0x2911, 0x2911,
+ 0x2315, 0x2315, 0x2415, 0x2415, 0x2f0d, 0x2f0d, 0x300d, 0x300d,
+ 0x0098, 0x00a0, 0x00a8, 0x00b0, 0x00c9, 0x00d1, 0x00d9, 0x0149,
+ 0x0619, 0x0151, 0x0229, 0x0719, 0x0e09, 0x0045, 0x0515, 0x0615,
+ 0x110d, 0x120d, 0x130d, 0x140d, 0x00c0, 0x00c8, 0x00d0, 0x00d8,
+ 0x0091, 0x0089, 0x2e0d, 0x2e0d, 0x2d0d, 0x2d0d, 0x2c0d, 0x2c0d,
+ 0x2b0d, 0x2b0d, 0x2a0d, 0x2a0d, 0x2115, 0x2115, 0x2025, 0x2025,
+ 0x00e8, 0x00f0, 0x00f8, 0x0100, 0x2c09, 0x2c09, 0x2b09, 0x2b09,
+ 0x2711, 0x2711, 0x2611, 0x2611, 0x2511, 0x2511, 0x2319, 0x2319,
+ 0x2219, 0x2219, 0x2131, 0x2131, 0x0110, 0x0130, 0x0138, 0x0140,
+ 0x0118, 0x0120, 0x0128, 0x080d, 0x2129, 0x2129, 0x2081, 0x2081,
+ 0x2411, 0x2411, 0x2079, 0x2079, 0x2071, 0x2071, 0x2069, 0x2069,
+ 0x1bb5, 0x060d, 0x001d, 0xd3f9, 0x0909, 0x0809, 0x090d, 0x0311,
+ 0x0121, 0x0061, 0x0059, 0x0051, 0x0150, 0x0158, 0x0160, 0x0168,
+ 0x240d, 0x240d, 0x230d, 0x230d, 0x2609, 0x2609, 0x250d, 0x250d,
+ 0x2709, 0x2709, 0x2211, 0x2211, 0x2119, 0x2119, 0x2049, 0x2049,
+ 0x0015, 0x0509, 0x020d, 0x010d, 0x0409, 0x0309, 0x0041, 0x0039,
+ 0x0111, 0x0031, 0x2209, 0x2209, 0x2029, 0x2029, 0x2021, 0x2021
+};
+
+const OMX_U16 armVCM4P2_aIntraDCLumaChromaIndex[64] = {
+ 0x0020, 0x000b, 0x2009, 0x2009, 0x2007, 0x2007, 0x2001, 0x2001,
+ 0x4005, 0x4005, 0x4005, 0x4005, 0x4003, 0x4003, 0x4003, 0x4003,
+ 0x0028, 0x000f, 0x200d, 0x200d, 0x0030, 0x0013, 0x2011, 0x2011,
+ 0x0038, 0x0017, 0x2015, 0x2015, 0x3fff, 0x3fff, 0x2019, 0x2019,
+
+ 0x0020, 0x0009, 0x2007, 0x2007, 0x4005, 0x4005, 0x4005, 0x4005,
+ 0x4003, 0x4003, 0x4003, 0x4003, 0x4001, 0x4001, 0x4001, 0x4001,
+ 0x0028, 0x000d, 0x200b, 0x200b, 0x0030, 0x0011, 0x200f, 0x200f,
+ 0x0038, 0x0015, 0x2013, 0x2013, 0x1fff, 0x0019, 0x2017, 0x2017
+};
+
+
+const OMX_U16 armVCM4P2_aVlcMVD[124] = {
+ 0x0010, 0x00f0, 0x0043, 0x003f, 0x4041, 0x4041, 0x4041, 0x4041,
+ 0x0018, 0x00d8, 0x0047, 0x003b, 0x0020, 0x0080, 0x00a8, 0x00d0,
+ 0x0028, 0x0048, 0x0070, 0x0078, 0x1fff, 0x0030, 0x0038, 0x0040,
+ 0x0081, 0x0001, 0x007f, 0x0003, 0x207d, 0x207d, 0x2005, 0x2005,
+ 0x207b, 0x207b, 0x2007, 0x2007, 0x0050, 0x0058, 0x0060, 0x0068,
+ 0x2079, 0x2079, 0x2009, 0x2009, 0x2077, 0x2077, 0x200b, 0x200b,
+ 0x2075, 0x2075, 0x200d, 0x200d, 0x2073, 0x2073, 0x200f, 0x200f,
+ 0x0071, 0x0011, 0x006f, 0x0013, 0x006d, 0x0015, 0x006b, 0x0017,
+ 0x0088, 0x0090, 0x0098, 0x00a0, 0x0069, 0x0019, 0x0067, 0x001b,
+ 0x0065, 0x001d, 0x0063, 0x001f, 0x0061, 0x0021, 0x005f, 0x0023,
+ 0x005d, 0x0025, 0x005b, 0x0027, 0x00b0, 0x00b8, 0x00c0, 0x00c8,
+ 0x0059, 0x0029, 0x0057, 0x002b, 0x2055, 0x2055, 0x202d, 0x202d,
+ 0x2053, 0x2053, 0x202f, 0x202f, 0x2051, 0x2051, 0x2031, 0x2031,
+ 0x204f, 0x204f, 0x2033, 0x2033, 0x00e0, 0x00e8, 0x0049, 0x0039,
+ 0x204d, 0x204d, 0x2035, 0x2035, 0x204b, 0x204b, 0x2037, 0x2037,
+ 0x2045, 0x2045, 0x203d, 0x203d
+};
+
+/* LMAX table for non Inter (Last == 0 and Last=1)
+ Level - 1 Indexed
+ padded armVCM4P2_InterL0L1LMAX[27-31] with zeros to acess entries for Last=1 effectively
+
+*/
+const OMX_U8 armVCM4P2_InterL0L1LMAX[73] =
+{
+ 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,
+ 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
+};
+
+/* RMAX table for non Inter (Last == 0 and Last=1)
+ Level - 1 Indexed
+ padded armVCM4P2_InterL0L1RMAX[12-31] with zeros to access entries for Last=1 table effectively */
+
+
+const OMX_U8 armVCM4P2_InterL0L1RMAX[35] =
+{
+ 26, 10, 6, 2, 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, 40, 1, 0
+};
+
+/* LMAX table for non Intra (Last == 0 and Last=1)
+ Level - 1 Indexed
+ padded armVCM4P2_IntraL0L1LMAX[15-31] with zeros to acess entries for Last=1 effectively
+
+*/
+const OMX_U8 armVCM4P2_IntraL0L1LMAX[53] =
+{
+ 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,
+
+ 8, 3, 2, 2, 2, 2, 2, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+};
+
+
+/* RMAX table for non Inter (Last == 0 and Last=1)
+ Level - 1 Indexed
+ padded armVCM4P2_IntraL0L1RMAX[27-31] with zeros to access entries for Last=1 table effectively */
+
+
+const OMX_U8 armVCM4P2_IntraL0L1RMAX[40] =
+{
+ 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, 0,
+ 0, 0, 0, 0,
+
+ 20, 6, 1, 0, 0, 0, 0, 0
+
+};
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_Lookup_Tables.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_Lookup_Tables.c
new file mode 100644
index 0000000..25cf8db
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_Lookup_Tables.c
@@ -0,0 +1,75 @@
+ /**
+ *
+ * File Name: armVCM4P2_Lookup_Tables.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * File: armVCM4P2_Lookup_Tables.c
+ * Description: Contains all the Lookup tables used in MPEG4 codec
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+
+ /* * Table Entries contain Dc Scaler values
+ * armVCM4P2_DCScaler[i]= 8 for i=1 to 4 and i=33 to 36
+ * = 2*i for i=5 to 8
+ * = i+8 for i=9 to 25
+ * = 2*i-16 for i=26 to 31
+ * = (i-32+13)/2 for i=37 to 59
+ * = i-6-32 for i=60 to 63
+ * = 255 for i=0 and i=32
+ */
+
+const OMX_U8 armVCM4P2_DCScaler[64]={
+ 0xff, 0x8, 0x8, 0x8, 0x8, 0xa, 0xc, 0xe,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e,
+ 0xff, 0x8, 0x8, 0x8, 0x8, 0x9, 0x9, 0xa,
+ 0xa, 0xb, 0xb, 0xc, 0xc, 0xd, 0xd, 0xe,
+ 0xe, 0xf, 0xf, 0x10, 0x10, 0x11, 0x11, 0x12,
+ 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
+
+};
+
+
+ /* Table Entries Contain reciprocal of 1 to 63
+ * armVCM4P2_Reciprocal_QP_S16[i]=round(32767/i)
+ * armVCM4P2_Reciprocal_QP_S16[0]= 0
+ */
+
+const OMX_S16 armVCM4P2_Reciprocal_QP_S16[64]={
+ 0x0000,0x7fff,0x4000,0x2aaa,0x2000,0x1999,0x1555,0x1249,
+ 0x1000,0x0e39,0x0ccd,0x0ba3,0x0aab,0x09d9,0x0925,0x0888,
+ 0x0800,0x0787,0x071c,0x06bd,0x0666,0x0618,0x05d1,0x0591,
+ 0x0555,0x051f,0x04ec,0x04be,0x0492,0x046a,0x0444,0x0421,
+ 0x0400,0x03e1,0x03c4,0x03a8,0x038e,0x0376,0x035e,0x0348,
+ 0x0333,0x031f,0x030c,0x02fa,0x02e9,0x02d8,0x02c8,0x02b9,
+ 0x02ab,0x029d,0x028f,0x0282,0x0276,0x026a,0x025f,0x0254,
+ 0x0249,0x023f,0x0235,0x022b,0x0222,0x0219,0x0211,0x0208
+
+};
+
+ /* Table Entries Contain reciprocal of 1 to 63
+ * armVCM4P2_Reciprocal_QP_S32[i]=round(131071/i)
+ * armVCM4P2_Reciprocal_QP_S32[0]= 0
+ */
+
+const OMX_S32 armVCM4P2_Reciprocal_QP_S32[64]={
+ 0x00000000,0x0001ffff,0x00010000,0x0000aaaa, 0x00008000, 0x00006666, 0x00005555, 0x00004924,
+ 0x00004000,0x000038e3,0x00003333,0x00002e8c, 0x00002aab, 0x00002762, 0x00002492, 0x00002222,
+ 0x00002000,0x00001e1e,0x00001c72,0x00001af2, 0x0000199a, 0x00001861, 0x00001746, 0x00001643,
+ 0x00001555,0x0000147b,0x000013b1,0x000012f6, 0x00001249, 0x000011a8, 0x00001111, 0x00001084,
+ 0x00001000,0x00000f84,0x00000f0f,0x00000ea1, 0x00000e39, 0x00000dd6, 0x00000d79, 0x00000d21,
+ 0x00000ccd,0x00000c7d,0x00000c31,0x00000be8, 0x00000ba3, 0x00000b61, 0x00000b21, 0x00000ae5,
+ 0x00000aab,0x00000a73,0x00000a3d,0x00000a0a, 0x000009d9, 0x000009a9, 0x0000097b, 0x0000094f,
+ 0x00000925,0x000008fb,0x000008d4,0x000008ae, 0x00000889, 0x00000865, 0x00000842, 0x00000820
+
+};
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_SetPredDir_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_SetPredDir_s.s
new file mode 100644
index 0000000..3f92d85
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_SetPredDir_s.s
@@ -0,0 +1,104 @@
+;//
+;//
+;// File Name: armVCM4P2_SetPredDir_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 9641
+;// Date: Thursday, February 7, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+; **
+; * Function: armVCM4P2_SetPredDir
+; *
+; * Description:
+; * Performs detecting the prediction direction
+; *
+; * Remarks:
+; *
+; * Parameters:
+; * [in] blockIndex block index indicating the component type and
+; * position as defined in subclause 6.1.3.8, of ISO/IEC
+; * 14496-2. Furthermore, indexes 6 to 9 indicate the
+; * alpha blocks spatially corresponding to luminance
+; * blocks 0 to 3 in the same macroblock.
+; * [in] pCoefBufRow pointer to the coefficient row buffer
+; * [in] pQpBuf pointer to the quantization parameter buffer
+; * [out]predQP quantization parameter of the predictor block
+; * [out]predDir indicates the prediction direction which takes one
+; * of the following values:
+; * OMX_VC_HORIZONTAL predict horizontally
+; * OMX_VC_VERTICAL predict vertically
+; *
+; * Return Value:
+; * Standard OMXResult result. See enumeration for possible result codes.
+; *
+; */
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+ INCLUDE omxVC_s.h
+
+
+ M_VARIANTS ARM1136JS
+
+
+ IF ARM1136JS
+
+;// Input Arguments
+BlockIndex RN 0
+pCoefBufRow RN 1
+pCoefBufCol RN 2
+predDir RN 3
+predQP RN 4
+pQpBuf RN 5
+
+;// Local Variables
+
+Return RN 0
+blockDCLeft RN 6
+blockDCTop RN 7
+blockDCTopLeft RN 8
+temp1 RN 9
+temp2 RN 14
+
+ M_START armVCM4P2_SetPredDir,r9
+
+ M_ARG ppredQP,4
+ M_ARG ppQpBuf,4
+
+ LDRH blockDCTopLeft,[pCoefBufRow,#-16]
+ LDRH blockDCLeft,[pCoefBufCol]
+
+ TEQ BlockIndex,#3
+ LDREQH blockDCTop,[pCoefBufCol,#-16]
+ LDRNEH blockDCTop,[pCoefBufRow]
+
+ SUBS temp1,blockDCLeft,blockDCTopLeft
+ RSBLT temp1,temp1,#0
+ SUBS temp2,blockDCTopLeft,blockDCTop
+ RSBLT temp2,temp2,#0
+
+ M_LDR pQpBuf,ppQpBuf
+ M_LDR predQP,ppredQP
+ CMP temp1,temp2
+ MOV temp2,#OMX_VC_VERTICAL
+ LDRLTB temp1,[pQpBuf,#1]
+ STRLT temp2,[predDir]
+ STRLT temp1,[predQP]
+ MOV temp2,#OMX_VC_HORIZONTAL
+ LDRGEB temp1,[pQpBuf]
+ STRGE temp2,[predDir]
+ MOV Return,#OMX_Sts_NoErr
+ STRGE temp1,[predQP]
+
+
+
+ M_END
+
+ ENDIF
+
+ END
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_Zigzag_Tables.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_Zigzag_Tables.c
new file mode 100644
index 0000000..ed17f9b
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_Zigzag_Tables.c
@@ -0,0 +1,61 @@
+/**
+ *
+ * File Name: armVCM4P2_Zigzag_Tables.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * File: armVCM4P2_ZigZag_Tables.c
+ * Description: Contains the zigzag tables
+ *
+ */
+
+#include "omxtypes.h"
+
+/* Contains Double the values in the reference Zigzag Table
+ * Contains Classical,Vetical and Horizontal Zigzagscan tables in one array
+ */
+
+const OMX_U8 armVCM4P2_aClassicalZigzagScan [192] =
+{
+ 0, 2, 16, 32, 18, 4, 6, 20,
+ 34, 48, 64, 50, 36, 22, 8, 10,
+ 24, 38, 52, 66, 80, 96, 82, 68,
+ 54, 40, 26, 12, 14, 28, 42, 56,
+ 70, 84, 98, 112, 114, 100, 86, 72,
+ 58, 44, 30, 46, 60, 74, 88, 102,
+ 116, 118, 104, 90, 76, 62, 78, 92,
+ 106, 120, 122, 104, 94, 110, 124, 126,
+
+ 0, 16, 32, 48, 2, 18, 4, 20,
+ 34, 50, 64, 80, 96, 112, 114, 98,
+ 82, 66, 52, 36, 6, 22, 8, 24,
+ 38, 54, 68, 84, 100, 116, 70, 86,
+ 102, 118, 40, 56, 10, 26, 12, 28,
+ 42, 58, 72, 88, 104, 120, 74, 90,
+ 106, 122, 44, 60, 14, 30, 46, 62,
+ 76, 92, 108, 124, 78, 94, 110, 126,
+
+ 0, 2, 4, 6, 16, 18, 32, 34,
+ 20, 22, 8, 10, 12, 14, 30, 28,
+ 26, 24, 38, 36, 48, 50, 64, 66,
+ 52, 54, 40, 42, 44, 46, 56, 58,
+ 60, 62, 68, 70, 80, 82, 96, 98,
+ 84, 86, 72, 74, 76, 78, 88, 90,
+ 92, 94, 100, 102, 112, 114, 116, 118,
+ 104, 106, 108, 110, 120, 122, 124, 126
+
+
+};
+
+
+
+
+
+/* End of file */
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Inter.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Inter.c
new file mode 100644
index 0000000..b63d295
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Inter.c
@@ -0,0 +1,102 @@
+/**
+ *
+ * File Name: omxVCM4P2_DecodeBlockCoef_Inter.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains modules for inter reconstruction
+ *
+ */
+
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+
+
+/**
+ * Function: omxVCM4P2_DecodeBlockCoef_Inter
+ *
+ * Description:
+ * Decodes the INTER block coefficients. Inverse quantization, inversely zigzag
+ * positioning and IDCT, with appropriate clipping on each step, are performed
+ * on the coefficients. The results (residuals) are placed in a contiguous array
+ * of 64 elements. For INTER block, the output buffer holds the residuals for
+ * further reconstruction.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream pointer to the pointer to the current byte in
+ * the bit stream buffer. There is no boundary
+ * check for the bit stream buffer.
+ * [in] pBitOffset pointer to the bit position in the byte pointed
+ * to by *ppBitStream. *pBitOffset is valid within
+ * [0-7]
+ * [in] QP quantization parameter
+ * [in] shortVideoHeader a flag indicating presence of short_video_header;
+ * shortVideoHeader==1 indicates using quantization method defined in short
+ * video header mode, and shortVideoHeader==0 indicates normail quantization method.
+ * [out] ppBitStream *ppBitStream is updated after the block is decoded, so that it points to the
+ * current byte in the bit stream buffer.
+ * [out] pBitOffset *pBitOffset is updated so that it points to the current bit position in the
+ * byte pointed by *ppBitStream
+ * [out] pDst pointer to the decoded residual buffer (a contiguous array of 64 elements of
+ * OMX_S16 data type). Must be 16-byte aligned.
+ *
+ * Return Value:
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments
+ * - At least one of the following pointers is Null: ppBitStream, *ppBitStream, pBitOffset , pDst
+ * - At least one of the below case:
+ * - *pBitOffset exceeds [0,7], QP <= 0;
+ * - pDst not 16-byte aligned
+ * OMX_Sts_Err - status error
+ *
+ */
+OMXResult omxVCM4P2_DecodeBlockCoef_Inter(
+ const OMX_U8 ** ppBitStream,
+ OMX_INT * pBitOffset,
+ OMX_S16 * pDst,
+ OMX_INT QP,
+ OMX_INT shortVideoHeader
+)
+{
+ /* 64 elements are needed but to align it to 16 bytes need
+ 15 more elements of padding */
+ OMX_S16 tempBuf[79];
+ OMX_S16 *pTempBuf1;
+ OMXResult errorCode;
+ /* Aligning the local buffers */
+ pTempBuf1 = armAlignTo16Bytes(tempBuf);
+
+
+ /* VLD and zigzag */
+ errorCode = omxVCM4P2_DecodeVLCZigzag_Inter(ppBitStream, pBitOffset,
+ pTempBuf1,shortVideoHeader);
+ armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode);
+
+ /* Dequantization */
+ errorCode = omxVCM4P2_QuantInvInter_I(
+ pTempBuf1,
+ QP);
+ armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode);
+
+ /* Inverse transform */
+ errorCode = omxVCM4P2_IDCT8x8blk(pTempBuf1, pDst);
+ armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode);
+
+ return OMX_Sts_NoErr;
+}
+
+/* End of file */
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Intra.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Intra.c
new file mode 100644
index 0000000..c609a60
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Intra.c
@@ -0,0 +1,208 @@
+/**
+ *
+ * File Name: omxVCM4P2_DecodeBlockCoef_Intra.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains modules for intra reconstruction
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/**
+ * Function: omxVCM4P2_DecodeBlockCoef_Intra
+ *
+ * Description:
+ * Decodes the INTRA block coefficients. Inverse quantization, inversely zigzag
+ * positioning, and IDCT, with appropriate clipping on each step, are performed
+ * on the coefficients. The results are then placed in the output frame/plane on
+ * a pixel basis. For INTRA block, the output values are clipped to [0, 255] and
+ * written to corresponding block buffer within the destination plane.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream pointer to the pointer to the current byte in
+ * the bit stream buffer. There is no boundary
+ * check for the bit stream buffer.
+ * [in] pBitOffset pointer to the bit position in the byte pointed
+ * to by *ppBitStream. *pBitOffset is valid within
+ * [0-7].
+ * [in] step width of the destination plane
+ * [in/out] pCoefBufRow [in] pointer to the coefficient row buffer
+ * [out] updated coefficient rwo buffer
+ * [in/out] pCoefBufCol [in] pointer to the coefficient column buffer
+ * [out] updated coefficient column buffer
+ * [in] curQP quantization parameter of the macroblock which
+ * the current block belongs to
+ * [in] pQpBuf Pointer to a 2-element QP array. pQpBuf[0] holds the QP of the 8x8 block left to
+ * the current block(QPa). pQpBuf[1] holds the QP of the 8x8 block just above the
+ * current block(QPc).
+ * Note, in case the corresponding block is out of VOP bound, the QP value will have
+ * no effect to the intra-prediction process. Refer to subclause "7.4.3.3 Adaptive
+ * ac coefficient prediction" of ISO/IEC 14496-2(MPEG4 Part2) for accurate description.
+ * [in] blockIndex block index indicating the component type and
+ * position as defined in subclause 6.1.3.8,
+ * Figure 6-5 of ISO/IEC 14496-2.
+ * [in] intraDCVLC a code determined by intra_dc_vlc_thr and QP.
+ * This allows a mechanism to switch between two VLC
+ * for coding of Intra DC coefficients as per Table
+ * 6-21 of ISO/IEC 14496-2.
+ * [in] ACPredFlag a flag equal to ac_pred_flag (of luminance) indicating
+ * if the ac coefficients of the first row or first
+ * column are differentially coded for intra coded
+ * macroblock.
+ * [in] shortVideoHeader a flag indicating presence of short_video_header;
+ * shortVideoHeader==1 selects linear intra DC mode,
+ * and shortVideoHeader==0 selects nonlinear intra DC mode.
+ * [out] ppBitStream *ppBitStream is updated after the block is
+ * decoded, so that it points to the current byte
+ * in the bit stream buffer
+ * [out] pBitOffset *pBitOffset is updated so that it points to the
+ * current bit position in the byte pointed by
+ * *ppBitStream
+ * [out] pDst pointer to the block in the destination plane.
+ * pDst should be 16-byte aligned.
+ * [out] pCoefBufRow pointer to the updated coefficient row buffer.
+ *
+ * Return Value:
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments
+ * - At least one of the following pointers is NULL: ppBitStream, *ppBitStream, pBitOffset,
+ * pCoefBufRow, pCoefBufCol, pQPBuf, pDst.
+ * or
+ * - At least one of the below case: *pBitOffset exceeds [0,7], curQP exceeds (1, 31),
+ * blockIndex exceeds [0,9], step is not the multiple of 8, intraDCVLC is zero while
+ * blockIndex greater than 5.
+ * or
+ * - pDst is not 16-byte aligned
+ * OMX_Sts_Err - status error
+ *
+ */
+
+OMXResult omxVCM4P2_DecodeBlockCoef_Intra(
+ const OMX_U8 ** ppBitStream,
+ OMX_INT *pBitOffset,
+ OMX_U8 *pDst,
+ OMX_INT step,
+ OMX_S16 *pCoefBufRow,
+ OMX_S16 *pCoefBufCol,
+ OMX_U8 curQP,
+ const OMX_U8 *pQPBuf,
+ OMX_INT blockIndex,
+ OMX_INT intraDCVLC,
+ OMX_INT ACPredFlag,
+ OMX_INT shortVideoHeader
+ )
+{
+ OMX_S16 tempBuf1[79], tempBuf2[79];
+ OMX_S16 *pTempBuf1, *pTempBuf2;
+ OMX_INT predDir, predACDir;
+ OMX_INT predQP;
+ OMXVCM4P2VideoComponent videoComp;
+ OMXResult errorCode;
+
+
+ /* Aligning the local buffers */
+ pTempBuf1 = armAlignTo16Bytes(tempBuf1);
+ pTempBuf2 = armAlignTo16Bytes(tempBuf2);
+
+ /* Setting the AC prediction direction and prediction direction */
+ armVCM4P2_SetPredDir(
+ blockIndex,
+ pCoefBufRow,
+ pCoefBufCol,
+ &predDir,
+ &predQP,
+ pQPBuf);
+
+ predACDir = predDir;
+
+
+ if (ACPredFlag == 0)
+ {
+ predACDir = OMX_VC_NONE;
+ }
+
+ /* Setting the videoComp */
+ if (blockIndex <= 3)
+ {
+ videoComp = OMX_VC_LUMINANCE;
+ }
+ else
+ {
+ videoComp = OMX_VC_CHROMINANCE;
+ }
+
+
+ /* VLD and zigzag */
+ if (intraDCVLC == 1)
+ {
+ errorCode = omxVCM4P2_DecodeVLCZigzag_IntraDCVLC(
+ ppBitStream,
+ pBitOffset,
+ pTempBuf1,
+ predACDir,
+ shortVideoHeader,
+ videoComp);
+ armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode);
+ }
+ else
+ {
+ errorCode = omxVCM4P2_DecodeVLCZigzag_IntraACVLC(
+ ppBitStream,
+ pBitOffset,
+ pTempBuf1,
+ predACDir,
+ shortVideoHeader);
+ armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode);
+ }
+
+ /* AC DC prediction */
+ errorCode = omxVCM4P2_PredictReconCoefIntra(
+ pTempBuf1,
+ pCoefBufRow,
+ pCoefBufCol,
+ curQP,
+ predQP,
+ predDir,
+ ACPredFlag,
+ videoComp);
+ armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode);
+
+ /* Dequantization */
+ errorCode = omxVCM4P2_QuantInvIntra_I(
+ pTempBuf1,
+ curQP,
+ videoComp,
+ shortVideoHeader);
+ armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode);
+
+ /* Inverse transform */
+ errorCode = omxVCM4P2_IDCT8x8blk (pTempBuf1, pTempBuf2);
+ armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode);
+
+ /* Placing the linear array into the destination plane and clipping
+ it to 0 to 255 */
+
+ armVCM4P2_Clip8(pTempBuf2,pDst,step);
+
+
+ return OMX_Sts_NoErr;
+}
+
+/* End of file */
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodePadMV_PVOP_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodePadMV_PVOP_s.s
new file mode 100644
index 0000000..a1861da
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodePadMV_PVOP_s.s
@@ -0,0 +1,364 @@
+; **********
+; *
+; * File Name: omxVCM4P2_DecodePadMV_PVOP_s.s
+; * OpenMAX DL: v1.0.2
+; * Revision: 9641
+; * Date: Thursday, February 7, 2008
+; *
+; * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+; *
+; *
+; *
+; **
+; * Function: omxVCM4P2_DecodePadMV_PVOP
+; *
+; * Description:
+; * Decodes and pads four motion vectors of the non-intra macroblock in P-VOP.
+; * The motion vector padding process is specified in subclause 7.6.1.6 of
+; * ISO/IEC 14496-2.
+; *
+; * Remarks:
+; *
+; *
+; * Parameters:
+; * [in] ppBitStream pointer to the pointer to the current byte in
+; * the bit stream buffer
+; * [in] pBitOffset pointer to the bit position in the byte pointed
+; * to by *ppBitStream. *pBitOffset is valid within
+; * [0-7].
+; * [in] pSrcMVLeftMB pointers to the motion vector buffers of the
+; * macroblocks specially at the left side of the current macroblock
+; * respectively.
+; * [in] pSrcMVUpperMB pointers to the motion vector buffers of the
+; * macroblocks specially at the upper side of the current macroblock
+; * respectively.
+; * [in] pSrcMVUpperRightMB pointers to the motion vector buffers of the
+; * macroblocks specially at the upper-right side of the current macroblock
+; * respectively.
+; * [in] fcodeForward a code equal to vop_fcode_forward in MPEG-4
+; * bit stream syntax
+; * [in] MBType the type of the current macroblock. If MBType
+; * is not equal to OMX_VC_INTER4V, the destination
+; * motion vector buffer is still filled with the
+; * same decoded vector.
+; * [out] ppBitStream *ppBitStream is updated after the block is decoded,
+; * so that it points to the current byte in the bit
+; * stream buffer
+; * [out] pBitOffset *pBitOffset is updated so that it points to the
+; * current bit position in the byte pointed by
+; * *ppBitStream
+; * [out] pDstMVCurMB pointer to the motion vector buffer of the current
+; * macroblock which contains four decoded motion vectors
+; *
+; * Return Value:
+; * OMX_Sts_NoErr -no error
+; *
+; *
+; * OMX_Sts_Err - status error
+; *
+; *
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+ INCLUDE armCOMM_BitDec_s.h
+ INCLUDE omxVC_s.h
+
+ M_VARIANTS ARM1136JS
+
+
+
+
+ IF ARM1136JS
+
+;//Input Arguments
+
+ppBitStream RN 0
+pBitOffset RN 1
+pSrcMVLeftMB RN 2
+pSrcMVUpperMB RN 3
+pSrcMVUpperRightMB RN 4
+pDstMVCurMB RN 5
+fcodeForward RN 6
+MBType RN 7
+
+;//Local Variables
+
+zero RN 4
+one RN 4
+scaleFactor RN 1
+
+
+Return RN 0
+
+VlcMVD RN 0
+index RN 4
+Count RN 7
+
+mvHorData RN 4
+mvHorResidual RN 0
+
+mvVerData RN 4
+mvVerResidual RN 0
+
+temp RN 1
+
+temp1 RN 3
+High RN 4
+Low RN 2
+Range RN 1
+
+BlkCount RN 14
+
+diffMVdx RN 0
+diffMVdy RN 1
+
+;// Scratch Registers
+
+RBitStream RN 8
+RBitCount RN 9
+RBitBuffer RN 10
+
+T1 RN 11
+T2 RN 12
+LR RN 14
+
+ IMPORT armVCM4P2_aVlcMVD
+ IMPORT omxVCM4P2_FindMVpred
+
+ ;// Allocate stack memory
+
+ M_ALLOC4 ppDstMVCurMB,4
+ M_ALLOC4 pDstMVPredME,4
+ M_ALLOC4 pBlkCount,4
+
+ M_ALLOC4 pppBitStream,4
+ M_ALLOC4 ppBitOffset,4
+ M_ALLOC4 ppSrcMVLeftMB,4
+ M_ALLOC4 ppSrcMVUpperMB,4
+
+ M_ALLOC4 pdiffMVdx,4
+ M_ALLOC4 pdiffMVdy,4
+ M_ALLOC4 pHigh,4
+
+
+
+
+ M_START omxVCM4P2_DecodePadMV_PVOP,r11
+
+ M_ARG pSrcMVUpperRightMBonStack,4 ;// pointer to pSrcMVUpperRightMB on stack
+ M_ARG pDstMVCurMBonStack,4 ;// pointer to pDstMVCurMB on stack
+ M_ARG fcodeForwardonStack,4 ;// pointer to fcodeForward on stack
+ M_ARG MBTypeonStack,4 ;// pointer to MBType on stack
+
+
+
+
+
+ ;// Initializing the BitStream Macro
+
+ M_BD_INIT0 ppBitStream, pBitOffset, RBitStream, RBitBuffer, RBitCount
+ M_LDR MBType,MBTypeonStack ;// Load MBType from stack
+ M_LDR pDstMVCurMB,pDstMVCurMBonStack ;// Load pDstMVCurMB from stack
+ MOV zero,#0
+
+ TEQ MBType,#OMX_VC_INTRA ;// Check if MBType=OMX_VC_INTRA
+ TEQNE MBType,#OMX_VC_INTRA_Q ;// check if MBType=OMX_VC_INTRA_Q
+ STREQ zero,[pDstMVCurMB]
+ M_BD_INIT1 T1, T2, T2
+ STREQ zero,[pDstMVCurMB,#4]
+ M_BD_INIT2 T1, T2, T2
+ STREQ zero,[pDstMVCurMB,#4]
+ MOVEQ Return,#OMX_Sts_NoErr
+ MOV BlkCount,#0
+ STREQ zero,[pDstMVCurMB,#4]
+
+ BEQ ExitOK
+
+ TEQ MBType,#OMX_VC_INTER4V ;// Check if MBType=OMX_VC_INTER4V
+ TEQNE MBType,#OMX_VC_INTER4V_Q ;// Check if MBType=OMX_VC_INTER4V_Q
+ MOVEQ Count,#4
+
+ TEQ MBType,#OMX_VC_INTER ;// Check if MBType=OMX_VC_INTER
+ TEQNE MBType,#OMX_VC_INTER_Q ;// Check if MBType=OMX_VC_INTER_Q
+ MOVEQ Count,#1
+
+ M_LDR fcodeForward,fcodeForwardonStack ;// Load fcodeForward from stack
+
+ ;// Storing the values temporarily on stack
+
+ M_STR ppBitStream,pppBitStream
+ M_STR pBitOffset,ppBitOffset
+
+
+ SUB temp,fcodeForward,#1 ;// temp=fcodeForward-1
+ MOV one,#1
+ M_STR pSrcMVLeftMB,ppSrcMVLeftMB
+ LSL scaleFactor,one,temp ;// scaleFactor=1<<(fcodeForward-1)
+ M_STR pSrcMVUpperMB,ppSrcMVUpperMB
+ LSL scaleFactor,scaleFactor,#5
+ M_STR scaleFactor,pHigh ;// [pHigh]=32*scaleFactor
+
+ ;// VLD Decoding
+
+
+Loop
+
+ LDR VlcMVD, =armVCM4P2_aVlcMVD ;// Load the optimized MVD VLC table
+
+ ;// Horizontal Data and Residual calculation
+
+ LDR temp,=0xFFF
+ M_BD_VLD index,T1,T2,VlcMVD,3,2 ;// variable lenght decoding using the macro
+
+ TEQ index,temp
+ BEQ ExitError ;// Exit with an Error Message if the decoded symbol is an invalied symbol
+
+ SUB mvHorData,index,#32 ;// mvHorData=index-32
+ MOV mvHorResidual,#1 ;// mvHorResidual=1
+ CMP fcodeForward,#1
+ TEQNE mvHorData,#0
+ MOVEQ diffMVdx,mvHorData ;// if scaleFactor=1(fcodeForward=1) or mvHorData=0 diffMVdx=mvHorData
+ BEQ VerticalData
+
+ SUB temp,fcodeForward,#1
+ M_BD_VREAD8 mvHorResidual,temp,T1,T2 ;// get mvHorResidual from bitstream if fcodeForward>1 and mvHorData!=0
+
+ CMP mvHorData,#0
+ RSBLT mvHorData,mvHorData,#0 ;// mvHorData=abs(mvHorData)
+ SUB mvHorResidual,mvHorResidual,fcodeForward
+ SMLABB diffMVdx,mvHorData,fcodeForward,mvHorResidual ;// diffMVdx=abs(mvHorData)*fcodeForward+mvHorResidual-fcodeForward
+ ADD diffMVdx,diffMVdx,#1
+ RSBLT diffMVdx,diffMVdx,#0
+
+ ;// Vertical Data and Residual calculation
+
+VerticalData
+
+ M_STR diffMVdx,pdiffMVdx ;// Store the diffMVdx on stack
+ LDR VlcMVD, =armVCM4P2_aVlcMVD ;// Loading the address of optimized VLC tables
+
+ LDR temp,=0xFFF
+ M_BD_VLD index,T1,T2,VlcMVD,3,2 ;// VLC decoding using the macro
+
+ TEQ index,temp
+ BEQ ExitError ;// Exit with an Error Message if an Invalied Symbol occurs
+
+ SUB mvVerData,index,#32 ;// mvVerData=index-32
+ MOV mvVerResidual,#1
+ CMP fcodeForward,#1
+ TEQNE mvVerData,#0
+ MOVEQ diffMVdy,mvVerData ;// diffMVdy = mvVerData if scaleFactor=1(fcodeForward=1) or mvVerData=0
+ BEQ FindMVPred
+
+ SUB temp,fcodeForward,#1
+ M_BD_VREAD8 mvVerResidual,temp,T1,T2 ;// Get mvVerResidual from bit stream if fcodeForward>1 and mnVerData!=0
+
+
+ CMP mvVerData,#0
+ RSBLT mvVerData,mvVerData,#0
+ SUB mvVerResidual,mvVerResidual,fcodeForward
+ SMLABB diffMVdy,mvVerData,fcodeForward,mvVerResidual ;// diffMVdy=abs(mvVerData)*fcodeForward+mvVerResidual-fcodeForward
+ ADD diffMVdy,diffMVdy,#1
+ RSBLT diffMVdy,diffMVdy,#0
+
+ ;//Calling the Function omxVCM4P2_FindMVpred
+
+FindMVPred
+
+ M_STR diffMVdy,pdiffMVdy
+ ADD temp,pDstMVCurMB,BlkCount,LSL #2 ;// temp=pDstMVCurMB[BlkCount]
+ M_STR temp,ppDstMVCurMB ;// store temp on stack for passing as an argument to FindMVPred
+
+ MOV temp,#0
+ M_STR temp,pDstMVPredME ;// Pass pDstMVPredME=NULL as an argument
+ M_STR BlkCount,pBlkCount ;// Passs BlkCount as Argument through stack
+
+ MOV temp,pSrcMVLeftMB ;// temp (RN 1)=pSrcMVLeftMB
+ M_LDR pSrcMVUpperRightMB,pSrcMVUpperRightMBonStack
+ MOV pSrcMVLeftMB,pSrcMVUpperMB ;// pSrcMVLeftMB ( RN 2) = pSrcMVUpperMB
+ MOV ppBitStream,pDstMVCurMB ;// ppBitStream ( RN 0) = pDstMVCurMB
+ MOV pSrcMVUpperMB,pSrcMVUpperRightMB ;// pSrcMVUpperMB( RN 3) = pSrcMVUpperRightMB
+ BL omxVCM4P2_FindMVpred ;// Branch to subroutine omxVCM4P2_FindMVpred
+
+ ;// Store Horizontal Motion Vector
+
+ M_LDR BlkCount,pBlkCount ;// Load BlkCount from stack
+ M_LDR High,pHigh ;// High=32*scaleFactor
+ LSL temp1,BlkCount,#2 ;// temp=BlkCount*4
+ M_LDR diffMVdx,pdiffMVdx ;// Laad diffMVdx
+
+ LDRSH temp,[pDstMVCurMB,temp1] ;// temp=pDstMVCurMB[BlkCount]
+
+
+ RSB Low,High,#0 ;// Low = -32*scaleFactor
+ ADD diffMVdx,temp,diffMVdx ;// diffMVdx=pDstMVCurMB[BlkCount]+diffMVdx
+ ADD Range,High,High ;// Range=64*ScaleFactor
+ SUB High,High,#1 ;// High= 32*scaleFactor-1
+
+ CMP diffMVdx,Low ;// If diffMVdx<Low
+ ADDLT diffMVdx,diffMVdx,Range ;// diffMVdx+=Range
+
+ CMP diffMVdx,High
+ SUBGT diffMVdx,diffMVdx,Range ;// If diffMVdx > High diffMVdx-=Range
+ STRH diffMVdx,[pDstMVCurMB,temp1]
+
+ ;// Store Vertical
+
+ ADD temp1,temp1,#2 ;// temp1=4*BlkCount+2
+ M_LDR diffMVdx,pdiffMVdy ;// Laad diffMVdy
+ LDRSH temp,[pDstMVCurMB,temp1] ;// temp=pDstMVCurMB[BlkCount].diffMVdy
+ ADD BlkCount,BlkCount,#1 ;// BlkCount=BlkCount+1
+ ADD diffMVdx,temp,diffMVdx
+ CMP diffMVdx,Low
+ ADDLT diffMVdx,diffMVdx,Range ;// If diffMVdy<Low diffMVdy+=Range
+ CMP diffMVdx,High
+ SUBGT diffMVdx,diffMVdx,Range ;// If diffMVdy > High diffMVdy-=Range
+ STRH diffMVdx,[pDstMVCurMB,temp1]
+
+ CMP BlkCount,Count
+ M_LDR pSrcMVLeftMB,ppSrcMVLeftMB
+ M_LDR pSrcMVUpperMB,ppSrcMVUpperMB
+
+ BLT Loop ;// If BlkCount<Count Continue the Loop
+
+
+ ;// If MBType=OMX_VC_INTER or MBtype=OMX_VC_INTER_Q copy pDstMVCurMB[0] to
+ ;// pDstMVCurMB[1], pDstMVCurMB[2], pDstMVCurMB[3]
+
+ M_LDR MBType,MBTypeonStack
+
+ TEQ MBType,#OMX_VC_INTER
+ TEQNE MBType,#OMX_VC_INTER_Q
+ LDREQ temp,[pDstMVCurMB]
+ M_LDR ppBitStream,pppBitStream
+ STREQ temp,[pDstMVCurMB,#4]
+
+ STREQ temp,[pDstMVCurMB,#8]
+ STREQ temp,[pDstMVCurMB,#12]
+
+
+ M_LDR pBitOffset,ppBitOffset
+ ;//Ending the macro
+ M_BD_FINI ppBitStream,pBitOffset ;// Finishing the Macro
+
+
+ MOV Return,#OMX_Sts_NoErr
+ B ExitOK
+
+ExitError
+
+ M_LDR ppBitStream,pppBitStream
+ M_LDR pBitOffset,ppBitOffset
+ ;//Ending the macro
+ M_BD_FINI ppBitStream,pBitOffset
+
+ MOV Return,#OMX_Sts_Err
+
+ExitOK
+
+ M_END
+ ENDIF
+ END
+
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_Inter_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_Inter_s.s
new file mode 100644
index 0000000..c43b253
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_Inter_s.s
@@ -0,0 +1,132 @@
+;/**
+; *
+; * File Name: omxVCM4P2_DecodeVLCZigzag_Inter_s.s
+; * OpenMAX DL: v1.0.2
+; * Revision: 9641
+; * Date: Thursday, February 7, 2008
+; *
+; * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+; *
+; *
+; *
+; * Description:
+; * Contains modules for zigzag scanning and VLC decoding
+; * for inter block.
+; *
+; *
+; *
+; * Function: omxVCM4P2_DecodeVLCZigzag_Inter
+; *
+; * Description:
+; * Performs VLC decoding and inverse zigzag scan for one inter coded block.
+; *
+; * Remarks:
+; *
+; * Parameters:
+; * [in] ppBitStream pointer to the pointer to the current byte in
+; * the bitstream buffer
+; * [in] pBitOffset pointer to the bit position in the byte pointed
+; * to by *ppBitStream. *pBitOffset is valid within [0-7].
+; * [in] shortVideoHeader binary flag indicating presence of short_video_header;
+; * escape modes 0-3 are used if shortVideoHeader==0,
+; * and escape mode 4 is used when shortVideoHeader==1.
+; * [out] ppBitStream *ppBitStream is updated after the block is
+; * decoded, so that it points to the current byte
+; * in the bit stream buffer
+; * [out] pBitOffset *pBitOffset is updated so that it points to the
+; * current bit position in the byte pointed by
+; * *ppBitStream
+; * [out] pDst pointer to the coefficient buffer of current
+; * block. Must be 16-byte aligned
+; *
+; * Return Value:
+; * OMX_Sts_BadArgErr - bad arguments
+; * -At least one of the following pointers is NULL: ppBitStream, *ppBitStream, pBitOffset, pDst, or
+; * -pDst is not 16-byte aligned, or
+; * -*pBitOffset exceeds [0,7].
+; * OMX_Sts_Err - status error
+; * -At least one mark bit is equal to zero
+; * -Encountered an illegal stream code that cannot be found in the VLC table
+; * -Encountered and illegal code in the VLC FLC table
+; * -The number of coefficients is greater than 64
+; *
+; */
+
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+ INCLUDE armCOMM_BitDec_s.h
+
+
+ M_VARIANTS ARM1136JS
+
+
+
+
+
+ IF ARM1136JS
+
+ ;// Import various tables needed for the function
+
+
+ IMPORT armVCM4P2_InterVlcL0L1 ;// Contains optimized and packed VLC Tables for both Last =1 and last=0
+ ;// Packed in Run:Level:Last format
+ IMPORT armVCM4P2_InterL0L1LMAX ;// Contains LMAX table entries with both Last=0 and Last=1
+ IMPORT armVCM4P2_InterL0L1RMAX ;// Contains RMAX table entries with both Last=0 and Last=1
+ IMPORT armVCM4P2_aClassicalZigzagScan ;// contains classical Zigzag table entries with double the original values
+ IMPORT armVCM4P2_DecodeVLCZigzag_AC_unsafe
+
+
+
+;//Input Arguments
+
+ppBitStream RN 0
+pBitOffset RN 1
+pDst RN 2
+shortVideoHeader RN 3
+
+;//Local Variables
+
+Return RN 0
+
+pVlcTableL0L1 RN 4
+pLMAXTableL0L1 RN 4
+pRMAXTableL0L1 RN 4
+pZigzagTable RN 4
+Count RN 6
+
+
+
+ ;// Allocate stack memory to store the VLC,Zigzag,LMAX and RMAX tables
+
+
+ M_ALLOC4 ppVlcTableL0L1,4
+ M_ALLOC4 ppLMAXTableL0L1,4
+ M_ALLOC4 ppRMAXTableL0L1,4
+ M_ALLOC4 ppZigzagTable,4
+
+
+ M_START omxVCM4P2_DecodeVLCZigzag_Inter,r12
+
+
+
+
+ LDR pZigzagTable, =armVCM4P2_aClassicalZigzagScan ;// Load zigzag table
+ M_STR pZigzagTable,ppZigzagTable ;// Store zigzag table on stack to pass as argument to unsafe function
+ LDR pVlcTableL0L1, =armVCM4P2_InterVlcL0L1 ;// Load optimized VLC table with both L=0 and L=1 entries
+ M_STR pVlcTableL0L1,ppVlcTableL0L1 ;// Store optimized VLC table address on stack
+ LDR pLMAXTableL0L1, =armVCM4P2_InterL0L1LMAX ;// Load Interleaved L=0 and L=1 LMAX Tables
+ M_STR pLMAXTableL0L1,ppLMAXTableL0L1 ;// Store LMAX table address on stack
+ LDR pRMAXTableL0L1, =armVCM4P2_InterL0L1RMAX ;// Load Interleaved L=0 and L=1 RMAX Tables
+ MOV Count,#0 ;// set start=0
+ M_STR pRMAXTableL0L1,ppRMAXTableL0L1 ;// store RMAX table address on stack
+
+
+ BL armVCM4P2_DecodeVLCZigzag_AC_unsafe ;// call Unsafe Function for VLC Zigzag Decoding
+
+
+
+ M_END
+ ENDIF
+
+ END
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraACVLC_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraACVLC_s.s
new file mode 100644
index 0000000..166729e
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraACVLC_s.s
@@ -0,0 +1,136 @@
+;/**
+; *
+; * File Name: omxVCM4P2_DecodeVLCZigzag_IntraACVLC_s.s
+; * OpenMAX DL: v1.0.2
+; * Revision: 9641
+; * Date: Thursday, February 7, 2008
+; *
+; * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+; *
+; *
+; *
+; * Description:
+; * Contains modules for zigzag scanning and VLC decoding
+; * for inter block.
+; *
+; *
+; *
+; * Function: omxVCM4P2_DecodeVLCZigzag_Inter
+; *
+; * Description:
+; * Performs VLC decoding and inverse zigzag scan for one intra coded block.
+; *
+; * Remarks:
+; *
+; * Parameters:
+; * [in] ppBitStream pointer to the pointer to the current byte in
+; * the bitstream buffer
+; * [in] pBitOffset pointer to the bit position in the byte pointed
+; * to by *ppBitStream. *pBitOffset is valid within [0-7].
+; * [in] shortVideoHeader binary flag indicating presence of short_video_header;
+; * escape modes 0-3 are used if shortVideoHeader==0,
+; * and escape mode 4 is used when shortVideoHeader==1.
+; * [out] ppBitStream *ppBitStream is updated after the block is
+; * decoded, so that it points to the current byte
+; * in the bit stream buffer
+; * [out] pBitOffset *pBitOffset is updated so that it points to the
+; * current bit position in the byte pointed by
+; * *ppBitStream
+; * [out] pDst pointer to the coefficient buffer of current
+; * block. Must be 16-byte aligned
+; *
+; * Return Value:
+; * OMX_Sts_BadArgErr - bad arguments
+; * -At least one of the following pointers is NULL: ppBitStream, *ppBitStream, pBitOffset, pDst, or
+; * -pDst is not 16-byte aligned, or
+; * -*pBitOffset exceeds [0,7].
+; * OMX_Sts_Err - status error
+; * -At least one mark bit is equal to zero
+; * -Encountered an illegal stream code that cannot be found in the VLC table
+; * -Encountered and illegal code in the VLC FLC table
+; * -The number of coefficients is greater than 64
+; *
+; */
+
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+ INCLUDE armCOMM_BitDec_s.h
+
+
+ M_VARIANTS ARM1136JS
+
+
+
+
+
+ IF ARM1136JS
+
+ ;// Import various tables needed for the function
+
+
+ IMPORT armVCM4P2_IntraVlcL0L1 ;// Contains optimized and packed VLC Tables for both Last =1 and last=0
+ ;// Packed in Run:Level:Last format
+ IMPORT armVCM4P2_IntraL0L1LMAX ;// Contains LMAX table entries with both Last=0 and Last=1
+ IMPORT armVCM4P2_IntraL0L1RMAX ;// Contains RMAX table entries with both Last=0 and Last=1
+ IMPORT armVCM4P2_aClassicalZigzagScan ;// contains classical Zigzag table entries with double the original values
+ IMPORT armVCM4P2_DecodeVLCZigzag_AC_unsafe
+
+;//Input Arguments
+
+ppBitStream RN 0
+pBitOffset RN 1
+pDst RN 2
+PredDir RN 3
+shortVideoHeader RN 3
+
+;//Local Variables
+
+Return RN 0
+
+pVlcTableL0L1 RN 4
+pLMAXTableL0L1 RN 4
+pRMAXTableL0L1 RN 4
+pZigzagTable RN 4
+Count RN 6
+
+
+
+ ;// Allocate stack memory to store optimized VLC,Zigzag, RMAX, LMAX Table Addresses
+
+ M_ALLOC4 ppVlcTableL0L1,4
+ M_ALLOC4 ppLMAXTableL0L1,4
+ M_ALLOC4 ppRMAXTableL0L1,4
+ M_ALLOC4 ppZigzagTable,4
+
+
+ M_START omxVCM4P2_DecodeVLCZigzag_IntraACVLC,r12
+
+ M_ARG shortVideoHeaderonStack,4 ;// pointer to Input Argument on stack
+
+ LDR pZigzagTable, =armVCM4P2_aClassicalZigzagScan ;// Load Address of the Zigzag table
+ ADD pZigzagTable, pZigzagTable, PredDir, LSL #6 ;// Loading Different type of zigzag tables based on PredDir
+
+ M_STR pZigzagTable,ppZigzagTable ;// Store Zigzag table address on stack
+ LDR pVlcTableL0L1, =armVCM4P2_IntraVlcL0L1 ;// Load optimized packed VLC Table with both L=0 and L=1 entries
+ M_STR pVlcTableL0L1,ppVlcTableL0L1 ;// Store VLC Table address on stack
+ LDR pLMAXTableL0L1, =armVCM4P2_IntraL0L1LMAX ;// Load LMAX Table
+ M_STR pLMAXTableL0L1,ppLMAXTableL0L1 ;// Store LMAX Table address on Stack
+ LDR pRMAXTableL0L1, =armVCM4P2_IntraL0L1RMAX ;// Load RMAX Table
+ MOV Count,#0 ;// Set Start=0
+
+ M_STR pRMAXTableL0L1,ppRMAXTableL0L1 ;// Store RMAX Table address on stack
+
+
+
+ M_LDR shortVideoHeader,shortVideoHeaderonStack ;// get the Input Argument from stack
+
+ BL armVCM4P2_DecodeVLCZigzag_AC_unsafe ;// Call Unsafe Function
+
+
+
+
+ M_END
+ ENDIF
+
+ END
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraDCVLC_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraDCVLC_s.s
new file mode 100644
index 0000000..d19cb13
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraDCVLC_s.s
@@ -0,0 +1,224 @@
+;/**
+; *
+; * File Name: omxVCM4P2_DecodeVLCZigzag_IntraDCVLC_s.s
+; * OpenMAX DL: v1.0.2
+; * Revision: 9641
+; * Date: Thursday, February 7, 2008
+; *
+; * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+; *
+; *
+; *
+; * Description:
+; * Contains modules for zigzag scanning and VLC decoding
+; * for inter block.
+; *
+; *
+; *
+; * Function: omxVCM4P2_DecodeVLCZigzag_Inter
+; *
+; * Description:
+; * Performs VLC decoding and inverse zigzag scan for one intra coded block.
+; *
+; * Remarks:
+; *
+; * Parameters:
+; * [in] ppBitStream pointer to the pointer to the current byte in
+; * the bitstream buffer
+; * [in] pBitOffset pointer to the bit position in the byte pointed
+; * to by *ppBitStream. *pBitOffset is valid within [0-7].
+; * [in] shortVideoHeader binary flag indicating presence of short_video_header;
+; * escape modes 0-3 are used if shortVideoHeader==0,
+; * and escape mode 4 is used when shortVideoHeader==1.
+; * [out] ppBitStream *ppBitStream is updated after the block is
+; * decoded, so that it points to the current byte
+; * in the bit stream buffer
+; * [out] pBitOffset *pBitOffset is updated so that it points to the
+; * current bit position in the byte pointed by
+; * *ppBitStream
+; * [out] pDst pointer to the coefficient buffer of current
+; * block. Must be 16-byte aligned
+; *
+; * Return Value:
+; * OMX_Sts_BadArgErr - bad arguments
+; * -At least one of the following pointers is NULL: ppBitStream, *ppBitStream, pBitOffset, pDst, or
+; * -pDst is not 16-byte aligned, or
+; * -*pBitOffset exceeds [0,7].
+; * OMX_Sts_Err - status error
+; * -At least one mark bit is equal to zero
+; * -Encountered an illegal stream code that cannot be found in the VLC table
+; * -Encountered and illegal code in the VLC FLC table
+; * -The number of coefficients is greater than 64
+; *
+; */
+
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+ INCLUDE armCOMM_BitDec_s.h
+
+
+ M_VARIANTS ARM1136JS
+
+
+
+
+
+ IF ARM1136JS :LOR: CortexA8
+
+
+ ;// Import various tables needed for the function
+
+
+ IMPORT armVCM4P2_IntraVlcL0L1 ;// Contains optimized and packed VLC Tables for both Last =1 and last=0
+ ;// Packed in Run:Level:Last format
+ IMPORT armVCM4P2_IntraL0L1LMAX ;// Contains LMAX table entries with both Last=0 and Last=1
+ IMPORT armVCM4P2_IntraL0L1RMAX ;// Contains RMAX table entries with both Last=0 and Last=1
+ IMPORT armVCM4P2_aClassicalZigzagScan ;// contains CLassical, Horizontal, Vertical Zigzag table entries with double the original values
+ IMPORT armVCM4P2_aIntraDCLumaChromaIndex ;// Contains Optimized DCLuma and DCChroma Index table Entries
+
+
+ IMPORT armVCM4P2_DecodeVLCZigzag_AC_unsafe
+
+;//Input Arguments
+
+ppBitStream RN 0
+pBitOffset RN 1
+pDst RN 2
+PredDir RN 3
+shortVideoHeader RN 3
+videoComp RN 5
+;//Local Variables
+
+Return RN 0
+
+pDCLumaChromaIndex RN 4
+pDCChromaIndex RN 7
+pVlcTableL0L1 RN 4
+pLMAXTableL0L1 RN 4
+pRMAXTableL0L1 RN 4
+pZigzagTable RN 4
+Count RN 6
+DCValueSize RN 6
+powOfSize RN 7
+temp1 RN 5
+
+
+;// Scratch Registers
+
+RBitStream RN 8
+RBitBuffer RN 9
+RBitCount RN 10
+
+T1 RN 11
+T2 RN 12
+DCVal RN 14
+
+
+ ;// Allocate stack memory to store optimized VLC,Zigzag, RMAX, LMAX Table Addresses
+
+ M_ALLOC4 ppVlcTableL0L1,4
+ M_ALLOC4 ppLMAXTableL0L1,4
+ M_ALLOC4 ppRMAXTableL0L1,4
+ M_ALLOC4 ppZigzagTable,4
+ M_ALLOC4 pDCCoeff,4
+
+
+
+ M_START omxVCM4P2_DecodeVLCZigzag_IntraDCVLC,r12
+
+ M_ARG shortVideoHeaderonStack,4 ;// Pointer to argument on stack
+ M_ARG videoComponstack,4 ;// Pointer to argument on stack
+
+
+ ;// Decode DC Coefficient
+
+
+ LDR pDCLumaChromaIndex, =armVCM4P2_aIntraDCLumaChromaIndex ;// Load Optimized VLC Table for Luminance and Chrominance
+
+ ;// Initializing the Bitstream Macro
+
+ M_BD_INIT0 ppBitStream, pBitOffset, RBitStream, RBitBuffer, RBitCount
+ M_LDR videoComp,videoComponstack
+ M_BD_INIT1 T1, T2, T2
+ ADD pDCLumaChromaIndex,pDCLumaChromaIndex,videoComp, LSL #6
+ M_BD_INIT2 T1, T2, T2
+
+
+ M_BD_VLD DCValueSize,T1,T2,pDCLumaChromaIndex,4,2 ;// VLC Decode using optimized Luminance and Chrominance VLC Table
+
+
+
+
+DecodeDC
+
+ CMP DCValueSize,#12
+ BGT ExitError
+
+ CMP DCValueSize,#0
+ MOVEQ DCVal,#0 ;// If DCValueSize is zero then DC coeff =0
+ BEQ ACDecode ;// Branch to perform AC Coeff Decoding
+
+ M_BD_VREAD16 DCVal,DCValueSize,T1,T2 ;// Get DC Value From Bit stream
+
+
+ MOV powOfSize,#1
+ LSL powOfSize,DCValueSize ;// powOfSize=pow(2,DCValueSize)
+ CMP DCVal,powOfSize,LSR #1 ;// Compare DCVal with powOfSize/2
+ ADDLT DCVal,DCVal,#1
+ SUBLT DCVal,DCVal,powOfSize ;// If Lessthan powOfSize/2 DCVal=DCVal-powOfSize+1
+ ;// Else DCVal= fetchbits from bit stream
+
+CheckDCValueSize
+
+ CMP DCValueSize,#8 ;// If DCValueSize greater than 8 check marker bit
+
+ BLE ACDecode
+
+ M_BD_READ8 temp1,1,T1
+ TEQ temp1,#0 ;// If Marker bit is zero Exit with an Error Message
+ BEQ ExitError
+
+
+
+ ;// Decode AC Coefficient
+
+ACDecode
+
+ M_STR DCVal,pDCCoeff ;// Store Decoded DC Coeff on Stack
+ M_BD_FINI ppBitStream,pBitOffset ;// Terminating the Bit stream Macro
+
+ LDR pZigzagTable, =armVCM4P2_aClassicalZigzagScan ;// Load Zigzag talbe address
+ ADD pZigzagTable, pZigzagTable, PredDir, LSL #6 ;// Modify the Zigzag table adress based on PredDir
+
+ M_STR pZigzagTable,ppZigzagTable ;// Store zigzag table on stack
+ LDR pVlcTableL0L1, =armVCM4P2_IntraVlcL0L1 ;// Load Optimized VLC Table With both Last=0 and Last=1 Entries
+ M_STR pVlcTableL0L1,ppVlcTableL0L1 ;// Store Optimized VLC Table on stack
+ LDR pLMAXTableL0L1, =armVCM4P2_IntraL0L1LMAX ;// Load LMAX Table
+ M_STR pLMAXTableL0L1,ppLMAXTableL0L1 ;// Store LMAX table on stack
+ LDR pRMAXTableL0L1, =armVCM4P2_IntraL0L1RMAX ;// Load RMAX Table
+ MOV Count,#1 ;// Set Start =1
+
+ M_STR pRMAXTableL0L1,ppRMAXTableL0L1 ;// Store RMAX Table on Stack
+
+
+ M_LDR shortVideoHeader,shortVideoHeaderonStack ;// Load the Input Argument From Stack
+
+ BL armVCM4P2_DecodeVLCZigzag_AC_unsafe ;// Call the Unsafe Function
+
+ M_LDR DCVal,pDCCoeff ;// Get the Decoded DC Value From Stack
+ STRH DCVal,[pDst] ;// Store the DC Value
+ B ExitOK
+
+
+
+ExitError
+
+ M_BD_FINI ppBitStream,pBitOffset ;// Terminating the Bit Stream Macro in case of an Error
+ MOV Return,#OMX_Sts_Err ;// Exit with an Error Message
+ExitOK
+
+ M_END
+ ENDIF
+
+ END
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_FindMVpred_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_FindMVpred_s.s
new file mode 100644
index 0000000..a4bfa71
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_FindMVpred_s.s
@@ -0,0 +1,194 @@
+;//
+;//
+;// File Name: omxVCM4P2_FindMVpred_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 9641
+;// Date: Thursday, February 7, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+;// Function:
+;// omxVCM4P2_FindMVpred
+;//
+ ;// Include headers
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+ INCLUDE armVCCOMM_s.h
+
+ ;// Define cpu variants
+ M_VARIANTS ARM1136JS
+
+
+ IF ARM1136JS
+
+ M_TABLE armVCM4P2_pBlkIndexTable
+ DCD OMXVCBlk0, OMXVCBlk1
+ DCD OMXVCBlk2, OMXVCBlk3
+
+;//--------------------------------------------
+;// Declare input registers
+;//--------------------------------------------
+
+pSrcMVCurMB RN 0
+pSrcCandMV1 RN 1
+pSrcCandMV2 RN 2
+pSrcCandMV3 RN 3
+pDstMVPred RN 4
+pDstMVPredME RN 5
+iBlk RN 6
+
+pTable RN 4
+CandMV RN 12
+
+pCandMV1 RN 7
+pCandMV2 RN 8
+pCandMV3 RN 9
+
+CandMV1dx RN 0
+CandMV1dy RN 1
+CandMV2dx RN 2
+CandMV2dy RN 3
+CandMV3dx RN 10
+CandMV3dy RN 11
+
+temp RN 14
+
+zero RN 14
+return RN 0
+
+; ----------------------------------------------
+; Main routine
+; ----------------------------------------------
+
+ M_ALLOC4 MV, 4
+
+ ;// Function header
+ M_START omxVCM4P2_FindMVpred, r11
+
+ ;// Define stack arguments
+ M_ARG ppDstMVPred, 4
+ M_ARG ppDstMVPredME, 4
+ M_ARG Blk, 4
+
+ M_ADR CandMV, MV
+ MOV zero, #0
+ M_LDR iBlk, Blk
+
+ ;// Set the default value for these
+ ;// to be used if pSrcCandMV[1|2|3] == NULL
+ MOV pCandMV1, CandMV
+ MOV pCandMV2, CandMV
+ MOV pCandMV3, CandMV
+
+ STR zero, [CandMV]
+
+ ;// Branch to the case based on blk number
+ M_SWITCH iBlk
+ M_CASE OMXVCBlk0 ;// iBlk=0
+ M_CASE OMXVCBlk1 ;// iBlk=0
+ M_CASE OMXVCBlk2 ;// iBlk=0
+ M_CASE OMXVCBlk3 ;// iBlk=0
+ M_ENDSWITCH
+
+OMXVCBlk0
+ CMP pSrcCandMV1, #0
+ ADDNE pCandMV1, pSrcCandMV1, #4
+
+ CMP pSrcCandMV2, #0
+ ADDNE pCandMV2, pSrcCandMV2, #8
+
+ CMP pSrcCandMV3, #0
+ ADDNE pCandMV3, pSrcCandMV3, #8
+ CMPEQ pSrcCandMV1, #0
+
+ MOVEQ pCandMV3, pCandMV2
+ MOVEQ pCandMV1, pCandMV2
+
+ CMP pSrcCandMV1, #0
+ CMPEQ pSrcCandMV2, #0
+
+ MOVEQ pCandMV1, pCandMV3
+ MOVEQ pCandMV2, pCandMV3
+
+ CMP pSrcCandMV2, #0
+ CMPEQ pSrcCandMV3, #0
+
+ MOVEQ pCandMV2, pCandMV1
+ MOVEQ pCandMV3, pCandMV1
+
+ B BlkEnd
+
+OMXVCBlk1
+ MOV pCandMV1, pSrcMVCurMB
+ CMP pSrcCandMV3, #0
+ ADDNE pCandMV3, pSrcCandMV3, #8
+
+ CMP pSrcCandMV2, #0
+ ADDNE pCandMV2, pSrcCandMV2, #12
+
+ CMPEQ pSrcCandMV3, #0
+
+ MOVEQ pCandMV2, pCandMV1
+ MOVEQ pCandMV3, pCandMV1
+
+ B BlkEnd
+
+OMXVCBlk2
+ CMP pSrcCandMV1, #0
+ MOV pCandMV2, pSrcMVCurMB
+ ADD pCandMV3, pSrcMVCurMB, #4
+ ADDNE pCandMV1, pSrcCandMV1, #12
+ B BlkEnd
+
+OMXVCBlk3
+ ADD pCandMV1, pSrcMVCurMB, #8
+ MOV pCandMV2, pSrcMVCurMB
+ ADD pCandMV3, pSrcMVCurMB, #4
+
+BlkEnd
+
+ ;// Using the transperancy info, zero
+ ;// out the candidate MV if neccesary
+ LDRSH CandMV1dx, [pCandMV1], #2
+ LDRSH CandMV2dx, [pCandMV2], #2
+ LDRSH CandMV3dx, [pCandMV3], #2
+
+ ;// Load argument from the stack
+ M_LDR pDstMVPredME, ppDstMVPredME
+
+ LDRSH CandMV1dy, [pCandMV1]
+ LDRSH CandMV2dy, [pCandMV2]
+ LDRSH CandMV3dy, [pCandMV3]
+
+ CMP pDstMVPredME, #0
+
+ ;// Store the candidate MV's into the pDstMVPredME,
+ ;// these can be used in the fast algorithm if implemented
+
+ STRHNE CandMV1dx, [pDstMVPredME], #2
+ STRHNE CandMV1dy, [pDstMVPredME], #2
+ STRHNE CandMV2dx, [pDstMVPredME], #2
+ STRHNE CandMV2dy, [pDstMVPredME], #2
+ STRHNE CandMV3dx, [pDstMVPredME], #2
+ STRHNE CandMV3dy, [pDstMVPredME]
+
+ ; Find the median of the 3 candidate MV's
+ M_MEDIAN3 CandMV1dx, CandMV2dx, CandMV3dx, temp
+
+ ;// Load argument from the stack
+ M_LDR pDstMVPred, ppDstMVPred
+
+ M_MEDIAN3 CandMV1dy, CandMV2dy, CandMV3dy, temp
+
+ STRH CandMV3dx, [pDstMVPred], #2
+ STRH CandMV3dy, [pDstMVPred]
+
+ MOV return, #OMX_Sts_NoErr
+
+ M_END
+ ENDIF ;// ARM1136JS :LOR: CortexA8
+
+ END
\ No newline at end of file
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_IDCT8x8blk_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_IDCT8x8blk_s.s
new file mode 100644
index 0000000..bfeb540
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_IDCT8x8blk_s.s
@@ -0,0 +1,73 @@
+;//
+;//
+;// File Name: omxVCM4P2_IDCT8x8blk_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 9641
+;// Date: Thursday, February 7, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+;// Function:
+;// omxVCM4P2_IDCT8x8blk
+;//
+ ;// Include headers
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ ;// Define cpu variants
+ M_VARIANTS ARM1136JS
+
+ INCLUDE armCOMM_IDCT_s.h
+
+ IMPORT armCOMM_IDCTPreScale
+ ;//
+ ;// Function prototype
+ ;//
+ ;// OMXResult
+ ;// omxVCM4P2_IDCT8x8blk(const OMX_S16* pSrc,
+ ;// OMX_S16* pDst)
+ ;//
+
+ IF ARM1136JS :LOR: CortexA8
+ M_ALLOC4 ppDest, 4
+ M_ALLOC4 pStride, 4
+ M_ALLOC8 pBlk, 2*8*8
+ ENDIF
+
+ IF ARM1136JS
+ M_START omxVCM4P2_IDCT8x8blk, r11
+ ENDIF
+
+
+ IF ARM1136JS :LOR: CortexA8
+
+;// Declare input registers
+pSrc RN 0
+pDst RN 1
+
+;// Declare other intermediate registers
+Result RN 0
+
+;// Prototype for macro M_IDCT
+;// pSrc RN 0 ;// source data buffer
+;// Stride RN 1 ;// destination stride in bytes
+;// pDest RN 2 ;// destination data buffer
+;// pScale RN 3 ;// pointer to scaling table
+
+pSrc RN 0
+Stride RN 1
+pDest RN 2
+pScale RN 3
+
+ MOV pDest, pDst
+ LDR pScale, =armCOMM_IDCTPreScale
+ M_IDCT s9, s16, 16
+ MOV Result, #OMX_Sts_NoErr
+ M_END
+ ENDIF
+ ;// ARM1136JS :LOR: CortexA8
+
+ END
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_MCReconBlock_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_MCReconBlock_s.s
new file mode 100644
index 0000000..20965bf
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_MCReconBlock_s.s
@@ -0,0 +1,713 @@
+;//
+;//
+;// File Name: omxVCM4P2_MCReconBlock_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 9641
+;// Date: Thursday, February 7, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+;// Description:
+;//
+;//
+
+;// Include standard headers
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+;// Import symbols required from other files
+
+ M_VARIANTS ARM1136JS
+
+;// ***************************************************************************
+;// ARM1136JS implementation
+;// ***************************************************************************
+ IF ARM1136JS
+
+;// ***************************************************************************
+;// MACRO DEFINITIONS
+;// ***************************************************************************
+ ;// Description:
+ ;//
+ ;// dest[j] = (x[j] + y[j] + round) >> 1, j=0..3
+ ;//
+ ;// Similar to UHADD8 instruction, but with a rounding value of 1 added to
+ ;// each sum before dividing by two, if round is 1
+ ;//
+ ;// Syntax:
+ ;// M_UHADD8R $dest, $x, $y, $round, $mask
+ ;//
+ ;// Inputs:
+ ;// $x four packed bytes, x[3] : x[2] : x[1] : x[0]
+ ;// $y four packed bytes, y[3] : y[2] : y[1] : y[0]
+ ;// $round 0 if no rounding to be added, 1 if rounding to be done
+ ;// $mask some register set to 0x80808080
+ ;//
+ ;// Outputs:
+ ;// $dest four packed bytes, z[3] : z[2] : z[1] : z[0]
+
+ MACRO
+ M_UHADD8R $dest, $x, $y, $round, $mask
+ IF $round = 1
+ IF $dest /= $y
+ MVN $dest, $x
+ UHSUB8 $dest, $y, $dest
+ EOR $dest, $dest, $mask
+ ELSE
+ MVN $dest, $y
+ UHSUB8 $dest, $x, $dest
+ EOR $dest, $dest, $mask
+ ENDIF
+ ELSE
+ UHADD8 $dest, $x, $y
+ ENDIF
+ MEND
+;// ***************************************************************************
+ ;// Description:
+ ;// Load 8 bytes from $pSrc (aligned or unaligned locations)
+ ;//
+ ;// Syntax:
+ ;// M_LOAD_X $pSrc, $srcStep, $out0, $out1, $scratch, $offset
+ ;//
+ ;// Inputs:
+ ;// $pSrc 4 byte aligned source pointer to an address just less than
+ ;// or equal to the data location
+ ;// $srcStep The stride on source
+ ;// $scratch A scratch register, used internally for temp calculations
+ ;// $offset Difference of source data location to the source pointer
+ ;// Use when $offset != 0 (unaligned load)
+ ;//
+ ;// Outputs:
+ ;// $pSrc In case the macro accepts stride, it increments the pSrc by
+ ;// that value, else unchanged
+ ;// $out0 four packed bytes, z[3] : z[2] : z[1] : z[0]
+ ;// $out1 four packed bytes, z[7] : z[6] : z[5] : z[4]
+ ;//
+ ;// Note: {$out0, $out1, $scratch} should be registers with ascending
+ ;// register numbering. In case offset is 0, $scratch is not modified.
+
+ MACRO
+ M_LOAD_X $pSrc, $srcStep, $out0, $out1, $scratch, $offset
+ IF $offset = 0
+ LDM $pSrc, {$out0, $out1}
+ ADD $pSrc, $pSrc, $srcStep
+ ELSE
+ LDM $pSrc, {$out0, $out1, $scratch}
+ ADD $pSrc, $pSrc, $srcStep
+
+ MOV $out0, $out0, LSR #8 * $offset
+ ORR $out0, $out0, $out1, LSL #(32 - 8 * ($offset))
+ MOV $out1, $out1, LSR #8 * $offset
+ ORR $out1, $out1, $scratch, LSL #(32 - 8 * ($offset))
+ ENDIF
+ MEND
+
+;// ***************************************************************************
+ ;// Description:
+ ;// Loads three words for X interpolation, update pointer to next row. For
+ ;// X interpolation, given a truncated-4byteAligned source pointer,
+ ;// invariably three continous words are required from there to get the
+ ;// nine bytes from the source pointer for filtering.
+ ;//
+ ;// Syntax:
+ ;// M_LOAD_XINT $pSrc, $srcStep, $offset, $word0, $word1, $word2, $word3
+ ;//
+ ;// Inputs:
+ ;// $pSrc 4 byte aligned source pointer to an address just less than
+ ;// or equal to the data location
+ ;//
+ ;// $srcStep The stride on source
+ ;//
+ ;// $offset Difference of source data location to the source pointer
+ ;// Use when $offset != 0 (unaligned load)
+ ;//
+ ;// Outputs:
+ ;// $pSrc Incremented by $srcStep
+ ;//
+ ;// $word0, $word1, $word2, $word3
+ ;// Three of these are outputs based on the $offset parameter.
+ ;// The outputs are specifically generated to be processed by
+ ;// the M_EXT_XINT macro. Following is the illustration to show
+ ;// how the nine bytes are spanned for different offsets from
+ ;// notTruncatedForAlignmentSourcePointer.
+ ;//
+ ;// ------------------------------------------------------
+ ;// | Offset | Aligned Ptr | word0 | word1 | word2 | word3 |
+ ;// |------------------------------------------------------|
+ ;// | 0 | 0 | 0123 | 4567 | 8xxx | |
+ ;// | 1 | -1 | x012 | 3456 | 78xx | |
+ ;// | 2 | -2 | xx01 | 2345 | 678x | |
+ ;// | 3 | -3 | xxx0 | | 1234 | 5678 |
+ ;// ------------------------------------------------------
+ ;//
+ ;// where the numbering (0-8) is to designate the 9 bytes from
+ ;// start of a particular row. The illustration doesn't take in
+ ;// account the positioning of bytes with in the word and the
+ ;// macro combination with M_EXT_XINT will work only in little
+ ;// endian environs
+ ;//
+ ;// Note: {$word0, $word1, $word2, $word3} should be registers with ascending
+ ;// register numbering
+
+ MACRO
+ M_LOAD_XINT $pSrc, $srcStep, $offset, $word0, $word1, $word2, $word3
+ IF $offset /= 3
+ LDM $pSrc, {$word0, $word1, $word2}
+ ELSE
+ LDM $pSrc, {$word0, $word2, $word3}
+ ENDIF
+ ADD $pSrc, $pSrc, $srcStep
+ MEND
+
+;// ***************************************************************************
+ ;// Description:
+ ;// Extract four registers of four pixels for X interpolation
+ ;//
+ ;// Syntax:
+ ;// M_EXT_XINT $offset, $word0, $word1, $word2, $word3
+ ;//
+ ;// Inputs:
+ ;// $offset Difference of source data location to the source pointer
+ ;// Use when $offset != 0 (unaligned load)
+ ;//
+ ;// $word0, $word1, $word2, $word3
+ ;// Three of these are inputs based on the $offset parameter.
+ ;// The inputs are specifically selected to be processed by
+ ;// the M_EXT_XINT macro.
+ ;//
+ ;// ------------------------------------------------------
+ ;// | Offset | Aligned Ptr | word0 | word1 | word2 | word3 |
+ ;// |------------------------------------------------------|
+ ;// | 0 | 0 | 0123 | 4567 | 8xxx | yyyy |
+ ;// | 1 | -1 | x012 | 3456 | 78xx | yyyy |
+ ;// | 2 | -2 | xx01 | 2345 | 678x | yyyy |
+ ;// | 3 | -3 | xxx0 | yyyy | 1234 | 5678 |
+ ;// ------------------------------------------------------
+ ;//
+ ;// Outputs:
+ ;// $word0, $word1, $word2, $word3
+ ;// Bytes from the original source pointer (not truncated for
+ ;// 4 byte alignment) as shown in the table.
+ ;// -------------------------------
+ ;// | word0 | word1 | word2 | word3 |
+ ;// |-------------------------------|
+ ;// | 0123 | 4567 | 1234 | 5678 |
+ ;// -------------------------------
+ ;//
+ ;// Note: {$word0, $word1, $word2, $word3} should be registers with ascending
+ ;// register numbering
+
+ MACRO
+ M_EXT_XINT $offset, $word0, $word1, $word2, $word3
+ IF $offset = 0
+ ; $word0 and $word1 are ok
+ ; $word2, $word3 are just 8 shifted versions
+ MOV $word3, $word1, LSR #8
+ ORR $word3, $word3, $word2, LSL #24
+ MOV $word2, $word0, LSR #8
+ ORR $word2, $word2, $word1, LSL #24
+ ELIF $offset = 3
+ ; $word2 and $word3 are ok (taken care while loading itself)
+ ; set $word0 & $word1
+ MOV $word0, $word0, LSR #24
+ ORR $word0, $word0, $word2, LSL #8
+ MOV $word1, $word2, LSR #24
+ ORR $word1, $word1, $word3, LSL #8
+ ELSE
+ MOV $word0, $word0, LSR #8 * $offset
+ ORR $word0, $word0, $word1, LSL #(32 - 8 * ($offset))
+ MOV $word1, $word1, LSR #8 * $offset
+ ORR $word1, $word1, $word2, LSL #(32 - 8 * ($offset))
+
+ MOV $word3, $word1, LSR #8
+ ORR $word3, $word3, $word2, LSL #(32 - 8 * (($offset)+1))
+ MOV $word2, $word0, LSR #8
+ ORR $word2, $word2, $word1, LSL #24
+ ENDIF
+ MEND
+
+;// ***************************************************************************
+ ;// Description:
+ ;// Computes half-sum and xor of two inputs and puts them in the input
+ ;// registers in that order
+ ;//
+ ;// Syntax:
+ ;// M_HSUM_XOR $v0, $v1, $tmp
+ ;//
+ ;// Inputs:
+ ;// $v0 a, first input
+ ;// $v1 b, second input
+ ;// $tmp scratch register
+ ;//
+ ;// Outputs:
+ ;// $v0 (a + b)/2
+ ;// $v1 a ^ b
+
+ MACRO
+ M_HSUM_XOR $v0, $v1, $tmp
+ UHADD8 $tmp, $v0, $v1 ;// s0 = a + b
+ EOR $v1, $v0, $v1 ;// l0 = a ^ b
+ MOV $v0, $tmp ;// s0
+ MEND
+;// ***************************************************************************
+ ;// Description:
+ ;// Calculates average of 4 values (a,b,c,d) for HalfPixelXY predict type in
+ ;// mcReconBlock module. Very specific to the implementation of
+ ;// M_MCRECONBLOCK_HalfPixelXY done here. Uses "tmp" as scratch register and
+ ;// "yMask" for mask variable "0x1010101x" set in it. In yMask 4 lsbs are
+ ;// not significant and are used by the callee for row counter (y)
+ ;//
+ ;// Some points to note are:
+ ;// 1. Input is pair of pair-averages and Xors
+ ;// 2. $sum1 and $lsb1 are not modified and hence can be reused in another
+ ;// running average
+ ;// 3. Output is in the first argument
+ ;//
+ ;// Syntax:
+ ;// M_AVG4 $sum0, $lsb0, $sum1, $lsb1, $rndVal
+ ;//
+ ;// Inputs:
+ ;// $sum0 (a + b) >> 1, where a and b are 1st and 2nd inputs to be averaged
+ ;// $lsb0 (a ^ b)
+ ;// $sum1 (c + d) >> 1. Not modified
+ ;// $lsb1 (c ^ d) Not modified
+ ;// $rndVal Assembler Variable. 0 for rounding, 1 for no rounding
+ ;//
+ ;// Outputs:
+ ;// $sum0 (a + b + c + d + 1) / 4 : If no rounding
+ ;// (a + b + c + d + 2) / 4 : If rounding
+
+ MACRO
+ M_AVG4 $sum0, $lsb0, $sum1, $lsb1, $rndVal
+ LCLS OP1
+ LCLS OP2
+ IF $rndVal = 0 ;// rounding case
+OP1 SETS "AND"
+OP2 SETS "ORR"
+ ELSE ;// Not rounding case
+OP1 SETS "ORR"
+OP2 SETS "AND"
+ ENDIF
+
+ LCLS lsb2
+ LCLS sum2
+ LCLS dest
+
+lsb2 SETS "tmp"
+sum2 SETS "$lsb0"
+dest SETS "$sum0"
+
+ $OP1 $lsb0, $lsb0, $lsb1 ;// e0 = e0 & e1
+ EOR $lsb2, $sum0, $sum1 ;// e2 = s0 ^ s1
+ $OP2 $lsb2, $lsb2, $lsb0 ;// e2 = e2 | e0
+ AND $lsb2, $lsb2, yMask, LSR # 4 ;// e2 = e2 & mask
+ UHADD8 $sum2, $sum0, $sum1 ;// s2 = (s0 + s1)/2
+ UADD8 $dest, $sum2, $lsb2 ;// dest = s2 + e2
+ MEND
+;// ***************************************************************************
+;// Motion compensation handler macros
+;// ***************************************************************************
+ ;// Description:
+ ;// Implement motion compensation routines using the named registers in
+ ;// callee function. Each of the following 4 implement the 4 predict type
+ ;// Each handles 8 cases each ie all the combinations of 4 types of source
+ ;// alignment offsets and 2 types of rounding flag
+ ;//
+ ;// Syntax:
+ ;// M_MCRECONBLOCK_IntegerPixel $rndVal, $offset
+ ;// M_MCRECONBLOCK_HalfPixelX $rndVal, $offset
+ ;// M_MCRECONBLOCK_HalfPixelY $rndVal, $offset
+ ;// M_MCRECONBLOCK_HalfPixelXY $rndVal, $offset
+ ;//
+ ;// Inputs:
+ ;// $rndVal Assembler Variable. 0 for rounding, 1 for no rounding
+ ;// $offset $pSrc MOD 4 value. Offset from 4 byte aligned location.
+ ;//
+ ;// Outputs:
+ ;// Outputs come in the named registers of the callee functions
+ ;// The macro loads the data from the source pointer, processes it and
+ ;// stores in the destination pointer. Does the whole prediction cycle
+ ;// of Motion Compensation routine for a particular predictType
+ ;// After this only residue addition to the predicted values remain
+
+ MACRO
+ M_MCRECONBLOCK_IntegerPixel $rndVal, $offset
+ ;// Algorithmic Description:
+ ;// This handles motion compensation for IntegerPixel predictType. Both
+ ;// rounding cases are handled by the same code base. It is just a copy
+ ;// from source to destination. Two lines are done per loop to reduce
+ ;// stalls. Loop has been software pipelined as well for that purpose.
+ ;//
+ ;// M_LOAD_X loads a whole row in two registers and then they are stored
+
+CaseIntegerPixelRnd0Offset$offset
+CaseIntegerPixelRnd1Offset$offset
+ M_LOAD_X pSrc, srcStep, tmp1, tmp2, tmp3, $offset
+ M_LOAD_X pSrc, srcStep, tmp3, tmp4, tmp5, $offset
+YloopIntegerPixelOffset$offset
+ SUBS y, y, #2
+ STRD tmp1, tmp2, [pDst], dstStep
+ STRD tmp3, tmp4, [pDst], dstStep
+ M_LOAD_X pSrc, srcStep, tmp1, tmp2, tmp3, $offset
+ M_LOAD_X pSrc, srcStep, tmp3, tmp4, tmp5, $offset
+ BGT YloopIntegerPixelOffset$offset
+
+ B SwitchPredictTypeEnd
+ MEND
+;// ***************************************************************************
+ MACRO
+ M_MCRECONBLOCK_HalfPixelX $rndVal, $offset
+ ;// Algorithmic Description:
+ ;// This handles motion compensation for HalfPixelX predictType. The two
+ ;// rounding cases are handled by the different code base and spanned by
+ ;// different macro calls. Loop has been software pipelined to reduce
+ ;// stalls.
+ ;//
+ ;// Filtering involves averaging a pixel with the next horizontal pixel.
+ ;// M_LOAD_XINT and M_EXT_XINT combination generate 4 registers, 2 with
+ ;// all pixels in a row with 4 pixel in each register and another 2
+ ;// registers with pixels corresponding to one horizontally shifted pixel
+ ;// corresponding to the initial row pixels. These are set of packed
+ ;// registers appropriate to do 4 lane SIMD.
+ ;// After that M_UHADD8R macro does the averaging taking care of the
+ ;// rounding as required
+
+CaseHalfPixelXRnd$rndVal.Offset$offset
+ IF $rndVal = 0
+ LDR mask, =0x80808080
+ ENDIF
+
+ M_LOAD_XINT pSrc, srcStep, $offset, tmp1, tmp2, tmp3, tmp4
+YloopHalfPixelXRnd$rndVal.Offset$offset
+ SUBS y, y, #1
+ M_EXT_XINT $offset, tmp1, tmp2, tmp3, tmp4
+ M_UHADD8R tmp5, tmp1, tmp3, (1-$rndVal), mask
+ M_UHADD8R tmp6, tmp2, tmp4, (1-$rndVal), mask
+ STRD tmp5, tmp6, [pDst], dstStep
+ M_LOAD_XINT pSrc, srcStep, $offset, tmp1, tmp2, tmp3, tmp4
+ BGT YloopHalfPixelXRnd$rndVal.Offset$offset
+
+ B SwitchPredictTypeEnd
+ MEND
+;// ***************************************************************************
+ MACRO
+ M_MCRECONBLOCK_HalfPixelY $rndVal, $offset
+ ;// Algorithmic Description:
+ ;// This handles motion compensation for HalfPixelY predictType. The two
+ ;// rounding cases are handled by the different code base and spanned by
+ ;// different macro calls. PreLoading is used to avoid reload of same data.
+ ;//
+ ;// Filtering involves averaging a pixel with the next vertical pixel.
+ ;// M_LOAD_X generates 2 registers with all pixels in a row with 4 pixel in
+ ;// each register. These are set of packed registers appropriate to do
+ ;// 4 lane SIMD. After that M_UHADD8R macro does the averaging taking care
+ ;// of the rounding as required
+
+CaseHalfPixelYRnd$rndVal.Offset$offset
+ IF $rndVal = 0
+ LDR mask, =0x80808080
+ ENDIF
+
+ M_LOAD_X pSrc, srcStep, tmp1, tmp2, tmp5, $offset ;// Pre-load
+YloopHalfPixelYRnd$rndVal.Offset$offset
+ SUBS y, y, #2
+ ;// Processing one line
+ M_LOAD_X pSrc, srcStep, tmp3, tmp4, tmp5, $offset
+ M_UHADD8R tmp1, tmp1, tmp3, (1-$rndVal), mask
+ M_UHADD8R tmp2, tmp2, tmp4, (1-$rndVal), mask
+ STRD tmp1, tmp2, [pDst], dstStep
+ ;// Processing another line
+ M_LOAD_X pSrc, srcStep, tmp1, tmp2, tmp5, $offset
+ M_UHADD8R tmp3, tmp3, tmp1, (1-$rndVal), mask
+ M_UHADD8R tmp4, tmp4, tmp2, (1-$rndVal), mask
+ STRD tmp3, tmp4, [pDst], dstStep
+
+ BGT YloopHalfPixelYRnd$rndVal.Offset$offset
+
+ B SwitchPredictTypeEnd
+ MEND
+;// ***************************************************************************
+ MACRO
+ M_MCRECONBLOCK_HalfPixelXY $rndVal, $offset
+ ;// Algorithmic Description:
+ ;// This handles motion compensation for HalfPixelXY predictType. The two
+ ;// rounding cases are handled by the different code base and spanned by
+ ;// different macro calls. PreLoading is used to avoid reload of same data.
+ ;//
+ ;// Filtering involves averaging a pixel with the next vertical, horizontal
+ ;// and right-down diagonal pixels. Just as in HalfPixelX case, M_LOAD_XINT
+ ;// and M_EXT_XINT combination generates 4 registers with a row and its
+ ;// 1 pixel right shifted version, with 4 pixels in one register. Another
+ ;// call of that macro-combination gets another row. Then M_HSUM_XOR is
+ ;// called to get mutual half-sum and xor combinations of a row with its
+ ;// shifted version as they are inputs to the M_AVG4 macro which computes
+ ;// the 4 element average with rounding. Note that it is the half-sum/xor
+ ;// values that are preserved for next row as they can be re-used in the
+ ;// next call to the M_AVG4 and saves recomputation.
+ ;// Due to lack of register, the row counter and a masking value required
+ ;// in M_AVG4 are packed into a single register yMask where the last nibble
+ ;// holds the row counter values and rest holds the masking variable left
+ ;// shifted by 4
+
+CaseHalfPixelXYRnd$rndVal.Offset$offset
+ LDR yMask, =((0x01010101 << 4) + 8)
+
+ M_LOAD_XINT pSrc, srcStep, $offset, t00, t01, t10, t11 ;// Load a, a', b, b'
+ M_EXT_XINT $offset, t00, t01, t10, t11
+ M_HSUM_XOR t00, t10, tmp ;// s0, l0
+ M_HSUM_XOR t01, t11, tmp ;// s0', l0'
+
+YloopHalfPixelXYRnd$rndVal.Offset$offset
+ ;// Processsing one line
+ ;// t00, t01, t10, t11 required from previous loop
+ M_LOAD_XINT pSrc, srcStep, $offset, t20, t21, t30, t31 ;// Load c, c', d, d'
+ SUB yMask, yMask, #2
+ M_EXT_XINT $offset, t20, t21, t30, t31
+ M_HSUM_XOR t20, t30, tmp ;// s1, l1
+ M_HSUM_XOR t21, t31, tmp ;// s1', l1'
+ M_AVG4 t00, t10, t20, t30, $rndVal ;// s0, l0, s1, l1
+ M_AVG4 t01, t11, t21, t31, $rndVal ;// s0', l0', s1', l1'
+ STRD t00, t01, [pDst], dstStep ;// store the average
+
+ ;// Processsing another line
+ ;// t20, t21, t30, t31 required from above
+ M_LOAD_XINT pSrc, srcStep, $offset, t00, t01, t10, t11 ;// Load a, a', b, b'
+ TST yMask, #7
+ M_EXT_XINT $offset, t00, t01, t10, t11
+ M_HSUM_XOR t00, t10, tmp
+ M_HSUM_XOR t01, t11, tmp
+ M_AVG4 t20, t30, t00, t10, $rndVal
+ M_AVG4 t21, t31, t01, t11, $rndVal
+ STRD t20, t21, [pDst], dstStep
+
+ BGT YloopHalfPixelXYRnd$rndVal.Offset$offset
+
+ IF $offset/=3 :LOR: $rndVal/=1
+ B SwitchPredictTypeEnd
+ ENDIF
+ MEND
+;// ***************************************************************************
+;// Motion compensation handler macros end here
+;// ***************************************************************************
+ ;// Description:
+ ;// Populates all 4 kinds of offsets "cases" for each predictType and rndVal
+ ;// combination in the "switch" to prediction processing code segment
+ ;//
+ ;// Syntax:
+ ;// M_CASE_OFFSET $rnd, $predictType
+ ;//
+ ;// Inputs:
+ ;// $rnd 0 for rounding, 1 for no rounding
+ ;// $predictType The prediction mode
+ ;//
+ ;// Outputs:
+ ;// Populated list of "M_CASE"s for the "M_SWITCH" macro
+
+ MACRO
+ M_CASE_OFFSET $rnd, $predictType
+ M_CASE Case$predictType.Rnd$rnd.Offset0
+ M_CASE Case$predictType.Rnd$rnd.Offset1
+ M_CASE Case$predictType.Rnd$rnd.Offset2
+ M_CASE Case$predictType.Rnd$rnd.Offset3
+ MEND
+;// ***************************************************************************
+ ;// Description:
+ ;// Populates all 2 kinds of rounding "cases" for each predictType in the
+ ;// "switch" to prediction processing code segment
+ ;//
+ ;// Syntax:
+ ;// M_CASE_OFFSET $predictType
+ ;//
+ ;// Inputs:
+ ;// $predictType The prediction mode
+ ;//
+ ;// Outputs:
+ ;// Populated list of "M_CASE_OFFSET" macros
+
+ MACRO
+ M_CASE_MCRECONBLOCK $predictType
+ M_CASE_OFFSET 0, $predictType ;// 0 for rounding
+ M_CASE_OFFSET 1, $predictType ;// 1 for no rounding
+ MEND
+;// ***************************************************************************
+ ;// Description:
+ ;// Populates all 8 kinds of rounding and offset combinations handling macros
+ ;// for the specified predictType. In case of "IntegerPixel" predictType,
+ ;// rounding is not required so same code segment handles both cases
+ ;//
+ ;// Syntax:
+ ;// M_MCRECONBLOCK $predictType
+ ;//
+ ;// Inputs:
+ ;// $predictType The prediction mode
+ ;//
+ ;// Outputs:
+ ;// Populated list of "M_MCRECONBLOCK_<predictType>" macros for specified
+ ;// predictType. Each
+ ;// M_MCRECONBLOCK_<predictType> $rnd, $offset
+ ;// is an code segment (starting with a label indicating the predictType,
+ ;// rounding and offset combination)
+ ;// Four calls of this macro with the 4 prediction modes populate all the 32
+ ;// handlers
+
+ MACRO
+ M_MCRECONBLOCK $predictType
+ M_MCRECONBLOCK_$predictType 0, 0
+ M_MCRECONBLOCK_$predictType 0, 1
+ M_MCRECONBLOCK_$predictType 0, 2
+ M_MCRECONBLOCK_$predictType 0, 3
+ IF "$predictType" /= "IntegerPixel" ;// If not IntegerPixel then rounding makes a difference
+ M_MCRECONBLOCK_$predictType 1, 0
+ M_MCRECONBLOCK_$predictType 1, 1
+ M_MCRECONBLOCK_$predictType 1, 2
+ M_MCRECONBLOCK_$predictType 1, 3
+ ENDIF
+ MEND
+;// ***************************************************************************
+;// Input/Output Registers
+pSrc RN 0
+srcStep RN 1
+arg_pSrcResidue RN 2
+pSrcResidue RN 12
+pDst RN 3
+dstStep RN 2
+predictType RN 10
+rndVal RN 11
+mask RN 11
+
+;// Local Scratch Registers
+zero RN 12
+y RN 14
+
+tmp1 RN 4
+tmp2 RN 5
+tmp3 RN 6
+tmp4 RN 7
+tmp5 RN 8
+tmp6 RN 9
+tmp7 RN 10
+tmp8 RN 11
+tmp9 RN 12
+
+t00 RN 4
+t01 RN 5
+t10 RN 6
+t11 RN 7
+t20 RN 8
+t21 RN 9
+t30 RN 10
+t31 RN 11
+tmp RN 12
+
+yMask RN 14
+
+dst RN 1
+return RN 0
+
+ ;// Allocate memory on stack
+ M_ALLOC4 Stk_pDst, 4
+ M_ALLOC4 Stk_pSrcResidue, 4
+ ;// Function header
+ M_START omxVCM4P2_MCReconBlock, r11
+ ;// Define stack arguments
+ M_ARG Arg_dstStep, 4
+ M_ARG Arg_predictType, 4
+ M_ARG Arg_rndVal, 4
+ ;// Save on stack
+ M_STR pDst, Stk_pDst
+ M_STR arg_pSrcResidue, Stk_pSrcResidue
+ ;// Load argument from the stack
+ M_LDR dstStep, Arg_dstStep
+ M_LDR predictType, Arg_predictType
+ M_LDR rndVal, Arg_rndVal
+
+ MOV y, #8
+
+ AND tmp1, pSrc, #3
+ ORR predictType, tmp1, predictType, LSL #3
+ ORR predictType, predictType, rndVal, LSL #2
+ ;// Truncating source pointer to align to 4 byte location
+ BIC pSrc, pSrc, #3
+
+ ;// Implementation takes care of all combinations of different
+ ;// predictTypes, rounding cases and source pointer offsets to alignment
+ ;// of 4 bytes in different code bases unless one of these parameter wasn't
+ ;// making any difference to the implementation. Below M_CASE_MCRECONBLOCK
+ ;// macros branch into 8 M_CASE macros for all combinations of the 2
+ ;// rounding cases and 4 offsets of the pSrc pointer to the 4 byte
+ ;// alignment.
+ M_SWITCH predictType
+ M_CASE_MCRECONBLOCK IntegerPixel
+ M_CASE_MCRECONBLOCK HalfPixelX
+ M_CASE_MCRECONBLOCK HalfPixelY
+ M_CASE_MCRECONBLOCK HalfPixelXY
+ M_ENDSWITCH
+
+ ;// The M_MCRECONBLOCK macros populate the code bases by calling all 8
+ ;// particular macros (4 in case of IntegerPixel as rounding makes no
+ ;// difference there) to generate the code for all cases of rounding and
+ ;// offsets. LTORG is used to segment the code as code size bloated beyond
+ ;// 4KB.
+ M_MCRECONBLOCK IntegerPixel
+ M_MCRECONBLOCK HalfPixelX
+ LTORG
+ M_MCRECONBLOCK HalfPixelY
+ M_MCRECONBLOCK HalfPixelXY
+SwitchPredictTypeEnd
+
+ ;// Residue Addition
+ ;// This is done in 2 lane SIMD though loads are further optimized and
+ ;// 4 bytes are loaded in case of destination buffer. Algorithmic
+ ;// details are in inlined comments
+ M_LDR pSrcResidue, Stk_pSrcResidue
+ CMP pSrcResidue, #0
+ BEQ pSrcResidueConditionEnd
+pSrcResidueNotNull
+ M_LDR pDst, Stk_pDst
+ MOV y, #8
+ SUB dstStep, dstStep, #4
+Yloop_pSrcResidueNotNull
+ SUBS y, y, #1
+ LDR dst, [pDst] ;// dst = [dcba]
+ LDMIA pSrcResidue!, {tmp1, tmp2} ;// tmp1=[DC] tmp2=[BA]
+ PKHBT tmp3, tmp1, tmp2, LSL #16 ;// Deltaval1 = [C A]
+ PKHTB tmp4, tmp2, tmp1, ASR #16 ;// DeltaVal2 = [D B]
+ UXTB16 tmp1, dst ;// tmp1 = [0c0a]
+ UXTB16 tmp2, dst, ROR #8 ;// tmp2 = [0d0b]
+ QADD16 tmp1, tmp1, tmp3 ;// Add and saturate to 16 bits
+ QADD16 tmp2, tmp2, tmp4
+ USAT16 tmp1, #8, tmp1
+ USAT16 tmp2, #8, tmp2 ;// armClip(0, 255, tmp2)
+ ORR tmp1, tmp1, tmp2, LSL #8 ;// tmp1 = [dcba]
+ STR tmp1, [pDst], #4
+
+ LDR dst, [pDst]
+ LDMIA pSrcResidue!, {tmp1, tmp2}
+ PKHBT tmp3, tmp1, tmp2, LSL #16
+ PKHTB tmp4, tmp2, tmp1, ASR #16
+ UXTB16 tmp1, dst
+ UXTB16 tmp2, dst, ROR #8
+ QADD16 tmp1, tmp1, tmp3
+ QADD16 tmp2, tmp2, tmp4
+ USAT16 tmp1, #8, tmp1
+ USAT16 tmp2, #8, tmp2
+ ORR tmp1, tmp1, tmp2, LSL #8
+ STR tmp1, [pDst], dstStep
+
+ BGT Yloop_pSrcResidueNotNull
+pSrcResidueConditionEnd
+
+ MOV return, #OMX_Sts_NoErr
+
+ M_END
+ ENDIF ;// ARM1136JS
+
+;// ***************************************************************************
+;// CortexA8 implementation
+;// ***************************************************************************
+ END
+;// ***************************************************************************
+;// omxVCM4P2_MCReconBlock ends
+;// ***************************************************************************
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_PredictReconCoefIntra_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_PredictReconCoefIntra_s.s
new file mode 100644
index 0000000..213444a
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_PredictReconCoefIntra_s.s
@@ -0,0 +1,283 @@
+; **********
+; *
+; * File Name: omxVCM4P2_PredictReconCoefIntra_s.s
+; * OpenMAX DL: v1.0.2
+; * Revision: 9641
+; * Date: Thursday, February 7, 2008
+; *
+; * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+; *
+; *
+; *
+; * Description:
+; * Contains module for DC/AC coefficient prediction
+; *
+; *
+; * Function: omxVCM4P2_PredictReconCoefIntra
+; *
+; * Description:
+; * Performs adaptive DC/AC coefficient prediction for an intra block. Prior
+; * to the function call, prediction direction (predDir) should be selected
+; * as specified in subclause 7.4.3.1 of ISO/IEC 14496-2.
+; *
+; * Remarks:
+; *
+; * Parameters:
+; * [in] pSrcDst pointer to the coefficient buffer which contains the
+; * quantized coefficient residuals (PQF) of the current
+; * block; must be aligned on a 4-byte boundary. The
+; * output coefficients are saturated to the range
+; * [-2048, 2047].
+; * [in] pPredBufRow pointer to the coefficient row buffer; must be aligned
+; * on a 4-byte boundary.
+; * [in] pPredBufCol pointer to the coefficient column buffer; must be
+; * aligned on a 4-byte boundary.
+; * [in] curQP quantization parameter of the current block. curQP may
+; * equal to predQP especially when the current block and
+; * the predictor block are in the same macroblock.
+; * [in] predQP quantization parameter of the predictor block
+; * [in] predDir indicates the prediction direction which takes one
+; * of the following values:
+; * OMX_VIDEO_HORIZONTAL predict horizontally
+; * OMX_VIDEO_VERTICAL predict vertically
+; * [in] ACPredFlag a flag indicating if AC prediction should be
+; * performed. It is equal to ac_pred_flag in the bit
+; * stream syntax of MPEG-4
+; * [in] videoComp video component type (luminance, chrominance or
+; * alpha) of the current block
+; * [out] pSrcDst pointer to the coefficient buffer which contains
+; * the quantized coefficients (QF) of the current
+; * block
+; * [out] pPredBufRow pointer to the updated coefficient row buffer
+; * [out] pPredBufCol pointer to the updated coefficient column buffer
+; * Return Value:
+; * OMX_Sts_NoErr - no error
+; * OMX_Sts_BadArgErr - Bad arguments
+; * - At least one of the pointers is NULL: pSrcDst, pPredBufRow, or pPredBufCol.
+; * - At least one the following cases: curQP <= 0, predQP <= 0, curQP >31,
+; * predQP > 31, preDir exceeds [1,2].
+; * - At least one of the pointers pSrcDst, pPredBufRow, or pPredBufCol is not
+; * 4-byte aligned.
+; *
+; *********
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS ARM1136JS
+
+
+
+ IMPORT armVCM4P2_Reciprocal_QP_S32
+ IMPORT armVCM4P2_Reciprocal_QP_S16
+ IMPORT armVCM4P2_DCScaler
+
+
+
+ IF ARM1136JS
+
+
+;// Input Arguments
+
+pSrcDst RN 0
+pPredBufRow RN 1
+pPredBufCol RN 2
+curQP RN 3
+QP RN 3
+predQP RN 4
+predDir RN 5
+ACPredFlag RN 6
+videoComp RN 7
+
+;// Local Variables
+
+temp2 RN 5
+negCurQP RN 7
+negdcScaler RN 7
+tempPred RN 8
+
+dcScaler RN 4
+CoeffTable RN 9
+absCoeffDC RN 9
+temp3 RN 6
+absCoeffAC RN 6
+
+shortVideoHeader RN 9
+predCoeffTable RN 10
+Count RN 10
+temp1 RN 12
+index RN 12
+Rem RN 14
+temp RN 11
+Return RN 0
+
+
+
+ M_START omxVCM4P2_PredictReconCoefIntra,r12
+
+ ;// Assigning pointers to Input arguments on Stack
+
+ M_ARG predQPonStack,4
+ M_ARG predDironStack,4
+ M_ARG ACPredFlagonStack,4
+ M_ARG videoComponStack,4
+
+ ;// DC Prediction
+
+ M_LDR videoComp,videoComponStack ;// Load videoComp From Stack
+
+ M_LDR predDir,predDironStack ;// Load Prediction direction
+
+ ;// dcScaler Calculation
+
+ LDR index, =armVCM4P2_DCScaler
+ ADD index,index,videoComp,LSL #5
+ LDRB dcScaler,[index,QP]
+
+
+calDCVal
+
+
+ LDR predCoeffTable, =armVCM4P2_Reciprocal_QP_S16 ;// Loading the table with entries 32767/(1 to 63)
+
+ CMP predDir,#2 ;// Check if the Prediction direction is vertical
+
+ ;// Caulucate temp pred by performing Division
+
+ LDREQSH absCoeffDC,[pPredBufRow] ;// If vetical load the coeff from Row Prediction Buffer
+ LDRNESH absCoeffDC,[pPredBufCol] ;// If horizontal load the coeff from column Prediction Buffer
+
+ RSB negdcScaler,dcScaler,#0 ;// negdcScaler=-dcScaler
+
+ MOV temp1,absCoeffDC ;// temp1=prediction coeff
+ CMP temp1,#0
+ RSBLT absCoeffDC,temp1,#0 ;//absCoeffDC=abs(temp1)
+
+ ADD temp,dcScaler,dcScaler
+ LDRH temp,[predCoeffTable,temp] ;// Load value from coeff table for performing division using multiplication
+
+ SMULBB tempPred,temp,absCoeffDC ;// tempPred=pPredBufRow(Col)[0]*32767/dcScaler
+ ADD temp3,dcScaler,#1
+ LSR tempPred,tempPred,#15 ;// tempPred=pPredBufRow(Col)[0]/dcScaler
+ LSR temp3,temp3,#1 ;// temp3=round(dcScaler/2)
+
+ MLA Rem,negdcScaler,tempPred,absCoeffDC ;// Rem = pPredBufRow(Col)[0]-tempPred*dcScaler
+
+
+ LDRH temp,[pPredBufCol]
+ CMP Rem,temp3
+ ADDGE tempPred,#1 ;// If Rem>=round(dcScaler/2);tempPred=tempPred+1
+ CMP temp1,#0
+ RSBLT tempPred,tempPred,#0 ;/ if pPredBufRow(Col)[0]<0; tempPred=-tempPred
+
+
+ STRH temp,[pPredBufRow,#-16]
+
+ LDRH temp,[pSrcDst] ;// temp=pSrcDst[0]
+ M_LDR ACPredFlag,ACPredFlagonStack
+ ADD temp,temp,tempPred ;// temp=pSrcDst[0]+tempPred
+ SSAT16 temp,#12,temp ;// clip temp to [-2048,2047]
+
+ SMULBB temp1,temp,dcScaler ;// temp1=clipped(pSrcDst[0])*dcScaler
+ M_LDR predQP,predQPonStack
+ STRH temp,[pSrcDst]
+ CMP ACPredFlag,#1 ;// Check if the AC prediction flag is set or not
+ STRH temp1,[pPredBufCol] ;// store temp1 to pPredBufCol
+
+ ;// AC Prediction
+
+
+ BNE Exit ;// If not set Exit
+
+ LDR predCoeffTable, =armVCM4P2_Reciprocal_QP_S32 ;// Loading the table with entries 0x1ffff/(1 to 63)
+ MOV temp1,#4
+ MUL temp1,curQP,temp1
+ CMP predDir,#2 ;// Check the Prediction direction
+ RSB negCurQP,curQP,#0
+ LDR CoeffTable,[predCoeffTable,temp1] ;// CoeffTable=0x1ffff/curQP
+ ADD curQP,curQP,#1 ;// curQP=curQP+1
+ LSR curQP,curQP,#1 ;// curQP=round(curQP/2)
+ MOV Count,#2 ;// Initializing the Loop Count
+ BNE Horizontal ;// If the Prediction direction is horizontal branch to Horizontal
+
+
+
+loop1
+ ;// Calculate tempPred
+
+ LDRSH absCoeffAC,[pPredBufRow,Count] ;// absCoeffAC=pPredBufRow[i], 1=<i<=7
+ MOV temp1,absCoeffAC
+ CMP temp1,#0 ;// compare pPredBufRow[i] with zero, 1=<i<=7
+ RSBLT absCoeffAC,temp1,#0 ;// absCoeffAC= abs(pPredBufRow[i])
+
+ SMULBB absCoeffAC,absCoeffAC,predQP ;// temp1=pPredBufRow[i]*predQP
+ MUL tempPred,absCoeffAC,CoeffTable ;// tempPred=pPredBufRow[i]*predQP*0x1ffff/curQP
+ LSR tempPred,tempPred,#17
+
+ MLA Rem,negCurQP,tempPred,absCoeffAC ;// Rem=abs(pPredBufRow[i])-tempPred*curQP
+ LDRH temp,[pSrcDst,Count] ;// temp=pSrcDst[i],1<=i<8
+
+ CMP Rem,curQP
+ ADDGE tempPred,#1 ;// if Rem>=round(curQP/2); tempPred=tempPred+1
+ CMP temp1,#0
+ RSBLT tempPred,tempPred,#0 ;// if pPredBufRow[i]<0 ; tempPred=-tempPred
+
+ ;// Update source and Row Prediction buffers
+
+ ADD temp,temp,tempPred ;// temp=tempPred+pSrcDst[i]
+ SSAT16 temp,#12,temp ;// Clip temp to [-2048,2047]
+ STRH temp,[pSrcDst,Count]
+ STRH temp,[pPredBufRow,Count] ;// pPredBufRow[i]=temp
+ ADD Count,Count,#2 ;// i=i+1
+ CMP Count,#16 ;// compare if i=8
+ BLT loop1
+ B Exit ;// Branch to exit
+
+Horizontal
+
+ MOV Count,#16 ;// Initializing i=8
+
+loop2
+
+ LSR temp2,Count,#3 ;// temp2=i>>3
+
+ ;// Calculate tempPred
+
+ LDRH absCoeffAC,[pPredBufCol,temp2] ;// absCoefAC=pPredBufCol[i>>3]
+ MOV temp1,absCoeffAC
+ CMP temp1,#0 ;// compare pPredBufRow[i] with zero, 1=<i<=7
+ RSBLT absCoeffAC,temp1,#0 ;// absCoeffAC=abs(pPredBufCol[i>>3])
+
+ SMULBB absCoeffAC,absCoeffAC,predQP ;// temp1=pPredBufCol[i>>3]*predQP
+ MUL tempPred,absCoeffAC,CoeffTable ;// tempPred=pPredBufCol[i>>3]*predQP*0x1ffff/curQP
+ LSR tempPred,tempPred,#17 ;// tempPred=pPredBufCol[i>>3]*predQP/curQP
+
+ MLA Rem,negCurQP,tempPred,absCoeffAC
+ LDRH temp,[pSrcDst,Count] ;// temp=pSrcDst[i]
+
+ CMP Rem,curQP ;// Compare Rem with round(curQP/2)
+ ADDGE tempPred,#1 ;// tempPred=tempPred+1 if Rem>=round(curQP/2)
+ CMP temp1,#0
+ RSBLT tempPred,tempPred,#0 ;// if pPredBufCol[i>>3 <0 tempPred=-tempPred
+
+ ;// Update source and Row Prediction buffers
+
+ ADD temp,temp,tempPred ;// temp=pSrcDst[i]+tempPred
+ SSAT16 temp,#12,temp ;// Clip temp to [-2048,2047]
+ STRH temp,[pSrcDst,Count] ;// pSrcDst[0]= clipped value
+ STRH temp,[pPredBufCol,temp2] ;// pPredBufCol[i>>3]=temp
+ ADD Count,Count,#16 ;// i=i+8
+ CMP Count,#128 ;// compare i with 64
+ BLT loop2
+
+
+Exit
+
+ MOV Return,#OMX_Sts_NoErr
+
+ M_END
+ ENDIF
+ END
+
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_QuantInvInter_I_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_QuantInvInter_I_s.s
new file mode 100644
index 0000000..c9591cb
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_QuantInvInter_I_s.s
@@ -0,0 +1,141 @@
+;/**
+; *
+; * File Name: omxVCM4P2_QuantInvInter_I_s.s
+; * OpenMAX DL: v1.0.2
+; * Revision: 9641
+; * Date: Thursday, February 7, 2008
+; *
+; * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+; *
+; *
+; *
+; * Description:
+; * Contains modules for inter reconstruction
+; *
+; *
+; *
+; *
+; *
+; * Function: omxVCM4P2_QuantInvInter_I
+; *
+; * Description:
+; * Performs inverse quantization on intra/inter coded block.
+; * This function supports bits_per_pixel = 8. Mismatch control
+; * is performed for the first MPEG-4 mode inverse quantization method.
+; * The output coefficients are clipped to the range: [-2048, 2047].
+; * Mismatch control is performed for the first inverse quantization method.
+; *
+; * Remarks:
+; *
+; * Parameters:
+; * [in] pSrcDst pointer to the input (quantized) intra/inter block. Must be 16-byte aligned.
+; * [in] QP quantization parameter (quantiser_scale)
+; * [in] videoComp (Intra version only.) Video component type of the
+; * current block. Takes one of the following flags:
+; * OMX_VC_LUMINANCE, OMX_VC_CHROMINANCE,
+; * OMX_VC_ALPHA.
+; * [in] shortVideoHeader a flag indicating presence of short_video_header;
+; * shortVideoHeader==1 selects linear intra DC mode,
+; * and shortVideoHeader==0 selects nonlinear intra DC mode.
+; * [out] pSrcDst pointer to the output (dequantized) intra/inter block. Must be 16-byte aligned.
+; *
+; * Return Value:
+; * OMX_Sts_NoErr - no error
+; * OMX_Sts_BadArgErr - bad arguments
+; * - If pSrcDst is NULL or is not 16-byte aligned.
+; * or
+; * - If QP <= 0.
+; * or
+; * - videoComp is none of OMX_VC_LUMINANCE, OMX_VC_CHROMINANCE and OMX_VC_ALPHA.
+; *
+; */
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS ARM1136JS
+
+
+
+ IF ARM1136JS
+
+;//Input Arguments
+pSrcDst RN 0
+QP RN 1
+
+;//Local Variables
+Return RN 0
+Count RN 4
+tempVal21 RN 2
+tempVal43 RN 3
+QP1 RN 5
+X2 RN 6
+X3 RN 14
+Result1 RN 8
+Result2 RN 9
+two RN 7
+
+ M_START omxVCM4P2_QuantInvInter_I,r9
+
+ MOV Count,#64
+ TST QP,#1
+ LDRD tempVal21,[pSrcDst] ;// Loads first two values of pSrcDst to tempVal21,
+ ;// next two values to tempVal43
+ SUBEQ QP1,QP,#1 ;// QP1=QP if QP is odd , QP1=QP-1 if QP is even
+ MOVNE QP1,QP
+ MOV two,#2
+
+
+
+Loop
+
+
+ SMULBB X2,tempVal21,two ;// X2= first val(lower 16 bits of tampVal21)*2
+ CMP X2,#0
+
+ RSBLT X2,X2,#0 ;// X2=absoluteval(first val)
+ SMLABBNE X2,QP,X2,QP1 ;// X2=2*absval(first val)*QP+QP if QP is odd
+ ;// X2=2*absval(first val)*QP+QP-1 if QP is even
+ SMULTB X3,tempVal21,two ;// X3= second val(top 16 bits of tampVal21)*2
+ RSBLT X2,X2,#0
+
+ CMP X3,#0
+
+ RSBLT X3,X3,#0
+ SMLABBNE X3,QP,X3,QP1
+
+ RSBLT X3,X3,#0
+ PKHBT Result1,X2,X3,LSL #16 ;// Result1[0-15]=X2[0-15],Result1[16-31]=X3[16-31]
+ SMULBB X2,tempVal43,two ;// X2= first val(lower 16 bits of tampVal43)*2
+ SSAT16 Result1,#12,Result1 ;// clip to range [-2048,2047]
+ CMP X2,#0
+
+
+
+ RSBLE X2,X2,#0
+ SMLABBNE X2,QP,X2,QP1
+ SMULTB X3,tempVal43,two ;// X2= first val(top 16 bits of tampVal21)*2
+ RSBLT X2,X2,#0
+ CMP X3,#0
+
+ LDRD tempVal21,[pSrcDst,#8] ;// Load next four Values to tempVal21,tempVal43
+
+ RSBLT X3,X3,#0
+ SMLABBNE X3,QP,X3,QP1
+ RSBLT X3,X3,#0
+ PKHBT Result2,X2,X3,LSL #16 ;// Result2[0-15]=X2[0-15],Result2[16-31]=X3[0-15]
+ SSAT16 Result2,#12,Result2 ;// clip to range [-2048,2047]
+
+ SUBS Count,Count,#4 ;// Decrement Count by 4 and continue if it has not reached 0
+ STRD Result1,[pSrcDst],#8 ;// Store Double words and increment the pointer to point the next store address
+
+
+
+ BGT Loop
+
+ MOV Return,#OMX_Sts_NoErr
+
+ M_END
+ ENDIF
+ END
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_QuantInvIntra_I_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_QuantInvIntra_I_s.s
new file mode 100644
index 0000000..6328e01
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_QuantInvIntra_I_s.s
@@ -0,0 +1,188 @@
+;/**
+; *
+; * File Name: omxVCM4P2_QuantInvIntra_I_s.s
+; * OpenMAX DL: v1.0.2
+; * Revision: 9641
+; * Date: Thursday, February 7, 2008
+; *
+; * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+; *
+; *
+; *
+; * Description:
+; * Contains modules for inter reconstruction
+; *
+; *
+; *
+; *
+; *
+; *
+; * Function: omxVCM4P2_QuantInvIntra_I
+; *
+; * Description:
+; * Performs inverse quantization on intra/inter coded block.
+; * This function supports bits_per_pixel = 8. Mismatch control
+; * is performed for the first MPEG-4 mode inverse quantization method.
+; * The output coefficients are clipped to the range: [-2048, 2047].
+; * Mismatch control is performed for the first inverse quantization method.
+; *
+; * Remarks:
+; *
+; * Parameters:
+; * [in] pSrcDst pointer to the input (quantized) intra/inter block. Must be 16-byte aligned.
+; * [in] QP quantization parameter (quantiser_scale)
+; * [in] videoComp (Intra version only.) Video component type of the
+; * current block. Takes one of the following flags:
+; * OMX_VC_LUMINANCE, OMX_VC_CHROMINANCE,
+; * OMX_VC_ALPHA.
+; * [in] shortVideoHeader a flag indicating presence of short_video_header;
+; * shortVideoHeader==1 selects linear intra DC mode,
+; * and shortVideoHeader==0 selects nonlinear intra DC mode.
+; * [out] pSrcDst pointer to the output (dequantized) intra/inter block. Must be 16-byte aligned.
+; *
+; * Return Value:
+; * OMX_Sts_NoErr - no error
+; * OMX_Sts_BadArgErr - bad arguments
+; * - If pSrcDst is NULL or is not 16-byte aligned.
+; * or
+; * - If QP <= 0.
+; * or
+; * - videoComp is none of OMX_VC_LUMINANCE, OMX_VC_CHROMINANCE and OMX_VC_ALPHA.
+; *
+
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS ARM1136JS
+
+
+ IMPORT armVCM4P2_DCScaler
+
+
+
+ IF ARM1136JS
+
+;//Input Arguments
+pSrcDst RN 0
+QP RN 1
+videoComp RN 2
+shortVideoHeader RN 3
+
+;//Local Variables
+Return RN 0
+dcScaler RN 4
+temp RN 12
+index RN 6
+
+tempVal21 RN 4
+tempVal43 RN 5
+QP1 RN 6
+X2 RN 7
+X3 RN 14
+Result1 RN 8
+Result2 RN 9
+two RN 10
+Count RN 11
+
+
+
+
+ M_START omxVCM4P2_QuantInvIntra_I,r11
+
+
+
+ ;// Perform Inverse Quantization for DC coefficient
+
+ TEQ shortVideoHeader,#0 ;// Test if short Video Header flag =0
+ MOVNE dcScaler,#8 ;// if shortVideoHeader is non zero dcScaler=8
+ BNE calDCVal
+ LDR index, =armVCM4P2_DCScaler
+ ADD index,index,videoComp,LSL #5
+ LDRB dcScaler,[index,QP]
+
+
+ ;//M_CalDCScalar shortVideoHeader,videoComp, QP
+
+calDCVal
+
+ LDRH temp,[pSrcDst]
+ SMULBB temp,temp,dcScaler ;// dcCoeff = dcScaler * Quantized DC coefficient(from memory)
+ SSAT temp,#12,temp ;// Saturating to 12 bits
+
+
+ MOV Count,#64
+ TST QP,#1
+ LDRD tempVal21,[pSrcDst] ;// Loads first two values of pSrcDst to tempVal21,
+ ;// next two values to tempVal43
+ SUBEQ QP1,QP,#1 ;// QP1=QP if QP is odd , QP1=QP-1 if QP is even
+ MOVNE QP1,QP
+ MOV two,#2
+
+
+
+
+
+Loop
+
+
+ SMULBB X2,tempVal21,two ;// X2= first val(lower 16 bits of tampVal21)*2
+ CMP X2,#0
+
+ RSBLT X2,X2,#0 ;// X2=absoluteval(first val)
+ SMLABBNE X2,QP,X2,QP1 ;// X2=2*absval(first val)*QP+QP if QP is odd
+ ;// X2=2*absval(first val)*QP+QP-1 if QP is even
+ SMULTB X3,tempVal21,two ;// X3= second val(top 16 bits of tampVal21)*2
+ RSBLT X2,X2,#0
+
+ CMP X3,#0
+
+ RSBLT X3,X3,#0
+ SMLABBNE X3,QP,X3,QP1
+
+ RSBLT X3,X3,#0
+ PKHBT Result1,X2,X3,LSL #16 ;// Result1[0-15]=X2[0-15],Result1[16-31]=X3[16-31]
+ SMULBB X2,tempVal43,two ;// X2= first val(lower 16 bits of tampVal43)*2
+ SSAT16 Result1,#12,Result1 ;// clip to range [-2048,2047]
+ CMP X2,#0
+
+
+
+ RSBLE X2,X2,#0
+ SMLABBNE X2,QP,X2,QP1
+ SMULTB X3,tempVal43,two ;// X2= first val(top 16 bits of tampVal21)*2
+ RSBLT X2,X2,#0
+ CMP X3,#0
+
+ LDRD tempVal21,[pSrcDst,#8] ;// Load next four Values to tempVal21,tempVal43
+
+ RSBLT X3,X3,#0
+ SMLABBNE X3,QP,X3,QP1
+ RSBLT X3,X3,#0
+ PKHBT Result2,X2,X3,LSL #16 ;// Result2[0-15]=X2[0-15],Result2[16-31]=X3[16-31]
+ SSAT16 Result2,#12,Result2 ;// clip to range [-2048,2047]
+
+ SUBS Count,Count,#4 ;// Decrement Count by 4 and continue if it has not reached 0
+ STRD Result1,[pSrcDst],#8 ;// Store Double words and increment the pointer to point the next store address
+
+
+
+ BGT Loop
+
+ SUB pSrcDst,pSrcDst,#128
+
+ ;// Storing the Inverse Quantized DC coefficient
+
+ STRH temp,[pSrcDst],#2
+
+
+
+ MOV Return,#OMX_Sts_NoErr
+
+
+
+
+ M_END
+ ENDIF
+ END
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/src/armVC_Version.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/src/armVC_Version.c
new file mode 100644
index 0000000..5d93681
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/src/armVC_Version.c
@@ -0,0 +1,6 @@
+#include "omxtypes.h"
+#include "armCOMM_Version.h"
+
+#ifdef ARM_INCLUDE_VERSION_DESCRIPTIONS
+const char * const omxVC_VersionDescription = "ARM OpenMAX DL v" ARM_VERSION_STRING " Rel=" OMX_ARM_RELEASE_TAG " Arch=" OMX_ARM_BUILD_ARCHITECTURE " Tools=" OMX_ARM_BUILD_TOOLCHAIN ;
+#endif /* ARM_INCLUDE_VERSION_DESCRIPTIONS */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/ARM_DELIVERY.TXT b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/ARM_DELIVERY.TXT
new file mode 100755
index 0000000..cc2d70a
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/ARM_DELIVERY.TXT
@@ -0,0 +1,63 @@
+The contents of this transaction was created by Hedley Francis
+of ARM on 19-Feb-2008.
+
+It contains the ARM data versions listed below.
+
+This data, unless otherwise stated, is ARM Proprietary and access to it
+is subject to the agreements indicated below.
+
+If you experience problems with this data, please contact ARM support
+quoting transaction reference <97414>.
+
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+- OX002-SW-98010-r0p0-00bet1
+ Video codecs - optimised code
+ V7 code release for Hantro (Ver 1.0.2)
+ internal access
+
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+This transaction contains deliverables which are designated as being of
+beta release status (BET).
+
+Beta release status has a particular meaning to ARM of which the recipient
+must be aware. Beta is a pre-release status indicating that the deliverable
+so described is believed to robustly demonstrate specified behaviour, to be
+consistent across its included aspects and be ready for general deployment.
+But Beta also indicates that pre-release reliability trials are ongoing and
+that it is possible residual defects or errors in operation, consistency
+and documentation may still be encountered. The recipient should consider
+this position when using this Beta material supplied. ARM will normally
+attempt to provide fixes or a work-around for defects identified by the
+recipient, but the provision or timeliness of this support cannot be
+guaranteed. ARM shall not be responsible for direct or consequential
+damages as a result of encountering one or more of these residual defects.
+By accepting a Beta release, the recipient agrees to these constraints and
+to providing reasonable information to ARM to enable the replication of the
+defects identified by the recipient. The specific Beta version supplied
+will not be supported after release of a later or higher status version.
+It should be noted that Support for the Beta release of the deliverable
+will only be provided by ARM to a recipient who has a current support and
+maintenance contract for the deliverable.
+
+
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+In addition to the data versions listed above, this transaction contains
+two additional files at the top level.
+
+The first is this file, ARM_DELIVERY_97414.TXT, which is the delivery
+note.
+
+The second is ARM_MANIFEST_97414.TXT which contains a manifest of all the
+files included in this transaction, together with their checksums.
+
+The checksums provided are calculated using the RSA Data Security, Inc.
+MD5 Message-Digest Algorithm.
+
+The checksums can be used to verify the integrity of this data using the
+"md5sum" tool (which is part of the GNU "textutils" package) by running:
+
+ % md5sum --check ARM_MANIFEST_97414.TXT
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/ARM_MANIFEST.TXT b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/ARM_MANIFEST.TXT
new file mode 100755
index 0000000..8310f67
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/ARM_MANIFEST.TXT
@@ -0,0 +1,91 @@
+ OX002-SW-98010-r0p0-00bet1/
+ OX002-SW-98010-r0p0-00bet1/api/
+e049791cfab6060a08cbac7b3ad767d6 OX002-SW-98010-r0p0-00bet1/api/armCOMM_s.h
+ed798face25497b2703ede736d6d52b6 OX002-SW-98010-r0p0-00bet1/api/omxtypes_s.h
+4eebd63af087376811d6749f0646b864 OX002-SW-98010-r0p0-00bet1/api/armCOMM_BitDec_s.h
+43cf46c2cf2fe1f93c615b57bcbe4809 OX002-SW-98010-r0p0-00bet1/api/armCOMM.h
+8f248ceaac8f602e277a521b679dcbbe OX002-SW-98010-r0p0-00bet1/api/armCOMM_IDCTTable.h
+8ac5fa80ea98e391f5730a375280b5bd OX002-SW-98010-r0p0-00bet1/api/armCOMM_Version.h
+3a2f420ddf6a1b950470bd0f5ebd5c62 OX002-SW-98010-r0p0-00bet1/api/armCOMM_IDCT_s.h
+511c0bb534fe223599e2c84eff24c9ed OX002-SW-98010-r0p0-00bet1/api/armCOMM_MaskTable.h
+8971932d56eed6b1ad1ba507f0bff5f0 OX002-SW-98010-r0p0-00bet1/api/armCOMM_Bitstream.h
+f87fedd9ca432fefa757008176864ef8 OX002-SW-98010-r0p0-00bet1/api/armOMX.h
+8e49899a428822c36ef9dd94e0e05f18 OX002-SW-98010-r0p0-00bet1/api/omxtypes.h
+323008b72e9f04099a8cb42e99a1face OX002-SW-98010-r0p0-00bet1/build_vc.pl
+e72d96c0a415459748df9807f3dae72f OX002-SW-98010-r0p0-00bet1/filelist_vc.txt
+ OX002-SW-98010-r0p0-00bet1/src/
+5eeae659a29477f5c52296d24afffd3c OX002-SW-98010-r0p0-00bet1/src/armCOMM_IDCTTable.c
+d64cdcf38f7749dc7f77465e5b7d356d OX002-SW-98010-r0p0-00bet1/src/armCOMM_MaskTable.c
+ OX002-SW-98010-r0p0-00bet1/vc/
+ OX002-SW-98010-r0p0-00bet1/vc/m4p10/
+ OX002-SW-98010-r0p0-00bet1/vc/m4p10/src/
+e7e0c320978564a7c9b2c723749a98d6 OX002-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_CAVLCTables.c
+4adcd0df081990bdfc4729041a2a9152 OX002-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_InterpolateChroma.c
+852e0404142965dc1f3aa7f00ee5127b OX002-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_UnpackBlock4x4_s.s
+7054151c5bfea6b5e74feee86b2d7b01 OX002-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_DecodeCoeffsToPairCAVLC.c
+5f7213a4f37627b3c58f6294ba477e30 OX002-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_DequantTables_s.s
+32ff4b8be62e2f0f3e764b83c1e5e2fd OX002-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_DeblockChroma_I.c
+d066e3c81d82616f37ec1810ea49e7b7 OX002-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_DeblockingLuma_unsafe_s.s
+fe629a3e9d55395a6098bdf2431b5f02 OX002-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_DeblockingChroma_unsafe_s.s
+5b13fb954b7679de20076bb6a7f4ee1d OX002-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_InterpolateLuma_s.s
+01ba60eff66ea49a4f833ce6279f8e2f OX002-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_DeblockLuma_I.c
+fa1072cf1d17e9666c9f1e215fa302b1 OX002-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe_s.s
+db387b9e66d32787f47ef9cf0347da2a OX002-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe_s.s
+ea537e4e2ad03a1940981055fa3ace01 OX002-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe_s.s
+29a4283885b9473a3550a81eff2559d2 OX002-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_TransformDequantChromaDCFromPair_s.s
+2ddcaf60a8ea1e6e6b77737f768bfb9d OX002-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_QuantTables_s.s
+c3002aad5600f872b70a5d7fe3915846 OX002-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_InterpolateLuma_Align_unsafe_s.s
+a2900f2c47f1c61d20bd6c1eda33d6d4 OX002-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_InterpolateLuma_Copy_unsafe_s.s
+c921df73397a32c947dc996ba6858553 OX002-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_PredictIntra_4x4_s.s
+3769e14f2fc3f514d025fe6ab73ff67a OX002-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_TransformDequantLumaDCFromPair_s.s
+c029d1cebea0a09e1d235a37e2155002 OX002-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_HorEdge_I_s.s
+076a033f8161750a685756f9f51f04c9 OX002-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe_s.s
+c5b5d22842822e6e5e31094882cbeb46 OX002-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_PredictIntra_16x16_s.s
+f6bdf6d914a4a1479f524951a3409846 OX002-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_VerEdge_I_s.s
+ebeb0713a9b2ea25986360ef262138c4 OX002-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_HorEdge_I_s.s
+78ed9ea200faa7be665445a713859af1 OX002-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_VerEdge_I_s.s
+c2d995f787b6f44ef10c751c12d1935f OX002-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_InterpolateLuma_DiagCopy_unsafe_s.s
+40bed679a9f6e0d3efe216b7d4a9cf45 OX002-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_PredictIntraChroma_8x8_s.s
+4a52b3e9e268b8a8f07829bf500d03af OX002-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_DecodeCoeffsToPair_s.s
+11249f8a98c5d4b84cb5575b0e37ca9c OX002-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_Average_4x_Align_unsafe_s.s
+2513b60559ba71ae495c6053fb779fa9 OX002-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_Interpolate_Chroma_s.s
+2fb1ee17c36e3c1469c170f6dac11bf1 OX002-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_TransformResidual4x4_s.s
+cc4a6f32db0b72a91d3f278f6855df69 OX002-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c
+ OX002-SW-98010-r0p0-00bet1/vc/m4p10/api/
+6e530ddaa7c2b57ffe88162c020cb662 OX002-SW-98010-r0p0-00bet1/vc/m4p10/api/armVCM4P10_CAVLCTables.h
+ OX002-SW-98010-r0p0-00bet1/vc/m4p2/
+ OX002-SW-98010-r0p0-00bet1/vc/m4p2/src/
+bec6de348b113438498867b869001622 OX002-SW-98010-r0p0-00bet1/vc/m4p2/src/armVCM4P2_Clip8_s.s
+dba9824e959b21d401cac925e68a11a6 OX002-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_Inter_s.s
+dfa7e5b58027be3542dda0593b77b2d3 OX002-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_QuantInvIntra_I_s.s
+4fba4c431a783a78a2eb6497a94ac967 OX002-SW-98010-r0p0-00bet1/vc/m4p2/src/armVCM4P2_Zigzag_Tables.c
+39991961179ca03b6381b6e653b1f14b OX002-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_MCReconBlock_s.s
+1b0b2990c2669dfb87cf6b810611c01b OX002-SW-98010-r0p0-00bet1/vc/m4p2/src/armVCM4P2_Huff_Tables_VLC.c
+1c9b87abf3283e957816b3937c680701 OX002-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_DecodePadMV_PVOP_s.s
+4fe1afca659a9055fc1172e58f78a506 OX002-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Intra.c
+2ea067f0436f91ba1351edaf411cb4ea OX002-SW-98010-r0p0-00bet1/vc/m4p2/src/armVCM4P2_Lookup_Tables.c
+6ce363aadc9d65c308b40cca8902e4f6 OX002-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_IDCT8x8blk_s.s
+bf212f786772aed2bc705d22ff4e74f5 OX002-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_FindMVpred_s.s
+293a48a648a3085456e6665bb7366fad OX002-SW-98010-r0p0-00bet1/vc/m4p2/src/armVCM4P2_SetPredDir_s.s
+2bb47ed9c9e25c5709c6d9b4ad39a38a OX002-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_QuantInvInter_I_s.s
+437dfa204508850d61d4b87091446e9f OX002-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraACVLC_s.s
+bc9778898dd41101dc0fb0139eaf83cc OX002-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraDCVLC_s.s
+fc191eeae43f8ce735dbd311cc7bcb8d OX002-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_PredictReconCoefIntra_s.s
+a0d85f4f517c945a4c9317ac021f2d08 OX002-SW-98010-r0p0-00bet1/vc/m4p2/src/armVCM4P2_DecodeVLCZigzag_AC_unsafe_s.s
+386020dee8b725c7fe2526f1fc211d7d OX002-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Inter.c
+ OX002-SW-98010-r0p0-00bet1/vc/m4p2/api/
+4624e7c838e10a249abcc3d3f4f40748 OX002-SW-98010-r0p0-00bet1/vc/m4p2/api/armVCM4P2_Huff_Tables_VLC.h
+65e1057d04e2cb844559dc9f6e09795a OX002-SW-98010-r0p0-00bet1/vc/m4p2/api/armVCM4P2_ZigZag_Tables.h
+ OX002-SW-98010-r0p0-00bet1/vc/src/
+e627b3346b0dc9aff14446005ce0fa43 OX002-SW-98010-r0p0-00bet1/vc/src/armVC_Version.c
+ OX002-SW-98010-r0p0-00bet1/vc/api/
+7ca94b1c33ac0211e17d38baadd7d1dd OX002-SW-98010-r0p0-00bet1/vc/api/armVC.h
+12cf7596edbbf6048b626d15e8d0ed48 OX002-SW-98010-r0p0-00bet1/vc/api/omxVC.h
+11726e286a81257cb45f5547fb4d374c OX002-SW-98010-r0p0-00bet1/vc/api/omxVC_s.h
+a5b2af605c319cd2491319e430741377 OX002-SW-98010-r0p0-00bet1/vc/api/armVCCOMM_s.h
+ OX002-SW-98010-r0p0-00bet1/vc/comm/
+ OX002-SW-98010-r0p0-00bet1/vc/comm/src/
+1f81187b48487a8ea6dbc327648e3e4f OX002-SW-98010-r0p0-00bet1/vc/comm/src/omxVCCOMM_Copy16x16_s.s
+936d3f2038a6f8613ec25e50cc601fe8 OX002-SW-98010-r0p0-00bet1/vc/comm/src/omxVCCOMM_Copy8x8_s.s
+8f6708a249130962e0bc5c044ac6dd93 OX002-SW-98010-r0p0-00bet1/vc/comm/src/omxVCCOMM_ExpandFrame_I_s.s
+aab7713414428e95de0ba799a2679b36 ARM_DELIVERY_97414.TXT
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM.h
new file mode 100755
index 0000000..64c1958
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM.h
@@ -0,0 +1,785 @@
+/**
+ *
+ * File Name: armCOMM.h
+ * OpenMAX DL: v1.0.2
+ * Revision: 12290
+ * Date: Wednesday, April 9, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * File: armCOMM.h
+ * Brief: Declares Common APIs/Data Types used across OpenMAX API's
+ *
+ */
+
+
+#ifndef _armCommon_H_
+#define _armCommon_H_
+
+#include "omxtypes.h"
+
+typedef struct
+{
+ OMX_F32 Re; /** Real part */
+ OMX_F32 Im; /** Imaginary part */
+
+} OMX_FC32; /** single precision floating point complex number */
+
+typedef struct
+{
+ OMX_F64 Re; /** Real part */
+ OMX_F64 Im; /** Imaginary part */
+
+} OMX_FC64; /** double precision floating point complex number */
+
+
+/* Used by both IP and IC domains for 8x8 JPEG blocks. */
+typedef OMX_S16 ARM_BLOCK8x8[64];
+
+
+#include "armOMX.h"
+
+#define armPI (OMX_F64)(3.1415926535897932384626433832795)
+
+/***********************************************************************/
+
+/* Compiler extensions */
+#ifdef ARM_DEBUG
+/* debug version */
+#include <stdlib.h>
+#include <assert.h>
+#include <stdio.h>
+#define armError(str) {printf((str)); printf("\n"); exit(-1);}
+#define armWarn(str) {printf((str)); printf("\n");}
+#define armIgnore(a) ((void)a)
+#define armAssert(a) assert(a)
+#else
+/* release version */
+#define armError(str) ((void) (str))
+#define armWarn(str) ((void) (str))
+#define armIgnore(a) ((void) (a))
+#define armAssert(a) ((void) (a))
+#endif /* ARM_DEBUG */
+
+/* Arithmetic operations */
+
+#define armMin(a,b) ( (a) > (b) ? (b):(a) )
+#define armMax(a,b) ( (a) > (b) ? (a):(b) )
+#define armAbs(a) ( (a) < 0 ? -(a):(a) )
+
+/* Alignment operation */
+
+#define armAlignToBytes(Ptr,N) (Ptr + ( ((N-(int)Ptr)&(N-1)) / sizeof(*Ptr) ))
+#define armAlignTo2Bytes(Ptr) armAlignToBytes(Ptr,2)
+#define armAlignTo4Bytes(Ptr) armAlignToBytes(Ptr,4)
+#define armAlignTo8Bytes(Ptr) armAlignToBytes(Ptr,8)
+#define armAlignTo16Bytes(Ptr) armAlignToBytes(Ptr,16)
+
+/* Error and Alignment check */
+
+#define armRetArgErrIf(condition, code) if(condition) { return (code); }
+#define armRetDataErrIf(condition, code) if(condition) { return (code); }
+
+#ifndef ALIGNMENT_DOESNT_MATTER
+#define armIsByteAligned(Ptr,N) ((((int)(Ptr)) % N)==0)
+#define armNotByteAligned(Ptr,N) ((((int)(Ptr)) % N)!=0)
+#else
+#define armIsByteAligned(Ptr,N) (1)
+#define armNotByteAligned(Ptr,N) (0)
+#endif
+
+#define armIs2ByteAligned(Ptr) armIsByteAligned(Ptr,2)
+#define armIs4ByteAligned(Ptr) armIsByteAligned(Ptr,4)
+#define armIs8ByteAligned(Ptr) armIsByteAligned(Ptr,8)
+#define armIs16ByteAligned(Ptr) armIsByteAligned(Ptr,16)
+
+#define armNot2ByteAligned(Ptr) armNotByteAligned(Ptr,2)
+#define armNot4ByteAligned(Ptr) armNotByteAligned(Ptr,4)
+#define armNot8ByteAligned(Ptr) armNotByteAligned(Ptr,8)
+#define armNot16ByteAligned(Ptr) armNotByteAligned(Ptr,16)
+#define armNot32ByteAligned(Ptr) armNotByteAligned(Ptr,32)
+
+/**
+ * Function: armRoundFloatToS16_ref/armRoundFloatToS32_ref/armRoundFloatToS64
+ *
+ * Description:
+ * Converts a double precision value into a short int/int after rounding
+ *
+ * Parameters:
+ * [in] Value Float value to be converted
+ *
+ * Return Value:
+ * [out] converted value in OMX_S16/OMX_S32 format
+ *
+ */
+
+OMX_S16 armRoundFloatToS16 (OMX_F64 Value);
+OMX_S32 armRoundFloatToS32 (OMX_F64 Value);
+OMX_S64 armRoundFloatToS64 (OMX_F64 Value);
+
+/**
+ * Function: armSatRoundFloatToS16_ref/armSatRoundFloatToS32
+ *
+ * Description:
+ * Converts a double precision value into a short int/int after rounding and saturation
+ *
+ * Parameters:
+ * [in] Value Float value to be converted
+ *
+ * Return Value:
+ * [out] converted value in OMX_S16/OMX_S32 format
+ *
+ */
+
+OMX_S16 armSatRoundFloatToS16 (OMX_F64 Value);
+OMX_S32 armSatRoundFloatToS32 (OMX_F64 Value);
+
+/**
+ * Function: armSatRoundFloatToU16_ref/armSatRoundFloatToU32
+ *
+ * Description:
+ * Converts a double precision value into a unsigned short int/int after rounding and saturation
+ *
+ * Parameters:
+ * [in] Value Float value to be converted
+ *
+ * Return Value:
+ * [out] converted value in OMX_U16/OMX_U32 format
+ *
+ */
+
+OMX_U16 armSatRoundFloatToU16 (OMX_F64 Value);
+OMX_U32 armSatRoundFloatToU32 (OMX_F64 Value);
+
+/**
+ * Function: armSignCheck
+ *
+ * Description:
+ * Checks the sign of a variable:
+ * returns 1 if it is Positive
+ * returns 0 if it is 0
+ * returns -1 if it is Negative
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] var Variable to be checked
+ *
+ * Return Value:
+ * OMX_INT -- returns 1 if it is Positive
+ * returns 0 if it is 0
+ * returns -1 if it is Negative
+ */
+
+OMX_INT armSignCheck (OMX_S16 var);
+
+/**
+ * Function: armClip
+ *
+ * Description: Clips the input between MAX and MIN value
+ *
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] Min lower bound
+ * [in] Max upper bound
+ * [in] src variable to the clipped
+ *
+ * Return Value:
+ * OMX_S32 -- returns clipped value
+ */
+
+OMX_S32 armClip (
+ OMX_INT min,
+ OMX_INT max,
+ OMX_S32 src
+ );
+
+/**
+ * Function: armClip_F32
+ *
+ * Description: Clips the input between MAX and MIN value
+ *
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] Min lower bound
+ * [in] Max upper bound
+ * [in] src variable to the clipped
+ *
+ * Return Value:
+ * OMX_F32 -- returns clipped value
+ */
+
+OMX_F32 armClip_F32 (
+ OMX_F32 min,
+ OMX_F32 max,
+ OMX_F32 src
+ );
+
+/**
+ * Function: armShiftSat_F32
+ *
+ * Description: Divides a float value by 2^shift and
+ * saturates it for unsigned value range for satBits.
+ * Second parameter is like "shifting" the corresponding
+ * integer value. Takes care of rounding while clipping the final
+ * value.
+ *
+ * Parameters:
+ * [in] v Number to be operated upon
+ * [in] shift Divides the input "v" by "2^shift"
+ * [in] satBits Final range is [0, 2^satBits)
+ *
+ * Return Value:
+ * OMX_S32 -- returns "shifted" saturated value
+ */
+
+OMX_U32 armShiftSat_F32(
+ OMX_F32 v,
+ OMX_INT shift,
+ OMX_INT satBits
+ );
+
+/**
+ * Functions: armSwapElem
+ *
+ * Description:
+ * This function swaps two elements at the specified pointer locations.
+ * The size of each element could be anything as specified by <elemSize>
+ *
+ * Return Value:
+ * OMXResult -- Error status from the function
+ */
+OMXResult armSwapElem(OMX_U8 *pBuf1, OMX_U8 *pBuf2, OMX_INT elemSize);
+
+
+/**
+ * Function: armMedianOf3
+ *
+ * Description: Finds the median of three numbers
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] fEntry First entry
+ * [in] sEntry second entry
+ * [in] tEntry Third entry
+ *
+ * Return Value:
+ * OMX_S32 -- returns the median value
+ */
+
+OMX_S32 armMedianOf3 (
+ OMX_S32 fEntry,
+ OMX_S32 sEntry,
+ OMX_S32 tEntry
+ );
+
+/**
+ * Function: armLogSize
+ *
+ * Description: Finds the size of a positive value and returns the same
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] value Positive value
+ *
+ * Return Value:
+ * OMX_U8 -- returns the size of the positive value
+ */
+
+OMX_U8 armLogSize (
+ OMX_U16 value
+ );
+
+/***********************************************************************/
+ /* Saturating Arithmetic operations */
+
+/**
+ * Function :armSatAdd_S32()
+ *
+ * Description :
+ * Returns the result of saturated addition of the two inputs Value1, Value2
+ *
+ * Parametrs:
+ * [in] Value1 First Operand
+ * [in] Value2 Second Operand
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ *
+ **/
+
+OMX_S32 armSatAdd_S32(
+ OMX_S32 Value1,
+ OMX_S32 Value2
+ );
+
+/**
+ * Function :armSatAdd_S64()
+ *
+ * Description :
+ * Returns the result of saturated addition of the two inputs Value1, Value2
+ *
+ * Parametrs:
+ * [in] Value1 First Operand
+ * [in] Value2 Second Operand
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ *
+ **/
+
+OMX_S64 armSatAdd_S64(
+ OMX_S64 Value1,
+ OMX_S64 Value2
+ );
+
+/** Function :armSatSub_S32()
+ *
+ * Description :
+ * Returns the result of saturated substraction of the two inputs Value1, Value2
+ *
+ * Parametrs:
+ * [in] Value1 First Operand
+ * [in] Value2 Second Operand
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ **/
+
+OMX_S32 armSatSub_S32(
+ OMX_S32 Value1,
+ OMX_S32 Value2
+ );
+
+/**
+ * Function :armSatMac_S32()
+ *
+ * Description :
+ * Returns the result of Multiplication of Value1 and Value2 and subesquent saturated
+ * accumulation with Mac
+ *
+ * Parametrs:
+ * [in] Value1 First Operand
+ * [in] Value2 Second Operand
+ * [in] Mac Accumulator
+ *
+ * Return:
+ * [out] Result of operation
+ **/
+
+OMX_S32 armSatMac_S32(
+ OMX_S32 Mac,
+ OMX_S16 Value1,
+ OMX_S16 Value2
+ );
+
+/**
+ * Function :armSatMac_S16S32_S32
+ *
+ * Description :
+ * Returns the result of saturated MAC operation of the three inputs delayElem, filTap , mac
+ *
+ * mac = mac + Saturate_in_32Bits(delayElem * filTap)
+ *
+ * Parametrs:
+ * [in] delayElem First 32 bit Operand
+ * [in] filTap Second 16 bit Operand
+ * [in] mac Result of MAC operation
+ *
+ * Return:
+ * [out] mac Result of operation
+ *
+ **/
+
+OMX_S32 armSatMac_S16S32_S32(
+ OMX_S32 mac,
+ OMX_S32 delayElem,
+ OMX_S16 filTap );
+
+/**
+ * Function :armSatRoundRightShift_S32_S16
+ *
+ * Description :
+ * Returns the result of rounded right shift operation of input by the scalefactor
+ *
+ * output = Saturate_in_16Bits( ( RightShift( (Round(input) , scaleFactor ) )
+ *
+ * Parametrs:
+ * [in] input The input to be operated on
+ * [in] scaleFactor The shift number
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ **/
+
+
+OMX_S16 armSatRoundRightShift_S32_S16(
+ OMX_S32 input,
+ OMX_INT scaleFactor);
+
+/**
+ * Function :armSatRoundLeftShift_S32()
+ *
+ * Description :
+ * Returns the result of saturating left-shift operation on input
+ * Or rounded Right shift if the input Shift is negative.
+ *
+ * Parametrs:
+ * [in] Value Operand
+ * [in] shift Operand for shift operation
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ **/
+
+OMX_S32 armSatRoundLeftShift_S32(
+ OMX_S32 Value,
+ OMX_INT shift
+ );
+
+/**
+ * Function :armSatRoundLeftShift_S64()
+ *
+ * Description :
+ * Returns the result of saturating left-shift operation on input
+ * Or rounded Right shift if the input Shift is negative.
+ *
+ * Parametrs:
+ * [in] Value Operand
+ * [in] shift Operand for shift operation
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ **/
+
+OMX_S64 armSatRoundLeftShift_S64(
+ OMX_S64 Value,
+ OMX_INT shift
+ );
+
+/**
+ * Function :armSatMulS16S32_S32()
+ *
+ * Description :
+ * Returns the result of a S16 data type multiplied with an S32 data type
+ * in a S32 container
+ *
+ * Parametrs:
+ * [in] input1 Operand 1
+ * [in] input2 Operand 2
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ **/
+
+
+OMX_S32 armSatMulS16S32_S32(
+ OMX_S16 input1,
+ OMX_S32 input2);
+
+/**
+ * Function :armSatMulS32S32_S32()
+ *
+ * Description :
+ * Returns the result of a S32 data type multiplied with an S32 data type
+ * in a S32 container
+ *
+ * Parametrs:
+ * [in] input1 Operand 1
+ * [in] input2 Operand 2
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ **/
+
+OMX_S32 armSatMulS32S32_S32(
+ OMX_S32 input1,
+ OMX_S32 input2);
+
+
+/**
+ * Function :armIntDivAwayFromZero()
+ *
+ * Description : Integer division with rounding to the nearest integer.
+ * Half-integer values are rounded away from zero
+ * unless otherwise specified. For example 3//2 is rounded
+ * to 2, and -3//2 is rounded to -2.
+ *
+ * Parametrs:
+ * [in] Num Operand 1
+ * [in] Deno Operand 2
+ *
+ * Return:
+ * [out] Result of operation input1//input2
+ *
+ **/
+
+OMX_S32 armIntDivAwayFromZero (OMX_S32 Num, OMX_S32 Deno);
+
+
+/***********************************************************************/
+/*
+ * Debugging macros
+ *
+ */
+
+
+/*
+ * Definition of output stream - change to stderr if necessary
+ */
+#define DEBUG_STREAM stdout
+
+/*
+ * Debug printf macros, one for each argument count.
+ * Add more if needed.
+ */
+#ifdef DEBUG_ON
+#include <stdio.h>
+
+#define DEBUG_PRINTF_0(a) fprintf(DEBUG_STREAM, a)
+#define DEBUG_PRINTF_1(a, b) fprintf(DEBUG_STREAM, a, b)
+#define DEBUG_PRINTF_2(a, b, c) fprintf(DEBUG_STREAM, a, b, c)
+#define DEBUG_PRINTF_3(a, b, c, d) fprintf(DEBUG_STREAM, a, b, c, d)
+#define DEBUG_PRINTF_4(a, b, c, d, e) fprintf(DEBUG_STREAM, a, b, c, d, e)
+#define DEBUG_PRINTF_5(a, b, c, d, e, f) fprintf(DEBUG_STREAM, a, b, c, d, e, f)
+#define DEBUG_PRINTF_6(a, b, c, d, e, f, g) fprintf(DEBUG_STREAM, a, b, c, d, e, f, g)
+#define DEBUG_PRINTF_7(a, b, c, d, e, f, g, h) fprintf(DEBUG_STREAM, a, b, c, d, e, f, g, h)
+#define DEBUG_PRINTF_8(a, b, c, d, e, f, g, h, i) fprintf(DEBUG_STREAM, a, b, c, d, e, f, g, h, i)
+#define DEBUG_PRINTF_9(a, b, c, d, e, f, g, h, i, j) fprintf(DEBUG_STREAM, a, b, c, d, e, f, g, h, i, j)
+#define DEBUG_PRINTF_10(a, b, c, d, e, f, g, h, i, j, k) fprintf(DEBUG_STREAM, a, b, c, d, e, f, g, h, i, j, k)
+#define DEBUG_PRINTF_11(a, b, c, d, e, f, g, h, i, j, k, l) fprintf(DEBUG_STREAM, a, b, c, d, e, f, g, h, i, j, k, l)
+#define DEBUG_PRINTF_12(a, b, c, d, e, f, g, h, i, j, k, l, m) fprintf(DEBUG_STREAM, a, b, c, d, e, f, g, h, i, j, k, l, m)
+#define DEBUG_PRINTF_13(a, b, c, d, e, f, g, h, i, j, k, l, m, n) fprintf(DEBUG_STREAM, a, b, c, d, e, f, g, h, i, j, k, l, m, n)
+#define DEBUG_PRINTF_14(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) fprintf(DEBUG_STREAM, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)
+#else /* DEBUG_ON */
+#define DEBUG_PRINTF_0(a)
+#define DEBUG_PRINTF_1(a, b)
+#define DEBUG_PRINTF_2(a, b, c)
+#define DEBUG_PRINTF_3(a, b, c, d)
+#define DEBUG_PRINTF_4(a, b, c, d, e)
+#define DEBUG_PRINTF_5(a, b, c, d, e, f)
+#define DEBUG_PRINTF_6(a, b, c, d, e, f, g)
+#define DEBUG_PRINTF_7(a, b, c, d, e, f, g, h)
+#define DEBUG_PRINTF_8(a, b, c, d, e, f, g, h, i)
+#define DEBUG_PRINTF_9(a, b, c, d, e, f, g, h, i, j)
+#define DEBUG_PRINTF_10(a, b, c, d, e, f, g, h, i, j, k)
+#define DEBUG_PRINTF_11(a, b, c, d, e, f, g, h, i, j, k, l)
+#define DEBUG_PRINTF_12(a, b, c, d, e, f, g, h, i, j, k, l, m)
+#define DEBUG_PRINTF_13(a, b, c, d, e, f, g, h, i, j, k, l, m, n)
+#define DEBUG_PRINTF_14(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)
+#endif /* DEBUG_ON */
+
+
+/*
+ * Domain and sub domain definitions
+ *
+ * In order to turn on debug for an entire domain or sub-domain
+ * at compile time, one of the DEBUG_DOMAIN_* below may be defined,
+ * which will activate debug in all of the defines it contains.
+ */
+
+#ifdef DEBUG_DOMAIN_AC
+#define DEBUG_OMXACAAC_DECODECHANPAIRELT_MPEG4
+#define DEBUG_OMXACAAC_DECODECHANPAIRELT
+#define DEBUG_OMXACAAC_DECODEDATSTRELT
+#define DEBUG_OMXACAAC_DECODEFILLELT
+#define DEBUG_OMXACAAC_DECODEISSTEREO_S32
+#define DEBUG_OMXACAAC_DECODEMSPNS_S32
+#define DEBUG_OMXACAAC_DECODEMSSTEREO_S32_I
+#define DEBUG_OMXACAAC_DECODEPRGCFGELT
+#define DEBUG_OMXACAAC_DECODETNS_S32_I
+#define DEBUG_OMXACAAC_DEINTERLEAVESPECTRUM_S32
+#define DEBUG_OMXACAAC_ENCODETNS_S32_I
+#define DEBUG_OMXACAAC_LONGTERMPREDICT_S32
+#define DEBUG_OMXACAAC_LONGTERMRECONSTRUCT_S32
+#define DEBUG_OMXACAAC_MDCTFWD_S32
+#define DEBUG_OMXACAAC_MDCTINV_S32_S16
+#define DEBUG_OMXACAAC_NOISELESSDECODE
+#define DEBUG_OMXACAAC_QUANTINV_S32_I
+#define DEBUG_OMXACAAC_UNPACKADIFHEADER
+#define DEBUG_OMXACAAC_UNPACKADTSFRAMEHEADER
+#define DEBUG_OMXACMP3_HUFFMANDECODESFBMBP_S32
+#define DEBUG_OMXACMP3_HUFFMANDECODESFB_S32
+#define DEBUG_OMXACMP3_HUFFMANDECODE_S32
+#define DEBUG_OMXACMP3_MDCTINV_S32
+#define DEBUG_OMXACMP3_REQUANTIZESFB_S32_I
+#define DEBUG_OMXACMP3_REQUANTIZE_S32_I
+#define DEBUG_OMXACMP3_SYNTHPQMF_S32_S16
+#define DEBUG_OMXACMP3_UNPACKFRAMEHEADER
+#define DEBUG_OMXACMP3_UNPACKSCALEFACTORS_S8
+#define DEBUG_OMXACMP3_UNPACKSIDEINFO
+#endif /* DEBUG_DOMAIN_AC */
+
+
+#ifdef DEBUG_DOMAIN_VC
+#define DEBUG_OMXVCM4P10_AVERAGE_16X
+#define DEBUG_OMXVCM4P10_AVERAGE_4X
+#define DEBUG_OMXVCM4P10_AVERAGE_8X
+#define DEBUG_OMXVCM4P10_DEBLOCKCHROMA_U8_C1IR
+#define DEBUG_OMXVCM4P10_DEBLOCKLUMA_U8_C1IR
+#define DEBUG_OMXVCM4P10_DECODECHROMADCCOEFFSTOPAIRCAVLC_U8
+#define DEBUG_OMXVCM4P10_DECODECOEFFSTOPAIRCAVLC_U8
+#define DEBUG_OMXVCM4P10_DEQUANTTRANSFORMACFROMPAIR_U8_S16_C1_DLX
+#define DEBUG_OMXVCM4P10_EXPANDFRAME
+#define DEBUG_OMXVCM4P10_FILTERDEBLOCKINGCHROMA_HOREDGE_U8_C1IR
+#define DEBUG_OMXVCM4P10_FILTERDEBLOCKINGCHROMA_VEREDGE_U8_C1IR
+#define DEBUG_OMXVCM4P10_FILTERDEBLOCKINGLUMA_HOREDGE_U8_C1IR
+#define DEBUG_OMXVCM4P10_FILTERDEBLOCKINGLUMA_VEREDGE_U8_C1IR
+#define DEBUG_OMXVCM4P10_PREDICTINTRACHROMA8X8_U8_C1R
+#define DEBUG_OMXVCM4P10_PREDICTINTRA_16X16_U8_C1R
+#define DEBUG_OMXVCM4P10_PREDICTINTRA_4X4_U8_C1R
+#define DEBUG_OMXVCM4P10_SADQUAR_16X
+#define DEBUG_OMXVCM4P10_SADQUAR_4X
+#define DEBUG_OMXVCM4P10_SADQUAR_8X
+#define DEBUG_OMXVCM4P10_SAD_16X
+#define DEBUG_OMXVCM4P10_SAD_4X
+#define DEBUG_OMXVCM4P10_SAD_8X
+#define DEBUG_OMXVCM4P10_SATD_4X4
+#define DEBUG_OMXVCM4P10_TRANSFORMDEQUANTCHROMADCFROMPAIR_U8_S16_C1
+#define DEBUG_OMXVCM4P10_TRANSFORMDEQUANTLUMADCFROMPAIR_U8_S16_C1
+#define DEBUG_OMXVCM4P10_TRANSFORMQUANT_CHROMADC
+#define DEBUG_OMXVCM4P10_TRANSFORMQUANT_LUMADC
+#define DEBUG_OMXVCM4P2_BLOCKMATCH_HALF_16X16
+#define DEBUG_OMXVCM4P2_BLOCKMATCH_HALF_8X8
+#define DEBUG_OMXVCM4P2_BLOCKMATCH_INTEGER_16X16
+#define DEBUG_OMXVCM4P2_BLOCKMATCH_INTEGER_8X8
+#define DEBUG_OMXVCM4P2_COMPUTETEXTUREERRORBLOCK_SAD_U8_S16
+#define DEBUG_OMXVCM4P2_COMPUTETEXTUREERRORBLOCK_U8_S16
+#define DEBUG_OMXVCM4P2_DCT8X8BLKDLX
+#define DEBUG_OMXVCM4P2_DECODEBLOCKCOEF_INTER_S16
+#define DEBUG_OMXVCM4P2_DECODEPADMV_PVOP
+#define DEBUG_OMXVCM4P2_DECODEVLCZIGZAG_INTER_S16
+#define DEBUG_OMXVCM4P2_DECODEVLCZIGZAG_INTRAACVLC_S16
+#define DEBUG_OMXVCM4P2_DECODEVLCZIGZAG_INTRADCVLC_S16
+#define DEBUG_OMXVCM4P2_ENCODEMV_U8_S16
+#define DEBUG_OMXVCM4P2_ENCODEVLCZIGZAG_INTER_S16
+#define DEBUG_OMXVCM4P2_ENCODEVLCZIGZAG_INTRAACVLC_S16
+#define DEBUG_OMXVCM4P2_ENCODEVLCZIGZAG_INTRADCVLC_S16
+#define DEBUG_OMXVCM4P2_FINDMVPRED
+#define DEBUG_OMXVCM4P2_IDCT8X8BLKDLX
+#define DEBUG_OMXVCM4P2_LIMITMVTORECT
+#define DEBUG_OMXVCM4P2_MOTIONESTIMATIONMB
+#define DEBUG_OMXVCM4P2_PADMBGRAY_U8
+#define DEBUG_OMXVCM4P2_PADMBHORIZONTAL_U8
+#define DEBUG_OMXVCM4P2_PADMBVERTICAL_U8
+#define DEBUG_OMXVCM4P2_PADMV
+#define DEBUG_OMXVCM4P2_QUANTINTER_S16_I
+#define DEBUG_OMXVCM4P2_QUANTINTRA_S16_I
+#define DEBUG_OMXVCM4P2_QUANTINVINTER_S16_I
+#define DEBUG_OMXVCM4P2_QUANTINVINTRA_S16_I
+#define DEBUG_OMXVCM4P2_TRANSRECBLOCKCEOF_INTER
+#define DEBUG_OMXVCM4P2_TRANSRECBLOCKCEOF_INTRA
+#endif /* DEBUG_DOMAIN_VC */
+
+
+#ifdef DEBUG_DOMAIN_IC
+/* To be filled in */
+#endif /* DEBUG_DOMAIN_IC */
+
+
+#ifdef DEBUG_DOMAIN_SP
+#define DEBUG_OMXACSP_DOTPROD_S16
+#define DEBUG_OMXACSP_BLOCKEXP_S16
+#define DEBUG_OMXACSP_BLOCKEXP_S32
+#define DEBUG_OMXACSP_COPY_S16
+#define DEBUG_OMXACSP_DOTPROD_S16
+#define DEBUG_OMXACSP_DOTPROD_S16_SFS
+#define DEBUG_OMXACSP_FFTFWD_CTOC_SC16_SFS
+#define DEBUG_OMXACSP_FFTFWD_CTOC_SC32_SFS
+#define DEBUG_OMXACSP_FFTFWD_RTOCCS_S16S32_SFS
+#define DEBUG_OMXACSP_FFTFWD_RTOCCS_S32_SFS
+#define DEBUG_OMXACSP_FFTGETBUFSIZE_C_SC16
+#define DEBUG_OMXACSP_FFTGETBUFSIZE_C_SC32
+#define DEBUG_OMXACSP_FFTGETBUFSIZE_R_S16_S32
+#define DEBUG_OMXACSP_FFTGETBUFSIZE_R_S32
+#define DEBUG_OMXACSP_FFTINIT_C_SC16
+#define DEBUG_OMXACSP_FFTINIT_C_SC32
+#define DEBUG_OMXACSP_FFTINIT_R_S16_S32
+#define DEBUG_OMXACSP_FFTINIT_R_S32
+#define DEBUG_OMXACSP_FFTINV_CCSTOR_S32S16_SFS
+#define DEBUG_OMXACSP_FFTINV_CCSTOR_S32_SFS
+#define DEBUG_OMXACSP_FFTINV_CTOC_SC16_SFS
+#define DEBUG_OMXACSP_FFTINV_CTOC_SC32_SFS
+#define DEBUG_OMXACSP_FILTERMEDIAN_S32_I
+#define DEBUG_OMXACSP_FILTERMEDIAN_S32
+#define DEBUG_OMXACSP_FIRONE_DIRECT_S16_ISFS
+#define DEBUG_OMXACSP_FIRONE_DIRECT_S16_I
+#define DEBUG_OMXACSP_FIRONE_DIRECT_S16
+#define DEBUG_OMXACSP_FIRONE_DIRECT_S16_SFS
+#define DEBUG_OMXACSP_FIR_DIRECT_S16_ISFS
+#define DEBUG_OMXACSP_FIR_DIRECT_S16_I
+#define DEBUG_OMXACSP_FIR_DIRECT_S16
+#define DEBUG_OMXACSP_FIR_DIRECT_S16_SFS
+#define DEBUG_OMXACSP_IIRONE_BIQUADDIRECT_S16_I
+#define DEBUG_OMXACSP_IIRONE_BIQUADDIRECT_S16
+#define DEBUG_OMXACSP_IIRONE_DIRECT_S16_I
+#define DEBUG_OMXACSP_IIRONE_DIRECT_S16
+#define DEBUG_OMXACSP_IIR_BIQUADDIRECT_S16_I
+#define DEBUG_OMXACSP_IIR_BIQUADDIRECT_S16
+#define DEBUG_OMXACSP_IIR_DIRECT_S16_I
+#define DEBUG_OMXACSP_IIR_DIRECT_S16
+#endif /* DEBUG_DOMAIN_SP */
+
+
+#ifdef DEBUG_DOMAIN_IP
+#define DEBUG_OMXIPBM_ADDC_U8_C1R_SFS
+#define DEBUG_OMXIPBM_COPY_U8_C1R
+#define DEBUG_OMXIPBM_COPY_U8_C3R
+#define DEBUG_OMXIPBM_MIRROR_U8_C1R
+#define DEBUG_OMXIPBM_MULC_U8_C1R_SFS
+#define DEBUG_OMXIPCS_COLORTWISTQ14_U8_C3R
+#define DEBUG_OMXIPCS_RGB565TOYCBCR420LS_MCU_U16_S16_C3P3R
+#define DEBUG_OMXIPCS_RGB565TOYCBCR422LS_MCU_U16_S16_C3P3R
+#define DEBUG_OMXIPCS_RGB565TOYCBCR444LS_MCU_U16_S16_C3P3R
+#define DEBUG_OMXIPCS_RGBTOYCBCR420LS_MCU_U8_S16_C3P3R
+#define DEBUG_OMXIPCS_RGBTOYCBCR422LS_MCU_U8_S16_C3P3R
+#define DEBUG_OMXIPCS_RGBTOYCBCR444LS_MCU_U8_S16_C3P3R
+#define DEBUG_OMXIPCS_YCBCR420RSZROT_U8_P3R
+#define DEBUG_OMXIPCS_YCBCR420TORGB565LS_MCU_S16_U16_P3C3R
+#define DEBUG_OMXIPCS_YCBCR420TORGB565_U8_U16_P3C3R
+#define DEBUG_OMXIPCS_YCBCR420TORGBLS_MCU_S16_U8_P3C3R
+#define DEBUG_OMXIPCS_YCBCR422RSZCSCROTRGB_U8_C2R
+#define DEBUG_OMXIPCS_YCBCR422RSZROT_U8_P3R
+#define DEBUG_OMXIPCS_YCBCR422TORGB565LS_MCU_S16_U16_P3C3R
+#define DEBUG_OMXIPCS_YCBCR422TORGB565_U8_U16_C2C3R
+#define DEBUG_OMXIPCS_YCBCR422TORGBLS_MCU_S16_U8_P3C3R
+#define DEBUG_OMXIPCS_YCBCR422TORGB_U8_C2C3R
+#define DEBUG_OMXIPCS_YCBCR422TOYCBCR420ROTATE_U8_C2P3R
+#define DEBUG_OMXIPCS_YCBCR422TOYCBCR420ROTATE_U8_P3R
+#define DEBUG_OMXIPCS_YCBCR444TORGB565LS_MCU_S16_U16_P3C3R
+#define DEBUG_OMXIPCS_YCBCR444TORGBLS_MCU_S16_U8_P3C3R
+#define DEBUG_OMXIPCS_YCBCRTORGB565_U8_U16_C3R
+#define DEBUG_OMXIPCS_YCBCRTORGB565_U8_U16_P3C3R
+#define DEBUG_OMXIPCS_YCBCRTORGB_U8_C3R
+#define DEBUG_OMXIPPP_GETCENTRALMOMENT_S64
+#define DEBUG_OMXIPPP_GETSPATIALMOMENT_S64
+#define DEBUG_OMXIPPP_MOMENTGETSTATESIZE_S64
+#define DEBUG_OMXIPPP_MOMENTINIT_S64
+#define DEBUG_OMXIPPP_MOMENTS64S_U8_C1R
+#define DEBUG_OMXIPPP_MOMENTS64S_U8_C3R
+#endif /* DEBUG_DOMAIN_IP */
+
+
+#endif /* _armCommon_H_ */
+
+/*End of File*/
+
+
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_BitDec_s.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_BitDec_s.h
new file mode 100755
index 0000000..c738f72
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_BitDec_s.h
@@ -0,0 +1,670 @@
+;//
+;//
+;// File Name: armCOMM_BitDec_s.h
+;// OpenMAX DL: v1.0.2
+;// Revision: 12290
+;// Date: Wednesday, April 9, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+;// OpenMAX optimized bitstream decode module
+;//
+;// You must include armCOMM_s.h before including this file
+;//
+;// This module provides macros to perform assembly optimized fixed and
+;// variable length decoding from a read-only bitstream. The variable
+;// length decode modules take as input a pointer to a table of 16-bit
+;// entries of the following format.
+;//
+;// VLD Table Entry format
+;//
+;// 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
+;// +------------------------------------------------+
+;// | Len | Symbol | 1 |
+;// +------------------------------------------------+
+;// | Offset | 0 |
+;// +------------------------------------------------+
+;//
+;// If the table entry is a leaf entry then bit 0 set:
+;// Len = Number of bits overread (0 to 7)
+;// Symbol = Symbol payload (unsigned 12 bits)
+;//
+;// If the table entry is an internal node then bit 0 is clear:
+;// Offset = Number of (16-bit) half words from the table
+;// start to the next table node
+;//
+;// The table is accessed by successive lookup up on the
+;// next Step bits of the input bitstream until a leaf node
+;// is obtained. The Step sizes are supplied to the VLD macro.
+;//
+;// USAGE:
+;//
+;// To use any of the macros in this package, first call:
+;//
+;// M_BD_INIT ppBitStream, pBitOffset, pBitStream, RBitBuffer, RBitCount, Tmp
+;//
+;// This caches the current bitstream position and next available
+;// bits in registers pBitStream, RBitBuffer, RBitCount. These registers
+;// are reserved for use by the bitstream decode package until you
+;// call M_BD_FINI.
+;//
+;// Next call the following macro(s) as many times as you need:
+;//
+;// M_BD_LOOK8 - Look ahead constant 1<=N<=8 bits into the bitstream
+;// M_BD_LOOK16 - Look ahead constant 1<=N<=16 bits into the bitstream
+;// M_BD_READ8 - Read constant 1<=N<=8 bits from the bitstream
+;// M_BD_READ16 - Read constant 1<=N<=16 bits from the bitstream
+;// M_BD_VREAD8 - Read variable 1<=N<=8 bits from the bitstream
+;// M_BD_VREAD16 - Read variable 1<=N<=16 bits from the bitstream
+;// M_BD_VLD - Perform variable length decode using lookup table
+;//
+;// Finally call the macro:
+;//
+;// M_BD_FINI ppBitStream, pBitOffset
+;//
+;// This writes the bitstream state back to memory.
+;//
+;// The three bitstream cache register names are assigned to the following global
+;// variables:
+;//
+
+ GBLS pBitStream ;// Register name for pBitStream
+ GBLS BitBuffer ;// Register name for BitBuffer
+ GBLS BitCount ;// Register name for BitCount
+
+;//
+;// These register variables must have a certain defined state on entry to every bitstream
+;// macro (except M_BD_INIT) and on exit from every bitstream macro (except M_BD_FINI).
+;// The state may depend on implementation.
+;//
+;// For the default (ARM11) implementation the following hold:
+;// pBitStream - points to the first byte not held in the BitBuffer
+;// BitBuffer - is a cache of (4 bytes) 32 bits, bit 31 the first bit
+;// BitCount - is offset (from the top bit) to the next unused bitstream bit
+;// 0<=BitCount<=15 (so BitBuffer holds at least 17 unused bits)
+;//
+;//
+
+ ;// Bitstream Decode initialise
+ ;//
+ ;// Initialises the bitstream decode global registers from
+ ;// bitstream pointers. This macro is split into 3 parts to enable
+ ;// scheduling.
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// $ppBitStream - pointer to pointer to the next bitstream byte
+ ;// $pBitOffset - pointer to the number of bits used in the current byte (0..7)
+ ;// $RBitStream - register to use for pBitStream (can be $ppBitStream)
+ ;// $RBitBuffer - register to use for BitBuffer
+ ;// $RBitCount - register to use for BitCount (can be $pBitOffset)
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// $T1,$T2,$T3 - registers that must be preserved between calls to
+ ;// M_BD_INIT1 and M_BD_INIT2
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ MACRO
+ M_BD_INIT0 $ppBitStream, $pBitOffset, $RBitStream, $RBitBuffer, $RBitCount
+
+pBitStream SETS "$RBitStream"
+BitBuffer SETS "$RBitBuffer"
+BitCount SETS "$RBitCount"
+
+ ;// load inputs
+ LDR $pBitStream, [$ppBitStream]
+ LDR $BitCount, [$pBitOffset]
+ MEND
+
+ MACRO
+ M_BD_INIT1 $T1, $T2, $T3
+ LDRB $T2, [$pBitStream, #2]
+ LDRB $T1, [$pBitStream, #1]
+ LDRB $BitBuffer, [$pBitStream], #3
+ ADD $BitCount, $BitCount, #8
+ MEND
+
+ MACRO
+ M_BD_INIT2 $T1, $T2, $T3
+ ORR $T2, $T2, $T1, LSL #8
+ ORR $BitBuffer, $T2, $BitBuffer, LSL #16
+ MEND
+
+ ;//
+ ;// Look ahead fixed 1<=N<=8 bits without consuming any bits
+ ;// The next bits will be placed at bit 31..24 of destination register
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// $N - number of bits to look
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// $Symbol - the next N bits of the bitstream
+ ;// $T1 - corrupted temp/scratch register
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ MACRO
+ M_BD_LOOK8 $Symbol, $N
+ ASSERT ($N>=1):LAND:($N<=8)
+ MOV $Symbol, $BitBuffer, LSL $BitCount
+ MEND
+
+ ;//
+ ;// Look ahead fixed 1<=N<=16 bits without consuming any bits
+ ;// The next bits will be placed at bit 31..16 of destination register
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// $N - number of bits to look
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// $Symbol - the next N bits of the bitstream
+ ;// $T1 - corrupted temp/scratch register
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ MACRO
+ M_BD_LOOK16 $Symbol, $N, $T1
+ ASSERT ($N >= 1):LAND:($N <= 16)
+ MOV $Symbol, $BitBuffer, LSL $BitCount
+ MEND
+
+ ;//
+ ;// Skips fixed 1<=N<=8 bits from the bitstream, advancing the bitstream pointer
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// $N - number of bits
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// $T1 - corrupted temp/scratch register
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ MACRO
+ M_BD_SKIP8 $N, $T1
+ ASSERT ($N>=1):LAND:($N<=8)
+ SUBS $BitCount, $BitCount, #(8-$N)
+ LDRCSB $T1, [$pBitStream], #1
+ ADDCC $BitCount, $BitCount, #8
+ ORRCS $BitBuffer, $T1, $BitBuffer, LSL #8
+ MEND
+
+
+ ;//
+ ;// Read fixed 1<=N<=8 bits from the bitstream, advancing the bitstream pointer
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// $N - number of bits to read
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// $Symbol - the next N bits of the bitstream
+ ;// $T1 - corrupted temp/scratch register
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ MACRO
+ M_BD_READ8 $Symbol, $N, $T1
+ ASSERT ($N>=1):LAND:($N<=8)
+ MOVS $Symbol, $BitBuffer, LSL $BitCount
+ SUBS $BitCount, $BitCount, #(8-$N)
+ LDRCSB $T1, [$pBitStream], #1
+ ADDCC $BitCount, $BitCount, #8
+ MOV $Symbol, $Symbol, LSR #(32-$N)
+ ORRCS $BitBuffer, $T1, $BitBuffer, LSL #8
+ MEND
+
+ ;//
+ ;// Read fixed 1<=N<=16 bits from the bitstream, advancing the bitstream pointer
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// $N - number of bits to read
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// $Symbol - the next N bits of the bitstream
+ ;// $T1 - corrupted temp/scratch register
+ ;// $T2 - corrupted temp/scratch register
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ MACRO
+ M_BD_READ16 $Symbol, $N, $T1, $T2
+ ASSERT ($N>=1):LAND:($N<=16)
+ ASSERT $Symbol<>$T1
+ IF ($N<=8)
+ M_BD_READ8 $Symbol, $N, $T1
+ ELSE
+ ;// N>8 so we will be able to refill at least one byte
+ LDRB $T1, [$pBitStream], #1
+ MOVS $Symbol, $BitBuffer, LSL $BitCount
+ ORR $BitBuffer, $T1, $BitBuffer, LSL #8
+ SUBS $BitCount, $BitCount, #(16-$N)
+ LDRCSB $T1, [$pBitStream], #1
+ MOV $Symbol, $Symbol, LSR #(32-$N)
+ ADDCC $BitCount, $BitCount, #8
+ ORRCS $BitBuffer, $T1, $BitBuffer, LSL #8
+ ENDIF
+ MEND
+
+ ;//
+ ;// Skip variable 1<=N<=8 bits from the bitstream, advancing the bitstream pointer.
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// $N - number of bits. 1<=N<=8
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// $T1 - corrupted temp/scratch register
+ ;// $T2 - corrupted temp/scratch register
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ MACRO
+ M_BD_VSKIP8 $N, $T1
+ ADD $BitCount, $BitCount, $N
+ SUBS $BitCount, $BitCount, #8
+ LDRCSB $T1, [$pBitStream], #1
+ ADDCC $BitCount, $BitCount, #8
+ ORRCS $BitBuffer, $T1, $BitBuffer, LSL #8
+ MEND
+
+ ;//
+ ;// Skip variable 1<=N<=16 bits from the bitstream, advancing the bitstream pointer.
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// $N - number of bits. 1<=N<=16
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// $T1 - corrupted temp/scratch register
+ ;// $T2 - corrupted temp/scratch register
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ MACRO
+ M_BD_VSKIP16 $N, $T1, $T2
+ ADD $BitCount, $BitCount, $N
+ SUBS $BitCount, $BitCount, #8
+ LDRCSB $T1, [$pBitStream], #1
+ ORRCS $BitBuffer, $T1, $BitBuffer, LSL #8
+ SUBCSS $BitCount, $BitCount, #8
+ LDRCSB $T1, [$pBitStream], #1
+ ADDCC $BitCount, $BitCount, #8
+ ORRCS $BitBuffer, $T1, $BitBuffer, LSL #8
+ MEND
+
+ ;//
+ ;// Read variable 1<=N<=8 bits from the bitstream, advancing the bitstream pointer.
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// $N - number of bits to read. 1<=N<=8
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// $Symbol - the next N bits of the bitstream
+ ;// $T1 - corrupted temp/scratch register
+ ;// $T2 - corrupted temp/scratch register
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ MACRO
+ M_BD_VREAD8 $Symbol, $N, $T1, $T2
+ MOV $Symbol, $BitBuffer, LSL $BitCount
+ ADD $BitCount, $BitCount, $N
+ SUBS $BitCount, $BitCount, #8
+ LDRCSB $T1, [$pBitStream], #1
+ RSB $T2, $N, #32
+ ADDCC $BitCount, $BitCount, #8
+ MOV $Symbol, $Symbol, LSR $T2
+ ORRCS $BitBuffer, $T1, $BitBuffer, LSL #8
+ MEND
+
+
+ ;//
+ ;// Read variable 1<=N<=16 bits from the bitstream, advancing the bitstream pointer.
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// $N - number of bits to read. 1<=N<=16
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// $Symbol - the next N bits of the bitstream
+ ;// $T1 - corrupted temp/scratch register
+ ;// $T2 - corrupted temp/scratch register
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ MACRO
+ M_BD_VREAD16 $Symbol, $N, $T1, $T2
+ MOV $Symbol, $BitBuffer, LSL $BitCount
+ ADD $BitCount, $BitCount, $N
+ SUBS $BitCount, $BitCount, #8
+ LDRCSB $T1, [$pBitStream], #1
+ RSB $T2, $N, #32
+ ORRCS $BitBuffer, $T1, $BitBuffer, LSL #8
+ SUBCSS $BitCount, $BitCount, #8
+ LDRCSB $T1, [$pBitStream], #1
+ ADDCC $BitCount, $BitCount, #8
+ MOV $Symbol, $Symbol, LSR $T2
+ ORRCS $BitBuffer, $T1, $BitBuffer, LSL #8
+ MEND
+
+
+ ;//
+ ;// Decode a code of the form 0000...001 where there
+ ;// are N zeros before the 1 and N<=15 (code length<=16)
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// $Symbol - the number of zeros before the next 1
+ ;// >=16 is an illegal code
+ ;// $T1 - corrupted temp/scratch register
+ ;// $T2 - corrupted temp/scratch register
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ MACRO
+ M_BD_CLZ16 $Symbol, $T1, $T2
+ MOVS $Symbol, $BitBuffer, LSL $BitCount
+ CLZ $Symbol, $Symbol
+ ADD $BitCount, $BitCount, $Symbol
+ SUBS $BitCount, $BitCount, #7 ;// length is Symbol+1
+ LDRCSB $T1, [$pBitStream], #1
+ ORRCS $BitBuffer, $T1, $BitBuffer, LSL #8
+ SUBCSS $BitCount, $BitCount, #8
+ LDRCSB $T1, [$pBitStream], #1
+ ADDCC $BitCount, $BitCount, #8
+ ORRCS $BitBuffer, $T1, $BitBuffer, LSL #8
+ MEND
+
+ ;//
+ ;// Decode a code of the form 1111...110 where there
+ ;// are N ones before the 0 and N<=15 (code length<=16)
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// $Symbol - the number of zeros before the next 1
+ ;// >=16 is an illegal code
+ ;// $T1 - corrupted temp/scratch register
+ ;// $T2 - corrupted temp/scratch register
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ MACRO
+ M_BD_CLO16 $Symbol, $T1, $T2
+ MOV $Symbol, $BitBuffer, LSL $BitCount
+ MVN $Symbol, $Symbol
+ CLZ $Symbol, $Symbol
+ ADD $BitCount, $BitCount, $Symbol
+ SUBS $BitCount, $BitCount, #7 ;// length is Symbol+1
+ LDRCSB $T1, [$pBitStream], #1
+ ORRCS $BitBuffer, $T1, $BitBuffer, LSL #8
+ SUBCSS $BitCount, $BitCount, #8
+ LDRCSB $T1, [$pBitStream], #1
+ ADDCC $BitCount, $BitCount, #8
+ ORRCS $BitBuffer, $T1, $BitBuffer, LSL #8
+ MEND
+
+
+ ;//
+ ;// Variable Length Decode module
+ ;//
+ ;// Decodes one VLD Symbol from a bitstream and refill the bitstream
+ ;// buffer.
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// $pVLDTable - pointer to VLD decode table of 16-bit entries.
+ ;// The format is described above at the start of
+ ;// this file.
+ ;// $S0 - The number of bits to look up for the first step
+ ;// 1<=$S0<=8
+ ;// $S1 - The number of bits to look up for each subsequent
+ ;// step 1<=$S1<=$S0.
+ ;//
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// $Symbol - decoded VLD symbol value
+ ;// $T1 - corrupted temp/scratch register
+ ;// $T2 - corrupted temp/scratch register
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ MACRO
+ M_BD_VLD $Symbol, $T1, $T2, $pVLDTable, $S0, $S1
+ ASSERT (1<=$S0):LAND:($S0<=8)
+ ASSERT (1<=$S1):LAND:($S1<=$S0)
+
+ ;// Note 0<=BitCount<=15 on entry and exit
+
+ MOVS $T1, $BitBuffer, LSL $BitCount ;// left align next bits
+ MOVS $Symbol, #(2<<$S0)-2 ;// create mask
+ AND $Symbol, $Symbol, $T1, LSR #(31-$S0) ;// 2*(next $S0 bits)
+ SUBS $BitCount, $BitCount, #8 ;// CS if buffer can be filled
+01
+ LDRCSB $T1, [$pBitStream], #1 ;// load refill byte
+ LDRH $Symbol, [$pVLDTable, $Symbol] ;// load table entry
+ ADDCC $BitCount, $BitCount, #8 ;// refill not possible
+ ADD $BitCount, $BitCount, #$S0 ;// assume $S0 bits used
+ ORRCS $BitBuffer, $T1, $BitBuffer, LSL #8 ;// merge in refill byte
+ MOVS $T1, $Symbol, LSR #1 ;// CS=leaf entry
+ BCS %FT02
+
+ MOVS $T1, $BitBuffer, LSL $BitCount ;// left align next bit
+ IF (2*$S0-$S1<=8)
+ ;// Can combine refill check and -S0+S1 and keep $BitCount<=15
+ SUBS $BitCount, $BitCount, #8+($S0-$S1)
+ ELSE
+ ;// Separate refill check and -S0+S1 offset
+ SUBS $BitCount, $BitCount, #8
+ SUB $BitCount, $BitCount, #($S0-$S1)
+ ENDIF
+ ADD $Symbol, $Symbol, $T1, LSR #(31-$S1) ;// add 2*(next $S1 bits) to
+ BIC $Symbol, $Symbol, #1 ;// table offset
+ B %BT01 ;// load next table entry
+02
+ ;// BitCount range now depend on the route here
+ ;// if (first step) S0 <= BitCount <= 7+S0 <=15
+ ;// else if (2*S0-S1<=8) S0 <= BitCount <= 7+(2*S0-S1) <=15
+ ;// else S1 <= BitCount <= 7+S1 <=15
+
+ SUB $BitCount, $BitCount, $Symbol, LSR#13
+ BIC $Symbol, $T1, #0xF000
+ MEND
+
+
+ ;// Add an offset number of bits
+ ;//
+ ;// Outputs destination byte and bit index values which corresponds to an offset number of bits
+ ;// from the current location. This is used to compare bitstream positions using. M_BD_CMP.
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// $Offset - Offset to be added in bits.
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// $ByteIndex - Destination pBitStream pointer after adding the Offset.
+ ;// This value will be 4 byte ahead and needs to subtract by 4 to get exact
+ ;// pointer (as in M_BD_FINI). But for using with M_BD_CMP subtract is not needed.
+ ;// $BitIndex - Destination BitCount after the addition of Offset number of bits
+ ;//
+ MACRO
+ M_BD_ADD $ByteIndex, $BitIndex, $Offset
+
+ ;// ($ByteIndex,$BitIndex) = Current position + $Offset bits
+ ADD $Offset, $Offset, $BitCount
+ AND $BitIndex, $Offset, #7
+ ADD $ByteIndex, $pBitStream, $Offset, ASR #3
+ MEND
+
+ ;// Move bitstream pointers to the location given
+ ;//
+ ;// Outputs destination byte and bit index values which corresponds to
+ ;// the current location given (calculated using M_BD_ADD).
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;// $ByteIndex - Destination pBitStream pointer after move.
+ ;// This value will be 4 byte ahead and needs to subtract by 4 to get exact
+ ;// pointer (as in M_BD_FINI).
+ ;// $BitIndex - Destination BitCount after the move
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// $pBitStream \
+ ;// } See description above.
+ ;// $BitCount /
+ ;//
+ MACRO
+ M_BD_MOV $ByteIndex, $BitIndex
+
+ ;// ($pBitStream, $Offset) = ($ByteIndex,$BitIndex)
+ MOV $BitCount, $BitIndex
+ MOV $pBitStream, $ByteIndex
+ MEND
+
+ ;// Bitstream Compare
+ ;//
+ ;// Compares bitstream position with that of a destination position. Destination position
+ ;// is held in two input registers which are calculated using M_BD_ADD macro
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// $ByteIndex - Destination pBitStream pointer, (4 byte ahead as described in M_BD_ADD)
+ ;// $BitIndex - Destination BitCount
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// FLAGS - GE if destination is reached, LT = is destination is ahead
+ ;// $T1 - corrupted temp/scratch register
+ ;//
+ MACRO
+ M_BD_CMP $ByteIndex, $BitIndex, $T1
+
+ ;// Return flags set by (current positon)-($ByteIndex,$BitIndex)
+ ;// so GE means that we have reached the indicated position
+
+ ADD $T1, $pBitStream, $BitCount, LSR #3
+ CMP $T1, $ByteIndex
+ AND $T1, $BitCount, #7
+ CMPEQ $T1, $BitIndex
+ MEND
+
+
+ ;// Bitstream Decode finalise
+ ;//
+ ;// Writes back the bitstream state to the bitstream pointers
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// $pBitStream \
+ ;// $BitBuffer } See description above.
+ ;// $BitCount /
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// $ppBitStream - pointer to pointer to the next bitstream byte
+ ;// $pBitOffset - pointer to the number of bits used in the current byte (0..7)
+ ;// $pBitStream \
+ ;// $BitBuffer } these register are corrupted
+ ;// $BitCount /
+ ;//
+ MACRO
+ M_BD_FINI $ppBitStream, $pBitOffset
+
+ ;// Advance pointer by the number of free bits in the buffer
+ ADD $pBitStream, $pBitStream, $BitCount, LSR#3
+ AND $BitCount, $BitCount, #7
+
+ ;// Now move back 32 bits to reach the first usued bit
+ SUB $pBitStream, $pBitStream, #4
+
+ ;// Store out bitstream state
+ STR $BitCount, [$pBitOffset]
+ STR $pBitStream, [$ppBitStream]
+ MEND
+
+ END
+
\ No newline at end of file
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_Bitstream.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_Bitstream.h
new file mode 100755
index 0000000..b699034
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_Bitstream.h
@@ -0,0 +1,212 @@
+/**
+ *
+ * File Name: armCOMM_Bitstream.h
+ * OpenMAX DL: v1.0.2
+ * Revision: 12290
+ * Date: Wednesday, April 9, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * File: armCOMM_Bitstream.h
+ * Brief: Declares common API's/Data types used across the OpenMax Encoders/Decoders.
+ *
+ */
+
+#ifndef _armCodec_H_
+#define _armCodec_H_
+
+#include "omxtypes.h"
+
+typedef struct {
+ OMX_U8 codeLen;
+ OMX_U32 codeWord;
+} ARM_VLC32;
+
+/* The above should be renamed as "ARM_VLC32" */
+
+/**
+ * Function: armLookAheadBits()
+ *
+ * Description:
+ * Get the next N bits from the bitstream without advancing the bitstream pointer
+ *
+ * Parameters:
+ * [in] **ppBitStream
+ * [in] *pOffset
+ * [in] N=1...32
+ *
+ * Returns Value
+ */
+
+OMX_U32 armLookAheadBits(const OMX_U8 **ppBitStream, OMX_INT *pOffset, OMX_INT N);
+
+/**
+ * Function: armGetBits()
+ *
+ * Description:
+ * Read N bits from the bitstream
+ *
+ * Parameters:
+ * [in] *ppBitStream
+ * [in] *pOffset
+ * [in] N=1..32
+ *
+ * [out] *ppBitStream
+ * [out] *pOffset
+ * Returns Value
+ */
+
+OMX_U32 armGetBits(const OMX_U8 **ppBitStream, OMX_INT *pOffset, OMX_INT N);
+
+/**
+ * Function: armByteAlign()
+ *
+ * Description:
+ * Align the pointer *ppBitStream to the next byte boundary
+ *
+ * Parameters:
+ * [in] *ppBitStream
+ * [in] *pOffset
+ *
+ * [out] *ppBitStream
+ * [out] *pOffset
+ *
+ **/
+
+OMXVoid armByteAlign(const OMX_U8 **ppBitStream,OMX_INT *pOffset);
+
+/**
+ * Function: armSkipBits()
+ *
+ * Description:
+ * Skip N bits from the value at *ppBitStream
+ *
+ * Parameters:
+ * [in] *ppBitStream
+ * [in] *pOffset
+ * [in] N
+ *
+ * [out] *ppBitStream
+ * [out] *pOffset
+ *
+ **/
+
+OMXVoid armSkipBits(const OMX_U8 **ppBitStream,OMX_INT *pOffset,OMX_INT N);
+
+/***************************************
+ * Variable bit length Decode
+ ***************************************/
+
+/**
+ * Function: armUnPackVLC32()
+ *
+ * Description:
+ * Variable length decode of variable length symbol (max size 32 bits) read from
+ * the bit stream pointed by *ppBitStream at *pOffset by using the table
+ * pointed by pCodeBook
+ *
+ * Parameters:
+ * [in] **ppBitStream
+ * [in] *pOffset
+ * [in] pCodeBook
+ *
+ * [out] **ppBitStream
+ * [out] *pOffset
+ *
+ * Returns : Code Book Index if successfull.
+ * : "ARM_NO_CODEBOOK_INDEX = 0xFFFF" if search fails.
+ **/
+
+#define ARM_NO_CODEBOOK_INDEX (OMX_U16)(0xFFFF)
+
+OMX_U16 armUnPackVLC32(
+ const OMX_U8 **ppBitStream,
+ OMX_INT *pOffset,
+ const ARM_VLC32 *pCodeBook
+);
+
+/***************************************
+ * Fixed bit length Encode
+ ***************************************/
+
+/**
+ * Function: armPackBits
+ *
+ * Description:
+ * Pack a VLC code word into the bitstream
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream pointer to the pointer to the current byte
+ * in the bit stream.
+ * [in] pOffset pointer to the bit position in the byte
+ * pointed by *ppBitStream. Valid within 0
+ * to 7.
+ * [in] codeWord Code word that need to be inserted in to the
+ * bitstream
+ * [in] codeLength Length of the code word valid range 1...32
+ *
+ * [out] ppBitStream *ppBitStream is updated after the block is encoded,
+ * so that it points to the current byte in the bit
+ * stream buffer.
+ * [out] pBitOffset *pBitOffset is updated so that it points to the
+ * current bit position in the byte pointed by
+ * *ppBitStream.
+ *
+ * Return Value:
+ * Standard OMX_RESULT result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armPackBits (
+ OMX_U8 **ppBitStream,
+ OMX_INT *pOffset,
+ OMX_U32 codeWord,
+ OMX_INT codeLength
+);
+
+/***************************************
+ * Variable bit length Encode
+ ***************************************/
+
+/**
+ * Function: armPackVLC32
+ *
+ * Description:
+ * Pack a VLC code word into the bitstream
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream pointer to the pointer to the current byte
+ * in the bit stream.
+ * [in] pBitOffset pointer to the bit position in the byte
+ * pointed by *ppBitStream. Valid within 0
+ * to 7.
+ * [in] code VLC code word that need to be inserted in to the
+ * bitstream
+ *
+ * [out] ppBitStream *ppBitStream is updated after the block is encoded,
+ * so that it points to the current byte in the bit
+ * stream buffer.
+ * [out] pBitOffset *pBitOffset is updated so that it points to the
+ * current bit position in the byte pointed by
+ * *ppBitStream.
+ *
+ * Return Value:
+ * Standard OMX_RESULT result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armPackVLC32 (
+ OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ ARM_VLC32 code
+);
+
+#endif /*_armCodec_H_*/
+
+/*End of File*/
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_IDCTTable.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_IDCTTable.h
new file mode 100755
index 0000000..e0cfdaa
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_IDCTTable.h
@@ -0,0 +1,40 @@
+/**
+ *
+ *
+ * File Name: armCOMM_IDCTTable.h
+ * OpenMAX DL: v1.0.2
+ * Revision: 12290
+ * Date: Wednesday, April 9, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * File : armCOMM_IDCTTable.h
+ * Description : Contains declarations of tables for IDCT calculation.
+ *
+ */
+
+#ifndef _armCOMM_IDCTTable_H_
+#define _armCOMM_IDCTTable_H_
+
+#include "omxtypes.h"
+
+ /* Table of s(u)*A(u)*A(v)/16 at Q15
+ * s(u)=1.0 0 <= u <= 5
+ * s(6)=2.0
+ * s(7)=4.0
+ * A(0) = 2*sqrt(2)
+ * A(u) = 4*cos(u*pi/16) for (u!=0)
+ */
+extern const OMX_U16 armCOMM_IDCTPreScale [64];
+extern const OMX_U16 armCOMM_IDCTCoef [4];
+
+#endif /* _armCOMM_IDCTTable_H_ */
+
+
+/* End of File */
+
+
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_IDCT_s.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_IDCT_s.h
new file mode 100755
index 0000000..0baa087
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_IDCT_s.h
@@ -0,0 +1,1451 @@
+;//
+;// This confidential and proprietary software may be used only as
+;// authorised by a licensing agreement from ARM Limited
+;// (C) COPYRIGHT 2004 ARM Limited
+;// ALL RIGHTS RESERVED
+;// The entire notice above must be reproduced on all authorised
+;// copies and copies may only be made to the extent permitted
+;// by a licensing agreement from ARM Limited.
+;//
+;// IDCT_s.s
+;//
+;// Inverse DCT module
+;//
+;//
+;// ALGORITHM DESCRIPTION
+;//
+;// The 8x8 2D IDCT is performed by calculating a 1D IDCT for each
+;// column and then a 1D IDCT for each row.
+;//
+;// The 8-point 1D IDCT is defined by
+;// f(x) = (C(0)*T(0)*c(0,x) + ... + C(7)*T(7)*c(7,x))/2
+;//
+;// C(u) = 1/sqrt(2) if u=0 or 1 if u!=0
+;// c(u,x) = cos( (2x+1)*u*pi/16 )
+;//
+;// We compute the 8-point 1D IDCT using the reverse of
+;// the Arai-Agui-Nakajima flow graph which we split into
+;// 5 stages named in reverse order to identify with the
+;// forward DCT. Direct inversion of the forward formulae
+;// in file FDCT_s.s gives:
+;//
+;// IStage 5: j(u) = T(u)*A(u) [ A(u)=4*C(u)*c(u,0) ]
+;// [ A(0) = 2*sqrt(2)
+;// A(u) = 4*cos(u*pi/16) for (u!=0) ]
+;//
+;// IStage 4: i0 = j0 i1 = j4
+;// i3 = (j2+j6)/2 i2 = (j2-j6)/2
+;// i7 = (j5+j3)/2 i4 = (j5-j3)/2
+;// i5 = (j1+j7)/2 i6 = (j1-j7)/2
+;//
+;// IStage 3: h0 = (i0+i1)/2 h1 = (i0-i1)/2
+;// h2 = (i2*sqrt2)-i3 h3 = i3
+;// h4 = cos(pi/8)*i4 + sin(pi/8)*i6
+;// h6 = -sin(pi/8)*i4 + cos(pi/8)*i6
+;// [ The above two lines rotate by -(pi/8) ]
+;// h5 = (i5-i7)/sqrt2 h7 = (i5+i7)/2
+;//
+;// IStage 2: g0 = (h0+h3)/2 g3 = (h0-h3)/2
+;// g1 = (h1+h2)/2 g2 = (h1-h2)/2
+;// g7 = h7 g6 = h6 - h7
+;// g5 = h5 - g6 g4 = h4 - g5
+;//
+;// IStage 1: f0 = (g0+g7)/2 f7 = (g0-g7)/2
+;// f1 = (g1+g6)/2 f6 = (g1-g6)/2
+;// f2 = (g2+g5)/2 f5 = (g2-g5)/2
+;// f3 = (g3+g4)/2 f4 = (g3-g4)/2
+;//
+;// Note that most coefficients are halved 3 times during the
+;// above calculation. We can rescale the algorithm dividing
+;// the input by 8 to remove the halvings.
+;//
+;// IStage 5: j(u) = T(u)*A(u)/8
+;//
+;// IStage 4: i0 = j0 i1 = j4
+;// i3 = j2 + j6 i2 = j2 - j6
+;// i7 = j5 + j3 i4 = j5 - j3
+;// i5 = j1 + j7 i6 = j1 - j7
+;//
+;// IStage 3: h0 = i0 + i1 h1 = i0 - i1
+;// h2 = (i2*sqrt2)-i3 h3 = i3
+;// h4 = 2*( cos(pi/8)*i4 + sin(pi/8)*i6)
+;// h6 = 2*(-sin(pi/8)*i4 + cos(pi/8)*i6)
+;// h5 = (i5-i7)*sqrt2 h7 = i5 + i7
+;//
+;// IStage 2: g0 = h0 + h3 g3 = h0 - h3
+;// g1 = h1 + h2 g2 = h1 - h2
+;// g7 = h7 g6 = h6 - h7
+;// g5 = h5 - g6 g4 = h4 - g5
+;//
+;// IStage 1: f0 = g0 + g7 f7 = g0 - g7
+;// f1 = g1 + g6 f6 = g1 - g6
+;// f2 = g2 + g5 f5 = g2 - g5
+;// f3 = g3 + g4 f4 = g3 - g4
+;//
+;// Note:
+;// 1. The scaling by A(u)/8 can often be combined with inverse
+;// quantization. The column and row scalings can be combined.
+;// 2. The flowgraph in the AAN paper has h4,g6 negated compared
+;// to the above code but is otherwise identical.
+;// 3. The rotation by -pi/8 can be peformed using three multiplies
+;// Eg c*i4+s*i6 = (i6-i4)*s + (c+s)*i4
+;// -s*i4+c*i6 = (i6-i4)*s + (c-s)*i6
+;// 4. If |T(u)|<=1 then from the IDCT definition,
+;// |f(x)| <= ((1/sqrt2) + |c(1,x)| + .. + |c(7,x)|)/2
+;// = ((1/sqrt2) + cos(pi/16) + ... + cos(7*pi/16))/2
+;// = ((1/sqrt2) + (cot(pi/32)-1)/2)/2
+;// = (1 + cos(pi/16) + cos(2pi/16) + cos(3pi/16))/sqrt(2)
+;// = (approx)2.64
+;// So the max gain of the 2D IDCT is ~x7.0 = 3 bits.
+;// The table below shows input patterns generating the maximum
+;// value of |f(u)| for input in the range |T(x)|<=1. M=-1, P=+1
+;// InputPattern Max |f(x)|
+;// PPPPPPPP |f0| = 2.64
+;// PPPMMMMM |f1| = 2.64
+;// PPMMMPPP |f2| = 2.64
+;// PPMMPPMM |f3| = 2.64
+;// PMMPPMMP |f4| = 2.64
+;// PMMPMMPM |f5| = 2.64
+;// PMPPMPMP |f6| = 2.64
+;// PMPMPMPM |f7| = 2.64
+;// Note that this input pattern is the transpose of the
+;// corresponding max input patter for the FDCT.
+
+;// Arguments
+
+pSrc RN 0 ;// source data buffer
+Stride RN 1 ;// destination stride in bytes
+pDest RN 2 ;// destination data buffer
+pScale RN 3 ;// pointer to scaling table
+
+
+ ;// DCT Inverse Macro
+ ;// The DCT code should be parametrized according
+ ;// to the following inputs:
+ ;// $outsize = "u8" : 8-bit unsigned data saturated (0 to +255)
+ ;// "s9" : 16-bit signed data saturated to 9-bit (-256 to +255)
+ ;// "s16" : 16-bit signed data not saturated (max size ~+/-14273)
+ ;// $inscale = "s16" : signed 16-bit aan-scale table, Q15 format, with 4 byte alignment
+ ;// "s32" : signed 32-bit aan-scale table, Q23 format, with 4 byte alignment
+ ;//
+ ;// Inputs:
+ ;// pSrc = r0 = Pointer to input data
+ ;// Range is -256 to +255 (9-bit)
+ ;// Stride = r1 = Stride between input lines
+ ;// pDest = r2 = Pointer to output data
+ ;// pScale = r3 = Pointer to aan-scale table in the format defined by $inscale
+
+
+
+ MACRO
+ M_IDCT $outsize, $inscale, $stride
+ LCLA SHIFT
+
+
+ IF ARM1136JS
+
+;// REGISTER ALLOCATION
+;// This is hard since we have 8 values, 9 free registers and each
+;// butterfly requires a temporary register. We also want to
+;// maintain register order so we can use LDM/STM. The table below
+;// summarises the register allocation that meets all these criteria.
+;// a=1stcol, b=2ndcol, f,g,h,i are dataflow points described above.
+;//
+;// r1 a01 g0 h0
+;// r4 b01 f0 g1 h1 i0
+;// r5 a23 f1 g2 i1
+;// r6 b23 f2 g3 h2 i2
+;// r7 a45 f3 h3 i3
+;// r8 b45 f4 g4 h4 i4
+;// r9 a67 f5 g5 h5 i5
+;// r10 b67 f6 g6 h6 i6
+;// r11 f7 g7 h7 i7
+;//
+ra01 RN 1
+rb01 RN 4
+ra23 RN 5
+rb23 RN 6
+ra45 RN 7
+rb45 RN 8
+ra67 RN 9
+rb67 RN 10
+rtmp RN 11
+csPiBy8 RN 12 ;// [ (Sin(pi/8)@Q15), (Cos(pi/8)@Q15) ]
+LoopRR2 RN 14 ;// [ LoopNumber<<13 , (1/Sqrt(2))@Q15 ]
+;// Transpose allocation
+xft RN ra01
+xf0 RN rb01
+xf1 RN ra23
+xf2 RN rb23
+xf3 RN ra45
+xf4 RN rb45
+xf5 RN ra67
+xf6 RN rb67
+xf7 RN rtmp
+;// IStage 1 allocation
+xg0 RN xft
+xg1 RN xf0
+xg2 RN xf1
+xg3 RN xf2
+xgt RN xf3
+xg4 RN xf4
+xg5 RN xf5
+xg6 RN xf6
+xg7 RN xf7
+;// IStage 2 allocation
+xh0 RN xg0
+xh1 RN xg1
+xht RN xg2
+xh2 RN xg3
+xh3 RN xgt
+xh4 RN xg4
+xh5 RN xg5
+xh6 RN xg6
+xh7 RN xg7
+;// IStage 3,4 allocation
+xit RN xh0
+xi0 RN xh1
+xi1 RN xht
+xi2 RN xh2
+xi3 RN xh3
+xi4 RN xh4
+xi5 RN xh5
+xi6 RN xh6
+xi7 RN xh7
+
+ M_STR pDest, ppDest
+ IF "$stride"="s"
+ M_STR Stride, pStride
+ ENDIF
+ M_ADR pDest, pBlk
+ LDR csPiBy8, =0x30fc7642
+ LDR LoopRR2, =0x00005a82
+
+v6_idct_col$_F
+ ;// Load even values
+ LDR xi4, [pSrc], #4 ;// j0
+ LDR xi5, [pSrc, #4*16-4] ;// j4
+ LDR xi6, [pSrc, #2*16-4] ;// j2
+ LDR xi7, [pSrc, #6*16-4] ;// j6
+
+ ;// Scale Even Values
+ IF "$inscale"="s16" ;// 16x16 mul
+SHIFT SETA 12
+ LDR xi0, [pScale], #4
+ LDR xi1, [pScale, #4*16-4]
+ LDR xi2, [pScale, #2*16-4]
+ MOV xit, #1<<(SHIFT-1)
+ SMLABB xi3, xi0, xi4, xit
+ SMLATT xi4, xi0, xi4, xit
+ SMLABB xi0, xi1, xi5, xit
+ SMLATT xi5, xi1, xi5, xit
+ MOV xi3, xi3, ASR #SHIFT
+ PKHBT xi4, xi3, xi4, LSL #(16-SHIFT)
+ LDR xi3, [pScale, #6*16-4]
+ SMLABB xi1, xi2, xi6, xit
+ SMLATT xi6, xi2, xi6, xit
+ MOV xi0, xi0, ASR #SHIFT
+ PKHBT xi5, xi0, xi5, LSL #(16-SHIFT)
+ SMLABB xi2, xi3, xi7, xit
+ SMLATT xi7, xi3, xi7, xit
+ MOV xi1, xi1, ASR #SHIFT
+ PKHBT xi6, xi1, xi6, LSL #(16-SHIFT)
+ MOV xi2, xi2, ASR #SHIFT
+ PKHBT xi7, xi2, xi7, LSL #(16-SHIFT)
+ ENDIF
+ IF "$inscale"="s32" ;// 32x16 mul
+SHIFT SETA (12+8-16)
+ MOV xit, #1<<(SHIFT-1)
+ LDR xi0, [pScale], #8
+ LDR xi1, [pScale, #0*32+4-8]
+ LDR xi2, [pScale, #4*32-8]
+ LDR xi3, [pScale, #4*32+4-8]
+ SMLAWB xi0, xi0, xi4, xit
+ SMLAWT xi1, xi1, xi4, xit
+ SMLAWB xi2, xi2, xi5, xit
+ SMLAWT xi3, xi3, xi5, xit
+ MOV xi0, xi0, ASR #SHIFT
+ PKHBT xi4, xi0, xi1, LSL #(16-SHIFT)
+ MOV xi2, xi2, ASR #SHIFT
+ PKHBT xi5, xi2, xi3, LSL #(16-SHIFT)
+ LDR xi0, [pScale, #2*32-8]
+ LDR xi1, [pScale, #2*32+4-8]
+ LDR xi2, [pScale, #6*32-8]
+ LDR xi3, [pScale, #6*32+4-8]
+ SMLAWB xi0, xi0, xi6, xit
+ SMLAWT xi1, xi1, xi6, xit
+ SMLAWB xi2, xi2, xi7, xit
+ SMLAWT xi3, xi3, xi7, xit
+ MOV xi0, xi0, ASR #SHIFT
+ PKHBT xi6, xi0, xi1, LSL #(16-SHIFT)
+ MOV xi2, xi2, ASR #SHIFT
+ PKHBT xi7, xi2, xi3, LSL #(16-SHIFT)
+ ENDIF
+
+ ;// Load odd values
+ LDR xi0, [pSrc, #1*16-4] ;// j1
+ LDR xi1, [pSrc, #7*16-4] ;// j7
+ LDR xi2, [pSrc, #5*16-4] ;// j5
+ LDR xi3, [pSrc, #3*16-4] ;// j3
+
+ IF {TRUE}
+ ;// shortcut if odd values 0
+ TEQ xi0, #0
+ TEQEQ xi1, #0
+ TEQEQ xi2, #0
+ TEQEQ xi3, #0
+ BEQ v6OddZero$_F
+ ENDIF
+
+ ;// Store scaled even values
+ STMIA pDest, {xi4, xi5, xi6, xi7}
+
+ ;// Scale odd values
+ IF "$inscale"="s16"
+ ;// Perform AAN Scale
+ LDR xi4, [pScale, #1*16-4]
+ LDR xi5, [pScale, #7*16-4]
+ LDR xi6, [pScale, #5*16-4]
+ SMLABB xi7, xi0, xi4, xit
+ SMLATT xi0, xi0, xi4, xit
+ SMLABB xi4, xi1, xi5, xit
+ SMLATT xi1, xi1, xi5, xit
+ MOV xi7, xi7, ASR #SHIFT
+ PKHBT xi0, xi7, xi0, LSL #(16-SHIFT)
+ LDR xi7, [pScale, #3*16-4]
+ SMLABB xi5, xi2, xi6, xit
+ SMLATT xi2, xi2, xi6, xit
+ MOV xi4, xi4, ASR #SHIFT
+ PKHBT xi1, xi4, xi1, LSL #(16-SHIFT)
+ SMLABB xi6, xi3, xi7, xit
+ SMLATT xi3, xi3, xi7, xit
+ MOV xi5, xi5, ASR #SHIFT
+ PKHBT xi2, xi5, xi2, LSL #(16-SHIFT)
+ MOV xi6, xi6, ASR #SHIFT
+ PKHBT xi3, xi6, xi3, LSL #(16-SHIFT)
+ ENDIF
+ IF "$inscale"="s32" ;// 32x16 mul
+ LDR xi4, [pScale, #1*32-8]
+ LDR xi5, [pScale, #1*32+4-8]
+ LDR xi6, [pScale, #7*32-8]
+ LDR xi7, [pScale, #7*32+4-8]
+ SMLAWB xi4, xi4, xi0, xit
+ SMLAWT xi5, xi5, xi0, xit
+ SMLAWB xi6, xi6, xi1, xit
+ SMLAWT xi7, xi7, xi1, xit
+ MOV xi4, xi4, ASR #SHIFT
+ PKHBT xi0, xi4, xi5, LSL #(16-SHIFT)
+ MOV xi6, xi6, ASR #SHIFT
+ PKHBT xi1, xi6, xi7, LSL #(16-SHIFT)
+ LDR xi4, [pScale, #5*32-8]
+ LDR xi5, [pScale, #5*32+4-8]
+ LDR xi6, [pScale, #3*32-8]
+ LDR xi7, [pScale, #3*32+4-8]
+ SMLAWB xi4, xi4, xi2, xit
+ SMLAWT xi5, xi5, xi2, xit
+ SMLAWB xi6, xi6, xi3, xit
+ SMLAWT xi7, xi7, xi3, xit
+ MOV xi4, xi4, ASR #SHIFT
+ PKHBT xi2, xi4, xi5, LSL #(16-SHIFT)
+ MOV xi6, xi6, ASR #SHIFT
+ PKHBT xi3, xi6, xi7, LSL #(16-SHIFT)
+ ENDIF
+
+ LDR xit, =0x00010001 ;// rounding constant
+ SADD16 xi5, xi0, xi1 ;// (j1+j7)/2
+ SHADD16 xi5, xi5, xit
+
+ SSUB16 xi6, xi0, xi1 ;// j1-j7
+ SADD16 xi7, xi2, xi3 ;// (j5+j3)/2
+ SHADD16 xi7, xi7, xit
+
+ SSUB16 xi4, xi2, xi3 ;// j5-j3
+
+ SSUB16 xi3, xi5, xi7 ;// (i5-i7)/2
+
+ PKHBT xi0, xi6, xi4, LSL#16 ;// [i4,i6] row a
+ PKHTB xi1, xi4, xi6, ASR#16 ;// [i4,i6] row b
+
+ SMUADX xi2, xi0, csPiBy8 ;// rowa by [c,s]
+ SMUADX xi4, xi1, csPiBy8 ;// rowb by [c,s]
+ SMUSD xi0, xi0, csPiBy8 ;// rowa by [-s,c]
+ SMUSD xi6, xi1, csPiBy8 ;// rowb by [-s,c]
+
+ SMULBB xi1, xi3, LoopRR2
+ SMULTB xi3, xi3, LoopRR2
+
+ PKHTB xh4, xi4, xi2, ASR#16 ;// h4/4
+ PKHTB xh6, xi6, xi0, ASR#16 ;// h6/4
+ SHADD16 xh7, xi5, xi7 ;// (i5+i7)/4
+
+ ;// xi0,xi1,xi2,xi3 now free
+ ;// IStage 4,3, rows 2to3 x1/2
+
+ MOV xi3, xi3, LSL #1
+ PKHTB xh5, xi3, xi1, ASR#15 ;// h5/4
+ LDRD xi0, [pDest, #8] ;// j2,j6 scaled
+
+ ;// IStage 2, rows4to7
+ SSUB16 xg6, xh6, xh7
+ SSUB16 xg5, xh5, xg6
+ SSUB16 xg4, xh4, xg5
+
+ SSUB16 xi2, xi0, xi1 ;// (j2-j6)
+
+ SHADD16 xi3, xi0, xi1 ;// (j2+j6)/2
+
+ SMULBB xi0, xi2, LoopRR2
+ SMULTB xi2, xi2, LoopRR2
+
+ MOV xi2, xi2, LSL #1
+ PKHTB xh2, xi2, xi0, ASR#15 ;// i2*sqrt(2)/4
+
+ ;// xi0, xi1 now free
+ ;// IStage 4,3 rows 0to1 x 1/2
+ LDRD xi0, [pDest] ;// j0, j4 scaled
+ SSUB16 xh2, xh2, xi3
+ ADDS LoopRR2, LoopRR2, #2<<29 ;// done two rows
+
+ SHADD16 xh0, xi0, xi1
+ SHSUB16 xh1, xi0, xi1
+
+ ;// IStage 2 rows 0to3 x 1/2
+ SHSUB16 xg2, xh1, xh2
+ SHADD16 xg1, xh1, xh2
+ SHSUB16 xg3, xh0, xh3
+ SHADD16 xg0, xh0, xh3
+
+ ;// IStage 1 all rows
+ SADD16 xf3, xg3, xg4
+ SSUB16 xf4, xg3, xg4
+ SADD16 xf2, xg2, xg5
+ SSUB16 xf5, xg2, xg5
+ SADD16 xf1, xg1, xg6
+ SSUB16 xf6, xg1, xg6
+ SADD16 xf0, xg0, xg7
+ SSUB16 xf7, xg0, xg7
+
+ ;// Transpose, store and loop
+ PKHBT ra01, xf0, xf1, LSL #16
+ PKHTB rb01, xf1, xf0, ASR #16
+
+ PKHBT ra23, xf2, xf3, LSL #16
+ PKHTB rb23, xf3, xf2, ASR #16
+
+ PKHBT ra45, xf4, xf5, LSL #16
+ PKHTB rb45, xf5, xf4, ASR #16
+
+ PKHBT ra67, xf6, xf7, LSL #16
+ STMIA pDest!, {ra01, ra23, ra45, ra67}
+ PKHTB rb67, xf7, xf6, ASR #16
+ STMIA pDest!, {rb01, rb23, rb45, rb67}
+ BCC v6_idct_col$_F
+
+ SUB pSrc, pDest, #(64*2)
+ M_LDR pDest, ppDest
+ IF "$stride"="s"
+ M_LDR pScale, pStride
+ ENDIF
+ B v6_idct_row$_F
+
+v6OddZero$_F
+ SSUB16 xi2, xi6, xi7 ;// (j2-j6)
+ SHADD16 xi3, xi6, xi7 ;// (j2+j6)/2
+
+ SMULBB xi0, xi2, LoopRR2
+ SMULTB xi2, xi2, LoopRR2
+
+ MOV xi2, xi2, LSL #1
+ PKHTB xh2, xi2, xi0, ASR#15 ;// i2*sqrt(2)/4
+ SSUB16 xh2, xh2, xi3
+
+ ;// xi0, xi1 now free
+ ;// IStage 4,3 rows 0to1 x 1/2
+
+ SHADD16 xh0, xi4, xi5
+ SHSUB16 xh1, xi4, xi5
+
+ ;// IStage 2 rows 0to3 x 1/2
+ SHSUB16 xg2, xh1, xh2
+ SHADD16 xg1, xh1, xh2
+ SHSUB16 xg3, xh0, xh3
+ SHADD16 xg0, xh0, xh3
+
+ ;// IStage 1 all rows
+ MOV xf3, xg3
+ MOV xf4, xg3
+ MOV xf2, xg2
+ MOV xf5, xg2
+ MOV xf1, xg1
+ MOV xf6, xg1
+ MOV xf0, xg0
+ MOV xf7, xg0
+
+ ;// Transpose
+ PKHBT ra01, xf0, xf1, LSL #16
+ PKHTB rb01, xf1, xf0, ASR #16
+
+ PKHBT ra23, xf2, xf3, LSL #16
+ PKHTB rb23, xf3, xf2, ASR #16
+
+ PKHBT ra45, xf4, xf5, LSL #16
+ PKHTB rb45, xf5, xf4, ASR #16
+
+ PKHBT ra67, xf6, xf7, LSL #16
+ PKHTB rb67, xf7, xf6, ASR #16
+
+ STMIA pDest!, {ra01, ra23, ra45, ra67}
+ ADDS LoopRR2, LoopRR2, #2<<29 ;// done two rows
+ STMIA pDest!, {rb01, rb23, rb45, rb67}
+
+ BCC v6_idct_col$_F
+ SUB pSrc, pDest, #(64*2)
+ M_LDR pDest, ppDest
+ IF "$stride"="s"
+ M_LDR pScale, pStride
+ ENDIF
+
+
+v6_idct_row$_F
+ ;// IStage 4,3, rows4to7 x1/4
+ LDR xit, =0x00010001 ;// rounding constant
+ LDR xi0, [pSrc, #1*16] ;// j1
+ LDR xi1, [pSrc, #7*16] ;// 4*j7
+ LDR xi2, [pSrc, #5*16] ;// j5
+ LDR xi3, [pSrc, #3*16] ;// j3
+
+ SHADD16 xi1, xi1, xit ;// 2*j7
+ SHADD16 xi1, xi1, xit ;// j7
+
+ SHADD16 xi5, xi0, xi1 ;// (j1+j7)/2
+ SSUB16 xi6, xi0, xi1 ;// j1-j7
+ SHADD16 xi7, xi2, xi3 ;// (j5+j3)/2
+ SSUB16 xi4, xi2, xi3 ;// j5-j3
+
+ SSUB16 xi3, xi5, xi7 ;// (i5-i7)/2
+
+ PKHBT xi0, xi6, xi4, LSL#16 ;// [i4,i6] row a
+ PKHTB xi1, xi4, xi6, ASR#16 ;// [i4,i6] row b
+
+ SMUADX xi2, xi0, csPiBy8 ;// rowa by [c,s]
+ SMUADX xi4, xi1, csPiBy8 ;// rowb by [c,s]
+ SMUSD xi0, xi0, csPiBy8 ;// rowa by [-s,c]
+ SMUSD xi6, xi1, csPiBy8 ;// rowb by [-s,c]
+
+ SMULBB xi1, xi3, LoopRR2
+ SMULTB xi3, xi3, LoopRR2
+
+ PKHTB xh4, xi4, xi2, ASR#16 ;// h4/4
+ PKHTB xh6, xi6, xi0, ASR#16 ;// h6/4
+ SHADD16 xh7, xi5, xi7 ;// (i5+i7)/4
+
+ MOV xi3, xi3, LSL #1
+ PKHTB xh5, xi3, xi1, ASR#15 ;// h5/4
+
+ ;// xi0,xi1,xi2,xi3 now free
+ ;// IStage 4,3, rows 2to3 x1/2
+
+ LDR xi0, [pSrc, #2*16] ;// j2
+ LDR xi1, [pSrc, #6*16] ;// 2*j6
+
+ ;// IStage 2, rows4to7
+ SSUB16 xg6, xh6, xh7
+ SSUB16 xg5, xh5, xg6
+ SSUB16 xg4, xh4, xg5
+
+ SHADD16 xi1, xi1, xit ;// j6
+ SSUB16 xi2, xi0, xi1 ;// (j2-j6)
+ SHADD16 xi3, xi0, xi1 ;// (j2+j6)/2
+
+ SMULBB xi0, xi2, LoopRR2
+ SMULTB xi2, xi2, LoopRR2
+
+ MOV xi2, xi2, LSL #1
+
+ PKHTB xh2, xi2, xi0, ASR#15 ;// i2*sqrt(2)/4
+
+ ;// xi0, xi1 now free
+ ;// IStage 4,3 rows 0to1 x 1/2
+ LDR xi1, [pSrc, #4*16] ;// j4
+ LDR xi0, [pSrc], #4 ;// j0
+
+ SSUB16 xh2, xh2, xi3
+ ADDS LoopRR2, LoopRR2, #2<<29 ;// done two rows
+
+ ADD xi0, xi0, xit, LSL #2 ;// ensure correct round
+ SHADD16 xh0, xi0, xi1 ;// of DC result
+ SHSUB16 xh1, xi0, xi1
+
+ ;// IStage 2 rows 0to3 x 1/2
+ SHSUB16 xg2, xh1, xh2
+ SHADD16 xg1, xh1, xh2
+ SHSUB16 xg3, xh0, xh3
+ SHADD16 xg0, xh0, xh3
+
+ ;// IStage 1 all rows
+ SHADD16 xf3, xg3, xg4
+ SHSUB16 xf4, xg3, xg4
+ SHADD16 xf2, xg2, xg5
+ SHSUB16 xf5, xg2, xg5
+ SHADD16 xf1, xg1, xg6
+ SHSUB16 xf6, xg1, xg6
+ SHADD16 xf0, xg0, xg7
+ SHSUB16 xf7, xg0, xg7
+
+ ;// Saturate
+ IF ("$outsize"="u8")
+ USAT16 xf0, #8, xf0
+ USAT16 xf1, #8, xf1
+ USAT16 xf2, #8, xf2
+ USAT16 xf3, #8, xf3
+ USAT16 xf4, #8, xf4
+ USAT16 xf5, #8, xf5
+ USAT16 xf6, #8, xf6
+ USAT16 xf7, #8, xf7
+ ENDIF
+ IF ("$outsize"="s9")
+ SSAT16 xf0, #9, xf0
+ SSAT16 xf1, #9, xf1
+ SSAT16 xf2, #9, xf2
+ SSAT16 xf3, #9, xf3
+ SSAT16 xf4, #9, xf4
+ SSAT16 xf5, #9, xf5
+ SSAT16 xf6, #9, xf6
+ SSAT16 xf7, #9, xf7
+ ENDIF
+
+ ;// Transpose to Row, Pack and store
+ IF ("$outsize"="u8")
+ ORR xf0, xf0, xf1, LSL #8 ;// [ b1 b0 a1 a0 ]
+ ORR xf2, xf2, xf3, LSL #8 ;// [ b3 b2 a3 a2 ]
+ ORR xf4, xf4, xf5, LSL #8 ;// [ b5 b4 a5 a4 ]
+ ORR xf6, xf6, xf7, LSL #8 ;// [ b7 b6 a7 a6 ]
+ PKHBT ra01, xf0, xf2, LSL #16
+ PKHTB rb01, xf2, xf0, ASR #16
+ PKHBT ra23, xf4, xf6, LSL #16
+ PKHTB rb23, xf6, xf4, ASR #16
+ STMIA pDest, {ra01, ra23}
+ IF "$stride"="s"
+ ADD pDest, pDest, pScale
+ STMIA pDest, {rb01, rb23}
+ ADD pDest, pDest, pScale
+ ELSE
+ ADD pDest, pDest, #($stride)
+ STMIA pDest, {rb01, rb23}
+ ADD pDest, pDest, #($stride)
+ ENDIF
+ ENDIF
+ IF ("$outsize"="s9"):LOR:("$outsize"="s16")
+ PKHBT ra01, xf0, xf1, LSL #16
+ PKHTB rb01, xf1, xf0, ASR #16
+
+ PKHBT ra23, xf2, xf3, LSL #16
+ PKHTB rb23, xf3, xf2, ASR #16
+
+ PKHBT ra45, xf4, xf5, LSL #16
+ PKHTB rb45, xf5, xf4, ASR #16
+
+ PKHBT ra67, xf6, xf7, LSL #16
+ PKHTB rb67, xf7, xf6, ASR #16
+
+ STMIA pDest, {ra01, ra23, ra45, ra67}
+ IF "$stride"="s"
+ ADD pDest, pDest, pScale
+ STMIA pDest, {rb01, rb23, rb45, rb67}
+ ADD pDest, pDest, pScale
+ ELSE
+ ADD pDest, pDest, #($stride)
+ STMIA pDest, {rb01, rb23, rb45, rb67}
+ ADD pDest, pDest, #($stride)
+ ENDIF
+ ENDIF
+
+ BCC v6_idct_row$_F
+ ENDIF ;// ARM1136JS
+
+
+ IF CortexA8
+
+Src0 EQU 7
+Src1 EQU 8
+Src2 EQU 9
+Src3 EQU 10
+Src4 EQU 11
+Src5 EQU 12
+Src6 EQU 13
+Src7 EQU 14
+Tmp EQU 15
+
+qXj0 QN Src0.S16
+qXj1 QN Src1.S16
+qXj2 QN Src2.S16
+qXj3 QN Src3.S16
+qXj4 QN Src4.S16
+qXj5 QN Src5.S16
+qXj6 QN Src6.S16
+qXj7 QN Src7.S16
+qXjt QN Tmp.S16
+
+dXj0lo DN (Src0*2).S16
+dXj0hi DN (Src0*2+1).S16
+dXj1lo DN (Src1*2).S16
+dXj1hi DN (Src1*2+1).S16
+dXj2lo DN (Src2*2).S16
+dXj2hi DN (Src2*2+1).S16
+dXj3lo DN (Src3*2).S16
+dXj3hi DN (Src3*2+1).S16
+dXj4lo DN (Src4*2).S16
+dXj4hi DN (Src4*2+1).S16
+dXj5lo DN (Src5*2).S16
+dXj5hi DN (Src5*2+1).S16
+dXj6lo DN (Src6*2).S16
+dXj6hi DN (Src6*2+1).S16
+dXj7lo DN (Src7*2).S16
+dXj7hi DN (Src7*2+1).S16
+dXjtlo DN (Tmp*2).S16
+dXjthi DN (Tmp*2+1).S16
+
+qXi0 QN qXj0
+qXi1 QN qXj4
+qXi2 QN qXj2
+qXi3 QN qXj7
+qXi4 QN qXj5
+qXi5 QN qXjt
+qXi6 QN qXj1
+qXi7 QN qXj6
+qXit QN qXj3
+
+dXi0lo DN dXj0lo
+dXi0hi DN dXj0hi
+dXi1lo DN dXj4lo
+dXi1hi DN dXj4hi
+dXi2lo DN dXj2lo
+dXi2hi DN dXj2hi
+dXi3lo DN dXj7lo
+dXi3hi DN dXj7hi
+dXi4lo DN dXj5lo
+dXi4hi DN dXj5hi
+dXi5lo DN dXjtlo
+dXi5hi DN dXjthi
+dXi6lo DN dXj1lo
+dXi6hi DN dXj1hi
+dXi7lo DN dXj6lo
+dXi7hi DN dXj6hi
+dXitlo DN dXj3lo
+dXithi DN dXj3hi
+
+qXh0 QN qXit
+qXh1 QN qXi0
+qXh2 QN qXi2
+qXh3 QN qXi3
+qXh4 QN qXi7
+qXh5 QN qXi5
+qXh6 QN qXi4
+qXh7 QN qXi1
+qXht QN qXi6
+
+dXh0lo DN dXitlo
+dXh0hi DN dXithi
+dXh1lo DN dXi0lo
+dXh1hi DN dXi0hi
+dXh2lo DN dXi2lo
+dXh2hi DN dXi2hi
+dXh3lo DN dXi3lo
+dXh3hi DN dXi3hi
+dXh4lo DN dXi7lo
+dXh4hi DN dXi7hi
+dXh5lo DN dXi5lo
+dXh5hi DN dXi5hi
+dXh6lo DN dXi4lo
+dXh6hi DN dXi4hi
+dXh7lo DN dXi1lo
+dXh7hi DN dXi1hi
+dXhtlo DN dXi6lo
+dXhthi DN dXi6hi
+
+qXg0 QN qXh2
+qXg1 QN qXht
+qXg2 QN qXh1
+qXg3 QN qXh0
+qXg4 QN qXh4
+qXg5 QN qXh5
+qXg6 QN qXh6
+qXg7 QN qXh7
+qXgt QN qXh3
+
+qXf0 QN qXg6
+qXf1 QN qXg5
+qXf2 QN qXg4
+qXf3 QN qXgt
+qXf4 QN qXg3
+qXf5 QN qXg2
+qXf6 QN qXg1
+qXf7 QN qXg0
+qXft QN qXg7
+
+
+qXt0 QN 1.S32
+qXt1 QN 2.S32
+qT0lo QN 1.S32
+qT0hi QN 2.S32
+qT1lo QN 3.S32
+qT1hi QN 4.S32
+qScalelo QN 5.S32 ;// used to read post scale values
+qScalehi QN 6.S32
+qTemp0 QN 5.S32
+qTemp1 QN 6.S32
+
+
+Scale1 EQU 6
+Scale2 EQU 15
+qScale1 QN Scale1.S16
+qScale2 QN Scale2.S16
+dScale1lo DN (Scale1*2).S16
+dScale1hi DN (Scale1*2+1).S16
+dScale2lo DN (Scale2*2).S16
+dScale2hi DN (Scale2*2+1).S16
+
+dCoefs DN 0.S16 ;// Scale coefficients in format {[0] [C] [S] [InvSqrt2]}
+InvSqrt2 DN dCoefs[0] ;// 1/sqrt(2) in Q15
+S DN dCoefs[1] ;// Sin(PI/8) in Q15
+C DN dCoefs[2] ;// Cos(PI/8) in Q15
+
+pTemp RN 12
+
+
+ IMPORT armCOMM_IDCTCoef
+
+ VLD1 {qXj0,qXj1}, [pSrc @64]!
+ VLD1 {qXj2,qXj3}, [pSrc @64]!
+ VLD1 {qXj4,qXj5}, [pSrc @64]!
+ VLD1 {qXj6,qXj7}, [pSrc @64]!
+
+ ;// Load PreScale and multiply with Src
+ ;// IStage 4
+
+ IF "$inscale"="s16" ;// 16X16 Mul
+ M_IDCT_PRESCALE16
+ ENDIF
+
+ IF "$inscale"="s32" ;// 32X32 ,ul
+ M_IDCT_PRESCALE32
+ ENDIF
+
+ ;// IStage 3
+ VQDMULH qXi2, qXi2, InvSqrt2 ;// i2/sqrt(2)
+ VHADD qXh0, qXi0, qXi1 ;// (i0+i1)/2
+ VHSUB qXh1, qXi0, qXi1 ;// (i0-i1)/2
+ VHADD qXh7, qXi5, qXi7 ;// (i5+i7)/4
+ VSUB qXh5, qXi5, qXi7 ;// (i5-i7)/2
+ VQDMULH qXh5, qXh5, InvSqrt2 ;// h5/sqrt(2)
+ VSUB qXh2, qXi2, qXi3 ;// h2, h3
+
+ VMULL qXt0, dXi4lo, C ;// c*i4
+ VMLAL qXt0, dXi6lo, S ;// c*i4+s*i6
+ VMULL qXt1, dXi4hi, C
+ VMLAL qXt1, dXi6hi, S
+ VSHRN dXh4lo, qXt0, #16 ;// h4
+ VSHRN dXh4hi, qXt1, #16
+
+ VMULL qXt0, dXi6lo, C ;// c*i6
+ VMLSL qXt0, dXi4lo, S ;// -s*i4 + c*h6
+ VMULL qXt1, dXi6hi, C
+ VMLSL qXt1, dXi4hi, S
+ VSHRN dXh6lo, qXt0, #16 ;// h6
+ VSHRN dXh6hi, qXt1, #16
+
+ ;// IStage 2
+ VSUB qXg6, qXh6, qXh7
+ VSUB qXg5, qXh5, qXg6
+ VSUB qXg4, qXh4, qXg5
+ VHADD qXg1, qXh1, qXh2 ;// (h1+h2)/2
+ VHSUB qXg2, qXh1, qXh2 ;// (h1-h2)/2
+ VHADD qXg0, qXh0, qXh3 ;// (h0+h3)/2
+ VHSUB qXg3, qXh0, qXh3 ;// (h0-h3)/2
+
+ ;// IStage 1 all rows
+ VADD qXf3, qXg3, qXg4
+ VSUB qXf4, qXg3, qXg4
+ VADD qXf2, qXg2, qXg5
+ VSUB qXf5, qXg2, qXg5
+ VADD qXf1, qXg1, qXg6
+ VSUB qXf6, qXg1, qXg6
+ VADD qXf0, qXg0, qXg7
+ VSUB qXf7, qXg0, qXg7
+
+ ;// Transpose, store and loop
+XTR0 EQU Src5
+XTR1 EQU Tmp
+XTR2 EQU Src6
+XTR3 EQU Src7
+XTR4 EQU Src3
+XTR5 EQU Src0
+XTR6 EQU Src1
+XTR7 EQU Src2
+XTRt EQU Src4
+
+qA0 QN XTR0.S32 ;// for XTRpose
+qA1 QN XTR1.S32
+qA2 QN XTR2.S32
+qA3 QN XTR3.S32
+qA4 QN XTR4.S32
+qA5 QN XTR5.S32
+qA6 QN XTR6.S32
+qA7 QN XTR7.S32
+
+dB0 DN XTR0*2+1 ;// for using VSWP
+dB1 DN XTR1*2+1
+dB2 DN XTR2*2+1
+dB3 DN XTR3*2+1
+dB4 DN XTR4*2
+dB5 DN XTR5*2
+dB6 DN XTR6*2
+dB7 DN XTR7*2
+
+
+ VTRN qXf0, qXf1
+ VTRN qXf2, qXf3
+ VTRN qXf4, qXf5
+ VTRN qXf6, qXf7
+ VTRN qA0, qA2
+ VTRN qA1, qA3
+ VTRN qA4, qA6
+ VTRN qA5, qA7
+ VSWP dB0, dB4
+ VSWP dB1, dB5
+ VSWP dB2, dB6
+ VSWP dB3, dB7
+
+
+qYj0 QN qXf0
+qYj1 QN qXf1
+qYj2 QN qXf2
+qYj3 QN qXf3
+qYj4 QN qXf4
+qYj5 QN qXf5
+qYj6 QN qXf6
+qYj7 QN qXf7
+qYjt QN qXft
+
+dYj0lo DN (XTR0*2).S16
+dYj0hi DN (XTR0*2+1).S16
+dYj1lo DN (XTR1*2).S16
+dYj1hi DN (XTR1*2+1).S16
+dYj2lo DN (XTR2*2).S16
+dYj2hi DN (XTR2*2+1).S16
+dYj3lo DN (XTR3*2).S16
+dYj3hi DN (XTR3*2+1).S16
+dYj4lo DN (XTR4*2).S16
+dYj4hi DN (XTR4*2+1).S16
+dYj5lo DN (XTR5*2).S16
+dYj5hi DN (XTR5*2+1).S16
+dYj6lo DN (XTR6*2).S16
+dYj6hi DN (XTR6*2+1).S16
+dYj7lo DN (XTR7*2).S16
+dYj7hi DN (XTR7*2+1).S16
+dYjtlo DN (XTRt*2).S16
+dYjthi DN (XTRt*2+1).S16
+
+qYi0 QN qYj0
+qYi1 QN qYj4
+qYi2 QN qYj2
+qYi3 QN qYj7
+qYi4 QN qYj5
+qYi5 QN qYjt
+qYi6 QN qYj1
+qYi7 QN qYj6
+qYit QN qYj3
+
+dYi0lo DN dYj0lo
+dYi0hi DN dYj0hi
+dYi1lo DN dYj4lo
+dYi1hi DN dYj4hi
+dYi2lo DN dYj2lo
+dYi2hi DN dYj2hi
+dYi3lo DN dYj7lo
+dYi3hi DN dYj7hi
+dYi4lo DN dYj5lo
+dYi4hi DN dYj5hi
+dYi5lo DN dYjtlo
+dYi5hi DN dYjthi
+dYi6lo DN dYj1lo
+dYi6hi DN dYj1hi
+dYi7lo DN dYj6lo
+dYi7hi DN dYj6hi
+dYitlo DN dYj3lo
+dYithi DN dYj3hi
+
+qYh0 QN qYit
+qYh1 QN qYi0
+qYh2 QN qYi2
+qYh3 QN qYi3
+qYh4 QN qYi7
+qYh5 QN qYi5
+qYh6 QN qYi4
+qYh7 QN qYi1
+qYht QN qYi6
+
+dYh0lo DN dYitlo
+dYh0hi DN dYithi
+dYh1lo DN dYi0lo
+dYh1hi DN dYi0hi
+dYh2lo DN dYi2lo
+dYh2hi DN dYi2hi
+dYh3lo DN dYi3lo
+dYh3hi DN dYi3hi
+dYh4lo DN dYi7lo
+dYh4hi DN dYi7hi
+dYh5lo DN dYi5lo
+dYh5hi DN dYi5hi
+dYh6lo DN dYi4lo
+dYh6hi DN dYi4hi
+dYh7lo DN dYi1lo
+dYh7hi DN dYi1hi
+dYhtlo DN dYi6lo
+dYhthi DN dYi6hi
+
+qYg0 QN qYh2
+qYg1 QN qYht
+qYg2 QN qYh1
+qYg3 QN qYh0
+qYg4 QN qYh4
+qYg5 QN qYh5
+qYg6 QN qYh6
+qYg7 QN qYh7
+qYgt QN qYh3
+
+qYf0 QN qYg6
+qYf1 QN qYg5
+qYf2 QN qYg4
+qYf3 QN qYgt
+qYf4 QN qYg3
+qYf5 QN qYg2
+qYf6 QN qYg1
+qYf7 QN qYg0
+qYft QN qYg7
+
+ VRSHR qYj7, qYj7, #2
+ VRSHR qYj6, qYj6, #1
+
+ VHADD qYi5, qYj1, qYj7 ;// i5 = (j1+j7)/2
+ VSUB qYi6, qYj1, qYj7 ;// i6 = j1-j7
+ VHADD qYi3, qYj2, qYj6 ;// i3 = (j2+j6)/2
+ VSUB qYi2, qYj2, qYj6 ;// i2 = j2-j6
+ VHADD qYi7, qYj5, qYj3 ;// i7 = (j5+j3)/2
+ VSUB qYi4, qYj5, qYj3 ;// i4 = j5-j3
+
+ VQDMULH qYi2, qYi2, InvSqrt2 ;// i2/sqrt(2)
+ ;// IStage 4,3 rows 0to1 x 1/2
+
+ MOV pTemp, #0x4 ;// ensure correct round
+ VDUP qScale1, pTemp ;// of DC result
+ VADD qYi0, qYi0, qScale1
+
+ VHADD qYh0, qYi0, qYi1 ;// (i0+i1)/2
+ VHSUB qYh1, qYi0, qYi1 ;// (i0-i1)/2
+
+ VHADD qYh7, qYi5, qYi7 ;// (i5+i7)/4
+ VSUB qYh5, qYi5, qYi7 ;// (i5-i7)/2
+ VSUB qYh2, qYi2, qYi3 ;// h2, h3
+ VQDMULH qYh5, qYh5, InvSqrt2 ;// h5/sqrt(2)
+
+ VMULL qXt0, dYi4lo, C ;// c*i4
+ VMLAL qXt0, dYi6lo, S ;// c*i4+s*i6
+ VMULL qXt1, dYi4hi, C
+ VMLAL qXt1, dYi6hi, S
+ VSHRN dYh4lo, qXt0, #16 ;// h4
+ VSHRN dYh4hi, qXt1, #16
+
+ VMULL qXt0, dYi6lo, C ;// c*i6
+ VMLSL qXt0, dYi4lo, S ;// -s*i4 + c*h6
+ VMULL qXt1, dYi6hi, C
+ VMLSL qXt1, dYi4hi, S
+ VSHRN dYh6lo, qXt0, #16 ;// h6
+ VSHRN dYh6hi, qXt1, #16
+
+ VSUB qYg6, qYh6, qYh7
+ VSUB qYg5, qYh5, qYg6
+ VSUB qYg4, qYh4, qYg5
+
+ ;// IStage 2 rows 0to3 x 1/2
+ VHADD qYg1, qYh1, qYh2 ;// (h1+h2)/2
+ VHSUB qYg2, qYh1, qYh2 ;// (h1-h2)/2
+ VHADD qYg0, qYh0, qYh3 ;// (h0+h3)/2
+ VHSUB qYg3, qYh0, qYh3 ;// (h0-h3)/2
+
+
+ ;// IStage 1 all rows
+ VHADD qYf3, qYg3, qYg4
+ VHSUB qYf4, qYg3, qYg4
+ VHADD qYf2, qYg2, qYg5
+ VHSUB qYf5, qYg2, qYg5
+ VHADD qYf1, qYg1, qYg6
+ VHSUB qYf6, qYg1, qYg6
+ VHADD qYf0, qYg0, qYg7
+ VHSUB qYf7, qYg0, qYg7
+
+YTR0 EQU Src0
+YTR1 EQU Src4
+YTR2 EQU Src1
+YTR3 EQU Src2
+YTR4 EQU Src7
+YTR5 EQU Src5
+YTR6 EQU Tmp
+YTR7 EQU Src6
+YTRt EQU Src3
+
+qC0 QN YTR0.S32 ;// for YTRpose
+qC1 QN YTR1.S32
+qC2 QN YTR2.S32
+qC3 QN YTR3.S32
+qC4 QN YTR4.S32
+qC5 QN YTR5.S32
+qC6 QN YTR6.S32
+qC7 QN YTR7.S32
+
+dD0 DN YTR0*2+1 ;// for using VSWP
+dD1 DN YTR1*2+1
+dD2 DN YTR2*2+1
+dD3 DN YTR3*2+1
+dD4 DN YTR4*2
+dD5 DN YTR5*2
+dD6 DN YTR6*2
+dD7 DN YTR7*2
+
+ VTRN qYf0, qYf1
+ VTRN qYf2, qYf3
+ VTRN qYf4, qYf5
+ VTRN qYf6, qYf7
+ VTRN qC0, qC2
+ VTRN qC1, qC3
+ VTRN qC4, qC6
+ VTRN qC5, qC7
+ VSWP dD0, dD4
+ VSWP dD1, dD5
+ VSWP dD2, dD6
+ VSWP dD3, dD7
+
+
+dYf0U8 DN YTR0*2.U8
+dYf1U8 DN YTR1*2.U8
+dYf2U8 DN YTR2*2.U8
+dYf3U8 DN YTR3*2.U8
+dYf4U8 DN YTR4*2.U8
+dYf5U8 DN YTR5*2.U8
+dYf6U8 DN YTR6*2.U8
+dYf7U8 DN YTR7*2.U8
+
+ ;//
+ ;// Do saturation if outsize is other than S16
+ ;//
+
+ IF ("$outsize"="u8")
+ ;// Output range [0-255]
+ VQMOVN dYf0U8, qYf0
+ VQMOVN dYf1U8, qYf1
+ VQMOVN dYf2U8, qYf2
+ VQMOVN dYf3U8, qYf3
+ VQMOVN dYf4U8, qYf4
+ VQMOVN dYf5U8, qYf5
+ VQMOVN dYf6U8, qYf6
+ VQMOVN dYf7U8, qYf7
+ ENDIF
+
+ IF ("$outsize"="s9")
+ ;// Output range [-256 to +255]
+ VQSHL qYf0, qYf0, #16-9
+ VQSHL qYf1, qYf1, #16-9
+ VQSHL qYf2, qYf2, #16-9
+ VQSHL qYf3, qYf3, #16-9
+ VQSHL qYf4, qYf4, #16-9
+ VQSHL qYf5, qYf5, #16-9
+ VQSHL qYf6, qYf6, #16-9
+ VQSHL qYf7, qYf7, #16-9
+
+ VSHR qYf0, qYf0, #16-9
+ VSHR qYf1, qYf1, #16-9
+ VSHR qYf2, qYf2, #16-9
+ VSHR qYf3, qYf3, #16-9
+ VSHR qYf4, qYf4, #16-9
+ VSHR qYf5, qYf5, #16-9
+ VSHR qYf6, qYf6, #16-9
+ VSHR qYf7, qYf7, #16-9
+ ENDIF
+
+ ;// Store output depending on the Stride size
+ IF "$stride"="s"
+ VST1 qYf0, [pDest @64], Stride
+ VST1 qYf1, [pDest @64], Stride
+ VST1 qYf2, [pDest @64], Stride
+ VST1 qYf3, [pDest @64], Stride
+ VST1 qYf4, [pDest @64], Stride
+ VST1 qYf5, [pDest @64], Stride
+ VST1 qYf6, [pDest @64], Stride
+ VST1 qYf7, [pDest @64]
+ ELSE
+ IF ("$outsize"="u8")
+ VST1 dYf0U8, [pDest @64], #8
+ VST1 dYf1U8, [pDest @64], #8
+ VST1 dYf2U8, [pDest @64], #8
+ VST1 dYf3U8, [pDest @64], #8
+ VST1 dYf4U8, [pDest @64], #8
+ VST1 dYf5U8, [pDest @64], #8
+ VST1 dYf6U8, [pDest @64], #8
+ VST1 dYf7U8, [pDest @64]
+ ELSE
+ ;// ("$outsize"="s9") or ("$outsize"="s16")
+ VST1 qYf0, [pDest @64], #16
+ VST1 qYf1, [pDest @64], #16
+ VST1 qYf2, [pDest @64], #16
+ VST1 qYf3, [pDest @64], #16
+ VST1 qYf4, [pDest @64], #16
+ VST1 qYf5, [pDest @64], #16
+ VST1 qYf6, [pDest @64], #16
+ VST1 qYf7, [pDest @64]
+ ENDIF
+
+ ENDIF
+
+
+
+ ENDIF ;// CortexA8
+
+
+
+ MEND
+
+ ;// Scale TWO input rows with TWO rows of 16 bit scale values
+ ;//
+ ;// This macro is used by M_IDCT_PRESCALE16 to pre-scale one row
+ ;// input (Eight input values) with one row of scale values. Also
+ ;// Loads next scale values from pScale, if $LastRow flag is not set.
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// $dAlo - Input D register with first four S16 values of row n
+ ;// $dAhi - Input D register with next four S16 values of row n
+ ;// $dBlo - Input D register with first four S16 values of row n+1
+ ;// $dBhi - Input D register with next four S16 values of row n+1
+ ;// pScale - Pointer to next row of scale values
+ ;// qT0lo - Temporary scratch register
+ ;// qT0hi - Temporary scratch register
+ ;// qT1lo - Temporary scratch register
+ ;// qT1hi - Temporary scratch register
+ ;// dScale1lo - Scale value of row n
+ ;// dScale1hi - Scale value of row n
+ ;// dScale2lo - Scale value of row n+1
+ ;// dScale2hi - Scale value of row n+1
+ ;//
+ ;// Input Flag
+ ;//
+ ;// $LastRow - Flag to indicate whether current row is last row
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// $dAlo - Scaled output values (first four S16 of row n)
+ ;// $dAhi - Scaled output values (next four S16 of row n)
+ ;// $dBlo - Scaled output values (first four S16 of row n+1)
+ ;// $dBhi - Scaled output values (next four S16 of row n+1)
+ ;// qScale1 - Scale values for next row
+ ;// qScale2 - Scale values for next row+1
+ ;// pScale - Pointer to next row of scale values
+ ;//
+ MACRO
+ M_IDCT_SCALE16 $dAlo, $dAhi, $dBlo, $dBhi, $LastRow
+ VMULL qT0lo, $dAlo, dScale1lo
+ VMULL qT0hi, $dAhi, dScale1hi
+ VMULL qT1lo, $dBlo, dScale2lo
+ VMULL qT1hi, $dBhi, dScale2hi
+ IF "$LastRow"="0"
+ VLD1 qScale1, [pScale], #16 ;// Load scale for row n+1
+ VLD1 qScale2, [pScale], #16 ;// Load scale for row n+2
+ ENDIF
+ VQRSHRN $dAlo, qT0lo, #12
+ VQRSHRN $dAhi, qT0hi, #12
+ VQRSHRN $dBlo, qT1lo, #12
+ VQRSHRN $dBhi, qT1hi, #12
+ MEND
+
+ ;// Scale 8x8 block input values with 16 bit scale values
+ ;//
+ ;// This macro is used to pre-scale block of 8x8 input.
+ ;// This also do the Ist stage transformations of IDCT.
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// dXjnlo - n th input D register with first four S16 values
+ ;// dXjnhi - n th input D register with next four S16 values
+ ;// qXjn - n th input Q register with eight S16 values
+ ;// pScale - Pointer to scale values
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// qXin - n th output Q register with eight S16 output values of 1st stage
+ ;//
+ MACRO
+ M_IDCT_PRESCALE16
+ VLD1 qScale1, [pScale], #16 ;// Load Pre scale for row 0
+ VLD1 qScale2, [pScale], #16 ;// Load Pre scale for row 0
+ M_IDCT_SCALE16 dXj0lo, dXj0hi, dXj1lo, dXj1hi, 0 ;// Pre scale row 0 & 1
+ M_IDCT_SCALE16 dXj2lo, dXj2hi, dXj3lo, dXj3hi, 0
+ M_IDCT_SCALE16 dXj4lo, dXj4hi, dXj5lo, dXj5hi, 0
+ M_IDCT_SCALE16 dXj6lo, dXj6hi, dXj7lo, dXj7hi, 1
+ VHADD qXi5, qXj1, qXj7 ;// (j1+j7)/2
+ VSUB qXi6, qXj1, qXj7 ;// j1-j7
+ LDR pSrc, =armCOMM_IDCTCoef ;// Address of DCT inverse AAN constants
+ VHADD qXi3, qXj2, qXj6 ;// (j2+j6)/2
+ VSUB qXi2, qXj2, qXj6 ;// j2-j6
+ VLDR dCoefs, [pSrc] ;// Load DCT inverse AAN constants
+ VHADD qXi7, qXj5, qXj3 ;// (j5+j3)/2
+ VSUB qXi4, qXj5, qXj3 ;// j5-j3
+ MEND
+
+
+ ;// Scale 8x8 block input values with 32 bit scale values
+ ;//
+ ;// This macro is used to pre-scale block of 8x8 input.
+ ;// This also do the Ist stage transformations of IDCT.
+ ;//
+ ;// Input Registers:
+ ;//
+ ;// dXjnlo - n th input D register with first four S16 values
+ ;// dXjnhi - n th input D register with next four S16 values
+ ;// qXjn - n th input Q register with eight S16 values
+ ;// pScale - Pointer to 32bit scale values in Q23 format
+ ;//
+ ;// Output Registers:
+ ;//
+ ;// dXinlo - n th output D register with first four S16 output values of 1st stage
+ ;// dXinhi - n th output D register with next four S16 output values of 1st stage
+ ;//
+ MACRO
+ M_IDCT_PRESCALE32
+qScale0lo QN 0.S32
+qScale0hi QN 1.S32
+qScale1lo QN 2.S32
+qScale1hi QN 3.S32
+qScale2lo QN qScale1lo
+qScale2hi QN qScale1hi
+qScale3lo QN qScale1lo
+qScale3hi QN qScale1hi
+qScale4lo QN qScale1lo
+qScale4hi QN qScale1hi
+qScale5lo QN qScale0lo
+qScale5hi QN qScale0hi
+qScale6lo QN qScale0lo
+qScale6hi QN qScale0hi
+qScale7lo QN qScale0lo
+qScale7hi QN qScale0hi
+
+qSrc0lo QN 4.S32
+qSrc0hi QN 5.S32
+qSrc1lo QN 6.S32
+qSrc1hi QN Src4.S32
+qSrc2lo QN qSrc0lo
+qSrc2hi QN qSrc0hi
+qSrc3lo QN qSrc0lo
+qSrc3hi QN qSrc0hi
+qSrc4lo QN qSrc0lo
+qSrc4hi QN qSrc0hi
+qSrc5lo QN qSrc1lo
+qSrc5hi QN qSrc1hi
+qSrc6lo QN qSrc1lo
+qSrc6hi QN qSrc1hi
+qSrc7lo QN qSrc0lo
+qSrc7hi QN qSrc0hi
+
+qRes17lo QN qScale0lo
+qRes17hi QN qScale0hi
+qRes26lo QN qScale0lo
+qRes26hi QN qScale0hi
+qRes53lo QN qScale0lo
+qRes53hi QN qScale0hi
+
+ ADD pTemp, pScale, #4*8*7 ;// Address of pScale[7]
+
+ ;// Row 0
+ VLD1 {qScale0lo, qScale0hi}, [pScale]!
+ VSHLL qSrc0lo, dXj0lo, #(12-1)
+ VSHLL qSrc0hi, dXj0hi, #(12-1)
+ VLD1 {qScale1lo, qScale1hi}, [pScale]!
+ VQRDMULH qSrc0lo, qScale0lo, qSrc0lo
+ VQRDMULH qSrc0hi, qScale0hi, qSrc0hi
+ VLD1 {qScale7lo, qScale7hi}, [pTemp]!
+ VSHLL qSrc1lo, dXj1lo, #(12-1)
+ VSHLL qSrc1hi, dXj1hi, #(12-1)
+ VMOVN dXi0lo, qSrc0lo ;// Output i0
+ VMOVN dXi0hi, qSrc0hi
+ VSHLL qSrc7lo, dXj7lo, #(12-1)
+ VSHLL qSrc7hi, dXj7hi, #(12-1)
+ SUB pTemp, pTemp, #((16*2)+(4*8*1))
+ VQRDMULH qSrc1lo, qScale1lo, qSrc1lo
+ VQRDMULH qSrc1hi, qScale1hi, qSrc1hi
+ VQRDMULH qSrc7lo, qScale7lo, qSrc7lo
+ VQRDMULH qSrc7hi, qScale7hi, qSrc7hi
+ VLD1 {qScale2lo, qScale2hi}, [pScale]!
+
+ ;// Row 1 & 7
+ VHADD qRes17lo, qSrc1lo, qSrc7lo ;// (j1+j7)/2
+ VHADD qRes17hi, qSrc1hi, qSrc7hi ;// (j1+j7)/2
+ VMOVN dXi5lo, qRes17lo ;// Output i5
+ VMOVN dXi5hi, qRes17hi
+ VSUB qRes17lo, qSrc1lo, qSrc7lo ;// j1-j7
+ VSUB qRes17hi, qSrc1hi, qSrc7hi ;// j1-j7
+ VMOVN dXi6lo, qRes17lo ;// Output i6
+ VMOVN dXi6hi, qRes17hi
+ VSHLL qSrc2lo, dXj2lo, #(12-1)
+ VSHLL qSrc2hi, dXj2hi, #(12-1)
+ VLD1 {qScale6lo, qScale6hi}, [pTemp]!
+ VSHLL qSrc6lo, dXj6lo, #(12-1)
+ VSHLL qSrc6hi, dXj6hi, #(12-1)
+ SUB pTemp, pTemp, #((16*2)+(4*8*1))
+ VQRDMULH qSrc2lo, qScale2lo, qSrc2lo
+ VQRDMULH qSrc2hi, qScale2hi, qSrc2hi
+ VQRDMULH qSrc6lo, qScale6lo, qSrc6lo
+ VQRDMULH qSrc6hi, qScale6hi, qSrc6hi
+ VLD1 {qScale3lo, qScale3hi}, [pScale]!
+
+ ;// Row 2 & 6
+ VHADD qRes26lo, qSrc2lo, qSrc6lo ;// (j2+j6)/2
+ VHADD qRes26hi, qSrc2hi, qSrc6hi ;// (j2+j6)/2
+ VMOVN dXi3lo, qRes26lo ;// Output i3
+ VMOVN dXi3hi, qRes26hi
+ VSUB qRes26lo, qSrc2lo, qSrc6lo ;// j2-j6
+ VSUB qRes26hi, qSrc2hi, qSrc6hi ;// j2-j6
+ VMOVN dXi2lo, qRes26lo ;// Output i2
+ VMOVN dXi2hi, qRes26hi
+ VSHLL qSrc3lo, dXj3lo, #(12-1)
+ VSHLL qSrc3hi, dXj3hi, #(12-1)
+ VLD1 {qScale5lo, qScale5hi}, [pTemp]!
+ VSHLL qSrc5lo, dXj5lo, #(12-1)
+ VSHLL qSrc5hi, dXj5hi, #(12-1)
+ VQRDMULH qSrc3lo, qScale3lo, qSrc3lo
+ VQRDMULH qSrc3hi, qScale3hi, qSrc3hi
+ VQRDMULH qSrc5lo, qScale5lo, qSrc5lo
+ VQRDMULH qSrc5hi, qScale5hi, qSrc5hi
+
+ ;// Row 3 & 5
+ VHADD qRes53lo, qSrc5lo, qSrc3lo ;// (j5+j3)/2
+ VHADD qRes53hi, qSrc5hi, qSrc3hi ;// (j5+j3)/2
+ SUB pSrc, pSrc, #16*2*2
+ VMOVN dXi7lo, qRes53lo ;// Output i7
+ VMOVN dXi7hi, qRes53hi
+ VSUB qRes53lo, qSrc5lo, qSrc3lo ;// j5-j3
+ VSUB qRes53hi, qSrc5hi, qSrc3hi ;// j5-j3
+ VLD1 qXj4, [pSrc @64]
+ VMOVN dXi4lo, qRes53lo ;// Output i4
+ VMOVN dXi4hi, qRes53hi
+ VSHLL qSrc4lo, dXj4lo, #(12-1)
+ VSHLL qSrc4hi, dXj4hi, #(12-1)
+ VLD1 {qScale4lo, qScale4hi}, [pScale]
+ LDR pSrc, =armCOMM_IDCTCoef ;// Address of DCT inverse AAN constants
+ VQRDMULH qSrc4lo, qScale4lo, qSrc4lo
+ VQRDMULH qSrc4hi, qScale4hi, qSrc4hi
+ VLDR dCoefs, [pSrc] ;// Load DCT inverse AAN constants
+ ;// Row 4
+ VMOVN dXi1lo, qSrc4lo ;// Output i1
+ VMOVN dXi1hi, qSrc4hi
+
+ MEND
+
+ END
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_MaskTable.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_MaskTable.h
new file mode 100755
index 0000000..51118fd
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_MaskTable.h
@@ -0,0 +1,27 @@
+/**
+ *
+ * File Name: armCOMM_MaskTable.h
+ * OpenMAX DL: v1.0.2
+ * Revision: 12290
+ * Date: Wednesday, April 9, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Mask Table to mask the end of array
+ */
+
+
+
+#ifndef _ARMCOMM_MASKTABLE_H_
+#define _ARMCOMM_MASKTABLE_H_
+
+#define MaskTableSize 72
+
+/* Mask table */
+
+extern const OMX_U16 armCOMM_qMaskTable16[MaskTableSize];
+extern const OMX_U8 armCOMM_qMaskTable8[MaskTableSize];
+
+#endif
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_Version.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_Version.h
new file mode 100755
index 0000000..41b3e1e
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_Version.h
@@ -0,0 +1,43 @@
+/* Guard the header against multiple inclusion. */
+#ifndef __ARM_COMM_VERSION_H__
+#define __ARM_COMM_VERSION_H__
+
+
+/* The following line should be in omxtypes.h but hasn't been approved by OpenMAX yet */
+#define OMX_VERSION 102
+
+/* We need to define these macros in order to convert a #define number into a #define string. */
+#define ARM_QUOTE(a) #a
+#define ARM_INDIRECT(A) ARM_QUOTE(A)
+
+/* Convert the OMX_VERSION number into a string that can be used, for example, to print it out. */
+#define ARM_VERSION_STRING ARM_INDIRECT(OMX_VERSION)
+
+
+/* Define this in order to turn on ARM version/release/build strings in each domain */
+#define ARM_INCLUDE_VERSION_DESCRIPTIONS
+
+#ifdef ARM_INCLUDE_VERSION_DESCRIPTIONS
+ extern const char * const omxAC_VersionDescription;
+ extern const char * const omxIC_VersionDescription;
+ extern const char * const omxIP_VersionDescription;
+ extern const char * const omxSP_VersionDescription;
+ extern const char * const omxVC_VersionDescription;
+#endif /* ARM_INCLUDE_VERSION_DESCRIPTIONS */
+
+
+/* The following entries should be automatically updated by the release script */
+/* They are used in the ARM version strings defined for each domain. */
+
+/* The release tag associated with this release of the library. - used for source and object releases */
+#define OMX_ARM_RELEASE_TAG "r1p0-00bet0"
+
+/* The ARM architecture used to build any objects or executables in this release. */
+#define OMX_ARM_BUILD_ARCHITECTURE "ARM Architecture V7 with NEON"
+
+/* The ARM Toolchain used to build any objects or executables in this release. */
+#define OMX_ARM_BUILD_TOOLCHAIN "ARM RVCT 3.1"
+
+
+#endif /* __ARM_COMM_VERSION_H__ */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_s.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_s.h
new file mode 100755
index 0000000..0956bd1
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_s.h
@@ -0,0 +1,1157 @@
+;//
+;//
+;// File Name: armCOMM_s.h
+;// OpenMAX DL: v1.0.2
+;// Revision: 12290
+;// Date: Wednesday, April 9, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+;// ARM optimized OpenMAX common header file
+;//
+
+;// Protect against multiple inclusion
+ IF :LNOT::DEF:ARMCOMM_S_H
+ GBLL ARMCOMM_S_H
+
+ REQUIRE8 ;// Requires 8-byte stack alignment
+ PRESERVE8 ;// Preserves 8-byte stack alignment
+
+ GBLL ARM_ERRORCHECK
+ARM_ERRORCHECK SETL {FALSE}
+
+;// Globals
+
+ GBLS _RRegList ;// R saved register list
+ GBLS _DRegList ;// D saved register list
+ GBLS _Variant ;// Selected processor variant
+ GBLS _CPU ;// CPU name
+ GBLS _Struct ;// Structure name
+
+ GBLL _InFunc ;// Inside function assembly flag
+ GBLL _SwLong ;// Long switch flag
+
+ GBLA _RBytes ;// Number of register bytes on stack
+ GBLA _SBytes ;// Number of scratch bytes on stack
+ GBLA _ABytes ;// Stack offset of next argument
+ GBLA _Workspace ;// Stack offset of scratch workspace
+ GBLA _F ;// Function number
+ GBLA _StOff ;// Struct offset
+ GBLA _SwNum ;// Switch number
+ GBLS _32 ;// Suffix for 32 byte alignmnet
+ GBLS _16 ;// Suffix for 16 byte alignmnet
+
+_InFunc SETL {FALSE}
+_SBytes SETA 0
+_F SETA 0
+_SwNum SETA 0
+_32 SETS "ALIGN32"
+_16 SETS "ALIGN16"
+
+;/////////////////////////////////////////////////////////
+;// Override the tools settings of the CPU if the #define
+;// USECPU is set, otherwise use the CPU defined by the
+;// assembler settings.
+;/////////////////////////////////////////////////////////
+
+ IF :DEF: OVERRIDECPU
+_CPU SETS OVERRIDECPU
+ ELSE
+_CPU SETS {CPU}
+ ENDIF
+
+
+
+;/////////////////////////////////////////////////////////
+;// Work out which code to build
+;/////////////////////////////////////////////////////////
+
+ IF :DEF:ARM1136JS:LOR::DEF:CortexA8:LOR::DEF:ARM_GENERIC
+ INFO 1,"Please switch to using M_VARIANTS"
+ ENDIF
+
+ ;// Define and reset all officially recongnised variants
+ MACRO
+ _M_DEF_VARIANTS
+ _M_DEF_VARIANT ARM926EJS
+ _M_DEF_VARIANT ARM1136JS
+ _M_DEF_VARIANT ARM1136JS_U
+ _M_DEF_VARIANT CortexA8
+ _M_DEF_VARIANT ARM7TDMI
+ MEND
+
+ MACRO
+ _M_DEF_VARIANT $var
+ GBLL $var
+ GBLL _ok$var
+$var SETL {FALSE}
+ MEND
+
+
+ ;// Variant declaration
+ ;//
+ ;// Define a list of code variants supported by this
+ ;// source file. This macro then chooses the most
+ ;// appropriate variant to build for the currently configured
+ ;// core.
+ ;//
+ MACRO
+ M_VARIANTS $v0,$v1,$v2,$v3,$v4,$v5,$v6,$v7
+ ;// Set to TRUE variants that are supported
+ _M_DEF_VARIANTS
+ _M_VARIANT $v0
+ _M_VARIANT $v1
+ _M_VARIANT $v2
+ _M_VARIANT $v3
+ _M_VARIANT $v4
+ _M_VARIANT $v5
+ _M_VARIANT $v6
+ _M_VARIANT $v7
+
+ ;// Look for first available variant to match a CPU
+ ;// _M_TRY cpu, variant fall back list
+_Variant SETS ""
+ _M_TRY ARM926EJ-S, ARM926EJS
+ _M_TRY ARM1176JZ-S, ARM1136JS
+ _M_TRY ARM1176JZF-S, ARM1136JS
+ _M_TRY ARM1156T2-S, ARM1136JS
+ _M_TRY ARM1156T2F-S, ARM1136JS
+ _M_TRY ARM1136J-S, ARM1136JS
+ _M_TRY ARM1136JF-S, ARM1136JS
+ _M_TRY MPCore, ARM1136JS
+ _M_TRY falcon-vfp, ARM1136JS
+ _M_TRY falcon-full-neon, CortexA8
+ _M_TRY Cortex-A8NoNeon, ARM1136JS
+ _M_TRY Cortex-A8, CortexA8, ARM1136JS
+ _M_TRY Cortex-R4, ARM1136JS
+ _M_TRY ARM7TDMI
+
+ ;// Select the correct variant
+ _M_DEF_VARIANTS
+ IF _Variant=""
+ INFO 1, "No match found for CPU '$_CPU'"
+ ELSE
+$_Variant SETL {TRUE}
+ ENDIF
+ MEND
+
+ ;// Register a variant as available
+ MACRO
+ _M_VARIANT $var
+ IF "$var"=""
+ MEXIT
+ ENDIF
+ IF :LNOT::DEF:_ok$var
+ INFO 1, "Unrecognized variant '$var'"
+ ENDIF
+$var SETL {TRUE}
+ MEND
+
+ ;// For a given CPU, see if any of the variants supporting
+ ;// this CPU are available. The first available variant is
+ ;// chosen
+ MACRO
+ _M_TRY $cpu, $v0,$v1,$v2,$v3,$v4,$v5,$v6,$v7
+ IF "$cpu"<>_CPU
+ MEXIT
+ ENDIF
+ _M_TRY1 $v0
+ _M_TRY1 $v1
+ _M_TRY1 $v2
+ _M_TRY1 $v3
+ _M_TRY1 $v4
+ _M_TRY1 $v5
+ _M_TRY1 $v6
+ _M_TRY1 $v7
+ ;// Check a match was found
+ IF _Variant=""
+ INFO 1, "No variant match found for CPU '$_CPU'"
+ ENDIF
+ MEND
+
+ MACRO
+ _M_TRY1 $var
+ IF "$var"=""
+ MEXIT
+ ENDIF
+ IF (_Variant=""):LAND:$var
+_Variant SETS "$var"
+ ENDIF
+ MEND
+
+;////////////////////////////////////////////////////////
+;// Structure definition
+;////////////////////////////////////////////////////////
+
+ ;// Declare a structure of given name
+ MACRO
+ M_STRUCT $sname
+_Struct SETS "$sname"
+_StOff SETA 0
+ MEND
+
+ ;// Declare a structure field
+ ;// The field is called $sname_$fname
+ ;// $size = the size of each entry, must be power of 2
+ ;// $number = (if provided) the number of entries for an array
+ MACRO
+ M_FIELD $fname, $size, $number
+ IF (_StOff:AND:($size-1))!=0
+_StOff SETA _StOff + ($size - (_StOff:AND:($size-1)))
+ ENDIF
+$_Struct._$fname EQU _StOff
+ IF "$number"<>""
+_StOff SETA _StOff + $size*$number
+ ELSE
+_StOff SETA _StOff + $size
+ ENDIF
+ MEND
+
+
+ MACRO
+ M_ENDSTRUCT
+sizeof_$_Struct EQU _StOff
+_Struct SETS ""
+ MEND
+
+;//////////////////////////////////////////////////////////
+;// Switch and table macros
+;//////////////////////////////////////////////////////////
+
+ ;// Start a relative switch table with register to switch on
+ ;//
+ ;// $v = the register to switch on
+ ;// $s = if specified must be "L" to indicate long
+ ;// this allows a greater range to the case code
+ MACRO
+ M_SWITCH $v, $s
+ ASSERT "$s"="":LOR:"$s"="L"
+_SwLong SETL {FALSE}
+ IF "$s"="L"
+_SwLong SETL {TRUE}
+ ENDIF
+_SwNum SETA _SwNum+1
+ IF {CONFIG}=16
+ ;// Thumb
+ IF _SwLong
+ TBH [pc, $v, LSL#1]
+ ELSE
+ TBB [pc, $v]
+ ENDIF
+_Switch$_SwNum
+ ELSE
+ ;// ARM
+ ADD pc, pc, $v, LSL #2
+ NOP
+ ENDIF
+ MEND
+
+ ;// Add a case to the switch statement
+ MACRO
+ M_CASE $label
+ IF {CONFIG}=16
+ ;// Thumb
+ IF _SwLong
+ DCW ($label - _Switch$_SwNum)/2
+ ELSE
+ DCB ($label - _Switch$_SwNum)/2
+ ENDIF
+ ELSE
+ ;// ARM
+ B $label
+ ENDIF
+ MEND
+
+ ;// End of switch statement
+ MACRO
+ M_ENDSWITCH
+ ALIGN 2
+ MEND
+
+
+;////////////////////////////////////////////////////////
+;// Data area allocation
+;////////////////////////////////////////////////////////
+
+ ;// Constant table allocator macro
+ ;//
+ ;// Creates a new section for each constant table
+ ;// $name is symbol through which the table can be accessed.
+ ;// $align is the optional alignment of the table, log2 of
+ ;// the byte alignment - $align=4 is 16 byte aligned
+ MACRO
+ M_TABLE $name, $align
+ ASSERT :LNOT:_InFunc
+ IF "$align"=""
+ AREA |.constdata|, READONLY, DATA
+ ELSE
+ ;// AREAs inherit the alignment of the first declaration.
+ ;// Therefore for each alignment size we must have an area
+ ;// of a different name.
+ AREA constdata_a$align, READONLY, DATA, ALIGN=$align
+
+ ;// We also force alignment incase we are tagging onto
+ ;// an already started area.
+ ALIGN (1<<$align)
+ ENDIF
+$name
+ MEND
+
+;/////////////////////////////////////////////////////
+;// Macros to allocate space on the stack
+;//
+;// These all assume that the stack is 8-byte aligned
+;// at entry to the function, which means that the
+;// 32-byte alignment macro needs to work in a
+;// bit more of a special way...
+;/////////////////////////////////////////////////////
+
+
+
+
+ ;// Allocate 1-byte aligned area of name
+ ;// $name size $size bytes.
+ MACRO
+ M_ALLOC1 $name, $size
+ ASSERT :LNOT:_InFunc
+$name$_F EQU _SBytes
+_SBytes SETA _SBytes + ($size)
+ MEND
+
+ ;// Allocate 2-byte aligned area of name
+ ;// $name size $size bytes.
+ MACRO
+ M_ALLOC2 $name, $size
+ ASSERT :LNOT:_InFunc
+ IF (_SBytes:AND:1)!=0
+_SBytes SETA _SBytes + (2 - (_SBytes:AND:1))
+ ENDIF
+$name$_F EQU _SBytes
+_SBytes SETA _SBytes + ($size)
+ MEND
+
+ ;// Allocate 4-byte aligned area of name
+ ;// $name size $size bytes.
+ MACRO
+ M_ALLOC4 $name, $size
+ ASSERT :LNOT:_InFunc
+ IF (_SBytes:AND:3)!=0
+_SBytes SETA _SBytes + (4 - (_SBytes:AND:3))
+ ENDIF
+$name$_F EQU _SBytes
+_SBytes SETA _SBytes + ($size)
+ MEND
+
+ ;// Allocate 8-byte aligned area of name
+ ;// $name size $size bytes.
+ MACRO
+ M_ALLOC8 $name, $size
+ ASSERT :LNOT:_InFunc
+ IF (_SBytes:AND:7)!=0
+_SBytes SETA _SBytes + (8 - (_SBytes:AND:7))
+ ENDIF
+$name$_F EQU _SBytes
+_SBytes SETA _SBytes + ($size)
+ MEND
+
+
+ ;// Allocate 8-byte aligned area of name
+ ;// $name size ($size+16) bytes.
+ ;// The extra 16 bytes are later used to align the pointer to 16 bytes
+
+ MACRO
+ M_ALLOC16 $name, $size
+ ASSERT :LNOT:_InFunc
+ IF (_SBytes:AND:7)!=0
+_SBytes SETA _SBytes + (8 - (_SBytes:AND:7))
+ ENDIF
+$name$_F$_16 EQU (_SBytes + 8)
+_SBytes SETA _SBytes + ($size) + 8
+ MEND
+
+ ;// Allocate 8-byte aligned area of name
+ ;// $name size ($size+32) bytes.
+ ;// The extra 32 bytes are later used to align the pointer to 32 bytes
+
+ MACRO
+ M_ALLOC32 $name, $size
+ ASSERT :LNOT:_InFunc
+ IF (_SBytes:AND:7)!=0
+_SBytes SETA _SBytes + (8 - (_SBytes:AND:7))
+ ENDIF
+$name$_F$_32 EQU (_SBytes + 24)
+_SBytes SETA _SBytes + ($size) + 24
+ MEND
+
+
+
+
+ ;// Argument Declaration Macro
+ ;//
+ ;// Allocate an argument name $name
+ ;// size $size bytes
+ MACRO
+ M_ARG $name, $size
+ ASSERT _InFunc
+$name$_F EQU _ABytes
+_ABytes SETA _ABytes + ($size)
+ MEND
+
+;///////////////////////////////////////////////
+;// Macros to access stacked variables
+;///////////////////////////////////////////////
+
+ ;// Macro to perform a data processing operation
+ ;// with a constant second operand
+ MACRO
+ _M_OPC $op,$rd,$rn,$const
+ LCLA _sh
+ LCLA _cst
+_sh SETA 0
+_cst SETA $const
+ IF _cst=0
+ $op $rd, $rn, #_cst
+ MEXIT
+ ENDIF
+ WHILE (_cst:AND:3)=0
+_cst SETA _cst>>2
+_sh SETA _sh+2
+ WEND
+ $op $rd, $rn, #(_cst:AND:0x000000FF)<<_sh
+ IF _cst>=256
+ $op $rd, $rd, #(_cst:AND:0xFFFFFF00)<<_sh
+ ENDIF
+ MEND
+
+ ;// Macro to perform a data access operation
+ ;// Such as LDR or STR
+ ;// The addressing mode is modified such that
+ ;// 1. If no address is given then the name is taken
+ ;// as a stack offset
+ ;// 2. If the addressing mode is not available for the
+ ;// state being assembled for (eg Thumb) then a suitable
+ ;// addressing mode is substituted.
+ ;//
+ ;// On Entry:
+ ;// $i = Instruction to perform (eg "LDRB")
+ ;// $a = Required byte alignment
+ ;// $r = Register(s) to transfer (eg "r1")
+ ;// $a0,$a1,$a2. Addressing mode and condition. One of:
+ ;// label {,cc}
+ ;// [base] {,,,cc}
+ ;// [base, offset]{!} {,,cc}
+ ;// [base, offset, shift]{!} {,cc}
+ ;// [base], offset {,,cc}
+ ;// [base], offset, shift {,cc}
+ MACRO
+ _M_DATA $i,$a,$r,$a0,$a1,$a2,$a3
+ IF "$a0":LEFT:1="["
+ IF "$a1"=""
+ $i$a3 $r, $a0
+ ELSE
+ IF "$a0":RIGHT:1="]"
+ IF "$a2"=""
+ _M_POSTIND $i$a3, "$r", $a0, $a1
+ ELSE
+ _M_POSTIND $i$a3, "$r", $a0, "$a1,$a2"
+ ENDIF
+ ELSE
+ IF "$a2"=""
+ _M_PREIND $i$a3, "$r", $a0, $a1
+ ELSE
+ _M_PREIND $i$a3, "$r", $a0, "$a1,$a2"
+ ENDIF
+ ENDIF
+ ENDIF
+ ELSE
+ LCLA _Offset
+_Offset SETA _Workspace + $a0$_F
+ ASSERT (_Offset:AND:($a-1))=0
+ $i$a1 $r, [sp, #_Offset]
+ ENDIF
+ MEND
+
+ ;// Handle post indexed load/stores
+ ;// op reg, [base], offset
+ MACRO
+ _M_POSTIND $i,$r,$a0,$a1
+ LCLS _base
+ LCLS _offset
+ IF {CONFIG}=16 ;// Thumb
+_base SETS ("$a0":LEFT:(:LEN:"$a0"-1)):RIGHT:(:LEN:"$a0"-2) ;// remove []
+_offset SETS "$a1"
+ IF _offset:LEFT:1="+"
+_offset SETS _offset:RIGHT:(:LEN:_offset-1)
+ ENDIF
+ $i $r, $a0
+ IF _offset:LEFT:1="-"
+_offset SETS _offset:RIGHT:(:LEN:_offset-1)
+ SUB $_base, $_base, $_offset
+ ELSE
+ ADD $_base, $_base, $_offset
+ ENDIF
+ ELSE ;// ARM
+ $i $r, $a0, $a1
+ ENDIF
+ MEND
+
+ ;// Handle pre indexed load/store
+ ;// op reg, [base, offset]{!}
+ MACRO
+ _M_PREIND $i,$r,$a0,$a1
+ LCLS _base
+ LCLS _offset
+ IF ({CONFIG}=16):LAND:(("$a1":RIGHT:2)="]!")
+_base SETS "$a0":RIGHT:(:LEN:("$a0")-1)
+_offset SETS "$a1":LEFT:(:LEN:("$a1")-2)
+ $i $r, [$_base, $_offset]
+ ADD $_base, $_base, $_offset
+ ELSE
+ $i $r, $a0, $a1
+ ENDIF
+ MEND
+
+ ;// Load unsigned byte from stack
+ MACRO
+ M_LDRB $r,$a0,$a1,$a2,$a3
+ _M_DATA "LDRB",1,$r,$a0,$a1,$a2,$a3
+ MEND
+
+ ;// Load signed byte from stack
+ MACRO
+ M_LDRSB $r,$a0,$a1,$a2,$a3
+ _M_DATA "LDRSB",1,$r,$a0,$a1,$a2,$a3
+ MEND
+
+ ;// Store byte to stack
+ MACRO
+ M_STRB $r,$a0,$a1,$a2,$a3
+ _M_DATA "STRB",1,$r,$a0,$a1,$a2,$a3
+ MEND
+
+ ;// Load unsigned half word from stack
+ MACRO
+ M_LDRH $r,$a0,$a1,$a2,$a3
+ _M_DATA "LDRH",2,$r,$a0,$a1,$a2,$a3
+ MEND
+
+ ;// Load signed half word from stack
+ MACRO
+ M_LDRSH $r,$a0,$a1,$a2,$a3
+ _M_DATA "LDRSH",2,$r,$a0,$a1,$a2,$a3
+ MEND
+
+ ;// Store half word to stack
+ MACRO
+ M_STRH $r,$a0,$a1,$a2,$a3
+ _M_DATA "STRH",2,$r,$a0,$a1,$a2,$a3
+ MEND
+
+ ;// Load word from stack
+ MACRO
+ M_LDR $r,$a0,$a1,$a2,$a3
+ _M_DATA "LDR",4,$r,$a0,$a1,$a2,$a3
+ MEND
+
+ ;// Store word to stack
+ MACRO
+ M_STR $r,$a0,$a1,$a2,$a3
+ _M_DATA "STR",4,$r,$a0,$a1,$a2,$a3
+ MEND
+
+ ;// Load double word from stack
+ MACRO
+ M_LDRD $r0,$r1,$a0,$a1,$a2,$a3
+ _M_DATA "LDRD",8,"$r0,$r1",$a0,$a1,$a2,$a3
+ MEND
+
+ ;// Store double word to stack
+ MACRO
+ M_STRD $r0,$r1,$a0,$a1,$a2,$a3
+ _M_DATA "STRD",8,"$r0,$r1",$a0,$a1,$a2,$a3
+ MEND
+
+ ;// Get absolute address of stack allocated location
+ MACRO
+ M_ADR $a, $b, $cc
+ _M_OPC ADD$cc, $a, sp, (_Workspace + $b$_F)
+ MEND
+
+ ;// Get absolute address of stack allocated location and align the address to 16 bytes
+ MACRO
+ M_ADR16 $a, $b, $cc
+ _M_OPC ADD$cc, $a, sp, (_Workspace + $b$_F$_16)
+
+ ;// Now align $a to 16 bytes
+ BIC$cc $a,$a,#0x0F
+ MEND
+
+ ;// Get absolute address of stack allocated location and align the address to 32 bytes
+ MACRO
+ M_ADR32 $a, $b, $cc
+ _M_OPC ADD$cc, $a, sp, (_Workspace + $b$_F$_32)
+
+ ;// Now align $a to 32 bytes
+ BIC$cc $a,$a,#0x1F
+ MEND
+
+;//////////////////////////////////////////////////////////
+;// Function header and footer macros
+;//////////////////////////////////////////////////////////
+
+ ;// Function Header Macro
+ ;// Generates the function prologue
+ ;// Note that functions should all be "stack-moves-once"
+ ;// The FNSTART and FNEND macros should be the only places
+ ;// where the stack moves.
+ ;//
+ ;// $name = function name
+ ;// $rreg = "" don't stack any registers
+ ;// "lr" stack "lr" only
+ ;// "rN" stack registers "r4-rN,lr"
+ ;// $dreg = "" don't stack any D registers
+ ;// "dN" stack registers "d8-dN"
+ ;//
+ ;// Note: ARM Archicture procedure call standard AAPCS
+ ;// states that r4-r11, sp, d8-d15 must be preserved by
+ ;// a compliant function.
+ MACRO
+ M_START $name, $rreg, $dreg
+ ASSERT :LNOT:_InFunc
+ ASSERT "$name"!=""
+_InFunc SETL {TRUE}
+_RBytes SETA 0
+_Workspace SETA 0
+
+ ;// Create an area for the function
+ AREA |.text|, CODE
+ EXPORT $name
+$name FUNCTION
+
+ ;// Save R registers
+ _M_GETRREGLIST $rreg
+ IF _RRegList<>""
+ STMFD sp!, {$_RRegList, lr}
+ ENDIF
+
+ ;// Save D registers
+ _M_GETDREGLIST $dreg
+ IF _DRegList<>""
+ VSTMFD sp!, {$_DRegList}
+ ENDIF
+
+
+ ;// Ensure size claimed on stack is 8-byte aligned
+ IF ((_SBytes:AND:7)!=0)
+_SBytes SETA _SBytes + (8 - (_SBytes:AND:7))
+ ENDIF
+
+ IF (_SBytes!=0)
+ _M_OPC SUB, sp, sp, _SBytes
+ ENDIF
+
+
+_ABytes SETA _SBytes + _RBytes - _Workspace
+
+
+ ;// Print function name if debug enabled
+ M_PRINTF "$name\n",
+ MEND
+
+ ;// Work out a list of R saved registers
+ MACRO
+ _M_GETRREGLIST $rreg
+ IF "$rreg"=""
+_RRegList SETS ""
+ MEXIT
+ ENDIF
+ IF "$rreg"="lr":LOR:"$rreg"="r4"
+_RRegList SETS "r4"
+_RBytes SETA _RBytes+8
+ MEXIT
+ ENDIF
+ IF "$rreg"="r5":LOR:"$rreg"="r6"
+_RRegList SETS "r4-r6"
+_RBytes SETA _RBytes+16
+ MEXIT
+ ENDIF
+ IF "$rreg"="r7":LOR:"$rreg"="r8"
+_RRegList SETS "r4-r8"
+_RBytes SETA _RBytes+24
+ MEXIT
+ ENDIF
+ IF "$rreg"="r9":LOR:"$rreg"="r10"
+_RRegList SETS "r4-r10"
+_RBytes SETA _RBytes+32
+ MEXIT
+ ENDIF
+ IF "$rreg"="r11":LOR:"$rreg"="r12"
+_RRegList SETS "r4-r12"
+_RBytes SETA _RBytes+40
+ MEXIT
+ ENDIF
+ INFO 1, "Unrecognized saved r register limit '$rreg'"
+ MEND
+
+ ;// Work out a list of D saved registers
+ MACRO
+ _M_GETDREGLIST $dreg
+ IF "$dreg"=""
+_DRegList SETS ""
+ MEXIT
+ ENDIF
+ IF "$dreg"="d8"
+_DRegList SETS "d8"
+_RBytes SETA _RBytes+8
+ MEXIT
+ ENDIF
+ IF "$dreg"="d9"
+_DRegList SETS "d8-d9"
+_RBytes SETA _RBytes+16
+ MEXIT
+ ENDIF
+ IF "$dreg"="d10"
+_DRegList SETS "d8-d10"
+_RBytes SETA _RBytes+24
+ MEXIT
+ ENDIF
+ IF "$dreg"="d11"
+_DRegList SETS "d8-d11"
+_RBytes SETA _RBytes+32
+ MEXIT
+ ENDIF
+ IF "$dreg"="d12"
+_DRegList SETS "d8-d12"
+_RBytes SETA _RBytes+40
+ MEXIT
+ ENDIF
+ IF "$dreg"="d13"
+_DRegList SETS "d8-d13"
+_RBytes SETA _RBytes+48
+ MEXIT
+ ENDIF
+ IF "$dreg"="d14"
+_DRegList SETS "d8-d14"
+_RBytes SETA _RBytes+56
+ MEXIT
+ ENDIF
+ IF "$dreg"="d15"
+_DRegList SETS "d8-d15"
+_RBytes SETA _RBytes+64
+ MEXIT
+ ENDIF
+ INFO 1, "Unrecognized saved d register limit '$dreg'"
+ MEND
+
+ ;// Produce function return instructions
+ MACRO
+ _M_RET $cc
+ IF _DRegList<>""
+ VPOP$cc {$_DRegList}
+ ENDIF
+ IF _RRegList=""
+ BX$cc lr
+ ELSE
+ LDM$cc.FD sp!, {$_RRegList, pc}
+ ENDIF
+ MEND
+
+ ;// Early Function Exit Macro
+ ;// $cc = condition to exit with
+ ;// (Example: M_EXIT EQ)
+ MACRO
+ M_EXIT $cc
+ ASSERT _InFunc
+ IF _SBytes!=0
+ ;// Restore stack frame and exit
+ B$cc _End$_F
+ ELSE
+ ;// Can return directly
+ _M_RET $cc
+ ENDIF
+ MEND
+
+ ;// Function Footer Macro
+ ;// Generates the function epilogue
+ MACRO
+ M_END
+ ASSERT _InFunc
+_InFunc SETL {FALSE}
+_End$_F
+
+ ;// Restore the stack pointer to its original value on function entry
+ IF _SBytes!=0
+ _M_OPC ADD, sp, sp, _SBytes
+ ENDIF
+ _M_RET
+ ENDFUNC
+
+ ;// Reset the global stack tracking variables back to their
+ ;// initial values, and increment the function count
+_SBytes SETA 0
+_F SETA _F+1
+ MEND
+
+
+;//==========================================================================
+;// Debug Macros
+;//==========================================================================
+
+ GBLL DEBUG_ON
+DEBUG_ON SETL {FALSE}
+ GBLL DEBUG_STALLS_ON
+DEBUG_STALLS_ON SETL {FALSE}
+
+ ;//==========================================================================
+ ;// Debug call to printf
+ ;// M_PRINTF $format, $val0, $val1, $val2
+ ;//
+ ;// Examples:
+ ;// M_PRINTF "x=%08x\n", r0
+ ;//
+ ;// This macro preserves the value of all registers including the
+ ;// flags.
+ ;//==========================================================================
+
+ MACRO
+ M_PRINTF $format, $val0, $val1, $val2
+ IF DEBUG_ON
+
+ IMPORT printf
+ LCLA nArgs
+nArgs SETA 0
+
+ ;// save registers so we don't corrupt them
+ STMFD sp!, {r0-r12, lr}
+
+ ;// Drop stack to give us some workspace
+ SUB sp, sp, #16
+
+ ;// Save registers we need to print to the stack
+ IF "$val2" <> ""
+ ASSERT "$val1" <> ""
+ STR $val2, [sp, #8]
+nArgs SETA nArgs+1
+ ENDIF
+ IF "$val1" <> ""
+ ASSERT "$val0" <> ""
+ STR $val1, [sp, #4]
+nArgs SETA nArgs+1
+ ENDIF
+ IF "$val0"<>""
+ STR $val0, [sp]
+nArgs SETA nArgs+1
+ ENDIF
+
+ ;// Now we are safe to corrupt registers
+ ADR r0, %FT00
+ IF nArgs=1
+ LDR r1, [sp]
+ ENDIF
+ IF nArgs=2
+ LDMIA sp, {r1,r2}
+ ENDIF
+ IF nArgs=3
+ LDMIA sp, {r1,r2,r3}
+ ENDIF
+
+ ;// print the values
+ MRS r4, cpsr ;// preserve flags
+ BL printf
+ MSR cpsr_f, r4 ;// restore flags
+ B %FT01
+00 ;// string to print
+ DCB "$format", 0
+ ALIGN
+01 ;// Finished
+ ADD sp, sp, #16
+ ;// Restore registers
+ LDMFD sp!, {r0-r12,lr}
+
+ ENDIF ;// DEBUG_ON
+ MEND
+
+
+ ;// Stall Simulation Macro
+ ;// Inserts a given number of NOPs for the currently
+ ;// defined platform
+ MACRO
+ M_STALL $plat1stall, $plat2stall, $plat3stall, $plat4stall, $plat5stall, $plat6stall
+ IF DEBUG_STALLS_ON
+ _M_STALL_SUB $plat1stall
+ _M_STALL_SUB $plat2stall
+ _M_STALL_SUB $plat3stall
+ _M_STALL_SUB $plat4stall
+ _M_STALL_SUB $plat5stall
+ _M_STALL_SUB $plat6stall
+ ENDIF
+ MEND
+
+ MACRO
+ _M_STALL_SUB $platstall
+ IF "$platstall"!=""
+ LCLA _pllen
+ LCLS _pl
+ LCLL _pllog
+_pllen SETA :LEN:"$platstall"
+_pl SETS "$platstall":LEFT:(_pllen - 2)
+ IF :DEF:$_pl
+ IF $_pl
+ LCLS _st
+ LCLA _stnum
+_st SETS "$platstall":RIGHT:1
+_stnum SETA $_st
+ WHILE _stnum>0
+ MOV sp, sp
+_stnum SETA _stnum - 1
+ WEND
+ ENDIF
+ ENDIF
+ ENDIF
+ MEND
+
+
+
+;//==========================================================================
+;// Endian Invarience Macros
+;//
+;// The idea behind these macros is that if an array is
+;// loaded as words then the SMUL00 macro will multiply
+;// array elements 0 regardless of the endianess of the
+;// system. For little endian SMUL00=SMULBB, for big
+;// endian SMUL00=SMULTT and similarly for other packed operations.
+;//
+;//==========================================================================
+
+ MACRO
+ LIBI4 $comli, $combi, $a, $b, $c, $d, $cc
+ IF {ENDIAN}="big"
+ $combi.$cc $a, $b, $c, $d
+ ELSE
+ $comli.$cc $a, $b, $c, $d
+ ENDIF
+ MEND
+
+ MACRO
+ LIBI3 $comli, $combi, $a, $b, $c, $cc
+ IF {ENDIAN}="big"
+ $combi.$cc $a, $b, $c
+ ELSE
+ $comli.$cc $a, $b, $c
+ ENDIF
+ MEND
+
+ ;// SMLAxy macros
+
+ MACRO
+ SMLA00 $a, $b, $c, $d, $cc
+ LIBI4 SMLABB, SMLATT, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLA01 $a, $b, $c, $d, $cc
+ LIBI4 SMLABT, SMLATB, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLA0B $a, $b, $c, $d, $cc
+ LIBI4 SMLABB, SMLATB, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLA0T $a, $b, $c, $d, $cc
+ LIBI4 SMLABT, SMLATT, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLA10 $a, $b, $c, $d, $cc
+ LIBI4 SMLATB, SMLABT, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLA11 $a, $b, $c, $d, $cc
+ LIBI4 SMLATT, SMLABB, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLA1B $a, $b, $c, $d, $cc
+ LIBI4 SMLATB, SMLABB, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLA1T $a, $b, $c, $d, $cc
+ LIBI4 SMLATT, SMLABT, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLAB0 $a, $b, $c, $d, $cc
+ LIBI4 SMLABB, SMLABT, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLAB1 $a, $b, $c, $d, $cc
+ LIBI4 SMLABT, SMLABB, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLAT0 $a, $b, $c, $d, $cc
+ LIBI4 SMLATB, SMLATT, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLAT1 $a, $b, $c, $d, $cc
+ LIBI4 SMLATT, SMLATB, $a, $b, $c, $d, $cc
+ MEND
+
+ ;// SMULxy macros
+
+ MACRO
+ SMUL00 $a, $b, $c, $cc
+ LIBI3 SMULBB, SMULTT, $a, $b, $c, $cc
+ MEND
+
+ MACRO
+ SMUL01 $a, $b, $c, $cc
+ LIBI3 SMULBT, SMULTB, $a, $b, $c, $cc
+ MEND
+
+ MACRO
+ SMUL0B $a, $b, $c, $cc
+ LIBI3 SMULBB, SMULTB, $a, $b, $c, $cc
+ MEND
+
+ MACRO
+ SMUL0T $a, $b, $c, $cc
+ LIBI3 SMULBT, SMULTT, $a, $b, $c, $cc
+ MEND
+
+ MACRO
+ SMUL10 $a, $b, $c, $cc
+ LIBI3 SMULTB, SMULBT, $a, $b, $c, $cc
+ MEND
+
+ MACRO
+ SMUL11 $a, $b, $c, $cc
+ LIBI3 SMULTT, SMULBB, $a, $b, $c, $cc
+ MEND
+
+ MACRO
+ SMUL1B $a, $b, $c, $cc
+ LIBI3 SMULTB, SMULBB, $a, $b, $c, $cc
+ MEND
+
+ MACRO
+ SMUL1T $a, $b, $c, $cc
+ LIBI3 SMULTT, SMULBT, $a, $b, $c, $cc
+ MEND
+
+ MACRO
+ SMULB0 $a, $b, $c, $cc
+ LIBI3 SMULBB, SMULBT, $a, $b, $c, $cc
+ MEND
+
+ MACRO
+ SMULB1 $a, $b, $c, $cc
+ LIBI3 SMULBT, SMULBB, $a, $b, $c, $cc
+ MEND
+
+ MACRO
+ SMULT0 $a, $b, $c, $cc
+ LIBI3 SMULTB, SMULTT, $a, $b, $c, $cc
+ MEND
+
+ MACRO
+ SMULT1 $a, $b, $c, $cc
+ LIBI3 SMULTT, SMULTB, $a, $b, $c, $cc
+ MEND
+
+ ;// SMLAWx, SMULWx macros
+
+ MACRO
+ SMLAW0 $a, $b, $c, $d, $cc
+ LIBI4 SMLAWB, SMLAWT, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLAW1 $a, $b, $c, $d, $cc
+ LIBI4 SMLAWT, SMLAWB, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMULW0 $a, $b, $c, $cc
+ LIBI3 SMULWB, SMULWT, $a, $b, $c, $cc
+ MEND
+
+ MACRO
+ SMULW1 $a, $b, $c, $cc
+ LIBI3 SMULWT, SMULWB, $a, $b, $c, $cc
+ MEND
+
+ ;// SMLALxy macros
+
+
+ MACRO
+ SMLAL00 $a, $b, $c, $d, $cc
+ LIBI4 SMLALBB, SMLALTT, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLAL01 $a, $b, $c, $d, $cc
+ LIBI4 SMLALBT, SMLALTB, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLAL0B $a, $b, $c, $d, $cc
+ LIBI4 SMLALBB, SMLALTB, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLAL0T $a, $b, $c, $d, $cc
+ LIBI4 SMLALBT, SMLALTT, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLAL10 $a, $b, $c, $d, $cc
+ LIBI4 SMLALTB, SMLALBT, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLAL11 $a, $b, $c, $d, $cc
+ LIBI4 SMLALTT, SMLALBB, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLAL1B $a, $b, $c, $d, $cc
+ LIBI4 SMLALTB, SMLALBB, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLAL1T $a, $b, $c, $d, $cc
+ LIBI4 SMLALTT, SMLALBT, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLALB0 $a, $b, $c, $d, $cc
+ LIBI4 SMLALBB, SMLALBT, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLALB1 $a, $b, $c, $d, $cc
+ LIBI4 SMLALBT, SMLALBB, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLALT0 $a, $b, $c, $d, $cc
+ LIBI4 SMLALTB, SMLALTT, $a, $b, $c, $d, $cc
+ MEND
+
+ MACRO
+ SMLALT1 $a, $b, $c, $d, $cc
+ LIBI4 SMLALTT, SMLALTB, $a, $b, $c, $d, $cc
+ MEND
+
+ ENDIF ;// ARMCOMM_S_H
+
+ END
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armOMX.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armOMX.h
new file mode 100755
index 0000000..7a68d14
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armOMX.h
@@ -0,0 +1,274 @@
+/*
+ *
+ * File Name: armOMX_ReleaseVersion.h
+ * OpenMAX DL: v1.0.2
+ * Revision: 12290
+ * Date: Wednesday, April 9, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * This file allows a version of the OMX DL libraries to be built where some or
+ * all of the function names can be given a user specified suffix.
+ *
+ * You might want to use it where:
+ *
+ * - you want to rename a function "out of the way" so that you could replace
+ * a function with a different version (the original version would still be
+ * in the library just with a different name - so you could debug the new
+ * version by comparing it to the output of the old)
+ *
+ * - you want to rename all the functions to versions with a suffix so that
+ * you can include two versions of the library and choose between functions
+ * at runtime.
+ *
+ * e.g. omxIPBM_Copy_U8_C1R could be renamed omxIPBM_Copy_U8_C1R_CortexA8
+ *
+ */
+
+
+#ifndef _armOMX_H_
+#define _armOMX_H_
+
+
+/* We need to define these two macros in order to expand and concatenate the names */
+#define OMXCAT2BAR(A, B) omx ## A ## B
+#define OMXCATBAR(A, B) OMXCAT2BAR(A, B)
+
+/* Define the suffix to add to all functions - the default is no suffix */
+#define BARE_SUFFIX
+
+
+
+/* Define what happens to the bare suffix-less functions, down to the sub-domain accuracy */
+#define OMXACAAC_SUFFIX BARE_SUFFIX
+#define OMXACMP3_SUFFIX BARE_SUFFIX
+#define OMXICJP_SUFFIX BARE_SUFFIX
+#define OMXIPBM_SUFFIX BARE_SUFFIX
+#define OMXIPCS_SUFFIX BARE_SUFFIX
+#define OMXIPPP_SUFFIX BARE_SUFFIX
+#define OMXSP_SUFFIX BARE_SUFFIX
+#define OMXVCCOMM_SUFFIX BARE_SUFFIX
+#define OMXVCM4P10_SUFFIX BARE_SUFFIX
+#define OMXVCM4P2_SUFFIX BARE_SUFFIX
+
+
+
+
+/* Define what the each bare, un-suffixed OpenMAX API function names is to be renamed */
+#define omxACAAC_DecodeChanPairElt OMXCATBAR(ACAAC_DecodeChanPairElt, OMXACAAC_SUFFIX)
+#define omxACAAC_DecodeDatStrElt OMXCATBAR(ACAAC_DecodeDatStrElt, OMXACAAC_SUFFIX)
+#define omxACAAC_DecodeFillElt OMXCATBAR(ACAAC_DecodeFillElt, OMXACAAC_SUFFIX)
+#define omxACAAC_DecodeIsStereo_S32 OMXCATBAR(ACAAC_DecodeIsStereo_S32, OMXACAAC_SUFFIX)
+#define omxACAAC_DecodeMsPNS_S32_I OMXCATBAR(ACAAC_DecodeMsPNS_S32_I, OMXACAAC_SUFFIX)
+#define omxACAAC_DecodeMsStereo_S32_I OMXCATBAR(ACAAC_DecodeMsStereo_S32_I, OMXACAAC_SUFFIX)
+#define omxACAAC_DecodePrgCfgElt OMXCATBAR(ACAAC_DecodePrgCfgElt, OMXACAAC_SUFFIX)
+#define omxACAAC_DecodeTNS_S32_I OMXCATBAR(ACAAC_DecodeTNS_S32_I, OMXACAAC_SUFFIX)
+#define omxACAAC_DeinterleaveSpectrum_S32 OMXCATBAR(ACAAC_DeinterleaveSpectrum_S32, OMXACAAC_SUFFIX)
+#define omxACAAC_EncodeTNS_S32_I OMXCATBAR(ACAAC_EncodeTNS_S32_I, OMXACAAC_SUFFIX)
+#define omxACAAC_LongTermPredict_S32 OMXCATBAR(ACAAC_LongTermPredict_S32, OMXACAAC_SUFFIX)
+#define omxACAAC_LongTermReconstruct_S32_I OMXCATBAR(ACAAC_LongTermReconstruct_S32_I, OMXACAAC_SUFFIX)
+#define omxACAAC_MDCTFwd_S32 OMXCATBAR(ACAAC_MDCTFwd_S32, OMXACAAC_SUFFIX)
+#define omxACAAC_MDCTInv_S32_S16 OMXCATBAR(ACAAC_MDCTInv_S32_S16, OMXACAAC_SUFFIX)
+#define omxACAAC_NoiselessDecode OMXCATBAR(ACAAC_NoiselessDecode, OMXACAAC_SUFFIX)
+#define omxACAAC_QuantInv_S32_I OMXCATBAR(ACAAC_QuantInv_S32_I, OMXACAAC_SUFFIX)
+#define omxACAAC_UnpackADIFHeader OMXCATBAR(ACAAC_UnpackADIFHeader, OMXACAAC_SUFFIX)
+#define omxACAAC_UnpackADTSFrameHeader OMXCATBAR(ACAAC_UnpackADTSFrameHeader, OMXACAAC_SUFFIX)
+
+
+#define omxACMP3_HuffmanDecode_S32 OMXCATBAR(ACMP3_HuffmanDecode_S32, OMXACMP3_SUFFIX)
+#define omxACMP3_HuffmanDecodeSfb_S32 OMXCATBAR(ACMP3_HuffmanDecodeSfb_S32, OMXACMP3_SUFFIX)
+#define omxACMP3_HuffmanDecodeSfbMbp_S32 OMXCATBAR(ACMP3_HuffmanDecodeSfbMbp_S32, OMXACMP3_SUFFIX)
+#define omxACMP3_MDCTInv_S32 OMXCATBAR(ACMP3_MDCTInv_S32, OMXACMP3_SUFFIX)
+#define omxACMP3_ReQuantize_S32_I OMXCATBAR(ACMP3_ReQuantize_S32_I, OMXACMP3_SUFFIX)
+#define omxACMP3_ReQuantizeSfb_S32_I OMXCATBAR(ACMP3_ReQuantizeSfb_S32_I, OMXACMP3_SUFFIX)
+#define omxACMP3_SynthPQMF_S32_S16 OMXCATBAR(ACMP3_SynthPQMF_S32_S16, OMXACMP3_SUFFIX)
+#define omxACMP3_UnpackFrameHeader OMXCATBAR(ACMP3_UnpackFrameHeader, OMXACMP3_SUFFIX)
+#define omxACMP3_UnpackScaleFactors_S8 OMXCATBAR(ACMP3_UnpackScaleFactors_S8, OMXACMP3_SUFFIX)
+#define omxACMP3_UnpackSideInfo OMXCATBAR(ACMP3_UnpackSideInfo, OMXACMP3_SUFFIX)
+
+#define omxICJP_CopyExpand_U8_C3 OMXCATBAR(ICJP_CopyExpand_U8_C3, OMXICJP_SUFFIX)
+#define omxICJP_DCTFwd_S16 OMXCATBAR(ICJP_DCTFwd_S16, OMXICJP_SUFFIX)
+#define omxICJP_DCTFwd_S16_I OMXCATBAR(ICJP_DCTFwd_S16_I, OMXICJP_SUFFIX)
+#define omxICJP_DCTInv_S16 OMXCATBAR(ICJP_DCTInv_S16, OMXICJP_SUFFIX)
+#define omxICJP_DCTInv_S16_I OMXCATBAR(ICJP_DCTInv_S16_I, OMXICJP_SUFFIX)
+#define omxICJP_DCTQuantFwd_Multiple_S16 OMXCATBAR(ICJP_DCTQuantFwd_Multiple_S16, OMXICJP_SUFFIX)
+#define omxICJP_DCTQuantFwd_S16 OMXCATBAR(ICJP_DCTQuantFwd_S16, OMXICJP_SUFFIX)
+#define omxICJP_DCTQuantFwd_S16_I OMXCATBAR(ICJP_DCTQuantFwd_S16_I, OMXICJP_SUFFIX)
+#define omxICJP_DCTQuantFwdTableInit OMXCATBAR(ICJP_DCTQuantFwdTableInit, OMXICJP_SUFFIX)
+#define omxICJP_DCTQuantInv_Multiple_S16 OMXCATBAR(ICJP_DCTQuantInv_Multiple_S16, OMXICJP_SUFFIX)
+#define omxICJP_DCTQuantInv_S16 OMXCATBAR(ICJP_DCTQuantInv_S16, OMXICJP_SUFFIX)
+#define omxICJP_DCTQuantInv_S16_I OMXCATBAR(ICJP_DCTQuantInv_S16_I, OMXICJP_SUFFIX)
+#define omxICJP_DCTQuantInvTableInit OMXCATBAR(ICJP_DCTQuantInvTableInit, OMXICJP_SUFFIX)
+#define omxICJP_DecodeHuffman8x8_Direct_S16_C1 OMXCATBAR(ICJP_DecodeHuffman8x8_Direct_S16_C1, OMXICJP_SUFFIX)
+#define omxICJP_DecodeHuffmanSpecGetBufSize_U8 OMXCATBAR(ICJP_DecodeHuffmanSpecGetBufSize_U8, OMXICJP_SUFFIX)
+#define omxICJP_DecodeHuffmanSpecInit_U8 OMXCATBAR(ICJP_DecodeHuffmanSpecInit_U8, OMXICJP_SUFFIX)
+#define omxICJP_EncodeHuffman8x8_Direct_S16_U1_C1 OMXCATBAR(ICJP_EncodeHuffman8x8_Direct_S16_U1_C1, OMXICJP_SUFFIX)
+#define omxICJP_EncodeHuffmanSpecGetBufSize_U8 OMXCATBAR(ICJP_EncodeHuffmanSpecGetBufSize_U8, OMXICJP_SUFFIX)
+#define omxICJP_EncodeHuffmanSpecInit_U8 OMXCATBAR(ICJP_EncodeHuffmanSpecInit_U8, OMXICJP_SUFFIX)
+
+#define omxIPBM_AddC_U8_C1R_Sfs OMXCATBAR(IPBM_AddC_U8_C1R_Sfs, OMXIPBM_SUFFIX)
+#define omxIPBM_Copy_U8_C1R OMXCATBAR(IPBM_Copy_U8_C1R, OMXIPBM_SUFFIX)
+#define omxIPBM_Copy_U8_C3R OMXCATBAR(IPBM_Copy_U8_C3R, OMXIPBM_SUFFIX)
+#define omxIPBM_Mirror_U8_C1R OMXCATBAR(IPBM_Mirror_U8_C1R, OMXIPBM_SUFFIX)
+#define omxIPBM_MulC_U8_C1R_Sfs OMXCATBAR(IPBM_MulC_U8_C1R_Sfs, OMXIPBM_SUFFIX)
+
+#define omxIPCS_ColorTwistQ14_U8_C3R OMXCATBAR(IPCS_ColorTwistQ14_U8_C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_BGR565ToYCbCr420LS_MCU_U16_S16_C3P3R OMXCATBAR(IPCS_BGR565ToYCbCr420LS_MCU_U16_S16_C3P3R, OMXIPCS_SUFFIX)
+#define omxIPCS_BGR565ToYCbCr422LS_MCU_U16_S16_C3P3R OMXCATBAR(IPCS_BGR565ToYCbCr422LS_MCU_U16_S16_C3P3R, OMXIPCS_SUFFIX)
+#define omxIPCS_BGR565ToYCbCr444LS_MCU_U16_S16_C3P3R OMXCATBAR(IPCS_BGR565ToYCbCr444LS_MCU_U16_S16_C3P3R, OMXIPCS_SUFFIX)
+#define omxIPCS_BGR888ToYCbCr420LS_MCU_U8_S16_C3P3R OMXCATBAR(IPCS_BGR888ToYCbCr420LS_MCU_U8_S16_C3P3R, OMXIPCS_SUFFIX)
+#define omxIPCS_BGR888ToYCbCr422LS_MCU_U8_S16_C3P3R OMXCATBAR(IPCS_BGR888ToYCbCr422LS_MCU_U8_S16_C3P3R, OMXIPCS_SUFFIX)
+#define omxIPCS_BGR888ToYCbCr444LS_MCU_U8_S16_C3P3R OMXCATBAR(IPCS_BGR888ToYCbCr444LS_MCU_U8_S16_C3P3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr420RszCscRotBGR_U8_P3C3R OMXCATBAR(IPCS_YCbCr420RszCscRotBGR_U8_P3C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr420RszRot_U8_P3R OMXCATBAR(IPCS_YCbCr420RszRot_U8_P3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr420ToBGR565_U8_U16_P3C3R OMXCATBAR(IPCS_YCbCr420ToBGR565_U8_U16_P3C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr420ToBGR565LS_MCU_S16_U16_P3C3R OMXCATBAR(IPCS_YCbCr420ToBGR565LS_MCU_S16_U16_P3C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr420ToBGR888LS_MCU_S16_U8_P3C3R OMXCATBAR(IPCS_YCbCr420ToBGR888LS_MCU_S16_U8_P3C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr422RszCscRotBGR_U8_P3C3R OMXCATBAR(IPCS_YCbCr422RszCscRotBGR_U8_P3C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_CbYCrY422RszCscRotBGR_U8_U16_C2R OMXCATBAR(IPCS_CbYCrY422RszCscRotBGR_U8_U16_C2R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr422RszRot_U8_P3R OMXCATBAR(IPCS_YCbCr422RszRot_U8_P3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbYCr422ToBGR565_U8_U16_C2C3R OMXCATBAR(IPCS_YCbYCr422ToBGR565_U8_U16_C2C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr422ToBGR565LS_MCU_S16_U16_P3C3R OMXCATBAR(IPCS_YCbCr422ToBGR565LS_MCU_S16_U16_P3C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbYCr422ToBGR888_U8_C2C3R OMXCATBAR(IPCS_YCbYCr422ToBGR888_U8_C2C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr422ToBGR888LS_MCU_S16_U8_P3C3R OMXCATBAR(IPCS_YCbCr422ToBGR888LS_MCU_S16_U8_P3C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr422ToBGR888LS_MCU_S16_U8_P3C3R OMXCATBAR(IPCS_YCbCr422ToBGR888LS_MCU_S16_U8_P3C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_CbYCrY422ToYCbCr420Rotate_U8_C2P3R OMXCATBAR(IPCS_CbYCrY422ToYCbCr420Rotate_U8_C2P3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr422ToYCbCr420Rotate_U8_P3R OMXCATBAR(IPCS_YCbCr422ToYCbCr420Rotate_U8_P3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr444ToBGR565_U8_U16_C3R OMXCATBAR(IPCS_YCbCr444ToBGR565_U8_U16_C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr444ToBGR565_U8_U16_P3C3R OMXCATBAR(IPCS_YCbCr444ToBGR565_U8_U16_P3C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr444ToBGR565LS_MCU_S16_U16_P3C3R OMXCATBAR(IPCS_YCbCr444ToBGR565LS_MCU_S16_U16_P3C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr444ToBGR888_U8_C3R OMXCATBAR(IPCS_YCbCr444ToBGR888_U8_C3R, OMXIPCS_SUFFIX)
+
+#define omxIPPP_Deblock_HorEdge_U8_I OMXCATBAR(IPPP_Deblock_HorEdge_U8_I, OMXIPPP_SUFFIX)
+#define omxIPPP_Deblock_VerEdge_U8_I OMXCATBAR(IPPP_Deblock_VerEdge_U8_I, OMXIPPP_SUFFIX)
+#define omxIPPP_FilterFIR_U8_C1R OMXCATBAR(IPPP_FilterFIR_U8_C1R, OMXIPPP_SUFFIX)
+#define omxIPPP_FilterMedian_U8_C1R OMXCATBAR(IPPP_FilterMedian_U8_C1R, OMXIPPP_SUFFIX)
+#define omxIPPP_GetCentralMoment_S64 OMXCATBAR(IPPP_GetCentralMoment_S64, OMXIPPP_SUFFIX)
+#define omxIPPP_GetSpatialMoment_S64 OMXCATBAR(IPPP_GetSpatialMoment_S64, OMXIPPP_SUFFIX)
+#define omxIPPP_MomentGetStateSize OMXCATBAR(IPPP_MomentGetStateSize, OMXIPPP_SUFFIX)
+#define omxIPPP_MomentInit OMXCATBAR(IPPP_MomentInit, OMXIPPP_SUFFIX)
+#define omxIPPP_Moments_U8_C1R OMXCATBAR(IPPP_Moments_U8_C1R, OMXIPPP_SUFFIX)
+#define omxIPPP_Moments_U8_C3R OMXCATBAR(IPPP_Moments_U8_C3R, OMXIPPP_SUFFIX)
+
+#define omxSP_BlockExp_S16 OMXCATBAR(SP_BlockExp_S16, OMXSP_SUFFIX)
+#define omxSP_BlockExp_S32 OMXCATBAR(SP_BlockExp_S32, OMXSP_SUFFIX)
+#define omxSP_Copy_S16 OMXCATBAR(SP_Copy_S16, OMXSP_SUFFIX)
+#define omxSP_DotProd_S16 OMXCATBAR(SP_DotProd_S16, OMXSP_SUFFIX)
+#define omxSP_DotProd_S16_Sfs OMXCATBAR(SP_DotProd_S16_Sfs, OMXSP_SUFFIX)
+#define omxSP_FFTFwd_CToC_SC16_Sfs OMXCATBAR(SP_FFTFwd_CToC_SC16_Sfs, OMXSP_SUFFIX)
+#define omxSP_FFTFwd_CToC_SC32_Sfs OMXCATBAR(SP_FFTFwd_CToC_SC32_Sfs, OMXSP_SUFFIX)
+#define omxSP_FFTFwd_RToCCS_S16S32_Sfs OMXCATBAR(SP_FFTFwd_RToCCS_S16S32_Sfs, OMXSP_SUFFIX)
+#define omxSP_FFTFwd_RToCCS_S32_Sfs OMXCATBAR(SP_FFTFwd_RToCCS_S32_Sfs, OMXSP_SUFFIX)
+#define omxSP_FFTGetBufSize_C_SC16 OMXCATBAR(SP_FFTGetBufSize_C_SC16, OMXSP_SUFFIX)
+#define omxSP_FFTGetBufSize_C_SC32 OMXCATBAR(SP_FFTGetBufSize_C_SC32, OMXSP_SUFFIX)
+#define omxSP_FFTGetBufSize_R_S16S32 OMXCATBAR(SP_FFTGetBufSize_R_S16S32, OMXSP_SUFFIX)
+#define omxSP_FFTGetBufSize_R_S32 OMXCATBAR(SP_FFTGetBufSize_R_S32, OMXSP_SUFFIX)
+#define omxSP_FFTInit_C_SC16 OMXCATBAR(SP_FFTInit_C_SC16, OMXSP_SUFFIX)
+#define omxSP_FFTInit_C_SC32 OMXCATBAR(SP_FFTInit_C_SC32, OMXSP_SUFFIX)
+#define omxSP_FFTInit_R_S16S32 OMXCATBAR(SP_FFTInit_R_S16S32, OMXSP_SUFFIX)
+#define omxSP_FFTInit_R_S32 OMXCATBAR(SP_FFTInit_R_S32, OMXSP_SUFFIX)
+#define omxSP_FFTInv_CCSToR_S32_Sfs OMXCATBAR(SP_FFTInv_CCSToR_S32_Sfs, OMXSP_SUFFIX)
+#define omxSP_FFTInv_CCSToR_S32S16_Sfs OMXCATBAR(SP_FFTInv_CCSToR_S32S16_Sfs, OMXSP_SUFFIX)
+#define omxSP_FFTInv_CToC_SC16_Sfs OMXCATBAR(SP_FFTInv_CToC_SC16_Sfs, OMXSP_SUFFIX)
+#define omxSP_FFTInv_CToC_SC32_Sfs OMXCATBAR(SP_FFTInv_CToC_SC32_Sfs, OMXSP_SUFFIX)
+#define omxSP_FilterMedian_S32 OMXCATBAR(SP_FilterMedian_S32, OMXSP_SUFFIX)
+#define omxSP_FilterMedian_S32_I OMXCATBAR(SP_FilterMedian_S32_I, OMXSP_SUFFIX)
+#define omxSP_FIR_Direct_S16 OMXCATBAR(SP_FIR_Direct_S16, OMXSP_SUFFIX)
+#define omxSP_FIR_Direct_S16_I OMXCATBAR(SP_FIR_Direct_S16_I, OMXSP_SUFFIX)
+#define omxSP_FIR_Direct_S16_ISfs OMXCATBAR(SP_FIR_Direct_S16_ISfs, OMXSP_SUFFIX)
+#define omxSP_FIR_Direct_S16_Sfs OMXCATBAR(SP_FIR_Direct_S16_Sfs, OMXSP_SUFFIX)
+#define omxSP_FIROne_Direct_S16 OMXCATBAR(SP_FIROne_Direct_S16, OMXSP_SUFFIX)
+#define omxSP_FIROne_Direct_S16_I OMXCATBAR(SP_FIROne_Direct_S16_I, OMXSP_SUFFIX)
+#define omxSP_FIROne_Direct_S16_ISfs OMXCATBAR(SP_FIROne_Direct_S16_ISfs, OMXSP_SUFFIX)
+#define omxSP_FIROne_Direct_S16_Sfs OMXCATBAR(SP_FIROne_Direct_S16_Sfs, OMXSP_SUFFIX)
+#define omxSP_IIR_BiQuadDirect_S16 OMXCATBAR(SP_IIR_BiQuadDirect_S16, OMXSP_SUFFIX)
+#define omxSP_IIR_BiQuadDirect_S16_I OMXCATBAR(SP_IIR_BiQuadDirect_S16_I, OMXSP_SUFFIX)
+#define omxSP_IIR_Direct_S16 OMXCATBAR(SP_IIR_Direct_S16, OMXSP_SUFFIX)
+#define omxSP_IIR_Direct_S16_I OMXCATBAR(SP_IIR_Direct_S16_I, OMXSP_SUFFIX)
+#define omxSP_IIROne_BiQuadDirect_S16 OMXCATBAR(SP_IIROne_BiQuadDirect_S16, OMXSP_SUFFIX)
+#define omxSP_IIROne_BiQuadDirect_S16_I OMXCATBAR(SP_IIROne_BiQuadDirect_S16_I, OMXSP_SUFFIX)
+#define omxSP_IIROne_Direct_S16 OMXCATBAR(SP_IIROne_Direct_S16, OMXSP_SUFFIX)
+#define omxSP_IIROne_Direct_S16_I OMXCATBAR(SP_IIROne_Direct_S16_I, OMXSP_SUFFIX)
+
+#define omxVCCOMM_Average_16x OMXCATBAR(VCCOMM_Average_16x, OMXVCCOMM_SUFFIX)
+#define omxVCCOMM_Average_8x OMXCATBAR(VCCOMM_Average_8x, OMXVCCOMM_SUFFIX)
+#define omxVCCOMM_ComputeTextureErrorBlock OMXCATBAR(VCCOMM_ComputeTextureErrorBlock, OMXVCCOMM_SUFFIX)
+#define omxVCCOMM_ComputeTextureErrorBlock_SAD OMXCATBAR(VCCOMM_ComputeTextureErrorBlock_SAD, OMXVCCOMM_SUFFIX)
+#define omxVCCOMM_Copy16x16 OMXCATBAR(VCCOMM_Copy16x16, OMXVCCOMM_SUFFIX)
+#define omxVCCOMM_Copy8x8 OMXCATBAR(VCCOMM_Copy8x8, OMXVCCOMM_SUFFIX)
+#define omxVCCOMM_ExpandFrame_I OMXCATBAR(VCCOMM_ExpandFrame_I, OMXVCCOMM_SUFFIX)
+#define omxVCCOMM_LimitMVToRect OMXCATBAR(VCCOMM_LimitMVToRect, OMXVCCOMM_SUFFIX)
+#define omxVCCOMM_SAD_16x OMXCATBAR(VCCOMM_SAD_16x, OMXVCCOMM_SUFFIX)
+#define omxVCCOMM_SAD_8x OMXCATBAR(VCCOMM_SAD_8x, OMXVCCOMM_SUFFIX)
+
+#define omxVCM4P10_Average_4x OMXCATBAR(VCM4P10_Average_4x, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_BlockMatch_Half OMXCATBAR(VCM4P10_BlockMatch_Half, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_BlockMatch_Integer OMXCATBAR(VCM4P10_BlockMatch_Integer, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_BlockMatch_Quarter OMXCATBAR(VCM4P10_BlockMatch_Quarter, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_DeblockChroma_I OMXCATBAR(VCM4P10_DeblockChroma_I, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_DeblockLuma_I OMXCATBAR(VCM4P10_DeblockLuma_I, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC OMXCATBAR(VCM4P10_DecodeChromaDcCoeffsToPairCAVLC, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_DecodeCoeffsToPairCAVLC OMXCATBAR(VCM4P10_DecodeCoeffsToPairCAVLC, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_DequantTransformResidualFromPairAndAdd OMXCATBAR(VCM4P10_DequantTransformResidualFromPairAndAdd, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_FilterDeblockingChroma_HorEdge_I OMXCATBAR(VCM4P10_FilterDeblockingChroma_HorEdge_I, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_FilterDeblockingChroma_VerEdge_I OMXCATBAR(VCM4P10_FilterDeblockingChroma_VerEdge_I, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_FilterDeblockingLuma_HorEdge_I OMXCATBAR(VCM4P10_FilterDeblockingLuma_HorEdge_I, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_FilterDeblockingLuma_VerEdge_I OMXCATBAR(VCM4P10_FilterDeblockingLuma_VerEdge_I, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_GetVLCInfo OMXCATBAR(VCM4P10_GetVLCInfo, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_InterpolateChroma OMXCATBAR(VCM4P10_InterpolateChroma, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_InterpolateHalfHor_Luma OMXCATBAR(VCM4P10_InterpolateHalfHor_Luma, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_InterpolateHalfVer_Luma OMXCATBAR(VCM4P10_InterpolateHalfVer_Luma, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_InterpolateLuma OMXCATBAR(VCM4P10_InterpolateLuma, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_InvTransformDequant_ChromaDC OMXCATBAR(VCM4P10_InvTransformDequant_ChromaDC, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_InvTransformDequant_LumaDC OMXCATBAR(VCM4P10_InvTransformDequant_LumaDC, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_InvTransformResidualAndAdd OMXCATBAR(VCM4P10_InvTransformResidualAndAdd, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_MEGetBufSize OMXCATBAR(VCM4P10_MEGetBufSize, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_MEInit OMXCATBAR(VCM4P10_MEInit, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_MotionEstimationMB OMXCATBAR(VCM4P10_MotionEstimationMB, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_PredictIntra_16x16 OMXCATBAR(VCM4P10_PredictIntra_16x16, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_PredictIntra_4x4 OMXCATBAR(VCM4P10_PredictIntra_4x4, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_PredictIntraChroma_8x8 OMXCATBAR(VCM4P10_PredictIntraChroma_8x8, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_SAD_4x OMXCATBAR(VCM4P10_SAD_4x, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_SADQuar_16x OMXCATBAR(VCM4P10_SADQuar_16x, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_SADQuar_4x OMXCATBAR(VCM4P10_SADQuar_4x, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_SADQuar_8x OMXCATBAR(VCM4P10_SADQuar_8x, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_SATD_4x4 OMXCATBAR(VCM4P10_SATD_4x4, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_SubAndTransformQDQResidual OMXCATBAR(VCM4P10_SubAndTransformQDQResidual, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_TransformDequantChromaDCFromPair OMXCATBAR(VCM4P10_TransformDequantChromaDCFromPair, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_TransformDequantLumaDCFromPair OMXCATBAR(VCM4P10_TransformDequantLumaDCFromPair, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_TransformQuant_ChromaDC OMXCATBAR(VCM4P10_TransformQuant_ChromaDC, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_TransformQuant_LumaDC OMXCATBAR(VCM4P10_TransformQuant_LumaDC, OMXVCM4P10_SUFFIX)
+
+#define omxVCM4P2_BlockMatch_Half_16x16 OMXCATBAR(VCM4P2_BlockMatch_Half_16x16, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_BlockMatch_Half_8x8 OMXCATBAR(VCM4P2_BlockMatch_Half_8x8, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_BlockMatch_Integer_16x16 OMXCATBAR(VCM4P2_BlockMatch_Integer_16x16, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_BlockMatch_Integer_8x8 OMXCATBAR(VCM4P2_BlockMatch_Integer_8x8, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_DCT8x8blk OMXCATBAR(VCM4P2_DCT8x8blk, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_DecodeBlockCoef_Inter OMXCATBAR(VCM4P2_DecodeBlockCoef_Inter, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_DecodeBlockCoef_Intra OMXCATBAR(VCM4P2_DecodeBlockCoef_Intra, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_DecodePadMV_PVOP OMXCATBAR(VCM4P2_DecodePadMV_PVOP, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_DecodeVLCZigzag_Inter OMXCATBAR(VCM4P2_DecodeVLCZigzag_Inter, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_DecodeVLCZigzag_IntraACVLC OMXCATBAR(VCM4P2_DecodeVLCZigzag_IntraACVLC, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_DecodeVLCZigzag_IntraDCVLC OMXCATBAR(VCM4P2_DecodeVLCZigzag_IntraDCVLC, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_EncodeMV OMXCATBAR(VCM4P2_EncodeMV, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_EncodeVLCZigzag_Inter OMXCATBAR(VCM4P2_EncodeVLCZigzag_Inter, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_EncodeVLCZigzag_IntraACVLC OMXCATBAR(VCM4P2_EncodeVLCZigzag_IntraACVLC, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_EncodeVLCZigzag_IntraDCVLC OMXCATBAR(VCM4P2_EncodeVLCZigzag_IntraDCVLC, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_FindMVpred OMXCATBAR(VCM4P2_FindMVpred, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_IDCT8x8blk OMXCATBAR(VCM4P2_IDCT8x8blk, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_MCReconBlock OMXCATBAR(VCM4P2_MCReconBlock, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_MEGetBufSize OMXCATBAR(VCM4P2_MEGetBufSize, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_MEInit OMXCATBAR(VCM4P2_MEInit, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_MotionEstimationMB OMXCATBAR(VCM4P2_MotionEstimationMB, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_PredictReconCoefIntra OMXCATBAR(VCM4P2_PredictReconCoefIntra, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_QuantInter_I OMXCATBAR(VCM4P2_QuantInter_I, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_QuantIntra_I OMXCATBAR(VCM4P2_QuantIntra_I, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_QuantInvInter_I OMXCATBAR(VCM4P2_QuantInvInter_I, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_QuantInvIntra_I OMXCATBAR(VCM4P2_QuantInvIntra_I, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_TransRecBlockCoef_inter OMXCATBAR(VCM4P2_TransRecBlockCoef_inter, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_TransRecBlockCoef_intra OMXCATBAR(VCM4P2_TransRecBlockCoef_intra, OMXVCM4P2_SUFFIX)
+
+
+#endif /* _armOMX_h_ */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/omxtypes.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/omxtypes.h
new file mode 100755
index 0000000..8b295a6
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/omxtypes.h
@@ -0,0 +1,252 @@
+/**
+ * File: omxtypes.h
+ * Brief: Defines basic Data types used in OpenMAX v1.0.2 header files.
+ *
+ * Copyright © 2005-2008 The Khronos Group Inc. All Rights Reserved.
+ *
+ * These materials are protected by copyright laws and contain material
+ * proprietary to the Khronos Group, Inc. You may use these materials
+ * for implementing Khronos specifications, without altering or removing
+ * any trademark, copyright or other notice from the specification.
+ *
+ * Khronos Group makes no, and expressly disclaims any, representations
+ * or warranties, express or implied, regarding these materials, including,
+ * without limitation, any implied warranties of merchantability or fitness
+ * for a particular purpose or non-infringement of any intellectual property.
+ * Khronos Group makes no, and expressly disclaims any, warranties, express
+ * or implied, regarding the correctness, accuracy, completeness, timeliness,
+ * and reliability of these materials.
+ *
+ * Under no circumstances will the Khronos Group, or any of its Promoters,
+ * Contributors or Members or their respective partners, officers, directors,
+ * employees, agents or representatives be liable for any damages, whether
+ * direct, indirect, special or consequential damages for lost revenues,
+ * lost profits, or otherwise, arising from or in connection with these
+ * materials.
+ *
+ * Khronos and OpenMAX are trademarks of the Khronos Group Inc.
+ *
+ */
+
+#ifndef _OMXTYPES_H_
+#define _OMXTYPES_H_
+
+#include <limits.h>
+
+#define OMX_IN
+#define OMX_OUT
+#define OMX_INOUT
+
+
+typedef enum {
+
+ /* Mandatory return codes - use cases are explicitly described for each function */
+ OMX_Sts_NoErr = 0, /* No error, the function completed successfully */
+ OMX_Sts_Err = -2, /* Unknown/unspecified error */
+ OMX_Sts_InvalidBitstreamValErr = -182, /* Invalid value detected during bitstream processing */
+ OMX_Sts_MemAllocErr = -9, /* Not enough memory allocated for the operation */
+ OMX_StsACAAC_GainCtrErr = -159, /* AAC: Unsupported gain control data detected */
+ OMX_StsACAAC_PrgNumErr = -167, /* AAC: Invalid number of elements for one program */
+ OMX_StsACAAC_CoefValErr = -163, /* AAC: Invalid quantized coefficient value */
+ OMX_StsACAAC_MaxSfbErr = -162, /* AAC: Invalid maxSfb value in relation to numSwb */
+ OMX_StsACAAC_PlsDataErr = -160, /* AAC: pulse escape sequence data error */
+
+ /* Optional return codes - use cases are explicitly described for each function*/
+ OMX_Sts_BadArgErr = -5, /* Bad Arguments */
+
+ OMX_StsACAAC_TnsNumFiltErr = -157, /* AAC: Invalid number of TNS filters */
+ OMX_StsACAAC_TnsLenErr = -156, /* AAC: Invalid TNS region length */
+ OMX_StsACAAC_TnsOrderErr = -155, /* AAC: Invalid order of TNS filter */
+ OMX_StsACAAC_TnsCoefResErr = -154, /* AAC: Invalid bit-resolution for TNS filter coefficients */
+ OMX_StsACAAC_TnsCoefErr = -153, /* AAC: Invalid TNS filter coefficients */
+ OMX_StsACAAC_TnsDirectErr = -152, /* AAC: Invalid TNS filter direction */
+
+ OMX_StsICJP_JPEGMarkerErr = -183, /* JPEG marker encountered within an entropy-coded block; */
+ /* Huffman decoding operation terminated early. */
+ OMX_StsICJP_JPEGMarker = -181, /* JPEG marker encountered; Huffman decoding */
+ /* operation terminated early. */
+ OMX_StsIPPP_ContextMatchErr = -17, /* Context parameter doesn't match to the operation */
+
+ OMX_StsSP_EvenMedianMaskSizeErr = -180, /* Even size of the Median Filter mask was replaced by the odd one */
+
+ OMX_Sts_MaximumEnumeration = INT_MAX /*Placeholder, forces enum of size OMX_INT*/
+
+ } OMXResult; /** Return value or error value returned from a function. Identical to OMX_INT */
+
+
+/* OMX_U8 */
+#if UCHAR_MAX == 0xff
+typedef unsigned char OMX_U8;
+#elif USHRT_MAX == 0xff
+typedef unsigned short int OMX_U8;
+#else
+#error OMX_U8 undefined
+#endif
+
+
+/* OMX_S8 */
+#if SCHAR_MAX == 0x7f
+typedef signed char OMX_S8;
+#elif SHRT_MAX == 0x7f
+typedef signed short int OMX_S8;
+#else
+#error OMX_S8 undefined
+#endif
+
+
+/* OMX_U16 */
+#if USHRT_MAX == 0xffff
+typedef unsigned short int OMX_U16;
+#elif UINT_MAX == 0xffff
+typedef unsigned int OMX_U16;
+#else
+#error OMX_U16 undefined
+#endif
+
+
+/* OMX_S16 */
+#if SHRT_MAX == 0x7fff
+typedef signed short int OMX_S16;
+#elif INT_MAX == 0x7fff
+typedef signed int OMX_S16;
+#else
+#error OMX_S16 undefined
+#endif
+
+
+/* OMX_U32 */
+#if UINT_MAX == 0xffffffff
+typedef unsigned int OMX_U32;
+#elif LONG_MAX == 0xffffffff
+typedef unsigned long int OMX_U32;
+#else
+#error OMX_U32 undefined
+#endif
+
+
+/* OMX_S32 */
+#if INT_MAX == 0x7fffffff
+typedef signed int OMX_S32;
+#elif LONG_MAX == 0x7fffffff
+typedef long signed int OMX_S32;
+#else
+#error OMX_S32 undefined
+#endif
+
+
+/* OMX_U64 & OMX_S64 */
+#if defined( _WIN32 ) || defined ( _WIN64 )
+ typedef __int64 OMX_S64; /** Signed 64-bit integer */
+ typedef unsigned __int64 OMX_U64; /** Unsigned 64-bit integer */
+ #define OMX_MIN_S64 (0x8000000000000000i64)
+ #define OMX_MIN_U64 (0x0000000000000000i64)
+ #define OMX_MAX_S64 (0x7FFFFFFFFFFFFFFFi64)
+ #define OMX_MAX_U64 (0xFFFFFFFFFFFFFFFFi64)
+#else
+ typedef long long OMX_S64; /** Signed 64-bit integer */
+ typedef unsigned long long OMX_U64; /** Unsigned 64-bit integer */
+ #define OMX_MIN_S64 (0x8000000000000000LL)
+ #define OMX_MIN_U64 (0x0000000000000000LL)
+ #define OMX_MAX_S64 (0x7FFFFFFFFFFFFFFFLL)
+ #define OMX_MAX_U64 (0xFFFFFFFFFFFFFFFFLL)
+#endif
+
+
+/* OMX_SC8 */
+typedef struct
+{
+ OMX_S8 Re; /** Real part */
+ OMX_S8 Im; /** Imaginary part */
+
+} OMX_SC8; /** Signed 8-bit complex number */
+
+
+/* OMX_SC16 */
+typedef struct
+{
+ OMX_S16 Re; /** Real part */
+ OMX_S16 Im; /** Imaginary part */
+
+} OMX_SC16; /** Signed 16-bit complex number */
+
+
+/* OMX_SC32 */
+typedef struct
+{
+ OMX_S32 Re; /** Real part */
+ OMX_S32 Im; /** Imaginary part */
+
+} OMX_SC32; /** Signed 32-bit complex number */
+
+
+/* OMX_SC64 */
+typedef struct
+{
+ OMX_S64 Re; /** Real part */
+ OMX_S64 Im; /** Imaginary part */
+
+} OMX_SC64; /** Signed 64-bit complex number */
+
+
+/* OMX_F32 */
+typedef float OMX_F32; /** Single precision floating point,IEEE 754 */
+
+
+/* OMX_F64 */
+typedef double OMX_F64; /** Double precision floating point,IEEE 754 */
+
+
+/* OMX_INT */
+typedef int OMX_INT; /** signed integer corresponding to machine word length, has maximum signed value INT_MAX*/
+
+
+#define OMX_MIN_S8 (-128)
+#define OMX_MIN_U8 0
+#define OMX_MIN_S16 (-32768)
+#define OMX_MIN_U16 0
+#define OMX_MIN_S32 (-2147483647-1)
+#define OMX_MIN_U32 0
+
+#define OMX_MAX_S8 (127)
+#define OMX_MAX_U8 (255)
+#define OMX_MAX_S16 (32767)
+#define OMX_MAX_U16 (0xFFFF)
+#define OMX_MAX_S32 (2147483647)
+#define OMX_MAX_U32 (0xFFFFFFFF)
+
+typedef void OMXVoid;
+
+#ifndef NULL
+#define NULL ((void*)0)
+#endif
+
+/** Defines the geometric position and size of a rectangle,
+ * where x,y defines the coordinates of the top left corner
+ * of the rectangle, with dimensions width in the x-direction
+ * and height in the y-direction */
+typedef struct {
+ OMX_INT x; /** x-coordinate of top left corner of rectangle */
+ OMX_INT y; /** y-coordinate of top left corner of rectangle */
+ OMX_INT width; /** Width in the x-direction. */
+ OMX_INT height; /** Height in the y-direction. */
+}OMXRect;
+
+
+/** Defines the geometric position of a point, */
+typedef struct
+{
+ OMX_INT x; /** x-coordinate */
+ OMX_INT y; /** y-coordinate */
+
+} OMXPoint;
+
+
+/** Defines the dimensions of a rectangle, or region of interest in an image */
+typedef struct
+{
+ OMX_INT width; /** Width of the rectangle, in the x-direction */
+ OMX_INT height; /** Height of the rectangle, in the y-direction */
+
+} OMXSize;
+
+#endif /* _OMXTYPES_H_ */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/omxtypes_s.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/omxtypes_s.h
new file mode 100755
index 0000000..48703d1
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/omxtypes_s.h
@@ -0,0 +1,77 @@
+;//
+;//
+;// File Name: omxtypes_s.h
+;// OpenMAX DL: v1.0.2
+;// Revision: 12290
+;// Date: Wednesday, April 9, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+;// Mandatory return codes - use cases are explicitly described for each function
+OMX_Sts_NoErr EQU 0 ;// No error the function completed successfully
+OMX_Sts_Err EQU -2 ;// Unknown/unspecified error
+OMX_Sts_InvalidBitstreamValErr EQU -182 ;// Invalid value detected during bitstream processing
+OMX_Sts_MemAllocErr EQU -9 ;// Not enough memory allocated for the operation
+OMX_StsACAAC_GainCtrErr EQU -159 ;// AAC: Unsupported gain control data detected
+OMX_StsACAAC_PrgNumErr EQU -167 ;// AAC: Invalid number of elements for one program
+OMX_StsACAAC_CoefValErr EQU -163 ;// AAC: Invalid quantized coefficient value
+OMX_StsACAAC_MaxSfbErr EQU -162 ;// AAC: Invalid maxSfb value in relation to numSwb
+OMX_StsACAAC_PlsDataErr EQU -160 ;// AAC: pulse escape sequence data error
+
+;// Optional return codes - use cases are explicitly described for each function
+OMX_Sts_BadArgErr EQU -5 ;// Bad Arguments
+
+OMX_StsACAAC_TnsNumFiltErr EQU -157 ;// AAC: Invalid number of TNS filters
+OMX_StsACAAC_TnsLenErr EQU -156 ;// AAC: Invalid TNS region length
+OMX_StsACAAC_TnsOrderErr EQU -155 ;// AAC: Invalid order of TNS filter
+OMX_StsACAAC_TnsCoefResErr EQU -154 ;// AAC: Invalid bit-resolution for TNS filter coefficients
+OMX_StsACAAC_TnsCoefErr EQU -153 ;// AAC: Invalid TNS filter coefficients
+OMX_StsACAAC_TnsDirectErr EQU -152 ;// AAC: Invalid TNS filter direction
+
+OMX_StsICJP_JPEGMarkerErr EQU -183 ;// JPEG marker encountered within an entropy-coded block;
+ ;// Huffman decoding operation terminated early.
+OMX_StsICJP_JPEGMarker EQU -181 ;// JPEG marker encountered; Huffman decoding
+ ;// operation terminated early.
+OMX_StsIPPP_ContextMatchErr EQU -17 ;// Context parameter doesn't match to the operation
+
+OMX_StsSP_EvenMedianMaskSizeErr EQU -180 ;// Even size of the Median Filter mask was replaced by the odd one
+
+OMX_Sts_MaximumEnumeration EQU 0x7FFFFFFF
+
+
+
+OMX_MIN_S8 EQU (-128)
+OMX_MIN_U8 EQU 0
+OMX_MIN_S16 EQU (-32768)
+OMX_MIN_U16 EQU 0
+
+
+OMX_MIN_S32 EQU (-2147483647-1)
+OMX_MIN_U32 EQU 0
+
+OMX_MAX_S8 EQU (127)
+OMX_MAX_U8 EQU (255)
+OMX_MAX_S16 EQU (32767)
+OMX_MAX_U16 EQU (0xFFFF)
+OMX_MAX_S32 EQU (2147483647)
+OMX_MAX_U32 EQU (0xFFFFFFFF)
+
+OMX_VC_UPPER EQU 0x1 ;// Used by the PredictIntra functions
+OMX_VC_LEFT EQU 0x2 ;// Used by the PredictIntra functions
+OMX_VC_UPPER_RIGHT EQU 0x40 ;// Used by the PredictIntra functions
+
+NULL EQU 0
+
+;// Structures
+
+ INCLUDE armCOMM_s.h
+
+ M_STRUCT OMXPoint
+ M_FIELD x, 4
+ M_FIELD y, 4
+ M_ENDSTRUCT
+
+ END
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/build_vc.pl b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/build_vc.pl
new file mode 100755
index 0000000..649e74c
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/build_vc.pl
@@ -0,0 +1,113 @@
+#!/usr/bin/perl
+#
+#
+# File Name: build_vc.pl
+# OpenMAX DL: v1.0.2
+# Revision: 12290
+# Date: Wednesday, April 9, 2008
+#
+# (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+#
+#
+#
+# This file builds the OpenMAX DL vc domain library omxVC.o.
+#
+
+use File::Spec;
+use strict;
+
+my ($CC, $CC_OPTS, $AS, $AS_OPTS, $LIB, $LIB_OPTS, $LIB_TYPE);
+
+$CC = 'armcc';
+$CC_OPTS = '--no_unaligned_access --cpu Cortex-A8 -c';
+$AS = 'armasm';
+$AS_OPTS = '--no_unaligned_access --cpu Cortex-A8';
+# $LIB = 'armlink';
+# $LIB_OPTS = '--partial -o';
+# $LIB_TYPE = '.o';
+$LIB = 'armar';
+$LIB_OPTS = '--create -r';
+$LIB_TYPE = '.a';
+
+#------------------------
+
+my (@headerlist, @filelist, $hd, $file, $ofile, $command, $objlist, $libfile, $h);
+
+# Define the list of directories containing included header files.
+@headerlist = qw(api vc/api vc/m4p2/api vc/m4p10/api);
+
+# Define the list of source files to compile.
+open(FILES, '<filelist_vc.txt') or die("Can't open source file list\n");
+@filelist = <FILES>;
+close(FILES);
+
+# Fix the file separators in the header paths
+foreach $h (@headerlist)
+{
+ $h = File::Spec->canonpath($h);
+}
+
+# Create the include path to be passed to the compiler
+$hd = '-I' . join(' -I', @headerlist);
+
+# Create the build directories "/lib/" and "/obj/" (if they are not there already)
+mkdir "obj", 0777 if (! -d "obj");
+mkdir "lib", 0777 if (! -d "lib");
+
+$objlist = '';
+
+# Compile each file
+foreach $file (@filelist)
+{
+ my $f;
+ my $base;
+ my $ext;
+ my $objfile;
+
+ chomp($file);
+ $file = File::Spec->canonpath($file);
+
+ (undef, undef, $f) = File::Spec->splitpath($file);
+ $f=~s/[\n\f\r]//g; # Remove any end-of-line characters
+
+ if(($base, $ext) = $f =~ /(.+)\.(\w)$/)
+ {
+ $objfile = File::Spec->catfile('obj', $base.'.o');
+
+ if($ext eq 'c')
+ {
+ $objlist .= "$objfile ";
+ $command = $CC.' '.$CC_OPTS.' '.$hd.' -o '.$objfile.' '.$file;
+ print "$command\n";
+ system($command);
+ }
+ elsif($ext eq 's')
+ {
+ $objlist .= "$objfile ";
+ $command = $AS.' '.$AS_OPTS.' '.$hd.' -o '.$objfile.' '.$file;
+ print "$command\n";
+ system($command);
+ }
+ else
+ {
+ print "Ignoring file: $f\n";
+ }
+ }
+ else
+ {
+ die "No file extension found: $f\n";
+ }
+}
+
+# Do the final link stage to create the libraries.
+$libfile = File::Spec->catfile('lib', 'omxVC'.$LIB_TYPE);
+$command = $LIB.' '.$LIB_OPTS.' '.$libfile.' '.$objlist;
+print "$command\n";
+(system($command) == 0) and print "Build successful\n";
+
+
+
+
+
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/filelist_vc.txt b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/filelist_vc.txt
new file mode 100755
index 0000000..8db8eeb
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/filelist_vc.txt
@@ -0,0 +1,75 @@
+./api/armCOMM.h
+./api/armCOMM_BitDec_s.h
+./api/armCOMM_Bitstream.h
+./api/armCOMM_IDCT_s.h
+./api/armCOMM_IDCTTable.h
+./api/armCOMM_MaskTable.h
+./api/armCOMM_s.h
+./api/armCOMM_Version.h
+./api/armOMX_ReleaseVersion.h
+./api/omxtypes.h
+./api/omxtypes_s.h
+./src/armCOMM_IDCTTable.c
+./src/armCOMM_MaskTable.c
+./vc/api/armVC.h
+./vc/api/armVCCOMM_s.h
+./vc/api/omxVC.h
+./vc/api/omxVC_s.h
+./vc/comm/src/omxVCCOMM_Copy16x16_s.s
+./vc/comm/src/omxVCCOMM_Copy8x8_s.s
+./vc/comm/src/omxVCCOMM_ExpandFrame_I_s.s
+./vc/m4p10/api/armVCM4P10_CAVLCTables.h
+./vc/m4p10/src/armVCM4P10_Average_4x_Align_unsafe_s.s
+./vc/m4p10/src/armVCM4P10_CAVLCTables.c
+./vc/m4p10/src/armVCM4P10_DeblockingChroma_unsafe_s.s
+./vc/m4p10/src/armVCM4P10_DeblockingLuma_unsafe_s.s
+./vc/m4p10/src/armVCM4P10_DecodeCoeffsToPair_s.s
+./vc/m4p10/src/armVCM4P10_DequantTables_s.s
+./vc/m4p10/src/armVCM4P10_Interpolate_Chroma_s.s
+./vc/m4p10/src/armVCM4P10_InterpolateLuma_Align_unsafe_s.s
+./vc/m4p10/src/armVCM4P10_InterpolateLuma_Copy_unsafe_s.s
+./vc/m4p10/src/armVCM4P10_InterpolateLuma_DiagCopy_unsafe_s.s
+./vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe_s.s
+./vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe_s.s
+./vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe_s.s
+./vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe_s.s
+./vc/m4p10/src/armVCM4P10_QuantTables_s.s
+./vc/m4p10/src/armVCM4P10_TransformResidual4x4_s.s
+./vc/m4p10/src/armVCM4P10_UnpackBlock4x4_s.s
+./vc/m4p10/src/omxVCM4P10_DeblockChroma_I.c
+./vc/m4p10/src/omxVCM4P10_DeblockLuma_I.c
+./vc/m4p10/src/omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c
+./vc/m4p10/src/omxVCM4P10_DecodeCoeffsToPairCAVLC.c
+./vc/m4p10/src/omxVCM4P10_DequantTransformResidualFromPairAndAdd_s.s
+./vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_HorEdge_I_s.s
+./vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_VerEdge_I_s.s
+./vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_HorEdge_I_s.s
+./vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_VerEdge_I_s.s
+./vc/m4p10/src/omxVCM4P10_InterpolateChroma.c
+./vc/m4p10/src/omxVCM4P10_InterpolateLuma_s.s
+./vc/m4p10/src/omxVCM4P10_PredictIntra_16x16_s.s
+./vc/m4p10/src/omxVCM4P10_PredictIntra_4x4_s.s
+./vc/m4p10/src/omxVCM4P10_PredictIntraChroma_8x8_s.s
+./vc/m4p10/src/omxVCM4P10_TransformDequantChromaDCFromPair_s.s
+./vc/m4p10/src/omxVCM4P10_TransformDequantLumaDCFromPair_s.s
+./vc/m4p2/api/armVCM4P2_Huff_Tables_VLC.h
+./vc/m4p2/api/armVCM4P2_ZigZag_Tables.h
+./vc/m4p2/src/armVCM4P2_Clip8_s.s
+./vc/m4p2/src/armVCM4P2_DecodeVLCZigzag_AC_unsafe_s.s
+./vc/m4p2/src/armVCM4P2_Huff_Tables_VLC.c
+./vc/m4p2/src/armVCM4P2_Lookup_Tables.c
+./vc/m4p2/src/armVCM4P2_SetPredDir_s.s
+./vc/m4p2/src/armVCM4P2_Zigzag_Tables.c
+./vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Inter.c
+./vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Intra.c
+./vc/m4p2/src/omxVCM4P2_DecodePadMV_PVOP_s.s
+./vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_Inter_s.s
+./vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraACVLC_s.s
+./vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraDCVLC_s.s
+./vc/m4p2/src/omxVCM4P2_FindMVpred_s.s
+./vc/m4p2/src/omxVCM4P2_IDCT8x8blk_s.s
+./vc/m4p2/src/omxVCM4P2_MCReconBlock_s.s
+./vc/m4p2/src/omxVCM4P2_PredictReconCoefIntra_s.s
+./vc/m4p2/src/omxVCM4P2_QuantInvInter_I_s.s
+./vc/m4p2/src/omxVCM4P2_QuantInvIntra_I_s.s
+./vc/src/armVC_Version.c
\ No newline at end of file
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM.c
new file mode 100755
index 0000000..e572a89
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM.c
@@ -0,0 +1,936 @@
+/**
+ *
+ * File Name: armCOMM.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Defines Common APIs used across OpenMAX API's
+ */
+
+#include "omxtypes.h"
+#include "armCOMM.h"
+
+/***********************************************************************/
+ /* Miscellaneous Arithmetic operations */
+
+/**
+ * Function: armRoundFloatToS16
+ *
+ * Description:
+ * Converts a double precision value into a short int after rounding
+ *
+ * Parameters:
+ * [in] Value Float value to be converted
+ *
+ * Return Value:
+ * [out] converted value in OMX_S16 format
+ *
+ */
+
+OMX_S16 armRoundFloatToS16 (OMX_F64 Value)
+{
+ if (Value > 0)
+ {
+ return (OMX_S16)(Value + .5);
+ }
+ else
+ {
+ return (OMX_S16)(Value - .5);
+ }
+}
+
+/**
+ * Function: armRoundFloatToS32
+ *
+ * Description:
+ * Converts a double precision value into a int after rounding
+ *
+ * Parameters:
+ * [in] Value Float value to be converted
+ *
+ * Return Value:
+ * [out] converted value in OMX_S32 format
+ *
+ */
+
+OMX_S32 armRoundFloatToS32 (OMX_F64 Value)
+{
+ if (Value > 0)
+ {
+ return (OMX_S32)(Value + .5);
+ }
+ else
+ {
+ return (OMX_S32)(Value - .5);
+ }
+}
+/**
+ * Function: armSatRoundFloatToS16
+ *
+ * Description:
+ * Converts a double precision value into a short int after rounding and saturation
+ *
+ * Parameters:
+ * [in] Value Float value to be converted
+ *
+ * Return Value:
+ * [out] converted value in OMX_S16 format
+ *
+ */
+
+OMX_S16 armSatRoundFloatToS16 (OMX_F64 Value)
+{
+ if (Value > 0)
+ {
+ Value += 0.5;
+
+ if(Value > (OMX_S16)OMX_MAX_S16 )
+ {
+ return (OMX_S16)OMX_MAX_S16;
+ }
+ else
+ {
+ return (OMX_S16)Value;
+ }
+ }
+ else
+ {
+ Value -= 0.5;
+
+ if(Value < (OMX_S16)OMX_MIN_S16 )
+ {
+ return (OMX_S16)OMX_MIN_S16;
+ }
+ else
+ {
+ return (OMX_S16)Value;
+ }
+ }
+}
+
+/**
+ * Function: armSatRoundFloatToS32
+ *
+ * Description:
+ * Converts a double precision value into a int after rounding and saturation
+ *
+ * Parameters:
+ * [in] Value Float value to be converted
+ *
+ * Return Value:
+ * [out] converted value in OMX_S32 format
+ *
+ */
+
+OMX_S32 armSatRoundFloatToS32 (OMX_F64 Value)
+{
+ if (Value > 0)
+ {
+ Value += 0.5;
+
+ if(Value > (OMX_S32)OMX_MAX_S32 )
+ {
+ return (OMX_S32)OMX_MAX_S32;
+ }
+ else
+ {
+ return (OMX_S32)Value;
+ }
+ }
+ else
+ {
+ Value -= 0.5;
+
+ if(Value < (OMX_S32)OMX_MIN_S32 )
+ {
+ return (OMX_S32)OMX_MIN_S32;
+ }
+ else
+ {
+ return (OMX_S32)Value;
+ }
+ }
+}
+
+/**
+ * Function: armSatRoundFloatToU16
+ *
+ * Description:
+ * Converts a double precision value into a unsigned short int after rounding and saturation
+ *
+ * Parameters:
+ * [in] Value Float value to be converted
+ *
+ * Return Value:
+ * [out] converted value in OMX_U16 format
+ *
+ */
+
+OMX_U16 armSatRoundFloatToU16 (OMX_F64 Value)
+{
+ Value += 0.5;
+
+ if(Value > (OMX_U16)OMX_MAX_U16 )
+ {
+ return (OMX_U16)OMX_MAX_U16;
+ }
+ else
+ {
+ return (OMX_U16)Value;
+ }
+}
+
+/**
+ * Function: armSatRoundFloatToU32
+ *
+ * Description:
+ * Converts a double precision value into a unsigned int after rounding and saturation
+ *
+ * Parameters:
+ * [in] Value Float value to be converted
+ *
+ * Return Value:
+ * [out] converted value in OMX_U32 format
+ *
+ */
+
+OMX_U32 armSatRoundFloatToU32 (OMX_F64 Value)
+{
+ Value += 0.5;
+
+ if(Value > (OMX_U32)OMX_MAX_U32 )
+ {
+ return (OMX_U32)OMX_MAX_U32;
+ }
+ else
+ {
+ return (OMX_U32)Value;
+ }
+}
+
+/**
+ * Function: armRoundFloatToS64
+ *
+ * Description:
+ * Converts a double precision value into a 64 bit int after rounding
+ *
+ * Parameters:
+ * [in] Value Float value to be converted
+ *
+ * Return Value:
+ * [out] converted value in OMX_S64 format
+ *
+ */
+
+OMX_S64 armRoundFloatToS64 (OMX_F64 Value)
+{
+ if (Value > 0)
+ {
+ return (OMX_S64)(Value + .5);
+ }
+ else
+ {
+ return (OMX_S64)(Value - .5);
+ }
+}
+
+/**
+ * Function: armSignCheck
+ *
+ * Description:
+ * Checks the sign of a variable:
+ * returns 1 if it is Positive
+ * returns 0 if it is 0
+ * returns -1 if it is Negative
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] var Variable to be checked
+ *
+ * Return Value:
+ * OMX_INT -- returns 1 if it is Positive
+ * returns 0 if it is 0
+ * returns -1 if it is Negative
+ */
+
+OMX_INT armSignCheck (
+ OMX_S16 var
+)
+
+{
+ OMX_INT Sign;
+
+ if (var < 0)
+ {
+ Sign = -1;
+ }
+ else if ( var > 0)
+ {
+ Sign = 1;
+ }
+ else
+ {
+ Sign = 0;
+ }
+
+ return Sign;
+}
+
+/**
+ * Function: armClip
+ *
+ * Description: Clips the input between MAX and MIN value
+ *
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] Min lower bound
+ * [in] Max upper bound
+ * [in] src variable to the clipped
+ *
+ * Return Value:
+ * OMX_S32 -- returns clipped value
+ */
+
+OMX_S32 armClip (
+ OMX_INT min,
+ OMX_INT max,
+ OMX_S32 src
+)
+
+{
+ if (src > max)
+ {
+ src = max;
+ }
+ else if (src < min)
+ {
+ src = min;
+ }
+
+ return src;
+}
+
+/**
+ * Function: armClip_F32
+ *
+ * Description: Clips the input between MAX and MIN value
+ *
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] Min lower bound
+ * [in] Max upper bound
+ * [in] src variable to the clipped
+ *
+ * Return Value:
+ * OMX_F32 -- returns clipped value
+ */
+
+OMX_F32 armClip_F32 (
+ OMX_F32 min,
+ OMX_F32 max,
+ OMX_F32 src
+)
+
+{
+ if (src > max)
+ {
+ src = max;
+ }
+ else if (src < min)
+ {
+ src = min;
+ }
+
+ return src;
+}
+
+/**
+ * Function: armShiftSat_F32
+ *
+ * Description: Divides a float value by 2^shift and
+ * saturates it for unsigned value range for satBits.
+ * Second parameter is like "shifting" the corresponding
+ * integer value. Takes care of rounding while clipping the final
+ * value.
+ *
+ * Parameters:
+ * [in] v Number to be operated upon
+ * [in] shift Divides the input "v" by "2^shift"
+ * [in] satBits Final range is [0, 2^satBits)
+ *
+ * Return Value:
+ * OMX_S32 -- returns "shifted" saturated value
+ */
+
+OMX_U32 armShiftSat_F32(OMX_F32 v, OMX_INT shift, OMX_INT satBits)
+{
+ OMX_U32 allOnes = (OMX_U32)(-1);
+ OMX_U32 maxV = allOnes >> (32-satBits);
+ OMX_F32 vShifted, vRounded, shiftDiv = (OMX_F32)(1 << shift);
+ OMX_U32 vInt;
+ OMX_U32 vIntSat;
+
+ if(v <= 0)
+ return 0;
+
+ vShifted = v / shiftDiv;
+ vRounded = (OMX_F32)(vShifted + 0.5);
+ vInt = (OMX_U32)vRounded;
+ vIntSat = vInt;
+ if(vIntSat > maxV)
+ vIntSat = maxV;
+ return vIntSat;
+}
+
+/**
+ * Functions: armSwapElem
+ *
+ * Description:
+ * These function swaps two elements at the specified pointer locations.
+ * The size of each element could be anything as specified by <elemSize>
+ *
+ * Return Value:
+ * OMXResult -- Error status from the function
+ */
+OMXResult armSwapElem(
+ OMX_U8 *pBuf1,
+ OMX_U8 *pBuf2,
+ OMX_INT elemSize
+ )
+{
+ OMX_INT i;
+ OMX_U8 temp;
+ armRetArgErrIf(!pBuf1 || !pBuf2, OMX_Sts_BadArgErr);
+
+ for(i = 0; i < elemSize; i++)
+ {
+ temp = *(pBuf1 + i);
+ *(pBuf1 + i) = *(pBuf2 + i);
+ *(pBuf2 + i) = temp;
+ }
+ return OMX_Sts_NoErr;
+}
+
+/**
+ * Function: armMedianOf3
+ *
+ * Description: Finds the median of three numbers
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] fEntry First entry
+ * [in] sEntry second entry
+ * [in] tEntry Third entry
+ *
+ * Return Value:
+ * OMX_S32 -- returns the median value
+ */
+
+OMX_S32 armMedianOf3 (
+ OMX_S32 fEntry,
+ OMX_S32 sEntry,
+ OMX_S32 tEntry
+)
+{
+ OMX_S32 a, b, c;
+
+ a = armMin (fEntry, sEntry);
+ b = armMax (fEntry, sEntry);
+ c = armMin (b, tEntry);
+ return (armMax (a, c));
+}
+
+/**
+ * Function: armLogSize
+ *
+ * Description: Finds the size of a positive value and returns the same
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] value Positive value
+ *
+ * Return Value:
+ * OMX_U8 -- Returns the minimum number of bits required to represent the positive value.
+ This is the smallest k>=0 such that that value is less than (1<<k).
+ */
+
+OMX_U8 armLogSize (
+ OMX_U16 value
+)
+{
+ OMX_U8 i;
+ for ( i = 0; value > 0; value = value >> 1)
+ {
+ i++;
+ }
+ return i;
+}
+
+/***********************************************************************/
+ /* Saturating Arithmetic operations */
+
+/**
+ * Function :armSatAdd_S32()
+ *
+ * Description :
+ * Returns the result of saturated addition of the two inputs Value1, Value2
+ *
+ * Parametrs:
+ * [in] Value1 First Operand
+ * [in] Value2 Second Operand
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ *
+ **/
+
+OMX_S32 armSatAdd_S32(OMX_S32 Value1,OMX_S32 Value2)
+{
+ OMX_S32 Result;
+
+ Result = Value1 + Value2;
+
+ if( (Value1^Value2) >= 0)
+ {
+ /*Same sign*/
+ if( (Result^Value1) >= 0)
+ {
+ /*Result has not saturated*/
+ return Result;
+ }
+ else
+ {
+ if(Value1 >= 0)
+ {
+ /*Result has saturated in positive side*/
+ return OMX_MAX_S32;
+ }
+ else
+ {
+ /*Result has saturated in negative side*/
+ return OMX_MIN_S32;
+ }
+
+ }
+
+ }
+ else
+ {
+ return Result;
+ }
+
+}
+
+/**
+ * Function :armSatAdd_S64()
+ *
+ * Description :
+ * Returns the result of saturated addition of the two inputs Value1, Value2
+ *
+ * Parametrs:
+ * [in] Value1 First Operand
+ * [in] Value2 Second Operand
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ *
+ **/
+
+OMX_S64 armSatAdd_S64(OMX_S64 Value1,OMX_S64 Value2)
+{
+ OMX_S64 Result;
+
+ Result = Value1 + Value2;
+
+ if( (Value1^Value2) >= 0)
+ {
+ /*Same sign*/
+ if( (Result^Value1) >= 0)
+ {
+ /*Result has not saturated*/
+ return Result;
+ }
+ else
+ {
+ if(Value1 >= 0)
+ {
+ /*Result has saturated in positive side*/
+ Result = OMX_MAX_S64;
+ return Result;
+ }
+ else
+ {
+ /*Result has saturated in negative side*/
+ return OMX_MIN_S64;
+ }
+
+ }
+
+ }
+ else
+ {
+ return Result;
+ }
+
+}
+
+/** Function :armSatSub_S32()
+ *
+ * Description :
+ * Returns the result of saturated substraction of the two inputs Value1, Value2
+ *
+ * Parametrs:
+ * [in] Value1 First Operand
+ * [in] Value2 Second Operand
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ **/
+
+OMX_S32 armSatSub_S32(OMX_S32 Value1,OMX_S32 Value2)
+{
+ OMX_S32 Result;
+
+ Result = Value1 - Value2;
+
+ if( (Value1^Value2) < 0)
+ {
+ /*Opposite sign*/
+ if( (Result^Value1) >= 0)
+ {
+ /*Result has not saturated*/
+ return Result;
+ }
+ else
+ {
+ if(Value1 >= 0)
+ {
+ /*Result has saturated in positive side*/
+ return OMX_MAX_S32;
+ }
+ else
+ {
+ /*Result has saturated in negative side*/
+ return OMX_MIN_S32;
+ }
+
+ }
+
+ }
+ else
+ {
+ return Result;
+ }
+
+}
+
+/**
+ * Function :armSatMac_S32()
+ *
+ * Description :
+ * Returns the result of Multiplication of Value1 and Value2 and subesquent saturated
+ * accumulation with Mac
+ *
+ * Parametrs:
+ * [in] Value1 First Operand
+ * [in] Value2 Second Operand
+ * [in] Mac Accumulator
+ *
+ * Return:
+ * [out] Result of operation
+ **/
+
+OMX_S32 armSatMac_S32(OMX_S32 Mac,OMX_S16 Value1,OMX_S16 Value2)
+{
+ OMX_S32 Result;
+
+ Result = (OMX_S32)(Value1*Value2);
+ Result = armSatAdd_S32( Mac , Result );
+
+ return Result;
+}
+
+/**
+ * Function :armSatMac_S16S32_S32
+ *
+ * Description :
+ * Returns the result of saturated MAC operation of the three inputs delayElem, filTap , mac
+ *
+ * mac = mac + Saturate_in_32Bits(delayElem * filTap)
+ *
+ * Parametrs:
+ * [in] delayElem First 32 bit Operand
+ * [in] filTap Second 16 bit Operand
+ * [in] mac Result of MAC operation
+ *
+ * Return:
+ * [out] mac Result of operation
+ *
+ **/
+
+OMX_S32 armSatMac_S16S32_S32(OMX_S32 mac, OMX_S32 delayElem, OMX_S16 filTap )
+{
+
+ OMX_S32 result;
+
+ result = armSatMulS16S32_S32(filTap,delayElem);
+
+ if ( result > OMX_MAX_S16 )
+ {
+ result = OMX_MAX_S32;
+ }
+ else if( result < OMX_MIN_S16 )
+ {
+ result = OMX_MIN_S32;
+ }
+ else
+ {
+ result = delayElem * filTap;
+ }
+
+ mac = armSatAdd_S32(mac,result);
+
+ return mac;
+}
+
+
+/**
+ * Function :armSatRoundRightShift_S32_S16
+ *
+ * Description :
+ * Returns the result of rounded right shift operation of input by the scalefactor
+ *
+ * output = Saturate_in_16Bits( ( Right/LeftShift( (Round(input) , shift ) )
+ *
+ * Parametrs:
+ * [in] input The input to be operated on
+ * [in] shift The shift number
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ **/
+
+
+OMX_S16 armSatRoundRightShift_S32_S16(OMX_S32 input, OMX_INT shift)
+{
+ input = armSatRoundLeftShift_S32(input,-shift);
+
+ if ( input > OMX_MAX_S16 )
+ {
+ return (OMX_S16)OMX_MAX_S16;
+ }
+ else if (input < OMX_MIN_S16)
+ {
+ return (OMX_S16)OMX_MIN_S16;
+ }
+ else
+ {
+ return (OMX_S16)input;
+ }
+
+}
+
+/**
+ * Function :armSatRoundLeftShift_S32()
+ *
+ * Description :
+ * Returns the result of saturating left-shift operation on input
+ * Or rounded Right shift if the input Shift is negative.
+ *
+ * Parametrs:
+ * [in] Value Operand
+ * [in] Shift Operand for shift operation
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ **/
+
+OMX_S32 armSatRoundLeftShift_S32(OMX_S32 Value, OMX_INT Shift)
+{
+ OMX_INT i;
+
+ if (Shift < 0)
+ {
+ Shift = -Shift;
+ Value = armSatAdd_S32(Value, (1 << (Shift - 1)));
+ Value = Value >> Shift;
+ }
+ else
+ {
+ for (i = 0; i < Shift; i++)
+ {
+ Value = armSatAdd_S32(Value, Value);
+ }
+ }
+ return Value;
+}
+
+/**
+ * Function :armSatRoundLeftShift_S64()
+ *
+ * Description :
+ * Returns the result of saturating left-shift operation on input
+ * Or rounded Right shift if the input Shift is negative.
+ *
+ * Parametrs:
+ * [in] Value Operand
+ * [in] shift Operand for shift operation
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ **/
+
+OMX_S64 armSatRoundLeftShift_S64(OMX_S64 Value, OMX_INT Shift)
+{
+ OMX_INT i;
+
+ if (Shift < 0)
+ {
+ Shift = -Shift;
+ Value = armSatAdd_S64(Value, ((OMX_S64)1 << (Shift - 1)));
+ Value = Value >> Shift;
+ }
+ else
+ {
+ for (i = 0; i < Shift; i++)
+ {
+ Value = armSatAdd_S64(Value, Value);
+ }
+ }
+ return Value;
+}
+
+/**
+ * Function :armSatMulS16S32_S32()
+ *
+ * Description :
+ * Returns the result of a S16 data type multiplied with an S32 data type
+ * in a S32 container
+ *
+ * Parametrs:
+ * [in] input1 Operand 1
+ * [in] input2 Operand 2
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ **/
+
+
+OMX_S32 armSatMulS16S32_S32(OMX_S16 input1,OMX_S32 input2)
+{
+ OMX_S16 hi2,lo1;
+ OMX_U16 lo2;
+
+ OMX_S32 temp1,temp2;
+ OMX_S32 result;
+
+ lo1 = input1;
+
+ hi2 = ( input2 >> 16 );
+ lo2 = ( (OMX_U32)( input2 << 16 ) >> 16 );
+
+ temp1 = hi2 * lo1;
+ temp2 = ( lo2* lo1 ) >> 16;
+
+ result = armSatAdd_S32(temp1,temp2);
+
+ return result;
+}
+
+/**
+ * Function :armSatMulS32S32_S32()
+ *
+ * Description :
+ * Returns the result of a S32 data type multiplied with an S32 data type
+ * in a S32 container
+ *
+ * Parametrs:
+ * [in] input1 Operand 1
+ * [in] input2 Operand 2
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ **/
+
+OMX_S32 armSatMulS32S32_S32(OMX_S32 input1,OMX_S32 input2)
+{
+ OMX_S16 hi1,hi2;
+ OMX_U16 lo1,lo2;
+
+ OMX_S32 temp1,temp2,temp3;
+ OMX_S32 result;
+
+ hi1 = ( input1 >> 16 );
+ lo1 = ( (OMX_U32)( input1 << 16 ) >> 16 );
+
+ hi2 = ( input2 >> 16 );
+ lo2 = ( (OMX_U32)( input2 << 16 ) >> 16 );
+
+ temp1 = hi1 * hi2;
+ temp2 = ( hi1* lo2 ) >> 16;
+ temp3 = ( hi2* lo1 ) >> 16;
+
+ result = armSatAdd_S32(temp1,temp2);
+ result = armSatAdd_S32(result,temp3);
+
+ return result;
+}
+
+/**
+ * Function :armIntDivAwayFromZero()
+ *
+ * Description : Integer division with rounding to the nearest integer.
+ * Half-integer values are rounded away from zero
+ * unless otherwise specified. For example 3//2 is rounded
+ * to 2, and -3//2 is rounded to -2.
+ *
+ * Parametrs:
+ * [in] Num Operand 1
+ * [in] Deno Operand 2
+ *
+ * Return:
+ * [out] Result of operation input1//input2
+ *
+ **/
+
+OMX_S32 armIntDivAwayFromZero (OMX_S32 Num, OMX_S32 Deno)
+{
+ OMX_F64 result;
+
+ result = ((OMX_F64)Num)/((OMX_F64)Deno);
+
+ if (result >= 0)
+ {
+ result += 0.5;
+ }
+ else
+ {
+ result -= 0.5;
+ }
+
+ return (OMX_S32)(result);
+}
+
+
+/*End of File*/
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM_Bitstream.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM_Bitstream.c
new file mode 100755
index 0000000..9ef9319
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM_Bitstream.c
@@ -0,0 +1,329 @@
+/**
+ *
+ * File Name: armCOMM_Bitstream.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Defines bitstream encode and decode functions common to all codecs
+ */
+
+#include "omxtypes.h"
+#include "armCOMM.h"
+#include "armCOMM_Bitstream.h"
+
+/***************************************
+ * Fixed bit length Decode
+ ***************************************/
+
+/**
+ * Function: armLookAheadBits()
+ *
+ * Description:
+ * Get the next N bits from the bitstream without advancing the bitstream pointer
+ *
+ * Parameters:
+ * [in] **ppBitStream
+ * [in] *pOffset
+ * [in] N=1...32
+ *
+ * Returns Value
+ */
+
+OMX_U32 armLookAheadBits(const OMX_U8 **ppBitStream, OMX_INT *pOffset, OMX_INT N)
+{
+ const OMX_U8 *pBitStream = *ppBitStream;
+ OMX_INT Offset = *pOffset;
+ OMX_U32 Value;
+
+ armAssert(Offset>=0 && Offset<=7);
+ armAssert(N>=1 && N<=32);
+
+ /* Read next 32 bits from stream */
+ Value = (pBitStream[0] << 24 ) | ( pBitStream[1] << 16) | (pBitStream[2] << 8 ) | (pBitStream[3]) ;
+ Value = (Value << Offset ) | (pBitStream[4] >> (8-Offset));
+
+ /* Return N bits */
+ return Value >> (32-N);
+}
+
+
+/**
+ * Function: armGetBits()
+ *
+ * Description:
+ * Read N bits from the bitstream
+ *
+ * Parameters:
+ * [in] *ppBitStream
+ * [in] *pOffset
+ * [in] N=1..32
+ *
+ * [out] *ppBitStream
+ * [out] *pOffset
+ * Returns Value
+ */
+
+
+OMX_U32 armGetBits(const OMX_U8 **ppBitStream, OMX_INT *pOffset, OMX_INT N)
+{
+ const OMX_U8 *pBitStream = *ppBitStream;
+ OMX_INT Offset = *pOffset;
+ OMX_U32 Value;
+
+ if(N == 0)
+ {
+ return 0;
+ }
+
+ armAssert(Offset>=0 && Offset<=7);
+ armAssert(N>=1 && N<=32);
+
+ /* Read next 32 bits from stream */
+ Value = (pBitStream[0] << 24 ) | ( pBitStream[1] << 16) | (pBitStream[2] << 8 ) | (pBitStream[3]) ;
+ Value = (Value << Offset ) | (pBitStream[4] >> (8-Offset));
+
+ /* Advance bitstream pointer by N bits */
+ Offset += N;
+ *ppBitStream = pBitStream + (Offset>>3);
+ *pOffset = Offset & 7;
+
+ /* Return N bits */
+ return Value >> (32-N);
+}
+
+/**
+ * Function: armByteAlign()
+ *
+ * Description:
+ * Align the pointer *ppBitStream to the next byte boundary
+ *
+ * Parameters:
+ * [in] *ppBitStream
+ * [in] *pOffset
+ *
+ * [out] *ppBitStream
+ * [out] *pOffset
+ *
+ **/
+
+OMXVoid armByteAlign(const OMX_U8 **ppBitStream,OMX_INT *pOffset)
+{
+ if(*pOffset > 0)
+ {
+ *ppBitStream += 1;
+ *pOffset = 0;
+ }
+}
+
+/**
+ * Function: armSkipBits()
+ *
+ * Description:
+ * Skip N bits from the value at *ppBitStream
+ *
+ * Parameters:
+ * [in] *ppBitStream
+ * [in] *pOffset
+ * [in] N
+ *
+ * [out] *ppBitStream
+ * [out] *pOffset
+ *
+ **/
+
+
+OMXVoid armSkipBits(const OMX_U8 **ppBitStream,OMX_INT *pOffset,OMX_INT N)
+{
+ OMX_INT Offset = *pOffset;
+ const OMX_U8 *pBitStream = *ppBitStream;
+
+ /* Advance bitstream pointer by N bits */
+ Offset += N;
+ *ppBitStream = pBitStream + (Offset>>3);
+ *pOffset = Offset & 7;
+}
+
+/***************************************
+ * Variable bit length Decode
+ ***************************************/
+
+/**
+ * Function: armUnPackVLC32()
+ *
+ * Description:
+ * Variable length decode of variable length symbol (max size 32 bits) read from
+ * the bit stream pointed by *ppBitStream at *pOffset by using the table
+ * pointed by pCodeBook
+ *
+ * Parameters:
+ * [in] *pBitStream
+ * [in] *pOffset
+ * [in] pCodeBook
+ *
+ * [out] *pBitStream
+ * [out] *pOffset
+ *
+ * Returns : Code Book Index if successfull.
+ * : ARM_NO_CODEBOOK_INDEX = -1 if search fails.
+ **/
+#ifndef C_OPTIMIZED_IMPLEMENTATION
+
+OMX_U16 armUnPackVLC32(
+ const OMX_U8 **ppBitStream,
+ OMX_INT *pOffset,
+ const ARM_VLC32 *pCodeBook
+)
+{
+ const OMX_U8 *pBitStream = *ppBitStream;
+ OMX_INT Offset = *pOffset;
+ OMX_U32 Value;
+ OMX_INT Index;
+
+ armAssert(Offset>=0 && Offset<=7);
+
+ /* Read next 32 bits from stream */
+ Value = (pBitStream[0] << 24 ) | ( pBitStream[1] << 16) | (pBitStream[2] << 8 ) | (pBitStream[3]) ;
+ Value = (Value << Offset ) | (pBitStream[4] >> (8-Offset));
+
+ /* Search through the codebook */
+ for (Index=0; pCodeBook->codeLen != 0; Index++)
+ {
+ if (pCodeBook->codeWord == (Value >> (32 - pCodeBook->codeLen)))
+ {
+ Offset = Offset + pCodeBook->codeLen;
+ *ppBitStream = pBitStream + (Offset >> 3) ;
+ *pOffset = Offset & 7;
+
+ return Index;
+ }
+ pCodeBook++;
+ }
+
+ /* No code match found */
+ return ARM_NO_CODEBOOK_INDEX;
+}
+
+#endif
+
+/***************************************
+ * Fixed bit length Encode
+ ***************************************/
+
+/**
+ * Function: armPackBits
+ *
+ * Description:
+ * Pack a VLC code word into the bitstream
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream pointer to the pointer to the current byte
+ * in the bit stream.
+ * [in] pOffset pointer to the bit position in the byte
+ * pointed by *ppBitStream. Valid within 0
+ * to 7.
+ * [in] codeWord Code word that need to be inserted in to the
+ * bitstream
+ * [in] codeLength Length of the code word valid range 1...32
+ *
+ * [out] ppBitStream *ppBitStream is updated after the block is encoded,
+ * so that it points to the current byte in the bit
+ * stream buffer.
+ * [out] pBitOffset *pBitOffset is updated so that it points to the
+ * current bit position in the byte pointed by
+ * *ppBitStream.
+ *
+ * Return Value:
+ * Standard OMX_RESULT result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armPackBits (
+ OMX_U8 **ppBitStream,
+ OMX_INT *pOffset,
+ OMX_U32 codeWord,
+ OMX_INT codeLength
+)
+{
+ OMX_U8 *pBitStream = *ppBitStream;
+ OMX_INT Offset = *pOffset;
+ OMX_U32 Value;
+
+ /* checking argument validity */
+ armRetArgErrIf(Offset < 0, OMX_Sts_BadArgErr);
+ armRetArgErrIf(Offset > 7, OMX_Sts_BadArgErr);
+ armRetArgErrIf(codeLength < 1, OMX_Sts_BadArgErr);
+ armRetArgErrIf(codeLength > 32, OMX_Sts_BadArgErr);
+
+ /* Prepare the first byte */
+ codeWord = codeWord << (32-codeLength);
+ Value = (pBitStream[0] >> (8-Offset)) << (8-Offset);
+ Value = Value | (codeWord >> (24+Offset));
+
+ /* Write out whole bytes */
+ while (8-Offset <= codeLength)
+ {
+ *pBitStream++ = (OMX_U8)Value;
+ codeWord = codeWord << (8-Offset);
+ codeLength = codeLength - (8-Offset);
+ Offset = 0;
+ Value = codeWord >> 24;
+ }
+
+ /* Write out final partial byte */
+ *pBitStream = (OMX_U8)Value;
+ *ppBitStream = pBitStream;
+ *pOffset = Offset + codeLength;
+
+ return OMX_Sts_NoErr;
+}
+
+/***************************************
+ * Variable bit length Encode
+ ***************************************/
+
+/**
+ * Function: armPackVLC32
+ *
+ * Description:
+ * Pack a VLC code word into the bitstream
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream pointer to the pointer to the current byte
+ * in the bit stream.
+ * [in] pBitOffset pointer to the bit position in the byte
+ * pointed by *ppBitStream. Valid within 0
+ * to 7.
+ * [in] code VLC code word that need to be inserted in to the
+ * bitstream
+ *
+ * [out] ppBitStream *ppBitStream is updated after the block is encoded,
+ * so that it points to the current byte in the bit
+ * stream buffer.
+ * [out] pBitOffset *pBitOffset is updated so that it points to the
+ * current bit position in the byte pointed by
+ * *ppBitStream.
+ *
+ * Return Value:
+ * Standard OMX_RESULT result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armPackVLC32 (
+ OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ ARM_VLC32 code
+)
+{
+ return (armPackBits(ppBitStream, pBitOffset, code.codeWord, code.codeLen));
+}
+
+/*End of File*/
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM_IDCTTable.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM_IDCTTable.c
new file mode 100755
index 0000000..3f5e279
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM_IDCTTable.c
@@ -0,0 +1,60 @@
+/**
+ *
+ * File Name: armCOMM_IDCTTable.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 12290
+ * Date: Wednesday, April 9, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * File: armCOMM_IDCTTable.c
+ * Brief: Defines Tables used in IDCT computation
+ *
+ */
+
+#include "armCOMM_IDCTTable.h"
+
+ /* Table of s(u)*A(u)*A(v)/16 at Q15
+ * s(u)=1.0 0 <= u <= 5
+ * s(6)=2.0
+ * s(7)=4.0
+ * A(0) = 2*sqrt(2)
+ * A(u) = 4*cos(u*pi/16) for (u!=0)
+ */
+
+__align(4) const OMX_U16 armCOMM_IDCTPreScale [64] =
+{
+ 0x4000, 0x58c5, 0x539f, 0x4b42, 0x4000, 0x3249, 0x4546, 0x46a1,
+ 0x58c5, 0x7b21, 0x73fc, 0x6862, 0x58c5, 0x45bf, 0x6016, 0x61f8,
+ 0x539f, 0x73fc, 0x6d41, 0x6254, 0x539f, 0x41b3, 0x5a82, 0x5c48,
+ 0x4b42, 0x6862, 0x6254, 0x587e, 0x4b42, 0x3b21, 0x5175, 0x530d,
+ 0x4000, 0x58c5, 0x539f, 0x4b42, 0x4000, 0x3249, 0x4546, 0x46a1,
+ 0x3249, 0x45bf, 0x41b3, 0x3b21, 0x3249, 0x2782, 0x366d, 0x377e,
+ 0x22a3, 0x300b, 0x2d41, 0x28ba, 0x22a3, 0x1b37, 0x257e, 0x263a,
+ 0x11a8, 0x187e, 0x1712, 0x14c3, 0x11a8, 0x0de0, 0x131d, 0x137d
+};
+ /* Above array armCOMM_IDCTPreScale, in Q23 format */
+const OMX_U32 armCOMM_IDCTPreScaleU32 [64] =
+{
+ 0x400000, 0x58c543, 0x539eba, 0x4b418c, 0x400000, 0x3248d4, 0x4545ea, 0x46a157,
+ 0x58c543, 0x7b20d8, 0x73fbfc, 0x686214, 0x58c543, 0x45bf1f, 0x6015a5, 0x61f78b,
+ 0x539eba, 0x73fbfc, 0x6d413d, 0x6253a6, 0x539eba, 0x41b328, 0x5a827a, 0x5c4869,
+ 0x4b418c, 0x686214, 0x6253a6, 0x587de3, 0x4b418c, 0x3b20d8, 0x5174e0, 0x530d69,
+ 0x400000, 0x58c543, 0x539eba, 0x4b418c, 0x400000, 0x3248d4, 0x4545ea, 0x46a157,
+ 0x3248d4, 0x45bf1f, 0x41b328, 0x3b20d8, 0x3248d4, 0x27821d, 0x366d72, 0x377e6b,
+ 0x22a2f5, 0x300ad3, 0x2d413d, 0x28ba70, 0x22a2f5, 0x1b36b9, 0x257d86, 0x26398d,
+ 0x11a856, 0x187de3, 0x17121a, 0x14c35a, 0x11a856, 0x0ddf9b, 0x131cc7, 0x137ca2
+};
+
+const OMX_U16 armCOMM_IDCTCoef [4] =
+{
+ 0x5a82, /* InvSqrt2 */
+ 0x30fc, /* SinPIBy8 */
+ 0x7642, /* CosPIBy8 */
+ 0x0000
+};
+
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM_MaskTable.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM_MaskTable.c
new file mode 100755
index 0000000..09f88c3
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM_MaskTable.c
@@ -0,0 +1,45 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: armCOMM_MaskTable.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 12290
+ * Date: Wednesday, April 9, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Mask Table to mask the end of array.
+ *
+ */
+
+#include "omxtypes.h"
+
+#define MaskTableSize 72
+
+const OMX_U16 armCOMM_qMaskTable16[MaskTableSize] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000,
+ 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000,
+ 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000,
+ 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF
+};
+
+const OMX_U8 armCOMM_qMaskTable8[MaskTableSize] =
+{
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/api/armVC.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/api/armVC.h
new file mode 100755
index 0000000..35b510b
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/api/armVC.h
@@ -0,0 +1,1153 @@
+/**
+ *
+ * File Name: armVC.h
+ * OpenMAX DL: v1.0.2
+ * Revision: 12290
+ * Date: Wednesday, April 9, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * File: armVideo.h
+ * Brief: Declares API's/Basic Data types used across the OpenMAX Video domain
+ *
+ */
+
+
+#ifndef _armVideo_H_
+#define _armVideo_H_
+
+#include "omxVC.h"
+#include "armCOMM_Bitstream.h"
+
+/**
+ * ARM specific state structure to hold Motion Estimation information.
+ */
+
+struct m4p2_MESpec
+{
+ OMXVCM4P2MEParams MEParams;
+ OMXVCM4P2MEMode MEMode;
+};
+
+struct m4p10_MESpec
+{
+ OMXVCM4P10MEParams MEParams;
+ OMXVCM4P10MEMode MEMode;
+};
+
+typedef struct m4p2_MESpec ARMVCM4P2_MESpec;
+typedef struct m4p10_MESpec ARMVCM4P10_MESpec;
+
+/**
+ * Function: armVCM4P2_CompareMV
+ *
+ * Description:
+ * Performs comparision of motion vectors and SAD's to decide the
+ * best MV and SAD
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] mvX x coordinate of the candidate motion vector
+ * [in] mvY y coordinate of the candidate motion vector
+ * [in] candSAD Candidate SAD
+ * [in] bestMVX x coordinate of the best motion vector
+ * [in] bestMVY y coordinate of the best motion vector
+ * [in] bestSAD best SAD
+ *
+ * Return Value:
+ * OMX_INT -- 1 to indicate that the current sad is the best
+ * 0 to indicate that it is NOT the best SAD
+ */
+
+OMX_INT armVCM4P2_CompareMV (
+ OMX_S16 mvX,
+ OMX_S16 mvY,
+ OMX_INT candSAD,
+ OMX_S16 bestMVX,
+ OMX_S16 bestMVY,
+ OMX_INT bestSAD);
+
+/**
+ * Function: armVCM4P2_ACDCPredict
+ *
+ * Description:
+ * Performs adaptive DC/AC coefficient prediction for an intra block. Prior
+ * to the function call, prediction direction (predDir) should be selected
+ * as specified in subclause 7.4.3.1 of ISO/IEC 14496-2.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] pSrcDst pointer to the coefficient buffer which contains
+ * the quantized coefficient residuals (PQF) of the
+ * current block
+ * [in] pPredBufRow pointer to the coefficient row buffer
+ * [in] pPredBufCol pointer to the coefficient column buffer
+ * [in] curQP quantization parameter of the current block. curQP
+ * may equal to predQP especially when the current
+ * block and the predictor block are in the same
+ * macroblock.
+ * [in] predQP quantization parameter of the predictor block
+ * [in] predDir indicates the prediction direction which takes one
+ * of the following values:
+ * OMX_VIDEO_HORIZONTAL predict horizontally
+ * OMX_VIDEO_VERTICAL predict vertically
+ * [in] ACPredFlag a flag indicating if AC prediction should be
+ * performed. It is equal to ac_pred_flag in the bit
+ * stream syntax of MPEG-4
+ * [in] videoComp video component type (luminance, chrominance or
+ * alpha) of the current block
+ * [in] flag This flag defines the if one wants to use this functions to
+ * calculate PQF (set 1, prediction) or QF (set 0, reconstruction)
+ * [out] pPreACPredict pointer to the predicted coefficients buffer.
+ * Filled ONLY if it is not NULL
+ * [out] pSrcDst pointer to the coefficient buffer which contains
+ * the quantized coefficients (QF) of the current
+ * block
+ * [out] pPredBufRow pointer to the updated coefficient row buffer
+ * [out] pPredBufCol pointer to the updated coefficient column buffer
+ * [out] pSumErr pointer to the updated sum of the difference
+ * between predicted and unpredicted coefficients
+ * If this is NULL, do not update
+ *
+ * Return Value:
+ * Standard OMXResult result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armVCM4P2_ACDCPredict(
+ OMX_S16 * pSrcDst,
+ OMX_S16 * pPreACPredict,
+ OMX_S16 * pPredBufRow,
+ OMX_S16 * pPredBufCol,
+ OMX_INT curQP,
+ OMX_INT predQP,
+ OMX_INT predDir,
+ OMX_INT ACPredFlag,
+ OMXVCM4P2VideoComponent videoComp,
+ OMX_U8 flag,
+ OMX_INT *pSumErr
+);
+
+/**
+ * Function: armVCM4P2_SetPredDir
+ *
+ * Description:
+ * Performs detecting the prediction direction
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] blockIndex block index indicating the component type and
+ * position as defined in subclause 6.1.3.8, of ISO/IEC
+ * 14496-2. Furthermore, indexes 6 to 9 indicate the
+ * alpha blocks spatially corresponding to luminance
+ * blocks 0 to 3 in the same macroblock.
+ * [in] pCoefBufRow pointer to the coefficient row buffer
+ * [in] pQpBuf pointer to the quantization parameter buffer
+ * [out] predQP quantization parameter of the predictor block
+ * [out] predDir indicates the prediction direction which takes one
+ * of the following values:
+ * OMX_VIDEO_HORIZONTAL predict horizontally
+ * OMX_VIDEO_VERTICAL predict vertically
+ *
+ * Return Value:
+ * Standard OMXResult result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armVCM4P2_SetPredDir(
+ OMX_INT blockIndex,
+ OMX_S16 *pCoefBufRow,
+ OMX_S16 *pCoefBufCol,
+ OMX_INT *predDir,
+ OMX_INT *predQP,
+ const OMX_U8 *pQpBuf
+);
+
+/**
+ * Function: armVCM4P2_EncodeVLCZigzag_Intra
+ *
+ * Description:
+ * Performs zigzag scanning and VLC encoding for one intra block.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream pointer to the pointer to the current byte in
+ * the bit stream
+ * [in] pBitOffset pointer to the bit position in the byte pointed
+ * by *ppBitStream. Valid within 0 to 7.
+ * [in] pQDctBlkCoef pointer to the quantized DCT coefficient
+ * [in] predDir AC prediction direction, which is used to decide
+ * the zigzag scan pattern. This takes one of the
+ * following values:
+ * OMX_VIDEO_NONE AC prediction not used.
+ * Performs classical zigzag
+ * scan.
+ * OMX_VIDEO_HORIZONTAL Horizontal prediction.
+ * Performs alternate-vertical
+ * zigzag scan.
+ * OMX_VIDEO_VERTICAL Vertical prediction.
+ * Performs alternate-horizontal
+ * zigzag scan.
+ * [in] pattern block pattern which is used to decide whether
+ * this block is encoded
+ * [in] start start indicates whether the encoding begins with 0th element
+ * or 1st.
+ * [out] ppBitStream *ppBitStream is updated after the block is encoded,
+ * so that it points to the current byte in the bit
+ * stream buffer.
+ * [out] pBitOffset *pBitOffset is updated so that it points to the
+ * current bit position in the byte pointed by
+ * *ppBitStream.
+ *
+ * Return Value:
+ * Standard OMXResult result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armVCM4P2_EncodeVLCZigzag_Intra(
+ OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ const OMX_S16 *pQDctBlkCoef,
+ OMX_U8 predDir,
+ OMX_U8 pattern,
+ OMX_INT shortVideoHeader,
+ OMX_U8 start
+);
+
+/**
+ * Function: armVCM4P2_DecodeVLCZigzag_Intra
+ *
+ * Description:
+ * Performs VLC decoding and inverse zigzag scan for one intra coded block.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream pointer to the pointer to the current byte in
+ * the bitstream buffer
+ * [in] pBitOffset pointer to the bit position in the byte pointed
+ * to by *ppBitStream. *pBitOffset is valid within
+ * [0-7].
+ * [in] predDir AC prediction direction which is used to decide
+ * the zigzag scan pattern. It takes one of the
+ * following values:
+ * OMX_VIDEO_NONE AC prediction not used;
+ * perform classical zigzag scan;
+ * OMX_VIDEO_HORIZONTAL Horizontal prediction;
+ * perform alternate-vertical
+ * zigzag scan;
+ * OMX_VIDEO_VERTICAL Vertical prediction;
+ * thus perform
+ * alternate-horizontal
+ * zigzag scan.
+ * [in] videoComp video component type (luminance, chrominance or
+ * alpha) of the current block
+ * [in] shortVideoHeader binary flag indicating presence of short_video_header; escape modes 0-3 are used if shortVideoHeader==0,
+ * and escape mode 4 is used when shortVideoHeader==1.
+ * [in] start start indicates whether the encoding begins with 0th element
+ * or 1st.
+ * [out] ppBitStream *ppBitStream is updated after the block is
+ * decoded, so that it points to the current byte
+ * in the bit stream buffer
+ * [out] pBitOffset *pBitOffset is updated so that it points to the
+ * current bit position in the byte pointed by
+ * *ppBitStream
+ * [out] pDst pointer to the coefficient buffer of current
+ * block. Should be 32-bit aligned
+ *
+ * Return Value:
+ * Standard OMXResult result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armVCM4P2_DecodeVLCZigzag_Intra(
+ const OMX_U8 ** ppBitStream,
+ OMX_INT * pBitOffset,
+ OMX_S16 * pDst,
+ OMX_U8 predDir,
+ OMX_INT shortVideoHeader,
+ OMX_U8 start
+);
+
+/**
+ * Function: armVCM4P2_FillVLDBuffer
+ *
+ * Description:
+ * Performs filling of the coefficient buffer according to the run, level
+ * and sign, also updates the index
+ *
+ * Parameters:
+ * [in] storeRun Stored Run value (count of zeros)
+ * [in] storeLevel Stored Level value (non-zero value)
+ * [in] sign Flag indicating the sign of level
+ * [in] last status of the last flag
+ * [in] pIndex pointer to coefficient index in 8x8 matrix
+ * [out] pIndex pointer to updated coefficient index in 8x8
+ * matrix
+ * [in] pZigzagTable pointer to the zigzag tables
+ * [out] pDst pointer to the coefficient buffer of current
+ * block. Should be 32-bit aligned
+ * Return Value:
+ * Standard OMXResult result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armVCM4P2_FillVLDBuffer(
+ OMX_U32 storeRun,
+ OMX_S16 * pDst,
+ OMX_S16 storeLevel,
+ OMX_U8 sign,
+ OMX_U8 last,
+ OMX_U8 * index,
+ const OMX_U8 * pZigzagTable
+);
+
+/**
+ * Function: armVCM4P2_GetVLCBits
+ *
+ * Description:
+ * Performs escape mode decision based on the run, run+, level, level+ and
+ * last combinations.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream pointer to the pointer to the current byte in
+ * the bit stream
+ * [in] pBitOffset pointer to the bit position in the byte pointed
+ * by *ppBitStream. Valid within 0 to 7
+ * [in] shortVideoHeader binary flag indicating presence of short_video_header; escape modes 0-3 are used if shortVideoHeader==0,
+ * and escape mode 4 is used when shortVideoHeader==1.
+ * [in] start start indicates whether the encoding begins with
+ * 0th element or 1st.
+ * [in/out] pLast pointer to last status flag
+ * [in] runBeginSingleLevelEntriesL0 The run value from which level
+ * will be equal to 1: last == 0
+ * [in] IndexBeginSingleLevelEntriesL0 Array index in the VLC table
+ * pointing to the
+ * runBeginSingleLevelEntriesL0
+ * [in] runBeginSingleLevelEntriesL1 The run value from which level
+ * will be equal to 1: last == 1
+ * [in] IndexBeginSingleLevelEntriesL1 Array index in the VLC table
+ * pointing to the
+ * runBeginSingleLevelEntriesL0
+ * [in] pRunIndexTableL0 Run Index table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 0
+ * [in] pVlcTableL0 VLC table for last == 0
+ * [in] pRunIndexTableL1 Run Index table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 1
+ * [in] pVlcTableL1 VLC table for last == 1
+ * [in] pLMAXTableL0 Level MAX table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 0
+ * [in] pLMAXTableL1 Level MAX table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 1
+ * [in] pRMAXTableL0 Run MAX table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 0
+ * [in] pRMAXTableL1 Run MAX table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 1
+ * [out]pDst pointer to the coefficient buffer of current
+ * block. Should be 32-bit aligned
+ *
+ * Return Value:
+ * Standard OMXResult result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armVCM4P2_GetVLCBits (
+ const OMX_U8 **ppBitStream,
+ OMX_INT * pBitOffset,
+ OMX_S16 * pDst,
+ OMX_INT shortVideoHeader,
+ OMX_U8 start,
+ OMX_U8 * pLast,
+ OMX_U8 runBeginSingleLevelEntriesL0,
+ OMX_U8 maxIndexForMultipleEntriesL0,
+ OMX_U8 maxRunForMultipleEntriesL1,
+ OMX_U8 maxIndexForMultipleEntriesL1,
+ const OMX_U8 * pRunIndexTableL0,
+ const ARM_VLC32 *pVlcTableL0,
+ const OMX_U8 * pRunIndexTableL1,
+ const ARM_VLC32 *pVlcTableL1,
+ const OMX_U8 * pLMAXTableL0,
+ const OMX_U8 * pLMAXTableL1,
+ const OMX_U8 * pRMAXTableL0,
+ const OMX_U8 * pRMAXTableL1,
+ const OMX_U8 * pZigzagTable
+);
+
+/**
+ * Function: armVCM4P2_PutVLCBits
+ *
+ * Description:
+ * Checks the type of Escape Mode and put encoded bits for
+ * quantized DCT coefficients.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream pointer to the pointer to the current byte in
+ * the bit stream
+ * [in] pBitOffset pointer to the bit position in the byte pointed
+ * by *ppBitStream. Valid within 0 to 7
+ * [in] shortVideoHeader binary flag indicating presence of short_video_header; escape modes 0-3 are used if shortVideoHeader==0,
+ * and escape mode 4 is used when shortVideoHeader==1.
+ * [in] start start indicates whether the encoding begins with
+ * 0th element or 1st.
+ * [in] maxStoreRunL0 Max store possible (considering last and inter/intra)
+ * for last = 0
+ * [in] maxStoreRunL1 Max store possible (considering last and inter/intra)
+ * for last = 1
+ * [in] maxRunForMultipleEntriesL0
+ * The run value after which level
+ * will be equal to 1:
+ * (considering last and inter/intra status) for last = 0
+ * [in] maxRunForMultipleEntriesL1
+ * The run value after which level
+ * will be equal to 1:
+ * (considering last and inter/intra status) for last = 1
+ * [in] pRunIndexTableL0 Run Index table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 0
+ * [in] pVlcTableL0 VLC table for last == 0
+ * [in] pRunIndexTableL1 Run Index table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 1
+ * [in] pVlcTableL1 VLC table for last == 1
+ * [in] pLMAXTableL0 Level MAX table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 0
+ * [in] pLMAXTableL1 Level MAX table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 1
+ * [in] pRMAXTableL0 Run MAX table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 0
+ * [in] pRMAXTableL1 Run MAX table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 1
+ * [out] pQDctBlkCoef pointer to the quantized DCT coefficient
+ * [out] ppBitStream *ppBitStream is updated after the block is encoded
+ * so that it points to the current byte in the bit
+ * stream buffer.
+ * [out] pBitOffset *pBitOffset is updated so that it points to the
+ * current bit position in the byte pointed by
+ * *ppBitStream.
+ *
+ * Return Value:
+ * Standard OMXResult result. See enumeration for possible result codes.
+ *
+ */
+
+
+OMXResult armVCM4P2_PutVLCBits (
+ OMX_U8 **ppBitStream,
+ OMX_INT * pBitOffset,
+ const OMX_S16 *pQDctBlkCoef,
+ OMX_INT shortVideoHeader,
+ OMX_U8 start,
+ OMX_U8 maxStoreRunL0,
+ OMX_U8 maxStoreRunL1,
+ OMX_U8 maxRunForMultipleEntriesL0,
+ OMX_U8 maxRunForMultipleEntriesL1,
+ const OMX_U8 * pRunIndexTableL0,
+ const ARM_VLC32 *pVlcTableL0,
+ const OMX_U8 * pRunIndexTableL1,
+ const ARM_VLC32 *pVlcTableL1,
+ const OMX_U8 * pLMAXTableL0,
+ const OMX_U8 * pLMAXTableL1,
+ const OMX_U8 * pRMAXTableL0,
+ const OMX_U8 * pRMAXTableL1,
+ const OMX_U8 * pZigzagTable
+);
+/**
+ * Function: armVCM4P2_FillVLCBuffer
+ *
+ * Description:
+ * Performs calculating the VLC bits depending on the escape type and insert
+ * the same in the bitstream
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream pointer to the pointer to the current byte in
+ * the bit stream
+ * [in] pBitOffset pointer to the bit position in the byte pointed
+ * by *ppBitStream. Valid within 0 to 7
+ * [in] run Run value (count of zeros) to be encoded
+ * [in] level Level value (non-zero value) to be encoded
+ * [in] runPlus Calculated as runPlus = run - (RMAX + 1)
+ * [in] levelPlus Calculated as
+ * levelPlus = sign(level)*[abs(level) - LMAX]
+ * [in] fMode Flag indicating the escape modes
+ * [in] last status of the last flag
+ * [in] maxRunForMultipleEntries
+ * The run value after which level will be equal to 1:
+ * (considering last and inter/intra status)
+ * [in] pRunIndexTable Run Index table defined in
+ * armVCM4P2_Huff_tables_VLC.h
+ * [in] pVlcTable VLC table defined in armVCM4P2_Huff_tables_VLC.h
+ * [out] ppBitStream *ppBitStream is updated after the block is encoded
+ * so that it points to the current byte in the bit
+ * stream buffer.
+ * [out] pBitOffset *pBitOffset is updated so that it points to the
+ * current bit position in the byte pointed by
+ * *ppBitStream.
+ *
+ * Return Value:
+ * Standard OMXResult result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armVCM4P2_FillVLCBuffer (
+ OMX_U8 **ppBitStream,
+ OMX_INT * pBitOffset,
+ OMX_U32 run,
+ OMX_S16 level,
+ OMX_U32 runPlus,
+ OMX_S16 levelPlus,
+ OMX_U8 fMode,
+ OMX_U8 last,
+ OMX_U8 maxRunForMultipleEntries,
+ const OMX_U8 *pRunIndexTable,
+ const ARM_VLC32 *pVlcTable
+);
+
+/**
+ * Function: armVCM4P2_CheckVLCEscapeMode
+ *
+ * Description:
+ * Performs escape mode decision based on the run, run+, level, level+ and
+ * last combinations.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] run Run value (count of zeros) to be encoded
+ * [in] level Level value (non-zero value) to be encoded
+ * [in] runPlus Calculated as runPlus = run - (RMAX + 1)
+ * [in] levelPlus Calculated as
+ * levelPlus = sign(level)*[abs(level) - LMAX]
+ * [in] maxStoreRun Max store possible (considering last and inter/intra)
+ * [in] maxRunForMultipleEntries
+ * The run value after which level
+ * will be equal to 1:
+ * (considering last and inter/intra status)
+ * [in] shortVideoHeader binary flag indicating presence of short_video_header; escape modes 0-3 are used if shortVideoHeader==0,
+ * and escape mode 4 is used when shortVideoHeader==1.
+ * [in] pRunIndexTable Run Index table defined in
+ * armVCM4P2_Huff_Tables_VLC.c
+ * (considering last and inter/intra status)
+ *
+ *
+ * Return Value:
+ * Returns an Escape mode which can take values from 0 to 3
+ * 0 --> no escape mode, 1 --> escape type 1,
+ * 1 --> escape type 2, 3 --> escape type 3, check section 7.4.1.3
+ * in the MPEG ISO standard.
+ *
+ */
+
+OMX_U8 armVCM4P2_CheckVLCEscapeMode(
+ OMX_U32 run,
+ OMX_U32 runPlus,
+ OMX_S16 level,
+ OMX_S16 levelPlus,
+ OMX_U8 maxStoreRun,
+ OMX_U8 maxRunForMultipleEntries,
+ OMX_INT shortVideoHeader,
+ const OMX_U8 *pRunIndexTable
+);
+
+
+/**
+ * Function: armVCM4P2_BlockMatch_Integer
+ *
+ * Description:
+ * Performs a 16x16 block search; estimates motion vector and associated minimum SAD.
+ * Both the input and output motion vectors are represented using half-pixel units, and
+ * therefore a shift left or right by 1 bit may be required, respectively, to match the
+ * input or output MVs with other functions that either generate output MVs or expect
+ * input MVs represented using integer pixel units.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] pSrcRefBuf pointer to the reference Y plane; points to the reference MB that
+ * corresponds to the location of the current macroblock in the current
+ * plane.
+ * [in] refWidth width of the reference plane
+ * [in] pRefRect pointer to the valid rectangular in reference plane. Relative to image origin.
+ * It's not limited to the image boundary, but depended on the padding. For example,
+ * if you pad 4 pixels outside the image border, then the value for left border
+ * can be -4
+ * [in] pSrcCurrBuf pointer to the current macroblock extracted from original plane (linear array,
+ * 256 entries); must be aligned on an 8-byte boundary.
+ * [in] pCurrPointPos position of the current macroblock in the current plane
+ * [in] pSrcPreMV pointer to predicted motion vector; NULL indicates no predicted MV
+ * [in] pSrcPreSAD pointer to SAD associated with the predicted MV (referenced by pSrcPreMV)
+ * [in] searchRange search range for 16X16 integer block,the units of it is full pixel,the search range
+ * is the same in all directions.It is in inclusive of the boundary and specified in
+ * terms of integer pixel units.
+ * [in] pMESpec vendor-specific motion estimation specification structure; must have been allocated
+ * and then initialized using omxVCM4P2_MEInit prior to calling the block matching
+ * function.
+ * [in] BlockSize MacroBlock Size i.e either 16x16 or 8x8.
+ * [out] pDstMV pointer to estimated MV
+ * [out] pDstSAD pointer to minimum SAD
+ *
+ * Return Value:
+ * OMX_Sts_NoErr ¨C no error.
+ * OMX_Sts_BadArgErr ¨C bad arguments
+ *
+ */
+
+OMXResult armVCM4P2_BlockMatch_Integer(
+ const OMX_U8 *pSrcRefBuf,
+ OMX_INT refWidth,
+ const OMXRect *pRefRect,
+ const OMX_U8 *pSrcCurrBuf,
+ const OMXVCM4P2Coordinate *pCurrPointPos,
+ const OMXVCMotionVector *pSrcPreMV,
+ const OMX_INT *pSrcPreSAD,
+ void *pMESpec,
+ OMXVCMotionVector *pDstMV,
+ OMX_INT *pDstSAD,
+ OMX_U8 BlockSize
+);
+
+/**
+ * Function: armVCM4P2_BlockMatch_Half
+ *
+ * Description:
+ * Performs a 16x16 block match with half-pixel resolution. Returns the estimated
+ * motion vector and associated minimum SAD. This function estimates the half-pixel
+ * motion vector by interpolating the integer resolution motion vector referenced
+ * by the input parameter pSrcDstMV, i.e., the initial integer MV is generated
+ * externally. The input parameters pSrcRefBuf and pSearchPointRefPos should be
+ * shifted by the winning MV of 16x16 integer search prior to calling BlockMatch_Half_16x16.
+ * The function BlockMatch_Integer_16x16 may be used for integer motion estimation.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] pSrcRefBuf pointer to the reference Y plane; points to the reference MB
+ * that corresponds to the location of the current macroblock in
+ * the current plane.
+ * [in] refWidth width of the reference plane
+ * [in] pRefRect reference plane valid region rectangle
+ * [in] pSrcCurrBuf pointer to the current macroblock extracted from original plane
+ * (linear array, 256 entries); must be aligned on an 8-byte boundary.
+ * [in] pSearchPointRefPos position of the starting point for half pixel search (specified
+ * in terms of integer pixel units) in the reference plane.
+ * [in] rndVal rounding control bit for half pixel motion estimation;
+ * 0=rounding control disabled; 1=rounding control enabled
+ * [in] pSrcDstMV pointer to the initial MV estimate; typically generated during a prior
+ * 16X16 integer search and its unit is half pixel.
+ * [in] BlockSize MacroBlock Size i.e either 16x16 or 8x8.
+ * [out]pSrcDstMV pointer to estimated MV
+ * [out]pDstSAD pointer to minimum SAD
+ *
+ * Return Value:
+ * OMX_Sts_NoErr ¨C no error
+ * OMX_Sts_BadArgErr ¨C bad arguments
+ *
+ */
+
+OMXResult armVCM4P2_BlockMatch_Half(
+ const OMX_U8 *pSrcRefBuf,
+ OMX_INT refWidth,
+ const OMXRect *pRefRect,
+ const OMX_U8 *pSrcCurrBuf,
+ const OMXVCM4P2Coordinate *pSearchPointRefPos,
+ OMX_INT rndVal,
+ OMXVCMotionVector *pSrcDstMV,
+ OMX_INT *pDstSAD,
+ OMX_U8 BlockSize
+);
+/**
+ * Function: armVCM4P2_PadMV
+ *
+ * Description:
+ * Performs motion vector padding for a macroblock.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] pSrcDstMV pointer to motion vector buffer of the current
+ * macroblock
+ * [in] pTransp pointer to transparent status buffer of the
+ * current macroblock
+ * [out] pSrcDstMV pointer to motion vector buffer in which the
+ * motion vectors have been padded
+ * Return Value:
+ * Standard OMXResult result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armVCM4P2_PadMV(
+ OMXVCMotionVector * pSrcDstMV,
+ OMX_U8 * pTransp
+);
+
+/*
+ * H.264 Specific Declarations
+ */
+/* Defines */
+#define ARM_M4P10_Q_OFFSET (15)
+
+
+/* Dequant tables */
+
+extern const OMX_U8 armVCM4P10_PosToVCol4x4[16];
+extern const OMX_U8 armVCM4P10_PosToVCol2x2[4];
+extern const OMX_U8 armVCM4P10_VMatrix[6][3];
+extern const OMX_U32 armVCM4P10_MFMatrix[6][3];
+
+
+/*
+ * Description:
+ * This function perform the work required by the OpenMAX
+ * DecodeCoeffsToPair function and DecodeChromaDCCoeffsToPair.
+ * Since most of the code is common we share it here.
+ *
+ * Parameters:
+ * [in] ppBitStream Double pointer to current byte in bit stream buffer
+ * [in] pOffset Pointer to current bit position in the byte pointed
+ * to by *ppBitStream
+ * [in] sMaxNumCoeff Maximum number of non-zero coefficients in current
+ * block (4,15 or 16)
+ * [in] nTable Table number (0 to 4) according to the five columns
+ * of Table 9-5 in the H.264 spec
+ * [out] ppBitStream *ppBitStream is updated after each block is decoded
+ * [out] pOffset *pOffset is updated after each block is decoded
+ * [out] pNumCoeff Pointer to the number of nonzero coefficients in
+ * this block
+ * [out] ppPosCoefbuf Double pointer to destination residual
+ * coefficient-position pair buffer
+ * Return Value:
+ * Standard omxError result. See enumeration for possible result codes.
+
+ */
+
+OMXResult armVCM4P10_DecodeCoeffsToPair(
+ const OMX_U8** ppBitStream,
+ OMX_S32* pOffset,
+ OMX_U8* pNumCoeff,
+ OMX_U8**ppPosCoefbuf,
+ OMX_INT nTable,
+ OMX_INT sMaxNumCoeff
+ );
+
+/*
+ * Description:
+ * Perform DC style intra prediction, averaging upper and left block
+ *
+ * Parameters:
+ * [in] pSrcLeft Pointer to the buffer of 16 left coefficients:
+ * p[x, y] (x = -1, y = 0..3)
+ * [in] pSrcAbove Pointer to the buffer of 16 above coefficients:
+ * p[x,y] (x = 0..3, y = -1)
+ * [in] leftStep Step of left coefficient buffer
+ * [in] dstStep Step of the destination buffer
+ * [in] availability Neighboring 16x16 MB availability flag
+ * [out] pDst Pointer to the destination buffer
+ *
+ * Return Value:
+ * None
+ */
+
+void armVCM4P10_PredictIntraDC4x4(
+ const OMX_U8* pSrcLeft,
+ const OMX_U8 *pSrcAbove,
+ OMX_U8* pDst,
+ OMX_INT leftStep,
+ OMX_INT dstStep,
+ OMX_S32 availability
+);
+
+/*
+ * Description
+ * Unpack a 4x4 block of coefficient-residual pair values
+ *
+ * Parameters:
+ * [in] ppSrc Double pointer to residual coefficient-position pair
+ * buffer output by CALVC decoding
+ * [out] ppSrc *ppSrc is updated to the start of next non empty block
+ * [out] pDst Pointer to unpacked 4x4 block
+ */
+
+void armVCM4P10_UnpackBlock4x4(
+ const OMX_U8 **ppSrc,
+ OMX_S16* pDst
+);
+
+/*
+ * Description
+ * Unpack a 2x2 block of coefficient-residual pair values
+ *
+ * Parameters:
+ * [in] ppSrc Double pointer to residual coefficient-position pair
+ * buffer output by CALVC decoding
+ * [out] ppSrc *ppSrc is updated to the start of next non empty block
+ * [out] pDst Pointer to unpacked 4x4 block
+ */
+
+void armVCM4P10_UnpackBlock2x2(
+ const OMX_U8 **ppSrc,
+ OMX_S16* pDst
+);
+
+/*
+ * Description
+ * Deblock one boundary pixel
+ *
+ * Parameters:
+ * [in] pQ0 Pointer to pixel q0
+ * [in] Step Step between pixels q0 and q1
+ * [in] tC0 Edge threshold value
+ * [in] alpha alpha threshold value
+ * [in] beta beta threshold value
+ * [in] bS deblocking strength
+ * [in] ChromaFlag True for chroma blocks
+ * [out] pQ0 Deblocked pixels
+ *
+ */
+
+void armVCM4P10_DeBlockPixel(
+ OMX_U8 *pQ0, /* pointer to the pixel q0 */
+ int Step, /* step between pixels q0 and q1 */
+ int tC0, /* edge threshold value */
+ int alpha, /* alpha */
+ int beta, /* beta */
+ int bS, /* deblocking strength */
+ int ChromaFlag
+);
+
+/**
+ * Function: armVCM4P10_InterpolateHalfHor_Luma
+ *
+ * Description:
+ * This function performs interpolation for horizontal 1/2-pel positions
+ *
+ * Remarks:
+ *
+ * [in] pSrc Pointer to top-left corner of block used to interpolate
+ in the reconstructed frame plane
+ * [in] iSrcStep Step of the source buffer.
+ * [in] iDstStep Step of the destination(interpolation) buffer.
+ * [in] iWidth Width of the current block
+ * [in] iHeight Height of the current block
+ * [out] pDst Pointer to the interpolation buffer of the 1/2-pel
+ *
+ * Return Value:
+ * Standard OMXResult value.
+ *
+ */
+
+OMXResult armVCM4P10_InterpolateHalfHor_Luma(
+ const OMX_U8* pSrc,
+ OMX_U32 iSrcStep,
+ OMX_U8* pDst,
+ OMX_U32 iDstStep,
+ OMX_U32 iWidth,
+ OMX_U32 iHeight
+);
+
+/**
+ * Function: armVCM4P10_InterpolateHalfVer_Luma
+ *
+ * Description:
+ * This function performs interpolation for vertical 1/2-pel positions
+ * around a full-pel position.
+ *
+ * Remarks:
+ *
+ * [in] pSrc Pointer to top-left corner of block used to interpolate
+ * in the reconstructed frame plane
+ * [in] iSrcStep Step of the source buffer.
+ * [in] iDstStep Step of the destination(interpolation) buffer.
+ * [in] iWidth Width of the current block
+ * [in] iHeight Height of the current block
+ * [out] pDst Pointer to the interpolation buffer of the 1/2-pel
+ *
+ * Return Value:
+ * Standard OMXResult value.
+ *
+ */
+
+OMXResult armVCM4P10_InterpolateHalfVer_Luma(
+ const OMX_U8* pSrc,
+ OMX_U32 iSrcStep,
+ OMX_U8* pDst,
+ OMX_U32 iDstStep,
+ OMX_U32 iWidth,
+ OMX_U32 iHeight
+);
+
+/**
+ * Function: armVCM4P10_InterpolateHalfDiag_Luma
+ *
+ * Description:
+ * This function performs interpolation for (1/2, 1/2) positions
+ * around a full-pel position.
+ *
+ * Remarks:
+ *
+ * [in] pSrc Pointer to top-left corner of block used to interpolate
+ * in the reconstructed frame plane
+ * [in] iSrcStep Step of the source buffer.
+ * [in] iDstStep Step of the destination(interpolation) buffer.
+ * [in] iWidth Width of the current block
+ * [in] iHeight Height of the current block
+ * [out] pDst Pointer to the interpolation buffer of the (1/2,1/2)-pel
+ *
+ * Return Value:
+ * Standard OMXResult value.
+ *
+ */
+
+OMXResult armVCM4P10_InterpolateHalfDiag_Luma(
+ const OMX_U8* pSrc,
+ OMX_U32 iSrcStep,
+ OMX_U8* pDst,
+ OMX_U32 iDstStep,
+ OMX_U32 iWidth,
+ OMX_U32 iHeight
+);
+
+/*
+ * Description:
+ * Transform Residual 4x4 Coefficients
+ *
+ * Parameters:
+ * [in] pSrc Source 4x4 block
+ * [out] pDst Destination 4x4 block
+ *
+ */
+
+void armVCM4P10_TransformResidual4x4(OMX_S16* pDst, OMX_S16 *pSrc);
+
+/*
+ * Description:
+ * Forward Transform Residual 4x4 Coefficients
+ *
+ * Parameters:
+ * [in] pSrc Source 4x4 block
+ * [out] pDst Destination 4x4 block
+ *
+ */
+
+void armVCM4P10_FwdTransformResidual4x4(OMX_S16* pDst, OMX_S16 *pSrc);
+
+OMX_INT armVCM4P10_CompareMotionCostToMV (
+ OMX_S16 mvX,
+ OMX_S16 mvY,
+ OMXVCMotionVector diffMV,
+ OMX_INT candSAD,
+ OMXVCMotionVector *bestMV,
+ OMX_U32 nLamda,
+ OMX_S32 *pBestCost);
+
+/**
+ * Function: armVCCOMM_SAD
+ *
+ * Description:
+ * This function calculate the SAD for NxM blocks.
+ *
+ * Remarks:
+ *
+ * [in] pSrcOrg Pointer to the original block
+ * [in] iStepOrg Step of the original block buffer
+ * [in] pSrcRef Pointer to the reference block
+ * [in] iStepRef Step of the reference block buffer
+ * [in] iHeight Height of the block
+ * [in] iWidth Width of the block
+ * [out] pDstSAD Pointer of result SAD
+ *
+ * Return Value:
+ * Standard OMXResult value.
+ *
+ */
+OMXResult armVCCOMM_SAD(
+ const OMX_U8* pSrcOrg,
+ OMX_U32 iStepOrg,
+ const OMX_U8* pSrcRef,
+ OMX_U32 iStepRef,
+ OMX_S32* pDstSAD,
+ OMX_U32 iHeight,
+ OMX_U32 iWidth);
+
+/**
+ * Function: armVCCOMM_Average
+ *
+ * Description:
+ * This function calculates the average of two blocks and stores the result.
+ *
+ * Remarks:
+ *
+ * [in] pPred0 Pointer to the top-left corner of reference block 0
+ * [in] pPred1 Pointer to the top-left corner of reference block 1
+ * [in] iPredStep0 Step of reference block 0
+ * [in] iPredStep1 Step of reference block 1
+ * [in] iDstStep Step of the destination buffer
+ * [in] iWidth Width of the blocks
+ * [in] iHeight Height of the blocks
+ * [out] pDstPred Pointer to the destination buffer
+ *
+ * Return Value:
+ * Standard OMXResult value.
+ *
+ */
+ OMXResult armVCCOMM_Average (
+ const OMX_U8* pPred0,
+ const OMX_U8* pPred1,
+ OMX_U32 iPredStep0,
+ OMX_U32 iPredStep1,
+ OMX_U8* pDstPred,
+ OMX_U32 iDstStep,
+ OMX_U32 iWidth,
+ OMX_U32 iHeight
+);
+
+/**
+ * Function: armVCM4P10_SADQuar
+ *
+ * Description:
+ * This function calculates the SAD between one block (pSrc) and the
+ * average of the other two (pSrcRef0 and pSrcRef1)
+ *
+ * Remarks:
+ *
+ * [in] pSrc Pointer to the original block
+ * [in] pSrcRef0 Pointer to reference block 0
+ * [in] pSrcRef1 Pointer to reference block 1
+ * [in] iSrcStep Step of the original block buffer
+ * [in] iRefStep0 Step of reference block 0
+ * [in] iRefStep1 Step of reference block 1
+ * [in] iHeight Height of the block
+ * [in] iWidth Width of the block
+ * [out] pDstSAD Pointer of result SAD
+ *
+ * Return Value:
+ * Standard OMXResult value.
+ *
+ */
+OMXResult armVCM4P10_SADQuar(
+ const OMX_U8* pSrc,
+ const OMX_U8* pSrcRef0,
+ const OMX_U8* pSrcRef1,
+ OMX_U32 iSrcStep,
+ OMX_U32 iRefStep0,
+ OMX_U32 iRefStep1,
+ OMX_U32* pDstSAD,
+ OMX_U32 iHeight,
+ OMX_U32 iWidth
+);
+
+/**
+ * Function: armVCM4P10_Interpolate_Chroma
+ *
+ * Description:
+ * This function performs interpolation for chroma components.
+ *
+ * Remarks:
+ *
+ * [in] pSrc Pointer to top-left corner of block used to
+ * interpolate in the reconstructed frame plane
+ * [in] iSrcStep Step of the source buffer.
+ * [in] iDstStep Step of the destination(interpolation) buffer.
+ * [in] iWidth Width of the current block
+ * [in] iHeight Height of the current block
+ * [in] dx Fractional part of horizontal motion vector
+ * component in 1/8 pixel unit (0~7)
+ * [in] dy Fractional part of vertical motion vector
+ * component in 1/8 pixel unit (0~7)
+ * [out] pDst Pointer to the interpolation buffer
+ *
+ * Return Value:
+ * Standard OMXResult value.
+ *
+ */
+ OMXResult armVCM4P10_Interpolate_Chroma(
+ OMX_U8 *pSrc,
+ OMX_U32 iSrcStep,
+ OMX_U8 *pDst,
+ OMX_U32 iDstStep,
+ OMX_U32 iWidth,
+ OMX_U32 iHeight,
+ OMX_U32 dx,
+ OMX_U32 dy
+);
+
+/**
+ * Function: armVCM4P10_Interpolate_Luma
+ *
+ * Description:
+ * This function performs interpolation for luma components.
+ *
+ * Remarks:
+ *
+ * [in] pSrc Pointer to top-left corner of block used to
+ * interpolate in the reconstructed frame plane
+ * [in] iSrcStep Step of the source buffer.
+ * [in] iDstStep Step of the destination(interpolation) buffer.
+ * [in] iWidth Width of the current block
+ * [in] iHeight Height of the current block
+ * [in] dx Fractional part of horizontal motion vector
+ * component in 1/4 pixel unit (0~3)
+ * [in] dy Fractional part of vertical motion vector
+ * component in 1/4 pixel unit (0~3)
+ * [out] pDst Pointer to the interpolation buffer
+ *
+ * Return Value:
+ * Standard OMXResult value.
+ *
+ */
+
+ OMXResult armVCM4P10_Interpolate_Luma(
+ const OMX_U8 *pSrc,
+ OMX_U32 iSrcStep,
+ OMX_U8 *pDst,
+ OMX_U32 iDstStep,
+ OMX_U32 iWidth,
+ OMX_U32 iHeight,
+ OMX_U32 dx,
+ OMX_U32 dy
+);
+
+/**
+ * Function: omxVCH264_DequantTransformACFromPair_U8_S16_C1_DLx
+ *
+ * Description:
+ * Reconstruct the 4x4 residual block from coefficient-position pair buffer,
+ * perform dequantisation and integer inverse transformation for 4x4 block of
+ * residuals and update the pair buffer pointer to next non-empty block.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppSrc Double pointer to residual coefficient-position
+ * pair buffer output by CALVC decoding
+ * [in] pDC Pointer to the DC coefficient of this block, NULL
+ * if it doesn't exist
+ * [in] QP Quantization parameter
+ * [in] AC Flag indicating if at least one non-zero coefficient exists
+ * [out] pDst pointer to the reconstructed 4x4 block data
+ *
+ * Return Value:
+ * Standard omxError result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armVCM4P10_DequantTransformACFromPair_U8_S16_C1_DLx(
+ OMX_U8 **ppSrc,
+ OMX_S16 *pDst,
+ OMX_INT QP,
+ OMX_S16* pDC,
+ int AC
+);
+
+#endif /*_armVideo_H_*/
+
+/*End of File*/
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/api/armVCCOMM_s.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/api/armVCCOMM_s.h
new file mode 100755
index 0000000..32a0166
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/api/armVCCOMM_s.h
@@ -0,0 +1,72 @@
+;//
+;//
+;// File Name: armVCCOMM_s.h
+;// OpenMAX DL: v1.0.2
+;// Revision: 12290
+;// Date: Wednesday, April 9, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+;// ARM optimized OpenMAX AC header file
+;//
+;// Formula used:
+;// MACRO for calculating median for three values.
+
+
+
+ IF :LNOT::DEF:ARMVCCOMM_S_H
+ INCLUDE armCOMM_s.h
+ M_VARIANTS CortexA8, ARM1136JS
+
+ IF ARM1136JS :LOR: CortexA8
+
+ ;///*
+ ;// * Macro: M_MEDIAN3
+ ;// *
+ ;// * Description: Finds the median of three numbers
+ ;// *
+ ;// * Remarks:
+ ;// *
+ ;// * Parameters:
+ ;// * [in] x First entry for the list of three numbers.
+ ;// * [in] y Second entry for the list of three numbers.
+ ;// * Input value may be corrupted at the end of
+ ;// * the execution of this macro.
+ ;// * [in] z Third entry of the list of three numbers.
+ ;// * Input value corrupted at the end of the
+ ;// * execution of this macro.
+ ;// * [in] t Temporary scratch register.
+ ;// * [out]z Median of the three numbers.
+ ;// */
+
+ MACRO
+
+ M_MEDIAN3 $x, $y, $z, $t
+
+ SUBS $t, $y, $z; // if (y < z)
+ ADDLT $z, $z, $t; // swap y and z
+ SUBLT $y, $y, $t;
+
+ ;// Now z' <= y', so there are three cases for the
+ ;// median value, depending on x.
+
+ ;// 1) x <= z' <= y' : median value is z'
+ ;// 2) z' <= x <= y' : median value is x
+ ;// 3) z' <= y' <= x : median value is y'
+
+ CMP $z, $x; // if ( x > min(y,z) )
+ MOVLT $z, $x; // ans = x
+
+ CMP $x, $y; // if ( x > max(y,z) )
+ MOVGT $z, $y; // ans = max(y,z)
+
+ MEND
+ ENDIF
+
+
+
+ ENDIF ;// ARMACCOMM_S_H
+
+ END
\ No newline at end of file
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/api/omxVC.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/api/omxVC.h
new file mode 100755
index 0000000..7b3cc72
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/api/omxVC.h
@@ -0,0 +1,4381 @@
+/**
+ * File: omxVC.h
+ * Brief: OpenMAX DL v1.0.2 - Video Coding library
+ *
+ * Copyright © 2005-2008 The Khronos Group Inc. All Rights Reserved.
+ *
+ * These materials are protected by copyright laws and contain material
+ * proprietary to the Khronos Group, Inc. You may use these materials
+ * for implementing Khronos specifications, without altering or removing
+ * any trademark, copyright or other notice from the specification.
+ *
+ * Khronos Group makes no, and expressly disclaims any, representations
+ * or warranties, express or implied, regarding these materials, including,
+ * without limitation, any implied warranties of merchantability or fitness
+ * for a particular purpose or non-infringement of any intellectual property.
+ * Khronos Group makes no, and expressly disclaims any, warranties, express
+ * or implied, regarding the correctness, accuracy, completeness, timeliness,
+ * and reliability of these materials.
+ *
+ * Under no circumstances will the Khronos Group, or any of its Promoters,
+ * Contributors or Members or their respective partners, officers, directors,
+ * employees, agents or representatives be liable for any damages, whether
+ * direct, indirect, special or consequential damages for lost revenues,
+ * lost profits, or otherwise, arising from or in connection with these
+ * materials.
+ *
+ * Khronos and OpenMAX are trademarks of the Khronos Group Inc.
+ *
+ */
+
+/* *****************************************************************************************/
+
+#ifndef _OMXVC_H_
+#define _OMXVC_H_
+
+#include "omxtypes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* 6.1.1.1 Motion Vectors */
+/* In omxVC, motion vectors are represented as follows: */
+
+typedef struct {
+ OMX_S16 dx;
+ OMX_S16 dy;
+} OMXVCMotionVector;
+
+
+
+/**
+ * Function: omxVCCOMM_Average_8x (6.1.3.1.1)
+ *
+ * Description:
+ * This function calculates the average of two 8x4, 8x8, or 8x16 blocks. The
+ * result is rounded according to (a+b+1)/2. The block average function can
+ * be used in conjunction with half-pixel interpolation to obtain quarter
+ * pixel motion estimates, as described in [ISO14496-10], subclause 8.4.2.2.1.
+ *
+ * Input Arguments:
+ *
+ * pPred0 - Pointer to the top-left corner of reference block 0
+ * pPred1 - Pointer to the top-left corner of reference block 1
+ * iPredStep0 - Step of reference block 0
+ * iPredStep1 - Step of reference block 1
+ * iDstStep - Step of the destination buffer.
+ * iHeight - Height of the blocks
+ *
+ * Output Arguments:
+ *
+ * pDstPred - Pointer to the destination buffer. 8-byte aligned.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned under any of the following
+ * conditions:
+ * - one or more of the following pointers is NULL: pPred0, pPred1, or
+ * pDstPred.
+ * - pDstPred is not aligned on an 8-byte boundary.
+ * - iPredStep0 <= 0 or iPredStep0 is not a multiple of 8.
+ * - iPredStep1 <= 0 or iPredStep1 is not a multiple of 8.
+ * - iDstStep <= 0 or iDstStep is not a multiple of 8.
+ * - iHeight is not 4, 8, or 16.
+ *
+ */
+OMXResult omxVCCOMM_Average_8x (
+ const OMX_U8 *pPred0,
+ const OMX_U8 *pPred1,
+ OMX_U32 iPredStep0,
+ OMX_U32 iPredStep1,
+ OMX_U8 *pDstPred,
+ OMX_U32 iDstStep,
+ OMX_U32 iHeight
+);
+
+
+
+/**
+ * Function: omxVCCOMM_Average_16x (6.1.3.1.2)
+ *
+ * Description:
+ * This function calculates the average of two 16x16 or 16x8 blocks. The
+ * result is rounded according to (a+b+1)/2. The block average function can
+ * be used in conjunction with half-pixel interpolation to obtain quarter
+ * pixel motion estimates, as described in [ISO14496-10], subclause 8.4.2.2.1.
+ *
+ * Input Arguments:
+ *
+ * pPred0 - Pointer to the top-left corner of reference block 0
+ * pPred1 - Pointer to the top-left corner of reference block 1
+ * iPredStep0 - Step of reference block 0
+ * iPredStep1 - Step of reference block 1
+ * iDstStep - Step of the destination buffer
+ * iHeight - Height of the blocks
+ *
+ * Output Arguments:
+ *
+ * pDstPred - Pointer to the destination buffer. 16-byte aligned.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned under any of the following
+ * conditions:
+ * - one or more of the following pointers is NULL: pPred0, pPred1, or
+ * pDstPred.
+ * - pDstPred is not aligned on a 16-byte boundary.
+ * - iPredStep0 <= 0 or iPredStep0 is not a multiple of 16.
+ * - iPredStep1 <= 0 or iPredStep1 is not a multiple of 16.
+ * - iDstStep <= 0 or iDstStep is not a multiple of 16.
+ * - iHeight is not 8 or 16.
+ *
+ */
+OMXResult omxVCCOMM_Average_16x (
+ const OMX_U8 *pPred0,
+ const OMX_U8 *pPred1,
+ OMX_U32 iPredStep0,
+ OMX_U32 iPredStep1,
+ OMX_U8 *pDstPred,
+ OMX_U32 iDstStep,
+ OMX_U32 iHeight
+);
+
+
+
+/**
+ * Function: omxVCCOMM_ExpandFrame_I (6.1.3.2.1)
+ *
+ * Description:
+ * This function expands a reconstructed frame in-place. The unexpanded
+ * source frame should be stored in a plane buffer with sufficient space
+ * pre-allocated for edge expansion, and the input frame should be located in
+ * the plane buffer center. This function executes the pixel expansion by
+ * replicating source frame edge pixel intensities in the empty pixel
+ * locations (expansion region) between the source frame edge and the plane
+ * buffer edge. The width/height of the expansion regions on the
+ * horizontal/vertical edges is controlled by the parameter iExpandPels.
+ *
+ * Input Arguments:
+ *
+ * pSrcDstPlane - pointer to the top-left corner of the frame to be
+ * expanded; must be aligned on an 8-byte boundary.
+ * iFrameWidth - frame width; must be a multiple of 8.
+ * iFrameHeight -frame height; must be a multiple of 8.
+ * iExpandPels - number of pixels to be expanded in the horizontal and
+ * vertical directions; must be a multiple of 8.
+ * iPlaneStep - distance, in bytes, between the start of consecutive lines
+ * in the plane buffer; must be larger than or equal to
+ * (iFrameWidth + 2 * iExpandPels).
+ *
+ * Output Arguments:
+ *
+ * pSrcDstPlane -Pointer to the top-left corner of the frame (NOT the
+ * top-left corner of the plane); must be aligned on an 8-byte
+ * boundary.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned under any of the following
+ * conditions:
+ * - pSrcDstPlane is NULL.
+ * - pSrcDstPlane is not aligned on an 8-byte boundary.
+ * - one of the following parameters is either equal to zero or is a
+ * non-multiple of 8: iFrameHeight, iFrameWidth, iPlaneStep, or
+ * iExpandPels.
+ * - iPlaneStep < (iFrameWidth + 2 * iExpandPels).
+ *
+ */
+OMXResult omxVCCOMM_ExpandFrame_I (
+ OMX_U8 *pSrcDstPlane,
+ OMX_U32 iFrameWidth,
+ OMX_U32 iFrameHeight,
+ OMX_U32 iExpandPels,
+ OMX_U32 iPlaneStep
+);
+
+
+
+/**
+ * Function: omxVCCOMM_Copy8x8 (6.1.3.3.1)
+ *
+ * Description:
+ * Copies the reference 8x8 block to the current block.
+ *
+ * Input Arguments:
+ *
+ * pSrc - pointer to the reference block in the source frame; must be
+ * aligned on an 8-byte boundary.
+ * step - distance between the starts of consecutive lines in the reference
+ * frame, in bytes; must be a multiple of 8 and must be larger than
+ * or equal to 8.
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the destination block; must be aligned on an 8-byte
+ * boundary.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned under any of the following
+ * conditions:
+ * - one or more of the following pointers is NULL: pSrc, pDst
+ * - one or more of the following pointers is not aligned on an 8-byte
+ * boundary: pSrc, pDst
+ * - step <8 or step is not a multiple of 8.
+ *
+ */
+OMXResult omxVCCOMM_Copy8x8 (
+ const OMX_U8 *pSrc,
+ OMX_U8 *pDst,
+ OMX_INT step
+);
+
+
+
+/**
+ * Function: omxVCCOMM_Copy16x16 (6.1.3.3.2)
+ *
+ * Description:
+ * Copies the reference 16x16 macroblock to the current macroblock.
+ *
+ * Input Arguments:
+ *
+ * pSrc - pointer to the reference macroblock in the source frame; must be
+ * aligned on a 16-byte boundary.
+ * step - distance between the starts of consecutive lines in the reference
+ * frame, in bytes; must be a multiple of 16 and must be larger
+ * than or equal to 16.
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the destination macroblock; must be aligned on a
+ * 16-byte boundary.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned under any of the following
+ * conditions:
+ * - one or more of the following pointers is NULL: pSrc, pDst
+ * - one or more of the following pointers is not aligned on a 16-byte
+ * boundary: pSrc, pDst
+ * - step <16 or step is not a multiple of 16.
+ *
+ */
+OMXResult omxVCCOMM_Copy16x16 (
+ const OMX_U8 *pSrc,
+ OMX_U8 *pDst,
+ OMX_INT step
+);
+
+
+
+/**
+ * Function: omxVCCOMM_ComputeTextureErrorBlock_SAD (6.1.4.1.1)
+ *
+ * Description:
+ * Computes texture error of the block; also returns SAD.
+ *
+ * Input Arguments:
+ *
+ * pSrc - pointer to the source plane; must be aligned on an 8-byte
+ * boundary.
+ * srcStep - step of the source plane
+ * pSrcRef - pointer to the reference buffer, an 8x8 block; must be aligned
+ * on an 8-byte boundary.
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the destination buffer, an 8x8 block; must be aligned
+ * on an 8-byte boundary.
+ * pDstSAD - pointer to the Sum of Absolute Differences (SAD) value
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments
+ * - At least one of the following
+ * pointers is NULL: pSrc, pSrcRef, pDst and pDstSAD.
+ * - pSrc is not 8-byte aligned.
+ * - SrcStep <= 0 or srcStep is not a multiple of 8.
+ * - pSrcRef is not 8-byte aligned.
+ * - pDst is not 8-byte aligned.
+ *
+ */
+OMXResult omxVCCOMM_ComputeTextureErrorBlock_SAD (
+ const OMX_U8 *pSrc,
+ OMX_INT srcStep,
+ const OMX_U8 *pSrcRef,
+ OMX_S16 *pDst,
+ OMX_INT *pDstSAD
+);
+
+
+
+/**
+ * Function: omxVCCOMM_ComputeTextureErrorBlock (6.1.4.1.2)
+ *
+ * Description:
+ * Computes the texture error of the block.
+ *
+ * Input Arguments:
+ *
+ * pSrc - pointer to the source plane. This should be aligned on an 8-byte
+ * boundary.
+ * srcStep - step of the source plane
+ * pSrcRef - pointer to the reference buffer, an 8x8 block. This should be
+ * aligned on an 8-byte boundary.
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the destination buffer, an 8x8 block. This should be
+ * aligned on an 8-byte boundary.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments:
+ * - At least one of the following pointers is NULL:
+ * pSrc, pSrcRef, pDst.
+ * - pSrc is not 8-byte aligned.
+ * - SrcStep <= 0 or srcStep is not a multiple of 8.
+ * - pSrcRef is not 8-byte aligned.
+ * - pDst is not 8-byte aligned
+ *
+ */
+OMXResult omxVCCOMM_ComputeTextureErrorBlock (
+ const OMX_U8 *pSrc,
+ OMX_INT srcStep,
+ const OMX_U8 *pSrcRef,
+ OMX_S16 *pDst
+);
+
+
+
+/**
+ * Function: omxVCCOMM_LimitMVToRect (6.1.4.1.3)
+ *
+ * Description:
+ * Limits the motion vector associated with the current block/macroblock to
+ * prevent the motion compensated block/macroblock from moving outside a
+ * bounding rectangle as shown in Figure 6-1.
+ *
+ * Input Arguments:
+ *
+ * pSrcMV - pointer to the motion vector associated with the current block
+ * or macroblock
+ * pRectVOPRef - pointer to the bounding rectangle
+ * Xcoord, Ycoord - coordinates of the current block or macroblock
+ * size - size of the current block or macroblock; must be equal to 8 or
+ * 16.
+ *
+ * Output Arguments:
+ *
+ * pDstMV - pointer to the limited motion vector
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments. Returned if one or more of the
+ * following conditions is true:
+ * - at least one of the following pointers is NULL:
+ * pSrcMV, pDstMV, or pRectVOPRef.
+ * - size is not equal to either 8 or 16.
+ * - the width or height of the bounding rectangle is less than
+ * twice the block size.
+ */
+OMXResult omxVCCOMM_LimitMVToRect (
+ const OMXVCMotionVector *pSrcMV,
+ OMXVCMotionVector *pDstMV,
+ const OMXRect *pRectVOPRef,
+ OMX_INT Xcoord,
+ OMX_INT Ycoord,
+ OMX_INT size
+);
+
+
+
+/**
+ * Function: omxVCCOMM_SAD_16x (6.1.4.1.4)
+ *
+ * Description:
+ * This function calculates the SAD for 16x16 and 16x8 blocks.
+ *
+ * Input Arguments:
+ *
+ * pSrcOrg - Pointer to the original block; must be aligned on a 16-byte
+ * boundary.
+ * iStepOrg - Step of the original block buffer
+ * pSrcRef - Pointer to the reference block
+ * iStepRef - Step of the reference block buffer
+ * iHeight - Height of the block
+ *
+ * Output Arguments:
+ *
+ * pDstSAD - Pointer of result SAD
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments. Returned if one or more of the
+ * following conditions is true:
+ * - at least one of the following pointers is NULL:
+ * pSrcOrg, pDstSAD, or pSrcRef
+ * - pSrcOrg is not 16-byte aligned.
+ * - iStepOrg <= 0 or iStepOrg is not a multiple of 16
+ * - iStepRef <= 0 or iStepRef is not a multiple of 16
+ * - iHeight is not 8 or 16
+ *
+ */
+OMXResult omxVCCOMM_SAD_16x (
+ const OMX_U8 *pSrcOrg,
+ OMX_U32 iStepOrg,
+ const OMX_U8 *pSrcRef,
+ OMX_U32 iStepRef,
+ OMX_S32 *pDstSAD,
+ OMX_U32 iHeight
+);
+
+
+
+/**
+ * Function: omxVCCOMM_SAD_8x (6.1.4.1.5)
+ *
+ * Description:
+ * This function calculates the SAD for 8x16, 8x8, 8x4 blocks.
+ *
+ * Input Arguments:
+ *
+ * pSrcOrg - Pointer to the original block; must be aligned on a 8-byte
+ * boundary.
+ * iStepOrg - Step of the original block buffer
+ * pSrcRef - Pointer to the reference block
+ * iStepRef - Step of the reference block buffer
+ * iHeight - Height of the block
+ *
+ * Output Arguments:
+ *
+ * pDstSAD -Pointer of result SAD
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments. Returned if one or more of the
+ * following conditions is true:
+ * - at least one of the following pointers is NULL:
+ * pSrcOrg, pDstSAD, or pSrcRef
+ * - pSrcOrg is not 8-byte aligned.
+ * - iStepOrg <= 0 or iStepOrg is not a multiple of 8
+ * - iStepRef <= 0 or iStepRef is not a multiple of 8
+ * - iHeight is not 4, 8 or 16
+ *
+ */
+OMXResult omxVCCOMM_SAD_8x (
+ const OMX_U8 *pSrcOrg,
+ OMX_U32 iStepOrg,
+ const OMX_U8 *pSrcRef,
+ OMX_U32 iStepRef,
+ OMX_S32*pDstSAD,
+ OMX_U32 iHeight
+);
+
+
+
+/* 6.2.1.1 Direction */
+/* The direction enumerator is used with functions that perform AC/DC prediction and zig-zag scan. */
+
+enum {
+ OMX_VC_NONE = 0,
+ OMX_VC_HORIZONTAL = 1,
+ OMX_VC_VERTICAL = 2
+};
+
+
+
+/* 6.2.1.2 Bilinear Interpolation */
+/* The bilinear interpolation enumerator is used with motion estimation, motion compensation, and reconstruction functions. */
+
+enum {
+ OMX_VC_INTEGER_PIXEL = 0, /* case a */
+ OMX_VC_HALF_PIXEL_X = 1, /* case b */
+ OMX_VC_HALF_PIXEL_Y = 2, /* case c */
+ OMX_VC_HALF_PIXEL_XY = 3 /* case d */
+};
+
+
+
+/* 6.2.1.3 Neighboring Macroblock Availability */
+/* Neighboring macroblock availability is indicated using the following flags: */
+
+enum {
+ OMX_VC_UPPER = 1, /** above macroblock is available */
+ OMX_VC_LEFT = 2, /** left macroblock is available */
+ OMX_VC_CENTER = 4,
+ OMX_VC_RIGHT = 8,
+ OMX_VC_LOWER = 16,
+ OMX_VC_UPPER_LEFT = 32, /** above-left macroblock is available */
+ OMX_VC_UPPER_RIGHT = 64, /** above-right macroblock is available */
+ OMX_VC_LOWER_LEFT = 128,
+ OMX_VC_LOWER_RIGHT = 256
+};
+
+
+
+/* 6.2.1.4 Video Components */
+/* A data type that enumerates video components is defined as follows: */
+
+typedef enum {
+ OMX_VC_LUMINANCE, /** Luminance component */
+ OMX_VC_CHROMINANCE /** chrominance component */
+} OMXVCM4P2VideoComponent;
+
+
+
+/* 6.2.1.5 MacroblockTypes */
+/* A data type that enumerates macroblock types is defined as follows: */
+
+typedef enum {
+ OMX_VC_INTER = 0, /** P picture or P-VOP */
+ OMX_VC_INTER_Q = 1, /** P picture or P-VOP */
+ OMX_VC_INTER4V = 2, /** P picture or P-VOP */
+ OMX_VC_INTRA = 3, /** I and P picture, I- and P-VOP */
+ OMX_VC_INTRA_Q = 4, /** I and P picture, I- and P-VOP */
+ OMX_VC_INTER4V_Q = 5 /** P picture or P-VOP (H.263)*/
+} OMXVCM4P2MacroblockType;
+
+
+
+/* 6.2.1.6 Coordinates */
+/* Coordinates are represented as follows: */
+
+typedef struct {
+ OMX_INT x;
+ OMX_INT y;
+} OMXVCM4P2Coordinate;
+
+
+
+/* 6.2.1.7 Motion Estimation Algorithms */
+/* A data type that enumerates motion estimation search methods is defined as follows: */
+
+typedef enum {
+ OMX_VC_M4P2_FAST_SEARCH = 0, /** Fast motion search */
+ OMX_VC_M4P2_FULL_SEARCH = 1 /** Full motion search */
+} OMXVCM4P2MEMode;
+
+
+
+/* 6.2.1.8 Motion Estimation Parameters */
+/* A data structure containing control parameters for
+ * motion estimation functions is defined as follows:
+ */
+
+typedef struct {
+ OMX_INT searchEnable8x8; /** enables 8x8 search */
+ OMX_INT halfPelSearchEnable; /** enables half-pel resolution */
+ OMX_INT searchRange; /** search range */
+ OMX_INT rndVal; /** rounding control; 0-disabled, 1-enabled*/
+} OMXVCM4P2MEParams;
+
+
+
+/* 6.2.1.9 Macroblock Information */
+/* A data structure containing macroblock parameters for
+ * motion estimation functions is defined as follows:
+ */
+
+typedef struct {
+ OMX_S32 sliceId; /* slice number */
+ OMXVCM4P2MacroblockType mbType; /* MB type: OMX_VC_INTRA, OMX_VC_INTER, or OMX_VC_INTER4 */
+ OMX_S32 qp; /* quantization parameter*/
+ OMX_U32 cbpy; /* CBP Luma */
+ OMX_U32 cbpc; /* CBP Chroma */
+ OMXVCMotionVector pMV0[2][2]; /* motion vector, represented using 1/2-pel units,
+ * pMV0[blocky][blockx] (blocky = 0~1, blockx =0~1)
+ */
+ OMXVCMotionVector pMVPred[2][2]; /* motion vector prediction, represented using 1/2-pel units,
+ * pMVPred[blocky][blockx] (blocky = 0~1, blockx = 0~1)
+ */
+ OMX_U8 pPredDir[2][2]; /* AC prediction direction:
+ * OMX_VC_NONE, OMX_VC_VERTICAL, OMX_VC_HORIZONTAL
+ */
+} OMXVCM4P2MBInfo, *OMXVCM4P2MBInfoPtr;
+
+
+
+/**
+ * Function: omxVCM4P2_FindMVpred (6.2.3.1.1)
+ *
+ * Description:
+ * Predicts a motion vector for the current block using the procedure
+ * specified in [ISO14496-2], subclause 7.6.5. The resulting predicted MV is
+ * returned in pDstMVPred. If the parameter pDstMVPredME if is not NULL then
+ * the set of three MV candidates used for prediction is also returned,
+ * otherwise pDstMVPredMEis NULL upon return.
+ *
+ * Input Arguments:
+ *
+ * pSrcMVCurMB - pointer to the MV buffer associated with the current Y
+ * macroblock; a value of NULL indicates unavailability.
+ * pSrcCandMV1 - pointer to the MV buffer containing the 4 MVs associated
+ * with the MB located to the left of the current MB; set to NULL
+ * if there is no MB to the left.
+ * pSrcCandMV2 - pointer to the MV buffer containing the 4 MVs associated
+ * with the MB located above the current MB; set to NULL if there
+ * is no MB located above the current MB.
+ * pSrcCandMV3 - pointer to the MV buffer containing the 4 MVs associated
+ * with the MB located to the right and above the current MB; set
+ * to NULL if there is no MB located to the above-right.
+ * iBlk - the index of block in the current macroblock
+ * pDstMVPredME - MV candidate return buffer; if set to NULL then
+ * prediction candidate MVs are not returned and pDstMVPredME will
+ * be NULL upon function return; if pDstMVPredME is non-NULL then it
+ * must point to a buffer containing sufficient space for three
+ * return MVs.
+ *
+ * Output Arguments:
+ *
+ * pDstMVPred - pointer to the predicted motion vector
+ * pDstMVPredME - if non-NULL upon input then pDstMVPredME points upon
+ * return to a buffer containing the three motion vector candidates
+ * used for prediction as specified in [ISO14496-2], subclause
+ * 7.6.5, otherwise if NULL upon input then pDstMVPredME is NULL
+ * upon output.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned under any of the following
+ * conditions:
+ * - the pointer pDstMVPred is NULL
+ * - the parameter iBlk does not fall into the range 0 <= iBlk<=3
+ *
+ */
+OMXResult omxVCM4P2_FindMVpred (
+ const OMXVCMotionVector *pSrcMVCurMB,
+ const OMXVCMotionVector *pSrcCandMV1,
+ const OMXVCMotionVector *pSrcCandMV2,
+ const OMXVCMotionVector *pSrcCandMV3,
+ OMXVCMotionVector *pDstMVPred,
+ OMXVCMotionVector *pDstMVPredME,
+ OMX_INT iBlk
+);
+
+
+
+/**
+ * Function: omxVCM4P2_IDCT8x8blk (6.2.3.2.1)
+ *
+ * Description:
+ * Computes a 2D inverse DCT for a single 8x8 block, as defined in
+ * [ISO14496-2].
+ *
+ * Input Arguments:
+ *
+ * pSrc - pointer to the start of the linearly arranged IDCT input buffer;
+ * must be aligned on a 16-byte boundary. According to
+ * [ISO14496-2], the input coefficient values should lie within the
+ * range [-2048, 2047].
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the start of the linearly arranged IDCT output buffer;
+ * must be aligned on a 16-byte boundary.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments:
+ * - pSrc or pDst is NULL.
+ * - pSrc or pDst is not 16-byte aligned.
+ *
+ */
+OMXResult omxVCM4P2_IDCT8x8blk (
+ const OMX_S16 *pSrc,
+ OMX_S16 *pDst
+);
+
+
+
+/**
+ * Function: omxVCM4P2_MEGetBufSize (6.2.4.1.1)
+ *
+ * Description:
+ * Computes the size, in bytes, of the vendor-specific specification
+ * structure for the following motion estimation functions:
+ * BlockMatch_Integer_8x8, BlockMatch_Integer_16x16, and MotionEstimationMB.
+ *
+ * Input Arguments:
+ *
+ * MEmode - motion estimation mode; available modes are defined by the
+ * enumerated type OMXVCM4P2MEMode
+ * pMEParams - motion estimation parameters
+ *
+ * Output Arguments:
+ *
+ * pSize - pointer to the number of bytes required for the specification
+ * structure
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - one or more of the following is true:
+ * - an invalid value was specified for the parameter MEmode
+ * - a negative or zero value was specified for the
+ * parameter pMEParams->searchRange
+ *
+ */
+OMXResult omxVCM4P2_MEGetBufSize (
+ OMXVCM4P2MEMode MEmode,
+ const OMXVCM4P2MEParams *pMEParams,
+ OMX_U32 *pSize
+);
+
+
+
+/**
+ * Function: omxVCM4P2_MEInit (6.2.4.1.2)
+ *
+ * Description:
+ * Initializes the vendor-specific specification structure required for the
+ * following motion estimation functions: BlockMatch_Integer_8x8,
+ * BlockMatch_Integer_16x16, and MotionEstimationMB. Memory for the
+ * specification structure *pMESpec must be allocated prior to calling the
+ * function, and should be aligned on a 4-byte boundary. Following
+ * initialization by this function, the vendor-specific structure *pMESpec
+ * should contain an implementation-specific representation of all motion
+ * estimation parameters received via the structure pMEParams, for example
+ * rndVal, searchRange, etc. The number of bytes required for the
+ * specification structure can be determined using the function
+ * omxVCM4P2_MEGetBufSize.
+ *
+ * Input Arguments:
+ *
+ * MEmode - motion estimation mode; available modes are defined by the
+ * enumerated type OMXVCM4P2MEMode
+ * pMEParams - motion estimation parameters
+ * pMESpec - pointer to the uninitialized ME specification structure
+ *
+ * Output Arguments:
+ *
+ * pMESpec - pointer to the initialized ME specification structure
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - one or more of the following is true:
+ * - an invalid value was specified for the parameter MEmode
+ * - a negative or zero value was specified for the
+ * parameter pMEParams->searchRange
+ *
+ */
+OMXResult omxVCM4P2_MEInit (
+ OMXVCM4P2MEMode MEmode,
+ const OMXVCM4P2MEParams*pMEParams,
+ void *pMESpec
+);
+
+
+
+/**
+ * Function: omxVCM4P2_BlockMatch_Integer_16x16 (6.2.4.2.1)
+ *
+ * Description:
+ * Performs a 16x16 block search; estimates motion vector and associated
+ * minimum SAD. Both the input and output motion vectors are represented using
+ * half-pixel units, and therefore a shift left or right by 1 bit may be
+ * required, respectively, to match the input or output MVs with other
+ * functions that either generate output MVs or expect input MVs represented
+ * using integer pixel units.
+ *
+ * Input Arguments:
+ *
+ * pSrcRefBuf - pointer to the reference Y plane; points to the reference
+ * MB that corresponds to the location of the current macroblock in
+ * the current plane.
+ * refWidth - width of the reference plane
+ * pRefRect - pointer to the valid reference plane rectangle; coordinates
+ * are specified relative to the image origin. Rectangle
+ * boundaries may extend beyond image boundaries if the image has
+ * been padded. For example, if padding extends 4 pixels beyond
+ * frame border, then the value for the left border could be set to
+ * -4.
+ * pSrcCurrBuf - pointer to the current block in the current macroblock
+ * buffer extracted from the original plane (linear array, 256
+ * entries); must be aligned on a 16-byte boundary. The number of
+ * bytes between lines (step) is 16.
+ * pCurrPointPos - position of the current macroblock in the current plane
+ * pSrcPreMV - pointer to predicted motion vector; NULL indicates no
+ * predicted MV
+ * pSrcPreSAD - pointer to SAD associated with the predicted MV (referenced
+ * by pSrcPreMV); may be set to NULL if unavailable.
+ * pMESpec - vendor-specific motion estimation specification structure;
+ * must have been allocated and then initialized using
+ * omxVCM4P2_MEInit prior to calling the block matching function.
+ *
+ * Output Arguments:
+ *
+ * pDstMV - pointer to estimated MV
+ * pDstSAD - pointer to minimum SAD
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments. Returned if one of the following
+ * conditions is true:
+ * - at least one of the following pointers is NULL: pSrcRefBuf,
+ * pRefRect, pSrcCurrBuff, pCurrPointPos, pDstMV, pDstSAD or
+ * pMESpec, or
+ * - pSrcCurrBuf is not 16-byte aligned
+ *
+ */
+OMXResult omxVCM4P2_BlockMatch_Integer_16x16 (
+ const OMX_U8 *pSrcRefBuf,
+ OMX_INT refWidth,
+ const OMXRect *pRefRect,
+ const OMX_U8 *pSrcCurrBuf,
+ const OMXVCM4P2Coordinate *pCurrPointPos,
+ const OMXVCMotionVector*pSrcPreMV,
+ const OMX_INT *pSrcPreSAD,
+ void *pMESpec,
+ OMXVCMotionVector*pDstMV,
+ OMX_INT *pDstSAD
+);
+
+
+
+/**
+ * Function: omxVCM4P2_BlockMatch_Integer_8x8 (6.2.4.2.2)
+ *
+ * Description:
+ * Performs an 8x8 block search; estimates motion vector and associated
+ * minimum SAD. Both the input and output motion vectors are represented
+ * using half-pixel units, and therefore a shift left or right by 1 bit may be
+ * required, respectively, to match the input or output MVs with other
+ * functions that either generate output MVs or expect input MVs represented
+ * using integer pixel units.
+ *
+ * Input Arguments:
+ *
+ * pSrcRefBuf - pointer to the reference Y plane; points to the reference
+ * block that corresponds to the location of the current 8x8 block
+ * in the current plane.
+ * refWidth - width of the reference plane
+ * pRefRect - pointer to the valid reference plane rectangle; coordinates
+ * are specified relative to the image origin. Rectangle
+ * boundaries may extend beyond image boundaries if the image has
+ * been padded.
+ * pSrcCurrBuf - pointer to the current block in the current macroblock
+ * buffer extracted from the original plane (linear array, 128
+ * entries); must be aligned on an 8-byte boundary. The number of
+ * bytes between lines (step) is 16 bytes.
+ * pCurrPointPos - position of the current block in the current plane
+ * pSrcPreMV - pointer to predicted motion vector; NULL indicates no
+ * predicted MV
+ * pSrcPreSAD - pointer to SAD associated with the predicted MV (referenced
+ * by pSrcPreMV); may be set to NULL if unavailable.
+ * pMESpec - vendor-specific motion estimation specification structure;
+ * must have been allocated and then initialized using
+ * omxVCM4P2_MEInit prior to calling the block matching function.
+ *
+ * Output Arguments:
+ *
+ * pDstMV - pointer to estimated MV
+ * pDstSAD - pointer to minimum SAD
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments. Returned if one of the following
+ * conditions is true:
+ * - at least one of the following pointers is NULL: pSrcRefBuf,
+ * pRefRect, pSrcCurrBuff, pCurrPointPos, pDstMV, pDstSAD or
+ * pMESpec, or
+ * - pSrcCurrBuf is not 8-byte aligned
+ *
+ */
+OMXResult omxVCM4P2_BlockMatch_Integer_8x8 (
+ const OMX_U8 *pSrcRefBuf,
+ OMX_INT refWidth,
+ const OMXRect *pRefRect,
+ const OMX_U8 *pSrcCurrBuf,
+ const OMXVCM4P2Coordinate *pCurrPointPos,
+ const OMXVCMotionVector *pSrcPreMV,
+ const OMX_INT *pSrcPreSAD,
+ void *pMESpec,
+ OMXVCMotionVector *pDstMV,
+ OMX_INT *pDstSAD
+);
+
+
+
+/**
+ * Function: omxVCM4P2_BlockMatch_Half_16x16 (6.2.4.2.3)
+ *
+ * Description:
+ * Performs a 16x16 block match with half-pixel resolution. Returns the
+ * estimated motion vector and associated minimum SAD. This function
+ * estimates the half-pixel motion vector by interpolating the integer
+ * resolution motion vector referenced by the input parameter pSrcDstMV, i.e.,
+ * the initial integer MV is generated externally. The input parameters
+ * pSrcRefBuf and pSearchPointRefPos should be shifted by the winning MV of
+ * 16x16 integer search prior to calling BlockMatch_Half_16x16. The function
+ * BlockMatch_Integer_16x16 may be used for integer motion estimation.
+ *
+ * Input Arguments:
+ *
+ * pSrcRefBuf - pointer to the reference Y plane; points to the reference
+ * macroblock that corresponds to the location of the current
+ * macroblock in the current plane.
+ * refWidth - width of the reference plane
+ * pRefRect - reference plane valid region rectangle
+ * pSrcCurrBuf - pointer to the current block in the current macroblock
+ * buffer extracted from the original plane (linear array, 256
+ * entries); must be aligned on a 16-byte boundary. The number of
+ * bytes between lines (step) is 16.
+ * pSearchPointRefPos - position of the starting point for half pixel
+ * search (specified in terms of integer pixel units) in the
+ * reference plane, i.e., the reference position pointed to by the
+ * predicted motion vector.
+ * rndVal - rounding control parameter: 0 - disabled; 1 - enabled.
+ * pSrcDstMV - pointer to the initial MV estimate; typically generated
+ * during a prior 16X16 integer search; specified in terms of
+ * half-pixel units.
+ *
+ * Output Arguments:
+ *
+ * pSrcDstMV - pointer to estimated MV
+ * pDstSAD - pointer to minimum SAD
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments. Returned if one of the following
+ * conditions is true:
+ * - at least one of the following pointers is NULL: pSrcRefBuf,
+ * pRefRect, pSrcCurrBuff, pSearchPointRefPos, pSrcDstMV.
+ * - pSrcCurrBuf is not 16-byte aligned, or
+ *
+ */
+OMXResult omxVCM4P2_BlockMatch_Half_16x16 (
+ const OMX_U8 *pSrcRefBuf,
+ OMX_INT refWidth,
+ const OMXRect *pRefRect,
+ const OMX_U8 *pSrcCurrBuf,
+ const OMXVCM4P2Coordinate *pSearchPointRefPos,
+ OMX_INT rndVal,
+ OMXVCMotionVector *pSrcDstMV,
+ OMX_INT *pDstSAD
+);
+
+
+
+/**
+ * Function: omxVCM4P2_BlockMatch_Half_8x8 (6.2.4.2.4)
+ *
+ * Description:
+ * Performs an 8x8 block match with half-pixel resolution. Returns the
+ * estimated motion vector and associated minimum SAD. This function
+ * estimates the half-pixel motion vector by interpolating the integer
+ * resolution motion vector referenced by the input parameter pSrcDstMV, i.e.,
+ * the initial integer MV is generated externally. The input parameters
+ * pSrcRefBuf and pSearchPointRefPos should be shifted by the winning MV of
+ * 8x8 integer search prior to calling BlockMatch_Half_8x8. The function
+ * BlockMatch_Integer_8x8 may be used for integer motion estimation.
+ *
+ * Input Arguments:
+ *
+ * pSrcRefBuf - pointer to the reference Y plane; points to the reference
+ * block that corresponds to the location of the current 8x8 block
+ * in the current plane.
+ * refWidth - width of the reference plane
+ * pRefRect - reference plane valid region rectangle
+ * pSrcCurrBuf - pointer to the current block in the current macroblock
+ * buffer extracted from the original plane (linear array, 128
+ * entries); must be aligned on a 8-byte boundary. The number of
+ * bytes between lines (step) is 16.
+ * pSearchPointRefPos - position of the starting point for half pixel
+ * search (specified in terms of integer pixel units) in the
+ * reference plane.
+ * rndVal - rounding control parameter: 0 - disabled; 1 - enabled.
+ * pSrcDstMV - pointer to the initial MV estimate; typically generated
+ * during a prior 8x8 integer search, specified in terms of
+ * half-pixel units.
+ *
+ * Output Arguments:
+ *
+ * pSrcDstMV - pointer to estimated MV
+ * pDstSAD - pointer to minimum SAD
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments. Returned if one of the following
+ * conditions is true:
+ * - at least one of the following pointers is NULL:
+ * pSrcRefBuf, pRefRect, pSrcCurrBuff, pSearchPointRefPos, pSrcDstMV
+ * - pSrcCurrBuf is not 8-byte aligned
+ *
+ */
+OMXResult omxVCM4P2_BlockMatch_Half_8x8 (
+ const OMX_U8 *pSrcRefBuf,
+ OMX_INT refWidth,
+ const OMXRect *pRefRect,
+ const OMX_U8 *pSrcCurrBuf,
+ const OMXVCM4P2Coordinate *pSearchPointRefPos,
+ OMX_INT rndVal,
+ OMXVCMotionVector *pSrcDstMV,
+ OMX_INT *pDstSAD
+);
+
+
+
+/**
+ * Function: omxVCM4P2_MotionEstimationMB (6.2.4.3.1)
+ *
+ * Description:
+ * Performs motion search for a 16x16 macroblock. Selects best motion search
+ * strategy from among inter-1MV, inter-4MV, and intra modes. Supports
+ * integer and half pixel resolution.
+ *
+ * Input Arguments:
+ *
+ * pSrcCurrBuf - pointer to the top-left corner of the current MB in the
+ * original picture plane; must be aligned on a 16-byte boundary.
+ * The function does not expect source data outside the region
+ * bounded by the MB to be available; for example it is not
+ * necessary for the caller to guarantee the availability of
+ * pSrcCurrBuf[-SrcCurrStep], i.e., the row of pixels above the MB
+ * to be processed.
+ * srcCurrStep - width of the original picture plane, in terms of full
+ * pixels; must be a multiple of 16.
+ * pSrcRefBuf - pointer to the reference Y plane; points to the reference
+ * plane location corresponding to the location of the current
+ * macroblock in the current plane; must be aligned on a 16-byte
+ * boundary.
+ * srcRefStep - width of the reference picture plane, in terms of full
+ * pixels; must be a multiple of 16.
+ * pRefRect - reference plane valid region rectangle, specified relative to
+ * the image origin
+ * pCurrPointPos - position of the current macroblock in the current plane
+ * pMESpec - pointer to the vendor-specific motion estimation specification
+ * structure; must be allocated and then initialized using
+ * omxVCM4P2_MEInit prior to calling this function.
+ * pMBInfo - array, of dimension four, containing pointers to information
+ * associated with four nearby MBs:
+ * - pMBInfo[0] - pointer to left MB information
+ * - pMBInfo[1] - pointer to top MB information
+ * - pMBInfo[2] - pointer to top-left MB information
+ * - pMBInfo[3] - pointer to top-right MB information
+ * Any pointer in the array may be set equal to NULL if the
+ * corresponding MB doesn't exist. For each MB, the following structure
+ * members are used:
+ * - mbType - macroblock type, either OMX_VC_INTRA, OMX_VC_INTER, or
+ * OMX_VC_INTER4V
+ * - pMV0[2][2] - estimated motion vectors; represented
+ * in 1/2 pixel units
+ * - sliceID - number of the slice to which the MB belongs
+ * pSrcDstMBCurr - pointer to information structure for the current MB.
+ * The following entries should be set prior to calling the
+ * function: sliceID - the number of the slice the to which the
+ * current MB belongs. The structure elements cbpy and cbpc are
+ * ignored.
+ *
+ * Output Arguments:
+ *
+ * pSrcDstMBCurr - pointer to updated information structure for the current
+ * MB after MB-level motion estimation has been completed. The
+ * following structure members are updated by the ME function:
+ * - mbType - macroblock type: OMX_VC_INTRA, OMX_VC_INTER, or
+ * OMX_VC_INTER4V.
+ * - pMV0[2][2] - estimated motion vectors; represented in
+ * terms of 1/2 pel units.
+ * - pMVPred[2][2] - predicted motion vectors; represented
+ * in terms of 1/2 pel units.
+ * The structure members cbpy and cbpc are not updated by the function.
+ * pDstSAD - pointer to the minimum SAD for INTER1V, or sum of minimum SADs
+ * for INTER4V
+ * pDstBlockSAD - pointer to an array of SAD values for each of the four
+ * 8x8 luma blocks in the MB. The block SADs are in scan order for
+ * each MB.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments. Returned if one or more of the
+ * following conditions is true:
+ * - at least one of the following pointers is NULL: pSrcCurrBuf,
+ * pSrcRefBuf, pRefRect, pCurrPointPos, pMBInter, pMBIntra,
+ * pSrcDstMBCurr, or pDstSAD.
+ *
+ */
+OMXResult omxVCM4P2_MotionEstimationMB (
+ const OMX_U8 *pSrcCurrBuf,
+ OMX_S32 srcCurrStep,
+ const OMX_U8 *pSrcRefBuf,
+ OMX_S32 srcRefStep,
+ const OMXRect*pRefRect,
+ const OMXVCM4P2Coordinate *pCurrPointPos,
+ void *pMESpec,
+ const OMXVCM4P2MBInfoPtr *pMBInfo,
+ OMXVCM4P2MBInfo *pSrcDstMBCurr,
+ OMX_U16 *pDstSAD,
+ OMX_U16 *pDstBlockSAD
+);
+
+
+
+/**
+ * Function: omxVCM4P2_DCT8x8blk (6.2.4.4.1)
+ *
+ * Description:
+ * Computes a 2D forward DCT for a single 8x8 block, as defined in
+ * [ISO14496-2].
+ *
+ * Input Arguments:
+ *
+ * pSrc - pointer to the start of the linearly arranged input buffer; must
+ * be aligned on a 16-byte boundary. Input values (pixel
+ * intensities) are valid in the range [-255,255].
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the start of the linearly arranged output buffer; must
+ * be aligned on a 16-byte boundary.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments, returned if:
+ * - pSrc or pDst is NULL.
+ * - pSrc or pDst is not 16-byte aligned.
+ *
+ */
+OMXResult omxVCM4P2_DCT8x8blk (
+ const OMX_S16 *pSrc,
+ OMX_S16 *pDst
+);
+
+
+
+/**
+ * Function: omxVCM4P2_QuantIntra_I (6.2.4.4.2)
+ *
+ * Description:
+ * Performs quantization on intra block coefficients. This function supports
+ * bits_per_pixel == 8.
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - pointer to the input intra block coefficients; must be aligned
+ * on a 16-byte boundary.
+ * QP - quantization parameter (quantizer_scale).
+ * blockIndex - block index indicating the component type and position,
+ * valid in the range 0 to 5, as defined in [ISO14496-2], subclause
+ * 6.1.3.8.
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; shortVideoHeader==1 selects linear intra DC
+ * mode, and shortVideoHeader==0 selects non linear intra DC mode.
+ *
+ * Output Arguments:
+ *
+ * pSrcDst - pointer to the output (quantized) interblock coefficients.
+ * When shortVideoHeader==1, AC coefficients are saturated on the
+ * interval [-127, 127], and DC coefficients are saturated on the
+ * interval [1, 254]. When shortVideoHeader==0, AC coefficients
+ * are saturated on the interval [-2047, 2047].
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments:
+ * - pSrcDst is NULL.
+ * - blockIndex < 0 or blockIndex >= 10
+ * - QP <= 0 or QP >= 32.
+ *
+ */
+OMXResult omxVCM4P2_QuantIntra_I (
+ OMX_S16 *pSrcDst,
+ OMX_U8 QP,
+ OMX_INT blockIndex,
+ OMX_INT shortVideoHeader
+);
+
+
+
+/**
+ * Function: omxVCM4P2_QuantInter_I (6.2.4.4.3)
+ *
+ * Description:
+ * Performs quantization on an inter coefficient block; supports
+ * bits_per_pixel == 8.
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - pointer to the input inter block coefficients; must be aligned
+ * on a 16-byte boundary.
+ * QP - quantization parameter (quantizer_scale)
+ * shortVideoHeader - binary flag indicating presence of short_video_header;
+ * shortVideoHeader==1 selects linear intra DC mode, and
+ * shortVideoHeader==0 selects non linear intra DC mode.
+ *
+ * Output Arguments:
+ *
+ * pSrcDst - pointer to the output (quantized) interblock coefficients.
+ * When shortVideoHeader==1, AC coefficients are saturated on the
+ * interval [-127, 127], and DC coefficients are saturated on the
+ * interval [1, 254]. When shortVideoHeader==0, AC coefficients
+ * are saturated on the interval [-2047, 2047].
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments:
+ * - pSrcDst is NULL.
+ * - QP <= 0 or QP >= 32.
+ *
+ */
+OMXResult omxVCM4P2_QuantInter_I (
+ OMX_S16 *pSrcDst,
+ OMX_U8 QP,
+ OMX_INT shortVideoHeader
+);
+
+
+
+/**
+ * Function: omxVCM4P2_TransRecBlockCoef_intra (6.2.4.4.4)
+ *
+ * Description:
+ * Quantizes the DCT coefficients, implements intra block AC/DC coefficient
+ * prediction, and reconstructs the current intra block texture for prediction
+ * on the next frame. Quantized row and column coefficients are returned in
+ * the updated coefficient buffers.
+ *
+ * Input Arguments:
+ *
+ * pSrc - pointer to the pixels of current intra block; must be aligned on
+ * an 8-byte boundary.
+ * pPredBufRow - pointer to the coefficient row buffer containing
+ * ((num_mb_per_row * 2 + 1) * 8) elements of type OMX_S16.
+ * Coefficients are organized into blocks of eight as described
+ * below (Internal Prediction Coefficient Update Procedures). The
+ * DC coefficient is first, and the remaining buffer locations
+ * contain the quantized AC coefficients. Each group of eight row
+ * buffer elements combined with one element eight elements ahead
+ * contains the coefficient predictors of the neighboring block
+ * that is spatially above or to the left of the block currently to
+ * be decoded. A negative-valued DC coefficient indicates that this
+ * neighboring block is not INTRA-coded or out of bounds, and
+ * therefore the AC and DC coefficients are invalid. Pointer must
+ * be aligned on an 8-byte boundary.
+ * pPredBufCol - pointer to the prediction coefficient column buffer
+ * containing 16 elements of type OMX_S16. Coefficients are
+ * organized as described in section 6.2.2.5. Pointer must be
+ * aligned on an 8-byte boundary.
+ * pSumErr - pointer to a flag indicating whether or not AC prediction is
+ * required; AC prediction is enabled if *pSumErr >=0, but the
+ * value is not used for coefficient prediction, i.e., the sum of
+ * absolute differences starts from 0 for each call to this
+ * function. Otherwise AC prediction is disabled if *pSumErr < 0 .
+ * blockIndex - block index indicating the component type and position, as
+ * defined in [ISO14496-2], subclause 6.1.3.8.
+ * curQp - quantization parameter of the macroblock to which the current
+ * block belongs
+ * pQpBuf - pointer to a 2-element quantization parameter buffer; pQpBuf[0]
+ * contains the quantization parameter associated with the 8x8
+ * block left of the current block (QPa), and pQpBuf[1] contains
+ * the quantization parameter associated with the 8x8 block above
+ * the current block (QPc). In the event that the corresponding
+ * block is outside of the VOP bound, the Qp value will not affect
+ * the intra prediction process, as described in [ISO14496-2],
+ * sub-clause 7.4.3.3, Adaptive AC Coefficient Prediction.
+ * srcStep - width of the source buffer; must be a multiple of 8.
+ * dstStep - width of the reconstructed destination buffer; must be a
+ * multiple of 16.
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; shortVideoHeader==1 selects linear intra DC
+ * mode, and shortVideoHeader==0 selects non linear intra DC mode.
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the quantized DCT coefficient buffer; pDst[0] contains
+ * the predicted DC coefficient; the remaining entries contain the
+ * quantized AC coefficients (without prediction). The pointer
+ * pDstmust be aligned on a 16-byte boundary.
+ * pRec - pointer to the reconstructed texture; must be aligned on an
+ * 8-byte boundary.
+ * pPredBufRow - pointer to the updated coefficient row buffer
+ * pPredBufCol - pointer to the updated coefficient column buffer
+ * pPreACPredict - if prediction is enabled, the parameter points to the
+ * start of the buffer containing the coefficient differences for
+ * VLC encoding. The entry pPreACPredict[0]indicates prediction
+ * direction for the current block and takes one of the following
+ * values: OMX_VC_NONE (prediction disabled), OMX_VC_HORIZONTAL, or
+ * OMX_VC_VERTICAL. The entries
+ * pPreACPredict[1]-pPreACPredict[7]contain predicted AC
+ * coefficients. If prediction is disabled (*pSumErr<0) then the
+ * contents of this buffer are undefined upon return from the
+ * function
+ * pSumErr - pointer to the value of the accumulated AC coefficient errors,
+ * i.e., sum of the absolute differences between predicted and
+ * unpredicted AC coefficients
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - Bad arguments:
+ * - At least one of the following pointers is NULL: pSrc, pDst, pRec,
+ * pCoefBufRow, pCoefBufCol, pQpBuf, pPreACPredict, pSumErr.
+ * - blockIndex < 0 or blockIndex >= 10;
+ * - curQP <= 0 or curQP >= 32.
+ * - srcStep, or dstStep <= 0 or not a multiple of 8.
+ * - pDst is not 16-byte aligned: .
+ * - At least one of the following pointers is not 8-byte aligned:
+ * pSrc, pRec.
+ *
+ * Note: The coefficient buffers must be updated in accordance with the
+ * update procedures defined in section in 6.2.2.
+ *
+ */
+OMXResult omxVCM4P2_TransRecBlockCoef_intra (
+ const OMX_U8 *pSrc,
+ OMX_S16 *pDst,
+ OMX_U8 *pRec,
+ OMX_S16 *pPredBufRow,
+ OMX_S16 *pPredBufCol,
+ OMX_S16 *pPreACPredict,
+ OMX_INT *pSumErr,
+ OMX_INT blockIndex,
+ OMX_U8 curQp,
+ const OMX_U8 *pQpBuf,
+ OMX_INT srcStep,
+ OMX_INT dstStep,
+ OMX_INT shortVideoHeader
+);
+
+
+
+/**
+ * Function: omxVCM4P2_TransRecBlockCoef_inter (6.2.4.4.5)
+ *
+ * Description:
+ * Implements DCT, and quantizes the DCT coefficients of the inter block
+ * while reconstructing the texture residual. There is no boundary check for
+ * the bit stream buffer.
+ *
+ * Input Arguments:
+ *
+ * pSrc -pointer to the residuals to be encoded; must be aligned on an
+ * 16-byte boundary.
+ * QP - quantization parameter.
+ * shortVideoHeader - binary flag indicating presence of short_video_header;
+ * shortVideoHeader==1 selects linear intra DC mode, and
+ * shortVideoHeader==0 selects non linear intra DC mode.
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the quantized DCT coefficients buffer; must be aligned
+ * on a 16-byte boundary.
+ * pRec - pointer to the reconstructed texture residuals; must be aligned
+ * on a 16-byte boundary.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments:
+ * - At least one of the following pointers is either NULL or
+ * not 16-byte aligned:
+ * - pSrc
+ * - pDst
+ * - pRec
+ * - QP <= 0 or QP >= 32.
+ *
+ */
+OMXResult omxVCM4P2_TransRecBlockCoef_inter (
+ const OMX_S16 *pSrc,
+ OMX_S16 *pDst,
+ OMX_S16 *pRec,
+ OMX_U8 QP,
+ OMX_INT shortVideoHeader
+);
+
+
+
+/**
+ * Function: omxVCM4P2_EncodeVLCZigzag_IntraDCVLC (6.2.4.5.2)
+ *
+ * Description:
+ * Performs zigzag scan and VLC encoding of AC and DC coefficients for one
+ * intra block. Two versions of the function (DCVLC and ACVLC) are provided
+ * in order to support the two different methods of processing DC
+ * coefficients, as described in [ISO14496-2], subclause 7.4.1.4, "Intra DC
+ * Coefficient Decoding for the Case of Switched VLC Encoding".
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - double pointer to the current byte in the bitstream
+ * pBitOffset - pointer to the bit position in the byte pointed by
+ * *ppBitStream. Valid within 0 to 7.
+ * pQDctBlkCoef - pointer to the quantized DCT coefficient
+ * predDir - AC prediction direction, which is used to decide the zigzag
+ * scan pattern; takes one of the following values:
+ * - OMX_VC_NONE - AC prediction not used.
+ * Performs classical zigzag scan.
+ * - OMX_VC_HORIZONTAL - Horizontal prediction.
+ * Performs alternate-vertical zigzag scan.
+ * - OMX_VC_VERTICAL - Vertical prediction.
+ * Performs alternate-horizontal zigzag scan.
+ * pattern - block pattern which is used to decide whether this block is
+ * encoded
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; escape modes 0-3 are used if
+ * shortVideoHeader==0, and escape mode 4 is used when
+ * shortVideoHeader==1.
+ * videoComp - video component type (luminance, chrominance) of the current
+ * block
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after the block is encoded, so
+ * that it points to the current byte in the bit stream buffer.
+ * pBitOffset - *pBitOffset is updated so that it points to the current bit
+ * position in the byte pointed by *ppBitStream.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - Bad arguments:
+ * - At least one of the following pointers is NULL: ppBitStream,
+ * *ppBitStream, pBitOffset, pQDctBlkCoef.
+ * - *pBitOffset < 0, or *pBitOffset >7.
+ * - PredDir is not one of: OMX_VC_NONE, OMX_VC_HORIZONTAL, or
+ * OMX_VC_VERTICAL.
+ * - VideoComp is not one component of enum OMXVCM4P2VideoComponent.
+ *
+ */
+OMXResult omxVCM4P2_EncodeVLCZigzag_IntraDCVLC (
+ OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ const OMX_S16 *pQDctBlkCoef,
+ OMX_U8 predDir,
+ OMX_U8 pattern,
+ OMX_INT shortVideoHeader,
+ OMXVCM4P2VideoComponent videoComp
+);
+
+
+
+/**
+ * Function: omxVCM4P2_EncodeVLCZigzag_IntraACVLC (6.2.4.5.2)
+ *
+ * Description:
+ * Performs zigzag scan and VLC encoding of AC and DC coefficients for one
+ * intra block. Two versions of the function (DCVLC and ACVLC) are provided
+ * in order to support the two different methods of processing DC
+ * coefficients, as described in [ISO14496-2], subclause 7.4.1.4, Intra DC
+ * Coefficient Decoding for the Case of Switched VLC Encoding.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - double pointer to the current byte in the bitstream
+ * pBitOffset - pointer to the bit position in the byte pointed by
+ * *ppBitStream. Valid within 0 to 7.
+ * pQDctBlkCoef - pointer to the quantized DCT coefficient
+ * predDir - AC prediction direction, which is used to decide the zigzag
+ * scan pattern; takes one of the following values:
+ * - OMX_VC_NONE - AC prediction not used.
+ * Performs classical zigzag scan.
+ * - OMX_VC_HORIZONTAL - Horizontal prediction.
+ * Performs alternate-vertical zigzag scan.
+ * - OMX_VC_VERTICAL - Vertical prediction.
+ * Performs alternate-horizontal zigzag scan.
+ * pattern - block pattern which is used to decide whether this block is
+ * encoded
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; escape modes 0-3 are used if
+ * shortVideoHeader==0, and escape mode 4 is used when
+ * shortVideoHeader==1.
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after the block is encoded, so
+ * that it points to the current byte in the bit stream buffer.
+ * pBitOffset - *pBitOffset is updated so that it points to the current bit
+ * position in the byte pointed by *ppBitStream.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - Bad arguments:
+ * - At least one of the following pointers is NULL: ppBitStream,
+ * *ppBitStream, pBitOffset, pQDctBlkCoef.
+ * - *pBitOffset < 0, or *pBitOffset >7.
+ * - PredDir is not one of: OMX_VC_NONE, OMX_VC_HORIZONTAL, or
+ * OMX_VC_VERTICAL.
+ * - VideoComp is not one component of enum OMXVCM4P2VideoComponent.
+ *
+ */
+OMXResult omxVCM4P2_EncodeVLCZigzag_IntraACVLC (
+ OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ const OMX_S16 *pQDctBlkCoef,
+ OMX_U8 predDir,
+ OMX_U8 pattern,
+ OMX_INT shortVideoHeader
+);
+
+
+
+/**
+ * Function: omxVCM4P2_EncodeVLCZigzag_Inter (6.2.4.5.3)
+ *
+ * Description:
+ * Performs classical zigzag scanning and VLC encoding for one inter block.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - pointer to the pointer to the current byte in the bit
+ * stream
+ * pBitOffset - pointer to the bit position in the byte pointed by
+ * *ppBitStream. Valid within 0 to 7
+ * pQDctBlkCoef - pointer to the quantized DCT coefficient
+ * pattern - block pattern which is used to decide whether this block is
+ * encoded
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; escape modes 0-3 are used if
+ * shortVideoHeader==0, and escape mode 4 is used when
+ * shortVideoHeader==1.
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after the block is encoded so that
+ * it points to the current byte in the bit stream buffer.
+ * pBitOffset - *pBitOffset is updated so that it points to the current bit
+ * position in the byte pointed by *ppBitStream.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - Bad arguments
+ * - At least one of the pointers: is NULL: ppBitStream, *ppBitStream,
+ * pBitOffset, pQDctBlkCoef
+ * - *pBitOffset < 0, or *pBitOffset >7.
+ *
+ */
+OMXResult omxVCM4P2_EncodeVLCZigzag_Inter (
+ OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ const OMX_S16 *pQDctBlkCoef,
+ OMX_U8 pattern,
+ OMX_INT shortVideoHeader
+);
+
+
+
+/**
+ * Function: omxVCM4P2_EncodeMV (6.2.4.5.4)
+ *
+ * Description:
+ * Predicts a motion vector for the current macroblock, encodes the
+ * difference, and writes the output to the stream buffer. The input MVs
+ * pMVCurMB, pSrcMVLeftMB, pSrcMVUpperMB, and pSrcMVUpperRightMB should lie
+ * within the ranges associated with the input parameter fcodeForward, as
+ * described in [ISO14496-2], subclause 7.6.3. This function provides a
+ * superset of the functionality associated with the function
+ * omxVCM4P2_FindMVpred.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - double pointer to the current byte in the bitstream buffer
+ * pBitOffset - index of the first free (next available) bit in the stream
+ * buffer referenced by *ppBitStream, valid in the range 0 to 7.
+ * pMVCurMB - pointer to the current macroblock motion vector; a value of
+ * NULL indicates unavailability.
+ * pSrcMVLeftMB - pointer to the source left macroblock motion vector; a
+ * value of NULLindicates unavailability.
+ * pSrcMVUpperMB - pointer to source upper macroblock motion vector; a
+ * value of NULL indicates unavailability.
+ * pSrcMVUpperRightMB - pointer to source upper right MB motion vector; a
+ * value of NULL indicates unavailability.
+ * fcodeForward - an integer with values from 1 to 7; used in encoding
+ * motion vectors related to search range, as described in
+ * [ISO14496-2], subclause 7.6.3.
+ * MBType - macro block type, valid in the range 0 to 5
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - updated pointer to the current byte in the bit stream
+ * buffer
+ * pBitOffset - updated index of the next available bit position in stream
+ * buffer referenced by *ppBitStream
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments
+ * - At least one of the following pointers is NULL: ppBitStream,
+ * *ppBitStream, pBitOffset, pMVCurMB
+ * - *pBitOffset < 0, or *pBitOffset >7.
+ * - fcodeForward <= 0, or fcodeForward > 7, or MBType < 0.
+ *
+ */
+OMXResult omxVCM4P2_EncodeMV (
+ OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ const OMXVCMotionVector *pMVCurMB,
+ const OMXVCMotionVector*pSrcMVLeftMB,
+ const OMXVCMotionVector *pSrcMVUpperMB,
+ const OMXVCMotionVector *pSrcMVUpperRightMB,
+ OMX_INT fcodeForward,
+ OMXVCM4P2MacroblockType MBType
+);
+
+
+
+/**
+ * Function: omxVCM4P2_DecodePadMV_PVOP (6.2.5.1.1)
+ *
+ * Description:
+ * Decodes and pads the four motion vectors associated with a non-intra P-VOP
+ * macroblock. For macroblocks of type OMX_VC_INTER4V, the output MV is
+ * padded as specified in [ISO14496-2], subclause 7.6.1.6. Otherwise, for
+ * macroblocks of types other than OMX_VC_INTER4V, the decoded MV is copied to
+ * all four output MV buffer entries.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - pointer to the pointer to the current byte in the bit
+ * stream buffer
+ * pBitOffset - pointer to the bit position in the byte pointed to by
+ * *ppBitStream. *pBitOffset is valid within [0-7].
+ * pSrcMVLeftMB, pSrcMVUpperMB, and pSrcMVUpperRightMB - pointers to the
+ * motion vector buffers of the macroblocks specially at the left,
+ * upper, and upper-right side of the current macroblock,
+ * respectively; a value of NULL indicates unavailability. Note:
+ * Any neighborhood macroblock outside the current VOP or video
+ * packet or outside the current GOB (when short_video_header is
+ * 1 ) for which gob_header_empty is 0 is treated as
+ * transparent, according to [ISO14496-2], subclause 7.6.5.
+ * fcodeForward - a code equal to vop_fcode_forward in MPEG-4 bit stream
+ * syntax
+ * MBType - the type of the current macroblock. If MBType is not equal to
+ * OMX_VC_INTER4V, the destination motion vector buffer is still
+ * filled with the same decoded vector.
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after the block is decoded, so
+ * that it points to the current byte in the bit stream buffer
+ * pBitOffset - *pBitOffset is updated so that it points to the current bit
+ * position in the byte pointed by *ppBitStream
+ * pDstMVCurMB - pointer to the motion vector buffer for the current
+ * macroblock; contains four decoded motion vectors
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments:
+ * - At least one of the following pointers is NULL:
+ * ppBitStream, *ppBitStream, pBitOffset, pDstMVCurMB
+ * - *pBitOffset exceeds [0,7]
+ * - fcodeForward exceeds (0,7]
+ * - MBType less than zero
+ * - motion vector buffer is not 4-byte aligned.
+ * OMX_Sts_Err - status error
+ *
+ */
+OMXResult omxVCM4P2_DecodePadMV_PVOP (
+ const OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ OMXVCMotionVector *pSrcMVLeftMB,
+ OMXVCMotionVector*pSrcMVUpperMB,
+ OMXVCMotionVector *pSrcMVUpperRightMB,
+ OMXVCMotionVector*pDstMVCurMB,
+ OMX_INT fcodeForward,
+ OMXVCM4P2MacroblockType MBType
+);
+
+
+
+/**
+ * Function: omxVCM4P2_DecodeVLCZigzag_IntraDCVLC (6.2.5.2.2)
+ *
+ * Description:
+ * Performs VLC decoding and inverse zigzag scan of AC and DC coefficients
+ * for one intra block. Two versions of the function (DCVLC and ACVLC) are
+ * provided in order to support the two different methods of processing DC
+ * coefficients, as described in [ISO14496-2], subclause 7.4.1.4, Intra DC
+ * Coefficient Decoding for the Case of Switched VLC Encoding.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - pointer to the pointer to the current byte in the
+ * bitstream buffer
+ * pBitOffset - pointer to the bit position in the current byte referenced
+ * by *ppBitStream. The parameter *pBitOffset is valid in the
+ * range [0-7].
+ * Bit Position in one byte: |Most Least|
+ * *pBitOffset |0 1 2 3 4 5 6 7|
+ * predDir - AC prediction direction; used to select the zigzag scan
+ * pattern; takes one of the following values:
+ * - OMX_VC_NONE - AC prediction not used;
+ * performs classical zigzag scan.
+ * - OMX_VC_HORIZONTAL - Horizontal prediction;
+ * performs alternate-vertical zigzag scan;
+ * - OMX_VC_VERTICAL - Vertical prediction;
+ * performs alternate-horizontal zigzag scan.
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; escape modes 0-3 are used if
+ * shortVideoHeader==0, and escape mode 4 is used when
+ * shortVideoHeader==1.
+ * videoComp - video component type (luminance or chrominance) of the
+ * current block
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after the block is decoded such
+ * that it points to the current byte in the bit stream buffer
+ * pBitOffset - *pBitOffset is updated such that it points to the current
+ * bit position in the byte pointed by *ppBitStream
+ * pDst - pointer to the coefficient buffer of current block; must be
+ * 4-byte aligned.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments, if:
+ * - At least one of the following pointers is NULL:
+ * ppBitStream, *ppBitStream, pBitOffset, pDst
+ * - *pBitOffset exceeds [0,7]
+ * - preDir exceeds [0,2]
+ * - pDst is not 4-byte aligned
+ * OMX_Sts_Err - if:
+ * - In DecodeVLCZigzag_IntraDCVLC, dc_size > 12
+ * - At least one of mark bits equals zero
+ * - Illegal stream encountered; code cannot be located in VLC table
+ * - Forbidden code encountered in the VLC FLC table.
+ * - The number of coefficients is greater than 64
+ *
+ */
+OMXResult omxVCM4P2_DecodeVLCZigzag_IntraDCVLC (
+ const OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ OMX_S16 *pDst,
+ OMX_U8 predDir,
+ OMX_INT shortVideoHeader,
+ OMXVCM4P2VideoComponent videoComp
+);
+
+
+
+/**
+ * Function: omxVCM4P2_DecodeVLCZigzag_IntraACVLC (6.2.5.2.2)
+ *
+ * Description:
+ * Performs VLC decoding and inverse zigzag scan of AC and DC coefficients
+ * for one intra block. Two versions of the function (DCVLC and ACVLC) are
+ * provided in order to support the two different methods of processing DC
+ * coefficients, as described in [ISO14496-2], subclause 7.4.1.4, Intra DC
+ * Coefficient Decoding for the Case of Switched VLC Encoding.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - pointer to the pointer to the current byte in the
+ * bitstream buffer
+ * pBitOffset - pointer to the bit position in the current byte referenced
+ * by *ppBitStream. The parameter *pBitOffset is valid in the
+ * range [0-7]. Bit Position in one byte: |Most Least| *pBitOffset
+ * |0 1 2 3 4 5 6 7|
+ * predDir - AC prediction direction; used to select the zigzag scan
+ * pattern; takes one of the following values: OMX_VC_NONE - AC
+ * prediction not used; performs classical zigzag scan.
+ * OMX_VC_HORIZONTAL - Horizontal prediction; performs
+ * alternate-vertical zigzag scan; OMX_VC_VERTICAL - Vertical
+ * prediction; performs alternate-horizontal zigzag scan.
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; escape modes 0-3 are used if
+ * shortVideoHeader==0, and escape mode 4 is used when
+ * shortVideoHeader==1.
+ * videoComp - video component type (luminance or chrominance) of the
+ * current block
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after the block is decoded such
+ * that it points to the current byte in the bit stream buffer
+ * pBitOffset - *pBitOffset is updated such that it points to the current
+ * bit position in the byte pointed by *ppBitStream
+ * pDst - pointer to the coefficient buffer of current block; must be
+ * 4-byte aligned.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments At least one of the following
+ * pointers is NULL: ppBitStream, *ppBitStream, pBitOffset, pDst,
+ * or At least one of the following conditions is true:
+ * *pBitOffset exceeds [0,7], preDir exceeds [0,2], or pDst is
+ * not 4-byte aligned
+ * OMX_Sts_Err In DecodeVLCZigzag_IntraDCVLC, dc_size > 12 At least one of
+ * mark bits equals zero Illegal stream encountered; code cannot
+ * be located in VLC table Forbidden code encountered in the VLC
+ * FLC table The number of coefficients is greater than 64
+ *
+ */
+OMXResult omxVCM4P2_DecodeVLCZigzag_IntraACVLC (
+ const OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ OMX_S16 *pDst,
+ OMX_U8 predDir,
+ OMX_INT shortVideoHeader
+);
+
+
+
+/**
+ * Function: omxVCM4P2_DecodeVLCZigzag_Inter (6.2.5.2.3)
+ *
+ * Description:
+ * Performs VLC decoding and inverse zigzag scan for one inter-coded block.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - double pointer to the current byte in the stream buffer
+ * pBitOffset - pointer to the next available bit in the current stream
+ * byte referenced by *ppBitStream. The parameter *pBitOffset is
+ * valid within the range [0-7].
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; escape modes 0-3 are used if
+ * shortVideoHeader==0, and escape mode 4 is used when
+ * shortVideoHeader==1.
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after the block is decoded such
+ * that it points to the current byte in the stream buffer
+ * pBitOffset - *pBitOffset is updated after decoding such that it points
+ * to the next available bit in the stream byte referenced by
+ * *ppBitStream
+ * pDst - pointer to the coefficient buffer of current block; must be
+ * 4-byte aligned.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_BadArgErr - bad arguments:
+ * - At least one of the following pointers is NULL:
+ * ppBitStream, *ppBitStream, pBitOffset, pDst
+ * - pDst is not 4-byte aligned
+ * - *pBitOffset exceeds [0,7]
+ * OMX_Sts_Err - status error, if:
+ * - At least one mark bit is equal to zero
+ * - Encountered an illegal stream code that cannot be found in the VLC table
+ * - Encountered an illegal code in the VLC FLC table
+ * - The number of coefficients is greater than 64
+ *
+ */
+OMXResult omxVCM4P2_DecodeVLCZigzag_Inter (
+ const OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ OMX_S16 *pDst,
+ OMX_INT shortVideoHeader
+);
+
+
+
+/**
+ * Function: omxVCM4P2_QuantInvIntra_I (6.2.5.3.2)
+ *
+ * Description:
+ * Performs the second inverse quantization mode on an intra/inter coded
+ * block. Supports bits_per_pixel = 8. The output coefficients are clipped to
+ * the range [-2048, 2047].
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - pointer to the input (quantized) intra/inter block; must be
+ * aligned on a 16-byte boundary.
+ * QP - quantization parameter (quantizer_scale)
+ * videoComp - video component type of the current block. Takes one of the
+ * following flags: OMX_VC_LUMINANCE, OMX_VC_CHROMINANCE (intra
+ * version only).
+ * shortVideoHeader - binary flag indicating presence of short_video_header
+ * (intra version only).
+ *
+ * Output Arguments:
+ *
+ * pSrcDst - pointer to the output (dequantized) intra/inter block
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; one or more of the following is
+ * true:
+ * - pSrcDst is NULL
+ * - QP <= 0 or QP >=31
+ * - videoComp is neither OMX_VC_LUMINANCE nor OMX_VC_CHROMINANCE.
+ *
+ */
+OMXResult omxVCM4P2_QuantInvIntra_I (
+ OMX_S16 *pSrcDst,
+ OMX_INT QP,
+ OMXVCM4P2VideoComponent videoComp,
+ OMX_INT shortVideoHeader
+);
+
+
+
+/**
+ * Function: omxVCM4P2_QuantInvInter_I (6.2.5.3.2)
+ *
+ * Description:
+ * Performs the second inverse quantization mode on an intra/inter coded
+ * block. Supports bits_per_pixel = 8. The output coefficients are clipped to
+ * the range [-2048, 2047].
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - pointer to the input (quantized) intra/inter block; must be
+ * aligned on a 16-byte boundary.
+ * QP - quantization parameter (quantizer_scale)
+ * videoComp - video component type of the current block. Takes one of the
+ * following flags: OMX_VC_LUMINANCE, OMX_VC_CHROMINANCE (intra
+ * version only).
+ * shortVideoHeader - binary flag indicating presence of short_video_header
+ * (intra version only).
+ *
+ * Output Arguments:
+ *
+ * pSrcDst - pointer to the output (dequantized) intra/inter block
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; one or more of the following is
+ * true:
+ * - pSrcDst is NULL
+ * - QP <= 0 or QP >=31
+ * - videoComp is neither OMX_VC_LUMINANCE nor OMX_VC_CHROMINANCE.
+ *
+ */
+OMXResult omxVCM4P2_QuantInvInter_I (
+ OMX_S16 *pSrcDst,
+ OMX_INT QP
+);
+
+
+
+/**
+ * Function: omxVCM4P2_DecodeBlockCoef_Intra (6.2.5.4.1)
+ *
+ * Description:
+ * Decodes the INTRA block coefficients. Inverse quantization, inversely
+ * zigzag positioning, and IDCT, with appropriate clipping on each step, are
+ * performed on the coefficients. The results are then placed in the output
+ * frame/plane on a pixel basis. Note: This function will be used only when
+ * at least one non-zero AC coefficient of current block exists in the bit
+ * stream. The DC only condition will be handled in another function.
+ *
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - pointer to the pointer to the current byte in the bit
+ * stream buffer. There is no boundary check for the bit stream
+ * buffer.
+ * pBitOffset - pointer to the bit position in the byte pointed to by
+ * *ppBitStream. *pBitOffset is valid within [0-7].
+ * step - width of the destination plane
+ * pCoefBufRow - pointer to the coefficient row buffer; must be aligned on
+ * an 8-byte boundary.
+ * pCoefBufCol - pointer to the coefficient column buffer; must be aligned
+ * on an 8-byte boundary.
+ * curQP - quantization parameter of the macroblock which the current block
+ * belongs to
+ * pQPBuf - pointer to the quantization parameter buffer
+ * blockIndex - block index indicating the component type and position as
+ * defined in [ISO14496-2], subclause 6.1.3.8, Figure 6-5.
+ * intraDCVLC - a code determined by intra_dc_vlc_thr and QP. This allows a
+ * mechanism to switch between two VLC for coding of Intra DC
+ * coefficients as per [ISO14496-2], Table 6-21.
+ * ACPredFlag - a flag equal to ac_pred_flag (of luminance) indicating if
+ * the ac coefficients of the first row or first column are
+ * differentially coded for intra coded macroblock.
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; shortVideoHeader==1 selects linear intra DC
+ * mode, and shortVideoHeader==0 selects non linear intra DC mode.
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after the block is decoded, so
+ * that it points to the current byte in the bit stream buffer
+ * pBitOffset - *pBitOffset is updated so that it points to the current bit
+ * position in the byte pointed by *ppBitStream
+ * pDst - pointer to the block in the destination plane; must be aligned on
+ * an 8-byte boundary.
+ * pCoefBufRow - pointer to the updated coefficient row buffer.
+ * pCoefBufCol - pointer to the updated coefficient column buffer Note:
+ * The coefficient buffers must be updated in accordance with the
+ * update procedure defined in section 6.2.2.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments, if:
+ * - At least one of the following pointers is NULL:
+ * ppBitStream, *ppBitStream, pBitOffset, pCoefBufRow, pCoefBufCol,
+ * pQPBuf, pDst.
+ * - *pBitOffset exceeds [0,7]
+ * - curQP exceeds (1, 31)
+ * - blockIndex exceeds [0,5]
+ * - step is not the multiple of 8
+ * - a pointer alignment requirement was violated.
+ * OMX_Sts_Err - status error. Refer to OMX_Sts_Err of DecodeVLCZigzag_Intra.
+ *
+ */
+OMXResult omxVCM4P2_DecodeBlockCoef_Intra (
+ const OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ OMX_U8 *pDst,
+ OMX_INT step,
+ OMX_S16 *pCoefBufRow,
+ OMX_S16 *pCoefBufCol,
+ OMX_U8 curQP,
+ const OMX_U8 *pQPBuf,
+ OMX_INT blockIndex,
+ OMX_INT intraDCVLC,
+ OMX_INT ACPredFlag,
+ OMX_INT shortVideoHeader
+);
+
+
+
+/**
+ * Function: omxVCM4P2_DecodeBlockCoef_Inter (6.2.5.4.2)
+ *
+ * Description:
+ * Decodes the INTER block coefficients. This function performs inverse
+ * quantization, inverse zigzag positioning, and IDCT (with appropriate
+ * clipping on each step) on the coefficients. The results (residuals) are
+ * placed in a contiguous array of 64 elements. For INTER block, the output
+ * buffer holds the residuals for further reconstruction.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - pointer to the pointer to the current byte in the bit
+ * stream buffer. There is no boundary check for the bit stream
+ * buffer.
+ * pBitOffset - pointer to the bit position in the byte pointed to by
+ * *ppBitStream. *pBitOffset is valid within [0-7]
+ * QP - quantization parameter
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; shortVideoHeader==1 selects linear intra DC
+ * mode, and shortVideoHeader==0 selects non linear intra DC mode.
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after the block is decoded, so
+ * that it points to the current byte in the bit stream buffer
+ * pBitOffset - *pBitOffset is updated so that it points to the current bit
+ * position in the byte pointed by *ppBitStream
+ * pDst - pointer to the decoded residual buffer (a contiguous array of 64
+ * elements of OMX_S16 data type); must be aligned on a 16-byte
+ * boundary.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments, if:
+ * - At least one of the following pointers is Null:
+ * ppBitStream, *ppBitStream, pBitOffset , pDst
+ * - *pBitOffset exceeds [0,7]
+ * - QP <= 0.
+ * - pDst is not 16-byte aligned
+ * OMX_Sts_Err - status error. Refer to OMX_Sts_Err of DecodeVLCZigzag_Inter .
+ *
+ */
+OMXResult omxVCM4P2_DecodeBlockCoef_Inter (
+ const OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ OMX_S16 *pDst,
+ OMX_INT QP,
+ OMX_INT shortVideoHeader
+);
+
+
+
+/**
+ * Function: omxVCM4P2_PredictReconCoefIntra (6.2.5.4.3)
+ *
+ * Description:
+ * Performs adaptive DC/AC coefficient prediction for an intra block. Prior
+ * to the function call, prediction direction (predDir) should be selected as
+ * specified in [ISO14496-2], subclause 7.4.3.1.
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - pointer to the coefficient buffer which contains the quantized
+ * coefficient residuals (PQF) of the current block; must be
+ * aligned on a 4-byte boundary. The output coefficients are
+ * saturated to the range [-2048, 2047].
+ * pPredBufRow - pointer to the coefficient row buffer; must be aligned on
+ * a 4-byte boundary.
+ * pPredBufCol - pointer to the coefficient column buffer; must be aligned
+ * on a 4-byte boundary.
+ * curQP - quantization parameter of the current block. curQP may equal to
+ * predQP especially when the current block and the predictor block
+ * are in the same macroblock.
+ * predQP - quantization parameter of the predictor block
+ * predDir - indicates the prediction direction which takes one of the
+ * following values: OMX_VC_HORIZONTAL - predict horizontally
+ * OMX_VC_VERTICAL - predict vertically
+ * ACPredFlag - a flag indicating if AC prediction should be performed. It
+ * is equal to ac_pred_flag in the bit stream syntax of MPEG-4
+ * videoComp - video component type (luminance or chrominance) of the
+ * current block
+ *
+ * Output Arguments:
+ *
+ * pSrcDst - pointer to the coefficient buffer which contains the quantized
+ * coefficients (QF) of the current block
+ * pPredBufRow - pointer to the updated coefficient row buffer
+ * pPredBufCol - pointer to the updated coefficient column buffer Note:
+ * Buffer update: Update the AC prediction buffer (both row and
+ * column buffer).
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments, if:
+ * - At least one of the pointers is NULL:
+ * pSrcDst, pPredBufRow, or pPredBufCol.
+ * - curQP <= 0,
+ * - predQP <= 0,
+ * - curQP >31,
+ * - predQP > 31,
+ * - preDir exceeds [1,2]
+ * - pSrcDst, pPredBufRow, or pPredBufCol is not 4-byte aligned.
+ *
+ */
+OMXResult omxVCM4P2_PredictReconCoefIntra (
+ OMX_S16 *pSrcDst,
+ OMX_S16 *pPredBufRow,
+ OMX_S16 *pPredBufCol,
+ OMX_INT curQP,
+ OMX_INT predQP,
+ OMX_INT predDir,
+ OMX_INT ACPredFlag,
+ OMXVCM4P2VideoComponent videoComp
+);
+
+
+
+/**
+ * Function: omxVCM4P2_MCReconBlock (6.2.5.5.1)
+ *
+ * Description:
+ * Performs motion compensation prediction for an 8x8 block using
+ * interpolation described in [ISO14496-2], subclause 7.6.2.
+ *
+ * Input Arguments:
+ *
+ * pSrc - pointer to the block in the reference plane.
+ * srcStep - distance between the start of consecutive lines in the
+ * reference plane, in bytes; must be a multiple of 8.
+ * dstStep - distance between the start of consecutive lines in the
+ * destination plane, in bytes; must be a multiple of 8.
+ * pSrcResidue - pointer to a buffer containing the 16-bit prediction
+ * residuals; must be 16-byte aligned. If the pointer is NULL, then
+ * no prediction is done, only motion compensation, i.e., the block
+ * is moved with interpolation.
+ * predictType - bilinear interpolation type, as defined in section
+ * 6.2.1.2.
+ * rndVal - rounding control parameter: 0 - disabled; 1 - enabled.
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the destination buffer; must be 8-byte aligned. If
+ * prediction residuals are added then output intensities are
+ * clipped to the range [0,255].
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned under any of the following
+ * conditions:
+ * - pDst is not 8-byte aligned.
+ * - pSrcResidue is not 16-byte aligned.
+ * - one or more of the following pointers is NULL: pSrc or pDst.
+ * - either srcStep or dstStep is not a multiple of 8.
+ * - invalid type specified for the parameter predictType.
+ * - the parameter rndVal is not equal either to 0 or 1.
+ *
+ */
+OMXResult omxVCM4P2_MCReconBlock (
+ const OMX_U8 *pSrc,
+ OMX_INT srcStep,
+ const OMX_S16 *pSrcResidue,
+ OMX_U8 *pDst,
+ OMX_INT dstStep,
+ OMX_INT predictType,
+ OMX_INT rndVal
+);
+
+
+
+/* 6.3.1.1 Intra 16x16 Prediction Modes */
+/* A data type that enumerates intra_16x16 macroblock prediction modes is defined as follows: */
+
+typedef enum {
+ OMX_VC_16X16_VERT = 0, /** Intra_16x16_Vertical */
+ OMX_VC_16X16_HOR = 1, /** Intra_16x16_Horizontal */
+ OMX_VC_16X16_DC = 2, /** Intra_16x16_DC */
+ OMX_VC_16X16_PLANE = 3 /** Intra_16x16_Plane */
+} OMXVCM4P10Intra16x16PredMode;
+
+
+
+/* 6.3.1.2 Intra 4x4 Prediction Modes */
+/* A data type that enumerates intra_4x4 macroblock prediction modes is defined as follows: */
+
+typedef enum {
+ OMX_VC_4X4_VERT = 0, /** Intra_4x4_Vertical */
+ OMX_VC_4X4_HOR = 1, /** Intra_4x4_Horizontal */
+ OMX_VC_4X4_DC = 2, /** Intra_4x4_DC */
+ OMX_VC_4X4_DIAG_DL = 3, /** Intra_4x4_Diagonal_Down_Left */
+ OMX_VC_4X4_DIAG_DR = 4, /** Intra_4x4_Diagonal_Down_Right */
+ OMX_VC_4X4_VR = 5, /** Intra_4x4_Vertical_Right */
+ OMX_VC_4X4_HD = 6, /** Intra_4x4_Horizontal_Down */
+ OMX_VC_4X4_VL = 7, /** Intra_4x4_Vertical_Left */
+ OMX_VC_4X4_HU = 8 /** Intra_4x4_Horizontal_Up */
+} OMXVCM4P10Intra4x4PredMode;
+
+
+
+/* 6.3.1.3 Chroma Prediction Modes */
+/* A data type that enumerates intra chroma prediction modes is defined as follows: */
+
+typedef enum {
+ OMX_VC_CHROMA_DC = 0, /** Intra_Chroma_DC */
+ OMX_VC_CHROMA_HOR = 1, /** Intra_Chroma_Horizontal */
+ OMX_VC_CHROMA_VERT = 2, /** Intra_Chroma_Vertical */
+ OMX_VC_CHROMA_PLANE = 3 /** Intra_Chroma_Plane */
+} OMXVCM4P10IntraChromaPredMode;
+
+
+
+/* 6.3.1.4 Motion Estimation Modes */
+/* A data type that enumerates H.264 motion estimation modes is defined as follows: */
+
+typedef enum {
+ OMX_VC_M4P10_FAST_SEARCH = 0, /** Fast motion search */
+ OMX_VC_M4P10_FULL_SEARCH = 1 /** Full motion search */
+} OMXVCM4P10MEMode;
+
+
+
+/* 6.3.1.5 Macroblock Types */
+/* A data type that enumerates H.264 macroblock types is defined as follows: */
+
+typedef enum {
+ OMX_VC_P_16x16 = 0, /* defined by [ISO14496-10] */
+ OMX_VC_P_16x8 = 1,
+ OMX_VC_P_8x16 = 2,
+ OMX_VC_P_8x8 = 3,
+ OMX_VC_PREF0_8x8 = 4,
+ OMX_VC_INTER_SKIP = 5,
+ OMX_VC_INTRA_4x4 = 8,
+ OMX_VC_INTRA_16x16 = 9,
+ OMX_VC_INTRA_PCM = 10
+} OMXVCM4P10MacroblockType;
+
+
+
+/* 6.3.1.6 Sub-Macroblock Types */
+/* A data type that enumerates H.264 sub-macroblock types is defined as follows: */
+
+typedef enum {
+ OMX_VC_SUB_P_8x8 = 0, /* defined by [ISO14496-10] */
+ OMX_VC_SUB_P_8x4 = 1,
+ OMX_VC_SUB_P_4x8 = 2,
+ OMX_VC_SUB_P_4x4 = 3
+} OMXVCM4P10SubMacroblockType;
+
+
+
+/* 6.3.1.7 Variable Length Coding (VLC) Information */
+
+typedef struct {
+ OMX_U8 uTrailing_Ones; /* Trailing ones; 3 at most */
+ OMX_U8 uTrailing_One_Signs; /* Trailing ones signal */
+ OMX_U8 uNumCoeffs; /* Total number of non-zero coefs, including trailing ones */
+ OMX_U8 uTotalZeros; /* Total number of zero coefs */
+ OMX_S16 iLevels[16]; /* Levels of non-zero coefs, in reverse zig-zag order */
+ OMX_U8 uRuns[16]; /* Runs for levels and trailing ones, in reverse zig-zag order */
+} OMXVCM4P10VLCInfo;
+
+
+
+/* 6.3.1.8 Macroblock Information */
+
+typedef struct {
+ OMX_S32 sliceId; /* slice number */
+ OMXVCM4P10MacroblockType mbType; /* MB type */
+ OMXVCM4P10SubMacroblockType subMBType[4]; /* sub-block type */
+ OMX_S32 qpy; /* qp for luma */
+ OMX_S32 qpc; /* qp for chroma */
+ OMX_U32 cbpy; /* CBP Luma */
+ OMX_U32 cbpc; /* CBP Chroma */
+ OMXVCMotionVector pMV0[4][4]; /* motion vector, represented using 1/4-pel units, pMV0[blocky][blockx] (blocky = 0~3, blockx =0~3) */
+ OMXVCMotionVector pMVPred[4][4]; /* motion vector prediction, Represented using 1/4-pel units, pMVPred[blocky][blockx] (blocky = 0~3, blockx = 0~3) */
+ OMX_U8 pRefL0Idx[4]; /* reference picture indices */
+ OMXVCM4P10Intra16x16PredMode Intra16x16PredMode; /* best intra 16x16 prediction mode */
+ OMXVCM4P10Intra4x4PredMode pIntra4x4PredMode[16]; /* best intra 4x4 prediction mode for each block, pMV0 indexed as above */
+} OMXVCM4P10MBInfo, *OMXVCM4P10MBInfoPtr;
+
+
+
+/* 6.3.1.9 Motion Estimation Parameters */
+
+typedef struct {
+ OMX_S32 blockSplitEnable8x8; /* enables 16x8, 8x16, 8x8 */
+ OMX_S32 blockSplitEnable4x4; /* enable splitting of 8x4, 4x8, 4x4 blocks */
+ OMX_S32 halfSearchEnable;
+ OMX_S32 quarterSearchEnable;
+ OMX_S32 intraEnable4x4; /* 1=enable, 0=disable */
+ OMX_S32 searchRange16x16; /* integer pixel units */
+ OMX_S32 searchRange8x8;
+ OMX_S32 searchRange4x4;
+} OMXVCM4P10MEParams;
+
+
+
+/**
+ * Function: omxVCM4P10_PredictIntra_4x4 (6.3.3.1.1)
+ *
+ * Description:
+ * Perform Intra_4x4 prediction for luma samples. If the upper-right block is
+ * not available, then duplication work should be handled inside the function.
+ * Users need not define them outside.
+ *
+ * Input Arguments:
+ *
+ * pSrcLeft - Pointer to the buffer of 4 left pixels:
+ * p[x, y] (x = -1, y = 0..3)
+ * pSrcAbove - Pointer to the buffer of 8 above pixels:
+ * p[x,y] (x = 0..7, y =-1);
+ * must be aligned on a 4-byte boundary.
+ * pSrcAboveLeft - Pointer to the above left pixels: p[x,y] (x = -1, y = -1)
+ * leftStep - Step of left pixel buffer; must be a multiple of 4.
+ * dstStep - Step of the destination buffer; must be a multiple of 4.
+ * predMode - Intra_4x4 prediction mode.
+ * availability - Neighboring 4x4 block availability flag, refer to
+ * "Neighboring Macroblock Availability" .
+ *
+ * Output Arguments:
+ *
+ * pDst - Pointer to the destination buffer; must be aligned on a 4-byte
+ * boundary.
+ *
+ * Return Value:
+ * If the function runs without error, it returns OMX_Sts_NoErr.
+ * If one of the following cases occurs, the function returns
+ * OMX_Sts_BadArgErr:
+ * pDst is NULL.
+ * dstStep < 4, or dstStep is not a multiple of 4.
+ * leftStep is not a multiple of 4.
+ * predMode is not in the valid range of enumeration
+ * OMXVCM4P10Intra4x4PredMode.
+ * predMode is OMX_VC_4x4_VERT, but availability doesn't set OMX_VC_UPPER
+ * indicating p[x,-1] (x = 0..3) is not available.
+ * predMode is OMX_VC_4x4_HOR, but availability doesn't set OMX_VC_LEFT
+ * indicating p[-1,y] (y = 0..3) is not available.
+ * predMode is OMX_VC_4x4_DIAG_DL, but availability doesn't set
+ * OMX_VC_UPPER indicating p[x, -1] (x = 0..3) is not available.
+ * predMode is OMX_VC_4x4_DIAG_DR, but availability doesn't set
+ * OMX_VC_UPPER_LEFT or OMX_VC_UPPER or OMX_VC_LEFT indicating
+ * p[x,-1] (x = 0..3), or p[-1,y] (y = 0..3) or p[-1,-1] is not
+ * available.
+ * predMode is OMX_VC_4x4_VR, but availability doesn't set
+ * OMX_VC_UPPER_LEFT or OMX_VC_UPPER or OMX_VC_LEFT indicating
+ * p[x,-1] (x = 0..3), or p[-1,y] (y = 0..3) or p[-1,-1] is not
+ * available.
+ * predMode is OMX_VC_4x4_HD, but availability doesn't set
+ * OMX_VC_UPPER_LEFT or OMX_VC_UPPER or OMX_VC_LEFT indicating
+ * p[x,-1] (x = 0..3), or p[-1,y] (y = 0..3) or p[-1,-1] is not
+ * available.
+ * predMode is OMX_VC_4x4_VL, but availability doesn't set OMX_VC_UPPER
+ * indicating p[x,-1] (x = 0..3) is not available.
+ * predMode is OMX_VC_4x4_HU, but availability doesn't set OMX_VC_LEFT
+ * indicating p[-1,y] (y = 0..3) is not available.
+ * availability sets OMX_VC_UPPER, but pSrcAbove is NULL.
+ * availability sets OMX_VC_LEFT, but pSrcLeft is NULL.
+ * availability sets OMX_VC_UPPER_LEFT, but pSrcAboveLeft is NULL.
+ * either pSrcAbove or pDst is not aligned on a 4-byte boundary.
+ *
+ * Note:
+ * pSrcAbove, pSrcAbove, pSrcAboveLeft may be invalid pointers if
+ * they are not used by intra prediction as implied in predMode.
+ *
+ */
+OMXResult omxVCM4P10_PredictIntra_4x4 (
+ const OMX_U8 *pSrcLeft,
+ const OMX_U8 *pSrcAbove,
+ const OMX_U8 *pSrcAboveLeft,
+ OMX_U8 *pDst,
+ OMX_INT leftStep,
+ OMX_INT dstStep,
+ OMXVCM4P10Intra4x4PredMode predMode,
+ OMX_S32 availability
+);
+
+
+
+/**
+ * Function: omxVCM4P10_PredictIntra_16x16 (6.3.3.1.2)
+ *
+ * Description:
+ * Perform Intra_16x16 prediction for luma samples. If the upper-right block
+ * is not available, then duplication work should be handled inside the
+ * function. Users need not define them outside.
+ *
+ * Input Arguments:
+ *
+ * pSrcLeft - Pointer to the buffer of 16 left pixels: p[x, y] (x = -1, y =
+ * 0..15)
+ * pSrcAbove - Pointer to the buffer of 16 above pixels: p[x,y] (x = 0..15,
+ * y= -1); must be aligned on a 16-byte boundary.
+ * pSrcAboveLeft - Pointer to the above left pixels: p[x,y] (x = -1, y = -1)
+ * leftStep - Step of left pixel buffer; must be a multiple of 16.
+ * dstStep - Step of the destination buffer; must be a multiple of 16.
+ * predMode - Intra_16x16 prediction mode, please refer to section 3.4.1.
+ * availability - Neighboring 16x16 MB availability flag. Refer to
+ * section 3.4.4.
+ *
+ * Output Arguments:
+ *
+ * pDst -Pointer to the destination buffer; must be aligned on a 16-byte
+ * boundary.
+ *
+ * Return Value:
+ * If the function runs without error, it returns OMX_Sts_NoErr.
+ * If one of the following cases occurs, the function returns
+ * OMX_Sts_BadArgErr:
+ * pDst is NULL.
+ * dstStep < 16. or dstStep is not a multiple of 16.
+ * leftStep is not a multiple of 16.
+ * predMode is not in the valid range of enumeration
+ * OMXVCM4P10Intra16x16PredMode
+ * predMode is OMX_VC_16X16_VERT, but availability doesn't set
+ * OMX_VC_UPPER indicating p[x,-1] (x = 0..15) is not available.
+ * predMode is OMX_VC_16X16_HOR, but availability doesn't set OMX_VC_LEFT
+ * indicating p[-1,y] (y = 0..15) is not available.
+ * predMode is OMX_VC_16X16_PLANE, but availability doesn't set
+ * OMX_VC_UPPER_LEFT or OMX_VC_UPPER or OMX_VC_LEFT indicating
+ * p[x,-1](x = 0..15), or p[-1,y] (y = 0..15), or p[-1,-1] is not
+ * available.
+ * availability sets OMX_VC_UPPER, but pSrcAbove is NULL.
+ * availability sets OMX_VC_LEFT, but pSrcLeft is NULL.
+ * availability sets OMX_VC_UPPER_LEFT, but pSrcAboveLeft is NULL.
+ * either pSrcAbove or pDst is not aligned on a 16-byte boundary.
+ *
+ * Note:
+ * pSrcAbove, pSrcAbove, pSrcAboveLeft may be invalid pointers if
+ * they are not used by intra prediction implied in predMode.
+ * Note:
+ * OMX_VC_UPPER_RIGHT is not used in intra_16x16 luma prediction.
+ *
+ */
+OMXResult omxVCM4P10_PredictIntra_16x16 (
+ const OMX_U8 *pSrcLeft,
+ const OMX_U8 *pSrcAbove,
+ const OMX_U8 *pSrcAboveLeft,
+ OMX_U8 *pDst,
+ OMX_INT leftStep,
+ OMX_INT dstStep,
+ OMXVCM4P10Intra16x16PredMode predMode,
+ OMX_S32 availability
+);
+
+
+
+/**
+ * Function: omxVCM4P10_PredictIntraChroma_8x8 (6.3.3.1.3)
+ *
+ * Description:
+ * Performs intra prediction for chroma samples.
+ *
+ * Input Arguments:
+ *
+ * pSrcLeft - Pointer to the buffer of 8 left pixels: p[x, y] (x = -1, y=
+ * 0..7).
+ * pSrcAbove - Pointer to the buffer of 8 above pixels: p[x,y] (x = 0..7, y
+ * = -1); must be aligned on an 8-byte boundary.
+ * pSrcAboveLeft - Pointer to the above left pixels: p[x,y] (x = -1, y = -1)
+ * leftStep - Step of left pixel buffer; must be a multiple of 8.
+ * dstStep - Step of the destination buffer; must be a multiple of 8.
+ * predMode - Intra chroma prediction mode, please refer to section 3.4.3.
+ * availability - Neighboring chroma block availability flag, please refer
+ * to "Neighboring Macroblock Availability".
+ *
+ * Output Arguments:
+ *
+ * pDst - Pointer to the destination buffer; must be aligned on an 8-byte
+ * boundary.
+ *
+ * Return Value:
+ * If the function runs without error, it returns OMX_Sts_NoErr.
+ * If any of the following cases occurs, the function returns
+ * OMX_Sts_BadArgErr:
+ * pDst is NULL.
+ * dstStep < 8 or dstStep is not a multiple of 8.
+ * leftStep is not a multiple of 8.
+ * predMode is not in the valid range of enumeration
+ * OMXVCM4P10IntraChromaPredMode.
+ * predMode is OMX_VC_CHROMA_VERT, but availability doesn't set
+ * OMX_VC_UPPER indicating p[x,-1] (x = 0..7) is not available.
+ * predMode is OMX_VC_CHROMA_HOR, but availability doesn't set OMX_VC_LEFT
+ * indicating p[-1,y] (y = 0..7) is not available.
+ * predMode is OMX_VC_CHROMA_PLANE, but availability doesn't set
+ * OMX_VC_UPPER_LEFT or OMX_VC_UPPER or OMX_VC_LEFT indicating
+ * p[x,-1](x = 0..7), or p[-1,y] (y = 0..7), or p[-1,-1] is not
+ * available.
+ * availability sets OMX_VC_UPPER, but pSrcAbove is NULL.
+ * availability sets OMX_VC_LEFT, but pSrcLeft is NULL.
+ * availability sets OMX_VC_UPPER_LEFT, but pSrcAboveLeft is NULL.
+ * either pSrcAbove or pDst is not aligned on a 8-byte boundary.
+ *
+ * Note: pSrcAbove, pSrcAbove, pSrcAboveLeft may be invalid pointer if
+ * they are not used by intra prediction implied in predMode.
+ *
+ * Note: OMX_VC_UPPER_RIGHT is not used in intra chroma prediction.
+ *
+ */
+OMXResult omxVCM4P10_PredictIntraChroma_8x8 (
+ const OMX_U8 *pSrcLeft,
+ const OMX_U8 *pSrcAbove,
+ const OMX_U8 *pSrcAboveLeft,
+ OMX_U8 *pDst,
+ OMX_INT leftStep,
+ OMX_INT dstStep,
+ OMXVCM4P10IntraChromaPredMode predMode,
+ OMX_S32 availability
+);
+
+
+
+/**
+ * Function: omxVCM4P10_InterpolateLuma (6.3.3.2.1)
+ *
+ * Description:
+ * Performs quarter-pixel interpolation for inter luma MB. It is assumed that
+ * the frame is already padded when calling this function.
+ *
+ * Input Arguments:
+ *
+ * pSrc - Pointer to the source reference frame buffer
+ * srcStep - reference frame step, in bytes; must be a multiple of roi.width
+ * dstStep - destination frame step, in bytes; must be a multiple of
+ * roi.width
+ * dx - Fractional part of horizontal motion vector component in 1/4 pixel
+ * unit; valid in the range [0,3]
+ * dy - Fractional part of vertical motion vector y component in 1/4 pixel
+ * unit; valid in the range [0,3]
+ * roi - Dimension of the interpolation region; the parameters roi.width and
+ * roi.height must be equal to either 4, 8, or 16.
+ *
+ * Output Arguments:
+ *
+ * pDst - Pointer to the destination frame buffer:
+ * if roi.width==4, 4-byte alignment required
+ * if roi.width==8, 8-byte alignment required
+ * if roi.width==16, 16-byte alignment required
+ *
+ * Return Value:
+ * If the function runs without error, it returns OMX_Sts_NoErr.
+ * If one of the following cases occurs, the function returns
+ * OMX_Sts_BadArgErr:
+ * pSrc or pDst is NULL.
+ * srcStep or dstStep < roi.width.
+ * dx or dy is out of range [0,3].
+ * roi.width or roi.height is out of range {4, 8, 16}.
+ * roi.width is equal to 4, but pDst is not 4 byte aligned.
+ * roi.width is equal to 8 or 16, but pDst is not 8 byte aligned.
+ * srcStep or dstStep is not a multiple of 8.
+ *
+ */
+OMXResult omxVCM4P10_InterpolateLuma (
+ const OMX_U8 *pSrc,
+ OMX_S32 srcStep,
+ OMX_U8 *pDst,
+ OMX_S32 dstStep,
+ OMX_S32 dx,
+ OMX_S32 dy,
+ OMXSize roi
+);
+
+
+
+/**
+ * Function: omxVCM4P10_InterpolateChroma (6.3.3.2.2)
+ *
+ * Description:
+ * Performs 1/8-pixel interpolation for inter chroma MB.
+ *
+ * Input Arguments:
+ *
+ * pSrc -Pointer to the source reference frame buffer
+ * srcStep -Reference frame step in bytes
+ * dstStep -Destination frame step in bytes; must be a multiple of
+ * roi.width.
+ * dx -Fractional part of horizontal motion vector component in 1/8 pixel
+ * unit; valid in the range [0,7]
+ * dy -Fractional part of vertical motion vector component in 1/8 pixel
+ * unit; valid in the range [0,7]
+ * roi -Dimension of the interpolation region; the parameters roi.width and
+ * roi.height must be equal to either 2, 4, or 8.
+ *
+ * Output Arguments:
+ *
+ * pDst -Pointer to the destination frame buffer:
+ * if roi.width==2, 2-byte alignment required
+ * if roi.width==4, 4-byte alignment required
+ * if roi.width==8, 8-byte alignment required
+ *
+ * Return Value:
+ * If the function runs without error, it returns OMX_Sts_NoErr.
+ * If one of the following cases occurs, the function returns
+ * OMX_Sts_BadArgErr:
+ * pSrc or pDst is NULL.
+ * srcStep or dstStep < 8.
+ * dx or dy is out of range [0-7].
+ * roi.width or roi.height is out of range {2,4,8}.
+ * roi.width is equal to 2, but pDst is not 2-byte aligned.
+ * roi.width is equal to 4, but pDst is not 4-byte aligned.
+ * roi.width is equal to 8, but pDst is not 8 byte aligned.
+ * srcStep or dstStep is not a multiple of 8.
+ *
+ */
+OMXResult omxVCM4P10_InterpolateChroma (
+ const OMX_U8 *pSrc,
+ OMX_S32 srcStep,
+ OMX_U8 *pDst,
+ OMX_S32 dstStep,
+ OMX_S32 dx,
+ OMX_S32 dy,
+ OMXSize roi
+);
+
+
+
+/**
+ * Function: omxVCM4P10_FilterDeblockingLuma_VerEdge_I (6.3.3.3.1)
+ *
+ * Description:
+ * Performs in-place deblock filtering on four vertical edges of the luma
+ * macroblock (16x16).
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - Pointer to the input macroblock; must be 16-byte aligned.
+ * srcdstStep -Step of the arrays; must be a multiple of 16.
+ * pAlpha -Array of size 2 of alpha thresholds (the first item is the alpha
+ * threshold for the external vertical edge, and the second item is
+ * for the internal vertical edge); per [ISO14496-10] alpha values
+ * must be in the range [0,255].
+ * pBeta -Array of size 2 of beta thresholds (the first item is the beta
+ * threshold for the external vertical edge, and the second item is
+ * for the internal vertical edge); per [ISO14496-10] beta values
+ * must be in the range [0,18].
+ * pThresholds -Array of size 16 of Thresholds (TC0) (values for the left
+ * edge of each 4x4 block, arranged in vertical block order); must
+ * be aligned on a 4-byte boundary.. Per [ISO14496-10] values must
+ * be in the range [0,25].
+ * pBS -Array of size 16 of BS parameters (arranged in vertical block
+ * order); valid in the range [0,4] with the following
+ * restrictions: i) pBS[i]== 4 may occur only for 0<=i<=3, ii)
+ * pBS[i]== 4 if and only if pBS[i^3]== 4. Must be 4-byte aligned.
+ *
+ * Output Arguments:
+ *
+ * pSrcDst -Pointer to filtered output macroblock.
+ *
+ * Return Value:
+ * If the function runs without error, it returns OMX_Sts_NoErr.
+ * If one of the following cases occurs, the function returns
+ * OMX_Sts_BadArgErr:
+ * Either of the pointers in pSrcDst, pAlpha, pBeta, pThresholds, or pBS
+ * is NULL.
+ * Either pThresholds or pBS is not aligned on a 4-byte boundary.
+ * pSrcDst is not 16-byte aligned.
+ * srcdstStep is not a multiple of 16.
+ * pAlpha[0] and/or pAlpha[1] is outside the range [0,255].
+ * pBeta[0] and/or pBeta[1] is outside the range [0,18].
+ * One or more entries in the table pThresholds[0..15]is outside of the
+ * range [0,25].
+ * pBS is out of range, i.e., one of the following conditions is true:
+ * pBS[i]<0, pBS[i]>4, pBS[i]==4 for i>=4, or (pBS[i]==4 &&
+ * pBS[i^3]!=4) for 0<=i<=3.
+ *
+ */
+OMXResult omxVCM4P10_FilterDeblockingLuma_VerEdge_I (
+ OMX_U8 *pSrcDst,
+ OMX_S32 srcdstStep,
+ const OMX_U8 *pAlpha,
+ const OMX_U8 *pBeta,
+ const OMX_U8 *pThresholds,
+ const OMX_U8 *pBS
+);
+
+
+
+/**
+ * Function: omxVCM4P10_FilterDeblockingLuma_HorEdge_I (6.3.3.3.2)
+ *
+ * Description:
+ * Performs in-place deblock filtering on four horizontal edges of the luma
+ * macroblock (16x16).
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - pointer to the input macroblock; must be 16-byte aligned.
+ * srcdstStep - step of the arrays; must be a multiple of 16.
+ * pAlpha - array of size 2 of alpha thresholds (the first item is the alpha
+ * threshold for the external vertical edge, and the second item is
+ * for the internal horizontal edge); per [ISO14496-10] alpha
+ * values must be in the range [0,255].
+ * pBeta - array of size 2 of beta thresholds (the first item is the beta
+ * threshold for the external horizontal edge, and the second item
+ * is for the internal horizontal edge). Per [ISO14496-10] beta
+ * values must be in the range [0,18].
+ * pThresholds - array of size 16 containing thresholds, TC0, for the top
+ * horizontal edge of each 4x4 block, arranged in horizontal block
+ * order; must be aligned on a 4-byte boundary. Per [ISO14496 10]
+ * values must be in the range [0,25].
+ * pBS - array of size 16 of BS parameters (arranged in horizontal block
+ * order); valid in the range [0,4] with the following
+ * restrictions: i) pBS[i]== 4 may occur only for 0<=i<=3, ii)
+ * pBS[i]== 4 if and only if pBS[i^3]== 4. Must be 4-byte aligned.
+ *
+ * Output Arguments:
+ *
+ * pSrcDst -Pointer to filtered output macroblock.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr, if the function runs without error.
+ *
+ * OMX_Sts_BadArgErr, if one of the following cases occurs:
+ * - one or more of the following pointers is NULL: pSrcDst, pAlpha,
+ * pBeta, pThresholds, or pBS.
+ * - either pThresholds or pBS is not aligned on a 4-byte boundary.
+ * - pSrcDst is not 16-byte aligned.
+ * - srcdstStep is not a multiple of 16.
+ * - pAlpha[0] and/or pAlpha[1] is outside the range [0,255].
+ * - pBeta[0] and/or pBeta[1] is outside the range [0,18].
+ * - One or more entries in the table pThresholds[0..15] is
+ * outside of the range [0,25].
+ * - pBS is out of range, i.e., one of the following conditions is true:
+ * pBS[i]<0, pBS[i]>4, pBS[i]==4 for i>=4, or
+ * (pBS[i]==4 && pBS[i^3]!=4) for 0<=i<=3.
+ *
+ */
+OMXResult omxVCM4P10_FilterDeblockingLuma_HorEdge_I (
+ OMX_U8 *pSrcDst,
+ OMX_S32 srcdstStep,
+ const OMX_U8 *pAlpha,
+ const OMX_U8 *pBeta,
+ const OMX_U8 *pThresholds,
+ const OMX_U8 *pBS
+);
+
+
+
+/**
+ * Function: omxVCM4P10_FilterDeblockingChroma_VerEdge_I (6.3.3.3.3)
+ *
+ * Description:
+ * Performs in-place deblock filtering on four vertical edges of the chroma
+ * macroblock (8x8).
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - Pointer to the input macroblock; must be 8-byte aligned.
+ * srcdstStep - Step of the arrays; must be a multiple of 8.
+ * pAlpha - Array of size 2 of alpha thresholds (the first item is alpha
+ * threshold for external vertical edge, and the second item is for
+ * internal vertical edge); per [ISO14496-10] alpha values must be
+ * in the range [0,255].
+ * pBeta - Array of size 2 of beta thresholds (the first item is the beta
+ * threshold for the external vertical edge, and the second item is
+ * for the internal vertical edge); per [ISO14496-10] beta values
+ * must be in the range [0,18].
+ * pThresholds - Array of size 8 containing thresholds, TC0, for the left
+ * vertical edge of each 4x2 chroma block, arranged in vertical
+ * block order; must be aligned on a 4-byte boundary. Per
+ * [ISO14496-10] values must be in the range [0,25].
+ * pBS - Array of size 16 of BS parameters (values for each 2x2 chroma
+ * block, arranged in vertical block order). This parameter is the
+ * same as the pBS parameter passed into FilterDeblockLuma_VerEdge;
+ * valid in the range [0,4] with the following restrictions: i)
+ * pBS[i]== 4 may occur only for 0<=i<=3, ii) pBS[i]== 4 if and
+ * only if pBS[i^3]== 4. Must be 4 byte aligned.
+ *
+ * Output Arguments:
+ *
+ * pSrcDst -Pointer to filtered output macroblock.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr, if the function runs without error.
+ *
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - one or more of the following pointers is NULL: pSrcDst, pAlpha,
+ * pBeta, pThresholds, or pBS.
+ * - pSrcDst is not 8-byte aligned.
+ * - srcdstStep is not a multiple of 8.
+ * - pThresholds is not 4-byte aligned.
+ * - pAlpha[0] and/or pAlpha[1] is outside the range [0,255].
+ * - pBeta[0] and/or pBeta[1] is outside the range [0,18].
+ * - One or more entries in the table pThresholds[0..7] is outside
+ * of the range [0,25].
+ * - pBS is out of range, i.e., one of the following conditions is true:
+ * pBS[i]<0, pBS[i]>4, pBS[i]==4 for i>=4, or
+ * (pBS[i]==4 && pBS[i^3]!=4) for 0<=i<=3.
+ * - pBS is not 4-byte aligned.
+ *
+ */
+OMXResult omxVCM4P10_FilterDeblockingChroma_VerEdge_I (
+ OMX_U8 *pSrcDst,
+ OMX_S32 srcdstStep,
+ const OMX_U8 *pAlpha,
+ const OMX_U8 *pBeta,
+ const OMX_U8 *pThresholds,
+ const OMX_U8 *pBS
+);
+
+
+
+/**
+ * Function: omxVCM4P10_FilterDeblockingChroma_HorEdge_I (6.3.3.3.4)
+ *
+ * Description:
+ * Performs in-place deblock filtering on the horizontal edges of the chroma
+ * macroblock (8x8).
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - pointer to the input macroblock; must be 8-byte aligned.
+ * srcdstStep - array step; must be a multiple of 8.
+ * pAlpha - array of size 2 containing alpha thresholds; the first element
+ * contains the threshold for the external horizontal edge, and the
+ * second element contains the threshold for internal horizontal
+ * edge. Per [ISO14496-10] alpha values must be in the range
+ * [0,255].
+ * pBeta - array of size 2 containing beta thresholds; the first element
+ * contains the threshold for the external horizontal edge, and the
+ * second element contains the threshold for the internal
+ * horizontal edge. Per [ISO14496-10] beta values must be in the
+ * range [0,18].
+ * pThresholds - array of size 8 containing thresholds, TC0, for the top
+ * horizontal edge of each 2x4 chroma block, arranged in horizontal
+ * block order; must be aligned on a 4-byte boundary. Per
+ * [ISO14496-10] values must be in the range [0,25].
+ * pBS - array of size 16 containing BS parameters for each 2x2 chroma
+ * block, arranged in horizontal block order; valid in the range
+ * [0,4] with the following restrictions: i) pBS[i]== 4 may occur
+ * only for 0<=i<=3, ii) pBS[i]== 4 if and only if pBS[i^3]== 4.
+ * Must be 4-byte aligned.
+ *
+ * Output Arguments:
+ *
+ * pSrcDst -Pointer to filtered output macroblock.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr, if the function runs without error.
+ *
+ * OMX_Sts_BadArgErr, if one of the following cases occurs:
+ * - any of the following pointers is NULL:
+ * pSrcDst, pAlpha, pBeta, pThresholds, or pBS.
+ * - pSrcDst is not 8-byte aligned.
+ * - srcdstStep is not a multiple of 8.
+ * - pThresholds is not 4-byte aligned.
+ * - pAlpha[0] and/or pAlpha[1] is outside the range [0,255].
+ * - pBeta[0] and/or pBeta[1] is outside the range [0,18].
+ * - One or more entries in the table pThresholds[0..7] is outside
+ * of the range [0,25].
+ * - pBS is out of range, i.e., one of the following conditions is true:
+ * pBS[i]<0, pBS[i]>4, pBS[i]==4 for i>=4, or
+ * (pBS[i]==4 && pBS[i^3]!=4) for 0<=i<=3.
+ * - pBS is not 4-byte aligned.
+ *
+ */
+OMXResult omxVCM4P10_FilterDeblockingChroma_HorEdge_I (
+ OMX_U8 *pSrcDst,
+ OMX_S32 srcdstStep,
+ const OMX_U8 *pAlpha,
+ const OMX_U8 *pBeta,
+ const OMX_U8 *pThresholds,
+ const OMX_U8 *pBS
+);
+
+
+
+/**
+ * Function: omxVCM4P10_DeblockLuma_I (6.3.3.3.5)
+ *
+ * Description:
+ * This function performs in-place deblock filtering the horizontal and
+ * vertical edges of a luma macroblock (16x16).
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - pointer to the input macroblock; must be 16-byte aligned.
+ * srcdstStep - image width; must be a multiple of 16.
+ * pAlpha - pointer to a 2x2 table of alpha thresholds, organized as
+ * follows: {external vertical edge, internal vertical edge,
+ * external horizontal edge, internal horizontal edge }. Per
+ * [ISO14496-10] alpha values must be in the range [0,255].
+ * pBeta - pointer to a 2x2 table of beta thresholds, organized as follows:
+ * {external vertical edge, internal vertical edge, external
+ * horizontal edge, internal horizontal edge }. Per [ISO14496-10]
+ * beta values must be in the range [0,18].
+ * pThresholds - pointer to a 16x2 table of threshold (TC0), organized as
+ * follows: {values for the left or above edge of each 4x4 block,
+ * arranged in vertical block order and then in horizontal block
+ * order}; must be aligned on a 4-byte boundary. Per [ISO14496-10]
+ * values must be in the range [0,25].
+ * pBS - pointer to a 16x2 table of BS parameters arranged in scan block
+ * order for vertical edges and then horizontal edges; valid in the
+ * range [0,4] with the following restrictions: i) pBS[i]== 4 may
+ * occur only for 0<=i<=3, ii) pBS[i]== 4 if and only if pBS[i^3]==
+ * 4. Must be 4-byte aligned.
+ *
+ * Output Arguments:
+ *
+ * pSrcDst - pointer to filtered output macroblock.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments
+ * - one or more of the following pointers is NULL: pSrcDst, pAlpha,
+ * pBeta, pThresholds or pBS.
+ * - pSrcDst is not 16-byte aligned.
+ * - either pThresholds or pBS is not aligned on a 4-byte boundary.
+ * - one or more entries in the table pAlpha[0..3] is outside the range
+ * [0,255].
+ * - one or more entries in the table pBeta[0..3] is outside the range
+ * [0,18].
+ * - one or more entries in the table pThresholds[0..31]is outside of
+ * the range [0,25].
+ * - pBS is out of range, i.e., one of the following conditions is true:
+ * pBS[i]<0, pBS[i]>4, pBS[i]==4 for i>=4, or
+ * (pBS[i]==4 && pBS[i^3]!=4) for 0<=i<=3.
+ * - srcdstStep is not a multiple of 16.
+ *
+ */
+OMXResult omxVCM4P10_DeblockLuma_I (
+ OMX_U8 *pSrcDst,
+ OMX_S32 srcdstStep,
+ const OMX_U8 *pAlpha,
+ const OMX_U8 *pBeta,
+ const OMX_U8 *pThresholds,
+ const OMX_U8 *pBS
+);
+
+
+
+/**
+ * Function: omxVCM4P10_DeblockChroma_I (6.3.3.3.6)
+ *
+ * Description:
+ * Performs in-place deblocking filtering on all edges of the chroma
+ * macroblock (16x16).
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - pointer to the input macroblock; must be 8-byte aligned.
+ * srcdstStep - step of the arrays; must be a multiple of 8.
+ * pAlpha - pointer to a 2x2 array of alpha thresholds, organized as
+ * follows: {external vertical edge, internal vertical edge,
+ * external horizontal edge, internal horizontal edge }. Per
+ * [ISO14496-10] alpha values must be in the range [0,255].
+ * pBeta - pointer to a 2x2 array of Beta Thresholds, organized as follows:
+ * { external vertical edge, internal vertical edge, external
+ * horizontal edge, internal horizontal edge }. Per [ISO14496-10]
+ * beta values must be in the range [0,18].
+ * pThresholds - array of size 8x2 of Thresholds (TC0) (values for the left
+ * or above edge of each 4x2 or 2x4 block, arranged in vertical
+ * block order and then in horizontal block order); must be aligned
+ * on a 4-byte boundary. Per [ISO14496-10] values must be in the
+ * range [0,25].
+ * pBS - array of size 16x2 of BS parameters (arranged in scan block order
+ * for vertical edges and then horizontal edges); valid in the
+ * range [0,4] with the following restrictions: i) pBS[i]== 4 may
+ * occur only for 0<=i<=3, ii) pBS[i]== 4 if and only if pBS[i^3]==
+ * 4. Must be 4-byte aligned.
+ *
+ * Output Arguments:
+ *
+ * pSrcDst - pointer to filtered output macroblock.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments
+ * - one or more of the following pointers is NULL: pSrcDst, pAlpha,
+ * pBeta, pThresholds, or pBS.
+ * - pSrcDst is not 8-byte aligned.
+ * - either pThresholds or pBS is not 4-byte aligned.
+ * - one or more entries in the table pAlpha[0..3] is outside the range
+ * [0,255].
+ * - one or more entries in the table pBeta[0..3] is outside the range
+ * [0,18].
+ * - one or more entries in the table pThresholds[0..15]is outside of
+ * the range [0,25].
+ * - pBS is out of range, i.e., one of the following conditions is true:
+ * pBS[i]<0, pBS[i]>4, pBS[i]==4 for i>=4, or
+ * (pBS[i]==4 && pBS[i^3]!=4) for 0<=i<=3.
+ * - srcdstStep is not a multiple of 8.
+ *
+ */
+OMXResult omxVCM4P10_DeblockChroma_I (
+ OMX_U8 *pSrcDst,
+ OMX_S32 srcdstStep,
+ const OMX_U8 *pAlpha,
+ const OMX_U8 *pBeta,
+ const OMX_U8 *pThresholds,
+ const OMX_U8 *pBS
+);
+
+
+
+/**
+ * Function: omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC (6.3.4.1.1)
+ *
+ * Description:
+ * Performs CAVLC decoding and inverse raster scan for a 2x2 block of
+ * ChromaDCLevel. The decoded coefficients in the packed position-coefficient
+ * buffer are stored in reverse zig-zag order, i.e., the first buffer element
+ * contains the last non-zero postion-coefficient pair of the block. Within
+ * each position-coefficient pair, the position entry indicates the
+ * raster-scan position of the coefficient, while the coefficient entry
+ * contains the coefficient value.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - Double pointer to current byte in bit stream buffer
+ * pOffset - Pointer to current bit position in the byte pointed to by
+ * *ppBitStream; valid in the range [0,7].
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after each block is decoded
+ * pOffset - *pOffset is updated after each block is decoded
+ * pNumCoeff - Pointer to the number of nonzero coefficients in this block
+ * ppPosCoefBuf - Double pointer to destination residual
+ * coefficient-position pair buffer. Buffer position
+ * (*ppPosCoefBuf) is updated upon return, unless there are only
+ * zero coefficients in the currently decoded block. In this case
+ * the caller is expected to bypass the transform/dequantization of
+ * the empty blocks.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr, if the function runs without error.
+ *
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - ppBitStream or pOffset is NULL.
+ * - ppPosCoefBuf or pNumCoeff is NULL.
+ * OMX_Sts_Err - if one of the following is true:
+ * - an illegal code is encountered in the bitstream
+ *
+ */
+OMXResult omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC (
+ const OMX_U8 **ppBitStream,
+ OMX_S32*pOffset,
+ OMX_U8 *pNumCoeff,
+ OMX_U8 **ppPosCoefbuf
+);
+
+
+
+/**
+ * Function: omxVCM4P10_DecodeCoeffsToPairCAVLC (6.3.4.1.2)
+ *
+ * Description:
+ * Performs CAVLC decoding and inverse zigzag scan for 4x4 block of
+ * Intra16x16DCLevel, Intra16x16ACLevel, LumaLevel, and ChromaACLevel. Inverse
+ * field scan is not supported. The decoded coefficients in the packed
+ * position-coefficient buffer are stored in reverse zig-zag order, i.e., the
+ * first buffer element contains the last non-zero postion-coefficient pair of
+ * the block. Within each position-coefficient pair, the position entry
+ * indicates the raster-scan position of the coefficient, while the
+ * coefficient entry contains the coefficient value.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream -Double pointer to current byte in bit stream buffer
+ * pOffset - Pointer to current bit position in the byte pointed to by
+ * *ppBitStream; valid in the range [0,7].
+ * sMaxNumCoeff - Maximum the number of non-zero coefficients in current
+ * block
+ * sVLCSelect - VLC table selector, obtained from the number of non-zero
+ * coefficients contained in the above and left 4x4 blocks. It is
+ * equivalent to the variable nC described in H.264 standard table
+ * 9 5, except its value can t be less than zero.
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after each block is decoded.
+ * Buffer position (*ppPosCoefBuf) is updated upon return, unless
+ * there are only zero coefficients in the currently decoded block.
+ * In this case the caller is expected to bypass the
+ * transform/dequantization of the empty blocks.
+ * pOffset - *pOffset is updated after each block is decoded
+ * pNumCoeff - Pointer to the number of nonzero coefficients in this block
+ * ppPosCoefBuf - Double pointer to destination residual
+ * coefficient-position pair buffer
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ *
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - ppBitStream or pOffset is NULL.
+ * - ppPosCoefBuf or pNumCoeff is NULL.
+ * - sMaxNumCoeff is not equal to either 15 or 16.
+ * - sVLCSelect is less than 0.
+ *
+ * OMX_Sts_Err - if one of the following is true:
+ * - an illegal code is encountered in the bitstream
+ *
+ */
+OMXResult omxVCM4P10_DecodeCoeffsToPairCAVLC (
+ const OMX_U8 **ppBitStream,
+ OMX_S32 *pOffset,
+ OMX_U8 *pNumCoeff,
+ OMX_U8 **ppPosCoefbuf,
+ OMX_INT sVLCSelect,
+ OMX_INT sMaxNumCoeff
+);
+
+
+
+/**
+ * Function: omxVCM4P10_TransformDequantLumaDCFromPair (6.3.4.2.1)
+ *
+ * Description:
+ * Reconstructs the 4x4 LumaDC block from the coefficient-position pair
+ * buffer, performs integer inverse, and dequantization for 4x4 LumaDC
+ * coefficients, and updates the pair buffer pointer to the next non-empty
+ * block.
+ *
+ * Input Arguments:
+ *
+ * ppSrc - Double pointer to residual coefficient-position pair buffer
+ * output by CALVC decoding
+ * QP - Quantization parameter QpY
+ *
+ * Output Arguments:
+ *
+ * ppSrc - *ppSrc is updated to the start of next non empty block
+ * pDst - Pointer to the reconstructed 4x4 LumaDC coefficients buffer; must
+ * be aligned on a 8-byte boundary.
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - ppSrc or pDst is NULL.
+ * - pDst is not 8 byte aligned.
+ * - QP is not in the range of [0-51].
+ *
+ */
+OMXResult omxVCM4P10_TransformDequantLumaDCFromPair (
+ const OMX_U8 **ppSrc,
+ OMX_S16 *pDst,
+ OMX_INT QP
+);
+
+
+
+/**
+ * Function: omxVCM4P10_TransformDequantChromaDCFromPair (6.3.4.2.2)
+ *
+ * Description:
+ * Reconstruct the 2x2 ChromaDC block from coefficient-position pair buffer,
+ * perform integer inverse transformation, and dequantization for 2x2 chroma
+ * DC coefficients, and update the pair buffer pointer to next non-empty
+ * block.
+ *
+ * Input Arguments:
+ *
+ * ppSrc - Double pointer to residual coefficient-position pair buffer
+ * output by CALVC decoding
+ * QP - Quantization parameter QpC
+ *
+ * Output Arguments:
+ *
+ * ppSrc - *ppSrc is updated to the start of next non empty block
+ * pDst - Pointer to the reconstructed 2x2 ChromaDC coefficients buffer;
+ * must be aligned on a 4-byte boundary.
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - ppSrc or pDst is NULL.
+ * - pDst is not 4-byte aligned.
+ * - QP is not in the range of [0-51].
+ *
+ */
+OMXResult omxVCM4P10_TransformDequantChromaDCFromPair (
+ const OMX_U8 **ppSrc,
+ OMX_S16 *pDst,
+ OMX_INT QP
+);
+
+
+
+/**
+ * Function: omxVCM4P10_DequantTransformResidualFromPairAndAdd (6.3.4.2.3)
+ *
+ * Description:
+ * Reconstruct the 4x4 residual block from coefficient-position pair buffer,
+ * perform dequantization and integer inverse transformation for 4x4 block of
+ * residuals with previous intra prediction or motion compensation data, and
+ * update the pair buffer pointer to next non-empty block. If pDC == NULL,
+ * there re 16 non-zero AC coefficients at most in the packed buffer starting
+ * from 4x4 block position 0; If pDC != NULL, there re 15 non-zero AC
+ * coefficients at most in the packet buffer starting from 4x4 block position
+ * 1.
+ *
+ * Input Arguments:
+ *
+ * ppSrc - Double pointer to residual coefficient-position pair buffer
+ * output by CALVC decoding
+ * pPred - Pointer to the predicted 4x4 block; must be aligned on a 4-byte
+ * boundary
+ * predStep - Predicted frame step size in bytes; must be a multiple of 4
+ * dstStep - Destination frame step in bytes; must be a multiple of 4
+ * pDC - Pointer to the DC coefficient of this block, NULL if it doesn't
+ * exist
+ * QP - QP Quantization parameter. It should be QpC in chroma 4x4 block
+ * decoding, otherwise it should be QpY.
+ * AC - Flag indicating if at least one non-zero AC coefficient exists
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the reconstructed 4x4 block data; must be aligned on a
+ * 4-byte boundary
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - pPred or pDst is NULL.
+ * - pPred or pDst is not 4-byte aligned.
+ * - predStep or dstStep is not a multiple of 4.
+ * - AC !=0 and Qp is not in the range of [0-51] or ppSrc == NULL.
+ * - AC ==0 && pDC ==NULL.
+ *
+ */
+OMXResult omxVCM4P10_DequantTransformResidualFromPairAndAdd (
+ const OMX_U8 **ppSrc,
+ const OMX_U8 *pPred,
+ const OMX_S16 *pDC,
+ OMX_U8 *pDst,
+ OMX_INT predStep,
+ OMX_INT dstStep,
+ OMX_INT QP,
+ OMX_INT AC
+);
+
+
+
+/**
+ * Function: omxVCM4P10_MEGetBufSize (6.3.5.1.1)
+ *
+ * Description:
+ * Computes the size, in bytes, of the vendor-specific specification
+ * structure for the omxVCM4P10 motion estimation functions BlockMatch_Integer
+ * and MotionEstimationMB.
+ *
+ * Input Arguments:
+ *
+ * MEmode - motion estimation mode; available modes are defined by the
+ * enumerated type OMXVCM4P10MEMode
+ * pMEParams -motion estimation parameters
+ *
+ * Output Arguments:
+ *
+ * pSize - pointer to the number of bytes required for the motion
+ * estimation specification structure
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - pMEParams or pSize is NULL.
+ * - an invalid MEMode is specified.
+ *
+ */
+OMXResult omxVCM4P10_MEGetBufSize (
+ OMXVCM4P10MEMode MEmode,
+ const OMXVCM4P10MEParams *pMEParams,
+ OMX_U32 *pSize
+);
+
+
+
+/**
+ * Function: omxVCM4P10_MEInit (6.3.5.1.2)
+ *
+ * Description:
+ * Initializes the vendor-specific specification structure required for the
+ * omxVCM4P10 motion estimation functions: BlockMatch_Integer and
+ * MotionEstimationMB. Memory for the specification structure *pMESpec must be
+ * allocated prior to calling the function, and should be aligned on a 4-byte
+ * boundary. The number of bytes required for the specification structure can
+ * be determined using the function omxVCM4P10_MEGetBufSize. Following
+ * initialization by this function, the vendor-specific structure *pMESpec
+ * should contain an implementation-specific representation of all motion
+ * estimation parameters received via the structure pMEParams, for example
+ * searchRange16x16, searchRange8x8, etc.
+ *
+ * Input Arguments:
+ *
+ * MEmode - motion estimation mode; available modes are defined by the
+ * enumerated type OMXVCM4P10MEMode
+ * pMEParams - motion estimation parameters
+ * pMESpec - pointer to the uninitialized ME specification structure
+ *
+ * Output Arguments:
+ *
+ * pMESpec - pointer to the initialized ME specification structure
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - pMEParams or pSize is NULL.
+ * - an invalid value was specified for the parameter MEmode
+ * - a negative or zero value was specified for one of the search ranges
+ * (e.g., pMBParams >searchRange8x8, pMEParams->searchRange16x16, etc.)
+ * - either in isolation or in combination, one or more of the enables or
+ * search ranges in the structure *pMEParams were configured such
+ * that the requested behavior fails to comply with [ISO14496-10].
+ *
+ */
+OMXResult omxVCM4P10_MEInit (
+ OMXVCM4P10MEMode MEmode,
+ const OMXVCM4P10MEParams *pMEParams,
+ void *pMESpec
+);
+
+
+
+/**
+ * Function: omxVCM4P10_BlockMatch_Integer (6.3.5.2.1)
+ *
+ * Description:
+ * Performs integer block match. Returns best MV and associated cost.
+ *
+ * Input Arguments:
+ *
+ * pSrcOrgY - Pointer to the top-left corner of the current block:
+ * If iBlockWidth==4, 4-byte alignment required.
+ * If iBlockWidth==8, 8-byte alignment required.
+ * If iBlockWidth==16, 16-byte alignment required.
+ * pSrcRefY - Pointer to the top-left corner of the co-located block in the
+ * reference picture:
+ * If iBlockWidth==4, 4-byte alignment required.
+ * If iBlockWidth==8, 8-byte alignment required.
+ * If iBlockWidth==16, 16-byte alignment required.
+ * nSrcOrgStep - Stride of the original picture plane, expressed in terms
+ * of integer pixels; must be a multiple of iBlockWidth.
+ * nSrcRefStep - Stride of the reference picture plane, expressed in terms
+ * of integer pixels
+ * pRefRect - pointer to the valid reference rectangle inside the reference
+ * picture plane
+ * nCurrPointPos - position of the current block in the current plane
+ * iBlockWidth - Width of the current block, expressed in terms of integer
+ * pixels; must be equal to either 4, 8, or 16.
+ * iBlockHeight - Height of the current block, expressed in terms of
+ * integer pixels; must be equal to either 4, 8, or 16.
+ * nLamda - Lamda factor; used to compute motion cost
+ * pMVPred - Predicted MV; used to compute motion cost, expressed in terms
+ * of 1/4-pel units
+ * pMVCandidate - Candidate MV; used to initialize the motion search,
+ * expressed in terms of integer pixels
+ * pMESpec - pointer to the ME specification structure
+ *
+ * Output Arguments:
+ *
+ * pDstBestMV - Best MV resulting from integer search, expressed in terms
+ * of 1/4-pel units
+ * pBestCost - Motion cost associated with the best MV; computed as
+ * SAD+Lamda*BitsUsedByMV
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - any of the following pointers are NULL:
+ * pSrcOrgY, pSrcRefY, pRefRect, pMVPred, pMVCandidate, or pMESpec.
+ * - Either iBlockWidth or iBlockHeight are values other than 4, 8, or 16.
+ * - Any alignment restrictions are violated
+ *
+ */
+OMXResult omxVCM4P10_BlockMatch_Integer (
+ const OMX_U8 *pSrcOrgY,
+ OMX_S32 nSrcOrgStep,
+ const OMX_U8 *pSrcRefY,
+ OMX_S32 nSrcRefStep,
+ const OMXRect *pRefRect,
+ const OMXVCM4P2Coordinate *pCurrPointPos,
+ OMX_U8 iBlockWidth,
+ OMX_U8 iBlockHeight,
+ OMX_U32 nLamda,
+ const OMXVCMotionVector *pMVPred,
+ const OMXVCMotionVector *pMVCandidate,
+ OMXVCMotionVector *pBestMV,
+ OMX_S32 *pBestCost,
+ void *pMESpec
+);
+
+
+
+/**
+ * Function: omxVCM4P10_BlockMatch_Half (6.3.5.2.2)
+ *
+ * Description:
+ * Performs a half-pel block match using results from a prior integer search.
+ * Returns the best MV and associated cost. This function estimates the
+ * half-pixel motion vector by interpolating the integer resolution motion
+ * vector referenced by the input parameter pSrcDstBestMV, i.e., the initial
+ * integer MV is generated externally. The function
+ * omxVCM4P10_BlockMatch_Integer may be used for integer motion estimation.
+ *
+ * Input Arguments:
+ *
+ * pSrcOrgY - Pointer to the current position in original picture plane:
+ * If iBlockWidth==4, 4-byte alignment required.
+ * If iBlockWidth==8, 8-byte alignment required.
+ * If iBlockWidth==16, 16-byte alignment required.
+ * pSrcRefY - Pointer to the top-left corner of the co-located block in the
+ * reference picture:
+ * If iBlockWidth==4, 4-byte alignment required.
+ * If iBlockWidth==8, 8-byte alignment required.
+ * If iBlockWidth==16, 16-byte alignment required.
+ * nSrcOrgStep - Stride of the original picture plane in terms of full
+ * pixels; must be a multiple of iBlockWidth.
+ * nSrcRefStep - Stride of the reference picture plane in terms of full
+ * pixels
+ * iBlockWidth - Width of the current block in terms of full pixels; must
+ * be equal to either 4, 8, or 16.
+ * iBlockHeight - Height of the current block in terms of full pixels; must
+ * be equal to either 4, 8, or 16.
+ * nLamda - Lamda factor, used to compute motion cost
+ * pMVPred - Predicted MV, represented in terms of 1/4-pel units; used to
+ * compute motion cost
+ * pSrcDstBestMV - The best MV resulting from a prior integer search,
+ * represented in terms of 1/4-pel units
+ *
+ * Output Arguments:
+ *
+ * pSrcDstBestMV - Best MV resulting from the half-pel search, expressed in
+ * terms of 1/4-pel units
+ * pBestCost - Motion cost associated with the best MV; computed as
+ * SAD+Lamda*BitsUsedByMV
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - any of the following pointers is NULL: pSrcOrgY, pSrcRefY,
+ * pSrcDstBestMV, pMVPred, pBestCost
+ * - iBlockWidth or iBlockHeight are equal to values other than 4, 8, or 16.
+ * - Any alignment restrictions are violated
+ *
+ */
+OMXResult omxVCM4P10_BlockMatch_Half (
+ const OMX_U8 *pSrcOrgY,
+ OMX_S32 nSrcOrgStep,
+ const OMX_U8 *pSrcRefY,
+ OMX_S32 nSrcRefStep,
+ OMX_U8 iBlockWidth,
+ OMX_U8 iBlockHeight,
+ OMX_U32 nLamda,
+ const OMXVCMotionVector *pMVPred,
+ OMXVCMotionVector *pSrcDstBestMV,
+ OMX_S32 *pBestCost
+);
+
+
+
+/**
+ * Function: omxVCM4P10_BlockMatch_Quarter (6.3.5.2.3)
+ *
+ * Description:
+ * Performs a quarter-pel block match using results from a prior half-pel
+ * search. Returns the best MV and associated cost. This function estimates
+ * the quarter-pixel motion vector by interpolating the half-pel resolution
+ * motion vector referenced by the input parameter pSrcDstBestMV, i.e., the
+ * initial half-pel MV is generated externally. The function
+ * omxVCM4P10_BlockMatch_Half may be used for half-pel motion estimation.
+ *
+ * Input Arguments:
+ *
+ * pSrcOrgY - Pointer to the current position in original picture plane:
+ * If iBlockWidth==4, 4-byte alignment required.
+ * If iBlockWidth==8, 8-byte alignment required.
+ * If iBlockWidth==16, 16-byte alignment required.
+ * pSrcRefY - Pointer to the top-left corner of the co-located block in the
+ * reference picture:
+ * If iBlockWidth==4, 4-byte alignment required.
+ * If iBlockWidth==8, 8-byte alignment required.
+ * If iBlockWidth==16, 16-byte alignment required.
+ * nSrcOrgStep - Stride of the original picture plane in terms of full
+ * pixels; must be a multiple of iBlockWidth.
+ * nSrcRefStep - Stride of the reference picture plane in terms of full
+ * pixels
+ * iBlockWidth - Width of the current block in terms of full pixels; must
+ * be equal to either 4, 8, or 16.
+ * iBlockHeight - Height of the current block in terms of full pixels; must
+ * be equal to either 4, 8, or 16.
+ * nLamda - Lamda factor, used to compute motion cost
+ * pMVPred - Predicted MV, represented in terms of 1/4-pel units; used to
+ * compute motion cost
+ * pSrcDstBestMV - The best MV resulting from a prior half-pel search,
+ * represented in terms of 1/4 pel units
+ *
+ * Output Arguments:
+ *
+ * pSrcDstBestMV - Best MV resulting from the quarter-pel search, expressed
+ * in terms of 1/4-pel units
+ * pBestCost - Motion cost associated with the best MV; computed as
+ * SAD+Lamda*BitsUsedByMV
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - One or more of the following pointers is NULL:
+ * pSrcOrgY, pSrcRefY, pSrcDstBestMV, pMVPred, pBestCost
+ * - iBlockWidth or iBlockHeight are equal to values other than 4, 8, or 16.
+ * - Any alignment restrictions are violated
+ *
+ */
+OMXResult omxVCM4P10_BlockMatch_Quarter (
+ const OMX_U8 *pSrcOrgY,
+ OMX_S32 nSrcOrgStep,
+ const OMX_U8 *pSrcRefY,
+ OMX_S32 nSrcRefStep,
+ OMX_U8 iBlockWidth,
+ OMX_U8 iBlockHeight,
+ OMX_U32 nLamda,
+ const OMXVCMotionVector *pMVPred,
+ OMXVCMotionVector *pSrcDstBestMV,
+ OMX_S32 *pBestCost
+);
+
+
+
+/**
+ * Function: omxVCM4P10_MotionEstimationMB (6.3.5.3.1)
+ *
+ * Description:
+ * Performs MB-level motion estimation and selects best motion estimation
+ * strategy from the set of modes supported in baseline profile [ISO14496-10].
+ *
+ * Input Arguments:
+ *
+ * pSrcCurrBuf - Pointer to the current position in original picture plane;
+ * 16-byte alignment required
+ * pSrcRefBufList - Pointer to an array with 16 entries. Each entry points
+ * to the top-left corner of the co-located MB in a reference
+ * picture. The array is filled from low-to-high with valid
+ * reference frame pointers; the unused high entries should be set
+ * to NULL. Ordering of the reference frames should follow
+ * [ISO14496-10] subclause 8.2.4 Decoding Process for Reference
+ * Picture Lists. The entries must be 16-byte aligned.
+ * pSrcRecBuf - Pointer to the top-left corner of the co-located MB in the
+ * reconstructed picture; must be 16-byte aligned.
+ * SrcCurrStep - Width of the original picture plane in terms of full
+ * pixels; must be a multiple of 16.
+ * SrcRefStep - Width of the reference picture plane in terms of full
+ * pixels; must be a multiple of 16.
+ * SrcRecStep - Width of the reconstructed picture plane in terms of full
+ * pixels; must be a multiple of 16.
+ * pRefRect - Pointer to the valid reference rectangle; relative to the
+ * image origin.
+ * pCurrPointPos - Position of the current macroblock in the current plane.
+ * Lambda - Lagrange factor for computing the cost function
+ * pMESpec - Pointer to the motion estimation specification structure; must
+ * have been allocated and initialized prior to calling this
+ * function.
+ * pMBInter - Array, of dimension four, containing pointers to information
+ * associated with four adjacent type INTER MBs (Left, Top,
+ * Top-Left, Top-Right). Any pointer in the array may be set equal
+ * to NULL if the corresponding MB doesn t exist or is not of type
+ * INTER.
+ * - pMBInter[0] - Pointer to left MB information
+ * - pMBInter[1] - Pointer to top MB information
+ * - pMBInter[2] - Pointer to top-left MB information
+ * - pMBInter[3] - Pointer to top-right MB information
+ * pMBIntra - Array, of dimension four, containing pointers to information
+ * associated with four adjacent type INTRA MBs (Left, Top,
+ * Top-Left, Top-Right). Any pointer in the array may be set equal
+ * to NULL if the corresponding MB doesn t exist or is not of type
+ * INTRA.
+ * - pMBIntra[0] - Pointer to left MB information
+ * - pMBIntra[1] - Pointer to top MB information
+ * - pMBIntra[2] - Pointer to top-left MB information
+ * - pMBIntra[3] - Pointer to top-right MB information
+ * pSrcDstMBCurr - Pointer to information structure for the current MB.
+ * The following entries should be set prior to calling the
+ * function: sliceID - the number of the slice the to which the
+ * current MB belongs.
+ *
+ * Output Arguments:
+ *
+ * pDstCost - Pointer to the minimum motion cost for the current MB.
+ * pDstBlockSAD - Pointer to the array of SADs for each of the sixteen luma
+ * 4x4 blocks in each MB. The block SADs are in scan order for
+ * each MB. For implementations that cannot compute the SAD values
+ * individually, the maximum possible value (0xffff) is returned
+ * for each of the 16 block SAD entries.
+ * pSrcDstMBCurr - Pointer to updated information structure for the current
+ * MB after MB-level motion estimation has been completed. The
+ * following fields are updated by the ME function. The following
+ * parameter set quantifies the MB-level ME search results:
+ * - MbType
+ * - subMBType[4]
+ * - pMV0[4][4]
+ * - pMVPred[4][4]
+ * - pRefL0Idx[4]
+ * - Intra16x16PredMode
+ * - pIntra4x4PredMode[4][4]
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - One or more of the following pointers is NULL: pSrcCurrBuf,
+ * pSrcRefBufList, pSrcRecBuf, pRefRect, pCurrPointPos, pMESpec,
+ * pMBInter, pMBIntra,pSrcDstMBCurr, pDstCost, pSrcRefBufList[0]
+ * - SrcRefStep, SrcRecStep are not multiples of 16
+ * - iBlockWidth or iBlockHeight are values other than 4, 8, or 16.
+ * - Any alignment restrictions are violated
+ *
+ */
+OMXResult omxVCM4P10_MotionEstimationMB (
+ const OMX_U8 *pSrcCurrBuf,
+ OMX_S32 SrcCurrStep,
+ const OMX_U8 *pSrcRefBufList[15],
+ OMX_S32 SrcRefStep,
+ const OMX_U8 *pSrcRecBuf,
+ OMX_S32 SrcRecStep,
+ const OMXRect *pRefRect,
+ const OMXVCM4P2Coordinate *pCurrPointPos,
+ OMX_U32 Lambda,
+ void *pMESpec,
+ const OMXVCM4P10MBInfoPtr *pMBInter,
+ const OMXVCM4P10MBInfoPtr *pMBIntra,
+ OMXVCM4P10MBInfoPtr pSrcDstMBCurr,
+ OMX_INT *pDstCost,
+ OMX_U16 *pDstBlockSAD
+);
+
+
+
+/**
+ * Function: omxVCM4P10_SAD_4x (6.3.5.4.1)
+ *
+ * Description:
+ * This function calculates the SAD for 4x8 and 4x4 blocks.
+ *
+ * Input Arguments:
+ *
+ * pSrcOrg -Pointer to the original block; must be aligned on a 4-byte
+ * boundary.
+ * iStepOrg -Step of the original block buffer; must be a multiple of 4.
+ * pSrcRef -Pointer to the reference block
+ * iStepRef -Step of the reference block buffer
+ * iHeight -Height of the block; must be equal to either 4 or 8.
+ *
+ * Output Arguments:
+ *
+ * pDstSAD -Pointer of result SAD
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - One or more of the following pointers is NULL:
+ * pSrcOrg, pSrcRef, or pDstSAD
+ * - iHeight is not equal to either 4 or 8.
+ * - iStepOrg is not a multiple of 4
+ * - Any alignment restrictions are violated
+ *
+ */
+OMXResult omxVCM4P10_SAD_4x (
+ const OMX_U8 *pSrcOrg,
+ OMX_U32 iStepOrg,
+ const OMX_U8 *pSrcRef,
+ OMX_U32 iStepRef,
+ OMX_S32 *pDstSAD,
+ OMX_U32 iHeight
+);
+
+
+
+/**
+ * Function: omxVCM4P10_SADQuar_4x (6.3.5.4.2)
+ *
+ * Description:
+ * This function calculates the SAD between one block (pSrc) and the average
+ * of the other two (pSrcRef0 and pSrcRef1) for 4x8 or 4x4 blocks. Rounding
+ * is applied according to the convention (a+b+1)>>1.
+ *
+ * Input Arguments:
+ *
+ * pSrc - Pointer to the original block; must be aligned on a 4-byte
+ * boundary.
+ * pSrcRef0 - Pointer to reference block 0
+ * pSrcRef1 - Pointer to reference block 1
+ * iSrcStep - Step of the original block buffer; must be a multiple of 4.
+ * iRefStep0 - Step of reference block 0
+ * iRefStep1 - Step of reference block 1
+ * iHeight - Height of the block; must be equal to either 4 or 8.
+ *
+ * Output Arguments:
+ *
+ * pDstSAD - Pointer of result SAD
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - iHeight is not equal to either 4 or 8.
+ * - One or more of the following pointers is NULL: pSrc, pSrcRef0,
+ * pSrcRef1, pDstSAD.
+ * - iSrcStep is not a multiple of 4
+ * - Any alignment restrictions are violated
+ *
+ */
+OMXResult omxVCM4P10_SADQuar_4x (
+ const OMX_U8 *pSrc,
+ const OMX_U8 *pSrcRef0,
+ const OMX_U8 *pSrcRef1,
+ OMX_U32 iSrcStep,
+ OMX_U32 iRefStep0,
+ OMX_U32 iRefStep1,
+ OMX_U32 *pDstSAD,
+ OMX_U32 iHeight
+);
+
+
+
+/**
+ * Function: omxVCM4P10_SADQuar_8x (6.3.5.4.3)
+ *
+ * Description:
+ * This function calculates the SAD between one block (pSrc) and the average
+ * of the other two (pSrcRef0 and pSrcRef1) for 8x16, 8x8, or 8x4 blocks.
+ * Rounding is applied according to the convention (a+b+1)>>1.
+ *
+ * Input Arguments:
+ *
+ * pSrc - Pointer to the original block; must be aligned on an 8-byte
+ * boundary.
+ * pSrcRef0 - Pointer to reference block 0
+ * pSrcRef1 - Pointer to reference block 1
+ * iSrcStep - Step of the original block buffer; must be a multiple of 8.
+ * iRefStep0 - Step of reference block 0
+ * iRefStep1 - Step of reference block 1
+ * iHeight - Height of the block; must be equal either 4, 8, or 16.
+ *
+ * Output Arguments:
+ *
+ * pDstSAD - Pointer of result SAD
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - iHeight is not equal to either 4, 8, or 16.
+ * - One or more of the following pointers is NULL: pSrc, pSrcRef0,
+ * pSrcRef1, pDstSAD.
+ * - iSrcStep is not a multiple of 8
+ * - Any alignment restrictions are violated
+ *
+ */
+OMXResult omxVCM4P10_SADQuar_8x (
+ const OMX_U8 *pSrc,
+ const OMX_U8 *pSrcRef0,
+ const OMX_U8 *pSrcRef1,
+ OMX_U32 iSrcStep,
+ OMX_U32 iRefStep0,
+ OMX_U32 iRefStep1,
+ OMX_U32 *pDstSAD,
+ OMX_U32 iHeight
+);
+
+
+
+/**
+ * Function: omxVCM4P10_SADQuar_16x (6.3.5.4.4)
+ *
+ * Description:
+ * This function calculates the SAD between one block (pSrc) and the average
+ * of the other two (pSrcRef0 and pSrcRef1) for 16x16 or 16x8 blocks.
+ * Rounding is applied according to the convention (a+b+1)>>1.
+ *
+ * Input Arguments:
+ *
+ * pSrc - Pointer to the original block; must be aligned on a 16-byte
+ * boundary.
+ * pSrcRef0 - Pointer to reference block 0
+ * pSrcRef1 - Pointer to reference block 1
+ * iSrcStep - Step of the original block buffer; must be a multiple of 16
+ * iRefStep0 - Step of reference block 0
+ * iRefStep1 - Step of reference block 1
+ * iHeight - Height of the block; must be equal to either 8 or 16
+ *
+ * Output Arguments:
+ *
+ * pDstSAD -Pointer of result SAD
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - iHeight is not equal to either 8 or 16.
+ * - One or more of the following pointers is NULL: pSrc, pSrcRef0,
+ * pSrcRef1, pDstSAD.
+ * - iSrcStep is not a multiple of 16
+ * - Any alignment restrictions are violated
+ *
+ */
+OMXResult omxVCM4P10_SADQuar_16x (
+ const OMX_U8 *pSrc,
+ const OMX_U8 *pSrcRef0,
+ const OMX_U8 *pSrcRef1,
+ OMX_U32 iSrcStep,
+ OMX_U32 iRefStep0,
+ OMX_U32 iRefStep1,
+ OMX_U32 *pDstSAD,
+ OMX_U32 iHeight
+);
+
+
+
+/**
+ * Function: omxVCM4P10_SATD_4x4 (6.3.5.4.5)
+ *
+ * Description:
+ * This function calculates the sum of absolute transform differences (SATD)
+ * for a 4x4 block by applying a Hadamard transform to the difference block
+ * and then calculating the sum of absolute coefficient values.
+ *
+ * Input Arguments:
+ *
+ * pSrcOrg - Pointer to the original block; must be aligned on a 4-byte
+ * boundary
+ * iStepOrg - Step of the original block buffer; must be a multiple of 4
+ * pSrcRef - Pointer to the reference block; must be aligned on a 4-byte
+ * boundary
+ * iStepRef - Step of the reference block buffer; must be a multiple of 4
+ *
+ * Output Arguments:
+ *
+ * pDstSAD - pointer to the resulting SAD
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL:
+ * pSrcOrg, pSrcRef, or pDstSAD either pSrcOrg
+ * - pSrcRef is not aligned on a 4-byte boundary
+ * - iStepOrg <= 0 or iStepOrg is not a multiple of 4
+ * - iStepRef <= 0 or iStepRef is not a multiple of 4
+ *
+ */
+OMXResult omxVCM4P10_SATD_4x4 (
+ const OMX_U8 *pSrcOrg,
+ OMX_U32 iStepOrg,
+ const OMX_U8 *pSrcRef,
+ OMX_U32 iStepRef,
+ OMX_U32 *pDstSAD
+);
+
+
+
+/**
+ * Function: omxVCM4P10_InterpolateHalfHor_Luma (6.3.5.5.1)
+ *
+ * Description:
+ * This function performs interpolation for two horizontal 1/2-pel positions
+ * (-1/2,0) and (1/2, 0) - around a full-pel position.
+ *
+ * Input Arguments:
+ *
+ * pSrc - Pointer to the top-left corner of the block used to interpolate in
+ * the reconstruction frame plane.
+ * iSrcStep - Step of the source buffer.
+ * iDstStep - Step of the destination(interpolation) buffer; must be a
+ * multiple of iWidth.
+ * iWidth - Width of the current block; must be equal to either 4, 8, or 16
+ * iHeight - Height of the current block; must be equal to 4, 8, or 16
+ *
+ * Output Arguments:
+ *
+ * pDstLeft -Pointer to the interpolation buffer of the left -pel position
+ * (-1/2, 0)
+ * If iWidth==4, 4-byte alignment required.
+ * If iWidth==8, 8-byte alignment required.
+ * If iWidth==16, 16-byte alignment required.
+ * pDstRight -Pointer to the interpolation buffer of the right -pel
+ * position (1/2, 0)
+ * If iWidth==4, 4-byte alignment required.
+ * If iWidth==8, 8-byte alignment required.
+ * If iWidth==16, 16-byte alignment required.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL:
+ * pSrc, pDstLeft, or pDstRight
+ * - iWidth or iHeight have values other than 4, 8, or 16
+ * - iWidth==4 but pDstLeft and/or pDstRight is/are not aligned on a 4-byte boundary
+ * - iWidth==8 but pDstLeft and/or pDstRight is/are not aligned on a 8-byte boundary
+ * - iWidth==16 but pDstLeft and/or pDstRight is/are not aligned on a 16-byte boundary
+ * - any alignment restrictions are violated
+ *
+ */
+OMXResult omxVCM4P10_InterpolateHalfHor_Luma (
+ const OMX_U8 *pSrc,
+ OMX_U32 iSrcStep,
+ OMX_U8 *pDstLeft,
+ OMX_U8 *pDstRight,
+ OMX_U32 iDstStep,
+ OMX_U32 iWidth,
+ OMX_U32 iHeight
+);
+
+
+
+/**
+ * Function: omxVCM4P10_InterpolateHalfVer_Luma (6.3.5.5.2)
+ *
+ * Description:
+ * This function performs interpolation for two vertical 1/2-pel positions -
+ * (0, -1/2) and (0, 1/2) - around a full-pel position.
+ *
+ * Input Arguments:
+ *
+ * pSrc - Pointer to top-left corner of block used to interpolate in the
+ * reconstructed frame plane
+ * iSrcStep - Step of the source buffer.
+ * iDstStep - Step of the destination (interpolation) buffer; must be a
+ * multiple of iWidth.
+ * iWidth - Width of the current block; must be equal to either 4, 8, or 16
+ * iHeight - Height of the current block; must be equal to either 4, 8, or 16
+ *
+ * Output Arguments:
+ *
+ * pDstUp -Pointer to the interpolation buffer of the -pel position above
+ * the current full-pel position (0, -1/2)
+ * If iWidth==4, 4-byte alignment required.
+ * If iWidth==8, 8-byte alignment required.
+ * If iWidth==16, 16-byte alignment required.
+ * pDstDown -Pointer to the interpolation buffer of the -pel position below
+ * the current full-pel position (0, 1/2)
+ * If iWidth==4, 4-byte alignment required.
+ * If iWidth==8, 8-byte alignment required.
+ * If iWidth==16, 16-byte alignment required.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL:
+ * pSrc, pDstUp, or pDstDown
+ * - iWidth or iHeight have values other than 4, 8, or 16
+ * - iWidth==4 but pDstUp and/or pDstDown is/are not aligned on a 4-byte boundary
+ * - iWidth==8 but pDstUp and/or pDstDown is/are not aligned on a 8-byte boundary
+ * - iWidth==16 but pDstUp and/or pDstDown is/are not aligned on a 16-byte boundary
+ *
+ */
+OMXResult omxVCM4P10_InterpolateHalfVer_Luma (
+ const OMX_U8 *pSrc,
+ OMX_U32 iSrcStep,
+ OMX_U8 *pDstUp,
+ OMX_U8 *pDstDown,
+ OMX_U32 iDstStep,
+ OMX_U32 iWidth,
+ OMX_U32 iHeight
+);
+
+
+
+/**
+ * Function: omxVCM4P10_Average_4x (6.3.5.5.3)
+ *
+ * Description:
+ * This function calculates the average of two 4x4, 4x8 blocks. The result
+ * is rounded according to (a+b+1)/2.
+ *
+ * Input Arguments:
+ *
+ * pPred0 - Pointer to the top-left corner of reference block 0
+ * pPred1 - Pointer to the top-left corner of reference block 1
+ * iPredStep0 - Step of reference block 0; must be a multiple of 4.
+ * iPredStep1 - Step of reference block 1; must be a multiple of 4.
+ * iDstStep - Step of the destination buffer; must be a multiple of 4.
+ * iHeight - Height of the blocks; must be either 4 or 8.
+ *
+ * Output Arguments:
+ *
+ * pDstPred - Pointer to the destination buffer. 4-byte alignment required.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL:
+ * pPred0, pPred1, or pDstPred
+ * - pDstPred is not aligned on a 4-byte boundary
+ * - iPredStep0 <= 0 or iPredStep0 is not a multiple of 4
+ * - iPredStep1 <= 0 or iPredStep1 is not a multiple of 4
+ * - iDstStep <= 0 or iDstStep is not a multiple of 4
+ * - iHeight is not equal to either 4 or 8
+ *
+ */
+OMXResult omxVCM4P10_Average_4x (
+ const OMX_U8 *pPred0,
+ const OMX_U8 *pPred1,
+ OMX_U32 iPredStep0,
+ OMX_U32 iPredStep1,
+ OMX_U8 *pDstPred,
+ OMX_U32 iDstStep,
+ OMX_U32 iHeight
+);
+
+
+
+/**
+ * Function: omxVCM4P10_TransformQuant_ChromaDC (6.3.5.6.1)
+ *
+ * Description:
+ * This function performs 2x2 Hadamard transform of chroma DC coefficients
+ * and then quantizes the coefficients.
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - Pointer to the 2x2 array of chroma DC coefficients. 8-byte
+ * alignment required.
+ * iQP - Quantization parameter; must be in the range [0,51].
+ * bIntra - Indicate whether this is an INTRA block. 1-INTRA, 0-INTER
+ *
+ * Output Arguments:
+ *
+ * pSrcDst - Pointer to transformed and quantized coefficients. 8-byte
+ * alignment required.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL:
+ * pSrcDst
+ * - pSrcDst is not aligned on an 8-byte boundary
+ *
+ */
+OMXResult omxVCM4P10_TransformQuant_ChromaDC (
+ OMX_S16 *pSrcDst,
+ OMX_U32 iQP,
+ OMX_U8 bIntra
+);
+
+
+
+/**
+ * Function: omxVCM4P10_TransformQuant_LumaDC (6.3.5.6.2)
+ *
+ * Description:
+ * This function performs a 4x4 Hadamard transform of luma DC coefficients
+ * and then quantizes the coefficients.
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - Pointer to the 4x4 array of luma DC coefficients. 16-byte
+ * alignment required.
+ * iQP - Quantization parameter; must be in the range [0,51].
+ *
+ * Output Arguments:
+ *
+ * pSrcDst - Pointer to transformed and quantized coefficients. 16-byte
+ * alignment required.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL: pSrcDst
+ * - pSrcDst is not aligned on an 16-byte boundary
+ *
+ */
+OMXResult omxVCM4P10_TransformQuant_LumaDC (
+ OMX_S16 *pSrcDst,
+ OMX_U32 iQP
+);
+
+
+
+/**
+ * Function: omxVCM4P10_InvTransformDequant_LumaDC (6.3.5.6.3)
+ *
+ * Description:
+ * This function performs inverse 4x4 Hadamard transform and then dequantizes
+ * the coefficients.
+ *
+ * Input Arguments:
+ *
+ * pSrc - Pointer to the 4x4 array of the 4x4 Hadamard-transformed and
+ * quantized coefficients. 16 byte alignment required.
+ * iQP - Quantization parameter; must be in the range [0,51].
+ *
+ * Output Arguments:
+ *
+ * pDst - Pointer to inverse-transformed and dequantized coefficients.
+ * 16-byte alignment required.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL: pSrc
+ * - pSrc or pDst is not aligned on a 16-byte boundary
+ *
+ */
+OMXResult omxVCM4P10_InvTransformDequant_LumaDC (
+ const OMX_S16 *pSrc,
+ OMX_S16 *pDst,
+ OMX_U32 iQP
+);
+
+
+
+/**
+ * Function: omxVCM4P10_InvTransformDequant_ChromaDC (6.3.5.6.4)
+ *
+ * Description:
+ * This function performs inverse 2x2 Hadamard transform and then dequantizes
+ * the coefficients.
+ *
+ * Input Arguments:
+ *
+ * pSrc - Pointer to the 2x2 array of the 2x2 Hadamard-transformed and
+ * quantized coefficients. 8 byte alignment required.
+ * iQP - Quantization parameter; must be in the range [0,51].
+ *
+ * Output Arguments:
+ *
+ * pDst - Pointer to inverse-transformed and dequantized coefficients.
+ * 8-byte alignment required.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL: pSrc
+ * - pSrc or pDst is not aligned on an 8-byte boundary
+ *
+ */
+OMXResult omxVCM4P10_InvTransformDequant_ChromaDC (
+ const OMX_S16 *pSrc,
+ OMX_S16 *pDst,
+ OMX_U32 iQP
+);
+
+
+
+/**
+ * Function: omxVCM4P10_InvTransformResidualAndAdd (6.3.5.7.1)
+ *
+ * Description:
+ * This function performs inverse an 4x4 integer transformation to produce
+ * the difference signal and then adds the difference to the prediction to get
+ * the reconstructed signal.
+ *
+ * Input Arguments:
+ *
+ * pSrcPred - Pointer to prediction signal. 4-byte alignment required.
+ * pDequantCoeff - Pointer to the transformed coefficients. 8-byte
+ * alignment required.
+ * iSrcPredStep - Step of the prediction buffer; must be a multiple of 4.
+ * iDstReconStep - Step of the destination reconstruction buffer; must be a
+ * multiple of 4.
+ * bAC - Indicate whether there is AC coefficients in the coefficients
+ * matrix.
+ *
+ * Output Arguments:
+ *
+ * pDstRecon -Pointer to the destination reconstruction buffer. 4-byte
+ * alignment required.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL:
+ * pSrcPred, pDequantCoeff, pDstRecon
+ * - pSrcPred is not aligned on a 4-byte boundary
+ * - iSrcPredStep or iDstReconStep is not a multiple of 4.
+ * - pDequantCoeff is not aligned on an 8-byte boundary
+ *
+ */
+OMXResult omxVCM4P10_InvTransformResidualAndAdd (
+ const OMX_U8 *pSrcPred,
+ const OMX_S16 *pDequantCoeff,
+ OMX_U8 *pDstRecon,
+ OMX_U32 iSrcPredStep,
+ OMX_U32 iDstReconStep,
+ OMX_U8 bAC
+);
+
+
+
+/**
+ * Function: omxVCM4P10_SubAndTransformQDQResidual (6.3.5.8.1)
+ *
+ * Description:
+ * This function subtracts the prediction signal from the original signal to
+ * produce the difference signal and then performs a 4x4 integer transform and
+ * quantization. The quantized transformed coefficients are stored as
+ * pDstQuantCoeff. This function can also output dequantized coefficients or
+ * unquantized DC coefficients optionally by setting the pointers
+ * pDstDeQuantCoeff, pDCCoeff.
+ *
+ * Input Arguments:
+ *
+ * pSrcOrg - Pointer to original signal. 4-byte alignment required.
+ * pSrcPred - Pointer to prediction signal. 4-byte alignment required.
+ * iSrcOrgStep - Step of the original signal buffer; must be a multiple of
+ * 4.
+ * iSrcPredStep - Step of the prediction signal buffer; must be a multiple
+ * of 4.
+ * pNumCoeff -Number of non-zero coefficients after quantization. If this
+ * parameter is not required, it is set to NULL.
+ * nThreshSAD - Zero-block early detection threshold. If this parameter is
+ * not required, it is set to 0.
+ * iQP - Quantization parameter; must be in the range [0,51].
+ * bIntra - Indicates whether this is an INTRA block, either 1-INTRA or
+ * 0-INTER
+ *
+ * Output Arguments:
+ *
+ * pDstQuantCoeff - Pointer to the quantized transformed coefficients.
+ * 8-byte alignment required.
+ * pDstDeQuantCoeff - Pointer to the dequantized transformed coefficients
+ * if this parameter is not equal to NULL. 8-byte alignment
+ * required.
+ * pDCCoeff - Pointer to the unquantized DC coefficient if this parameter
+ * is not equal to NULL.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL:
+ * pSrcOrg, pSrcPred, pNumCoeff, pDstQuantCoeff,
+ * pDstDeQuantCoeff, pDCCoeff
+ * - pSrcOrg is not aligned on a 4-byte boundary
+ * - pSrcPred is not aligned on a 4-byte boundary
+ * - iSrcOrgStep is not a multiple of 4
+ * - iSrcPredStep is not a multiple of 4
+ * - pDstQuantCoeff or pDstDeQuantCoeff is not aligned on an 8-byte boundary
+ *
+ */
+OMXResult omxVCM4P10_SubAndTransformQDQResidual (
+ const OMX_U8 *pSrcOrg,
+ const OMX_U8 *pSrcPred,
+ OMX_U32 iSrcOrgStep,
+ OMX_U32 iSrcPredStep,
+ OMX_S16 *pDstQuantCoeff,
+ OMX_S16 *pDstDeQuantCoeff,
+ OMX_S16 *pDCCoeff,
+ OMX_S8 *pNumCoeff,
+ OMX_U32 nThreshSAD,
+ OMX_U32 iQP,
+ OMX_U8 bIntra
+);
+
+
+
+/**
+ * Function: omxVCM4P10_GetVLCInfo (6.3.5.9.1)
+ *
+ * Description:
+ * This function extracts run-length encoding (RLE) information from the
+ * coefficient matrix. The results are returned in an OMXVCM4P10VLCInfo
+ * structure.
+ *
+ * Input Arguments:
+ *
+ * pSrcCoeff - pointer to the transform coefficient matrix. 8-byte
+ * alignment required.
+ * pScanMatrix - pointer to the scan order definition matrix. For a luma
+ * block the scan matrix should follow [ISO14496-10] section 8.5.4,
+ * and should contain the values 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13,
+ * 10, 7, 11, 14, 15. For a chroma block, the scan matrix should
+ * contain the values 0, 1, 2, 3.
+ * bAC - indicates presence of a DC coefficient; 0 = DC coefficient
+ * present, 1= DC coefficient absent.
+ * MaxNumCoef - specifies the number of coefficients contained in the
+ * transform coefficient matrix, pSrcCoeff. The value should be 16
+ * for blocks of type LUMADC, LUMAAC, LUMALEVEL, and CHROMAAC. The
+ * value should be 4 for blocks of type CHROMADC.
+ *
+ * Output Arguments:
+ *
+ * pDstVLCInfo - pointer to structure that stores information for
+ * run-length coding.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL:
+ * pSrcCoeff, pScanMatrix, pDstVLCInfo
+ * - pSrcCoeff is not aligned on an 8-byte boundary
+ *
+ */
+OMXResult omxVCM4P10_GetVLCInfo (
+ const OMX_S16 *pSrcCoeff,
+ const OMX_U8 *pScanMatrix,
+ OMX_U8 bAC,
+ OMX_U32 MaxNumCoef,
+ OMXVCM4P10VLCInfo*pDstVLCInfo
+);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /** end of #define _OMXVC_H_ */
+
+/** EOF */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/api/omxVC_s.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/api/omxVC_s.h
new file mode 100755
index 0000000..89f3040
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/api/omxVC_s.h
@@ -0,0 +1,129 @@
+;/******************************************************************************
+;// Copyright (c) 1999-2005 The Khronos Group Inc. All Rights Reserved
+;//
+;//
+;//
+;//
+;//
+;//
+;//
+;//
+;******************************************************************************/
+
+;/** =============== Structure Definition for Sample Generation ============== */
+;/** transparent status */
+
+;enum {
+OMX_VIDEO_TRANSPARENT EQU 0; /** Wholly transparent */
+OMX_VIDEO_PARTIAL EQU 1; /** Partially transparent */
+OMX_VIDEO_OPAQUE EQU 2; /** Opaque */
+;}
+
+;/** direction */
+;enum {
+OMX_VIDEO_NONE EQU 0;
+OMX_VIDEO_HORIZONTAL EQU 1;
+OMX_VIDEO_VERTICAL EQU 2;
+;}
+
+;/** bilinear interpolation type */
+;enum {
+OMX_VIDEO_INTEGER_PIXEL EQU 0; /** case a */
+OMX_VIDEO_HALF_PIXEL_X EQU 1; /** case b */
+OMX_VIDEO_HALF_PIXEL_Y EQU 2; /** case c */
+OMX_VIDEO_HALF_PIXEL_XY EQU 3; /** case d */
+;}
+
+;enum {
+OMX_UPPER EQU 1; /** set if the above macroblock is available */
+OMX_LEFT EQU 2; /** set if the left macroblock is available */
+OMX_CENTER EQU 4;
+OMX_RIGHT EQU 8;
+OMX_LOWER EQU 16;
+OMX_UPPER_LEFT EQU 32; /** set if the above-left macroblock is available */
+OMX_UPPER_RIGHT EQU 64; /** set if the above-right macroblock is available */
+OMX_LOWER_LEFT EQU 128;
+OMX_LOWER_RIGHT EQU 256
+;}
+
+;enum {
+OMX_VIDEO_LUMINANCE EQU 0; /** Luminance component */
+OMX_VIDEO_CHROMINANCE EQU 1; /** chrominance component */
+OMX_VIDEO_ALPHA EQU 2; /** Alpha component */
+;}
+
+;enum {
+OMX_VIDEO_INTER EQU 0; /** P picture or P-VOP */
+OMX_VIDEO_INTER_Q EQU 1; /** P picture or P-VOP */
+OMX_VIDEO_INTER4V EQU 2; /** P picture or P-VOP */
+OMX_VIDEO_INTRA EQU 3; /** I and P picture; I- and P-VOP */
+OMX_VIDEO_INTRA_Q EQU 4; /** I and P picture; I- and P-VOP */
+OMX_VIDEO_INTER4V_Q EQU 5; /** P picture or P-VOP (H.263)*/
+OMX_VIDEO_DIRECT EQU 6; /** B picture or B-VOP (MPEG-4 only) */
+OMX_VIDEO_INTERPOLATE EQU 7; /** B picture or B-VOP */
+OMX_VIDEO_BACKWARD EQU 8; /** B picture or B-VOP */
+OMX_VIDEO_FORWARD EQU 9; /** B picture or B-VOP */
+OMX_VIDEO_NOTCODED EQU 10; /** B picture or B-VOP */
+;}
+
+;enum {
+OMX_16X16_VERT EQU 0; /** Intra_16x16_Vertical (prediction mode) */
+OMX_16X16_HOR EQU 1; /** Intra_16x16_Horizontal (prediction mode) */
+OMX_16X16_DC EQU 2; /** Intra_16x16_DC (prediction mode) */
+OMX_16X16_PLANE EQU 3; /** Intra_16x16_Plane (prediction mode) */
+;}
+
+;enum {
+OMX_4x4_VERT EQU 0; /** Intra_4x4_Vertical (prediction mode) */
+OMX_4x4_HOR EQU 1; /** Intra_4x4_Horizontal (prediction mode) */
+OMX_4x4_DC EQU 2; /** Intra_4x4_DC (prediction mode) */
+OMX_4x4_DIAG_DL EQU 3; /** Intra_4x4_Diagonal_Down_Left (prediction mode) */
+OMX_4x4_DIAG_DR EQU 4; /** Intra_4x4_Diagonal_Down_Right (prediction mode) */
+OMX_4x4_VR EQU 5; /** Intra_4x4_Vertical_Right (prediction mode) */
+OMX_4x4_HD EQU 6; /** Intra_4x4_Horizontal_Down (prediction mode) */
+OMX_4x4_VL EQU 7; /** Intra_4x4_Vertical_Left (prediction mode) */
+OMX_4x4_HU EQU 8; /** Intra_4x4_Horizontal_Up (prediction mode) */
+;}
+
+;enum {
+OMX_CHROMA_DC EQU 0; /** Intra_Chroma_DC (prediction mode) */
+OMX_CHROMA_HOR EQU 1; /** Intra_Chroma_Horizontal (prediction mode) */
+OMX_CHROMA_VERT EQU 2; /** Intra_Chroma_Vertical (prediction mode) */
+OMX_CHROMA_PLANE EQU 3; /** Intra_Chroma_Plane (prediction mode) */
+;}
+
+;typedef struct {
+x EQU 0;
+y EQU 4;
+;}OMXCoordinate;
+
+;typedef struct {
+dx EQU 0;
+dy EQU 2;
+;}OMXMotionVector;
+
+;typedef struct {
+xx EQU 0;
+yy EQU 4;
+width EQU 8;
+height EQU 12;
+;}OMXiRect;
+
+;typedef enum {
+OMX_VC_INTER EQU 0; /** P picture or P-VOP */
+OMX_VC_INTER_Q EQU 1; /** P picture or P-VOP */
+OMX_VC_INTER4V EQU 2; /** P picture or P-VOP */
+OMX_VC_INTRA EQU 3; /** I and P picture, I- and P-VOP */
+OMX_VC_INTRA_Q EQU 4; /** I and P picture, I- and P-VOP */
+OMX_VC_INTER4V_Q EQU 5; /** P picture or P-VOP (H.263)*/
+;} OMXVCM4P2MacroblockType;
+
+;enum {
+OMX_VC_NONE EQU 0
+OMX_VC_HORIZONTAL EQU 1
+OMX_VC_VERTICAL EQU 2
+;};
+
+
+ END
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/comm/src/omxVCCOMM_Copy16x16_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/comm/src/omxVCCOMM_Copy16x16_s.s
new file mode 100755
index 0000000..296d59d
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/comm/src/omxVCCOMM_Copy16x16_s.s
@@ -0,0 +1,95 @@
+ ;/**
+ ; * Function: omxVCCOMM_Copy16x16
+ ; *
+ ; * Description:
+ ; * Copies the reference 16x16 block to the current block.
+ ; * Parameters:
+ ; * [in] pSrc - pointer to the reference block in the source frame; must be aligned on an 16-byte boundary.
+ ; * [in] step - distance between the starts of consecutive lines in the reference frame, in bytes;
+ ; * must be a multiple of 16 and must be larger than or equal to 16.
+ ; * [out] pDst - pointer to the destination block; must be aligned on an 8-byte boundary.
+ ; * Return Value:
+ ; * OMX_Sts_NoErr - no error
+ ; * OMX_Sts_BadArgErr - bad arguments; returned under any of the following conditions:
+ ; * - one or more of the following pointers is NULL: pSrc, pDst
+ ; * - one or more of the following pointers is not aligned on an 16-byte boundary: pSrc, pDst
+ ; * - step <16 or step is not a multiple of 16.
+ ; */
+
+ INCLUDE omxtypes_s.h
+
+
+ M_VARIANTS CortexA8
+
+ IF CortexA8
+
+
+ ;//Input Arguments
+pSrc RN 0
+pDst RN 1
+step RN 2
+
+;//Local Variables
+Return RN 0
+;// Neon Registers
+
+X0 DN D0.S8
+X1 DN D1.S8
+X2 DN D2.S8
+X3 DN D3.S8
+X4 DN D4.S8
+X5 DN D5.S8
+X6 DN D6.S8
+X7 DN D7.S8
+
+ M_START omxVCCOMM_Copy16x16
+
+
+ VLD1 {X0,X1},[pSrc@128],step ;// Load 16 bytes from 16 byte aligned pSrc and pSrc=pSrc + step after loading
+ VLD1 {X2,X3},[pSrc@128],step
+ VLD1 {X4,X5},[pSrc@128],step
+ VLD1 {X6,X7},[pSrc@128],step
+
+ VST1 {X0,X1,X2,X3},[pDst@128]! ;// Store 32 bytes to 16 byte aligned pDst
+ VST1 {X4,X5,X6,X7},[pDst@128]!
+
+
+ VLD1 {X0,X1},[pSrc@128],step
+ VLD1 {X2,X3},[pSrc@128],step
+ VLD1 {X4,X5},[pSrc@128],step
+ VLD1 {X6,X7},[pSrc@128],step
+
+ VST1 {X0,X1,X2,X3},[pDst@128]!
+ VST1 {X4,X5,X6,X7},[pDst@128]!
+
+
+ VLD1 {X0,X1},[pSrc@128],step
+ VLD1 {X2,X3},[pSrc@128],step
+ VLD1 {X4,X5},[pSrc@128],step
+ VLD1 {X6,X7},[pSrc@128],step
+
+ VST1 {X0,X1,X2,X3},[pDst@128]!
+ VST1 {X4,X5,X6,X7},[pDst@128]!
+
+
+ VLD1 {X0,X1},[pSrc@128],step
+ VLD1 {X2,X3},[pSrc@128],step
+ VLD1 {X4,X5},[pSrc@128],step
+ VLD1 {X6,X7},[pSrc@128],step
+
+ VST1 {X0,X1,X2,X3},[pDst@128]!
+ VST1 {X4,X5,X6,X7},[pDst@128]!
+
+
+ MOV Return,#OMX_Sts_NoErr
+
+
+
+ M_END
+ ENDIF
+
+
+
+
+ END
+
\ No newline at end of file
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/comm/src/omxVCCOMM_Copy8x8_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/comm/src/omxVCCOMM_Copy8x8_s.s
new file mode 100755
index 0000000..db9e5ef
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/comm/src/omxVCCOMM_Copy8x8_s.s
@@ -0,0 +1,70 @@
+ ;/**
+ ; * Function: omxVCCOMM_Copy8x8
+ ; *
+ ; * Description:
+ ; * Copies the reference 8x8 block to the current block.
+ ; * Parameters:
+ ; * [in] pSrc - pointer to the reference block in the source frame; must be aligned on an 8-byte boundary.
+ ; * [in] step - distance between the starts of consecutive lines in the reference frame, in bytes;
+ ; * must be a multiple of 8 and must be larger than or equal to 8.
+ ; * [out] pDst - pointer to the destination block; must be aligned on an 8-byte boundary.
+ ; * Return Value:
+ ; * OMX_Sts_NoErr - no error
+ ; * OMX_Sts_BadArgErr - bad arguments; returned under any of the following conditions:
+ ; * - one or more of the following pointers is NULL: pSrc, pDst
+ ; * - one or more of the following pointers is not aligned on an 8-byte boundary: pSrc, pDst
+ ; * - step <8 or step is not a multiple of 8.
+ ; */
+
+ INCLUDE omxtypes_s.h
+
+
+ M_VARIANTS CortexA8
+
+ IF CortexA8
+
+
+ ;//Input Arguments
+pSrc RN 0
+pDst RN 1
+step RN 2
+
+;//Local Variables
+Count RN 3
+Return RN 0
+;// Neon Registers
+
+X0 DN D0.S8
+X1 DN D1.S8
+X2 DN D2.S8
+X3 DN D3.S8
+ M_START omxVCCOMM_Copy8x8
+
+
+
+ VLD1 {X0},[pSrc],step ;// Load 8 bytes from 8 byte aligned pSrc, pSrc=pSrc+step after load
+ VLD1 {X1},[pSrc],step
+ VLD1 {X2},[pSrc],step
+ VLD1 {X3},[pSrc],step
+
+ VST1 {X0,X1},[pDst]! ;// Store 16 bytes to 8 byte aligned pDst
+ VST1 {X2,X3},[pDst]!
+
+ VLD1 {X0},[pSrc],step
+ VLD1 {X1},[pSrc],step
+ VLD1 {X2},[pSrc],step
+ VLD1 {X3},[pSrc],step
+
+ VST1 {X0,X1},[pDst]!
+ VST1 {X2,X3},[pDst]!
+
+ MOV Return,#OMX_Sts_NoErr
+
+ M_END
+ ENDIF
+
+
+
+
+ END
+
\ No newline at end of file
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/comm/src/omxVCCOMM_ExpandFrame_I_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/comm/src/omxVCCOMM_ExpandFrame_I_s.s
new file mode 100755
index 0000000..5c5b7d8
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/comm/src/omxVCCOMM_ExpandFrame_I_s.s
@@ -0,0 +1,236 @@
+;//
+;//
+;// File Name: omxVCCOMM_ExpandFrame_I_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 12290
+;// Date: Wednesday, April 9, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+;// Description:
+;// This function will Expand Frame boundary pixels into Plane
+;//
+;//
+
+;// Include standard headers
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS CortexA8
+
+;// Import symbols required from other files
+;// (For example tables)
+
+
+;// Set debugging level
+DEBUG_ON SETL {FALSE}
+
+
+
+ IF CortexA8
+
+ M_START omxVCCOMM_ExpandFrame_I,r11
+
+;//Input registers
+
+pSrcDstPlane RN 0
+iFrameWidth RN 1
+iFrameHeight RN 2
+iExpandPels RN 3
+iPlaneStep RN 4
+pTop RN 5
+pBot RN 6
+pDstTop RN 7
+pDstBot RN 8
+pLeft RN 5
+pRight RN 6
+pDstLeft RN 9
+pDstRight RN 10
+Offset RN 11
+Temp RN 14
+Counter RN 12
+Tmp RN 7
+;//Output registers
+
+result RN 0
+;// Neon registers
+qData0 QN 0.U8
+qData1 QN 1.U8
+dData0 DN 0.U8
+dData1 DN 1.U8
+dData2 DN 2.U8
+dData3 DN 3.U8
+
+ ;// Define stack arguments
+ M_ARG pPlaneStep, 4
+
+ ;// Load argument from the stack
+ M_LDR iPlaneStep, pPlaneStep
+
+ SUB pTop, pSrcDstPlane, #0 ;// Top row pointer of the frame
+ MUL Offset, iExpandPels, iPlaneStep ;// E*Step
+ SUB Temp, iFrameHeight, #1 ;// H-1
+ MUL Temp, iPlaneStep, Temp ;// (H-1)*Step
+ ADD pBot, Temp, pSrcDstPlane ;// BPtr = TPtr + (H-1)*Step
+ MOV Temp, iFrameWidth ;// Outer loop counter
+
+ ;// Check if pSrcDstPlane and iPlaneStep are 16 byte aligned
+ TST pSrcDstPlane, #0xf
+ TSTEQ iPlaneStep, #0xf
+ BNE Hor8Loop00
+
+ ;//
+ ;// Copy top and bottom region of the plane as follows
+ ;// top region = top row elements from the frame
+ ;// bottom region = last row elements from the frame
+ ;//
+
+ ;// Case for 16 byte alignment
+Hor16Loop00
+ SUB pDstTop, pTop, Offset
+ VLD1 qData0, [pTop @128]!
+ MOV Counter, iExpandPels ;// Inner loop counter
+ ADD pDstBot, pBot, iPlaneStep
+ VLD1 qData1, [pBot @128]!
+Ver16Loop0
+ VST1 qData0, [pDstTop @128], iPlaneStep
+ VST1 qData0, [pDstTop @128], iPlaneStep
+ VST1 qData0, [pDstTop @128], iPlaneStep
+ VST1 qData0, [pDstTop @128], iPlaneStep
+ VST1 qData0, [pDstTop @128], iPlaneStep
+ VST1 qData0, [pDstTop @128], iPlaneStep
+ VST1 qData0, [pDstTop @128], iPlaneStep
+ VST1 qData0, [pDstTop @128], iPlaneStep
+ SUBS Counter, Counter, #8
+ VST1 qData1, [pDstBot @128], iPlaneStep
+ VST1 qData1, [pDstBot @128], iPlaneStep
+ VST1 qData1, [pDstBot @128], iPlaneStep
+ VST1 qData1, [pDstBot @128], iPlaneStep
+ VST1 qData1, [pDstBot @128], iPlaneStep
+ VST1 qData1, [pDstBot @128], iPlaneStep
+ VST1 qData1, [pDstBot @128], iPlaneStep
+ VST1 qData1, [pDstBot @128], iPlaneStep
+ BGT Ver16Loop0
+
+ SUBS Temp, Temp, #16
+ BGT Hor16Loop00
+ B EndAlignedLoop
+
+ ;// Case for 8 byte alignment
+Hor8Loop00
+ SUB pDstTop, pTop, Offset
+ VLD1 qData0, [pTop @64]!
+ MOV Counter, iExpandPels ;// Inner loop counter
+ ADD pDstBot, pBot, iPlaneStep
+ VLD1 qData1, [pBot @64]!
+Ver8Loop0
+ VST1 qData0, [pDstTop @64], iPlaneStep
+ VST1 qData0, [pDstTop @64], iPlaneStep
+ VST1 qData0, [pDstTop @64], iPlaneStep
+ VST1 qData0, [pDstTop @64], iPlaneStep
+ VST1 qData0, [pDstTop @64], iPlaneStep
+ VST1 qData0, [pDstTop @64], iPlaneStep
+ VST1 qData0, [pDstTop @64], iPlaneStep
+ VST1 qData0, [pDstTop @64], iPlaneStep
+ SUBS Counter, Counter, #8
+ VST1 qData1, [pDstBot @64], iPlaneStep
+ VST1 qData1, [pDstBot @64], iPlaneStep
+ VST1 qData1, [pDstBot @64], iPlaneStep
+ VST1 qData1, [pDstBot @64], iPlaneStep
+ VST1 qData1, [pDstBot @64], iPlaneStep
+ VST1 qData1, [pDstBot @64], iPlaneStep
+ VST1 qData1, [pDstBot @64], iPlaneStep
+ VST1 qData1, [pDstBot @64], iPlaneStep
+ BGT Ver8Loop0
+
+ SUBS Temp, Temp, #16
+ BGT Hor8Loop00
+
+EndAlignedLoop
+ ADD Temp, pSrcDstPlane, iFrameWidth
+ SUB pDstRight, Temp, Offset
+ SUB pRight, Temp, #1
+ SUB pDstLeft, pSrcDstPlane, Offset
+ SUB pDstLeft, pDstLeft, iExpandPels
+ ADD pLeft, pSrcDstPlane, #0
+
+ VLD1 {dData0 []}, [pLeft], iPlaneStep ;// Top-Left corner pixel from frame duplicated in dData0
+ SUB Offset, iPlaneStep, iExpandPels
+ VLD1 {dData1 []}, [pRight], iPlaneStep ;// Top-Right corner pixel from frame duplicated in dData1
+ MOV Temp, iExpandPels
+
+ ;//
+ ;// Copy top-left and top-right region of the plane as follows
+ ;// top-left region = top-left corner pixel from the frame
+ ;// top-right region = top-right corner pixel from the frame
+ ;//
+HorLoop11
+ MOV Counter, iExpandPels
+VerLoop1
+ VST1 dData0, [pDstLeft], #8
+ SUBS Counter, Counter, #8
+ VST1 dData1, [pDstRight], #8
+ BGT VerLoop1
+
+ SUBS Temp, Temp, #1
+ ADD pDstLeft, pDstLeft, Offset
+ ADD pDstRight, pDstRight, Offset
+ BPL HorLoop11
+
+ SUB iFrameHeight, iFrameHeight, #1
+ ;//
+ ;// Copy left and right region of the plane as follows
+ ;// Left region = copy the row with left start pixel from the frame
+ ;// Right region = copy the row with right end pixel from the frame
+ ;//
+HorLoop22
+ VLD1 {dData0 []}, [pLeft], iPlaneStep
+ MOV Counter, iExpandPels
+ VLD1 {dData1 []}, [pRight], iPlaneStep
+VerLoop2
+ VST1 dData0, [pDstLeft], #8
+ SUBS Counter, Counter, #8
+ VST1 dData1, [pDstRight], #8
+ BGT VerLoop2
+
+ SUBS iFrameHeight, iFrameHeight, #1
+ ADD pDstLeft, pDstLeft, Offset
+ ADD pDstRight, pDstRight, Offset
+ BGT HorLoop22
+
+ MOV Temp, iExpandPels
+ ;//
+ ;// Copy bottom-left and bottom-right region of the plane as follows
+ ;// bottom-left region = bottom-left corner pixel from the frame
+ ;// bottom-right region = bottom-right corner pixel from the frame
+ ;//
+HorLoop33
+ MOV Counter, iExpandPels
+VerLoop3
+ VST1 dData0, [pDstLeft], #8
+ SUBS Counter, Counter, #8
+ VST1 dData1, [pDstRight], #8
+ BGT VerLoop3
+
+ SUBS Temp, Temp, #1
+ ADD pDstLeft, pDstLeft, Offset
+ ADD pDstRight, pDstRight, Offset
+ BGT HorLoop33
+End
+ MOV r0, #OMX_Sts_NoErr
+
+ M_END
+
+ ENDIF
+
+
+
+
+;// Guarding implementation by the processor name
+
+
+
+ END
\ No newline at end of file
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/api/armVCM4P10_CAVLCTables.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/api/armVCM4P10_CAVLCTables.h
new file mode 100755
index 0000000..547a2d9
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/api/armVCM4P10_CAVLCTables.h
@@ -0,0 +1,30 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: armVCM4P10_CAVLCTables.h
+ * OpenMAX DL: v1.0.2
+ * Revision: 12290
+ * Date: Wednesday, April 9, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Header file for optimized H.264 CALVC tables
+ *
+ */
+
+#ifndef ARMVCM4P10_CAVLCTABLES_H
+#define ARMVCM4P10_CAVLCTABLES_H
+
+/* CAVLC tables */
+
+extern const OMX_U16 *armVCM4P10_CAVLCCoeffTokenTables[18];
+extern const OMX_U16 *armVCM4P10_CAVLCTotalZeroTables[15];
+extern const OMX_U16 *armVCM4P10_CAVLCTotalZeros2x2Tables[3];
+extern const OMX_U16 *armVCM4P10_CAVLCRunBeforeTables[15];
+extern const OMX_U8 armVCM4P10_ZigZag_4x4[16];
+extern const OMX_U8 armVCM4P10_ZigZag_2x2[4];
+extern const OMX_S8 armVCM4P10_SuffixToLevel[7];
+
+#endif
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_Average_4x_Align_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_Average_4x_Align_unsafe_s.s
new file mode 100755
index 0000000..4f0892d
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_Average_4x_Align_unsafe_s.s
@@ -0,0 +1,222 @@
+;//
+;//
+;// File Name: armVCM4P10_Average_4x_Align_unsafe_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 12290
+;// Date: Wednesday, April 9, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+
+;// Functions:
+;// armVCM4P10_Average_4x4_Align<ALIGNMENT>_unsafe
+;//
+;// Implements Average of 4x4 with equation c = (a+b+1)>>1.
+;// First operand will be at offset ALIGNMENT from aligned address
+;// Second operand will be at aligned location and will be used as output.
+;// destination pointed by (pDst) for vertical interpolation.
+;// This function needs to copy 4 bytes in horizontal direction
+;//
+;// Registers used as input for this function
+;// r0,r1,r2,r3 where r2 containings aligned memory pointer and r3 step size
+;//
+;// Registers preserved for top level function
+;// r4,r5,r6,r8,r9,r14
+;//
+;// Registers modified by the function
+;// r7,r10,r11,r12
+;//
+;// Output registers
+;// r2 - pointer to the aligned location
+;// r3 - step size to this aligned location
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS ARM1136JS
+
+ EXPORT armVCM4P10_Average_4x4_Align0_unsafe
+ EXPORT armVCM4P10_Average_4x4_Align2_unsafe
+ EXPORT armVCM4P10_Average_4x4_Align3_unsafe
+
+DEBUG_ON SETL {FALSE}
+
+;// Declare input registers
+pPred0 RN 0
+iPredStep0 RN 1
+pPred1 RN 2
+iPredStep1 RN 3
+pDstPred RN 2
+iDstStep RN 3
+
+;// Declare other intermediate registers
+iPredA0 RN 10
+iPredA1 RN 11
+iPredB0 RN 12
+iPredB1 RN 14
+Temp1 RN 4
+Temp2 RN 5
+ResultA RN 5
+ResultB RN 4
+r0x80808080 RN 7
+
+ IF ARM1136JS
+
+ ;// This function calculates average of 4x4 block
+ ;// pPred0 is at alignment offset 0 and pPred1 is alignment 4
+
+ ;// Function header
+ M_START armVCM4P10_Average_4x4_Align0_unsafe, r6
+
+ ;// Code start
+ LDR r0x80808080, =0x80808080
+
+ ;// 1st load
+ M_LDR iPredB0, [pPred1]
+ M_LDR iPredA0, [pPred0], iPredStep0
+ M_LDR iPredB1, [pPred1, iPredStep1]
+ M_LDR iPredA1, [pPred0], iPredStep0
+
+ ;// (a+b+1)/2 = (a+256-(255-b))/2 = (a-(255-b))/2 + 128
+ MVN iPredB0, iPredB0
+ MVN iPredB1, iPredB1
+ UHSUB8 ResultA, iPredA0, iPredB0
+ UHSUB8 ResultB, iPredA1, iPredB1
+ EOR ResultA, ResultA, r0x80808080
+ M_STR ResultA, [pDstPred], iDstStep
+ EOR ResultB, ResultB, r0x80808080
+ M_STR ResultB, [pDstPred], iDstStep
+
+ ;// 2nd load
+ M_LDR iPredA0, [pPred0], iPredStep0
+ M_LDR iPredB0, [pPred1]
+ M_LDR iPredA1, [pPred0], iPredStep0
+ M_LDR iPredB1, [pPred1, iPredStep1]
+
+ MVN iPredB0, iPredB0
+ UHSUB8 ResultA, iPredA0, iPredB0
+ MVN iPredB1, iPredB1
+ UHSUB8 ResultB, iPredA1, iPredB1
+ EOR ResultA, ResultA, r0x80808080
+ M_STR ResultA, [pDstPred], iDstStep
+ EOR ResultB, ResultB, r0x80808080
+ M_STR ResultB, [pDstPred], iDstStep
+End0
+ M_END
+
+ ;// This function calculates average of 4x4 block
+ ;// pPred0 is at alignment offset 2 and pPred1 is alignment 4
+
+ ;// Function header
+ M_START armVCM4P10_Average_4x4_Align2_unsafe, r6
+
+ ;// Code start
+ LDR r0x80808080, =0x80808080
+
+ ;// 1st load
+ LDR Temp1, [pPred0, #4]
+ M_LDR iPredA0, [pPred0], iPredStep0
+ M_LDR iPredB0, [pPred1]
+ M_LDR iPredB1, [pPred1, iPredStep1]
+ M_LDR Temp2, [pPred0, #4]
+ M_LDR iPredA1, [pPred0], iPredStep0
+ MVN iPredB0, iPredB0
+ MVN iPredB1, iPredB1
+ MOV iPredA0, iPredA0, LSR #16
+ ORR iPredA0, iPredA0, Temp1, LSL #16
+ MOV iPredA1, iPredA1, LSR #16
+ ORR iPredA1, iPredA1, Temp2, LSL #16
+
+ ;// (a+b+1)/2 = (a+256-(255-b))/2 = (a-(255-b))/2 + 128
+ UHSUB8 ResultA, iPredA0, iPredB0
+ UHSUB8 ResultB, iPredA1, iPredB1
+ EOR ResultA, ResultA, r0x80808080
+ M_STR ResultA, [pDstPred], iDstStep
+ EOR ResultB, ResultB, r0x80808080
+ M_STR ResultB, [pDstPred], iDstStep
+
+ ;// 2nd load
+ LDR Temp1, [pPred0, #4]
+ M_LDR iPredA0, [pPred0], iPredStep0
+ LDR iPredB0, [pPred1]
+ LDR iPredB1, [pPred1, iPredStep1]
+ LDR Temp2, [pPred0, #4]
+ M_LDR iPredA1, [pPred0], iPredStep0
+ MVN iPredB0, iPredB0
+ MVN iPredB1, iPredB1
+ MOV iPredA0, iPredA0, LSR #16
+ ORR iPredA0, iPredA0, Temp1, LSL #16
+ MOV iPredA1, iPredA1, LSR #16
+ ORR iPredA1, iPredA1, Temp2, LSL #16
+
+ UHSUB8 ResultA, iPredA0, iPredB0
+ UHSUB8 ResultB, iPredA1, iPredB1
+ EOR ResultA, ResultA, r0x80808080
+ M_STR ResultA, [pDstPred], iDstStep
+ EOR ResultB, ResultB, r0x80808080
+ M_STR ResultB, [pDstPred], iDstStep
+End2
+ M_END
+
+
+ ;// This function calculates average of 4x4 block
+ ;// pPred0 is at alignment offset 3 and pPred1 is alignment 4
+
+ ;// Function header
+ M_START armVCM4P10_Average_4x4_Align3_unsafe, r6
+
+ ;// Code start
+ LDR r0x80808080, =0x80808080
+
+ ;// 1st load
+ LDR Temp1, [pPred0, #4]
+ M_LDR iPredA0, [pPred0], iPredStep0
+ LDR iPredB0, [pPred1]
+ LDR iPredB1, [pPred1, iPredStep1]
+ LDR Temp2, [pPred0, #4]
+ M_LDR iPredA1, [pPred0], iPredStep0
+
+ MVN iPredB0, iPredB0
+ MVN iPredB1, iPredB1
+ MOV iPredA0, iPredA0, LSR #24
+ ORR iPredA0, iPredA0, Temp1, LSL #8
+ MOV iPredA1, iPredA1, LSR #24
+ ORR iPredA1, iPredA1, Temp2, LSL #8
+ UHSUB8 ResultA, iPredA0, iPredB0
+ UHSUB8 ResultB, iPredA1, iPredB1
+ EOR ResultA, ResultA, r0x80808080
+ M_STR ResultA, [pDstPred], iDstStep
+ EOR ResultB, ResultB, r0x80808080
+ M_STR ResultB, [pDstPred], iDstStep
+
+ ;// 2nd load
+ LDR Temp1, [pPred0, #4]
+ M_LDR iPredA0, [pPred0], iPredStep0
+ LDR iPredB0, [pPred1]
+ LDR iPredB1, [pPred1, iPredStep1]
+ LDR Temp2, [pPred0, #4]
+ M_LDR iPredA1, [pPred0], iPredStep0
+
+ MVN iPredB0, iPredB0
+ MVN iPredB1, iPredB1
+ MOV iPredA0, iPredA0, LSR #24
+ ORR iPredA0, iPredA0, Temp1, LSL #8
+ MOV iPredA1, iPredA1, LSR #24
+ ORR iPredA1, iPredA1, Temp2, LSL #8
+
+ UHSUB8 ResultA, iPredA0, iPredB0
+ UHSUB8 ResultB, iPredA1, iPredB1
+ EOR ResultA, ResultA, r0x80808080
+ M_STR ResultA, [pDstPred], iDstStep
+ EOR ResultB, ResultB, r0x80808080
+ M_STR ResultB, [pDstPred], iDstStep
+End3
+ M_END
+
+ ENDIF
+
+ END
+
\ No newline at end of file
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_CAVLCTables.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_CAVLCTables.c
new file mode 100755
index 0000000..137495d
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_CAVLCTables.c
@@ -0,0 +1,327 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: armVCM4P10_CAVLCTables.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 12290
+ * Date: Wednesday, April 9, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Optimized CAVLC tables for H.264
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+
+#include "armVCM4P10_CAVLCTables.h"
+
+/* 4x4 DeZigZag table */
+
+const OMX_U8 armVCM4P10_ZigZag_4x4[16] =
+{
+ 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15
+};
+
+/* 2x2 DeZigZag table */
+
+const OMX_U8 armVCM4P10_ZigZag_2x2[4] =
+{
+ 0, 1, 2, 3
+};
+
+
+/*
+ * Suffix To Level table
+ * We increment the suffix length if
+ * ((LevelCode>>1)+1)>(3<<(SuffixLength-1)) && SuffixLength<6
+ * (LevelCode>>1)>=(3<<(SuffixLength-1)) && SuffixLength<6
+ * LevelCode >= 3<<SuffixLength && SuffixLength<6
+ * (LevelCode+2) >= (3<<SuffixLength)+2 && SuffixLength<6
+ */
+const OMX_S8 armVCM4P10_SuffixToLevel[7] =
+{
+ (3<<1)+2, /* SuffixLength=1 */
+ (3<<1)+2, /* SuffixLength=1 */
+ (3<<2)+2, /* SuffixLength=2 */
+ (3<<3)+2, /* SuffixLength=3 */
+ (3<<4)+2, /* SuffixLength=4 */
+ (3<<5)+2, /* SuffixLength=5 */
+ -1 /* SuffixLength=6 - never increment */
+};
+
+static const OMX_U16 armVCM4P10_CAVLCCoeffTokenTables_0[132] = {
+ 0x0020, 0x0100, 0x2015, 0x2015, 0x400b, 0x400b, 0x400b, 0x400b,
+ 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001,
+ 0x0028, 0x00f0, 0x00f8, 0x0027, 0x0030, 0x00d8, 0x00e0, 0x00e8,
+ 0x0038, 0x00a0, 0x00c8, 0x00d0, 0x0040, 0x0068, 0x0090, 0x0098,
+ 0x0048, 0x0050, 0x0058, 0x0060, 0x27ff, 0x27ff, 0x206b, 0x206b,
+ 0x0081, 0x0085, 0x0083, 0x0079, 0x0087, 0x007d, 0x007b, 0x0071,
+ 0x007f, 0x0075, 0x0073, 0x0069, 0x0070, 0x0078, 0x0080, 0x0088,
+ 0x2077, 0x2077, 0x206d, 0x206d, 0x2063, 0x2063, 0x2061, 0x2061,
+ 0x206f, 0x206f, 0x2065, 0x2065, 0x205b, 0x205b, 0x2059, 0x2059,
+ 0x0067, 0x005d, 0x0053, 0x0051, 0x005f, 0x0055, 0x004b, 0x0049,
+ 0x00a8, 0x00b0, 0x00b8, 0x00c0, 0x2041, 0x2041, 0x204d, 0x204d,
+ 0x2043, 0x2043, 0x2039, 0x2039, 0x2057, 0x2057, 0x2045, 0x2045,
+ 0x203b, 0x203b, 0x2031, 0x2031, 0x204f, 0x204f, 0x203d, 0x203d,
+ 0x2033, 0x2033, 0x2029, 0x2029, 0x0047, 0x0035, 0x002b, 0x0021,
+ 0x203f, 0x203f, 0x202d, 0x202d, 0x2023, 0x2023, 0x2019, 0x2019,
+ 0x0037, 0x0025, 0x001b, 0x0011, 0x202f, 0x202f, 0x201d, 0x201d,
+ 0x0013, 0x0009, 0x201f, 0x201f
+};
+
+static const OMX_U16 armVCM4P10_CAVLCCoeffTokenTables_1[128] = {
+ 0x0020, 0x00e8, 0x00f0, 0x00f8, 0x0027, 0x001f, 0x2015, 0x2015,
+ 0x400b, 0x400b, 0x400b, 0x400b, 0x4001, 0x4001, 0x4001, 0x4001,
+ 0x0028, 0x00d0, 0x00d8, 0x00e0, 0x0030, 0x0098, 0x00c0, 0x00c8,
+ 0x0038, 0x0060, 0x0088, 0x0090, 0x0040, 0x0048, 0x0050, 0x0058,
+ 0x27ff, 0x27ff, 0x207f, 0x207f, 0x0087, 0x0085, 0x0083, 0x0081,
+ 0x007b, 0x0079, 0x007d, 0x0073, 0x2075, 0x2075, 0x2071, 0x2071,
+ 0x0068, 0x0070, 0x0078, 0x0080, 0x2077, 0x2077, 0x206d, 0x206d,
+ 0x206b, 0x206b, 0x2069, 0x2069, 0x206f, 0x206f, 0x2065, 0x2065,
+ 0x2063, 0x2063, 0x2061, 0x2061, 0x0059, 0x005d, 0x005b, 0x0051,
+ 0x0067, 0x0055, 0x0053, 0x0049, 0x00a0, 0x00a8, 0x00b0, 0x00b8,
+ 0x205f, 0x205f, 0x204d, 0x204d, 0x204b, 0x204b, 0x2041, 0x2041,
+ 0x2057, 0x2057, 0x2045, 0x2045, 0x2043, 0x2043, 0x2039, 0x2039,
+ 0x204f, 0x204f, 0x203d, 0x203d, 0x203b, 0x203b, 0x2031, 0x2031,
+ 0x0029, 0x0035, 0x0033, 0x0021, 0x2047, 0x2047, 0x202d, 0x202d,
+ 0x202b, 0x202b, 0x2019, 0x2019, 0x003f, 0x0025, 0x0023, 0x0011,
+ 0x0037, 0x001d, 0x001b, 0x0009, 0x202f, 0x202f, 0x2013, 0x2013
+};
+
+static const OMX_U16 armVCM4P10_CAVLCCoeffTokenTables_2[112] = {
+ 0x0020, 0x0088, 0x00b0, 0x00b8, 0x00c0, 0x00c8, 0x00d0, 0x00d8,
+ 0x003f, 0x0037, 0x002f, 0x0027, 0x001f, 0x0015, 0x000b, 0x0001,
+ 0x0028, 0x0050, 0x0078, 0x0080, 0x0030, 0x0038, 0x0040, 0x0048,
+ 0x07ff, 0x0081, 0x0087, 0x0085, 0x0083, 0x0079, 0x007f, 0x007d,
+ 0x007b, 0x0071, 0x0077, 0x0075, 0x0073, 0x0069, 0x206b, 0x206b,
+ 0x0058, 0x0060, 0x0068, 0x0070, 0x2061, 0x2061, 0x206d, 0x206d,
+ 0x2063, 0x2063, 0x2059, 0x2059, 0x206f, 0x206f, 0x2065, 0x2065,
+ 0x205b, 0x205b, 0x2051, 0x2051, 0x0067, 0x005d, 0x0053, 0x0049,
+ 0x005f, 0x0055, 0x004b, 0x0041, 0x0090, 0x0098, 0x00a0, 0x00a8,
+ 0x2039, 0x2039, 0x2031, 0x2031, 0x204d, 0x204d, 0x2029, 0x2029,
+ 0x2057, 0x2057, 0x2045, 0x2045, 0x2043, 0x2043, 0x2021, 0x2021,
+ 0x0019, 0x003d, 0x003b, 0x0011, 0x004f, 0x0035, 0x0033, 0x0009,
+ 0x202b, 0x202b, 0x202d, 0x202d, 0x2023, 0x2023, 0x2025, 0x2025,
+ 0x201b, 0x201b, 0x2047, 0x2047, 0x201d, 0x201d, 0x2013, 0x2013
+};
+
+static const OMX_U16 armVCM4P10_CAVLCCoeffTokenTables_3[80] = {
+ 0x0020, 0x0028, 0x0030, 0x0038, 0x0040, 0x0048, 0x0050, 0x0058,
+ 0x0060, 0x0068, 0x0070, 0x0078, 0x0080, 0x0088, 0x0090, 0x0098,
+ 0x0009, 0x000b, 0x07ff, 0x0001, 0x0011, 0x0013, 0x0015, 0x07ff,
+ 0x0019, 0x001b, 0x001d, 0x001f, 0x0021, 0x0023, 0x0025, 0x0027,
+ 0x0029, 0x002b, 0x002d, 0x002f, 0x0031, 0x0033, 0x0035, 0x0037,
+ 0x0039, 0x003b, 0x003d, 0x003f, 0x0041, 0x0043, 0x0045, 0x0047,
+ 0x0049, 0x004b, 0x004d, 0x004f, 0x0051, 0x0053, 0x0055, 0x0057,
+ 0x0059, 0x005b, 0x005d, 0x005f, 0x0061, 0x0063, 0x0065, 0x0067,
+ 0x0069, 0x006b, 0x006d, 0x006f, 0x0071, 0x0073, 0x0075, 0x0077,
+ 0x0079, 0x007b, 0x007d, 0x007f, 0x0081, 0x0083, 0x0085, 0x0087
+};
+
+static const OMX_U16 armVCM4P10_CAVLCCoeffTokenTables_4[32] = {
+ 0x0020, 0x0038, 0x2015, 0x2015, 0x4001, 0x4001, 0x4001, 0x4001,
+ 0x600b, 0x600b, 0x600b, 0x600b, 0x600b, 0x600b, 0x600b, 0x600b,
+ 0x0028, 0x0030, 0x0021, 0x0019, 0x2027, 0x2027, 0x0025, 0x0023,
+ 0x201d, 0x201d, 0x201b, 0x201b, 0x0011, 0x001f, 0x0013, 0x0009
+};
+
+const OMX_U16 * armVCM4P10_CAVLCCoeffTokenTables[18] = {
+ armVCM4P10_CAVLCCoeffTokenTables_0, /* nC=0 */
+ armVCM4P10_CAVLCCoeffTokenTables_0, /* nC=1 */
+ armVCM4P10_CAVLCCoeffTokenTables_1, /* nC=2 */
+ armVCM4P10_CAVLCCoeffTokenTables_1, /* nC=3 */
+ armVCM4P10_CAVLCCoeffTokenTables_2, /* nC=4 */
+ armVCM4P10_CAVLCCoeffTokenTables_2, /* nC=5 */
+ armVCM4P10_CAVLCCoeffTokenTables_2, /* nC=6 */
+ armVCM4P10_CAVLCCoeffTokenTables_2, /* nC=7 */
+ armVCM4P10_CAVLCCoeffTokenTables_3, /* nC=8 */
+ armVCM4P10_CAVLCCoeffTokenTables_3, /* nC=9 */
+ armVCM4P10_CAVLCCoeffTokenTables_3, /* nC=10 */
+ armVCM4P10_CAVLCCoeffTokenTables_3, /* nC=11 */
+ armVCM4P10_CAVLCCoeffTokenTables_3, /* nC=12 */
+ armVCM4P10_CAVLCCoeffTokenTables_3, /* nC=13 */
+ armVCM4P10_CAVLCCoeffTokenTables_3, /* nC=14 */
+ armVCM4P10_CAVLCCoeffTokenTables_3, /* nC=15 */
+ armVCM4P10_CAVLCCoeffTokenTables_3, /* nC=16 */
+ armVCM4P10_CAVLCCoeffTokenTables_4 /* nC=-1 */
+};
+
+static const OMX_U16 armVCM4P10_CAVLCTotalZeroTables_0[40] = {
+ 0x0020, 0x0048, 0x0009, 0x0007, 0x2005, 0x2005, 0x2003, 0x2003,
+ 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001,
+ 0x0028, 0x0040, 0x0011, 0x000f, 0x0030, 0x0038, 0x0019, 0x0017,
+ 0x27ff, 0x27ff, 0x201f, 0x201f, 0x201d, 0x201d, 0x201b, 0x201b,
+ 0x2015, 0x2015, 0x2013, 0x2013, 0x200d, 0x200d, 0x200b, 0x200b
+};
+
+static const OMX_U16 armVCM4P10_CAVLCTotalZeroTables_1[24] = {
+ 0x0020, 0x0028, 0x0011, 0x000f, 0x000d, 0x000b, 0x2009, 0x2009,
+ 0x2007, 0x2007, 0x2005, 0x2005, 0x2003, 0x2003, 0x2001, 0x2001,
+ 0x001d, 0x001b, 0x0019, 0x0017, 0x2015, 0x2015, 0x2013, 0x2013
+};
+
+static const OMX_U16 armVCM4P10_CAVLCTotalZeroTables_2[24] = {
+ 0x0020, 0x0028, 0x0011, 0x000b, 0x0009, 0x0001, 0x200f, 0x200f,
+ 0x200d, 0x200d, 0x2007, 0x2007, 0x2005, 0x2005, 0x2003, 0x2003,
+ 0x001b, 0x0017, 0x2019, 0x2019, 0x2015, 0x2015, 0x2013, 0x2013
+};
+
+static const OMX_U16 armVCM4P10_CAVLCTotalZeroTables_3[24] = {
+ 0x0020, 0x0028, 0x0013, 0x000f, 0x0007, 0x0005, 0x2011, 0x2011,
+ 0x200d, 0x200d, 0x200b, 0x200b, 0x2009, 0x2009, 0x2003, 0x2003,
+ 0x2019, 0x2019, 0x2017, 0x2017, 0x2015, 0x2015, 0x2001, 0x2001
+};
+
+static const OMX_U16 armVCM4P10_CAVLCTotalZeroTables_4[20] = {
+ 0x0020, 0x0015, 0x0011, 0x0005, 0x0003, 0x0001, 0x200f, 0x200f,
+ 0x200d, 0x200d, 0x200b, 0x200b, 0x2009, 0x2009, 0x2007, 0x2007,
+ 0x2017, 0x2017, 0x2013, 0x2013
+};
+
+static const OMX_U16 armVCM4P10_CAVLCTotalZeroTables_5[20] = {
+ 0x0020, 0x0011, 0x2013, 0x2013, 0x200f, 0x200f, 0x200d, 0x200d,
+ 0x200b, 0x200b, 0x2009, 0x2009, 0x2007, 0x2007, 0x2005, 0x2005,
+ 0x0015, 0x0001, 0x2003, 0x2003
+};
+
+static const OMX_U16 armVCM4P10_CAVLCTotalZeroTables_6[20] = {
+ 0x0020, 0x000f, 0x2011, 0x2011, 0x200d, 0x200d, 0x2009, 0x2009,
+ 0x2007, 0x2007, 0x2005, 0x2005, 0x400b, 0x400b, 0x400b, 0x400b,
+ 0x0013, 0x0001, 0x2003, 0x2003
+};
+
+static const OMX_U16 armVCM4P10_CAVLCTotalZeroTables_7[20] = {
+ 0x0020, 0x0003, 0x200f, 0x200f, 0x200d, 0x200d, 0x2007, 0x2007,
+ 0x400b, 0x400b, 0x400b, 0x400b, 0x4009, 0x4009, 0x4009, 0x4009,
+ 0x0011, 0x0001, 0x2005, 0x2005
+};
+
+static const OMX_U16 armVCM4P10_CAVLCTotalZeroTables_8[20] = {
+ 0x0020, 0x0005, 0x200b, 0x200b, 0x400d, 0x400d, 0x400d, 0x400d,
+ 0x4009, 0x4009, 0x4009, 0x4009, 0x4007, 0x4007, 0x4007, 0x4007,
+ 0x0003, 0x0001, 0x200f, 0x200f
+};
+
+static const OMX_U16 armVCM4P10_CAVLCTotalZeroTables_9[20] = {
+ 0x0020, 0x000d, 0x2005, 0x2005, 0x400b, 0x400b, 0x400b, 0x400b,
+ 0x4009, 0x4009, 0x4009, 0x4009, 0x4007, 0x4007, 0x4007, 0x4007,
+ 0x2003, 0x2003, 0x2001, 0x2001
+};
+
+static const OMX_U16 armVCM4P10_CAVLCTotalZeroTables_10[16] = {
+ 0x0001, 0x0003, 0x2005, 0x2005, 0x2007, 0x2007, 0x200b, 0x200b,
+ 0x6009, 0x6009, 0x6009, 0x6009, 0x6009, 0x6009, 0x6009, 0x6009
+};
+
+static const OMX_U16 armVCM4P10_CAVLCTotalZeroTables_11[16] = {
+ 0x0001, 0x0003, 0x2009, 0x2009, 0x4005, 0x4005, 0x4005, 0x4005,
+ 0x6007, 0x6007, 0x6007, 0x6007, 0x6007, 0x6007, 0x6007, 0x6007
+};
+
+static const OMX_U16 armVCM4P10_CAVLCTotalZeroTables_12[16] = {
+ 0x2001, 0x2001, 0x2003, 0x2003, 0x4007, 0x4007, 0x4007, 0x4007,
+ 0x6005, 0x6005, 0x6005, 0x6005, 0x6005, 0x6005, 0x6005, 0x6005
+};
+
+static const OMX_U16 armVCM4P10_CAVLCTotalZeroTables_13[16] = {
+ 0x4001, 0x4001, 0x4001, 0x4001, 0x4003, 0x4003, 0x4003, 0x4003,
+ 0x6005, 0x6005, 0x6005, 0x6005, 0x6005, 0x6005, 0x6005, 0x6005
+};
+
+static const OMX_U16 armVCM4P10_CAVLCTotalZeroTables_14[16] = {
+ 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001,
+ 0x6003, 0x6003, 0x6003, 0x6003, 0x6003, 0x6003, 0x6003, 0x6003
+};
+
+const OMX_U16 * armVCM4P10_CAVLCTotalZeroTables[15] = {
+ armVCM4P10_CAVLCTotalZeroTables_0,
+ armVCM4P10_CAVLCTotalZeroTables_1,
+ armVCM4P10_CAVLCTotalZeroTables_2,
+ armVCM4P10_CAVLCTotalZeroTables_3,
+ armVCM4P10_CAVLCTotalZeroTables_4,
+ armVCM4P10_CAVLCTotalZeroTables_5,
+ armVCM4P10_CAVLCTotalZeroTables_6,
+ armVCM4P10_CAVLCTotalZeroTables_7,
+ armVCM4P10_CAVLCTotalZeroTables_8,
+ armVCM4P10_CAVLCTotalZeroTables_9,
+ armVCM4P10_CAVLCTotalZeroTables_10,
+ armVCM4P10_CAVLCTotalZeroTables_11,
+ armVCM4P10_CAVLCTotalZeroTables_12,
+ armVCM4P10_CAVLCTotalZeroTables_13,
+ armVCM4P10_CAVLCTotalZeroTables_14
+};
+
+static const OMX_U16 armVCM4P10_CAVLCTotalZeros2x2Tables_0[16] = {
+ 0x2007, 0x2007, 0x2005, 0x2005, 0x4003, 0x4003, 0x4003, 0x4003,
+ 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001
+};
+
+static const OMX_U16 armVCM4P10_CAVLCTotalZeros2x2Tables_1[16] = {
+ 0x4005, 0x4005, 0x4005, 0x4005, 0x4003, 0x4003, 0x4003, 0x4003,
+ 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001
+};
+
+static const OMX_U16 armVCM4P10_CAVLCTotalZeros2x2Tables_2[16] = {
+ 0x6003, 0x6003, 0x6003, 0x6003, 0x6003, 0x6003, 0x6003, 0x6003,
+ 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001
+};
+
+const OMX_U16 * armVCM4P10_CAVLCTotalZeros2x2Tables[3] = {
+ armVCM4P10_CAVLCTotalZeros2x2Tables_0,
+ armVCM4P10_CAVLCTotalZeros2x2Tables_1,
+ armVCM4P10_CAVLCTotalZeros2x2Tables_2
+};
+
+static const OMX_U16 armVCM4P10_CAVLCRunBeforeTables_0[8] = {
+ 0x4003, 0x4003, 0x4003, 0x4003, 0x4001, 0x4001, 0x4001, 0x4001
+};
+
+static const OMX_U16 armVCM4P10_CAVLCRunBeforeTables_1[8] = {
+ 0x2005, 0x2005, 0x2003, 0x2003, 0x4001, 0x4001, 0x4001, 0x4001
+};
+
+static const OMX_U16 armVCM4P10_CAVLCRunBeforeTables_2[8] = {
+ 0x2007, 0x2007, 0x2005, 0x2005, 0x2003, 0x2003, 0x2001, 0x2001
+};
+
+static const OMX_U16 armVCM4P10_CAVLCRunBeforeTables_3[8] = {
+ 0x0009, 0x0007, 0x2005, 0x2005, 0x2003, 0x2003, 0x2001, 0x2001
+};
+
+static const OMX_U16 armVCM4P10_CAVLCRunBeforeTables_4[8] = {
+ 0x000b, 0x0009, 0x0007, 0x0005, 0x2003, 0x2003, 0x2001, 0x2001
+};
+
+static const OMX_U16 armVCM4P10_CAVLCRunBeforeTables_5[8] = {
+ 0x0003, 0x0005, 0x0009, 0x0007, 0x000d, 0x000b, 0x2001, 0x2001
+};
+
+static const OMX_U16 armVCM4P10_CAVLCRunBeforeTables_6[24] = {
+ 0x0010, 0x000d, 0x000b, 0x0009, 0x0007, 0x0005, 0x0003, 0x0001,
+ 0x0018, 0x0011, 0x200f, 0x200f, 0x0020, 0x0015, 0x2013, 0x2013,
+ 0x0028, 0x0019, 0x2017, 0x2017, 0x07ff, 0x001d, 0x201b, 0x201b
+};
+
+/* Tables 7 to 14 are duplicates of table 6 */
+
+const OMX_U16 * armVCM4P10_CAVLCRunBeforeTables[15] = {
+ armVCM4P10_CAVLCRunBeforeTables_0, /* ZerosLeft=1 */
+ armVCM4P10_CAVLCRunBeforeTables_1,
+ armVCM4P10_CAVLCRunBeforeTables_2,
+ armVCM4P10_CAVLCRunBeforeTables_3,
+ armVCM4P10_CAVLCRunBeforeTables_4,
+ armVCM4P10_CAVLCRunBeforeTables_5, /* ZerosLeft=6 */
+ armVCM4P10_CAVLCRunBeforeTables_6, /* ZerosLeft=7 */
+ armVCM4P10_CAVLCRunBeforeTables_6, /* ZerosLeft=8 */
+ armVCM4P10_CAVLCRunBeforeTables_6, /* ZerosLeft=9 */
+ armVCM4P10_CAVLCRunBeforeTables_6, /* ZerosLeft=10 */
+ armVCM4P10_CAVLCRunBeforeTables_6, /* ZerosLeft=11 */
+ armVCM4P10_CAVLCRunBeforeTables_6, /* ZerosLeft=12 */
+ armVCM4P10_CAVLCRunBeforeTables_6, /* ZerosLeft=13 */
+ armVCM4P10_CAVLCRunBeforeTables_6, /* ZerosLeft=14 */
+ armVCM4P10_CAVLCRunBeforeTables_6 /* ZerosLeft=15 */
+};
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_DeblockingChroma_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_DeblockingChroma_unsafe_s.s
new file mode 100755
index 0000000..4c3a77c
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_DeblockingChroma_unsafe_s.s
@@ -0,0 +1,198 @@
+;//
+;//
+;// File Name: armVCM4P10_DeblockingChroma_unsafe_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 12290
+;// Date: Wednesday, April 9, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS CortexA8
+
+
+ IF CortexA8
+
+pAlpha RN 2
+pBeta RN 3
+
+pThresholds RN 5
+pBS RN 4
+bS3210 RN 6
+
+;// Pixels
+dP_0 DN D4.U8
+dP_1 DN D5.U8
+dP_2 DN D6.U8
+dP_3 DN D7.U8
+dQ_0 DN D8.U8
+dQ_1 DN D9.U8
+dQ_2 DN D10.U8
+dQ_3 DN D11.U8
+
+
+;// Filtering Decision
+dAlpha DN D0.U8
+dBeta DN D2.U8
+
+dFilt DN D16.U8
+dAqflg DN D12.U8
+dApflg DN D17.U8
+
+dAp0q0 DN D13.U8
+
+;// bSLT4
+dTC3210 DN D18.U8
+dTCs DN D31.S8
+dTC DN D31.U8
+
+dMask_0 DN D14.U8
+dMask_1 DN D15.U8
+dMask_4 DN D26.U16
+
+dTemp DN D28.U8
+dDummy DN D17.U8
+
+;// Computing P0,Q0
+qDq0p0 QN Q10.S16
+qDp1q1 QN Q11.S16
+qDelta QN Q10.S16 ; reuse qDq0p0
+dDelta DN D20.S8
+
+
+;// Computing P1,Q1
+qP_0n QN Q14.S16
+qQ_0n QN Q12.S16
+
+dQ_0n DN D24.U8
+dP_0n DN D29.U8
+
+;// bSGE4
+
+dHSp0q1 DN D13.U8
+dHSq0p1 DN D31.U8
+
+dBS3210 DN D28.U16
+
+dP_0t DN D13.U8 ;dHSp0q1
+dQ_0t DN D31.U8 ;Temp1
+
+dP_0n DN D29.U8
+dQ_0n DN D24.U8 ;Temp2
+
+;// Register usage for - armVCM4P10_DeblockingLumabSLT4_unsafe
+;//
+;// Inputs - Pixels - p0-p3: D4-D7, q0-q3: D8-D11
+;// - Filter masks - filt: D16, aqflg: D12, apflg: D17
+;// - Additional Params - pThresholds: r5
+;//
+;// Outputs - Pixels - P0-P1: D29-D30, Q0-Q1: D24-D25
+;// - Additional Params - pThresholds: r5
+
+;// Registers Corrupted - D18-D31
+
+
+ M_START armVCM4P10_DeblockingChromabSLT4_unsafe
+
+
+ ;dTC3210 -18
+ ;dTemp-28
+
+ VLD1 d18.U32[0], [pThresholds]! ;here
+
+ ;// delta = (((q0-p0)<<2) + (p1-q1) + 4) >> 3;
+ ;// dDelta = (qDp1q1 >> 2 + qDq0p0 + 1)>> 1
+
+ ;// qDp1q1-11
+ ;// qDq0p0-10
+ VSUBL qDp1q1, dP_1, dQ_1
+ VMOV dTemp, dTC3210
+ VSUBL qDq0p0, dQ_0, dP_0
+ VSHR qDp1q1, qDp1q1, #2
+ VZIP.8 dTC3210, dTemp
+
+ ;// qDelta-qDq0p0-10
+
+ ;// dTC = dTC01 + (dAplg & 1) + (dAqflg & 1)
+
+ ;// dTC3210-18
+ ;// dTemp-28
+ ;// dTC-31
+ VBIF dTC3210, dMask_0, dFilt
+ VRHADD qDelta, qDp1q1, qDq0p0
+ VADD dTC, dTC3210, dMask_1
+ VQMOVN dDelta, qDelta
+ ;// dDelta-d20
+
+ ;// dDelta = (OMX_U8)armClip(0, 255, q0 - delta);
+ VLD1 {dAlpha[]}, [pAlpha]
+ VMIN dDelta, dDelta, dTCs
+ VNEG dTCs, dTCs
+ VLD1 {dBeta[]}, [pBeta]
+ ;1
+ VMAX dDelta, dDelta, dTCs
+
+ ;// dP_0n - 29
+ ;// dQ_0n - 24
+
+ ;// pQ0[-1*Step] = (OMX_U8)armClip(0, 255, dP_0 - delta);
+ ;// pQ0[0*Step] = (OMX_U8)armClip(0, 255, dQ_0 - delta);
+
+ ;// dP_0n = (OMX_U8)armClip(0, 255, dP_0 - dDelta);
+ ;// dQ_0n = (OMX_U8)armClip(0, 255, dP_0 - dDelta);
+
+ ;// qP_0n - 14
+ ;// qQ_0n - 12
+
+ VMOVL qP_0n, dP_0
+ VMOVL qQ_0n, dQ_0
+
+ ;1
+ VADDW qP_0n, qP_0n, dDelta
+ VSUBW qQ_0n, qQ_0n, dDelta
+
+ VQMOVUN dP_0n, qP_0n
+ VQMOVUN dQ_0n, qQ_0n
+
+ M_END
+
+;// Register usage for - armVCM4P10_DeblockingLumabSGE4_unsafe()
+;//
+;// Inputs - Pixels - p0-p3: D4-D7, q0-q3: D8-D11
+;// - Filter masks - filt: D16, aqflg: D12, apflg: D17
+;// - Additional Params - alpha: D0, dMask_1: D15
+;//
+;// Outputs - Pixels - P0-P2: D29-D31, Q0-Q2: D24,D25,D28
+
+;// Registers Corrupted - D18-D31
+
+ M_START armVCM4P10_DeblockingChromabSGE4_unsafe
+
+ ;dHSq0p1 - 31
+ ;dHSp0q1 - 13
+ VHADD dHSp0q1, dP_0, dQ_1
+ VHADD dHSq0p1, dQ_0, dP_1
+
+ ;// Prepare the bS mask
+
+ ;// dHSp0q1-13
+ ;// dP_0t-dHSp0q1-13
+ ;// dHSq0p1-31
+ ;// dQ_0t-Temp1-31
+ VLD1 {dAlpha[]}, [pAlpha]
+ ADD pThresholds, pThresholds, #4
+ VLD1 {dBeta[]}, [pBeta]
+
+ VRHADD dP_0t, dHSp0q1, dP_1
+ VRHADD dQ_0t, dHSq0p1, dQ_1
+
+ M_END
+
+ ENDIF
+
+ END
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_DeblockingLuma_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_DeblockingLuma_unsafe_s.s
new file mode 100755
index 0000000..0afe4fd
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_DeblockingLuma_unsafe_s.s
@@ -0,0 +1,396 @@
+;//
+;//
+;// File Name: armVCM4P10_DeblockingLuma_unsafe_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 12290
+;// Date: Wednesday, April 9, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS CortexA8
+
+
+ IF CortexA8
+
+pThresholds RN 5
+
+;// Pixels
+dP_0 DN D4.U8
+dP_1 DN D5.U8
+dP_2 DN D6.U8
+dP_3 DN D7.U8
+dQ_0 DN D8.U8
+dQ_1 DN D9.U8
+dQ_2 DN D10.U8
+dQ_3 DN D11.U8
+
+
+;// Filtering Decision
+dAlpha DN D0.U8
+
+dFilt DN D16.U8
+dAqflg DN D12.U8
+dApflg DN D17.U8
+
+dAp0q0 DN D13.U8
+
+;// bSLT4
+dTC0 DN D18.U8
+dTC1 DN D19.U8
+dTC01 DN D18.U8
+
+dTCs DN D31.S8
+dTC DN D31.U8
+
+dMask_0 DN D14.U8
+dMask_1 DN D15.U8
+
+dTemp DN D19.U8
+
+;// Computing P0,Q0
+qDq0p0 QN Q10.S16
+qDp1q1 QN Q11.S16
+qDelta QN Q10.S16 ; reuse qDq0p0
+dDelta DN D20.S8
+
+
+;// Computing P1,Q1
+dRp0q0 DN D24.U8
+
+dMaxP DN D23.U8
+dMinP DN D22.U8
+
+dMaxQ DN D19.U8
+dMinQ DN D21.U8
+
+dDeltaP DN D26.U8
+dDeltaQ DN D27.U8
+
+qP_0n QN Q14.S16
+qQ_0n QN Q12.S16
+
+dQ_0n DN D24.U8
+dQ_1n DN D25.U8
+dP_0n DN D29.U8
+dP_1n DN D30.U8
+
+;// bSGE4
+
+qSp0q0 QN Q10.U16
+
+qSp2q1 QN Q11.U16
+qSp0q0p1 QN Q12.U16
+qSp3p2 QN Q13.U16
+dHSp0q1 DN D28.U8
+
+qSq2p1 QN Q11.U16
+qSp0q0q1 QN Q12.U16
+qSq3q2 QN Q13.U16 ;!!
+dHSq0p1 DN D28.U8 ;!!
+
+qTemp1 QN Q11.U16 ;!!;qSp2q1
+qTemp2 QN Q12.U16 ;!!;qSp0q0p1
+
+dP_0t DN D28.U8 ;!!;dHSp0q1
+dQ_0t DN D22.U8 ;!!;Temp1
+
+dP_0n DN D29.U8
+dP_1n DN D30.U8
+dP_2n DN D31.U8
+
+dQ_0n DN D24.U8 ;!!;Temp2
+dQ_1n DN D25.U8 ;!!;Temp2
+dQ_2n DN D28.U8 ;!!;dQ_0t
+
+;// Register usage for - armVCM4P10_DeblockingLumabSLT4_unsafe
+;//
+;// Inputs - Pixels - p0-p3: D4-D7, q0-q3: D8-D11
+;// - Filter masks - filt: D16, aqflg: D12, apflg: D17
+;// - Additional Params - pThresholds: r5
+;//
+;// Outputs - Pixels - P0-P1: D29-D30, Q0-Q1: D24-D25
+;// - Additional Params - pThresholds: r5
+
+;// Registers Corrupted - D18-D31
+
+
+ M_START armVCM4P10_DeblockingLumabSLT4_unsafe
+
+
+ ;// qDq0p0-10
+ VSUBL qDp1q1, dP_1, dQ_1
+ VLD1 {dTC0[]}, [pThresholds]!
+ ;// qDp1q1-11
+ VSUBL qDq0p0, dQ_0, dP_0
+ VLD1 {dTC1[]}, [pThresholds]!
+
+ ;// dRp0q0-24
+ VSHR qDp1q1, qDp1q1, #2
+
+ ;// dTC01 = (dTC1 << 4) | dTC0
+ ;// dTC01-18
+ VEXT dTC01, dTC0, dTC1, #4
+ ;// dTemp-19
+ VAND dTemp, dApflg, dMask_1
+
+ VBIF dTC01, dMask_0, dFilt
+
+
+ ;// delta = (((q0-p0)<<2) + (p1-q1) + 4) >> 3;
+ ;// dDelta = (qDp1q1 >> 2 + qDq0p0 + 1)>> 1
+
+ ;// qDelta-qDq0p0-10
+ VRHADD qDelta, qDp1q1, qDq0p0
+ VRHADD dRp0q0, dP_0, dQ_0
+ VADD dTC, dTC01, dTemp
+
+ ;// dTC = dTC01 + (dAplg & 1) + (dAqflg & 1)
+
+ VAND dTemp, dAqflg, dMask_1
+ VQADD dMaxP, dP_1, dTC01
+ VQMOVN dDelta, qDelta
+ VADD dTC, dTC, dTemp
+
+ ;// dMaxP = QADD(dP_1, dTC01)
+ ;// dMinP = QSUB(dP_1, dTC01)
+
+ ;// dMaxP-d23
+ ;// dMinP-d22
+ VQSUB dMinP, dP_1, dTC01
+
+ ;// dDelta-d20
+
+ ;// dMaxQ = QADD(dQ_1, dTC01)
+ ;// dMinQ = QSUB(dQ_1, dTC01)
+
+ ;// dMaxQ-19
+ ;// dMinQ-21
+ VQADD dMaxQ, dQ_1, dTC01
+ VHADD dDeltaP, dRp0q0, dP_2
+ VMIN dDelta, dDelta, dTCs
+
+ ;// dDelta = (OMX_U8)armClip(0, 255, q0 - delta);
+ VNEG dTCs, dTCs
+
+ VQSUB dMinQ, dQ_1, dTC01
+
+ ;// delta = (p2 + ((p0+q0+1)>>1) - (p1<<1))>>1;
+ ;// delta = armClip(-tC0, tC0, delta);
+ ;// pQ0[-2*Step] = (OMX_U8)(p1 + delta);
+
+ ;// dDeltaP = (dP_2 + dRp0q0)>>1;
+ ;// dP_1n = armClip(dP_1 - dTC01, dP_1 + dTC01, dDeltaP);
+ ;// dP_1n = armClip(MinP, MaxP, dDeltaP);
+
+ ;// delta = (q2 + ((p0+q0+1)>>1) - (q1<<1))>>1;
+ ;// delta = armClip(-tC0, tC0, delta);
+ ;// pQ0[1*Step] = (OMX_U8)(q1 + delta);
+
+ ;// dDeltaQ = (dQ_2 + dRp0q0)>>1;
+ ;// dQ_1n = armClip(dQ_1 - dTC01, dQ_1 + dTC01, dDeltaQ);
+ ;// dQ_1n = armClip(MinQ, MaxQ, dDeltaQ);
+
+ ;// dDeltaP-26
+ VHADD dDeltaQ, dRp0q0, dQ_2
+
+ ;// dDeltaQ-27
+
+ ;// dP_0n - 29
+ ;// dP_1n - 30
+ ;// dQ_0n - 24
+ ;// dQ_1n - 25
+
+ ;// delta = (q2 + ((p0+q0+1)>>1) - (q1<<1))>>1;
+ ;// dDeltaQ = (dQ_2 + dRp0q0)>>1;
+
+ VMAX dP_1n, dDeltaP, dMinP
+ VMAX dDelta, dDelta, dTCs
+
+ ;// pQ0[-1*Step] = (OMX_U8)armClip(0, 255, dP_0 - delta);
+ ;// pQ0[0*Step] = (OMX_U8)armClip(0, 255, dQ_0 - delta);
+
+ ;// dP_0n = (OMX_U8)armClip(0, 255, dP_0 - dDelta);
+ ;// dQ_0n = (OMX_U8)armClip(0, 255, dP_0 - dDelta);
+
+ ;// qP_0n - 14
+ ;// qQ_0n - 12
+
+ VMOVL qP_0n, dP_0
+ VMOVL qQ_0n, dQ_0
+
+ VADDW qP_0n, qP_0n, dDelta
+ VSUBW qQ_0n, qQ_0n, dDelta
+
+ VQMOVUN dP_0n, qP_0n
+ VQMOVUN dQ_0n, qQ_0n
+
+ VMAX dQ_1n, dDeltaQ, dMinQ
+
+ VMIN dP_1n, dP_1n, dMaxP
+ VMIN dQ_1n, dQ_1n, dMaxQ
+ VBIF dP_0n, dP_0, dFilt
+
+ VBIF dP_1n, dP_1, dApflg
+ VBIF dQ_0n, dQ_0, dFilt
+ VBIF dQ_1n, dQ_1, dAqflg
+
+ M_END
+
+;// Register usage for - armVCM4P10_DeblockingLumabSGE4_unsafe()
+;//
+;// Inputs - Pixels - p0-p3: D4-D7, q0-q3: D8-D11
+;// - Filter masks - filt: D16, aqflg: D12, apflg: D17
+;// - Additional Params - alpha: D0, dMask_1: D15
+;//
+;// Outputs - Pixels - P0-P2: D29-D31, Q0-Q2: D24,D25,D28
+
+;// Registers Corrupted - D18-D31
+
+ M_START armVCM4P10_DeblockingLumabSGE4_unsafe
+
+
+ ;// ap<beta && armAbs(p0-q0)<((alpha>>2)+2)
+ ;// aq<beta && armAbs(p0-q0)<((alpha>>2)+2)
+
+ ;// ( dApflg & dAp0q0 < (dAlpha >> 2 + 2) )
+ ;// ( dAqflg & dAp0q0 < (dAlpha >> 2 + 2) )
+
+ ;// ( dApflg = dApflg & dAp0q0 < (dTemp + dMask_1 + dMask_1) )
+ ;// ( dAqflg = dAqflg & dAp0q0 < (dTemp + dMask_1 + dMask_1) )
+
+ ;// P Filter
+
+ VSHR dTemp, dAlpha, #2
+ VADD dTemp, dTemp, dMask_1
+
+ ;// qSp0q0-10
+ VADDL qSp0q0, dQ_0, dP_0
+ VADD dTemp, dTemp, dMask_1
+
+ ;// qSp2q1-11
+ ;// qSp0q0p1-12
+ VADDL qSp2q1, dP_2, dQ_1
+ VADDW qSp0q0p1, qSp0q0, dP_1
+
+ VCGT dTemp, dTemp, dAp0q0
+ VSHR qSp2q1, #1
+
+ ;// pQ0[-1*Step] = (OMX_U8)((p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4)>>3);
+ ;// pQ0[-1*Step] = ( ( (p0 + q0 + p1) + (p2 + q1)>>1 ) >> 1 + 1 ) >> 1
+
+ ;// dP_0n = ( ( (qSp0q0 + dP_1) + qSp2q1>>1 ) >> 1 + 1 ) >> 1
+ ;// dP_0n = ( ( qSp0q0p1 + qSp2q1>>1 ) >> 1 + 1 ) >> 1
+ ;// dP_0n = ( qTemp1 + 1 ) >> 1
+
+ ;// pQ0[-2*Step] = (OMX_U8)((p2 + p1 + p0 + q0 + 2)>>2);
+
+ ;// dP_1n = (OMX_U8)((dP_2 + qSp0q0p1 + 2)>>2);
+ ;// dP_1n = (OMX_U8)((qTemp2 + 2)>>2);
+
+ ;// pQ0[-3*Step] = (OMX_U8)((2*p3 + 3*p2 + p1 + p0 + q0 + 4)>>3);
+ ;// pQ0[-3*Step] = (OMX_U8)(( (p3 + p2) + (p1 + p0 + q0 + p2) >> 1 + 2)>>2);
+
+ ;// dP_2n = (OMX_U8)(( qSp3p2 + (dP_2 + qSp0q0p1) >> 1 + 2) >> 2);
+ ;// dP_2n = (OMX_U8)(( qSp3p2 + qTemp2 >> 1 + 2) >> 2);
+
+ ;// qTemp1-qSp2q1-11
+ ;// qTemp2-qSp0q0p1-12
+ VHADD qTemp1, qSp0q0p1, qSp2q1
+ VADDW qTemp2, qSp0q0p1, dP_2
+
+ ;// qSp3p2-13
+ VADDL qSp3p2, dP_3, dP_2
+
+ VAND dApflg, dApflg, dTemp
+ VHADD dHSp0q1, dP_0, dQ_1
+ VSRA qSp3p2, qTemp2, #1
+ ;// dHSp0q1-28
+ VAND dAqflg, dAqflg, dTemp
+
+ ;// dP_0n-29
+ ;// dP_0t-dHSp0q1-28
+ VQRSHRN dP_0n, qTemp1, #1
+ VRHADD dP_0t, dHSp0q1, dP_1
+
+ ;// dP_1n-30
+ VQRSHRN dP_1n, qTemp2, #2
+
+ VADDL qSq2p1, dQ_2, dP_1
+ VADDW qSp0q0q1, qSp0q0, dQ_1
+
+ VBIF dP_0n, dP_0t, dApflg
+
+ ;// Q Filter
+
+ ;// pQ0[0*Step] = (OMX_U8)((q2 + 2*q1 + 2*q0 + 2*p0 + p1 + 4)>>3);
+ ;// pQ0[0*Step] = ( ( (p0 + q0 + q1) + (q2 + p1)>>1 ) >> 1 + 1 ) >> 1
+
+ ;// dQ_0n = ( ( (qSp0q0 + dQ_1) + qSq2p1>>1 ) >> 1 + 1 ) >> 1
+ ;// dQ_0n = ( ( qSp0q0q1 + qSq2p1>>1 ) >> 1 + 1 ) >> 1
+ ;// dQ_0n = ( qTemp1 + 1 ) >> 1
+
+ ;// pQ0[1*Step] = (OMX_U8)((q2 + q1 + q0 + q0 + 2)>>2);
+
+ ;// dQ_1n = (OMX_U8)((dQ_2 + qSp0q0q1 + 2)>>2);
+ ;// dQ_1n = (OMX_U8)((qTemp2 + 2)>>2);
+
+ ;// pQ0[2*Step] = (OMX_U8)((2*q3 + 3*q2 + q1 + q0 + p0 + 4)>>3);
+ ;// pQ0[2*Step] = (OMX_U8)(( (q3 + q2) + (q1 + p0 + q0 + q2) >> 1 + 2)>>2);
+
+ ;// dQ_2n = (OMX_U8)(( qSq3q2 + (dQ_2 + qSp0q0q1) >> 1 + 2) >> 2);
+ ;// dQ_2n = (OMX_U8)(( qSq3q2 + qTemp2 >> 1 + 2) >> 2);
+
+ ;// qTemp1-qSp2q1-11
+ ;// qTemp2-qSp0q0p1-12
+ ;// qSq2p1-11
+ ;// qSp0q0q1-12
+
+
+ ;// qTemp2-qSp0q0p1-12
+ ;// qTemp1-qSq2p1-11
+ ;// qSq3q2-13
+ ;// dP_2n-31
+
+ VQRSHRN dP_2n, qSp3p2, #2
+ VADDL qSq3q2, dQ_3, dQ_2
+
+ VSHR qSq2p1, #1
+
+ VHADD qTemp1, qSp0q0q1, qSq2p1
+ VADDW qTemp2, qSp0q0q1, dQ_2
+
+ ;// dHSq0p1-28
+ VHADD dHSq0p1, dQ_0, dP_1
+
+ VBIF dP_0n, dP_0, dFilt
+ VBIF dP_1n, dP_1, dApflg
+
+ VSRA qSq3q2, qTemp2, #1
+
+ ;// dQ_1-Temp2-25
+ ;// dQ_0-Temp2-24
+ VQRSHRN dQ_1n, qTemp2, #2
+ VQRSHRN dQ_0n, qTemp1, #1
+
+ ;// dQ_0t-Temp1-22
+ VRHADD dQ_0t, dHSq0p1, dQ_1
+ VBIF dQ_1n, dQ_1, dAqflg
+
+ VBIF dP_2n, dP_2, dApflg
+ VBIF dQ_0n, dQ_0t, dAqflg
+ VQRSHRN dQ_2n, qSq3q2, #2
+ VBIF dQ_0n, dQ_0, dFilt
+ VBIF dQ_2n, dQ_2, dAqflg
+
+ M_END
+
+ ENDIF
+
+
+ END
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_DecodeCoeffsToPair_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_DecodeCoeffsToPair_s.s
new file mode 100755
index 0000000..10a89e9
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_DecodeCoeffsToPair_s.s
@@ -0,0 +1,325 @@
+;//
+;//
+;// File Name: armVCM4P10_DecodeCoeffsToPair_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 12290
+;// Date: Wednesday, April 9, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+ INCLUDE armCOMM_BitDec_s.h
+
+ IMPORT armVCM4P10_CAVLCCoeffTokenTables
+ IMPORT armVCM4P10_CAVLCTotalZeroTables
+ IMPORT armVCM4P10_CAVLCTotalZeros2x2Tables
+ IMPORT armVCM4P10_CAVLCRunBeforeTables
+ IMPORT armVCM4P10_SuffixToLevel
+ IMPORT armVCM4P10_ZigZag_4x4
+ IMPORT armVCM4P10_ZigZag_2x2
+
+ M_VARIANTS ARM1136JS
+
+;//DEBUG_ON SETL {TRUE}
+
+LAST_COEFF EQU 0x20 ;// End of block flag
+TWO_BYTE_COEFF EQU 0x10
+
+;// Declare input registers
+
+ppBitStream RN 0
+pOffset RN 1
+pNumCoeff RN 2
+ppPosCoefbuf RN 3
+nC RN 4 ;// number of coeffs or 17 for chroma
+sMaxNumCoeff RN 5
+
+;// Declare inner loop registers
+
+;// Level loop
+Count RN 0
+TrailingOnes RN 1
+pLevel RN 2
+LevelSuffix RN 3
+SuffixLength RN 4
+TotalCoeff RN 5
+
+pVLDTable RN 6
+Symbol RN 7
+T1 RN 8
+T2 RN 9
+RBitStream RN 10
+RBitBuffer RN 11
+RBitCount RN 12
+lr RN 14
+
+;// Run loop
+Count RN 0
+ZerosLeft RN 1
+pLevel RN 2
+ppRunTable RN 3
+pRun RN 4
+TotalCoeff RN 5
+
+pVLDTable RN 6
+Symbol RN 7
+T1 RN 8
+T2 RN 9
+RBitStream RN 10
+RBitBuffer RN 11
+RBitCount RN 12
+lr RN 14
+
+;// Fill in coefficients loop
+pPosCoefbuf RN 0
+temp RN 1
+pLevel RN 2
+ppPosCoefbuf RN 3
+pRun RN 4
+TotalCoeff RN 5
+pZigZag RN 6
+
+T1 RN 8
+T2 RN 9
+RBitStream RN 10
+RBitBuffer RN 11
+RBitCount RN 12
+CoeffNum RN 14
+
+
+
+ IF ARM1136JS
+
+ ;// Allocate stack memory required by the function
+ M_ALLOC4 pppBitStream, 4
+ M_ALLOC4 ppOffset, 4
+ M_ALLOC4 pppPosCoefbuf, 4
+ M_ALLOC4 ppLevel, 16*2
+ M_ALLOC4 ppRun, 16
+
+ ;// Write function header
+ M_START armVCM4P10_DecodeCoeffsToPair, r11
+
+ ;// Define stack arguments
+ M_ARG pNC, 4
+ M_ARG pSMaxNumCoeff,4
+
+ ;// Code start
+ M_BD_INIT0 ppBitStream, pOffset, RBitStream, RBitBuffer, RBitCount
+ LDR pVLDTable, =armVCM4P10_CAVLCCoeffTokenTables
+ M_LDR nC, pNC
+
+ M_BD_INIT1 T1, T2, lr
+ LDR pVLDTable, [pVLDTable, nC, LSL #2] ;// Find VLD table
+
+ M_BD_INIT2 T1, T2, lr
+
+ ;// Decode Symbol = TotalCoeff*4 + TrailingOnes
+ M_BD_VLD Symbol, T1, T2, pVLDTable, 4, 2
+
+ MOVS TotalCoeff, Symbol, LSR #2
+ STRB TotalCoeff, [pNumCoeff]
+ M_PRINTF "TotalCoeff=%d\n", TotalCoeff
+ BEQ.W EndNoError ;// Finished if no coefficients
+
+ CMP Symbol, #17*4
+ BGE.W EndBadSymbol ;// Error if bad symbol
+
+ ;// Save bitstream pointers
+ M_STR ppBitStream, pppBitStream
+ M_STR pOffset, ppOffset
+ M_STR ppPosCoefbuf, pppPosCoefbuf
+
+ ;// Decode Trailing Ones
+ ANDS TrailingOnes, Symbol, #3
+ M_ADR pLevel, ppLevel
+ M_PRINTF "TrailingOnes=%d\n", TrailingOnes
+ BEQ TrailingOnesDone
+ MOV Count, TrailingOnes
+TrailingOnesLoop
+ M_BD_READ8 Symbol, 1, T1
+ SUBS Count, Count, #1
+ MOV T1, #1
+ SUB T1, T1, Symbol, LSL #1
+ M_PRINTF "Level=%d\n", T1
+ STRH T1, [pLevel], #2
+ BGT TrailingOnesLoop
+TrailingOnesDone
+
+ ;// Decode level values
+ SUBS Count, TotalCoeff, TrailingOnes ;// Number of levels to read
+ BEQ DecodeRuns ;// None left
+
+ MOV SuffixLength, #1
+ CMP TotalCoeff, #10
+ MOVLE SuffixLength, #0
+ CMP TrailingOnes, #3 ;// if (TrailingOnes<3)
+ MOVLT TrailingOnes, #4 ;// then TrailingOnes = +4
+ MOVGE TrailingOnes, #2 ;// else TrailingOnes = +2
+ MOVGE SuffixLength, #0 ;// SuffixLength = 0
+
+LevelLoop
+ M_BD_CLZ16 Symbol, T1, T2 ;// Symbol=LevelPrefix
+ CMP Symbol,#16
+ BGE EndBadSymbol
+
+ MOVS lr, SuffixLength ;// if LevelSuffixSize==0
+ TEQEQ Symbol, #14 ;// and LevelPrefix==14
+ MOVEQ lr, #4 ;// then LevelSuffixSize=4
+ TEQ Symbol, #15 ;// if LevelSuffixSize==15
+ MOVEQ lr, #12 ;// then LevelSuffixSize=12
+
+ TEQEQ SuffixLength,#0
+ ADDEQ Symbol,Symbol,#15
+
+ TEQ lr, #0 ;// if LevelSuffixSize==0
+ BEQ LevelCodeRead ;// LevelCode = LevelPrefix
+
+ M_BD_VREAD16 LevelSuffix, lr, T1, T2 ;// Read Level Suffix
+
+ MOV Symbol, Symbol, LSL SuffixLength
+ ADD Symbol, LevelSuffix, Symbol
+
+LevelCodeRead
+ ;// Symbol = LevelCode
+ ADD Symbol, Symbol, TrailingOnes ;// +4 if level cannot be +/-1, +2 o/w
+ MOV TrailingOnes, #2
+ MOVS T1, Symbol, LSR #1
+ RSBCS T1, T1, #0 ;// If Symbol odd then negate
+ M_PRINTF "Level=%d\n", T1
+ STRH T1, [pLevel], #2 ;// Store level.
+
+ LDR T2, =armVCM4P10_SuffixToLevel
+ LDRSB T1, [T2, SuffixLength] ;// Find increment level
+ TEQ SuffixLength, #0
+ MOVEQ SuffixLength, #1
+ CMP Symbol, T1
+ ADDCS SuffixLength, SuffixLength, #1
+ SUBS Count, Count, #1
+ BGT LevelLoop
+
+DecodeRuns
+ ;// Find number of zeros
+ M_LDR T1, pSMaxNumCoeff ;// sMaxNumCoeff
+ SUB Count, TotalCoeff, #1 ;// Number of runs excluding last
+ SUBS ZerosLeft, T1, TotalCoeff ;// Maximum number of zeros there could be
+ M_ADR pRun, ppRun
+ MOV CoeffNum,TotalCoeff
+ SUB CoeffNum,CoeffNum,#1
+ BEQ NoZerosLeft
+
+ ;// Unpack number of zeros from bitstream
+ TEQ T1, #4
+ LDREQ pVLDTable, =(armVCM4P10_CAVLCTotalZeros2x2Tables-4)
+ LDRNE pVLDTable, =(armVCM4P10_CAVLCTotalZeroTables-4)
+ LDR pVLDTable, [pVLDTable, TotalCoeff, LSL #2]
+
+ M_BD_VLD Symbol, T1, T2, pVLDTable, 4, 2 ;// Symbol = ZerosLeft
+ CMP Symbol,#16
+ BGE EndBadSymbol
+
+ LDR ppRunTable, =(armVCM4P10_CAVLCRunBeforeTables-4)
+ M_ADR pRun, ppRun
+ MOVS ZerosLeft, Symbol
+
+ ADD CoeffNum,CoeffNum,ZerosLeft
+
+ BEQ NoZerosLeft
+
+ ;// Decode runs while zeros are left and more than one coefficient
+RunLoop
+ SUBS Count, Count, #1
+ LDR pVLDTable, [ppRunTable, ZerosLeft, LSL#2]
+ BLT LastRun
+ M_BD_VLD Symbol, T1, T2, pVLDTable, 3, 2 ;// Symbol = Run
+ CMP Symbol,#15
+ BGE EndBadSymbol
+
+ SUBS ZerosLeft, ZerosLeft, Symbol
+ M_PRINTF "Run=%d\n", Symbol
+ STRB Symbol, [pRun], #1
+ BGT RunLoop
+
+ ;// Decode runs while no zeros are left
+NoZerosLeft
+ SUBS Count, Count, #1
+ M_PRINTF "Run=%d\n", ZerosLeft
+ STRGEB ZerosLeft, [pRun], #1
+ BGT NoZerosLeft
+
+LastRun
+ ;// Final run length is remaining zeros
+ M_PRINTF "LastRun=%d\n", ZerosLeft
+ STRB ZerosLeft, [pRun], #1
+
+ ;// Write coefficients to output array
+ M_LDR T1, pSMaxNumCoeff ;// sMaxNumCoeff
+ TEQ T1, #15
+ ADDEQ CoeffNum,CoeffNum,#1
+
+
+ SUB pRun,pRun,TotalCoeff
+ SUB pLevel,pLevel,TotalCoeff
+ SUB pLevel,pLevel,TotalCoeff
+
+ M_LDR ppPosCoefbuf, pppPosCoefbuf
+ LDR pPosCoefbuf, [ppPosCoefbuf]
+ TEQ T1, #4
+ LDREQ pZigZag, =armVCM4P10_ZigZag_2x2
+ LDRNE pZigZag, =armVCM4P10_ZigZag_4x4
+
+
+
+OutputLoop
+
+ LDRB T2, [pRun],#1
+ LDRB T1, [pZigZag, CoeffNum]
+ SUB CoeffNum, CoeffNum, #1 ;// Skip Non zero
+ SUB CoeffNum, CoeffNum, T2 ;// Skip Zero run
+
+ LDRSH T2, [pLevel],#2
+
+ SUBS TotalCoeff, TotalCoeff, #1
+ ORREQ T1, T1, #LAST_COEFF
+
+ ADD temp, T2, #128
+ CMP temp, #256
+ ORRCS T1, T1, #TWO_BYTE_COEFF
+
+
+ TEQ TotalCoeff, #0 ;// Preserves carry
+
+ M_PRINTF "Output=%02x %04x\n", T1, T2
+ STRB T1, [pPosCoefbuf], #1
+ STRB T2, [pPosCoefbuf], #1
+ MOV T2, T2, LSR #8
+ STRCSB T2, [pPosCoefbuf], #1
+ BNE OutputLoop
+
+ ;// Finished
+ STR pPosCoefbuf, [ppPosCoefbuf]
+ M_LDR ppBitStream, pppBitStream
+ M_LDR pOffset, ppOffset
+ B EndNoError
+
+EndBadSymbol
+ MOV r0, #OMX_Sts_Err
+ B End
+
+EndNoError
+ ;// Finished reading from the bitstream
+ M_BD_FINI ppBitStream, pOffset
+
+ ;// Set return value
+ MOV r0, #OMX_Sts_NoErr
+End
+ M_END
+
+ ENDIF
+
+ END
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_DequantTables_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_DequantTables_s.s
new file mode 100755
index 0000000..2761600
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_DequantTables_s.s
@@ -0,0 +1,123 @@
+;//
+;//
+;// File Name: armVCM4P10_DequantTables_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 12290
+;// Date: Wednesday, April 9, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ EXPORT armVCM4P10_QPDivTable
+ EXPORT armVCM4P10_VMatrixQPModTable
+ EXPORT armVCM4P10_PosToVCol4x4
+ EXPORT armVCM4P10_PosToVCol2x2
+ EXPORT armVCM4P10_VMatrix
+ EXPORT armVCM4P10_QPModuloTable
+ EXPORT armVCM4P10_VMatrixU16
+
+;// Define the processor variants supported by this file
+
+ M_VARIANTS CortexA8
+
+
+;// Guarding implementation by the processor name
+
+
+ IF CortexA8
+
+
+ M_TABLE armVCM4P10_PosToVCol4x4
+ DCB 0, 2, 0, 2
+ DCB 2, 1, 2, 1
+ DCB 0, 2, 0, 2
+ DCB 2, 1, 2, 1
+
+
+ M_TABLE armVCM4P10_PosToVCol2x2
+ DCB 0, 2
+ DCB 2, 1
+
+
+ M_TABLE armVCM4P10_VMatrix
+ DCB 10, 16, 13
+ DCB 11, 18, 14
+ DCB 13, 20, 16
+ DCB 14, 23, 18
+ DCB 16, 25, 20
+ DCB 18, 29, 23
+
+;//-------------------------------------------------------
+;// This table evaluates the expression [(INT)(QP/6)],
+;// for values of QP from 0 to 51 (inclusive).
+;//-------------------------------------------------------
+
+ M_TABLE armVCM4P10_QPDivTable
+ DCB 0, 0, 0, 0, 0, 0
+ DCB 1, 1, 1, 1, 1, 1
+ DCB 2, 2, 2, 2, 2, 2
+ DCB 3, 3, 3, 3, 3, 3
+ DCB 4, 4, 4, 4, 4, 4
+ DCB 5, 5, 5, 5, 5, 5
+ DCB 6, 6, 6, 6, 6, 6
+ DCB 7, 7, 7, 7, 7, 7
+ DCB 8, 8, 8, 8, 8, 8
+
+;//----------------------------------------------------
+;// This table contains armVCM4P10_VMatrix[QP%6][0] entires,
+;// for values of QP from 0 to 51 (inclusive).
+;//----------------------------------------------------
+
+ M_TABLE armVCM4P10_VMatrixQPModTable
+ DCB 10, 11, 13, 14, 16, 18
+ DCB 10, 11, 13, 14, 16, 18
+ DCB 10, 11, 13, 14, 16, 18
+ DCB 10, 11, 13, 14, 16, 18
+ DCB 10, 11, 13, 14, 16, 18
+ DCB 10, 11, 13, 14, 16, 18
+ DCB 10, 11, 13, 14, 16, 18
+ DCB 10, 11, 13, 14, 16, 18
+ DCB 10, 11, 13, 14, 16, 18
+
+;//-------------------------------------------------------
+;// This table evaluates the modulus expression [QP%6]*6,
+;// for values of QP from 0 to 51 (inclusive).
+;//-------------------------------------------------------
+
+ M_TABLE armVCM4P10_QPModuloTable
+ DCB 0, 6, 12, 18, 24, 30
+ DCB 0, 6, 12, 18, 24, 30
+ DCB 0, 6, 12, 18, 24, 30
+ DCB 0, 6, 12, 18, 24, 30
+ DCB 0, 6, 12, 18, 24, 30
+ DCB 0, 6, 12, 18, 24, 30
+ DCB 0, 6, 12, 18, 24, 30
+ DCB 0, 6, 12, 18, 24, 30
+ DCB 0, 6, 12, 18, 24, 30
+
+;//-------------------------------------------------------
+;// This table contains the invidual byte values stored as
+;// halfwords. This avoids unpacking inside the function
+;//-------------------------------------------------------
+
+ M_TABLE armVCM4P10_VMatrixU16
+ DCW 10, 16, 13
+ DCW 11, 18, 14
+ DCW 13, 20, 16
+ DCW 14, 23, 18
+ DCW 16, 25, 20
+ DCW 18, 29, 23
+
+ ENDIF ;//ARM1136JS
+
+
+
+
+ END
\ No newline at end of file
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_Align_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_Align_unsafe_s.s
new file mode 100755
index 0000000..6e912d7
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_Align_unsafe_s.s
@@ -0,0 +1,236 @@
+;//
+;//
+;// File Name: armVCM4P10_InterpolateLuma_Align_unsafe_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 12290
+;// Date: Wednesday, April 9, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS ARM1136JS
+
+ EXPORT armVCM4P10_InterpolateLuma_HorAlign9x_unsafe
+ EXPORT armVCM4P10_InterpolateLuma_VerAlign4x_unsafe
+
+DEBUG_ON SETL {FALSE}
+
+ IF ARM1136JS
+
+;// Declare input registers
+pSrc RN 0
+srcStep RN 1
+pDst RN 8
+iHeight RN 9
+
+;// Declare inner loop registers
+x RN 7
+x0 RN 7
+x1 RN 10
+x2 RN 11
+Scratch RN 12
+
+;// Function:
+;// armVCM4P10_InterpolateLuma_HorAlign9x_unsafe
+;//
+;// Implements copy from an arbitrary aligned source memory location (pSrc) to a 4 byte aligned
+;// destination pointed by (pDst) for horizontal interpolation.
+;// This function needs to copy 9 bytes in horizontal direction.
+;//
+;// Registers used as input for this function
+;// r0,r1,r8,r9 where r8 containings aligned memory pointer and r9 no rows to copy
+;//
+;// Registers preserved for top level function
+;// r2,r3,r4,r5,r6
+;//
+;// Registers modified by the function
+;// r7,r8,r9,r10,r11,r12
+;//
+;// Output registers
+;// r0 - pointer to the new aligned location which will be used as pSrc
+;// r1 - step size to this aligned location
+
+ ;// Function header
+ M_START armVCM4P10_InterpolateLuma_HorAlign9x_unsafe
+
+ ;// Copy pDst to scratch
+ MOV Scratch, pDst
+
+StartAlignedStackCopy
+ AND x, pSrc, #3
+ BIC pSrc, pSrc, #3
+
+ M_SWITCH x
+ M_CASE Copy0toAligned
+ M_CASE Copy1toAligned
+ M_CASE Copy2toAligned
+ M_CASE Copy3toAligned
+ M_ENDSWITCH
+
+Copy0toAligned
+ LDM pSrc, {x0, x1, x2}
+ SUBS iHeight, iHeight, #1
+ ADD pSrc, pSrc, srcStep
+
+ ;// One cycle stall
+
+ STM pDst!, {x0, x1, x2} ;// Store aligned output row
+ BGT Copy0toAligned
+ B CopyEnd
+
+Copy1toAligned
+ LDM pSrc, {x0, x1, x2}
+ SUBS iHeight, iHeight, #1
+ ADD pSrc, pSrc, srcStep
+
+ ;// One cycle stall
+
+ MOV x0, x0, LSR #8
+ ORR x0, x0, x1, LSL #24
+ MOV x1, x1, LSR #8
+ ORR x1, x1, x2, LSL #24
+ MOV x2, x2, LSR #8
+ STM pDst!, {x0, x1, x2} ;// Store aligned output row
+ BGT Copy1toAligned
+ B CopyEnd
+
+Copy2toAligned
+ LDM pSrc, {x0, x1, x2}
+ SUBS iHeight, iHeight, #1
+ ADD pSrc, pSrc, srcStep
+
+ ;// One cycle stall
+
+ MOV x0, x0, LSR #16
+ ORR x0, x0, x1, LSL #16
+ MOV x1, x1, LSR #16
+ ORR x1, x1, x2, LSL #16
+ MOV x2, x2, LSR #16
+ STM pDst!, {x0, x1, x2} ;// Store aligned output row
+ BGT Copy2toAligned
+ B CopyEnd
+
+Copy3toAligned
+ LDM pSrc, {x0, x1, x2}
+ SUBS iHeight, iHeight, #1
+ ADD pSrc, pSrc, srcStep
+
+ ;// One cycle stall
+
+ MOV x0, x0, LSR #24
+ ORR x0, x0, x1, LSL #8
+ MOV x1, x1, LSR #24
+ ORR x1, x1, x2, LSL #8
+ MOV x2, x2, LSR #24
+ STM pDst!, {x0, x1, x2} ;// Store aligned output row
+ BGT Copy3toAligned
+
+CopyEnd
+
+ MOV pSrc, Scratch
+ MOV srcStep, #12
+
+ M_END
+
+
+;// Function:
+;// armVCM4P10_InterpolateLuma_VerAlign4x_unsafe
+;//
+;// Implements copy from an arbitrary aligned source memory location (pSrc) to an aligned
+;// destination pointed by (pDst) for vertical interpolation.
+;// This function needs to copy 4 bytes in horizontal direction
+;//
+;// Registers used as input for this function
+;// r0,r1,r8,r9 where r8 containings aligned memory pointer and r9 no of rows to copy
+;//
+;// Registers preserved for top level function
+;// r2,r3,r4,r5,r6
+;//
+;// Registers modified by the function
+;// r7,r8,r9,r10,r11,r12
+;//
+;// Output registers
+;// r0 - pointer to the new aligned location which will be used as pSrc
+;// r1 - step size to this aligned location
+
+ ;// Function header
+ M_START armVCM4P10_InterpolateLuma_VerAlign4x_unsafe
+
+ ;// Copy pSrc to stack
+StartVAlignedStackCopy
+ AND x, pSrc, #3
+ BIC pSrc, pSrc, #3
+
+
+ M_SWITCH x
+ M_CASE Copy0toVAligned
+ M_CASE Copy1toVAligned
+ M_CASE Copy2toVAligned
+ M_CASE Copy3toVAligned
+ M_ENDSWITCH
+
+Copy0toVAligned
+ M_LDR x0, [pSrc], srcStep
+ SUBS iHeight, iHeight, #1
+
+ ;// One cycle stall
+
+ STR x0, [pDst], #4 ;// Store aligned output row
+ BGT Copy0toVAligned
+ B CopyVEnd
+
+Copy1toVAligned
+ LDR x1, [pSrc, #4]
+ M_LDR x0, [pSrc], srcStep
+ SUBS iHeight, iHeight, #1
+
+ ;// One cycle stall
+
+ MOV x1, x1, LSL #24
+ ORR x0, x1, x0, LSR #8
+ STR x0, [pDst], #4 ;// Store aligned output row
+ BGT Copy1toVAligned
+ B CopyVEnd
+
+Copy2toVAligned
+ LDR x1, [pSrc, #4]
+ M_LDR x0, [pSrc], srcStep
+ SUBS iHeight, iHeight, #1
+
+ ;// One cycle stall
+
+ MOV x1, x1, LSL #16
+ ORR x0, x1, x0, LSR #16
+ STR x0, [pDst], #4 ;// Store aligned output row
+ BGT Copy2toVAligned
+ B CopyVEnd
+
+Copy3toVAligned
+ LDR x1, [pSrc, #4]
+ M_LDR x0, [pSrc], srcStep
+ SUBS iHeight, iHeight, #1
+
+ ;// One cycle stall
+
+ MOV x1, x1, LSL #8
+ ORR x0, x1, x0, LSR #24
+ STR x0, [pDst], #4 ;// Store aligned output row
+ BGT Copy3toVAligned
+
+CopyVEnd
+
+ SUB pSrc, pDst, #28
+ MOV srcStep, #4
+
+ M_END
+
+
+ ENDIF
+
+ END
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_Copy_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_Copy_unsafe_s.s
new file mode 100755
index 0000000..d275891
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_Copy_unsafe_s.s
@@ -0,0 +1,149 @@
+;//
+;//
+;// File Name: armVCM4P10_InterpolateLuma_Copy_unsafe_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 12290
+;// Date: Wednesday, April 9, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+;// Function:
+;// armVCM4P10_InterpolateLuma_Copy4x4_unsafe
+;//
+;// Implements copy from an arbitrary aligned source memory location (pSrc) to an aligned
+;// destination pointed by (pDst)
+;//
+;// Registers preserved for top level function
+;// r1,r3,r4,r5,r6,r7,r10,r11,r14
+;//
+;// Registers modified by the function
+;// r0,r2,r8,r9,r12
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS ARM1136JS
+
+ EXPORT armVCM4P10_InterpolateLuma_Copy4x4_unsafe
+
+;// Declare input registers
+pSrc RN 0
+srcStep RN 1
+pDst RN 2
+dstStep RN 3
+
+;// Declare other intermediate registers
+x0 RN 4
+x1 RN 5
+x2 RN 8
+x3 RN 9
+Temp RN 12
+
+ IF ARM1136JS
+
+ M_START armVCM4P10_InterpolateLuma_Copy4x4_unsafe, r6
+
+Copy4x4Start
+ ;// Do Copy and branch to EndOfInterpolation
+ AND Temp, pSrc, #3
+ BIC pSrc, pSrc, #3
+
+ M_SWITCH Temp
+ M_CASE Copy4x4Align0
+ M_CASE Copy4x4Align1
+ M_CASE Copy4x4Align2
+ M_CASE Copy4x4Align3
+ M_ENDSWITCH
+
+Copy4x4Align0
+ M_LDR x0, [pSrc], srcStep
+ M_LDR x1, [pSrc], srcStep
+ M_STR x0, [pDst], dstStep
+ M_LDR x2, [pSrc], srcStep
+ M_STR x1, [pDst], dstStep
+ M_LDR x3, [pSrc], srcStep
+ M_STR x2, [pDst], dstStep
+ M_STR x3, [pDst], dstStep
+ B Copy4x4End
+
+Copy4x4Align1
+ LDR x1, [pSrc, #4]
+ M_LDR x0, [pSrc], srcStep
+ LDR x3, [pSrc, #4]
+ M_LDR x2, [pSrc], srcStep
+ MOV x0, x0, LSR #8
+ ORR x0, x0, x1, LSL #24
+ M_STR x0, [pDst], dstStep
+ MOV x2, x2, LSR #8
+ ORR x2, x2, x3, LSL #24
+ LDR x1, [pSrc, #4]
+ M_LDR x0, [pSrc], srcStep
+ M_STR x2, [pDst], dstStep
+ LDR x3, [pSrc, #4]
+ M_LDR x2, [pSrc], srcStep
+ MOV x0, x0, LSR #8
+ ORR x0, x0, x1, LSL #24
+ M_STR x0, [pDst], dstStep
+ MOV x2, x2, LSR #8
+ ORR x2, x2, x3, LSL #24
+ M_STR x2, [pDst], dstStep
+ B Copy4x4End
+
+Copy4x4Align2
+ LDR x1, [pSrc, #4]
+ M_LDR x0, [pSrc], srcStep
+ LDR x3, [pSrc, #4]
+ M_LDR x2, [pSrc], srcStep
+ MOV x0, x0, LSR #16
+ ORR x0, x0, x1, LSL #16
+ M_STR x0, [pDst], dstStep
+ MOV x2, x2, LSR #16
+ ORR x2, x2, x3, LSL #16
+ M_STR x2, [pDst], dstStep
+
+ LDR x1, [pSrc, #4]
+ M_LDR x0, [pSrc], srcStep
+ LDR x3, [pSrc, #4]
+ M_LDR x2, [pSrc], srcStep
+ MOV x0, x0, LSR #16
+ ORR x0, x0, x1, LSL #16
+ M_STR x0, [pDst], dstStep
+ MOV x2, x2, LSR #16
+ ORR x2, x2, x3, LSL #16
+ M_STR x2, [pDst], dstStep
+ B Copy4x4End
+
+Copy4x4Align3
+ LDR x1, [pSrc, #4]
+ M_LDR x0, [pSrc], srcStep
+ LDR x3, [pSrc, #4]
+ M_LDR x2, [pSrc], srcStep
+ MOV x0, x0, LSR #24
+ ORR x0, x0, x1, LSL #8
+ M_STR x0, [pDst], dstStep
+ MOV x2, x2, LSR #24
+ ORR x2, x2, x3, LSL #8
+ M_STR x2, [pDst], dstStep
+
+ LDR x1, [pSrc, #4]
+ M_LDR x0, [pSrc], srcStep
+ LDR x3, [pSrc, #4]
+ M_LDR x2, [pSrc], srcStep
+ MOV x0, x0, LSR #24
+ ORR x0, x0, x1, LSL #8
+ M_STR x0, [pDst], dstStep
+ MOV x2, x2, LSR #24
+ ORR x2, x2, x3, LSL #8
+ M_STR x2, [pDst], dstStep
+ B Copy4x4End
+
+Copy4x4End
+ M_END
+
+ ENDIF
+
+ END
+
\ No newline at end of file
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_DiagCopy_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_DiagCopy_unsafe_s.s
new file mode 100755
index 0000000..4e5a39d
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_DiagCopy_unsafe_s.s
@@ -0,0 +1,178 @@
+;//
+;//
+;// File Name: armVCM4P10_InterpolateLuma_DiagCopy_unsafe_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 12290
+;// Date: Wednesday, April 9, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS ARM1136JS
+
+ EXPORT armVCM4P10_InterpolateLuma_HorDiagCopy_unsafe
+ EXPORT armVCM4P10_InterpolateLuma_VerDiagCopy_unsafe
+
+;// Functions:
+;// armVCM4P10_InterpolateLuma_HorDiagCopy_unsafe and
+;// armVCM4P10_InterpolateLuma_VerDiagCopy_unsafe
+;//
+;// Implements re-arrangement of data from temporary buffer to a buffer pointed by pBuf.
+;// This will do the convertion of data from 16 bit to 8 bit and it also
+;// remove offset and check for saturation.
+;//
+;// Registers used as input for this function
+;// r0,r1,r7 where r0 is input pointer and r2 its step size, r7 is output pointer
+;//
+;// Registers preserved for top level function
+;// r4,r5,r6,r8,r9,r14
+;//
+;// Registers modified by the function
+;// r7,r10,r11,r12
+;//
+;// Output registers
+;// r0 - pointer to the destination location
+;// r1 - step size to this destination location
+
+
+DEBUG_ON SETL {FALSE}
+
+MASK EQU 0x80808080 ;// Mask is used to implement (a+b+1)/2
+
+;// Declare input registers
+
+pSrc0 RN 0
+srcStep0 RN 1
+
+;// Declare other intermediate registers
+Temp1 RN 4
+Temp2 RN 5
+Temp3 RN 10
+Temp4 RN 11
+pBuf RN 7
+r0x0fe00fe0 RN 6
+r0x00ff00ff RN 12
+Count RN 14
+ValueA0 RN 10
+ValueA1 RN 11
+
+ IF ARM1136JS
+
+
+ ;// Function header
+ M_START armVCM4P10_InterpolateLuma_HorDiagCopy_unsafe, r6
+
+ ;// Code start
+ MOV Count, #4
+ LDR r0x0fe00fe0, =0x0fe00fe0
+ LDR r0x00ff00ff, =0x00ff00ff
+LoopStart1
+ LDR Temp4, [pSrc0, #12]
+ LDR Temp3, [pSrc0, #8]
+ LDR Temp2, [pSrc0, #4]
+ M_LDR Temp1, [pSrc0], srcStep0
+ UQSUB16 Temp4, Temp4, r0x0fe00fe0
+ UQSUB16 Temp3, Temp3, r0x0fe00fe0
+ UQSUB16 Temp2, Temp2, r0x0fe00fe0
+ UQSUB16 Temp1, Temp1, r0x0fe00fe0
+ USAT16 Temp4, #13, Temp4
+ USAT16 Temp3, #13, Temp3
+ USAT16 Temp2, #13, Temp2
+ USAT16 Temp1, #13, Temp1
+ AND Temp4, r0x00ff00ff, Temp4, LSR #5
+ AND Temp3, r0x00ff00ff, Temp3, LSR #5
+ AND Temp2, r0x00ff00ff, Temp2, LSR #5
+ AND Temp1, r0x00ff00ff, Temp1, LSR #5
+ ORR ValueA1, Temp3, Temp4, LSL #8
+ ORR ValueA0, Temp1, Temp2, LSL #8
+ SUBS Count, Count, #1
+ STRD ValueA0, [pBuf], #8
+ BGT LoopStart1
+End1
+ SUB pSrc0, pBuf, #32
+ MOV srcStep0, #8
+
+ M_END
+
+
+ ;// Function header
+ M_START armVCM4P10_InterpolateLuma_VerDiagCopy_unsafe, r6
+
+ ;// Code start
+ LDR r0x0fe00fe0, =0x0fe00fe0
+ LDR r0x00ff00ff, =0x00ff00ff
+ MOV Count, #2
+
+LoopStart
+ LDR Temp4, [pSrc0, #12]
+ LDR Temp3, [pSrc0, #8]
+ LDR Temp2, [pSrc0, #4]
+ M_LDR Temp1, [pSrc0], srcStep0
+
+ UQSUB16 Temp4, Temp4, r0x0fe00fe0
+ UQSUB16 Temp3, Temp3, r0x0fe00fe0
+ UQSUB16 Temp2, Temp2, r0x0fe00fe0
+ UQSUB16 Temp1, Temp1, r0x0fe00fe0
+
+ USAT16 Temp4, #13, Temp4
+ USAT16 Temp3, #13, Temp3
+ USAT16 Temp2, #13, Temp2
+ USAT16 Temp1, #13, Temp1
+
+ AND Temp4, r0x00ff00ff, Temp4, LSR #5
+ AND Temp3, r0x00ff00ff, Temp3, LSR #5
+ AND Temp2, r0x00ff00ff, Temp2, LSR #5
+ AND Temp1, r0x00ff00ff, Temp1, LSR #5
+ ORR ValueA1, Temp3, Temp4, LSL #8 ;// [d2 c2 d0 c0]
+ ORR ValueA0, Temp1, Temp2, LSL #8 ;// [b2 a2 b0 a0]
+
+ PKHBT Temp1, ValueA0, ValueA1, LSL #16 ;// [d0 c0 b0 a0]
+
+ STR Temp1, [pBuf], #8
+ PKHTB Temp2, ValueA1, ValueA0, ASR #16 ;// [d2 c2 b2 a2]
+ STR Temp2, [pBuf], #-4
+
+ LDR Temp4, [pSrc0, #12]
+ LDR Temp3, [pSrc0, #8]
+ LDR Temp2, [pSrc0, #4]
+ M_LDR Temp1, [pSrc0], srcStep0
+
+ UQSUB16 Temp4, Temp4, r0x0fe00fe0
+ UQSUB16 Temp3, Temp3, r0x0fe00fe0
+ UQSUB16 Temp2, Temp2, r0x0fe00fe0
+ UQSUB16 Temp1, Temp1, r0x0fe00fe0
+
+ USAT16 Temp4, #13, Temp4
+ USAT16 Temp3, #13, Temp3
+ USAT16 Temp2, #13, Temp2
+ USAT16 Temp1, #13, Temp1
+
+ AND Temp4, r0x00ff00ff, Temp4, LSR #5
+ AND Temp3, r0x00ff00ff, Temp3, LSR #5
+ AND Temp2, r0x00ff00ff, Temp2, LSR #5
+ AND Temp1, r0x00ff00ff, Temp1, LSR #5
+ ORR ValueA1, Temp3, Temp4, LSL #8 ;// [d2 c2 d0 c0]
+ ORR ValueA0, Temp1, Temp2, LSL #8 ;// [b2 a2 b0 a0]
+
+ PKHBT Temp1, ValueA0, ValueA1, LSL #16 ;// [d0 c0 b0 a0]
+ SUBS Count, Count, #1
+ STR Temp1, [pBuf], #8
+ PKHTB Temp2, ValueA1, ValueA0, ASR #16 ;// [d2 c2 b2 a2]
+ STR Temp2, [pBuf], #4
+
+ BGT LoopStart
+End2
+ SUB pSrc0, pBuf, #32-8
+ MOV srcStep0, #4
+
+ M_END
+
+ ENDIF
+
+ END
+
\ No newline at end of file
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe_s.s
new file mode 100755
index 0000000..d1684cb
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe_s.s
@@ -0,0 +1,313 @@
+;//
+;//
+;// File Name: armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 12290
+;// Date: Wednesday, April 9, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ EXPORT armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe
+
+ M_VARIANTS CortexA8
+
+ IF CortexA8
+
+ M_START armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe, r11
+
+;// Declare input registers
+pSrc RN 0
+srcStep RN 1
+pDst RN 2
+dstStep RN 3
+
+;// Declare Neon registers
+dCoeff5 DN 30.S16
+dCoeff20 DN 31.S16
+qCoeff5 QN 14.S32
+qCoeff20 QN 15.S32
+
+qSrc01 QN 0.U8
+dSrc0 DN 0.U8
+dSrc1 DN 1.U8
+
+dSrcb DN 4.U8
+dSrcc DN 2.U8
+dSrcd DN 3.U8
+dSrce DN 5.U8
+dSrcf DN 1.U8
+
+qSrcb QN 2.S16
+qSrcc QN 1.S16
+dSrcB DN 4.S16
+dSrcC DN 2.S16
+
+qRes0 QN 5.S16
+qRes1 QN 6.S16
+qRes2 QN 7.S16
+qRes3 QN 8.S16
+qRes4 QN 9.S16
+qRes5 QN 10.S16
+qRes6 QN 11.S16
+qRes7 QN 12.S16
+qRes8 QN 13.S16
+
+dRes0 DN 10.S16
+dRes1 DN 12.S16
+dRes2 DN 14.S16
+dRes3 DN 16.S16
+dRes4 DN 18.S16
+dRes5 DN 20.S16
+dRes6 DN 22.S16
+dRes7 DN 24.S16
+dRes8 DN 26.S16
+
+qAcc01 QN 5.S32
+qAcc23 QN 6.S32
+qAcc45 QN 2.S32
+qAcc67 QN 3.S32
+qSumBE QN 0.S32
+qSumCD QN 1.S32
+
+dTempAcc0 DN 0.U16
+dTempAcc1 DN 2.U16
+dTempAcc2 DN 4.U16
+dTempAcc3 DN 6.U16
+
+qTAcc0 QN 0.U16
+qTAcc1 QN 1.U16
+qTAcc2 QN 2.U16
+qTAcc3 QN 3.U16
+
+dAcc0 DN 0.U8
+dAcc1 DN 2.U8
+dAcc2 DN 4.U8
+dAcc3 DN 6.U8
+
+dTmp0 DN 8.S16
+dTmp1 DN 9.S16
+qTmp0 QN 4.S32
+
+ VLD1 qSrc01, [pSrc], srcStep ;// [a0 a1 a2 a3 ..]
+ VMOV dCoeff20, #20
+ VMOV dCoeff5, #5
+
+ ;// Row0
+ VEXT dSrcb, dSrc0, dSrc1, #1 ;// [b0 b1 b2 b3 ..]
+ VEXT dSrcc, dSrc0, dSrc1, #2
+ VEXT dSrcd, dSrc0, dSrc1, #3
+ VEXT dSrce, dSrc0, dSrc1, #4
+ VEXT dSrcf, dSrc0, dSrc1, #5 ;// [f0 f1 f2 f3 ..]
+ VADDL qSrcc, dSrcc, dSrcd ;// c+d
+ VADDL qSrcb, dSrcb, dSrce ;// b+e
+ VADDL qRes0, dSrc0, dSrcf ;// Acc=a+f
+ VLD1 qSrc01, [pSrc], srcStep ;// [a0 a1 a2 a3 ..]
+ VMLA dRes0, dSrcC, dCoeff20 ;// Acc += 20*(c+d)
+; VMLS dRes0, dSrcB, dCoeff5 ;// Acc -= 5*(b+e)
+ VMUL dTmp0, dSrcB, dCoeff5 ;// Acc -= 5*(b+e)
+
+ ;// Row1
+ VEXT dSrcb, dSrc0, dSrc1, #1 ;// [b0 b1 b2 b3 ..]
+ VEXT dSrcc, dSrc0, dSrc1, #2
+ VEXT dSrcd, dSrc0, dSrc1, #3
+ VEXT dSrce, dSrc0, dSrc1, #4
+ VEXT dSrcf, dSrc0, dSrc1, #5 ;// [f0 f1 f2 f3 ..]
+ VADDL qSrcc, dSrcc, dSrcd ;// c+d
+ VADDL qSrcb, dSrcb, dSrce ;// b+e
+ VADDL qRes1, dSrc0, dSrcf ;// Acc=a+f
+ VLD1 qSrc01, [pSrc], srcStep ;// [a0 a1 a2 a3 ..]
+
+ VSUB dRes0, dRes0, dTmp0 ;// TeRi
+
+ VMLA dRes1, dSrcC, dCoeff20 ;// Acc += 20*(c+d)
+; VMLS dRes1, dSrcB, dCoeff5 ;// Acc -= 5*(b+e)
+ VMUL dTmp0, dSrcB, dCoeff5 ;// Acc -= 5*(b+e)
+
+ ;// Row2
+ VEXT dSrcb, dSrc0, dSrc1, #1 ;// [b0 b1 b2 b3 ..]
+ VEXT dSrcc, dSrc0, dSrc1, #2
+ VEXT dSrcd, dSrc0, dSrc1, #3
+ VEXT dSrce, dSrc0, dSrc1, #4
+ VEXT dSrcf, dSrc0, dSrc1, #5 ;// [f0 f1 f2 f3 ..]
+ VADDL qSrcc, dSrcc, dSrcd ;// c+d
+ VADDL qSrcb, dSrcb, dSrce ;// b+e
+ VADDL qRes2, dSrc0, dSrcf ;// Acc=a+f
+ VLD1 qSrc01, [pSrc], srcStep ;// [a0 a1 a2 a3 ..]
+
+ VSUB dRes1, dRes1, dTmp0
+
+ VMLA dRes2, dSrcC, dCoeff20 ;// Acc += 20*(c+d)
+; VMLS dRes2, dSrcB, dCoeff5 ;// Acc -= 5*(b+e)
+ VMUL dTmp0, dSrcB, dCoeff5 ;// Acc -= 5*(b+e)
+
+ ;// Row3
+ VEXT dSrcb, dSrc0, dSrc1, #1 ;// [b0 b1 b2 b3 ..]
+ VEXT dSrcc, dSrc0, dSrc1, #2
+ VEXT dSrcd, dSrc0, dSrc1, #3
+ VEXT dSrce, dSrc0, dSrc1, #4
+ VEXT dSrcf, dSrc0, dSrc1, #5 ;// [f0 f1 f2 f3 ..]
+ VADDL qSrcc, dSrcc, dSrcd ;// c+d
+ VADDL qSrcb, dSrcb, dSrce ;// b+e
+ VADDL qRes3, dSrc0, dSrcf ;// Acc=a+f
+ VLD1 qSrc01, [pSrc], srcStep ;// [a0 a1 a2 a3 ..]
+
+ VSUB dRes2, dRes2, dTmp0
+
+ VMLA dRes3, dSrcC, dCoeff20 ;// Acc += 20*(c+d)
+; VMLS dRes3, dSrcB, dCoeff5 ;// Acc -= 5*(b+e)
+ VMUL dTmp0, dSrcB, dCoeff5 ;// Acc -= 5*(b+e)
+
+ ;// Row4
+ VEXT dSrcb, dSrc0, dSrc1, #1 ;// [b0 b1 b2 b3 ..]
+ VEXT dSrcc, dSrc0, dSrc1, #2
+ VEXT dSrcd, dSrc0, dSrc1, #3
+ VEXT dSrce, dSrc0, dSrc1, #4
+ VEXT dSrcf, dSrc0, dSrc1, #5 ;// [f0 f1 f2 f3 ..]
+ VADDL qSrcc, dSrcc, dSrcd ;// c+d
+ VADDL qSrcb, dSrcb, dSrce ;// b+e
+ VADDL qRes4, dSrc0, dSrcf ;// Acc=a+f
+ VLD1 qSrc01, [pSrc], srcStep ;// [a0 a1 a2 a3 ..]
+
+ VSUB dRes3, dRes3, dTmp0
+
+ VMLA dRes4, dSrcC, dCoeff20 ;// Acc += 20*(c+d)
+; VMLS dRes4, dSrcB, dCoeff5 ;// Acc -= 5*(b+e)
+ VMUL dTmp0, dSrcB, dCoeff5 ;// Acc -= 5*(b+e)
+
+ ;// Row5
+ VEXT dSrcb, dSrc0, dSrc1, #1 ;// [b0 b1 b2 b3 ..]
+ VEXT dSrcc, dSrc0, dSrc1, #2
+ VEXT dSrcd, dSrc0, dSrc1, #3
+ VEXT dSrce, dSrc0, dSrc1, #4
+ VEXT dSrcf, dSrc0, dSrc1, #5 ;// [f0 f1 f2 f3 ..]
+ VADDL qSrcc, dSrcc, dSrcd ;// c+d
+ VADDL qSrcb, dSrcb, dSrce ;// b+e
+ VADDL qRes5, dSrc0, dSrcf ;// Acc=a+f
+ VLD1 qSrc01, [pSrc], srcStep ;// [a0 a1 a2 a3 ..]
+
+ VSUB dRes4, dRes4, dTmp0
+
+ VMLA dRes5, dSrcC, dCoeff20 ;// Acc += 20*(c+d)
+; VMLS dRes5, dSrcB, dCoeff5 ;// Acc -= 5*(b+e)
+ VMUL dTmp0, dSrcB, dCoeff5 ;// Acc -= 5*(b+e)
+
+ ;// Row6
+ VEXT dSrcb, dSrc0, dSrc1, #1 ;// [b0 b1 b2 b3 ..]
+ VEXT dSrcc, dSrc0, dSrc1, #2
+ VEXT dSrcd, dSrc0, dSrc1, #3
+ VEXT dSrce, dSrc0, dSrc1, #4
+ VEXT dSrcf, dSrc0, dSrc1, #5 ;// [f0 f1 f2 f3 ..]
+ VADDL qSrcc, dSrcc, dSrcd ;// c+d
+ VADDL qSrcb, dSrcb, dSrce ;// b+e
+ VADDL qRes6, dSrc0, dSrcf ;// Acc=a+f
+ VLD1 qSrc01, [pSrc], srcStep ;// [a0 a1 a2 a3 ..]
+
+ VSUB dRes5, dRes5, dTmp0
+
+ VMLA dRes6, dSrcC, dCoeff20 ;// Acc += 20*(c+d)
+; VMLS dRes6, dSrcB, dCoeff5 ;// Acc -= 5*(b+e)
+ VMUL dTmp0, dSrcB, dCoeff5 ;// Acc -= 5*(b+e)
+
+ ;// Row7
+ VEXT dSrcb, dSrc0, dSrc1, #1 ;// [b0 b1 b2 b3 ..]
+ VEXT dSrcc, dSrc0, dSrc1, #2
+ VEXT dSrcd, dSrc0, dSrc1, #3
+ VEXT dSrce, dSrc0, dSrc1, #4
+ VEXT dSrcf, dSrc0, dSrc1, #5 ;// [f0 f1 f2 f3 ..]
+ VADDL qSrcc, dSrcc, dSrcd ;// c+d
+ VADDL qSrcb, dSrcb, dSrce ;// b+e
+ VADDL qRes7, dSrc0, dSrcf ;// Acc=a+f
+ VLD1 qSrc01, [pSrc], srcStep ;// [a0 a1 a2 a3 ..]
+
+ VSUB dRes6, dRes6, dTmp0
+
+ VMLA dRes7, dSrcC, dCoeff20 ;// Acc += 20*(c+d)
+; VMLS dRes7, dSrcB, dCoeff5 ;// Acc -= 5*(b+e)
+ VMUL dTmp0, dSrcB, dCoeff5 ;// Acc -= 5*(b+e)
+
+ ;// Row8
+ VEXT dSrcb, dSrc0, dSrc1, #1 ;// [b0 b1 b2 b3 ..]
+ VEXT dSrcc, dSrc0, dSrc1, #2
+ VEXT dSrcd, dSrc0, dSrc1, #3
+ VEXT dSrce, dSrc0, dSrc1, #4
+ VEXT dSrcf, dSrc0, dSrc1, #5 ;// [f0 f1 f2 f3 ..]
+ VADDL qSrcc, dSrcc, dSrcd ;// c+d
+ VADDL qSrcb, dSrcb, dSrce ;// b+e
+ VADDL qRes8, dSrc0, dSrcf ;// Acc=a+f
+
+ VSUB dRes7, dRes7, dTmp0
+
+ VMLA dRes8, dSrcC, dCoeff20 ;// Acc += 20*(c+d)
+; VMLS dRes8, dSrcB, dCoeff5 ;// Acc -= 5*(b+e)
+ VMUL dTmp0, dSrcB, dCoeff5 ;// Acc -= 5*(b+e)
+
+ VMOV qCoeff20, #20
+ VMOV qCoeff5, #5
+
+ ;// Col0
+ VADDL qAcc01, dRes0, dRes5 ;// Acc = a+f
+ VADDL qSumCD, dRes2, dRes3 ;// c+d
+ VADDL qSumBE, dRes1, dRes4 ;// b+e
+
+ VSUB dRes8, dRes8, dTmp0
+
+ VMLA qAcc01, qSumCD, qCoeff20 ;// Acc += 20*(c+d)
+; VMLS qAcc01, qSumBE, qCoeff5 ;// Acc -= 20*(b+e)
+ VMUL qTmp0, qSumBE, qCoeff5 ;// Acc -= 20*(b+e)
+
+ ;// Col1
+ VADDL qAcc23, dRes1, dRes6 ;// Acc = a+f
+ VADDL qSumCD, dRes3, dRes4 ;// c+d
+ VADDL qSumBE, dRes2, dRes5 ;// b+e
+ VMLA qAcc23, qSumCD, qCoeff20 ;// Acc += 20*(c+d)
+
+ VSUB qAcc01, qAcc01, qTmp0
+
+; VMLS qAcc23, qSumBE, qCoeff5 ;// Acc -= 20*(b+e)
+ VMUL qTmp0, qSumBE, qCoeff5 ;// Acc -= 20*(b+e)
+
+ ;// Col2
+ VADDL qAcc45, dRes2, dRes7 ;// Acc = a+f
+ VADDL qSumCD, dRes4, dRes5 ;// c+d
+ VADDL qSumBE, dRes3, dRes6 ;// b+e
+ VMLA qAcc45, qSumCD, qCoeff20 ;// Acc += 20*(c+d)
+
+ VSUB qAcc23, qAcc23, qTmp0
+
+; VMLS qAcc45, qSumBE, qCoeff5 ;// Acc -= 20*(b+e)
+ VMUL qTmp0, qSumBE, qCoeff5 ;// Acc -= 20*(b+e)
+
+ ;// Col3
+ VADDL qAcc67, dRes3, dRes8 ;// Acc = a+f
+ VADDL qSumCD, dRes5, dRes6 ;// c+d
+ VADDL qSumBE, dRes4, dRes7 ;// b+e
+ VMLA qAcc67, qSumCD, qCoeff20 ;// Acc += 20*(c+d)
+
+ VSUB qAcc45, qAcc45, qTmp0
+
+ VMLS qAcc67, qSumBE, qCoeff5 ;// Acc -= 20*(b+e)
+
+ VQRSHRUN dTempAcc0, qAcc01, #10
+ VQRSHRUN dTempAcc1, qAcc23, #10
+ VQRSHRUN dTempAcc2, qAcc45, #10
+ VQRSHRUN dTempAcc3, qAcc67, #10
+
+ VQMOVN dAcc0, qTAcc0
+ VQMOVN dAcc1, qTAcc1
+ VQMOVN dAcc2, qTAcc2
+ VQMOVN dAcc3, qTAcc3
+
+ M_END
+
+ ENDIF
+
+
+
+ END
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe_s.s
new file mode 100755
index 0000000..7bc091f
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe_s.s
@@ -0,0 +1,266 @@
+;//
+;//
+;// File Name: armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 12290
+;// Date: Wednesday, April 9, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ EXPORT armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe
+
+ M_VARIANTS CortexA8
+
+ IF CortexA8
+ M_START armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe, r11
+
+;// Declare input registers
+pSrc RN 0
+srcStep RN 1
+pDst RN 2
+dstStep RN 3
+
+;// Declare Neon registers
+dTCoeff5 DN 30.U8
+dTCoeff20 DN 31.U8
+dCoeff5 DN 30.S16
+dCoeff20 DN 31.S16
+
+qSrcA01 QN 0.U8
+qSrcB23 QN 1.U8
+qSrcC45 QN 2.U8
+qSrcD67 QN 3.U8
+qSrcE89 QN 4.U8
+qSrcF1011 QN 5.U8
+qSrcG1213 QN 6.U8
+qSrcH1415 QN 7.U8
+qSrcI1617 QN 8.U8
+
+dSrcA0 DN 0.U8
+dSrcB2 DN 2.U8
+dSrcC4 DN 4.U8
+dSrcD6 DN 6.U8
+dSrcE8 DN 8.U8
+dSrcF10 DN 10.U8
+dSrcG12 DN 12.U8
+dSrcH14 DN 14.U8
+dSrcI16 DN 16.U8
+
+dSrcA1 DN 1.U8
+dSrcB3 DN 3.U8
+dSrcC5 DN 5.U8
+dSrcD7 DN 7.U8
+dSrcE9 DN 9.U8
+dSrcF11 DN 11.U8
+dSrcG13 DN 13.U8
+dSrcH15 DN 15.U8
+dSrcI17 DN 17.U8
+
+qTempP01 QN 9.S16
+qTempQ01 QN 10.S16
+qTempR01 QN 11.S16
+qTempS01 QN 12.S16
+
+qTempP23 QN 0.S16
+qTempQ23 QN 1.S16
+qTempR23 QN 2.S16
+qTempS23 QN 3.S16
+
+dTempP0 DN 18.S16
+dTempP1 DN 19.S16
+dTempP2 DN 0.S16
+
+dTempQ0 DN 20.S16
+dTempQ1 DN 21.S16
+dTempQ2 DN 2.S16
+
+dTempR0 DN 22.S16
+dTempR1 DN 23.S16
+dTempR2 DN 4.S16
+
+dTempS0 DN 24.S16
+dTempS1 DN 25.S16
+dTempS2 DN 6.S16
+
+dTempB0 DN 26.S16
+dTempC0 DN 27.S16
+dTempD0 DN 28.S16
+dTempF0 DN 29.S16
+
+dTempAcc0 DN 0.U16
+dTempAcc1 DN 2.U16
+dTempAcc2 DN 4.U16
+dTempAcc3 DN 6.U16
+
+dAcc0 DN 0.U8
+dAcc1 DN 2.U8
+dAcc2 DN 4.U8
+dAcc3 DN 6.U8
+
+qAcc0 QN 0.S32
+qAcc1 QN 1.S32
+qAcc2 QN 2.S32
+qAcc3 QN 3.S32
+
+qTAcc0 QN 0.U16
+qTAcc1 QN 1.U16
+qTAcc2 QN 2.U16
+qTAcc3 QN 3.U16
+
+qTmp QN 4.S16
+dTmp DN 8.S16
+
+ VLD1 qSrcA01, [pSrc], srcStep ;// [a0 a1 a2 a3 .. a15]
+ ADD r12, pSrc, srcStep, LSL #2
+ VMOV dTCoeff5, #5
+ VMOV dTCoeff20, #20
+ VLD1 qSrcF1011, [r12], srcStep
+ VLD1 qSrcB23, [pSrc], srcStep ;// [b0 b1 b2 b3 .. b15]
+
+ VLD1 qSrcG1213, [r12], srcStep
+ VADDL qTempP01, dSrcA0, dSrcF10
+ VLD1 qSrcC45, [pSrc], srcStep ;// [c0 c1 c2 c3 .. c15]
+ VADDL qTempP23, dSrcA1, dSrcF11
+ VLD1 qSrcD67, [pSrc], srcStep
+ VADDL qTempQ01, dSrcB2, dSrcG12
+ VLD1 qSrcE89, [pSrc], srcStep
+
+ ;//t0
+ VMLAL qTempP01, dSrcC4, dTCoeff20
+
+ VLD1 qSrcH1415, [r12], srcStep
+
+ VMLAL qTempP23, dSrcC5, dTCoeff20
+
+ VLD1 qSrcI1617, [r12], srcStep ;// [i0 i1 i2 i3 .. ]
+
+ VMLAL qTempP01, dSrcD6, dTCoeff20
+ VMLAL qTempQ01, dSrcD6, dTCoeff20
+ VMLSL qTempP23, dSrcB3, dTCoeff5
+
+ VADDL qTempR01, dSrcC4, dSrcH14
+
+ VMLSL qTempP01, dSrcB2, dTCoeff5
+
+ VADDL qTempQ23, dSrcB3, dSrcG13
+
+ VMLAL qTempP23, dSrcD7, dTCoeff20
+ VMLAL qTempQ01, dSrcE8, dTCoeff20
+
+ VMLSL qTempP01, dSrcE8, dTCoeff5
+ VMLAL qTempQ23, dSrcD7, dTCoeff20
+
+ VMLSL qTempP23, dSrcE9, dTCoeff5
+
+ ;//t1
+
+ VMLAL qTempR01, dSrcE8, dTCoeff20
+ VMLSL qTempQ01, dSrcC4, dTCoeff5
+ VMLSL qTempQ23, dSrcC5, dTCoeff5
+ VADDL qTempR23, dSrcC5, dSrcH15
+
+ VMLAL qTempR01, dSrcF10, dTCoeff20
+ VMLSL qTempQ01, dSrcF10, dTCoeff5
+ VMLAL qTempQ23, dSrcE9, dTCoeff20
+ VMLAL qTempR23, dSrcE9, dTCoeff20
+ VADDL qTempS01, dSrcD6, dSrcI16
+
+
+ VMLSL qTempR01, dSrcD6, dTCoeff5
+ VMLSL qTempQ23, dSrcF11, dTCoeff5
+ VMLSL qTempR23, dSrcD7, dTCoeff5
+
+ ;//t2
+ VADDL qTempS23, dSrcD7, dSrcI17
+ VMLAL qTempS01, dSrcF10, dTCoeff20
+ VMLSL qTempR01, dSrcG12, dTCoeff5
+ VMLSL qTempR23, dSrcG13, dTCoeff5
+
+ VMLAL qTempS23, dSrcF11, dTCoeff20
+ VMLAL qTempS01, dSrcG12, dTCoeff20
+ VEXT dTempB0, dTempP0, dTempP1, #1
+ VMLAL qTempR23, dSrcF11, dTCoeff20
+
+
+ ;//t3
+ VMLAL qTempS23, dSrcG13, dTCoeff20
+ VMLSL qTempS01, dSrcE8, dTCoeff5
+ VEXT dTempC0, dTempP0, dTempP1, #2
+ VMOV dCoeff20, #20
+ VMLSL qTempS23, dSrcE9, dTCoeff5
+ VMLSL qTempS01, dSrcH14, dTCoeff5
+ VEXT dTempF0, dTempP1, dTempP2, #1
+ VEXT dTempD0, dTempP0, dTempP1, #3
+ VMLSL qTempS23, dSrcH15, dTCoeff5
+
+ VADDL qAcc0, dTempP0, dTempF0
+ VADD dTempC0, dTempC0, dTempD0
+ ;//h
+ VMOV dCoeff5, #5
+
+ ;// res0
+ VADD dTempB0, dTempB0, dTempP1
+ VMLAL qAcc0, dTempC0, dCoeff20
+ VEXT dTempC0, dTempQ0, dTempQ1, #2
+ VEXT dTempD0, dTempQ0, dTempQ1, #3
+ VEXT dTempF0, dTempQ1, dTempQ2, #1
+ VMLSL qAcc0, dTempB0, dCoeff5
+
+ ;// res1
+ VEXT dTempB0, dTempQ0, dTempQ1, #1
+ VADDL qAcc1, dTempQ0, dTempF0
+ VADD dTempC0, dTempC0, dTempD0
+ VADD dTempB0, dTempB0, dTempQ1
+ VEXT dTempD0, dTempR0, dTempR1, #3
+ VMLAL qAcc1, dTempC0, dCoeff20
+ VEXT dTempF0, dTempR1, dTempR2, #1
+ VEXT dTempC0, dTempR0, dTempR1, #2
+ VEXT dTmp, dTempR0, dTempR1, #1
+ VADDL qAcc2, dTempR0, dTempF0
+ VMLSL qAcc1, dTempB0, dCoeff5
+; VEXT dTempB0, dTempR0, dTempR1, #1
+ VADD dTempC0, dTempC0, dTempD0
+
+ ;// res2
+ VADD dTempB0, dTmp, dTempR1
+ VEXT dTempD0, dTempS0, dTempS1, #3
+ VMLAL qAcc2, dTempC0, dCoeff20
+; VADD dTempB0, dTempB0, dTempR1
+
+ ;// res3
+ VEXT dTempC0, dTempS0, dTempS1, #2
+ VEXT dTempF0, dTempS1, dTempS2, #1
+ VADD dTempC0, dTempC0, dTempD0
+ VEXT dTmp, dTempS0, dTempS1, #1
+ VADDL qAcc3, dTempS0, dTempF0
+ VMLSL qAcc2, dTempB0, dCoeff5
+ VMLAL qAcc3, dTempC0, dCoeff20
+ VADD dTmp, dTmp, dTempS1
+ VMLSL qAcc3, dTmp, dCoeff5
+
+ VQRSHRUN dTempAcc0, qAcc0, #10
+ VQRSHRUN dTempAcc1, qAcc1, #10
+ VQRSHRUN dTempAcc2, qAcc2, #10
+ VQRSHRUN dTempAcc3, qAcc3, #10
+
+ VQMOVN dAcc0, qTAcc0
+ VQMOVN dAcc1, qTAcc1
+ VQMOVN dAcc2, qTAcc2
+ VQMOVN dAcc3, qTAcc3
+
+ M_END
+
+ ENDIF
+
+
+
+
+
+ END
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe_s.s
new file mode 100755
index 0000000..babe8ad
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe_s.s
@@ -0,0 +1,228 @@
+;//
+;//
+;// File Name: armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 12290
+;// Date: Wednesday, April 9, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS CortexA8
+
+ EXPORT armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe
+
+DEBUG_ON SETL {FALSE}
+
+ IF CortexA8
+
+ M_START armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe, r11
+
+;// Declare input registers
+pSrc RN 0
+srcStep RN 1
+pDst RN 2
+dstStep RN 3
+
+;// Declare Neon registers
+dCoeff5 DN 30.S16
+dCoeff20 DN 31.S16
+
+qSrcA01 QN 11.U8
+qSrcB01 QN 12.U8
+qSrcC01 QN 13.U8
+qSrcD01 QN 14.U8
+
+dSrcA0 DN 22.U8
+dSrcA1 DN 23.U8
+dSrcB0 DN 24.U8
+dSrcB1 DN 25.U8
+dSrcC0 DN 26.U8
+dSrcC1 DN 27.U8
+dSrcD0 DN 28.U8
+dSrcD1 DN 29.U8
+
+dSrcb DN 12.U8
+dSrce DN 13.U8
+dSrcf DN 10.U8
+
+dSrc0c DN 14.U8
+dSrc1c DN 16.U8
+dSrc2c DN 18.U8
+dSrc3c DN 20.U8
+
+dSrc0d DN 15.U8
+dSrc1d DN 17.U8
+dSrc2d DN 19.U8
+dSrc3d DN 21.U8
+
+qTemp01 QN 4.S16
+qTemp23 QN 6.S16
+dTemp0 DN 8.S16
+dTemp2 DN 12.S16
+
+qRes01 QN 11.S16
+qRes23 QN 12.S16
+qRes45 QN 13.S16
+qRes67 QN 14.S16
+
+dRes0 DN 22.S16
+dRes2 DN 24.S16
+dRes4 DN 26.S16
+dRes6 DN 28.S16
+
+dAcc0 DN 22.U8
+dAcc2 DN 24.U8
+dAcc4 DN 26.U8
+dAcc6 DN 28.U8
+
+dResult0 DN 22.U32
+dResult2 DN 24.U32
+dResult4 DN 26.U32
+dResult6 DN 28.U32
+
+ VLD1 qSrcA01, [pSrc], srcStep ;// Load A register [a0 a1 a2 a3 ..]
+ ;// One cycle stall
+ VEXT dSrcf, dSrcA0, dSrcA1, #5 ;// [f0 f1 f2 f3 ..]
+ VEXT dSrcb, dSrcA0, dSrcA1, #1 ;// [b0 b1 b2 b3 ..]
+; VLD1 qSrcB01, [pSrc], srcStep ;// Load B register [a0 a1 a2 a3 ..]
+ VEXT dSrc0c, dSrcA0, dSrcA1, #2
+ VEXT dSrc0d, dSrcA0, dSrcA1, #3
+ VEXT dSrce, dSrcA0, dSrcA1, #4
+ VADDL qRes01, dSrcA0, dSrcf ;// Acc=a+f
+ VADDL qTemp01, dSrc0c, dSrc0d ;// c+d
+ VADDL qTemp23, dSrcb, dSrce ;// b+e
+
+ VLD1 qSrcB01, [pSrc], srcStep ;// Load B register [a0 a1 a2 a3 ..]
+; VLD1 qSrcC01, [pSrc], srcStep ;// Load C register [a0 a1 a2 a3 ..]
+ VMLA dRes0, dTemp0, dCoeff20 ;// Acc += 20*(c+d)
+; VMLS dRes0, dTemp2, dCoeff5 ;// Acc -= 5*(b+e)
+ VMUL dTemp0, dTemp2, dCoeff5 ;// TeRi
+
+ VEXT dSrcf, dSrcB0, dSrcB1, #5 ;// [f0 f1 f2 f3 ..]
+ VEXT dSrcb, dSrcB0, dSrcB1, #1 ;// [b0 b1 b2 b3 ..]
+ VEXT dSrc1c, dSrcB0, dSrcB1, #2
+ VEXT dSrc1d, dSrcB0, dSrcB1, #3
+ VEXT dSrce, dSrcB0, dSrcB1, #4
+ VADDL qRes23, dSrcB0, dSrcf ;// Acc=a+f
+
+ VSUB dRes0, dRes0, dTemp0 ;// TeRi
+
+ VADDL qTemp01, dSrc1c, dSrc1d ;// c+d
+ VADDL qTemp23, dSrcb, dSrce ;// b+e
+
+ VLD1 qSrcC01, [pSrc], srcStep ;// Load C register [a0 a1 a2 a3 ..]
+; VLD1 qSrcD01, [pSrc], srcStep ;// Load D register [a0 a1 a2 a3 ..]
+
+ VMLA dRes2, dTemp0, dCoeff20 ;// Acc += 20*(c+d)
+; VMLS dRes2, dTemp2, dCoeff5 ;// Acc -= 5*(b+e)
+ VMUL dTemp0, dTemp2, dCoeff5 ;// TeRi
+
+ VEXT dSrcf, dSrcC0, dSrcC1, #5 ;// [f0 f1 f2 f3 ..]
+ VEXT dSrcb, dSrcC0, dSrcC1, #1 ;// [b0 b1 b2 b3 ..]
+ VEXT dSrc2c, dSrcC0, dSrcC1, #2
+ VEXT dSrc2d, dSrcC0, dSrcC1, #3
+ VEXT dSrce, dSrcC0, dSrcC1, #4
+ VADDL qRes45, dSrcC0, dSrcf ;// Acc=a+f
+
+ VSUB dRes2, dRes2, dTemp0 ;// TeRi
+
+ VADDL qTemp01, dSrc2c, dSrc2d ;// c+d
+ VADDL qTemp23, dSrcb, dSrce ;// b+e
+
+ VLD1 qSrcD01, [pSrc], srcStep ;// Load D register [a0 a1 a2 a3 ..]
+
+ VMLA dRes4, dTemp0, dCoeff20 ;// Acc += 20*(c+d)
+; VMLS dRes4, dTemp2, dCoeff5 ;// Acc -= 5*(b+e)
+ VMUL dTemp0, dTemp2, dCoeff5 ;// Acc -= 5*(b+e) TeRi
+
+
+ VEXT dSrcf, dSrcD0, dSrcD1, #5 ;// [f0 f1 f2 f3 ..]
+ VEXT dSrcb, dSrcD0, dSrcD1, #1 ;// [b0 b1 b2 b3 ..]
+ VEXT dSrc3c, dSrcD0, dSrcD1, #2
+ VEXT dSrc3d, dSrcD0, dSrcD1, #3
+ VEXT dSrce, dSrcD0, dSrcD1, #4
+ VADDL qRes67, dSrcD0, dSrcf ;// Acc=a+f
+
+ VSUB dRes4, dRes4, dTemp0 ;// TeRi
+
+ VADDL qTemp01, dSrc3c, dSrc3d ;// c+d
+ VADDL qTemp23, dSrcb, dSrce ;// b+e
+ VMLA dRes6, dTemp0, dCoeff20 ;// Acc += 20*(c+d)
+ VMLS dRes6, dTemp2, dCoeff5 ;// Acc -= 5*(b+e)
+
+ VQRSHRUN dAcc0, qRes01, #5 ;// Acc = Sat ((Acc + 16) / 32)
+ VQRSHRUN dAcc2, qRes23, #5 ;// Acc = Sat ((Acc + 16) / 32)
+ VQRSHRUN dAcc4, qRes45, #5 ;// Acc = Sat ((Acc + 16) / 32)
+ VQRSHRUN dAcc6, qRes67, #5 ;// Acc = Sat ((Acc + 16) / 32)
+
+ M_END
+
+ ENDIF
+
+
+ END
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe_s.s
new file mode 100755
index 0000000..89c90aa
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe_s.s
@@ -0,0 +1,134 @@
+;//
+;//
+;// File Name: armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 12290
+;// Date: Wednesday, April 9, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS CortexA8
+
+ EXPORT armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe
+
+ IF CortexA8
+
+ M_START armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe, r11
+
+;// Declare input registers
+pSrc RN 0
+srcStep RN 1
+pDst RN 2
+dstStep RN 3
+
+Temp RN 12
+
+;// Declare Neon registers
+dCoeff5 DN 30.S16
+dCoeff20 DN 31.S16
+
+dSrc0 DN 7.U8
+dSrc1 DN 8.U8
+dSrc2 DN 9.U8
+dSrc3 DN 10.U8
+dSrc4 DN 11.U8
+dSrc5 DN 12.U8
+dSrc6 DN 13.U8
+dSrc7 DN 14.U8
+dSrc8 DN 15.U8
+
+qSumBE01 QN 8.S16
+qSumCD01 QN 9.S16
+dSumBE0 DN 16.S16
+dSumCD0 DN 18.S16
+
+qAcc01 QN 0.S16
+qAcc23 QN 1.S16
+qAcc45 QN 2.S16
+qAcc67 QN 3.S16
+
+dRes0 DN 0.S16
+dRes1 DN 2.S16
+dRes2 DN 4.S16
+dRes3 DN 6.S16
+
+dAcc0 DN 0.U8
+dAcc1 DN 2.U8
+dAcc2 DN 4.U8
+dAcc3 DN 6.U8
+
+
+dTmp0 DN 20.S16
+dTmp1 DN 21.S16
+dTmp2 DN 22.S16
+dTmp3 DN 23.S16
+
+
+ VLD1 dSrc0, [pSrc], srcStep ;// [a0 a1 a2 a3 .. ]
+ ADD Temp, pSrc, srcStep, LSL #2
+ VLD1 dSrc1, [pSrc], srcStep ;// [b0 b1 b2 b3 .. ]
+ ;// One cycle stall
+ VLD1 dSrc5, [Temp], srcStep
+ ;// One cycle stall
+ VLD1 dSrc2, [pSrc], srcStep ;// [c0 c1 c2 c3 .. ]
+ VADDL qAcc01, dSrc0, dSrc5 ;// Acc = a+f
+ VLD1 dSrc3, [pSrc], srcStep
+ ;// One cycle stall
+ VLD1 dSrc6, [Temp], srcStep ;// TeRi
+
+ VLD1 dSrc4, [pSrc], srcStep
+ VLD1 dSrc7, [Temp], srcStep ;// TeRi
+ VADDL qSumBE01, dSrc1, dSrc4 ;// b+e
+ VADDL qSumCD01, dSrc2, dSrc3 ;// c+d
+ VLD1 dSrc8, [Temp], srcStep ;// TeRi
+ VMLS dRes0, dSumBE0, dCoeff5 ;// Acc -= 20*(b+e)
+; VMLA dRes0, dSumCD0, dCoeff20 ;// Acc += 20*(c+d)
+ VMUL dTmp0, dSumCD0, dCoeff20 ;// Acc += 20*(c+d)
+
+; VLD1 dSrc6, [Temp], srcStep
+ VADDL qSumBE01, dSrc2, dSrc5 ;// b+e
+ VADDL qSumCD01, dSrc3, dSrc4 ;// c+d
+ VADDL qAcc23, dSrc1, dSrc6 ;// Acc = a+f
+ VMLS dRes1, dSumBE0, dCoeff5 ;// Acc -= 20*(b+e)
+; VMLA dRes1, dSumCD0, dCoeff20 ;// Acc += 20*(c+d)
+ VMUL dTmp1, dSumCD0, dCoeff20 ;// Acc += 20*(c+d)
+
+; VLD1 dSrc7, [Temp], srcStep
+ VADDL qSumBE01, dSrc3, dSrc6 ;// b+e
+ VADDL qSumCD01, dSrc4, dSrc5 ;// c+d
+ VADDL qAcc45, dSrc2, dSrc7 ;// Acc = a+f
+ VMLS dRes2, dSumBE0, dCoeff5 ;// Acc -= 20*(b+e)
+; VMLA dRes2, dSumCD0, dCoeff20 ;// Acc += 20*(c+d)
+ VMUL dTmp2, dSumCD0, dCoeff20 ;// Acc += 20*(c+d)
+
+; VLD1 dSrc8, [Temp], srcStep ;// [i0 i1 i2 i3 .. ]
+ VADDL qSumBE01, dSrc4, dSrc7 ;// b+e
+ VADDL qAcc67, dSrc3, dSrc8 ;// Acc = a+f
+ VADDL qSumCD01, dSrc5, dSrc6 ;// c+d
+ VMLS dRes3, dSumBE0, dCoeff5 ;// Acc -= 20*(b+e)
+ VADD dRes0, dRes0, dTmp0
+ VADD dRes1, dRes1, dTmp1
+ VADD dRes2, dRes2, dTmp2
+ VMLA dRes3, dSumCD0, dCoeff20 ;// Acc += 20*(c+d)
+; VMUL dTmp3, dSumCD0, dCoeff20 ;// Acc += 20*(c+d)
+; VADD dRes3, dRes3, dTmp3
+
+ VQRSHRUN dAcc0, qAcc01, #5
+ VQRSHRUN dAcc1, qAcc23, #5
+ VQRSHRUN dAcc2, qAcc45, #5
+ VQRSHRUN dAcc3, qAcc67, #5
+
+ M_END
+
+ ENDIF
+
+
+
+ END
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_Interpolate_Chroma_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_Interpolate_Chroma_s.s
new file mode 100755
index 0000000..0f0ec78
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_Interpolate_Chroma_s.s
@@ -0,0 +1,318 @@
+;//
+;//
+;// File Name: armVCM4P10_Interpolate_Chroma_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 9641
+;// Date: Thursday, February 7, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS CortexA8
+
+
+ IF CortexA8
+
+ M_TABLE armVCM4P10_WidthBranchTableMVIsNotZero
+
+ DCD WidthIs2MVIsNotZero, WidthIs2MVIsNotZero
+ DCD WidthIs4MVIsNotZero, WidthIs4MVIsNotZero
+ DCD WidthIs8MVIsNotZero
+
+ M_TABLE armVCM4P10_WidthBranchTableMVIsZero
+
+ DCD WidthIs2MVIsZero, WidthIs2MVIsZero
+ DCD WidthIs4MVIsZero, WidthIs4MVIsZero
+ DCD WidthIs8MVIsZero
+
+
+;// input registers
+
+pSrc RN 0
+iSrcStep RN 1
+pDst RN 2
+iDstStep RN 3
+iWidth RN 4
+iHeight RN 5
+dx RN 6
+dy RN 7
+
+;// local variable registers
+pc RN 15
+return RN 0
+EightMinusdx RN 8
+EightMinusdy RN 9
+
+ACoeff RN 12
+BCoeff RN 9
+CCoeff RN 8
+DCoeff RN 6
+
+pTable RN 11
+
+Step1 RN 10
+SrcStepMinus1 RN 14
+
+dACoeff DN D12.U8
+dBCoeff DN D13.U8
+dCCoeff DN D14.U8
+dDCoeff DN D15.U8
+
+dRow0a DN D0.U8
+dRow0b DN D1.U8
+dRow1a DN D2.U8
+dRow1b DN D3.U8
+
+qRow0a QN Q2.S16
+qRow0b QN Q3.S16
+
+;//dIndex DN D16.U8
+qRow1a QN Q11.S16
+qRow1b QN Q12.S16
+
+dRow2a DN D16.U8
+dRow2b DN D17.U8
+dRow3a DN D18.U8
+dRow3b DN D19.U8
+
+qOutRow2 QN Q11.U16
+qOutRow3 QN Q12.U16
+dOutRow2 DN D20.U8
+dOutRow3 DN D21.U8
+dOutRow2U64 DN D20.U64
+dOutRow3U64 DN D21.U64
+
+qOutRow0 QN Q2.U16
+qOutRow1 QN Q3.U16
+dOutRow0 DN D8.U8
+dOutRow1 DN D9.U8
+
+dOutRow0U64 DN D8.U64
+dOutRow1U64 DN D9.U64
+
+dOutRow0U32 DN D8.U32
+dOutRow1U32 DN D9.U32
+
+dOutRow0U16 DN D8.U16
+dOutRow1U16 DN D9.U16
+
+
+dOut0U64 DN D0.U64
+dOut1U64 DN D1.U64
+
+dOut00U32 DN D0.U32
+dOut01U32 DN D1.U32
+dOut10U32 DN D2.U32
+dOut11U32 DN D3.U32
+
+dOut0U16 DN D0.U16
+dOut1U16 DN D1.U16
+
+;//-----------------------------------------------------------------------------------------------
+;// armVCM4P10_Interpolate_Chroma_asm starts
+;//-----------------------------------------------------------------------------------------------
+
+ ;// Write function header
+ M_START armVCM4P10_Interpolate_Chroma, r11, d15
+
+ ;// Define stack arguments
+ M_ARG Width, 4
+ M_ARG Height, 4
+ M_ARG Dx, 4
+ M_ARG Dy, 4
+
+ ;// Load argument from the stack
+ ;// M_STALL ARM1136JS=4
+
+ M_LDRD dx, dy, Dx
+ M_LDRD iWidth, iHeight, Width
+
+ ;// EightMinusdx = 8 - dx
+ ;// EightMinusdy = 8 - dy
+
+ ;// ACoeff = EightMinusdx * EightMinusdy
+ ;// BCoeff = dx * EightMinusdy
+ ;// CCoeff = EightMinusdx * dy
+ ;// DCoeff = dx * dy
+
+ RSB EightMinusdx, dx, #8
+ RSB EightMinusdy, dy, #8
+ CMN dx,dy
+ MOV Step1, #1
+ LDREQ pTable, =armVCM4P10_WidthBranchTableMVIsZero
+ SUB SrcStepMinus1, iSrcStep, Step1
+ LDRNE pTable, =armVCM4P10_WidthBranchTableMVIsNotZero
+
+ VLD1 dRow0a, [pSrc], Step1 ;// 0a
+
+ SMULBB ACoeff, EightMinusdx, EightMinusdy
+ SMULBB BCoeff, dx, EightMinusdy
+ VLD1 dRow0b, [pSrc], SrcStepMinus1 ;// 0b
+ SMULBB CCoeff, EightMinusdx, dy
+ SMULBB DCoeff, dx, dy
+
+ VDUP dACoeff, ACoeff
+ VDUP dBCoeff, BCoeff
+ VDUP dCCoeff, CCoeff
+ VDUP dDCoeff, DCoeff
+
+ LDR pc, [pTable, iWidth, LSL #1] ;// Branch to the case based on iWidth
+
+;// Pixel layout:
+;//
+;// x00 x01 x02
+;// x10 x11 x12
+;// x20 x21 x22
+
+;// If fractionl mv is not (0, 0)
+WidthIs8MVIsNotZero
+
+ VLD1 dRow1a, [pSrc], Step1 ;// 1a
+ VMULL qRow0a, dRow0a, dACoeff
+ VLD1 dRow1b, [pSrc], SrcStepMinus1 ;// 1b
+ VMULL qRow0b, dRow1a, dACoeff
+ VLD1 dRow2a, [pSrc], Step1 ;// 2a
+ VMLAL qRow0a, dRow0b, dBCoeff
+ VLD1 dRow2b, [pSrc], SrcStepMinus1 ;// 2b
+ VMULL qRow1a, dRow2a, dACoeff
+ VMLAL qRow0b, dRow1b, dBCoeff
+ VLD1 dRow3a, [pSrc], Step1 ;// 3a
+ VMLAL qRow0a, dRow1a, dCCoeff
+ VMLAL qRow1a, dRow2b, dBCoeff
+ VMULL qRow1b, dRow3a, dACoeff
+ VLD1 dRow3b, [pSrc], SrcStepMinus1 ;// 3b
+ VMLAL qRow0b, dRow2a, dCCoeff
+ VLD1 dRow0a, [pSrc], Step1 ;// 0a
+ VMLAL qRow1b, dRow3b, dBCoeff
+ VMLAL qRow1a, dRow3a, dCCoeff
+ VMLAL qRow0a, dRow1b, dDCoeff
+ VLD1 dRow0b, [pSrc], SrcStepMinus1 ;// 0b
+ VMLAL qRow1b, dRow0a, dCCoeff
+ VMLAL qRow0b, dRow2b, dDCoeff
+ VMLAL qRow1a, dRow3b, dDCoeff
+
+
+ SUBS iHeight, iHeight, #4
+ VMLAL qRow1b, dRow0b, dDCoeff
+
+ VQRSHRN dOutRow0, qOutRow0, #6
+ VQRSHRN dOutRow1, qOutRow1, #6
+ VQRSHRN dOutRow2, qOutRow2, #6
+ VST1 dOutRow0U64, [pDst], iDstStep
+ VQRSHRN dOutRow3, qOutRow3, #6
+
+ VST1 dOutRow1U64, [pDst], iDstStep
+ VST1 dOutRow2U64, [pDst], iDstStep
+ VST1 dOutRow3U64, [pDst], iDstStep
+
+
+ BGT WidthIs8MVIsNotZero
+ MOV return, #OMX_Sts_NoErr
+ M_EXIT
+
+WidthIs4MVIsNotZero
+
+ VLD1 dRow1a, [pSrc], Step1
+ VMULL qRow0a, dRow0a, dACoeff
+ VMULL qRow0b, dRow1a, dACoeff
+ VLD1 dRow1b, [pSrc], SrcStepMinus1
+ VMLAL qRow0a, dRow0b, dBCoeff
+ VMLAL qRow0b, dRow1b, dBCoeff
+ VLD1 dRow0a, [pSrc], Step1
+ VMLAL qRow0a, dRow1a, dCCoeff
+ VMLAL qRow0b, dRow0a, dCCoeff
+ VLD1 dRow0b, [pSrc], SrcStepMinus1
+ SUBS iHeight, iHeight, #2
+ VMLAL qRow0b, dRow0b, dDCoeff
+ VMLAL qRow0a, dRow1b, dDCoeff
+
+ VQRSHRN dOutRow1, qOutRow1, #6
+ VQRSHRN dOutRow0, qOutRow0, #6
+
+ VST1 dOutRow0U32[0], [pDst], iDstStep
+ VST1 dOutRow1U32[0], [pDst], iDstStep
+
+ BGT WidthIs4MVIsNotZero
+ MOV return, #OMX_Sts_NoErr
+ M_EXIT
+
+WidthIs2MVIsNotZero
+
+ VLD1 dRow1a, [pSrc], Step1
+ VMULL qRow0a, dRow0a, dACoeff
+ VMULL qRow0b, dRow1a, dACoeff
+ VLD1 dRow1b, [pSrc], SrcStepMinus1
+ VMLAL qRow0a, dRow0b, dBCoeff
+ VMLAL qRow0b, dRow1b, dBCoeff
+ VLD1 dRow0a, [pSrc], Step1
+ VMLAL qRow0a, dRow1a, dCCoeff
+ VMLAL qRow0b, dRow0a, dCCoeff
+ VLD1 dRow0b, [pSrc], SrcStepMinus1
+ SUBS iHeight, iHeight, #2
+ VMLAL qRow0b, dRow0b, dDCoeff
+ VMLAL qRow0a, dRow1b, dDCoeff
+
+ VQRSHRN dOutRow1, qOutRow1, #6
+ VQRSHRN dOutRow0, qOutRow0, #6
+
+ VST1 dOutRow0U16[0], [pDst], iDstStep
+ VST1 dOutRow1U16[0], [pDst], iDstStep
+
+ BGT WidthIs2MVIsNotZero
+ MOV return, #OMX_Sts_NoErr
+ M_EXIT
+
+;// If fractionl mv is (0, 0)
+WidthIs8MVIsZero
+ SUB pSrc, pSrc, iSrcStep
+
+WidthIs8LoopMVIsZero
+ VLD1 dRow0a, [pSrc], iSrcStep
+ SUBS iHeight, iHeight, #2
+ VLD1 dRow0b, [pSrc], iSrcStep
+ VST1 dOut0U64, [pDst], iDstStep
+ VST1 dOut1U64, [pDst], iDstStep
+ BGT WidthIs8LoopMVIsZero
+
+ MOV return, #OMX_Sts_NoErr
+ M_EXIT
+
+WidthIs4MVIsZero
+ VLD1 dRow0b, [pSrc], iSrcStep
+
+ SUBS iHeight, iHeight, #2
+
+ VST1 dOut00U32[0], [pDst], iDstStep
+ VLD1 dRow0a, [pSrc], iSrcStep
+ VST1 dOut01U32[0], [pDst], iDstStep
+
+ BGT WidthIs4MVIsZero
+ MOV return, #OMX_Sts_NoErr
+ M_EXIT
+
+WidthIs2MVIsZero
+ VLD1 dRow0b, [pSrc], iSrcStep
+ SUBS iHeight, iHeight, #2
+
+ VST1 dOut0U16[0], [pDst], iDstStep
+ VLD1 dRow0a, [pSrc], iSrcStep
+ VST1 dOut1U16[0], [pDst], iDstStep
+
+ BGT WidthIs2MVIsZero
+ MOV return, #OMX_Sts_NoErr
+ M_END
+
+ ENDIF ;// CortexA8
+
+ END
+
+;//-----------------------------------------------------------------------------------------------
+;// armVCM4P10_Interpolate_Chroma_asm ends
+;//-----------------------------------------------------------------------------------------------
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_QuantTables_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_QuantTables_s.s
new file mode 100755
index 0000000..7e2642b
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_QuantTables_s.s
@@ -0,0 +1,74 @@
+;//
+;//
+;// File Name: armVCM4P10_QuantTables_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 12290
+;// Date: Wednesday, April 9, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;// Description:
+;// This file contains quantization tables
+;//
+;//
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+
+ EXPORT armVCM4P10_MFMatrixQPModTable
+ EXPORT armVCM4P10_QPDivIntraTable
+ EXPORT armVCM4P10_QPDivPlusOneTable
+
+;//--------------------------------------------------------------
+;// This table contains armVCM4P10_MFMatrix [iQP % 6][0] entires,
+;// for values of iQP from 0 to 51 (inclusive).
+;//--------------------------------------------------------------
+
+ M_TABLE armVCM4P10_MFMatrixQPModTable
+ DCW 13107, 11916, 10082, 9362, 8192, 7282
+ DCW 13107, 11916, 10082, 9362, 8192, 7282
+ DCW 13107, 11916, 10082, 9362, 8192, 7282
+ DCW 13107, 11916, 10082, 9362, 8192, 7282
+ DCW 13107, 11916, 10082, 9362, 8192, 7282
+ DCW 13107, 11916, 10082, 9362, 8192, 7282
+ DCW 13107, 11916, 10082, 9362, 8192, 7282
+ DCW 13107, 11916, 10082, 9362, 8192, 7282
+ DCW 13107, 11916, 10082, 9362, 8192, 7282
+
+;//---------------------------------------------------------------
+;// This table contains ARM_M4P10_Q_OFFSET + 1 + (iQP / 6) values,
+;// for values of iQP from 0 to 51 (inclusive).
+;//---------------------------------------------------------------
+
+ M_TABLE armVCM4P10_QPDivPlusOneTable
+ DCB 16, 16, 16, 16, 16, 16
+ DCB 17, 17, 17, 17, 17, 17
+ DCB 18, 18, 18, 18, 18, 18
+ DCB 19, 19, 19, 19, 19, 19
+ DCB 20, 20, 20, 20, 20, 20
+ DCB 21, 21, 21, 21, 21, 21
+ DCB 22, 22, 22, 22, 22, 22
+ DCB 23, 23, 23, 23, 23, 23
+ DCB 24, 24, 24, 24, 24, 24
+
+;//------------------------------------------------------------------
+;// This table contains (1 << QbitsPlusOne) / 3 Values (Intra case) ,
+;// for values of iQP from 0 to 51 (inclusive).
+;//------------------------------------------------------------------
+
+ M_TABLE armVCM4P10_QPDivIntraTable, 2
+ DCD 21845, 21845, 21845, 21845, 21845, 21845
+ DCD 43690, 43690, 43690, 43690, 43690, 43690
+ DCD 87381, 87381, 87381, 87381, 87381, 87381
+ DCD 174762, 174762, 174762, 174762, 174762, 174762
+ DCD 349525, 349525, 349525, 349525, 349525, 349525
+ DCD 699050, 699050, 699050, 699050, 699050, 699050
+ DCD 1398101, 1398101, 1398101, 1398101, 1398101, 1398101
+ DCD 2796202, 2796202, 2796202, 2796202, 2796202, 2796202
+ DCD 5592405, 5592405, 5592405, 5592405, 5592405, 5592405
+
+
+ END
+
\ No newline at end of file
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_TransformResidual4x4_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_TransformResidual4x4_s.s
new file mode 100755
index 0000000..ee9c339
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_TransformResidual4x4_s.s
@@ -0,0 +1,186 @@
+;//
+;//
+;// File Name: armVCM4P10_TransformResidual4x4_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 12290
+;// Date: Wednesday, April 9, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+;// Description:
+;// Transform Residual 4x4 Coefficients
+;//
+;//
+
+
+;// Include standard headers
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS CortexA8
+
+;// Import symbols required from other files
+;// (For example tables)
+
+
+
+
+;// Set debugging level
+;//DEBUG_ON SETL {TRUE}
+
+
+
+;// Guarding implementation by the processor name
+
+
+
+
+
+
+
+
+;// Guarding implementation by the processor name
+
+ IF CortexA8
+
+;// ARM Registers
+
+;//Input Registers
+pDst RN 0
+pSrc RN 1
+
+
+;// Neon Registers
+
+;// Packed Input pixels
+dIn0 DN D0.S16
+dIn1 DN D1.S16
+dIn2 DN D2.S16
+dIn3 DN D3.S16
+
+;// Intermediate calculations
+dZero DN D4.S16
+de0 DN D5.S16
+de1 DN D6.S16
+de2 DN D7.S16
+de3 DN D8.S16
+dIn1RS DN D7.S16
+dIn3RS DN D8.S16
+df0 DN D0.S16
+df1 DN D1.S16
+df2 DN D2.S16
+df3 DN D3.S16
+qf01 QN Q0.32
+qf23 QN Q1.32
+dg0 DN D5.S16
+dg1 DN D6.S16
+dg2 DN D7.S16
+dg3 DN D8.S16
+df1RS DN D7.S16
+df3RS DN D8.S16
+
+;// Output pixels
+dh0 DN D0.S16
+dh1 DN D1.S16
+dh2 DN D2.S16
+dh3 DN D3.S16
+
+
+ ;// Allocate stack memory required by the function
+
+
+ ;// Write function header
+ M_START armVCM4P10_TransformResidual4x4, ,d8
+
+ ;******************************************************************
+ ;// The strategy used in implementing the transform is as follows:*
+ ;// Load the 4x4 block into 8 registers *
+ ;// Transpose the 4x4 matrix *
+ ;// Perform the row operations (on columns) using SIMD *
+ ;// Transpose the 4x4 result matrix *
+ ;// Perform the coloumn operations *
+ ;// Store the 4x4 block at one go *
+ ;******************************************************************
+
+ ;// Load all the 4x4 pixels in transposed form
+
+ VLD4 {dIn0,dIn1,dIn2,dIn3},[pSrc]
+
+ VMOV dZero,#0 ;// Used to right shift by 1
+
+
+ ;****************************************
+ ;// Row Operations (Performed on columns)
+ ;****************************************
+
+
+ VADD de0,dIn0,dIn2 ;// e0 = d0 + d2
+ VSUB de1,dIn0,dIn2 ;// e1 = d0 - d2
+ VHADD dIn1RS,dIn1,dZero ;// (f1>>1) constZero is a register holding 0
+ VHADD dIn3RS,dIn3,dZero
+ VSUB de2,dIn1RS,dIn3 ;// e2 = (d1>>1) - d3
+ VADD de3,dIn1,dIn3RS ;// e3 = d1 + (d3>>1)
+ VADD df0,de0,de3 ;// f0 = e0 + e3
+ VADD df1,de1,de2 ;// f1 = e1 + e2
+ VSUB df2,de1,de2 ;// f2 = e1 - e2
+ VSUB df3,de0,de3 ;// f3 = e0 - e3
+
+
+
+ ;*****************************************************************
+ ;// Transpose the resultant matrix
+ ;*****************************************************************
+
+ VTRN df0,df1
+ VTRN df2,df3
+ VTRN qf01,qf23
+
+
+ ;*******************************
+ ;// Coloumn Operations
+ ;*******************************
+
+
+ VADD dg0,df0,df2 ;// e0 = d0 + d2
+ VSUB dg1,df0,df2 ;// e1 = d0 - d2
+ VHADD df1RS,df1,dZero ;// (f1>>1) constZero is a register holding 0
+ VHADD df3RS,df3,dZero
+ VSUB dg2,df1RS,df3 ;// e2 = (d1>>1) - d3
+ VADD dg3,df1,df3RS ;// e3 = d1 + (d3>>1)
+ VADD dh0,dg0,dg3 ;// f0 = e0 + e3
+ VADD dh1,dg1,dg2 ;// f1 = e1 + e2
+ VSUB dh2,dg1,dg2 ;// f2 = e1 - e2
+ VSUB dh3,dg0,dg3 ;// f3 = e0 - e3
+
+
+ ;************************************************
+ ;// Calculate final value (colOp[i][j] + 32)>>6
+ ;************************************************
+
+ VRSHR dh0,#6
+ VRSHR dh1,#6
+ VRSHR dh2,#6
+ VRSHR dh3,#6
+
+
+ ;***************************
+ ;// Store all the 4x4 pixels
+ ;***************************
+
+ VST1 {dh0,dh1,dh2,dh3},[pDst]
+
+
+ ;// Set return value
+
+End
+
+
+ ;// Write function tail
+ M_END
+
+ ENDIF ;//CortexA8
+
+ END
\ No newline at end of file
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_UnpackBlock4x4_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_UnpackBlock4x4_s.s
new file mode 100755
index 0000000..4c52e22
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_UnpackBlock4x4_s.s
@@ -0,0 +1,92 @@
+;//
+;//
+;// File Name: armVCM4P10_UnpackBlock4x4_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 12290
+;// Date: Wednesday, April 9, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+;// Define the processor variants supported by this file
+
+ M_VARIANTS ARM1136JS
+
+
+ IF ARM1136JS
+
+;//--------------------------------------
+;// Input Arguments and their scope/usage
+;//--------------------------------------
+ppSrc RN 0 ;// Persistent variable
+pDst RN 1 ;// Persistent variable
+
+;//--------------------------------
+;// Variables and their scope/usage
+;//--------------------------------
+pSrc RN 2 ;// Persistent variables
+Flag RN 3
+Value RN 4
+Value2 RN 5
+strOffset RN 6
+cstOffset RN 7
+
+
+ M_START armVCM4P10_UnpackBlock4x4, r7
+
+ LDR pSrc, [ppSrc] ;// Load pSrc
+ MOV cstOffset, #31 ;// To be used in the loop, to compute offset
+
+ ;//-----------------------------------------------------------------------
+ ; Firstly, fill all the coefficient values on the <pDst> buffer by zero
+ ;//-----------------------------------------------------------------------
+
+ MOV Value, #0 ;// Initialize the zero value
+ MOV Value2, #0 ;// Initialize the zero value
+ LDRB Flag, [pSrc], #1 ;// Preload <Flag> before <unpackLoop>
+
+ STRD Value, [pDst, #0] ;// pDst[0] = pDst[1] = pDst[2] = pDst[3] = 0
+ STRD Value, [pDst, #8] ;// pDst[4] = pDst[5] = pDst[6] = pDst[7] = 0
+ STRD Value, [pDst, #16] ;// pDst[8] = pDst[9] = pDst[10] = pDst[11] = 0
+ STRD Value, [pDst, #24] ;// pDst[12] = pDst[13] = pDst[14] = pDst[15] = 0
+
+ ;//----------------------------------------------------------------------------
+ ;// The loop below parses and unpacks the input stream. The C-model has
+ ;// a somewhat complicated logic for sign extension. But in the v6 version,
+ ;// that can be easily taken care by loading the data from <pSrc> stream as
+ ;// SIGNED byte/halfword. So, based on the first TST instruction, 8-bits or
+ ;// 16-bits are read.
+ ;//
+ ;// Next, to compute the offset, where the unpacked value needs to be stored,
+ ;// we modify the computation to perform [(Flag & 15) < 1] as [(Flag < 1) & 31]
+ ;// This results in a saving of one cycle.
+ ;//----------------------------------------------------------------------------
+
+unpackLoop
+ TST Flag, #0x10 ;// Computing (Flag & 0x10)
+ LDRSBNE Value2,[pSrc,#1] ;// Load byte wise to avoid unaligned access
+ LDRBNE Value, [pSrc], #2
+ AND strOffset, cstOffset, Flag, LSL #1 ;// strOffset = (Flag & 15) < 1;
+ LDRSBEQ Value, [pSrc], #1 ;// Value = (OMX_U8) *pSrc++
+ ORRNE Value,Value,Value2, LSL #8 ;// Value = (OMX_U16) *pSrc++
+
+ TST Flag, #0x20 ;// Computing (Flag & 0x20) to check, if we're done
+ LDRBEQ Flag, [pSrc], #1 ;// Flag = (OMX_U8) *pSrc++, for next iteration
+ STRH Value, [pDst, strOffset] ;// Store <Value> at offset <strOffset>
+ BEQ unpackLoop ;// Branch to the loop beginning
+
+ STR pSrc, [ppSrc] ;// Update the bitstream pointer
+ M_END
+
+ ENDIF
+
+
+
+ END
+
\ No newline at end of file
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DeblockChroma_I.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DeblockChroma_I.c
new file mode 100755
index 0000000..40d4d5e
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DeblockChroma_I.c
@@ -0,0 +1,88 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: omxVCM4P10_DeblockChroma_I.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 12290
+ * Date: Wednesday, April 9, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * H.264 intra chroma deblock
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/**
+ * Function: omxVCM4P10_DeblockChroma_I
+ *
+ * Description:
+ * Performs deblocking filtering on all edges of the chroma macroblock (16x16).
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] pSrcDst pointer to the input macroblock. Must be 8-byte aligned.
+ * [in] srcdstStep Step of the arrays
+ * [in] pAlpha pointer to a 2x2 array of alpha thresholds, organized as follows: { external
+ * vertical edge, internal vertical edge, external
+ * horizontal edge, internal horizontal edge }
+ * [in] pBeta pointer to a 2x2 array of beta thresholds, organized as follows: { external
+ * vertical edge, internal vertical edge, external horizontal edge,
+ * internal horizontal edge }
+ * [in] pThresholds AArray of size 8x2 of Thresholds (TC0) (values for the left or
+ * above edge of each 4x2 or 2x4 block, arranged in vertical block order
+ * and then in horizontal block order)
+ * [in] pBS array of size 16x2 of BS parameters (arranged in scan block order for vertical edges and then horizontal edges);
+ * valid in the range [0,4] with the following restrictions: i) pBS[i]== 4 may occur only for 0<=i<=3, ii) pBS[i]== 4 if and only if pBS[i^1]== 4. Must be 4-byte aligned.
+ * [out] pSrcDst pointer to filtered output macroblock
+ *
+ * Return Value:
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments
+ * - Either of the pointers in pSrcDst, pAlpha, pBeta, pTresholds, or pBS is NULL.
+ * - pSrcDst is not 8-byte aligned.
+ * - either pThresholds or pBS is not 4-byte aligned.
+ * - pBS is out of range, i.e., one of the following conditions is true: pBS[i]<0, pBS[i]>4, pBS[i]==4 for i>=4, or (pBS[i]==4 && pBS[i^1]!=4) for 0<=i<=3.
+ * - srcdstStep is not a multiple of 8.
+ *
+ */
+OMXResult omxVCM4P10_DeblockChroma_I(
+ OMX_U8* pSrcDst,
+ OMX_S32 srcdstStep,
+ const OMX_U8* pAlpha,
+ const OMX_U8* pBeta,
+ const OMX_U8* pThresholds,
+ const OMX_U8 *pBS
+)
+{
+ OMXResult errorCode;
+
+ armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot8ByteAligned(pSrcDst), OMX_Sts_BadArgErr);
+ armRetArgErrIf(srcdstStep & 7, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pAlpha == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pBeta == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pThresholds == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot4ByteAligned(pThresholds), OMX_Sts_BadArgErr);
+ armRetArgErrIf(pBS == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot4ByteAligned(pBS), OMX_Sts_BadArgErr);
+
+ errorCode = omxVCM4P10_FilterDeblockingChroma_VerEdge_I(
+ pSrcDst, srcdstStep, pAlpha, pBeta, pThresholds, pBS);
+
+ armRetArgErrIf(errorCode != OMX_Sts_NoErr, errorCode)
+
+ errorCode = omxVCM4P10_FilterDeblockingChroma_HorEdge_I(
+ pSrcDst, srcdstStep, pAlpha+2, pBeta+2, pThresholds+8, pBS+16);
+
+ return errorCode;
+}
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DeblockLuma_I.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DeblockLuma_I.c
new file mode 100755
index 0000000..619365f
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DeblockLuma_I.c
@@ -0,0 +1,91 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: omxVCM4P10_DeblockLuma_I.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 12290
+ * Date: Wednesday, April 9, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * H.264 luma deblock
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+
+/**
+ * Function: omxVCM4P10_DeblockLuma_I
+ *
+ * Description:
+ * This function performs deblock filtering the horizontal and vertical edges of a luma macroblock
+ *(16x16).
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] pSrcDst pointer to the input macroblock. Must be 8-byte aligned.
+ * [in] srcdstStep image width
+ * [in] pAlpha pointer to a 2x2 table of alpha thresholds, organized as follows: { external
+ * vertical edge, internal vertical edge, external horizontal
+ * edge, internal horizontal edge }
+ * [in] pBeta pointer to a 2x2 table of beta thresholds, organized as follows: { external
+ * vertical edge, internal vertical edge, external horizontal edge,
+ * internal horizontal edge }
+ * [in] pThresholds pointer to a 16x2 table of threshold (TC0), organized as follows: { values for
+ * the left or above edge of each 4x4 block, arranged in vertical block order
+ * and then in horizontal block order)
+ * [in] pBS pointer to a 16x2 table of BS parameters arranged in scan block order for vertical edges and then horizontal edges;
+ * valid in the range [0,4] with the following restrictions: i) pBS[i]== 4 may occur only for 0<=i<=3, ii) pBS[i]== 4 if and only if pBS[i^1]== 4. Must be 4-byte aligned.
+ * [out] pSrcDst pointer to filtered output macroblock.
+ *
+ * Return Value:
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments
+ * - Either of the pointers in pSrcDst, pAlpha, pBeta, pTresholds or pBS is NULL.
+ * - pSrcDst is not 8-byte aligned.
+ * - srcdstStep is not a multiple of 8
+ * - pBS is out of range, i.e., one of the following conditions is true: pBS[i]<0, pBS[i]>4, pBS[i]==4 for i>=4, or (pBS[i]==4 && pBS[i^1]!=4) for 0<=i<=3.
+.
+ *
+ */
+
+OMXResult omxVCM4P10_DeblockLuma_I(
+ OMX_U8* pSrcDst,
+ OMX_S32 srcdstStep,
+ const OMX_U8* pAlpha,
+ const OMX_U8* pBeta,
+ const OMX_U8* pThresholds,
+ const OMX_U8 *pBS
+)
+{
+ OMXResult errorCode;
+
+ armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot8ByteAligned(pSrcDst), OMX_Sts_BadArgErr);
+ armRetArgErrIf(srcdstStep & 7, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pAlpha == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pBeta == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pThresholds == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot4ByteAligned(pThresholds), OMX_Sts_BadArgErr);
+ armRetArgErrIf(pBS == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot4ByteAligned(pBS), OMX_Sts_BadArgErr);
+
+ errorCode = omxVCM4P10_FilterDeblockingLuma_VerEdge_I(
+ pSrcDst, srcdstStep, pAlpha, pBeta, pThresholds, pBS);
+
+ armRetArgErrIf(errorCode != OMX_Sts_NoErr, errorCode)
+
+ errorCode = omxVCM4P10_FilterDeblockingLuma_HorEdge_I(
+ pSrcDst, srcdstStep, pAlpha+2, pBeta+2, pThresholds+16, pBS+16);
+
+ return errorCode;
+}
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c
new file mode 100755
index 0000000..4e871bf
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c
@@ -0,0 +1,62 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 12290
+ * Date: Wednesday, April 9, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * H.264 decode coefficients module
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/**
+ * Function: omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC
+ *
+ * Description:
+ * Performs CAVLC decoding and inverse raster scan for 2x2 block of
+ * ChromaDCLevel. The decoded coefficients in packed position-coefficient
+ * buffer are stored in increasing raster scan order, namely position order.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream Double pointer to current byte in bit stream
+ * buffer
+ * [in] pOffset Pointer to current bit position in the byte
+ * pointed to by *ppBitStream
+ * [out] ppBitStream *ppBitStream is updated after each block is decoded
+ * [out] pOffset *pOffset is updated after each block is decoded
+ * [out] pNumCoeff Pointer to the number of nonzero coefficients
+ * in this block
+ * [out] ppPosCoefbuf Double pointer to destination residual
+ * coefficient-position pair buffer
+ *
+ * Return Value:
+ * Standard omxError result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC (
+ const OMX_U8** ppBitStream,
+ OMX_S32* pOffset,
+ OMX_U8* pNumCoeff,
+ OMX_U8** ppPosCoefbuf
+ )
+
+{
+ return armVCM4P10_DecodeCoeffsToPair(ppBitStream, pOffset, pNumCoeff,
+ ppPosCoefbuf, 17, 4);
+
+}
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DecodeCoeffsToPairCAVLC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DecodeCoeffsToPairCAVLC.c
new file mode 100755
index 0000000..b29e576
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DecodeCoeffsToPairCAVLC.c
@@ -0,0 +1,68 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: omxVCM4P10_DecodeCoeffsToPairCAVLC.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 12290
+ * Date: Wednesday, April 9, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * H.264 decode coefficients module
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/**
+ * Function: omxVCM4P10_DecodeCoeffsToPairCAVLC
+ *
+ * Description:
+ * Performs CAVLC decoding and inverse zigzag scan for 4x4 block of
+ * Intra16x16DCLevel, Intra16x16ACLevel,LumaLevel, and ChromaACLevel.
+ * Inverse field scan is not supported. The decoded coefficients in packed
+ * position-coefficient buffer are stored in increasing zigzag order instead
+ * of position order.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream Double pointer to current byte in bit stream buffer
+ * [in] pOffset Pointer to current bit position in the byte pointed
+ * to by *ppBitStream
+ * [in] sMaxNumCoeff Maximum number of non-zero coefficients in current
+ * block
+ * [in] sVLCSelect VLC table selector, obtained from number of non-zero
+ * AC coefficients of above and left 4x4 blocks. It is
+ * equivalent to the variable nC described in H.264 standard
+ * table 9-5, except its value can¡¯t be less than zero.
+ * [out] ppBitStream *ppBitStream is updated after each block is decoded
+ * [out] pOffset *pOffset is updated after each block is decoded
+ * [out] pNumCoeff Pointer to the number of nonzero coefficients in
+ * this block
+ * [out] ppPosCoefbuf Double pointer to destination residual
+ * coefficient-position pair buffer
+ * Return Value:
+ * Standard omxError result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult omxVCM4P10_DecodeCoeffsToPairCAVLC(
+ const OMX_U8** ppBitStream,
+ OMX_S32* pOffset,
+ OMX_U8* pNumCoeff,
+ OMX_U8**ppPosCoefbuf,
+ OMX_INT sVLCSelect,
+ OMX_INT sMaxNumCoeff
+ )
+{
+ return armVCM4P10_DecodeCoeffsToPair(ppBitStream, pOffset, pNumCoeff,
+ ppPosCoefbuf, sVLCSelect, sMaxNumCoeff);
+}
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DequantTransformResidualFromPairAndAdd_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DequantTransformResidualFromPairAndAdd_s.s
new file mode 100755
index 0000000..485a488
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DequantTransformResidualFromPairAndAdd_s.s
@@ -0,0 +1,396 @@
+;//
+;//
+;// File Name: omxVCM4P10_DequantTransformResidualFromPairAndAdd_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 12290
+;// Date: Wednesday, April 9, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+;// Description:
+;// H.264 inverse quantize and transform module
+;//
+;//
+
+
+
+;// Include standard headers
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+;// Import symbols required from other files
+;// (For example tables)
+
+ IMPORT armVCM4P10_UnpackBlock4x4
+ IMPORT armVCM4P10_TransformResidual4x4
+ IMPORT armVCM4P10_QPDivTable
+ IMPORT armVCM4P10_VMatrixU16
+ IMPORT armVCM4P10_QPModuloTable
+
+ M_VARIANTS CortexA8
+
+;// Set debugging level
+;//DEBUG_ON SETL {TRUE}
+
+
+;// Static Function: armVCM4P10_DequantLumaAC4x4
+
+;// Guarding implementation by the processor name
+
+
+
+;// Guarding implementation by the processor name
+
+
+
+
+
+
+;// Function: omxVCM4P10_DequantTransformResidualFromPairAndAdd
+
+;// Guarding implementation by the processor name
+
+
+
+;// Function: omxVCM4P10_DequantTransformResidualFromPairAndAdd
+
+;// Guarding implementation by the processor name
+
+ IF CortexA8
+
+
+;// ARM Registers
+
+;//Input Registers
+ppSrc RN 0
+pPred RN 1
+pDC RN 2
+pDst RN 3
+
+
+;//Output Registers
+result RN 0
+
+;//Local Scratch Registers
+
+;//Registers used in armVCM4P10_DequantLumaAC4x4
+pQPdiv RN 10
+pQPmod RN 11
+pVRow RN 2
+QPmod RN 12
+shift RN 14
+index0 RN 1
+index1 RN 10
+
+;//Registers used in DequantTransformResidualFromPairAndAdd
+pDelta RN 4
+pDeltaTmp RN 6
+AC RN 5 ;//Load from stack
+pPredTemp RN 7
+pDCTemp RN 8
+pDstTemp RN 9
+pDeltaArg1 RN 1
+pDeltaArg0 RN 0
+QP RN 1 ;//Load from stack
+DCval RN 10
+predstep RN 1
+dstStep RN 10
+PredVal1 RN 3
+PredVal2 RN 5
+
+
+
+
+;// Neon Registers
+
+;// Registers used in armVCM4P10_DequantLumaAC4x4
+
+dVmatrix DN D6.8
+dindexRow0 DN D7.32
+dindexRow1 DN D9.32
+dByteIndexRow0 DN D7.8
+dByteIndexRow1 DN D9.8
+dVRow0 DN D8.8
+dVRow1 DN D4.8
+dVRow0U16 DN D8.U16
+dVRow1U16 DN D4.U16
+dVRow2U16 DN D8.U16
+dVRow3U16 DN D4.U16
+
+dShift DN D5.U16
+dSrcRow0 DN D0.I16
+dSrcRow1 DN D1.I16
+dSrcRow2 DN D2.I16
+dSrcRow3 DN D3.I16
+dDqntRow0 DN D0.I16
+dDqntRow1 DN D1.I16
+dDqntRow2 DN D2.I16
+dDqntRow3 DN D3.I16
+
+;// Registers used in TransformResidual4x4
+
+;// Packed Input pixels
+dIn0 DN D0.S16
+dIn1 DN D1.S16
+dIn2 DN D2.S16
+dIn3 DN D3.S16
+qIn01 QN Q0.32
+qIn23 QN Q1.32
+
+;// Intermediate calculations
+dZero DN D4.S16
+de0 DN D5.S16
+de1 DN D6.S16
+de2 DN D7.S16
+de3 DN D8.S16
+dIn1RS DN D7.S16
+dIn3RS DN D8.S16
+df0 DN D0.S16
+df1 DN D1.S16
+df2 DN D2.S16
+df3 DN D3.S16
+qf01 QN Q0.32
+qf23 QN Q1.32
+dg0 DN D5.S16
+dg1 DN D6.S16
+dg2 DN D7.S16
+dg3 DN D8.S16
+df1RS DN D7.S16
+df3RS DN D8.S16
+
+;// Output pixels
+dh0 DN D0.S16
+dh1 DN D1.S16
+dh2 DN D2.S16
+dh3 DN D3.S16
+
+;// Registers used in DequantTransformResidualFromPairAndAdd
+
+dDeltaRow0 DN D0.S16
+dDeltaRow1 DN D1.S16
+dDeltaRow2 DN D2.S16
+dDeltaRow3 DN D3.S16
+qDeltaRow01 QN Q0.S16
+qDeltaRow23 QN Q1.S16
+
+dPredValRow01 DN D4.U8
+dPredValRow23 DN D5.U8
+
+qSumRow01 QN Q3.S16
+qSumRow23 QN Q4.S16
+dDstRow01 DN D0.U8
+dDstRow23 DN D1.U8
+dDstRow0 DN D0.32[0]
+dDstRow1 DN D0.32[1]
+dDstRow2 DN D1.32[0]
+dDstRow3 DN D1.32[1]
+
+
+ ;// Allocate stack memory required by the function
+ M_ALLOC8 pBuffer, 32
+
+
+ ;// Write function header
+ M_START omxVCM4P10_DequantTransformResidualFromPairAndAdd,r11,d9
+
+ ;// Define stack arguments
+ M_ARG predStepOnStack, 4
+ M_ARG dstStepOnStack,4
+ M_ARG QPOnStack, 4
+ M_ARG ACOnStack,4
+
+
+ M_ADR pDelta,pBuffer
+ M_LDR AC,ACOnStack
+
+
+ ;// Save registers r1,r2,r3 before function call
+ MOV pPredTemp,pPred
+ MOV pDCTemp,pDC
+ MOV pDstTemp,pDst
+
+ CMP AC,#0
+ BEQ DCcase
+ MOV pDeltaArg1,pDelta ;// Set up r1 for armVCM4P10_UnpackBlock4x4
+
+ BL armVCM4P10_UnpackBlock4x4
+
+ ;//--------------------------------------------------------
+ ;// armVCM4P10_DequantLumaAC4x4 : static function inlined
+ ;//--------------------------------------------------------
+
+ ;//BL armVCM4P10_DequantLumaAC4x4
+ M_LDR QP,QPOnStack ;// Set up r1 for armVCM4P10_DequantLumaAC4x4
+
+ LDR pQPmod,=armVCM4P10_QPModuloTable
+ LDR pQPdiv,=armVCM4P10_QPDivTable
+ LDR pVRow,=armVCM4P10_VMatrixU16
+
+
+ LDRSB QPmod,[pQPmod,QP] ;// (QP%6) * 6
+ LDRSB shift,[pQPdiv,QP] ;// Shift = QP / 6
+
+ LDR index1,=0x03020504
+ LDR index0,=0x05040100 ;// Indexes into dVmatrix
+ ADD pVRow,pVRow,QPmod
+ VDUP dindexRow0,index0
+ VDUP dindexRow1,index1
+ VDUP dShift,shift
+
+ ;// Load all 4x4 pVRow[] values
+ VLD1 dVmatrix,[pVRow] ;// dVmatrix = [0d|0c|0b|0a]
+
+
+ VTBL dVRow0,dVmatrix,dByteIndexRow0 ;// row0 = row2 = [pVRow[2] | pVRow[0] | pVRow[2] | pVRow[0]]
+ VTBL dVRow1,dVmatrix,dByteIndexRow1 ;// row1 = row3 = [pVRow[1] | pVRow[2] | pVRow[1] | pVRow[2]]
+ CMP pDCTemp,#0
+ ;// Load all the 4x4 'src' values
+ VLD1 { dSrcRow0,dSrcRow1,dSrcRow2,dSrcRow3 },[pDelta]
+
+ VSHL dVRow0U16,dVRow0U16,dShift
+ VSHL dVRow1U16,dVRow1U16,dShift
+ LDRSHNE DCval,[pDCTemp]
+
+
+ ;// Multiply src[] with pVRow[]
+ VMUL dDqntRow0,dSrcRow0,dVRow0U16
+ VMUL dDqntRow1,dSrcRow1,dVRow1U16
+ VMUL dDqntRow2,dSrcRow2,dVRow2U16
+ VMUL dDqntRow3,dSrcRow3,dVRow3U16
+
+
+
+ ;//-------------------------------------------------------------
+ ;// TransformResidual4x4 : Inlined to avoid Load/Stores
+ ;//-------------------------------------------------------------
+
+
+ ;//BL armVCM4P10_TransformResidual4x4
+ ;//STRHNE DCval,[pDelta]
+ VMOVNE dIn0[0],DCval
+
+
+
+ ;//*****************************************************************
+ ;// Transpose the input pixels : perform Row ops as Col ops
+ ;//*****************************************************************
+
+ VTRN dIn0,dIn1
+ VTRN dIn2,dIn3
+ VTRN qIn01,qIn23
+
+
+ VMOV dZero,#0 ;// Used to right shift by 1
+
+
+ ;//****************************************
+ ;// Row Operations (Performed on columns)
+ ;//****************************************
+
+
+ VADD de0,dIn0,dIn2 ;// e0 = d0 + d2
+ VSUB de1,dIn0,dIn2 ;// e1 = d0 - d2
+ VHADD dIn1RS,dIn1,dZero ;// (f1>>1) constZero is a register holding 0
+ VHADD dIn3RS,dIn3,dZero
+ VSUB de2,dIn1RS,dIn3 ;// e2 = (d1>>1) - d3
+ VADD de3,dIn1,dIn3RS ;// e3 = d1 + (d3>>1)
+ VADD df0,de0,de3 ;// f0 = e0 + e3
+ VADD df1,de1,de2 ;// f1 = e1 + e2
+ VSUB df2,de1,de2 ;// f2 = e1 - e2
+ VSUB df3,de0,de3 ;// f3 = e0 - e3
+
+
+
+ ;//*****************************************************************
+ ;// Transpose the resultant matrix
+ ;//*****************************************************************
+
+ VTRN df0,df1
+ VTRN df2,df3
+ VTRN qf01,qf23
+
+
+ ;//*******************************
+ ;// Coloumn Operations
+ ;//*******************************
+
+
+ VADD dg0,df0,df2 ;// e0 = d0 + d2
+ VSUB dg1,df0,df2 ;// e1 = d0 - d2
+ VHADD df1RS,df1,dZero ;// (f1>>1) constZero is a register holding 0
+ VHADD df3RS,df3,dZero
+ VSUB dg2,df1RS,df3 ;// e2 = (d1>>1) - d3
+ VADD dg3,df1,df3RS ;// e3 = d1 + (d3>>1)
+ VADD dh0,dg0,dg3 ;// f0 = e0 + e3
+ VADD dh1,dg1,dg2 ;// f1 = e1 + e2
+ VSUB dh2,dg1,dg2 ;// f2 = e1 - e2
+ VSUB dh3,dg0,dg3 ;// f3 = e0 - e3
+
+
+ ;//************************************************
+ ;// Calculate final value (colOp[i][j] + 32)>>6
+ ;//************************************************
+
+ VRSHR dh0,#6
+ VRSHR dh1,#6
+ VRSHR dh2,#6
+ VRSHR dh3,#6
+
+
+ B OutDCcase
+
+
+DCcase
+ ;// Calculate the Transformed DCvalue : (DCval+32)>>6
+ LDRSH DCval,[pDCTemp]
+ ADD DCval,DCval,#32
+ ASR DCval,DCval,#6
+
+ VDUP dDeltaRow0, DCval ;// pDelta[0] = pDelta[1] = pDelta[2] = pDelta[3] = DCval
+ VDUP dDeltaRow1, DCval ;// pDelta[4] = pDelta[5] = pDelta[6] = pDelta[7] = DCval
+ VDUP dDeltaRow2, DCval ;// pDelta[8] = pDelta[9] = pDelta[10] = pDelta[11] = DCval
+ VDUP dDeltaRow3, DCval
+
+
+OutDCcase
+ M_LDR predstep,predStepOnStack
+ M_LDR dstStep,dstStepOnStack
+
+ LDR PredVal1,[pPredTemp],predstep
+ LDR PredVal2,[pPredTemp],predstep
+ VMOV dPredValRow01,PredVal1,PredVal2
+
+ LDR PredVal1,[pPredTemp],predstep
+ LDR PredVal2,[pPredTemp]
+ VMOV dPredValRow23,PredVal1,PredVal2
+
+
+ VADDW qSumRow01,qDeltaRow01,dPredValRow01
+ VADDW qSumRow23,qDeltaRow23,dPredValRow23
+ VQMOVUN dDstRow01,qSumRow01
+ VQMOVUN dDstRow23,qSumRow23
+
+
+ VST1 dDstRow0,[pDstTemp],dstStep
+ VST1 dDstRow1,[pDstTemp],dstStep
+ VST1 dDstRow2,[pDstTemp],dstStep
+ VST1 dDstRow3,[pDstTemp]
+
+ ;// Set return value
+ MOV result,#OMX_Sts_NoErr
+
+End
+
+
+ ;// Write function tail
+
+ M_END
+
+ ENDIF ;//CORTEXA8
+
+
+
+ END
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_HorEdge_I_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_HorEdge_I_s.s
new file mode 100644
index 0000000..4606197
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_HorEdge_I_s.s
@@ -0,0 +1,202 @@
+;//
+;//
+;// File Name: omxVCM4P10_FilterDeblockingChroma_HorEdge_I_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 12290
+;// Date: Wednesday, April 9, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS CortexA8
+
+ IF CortexA8
+
+ IMPORT armVCM4P10_DeblockingChromabSGE4_unsafe
+ IMPORT armVCM4P10_DeblockingChromabSLT4_unsafe
+
+LOOP_COUNT EQU 0x40000000
+MASK_3 EQU 0x03030303
+MASK_4 EQU 0x04040404
+
+;// Function arguments
+
+pSrcDst RN 0
+srcdstStep RN 1
+pAlpha RN 2
+pBeta RN 3
+
+pThresholds RN 5
+pBS RN 4
+bS3210 RN 6
+
+;// Loop
+
+XY RN 7
+
+;// Pixels
+dP_0 DN D4.U8
+dP_1 DN D5.U8
+dP_2 DN D6.U8
+dQ_0 DN D8.U8
+dQ_1 DN D9.U8
+dQ_2 DN D10.U8
+
+;// Filtering Decision
+dAlpha DN D0.U8
+dBeta DN D2.U8
+
+dFilt DN D16.U8
+dAqflg DN D12.U8
+dApflg DN D17.U8
+
+dAp0q0 DN D13.U8
+dAp1p0 DN D12.U8
+dAq1q0 DN D18.U8
+dAp2p0 DN D19.U8
+dAq2q0 DN D17.U8
+
+qBS3210 QN Q13.U16
+dBS3210 DN D26
+dMask_bs DN D27
+dFilt_bs DN D26.U16
+
+;// bSLT4
+dMask_0 DN D14.U8
+dMask_1 DN D15.U8
+dMask_4 DN D1.U16
+
+Mask_4 RN 8
+Mask_3 RN 9
+
+dTemp DN D19.U8
+
+;// Result
+dP_0t DN D13.U8
+dQ_0t DN D31.U8
+
+dP_0n DN D29.U8
+dQ_0n DN D24.U8
+
+
+ ;// Function header
+ M_START omxVCM4P10_FilterDeblockingChroma_HorEdge_I, r9, d15
+
+ ;//Arguments on the stack
+ M_ARG ppThresholds, 4
+ M_ARG ppBS, 4
+
+ ;// d0-dAlpha_0
+ ;// d2-dBeta_0
+
+ ;load alpha1,beta1 somewhere to avoid more loads
+ VLD1 {dAlpha[]}, [pAlpha]!
+ SUB pSrcDst, pSrcDst, srcdstStep, LSL #1 ;?
+ SUB pSrcDst, pSrcDst, srcdstStep
+ VLD1 {dBeta[]}, [pBeta]!
+
+ M_LDR pBS, ppBS
+ M_LDR pThresholds, ppThresholds
+
+ LDR Mask_3, =MASK_3
+ LDR Mask_4, =MASK_4
+
+ VMOV dMask_0, #0
+ VMOV dMask_1, #1
+ VMOV dMask_4, #4
+
+ LDR XY, =LOOP_COUNT
+
+ ;// p0-p3 - d4-d7
+ ;// q0-q3 - d8-d11
+LoopY
+ LDR bS3210, [pBS], #8
+
+ VLD1 dP_2, [pSrcDst], srcdstStep
+ ;1
+ VLD1 dP_1, [pSrcDst], srcdstStep
+ CMP bS3210, #0
+ VLD1 dP_0, [pSrcDst], srcdstStep
+ ;1
+ VLD1 dQ_0, [pSrcDst], srcdstStep
+ VABD dAp2p0, dP_2, dP_0
+ VLD1 dQ_1, [pSrcDst], srcdstStep
+ VABD dAp0q0, dP_0, dQ_0
+ VLD1 dQ_2, [pSrcDst], srcdstStep
+ BEQ NoFilterBS0
+
+ VABD dAp1p0, dP_1, dP_0
+ VABD dAq1q0, dQ_1, dQ_0
+
+ VCGT dFilt, dAlpha, dAp0q0
+ VMOV.U32 dBS3210[0], bS3210
+ VMAX dAp1p0, dAq1q0, dAp1p0
+ VMOVL qBS3210, dBS3210.U8
+ VABD dAq2q0, dQ_2, dQ_0
+ VCGT dMask_bs.S16, dBS3210.S16, #0
+
+ VCGT dAp1p0, dBeta, dAp1p0
+ VCGT dAp2p0, dBeta, dAp2p0
+
+ VAND dFilt, dMask_bs.U8
+
+ TST bS3210, Mask_3
+
+ VCGT dAq2q0, dBeta, dAq2q0
+ VAND dFilt, dFilt, dAp1p0
+
+ VAND dAqflg, dFilt, dAq2q0
+ VAND dApflg, dFilt, dAp2p0
+
+ ;// bS < 4 Filtering
+ BLNE armVCM4P10_DeblockingChromabSLT4_unsafe
+
+ TST bS3210, Mask_4
+
+ SUB pSrcDst, pSrcDst, srcdstStep, LSL #2
+ VTST dFilt_bs, dFilt_bs, dMask_4
+
+ ;// bS == 4 Filtering
+ BLNE armVCM4P10_DeblockingChromabSGE4_unsafe
+
+ VBIT dP_0n, dP_0t, dFilt_bs
+ VBIT dQ_0n, dQ_0t, dFilt_bs
+
+ VBIF dP_0n, dP_0, dFilt
+ VBIF dQ_0n, dQ_0, dFilt
+
+ ;// Result Storage
+ VST1 dP_0n, [pSrcDst], srcdstStep
+ ADDS XY, XY, XY
+ VST1 dQ_0n, [pSrcDst], srcdstStep
+
+ BNE LoopY
+
+ MOV r0, #OMX_Sts_NoErr
+
+ M_EXIT
+
+NoFilterBS0
+
+ VLD1 {dAlpha[]}, [pAlpha]
+ SUB pSrcDst, pSrcDst, srcdstStep, LSL #1
+ ADDS XY, XY, XY
+ VLD1 {dBeta[]}, [pBeta]
+ ADD pThresholds, pThresholds, #4
+ BNE LoopY
+
+ MOV r0, #OMX_Sts_NoErr
+ M_END
+
+ ENDIF
+
+
+ END
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_VerEdge_I_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_VerEdge_I_s.s
new file mode 100644
index 0000000..18e6c1d
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_VerEdge_I_s.s
@@ -0,0 +1,282 @@
+;//
+;//
+;// File Name: omxVCM4P10_FilterDeblockingChroma_VerEdge_I_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 12290
+;// Date: Wednesday, April 9, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS CortexA8
+
+ IF CortexA8
+
+ IMPORT armVCM4P10_DeblockingChromabSGE4_unsafe
+ IMPORT armVCM4P10_DeblockingChromabSLT4_unsafe
+
+LOOP_COUNT EQU 0x40000000
+MASK_3 EQU 0x03030303
+MASK_4 EQU 0x04040404
+
+;// Function arguments
+
+pSrcDst RN 0
+srcdstStep RN 1
+pAlpha RN 2
+pBeta RN 3
+
+pThresholds RN 5
+pBS RN 4
+bS3210 RN 6
+pSrcDst_P RN 10
+pSrcDst_Q RN 12
+
+pTmp RN 10
+pTmp2 RN 12
+step RN 14
+
+;// Loop
+
+XY RN 7
+
+;// Rows input
+dRow0 DN D7.U8
+dRow1 DN D8.U8
+dRow2 DN D5.U8
+dRow3 DN D10.U8
+dRow4 DN D6.U8
+dRow5 DN D9.U8
+dRow6 DN D4.U8
+dRow7 DN D11.U8
+
+
+;// Pixels
+dP_0 DN D4.U8
+dP_1 DN D5.U8
+dP_2 DN D6.U8
+dQ_0 DN D8.U8
+dQ_1 DN D9.U8
+dQ_2 DN D10.U8
+
+;// Filtering Decision
+dAlpha DN D0.U8
+dBeta DN D2.U8
+
+dFilt DN D16.U8
+dAqflg DN D12.U8
+dApflg DN D17.U8
+
+dAp0q0 DN D13.U8
+dAp1p0 DN D12.U8
+dAq1q0 DN D18.U8
+dAp2p0 DN D19.U8
+dAq2q0 DN D17.U8
+
+qBS3210 QN Q13.U16
+dBS3210 DN D26
+dMask_bs DN D27
+dFilt_bs DN D26.U16
+
+;// bSLT4
+dMask_0 DN D14.U8
+dMask_1 DN D15.U8
+dMask_4 DN D1.U16
+
+Mask_4 RN 8
+Mask_3 RN 9
+
+dTemp DN D19.U8
+
+;// Result
+dP_0t DN D13.U8
+dQ_0t DN D31.U8
+
+dP_0n DN D29.U8
+dQ_0n DN D24.U8
+
+
+ ;// Function header
+ M_START omxVCM4P10_FilterDeblockingChroma_VerEdge_I, r12, d15
+
+ ;//Arguments on the stack
+ M_ARG ppThresholds, 4
+ M_ARG ppBS, 4
+
+ ;// d0-dAlpha_0
+ ;// d2-dBeta_0
+
+ ;load alpha1,beta1 somewhere to avoid more loads
+ VLD1 {dAlpha[]}, [pAlpha]!
+ SUB pSrcDst, pSrcDst, #4
+ VLD1 {dBeta[]}, [pBeta]!
+
+ M_LDR pBS, ppBS
+ M_LDR pThresholds, ppThresholds
+
+ LDR Mask_4, =MASK_4
+ LDR Mask_3, =MASK_3
+
+ ;dMask_0-14
+ ;dMask_1-15
+ ;dMask_4-19
+
+ VMOV dMask_0, #0
+ VMOV dMask_1, #1
+ VMOV dMask_4, #4
+
+ LDR XY, =LOOP_COUNT
+
+ ;// p0-p3 - d4-d7
+ ;// q0-q3 - d8-d11
+
+
+LoopY
+ LDR bS3210, [pBS], #8
+ ADD pTmp, pSrcDst, srcdstStep
+ ADD step, srcdstStep, srcdstStep
+
+ ;1
+ VLD1 dRow0, [pSrcDst], step
+ ;1
+ VLD1 dRow1, [pTmp], step
+ VLD1 dRow2, [pSrcDst], step
+ VLD1 dRow3, [pTmp], step
+ VLD1 dRow4, [pSrcDst], step
+ VLD1 dRow5, [pTmp], step
+ VLD1 dRow6, [pSrcDst], step
+ VLD1 dRow7, [pTmp], step
+
+
+ ;// dRow0 = [q3r0 q2r0 q1r0 q0r0 p0r0 p1r0 p2r0 p3r0]
+ ;// dRow1 = [q3r1 q2r1 q1r1 q0r1 p0r1 p1r1 p2r1 p3r1]
+ ;// dRow2 = [q3r2 q2r2 q1r2 q0r2 p0r2 p1r2 p2r2 p3r2]
+ ;// dRow3 = [q3r3 q2r3 q1r3 q0r3 p0r3 p1r3 p2r3 p3r3]
+ ;// dRow4 = [q3r4 q2r4 q1r4 q0r4 p0r4 p1r4 p2r4 p3r4]
+ ;// dRow5 = [q3r5 q2r5 q1r5 q0r5 p0r5 p1r5 p2r5 p3r5]
+ ;// dRow6 = [q3r6 q2r6 q1r6 q0r6 p0r6 p1r6 p2r6 p3r6]
+ ;// dRow7 = [q3r7 q2r7 q1r7 q0r7 p0r7 p1r7 p2r7 p3r7]
+
+ ;// 8x8 Transpose
+ VZIP.8 dRow0, dRow1
+ VZIP.8 dRow2, dRow3
+ VZIP.8 dRow4, dRow5
+ VZIP.8 dRow6, dRow7
+
+ VZIP.16 dRow0, dRow2
+ VZIP.16 dRow1, dRow3
+ VZIP.16 dRow4, dRow6
+ VZIP.16 dRow5, dRow7
+
+ VZIP.32 dRow0, dRow4
+ VZIP.32 dRow2, dRow6
+ VZIP.32 dRow3, dRow7
+ VZIP.32 dRow1, dRow5
+
+
+ ;Realign the pointers
+
+ CMP bS3210, #0
+ VABD dAp2p0, dP_2, dP_0
+ VABD dAp0q0, dP_0, dQ_0
+ BEQ NoFilterBS0
+
+ VABD dAp1p0, dP_1, dP_0
+ VABD dAq1q0, dQ_1, dQ_0
+
+ VMOV.U32 dBS3210[0], bS3210
+ VCGT dFilt, dAlpha, dAp0q0
+ VMAX dAp1p0, dAq1q0, dAp1p0
+ VMOVL qBS3210, dBS3210.U8
+ VABD dAq2q0, dQ_2, dQ_0
+ VCGT dMask_bs.S16, dBS3210.S16, #0
+
+ VCGT dAp1p0, dBeta, dAp1p0
+ VCGT dAp2p0, dBeta, dAp2p0
+ VAND dFilt, dMask_bs.U8
+
+ TST bS3210, Mask_3
+
+ VCGT dAq2q0, dBeta, dAq2q0
+ VAND dFilt, dFilt, dAp1p0
+
+ VAND dAqflg, dFilt, dAq2q0
+ VAND dApflg, dFilt, dAp2p0
+
+ ;// bS < 4 Filtering
+ BLNE armVCM4P10_DeblockingChromabSLT4_unsafe
+
+ TST bS3210, Mask_4
+
+ SUB pSrcDst, pSrcDst, srcdstStep, LSL #3
+ VTST dFilt_bs, dFilt_bs, dMask_4
+
+ ;// bS == 4 Filtering
+ BLNE armVCM4P10_DeblockingChromabSGE4_unsafe
+
+ VBIT dP_0n, dP_0t, dFilt_bs
+ VBIT dQ_0n, dQ_0t, dFilt_bs
+
+ ;// Result Storage
+ ADD pSrcDst_P, pSrcDst, #3
+ VBIF dP_0n, dP_0, dFilt
+
+ ADD pTmp2, pSrcDst_P, srcdstStep
+ ADD step, srcdstStep, srcdstStep
+ VBIF dQ_0n, dQ_0, dFilt
+
+ ADDS XY, XY, XY
+
+ VST1 {dP_0n[0]}, [pSrcDst_P], step
+ VST1 {dP_0n[1]}, [pTmp2], step
+ VST1 {dP_0n[2]}, [pSrcDst_P], step
+ VST1 {dP_0n[3]}, [pTmp2], step
+ VST1 {dP_0n[4]}, [pSrcDst_P], step
+ VST1 {dP_0n[5]}, [pTmp2], step
+ VST1 {dP_0n[6]}, [pSrcDst_P], step
+ VST1 {dP_0n[7]}, [pTmp2], step
+
+ ADD pSrcDst_Q, pSrcDst, #4
+ ADD pTmp, pSrcDst_Q, srcdstStep
+
+ VST1 {dQ_0n[0]}, [pSrcDst_Q], step
+ VST1 {dQ_0n[1]}, [pTmp], step
+ VST1 {dQ_0n[2]}, [pSrcDst_Q], step
+ VST1 {dQ_0n[3]}, [pTmp], step
+ VST1 {dQ_0n[4]}, [pSrcDst_Q], step
+ VST1 {dQ_0n[5]}, [pTmp], step
+ VST1 {dQ_0n[6]}, [pSrcDst_Q], step
+ VST1 {dQ_0n[7]}, [pTmp], step
+
+ ADD pSrcDst, pSrcDst, #4
+
+ BNE LoopY
+
+ MOV r0, #OMX_Sts_NoErr
+
+ M_EXIT
+
+NoFilterBS0
+ VLD1 {dAlpha[]}, [pAlpha]
+ ADD pSrcDst, pSrcDst, #4
+ SUB pSrcDst, pSrcDst, srcdstStep, LSL #3
+ ADDS XY, XY, XY
+ VLD1 {dBeta[]}, [pBeta]
+ ADD pThresholds, pThresholds, #4
+ BNE LoopY
+
+ MOV r0, #OMX_Sts_NoErr
+
+ M_END
+
+ ENDIF
+
+
+ END
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_HorEdge_I_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_HorEdge_I_s.s
new file mode 100755
index 0000000..0c3f4f2
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_HorEdge_I_s.s
@@ -0,0 +1,288 @@
+;//
+;//
+;// File Name: omxVCM4P10_FilterDeblockingLuma_HorEdge_I_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 12290
+;// Date: Wednesday, April 9, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS CortexA8
+
+ IMPORT armVCM4P10_DeblockingLumabSLT4_unsafe
+ IMPORT armVCM4P10_DeblockingLumabSGE4_unsafe
+
+ IF CortexA8
+
+LOOP_COUNT EQU 0x55000000
+
+
+;// Function arguments
+
+pSrcDst RN 0
+srcdstStep RN 1
+pAlpha RN 2
+pBeta RN 3
+
+pThresholds RN 5
+pBS RN 4
+bS10 RN 12
+
+pAlpha_0 RN 2
+pBeta_0 RN 3
+
+pAlpha_1 RN 7
+pBeta_1 RN 8
+
+
+
+;// Loop
+
+XY RN 9
+
+pTmp RN 6
+step RN 10
+
+;// Pixels
+dP_0 DN D4.U8
+dP_1 DN D5.U8
+dP_2 DN D6.U8
+dP_3 DN D7.U8
+dQ_0 DN D8.U8
+dQ_1 DN D9.U8
+dQ_2 DN D10.U8
+dQ_3 DN D11.U8
+
+
+;// Filtering Decision
+dAlpha DN D0.U8
+dBeta DN D2.U8
+
+dFilt DN D16.U8
+dAqflg DN D12.U8
+dApflg DN D17.U8
+
+dAp0q0 DN D13.U8
+dAp1p0 DN D12.U8
+dAq1q0 DN D18.U8
+dAp2p0 DN D19.U8
+dAq2q0 DN D17.U8
+
+;// bSLT4
+dTC0 DN D18.U8
+dTC1 DN D19.U8
+dTC01 DN D18.U8
+
+dTCs DN D31.S8
+dTC DN D31.U8
+
+dMask_0 DN D14.U8
+dMask_1 DN D15.U8
+
+Mask_0 RN 11
+
+dTemp DN D19.U8
+
+;// Computing P0,Q0
+qDq0p0 QN Q10.S16
+qDp1q1 QN Q11.S16
+qDelta QN Q10.S16 ; reuse qDq0p0
+dDelta DN D20.S8
+
+
+;// Computing P1,Q1
+dRp0q0 DN D24.U8
+
+dMaxP DN D23.U8
+dMinP DN D22.U8
+
+dMaxQ DN D19.U8
+dMinQ DN D21.U8
+
+dDeltaP DN D26.U8
+dDeltaQ DN D27.U8
+
+qP_0n QN Q14.S16
+qQ_0n QN Q12.S16
+
+dQ_0n DN D24.U8
+dQ_1n DN D25.U8
+dP_0n DN D29.U8
+dP_1n DN D30.U8
+
+;// bSGE4
+
+qSp0q0 QN Q10.U16
+
+qSp2q1 QN Q11.U16
+qSp0q0p1 QN Q12.U16
+qSp3p2 QN Q13.U16
+dHSp0q1 DN D28.U8
+
+qSq2p1 QN Q11.U16
+qSp0q0q1 QN Q12.U16
+qSq3q2 QN Q13.U16 ;!!
+dHSq0p1 DN D28.U8 ;!!
+
+qTemp1 QN Q11.U16 ;!!;qSp2q1
+qTemp2 QN Q12.U16 ;!!;qSp0q0p1
+
+dP_0t DN D28.U8 ;!!;dHSp0q1
+dQ_0t DN D22.U8 ;!!;Temp1
+
+dP_0n DN D29.U8
+dP_1n DN D30.U8
+dP_2n DN D31.U8
+
+dQ_0n DN D24.U8 ;!!;Temp2
+dQ_1n DN D25.U8 ;!!;Temp2
+dQ_2n DN D28.U8 ;!!;dQ_0t
+
+
+ ;// Function header
+ M_START omxVCM4P10_FilterDeblockingLuma_HorEdge_I, r11, d15
+
+ ;//Arguments on the stack
+ M_ARG ppThresholds, 4
+ M_ARG ppBS, 4
+
+ ;// d0-dAlpha_0
+ ;// d2-dBeta_0
+
+ ADD pAlpha_1, pAlpha_0, #1
+ ADD pBeta_1, pBeta_0, #1
+
+ VLD1 {dAlpha[]}, [pAlpha_0]
+ SUB pSrcDst, pSrcDst, srcdstStep, LSL #2
+ VLD1 {dBeta[]}, [pBeta_0]
+
+ M_LDR pBS, ppBS
+ M_LDR pThresholds, ppThresholds
+
+ MOV Mask_0,#0
+
+ ;dMask_0-14
+ ;dMask_1-15
+
+ VMOV dMask_0, #0
+ VMOV dMask_1, #1
+
+ ADD step, srcdstStep, srcdstStep
+
+ LDR XY,=LOOP_COUNT
+
+ ;// p0-p3 - d4-d7
+ ;// q0-q3 - d8-d11
+LoopY
+LoopX
+ LDRH bS10, [pBS], #2
+ ADD pTmp, pSrcDst, srcdstStep
+ CMP bS10, #0
+ BEQ NoFilterBS0
+
+ VLD1 dP_3, [pSrcDst], step
+ VLD1 dP_2, [pTmp], step
+ VLD1 dP_1, [pSrcDst], step
+ VLD1 dP_0, [pTmp], step
+ VLD1 dQ_0, [pSrcDst], step
+ VABD dAp1p0, dP_0, dP_1
+ VLD1 dQ_1, [pTmp]
+ VABD dAp0q0, dQ_0, dP_0
+ VLD1 dQ_2, [pSrcDst], srcdstStep
+
+ VABD dAq1q0, dQ_1, dQ_0
+ VABD dAp2p0, dP_2, dP_0
+ VCGT dFilt, dAlpha, dAp0q0
+
+ TST bS10, #0xff
+ VMAX dAp1p0, dAq1q0, dAp1p0
+ VABD dAq2q0, dQ_2, dQ_0
+
+ VMOVEQ.U32 dFilt[0], Mask_0
+ TST bS10, #0xff00
+
+ VCGT dAp2p0, dBeta, dAp2p0
+ VCGT dAp1p0, dBeta, dAp1p0
+
+ VMOVEQ.U32 dFilt[1], Mask_0
+
+ VCGT dAq2q0, dBeta, dAq2q0
+ VLD1 dQ_3, [pSrcDst]
+ VAND dFilt, dFilt, dAp1p0
+ TST bS10, #4
+
+ VAND dAqflg, dFilt, dAq2q0
+ VAND dApflg, dFilt, dAp2p0
+
+ BNE bSGE4
+bSLT4
+ ;// bS < 4 Filtering
+ SUB pSrcDst, pSrcDst, srcdstStep, LSL #2
+ SUB pSrcDst, pSrcDst, srcdstStep
+
+ BL armVCM4P10_DeblockingLumabSLT4_unsafe
+
+ ;// Result Storage
+ VST1 dP_1n, [pSrcDst], srcdstStep
+ VST1 dP_0n, [pSrcDst], srcdstStep
+ SUB pTmp, pSrcDst, srcdstStep, LSL #2
+ VST1 dQ_0n, [pSrcDst], srcdstStep
+ ADDS XY, XY, XY
+ VST1 dQ_1n, [pSrcDst]
+ ADD pSrcDst, pTmp, #8
+
+ BCC LoopX
+ B ExitLoopY
+
+NoFilterBS0
+ ADD pSrcDst, pSrcDst, #8
+ ADDS XY, XY, XY
+ ADD pThresholds, pThresholds, #2
+ BCC LoopX
+ B ExitLoopY
+bSGE4
+ ;// bS >= 4 Filtering
+ SUB pSrcDst, pSrcDst, srcdstStep, LSL #2
+ SUB pSrcDst, pSrcDst, srcdstStep, LSL #1
+ BL armVCM4P10_DeblockingLumabSGE4_unsafe
+
+ ;// Result Storage
+ VST1 dP_2n, [pSrcDst], srcdstStep
+ VST1 dP_1n, [pSrcDst], srcdstStep
+ VST1 dP_0n, [pSrcDst], srcdstStep
+ SUB pTmp, pSrcDst, srcdstStep, LSL #2
+ VST1 dQ_0n, [pSrcDst], srcdstStep
+ ADDS XY,XY,XY
+ VST1 dQ_1n, [pSrcDst], srcdstStep
+ ADD pThresholds, pThresholds, #2
+ VST1 dQ_2n, [pSrcDst]
+
+ ADD pSrcDst, pTmp, #8
+ BCC LoopX
+
+ExitLoopY
+
+ SUB pSrcDst, pSrcDst, #16
+ VLD1 {dAlpha[]}, [pAlpha_1]
+ ADD pSrcDst, pSrcDst, srcdstStep, LSL #2
+ VLD1 {dBeta[]}, [pBeta_1]
+ BNE LoopY
+
+ MOV r0, #OMX_Sts_NoErr
+
+ M_END
+
+ ENDIF
+
+
+
+
+ END
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_VerEdge_I_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_VerEdge_I_s.s
new file mode 100755
index 0000000..e6fbb34
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_VerEdge_I_s.s
@@ -0,0 +1,436 @@
+;//
+;//
+;// File Name: omxVCM4P10_FilterDeblockingLuma_VerEdge_I_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 12290
+;// Date: Wednesday, April 9, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS CortexA8
+
+ IMPORT armVCM4P10_DeblockingLumabSLT4_unsafe
+ IMPORT armVCM4P10_DeblockingLumabSGE4_unsafe
+
+ IF CortexA8
+
+LOOP_COUNT EQU 0x11000000
+
+
+;// Function arguments
+
+pSrcDst RN 0
+srcdstStep RN 1
+pAlpha RN 2
+pBeta RN 3
+
+pThresholds RN 5
+pBS RN 4
+bS10 RN 12
+
+pAlpha_0 RN 2
+pBeta_0 RN 3
+
+pAlpha_1 RN 7
+pBeta_1 RN 8
+
+pTmp RN 10
+pTmpStep RN 11
+
+;// Loop
+
+XY RN 9
+
+;// Rows input
+dRow0 DN D7.U8
+dRow1 DN D8.U8
+dRow2 DN D5.U8
+dRow3 DN D10.U8
+dRow4 DN D6.U8
+dRow5 DN D9.U8
+dRow6 DN D4.U8
+dRow7 DN D11.U8
+
+;// dRow0 - dP_3, dRow1 - dQ_0, dRow2 - dP_1, dRow3 - dQ_2
+;// dRow4 - dP_2, dRow5 - dQ_1, dRow6 - dP_0, dRow7 - dQ_3
+
+;// Rows output
+dRown0 DN D7.U8
+dRown1 DN D24.U8
+dRown2 DN D30.U8
+dRown3 DN D10.U8
+dRown4 DN D6.U8
+dRown5 DN D25.U8
+dRown6 DN D29.U8
+dRown7 DN D11.U8
+
+;// dP_0n DN D29.U8
+;// dP_1n DN D30.U8
+;// dP_2n DN D31.U8
+;//
+;// dQ_0n DN D24.U8 ;!!;Temp2
+;// dQ_1n DN D25.U8 ;!!;Temp2
+;// dQ_2n DN D28.U8 ;!!;dQ_0t
+;//
+;// dRown0 - dP_3, dRown1 - dQ_0n
+;// dRown2 - dP_1n, dRown3 - dQ_2
+;// dRown4 - dP_2, dRown5 - dQ_1n
+;// dRown6 - dP_0n, dRown7 - dQ_3
+
+dRow0n DN D7.U8
+dRow1n DN D24.U8
+dRow2n DN D30.U8
+dRow3n DN D28.U8
+dRow4n DN D31.U8
+dRow5n DN D25.U8
+dRow6n DN D29.U8
+dRow7n DN D11.U8
+
+;// dRow0n - dP_3, dRow1n - dQ_0n, dRow2n - dP_1n, dRow3n - dQ_2n
+;// dRow4n - dP_2, dRow5n - dQ_1n, dRow6n - dP_0n, dRow7n - dQ_3
+
+;// Pixels
+dP_0 DN D4.U8
+dP_1 DN D5.U8
+dP_2 DN D6.U8
+dP_3 DN D7.U8
+dQ_0 DN D8.U8
+dQ_1 DN D9.U8
+dQ_2 DN D10.U8
+dQ_3 DN D11.U8
+
+
+;// Filtering Decision
+dAlpha DN D0.U8
+dBeta DN D2.U8
+
+dFilt DN D16.U8
+dAqflg DN D12.U8
+dApflg DN D17.U8
+
+dAp0q0 DN D13.U8
+dAp1p0 DN D12.U8
+dAq1q0 DN D18.U8
+dAp2p0 DN D19.U8
+dAq2q0 DN D17.U8
+
+;// bSLT4
+dTC0 DN D18.U8
+dTC1 DN D19.U8
+dTC01 DN D18.U8
+
+dTCs DN D31.S8
+dTC DN D31.U8
+
+dMask_0 DN D14.U8
+dMask_1 DN D15.U8
+
+Mask_0 RN 6
+
+dTemp DN D19.U8
+
+;// Computing P0,Q0
+qDq0p0 QN Q10.S16
+qDp1q1 QN Q11.S16
+qDelta QN Q10.S16 ; reuse qDq0p0
+dDelta DN D20.S8
+
+
+;// Computing P1,Q1
+dRp0q0 DN D24.U8
+
+dMaxP DN D23.U8
+dMinP DN D22.U8
+
+dMaxQ DN D19.U8
+dMinQ DN D21.U8
+
+dDeltaP DN D26.U8
+dDeltaQ DN D27.U8
+
+qP_0n QN Q14.S16
+qQ_0n QN Q12.S16
+
+dQ_0n DN D24.U8
+dQ_1n DN D25.U8
+dP_0n DN D29.U8
+dP_1n DN D30.U8
+
+;// bSGE4
+
+qSp0q0 QN Q10.U16
+
+qSp2q1 QN Q11.U16
+qSp0q0p1 QN Q12.U16
+qSp3p2 QN Q13.U16
+dHSp0q1 DN D28.U8
+
+qSq2p1 QN Q11.U16
+qSp0q0q1 QN Q12.U16
+qSq3q2 QN Q13.U16 ;!!
+dHSq0p1 DN D28.U8 ;!!
+
+qTemp1 QN Q11.U16 ;!!;qSp2q1
+qTemp2 QN Q12.U16 ;!!;qSp0q0p1
+
+dP_0t DN D28.U8 ;!!;dHSp0q1
+dQ_0t DN D22.U8 ;!!;Temp1
+
+dP_0n DN D29.U8
+dP_1n DN D30.U8
+dP_2n DN D31.U8
+
+dQ_0n DN D24.U8 ;!!;Temp2
+dQ_1n DN D25.U8 ;!!;Temp2
+dQ_2n DN D28.U8 ;!!;dQ_0t
+
+
+ ;// Function header
+ M_START omxVCM4P10_FilterDeblockingLuma_VerEdge_I, r11, d15
+
+ ;//Arguments on the stack
+ M_ARG ppThresholds, 4
+ M_ARG ppBS, 4
+
+ ;// d0-dAlpha_0
+ ;// d2-dBeta_0
+
+ ADD pAlpha_1, pAlpha_0, #1
+ ADD pBeta_1, pBeta_0, #1
+
+ VLD1 {dAlpha[]}, [pAlpha_0]
+ SUB pSrcDst, pSrcDst, #4
+ VLD1 {dBeta[]}, [pBeta_0]
+
+ M_LDR pBS, ppBS
+ M_LDR pThresholds, ppThresholds
+
+ MOV Mask_0,#0
+
+ ;dMask_0-14
+ ;dMask_1-15
+
+ VMOV dMask_0, #0
+ VMOV dMask_1, #1
+
+ LDR XY,=LOOP_COUNT
+
+ ADD pTmpStep, srcdstStep, srcdstStep
+
+ ;// p0-p3 - d4-d7
+ ;// q0-q3 - d8-d11
+LoopY
+LoopX
+ LDRH bS10, [pBS], #4
+
+ CMP bS10, #0
+ BEQ NoFilterBS0
+
+ ;// Load 8 rows of data
+ ADD pTmp, pSrcDst, srcdstStep
+ VLD1 dRow0, [pSrcDst], pTmpStep
+ VLD1 dRow1, [pTmp], pTmpStep
+ VLD1 dRow2, [pSrcDst], pTmpStep
+ VZIP.8 dRow0, dRow1
+ VLD1 dRow3, [pTmp], pTmpStep
+ VLD1 dRow4, [pSrcDst], pTmpStep
+ VZIP.8 dRow2, dRow3
+ VLD1 dRow5, [pTmp], pTmpStep
+ VLD1 dRow6, [pSrcDst], pTmpStep
+ VLD1 dRow7, [pTmp], pTmpStep
+ VZIP.8 dRow4, dRow5
+ VZIP.16 dRow1, dRow3
+
+
+ ;// dRow0 = [q3r0 q2r0 q1r0 q0r0 p0r0 p1r0 p2r0 p3r0]
+ ;// dRow1 = [q3r1 q2r1 q1r1 q0r1 p0r1 p1r1 p2r1 p3r1]
+ ;// dRow2 = [q3r2 q2r2 q1r2 q0r2 p0r2 p1r2 p2r2 p3r2]
+ ;// dRow3 = [q3r3 q2r3 q1r3 q0r3 p0r3 p1r3 p2r3 p3r3]
+ ;// dRow4 = [q3r4 q2r4 q1r4 q0r4 p0r4 p1r4 p2r4 p3r4]
+ ;// dRow5 = [q3r5 q2r5 q1r5 q0r5 p0r5 p1r5 p2r5 p3r5]
+ ;// dRow6 = [q3r6 q2r6 q1r6 q0r6 p0r6 p1r6 p2r6 p3r6]
+ ;// dRow7 = [q3r7 q2r7 q1r7 q0r7 p0r7 p1r7 p2r7 p3r7]
+
+ ;// 8x8 Transpose
+
+ VZIP.8 dRow6, dRow7
+
+ SUB pSrcDst, pSrcDst, srcdstStep, LSL #3
+ VZIP.16 dRow0, dRow2
+ VZIP.16 dRow5, dRow7
+
+
+ VZIP.16 dRow4, dRow6
+ VZIP.32 dRow1, dRow5
+ VZIP.32 dRow2, dRow6
+ VZIP.32 dRow3, dRow7
+ VZIP.32 dRow0, dRow4
+
+
+ ;// dRow0 - dP_3, dRow1 - dQ_0, dRow2 - dP_1, dRow3 - dQ_2
+ ;// dRow4 - dP_2, dRow5 - dQ_1, dRow6 - dP_0, dRow7 - dQ_3
+
+ ;// dQ_0 = [q0r7 q0r6 q0r5 q0r4 q0r3 q0r2 q0r1 q0r0]
+ ;// dQ_1 = [q1r7 q1r6 q1r5 q1r4 q1r3 q1r2 q1r1 q1r0]
+ ;// dQ_2 = [q2r7 q2r6 q2r5 q2r4 q2r3 q2r2 q2r1 q2r0]
+ ;// dQ_3 = [q3r7 q3r6 q3r5 q3r4 q3r3 q3r2 q3r1 q3r0]
+
+ ;// dP_0 = [p0r7 p0r6 p0r5 p0r4 p0r3 p0r2 p0r1 p0r0]
+ ;// dP_1 = [p1r7 p1r6 p1r5 p1r4 p1r3 p1r2 p1r1 p1r0]
+ ;// dP_2 = [p2r7 p2r6 p2r5 p2r4 p2r3 p2r2 p2r1 p2r0]
+ ;// dP_3 = [p3r7 p3r6 p3r5 p3r4 p3r3 p3r2 p3r1 p3r0]
+
+ VABD dAp0q0, dP_0, dQ_0
+ VABD dAp1p0, dP_1, dP_0
+
+ VABD dAq1q0, dQ_1, dQ_0
+ VABD dAp2p0, dP_2, dP_0
+
+ TST bS10, #0xff
+ VCGT dFilt, dAlpha, dAp0q0
+
+ VMAX dAp1p0, dAq1q0, dAp1p0
+ VABD dAq2q0, dQ_2, dQ_0
+
+ VMOVEQ.U32 dFilt[0], Mask_0
+ TST bS10, #0xff00
+
+ VCGT dAp2p0, dBeta, dAp2p0
+ VCGT dAp1p0, dBeta, dAp1p0
+
+ VMOVEQ.U32 dFilt[1], Mask_0
+
+ VCGT dAq2q0, dBeta, dAq2q0
+ VAND dFilt, dFilt, dAp1p0
+ TST bS10, #4
+
+ VAND dAqflg, dFilt, dAq2q0
+ VAND dApflg, dFilt, dAp2p0
+
+ BNE bSGE4
+bSLT4
+ ;// bS < 4 Filtering
+
+ BL armVCM4P10_DeblockingLumabSLT4_unsafe
+
+ ;// Transpose
+
+ VZIP.8 dP_3, dP_2
+ VZIP.8 dP_1n, dP_0n
+ VZIP.8 dQ_0n, dQ_1n
+ VZIP.8 dQ_2, dQ_3
+
+
+ VZIP.16 dP_3, dP_1n
+ ADD pTmp, pSrcDst, srcdstStep
+ VZIP.16 dQ_0n, dQ_2
+ VZIP.16 dQ_1n, dQ_3
+ VZIP.16 dP_2, dP_0n
+
+ VZIP.32 dP_3, dQ_0n
+ VZIP.32 dP_1n, dQ_2
+ VZIP.32 dP_2, dQ_1n
+ VZIP.32 dP_0n, dQ_3
+
+ ;// dRown0 - dP_3, dRown1 - dQ_0n
+ ;// dRown2 - dP_1n, dRown3 - dQ_2
+ ;// dRown4 - dP_2, dRown5 - dQ_1n
+ ;// dRown6 - dP_0n, dRown7 - dQ_3
+
+ VST1 dRown0, [pSrcDst], pTmpStep
+ VST1 dRown1, [pTmp], pTmpStep
+ VST1 dRown2, [pSrcDst], pTmpStep
+ VST1 dRown3, [pTmp], pTmpStep
+ ;1
+ VST1 dRown4, [pSrcDst], pTmpStep
+ VST1 dRown5, [pTmp], pTmpStep
+ ADDS XY, XY, XY
+ VST1 dRown6, [pSrcDst], pTmpStep
+ ADD pThresholds, pThresholds, #2
+ VST1 dRown7, [pTmp], srcdstStep
+
+ SUB pSrcDst, pSrcDst, srcdstStep, LSL #3
+ VLD1 {dAlpha[]}, [pAlpha_1]
+ ADD pSrcDst, pSrcDst, #4
+ VLD1 {dBeta[]}, [pBeta_1]
+
+ BCC LoopX
+ B ExitLoopY
+
+NoFilterBS0
+ ADD pSrcDst, pSrcDst, #4
+ ADDS XY, XY, XY
+ VLD1 {dAlpha[]}, [pAlpha_1]
+ ADD pThresholds, pThresholds, #4
+ VLD1 {dBeta[]}, [pBeta_1]
+ BCC LoopX
+ B ExitLoopY
+bSGE4
+ ;// bS >= 4 Filtering
+
+ BL armVCM4P10_DeblockingLumabSGE4_unsafe
+
+ ;// Transpose
+
+ VZIP.8 dP_3, dP_2n
+ VZIP.8 dP_1n, dP_0n
+ VZIP.8 dQ_0n, dQ_1n
+ VZIP.8 dQ_2n, dQ_3
+
+ VZIP.16 dP_3, dP_1n
+ ADD pTmp, pSrcDst, srcdstStep
+ VZIP.16 dQ_0n, dQ_2n
+ VZIP.16 dQ_1n, dQ_3
+ VZIP.16 dP_2n, dP_0n
+
+ VZIP.32 dP_3, dQ_0n
+ VZIP.32 dP_1n, dQ_2n
+ VZIP.32 dP_2n, dQ_1n
+ VZIP.32 dP_0n, dQ_3
+
+ ;// dRow0n - dP_3, dRow1n - dQ_0n, dRow2n - dP_1n, dRow3n - dQ_2n
+ ;// dRow4n - dP_2, dRow5n - dQ_1n, dRow6n - dP_0n, dRow7n - dQ_3
+
+ VST1 dRow0n, [pSrcDst], pTmpStep
+ VST1 dRow1n, [pTmp], pTmpStep
+ VST1 dRow2n, [pSrcDst], pTmpStep
+ VST1 dRow3n, [pTmp], pTmpStep
+ VST1 dRow4n, [pSrcDst], pTmpStep
+ VST1 dRow5n, [pTmp], pTmpStep
+ ADDS XY,XY,XY
+ VST1 dRow6n, [pSrcDst], pTmpStep
+ ADD pThresholds, pThresholds, #4
+ VST1 dRow7n, [pTmp], pTmpStep
+
+ SUB pSrcDst, pSrcDst, srcdstStep, LSL #3
+ VLD1 {dAlpha[]}, [pAlpha_1]
+ ADD pSrcDst, pSrcDst, #4
+ VLD1 {dBeta[]}, [pBeta_1]
+
+ BCC LoopX
+
+ExitLoopY
+ SUB pBS, pBS, #14
+ SUB pThresholds, pThresholds, #14
+ SUB pSrcDst, pSrcDst, #16
+ VLD1 {dAlpha[]}, [pAlpha_0]
+ ADD pSrcDst, pSrcDst, srcdstStep, LSL #3
+ VLD1 {dBeta[]}, [pBeta_0]
+ BNE LoopY
+
+ MOV r0, #OMX_Sts_NoErr
+
+ M_END
+
+ ENDIF
+
+
+ END
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_InterpolateChroma.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_InterpolateChroma.c
new file mode 100755
index 0000000..3ce41be
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_InterpolateChroma.c
@@ -0,0 +1,79 @@
+/**
+ *
+ * File Name: omxVCM4P10_InterpolateChroma.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 12290
+ * Date: Wednesday, April 9, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ * Description:
+ * This function will calculate 1/8 Pixel interpolation for Chroma Block
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armVC.h"
+#include "armCOMM.h"
+
+
+/**
+ * Function: omxVCM4P10_InterpolateChroma,
+ *
+ * Description:
+ * Performs 1/8-pixel interpolation for inter chroma MB.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] pSrc Pointer to the source reference frame buffer
+ * [in] srcStep Reference frame step in byte
+ * [in] dstStep Destination frame step in byte. Must be multiple of roi.width.
+ * [in] dx Fractional part of horizontal motion vector component
+ * in 1/8 pixel unit;valid in the range [0,7]
+ * [in] dy Fractional part of vertical motion vector component
+ * in 1/8 pixel unit;valid in the range [0,7]
+ * [in] roi Dimension of the interpolation region;the parameters roi.width and roi.height must
+ * be equal to either 2, 4, or 8.
+ * [out] pDst Pointer to the destination frame buffer.
+ * if roi.width==2, 2-byte alignment required
+ * if roi.width==4, 4-byte alignment required
+ * if roi.width==8, 8-byte alignment required
+ *
+ * Return Value:
+ * If the function runs without error, it returns OMX_Sts_NoErr.
+ * If one of the following cases occurs, the function returns OMX_Sts_BadArgErr:
+ * pSrc or pDst is NULL.
+ * srcStep or dstStep < 8.
+ * dx or dy is out of range [0-7].
+ * roi.width or roi.height is out of range {2,4,8}.
+ * roi.width is equal to 2, but pDst is not 2-byte aligned.
+ * roi.width is equal to 4, but pDst is not 4-byte aligned.
+ * roi.width is equal to 8, but pDst is not 8 byte aligned.
+ * srcStep or dstStep is not a multiple of 8.
+ *
+ */
+
+OMXResult omxVCM4P10_InterpolateChroma (
+ const OMX_U8* pSrc,
+ OMX_S32 srcStep,
+ OMX_U8* pDst,
+ OMX_S32 dstStep,
+ OMX_S32 dx,
+ OMX_S32 dy,
+ OMXSize roi
+ )
+{
+ return armVCM4P10_Interpolate_Chroma
+ ((OMX_U8*)pSrc, srcStep, pDst, dstStep, roi.width, roi.height, dx, dy);
+}
+
+
+/*****************************************************************************
+ * END OF FILE
+ *****************************************************************************/
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_InterpolateLuma_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_InterpolateLuma_s.s
new file mode 100755
index 0000000..942ebc6
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_InterpolateLuma_s.s
@@ -0,0 +1,553 @@
+;//
+;//
+;// File Name: omxVCM4P10_InterpolateLuma_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 12290
+;// Date: Wednesday, April 9, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+;// Function:
+;// omxVCM4P10_InterpolateLuma
+;//
+;// This function implements omxVCM4P10_InterpolateLuma in v6 assembly.
+;// Performs quarter pel interpolation of inter luma MB.
+;// It's assumed that the frame is already padded when calling this function.
+;// Parameters:
+;// [in] pSrc Pointer to the source reference frame buffer
+;// [in] srcStep Reference frame step in byte
+;// [in] dstStep Destination frame step in byte. Must be multiple of roi.width
+;// [in] dx Fractional part of horizontal motion vector
+;// component in 1/4 pixel unit; valid in the range [0,3]
+;// [in] dy Fractional part of vertical motion vector
+;// component in 1/4 pixel unit; valid in the range [0,3]
+;// [in] roi Dimension of the interpolation region;the parameters roi.width and roi.height must
+;// be equal to either 4, 8, or 16.
+;// [out] pDst Pointer to the destination frame buffer.
+;// if roi.width==4, 4-byte alignment required
+;// if roi.width==8, 8-byte alignment required
+;// if roi.width==16, 16-byte alignment required
+;//
+;// Return Value:
+;// If the function runs without error, it returns OMX_Sts_NoErr.
+;// It is assued that following cases are satisfied before calling this function:
+;// pSrc or pDst is not NULL.
+;// srcStep or dstStep >= roi.width.
+;// dx or dy is in the range [0-3].
+;// roi.width or roi.height is not out of range {4, 8, 16}.
+;// If roi.width is equal to 4, Dst is 4 byte aligned.
+;// If roi.width is equal to 8, pDst is 8 byte aligned.
+;// If roi.width is equal to 16, pDst is 16 byte aligned.
+;// srcStep and dstStep is multiple of 8.
+;//
+;//
+
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS CortexA8
+
+ EXPORT omxVCM4P10_InterpolateLuma
+
+
+ IF CortexA8
+ IMPORT armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe
+ IMPORT armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe
+ IMPORT armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe
+ IMPORT armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe
+ ENDIF
+
+
+
+;// Declare input registers
+pSrc RN 0
+srcStep RN 1
+pDst RN 2
+dstStep RN 3
+iHeight RN 4
+iWidth RN 5
+
+;// Declare other intermediate registers
+idx RN 6
+idy RN 7
+index RN 6
+Temp RN 12
+pArgs RN 11
+
+
+ IF CortexA8
+
+ ;//
+ ;// Interpolation of luma is implemented by processing block of pixels, size 4x4 at a time.
+ ;//
+ M_ALLOC4 ppArgs, 16
+
+ ;// Function header
+ M_START omxVCM4P10_InterpolateLuma, r11, d15
+
+pSrcBK RN 8
+
+;// Declare Neon registers
+dCoeff5 DN 30.S16
+dCoeff20 DN 31.S16
+
+;// Registers used for implementing Horizontal interpolation
+dSrc0c DN 14.U8
+dSrc1c DN 16.U8
+dSrc2c DN 18.U8
+dSrc3c DN 20.U8
+dSrc0d DN 15.U8
+dSrc1d DN 17.U8
+dSrc2d DN 19.U8
+dSrc3d DN 21.U8
+dAccH0 DN 22.U8
+dAccH1 DN 24.U8
+dAccH2 DN 26.U8
+dAccH3 DN 28.U8
+dResultH0 DN 22.U32
+dResultH1 DN 24.U32
+dResultH2 DN 26.U32
+dResultH3 DN 28.U32
+
+;// Registers used for implementing Vertical interpolation
+dSrc0 DN 9.U8
+dSrc1 DN 10.U8
+dSrc2 DN 11.U8
+dSrc3 DN 12.U8
+dSrc4 DN 13.U8
+dAccV0 DN 0.U8
+dAccV1 DN 2.U8
+dAccV2 DN 4.U8
+dAccV3 DN 6.U8
+dResultV0 DN 0.U32
+dResultV1 DN 2.U32
+dResultV2 DN 4.U32
+dResultV3 DN 6.U32
+
+;// Registers used for implementing Diagonal interpolation
+dTAcc0 DN 0.U8
+dTAcc1 DN 2.U8
+dTAcc2 DN 4.U8
+dTAcc3 DN 6.U8
+dTRes0 DN 0.32
+dTRes1 DN 2.32
+dTRes2 DN 4.32
+dTRes3 DN 6.32
+dTResult0 DN 14.U8
+dTResult1 DN 16.U8
+dTResult2 DN 18.U8
+dTResult3 DN 20.U8
+dTempP0 DN 18.S16
+dTempP1 DN 19.S16
+dTempQ0 DN 20.S16
+dTempQ1 DN 21.S16
+dTempR0 DN 22.S16
+dTempR1 DN 23.S16
+dTempS0 DN 24.S16
+dTempS1 DN 25.S16
+qTempP01 QN 9.S16
+qTempQ01 QN 10.S16
+qTempR01 QN 11.S16
+qTempS01 QN 12.S16
+
+;// Intermediate values for averaging
+qRes2 QN 7.S16
+qRes3 QN 8.S16
+qRes4 QN 9.S16
+qRes5 QN 10.S16
+qRes6 QN 11.S16
+
+;// For implementing copy
+dDst0 DN 9.32
+dDst1 DN 10.32
+dDst2 DN 11.32
+dDst3 DN 12.32
+
+ ;// Define stack arguments
+ M_ARG ptridx, 4
+ M_ARG ptridy, 4
+ M_ARG ptrWidth, 4
+ M_ARG ptrHeight, 4
+
+ ;// Load structure elements of roi
+ M_LDR idx, ptridx
+ M_LDR idy, ptridy
+ M_LDR iWidth, ptrWidth
+ M_LDR iHeight, ptrHeight
+
+ ADD index, idx, idy, LSL #2 ;// [index] = [idy][idx]
+ M_ADR pArgs, ppArgs
+
+ ;// Move coefficients Neon registers
+ VMOV dCoeff20, #20
+ VMOV dCoeff5, #5
+
+Block4x4WidthLoop
+Block4x4HeightLoop
+
+ STM pArgs, {pSrc,srcStep,pDst,dstStep}
+
+ ;// switch table using motion vector as index
+ ADD pc, pc, index, LSL #2
+ B Case_f
+ B Case_0
+ B Case_1
+ B Case_2
+ B Case_3
+ B Case_4
+ B Case_5
+ B Case_6
+ B Case_7
+ B Case_8
+ B Case_9
+ B Case_a
+ B Case_b
+ B Case_c
+ B Case_d
+ B Case_e
+ B Case_f
+
+Case_0
+ ;// Case G
+ M_PRINTF "Case 0 \n"
+
+ ;// Loads a 4x4 block of .8 and stores as .32
+ ADD Temp, pSrc, srcStep, LSL #1
+ VLD1 dSrc0, [pSrc], srcStep
+ VLD1 dSrc2, [Temp], srcStep
+ VLD1 dSrc1, [pSrc]
+ VLD1 dSrc3, [Temp]
+
+ ADD Temp, pDst, dstStep, LSL #1
+ VST1 dDst0[0], [pDst], dstStep
+ VST1 dDst2[0], [Temp], dstStep
+ VST1 dDst1[0], [pDst]
+ VST1 dDst3[0], [Temp]
+ M_ADR pArgs, ppArgs
+ B Block4x4LoopEnd
+Case_1
+ ;// Case a
+ M_PRINTF "Case 1 \n"
+
+ SUB pSrc, pSrc, #2
+ BL armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe
+ VRHADD dAccH0, dAccH0, dSrc0c
+ VRHADD dAccH2, dAccH2, dSrc2c
+ VRHADD dAccH1, dAccH1, dSrc1c
+ VRHADD dAccH3, dAccH3, dSrc3c
+ ADD Temp, pDst, dstStep, LSL #1
+ VST1 dResultH0[0], [pDst], dstStep
+ VST1 dResultH2[0], [Temp], dstStep
+ VST1 dResultH1[0], [pDst]
+ VST1 dResultH3[0], [Temp]
+ M_ADR pArgs, ppArgs
+ B Block4x4LoopEnd
+Case_2
+ ;// Case b
+ M_PRINTF "Case 2 \n"
+
+ SUB pSrc, pSrc, #2
+ BL armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe
+ ADD Temp, pDst, dstStep, LSL #1
+ VST1 dResultH0[0], [pDst], dstStep
+ VST1 dResultH2[0], [Temp], dstStep
+ VST1 dResultH1[0], [pDst]
+ VST1 dResultH3[0], [Temp]
+ M_ADR pArgs, ppArgs
+ B Block4x4LoopEnd
+Case_3
+ ;// Case c
+ M_PRINTF "Case 3 \n"
+
+ SUB pSrc, pSrc, #2
+ BL armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe
+ VRHADD dAccH0, dAccH0, dSrc0d
+ VRHADD dAccH2, dAccH2, dSrc2d
+ VRHADD dAccH1, dAccH1, dSrc1d
+ VRHADD dAccH3, dAccH3, dSrc3d
+ ADD Temp, pDst, dstStep, LSL #1
+ VST1 dResultH0[0], [pDst], dstStep
+ VST1 dResultH2[0], [Temp], dstStep
+ VST1 dResultH1[0], [pDst]
+ VST1 dResultH3[0], [Temp]
+ M_ADR pArgs, ppArgs
+ B Block4x4LoopEnd
+Case_4
+ ;// Case d
+ M_PRINTF "Case 4 \n"
+
+ SUB pSrc, pSrc, srcStep, LSL #1
+ BL armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe
+ VRHADD dAccV0, dAccV0, dSrc0
+ VRHADD dAccV2, dAccV2, dSrc2
+ VRHADD dAccV1, dAccV1, dSrc1
+ VRHADD dAccV3, dAccV3, dSrc3
+ ADD Temp, pDst, dstStep, LSL #1
+ VST1 dResultV0[0], [pDst], dstStep
+ VST1 dResultV2[0], [Temp], dstStep
+ VST1 dResultV1[0], [pDst]
+ VST1 dResultV3[0], [Temp]
+ M_ADR pArgs, ppArgs
+ B Block4x4LoopEnd
+Case_5
+ ;// Case e
+ M_PRINTF "Case 5 \n"
+
+ MOV pSrcBK, pSrc
+ SUB pSrc, pSrc, srcStep, LSL #1
+ BL armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe
+ SUB pSrc, pSrcBK, #2
+ BL armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe
+ VRHADD dAccH0, dAccH0, dAccV0
+ VRHADD dAccH2, dAccH2, dAccV2
+ VRHADD dAccH1, dAccH1, dAccV1
+ VRHADD dAccH3, dAccH3, dAccV3
+ ADD Temp, pDst, dstStep, LSL #1
+ VST1 dResultH0[0], [pDst], dstStep
+ VST1 dResultH2[0], [Temp], dstStep
+ VST1 dResultH1[0], [pDst]
+ VST1 dResultH3[0], [Temp]
+
+ M_ADR pArgs, ppArgs
+ B Block4x4LoopEnd
+Case_6
+ ;// Case f
+ M_PRINTF "Case 6 \n"
+
+ SUB pSrc, pSrc, srcStep, LSL #1
+ SUB pSrc, pSrc, #2
+ BL armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe
+ VQRSHRUN dTResult0, qRes2, #5
+ VQRSHRUN dTResult1, qRes3, #5
+ VQRSHRUN dTResult2, qRes4, #5
+ VQRSHRUN dTResult3, qRes5, #5
+ VRHADD dTAcc0, dTAcc0, dTResult0
+ VRHADD dTAcc2, dTAcc2, dTResult2
+ VRHADD dTAcc1, dTAcc1, dTResult1
+ VRHADD dTAcc3, dTAcc3, dTResult3
+ ADD Temp, pDst, dstStep, LSL #1
+ VST1 dTRes0[0], [pDst], dstStep
+ VST1 dTRes2[0], [Temp], dstStep
+ VST1 dTRes1[0], [pDst]
+ VST1 dTRes3[0], [Temp]
+
+ M_ADR pArgs, ppArgs
+ B Block4x4LoopEnd
+Case_7
+ ;// Case g
+ M_PRINTF "Case 7 \n"
+ MOV pSrcBK, pSrc
+ ADD pSrc, pSrc, #1
+ SUB pSrc, pSrc, srcStep, LSL #1
+ BL armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe
+ SUB pSrc, pSrcBK, #2
+ BL armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe
+ VRHADD dAccH0, dAccH0, dAccV0
+ VRHADD dAccH2, dAccH2, dAccV2
+ VRHADD dAccH1, dAccH1, dAccV1
+ VRHADD dAccH3, dAccH3, dAccV3
+ ADD Temp, pDst, dstStep, LSL #1
+ VST1 dResultH0[0], [pDst], dstStep
+ VST1 dResultH2[0], [Temp], dstStep
+ VST1 dResultH1[0], [pDst]
+ VST1 dResultH3[0], [Temp]
+
+ M_ADR pArgs, ppArgs
+ B Block4x4LoopEnd
+Case_8
+ ;// Case h
+ M_PRINTF "Case 8 \n"
+
+ SUB pSrc, pSrc, srcStep, LSL #1
+ BL armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe
+ ADD Temp, pDst, dstStep, LSL #1
+ VST1 dResultV0[0], [pDst], dstStep
+ VST1 dResultV2[0], [Temp], dstStep
+ VST1 dResultV1[0], [pDst]
+ VST1 dResultV3[0], [Temp]
+ M_ADR pArgs, ppArgs
+ B Block4x4LoopEnd
+Case_9
+ ;// Case i
+ M_PRINTF "Case 9 \n"
+ SUB pSrc, pSrc, srcStep, LSL #1
+ SUB pSrc, pSrc, #2
+ BL armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe
+ VEXT dTempP0, dTempP0, dTempP1, #2
+ VEXT dTempQ0, dTempQ0, dTempQ1, #2
+ VEXT dTempR0, dTempR0, dTempR1, #2
+ VEXT dTempS0, dTempS0, dTempS1, #2
+
+ VQRSHRUN dTResult0, qTempP01, #5
+ VQRSHRUN dTResult1, qTempQ01, #5
+ VQRSHRUN dTResult2, qTempR01, #5
+ VQRSHRUN dTResult3, qTempS01, #5
+
+ VRHADD dTAcc0, dTAcc0, dTResult0
+ VRHADD dTAcc2, dTAcc2, dTResult2
+ VRHADD dTAcc1, dTAcc1, dTResult1
+ VRHADD dTAcc3, dTAcc3, dTResult3
+ ADD Temp, pDst, dstStep, LSL #1
+ VST1 dTRes0[0], [pDst], dstStep
+ VST1 dTRes2[0], [Temp], dstStep
+ VST1 dTRes1[0], [pDst]
+ VST1 dTRes3[0], [Temp]
+ M_ADR pArgs, ppArgs
+ B Block4x4LoopEnd
+Case_a
+ ;// Case j
+ M_PRINTF "Case a \n"
+
+ SUB pSrc, pSrc, srcStep, LSL #1
+ SUB pSrc, pSrc, #2
+ BL armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe
+ ADD Temp, pDst, dstStep, LSL #1
+ VST1 dTRes0[0], [pDst], dstStep
+ VST1 dTRes2[0], [Temp], dstStep
+ VST1 dTRes1[0], [pDst]
+ VST1 dTRes3[0], [Temp]
+ M_ADR pArgs, ppArgs
+ B Block4x4LoopEnd
+Case_b
+ ;// Case k
+ M_PRINTF "Case b \n"
+ SUB pSrc, pSrc, srcStep, LSL #1
+ SUB pSrc, pSrc, #2
+ BL armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe
+ VEXT dTempP0, dTempP0, dTempP1, #3
+ VEXT dTempQ0, dTempQ0, dTempQ1, #3
+ VEXT dTempR0, dTempR0, dTempR1, #3
+ VEXT dTempS0, dTempS0, dTempS1, #3
+
+ VQRSHRUN dTResult0, qTempP01, #5
+ VQRSHRUN dTResult1, qTempQ01, #5
+ VQRSHRUN dTResult2, qTempR01, #5
+ VQRSHRUN dTResult3, qTempS01, #5
+
+ VRHADD dTAcc0, dTAcc0, dTResult0
+ VRHADD dTAcc2, dTAcc2, dTResult2
+ VRHADD dTAcc1, dTAcc1, dTResult1
+ VRHADD dTAcc3, dTAcc3, dTResult3
+ ADD Temp, pDst, dstStep, LSL #1
+ VST1 dTRes0[0], [pDst], dstStep
+ VST1 dTRes2[0], [Temp], dstStep
+ VST1 dTRes1[0], [pDst]
+ VST1 dTRes3[0], [Temp]
+ M_ADR pArgs, ppArgs
+ B Block4x4LoopEnd
+Case_c
+ ;// Case n
+ M_PRINTF "Case c \n"
+
+ SUB pSrc, pSrc, srcStep, LSL #1
+ BL armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe
+ VRHADD dAccV0, dAccV0, dSrc1
+ VRHADD dAccV2, dAccV2, dSrc3
+ VRHADD dAccV1, dAccV1, dSrc2
+ VRHADD dAccV3, dAccV3, dSrc4
+ ADD Temp, pDst, dstStep, LSL #1
+ VST1 dResultV0[0], [pDst], dstStep
+ VST1 dResultV2[0], [Temp], dstStep
+ VST1 dResultV1[0], [pDst]
+ VST1 dResultV3[0], [Temp]
+ M_ADR pArgs, ppArgs
+ B Block4x4LoopEnd
+Case_d
+ ;// Case p
+ M_PRINTF "Case d \n"
+
+ MOV pSrcBK, pSrc
+ SUB pSrc, pSrc, srcStep, LSL #1
+ BL armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe
+ ADD pSrc, pSrcBK, srcStep
+ SUB pSrc, pSrc, #2
+ BL armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe
+ VRHADD dAccH0, dAccH0, dAccV0
+ VRHADD dAccH2, dAccH2, dAccV2
+ VRHADD dAccH1, dAccH1, dAccV1
+ VRHADD dAccH3, dAccH3, dAccV3
+ ADD Temp, pDst, dstStep, LSL #1
+ VST1 dResultH0[0], [pDst], dstStep
+ VST1 dResultH2[0], [Temp], dstStep
+ VST1 dResultH1[0], [pDst]
+ VST1 dResultH3[0], [Temp]
+ M_ADR pArgs, ppArgs
+ B Block4x4LoopEnd
+Case_e
+ ;// Case q
+ M_PRINTF "Case e \n"
+
+ SUB pSrc, pSrc, srcStep, LSL #1
+ SUB pSrc, pSrc, #2
+ BL armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe
+ VQRSHRUN dTResult0, qRes3, #5
+ VQRSHRUN dTResult1, qRes4, #5
+ VQRSHRUN dTResult2, qRes5, #5
+ VQRSHRUN dTResult3, qRes6, #5
+
+ VRHADD dTAcc0, dTAcc0, dTResult0
+ VRHADD dTAcc2, dTAcc2, dTResult2
+ VRHADD dTAcc1, dTAcc1, dTResult1
+ VRHADD dTAcc3, dTAcc3, dTResult3
+ ADD Temp, pDst, dstStep, LSL #1
+ VST1 dTRes0[0], [pDst], dstStep
+ VST1 dTRes2[0], [Temp], dstStep
+ VST1 dTRes1[0], [pDst]
+ VST1 dTRes3[0], [Temp]
+ M_ADR pArgs, ppArgs
+ B Block4x4LoopEnd
+Case_f
+ ;// Case r
+ M_PRINTF "Case f \n"
+ MOV pSrcBK, pSrc
+ ADD pSrc, pSrc, #1
+ SUB pSrc, pSrc, srcStep, LSL #1
+ BL armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe
+ ADD pSrc, pSrcBK, srcStep
+ SUB pSrc, pSrc, #2
+ BL armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe
+ VRHADD dAccH0, dAccH0, dAccV0
+ VRHADD dAccH2, dAccH2, dAccV2
+ VRHADD dAccH1, dAccH1, dAccV1
+ VRHADD dAccH3, dAccH3, dAccV3
+ ADD Temp, pDst, dstStep, LSL #1
+ VST1 dResultH0[0], [pDst], dstStep
+ VST1 dResultH2[0], [Temp], dstStep
+ VST1 dResultH1[0], [pDst]
+ VST1 dResultH3[0], [Temp]
+ M_ADR pArgs, ppArgs
+
+
+Block4x4LoopEnd
+
+ ;// Width Loop
+ ;//M_ADR pArgs, ppArgs
+ LDM pArgs, {pSrc,srcStep,pDst,dstStep} ;// Load arguments
+ SUBS iWidth, iWidth, #4
+ ADD pSrc, pSrc, #4
+ ADD pDst, pDst, #4
+ BGT Block4x4WidthLoop
+
+ ;// Height Loop
+ SUBS iHeight, iHeight, #4
+ M_LDR iWidth, ptrWidth
+ M_ADR pArgs, ppArgs
+ ADD pSrc, pSrc, srcStep, LSL #2
+ ADD pDst, pDst, dstStep, LSL #2
+ SUB pSrc, pSrc, iWidth
+ SUB pDst, pDst, iWidth
+ BGT Block4x4HeightLoop
+
+EndOfInterpolation
+ MOV r0, #0
+ M_END
+
+ ENDIF
+ ;// End of CortexA8
+
+ END
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_PredictIntraChroma_8x8_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_PredictIntraChroma_8x8_s.s
new file mode 100755
index 0000000..3a60705
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_PredictIntraChroma_8x8_s.s
@@ -0,0 +1,436 @@
+;//
+;//
+;// File Name: omxVCM4P10_PredictIntraChroma_8x8_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 12290
+;// Date: Wednesday, April 9, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ EXPORT armVCM4P10_pIndexTable8x8
+
+;// Define the processor variants supported by this file
+
+ M_VARIANTS CortexA8
+
+ AREA table, DATA
+;//-------------------------------------------------------
+;// This table for implementing switch case of C in asm by
+;// the mehtod of two levels of indexing.
+;//-------------------------------------------------------
+
+ M_TABLE armVCM4P10_pIndexTable8x8
+ DCD OMX_VC_CHROMA_DC, OMX_VC_CHROMA_HOR
+ DCD OMX_VC_CHROMA_VERT, OMX_VC_CHROMA_PLANE
+
+ M_TABLE armVCM4P10_MultiplierTableChroma8x8,1
+ DCW 3, 2, 1,4
+ DCW -3,-2,-1,0
+ DCW 1, 2, 3,4
+
+
+
+ IF CortexA8
+
+;//--------------------------------------------
+;// Scratch variable
+;//--------------------------------------------
+
+pc RN 15
+return RN 0
+pTable RN 8
+
+;//--------------------------------------------
+;// Input Arguments
+;//--------------------------------------------
+pSrcLeft RN 0 ;// input pointer
+pSrcAbove RN 1 ;// input pointer
+pSrcAboveLeft RN 2 ;// input pointer
+pDst RN 3 ;// output pointer
+leftStep RN 4 ;// input variable
+dstStep RN 5 ;// input variable
+predMode RN 6 ;// input variable
+availability RN 7 ;// input variable
+pMultiplierTable RN 2
+
+pTmp RN 9
+step RN 10
+
+;//---------------------
+;// Neon Registers
+;//---------------------
+
+;// OMX_VC_CHROMA_HOR
+
+dLeftVal0 DN D0.8
+dLeftVal1 DN D1.8
+dLeftVal2 DN D2.8
+dLeftVal3 DN D3.8
+dLeftVal4 DN D4.8
+dLeftVal5 DN D5.8
+dLeftVal6 DN D6.8
+dLeftVal7 DN D7.8
+
+;// OMX_VC_CHROMA_VERT
+
+dAboveVal DN D0.U8
+
+;// OMX_VC_CHROMA_DC
+
+dLeftVal DN D1.U8
+dSumAboveValU16 DN D2.U16
+dSumAboveValU32 DN D3.U32
+dSumAboveValU8 DN D3.U8
+dSumLeftValU16 DN D2.U16
+dSumLeftValU32 DN D1.U32
+dSumLeftValU8 DN D1.U8
+dSumAboveLeft DN D2.U32
+dSumAboveLeftU8 DN D2.U8
+dIndexRow0U8 DN D5.U8
+dIndexRow0 DN D5.U64
+dIndexRow4U8 DN D6.U8
+dIndexRow4 DN D6.U64
+dDstRow0 DN D0.U8
+dDstRow4 DN D4.U8
+dConst128U8 DN D0.U8
+
+;// OMX_VC_CHROMA_PLANE
+
+dRevAboveVal DN D3.U8
+dRevAboveValU64 DN D3.U64
+dAboveLeftVal DN D2.U8
+qAbove7minus0 QN Q3.S16
+qAboveDiff QN Q2.S16
+dIndex DN D8.U8
+dDiffAboveU8 DN D9.U8
+dDiffAboveS16 DN D9.S16
+dAboveDiff0U8 DN D4.U8
+dAboveDiff0U64 DN D4.U64
+dAbove7minus0U8 DN D6.U8
+dMultiplier DN D10.S16
+dHorPred DN D11.S16
+dRevLeftVal DN D3.U8
+dRevLeftValU64 DN D3.U64
+qLeft7minus0 QN Q7.S16
+qLeftDiff QN Q6.S16
+dDiffLeftU8 DN D16.U8
+dDiffLeftS16 DN D16.S16
+dLeftDiff0U8 DN D12.U8
+dLeftDiff0U64 DN D12.U64
+dLeft7minus0U8 DN D14.U8
+dVerPred DN D3.S16
+dHVValS16 DN D3.S16
+dHVValS32 DN D3.S32
+dHVTempS32 DN D2.S32
+qA QN Q0.S16
+qB QN Q2.S16
+qC QN Q3.S16
+qMultiplier QN Q5.S16
+dMultiplier0 DN D10.S16
+dMultiplier1 DN D11.S16
+qC0 QN Q0.S16
+qC1 QN Q1.S16
+qC2 QN Q4.S16
+qC3 QN Q5.S16
+qC4 QN Q6.S16
+qC5 QN Q7.S16
+qC6 QN Q8.S16
+qC7 QN Q9.S16
+qSum0 QN Q0.S16
+qSum1 QN Q1.S16
+qSum2 QN Q4.S16
+qSum3 QN Q5.S16
+qSum4 QN Q6.S16
+qSum5 QN Q7.S16
+qSum6 QN Q8.S16
+qSum7 QN Q9.S16
+dSum0 DN D0.U8
+dSum1 DN D1.U8
+dSum2 DN D2.U8
+dSum3 DN D3.U8
+dSum4 DN D4.U8
+dSum5 DN D5.U8
+dSum6 DN D6.U8
+dSum7 DN D7.U8
+
+;//-----------------------------------------------------------------------------------------------
+;// omxVCM4P10_PredictIntraChroma_8x8 starts
+;//-----------------------------------------------------------------------------------------------
+
+ ;// Write function header
+ M_START omxVCM4P10_PredictIntraChroma_8x8, r10, d15
+
+ ;// Define stack arguments
+ M_ARG LeftStep, 4
+ M_ARG DstStep, 4
+ M_ARG PredMode, 4
+ M_ARG Availability, 4
+
+ LDR pTable,=armVCM4P10_pIndexTable8x8 ;// Load index table for switch case
+
+ ;// Load argument from the stack
+ M_LDR predMode, PredMode ;// Arg predMode loaded from stack to reg
+ M_LDR leftStep, LeftStep ;// Arg leftStep loaded from stack to reg
+ M_LDR dstStep, DstStep ;// Arg dstStep loaded from stack to reg
+ M_LDR availability, Availability ;// Arg availability loaded from stack to reg
+
+
+ LDR pc, [pTable, predMode, LSL #2] ;// Branch to the case based on preMode
+
+OMX_VC_CHROMA_DC
+
+ TST availability, #OMX_VC_LEFT
+ BEQ DCChroma8x8LeftNotAvailable
+
+ ADD pTmp, pSrcLeft, leftStep
+ ADD step, leftStep, leftStep
+
+ ;// Load Left Edge
+ VLD1 {dLeftVal[0]},[pSrcLeft],step ;// pSrcLeft[0*leftStep]
+ VLD1 {dLeftVal[1]},[pTmp],step ;// pSrcLeft[1*leftStep]
+ VLD1 {dLeftVal[2]},[pSrcLeft],step ;// pSrcLeft[2*leftStep]
+ VLD1 {dLeftVal[3]},[pTmp],step ;// pSrcLeft[3*leftStep]
+ VLD1 {dLeftVal[4]},[pSrcLeft],step ;// pSrcLeft[4*leftStep]
+ VLD1 {dLeftVal[5]},[pTmp],step ;// pSrcLeft[5*leftStep]
+ VLD1 {dLeftVal[6]},[pSrcLeft],step ;// pSrcLeft[6*leftStep]
+ VLD1 {dLeftVal[7]},[pTmp] ;// pSrcLeft[7*leftStep]
+
+ TST availability, #OMX_VC_UPPER
+ BEQ DCChroma8x8LeftOnlyAvailable
+
+ ;// Load Upper Edge also
+ VLD1 dAboveVal,[pSrcAbove] ;// pSrcAbove[0 to 7]
+
+ MOV return, #OMX_Sts_NoErr ;// returnNoError
+
+ VPADDL dSumAboveValU16, dAboveVal ;// pSrcAbove[ 6+7 | 4+5 | 2+3 | 0+1 ]
+ VPADDL dSumAboveValU32, dSumAboveValU16 ;// pSrcAbove[ 4+5+6+7 | 0+1+2+3 ]
+
+ VPADDL dSumLeftValU16, dLeftVal ;// pSrcLeft[ 6+7 | 4+5 | 2+3 | 0+1 ]
+ VPADDL dSumLeftValU32, dSumLeftValU16 ;// pSrcLeft[ 4+5+6+7 | 0+1+2+3 ]
+
+ VADD dSumAboveLeft,dSumAboveValU32,dSumLeftValU32
+ VRSHR dSumAboveLeft,dSumAboveLeft,#3 ;// Sum = (Sum + 4) >> 3
+ VRSHR dSumAboveValU32,dSumAboveValU32,#2 ;// Sum = (Sum + 2) >> 2
+ VRSHR dSumLeftValU32,dSumLeftValU32,#2 ;// Sum = (Sum + 2) >> 2
+
+ VMOV dIndexRow0U8,#0x0c
+ VMOV dIndexRow4U8,#0x04
+ VSHL dIndexRow0,dIndexRow0,#32 ;// index0 = 0x0c0c0c0c00000000
+ VSHR dIndexRow4,dIndexRow4,#32 ;// index4 = 0x0000000004040404
+ VADD dIndexRow4U8,dIndexRow4U8,dIndexRow0U8 ;// index4 = 0x0c0c0c0c04040404
+ VTBL dDstRow0,{dSumAboveLeftU8,dSumAboveValU8},dIndexRow0U8
+ VTBL dDstRow4,{dSumLeftValU8,dSumAboveLeftU8},dIndexRow4U8
+
+DCChroma8x8LeftStore
+ ADD pTmp, pDst, dstStep
+ ADD step, dstStep, dstStep
+
+ VST1 dDstRow0,[pDst],step ;// pDst[0*dstStep+x] :0<= x <= 7
+ VST1 dDstRow0,[pTmp],step ;// pDst[1*dstStep+x] :0<= x <= 7
+ VST1 dDstRow0,[pDst],step ;// pDst[2*dstStep+x] :0<= x <= 7
+ VST1 dDstRow0,[pTmp],step ;// pDst[3*dstStep+x] :0<= x <= 7
+ VST1 dDstRow4,[pDst],step ;// pDst[4*dstStep+x] :0<= x <= 7
+ VST1 dDstRow4,[pTmp],step ;// pDst[5*dstStep+x] :0<= x <= 7
+ VST1 dDstRow4,[pDst],step ;// pDst[6*dstStep+x] :0<= x <= 7
+ VST1 dDstRow4,[pTmp] ;// pDst[7*dstStep+x] :0<= x <= 7
+
+ M_EXIT
+
+
+DCChroma8x8LeftOnlyAvailable
+
+ MOV return, #OMX_Sts_NoErr
+
+ VPADDL dSumLeftValU16, dLeftVal ;// pSrcLeft[ 6+7 | 4+5 | 2+3 | 0+1 ]
+ VPADDL dSumLeftValU32, dSumLeftValU16 ;// pSrcLeft[ 4+5+6+7 | 0+1+2+3 ]
+ VRSHR dSumLeftValU32,dSumLeftValU32,#2 ;// Sum = (Sum + 2) >> 2
+
+ VDUP dDstRow0,dSumLeftValU8[0]
+ VDUP dDstRow4,dSumLeftValU8[4]
+
+ B DCChroma8x8LeftStore
+
+
+DCChroma8x8LeftNotAvailable
+
+ TST availability, #OMX_VC_UPPER
+ BEQ DCChroma8x8NoneAvailable
+
+ ;// Load Upper Edge
+ VLD1 dAboveVal,[pSrcAbove] ;// pSrcAbove[0 to 7]
+ MOV return, #OMX_Sts_NoErr ;// returnNoError
+
+ VPADDL dSumAboveValU16, dAboveVal ;// pSrcAbove[ 6+7 | 4+5 | 2+3 | 0+1 ]
+ VPADDL dSumAboveValU32, dSumAboveValU16 ;// pSrcAbove[ 4+5+6+7 | 0+1+2+3 ]
+ VRSHR dSumAboveValU32,dSumAboveValU32,#2 ;// Sum = (Sum + 2) >> 2
+ VMOV dIndexRow0U8,#0x04
+ VSHL dIndexRow0,dIndexRow0,#32 ;// index = 0x0404040400000000
+ VTBL dDstRow0,{dSumAboveValU8},dIndexRow0U8
+
+ B DCChroma8x8UpperStore
+
+
+DCChroma8x8NoneAvailable
+
+ VMOV dConst128U8,#0x80 ;// 0x8080808080808080 if(count == 0)
+ MOV return, #OMX_Sts_NoErr ;// returnNoError
+
+DCChroma8x8UpperStore
+
+ ADD pTmp, pDst, dstStep
+ ADD step, dstStep, dstStep
+
+ VST1 dDstRow0,[pDst],step ;// pDst[0*dstStep+x] :0<= x <= 7
+ VST1 dDstRow0,[pTmp],step ;// pDst[1*dstStep+x] :0<= x <= 7
+ VST1 dDstRow0,[pDst],step ;// pDst[2*dstStep+x] :0<= x <= 7
+ VST1 dDstRow0,[pTmp],step ;// pDst[3*dstStep+x] :0<= x <= 7
+ VST1 dDstRow0,[pDst],step ;// pDst[4*dstStep+x] :0<= x <= 7
+ VST1 dDstRow0,[pTmp],step ;// pDst[5*dstStep+x] :0<= x <= 7
+ VST1 dDstRow0,[pDst],step ;// pDst[6*dstStep+x] :0<= x <= 7
+ VST1 dDstRow0,[pTmp] ;// pDst[7*dstStep+x] :0<= x <= 7
+
+ M_EXIT
+
+
+OMX_VC_CHROMA_VERT
+
+ VLD1 dAboveVal,[pSrcAbove] ;// pSrcAbove[x] :0<= x <= 7
+ MOV return, #OMX_Sts_NoErr
+
+ B DCChroma8x8UpperStore
+
+
+OMX_VC_CHROMA_HOR
+
+ ADD pTmp, pSrcLeft, leftStep
+ ADD step, leftStep, leftStep
+
+ VLD1 {dLeftVal0[]},[pSrcLeft],step ;// pSrcLeft[0*leftStep]
+ VLD1 {dLeftVal1[]},[pTmp],step ;// pSrcLeft[1*leftStep]
+ VLD1 {dLeftVal2[]},[pSrcLeft],step ;// pSrcLeft[2*leftStep]
+ VLD1 {dLeftVal3[]},[pTmp],step ;// pSrcLeft[3*leftStep]
+ VLD1 {dLeftVal4[]},[pSrcLeft],step ;// pSrcLeft[4*leftStep]
+ VLD1 {dLeftVal5[]},[pTmp],step ;// pSrcLeft[5*leftStep]
+ VLD1 {dLeftVal6[]},[pSrcLeft],step ;// pSrcLeft[6*leftStep]
+ VLD1 {dLeftVal7[]},[pTmp] ;// pSrcLeft[7*leftStep]
+
+ B DCChroma8x8PlaneStore
+
+
+OMX_VC_CHROMA_PLANE
+ ADD pTmp, pSrcLeft, leftStep
+ ADD step, leftStep, leftStep
+
+ VLD1 dAboveVal,[pSrcAbove] ;// pSrcAbove[x] :0<= x <= 7
+ VLD1 dAboveLeftVal[0],[pSrcAboveLeft]
+
+ VLD1 {dLeftVal[0]},[pSrcLeft],step ;// pSrcLeft[0*leftStep]
+ VLD1 {dLeftVal[1]},[pTmp],step ;// pSrcLeft[1*leftStep]
+ VLD1 {dLeftVal[2]},[pSrcLeft],step ;// pSrcLeft[2*leftStep]
+ VLD1 {dLeftVal[3]},[pTmp],step ;// pSrcLeft[3*leftStep]
+ VLD1 {dLeftVal[4]},[pSrcLeft],step ;// pSrcLeft[4*leftStep]
+ VLD1 {dLeftVal[5]},[pTmp],step ;// pSrcLeft[5*leftStep]
+ VLD1 {dLeftVal[6]},[pSrcLeft],step ;// pSrcLeft[6*leftStep]
+ VLD1 {dLeftVal[7]},[pTmp] ;// pSrcLeft[7*leftStep]
+
+
+ VREV64 dRevAboveVal,dAboveVal ;// Reverse order of bytes = pSrcAbove[0:1:2:3:4:5:6:7]
+ VSUBL qAbove7minus0,dRevAboveVal,dAboveLeftVal ;// qAbove7minus0[0] = pSrcAbove[7] - pSrcAboveLeft[0]
+ VSHR dRevAboveValU64,dRevAboveValU64,#8 ;// pSrcAbove[X:0:1:2:3:4:5:6]
+ VSUBL qAboveDiff,dRevAboveVal,dAboveVal ;// pSrcAbove[6] - pSrcAbove[0]
+ ;// pSrcAbove[5] - pSrcAbove[1]
+ ;// pSrcAbove[4] - pSrcAbove[2]
+
+ VREV64 dRevLeftVal,dLeftVal ;// Reverse order of bytes = pSrcLeft[0:1:2:3:4:5:6:7]
+ VSUBL qLeft7minus0,dRevLeftVal,dAboveLeftVal ;// qAbove7minus0[0] = pSrcLeft[7] - pSrcAboveLeft[0]
+ VSHR dRevLeftValU64,dRevLeftValU64,#8 ;// pSrcLeft[X:0:1:2:3:4:5:6]
+ VSUBL qLeftDiff,dRevLeftVal,dLeftVal ;// pSrcLeft[6] - pSrcLeft[0]
+ ;// pSrcLeft[5] - pSrcLeft[1]
+ ;// pSrcLeft[4] - pSrcLeft[2]
+
+ LDR pMultiplierTable,=armVCM4P10_MultiplierTableChroma8x8 ;// Used to calculate Hval & Vval
+ VSHL dAboveDiff0U64,dAboveDiff0U64,#16
+ VEXT dDiffAboveU8,dAboveDiff0U8,dAbove7minus0U8,#2 ;// pSrcAbove[ 7-0 | 4-2 | 5-1 | 6-0 ]
+ VLD1 dMultiplier,[pMultiplierTable]!
+ VSHL dLeftDiff0U64,dLeftDiff0U64,#16
+ VEXT dDiffLeftU8,dLeftDiff0U8,dLeft7minus0U8,#2 ;// pSrcLeft[ 7-0 | 4-2 | 5-1 | 6-0 ]
+
+
+ VMUL dHorPred,dDiffAboveS16,dMultiplier ;// pSrcAbove[ 4*(7-0) | 1*(4-2) | 2*(5-1) | 3*(6-0) ]
+ VMUL dVerPred,dDiffLeftS16,dMultiplier
+ VPADD dHVValS16,dHorPred,dVerPred
+
+
+ VPADDL dHVValS32,dHVValS16 ;// [V|H] in 32 bits each
+ VSHL dHVTempS32,dHVValS32,#4 ;// 17*H = 16*H + H = (H<<4)+H
+ VADD dHVValS32,dHVValS32,dHVTempS32 ;// [ 17*V | 17*H ]in 32 bits each
+ VLD1 {dMultiplier0,dMultiplier1},[pMultiplierTable] ;// qMultiplier = [ 4|3|2|1|0|-1|-2|-3 ]
+ VRSHR dHVValS32,dHVValS32,#5 ;// [c|b] in 16bits each
+ VADDL qA,dAboveVal,dLeftVal
+ VDUP qA,qA[7]
+ VSHL qA,qA,#4 ;// [a|a|a|a|a|a|a|a]
+ VDUP qB,dHVValS16[0] ;// [b|b|b|b|b|b|b|b]
+ VDUP qC,dHVValS16[2] ;// [c|c|c|c|c|c|c|c]
+
+
+ VMUL qB,qB,qMultiplier
+ VMUL qC,qC,qMultiplier
+ VADD qB,qB,qA
+
+ VDUP qC0,qC[0]
+ VDUP qC1,qC[1]
+ VDUP qC2,qC[2]
+ VDUP qC3,qC[3]
+ VDUP qC4,qC[4]
+ VDUP qC5,qC[5]
+ VDUP qC6,qC[6]
+ VDUP qC7,qC[7]
+
+ VADD qSum0,qB,qC0
+ VADD qSum1,qB,qC1
+ VADD qSum2,qB,qC2
+ VADD qSum3,qB,qC3
+ VADD qSum4,qB,qC4
+ VADD qSum5,qB,qC5
+ VADD qSum6,qB,qC6
+ VADD qSum7,qB,qC7
+
+ VQRSHRUN dSum0,qSum0,#5 ;// (OMX_U8)armClip(0,255,(Sum+16)>>5)
+ VQRSHRUN dSum1,qSum1,#5
+ VQRSHRUN dSum2,qSum2,#5
+ VQRSHRUN dSum3,qSum3,#5
+ VQRSHRUN dSum4,qSum4,#5
+ VQRSHRUN dSum5,qSum5,#5
+ VQRSHRUN dSum6,qSum6,#5
+ VQRSHRUN dSum7,qSum7,#5
+
+DCChroma8x8PlaneStore
+ ADD pTmp, pDst, dstStep
+ ADD step, dstStep, dstStep
+
+ VST1 dSum0,[pDst],step ;// pDst[0*dstStep+x] :0<= x <= 7
+ VST1 dSum1,[pTmp],step ;// pDst[1*dstStep+x] :0<= x <= 7
+ VST1 dSum2,[pDst],step ;// pDst[2*dstStep+x] :0<= x <= 7
+ VST1 dSum3,[pTmp],step ;// pDst[3*dstStep+x] :0<= x <= 7
+ VST1 dSum4,[pDst],step ;// pDst[4*dstStep+x] :0<= x <= 7
+ VST1 dSum5,[pTmp],step ;// pDst[5*dstStep+x] :0<= x <= 7
+ VST1 dSum6,[pDst],step ;// pDst[6*dstStep+x] :0<= x <= 7
+ VST1 dSum7,[pTmp] ;// pDst[7*dstStep+x] :0<= x <= 7
+
+ MOV return, #OMX_Sts_NoErr
+ M_END
+
+ ENDIF ;// CortexA8
+
+ END
+;//-----------------------------------------------------------------------------------------------
+;// omxVCM4P10_PredictIntraChroma_8x8 ends
+;//-----------------------------------------------------------------------------------------------
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_PredictIntra_16x16_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_PredictIntra_16x16_s.s
new file mode 100755
index 0000000..e9c0eee
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_PredictIntra_16x16_s.s
@@ -0,0 +1,424 @@
+;//
+;//
+;// File Name: omxVCM4P10_PredictIntra_16x16_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 12290
+;// Date: Wednesday, April 9, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS CortexA8
+
+
+;//-------------------------------------------------------
+;// This table for implementing switch case of C in asm by
+;// the mehtod of two levels of indexing.
+;//-------------------------------------------------------
+
+ M_TABLE armVCM4P10_pIndexTable16x16
+ DCD OMX_VC_16X16_VERT, OMX_VC_16X16_HOR
+ DCD OMX_VC_16X16_DC, OMX_VC_16X16_PLANE
+
+
+ IF CortexA8
+
+ M_TABLE armVCM4P10_MultiplierTable16x16,1
+ DCW 7, 6, 5, 4, 3, 2, 1, 8
+ DCW 0, 1, 2, 3, 4, 5, 6, 7
+ DCW 8, 9, 10, 11, 12, 13, 14, 15
+
+;//--------------------------------------------
+;// Constants
+;//--------------------------------------------
+BLK_SIZE EQU 0x10
+MUL_CONST0 EQU 0x01010101
+MUL_CONST1 EQU 0x00060004
+MUL_CONST2 EQU 0x00070005
+MUL_CONST3 EQU 0x00030001
+MASK_CONST EQU 0x00FF00FF
+
+;//--------------------------------------------
+;// Scratch variable
+;//--------------------------------------------
+y RN 12
+pc RN 15
+
+return RN 0
+pTable RN 9
+count RN 11
+pMultTable RN 9
+; ----------------------------------------------
+; Neon registers
+; ----------------------------------------------
+qAbove QN Q0.U8
+qLeft QN Q1.U8
+qSum8 QN Q0.U16
+dSum80 DN D0.U16
+dSum81 DN D1.U16
+dSum4 DN D0.U16
+dSum2 DN D0.U32
+dSum1 DN D0.U64
+qOut QN Q3.U8
+dSumLeft DN D6.U64
+dSumAbove DN D7.U64
+dSum DN D8.U64
+dSum0 DN D8.U8[0]
+
+qH QN Q11.S32
+qV QN Q12.S32
+qA QN Q11.S16
+qB QN Q6.S16
+qC QN Q7.S16
+
+qB0 QN Q5.S16
+qB1 QN Q6.S16
+dA1 DN D23.S16
+
+dH0 DN D22.S32
+dH1 DN D23.S32
+dV0 DN D24.S32
+dV1 DN D25.S32
+
+qHV QN Q11.S64
+qHV0 QN Q11.S32
+qHV1 QN Q12.S64
+
+dHV00 DN D22.S32
+dHV01 DN D23.S32
+
+dHV0 DN D22.S16[0]
+dHV1 DN D23.S16[0]
+dHV10 DN D24.S64
+dHV11 DN D25.S64
+
+qSum0 QN Q0.S16
+qSum1 QN Q1.S16
+
+dOut0 DN D6.U8
+dOut1 DN D7.U8
+
+dLeft0 DN D2.U8
+dLeft1 DN D3.U8
+qConst QN Q13.S16
+
+dAbove0 DN D0.U8
+dAbove1 DN D1.U8
+
+dRevLeft64 DN D12.U64
+dRevLeft DN D12.U8
+dRevAbove64 DN D5.U64
+dRevAbove DN D5.U8
+qLeftDiff QN Q8.S16
+dLeftDiff1 DN D17.S16
+dLeftDiff64 DN D17.S64
+qDiffLeft QN Q8.S16
+qDiffAbove QN Q4.S16
+dAboveDiff1 DN D9.S16
+dAboveDiff64 DN D9.S64
+qAboveDiff QN Q4.S16
+
+dAboveLeft DN D4.U8
+
+dDiffLeft0 DN D16.S16
+dDiffLeft1 DN D17.S16
+dDiffAbove0 DN D8.S16
+dDiffAbove1 DN D9.S16
+
+qLeft15minus0 QN Q7.S16
+dLeft15minus0 DN D14.S16
+qAbove15minus0 QN Q3.S16
+dAbove15minus0 DN D6.S16
+
+qMultiplier QN Q10.S16
+qMultiplier0 QN Q10.S16
+qMultiplier1 QN Q12.S16
+dMultiplier0 DN D20.S16
+dMultiplier1 DN D21.S16
+
+dBPlusCMult7 DN D1.S64
+dBPlusCMult7S16 DN D1.S16
+
+qTmp QN Q0.U8
+
+;//--------------------------------------------
+;// Declare input registers
+;//--------------------------------------------
+pSrcLeft RN 0 ;// input pointer
+pSrcAbove RN 1 ;// input pointer
+pSrcAboveLeft RN 2 ;// input pointer
+pDst RN 3 ;// output pointer
+leftStep RN 4 ;// input variable
+dstStep RN 5 ;// input variable
+predMode RN 6 ;// input variable
+availability RN 7 ;// input variable
+
+pTmp RN 8
+step RN 10
+pTmp2 RN 11
+
+;//-----------------------------------------------------------------------------------------------
+;// omxVCM4P10_PredictIntra_16x16 starts
+;//-----------------------------------------------------------------------------------------------
+
+ ;// Write function header
+ M_START omxVCM4P10_PredictIntra_16x16, r11, d15
+
+ ;// Define stack arguments
+ M_ARG LeftStep, 4
+ M_ARG DstStep, 4
+ M_ARG PredMode, 4
+ M_ARG Availability, 4
+
+ ;// M_STALL ARM1136JS=4
+
+ LDR pTable,=armVCM4P10_pIndexTable16x16 ;// Load index table for switch case
+
+ ;// Load argument from the stack
+ M_LDR predMode, PredMode ;// Arg predMode loaded from stack to reg
+ M_LDR leftStep, LeftStep ;// Arg leftStep loaded from stack to reg
+ M_LDR dstStep, DstStep ;// Arg dstStep loaded from stack to reg
+ M_LDR availability, Availability ;// Arg availability loaded from stack to reg
+
+ MOV y, #BLK_SIZE ;// Outer Loop Count
+ LDR pc, [pTable, predMode, LSL #2] ;// Branch to the case based on preMode
+
+OMX_VC_16X16_VERT
+ VLD1 qAbove, [pSrcAbove]
+ ADD pTmp, pDst, dstStep
+ ADD step, dstStep, dstStep
+ VST1 qAbove, [pDst], step
+ VST1 qAbove, [pTmp], step
+ VST1 qAbove, [pDst], step
+ VST1 qAbove, [pTmp], step
+ VST1 qAbove, [pDst], step
+ VST1 qAbove, [pTmp], step
+ VST1 qAbove, [pDst], step
+ VST1 qAbove, [pTmp], step
+ VST1 qAbove, [pDst], step
+ VST1 qAbove, [pTmp], step
+ VST1 qAbove, [pDst], step
+ VST1 qAbove, [pTmp], step
+ VST1 qAbove, [pDst], step
+ VST1 qAbove, [pTmp], step
+ VST1 qAbove, [pDst]
+ VST1 qAbove, [pTmp]
+ MOV return, #OMX_Sts_NoErr ;// returnNoError
+ M_EXIT
+
+OMX_VC_16X16_HOR
+ ADD pTmp, pSrcLeft, leftStep
+ ADD leftStep, leftStep, leftStep
+ ADD pTmp2, pDst, dstStep
+ ADD dstStep, dstStep, dstStep
+LoopHor
+ VLD1 {qLeft[]}, [pSrcLeft], leftStep
+ VLD1 {qTmp[]}, [pTmp], leftStep
+ SUBS y, y, #8
+ VST1 qLeft, [pDst], dstStep
+ VST1 qTmp, [pTmp2], dstStep
+ VLD1 {qLeft[]}, [pSrcLeft], leftStep
+ VLD1 {qTmp[]}, [pTmp], leftStep
+ VST1 qLeft, [pDst], dstStep
+ VST1 qTmp, [pTmp2], dstStep
+ VLD1 {qLeft[]}, [pSrcLeft], leftStep
+ VLD1 {qTmp[]}, [pTmp], leftStep
+ VST1 qLeft, [pDst], dstStep
+ VST1 qTmp, [pTmp2], dstStep
+ VLD1 {qLeft[]}, [pSrcLeft], leftStep
+ VLD1 {qTmp[]}, [pTmp], leftStep
+ VST1 qLeft, [pDst], dstStep
+ VST1 qTmp, [pTmp2], dstStep
+
+ BNE LoopHor ;// Loop for 16 times
+ MOV return, #OMX_Sts_NoErr
+ M_EXIT
+
+OMX_VC_16X16_DC
+ MOV count, #0 ;// count = 0
+ TST availability, #OMX_VC_LEFT
+ BEQ UpperOrNoneAvailable ;// Jump to Upper if not left
+
+ ADD pTmp, pSrcLeft, leftStep
+ ADD step, leftStep, leftStep
+
+ VLD1 {qLeft[0]}, [pSrcLeft],step
+ VLD1 {qLeft[1]}, [pTmp],step
+ VLD1 {qLeft[2]}, [pSrcLeft],step
+ VLD1 {qLeft[3]}, [pTmp],step
+ VLD1 {qLeft[4]}, [pSrcLeft],step
+ VLD1 {qLeft[5]}, [pTmp],step
+ VLD1 {qLeft[6]}, [pSrcLeft],step
+ VLD1 {qLeft[7]}, [pTmp],step
+ VLD1 {qLeft[8]}, [pSrcLeft],step
+ VLD1 {qLeft[9]}, [pTmp],step
+ VLD1 {qLeft[10]},[pSrcLeft],step
+ VLD1 {qLeft[11]},[pTmp],step
+ VLD1 {qLeft[12]},[pSrcLeft],step
+ VLD1 {qLeft[13]},[pTmp],step
+ VLD1 {qLeft[14]},[pSrcLeft],step
+ VLD1 {qLeft[15]},[pTmp]
+
+ VPADDL qSum8, qLeft
+ ADD count, count, #1
+ VPADD dSum4, dSum80, dSum81
+ VPADDL dSum2, dSum4
+ VPADDL dSumLeft, dSum2
+ VRSHR dSum, dSumLeft, #4
+
+UpperOrNoneAvailable
+ TST availability, #OMX_VC_UPPER ;// if(availability & #OMX_VC_UPPER)
+ BEQ BothOrNoneAvailable ;// Jump to Left if not upper
+ VLD1 qAbove, [pSrcAbove]
+ ADD count, count, #1 ;// if upper inc count by 1
+ VPADDL qSum8, qAbove
+ VPADD dSum4, dSum80, dSum81
+ VPADDL dSum2, dSum4
+ VPADDL dSumAbove, dSum2
+ VRSHR dSum, dSumAbove, #4
+
+BothOrNoneAvailable
+ CMP count, #2 ;// check if both available
+ BNE NoneAvailable
+ VADD dSum, dSumAbove, dSumLeft
+ VRSHR dSum, dSum, #5
+
+
+NoneAvailable
+ VDUP qOut, dSum0
+ CMP count, #0 ;// check if none available
+ ADD pTmp, pDst, dstStep
+ ADD step, dstStep, dstStep
+ BNE LoopDC
+ VMOV qOut, #128
+LoopDC
+ VST1 qOut, [pDst], step
+ VST1 qOut, [pTmp], step
+ VST1 qOut, [pDst], step
+ VST1 qOut, [pTmp], step
+ VST1 qOut, [pDst], step
+ VST1 qOut, [pTmp], step
+ VST1 qOut, [pDst], step
+ VST1 qOut, [pTmp], step
+ VST1 qOut, [pDst], step
+ VST1 qOut, [pTmp], step
+ VST1 qOut, [pDst], step
+ VST1 qOut, [pTmp], step
+ VST1 qOut, [pDst], step
+ VST1 qOut, [pTmp], step
+ VST1 qOut, [pDst], step
+ VST1 qOut, [pTmp], step
+ MOV return, #OMX_Sts_NoErr
+ M_EXIT
+
+OMX_VC_16X16_PLANE
+ LDR pMultTable, =armVCM4P10_MultiplierTable16x16
+ VLD1 qAbove, [pSrcAbove] ;// pSrcAbove[x] :0<= x <= 7
+ VLD1 dAboveLeft[0],[pSrcAboveLeft]
+ ADD pTmp, pSrcLeft, leftStep
+ ADD step, leftStep, leftStep
+ VLD1 {qLeft[0]}, [pSrcLeft],step
+ VLD1 {qLeft[1]}, [pTmp],step
+ VLD1 {qLeft[2]}, [pSrcLeft],step
+ VLD1 {qLeft[3]}, [pTmp],step
+ VLD1 {qLeft[4]}, [pSrcLeft],step
+ VLD1 {qLeft[5]}, [pTmp],step
+ VLD1 {qLeft[6]}, [pSrcLeft],step
+ VLD1 {qLeft[7]}, [pTmp],step
+ VLD1 {qLeft[8]}, [pSrcLeft],step
+ VLD1 {qLeft[9]}, [pTmp],step
+ VLD1 {qLeft[10]}, [pSrcLeft],step
+ VLD1 {qLeft[11]}, [pTmp],step
+ VLD1 {qLeft[12]}, [pSrcLeft],step
+ VLD1 {qLeft[13]}, [pTmp],step
+ VLD1 {qLeft[14]}, [pSrcLeft],step
+ VLD1 {qLeft[15]}, [pTmp]
+
+ VREV64 dRevAbove, dAbove1 ;// pSrcAbove[15:14:13:12:11:10:9:8]
+ VSUBL qAbove15minus0, dRevAbove, dAboveLeft ;// qAbove7minus0[0] = pSrcAbove[15] - pSrcAboveLeft[0]
+ VSHR dRevAbove64, dRevAbove64, #8 ;// pSrcAbove[14:13:12:11:10:9:8:X]
+ VSUBL qAboveDiff, dRevAbove, dAbove0
+
+ VSHL dAboveDiff64, dAboveDiff64, #16
+ VEXT dDiffAbove1, dAboveDiff1, dAbove15minus0, #1
+
+ VREV64 dRevLeft,dLeft1 ;// pSrcLeft[15:14:13:12:11:10:9:8]
+ VSUBL qLeft15minus0,dRevLeft, dAboveLeft ;// qAbove7minus0[0] = pSrcLeft[7] - pSrcAboveLeft[0]
+ VSHR dRevLeft64, dRevLeft64, #8 ;// pSrcLeft[14:13:12:11:10:9:8:X]
+ VSUBL qLeftDiff,dRevLeft, dLeft0
+
+ ;// Multiplier = [8|1|2|...|6|7]
+ VLD1 qMultiplier, [pMultTable]!
+
+ VSHL dLeftDiff64, dLeftDiff64, #16
+ VEXT dDiffLeft1, dLeftDiff1, dLeft15minus0, #1
+
+ VMULL qH,dDiffAbove0, dMultiplier0
+ VMULL qV,dDiffLeft0, dMultiplier0
+ VMLAL qH,dDiffAbove1, dMultiplier1
+ VMLAL qV,dDiffLeft1, dMultiplier1
+
+ VPADD dHV00,dH1,dH0
+ VPADD dHV01,dV1,dV0
+ VPADDL qHV, qHV0
+ VSHL qHV1,qHV,#2
+ VADD qHV,qHV,qHV1
+
+ ;// HV = [c = ((5*V+32)>>6) | b = ((5*H+32)>>6)]
+ VRSHR qHV,qHV,#6
+
+ ;// HV1 = [c*7|b*7]
+ VSHL qHV1,qHV,#3
+ VSUB qHV1,qHV1,qHV
+
+ ;// Multiplier1 = [0|1|2|...|7]
+ VLD1 qMultiplier0, [pMultTable]!
+ VDUP qB, dHV0
+ VDUP qC, dHV1
+
+ VADDL qA,dAbove1,dLeft1
+ VSHL qA,qA, #4
+ VDUP qA,dA1[3]
+ VADD dBPlusCMult7, dHV10, dHV11
+
+ ;// Multiplier1 = [8|9|10|...|15]
+ VLD1 qMultiplier1, [pMultTable]
+ ;// Const = a - 7*(b+c)
+ VDUP qConst, dBPlusCMult7S16[0]
+ VSUB qConst, qA, qConst
+
+ ;// B0 = [0*b|1*b|2*b|3*b|......|7*b]
+ VMUL qB0,qB,qMultiplier0
+
+ ;// B0 = [8*b|9*b|10*b|11*b|....|15*b]
+ VMUL qB1,qB,qMultiplier1
+
+ VADD qSum0, qB0, qConst
+ VADD qSum1, qB1, qConst
+
+ ;// Loops for 16 times
+LoopPlane
+ ;// (b*x + c*y + C)>>5
+ VQRSHRUN dOut0, qSum0,#5
+ VQRSHRUN dOut1, qSum1,#5
+ SUBS y, y, #1
+ VST1 qOut,[pDst],dstStep
+ VADD qSum0,qSum0,qC
+ VADD qSum1,qSum1,qC
+ BNE LoopPlane
+
+ MOV return, #OMX_Sts_NoErr
+
+ M_END
+
+ ENDIF ;// CortexA8
+
+ END
+;-----------------------------------------------------------------------------------------------
+; omxVCM4P10_PredictIntra_16x16 ends
+;-----------------------------------------------------------------------------------------------
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_PredictIntra_4x4_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_PredictIntra_4x4_s.s
new file mode 100755
index 0000000..39eb8a4
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_PredictIntra_4x4_s.s
@@ -0,0 +1,531 @@
+;//
+;//
+;// File Name: omxVCM4P10_PredictIntra_4x4_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 12290
+;// Date: Wednesday, April 9, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+;// Define the processor variants supported by this file
+
+ M_VARIANTS CortexA8
+
+;//-------------------------------------------------------
+;// This table for implementing switch case of C in asm by
+;// the mehtod of two levels of indexing.
+;//-------------------------------------------------------
+
+ M_TABLE armVCM4P10_pSwitchTable4x4
+ DCD OMX_VC_4x4_VERT, OMX_VC_4x4_HOR
+ DCD OMX_VC_4x4_DC, OMX_VC_4x4_DIAG_DL
+ DCD OMX_VC_4x4_DIAG_DR, OMX_VC_4x4_VR
+ DCD OMX_VC_4x4_HD, OMX_VC_4x4_VL
+ DCD OMX_VC_4x4_HU
+
+
+ IF CortexA8
+
+;//--------------------------------------------
+;// Scratch variable
+;//--------------------------------------------
+return RN 0
+pTable RN 8
+pc RN 15
+
+;//--------------------------------------------
+;// Declare input registers
+;//--------------------------------------------
+pSrcLeft RN 0 ;// input pointer
+pSrcAbove RN 1 ;// input pointer
+pSrcAboveLeft RN 2 ;// input pointer
+pDst RN 3 ;// output pointer
+leftStep RN 4 ;// input variable
+dstStep RN 5 ;// input variable
+predMode RN 6 ;// input variable
+availability RN 7 ;// input variable
+pDst1 RN 1
+pDst2 RN 4
+pDst3 RN 6
+
+pSrcTmp RN 9
+srcStep RN 10
+pDstTmp RN 11
+dstep RN 12
+
+;//-------------------
+;// Neon registers
+;//-------------------
+
+;// OMX_VC_CHROMA_VERT
+dAboveU32 DN D0.U32
+
+;// OMX_VC_CHROMA_HOR
+dLeftVal0 DN D0.8
+dLeftVal1 DN D1.8
+dLeftVal2 DN D2.8
+dLeftVal3 DN D3.8
+dLeftVal0U32 DN D0.U32
+dLeftVal1U32 DN D1.U32
+dLeftVal2U32 DN D2.U32
+dLeftVal3U32 DN D3.U32
+
+;// OMX_VC_4x4_DC
+dLeftVal DN D0.U8
+dLeftValU32 DN D0.U32
+dSumAboveLeftU16 DN D1.U16
+dSumAboveLeftU32 DN D1.U32
+dSumAboveLeftU64 DN D1.U64
+dSumAboveLeftU8 DN D1.U8
+dSum DN D0.U8
+
+dSumLeftValU16 DN D1.U16
+dSumLeftValU32 DN D1.U32
+dSumLeftValU64 DN D1.U64
+dSumLeftValU8 DN D1.U8
+
+dAboveVal DN D0.U8
+dSumAboveValU16 DN D1.U16
+dSumAboveValU32 DN D1.U32
+dSumAboveValU64 DN D1.U64
+dSumAboveValU8 DN D1.U8
+dConst128U8 DN D0.U8
+
+
+;//OMX_VC_4x4_DIAG_DL
+
+dAbove DN D0.U8
+dU7 DN D2.U8
+dU3 DN D2.U8
+dAbove0 DN D3.U8
+dAbove1 DN D4.U8
+dAbove2 DN D5.U8
+dTmp DN D6.U8
+dTmp0 DN D7.U8
+dTmp1 DN D8.U8
+dTmp2 DN D9.U8
+dTmp3 DN D10.U8
+dTmpU32 DN D6.U32
+
+
+;//OMX_VC_4x4_DIAG_DR
+dLeft DN D1.U8
+dUL DN D2.U8
+
+;//OMX_VC_4x4_VR
+dLeft0 DN D1.U8
+dLeft1 DN D2.U8
+dEven0 DN D3.U8
+dEven1 DN D4.U8
+dEven2 DN D5.U8
+dOdd0 DN D6.U8
+dOdd1 DN D11.U8
+dOdd2 DN D12.U8
+dTmp3U32 DN D10.U32
+dTmp2U32 DN D9.U32
+
+
+;//OMX_VC_4x4_HD
+dTmp1U64 DN D8.U64
+dTmp0U64 DN D7.U64
+dTmpU64 DN D6.U64
+dTmpU32 DN D6.U32
+dTmp1U32 DN D8.U32
+
+;//OMX_VC_4x4_HU
+dL3 DN D2.U8
+dLeftHU0 DN D3.U8
+dLeftHU1 DN D4.U8
+dLeftHU2 DN D5.U8
+dTmp0U32 DN D7.U32
+
+
+
+
+;//-----------------------------------------------------------------------------------------------
+;// omxVCM4P10_PredictIntra_4x4 starts
+;//-----------------------------------------------------------------------------------------------
+
+ ;// Write function header
+ M_START omxVCM4P10_PredictIntra_4x4, r12,d12
+
+ ;// Define stack arguments
+ M_ARG LeftStep, 4
+ M_ARG DstStep, 4
+ M_ARG PredMode, 4
+ M_ARG Availability, 4
+
+
+ LDR pTable,=armVCM4P10_pSwitchTable4x4 ;// Load index table for switch case
+
+ ;// Load argument from the stack
+ M_LDRD predMode,availability,PredMode ;// Arg predMode & availability loaded from stack to reg
+ M_LDRD leftStep,dstStep,LeftStep ;// Arg leftStep & dstStep loaded from stack to reg
+
+
+ LDR pc, [pTable, predMode, LSL #2] ;// Branch to the case based on preMode
+
+
+OMX_VC_4x4_HOR
+
+ ADD pSrcTmp, pSrcLeft, leftStep
+ ADD srcStep, leftStep, leftStep
+ ;// Load Left Edge
+ VLD1 {dLeftVal0[]},[pSrcLeft],srcStep ;// pSrcLeft[0*leftStep]
+ VLD1 {dLeftVal1[]},[pSrcTmp],srcStep ;// pSrcLeft[1*leftStep]
+ VLD1 {dLeftVal2[]},[pSrcLeft] ;// pSrcLeft[2*leftStep]
+ VLD1 {dLeftVal3[]},[pSrcTmp] ;// pSrcLeft[3*leftStep]
+
+ ADD pDstTmp, pDst, dstStep
+ ADD dstep, dstStep, dstStep
+
+ VST1 dLeftVal0U32[0],[pDst],dstep ;// pDst[0*dstStep+x] :0<= x <= 7
+ VST1 dLeftVal1U32[0],[pDstTmp],dstep ;// pDst[1*dstStep+x] :0<= x <= 7
+ VST1 dLeftVal2U32[0],[pDst] ;// pDst[2*dstStep+x] :0<= x <= 7
+ VST1 dLeftVal3U32[0],[pDstTmp] ;// pDst[3*dstStep+x] :0<= x <= 7
+
+ B ExitPredict4x4 ;// Branch to exit code
+
+OMX_VC_4x4_VERT
+
+ ;// Load Upper Edge
+ VLD1 dAboveU32[0],[pSrcAbove]
+ ADD pDstTmp, pDst, dstStep
+ ADD dstep, dstStep, dstStep
+
+DCPredict4x4VertStore
+
+ VST1 dAboveU32[0],[pDst],dstep
+ VST1 dAboveU32[0],[pDstTmp],dstep
+ VST1 dAboveU32[0],[pDst]
+ VST1 dAboveU32[0],[pDstTmp]
+
+ B ExitPredict4x4 ;// Branch to exit code
+
+OMX_VC_4x4_DC
+
+
+ TST availability, #OMX_VC_LEFT
+ BEQ DCPredict4x4LeftNotAvailable
+
+ ADD pSrcTmp, pSrcLeft, leftStep
+ ADD srcStep, leftStep, leftStep
+ ;// Load Left Edge
+ VLD1 {dLeftVal[0]},[pSrcLeft],srcStep ;// pSrcLeft[0*leftStep]
+ VLD1 {dLeftVal[1]},[pSrcTmp],srcStep ;// pSrcLeft[1*leftStep]
+ VLD1 {dLeftVal[2]},[pSrcLeft] ;// pSrcLeft[2*leftStep]
+ VLD1 {dLeftVal[3]},[pSrcTmp] ;// pSrcLeft[3*leftStep]
+
+ TST availability, #OMX_VC_UPPER
+ BEQ DCPredict4x4LeftOnlyAvailable
+
+ ;// Load Upper Edge also
+ VLD1 dLeftValU32[1],[pSrcAbove] ;// pSrcAbove[0 to 3]
+ MOV return, #OMX_Sts_NoErr
+
+ VPADDL dSumAboveLeftU16, dLeftVal ;// [pSrcAbove[2+3 | 0+1] | pSrcLeft[2+3 | 0+1]]
+ VPADDL dSumAboveLeftU32, dSumAboveLeftU16 ;// [pSrcAbove[2+3+0+1] | pSrcLeft[2+3+0+1]]
+ VPADDL dSumAboveLeftU64, dSumAboveLeftU32 ;// [pSrcAbove[2+3+0+1] + pSrcLeft[2+3+0+1]]
+ VRSHR dSumAboveLeftU64,dSumAboveLeftU64,#3 ;// Sum = (Sum + 4) >> 3
+ ADD pDstTmp, pDst, dstStep
+ ADD dstep, dstStep, dstStep
+ VDUP dSum,dSumAboveLeftU8[0]
+
+ B DCPredict4x4VertStore
+
+DCPredict4x4LeftOnlyAvailable
+
+ MOV return, #OMX_Sts_NoErr ;// returnNoError
+
+ VPADDL dSumLeftValU16, dLeftVal ;// [ XX | pSrcLeft[2+3 | 0+1]]
+ VPADDL dSumLeftValU32, dSumLeftValU16 ;// [ XXXX | pSrcLeft[2+3+0+1]]
+
+ VRSHR dSumLeftValU32,dSumLeftValU32,#2 ;// Sum = (Sum + 2) >> 2
+ ADD pDstTmp, pDst, dstStep
+ ADD dstep, dstStep, dstStep
+ VDUP dSum,dSumLeftValU8[0]
+
+ B DCPredict4x4VertStore
+
+DCPredict4x4LeftNotAvailable
+
+ TST availability, #OMX_VC_UPPER
+ BEQ DCPredict4x4NoneAvailable
+
+ ;// Load Upper Edge
+ VLD1 dAboveU32[0],[pSrcAbove] ;// pSrcAbove[0 to 3]
+ MOV return, #OMX_Sts_NoErr
+
+ VPADDL dSumAboveValU16, dAboveVal ;// [ XX | pSrcAbove[2+3 | 0+1]]
+ VPADDL dSumAboveValU32, dSumAboveValU16 ;// [ XXXX | pSrcAbove[2+3+0+1]]
+
+ VRSHR dSumAboveValU32,dSumAboveValU32,#2 ;// Sum = (Sum + 2) >> 2
+ ADD pDstTmp, pDst, dstStep
+ ADD dstep, dstStep, dstStep
+ VDUP dSum,dSumAboveValU8[0]
+
+ B DCPredict4x4VertStore
+
+DCPredict4x4NoneAvailable
+
+ VMOV dConst128U8,#0x80 ;// 0x8080808080808080 if(count == 0)
+ MOV return, #OMX_Sts_NoErr
+
+ ADD pDstTmp, pDst, dstStep
+ ADD dstep, dstStep, dstStep
+ B DCPredict4x4VertStore
+
+
+
+OMX_VC_4x4_DIAG_DL
+
+ TST availability, #OMX_VC_UPPER_RIGHT
+ BEQ DiagDLUpperRightNotAvailable
+
+ VLD1 dAbove0,[pSrcAbove] ;// [U7|U6|U5|U4|U3|U2|U1|U0]
+ VDUP dU7, dAbove0[7] ;// [U7|U7|U7|U7|U7|U7|U7|U7]
+ VEXT dAbove1, dAbove0, dU7, #1 ;// [U7|U7|U6|U5|U4|U3|U2|U1]
+ VEXT dAbove2, dAbove0, dU7, #2 ;// [U7|U7|U7|U6|U5|U4|U3|U2]
+ B DiagDLPredict4x4Store
+
+DiagDLUpperRightNotAvailable
+ VLD1 dAboveU32[1],[pSrcAbove] ;// [U3|U2|U1|U0|-|-|-|-]
+ VDUP dU3, dAbove[7] ;// [U3 U3 U3 U3 U3 U3 U3 U3]
+
+ VEXT dAbove0, dAbove, dU3, #4 ;// [U3 U3 U3 U3 U3 U2 U1 U0]
+ VEXT dAbove1, dAbove, dU3, #5 ;// [U3 U3 U3 U3 U3 U3 U2 U1]
+ VEXT dAbove2, dAbove, dU3, #6 ;// [U3 U3 U3 U3 U3 U3 U3 U2]
+
+DiagDLPredict4x4Store
+
+ VHADD dTmp, dAbove0, dAbove2
+ VRHADD dTmp, dTmp, dAbove1 ;// (a+2*b+c+2)>>2
+
+
+ VST1 dTmpU32[0],[pDst],dstStep
+ VEXT dTmp,dTmp,dTmp,#1
+ VST1 dTmpU32[0],[pDst],dstStep
+ VEXT dTmp,dTmp,dTmp,#1
+ VST1 dTmpU32[0],[pDst],dstStep
+ VEXT dTmp,dTmp,dTmp,#1
+ VST1 dTmpU32[0],[pDst]
+
+ B ExitPredict4x4 ;// Branch to exit code
+
+
+OMX_VC_4x4_DIAG_DR
+
+
+ ;// Load U0,U1,U2,U3
+
+ VLD1 dAboveU32[0],[pSrcAbove] ;// [X|X|X|X|U3|U2|U1|U0]
+
+ ;// Load UL,L0,L1,L2,L3 ;// dLeft = [UL|L0|L1|L2|L3|X|X|X]
+ VLD1 {dLeft[7]},[pSrcAboveLeft]
+ ADD pSrcTmp, pSrcLeft, leftStep
+ ADD srcStep, leftStep, leftStep
+ ADD pDst1,pDst,dstStep
+
+ VLD1 {dLeft[6]},[pSrcLeft],srcStep ;// pSrcLeft[0*leftStep]
+ VLD1 {dLeft[5]},[pSrcTmp],srcStep ;// pSrcLeft[1*leftStep]
+ VLD1 {dLeft[4]},[pSrcLeft] ;// pSrcLeft[2*leftStep]
+ VLD1 {dLeft[3]},[pSrcTmp] ;// pSrcLeft[3*leftStep]
+
+
+ VEXT dAbove0,dLeft,dAbove,#3 ;// [U2|U1|U0|UL|L0|L1|L2|L3]
+ ADD pDst2,pDst1,dstStep
+ VEXT dAbove1,dLeft,dAbove,#4 ;// [U3|U2|U1|U0|UL|L0|L1|L2]
+ ADD pDst3,pDst2,dstStep
+ VEXT dAbove2,dLeft,dAbove,#5 ;// [ X|U3|U2|U1|U0|UL|L0|L1]
+
+ VHADD dTmp, dAbove0, dAbove2
+ VRHADD dTmp, dTmp, dAbove1 ;// (a+2*b+c+2)>>2
+
+
+ VST1 dTmpU32[0],[pDst3] ;// Store pTmp[0],[1],[2],[3] @ pDst3
+ VEXT dTmp,dTmp,dTmp,#1
+ VST1 dTmpU32[0],[pDst2] ;// Store pTmp[1],[2],[3],[4] @ pDst2
+ VEXT dTmp,dTmp,dTmp,#1
+ VST1 dTmpU32[0],[pDst1] ;// Store pTmp[2],[3],[4],[5] @ pDst1
+ VEXT dTmp,dTmp,dTmp,#1
+ VST1 dTmpU32[0],[pDst] ;// Store pTmp[3],[4],[5],[6] @ pDst
+
+ B ExitPredict4x4 ;// Branch to exit code
+
+OMX_VC_4x4_VR
+
+
+ ;// Load UL,U0,U1,U2,U3
+ VLD1 dAboveU32[0],[pSrcAbove]
+ VLD1 dAbove[7],[pSrcAboveLeft] ;// [UL|X|X|X|U3|U2|U1|U0]
+
+ ;// Load L0,L1,L2 ;// dLeft0 = [L0|L2|X|X|X|X|X|X]
+ ;// dLeft1 = [L1| X|X|X|X|X|X|X]
+ VLD1 {dLeft0[7]},[pSrcLeft],leftStep ;// pSrcLeft[0*leftStep]
+ VLD1 {dLeft1[7]},[pSrcLeft],leftStep ;// pSrcLeft[1*leftStep]
+ VLD1 {dLeft0[6]},[pSrcLeft] ;// pSrcLeft[2*leftStep]
+
+
+ VEXT dOdd2,dAbove,dAbove,#7 ;// [ x x x U3 U2 U1 U0 UL ]
+ VEXT dEven0,dLeft0,dOdd2,#6 ;// [ x x x U1 U0 UL L0 L2 ]
+ VEXT dEven1,dLeft1,dOdd2,#7 ;// [ x x x U2 U1 U0 UL L1 ]
+ VEXT dEven2,dLeft0,dAbove,#7 ;// [ x x x U3 U2 U1 U0 L0 ]
+ VEXT dOdd0,dLeft1,dAbove,#7 ;// [ x x x U3 U2 U1 U0 L1 ]
+ VEXT dOdd1,dLeft0,dOdd2,#7 ;// [ x x x U2 U1 U0 UL L0 ]
+
+ VHADD dTmp1, dOdd0, dOdd2
+ VRHADD dTmp1, dTmp1, dOdd1 ;// Tmp[ x x x 9 7 5 3 1 ]
+
+ VHADD dTmp0, dEven0, dEven2
+ VRHADD dTmp0, dTmp0, dEven1 ;// Tmp[ x x x 8 6 4 2 0 ]
+
+
+ VEXT dTmp3,dTmp1,dTmp1,#1 ;// Tmp[ x x x x 9 7 5 3 ]
+ ADD pDstTmp, pDst, dstStep
+ ADD dstep, dstStep, dstStep
+ VEXT dTmp2,dTmp0,dTmp0,#1 ;// Tmp[ x x x x 8 6 4 2 ]
+
+
+ VST1 dTmp3U32[0],[pDst],dstep ;// Tmp[9],[7],[5],[3]
+ VST1 dTmp2U32[0],[pDstTmp],dstep ;// Tmp[8],[6],[4],[2]
+ VST1 dTmp1U32[0],[pDst],dstep ;// Tmp[7],[5],[3],[1]
+ VST1 dTmp0U32[0],[pDstTmp] ;// Tmp[6],[4],[2],[0]
+
+ B ExitPredict4x4 ;// Branch to exit code
+
+OMX_VC_4x4_HD
+
+
+ ;// Load U0,U1,U2,U3
+ VLD1 dAbove,[pSrcAbove] ;//dAboveLeftVal = [U7|U6|U5|U4|U3|U2|U1|U0]
+
+ ;// Load UL,L0,L1,L2,L3 ;// dLeft = [UL|L0|L1|L2|L3|X|X|X]
+ VLD1 {dLeft[7]},[pSrcAboveLeft]
+ ADD pSrcTmp, pSrcLeft, leftStep
+ ADD srcStep, leftStep, leftStep
+
+ VLD1 {dLeft[6]},[pSrcLeft],srcStep ;// pSrcLeft[0*leftStep]
+ VLD1 {dLeft[5]},[pSrcTmp],srcStep ;// pSrcLeft[1*leftStep]
+ VLD1 {dLeft[4]},[pSrcLeft] ;// pSrcLeft[2*leftStep]
+ VLD1 {dLeft[3]},[pSrcTmp] ;// pSrcLeft[3*leftStep]
+
+ VEXT dAbove0,dLeft,dAbove,#3 ;// [ U2|U1|U0|UL|L0|L1|L2|L3 ]
+ VEXT dAbove1,dLeft,dAbove,#2 ;// [ U1|U0|UL|L0|L1|L2|L3|X ]
+ VEXT dAbove2,dLeft,dAbove,#1 ;// [ U0|UL|L0|L1|L2|L3|X|X ]
+
+ VHADD dTmp0, dAbove0, dAbove2
+ VRHADD dTmp0, dTmp0, dAbove1 ;// Tmp[ 0 | 1 | 2 | 4 | 6 | 8 | X | X ]
+
+
+ VRHADD dTmp1, dAbove1, dAbove0 ;// (a+b+1)>>1
+ VSHL dTmp1U64,dTmp1U64,#24 ;// Tmp[ 3|5| 7 |9 | X | X | X | X ]
+
+
+ VSHL dTmpU64,dTmp0U64,#16 ;// Tmp[ 2|4|6|8| X | X | X | X ]
+ VZIP dTmp1,dTmp ;// dTmp = [ 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 ]
+ VEXT dTmp0,dTmp0,dTmp0,#6 ;// Tmp[ X| X| X| X| X| X| 0 | 1 ]
+ VEXT dTmp1,dTmp,dTmp0,#2 ;// Tmp[ 0 | 1 | 2 | 3 | 4 | 5 | 6 |7 ]
+
+ ADD pDstTmp, pDst, dstStep
+ ADD dstep, dstStep, dstStep
+
+ VST1 dTmp1U32[1],[pDst],dstep ;// Store pTmp[0|1|2|3]
+ VST1 dTmpU32[1],[pDstTmp],dstep ;// Store pTmp[2|3|4|5]
+ VST1 dTmp1U32[0],[pDst] ;// Store pTmp[4|5|6|7]
+ VST1 dTmpU32[0],[pDstTmp] ;// Store pTmp[6|7|8|9]
+
+ B ExitPredict4x4 ;// Branch to exit code
+
+OMX_VC_4x4_VL
+
+
+ TST availability, #OMX_VC_UPPER_RIGHT
+ BEQ DiagVLUpperRightNotAvailable
+
+ VLD1 dAbove0,[pSrcAbove] ;// [U7|U6|U5|U4|U3|U2|U1|U0]
+ VEXT dAbove1,dAbove0,dAbove0,#1 ;// [ X|U7|U6|U5|U4|U3|U2|U1]
+ VEXT dAbove2,dAbove1,dAbove1,#1 ;// [ X| X|U7|U6|U5|U4|U3|U2]
+
+ B DiagVLPredict4x4Store
+
+DiagVLUpperRightNotAvailable
+ VLD1 dAboveU32[1],[pSrcAbove] ;// [U3|U2|U1|U0|-|-|-|-]
+ VDUP dU3, dAbove[7] ;// [U3 U3 U3 U3 U3 U3 U3 U3]
+
+ VEXT dAbove0, dAbove, dU3, #4 ;// [U3 U3 U3 U3 U3 U2 U1 U0]
+ VEXT dAbove1, dAbove, dU3, #5 ;// [U3 U3 U3 U3 U3 U3 U2 U1]
+ VEXT dAbove2, dAbove, dU3, #6 ;// [U3 U3 U3 U3 U3 U3 U3 U2]
+
+DiagVLPredict4x4Store
+
+ VRHADD dTmp0, dAbove1, dAbove0 ;// (a+b+1)>>1
+ ;// Tmp[ X| X| X| 8| 6| 4| 2| 0 ]
+
+ VHADD dTmp3, dAbove0, dAbove2
+ VRHADD dTmp3, dTmp3, dAbove1 ;// (a+2*b+c+2)>>2
+ ;// Tmp[ X| X| X| 9| 7| 5| 3| 1 ]
+
+ VEXT dTmp1,dTmp0,dTmp0,#1 ;// Tmp[ X| X| X| X| 8| 6| 4| 2 ]
+ ADD pDstTmp, pDst, dstStep
+ ADD dstep, dstStep, dstStep
+ VEXT dTmp2,dTmp3,dTmp1,#1 ;// Tmp[ X| X| X| X| 9| 7| 5| 3 ]
+
+ VST1 dTmp0U32[0],[pDst],dstep ;// Tmp[6],[4],[2],[0]
+ VST1 dTmp3U32[0],[pDstTmp],dstep ;// Tmp[7],[5],[3],[1]
+ VST1 dTmp1U32[0],[pDst] ;// Tmp[8],[6],[4],[2]
+ VST1 dTmp2U32[0],[pDstTmp] ;// Tmp[9],[7],[5],[3]
+
+ B ExitPredict4x4 ;// Branch to exit code
+
+OMX_VC_4x4_HU
+ ADD pSrcTmp, pSrcLeft, leftStep
+ ADD srcStep, leftStep, leftStep
+
+ ;// Load Left Edge ;// [L3|L2|L1|L0|X|X|X|X]
+ VLD1 {dLeft[4]},[pSrcLeft],srcStep ;// pSrcLeft[0*leftStep]
+ VLD1 {dLeft[5]},[pSrcTmp],srcStep ;// pSrcLeft[1*leftStep]
+ VLD1 {dLeft[6]},[pSrcLeft] ;// pSrcLeft[2*leftStep]
+ VLD1 {dLeft[7]},[pSrcTmp] ;// pSrcLeft[3*leftStep]
+
+ VDUP dL3,dLeft[7] ;// [L3|L3|L3|L3|L3|L3|L3|L3]
+
+ VEXT dLeftHU0,dLeft,dL3,#4 ;// [L3|L3|L3|L3|L3|L2|L1|L0]
+ VEXT dLeftHU1,dLeft,dL3,#5 ;// [L3|L3|L3|L3|L3|L3|L2|L1]
+ VEXT dLeftHU2,dLeft,dL3,#6 ;// [L3|L3|L3|L3|L3|L3|L3|L2]
+
+ VHADD dTmp0, dLeftHU0, dLeftHU2
+ VRHADD dTmp0, dTmp0, dLeftHU1 ;// Tmp[ L3 | L3 | L3 | L3 | L3 | 5 | 3 | 1 ]
+
+ VRHADD dTmp1, dLeftHU1, dLeftHU0 ;// (a+b+1)>>1
+ ;// Tmp[ L3 | L3 | L3 | L3 | L3 | 4 | 2 | 0 ]
+
+ VZIP dTmp1,dTmp0 ;// dTmp1 = Tmp[7| 6| 5| 4| 3| 2| 1| 0]
+ ;// dTmp0 = [L3|L3|L3|L3|L3|L3|L3|L3]
+
+
+ VST1 dTmp1U32[0],[pDst],dstStep ;// [3|2|1|0]
+ VEXT dTmp1,dTmp1,dTmp1,#2
+ VST1 dTmp1U32[0],[pDst],dstStep ;// [5|4|3|2]
+ VEXT dTmp1,dTmp1,dTmp1,#2
+ VST1 dTmp1U32[0],[pDst],dstStep ;// [7|6|5|4]
+ VST1 dTmp0U32[0],[pDst] ;// [9|8|7|6]
+
+
+ExitPredict4x4
+
+ MOV return, #OMX_Sts_NoErr
+ M_END
+
+ ENDIF ;// CortexA8
+
+ END
+;//-----------------------------------------------------------------------------------------------
+;// omxVCM4P10_PredictIntra_4x4 ends
+;//-----------------------------------------------------------------------------------------------
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_TransformDequantChromaDCFromPair_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_TransformDequantChromaDCFromPair_s.s
new file mode 100755
index 0000000..e394339
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_TransformDequantChromaDCFromPair_s.s
@@ -0,0 +1,140 @@
+;//
+;//
+;// File Name: omxVCM4P10_TransformDequantChromaDCFromPair_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 12290
+;// Date: Wednesday, April 9, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ IMPORT armVCM4P10_QPDivTable
+ IMPORT armVCM4P10_VMatrixQPModTable
+
+ M_VARIANTS CortexA8
+
+
+
+
+ IF CortexA8
+
+;// ARM Registers
+;//--------------------------------------
+;// Declare input registers
+;//--------------------------------------
+ppSrc RN 0
+pDst RN 1
+QP RN 2
+
+;//--------------------------------
+;// Scratch variable for Unpack2x2
+;//--------------------------------
+pSrc RN 9
+Value RN 4
+Value2 RN 5
+Flag RN 6
+strOffset RN 7
+cstOffset RN 8
+
+;//--------------------------------
+;// Scratch variable
+;//--------------------------------
+r0w0 RN 3
+r0w1 RN 4
+
+c0w0 RN 5
+c1w0 RN 6
+
+return RN 0
+pQPDivTable RN 5
+pQPModTable RN 6
+Shift RN 9
+Scale RN 2
+
+
+
+;// Neon Registers
+
+dZero DN D0.U16
+dInvTrCoeff DN D0.S16
+dScale DN D1.S16
+qDqntCoeff QN Q1.S32
+dDqntCoeff DN D2.S16
+
+
+ ;// Write function header
+ M_START omxVCM4P10_TransformDequantChromaDCFromPair, r9
+
+ LDR pSrc, [ppSrc] ;// Load pSrc
+ VMOV dZero, #0
+ MOV cstOffset, #31 ;// To be used in the loop, to compute offset
+
+ ;//-----------------------------------------------------------------------
+ ;// Firstly, fill all the coefficient values on the <pDst> buffer by zero
+ ;//-----------------------------------------------------------------------
+
+ VST1 dZero,[pDst] ;// pDst[0] = pDst[1] = pDst[2] = pDst[3] = 0
+ LDRB Flag, [pSrc], #1 ;// Preload <Flag> before <unpackLoop>
+
+
+unpackLoop
+ TST Flag, #0x10 ;// Computing (Flag & 0x10)
+ LDRSBNE Value2,[pSrc,#1]
+ LDRBNE Value, [pSrc], #2 ;// Load byte wise to avoid unaligned access
+ AND strOffset, cstOffset, Flag, LSL #1 ;// strOffset = (Flag & 15) < 1;
+ LDRSBEQ Value, [pSrc], #1 ;// Value = (OMX_U8) *pSrc++
+ ORRNE Value,Value,Value2, LSL #8 ;// Value = (OMX_U16) *pSrc++
+
+ TST Flag, #0x20 ;// Computing (Flag & 0x20) to check, if we're done
+ LDRBEQ Flag, [pSrc], #1 ;// Flag = (OMX_U8) *pSrc++, for next iteration
+ STRH Value, [pDst, strOffset] ;// Store <Value> at offset <strOffset>
+ BEQ unpackLoop ;// Branch to the loop beginning
+
+ ;//--------------------------------------------------
+ ;//InvTransformDC2x2: Inlined (Implemented in ARM V6)
+ ;//--------------------------------------------------
+
+ LDMIA pDst, {r0w0, r0w1} ;// r0w0 = |c1|c0| & r0w1 = |c3|c2|
+
+ STR pSrc, [ppSrc] ;// Update the bitstream pointer
+
+ LDR pQPDivTable, =armVCM4P10_QPDivTable ;// QP Division look-up-table base pointer
+ LDR pQPModTable, =armVCM4P10_VMatrixQPModTable ;// QP Modulo look-up-table base pointer
+
+ SADDSUBX r0w0, r0w0, r0w0 ;// [ c00+c01, c00-c01 ]
+ SADDSUBX r0w1, r0w1, r0w1 ;// [ c10+c11, c10-c11 ]
+
+ LDRSB Shift, [pQPDivTable, QP] ;// Shift = pQPDivTable[QP]
+ LDRSB Scale, [pQPModTable, QP] ;// Scale = pQPModTable[QP]
+
+ SADD16 c0w0, r0w0, r0w1 ;// [ d00+d10, d01+d11 ]
+ SSUB16 c1w0, r0w0, r0w1 ;// [ d00-d10, d01-d11 ]
+
+ ;//-------------------------------------------------
+ ;//DequantChromaDC2x2: Inlined (Neon Implementation)
+ ;//-------------------------------------------------
+
+ LSL Scale, Scale, Shift ;// Scale = Scale << Shift
+ VMOV dInvTrCoeff, c0w0, c1w0
+ VREV32 dInvTrCoeff,dInvTrCoeff
+ VDUP dScale,Scale
+
+ VMULL qDqntCoeff,dInvTrCoeff,dScale
+ VSHRN dDqntCoeff,qDqntCoeff,#1
+
+
+ VST1 dDqntCoeff,[pDst] ;// Storing all the coefficients at once
+
+ MOV return, #OMX_Sts_NoErr
+ M_END
+
+ ENDIF ;// CortexA8
+
+
+ END
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_TransformDequantLumaDCFromPair_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_TransformDequantLumaDCFromPair_s.s
new file mode 100755
index 0000000..2529959
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_TransformDequantLumaDCFromPair_s.s
@@ -0,0 +1,264 @@
+;//
+;//
+;// File Name: omxVCM4P10_TransformDequantLumaDCFromPair_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 12290
+;// Date: Wednesday, April 9, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+;// Description:
+;// H.264 inverse quantize and transform module
+;//
+;//
+
+;// Include standard headers
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+;// Import/Export symbols required from/to other files
+;// (For example tables)
+
+ IMPORT armVCM4P10_UnpackBlock4x4
+ IMPORT armVCM4P10_QPDivTable
+ IMPORT armVCM4P10_VMatrixQPModTable
+
+ M_VARIANTS CortexA8
+
+;// Set debugging level
+;//DEBUG_ON SETL {TRUE}
+
+
+;// Static Function: armVCM4P10_InvTransformDequantLumaDC4x4
+
+
+;// Guarding implementation by the processor name
+
+
+
+;// Static Function: armVCM4P10_InvTransformDequantLumaDC4x4
+
+;// Guarding implementation by the processor name
+
+ IF CortexA8
+
+;//Input Registers
+pData RN 0
+QP RN 1
+
+
+;//Local Scratch Registers
+
+;// ARM Registers
+
+pQPDivTable RN 2
+pQPModTable RN 3
+Shift RN 4
+Scale RN 5
+
+;// NEON Registers
+
+;// Packed Input pixels
+dIn0 DN D0.S16
+dIn1 DN D1.S16
+dIn2 DN D2.S16
+dIn3 DN D3.S16
+
+;// Intermediate calculations
+dRowSum1 DN D4.S16
+dRowSum2 DN D5.S16
+dRowDiff1 DN D6.S16
+dRowDiff2 DN D7.S16
+
+;// Row operated pixels
+dRowOp0 DN D0.S16
+dRowOp1 DN D1.S16
+dRowOp2 DN D2.S16
+dRowOp3 DN D3.S16
+qRowOp01 QN Q0.32
+qRowOp23 QN Q1.32
+
+;// Intermediate calculations
+dColSum1 DN D4.S16
+dColSum2 DN D5.S16
+dColDiff1 DN D6.S16
+dColDiff2 DN D7.S16
+
+;// Coloumn operated pixels
+dColOp0 DN D0.S16
+dColOp1 DN D1.S16
+dColOp2 DN D2.S16
+dColOp3 DN D3.S16
+
+;// Temporary scratch varaibles
+
+dScale DN D5.S16
+qRound0 QN Q3.S32
+qRound1 QN Q4.S32
+qRound2 QN Q5.S32
+qRound3 QN Q6.S32
+
+;// InvTransformed and Dequantized pixels
+dOut0 DN D0.S16
+dOut1 DN D1.S16
+dOut2 DN D2.S16
+dOut3 DN D3.S16
+
+
+ ;// Allocate stack memory required by the function
+
+
+ ;// Write function header
+ M_START armVCM4P10_InvTransformDequantLumaDC4x4,r5,d13
+
+ ;******************************************************************
+ ;// The strategy used in implementing the transform is as follows:*
+ ;// Load the 4x4 block into 4 D-registers *
+ ;// Transpose the 4x4 matrix *
+ ;// Perform the row operations (on columns) using SIMD *
+ ;// Transpose the 4x4 result matrix *
+ ;// Perform the coloumn operations *
+ ;******************************************************************
+
+ ;// Load all the 4x4 pixels in Transposed form
+
+ VLD4 {dIn0,dIn1,dIn2,dIn3},[pData]
+ LDR pQPDivTable, =armVCM4P10_QPDivTable ;// QP Division look-up-table base pointer
+ LDR pQPModTable, =armVCM4P10_VMatrixQPModTable ;// QP Modulo look-up-table base pointer
+
+ ;****************************************
+ ;// Row Operations (Performed on columns)
+ ;****************************************
+ ;// Scale factor calculation is done using ARM instructions
+ ;// Interleaved with NEON instructions inorder to Dual issue
+
+ VADD dRowSum1,dIn0,dIn1
+ VADD dRowSum2,dIn2,dIn3
+ VSUB dRowDiff1,dIn0,dIn1
+ LDRSB Shift, [pQPDivTable, QP] ;// ARM CODE: Shift = pQPDivTable[QP]
+ VSUB dRowDiff2,dIn2,dIn3
+ LDRSB Scale, [pQPModTable, QP] ;// ARM CODE: Scale = pQPModTable[QP]
+ VADD dRowOp0,dRowSum1,dRowSum2
+ VSUB dRowOp1,dRowSum1,dRowSum2
+ VSUB dRowOp2,dRowDiff1,dRowDiff2
+ LSL Scale, Scale, Shift ;// ARM CODE: Scale = Scale << Shift
+ VADD dRowOp3,dRowDiff1,dRowDiff2
+
+ ;****************************************
+ ;// Transpose the resultant matrix
+ ;****************************************
+
+ VTRN dRowOp0,dRowOp1
+ VTRN dRowOp2,dRowOp3
+ VTRN qRowOp01,qRowOp23
+
+ ;****************************************
+ ;// Coloumn Operations
+ ;****************************************
+
+ VADD dColSum1,dRowOp0,dRowOp1
+ VADD dColSum2,dRowOp2,dRowOp3
+ VSUB dColDiff1,dRowOp0,dRowOp1
+ VSUB dColDiff2,dRowOp2,dRowOp3
+ VADD dColOp0,dColSum1,dColSum2
+ VSUB dColOp1,dColSum1,dColSum2
+ VSUB dColOp2,dColDiff1,dColDiff2
+ VADD dColOp3,dColDiff1,dColDiff2
+
+ ;//----------------------------------------------------------------------
+ ;//
+ ;// <Dequantize> improves on the c-reference code
+ ;// Both the cases i.e., Shift>=0 and Shift<0 cases are covered together
+ ;// We do not subtract 2 from Shift as in C reference, instead perform a
+ ;// Scale << Shift once in the beginning and do a right shift by a
+ ;// constant 2 after the Multiplication. The value of Round would be 2
+ ;//
+ ;// By doing this we aviod the Branches required and also
+ ;// reduce the code size substantially
+ ;//
+ ;//----------------------------------------------------------------------
+
+
+ VDUP dScale, Scale ;// ARM -> NEON copy 'scale' to vector
+
+
+ VMOV qRound0,#2 ;// Set the Round Value
+ VMOV qRound1,#2
+ VMOV qRound2,#2
+ VMOV qRound3,#2
+
+ VMLAL qRound0,dColOp0,dScale ;// pDst[i] * Scale + Round
+ VMLAL qRound1,dColOp1,dScale
+ VMLAL qRound2,dColOp2,dScale
+ VMLAL qRound3,dColOp3,dScale
+
+ VSHRN dOut0,qRound0,#2 ;// Right shift by 2 & (OMX_S16)Value
+ VSHRN dOut1,qRound1,#2
+ VSHRN dOut2,qRound2,#2
+ VSHRN dOut3,qRound3,#2
+
+ ;***************************
+ ;// Store all the 4x4 pixels
+ ;***************************
+
+ VST1 {dOut0,dOut1,dOut2,dOut3}, [pData]
+
+
+ ;// Set return value
+
+ ;// Write function tail
+ M_END
+
+ ENDIF ;//CORTEXA8
+
+
+
+;// Function: omxVCM4P10_TransformDequantLumaDCFromPair
+
+;//Input Registers
+ppSrc RN 0
+pDst RN 1
+QPR2 RN 2
+
+;//Output Registers
+result RN 0
+
+;//Local Scratch Registers
+pDstR4 RN 4
+pDstR0 RN 0
+QPR1 RN 1
+QPR5 RN 5
+
+;// Guarding implementation by the processor name
+
+ IF CortexA8
+
+ ;// Allocate stack memory required by the function
+
+
+ ;// Write function header
+ M_START omxVCM4P10_TransformDequantLumaDCFromPair,r5
+
+ MOV pDstR4,pDst ;// Saving register r1
+ MOV QPR5,QPR2 ;// Saving register r2
+ BL armVCM4P10_UnpackBlock4x4
+
+ MOV pDstR0,pDstR4 ;// Setting up register r0
+ MOV QPR1,QPR5 ;// Setting up register r1
+ BL armVCM4P10_InvTransformDequantLumaDC4x4
+
+
+ ;// Set return value
+ MOV result,#OMX_Sts_NoErr
+
+ ;// Write function tail
+ M_END
+
+
+ ENDIF ;//ARM1136JS
+
+
+ END
\ No newline at end of file
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_Average_4x_Align_unsafe_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_Average_4x_Align_unsafe_s.S
new file mode 100644
index 0000000..aca2df4
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_Average_4x_Align_unsafe_s.S
@@ -0,0 +1,134 @@
+/*
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ */
+
+ .eabi_attribute 24, 1
+ .eabi_attribute 25, 1
+
+ .arm
+ .fpu neon
+ .text
+
+ .global armVCM4P10_Average_4x4_Align0_unsafe
+ .func armVCM4P10_Average_4x4_Align0_unsafe
+armVCM4P10_Average_4x4_Align0_unsafe:
+ PUSH {r4-r6,lr}
+ LDR r7, =0x80808080
+ LDR r12,[r2,#0]
+ LDR r10,[r0],r1
+ LDR lr,[r2,r3]
+ LDR r11,[r0],r1
+ MVN r12,r12
+ MVN lr,lr
+ UHSUB8 r5,r10,r12
+ UHSUB8 r4,r11,lr
+ EOR r5,r5,r7
+ STR r5,[r2],r3
+ EOR r4,r4,r7
+ STR r4,[r2],r3
+ LDR r10,[r0],r1
+ LDR r12,[r2,#0]
+ LDR r11,[r0],r1
+ LDR lr,[r2,r3]
+ MVN r12,r12
+ UHSUB8 r5,r10,r12
+ MVN lr,lr
+ UHSUB8 r4,r11,lr
+ EOR r5,r5,r7
+ STR r5,[r2],r3
+ EOR r4,r4,r7
+ STR r4,[r2],r3
+ POP {r4-r6,pc}
+ .endfunc
+
+ .global armVCM4P10_Average_4x4_Align2_unsafe
+ .func armVCM4P10_Average_4x4_Align2_unsafe
+armVCM4P10_Average_4x4_Align2_unsafe:
+ PUSH {r4-r6,lr}
+ LDR r7, =0x80808080
+ LDR r4,[r0,#4]
+ LDR r10,[r0],r1
+ LDR r12,[r2,#0]
+ LDR lr,[r2,r3]
+ LDR r5,[r0,#4]
+ LDR r11,[r0],r1
+ MVN r12,r12
+ MVN lr,lr
+ LSR r10,r10,#16
+ ORR r10,r10,r4,LSL #16
+ LSR r11,r11,#16
+ ORR r11,r11,r5,LSL #16
+ UHSUB8 r5,r10,r12
+ UHSUB8 r4,r11,lr
+ EOR r5,r5,r7
+ STR r5,[r2],r3
+ EOR r4,r4,r7
+ STR r4,[r2],r3
+ LDR r4,[r0,#4]
+ LDR r10,[r0],r1
+ LDR r12,[r2,#0]
+ LDR lr,[r2,r3]
+ LDR r5,[r0,#4]
+ LDR r11,[r0],r1
+ MVN r12,r12
+ MVN lr,lr
+ LSR r10,r10,#16
+ ORR r10,r10,r4,LSL #16
+ LSR r11,r11,#16
+ ORR r11,r11,r5,LSL #16
+ UHSUB8 r5,r10,r12
+ UHSUB8 r4,r11,lr
+ EOR r5,r5,r7
+ STR r5,[r2],r3
+ EOR r4,r4,r7
+ STR r4,[r2],r3
+ POP {r4-r6,pc}
+ .endfunc
+
+ .global armVCM4P10_Average_4x4_Align3_unsafe
+ .func armVCM4P10_Average_4x4_Align3_unsafe
+armVCM4P10_Average_4x4_Align3_unsafe:
+ PUSH {r4-r6,lr}
+ LDR r7, =0x80808080
+ LDR r4,[r0,#4]
+ LDR r10,[r0],r1
+ LDR r12,[r2,#0]
+ LDR lr,[r2,r3]
+ LDR r5,[r0,#4]
+ LDR r11,[r0],r1
+ MVN r12,r12
+ MVN lr,lr
+ LSR r10,r10,#24
+ ORR r10,r10,r4,LSL #8
+ LSR r11,r11,#24
+ ORR r11,r11,r5,LSL #8
+ UHSUB8 r5,r10,r12
+ UHSUB8 r4,r11,lr
+ EOR r5,r5,r7
+ STR r5,[r2],r3
+ EOR r4,r4,r7
+ STR r4,[r2],r3
+ LDR r4,[r0,#4]
+ LDR r10,[r0],r1
+ LDR r12,[r2,#0]
+ LDR lr,[r2,r3]
+ LDR r5,[r0,#4]
+ LDR r11,[r0],r1
+ MVN r12,r12
+ MVN lr,lr
+ LSR r10,r10,#24
+ ORR r10,r10,r4,LSL #8
+ LSR r11,r11,#24
+ ORR r11,r11,r5,LSL #8
+ UHSUB8 r5,r10,r12
+ UHSUB8 r4,r11,lr
+ EOR r5,r5,r7
+ STR r5,[r2],r3
+ EOR r4,r4,r7
+ STR r4,[r2],r3
+ POP {r4-r6,pc}
+ .endfunc
+
+ .end
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DeblockingChroma_unsafe_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DeblockingChroma_unsafe_s.S
new file mode 100644
index 0000000..b9ee221
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DeblockingChroma_unsafe_s.S
@@ -0,0 +1,54 @@
+/*
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ */
+
+ .eabi_attribute 24, 1
+ .eabi_attribute 25, 1
+
+ .arm
+ .fpu neon
+ .text
+
+ .global armVCM4P10_DeblockingChromabSLT4_unsafe
+ .func armVCM4P10_DeblockingChromabSLT4_unsafe
+armVCM4P10_DeblockingChromabSLT4_unsafe:
+ VLD1.32 {d18[0]},[r5]!
+ VSUBL.U8 q11,d5,d9
+ VMOV d28,d18
+ VSUBL.U8 q10,d8,d4
+ VSHR.S16 q11,q11,#2
+ VZIP.8 d18,d28
+ VBIF d18,d14,d16
+ VRHADD.S16 q10,q11,q10
+ VADD.I8 d31,d18,d15
+ VQMOVN.S16 d20,q10
+ VLD1.8 {d0[]},[r2]
+ VMIN.S8 d20,d20,d31
+ VNEG.S8 d31,d31
+ VLD1.8 {d2[]},[r3]
+ VMAX.S8 d20,d20,d31
+ VMOVL.U8 q14,d4
+ VMOVL.U8 q12,d8
+ VADDW.S8 q14,q14,d20
+ VSUBW.S8 q12,q12,d20
+ VQMOVUN.S16 d29,q14
+ VQMOVUN.S16 d24,q12
+ BX lr
+ .endfunc
+
+ .global armVCM4P10_DeblockingChromabSGE4_unsafe
+ .func armVCM4P10_DeblockingChromabSGE4_unsafe
+armVCM4P10_DeblockingChromabSGE4_unsafe:
+ VHADD.U8 d13,d4,d9
+ VHADD.U8 d31,d8,d5
+ VLD1.8 {d0[]},[r2]
+ ADD r5,r5,#4
+ VLD1.8 {d2[]},[r3]
+ VRHADD.U8 d13,d13,d5
+ VRHADD.U8 d31,d31,d9
+ BX lr
+ .endfunc
+
+ .end
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DeblockingLuma_unsafe_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DeblockingLuma_unsafe_s.S
new file mode 100644
index 0000000..47f3d44
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DeblockingLuma_unsafe_s.S
@@ -0,0 +1,102 @@
+/*
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ */
+
+ .eabi_attribute 24, 1
+ .eabi_attribute 25, 1
+
+ .arm
+ .fpu neon
+ .text
+
+ .global armVCM4P10_DeblockingLumabSLT4_unsafe
+ .func armVCM4P10_DeblockingLumabSLT4_unsafe
+armVCM4P10_DeblockingLumabSLT4_unsafe:
+ VSUBL.U8 q11,d5,d9
+ VLD1.8 {d18[]},[r5]!
+ VSUBL.U8 q10,d8,d4
+ VLD1.8 {d19[]},[r5]!
+ VSHR.S16 q11,q11,#2
+ VEXT.8 d18,d18,d19,#4
+ VAND d19,d17,d15
+ VBIF d18,d14,d16
+ VRHADD.S16 q10,q11,q10
+ VRHADD.U8 d24,d4,d8
+ VADD.I8 d31,d18,d19
+ VAND d19,d12,d15
+ VQADD.U8 d23,d5,d18
+ VQMOVN.S16 d20,q10
+ VADD.I8 d31,d31,d19
+ VQSUB.U8 d22,d5,d18
+ VQADD.U8 d19,d9,d18
+ VHADD.U8 d26,d24,d6
+ VMIN.S8 d20,d20,d31
+ VNEG.S8 d31,d31
+ VQSUB.U8 d21,d9,d18
+ VHADD.U8 d27,d24,d10
+ VMAX.U8 d30,d26,d22
+ VMAX.S8 d20,d20,d31
+ VMOVL.U8 q14,d4
+ VMOVL.U8 q12,d8
+ VADDW.S8 q14,q14,d20
+ VSUBW.S8 q12,q12,d20
+ VQMOVUN.S16 d29,q14
+ VQMOVUN.S16 d24,q12
+ VMAX.U8 d25,d27,d21
+ VMIN.U8 d30,d30,d23
+ VMIN.U8 d25,d25,d19
+ VBIF d29,d4,d16
+ VBIF d30,d5,d17
+ VBIF d24,d8,d16
+ VBIF d25,d9,d12
+ BX lr
+ .endfunc
+
+ .global armVCM4P10_DeblockingLumabSGE4_unsafe
+ .func armVCM4P10_DeblockingLumabSGE4_unsafe
+armVCM4P10_DeblockingLumabSGE4_unsafe:
+ VSHR.U8 d19,d0,#2
+ VADD.I8 d19,d19,d15
+ VADDL.U8 q10,d8,d4
+ VADD.I8 d19,d19,d15
+ VADDL.U8 q11,d6,d9
+ VADDW.U8 q12,q10,d5
+ VCGT.U8 d19,d19,d13
+ VSHR.U16 q11,q11,#1
+ VHADD.U16 q11,q12,q11
+ VADDW.U8 q12,q12,d6
+ VADDL.U8 q13,d7,d6
+ VAND d17,d17,d19
+ VHADD.U8 d28,d4,d9
+ VSRA.U16 q13,q12,#1
+ VAND d12,d12,d19
+ VQRSHRN.U16 d29,q11,#1
+ VRHADD.U8 d28,d28,d5
+ VQRSHRN.U16 d30,q12,#2
+ VADDL.U8 q11,d10,d5
+ VADDW.U8 q12,q10,d9
+ VBIF d29,d28,d17
+ VQRSHRN.U16 d31,q13,#2
+ VADDL.U8 q13,d11,d10
+ VSHR.U16 q11,q11,#1
+ VHADD.U16 q11,q12,q11
+ VADDW.U8 q12,q12,d10
+ VHADD.U8 d28,d8,d5
+ VBIF d29,d4,d16
+ VBIF d30,d5,d17
+ VSRA.U16 q13,q12,#1
+ VQRSHRN.U16 d25,q12,#2
+ VQRSHRN.U16 d24,q11,#1
+ VRHADD.U8 d22,d28,d9
+ VBIF d25,d9,d12
+ VBIF d31,d6,d17
+ VBIF d24,d22,d12
+ VQRSHRN.U16 d28,q13,#2
+ VBIF d24,d8,d16
+ VBIF d28,d10,d12
+ BX lr
+ .endfunc
+
+ .end
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DecodeCoeffsToPair_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DecodeCoeffsToPair_s.S
new file mode 100644
index 0000000..e68bd8e
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DecodeCoeffsToPair_s.S
@@ -0,0 +1,272 @@
+/*
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ */
+
+ .eabi_attribute 24, 1
+ .eabi_attribute 25, 1
+
+ .arm
+ .fpu neon
+ .text
+
+ .global armVCM4P10_DecodeCoeffsToPair
+ .func armVCM4P10_DecodeCoeffsToPair
+armVCM4P10_DecodeCoeffsToPair:
+ PUSH {r4-r12,lr}
+ SUB sp,sp,#0x40
+ LDR r10,[r0,#0]
+ LDR r12,[r1,#0]
+ LDR r6, =armVCM4P10_CAVLCCoeffTokenTables
+ LDR r4,[sp,#0x68]
+ LDRB r9,[r10,#2]
+ LDRB r8,[r10,#1]
+ LDRB r11,[r10],#3
+ ADD r12,r12,#8
+ LDR r6,[r6,r4,LSL #2]
+ ORR r9,r9,r8,LSL #8
+ ORR r11,r9,r11,LSL #16
+ LSLS r8,r11,r12
+ MOVS r7,#0x1e
+ AND r7,r7,r8,LSR #27
+ SUBS r12,r12,#8
+L0x44:
+ BCC L1
+ LDRB r8,[r10],#1
+L1:
+ LDRH r7,[r6,r7]
+ ADDCC r12,r12,#8
+ ADD r12,r12,#4
+ ORRCS r11,r8,r11,LSL #8
+ LSRS r8,r7,#1
+ BCS L0x74
+ LSLS r8,r11,r12
+ SUBS r12,r12,#0xa
+ ADD r7,r7,r8,LSR #29
+ BIC r7,r7,#1
+ B L0x44
+L0x74:
+ SUB r12,r12,r7,LSR #13
+ BIC r7,r8,#0xf000
+ LSRS r5,r7,#2
+ STRB r5,[r2,#0]
+ BEQ L0x344
+ CMP r7,#0x44
+ BGE L0x33c
+ STR r0,[sp,#0]
+ STR r1,[sp,#4]
+ STR r3,[sp,#8]
+ ANDS r1,r7,#3
+ ADD r2,sp,#0xc
+ BEQ L0xd8
+ MOV r0,r1
+L0xac:
+ LSLS r7,r11,r12
+ SUBS r12,r12,#7
+ BCC L2
+ LDRB r8,[r10],#1
+L2:
+ ADDCC r12,r12,#8
+ LSR r7,r7,#31
+ ORRCS r11,r8,r11,LSL #8
+ SUBS r0,r0,#1
+ MOV r8,#1
+ SUB r8,r8,r7,LSL #1
+ STRH r8,[r2],#2
+ BGT L0xac
+L0xd8:
+ SUBS r0,r5,r1
+ BEQ L0x1b8
+ MOV r4,#1
+ CMP r5,#0xa
+ MOVLE r4,#0
+ CMP r1,#3
+ MOVLT r1,#4
+ MOVGE r1,#2
+ MOVGE r4,#0
+L0xfc:
+ LSLS r7,r11,r12
+ CLZ r7,r7
+ ADD r12,r12,r7
+ SUBS r12,r12,#7
+ BCC L3
+ LDRB r8,[r10],#1
+ ORR r11,r8,r11,LSL #8
+ SUBS r12,r12,#8
+ BCC L3
+ LDRB r8,[r10],#1
+L3:
+ ADDCC r12,r12,#8
+ ORRCS r11,r8,r11,LSL #8
+ CMP r7,#0x10
+ BGE L0x33c
+ MOVS lr,r4
+ TEQEQ r7,#0xe
+ MOVEQ lr,#4
+ TEQ r7,#0xf
+ MOVEQ lr,#0xc
+ TEQEQ r4,#0
+ ADDEQ r7,r7,#0xf
+ TEQ lr,#0
+ BEQ L0x184
+ LSL r3,r11,r12
+ ADD r12,r12,lr
+ SUBS r12,r12,#8
+ RSB r9,lr,#0x20
+ BCC L4
+ LDRB r8,[r10],#1
+ ORR r11,r8,r11,LSL #8
+ SUBS r12,r12,#8
+ BCC L4
+ LDRB r8,[r10],#1
+L4:
+ ADDCC r12,r12,#8
+ LSR r3,r3,r9
+ ORRCS r11,r8,r11,LSL #8
+ LSL r7,r7,r4
+ ADD r7,r3,r7
+L0x184:
+ ADD r7,r7,r1
+ MOV r1,#2
+ LSRS r8,r7,#1
+ RSBCS r8,r8,#0
+ STRH r8,[r2],#2
+ LDR r9, =armVCM4P10_SuffixToLevel
+ LDRSB r8,[r9,r4]
+ TEQ r4,#0
+ MOVEQ r4,#1
+ CMP r7,r8
+ ADDCS r4,r4,#1
+ SUBS r0,r0,#1
+ BGT L0xfc
+L0x1b8:
+ LDR r8,[sp,#0x6c]
+ SUB r0,r5,#1
+ SUBS r1,r8,r5
+ ADD r4,sp,#0x2c
+ MOV lr,r5
+ SUB lr,lr,#1
+ BEQ L0x2b0
+ TEQ r8,#4
+ LDREQ r6, =(armVCM4P10_CAVLCTotalZeros2x2Tables - 4)
+ LDRNE r6, =(armVCM4P10_CAVLCTotalZeroTables - 4)
+ LDR r6,[r6,r5,LSL #2]
+ LSLS r8,r11,r12
+ MOVS r7,#0x1e
+ AND r7,r7,r8,LSR #27
+ SUBS r12,r12,#8
+L0x1f4:
+ BCC L5
+ LDRB r8,[r10],#1
+L5:
+ LDRH r7,[r6,r7]
+ ADDCC r12,r12,#8
+ ADD r12,r12,#4
+ ORRCS r11,r8,r11,LSL #8
+ LSRS r8,r7,#1
+ BCS L0x224
+ LSLS r8,r11,r12
+ SUBS r12,r12,#0xa
+ ADD r7,r7,r8,LSR #29
+ BIC r7,r7,#1
+ B L0x1f4
+L0x224:
+ SUB r12,r12,r7,LSR #13
+ BIC r7,r8,#0xf000
+ CMP r7,#0x10
+ BGE L0x33c
+ LDR r3, =(armVCM4P10_CAVLCRunBeforeTables - 4)
+ ADD r4,sp,#0x2c
+ MOVS r1,r7
+ ADD lr,lr,r1
+ BEQ L0x2b0
+L0x248:
+ SUBS r0,r0,#1
+ LDR r6,[r3,r1,LSL #2]
+ BLT L0x2bc
+ LSLS r8,r11,r12
+ MOVS r7,#0xe
+ AND r7,r7,r8,LSR #28
+ SUBS r12,r12,#8
+L0x264:
+ BCC L6
+ LDRB r8,[r10],#1
+L6:
+ LDRH r7,[r6,r7]
+ ADDCC r12,r12,#8
+ ADD r12,r12,#3
+ ORRCS r11,r8,r11,LSL #8
+ LSRS r8,r7,#1
+ BCS L0x294
+ LSLS r8,r11,r12
+ SUBS r12,r12,#9
+ ADD r7,r7,r8,LSR #29
+ BIC r7,r7,#1
+ B L0x264
+L0x294:
+ SUB r12,r12,r7,LSR #13
+ BIC r7,r8,#0xf000
+ CMP r7,#0xf
+ BGE L0x33c
+ SUBS r1,r1,r7
+ STRB r7,[r4],#1
+ BGT L0x248
+L0x2b0:
+ SUBS r0,r0,#1
+ BLT L7
+ STRB r1,[r4],#1
+L7:
+ BGT L0x2b0
+L0x2bc:
+ STRB r1,[r4],#1
+ LDR r8,[sp,#0x6c]
+ TEQ r8,#0xf
+ ADDEQ lr,lr,#1
+ SUB r4,r4,r5
+ SUB r2,r2,r5
+ SUB r2,r2,r5
+ LDR r3,[sp,#8]
+ LDR r0,[r3,#0]
+ TEQ r8,#4
+ LDREQ r6, =armVCM4P10_ZigZag_2x2
+ LDRNE r6, =armVCM4P10_ZigZag_4x4
+L0x2ec:
+ LDRB r9,[r4],#1
+ LDRB r8,[r6,lr]
+ SUB lr,lr,#1
+ SUB lr,lr,r9
+ LDRSH r9,[r2],#2
+ SUBS r5,r5,#1
+ ORREQ r8,r8,#0x20
+ ADD r1,r9,#0x80
+ CMP r1,#0x100
+ ORRCS r8,r8,#0x10
+ TEQ r5,#0
+ STRB r8,[r0],#1
+ STRB r9,[r0],#1
+ LSR r9,r9,#8
+ BCC L8
+ STRB r9,[r0],#1
+L8:
+ BNE L0x2ec
+ STR r0,[r3,#0]
+ LDR r0,[sp,#0]
+ LDR r1,[sp,#4]
+ B L0x344
+L0x33c:
+ MVN r0,#1
+ B L0x35c
+L0x344:
+ ADD r10,r10,r12,LSR #3
+ AND r12,r12,#7
+ SUB r10,r10,#4
+ STR r12,[r1,#0]
+ STR r10,[r0,#0]
+ MOV r0,#0
+L0x35c:
+ ADD sp,sp,#0x40
+ POP {r4-r12,pc}
+ .endfunc
+
+ .end
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DequantTables_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DequantTables_s.S
new file mode 100644
index 0000000..44eb428
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DequantTables_s.S
@@ -0,0 +1,103 @@
+/*
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ */
+
+ .eabi_attribute 24, 1
+ .eabi_attribute 25, 1
+
+ .arm
+ .fpu neon
+ .section .rodata
+ .align 4
+
+
+ .global armVCM4P10_QPDivTable
+ .global armVCM4P10_VMatrixQPModTable
+ .global armVCM4P10_PosToVCol4x4
+ .global armVCM4P10_PosToVCol2x2
+ .global armVCM4P10_VMatrix
+ .global armVCM4P10_QPModuloTable
+ .global armVCM4P10_VMatrixU16
+
+armVCM4P10_PosToVCol4x4:
+ .byte 0, 2, 0, 2
+ .byte 2, 1, 2, 1
+ .byte 0, 2, 0, 2
+ .byte 2, 1, 2, 1
+
+armVCM4P10_PosToVCol2x2:
+ .byte 0, 2
+ .byte 2, 1
+
+armVCM4P10_VMatrix:
+ .byte 10, 16, 13
+ .byte 11, 18, 14
+ .byte 13, 20, 16
+ .byte 14, 23, 18
+ .byte 16, 25, 20
+ .byte 18, 29, 23
+
+;//-------------------------------------------------------
+;// This table evaluates the expression [(INT)(QP/6)],
+;// for values of QP from 0 to 51 (inclusive).
+;//-------------------------------------------------------
+
+armVCM4P10_QPDivTable:
+ .byte 0, 0, 0, 0, 0, 0
+ .byte 1, 1, 1, 1, 1, 1
+ .byte 2, 2, 2, 2, 2, 2
+ .byte 3, 3, 3, 3, 3, 3
+ .byte 4, 4, 4, 4, 4, 4
+ .byte 5, 5, 5, 5, 5, 5
+ .byte 6, 6, 6, 6, 6, 6
+ .byte 7, 7, 7, 7, 7, 7
+ .byte 8, 8, 8, 8, 8, 8
+
+;//----------------------------------------------------
+;// This table contains armVCM4P10_VMatrix[QP%6][0] entires,
+;// for values of QP from 0 to 51 (inclusive).
+;//----------------------------------------------------
+
+armVCM4P10_VMatrixQPModTable:
+ .byte 10, 11, 13, 14, 16, 18
+ .byte 10, 11, 13, 14, 16, 18
+ .byte 10, 11, 13, 14, 16, 18
+ .byte 10, 11, 13, 14, 16, 18
+ .byte 10, 11, 13, 14, 16, 18
+ .byte 10, 11, 13, 14, 16, 18
+ .byte 10, 11, 13, 14, 16, 18
+ .byte 10, 11, 13, 14, 16, 18
+ .byte 10, 11, 13, 14, 16, 18
+
+;//-------------------------------------------------------
+;// This table evaluates the modulus expression [QP%6]*6,
+;// for values of QP from 0 to 51 (inclusive).
+;//-------------------------------------------------------
+
+armVCM4P10_QPModuloTable:
+ .byte 0, 6, 12, 18, 24, 30
+ .byte 0, 6, 12, 18, 24, 30
+ .byte 0, 6, 12, 18, 24, 30
+ .byte 0, 6, 12, 18, 24, 30
+ .byte 0, 6, 12, 18, 24, 30
+ .byte 0, 6, 12, 18, 24, 30
+ .byte 0, 6, 12, 18, 24, 30
+ .byte 0, 6, 12, 18, 24, 30
+ .byte 0, 6, 12, 18, 24, 30
+
+;//-------------------------------------------------------
+;// This table contains the invidual byte values stored as
+;// halfwords. This avoids unpacking inside the function
+;//-------------------------------------------------------
+
+armVCM4P10_VMatrixU16:
+ .hword 10, 16, 13
+ .hword 11, 18, 14
+ .hword 13, 20, 16
+ .hword 14, 23, 18
+ .hword 16, 25, 20
+ .hword 18, 29, 23
+
+ .end
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_Align_unsafe_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_Align_unsafe_s.S
new file mode 100644
index 0000000..37bc69b
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_Align_unsafe_s.S
@@ -0,0 +1,123 @@
+/*
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ */
+
+ .eabi_attribute 24, 1
+ .eabi_attribute 25, 1
+
+ .arm
+ .fpu neon
+ .text
+
+ .global armVCM4P10_InterpolateLuma_HorAlign9x_unsafe
+ .func armVCM4P10_InterpolateLuma_HorAlign9x_unsafe
+armVCM4P10_InterpolateLuma_HorAlign9x_unsafe:
+ MOV r12,r8
+ AND r7,r0,#3
+ BIC r0,r0,#3
+ ADD pc,pc,r7,LSL #2
+ NOP
+ B Copy0toAligned
+ B Copy1toAligned
+ B Copy2toAligned
+ B Copy3toAligned
+Copy0toAligned:
+ LDM r0,{r7,r10,r11}
+ SUBS r9,r9,#1
+ ADD r0,r0,r1
+ STM r8!,{r7,r10,r11}
+ BGT Copy0toAligned
+ B CopyEnd
+Copy1toAligned:
+ LDM r0,{r7,r10,r11}
+ SUBS r9,r9,#1
+ ADD r0,r0,r1
+ LSR r7,r7,#8
+ ORR r7,r7,r10,LSL #24
+ LSR r10,r10,#8
+ ORR r10,r10,r11,LSL #24
+ LSR r11,r11,#8
+ STM r8!,{r7,r10,r11}
+ BGT Copy1toAligned
+ B CopyEnd
+Copy2toAligned:
+ LDM r0,{r7,r10,r11}
+ SUBS r9,r9,#1
+ ADD r0,r0,r1
+ LSR r7,r7,#16
+ ORR r7,r7,r10,LSL #16
+ LSR r10,r10,#16
+ ORR r10,r10,r11,LSL #16
+ LSR r11,r11,#16
+ STM r8!,{r7,r10,r11}
+ BGT Copy2toAligned
+ B CopyEnd
+Copy3toAligned:
+ LDM r0,{r7,r10,r11}
+ SUBS r9,r9,#1
+ ADD r0,r0,r1
+ LSR r7,r7,#24
+ ORR r7,r7,r10,LSL #8
+ LSR r10,r10,#24
+ ORR r10,r10,r11,LSL #8
+ LSR r11,r11,#24
+ STM r8!,{r7,r10,r11}
+ BGT Copy3toAligned
+CopyEnd:
+ MOV r0,r12
+ MOV r1,#0xc
+ BX lr
+ .endfunc
+
+ .global armVCM4P10_InterpolateLuma_VerAlign4x_unsafe
+ .func armVCM4P10_InterpolateLuma_VerAlign4x_unsafe
+armVCM4P10_InterpolateLuma_VerAlign4x_unsafe:
+ AND r7,r0,#3
+ BIC r0,r0,#3
+ ADD pc,pc,r7,LSL #2
+ NOP
+ B Copy0toVAligned
+ B Copy1toVAligned
+ B Copy2toVAligned
+ B Copy3toVAligned
+Copy0toVAligned:
+ LDR r7,[r0],r1
+ SUBS r9,r9,#1
+ STR r7,[r8],#4
+ BGT Copy0toVAligned
+ B CopyVEnd
+Copy1toVAligned:
+ LDR r10,[r0,#4]
+ LDR r7,[r0],r1
+ SUBS r9,r9,#1
+ LSL r10,r10,#24
+ ORR r7,r10,r7,LSR #8
+ STR r7,[r8],#4
+ BGT Copy1toVAligned
+ B CopyVEnd
+Copy2toVAligned:
+ LDR r10,[r0,#4]
+ LDR r7,[r0],r1
+ SUBS r9,r9,#1
+ LSL r10,r10,#16
+ ORR r7,r10,r7,LSR #16
+ STR r7,[r8],#4
+ BGT Copy2toVAligned
+ B CopyVEnd
+Copy3toVAligned:
+ LDR r10,[r0,#4]
+ LDR r7,[r0],r1
+ SUBS r9,r9,#1
+ LSL r10,r10,#8
+ ORR r7,r10,r7,LSR #24
+ STR r7,[r8],#4
+ BGT Copy3toVAligned
+CopyVEnd:
+ SUB r0,r8,#0x1c
+ MOV r1,#4
+ BX lr
+ .endfunc
+
+ .end
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_Copy_unsafe_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_Copy_unsafe_s.S
new file mode 100644
index 0000000..fe92201
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_Copy_unsafe_s.S
@@ -0,0 +1,105 @@
+/*
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ */
+
+ .eabi_attribute 24, 1
+ .eabi_attribute 25, 1
+
+ .arm
+ .fpu neon
+ .text
+
+ .global armVCM4P10_InterpolateLuma_Copy4x4_unsafe
+ .func armVCM4P10_InterpolateLuma_Copy4x4_unsafe
+armVCM4P10_InterpolateLuma_Copy4x4_unsafe:
+ PUSH {r4-r6,lr}
+ AND r12,r0,#3
+ BIC r0,r0,#3
+ ADD pc,pc,r12,LSL #2
+ NOP
+ B Copy4x4Align0
+ B Copy4x4Align1
+ B Copy4x4Align2
+ B Copy4x4Align3
+Copy4x4Align0:
+ LDR r4,[r0],r1
+ LDR r5,[r0],r1
+ STR r4,[r2],r3
+ LDR r8,[r0],r1
+ STR r5,[r2],r3
+ LDR r9,[r0],r1
+ STR r8,[r2],r3
+ STR r9,[r2],r3
+ B Copy4x4End
+Copy4x4Align1:
+ LDR r5,[r0,#4]
+ LDR r4,[r0],r1
+ LDR r9,[r0,#4]
+ LDR r8,[r0],r1
+ LSR r4,r4,#8
+ ORR r4,r4,r5,LSL #24
+ STR r4,[r2],r3
+ LSR r8,r8,#8
+ ORR r8,r8,r9,LSL #24
+ LDR r5,[r0,#4]
+ LDR r4,[r0],r1
+ STR r8,[r2],r3
+ LDR r9,[r0,#4]
+ LDR r8,[r0],r1
+ LSR r4,r4,#8
+ ORR r4,r4,r5,LSL #24
+ STR r4,[r2],r3
+ LSR r8,r8,#8
+ ORR r8,r8,r9,LSL #24
+ STR r8,[r2],r3
+ B Copy4x4End
+Copy4x4Align2:
+ LDR r5,[r0,#4]
+ LDR r4,[r0],r1
+ LDR r9,[r0,#4]
+ LDR r8,[r0],r1
+ LSR r4,r4,#16
+ ORR r4,r4,r5,LSL #16
+ STR r4,[r2],r3
+ LSR r8,r8,#16
+ ORR r8,r8,r9,LSL #16
+ STR r8,[r2],r3
+ LDR r5,[r0,#4]
+ LDR r4,[r0],r1
+ LDR r9,[r0,#4]
+ LDR r8,[r0],r1
+ LSR r4,r4,#16
+ ORR r4,r4,r5,LSL #16
+ STR r4,[r2],r3
+ LSR r8,r8,#16
+ ORR r8,r8,r9,LSL #16
+ STR r8,[r2],r3
+ B Copy4x4End
+Copy4x4Align3:
+ LDR r5,[r0,#4]
+ LDR r4,[r0],r1
+ LDR r9,[r0,#4]
+ LDR r8,[r0],r1
+ LSR r4,r4,#24
+ ORR r4,r4,r5,LSL #8
+ STR r4,[r2],r3
+ LSR r8,r8,#24
+ ORR r8,r8,r9,LSL #8
+ STR r8,[r2],r3
+ LDR r5,[r0,#4]
+ LDR r4,[r0],r1
+ LDR r9,[r0,#4]
+ LDR r8,[r0],r1
+ LSR r4,r4,#24
+ ORR r4,r4,r5,LSL #8
+ STR r4,[r2],r3
+ LSR r8,r8,#24
+ ORR r8,r8,r9,LSL #8
+ STR r8,[r2],r3
+Copy4x4End:
+ POP {r4-r6,pc}
+ .endfunc
+
+ .end
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_DiagCopy_unsafe_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_DiagCopy_unsafe_s.S
new file mode 100644
index 0000000..544abe8
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_DiagCopy_unsafe_s.S
@@ -0,0 +1,107 @@
+/*
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ */
+
+ .eabi_attribute 24, 1
+ .eabi_attribute 25, 1
+
+ .arm
+ .fpu neon
+ .text
+
+ .global armVCM4P10_InterpolateLuma_HorDiagCopy_unsafe
+ .func armVCM4P10_InterpolateLuma_HorDiagCopy_unsafe
+armVCM4P10_InterpolateLuma_HorDiagCopy_unsafe:
+ PUSH {r4-r6,lr}
+ MOV lr,#4
+ LDR r6, =0xfe00fe0
+ LDR r12, =0xff00ff
+LoopStart1:
+ LDR r11,[r0,#0xc]
+ LDR r10,[r0,#8]
+ LDR r5,[r0,#4]
+ LDR r4,[r0],r1
+ UQSUB16 r11,r11,r6
+ UQSUB16 r10,r10,r6
+ UQSUB16 r5,r5,r6
+ UQSUB16 r4,r4,r6
+ USAT16 r11,#13,r11
+ USAT16 r10,#13,r10
+ USAT16 r5,#13,r5
+ USAT16 r4,#13,r4
+ AND r11,r12,r11,LSR #5
+ AND r10,r12,r10,LSR #5
+ AND r5,r12,r5,LSR #5
+ AND r4,r12,r4,LSR #5
+ ORR r11,r10,r11,LSL #8
+ ORR r10,r4,r5,LSL #8
+ SUBS lr,lr,#1
+ STRD r10,r11,[r7],#8
+ BGT LoopStart1
+ SUB r0,r7,#0x20
+ MOV r1,#8
+ POP {r4-r6,pc}
+ .endfunc
+
+ .global armVCM4P10_InterpolateLuma_VerDiagCopy_unsafe
+ .func armVCM4P10_InterpolateLuma_VerDiagCopy_unsafe
+armVCM4P10_InterpolateLuma_VerDiagCopy_unsafe:
+ PUSH {r4-r6,lr}
+ LDR r6, =0xfe00fe0
+ LDR r12, =0xff00ff
+ MOV lr,#2
+LoopStart:
+ LDR r11,[r0,#0xc]
+ LDR r10,[r0,#8]
+ LDR r5,[r0,#4]
+ LDR r4,[r0],r1
+ UQSUB16 r11,r11,r6
+ UQSUB16 r10,r10,r6
+ UQSUB16 r5,r5,r6
+ UQSUB16 r4,r4,r6
+ USAT16 r11,#13,r11
+ USAT16 r10,#13,r10
+ USAT16 r5,#13,r5
+ USAT16 r4,#13,r4
+ AND r11,r12,r11,LSR #5
+ AND r10,r12,r10,LSR #5
+ AND r5,r12,r5,LSR #5
+ AND r4,r12,r4,LSR #5
+ ORR r11,r10,r11,LSL #8
+ ORR r10,r4,r5,LSL #8
+ PKHBT r4,r10,r11,LSL #16
+ STR r4,[r7],#8
+ PKHTB r5,r11,r10,ASR #16
+ STR r5,[r7],#-4
+ LDR r11,[r0,#0xc]
+ LDR r10,[r0,#8]
+ LDR r5,[r0,#4]
+ LDR r4,[r0],r1
+ UQSUB16 r11,r11,r6
+ UQSUB16 r10,r10,r6
+ UQSUB16 r5,r5,r6
+ UQSUB16 r4,r4,r6
+ USAT16 r11,#13,r11
+ USAT16 r10,#13,r10
+ USAT16 r5,#13,r5
+ USAT16 r4,#13,r4
+ AND r11,r12,r11,LSR #5
+ AND r10,r12,r10,LSR #5
+ AND r5,r12,r5,LSR #5
+ AND r4,r12,r4,LSR #5
+ ORR r11,r10,r11,LSL #8
+ ORR r10,r4,r5,LSL #8
+ PKHBT r4,r10,r11,LSL #16
+ SUBS lr,lr,#1
+ STR r4,[r7],#8
+ PKHTB r5,r11,r10,ASR #16
+ STR r5,[r7],#4
+ BGT LoopStart
+ SUB r0,r7,#0x18
+ MOV r1,#4
+ POP {r4-r6,pc}
+ .endfunc
+
+ .end
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe_s.S
new file mode 100644
index 0000000..a330972
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe_s.S
@@ -0,0 +1,164 @@
+/*
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ */
+
+ .eabi_attribute 24, 1
+ .eabi_attribute 25, 1
+
+ .arm
+ .fpu neon
+ .text
+
+ .global armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe
+ .func armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe
+armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe:
+ PUSH {r4-r12,lr}
+ VLD1.8 {d0,d1},[r0],r1
+ VMOV.I16 d31,#0x14
+ VMOV.I16 d30,#0x5
+ VEXT.8 d4,d0,d1,#1
+ VEXT.8 d2,d0,d1,#2
+ VEXT.8 d3,d0,d1,#3
+ VEXT.8 d5,d0,d1,#4
+ VEXT.8 d1,d0,d1,#5
+ VADDL.U8 q1,d2,d3
+ VADDL.U8 q2,d4,d5
+ VADDL.U8 q5,d0,d1
+ VLD1.8 {d0,d1},[r0],r1
+ VMLA.I16 d10,d2,d31
+ VMUL.I16 d8,d4,d30
+ VEXT.8 d4,d0,d1,#1
+ VEXT.8 d2,d0,d1,#2
+ VEXT.8 d3,d0,d1,#3
+ VEXT.8 d5,d0,d1,#4
+ VEXT.8 d1,d0,d1,#5
+ VADDL.U8 q1,d2,d3
+ VADDL.U8 q2,d4,d5
+ VADDL.U8 q6,d0,d1
+ VLD1.8 {d0,d1},[r0],r1
+ VSUB.I16 d10,d10,d8
+ VMLA.I16 d12,d2,d31
+ VMUL.I16 d8,d4,d30
+ VEXT.8 d4,d0,d1,#1
+ VEXT.8 d2,d0,d1,#2
+ VEXT.8 d3,d0,d1,#3
+ VEXT.8 d5,d0,d1,#4
+ VEXT.8 d1,d0,d1,#5
+ VADDL.U8 q1,d2,d3
+ VADDL.U8 q2,d4,d5
+ VADDL.U8 q7,d0,d1
+ VLD1.8 {d0,d1},[r0],r1
+ VSUB.I16 d12,d12,d8
+ VMLA.I16 d14,d2,d31
+ VMUL.I16 d8,d4,d30
+ VEXT.8 d4,d0,d1,#1
+ VEXT.8 d2,d0,d1,#2
+ VEXT.8 d3,d0,d1,#3
+ VEXT.8 d5,d0,d1,#4
+ VEXT.8 d1,d0,d1,#5
+ VADDL.U8 q1,d2,d3
+ VADDL.U8 q2,d4,d5
+ VADDL.U8 q8,d0,d1
+ VLD1.8 {d0,d1},[r0],r1
+ VSUB.I16 d14,d14,d8
+ VMLA.I16 d16,d2,d31
+ VMUL.I16 d8,d4,d30
+ VEXT.8 d4,d0,d1,#1
+ VEXT.8 d2,d0,d1,#2
+ VEXT.8 d3,d0,d1,#3
+ VEXT.8 d5,d0,d1,#4
+ VEXT.8 d1,d0,d1,#5
+ VADDL.U8 q1,d2,d3
+ VADDL.U8 q2,d4,d5
+ VADDL.U8 q9,d0,d1
+ VLD1.8 {d0,d1},[r0],r1
+ VSUB.I16 d16,d16,d8
+ VMLA.I16 d18,d2,d31
+ VMUL.I16 d8,d4,d30
+ VEXT.8 d4,d0,d1,#1
+ VEXT.8 d2,d0,d1,#2
+ VEXT.8 d3,d0,d1,#3
+ VEXT.8 d5,d0,d1,#4
+ VEXT.8 d1,d0,d1,#5
+ VADDL.U8 q1,d2,d3
+ VADDL.U8 q2,d4,d5
+ VADDL.U8 q10,d0,d1
+ VLD1.8 {d0,d1},[r0],r1
+ VSUB.I16 d18,d18,d8
+ VMLA.I16 d20,d2,d31
+ VMUL.I16 d8,d4,d30
+ VEXT.8 d4,d0,d1,#1
+ VEXT.8 d2,d0,d1,#2
+ VEXT.8 d3,d0,d1,#3
+ VEXT.8 d5,d0,d1,#4
+ VEXT.8 d1,d0,d1,#5
+ VADDL.U8 q1,d2,d3
+ VADDL.U8 q2,d4,d5
+ VADDL.U8 q11,d0,d1
+ VLD1.8 {d0,d1},[r0],r1
+ VSUB.I16 d20,d20,d8
+ VMLA.I16 d22,d2,d31
+ VMUL.I16 d8,d4,d30
+ VEXT.8 d4,d0,d1,#1
+ VEXT.8 d2,d0,d1,#2
+ VEXT.8 d3,d0,d1,#3
+ VEXT.8 d5,d0,d1,#4
+ VEXT.8 d1,d0,d1,#5
+ VADDL.U8 q1,d2,d3
+ VADDL.U8 q2,d4,d5
+ VADDL.U8 q12,d0,d1
+ VLD1.8 {d0,d1},[r0],r1
+ VSUB.I16 d22,d22,d8
+ VMLA.I16 d24,d2,d31
+ VMUL.I16 d8,d4,d30
+ VEXT.8 d4,d0,d1,#1
+ VEXT.8 d2,d0,d1,#2
+ VEXT.8 d3,d0,d1,#3
+ VEXT.8 d5,d0,d1,#4
+ VEXT.8 d1,d0,d1,#5
+ VADDL.U8 q1,d2,d3
+ VADDL.U8 q2,d4,d5
+ VADDL.U8 q13,d0,d1
+ VSUB.I16 d24,d24,d8
+ VMLA.I16 d26,d2,d31
+ VMUL.I16 d8,d4,d30
+ VMOV.I32 q15,#0x14
+ VMOV.I32 q14,#0x5
+ VADDL.S16 q5,d10,d20
+ VADDL.S16 q1,d14,d16
+ VADDL.S16 q0,d12,d18
+ VSUB.I16 d26,d26,d8
+ VMLA.I32 q5,q1,q15
+ VMUL.I32 q4,q0,q14
+ VADDL.S16 q6,d12,d22
+ VADDL.S16 q1,d16,d18
+ VADDL.S16 q0,d14,d20
+ VMLA.I32 q6,q1,q15
+ VSUB.I32 q5,q5,q4
+ VMUL.I32 q4,q0,q14
+ VADDL.S16 q2,d14,d24
+ VADDL.S16 q1,d18,d20
+ VADDL.S16 q0,d16,d22
+ VMLA.I32 q2,q1,q15
+ VSUB.I32 q6,q6,q4
+ VMUL.I32 q4,q0,q14
+ VADDL.S16 q3,d16,d26
+ VADDL.S16 q1,d20,d22
+ VADDL.S16 q0,d18,d24
+ VMLA.I32 q3,q1,q15
+ VSUB.I32 q2,q2,q4
+ VMLS.I32 q3,q0,q14
+ VQRSHRUN.S32 d0,q5,#10
+ VQRSHRUN.S32 d2,q6,#10
+ VQRSHRUN.S32 d4,q2,#10
+ VQRSHRUN.S32 d6,q3,#10
+ VQMOVN.U16 d0,q0
+ VQMOVN.U16 d2,q1
+ VQMOVN.U16 d4,q2
+ VQMOVN.U16 d6,q3
+ POP {r4-r12,pc}
+ .endfunc
+
+ .end
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe_s.S
new file mode 100644
index 0000000..991c33f
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe_s.S
@@ -0,0 +1,119 @@
+/*
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ */
+
+ .eabi_attribute 24, 1
+ .eabi_attribute 25, 1
+
+ .arm
+ .fpu neon
+ .text
+
+ .global armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe
+ .func armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe
+armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe:
+ PUSH {r4-r12,lr}
+ VLD1.8 {d0,d1},[r0],r1
+ ADD r12,r0,r1,LSL #2
+ VMOV.I8 d30,#0x5
+ VMOV.I8 d31,#0x14
+ VLD1.8 {d10,d11},[r12],r1
+ VLD1.8 {d2,d3},[r0],r1
+ VLD1.8 {d12,d13},[r12],r1
+ VADDL.U8 q9,d0,d10
+ VLD1.8 {d4,d5},[r0],r1
+ VADDL.U8 q0,d1,d11
+ VLD1.8 {d6,d7},[r0],r1
+ VADDL.U8 q10,d2,d12
+ VLD1.8 {d8,d9},[r0],r1
+ VMLAL.U8 q9,d4,d31
+ VLD1.8 {d14,d15},[r12],r1
+ VMLAL.U8 q0,d5,d31
+ VLD1.8 {d16,d17},[r12],r1
+ VMLAL.U8 q9,d6,d31
+ VMLAL.U8 q10,d6,d31
+ VMLSL.U8 q0,d3,d30
+ VADDL.U8 q11,d4,d14
+ VMLSL.U8 q9,d2,d30
+ VADDL.U8 q1,d3,d13
+ VMLAL.U8 q0,d7,d31
+ VMLAL.U8 q10,d8,d31
+ VMLSL.U8 q9,d8,d30
+ VMLAL.U8 q1,d7,d31
+ VMLSL.U8 q0,d9,d30
+ VMLAL.U8 q11,d8,d31
+ VMLSL.U8 q10,d4,d30
+ VMLSL.U8 q1,d5,d30
+ VADDL.U8 q2,d5,d15
+ VMLAL.U8 q11,d10,d31
+ VMLSL.U8 q10,d10,d30
+ VMLAL.U8 q1,d9,d31
+ VMLAL.U8 q2,d9,d31
+ VADDL.U8 q12,d6,d16
+ VMLSL.U8 q11,d6,d30
+ VMLSL.U8 q1,d11,d30
+ VMLSL.U8 q2,d7,d30
+ VADDL.U8 q3,d7,d17
+ VMLAL.U8 q12,d10,d31
+ VMLSL.U8 q11,d12,d30
+ VMLSL.U8 q2,d13,d30
+ VMLAL.U8 q3,d11,d31
+ VMLAL.U8 q12,d12,d31
+ VEXT.8 d26,d18,d19,#2
+ VMLAL.U8 q2,d11,d31
+ VMLAL.U8 q3,d13,d31
+ VMLSL.U8 q12,d8,d30
+ VEXT.8 d27,d18,d19,#4
+ VMOV.I16 d31,#0x14
+ VMLSL.U8 q3,d9,d30
+ VMLSL.U8 q12,d14,d30
+ VEXT.8 d29,d19,d0,#2
+ VEXT.8 d28,d18,d19,#6
+ VMLSL.U8 q3,d15,d30
+ VADDL.S16 q0,d18,d29
+ VADD.I16 d27,d27,d28
+ VMOV.I16 d30,#0x5
+ VADD.I16 d26,d26,d19
+ VMLAL.S16 q0,d27,d31
+ VEXT.8 d27,d20,d21,#4
+ VEXT.8 d28,d20,d21,#6
+ VEXT.8 d29,d21,d2,#2
+ VMLSL.S16 q0,d26,d30
+ VEXT.8 d26,d20,d21,#2
+ VADDL.S16 q1,d20,d29
+ VADD.I16 d27,d27,d28
+ VADD.I16 d26,d26,d21
+ VEXT.8 d28,d22,d23,#6
+ VMLAL.S16 q1,d27,d31
+ VEXT.8 d29,d23,d4,#2
+ VEXT.8 d27,d22,d23,#4
+ VEXT.8 d8,d22,d23,#2
+ VADDL.S16 q2,d22,d29
+ VMLSL.S16 q1,d26,d30
+ VADD.I16 d27,d27,d28
+ VADD.I16 d26,d8,d23
+ VEXT.8 d28,d24,d25,#6
+ VMLAL.S16 q2,d27,d31
+ VEXT.8 d27,d24,d25,#4
+ VEXT.8 d29,d25,d6,#2
+ VADD.I16 d27,d27,d28
+ VEXT.8 d8,d24,d25,#2
+ VADDL.S16 q3,d24,d29
+ VMLSL.S16 q2,d26,d30
+ VMLAL.S16 q3,d27,d31
+ VADD.I16 d8,d8,d25
+ VMLSL.S16 q3,d8,d30
+ VQRSHRUN.S32 d0,q0,#10
+ VQRSHRUN.S32 d2,q1,#10
+ VQRSHRUN.S32 d4,q2,#10
+ VQRSHRUN.S32 d6,q3,#10
+ VQMOVN.U16 d0,q0
+ VQMOVN.U16 d2,q1
+ VQMOVN.U16 d4,q2
+ VQMOVN.U16 d6,q3
+ POP {r4-r12,pc}
+ .endfunc
+
+ .end
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe_s.S
new file mode 100644
index 0000000..40e141b
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe_s.S
@@ -0,0 +1,72 @@
+/*
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ */
+
+ .eabi_attribute 24, 1
+ .eabi_attribute 25, 1
+
+ .arm
+ .fpu neon
+ .text
+
+ .global armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe
+ .func armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe
+armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe:
+ PUSH {r4-r12,lr}
+ VLD1.8 {d22,d23},[r0],r1
+ VEXT.8 d10,d22,d23,#5
+ VEXT.8 d12,d22,d23,#1
+ VEXT.8 d14,d22,d23,#2
+ VEXT.8 d15,d22,d23,#3
+ VEXT.8 d13,d22,d23,#4
+ VADDL.U8 q11,d22,d10
+ VADDL.U8 q4,d14,d15
+ VADDL.U8 q6,d12,d13
+ VLD1.8 {d24,d25},[r0],r1
+ VMLA.I16 d22,d8,d31
+ VMUL.I16 d8,d12,d30
+ VEXT.8 d10,d24,d25,#5
+ VEXT.8 d12,d24,d25,#1
+ VEXT.8 d16,d24,d25,#2
+ VEXT.8 d17,d24,d25,#3
+ VEXT.8 d13,d24,d25,#4
+ VADDL.U8 q12,d24,d10
+ VSUB.I16 d22,d22,d8
+ VADDL.U8 q4,d16,d17
+ VADDL.U8 q6,d12,d13
+ VLD1.8 {d26,d27},[r0],r1
+ VMLA.I16 d24,d8,d31
+ VMUL.I16 d8,d12,d30
+ VEXT.8 d10,d26,d27,#5
+ VEXT.8 d12,d26,d27,#1
+ VEXT.8 d18,d26,d27,#2
+ VEXT.8 d19,d26,d27,#3
+ VEXT.8 d13,d26,d27,#4
+ VADDL.U8 q13,d26,d10
+ VSUB.I16 d24,d24,d8
+ VADDL.U8 q4,d18,d19
+ VADDL.U8 q6,d12,d13
+ VLD1.8 {d28,d29},[r0],r1
+ VMLA.I16 d26,d8,d31
+ VMUL.I16 d8,d12,d30
+ VEXT.8 d10,d28,d29,#5
+ VEXT.8 d12,d28,d29,#1
+ VEXT.8 d20,d28,d29,#2
+ VEXT.8 d21,d28,d29,#3
+ VEXT.8 d13,d28,d29,#4
+ VADDL.U8 q14,d28,d10
+ VSUB.I16 d26,d26,d8
+ VADDL.U8 q4,d20,d21
+ VADDL.U8 q6,d12,d13
+ VMLA.I16 d28,d8,d31
+ VMLS.I16 d28,d12,d30
+ VQRSHRUN.S16 d22,q11,#5
+ VQRSHRUN.S16 d24,q12,#5
+ VQRSHRUN.S16 d26,q13,#5
+ VQRSHRUN.S16 d28,q14,#5
+ POP {r4-r12,pc}
+ .endfunc
+
+ .end
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe_s.S
new file mode 100644
index 0000000..955846f
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe_s.S
@@ -0,0 +1,58 @@
+/*
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ */
+
+ .eabi_attribute 24, 1
+ .eabi_attribute 25, 1
+
+ .arm
+ .fpu neon
+ .text
+
+ .global armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe
+ .func armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe
+armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe:
+ PUSH {r4-r12,lr}
+ VLD1.8 {d7},[r0],r1
+ ADD r12,r0,r1,LSL #2
+ VLD1.8 {d8},[r0],r1
+ VLD1.8 {d12},[r12],r1
+ VLD1.8 {d9},[r0],r1
+ VADDL.U8 q0,d7,d12
+ VLD1.8 {d10},[r0],r1
+ VLD1.8 {d13},[r12],r1
+ VLD1.8 {d11},[r0],r1
+ VLD1.8 {d14},[r12],r1
+ VADDL.U8 q8,d8,d11
+ VADDL.U8 q9,d9,d10
+ VLD1.8 {d15},[r12],r1
+ VMLS.I16 d0,d16,d30
+ VMUL.I16 d20,d18,d31
+ VADDL.U8 q8,d9,d12
+ VADDL.U8 q9,d10,d11
+ VADDL.U8 q1,d8,d13
+ VMLS.I16 d2,d16,d30
+ VMUL.I16 d21,d18,d31
+ VADDL.U8 q8,d10,d13
+ VADDL.U8 q9,d11,d12
+ VADDL.U8 q2,d9,d14
+ VMLS.I16 d4,d16,d30
+ VMUL.I16 d22,d18,d31
+ VADDL.U8 q8,d11,d14
+ VADDL.U8 q3,d10,d15
+ VADDL.U8 q9,d12,d13
+ VMLS.I16 d6,d16,d30
+ VADD.I16 d0,d0,d20
+ VADD.I16 d2,d2,d21
+ VADD.I16 d4,d4,d22
+ VMLA.I16 d6,d18,d31
+ VQRSHRUN.S16 d0,q0,#5
+ VQRSHRUN.S16 d2,q1,#5
+ VQRSHRUN.S16 d4,q2,#5
+ VQRSHRUN.S16 d6,q3,#5
+ POP {r4-r12,pc}
+ .endfunc
+
+ .end
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_Interpolate_Chroma_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_Interpolate_Chroma_s.S
new file mode 100644
index 0000000..66520da
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_Interpolate_Chroma_s.S
@@ -0,0 +1,175 @@
+/*
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ */
+
+ .eabi_attribute 24, 1
+ .eabi_attribute 25, 1
+
+ .arm
+ .fpu neon
+
+ .section .rodata
+ .align 4
+
+armVCM4P10_WidthBranchTableMVIsNotZero:
+ .word WidthIs2MVIsNotZero, WidthIs2MVIsNotZero
+ .word WidthIs4MVIsNotZero, WidthIs4MVIsNotZero
+ .word WidthIs8MVIsNotZero
+
+armVCM4P10_WidthBranchTableMVIsZero:
+ .word WidthIs2MVIsZero, WidthIs2MVIsZero
+ .word WidthIs4MVIsZero, WidthIs4MVIsZero
+ .word WidthIs8MVIsZero
+
+ .text
+
+ .global armVCM4P10_Interpolate_Chroma
+ .func armVCM4P10_Interpolate_Chroma
+armVCM4P10_Interpolate_Chroma:
+ PUSH {r4-r12,lr}
+ VPUSH {d8-d15}
+ LDRD r6,r7,[sp,#0x70]
+ LDRD r4,r5,[sp,#0x68]
+ RSB r8,r6,#8
+ RSB r9,r7,#8
+ CMN r6,r7
+ MOV r10,#1
+ LDREQ r11, =armVCM4P10_WidthBranchTableMVIsZero
+ SUB lr,r1,r10
+ LDRNE r11, =armVCM4P10_WidthBranchTableMVIsNotZero
+ VLD1.8 {d0},[r0],r10
+ SMULBB r12,r8,r9
+ SMULBB r9,r6,r9
+ VLD1.8 {d1},[r0],lr
+ SMULBB r8,r8,r7
+ SMULBB r6,r6,r7
+ VDUP.8 d12,r12
+ VDUP.8 d13,r9
+ VDUP.8 d14,r8
+ VDUP.8 d15,r6
+ LDR pc,[r11,r4,LSL #1]
+
+WidthIs8MVIsNotZero:
+ VLD1.8 {d2},[r0],r10
+ VMULL.U8 q2,d0,d12
+ VLD1.8 {d3},[r0],lr
+ VMULL.U8 q3,d2,d12
+ VLD1.8 {d16},[r0],r10
+ VMLAL.U8 q2,d1,d13
+ VLD1.8 {d17},[r0],lr
+ VMULL.U8 q11,d16,d12
+ VMLAL.U8 q3,d3,d13
+ VLD1.8 {d18},[r0],r10
+ VMLAL.U8 q2,d2,d14
+ VMLAL.U8 q11,d17,d13
+ VMULL.U8 q12,d18,d12
+ VLD1.8 {d19},[r0],lr
+ VMLAL.U8 q3,d16,d14
+ VLD1.8 {d0},[r0],r10
+ VMLAL.U8 q12,d19,d13
+ VMLAL.U8 q11,d18,d14
+ VMLAL.U8 q2,d3,d15
+ VLD1.8 {d1},[r0],lr
+ VMLAL.U8 q12,d0,d14
+ VMLAL.U8 q3,d17,d15
+ VMLAL.U8 q11,d19,d15
+ SUBS r5,r5,#4
+ VMLAL.U8 q12,d1,d15
+ VQRSHRN.U16 d8,q2,#6
+ VQRSHRN.U16 d9,q3,#6
+ VQRSHRN.U16 d20,q11,#6
+ VST1.64 {d8},[r2],r3
+ VQRSHRN.U16 d21,q12,#6
+ VST1.64 {d9},[r2],r3
+ VST1.64 {d20},[r2],r3
+ VST1.64 {d21},[r2],r3
+ BGT WidthIs8MVIsNotZero
+ MOV r0,#0
+ VPOP {d8-d15}
+ POP {r4-r12,pc}
+
+WidthIs4MVIsNotZero:
+ VLD1.8 {d2},[r0],r10
+ VMULL.U8 q2,d0,d12
+ VMULL.U8 q3,d2,d12
+ VLD1.8 {d3},[r0],lr
+ VMLAL.U8 q2,d1,d13
+ VMLAL.U8 q3,d3,d13
+ VLD1.8 {d0},[r0],r10
+ VMLAL.U8 q2,d2,d14
+ VMLAL.U8 q3,d0,d14
+ VLD1.8 {d1},[r0],lr
+ SUBS r5,r5,#2
+ VMLAL.U8 q3,d1,d15
+ VMLAL.U8 q2,d3,d15
+ VQRSHRN.U16 d9,q3,#6
+ VQRSHRN.U16 d8,q2,#6
+ VST1.32 {d8[0]},[r2],r3
+ VST1.32 {d9[0]},[r2],r3
+ BGT WidthIs4MVIsNotZero
+ MOV r0,#0
+ VPOP {d8-d15}
+ POP {r4-r12,pc}
+
+WidthIs2MVIsNotZero:
+ VLD1.8 {d2},[r0],r10
+ VMULL.U8 q2,d0,d12
+ VMULL.U8 q3,d2,d12
+ VLD1.8 {d3},[r0],lr
+ VMLAL.U8 q2,d1,d13
+ VMLAL.U8 q3,d3,d13
+ VLD1.8 {d0},[r0],r10
+ VMLAL.U8 q2,d2,d14
+ VMLAL.U8 q3,d0,d14
+ VLD1.8 {d1},[r0],lr
+ SUBS r5,r5,#2
+ VMLAL.U8 q3,d1,d15
+ VMLAL.U8 q2,d3,d15
+ VQRSHRN.U16 d9,q3,#6
+ VQRSHRN.U16 d8,q2,#6
+ VST1.16 {d8[0]},[r2],r3
+ VST1.16 {d9[0]},[r2],r3
+ BGT WidthIs2MVIsNotZero
+ MOV r0,#0
+ VPOP {d8-d15}
+ POP {r4-r12,pc}
+
+WidthIs8MVIsZero:
+ SUB r0,r0,r1
+WidthIs8LoopMVIsZero:
+ VLD1.8 {d0},[r0],r1
+ SUBS r5,r5,#2
+ VLD1.8 {d1},[r0],r1
+ VST1.64 {d0},[r2],r3
+ VST1.64 {d1},[r2],r3
+ BGT WidthIs8LoopMVIsZero
+ MOV r0,#0
+ VPOP {d8-d15}
+ POP {r4-r12,pc}
+
+WidthIs4MVIsZero:
+ VLD1.8 {d1},[r0],r1
+ SUBS r5,r5,#2
+ VST1.32 {d0[0]},[r2],r3
+ VLD1.8 {d0},[r0],r1
+ VST1.32 {d1[0]},[r2],r3
+ BGT WidthIs4MVIsZero
+ MOV r0,#0
+ VPOP {d8-d15}
+ POP {r4-r12,pc}
+
+WidthIs2MVIsZero:
+ VLD1.8 {d1},[r0],r1
+ SUBS r5,r5,#2
+ VST1.16 {d0[0]},[r2],r3
+ VLD1.8 {d0},[r0],r1
+ VST1.16 {d1[0]},[r2],r3
+ BGT WidthIs2MVIsZero
+ MOV r0,#0
+ VPOP {d8-d15}
+ POP {r4-r12,pc}
+ .endfunc
+
+ .end
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_QuantTables_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_QuantTables_s.S
new file mode 100644
index 0000000..f5d6d1f
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_QuantTables_s.S
@@ -0,0 +1,68 @@
+/*
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ */
+
+ .eabi_attribute 24, 1
+ .eabi_attribute 25, 1
+
+ .arm
+ .fpu neon
+ .section .rodata
+ .align 4
+
+ .global armVCM4P10_MFMatrixQPModTable
+ .global armVCM4P10_QPDivIntraTable
+ .global armVCM4P10_QPDivPlusOneTable
+
+;//------------------------------------------------------------------
+;// This table contains (1 << QbitsPlusOne) / 3 Values (Intra case) ,
+;// for values of iQP from 0 to 51 (inclusive).
+;//------------------------------------------------------------------
+
+
+armVCM4P10_QPDivIntraTable:
+ .word 21845, 21845, 21845, 21845, 21845, 21845
+ .word 43690, 43690, 43690, 43690, 43690, 43690
+ .word 87381, 87381, 87381, 87381, 87381, 87381
+ .word 174762, 174762, 174762, 174762, 174762, 174762
+ .word 349525, 349525, 349525, 349525, 349525, 349525
+ .word 699050, 699050, 699050, 699050, 699050, 699050
+ .word 1398101, 1398101, 1398101, 1398101, 1398101, 1398101
+ .word 2796202, 2796202, 2796202, 2796202, 2796202, 2796202
+
+
+;//--------------------------------------------------------------
+;// This table contains armVCM4P10_MFMatrix [iQP % 6][0] entires,
+;// for values of iQP from 0 to 51 (inclusive).
+;//--------------------------------------------------------------
+
+armVCM4P10_MFMatrixQPModTable:
+ .hword 13107, 11916, 10082, 9362, 8192, 7282
+ .hword 13107, 11916, 10082, 9362, 8192, 7282
+ .hword 13107, 11916, 10082, 9362, 8192, 7282
+ .hword 13107, 11916, 10082, 9362, 8192, 7282
+ .hword 13107, 11916, 10082, 9362, 8192, 7282
+ .hword 13107, 11916, 10082, 9362, 8192, 7282
+ .hword 13107, 11916, 10082, 9362, 8192, 7282
+ .hword 13107, 11916, 10082, 9362, 8192, 7282
+ .hword 13107, 11916, 10082, 9362, 8192, 7282
+
+;//---------------------------------------------------------------
+;// This table contains ARM_M4P10_Q_OFFSET + 1 + (iQP / 6) values,
+;// for values of iQP from 0 to 51 (inclusive).
+;//---------------------------------------------------------------
+
+armVCM4P10_QPDivPlusOneTable:
+ .byte 16, 16, 16, 16, 16, 16
+ .byte 17, 17, 17, 17, 17, 17
+ .byte 18, 18, 18, 18, 18, 18
+ .byte 19, 19, 19, 19, 19, 19
+ .byte 20, 20, 20, 20, 20, 20
+ .byte 21, 21, 21, 21, 21, 21
+ .byte 22, 22, 22, 22, 22, 22
+ .byte 23, 23, 23, 23, 23, 23
+ .byte 24, 24, 24, 24, 24, 24
+
+ .end
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_TransformResidual4x4_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_TransformResidual4x4_s.S
new file mode 100644
index 0000000..c24d717
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_TransformResidual4x4_s.S
@@ -0,0 +1,52 @@
+/*
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ */
+
+ .eabi_attribute 24, 1
+ .eabi_attribute 25, 1
+
+ .arm
+ .fpu neon
+ .text
+
+ .global armVCM4P10_TransformResidual4x4
+ .func armVCM4P10_TransformResidual4x4
+armVCM4P10_TransformResidual4x4:
+ VPUSH {d8}
+ VLD4.16 {d0,d1,d2,d3},[r1]
+ VMOV.I16 d4,#0
+ VADD.I16 d5,d0,d2
+ VSUB.I16 d6,d0,d2
+ VHADD.S16 d7,d1,d4
+ VHADD.S16 d8,d3,d4
+ VSUB.I16 d7,d7,d3
+ VADD.I16 d8,d1,d8
+ VADD.I16 d0,d5,d8
+ VADD.I16 d1,d6,d7
+ VSUB.I16 d2,d6,d7
+ VSUB.I16 d3,d5,d8
+ VTRN.16 d0,d1
+ VTRN.16 d2,d3
+ VTRN.32 q0,q1
+ VADD.I16 d5,d0,d2
+ VSUB.I16 d6,d0,d2
+ VHADD.S16 d7,d1,d4
+ VHADD.S16 d8,d3,d4
+ VSUB.I16 d7,d7,d3
+ VADD.I16 d8,d1,d8
+ VADD.I16 d0,d5,d8
+ VADD.I16 d1,d6,d7
+ VSUB.I16 d2,d6,d7
+ VSUB.I16 d3,d5,d8
+ VRSHR.S16 d0,d0,#6
+ VRSHR.S16 d1,d1,#6
+ VRSHR.S16 d2,d2,#6
+ VRSHR.S16 d3,d3,#6
+ VST1.16 {d0,d1,d2,d3},[r0]
+ VPOP {d8}
+ BX lr
+ .endfunc
+
+ .end
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_UnpackBlock4x4_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_UnpackBlock4x4_s.S
new file mode 100644
index 0000000..c552f8d
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_UnpackBlock4x4_s.S
@@ -0,0 +1,40 @@
+/*
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ */
+
+ .eabi_attribute 24, 1
+ .eabi_attribute 25, 1
+
+ .arm
+ .fpu neon
+ .text
+
+ .global armVCM4P10_UnpackBlock4x4
+ .func armVCM4P10_UnpackBlock4x4
+armVCM4P10_UnpackBlock4x4:
+ PUSH {r4-r8,lr}
+ LDR r2,[r0,#0]
+ MOV r7,#0x1f
+ MOV r4,#0
+ MOV r5,#0
+ LDRB r3,[r2],#1
+ STRD r4,r5,[r1,#0]
+ STRD r4,r5,[r1,#8]
+ STRD r4,r5,[r1,#0x10]
+ STRD r4,r5,[r1,#0x18]
+unpackLoop:
+ TST r3,#0x10
+ LDRNESB r5,[r2,#1]
+ LDRNEB r4,[r2],#2
+ AND r6,r7,r3,LSL #1
+ LDREQSB r4,[r2],#1
+ ORRNE r4,r4,r5,LSL #8
+ TST r3,#0x20
+ LDREQB r3,[r2],#1
+ STRH r4,[r1,r6]
+ BEQ unpackLoop
+ STR r2,[r0,#0]
+ POP {r4-r8,pc}
+ .endfunc
+ .end
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_DeblockLuma_I.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_DeblockLuma_I.S
new file mode 100644
index 0000000..ba61059
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_DeblockLuma_I.S
@@ -0,0 +1,67 @@
+/*
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ */
+
+ .eabi_attribute 24, 1
+ .eabi_attribute 25, 1
+
+ .arm
+ .fpu neon
+ .text
+
+ .global omxVCM4P10_DeblockLuma_I
+ .func omxVCM4P10_DeblockLuma_I
+omxVCM4P10_DeblockLuma_I:
+ PUSH {r4-r9,lr}
+ MOVS r6,r0
+ SUB sp,sp,#0xc
+ MOV r9,r1
+ MOV r7,r2
+ MOV r8,r3
+ LDR r4,[sp,#0x28]
+ LDR r5,[sp,#0x2c]
+ BEQ L0x58
+ TST r6,#7
+ TSTEQ r9,#7
+ BNE L0x58
+ CMP r7,#0
+ CMPNE r8,#0
+ CMPNE r4,#0
+ BEQ L0x58
+ TST r4,#3
+ BNE L0x58
+ CMP r5,#0
+ BEQ L0x58
+ TST r5,#3
+ BEQ L0x64
+L0x58:
+ MVN r0,#4
+L0x5c:
+ ADD sp,sp,#0xc
+ POP {r4-r9,pc}
+L0x64:
+ STR r4,[sp,#0]
+ MOV r3,r8
+ STR r5,[sp,#4]
+ MOV r2,r7
+ MOV r1,r9
+ MOV r0,r6
+ BL omxVCM4P10_FilterDeblockingLuma_VerEdge_I
+ CMP r0,#0
+ BNE L0x5c
+ ADD r3,r5,#0x10
+ ADD r2,r4,#0x10
+ STR r3,[sp,#4]
+ STR r2,[sp,#0]
+ ADD r3,r8,#2
+ ADD r2,r7,#2
+ MOV r1,r9
+ MOV r0,r6
+ BL omxVCM4P10_FilterDeblockingLuma_HorEdge_I
+ ADD sp,sp,#0xc
+ POP {r4-r9,pc}
+ .endfunc
+
+ .end
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_DequantTransformResidualFromPairAndAdd_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_DequantTransformResidualFromPairAndAdd_s.S
new file mode 100644
index 0000000..be21ee7
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_DequantTransformResidualFromPairAndAdd_s.S
@@ -0,0 +1,119 @@
+/*
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ */
+
+ .eabi_attribute 24, 1
+ .eabi_attribute 25, 1
+
+ .arm
+ .fpu neon
+ .text
+
+ .global omxVCM4P10_DequantTransformResidualFromPairAndAdd
+ .func omxVCM4P10_DequantTransformResidualFromPairAndAdd
+omxVCM4P10_DequantTransformResidualFromPairAndAdd:
+ PUSH {r4-r12,lr}
+ VPUSH {d8-d9}
+ SUB sp,sp,#0x20
+ ADD r4,sp,#0
+ LDR r5,[sp,#0x64]
+ MOV r7,r1
+ MOV r8,r2
+ MOV r9,r3
+ CMP r5,#0
+ BEQ L0x114
+ MOV r1,r4
+ BL armVCM4P10_UnpackBlock4x4 ;//
+ LDR r1,[sp,#0x60]
+ LDR r11, =armVCM4P10_QPModuloTable
+ LDR r10, =armVCM4P10_QPDivTable
+ LDR r2, =armVCM4P10_VMatrixU16
+ LDRSB r12,[r11,r1]
+ LDRSB lr,[r10,r1]
+ LDR r10, =0x3020504
+ LDR r1, =0x5040100
+ ADD r2,r2,r12
+ VDUP.32 d7,r1
+ VDUP.32 d9,r10
+ VDUP.16 d5,lr
+ VLD1.8 {d6},[r2]
+ VTBL.8 d8,{d6},d7
+ VTBL.8 d4,{d6},d9
+ CMP r8,#0
+ VLD1.16 {d0,d1,d2,d3},[r4]
+ VSHL.U16 d8,d8,d5
+ VSHL.U16 d4,d4,d5
+ BEQ L1
+ LDRSH r10,[r8,#0]
+L1:
+ VMUL.I16 d0,d0,d8
+ VMUL.I16 d1,d1,d4
+ VMUL.I16 d2,d2,d8
+ VMUL.I16 d3,d3,d4
+ VMOVNE.16 d0[0],r10
+ VTRN.16 d0,d1
+ VTRN.16 d2,d3
+ VTRN.32 q0,q1
+ VMOV.I16 d4,#0
+ VADD.I16 d5,d0,d2
+ VSUB.I16 d6,d0,d2
+ VHADD.S16 d7,d1,d4
+ VHADD.S16 d8,d3,d4
+ VSUB.I16 d7,d7,d3
+ VADD.I16 d8,d1,d8
+ VADD.I16 d0,d5,d8
+ VADD.I16 d1,d6,d7
+ VSUB.I16 d2,d6,d7
+ VSUB.I16 d3,d5,d8
+ VTRN.16 d0,d1
+ VTRN.16 d2,d3
+ VTRN.32 q0,q1
+ VADD.I16 d5,d0,d2
+ VSUB.I16 d6,d0,d2
+ VHADD.S16 d7,d1,d4
+ VHADD.S16 d8,d3,d4
+ VSUB.I16 d7,d7,d3
+ VADD.I16 d8,d1,d8
+ VADD.I16 d0,d5,d8
+ VADD.I16 d1,d6,d7
+ VSUB.I16 d2,d6,d7
+ VSUB.I16 d3,d5,d8
+ VRSHR.S16 d0,d0,#6
+ VRSHR.S16 d1,d1,#6
+ VRSHR.S16 d2,d2,#6
+ VRSHR.S16 d3,d3,#6
+ B L0x130
+L0x114:
+ LDRSH r10,[r8,#0]
+ ADD r10,r10,#0x20
+ ASR r10,r10,#6
+ VDUP.16 d0,r10
+ VDUP.16 d1,r10
+ VDUP.16 d2,r10
+ VDUP.16 d3,r10
+L0x130:
+ LDR r1,[sp,#0x58]
+ LDR r10,[sp,#0x5c]
+ LDR r3,[r7],r1
+ LDR r5,[r7],r1
+ VMOV d4,r3,r5
+ LDR r3,[r7],r1
+ LDR r5,[r7,#0]
+ VMOV d5,r3,r5
+ VADDW.U8 q3,q0,d4
+ VADDW.U8 q4,q1,d5
+ VQMOVUN.S16 d0,q3
+ VQMOVUN.S16 d1,q4
+ VST1.32 {d0[0]},[r9],r10
+ VST1.32 {d0[1]},[r9],r10
+ VST1.32 {d1[0]},[r9],r10
+ VST1.32 {d1[1]},[r9]
+ MOV r0,#0
+ ADD sp,sp,#0x20
+ VPOP {d8-d9}
+ POP {r4-r12,pc}
+ .endfunc
+
+ .end
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_FilterDeblockingChroma_HorEdge_I_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_FilterDeblockingChroma_HorEdge_I_s.S
new file mode 100644
index 0000000..79ba538
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_FilterDeblockingChroma_HorEdge_I_s.S
@@ -0,0 +1,87 @@
+/*
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ */
+
+ .eabi_attribute 24, 1
+ .eabi_attribute 25, 1
+
+ .arm
+ .fpu neon
+ .text
+
+ .global omxVCM4P10_FilterDeblockingChroma_HorEdge_I
+ .func omxVCM4P10_FilterDeblockingChroma_HorEdge_I
+omxVCM4P10_FilterDeblockingChroma_HorEdge_I:
+ PUSH {r4-r10,lr}
+ VPUSH {d8-d15}
+ VLD1.8 {d0[]},[r2]!
+ SUB r0,r0,r1,LSL #1
+ SUB r0,r0,r1
+ VLD1.8 {d2[]},[r3]!
+ LDR r4,[sp,#0x64]
+ LDR r5,[sp,#0x60]
+ LDR r9, =0x3030303
+ LDR r8, =0x4040404
+ VMOV.I8 d14,#0
+ VMOV.I8 d15,#0x1
+ VMOV.I16 d1,#0x4
+ MOV r7,#0x40000000
+L0x38:
+ LDR r6,[r4],#8
+ VLD1.8 {d6},[r0],r1
+ VLD1.8 {d5},[r0],r1
+ CMP r6,#0
+ VLD1.8 {d4},[r0],r1
+ VLD1.8 {d8},[r0],r1
+ VABD.U8 d19,d6,d4
+ VLD1.8 {d9},[r0],r1
+ VABD.U8 d13,d4,d8
+ VLD1.8 {d10},[r0],r1
+ BEQ L0xe4
+ VABD.U8 d12,d5,d4
+ VABD.U8 d18,d9,d8
+ VCGT.U8 d16,d0,d13
+ VMOV.32 d26[0],r6
+ VMAX.U8 d12,d18,d12
+ VMOVL.U8 q13,d26
+ VABD.U8 d17,d10,d8
+ VCGT.S16 d27,d26,#0
+ VCGT.U8 d12,d2,d12
+ VCGT.U8 d19,d2,d19
+ VAND d16,d16,d27
+ TST r6,r9
+ VCGT.U8 d17,d2,d17
+ VAND d16,d16,d12
+ VAND d12,d16,d17
+ VAND d17,d16,d19
+ BLNE armVCM4P10_DeblockingChromabSLT4_unsafe
+ TST r6,r8
+ SUB r0,r0,r1,LSL #2
+ VTST.16 d26,d26,d1
+ BLNE armVCM4P10_DeblockingChromabSGE4_unsafe
+ VBIT d29,d13,d26
+ VBIT d24,d31,d26
+ VBIF d29,d4,d16
+ VBIF d24,d8,d16
+ VST1.8 {d29},[r0],r1
+ ADDS r7,r7,r7
+ VST1.8 {d24},[r0],r1
+ BNE L0x38
+ MOV r0,#0
+ VPOP {d8-d15}
+ POP {r4-r10,pc}
+L0xe4:
+ VLD1.8 {d0[]},[r2]
+ SUB r0,r0,r1,LSL #1
+ ADDS r7,r7,r7
+ VLD1.8 {d2[]},[r3]
+ ADD r5,r5,#4
+ BNE L0x38
+ MOV r0,#0
+ VPOP {d8-d15}
+ POP {r4-r10,pc}
+ .endfunc
+
+ .end
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_FilterDeblockingChroma_VerEdge_I_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_FilterDeblockingChroma_VerEdge_I_s.S
new file mode 100644
index 0000000..dcdddbe
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_FilterDeblockingChroma_VerEdge_I_s.S
@@ -0,0 +1,123 @@
+/*
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ */
+
+ .eabi_attribute 24, 1
+ .eabi_attribute 25, 1
+
+ .arm
+ .fpu neon
+ .text
+
+ .global omxVCM4P10_FilterDeblockingChroma_VerEdge_I
+ .func omxVCM4P10_FilterDeblockingChroma_VerEdge_I
+omxVCM4P10_FilterDeblockingChroma_VerEdge_I:
+ PUSH {r4-r12,lr}
+ VPUSH {d8-d15}
+ VLD1.8 {d0[]},[r2]!
+ SUB r0,r0,#4
+ VLD1.8 {d2[]},[r3]!
+ LDR r4,[sp,#0x6c]
+ LDR r5,[sp,#0x68]
+ LDR r8, =0x4040404
+ LDR r9, =0x3030303
+ VMOV.I8 d14,#0
+ VMOV.I8 d15,#0x1
+ VMOV.I16 d1,#0x4
+ MOV r7,#0x40000000
+L0x34:
+ LDR r6,[r4],#8
+ ADD r10,r0,r1
+ ADD lr,r1,r1
+ VLD1.8 {d7},[r0],lr
+ VLD1.8 {d8},[r10],lr
+ VLD1.8 {d5},[r0],lr
+ VLD1.8 {d10},[r10],lr
+ VLD1.8 {d6},[r0],lr
+ VLD1.8 {d9},[r10],lr
+ VLD1.8 {d4},[r0],lr
+ VLD1.8 {d11},[r10],lr
+ VZIP.8 d7,d8
+ VZIP.8 d5,d10
+ VZIP.8 d6,d9
+ VZIP.8 d4,d11
+ VZIP.16 d7,d5
+ VZIP.16 d8,d10
+ VZIP.16 d6,d4
+ VZIP.16 d9,d11
+ VTRN.32 d7,d6
+ VTRN.32 d5,d4
+ VTRN.32 d10,d11
+ VTRN.32 d8,d9
+ CMP r6,#0
+ VABD.U8 d19,d6,d4
+ VABD.U8 d13,d4,d8
+ BEQ L0x170
+ VABD.U8 d12,d5,d4
+ VABD.U8 d18,d9,d8
+ VMOV.32 d26[0],r6
+ VCGT.U8 d16,d0,d13
+ VMAX.U8 d12,d18,d12
+ VMOVL.U8 q13,d26
+ VABD.U8 d17,d10,d8
+ VCGT.S16 d27,d26,#0
+ VCGT.U8 d12,d2,d12
+ VCGT.U8 d19,d2,d19
+ VAND d16,d16,d27
+ TST r6,r9
+ VCGT.U8 d17,d2,d17
+ VAND d16,d16,d12
+ VAND d12,d16,d17
+ VAND d17,d16,d19
+ BLNE armVCM4P10_DeblockingChromabSLT4_unsafe
+ TST r6,r8
+ SUB r0,r0,r1,LSL #3
+ VTST.16 d26,d26,d1
+ BLNE armVCM4P10_DeblockingChromabSGE4_unsafe
+ VBIT d29,d13,d26
+ VBIT d24,d31,d26
+ ADD r10,r0,#3
+ VBIF d29,d4,d16
+ ADD r12,r10,r1
+ ADD lr,r1,r1
+ VBIF d24,d8,d16
+ ADDS r7,r7,r7
+ VST1.8 {d29[0]},[r10],lr
+ VST1.8 {d29[1]},[r12],lr
+ VST1.8 {d29[2]},[r10],lr
+ VST1.8 {d29[3]},[r12],lr
+ VST1.8 {d29[4]},[r10],lr
+ VST1.8 {d29[5]},[r12],lr
+ VST1.8 {d29[6]},[r10],lr
+ VST1.8 {d29[7]},[r12],lr
+ ADD r12,r0,#4
+ ADD r10,r12,r1
+ VST1.8 {d24[0]},[r12],lr
+ VST1.8 {d24[1]},[r10],lr
+ VST1.8 {d24[2]},[r12],lr
+ VST1.8 {d24[3]},[r10],lr
+ VST1.8 {d24[4]},[r12],lr
+ VST1.8 {d24[5]},[r10],lr
+ VST1.8 {d24[6]},[r12],lr
+ VST1.8 {d24[7]},[r10],lr
+ ADD r0,r0,#4
+ BNE L0x34
+ MOV r0,#0
+ VPOP {d8-d15}
+ POP {r4-r12,pc}
+L0x170:
+ VLD1.8 {d0[]},[r2]
+ ADD r0,r0,#4
+ SUB r0,r0,r1,LSL #3
+ ADDS r7,r7,r7
+ VLD1.8 {d2[]},[r3]
+ ADD r5,r5,#4
+ BNE L0x34
+ MOV r0,#0
+ VPOP {d8-d15}
+ POP {r4-r12,pc}
+ .endfunc
+
+ .end
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_FilterDeblockingLuma_HorEdge_I_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_FilterDeblockingLuma_HorEdge_I_s.S
new file mode 100644
index 0000000..9755899
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_FilterDeblockingLuma_HorEdge_I_s.S
@@ -0,0 +1,107 @@
+/*
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ */
+
+ .eabi_attribute 24, 1
+ .eabi_attribute 25, 1
+
+ .arm
+ .fpu neon
+ .text
+
+ .global omxVCM4P10_FilterDeblockingLuma_HorEdge_I
+ .func omxVCM4P10_FilterDeblockingLuma_HorEdge_I
+omxVCM4P10_FilterDeblockingLuma_HorEdge_I:
+ PUSH {r4-r12,lr}
+ VPUSH {d8-d15}
+ ADD r7,r2,#1
+ ADD r8,r3,#1
+ VLD1.8 {d0[]},[r2]
+ SUB r0,r0,r1,LSL #2
+ VLD1.8 {d2[]},[r3]
+ LDR r4,[sp,#0x6c]
+ LDR r5,[sp,#0x68]
+ MOV r11,#0
+ VMOV.I8 d14,#0
+ VMOV.I8 d15,#0x1
+ ADD r10,r1,r1
+ MOV r9,#0x55000000
+L0x38:
+ LDRH r12,[r4],#2
+ ADD r6,r0,r1
+ CMP r12,#0
+ BEQ L0xe4
+ VLD1.8 {d7},[r0],r10
+ VLD1.8 {d6},[r6],r10
+ VLD1.8 {d5},[r0],r10
+ VLD1.8 {d4},[r6],r10
+ VLD1.8 {d8},[r0],r10
+ VABD.U8 d12,d4,d5
+ VLD1.8 {d9},[r6]
+ VABD.U8 d13,d8,d4
+ VLD1.8 {d10},[r0],r1
+ VABD.U8 d18,d9,d8
+ VABD.U8 d19,d6,d4
+ VCGT.U8 d16,d0,d13
+ TST r12,#0xff
+ VMAX.U8 d12,d18,d12
+ VABD.U8 d17,d10,d8
+ VMOVEQ.32 d16[0],r11
+ TST r12,#0xff00
+ VCGT.U8 d19,d2,d19
+ VCGT.U8 d12,d2,d12
+ VMOVEQ.32 d16[1],r11
+ VCGT.U8 d17,d2,d17
+ VLD1.8 {d11},[r0]
+ VAND d16,d16,d12
+ TST r12,#4
+ VAND d12,d16,d17
+ VAND d17,d16,d19
+ BNE L0xf8
+ SUB r0,r0,r1,LSL #2
+ SUB r0,r0,r1
+ BL armVCM4P10_DeblockingLumabSLT4_unsafe
+ VST1.8 {d30},[r0],r1
+ VST1.8 {d29},[r0],r1
+ SUB r6,r0,r1,LSL #2
+ VST1.8 {d24},[r0],r1
+ ADDS r9,r9,r9
+ VST1.8 {d25},[r0]
+ ADD r0,r6,#8
+ BCC L0x38
+ B L0x130
+L0xe4:
+ ADD r0,r0,#8
+ ADDS r9,r9,r9
+ ADD r5,r5,#2
+ BCC L0x38
+ B L0x130
+L0xf8:
+ SUB r0,r0,r1,LSL #2
+ SUB r0,r0,r1,LSL #1
+ BL armVCM4P10_DeblockingLumabSGE4_unsafe
+ VST1.8 {d31},[r0],r1
+ VST1.8 {d30},[r0],r1
+ VST1.8 {d29},[r0],r1
+ SUB r6,r0,r1,LSL #2
+ VST1.8 {d24},[r0],r1
+ ADDS r9,r9,r9
+ VST1.8 {d25},[r0],r1
+ ADD r5,r5,#2
+ VST1.8 {d28},[r0]
+ ADD r0,r6,#8
+ BCC L0x38
+L0x130:
+ SUB r0,r0,#0x10
+ VLD1.8 {d0[]},[r7]
+ ADD r0,r0,r1,LSL #2
+ VLD1.8 {d2[]},[r8]
+ BNE L0x38
+ MOV r0,#0
+ VPOP {d8-d15}
+ POP {r4-r12,pc}
+ .endfunc
+
+ .end
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_FilterDeblockingLuma_VerEdge_I_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_FilterDeblockingLuma_VerEdge_I_s.S
new file mode 100644
index 0000000..66cc32e
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_FilterDeblockingLuma_VerEdge_I_s.S
@@ -0,0 +1,157 @@
+/*
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ */
+
+ .eabi_attribute 24, 1
+ .eabi_attribute 25, 1
+
+ .arm
+ .fpu neon
+ .text
+
+ .global omxVCM4P10_FilterDeblockingLuma_VerEdge_I
+ .func omxVCM4P10_FilterDeblockingLuma_VerEdge_I
+omxVCM4P10_FilterDeblockingLuma_VerEdge_I:
+ PUSH {r4-r12,lr}
+ VPUSH {d8-d15}
+ ADD r7,r2,#1
+ ADD r8,r3,#1
+ VLD1.8 {d0[]},[r2]
+ SUB r0,r0,#4
+ VLD1.8 {d2[]},[r3]
+ LDR r4,[sp,#0x6c]
+ LDR r5,[sp,#0x68]
+ MOV r6,#0
+ VMOV.I8 d14,#0
+ VMOV.I8 d15,#0x1
+ MOV r9,#0x11000000
+ ADD r11,r1,r1
+L0x38:
+ LDRH r12,[r4],#4
+ CMP r12,#0
+ BEQ L0x160
+ ADD r10,r0,r1
+ VLD1.8 {d7},[r0],r11
+ VLD1.8 {d8},[r10],r11
+ VLD1.8 {d5},[r0],r11
+ VZIP.8 d7,d8
+ VLD1.8 {d10},[r10],r11
+ VLD1.8 {d6},[r0],r11
+ VZIP.8 d5,d10
+ VLD1.8 {d9},[r10],r11
+ VLD1.8 {d4},[r0],r11
+ VLD1.8 {d11},[r10],r11
+ VZIP.8 d6,d9
+ VZIP.16 d8,d10
+ VZIP.8 d4,d11
+ SUB r0,r0,r1,LSL #3
+ VZIP.16 d7,d5
+ VZIP.16 d9,d11
+ VZIP.16 d6,d4
+ VTRN.32 d8,d9
+ VTRN.32 d5,d4
+ VTRN.32 d10,d11
+ VTRN.32 d7,d6
+ VABD.U8 d13,d4,d8
+ VABD.U8 d12,d5,d4
+ VABD.U8 d18,d9,d8
+ VABD.U8 d19,d6,d4
+ TST r12,#0xff
+ VCGT.U8 d16,d0,d13
+ VMAX.U8 d12,d18,d12
+ VABD.U8 d17,d10,d8
+ VMOVEQ.32 d16[0],r6
+ TST r12,#0xff00
+ VCGT.U8 d19,d2,d19
+ VCGT.U8 d12,d2,d12
+ VMOVEQ.32 d16[1],r6
+ VCGT.U8 d17,d2,d17
+ VAND d16,d16,d12
+ TST r12,#4
+ VAND d12,d16,d17
+ VAND d17,d16,d19
+ BNE L0x17c
+ BL armVCM4P10_DeblockingLumabSLT4_unsafe
+ VZIP.8 d7,d6
+ VZIP.8 d30,d29
+ VZIP.8 d24,d25
+ VZIP.8 d10,d11
+ VZIP.16 d7,d30
+ ADD r10,r0,r1
+ VZIP.16 d24,d10
+ VZIP.16 d25,d11
+ VZIP.16 d6,d29
+ VTRN.32 d7,d24
+ VTRN.32 d30,d10
+ VTRN.32 d6,d25
+ VTRN.32 d29,d11
+ VST1.8 {d7},[r0],r11
+ VST1.8 {d24},[r10],r11
+ VST1.8 {d30},[r0],r11
+ VST1.8 {d10},[r10],r11
+ VST1.8 {d6},[r0],r11
+ VST1.8 {d25},[r10],r11
+ ADDS r9,r9,r9
+ VST1.8 {d29},[r0],r11
+ ADD r5,r5,#2
+ VST1.8 {d11},[r10],r1
+ SUB r0,r0,r1,LSL #3
+ VLD1.8 {d0[]},[r7]
+ ADD r0,r0,#4
+ VLD1.8 {d2[]},[r8]
+ BCC L0x38
+ B L0x1f0
+L0x160:
+ ADD r0,r0,#4
+ ADDS r9,r9,r9
+ VLD1.8 {d0[]},[r7]
+ ADD r5,r5,#4
+ VLD1.8 {d2[]},[r8]
+ BCC L0x38
+ B L0x1f0
+L0x17c:
+ BL armVCM4P10_DeblockingLumabSGE4_unsafe
+ VZIP.8 d7,d31
+ VZIP.8 d30,d29
+ VZIP.8 d24,d25
+ VZIP.8 d28,d11
+ VZIP.16 d7,d30
+ ADD r10,r0,r1
+ VZIP.16 d24,d28
+ VZIP.16 d25,d11
+ VZIP.16 d31,d29
+ VTRN.32 d7,d24
+ VTRN.32 d30,d28
+ VTRN.32 d31,d25
+ VTRN.32 d29,d11
+ VST1.8 {d7},[r0],r11
+ VST1.8 {d24},[r10],r11
+ VST1.8 {d30},[r0],r11
+ VST1.8 {d28},[r10],r11
+ VST1.8 {d31},[r0],r11
+ VST1.8 {d25},[r10],r11
+ ADDS r9,r9,r9
+ VST1.8 {d29},[r0],r11
+ ADD r5,r5,#4
+ VST1.8 {d11},[r10],r11
+ SUB r0,r0,r1,LSL #3
+ VLD1.8 {d0[]},[r7]
+ ADD r0,r0,#4
+ VLD1.8 {d2[]},[r8]
+ BCC L0x38
+L0x1f0:
+ SUB r4,r4,#0xe
+ SUB r5,r5,#0xe
+ SUB r0,r0,#0x10
+ VLD1.8 {d0[]},[r2]
+ ADD r0,r0,r1,LSL #3
+ VLD1.8 {d2[]},[r3]
+ BNE L0x38
+ MOV r0,#0
+ VPOP {d8-d15}
+ POP {r4-r12,pc}
+ .endfunc
+
+ .end
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_InterpolateLuma_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_InterpolateLuma_s.S
new file mode 100644
index 0000000..76c3d7d
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_InterpolateLuma_s.S
@@ -0,0 +1,323 @@
+/*
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ */
+
+ .eabi_attribute 24, 1
+ .eabi_attribute 25, 1
+
+ .arm
+ .fpu neon
+ .text
+
+ .global omxVCM4P10_InterpolateLuma
+ .func omxVCM4P10_InterpolateLuma
+omxVCM4P10_InterpolateLuma:
+ PUSH {r4-r12,lr}
+ VPUSH {d8-d15}
+ SUB sp,sp,#0x10
+ LDR r6,[sp,#0x78]
+ LDR r7,[sp,#0x7c]
+ LDR r5,[sp,#0x80]
+ LDR r4,[sp,#0x84]
+ ADD r6,r6,r7,LSL #2
+ ADD r11,sp,#0
+ VMOV.I16 d31,#0x14
+ VMOV.I16 d30,#0x5
+L0x2c:
+ STM r11,{r0-r3}
+ ADD pc,pc,r6,LSL #2
+ B L0x3f0
+ B L0x78
+ B L0xa8
+ B L0xdc
+ B L0x100
+ B L0x134
+ B L0x168
+ B L0x1a8
+ B L0x1f0
+ B L0x234
+ B L0x258
+ B L0x2b0
+ B L0x2d8
+ B L0x330
+ B L0x364
+ B L0x3a8
+ B L0x3f0
+L0x78:
+ ADD r12,r0,r1,LSL #1
+ VLD1.8 {d9},[r0],r1
+ VLD1.8 {d11},[r12],r1
+ VLD1.8 {d10},[r0]
+ VLD1.8 {d12},[r12]
+ ADD r12,r2,r3,LSL #1
+ VST1.32 {d9[0]},[r2],r3
+ VST1.32 {d11[0]},[r12],r3
+ VST1.32 {d10[0]},[r2]
+ VST1.32 {d12[0]},[r12]
+ ADD r11,sp,#0
+ B L0x434
+L0xa8:
+ SUB r0,r0,#2
+ BL armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe
+ VRHADD.U8 d22,d22,d14
+ VRHADD.U8 d26,d26,d18
+ VRHADD.U8 d24,d24,d16
+ VRHADD.U8 d28,d28,d20
+ ADD r12,r2,r3,LSL #1
+ VST1.32 {d22[0]},[r2],r3
+ VST1.32 {d26[0]},[r12],r3
+ VST1.32 {d24[0]},[r2]
+ VST1.32 {d28[0]},[r12]
+ ADD r11,sp,#0
+ B L0x434
+L0xdc:
+ SUB r0,r0,#2
+ BL armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe
+ ADD r12,r2,r3,LSL #1
+ VST1.32 {d22[0]},[r2],r3
+ VST1.32 {d26[0]},[r12],r3
+ VST1.32 {d24[0]},[r2]
+ VST1.32 {d28[0]},[r12]
+ ADD r11,sp,#0
+ B L0x434
+L0x100:
+ SUB r0,r0,#2
+ BL armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe
+ VRHADD.U8 d22,d22,d15
+ VRHADD.U8 d26,d26,d19
+ VRHADD.U8 d24,d24,d17
+ VRHADD.U8 d28,d28,d21
+ ADD r12,r2,r3,LSL #1
+ VST1.32 {d22[0]},[r2],r3
+ VST1.32 {d26[0]},[r12],r3
+ VST1.32 {d24[0]},[r2]
+ VST1.32 {d28[0]},[r12]
+ ADD r11,sp,#0
+ B L0x434
+L0x134:
+ SUB r0,r0,r1,LSL #1
+ BL armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe
+ VRHADD.U8 d0,d0,d9
+ VRHADD.U8 d4,d4,d11
+ VRHADD.U8 d2,d2,d10
+ VRHADD.U8 d6,d6,d12
+ ADD r12,r2,r3,LSL #1
+ VST1.32 {d0[0]},[r2],r3
+ VST1.32 {d4[0]},[r12],r3
+ VST1.32 {d2[0]},[r2]
+ VST1.32 {d6[0]},[r12]
+ ADD r11,sp,#0
+ B L0x434
+L0x168:
+ MOV r8,r0
+ SUB r0,r0,r1,LSL #1
+ BL armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe
+ SUB r0,r8,#2
+ BL armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe
+ VRHADD.U8 d22,d22,d0
+ VRHADD.U8 d26,d26,d4
+ VRHADD.U8 d24,d24,d2
+ VRHADD.U8 d28,d28,d6
+ ADD r12,r2,r3,LSL #1
+ VST1.32 {d22[0]},[r2],r3
+ VST1.32 {d26[0]},[r12],r3
+ VST1.32 {d24[0]},[r2]
+ VST1.32 {d28[0]},[r12]
+ ADD r11,sp,#0
+ B L0x434
+L0x1a8:
+ SUB r0,r0,r1,LSL #1
+ SUB r0,r0,#2
+ BL armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe
+ VQRSHRUN.S16 d14,q7,#5
+ VQRSHRUN.S16 d16,q8,#5
+ VQRSHRUN.S16 d18,q9,#5
+ VQRSHRUN.S16 d20,q10,#5
+ VRHADD.U8 d0,d0,d14
+ VRHADD.U8 d4,d4,d18
+ VRHADD.U8 d2,d2,d16
+ VRHADD.U8 d6,d6,d20
+ ADD r12,r2,r3,LSL #1
+ VST1.32 {d0[0]},[r2],r3
+ VST1.32 {d4[0]},[r12],r3
+ VST1.32 {d2[0]},[r2]
+ VST1.32 {d6[0]},[r12]
+ ADD r11,sp,#0
+ B L0x434
+L0x1f0:
+ MOV r8,r0
+ ADD r0,r0,#1
+ SUB r0,r0,r1,LSL #1
+ BL armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe
+ SUB r0,r8,#2
+ BL armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe
+ VRHADD.U8 d22,d22,d0
+ VRHADD.U8 d26,d26,d4
+ VRHADD.U8 d24,d24,d2
+ VRHADD.U8 d28,d28,d6
+ ADD r12,r2,r3,LSL #1
+ VST1.32 {d22[0]},[r2],r3
+ VST1.32 {d26[0]},[r12],r3
+ VST1.32 {d24[0]},[r2]
+ VST1.32 {d28[0]},[r12]
+ ADD r11,sp,#0
+ B L0x434
+L0x234:
+ SUB r0,r0,r1,LSL #1
+ BL armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe
+ ADD r12,r2,r3,LSL #1
+ VST1.32 {d0[0]},[r2],r3
+ VST1.32 {d4[0]},[r12],r3
+ VST1.32 {d2[0]},[r2]
+ VST1.32 {d6[0]},[r12]
+ ADD r11,sp,#0
+ B L0x434
+L0x258:
+ SUB r0,r0,r1,LSL #1
+ SUB r0,r0,#2
+ BL armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe
+ VEXT.8 d18,d18,d19,#4
+ VEXT.8 d20,d20,d21,#4
+ VEXT.8 d22,d22,d23,#4
+ VEXT.8 d24,d24,d25,#4
+ VQRSHRUN.S16 d14,q9,#5
+ VQRSHRUN.S16 d16,q10,#5
+ VQRSHRUN.S16 d18,q11,#5
+ VQRSHRUN.S16 d20,q12,#5
+ VRHADD.U8 d0,d0,d14
+ VRHADD.U8 d4,d4,d18
+ VRHADD.U8 d2,d2,d16
+ VRHADD.U8 d6,d6,d20
+ ADD r12,r2,r3,LSL #1
+ VST1.32 {d0[0]},[r2],r3
+ VST1.32 {d4[0]},[r12],r3
+ VST1.32 {d2[0]},[r2]
+ VST1.32 {d6[0]},[r12]
+ ADD r11,sp,#0
+ B L0x434
+L0x2b0:
+ SUB r0,r0,r1,LSL #1
+ SUB r0,r0,#2
+ BL armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe
+ ADD r12,r2,r3,LSL #1
+ VST1.32 {d0[0]},[r2],r3
+ VST1.32 {d4[0]},[r12],r3
+ VST1.32 {d2[0]},[r2]
+ VST1.32 {d6[0]},[r12]
+ ADD r11,sp,#0
+ B L0x434
+L0x2d8:
+ SUB r0,r0,r1,LSL #1
+ SUB r0,r0,#2
+ BL armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe
+ VEXT.8 d18,d18,d19,#6
+ VEXT.8 d20,d20,d21,#6
+ VEXT.8 d22,d22,d23,#6
+ VEXT.8 d24,d24,d25,#6
+ VQRSHRUN.S16 d14,q9,#5
+ VQRSHRUN.S16 d16,q10,#5
+ VQRSHRUN.S16 d18,q11,#5
+ VQRSHRUN.S16 d20,q12,#5
+ VRHADD.U8 d0,d0,d14
+ VRHADD.U8 d4,d4,d18
+ VRHADD.U8 d2,d2,d16
+ VRHADD.U8 d6,d6,d20
+ ADD r12,r2,r3,LSL #1
+ VST1.32 {d0[0]},[r2],r3
+ VST1.32 {d4[0]},[r12],r3
+ VST1.32 {d2[0]},[r2]
+ VST1.32 {d6[0]},[r12]
+ ADD r11,sp,#0
+ B L0x434
+L0x330:
+ SUB r0,r0,r1,LSL #1
+ BL armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe
+ VRHADD.U8 d0,d0,d10
+ VRHADD.U8 d4,d4,d12
+ VRHADD.U8 d2,d2,d11
+ VRHADD.U8 d6,d6,d13
+ ADD r12,r2,r3,LSL #1
+ VST1.32 {d0[0]},[r2],r3
+ VST1.32 {d4[0]},[r12],r3
+ VST1.32 {d2[0]},[r2]
+ VST1.32 {d6[0]},[r12]
+ ADD r11,sp,#0
+ B L0x434
+L0x364:
+ MOV r8,r0
+ SUB r0,r0,r1,LSL #1
+ BL armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe
+ ADD r0,r8,r1
+ SUB r0,r0,#2
+ BL armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe
+ VRHADD.U8 d22,d22,d0
+ VRHADD.U8 d26,d26,d4
+ VRHADD.U8 d24,d24,d2
+ VRHADD.U8 d28,d28,d6
+ ADD r12,r2,r3,LSL #1
+ VST1.32 {d22[0]},[r2],r3
+ VST1.32 {d26[0]},[r12],r3
+ VST1.32 {d24[0]},[r2]
+ VST1.32 {d28[0]},[r12]
+ ADD r11,sp,#0
+ B L0x434
+L0x3a8:
+ SUB r0,r0,r1,LSL #1
+ SUB r0,r0,#2
+ BL armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe
+ VQRSHRUN.S16 d14,q8,#5
+ VQRSHRUN.S16 d16,q9,#5
+ VQRSHRUN.S16 d18,q10,#5
+ VQRSHRUN.S16 d20,q11,#5
+ VRHADD.U8 d0,d0,d14
+ VRHADD.U8 d4,d4,d18
+ VRHADD.U8 d2,d2,d16
+ VRHADD.U8 d6,d6,d20
+ ADD r12,r2,r3,LSL #1
+ VST1.32 {d0[0]},[r2],r3
+ VST1.32 {d4[0]},[r12],r3
+ VST1.32 {d2[0]},[r2]
+ VST1.32 {d6[0]},[r12]
+ ADD r11,sp,#0
+ B L0x434
+L0x3f0:
+ MOV r8,r0
+ ADD r0,r0,#1
+ SUB r0,r0,r1,LSL #1
+ BL armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe
+ ADD r0,r8,r1
+ SUB r0,r0,#2
+ BL armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe
+ VRHADD.U8 d22,d22,d0
+ VRHADD.U8 d26,d26,d4
+ VRHADD.U8 d24,d24,d2
+ VRHADD.U8 d28,d28,d6
+ ADD r12,r2,r3,LSL #1
+ VST1.32 {d22[0]},[r2],r3
+ VST1.32 {d26[0]},[r12],r3
+ VST1.32 {d24[0]},[r2]
+ VST1.32 {d28[0]},[r12]
+ ADD r11,sp,#0
+L0x434:
+ LDM r11,{r0-r3}
+ SUBS r5,r5,#4
+ ADD r0,r0,#4
+ ADD r2,r2,#4
+ BGT L0x2c
+ SUBS r4,r4,#4
+ LDR r5,[sp,#0x80]
+ ADD r11,sp,#0
+ ADD r0,r0,r1,LSL #2
+ ADD r2,r2,r3,LSL #2
+ SUB r0,r0,r5
+ SUB r2,r2,r5
+ BGT L0x2c
+ MOV r0,#0
+ ADD sp,sp,#0x10
+ VPOP {d8-d15}
+ POP {r4-r12,pc}
+ .endfunc
+
+ .end
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_PredictIntraChroma_8x8_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_PredictIntraChroma_8x8_s.S
new file mode 100644
index 0000000..0d49e4b
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_PredictIntraChroma_8x8_s.S
@@ -0,0 +1,217 @@
+/*
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ */
+
+ .eabi_attribute 24, 1
+ .eabi_attribute 25, 1
+
+ .arm
+ .fpu neon
+ .section .rodata
+ .align 4
+
+armVCM4P10_pIndexTable8x8:
+ .word OMX_VC_CHROMA_DC, OMX_VC_CHROMA_HOR
+ .word OMX_VC_CHROMA_VERT, OMX_VC_CHROMA_PLANE
+
+armVCM4P10_MultiplierTableChroma8x8:
+ .hword 3, 2, 1,4
+ .hword -3,-2,-1,0
+ .hword 1, 2, 3,4
+
+
+ .text
+ .global omxVCM4P10_PredictIntraChroma_8x8
+ .func omxVCM4P10_PredictIntraChroma_8x8
+omxVCM4P10_PredictIntraChroma_8x8:
+ PUSH {r4-r10,lr}
+ VPUSH {d8-d15}
+ LDR r8, =armVCM4P10_pIndexTable8x8
+ LDR r6,[sp,#0x68]
+ LDR r4,[sp,#0x60]
+ LDR r5,[sp,#0x64]
+ LDR r7,[sp,#0x6c]
+ LDR pc,[r8,r6,LSL #2]
+OMX_VC_CHROMA_DC:
+ TST r7,#2
+ BEQ L0xe8
+ ADD r9,r0,r4
+ ADD r10,r4,r4
+ VLD1.8 {d1[0]},[r0],r10
+ VLD1.8 {d1[1]},[r9],r10
+ VLD1.8 {d1[2]},[r0],r10
+ VLD1.8 {d1[3]},[r9],r10
+ VLD1.8 {d1[4]},[r0],r10
+ VLD1.8 {d1[5]},[r9],r10
+ VLD1.8 {d1[6]},[r0],r10
+ VLD1.8 {d1[7]},[r9]
+ TST r7,#1
+ BEQ L0xcc
+ VLD1.8 {d0},[r1]
+ MOV r0,#0
+ VPADDL.U8 d2,d0
+ VPADDL.U16 d3,d2
+ VPADDL.U8 d2,d1
+ VPADDL.U16 d1,d2
+ VADD.I32 d2,d3,d1
+ VRSHR.U32 d2,d2,#3
+ VRSHR.U32 d3,d3,#2
+ VRSHR.U32 d1,d1,#2
+ VMOV.I8 d5,#0xc
+ VMOV.I8 d6,#0x4
+ VSHL.I64 d5,d5,#32
+ VSHR.U64 d6,d6,#32
+ VADD.I8 d6,d6,d5
+ VTBL.8 d0,{d2-d3},d5
+ VTBL.8 d4,{d1-d2},d6
+L0x9c:
+ ADD r9,r3,r5
+ ADD r10,r5,r5
+ VST1.8 {d0},[r3],r10
+ VST1.8 {d0},[r9],r10
+ VST1.8 {d0},[r3],r10
+ VST1.8 {d0},[r9],r10
+ VST1.8 {d4},[r3],r10
+ VST1.8 {d4},[r9],r10
+ VST1.8 {d4},[r3],r10
+ VST1.8 {d4},[r9]
+ VPOP {d8-d15}
+ POP {r4-r10,pc}
+L0xcc:
+ MOV r0,#0
+ VPADDL.U8 d2,d1
+ VPADDL.U16 d1,d2
+ VRSHR.U32 d1,d1,#2
+ VDUP.8 d0,d1[0]
+ VDUP.8 d4,d1[4]
+ B L0x9c
+L0xe8:
+ TST r7,#1
+ BEQ L0x114
+ VLD1.8 {d0},[r1]
+ MOV r0,#0
+ VPADDL.U8 d2,d0
+ VPADDL.U16 d3,d2
+ VRSHR.U32 d3,d3,#2
+ VMOV.I8 d5,#0x4
+ VSHL.I64 d5,d5,#32
+ VTBL.8 d0,{d3},d5
+ B L0x11c
+L0x114:
+ VMOV.I8 d0,#0x80
+ MOV r0,#0
+L0x11c:
+ ADD r9,r3,r5
+ ADD r10,r5,r5
+ VST1.8 {d0},[r3],r10
+ VST1.8 {d0},[r9],r10
+ VST1.8 {d0},[r3],r10
+ VST1.8 {d0},[r9],r10
+ VST1.8 {d0},[r3],r10
+ VST1.8 {d0},[r9],r10
+ VST1.8 {d0},[r3],r10
+ VST1.8 {d0},[r9]
+ VPOP {d8-d15}
+ POP {r4-r10,pc}
+OMX_VC_CHROMA_VERT:
+ VLD1.8 {d0},[r1]
+ MOV r0,#0
+ B L0x11c
+OMX_VC_CHROMA_HOR:
+ ADD r9,r0,r4
+ ADD r10,r4,r4
+ VLD1.8 {d0[]},[r0],r10
+ VLD1.8 {d1[]},[r9],r10
+ VLD1.8 {d2[]},[r0],r10
+ VLD1.8 {d3[]},[r9],r10
+ VLD1.8 {d4[]},[r0],r10
+ VLD1.8 {d5[]},[r9],r10
+ VLD1.8 {d6[]},[r0],r10
+ VLD1.8 {d7[]},[r9]
+ B L0x28c
+OMX_VC_CHROMA_PLANE:
+ ADD r9,r0,r4
+ ADD r10,r4,r4
+ VLD1.8 {d0},[r1]
+ VLD1.8 {d2[0]},[r2]
+ VLD1.8 {d1[0]},[r0],r10
+ VLD1.8 {d1[1]},[r9],r10
+ VLD1.8 {d1[2]},[r0],r10
+ VLD1.8 {d1[3]},[r9],r10
+ VLD1.8 {d1[4]},[r0],r10
+ VLD1.8 {d1[5]},[r9],r10
+ VLD1.8 {d1[6]},[r0],r10
+ VLD1.8 {d1[7]},[r9]
+ VREV64.8 d3,d0
+ VSUBL.U8 q3,d3,d2
+ VSHR.U64 d3,d3,#8
+ VSUBL.U8 q2,d3,d0
+ VREV64.8 d3,d1
+ VSUBL.U8 q7,d3,d2
+ VSHR.U64 d3,d3,#8
+ VSUBL.U8 q6,d3,d1
+ LDR r2, =armVCM4P10_MultiplierTableChroma8x8
+ VSHL.I64 d4,d4,#16
+ VEXT.8 d9,d4,d6,#2
+ VLD1.16 {d10},[r2]!
+ VSHL.I64 d12,d12,#16
+ VEXT.8 d16,d12,d14,#2
+ VMUL.I16 d11,d9,d10
+ VMUL.I16 d3,d16,d10
+ VPADD.I16 d3,d11,d3
+ VPADDL.S16 d3,d3
+ VSHL.I32 d2,d3,#4
+ VADD.I32 d3,d3,d2
+ VLD1.16 {d10,d11},[r2]
+ VRSHR.S32 d3,d3,#5
+ VADDL.U8 q0,d0,d1
+ VDUP.16 q0,d1[3]
+ VSHL.I16 q0,q0,#4
+ VDUP.16 q2,d3[0]
+ VDUP.16 q3,d3[2]
+ VMUL.I16 q2,q2,q5
+ VMUL.I16 q3,q3,q5
+ VADD.I16 q2,q2,q0
+ VDUP.16 q0,d6[0]
+ VDUP.16 q1,d6[1]
+ VDUP.16 q4,d6[2]
+ VDUP.16 q5,d6[3]
+ VDUP.16 q6,d7[0]
+ VDUP.16 q7,d7[1]
+ VDUP.16 q8,d7[2]
+ VDUP.16 q9,d7[3]
+ VADD.I16 q0,q2,q0
+ VADD.I16 q1,q2,q1
+ VADD.I16 q4,q2,q4
+ VADD.I16 q5,q2,q5
+ VADD.I16 q6,q2,q6
+ VADD.I16 q7,q2,q7
+ VADD.I16 q8,q2,q8
+ VADD.I16 q9,q2,q9
+ VQRSHRUN.S16 d0,q0,#5
+ VQRSHRUN.S16 d1,q1,#5
+ VQRSHRUN.S16 d2,q4,#5
+ VQRSHRUN.S16 d3,q5,#5
+ VQRSHRUN.S16 d4,q6,#5
+ VQRSHRUN.S16 d5,q7,#5
+ VQRSHRUN.S16 d6,q8,#5
+ VQRSHRUN.S16 d7,q9,#5
+L0x28c:
+ ADD r9,r3,r5
+ ADD r10,r5,r5
+ VST1.8 {d0},[r3],r10
+ VST1.8 {d1},[r9],r10
+ VST1.8 {d2},[r3],r10
+ VST1.8 {d3},[r9],r10
+ VST1.8 {d4},[r3],r10
+ VST1.8 {d5},[r9],r10
+ VST1.8 {d6},[r3],r10
+ VST1.8 {d7},[r9]
+ MOV r0,#0
+ VPOP {d8-d15}
+ POP {r4-r10,pc}
+ .endfunc
+
+ .end
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_PredictIntra_16x16_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_PredictIntra_16x16_s.S
new file mode 100644
index 0000000..53268f6
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_PredictIntra_16x16_s.S
@@ -0,0 +1,239 @@
+/*
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ */
+
+ .eabi_attribute 24, 1
+ .eabi_attribute 25, 1
+
+ .arm
+ .fpu neon
+
+ .section .rodata
+ .align 4
+;//-------------------------------------------------------
+;// This table for implementing switch case of C in asm by
+;// the mehtod of two levels of indexing.
+;//-------------------------------------------------------
+
+armVCM4P10_pIndexTable16x16:
+ .word OMX_VC_16X16_VERT, OMX_VC_16X16_HOR
+ .word OMX_VC_16X16_DC, OMX_VC_16X16_PLANE
+
+
+
+armVCM4P10_MultiplierTable16x16:
+ .hword 7, 6, 5, 4, 3, 2, 1, 8
+ .hword 0, 1, 2, 3, 4, 5, 6, 7
+ .hword 8, 9, 10, 11, 12, 13, 14, 15
+
+ .text
+
+ .global omxVCM4P10_PredictIntra_16x16
+ .func omxVCM4P10_PredictIntra_16x16
+omxVCM4P10_PredictIntra_16x16:
+ PUSH {r4-r12,lr}
+ VPUSH {d8-d15}
+ LDR r9, =armVCM4P10_pIndexTable16x16
+ LDR r6,[sp,#0x70]
+ LDR r4,[sp,#0x68]
+ LDR r5,[sp,#0x6c]
+ LDR r7,[sp,#0x74]
+ MOV r12,#0x10
+ LDR pc,[r9,r6,LSL #2]
+OMX_VC_16X16_VERT:
+ VLD1.8 {d0,d1},[r1]
+ ADD r8,r3,r5
+ ADD r10,r5,r5
+ VST1.8 {d0,d1},[r3],r10
+ VST1.8 {d0,d1},[r8],r10
+ VST1.8 {d0,d1},[r3],r10
+ VST1.8 {d0,d1},[r8],r10
+ VST1.8 {d0,d1},[r3],r10
+ VST1.8 {d0,d1},[r8],r10
+ VST1.8 {d0,d1},[r3],r10
+ VST1.8 {d0,d1},[r8],r10
+ VST1.8 {d0,d1},[r3],r10
+ VST1.8 {d0,d1},[r8],r10
+ VST1.8 {d0,d1},[r3],r10
+ VST1.8 {d0,d1},[r8],r10
+ VST1.8 {d0,d1},[r3],r10
+ VST1.8 {d0,d1},[r8],r10
+ VST1.8 {d0,d1},[r3]
+ VST1.8 {d0,d1},[r8]
+ MOV r0,#0
+ VPOP {d8-d15}
+ POP {r4-r12,pc}
+OMX_VC_16X16_HOR:
+ ADD r8,r0,r4
+ ADD r4,r4,r4
+ ADD r11,r3,r5
+ ADD r5,r5,r5
+L0x8c:
+ VLD1.8 {d2[],d3[]},[r0],r4
+ VLD1.8 {d0[],d1[]},[r8],r4
+ SUBS r12,r12,#8
+ VST1.8 {d2,d3},[r3],r5
+ VST1.8 {d0,d1},[r11],r5
+ VLD1.8 {d2[],d3[]},[r0],r4
+ VLD1.8 {d0[],d1[]},[r8],r4
+ VST1.8 {d2,d3},[r3],r5
+ VST1.8 {d0,d1},[r11],r5
+ VLD1.8 {d2[],d3[]},[r0],r4
+ VLD1.8 {d0[],d1[]},[r8],r4
+ VST1.8 {d2,d3},[r3],r5
+ VST1.8 {d0,d1},[r11],r5
+ VLD1.8 {d2[],d3[]},[r0],r4
+ VLD1.8 {d0[],d1[]},[r8],r4
+ VST1.8 {d2,d3},[r3],r5
+ VST1.8 {d0,d1},[r11],r5
+ BNE L0x8c
+ MOV r0,#0
+ VPOP {d8-d15}
+ POP {r4-r12,pc}
+OMX_VC_16X16_DC:
+ MOV r11,#0
+ TST r7,#2
+ BEQ L0x14c
+ ADD r8,r0,r4
+ ADD r10,r4,r4
+ VLD1.8 {d2[0]},[r0],r10
+ VLD1.8 {d2[1]},[r8],r10
+ VLD1.8 {d2[2]},[r0],r10
+ VLD1.8 {d2[3]},[r8],r10
+ VLD1.8 {d2[4]},[r0],r10
+ VLD1.8 {d2[5]},[r8],r10
+ VLD1.8 {d2[6]},[r0],r10
+ VLD1.8 {d2[7]},[r8],r10
+ VLD1.8 {d3[0]},[r0],r10
+ VLD1.8 {d3[1]},[r8],r10
+ VLD1.8 {d3[2]},[r0],r10
+ VLD1.8 {d3[3]},[r8],r10
+ VLD1.8 {d3[4]},[r0],r10
+ VLD1.8 {d3[5]},[r8],r10
+ VLD1.8 {d3[6]},[r0],r10
+ VLD1.8 {d3[7]},[r8]
+ VPADDL.U8 q0,q1
+ ADD r11,r11,#1
+ VPADD.I16 d0,d0,d1
+ VPADDL.U16 d0,d0
+ VPADDL.U32 d6,d0
+ VRSHR.U64 d8,d6,#4
+L0x14c:
+ TST r7,#1
+ BEQ L0x170
+ VLD1.8 {d0,d1},[r1]
+ ADD r11,r11,#1
+ VPADDL.U8 q0,q0
+ VPADD.I16 d0,d0,d1
+ VPADDL.U16 d0,d0
+ VPADDL.U32 d7,d0
+ VRSHR.U64 d8,d7,#4
+L0x170:
+ CMP r11,#2
+ BNE L0x180
+ VADD.I64 d8,d7,d6
+ VRSHR.U64 d8,d8,#5
+L0x180:
+ VDUP.8 q3,d8[0]
+ CMP r11,#0
+ ADD r8,r3,r5
+ ADD r10,r5,r5
+ BNE L0x198
+ VMOV.I8 q3,#0x80
+L0x198:
+ VST1.8 {d6,d7},[r3],r10
+ VST1.8 {d6,d7},[r8],r10
+ VST1.8 {d6,d7},[r3],r10
+ VST1.8 {d6,d7},[r8],r10
+ VST1.8 {d6,d7},[r3],r10
+ VST1.8 {d6,d7},[r8],r10
+ VST1.8 {d6,d7},[r3],r10
+ VST1.8 {d6,d7},[r8],r10
+ VST1.8 {d6,d7},[r3],r10
+ VST1.8 {d6,d7},[r8],r10
+ VST1.8 {d6,d7},[r3],r10
+ VST1.8 {d6,d7},[r8],r10
+ VST1.8 {d6,d7},[r3],r10
+ VST1.8 {d6,d7},[r8],r10
+ VST1.8 {d6,d7},[r3],r10
+ VST1.8 {d6,d7},[r8],r10
+ MOV r0,#0
+ VPOP {d8-d15}
+ POP {r4-r12,pc}
+OMX_VC_16X16_PLANE:
+ LDR r9, =armVCM4P10_MultiplierTable16x16
+ VLD1.8 {d0,d1},[r1]
+ VLD1.8 {d4[0]},[r2]
+ ADD r8,r0,r4
+ ADD r10,r4,r4
+ VLD1.8 {d2[0]},[r0],r10
+ VLD1.8 {d2[1]},[r8],r10
+ VLD1.8 {d2[2]},[r0],r10
+ VLD1.8 {d2[3]},[r8],r10
+ VLD1.8 {d2[4]},[r0],r10
+ VLD1.8 {d2[5]},[r8],r10
+ VLD1.8 {d2[6]},[r0],r10
+ VLD1.8 {d2[7]},[r8],r10
+ VLD1.8 {d3[0]},[r0],r10
+ VLD1.8 {d3[1]},[r8],r10
+ VLD1.8 {d3[2]},[r0],r10
+ VLD1.8 {d3[3]},[r8],r10
+ VLD1.8 {d3[4]},[r0],r10
+ VLD1.8 {d3[5]},[r8],r10
+ VLD1.8 {d3[6]},[r0],r10
+ VLD1.8 {d3[7]},[r8]
+ VREV64.8 d5,d1
+ VSUBL.U8 q3,d5,d4
+ VSHR.U64 d5,d5,#8
+ VSUBL.U8 q4,d5,d0
+ VSHL.I64 d9,d9,#16
+ VEXT.8 d9,d9,d6,#2
+ VREV64.8 d12,d3
+ VSUBL.U8 q7,d12,d4
+ VSHR.U64 d12,d12,#8
+ VSUBL.U8 q8,d12,d2
+ VLD1.16 {d20,d21},[r9]!
+ VSHL.I64 d17,d17,#16
+ VEXT.8 d17,d17,d14,#2
+ VMULL.S16 q11,d8,d20
+ VMULL.S16 q12,d16,d20
+ VMLAL.S16 q11,d9,d21
+ VMLAL.S16 q12,d17,d21
+ VPADD.I32 d22,d23,d22
+ VPADD.I32 d23,d25,d24
+ VPADDL.S32 q11,q11
+ VSHL.I64 q12,q11,#2
+ VADD.I64 q11,q11,q12
+ VRSHR.S64 q11,q11,#6
+ VSHL.I64 q12,q11,#3
+ VSUB.I64 q12,q12,q11
+ VLD1.16 {d20,d21},[r9]!
+ VDUP.16 q6,d22[0]
+ VDUP.16 q7,d23[0]
+ VADDL.U8 q11,d1,d3
+ VSHL.I16 q11,q11,#4
+ VDUP.16 q11,d23[3]
+ VADD.I64 d1,d24,d25
+ VLD1.16 {d24,d25},[r9]
+ VDUP.16 q13,d1[0]
+ VSUB.I16 q13,q11,q13
+ VMUL.I16 q5,q6,q10
+ VMUL.I16 q6,q6,q12
+ VADD.I16 q0,q5,q13
+ VADD.I16 q1,q6,q13
+L0x2d4:
+ VQRSHRUN.S16 d6,q0,#5
+ VQRSHRUN.S16 d7,q1,#5
+ SUBS r12,r12,#1
+ VST1.8 {d6,d7},[r3],r5
+ VADD.I16 q0,q0,q7
+ VADD.I16 q1,q1,q7
+ BNE L0x2d4
+ MOV r0,#0
+ VPOP {d8-d15}
+ POP {r4-r12,pc}
+ .endfunc
+
+ .end
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_PredictIntra_4x4_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_PredictIntra_4x4_s.S
new file mode 100644
index 0000000..aa6d7ef
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_PredictIntra_4x4_s.S
@@ -0,0 +1,261 @@
+/*
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ */
+
+ .eabi_attribute 24, 1
+ .eabi_attribute 25, 1
+
+ .arm
+ .fpu neon
+
+ .section .rodata
+ .align 4
+
+armVCM4P10_pSwitchTable4x4:
+ .word OMX_VC_4x4_VERT, OMX_VC_4x4_HOR
+ .word OMX_VC_4x4_DC, OMX_VC_4x4_DIAG_DL
+ .word OMX_VC_4x4_DIAG_DR, OMX_VC_4x4_VR
+ .word OMX_VC_4x4_HD, OMX_VC_4x4_VL
+ .word OMX_VC_4x4_HU
+
+ .text
+
+ .global omxVCM4P10_PredictIntra_4x4
+ .func omxVCM4P10_PredictIntra_4x4
+omxVCM4P10_PredictIntra_4x4:
+ PUSH {r4-r12,lr}
+ VPUSH {d8-d12}
+ LDR r8, =armVCM4P10_pSwitchTable4x4
+ LDRD r6,r7,[sp,#0x58]
+ LDRD r4,r5,[sp,#0x50]
+ LDR pc,[r8,r6,LSL #2]
+OMX_VC_4x4_HOR:
+ ADD r9,r0,r4
+ ADD r10,r4,r4
+ VLD1.8 {d0[]},[r0],r10
+ VLD1.8 {d1[]},[r9],r10
+ VLD1.8 {d2[]},[r0]
+ VLD1.8 {d3[]},[r9]
+ ADD r11,r3,r5
+ ADD r12,r5,r5
+ VST1.32 {d0[0]},[r3],r12
+ VST1.32 {d1[0]},[r11],r12
+ VST1.32 {d2[0]},[r3]
+ VST1.32 {d3[0]},[r11]
+ B L0x348
+OMX_VC_4x4_VERT:
+ VLD1.32 {d0[0]},[r1]
+ ADD r11,r3,r5
+ ADD r12,r5,r5
+L0x58:
+ VST1.32 {d0[0]},[r3],r12
+ VST1.32 {d0[0]},[r11],r12
+ VST1.32 {d0[0]},[r3]
+ VST1.32 {d0[0]},[r11]
+ B L0x348
+OMX_VC_4x4_DC:
+ TST r7,#2
+ BEQ L0xdc
+ ADD r9,r0,r4
+ ADD r10,r4,r4
+ VLD1.8 {d0[0]},[r0],r10
+ VLD1.8 {d0[1]},[r9],r10
+ VLD1.8 {d0[2]},[r0]
+ VLD1.8 {d0[3]},[r9]
+ TST r7,#1
+ BEQ L0xbc
+ VLD1.32 {d0[1]},[r1]
+ MOV r0,#0
+ VPADDL.U8 d1,d0
+ VPADDL.U16 d1,d1
+ VPADDL.U32 d1,d1
+ VRSHR.U64 d1,d1,#3
+ ADD r11,r3,r5
+ ADD r12,r5,r5
+ VDUP.8 d0,d1[0]
+ B L0x58
+L0xbc:
+ MOV r0,#0
+ VPADDL.U8 d1,d0
+ VPADDL.U16 d1,d1
+ VRSHR.U32 d1,d1,#2
+ ADD r11,r3,r5
+ ADD r12,r5,r5
+ VDUP.8 d0,d1[0]
+ B L0x58
+L0xdc:
+ TST r7,#1
+ BEQ L0x108
+ VLD1.32 {d0[0]},[r1]
+ MOV r0,#0
+ VPADDL.U8 d1,d0
+ VPADDL.U16 d1,d1
+ VRSHR.U32 d1,d1,#2
+ ADD r11,r3,r5
+ ADD r12,r5,r5
+ VDUP.8 d0,d1[0]
+ B L0x58
+L0x108:
+ VMOV.I8 d0,#0x80
+ MOV r0,#0
+ ADD r11,r3,r5
+ ADD r12,r5,r5
+ B L0x58
+OMX_VC_4x4_DIAG_DL:
+ TST r7,#0x40
+ BEQ L0x138
+ VLD1.8 {d3},[r1]
+ VDUP.8 d2,d3[7]
+ VEXT.8 d4,d3,d2,#1
+ VEXT.8 d5,d3,d2,#2
+ B L0x14c
+L0x138:
+ VLD1.32 {d0[1]},[r1]
+ VDUP.8 d2,d0[7]
+ VEXT.8 d3,d0,d2,#4
+ VEXT.8 d4,d0,d2,#5
+ VEXT.8 d5,d0,d2,#6
+L0x14c:
+ VHADD.U8 d6,d3,d5
+ VRHADD.U8 d6,d6,d4
+ VST1.32 {d6[0]},[r3],r5
+ VEXT.8 d6,d6,d6,#1
+ VST1.32 {d6[0]},[r3],r5
+ VEXT.8 d6,d6,d6,#1
+ VST1.32 {d6[0]},[r3],r5
+ VEXT.8 d6,d6,d6,#1
+ VST1.32 {d6[0]},[r3]
+ B L0x348
+OMX_VC_4x4_DIAG_DR:
+ VLD1.32 {d0[0]},[r1]
+ VLD1.8 {d1[7]},[r2]
+ ADD r9,r0,r4
+ ADD r10,r4,r4
+ ADD r1,r3,r5
+ VLD1.8 {d1[6]},[r0],r10
+ VLD1.8 {d1[5]},[r9],r10
+ VLD1.8 {d1[4]},[r0]
+ VLD1.8 {d1[3]},[r9]
+ VEXT.8 d3,d1,d0,#3
+ ADD r4,r1,r5
+ VEXT.8 d4,d1,d0,#4
+ ADD r6,r4,r5
+ VEXT.8 d5,d1,d0,#5
+ VHADD.U8 d6,d3,d5
+ VRHADD.U8 d6,d6,d4
+ VST1.32 {d6[0]},[r6]
+ VEXT.8 d6,d6,d6,#1
+ VST1.32 {d6[0]},[r4]
+ VEXT.8 d6,d6,d6,#1
+ VST1.32 {d6[0]},[r1]
+ VEXT.8 d6,d6,d6,#1
+ VST1.32 {d6[0]},[r3]
+ B L0x348
+OMX_VC_4x4_VR:
+ VLD1.32 {d0[0]},[r1]
+ VLD1.8 {d0[7]},[r2]
+ VLD1.8 {d1[7]},[r0],r4
+ VLD1.8 {d2[7]},[r0],r4
+ VLD1.8 {d1[6]},[r0]
+ VEXT.8 d12,d0,d0,#7
+ VEXT.8 d3,d1,d12,#6
+ VEXT.8 d4,d2,d12,#7
+ VEXT.8 d5,d1,d0,#7
+ VEXT.8 d6,d2,d0,#7
+ VEXT.8 d11,d1,d12,#7
+ VHADD.U8 d8,d6,d12
+ VRHADD.U8 d8,d8,d11
+ VHADD.U8 d7,d3,d5
+ VRHADD.U8 d7,d7,d4
+ VEXT.8 d10,d8,d8,#1
+ ADD r11,r3,r5
+ ADD r12,r5,r5
+ VEXT.8 d9,d7,d7,#1
+ VST1.32 {d10[0]},[r3],r12
+ VST1.32 {d9[0]},[r11],r12
+ VST1.32 {d8[0]},[r3],r12
+ VST1.32 {d7[0]},[r11]
+ B L0x348
+OMX_VC_4x4_HD:
+ VLD1.8 {d0},[r1]
+ VLD1.8 {d1[7]},[r2]
+ ADD r9,r0,r4
+ ADD r10,r4,r4
+ VLD1.8 {d1[6]},[r0],r10
+ VLD1.8 {d1[5]},[r9],r10
+ VLD1.8 {d1[4]},[r0]
+ VLD1.8 {d1[3]},[r9]
+ VEXT.8 d3,d1,d0,#3
+ VEXT.8 d4,d1,d0,#2
+ VEXT.8 d5,d1,d0,#1
+ VHADD.U8 d7,d3,d5
+ VRHADD.U8 d7,d7,d4
+ VRHADD.U8 d8,d4,d3
+ VSHL.I64 d8,d8,#24
+ VSHL.I64 d6,d7,#16
+ VZIP.8 d8,d6
+ VEXT.8 d7,d7,d7,#6
+ VEXT.8 d8,d6,d7,#2
+ ADD r11,r3,r5
+ ADD r12,r5,r5
+ VST1.32 {d8[1]},[r3],r12
+ VST1.32 {d6[1]},[r11],r12
+ VST1.32 {d8[0]},[r3]
+ VST1.32 {d6[0]},[r11]
+ B L0x348
+OMX_VC_4x4_VL:
+ TST r7,#0x40
+ BEQ L0x2b4
+ VLD1.8 {d3},[r1]
+ VEXT.8 d4,d3,d3,#1
+ VEXT.8 d5,d4,d4,#1
+ B L0x2c8
+L0x2b4:
+ VLD1.32 {d0[1]},[r1]
+ VDUP.8 d2,d0[7]
+ VEXT.8 d3,d0,d2,#4
+ VEXT.8 d4,d0,d2,#5
+ VEXT.8 d5,d0,d2,#6
+L0x2c8:
+ VRHADD.U8 d7,d4,d3
+ VHADD.U8 d10,d3,d5
+ VRHADD.U8 d10,d10,d4
+ VEXT.8 d8,d7,d7,#1
+ ADD r11,r3,r5
+ ADD r12,r5,r5
+ VEXT.8 d9,d10,d8,#1
+ VST1.32 {d7[0]},[r3],r12
+ VST1.32 {d10[0]},[r11],r12
+ VST1.32 {d8[0]},[r3]
+ VST1.32 {d9[0]},[r11]
+ B L0x348
+OMX_VC_4x4_HU:
+ ADD r9,r0,r4
+ ADD r10,r4,r4
+ VLD1.8 {d1[4]},[r0],r10
+ VLD1.8 {d1[5]},[r9],r10
+ VLD1.8 {d1[6]},[r0]
+ VLD1.8 {d1[7]},[r9]
+ VDUP.8 d2,d1[7]
+ VEXT.8 d3,d1,d2,#4
+ VEXT.8 d4,d1,d2,#5
+ VEXT.8 d5,d1,d2,#6
+ VHADD.U8 d7,d3,d5
+ VRHADD.U8 d7,d7,d4
+ VRHADD.U8 d8,d4,d3
+ VZIP.8 d8,d7
+ VST1.32 {d8[0]},[r3],r5
+ VEXT.8 d8,d8,d8,#2
+ VST1.32 {d8[0]},[r3],r5
+ VEXT.8 d8,d8,d8,#2
+ VST1.32 {d8[0]},[r3],r5
+ VST1.32 {d7[0]},[r3]
+L0x348:
+ MOV r0,#0
+ VPOP {d8-d12}
+ POP {r4-r12,pc}
+ .endfunc
+
+ .end
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_TransformDequantChromaDCFromPair_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_TransformDequantChromaDCFromPair_s.S
new file mode 100644
index 0000000..28a89cb
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_TransformDequantChromaDCFromPair_s.S
@@ -0,0 +1,54 @@
+/*
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ */
+
+ .eabi_attribute 24, 1
+ .eabi_attribute 25, 1
+
+ .arm
+ .fpu neon
+ .text
+
+ .global omxVCM4P10_TransformDequantChromaDCFromPair
+ .func omxVCM4P10_TransformDequantChromaDCFromPair
+omxVCM4P10_TransformDequantChromaDCFromPair:
+ push {r4-r10, lr}
+ ldr r9, [r0,#0]
+ vmov.i16 d0, #0
+ mov r8, #0x1f
+ vst1.16 {d0}, [r1]
+ ldrb r6, [r9], #1
+unpackLoop:
+ tst r6, #0x10
+ ldrnesb r5, [r9, #1]
+ ldrneb r4, [r9], #2
+ and r7, r8, r6, lsl #1
+ ldreqsb r4, [r9], #1
+ orrne r4, r4, r5, lsl #8
+ tst r6, #0x20
+ ldreqb r6, [r9], #1
+ strh r4, [r1, r7]
+ beq unpackLoop
+ ldmia r1, {r3, r4}
+ str r9, [r0, #0]
+ ldr r5, =armVCM4P10_QPDivTable
+ ldr r6, =armVCM4P10_VMatrixQPModTable
+ saddsubx r3, r3, r3
+ saddsubx r4, r4, r4
+ ldrsb r9, [r5, r2]
+ ldrsb r2, [r6, r2]
+ sadd16 r5, r3, r4
+ ssub16 r6, r3, r4
+ lsl r2, r2, r9
+ vmov d0, r5, r6
+ vrev32.16 d0, d0
+ vdup.16 d1, r2
+ vmull.s16 q1, d0, d1
+ vshrn.i32 d2, q1, #1
+ vst1.16 {d2}, [r1]
+ mov r0, #0
+ pop {r4-r10, pc}
+ .endfunc
+
+ .end
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_TransformDequantLumaDCFromPair_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_TransformDequantLumaDCFromPair_s.S
new file mode 100644
index 0000000..a3a0715
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_TransformDequantLumaDCFromPair_s.S
@@ -0,0 +1,76 @@
+/*
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ */
+
+ .eabi_attribute 24, 1
+ .eabi_attribute 25, 1
+
+ .arm
+ .fpu neon
+ .text
+
+ .global armVCM4P10_InvTransformDequantLumaDC4x4
+ .func armVCM4P10_InvTransformDequantLumaDC4x4
+armVCM4P10_InvTransformDequantLumaDC4x4:
+ PUSH {r4-r6,lr}
+ VPUSH {d8-d13}
+ VLD4.16 {d0,d1,d2,d3},[r0]
+ LDR r2, =armVCM4P10_QPDivTable
+ LDR r3, =armVCM4P10_VMatrixQPModTable
+ VADD.I16 d4,d0,d1
+ VADD.I16 d5,d2,d3
+ VSUB.I16 d6,d0,d1
+ LDRSB r4,[r2,r1]
+ VSUB.I16 d7,d2,d3
+ LDRSB r5,[r3,r1]
+ VADD.I16 d0,d4,d5
+ VSUB.I16 d1,d4,d5
+ VSUB.I16 d2,d6,d7
+ LSL r5,r5,r4
+ VADD.I16 d3,d6,d7
+ VTRN.16 d0,d1
+ VTRN.16 d2,d3
+ VTRN.32 q0,q1
+ VADD.I16 d4,d0,d1
+ VADD.I16 d5,d2,d3
+ VSUB.I16 d6,d0,d1
+ VSUB.I16 d7,d2,d3
+ VADD.I16 d0,d4,d5
+ VSUB.I16 d1,d4,d5
+ VSUB.I16 d2,d6,d7
+ VADD.I16 d3,d6,d7
+ VDUP.16 d5,r5
+ VMOV.I32 q3,#0x2
+ VMOV.I32 q4,#0x2
+ VMOV.I32 q5,#0x2
+ VMOV.I32 q6,#0x2
+ VMLAL.S16 q3,d0,d5
+ VMLAL.S16 q4,d1,d5
+ VMLAL.S16 q5,d2,d5
+ VMLAL.S16 q6,d3,d5
+ VSHRN.I32 d0,q3,#2
+ VSHRN.I32 d1,q4,#2
+ VSHRN.I32 d2,q5,#2
+ VSHRN.I32 d3,q6,#2
+ VST1.16 {d0,d1,d2,d3},[r0]
+ VPOP {d8-d13}
+ POP {r4-r6,pc}
+ .endfunc
+
+.global omxVCM4P10_TransformDequantLumaDCFromPair
+.func omxVCM4P10_TransformDequantLumaDCFromPair
+omxVCM4P10_TransformDequantLumaDCFromPair:
+ PUSH {r4-r6,lr}
+ MOV r4,r1
+ MOV r5,r2
+ BL armVCM4P10_UnpackBlock4x4
+ MOV r0,r4
+ MOV r1,r5
+ BL armVCM4P10_InvTransformDequantLumaDC4x4
+ MOV r0,#0
+ POP {r4-r6,pc}
+ .endfunc
+
+ .end
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/api/armVCM4P2_Huff_Tables_VLC.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/api/armVCM4P2_Huff_Tables_VLC.h
new file mode 100755
index 0000000..74b5505
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/api/armVCM4P2_Huff_Tables_VLC.h
@@ -0,0 +1,37 @@
+/**
+ *
+ * File Name: armVCM4P2_Huff_Tables_VLC.h
+ * OpenMAX DL: v1.0.2
+ * Revision: 12290
+ * Date: Wednesday, April 9, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ *
+ * File: armVCM4P2_Huff_Tables.h
+ * Description: Declares Tables used for Hufffman coding and decoding
+ * in MP4P2 codec.
+ *
+ */
+
+#ifndef _OMXHUFFTAB_H_
+#define _OMXHUFFTAB_H_
+
+
+extern const OMX_U16 armVCM4P2_IntraVlcL0L1[200];
+
+
+extern const OMX_U16 armVCM4P2_InterVlcL0L1[200];
+
+extern const OMX_U16 armVCM4P2_aIntraDCLumaChromaIndex[64];
+//extern const OMX_U16 armVCM4P2_aIntraDCChromaIndex[32];
+extern const OMX_U16 armVCM4P2_aVlcMVD[124];
+
+extern const OMX_U8 armVCM4P2_InterL0L1LMAX[73];
+extern const OMX_U8 armVCM4P2_InterL0L1RMAX[35];
+extern const OMX_U8 armVCM4P2_IntraL0L1LMAX[53];
+extern const OMX_U8 armVCM4P2_IntraL0L1RMAX[40]
+
+#endif /* _OMXHUFFTAB_H_ */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/api/armVCM4P2_ZigZag_Tables.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/api/armVCM4P2_ZigZag_Tables.h
new file mode 100755
index 0000000..e95203a
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/api/armVCM4P2_ZigZag_Tables.h
@@ -0,0 +1,25 @@
+/**
+ *
+ * File Name: armVCM4P2_ZigZag_Tables.h
+ * OpenMAX DL: v1.0.2
+ * Revision: 12290
+ * Date: Wednesday, April 9, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ *
+ * File: armVCM4P2_Zigzag_Tables.h
+ * Description: Declares Tables used for Zigzag scan in MP4P2 codec.
+ *
+ */
+
+#ifndef _OMXZIGZAGTAB_H
+#define _OMXZIGZAGTAB_H
+
+extern const OMX_U8 armVCM4P2_aClassicalZigzagScan [192];
+//extern const OMX_U8 armVCM4P2_aHorizontalZigzagScan [64];
+//extern const OMX_U8 armVCM4P2_aVerticalZigzagScan [64];
+
+#endif /* _OMXZIGZAGTAB_H_ */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Clip8_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Clip8_s.s
new file mode 100755
index 0000000..95fe6d2
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Clip8_s.s
@@ -0,0 +1,82 @@
+; /**
+; *
+; * File Name: armVCM4P2_Clip8_s.s
+; * OpenMAX DL: v1.0.2
+; * Revision: 12290
+; * Date: Wednesday, April 9, 2008
+; *
+; * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+; *
+; *
+; *
+; * Description:
+; * Contains module for Clipping 16 bit value to [0,255] Range
+; */
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+
+ M_VARIANTS CortexA8
+
+ IF CortexA8
+;//Input Arguments
+
+pSrc RN 0
+pDst RN 1
+step RN 2
+
+;// Neon Registers
+
+qx0 QN Q0.S16
+dx00 DN D0.S16
+dx01 DN D1.S16
+qx1 QN Q1.S16
+dx10 DN D2.S16
+dx11 DN D3.S16
+
+qx2 QN Q2.S16
+dx20 DN D4.S16
+dx21 DN D5.S16
+qx3 QN Q3.S16
+dx30 DN D6.S16
+dx31 DN D7.S16
+
+
+dclip0 DN D0.U8
+dclip1 DN D2.U8
+dclip2 DN D4.U8
+dclip3 DN D6.U8
+
+ M_START armVCM4P2_Clip8
+
+ VLD1 {dx00,dx01,dx10,dx11},[pSrc]! ;// Load 16 entries from pSrc
+ VLD1 {dx20,dx21,dx30,dx31},[pSrc]! ;// Load next 16 entries from pSrc
+ VQSHRUN dclip0,qx0,#0 ;// dclip0[i]=clip qx0[i] to [0,255]
+ VQSHRUN dclip1,qx1,#0 ;// dclip1[i]=clip qx1[i] to [0,255]
+ VST1 {dclip0},[pDst],step ;// store 8 bytes and pDst=pDst+step
+ VST1 {dclip1},[pDst],step ;// store 8 bytes and pDst=pDst+step
+ VQSHRUN dclip2,qx2,#0
+ VQSHRUN dclip3,qx3,#0
+ VST1 {dclip2},[pDst],step
+ VST1 {dclip3},[pDst],step
+
+ VLD1 {dx00,dx01,dx10,dx11},[pSrc]! ;// Load 16 entries from pSrc
+ VLD1 {dx20,dx21,dx30,dx31},[pSrc]! ;// Load next 16 entries from pSrc
+ VQSHRUN dclip0,qx0,#0 ;// dclip0[i]=clip qx0[i] to [0,255]
+ VQSHRUN dclip1,qx1,#0 ;// dclip1[i]=clip qx1[i] to [0,255]
+ VST1 {dclip0},[pDst],step ;// store 8 bytes and pDst=pDst+step
+ VST1 {dclip1},[pDst],step ;// store 8 bytes and pDst=pDst+step
+ VQSHRUN dclip2,qx2,#0
+ VQSHRUN dclip3,qx3,#0
+ VST1 {dclip2},[pDst],step
+ VST1 {dclip3},[pDst],step
+
+
+
+ M_END
+ ENDIF
+
+
+
+ END
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_DecodeVLCZigzag_AC_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_DecodeVLCZigzag_AC_unsafe_s.s
new file mode 100755
index 0000000..e4a7f33
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_DecodeVLCZigzag_AC_unsafe_s.s
@@ -0,0 +1,398 @@
+;/**
+; *
+; * File Name: armVCM4P2_DecodeVLCZigzag_AC_unsafe_s.s
+; * OpenMAX DL: v1.0.2
+; * Revision: 12290
+; * Date: Wednesday, April 9, 2008
+; *
+; * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+; *
+; *
+; *
+; * Description:
+; * Contains modules for zigzag scanning and VLC decoding
+; * for inter, intra block.
+; *
+; *
+; *
+; * Function: omxVCM4P2_DecodeVLCZigzag_AC_unsafe
+; *
+; * Description:
+; * Performs VLC decoding and inverse zigzag scan
+; *
+; *
+; *
+; *
+; */
+
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+ INCLUDE armCOMM_BitDec_s.h
+
+
+ M_VARIANTS ARM1136JS
+
+
+
+
+
+ IF ARM1136JS
+
+
+
+
+
+;//Input Arguments
+
+ppBitStream RN 0
+pBitOffset RN 1
+pDst RN 2
+shortVideoHeader RN 3
+
+
+;//Local Variables
+
+Return RN 0
+
+pVlcTableL0L1 RN 4
+pLMAXTableL0L1 RN 4
+pRMAXTableL0L1 RN 4
+pZigzagTable RN 4
+
+ftype RN 0
+temp3 RN 4
+temp RN 5
+Count RN 6
+Escape RN 5
+
+;// armVCM4P2_FillVLDBuffer
+zigzag RN 0
+storeLevel RN 1
+temp2 RN 4
+temp1 RN 5
+sign RN 5
+Last RN 7
+storeRun RN 14
+
+
+packRetIndex RN 5
+
+
+markerbit RN 5
+
+;// Scratch Registers
+
+RBitStream RN 8
+RBitBuffer RN 9
+RBitCount RN 10
+
+T1 RN 11
+T2 RN 12
+LR RN 14
+
+
+
+ M_ALLOC4 pppBitStream,4
+ M_ALLOC4 ppOffset,4
+ M_ALLOC4 pLinkRegister,4
+
+ M_START armVCM4P2_DecodeVLCZigzag_AC_unsafe
+
+ ;// get the table addresses from stack
+ M_ARG ppVlcTableL0L1,4
+ M_ARG ppLMAXTableL0L1,4
+ M_ARG ppRMAXTableL0L1,4
+ M_ARG ppZigzagTable,4
+
+ ;// Store ALL zeros at pDst
+
+ MOV temp1,#0 ;// Initialize Count to zero
+ MOV Last,#0
+ M_STR LR,pLinkRegister ;// Store Link Register on Stack
+ MOV temp2,#0
+ MOV LR,#0
+
+ ;// Initialize the Macro and Store all zeros to pDst
+
+ STM pDst!,{temp2,temp1,Last,LR}
+ M_BD_INIT0 ppBitStream, pBitOffset, RBitStream, RBitBuffer, RBitCount
+ STM pDst!,{temp2,temp1,Last,LR}
+ M_BD_INIT1 T1, T2, T2
+ STM pDst!,{temp2,temp1,Last,LR}
+ M_BD_INIT2 T1, T2, T2
+ STM pDst!,{temp2,temp1,Last,LR}
+ M_STR ppBitStream,pppBitStream ;// Store ppBitstream on stack
+ STM pDst!,{temp2,temp1,Last,LR}
+ M_STR pBitOffset,ppOffset ;// Store pBitOffset on stack
+ STM pDst!,{temp2,temp1,Last,LR}
+
+ STM pDst!,{temp2,temp1,Last,LR}
+ STM pDst!,{temp2,temp1,Last,LR}
+
+
+ SUB pDst,pDst,#128 ;// Restore pDst
+
+ ;// The armVCM4P2_GetVLCBits begins
+
+getVLCbits
+
+ M_BD_LOOK8 Escape,7 ;// Load Escape Value
+ LSR Escape,Escape,#25
+ CMP Escape,#3 ;// check for escape mode
+ MOVNE ftype,#0
+ BNE notEscapemode ;// Branch if not in Escape mode 3
+
+ M_BD_VSKIP8 #7,T1
+ CMP shortVideoHeader,#0 ;// Check shortVideoHeader flag to know the type of Escape mode
+ BEQ endFillVLD
+
+ ;// Escape Mode 4
+
+ M_BD_READ8 Last,1,T1
+ M_BD_READ8 storeRun,6,T1
+ M_BD_READ8 storeLevel,8,T1
+
+
+ ;// Check whether the Reserved values for Level are used and Exit with an Error Message if it is so
+
+ TEQ storeLevel,#0
+ TEQNE storeLevel,#128
+ BEQ ExitError
+
+ ADD temp2,storeRun,Count
+ CMP temp2,#64
+ BGE ExitError ;// error if Count+storeRun >= 64
+
+
+ ;// Load address of zigzagTable
+
+ M_LDR pZigzagTable,ppZigzagTable ;// Loading the Address of Zigzag table
+
+
+ ;// armVCM4P2_FillVLDBuffer
+
+ SXTB storeLevel,storeLevel ;// Sign Extend storeLevel to 32 bits
+
+
+ ;// To Reflect Runlength
+
+ ADD Count,Count,storeRun
+ LDRB zigzag,[pZigzagTable,Count]
+ ADD Count,Count,#1
+ STRH storeLevel,[pDst,zigzag] ;// store Level
+
+ B ExitOk
+
+
+
+endFillVLD
+
+
+ ;// Load Ftype( Escape Mode) value based on the two successive bits in the bitstream
+
+ M_BD_READ8 temp1,1,T1
+ CMP temp1,#0
+ MOVEQ ftype,#1
+ BEQ notEscapemode
+ M_BD_READ8 temp1,1,T1
+ CMP temp1,#1
+ MOVEQ ftype,#3
+ MOVNE ftype,#2
+
+
+notEscapemode
+
+ ;// Load optimized packed VLC table with last=0 and Last=1
+
+ M_LDR pVlcTableL0L1,ppVlcTableL0L1 ;// Load Combined VLC Table
+
+
+ CMP ftype,#3 ;// If ftype >=3 get perform Fixed Length Decoding (Escape Mode 3)
+ BGE EscapeMode3 ;// Else continue normal VLC Decoding
+
+ ;// Variable lengh decoding, "armUnPackVLC32"
+
+
+ M_BD_VLD packRetIndex,T1,T2,pVlcTableL0L1,4,2
+
+
+ LDR temp3,=0xFFF
+
+ CMP packRetIndex,temp3 ;// Check for invalid symbol
+ BEQ ExitError ;// if invalid symbol occurs exit with an error message
+
+ AND Last,packRetIndex,#2 ;// Get Last from packed Index
+
+
+
+
+ LSR storeRun,packRetIndex,#7 ;// Get Run Value from Packed index
+ AND storeLevel,packRetIndex,#0x7c ;// storeLevel=packRetIndex[2-6],storeLevel[0-1]=0
+
+
+ M_LDR pLMAXTableL0L1,ppLMAXTableL0L1 ;// Load LMAX table
+
+
+ LSR storeLevel,storeLevel,#2 ;// Level value
+
+ CMP ftype,#1
+ BNE ftype2
+
+ ;// ftype==1; Escape mode =1
+
+
+ ADD temp1, pLMAXTableL0L1, Last, LSL#4 ;// If the Last=1 add 32 to table address
+ LDRB temp1,[temp1,storeRun]
+
+
+ ADD storeLevel,temp1,storeLevel
+
+ftype2
+
+ ;// ftype =2; Escape mode =2
+
+ M_LDR pRMAXTableL0L1,ppRMAXTableL0L1 ;// Load RMAX Table
+
+ CMP ftype,#2
+ BNE FillVLDL1
+
+ ADD temp1, pRMAXTableL0L1, Last, LSL#4 ;// If Last=1 add 32 to table address
+ SUB temp2,storeLevel,#1
+ LDRB temp1,[temp1,temp2]
+
+
+ ADD storeRun,storeRun,#1
+ ADD storeRun,temp1
+
+FillVLDL1
+
+
+ ;// armVCM4P2_FillVLDBuffer
+
+ M_LDR pZigzagTable,ppZigzagTable ;// Load address of zigzagTable
+
+ M_BD_READ8 sign,1,T1
+
+ CMP sign,#1
+ RSBEQ storeLevel,storeLevel,#0
+
+ ADD temp1,storeRun,Count ;// Exit with an error message if Run + Count exceeds 63
+ CMP temp1,#64
+ BGE ExitError
+
+
+
+
+
+
+ ;// To Reflect Runlenght
+
+ ADD Count,Count,storeRun
+
+storeLevelL1
+
+ LDRB zigzag,[pZigzagTable,Count]
+ CMP Last,#2 ;// Check if the Level val is Last non zero val
+ ADD Count,Count,#1
+ LSR Last,Last,#1
+ STRH storeLevel,[pDst,zigzag]
+
+ BNE end
+
+ B ExitOk
+
+
+
+ ;// Fixed Lengh Decoding Escape Mode 3
+
+EscapeMode3
+
+ M_BD_READ8 Last,1,T1
+ M_BD_READ8 storeRun,6,T1
+
+ ADD temp2,storeRun,Count ;// Exit with an error message if Run + Count exceeds 63
+ CMP temp2,#64
+ BGE ExitError
+
+ M_BD_READ8 markerbit,1,T1
+ TEQ markerbit,#0 ;// Exit with an error message if marker bit is zero
+ BEQ ExitError
+
+ M_BD_READ16 storeLevel,12,T1
+
+ TST storeLevel,#0x800 ;// test if the level is negative
+ SUBNE storeLevel,storeLevel,#4096
+ CMP storeLevel,#0
+ CMPNE storeLevel,#-2048
+ BEQ ExitError ;// Exit with an error message if Level==0 or -2048
+
+ M_LDR pZigzagTable,ppZigzagTable ;// Load address of zigzagTable
+
+ M_BD_READ8 markerbit,1,T1
+
+
+ ;// armVCM4P2_FillVLDBuffer ( Sign not used as storeLevel is preprocessed)
+
+
+
+ ;// To Reflect Run Length
+
+ ADD Count,Count,storeRun
+
+
+
+storeLevelLast
+
+ LDRB zigzag,[pZigzagTable,Count]
+ CMP Last,#1
+ ADD Count,Count,#1
+ STRH storeLevel,[pDst,zigzag]
+
+ BNE end
+
+ B ExitOk
+
+end
+
+ CMP Count,#64 ;//Run the Loop untill Count reaches 64
+
+ BLT getVLCbits
+
+
+ExitOk
+ ;// Exit When VLC Decoding is done Successfully
+
+ ;// Loading ppBitStream and pBitOffset from stack
+
+ CMP Last,#1
+ M_LDR ppBitStream,pppBitStream
+ M_LDR pBitOffset,ppOffset
+
+ ;//Ending the macro
+
+ M_BD_FINI ppBitStream,pBitOffset
+
+ MOVEQ Return,#OMX_Sts_NoErr
+ MOVNE Return,#OMX_Sts_Err
+ M_LDR LR,pLinkRegister ;// Load the Link Register Back
+ B exit2
+
+ExitError
+ ;// Exit When an Error occurs
+
+ M_LDR ppBitStream,pppBitStream
+ M_LDR pBitOffset,ppOffset
+ ;//Ending the macro
+
+ M_BD_FINI ppBitStream,pBitOffset
+ M_LDR LR,pLinkRegister
+ MOV Return,#OMX_Sts_Err
+
+exit2
+
+
+ M_END
+ ENDIF
+
+ END
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Huff_Tables_VLC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Huff_Tables_VLC.c
new file mode 100755
index 0000000..38af975
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Huff_Tables_VLC.c
@@ -0,0 +1,211 @@
+ /**
+ *
+ * File Name: armVCM4P2_Huff_Tables_VLC.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 12290
+ * Date: Wednesday, April 9, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * File: armVCM4P2_Huff_Tables_VLC.c
+ * Description: Contains all the Huffman tables used in MPEG4 codec
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+
+#include "armCOMM_Bitstream.h"
+
+
+
+
+// Contains optimized and Packed VLC tables with Last=0 and Last=1
+
+// optimized Packed VLC table Entry Format
+// ---------------------------------------
+//
+// 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
+// +------------------------------------------------+
+// | Len | Run | Level |L | 1 |
+// +------------------------------------------------+
+// | Offset | 0 |
+// +------------------------------------------------+
+// If the table entry is a leaf entry then bit 0 set:
+// Len = Number of bits overread (0 to 7) 3 bits
+// Run = RunLength of the Symbol (0 to 63) 6 bits
+// Level = Level of the Symbol (0 to 31) 5 bits
+// L = Last Value of the Symbol (0 or 1) 1 bit
+//
+// If the table entry is an internal node then bit 0 is clear:
+// Offset = Number of (16-bit) half words from the table
+// start to the next table node
+//
+// The table is accessed by successive lookup up on the
+// next Step bits of the input bitstream until a leaf node
+// is obtained. The Step sizes are supplied to the VLD macro.
+
+// The VLC tables used for Intra and non inta coefficients in non Escape mode
+// contains symbols with both Last=0 and Last=1.
+// If a symbol is not found in the table it will be coded as 0xFFF
+
+
+const OMX_U16 armVCM4P2_InterVlcL0L1[200] = {
+ 0x0020, 0x0108, 0x0148, 0x0170, 0x0178, 0x0180, 0x0188, 0x1b09,
+ 0x4009, 0x4009, 0x4009, 0x4009, 0x2109, 0x2109, 0x0209, 0x0011,
+ 0x0028, 0x0060, 0x00b8, 0x00e0, 0x0030, 0x0048, 0x0050, 0x0058,
+ 0x3fff, 0x3fff, 0x0038, 0x0040, 0x2115, 0x2115, 0x201d, 0x201d,
+ 0x2059, 0x2059, 0x2051, 0x2051, 0x1c0d, 0x1b0d, 0x1a0d, 0x190d,
+ 0x0911, 0x0811, 0x0711, 0x0611, 0x0511, 0x0319, 0x0219, 0x0121,
+ 0x0068, 0x0090, 0x3fff, 0x3fff, 0x0070, 0x0078, 0x0080, 0x0088,
+ 0x2061, 0x2061, 0x2129, 0x2129, 0x3709, 0x3709, 0x3809, 0x3809,
+ 0x3d0d, 0x3d0d, 0x3e0d, 0x3e0d, 0x3f0d, 0x3f0d, 0x200d, 0x200d,
+ 0x0098, 0x00a0, 0x00a8, 0x00b0, 0x0131, 0x0221, 0x0419, 0x0519,
+ 0x0619, 0x0a11, 0x1909, 0x1a09, 0x210d, 0x220d, 0x230d, 0x240d,
+ 0x250d, 0x260d, 0x270d, 0x280d, 0x00c0, 0x00c8, 0x00d0, 0x00d8,
+ 0x0049, 0x0041, 0x380d, 0x380d, 0x370d, 0x370d, 0x360d, 0x360d,
+ 0x350d, 0x350d, 0x340d, 0x340d, 0x330d, 0x330d, 0x320d, 0x320d,
+ 0x00e8, 0x00f0, 0x00f8, 0x0100, 0x310d, 0x310d, 0x2015, 0x2015,
+ 0x3609, 0x3609, 0x3509, 0x3509, 0x3409, 0x3409, 0x3309, 0x3309,
+ 0x3209, 0x3209, 0x3109, 0x3109, 0x0110, 0x0130, 0x0138, 0x0140,
+ 0x0118, 0x0120, 0x0128, 0x100d, 0x3009, 0x3009, 0x2f09, 0x2f09,
+ 0x2411, 0x2411, 0x2311, 0x2311, 0x2039, 0x2039, 0x2031, 0x2031,
+ 0x0f0d, 0x0e0d, 0x0d0d, 0x0c0d, 0x0b0d, 0x0a0d, 0x090d, 0x0e09,
+ 0x0d09, 0x0211, 0x0119, 0x0029, 0x0150, 0x0158, 0x0160, 0x0168,
+ 0x280d, 0x280d, 0x270d, 0x270d, 0x260d, 0x260d, 0x250d, 0x250d,
+ 0x2c09, 0x2c09, 0xb759, 0xb759, 0x2a09, 0x2a09, 0x2021, 0x2021,
+ 0x040d, 0x030d, 0x0b35, 0x010d, 0x0909, 0x0809, 0x0709, 0x0609,
+ 0x0111, 0x0019, 0x2509, 0x2509, 0x2409, 0x2409, 0x2309, 0x2309
+};
+
+
+const OMX_U16 armVCM4P2_IntraVlcL0L1[200] = {
+ 0x0020, 0x0108, 0x0148, 0x0170, 0x0178, 0x0180, 0x0188, 0x0f09,
+ 0x4009, 0x4009, 0x4009, 0x4009, 0x2011, 0x2011, 0x0109, 0x0019,
+ 0x0028, 0x0060, 0x00b8, 0x00e0, 0x0030, 0x0048, 0x0050, 0x0058,
+ 0x3fff, 0x3fff, 0x0038, 0x0040, 0x203d, 0x203d, 0x2035, 0x2035,
+ 0x20b1, 0x20b1, 0x20a9, 0x20a9, 0x0215, 0x011d, 0x002d, 0x0d09,
+ 0x0519, 0x0811, 0x0419, 0x0321, 0x0221, 0x0139, 0x00a1, 0x0099,
+ 0x0068, 0x0090, 0x3fff, 0x3fff, 0x0070, 0x0078, 0x0080, 0x0088,
+ 0x20b9, 0x20b9, 0x20c1, 0x20c1, 0x2141, 0x2141, 0x2911, 0x2911,
+ 0x2315, 0x2315, 0x2415, 0x2415, 0x2f0d, 0x2f0d, 0x300d, 0x300d,
+ 0x0098, 0x00a0, 0x00a8, 0x00b0, 0x00c9, 0x00d1, 0x00d9, 0x0149,
+ 0x0619, 0x0151, 0x0229, 0x0719, 0x0e09, 0x0045, 0x0515, 0x0615,
+ 0x110d, 0x120d, 0x130d, 0x140d, 0x00c0, 0x00c8, 0x00d0, 0x00d8,
+ 0x0091, 0x0089, 0x2e0d, 0x2e0d, 0x2d0d, 0x2d0d, 0x2c0d, 0x2c0d,
+ 0x2b0d, 0x2b0d, 0x2a0d, 0x2a0d, 0x2115, 0x2115, 0x2025, 0x2025,
+ 0x00e8, 0x00f0, 0x00f8, 0x0100, 0x2c09, 0x2c09, 0x2b09, 0x2b09,
+ 0x2711, 0x2711, 0x2611, 0x2611, 0x2511, 0x2511, 0x2319, 0x2319,
+ 0x2219, 0x2219, 0x2131, 0x2131, 0x0110, 0x0130, 0x0138, 0x0140,
+ 0x0118, 0x0120, 0x0128, 0x080d, 0x2129, 0x2129, 0x2081, 0x2081,
+ 0x2411, 0x2411, 0x2079, 0x2079, 0x2071, 0x2071, 0x2069, 0x2069,
+ 0x1bb5, 0x060d, 0x001d, 0xd3f9, 0x0909, 0x0809, 0x090d, 0x0311,
+ 0x0121, 0x0061, 0x0059, 0x0051, 0x0150, 0x0158, 0x0160, 0x0168,
+ 0x240d, 0x240d, 0x230d, 0x230d, 0x2609, 0x2609, 0x250d, 0x250d,
+ 0x2709, 0x2709, 0x2211, 0x2211, 0x2119, 0x2119, 0x2049, 0x2049,
+ 0x0015, 0x0509, 0x020d, 0x010d, 0x0409, 0x0309, 0x0041, 0x0039,
+ 0x0111, 0x0031, 0x2209, 0x2209, 0x2029, 0x2029, 0x2021, 0x2021
+};
+
+const OMX_U16 armVCM4P2_aIntraDCLumaChromaIndex[64] = {
+ 0x0020, 0x000b, 0x2009, 0x2009, 0x2007, 0x2007, 0x2001, 0x2001,
+ 0x4005, 0x4005, 0x4005, 0x4005, 0x4003, 0x4003, 0x4003, 0x4003,
+ 0x0028, 0x000f, 0x200d, 0x200d, 0x0030, 0x0013, 0x2011, 0x2011,
+ 0x0038, 0x0017, 0x2015, 0x2015, 0x3fff, 0x3fff, 0x2019, 0x2019,
+
+ 0x0020, 0x0009, 0x2007, 0x2007, 0x4005, 0x4005, 0x4005, 0x4005,
+ 0x4003, 0x4003, 0x4003, 0x4003, 0x4001, 0x4001, 0x4001, 0x4001,
+ 0x0028, 0x000d, 0x200b, 0x200b, 0x0030, 0x0011, 0x200f, 0x200f,
+ 0x0038, 0x0015, 0x2013, 0x2013, 0x1fff, 0x0019, 0x2017, 0x2017
+};
+
+
+const OMX_U16 armVCM4P2_aVlcMVD[124] = {
+ 0x0010, 0x00f0, 0x0043, 0x003f, 0x4041, 0x4041, 0x4041, 0x4041,
+ 0x0018, 0x00d8, 0x0047, 0x003b, 0x0020, 0x0080, 0x00a8, 0x00d0,
+ 0x0028, 0x0048, 0x0070, 0x0078, 0x1fff, 0x0030, 0x0038, 0x0040,
+ 0x0081, 0x0001, 0x007f, 0x0003, 0x207d, 0x207d, 0x2005, 0x2005,
+ 0x207b, 0x207b, 0x2007, 0x2007, 0x0050, 0x0058, 0x0060, 0x0068,
+ 0x2079, 0x2079, 0x2009, 0x2009, 0x2077, 0x2077, 0x200b, 0x200b,
+ 0x2075, 0x2075, 0x200d, 0x200d, 0x2073, 0x2073, 0x200f, 0x200f,
+ 0x0071, 0x0011, 0x006f, 0x0013, 0x006d, 0x0015, 0x006b, 0x0017,
+ 0x0088, 0x0090, 0x0098, 0x00a0, 0x0069, 0x0019, 0x0067, 0x001b,
+ 0x0065, 0x001d, 0x0063, 0x001f, 0x0061, 0x0021, 0x005f, 0x0023,
+ 0x005d, 0x0025, 0x005b, 0x0027, 0x00b0, 0x00b8, 0x00c0, 0x00c8,
+ 0x0059, 0x0029, 0x0057, 0x002b, 0x2055, 0x2055, 0x202d, 0x202d,
+ 0x2053, 0x2053, 0x202f, 0x202f, 0x2051, 0x2051, 0x2031, 0x2031,
+ 0x204f, 0x204f, 0x2033, 0x2033, 0x00e0, 0x00e8, 0x0049, 0x0039,
+ 0x204d, 0x204d, 0x2035, 0x2035, 0x204b, 0x204b, 0x2037, 0x2037,
+ 0x2045, 0x2045, 0x203d, 0x203d
+};
+
+/* LMAX table for non Inter (Last == 0 and Last=1)
+ Level - 1 Indexed
+ padded armVCM4P2_InterL0L1LMAX[27-31] with zeros to acess entries for Last=1 effectively
+
+*/
+const OMX_U8 armVCM4P2_InterL0L1LMAX[73] =
+{
+ 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,
+ 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
+};
+
+/* RMAX table for non Inter (Last == 0 and Last=1)
+ Level - 1 Indexed
+ padded armVCM4P2_InterL0L1RMAX[12-31] with zeros to access entries for Last=1 table effectively */
+
+
+const OMX_U8 armVCM4P2_InterL0L1RMAX[35] =
+{
+ 26, 10, 6, 2, 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, 40, 1, 0
+};
+
+/* LMAX table for non Intra (Last == 0 and Last=1)
+ Level - 1 Indexed
+ padded armVCM4P2_IntraL0L1LMAX[15-31] with zeros to acess entries for Last=1 effectively
+
+*/
+const OMX_U8 armVCM4P2_IntraL0L1LMAX[53] =
+{
+ 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,
+
+ 8, 3, 2, 2, 2, 2, 2, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+};
+
+
+/* RMAX table for non Inter (Last == 0 and Last=1)
+ Level - 1 Indexed
+ padded armVCM4P2_IntraL0L1RMAX[27-31] with zeros to access entries for Last=1 table effectively */
+
+
+const OMX_U8 armVCM4P2_IntraL0L1RMAX[40] =
+{
+ 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, 0,
+ 0, 0, 0, 0,
+
+ 20, 6, 1, 0, 0, 0, 0, 0
+
+};
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Lookup_Tables.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Lookup_Tables.c
new file mode 100755
index 0000000..6948f80
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Lookup_Tables.c
@@ -0,0 +1,75 @@
+ /**
+ *
+ * File Name: armVCM4P2_Lookup_Tables.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 12290
+ * Date: Wednesday, April 9, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * File: armVCM4P2_Lookup_Tables.c
+ * Description: Contains all the Lookup tables used in MPEG4 codec
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+
+ /* * Table Entries contain Dc Scaler values
+ * armVCM4P2_DCScaler[i]= 8 for i=1 to 4 and i=33 to 36
+ * = 2*i for i=5 to 8
+ * = i+8 for i=9 to 25
+ * = 2*i-16 for i=26 to 31
+ * = (i-32+13)/2 for i=37 to 59
+ * = i-6-32 for i=60 to 63
+ * = 255 for i=0 and i=32
+ */
+
+const OMX_U8 armVCM4P2_DCScaler[64]={
+ 0xff, 0x8, 0x8, 0x8, 0x8, 0xa, 0xc, 0xe,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e,
+ 0xff, 0x8, 0x8, 0x8, 0x8, 0x9, 0x9, 0xa,
+ 0xa, 0xb, 0xb, 0xc, 0xc, 0xd, 0xd, 0xe,
+ 0xe, 0xf, 0xf, 0x10, 0x10, 0x11, 0x11, 0x12,
+ 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
+
+};
+
+
+ /* Table Entries Contain reciprocal of 1 to 63
+ * armVCM4P2_Reciprocal_QP_S16[i]=round(32767/i)
+ * armVCM4P2_Reciprocal_QP_S16[0]= 0
+ */
+
+const OMX_S16 armVCM4P2_Reciprocal_QP_S16[64]={
+ 0x0000,0x7fff,0x4000,0x2aaa,0x2000,0x1999,0x1555,0x1249,
+ 0x1000,0x0e39,0x0ccd,0x0ba3,0x0aab,0x09d9,0x0925,0x0888,
+ 0x0800,0x0787,0x071c,0x06bd,0x0666,0x0618,0x05d1,0x0591,
+ 0x0555,0x051f,0x04ec,0x04be,0x0492,0x046a,0x0444,0x0421,
+ 0x0400,0x03e1,0x03c4,0x03a8,0x038e,0x0376,0x035e,0x0348,
+ 0x0333,0x031f,0x030c,0x02fa,0x02e9,0x02d8,0x02c8,0x02b9,
+ 0x02ab,0x029d,0x028f,0x0282,0x0276,0x026a,0x025f,0x0254,
+ 0x0249,0x023f,0x0235,0x022b,0x0222,0x0219,0x0211,0x0208
+
+};
+
+ /* Table Entries Contain reciprocal of 1 to 63
+ * armVCM4P2_Reciprocal_QP_S32[i]=round(131071/i)
+ * armVCM4P2_Reciprocal_QP_S32[0]= 0
+ */
+
+const OMX_S32 armVCM4P2_Reciprocal_QP_S32[64]={
+ 0x00000000,0x0001ffff,0x00010000,0x0000aaaa, 0x00008000, 0x00006666, 0x00005555, 0x00004924,
+ 0x00004000,0x000038e3,0x00003333,0x00002e8c, 0x00002aab, 0x00002762, 0x00002492, 0x00002222,
+ 0x00002000,0x00001e1e,0x00001c72,0x00001af2, 0x0000199a, 0x00001861, 0x00001746, 0x00001643,
+ 0x00001555,0x0000147b,0x000013b1,0x000012f6, 0x00001249, 0x000011a8, 0x00001111, 0x00001084,
+ 0x00001000,0x00000f84,0x00000f0f,0x00000ea1, 0x00000e39, 0x00000dd6, 0x00000d79, 0x00000d21,
+ 0x00000ccd,0x00000c7d,0x00000c31,0x00000be8, 0x00000ba3, 0x00000b61, 0x00000b21, 0x00000ae5,
+ 0x00000aab,0x00000a73,0x00000a3d,0x00000a0a, 0x000009d9, 0x000009a9, 0x0000097b, 0x0000094f,
+ 0x00000925,0x000008fb,0x000008d4,0x000008ae, 0x00000889, 0x00000865, 0x00000842, 0x00000820
+
+};
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_SetPredDir_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_SetPredDir_s.s
new file mode 100755
index 0000000..44f2460
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_SetPredDir_s.s
@@ -0,0 +1,104 @@
+;//
+;//
+;// File Name: armVCM4P2_SetPredDir_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 12290
+;// Date: Wednesday, April 9, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+; **
+; * Function: armVCM4P2_SetPredDir
+; *
+; * Description:
+; * Performs detecting the prediction direction
+; *
+; * Remarks:
+; *
+; * Parameters:
+; * [in] blockIndex block index indicating the component type and
+; * position as defined in subclause 6.1.3.8, of ISO/IEC
+; * 14496-2. Furthermore, indexes 6 to 9 indicate the
+; * alpha blocks spatially corresponding to luminance
+; * blocks 0 to 3 in the same macroblock.
+; * [in] pCoefBufRow pointer to the coefficient row buffer
+; * [in] pQpBuf pointer to the quantization parameter buffer
+; * [out]predQP quantization parameter of the predictor block
+; * [out]predDir indicates the prediction direction which takes one
+; * of the following values:
+; * OMX_VC_HORIZONTAL predict horizontally
+; * OMX_VC_VERTICAL predict vertically
+; *
+; * Return Value:
+; * Standard OMXResult result. See enumeration for possible result codes.
+; *
+; */
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+ INCLUDE omxVC_s.h
+
+
+ M_VARIANTS ARM1136JS
+
+
+ IF ARM1136JS
+
+;// Input Arguments
+BlockIndex RN 0
+pCoefBufRow RN 1
+pCoefBufCol RN 2
+predDir RN 3
+predQP RN 4
+pQpBuf RN 5
+
+;// Local Variables
+
+Return RN 0
+blockDCLeft RN 6
+blockDCTop RN 7
+blockDCTopLeft RN 8
+temp1 RN 9
+temp2 RN 14
+
+ M_START armVCM4P2_SetPredDir,r9
+
+ M_ARG ppredQP,4
+ M_ARG ppQpBuf,4
+
+ LDRH blockDCTopLeft,[pCoefBufRow,#-16]
+ LDRH blockDCLeft,[pCoefBufCol]
+
+ TEQ BlockIndex,#3
+ LDREQH blockDCTop,[pCoefBufCol,#-16]
+ LDRNEH blockDCTop,[pCoefBufRow]
+
+ SUBS temp1,blockDCLeft,blockDCTopLeft
+ RSBLT temp1,temp1,#0
+ SUBS temp2,blockDCTopLeft,blockDCTop
+ RSBLT temp2,temp2,#0
+
+ M_LDR pQpBuf,ppQpBuf
+ M_LDR predQP,ppredQP
+ CMP temp1,temp2
+ MOV temp2,#OMX_VC_VERTICAL
+ LDRLTB temp1,[pQpBuf,#1]
+ STRLT temp2,[predDir]
+ STRLT temp1,[predQP]
+ MOV temp2,#OMX_VC_HORIZONTAL
+ LDRGEB temp1,[pQpBuf]
+ STRGE temp2,[predDir]
+ MOV Return,#OMX_Sts_NoErr
+ STRGE temp1,[predQP]
+
+
+
+ M_END
+
+ ENDIF
+
+ END
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Zigzag_Tables.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Zigzag_Tables.c
new file mode 100755
index 0000000..21fa715
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Zigzag_Tables.c
@@ -0,0 +1,61 @@
+/**
+ *
+ * File Name: armVCM4P2_Zigzag_Tables.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 12290
+ * Date: Wednesday, April 9, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * File: armVCM4P2_ZigZag_Tables.c
+ * Description: Contains the zigzag tables
+ *
+ */
+
+#include "omxtypes.h"
+
+/* Contains Double the values in the reference Zigzag Table
+ * Contains Classical,Vetical and Horizontal Zigzagscan tables in one array
+ */
+
+const OMX_U8 armVCM4P2_aClassicalZigzagScan [192] =
+{
+ 0, 2, 16, 32, 18, 4, 6, 20,
+ 34, 48, 64, 50, 36, 22, 8, 10,
+ 24, 38, 52, 66, 80, 96, 82, 68,
+ 54, 40, 26, 12, 14, 28, 42, 56,
+ 70, 84, 98, 112, 114, 100, 86, 72,
+ 58, 44, 30, 46, 60, 74, 88, 102,
+ 116, 118, 104, 90, 76, 62, 78, 92,
+ 106, 120, 122, 104, 94, 110, 124, 126,
+
+ 0, 16, 32, 48, 2, 18, 4, 20,
+ 34, 50, 64, 80, 96, 112, 114, 98,
+ 82, 66, 52, 36, 6, 22, 8, 24,
+ 38, 54, 68, 84, 100, 116, 70, 86,
+ 102, 118, 40, 56, 10, 26, 12, 28,
+ 42, 58, 72, 88, 104, 120, 74, 90,
+ 106, 122, 44, 60, 14, 30, 46, 62,
+ 76, 92, 108, 124, 78, 94, 110, 126,
+
+ 0, 2, 4, 6, 16, 18, 32, 34,
+ 20, 22, 8, 10, 12, 14, 30, 28,
+ 26, 24, 38, 36, 48, 50, 64, 66,
+ 52, 54, 40, 42, 44, 46, 56, 58,
+ 60, 62, 68, 70, 80, 82, 96, 98,
+ 84, 86, 72, 74, 76, 78, 88, 90,
+ 92, 94, 100, 102, 112, 114, 116, 118,
+ 104, 106, 108, 110, 120, 122, 124, 126
+
+
+};
+
+
+
+
+
+/* End of file */
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Inter.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Inter.c
new file mode 100755
index 0000000..796ad6e
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Inter.c
@@ -0,0 +1,102 @@
+/**
+ *
+ * File Name: omxVCM4P2_DecodeBlockCoef_Inter.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 12290
+ * Date: Wednesday, April 9, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains modules for inter reconstruction
+ *
+ */
+
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+
+
+/**
+ * Function: omxVCM4P2_DecodeBlockCoef_Inter
+ *
+ * Description:
+ * Decodes the INTER block coefficients. Inverse quantization, inversely zigzag
+ * positioning and IDCT, with appropriate clipping on each step, are performed
+ * on the coefficients. The results (residuals) are placed in a contiguous array
+ * of 64 elements. For INTER block, the output buffer holds the residuals for
+ * further reconstruction.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream pointer to the pointer to the current byte in
+ * the bit stream buffer. There is no boundary
+ * check for the bit stream buffer.
+ * [in] pBitOffset pointer to the bit position in the byte pointed
+ * to by *ppBitStream. *pBitOffset is valid within
+ * [0-7]
+ * [in] QP quantization parameter
+ * [in] shortVideoHeader a flag indicating presence of short_video_header;
+ * shortVideoHeader==1 indicates using quantization method defined in short
+ * video header mode, and shortVideoHeader==0 indicates normail quantization method.
+ * [out] ppBitStream *ppBitStream is updated after the block is decoded, so that it points to the
+ * current byte in the bit stream buffer.
+ * [out] pBitOffset *pBitOffset is updated so that it points to the current bit position in the
+ * byte pointed by *ppBitStream
+ * [out] pDst pointer to the decoded residual buffer (a contiguous array of 64 elements of
+ * OMX_S16 data type). Must be 16-byte aligned.
+ *
+ * Return Value:
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments
+ * - At least one of the following pointers is Null: ppBitStream, *ppBitStream, pBitOffset , pDst
+ * - At least one of the below case:
+ * - *pBitOffset exceeds [0,7], QP <= 0;
+ * - pDst not 16-byte aligned
+ * OMX_Sts_Err - status error
+ *
+ */
+OMXResult omxVCM4P2_DecodeBlockCoef_Inter(
+ const OMX_U8 ** ppBitStream,
+ OMX_INT * pBitOffset,
+ OMX_S16 * pDst,
+ OMX_INT QP,
+ OMX_INT shortVideoHeader
+)
+{
+ /* 64 elements are needed but to align it to 16 bytes need
+ 15 more elements of padding */
+ OMX_S16 tempBuf[79];
+ OMX_S16 *pTempBuf1;
+ OMXResult errorCode;
+ /* Aligning the local buffers */
+ pTempBuf1 = armAlignTo16Bytes(tempBuf);
+
+
+ /* VLD and zigzag */
+ errorCode = omxVCM4P2_DecodeVLCZigzag_Inter(ppBitStream, pBitOffset,
+ pTempBuf1,shortVideoHeader);
+ armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode);
+
+ /* Dequantization */
+ errorCode = omxVCM4P2_QuantInvInter_I(
+ pTempBuf1,
+ QP);
+ armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode);
+
+ /* Inverse transform */
+ errorCode = omxVCM4P2_IDCT8x8blk(pTempBuf1, pDst);
+ armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode);
+
+ return OMX_Sts_NoErr;
+}
+
+/* End of file */
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Intra.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Intra.c
new file mode 100755
index 0000000..b28657c
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Intra.c
@@ -0,0 +1,214 @@
+/**
+ *
+ * File Name: omxVCM4P2_DecodeBlockCoef_Intra.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 12290
+ * Date: Wednesday, April 9, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains modules for intra reconstruction
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/* Function for saturating 16 bit values to the [0,255] range and */
+/* writing out as 8 bit values. Does 64 entries */
+void armVCM4P2_Clip8(OMX_S16 *pSrc, OMX_U8 *pDst, OMX_INT dstStep );
+
+
+
+/**
+ * Function: omxVCM4P2_DecodeBlockCoef_Intra
+ *
+ * Description:
+ * Decodes the INTRA block coefficients. Inverse quantization, inversely zigzag
+ * positioning, and IDCT, with appropriate clipping on each step, are performed
+ * on the coefficients. The results are then placed in the output frame/plane on
+ * a pixel basis. For INTRA block, the output values are clipped to [0, 255] and
+ * written to corresponding block buffer within the destination plane.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream pointer to the pointer to the current byte in
+ * the bit stream buffer. There is no boundary
+ * check for the bit stream buffer.
+ * [in] pBitOffset pointer to the bit position in the byte pointed
+ * to by *ppBitStream. *pBitOffset is valid within
+ * [0-7].
+ * [in] step width of the destination plane
+ * [in/out] pCoefBufRow [in] pointer to the coefficient row buffer
+ * [out] updated coefficient rwo buffer
+ * [in/out] pCoefBufCol [in] pointer to the coefficient column buffer
+ * [out] updated coefficient column buffer
+ * [in] curQP quantization parameter of the macroblock which
+ * the current block belongs to
+ * [in] pQpBuf Pointer to a 2-element QP array. pQpBuf[0] holds the QP of the 8x8 block left to
+ * the current block(QPa). pQpBuf[1] holds the QP of the 8x8 block just above the
+ * current block(QPc).
+ * Note, in case the corresponding block is out of VOP bound, the QP value will have
+ * no effect to the intra-prediction process. Refer to subclause "7.4.3.3 Adaptive
+ * ac coefficient prediction" of ISO/IEC 14496-2(MPEG4 Part2) for accurate description.
+ * [in] blockIndex block index indicating the component type and
+ * position as defined in subclause 6.1.3.8,
+ * Figure 6-5 of ISO/IEC 14496-2.
+ * [in] intraDCVLC a code determined by intra_dc_vlc_thr and QP.
+ * This allows a mechanism to switch between two VLC
+ * for coding of Intra DC coefficients as per Table
+ * 6-21 of ISO/IEC 14496-2.
+ * [in] ACPredFlag a flag equal to ac_pred_flag (of luminance) indicating
+ * if the ac coefficients of the first row or first
+ * column are differentially coded for intra coded
+ * macroblock.
+ * [in] shortVideoHeader a flag indicating presence of short_video_header;
+ * shortVideoHeader==1 selects linear intra DC mode,
+ * and shortVideoHeader==0 selects nonlinear intra DC mode.
+ * [out] ppBitStream *ppBitStream is updated after the block is
+ * decoded, so that it points to the current byte
+ * in the bit stream buffer
+ * [out] pBitOffset *pBitOffset is updated so that it points to the
+ * current bit position in the byte pointed by
+ * *ppBitStream
+ * [out] pDst pointer to the block in the destination plane.
+ * pDst should be 16-byte aligned.
+ * [out] pCoefBufRow pointer to the updated coefficient row buffer.
+ *
+ * Return Value:
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments
+ * - At least one of the following pointers is NULL: ppBitStream, *ppBitStream, pBitOffset,
+ * pCoefBufRow, pCoefBufCol, pQPBuf, pDst.
+ * or
+ * - At least one of the below case: *pBitOffset exceeds [0,7], curQP exceeds (1, 31),
+ * blockIndex exceeds [0,9], step is not the multiple of 8, intraDCVLC is zero while
+ * blockIndex greater than 5.
+ * or
+ * - pDst is not 16-byte aligned
+ * OMX_Sts_Err - status error
+ *
+ */
+
+OMXResult omxVCM4P2_DecodeBlockCoef_Intra(
+ const OMX_U8 ** ppBitStream,
+ OMX_INT *pBitOffset,
+ OMX_U8 *pDst,
+ OMX_INT step,
+ OMX_S16 *pCoefBufRow,
+ OMX_S16 *pCoefBufCol,
+ OMX_U8 curQP,
+ const OMX_U8 *pQPBuf,
+ OMX_INT blockIndex,
+ OMX_INT intraDCVLC,
+ OMX_INT ACPredFlag,
+ OMX_INT shortVideoHeader
+ )
+{
+ OMX_S16 tempBuf1[79], tempBuf2[79];
+ OMX_S16 *pTempBuf1, *pTempBuf2;
+ OMX_INT predDir, predACDir;
+ OMX_INT predQP;
+ OMXVCM4P2VideoComponent videoComp;
+ OMXResult errorCode;
+
+
+ /* Aligning the local buffers */
+ pTempBuf1 = armAlignTo16Bytes(tempBuf1);
+ pTempBuf2 = armAlignTo16Bytes(tempBuf2);
+
+ /* Setting the AC prediction direction and prediction direction */
+ armVCM4P2_SetPredDir(
+ blockIndex,
+ pCoefBufRow,
+ pCoefBufCol,
+ &predDir,
+ &predQP,
+ pQPBuf);
+
+ predACDir = predDir;
+
+
+ if (ACPredFlag == 0)
+ {
+ predACDir = OMX_VC_NONE;
+ }
+
+ /* Setting the videoComp */
+ if (blockIndex <= 3)
+ {
+ videoComp = OMX_VC_LUMINANCE;
+ }
+ else
+ {
+ videoComp = OMX_VC_CHROMINANCE;
+ }
+
+
+ /* VLD and zigzag */
+ if (intraDCVLC == 1)
+ {
+ errorCode = omxVCM4P2_DecodeVLCZigzag_IntraDCVLC(
+ ppBitStream,
+ pBitOffset,
+ pTempBuf1,
+ predACDir,
+ shortVideoHeader,
+ videoComp);
+ armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode);
+ }
+ else
+ {
+ errorCode = omxVCM4P2_DecodeVLCZigzag_IntraACVLC(
+ ppBitStream,
+ pBitOffset,
+ pTempBuf1,
+ predACDir,
+ shortVideoHeader);
+ armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode);
+ }
+
+ /* AC DC prediction */
+ errorCode = omxVCM4P2_PredictReconCoefIntra(
+ pTempBuf1,
+ pCoefBufRow,
+ pCoefBufCol,
+ curQP,
+ predQP,
+ predDir,
+ ACPredFlag,
+ videoComp);
+ armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode);
+
+ /* Dequantization */
+ errorCode = omxVCM4P2_QuantInvIntra_I(
+ pTempBuf1,
+ curQP,
+ videoComp,
+ shortVideoHeader);
+ armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode);
+
+ /* Inverse transform */
+ errorCode = omxVCM4P2_IDCT8x8blk (pTempBuf1, pTempBuf2);
+ armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode);
+
+ /* Placing the linear array into the destination plane and clipping
+ it to 0 to 255 */
+
+ armVCM4P2_Clip8(pTempBuf2,pDst,step);
+
+
+ return OMX_Sts_NoErr;
+}
+
+/* End of file */
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodePadMV_PVOP_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodePadMV_PVOP_s.s
new file mode 100755
index 0000000..cc16f5a
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodePadMV_PVOP_s.s
@@ -0,0 +1,364 @@
+; **********
+; *
+; * File Name: omxVCM4P2_DecodePadMV_PVOP_s.s
+; * OpenMAX DL: v1.0.2
+; * Revision: 12290
+; * Date: Wednesday, April 9, 2008
+; *
+; * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+; *
+; *
+; *
+; **
+; * Function: omxVCM4P2_DecodePadMV_PVOP
+; *
+; * Description:
+; * Decodes and pads four motion vectors of the non-intra macroblock in P-VOP.
+; * The motion vector padding process is specified in subclause 7.6.1.6 of
+; * ISO/IEC 14496-2.
+; *
+; * Remarks:
+; *
+; *
+; * Parameters:
+; * [in] ppBitStream pointer to the pointer to the current byte in
+; * the bit stream buffer
+; * [in] pBitOffset pointer to the bit position in the byte pointed
+; * to by *ppBitStream. *pBitOffset is valid within
+; * [0-7].
+; * [in] pSrcMVLeftMB pointers to the motion vector buffers of the
+; * macroblocks specially at the left side of the current macroblock
+; * respectively.
+; * [in] pSrcMVUpperMB pointers to the motion vector buffers of the
+; * macroblocks specially at the upper side of the current macroblock
+; * respectively.
+; * [in] pSrcMVUpperRightMB pointers to the motion vector buffers of the
+; * macroblocks specially at the upper-right side of the current macroblock
+; * respectively.
+; * [in] fcodeForward a code equal to vop_fcode_forward in MPEG-4
+; * bit stream syntax
+; * [in] MBType the type of the current macroblock. If MBType
+; * is not equal to OMX_VC_INTER4V, the destination
+; * motion vector buffer is still filled with the
+; * same decoded vector.
+; * [out] ppBitStream *ppBitStream is updated after the block is decoded,
+; * so that it points to the current byte in the bit
+; * stream buffer
+; * [out] pBitOffset *pBitOffset is updated so that it points to the
+; * current bit position in the byte pointed by
+; * *ppBitStream
+; * [out] pDstMVCurMB pointer to the motion vector buffer of the current
+; * macroblock which contains four decoded motion vectors
+; *
+; * Return Value:
+; * OMX_Sts_NoErr -no error
+; *
+; *
+; * OMX_Sts_Err - status error
+; *
+; *
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+ INCLUDE armCOMM_BitDec_s.h
+ INCLUDE omxVC_s.h
+
+ M_VARIANTS ARM1136JS
+
+
+
+
+ IF ARM1136JS
+
+;//Input Arguments
+
+ppBitStream RN 0
+pBitOffset RN 1
+pSrcMVLeftMB RN 2
+pSrcMVUpperMB RN 3
+pSrcMVUpperRightMB RN 4
+pDstMVCurMB RN 5
+fcodeForward RN 6
+MBType RN 7
+
+;//Local Variables
+
+zero RN 4
+one RN 4
+scaleFactor RN 1
+
+
+Return RN 0
+
+VlcMVD RN 0
+index RN 4
+Count RN 7
+
+mvHorData RN 4
+mvHorResidual RN 0
+
+mvVerData RN 4
+mvVerResidual RN 0
+
+temp RN 1
+
+temp1 RN 3
+High RN 4
+Low RN 2
+Range RN 1
+
+BlkCount RN 14
+
+diffMVdx RN 0
+diffMVdy RN 1
+
+;// Scratch Registers
+
+RBitStream RN 8
+RBitCount RN 9
+RBitBuffer RN 10
+
+T1 RN 11
+T2 RN 12
+LR RN 14
+
+ IMPORT armVCM4P2_aVlcMVD
+ IMPORT omxVCM4P2_FindMVpred
+
+ ;// Allocate stack memory
+
+ M_ALLOC4 ppDstMVCurMB,4
+ M_ALLOC4 pDstMVPredME,4
+ M_ALLOC4 pBlkCount,4
+
+ M_ALLOC4 pppBitStream,4
+ M_ALLOC4 ppBitOffset,4
+ M_ALLOC4 ppSrcMVLeftMB,4
+ M_ALLOC4 ppSrcMVUpperMB,4
+
+ M_ALLOC4 pdiffMVdx,4
+ M_ALLOC4 pdiffMVdy,4
+ M_ALLOC4 pHigh,4
+
+
+
+
+ M_START omxVCM4P2_DecodePadMV_PVOP,r11
+
+ M_ARG pSrcMVUpperRightMBonStack,4 ;// pointer to pSrcMVUpperRightMB on stack
+ M_ARG pDstMVCurMBonStack,4 ;// pointer to pDstMVCurMB on stack
+ M_ARG fcodeForwardonStack,4 ;// pointer to fcodeForward on stack
+ M_ARG MBTypeonStack,4 ;// pointer to MBType on stack
+
+
+
+
+
+ ;// Initializing the BitStream Macro
+
+ M_BD_INIT0 ppBitStream, pBitOffset, RBitStream, RBitBuffer, RBitCount
+ M_LDR MBType,MBTypeonStack ;// Load MBType from stack
+ M_LDR pDstMVCurMB,pDstMVCurMBonStack ;// Load pDstMVCurMB from stack
+ MOV zero,#0
+
+ TEQ MBType,#OMX_VC_INTRA ;// Check if MBType=OMX_VC_INTRA
+ TEQNE MBType,#OMX_VC_INTRA_Q ;// check if MBType=OMX_VC_INTRA_Q
+ STREQ zero,[pDstMVCurMB]
+ M_BD_INIT1 T1, T2, T2
+ STREQ zero,[pDstMVCurMB,#4]
+ M_BD_INIT2 T1, T2, T2
+ STREQ zero,[pDstMVCurMB,#4]
+ MOVEQ Return,#OMX_Sts_NoErr
+ MOV BlkCount,#0
+ STREQ zero,[pDstMVCurMB,#4]
+
+ BEQ ExitOK
+
+ TEQ MBType,#OMX_VC_INTER4V ;// Check if MBType=OMX_VC_INTER4V
+ TEQNE MBType,#OMX_VC_INTER4V_Q ;// Check if MBType=OMX_VC_INTER4V_Q
+ MOVEQ Count,#4
+
+ TEQ MBType,#OMX_VC_INTER ;// Check if MBType=OMX_VC_INTER
+ TEQNE MBType,#OMX_VC_INTER_Q ;// Check if MBType=OMX_VC_INTER_Q
+ MOVEQ Count,#1
+
+ M_LDR fcodeForward,fcodeForwardonStack ;// Load fcodeForward from stack
+
+ ;// Storing the values temporarily on stack
+
+ M_STR ppBitStream,pppBitStream
+ M_STR pBitOffset,ppBitOffset
+
+
+ SUB temp,fcodeForward,#1 ;// temp=fcodeForward-1
+ MOV one,#1
+ M_STR pSrcMVLeftMB,ppSrcMVLeftMB
+ LSL scaleFactor,one,temp ;// scaleFactor=1<<(fcodeForward-1)
+ M_STR pSrcMVUpperMB,ppSrcMVUpperMB
+ LSL scaleFactor,scaleFactor,#5
+ M_STR scaleFactor,pHigh ;// [pHigh]=32*scaleFactor
+
+ ;// VLD Decoding
+
+
+Loop
+
+ LDR VlcMVD, =armVCM4P2_aVlcMVD ;// Load the optimized MVD VLC table
+
+ ;// Horizontal Data and Residual calculation
+
+ LDR temp,=0xFFF
+ M_BD_VLD index,T1,T2,VlcMVD,3,2 ;// variable lenght decoding using the macro
+
+ TEQ index,temp
+ BEQ ExitError ;// Exit with an Error Message if the decoded symbol is an invalied symbol
+
+ SUB mvHorData,index,#32 ;// mvHorData=index-32
+ MOV mvHorResidual,#1 ;// mvHorResidual=1
+ CMP fcodeForward,#1
+ TEQNE mvHorData,#0
+ MOVEQ diffMVdx,mvHorData ;// if scaleFactor=1(fcodeForward=1) or mvHorData=0 diffMVdx=mvHorData
+ BEQ VerticalData
+
+ SUB temp,fcodeForward,#1
+ M_BD_VREAD8 mvHorResidual,temp,T1,T2 ;// get mvHorResidual from bitstream if fcodeForward>1 and mvHorData!=0
+
+ CMP mvHorData,#0
+ RSBLT mvHorData,mvHorData,#0 ;// mvHorData=abs(mvHorData)
+ SUB mvHorResidual,mvHorResidual,fcodeForward
+ SMLABB diffMVdx,mvHorData,fcodeForward,mvHorResidual ;// diffMVdx=abs(mvHorData)*fcodeForward+mvHorResidual-fcodeForward
+ ADD diffMVdx,diffMVdx,#1
+ RSBLT diffMVdx,diffMVdx,#0
+
+ ;// Vertical Data and Residual calculation
+
+VerticalData
+
+ M_STR diffMVdx,pdiffMVdx ;// Store the diffMVdx on stack
+ LDR VlcMVD, =armVCM4P2_aVlcMVD ;// Loading the address of optimized VLC tables
+
+ LDR temp,=0xFFF
+ M_BD_VLD index,T1,T2,VlcMVD,3,2 ;// VLC decoding using the macro
+
+ TEQ index,temp
+ BEQ ExitError ;// Exit with an Error Message if an Invalied Symbol occurs
+
+ SUB mvVerData,index,#32 ;// mvVerData=index-32
+ MOV mvVerResidual,#1
+ CMP fcodeForward,#1
+ TEQNE mvVerData,#0
+ MOVEQ diffMVdy,mvVerData ;// diffMVdy = mvVerData if scaleFactor=1(fcodeForward=1) or mvVerData=0
+ BEQ FindMVPred
+
+ SUB temp,fcodeForward,#1
+ M_BD_VREAD8 mvVerResidual,temp,T1,T2 ;// Get mvVerResidual from bit stream if fcodeForward>1 and mnVerData!=0
+
+
+ CMP mvVerData,#0
+ RSBLT mvVerData,mvVerData,#0
+ SUB mvVerResidual,mvVerResidual,fcodeForward
+ SMLABB diffMVdy,mvVerData,fcodeForward,mvVerResidual ;// diffMVdy=abs(mvVerData)*fcodeForward+mvVerResidual-fcodeForward
+ ADD diffMVdy,diffMVdy,#1
+ RSBLT diffMVdy,diffMVdy,#0
+
+ ;//Calling the Function omxVCM4P2_FindMVpred
+
+FindMVPred
+
+ M_STR diffMVdy,pdiffMVdy
+ ADD temp,pDstMVCurMB,BlkCount,LSL #2 ;// temp=pDstMVCurMB[BlkCount]
+ M_STR temp,ppDstMVCurMB ;// store temp on stack for passing as an argument to FindMVPred
+
+ MOV temp,#0
+ M_STR temp,pDstMVPredME ;// Pass pDstMVPredME=NULL as an argument
+ M_STR BlkCount,pBlkCount ;// Passs BlkCount as Argument through stack
+
+ MOV temp,pSrcMVLeftMB ;// temp (RN 1)=pSrcMVLeftMB
+ M_LDR pSrcMVUpperRightMB,pSrcMVUpperRightMBonStack
+ MOV pSrcMVLeftMB,pSrcMVUpperMB ;// pSrcMVLeftMB ( RN 2) = pSrcMVUpperMB
+ MOV ppBitStream,pDstMVCurMB ;// ppBitStream ( RN 0) = pDstMVCurMB
+ MOV pSrcMVUpperMB,pSrcMVUpperRightMB ;// pSrcMVUpperMB( RN 3) = pSrcMVUpperRightMB
+ BL omxVCM4P2_FindMVpred ;// Branch to subroutine omxVCM4P2_FindMVpred
+
+ ;// Store Horizontal Motion Vector
+
+ M_LDR BlkCount,pBlkCount ;// Load BlkCount from stack
+ M_LDR High,pHigh ;// High=32*scaleFactor
+ LSL temp1,BlkCount,#2 ;// temp=BlkCount*4
+ M_LDR diffMVdx,pdiffMVdx ;// Laad diffMVdx
+
+ LDRSH temp,[pDstMVCurMB,temp1] ;// temp=pDstMVCurMB[BlkCount]
+
+
+ RSB Low,High,#0 ;// Low = -32*scaleFactor
+ ADD diffMVdx,temp,diffMVdx ;// diffMVdx=pDstMVCurMB[BlkCount]+diffMVdx
+ ADD Range,High,High ;// Range=64*ScaleFactor
+ SUB High,High,#1 ;// High= 32*scaleFactor-1
+
+ CMP diffMVdx,Low ;// If diffMVdx<Low
+ ADDLT diffMVdx,diffMVdx,Range ;// diffMVdx+=Range
+
+ CMP diffMVdx,High
+ SUBGT diffMVdx,diffMVdx,Range ;// If diffMVdx > High diffMVdx-=Range
+ STRH diffMVdx,[pDstMVCurMB,temp1]
+
+ ;// Store Vertical
+
+ ADD temp1,temp1,#2 ;// temp1=4*BlkCount+2
+ M_LDR diffMVdx,pdiffMVdy ;// Laad diffMVdy
+ LDRSH temp,[pDstMVCurMB,temp1] ;// temp=pDstMVCurMB[BlkCount].diffMVdy
+ ADD BlkCount,BlkCount,#1 ;// BlkCount=BlkCount+1
+ ADD diffMVdx,temp,diffMVdx
+ CMP diffMVdx,Low
+ ADDLT diffMVdx,diffMVdx,Range ;// If diffMVdy<Low diffMVdy+=Range
+ CMP diffMVdx,High
+ SUBGT diffMVdx,diffMVdx,Range ;// If diffMVdy > High diffMVdy-=Range
+ STRH diffMVdx,[pDstMVCurMB,temp1]
+
+ CMP BlkCount,Count
+ M_LDR pSrcMVLeftMB,ppSrcMVLeftMB
+ M_LDR pSrcMVUpperMB,ppSrcMVUpperMB
+
+ BLT Loop ;// If BlkCount<Count Continue the Loop
+
+
+ ;// If MBType=OMX_VC_INTER or MBtype=OMX_VC_INTER_Q copy pDstMVCurMB[0] to
+ ;// pDstMVCurMB[1], pDstMVCurMB[2], pDstMVCurMB[3]
+
+ M_LDR MBType,MBTypeonStack
+
+ TEQ MBType,#OMX_VC_INTER
+ TEQNE MBType,#OMX_VC_INTER_Q
+ LDREQ temp,[pDstMVCurMB]
+ M_LDR ppBitStream,pppBitStream
+ STREQ temp,[pDstMVCurMB,#4]
+
+ STREQ temp,[pDstMVCurMB,#8]
+ STREQ temp,[pDstMVCurMB,#12]
+
+
+ M_LDR pBitOffset,ppBitOffset
+ ;//Ending the macro
+ M_BD_FINI ppBitStream,pBitOffset ;// Finishing the Macro
+
+
+ MOV Return,#OMX_Sts_NoErr
+ B ExitOK
+
+ExitError
+
+ M_LDR ppBitStream,pppBitStream
+ M_LDR pBitOffset,ppBitOffset
+ ;//Ending the macro
+ M_BD_FINI ppBitStream,pBitOffset
+
+ MOV Return,#OMX_Sts_Err
+
+ExitOK
+
+ M_END
+ ENDIF
+ END
+
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_Inter_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_Inter_s.s
new file mode 100755
index 0000000..7208c21
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_Inter_s.s
@@ -0,0 +1,132 @@
+;/**
+; *
+; * File Name: omxVCM4P2_DecodeVLCZigzag_Inter_s.s
+; * OpenMAX DL: v1.0.2
+; * Revision: 12290
+; * Date: Wednesday, April 9, 2008
+; *
+; * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+; *
+; *
+; *
+; * Description:
+; * Contains modules for zigzag scanning and VLC decoding
+; * for inter block.
+; *
+; *
+; *
+; * Function: omxVCM4P2_DecodeVLCZigzag_Inter
+; *
+; * Description:
+; * Performs VLC decoding and inverse zigzag scan for one inter coded block.
+; *
+; * Remarks:
+; *
+; * Parameters:
+; * [in] ppBitStream pointer to the pointer to the current byte in
+; * the bitstream buffer
+; * [in] pBitOffset pointer to the bit position in the byte pointed
+; * to by *ppBitStream. *pBitOffset is valid within [0-7].
+; * [in] shortVideoHeader binary flag indicating presence of short_video_header;
+; * escape modes 0-3 are used if shortVideoHeader==0,
+; * and escape mode 4 is used when shortVideoHeader==1.
+; * [out] ppBitStream *ppBitStream is updated after the block is
+; * decoded, so that it points to the current byte
+; * in the bit stream buffer
+; * [out] pBitOffset *pBitOffset is updated so that it points to the
+; * current bit position in the byte pointed by
+; * *ppBitStream
+; * [out] pDst pointer to the coefficient buffer of current
+; * block. Must be 16-byte aligned
+; *
+; * Return Value:
+; * OMX_Sts_BadArgErr - bad arguments
+; * -At least one of the following pointers is NULL: ppBitStream, *ppBitStream, pBitOffset, pDst, or
+; * -pDst is not 16-byte aligned, or
+; * -*pBitOffset exceeds [0,7].
+; * OMX_Sts_Err - status error
+; * -At least one mark bit is equal to zero
+; * -Encountered an illegal stream code that cannot be found in the VLC table
+; * -Encountered and illegal code in the VLC FLC table
+; * -The number of coefficients is greater than 64
+; *
+; */
+
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+ INCLUDE armCOMM_BitDec_s.h
+
+
+ M_VARIANTS ARM1136JS
+
+
+
+
+
+ IF ARM1136JS
+
+ ;// Import various tables needed for the function
+
+
+ IMPORT armVCM4P2_InterVlcL0L1 ;// Contains optimized and packed VLC Tables for both Last =1 and last=0
+ ;// Packed in Run:Level:Last format
+ IMPORT armVCM4P2_InterL0L1LMAX ;// Contains LMAX table entries with both Last=0 and Last=1
+ IMPORT armVCM4P2_InterL0L1RMAX ;// Contains RMAX table entries with both Last=0 and Last=1
+ IMPORT armVCM4P2_aClassicalZigzagScan ;// contains classical Zigzag table entries with double the original values
+ IMPORT armVCM4P2_DecodeVLCZigzag_AC_unsafe
+
+
+
+;//Input Arguments
+
+ppBitStream RN 0
+pBitOffset RN 1
+pDst RN 2
+shortVideoHeader RN 3
+
+;//Local Variables
+
+Return RN 0
+
+pVlcTableL0L1 RN 4
+pLMAXTableL0L1 RN 4
+pRMAXTableL0L1 RN 4
+pZigzagTable RN 4
+Count RN 6
+
+
+
+ ;// Allocate stack memory to store the VLC,Zigzag,LMAX and RMAX tables
+
+
+ M_ALLOC4 ppVlcTableL0L1,4
+ M_ALLOC4 ppLMAXTableL0L1,4
+ M_ALLOC4 ppRMAXTableL0L1,4
+ M_ALLOC4 ppZigzagTable,4
+
+
+ M_START omxVCM4P2_DecodeVLCZigzag_Inter,r12
+
+
+
+
+ LDR pZigzagTable, =armVCM4P2_aClassicalZigzagScan ;// Load zigzag table
+ M_STR pZigzagTable,ppZigzagTable ;// Store zigzag table on stack to pass as argument to unsafe function
+ LDR pVlcTableL0L1, =armVCM4P2_InterVlcL0L1 ;// Load optimized VLC table with both L=0 and L=1 entries
+ M_STR pVlcTableL0L1,ppVlcTableL0L1 ;// Store optimized VLC table address on stack
+ LDR pLMAXTableL0L1, =armVCM4P2_InterL0L1LMAX ;// Load Interleaved L=0 and L=1 LMAX Tables
+ M_STR pLMAXTableL0L1,ppLMAXTableL0L1 ;// Store LMAX table address on stack
+ LDR pRMAXTableL0L1, =armVCM4P2_InterL0L1RMAX ;// Load Interleaved L=0 and L=1 RMAX Tables
+ MOV Count,#0 ;// set start=0
+ M_STR pRMAXTableL0L1,ppRMAXTableL0L1 ;// store RMAX table address on stack
+
+
+ BL armVCM4P2_DecodeVLCZigzag_AC_unsafe ;// call Unsafe Function for VLC Zigzag Decoding
+
+
+
+ M_END
+ ENDIF
+
+ END
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraACVLC_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraACVLC_s.s
new file mode 100755
index 0000000..9a37ec9
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraACVLC_s.s
@@ -0,0 +1,136 @@
+;/**
+; *
+; * File Name: omxVCM4P2_DecodeVLCZigzag_IntraACVLC_s.s
+; * OpenMAX DL: v1.0.2
+; * Revision: 12290
+; * Date: Wednesday, April 9, 2008
+; *
+; * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+; *
+; *
+; *
+; * Description:
+; * Contains modules for zigzag scanning and VLC decoding
+; * for inter block.
+; *
+; *
+; *
+; * Function: omxVCM4P2_DecodeVLCZigzag_Inter
+; *
+; * Description:
+; * Performs VLC decoding and inverse zigzag scan for one intra coded block.
+; *
+; * Remarks:
+; *
+; * Parameters:
+; * [in] ppBitStream pointer to the pointer to the current byte in
+; * the bitstream buffer
+; * [in] pBitOffset pointer to the bit position in the byte pointed
+; * to by *ppBitStream. *pBitOffset is valid within [0-7].
+; * [in] shortVideoHeader binary flag indicating presence of short_video_header;
+; * escape modes 0-3 are used if shortVideoHeader==0,
+; * and escape mode 4 is used when shortVideoHeader==1.
+; * [out] ppBitStream *ppBitStream is updated after the block is
+; * decoded, so that it points to the current byte
+; * in the bit stream buffer
+; * [out] pBitOffset *pBitOffset is updated so that it points to the
+; * current bit position in the byte pointed by
+; * *ppBitStream
+; * [out] pDst pointer to the coefficient buffer of current
+; * block. Must be 16-byte aligned
+; *
+; * Return Value:
+; * OMX_Sts_BadArgErr - bad arguments
+; * -At least one of the following pointers is NULL: ppBitStream, *ppBitStream, pBitOffset, pDst, or
+; * -pDst is not 16-byte aligned, or
+; * -*pBitOffset exceeds [0,7].
+; * OMX_Sts_Err - status error
+; * -At least one mark bit is equal to zero
+; * -Encountered an illegal stream code that cannot be found in the VLC table
+; * -Encountered and illegal code in the VLC FLC table
+; * -The number of coefficients is greater than 64
+; *
+; */
+
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+ INCLUDE armCOMM_BitDec_s.h
+
+
+ M_VARIANTS ARM1136JS
+
+
+
+
+
+ IF ARM1136JS
+
+ ;// Import various tables needed for the function
+
+
+ IMPORT armVCM4P2_IntraVlcL0L1 ;// Contains optimized and packed VLC Tables for both Last =1 and last=0
+ ;// Packed in Run:Level:Last format
+ IMPORT armVCM4P2_IntraL0L1LMAX ;// Contains LMAX table entries with both Last=0 and Last=1
+ IMPORT armVCM4P2_IntraL0L1RMAX ;// Contains RMAX table entries with both Last=0 and Last=1
+ IMPORT armVCM4P2_aClassicalZigzagScan ;// contains classical Zigzag table entries with double the original values
+ IMPORT armVCM4P2_DecodeVLCZigzag_AC_unsafe
+
+;//Input Arguments
+
+ppBitStream RN 0
+pBitOffset RN 1
+pDst RN 2
+PredDir RN 3
+shortVideoHeader RN 3
+
+;//Local Variables
+
+Return RN 0
+
+pVlcTableL0L1 RN 4
+pLMAXTableL0L1 RN 4
+pRMAXTableL0L1 RN 4
+pZigzagTable RN 4
+Count RN 6
+
+
+
+ ;// Allocate stack memory to store optimized VLC,Zigzag, RMAX, LMAX Table Addresses
+
+ M_ALLOC4 ppVlcTableL0L1,4
+ M_ALLOC4 ppLMAXTableL0L1,4
+ M_ALLOC4 ppRMAXTableL0L1,4
+ M_ALLOC4 ppZigzagTable,4
+
+
+ M_START omxVCM4P2_DecodeVLCZigzag_IntraACVLC,r12
+
+ M_ARG shortVideoHeaderonStack,4 ;// pointer to Input Argument on stack
+
+ LDR pZigzagTable, =armVCM4P2_aClassicalZigzagScan ;// Load Address of the Zigzag table
+ ADD pZigzagTable, pZigzagTable, PredDir, LSL #6 ;// Loading Different type of zigzag tables based on PredDir
+
+ M_STR pZigzagTable,ppZigzagTable ;// Store Zigzag table address on stack
+ LDR pVlcTableL0L1, =armVCM4P2_IntraVlcL0L1 ;// Load optimized packed VLC Table with both L=0 and L=1 entries
+ M_STR pVlcTableL0L1,ppVlcTableL0L1 ;// Store VLC Table address on stack
+ LDR pLMAXTableL0L1, =armVCM4P2_IntraL0L1LMAX ;// Load LMAX Table
+ M_STR pLMAXTableL0L1,ppLMAXTableL0L1 ;// Store LMAX Table address on Stack
+ LDR pRMAXTableL0L1, =armVCM4P2_IntraL0L1RMAX ;// Load RMAX Table
+ MOV Count,#0 ;// Set Start=0
+
+ M_STR pRMAXTableL0L1,ppRMAXTableL0L1 ;// Store RMAX Table address on stack
+
+
+
+ M_LDR shortVideoHeader,shortVideoHeaderonStack ;// get the Input Argument from stack
+
+ BL armVCM4P2_DecodeVLCZigzag_AC_unsafe ;// Call Unsafe Function
+
+
+
+
+ M_END
+ ENDIF
+
+ END
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraDCVLC_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraDCVLC_s.s
new file mode 100755
index 0000000..778aaf2
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraDCVLC_s.s
@@ -0,0 +1,224 @@
+;/**
+; *
+; * File Name: omxVCM4P2_DecodeVLCZigzag_IntraDCVLC_s.s
+; * OpenMAX DL: v1.0.2
+; * Revision: 12290
+; * Date: Wednesday, April 9, 2008
+; *
+; * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+; *
+; *
+; *
+; * Description:
+; * Contains modules for zigzag scanning and VLC decoding
+; * for inter block.
+; *
+; *
+; *
+; * Function: omxVCM4P2_DecodeVLCZigzag_Inter
+; *
+; * Description:
+; * Performs VLC decoding and inverse zigzag scan for one intra coded block.
+; *
+; * Remarks:
+; *
+; * Parameters:
+; * [in] ppBitStream pointer to the pointer to the current byte in
+; * the bitstream buffer
+; * [in] pBitOffset pointer to the bit position in the byte pointed
+; * to by *ppBitStream. *pBitOffset is valid within [0-7].
+; * [in] shortVideoHeader binary flag indicating presence of short_video_header;
+; * escape modes 0-3 are used if shortVideoHeader==0,
+; * and escape mode 4 is used when shortVideoHeader==1.
+; * [out] ppBitStream *ppBitStream is updated after the block is
+; * decoded, so that it points to the current byte
+; * in the bit stream buffer
+; * [out] pBitOffset *pBitOffset is updated so that it points to the
+; * current bit position in the byte pointed by
+; * *ppBitStream
+; * [out] pDst pointer to the coefficient buffer of current
+; * block. Must be 16-byte aligned
+; *
+; * Return Value:
+; * OMX_Sts_BadArgErr - bad arguments
+; * -At least one of the following pointers is NULL: ppBitStream, *ppBitStream, pBitOffset, pDst, or
+; * -pDst is not 16-byte aligned, or
+; * -*pBitOffset exceeds [0,7].
+; * OMX_Sts_Err - status error
+; * -At least one mark bit is equal to zero
+; * -Encountered an illegal stream code that cannot be found in the VLC table
+; * -Encountered and illegal code in the VLC FLC table
+; * -The number of coefficients is greater than 64
+; *
+; */
+
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+ INCLUDE armCOMM_BitDec_s.h
+
+
+ M_VARIANTS CortexA8
+
+
+
+
+
+ IF CortexA8
+
+
+ ;// Import various tables needed for the function
+
+
+ IMPORT armVCM4P2_IntraVlcL0L1 ;// Contains optimized and packed VLC Tables for both Last =1 and last=0
+ ;// Packed in Run:Level:Last format
+ IMPORT armVCM4P2_IntraL0L1LMAX ;// Contains LMAX table entries with both Last=0 and Last=1
+ IMPORT armVCM4P2_IntraL0L1RMAX ;// Contains RMAX table entries with both Last=0 and Last=1
+ IMPORT armVCM4P2_aClassicalZigzagScan ;// contains CLassical, Horizontal, Vertical Zigzag table entries with double the original values
+ IMPORT armVCM4P2_aIntraDCLumaChromaIndex ;// Contains Optimized DCLuma and DCChroma Index table Entries
+
+
+ IMPORT armVCM4P2_DecodeVLCZigzag_AC_unsafe
+
+;//Input Arguments
+
+ppBitStream RN 0
+pBitOffset RN 1
+pDst RN 2
+PredDir RN 3
+shortVideoHeader RN 3
+videoComp RN 5
+;//Local Variables
+
+Return RN 0
+
+pDCLumaChromaIndex RN 4
+pDCChromaIndex RN 7
+pVlcTableL0L1 RN 4
+pLMAXTableL0L1 RN 4
+pRMAXTableL0L1 RN 4
+pZigzagTable RN 4
+Count RN 6
+DCValueSize RN 6
+powOfSize RN 7
+temp1 RN 5
+
+
+;// Scratch Registers
+
+RBitStream RN 8
+RBitBuffer RN 9
+RBitCount RN 10
+
+T1 RN 11
+T2 RN 12
+DCVal RN 14
+
+
+ ;// Allocate stack memory to store optimized VLC,Zigzag, RMAX, LMAX Table Addresses
+
+ M_ALLOC4 ppVlcTableL0L1,4
+ M_ALLOC4 ppLMAXTableL0L1,4
+ M_ALLOC4 ppRMAXTableL0L1,4
+ M_ALLOC4 ppZigzagTable,4
+ M_ALLOC4 pDCCoeff,4
+
+
+
+ M_START omxVCM4P2_DecodeVLCZigzag_IntraDCVLC,r12
+
+ M_ARG shortVideoHeaderonStack,4 ;// Pointer to argument on stack
+ M_ARG videoComponstack,4 ;// Pointer to argument on stack
+
+
+ ;// Decode DC Coefficient
+
+
+ LDR pDCLumaChromaIndex, =armVCM4P2_aIntraDCLumaChromaIndex ;// Load Optimized VLC Table for Luminance and Chrominance
+
+ ;// Initializing the Bitstream Macro
+
+ M_BD_INIT0 ppBitStream, pBitOffset, RBitStream, RBitBuffer, RBitCount
+ M_LDR videoComp,videoComponstack
+ M_BD_INIT1 T1, T2, T2
+ ADD pDCLumaChromaIndex,pDCLumaChromaIndex,videoComp, LSL #6
+ M_BD_INIT2 T1, T2, T2
+
+
+ M_BD_VLD DCValueSize,T1,T2,pDCLumaChromaIndex,4,2 ;// VLC Decode using optimized Luminance and Chrominance VLC Table
+
+
+
+
+DecodeDC
+
+ CMP DCValueSize,#12
+ BGT ExitError
+
+ CMP DCValueSize,#0
+ MOVEQ DCVal,#0 ;// If DCValueSize is zero then DC coeff =0
+ BEQ ACDecode ;// Branch to perform AC Coeff Decoding
+
+ M_BD_VREAD16 DCVal,DCValueSize,T1,T2 ;// Get DC Value From Bit stream
+
+
+ MOV powOfSize,#1
+ LSL powOfSize,DCValueSize ;// powOfSize=pow(2,DCValueSize)
+ CMP DCVal,powOfSize,LSR #1 ;// Compare DCVal with powOfSize/2
+ ADDLT DCVal,DCVal,#1
+ SUBLT DCVal,DCVal,powOfSize ;// If Lessthan powOfSize/2 DCVal=DCVal-powOfSize+1
+ ;// Else DCVal= fetchbits from bit stream
+
+CheckDCValueSize
+
+ CMP DCValueSize,#8 ;// If DCValueSize greater than 8 check marker bit
+
+ BLE ACDecode
+
+ M_BD_READ8 temp1,1,T1
+ TEQ temp1,#0 ;// If Marker bit is zero Exit with an Error Message
+ BEQ ExitError
+
+
+
+ ;// Decode AC Coefficient
+
+ACDecode
+
+ M_STR DCVal,pDCCoeff ;// Store Decoded DC Coeff on Stack
+ M_BD_FINI ppBitStream,pBitOffset ;// Terminating the Bit stream Macro
+
+ LDR pZigzagTable, =armVCM4P2_aClassicalZigzagScan ;// Load Zigzag talbe address
+ ADD pZigzagTable, pZigzagTable, PredDir, LSL #6 ;// Modify the Zigzag table adress based on PredDir
+
+ M_STR pZigzagTable,ppZigzagTable ;// Store zigzag table on stack
+ LDR pVlcTableL0L1, =armVCM4P2_IntraVlcL0L1 ;// Load Optimized VLC Table With both Last=0 and Last=1 Entries
+ M_STR pVlcTableL0L1,ppVlcTableL0L1 ;// Store Optimized VLC Table on stack
+ LDR pLMAXTableL0L1, =armVCM4P2_IntraL0L1LMAX ;// Load LMAX Table
+ M_STR pLMAXTableL0L1,ppLMAXTableL0L1 ;// Store LMAX table on stack
+ LDR pRMAXTableL0L1, =armVCM4P2_IntraL0L1RMAX ;// Load RMAX Table
+ MOV Count,#1 ;// Set Start =1
+
+ M_STR pRMAXTableL0L1,ppRMAXTableL0L1 ;// Store RMAX Table on Stack
+
+
+ M_LDR shortVideoHeader,shortVideoHeaderonStack ;// Load the Input Argument From Stack
+
+ BL armVCM4P2_DecodeVLCZigzag_AC_unsafe ;// Call the Unsafe Function
+
+ M_LDR DCVal,pDCCoeff ;// Get the Decoded DC Value From Stack
+ STRH DCVal,[pDst] ;// Store the DC Value
+ B ExitOK
+
+
+
+ExitError
+
+ M_BD_FINI ppBitStream,pBitOffset ;// Terminating the Bit Stream Macro in case of an Error
+ MOV Return,#OMX_Sts_Err ;// Exit with an Error Message
+ExitOK
+
+ M_END
+ ENDIF
+
+ END
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_FindMVpred_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_FindMVpred_s.s
new file mode 100755
index 0000000..caf7121
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_FindMVpred_s.s
@@ -0,0 +1,194 @@
+;//
+;//
+;// File Name: omxVCM4P2_FindMVpred_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 12290
+;// Date: Wednesday, April 9, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+;// Function:
+;// omxVCM4P2_FindMVpred
+;//
+ ;// Include headers
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+ INCLUDE armVCCOMM_s.h
+
+ ;// Define cpu variants
+ M_VARIANTS CortexA8
+
+
+ IF CortexA8
+
+ M_TABLE armVCM4P2_pBlkIndexTable
+ DCD OMXVCBlk0, OMXVCBlk1
+ DCD OMXVCBlk2, OMXVCBlk3
+
+;//--------------------------------------------
+;// Declare input registers
+;//--------------------------------------------
+
+pSrcMVCurMB RN 0
+pSrcCandMV1 RN 1
+pSrcCandMV2 RN 2
+pSrcCandMV3 RN 3
+pDstMVPred RN 4
+pDstMVPredME RN 5
+iBlk RN 6
+
+pTable RN 4
+CandMV RN 12
+
+pCandMV1 RN 7
+pCandMV2 RN 8
+pCandMV3 RN 9
+
+CandMV1dx RN 0
+CandMV1dy RN 1
+CandMV2dx RN 2
+CandMV2dy RN 3
+CandMV3dx RN 10
+CandMV3dy RN 11
+
+temp RN 14
+
+zero RN 14
+return RN 0
+
+; ----------------------------------------------
+; Main routine
+; ----------------------------------------------
+
+ M_ALLOC4 MV, 4
+
+ ;// Function header
+ M_START omxVCM4P2_FindMVpred, r11
+
+ ;// Define stack arguments
+ M_ARG ppDstMVPred, 4
+ M_ARG ppDstMVPredME, 4
+ M_ARG Blk, 4
+
+ M_ADR CandMV, MV
+ MOV zero, #0
+ M_LDR iBlk, Blk
+
+ ;// Set the default value for these
+ ;// to be used if pSrcCandMV[1|2|3] == NULL
+ MOV pCandMV1, CandMV
+ MOV pCandMV2, CandMV
+ MOV pCandMV3, CandMV
+
+ STR zero, [CandMV]
+
+ ;// Branch to the case based on blk number
+ M_SWITCH iBlk
+ M_CASE OMXVCBlk0 ;// iBlk=0
+ M_CASE OMXVCBlk1 ;// iBlk=0
+ M_CASE OMXVCBlk2 ;// iBlk=0
+ M_CASE OMXVCBlk3 ;// iBlk=0
+ M_ENDSWITCH
+
+OMXVCBlk0
+ CMP pSrcCandMV1, #0
+ ADDNE pCandMV1, pSrcCandMV1, #4
+
+ CMP pSrcCandMV2, #0
+ ADDNE pCandMV2, pSrcCandMV2, #8
+
+ CMP pSrcCandMV3, #0
+ ADDNE pCandMV3, pSrcCandMV3, #8
+ CMPEQ pSrcCandMV1, #0
+
+ MOVEQ pCandMV3, pCandMV2
+ MOVEQ pCandMV1, pCandMV2
+
+ CMP pSrcCandMV1, #0
+ CMPEQ pSrcCandMV2, #0
+
+ MOVEQ pCandMV1, pCandMV3
+ MOVEQ pCandMV2, pCandMV3
+
+ CMP pSrcCandMV2, #0
+ CMPEQ pSrcCandMV3, #0
+
+ MOVEQ pCandMV2, pCandMV1
+ MOVEQ pCandMV3, pCandMV1
+
+ B BlkEnd
+
+OMXVCBlk1
+ MOV pCandMV1, pSrcMVCurMB
+ CMP pSrcCandMV3, #0
+ ADDNE pCandMV3, pSrcCandMV3, #8
+
+ CMP pSrcCandMV2, #0
+ ADDNE pCandMV2, pSrcCandMV2, #12
+
+ CMPEQ pSrcCandMV3, #0
+
+ MOVEQ pCandMV2, pCandMV1
+ MOVEQ pCandMV3, pCandMV1
+
+ B BlkEnd
+
+OMXVCBlk2
+ CMP pSrcCandMV1, #0
+ MOV pCandMV2, pSrcMVCurMB
+ ADD pCandMV3, pSrcMVCurMB, #4
+ ADDNE pCandMV1, pSrcCandMV1, #12
+ B BlkEnd
+
+OMXVCBlk3
+ ADD pCandMV1, pSrcMVCurMB, #8
+ MOV pCandMV2, pSrcMVCurMB
+ ADD pCandMV3, pSrcMVCurMB, #4
+
+BlkEnd
+
+ ;// Using the transperancy info, zero
+ ;// out the candidate MV if neccesary
+ LDRSH CandMV1dx, [pCandMV1], #2
+ LDRSH CandMV2dx, [pCandMV2], #2
+ LDRSH CandMV3dx, [pCandMV3], #2
+
+ ;// Load argument from the stack
+ M_LDR pDstMVPredME, ppDstMVPredME
+
+ LDRSH CandMV1dy, [pCandMV1]
+ LDRSH CandMV2dy, [pCandMV2]
+ LDRSH CandMV3dy, [pCandMV3]
+
+ CMP pDstMVPredME, #0
+
+ ;// Store the candidate MV's into the pDstMVPredME,
+ ;// these can be used in the fast algorithm if implemented
+
+ STRHNE CandMV1dx, [pDstMVPredME], #2
+ STRHNE CandMV1dy, [pDstMVPredME], #2
+ STRHNE CandMV2dx, [pDstMVPredME], #2
+ STRHNE CandMV2dy, [pDstMVPredME], #2
+ STRHNE CandMV3dx, [pDstMVPredME], #2
+ STRHNE CandMV3dy, [pDstMVPredME]
+
+ ; Find the median of the 3 candidate MV's
+ M_MEDIAN3 CandMV1dx, CandMV2dx, CandMV3dx, temp
+
+ ;// Load argument from the stack
+ M_LDR pDstMVPred, ppDstMVPred
+
+ M_MEDIAN3 CandMV1dy, CandMV2dy, CandMV3dy, temp
+
+ STRH CandMV3dx, [pDstMVPred], #2
+ STRH CandMV3dy, [pDstMVPred]
+
+ MOV return, #OMX_Sts_NoErr
+
+ M_END
+ ENDIF ;// ARM1136JS :LOR: CortexA8
+
+ END
\ No newline at end of file
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_IDCT8x8blk_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_IDCT8x8blk_s.s
new file mode 100755
index 0000000..b5e3d0d
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_IDCT8x8blk_s.s
@@ -0,0 +1,73 @@
+;//
+;//
+;// File Name: omxVCM4P2_IDCT8x8blk_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 12290
+;// Date: Wednesday, April 9, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+
+;// Function:
+;// omxVCM4P2_IDCT8x8blk
+;//
+ ;// Include headers
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ ;// Define cpu variants
+ M_VARIANTS CortexA8
+
+ INCLUDE armCOMM_IDCT_s.h
+
+ IMPORT armCOMM_IDCTPreScale
+ ;//
+ ;// Function prototype
+ ;//
+ ;// OMXResult
+ ;// omxVCM4P2_IDCT8x8blk(const OMX_S16* pSrc,
+ ;// OMX_S16* pDst)
+ ;//
+
+ IF CortexA8
+ M_ALLOC4 ppDest, 4
+ M_ALLOC4 pStride, 4
+ M_ALLOC8 pBlk, 2*8*8
+ ENDIF
+
+
+ IF CortexA8
+ M_START omxVCM4P2_IDCT8x8blk, r11, d15
+ ENDIF
+
+ IF CortexA8
+
+;// Declare input registers
+pSrc RN 0
+pDst RN 1
+
+;// Declare other intermediate registers
+Result RN 0
+
+;// Prototype for macro M_IDCT
+;// pSrc RN 0 ;// source data buffer
+;// Stride RN 1 ;// destination stride in bytes
+;// pDest RN 2 ;// destination data buffer
+;// pScale RN 3 ;// pointer to scaling table
+
+pSrc RN 0
+Stride RN 1
+pDest RN 2
+pScale RN 3
+
+ MOV pDest, pDst
+ LDR pScale, =armCOMM_IDCTPreScale
+ M_IDCT s9, s16, 16
+ MOV Result, #OMX_Sts_NoErr
+ M_END
+ ENDIF
+ ;// ARM1136JS :LOR: CortexA8
+
+ END
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_MCReconBlock_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_MCReconBlock_s.s
new file mode 100755
index 0000000..dd00df5
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_MCReconBlock_s.s
@@ -0,0 +1,444 @@
+;//
+;//
+;// File Name: omxVCM4P2_MCReconBlock_s.s
+;// OpenMAX DL: v1.0.2
+;// Revision: 12290
+;// Date: Wednesday, April 9, 2008
+;//
+;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+;//
+;//
+;//
+;// Description:
+;//
+;//
+
+;// Include standard headers
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+;// Import symbols required from other files
+
+ M_VARIANTS CortexA8
+
+;// ***************************************************************************
+;// ARM1136JS implementation
+;// ***************************************************************************
+
+;// ***************************************************************************
+;// CortexA8 implementation
+;// ***************************************************************************
+ IF CortexA8
+;// ***************************************************************************
+;// MACRO DEFINITIONS
+;// ***************************************************************************
+ ;// Description:
+ ;// Does interpolation for the case of "IntegerPixel" predictType. Both
+ ;// rounding cases are handled. Just copies a block from pSrc to pDst
+ ;//
+ ;// Syntax:
+ ;// M_MCRECONBLOCK_IntegerPixel
+ ;//
+ ;// Inputs: None
+ ;// Outputs: None
+
+ MACRO
+ M_MCRECONBLOCK_IntegerPixel
+CaseIntegerPixel_Rnd0
+CaseIntegerPixel_Rnd1
+
+ VLD1 dRow0, [pSrc], srcStep
+ VLD1 dRow1, [pSrc], srcStep
+ VLD1 dRow2, [pSrc], srcStep
+ VLD1 dRow3, [pSrc], srcStep
+ VLD1 dRow4, [pSrc], srcStep
+ VLD1 dRow5, [pSrc], srcStep
+ VLD1 dRow6, [pSrc], srcStep
+ VLD1 dRow7, [pSrc], srcStep
+
+ VST1 dRow0, [pDst@64], dstStep
+ VST1 dRow1, [pDst@64], dstStep
+ VST1 dRow2, [pDst@64], dstStep
+ VST1 dRow3, [pDst@64], dstStep
+ VST1 dRow4, [pDst@64], dstStep
+ VST1 dRow5, [pDst@64], dstStep
+ VST1 dRow6, [pDst@64], dstStep
+ VST1 dRow7, [pDst@64], dstStep
+
+ B SwitchPredictTypeEnd
+ MEND
+;// ***************************************************************************
+ ;// Description:
+ ;// Does interpolation for the case of "HalfPixelX" predictType. The two
+ ;// rounding cases are handled by the parameter "$rndVal". Averages between
+ ;// a pixel and pixel right to it, rounding it based on $rndVal. The
+ ;// rounding is implemented by using opCode switching between "VRHADD" and
+ ;// "VHADD" instructions.
+ ;//
+ ;// Syntax:
+ ;// M_MCRECONBLOCK_HalfPixelX $rndVal
+ ;//
+ ;// Inputs:
+ ;// $rndVal: 0 for rounding and 1 for no rounding
+ ;// Outputs: None
+
+ MACRO
+ M_MCRECONBLOCK_HalfPixelX $rndVal
+
+ LCLS M_VHADDR
+ IF $rndVal = 0
+M_VHADDR SETS "VRHADD"
+ ELSE
+M_VHADDR SETS "VHADD"
+ ENDIF
+
+CaseHalfPixelX_Rnd$rndVal
+
+ VLD1 {dRow0, dRow0Shft}, [pSrc], srcStep
+ VEXT dRow0Shft, dRow0, dRow0Shft, #1
+ VLD1 {dRow1, dRow1Shft}, [pSrc], srcStep
+ VEXT dRow1Shft, dRow1, dRow1Shft, #1
+ VLD1 {dRow2, dRow2Shft}, [pSrc], srcStep
+ VEXT dRow2Shft, dRow2, dRow2Shft, #1
+ VLD1 {dRow3, dRow3Shft}, [pSrc], srcStep
+ VEXT dRow3Shft, dRow3, dRow3Shft, #1
+ VLD1 {dRow4, dRow4Shft}, [pSrc], srcStep
+ VEXT dRow4Shft, dRow4, dRow4Shft, #1
+ VLD1 {dRow5, dRow5Shft}, [pSrc], srcStep
+ VEXT dRow5Shft, dRow5, dRow5Shft, #1
+ VLD1 {dRow6, dRow6Shft}, [pSrc], srcStep
+ VEXT dRow6Shft, dRow6, dRow6Shft, #1
+ VLD1 {dRow7, dRow7Shft}, [pSrc], srcStep
+ VEXT dRow7Shft, dRow7, dRow7Shft, #1
+ $M_VHADDR dRow0, dRow0, dRow0Shft
+ $M_VHADDR dRow1, dRow1, dRow1Shft
+ VST1 dRow0, [pDst@64], dstStep
+ $M_VHADDR dRow2, dRow2, dRow2Shft
+ VST1 dRow1, [pDst@64], dstStep
+ $M_VHADDR dRow3, dRow3, dRow3Shft
+ VST1 dRow2, [pDst@64], dstStep
+ $M_VHADDR dRow4, dRow4, dRow4Shft
+ VST1 dRow3, [pDst@64], dstStep
+ $M_VHADDR dRow5, dRow5, dRow5Shft
+ VST1 dRow4, [pDst@64], dstStep
+ $M_VHADDR dRow6, dRow6, dRow6Shft
+ VST1 dRow5, [pDst@64], dstStep
+ $M_VHADDR dRow7, dRow7, dRow7Shft
+ VST1 dRow6, [pDst@64], dstStep
+ VST1 dRow7, [pDst@64], dstStep
+
+ B SwitchPredictTypeEnd
+ MEND
+;// ***************************************************************************
+ ;// Description:
+ ;// Does interpolation for the case of "HalfPixelY" predictType. The two
+ ;// rounding cases are handled by the parameter "$rndVal". Averages between
+ ;// a pixel and pixel below it, rounding it based on $rndVal. The
+ ;// rounding is implemented by using opCode switching between "VRHADD" and
+ ;// "VHADD" instructions.
+ ;//
+ ;// Syntax:
+ ;// M_MCRECONBLOCK_HalfPixelY $rndVal
+ ;//
+ ;// Inputs:
+ ;// $rndVal: 0 for rounding and 1 for no rounding
+ ;// Outputs: None
+
+ MACRO
+ M_MCRECONBLOCK_HalfPixelY $rndVal
+
+ LCLS M_VHADDR
+ IF $rndVal = 0
+M_VHADDR SETS "VRHADD"
+ ELSE
+M_VHADDR SETS "VHADD"
+ ENDIF
+
+CaseHalfPixelY_Rnd$rndVal
+ VLD1 dRow0, [pSrc], srcStep
+ VLD1 dRow1, [pSrc], srcStep
+ VLD1 dRow2, [pSrc], srcStep
+ VLD1 dRow3, [pSrc], srcStep
+ VLD1 dRow4, [pSrc], srcStep
+ VLD1 dRow5, [pSrc], srcStep
+ VLD1 dRow6, [pSrc], srcStep
+ VLD1 dRow7, [pSrc], srcStep
+ $M_VHADDR dRow0, dRow0, dRow1
+ VLD1 dRow8, [pSrc], srcStep
+ $M_VHADDR dRow1, dRow1, dRow2
+ VST1 dRow0, [pDst@64], dstStep
+ $M_VHADDR dRow2, dRow2, dRow3
+ VST1 dRow1, [pDst@64], dstStep
+ $M_VHADDR dRow3, dRow3, dRow4
+ VST1 dRow2, [pDst@64], dstStep
+ $M_VHADDR dRow4, dRow4, dRow5
+ VST1 dRow3, [pDst@64], dstStep
+ $M_VHADDR dRow5, dRow5, dRow6
+ VST1 dRow4, [pDst@64], dstStep
+ $M_VHADDR dRow6, dRow6, dRow7
+ VST1 dRow5, [pDst@64], dstStep
+ $M_VHADDR dRow7, dRow7, dRow8
+ VST1 dRow6, [pDst@64], dstStep
+ VST1 dRow7, [pDst@64], dstStep
+
+ B SwitchPredictTypeEnd
+ MEND
+;// ***************************************************************************
+ ;// Description:
+ ;// Does interpolation for the case of "IntegerPixel" predictType. Both
+ ;// rounding cases are handled.
+ ;// Typical computation for a row goes like this
+ ;// 1. VLD1 {dRow0, dRow0Shft}, [pSrc], srcStep ;// Load the row and next 8 bytes
+ ;// 2. VEXT dRow0Shft, dRow0, dRow0Shft, #1 ;// Generate the shifted row
+ ;// 3. VADDL qSum0, dRow0, dRow0Shft ;// Generate the sum of row and shifted row
+ ;// 5. VADD qSum0, qSum0, qSum1 ;// Add to the sum of next row (odd row sum has rounding value added to it)
+ ;// 6. VSHRN dRow0, qSum0, #2 ;// Divide by 4
+ ;// 7. VST1 dRow0, [pDst@64], dstStep ;// Store
+ ;// Odd rows undergo following computation after step 3
+ ;// 4. VADD qSum1, qSum1, qRound
+ ;// This saves for adding rounding value to each final sum (overall saves 4
+ ;// instructions).
+ ;// There is reuse of registers for qSum6, qSum7 & qSum8. Overall scheduling takes
+ ;// care of this and also minimizes stalls. Rounding value was modified in
+ ;// ARM register rndVal (originally used for rounding flag) before the switch.
+ ;// It is then populated into all lanes in this macro. No branching out to
+ ;// label "SwitchPredictTypeEnd" is required in the end of the macro as these
+ ;// are the last of switch cases.
+ ;//
+ ;// Syntax:
+ ;// M_MCRECONBLOCK_HalfPixelXY
+ ;//
+ ;// Inputs: None
+ ;// Outputs: None
+
+ MACRO
+ M_MCRECONBLOCK_HalfPixelXY
+
+CaseHalfPixelXY_Rnd0
+CaseHalfPixelXY_Rnd1
+ VLD1 {dRow0, dRow0Shft}, [pSrc], srcStep
+ VDUP qRound, rndVal
+ VLD1 {dRow1, dRow1Shft}, [pSrc], srcStep
+ VEXT dRow0Shft, dRow0, dRow0Shft, #1
+ VLD1 {dRow2, dRow2Shft}, [pSrc], srcStep
+ VEXT dRow1Shft, dRow1, dRow1Shft, #1
+ VLD1 {dRow3, dRow3Shft}, [pSrc], srcStep
+ VEXT dRow2Shft, dRow2, dRow2Shft, #1
+ VLD1 {dRow4, dRow4Shft}, [pSrc], srcStep
+ VADDL qSum0, dRow0, dRow0Shft
+ VLD1 {dRow5, dRow5Shft}, [pSrc], srcStep
+ VADDL qSum1, dRow1, dRow1Shft
+ VLD1 {dRow6, dRow6Shft}, [pSrc], srcStep
+ VEXT dRow3Shft, dRow3, dRow3Shft, #1
+ VLD1 {dRow7, dRow7Shft}, [pSrc], srcStep
+ VEXT dRow4Shft, dRow4, dRow4Shft, #1
+ VLD1 {dRow8, dRow8Shft}, [pSrc], srcStep
+ VADD qSum1, qSum1, qRound
+ VADDL qSum2, dRow2, dRow2Shft
+ VEXT dRow5Shft, dRow5, dRow5Shft, #1
+ VADD qSum0, qSum0, qSum1
+ VADDL qSum3, dRow3, dRow3Shft
+ VEXT dRow6Shft, dRow6, dRow6Shft, #1
+ VADD qSum1, qSum1, qSum2
+ VSHRN dRow0, qSum0, #2
+ VADDL qSum4, dRow4, dRow4Shft
+ VSHRN dRow1, qSum1, #2
+ VADD qSum3, qSum3, qRound
+ VADDL qSum5, dRow5, dRow5Shft
+ VST1 dRow0, [pDst@64], dstStep
+ VEXT dRow7Shft, dRow7, dRow7Shft, #1
+ VST1 dRow1, [pDst@64], dstStep
+ VEXT dRow8Shft, dRow8, dRow8Shft, #1
+ VADD qSum5, qSum5, qRound
+ VADD qSum2, qSum2, qSum3
+ VADD qSum3, qSum3, qSum4
+ VADD qSum4, qSum4, qSum5
+ VSHRN dRow2, qSum2, #2
+ VSHRN dRow3, qSum3, #2
+ VSHRN dRow4, qSum4, #2
+ VADDL qSum6, dRow6, dRow6Shft
+ VADDL qSum7, dRow7, dRow7Shft
+ VST1 dRow2, [pDst@64], dstStep
+ VADDL qSum8, dRow8, dRow8Shft
+ VADD qSum7, qSum7, qRound
+ VST1 dRow3, [pDst@64], dstStep
+ VST1 dRow4, [pDst@64], dstStep
+ VADD qSum5, qSum5, qSum6
+ VADD qSum6, qSum6, qSum7
+ VADD qSum7, qSum7, qSum8
+ VSHRN dRow5, qSum5, #2
+ VSHRN dRow6, qSum6, #2
+ VSHRN dRow7, qSum7, #2
+ VST1 dRow5, [pDst@64], dstStep
+ VST1 dRow6, [pDst@64], dstStep
+ VST1 dRow7, [pDst@64], dstStep
+
+ MEND
+;// ***************************************************************************
+
+;// Input/Output Registers
+pSrc RN 0
+srcStep RN 1
+pSrcResidue RN 2
+pDst RN 3
+dstStep RN 4
+predictType RN 5
+rndVal RN 6
+
+;// Local Scratch Registers
+pDstCopy RN 0
+return RN 0
+
+;// Neon Registers
+dRow0 DN D0.U8
+dRow0Shft DN D1.U8
+dRow1 DN D2.U8
+dRow1Shft DN D3.U8
+dRow2 DN D4.U8
+dRow2Shft DN D5.U8
+dRow3 DN D6.U8
+dRow3Shft DN D7.U8
+dRow4 DN D8.U8
+dRow4Shft DN D9.U8
+dRow5 DN D10.U8
+dRow5Shft DN D11.U8
+dRow6 DN D12.U8
+dRow6Shft DN D13.U8
+dRow7 DN D14.U8
+dRow7Shft DN D15.U8
+dRow8 DN D16.U8
+dRow8Shft DN D17.U8
+
+
+qSum0 QN Q9.U16
+qSum1 QN Q10.U16
+qSum2 QN Q11.U16
+qSum3 QN Q12.U16
+qSum4 QN Q13.U16
+qSum5 QN Q14.U16
+qSum6 QN Q0.U16
+qSum7 QN Q1.U16
+qSum8 QN Q2.U16
+
+qRound QN Q15.U16
+
+dDst0 DN D0.U8
+dDst1 DN D1.U8
+dDst2 DN D2.U8
+dDst3 DN D3.U8
+dDst4 DN D4.U8
+dDst5 DN D5.U8
+dDst6 DN D6.U8
+dDst7 DN D7.U8
+
+qRes0 QN Q4.S16
+qRes1 QN Q5.S16
+qRes2 QN Q6.S16
+qRes3 QN Q7.S16
+qRes4 QN Q8.S16
+qRes5 QN Q9.S16
+qRes6 QN Q10.S16
+qRes7 QN Q11.S16
+
+ ;// Function header
+ M_START omxVCM4P2_MCReconBlock, r6, d15
+ ;// Define stack arguments
+ M_ARG Arg_dstStep, 4
+ M_ARG Arg_predictType, 4
+ M_ARG Arg_rndVal, 4
+ ;// Load argument from the stack
+ M_LDR dstStep, Arg_dstStep
+ M_LDR predictType, Arg_predictType
+ M_LDR rndVal, Arg_rndVal
+ ADD predictType, rndVal, predictType, LSL #1
+ RSB rndVal, rndVal, #2 ;// preparing rndVal for HalfPixelXY
+
+ ;// The following is implementation of switching to different code segments
+ ;// based on different predictType and rndVal flags. The corresponding
+ ;// labels (e.g. CaseIntegerPixel_Rnd0) are embedded in the macros following
+ ;// M_ENDSWITCH (e.g. M_MCRECONBLOCK_IntegerPixel). While "M_MCRECONBLOCK_IntegerPixel"
+ ;// and "M_MCRECONBLOCK_HalfPixelXY" handle for both rounding cases;
+ ;// "M_MCRECONBLOCK_HalfPixelX" and "M_MCRECONBLOCK_HalfPixelY" macros handle
+ ;// the two rounding cases in separate code bases.
+ ;// All these together implement the interpolation functionality
+
+ M_SWITCH predictType
+ M_CASE CaseIntegerPixel_Rnd0
+ M_CASE CaseIntegerPixel_Rnd1
+ M_CASE CaseHalfPixelX_Rnd0
+ M_CASE CaseHalfPixelX_Rnd1
+ M_CASE CaseHalfPixelY_Rnd0
+ M_CASE CaseHalfPixelY_Rnd1
+ M_CASE CaseHalfPixelXY_Rnd0
+ M_CASE CaseHalfPixelXY_Rnd1
+ M_ENDSWITCH
+
+ M_MCRECONBLOCK_IntegerPixel
+ M_MCRECONBLOCK_HalfPixelX 0
+ M_MCRECONBLOCK_HalfPixelX 1
+ M_MCRECONBLOCK_HalfPixelY 0
+ M_MCRECONBLOCK_HalfPixelY 1
+ M_MCRECONBLOCK_HalfPixelXY
+SwitchPredictTypeEnd
+
+ ;// After interpolation is done, residue needs to be added. This is done
+ ;// only in case "pSrcResidue" parameter to the function is not NULL.
+ ;// Following is a completely unrolled code to do so. Each row and
+ ;// corresponding residue is loaded and residue is added and value
+ ;// stored
+
+ CMP pSrcResidue, #0
+ SUBNE pDst, pDst, dstStep, LSL #3 ;// Restoring pDst
+ MOVNE pDstCopy, pDst
+ BEQ pSrcResidueConditionEnd
+pSrcResidueNotNull
+ VLD1 dDst0, [pDst@64], dstStep
+ VLD1 qRes0, [pSrcResidue@128]!
+ VLD1 dDst1, [pDst@64], dstStep
+ VLD1 qRes1, [pSrcResidue@128]!
+ VLD1 dDst2, [pDst@64], dstStep
+ VLD1 qRes2, [pSrcResidue@128]!
+ VADDW qRes0, qRes0, dDst0
+ VLD1 dDst3, [pDst@64], dstStep
+ VADDW qRes1, qRes1, dDst1
+ VLD1 qRes3, [pSrcResidue@128]!
+ VADDW qRes2, qRes2, dDst2
+ VLD1 dDst4, [pDst@64], dstStep
+ VQMOVUN dDst0, qRes0
+ VLD1 qRes4, [pSrcResidue@128]!
+ VADDW qRes3, qRes3, dDst3
+ VLD1 dDst5, [pDst@64], dstStep
+ VQMOVUN dDst1, qRes1
+ VLD1 qRes5, [pSrcResidue@128]!
+ VADDW qRes4, qRes4, dDst4
+ VLD1 dDst6, [pDst@64], dstStep
+ VQMOVUN dDst2, qRes2
+ VLD1 qRes6, [pSrcResidue@128]!
+ VADDW qRes5, qRes5, dDst5
+ VLD1 dDst7, [pDst@64], dstStep
+ VQMOVUN dDst3, qRes3
+ VLD1 qRes7, [pSrcResidue@128]!
+ VADDW qRes6, qRes6, dDst6
+ VST1 dDst0, [pDstCopy@64], dstStep
+ VQMOVUN dDst4, qRes4
+ VST1 dDst1, [pDstCopy@64], dstStep
+ VADDW qRes7, qRes7, dDst7
+ VST1 dDst2, [pDstCopy@64], dstStep
+ VQMOVUN dDst5, qRes5
+ VST1 dDst3, [pDstCopy@64], dstStep
+ VQMOVUN dDst6, qRes6
+ VST1 dDst4, [pDstCopy@64], dstStep
+ VQMOVUN dDst7, qRes7
+ VST1 dDst5, [pDstCopy@64], dstStep
+ VST1 dDst6, [pDstCopy@64], dstStep
+ VST1 dDst7, [pDstCopy@64], dstStep
+
+pSrcResidueConditionEnd
+ MOV return, #OMX_Sts_NoErr
+
+ M_END
+ ENDIF ;// CortexA8
+ END
+;// ***************************************************************************
+;// omxVCM4P2_MCReconBlock ends
+;// ***************************************************************************
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_PredictReconCoefIntra_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_PredictReconCoefIntra_s.s
new file mode 100755
index 0000000..a73f64a
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_PredictReconCoefIntra_s.s
@@ -0,0 +1,320 @@
+; **********
+; *
+; * File Name: omxVCM4P2_PredictReconCoefIntra_s.s
+; * OpenMAX DL: v1.0.2
+; * Revision: 12290
+; * Date: Wednesday, April 9, 2008
+; *
+; * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+; *
+; *
+; *
+; * Description:
+; * Contains module for DC/AC coefficient prediction
+; *
+; *
+; * Function: omxVCM4P2_PredictReconCoefIntra
+; *
+; * Description:
+; * Performs adaptive DC/AC coefficient prediction for an intra block. Prior
+; * to the function call, prediction direction (predDir) should be selected
+; * as specified in subclause 7.4.3.1 of ISO/IEC 14496-2.
+; *
+; * Remarks:
+; *
+; * Parameters:
+; * [in] pSrcDst pointer to the coefficient buffer which contains the
+; * quantized coefficient residuals (PQF) of the current
+; * block; must be aligned on a 4-byte boundary. The
+; * output coefficients are saturated to the range
+; * [-2048, 2047].
+; * [in] pPredBufRow pointer to the coefficient row buffer; must be aligned
+; * on a 4-byte boundary.
+; * [in] pPredBufCol pointer to the coefficient column buffer; must be
+; * aligned on a 4-byte boundary.
+; * [in] curQP quantization parameter of the current block. curQP may
+; * equal to predQP especially when the current block and
+; * the predictor block are in the same macroblock.
+; * [in] predQP quantization parameter of the predictor block
+; * [in] predDir indicates the prediction direction which takes one
+; * of the following values:
+; * OMX_VIDEO_HORIZONTAL predict horizontally
+; * OMX_VIDEO_VERTICAL predict vertically
+; * [in] ACPredFlag a flag indicating if AC prediction should be
+; * performed. It is equal to ac_pred_flag in the bit
+; * stream syntax of MPEG-4
+; * [in] videoComp video component type (luminance, chrominance or
+; * alpha) of the current block
+; * [out] pSrcDst pointer to the coefficient buffer which contains
+; * the quantized coefficients (QF) of the current
+; * block
+; * [out] pPredBufRow pointer to the updated coefficient row buffer
+; * [out] pPredBufCol pointer to the updated coefficient column buffer
+; * Return Value:
+; * OMX_Sts_NoErr - no error
+; * OMX_Sts_BadArgErr - Bad arguments
+; * - At least one of the pointers is NULL: pSrcDst, pPredBufRow, or pPredBufCol.
+; * - At least one the following cases: curQP <= 0, predQP <= 0, curQP >31,
+; * predQP > 31, preDir exceeds [1,2].
+; * - At least one of the pointers pSrcDst, pPredBufRow, or pPredBufCol is not
+; * 4-byte aligned.
+; *
+; *********
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS CortexA8
+
+
+
+ IMPORT armVCM4P2_Reciprocal_QP_S32
+ IMPORT armVCM4P2_Reciprocal_QP_S16
+ IMPORT armVCM4P2_DCScaler
+
+ IF CortexA8
+;// Input Arguments
+
+pSrcDst RN 0
+pPredBufRow RN 1
+pPredBufCol RN 2
+curQP RN 3
+QP RN 3
+predQP RN 4
+predDir RN 5
+ACPredFlag RN 6
+videoComp RN 7
+
+;// Local Variables
+
+shortVideoHeader RN 4
+dcScaler RN 4
+index RN 6
+predCoeffTable RN 7
+temp1 RN 6
+temp2 RN 9
+temp RN 14
+Const RN 8
+temppPredColBuf RN 8
+tempPred RN 9
+
+absCoeffDC RN 8
+negdcScaler RN 10
+Rem RN 11
+temp3 RN 12
+
+dcRowbufCoeff RN 10
+dcColBuffCoeff RN 11
+Return RN 0
+
+;//NEON Registers
+
+qPredRowBuf QN Q0.S16
+dPredRowBuf0 DN D0.S16
+dPredRowBuf1 DN D1.S16
+
+
+
+
+qCoeffTab QN Q1.S32
+
+qPredQP QN Q2.S16
+dPredQP0 DN D4.S16
+dPredQP1 DN D5.S16
+
+
+qtemp1 QN Q3.S32
+qtemp QN Q3.S16
+
+dtemp0 DN D6.S16
+dtemp1 DN D7.S16
+
+dtemp2 DN D8.S16
+dtemp3 DN D9.S16
+
+dtemp4 DN D2.S16
+dtemp5 DN D3.S16
+dtemp6 DN D4.S16
+dtemp7 DN D5.S16
+
+qtempPred1 QN Q5.S32
+qtempPred QN Q5.S16
+
+dtempPred0 DN D10.S16
+dtempPred1 DN D11.S16
+
+
+
+ M_START omxVCM4P2_PredictReconCoefIntra,r11,d11
+
+ ;// Assigning pointers to Input arguments on Stack
+
+ M_ARG predQPonStack,4
+ M_ARG predDironStack,4
+ M_ARG ACPredFlagonStack,4
+ M_ARG videoComponStack,4
+
+ ;// DC Prediction
+
+ M_LDR videoComp,videoComponStack ;// Load videoComp From Stack
+
+ M_LDR predDir,predDironStack ;// Load Prediction direction
+ ;// DC Scaler calculation
+ LDR index, =armVCM4P2_DCScaler
+ ADD index,index,videoComp,LSL #5
+ LDRB dcScaler,[index,QP]
+
+
+ LDR predCoeffTable, =armVCM4P2_Reciprocal_QP_S16 ;// Loading the table with entries 32767/(1 to 63)
+ CMP predDir,#2 ;// Check if the Prediction direction is vertical
+
+ ;// Caulucate tempPred
+
+ LDREQSH absCoeffDC,[pPredBufRow] ;// If vetical load the coeff from Row Prediction Buffer
+ LDRNESH absCoeffDC,[pPredBufCol] ;// If horizontal load the coeff from column Prediction Buffer
+
+ RSB negdcScaler,dcScaler,#0 ;// negdcScaler=-dcScaler
+ MOV temp1,absCoeffDC ;// Load the Prediction coeff to temp for comparision
+ CMP temp1,#0
+ RSBLT absCoeffDC,temp1,#0 ;// calculate absolute val of prediction coeff
+
+ ADD temp,dcScaler,dcScaler
+ LDRH temp,[predCoeffTable,temp] ;// Load value from coeff table for performing division using multiplication
+ SMULBB tempPred,temp,absCoeffDC ;// tempped=pPredBufRow(Col)[0]*32767/dcScaler
+ ADD temp3,dcScaler,#1
+ LSR tempPred,tempPred,#15 ;// tempped=pPredBufRow(Col)[0]/dcScaler
+ LSR temp3,temp3,#1 ;// temp3=round(dcScaler/2)
+ MLA Rem,negdcScaler,tempPred,absCoeffDC ;// Remainder Rem=abs(pPredBufRow(Col)[0])-tempPred*dcScaler
+
+ LDRH dcRowbufCoeff,[pPredBufCol]
+
+ CMP Rem,temp3 ;// compare Rem with (dcScaler/2)
+ ADDGE tempPred,#1 ;// tempPred=tempPred+1 if Rem>=(dcScaler/2)
+ CMP temp1,#0
+ RSBLT tempPred,tempPred,#0 ;// tempPred=-tempPred if
+
+ STRH dcRowbufCoeff,[pPredBufRow,#-16]
+
+
+ LDRH temp,[pSrcDst] ;// temp=pSrcDst[0]
+ ADD temp,temp,tempPred ;// temp=pSrcDst[0]+tempPred
+ SSAT16 temp,#12,temp ;// clip temp to [-2048,2047]
+ SMULBB dcColBuffCoeff,temp,dcScaler ;// temp1=clipped(pSrcDst[0])*dcScaler
+ M_LDR ACPredFlag,ACPredFlagonStack
+ STRH dcColBuffCoeff,[pPredBufCol]
+
+
+ ;// AC Prediction
+
+ M_LDR predQP,predQPonStack
+
+ CMP ACPredFlag,#1 ;// Check if the AC prediction flag is set or not
+ BNE Exit ;// If not set Exit
+ CMP predDir,#2 ;// Check the Prediction direction
+ LDR predCoeffTable, =armVCM4P2_Reciprocal_QP_S32 ;// Loading the table with entries 0x1ffff/(1 to 63)
+ MOV Const,#4
+ MUL curQP,curQP,Const ;// curQP=4*curQP
+ VDUP dPredQP0,predQP
+ LDR temp2,[predCoeffTable,curQP] ;// temp=0x1ffff/curQP
+ VDUP qCoeffTab,temp2
+ BNE Horizontal ;// If the Prediction direction is horizontal branch to Horizontal
+
+
+
+ ;// Vertical
+ ;//Calculating tempPred
+
+ VLD1 {dPredRowBuf0,dPredRowBuf1},[pPredBufRow] ;// Loading pPredBufRow[i]:i=0 t0 7
+
+ VMULL qtemp1,dPredRowBuf0,dPredQP0 ;//qtemp1[i]=pPredBufRow[i]*dPredQP[i]: i=0 t0 3
+ VMUL qtempPred1,qtemp1,qCoeffTab ;//qtempPred1[i]=pPredBufRow[i]*dPredQP[i]*0x1ffff/curQP : i=0 t0 3
+
+ VMULL qtemp1,dPredRowBuf1,dPredQP0 ;//qtemp1[i]=pPredBufRow[i]*dPredQP[i] : i=4 t0 7
+
+ VRSHR qtempPred1,qtempPred1,#17 ;//qtempPred1[i]=round(pPredBufRow[i]*dPredQP[i]/curQP) : i=0 t0 3
+ VSHRN dPredQP1,qtempPred1,#0 ;// narrow qtempPred1[i] to 16 bits
+
+
+ VMUL qtempPred1,qtemp1,qCoeffTab ;//qtempPred1[i]=pPredBufRow[i]*dPredQP[i]*0x1ffff/curQP : i=4 t0 7
+ VRSHR qtempPred1,qtempPred1,#17 ;//qtempPred1[i]=round(pPredBufRow[i]*dPredQP[i]/curQP) : i=4 t0 7
+ VLD1 {dtemp0,dtemp1},[pSrcDst] ;//Loading pSrcDst[i] : i=0 to 7
+ VSHRN dtempPred1,qtempPred1,#0 ;// narrow qtempPred1[i] to 16 bits
+ VMOV dtempPred0,dPredQP1
+
+ ;//updating source and row prediction buffer contents
+ VADD qtemp,qtemp,qtempPred ;//pSrcDst[i]=pSrcDst[i]+qtempPred[i]: i=0 to 7
+ VQSHL qtemp,qtemp,#4 ;//Clip to [-2048,2047]
+ LDRH dcRowbufCoeff,[pPredBufRow] ;//Loading Dc Value of Row Prediction buffer
+ VSHR qtemp,qtemp,#4
+
+ VST1 {dtemp0,dtemp1},[pSrcDst] ;//storing back the updated values
+ VST1 {dtemp0,dtemp1},[pPredBufRow] ;//storing back the updated row prediction values
+ STRH dcRowbufCoeff,[pPredBufRow] ;// storing the updated DC Row Prediction coeff
+
+ B Exit
+
+Horizontal
+
+ ;// Calculating Temppred
+
+
+
+ VLD1 {dPredRowBuf0,dPredRowBuf1},[pPredBufCol] ;// Loading pPredBufCol[i]:i=0 t0 7
+ VMULL qtemp1,dPredRowBuf0,dPredQP0 ;//qtemp1[i]=pPredBufCol[i]*dPredQP[i]: i=0 t0 3
+ VMUL qtempPred1,qtemp1,qCoeffTab ;//qtempPred1[i]=pPredBufCol[i]*dPredQP[i]*0x1ffff/curQP : i=0 t0 3
+
+ VMULL qtemp1,dPredRowBuf1,dPredQP0 ;//qtemp1[i]=pPredBufCol[i]*dPredQP[i] : i=4 t0 7
+
+ VRSHR qtempPred1,qtempPred1,#17 ;//qtempPred1[i]=round(pPredBufCol[i]*dPredQP[i]/curQP) : i=0 t0 3
+ VSHRN dPredQP1,qtempPred1,#0 ;// narrow qtempPred1[i] to 16 bits
+
+
+ VMUL qtempPred1,qtemp1,qCoeffTab ;//qtempPred1[i]=pPredBufCol[i]*dPredQP[i]*0x1ffff/curQP : i=4 t0 7
+
+ MOV temppPredColBuf,pPredBufCol
+ VRSHR qtempPred1,qtempPred1,#17 ;//qtempPred1[i]=round(pPredBufCol[i]*dPredQP[i]/curQP) : i=4 t0 7
+ VLD4 {dtemp0,dtemp1,dtemp2,dtemp3},[pSrcDst] ;// Loading coefficients Interleaving by 4
+ VSHRN dtempPred1,qtempPred1,#0 ;// narrow qtempPred1[i] to 16 bits
+ VMOV dtempPred0,dPredQP1
+
+ ;// Updating source and column prediction buffer contents
+ ADD temp2,pSrcDst,#32
+ VLD4 {dtemp4,dtemp5,dtemp6,dtemp7},[temp2] ;// Loading next 16 coefficients Interleaving by 4
+ VUZP dtemp0,dtemp4 ;// Interleaving by 8
+ VADD dtemp0,dtemp0,dtempPred0 ;// Adding tempPred to coeffs
+ VQSHL dtemp0,dtemp0,#4 ;// Clip to [-2048,2047]
+ VSHR dtemp0,dtemp0,#4
+ VST1 {dtemp0},[pPredBufCol]! ;// Updating Pridiction column buffer
+ VZIP dtemp0,dtemp4 ;// deinterleaving
+ VST4 {dtemp0,dtemp1,dtemp2,dtemp3},[pSrcDst] ;// Updating source coeffs
+ VST4 {dtemp4,dtemp5,dtemp6,dtemp7},[temp2]!
+
+ MOV temp1,temp2
+ VLD4 {dtemp0,dtemp1,dtemp2,dtemp3},[temp2]! ;// Loading coefficients Interleaving by 4
+
+ VLD4 {dtemp4,dtemp5,dtemp6,dtemp7},[temp2]
+ VUZP dtemp0,dtemp4 ;// Interleaving by 8
+ VADD dtemp0,dtemp0,dtempPred1
+ VQSHL dtemp0,dtemp0,#4 ;// Clip to [-2048,2047]
+ VSHR dtemp0,dtemp0,#4
+ VST1 {dtemp0},[pPredBufCol]!
+ VZIP dtemp0,dtemp4
+ VST4 {dtemp0,dtemp1,dtemp2,dtemp3},[temp1]
+ STRH dcColBuffCoeff,[temppPredColBuf]
+ VST4 {dtemp4,dtemp5,dtemp6,dtemp7},[temp2]
+
+Exit
+
+ STRH temp,[pSrcDst]
+
+
+ MOV Return,#OMX_Sts_NoErr
+
+ M_END
+ ENDIF
+
+
+ END
+
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_QuantInvInter_I_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_QuantInvInter_I_s.s
new file mode 100755
index 0000000..bd0ad1f
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_QuantInvInter_I_s.s
@@ -0,0 +1,162 @@
+;/**
+; *
+; * File Name: omxVCM4P2_QuantInvInter_I_s.s
+; * OpenMAX DL: v1.0.2
+; * Revision: 12290
+; * Date: Wednesday, April 9, 2008
+; *
+; * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+; *
+; *
+; *
+; * Description:
+; * Contains modules for inter reconstruction
+; *
+; *
+; *
+; *
+; *
+; * Function: omxVCM4P2_QuantInvInter_I
+; *
+; * Description:
+; * Performs inverse quantization on intra/inter coded block.
+; * This function supports bits_per_pixel = 8. Mismatch control
+; * is performed for the first MPEG-4 mode inverse quantization method.
+; * The output coefficients are clipped to the range: [-2048, 2047].
+; * Mismatch control is performed for the first inverse quantization method.
+; *
+; * Remarks:
+; *
+; * Parameters:
+; * [in] pSrcDst pointer to the input (quantized) intra/inter block. Must be 16-byte aligned.
+; * [in] QP quantization parameter (quantiser_scale)
+; * [in] videoComp (Intra version only.) Video component type of the
+; * current block. Takes one of the following flags:
+; * OMX_VC_LUMINANCE, OMX_VC_CHROMINANCE,
+; * OMX_VC_ALPHA.
+; * [in] shortVideoHeader a flag indicating presence of short_video_header;
+; * shortVideoHeader==1 selects linear intra DC mode,
+; * and shortVideoHeader==0 selects nonlinear intra DC mode.
+; * [out] pSrcDst pointer to the output (dequantized) intra/inter block. Must be 16-byte aligned.
+; *
+; * Return Value:
+; * OMX_Sts_NoErr - no error
+; * OMX_Sts_BadArgErr - bad arguments
+; * - If pSrcDst is NULL or is not 16-byte aligned.
+; * or
+; * - If QP <= 0.
+; * or
+; * - videoComp is none of OMX_VC_LUMINANCE, OMX_VC_CHROMINANCE and OMX_VC_ALPHA.
+; *
+; */
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS CortexA8
+
+ IF CortexA8
+
+
+;//Input Arguments
+pSrcDst RN 0
+QP RN 1
+
+
+;//Local Variables
+Count RN 3
+doubleQP RN 4
+Return RN 0
+;// Neon registers
+
+
+dQP10 DN D0.S32[0]
+qQP1 QN Q0.S32
+
+dQP1 DN D0.S16
+dMinusQP1 DN D1.S16
+
+dCoeff0 DN D2.S16
+dCoeff1 DN D3.S16
+
+qResult0 QN Q3.S32
+dResult0 DN D7.S16
+qSign0 QN Q3.S32
+dSign0 DN D6.S16
+
+qResult1 QN Q4.S32
+dResult1 DN D8.S16
+qSign1 QN Q4.S32
+dSign1 DN D8.S16
+
+d2QP0 DN D10.S32[0]
+q2QP0 QN Q5.S32
+d2QP DN D10.S16
+
+dZero0 DN D11.S16
+dZero1 DN D12.S16
+dConst0 DN D13.S16
+
+
+ M_START omxVCM4P2_QuantInvInter_I,r4,d13
+
+
+
+ ADD doubleQP,QP,QP ;// doubleQP= 2*QP
+ VMOV d2QP0,doubleQP
+ VDUP q2QP0,d2QP0 ;// Move doubleQP in to a scalar
+ TST QP,#1
+ VLD1 {dCoeff0,dCoeff1},[pSrcDst] ;// Load first 8 values to Coeff0,Coeff1
+ SUBEQ QP,QP,#1
+ VMOV dQP10,QP ;// If QP is even then QP1=QP-1 else QP1=QP
+ MOV Count,#64
+ VDUP qQP1,dQP10 ;// Duplicate tempResult with QP1
+ VSHRN d2QP,q2QP0,#0
+ VEOR dConst0,dConst0,dConst0
+ VSHRN dQP1,qQP1,#0 ;// QP1 truncated to 16 bits
+ VSUB dMinusQP1,dConst0,dQP1 ;// dMinusQP1=-QP1
+
+Loop
+
+ ;//Performing Inverse Quantization
+
+ VCLT dSign0,dCoeff0, #0 ;// Compare Coefficient 0 against 0
+ VCLT dSign1,dCoeff1, #0 ;// Compare Coefficient 1 against 0
+ VCEQ dZero0,dCoeff0,#0 ;// Compare Coefficient 0 against zero
+ VBSL dSign0,dMinusQP1,dQP1 ;// dSign0 = -QP1 if Coeff0< 0 else QP1
+ VCEQ dZero1,dCoeff1,#0 ;// Compare Coefficient 1 against zero
+ VBSL dSign1,dMinusQP1,dQP1 ;// dSign1 = -QP1 if Coeff1< 0 else QP1
+ VMOVL qSign0,dSign0 ;// Sign extend qSign0 to 32 bits
+ VMOVL qSign1,dSign1
+ VMLAL qResult0,dCoeff0,d2QP ;// qResult0[i]= qCoeff0[i]+qCoeff0[i]*(-2) if Coeff <0
+ ;// qResult0[i]= qCoeff0[i] if Coeff >=0
+ VMLAL qResult1,dCoeff1,d2QP ;// qResult1[i]= qCoeff1[i]+qCoeff1[i]*(-2) if Coeff <0
+ ;// qResult1[i]= qCoeff1[i] if Coeff >=0
+ ;// Clip Result to [-2048,2047]
+
+ VQSHL qResult0,qResult0,#20 ;// clip to [-2048,2047]
+ VQSHL qResult1,qResult1,#20
+
+ VSHR qResult0,qResult0,#4
+ VSHR qResult1,qResult1,#4
+ VSHRN dResult0,qResult0,#16 ;// Narrow the clipped Value to Halfword
+ VSHRN dResult1,qResult1,#16
+ VBIT dResult0,dConst0,dZero0
+ VBIT dResult1,dConst0,dZero1
+
+ VST1 {dResult0,dResult1},[pSrcDst]! ;// Store the result
+ SUBS Count,Count,#8
+ VLD1 {dCoeff0,dCoeff1},[pSrcDst]
+
+
+ BGT Loop
+
+ MOV Return,#OMX_Sts_NoErr
+
+
+ M_END
+ ENDIF
+
+
+ END
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_QuantInvIntra_I_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_QuantInvIntra_I_s.s
new file mode 100755
index 0000000..e00591f
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_QuantInvIntra_I_s.s
@@ -0,0 +1,210 @@
+;/**
+; *
+; * File Name: omxVCM4P2_QuantInvIntra_I_s.s
+; * OpenMAX DL: v1.0.2
+; * Revision: 12290
+; * Date: Wednesday, April 9, 2008
+; *
+; * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+; *
+; *
+; *
+; * Description:
+; * Contains modules for inter reconstruction
+; *
+; *
+; *
+; *
+; *
+; *
+; * Function: omxVCM4P2_QuantInvIntra_I
+; *
+; * Description:
+; * Performs inverse quantization on intra/inter coded block.
+; * This function supports bits_per_pixel = 8. Mismatch control
+; * is performed for the first MPEG-4 mode inverse quantization method.
+; * The output coefficients are clipped to the range: [-2048, 2047].
+; * Mismatch control is performed for the first inverse quantization method.
+; *
+; * Remarks:
+; *
+; * Parameters:
+; * [in] pSrcDst pointer to the input (quantized) intra/inter block. Must be 16-byte aligned.
+; * [in] QP quantization parameter (quantiser_scale)
+; * [in] videoComp (Intra version only.) Video component type of the
+; * current block. Takes one of the following flags:
+; * OMX_VC_LUMINANCE, OMX_VC_CHROMINANCE,
+; * OMX_VC_ALPHA.
+; * [in] shortVideoHeader a flag indicating presence of short_video_header;
+; * shortVideoHeader==1 selects linear intra DC mode,
+; * and shortVideoHeader==0 selects nonlinear intra DC mode.
+; * [out] pSrcDst pointer to the output (dequantized) intra/inter block. Must be 16-byte aligned.
+; *
+; * Return Value:
+; * OMX_Sts_NoErr - no error
+; * OMX_Sts_BadArgErr - bad arguments
+; * - If pSrcDst is NULL or is not 16-byte aligned.
+; * or
+; * - If QP <= 0.
+; * or
+; * - videoComp is none of OMX_VC_LUMINANCE, OMX_VC_CHROMINANCE and OMX_VC_ALPHA.
+; *
+
+
+ INCLUDE omxtypes_s.h
+ INCLUDE armCOMM_s.h
+
+ M_VARIANTS CortexA8
+
+
+ IMPORT armVCM4P2_DCScaler
+
+ IF CortexA8
+
+
+;//Input Arguments
+pSrcDst RN 0
+QP RN 1
+videoComp RN 2
+shortVideoHeader RN 3
+
+
+;//Local Variables
+
+dcScaler RN 4
+temp RN 14
+index RN 5
+
+
+Count RN 5
+doubleQP RN 4
+Return RN 0
+
+
+;// Neon registers
+
+
+dQP10 DN D0.S32[0]
+qQP1 QN Q0.S32
+
+dQP1 DN D0.S16
+dMinusQP1 DN D1.S16
+
+dCoeff0 DN D2.S16
+dCoeff1 DN D3.S16
+
+qResult0 QN Q3.S32
+dResult0 DN D7.S16
+qSign0 QN Q3.S32
+dSign0 DN D6.S16
+
+qResult1 QN Q4.S32
+dResult1 DN D8.S16
+qSign1 QN Q4.S32
+dSign1 DN D8.S16
+
+d2QP0 DN D10.S32[0]
+q2QP0 QN Q5.S32
+d2QP DN D10.S16
+
+dZero0 DN D11.S16
+dZero1 DN D4.S16
+dConst0 DN D5.S16
+
+
+
+
+
+
+ M_START omxVCM4P2_QuantInvIntra_I,r5,d11
+
+
+ ;// Perform Inverse Quantization for DC coefficient
+
+ TEQ shortVideoHeader,#0 ;// Test if short Video Header flag =0
+ MOVNE dcScaler,#8 ;// if shortVideoHeader is non zero dcScaler=8
+ BNE calDCVal
+
+ LDR index, =armVCM4P2_DCScaler
+ ADD index,index,videoComp,LSL #5
+ LDRB dcScaler,[index,QP]
+
+ ;//M_CalDCScalar shortVideoHeader,videoComp, QP
+
+calDCVal
+
+ LDRH temp,[pSrcDst]
+ SMULBB temp,temp,dcScaler ;// dcCoeff = dcScaler * Quantized DC coefficient(from memory)
+ SSAT temp,#12,temp ;// Saturating to 12 bits
+
+
+
+ ;// Perform Inverse Quantization for Ac Coefficients
+
+
+
+ ADD doubleQP,QP,QP ;// doubleQP= 2*QP
+ VMOV d2QP0,doubleQP
+ VDUP q2QP0,d2QP0 ;// Move doubleQP in to a scalar
+ TST QP,#1
+ VLD1 {dCoeff0,dCoeff1},[pSrcDst] ;// Load first 8 values to Coeff0,Coeff1
+ SUBEQ QP,QP,#1
+ VMOV dQP10,QP ;// If QP is even then QP1=QP-1 else QP1=QP
+ MOV Count,#64
+ VDUP qQP1,dQP10 ;// Duplicate tempResult with QP1
+ VSHRN d2QP,q2QP0,#0
+ VEOR dConst0,dConst0,dConst0
+ VSHRN dQP1,qQP1,#0 ;// QP1 truncated to 16 bits
+ VSUB dMinusQP1,dConst0,dQP1 ;// dMinusQP1=-QP1
+
+Loop
+
+ ;//Performing Inverse Quantization
+
+ VCLT dSign0,dCoeff0, #0 ;// Compare Coefficient 0 against 0
+ VCLT dSign1,dCoeff1, #0 ;// Compare Coefficient 1 against 0
+ VCEQ dZero0,dCoeff0,#0 ;// Compare Coefficient 0 against zero
+ VBSL dSign0,dMinusQP1,dQP1 ;// dSign0 = -QP1 if Coeff0< 0 else QP1
+ VCEQ dZero1,dCoeff1,#0 ;// Compare Coefficient 1 against zero
+ VBSL dSign1,dMinusQP1,dQP1 ;// dSign1 = -QP1 if Coeff1< 0 else QP1
+ VMOVL qSign0,dSign0 ;// Sign extend qSign0 to 32 bits
+ VMOVL qSign1,dSign1
+ VMLAL qResult0,dCoeff0,d2QP ;// qResult0[i]= qCoeff0[i]+qCoeff0[i]*(-2) if Coeff <0
+ ;// qResult0[i]= qCoeff0[i] if Coeff >=0
+ VMLAL qResult1,dCoeff1,d2QP ;// qResult1[i]= qCoeff1[i]+qCoeff1[i]*(-2) if Coeff <0
+ ;// qResult1[i]= qCoeff1[i] if Coeff >=0
+ ;// Clip Result to [-2048,2047]
+
+ VQSHL qResult0,qResult0,#20 ;// clip to [-2048,2047]
+ VQSHL qResult1,qResult1,#20
+
+ VSHR qResult0,qResult0,#4
+ VSHR qResult1,qResult1,#4
+ VSHRN dResult0,qResult0,#16 ;// Narrow the clipped Value to Halfword
+ VSHRN dResult1,qResult1,#16
+ VBIT dResult0,dConst0,dZero0
+ VBIT dResult1,dConst0,dZero1
+
+ VST1 {dResult0,dResult1},[pSrcDst]! ;// Store the result
+ SUBS Count,Count,#8
+ VLD1 {dCoeff0,dCoeff1},[pSrcDst]
+
+
+ BGT Loop
+
+ SUB pSrcDst,pSrcDst,#128
+
+ ;// Store the Inverse quantized Dc coefficient
+
+ STRH temp,[pSrcDst],#2
+
+ MOV Return,#OMX_Sts_NoErr
+
+
+
+ M_END
+ ENDIF
+
+
+ END
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/src/armVC_Version.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/src/armVC_Version.c
new file mode 100755
index 0000000..5d93681
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/src/armVC_Version.c
@@ -0,0 +1,6 @@
+#include "omxtypes.h"
+#include "armCOMM_Version.h"
+
+#ifdef ARM_INCLUDE_VERSION_DESCRIPTIONS
+const char * const omxVC_VersionDescription = "ARM OpenMAX DL v" ARM_VERSION_STRING " Rel=" OMX_ARM_RELEASE_TAG " Arch=" OMX_ARM_BUILD_ARCHITECTURE " Tools=" OMX_ARM_BUILD_TOOLCHAIN ;
+#endif /* ARM_INCLUDE_VERSION_DESCRIPTIONS */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/ARM_DELIVERY.TXT b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/ARM_DELIVERY.TXT
new file mode 100644
index 0000000..7801f3d
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/ARM_DELIVERY.TXT
@@ -0,0 +1,63 @@
+The contents of this transaction was created by Hedley Francis
+of ARM on 19-Feb-2008.
+
+It contains the ARM data versions listed below.
+
+This data, unless otherwise stated, is ARM Proprietary and access to it
+is subject to the agreements indicated below.
+
+If you experience problems with this data, please contact ARM support
+quoting transaction reference <97412>.
+
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+- OX000-SW-98010-r0p0-00bet1
+ Video codecs - sample code
+ Sample code release for Hantro (Ver 1.0.2)
+ internal access
+
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+This transaction contains deliverables which are designated as being of
+beta release status (BET).
+
+Beta release status has a particular meaning to ARM of which the recipient
+must be aware. Beta is a pre-release status indicating that the deliverable
+so described is believed to robustly demonstrate specified behaviour, to be
+consistent across its included aspects and be ready for general deployment.
+But Beta also indicates that pre-release reliability trials are ongoing and
+that it is possible residual defects or errors in operation, consistency
+and documentation may still be encountered. The recipient should consider
+this position when using this Beta material supplied. ARM will normally
+attempt to provide fixes or a work-around for defects identified by the
+recipient, but the provision or timeliness of this support cannot be
+guaranteed. ARM shall not be responsible for direct or consequential
+damages as a result of encountering one or more of these residual defects.
+By accepting a Beta release, the recipient agrees to these constraints and
+to providing reasonable information to ARM to enable the replication of the
+defects identified by the recipient. The specific Beta version supplied
+will not be supported after release of a later or higher status version.
+It should be noted that Support for the Beta release of the deliverable
+will only be provided by ARM to a recipient who has a current support and
+maintenance contract for the deliverable.
+
+
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+In addition to the data versions listed above, this transaction contains
+two additional files at the top level.
+
+The first is this file, ARM_DELIVERY_97412.TXT, which is the delivery
+note.
+
+The second is ARM_MANIFEST_97412.TXT which contains a manifest of all the
+files included in this transaction, together with their checksums.
+
+The checksums provided are calculated using the RSA Data Security, Inc.
+MD5 Message-Digest Algorithm.
+
+The checksums can be used to verify the integrity of this data using the
+"md5sum" tool (which is part of the GNU "textutils" package) by running:
+
+ % md5sum --check ARM_MANIFEST_97412.TXT
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/ARM_MANIFEST.TXT b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/ARM_MANIFEST.TXT
new file mode 100644
index 0000000..8e01b1e
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/ARM_MANIFEST.TXT
@@ -0,0 +1,140 @@
+ OX000-SW-98010-r0p0-00bet1/
+ OX000-SW-98010-r0p0-00bet1/api/
+8971932d56eed6b1ad1ba507f0bff5f0 OX000-SW-98010-r0p0-00bet1/api/armCOMM_Bitstream.h
+e88ec84e122534092b90c67841549d6f OX000-SW-98010-r0p0-00bet1/api/armCOMM_Version.h
+43cf46c2cf2fe1f93c615b57bcbe4809 OX000-SW-98010-r0p0-00bet1/api/armCOMM.h
+f87fedd9ca432fefa757008176864ef8 OX000-SW-98010-r0p0-00bet1/api/armOMX.h
+8e49899a428822c36ef9dd94e0e05f18 OX000-SW-98010-r0p0-00bet1/api/omxtypes.h
+a06983abb39c476b081e87ea271361a5 OX000-SW-98010-r0p0-00bet1/build_vc.pl
+c01f8b93ab73d8c00ddf2499f01da5ff OX000-SW-98010-r0p0-00bet1/filelist_vc.txt
+ OX000-SW-98010-r0p0-00bet1/src/
+26e2ff3f633764eb720deb340978dc2d OX000-SW-98010-r0p0-00bet1/src/armCOMM_Bitstream.c
+79aa23d9817efd11d0c4c2be36ec1e5c OX000-SW-98010-r0p0-00bet1/src/armCOMM.c
+ OX000-SW-98010-r0p0-00bet1/vc/
+ OX000-SW-98010-r0p0-00bet1/vc/m4p10/
+ OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/
+e45297704d72302d4a947d0798c666fb OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_CAVLCTables.c
+205dfafe1fe7bb160bf36d2600e1100a OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_DeblockLuma_I.c
+bf92641e8548577b77e04e03ec04c358 OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_MEGetBufSize.c
+f5ee6f7be822d87471cef3b1801dbfc2 OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_VerEdge_I.c
+28110b3a13cecf4f216d10bcc761c401 OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_Interpolate_Chroma.c
+9a1a25245c975d641e1c6378834aea4d OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_InterpolateHalfVer_Luma.c
+3a643eaaaeb12e8d274dc59a7357a586 OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_HorEdge_I.c
+4c4de5973a6b74250ce91ac0b317a617 OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_InvTransformDequant_LumaDC.c
+4ecdbe9193aaba1f9bb0e24c938b34f9 OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_UnpackBlock2x2.c
+66e912f8c88f6019cba3ede27150a407 OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_InterpolateLuma.c
+266da42f4e3015e67b2cbb58169d437f OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_InterpolateHalfDiag_Luma.c
+d905247eeaa52d4e2cf5f6bc3f61b348 OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_DecodeCoeffsToPair.c
+5b29448db0495cd1717a4b925f13377c OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_PredictIntra_16x16.c
+f6451df27f6dcc99036b4b1253c23bb6 OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_HorEdge_I.c
+892787d850eef09dc2148d45b416b062 OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_TransformQuant_ChromaDC.c
+33da1c01a31f47c0f3aea9a7a5eaa9be OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_BlockMatch_Quarter.c
+e9fb11b066775283dcfeae8d12a6c97a OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_InterpolateHalfVer_Luma.c
+add97bec08e5e1a538aa8607168e61ba OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_PredictIntraChroma_8x8.c
+b695ecfc917b39470d1f40773b923972 OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_PredictIntraDC4x4.c
+51bc596fd2ff61ad5450d7138461f4a1 OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_MEInit.c
+dc6baa0a388dc5ea8ff65c24b179e670 OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_GetVLCInfo.c
+a5499902996576f6712849db34d5ad65 OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_VerEdge_I.c
+0c3b76745d53e74a8e64e80def31faba OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_PredictIntra_4x4.c
+4f2742ba5a3c2208f53bc0f6a443be14 OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_SADQuar_4x.c
+b4ae2dc948e8ca64831fe3bbfbd89523 OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_InterpolateChroma.c
+e15118cbe372db7cadba225c9456f189 OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_SADQuar.c
+623cf336cfce7d0174f4e54072456f33 OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_InvTransformResidualAndAdd.c
+89e452c80e30357cadfb04c05b6fe00c OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_InterpolateHalfHor_Luma.c
+3a5551cc54e85bbe34fc966c7dc00f1c OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_BlockMatch_Integer.c
+114030fa0d8f00af6d3289f47a5e85bf OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_DecodeCoeffsToPairCAVLC.c
+9e373ab296fb85bb45565a6c384f6ed8 OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_DequantTables.c
+2d200f7cc230f302da48c589da42c02f OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_UnpackBlock4x4.c
+ea3f1d1d1507b55610b1349c7b5946e8 OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_TransformDequantChromaDCFromPair.c
+bd2bf1743aef2a9396545ed025362be2 OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_Average_4x.c
+ca68e809567bf89044631b67d228c7ce OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_DeblockChroma_I.c
+77caf2b5cbee96d360a919f27e1f14f4 OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_QuantTables.c
+26081e384ec627fedad474a0e7dad877 OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_SADQuar_8x.c
+1c83ae9207a54944936f4a63c665bd99 OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_MotionEstimationMB.c
+4c36e04db20200f4ec72e5aba57446fd OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_SATD_4x4.c
+f75b7c5a80d8bf33e315380e4ef0ab8a OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_InterpolateHalfHor_Luma.c
+488925bb7aeeae0ccf93ec44af9fce35 OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_SADQuar_16x.c
+c91a5345b5f877b3831ed1abcc60d579 OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_BlockMatch_Half.c
+35515a115a32fcac8479072a9a5b0db9 OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_Interpolate_Luma.c
+fdcf4622bc5f0ae75bdb0a51dcd03397 OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_TransformQuant_LumaDC.c
+74c9278177400a1f7cc6d799a8c8ab34 OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_SAD_4x.c
+56aa2d506d0cfdb4ebd366c07adb2d85 OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_DeBlockPixel.c
+36b2165fd4d2a7f3f3e1f8daff4f94e5 OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_SubAndTransformQDQResidual.c
+4b6b1b933fc7bc8f14a184c02c028085 OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_TransformResidual4x4.c
+cf0ff093a9b372dd3271e3e5c28984d4 OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_TransformDequantLumaDCFromPair.c
+9ccad9f894fbd32194f5b53da217072a OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_InvTransformDequant_ChromaDC.c
+4943a7a2df7e9d700675f8c1debf4d90 OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_CompareMotionCostToMV.c
+29e4a7f38f8c2e8246ed756db03c012e OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/armVCM4P10_FwdTransformResidual4x4.c
+27bc64e7c18da0aab9c987a388f61608 OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c
+859185614bb9d0013861e454d7b918f2 OX000-SW-98010-r0p0-00bet1/vc/m4p10/src/omxVCM4P10_DequantTransformResidualFromPairAndAdd.c
+ OX000-SW-98010-r0p0-00bet1/vc/m4p10/api/
+63e3b64b96cc42a235c04f3a0f991316 OX000-SW-98010-r0p0-00bet1/vc/m4p10/api/armVCM4P10_CAVLCTables.h
+ OX000-SW-98010-r0p0-00bet1/vc/m4p2/
+ OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/
+0aae4f683d8903cba9956d3301ed9ffe OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/armVCM4P2_ACDCPredict.c
+8d6c1b44915329165df643081cc11a97 OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_MCReconBlock.c
+0435eca930eacda0f2a59e843d405eff OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_MotionEstimationMB.c
+9a82dd0b1f05f798567436a009d02969 OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_DecodePadMV_PVOP.c
+e1e24646c4bd03f5df78295452dd4eb2 OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_BlockMatch_Integer_8x8.c
+746e6b334e4a26d4a9bfae6d735826f6 OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_DCT8x8blk.c
+8b1d87b74d80ff13a16215b61d5e52ba OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_IDCT8x8blk.c
+309358d357baafc38d2b37bf1e9768a9 OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_QuantInvInter_I.c
+cc77c7242b53c153f8d09527583f2771 OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_FindMVpred.c
+7cd8e7796017e3dd00b494d34f629f3f OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_MEGetBufSize.c
+a4905cb5f8d4b244454ee4f60d18358b OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/armVCM4P2_PutVLCBits.c
+5596b31e433222c1e4860deebfa98ef2 OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/armVCM4P2_DCT_Table.c
+365d072be6eab201f6e040058a3bacfc OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/armVCM4P2_BlockMatch_Integer.c
+78ed2212585b0cca75913a473b2ec430 OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_EncodeVLCZigzag_IntraACVLC.c
+50b2d8da8f20f6b1d39b8d3df38af55d OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_EncodeMV.c
+4a851a2ad6d357cdc233d9c0bf475e02 OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/armVCM4P2_BlockMatch_Half.c
+0d6d63878f2827e00e5f85b1e8e26017 OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/armVCM4P2_Zigzag_Tables.c
+48b865a983fe5bf3075eddf652950722 OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_PredictReconCoefIntra.c
+5f48fa7941835c46ac767e63fc29403b OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_EncodeVLCZigzag_IntraDCVLC.c
+bbaf454b64b32b2c42a76a7ec393d977 OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/armVCM4P2_CompareMV.c
+eebff772f87a414436c5c5286f2cd213 OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_MEInit.c
+65ae242eb8cb6d1027677c8ef8f77ca0 OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/armVCM4P2_FillVLCBuffer.c
+125642b1ea0c1256d79af1e0ddecae93 OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_QuantInter_I.c
+ce24ba3d83da4cb791485d3128268bf6 OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_TransRecBlockCoef_intra.c
+09bc09a2e6fd962e719944582e38a8fd OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Intra.c
+6b0ee7a116471a4dadbe5bc8dbf425b0 OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/armVCM4P2_FillVLDBuffer.c
+21322dca027c28353e3e7eb8f3620062 OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/armVCM4P2_CheckVLCEscapeMode.c
+ef353d83244288d8c37e0f70249177cc OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/armVCM4P2_GetVLCBits.c
+541de824f8aebe4a5cac6f15da943efa OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_BlockMatch_Half_8x8.c
+0b40b154b591c7f8842cffe4042d17c5 OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/armVCM4P2_Huff_Tables_VLC.c
+2ffcec88d3fcb372543a8f4508ea1ac6 OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_QuantIntra_I.c
+e06d85ca000afcbb50580f98f0203ac8 OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraACVLC.c
+ae82b6fcfcf731a61d70e1aa42e6277a OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_BlockMatch_Integer_16x16.c
+1d04395e231b597562257e98cda6cfb0 OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Inter.c
+72c0a36327b6b9b436d3bce7c896c520 OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraDCVLC.c
+1b65aa7f311124ea6fb47e384ec06a50 OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_QuantInvIntra_I.c
+714957104a6ef71341fbe6a9ec65c136 OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/armVCM4P2_SetPredDir.c
+86493f0ee853f653354a7389f1727f73 OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_TransRecBlockCoef_inter.c
+5de8afcfb3052968794782a7c3a0b41a OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_EncodeVLCZigzag_Inter.c
+50bcc228cc660dbda037725309de3f8b OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/armVCM4P2_EncodeVLCZigzag_intra.c
+4f5cfa1ecc668913dde94e3caf97a2e1 OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/armVCM4P2_DecodeVLCZigzag_intra.c
+c2ec804ddf64ee841146e39c3a783451 OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_BlockMatch_Half_16x16.c
+4087f6a827912ee5b45ed4217f1a6d77 OX000-SW-98010-r0p0-00bet1/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_Inter.c
+ OX000-SW-98010-r0p0-00bet1/vc/m4p2/api/
+5c711702dddcec85298003860d760cec OX000-SW-98010-r0p0-00bet1/vc/m4p2/api/armVCM4P2_DCT_Table.h
+1b92c94b785c03ec76d4fae2f2bbdb8a OX000-SW-98010-r0p0-00bet1/vc/m4p2/api/armVCM4P2_ZigZag_Tables.h
+ad9c6986d2a3200dd5e1f6103a54a99b OX000-SW-98010-r0p0-00bet1/vc/m4p2/api/armVCM4P2_Huff_Tables_VLC.h
+ OX000-SW-98010-r0p0-00bet1/vc/src/
+e627b3346b0dc9aff14446005ce0fa43 OX000-SW-98010-r0p0-00bet1/vc/src/armVC_Version.c
+ OX000-SW-98010-r0p0-00bet1/vc/api/
+7ca94b1c33ac0211e17d38baadd7d1dd OX000-SW-98010-r0p0-00bet1/vc/api/armVC.h
+12cf7596edbbf6048b626d15e8d0ed48 OX000-SW-98010-r0p0-00bet1/vc/api/omxVC.h
+ OX000-SW-98010-r0p0-00bet1/vc/comm/
+ OX000-SW-98010-r0p0-00bet1/vc/comm/src/
+3a6df0085736cbcbe2e3f45d08af4221 OX000-SW-98010-r0p0-00bet1/vc/comm/src/armVCCOMM_Average.c
+0bf3cb52863c829b28c0352835170211 OX000-SW-98010-r0p0-00bet1/vc/comm/src/omxVCCOMM_Copy8x8.c
+538b62f510b5a8bdced4a39fa12d9a23 OX000-SW-98010-r0p0-00bet1/vc/comm/src/omxVCCOMM_ComputeTextureErrorBlock_SAD.c
+66993edd9d441bf3b5b6c912f6400b6e OX000-SW-98010-r0p0-00bet1/vc/comm/src/omxVCCOMM_ExpandFrame_I.c
+8e526a9007eb0d43ebf362c498b37415 OX000-SW-98010-r0p0-00bet1/vc/comm/src/omxVCCOMM_LimitMVToRect.c
+87f8f26e6e9178df0ab7419334d5a3db OX000-SW-98010-r0p0-00bet1/vc/comm/src/omxVCCOMM_SAD_16x.c
+1a8577646132ad9b63a1477fdaec2464 OX000-SW-98010-r0p0-00bet1/vc/comm/src/omxVCCOMM_Average_16x.c
+48529c4f70c7e954e832eece1aee57bd OX000-SW-98010-r0p0-00bet1/vc/comm/src/omxVCCOMM_SAD_8x.c
+252977764d4f38282b6a56c59ccf4f09 OX000-SW-98010-r0p0-00bet1/vc/comm/src/armVCCOMM_SAD.c
+cc78cfaed9502c2e0282c91fb95eeac4 OX000-SW-98010-r0p0-00bet1/vc/comm/src/omxVCCOMM_Average_8x.c
+e468751c15a581ebd22da031e22117d1 OX000-SW-98010-r0p0-00bet1/vc/comm/src/omxVCCOMM_Copy16x16.c
+3f448d191eaeb82ecb7e27ef8ba27875 OX000-SW-98010-r0p0-00bet1/vc/comm/src/omxVCCOMM_ComputeTextureErrorBlock.c
+b1291c307808631fa833684abb9c34ce ARM_DELIVERY_97412.TXT
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/armCOMM.h b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/armCOMM.h
new file mode 100644
index 0000000..2ed86a4
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/armCOMM.h
@@ -0,0 +1,785 @@
+/**
+ *
+ * File Name: armCOMM.h
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * File: armCOMM.h
+ * Brief: Declares Common APIs/Data Types used across OpenMAX API's
+ *
+ */
+
+
+#ifndef _armCommon_H_
+#define _armCommon_H_
+
+#include "omxtypes.h"
+
+typedef struct
+{
+ OMX_F32 Re; /** Real part */
+ OMX_F32 Im; /** Imaginary part */
+
+} OMX_FC32; /** single precision floating point complex number */
+
+typedef struct
+{
+ OMX_F64 Re; /** Real part */
+ OMX_F64 Im; /** Imaginary part */
+
+} OMX_FC64; /** double precision floating point complex number */
+
+
+/* Used by both IP and IC domains for 8x8 JPEG blocks. */
+typedef OMX_S16 ARM_BLOCK8x8[64];
+
+
+#include "armOMX.h"
+
+#define armPI (OMX_F64)(3.1415926535897932384626433832795)
+
+/***********************************************************************/
+
+/* Compiler extensions */
+#ifdef ARM_DEBUG
+/* debug version */
+#include <stdlib.h>
+#include <assert.h>
+#include <stdio.h>
+#define armError(str) {printf((str)); printf("\n"); exit(-1);}
+#define armWarn(str) {printf((str)); printf("\n");}
+#define armIgnore(a) ((void)a)
+#define armAssert(a) assert(a)
+#else
+/* release version */
+#define armError(str) ((void) (str))
+#define armWarn(str) ((void) (str))
+#define armIgnore(a) ((void) (a))
+#define armAssert(a) ((void) (a))
+#endif /* ARM_DEBUG */
+
+/* Arithmetic operations */
+
+#define armMin(a,b) ( (a) > (b) ? (b):(a) )
+#define armMax(a,b) ( (a) > (b) ? (a):(b) )
+#define armAbs(a) ( (a) < 0 ? -(a):(a) )
+
+/* Alignment operation */
+
+#define armAlignToBytes(Ptr,N) (Ptr + ( ((N-(int)Ptr)&(N-1)) / sizeof(*Ptr) ))
+#define armAlignTo2Bytes(Ptr) armAlignToBytes(Ptr,2)
+#define armAlignTo4Bytes(Ptr) armAlignToBytes(Ptr,4)
+#define armAlignTo8Bytes(Ptr) armAlignToBytes(Ptr,8)
+#define armAlignTo16Bytes(Ptr) armAlignToBytes(Ptr,16)
+
+/* Error and Alignment check */
+
+#define armRetArgErrIf(condition, code) if(condition) { return (code); }
+#define armRetDataErrIf(condition, code) if(condition) { return (code); }
+
+#ifndef ALIGNMENT_DOESNT_MATTER
+#define armIsByteAligned(Ptr,N) ((((int)(Ptr)) % N)==0)
+#define armNotByteAligned(Ptr,N) ((((int)(Ptr)) % N)!=0)
+#else
+#define armIsByteAligned(Ptr,N) (1)
+#define armNotByteAligned(Ptr,N) (0)
+#endif
+
+#define armIs2ByteAligned(Ptr) armIsByteAligned(Ptr,2)
+#define armIs4ByteAligned(Ptr) armIsByteAligned(Ptr,4)
+#define armIs8ByteAligned(Ptr) armIsByteAligned(Ptr,8)
+#define armIs16ByteAligned(Ptr) armIsByteAligned(Ptr,16)
+
+#define armNot2ByteAligned(Ptr) armNotByteAligned(Ptr,2)
+#define armNot4ByteAligned(Ptr) armNotByteAligned(Ptr,4)
+#define armNot8ByteAligned(Ptr) armNotByteAligned(Ptr,8)
+#define armNot16ByteAligned(Ptr) armNotByteAligned(Ptr,16)
+#define armNot32ByteAligned(Ptr) armNotByteAligned(Ptr,32)
+
+/**
+ * Function: armRoundFloatToS16_ref/armRoundFloatToS32_ref/armRoundFloatToS64
+ *
+ * Description:
+ * Converts a double precision value into a short int/int after rounding
+ *
+ * Parameters:
+ * [in] Value Float value to be converted
+ *
+ * Return Value:
+ * [out] converted value in OMX_S16/OMX_S32 format
+ *
+ */
+
+OMX_S16 armRoundFloatToS16 (OMX_F64 Value);
+OMX_S32 armRoundFloatToS32 (OMX_F64 Value);
+OMX_S64 armRoundFloatToS64 (OMX_F64 Value);
+
+/**
+ * Function: armSatRoundFloatToS16_ref/armSatRoundFloatToS32
+ *
+ * Description:
+ * Converts a double precision value into a short int/int after rounding and saturation
+ *
+ * Parameters:
+ * [in] Value Float value to be converted
+ *
+ * Return Value:
+ * [out] converted value in OMX_S16/OMX_S32 format
+ *
+ */
+
+OMX_S16 armSatRoundFloatToS16 (OMX_F64 Value);
+OMX_S32 armSatRoundFloatToS32 (OMX_F64 Value);
+
+/**
+ * Function: armSatRoundFloatToU16_ref/armSatRoundFloatToU32
+ *
+ * Description:
+ * Converts a double precision value into a unsigned short int/int after rounding and saturation
+ *
+ * Parameters:
+ * [in] Value Float value to be converted
+ *
+ * Return Value:
+ * [out] converted value in OMX_U16/OMX_U32 format
+ *
+ */
+
+OMX_U16 armSatRoundFloatToU16 (OMX_F64 Value);
+OMX_U32 armSatRoundFloatToU32 (OMX_F64 Value);
+
+/**
+ * Function: armSignCheck
+ *
+ * Description:
+ * Checks the sign of a variable:
+ * returns 1 if it is Positive
+ * returns 0 if it is 0
+ * returns -1 if it is Negative
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] var Variable to be checked
+ *
+ * Return Value:
+ * OMX_INT -- returns 1 if it is Positive
+ * returns 0 if it is 0
+ * returns -1 if it is Negative
+ */
+
+OMX_INT armSignCheck (OMX_S16 var);
+
+/**
+ * Function: armClip
+ *
+ * Description: Clips the input between MAX and MIN value
+ *
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] Min lower bound
+ * [in] Max upper bound
+ * [in] src variable to the clipped
+ *
+ * Return Value:
+ * OMX_S32 -- returns clipped value
+ */
+
+OMX_S32 armClip (
+ OMX_INT min,
+ OMX_INT max,
+ OMX_S32 src
+ );
+
+/**
+ * Function: armClip_F32
+ *
+ * Description: Clips the input between MAX and MIN value
+ *
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] Min lower bound
+ * [in] Max upper bound
+ * [in] src variable to the clipped
+ *
+ * Return Value:
+ * OMX_F32 -- returns clipped value
+ */
+
+OMX_F32 armClip_F32 (
+ OMX_F32 min,
+ OMX_F32 max,
+ OMX_F32 src
+ );
+
+/**
+ * Function: armShiftSat_F32
+ *
+ * Description: Divides a float value by 2^shift and
+ * saturates it for unsigned value range for satBits.
+ * Second parameter is like "shifting" the corresponding
+ * integer value. Takes care of rounding while clipping the final
+ * value.
+ *
+ * Parameters:
+ * [in] v Number to be operated upon
+ * [in] shift Divides the input "v" by "2^shift"
+ * [in] satBits Final range is [0, 2^satBits)
+ *
+ * Return Value:
+ * OMX_S32 -- returns "shifted" saturated value
+ */
+
+OMX_U32 armShiftSat_F32(
+ OMX_F32 v,
+ OMX_INT shift,
+ OMX_INT satBits
+ );
+
+/**
+ * Functions: armSwapElem
+ *
+ * Description:
+ * This function swaps two elements at the specified pointer locations.
+ * The size of each element could be anything as specified by <elemSize>
+ *
+ * Return Value:
+ * OMXResult -- Error status from the function
+ */
+OMXResult armSwapElem(OMX_U8 *pBuf1, OMX_U8 *pBuf2, OMX_INT elemSize);
+
+
+/**
+ * Function: armMedianOf3
+ *
+ * Description: Finds the median of three numbers
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] fEntry First entry
+ * [in] sEntry second entry
+ * [in] tEntry Third entry
+ *
+ * Return Value:
+ * OMX_S32 -- returns the median value
+ */
+
+OMX_S32 armMedianOf3 (
+ OMX_S32 fEntry,
+ OMX_S32 sEntry,
+ OMX_S32 tEntry
+ );
+
+/**
+ * Function: armLogSize
+ *
+ * Description: Finds the size of a positive value and returns the same
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] value Positive value
+ *
+ * Return Value:
+ * OMX_U8 -- returns the size of the positive value
+ */
+
+OMX_U8 armLogSize (
+ OMX_U16 value
+ );
+
+/***********************************************************************/
+ /* Saturating Arithmetic operations */
+
+/**
+ * Function :armSatAdd_S32()
+ *
+ * Description :
+ * Returns the result of saturated addition of the two inputs Value1, Value2
+ *
+ * Parametrs:
+ * [in] Value1 First Operand
+ * [in] Value2 Second Operand
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ *
+ **/
+
+OMX_S32 armSatAdd_S32(
+ OMX_S32 Value1,
+ OMX_S32 Value2
+ );
+
+/**
+ * Function :armSatAdd_S64()
+ *
+ * Description :
+ * Returns the result of saturated addition of the two inputs Value1, Value2
+ *
+ * Parametrs:
+ * [in] Value1 First Operand
+ * [in] Value2 Second Operand
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ *
+ **/
+
+OMX_S64 armSatAdd_S64(
+ OMX_S64 Value1,
+ OMX_S64 Value2
+ );
+
+/** Function :armSatSub_S32()
+ *
+ * Description :
+ * Returns the result of saturated substraction of the two inputs Value1, Value2
+ *
+ * Parametrs:
+ * [in] Value1 First Operand
+ * [in] Value2 Second Operand
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ **/
+
+OMX_S32 armSatSub_S32(
+ OMX_S32 Value1,
+ OMX_S32 Value2
+ );
+
+/**
+ * Function :armSatMac_S32()
+ *
+ * Description :
+ * Returns the result of Multiplication of Value1 and Value2 and subesquent saturated
+ * accumulation with Mac
+ *
+ * Parametrs:
+ * [in] Value1 First Operand
+ * [in] Value2 Second Operand
+ * [in] Mac Accumulator
+ *
+ * Return:
+ * [out] Result of operation
+ **/
+
+OMX_S32 armSatMac_S32(
+ OMX_S32 Mac,
+ OMX_S16 Value1,
+ OMX_S16 Value2
+ );
+
+/**
+ * Function :armSatMac_S16S32_S32
+ *
+ * Description :
+ * Returns the result of saturated MAC operation of the three inputs delayElem, filTap , mac
+ *
+ * mac = mac + Saturate_in_32Bits(delayElem * filTap)
+ *
+ * Parametrs:
+ * [in] delayElem First 32 bit Operand
+ * [in] filTap Second 16 bit Operand
+ * [in] mac Result of MAC operation
+ *
+ * Return:
+ * [out] mac Result of operation
+ *
+ **/
+
+OMX_S32 armSatMac_S16S32_S32(
+ OMX_S32 mac,
+ OMX_S32 delayElem,
+ OMX_S16 filTap );
+
+/**
+ * Function :armSatRoundRightShift_S32_S16
+ *
+ * Description :
+ * Returns the result of rounded right shift operation of input by the scalefactor
+ *
+ * output = Saturate_in_16Bits( ( RightShift( (Round(input) , scaleFactor ) )
+ *
+ * Parametrs:
+ * [in] input The input to be operated on
+ * [in] scaleFactor The shift number
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ **/
+
+
+OMX_S16 armSatRoundRightShift_S32_S16(
+ OMX_S32 input,
+ OMX_INT scaleFactor);
+
+/**
+ * Function :armSatRoundLeftShift_S32()
+ *
+ * Description :
+ * Returns the result of saturating left-shift operation on input
+ * Or rounded Right shift if the input Shift is negative.
+ *
+ * Parametrs:
+ * [in] Value Operand
+ * [in] shift Operand for shift operation
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ **/
+
+OMX_S32 armSatRoundLeftShift_S32(
+ OMX_S32 Value,
+ OMX_INT shift
+ );
+
+/**
+ * Function :armSatRoundLeftShift_S64()
+ *
+ * Description :
+ * Returns the result of saturating left-shift operation on input
+ * Or rounded Right shift if the input Shift is negative.
+ *
+ * Parametrs:
+ * [in] Value Operand
+ * [in] shift Operand for shift operation
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ **/
+
+OMX_S64 armSatRoundLeftShift_S64(
+ OMX_S64 Value,
+ OMX_INT shift
+ );
+
+/**
+ * Function :armSatMulS16S32_S32()
+ *
+ * Description :
+ * Returns the result of a S16 data type multiplied with an S32 data type
+ * in a S32 container
+ *
+ * Parametrs:
+ * [in] input1 Operand 1
+ * [in] input2 Operand 2
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ **/
+
+
+OMX_S32 armSatMulS16S32_S32(
+ OMX_S16 input1,
+ OMX_S32 input2);
+
+/**
+ * Function :armSatMulS32S32_S32()
+ *
+ * Description :
+ * Returns the result of a S32 data type multiplied with an S32 data type
+ * in a S32 container
+ *
+ * Parametrs:
+ * [in] input1 Operand 1
+ * [in] input2 Operand 2
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ **/
+
+OMX_S32 armSatMulS32S32_S32(
+ OMX_S32 input1,
+ OMX_S32 input2);
+
+
+/**
+ * Function :armIntDivAwayFromZero()
+ *
+ * Description : Integer division with rounding to the nearest integer.
+ * Half-integer values are rounded away from zero
+ * unless otherwise specified. For example 3//2 is rounded
+ * to 2, and -3//2 is rounded to -2.
+ *
+ * Parametrs:
+ * [in] Num Operand 1
+ * [in] Deno Operand 2
+ *
+ * Return:
+ * [out] Result of operation input1//input2
+ *
+ **/
+
+OMX_S32 armIntDivAwayFromZero (OMX_S32 Num, OMX_S32 Deno);
+
+
+/***********************************************************************/
+/*
+ * Debugging macros
+ *
+ */
+
+
+/*
+ * Definition of output stream - change to stderr if necessary
+ */
+#define DEBUG_STREAM stdout
+
+/*
+ * Debug printf macros, one for each argument count.
+ * Add more if needed.
+ */
+#ifdef DEBUG_ON
+#include <stdio.h>
+
+#define DEBUG_PRINTF_0(a) fprintf(DEBUG_STREAM, a)
+#define DEBUG_PRINTF_1(a, b) fprintf(DEBUG_STREAM, a, b)
+#define DEBUG_PRINTF_2(a, b, c) fprintf(DEBUG_STREAM, a, b, c)
+#define DEBUG_PRINTF_3(a, b, c, d) fprintf(DEBUG_STREAM, a, b, c, d)
+#define DEBUG_PRINTF_4(a, b, c, d, e) fprintf(DEBUG_STREAM, a, b, c, d, e)
+#define DEBUG_PRINTF_5(a, b, c, d, e, f) fprintf(DEBUG_STREAM, a, b, c, d, e, f)
+#define DEBUG_PRINTF_6(a, b, c, d, e, f, g) fprintf(DEBUG_STREAM, a, b, c, d, e, f, g)
+#define DEBUG_PRINTF_7(a, b, c, d, e, f, g, h) fprintf(DEBUG_STREAM, a, b, c, d, e, f, g, h)
+#define DEBUG_PRINTF_8(a, b, c, d, e, f, g, h, i) fprintf(DEBUG_STREAM, a, b, c, d, e, f, g, h, i)
+#define DEBUG_PRINTF_9(a, b, c, d, e, f, g, h, i, j) fprintf(DEBUG_STREAM, a, b, c, d, e, f, g, h, i, j)
+#define DEBUG_PRINTF_10(a, b, c, d, e, f, g, h, i, j, k) fprintf(DEBUG_STREAM, a, b, c, d, e, f, g, h, i, j, k)
+#define DEBUG_PRINTF_11(a, b, c, d, e, f, g, h, i, j, k, l) fprintf(DEBUG_STREAM, a, b, c, d, e, f, g, h, i, j, k, l)
+#define DEBUG_PRINTF_12(a, b, c, d, e, f, g, h, i, j, k, l, m) fprintf(DEBUG_STREAM, a, b, c, d, e, f, g, h, i, j, k, l, m)
+#define DEBUG_PRINTF_13(a, b, c, d, e, f, g, h, i, j, k, l, m, n) fprintf(DEBUG_STREAM, a, b, c, d, e, f, g, h, i, j, k, l, m, n)
+#define DEBUG_PRINTF_14(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) fprintf(DEBUG_STREAM, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)
+#else /* DEBUG_ON */
+#define DEBUG_PRINTF_0(a)
+#define DEBUG_PRINTF_1(a, b)
+#define DEBUG_PRINTF_2(a, b, c)
+#define DEBUG_PRINTF_3(a, b, c, d)
+#define DEBUG_PRINTF_4(a, b, c, d, e)
+#define DEBUG_PRINTF_5(a, b, c, d, e, f)
+#define DEBUG_PRINTF_6(a, b, c, d, e, f, g)
+#define DEBUG_PRINTF_7(a, b, c, d, e, f, g, h)
+#define DEBUG_PRINTF_8(a, b, c, d, e, f, g, h, i)
+#define DEBUG_PRINTF_9(a, b, c, d, e, f, g, h, i, j)
+#define DEBUG_PRINTF_10(a, b, c, d, e, f, g, h, i, j, k)
+#define DEBUG_PRINTF_11(a, b, c, d, e, f, g, h, i, j, k, l)
+#define DEBUG_PRINTF_12(a, b, c, d, e, f, g, h, i, j, k, l, m)
+#define DEBUG_PRINTF_13(a, b, c, d, e, f, g, h, i, j, k, l, m, n)
+#define DEBUG_PRINTF_14(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)
+#endif /* DEBUG_ON */
+
+
+/*
+ * Domain and sub domain definitions
+ *
+ * In order to turn on debug for an entire domain or sub-domain
+ * at compile time, one of the DEBUG_DOMAIN_* below may be defined,
+ * which will activate debug in all of the defines it contains.
+ */
+
+#ifdef DEBUG_DOMAIN_AC
+#define DEBUG_OMXACAAC_DECODECHANPAIRELT_MPEG4
+#define DEBUG_OMXACAAC_DECODECHANPAIRELT
+#define DEBUG_OMXACAAC_DECODEDATSTRELT
+#define DEBUG_OMXACAAC_DECODEFILLELT
+#define DEBUG_OMXACAAC_DECODEISSTEREO_S32
+#define DEBUG_OMXACAAC_DECODEMSPNS_S32
+#define DEBUG_OMXACAAC_DECODEMSSTEREO_S32_I
+#define DEBUG_OMXACAAC_DECODEPRGCFGELT
+#define DEBUG_OMXACAAC_DECODETNS_S32_I
+#define DEBUG_OMXACAAC_DEINTERLEAVESPECTRUM_S32
+#define DEBUG_OMXACAAC_ENCODETNS_S32_I
+#define DEBUG_OMXACAAC_LONGTERMPREDICT_S32
+#define DEBUG_OMXACAAC_LONGTERMRECONSTRUCT_S32
+#define DEBUG_OMXACAAC_MDCTFWD_S32
+#define DEBUG_OMXACAAC_MDCTINV_S32_S16
+#define DEBUG_OMXACAAC_NOISELESSDECODE
+#define DEBUG_OMXACAAC_QUANTINV_S32_I
+#define DEBUG_OMXACAAC_UNPACKADIFHEADER
+#define DEBUG_OMXACAAC_UNPACKADTSFRAMEHEADER
+#define DEBUG_OMXACMP3_HUFFMANDECODESFBMBP_S32
+#define DEBUG_OMXACMP3_HUFFMANDECODESFB_S32
+#define DEBUG_OMXACMP3_HUFFMANDECODE_S32
+#define DEBUG_OMXACMP3_MDCTINV_S32
+#define DEBUG_OMXACMP3_REQUANTIZESFB_S32_I
+#define DEBUG_OMXACMP3_REQUANTIZE_S32_I
+#define DEBUG_OMXACMP3_SYNTHPQMF_S32_S16
+#define DEBUG_OMXACMP3_UNPACKFRAMEHEADER
+#define DEBUG_OMXACMP3_UNPACKSCALEFACTORS_S8
+#define DEBUG_OMXACMP3_UNPACKSIDEINFO
+#endif /* DEBUG_DOMAIN_AC */
+
+
+#ifdef DEBUG_DOMAIN_VC
+#define DEBUG_OMXVCM4P10_AVERAGE_16X
+#define DEBUG_OMXVCM4P10_AVERAGE_4X
+#define DEBUG_OMXVCM4P10_AVERAGE_8X
+#define DEBUG_OMXVCM4P10_DEBLOCKCHROMA_U8_C1IR
+#define DEBUG_OMXVCM4P10_DEBLOCKLUMA_U8_C1IR
+#define DEBUG_OMXVCM4P10_DECODECHROMADCCOEFFSTOPAIRCAVLC_U8
+#define DEBUG_OMXVCM4P10_DECODECOEFFSTOPAIRCAVLC_U8
+#define DEBUG_OMXVCM4P10_DEQUANTTRANSFORMACFROMPAIR_U8_S16_C1_DLX
+#define DEBUG_OMXVCM4P10_EXPANDFRAME
+#define DEBUG_OMXVCM4P10_FILTERDEBLOCKINGCHROMA_HOREDGE_U8_C1IR
+#define DEBUG_OMXVCM4P10_FILTERDEBLOCKINGCHROMA_VEREDGE_U8_C1IR
+#define DEBUG_OMXVCM4P10_FILTERDEBLOCKINGLUMA_HOREDGE_U8_C1IR
+#define DEBUG_OMXVCM4P10_FILTERDEBLOCKINGLUMA_VEREDGE_U8_C1IR
+#define DEBUG_OMXVCM4P10_PREDICTINTRACHROMA8X8_U8_C1R
+#define DEBUG_OMXVCM4P10_PREDICTINTRA_16X16_U8_C1R
+#define DEBUG_OMXVCM4P10_PREDICTINTRA_4X4_U8_C1R
+#define DEBUG_OMXVCM4P10_SADQUAR_16X
+#define DEBUG_OMXVCM4P10_SADQUAR_4X
+#define DEBUG_OMXVCM4P10_SADQUAR_8X
+#define DEBUG_OMXVCM4P10_SAD_16X
+#define DEBUG_OMXVCM4P10_SAD_4X
+#define DEBUG_OMXVCM4P10_SAD_8X
+#define DEBUG_OMXVCM4P10_SATD_4X4
+#define DEBUG_OMXVCM4P10_TRANSFORMDEQUANTCHROMADCFROMPAIR_U8_S16_C1
+#define DEBUG_OMXVCM4P10_TRANSFORMDEQUANTLUMADCFROMPAIR_U8_S16_C1
+#define DEBUG_OMXVCM4P10_TRANSFORMQUANT_CHROMADC
+#define DEBUG_OMXVCM4P10_TRANSFORMQUANT_LUMADC
+#define DEBUG_OMXVCM4P2_BLOCKMATCH_HALF_16X16
+#define DEBUG_OMXVCM4P2_BLOCKMATCH_HALF_8X8
+#define DEBUG_OMXVCM4P2_BLOCKMATCH_INTEGER_16X16
+#define DEBUG_OMXVCM4P2_BLOCKMATCH_INTEGER_8X8
+#define DEBUG_OMXVCM4P2_COMPUTETEXTUREERRORBLOCK_SAD_U8_S16
+#define DEBUG_OMXVCM4P2_COMPUTETEXTUREERRORBLOCK_U8_S16
+#define DEBUG_OMXVCM4P2_DCT8X8BLKDLX
+#define DEBUG_OMXVCM4P2_DECODEBLOCKCOEF_INTER_S16
+#define DEBUG_OMXVCM4P2_DECODEPADMV_PVOP
+#define DEBUG_OMXVCM4P2_DECODEVLCZIGZAG_INTER_S16
+#define DEBUG_OMXVCM4P2_DECODEVLCZIGZAG_INTRAACVLC_S16
+#define DEBUG_OMXVCM4P2_DECODEVLCZIGZAG_INTRADCVLC_S16
+#define DEBUG_OMXVCM4P2_ENCODEMV_U8_S16
+#define DEBUG_OMXVCM4P2_ENCODEVLCZIGZAG_INTER_S16
+#define DEBUG_OMXVCM4P2_ENCODEVLCZIGZAG_INTRAACVLC_S16
+#define DEBUG_OMXVCM4P2_ENCODEVLCZIGZAG_INTRADCVLC_S16
+#define DEBUG_OMXVCM4P2_FINDMVPRED
+#define DEBUG_OMXVCM4P2_IDCT8X8BLKDLX
+#define DEBUG_OMXVCM4P2_LIMITMVTORECT
+#define DEBUG_OMXVCM4P2_MOTIONESTIMATIONMB
+#define DEBUG_OMXVCM4P2_PADMBGRAY_U8
+#define DEBUG_OMXVCM4P2_PADMBHORIZONTAL_U8
+#define DEBUG_OMXVCM4P2_PADMBVERTICAL_U8
+#define DEBUG_OMXVCM4P2_PADMV
+#define DEBUG_OMXVCM4P2_QUANTINTER_S16_I
+#define DEBUG_OMXVCM4P2_QUANTINTRA_S16_I
+#define DEBUG_OMXVCM4P2_QUANTINVINTER_S16_I
+#define DEBUG_OMXVCM4P2_QUANTINVINTRA_S16_I
+#define DEBUG_OMXVCM4P2_TRANSRECBLOCKCEOF_INTER
+#define DEBUG_OMXVCM4P2_TRANSRECBLOCKCEOF_INTRA
+#endif /* DEBUG_DOMAIN_VC */
+
+
+#ifdef DEBUG_DOMAIN_IC
+/* To be filled in */
+#endif /* DEBUG_DOMAIN_IC */
+
+
+#ifdef DEBUG_DOMAIN_SP
+#define DEBUG_OMXACSP_DOTPROD_S16
+#define DEBUG_OMXACSP_BLOCKEXP_S16
+#define DEBUG_OMXACSP_BLOCKEXP_S32
+#define DEBUG_OMXACSP_COPY_S16
+#define DEBUG_OMXACSP_DOTPROD_S16
+#define DEBUG_OMXACSP_DOTPROD_S16_SFS
+#define DEBUG_OMXACSP_FFTFWD_CTOC_SC16_SFS
+#define DEBUG_OMXACSP_FFTFWD_CTOC_SC32_SFS
+#define DEBUG_OMXACSP_FFTFWD_RTOCCS_S16S32_SFS
+#define DEBUG_OMXACSP_FFTFWD_RTOCCS_S32_SFS
+#define DEBUG_OMXACSP_FFTGETBUFSIZE_C_SC16
+#define DEBUG_OMXACSP_FFTGETBUFSIZE_C_SC32
+#define DEBUG_OMXACSP_FFTGETBUFSIZE_R_S16_S32
+#define DEBUG_OMXACSP_FFTGETBUFSIZE_R_S32
+#define DEBUG_OMXACSP_FFTINIT_C_SC16
+#define DEBUG_OMXACSP_FFTINIT_C_SC32
+#define DEBUG_OMXACSP_FFTINIT_R_S16_S32
+#define DEBUG_OMXACSP_FFTINIT_R_S32
+#define DEBUG_OMXACSP_FFTINV_CCSTOR_S32S16_SFS
+#define DEBUG_OMXACSP_FFTINV_CCSTOR_S32_SFS
+#define DEBUG_OMXACSP_FFTINV_CTOC_SC16_SFS
+#define DEBUG_OMXACSP_FFTINV_CTOC_SC32_SFS
+#define DEBUG_OMXACSP_FILTERMEDIAN_S32_I
+#define DEBUG_OMXACSP_FILTERMEDIAN_S32
+#define DEBUG_OMXACSP_FIRONE_DIRECT_S16_ISFS
+#define DEBUG_OMXACSP_FIRONE_DIRECT_S16_I
+#define DEBUG_OMXACSP_FIRONE_DIRECT_S16
+#define DEBUG_OMXACSP_FIRONE_DIRECT_S16_SFS
+#define DEBUG_OMXACSP_FIR_DIRECT_S16_ISFS
+#define DEBUG_OMXACSP_FIR_DIRECT_S16_I
+#define DEBUG_OMXACSP_FIR_DIRECT_S16
+#define DEBUG_OMXACSP_FIR_DIRECT_S16_SFS
+#define DEBUG_OMXACSP_IIRONE_BIQUADDIRECT_S16_I
+#define DEBUG_OMXACSP_IIRONE_BIQUADDIRECT_S16
+#define DEBUG_OMXACSP_IIRONE_DIRECT_S16_I
+#define DEBUG_OMXACSP_IIRONE_DIRECT_S16
+#define DEBUG_OMXACSP_IIR_BIQUADDIRECT_S16_I
+#define DEBUG_OMXACSP_IIR_BIQUADDIRECT_S16
+#define DEBUG_OMXACSP_IIR_DIRECT_S16_I
+#define DEBUG_OMXACSP_IIR_DIRECT_S16
+#endif /* DEBUG_DOMAIN_SP */
+
+
+#ifdef DEBUG_DOMAIN_IP
+#define DEBUG_OMXIPBM_ADDC_U8_C1R_SFS
+#define DEBUG_OMXIPBM_COPY_U8_C1R
+#define DEBUG_OMXIPBM_COPY_U8_C3R
+#define DEBUG_OMXIPBM_MIRROR_U8_C1R
+#define DEBUG_OMXIPBM_MULC_U8_C1R_SFS
+#define DEBUG_OMXIPCS_COLORTWISTQ14_U8_C3R
+#define DEBUG_OMXIPCS_RGB565TOYCBCR420LS_MCU_U16_S16_C3P3R
+#define DEBUG_OMXIPCS_RGB565TOYCBCR422LS_MCU_U16_S16_C3P3R
+#define DEBUG_OMXIPCS_RGB565TOYCBCR444LS_MCU_U16_S16_C3P3R
+#define DEBUG_OMXIPCS_RGBTOYCBCR420LS_MCU_U8_S16_C3P3R
+#define DEBUG_OMXIPCS_RGBTOYCBCR422LS_MCU_U8_S16_C3P3R
+#define DEBUG_OMXIPCS_RGBTOYCBCR444LS_MCU_U8_S16_C3P3R
+#define DEBUG_OMXIPCS_YCBCR420RSZROT_U8_P3R
+#define DEBUG_OMXIPCS_YCBCR420TORGB565LS_MCU_S16_U16_P3C3R
+#define DEBUG_OMXIPCS_YCBCR420TORGB565_U8_U16_P3C3R
+#define DEBUG_OMXIPCS_YCBCR420TORGBLS_MCU_S16_U8_P3C3R
+#define DEBUG_OMXIPCS_YCBCR422RSZCSCROTRGB_U8_C2R
+#define DEBUG_OMXIPCS_YCBCR422RSZROT_U8_P3R
+#define DEBUG_OMXIPCS_YCBCR422TORGB565LS_MCU_S16_U16_P3C3R
+#define DEBUG_OMXIPCS_YCBCR422TORGB565_U8_U16_C2C3R
+#define DEBUG_OMXIPCS_YCBCR422TORGBLS_MCU_S16_U8_P3C3R
+#define DEBUG_OMXIPCS_YCBCR422TORGB_U8_C2C3R
+#define DEBUG_OMXIPCS_YCBCR422TOYCBCR420ROTATE_U8_C2P3R
+#define DEBUG_OMXIPCS_YCBCR422TOYCBCR420ROTATE_U8_P3R
+#define DEBUG_OMXIPCS_YCBCR444TORGB565LS_MCU_S16_U16_P3C3R
+#define DEBUG_OMXIPCS_YCBCR444TORGBLS_MCU_S16_U8_P3C3R
+#define DEBUG_OMXIPCS_YCBCRTORGB565_U8_U16_C3R
+#define DEBUG_OMXIPCS_YCBCRTORGB565_U8_U16_P3C3R
+#define DEBUG_OMXIPCS_YCBCRTORGB_U8_C3R
+#define DEBUG_OMXIPPP_GETCENTRALMOMENT_S64
+#define DEBUG_OMXIPPP_GETSPATIALMOMENT_S64
+#define DEBUG_OMXIPPP_MOMENTGETSTATESIZE_S64
+#define DEBUG_OMXIPPP_MOMENTINIT_S64
+#define DEBUG_OMXIPPP_MOMENTS64S_U8_C1R
+#define DEBUG_OMXIPPP_MOMENTS64S_U8_C3R
+#endif /* DEBUG_DOMAIN_IP */
+
+
+#endif /* _armCommon_H_ */
+
+/*End of File*/
+
+
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/armCOMM_Bitstream.h b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/armCOMM_Bitstream.h
new file mode 100644
index 0000000..4f9bc3b
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/armCOMM_Bitstream.h
@@ -0,0 +1,212 @@
+/**
+ *
+ * File Name: armCOMM_Bitstream.h
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * File: armCOMM_Bitstream.h
+ * Brief: Declares common API's/Data types used across the OpenMax Encoders/Decoders.
+ *
+ */
+
+#ifndef _armCodec_H_
+#define _armCodec_H_
+
+#include "omxtypes.h"
+
+typedef struct {
+ OMX_U8 codeLen;
+ OMX_U32 codeWord;
+} ARM_VLC32;
+
+/* The above should be renamed as "ARM_VLC32" */
+
+/**
+ * Function: armLookAheadBits()
+ *
+ * Description:
+ * Get the next N bits from the bitstream without advancing the bitstream pointer
+ *
+ * Parameters:
+ * [in] **ppBitStream
+ * [in] *pOffset
+ * [in] N=1...32
+ *
+ * Returns Value
+ */
+
+OMX_U32 armLookAheadBits(const OMX_U8 **ppBitStream, OMX_INT *pOffset, OMX_INT N);
+
+/**
+ * Function: armGetBits()
+ *
+ * Description:
+ * Read N bits from the bitstream
+ *
+ * Parameters:
+ * [in] *ppBitStream
+ * [in] *pOffset
+ * [in] N=1..32
+ *
+ * [out] *ppBitStream
+ * [out] *pOffset
+ * Returns Value
+ */
+
+OMX_U32 armGetBits(const OMX_U8 **ppBitStream, OMX_INT *pOffset, OMX_INT N);
+
+/**
+ * Function: armByteAlign()
+ *
+ * Description:
+ * Align the pointer *ppBitStream to the next byte boundary
+ *
+ * Parameters:
+ * [in] *ppBitStream
+ * [in] *pOffset
+ *
+ * [out] *ppBitStream
+ * [out] *pOffset
+ *
+ **/
+
+OMXVoid armByteAlign(const OMX_U8 **ppBitStream,OMX_INT *pOffset);
+
+/**
+ * Function: armSkipBits()
+ *
+ * Description:
+ * Skip N bits from the value at *ppBitStream
+ *
+ * Parameters:
+ * [in] *ppBitStream
+ * [in] *pOffset
+ * [in] N
+ *
+ * [out] *ppBitStream
+ * [out] *pOffset
+ *
+ **/
+
+OMXVoid armSkipBits(const OMX_U8 **ppBitStream,OMX_INT *pOffset,OMX_INT N);
+
+/***************************************
+ * Variable bit length Decode
+ ***************************************/
+
+/**
+ * Function: armUnPackVLC32()
+ *
+ * Description:
+ * Variable length decode of variable length symbol (max size 32 bits) read from
+ * the bit stream pointed by *ppBitStream at *pOffset by using the table
+ * pointed by pCodeBook
+ *
+ * Parameters:
+ * [in] **ppBitStream
+ * [in] *pOffset
+ * [in] pCodeBook
+ *
+ * [out] **ppBitStream
+ * [out] *pOffset
+ *
+ * Returns : Code Book Index if successfull.
+ * : "ARM_NO_CODEBOOK_INDEX = 0xFFFF" if search fails.
+ **/
+
+#define ARM_NO_CODEBOOK_INDEX (OMX_U16)(0xFFFF)
+
+OMX_U16 armUnPackVLC32(
+ const OMX_U8 **ppBitStream,
+ OMX_INT *pOffset,
+ const ARM_VLC32 *pCodeBook
+);
+
+/***************************************
+ * Fixed bit length Encode
+ ***************************************/
+
+/**
+ * Function: armPackBits
+ *
+ * Description:
+ * Pack a VLC code word into the bitstream
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream pointer to the pointer to the current byte
+ * in the bit stream.
+ * [in] pOffset pointer to the bit position in the byte
+ * pointed by *ppBitStream. Valid within 0
+ * to 7.
+ * [in] codeWord Code word that need to be inserted in to the
+ * bitstream
+ * [in] codeLength Length of the code word valid range 1...32
+ *
+ * [out] ppBitStream *ppBitStream is updated after the block is encoded,
+ * so that it points to the current byte in the bit
+ * stream buffer.
+ * [out] pBitOffset *pBitOffset is updated so that it points to the
+ * current bit position in the byte pointed by
+ * *ppBitStream.
+ *
+ * Return Value:
+ * Standard OMX_RESULT result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armPackBits (
+ OMX_U8 **ppBitStream,
+ OMX_INT *pOffset,
+ OMX_U32 codeWord,
+ OMX_INT codeLength
+);
+
+/***************************************
+ * Variable bit length Encode
+ ***************************************/
+
+/**
+ * Function: armPackVLC32
+ *
+ * Description:
+ * Pack a VLC code word into the bitstream
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream pointer to the pointer to the current byte
+ * in the bit stream.
+ * [in] pBitOffset pointer to the bit position in the byte
+ * pointed by *ppBitStream. Valid within 0
+ * to 7.
+ * [in] code VLC code word that need to be inserted in to the
+ * bitstream
+ *
+ * [out] ppBitStream *ppBitStream is updated after the block is encoded,
+ * so that it points to the current byte in the bit
+ * stream buffer.
+ * [out] pBitOffset *pBitOffset is updated so that it points to the
+ * current bit position in the byte pointed by
+ * *ppBitStream.
+ *
+ * Return Value:
+ * Standard OMX_RESULT result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armPackVLC32 (
+ OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ ARM_VLC32 code
+);
+
+#endif /*_armCodec_H_*/
+
+/*End of File*/
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/armCOMM_Version.h b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/armCOMM_Version.h
new file mode 100644
index 0000000..e99a450
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/armCOMM_Version.h
@@ -0,0 +1,43 @@
+/* Guard the header against multiple inclusion. */
+#ifndef __ARM_COMM_VERSION_H__
+#define __ARM_COMM_VERSION_H__
+
+
+/* The following line should be in omxtypes.h but hasn't been approved by OpenMAX yet */
+#define OMX_VERSION 102
+
+/* We need to define these macros in order to convert a #define number into a #define string. */
+#define ARM_QUOTE(a) #a
+#define ARM_INDIRECT(A) ARM_QUOTE(A)
+
+/* Convert the OMX_VERSION number into a string that can be used, for example, to print it out. */
+#define ARM_VERSION_STRING ARM_INDIRECT(OMX_VERSION)
+
+
+/* Define this in order to turn on ARM version/release/build strings in each domain */
+#define ARM_INCLUDE_VERSION_DESCRIPTIONS
+
+#ifdef ARM_INCLUDE_VERSION_DESCRIPTIONS
+ extern const char * const omxAC_VersionDescription;
+ extern const char * const omxIC_VersionDescription;
+ extern const char * const omxIP_VersionDescription;
+ extern const char * const omxSP_VersionDescription;
+ extern const char * const omxVC_VersionDescription;
+#endif /* ARM_INCLUDE_VERSION_DESCRIPTIONS */
+
+
+/* The following entries should be automatically updated by the release script */
+/* They are used in the ARM version strings defined for each domain. */
+
+/* The release tag associated with this release of the library. - used for source and object releases */
+#define OMX_ARM_RELEASE_TAG "r0p0-00bet1"
+
+/* The ARM architecture used to build any objects or executables in this release. */
+#define OMX_ARM_BUILD_ARCHITECTURE "ANSI C"
+
+/* The ARM Toolchain used to build any objects or executables in this release. */
+#define OMX_ARM_BUILD_TOOLCHAIN "ARM RVCT 3.1"
+
+
+#endif /* __ARM_COMM_VERSION_H__ */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/armOMX.h b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/armOMX.h
new file mode 100644
index 0000000..f629f72
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/armOMX.h
@@ -0,0 +1,274 @@
+/*
+ *
+ * File Name: armOMX_ReleaseVersion.h
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * This file allows a version of the OMX DL libraries to be built where some or
+ * all of the function names can be given a user specified suffix.
+ *
+ * You might want to use it where:
+ *
+ * - you want to rename a function "out of the way" so that you could replace
+ * a function with a different version (the original version would still be
+ * in the library just with a different name - so you could debug the new
+ * version by comparing it to the output of the old)
+ *
+ * - you want to rename all the functions to versions with a suffix so that
+ * you can include two versions of the library and choose between functions
+ * at runtime.
+ *
+ * e.g. omxIPBM_Copy_U8_C1R could be renamed omxIPBM_Copy_U8_C1R_CortexA8
+ *
+ */
+
+
+#ifndef _armOMX_H_
+#define _armOMX_H_
+
+
+/* We need to define these two macros in order to expand and concatenate the names */
+#define OMXCAT2BAR(A, B) omx ## A ## B
+#define OMXCATBAR(A, B) OMXCAT2BAR(A, B)
+
+/* Define the suffix to add to all functions - the default is no suffix */
+#define BARE_SUFFIX
+
+
+
+/* Define what happens to the bare suffix-less functions, down to the sub-domain accuracy */
+#define OMXACAAC_SUFFIX BARE_SUFFIX
+#define OMXACMP3_SUFFIX BARE_SUFFIX
+#define OMXICJP_SUFFIX BARE_SUFFIX
+#define OMXIPBM_SUFFIX BARE_SUFFIX
+#define OMXIPCS_SUFFIX BARE_SUFFIX
+#define OMXIPPP_SUFFIX BARE_SUFFIX
+#define OMXSP_SUFFIX BARE_SUFFIX
+#define OMXVCCOMM_SUFFIX BARE_SUFFIX
+#define OMXVCM4P10_SUFFIX BARE_SUFFIX
+#define OMXVCM4P2_SUFFIX BARE_SUFFIX
+
+
+
+
+/* Define what the each bare, un-suffixed OpenMAX API function names is to be renamed */
+#define omxACAAC_DecodeChanPairElt OMXCATBAR(ACAAC_DecodeChanPairElt, OMXACAAC_SUFFIX)
+#define omxACAAC_DecodeDatStrElt OMXCATBAR(ACAAC_DecodeDatStrElt, OMXACAAC_SUFFIX)
+#define omxACAAC_DecodeFillElt OMXCATBAR(ACAAC_DecodeFillElt, OMXACAAC_SUFFIX)
+#define omxACAAC_DecodeIsStereo_S32 OMXCATBAR(ACAAC_DecodeIsStereo_S32, OMXACAAC_SUFFIX)
+#define omxACAAC_DecodeMsPNS_S32_I OMXCATBAR(ACAAC_DecodeMsPNS_S32_I, OMXACAAC_SUFFIX)
+#define omxACAAC_DecodeMsStereo_S32_I OMXCATBAR(ACAAC_DecodeMsStereo_S32_I, OMXACAAC_SUFFIX)
+#define omxACAAC_DecodePrgCfgElt OMXCATBAR(ACAAC_DecodePrgCfgElt, OMXACAAC_SUFFIX)
+#define omxACAAC_DecodeTNS_S32_I OMXCATBAR(ACAAC_DecodeTNS_S32_I, OMXACAAC_SUFFIX)
+#define omxACAAC_DeinterleaveSpectrum_S32 OMXCATBAR(ACAAC_DeinterleaveSpectrum_S32, OMXACAAC_SUFFIX)
+#define omxACAAC_EncodeTNS_S32_I OMXCATBAR(ACAAC_EncodeTNS_S32_I, OMXACAAC_SUFFIX)
+#define omxACAAC_LongTermPredict_S32 OMXCATBAR(ACAAC_LongTermPredict_S32, OMXACAAC_SUFFIX)
+#define omxACAAC_LongTermReconstruct_S32_I OMXCATBAR(ACAAC_LongTermReconstruct_S32_I, OMXACAAC_SUFFIX)
+#define omxACAAC_MDCTFwd_S32 OMXCATBAR(ACAAC_MDCTFwd_S32, OMXACAAC_SUFFIX)
+#define omxACAAC_MDCTInv_S32_S16 OMXCATBAR(ACAAC_MDCTInv_S32_S16, OMXACAAC_SUFFIX)
+#define omxACAAC_NoiselessDecode OMXCATBAR(ACAAC_NoiselessDecode, OMXACAAC_SUFFIX)
+#define omxACAAC_QuantInv_S32_I OMXCATBAR(ACAAC_QuantInv_S32_I, OMXACAAC_SUFFIX)
+#define omxACAAC_UnpackADIFHeader OMXCATBAR(ACAAC_UnpackADIFHeader, OMXACAAC_SUFFIX)
+#define omxACAAC_UnpackADTSFrameHeader OMXCATBAR(ACAAC_UnpackADTSFrameHeader, OMXACAAC_SUFFIX)
+
+
+#define omxACMP3_HuffmanDecode_S32 OMXCATBAR(ACMP3_HuffmanDecode_S32, OMXACMP3_SUFFIX)
+#define omxACMP3_HuffmanDecodeSfb_S32 OMXCATBAR(ACMP3_HuffmanDecodeSfb_S32, OMXACMP3_SUFFIX)
+#define omxACMP3_HuffmanDecodeSfbMbp_S32 OMXCATBAR(ACMP3_HuffmanDecodeSfbMbp_S32, OMXACMP3_SUFFIX)
+#define omxACMP3_MDCTInv_S32 OMXCATBAR(ACMP3_MDCTInv_S32, OMXACMP3_SUFFIX)
+#define omxACMP3_ReQuantize_S32_I OMXCATBAR(ACMP3_ReQuantize_S32_I, OMXACMP3_SUFFIX)
+#define omxACMP3_ReQuantizeSfb_S32_I OMXCATBAR(ACMP3_ReQuantizeSfb_S32_I, OMXACMP3_SUFFIX)
+#define omxACMP3_SynthPQMF_S32_S16 OMXCATBAR(ACMP3_SynthPQMF_S32_S16, OMXACMP3_SUFFIX)
+#define omxACMP3_UnpackFrameHeader OMXCATBAR(ACMP3_UnpackFrameHeader, OMXACMP3_SUFFIX)
+#define omxACMP3_UnpackScaleFactors_S8 OMXCATBAR(ACMP3_UnpackScaleFactors_S8, OMXACMP3_SUFFIX)
+#define omxACMP3_UnpackSideInfo OMXCATBAR(ACMP3_UnpackSideInfo, OMXACMP3_SUFFIX)
+
+#define omxICJP_CopyExpand_U8_C3 OMXCATBAR(ICJP_CopyExpand_U8_C3, OMXICJP_SUFFIX)
+#define omxICJP_DCTFwd_S16 OMXCATBAR(ICJP_DCTFwd_S16, OMXICJP_SUFFIX)
+#define omxICJP_DCTFwd_S16_I OMXCATBAR(ICJP_DCTFwd_S16_I, OMXICJP_SUFFIX)
+#define omxICJP_DCTInv_S16 OMXCATBAR(ICJP_DCTInv_S16, OMXICJP_SUFFIX)
+#define omxICJP_DCTInv_S16_I OMXCATBAR(ICJP_DCTInv_S16_I, OMXICJP_SUFFIX)
+#define omxICJP_DCTQuantFwd_Multiple_S16 OMXCATBAR(ICJP_DCTQuantFwd_Multiple_S16, OMXICJP_SUFFIX)
+#define omxICJP_DCTQuantFwd_S16 OMXCATBAR(ICJP_DCTQuantFwd_S16, OMXICJP_SUFFIX)
+#define omxICJP_DCTQuantFwd_S16_I OMXCATBAR(ICJP_DCTQuantFwd_S16_I, OMXICJP_SUFFIX)
+#define omxICJP_DCTQuantFwdTableInit OMXCATBAR(ICJP_DCTQuantFwdTableInit, OMXICJP_SUFFIX)
+#define omxICJP_DCTQuantInv_Multiple_S16 OMXCATBAR(ICJP_DCTQuantInv_Multiple_S16, OMXICJP_SUFFIX)
+#define omxICJP_DCTQuantInv_S16 OMXCATBAR(ICJP_DCTQuantInv_S16, OMXICJP_SUFFIX)
+#define omxICJP_DCTQuantInv_S16_I OMXCATBAR(ICJP_DCTQuantInv_S16_I, OMXICJP_SUFFIX)
+#define omxICJP_DCTQuantInvTableInit OMXCATBAR(ICJP_DCTQuantInvTableInit, OMXICJP_SUFFIX)
+#define omxICJP_DecodeHuffman8x8_Direct_S16_C1 OMXCATBAR(ICJP_DecodeHuffman8x8_Direct_S16_C1, OMXICJP_SUFFIX)
+#define omxICJP_DecodeHuffmanSpecGetBufSize_U8 OMXCATBAR(ICJP_DecodeHuffmanSpecGetBufSize_U8, OMXICJP_SUFFIX)
+#define omxICJP_DecodeHuffmanSpecInit_U8 OMXCATBAR(ICJP_DecodeHuffmanSpecInit_U8, OMXICJP_SUFFIX)
+#define omxICJP_EncodeHuffman8x8_Direct_S16_U1_C1 OMXCATBAR(ICJP_EncodeHuffman8x8_Direct_S16_U1_C1, OMXICJP_SUFFIX)
+#define omxICJP_EncodeHuffmanSpecGetBufSize_U8 OMXCATBAR(ICJP_EncodeHuffmanSpecGetBufSize_U8, OMXICJP_SUFFIX)
+#define omxICJP_EncodeHuffmanSpecInit_U8 OMXCATBAR(ICJP_EncodeHuffmanSpecInit_U8, OMXICJP_SUFFIX)
+
+#define omxIPBM_AddC_U8_C1R_Sfs OMXCATBAR(IPBM_AddC_U8_C1R_Sfs, OMXIPBM_SUFFIX)
+#define omxIPBM_Copy_U8_C1R OMXCATBAR(IPBM_Copy_U8_C1R, OMXIPBM_SUFFIX)
+#define omxIPBM_Copy_U8_C3R OMXCATBAR(IPBM_Copy_U8_C3R, OMXIPBM_SUFFIX)
+#define omxIPBM_Mirror_U8_C1R OMXCATBAR(IPBM_Mirror_U8_C1R, OMXIPBM_SUFFIX)
+#define omxIPBM_MulC_U8_C1R_Sfs OMXCATBAR(IPBM_MulC_U8_C1R_Sfs, OMXIPBM_SUFFIX)
+
+#define omxIPCS_ColorTwistQ14_U8_C3R OMXCATBAR(IPCS_ColorTwistQ14_U8_C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_BGR565ToYCbCr420LS_MCU_U16_S16_C3P3R OMXCATBAR(IPCS_BGR565ToYCbCr420LS_MCU_U16_S16_C3P3R, OMXIPCS_SUFFIX)
+#define omxIPCS_BGR565ToYCbCr422LS_MCU_U16_S16_C3P3R OMXCATBAR(IPCS_BGR565ToYCbCr422LS_MCU_U16_S16_C3P3R, OMXIPCS_SUFFIX)
+#define omxIPCS_BGR565ToYCbCr444LS_MCU_U16_S16_C3P3R OMXCATBAR(IPCS_BGR565ToYCbCr444LS_MCU_U16_S16_C3P3R, OMXIPCS_SUFFIX)
+#define omxIPCS_BGR888ToYCbCr420LS_MCU_U8_S16_C3P3R OMXCATBAR(IPCS_BGR888ToYCbCr420LS_MCU_U8_S16_C3P3R, OMXIPCS_SUFFIX)
+#define omxIPCS_BGR888ToYCbCr422LS_MCU_U8_S16_C3P3R OMXCATBAR(IPCS_BGR888ToYCbCr422LS_MCU_U8_S16_C3P3R, OMXIPCS_SUFFIX)
+#define omxIPCS_BGR888ToYCbCr444LS_MCU_U8_S16_C3P3R OMXCATBAR(IPCS_BGR888ToYCbCr444LS_MCU_U8_S16_C3P3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr420RszCscRotBGR_U8_P3C3R OMXCATBAR(IPCS_YCbCr420RszCscRotBGR_U8_P3C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr420RszRot_U8_P3R OMXCATBAR(IPCS_YCbCr420RszRot_U8_P3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr420ToBGR565_U8_U16_P3C3R OMXCATBAR(IPCS_YCbCr420ToBGR565_U8_U16_P3C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr420ToBGR565LS_MCU_S16_U16_P3C3R OMXCATBAR(IPCS_YCbCr420ToBGR565LS_MCU_S16_U16_P3C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr420ToBGR888LS_MCU_S16_U8_P3C3R OMXCATBAR(IPCS_YCbCr420ToBGR888LS_MCU_S16_U8_P3C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr422RszCscRotBGR_U8_P3C3R OMXCATBAR(IPCS_YCbCr422RszCscRotBGR_U8_P3C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_CbYCrY422RszCscRotBGR_U8_U16_C2R OMXCATBAR(IPCS_CbYCrY422RszCscRotBGR_U8_U16_C2R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr422RszRot_U8_P3R OMXCATBAR(IPCS_YCbCr422RszRot_U8_P3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbYCr422ToBGR565_U8_U16_C2C3R OMXCATBAR(IPCS_YCbYCr422ToBGR565_U8_U16_C2C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr422ToBGR565LS_MCU_S16_U16_P3C3R OMXCATBAR(IPCS_YCbCr422ToBGR565LS_MCU_S16_U16_P3C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbYCr422ToBGR888_U8_C2C3R OMXCATBAR(IPCS_YCbYCr422ToBGR888_U8_C2C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr422ToBGR888LS_MCU_S16_U8_P3C3R OMXCATBAR(IPCS_YCbCr422ToBGR888LS_MCU_S16_U8_P3C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr422ToBGR888LS_MCU_S16_U8_P3C3R OMXCATBAR(IPCS_YCbCr422ToBGR888LS_MCU_S16_U8_P3C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_CbYCrY422ToYCbCr420Rotate_U8_C2P3R OMXCATBAR(IPCS_CbYCrY422ToYCbCr420Rotate_U8_C2P3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr422ToYCbCr420Rotate_U8_P3R OMXCATBAR(IPCS_YCbCr422ToYCbCr420Rotate_U8_P3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr444ToBGR565_U8_U16_C3R OMXCATBAR(IPCS_YCbCr444ToBGR565_U8_U16_C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr444ToBGR565_U8_U16_P3C3R OMXCATBAR(IPCS_YCbCr444ToBGR565_U8_U16_P3C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr444ToBGR565LS_MCU_S16_U16_P3C3R OMXCATBAR(IPCS_YCbCr444ToBGR565LS_MCU_S16_U16_P3C3R, OMXIPCS_SUFFIX)
+#define omxIPCS_YCbCr444ToBGR888_U8_C3R OMXCATBAR(IPCS_YCbCr444ToBGR888_U8_C3R, OMXIPCS_SUFFIX)
+
+#define omxIPPP_Deblock_HorEdge_U8_I OMXCATBAR(IPPP_Deblock_HorEdge_U8_I, OMXIPPP_SUFFIX)
+#define omxIPPP_Deblock_VerEdge_U8_I OMXCATBAR(IPPP_Deblock_VerEdge_U8_I, OMXIPPP_SUFFIX)
+#define omxIPPP_FilterFIR_U8_C1R OMXCATBAR(IPPP_FilterFIR_U8_C1R, OMXIPPP_SUFFIX)
+#define omxIPPP_FilterMedian_U8_C1R OMXCATBAR(IPPP_FilterMedian_U8_C1R, OMXIPPP_SUFFIX)
+#define omxIPPP_GetCentralMoment_S64 OMXCATBAR(IPPP_GetCentralMoment_S64, OMXIPPP_SUFFIX)
+#define omxIPPP_GetSpatialMoment_S64 OMXCATBAR(IPPP_GetSpatialMoment_S64, OMXIPPP_SUFFIX)
+#define omxIPPP_MomentGetStateSize OMXCATBAR(IPPP_MomentGetStateSize, OMXIPPP_SUFFIX)
+#define omxIPPP_MomentInit OMXCATBAR(IPPP_MomentInit, OMXIPPP_SUFFIX)
+#define omxIPPP_Moments_U8_C1R OMXCATBAR(IPPP_Moments_U8_C1R, OMXIPPP_SUFFIX)
+#define omxIPPP_Moments_U8_C3R OMXCATBAR(IPPP_Moments_U8_C3R, OMXIPPP_SUFFIX)
+
+#define omxSP_BlockExp_S16 OMXCATBAR(SP_BlockExp_S16, OMXSP_SUFFIX)
+#define omxSP_BlockExp_S32 OMXCATBAR(SP_BlockExp_S32, OMXSP_SUFFIX)
+#define omxSP_Copy_S16 OMXCATBAR(SP_Copy_S16, OMXSP_SUFFIX)
+#define omxSP_DotProd_S16 OMXCATBAR(SP_DotProd_S16, OMXSP_SUFFIX)
+#define omxSP_DotProd_S16_Sfs OMXCATBAR(SP_DotProd_S16_Sfs, OMXSP_SUFFIX)
+#define omxSP_FFTFwd_CToC_SC16_Sfs OMXCATBAR(SP_FFTFwd_CToC_SC16_Sfs, OMXSP_SUFFIX)
+#define omxSP_FFTFwd_CToC_SC32_Sfs OMXCATBAR(SP_FFTFwd_CToC_SC32_Sfs, OMXSP_SUFFIX)
+#define omxSP_FFTFwd_RToCCS_S16S32_Sfs OMXCATBAR(SP_FFTFwd_RToCCS_S16S32_Sfs, OMXSP_SUFFIX)
+#define omxSP_FFTFwd_RToCCS_S32_Sfs OMXCATBAR(SP_FFTFwd_RToCCS_S32_Sfs, OMXSP_SUFFIX)
+#define omxSP_FFTGetBufSize_C_SC16 OMXCATBAR(SP_FFTGetBufSize_C_SC16, OMXSP_SUFFIX)
+#define omxSP_FFTGetBufSize_C_SC32 OMXCATBAR(SP_FFTGetBufSize_C_SC32, OMXSP_SUFFIX)
+#define omxSP_FFTGetBufSize_R_S16S32 OMXCATBAR(SP_FFTGetBufSize_R_S16S32, OMXSP_SUFFIX)
+#define omxSP_FFTGetBufSize_R_S32 OMXCATBAR(SP_FFTGetBufSize_R_S32, OMXSP_SUFFIX)
+#define omxSP_FFTInit_C_SC16 OMXCATBAR(SP_FFTInit_C_SC16, OMXSP_SUFFIX)
+#define omxSP_FFTInit_C_SC32 OMXCATBAR(SP_FFTInit_C_SC32, OMXSP_SUFFIX)
+#define omxSP_FFTInit_R_S16S32 OMXCATBAR(SP_FFTInit_R_S16S32, OMXSP_SUFFIX)
+#define omxSP_FFTInit_R_S32 OMXCATBAR(SP_FFTInit_R_S32, OMXSP_SUFFIX)
+#define omxSP_FFTInv_CCSToR_S32_Sfs OMXCATBAR(SP_FFTInv_CCSToR_S32_Sfs, OMXSP_SUFFIX)
+#define omxSP_FFTInv_CCSToR_S32S16_Sfs OMXCATBAR(SP_FFTInv_CCSToR_S32S16_Sfs, OMXSP_SUFFIX)
+#define omxSP_FFTInv_CToC_SC16_Sfs OMXCATBAR(SP_FFTInv_CToC_SC16_Sfs, OMXSP_SUFFIX)
+#define omxSP_FFTInv_CToC_SC32_Sfs OMXCATBAR(SP_FFTInv_CToC_SC32_Sfs, OMXSP_SUFFIX)
+#define omxSP_FilterMedian_S32 OMXCATBAR(SP_FilterMedian_S32, OMXSP_SUFFIX)
+#define omxSP_FilterMedian_S32_I OMXCATBAR(SP_FilterMedian_S32_I, OMXSP_SUFFIX)
+#define omxSP_FIR_Direct_S16 OMXCATBAR(SP_FIR_Direct_S16, OMXSP_SUFFIX)
+#define omxSP_FIR_Direct_S16_I OMXCATBAR(SP_FIR_Direct_S16_I, OMXSP_SUFFIX)
+#define omxSP_FIR_Direct_S16_ISfs OMXCATBAR(SP_FIR_Direct_S16_ISfs, OMXSP_SUFFIX)
+#define omxSP_FIR_Direct_S16_Sfs OMXCATBAR(SP_FIR_Direct_S16_Sfs, OMXSP_SUFFIX)
+#define omxSP_FIROne_Direct_S16 OMXCATBAR(SP_FIROne_Direct_S16, OMXSP_SUFFIX)
+#define omxSP_FIROne_Direct_S16_I OMXCATBAR(SP_FIROne_Direct_S16_I, OMXSP_SUFFIX)
+#define omxSP_FIROne_Direct_S16_ISfs OMXCATBAR(SP_FIROne_Direct_S16_ISfs, OMXSP_SUFFIX)
+#define omxSP_FIROne_Direct_S16_Sfs OMXCATBAR(SP_FIROne_Direct_S16_Sfs, OMXSP_SUFFIX)
+#define omxSP_IIR_BiQuadDirect_S16 OMXCATBAR(SP_IIR_BiQuadDirect_S16, OMXSP_SUFFIX)
+#define omxSP_IIR_BiQuadDirect_S16_I OMXCATBAR(SP_IIR_BiQuadDirect_S16_I, OMXSP_SUFFIX)
+#define omxSP_IIR_Direct_S16 OMXCATBAR(SP_IIR_Direct_S16, OMXSP_SUFFIX)
+#define omxSP_IIR_Direct_S16_I OMXCATBAR(SP_IIR_Direct_S16_I, OMXSP_SUFFIX)
+#define omxSP_IIROne_BiQuadDirect_S16 OMXCATBAR(SP_IIROne_BiQuadDirect_S16, OMXSP_SUFFIX)
+#define omxSP_IIROne_BiQuadDirect_S16_I OMXCATBAR(SP_IIROne_BiQuadDirect_S16_I, OMXSP_SUFFIX)
+#define omxSP_IIROne_Direct_S16 OMXCATBAR(SP_IIROne_Direct_S16, OMXSP_SUFFIX)
+#define omxSP_IIROne_Direct_S16_I OMXCATBAR(SP_IIROne_Direct_S16_I, OMXSP_SUFFIX)
+
+#define omxVCCOMM_Average_16x OMXCATBAR(VCCOMM_Average_16x, OMXVCCOMM_SUFFIX)
+#define omxVCCOMM_Average_8x OMXCATBAR(VCCOMM_Average_8x, OMXVCCOMM_SUFFIX)
+#define omxVCCOMM_ComputeTextureErrorBlock OMXCATBAR(VCCOMM_ComputeTextureErrorBlock, OMXVCCOMM_SUFFIX)
+#define omxVCCOMM_ComputeTextureErrorBlock_SAD OMXCATBAR(VCCOMM_ComputeTextureErrorBlock_SAD, OMXVCCOMM_SUFFIX)
+#define omxVCCOMM_Copy16x16 OMXCATBAR(VCCOMM_Copy16x16, OMXVCCOMM_SUFFIX)
+#define omxVCCOMM_Copy8x8 OMXCATBAR(VCCOMM_Copy8x8, OMXVCCOMM_SUFFIX)
+#define omxVCCOMM_ExpandFrame_I OMXCATBAR(VCCOMM_ExpandFrame_I, OMXVCCOMM_SUFFIX)
+#define omxVCCOMM_LimitMVToRect OMXCATBAR(VCCOMM_LimitMVToRect, OMXVCCOMM_SUFFIX)
+#define omxVCCOMM_SAD_16x OMXCATBAR(VCCOMM_SAD_16x, OMXVCCOMM_SUFFIX)
+#define omxVCCOMM_SAD_8x OMXCATBAR(VCCOMM_SAD_8x, OMXVCCOMM_SUFFIX)
+
+#define omxVCM4P10_Average_4x OMXCATBAR(VCM4P10_Average_4x, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_BlockMatch_Half OMXCATBAR(VCM4P10_BlockMatch_Half, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_BlockMatch_Integer OMXCATBAR(VCM4P10_BlockMatch_Integer, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_BlockMatch_Quarter OMXCATBAR(VCM4P10_BlockMatch_Quarter, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_DeblockChroma_I OMXCATBAR(VCM4P10_DeblockChroma_I, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_DeblockLuma_I OMXCATBAR(VCM4P10_DeblockLuma_I, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC OMXCATBAR(VCM4P10_DecodeChromaDcCoeffsToPairCAVLC, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_DecodeCoeffsToPairCAVLC OMXCATBAR(VCM4P10_DecodeCoeffsToPairCAVLC, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_DequantTransformResidualFromPairAndAdd OMXCATBAR(VCM4P10_DequantTransformResidualFromPairAndAdd, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_FilterDeblockingChroma_HorEdge_I OMXCATBAR(VCM4P10_FilterDeblockingChroma_HorEdge_I, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_FilterDeblockingChroma_VerEdge_I OMXCATBAR(VCM4P10_FilterDeblockingChroma_VerEdge_I, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_FilterDeblockingLuma_HorEdge_I OMXCATBAR(VCM4P10_FilterDeblockingLuma_HorEdge_I, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_FilterDeblockingLuma_VerEdge_I OMXCATBAR(VCM4P10_FilterDeblockingLuma_VerEdge_I, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_GetVLCInfo OMXCATBAR(VCM4P10_GetVLCInfo, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_InterpolateChroma OMXCATBAR(VCM4P10_InterpolateChroma, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_InterpolateHalfHor_Luma OMXCATBAR(VCM4P10_InterpolateHalfHor_Luma, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_InterpolateHalfVer_Luma OMXCATBAR(VCM4P10_InterpolateHalfVer_Luma, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_InterpolateLuma OMXCATBAR(VCM4P10_InterpolateLuma, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_InvTransformDequant_ChromaDC OMXCATBAR(VCM4P10_InvTransformDequant_ChromaDC, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_InvTransformDequant_LumaDC OMXCATBAR(VCM4P10_InvTransformDequant_LumaDC, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_InvTransformResidualAndAdd OMXCATBAR(VCM4P10_InvTransformResidualAndAdd, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_MEGetBufSize OMXCATBAR(VCM4P10_MEGetBufSize, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_MEInit OMXCATBAR(VCM4P10_MEInit, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_MotionEstimationMB OMXCATBAR(VCM4P10_MotionEstimationMB, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_PredictIntra_16x16 OMXCATBAR(VCM4P10_PredictIntra_16x16, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_PredictIntra_4x4 OMXCATBAR(VCM4P10_PredictIntra_4x4, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_PredictIntraChroma_8x8 OMXCATBAR(VCM4P10_PredictIntraChroma_8x8, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_SAD_4x OMXCATBAR(VCM4P10_SAD_4x, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_SADQuar_16x OMXCATBAR(VCM4P10_SADQuar_16x, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_SADQuar_4x OMXCATBAR(VCM4P10_SADQuar_4x, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_SADQuar_8x OMXCATBAR(VCM4P10_SADQuar_8x, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_SATD_4x4 OMXCATBAR(VCM4P10_SATD_4x4, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_SubAndTransformQDQResidual OMXCATBAR(VCM4P10_SubAndTransformQDQResidual, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_TransformDequantChromaDCFromPair OMXCATBAR(VCM4P10_TransformDequantChromaDCFromPair, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_TransformDequantLumaDCFromPair OMXCATBAR(VCM4P10_TransformDequantLumaDCFromPair, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_TransformQuant_ChromaDC OMXCATBAR(VCM4P10_TransformQuant_ChromaDC, OMXVCM4P10_SUFFIX)
+#define omxVCM4P10_TransformQuant_LumaDC OMXCATBAR(VCM4P10_TransformQuant_LumaDC, OMXVCM4P10_SUFFIX)
+
+#define omxVCM4P2_BlockMatch_Half_16x16 OMXCATBAR(VCM4P2_BlockMatch_Half_16x16, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_BlockMatch_Half_8x8 OMXCATBAR(VCM4P2_BlockMatch_Half_8x8, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_BlockMatch_Integer_16x16 OMXCATBAR(VCM4P2_BlockMatch_Integer_16x16, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_BlockMatch_Integer_8x8 OMXCATBAR(VCM4P2_BlockMatch_Integer_8x8, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_DCT8x8blk OMXCATBAR(VCM4P2_DCT8x8blk, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_DecodeBlockCoef_Inter OMXCATBAR(VCM4P2_DecodeBlockCoef_Inter, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_DecodeBlockCoef_Intra OMXCATBAR(VCM4P2_DecodeBlockCoef_Intra, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_DecodePadMV_PVOP OMXCATBAR(VCM4P2_DecodePadMV_PVOP, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_DecodeVLCZigzag_Inter OMXCATBAR(VCM4P2_DecodeVLCZigzag_Inter, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_DecodeVLCZigzag_IntraACVLC OMXCATBAR(VCM4P2_DecodeVLCZigzag_IntraACVLC, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_DecodeVLCZigzag_IntraDCVLC OMXCATBAR(VCM4P2_DecodeVLCZigzag_IntraDCVLC, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_EncodeMV OMXCATBAR(VCM4P2_EncodeMV, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_EncodeVLCZigzag_Inter OMXCATBAR(VCM4P2_EncodeVLCZigzag_Inter, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_EncodeVLCZigzag_IntraACVLC OMXCATBAR(VCM4P2_EncodeVLCZigzag_IntraACVLC, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_EncodeVLCZigzag_IntraDCVLC OMXCATBAR(VCM4P2_EncodeVLCZigzag_IntraDCVLC, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_FindMVpred OMXCATBAR(VCM4P2_FindMVpred, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_IDCT8x8blk OMXCATBAR(VCM4P2_IDCT8x8blk, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_MCReconBlock OMXCATBAR(VCM4P2_MCReconBlock, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_MEGetBufSize OMXCATBAR(VCM4P2_MEGetBufSize, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_MEInit OMXCATBAR(VCM4P2_MEInit, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_MotionEstimationMB OMXCATBAR(VCM4P2_MotionEstimationMB, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_PredictReconCoefIntra OMXCATBAR(VCM4P2_PredictReconCoefIntra, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_QuantInter_I OMXCATBAR(VCM4P2_QuantInter_I, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_QuantIntra_I OMXCATBAR(VCM4P2_QuantIntra_I, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_QuantInvInter_I OMXCATBAR(VCM4P2_QuantInvInter_I, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_QuantInvIntra_I OMXCATBAR(VCM4P2_QuantInvIntra_I, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_TransRecBlockCoef_inter OMXCATBAR(VCM4P2_TransRecBlockCoef_inter, OMXVCM4P2_SUFFIX)
+#define omxVCM4P2_TransRecBlockCoef_intra OMXCATBAR(VCM4P2_TransRecBlockCoef_intra, OMXVCM4P2_SUFFIX)
+
+
+#endif /* _armOMX_h_ */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/omxtypes.h b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/omxtypes.h
new file mode 100644
index 0000000..8b295a6
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/omxtypes.h
@@ -0,0 +1,252 @@
+/**
+ * File: omxtypes.h
+ * Brief: Defines basic Data types used in OpenMAX v1.0.2 header files.
+ *
+ * Copyright © 2005-2008 The Khronos Group Inc. All Rights Reserved.
+ *
+ * These materials are protected by copyright laws and contain material
+ * proprietary to the Khronos Group, Inc. You may use these materials
+ * for implementing Khronos specifications, without altering or removing
+ * any trademark, copyright or other notice from the specification.
+ *
+ * Khronos Group makes no, and expressly disclaims any, representations
+ * or warranties, express or implied, regarding these materials, including,
+ * without limitation, any implied warranties of merchantability or fitness
+ * for a particular purpose or non-infringement of any intellectual property.
+ * Khronos Group makes no, and expressly disclaims any, warranties, express
+ * or implied, regarding the correctness, accuracy, completeness, timeliness,
+ * and reliability of these materials.
+ *
+ * Under no circumstances will the Khronos Group, or any of its Promoters,
+ * Contributors or Members or their respective partners, officers, directors,
+ * employees, agents or representatives be liable for any damages, whether
+ * direct, indirect, special or consequential damages for lost revenues,
+ * lost profits, or otherwise, arising from or in connection with these
+ * materials.
+ *
+ * Khronos and OpenMAX are trademarks of the Khronos Group Inc.
+ *
+ */
+
+#ifndef _OMXTYPES_H_
+#define _OMXTYPES_H_
+
+#include <limits.h>
+
+#define OMX_IN
+#define OMX_OUT
+#define OMX_INOUT
+
+
+typedef enum {
+
+ /* Mandatory return codes - use cases are explicitly described for each function */
+ OMX_Sts_NoErr = 0, /* No error, the function completed successfully */
+ OMX_Sts_Err = -2, /* Unknown/unspecified error */
+ OMX_Sts_InvalidBitstreamValErr = -182, /* Invalid value detected during bitstream processing */
+ OMX_Sts_MemAllocErr = -9, /* Not enough memory allocated for the operation */
+ OMX_StsACAAC_GainCtrErr = -159, /* AAC: Unsupported gain control data detected */
+ OMX_StsACAAC_PrgNumErr = -167, /* AAC: Invalid number of elements for one program */
+ OMX_StsACAAC_CoefValErr = -163, /* AAC: Invalid quantized coefficient value */
+ OMX_StsACAAC_MaxSfbErr = -162, /* AAC: Invalid maxSfb value in relation to numSwb */
+ OMX_StsACAAC_PlsDataErr = -160, /* AAC: pulse escape sequence data error */
+
+ /* Optional return codes - use cases are explicitly described for each function*/
+ OMX_Sts_BadArgErr = -5, /* Bad Arguments */
+
+ OMX_StsACAAC_TnsNumFiltErr = -157, /* AAC: Invalid number of TNS filters */
+ OMX_StsACAAC_TnsLenErr = -156, /* AAC: Invalid TNS region length */
+ OMX_StsACAAC_TnsOrderErr = -155, /* AAC: Invalid order of TNS filter */
+ OMX_StsACAAC_TnsCoefResErr = -154, /* AAC: Invalid bit-resolution for TNS filter coefficients */
+ OMX_StsACAAC_TnsCoefErr = -153, /* AAC: Invalid TNS filter coefficients */
+ OMX_StsACAAC_TnsDirectErr = -152, /* AAC: Invalid TNS filter direction */
+
+ OMX_StsICJP_JPEGMarkerErr = -183, /* JPEG marker encountered within an entropy-coded block; */
+ /* Huffman decoding operation terminated early. */
+ OMX_StsICJP_JPEGMarker = -181, /* JPEG marker encountered; Huffman decoding */
+ /* operation terminated early. */
+ OMX_StsIPPP_ContextMatchErr = -17, /* Context parameter doesn't match to the operation */
+
+ OMX_StsSP_EvenMedianMaskSizeErr = -180, /* Even size of the Median Filter mask was replaced by the odd one */
+
+ OMX_Sts_MaximumEnumeration = INT_MAX /*Placeholder, forces enum of size OMX_INT*/
+
+ } OMXResult; /** Return value or error value returned from a function. Identical to OMX_INT */
+
+
+/* OMX_U8 */
+#if UCHAR_MAX == 0xff
+typedef unsigned char OMX_U8;
+#elif USHRT_MAX == 0xff
+typedef unsigned short int OMX_U8;
+#else
+#error OMX_U8 undefined
+#endif
+
+
+/* OMX_S8 */
+#if SCHAR_MAX == 0x7f
+typedef signed char OMX_S8;
+#elif SHRT_MAX == 0x7f
+typedef signed short int OMX_S8;
+#else
+#error OMX_S8 undefined
+#endif
+
+
+/* OMX_U16 */
+#if USHRT_MAX == 0xffff
+typedef unsigned short int OMX_U16;
+#elif UINT_MAX == 0xffff
+typedef unsigned int OMX_U16;
+#else
+#error OMX_U16 undefined
+#endif
+
+
+/* OMX_S16 */
+#if SHRT_MAX == 0x7fff
+typedef signed short int OMX_S16;
+#elif INT_MAX == 0x7fff
+typedef signed int OMX_S16;
+#else
+#error OMX_S16 undefined
+#endif
+
+
+/* OMX_U32 */
+#if UINT_MAX == 0xffffffff
+typedef unsigned int OMX_U32;
+#elif LONG_MAX == 0xffffffff
+typedef unsigned long int OMX_U32;
+#else
+#error OMX_U32 undefined
+#endif
+
+
+/* OMX_S32 */
+#if INT_MAX == 0x7fffffff
+typedef signed int OMX_S32;
+#elif LONG_MAX == 0x7fffffff
+typedef long signed int OMX_S32;
+#else
+#error OMX_S32 undefined
+#endif
+
+
+/* OMX_U64 & OMX_S64 */
+#if defined( _WIN32 ) || defined ( _WIN64 )
+ typedef __int64 OMX_S64; /** Signed 64-bit integer */
+ typedef unsigned __int64 OMX_U64; /** Unsigned 64-bit integer */
+ #define OMX_MIN_S64 (0x8000000000000000i64)
+ #define OMX_MIN_U64 (0x0000000000000000i64)
+ #define OMX_MAX_S64 (0x7FFFFFFFFFFFFFFFi64)
+ #define OMX_MAX_U64 (0xFFFFFFFFFFFFFFFFi64)
+#else
+ typedef long long OMX_S64; /** Signed 64-bit integer */
+ typedef unsigned long long OMX_U64; /** Unsigned 64-bit integer */
+ #define OMX_MIN_S64 (0x8000000000000000LL)
+ #define OMX_MIN_U64 (0x0000000000000000LL)
+ #define OMX_MAX_S64 (0x7FFFFFFFFFFFFFFFLL)
+ #define OMX_MAX_U64 (0xFFFFFFFFFFFFFFFFLL)
+#endif
+
+
+/* OMX_SC8 */
+typedef struct
+{
+ OMX_S8 Re; /** Real part */
+ OMX_S8 Im; /** Imaginary part */
+
+} OMX_SC8; /** Signed 8-bit complex number */
+
+
+/* OMX_SC16 */
+typedef struct
+{
+ OMX_S16 Re; /** Real part */
+ OMX_S16 Im; /** Imaginary part */
+
+} OMX_SC16; /** Signed 16-bit complex number */
+
+
+/* OMX_SC32 */
+typedef struct
+{
+ OMX_S32 Re; /** Real part */
+ OMX_S32 Im; /** Imaginary part */
+
+} OMX_SC32; /** Signed 32-bit complex number */
+
+
+/* OMX_SC64 */
+typedef struct
+{
+ OMX_S64 Re; /** Real part */
+ OMX_S64 Im; /** Imaginary part */
+
+} OMX_SC64; /** Signed 64-bit complex number */
+
+
+/* OMX_F32 */
+typedef float OMX_F32; /** Single precision floating point,IEEE 754 */
+
+
+/* OMX_F64 */
+typedef double OMX_F64; /** Double precision floating point,IEEE 754 */
+
+
+/* OMX_INT */
+typedef int OMX_INT; /** signed integer corresponding to machine word length, has maximum signed value INT_MAX*/
+
+
+#define OMX_MIN_S8 (-128)
+#define OMX_MIN_U8 0
+#define OMX_MIN_S16 (-32768)
+#define OMX_MIN_U16 0
+#define OMX_MIN_S32 (-2147483647-1)
+#define OMX_MIN_U32 0
+
+#define OMX_MAX_S8 (127)
+#define OMX_MAX_U8 (255)
+#define OMX_MAX_S16 (32767)
+#define OMX_MAX_U16 (0xFFFF)
+#define OMX_MAX_S32 (2147483647)
+#define OMX_MAX_U32 (0xFFFFFFFF)
+
+typedef void OMXVoid;
+
+#ifndef NULL
+#define NULL ((void*)0)
+#endif
+
+/** Defines the geometric position and size of a rectangle,
+ * where x,y defines the coordinates of the top left corner
+ * of the rectangle, with dimensions width in the x-direction
+ * and height in the y-direction */
+typedef struct {
+ OMX_INT x; /** x-coordinate of top left corner of rectangle */
+ OMX_INT y; /** y-coordinate of top left corner of rectangle */
+ OMX_INT width; /** Width in the x-direction. */
+ OMX_INT height; /** Height in the y-direction. */
+}OMXRect;
+
+
+/** Defines the geometric position of a point, */
+typedef struct
+{
+ OMX_INT x; /** x-coordinate */
+ OMX_INT y; /** y-coordinate */
+
+} OMXPoint;
+
+
+/** Defines the dimensions of a rectangle, or region of interest in an image */
+typedef struct
+{
+ OMX_INT width; /** Width of the rectangle, in the x-direction */
+ OMX_INT height; /** Height of the rectangle, in the y-direction */
+
+} OMXSize;
+
+#endif /* _OMXTYPES_H_ */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/build_vc.pl b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/build_vc.pl
new file mode 100755
index 0000000..f0b43e0
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/build_vc.pl
@@ -0,0 +1,111 @@
+#!/usr/bin/perl
+#
+#
+# File Name: build_vc.pl
+# OpenMAX DL: v1.0.2
+# Revision: 9641
+# Date: Thursday, February 7, 2008
+#
+# (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+#
+#
+#
+# This file builds the OpenMAX DL vc domain library omxVC.o.
+#
+
+use File::Spec;
+use strict;
+
+my ($CC, $CC_OPTS, $AS, $AS_OPTS, $LIB, $LIB_OPTS, $LIB_TYPE);
+
+$CC = 'armcc';
+$CC_OPTS = '--no_unaligned_access --cpu ARM7TDMI -c';
+$AS = 'armasm';
+$AS_OPTS = '--no_unaligned_access --cpu ARM7TDMI';
+# $LIB = 'armlink';
+# $LIB_OPTS = '--partial -o';
+# $LIB_TYPE = '.o';
+$LIB = 'armar';
+$LIB_OPTS = '--create -r';
+$LIB_TYPE = '.a';
+
+#------------------------
+
+my (@headerlist, @filelist, $hd, $file, $ofile, $command, $objlist, $libfile, $h);
+
+# Define the list of directories containing included header files.
+@headerlist = qw(api vc/api vc/m4p2/api vc/m4p10/api);
+
+# Define the list of source files to compile.
+open(FILES, '<filelist_vc.txt') or die("Can't open source file list\n");
+@filelist = <FILES>;
+close(FILES);
+
+# Fix the file separators in the header paths
+foreach $h (@headerlist)
+{
+ $h = File::Spec->canonpath($h);
+}
+
+# Create the include path to be passed to the compiler
+$hd = '-I' . join(' -I', @headerlist);
+
+# Create the build directories "/lib/" and "/obj/" (if they are not there already)
+mkdir "obj", 0777 if (! -d "obj");
+mkdir "lib", 0777 if (! -d "lib");
+
+$objlist = '';
+
+# Compile each file
+foreach $file (@filelist)
+{
+ my $f;
+ my $base;
+ my $ext;
+ my $objfile;
+
+ chomp($file);
+ $file = File::Spec->canonpath($file);
+
+ (undef, undef, $f) = File::Spec->splitpath($file);
+ if(($base, $ext) = $f =~ /(.+)\.(\w)$/)
+ {
+ $objfile = File::Spec->catfile('obj', $base.'.o');
+
+ if($ext eq 'c')
+ {
+ $objlist .= "$objfile ";
+ $command = $CC.' '.$CC_OPTS.' '.$hd.' -o '.$objfile.' '.$file;
+ print "$command\n";
+ system($command);
+ }
+ elsif($ext eq 's')
+ {
+ $objlist .= "$objfile ";
+ $command = $AS.' '.$AS_OPTS.' '.$hd.' -o '.$objfile.' '.$file;
+ print "$command\n";
+ system($command);
+ }
+ else
+ {
+ print "Ignoring file: $f\n";
+ }
+ }
+ else
+ {
+ die "No file extension found: $f\n";
+ }
+}
+
+# Do the final link stage to create the libraries.
+$libfile = File::Spec->catfile('lib', 'omxVC'.$LIB_TYPE);
+$command = $LIB.' '.$LIB_OPTS.' '.$libfile.' '.$objlist;
+print "$command\n";
+(system($command) == 0) and print "Build successful\n";
+
+
+
+
+
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/filelist_vc.txt b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/filelist_vc.txt
new file mode 100644
index 0000000..66f34ac
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/filelist_vc.txt
@@ -0,0 +1,123 @@
+./api/armCOMM.h
+./api/armCOMM_Bitstream.h
+./api/armCOMM_Version.h
+./api/armOMX_ReleaseVersion.h
+./api/omxtypes.h
+./src/armCOMM.c
+./src/armCOMM_Bitstream.c
+./vc/api/armVC.h
+./vc/api/omxVC.h
+./vc/comm/src/armVCCOMM_Average.c
+./vc/comm/src/armVCCOMM_SAD.c
+./vc/comm/src/omxVCCOMM_Average_16x.c
+./vc/comm/src/omxVCCOMM_Average_8x.c
+./vc/comm/src/omxVCCOMM_ComputeTextureErrorBlock.c
+./vc/comm/src/omxVCCOMM_ComputeTextureErrorBlock_SAD.c
+./vc/comm/src/omxVCCOMM_Copy16x16.c
+./vc/comm/src/omxVCCOMM_Copy8x8.c
+./vc/comm/src/omxVCCOMM_ExpandFrame_I.c
+./vc/comm/src/omxVCCOMM_LimitMVToRect.c
+./vc/comm/src/omxVCCOMM_SAD_16x.c
+./vc/comm/src/omxVCCOMM_SAD_8x.c
+./vc/m4p10/api/armVCM4P10_CAVLCTables.h
+./vc/m4p10/src/armVCM4P10_CAVLCTables.c
+./vc/m4p10/src/armVCM4P10_CompareMotionCostToMV.c
+./vc/m4p10/src/armVCM4P10_DeBlockPixel.c
+./vc/m4p10/src/armVCM4P10_DecodeCoeffsToPair.c
+./vc/m4p10/src/armVCM4P10_DequantTables.c
+./vc/m4p10/src/armVCM4P10_FwdTransformResidual4x4.c
+./vc/m4p10/src/armVCM4P10_Interpolate_Chroma.c
+./vc/m4p10/src/armVCM4P10_Interpolate_Luma.c
+./vc/m4p10/src/armVCM4P10_InterpolateHalfDiag_Luma.c
+./vc/m4p10/src/armVCM4P10_InterpolateHalfHor_Luma.c
+./vc/m4p10/src/armVCM4P10_InterpolateHalfVer_Luma.c
+./vc/m4p10/src/armVCM4P10_PredictIntraDC4x4.c
+./vc/m4p10/src/armVCM4P10_QuantTables.c
+./vc/m4p10/src/armVCM4P10_SADQuar.c
+./vc/m4p10/src/armVCM4P10_TransformResidual4x4.c
+./vc/m4p10/src/armVCM4P10_UnpackBlock2x2.c
+./vc/m4p10/src/armVCM4P10_UnpackBlock4x4.c
+./vc/m4p10/src/omxVCM4P10_Average_4x.c
+./vc/m4p10/src/omxVCM4P10_BlockMatch_Half.c
+./vc/m4p10/src/omxVCM4P10_BlockMatch_Integer.c
+./vc/m4p10/src/omxVCM4P10_BlockMatch_Quarter.c
+./vc/m4p10/src/omxVCM4P10_DeblockChroma_I.c
+./vc/m4p10/src/omxVCM4P10_DeblockLuma_I.c
+./vc/m4p10/src/omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c
+./vc/m4p10/src/omxVCM4P10_DecodeCoeffsToPairCAVLC.c
+./vc/m4p10/src/omxVCM4P10_DequantTransformResidualFromPairAndAdd.c
+./vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_HorEdge_I.c
+./vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_VerEdge_I.c
+./vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_HorEdge_I.c
+./vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_VerEdge_I.c
+./vc/m4p10/src/omxVCM4P10_GetVLCInfo.c
+./vc/m4p10/src/omxVCM4P10_InterpolateChroma.c
+./vc/m4p10/src/omxVCM4P10_InterpolateHalfHor_Luma.c
+./vc/m4p10/src/omxVCM4P10_InterpolateHalfVer_Luma.c
+./vc/m4p10/src/omxVCM4P10_InterpolateLuma.c
+./vc/m4p10/src/omxVCM4P10_InvTransformDequant_ChromaDC.c
+./vc/m4p10/src/omxVCM4P10_InvTransformDequant_LumaDC.c
+./vc/m4p10/src/omxVCM4P10_InvTransformResidualAndAdd.c
+./vc/m4p10/src/omxVCM4P10_MEGetBufSize.c
+./vc/m4p10/src/omxVCM4P10_MEInit.c
+./vc/m4p10/src/omxVCM4P10_MotionEstimationMB.c
+./vc/m4p10/src/omxVCM4P10_PredictIntra_16x16.c
+./vc/m4p10/src/omxVCM4P10_PredictIntra_4x4.c
+./vc/m4p10/src/omxVCM4P10_PredictIntraChroma_8x8.c
+./vc/m4p10/src/omxVCM4P10_SAD_4x.c
+./vc/m4p10/src/omxVCM4P10_SADQuar_16x.c
+./vc/m4p10/src/omxVCM4P10_SADQuar_4x.c
+./vc/m4p10/src/omxVCM4P10_SADQuar_8x.c
+./vc/m4p10/src/omxVCM4P10_SATD_4x4.c
+./vc/m4p10/src/omxVCM4P10_SubAndTransformQDQResidual.c
+./vc/m4p10/src/omxVCM4P10_TransformDequantChromaDCFromPair.c
+./vc/m4p10/src/omxVCM4P10_TransformDequantLumaDCFromPair.c
+./vc/m4p10/src/omxVCM4P10_TransformQuant_ChromaDC.c
+./vc/m4p10/src/omxVCM4P10_TransformQuant_LumaDC.c
+./vc/m4p2/api/armVCM4P2_DCT_Table.h
+./vc/m4p2/api/armVCM4P2_Huff_Tables_VLC.h
+./vc/m4p2/api/armVCM4P2_ZigZag_Tables.h
+./vc/m4p2/src/armVCM4P2_ACDCPredict.c
+./vc/m4p2/src/armVCM4P2_BlockMatch_Half.c
+./vc/m4p2/src/armVCM4P2_BlockMatch_Integer.c
+./vc/m4p2/src/armVCM4P2_CheckVLCEscapeMode.c
+./vc/m4p2/src/armVCM4P2_CompareMV.c
+./vc/m4p2/src/armVCM4P2_DCT_Table.c
+./vc/m4p2/src/armVCM4P2_DecodeVLCZigzag_intra.c
+./vc/m4p2/src/armVCM4P2_EncodeVLCZigzag_intra.c
+./vc/m4p2/src/armVCM4P2_FillVLCBuffer.c
+./vc/m4p2/src/armVCM4P2_FillVLDBuffer.c
+./vc/m4p2/src/armVCM4P2_GetVLCBits.c
+./vc/m4p2/src/armVCM4P2_Huff_Tables_VLC.c
+./vc/m4p2/src/armVCM4P2_PutVLCBits.c
+./vc/m4p2/src/armVCM4P2_SetPredDir.c
+./vc/m4p2/src/armVCM4P2_Zigzag_Tables.c
+./vc/m4p2/src/omxVCM4P2_BlockMatch_Half_16x16.c
+./vc/m4p2/src/omxVCM4P2_BlockMatch_Half_8x8.c
+./vc/m4p2/src/omxVCM4P2_BlockMatch_Integer_16x16.c
+./vc/m4p2/src/omxVCM4P2_BlockMatch_Integer_8x8.c
+./vc/m4p2/src/omxVCM4P2_DCT8x8blk.c
+./vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Inter.c
+./vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Intra.c
+./vc/m4p2/src/omxVCM4P2_DecodePadMV_PVOP.c
+./vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_Inter.c
+./vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraACVLC.c
+./vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraDCVLC.c
+./vc/m4p2/src/omxVCM4P2_EncodeMV.c
+./vc/m4p2/src/omxVCM4P2_EncodeVLCZigzag_Inter.c
+./vc/m4p2/src/omxVCM4P2_EncodeVLCZigzag_IntraACVLC.c
+./vc/m4p2/src/omxVCM4P2_EncodeVLCZigzag_IntraDCVLC.c
+./vc/m4p2/src/omxVCM4P2_FindMVpred.c
+./vc/m4p2/src/omxVCM4P2_IDCT8x8blk.c
+./vc/m4p2/src/omxVCM4P2_MCReconBlock.c
+./vc/m4p2/src/omxVCM4P2_MEGetBufSize.c
+./vc/m4p2/src/omxVCM4P2_MEInit.c
+./vc/m4p2/src/omxVCM4P2_MotionEstimationMB.c
+./vc/m4p2/src/omxVCM4P2_PredictReconCoefIntra.c
+./vc/m4p2/src/omxVCM4P2_QuantInter_I.c
+./vc/m4p2/src/omxVCM4P2_QuantIntra_I.c
+./vc/m4p2/src/omxVCM4P2_QuantInvInter_I.c
+./vc/m4p2/src/omxVCM4P2_QuantInvIntra_I.c
+./vc/m4p2/src/omxVCM4P2_TransRecBlockCoef_inter.c
+./vc/m4p2/src/omxVCM4P2_TransRecBlockCoef_intra.c
+./vc/src/armVC_Version.c
\ No newline at end of file
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/src/armCOMM.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/src/armCOMM.c
new file mode 100644
index 0000000..e572a89
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/src/armCOMM.c
@@ -0,0 +1,936 @@
+/**
+ *
+ * File Name: armCOMM.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Defines Common APIs used across OpenMAX API's
+ */
+
+#include "omxtypes.h"
+#include "armCOMM.h"
+
+/***********************************************************************/
+ /* Miscellaneous Arithmetic operations */
+
+/**
+ * Function: armRoundFloatToS16
+ *
+ * Description:
+ * Converts a double precision value into a short int after rounding
+ *
+ * Parameters:
+ * [in] Value Float value to be converted
+ *
+ * Return Value:
+ * [out] converted value in OMX_S16 format
+ *
+ */
+
+OMX_S16 armRoundFloatToS16 (OMX_F64 Value)
+{
+ if (Value > 0)
+ {
+ return (OMX_S16)(Value + .5);
+ }
+ else
+ {
+ return (OMX_S16)(Value - .5);
+ }
+}
+
+/**
+ * Function: armRoundFloatToS32
+ *
+ * Description:
+ * Converts a double precision value into a int after rounding
+ *
+ * Parameters:
+ * [in] Value Float value to be converted
+ *
+ * Return Value:
+ * [out] converted value in OMX_S32 format
+ *
+ */
+
+OMX_S32 armRoundFloatToS32 (OMX_F64 Value)
+{
+ if (Value > 0)
+ {
+ return (OMX_S32)(Value + .5);
+ }
+ else
+ {
+ return (OMX_S32)(Value - .5);
+ }
+}
+/**
+ * Function: armSatRoundFloatToS16
+ *
+ * Description:
+ * Converts a double precision value into a short int after rounding and saturation
+ *
+ * Parameters:
+ * [in] Value Float value to be converted
+ *
+ * Return Value:
+ * [out] converted value in OMX_S16 format
+ *
+ */
+
+OMX_S16 armSatRoundFloatToS16 (OMX_F64 Value)
+{
+ if (Value > 0)
+ {
+ Value += 0.5;
+
+ if(Value > (OMX_S16)OMX_MAX_S16 )
+ {
+ return (OMX_S16)OMX_MAX_S16;
+ }
+ else
+ {
+ return (OMX_S16)Value;
+ }
+ }
+ else
+ {
+ Value -= 0.5;
+
+ if(Value < (OMX_S16)OMX_MIN_S16 )
+ {
+ return (OMX_S16)OMX_MIN_S16;
+ }
+ else
+ {
+ return (OMX_S16)Value;
+ }
+ }
+}
+
+/**
+ * Function: armSatRoundFloatToS32
+ *
+ * Description:
+ * Converts a double precision value into a int after rounding and saturation
+ *
+ * Parameters:
+ * [in] Value Float value to be converted
+ *
+ * Return Value:
+ * [out] converted value in OMX_S32 format
+ *
+ */
+
+OMX_S32 armSatRoundFloatToS32 (OMX_F64 Value)
+{
+ if (Value > 0)
+ {
+ Value += 0.5;
+
+ if(Value > (OMX_S32)OMX_MAX_S32 )
+ {
+ return (OMX_S32)OMX_MAX_S32;
+ }
+ else
+ {
+ return (OMX_S32)Value;
+ }
+ }
+ else
+ {
+ Value -= 0.5;
+
+ if(Value < (OMX_S32)OMX_MIN_S32 )
+ {
+ return (OMX_S32)OMX_MIN_S32;
+ }
+ else
+ {
+ return (OMX_S32)Value;
+ }
+ }
+}
+
+/**
+ * Function: armSatRoundFloatToU16
+ *
+ * Description:
+ * Converts a double precision value into a unsigned short int after rounding and saturation
+ *
+ * Parameters:
+ * [in] Value Float value to be converted
+ *
+ * Return Value:
+ * [out] converted value in OMX_U16 format
+ *
+ */
+
+OMX_U16 armSatRoundFloatToU16 (OMX_F64 Value)
+{
+ Value += 0.5;
+
+ if(Value > (OMX_U16)OMX_MAX_U16 )
+ {
+ return (OMX_U16)OMX_MAX_U16;
+ }
+ else
+ {
+ return (OMX_U16)Value;
+ }
+}
+
+/**
+ * Function: armSatRoundFloatToU32
+ *
+ * Description:
+ * Converts a double precision value into a unsigned int after rounding and saturation
+ *
+ * Parameters:
+ * [in] Value Float value to be converted
+ *
+ * Return Value:
+ * [out] converted value in OMX_U32 format
+ *
+ */
+
+OMX_U32 armSatRoundFloatToU32 (OMX_F64 Value)
+{
+ Value += 0.5;
+
+ if(Value > (OMX_U32)OMX_MAX_U32 )
+ {
+ return (OMX_U32)OMX_MAX_U32;
+ }
+ else
+ {
+ return (OMX_U32)Value;
+ }
+}
+
+/**
+ * Function: armRoundFloatToS64
+ *
+ * Description:
+ * Converts a double precision value into a 64 bit int after rounding
+ *
+ * Parameters:
+ * [in] Value Float value to be converted
+ *
+ * Return Value:
+ * [out] converted value in OMX_S64 format
+ *
+ */
+
+OMX_S64 armRoundFloatToS64 (OMX_F64 Value)
+{
+ if (Value > 0)
+ {
+ return (OMX_S64)(Value + .5);
+ }
+ else
+ {
+ return (OMX_S64)(Value - .5);
+ }
+}
+
+/**
+ * Function: armSignCheck
+ *
+ * Description:
+ * Checks the sign of a variable:
+ * returns 1 if it is Positive
+ * returns 0 if it is 0
+ * returns -1 if it is Negative
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] var Variable to be checked
+ *
+ * Return Value:
+ * OMX_INT -- returns 1 if it is Positive
+ * returns 0 if it is 0
+ * returns -1 if it is Negative
+ */
+
+OMX_INT armSignCheck (
+ OMX_S16 var
+)
+
+{
+ OMX_INT Sign;
+
+ if (var < 0)
+ {
+ Sign = -1;
+ }
+ else if ( var > 0)
+ {
+ Sign = 1;
+ }
+ else
+ {
+ Sign = 0;
+ }
+
+ return Sign;
+}
+
+/**
+ * Function: armClip
+ *
+ * Description: Clips the input between MAX and MIN value
+ *
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] Min lower bound
+ * [in] Max upper bound
+ * [in] src variable to the clipped
+ *
+ * Return Value:
+ * OMX_S32 -- returns clipped value
+ */
+
+OMX_S32 armClip (
+ OMX_INT min,
+ OMX_INT max,
+ OMX_S32 src
+)
+
+{
+ if (src > max)
+ {
+ src = max;
+ }
+ else if (src < min)
+ {
+ src = min;
+ }
+
+ return src;
+}
+
+/**
+ * Function: armClip_F32
+ *
+ * Description: Clips the input between MAX and MIN value
+ *
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] Min lower bound
+ * [in] Max upper bound
+ * [in] src variable to the clipped
+ *
+ * Return Value:
+ * OMX_F32 -- returns clipped value
+ */
+
+OMX_F32 armClip_F32 (
+ OMX_F32 min,
+ OMX_F32 max,
+ OMX_F32 src
+)
+
+{
+ if (src > max)
+ {
+ src = max;
+ }
+ else if (src < min)
+ {
+ src = min;
+ }
+
+ return src;
+}
+
+/**
+ * Function: armShiftSat_F32
+ *
+ * Description: Divides a float value by 2^shift and
+ * saturates it for unsigned value range for satBits.
+ * Second parameter is like "shifting" the corresponding
+ * integer value. Takes care of rounding while clipping the final
+ * value.
+ *
+ * Parameters:
+ * [in] v Number to be operated upon
+ * [in] shift Divides the input "v" by "2^shift"
+ * [in] satBits Final range is [0, 2^satBits)
+ *
+ * Return Value:
+ * OMX_S32 -- returns "shifted" saturated value
+ */
+
+OMX_U32 armShiftSat_F32(OMX_F32 v, OMX_INT shift, OMX_INT satBits)
+{
+ OMX_U32 allOnes = (OMX_U32)(-1);
+ OMX_U32 maxV = allOnes >> (32-satBits);
+ OMX_F32 vShifted, vRounded, shiftDiv = (OMX_F32)(1 << shift);
+ OMX_U32 vInt;
+ OMX_U32 vIntSat;
+
+ if(v <= 0)
+ return 0;
+
+ vShifted = v / shiftDiv;
+ vRounded = (OMX_F32)(vShifted + 0.5);
+ vInt = (OMX_U32)vRounded;
+ vIntSat = vInt;
+ if(vIntSat > maxV)
+ vIntSat = maxV;
+ return vIntSat;
+}
+
+/**
+ * Functions: armSwapElem
+ *
+ * Description:
+ * These function swaps two elements at the specified pointer locations.
+ * The size of each element could be anything as specified by <elemSize>
+ *
+ * Return Value:
+ * OMXResult -- Error status from the function
+ */
+OMXResult armSwapElem(
+ OMX_U8 *pBuf1,
+ OMX_U8 *pBuf2,
+ OMX_INT elemSize
+ )
+{
+ OMX_INT i;
+ OMX_U8 temp;
+ armRetArgErrIf(!pBuf1 || !pBuf2, OMX_Sts_BadArgErr);
+
+ for(i = 0; i < elemSize; i++)
+ {
+ temp = *(pBuf1 + i);
+ *(pBuf1 + i) = *(pBuf2 + i);
+ *(pBuf2 + i) = temp;
+ }
+ return OMX_Sts_NoErr;
+}
+
+/**
+ * Function: armMedianOf3
+ *
+ * Description: Finds the median of three numbers
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] fEntry First entry
+ * [in] sEntry second entry
+ * [in] tEntry Third entry
+ *
+ * Return Value:
+ * OMX_S32 -- returns the median value
+ */
+
+OMX_S32 armMedianOf3 (
+ OMX_S32 fEntry,
+ OMX_S32 sEntry,
+ OMX_S32 tEntry
+)
+{
+ OMX_S32 a, b, c;
+
+ a = armMin (fEntry, sEntry);
+ b = armMax (fEntry, sEntry);
+ c = armMin (b, tEntry);
+ return (armMax (a, c));
+}
+
+/**
+ * Function: armLogSize
+ *
+ * Description: Finds the size of a positive value and returns the same
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] value Positive value
+ *
+ * Return Value:
+ * OMX_U8 -- Returns the minimum number of bits required to represent the positive value.
+ This is the smallest k>=0 such that that value is less than (1<<k).
+ */
+
+OMX_U8 armLogSize (
+ OMX_U16 value
+)
+{
+ OMX_U8 i;
+ for ( i = 0; value > 0; value = value >> 1)
+ {
+ i++;
+ }
+ return i;
+}
+
+/***********************************************************************/
+ /* Saturating Arithmetic operations */
+
+/**
+ * Function :armSatAdd_S32()
+ *
+ * Description :
+ * Returns the result of saturated addition of the two inputs Value1, Value2
+ *
+ * Parametrs:
+ * [in] Value1 First Operand
+ * [in] Value2 Second Operand
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ *
+ **/
+
+OMX_S32 armSatAdd_S32(OMX_S32 Value1,OMX_S32 Value2)
+{
+ OMX_S32 Result;
+
+ Result = Value1 + Value2;
+
+ if( (Value1^Value2) >= 0)
+ {
+ /*Same sign*/
+ if( (Result^Value1) >= 0)
+ {
+ /*Result has not saturated*/
+ return Result;
+ }
+ else
+ {
+ if(Value1 >= 0)
+ {
+ /*Result has saturated in positive side*/
+ return OMX_MAX_S32;
+ }
+ else
+ {
+ /*Result has saturated in negative side*/
+ return OMX_MIN_S32;
+ }
+
+ }
+
+ }
+ else
+ {
+ return Result;
+ }
+
+}
+
+/**
+ * Function :armSatAdd_S64()
+ *
+ * Description :
+ * Returns the result of saturated addition of the two inputs Value1, Value2
+ *
+ * Parametrs:
+ * [in] Value1 First Operand
+ * [in] Value2 Second Operand
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ *
+ **/
+
+OMX_S64 armSatAdd_S64(OMX_S64 Value1,OMX_S64 Value2)
+{
+ OMX_S64 Result;
+
+ Result = Value1 + Value2;
+
+ if( (Value1^Value2) >= 0)
+ {
+ /*Same sign*/
+ if( (Result^Value1) >= 0)
+ {
+ /*Result has not saturated*/
+ return Result;
+ }
+ else
+ {
+ if(Value1 >= 0)
+ {
+ /*Result has saturated in positive side*/
+ Result = OMX_MAX_S64;
+ return Result;
+ }
+ else
+ {
+ /*Result has saturated in negative side*/
+ return OMX_MIN_S64;
+ }
+
+ }
+
+ }
+ else
+ {
+ return Result;
+ }
+
+}
+
+/** Function :armSatSub_S32()
+ *
+ * Description :
+ * Returns the result of saturated substraction of the two inputs Value1, Value2
+ *
+ * Parametrs:
+ * [in] Value1 First Operand
+ * [in] Value2 Second Operand
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ **/
+
+OMX_S32 armSatSub_S32(OMX_S32 Value1,OMX_S32 Value2)
+{
+ OMX_S32 Result;
+
+ Result = Value1 - Value2;
+
+ if( (Value1^Value2) < 0)
+ {
+ /*Opposite sign*/
+ if( (Result^Value1) >= 0)
+ {
+ /*Result has not saturated*/
+ return Result;
+ }
+ else
+ {
+ if(Value1 >= 0)
+ {
+ /*Result has saturated in positive side*/
+ return OMX_MAX_S32;
+ }
+ else
+ {
+ /*Result has saturated in negative side*/
+ return OMX_MIN_S32;
+ }
+
+ }
+
+ }
+ else
+ {
+ return Result;
+ }
+
+}
+
+/**
+ * Function :armSatMac_S32()
+ *
+ * Description :
+ * Returns the result of Multiplication of Value1 and Value2 and subesquent saturated
+ * accumulation with Mac
+ *
+ * Parametrs:
+ * [in] Value1 First Operand
+ * [in] Value2 Second Operand
+ * [in] Mac Accumulator
+ *
+ * Return:
+ * [out] Result of operation
+ **/
+
+OMX_S32 armSatMac_S32(OMX_S32 Mac,OMX_S16 Value1,OMX_S16 Value2)
+{
+ OMX_S32 Result;
+
+ Result = (OMX_S32)(Value1*Value2);
+ Result = armSatAdd_S32( Mac , Result );
+
+ return Result;
+}
+
+/**
+ * Function :armSatMac_S16S32_S32
+ *
+ * Description :
+ * Returns the result of saturated MAC operation of the three inputs delayElem, filTap , mac
+ *
+ * mac = mac + Saturate_in_32Bits(delayElem * filTap)
+ *
+ * Parametrs:
+ * [in] delayElem First 32 bit Operand
+ * [in] filTap Second 16 bit Operand
+ * [in] mac Result of MAC operation
+ *
+ * Return:
+ * [out] mac Result of operation
+ *
+ **/
+
+OMX_S32 armSatMac_S16S32_S32(OMX_S32 mac, OMX_S32 delayElem, OMX_S16 filTap )
+{
+
+ OMX_S32 result;
+
+ result = armSatMulS16S32_S32(filTap,delayElem);
+
+ if ( result > OMX_MAX_S16 )
+ {
+ result = OMX_MAX_S32;
+ }
+ else if( result < OMX_MIN_S16 )
+ {
+ result = OMX_MIN_S32;
+ }
+ else
+ {
+ result = delayElem * filTap;
+ }
+
+ mac = armSatAdd_S32(mac,result);
+
+ return mac;
+}
+
+
+/**
+ * Function :armSatRoundRightShift_S32_S16
+ *
+ * Description :
+ * Returns the result of rounded right shift operation of input by the scalefactor
+ *
+ * output = Saturate_in_16Bits( ( Right/LeftShift( (Round(input) , shift ) )
+ *
+ * Parametrs:
+ * [in] input The input to be operated on
+ * [in] shift The shift number
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ **/
+
+
+OMX_S16 armSatRoundRightShift_S32_S16(OMX_S32 input, OMX_INT shift)
+{
+ input = armSatRoundLeftShift_S32(input,-shift);
+
+ if ( input > OMX_MAX_S16 )
+ {
+ return (OMX_S16)OMX_MAX_S16;
+ }
+ else if (input < OMX_MIN_S16)
+ {
+ return (OMX_S16)OMX_MIN_S16;
+ }
+ else
+ {
+ return (OMX_S16)input;
+ }
+
+}
+
+/**
+ * Function :armSatRoundLeftShift_S32()
+ *
+ * Description :
+ * Returns the result of saturating left-shift operation on input
+ * Or rounded Right shift if the input Shift is negative.
+ *
+ * Parametrs:
+ * [in] Value Operand
+ * [in] Shift Operand for shift operation
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ **/
+
+OMX_S32 armSatRoundLeftShift_S32(OMX_S32 Value, OMX_INT Shift)
+{
+ OMX_INT i;
+
+ if (Shift < 0)
+ {
+ Shift = -Shift;
+ Value = armSatAdd_S32(Value, (1 << (Shift - 1)));
+ Value = Value >> Shift;
+ }
+ else
+ {
+ for (i = 0; i < Shift; i++)
+ {
+ Value = armSatAdd_S32(Value, Value);
+ }
+ }
+ return Value;
+}
+
+/**
+ * Function :armSatRoundLeftShift_S64()
+ *
+ * Description :
+ * Returns the result of saturating left-shift operation on input
+ * Or rounded Right shift if the input Shift is negative.
+ *
+ * Parametrs:
+ * [in] Value Operand
+ * [in] shift Operand for shift operation
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ **/
+
+OMX_S64 armSatRoundLeftShift_S64(OMX_S64 Value, OMX_INT Shift)
+{
+ OMX_INT i;
+
+ if (Shift < 0)
+ {
+ Shift = -Shift;
+ Value = armSatAdd_S64(Value, ((OMX_S64)1 << (Shift - 1)));
+ Value = Value >> Shift;
+ }
+ else
+ {
+ for (i = 0; i < Shift; i++)
+ {
+ Value = armSatAdd_S64(Value, Value);
+ }
+ }
+ return Value;
+}
+
+/**
+ * Function :armSatMulS16S32_S32()
+ *
+ * Description :
+ * Returns the result of a S16 data type multiplied with an S32 data type
+ * in a S32 container
+ *
+ * Parametrs:
+ * [in] input1 Operand 1
+ * [in] input2 Operand 2
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ **/
+
+
+OMX_S32 armSatMulS16S32_S32(OMX_S16 input1,OMX_S32 input2)
+{
+ OMX_S16 hi2,lo1;
+ OMX_U16 lo2;
+
+ OMX_S32 temp1,temp2;
+ OMX_S32 result;
+
+ lo1 = input1;
+
+ hi2 = ( input2 >> 16 );
+ lo2 = ( (OMX_U32)( input2 << 16 ) >> 16 );
+
+ temp1 = hi2 * lo1;
+ temp2 = ( lo2* lo1 ) >> 16;
+
+ result = armSatAdd_S32(temp1,temp2);
+
+ return result;
+}
+
+/**
+ * Function :armSatMulS32S32_S32()
+ *
+ * Description :
+ * Returns the result of a S32 data type multiplied with an S32 data type
+ * in a S32 container
+ *
+ * Parametrs:
+ * [in] input1 Operand 1
+ * [in] input2 Operand 2
+ *
+ * Return:
+ * [out] Result of operation
+ *
+ **/
+
+OMX_S32 armSatMulS32S32_S32(OMX_S32 input1,OMX_S32 input2)
+{
+ OMX_S16 hi1,hi2;
+ OMX_U16 lo1,lo2;
+
+ OMX_S32 temp1,temp2,temp3;
+ OMX_S32 result;
+
+ hi1 = ( input1 >> 16 );
+ lo1 = ( (OMX_U32)( input1 << 16 ) >> 16 );
+
+ hi2 = ( input2 >> 16 );
+ lo2 = ( (OMX_U32)( input2 << 16 ) >> 16 );
+
+ temp1 = hi1 * hi2;
+ temp2 = ( hi1* lo2 ) >> 16;
+ temp3 = ( hi2* lo1 ) >> 16;
+
+ result = armSatAdd_S32(temp1,temp2);
+ result = armSatAdd_S32(result,temp3);
+
+ return result;
+}
+
+/**
+ * Function :armIntDivAwayFromZero()
+ *
+ * Description : Integer division with rounding to the nearest integer.
+ * Half-integer values are rounded away from zero
+ * unless otherwise specified. For example 3//2 is rounded
+ * to 2, and -3//2 is rounded to -2.
+ *
+ * Parametrs:
+ * [in] Num Operand 1
+ * [in] Deno Operand 2
+ *
+ * Return:
+ * [out] Result of operation input1//input2
+ *
+ **/
+
+OMX_S32 armIntDivAwayFromZero (OMX_S32 Num, OMX_S32 Deno)
+{
+ OMX_F64 result;
+
+ result = ((OMX_F64)Num)/((OMX_F64)Deno);
+
+ if (result >= 0)
+ {
+ result += 0.5;
+ }
+ else
+ {
+ result -= 0.5;
+ }
+
+ return (OMX_S32)(result);
+}
+
+
+/*End of File*/
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/src/armCOMM_Bitstream.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/src/armCOMM_Bitstream.c
new file mode 100644
index 0000000..9ef9319
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/src/armCOMM_Bitstream.c
@@ -0,0 +1,329 @@
+/**
+ *
+ * File Name: armCOMM_Bitstream.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Defines bitstream encode and decode functions common to all codecs
+ */
+
+#include "omxtypes.h"
+#include "armCOMM.h"
+#include "armCOMM_Bitstream.h"
+
+/***************************************
+ * Fixed bit length Decode
+ ***************************************/
+
+/**
+ * Function: armLookAheadBits()
+ *
+ * Description:
+ * Get the next N bits from the bitstream without advancing the bitstream pointer
+ *
+ * Parameters:
+ * [in] **ppBitStream
+ * [in] *pOffset
+ * [in] N=1...32
+ *
+ * Returns Value
+ */
+
+OMX_U32 armLookAheadBits(const OMX_U8 **ppBitStream, OMX_INT *pOffset, OMX_INT N)
+{
+ const OMX_U8 *pBitStream = *ppBitStream;
+ OMX_INT Offset = *pOffset;
+ OMX_U32 Value;
+
+ armAssert(Offset>=0 && Offset<=7);
+ armAssert(N>=1 && N<=32);
+
+ /* Read next 32 bits from stream */
+ Value = (pBitStream[0] << 24 ) | ( pBitStream[1] << 16) | (pBitStream[2] << 8 ) | (pBitStream[3]) ;
+ Value = (Value << Offset ) | (pBitStream[4] >> (8-Offset));
+
+ /* Return N bits */
+ return Value >> (32-N);
+}
+
+
+/**
+ * Function: armGetBits()
+ *
+ * Description:
+ * Read N bits from the bitstream
+ *
+ * Parameters:
+ * [in] *ppBitStream
+ * [in] *pOffset
+ * [in] N=1..32
+ *
+ * [out] *ppBitStream
+ * [out] *pOffset
+ * Returns Value
+ */
+
+
+OMX_U32 armGetBits(const OMX_U8 **ppBitStream, OMX_INT *pOffset, OMX_INT N)
+{
+ const OMX_U8 *pBitStream = *ppBitStream;
+ OMX_INT Offset = *pOffset;
+ OMX_U32 Value;
+
+ if(N == 0)
+ {
+ return 0;
+ }
+
+ armAssert(Offset>=0 && Offset<=7);
+ armAssert(N>=1 && N<=32);
+
+ /* Read next 32 bits from stream */
+ Value = (pBitStream[0] << 24 ) | ( pBitStream[1] << 16) | (pBitStream[2] << 8 ) | (pBitStream[3]) ;
+ Value = (Value << Offset ) | (pBitStream[4] >> (8-Offset));
+
+ /* Advance bitstream pointer by N bits */
+ Offset += N;
+ *ppBitStream = pBitStream + (Offset>>3);
+ *pOffset = Offset & 7;
+
+ /* Return N bits */
+ return Value >> (32-N);
+}
+
+/**
+ * Function: armByteAlign()
+ *
+ * Description:
+ * Align the pointer *ppBitStream to the next byte boundary
+ *
+ * Parameters:
+ * [in] *ppBitStream
+ * [in] *pOffset
+ *
+ * [out] *ppBitStream
+ * [out] *pOffset
+ *
+ **/
+
+OMXVoid armByteAlign(const OMX_U8 **ppBitStream,OMX_INT *pOffset)
+{
+ if(*pOffset > 0)
+ {
+ *ppBitStream += 1;
+ *pOffset = 0;
+ }
+}
+
+/**
+ * Function: armSkipBits()
+ *
+ * Description:
+ * Skip N bits from the value at *ppBitStream
+ *
+ * Parameters:
+ * [in] *ppBitStream
+ * [in] *pOffset
+ * [in] N
+ *
+ * [out] *ppBitStream
+ * [out] *pOffset
+ *
+ **/
+
+
+OMXVoid armSkipBits(const OMX_U8 **ppBitStream,OMX_INT *pOffset,OMX_INT N)
+{
+ OMX_INT Offset = *pOffset;
+ const OMX_U8 *pBitStream = *ppBitStream;
+
+ /* Advance bitstream pointer by N bits */
+ Offset += N;
+ *ppBitStream = pBitStream + (Offset>>3);
+ *pOffset = Offset & 7;
+}
+
+/***************************************
+ * Variable bit length Decode
+ ***************************************/
+
+/**
+ * Function: armUnPackVLC32()
+ *
+ * Description:
+ * Variable length decode of variable length symbol (max size 32 bits) read from
+ * the bit stream pointed by *ppBitStream at *pOffset by using the table
+ * pointed by pCodeBook
+ *
+ * Parameters:
+ * [in] *pBitStream
+ * [in] *pOffset
+ * [in] pCodeBook
+ *
+ * [out] *pBitStream
+ * [out] *pOffset
+ *
+ * Returns : Code Book Index if successfull.
+ * : ARM_NO_CODEBOOK_INDEX = -1 if search fails.
+ **/
+#ifndef C_OPTIMIZED_IMPLEMENTATION
+
+OMX_U16 armUnPackVLC32(
+ const OMX_U8 **ppBitStream,
+ OMX_INT *pOffset,
+ const ARM_VLC32 *pCodeBook
+)
+{
+ const OMX_U8 *pBitStream = *ppBitStream;
+ OMX_INT Offset = *pOffset;
+ OMX_U32 Value;
+ OMX_INT Index;
+
+ armAssert(Offset>=0 && Offset<=7);
+
+ /* Read next 32 bits from stream */
+ Value = (pBitStream[0] << 24 ) | ( pBitStream[1] << 16) | (pBitStream[2] << 8 ) | (pBitStream[3]) ;
+ Value = (Value << Offset ) | (pBitStream[4] >> (8-Offset));
+
+ /* Search through the codebook */
+ for (Index=0; pCodeBook->codeLen != 0; Index++)
+ {
+ if (pCodeBook->codeWord == (Value >> (32 - pCodeBook->codeLen)))
+ {
+ Offset = Offset + pCodeBook->codeLen;
+ *ppBitStream = pBitStream + (Offset >> 3) ;
+ *pOffset = Offset & 7;
+
+ return Index;
+ }
+ pCodeBook++;
+ }
+
+ /* No code match found */
+ return ARM_NO_CODEBOOK_INDEX;
+}
+
+#endif
+
+/***************************************
+ * Fixed bit length Encode
+ ***************************************/
+
+/**
+ * Function: armPackBits
+ *
+ * Description:
+ * Pack a VLC code word into the bitstream
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream pointer to the pointer to the current byte
+ * in the bit stream.
+ * [in] pOffset pointer to the bit position in the byte
+ * pointed by *ppBitStream. Valid within 0
+ * to 7.
+ * [in] codeWord Code word that need to be inserted in to the
+ * bitstream
+ * [in] codeLength Length of the code word valid range 1...32
+ *
+ * [out] ppBitStream *ppBitStream is updated after the block is encoded,
+ * so that it points to the current byte in the bit
+ * stream buffer.
+ * [out] pBitOffset *pBitOffset is updated so that it points to the
+ * current bit position in the byte pointed by
+ * *ppBitStream.
+ *
+ * Return Value:
+ * Standard OMX_RESULT result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armPackBits (
+ OMX_U8 **ppBitStream,
+ OMX_INT *pOffset,
+ OMX_U32 codeWord,
+ OMX_INT codeLength
+)
+{
+ OMX_U8 *pBitStream = *ppBitStream;
+ OMX_INT Offset = *pOffset;
+ OMX_U32 Value;
+
+ /* checking argument validity */
+ armRetArgErrIf(Offset < 0, OMX_Sts_BadArgErr);
+ armRetArgErrIf(Offset > 7, OMX_Sts_BadArgErr);
+ armRetArgErrIf(codeLength < 1, OMX_Sts_BadArgErr);
+ armRetArgErrIf(codeLength > 32, OMX_Sts_BadArgErr);
+
+ /* Prepare the first byte */
+ codeWord = codeWord << (32-codeLength);
+ Value = (pBitStream[0] >> (8-Offset)) << (8-Offset);
+ Value = Value | (codeWord >> (24+Offset));
+
+ /* Write out whole bytes */
+ while (8-Offset <= codeLength)
+ {
+ *pBitStream++ = (OMX_U8)Value;
+ codeWord = codeWord << (8-Offset);
+ codeLength = codeLength - (8-Offset);
+ Offset = 0;
+ Value = codeWord >> 24;
+ }
+
+ /* Write out final partial byte */
+ *pBitStream = (OMX_U8)Value;
+ *ppBitStream = pBitStream;
+ *pOffset = Offset + codeLength;
+
+ return OMX_Sts_NoErr;
+}
+
+/***************************************
+ * Variable bit length Encode
+ ***************************************/
+
+/**
+ * Function: armPackVLC32
+ *
+ * Description:
+ * Pack a VLC code word into the bitstream
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream pointer to the pointer to the current byte
+ * in the bit stream.
+ * [in] pBitOffset pointer to the bit position in the byte
+ * pointed by *ppBitStream. Valid within 0
+ * to 7.
+ * [in] code VLC code word that need to be inserted in to the
+ * bitstream
+ *
+ * [out] ppBitStream *ppBitStream is updated after the block is encoded,
+ * so that it points to the current byte in the bit
+ * stream buffer.
+ * [out] pBitOffset *pBitOffset is updated so that it points to the
+ * current bit position in the byte pointed by
+ * *ppBitStream.
+ *
+ * Return Value:
+ * Standard OMX_RESULT result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armPackVLC32 (
+ OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ ARM_VLC32 code
+)
+{
+ return (armPackBits(ppBitStream, pBitOffset, code.codeWord, code.codeLen));
+}
+
+/*End of File*/
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/api/armVC.h b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/api/armVC.h
new file mode 100644
index 0000000..7fa7716
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/api/armVC.h
@@ -0,0 +1,1153 @@
+/**
+ *
+ * File Name: armVC.h
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * File: armVideo.h
+ * Brief: Declares API's/Basic Data types used across the OpenMAX Video domain
+ *
+ */
+
+
+#ifndef _armVideo_H_
+#define _armVideo_H_
+
+#include "omxVC.h"
+#include "armCOMM_Bitstream.h"
+
+/**
+ * ARM specific state structure to hold Motion Estimation information.
+ */
+
+struct m4p2_MESpec
+{
+ OMXVCM4P2MEParams MEParams;
+ OMXVCM4P2MEMode MEMode;
+};
+
+struct m4p10_MESpec
+{
+ OMXVCM4P10MEParams MEParams;
+ OMXVCM4P10MEMode MEMode;
+};
+
+typedef struct m4p2_MESpec ARMVCM4P2_MESpec;
+typedef struct m4p10_MESpec ARMVCM4P10_MESpec;
+
+/**
+ * Function: armVCM4P2_CompareMV
+ *
+ * Description:
+ * Performs comparision of motion vectors and SAD's to decide the
+ * best MV and SAD
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] mvX x coordinate of the candidate motion vector
+ * [in] mvY y coordinate of the candidate motion vector
+ * [in] candSAD Candidate SAD
+ * [in] bestMVX x coordinate of the best motion vector
+ * [in] bestMVY y coordinate of the best motion vector
+ * [in] bestSAD best SAD
+ *
+ * Return Value:
+ * OMX_INT -- 1 to indicate that the current sad is the best
+ * 0 to indicate that it is NOT the best SAD
+ */
+
+OMX_INT armVCM4P2_CompareMV (
+ OMX_S16 mvX,
+ OMX_S16 mvY,
+ OMX_INT candSAD,
+ OMX_S16 bestMVX,
+ OMX_S16 bestMVY,
+ OMX_INT bestSAD);
+
+/**
+ * Function: armVCM4P2_ACDCPredict
+ *
+ * Description:
+ * Performs adaptive DC/AC coefficient prediction for an intra block. Prior
+ * to the function call, prediction direction (predDir) should be selected
+ * as specified in subclause 7.4.3.1 of ISO/IEC 14496-2.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] pSrcDst pointer to the coefficient buffer which contains
+ * the quantized coefficient residuals (PQF) of the
+ * current block
+ * [in] pPredBufRow pointer to the coefficient row buffer
+ * [in] pPredBufCol pointer to the coefficient column buffer
+ * [in] curQP quantization parameter of the current block. curQP
+ * may equal to predQP especially when the current
+ * block and the predictor block are in the same
+ * macroblock.
+ * [in] predQP quantization parameter of the predictor block
+ * [in] predDir indicates the prediction direction which takes one
+ * of the following values:
+ * OMX_VIDEO_HORIZONTAL predict horizontally
+ * OMX_VIDEO_VERTICAL predict vertically
+ * [in] ACPredFlag a flag indicating if AC prediction should be
+ * performed. It is equal to ac_pred_flag in the bit
+ * stream syntax of MPEG-4
+ * [in] videoComp video component type (luminance, chrominance or
+ * alpha) of the current block
+ * [in] flag This flag defines the if one wants to use this functions to
+ * calculate PQF (set 1, prediction) or QF (set 0, reconstruction)
+ * [out] pPreACPredict pointer to the predicted coefficients buffer.
+ * Filled ONLY if it is not NULL
+ * [out] pSrcDst pointer to the coefficient buffer which contains
+ * the quantized coefficients (QF) of the current
+ * block
+ * [out] pPredBufRow pointer to the updated coefficient row buffer
+ * [out] pPredBufCol pointer to the updated coefficient column buffer
+ * [out] pSumErr pointer to the updated sum of the difference
+ * between predicted and unpredicted coefficients
+ * If this is NULL, do not update
+ *
+ * Return Value:
+ * Standard OMXResult result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armVCM4P2_ACDCPredict(
+ OMX_S16 * pSrcDst,
+ OMX_S16 * pPreACPredict,
+ OMX_S16 * pPredBufRow,
+ OMX_S16 * pPredBufCol,
+ OMX_INT curQP,
+ OMX_INT predQP,
+ OMX_INT predDir,
+ OMX_INT ACPredFlag,
+ OMXVCM4P2VideoComponent videoComp,
+ OMX_U8 flag,
+ OMX_INT *pSumErr
+);
+
+/**
+ * Function: armVCM4P2_SetPredDir
+ *
+ * Description:
+ * Performs detecting the prediction direction
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] blockIndex block index indicating the component type and
+ * position as defined in subclause 6.1.3.8, of ISO/IEC
+ * 14496-2. Furthermore, indexes 6 to 9 indicate the
+ * alpha blocks spatially corresponding to luminance
+ * blocks 0 to 3 in the same macroblock.
+ * [in] pCoefBufRow pointer to the coefficient row buffer
+ * [in] pQpBuf pointer to the quantization parameter buffer
+ * [out] predQP quantization parameter of the predictor block
+ * [out] predDir indicates the prediction direction which takes one
+ * of the following values:
+ * OMX_VIDEO_HORIZONTAL predict horizontally
+ * OMX_VIDEO_VERTICAL predict vertically
+ *
+ * Return Value:
+ * Standard OMXResult result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armVCM4P2_SetPredDir(
+ OMX_INT blockIndex,
+ OMX_S16 *pCoefBufRow,
+ OMX_S16 *pCoefBufCol,
+ OMX_INT *predDir,
+ OMX_INT *predQP,
+ const OMX_U8 *pQpBuf
+);
+
+/**
+ * Function: armVCM4P2_EncodeVLCZigzag_Intra
+ *
+ * Description:
+ * Performs zigzag scanning and VLC encoding for one intra block.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream pointer to the pointer to the current byte in
+ * the bit stream
+ * [in] pBitOffset pointer to the bit position in the byte pointed
+ * by *ppBitStream. Valid within 0 to 7.
+ * [in] pQDctBlkCoef pointer to the quantized DCT coefficient
+ * [in] predDir AC prediction direction, which is used to decide
+ * the zigzag scan pattern. This takes one of the
+ * following values:
+ * OMX_VIDEO_NONE AC prediction not used.
+ * Performs classical zigzag
+ * scan.
+ * OMX_VIDEO_HORIZONTAL Horizontal prediction.
+ * Performs alternate-vertical
+ * zigzag scan.
+ * OMX_VIDEO_VERTICAL Vertical prediction.
+ * Performs alternate-horizontal
+ * zigzag scan.
+ * [in] pattern block pattern which is used to decide whether
+ * this block is encoded
+ * [in] start start indicates whether the encoding begins with 0th element
+ * or 1st.
+ * [out] ppBitStream *ppBitStream is updated after the block is encoded,
+ * so that it points to the current byte in the bit
+ * stream buffer.
+ * [out] pBitOffset *pBitOffset is updated so that it points to the
+ * current bit position in the byte pointed by
+ * *ppBitStream.
+ *
+ * Return Value:
+ * Standard OMXResult result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armVCM4P2_EncodeVLCZigzag_Intra(
+ OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ const OMX_S16 *pQDctBlkCoef,
+ OMX_U8 predDir,
+ OMX_U8 pattern,
+ OMX_INT shortVideoHeader,
+ OMX_U8 start
+);
+
+/**
+ * Function: armVCM4P2_DecodeVLCZigzag_Intra
+ *
+ * Description:
+ * Performs VLC decoding and inverse zigzag scan for one intra coded block.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream pointer to the pointer to the current byte in
+ * the bitstream buffer
+ * [in] pBitOffset pointer to the bit position in the byte pointed
+ * to by *ppBitStream. *pBitOffset is valid within
+ * [0-7].
+ * [in] predDir AC prediction direction which is used to decide
+ * the zigzag scan pattern. It takes one of the
+ * following values:
+ * OMX_VIDEO_NONE AC prediction not used;
+ * perform classical zigzag scan;
+ * OMX_VIDEO_HORIZONTAL Horizontal prediction;
+ * perform alternate-vertical
+ * zigzag scan;
+ * OMX_VIDEO_VERTICAL Vertical prediction;
+ * thus perform
+ * alternate-horizontal
+ * zigzag scan.
+ * [in] videoComp video component type (luminance, chrominance or
+ * alpha) of the current block
+ * [in] shortVideoHeader binary flag indicating presence of short_video_header; escape modes 0-3 are used if shortVideoHeader==0,
+ * and escape mode 4 is used when shortVideoHeader==1.
+ * [in] start start indicates whether the encoding begins with 0th element
+ * or 1st.
+ * [out] ppBitStream *ppBitStream is updated after the block is
+ * decoded, so that it points to the current byte
+ * in the bit stream buffer
+ * [out] pBitOffset *pBitOffset is updated so that it points to the
+ * current bit position in the byte pointed by
+ * *ppBitStream
+ * [out] pDst pointer to the coefficient buffer of current
+ * block. Should be 32-bit aligned
+ *
+ * Return Value:
+ * Standard OMXResult result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armVCM4P2_DecodeVLCZigzag_Intra(
+ const OMX_U8 ** ppBitStream,
+ OMX_INT * pBitOffset,
+ OMX_S16 * pDst,
+ OMX_U8 predDir,
+ OMX_INT shortVideoHeader,
+ OMX_U8 start
+);
+
+/**
+ * Function: armVCM4P2_FillVLDBuffer
+ *
+ * Description:
+ * Performs filling of the coefficient buffer according to the run, level
+ * and sign, also updates the index
+ *
+ * Parameters:
+ * [in] storeRun Stored Run value (count of zeros)
+ * [in] storeLevel Stored Level value (non-zero value)
+ * [in] sign Flag indicating the sign of level
+ * [in] last status of the last flag
+ * [in] pIndex pointer to coefficient index in 8x8 matrix
+ * [out] pIndex pointer to updated coefficient index in 8x8
+ * matrix
+ * [in] pZigzagTable pointer to the zigzag tables
+ * [out] pDst pointer to the coefficient buffer of current
+ * block. Should be 32-bit aligned
+ * Return Value:
+ * Standard OMXResult result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armVCM4P2_FillVLDBuffer(
+ OMX_U32 storeRun,
+ OMX_S16 * pDst,
+ OMX_S16 storeLevel,
+ OMX_U8 sign,
+ OMX_U8 last,
+ OMX_U8 * index,
+ const OMX_U8 * pZigzagTable
+);
+
+/**
+ * Function: armVCM4P2_GetVLCBits
+ *
+ * Description:
+ * Performs escape mode decision based on the run, run+, level, level+ and
+ * last combinations.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream pointer to the pointer to the current byte in
+ * the bit stream
+ * [in] pBitOffset pointer to the bit position in the byte pointed
+ * by *ppBitStream. Valid within 0 to 7
+ * [in] shortVideoHeader binary flag indicating presence of short_video_header; escape modes 0-3 are used if shortVideoHeader==0,
+ * and escape mode 4 is used when shortVideoHeader==1.
+ * [in] start start indicates whether the encoding begins with
+ * 0th element or 1st.
+ * [in/out] pLast pointer to last status flag
+ * [in] runBeginSingleLevelEntriesL0 The run value from which level
+ * will be equal to 1: last == 0
+ * [in] IndexBeginSingleLevelEntriesL0 Array index in the VLC table
+ * pointing to the
+ * runBeginSingleLevelEntriesL0
+ * [in] runBeginSingleLevelEntriesL1 The run value from which level
+ * will be equal to 1: last == 1
+ * [in] IndexBeginSingleLevelEntriesL1 Array index in the VLC table
+ * pointing to the
+ * runBeginSingleLevelEntriesL0
+ * [in] pRunIndexTableL0 Run Index table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 0
+ * [in] pVlcTableL0 VLC table for last == 0
+ * [in] pRunIndexTableL1 Run Index table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 1
+ * [in] pVlcTableL1 VLC table for last == 1
+ * [in] pLMAXTableL0 Level MAX table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 0
+ * [in] pLMAXTableL1 Level MAX table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 1
+ * [in] pRMAXTableL0 Run MAX table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 0
+ * [in] pRMAXTableL1 Run MAX table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 1
+ * [out]pDst pointer to the coefficient buffer of current
+ * block. Should be 32-bit aligned
+ *
+ * Return Value:
+ * Standard OMXResult result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armVCM4P2_GetVLCBits (
+ const OMX_U8 **ppBitStream,
+ OMX_INT * pBitOffset,
+ OMX_S16 * pDst,
+ OMX_INT shortVideoHeader,
+ OMX_U8 start,
+ OMX_U8 * pLast,
+ OMX_U8 runBeginSingleLevelEntriesL0,
+ OMX_U8 maxIndexForMultipleEntriesL0,
+ OMX_U8 maxRunForMultipleEntriesL1,
+ OMX_U8 maxIndexForMultipleEntriesL1,
+ const OMX_U8 * pRunIndexTableL0,
+ const ARM_VLC32 *pVlcTableL0,
+ const OMX_U8 * pRunIndexTableL1,
+ const ARM_VLC32 *pVlcTableL1,
+ const OMX_U8 * pLMAXTableL0,
+ const OMX_U8 * pLMAXTableL1,
+ const OMX_U8 * pRMAXTableL0,
+ const OMX_U8 * pRMAXTableL1,
+ const OMX_U8 * pZigzagTable
+);
+
+/**
+ * Function: armVCM4P2_PutVLCBits
+ *
+ * Description:
+ * Checks the type of Escape Mode and put encoded bits for
+ * quantized DCT coefficients.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream pointer to the pointer to the current byte in
+ * the bit stream
+ * [in] pBitOffset pointer to the bit position in the byte pointed
+ * by *ppBitStream. Valid within 0 to 7
+ * [in] shortVideoHeader binary flag indicating presence of short_video_header; escape modes 0-3 are used if shortVideoHeader==0,
+ * and escape mode 4 is used when shortVideoHeader==1.
+ * [in] start start indicates whether the encoding begins with
+ * 0th element or 1st.
+ * [in] maxStoreRunL0 Max store possible (considering last and inter/intra)
+ * for last = 0
+ * [in] maxStoreRunL1 Max store possible (considering last and inter/intra)
+ * for last = 1
+ * [in] maxRunForMultipleEntriesL0
+ * The run value after which level
+ * will be equal to 1:
+ * (considering last and inter/intra status) for last = 0
+ * [in] maxRunForMultipleEntriesL1
+ * The run value after which level
+ * will be equal to 1:
+ * (considering last and inter/intra status) for last = 1
+ * [in] pRunIndexTableL0 Run Index table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 0
+ * [in] pVlcTableL0 VLC table for last == 0
+ * [in] pRunIndexTableL1 Run Index table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 1
+ * [in] pVlcTableL1 VLC table for last == 1
+ * [in] pLMAXTableL0 Level MAX table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 0
+ * [in] pLMAXTableL1 Level MAX table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 1
+ * [in] pRMAXTableL0 Run MAX table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 0
+ * [in] pRMAXTableL1 Run MAX table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 1
+ * [out] pQDctBlkCoef pointer to the quantized DCT coefficient
+ * [out] ppBitStream *ppBitStream is updated after the block is encoded
+ * so that it points to the current byte in the bit
+ * stream buffer.
+ * [out] pBitOffset *pBitOffset is updated so that it points to the
+ * current bit position in the byte pointed by
+ * *ppBitStream.
+ *
+ * Return Value:
+ * Standard OMXResult result. See enumeration for possible result codes.
+ *
+ */
+
+
+OMXResult armVCM4P2_PutVLCBits (
+ OMX_U8 **ppBitStream,
+ OMX_INT * pBitOffset,
+ const OMX_S16 *pQDctBlkCoef,
+ OMX_INT shortVideoHeader,
+ OMX_U8 start,
+ OMX_U8 maxStoreRunL0,
+ OMX_U8 maxStoreRunL1,
+ OMX_U8 maxRunForMultipleEntriesL0,
+ OMX_U8 maxRunForMultipleEntriesL1,
+ const OMX_U8 * pRunIndexTableL0,
+ const ARM_VLC32 *pVlcTableL0,
+ const OMX_U8 * pRunIndexTableL1,
+ const ARM_VLC32 *pVlcTableL1,
+ const OMX_U8 * pLMAXTableL0,
+ const OMX_U8 * pLMAXTableL1,
+ const OMX_U8 * pRMAXTableL0,
+ const OMX_U8 * pRMAXTableL1,
+ const OMX_U8 * pZigzagTable
+);
+/**
+ * Function: armVCM4P2_FillVLCBuffer
+ *
+ * Description:
+ * Performs calculating the VLC bits depending on the escape type and insert
+ * the same in the bitstream
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream pointer to the pointer to the current byte in
+ * the bit stream
+ * [in] pBitOffset pointer to the bit position in the byte pointed
+ * by *ppBitStream. Valid within 0 to 7
+ * [in] run Run value (count of zeros) to be encoded
+ * [in] level Level value (non-zero value) to be encoded
+ * [in] runPlus Calculated as runPlus = run - (RMAX + 1)
+ * [in] levelPlus Calculated as
+ * levelPlus = sign(level)*[abs(level) - LMAX]
+ * [in] fMode Flag indicating the escape modes
+ * [in] last status of the last flag
+ * [in] maxRunForMultipleEntries
+ * The run value after which level will be equal to 1:
+ * (considering last and inter/intra status)
+ * [in] pRunIndexTable Run Index table defined in
+ * armVCM4P2_Huff_tables_VLC.h
+ * [in] pVlcTable VLC table defined in armVCM4P2_Huff_tables_VLC.h
+ * [out] ppBitStream *ppBitStream is updated after the block is encoded
+ * so that it points to the current byte in the bit
+ * stream buffer.
+ * [out] pBitOffset *pBitOffset is updated so that it points to the
+ * current bit position in the byte pointed by
+ * *ppBitStream.
+ *
+ * Return Value:
+ * Standard OMXResult result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armVCM4P2_FillVLCBuffer (
+ OMX_U8 **ppBitStream,
+ OMX_INT * pBitOffset,
+ OMX_U32 run,
+ OMX_S16 level,
+ OMX_U32 runPlus,
+ OMX_S16 levelPlus,
+ OMX_U8 fMode,
+ OMX_U8 last,
+ OMX_U8 maxRunForMultipleEntries,
+ const OMX_U8 *pRunIndexTable,
+ const ARM_VLC32 *pVlcTable
+);
+
+/**
+ * Function: armVCM4P2_CheckVLCEscapeMode
+ *
+ * Description:
+ * Performs escape mode decision based on the run, run+, level, level+ and
+ * last combinations.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] run Run value (count of zeros) to be encoded
+ * [in] level Level value (non-zero value) to be encoded
+ * [in] runPlus Calculated as runPlus = run - (RMAX + 1)
+ * [in] levelPlus Calculated as
+ * levelPlus = sign(level)*[abs(level) - LMAX]
+ * [in] maxStoreRun Max store possible (considering last and inter/intra)
+ * [in] maxRunForMultipleEntries
+ * The run value after which level
+ * will be equal to 1:
+ * (considering last and inter/intra status)
+ * [in] shortVideoHeader binary flag indicating presence of short_video_header; escape modes 0-3 are used if shortVideoHeader==0,
+ * and escape mode 4 is used when shortVideoHeader==1.
+ * [in] pRunIndexTable Run Index table defined in
+ * armVCM4P2_Huff_Tables_VLC.c
+ * (considering last and inter/intra status)
+ *
+ *
+ * Return Value:
+ * Returns an Escape mode which can take values from 0 to 3
+ * 0 --> no escape mode, 1 --> escape type 1,
+ * 1 --> escape type 2, 3 --> escape type 3, check section 7.4.1.3
+ * in the MPEG ISO standard.
+ *
+ */
+
+OMX_U8 armVCM4P2_CheckVLCEscapeMode(
+ OMX_U32 run,
+ OMX_U32 runPlus,
+ OMX_S16 level,
+ OMX_S16 levelPlus,
+ OMX_U8 maxStoreRun,
+ OMX_U8 maxRunForMultipleEntries,
+ OMX_INT shortVideoHeader,
+ const OMX_U8 *pRunIndexTable
+);
+
+
+/**
+ * Function: armVCM4P2_BlockMatch_Integer
+ *
+ * Description:
+ * Performs a 16x16 block search; estimates motion vector and associated minimum SAD.
+ * Both the input and output motion vectors are represented using half-pixel units, and
+ * therefore a shift left or right by 1 bit may be required, respectively, to match the
+ * input or output MVs with other functions that either generate output MVs or expect
+ * input MVs represented using integer pixel units.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] pSrcRefBuf pointer to the reference Y plane; points to the reference MB that
+ * corresponds to the location of the current macroblock in the current
+ * plane.
+ * [in] refWidth width of the reference plane
+ * [in] pRefRect pointer to the valid rectangular in reference plane. Relative to image origin.
+ * It's not limited to the image boundary, but depended on the padding. For example,
+ * if you pad 4 pixels outside the image border, then the value for left border
+ * can be -4
+ * [in] pSrcCurrBuf pointer to the current macroblock extracted from original plane (linear array,
+ * 256 entries); must be aligned on an 8-byte boundary.
+ * [in] pCurrPointPos position of the current macroblock in the current plane
+ * [in] pSrcPreMV pointer to predicted motion vector; NULL indicates no predicted MV
+ * [in] pSrcPreSAD pointer to SAD associated with the predicted MV (referenced by pSrcPreMV)
+ * [in] searchRange search range for 16X16 integer block,the units of it is full pixel,the search range
+ * is the same in all directions.It is in inclusive of the boundary and specified in
+ * terms of integer pixel units.
+ * [in] pMESpec vendor-specific motion estimation specification structure; must have been allocated
+ * and then initialized using omxVCM4P2_MEInit prior to calling the block matching
+ * function.
+ * [in] BlockSize MacroBlock Size i.e either 16x16 or 8x8.
+ * [out] pDstMV pointer to estimated MV
+ * [out] pDstSAD pointer to minimum SAD
+ *
+ * Return Value:
+ * OMX_Sts_NoErr ¨C no error.
+ * OMX_Sts_BadArgErr ¨C bad arguments
+ *
+ */
+
+OMXResult armVCM4P2_BlockMatch_Integer(
+ const OMX_U8 *pSrcRefBuf,
+ OMX_INT refWidth,
+ const OMXRect *pRefRect,
+ const OMX_U8 *pSrcCurrBuf,
+ const OMXVCM4P2Coordinate *pCurrPointPos,
+ const OMXVCMotionVector *pSrcPreMV,
+ const OMX_INT *pSrcPreSAD,
+ void *pMESpec,
+ OMXVCMotionVector *pDstMV,
+ OMX_INT *pDstSAD,
+ OMX_U8 BlockSize
+);
+
+/**
+ * Function: armVCM4P2_BlockMatch_Half
+ *
+ * Description:
+ * Performs a 16x16 block match with half-pixel resolution. Returns the estimated
+ * motion vector and associated minimum SAD. This function estimates the half-pixel
+ * motion vector by interpolating the integer resolution motion vector referenced
+ * by the input parameter pSrcDstMV, i.e., the initial integer MV is generated
+ * externally. The input parameters pSrcRefBuf and pSearchPointRefPos should be
+ * shifted by the winning MV of 16x16 integer search prior to calling BlockMatch_Half_16x16.
+ * The function BlockMatch_Integer_16x16 may be used for integer motion estimation.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] pSrcRefBuf pointer to the reference Y plane; points to the reference MB
+ * that corresponds to the location of the current macroblock in
+ * the current plane.
+ * [in] refWidth width of the reference plane
+ * [in] pRefRect reference plane valid region rectangle
+ * [in] pSrcCurrBuf pointer to the current macroblock extracted from original plane
+ * (linear array, 256 entries); must be aligned on an 8-byte boundary.
+ * [in] pSearchPointRefPos position of the starting point for half pixel search (specified
+ * in terms of integer pixel units) in the reference plane.
+ * [in] rndVal rounding control bit for half pixel motion estimation;
+ * 0=rounding control disabled; 1=rounding control enabled
+ * [in] pSrcDstMV pointer to the initial MV estimate; typically generated during a prior
+ * 16X16 integer search and its unit is half pixel.
+ * [in] BlockSize MacroBlock Size i.e either 16x16 or 8x8.
+ * [out]pSrcDstMV pointer to estimated MV
+ * [out]pDstSAD pointer to minimum SAD
+ *
+ * Return Value:
+ * OMX_Sts_NoErr ¨C no error
+ * OMX_Sts_BadArgErr ¨C bad arguments
+ *
+ */
+
+OMXResult armVCM4P2_BlockMatch_Half(
+ const OMX_U8 *pSrcRefBuf,
+ OMX_INT refWidth,
+ const OMXRect *pRefRect,
+ const OMX_U8 *pSrcCurrBuf,
+ const OMXVCM4P2Coordinate *pSearchPointRefPos,
+ OMX_INT rndVal,
+ OMXVCMotionVector *pSrcDstMV,
+ OMX_INT *pDstSAD,
+ OMX_U8 BlockSize
+);
+/**
+ * Function: armVCM4P2_PadMV
+ *
+ * Description:
+ * Performs motion vector padding for a macroblock.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] pSrcDstMV pointer to motion vector buffer of the current
+ * macroblock
+ * [in] pTransp pointer to transparent status buffer of the
+ * current macroblock
+ * [out] pSrcDstMV pointer to motion vector buffer in which the
+ * motion vectors have been padded
+ * Return Value:
+ * Standard OMXResult result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armVCM4P2_PadMV(
+ OMXVCMotionVector * pSrcDstMV,
+ OMX_U8 * pTransp
+);
+
+/*
+ * H.264 Specific Declarations
+ */
+/* Defines */
+#define ARM_M4P10_Q_OFFSET (15)
+
+
+/* Dequant tables */
+
+extern const OMX_U8 armVCM4P10_PosToVCol4x4[16];
+extern const OMX_U8 armVCM4P10_PosToVCol2x2[4];
+extern const OMX_U8 armVCM4P10_VMatrix[6][3];
+extern const OMX_U32 armVCM4P10_MFMatrix[6][3];
+
+
+/*
+ * Description:
+ * This function perform the work required by the OpenMAX
+ * DecodeCoeffsToPair function and DecodeChromaDCCoeffsToPair.
+ * Since most of the code is common we share it here.
+ *
+ * Parameters:
+ * [in] ppBitStream Double pointer to current byte in bit stream buffer
+ * [in] pOffset Pointer to current bit position in the byte pointed
+ * to by *ppBitStream
+ * [in] sMaxNumCoeff Maximum number of non-zero coefficients in current
+ * block (4,15 or 16)
+ * [in] nTable Table number (0 to 4) according to the five columns
+ * of Table 9-5 in the H.264 spec
+ * [out] ppBitStream *ppBitStream is updated after each block is decoded
+ * [out] pOffset *pOffset is updated after each block is decoded
+ * [out] pNumCoeff Pointer to the number of nonzero coefficients in
+ * this block
+ * [out] ppPosCoefbuf Double pointer to destination residual
+ * coefficient-position pair buffer
+ * Return Value:
+ * Standard omxError result. See enumeration for possible result codes.
+
+ */
+
+OMXResult armVCM4P10_DecodeCoeffsToPair(
+ const OMX_U8** ppBitStream,
+ OMX_S32* pOffset,
+ OMX_U8* pNumCoeff,
+ OMX_U8**ppPosCoefbuf,
+ OMX_INT nTable,
+ OMX_INT sMaxNumCoeff
+ );
+
+/*
+ * Description:
+ * Perform DC style intra prediction, averaging upper and left block
+ *
+ * Parameters:
+ * [in] pSrcLeft Pointer to the buffer of 16 left coefficients:
+ * p[x, y] (x = -1, y = 0..3)
+ * [in] pSrcAbove Pointer to the buffer of 16 above coefficients:
+ * p[x,y] (x = 0..3, y = -1)
+ * [in] leftStep Step of left coefficient buffer
+ * [in] dstStep Step of the destination buffer
+ * [in] availability Neighboring 16x16 MB availability flag
+ * [out] pDst Pointer to the destination buffer
+ *
+ * Return Value:
+ * None
+ */
+
+void armVCM4P10_PredictIntraDC4x4(
+ const OMX_U8* pSrcLeft,
+ const OMX_U8 *pSrcAbove,
+ OMX_U8* pDst,
+ OMX_INT leftStep,
+ OMX_INT dstStep,
+ OMX_S32 availability
+);
+
+/*
+ * Description
+ * Unpack a 4x4 block of coefficient-residual pair values
+ *
+ * Parameters:
+ * [in] ppSrc Double pointer to residual coefficient-position pair
+ * buffer output by CALVC decoding
+ * [out] ppSrc *ppSrc is updated to the start of next non empty block
+ * [out] pDst Pointer to unpacked 4x4 block
+ */
+
+void armVCM4P10_UnpackBlock4x4(
+ const OMX_U8 **ppSrc,
+ OMX_S16* pDst
+);
+
+/*
+ * Description
+ * Unpack a 2x2 block of coefficient-residual pair values
+ *
+ * Parameters:
+ * [in] ppSrc Double pointer to residual coefficient-position pair
+ * buffer output by CALVC decoding
+ * [out] ppSrc *ppSrc is updated to the start of next non empty block
+ * [out] pDst Pointer to unpacked 4x4 block
+ */
+
+void armVCM4P10_UnpackBlock2x2(
+ const OMX_U8 **ppSrc,
+ OMX_S16* pDst
+);
+
+/*
+ * Description
+ * Deblock one boundary pixel
+ *
+ * Parameters:
+ * [in] pQ0 Pointer to pixel q0
+ * [in] Step Step between pixels q0 and q1
+ * [in] tC0 Edge threshold value
+ * [in] alpha alpha threshold value
+ * [in] beta beta threshold value
+ * [in] bS deblocking strength
+ * [in] ChromaFlag True for chroma blocks
+ * [out] pQ0 Deblocked pixels
+ *
+ */
+
+void armVCM4P10_DeBlockPixel(
+ OMX_U8 *pQ0, /* pointer to the pixel q0 */
+ int Step, /* step between pixels q0 and q1 */
+ int tC0, /* edge threshold value */
+ int alpha, /* alpha */
+ int beta, /* beta */
+ int bS, /* deblocking strength */
+ int ChromaFlag
+);
+
+/**
+ * Function: armVCM4P10_InterpolateHalfHor_Luma
+ *
+ * Description:
+ * This function performs interpolation for horizontal 1/2-pel positions
+ *
+ * Remarks:
+ *
+ * [in] pSrc Pointer to top-left corner of block used to interpolate
+ in the reconstructed frame plane
+ * [in] iSrcStep Step of the source buffer.
+ * [in] iDstStep Step of the destination(interpolation) buffer.
+ * [in] iWidth Width of the current block
+ * [in] iHeight Height of the current block
+ * [out] pDst Pointer to the interpolation buffer of the 1/2-pel
+ *
+ * Return Value:
+ * Standard OMXResult value.
+ *
+ */
+
+OMXResult armVCM4P10_InterpolateHalfHor_Luma(
+ const OMX_U8* pSrc,
+ OMX_U32 iSrcStep,
+ OMX_U8* pDst,
+ OMX_U32 iDstStep,
+ OMX_U32 iWidth,
+ OMX_U32 iHeight
+);
+
+/**
+ * Function: armVCM4P10_InterpolateHalfVer_Luma
+ *
+ * Description:
+ * This function performs interpolation for vertical 1/2-pel positions
+ * around a full-pel position.
+ *
+ * Remarks:
+ *
+ * [in] pSrc Pointer to top-left corner of block used to interpolate
+ * in the reconstructed frame plane
+ * [in] iSrcStep Step of the source buffer.
+ * [in] iDstStep Step of the destination(interpolation) buffer.
+ * [in] iWidth Width of the current block
+ * [in] iHeight Height of the current block
+ * [out] pDst Pointer to the interpolation buffer of the 1/2-pel
+ *
+ * Return Value:
+ * Standard OMXResult value.
+ *
+ */
+
+OMXResult armVCM4P10_InterpolateHalfVer_Luma(
+ const OMX_U8* pSrc,
+ OMX_U32 iSrcStep,
+ OMX_U8* pDst,
+ OMX_U32 iDstStep,
+ OMX_U32 iWidth,
+ OMX_U32 iHeight
+);
+
+/**
+ * Function: armVCM4P10_InterpolateHalfDiag_Luma
+ *
+ * Description:
+ * This function performs interpolation for (1/2, 1/2) positions
+ * around a full-pel position.
+ *
+ * Remarks:
+ *
+ * [in] pSrc Pointer to top-left corner of block used to interpolate
+ * in the reconstructed frame plane
+ * [in] iSrcStep Step of the source buffer.
+ * [in] iDstStep Step of the destination(interpolation) buffer.
+ * [in] iWidth Width of the current block
+ * [in] iHeight Height of the current block
+ * [out] pDst Pointer to the interpolation buffer of the (1/2,1/2)-pel
+ *
+ * Return Value:
+ * Standard OMXResult value.
+ *
+ */
+
+OMXResult armVCM4P10_InterpolateHalfDiag_Luma(
+ const OMX_U8* pSrc,
+ OMX_U32 iSrcStep,
+ OMX_U8* pDst,
+ OMX_U32 iDstStep,
+ OMX_U32 iWidth,
+ OMX_U32 iHeight
+);
+
+/*
+ * Description:
+ * Transform Residual 4x4 Coefficients
+ *
+ * Parameters:
+ * [in] pSrc Source 4x4 block
+ * [out] pDst Destination 4x4 block
+ *
+ */
+
+void armVCM4P10_TransformResidual4x4(OMX_S16* pDst, OMX_S16 *pSrc);
+
+/*
+ * Description:
+ * Forward Transform Residual 4x4 Coefficients
+ *
+ * Parameters:
+ * [in] pSrc Source 4x4 block
+ * [out] pDst Destination 4x4 block
+ *
+ */
+
+void armVCM4P10_FwdTransformResidual4x4(OMX_S16* pDst, OMX_S16 *pSrc);
+
+OMX_INT armVCM4P10_CompareMotionCostToMV (
+ OMX_S16 mvX,
+ OMX_S16 mvY,
+ OMXVCMotionVector diffMV,
+ OMX_INT candSAD,
+ OMXVCMotionVector *bestMV,
+ OMX_U32 nLamda,
+ OMX_S32 *pBestCost);
+
+/**
+ * Function: armVCCOMM_SAD
+ *
+ * Description:
+ * This function calculate the SAD for NxM blocks.
+ *
+ * Remarks:
+ *
+ * [in] pSrcOrg Pointer to the original block
+ * [in] iStepOrg Step of the original block buffer
+ * [in] pSrcRef Pointer to the reference block
+ * [in] iStepRef Step of the reference block buffer
+ * [in] iHeight Height of the block
+ * [in] iWidth Width of the block
+ * [out] pDstSAD Pointer of result SAD
+ *
+ * Return Value:
+ * Standard OMXResult value.
+ *
+ */
+OMXResult armVCCOMM_SAD(
+ const OMX_U8* pSrcOrg,
+ OMX_U32 iStepOrg,
+ const OMX_U8* pSrcRef,
+ OMX_U32 iStepRef,
+ OMX_S32* pDstSAD,
+ OMX_U32 iHeight,
+ OMX_U32 iWidth);
+
+/**
+ * Function: armVCCOMM_Average
+ *
+ * Description:
+ * This function calculates the average of two blocks and stores the result.
+ *
+ * Remarks:
+ *
+ * [in] pPred0 Pointer to the top-left corner of reference block 0
+ * [in] pPred1 Pointer to the top-left corner of reference block 1
+ * [in] iPredStep0 Step of reference block 0
+ * [in] iPredStep1 Step of reference block 1
+ * [in] iDstStep Step of the destination buffer
+ * [in] iWidth Width of the blocks
+ * [in] iHeight Height of the blocks
+ * [out] pDstPred Pointer to the destination buffer
+ *
+ * Return Value:
+ * Standard OMXResult value.
+ *
+ */
+ OMXResult armVCCOMM_Average (
+ const OMX_U8* pPred0,
+ const OMX_U8* pPred1,
+ OMX_U32 iPredStep0,
+ OMX_U32 iPredStep1,
+ OMX_U8* pDstPred,
+ OMX_U32 iDstStep,
+ OMX_U32 iWidth,
+ OMX_U32 iHeight
+);
+
+/**
+ * Function: armVCM4P10_SADQuar
+ *
+ * Description:
+ * This function calculates the SAD between one block (pSrc) and the
+ * average of the other two (pSrcRef0 and pSrcRef1)
+ *
+ * Remarks:
+ *
+ * [in] pSrc Pointer to the original block
+ * [in] pSrcRef0 Pointer to reference block 0
+ * [in] pSrcRef1 Pointer to reference block 1
+ * [in] iSrcStep Step of the original block buffer
+ * [in] iRefStep0 Step of reference block 0
+ * [in] iRefStep1 Step of reference block 1
+ * [in] iHeight Height of the block
+ * [in] iWidth Width of the block
+ * [out] pDstSAD Pointer of result SAD
+ *
+ * Return Value:
+ * Standard OMXResult value.
+ *
+ */
+OMXResult armVCM4P10_SADQuar(
+ const OMX_U8* pSrc,
+ const OMX_U8* pSrcRef0,
+ const OMX_U8* pSrcRef1,
+ OMX_U32 iSrcStep,
+ OMX_U32 iRefStep0,
+ OMX_U32 iRefStep1,
+ OMX_U32* pDstSAD,
+ OMX_U32 iHeight,
+ OMX_U32 iWidth
+);
+
+/**
+ * Function: armVCM4P10_Interpolate_Chroma
+ *
+ * Description:
+ * This function performs interpolation for chroma components.
+ *
+ * Remarks:
+ *
+ * [in] pSrc Pointer to top-left corner of block used to
+ * interpolate in the reconstructed frame plane
+ * [in] iSrcStep Step of the source buffer.
+ * [in] iDstStep Step of the destination(interpolation) buffer.
+ * [in] iWidth Width of the current block
+ * [in] iHeight Height of the current block
+ * [in] dx Fractional part of horizontal motion vector
+ * component in 1/8 pixel unit (0~7)
+ * [in] dy Fractional part of vertical motion vector
+ * component in 1/8 pixel unit (0~7)
+ * [out] pDst Pointer to the interpolation buffer
+ *
+ * Return Value:
+ * Standard OMXResult value.
+ *
+ */
+ OMXResult armVCM4P10_Interpolate_Chroma(
+ OMX_U8 *pSrc,
+ OMX_U32 iSrcStep,
+ OMX_U8 *pDst,
+ OMX_U32 iDstStep,
+ OMX_U32 iWidth,
+ OMX_U32 iHeight,
+ OMX_U32 dx,
+ OMX_U32 dy
+);
+
+/**
+ * Function: armVCM4P10_Interpolate_Luma
+ *
+ * Description:
+ * This function performs interpolation for luma components.
+ *
+ * Remarks:
+ *
+ * [in] pSrc Pointer to top-left corner of block used to
+ * interpolate in the reconstructed frame plane
+ * [in] iSrcStep Step of the source buffer.
+ * [in] iDstStep Step of the destination(interpolation) buffer.
+ * [in] iWidth Width of the current block
+ * [in] iHeight Height of the current block
+ * [in] dx Fractional part of horizontal motion vector
+ * component in 1/4 pixel unit (0~3)
+ * [in] dy Fractional part of vertical motion vector
+ * component in 1/4 pixel unit (0~3)
+ * [out] pDst Pointer to the interpolation buffer
+ *
+ * Return Value:
+ * Standard OMXResult value.
+ *
+ */
+
+ OMXResult armVCM4P10_Interpolate_Luma(
+ const OMX_U8 *pSrc,
+ OMX_U32 iSrcStep,
+ OMX_U8 *pDst,
+ OMX_U32 iDstStep,
+ OMX_U32 iWidth,
+ OMX_U32 iHeight,
+ OMX_U32 dx,
+ OMX_U32 dy
+);
+
+/**
+ * Function: omxVCH264_DequantTransformACFromPair_U8_S16_C1_DLx
+ *
+ * Description:
+ * Reconstruct the 4x4 residual block from coefficient-position pair buffer,
+ * perform dequantisation and integer inverse transformation for 4x4 block of
+ * residuals and update the pair buffer pointer to next non-empty block.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppSrc Double pointer to residual coefficient-position
+ * pair buffer output by CALVC decoding
+ * [in] pDC Pointer to the DC coefficient of this block, NULL
+ * if it doesn't exist
+ * [in] QP Quantization parameter
+ * [in] AC Flag indicating if at least one non-zero coefficient exists
+ * [out] pDst pointer to the reconstructed 4x4 block data
+ *
+ * Return Value:
+ * Standard omxError result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armVCM4P10_DequantTransformACFromPair_U8_S16_C1_DLx(
+ OMX_U8 **ppSrc,
+ OMX_S16 *pDst,
+ OMX_INT QP,
+ OMX_S16* pDC,
+ int AC
+);
+
+#endif /*_armVideo_H_*/
+
+/*End of File*/
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/api/omxVC.h b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/api/omxVC.h
new file mode 100644
index 0000000..7b3cc72
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/api/omxVC.h
@@ -0,0 +1,4381 @@
+/**
+ * File: omxVC.h
+ * Brief: OpenMAX DL v1.0.2 - Video Coding library
+ *
+ * Copyright © 2005-2008 The Khronos Group Inc. All Rights Reserved.
+ *
+ * These materials are protected by copyright laws and contain material
+ * proprietary to the Khronos Group, Inc. You may use these materials
+ * for implementing Khronos specifications, without altering or removing
+ * any trademark, copyright or other notice from the specification.
+ *
+ * Khronos Group makes no, and expressly disclaims any, representations
+ * or warranties, express or implied, regarding these materials, including,
+ * without limitation, any implied warranties of merchantability or fitness
+ * for a particular purpose or non-infringement of any intellectual property.
+ * Khronos Group makes no, and expressly disclaims any, warranties, express
+ * or implied, regarding the correctness, accuracy, completeness, timeliness,
+ * and reliability of these materials.
+ *
+ * Under no circumstances will the Khronos Group, or any of its Promoters,
+ * Contributors or Members or their respective partners, officers, directors,
+ * employees, agents or representatives be liable for any damages, whether
+ * direct, indirect, special or consequential damages for lost revenues,
+ * lost profits, or otherwise, arising from or in connection with these
+ * materials.
+ *
+ * Khronos and OpenMAX are trademarks of the Khronos Group Inc.
+ *
+ */
+
+/* *****************************************************************************************/
+
+#ifndef _OMXVC_H_
+#define _OMXVC_H_
+
+#include "omxtypes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* 6.1.1.1 Motion Vectors */
+/* In omxVC, motion vectors are represented as follows: */
+
+typedef struct {
+ OMX_S16 dx;
+ OMX_S16 dy;
+} OMXVCMotionVector;
+
+
+
+/**
+ * Function: omxVCCOMM_Average_8x (6.1.3.1.1)
+ *
+ * Description:
+ * This function calculates the average of two 8x4, 8x8, or 8x16 blocks. The
+ * result is rounded according to (a+b+1)/2. The block average function can
+ * be used in conjunction with half-pixel interpolation to obtain quarter
+ * pixel motion estimates, as described in [ISO14496-10], subclause 8.4.2.2.1.
+ *
+ * Input Arguments:
+ *
+ * pPred0 - Pointer to the top-left corner of reference block 0
+ * pPred1 - Pointer to the top-left corner of reference block 1
+ * iPredStep0 - Step of reference block 0
+ * iPredStep1 - Step of reference block 1
+ * iDstStep - Step of the destination buffer.
+ * iHeight - Height of the blocks
+ *
+ * Output Arguments:
+ *
+ * pDstPred - Pointer to the destination buffer. 8-byte aligned.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned under any of the following
+ * conditions:
+ * - one or more of the following pointers is NULL: pPred0, pPred1, or
+ * pDstPred.
+ * - pDstPred is not aligned on an 8-byte boundary.
+ * - iPredStep0 <= 0 or iPredStep0 is not a multiple of 8.
+ * - iPredStep1 <= 0 or iPredStep1 is not a multiple of 8.
+ * - iDstStep <= 0 or iDstStep is not a multiple of 8.
+ * - iHeight is not 4, 8, or 16.
+ *
+ */
+OMXResult omxVCCOMM_Average_8x (
+ const OMX_U8 *pPred0,
+ const OMX_U8 *pPred1,
+ OMX_U32 iPredStep0,
+ OMX_U32 iPredStep1,
+ OMX_U8 *pDstPred,
+ OMX_U32 iDstStep,
+ OMX_U32 iHeight
+);
+
+
+
+/**
+ * Function: omxVCCOMM_Average_16x (6.1.3.1.2)
+ *
+ * Description:
+ * This function calculates the average of two 16x16 or 16x8 blocks. The
+ * result is rounded according to (a+b+1)/2. The block average function can
+ * be used in conjunction with half-pixel interpolation to obtain quarter
+ * pixel motion estimates, as described in [ISO14496-10], subclause 8.4.2.2.1.
+ *
+ * Input Arguments:
+ *
+ * pPred0 - Pointer to the top-left corner of reference block 0
+ * pPred1 - Pointer to the top-left corner of reference block 1
+ * iPredStep0 - Step of reference block 0
+ * iPredStep1 - Step of reference block 1
+ * iDstStep - Step of the destination buffer
+ * iHeight - Height of the blocks
+ *
+ * Output Arguments:
+ *
+ * pDstPred - Pointer to the destination buffer. 16-byte aligned.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned under any of the following
+ * conditions:
+ * - one or more of the following pointers is NULL: pPred0, pPred1, or
+ * pDstPred.
+ * - pDstPred is not aligned on a 16-byte boundary.
+ * - iPredStep0 <= 0 or iPredStep0 is not a multiple of 16.
+ * - iPredStep1 <= 0 or iPredStep1 is not a multiple of 16.
+ * - iDstStep <= 0 or iDstStep is not a multiple of 16.
+ * - iHeight is not 8 or 16.
+ *
+ */
+OMXResult omxVCCOMM_Average_16x (
+ const OMX_U8 *pPred0,
+ const OMX_U8 *pPred1,
+ OMX_U32 iPredStep0,
+ OMX_U32 iPredStep1,
+ OMX_U8 *pDstPred,
+ OMX_U32 iDstStep,
+ OMX_U32 iHeight
+);
+
+
+
+/**
+ * Function: omxVCCOMM_ExpandFrame_I (6.1.3.2.1)
+ *
+ * Description:
+ * This function expands a reconstructed frame in-place. The unexpanded
+ * source frame should be stored in a plane buffer with sufficient space
+ * pre-allocated for edge expansion, and the input frame should be located in
+ * the plane buffer center. This function executes the pixel expansion by
+ * replicating source frame edge pixel intensities in the empty pixel
+ * locations (expansion region) between the source frame edge and the plane
+ * buffer edge. The width/height of the expansion regions on the
+ * horizontal/vertical edges is controlled by the parameter iExpandPels.
+ *
+ * Input Arguments:
+ *
+ * pSrcDstPlane - pointer to the top-left corner of the frame to be
+ * expanded; must be aligned on an 8-byte boundary.
+ * iFrameWidth - frame width; must be a multiple of 8.
+ * iFrameHeight -frame height; must be a multiple of 8.
+ * iExpandPels - number of pixels to be expanded in the horizontal and
+ * vertical directions; must be a multiple of 8.
+ * iPlaneStep - distance, in bytes, between the start of consecutive lines
+ * in the plane buffer; must be larger than or equal to
+ * (iFrameWidth + 2 * iExpandPels).
+ *
+ * Output Arguments:
+ *
+ * pSrcDstPlane -Pointer to the top-left corner of the frame (NOT the
+ * top-left corner of the plane); must be aligned on an 8-byte
+ * boundary.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned under any of the following
+ * conditions:
+ * - pSrcDstPlane is NULL.
+ * - pSrcDstPlane is not aligned on an 8-byte boundary.
+ * - one of the following parameters is either equal to zero or is a
+ * non-multiple of 8: iFrameHeight, iFrameWidth, iPlaneStep, or
+ * iExpandPels.
+ * - iPlaneStep < (iFrameWidth + 2 * iExpandPels).
+ *
+ */
+OMXResult omxVCCOMM_ExpandFrame_I (
+ OMX_U8 *pSrcDstPlane,
+ OMX_U32 iFrameWidth,
+ OMX_U32 iFrameHeight,
+ OMX_U32 iExpandPels,
+ OMX_U32 iPlaneStep
+);
+
+
+
+/**
+ * Function: omxVCCOMM_Copy8x8 (6.1.3.3.1)
+ *
+ * Description:
+ * Copies the reference 8x8 block to the current block.
+ *
+ * Input Arguments:
+ *
+ * pSrc - pointer to the reference block in the source frame; must be
+ * aligned on an 8-byte boundary.
+ * step - distance between the starts of consecutive lines in the reference
+ * frame, in bytes; must be a multiple of 8 and must be larger than
+ * or equal to 8.
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the destination block; must be aligned on an 8-byte
+ * boundary.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned under any of the following
+ * conditions:
+ * - one or more of the following pointers is NULL: pSrc, pDst
+ * - one or more of the following pointers is not aligned on an 8-byte
+ * boundary: pSrc, pDst
+ * - step <8 or step is not a multiple of 8.
+ *
+ */
+OMXResult omxVCCOMM_Copy8x8 (
+ const OMX_U8 *pSrc,
+ OMX_U8 *pDst,
+ OMX_INT step
+);
+
+
+
+/**
+ * Function: omxVCCOMM_Copy16x16 (6.1.3.3.2)
+ *
+ * Description:
+ * Copies the reference 16x16 macroblock to the current macroblock.
+ *
+ * Input Arguments:
+ *
+ * pSrc - pointer to the reference macroblock in the source frame; must be
+ * aligned on a 16-byte boundary.
+ * step - distance between the starts of consecutive lines in the reference
+ * frame, in bytes; must be a multiple of 16 and must be larger
+ * than or equal to 16.
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the destination macroblock; must be aligned on a
+ * 16-byte boundary.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned under any of the following
+ * conditions:
+ * - one or more of the following pointers is NULL: pSrc, pDst
+ * - one or more of the following pointers is not aligned on a 16-byte
+ * boundary: pSrc, pDst
+ * - step <16 or step is not a multiple of 16.
+ *
+ */
+OMXResult omxVCCOMM_Copy16x16 (
+ const OMX_U8 *pSrc,
+ OMX_U8 *pDst,
+ OMX_INT step
+);
+
+
+
+/**
+ * Function: omxVCCOMM_ComputeTextureErrorBlock_SAD (6.1.4.1.1)
+ *
+ * Description:
+ * Computes texture error of the block; also returns SAD.
+ *
+ * Input Arguments:
+ *
+ * pSrc - pointer to the source plane; must be aligned on an 8-byte
+ * boundary.
+ * srcStep - step of the source plane
+ * pSrcRef - pointer to the reference buffer, an 8x8 block; must be aligned
+ * on an 8-byte boundary.
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the destination buffer, an 8x8 block; must be aligned
+ * on an 8-byte boundary.
+ * pDstSAD - pointer to the Sum of Absolute Differences (SAD) value
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments
+ * - At least one of the following
+ * pointers is NULL: pSrc, pSrcRef, pDst and pDstSAD.
+ * - pSrc is not 8-byte aligned.
+ * - SrcStep <= 0 or srcStep is not a multiple of 8.
+ * - pSrcRef is not 8-byte aligned.
+ * - pDst is not 8-byte aligned.
+ *
+ */
+OMXResult omxVCCOMM_ComputeTextureErrorBlock_SAD (
+ const OMX_U8 *pSrc,
+ OMX_INT srcStep,
+ const OMX_U8 *pSrcRef,
+ OMX_S16 *pDst,
+ OMX_INT *pDstSAD
+);
+
+
+
+/**
+ * Function: omxVCCOMM_ComputeTextureErrorBlock (6.1.4.1.2)
+ *
+ * Description:
+ * Computes the texture error of the block.
+ *
+ * Input Arguments:
+ *
+ * pSrc - pointer to the source plane. This should be aligned on an 8-byte
+ * boundary.
+ * srcStep - step of the source plane
+ * pSrcRef - pointer to the reference buffer, an 8x8 block. This should be
+ * aligned on an 8-byte boundary.
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the destination buffer, an 8x8 block. This should be
+ * aligned on an 8-byte boundary.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments:
+ * - At least one of the following pointers is NULL:
+ * pSrc, pSrcRef, pDst.
+ * - pSrc is not 8-byte aligned.
+ * - SrcStep <= 0 or srcStep is not a multiple of 8.
+ * - pSrcRef is not 8-byte aligned.
+ * - pDst is not 8-byte aligned
+ *
+ */
+OMXResult omxVCCOMM_ComputeTextureErrorBlock (
+ const OMX_U8 *pSrc,
+ OMX_INT srcStep,
+ const OMX_U8 *pSrcRef,
+ OMX_S16 *pDst
+);
+
+
+
+/**
+ * Function: omxVCCOMM_LimitMVToRect (6.1.4.1.3)
+ *
+ * Description:
+ * Limits the motion vector associated with the current block/macroblock to
+ * prevent the motion compensated block/macroblock from moving outside a
+ * bounding rectangle as shown in Figure 6-1.
+ *
+ * Input Arguments:
+ *
+ * pSrcMV - pointer to the motion vector associated with the current block
+ * or macroblock
+ * pRectVOPRef - pointer to the bounding rectangle
+ * Xcoord, Ycoord - coordinates of the current block or macroblock
+ * size - size of the current block or macroblock; must be equal to 8 or
+ * 16.
+ *
+ * Output Arguments:
+ *
+ * pDstMV - pointer to the limited motion vector
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments. Returned if one or more of the
+ * following conditions is true:
+ * - at least one of the following pointers is NULL:
+ * pSrcMV, pDstMV, or pRectVOPRef.
+ * - size is not equal to either 8 or 16.
+ * - the width or height of the bounding rectangle is less than
+ * twice the block size.
+ */
+OMXResult omxVCCOMM_LimitMVToRect (
+ const OMXVCMotionVector *pSrcMV,
+ OMXVCMotionVector *pDstMV,
+ const OMXRect *pRectVOPRef,
+ OMX_INT Xcoord,
+ OMX_INT Ycoord,
+ OMX_INT size
+);
+
+
+
+/**
+ * Function: omxVCCOMM_SAD_16x (6.1.4.1.4)
+ *
+ * Description:
+ * This function calculates the SAD for 16x16 and 16x8 blocks.
+ *
+ * Input Arguments:
+ *
+ * pSrcOrg - Pointer to the original block; must be aligned on a 16-byte
+ * boundary.
+ * iStepOrg - Step of the original block buffer
+ * pSrcRef - Pointer to the reference block
+ * iStepRef - Step of the reference block buffer
+ * iHeight - Height of the block
+ *
+ * Output Arguments:
+ *
+ * pDstSAD - Pointer of result SAD
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments. Returned if one or more of the
+ * following conditions is true:
+ * - at least one of the following pointers is NULL:
+ * pSrcOrg, pDstSAD, or pSrcRef
+ * - pSrcOrg is not 16-byte aligned.
+ * - iStepOrg <= 0 or iStepOrg is not a multiple of 16
+ * - iStepRef <= 0 or iStepRef is not a multiple of 16
+ * - iHeight is not 8 or 16
+ *
+ */
+OMXResult omxVCCOMM_SAD_16x (
+ const OMX_U8 *pSrcOrg,
+ OMX_U32 iStepOrg,
+ const OMX_U8 *pSrcRef,
+ OMX_U32 iStepRef,
+ OMX_S32 *pDstSAD,
+ OMX_U32 iHeight
+);
+
+
+
+/**
+ * Function: omxVCCOMM_SAD_8x (6.1.4.1.5)
+ *
+ * Description:
+ * This function calculates the SAD for 8x16, 8x8, 8x4 blocks.
+ *
+ * Input Arguments:
+ *
+ * pSrcOrg - Pointer to the original block; must be aligned on a 8-byte
+ * boundary.
+ * iStepOrg - Step of the original block buffer
+ * pSrcRef - Pointer to the reference block
+ * iStepRef - Step of the reference block buffer
+ * iHeight - Height of the block
+ *
+ * Output Arguments:
+ *
+ * pDstSAD -Pointer of result SAD
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments. Returned if one or more of the
+ * following conditions is true:
+ * - at least one of the following pointers is NULL:
+ * pSrcOrg, pDstSAD, or pSrcRef
+ * - pSrcOrg is not 8-byte aligned.
+ * - iStepOrg <= 0 or iStepOrg is not a multiple of 8
+ * - iStepRef <= 0 or iStepRef is not a multiple of 8
+ * - iHeight is not 4, 8 or 16
+ *
+ */
+OMXResult omxVCCOMM_SAD_8x (
+ const OMX_U8 *pSrcOrg,
+ OMX_U32 iStepOrg,
+ const OMX_U8 *pSrcRef,
+ OMX_U32 iStepRef,
+ OMX_S32*pDstSAD,
+ OMX_U32 iHeight
+);
+
+
+
+/* 6.2.1.1 Direction */
+/* The direction enumerator is used with functions that perform AC/DC prediction and zig-zag scan. */
+
+enum {
+ OMX_VC_NONE = 0,
+ OMX_VC_HORIZONTAL = 1,
+ OMX_VC_VERTICAL = 2
+};
+
+
+
+/* 6.2.1.2 Bilinear Interpolation */
+/* The bilinear interpolation enumerator is used with motion estimation, motion compensation, and reconstruction functions. */
+
+enum {
+ OMX_VC_INTEGER_PIXEL = 0, /* case a */
+ OMX_VC_HALF_PIXEL_X = 1, /* case b */
+ OMX_VC_HALF_PIXEL_Y = 2, /* case c */
+ OMX_VC_HALF_PIXEL_XY = 3 /* case d */
+};
+
+
+
+/* 6.2.1.3 Neighboring Macroblock Availability */
+/* Neighboring macroblock availability is indicated using the following flags: */
+
+enum {
+ OMX_VC_UPPER = 1, /** above macroblock is available */
+ OMX_VC_LEFT = 2, /** left macroblock is available */
+ OMX_VC_CENTER = 4,
+ OMX_VC_RIGHT = 8,
+ OMX_VC_LOWER = 16,
+ OMX_VC_UPPER_LEFT = 32, /** above-left macroblock is available */
+ OMX_VC_UPPER_RIGHT = 64, /** above-right macroblock is available */
+ OMX_VC_LOWER_LEFT = 128,
+ OMX_VC_LOWER_RIGHT = 256
+};
+
+
+
+/* 6.2.1.4 Video Components */
+/* A data type that enumerates video components is defined as follows: */
+
+typedef enum {
+ OMX_VC_LUMINANCE, /** Luminance component */
+ OMX_VC_CHROMINANCE /** chrominance component */
+} OMXVCM4P2VideoComponent;
+
+
+
+/* 6.2.1.5 MacroblockTypes */
+/* A data type that enumerates macroblock types is defined as follows: */
+
+typedef enum {
+ OMX_VC_INTER = 0, /** P picture or P-VOP */
+ OMX_VC_INTER_Q = 1, /** P picture or P-VOP */
+ OMX_VC_INTER4V = 2, /** P picture or P-VOP */
+ OMX_VC_INTRA = 3, /** I and P picture, I- and P-VOP */
+ OMX_VC_INTRA_Q = 4, /** I and P picture, I- and P-VOP */
+ OMX_VC_INTER4V_Q = 5 /** P picture or P-VOP (H.263)*/
+} OMXVCM4P2MacroblockType;
+
+
+
+/* 6.2.1.6 Coordinates */
+/* Coordinates are represented as follows: */
+
+typedef struct {
+ OMX_INT x;
+ OMX_INT y;
+} OMXVCM4P2Coordinate;
+
+
+
+/* 6.2.1.7 Motion Estimation Algorithms */
+/* A data type that enumerates motion estimation search methods is defined as follows: */
+
+typedef enum {
+ OMX_VC_M4P2_FAST_SEARCH = 0, /** Fast motion search */
+ OMX_VC_M4P2_FULL_SEARCH = 1 /** Full motion search */
+} OMXVCM4P2MEMode;
+
+
+
+/* 6.2.1.8 Motion Estimation Parameters */
+/* A data structure containing control parameters for
+ * motion estimation functions is defined as follows:
+ */
+
+typedef struct {
+ OMX_INT searchEnable8x8; /** enables 8x8 search */
+ OMX_INT halfPelSearchEnable; /** enables half-pel resolution */
+ OMX_INT searchRange; /** search range */
+ OMX_INT rndVal; /** rounding control; 0-disabled, 1-enabled*/
+} OMXVCM4P2MEParams;
+
+
+
+/* 6.2.1.9 Macroblock Information */
+/* A data structure containing macroblock parameters for
+ * motion estimation functions is defined as follows:
+ */
+
+typedef struct {
+ OMX_S32 sliceId; /* slice number */
+ OMXVCM4P2MacroblockType mbType; /* MB type: OMX_VC_INTRA, OMX_VC_INTER, or OMX_VC_INTER4 */
+ OMX_S32 qp; /* quantization parameter*/
+ OMX_U32 cbpy; /* CBP Luma */
+ OMX_U32 cbpc; /* CBP Chroma */
+ OMXVCMotionVector pMV0[2][2]; /* motion vector, represented using 1/2-pel units,
+ * pMV0[blocky][blockx] (blocky = 0~1, blockx =0~1)
+ */
+ OMXVCMotionVector pMVPred[2][2]; /* motion vector prediction, represented using 1/2-pel units,
+ * pMVPred[blocky][blockx] (blocky = 0~1, blockx = 0~1)
+ */
+ OMX_U8 pPredDir[2][2]; /* AC prediction direction:
+ * OMX_VC_NONE, OMX_VC_VERTICAL, OMX_VC_HORIZONTAL
+ */
+} OMXVCM4P2MBInfo, *OMXVCM4P2MBInfoPtr;
+
+
+
+/**
+ * Function: omxVCM4P2_FindMVpred (6.2.3.1.1)
+ *
+ * Description:
+ * Predicts a motion vector for the current block using the procedure
+ * specified in [ISO14496-2], subclause 7.6.5. The resulting predicted MV is
+ * returned in pDstMVPred. If the parameter pDstMVPredME if is not NULL then
+ * the set of three MV candidates used for prediction is also returned,
+ * otherwise pDstMVPredMEis NULL upon return.
+ *
+ * Input Arguments:
+ *
+ * pSrcMVCurMB - pointer to the MV buffer associated with the current Y
+ * macroblock; a value of NULL indicates unavailability.
+ * pSrcCandMV1 - pointer to the MV buffer containing the 4 MVs associated
+ * with the MB located to the left of the current MB; set to NULL
+ * if there is no MB to the left.
+ * pSrcCandMV2 - pointer to the MV buffer containing the 4 MVs associated
+ * with the MB located above the current MB; set to NULL if there
+ * is no MB located above the current MB.
+ * pSrcCandMV3 - pointer to the MV buffer containing the 4 MVs associated
+ * with the MB located to the right and above the current MB; set
+ * to NULL if there is no MB located to the above-right.
+ * iBlk - the index of block in the current macroblock
+ * pDstMVPredME - MV candidate return buffer; if set to NULL then
+ * prediction candidate MVs are not returned and pDstMVPredME will
+ * be NULL upon function return; if pDstMVPredME is non-NULL then it
+ * must point to a buffer containing sufficient space for three
+ * return MVs.
+ *
+ * Output Arguments:
+ *
+ * pDstMVPred - pointer to the predicted motion vector
+ * pDstMVPredME - if non-NULL upon input then pDstMVPredME points upon
+ * return to a buffer containing the three motion vector candidates
+ * used for prediction as specified in [ISO14496-2], subclause
+ * 7.6.5, otherwise if NULL upon input then pDstMVPredME is NULL
+ * upon output.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned under any of the following
+ * conditions:
+ * - the pointer pDstMVPred is NULL
+ * - the parameter iBlk does not fall into the range 0 <= iBlk<=3
+ *
+ */
+OMXResult omxVCM4P2_FindMVpred (
+ const OMXVCMotionVector *pSrcMVCurMB,
+ const OMXVCMotionVector *pSrcCandMV1,
+ const OMXVCMotionVector *pSrcCandMV2,
+ const OMXVCMotionVector *pSrcCandMV3,
+ OMXVCMotionVector *pDstMVPred,
+ OMXVCMotionVector *pDstMVPredME,
+ OMX_INT iBlk
+);
+
+
+
+/**
+ * Function: omxVCM4P2_IDCT8x8blk (6.2.3.2.1)
+ *
+ * Description:
+ * Computes a 2D inverse DCT for a single 8x8 block, as defined in
+ * [ISO14496-2].
+ *
+ * Input Arguments:
+ *
+ * pSrc - pointer to the start of the linearly arranged IDCT input buffer;
+ * must be aligned on a 16-byte boundary. According to
+ * [ISO14496-2], the input coefficient values should lie within the
+ * range [-2048, 2047].
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the start of the linearly arranged IDCT output buffer;
+ * must be aligned on a 16-byte boundary.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments:
+ * - pSrc or pDst is NULL.
+ * - pSrc or pDst is not 16-byte aligned.
+ *
+ */
+OMXResult omxVCM4P2_IDCT8x8blk (
+ const OMX_S16 *pSrc,
+ OMX_S16 *pDst
+);
+
+
+
+/**
+ * Function: omxVCM4P2_MEGetBufSize (6.2.4.1.1)
+ *
+ * Description:
+ * Computes the size, in bytes, of the vendor-specific specification
+ * structure for the following motion estimation functions:
+ * BlockMatch_Integer_8x8, BlockMatch_Integer_16x16, and MotionEstimationMB.
+ *
+ * Input Arguments:
+ *
+ * MEmode - motion estimation mode; available modes are defined by the
+ * enumerated type OMXVCM4P2MEMode
+ * pMEParams - motion estimation parameters
+ *
+ * Output Arguments:
+ *
+ * pSize - pointer to the number of bytes required for the specification
+ * structure
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - one or more of the following is true:
+ * - an invalid value was specified for the parameter MEmode
+ * - a negative or zero value was specified for the
+ * parameter pMEParams->searchRange
+ *
+ */
+OMXResult omxVCM4P2_MEGetBufSize (
+ OMXVCM4P2MEMode MEmode,
+ const OMXVCM4P2MEParams *pMEParams,
+ OMX_U32 *pSize
+);
+
+
+
+/**
+ * Function: omxVCM4P2_MEInit (6.2.4.1.2)
+ *
+ * Description:
+ * Initializes the vendor-specific specification structure required for the
+ * following motion estimation functions: BlockMatch_Integer_8x8,
+ * BlockMatch_Integer_16x16, and MotionEstimationMB. Memory for the
+ * specification structure *pMESpec must be allocated prior to calling the
+ * function, and should be aligned on a 4-byte boundary. Following
+ * initialization by this function, the vendor-specific structure *pMESpec
+ * should contain an implementation-specific representation of all motion
+ * estimation parameters received via the structure pMEParams, for example
+ * rndVal, searchRange, etc. The number of bytes required for the
+ * specification structure can be determined using the function
+ * omxVCM4P2_MEGetBufSize.
+ *
+ * Input Arguments:
+ *
+ * MEmode - motion estimation mode; available modes are defined by the
+ * enumerated type OMXVCM4P2MEMode
+ * pMEParams - motion estimation parameters
+ * pMESpec - pointer to the uninitialized ME specification structure
+ *
+ * Output Arguments:
+ *
+ * pMESpec - pointer to the initialized ME specification structure
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - one or more of the following is true:
+ * - an invalid value was specified for the parameter MEmode
+ * - a negative or zero value was specified for the
+ * parameter pMEParams->searchRange
+ *
+ */
+OMXResult omxVCM4P2_MEInit (
+ OMXVCM4P2MEMode MEmode,
+ const OMXVCM4P2MEParams*pMEParams,
+ void *pMESpec
+);
+
+
+
+/**
+ * Function: omxVCM4P2_BlockMatch_Integer_16x16 (6.2.4.2.1)
+ *
+ * Description:
+ * Performs a 16x16 block search; estimates motion vector and associated
+ * minimum SAD. Both the input and output motion vectors are represented using
+ * half-pixel units, and therefore a shift left or right by 1 bit may be
+ * required, respectively, to match the input or output MVs with other
+ * functions that either generate output MVs or expect input MVs represented
+ * using integer pixel units.
+ *
+ * Input Arguments:
+ *
+ * pSrcRefBuf - pointer to the reference Y plane; points to the reference
+ * MB that corresponds to the location of the current macroblock in
+ * the current plane.
+ * refWidth - width of the reference plane
+ * pRefRect - pointer to the valid reference plane rectangle; coordinates
+ * are specified relative to the image origin. Rectangle
+ * boundaries may extend beyond image boundaries if the image has
+ * been padded. For example, if padding extends 4 pixels beyond
+ * frame border, then the value for the left border could be set to
+ * -4.
+ * pSrcCurrBuf - pointer to the current block in the current macroblock
+ * buffer extracted from the original plane (linear array, 256
+ * entries); must be aligned on a 16-byte boundary. The number of
+ * bytes between lines (step) is 16.
+ * pCurrPointPos - position of the current macroblock in the current plane
+ * pSrcPreMV - pointer to predicted motion vector; NULL indicates no
+ * predicted MV
+ * pSrcPreSAD - pointer to SAD associated with the predicted MV (referenced
+ * by pSrcPreMV); may be set to NULL if unavailable.
+ * pMESpec - vendor-specific motion estimation specification structure;
+ * must have been allocated and then initialized using
+ * omxVCM4P2_MEInit prior to calling the block matching function.
+ *
+ * Output Arguments:
+ *
+ * pDstMV - pointer to estimated MV
+ * pDstSAD - pointer to minimum SAD
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments. Returned if one of the following
+ * conditions is true:
+ * - at least one of the following pointers is NULL: pSrcRefBuf,
+ * pRefRect, pSrcCurrBuff, pCurrPointPos, pDstMV, pDstSAD or
+ * pMESpec, or
+ * - pSrcCurrBuf is not 16-byte aligned
+ *
+ */
+OMXResult omxVCM4P2_BlockMatch_Integer_16x16 (
+ const OMX_U8 *pSrcRefBuf,
+ OMX_INT refWidth,
+ const OMXRect *pRefRect,
+ const OMX_U8 *pSrcCurrBuf,
+ const OMXVCM4P2Coordinate *pCurrPointPos,
+ const OMXVCMotionVector*pSrcPreMV,
+ const OMX_INT *pSrcPreSAD,
+ void *pMESpec,
+ OMXVCMotionVector*pDstMV,
+ OMX_INT *pDstSAD
+);
+
+
+
+/**
+ * Function: omxVCM4P2_BlockMatch_Integer_8x8 (6.2.4.2.2)
+ *
+ * Description:
+ * Performs an 8x8 block search; estimates motion vector and associated
+ * minimum SAD. Both the input and output motion vectors are represented
+ * using half-pixel units, and therefore a shift left or right by 1 bit may be
+ * required, respectively, to match the input or output MVs with other
+ * functions that either generate output MVs or expect input MVs represented
+ * using integer pixel units.
+ *
+ * Input Arguments:
+ *
+ * pSrcRefBuf - pointer to the reference Y plane; points to the reference
+ * block that corresponds to the location of the current 8x8 block
+ * in the current plane.
+ * refWidth - width of the reference plane
+ * pRefRect - pointer to the valid reference plane rectangle; coordinates
+ * are specified relative to the image origin. Rectangle
+ * boundaries may extend beyond image boundaries if the image has
+ * been padded.
+ * pSrcCurrBuf - pointer to the current block in the current macroblock
+ * buffer extracted from the original plane (linear array, 128
+ * entries); must be aligned on an 8-byte boundary. The number of
+ * bytes between lines (step) is 16 bytes.
+ * pCurrPointPos - position of the current block in the current plane
+ * pSrcPreMV - pointer to predicted motion vector; NULL indicates no
+ * predicted MV
+ * pSrcPreSAD - pointer to SAD associated with the predicted MV (referenced
+ * by pSrcPreMV); may be set to NULL if unavailable.
+ * pMESpec - vendor-specific motion estimation specification structure;
+ * must have been allocated and then initialized using
+ * omxVCM4P2_MEInit prior to calling the block matching function.
+ *
+ * Output Arguments:
+ *
+ * pDstMV - pointer to estimated MV
+ * pDstSAD - pointer to minimum SAD
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments. Returned if one of the following
+ * conditions is true:
+ * - at least one of the following pointers is NULL: pSrcRefBuf,
+ * pRefRect, pSrcCurrBuff, pCurrPointPos, pDstMV, pDstSAD or
+ * pMESpec, or
+ * - pSrcCurrBuf is not 8-byte aligned
+ *
+ */
+OMXResult omxVCM4P2_BlockMatch_Integer_8x8 (
+ const OMX_U8 *pSrcRefBuf,
+ OMX_INT refWidth,
+ const OMXRect *pRefRect,
+ const OMX_U8 *pSrcCurrBuf,
+ const OMXVCM4P2Coordinate *pCurrPointPos,
+ const OMXVCMotionVector *pSrcPreMV,
+ const OMX_INT *pSrcPreSAD,
+ void *pMESpec,
+ OMXVCMotionVector *pDstMV,
+ OMX_INT *pDstSAD
+);
+
+
+
+/**
+ * Function: omxVCM4P2_BlockMatch_Half_16x16 (6.2.4.2.3)
+ *
+ * Description:
+ * Performs a 16x16 block match with half-pixel resolution. Returns the
+ * estimated motion vector and associated minimum SAD. This function
+ * estimates the half-pixel motion vector by interpolating the integer
+ * resolution motion vector referenced by the input parameter pSrcDstMV, i.e.,
+ * the initial integer MV is generated externally. The input parameters
+ * pSrcRefBuf and pSearchPointRefPos should be shifted by the winning MV of
+ * 16x16 integer search prior to calling BlockMatch_Half_16x16. The function
+ * BlockMatch_Integer_16x16 may be used for integer motion estimation.
+ *
+ * Input Arguments:
+ *
+ * pSrcRefBuf - pointer to the reference Y plane; points to the reference
+ * macroblock that corresponds to the location of the current
+ * macroblock in the current plane.
+ * refWidth - width of the reference plane
+ * pRefRect - reference plane valid region rectangle
+ * pSrcCurrBuf - pointer to the current block in the current macroblock
+ * buffer extracted from the original plane (linear array, 256
+ * entries); must be aligned on a 16-byte boundary. The number of
+ * bytes between lines (step) is 16.
+ * pSearchPointRefPos - position of the starting point for half pixel
+ * search (specified in terms of integer pixel units) in the
+ * reference plane, i.e., the reference position pointed to by the
+ * predicted motion vector.
+ * rndVal - rounding control parameter: 0 - disabled; 1 - enabled.
+ * pSrcDstMV - pointer to the initial MV estimate; typically generated
+ * during a prior 16X16 integer search; specified in terms of
+ * half-pixel units.
+ *
+ * Output Arguments:
+ *
+ * pSrcDstMV - pointer to estimated MV
+ * pDstSAD - pointer to minimum SAD
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments. Returned if one of the following
+ * conditions is true:
+ * - at least one of the following pointers is NULL: pSrcRefBuf,
+ * pRefRect, pSrcCurrBuff, pSearchPointRefPos, pSrcDstMV.
+ * - pSrcCurrBuf is not 16-byte aligned, or
+ *
+ */
+OMXResult omxVCM4P2_BlockMatch_Half_16x16 (
+ const OMX_U8 *pSrcRefBuf,
+ OMX_INT refWidth,
+ const OMXRect *pRefRect,
+ const OMX_U8 *pSrcCurrBuf,
+ const OMXVCM4P2Coordinate *pSearchPointRefPos,
+ OMX_INT rndVal,
+ OMXVCMotionVector *pSrcDstMV,
+ OMX_INT *pDstSAD
+);
+
+
+
+/**
+ * Function: omxVCM4P2_BlockMatch_Half_8x8 (6.2.4.2.4)
+ *
+ * Description:
+ * Performs an 8x8 block match with half-pixel resolution. Returns the
+ * estimated motion vector and associated minimum SAD. This function
+ * estimates the half-pixel motion vector by interpolating the integer
+ * resolution motion vector referenced by the input parameter pSrcDstMV, i.e.,
+ * the initial integer MV is generated externally. The input parameters
+ * pSrcRefBuf and pSearchPointRefPos should be shifted by the winning MV of
+ * 8x8 integer search prior to calling BlockMatch_Half_8x8. The function
+ * BlockMatch_Integer_8x8 may be used for integer motion estimation.
+ *
+ * Input Arguments:
+ *
+ * pSrcRefBuf - pointer to the reference Y plane; points to the reference
+ * block that corresponds to the location of the current 8x8 block
+ * in the current plane.
+ * refWidth - width of the reference plane
+ * pRefRect - reference plane valid region rectangle
+ * pSrcCurrBuf - pointer to the current block in the current macroblock
+ * buffer extracted from the original plane (linear array, 128
+ * entries); must be aligned on a 8-byte boundary. The number of
+ * bytes between lines (step) is 16.
+ * pSearchPointRefPos - position of the starting point for half pixel
+ * search (specified in terms of integer pixel units) in the
+ * reference plane.
+ * rndVal - rounding control parameter: 0 - disabled; 1 - enabled.
+ * pSrcDstMV - pointer to the initial MV estimate; typically generated
+ * during a prior 8x8 integer search, specified in terms of
+ * half-pixel units.
+ *
+ * Output Arguments:
+ *
+ * pSrcDstMV - pointer to estimated MV
+ * pDstSAD - pointer to minimum SAD
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments. Returned if one of the following
+ * conditions is true:
+ * - at least one of the following pointers is NULL:
+ * pSrcRefBuf, pRefRect, pSrcCurrBuff, pSearchPointRefPos, pSrcDstMV
+ * - pSrcCurrBuf is not 8-byte aligned
+ *
+ */
+OMXResult omxVCM4P2_BlockMatch_Half_8x8 (
+ const OMX_U8 *pSrcRefBuf,
+ OMX_INT refWidth,
+ const OMXRect *pRefRect,
+ const OMX_U8 *pSrcCurrBuf,
+ const OMXVCM4P2Coordinate *pSearchPointRefPos,
+ OMX_INT rndVal,
+ OMXVCMotionVector *pSrcDstMV,
+ OMX_INT *pDstSAD
+);
+
+
+
+/**
+ * Function: omxVCM4P2_MotionEstimationMB (6.2.4.3.1)
+ *
+ * Description:
+ * Performs motion search for a 16x16 macroblock. Selects best motion search
+ * strategy from among inter-1MV, inter-4MV, and intra modes. Supports
+ * integer and half pixel resolution.
+ *
+ * Input Arguments:
+ *
+ * pSrcCurrBuf - pointer to the top-left corner of the current MB in the
+ * original picture plane; must be aligned on a 16-byte boundary.
+ * The function does not expect source data outside the region
+ * bounded by the MB to be available; for example it is not
+ * necessary for the caller to guarantee the availability of
+ * pSrcCurrBuf[-SrcCurrStep], i.e., the row of pixels above the MB
+ * to be processed.
+ * srcCurrStep - width of the original picture plane, in terms of full
+ * pixels; must be a multiple of 16.
+ * pSrcRefBuf - pointer to the reference Y plane; points to the reference
+ * plane location corresponding to the location of the current
+ * macroblock in the current plane; must be aligned on a 16-byte
+ * boundary.
+ * srcRefStep - width of the reference picture plane, in terms of full
+ * pixels; must be a multiple of 16.
+ * pRefRect - reference plane valid region rectangle, specified relative to
+ * the image origin
+ * pCurrPointPos - position of the current macroblock in the current plane
+ * pMESpec - pointer to the vendor-specific motion estimation specification
+ * structure; must be allocated and then initialized using
+ * omxVCM4P2_MEInit prior to calling this function.
+ * pMBInfo - array, of dimension four, containing pointers to information
+ * associated with four nearby MBs:
+ * - pMBInfo[0] - pointer to left MB information
+ * - pMBInfo[1] - pointer to top MB information
+ * - pMBInfo[2] - pointer to top-left MB information
+ * - pMBInfo[3] - pointer to top-right MB information
+ * Any pointer in the array may be set equal to NULL if the
+ * corresponding MB doesn't exist. For each MB, the following structure
+ * members are used:
+ * - mbType - macroblock type, either OMX_VC_INTRA, OMX_VC_INTER, or
+ * OMX_VC_INTER4V
+ * - pMV0[2][2] - estimated motion vectors; represented
+ * in 1/2 pixel units
+ * - sliceID - number of the slice to which the MB belongs
+ * pSrcDstMBCurr - pointer to information structure for the current MB.
+ * The following entries should be set prior to calling the
+ * function: sliceID - the number of the slice the to which the
+ * current MB belongs. The structure elements cbpy and cbpc are
+ * ignored.
+ *
+ * Output Arguments:
+ *
+ * pSrcDstMBCurr - pointer to updated information structure for the current
+ * MB after MB-level motion estimation has been completed. The
+ * following structure members are updated by the ME function:
+ * - mbType - macroblock type: OMX_VC_INTRA, OMX_VC_INTER, or
+ * OMX_VC_INTER4V.
+ * - pMV0[2][2] - estimated motion vectors; represented in
+ * terms of 1/2 pel units.
+ * - pMVPred[2][2] - predicted motion vectors; represented
+ * in terms of 1/2 pel units.
+ * The structure members cbpy and cbpc are not updated by the function.
+ * pDstSAD - pointer to the minimum SAD for INTER1V, or sum of minimum SADs
+ * for INTER4V
+ * pDstBlockSAD - pointer to an array of SAD values for each of the four
+ * 8x8 luma blocks in the MB. The block SADs are in scan order for
+ * each MB.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments. Returned if one or more of the
+ * following conditions is true:
+ * - at least one of the following pointers is NULL: pSrcCurrBuf,
+ * pSrcRefBuf, pRefRect, pCurrPointPos, pMBInter, pMBIntra,
+ * pSrcDstMBCurr, or pDstSAD.
+ *
+ */
+OMXResult omxVCM4P2_MotionEstimationMB (
+ const OMX_U8 *pSrcCurrBuf,
+ OMX_S32 srcCurrStep,
+ const OMX_U8 *pSrcRefBuf,
+ OMX_S32 srcRefStep,
+ const OMXRect*pRefRect,
+ const OMXVCM4P2Coordinate *pCurrPointPos,
+ void *pMESpec,
+ const OMXVCM4P2MBInfoPtr *pMBInfo,
+ OMXVCM4P2MBInfo *pSrcDstMBCurr,
+ OMX_U16 *pDstSAD,
+ OMX_U16 *pDstBlockSAD
+);
+
+
+
+/**
+ * Function: omxVCM4P2_DCT8x8blk (6.2.4.4.1)
+ *
+ * Description:
+ * Computes a 2D forward DCT for a single 8x8 block, as defined in
+ * [ISO14496-2].
+ *
+ * Input Arguments:
+ *
+ * pSrc - pointer to the start of the linearly arranged input buffer; must
+ * be aligned on a 16-byte boundary. Input values (pixel
+ * intensities) are valid in the range [-255,255].
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the start of the linearly arranged output buffer; must
+ * be aligned on a 16-byte boundary.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments, returned if:
+ * - pSrc or pDst is NULL.
+ * - pSrc or pDst is not 16-byte aligned.
+ *
+ */
+OMXResult omxVCM4P2_DCT8x8blk (
+ const OMX_S16 *pSrc,
+ OMX_S16 *pDst
+);
+
+
+
+/**
+ * Function: omxVCM4P2_QuantIntra_I (6.2.4.4.2)
+ *
+ * Description:
+ * Performs quantization on intra block coefficients. This function supports
+ * bits_per_pixel == 8.
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - pointer to the input intra block coefficients; must be aligned
+ * on a 16-byte boundary.
+ * QP - quantization parameter (quantizer_scale).
+ * blockIndex - block index indicating the component type and position,
+ * valid in the range 0 to 5, as defined in [ISO14496-2], subclause
+ * 6.1.3.8.
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; shortVideoHeader==1 selects linear intra DC
+ * mode, and shortVideoHeader==0 selects non linear intra DC mode.
+ *
+ * Output Arguments:
+ *
+ * pSrcDst - pointer to the output (quantized) interblock coefficients.
+ * When shortVideoHeader==1, AC coefficients are saturated on the
+ * interval [-127, 127], and DC coefficients are saturated on the
+ * interval [1, 254]. When shortVideoHeader==0, AC coefficients
+ * are saturated on the interval [-2047, 2047].
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments:
+ * - pSrcDst is NULL.
+ * - blockIndex < 0 or blockIndex >= 10
+ * - QP <= 0 or QP >= 32.
+ *
+ */
+OMXResult omxVCM4P2_QuantIntra_I (
+ OMX_S16 *pSrcDst,
+ OMX_U8 QP,
+ OMX_INT blockIndex,
+ OMX_INT shortVideoHeader
+);
+
+
+
+/**
+ * Function: omxVCM4P2_QuantInter_I (6.2.4.4.3)
+ *
+ * Description:
+ * Performs quantization on an inter coefficient block; supports
+ * bits_per_pixel == 8.
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - pointer to the input inter block coefficients; must be aligned
+ * on a 16-byte boundary.
+ * QP - quantization parameter (quantizer_scale)
+ * shortVideoHeader - binary flag indicating presence of short_video_header;
+ * shortVideoHeader==1 selects linear intra DC mode, and
+ * shortVideoHeader==0 selects non linear intra DC mode.
+ *
+ * Output Arguments:
+ *
+ * pSrcDst - pointer to the output (quantized) interblock coefficients.
+ * When shortVideoHeader==1, AC coefficients are saturated on the
+ * interval [-127, 127], and DC coefficients are saturated on the
+ * interval [1, 254]. When shortVideoHeader==0, AC coefficients
+ * are saturated on the interval [-2047, 2047].
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments:
+ * - pSrcDst is NULL.
+ * - QP <= 0 or QP >= 32.
+ *
+ */
+OMXResult omxVCM4P2_QuantInter_I (
+ OMX_S16 *pSrcDst,
+ OMX_U8 QP,
+ OMX_INT shortVideoHeader
+);
+
+
+
+/**
+ * Function: omxVCM4P2_TransRecBlockCoef_intra (6.2.4.4.4)
+ *
+ * Description:
+ * Quantizes the DCT coefficients, implements intra block AC/DC coefficient
+ * prediction, and reconstructs the current intra block texture for prediction
+ * on the next frame. Quantized row and column coefficients are returned in
+ * the updated coefficient buffers.
+ *
+ * Input Arguments:
+ *
+ * pSrc - pointer to the pixels of current intra block; must be aligned on
+ * an 8-byte boundary.
+ * pPredBufRow - pointer to the coefficient row buffer containing
+ * ((num_mb_per_row * 2 + 1) * 8) elements of type OMX_S16.
+ * Coefficients are organized into blocks of eight as described
+ * below (Internal Prediction Coefficient Update Procedures). The
+ * DC coefficient is first, and the remaining buffer locations
+ * contain the quantized AC coefficients. Each group of eight row
+ * buffer elements combined with one element eight elements ahead
+ * contains the coefficient predictors of the neighboring block
+ * that is spatially above or to the left of the block currently to
+ * be decoded. A negative-valued DC coefficient indicates that this
+ * neighboring block is not INTRA-coded or out of bounds, and
+ * therefore the AC and DC coefficients are invalid. Pointer must
+ * be aligned on an 8-byte boundary.
+ * pPredBufCol - pointer to the prediction coefficient column buffer
+ * containing 16 elements of type OMX_S16. Coefficients are
+ * organized as described in section 6.2.2.5. Pointer must be
+ * aligned on an 8-byte boundary.
+ * pSumErr - pointer to a flag indicating whether or not AC prediction is
+ * required; AC prediction is enabled if *pSumErr >=0, but the
+ * value is not used for coefficient prediction, i.e., the sum of
+ * absolute differences starts from 0 for each call to this
+ * function. Otherwise AC prediction is disabled if *pSumErr < 0 .
+ * blockIndex - block index indicating the component type and position, as
+ * defined in [ISO14496-2], subclause 6.1.3.8.
+ * curQp - quantization parameter of the macroblock to which the current
+ * block belongs
+ * pQpBuf - pointer to a 2-element quantization parameter buffer; pQpBuf[0]
+ * contains the quantization parameter associated with the 8x8
+ * block left of the current block (QPa), and pQpBuf[1] contains
+ * the quantization parameter associated with the 8x8 block above
+ * the current block (QPc). In the event that the corresponding
+ * block is outside of the VOP bound, the Qp value will not affect
+ * the intra prediction process, as described in [ISO14496-2],
+ * sub-clause 7.4.3.3, Adaptive AC Coefficient Prediction.
+ * srcStep - width of the source buffer; must be a multiple of 8.
+ * dstStep - width of the reconstructed destination buffer; must be a
+ * multiple of 16.
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; shortVideoHeader==1 selects linear intra DC
+ * mode, and shortVideoHeader==0 selects non linear intra DC mode.
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the quantized DCT coefficient buffer; pDst[0] contains
+ * the predicted DC coefficient; the remaining entries contain the
+ * quantized AC coefficients (without prediction). The pointer
+ * pDstmust be aligned on a 16-byte boundary.
+ * pRec - pointer to the reconstructed texture; must be aligned on an
+ * 8-byte boundary.
+ * pPredBufRow - pointer to the updated coefficient row buffer
+ * pPredBufCol - pointer to the updated coefficient column buffer
+ * pPreACPredict - if prediction is enabled, the parameter points to the
+ * start of the buffer containing the coefficient differences for
+ * VLC encoding. The entry pPreACPredict[0]indicates prediction
+ * direction for the current block and takes one of the following
+ * values: OMX_VC_NONE (prediction disabled), OMX_VC_HORIZONTAL, or
+ * OMX_VC_VERTICAL. The entries
+ * pPreACPredict[1]-pPreACPredict[7]contain predicted AC
+ * coefficients. If prediction is disabled (*pSumErr<0) then the
+ * contents of this buffer are undefined upon return from the
+ * function
+ * pSumErr - pointer to the value of the accumulated AC coefficient errors,
+ * i.e., sum of the absolute differences between predicted and
+ * unpredicted AC coefficients
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - Bad arguments:
+ * - At least one of the following pointers is NULL: pSrc, pDst, pRec,
+ * pCoefBufRow, pCoefBufCol, pQpBuf, pPreACPredict, pSumErr.
+ * - blockIndex < 0 or blockIndex >= 10;
+ * - curQP <= 0 or curQP >= 32.
+ * - srcStep, or dstStep <= 0 or not a multiple of 8.
+ * - pDst is not 16-byte aligned: .
+ * - At least one of the following pointers is not 8-byte aligned:
+ * pSrc, pRec.
+ *
+ * Note: The coefficient buffers must be updated in accordance with the
+ * update procedures defined in section in 6.2.2.
+ *
+ */
+OMXResult omxVCM4P2_TransRecBlockCoef_intra (
+ const OMX_U8 *pSrc,
+ OMX_S16 *pDst,
+ OMX_U8 *pRec,
+ OMX_S16 *pPredBufRow,
+ OMX_S16 *pPredBufCol,
+ OMX_S16 *pPreACPredict,
+ OMX_INT *pSumErr,
+ OMX_INT blockIndex,
+ OMX_U8 curQp,
+ const OMX_U8 *pQpBuf,
+ OMX_INT srcStep,
+ OMX_INT dstStep,
+ OMX_INT shortVideoHeader
+);
+
+
+
+/**
+ * Function: omxVCM4P2_TransRecBlockCoef_inter (6.2.4.4.5)
+ *
+ * Description:
+ * Implements DCT, and quantizes the DCT coefficients of the inter block
+ * while reconstructing the texture residual. There is no boundary check for
+ * the bit stream buffer.
+ *
+ * Input Arguments:
+ *
+ * pSrc -pointer to the residuals to be encoded; must be aligned on an
+ * 16-byte boundary.
+ * QP - quantization parameter.
+ * shortVideoHeader - binary flag indicating presence of short_video_header;
+ * shortVideoHeader==1 selects linear intra DC mode, and
+ * shortVideoHeader==0 selects non linear intra DC mode.
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the quantized DCT coefficients buffer; must be aligned
+ * on a 16-byte boundary.
+ * pRec - pointer to the reconstructed texture residuals; must be aligned
+ * on a 16-byte boundary.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments:
+ * - At least one of the following pointers is either NULL or
+ * not 16-byte aligned:
+ * - pSrc
+ * - pDst
+ * - pRec
+ * - QP <= 0 or QP >= 32.
+ *
+ */
+OMXResult omxVCM4P2_TransRecBlockCoef_inter (
+ const OMX_S16 *pSrc,
+ OMX_S16 *pDst,
+ OMX_S16 *pRec,
+ OMX_U8 QP,
+ OMX_INT shortVideoHeader
+);
+
+
+
+/**
+ * Function: omxVCM4P2_EncodeVLCZigzag_IntraDCVLC (6.2.4.5.2)
+ *
+ * Description:
+ * Performs zigzag scan and VLC encoding of AC and DC coefficients for one
+ * intra block. Two versions of the function (DCVLC and ACVLC) are provided
+ * in order to support the two different methods of processing DC
+ * coefficients, as described in [ISO14496-2], subclause 7.4.1.4, "Intra DC
+ * Coefficient Decoding for the Case of Switched VLC Encoding".
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - double pointer to the current byte in the bitstream
+ * pBitOffset - pointer to the bit position in the byte pointed by
+ * *ppBitStream. Valid within 0 to 7.
+ * pQDctBlkCoef - pointer to the quantized DCT coefficient
+ * predDir - AC prediction direction, which is used to decide the zigzag
+ * scan pattern; takes one of the following values:
+ * - OMX_VC_NONE - AC prediction not used.
+ * Performs classical zigzag scan.
+ * - OMX_VC_HORIZONTAL - Horizontal prediction.
+ * Performs alternate-vertical zigzag scan.
+ * - OMX_VC_VERTICAL - Vertical prediction.
+ * Performs alternate-horizontal zigzag scan.
+ * pattern - block pattern which is used to decide whether this block is
+ * encoded
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; escape modes 0-3 are used if
+ * shortVideoHeader==0, and escape mode 4 is used when
+ * shortVideoHeader==1.
+ * videoComp - video component type (luminance, chrominance) of the current
+ * block
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after the block is encoded, so
+ * that it points to the current byte in the bit stream buffer.
+ * pBitOffset - *pBitOffset is updated so that it points to the current bit
+ * position in the byte pointed by *ppBitStream.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - Bad arguments:
+ * - At least one of the following pointers is NULL: ppBitStream,
+ * *ppBitStream, pBitOffset, pQDctBlkCoef.
+ * - *pBitOffset < 0, or *pBitOffset >7.
+ * - PredDir is not one of: OMX_VC_NONE, OMX_VC_HORIZONTAL, or
+ * OMX_VC_VERTICAL.
+ * - VideoComp is not one component of enum OMXVCM4P2VideoComponent.
+ *
+ */
+OMXResult omxVCM4P2_EncodeVLCZigzag_IntraDCVLC (
+ OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ const OMX_S16 *pQDctBlkCoef,
+ OMX_U8 predDir,
+ OMX_U8 pattern,
+ OMX_INT shortVideoHeader,
+ OMXVCM4P2VideoComponent videoComp
+);
+
+
+
+/**
+ * Function: omxVCM4P2_EncodeVLCZigzag_IntraACVLC (6.2.4.5.2)
+ *
+ * Description:
+ * Performs zigzag scan and VLC encoding of AC and DC coefficients for one
+ * intra block. Two versions of the function (DCVLC and ACVLC) are provided
+ * in order to support the two different methods of processing DC
+ * coefficients, as described in [ISO14496-2], subclause 7.4.1.4, Intra DC
+ * Coefficient Decoding for the Case of Switched VLC Encoding.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - double pointer to the current byte in the bitstream
+ * pBitOffset - pointer to the bit position in the byte pointed by
+ * *ppBitStream. Valid within 0 to 7.
+ * pQDctBlkCoef - pointer to the quantized DCT coefficient
+ * predDir - AC prediction direction, which is used to decide the zigzag
+ * scan pattern; takes one of the following values:
+ * - OMX_VC_NONE - AC prediction not used.
+ * Performs classical zigzag scan.
+ * - OMX_VC_HORIZONTAL - Horizontal prediction.
+ * Performs alternate-vertical zigzag scan.
+ * - OMX_VC_VERTICAL - Vertical prediction.
+ * Performs alternate-horizontal zigzag scan.
+ * pattern - block pattern which is used to decide whether this block is
+ * encoded
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; escape modes 0-3 are used if
+ * shortVideoHeader==0, and escape mode 4 is used when
+ * shortVideoHeader==1.
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after the block is encoded, so
+ * that it points to the current byte in the bit stream buffer.
+ * pBitOffset - *pBitOffset is updated so that it points to the current bit
+ * position in the byte pointed by *ppBitStream.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - Bad arguments:
+ * - At least one of the following pointers is NULL: ppBitStream,
+ * *ppBitStream, pBitOffset, pQDctBlkCoef.
+ * - *pBitOffset < 0, or *pBitOffset >7.
+ * - PredDir is not one of: OMX_VC_NONE, OMX_VC_HORIZONTAL, or
+ * OMX_VC_VERTICAL.
+ * - VideoComp is not one component of enum OMXVCM4P2VideoComponent.
+ *
+ */
+OMXResult omxVCM4P2_EncodeVLCZigzag_IntraACVLC (
+ OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ const OMX_S16 *pQDctBlkCoef,
+ OMX_U8 predDir,
+ OMX_U8 pattern,
+ OMX_INT shortVideoHeader
+);
+
+
+
+/**
+ * Function: omxVCM4P2_EncodeVLCZigzag_Inter (6.2.4.5.3)
+ *
+ * Description:
+ * Performs classical zigzag scanning and VLC encoding for one inter block.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - pointer to the pointer to the current byte in the bit
+ * stream
+ * pBitOffset - pointer to the bit position in the byte pointed by
+ * *ppBitStream. Valid within 0 to 7
+ * pQDctBlkCoef - pointer to the quantized DCT coefficient
+ * pattern - block pattern which is used to decide whether this block is
+ * encoded
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; escape modes 0-3 are used if
+ * shortVideoHeader==0, and escape mode 4 is used when
+ * shortVideoHeader==1.
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after the block is encoded so that
+ * it points to the current byte in the bit stream buffer.
+ * pBitOffset - *pBitOffset is updated so that it points to the current bit
+ * position in the byte pointed by *ppBitStream.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - Bad arguments
+ * - At least one of the pointers: is NULL: ppBitStream, *ppBitStream,
+ * pBitOffset, pQDctBlkCoef
+ * - *pBitOffset < 0, or *pBitOffset >7.
+ *
+ */
+OMXResult omxVCM4P2_EncodeVLCZigzag_Inter (
+ OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ const OMX_S16 *pQDctBlkCoef,
+ OMX_U8 pattern,
+ OMX_INT shortVideoHeader
+);
+
+
+
+/**
+ * Function: omxVCM4P2_EncodeMV (6.2.4.5.4)
+ *
+ * Description:
+ * Predicts a motion vector for the current macroblock, encodes the
+ * difference, and writes the output to the stream buffer. The input MVs
+ * pMVCurMB, pSrcMVLeftMB, pSrcMVUpperMB, and pSrcMVUpperRightMB should lie
+ * within the ranges associated with the input parameter fcodeForward, as
+ * described in [ISO14496-2], subclause 7.6.3. This function provides a
+ * superset of the functionality associated with the function
+ * omxVCM4P2_FindMVpred.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - double pointer to the current byte in the bitstream buffer
+ * pBitOffset - index of the first free (next available) bit in the stream
+ * buffer referenced by *ppBitStream, valid in the range 0 to 7.
+ * pMVCurMB - pointer to the current macroblock motion vector; a value of
+ * NULL indicates unavailability.
+ * pSrcMVLeftMB - pointer to the source left macroblock motion vector; a
+ * value of NULLindicates unavailability.
+ * pSrcMVUpperMB - pointer to source upper macroblock motion vector; a
+ * value of NULL indicates unavailability.
+ * pSrcMVUpperRightMB - pointer to source upper right MB motion vector; a
+ * value of NULL indicates unavailability.
+ * fcodeForward - an integer with values from 1 to 7; used in encoding
+ * motion vectors related to search range, as described in
+ * [ISO14496-2], subclause 7.6.3.
+ * MBType - macro block type, valid in the range 0 to 5
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - updated pointer to the current byte in the bit stream
+ * buffer
+ * pBitOffset - updated index of the next available bit position in stream
+ * buffer referenced by *ppBitStream
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments
+ * - At least one of the following pointers is NULL: ppBitStream,
+ * *ppBitStream, pBitOffset, pMVCurMB
+ * - *pBitOffset < 0, or *pBitOffset >7.
+ * - fcodeForward <= 0, or fcodeForward > 7, or MBType < 0.
+ *
+ */
+OMXResult omxVCM4P2_EncodeMV (
+ OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ const OMXVCMotionVector *pMVCurMB,
+ const OMXVCMotionVector*pSrcMVLeftMB,
+ const OMXVCMotionVector *pSrcMVUpperMB,
+ const OMXVCMotionVector *pSrcMVUpperRightMB,
+ OMX_INT fcodeForward,
+ OMXVCM4P2MacroblockType MBType
+);
+
+
+
+/**
+ * Function: omxVCM4P2_DecodePadMV_PVOP (6.2.5.1.1)
+ *
+ * Description:
+ * Decodes and pads the four motion vectors associated with a non-intra P-VOP
+ * macroblock. For macroblocks of type OMX_VC_INTER4V, the output MV is
+ * padded as specified in [ISO14496-2], subclause 7.6.1.6. Otherwise, for
+ * macroblocks of types other than OMX_VC_INTER4V, the decoded MV is copied to
+ * all four output MV buffer entries.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - pointer to the pointer to the current byte in the bit
+ * stream buffer
+ * pBitOffset - pointer to the bit position in the byte pointed to by
+ * *ppBitStream. *pBitOffset is valid within [0-7].
+ * pSrcMVLeftMB, pSrcMVUpperMB, and pSrcMVUpperRightMB - pointers to the
+ * motion vector buffers of the macroblocks specially at the left,
+ * upper, and upper-right side of the current macroblock,
+ * respectively; a value of NULL indicates unavailability. Note:
+ * Any neighborhood macroblock outside the current VOP or video
+ * packet or outside the current GOB (when short_video_header is
+ * 1 ) for which gob_header_empty is 0 is treated as
+ * transparent, according to [ISO14496-2], subclause 7.6.5.
+ * fcodeForward - a code equal to vop_fcode_forward in MPEG-4 bit stream
+ * syntax
+ * MBType - the type of the current macroblock. If MBType is not equal to
+ * OMX_VC_INTER4V, the destination motion vector buffer is still
+ * filled with the same decoded vector.
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after the block is decoded, so
+ * that it points to the current byte in the bit stream buffer
+ * pBitOffset - *pBitOffset is updated so that it points to the current bit
+ * position in the byte pointed by *ppBitStream
+ * pDstMVCurMB - pointer to the motion vector buffer for the current
+ * macroblock; contains four decoded motion vectors
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments:
+ * - At least one of the following pointers is NULL:
+ * ppBitStream, *ppBitStream, pBitOffset, pDstMVCurMB
+ * - *pBitOffset exceeds [0,7]
+ * - fcodeForward exceeds (0,7]
+ * - MBType less than zero
+ * - motion vector buffer is not 4-byte aligned.
+ * OMX_Sts_Err - status error
+ *
+ */
+OMXResult omxVCM4P2_DecodePadMV_PVOP (
+ const OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ OMXVCMotionVector *pSrcMVLeftMB,
+ OMXVCMotionVector*pSrcMVUpperMB,
+ OMXVCMotionVector *pSrcMVUpperRightMB,
+ OMXVCMotionVector*pDstMVCurMB,
+ OMX_INT fcodeForward,
+ OMXVCM4P2MacroblockType MBType
+);
+
+
+
+/**
+ * Function: omxVCM4P2_DecodeVLCZigzag_IntraDCVLC (6.2.5.2.2)
+ *
+ * Description:
+ * Performs VLC decoding and inverse zigzag scan of AC and DC coefficients
+ * for one intra block. Two versions of the function (DCVLC and ACVLC) are
+ * provided in order to support the two different methods of processing DC
+ * coefficients, as described in [ISO14496-2], subclause 7.4.1.4, Intra DC
+ * Coefficient Decoding for the Case of Switched VLC Encoding.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - pointer to the pointer to the current byte in the
+ * bitstream buffer
+ * pBitOffset - pointer to the bit position in the current byte referenced
+ * by *ppBitStream. The parameter *pBitOffset is valid in the
+ * range [0-7].
+ * Bit Position in one byte: |Most Least|
+ * *pBitOffset |0 1 2 3 4 5 6 7|
+ * predDir - AC prediction direction; used to select the zigzag scan
+ * pattern; takes one of the following values:
+ * - OMX_VC_NONE - AC prediction not used;
+ * performs classical zigzag scan.
+ * - OMX_VC_HORIZONTAL - Horizontal prediction;
+ * performs alternate-vertical zigzag scan;
+ * - OMX_VC_VERTICAL - Vertical prediction;
+ * performs alternate-horizontal zigzag scan.
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; escape modes 0-3 are used if
+ * shortVideoHeader==0, and escape mode 4 is used when
+ * shortVideoHeader==1.
+ * videoComp - video component type (luminance or chrominance) of the
+ * current block
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after the block is decoded such
+ * that it points to the current byte in the bit stream buffer
+ * pBitOffset - *pBitOffset is updated such that it points to the current
+ * bit position in the byte pointed by *ppBitStream
+ * pDst - pointer to the coefficient buffer of current block; must be
+ * 4-byte aligned.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments, if:
+ * - At least one of the following pointers is NULL:
+ * ppBitStream, *ppBitStream, pBitOffset, pDst
+ * - *pBitOffset exceeds [0,7]
+ * - preDir exceeds [0,2]
+ * - pDst is not 4-byte aligned
+ * OMX_Sts_Err - if:
+ * - In DecodeVLCZigzag_IntraDCVLC, dc_size > 12
+ * - At least one of mark bits equals zero
+ * - Illegal stream encountered; code cannot be located in VLC table
+ * - Forbidden code encountered in the VLC FLC table.
+ * - The number of coefficients is greater than 64
+ *
+ */
+OMXResult omxVCM4P2_DecodeVLCZigzag_IntraDCVLC (
+ const OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ OMX_S16 *pDst,
+ OMX_U8 predDir,
+ OMX_INT shortVideoHeader,
+ OMXVCM4P2VideoComponent videoComp
+);
+
+
+
+/**
+ * Function: omxVCM4P2_DecodeVLCZigzag_IntraACVLC (6.2.5.2.2)
+ *
+ * Description:
+ * Performs VLC decoding and inverse zigzag scan of AC and DC coefficients
+ * for one intra block. Two versions of the function (DCVLC and ACVLC) are
+ * provided in order to support the two different methods of processing DC
+ * coefficients, as described in [ISO14496-2], subclause 7.4.1.4, Intra DC
+ * Coefficient Decoding for the Case of Switched VLC Encoding.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - pointer to the pointer to the current byte in the
+ * bitstream buffer
+ * pBitOffset - pointer to the bit position in the current byte referenced
+ * by *ppBitStream. The parameter *pBitOffset is valid in the
+ * range [0-7]. Bit Position in one byte: |Most Least| *pBitOffset
+ * |0 1 2 3 4 5 6 7|
+ * predDir - AC prediction direction; used to select the zigzag scan
+ * pattern; takes one of the following values: OMX_VC_NONE - AC
+ * prediction not used; performs classical zigzag scan.
+ * OMX_VC_HORIZONTAL - Horizontal prediction; performs
+ * alternate-vertical zigzag scan; OMX_VC_VERTICAL - Vertical
+ * prediction; performs alternate-horizontal zigzag scan.
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; escape modes 0-3 are used if
+ * shortVideoHeader==0, and escape mode 4 is used when
+ * shortVideoHeader==1.
+ * videoComp - video component type (luminance or chrominance) of the
+ * current block
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after the block is decoded such
+ * that it points to the current byte in the bit stream buffer
+ * pBitOffset - *pBitOffset is updated such that it points to the current
+ * bit position in the byte pointed by *ppBitStream
+ * pDst - pointer to the coefficient buffer of current block; must be
+ * 4-byte aligned.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments At least one of the following
+ * pointers is NULL: ppBitStream, *ppBitStream, pBitOffset, pDst,
+ * or At least one of the following conditions is true:
+ * *pBitOffset exceeds [0,7], preDir exceeds [0,2], or pDst is
+ * not 4-byte aligned
+ * OMX_Sts_Err In DecodeVLCZigzag_IntraDCVLC, dc_size > 12 At least one of
+ * mark bits equals zero Illegal stream encountered; code cannot
+ * be located in VLC table Forbidden code encountered in the VLC
+ * FLC table The number of coefficients is greater than 64
+ *
+ */
+OMXResult omxVCM4P2_DecodeVLCZigzag_IntraACVLC (
+ const OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ OMX_S16 *pDst,
+ OMX_U8 predDir,
+ OMX_INT shortVideoHeader
+);
+
+
+
+/**
+ * Function: omxVCM4P2_DecodeVLCZigzag_Inter (6.2.5.2.3)
+ *
+ * Description:
+ * Performs VLC decoding and inverse zigzag scan for one inter-coded block.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - double pointer to the current byte in the stream buffer
+ * pBitOffset - pointer to the next available bit in the current stream
+ * byte referenced by *ppBitStream. The parameter *pBitOffset is
+ * valid within the range [0-7].
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; escape modes 0-3 are used if
+ * shortVideoHeader==0, and escape mode 4 is used when
+ * shortVideoHeader==1.
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after the block is decoded such
+ * that it points to the current byte in the stream buffer
+ * pBitOffset - *pBitOffset is updated after decoding such that it points
+ * to the next available bit in the stream byte referenced by
+ * *ppBitStream
+ * pDst - pointer to the coefficient buffer of current block; must be
+ * 4-byte aligned.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_BadArgErr - bad arguments:
+ * - At least one of the following pointers is NULL:
+ * ppBitStream, *ppBitStream, pBitOffset, pDst
+ * - pDst is not 4-byte aligned
+ * - *pBitOffset exceeds [0,7]
+ * OMX_Sts_Err - status error, if:
+ * - At least one mark bit is equal to zero
+ * - Encountered an illegal stream code that cannot be found in the VLC table
+ * - Encountered an illegal code in the VLC FLC table
+ * - The number of coefficients is greater than 64
+ *
+ */
+OMXResult omxVCM4P2_DecodeVLCZigzag_Inter (
+ const OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ OMX_S16 *pDst,
+ OMX_INT shortVideoHeader
+);
+
+
+
+/**
+ * Function: omxVCM4P2_QuantInvIntra_I (6.2.5.3.2)
+ *
+ * Description:
+ * Performs the second inverse quantization mode on an intra/inter coded
+ * block. Supports bits_per_pixel = 8. The output coefficients are clipped to
+ * the range [-2048, 2047].
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - pointer to the input (quantized) intra/inter block; must be
+ * aligned on a 16-byte boundary.
+ * QP - quantization parameter (quantizer_scale)
+ * videoComp - video component type of the current block. Takes one of the
+ * following flags: OMX_VC_LUMINANCE, OMX_VC_CHROMINANCE (intra
+ * version only).
+ * shortVideoHeader - binary flag indicating presence of short_video_header
+ * (intra version only).
+ *
+ * Output Arguments:
+ *
+ * pSrcDst - pointer to the output (dequantized) intra/inter block
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; one or more of the following is
+ * true:
+ * - pSrcDst is NULL
+ * - QP <= 0 or QP >=31
+ * - videoComp is neither OMX_VC_LUMINANCE nor OMX_VC_CHROMINANCE.
+ *
+ */
+OMXResult omxVCM4P2_QuantInvIntra_I (
+ OMX_S16 *pSrcDst,
+ OMX_INT QP,
+ OMXVCM4P2VideoComponent videoComp,
+ OMX_INT shortVideoHeader
+);
+
+
+
+/**
+ * Function: omxVCM4P2_QuantInvInter_I (6.2.5.3.2)
+ *
+ * Description:
+ * Performs the second inverse quantization mode on an intra/inter coded
+ * block. Supports bits_per_pixel = 8. The output coefficients are clipped to
+ * the range [-2048, 2047].
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - pointer to the input (quantized) intra/inter block; must be
+ * aligned on a 16-byte boundary.
+ * QP - quantization parameter (quantizer_scale)
+ * videoComp - video component type of the current block. Takes one of the
+ * following flags: OMX_VC_LUMINANCE, OMX_VC_CHROMINANCE (intra
+ * version only).
+ * shortVideoHeader - binary flag indicating presence of short_video_header
+ * (intra version only).
+ *
+ * Output Arguments:
+ *
+ * pSrcDst - pointer to the output (dequantized) intra/inter block
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; one or more of the following is
+ * true:
+ * - pSrcDst is NULL
+ * - QP <= 0 or QP >=31
+ * - videoComp is neither OMX_VC_LUMINANCE nor OMX_VC_CHROMINANCE.
+ *
+ */
+OMXResult omxVCM4P2_QuantInvInter_I (
+ OMX_S16 *pSrcDst,
+ OMX_INT QP
+);
+
+
+
+/**
+ * Function: omxVCM4P2_DecodeBlockCoef_Intra (6.2.5.4.1)
+ *
+ * Description:
+ * Decodes the INTRA block coefficients. Inverse quantization, inversely
+ * zigzag positioning, and IDCT, with appropriate clipping on each step, are
+ * performed on the coefficients. The results are then placed in the output
+ * frame/plane on a pixel basis. Note: This function will be used only when
+ * at least one non-zero AC coefficient of current block exists in the bit
+ * stream. The DC only condition will be handled in another function.
+ *
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - pointer to the pointer to the current byte in the bit
+ * stream buffer. There is no boundary check for the bit stream
+ * buffer.
+ * pBitOffset - pointer to the bit position in the byte pointed to by
+ * *ppBitStream. *pBitOffset is valid within [0-7].
+ * step - width of the destination plane
+ * pCoefBufRow - pointer to the coefficient row buffer; must be aligned on
+ * an 8-byte boundary.
+ * pCoefBufCol - pointer to the coefficient column buffer; must be aligned
+ * on an 8-byte boundary.
+ * curQP - quantization parameter of the macroblock which the current block
+ * belongs to
+ * pQPBuf - pointer to the quantization parameter buffer
+ * blockIndex - block index indicating the component type and position as
+ * defined in [ISO14496-2], subclause 6.1.3.8, Figure 6-5.
+ * intraDCVLC - a code determined by intra_dc_vlc_thr and QP. This allows a
+ * mechanism to switch between two VLC for coding of Intra DC
+ * coefficients as per [ISO14496-2], Table 6-21.
+ * ACPredFlag - a flag equal to ac_pred_flag (of luminance) indicating if
+ * the ac coefficients of the first row or first column are
+ * differentially coded for intra coded macroblock.
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; shortVideoHeader==1 selects linear intra DC
+ * mode, and shortVideoHeader==0 selects non linear intra DC mode.
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after the block is decoded, so
+ * that it points to the current byte in the bit stream buffer
+ * pBitOffset - *pBitOffset is updated so that it points to the current bit
+ * position in the byte pointed by *ppBitStream
+ * pDst - pointer to the block in the destination plane; must be aligned on
+ * an 8-byte boundary.
+ * pCoefBufRow - pointer to the updated coefficient row buffer.
+ * pCoefBufCol - pointer to the updated coefficient column buffer Note:
+ * The coefficient buffers must be updated in accordance with the
+ * update procedure defined in section 6.2.2.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments, if:
+ * - At least one of the following pointers is NULL:
+ * ppBitStream, *ppBitStream, pBitOffset, pCoefBufRow, pCoefBufCol,
+ * pQPBuf, pDst.
+ * - *pBitOffset exceeds [0,7]
+ * - curQP exceeds (1, 31)
+ * - blockIndex exceeds [0,5]
+ * - step is not the multiple of 8
+ * - a pointer alignment requirement was violated.
+ * OMX_Sts_Err - status error. Refer to OMX_Sts_Err of DecodeVLCZigzag_Intra.
+ *
+ */
+OMXResult omxVCM4P2_DecodeBlockCoef_Intra (
+ const OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ OMX_U8 *pDst,
+ OMX_INT step,
+ OMX_S16 *pCoefBufRow,
+ OMX_S16 *pCoefBufCol,
+ OMX_U8 curQP,
+ const OMX_U8 *pQPBuf,
+ OMX_INT blockIndex,
+ OMX_INT intraDCVLC,
+ OMX_INT ACPredFlag,
+ OMX_INT shortVideoHeader
+);
+
+
+
+/**
+ * Function: omxVCM4P2_DecodeBlockCoef_Inter (6.2.5.4.2)
+ *
+ * Description:
+ * Decodes the INTER block coefficients. This function performs inverse
+ * quantization, inverse zigzag positioning, and IDCT (with appropriate
+ * clipping on each step) on the coefficients. The results (residuals) are
+ * placed in a contiguous array of 64 elements. For INTER block, the output
+ * buffer holds the residuals for further reconstruction.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - pointer to the pointer to the current byte in the bit
+ * stream buffer. There is no boundary check for the bit stream
+ * buffer.
+ * pBitOffset - pointer to the bit position in the byte pointed to by
+ * *ppBitStream. *pBitOffset is valid within [0-7]
+ * QP - quantization parameter
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; shortVideoHeader==1 selects linear intra DC
+ * mode, and shortVideoHeader==0 selects non linear intra DC mode.
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after the block is decoded, so
+ * that it points to the current byte in the bit stream buffer
+ * pBitOffset - *pBitOffset is updated so that it points to the current bit
+ * position in the byte pointed by *ppBitStream
+ * pDst - pointer to the decoded residual buffer (a contiguous array of 64
+ * elements of OMX_S16 data type); must be aligned on a 16-byte
+ * boundary.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments, if:
+ * - At least one of the following pointers is Null:
+ * ppBitStream, *ppBitStream, pBitOffset , pDst
+ * - *pBitOffset exceeds [0,7]
+ * - QP <= 0.
+ * - pDst is not 16-byte aligned
+ * OMX_Sts_Err - status error. Refer to OMX_Sts_Err of DecodeVLCZigzag_Inter .
+ *
+ */
+OMXResult omxVCM4P2_DecodeBlockCoef_Inter (
+ const OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ OMX_S16 *pDst,
+ OMX_INT QP,
+ OMX_INT shortVideoHeader
+);
+
+
+
+/**
+ * Function: omxVCM4P2_PredictReconCoefIntra (6.2.5.4.3)
+ *
+ * Description:
+ * Performs adaptive DC/AC coefficient prediction for an intra block. Prior
+ * to the function call, prediction direction (predDir) should be selected as
+ * specified in [ISO14496-2], subclause 7.4.3.1.
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - pointer to the coefficient buffer which contains the quantized
+ * coefficient residuals (PQF) of the current block; must be
+ * aligned on a 4-byte boundary. The output coefficients are
+ * saturated to the range [-2048, 2047].
+ * pPredBufRow - pointer to the coefficient row buffer; must be aligned on
+ * a 4-byte boundary.
+ * pPredBufCol - pointer to the coefficient column buffer; must be aligned
+ * on a 4-byte boundary.
+ * curQP - quantization parameter of the current block. curQP may equal to
+ * predQP especially when the current block and the predictor block
+ * are in the same macroblock.
+ * predQP - quantization parameter of the predictor block
+ * predDir - indicates the prediction direction which takes one of the
+ * following values: OMX_VC_HORIZONTAL - predict horizontally
+ * OMX_VC_VERTICAL - predict vertically
+ * ACPredFlag - a flag indicating if AC prediction should be performed. It
+ * is equal to ac_pred_flag in the bit stream syntax of MPEG-4
+ * videoComp - video component type (luminance or chrominance) of the
+ * current block
+ *
+ * Output Arguments:
+ *
+ * pSrcDst - pointer to the coefficient buffer which contains the quantized
+ * coefficients (QF) of the current block
+ * pPredBufRow - pointer to the updated coefficient row buffer
+ * pPredBufCol - pointer to the updated coefficient column buffer Note:
+ * Buffer update: Update the AC prediction buffer (both row and
+ * column buffer).
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments, if:
+ * - At least one of the pointers is NULL:
+ * pSrcDst, pPredBufRow, or pPredBufCol.
+ * - curQP <= 0,
+ * - predQP <= 0,
+ * - curQP >31,
+ * - predQP > 31,
+ * - preDir exceeds [1,2]
+ * - pSrcDst, pPredBufRow, or pPredBufCol is not 4-byte aligned.
+ *
+ */
+OMXResult omxVCM4P2_PredictReconCoefIntra (
+ OMX_S16 *pSrcDst,
+ OMX_S16 *pPredBufRow,
+ OMX_S16 *pPredBufCol,
+ OMX_INT curQP,
+ OMX_INT predQP,
+ OMX_INT predDir,
+ OMX_INT ACPredFlag,
+ OMXVCM4P2VideoComponent videoComp
+);
+
+
+
+/**
+ * Function: omxVCM4P2_MCReconBlock (6.2.5.5.1)
+ *
+ * Description:
+ * Performs motion compensation prediction for an 8x8 block using
+ * interpolation described in [ISO14496-2], subclause 7.6.2.
+ *
+ * Input Arguments:
+ *
+ * pSrc - pointer to the block in the reference plane.
+ * srcStep - distance between the start of consecutive lines in the
+ * reference plane, in bytes; must be a multiple of 8.
+ * dstStep - distance between the start of consecutive lines in the
+ * destination plane, in bytes; must be a multiple of 8.
+ * pSrcResidue - pointer to a buffer containing the 16-bit prediction
+ * residuals; must be 16-byte aligned. If the pointer is NULL, then
+ * no prediction is done, only motion compensation, i.e., the block
+ * is moved with interpolation.
+ * predictType - bilinear interpolation type, as defined in section
+ * 6.2.1.2.
+ * rndVal - rounding control parameter: 0 - disabled; 1 - enabled.
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the destination buffer; must be 8-byte aligned. If
+ * prediction residuals are added then output intensities are
+ * clipped to the range [0,255].
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned under any of the following
+ * conditions:
+ * - pDst is not 8-byte aligned.
+ * - pSrcResidue is not 16-byte aligned.
+ * - one or more of the following pointers is NULL: pSrc or pDst.
+ * - either srcStep or dstStep is not a multiple of 8.
+ * - invalid type specified for the parameter predictType.
+ * - the parameter rndVal is not equal either to 0 or 1.
+ *
+ */
+OMXResult omxVCM4P2_MCReconBlock (
+ const OMX_U8 *pSrc,
+ OMX_INT srcStep,
+ const OMX_S16 *pSrcResidue,
+ OMX_U8 *pDst,
+ OMX_INT dstStep,
+ OMX_INT predictType,
+ OMX_INT rndVal
+);
+
+
+
+/* 6.3.1.1 Intra 16x16 Prediction Modes */
+/* A data type that enumerates intra_16x16 macroblock prediction modes is defined as follows: */
+
+typedef enum {
+ OMX_VC_16X16_VERT = 0, /** Intra_16x16_Vertical */
+ OMX_VC_16X16_HOR = 1, /** Intra_16x16_Horizontal */
+ OMX_VC_16X16_DC = 2, /** Intra_16x16_DC */
+ OMX_VC_16X16_PLANE = 3 /** Intra_16x16_Plane */
+} OMXVCM4P10Intra16x16PredMode;
+
+
+
+/* 6.3.1.2 Intra 4x4 Prediction Modes */
+/* A data type that enumerates intra_4x4 macroblock prediction modes is defined as follows: */
+
+typedef enum {
+ OMX_VC_4X4_VERT = 0, /** Intra_4x4_Vertical */
+ OMX_VC_4X4_HOR = 1, /** Intra_4x4_Horizontal */
+ OMX_VC_4X4_DC = 2, /** Intra_4x4_DC */
+ OMX_VC_4X4_DIAG_DL = 3, /** Intra_4x4_Diagonal_Down_Left */
+ OMX_VC_4X4_DIAG_DR = 4, /** Intra_4x4_Diagonal_Down_Right */
+ OMX_VC_4X4_VR = 5, /** Intra_4x4_Vertical_Right */
+ OMX_VC_4X4_HD = 6, /** Intra_4x4_Horizontal_Down */
+ OMX_VC_4X4_VL = 7, /** Intra_4x4_Vertical_Left */
+ OMX_VC_4X4_HU = 8 /** Intra_4x4_Horizontal_Up */
+} OMXVCM4P10Intra4x4PredMode;
+
+
+
+/* 6.3.1.3 Chroma Prediction Modes */
+/* A data type that enumerates intra chroma prediction modes is defined as follows: */
+
+typedef enum {
+ OMX_VC_CHROMA_DC = 0, /** Intra_Chroma_DC */
+ OMX_VC_CHROMA_HOR = 1, /** Intra_Chroma_Horizontal */
+ OMX_VC_CHROMA_VERT = 2, /** Intra_Chroma_Vertical */
+ OMX_VC_CHROMA_PLANE = 3 /** Intra_Chroma_Plane */
+} OMXVCM4P10IntraChromaPredMode;
+
+
+
+/* 6.3.1.4 Motion Estimation Modes */
+/* A data type that enumerates H.264 motion estimation modes is defined as follows: */
+
+typedef enum {
+ OMX_VC_M4P10_FAST_SEARCH = 0, /** Fast motion search */
+ OMX_VC_M4P10_FULL_SEARCH = 1 /** Full motion search */
+} OMXVCM4P10MEMode;
+
+
+
+/* 6.3.1.5 Macroblock Types */
+/* A data type that enumerates H.264 macroblock types is defined as follows: */
+
+typedef enum {
+ OMX_VC_P_16x16 = 0, /* defined by [ISO14496-10] */
+ OMX_VC_P_16x8 = 1,
+ OMX_VC_P_8x16 = 2,
+ OMX_VC_P_8x8 = 3,
+ OMX_VC_PREF0_8x8 = 4,
+ OMX_VC_INTER_SKIP = 5,
+ OMX_VC_INTRA_4x4 = 8,
+ OMX_VC_INTRA_16x16 = 9,
+ OMX_VC_INTRA_PCM = 10
+} OMXVCM4P10MacroblockType;
+
+
+
+/* 6.3.1.6 Sub-Macroblock Types */
+/* A data type that enumerates H.264 sub-macroblock types is defined as follows: */
+
+typedef enum {
+ OMX_VC_SUB_P_8x8 = 0, /* defined by [ISO14496-10] */
+ OMX_VC_SUB_P_8x4 = 1,
+ OMX_VC_SUB_P_4x8 = 2,
+ OMX_VC_SUB_P_4x4 = 3
+} OMXVCM4P10SubMacroblockType;
+
+
+
+/* 6.3.1.7 Variable Length Coding (VLC) Information */
+
+typedef struct {
+ OMX_U8 uTrailing_Ones; /* Trailing ones; 3 at most */
+ OMX_U8 uTrailing_One_Signs; /* Trailing ones signal */
+ OMX_U8 uNumCoeffs; /* Total number of non-zero coefs, including trailing ones */
+ OMX_U8 uTotalZeros; /* Total number of zero coefs */
+ OMX_S16 iLevels[16]; /* Levels of non-zero coefs, in reverse zig-zag order */
+ OMX_U8 uRuns[16]; /* Runs for levels and trailing ones, in reverse zig-zag order */
+} OMXVCM4P10VLCInfo;
+
+
+
+/* 6.3.1.8 Macroblock Information */
+
+typedef struct {
+ OMX_S32 sliceId; /* slice number */
+ OMXVCM4P10MacroblockType mbType; /* MB type */
+ OMXVCM4P10SubMacroblockType subMBType[4]; /* sub-block type */
+ OMX_S32 qpy; /* qp for luma */
+ OMX_S32 qpc; /* qp for chroma */
+ OMX_U32 cbpy; /* CBP Luma */
+ OMX_U32 cbpc; /* CBP Chroma */
+ OMXVCMotionVector pMV0[4][4]; /* motion vector, represented using 1/4-pel units, pMV0[blocky][blockx] (blocky = 0~3, blockx =0~3) */
+ OMXVCMotionVector pMVPred[4][4]; /* motion vector prediction, Represented using 1/4-pel units, pMVPred[blocky][blockx] (blocky = 0~3, blockx = 0~3) */
+ OMX_U8 pRefL0Idx[4]; /* reference picture indices */
+ OMXVCM4P10Intra16x16PredMode Intra16x16PredMode; /* best intra 16x16 prediction mode */
+ OMXVCM4P10Intra4x4PredMode pIntra4x4PredMode[16]; /* best intra 4x4 prediction mode for each block, pMV0 indexed as above */
+} OMXVCM4P10MBInfo, *OMXVCM4P10MBInfoPtr;
+
+
+
+/* 6.3.1.9 Motion Estimation Parameters */
+
+typedef struct {
+ OMX_S32 blockSplitEnable8x8; /* enables 16x8, 8x16, 8x8 */
+ OMX_S32 blockSplitEnable4x4; /* enable splitting of 8x4, 4x8, 4x4 blocks */
+ OMX_S32 halfSearchEnable;
+ OMX_S32 quarterSearchEnable;
+ OMX_S32 intraEnable4x4; /* 1=enable, 0=disable */
+ OMX_S32 searchRange16x16; /* integer pixel units */
+ OMX_S32 searchRange8x8;
+ OMX_S32 searchRange4x4;
+} OMXVCM4P10MEParams;
+
+
+
+/**
+ * Function: omxVCM4P10_PredictIntra_4x4 (6.3.3.1.1)
+ *
+ * Description:
+ * Perform Intra_4x4 prediction for luma samples. If the upper-right block is
+ * not available, then duplication work should be handled inside the function.
+ * Users need not define them outside.
+ *
+ * Input Arguments:
+ *
+ * pSrcLeft - Pointer to the buffer of 4 left pixels:
+ * p[x, y] (x = -1, y = 0..3)
+ * pSrcAbove - Pointer to the buffer of 8 above pixels:
+ * p[x,y] (x = 0..7, y =-1);
+ * must be aligned on a 4-byte boundary.
+ * pSrcAboveLeft - Pointer to the above left pixels: p[x,y] (x = -1, y = -1)
+ * leftStep - Step of left pixel buffer; must be a multiple of 4.
+ * dstStep - Step of the destination buffer; must be a multiple of 4.
+ * predMode - Intra_4x4 prediction mode.
+ * availability - Neighboring 4x4 block availability flag, refer to
+ * "Neighboring Macroblock Availability" .
+ *
+ * Output Arguments:
+ *
+ * pDst - Pointer to the destination buffer; must be aligned on a 4-byte
+ * boundary.
+ *
+ * Return Value:
+ * If the function runs without error, it returns OMX_Sts_NoErr.
+ * If one of the following cases occurs, the function returns
+ * OMX_Sts_BadArgErr:
+ * pDst is NULL.
+ * dstStep < 4, or dstStep is not a multiple of 4.
+ * leftStep is not a multiple of 4.
+ * predMode is not in the valid range of enumeration
+ * OMXVCM4P10Intra4x4PredMode.
+ * predMode is OMX_VC_4x4_VERT, but availability doesn't set OMX_VC_UPPER
+ * indicating p[x,-1] (x = 0..3) is not available.
+ * predMode is OMX_VC_4x4_HOR, but availability doesn't set OMX_VC_LEFT
+ * indicating p[-1,y] (y = 0..3) is not available.
+ * predMode is OMX_VC_4x4_DIAG_DL, but availability doesn't set
+ * OMX_VC_UPPER indicating p[x, -1] (x = 0..3) is not available.
+ * predMode is OMX_VC_4x4_DIAG_DR, but availability doesn't set
+ * OMX_VC_UPPER_LEFT or OMX_VC_UPPER or OMX_VC_LEFT indicating
+ * p[x,-1] (x = 0..3), or p[-1,y] (y = 0..3) or p[-1,-1] is not
+ * available.
+ * predMode is OMX_VC_4x4_VR, but availability doesn't set
+ * OMX_VC_UPPER_LEFT or OMX_VC_UPPER or OMX_VC_LEFT indicating
+ * p[x,-1] (x = 0..3), or p[-1,y] (y = 0..3) or p[-1,-1] is not
+ * available.
+ * predMode is OMX_VC_4x4_HD, but availability doesn't set
+ * OMX_VC_UPPER_LEFT or OMX_VC_UPPER or OMX_VC_LEFT indicating
+ * p[x,-1] (x = 0..3), or p[-1,y] (y = 0..3) or p[-1,-1] is not
+ * available.
+ * predMode is OMX_VC_4x4_VL, but availability doesn't set OMX_VC_UPPER
+ * indicating p[x,-1] (x = 0..3) is not available.
+ * predMode is OMX_VC_4x4_HU, but availability doesn't set OMX_VC_LEFT
+ * indicating p[-1,y] (y = 0..3) is not available.
+ * availability sets OMX_VC_UPPER, but pSrcAbove is NULL.
+ * availability sets OMX_VC_LEFT, but pSrcLeft is NULL.
+ * availability sets OMX_VC_UPPER_LEFT, but pSrcAboveLeft is NULL.
+ * either pSrcAbove or pDst is not aligned on a 4-byte boundary.
+ *
+ * Note:
+ * pSrcAbove, pSrcAbove, pSrcAboveLeft may be invalid pointers if
+ * they are not used by intra prediction as implied in predMode.
+ *
+ */
+OMXResult omxVCM4P10_PredictIntra_4x4 (
+ const OMX_U8 *pSrcLeft,
+ const OMX_U8 *pSrcAbove,
+ const OMX_U8 *pSrcAboveLeft,
+ OMX_U8 *pDst,
+ OMX_INT leftStep,
+ OMX_INT dstStep,
+ OMXVCM4P10Intra4x4PredMode predMode,
+ OMX_S32 availability
+);
+
+
+
+/**
+ * Function: omxVCM4P10_PredictIntra_16x16 (6.3.3.1.2)
+ *
+ * Description:
+ * Perform Intra_16x16 prediction for luma samples. If the upper-right block
+ * is not available, then duplication work should be handled inside the
+ * function. Users need not define them outside.
+ *
+ * Input Arguments:
+ *
+ * pSrcLeft - Pointer to the buffer of 16 left pixels: p[x, y] (x = -1, y =
+ * 0..15)
+ * pSrcAbove - Pointer to the buffer of 16 above pixels: p[x,y] (x = 0..15,
+ * y= -1); must be aligned on a 16-byte boundary.
+ * pSrcAboveLeft - Pointer to the above left pixels: p[x,y] (x = -1, y = -1)
+ * leftStep - Step of left pixel buffer; must be a multiple of 16.
+ * dstStep - Step of the destination buffer; must be a multiple of 16.
+ * predMode - Intra_16x16 prediction mode, please refer to section 3.4.1.
+ * availability - Neighboring 16x16 MB availability flag. Refer to
+ * section 3.4.4.
+ *
+ * Output Arguments:
+ *
+ * pDst -Pointer to the destination buffer; must be aligned on a 16-byte
+ * boundary.
+ *
+ * Return Value:
+ * If the function runs without error, it returns OMX_Sts_NoErr.
+ * If one of the following cases occurs, the function returns
+ * OMX_Sts_BadArgErr:
+ * pDst is NULL.
+ * dstStep < 16. or dstStep is not a multiple of 16.
+ * leftStep is not a multiple of 16.
+ * predMode is not in the valid range of enumeration
+ * OMXVCM4P10Intra16x16PredMode
+ * predMode is OMX_VC_16X16_VERT, but availability doesn't set
+ * OMX_VC_UPPER indicating p[x,-1] (x = 0..15) is not available.
+ * predMode is OMX_VC_16X16_HOR, but availability doesn't set OMX_VC_LEFT
+ * indicating p[-1,y] (y = 0..15) is not available.
+ * predMode is OMX_VC_16X16_PLANE, but availability doesn't set
+ * OMX_VC_UPPER_LEFT or OMX_VC_UPPER or OMX_VC_LEFT indicating
+ * p[x,-1](x = 0..15), or p[-1,y] (y = 0..15), or p[-1,-1] is not
+ * available.
+ * availability sets OMX_VC_UPPER, but pSrcAbove is NULL.
+ * availability sets OMX_VC_LEFT, but pSrcLeft is NULL.
+ * availability sets OMX_VC_UPPER_LEFT, but pSrcAboveLeft is NULL.
+ * either pSrcAbove or pDst is not aligned on a 16-byte boundary.
+ *
+ * Note:
+ * pSrcAbove, pSrcAbove, pSrcAboveLeft may be invalid pointers if
+ * they are not used by intra prediction implied in predMode.
+ * Note:
+ * OMX_VC_UPPER_RIGHT is not used in intra_16x16 luma prediction.
+ *
+ */
+OMXResult omxVCM4P10_PredictIntra_16x16 (
+ const OMX_U8 *pSrcLeft,
+ const OMX_U8 *pSrcAbove,
+ const OMX_U8 *pSrcAboveLeft,
+ OMX_U8 *pDst,
+ OMX_INT leftStep,
+ OMX_INT dstStep,
+ OMXVCM4P10Intra16x16PredMode predMode,
+ OMX_S32 availability
+);
+
+
+
+/**
+ * Function: omxVCM4P10_PredictIntraChroma_8x8 (6.3.3.1.3)
+ *
+ * Description:
+ * Performs intra prediction for chroma samples.
+ *
+ * Input Arguments:
+ *
+ * pSrcLeft - Pointer to the buffer of 8 left pixels: p[x, y] (x = -1, y=
+ * 0..7).
+ * pSrcAbove - Pointer to the buffer of 8 above pixels: p[x,y] (x = 0..7, y
+ * = -1); must be aligned on an 8-byte boundary.
+ * pSrcAboveLeft - Pointer to the above left pixels: p[x,y] (x = -1, y = -1)
+ * leftStep - Step of left pixel buffer; must be a multiple of 8.
+ * dstStep - Step of the destination buffer; must be a multiple of 8.
+ * predMode - Intra chroma prediction mode, please refer to section 3.4.3.
+ * availability - Neighboring chroma block availability flag, please refer
+ * to "Neighboring Macroblock Availability".
+ *
+ * Output Arguments:
+ *
+ * pDst - Pointer to the destination buffer; must be aligned on an 8-byte
+ * boundary.
+ *
+ * Return Value:
+ * If the function runs without error, it returns OMX_Sts_NoErr.
+ * If any of the following cases occurs, the function returns
+ * OMX_Sts_BadArgErr:
+ * pDst is NULL.
+ * dstStep < 8 or dstStep is not a multiple of 8.
+ * leftStep is not a multiple of 8.
+ * predMode is not in the valid range of enumeration
+ * OMXVCM4P10IntraChromaPredMode.
+ * predMode is OMX_VC_CHROMA_VERT, but availability doesn't set
+ * OMX_VC_UPPER indicating p[x,-1] (x = 0..7) is not available.
+ * predMode is OMX_VC_CHROMA_HOR, but availability doesn't set OMX_VC_LEFT
+ * indicating p[-1,y] (y = 0..7) is not available.
+ * predMode is OMX_VC_CHROMA_PLANE, but availability doesn't set
+ * OMX_VC_UPPER_LEFT or OMX_VC_UPPER or OMX_VC_LEFT indicating
+ * p[x,-1](x = 0..7), or p[-1,y] (y = 0..7), or p[-1,-1] is not
+ * available.
+ * availability sets OMX_VC_UPPER, but pSrcAbove is NULL.
+ * availability sets OMX_VC_LEFT, but pSrcLeft is NULL.
+ * availability sets OMX_VC_UPPER_LEFT, but pSrcAboveLeft is NULL.
+ * either pSrcAbove or pDst is not aligned on a 8-byte boundary.
+ *
+ * Note: pSrcAbove, pSrcAbove, pSrcAboveLeft may be invalid pointer if
+ * they are not used by intra prediction implied in predMode.
+ *
+ * Note: OMX_VC_UPPER_RIGHT is not used in intra chroma prediction.
+ *
+ */
+OMXResult omxVCM4P10_PredictIntraChroma_8x8 (
+ const OMX_U8 *pSrcLeft,
+ const OMX_U8 *pSrcAbove,
+ const OMX_U8 *pSrcAboveLeft,
+ OMX_U8 *pDst,
+ OMX_INT leftStep,
+ OMX_INT dstStep,
+ OMXVCM4P10IntraChromaPredMode predMode,
+ OMX_S32 availability
+);
+
+
+
+/**
+ * Function: omxVCM4P10_InterpolateLuma (6.3.3.2.1)
+ *
+ * Description:
+ * Performs quarter-pixel interpolation for inter luma MB. It is assumed that
+ * the frame is already padded when calling this function.
+ *
+ * Input Arguments:
+ *
+ * pSrc - Pointer to the source reference frame buffer
+ * srcStep - reference frame step, in bytes; must be a multiple of roi.width
+ * dstStep - destination frame step, in bytes; must be a multiple of
+ * roi.width
+ * dx - Fractional part of horizontal motion vector component in 1/4 pixel
+ * unit; valid in the range [0,3]
+ * dy - Fractional part of vertical motion vector y component in 1/4 pixel
+ * unit; valid in the range [0,3]
+ * roi - Dimension of the interpolation region; the parameters roi.width and
+ * roi.height must be equal to either 4, 8, or 16.
+ *
+ * Output Arguments:
+ *
+ * pDst - Pointer to the destination frame buffer:
+ * if roi.width==4, 4-byte alignment required
+ * if roi.width==8, 8-byte alignment required
+ * if roi.width==16, 16-byte alignment required
+ *
+ * Return Value:
+ * If the function runs without error, it returns OMX_Sts_NoErr.
+ * If one of the following cases occurs, the function returns
+ * OMX_Sts_BadArgErr:
+ * pSrc or pDst is NULL.
+ * srcStep or dstStep < roi.width.
+ * dx or dy is out of range [0,3].
+ * roi.width or roi.height is out of range {4, 8, 16}.
+ * roi.width is equal to 4, but pDst is not 4 byte aligned.
+ * roi.width is equal to 8 or 16, but pDst is not 8 byte aligned.
+ * srcStep or dstStep is not a multiple of 8.
+ *
+ */
+OMXResult omxVCM4P10_InterpolateLuma (
+ const OMX_U8 *pSrc,
+ OMX_S32 srcStep,
+ OMX_U8 *pDst,
+ OMX_S32 dstStep,
+ OMX_S32 dx,
+ OMX_S32 dy,
+ OMXSize roi
+);
+
+
+
+/**
+ * Function: omxVCM4P10_InterpolateChroma (6.3.3.2.2)
+ *
+ * Description:
+ * Performs 1/8-pixel interpolation for inter chroma MB.
+ *
+ * Input Arguments:
+ *
+ * pSrc -Pointer to the source reference frame buffer
+ * srcStep -Reference frame step in bytes
+ * dstStep -Destination frame step in bytes; must be a multiple of
+ * roi.width.
+ * dx -Fractional part of horizontal motion vector component in 1/8 pixel
+ * unit; valid in the range [0,7]
+ * dy -Fractional part of vertical motion vector component in 1/8 pixel
+ * unit; valid in the range [0,7]
+ * roi -Dimension of the interpolation region; the parameters roi.width and
+ * roi.height must be equal to either 2, 4, or 8.
+ *
+ * Output Arguments:
+ *
+ * pDst -Pointer to the destination frame buffer:
+ * if roi.width==2, 2-byte alignment required
+ * if roi.width==4, 4-byte alignment required
+ * if roi.width==8, 8-byte alignment required
+ *
+ * Return Value:
+ * If the function runs without error, it returns OMX_Sts_NoErr.
+ * If one of the following cases occurs, the function returns
+ * OMX_Sts_BadArgErr:
+ * pSrc or pDst is NULL.
+ * srcStep or dstStep < 8.
+ * dx or dy is out of range [0-7].
+ * roi.width or roi.height is out of range {2,4,8}.
+ * roi.width is equal to 2, but pDst is not 2-byte aligned.
+ * roi.width is equal to 4, but pDst is not 4-byte aligned.
+ * roi.width is equal to 8, but pDst is not 8 byte aligned.
+ * srcStep or dstStep is not a multiple of 8.
+ *
+ */
+OMXResult omxVCM4P10_InterpolateChroma (
+ const OMX_U8 *pSrc,
+ OMX_S32 srcStep,
+ OMX_U8 *pDst,
+ OMX_S32 dstStep,
+ OMX_S32 dx,
+ OMX_S32 dy,
+ OMXSize roi
+);
+
+
+
+/**
+ * Function: omxVCM4P10_FilterDeblockingLuma_VerEdge_I (6.3.3.3.1)
+ *
+ * Description:
+ * Performs in-place deblock filtering on four vertical edges of the luma
+ * macroblock (16x16).
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - Pointer to the input macroblock; must be 16-byte aligned.
+ * srcdstStep -Step of the arrays; must be a multiple of 16.
+ * pAlpha -Array of size 2 of alpha thresholds (the first item is the alpha
+ * threshold for the external vertical edge, and the second item is
+ * for the internal vertical edge); per [ISO14496-10] alpha values
+ * must be in the range [0,255].
+ * pBeta -Array of size 2 of beta thresholds (the first item is the beta
+ * threshold for the external vertical edge, and the second item is
+ * for the internal vertical edge); per [ISO14496-10] beta values
+ * must be in the range [0,18].
+ * pThresholds -Array of size 16 of Thresholds (TC0) (values for the left
+ * edge of each 4x4 block, arranged in vertical block order); must
+ * be aligned on a 4-byte boundary.. Per [ISO14496-10] values must
+ * be in the range [0,25].
+ * pBS -Array of size 16 of BS parameters (arranged in vertical block
+ * order); valid in the range [0,4] with the following
+ * restrictions: i) pBS[i]== 4 may occur only for 0<=i<=3, ii)
+ * pBS[i]== 4 if and only if pBS[i^3]== 4. Must be 4-byte aligned.
+ *
+ * Output Arguments:
+ *
+ * pSrcDst -Pointer to filtered output macroblock.
+ *
+ * Return Value:
+ * If the function runs without error, it returns OMX_Sts_NoErr.
+ * If one of the following cases occurs, the function returns
+ * OMX_Sts_BadArgErr:
+ * Either of the pointers in pSrcDst, pAlpha, pBeta, pThresholds, or pBS
+ * is NULL.
+ * Either pThresholds or pBS is not aligned on a 4-byte boundary.
+ * pSrcDst is not 16-byte aligned.
+ * srcdstStep is not a multiple of 16.
+ * pAlpha[0] and/or pAlpha[1] is outside the range [0,255].
+ * pBeta[0] and/or pBeta[1] is outside the range [0,18].
+ * One or more entries in the table pThresholds[0..15]is outside of the
+ * range [0,25].
+ * pBS is out of range, i.e., one of the following conditions is true:
+ * pBS[i]<0, pBS[i]>4, pBS[i]==4 for i>=4, or (pBS[i]==4 &&
+ * pBS[i^3]!=4) for 0<=i<=3.
+ *
+ */
+OMXResult omxVCM4P10_FilterDeblockingLuma_VerEdge_I (
+ OMX_U8 *pSrcDst,
+ OMX_S32 srcdstStep,
+ const OMX_U8 *pAlpha,
+ const OMX_U8 *pBeta,
+ const OMX_U8 *pThresholds,
+ const OMX_U8 *pBS
+);
+
+
+
+/**
+ * Function: omxVCM4P10_FilterDeblockingLuma_HorEdge_I (6.3.3.3.2)
+ *
+ * Description:
+ * Performs in-place deblock filtering on four horizontal edges of the luma
+ * macroblock (16x16).
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - pointer to the input macroblock; must be 16-byte aligned.
+ * srcdstStep - step of the arrays; must be a multiple of 16.
+ * pAlpha - array of size 2 of alpha thresholds (the first item is the alpha
+ * threshold for the external vertical edge, and the second item is
+ * for the internal horizontal edge); per [ISO14496-10] alpha
+ * values must be in the range [0,255].
+ * pBeta - array of size 2 of beta thresholds (the first item is the beta
+ * threshold for the external horizontal edge, and the second item
+ * is for the internal horizontal edge). Per [ISO14496-10] beta
+ * values must be in the range [0,18].
+ * pThresholds - array of size 16 containing thresholds, TC0, for the top
+ * horizontal edge of each 4x4 block, arranged in horizontal block
+ * order; must be aligned on a 4-byte boundary. Per [ISO14496 10]
+ * values must be in the range [0,25].
+ * pBS - array of size 16 of BS parameters (arranged in horizontal block
+ * order); valid in the range [0,4] with the following
+ * restrictions: i) pBS[i]== 4 may occur only for 0<=i<=3, ii)
+ * pBS[i]== 4 if and only if pBS[i^3]== 4. Must be 4-byte aligned.
+ *
+ * Output Arguments:
+ *
+ * pSrcDst -Pointer to filtered output macroblock.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr, if the function runs without error.
+ *
+ * OMX_Sts_BadArgErr, if one of the following cases occurs:
+ * - one or more of the following pointers is NULL: pSrcDst, pAlpha,
+ * pBeta, pThresholds, or pBS.
+ * - either pThresholds or pBS is not aligned on a 4-byte boundary.
+ * - pSrcDst is not 16-byte aligned.
+ * - srcdstStep is not a multiple of 16.
+ * - pAlpha[0] and/or pAlpha[1] is outside the range [0,255].
+ * - pBeta[0] and/or pBeta[1] is outside the range [0,18].
+ * - One or more entries in the table pThresholds[0..15] is
+ * outside of the range [0,25].
+ * - pBS is out of range, i.e., one of the following conditions is true:
+ * pBS[i]<0, pBS[i]>4, pBS[i]==4 for i>=4, or
+ * (pBS[i]==4 && pBS[i^3]!=4) for 0<=i<=3.
+ *
+ */
+OMXResult omxVCM4P10_FilterDeblockingLuma_HorEdge_I (
+ OMX_U8 *pSrcDst,
+ OMX_S32 srcdstStep,
+ const OMX_U8 *pAlpha,
+ const OMX_U8 *pBeta,
+ const OMX_U8 *pThresholds,
+ const OMX_U8 *pBS
+);
+
+
+
+/**
+ * Function: omxVCM4P10_FilterDeblockingChroma_VerEdge_I (6.3.3.3.3)
+ *
+ * Description:
+ * Performs in-place deblock filtering on four vertical edges of the chroma
+ * macroblock (8x8).
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - Pointer to the input macroblock; must be 8-byte aligned.
+ * srcdstStep - Step of the arrays; must be a multiple of 8.
+ * pAlpha - Array of size 2 of alpha thresholds (the first item is alpha
+ * threshold for external vertical edge, and the second item is for
+ * internal vertical edge); per [ISO14496-10] alpha values must be
+ * in the range [0,255].
+ * pBeta - Array of size 2 of beta thresholds (the first item is the beta
+ * threshold for the external vertical edge, and the second item is
+ * for the internal vertical edge); per [ISO14496-10] beta values
+ * must be in the range [0,18].
+ * pThresholds - Array of size 8 containing thresholds, TC0, for the left
+ * vertical edge of each 4x2 chroma block, arranged in vertical
+ * block order; must be aligned on a 4-byte boundary. Per
+ * [ISO14496-10] values must be in the range [0,25].
+ * pBS - Array of size 16 of BS parameters (values for each 2x2 chroma
+ * block, arranged in vertical block order). This parameter is the
+ * same as the pBS parameter passed into FilterDeblockLuma_VerEdge;
+ * valid in the range [0,4] with the following restrictions: i)
+ * pBS[i]== 4 may occur only for 0<=i<=3, ii) pBS[i]== 4 if and
+ * only if pBS[i^3]== 4. Must be 4 byte aligned.
+ *
+ * Output Arguments:
+ *
+ * pSrcDst -Pointer to filtered output macroblock.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr, if the function runs without error.
+ *
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - one or more of the following pointers is NULL: pSrcDst, pAlpha,
+ * pBeta, pThresholds, or pBS.
+ * - pSrcDst is not 8-byte aligned.
+ * - srcdstStep is not a multiple of 8.
+ * - pThresholds is not 4-byte aligned.
+ * - pAlpha[0] and/or pAlpha[1] is outside the range [0,255].
+ * - pBeta[0] and/or pBeta[1] is outside the range [0,18].
+ * - One or more entries in the table pThresholds[0..7] is outside
+ * of the range [0,25].
+ * - pBS is out of range, i.e., one of the following conditions is true:
+ * pBS[i]<0, pBS[i]>4, pBS[i]==4 for i>=4, or
+ * (pBS[i]==4 && pBS[i^3]!=4) for 0<=i<=3.
+ * - pBS is not 4-byte aligned.
+ *
+ */
+OMXResult omxVCM4P10_FilterDeblockingChroma_VerEdge_I (
+ OMX_U8 *pSrcDst,
+ OMX_S32 srcdstStep,
+ const OMX_U8 *pAlpha,
+ const OMX_U8 *pBeta,
+ const OMX_U8 *pThresholds,
+ const OMX_U8 *pBS
+);
+
+
+
+/**
+ * Function: omxVCM4P10_FilterDeblockingChroma_HorEdge_I (6.3.3.3.4)
+ *
+ * Description:
+ * Performs in-place deblock filtering on the horizontal edges of the chroma
+ * macroblock (8x8).
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - pointer to the input macroblock; must be 8-byte aligned.
+ * srcdstStep - array step; must be a multiple of 8.
+ * pAlpha - array of size 2 containing alpha thresholds; the first element
+ * contains the threshold for the external horizontal edge, and the
+ * second element contains the threshold for internal horizontal
+ * edge. Per [ISO14496-10] alpha values must be in the range
+ * [0,255].
+ * pBeta - array of size 2 containing beta thresholds; the first element
+ * contains the threshold for the external horizontal edge, and the
+ * second element contains the threshold for the internal
+ * horizontal edge. Per [ISO14496-10] beta values must be in the
+ * range [0,18].
+ * pThresholds - array of size 8 containing thresholds, TC0, for the top
+ * horizontal edge of each 2x4 chroma block, arranged in horizontal
+ * block order; must be aligned on a 4-byte boundary. Per
+ * [ISO14496-10] values must be in the range [0,25].
+ * pBS - array of size 16 containing BS parameters for each 2x2 chroma
+ * block, arranged in horizontal block order; valid in the range
+ * [0,4] with the following restrictions: i) pBS[i]== 4 may occur
+ * only for 0<=i<=3, ii) pBS[i]== 4 if and only if pBS[i^3]== 4.
+ * Must be 4-byte aligned.
+ *
+ * Output Arguments:
+ *
+ * pSrcDst -Pointer to filtered output macroblock.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr, if the function runs without error.
+ *
+ * OMX_Sts_BadArgErr, if one of the following cases occurs:
+ * - any of the following pointers is NULL:
+ * pSrcDst, pAlpha, pBeta, pThresholds, or pBS.
+ * - pSrcDst is not 8-byte aligned.
+ * - srcdstStep is not a multiple of 8.
+ * - pThresholds is not 4-byte aligned.
+ * - pAlpha[0] and/or pAlpha[1] is outside the range [0,255].
+ * - pBeta[0] and/or pBeta[1] is outside the range [0,18].
+ * - One or more entries in the table pThresholds[0..7] is outside
+ * of the range [0,25].
+ * - pBS is out of range, i.e., one of the following conditions is true:
+ * pBS[i]<0, pBS[i]>4, pBS[i]==4 for i>=4, or
+ * (pBS[i]==4 && pBS[i^3]!=4) for 0<=i<=3.
+ * - pBS is not 4-byte aligned.
+ *
+ */
+OMXResult omxVCM4P10_FilterDeblockingChroma_HorEdge_I (
+ OMX_U8 *pSrcDst,
+ OMX_S32 srcdstStep,
+ const OMX_U8 *pAlpha,
+ const OMX_U8 *pBeta,
+ const OMX_U8 *pThresholds,
+ const OMX_U8 *pBS
+);
+
+
+
+/**
+ * Function: omxVCM4P10_DeblockLuma_I (6.3.3.3.5)
+ *
+ * Description:
+ * This function performs in-place deblock filtering the horizontal and
+ * vertical edges of a luma macroblock (16x16).
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - pointer to the input macroblock; must be 16-byte aligned.
+ * srcdstStep - image width; must be a multiple of 16.
+ * pAlpha - pointer to a 2x2 table of alpha thresholds, organized as
+ * follows: {external vertical edge, internal vertical edge,
+ * external horizontal edge, internal horizontal edge }. Per
+ * [ISO14496-10] alpha values must be in the range [0,255].
+ * pBeta - pointer to a 2x2 table of beta thresholds, organized as follows:
+ * {external vertical edge, internal vertical edge, external
+ * horizontal edge, internal horizontal edge }. Per [ISO14496-10]
+ * beta values must be in the range [0,18].
+ * pThresholds - pointer to a 16x2 table of threshold (TC0), organized as
+ * follows: {values for the left or above edge of each 4x4 block,
+ * arranged in vertical block order and then in horizontal block
+ * order}; must be aligned on a 4-byte boundary. Per [ISO14496-10]
+ * values must be in the range [0,25].
+ * pBS - pointer to a 16x2 table of BS parameters arranged in scan block
+ * order for vertical edges and then horizontal edges; valid in the
+ * range [0,4] with the following restrictions: i) pBS[i]== 4 may
+ * occur only for 0<=i<=3, ii) pBS[i]== 4 if and only if pBS[i^3]==
+ * 4. Must be 4-byte aligned.
+ *
+ * Output Arguments:
+ *
+ * pSrcDst - pointer to filtered output macroblock.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments
+ * - one or more of the following pointers is NULL: pSrcDst, pAlpha,
+ * pBeta, pThresholds or pBS.
+ * - pSrcDst is not 16-byte aligned.
+ * - either pThresholds or pBS is not aligned on a 4-byte boundary.
+ * - one or more entries in the table pAlpha[0..3] is outside the range
+ * [0,255].
+ * - one or more entries in the table pBeta[0..3] is outside the range
+ * [0,18].
+ * - one or more entries in the table pThresholds[0..31]is outside of
+ * the range [0,25].
+ * - pBS is out of range, i.e., one of the following conditions is true:
+ * pBS[i]<0, pBS[i]>4, pBS[i]==4 for i>=4, or
+ * (pBS[i]==4 && pBS[i^3]!=4) for 0<=i<=3.
+ * - srcdstStep is not a multiple of 16.
+ *
+ */
+OMXResult omxVCM4P10_DeblockLuma_I (
+ OMX_U8 *pSrcDst,
+ OMX_S32 srcdstStep,
+ const OMX_U8 *pAlpha,
+ const OMX_U8 *pBeta,
+ const OMX_U8 *pThresholds,
+ const OMX_U8 *pBS
+);
+
+
+
+/**
+ * Function: omxVCM4P10_DeblockChroma_I (6.3.3.3.6)
+ *
+ * Description:
+ * Performs in-place deblocking filtering on all edges of the chroma
+ * macroblock (16x16).
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - pointer to the input macroblock; must be 8-byte aligned.
+ * srcdstStep - step of the arrays; must be a multiple of 8.
+ * pAlpha - pointer to a 2x2 array of alpha thresholds, organized as
+ * follows: {external vertical edge, internal vertical edge,
+ * external horizontal edge, internal horizontal edge }. Per
+ * [ISO14496-10] alpha values must be in the range [0,255].
+ * pBeta - pointer to a 2x2 array of Beta Thresholds, organized as follows:
+ * { external vertical edge, internal vertical edge, external
+ * horizontal edge, internal horizontal edge }. Per [ISO14496-10]
+ * beta values must be in the range [0,18].
+ * pThresholds - array of size 8x2 of Thresholds (TC0) (values for the left
+ * or above edge of each 4x2 or 2x4 block, arranged in vertical
+ * block order and then in horizontal block order); must be aligned
+ * on a 4-byte boundary. Per [ISO14496-10] values must be in the
+ * range [0,25].
+ * pBS - array of size 16x2 of BS parameters (arranged in scan block order
+ * for vertical edges and then horizontal edges); valid in the
+ * range [0,4] with the following restrictions: i) pBS[i]== 4 may
+ * occur only for 0<=i<=3, ii) pBS[i]== 4 if and only if pBS[i^3]==
+ * 4. Must be 4-byte aligned.
+ *
+ * Output Arguments:
+ *
+ * pSrcDst - pointer to filtered output macroblock.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments
+ * - one or more of the following pointers is NULL: pSrcDst, pAlpha,
+ * pBeta, pThresholds, or pBS.
+ * - pSrcDst is not 8-byte aligned.
+ * - either pThresholds or pBS is not 4-byte aligned.
+ * - one or more entries in the table pAlpha[0..3] is outside the range
+ * [0,255].
+ * - one or more entries in the table pBeta[0..3] is outside the range
+ * [0,18].
+ * - one or more entries in the table pThresholds[0..15]is outside of
+ * the range [0,25].
+ * - pBS is out of range, i.e., one of the following conditions is true:
+ * pBS[i]<0, pBS[i]>4, pBS[i]==4 for i>=4, or
+ * (pBS[i]==4 && pBS[i^3]!=4) for 0<=i<=3.
+ * - srcdstStep is not a multiple of 8.
+ *
+ */
+OMXResult omxVCM4P10_DeblockChroma_I (
+ OMX_U8 *pSrcDst,
+ OMX_S32 srcdstStep,
+ const OMX_U8 *pAlpha,
+ const OMX_U8 *pBeta,
+ const OMX_U8 *pThresholds,
+ const OMX_U8 *pBS
+);
+
+
+
+/**
+ * Function: omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC (6.3.4.1.1)
+ *
+ * Description:
+ * Performs CAVLC decoding and inverse raster scan for a 2x2 block of
+ * ChromaDCLevel. The decoded coefficients in the packed position-coefficient
+ * buffer are stored in reverse zig-zag order, i.e., the first buffer element
+ * contains the last non-zero postion-coefficient pair of the block. Within
+ * each position-coefficient pair, the position entry indicates the
+ * raster-scan position of the coefficient, while the coefficient entry
+ * contains the coefficient value.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - Double pointer to current byte in bit stream buffer
+ * pOffset - Pointer to current bit position in the byte pointed to by
+ * *ppBitStream; valid in the range [0,7].
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after each block is decoded
+ * pOffset - *pOffset is updated after each block is decoded
+ * pNumCoeff - Pointer to the number of nonzero coefficients in this block
+ * ppPosCoefBuf - Double pointer to destination residual
+ * coefficient-position pair buffer. Buffer position
+ * (*ppPosCoefBuf) is updated upon return, unless there are only
+ * zero coefficients in the currently decoded block. In this case
+ * the caller is expected to bypass the transform/dequantization of
+ * the empty blocks.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr, if the function runs without error.
+ *
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - ppBitStream or pOffset is NULL.
+ * - ppPosCoefBuf or pNumCoeff is NULL.
+ * OMX_Sts_Err - if one of the following is true:
+ * - an illegal code is encountered in the bitstream
+ *
+ */
+OMXResult omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC (
+ const OMX_U8 **ppBitStream,
+ OMX_S32*pOffset,
+ OMX_U8 *pNumCoeff,
+ OMX_U8 **ppPosCoefbuf
+);
+
+
+
+/**
+ * Function: omxVCM4P10_DecodeCoeffsToPairCAVLC (6.3.4.1.2)
+ *
+ * Description:
+ * Performs CAVLC decoding and inverse zigzag scan for 4x4 block of
+ * Intra16x16DCLevel, Intra16x16ACLevel, LumaLevel, and ChromaACLevel. Inverse
+ * field scan is not supported. The decoded coefficients in the packed
+ * position-coefficient buffer are stored in reverse zig-zag order, i.e., the
+ * first buffer element contains the last non-zero postion-coefficient pair of
+ * the block. Within each position-coefficient pair, the position entry
+ * indicates the raster-scan position of the coefficient, while the
+ * coefficient entry contains the coefficient value.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream -Double pointer to current byte in bit stream buffer
+ * pOffset - Pointer to current bit position in the byte pointed to by
+ * *ppBitStream; valid in the range [0,7].
+ * sMaxNumCoeff - Maximum the number of non-zero coefficients in current
+ * block
+ * sVLCSelect - VLC table selector, obtained from the number of non-zero
+ * coefficients contained in the above and left 4x4 blocks. It is
+ * equivalent to the variable nC described in H.264 standard table
+ * 9 5, except its value can t be less than zero.
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after each block is decoded.
+ * Buffer position (*ppPosCoefBuf) is updated upon return, unless
+ * there are only zero coefficients in the currently decoded block.
+ * In this case the caller is expected to bypass the
+ * transform/dequantization of the empty blocks.
+ * pOffset - *pOffset is updated after each block is decoded
+ * pNumCoeff - Pointer to the number of nonzero coefficients in this block
+ * ppPosCoefBuf - Double pointer to destination residual
+ * coefficient-position pair buffer
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ *
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - ppBitStream or pOffset is NULL.
+ * - ppPosCoefBuf or pNumCoeff is NULL.
+ * - sMaxNumCoeff is not equal to either 15 or 16.
+ * - sVLCSelect is less than 0.
+ *
+ * OMX_Sts_Err - if one of the following is true:
+ * - an illegal code is encountered in the bitstream
+ *
+ */
+OMXResult omxVCM4P10_DecodeCoeffsToPairCAVLC (
+ const OMX_U8 **ppBitStream,
+ OMX_S32 *pOffset,
+ OMX_U8 *pNumCoeff,
+ OMX_U8 **ppPosCoefbuf,
+ OMX_INT sVLCSelect,
+ OMX_INT sMaxNumCoeff
+);
+
+
+
+/**
+ * Function: omxVCM4P10_TransformDequantLumaDCFromPair (6.3.4.2.1)
+ *
+ * Description:
+ * Reconstructs the 4x4 LumaDC block from the coefficient-position pair
+ * buffer, performs integer inverse, and dequantization for 4x4 LumaDC
+ * coefficients, and updates the pair buffer pointer to the next non-empty
+ * block.
+ *
+ * Input Arguments:
+ *
+ * ppSrc - Double pointer to residual coefficient-position pair buffer
+ * output by CALVC decoding
+ * QP - Quantization parameter QpY
+ *
+ * Output Arguments:
+ *
+ * ppSrc - *ppSrc is updated to the start of next non empty block
+ * pDst - Pointer to the reconstructed 4x4 LumaDC coefficients buffer; must
+ * be aligned on a 8-byte boundary.
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - ppSrc or pDst is NULL.
+ * - pDst is not 8 byte aligned.
+ * - QP is not in the range of [0-51].
+ *
+ */
+OMXResult omxVCM4P10_TransformDequantLumaDCFromPair (
+ const OMX_U8 **ppSrc,
+ OMX_S16 *pDst,
+ OMX_INT QP
+);
+
+
+
+/**
+ * Function: omxVCM4P10_TransformDequantChromaDCFromPair (6.3.4.2.2)
+ *
+ * Description:
+ * Reconstruct the 2x2 ChromaDC block from coefficient-position pair buffer,
+ * perform integer inverse transformation, and dequantization for 2x2 chroma
+ * DC coefficients, and update the pair buffer pointer to next non-empty
+ * block.
+ *
+ * Input Arguments:
+ *
+ * ppSrc - Double pointer to residual coefficient-position pair buffer
+ * output by CALVC decoding
+ * QP - Quantization parameter QpC
+ *
+ * Output Arguments:
+ *
+ * ppSrc - *ppSrc is updated to the start of next non empty block
+ * pDst - Pointer to the reconstructed 2x2 ChromaDC coefficients buffer;
+ * must be aligned on a 4-byte boundary.
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - ppSrc or pDst is NULL.
+ * - pDst is not 4-byte aligned.
+ * - QP is not in the range of [0-51].
+ *
+ */
+OMXResult omxVCM4P10_TransformDequantChromaDCFromPair (
+ const OMX_U8 **ppSrc,
+ OMX_S16 *pDst,
+ OMX_INT QP
+);
+
+
+
+/**
+ * Function: omxVCM4P10_DequantTransformResidualFromPairAndAdd (6.3.4.2.3)
+ *
+ * Description:
+ * Reconstruct the 4x4 residual block from coefficient-position pair buffer,
+ * perform dequantization and integer inverse transformation for 4x4 block of
+ * residuals with previous intra prediction or motion compensation data, and
+ * update the pair buffer pointer to next non-empty block. If pDC == NULL,
+ * there re 16 non-zero AC coefficients at most in the packed buffer starting
+ * from 4x4 block position 0; If pDC != NULL, there re 15 non-zero AC
+ * coefficients at most in the packet buffer starting from 4x4 block position
+ * 1.
+ *
+ * Input Arguments:
+ *
+ * ppSrc - Double pointer to residual coefficient-position pair buffer
+ * output by CALVC decoding
+ * pPred - Pointer to the predicted 4x4 block; must be aligned on a 4-byte
+ * boundary
+ * predStep - Predicted frame step size in bytes; must be a multiple of 4
+ * dstStep - Destination frame step in bytes; must be a multiple of 4
+ * pDC - Pointer to the DC coefficient of this block, NULL if it doesn't
+ * exist
+ * QP - QP Quantization parameter. It should be QpC in chroma 4x4 block
+ * decoding, otherwise it should be QpY.
+ * AC - Flag indicating if at least one non-zero AC coefficient exists
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the reconstructed 4x4 block data; must be aligned on a
+ * 4-byte boundary
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - pPred or pDst is NULL.
+ * - pPred or pDst is not 4-byte aligned.
+ * - predStep or dstStep is not a multiple of 4.
+ * - AC !=0 and Qp is not in the range of [0-51] or ppSrc == NULL.
+ * - AC ==0 && pDC ==NULL.
+ *
+ */
+OMXResult omxVCM4P10_DequantTransformResidualFromPairAndAdd (
+ const OMX_U8 **ppSrc,
+ const OMX_U8 *pPred,
+ const OMX_S16 *pDC,
+ OMX_U8 *pDst,
+ OMX_INT predStep,
+ OMX_INT dstStep,
+ OMX_INT QP,
+ OMX_INT AC
+);
+
+
+
+/**
+ * Function: omxVCM4P10_MEGetBufSize (6.3.5.1.1)
+ *
+ * Description:
+ * Computes the size, in bytes, of the vendor-specific specification
+ * structure for the omxVCM4P10 motion estimation functions BlockMatch_Integer
+ * and MotionEstimationMB.
+ *
+ * Input Arguments:
+ *
+ * MEmode - motion estimation mode; available modes are defined by the
+ * enumerated type OMXVCM4P10MEMode
+ * pMEParams -motion estimation parameters
+ *
+ * Output Arguments:
+ *
+ * pSize - pointer to the number of bytes required for the motion
+ * estimation specification structure
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - pMEParams or pSize is NULL.
+ * - an invalid MEMode is specified.
+ *
+ */
+OMXResult omxVCM4P10_MEGetBufSize (
+ OMXVCM4P10MEMode MEmode,
+ const OMXVCM4P10MEParams *pMEParams,
+ OMX_U32 *pSize
+);
+
+
+
+/**
+ * Function: omxVCM4P10_MEInit (6.3.5.1.2)
+ *
+ * Description:
+ * Initializes the vendor-specific specification structure required for the
+ * omxVCM4P10 motion estimation functions: BlockMatch_Integer and
+ * MotionEstimationMB. Memory for the specification structure *pMESpec must be
+ * allocated prior to calling the function, and should be aligned on a 4-byte
+ * boundary. The number of bytes required for the specification structure can
+ * be determined using the function omxVCM4P10_MEGetBufSize. Following
+ * initialization by this function, the vendor-specific structure *pMESpec
+ * should contain an implementation-specific representation of all motion
+ * estimation parameters received via the structure pMEParams, for example
+ * searchRange16x16, searchRange8x8, etc.
+ *
+ * Input Arguments:
+ *
+ * MEmode - motion estimation mode; available modes are defined by the
+ * enumerated type OMXVCM4P10MEMode
+ * pMEParams - motion estimation parameters
+ * pMESpec - pointer to the uninitialized ME specification structure
+ *
+ * Output Arguments:
+ *
+ * pMESpec - pointer to the initialized ME specification structure
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - pMEParams or pSize is NULL.
+ * - an invalid value was specified for the parameter MEmode
+ * - a negative or zero value was specified for one of the search ranges
+ * (e.g., pMBParams >searchRange8x8, pMEParams->searchRange16x16, etc.)
+ * - either in isolation or in combination, one or more of the enables or
+ * search ranges in the structure *pMEParams were configured such
+ * that the requested behavior fails to comply with [ISO14496-10].
+ *
+ */
+OMXResult omxVCM4P10_MEInit (
+ OMXVCM4P10MEMode MEmode,
+ const OMXVCM4P10MEParams *pMEParams,
+ void *pMESpec
+);
+
+
+
+/**
+ * Function: omxVCM4P10_BlockMatch_Integer (6.3.5.2.1)
+ *
+ * Description:
+ * Performs integer block match. Returns best MV and associated cost.
+ *
+ * Input Arguments:
+ *
+ * pSrcOrgY - Pointer to the top-left corner of the current block:
+ * If iBlockWidth==4, 4-byte alignment required.
+ * If iBlockWidth==8, 8-byte alignment required.
+ * If iBlockWidth==16, 16-byte alignment required.
+ * pSrcRefY - Pointer to the top-left corner of the co-located block in the
+ * reference picture:
+ * If iBlockWidth==4, 4-byte alignment required.
+ * If iBlockWidth==8, 8-byte alignment required.
+ * If iBlockWidth==16, 16-byte alignment required.
+ * nSrcOrgStep - Stride of the original picture plane, expressed in terms
+ * of integer pixels; must be a multiple of iBlockWidth.
+ * nSrcRefStep - Stride of the reference picture plane, expressed in terms
+ * of integer pixels
+ * pRefRect - pointer to the valid reference rectangle inside the reference
+ * picture plane
+ * nCurrPointPos - position of the current block in the current plane
+ * iBlockWidth - Width of the current block, expressed in terms of integer
+ * pixels; must be equal to either 4, 8, or 16.
+ * iBlockHeight - Height of the current block, expressed in terms of
+ * integer pixels; must be equal to either 4, 8, or 16.
+ * nLamda - Lamda factor; used to compute motion cost
+ * pMVPred - Predicted MV; used to compute motion cost, expressed in terms
+ * of 1/4-pel units
+ * pMVCandidate - Candidate MV; used to initialize the motion search,
+ * expressed in terms of integer pixels
+ * pMESpec - pointer to the ME specification structure
+ *
+ * Output Arguments:
+ *
+ * pDstBestMV - Best MV resulting from integer search, expressed in terms
+ * of 1/4-pel units
+ * pBestCost - Motion cost associated with the best MV; computed as
+ * SAD+Lamda*BitsUsedByMV
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - any of the following pointers are NULL:
+ * pSrcOrgY, pSrcRefY, pRefRect, pMVPred, pMVCandidate, or pMESpec.
+ * - Either iBlockWidth or iBlockHeight are values other than 4, 8, or 16.
+ * - Any alignment restrictions are violated
+ *
+ */
+OMXResult omxVCM4P10_BlockMatch_Integer (
+ const OMX_U8 *pSrcOrgY,
+ OMX_S32 nSrcOrgStep,
+ const OMX_U8 *pSrcRefY,
+ OMX_S32 nSrcRefStep,
+ const OMXRect *pRefRect,
+ const OMXVCM4P2Coordinate *pCurrPointPos,
+ OMX_U8 iBlockWidth,
+ OMX_U8 iBlockHeight,
+ OMX_U32 nLamda,
+ const OMXVCMotionVector *pMVPred,
+ const OMXVCMotionVector *pMVCandidate,
+ OMXVCMotionVector *pBestMV,
+ OMX_S32 *pBestCost,
+ void *pMESpec
+);
+
+
+
+/**
+ * Function: omxVCM4P10_BlockMatch_Half (6.3.5.2.2)
+ *
+ * Description:
+ * Performs a half-pel block match using results from a prior integer search.
+ * Returns the best MV and associated cost. This function estimates the
+ * half-pixel motion vector by interpolating the integer resolution motion
+ * vector referenced by the input parameter pSrcDstBestMV, i.e., the initial
+ * integer MV is generated externally. The function
+ * omxVCM4P10_BlockMatch_Integer may be used for integer motion estimation.
+ *
+ * Input Arguments:
+ *
+ * pSrcOrgY - Pointer to the current position in original picture plane:
+ * If iBlockWidth==4, 4-byte alignment required.
+ * If iBlockWidth==8, 8-byte alignment required.
+ * If iBlockWidth==16, 16-byte alignment required.
+ * pSrcRefY - Pointer to the top-left corner of the co-located block in the
+ * reference picture:
+ * If iBlockWidth==4, 4-byte alignment required.
+ * If iBlockWidth==8, 8-byte alignment required.
+ * If iBlockWidth==16, 16-byte alignment required.
+ * nSrcOrgStep - Stride of the original picture plane in terms of full
+ * pixels; must be a multiple of iBlockWidth.
+ * nSrcRefStep - Stride of the reference picture plane in terms of full
+ * pixels
+ * iBlockWidth - Width of the current block in terms of full pixels; must
+ * be equal to either 4, 8, or 16.
+ * iBlockHeight - Height of the current block in terms of full pixels; must
+ * be equal to either 4, 8, or 16.
+ * nLamda - Lamda factor, used to compute motion cost
+ * pMVPred - Predicted MV, represented in terms of 1/4-pel units; used to
+ * compute motion cost
+ * pSrcDstBestMV - The best MV resulting from a prior integer search,
+ * represented in terms of 1/4-pel units
+ *
+ * Output Arguments:
+ *
+ * pSrcDstBestMV - Best MV resulting from the half-pel search, expressed in
+ * terms of 1/4-pel units
+ * pBestCost - Motion cost associated with the best MV; computed as
+ * SAD+Lamda*BitsUsedByMV
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - any of the following pointers is NULL: pSrcOrgY, pSrcRefY,
+ * pSrcDstBestMV, pMVPred, pBestCost
+ * - iBlockWidth or iBlockHeight are equal to values other than 4, 8, or 16.
+ * - Any alignment restrictions are violated
+ *
+ */
+OMXResult omxVCM4P10_BlockMatch_Half (
+ const OMX_U8 *pSrcOrgY,
+ OMX_S32 nSrcOrgStep,
+ const OMX_U8 *pSrcRefY,
+ OMX_S32 nSrcRefStep,
+ OMX_U8 iBlockWidth,
+ OMX_U8 iBlockHeight,
+ OMX_U32 nLamda,
+ const OMXVCMotionVector *pMVPred,
+ OMXVCMotionVector *pSrcDstBestMV,
+ OMX_S32 *pBestCost
+);
+
+
+
+/**
+ * Function: omxVCM4P10_BlockMatch_Quarter (6.3.5.2.3)
+ *
+ * Description:
+ * Performs a quarter-pel block match using results from a prior half-pel
+ * search. Returns the best MV and associated cost. This function estimates
+ * the quarter-pixel motion vector by interpolating the half-pel resolution
+ * motion vector referenced by the input parameter pSrcDstBestMV, i.e., the
+ * initial half-pel MV is generated externally. The function
+ * omxVCM4P10_BlockMatch_Half may be used for half-pel motion estimation.
+ *
+ * Input Arguments:
+ *
+ * pSrcOrgY - Pointer to the current position in original picture plane:
+ * If iBlockWidth==4, 4-byte alignment required.
+ * If iBlockWidth==8, 8-byte alignment required.
+ * If iBlockWidth==16, 16-byte alignment required.
+ * pSrcRefY - Pointer to the top-left corner of the co-located block in the
+ * reference picture:
+ * If iBlockWidth==4, 4-byte alignment required.
+ * If iBlockWidth==8, 8-byte alignment required.
+ * If iBlockWidth==16, 16-byte alignment required.
+ * nSrcOrgStep - Stride of the original picture plane in terms of full
+ * pixels; must be a multiple of iBlockWidth.
+ * nSrcRefStep - Stride of the reference picture plane in terms of full
+ * pixels
+ * iBlockWidth - Width of the current block in terms of full pixels; must
+ * be equal to either 4, 8, or 16.
+ * iBlockHeight - Height of the current block in terms of full pixels; must
+ * be equal to either 4, 8, or 16.
+ * nLamda - Lamda factor, used to compute motion cost
+ * pMVPred - Predicted MV, represented in terms of 1/4-pel units; used to
+ * compute motion cost
+ * pSrcDstBestMV - The best MV resulting from a prior half-pel search,
+ * represented in terms of 1/4 pel units
+ *
+ * Output Arguments:
+ *
+ * pSrcDstBestMV - Best MV resulting from the quarter-pel search, expressed
+ * in terms of 1/4-pel units
+ * pBestCost - Motion cost associated with the best MV; computed as
+ * SAD+Lamda*BitsUsedByMV
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - One or more of the following pointers is NULL:
+ * pSrcOrgY, pSrcRefY, pSrcDstBestMV, pMVPred, pBestCost
+ * - iBlockWidth or iBlockHeight are equal to values other than 4, 8, or 16.
+ * - Any alignment restrictions are violated
+ *
+ */
+OMXResult omxVCM4P10_BlockMatch_Quarter (
+ const OMX_U8 *pSrcOrgY,
+ OMX_S32 nSrcOrgStep,
+ const OMX_U8 *pSrcRefY,
+ OMX_S32 nSrcRefStep,
+ OMX_U8 iBlockWidth,
+ OMX_U8 iBlockHeight,
+ OMX_U32 nLamda,
+ const OMXVCMotionVector *pMVPred,
+ OMXVCMotionVector *pSrcDstBestMV,
+ OMX_S32 *pBestCost
+);
+
+
+
+/**
+ * Function: omxVCM4P10_MotionEstimationMB (6.3.5.3.1)
+ *
+ * Description:
+ * Performs MB-level motion estimation and selects best motion estimation
+ * strategy from the set of modes supported in baseline profile [ISO14496-10].
+ *
+ * Input Arguments:
+ *
+ * pSrcCurrBuf - Pointer to the current position in original picture plane;
+ * 16-byte alignment required
+ * pSrcRefBufList - Pointer to an array with 16 entries. Each entry points
+ * to the top-left corner of the co-located MB in a reference
+ * picture. The array is filled from low-to-high with valid
+ * reference frame pointers; the unused high entries should be set
+ * to NULL. Ordering of the reference frames should follow
+ * [ISO14496-10] subclause 8.2.4 Decoding Process for Reference
+ * Picture Lists. The entries must be 16-byte aligned.
+ * pSrcRecBuf - Pointer to the top-left corner of the co-located MB in the
+ * reconstructed picture; must be 16-byte aligned.
+ * SrcCurrStep - Width of the original picture plane in terms of full
+ * pixels; must be a multiple of 16.
+ * SrcRefStep - Width of the reference picture plane in terms of full
+ * pixels; must be a multiple of 16.
+ * SrcRecStep - Width of the reconstructed picture plane in terms of full
+ * pixels; must be a multiple of 16.
+ * pRefRect - Pointer to the valid reference rectangle; relative to the
+ * image origin.
+ * pCurrPointPos - Position of the current macroblock in the current plane.
+ * Lambda - Lagrange factor for computing the cost function
+ * pMESpec - Pointer to the motion estimation specification structure; must
+ * have been allocated and initialized prior to calling this
+ * function.
+ * pMBInter - Array, of dimension four, containing pointers to information
+ * associated with four adjacent type INTER MBs (Left, Top,
+ * Top-Left, Top-Right). Any pointer in the array may be set equal
+ * to NULL if the corresponding MB doesn t exist or is not of type
+ * INTER.
+ * - pMBInter[0] - Pointer to left MB information
+ * - pMBInter[1] - Pointer to top MB information
+ * - pMBInter[2] - Pointer to top-left MB information
+ * - pMBInter[3] - Pointer to top-right MB information
+ * pMBIntra - Array, of dimension four, containing pointers to information
+ * associated with four adjacent type INTRA MBs (Left, Top,
+ * Top-Left, Top-Right). Any pointer in the array may be set equal
+ * to NULL if the corresponding MB doesn t exist or is not of type
+ * INTRA.
+ * - pMBIntra[0] - Pointer to left MB information
+ * - pMBIntra[1] - Pointer to top MB information
+ * - pMBIntra[2] - Pointer to top-left MB information
+ * - pMBIntra[3] - Pointer to top-right MB information
+ * pSrcDstMBCurr - Pointer to information structure for the current MB.
+ * The following entries should be set prior to calling the
+ * function: sliceID - the number of the slice the to which the
+ * current MB belongs.
+ *
+ * Output Arguments:
+ *
+ * pDstCost - Pointer to the minimum motion cost for the current MB.
+ * pDstBlockSAD - Pointer to the array of SADs for each of the sixteen luma
+ * 4x4 blocks in each MB. The block SADs are in scan order for
+ * each MB. For implementations that cannot compute the SAD values
+ * individually, the maximum possible value (0xffff) is returned
+ * for each of the 16 block SAD entries.
+ * pSrcDstMBCurr - Pointer to updated information structure for the current
+ * MB after MB-level motion estimation has been completed. The
+ * following fields are updated by the ME function. The following
+ * parameter set quantifies the MB-level ME search results:
+ * - MbType
+ * - subMBType[4]
+ * - pMV0[4][4]
+ * - pMVPred[4][4]
+ * - pRefL0Idx[4]
+ * - Intra16x16PredMode
+ * - pIntra4x4PredMode[4][4]
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - One or more of the following pointers is NULL: pSrcCurrBuf,
+ * pSrcRefBufList, pSrcRecBuf, pRefRect, pCurrPointPos, pMESpec,
+ * pMBInter, pMBIntra,pSrcDstMBCurr, pDstCost, pSrcRefBufList[0]
+ * - SrcRefStep, SrcRecStep are not multiples of 16
+ * - iBlockWidth or iBlockHeight are values other than 4, 8, or 16.
+ * - Any alignment restrictions are violated
+ *
+ */
+OMXResult omxVCM4P10_MotionEstimationMB (
+ const OMX_U8 *pSrcCurrBuf,
+ OMX_S32 SrcCurrStep,
+ const OMX_U8 *pSrcRefBufList[15],
+ OMX_S32 SrcRefStep,
+ const OMX_U8 *pSrcRecBuf,
+ OMX_S32 SrcRecStep,
+ const OMXRect *pRefRect,
+ const OMXVCM4P2Coordinate *pCurrPointPos,
+ OMX_U32 Lambda,
+ void *pMESpec,
+ const OMXVCM4P10MBInfoPtr *pMBInter,
+ const OMXVCM4P10MBInfoPtr *pMBIntra,
+ OMXVCM4P10MBInfoPtr pSrcDstMBCurr,
+ OMX_INT *pDstCost,
+ OMX_U16 *pDstBlockSAD
+);
+
+
+
+/**
+ * Function: omxVCM4P10_SAD_4x (6.3.5.4.1)
+ *
+ * Description:
+ * This function calculates the SAD for 4x8 and 4x4 blocks.
+ *
+ * Input Arguments:
+ *
+ * pSrcOrg -Pointer to the original block; must be aligned on a 4-byte
+ * boundary.
+ * iStepOrg -Step of the original block buffer; must be a multiple of 4.
+ * pSrcRef -Pointer to the reference block
+ * iStepRef -Step of the reference block buffer
+ * iHeight -Height of the block; must be equal to either 4 or 8.
+ *
+ * Output Arguments:
+ *
+ * pDstSAD -Pointer of result SAD
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - One or more of the following pointers is NULL:
+ * pSrcOrg, pSrcRef, or pDstSAD
+ * - iHeight is not equal to either 4 or 8.
+ * - iStepOrg is not a multiple of 4
+ * - Any alignment restrictions are violated
+ *
+ */
+OMXResult omxVCM4P10_SAD_4x (
+ const OMX_U8 *pSrcOrg,
+ OMX_U32 iStepOrg,
+ const OMX_U8 *pSrcRef,
+ OMX_U32 iStepRef,
+ OMX_S32 *pDstSAD,
+ OMX_U32 iHeight
+);
+
+
+
+/**
+ * Function: omxVCM4P10_SADQuar_4x (6.3.5.4.2)
+ *
+ * Description:
+ * This function calculates the SAD between one block (pSrc) and the average
+ * of the other two (pSrcRef0 and pSrcRef1) for 4x8 or 4x4 blocks. Rounding
+ * is applied according to the convention (a+b+1)>>1.
+ *
+ * Input Arguments:
+ *
+ * pSrc - Pointer to the original block; must be aligned on a 4-byte
+ * boundary.
+ * pSrcRef0 - Pointer to reference block 0
+ * pSrcRef1 - Pointer to reference block 1
+ * iSrcStep - Step of the original block buffer; must be a multiple of 4.
+ * iRefStep0 - Step of reference block 0
+ * iRefStep1 - Step of reference block 1
+ * iHeight - Height of the block; must be equal to either 4 or 8.
+ *
+ * Output Arguments:
+ *
+ * pDstSAD - Pointer of result SAD
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - iHeight is not equal to either 4 or 8.
+ * - One or more of the following pointers is NULL: pSrc, pSrcRef0,
+ * pSrcRef1, pDstSAD.
+ * - iSrcStep is not a multiple of 4
+ * - Any alignment restrictions are violated
+ *
+ */
+OMXResult omxVCM4P10_SADQuar_4x (
+ const OMX_U8 *pSrc,
+ const OMX_U8 *pSrcRef0,
+ const OMX_U8 *pSrcRef1,
+ OMX_U32 iSrcStep,
+ OMX_U32 iRefStep0,
+ OMX_U32 iRefStep1,
+ OMX_U32 *pDstSAD,
+ OMX_U32 iHeight
+);
+
+
+
+/**
+ * Function: omxVCM4P10_SADQuar_8x (6.3.5.4.3)
+ *
+ * Description:
+ * This function calculates the SAD between one block (pSrc) and the average
+ * of the other two (pSrcRef0 and pSrcRef1) for 8x16, 8x8, or 8x4 blocks.
+ * Rounding is applied according to the convention (a+b+1)>>1.
+ *
+ * Input Arguments:
+ *
+ * pSrc - Pointer to the original block; must be aligned on an 8-byte
+ * boundary.
+ * pSrcRef0 - Pointer to reference block 0
+ * pSrcRef1 - Pointer to reference block 1
+ * iSrcStep - Step of the original block buffer; must be a multiple of 8.
+ * iRefStep0 - Step of reference block 0
+ * iRefStep1 - Step of reference block 1
+ * iHeight - Height of the block; must be equal either 4, 8, or 16.
+ *
+ * Output Arguments:
+ *
+ * pDstSAD - Pointer of result SAD
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - iHeight is not equal to either 4, 8, or 16.
+ * - One or more of the following pointers is NULL: pSrc, pSrcRef0,
+ * pSrcRef1, pDstSAD.
+ * - iSrcStep is not a multiple of 8
+ * - Any alignment restrictions are violated
+ *
+ */
+OMXResult omxVCM4P10_SADQuar_8x (
+ const OMX_U8 *pSrc,
+ const OMX_U8 *pSrcRef0,
+ const OMX_U8 *pSrcRef1,
+ OMX_U32 iSrcStep,
+ OMX_U32 iRefStep0,
+ OMX_U32 iRefStep1,
+ OMX_U32 *pDstSAD,
+ OMX_U32 iHeight
+);
+
+
+
+/**
+ * Function: omxVCM4P10_SADQuar_16x (6.3.5.4.4)
+ *
+ * Description:
+ * This function calculates the SAD between one block (pSrc) and the average
+ * of the other two (pSrcRef0 and pSrcRef1) for 16x16 or 16x8 blocks.
+ * Rounding is applied according to the convention (a+b+1)>>1.
+ *
+ * Input Arguments:
+ *
+ * pSrc - Pointer to the original block; must be aligned on a 16-byte
+ * boundary.
+ * pSrcRef0 - Pointer to reference block 0
+ * pSrcRef1 - Pointer to reference block 1
+ * iSrcStep - Step of the original block buffer; must be a multiple of 16
+ * iRefStep0 - Step of reference block 0
+ * iRefStep1 - Step of reference block 1
+ * iHeight - Height of the block; must be equal to either 8 or 16
+ *
+ * Output Arguments:
+ *
+ * pDstSAD -Pointer of result SAD
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - iHeight is not equal to either 8 or 16.
+ * - One or more of the following pointers is NULL: pSrc, pSrcRef0,
+ * pSrcRef1, pDstSAD.
+ * - iSrcStep is not a multiple of 16
+ * - Any alignment restrictions are violated
+ *
+ */
+OMXResult omxVCM4P10_SADQuar_16x (
+ const OMX_U8 *pSrc,
+ const OMX_U8 *pSrcRef0,
+ const OMX_U8 *pSrcRef1,
+ OMX_U32 iSrcStep,
+ OMX_U32 iRefStep0,
+ OMX_U32 iRefStep1,
+ OMX_U32 *pDstSAD,
+ OMX_U32 iHeight
+);
+
+
+
+/**
+ * Function: omxVCM4P10_SATD_4x4 (6.3.5.4.5)
+ *
+ * Description:
+ * This function calculates the sum of absolute transform differences (SATD)
+ * for a 4x4 block by applying a Hadamard transform to the difference block
+ * and then calculating the sum of absolute coefficient values.
+ *
+ * Input Arguments:
+ *
+ * pSrcOrg - Pointer to the original block; must be aligned on a 4-byte
+ * boundary
+ * iStepOrg - Step of the original block buffer; must be a multiple of 4
+ * pSrcRef - Pointer to the reference block; must be aligned on a 4-byte
+ * boundary
+ * iStepRef - Step of the reference block buffer; must be a multiple of 4
+ *
+ * Output Arguments:
+ *
+ * pDstSAD - pointer to the resulting SAD
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL:
+ * pSrcOrg, pSrcRef, or pDstSAD either pSrcOrg
+ * - pSrcRef is not aligned on a 4-byte boundary
+ * - iStepOrg <= 0 or iStepOrg is not a multiple of 4
+ * - iStepRef <= 0 or iStepRef is not a multiple of 4
+ *
+ */
+OMXResult omxVCM4P10_SATD_4x4 (
+ const OMX_U8 *pSrcOrg,
+ OMX_U32 iStepOrg,
+ const OMX_U8 *pSrcRef,
+ OMX_U32 iStepRef,
+ OMX_U32 *pDstSAD
+);
+
+
+
+/**
+ * Function: omxVCM4P10_InterpolateHalfHor_Luma (6.3.5.5.1)
+ *
+ * Description:
+ * This function performs interpolation for two horizontal 1/2-pel positions
+ * (-1/2,0) and (1/2, 0) - around a full-pel position.
+ *
+ * Input Arguments:
+ *
+ * pSrc - Pointer to the top-left corner of the block used to interpolate in
+ * the reconstruction frame plane.
+ * iSrcStep - Step of the source buffer.
+ * iDstStep - Step of the destination(interpolation) buffer; must be a
+ * multiple of iWidth.
+ * iWidth - Width of the current block; must be equal to either 4, 8, or 16
+ * iHeight - Height of the current block; must be equal to 4, 8, or 16
+ *
+ * Output Arguments:
+ *
+ * pDstLeft -Pointer to the interpolation buffer of the left -pel position
+ * (-1/2, 0)
+ * If iWidth==4, 4-byte alignment required.
+ * If iWidth==8, 8-byte alignment required.
+ * If iWidth==16, 16-byte alignment required.
+ * pDstRight -Pointer to the interpolation buffer of the right -pel
+ * position (1/2, 0)
+ * If iWidth==4, 4-byte alignment required.
+ * If iWidth==8, 8-byte alignment required.
+ * If iWidth==16, 16-byte alignment required.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL:
+ * pSrc, pDstLeft, or pDstRight
+ * - iWidth or iHeight have values other than 4, 8, or 16
+ * - iWidth==4 but pDstLeft and/or pDstRight is/are not aligned on a 4-byte boundary
+ * - iWidth==8 but pDstLeft and/or pDstRight is/are not aligned on a 8-byte boundary
+ * - iWidth==16 but pDstLeft and/or pDstRight is/are not aligned on a 16-byte boundary
+ * - any alignment restrictions are violated
+ *
+ */
+OMXResult omxVCM4P10_InterpolateHalfHor_Luma (
+ const OMX_U8 *pSrc,
+ OMX_U32 iSrcStep,
+ OMX_U8 *pDstLeft,
+ OMX_U8 *pDstRight,
+ OMX_U32 iDstStep,
+ OMX_U32 iWidth,
+ OMX_U32 iHeight
+);
+
+
+
+/**
+ * Function: omxVCM4P10_InterpolateHalfVer_Luma (6.3.5.5.2)
+ *
+ * Description:
+ * This function performs interpolation for two vertical 1/2-pel positions -
+ * (0, -1/2) and (0, 1/2) - around a full-pel position.
+ *
+ * Input Arguments:
+ *
+ * pSrc - Pointer to top-left corner of block used to interpolate in the
+ * reconstructed frame plane
+ * iSrcStep - Step of the source buffer.
+ * iDstStep - Step of the destination (interpolation) buffer; must be a
+ * multiple of iWidth.
+ * iWidth - Width of the current block; must be equal to either 4, 8, or 16
+ * iHeight - Height of the current block; must be equal to either 4, 8, or 16
+ *
+ * Output Arguments:
+ *
+ * pDstUp -Pointer to the interpolation buffer of the -pel position above
+ * the current full-pel position (0, -1/2)
+ * If iWidth==4, 4-byte alignment required.
+ * If iWidth==8, 8-byte alignment required.
+ * If iWidth==16, 16-byte alignment required.
+ * pDstDown -Pointer to the interpolation buffer of the -pel position below
+ * the current full-pel position (0, 1/2)
+ * If iWidth==4, 4-byte alignment required.
+ * If iWidth==8, 8-byte alignment required.
+ * If iWidth==16, 16-byte alignment required.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL:
+ * pSrc, pDstUp, or pDstDown
+ * - iWidth or iHeight have values other than 4, 8, or 16
+ * - iWidth==4 but pDstUp and/or pDstDown is/are not aligned on a 4-byte boundary
+ * - iWidth==8 but pDstUp and/or pDstDown is/are not aligned on a 8-byte boundary
+ * - iWidth==16 but pDstUp and/or pDstDown is/are not aligned on a 16-byte boundary
+ *
+ */
+OMXResult omxVCM4P10_InterpolateHalfVer_Luma (
+ const OMX_U8 *pSrc,
+ OMX_U32 iSrcStep,
+ OMX_U8 *pDstUp,
+ OMX_U8 *pDstDown,
+ OMX_U32 iDstStep,
+ OMX_U32 iWidth,
+ OMX_U32 iHeight
+);
+
+
+
+/**
+ * Function: omxVCM4P10_Average_4x (6.3.5.5.3)
+ *
+ * Description:
+ * This function calculates the average of two 4x4, 4x8 blocks. The result
+ * is rounded according to (a+b+1)/2.
+ *
+ * Input Arguments:
+ *
+ * pPred0 - Pointer to the top-left corner of reference block 0
+ * pPred1 - Pointer to the top-left corner of reference block 1
+ * iPredStep0 - Step of reference block 0; must be a multiple of 4.
+ * iPredStep1 - Step of reference block 1; must be a multiple of 4.
+ * iDstStep - Step of the destination buffer; must be a multiple of 4.
+ * iHeight - Height of the blocks; must be either 4 or 8.
+ *
+ * Output Arguments:
+ *
+ * pDstPred - Pointer to the destination buffer. 4-byte alignment required.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL:
+ * pPred0, pPred1, or pDstPred
+ * - pDstPred is not aligned on a 4-byte boundary
+ * - iPredStep0 <= 0 or iPredStep0 is not a multiple of 4
+ * - iPredStep1 <= 0 or iPredStep1 is not a multiple of 4
+ * - iDstStep <= 0 or iDstStep is not a multiple of 4
+ * - iHeight is not equal to either 4 or 8
+ *
+ */
+OMXResult omxVCM4P10_Average_4x (
+ const OMX_U8 *pPred0,
+ const OMX_U8 *pPred1,
+ OMX_U32 iPredStep0,
+ OMX_U32 iPredStep1,
+ OMX_U8 *pDstPred,
+ OMX_U32 iDstStep,
+ OMX_U32 iHeight
+);
+
+
+
+/**
+ * Function: omxVCM4P10_TransformQuant_ChromaDC (6.3.5.6.1)
+ *
+ * Description:
+ * This function performs 2x2 Hadamard transform of chroma DC coefficients
+ * and then quantizes the coefficients.
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - Pointer to the 2x2 array of chroma DC coefficients. 8-byte
+ * alignment required.
+ * iQP - Quantization parameter; must be in the range [0,51].
+ * bIntra - Indicate whether this is an INTRA block. 1-INTRA, 0-INTER
+ *
+ * Output Arguments:
+ *
+ * pSrcDst - Pointer to transformed and quantized coefficients. 8-byte
+ * alignment required.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL:
+ * pSrcDst
+ * - pSrcDst is not aligned on an 8-byte boundary
+ *
+ */
+OMXResult omxVCM4P10_TransformQuant_ChromaDC (
+ OMX_S16 *pSrcDst,
+ OMX_U32 iQP,
+ OMX_U8 bIntra
+);
+
+
+
+/**
+ * Function: omxVCM4P10_TransformQuant_LumaDC (6.3.5.6.2)
+ *
+ * Description:
+ * This function performs a 4x4 Hadamard transform of luma DC coefficients
+ * and then quantizes the coefficients.
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - Pointer to the 4x4 array of luma DC coefficients. 16-byte
+ * alignment required.
+ * iQP - Quantization parameter; must be in the range [0,51].
+ *
+ * Output Arguments:
+ *
+ * pSrcDst - Pointer to transformed and quantized coefficients. 16-byte
+ * alignment required.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL: pSrcDst
+ * - pSrcDst is not aligned on an 16-byte boundary
+ *
+ */
+OMXResult omxVCM4P10_TransformQuant_LumaDC (
+ OMX_S16 *pSrcDst,
+ OMX_U32 iQP
+);
+
+
+
+/**
+ * Function: omxVCM4P10_InvTransformDequant_LumaDC (6.3.5.6.3)
+ *
+ * Description:
+ * This function performs inverse 4x4 Hadamard transform and then dequantizes
+ * the coefficients.
+ *
+ * Input Arguments:
+ *
+ * pSrc - Pointer to the 4x4 array of the 4x4 Hadamard-transformed and
+ * quantized coefficients. 16 byte alignment required.
+ * iQP - Quantization parameter; must be in the range [0,51].
+ *
+ * Output Arguments:
+ *
+ * pDst - Pointer to inverse-transformed and dequantized coefficients.
+ * 16-byte alignment required.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL: pSrc
+ * - pSrc or pDst is not aligned on a 16-byte boundary
+ *
+ */
+OMXResult omxVCM4P10_InvTransformDequant_LumaDC (
+ const OMX_S16 *pSrc,
+ OMX_S16 *pDst,
+ OMX_U32 iQP
+);
+
+
+
+/**
+ * Function: omxVCM4P10_InvTransformDequant_ChromaDC (6.3.5.6.4)
+ *
+ * Description:
+ * This function performs inverse 2x2 Hadamard transform and then dequantizes
+ * the coefficients.
+ *
+ * Input Arguments:
+ *
+ * pSrc - Pointer to the 2x2 array of the 2x2 Hadamard-transformed and
+ * quantized coefficients. 8 byte alignment required.
+ * iQP - Quantization parameter; must be in the range [0,51].
+ *
+ * Output Arguments:
+ *
+ * pDst - Pointer to inverse-transformed and dequantized coefficients.
+ * 8-byte alignment required.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL: pSrc
+ * - pSrc or pDst is not aligned on an 8-byte boundary
+ *
+ */
+OMXResult omxVCM4P10_InvTransformDequant_ChromaDC (
+ const OMX_S16 *pSrc,
+ OMX_S16 *pDst,
+ OMX_U32 iQP
+);
+
+
+
+/**
+ * Function: omxVCM4P10_InvTransformResidualAndAdd (6.3.5.7.1)
+ *
+ * Description:
+ * This function performs inverse an 4x4 integer transformation to produce
+ * the difference signal and then adds the difference to the prediction to get
+ * the reconstructed signal.
+ *
+ * Input Arguments:
+ *
+ * pSrcPred - Pointer to prediction signal. 4-byte alignment required.
+ * pDequantCoeff - Pointer to the transformed coefficients. 8-byte
+ * alignment required.
+ * iSrcPredStep - Step of the prediction buffer; must be a multiple of 4.
+ * iDstReconStep - Step of the destination reconstruction buffer; must be a
+ * multiple of 4.
+ * bAC - Indicate whether there is AC coefficients in the coefficients
+ * matrix.
+ *
+ * Output Arguments:
+ *
+ * pDstRecon -Pointer to the destination reconstruction buffer. 4-byte
+ * alignment required.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL:
+ * pSrcPred, pDequantCoeff, pDstRecon
+ * - pSrcPred is not aligned on a 4-byte boundary
+ * - iSrcPredStep or iDstReconStep is not a multiple of 4.
+ * - pDequantCoeff is not aligned on an 8-byte boundary
+ *
+ */
+OMXResult omxVCM4P10_InvTransformResidualAndAdd (
+ const OMX_U8 *pSrcPred,
+ const OMX_S16 *pDequantCoeff,
+ OMX_U8 *pDstRecon,
+ OMX_U32 iSrcPredStep,
+ OMX_U32 iDstReconStep,
+ OMX_U8 bAC
+);
+
+
+
+/**
+ * Function: omxVCM4P10_SubAndTransformQDQResidual (6.3.5.8.1)
+ *
+ * Description:
+ * This function subtracts the prediction signal from the original signal to
+ * produce the difference signal and then performs a 4x4 integer transform and
+ * quantization. The quantized transformed coefficients are stored as
+ * pDstQuantCoeff. This function can also output dequantized coefficients or
+ * unquantized DC coefficients optionally by setting the pointers
+ * pDstDeQuantCoeff, pDCCoeff.
+ *
+ * Input Arguments:
+ *
+ * pSrcOrg - Pointer to original signal. 4-byte alignment required.
+ * pSrcPred - Pointer to prediction signal. 4-byte alignment required.
+ * iSrcOrgStep - Step of the original signal buffer; must be a multiple of
+ * 4.
+ * iSrcPredStep - Step of the prediction signal buffer; must be a multiple
+ * of 4.
+ * pNumCoeff -Number of non-zero coefficients after quantization. If this
+ * parameter is not required, it is set to NULL.
+ * nThreshSAD - Zero-block early detection threshold. If this parameter is
+ * not required, it is set to 0.
+ * iQP - Quantization parameter; must be in the range [0,51].
+ * bIntra - Indicates whether this is an INTRA block, either 1-INTRA or
+ * 0-INTER
+ *
+ * Output Arguments:
+ *
+ * pDstQuantCoeff - Pointer to the quantized transformed coefficients.
+ * 8-byte alignment required.
+ * pDstDeQuantCoeff - Pointer to the dequantized transformed coefficients
+ * if this parameter is not equal to NULL. 8-byte alignment
+ * required.
+ * pDCCoeff - Pointer to the unquantized DC coefficient if this parameter
+ * is not equal to NULL.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL:
+ * pSrcOrg, pSrcPred, pNumCoeff, pDstQuantCoeff,
+ * pDstDeQuantCoeff, pDCCoeff
+ * - pSrcOrg is not aligned on a 4-byte boundary
+ * - pSrcPred is not aligned on a 4-byte boundary
+ * - iSrcOrgStep is not a multiple of 4
+ * - iSrcPredStep is not a multiple of 4
+ * - pDstQuantCoeff or pDstDeQuantCoeff is not aligned on an 8-byte boundary
+ *
+ */
+OMXResult omxVCM4P10_SubAndTransformQDQResidual (
+ const OMX_U8 *pSrcOrg,
+ const OMX_U8 *pSrcPred,
+ OMX_U32 iSrcOrgStep,
+ OMX_U32 iSrcPredStep,
+ OMX_S16 *pDstQuantCoeff,
+ OMX_S16 *pDstDeQuantCoeff,
+ OMX_S16 *pDCCoeff,
+ OMX_S8 *pNumCoeff,
+ OMX_U32 nThreshSAD,
+ OMX_U32 iQP,
+ OMX_U8 bIntra
+);
+
+
+
+/**
+ * Function: omxVCM4P10_GetVLCInfo (6.3.5.9.1)
+ *
+ * Description:
+ * This function extracts run-length encoding (RLE) information from the
+ * coefficient matrix. The results are returned in an OMXVCM4P10VLCInfo
+ * structure.
+ *
+ * Input Arguments:
+ *
+ * pSrcCoeff - pointer to the transform coefficient matrix. 8-byte
+ * alignment required.
+ * pScanMatrix - pointer to the scan order definition matrix. For a luma
+ * block the scan matrix should follow [ISO14496-10] section 8.5.4,
+ * and should contain the values 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13,
+ * 10, 7, 11, 14, 15. For a chroma block, the scan matrix should
+ * contain the values 0, 1, 2, 3.
+ * bAC - indicates presence of a DC coefficient; 0 = DC coefficient
+ * present, 1= DC coefficient absent.
+ * MaxNumCoef - specifies the number of coefficients contained in the
+ * transform coefficient matrix, pSrcCoeff. The value should be 16
+ * for blocks of type LUMADC, LUMAAC, LUMALEVEL, and CHROMAAC. The
+ * value should be 4 for blocks of type CHROMADC.
+ *
+ * Output Arguments:
+ *
+ * pDstVLCInfo - pointer to structure that stores information for
+ * run-length coding.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL:
+ * pSrcCoeff, pScanMatrix, pDstVLCInfo
+ * - pSrcCoeff is not aligned on an 8-byte boundary
+ *
+ */
+OMXResult omxVCM4P10_GetVLCInfo (
+ const OMX_S16 *pSrcCoeff,
+ const OMX_U8 *pScanMatrix,
+ OMX_U8 bAC,
+ OMX_U32 MaxNumCoef,
+ OMXVCM4P10VLCInfo*pDstVLCInfo
+);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /** end of #define _OMXVC_H_ */
+
+/** EOF */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/armVCCOMM_Average.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/armVCCOMM_Average.c
new file mode 100644
index 0000000..1e51077
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/armVCCOMM_Average.c
@@ -0,0 +1,78 @@
+/**
+ *
+ * File Name: armVCCOMM_Average.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ * Description:
+ * This function will calculate Average of two blocks if size iWidth X iHeight
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/**
+ * Function: armVCCOMM_Average
+ *
+ * Description:
+ * This function calculates the average of two blocks and stores the result.
+ *
+ * Remarks:
+ *
+ * [in] pPred0 Pointer to the top-left corner of reference block 0
+ * [in] pPred1 Pointer to the top-left corner of reference block 1
+ * [in] iPredStep0 Step of reference block 0
+ * [in] iPredStep1 Step of reference block 1
+ * [in] iDstStep Step of the destination buffer
+ * [in] iWidth Width of the blocks
+ * [in] iHeight Height of the blocks
+ * [out] pDstPred Pointer to the destination buffer
+ *
+ * Return Value:
+ * Standard OMXResult value.
+ *
+ */
+ OMXResult armVCCOMM_Average (
+ const OMX_U8* pPred0,
+ const OMX_U8* pPred1,
+ OMX_U32 iPredStep0,
+ OMX_U32 iPredStep1,
+ OMX_U8* pDstPred,
+ OMX_U32 iDstStep,
+ OMX_U32 iWidth,
+ OMX_U32 iHeight
+)
+{
+ OMX_U32 x, y;
+
+ /* check for argument error */
+ armRetArgErrIf(pPred0 == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pPred1 == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pDstPred == NULL, OMX_Sts_BadArgErr)
+
+ for (y = 0; y < iHeight; y++)
+ {
+ for (x = 0; x < iWidth; x++)
+ {
+ pDstPred [y * iDstStep + x] =
+ (OMX_U8)(((OMX_U32)pPred0 [y * iPredStep0 + x] +
+ pPred1 [y * iPredStep1 + x] + 1) >> 1);
+ }
+ }
+
+ return OMX_Sts_NoErr;
+}
+
+/*****************************************************************************
+ * END OF FILE
+ *****************************************************************************/
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/armVCCOMM_SAD.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/armVCCOMM_SAD.c
new file mode 100644
index 0000000..d41ac9a
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/armVCCOMM_SAD.c
@@ -0,0 +1,75 @@
+/**
+ *
+ * File Name: armVCCOMM_SAD.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ * Description:
+ * This function will calculate SAD for NxM blocks
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+
+/**
+ * Function: armVCCOMM_SAD
+ *
+ * Description:
+ * This function calculate the SAD for NxM blocks.
+ *
+ * Remarks:
+ *
+ * [in] pSrcOrg Pointer to the original block
+ * [in] iStepOrg Step of the original block buffer
+ * [in] pSrcRef Pointer to the reference block
+ * [in] iStepRef Step of the reference block buffer
+ * [in] iHeight Height of the block
+ * [in] iWidth Width of the block
+ * [out] pDstSAD Pointer of result SAD
+ *
+ * Return Value:
+ * Standard OMXResult value.
+ *
+ */
+OMXResult armVCCOMM_SAD(
+ const OMX_U8* pSrcOrg,
+ OMX_U32 iStepOrg,
+ const OMX_U8* pSrcRef,
+ OMX_U32 iStepRef,
+ OMX_S32* pDstSAD,
+ OMX_U32 iHeight,
+ OMX_U32 iWidth
+)
+{
+ OMX_INT x, y;
+
+ /* check for argument error */
+ armRetArgErrIf(pSrcOrg == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pSrcRef == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pDstSAD == NULL, OMX_Sts_BadArgErr)
+
+ *pDstSAD = 0;
+ for (y = 0; y < iHeight; y++)
+ {
+ for (x = 0; x < iWidth; x++)
+ {
+ *pDstSAD += armAbs(pSrcOrg [(y * iStepOrg) + x] -
+ pSrcRef [(y * iStepRef) + x]);
+ }
+ }
+
+ return OMX_Sts_NoErr;
+}
+
+/*****************************************************************************
+ * END OF FILE
+ *****************************************************************************/
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_Average_16x.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_Average_16x.c
new file mode 100644
index 0000000..6d1447e
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_Average_16x.c
@@ -0,0 +1,86 @@
+/**
+ *
+ * File Name: omxVCCOMM_Average_16x.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ * Description:
+ * This function will calculate Average of two 16x16 or 16x8 blocks
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/**
+ * Function: omxVCCOMM_Average_16x (6.1.3.1.2)
+ *
+ * Description:
+ * This function calculates the average of two 16x16 or 16x8 blocks. The
+ * result is rounded according to (a+b+1)/2. The block average function can
+ * be used in conjunction with half-pixel interpolation to obtain quarter
+ * pixel motion estimates, as described in [ISO14496-10], subclause 8.4.2.2.1.
+ *
+ * Input Arguments:
+ *
+ * pPred0 - Pointer to the top-left corner of reference block 0
+ * pPred1 - Pointer to the top-left corner of reference block 1
+ * iPredStep0 - Step of reference block 0
+ * iPredStep1 - Step of reference block 1
+ * iDstStep - Step of the destination buffer
+ * iHeight - Height of the blocks
+ *
+ * Output Arguments:
+ *
+ * pDstPred - Pointer to the destination buffer. 16-byte aligned.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned under any of the following
+ * conditions:
+ * - one or more of the following pointers is NULL: pPred0, pPred1, or
+ * pDstPred.
+ * - pDstPred is not aligned on a 16-byte boundary.
+ * - iPredStep0 <= 0 or iPredStep0 is not a multiple of 16.
+ * - iPredStep1 <= 0 or iPredStep1 is not a multiple of 16.
+ * - iDstStep <= 0 or iDstStep is not a multiple of 16.
+ * - iHeight is not 8 or 16.
+ *
+ */
+ OMXResult omxVCCOMM_Average_16x (
+ const OMX_U8* pPred0,
+ const OMX_U8* pPred1,
+ OMX_U32 iPredStep0,
+ OMX_U32 iPredStep1,
+ OMX_U8* pDstPred,
+ OMX_U32 iDstStep,
+ OMX_U32 iHeight
+)
+{
+ /* check for argument error */
+ armRetArgErrIf(pPred0 == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pPred1 == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pDstPred == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf((iHeight != 8) && (iHeight != 16), OMX_Sts_BadArgErr)
+ armRetArgErrIf(armNot16ByteAligned(pDstPred), OMX_Sts_BadArgErr)
+ armRetArgErrIf((iPredStep0 == 0) || (iPredStep0 & 15), OMX_Sts_BadArgErr)
+ armRetArgErrIf((iPredStep1 == 0) || (iPredStep1 & 15), OMX_Sts_BadArgErr)
+ armRetArgErrIf((iDstStep == 0) || (iDstStep & 15), OMX_Sts_BadArgErr)
+
+ return armVCCOMM_Average
+ (pPred0, pPred1, iPredStep0, iPredStep1, pDstPred, iDstStep, 16, iHeight);
+}
+
+/*****************************************************************************
+ * END OF FILE
+ *****************************************************************************/
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_Average_8x.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_Average_8x.c
new file mode 100644
index 0000000..17b1326
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_Average_8x.c
@@ -0,0 +1,87 @@
+/**
+ *
+ * File Name: omxVCCOMM_Average_8x.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ * Description:
+ * This function will calculate Average of two 8x4 or 8x8 or 8x16 blocks
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/**
+ * Function: omxVCCOMM_Average_8x (6.1.3.1.1)
+ *
+ * Description:
+ * This function calculates the average of two 8x4, 8x8, or 8x16 blocks. The
+ * result is rounded according to (a+b+1)/2. The block average function can
+ * be used in conjunction with half-pixel interpolation to obtain quarter
+ * pixel motion estimates, as described in [ISO14496-10], subclause 8.4.2.2.1.
+ *
+ * Input Arguments:
+ *
+ * pPred0 - Pointer to the top-left corner of reference block 0
+ * pPred1 - Pointer to the top-left corner of reference block 1
+ * iPredStep0 - Step of reference block 0
+ * iPredStep1 - Step of reference block 1
+ * iDstStep - Step of the destination buffer.
+ * iHeight - Height of the blocks
+ *
+ * Output Arguments:
+ *
+ * pDstPred - Pointer to the destination buffer. 8-byte aligned.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned under any of the following
+ * conditions:
+ * - one or more of the following pointers is NULL: pPred0, pPred1, or
+ * pDstPred.
+ * - pDstPred is not aligned on an 8-byte boundary.
+ * - iPredStep0 <= 0 or iPredStep0 is not a multiple of 8.
+ * - iPredStep1 <= 0 or iPredStep1 is not a multiple of 8.
+ * - iDstStep <= 0 or iDstStep is not a multiple of 8.
+ * - iHeight is not 4, 8, or 16.
+ *
+ */
+ OMXResult omxVCCOMM_Average_8x (
+ const OMX_U8* pPred0,
+ const OMX_U8* pPred1,
+ OMX_U32 iPredStep0,
+ OMX_U32 iPredStep1,
+ OMX_U8* pDstPred,
+ OMX_U32 iDstStep,
+ OMX_U32 iHeight
+)
+{
+ /* check for argument error */
+ armRetArgErrIf(pPred0 == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pPred1 == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pDstPred == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf((iPredStep0 == 0) || (iPredStep0 & 7), OMX_Sts_BadArgErr)
+ armRetArgErrIf((iPredStep1 == 0) || (iPredStep1 & 7), OMX_Sts_BadArgErr)
+ armRetArgErrIf((iDstStep == 0) || (iDstStep & 7), OMX_Sts_BadArgErr)
+ armRetArgErrIf((iHeight != 4) && (iHeight != 8) && (iHeight != 16), OMX_Sts_BadArgErr)
+ armRetArgErrIf(armNot8ByteAligned(pDstPred), OMX_Sts_BadArgErr)
+
+ return armVCCOMM_Average
+ (pPred0, pPred1, iPredStep0, iPredStep1, pDstPred, iDstStep, 8, iHeight);
+}
+
+
+/*****************************************************************************
+ * END OF FILE
+ *****************************************************************************/
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_ComputeTextureErrorBlock.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_ComputeTextureErrorBlock.c
new file mode 100644
index 0000000..e559adf
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_ComputeTextureErrorBlock.c
@@ -0,0 +1,88 @@
+/**
+ *
+ * File Name: omxVCCOMM_ComputeTextureErrorBlock.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains module computing the error for a MB of size 8x8
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+#include "armCOMM.h"
+
+/**
+ * Function: omxVCCOMM_ComputeTextureErrorBlock (6.1.4.1.2)
+ *
+ * Description:
+ * Computes the texture error of the block.
+ *
+ * Input Arguments:
+ *
+ * pSrc - pointer to the source plane. This should be aligned on an 8-byte
+ * boundary.
+ * srcStep - step of the source plane
+ * pSrcRef - pointer to the reference buffer, an 8x8 block. This should be
+ * aligned on an 8-byte boundary.
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the destination buffer, an 8x8 block. This should be
+ * aligned on an 8-byte boundary.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments:
+ * - At least one of the following pointers is NULL:
+ * pSrc, pSrcRef, pDst.
+ * - pSrc is not 8-byte aligned.
+ * - SrcStep <= 0 or srcStep is not a multiple of 8.
+ * - pSrcRef is not 8-byte aligned.
+ * - pDst is not 8-byte aligned
+ *
+ */
+
+OMXResult omxVCCOMM_ComputeTextureErrorBlock(
+ const OMX_U8 *pSrc,
+ OMX_INT srcStep,
+ const OMX_U8 *pSrcRef,
+ OMX_S16 * pDst
+)
+{
+
+ OMX_INT x, y, count;
+
+ /* Argument error checks */
+ armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pSrcRef == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(!armIs8ByteAligned(pSrc), OMX_Sts_BadArgErr);
+ armRetArgErrIf(!armIs8ByteAligned(pSrcRef), OMX_Sts_BadArgErr);
+ armRetArgErrIf(!armIs8ByteAligned(pDst), OMX_Sts_BadArgErr);
+ armRetArgErrIf((srcStep <= 0) || (srcStep & 7), OMX_Sts_BadArgErr);
+
+ /* Calculate the error block */
+ for (y = 0, count = 0;
+ y < 8;
+ y++, pSrc += srcStep)
+ {
+ for (x = 0; x < 8; x++, count++)
+ {
+ pDst[count] = pSrc[x] - pSrcRef[count];
+ }
+ }
+
+ return OMX_Sts_NoErr;
+
+}
+
+/* End of file */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_ComputeTextureErrorBlock_SAD.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_ComputeTextureErrorBlock_SAD.c
new file mode 100644
index 0000000..c4731aa
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_ComputeTextureErrorBlock_SAD.c
@@ -0,0 +1,93 @@
+/**
+ *
+ * File Name: omxVCCOMM_ComputeTextureErrorBlock_SAD.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains module computing the error for a MB of size 8x8
+ *
+ */
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+
+
+/**
+ * Function: omxVCCOMM_ComputeTextureErrorBlock_SAD (6.1.4.1.1)
+ *
+ * Description:
+ * Computes texture error of the block; also returns SAD.
+ *
+ * Input Arguments:
+ *
+ * pSrc - pointer to the source plane; must be aligned on an 8-byte
+ * boundary.
+ * srcStep - step of the source plane
+ * pSrcRef - pointer to the reference buffer, an 8x8 block; must be aligned
+ * on an 8-byte boundary.
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the destination buffer, an 8x8 block; must be aligned
+ * on an 8-byte boundary.
+ * pDstSAD - pointer to the Sum of Absolute Differences (SAD) value
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments
+ * - At least one of the following
+ * pointers is NULL: pSrc, pSrcRef, pDst and pDstSAD.
+ * - pSrc is not 8-byte aligned.
+ * - SrcStep <= 0 or srcStep is not a multiple of 8.
+ * - pSrcRef is not 8-byte aligned.
+ * - pDst is not 8-byte aligned.
+ *
+ */
+
+OMXResult omxVCCOMM_ComputeTextureErrorBlock_SAD(
+ const OMX_U8 *pSrc,
+ OMX_INT srcStep,
+ const OMX_U8 *pSrcRef,
+ OMX_S16 * pDst,
+ OMX_INT *pDstSAD
+)
+{
+
+ OMX_INT x, y, count;
+
+ /* Argument error checks */
+ armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pSrcRef == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pDstSAD == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(!armIs8ByteAligned(pSrc), OMX_Sts_BadArgErr);
+ armRetArgErrIf(!armIs8ByteAligned(pSrcRef), OMX_Sts_BadArgErr);
+ armRetArgErrIf(!armIs8ByteAligned(pDst), OMX_Sts_BadArgErr);
+ armRetArgErrIf((srcStep <= 0) || (srcStep & 7), OMX_Sts_BadArgErr);
+
+ /* Calculate the error block */
+ for (y = 0, count = 0, *pDstSAD = 0;
+ y < 8;
+ y++, pSrc += srcStep)
+ {
+ for (x = 0; x < 8; x++, count++)
+ {
+ pDst[count] = pSrc[x] - pSrcRef[count];
+ *pDstSAD += armAbs(pDst[count]);
+ }
+ }
+
+ return OMX_Sts_NoErr;
+
+}
+
+/* End of file */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_Copy16x16.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_Copy16x16.c
new file mode 100644
index 0000000..4857024
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_Copy16x16.c
@@ -0,0 +1,79 @@
+/**
+ *
+ * File Name: omxVCCOMM_Copy16x16.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ * Description:
+ * MPEG4 16x16 Copy module
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+
+/**
+ * Function: omxVCCOMM_Copy16x16 (6.1.3.3.2)
+ *
+ * Description:
+ * Copies the reference 16x16 macroblock to the current macroblock.
+ *
+ * Input Arguments:
+ *
+ * pSrc - pointer to the reference macroblock in the source frame; must be
+ * aligned on a 16-byte boundary.
+ * step - distance between the starts of consecutive lines in the reference
+ * frame, in bytes; must be a multiple of 16 and must be larger
+ * than or equal to 16.
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the destination macroblock; must be aligned on a
+ * 16-byte boundary.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned under any of the following
+ * conditions:
+ * - one or more of the following pointers is NULL: pSrc, pDst
+ * - one or more of the following pointers is not aligned on a 16-byte
+ * boundary: pSrc, pDst
+ * - step <16 or step is not a multiple of 16.
+ *
+ */
+
+OMXResult omxVCCOMM_Copy16x16(
+ const OMX_U8 *pSrc,
+ OMX_U8 *pDst,
+ OMX_INT step)
+ {
+ /* Definitions and Initializations*/
+
+ OMX_INT count,index, x, y;
+
+ /* Argument error checks */
+ armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(!armIs16ByteAligned(pSrc), OMX_Sts_BadArgErr);
+ armRetArgErrIf(!armIs16ByteAligned(pDst), OMX_Sts_BadArgErr);
+ armRetArgErrIf(((step < 16) || (step % 16)), OMX_Sts_BadArgErr);
+
+
+ /* Copying the ref 16x16 blk to the curr blk */
+ for (y = 0, count = 0, index = 0; y < 16; y++, count = count + step - 16)
+ {
+ for (x = 0; x < 16; x++, count++, index++)
+ {
+ pDst[index] = pSrc[count];
+ }
+ }
+ return OMX_Sts_NoErr;
+ }
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_Copy8x8.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_Copy8x8.c
new file mode 100644
index 0000000..a4f9dde
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_Copy8x8.c
@@ -0,0 +1,79 @@
+/**
+ *
+ * File Name: omxVCCOMM_Copy8x8.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ * Description:
+ * MPEG4 8x8 Copy module
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+
+/**
+ * Function: omxVCCOMM_Copy8x8 (6.1.3.3.1)
+ *
+ * Description:
+ * Copies the reference 8x8 block to the current block.
+ *
+ * Input Arguments:
+ *
+ * pSrc - pointer to the reference block in the source frame; must be
+ * aligned on an 8-byte boundary.
+ * step - distance between the starts of consecutive lines in the reference
+ * frame, in bytes; must be a multiple of 8 and must be larger than
+ * or equal to 8.
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the destination block; must be aligned on an 8-byte
+ * boundary.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned under any of the following
+ * conditions:
+ * - one or more of the following pointers is NULL: pSrc, pDst
+ * - one or more of the following pointers is not aligned on an 8-byte
+ * boundary: pSrc, pDst
+ * - step <8 or step is not a multiple of 8.
+ *
+ */
+
+OMXResult omxVCCOMM_Copy8x8(
+ const OMX_U8 *pSrc,
+ OMX_U8 *pDst,
+ OMX_INT step)
+ {
+ /* Definitions and Initializations*/
+
+ OMX_INT count,index, x, y;
+
+ /* Argument error checks */
+ armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(!armIs8ByteAligned(pSrc), OMX_Sts_BadArgErr);
+ armRetArgErrIf(!armIs8ByteAligned(pDst), OMX_Sts_BadArgErr);
+ armRetArgErrIf(((step < 8) || (step % 8)), OMX_Sts_BadArgErr);
+
+
+ /* Copying the ref 8x8 blk to the curr blk */
+ for (y = 0, count = 0, index = 0; y < 8; y++, count = count + step - 8)
+ {
+ for (x = 0; x < 8; x++, count++, index++)
+ {
+ pDst[index] = pSrc[count];
+ }
+ }
+ return OMX_Sts_NoErr;
+ }
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_ExpandFrame_I.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_ExpandFrame_I.c
new file mode 100644
index 0000000..9536df7
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_ExpandFrame_I.c
@@ -0,0 +1,126 @@
+/**
+ *
+ * File Name: omxVCCOMM_ExpandFrame_I.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ * Description:
+ * This function will Expand Frame boundary pixels into Plane
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+
+/**
+ * Function: omxVCCOMM_ExpandFrame_I (6.1.3.2.1)
+ *
+ * Description:
+ * This function expands a reconstructed frame in-place. The unexpanded
+ * source frame should be stored in a plane buffer with sufficient space
+ * pre-allocated for edge expansion, and the input frame should be located in
+ * the plane buffer center. This function executes the pixel expansion by
+ * replicating source frame edge pixel intensities in the empty pixel
+ * locations (expansion region) between the source frame edge and the plane
+ * buffer edge. The width/height of the expansion regions on the
+ * horizontal/vertical edges is controlled by the parameter iExpandPels.
+ *
+ * Input Arguments:
+ *
+ * pSrcDstPlane - pointer to the top-left corner of the frame to be
+ * expanded; must be aligned on an 8-byte boundary.
+ * iFrameWidth - frame width; must be a multiple of 8.
+ * iFrameHeight -frame height; must be a multiple of 8.
+ * iExpandPels - number of pixels to be expanded in the horizontal and
+ * vertical directions; must be a multiple of 8.
+ * iPlaneStep - distance, in bytes, between the start of consecutive lines
+ * in the plane buffer; must be larger than or equal to
+ * (iFrameWidth + 2 * iExpandPels).
+ *
+ * Output Arguments:
+ *
+ * pSrcDstPlane -Pointer to the top-left corner of the frame (NOT the
+ * top-left corner of the plane); must be aligned on an 8-byte
+ * boundary.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned under any of the following
+ * conditions:
+ * - pSrcDstPlane is NULL.
+ * - pSrcDstPlane is not aligned on an 8-byte boundary.
+ * - one of the following parameters is either equal to zero or is a
+ * non-multiple of 8: iFrameHeight, iFrameWidth, iPlaneStep, or
+ * iExpandPels.
+ * - iPlaneStep < (iFrameWidth + 2 * iExpandPels).
+ *
+ */
+OMXResult omxVCCOMM_ExpandFrame_I(
+ OMX_U8* pSrcDstPlane,
+ OMX_U32 iFrameWidth,
+ OMX_U32 iFrameHeight,
+ OMX_U32 iExpandPels,
+ OMX_U32 iPlaneStep
+)
+{
+ OMX_INT x, y;
+ OMX_U8* pLeft;
+ OMX_U8* pRight;
+ OMX_U8* pTop;
+ OMX_U8* pBottom;
+
+ /* check for argument error */
+ armRetArgErrIf(pSrcDstPlane == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(armNot8ByteAligned(pSrcDstPlane), OMX_Sts_BadArgErr)
+ armRetArgErrIf(iFrameWidth == 0 || iFrameWidth & 7, OMX_Sts_BadArgErr)
+ armRetArgErrIf(iFrameHeight== 0 || iFrameHeight & 7, OMX_Sts_BadArgErr)
+ armRetArgErrIf(iExpandPels == 0 || iExpandPels & 7, OMX_Sts_BadArgErr)
+ armRetArgErrIf(iPlaneStep == 0 || iPlaneStep & 7, OMX_Sts_BadArgErr)
+ armRetArgErrIf(iPlaneStep < (iFrameWidth + 2 * iExpandPels),
+ OMX_Sts_BadArgErr)
+
+ /* Top and Bottom */
+ pTop = pSrcDstPlane - (iExpandPels * iPlaneStep);
+ pBottom = pSrcDstPlane + (iFrameHeight * iPlaneStep);
+
+ for (y = 0; y < (OMX_INT)iExpandPels; y++)
+ {
+ for (x = 0; x < (OMX_INT)iFrameWidth; x++)
+ {
+ pTop [y * iPlaneStep + x] =
+ pSrcDstPlane [x];
+ pBottom [y * iPlaneStep + x] =
+ pSrcDstPlane [(iFrameHeight - 1) * iPlaneStep + x];
+ }
+ }
+
+ /* Left, Right and Corners */
+ pLeft = pSrcDstPlane - iExpandPels;
+ pRight = pSrcDstPlane + iFrameWidth;
+
+ for (y = -(OMX_INT)iExpandPels; y < (OMX_INT)(iFrameHeight + iExpandPels); y++)
+ {
+ for (x = 0; x < (OMX_INT)iExpandPels; x++)
+ {
+ pLeft [y * iPlaneStep + x] =
+ pSrcDstPlane [y * iPlaneStep + 0];
+ pRight [y * iPlaneStep + x] =
+ pSrcDstPlane [y * iPlaneStep + (iFrameWidth - 1)];
+ }
+ }
+
+ return OMX_Sts_NoErr;
+}
+
+/*****************************************************************************
+ * END OF FILE
+ *****************************************************************************/
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_LimitMVToRect.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_LimitMVToRect.c
new file mode 100644
index 0000000..af04582
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_LimitMVToRect.c
@@ -0,0 +1,81 @@
+/**
+ *
+ * File Name: omxVCCOMM_LimitMVToRect.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains module for limiting the MV
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+
+/**
+ * Function: omxVCCOMM_LimitMVToRect (6.1.4.1.3)
+ *
+ * Description:
+ * Limits the motion vector associated with the current block/macroblock to
+ * prevent the motion compensated block/macroblock from moving outside a
+ * bounding rectangle as shown in Figure 6-1.
+ *
+ * Input Arguments:
+ *
+ * pSrcMV - pointer to the motion vector associated with the current block
+ * or macroblock
+ * pRectVOPRef - pointer to the bounding rectangle
+ * Xcoord, Ycoord - coordinates of the current block or macroblock
+ * size - size of the current block or macroblock; must be equal to 8 or
+ * 16.
+ *
+ * Output Arguments:
+ *
+ * pDstMV - pointer to the limited motion vector
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments. Returned if one or more of the
+ * following conditions is true:
+ * - at least one of the following pointers is NULL:
+ * pSrcMV, pDstMV, or pRectVOPRef.
+ * - size is not equal to either 8 or 16.
+ * - the width or height of the bounding rectangle is less than
+ * twice the block size.
+ */
+OMXResult omxVCCOMM_LimitMVToRect(
+ const OMXVCMotionVector * pSrcMV,
+ OMXVCMotionVector *pDstMV,
+ const OMXRect * pRectVOPRef,
+ OMX_INT Xcoord,
+ OMX_INT Ycoord,
+ OMX_INT size
+)
+{
+ /* Argument error checks */
+ armRetArgErrIf(pSrcMV == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pDstMV == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pRectVOPRef == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf((size != 8) && (size != 16), OMX_Sts_BadArgErr);
+ armRetArgErrIf((pRectVOPRef->width < (2* size)), OMX_Sts_BadArgErr);
+ armRetArgErrIf((pRectVOPRef->height < (2* size)), OMX_Sts_BadArgErr);
+
+ pDstMV->dx = armMin (armMax (pSrcMV->dx, 2*pRectVOPRef->x - Xcoord),
+ (2*pRectVOPRef->x + pRectVOPRef->width - Xcoord - size));
+ pDstMV->dy = armMin (armMax (pSrcMV->dy, 2*pRectVOPRef->y - Ycoord),
+ (2*pRectVOPRef->y + pRectVOPRef->height - Ycoord - size));
+
+
+ return OMX_Sts_NoErr;
+}
+
+/* End of file */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_SAD_16x.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_SAD_16x.c
new file mode 100644
index 0000000..0f0cedb
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_SAD_16x.c
@@ -0,0 +1,80 @@
+/**
+ *
+ * File Name: omxVCCOMM_SAD_16x.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ * Description:
+ * This function will calculate SAD for 16x16 and 16x8 blocks
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armVC.h"
+#include "armCOMM.h"
+
+/**
+ * Function: omxVCCOMM_SAD_16x (6.1.4.1.4)
+ *
+ * Description:
+ * This function calculates the SAD for 16x16 and 16x8 blocks.
+ *
+ * Input Arguments:
+ *
+ * pSrcOrg - Pointer to the original block; must be aligned on a 16-byte
+ * boundary.
+ * iStepOrg - Step of the original block buffer
+ * pSrcRef - Pointer to the reference block
+ * iStepRef - Step of the reference block buffer
+ * iHeight - Height of the block
+ *
+ * Output Arguments:
+ *
+ * pDstSAD - Pointer of result SAD
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments. Returned if one or more of the
+ * following conditions is true:
+ * - at least one of the following pointers is NULL:
+ * pSrcOrg, pDstSAD, or pSrcRef
+ * - pSrcOrg is not 16-byte aligned.
+ * - iStepOrg <= 0 or iStepOrg is not a multiple of 16
+ * - iStepRef <= 0 or iStepRef is not a multiple of 16
+ * - iHeight is not 8 or 16
+ *
+ */
+OMXResult omxVCCOMM_SAD_16x(
+ const OMX_U8* pSrcOrg,
+ OMX_U32 iStepOrg,
+ const OMX_U8* pSrcRef,
+ OMX_U32 iStepRef,
+ OMX_S32* pDstSAD,
+ OMX_U32 iHeight
+)
+{
+ /* check for argument error */
+ armRetArgErrIf(pSrcOrg == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pSrcRef == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pDstSAD == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf((iHeight != 16) && (iHeight != 8), OMX_Sts_BadArgErr)
+ armRetArgErrIf(armNot16ByteAligned(pSrcOrg), OMX_Sts_BadArgErr)
+ armRetArgErrIf((iStepOrg == 0) || (iStepOrg & 15), OMX_Sts_BadArgErr)
+ armRetArgErrIf((iStepRef == 0) || (iStepRef & 15), OMX_Sts_BadArgErr)
+
+ return armVCCOMM_SAD
+ (pSrcOrg, iStepOrg, pSrcRef, iStepRef, pDstSAD, iHeight, 16);
+}
+
+/*****************************************************************************
+ * END OF FILE
+ *****************************************************************************/
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_SAD_8x.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_SAD_8x.c
new file mode 100644
index 0000000..1421d99
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_SAD_8x.c
@@ -0,0 +1,80 @@
+/**
+ *
+ * File Name: omxVCCOMM_SAD_8x.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ * Description:
+ * This function will calculate SAD for 8x16, 8x8, 8x4 blocks
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armVC.h"
+#include "armCOMM.h"
+
+/**
+ * Function: omxVCCOMM_SAD_8x (6.1.4.1.5)
+ *
+ * Description:
+ * This function calculates the SAD for 8x16, 8x8, 8x4 blocks.
+ *
+ * Input Arguments:
+ *
+ * pSrcOrg - Pointer to the original block; must be aligned on a 8-byte
+ * boundary.
+ * iStepOrg - Step of the original block buffer
+ * pSrcRef - Pointer to the reference block
+ * iStepRef - Step of the reference block buffer
+ * iHeight - Height of the block
+ *
+ * Output Arguments:
+ *
+ * pDstSAD -Pointer of result SAD
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments. Returned if one or more of the
+ * following conditions is true:
+ * - at least one of the following pointers is NULL:
+ * pSrcOrg, pDstSAD, or pSrcRef
+ * - pSrcOrg is not 8-byte aligned.
+ * - iStepOrg <= 0 or iStepOrg is not a multiple of 8
+ * - iStepRef <= 0 or iStepRef is not a multiple of 8
+ * - iHeight is not 4, 8 or 16
+ *
+ */
+OMXResult omxVCCOMM_SAD_8x(
+ const OMX_U8* pSrcOrg,
+ OMX_U32 iStepOrg,
+ const OMX_U8* pSrcRef,
+ OMX_U32 iStepRef,
+ OMX_S32* pDstSAD,
+ OMX_U32 iHeight
+)
+{
+ /* check for argument error */
+ armRetArgErrIf(pSrcOrg == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pSrcRef == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pDstSAD == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf((iHeight != 16) && (iHeight != 8) && (iHeight != 4), OMX_Sts_BadArgErr)
+ armRetArgErrIf(armNot8ByteAligned(pSrcOrg), OMX_Sts_BadArgErr)
+ armRetArgErrIf((iStepOrg == 0) || (iStepOrg & 7), OMX_Sts_BadArgErr)
+ armRetArgErrIf((iStepRef == 0) || (iStepRef & 7), OMX_Sts_BadArgErr)
+
+ return armVCCOMM_SAD
+ (pSrcOrg, iStepOrg, pSrcRef, iStepRef, pDstSAD, iHeight, 8);
+}
+
+/*****************************************************************************
+ * END OF FILE
+ *****************************************************************************/
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/api/armVCM4P10_CAVLCTables.h b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/api/armVCM4P10_CAVLCTables.h
new file mode 100644
index 0000000..8d18a8f
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/api/armVCM4P10_CAVLCTables.h
@@ -0,0 +1,34 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: armVCM4P10_CAVLCTables.h
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * ----------------------------------------------------------------
+ * File: armVCM4P10_CAVLCTables.h
+ * ----------------------------------------------------------------
+ *
+ * Header file for ARM implementation of OpenMAX VCM4P10
+ *
+ */
+
+#ifndef ARMVCM4P10_CAVLCTABLES_H
+#define ARMVCM4P10_CAVLCTABLES_H
+
+/* CAVLC tables */
+
+extern const OMX_U8 armVCM4P10_CAVLCTrailingOnes[62];
+extern const OMX_U8 armVCM4P10_CAVLCTotalCoeff[62];
+extern const ARM_VLC32 *armVCM4P10_CAVLCCoeffTokenTables[5];
+extern const ARM_VLC32 armVCM4P10_CAVLCLevelPrefix[17];
+extern const ARM_VLC32 *armVCM4P10_CAVLCTotalZeroTables[15];
+extern const ARM_VLC32 *armVCM4P10_CAVLCTotalZeros2x2Tables[3];
+extern const ARM_VLC32 *armVCM4P10_CAVLCRunBeforeTables[7];
+
+#endif
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_CAVLCTables.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_CAVLCTables.c
new file mode 100644
index 0000000..f4e36ad
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_CAVLCTables.c
@@ -0,0 +1,703 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: armVCM4P10_CAVLCTables.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * CAVLC tables for H.264
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM_Bitstream.h"
+#include "armVC.h"
+#include "armVCM4P10_CAVLCTables.h"
+
+/* Tables mapping a code to TrailingOnes and TotalCoeff */
+
+const OMX_U8 armVCM4P10_CAVLCTrailingOnes[62] = {
+ 0,
+ 0, 1,
+ 0, 1, 2,
+ 0, 1, 2, 3,
+ 0, 1, 2, 3,
+ 0, 1, 2, 3,
+ 0, 1, 2, 3,
+ 0, 1, 2, 3,
+ 0, 1, 2, 3,
+ 0, 1, 2, 3,
+ 0, 1, 2, 3,
+ 0, 1, 2, 3,
+ 0, 1, 2, 3,
+ 0, 1, 2, 3,
+ 0, 1, 2, 3,
+ 0, 1, 2, 3,
+ 0, 1, 2, 3
+};
+
+const OMX_U8 armVCM4P10_CAVLCTotalCoeff[62] = {
+ 0,
+ 1, 1,
+ 2, 2, 2,
+ 3, 3, 3, 3,
+ 4, 4, 4, 4,
+ 5, 5, 5, 5,
+ 6, 6, 6, 6,
+ 7, 7, 7, 7,
+ 8, 8, 8, 8,
+ 9, 9, 9, 9,
+ 10, 10, 10, 10,
+ 11, 11, 11, 11,
+ 12, 12, 12, 12,
+ 13, 13, 13, 13,
+ 14, 14, 14, 14,
+ 15, 15, 15, 15,
+ 16, 16, 16, 16
+};
+
+static const ARM_VLC32 armVCM4P10_CAVLCCoeffToken0[63] = {
+ { 1, 0x0001 },
+ { 6, 0x0005 },
+ { 2, 0x0001 },
+ { 8, 0x0007 },
+ { 6, 0x0004 },
+ { 3, 0x0001 },
+ { 9, 0x0007 },
+ { 8, 0x0006 },
+ { 7, 0x0005 },
+ { 5, 0x0003 },
+ { 10, 0x0007 },
+ { 9, 0x0006 },
+ { 8, 0x0005 },
+ { 6, 0x0003 },
+ { 11, 0x0007 },
+ { 10, 0x0006 },
+ { 9, 0x0005 },
+ { 7, 0x0004 },
+ { 13, 0x000f },
+ { 11, 0x0006 },
+ { 10, 0x0005 },
+ { 8, 0x0004 },
+ { 13, 0x000b },
+ { 13, 0x000e },
+ { 11, 0x0005 },
+ { 9, 0x0004 },
+ { 13, 0x0008 },
+ { 13, 0x000a },
+ { 13, 0x000d },
+ { 10, 0x0004 },
+ { 14, 0x000f },
+ { 14, 0x000e },
+ { 13, 0x0009 },
+ { 11, 0x0004 },
+ { 14, 0x000b },
+ { 14, 0x000a },
+ { 14, 0x000d },
+ { 13, 0x000c },
+ { 15, 0x000f },
+ { 15, 0x000e },
+ { 14, 0x0009 },
+ { 14, 0x000c },
+ { 15, 0x000b },
+ { 15, 0x000a },
+ { 15, 0x000d },
+ { 14, 0x0008 },
+ { 16, 0x000f },
+ { 15, 0x0001 },
+ { 15, 0x0009 },
+ { 15, 0x000c },
+ { 16, 0x000b },
+ { 16, 0x000e },
+ { 16, 0x000d },
+ { 15, 0x0008 },
+ { 16, 0x0007 },
+ { 16, 0x000a },
+ { 16, 0x0009 },
+ { 16, 0x000c },
+ { 16, 0x0004 },
+ { 16, 0x0006 },
+ { 16, 0x0005 },
+ { 16, 0x0008 },
+ { 0, 0x0000 }
+};
+
+static const ARM_VLC32 armVCM4P10_CAVLCCoeffToken1[63] = {
+ { 2, 0x0003 },
+ { 6, 0x000b },
+ { 2, 0x0002 },
+ { 6, 0x0007 },
+ { 5, 0x0007 },
+ { 3, 0x0003 },
+ { 7, 0x0007 },
+ { 6, 0x000a },
+ { 6, 0x0009 },
+ { 4, 0x0005 },
+ { 8, 0x0007 },
+ { 6, 0x0006 },
+ { 6, 0x0005 },
+ { 4, 0x0004 },
+ { 8, 0x0004 },
+ { 7, 0x0006 },
+ { 7, 0x0005 },
+ { 5, 0x0006 },
+ { 9, 0x0007 },
+ { 8, 0x0006 },
+ { 8, 0x0005 },
+ { 6, 0x0008 },
+ { 11, 0x000f },
+ { 9, 0x0006 },
+ { 9, 0x0005 },
+ { 6, 0x0004 },
+ { 11, 0x000b },
+ { 11, 0x000e },
+ { 11, 0x000d },
+ { 7, 0x0004 },
+ { 12, 0x000f },
+ { 11, 0x000a },
+ { 11, 0x0009 },
+ { 9, 0x0004 },
+ { 12, 0x000b },
+ { 12, 0x000e },
+ { 12, 0x000d },
+ { 11, 0x000c },
+ { 12, 0x0008 },
+ { 12, 0x000a },
+ { 12, 0x0009 },
+ { 11, 0x0008 },
+ { 13, 0x000f },
+ { 13, 0x000e },
+ { 13, 0x000d },
+ { 12, 0x000c },
+ { 13, 0x000b },
+ { 13, 0x000a },
+ { 13, 0x0009 },
+ { 13, 0x000c },
+ { 13, 0x0007 },
+ { 14, 0x000b },
+ { 13, 0x0006 },
+ { 13, 0x0008 },
+ { 14, 0x0009 },
+ { 14, 0x0008 },
+ { 14, 0x000a },
+ { 13, 0x0001 },
+ { 14, 0x0007 },
+ { 14, 0x0006 },
+ { 14, 0x0005 },
+ { 14, 0x0004 },
+ { 0, 0x0000 }
+};
+
+static const ARM_VLC32 armVCM4P10_CAVLCCoeffToken2[63] = {
+ { 4, 0x000f },
+ { 6, 0x000f },
+ { 4, 0x000e },
+ { 6, 0x000b },
+ { 5, 0x000f },
+ { 4, 0x000d },
+ { 6, 0x0008 },
+ { 5, 0x000c },
+ { 5, 0x000e },
+ { 4, 0x000c },
+ { 7, 0x000f },
+ { 5, 0x000a },
+ { 5, 0x000b },
+ { 4, 0x000b },
+ { 7, 0x000b },
+ { 5, 0x0008 },
+ { 5, 0x0009 },
+ { 4, 0x000a },
+ { 7, 0x0009 },
+ { 6, 0x000e },
+ { 6, 0x000d },
+ { 4, 0x0009 },
+ { 7, 0x0008 },
+ { 6, 0x000a },
+ { 6, 0x0009 },
+ { 4, 0x0008 },
+ { 8, 0x000f },
+ { 7, 0x000e },
+ { 7, 0x000d },
+ { 5, 0x000d },
+ { 8, 0x000b },
+ { 8, 0x000e },
+ { 7, 0x000a },
+ { 6, 0x000c },
+ { 9, 0x000f },
+ { 8, 0x000a },
+ { 8, 0x000d },
+ { 7, 0x000c },
+ { 9, 0x000b },
+ { 9, 0x000e },
+ { 8, 0x0009 },
+ { 8, 0x000c },
+ { 9, 0x0008 },
+ { 9, 0x000a },
+ { 9, 0x000d },
+ { 8, 0x0008 },
+ { 10, 0x000d },
+ { 9, 0x0007 },
+ { 9, 0x0009 },
+ { 9, 0x000c },
+ { 10, 0x0009 },
+ { 10, 0x000c },
+ { 10, 0x000b },
+ { 10, 0x000a },
+ { 10, 0x0005 },
+ { 10, 0x0008 },
+ { 10, 0x0007 },
+ { 10, 0x0006 },
+ { 10, 0x0001 },
+ { 10, 0x0004 },
+ { 10, 0x0003 },
+ { 10, 0x0002 },
+ { 0, 0x0000 }
+};
+
+static const ARM_VLC32 armVCM4P10_CAVLCCoeffToken3[63] = {
+ { 6, 0x0003 },
+ { 6, 0x0000 },
+ { 6, 0x0001 },
+ { 6, 0x0004 },
+ { 6, 0x0005 },
+ { 6, 0x0006 },
+ { 6, 0x0008 },
+ { 6, 0x0009 },
+ { 6, 0x000a },
+ { 6, 0x000b },
+ { 6, 0x000c },
+ { 6, 0x000d },
+ { 6, 0x000e },
+ { 6, 0x000f },
+ { 6, 0x0010 },
+ { 6, 0x0011 },
+ { 6, 0x0012 },
+ { 6, 0x0013 },
+ { 6, 0x0014 },
+ { 6, 0x0015 },
+ { 6, 0x0016 },
+ { 6, 0x0017 },
+ { 6, 0x0018 },
+ { 6, 0x0019 },
+ { 6, 0x001a },
+ { 6, 0x001b },
+ { 6, 0x001c },
+ { 6, 0x001d },
+ { 6, 0x001e },
+ { 6, 0x001f },
+ { 6, 0x0020 },
+ { 6, 0x0021 },
+ { 6, 0x0022 },
+ { 6, 0x0023 },
+ { 6, 0x0024 },
+ { 6, 0x0025 },
+ { 6, 0x0026 },
+ { 6, 0x0027 },
+ { 6, 0x0028 },
+ { 6, 0x0029 },
+ { 6, 0x002a },
+ { 6, 0x002b },
+ { 6, 0x002c },
+ { 6, 0x002d },
+ { 6, 0x002e },
+ { 6, 0x002f },
+ { 6, 0x0030 },
+ { 6, 0x0031 },
+ { 6, 0x0032 },
+ { 6, 0x0033 },
+ { 6, 0x0034 },
+ { 6, 0x0035 },
+ { 6, 0x0036 },
+ { 6, 0x0037 },
+ { 6, 0x0038 },
+ { 6, 0x0039 },
+ { 6, 0x003a },
+ { 6, 0x003b },
+ { 6, 0x003c },
+ { 6, 0x003d },
+ { 6, 0x003e },
+ { 6, 0x003f },
+ { 0, 0x0000 }
+};
+
+static const ARM_VLC32 armVCM4P10_CAVLCCoeffToken4[15] = {
+ { 2, 0x0001 },
+ { 6, 0x0007 },
+ { 1, 0x0001 },
+ { 6, 0x0004 },
+ { 6, 0x0006 },
+ { 3, 0x0001 },
+ { 6, 0x0003 },
+ { 7, 0x0003 },
+ { 7, 0x0002 },
+ { 6, 0x0005 },
+ { 6, 0x0002 },
+ { 8, 0x0003 },
+ { 8, 0x0002 },
+ { 7, 0x0000 },
+ { 0, 0x0000 }
+};
+
+
+const ARM_VLC32 *armVCM4P10_CAVLCCoeffTokenTables[5] = {
+ armVCM4P10_CAVLCCoeffToken0,
+ armVCM4P10_CAVLCCoeffToken1,
+ armVCM4P10_CAVLCCoeffToken2,
+ armVCM4P10_CAVLCCoeffToken3,
+ armVCM4P10_CAVLCCoeffToken4
+};
+
+/* Table for level_prefix */
+
+const ARM_VLC32 armVCM4P10_CAVLCLevelPrefix[17] = {
+ { 1, 1},
+ { 2, 1},
+ { 3, 1},
+ { 4, 1},
+ { 5, 1},
+ { 6, 1},
+ { 7, 1},
+ { 8, 1},
+ { 9, 1},
+ { 10, 1},
+ { 11, 1},
+ { 12, 1},
+ { 13, 1},
+ { 14, 1},
+ { 15, 1},
+ { 16, 1},
+ { 0, 0}
+};
+
+/* Tables for total_zeros */
+
+static const ARM_VLC32 armVCM4P10_CAVLCTotalZeros1[17] = {
+ { 1, 0x0001 },
+ { 3, 0x0003 },
+ { 3, 0x0002 },
+ { 4, 0x0003 },
+ { 4, 0x0002 },
+ { 5, 0x0003 },
+ { 5, 0x0002 },
+ { 6, 0x0003 },
+ { 6, 0x0002 },
+ { 7, 0x0003 },
+ { 7, 0x0002 },
+ { 8, 0x0003 },
+ { 8, 0x0002 },
+ { 9, 0x0003 },
+ { 9, 0x0002 },
+ { 9, 0x0001 },
+ { 0, 0x0000 }
+};
+
+static const ARM_VLC32 armVCM4P10_CAVLCTotalZeros2[16] = {
+ { 3, 0x0007 },
+ { 3, 0x0006 },
+ { 3, 0x0005 },
+ { 3, 0x0004 },
+ { 3, 0x0003 },
+ { 4, 0x0005 },
+ { 4, 0x0004 },
+ { 4, 0x0003 },
+ { 4, 0x0002 },
+ { 5, 0x0003 },
+ { 5, 0x0002 },
+ { 6, 0x0003 },
+ { 6, 0x0002 },
+ { 6, 0x0001 },
+ { 6, 0x0000 },
+ { 0, 0x0000 }
+};
+
+static const ARM_VLC32 armVCM4P10_CAVLCTotalZeros3[15] = {
+ { 4, 0x0005 },
+ { 3, 0x0007 },
+ { 3, 0x0006 },
+ { 3, 0x0005 },
+ { 4, 0x0004 },
+ { 4, 0x0003 },
+ { 3, 0x0004 },
+ { 3, 0x0003 },
+ { 4, 0x0002 },
+ { 5, 0x0003 },
+ { 5, 0x0002 },
+ { 6, 0x0001 },
+ { 5, 0x0001 },
+ { 6, 0x0000 },
+ { 0, 0x0000 }
+};
+
+static const ARM_VLC32 armVCM4P10_CAVLCTotalZeros4[14] = {
+ { 5, 0x0003 },
+ { 3, 0x0007 },
+ { 4, 0x0005 },
+ { 4, 0x0004 },
+ { 3, 0x0006 },
+ { 3, 0x0005 },
+ { 3, 0x0004 },
+ { 4, 0x0003 },
+ { 3, 0x0003 },
+ { 4, 0x0002 },
+ { 5, 0x0002 },
+ { 5, 0x0001 },
+ { 5, 0x0000 },
+ { 0, 0x0000 }
+};
+
+static const ARM_VLC32 armVCM4P10_CAVLCTotalZeros5[13] = {
+ { 4, 0x0005 },
+ { 4, 0x0004 },
+ { 4, 0x0003 },
+ { 3, 0x0007 },
+ { 3, 0x0006 },
+ { 3, 0x0005 },
+ { 3, 0x0004 },
+ { 3, 0x0003 },
+ { 4, 0x0002 },
+ { 5, 0x0001 },
+ { 4, 0x0001 },
+ { 5, 0x0000 },
+ { 0, 0x0000 }
+};
+
+static const ARM_VLC32 armVCM4P10_CAVLCTotalZeros6[12] = {
+ { 6, 0x0001 },
+ { 5, 0x0001 },
+ { 3, 0x0007 },
+ { 3, 0x0006 },
+ { 3, 0x0005 },
+ { 3, 0x0004 },
+ { 3, 0x0003 },
+ { 3, 0x0002 },
+ { 4, 0x0001 },
+ { 3, 0x0001 },
+ { 6, 0x0000 },
+ { 0, 0x0000 }
+};
+
+static const ARM_VLC32 armVCM4P10_CAVLCTotalZeros7[11] = {
+ { 6, 0x0001 },
+ { 5, 0x0001 },
+ { 3, 0x0005 },
+ { 3, 0x0004 },
+ { 3, 0x0003 },
+ { 2, 0x0003 },
+ { 3, 0x0002 },
+ { 4, 0x0001 },
+ { 3, 0x0001 },
+ { 6, 0x0000 },
+ { 0, 0x0000 }
+};
+
+static const ARM_VLC32 armVCM4P10_CAVLCTotalZeros8[10] = {
+ { 6, 0x0001 },
+ { 4, 0x0001 },
+ { 5, 0x0001 },
+ { 3, 0x0003 },
+ { 2, 0x0003 },
+ { 2, 0x0002 },
+ { 3, 0x0002 },
+ { 3, 0x0001 },
+ { 6, 0x0000 },
+ { 0, 0x0000 }
+};
+
+static const ARM_VLC32 armVCM4P10_CAVLCTotalZeros9[9] = {
+ { 6, 0x0001 },
+ { 6, 0x0000 },
+ { 4, 0x0001 },
+ { 2, 0x0003 },
+ { 2, 0x0002 },
+ { 3, 0x0001 },
+ { 2, 0x0001 },
+ { 5, 0x0001 },
+ { 0, 0x0000 }
+};
+
+static const ARM_VLC32 armVCM4P10_CAVLCTotalZeros10[8] = {
+ { 5, 0x0001 },
+ { 5, 0x0000 },
+ { 3, 0x0001 },
+ { 2, 0x0003 },
+ { 2, 0x0002 },
+ { 2, 0x0001 },
+ { 4, 0x0001 },
+ { 0, 0x0000 }
+};
+
+static const ARM_VLC32 armVCM4P10_CAVLCTotalZeros11[7] = {
+ { 4, 0x0000 },
+ { 4, 0x0001 },
+ { 3, 0x0001 },
+ { 3, 0x0002 },
+ { 1, 0x0001 },
+ { 3, 0x0003 },
+ { 0, 0x0000 }
+};
+
+static const ARM_VLC32 armVCM4P10_CAVLCTotalZeros12[6] = {
+ { 4, 0x0000 },
+ { 4, 0x0001 },
+ { 2, 0x0001 },
+ { 1, 0x0001 },
+ { 3, 0x0001 },
+ { 0, 0x0000 }
+};
+
+static const ARM_VLC32 armVCM4P10_CAVLCTotalZeros13[5] = {
+ { 3, 0x0000 },
+ { 3, 0x0001 },
+ { 1, 0x0001 },
+ { 2, 0x0001 },
+ { 0, 0x0000 }
+};
+
+static const ARM_VLC32 armVCM4P10_CAVLCTotalZeros14[4] = {
+ { 2, 0x0000 },
+ { 2, 0x0001 },
+ { 1, 0x0001 },
+ { 0, 0x0000 }
+};
+
+static const ARM_VLC32 armVCM4P10_CAVLCTotalZeros15[3] = {
+ { 1, 0x0000 },
+ { 1, 0x0001 },
+ { 0, 0x0000 }
+};
+
+const ARM_VLC32 *armVCM4P10_CAVLCTotalZeroTables[15] = {
+ armVCM4P10_CAVLCTotalZeros1,
+ armVCM4P10_CAVLCTotalZeros2,
+ armVCM4P10_CAVLCTotalZeros3,
+ armVCM4P10_CAVLCTotalZeros4,
+ armVCM4P10_CAVLCTotalZeros5,
+ armVCM4P10_CAVLCTotalZeros6,
+ armVCM4P10_CAVLCTotalZeros7,
+ armVCM4P10_CAVLCTotalZeros8,
+ armVCM4P10_CAVLCTotalZeros9,
+ armVCM4P10_CAVLCTotalZeros10,
+ armVCM4P10_CAVLCTotalZeros11,
+ armVCM4P10_CAVLCTotalZeros12,
+ armVCM4P10_CAVLCTotalZeros13,
+ armVCM4P10_CAVLCTotalZeros14,
+ armVCM4P10_CAVLCTotalZeros15
+};
+
+static const ARM_VLC32 armVCM4P10_CAVLCTotalZeros2x2_1[5] = {
+ { 1, 1 },
+ { 2, 1 },
+ { 3, 1 },
+ { 3, 0 },
+ { 0, 0 }
+};
+
+static const ARM_VLC32 armVCM4P10_CAVLCTotalZeros2x2_2[4] = {
+ { 1, 1 },
+ { 2, 1 },
+ { 2, 0 },
+ { 0, 0 }
+};
+
+static const ARM_VLC32 armVCM4P10_CAVLCTotalZeros2x2_3[3] = {
+ { 1, 1 },
+ { 1, 0 },
+ { 0, 0 }
+};
+
+const ARM_VLC32 *armVCM4P10_CAVLCTotalZeros2x2Tables[3] = {
+ armVCM4P10_CAVLCTotalZeros2x2_1,
+ armVCM4P10_CAVLCTotalZeros2x2_2,
+ armVCM4P10_CAVLCTotalZeros2x2_3
+};
+
+
+/* Tables for run_before */
+
+static const ARM_VLC32 armVCM4P10_CAVLCRunBefore1[3] = {
+ { 1, 0x0001 },
+ { 1, 0x0000 },
+ { 0, 0x0000 }
+};
+
+static const ARM_VLC32 armVCM4P10_CAVLCRunBefore2[4] = {
+ { 1, 0x0001 },
+ { 2, 0x0001 },
+ { 2, 0x0000 },
+ { 0, 0x0000 }
+};
+
+static const ARM_VLC32 armVCM4P10_CAVLCRunBefore3[5] = {
+ { 2, 0x0003 },
+ { 2, 0x0002 },
+ { 2, 0x0001 },
+ { 2, 0x0000 },
+ { 0, 0x0000 }
+};
+
+static const ARM_VLC32 armVCM4P10_CAVLCRunBefore4[6] = {
+ { 2, 0x0003 },
+ { 2, 0x0002 },
+ { 2, 0x0001 },
+ { 3, 0x0001 },
+ { 3, 0x0000 },
+ { 0, 0x0000 }
+};
+
+static const ARM_VLC32 armVCM4P10_CAVLCRunBefore5[7] = {
+ { 2, 0x0003 },
+ { 2, 0x0002 },
+ { 3, 0x0003 },
+ { 3, 0x0002 },
+ { 3, 0x0001 },
+ { 3, 0x0000 },
+ { 0, 0x0000 }
+};
+
+static const ARM_VLC32 armVCM4P10_CAVLCRunBefore6[8] = {
+ { 2, 0x0003 },
+ { 3, 0x0000 },
+ { 3, 0x0001 },
+ { 3, 0x0003 },
+ { 3, 0x0002 },
+ { 3, 0x0005 },
+ { 3, 0x0004 },
+ { 0, 0x0000 }
+};
+
+static const ARM_VLC32 armVCM4P10_CAVLCRunBefore7[16] = {
+ { 3, 0x0007 },
+ { 3, 0x0006 },
+ { 3, 0x0005 },
+ { 3, 0x0004 },
+ { 3, 0x0003 },
+ { 3, 0x0002 },
+ { 3, 0x0001 },
+ { 4, 0x0001 },
+ { 5, 0x0001 },
+ { 6, 0x0001 },
+ { 7, 0x0001 },
+ { 8, 0x0001 },
+ { 9, 0x0001 },
+ { 10, 0x0001 },
+ { 11, 0x0001 },
+ { 0, 0x0000 }
+};
+
+const ARM_VLC32 *armVCM4P10_CAVLCRunBeforeTables[7] = {
+ armVCM4P10_CAVLCRunBefore1,
+ armVCM4P10_CAVLCRunBefore2,
+ armVCM4P10_CAVLCRunBefore3,
+ armVCM4P10_CAVLCRunBefore4,
+ armVCM4P10_CAVLCRunBefore5,
+ armVCM4P10_CAVLCRunBefore6,
+ armVCM4P10_CAVLCRunBefore7
+};
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_CompareMotionCostToMV.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_CompareMotionCostToMV.c
new file mode 100644
index 0000000..e4bedc2
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_CompareMotionCostToMV.c
@@ -0,0 +1,133 @@
+/**
+ *
+ * File Name: armVCM4P10_CompareMotionCostToMV.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains module for comparing motion vectors and SAD's to decide
+ * the best MV and SAD
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+
+#include "armVC.h"
+#include "armCOMM.h"
+
+/**
+ * Function: armVCM4P10_ExpGolBitsUsed
+ *
+ * Description:
+ * Performs calculating Exp-Golomb code length for a given values
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] val Signed number for which Exp-Golomb code length has
+ * to be calculated
+ *
+ * Return Value:
+ * Returns the length of the Exp-Golomb code for val
+ */
+
+static OMX_U16 armVCM4P10_ExpGolBitsUsed (OMX_S16 val)
+{
+ OMX_U16 sizeCodeNum, codeNum;
+
+ /* Mapping val to codeNum */
+ codeNum = armAbs (val);
+ if (val > 0)
+ {
+ codeNum = (2 * codeNum) - 1;
+ }
+ else
+ {
+ codeNum = 2 * codeNum;
+ }
+
+ /* Size of the exp-golomb code */
+ sizeCodeNum = (2 * armLogSize (codeNum + 1)) - 1;
+
+ return sizeCodeNum;
+}
+
+
+/**
+ * Function: armVCM4P10_CompareMotionCostToMV
+ *
+ * Description:
+ * Performs comparision of motion vectors and Motion cost to decide the
+ * best MV and best MC
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] mvX x coordinate of the candidate motion vector in 1/4 pel units
+ * [in] mvY y coordinate of the candidate motion vector in 1/4 pel units
+ * [in] diffMV differential MV
+ * [in] candSAD Candidate SAD
+ * [in] bestMV Best MV, contains best MV till the previous interation.
+ * [in] nLamda Lamda factor; used to compute motion cost
+ * [in] *pBestCost Contains the current best motion cost.
+ * [out] *pBestCost pBestCost Motion cost will be associated with the best MV
+ * after judgement;
+ * computed as SAD+Lamda*BitsUsedByMV, if the candCost is less
+ * than the best cost passed then the *pBestCost will be equal to candCost
+ * [out] bestMV Finally will have the best MV after the judgement.
+ *
+ * Return Value:
+ * OMX_INT -- 1 to indicate that the current motion cost is the best
+ * 0 to indicate that it is NOT the best motion cost
+ */
+
+OMX_INT armVCM4P10_CompareMotionCostToMV (
+ OMX_S16 mvX,
+ OMX_S16 mvY,
+ OMXVCMotionVector diffMV,
+ OMX_INT candSAD,
+ OMXVCMotionVector *bestMV,
+ OMX_U32 nLamda,
+ OMX_S32 *pBestCost
+)
+{
+ OMX_S32 candCost;
+ OMX_U16 sizeCodeNum;
+
+ sizeCodeNum = armVCM4P10_ExpGolBitsUsed (diffMV.dx);
+ sizeCodeNum += armVCM4P10_ExpGolBitsUsed (diffMV.dy);
+
+ /* Motion cost = SAD + lamda * ((bitsused(diffMVx) + (bitsused(diffMVy))*/
+ candCost = candSAD + (nLamda * sizeCodeNum);
+
+ /* Calculate candCost */
+ if (candCost < *pBestCost)
+ {
+ *pBestCost = candCost;
+ bestMV->dx = mvX;
+ bestMV->dy = mvY;
+ return 1;
+ }
+ if (candCost > *pBestCost)
+ {
+ return 0;
+ }
+ /* shorter motion vector */
+ if ( (mvX * mvX + mvY * mvY) < ((bestMV->dx * bestMV->dx) + (bestMV->dy * bestMV->dy)) )
+ {
+ *pBestCost = candCost;
+ bestMV->dx = mvX;
+ bestMV->dy = mvY;
+ return 1;
+ }
+
+ return 0;
+}
+
+/*End of File*/
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_DeBlockPixel.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_DeBlockPixel.c
new file mode 100644
index 0000000..f4fb1d9
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_DeBlockPixel.c
@@ -0,0 +1,151 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: armVCM4P10_DeBlockPixel.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * H.264 luma deblock module
+ *
+ */
+
+#ifdef DEBUG_ARMVCM4P10_DEBLOCKPIXEL
+#undef DEBUG_ON
+#define DEBUG_ON
+#endif /* DEBUG_ARMVCM4P10_DEBLOCKPIXEL */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/*
+ * Description
+ * Deblock one boundary pixel
+ *
+ * Parameters:
+ * [in] pQ0 Pointer to pixel q0
+ * [in] Step Step between pixels q0 and q1
+ * [in] tC0 Edge threshold value
+ * [in] alpha alpha threshold value
+ * [in] beta beta threshold value
+ * [in] bS deblocking strength
+ * [in] ChromaFlag True for chroma blocks
+ * [out] pQ0 Deblocked pixels
+ *
+ */
+
+void armVCM4P10_DeBlockPixel(
+ OMX_U8 *pQ0, /* pointer to the pixel q0 */
+ int Step, /* step between pixels q0 and q1 */
+ int tC0, /* edge threshold value */
+ int alpha, /* alpha */
+ int beta, /* beta */
+ int bS, /* deblocking strength */
+ int ChromaFlag
+)
+{
+ int p3, p2, p1, p0, q0, q1, q2, q3;
+ int ap, aq, delta;
+
+ if (bS==0)
+ {
+ return;
+ }
+
+ p3 = pQ0[-4*Step];
+ p2 = pQ0[-3*Step];
+ p1 = pQ0[-2*Step];
+ p0 = pQ0[-1*Step];
+ q0 = pQ0[ 0*Step];
+ q1 = pQ0[ 1*Step];
+ q2 = pQ0[ 2*Step];
+ q3 = pQ0[ 3*Step];
+
+ if (armAbs(p0-q0)>=alpha || armAbs(p1-p0)>=beta || armAbs(q1-q0)>=beta)
+ {
+ DEBUG_PRINTF_10("DeBlockPixel: %02x %02x %02x %02x | %02x %02x %02x %02x alpha=%d beta=%d\n",
+ p3, p2, p1, p0, q0, q1, q2, q3, alpha, beta);
+ return;
+ }
+
+ ap = armAbs(p2 - p0);
+ aq = armAbs(q2 - q0);
+
+ if (bS < 4)
+ {
+ int tC = tC0;
+
+ if (ChromaFlag)
+ {
+ tC++;
+ }
+ else
+ {
+ if (ap < beta)
+ {
+ tC++;
+ }
+ if (aq < beta)
+ {
+ tC++;
+ }
+ }
+
+ delta = (((q0-p0)<<2) + (p1-q1) + 4) >> 3;
+ delta = armClip(-tC, tC, delta);
+
+ pQ0[-1*Step] = (OMX_U8)armClip(0, 255, p0 + delta);
+ pQ0[ 0*Step] = (OMX_U8)armClip(0, 255, q0 - delta);
+
+ if (ChromaFlag==0 && ap<beta)
+ {
+ delta = (p2 + ((p0+q0+1)>>1) - (p1<<1))>>1;
+ delta = armClip(-tC0, tC0, delta);
+ pQ0[-2*Step] = (OMX_U8)(p1 + delta);
+ }
+
+ if (ChromaFlag==0 && aq<beta)
+ {
+ delta = (q2 + ((p0+q0+1)>>1) - (q1<<1))>>1;
+ delta = armClip(-tC0, tC0, delta);
+ pQ0[ 1*Step] = (OMX_U8)(q1 + delta);
+ }
+ }
+ else /* bS==4 */
+ {
+ if (ChromaFlag==0 && ap<beta && armAbs(p0-q0)<((alpha>>2)+2))
+ {
+ pQ0[-1*Step] = (OMX_U8)((p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4)>>3);
+ pQ0[-2*Step] = (OMX_U8)((p2 + p1 + p0 + q0 + 2)>>2);
+ pQ0[-3*Step] = (OMX_U8)((2*p3 + 3*p2 + p1 + p0 + q0 + 4)>>3);
+ }
+ else
+ {
+ pQ0[-1*Step] = (OMX_U8)((2*p1 + p0 + q1 + 2)>>2);
+ }
+
+ if (ChromaFlag==0 && aq<beta && armAbs(p0-q0)<((alpha>>2)+2))
+ {
+ pQ0[ 0*Step] = (OMX_U8)((q2 + 2*q1 + 2*q0 + 2*p0 + p1 + 4)>>3);
+ pQ0[ 1*Step] = (OMX_U8)((q2 + q1 + p0 + q0 + 2)>>2);
+ pQ0[ 2*Step] = (OMX_U8)((2*q3 + 3*q2 + q1 + q0 + p0 + 4)>>3);
+ }
+ else
+ {
+ pQ0[ 0*Step] = (OMX_U8)((2*q1 + q0 + p1 + 2)>>2);
+ }
+ }
+
+ DEBUG_PRINTF_13("DeBlockPixel: %02x %02x %02x %02x | %02x %02x %02x %02x bS=%d -> %02x %02x %02x %02x\n",
+ p3, p2, p1, p0, q0, q1, q2, q3, bS,
+ pQ0[-2*Step], pQ0[-1*Step],pQ0[0*Step],pQ0[1*Step]);
+
+}
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_DecodeCoeffsToPair.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_DecodeCoeffsToPair.c
new file mode 100644
index 0000000..7616add
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_DecodeCoeffsToPair.c
@@ -0,0 +1,267 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: armVCM4P10_DecodeCoeffsToPair.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * H.264 decode coefficients module
+ *
+ */
+
+#ifdef DEBUG_ARMVCM4P10_DECODECOEFFSTOPAIR
+#undef DEBUG_ON
+#define DEBUG_ON
+#endif
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armCOMM_Bitstream.h"
+#include "armVCM4P10_CAVLCTables.h"
+
+/* 4x4 DeZigZag table */
+
+static const OMX_U8 armVCM4P10_ZigZag[16] =
+{
+ 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15
+};
+
+/*
+ * Description:
+ * This function perform the work required by the OpenMAX
+ * DecodeCoeffsToPair function and DecodeChromaDCCoeffsToPair.
+ * Since most of the code is common we share it here.
+ *
+ * Parameters:
+ * [in] ppBitStream Double pointer to current byte in bit stream buffer
+ * [in] pOffset Pointer to current bit position in the byte pointed
+ * to by *ppBitStream
+ * [in] sMaxNumCoeff Maximum number of non-zero coefficients in current
+ * block (4,15 or 16)
+ * [in] nTable Table number (0 to 4) according to the five columns
+ * of Table 9-5 in the H.264 spec
+ * [out] ppBitStream *ppBitStream is updated after each block is decoded
+ * [out] pOffset *pOffset is updated after each block is decoded
+ * [out] pNumCoeff Pointer to the number of nonzero coefficients in
+ * this block
+ * [out] ppPosCoefbuf Double pointer to destination residual
+ * coefficient-position pair buffer
+ * Return Value:
+ * Standard omxError result. See enumeration for possible result codes.
+
+ */
+
+OMXResult armVCM4P10_DecodeCoeffsToPair(
+ const OMX_U8** ppBitStream,
+ OMX_S32* pOffset,
+ OMX_U8* pNumCoeff,
+ OMX_U8 **ppPosCoefbuf,
+ OMX_INT nTable,
+ OMX_INT sMaxNumCoeff
+ )
+{
+ int CoeffToken, TotalCoeff, TrailingOnes;
+ int Level, LevelCode, LevelPrefix, LevelSuffix, LevelSuffixSize;
+ int SuffixLength, Run, ZerosLeft,CoeffNum;
+ int i, Flags;
+ OMX_U8 *pPosCoefbuf = *ppPosCoefbuf;
+ OMX_S16 pLevel[16];
+ OMX_U8 pRun[16];
+
+ CoeffToken = armUnPackVLC32(ppBitStream, pOffset, armVCM4P10_CAVLCCoeffTokenTables[nTable]);
+ armRetDataErrIf(CoeffToken == ARM_NO_CODEBOOK_INDEX, OMX_Sts_Err);
+
+ TrailingOnes = armVCM4P10_CAVLCTrailingOnes[CoeffToken];
+ TotalCoeff = armVCM4P10_CAVLCTotalCoeff[CoeffToken];
+ *pNumCoeff = (OMX_U8)TotalCoeff;
+
+ DEBUG_PRINTF_2("TotalCoeff = %d, TrailingOnes = %d\n", TotalCoeff, TrailingOnes);
+
+ if (TotalCoeff == 0)
+ {
+ /* Nothing to do */
+ return OMX_Sts_NoErr;
+ }
+
+ /* Decode trailing ones */
+ for (i=TotalCoeff-1; i>=TotalCoeff-TrailingOnes; i--)
+ {
+ if (armGetBits(ppBitStream, pOffset, 1))
+ {
+ Level = -1;
+ }
+ else
+ {
+ Level = +1;
+ }
+ pLevel[i] = (OMX_S16)Level;
+
+ DEBUG_PRINTF_2("Level[%d] = %d\n", i, pLevel[i]);
+ }
+
+ /* Decode (non zero) level values */
+ SuffixLength = 0;
+ if (TotalCoeff>10 && TrailingOnes<3)
+ {
+ SuffixLength=1;
+ }
+ for ( ; i>=0; i--)
+ {
+ LevelPrefix = armUnPackVLC32(ppBitStream, pOffset, armVCM4P10_CAVLCLevelPrefix);
+ armRetDataErrIf(LevelPrefix == ARM_NO_CODEBOOK_INDEX, OMX_Sts_Err);
+
+ LevelSuffixSize = SuffixLength;
+ if (LevelPrefix==14 && SuffixLength==0)
+ {
+ LevelSuffixSize = 4;
+ }
+ if (LevelPrefix==15)
+ {
+ LevelSuffixSize = 12;
+ }
+
+ LevelSuffix = 0;
+ if (LevelSuffixSize > 0)
+ {
+ LevelSuffix = armGetBits(ppBitStream, pOffset, LevelSuffixSize);
+ }
+
+ LevelCode = (LevelPrefix << SuffixLength) + LevelSuffix;
+
+
+ if (LevelPrefix==15 && SuffixLength==0)
+ {
+ LevelCode += 15;
+ }
+
+ /* LevelCode = 2*(magnitude-1) + sign */
+
+ if (i==TotalCoeff-1-TrailingOnes && TrailingOnes<3)
+ {
+ /* Level magnitude can't be 1 */
+ LevelCode += 2;
+ }
+ if (LevelCode & 1)
+ {
+ /* 2a+1 maps to -a-1 */
+ Level = (-LevelCode-1)>>1;
+ }
+ else
+ {
+ /* 2a+0 maps to +a+1 */
+ Level = (LevelCode+2)>>1;
+ }
+ pLevel[i] = (OMX_S16)Level;
+
+ DEBUG_PRINTF_2("Level[%d] = %d\n", i, pLevel[i]);
+
+ if (SuffixLength==0)
+ {
+ SuffixLength=1;
+ }
+ if ( ((LevelCode>>1)+1)>(3<<(SuffixLength-1)) && SuffixLength<6 )
+ {
+ SuffixLength++;
+ }
+ }
+
+ /* Decode run values */
+ ZerosLeft = 0;
+ if (TotalCoeff < sMaxNumCoeff)
+ {
+ /* Decode TotalZeros VLC */
+ if (sMaxNumCoeff==4)
+ {
+ ZerosLeft = armUnPackVLC32(ppBitStream, pOffset, armVCM4P10_CAVLCTotalZeros2x2Tables[TotalCoeff-1]);
+ armRetDataErrIf(ZerosLeft ==ARM_NO_CODEBOOK_INDEX , OMX_Sts_Err);
+ }
+ else
+ {
+ ZerosLeft = armUnPackVLC32(ppBitStream, pOffset, armVCM4P10_CAVLCTotalZeroTables[TotalCoeff-1]);
+ armRetDataErrIf(ZerosLeft ==ARM_NO_CODEBOOK_INDEX , OMX_Sts_Err);
+ }
+ }
+
+ DEBUG_PRINTF_1("TotalZeros = %d\n", ZerosLeft);
+
+ CoeffNum=ZerosLeft+TotalCoeff-1;
+
+ for (i=TotalCoeff-1; i>0; i--)
+ {
+ Run = 0;
+ if (ZerosLeft > 0)
+ {
+ int Table = ZerosLeft;
+ if (Table > 6)
+ {
+ Table = 7;
+ }
+ Run = armUnPackVLC32(ppBitStream, pOffset, armVCM4P10_CAVLCRunBeforeTables[Table-1]);
+ armRetDataErrIf(Run == ARM_NO_CODEBOOK_INDEX, OMX_Sts_Err);
+ }
+ pRun[i] = (OMX_U8)Run;
+
+ DEBUG_PRINTF_2("Run[%d] = %d\n", i, pRun[i]);
+
+ ZerosLeft -= Run;
+ }
+ pRun[0] = (OMX_U8)ZerosLeft;
+
+ DEBUG_PRINTF_1("Run[0] = %d\n", pRun[i]);
+
+
+ /* Fill in coefficients */
+
+ if (sMaxNumCoeff==15)
+ {
+ CoeffNum++; /* Skip the DC position */
+ }
+
+ /*for (i=0;i<TotalCoeff;i++)
+ CoeffNum += pRun[i]+1;*/
+
+ for (i=(TotalCoeff-1); i>=0; i--)
+ {
+ /*CoeffNum += pRun[i]+1;*/
+ Level = pLevel[i];
+
+ DEBUG_PRINTF_2("Coef[%d] = %d\n", CoeffNum, Level);
+
+ Flags = CoeffNum;
+ CoeffNum -= (pRun[i]+1);
+ if (sMaxNumCoeff>4)
+ {
+ /* Perform 4x4 DeZigZag */
+ Flags = armVCM4P10_ZigZag[Flags];
+ }
+ if (i==0)
+ {
+ /* End of block flag */
+ Flags += 0x20;
+ }
+ if (Level<-128 || Level>127)
+ {
+ /* Overflow flag */
+ Flags += 0x10;
+ }
+
+ *pPosCoefbuf++ = (OMX_U8)(Flags);
+ *pPosCoefbuf++ = (OMX_U8)(Level & 0xFF);
+ if (Flags & 0x10)
+ {
+ *pPosCoefbuf++ = (OMX_U8)(Level>>8);
+ }
+ }
+
+ *ppPosCoefbuf = pPosCoefbuf;
+
+ return OMX_Sts_NoErr;
+}
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_DequantTables.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_DequantTables.c
new file mode 100644
index 0000000..d9c2541
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_DequantTables.c
@@ -0,0 +1,45 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: armVCM4P10_DequantTables.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * H.264 inverse quantize tables
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+#include "armVC.h"
+
+
+const OMX_U8 armVCM4P10_PosToVCol4x4[16] =
+{
+ 0, 2, 0, 2,
+ 2, 1, 2, 1,
+ 0, 2, 0, 2,
+ 2, 1, 2, 1
+};
+
+const OMX_U8 armVCM4P10_PosToVCol2x2[4] =
+{
+ 0, 2,
+ 2, 1
+};
+
+const OMX_U8 armVCM4P10_VMatrix[6][3] =
+{
+ { 10, 16, 13 },
+ { 11, 18, 14 },
+ { 13, 20, 16 },
+ { 14, 23, 18 },
+ { 16, 25, 20 },
+ { 18, 29, 23 }
+};
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_FwdTransformResidual4x4.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_FwdTransformResidual4x4.c
new file mode 100644
index 0000000..93d54c3
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_FwdTransformResidual4x4.c
@@ -0,0 +1,78 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: armVCM4P10_FwdTransformResidual4x4.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * H.264 transform module
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/*
+ * Description:
+ * Forward Transform Residual 4x4 Coefficients
+ *
+ * Parameters:
+ * [in] pSrc Source 4x4 block
+ * [out] pDst Destination 4x4 block
+ *
+ */
+void armVCM4P10_FwdTransformResidual4x4(OMX_S16* pDst, OMX_S16 *pSrc)
+{
+ int i;
+
+ /* Transform rows */
+ for (i=0; i<16; i+=4)
+ {
+ int d0 = pSrc[i+0];
+ int d1 = pSrc[i+1];
+ int d2 = pSrc[i+2];
+ int d3 = pSrc[i+3];
+ int e0 = d0 + d3;
+ int e1 = d0 - d3;
+ int e2 = d1 + d2;
+ int e3 = d1 - d2;
+ int f0 = e0 + e2;
+ int f1 = (e1 << 1) + e3;
+ int f2 = e0 - e2;
+ int f3 = e1 - (e3 << 1);
+ pDst[i+0] = (OMX_S16)f0;
+ pDst[i+1] = (OMX_S16)f1;
+ pDst[i+2] = (OMX_S16)f2;
+ pDst[i+3] = (OMX_S16)f3;
+ }
+
+ /* Transform columns */
+ for (i=0; i<4; i++)
+ {
+ int f0 = pDst[i+0];
+ int f1 = pDst[i+4];
+ int f2 = pDst[i+8];
+ int f3 = pDst[i+12];
+ int g0 = f0 + f3;
+ int g1 = f0 - f3;
+ int g2 = f1 + f2;
+ int g3 = f1 - f2;
+ int h0 = g0 + g2;
+ int h1 = (g1 << 1) + g3;
+ int h2 = g0 - g2;
+ int h3 = g1 - (g3 << 1);
+ pDst[i+0] = (OMX_S16) h0;
+ pDst[i+4] = (OMX_S16) h1;
+ pDst[i+8] = (OMX_S16) h2;
+ pDst[i+12] = (OMX_S16) h3;
+ }
+}
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_InterpolateHalfDiag_Luma.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_InterpolateHalfDiag_Luma.c
new file mode 100644
index 0000000..8732f4f
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_InterpolateHalfDiag_Luma.c
@@ -0,0 +1,106 @@
+/**
+ *
+ * File Name: armVCM4P10_InterpolateHalfDiag_Luma.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ * Description:
+ * This functions will help to calculate Half Pel luma interpolation
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+
+/**
+ * Function: armVCM4P10_InterpolateHalfDiag_Luma
+ *
+ * Description:
+ * This function performs interpolation for (1/2, 1/2) positions
+ * around a full-pel position.
+ *
+ * Remarks:
+ *
+ * [in] pSrc Pointer to top-left corner of block used to interpolate
+ * in the reconstructed frame plane
+ * [in] iSrcStep Step of the source buffer.
+ * [in] iDstStep Step of the destination(interpolation) buffer.
+ * [in] iWidth Width of the current block
+ * [in] iHeight Height of the current block
+ * [out] pDst Pointer to the interpolation buffer of the (1/2,1/2)-pel
+ *
+ * Return Value:
+ * Standard OMXResult value.
+ *
+ */
+
+OMXResult armVCM4P10_InterpolateHalfDiag_Luma(
+ const OMX_U8* pSrc,
+ OMX_U32 iSrcStep,
+ OMX_U8* pDst,
+ OMX_U32 iDstStep,
+ OMX_U32 iWidth,
+ OMX_U32 iHeight
+)
+{
+ OMX_S32 HalfCoeff, pos;
+ OMX_S16 Buf [21 * 16]; /* 21 rows by 16 pixels per row */
+ OMX_U32 y, x;
+
+ /* check for argument error */
+ armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr)
+
+ /*
+ * Intermediate values will be 1/2 pel at Horizontal direction
+ * Starting at (0.5, -2) at top extending to (0.5, height + 3) at bottom
+ * Buf contains a 2D array of size (iWidth)X(iHeight + 5)
+ */
+ for (y = 0; y < iHeight + 5; y++)
+ {
+ for (x = 0; x < iWidth; x++)
+ {
+ pos = (y-2) * iSrcStep + x;
+ HalfCoeff =
+ pSrc [pos - 2] -
+ 5 * pSrc [pos - 1] +
+ 20 * pSrc [pos] +
+ 20 * pSrc [pos + 1] -
+ 5 * pSrc [pos + 2] +
+ pSrc [pos + 3];
+ Buf [y * iWidth + x] = (OMX_S16)HalfCoeff;
+ } /* x */
+ } /* y */
+
+ /* Vertical interpolate */
+ for (y = 0; y < iHeight; y++)
+ {
+ for (x = 0; x < iWidth; x++)
+ {
+ pos = y * iWidth + x;
+ HalfCoeff =
+ Buf [pos] -
+ 5 * Buf [pos + 1 * iWidth] +
+ 20 * Buf [pos + 2 * iWidth] +
+ 20 * Buf [pos + 3 * iWidth] -
+ 5 * Buf [pos + 4 * iWidth] +
+ Buf [pos + 5 * iWidth];
+
+ HalfCoeff = (HalfCoeff + 512) >> 10;
+ HalfCoeff = armClip(0, 255, HalfCoeff);
+
+ pDst [y * iDstStep + x] = (OMX_U8) HalfCoeff;
+ }
+ }
+
+ return OMX_Sts_NoErr;
+}
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_InterpolateHalfHor_Luma.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_InterpolateHalfHor_Luma.c
new file mode 100644
index 0000000..89c0079
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_InterpolateHalfHor_Luma.c
@@ -0,0 +1,82 @@
+/**
+ *
+ * File Name: armVCM4P10_InterpolateHalfHor_Luma.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ * Description:
+ * This functions will help to calculate Half Pel luma interpolation
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/**
+ * Function: armVCM4P10_InterpolateHalfHor_Luma
+ *
+ * Description:
+ * This function performs interpolation for horizontal 1/2-pel positions
+ *
+ * Remarks:
+ *
+ * [in] pSrc Pointer to top-left corner of block used to interpolate
+ * in the reconstructed frame plane
+ * [in] iSrcStep Step of the source buffer.
+ * [in] iDstStep Step of the destination(interpolation) buffer.
+ * [in] iWidth Width of the current block
+ * [in] iHeight Height of the current block
+ * [out] pDst Pointer to the interpolation buffer of the 1/2-pel
+ *
+ * Return Value:
+ * Standard OMXResult value.
+ *
+ */
+
+OMXResult armVCM4P10_InterpolateHalfHor_Luma(
+ const OMX_U8* pSrc,
+ OMX_U32 iSrcStep,
+ OMX_U8* pDst,
+ OMX_U32 iDstStep,
+ OMX_U32 iWidth,
+ OMX_U32 iHeight
+)
+{
+ OMX_INT x, y;
+ OMX_S32 HalfCoeff, pos;
+
+ /* check for argument error */
+ armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr)
+
+ for (y = 0; y < iHeight; y++)
+ {
+ for (x = 0; x < iWidth; x++)
+ {
+ pos = y * iSrcStep + x;
+ HalfCoeff =
+ pSrc [pos - 2] -
+ 5 * pSrc [pos - 1] +
+ 20 * pSrc [pos] +
+ 20 * pSrc [pos + 1] -
+ 5 * pSrc [pos + 2] +
+ pSrc [pos + 3];
+
+ HalfCoeff = (HalfCoeff + 16) >> 5;
+ HalfCoeff = armClip(0, 255, HalfCoeff);
+
+ pDst [y * iDstStep + x] = HalfCoeff;
+ } /* x */
+ } /* y */
+
+ return OMX_Sts_NoErr;
+}
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_InterpolateHalfVer_Luma.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_InterpolateHalfVer_Luma.c
new file mode 100644
index 0000000..f7ecfc5
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_InterpolateHalfVer_Luma.c
@@ -0,0 +1,84 @@
+/**
+ *
+ * File Name: armVCM4P10_InterpolateHalfVer_Luma.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ * Description:
+ * This functions will help to calculate Half Pel luma interpolation
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/**
+ * Function: armVCM4P10_InterpolateHalfVer_Luma
+ *
+ * Description:
+ * This function performs interpolation for vertical 1/2-pel positions
+ * around a full-pel position.
+ *
+ * Remarks:
+ *
+ * [in] pSrc Pointer to top-left corner of block used to interpolate
+ * in the reconstructed frame plane
+ * [in] iSrcStep Step of the source buffer.
+ * [in] iDstStep Step of the destination(interpolation) buffer.
+ * [in] iWidth Width of the current block
+ * [in] iHeight Height of the current block
+ * [out] pDst Pointer to the interpolation buffer of the 1/2-pel
+ *
+ * Return Value:
+ * Standard OMXResult value.
+ *
+ */
+
+OMXResult armVCM4P10_InterpolateHalfVer_Luma(
+ const OMX_U8* pSrc,
+ OMX_U32 iSrcStep,
+ OMX_U8* pDst,
+ OMX_U32 iDstStep,
+ OMX_U32 iWidth,
+ OMX_U32 iHeight
+)
+{
+ OMX_S32 HalfCoeff, pos;
+ OMX_INT y, x;
+
+ /* check for argument error */
+ armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr)
+
+
+ for (y = 0; y < iHeight; y++)
+ {
+ for (x = 0; x < iWidth; x++)
+ {
+ pos = y * iSrcStep + x;
+ HalfCoeff =
+ pSrc [pos - 2 * iSrcStep] -
+ 5 * pSrc [pos - 1 * iSrcStep] +
+ 20 * pSrc [pos] +
+ 20 * pSrc [pos + 1 * iSrcStep] -
+ 5 * pSrc [pos + 2 * iSrcStep] +
+ pSrc [pos + 3 * iSrcStep];
+
+ HalfCoeff = (HalfCoeff + 16) >> 5;
+ HalfCoeff = armClip(0, 255, HalfCoeff);
+
+ pDst [y * iDstStep + x] = (OMX_U8) HalfCoeff;
+ }
+ }
+
+ return OMX_Sts_NoErr;
+}
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_Interpolate_Chroma.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_Interpolate_Chroma.c
new file mode 100644
index 0000000..1507d23
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_Interpolate_Chroma.c
@@ -0,0 +1,109 @@
+/**
+ *
+ * File Name: armVCM4P10_Interpolate_Chroma.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ * Description:
+ * This function will calculate interpolation for chroma components
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+
+#include "armCOMM.h"
+
+/**
+ * Function: armVCM4P10_Interpolate_Chroma
+ *
+ * Description:
+ * This function performs interpolation for chroma components.
+ *
+ * Remarks:
+ *
+ * [in] pSrc Pointer to top-left corner of block used to
+ * interpolate in the reconstructed frame plane
+ * [in] iSrcStep Step of the source buffer.
+ * [in] iDstStep Step of the destination(interpolation) buffer.
+ * [in] iWidth Width of the current block
+ * [in] iHeight Height of the current block
+ * [in] dx Fractional part of horizontal motion vector
+ * component in 1/8 pixel unit (0~7)
+ * [in] dy Fractional part of vertical motion vector
+ * component in 1/8 pixel unit (0~7)
+ * [out] pDst Pointer to the interpolation buffer
+ *
+ * Return Value:
+ * Standard OMXResult value.
+ *
+ */
+ OMXResult armVCM4P10_Interpolate_Chroma(
+ OMX_U8 *pSrc,
+ OMX_U32 iSrcStep,
+ OMX_U8 *pDst,
+ OMX_U32 iDstStep,
+ OMX_U32 iWidth,
+ OMX_U32 iHeight,
+ OMX_U32 dx,
+ OMX_U32 dy
+)
+{
+ OMX_U32 EightMinusdx = 8 - dx;
+ OMX_U32 EightMinusdy = 8 - dy;
+ OMX_U32 ACoeff, BCoeff, CCoeff, DCoeff;
+ OMX_U32 x, y;
+
+ /* check for argument error */
+ armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(dx > 7, OMX_Sts_BadArgErr)
+ armRetArgErrIf(dy > 7, OMX_Sts_BadArgErr)
+ armRetArgErrIf(iSrcStep == 0, OMX_Sts_BadArgErr)
+ armRetArgErrIf(iDstStep == 0, OMX_Sts_BadArgErr)
+ armRetArgErrIf(iWidth == 0, OMX_Sts_BadArgErr)
+ armRetArgErrIf(iHeight == 0, OMX_Sts_BadArgErr)
+
+ /* if fractionl mv is not (0, 0) */
+ if (dx != 0 || dy != 0)
+ {
+ ACoeff = EightMinusdx * EightMinusdy;
+ BCoeff = dx * EightMinusdy;
+ CCoeff = EightMinusdx * dy;
+ DCoeff = dx * dy;
+
+ for (y = 0; y < iHeight; y++)
+ {
+ for (x = 0; x < iWidth; x++)
+ {
+ pDst [y * iDstStep + x] = (
+ ACoeff * pSrc [y * iSrcStep + x] +
+ BCoeff * pSrc [y * iSrcStep + x + 1] +
+ CCoeff * pSrc [(y + 1) * iSrcStep + x] +
+ DCoeff * pSrc [(y + 1) * iSrcStep + x + 1] +
+ 32) >> 6;
+ }
+ }
+ }
+ else
+ {
+ for (y = 0; y < iHeight; y++)
+ {
+ for (x = 0; x < iWidth; x++)
+ {
+ pDst [y * iDstStep + x] = pSrc [y * iSrcStep + x];
+ }
+ }
+ }
+
+ return OMX_Sts_NoErr;
+}
+
+/*****************************************************************************
+ * END OF FILE
+ *****************************************************************************/
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_Interpolate_Luma.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_Interpolate_Luma.c
new file mode 100644
index 0000000..89978dd
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_Interpolate_Luma.c
@@ -0,0 +1,195 @@
+/**
+ *
+ * File Name: armVCM4P10_Interpolate_Luma.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ * Description:
+ * This function will calculate interpolation for luma components
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/**
+ * Function: armM4P10_Copy
+ *
+ * Description:
+ * This function performs copy a block of data from source to destination
+ *
+ * Remarks:
+ *
+ * [in] pSrc Pointer to top-left corner of block
+ * [in] iSrcStep Step of the source buffer.
+ * [in] iDstStep Step of the destination buffer.
+ * [in] iWidth Width of the current block
+ * [in] iHeight Height of the current block
+ * [out] pDst Pointer to the interpolation buffer
+ *
+ * Return Value:
+ * Standard OMXResult value.
+ *
+ */
+static OMXResult armM4P10_Copy(
+ const OMX_U8* pSrc,
+ OMX_U32 iSrcStep,
+ OMX_U8* pDst,
+ OMX_U32 iDstStep,
+ OMX_U32 iWidth,
+ OMX_U32 iHeight
+)
+{
+ OMX_U32 x, y;
+
+ for (y = 0; y < iHeight; y++)
+ {
+ for (x = 0; x < iWidth; x++)
+ {
+ pDst [y * iDstStep + x] = pSrc [y * iSrcStep + x];
+ }
+ }
+
+ return OMX_Sts_NoErr;
+}
+
+/**
+ * Function: armVCM4P10_Interpolate_Luma
+ *
+ * Description:
+ * This function performs interpolation for luma components.
+ *
+ * Remarks:
+ *
+ * [in] pSrc Pointer to top-left corner of block used to
+ * interpolate in the reconstructed frame plane
+ * [in] iSrcStep Step of the source buffer.
+ * [in] iDstStep Step of the destination(interpolation) buffer.
+ * [in] iWidth Width of the current block
+ * [in] iHeight Height of the current block
+ * [in] dx Fractional part of horizontal motion vector
+ * component in 1/4 pixel unit (0~3)
+ * [in] dy Fractional part of vertical motion vector
+ * component in 1/4 pixel unit (0~3)
+ * [out] pDst Pointer to the interpolation buffer
+ *
+ * Return Value:
+ * Standard OMXResult value.
+ *
+ */
+
+ OMXResult armVCM4P10_Interpolate_Luma(
+ const OMX_U8 *pSrc,
+ OMX_U32 iSrcStep,
+ OMX_U8 *pDst,
+ OMX_U32 iDstStep,
+ OMX_U32 iWidth,
+ OMX_U32 iHeight,
+ OMX_U32 dx,
+ OMX_U32 dy
+)
+{
+ OMX_U8 pBuf1 [16*16];
+ const OMX_U8 *pSrcHalfHor = pSrc;
+ const OMX_U8 *pSrcHalfVer = pSrc;
+
+ /* check for argument error */
+ armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(dx > 3, OMX_Sts_BadArgErr)
+ armRetArgErrIf(dy > 3, OMX_Sts_BadArgErr)
+
+ /* Work out positions for half pixel interpolation */
+ if (dx == 3)
+ {
+ pSrcHalfVer += 1;
+ }
+ if (dy == 3)
+ {
+ pSrcHalfHor += iSrcStep;
+ }
+
+ /* Switch on type of pixel
+ * Pixels are named 'a' to 's' as in the H.264 standard
+ */
+ if (dx == 0 && dy == 0)
+ {
+ /* G */
+ armM4P10_Copy(pSrc, iSrcStep, pDst, iDstStep, iWidth, iHeight);
+ }
+ else if (dy == 0)
+ {
+ /* a, b, c */
+ armVCM4P10_InterpolateHalfHor_Luma
+ (pSrcHalfHor, iSrcStep, pDst, iDstStep, iWidth, iHeight);
+
+ if (dx == 1 || dx == 3)
+ {
+ armVCCOMM_Average
+ (pDst, pSrcHalfVer, iDstStep, iSrcStep, pDst, iDstStep, iWidth, iHeight);
+ }
+ }
+ else if (dx == 0)
+ {
+ /* d, h, n */
+ armVCM4P10_InterpolateHalfVer_Luma
+ (pSrcHalfVer, iSrcStep, pDst, iDstStep, iWidth, iHeight);
+
+ if (dy == 1 || dy == 3)
+ {
+ armVCCOMM_Average
+ (pDst, pSrcHalfHor, iDstStep, iSrcStep, pDst, iDstStep, iWidth, iHeight);
+ }
+ }
+ else if (dx == 2 || dy == 2)
+ {
+ /* j */
+ armVCM4P10_InterpolateHalfDiag_Luma
+ (pSrc, iSrcStep, pDst, iDstStep, iWidth, iHeight);
+
+ if (dx == 1 || dx == 3)
+ {
+ /* i, k */
+ armVCM4P10_InterpolateHalfVer_Luma
+ (pSrcHalfVer, iSrcStep, pBuf1, iWidth, iWidth, iHeight);
+
+ armVCCOMM_Average
+ (pDst, pBuf1, iDstStep, iWidth, pDst, iDstStep, iWidth, iHeight);
+ }
+ if (dy == 1 || dy == 3)
+ {
+ /* f,q */
+ armVCM4P10_InterpolateHalfHor_Luma
+ (pSrcHalfHor, iSrcStep, pBuf1, iWidth, iWidth, iHeight);
+
+ armVCCOMM_Average
+ (pDst, pBuf1, iDstStep, iWidth, pDst, iDstStep, iWidth, iHeight);
+ }
+ }
+ else /* dx=1,3 and dy=1,3 */
+ {
+ /* e, g, p, r */
+ armVCM4P10_InterpolateHalfHor_Luma
+ (pSrcHalfHor, iSrcStep, pBuf1, iWidth, iWidth, iHeight);
+
+ armVCM4P10_InterpolateHalfVer_Luma
+ (pSrcHalfVer, iSrcStep, pDst, iDstStep, iWidth, iHeight);
+
+ armVCCOMM_Average
+ (pBuf1, pDst, iWidth, iDstStep, pDst, iDstStep, iWidth, iHeight);
+ }
+
+ return OMX_Sts_NoErr;
+}
+
+/*****************************************************************************
+ * END OF FILE
+ *****************************************************************************/
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_PredictIntraDC4x4.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_PredictIntraDC4x4.c
new file mode 100644
index 0000000..b713073
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_PredictIntraDC4x4.c
@@ -0,0 +1,88 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: armVCM4P10_PredictIntraDC4x4.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * H.264 4x4 intra prediction module
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/*
+ * Description:
+ * Perform DC style intra prediction, averaging upper and left block
+ *
+ * Parameters:
+ * [in] pSrcLeft Pointer to the buffer of 16 left coefficients:
+ * p[x, y] (x = -1, y = 0..3)
+ * [in] pSrcAbove Pointer to the buffer of 16 above coefficients:
+ * p[x,y] (x = 0..3, y = -1)
+ * [in] leftStep Step of left coefficient buffer
+ * [in] dstStep Step of the destination buffer
+ * [in] availability Neighboring 16x16 MB availability flag
+ * [out] pDst Pointer to the destination buffer
+ *
+ * Return Value:
+ * None
+ */
+
+void armVCM4P10_PredictIntraDC4x4(
+ const OMX_U8* pSrcLeft,
+ const OMX_U8 *pSrcAbove,
+ OMX_U8* pDst,
+ OMX_INT leftStep,
+ OMX_INT dstStep,
+ OMX_S32 availability
+)
+{
+ int x, y, Sum=0, Count = 0;
+
+ if (availability & OMX_VC_LEFT)
+ {
+ for (y=0; y<4; y++)
+ {
+ Sum += pSrcLeft[y*leftStep];
+ }
+ Count++;
+ }
+ if (availability & OMX_VC_UPPER)
+ {
+ for (x=0; x<4; x++)
+ {
+ Sum += pSrcAbove[x];
+ }
+ Count++;
+ }
+ if (Count==0)
+ {
+ Sum = 128;
+ }
+ else if (Count==1)
+ {
+ Sum = (Sum + 2) >> 2;
+ }
+ else /* Count = 2 */
+ {
+ Sum = (Sum + 4) >> 3;
+ }
+ for (y=0; y<4; y++)
+ {
+ for (x=0; x<4; x++)
+ {
+ pDst[y*dstStep+x] = (OMX_U8)Sum;
+ }
+ }
+}
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_QuantTables.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_QuantTables.c
new file mode 100644
index 0000000..f0b5bb0
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_QuantTables.c
@@ -0,0 +1,31 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: armVCM4P10_QuantTables.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * H.264 inverse quantize tables
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armVC.h"
+
+const OMX_U32 armVCM4P10_MFMatrix[6][3] =
+{
+ {13107, 5243, 8066},
+ {11916, 4660, 7490},
+ {10082, 4194, 6554},
+ { 9362, 3647, 5825},
+ { 8192, 3355, 5243},
+ { 7282, 2893, 4559}
+};
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_SADQuar.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_SADQuar.c
new file mode 100644
index 0000000..a41e04b
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_SADQuar.c
@@ -0,0 +1,84 @@
+/**
+ *
+ * File Name: armVCM4P10_SADQuar.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ * Description:
+ * This function will calculate SAD of pSrc with average of two Ref blocks
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+
+#include "armVC.h"
+#include "armCOMM.h"
+
+/**
+ * Function: armVCM4P10_SADQuar
+ *
+ * Description:
+ * This function calculates the SAD between one block (pSrc) and the
+ * average of the other two (pSrcRef0 and pSrcRef1)
+ *
+ * Remarks:
+ *
+ * [in] pSrc Pointer to the original block
+ * [in] pSrcRef0 Pointer to reference block 0
+ * [in] pSrcRef1 Pointer to reference block 1
+ * [in] iSrcStep Step of the original block buffer
+ * [in] iRefStep0 Step of reference block 0
+ * [in] iRefStep1 Step of reference block 1
+ * [in] iHeight Height of the block
+ * [in] iWidth Width of the block
+ * [out] pDstSAD Pointer of result SAD
+ *
+ * Return Value:
+ * Standard OMXResult value.
+ *
+ */
+OMXResult armVCM4P10_SADQuar(
+ const OMX_U8* pSrc,
+ const OMX_U8* pSrcRef0,
+ const OMX_U8* pSrcRef1,
+ OMX_U32 iSrcStep,
+ OMX_U32 iRefStep0,
+ OMX_U32 iRefStep1,
+ OMX_U32* pDstSAD,
+ OMX_U32 iHeight,
+ OMX_U32 iWidth
+)
+{
+ OMX_INT x, y;
+ OMX_S32 SAD = 0;
+
+ /* check for argument error */
+ armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pSrcRef0 == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pSrcRef1 == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pDstSAD == NULL, OMX_Sts_BadArgErr)
+
+ for (y = 0; y < iHeight; y++)
+ {
+ for (x = 0; x < iWidth; x++)
+ {
+ SAD += armAbs(pSrc [y * iSrcStep + x] - ((
+ pSrcRef0 [y * iRefStep0 + x] +
+ pSrcRef1 [y * iRefStep1 + x] + 1) >> 1));
+ }
+ }
+
+ *pDstSAD = SAD;
+
+ return OMX_Sts_NoErr;
+}
+
+/*****************************************************************************
+ * END OF FILE
+ *****************************************************************************/
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_TransformResidual4x4.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_TransformResidual4x4.c
new file mode 100644
index 0000000..f9f756a
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_TransformResidual4x4.c
@@ -0,0 +1,80 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: armVCM4P10_TransformResidual4x4.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * H.264 transform module
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/*
+ * Description:
+ * Transform Residual 4x4 Coefficients
+ *
+ * Parameters:
+ * [in] pSrc Source 4x4 block
+ * [out] pDst Destination 4x4 block
+ *
+ */
+
+void armVCM4P10_TransformResidual4x4(OMX_S16* pDst, OMX_S16 *pSrc)
+{
+ int i;
+
+ /* Transform rows */
+ for (i=0; i<16; i+=4)
+ {
+ int d0 = pSrc[i+0];
+ int d1 = pSrc[i+1];
+ int d2 = pSrc[i+2];
+ int d3 = pSrc[i+3];
+ int e0 = d0 + d2;
+ int e1 = d0 - d2;
+ int e2 = (d1>>1) - d3;
+ int e3 = d1 + (d3>>1);
+ int f0 = e0 + e3;
+ int f1 = e1 + e2;
+ int f2 = e1 - e2;
+ int f3 = e0 - e3;
+ pDst[i+0] = (OMX_S16)f0;
+ pDst[i+1] = (OMX_S16)f1;
+ pDst[i+2] = (OMX_S16)f2;
+ pDst[i+3] = (OMX_S16)f3;
+ }
+
+ /* Transform columns */
+ for (i=0; i<4; i++)
+ {
+ int f0 = pDst[i+0];
+ int f1 = pDst[i+4];
+ int f2 = pDst[i+8];
+ int f3 = pDst[i+12];
+ int g0 = f0 + f2;
+ int g1 = f0 - f2;
+ int g2 = (f1>>1) - f3;
+ int g3 = f1 + (f3>>1);
+ int h0 = g0 + g3;
+ int h1 = g1 + g2;
+ int h2 = g1 - g2;
+ int h3 = g0 - g3;
+ pDst[i+0] = (OMX_S16)((h0+32)>>6);
+ pDst[i+4] = (OMX_S16)((h1+32)>>6);
+ pDst[i+8] = (OMX_S16)((h2+32)>>6);
+ pDst[i+12] = (OMX_S16)((h3+32)>>6);
+ }
+}
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_UnpackBlock2x2.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_UnpackBlock2x2.c
new file mode 100644
index 0000000..dda49f6
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_UnpackBlock2x2.c
@@ -0,0 +1,78 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: armVCM4P10_UnpackBlock2x2.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * H.264 inverse quantize and transform helper module
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armVC.h"
+
+/*
+ * Description
+ * Unpack a 2x2 block of coefficient-residual pair values
+ *
+ * Parameters:
+ * [in] ppSrc Double pointer to residual coefficient-position pair
+ * buffer output by CALVC decoding
+ * [out] ppSrc *ppSrc is updated to the start of next non empty block
+ * [out] pDst Pointer to unpacked 4x4 block
+ */
+
+void armVCM4P10_UnpackBlock2x2(
+ const OMX_U8 **ppSrc,
+ OMX_S16* pDst
+)
+{
+ const OMX_U8 *pSrc = *ppSrc;
+ int i;
+ int Flag, Value;
+
+ for (i=0; i<4; i++)
+ {
+ pDst[i] = 0;
+ }
+
+ do
+ {
+ Flag = *pSrc++;
+ if (Flag & 0x10)
+ {
+ /* 16 bit */
+ Value = *pSrc++;
+ Value = Value | ((*pSrc++)<<8);
+ if (Value & 0x8000)
+ {
+ Value -= 0x10000;
+ }
+ }
+ else
+ {
+ /* 8 bit */
+ Value = *pSrc++;
+ if (Value & 0x80)
+ {
+ Value -= 0x100;
+ }
+ }
+ i = Flag & 15;
+ pDst[i] = (OMX_S16)Value;
+ }
+ while ((Flag & 0x20)==0);
+
+ *ppSrc = pSrc;
+}
+
+/* End of file */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_UnpackBlock4x4.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_UnpackBlock4x4.c
new file mode 100644
index 0000000..3c0dcbd
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_UnpackBlock4x4.c
@@ -0,0 +1,78 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: armVCM4P10_UnpackBlock4x4.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * H.264 inverse quantize and transform helper module
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armVC.h"
+
+/*
+ * Description
+ * Unpack a 4x4 block of coefficient-residual pair values
+ *
+ * Parameters:
+ * [in] ppSrc Double pointer to residual coefficient-position pair
+ * buffer output by CALVC decoding
+ * [out] ppSrc *ppSrc is updated to the start of next non empty block
+ * [out] pDst Pointer to unpacked 4x4 block
+ */
+
+void armVCM4P10_UnpackBlock4x4(
+ const OMX_U8 **ppSrc,
+ OMX_S16* pDst
+)
+{
+ const OMX_U8 *pSrc = *ppSrc;
+ int i;
+ int Flag, Value;
+
+ for (i=0; i<16; i++)
+ {
+ pDst[i] = 0;
+ }
+
+ do
+ {
+ Flag = *pSrc++;
+ if (Flag & 0x10)
+ {
+ /* 16 bit */
+ Value = *pSrc++;
+ Value = Value | ((*pSrc++)<<8);
+ if (Value & 0x8000)
+ {
+ Value -= 0x10000;
+ }
+ }
+ else
+ {
+ /* 8 bit */
+ Value = *pSrc++;
+ if (Value & 0x80)
+ {
+ Value -= 0x100;
+ }
+ }
+ i = Flag & 15;
+ pDst[i] = (OMX_S16)Value;
+ }
+ while ((Flag & 0x20)==0);
+
+ *ppSrc = pSrc;
+}
+
+/* End of file */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_Average_4x.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_Average_4x.c
new file mode 100644
index 0000000..ac0d523
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_Average_4x.c
@@ -0,0 +1,84 @@
+/**
+ *
+ * File Name: omxVCM4P10_Average_4x.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ * Description:
+ * This function will calculate Average of two 4x4 or 4x8 blocks
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/**
+ * Function: omxVCM4P10_Average_4x (6.3.5.5.3)
+ *
+ * Description:
+ * This function calculates the average of two 4x4, 4x8 blocks. The result
+ * is rounded according to (a+b+1)/2.
+ *
+ * Input Arguments:
+ *
+ * pPred0 - Pointer to the top-left corner of reference block 0
+ * pPred1 - Pointer to the top-left corner of reference block 1
+ * iPredStep0 - Step of reference block 0; must be a multiple of 4.
+ * iPredStep1 - Step of reference block 1; must be a multiple of 4.
+ * iDstStep - Step of the destination buffer; must be a multiple of 4.
+ * iHeight - Height of the blocks; must be either 4 or 8.
+ *
+ * Output Arguments:
+ *
+ * pDstPred - Pointer to the destination buffer. 4-byte alignment required.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL:
+ * pPred0, pPred1, or pDstPred
+ * - pDstPred is not aligned on a 4-byte boundary
+ * - iPredStep0 <= 0 or iPredStep0 is not a multiple of 4
+ * - iPredStep1 <= 0 or iPredStep1 is not a multiple of 4
+ * - iDstStep <= 0 or iDstStep is not a multiple of 4
+ * - iHeight is not equal to either 4 or 8
+ *
+ */
+ OMXResult omxVCM4P10_Average_4x (
+ const OMX_U8* pPred0,
+ const OMX_U8* pPred1,
+ OMX_U32 iPredStep0,
+ OMX_U32 iPredStep1,
+ OMX_U8* pDstPred,
+ OMX_U32 iDstStep,
+ OMX_U32 iHeight
+)
+{
+ /* check for argument error */
+ armRetArgErrIf(pPred0 == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pPred1 == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pDstPred == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf((iHeight != 4) && (iHeight != 8), OMX_Sts_BadArgErr)
+ armRetArgErrIf((iPredStep0 == 0) || (iPredStep0 & 3), OMX_Sts_BadArgErr)
+ armRetArgErrIf((iPredStep1 == 0) || (iPredStep1 & 3), OMX_Sts_BadArgErr)
+ armRetArgErrIf((iDstStep == 0) || (iDstStep & 3), OMX_Sts_BadArgErr)
+ armRetArgErrIf(armNot4ByteAligned(pDstPred), OMX_Sts_BadArgErr)
+
+ return armVCCOMM_Average
+ (pPred0, pPred1, iPredStep0, iPredStep1, pDstPred, iDstStep, 4, iHeight);
+}
+
+/*****************************************************************************
+ * END OF FILE
+ *****************************************************************************/
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_BlockMatch_Half.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_BlockMatch_Half.c
new file mode 100644
index 0000000..c490e10
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_BlockMatch_Half.c
@@ -0,0 +1,191 @@
+/**
+ *
+ * File Name: omxVCM4P10_BlockMatch_Half.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains modules for half pel Block matching,
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armVC.h"
+#include "armCOMM.h"
+
+
+/**
+ * Function: omxVCM4P10_BlockMatch_Half (6.3.5.2.2)
+ *
+ * Description:
+ * Performs a half-pel block match using results from a prior integer search.
+ * Returns the best MV and associated cost. This function estimates the
+ * half-pixel motion vector by interpolating the integer resolution motion
+ * vector referenced by the input parameter pSrcDstBestMV, i.e., the initial
+ * integer MV is generated externally. The function
+ * omxVCM4P10_BlockMatch_Integer may be used for integer motion estimation.
+ *
+ * Input Arguments:
+ *
+ * pSrcOrgY - Pointer to the current position in original picture plane. If
+ * iBlockWidth==4, 4-byte alignment required. If iBlockWidth==8,
+ * 8-byte alignment required. If iBlockWidth==16, 16-byte alignment
+ * required.
+ * pSrcRefY - Pointer to the top-left corner of the co-located block in the
+ * reference picture If iBlockWidth==4, 4-byte alignment
+ * required. If iBlockWidth==8, 8-byte alignment required. If
+ * iBlockWidth==16, 16-byte alignment required.
+ * nSrcOrgStep - Stride of the original picture plane in terms of full
+ * pixels; must be a multiple of iBlockWidth.
+ * nSrcRefStep - Stride of the reference picture plane in terms of full
+ * pixels
+ * iBlockWidth - Width of the current block in terms of full pixels; must
+ * be equal to either 4, 8, or 16.
+ * iBlockHeight - Height of the current block in terms of full pixels; must
+ * be equal to either 4, 8, or 16.
+ * nLamda - Lamda factor, used to compute motion cost
+ * pMVPred - Predicted MV, represented in terms of 1/4-pel units; used to
+ * compute motion cost
+ * pSrcDstBestMV - The best MV resulting from a prior integer search,
+ * represented in terms of 1/4-pel units
+ *
+ * Output Arguments:
+ *
+ * pSrcDstBestMV - Best MV resulting from the half-pel search, expressed in
+ * terms of 1/4-pel units
+ * pBestCost - Motion cost associated with the best MV; computed as
+ * SAD+Lamda*BitsUsedByMV
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - any of the following pointers is NULL: pSrcOrgY, pSrcRefY,
+ * pSrcDstBestMV, pMVPred, pBestCost
+ * - iBlockWidth or iBlockHeight are equal to values other than 4, 8, or 16.
+ * - Any alignment restrictions are violated
+ *
+ */
+
+OMXResult omxVCM4P10_BlockMatch_Half(
+ const OMX_U8* pSrcOrgY,
+ OMX_S32 nSrcOrgStep,
+ const OMX_U8* pSrcRefY,
+ OMX_S32 nSrcRefStep,
+ OMX_U8 iBlockWidth,
+ OMX_U8 iBlockHeight,
+ OMX_U32 nLamda,
+ const OMXVCMotionVector* pMVPred,
+ OMXVCMotionVector* pSrcDstBestMV,
+ OMX_S32* pBestCost
+)
+{
+ /* Definitions and Initializations*/
+ OMX_INT candSAD;
+ OMX_INT fromX, toX, fromY, toY;
+ /* Offset to the reference at the begining of the bounding box */
+ const OMX_U8 *pTempSrcRefY, *pTempSrcOrgY;
+ OMX_S16 x, y;
+ OMXVCMotionVector diffMV, candMV, integerMV;
+ OMX_U8 interpolY[256];
+
+ /* Argument error checks */
+ armRetArgErrIf((iBlockWidth == 4) && (!armIs4ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr);
+ armRetArgErrIf((iBlockWidth == 8) && (!armIs8ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr);
+ armRetArgErrIf((iBlockWidth == 16) && (!armIs16ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr);
+ armRetArgErrIf((iBlockWidth == 4) && (!armIs4ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr);
+ armRetArgErrIf((iBlockWidth == 8) && (!armIs8ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr);
+ armRetArgErrIf((iBlockWidth == 16) && (!armIs16ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr);
+ armRetArgErrIf((nSrcOrgStep % iBlockWidth), OMX_Sts_BadArgErr);
+ armRetArgErrIf(pSrcOrgY == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pSrcRefY == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pMVPred == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pSrcDstBestMV == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pBestCost == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(((iBlockWidth!=4)&&(iBlockWidth!=8)&&(iBlockWidth!=16)) , OMX_Sts_BadArgErr);
+ armRetArgErrIf(((iBlockHeight!=4)&&(iBlockHeight!=8)&&(iBlockHeight!=16)) , OMX_Sts_BadArgErr);
+
+
+ /* Check for valid region */
+ fromX = 1;
+ toX = 1;
+ fromY = 1;
+ toY = 1;
+
+ /* Initialize to max value as a start point */
+ *pBestCost = 0x7fffffff;
+
+ integerMV.dx = pSrcDstBestMV->dx;
+ integerMV.dy = pSrcDstBestMV->dy;
+
+ /* Looping on y- axis */
+ for (y = -fromY; y <= toY; y++)
+ {
+ /* Looping on x- axis */
+ for (x = -fromX; x <= toX; x++)
+ {
+ /* Positioning the pointer */
+ pTempSrcRefY = pSrcRefY + (nSrcRefStep * (integerMV.dy/4)) + (integerMV.dx/4);
+ if (x < 0)
+ {
+ pTempSrcRefY = pTempSrcRefY + x;
+ }
+ if (y < 0)
+ {
+ pTempSrcRefY = pTempSrcRefY + (y * nSrcRefStep);
+ }
+ pTempSrcOrgY = pSrcOrgY;
+
+ /* Prepare cand MV */
+ candMV.dx = integerMV.dx + x * 2;
+ candMV.dy = integerMV.dy + y * 2;
+
+ /* Interpolate half pel for the current position*/
+ armVCM4P10_Interpolate_Luma(
+ pTempSrcRefY,
+ nSrcRefStep,
+ interpolY,
+ iBlockWidth,
+ iBlockWidth,
+ iBlockHeight,
+ armAbs(x) * 2,
+ armAbs(y) * 2);
+
+ /* Calculate the SAD */
+ armVCCOMM_SAD(
+ pTempSrcOrgY,
+ nSrcOrgStep,
+ interpolY,
+ iBlockWidth,
+ &candSAD,
+ iBlockHeight,
+ iBlockWidth);
+
+ diffMV.dx = candMV.dx - pMVPred->dx;
+ diffMV.dy = candMV.dy - pMVPred->dy;
+
+ /* Result calculations */
+ armVCM4P10_CompareMotionCostToMV (
+ candMV.dx,
+ candMV.dy,
+ diffMV,
+ candSAD,
+ pSrcDstBestMV,
+ nLamda,
+ pBestCost);
+
+ } /* End of x- axis */
+ } /* End of y-axis */
+
+ return OMX_Sts_NoErr;
+
+}
+
+/* End of file */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_BlockMatch_Integer.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_BlockMatch_Integer.c
new file mode 100644
index 0000000..f7764e1
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_BlockMatch_Integer.c
@@ -0,0 +1,196 @@
+/**
+ *
+ * File Name: omxVCM4P10_BlockMatch_Integer.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains modules for Block matching, a full search algorithm
+ * is implemented
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armVC.h"
+#include "armCOMM.h"
+
+/**
+ * Function: omxVCM4P10_BlockMatch_Integer (6.3.5.2.1)
+ *
+ * Description:
+ * Performs integer block match. Returns best MV and associated cost.
+ *
+ * Input Arguments:
+ *
+ * pSrcOrgY - Pointer to the top-left corner of the current block. If
+ * iBlockWidth==4, 4-byte alignment required. If iBlockWidth==8,
+ * 8-byte alignment required. If iBlockWidth==16, 16-byte alignment
+ * required.
+ * pSrcRefY - Pointer to the top-left corner of the co-located block in the
+ * reference picture. If iBlockWidth==4, 4-byte alignment
+ * required. If iBlockWidth==8, 8-byte alignment required. If
+ * iBlockWidth==16, 16-byte alignment required.
+ * nSrcOrgStep - Stride of the original picture plane, expressed in terms
+ * of integer pixels; must be a multiple of iBlockWidth.
+ * nSrcRefStep - Stride of the reference picture plane, expressed in terms
+ * of integer pixels
+ * pRefRect - pointer to the valid reference rectangle inside the reference
+ * picture plane
+ * nCurrPointPos - position of the current block in the current plane
+ * iBlockWidth - Width of the current block, expressed in terms of integer
+ * pixels; must be equal to either 4, 8, or 16.
+ * iBlockHeight - Height of the current block, expressed in terms of
+ * integer pixels; must be equal to either 4, 8, or 16.
+ * nLamda - Lamda factor; used to compute motion cost
+ * pMVPred - Predicted MV; used to compute motion cost, expressed in terms
+ * of 1/4-pel units
+ * pMVCandidate - Candidate MV; used to initialize the motion search,
+ * expressed in terms of integer pixels
+ * pMESpec - pointer to the ME specification structure
+ *
+ * Output Arguments:
+ *
+ * pDstBestMV - Best MV resulting from integer search, expressed in terms
+ * of 1/4-pel units
+ * pBestCost - Motion cost associated with the best MV; computed as
+ * SAD+Lamda*BitsUsedByMV
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - any of the following poitners are NULL:
+ * pSrcOrgY, pSrcRefY, pRefRect, pMVPred, pMVCandidate, or pMESpec.
+ * - Either iBlockWidth or iBlockHeight are values other than 4, 8, or 16.
+ * - Any alignment restrictions are violated
+ *
+ */
+
+ OMXResult omxVCM4P10_BlockMatch_Integer (
+ const OMX_U8 *pSrcOrgY,
+ OMX_S32 nSrcOrgStep,
+ const OMX_U8 *pSrcRefY,
+ OMX_S32 nSrcRefStep,
+ const OMXRect *pRefRect,
+ const OMXVCM4P2Coordinate *pCurrPointPos,
+ OMX_U8 iBlockWidth,
+ OMX_U8 iBlockHeight,
+ OMX_U32 nLamda,
+ const OMXVCMotionVector *pMVPred,
+ const OMXVCMotionVector *pMVCandidate,
+ OMXVCMotionVector *pBestMV,
+ OMX_S32 *pBestCost,
+ void *pMESpec
+)
+{
+ /* Definitions and Initializations*/
+ OMX_INT candSAD;
+ OMX_INT fromX, toX, fromY, toY;
+ /* Offset to the reference at the begining of the bounding box */
+ const OMX_U8 *pTempSrcRefY, *pTempSrcOrgY;
+ OMX_S16 x, y;
+ OMXVCMotionVector diffMV;
+ OMX_S32 nSearchRange;
+ ARMVCM4P10_MESpec *armMESpec = (ARMVCM4P10_MESpec *) pMESpec;
+
+ /* Argument error checks */
+ armRetArgErrIf((iBlockWidth == 4) && (!armIs4ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr);
+ armRetArgErrIf((iBlockWidth == 8) && (!armIs8ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr);
+ armRetArgErrIf((iBlockWidth == 16) && (!armIs16ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr);
+ armRetArgErrIf((iBlockWidth == 4) && (!armIs4ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr);
+ armRetArgErrIf((iBlockWidth == 8) && (!armIs8ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr);
+ armRetArgErrIf((iBlockWidth == 16) && (!armIs16ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr);
+ armRetArgErrIf(pSrcOrgY == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pSrcRefY == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pMVPred == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pMVCandidate == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pBestMV == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pBestCost == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(((iBlockWidth!=4)&&(iBlockWidth!=8)&&(iBlockWidth!=16)) , OMX_Sts_BadArgErr);
+ armRetArgErrIf(((iBlockHeight!=4)&&(iBlockHeight!=8)&&(iBlockHeight!=16)) , OMX_Sts_BadArgErr);
+ armIgnore (pMESpec);
+
+ if(iBlockWidth == 4)
+ {
+ nSearchRange = armMESpec->MEParams.searchRange4x4;
+ }
+ else if(iBlockWidth == 8)
+ {
+ nSearchRange = armMESpec->MEParams.searchRange8x8;
+ }
+ else
+ {
+ nSearchRange = armMESpec->MEParams.searchRange16x16;
+ }
+ /* Check for valid region */
+ fromX = nSearchRange;
+ toX = nSearchRange;
+ fromY = nSearchRange;
+ toY = nSearchRange;
+
+ if ((pCurrPointPos->x - nSearchRange) < pRefRect->x)
+ {
+ fromX = pCurrPointPos->x - pRefRect->x;
+ }
+
+ if ((pCurrPointPos->x + iBlockWidth + nSearchRange) > (pRefRect->x + pRefRect->width))
+ {
+ toX = pRefRect->width - (pCurrPointPos->x - pRefRect->x) - iBlockWidth;
+ }
+
+ if ((pCurrPointPos->y - nSearchRange) < pRefRect->y)
+ {
+ fromY = pCurrPointPos->y - pRefRect->y;
+ }
+
+ if ((pCurrPointPos->y + iBlockWidth + nSearchRange) > (pRefRect->y + pRefRect->height))
+ {
+ toY = pRefRect->width - (pCurrPointPos->y - pRefRect->y) - iBlockWidth;
+ }
+
+ pBestMV->dx = -fromX * 4;
+ pBestMV->dy = -fromY * 4;
+ /* Initialize to max value as a start point */
+ *pBestCost = 0x7fffffff;
+
+ /* Looping on y- axis */
+ for (y = -fromY; y <= toY; y++)
+ {
+ /* Looping on x- axis */
+ for (x = -fromX; x <= toX; x++)
+ {
+ /* Positioning the pointer */
+ pTempSrcRefY = pSrcRefY + (nSrcRefStep * y) + x;
+ pTempSrcOrgY = pSrcOrgY;
+
+ /* Calculate the SAD */
+ armVCCOMM_SAD(
+ pTempSrcOrgY,
+ nSrcOrgStep,
+ pTempSrcRefY,
+ nSrcRefStep,
+ &candSAD,
+ iBlockHeight,
+ iBlockWidth);
+
+ diffMV.dx = (x * 4) - pMVPred->dx;
+ diffMV.dy = (y * 4) - pMVPred->dy;
+
+ /* Result calculations */
+ armVCM4P10_CompareMotionCostToMV ((x * 4), (y * 4), diffMV, candSAD, pBestMV, nLamda, pBestCost);
+
+ } /* End of x- axis */
+ } /* End of y-axis */
+
+ return OMX_Sts_NoErr;
+
+}
+
+/* End of file */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_BlockMatch_Quarter.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_BlockMatch_Quarter.c
new file mode 100644
index 0000000..513ee25
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_BlockMatch_Quarter.c
@@ -0,0 +1,199 @@
+/**
+ *
+ * File Name: omxVCM4P10_BlockMatch_Quarter.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains modules for quater pel Block matching,
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armVC.h"
+#include "armCOMM.h"
+
+
+/**
+ * Function: omxVCM4P10_BlockMatch_Quarter (6.3.5.2.3)
+ *
+ * Description:
+ * Performs a quarter-pel block match using results from a prior half-pel
+ * search. Returns the best MV and associated cost. This function estimates
+ * the quarter-pixel motion vector by interpolating the half-pel resolution
+ * motion vector referenced by the input parameter pSrcDstBestMV, i.e., the
+ * initial half-pel MV is generated externally. The function
+ * omxVCM4P10_BlockMatch_Half may be used for half-pel motion estimation.
+ *
+ * Input Arguments:
+ *
+ * pSrcOrgY - Pointer to the current position in original picture plane. If
+ * iBlockWidth==4, 4-byte alignment required. If iBlockWidth==8,
+ * 8-byte alignment required. If iBlockWidth==16, 16-byte alignment
+ * required.
+ * pSrcRefY - Pointer to the top-left corner of the co-located block in the
+ * reference picture If iBlockWidth==4, 4-byte alignment
+ * required. If iBlockWidth==8, 8-byte alignment required. If
+ * iBlockWidth==16, 16-byte alignment required.
+ * nSrcOrgStep - Stride of the original picture plane in terms of full
+ * pixels; must be a multiple of iBlockWidth.
+ * nSrcRefStep - Stride of the reference picture plane in terms of full
+ * pixels
+ * iBlockWidth - Width of the current block in terms of full pixels; must
+ * be equal to either 4, 8, or 16.
+ * iBlockHeight - Height of the current block in terms of full pixels; must
+ * be equal to either 4, 8, or 16.
+ * nLamda - Lamda factor, used to compute motion cost
+ * pMVPred - Predicted MV, represented in terms of 1/4-pel units; used to
+ * compute motion cost
+ * pSrcDstBestMV - The best MV resulting from a prior half-pel search,
+ * represented in terms of 1/4 pel units
+ *
+ * Output Arguments:
+ *
+ * pSrcDstBestMV - Best MV resulting from the quarter-pel search, expressed
+ * in terms of 1/4-pel units
+ * pBestCost - Motion cost associated with the best MV; computed as
+ * SAD+Lamda*BitsUsedByMV
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - One of more of the following pointers is NULL:
+ * pSrcOrgY, pSrcRefY, pSrcDstBestMV, pMVPred, pBestCost
+ * - iBlockWidth or iBlockHeight are equal to values other than 4, 8, or 16.
+ * - Any alignment restrictions are violated
+ *
+ */
+
+OMXResult omxVCM4P10_BlockMatch_Quarter(
+ const OMX_U8* pSrcOrgY,
+ OMX_S32 nSrcOrgStep,
+ const OMX_U8* pSrcRefY,
+ OMX_S32 nSrcRefStep,
+ OMX_U8 iBlockWidth,
+ OMX_U8 iBlockHeight,
+ OMX_U32 nLamda,
+ const OMXVCMotionVector* pMVPred,
+ OMXVCMotionVector* pSrcDstBestMV,
+ OMX_S32* pBestCost
+)
+{
+ /* Definitions and Initializations*/
+ OMX_INT candSAD;
+ OMX_INT fromX, toX, fromY, toY;
+ /* Offset to the reference at the begining of the bounding box */
+ const OMX_U8 *pTempSrcRefY, *pTempSrcOrgY;
+ OMX_S16 x, y;
+ OMXVCMotionVector diffMV, candMV, initialMV;
+ OMX_U8 interpolY[256];
+ OMX_S32 pelPosX, pelPosY;
+
+ /* Argument error checks */
+ armRetArgErrIf((iBlockWidth == 4) && (!armIs4ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr);
+ armRetArgErrIf((iBlockWidth == 8) && (!armIs8ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr);
+ armRetArgErrIf((iBlockWidth == 16) && (!armIs16ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr);
+ armRetArgErrIf((iBlockWidth == 4) && (!armIs4ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr);
+ armRetArgErrIf((iBlockWidth == 8) && (!armIs8ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr);
+ armRetArgErrIf((iBlockWidth == 16) && (!armIs16ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr);
+ armRetArgErrIf((nSrcOrgStep % iBlockWidth), OMX_Sts_BadArgErr);
+ armRetArgErrIf(pSrcOrgY == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pSrcRefY == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pMVPred == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pSrcDstBestMV == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pBestCost == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(((iBlockWidth!=4)&&(iBlockWidth!=8)&&(iBlockWidth!=16)) , OMX_Sts_BadArgErr);
+ armRetArgErrIf(((iBlockHeight!=4)&&(iBlockHeight!=8)&&(iBlockHeight!=16)) , OMX_Sts_BadArgErr);
+
+
+ /* Check for valid region */
+ fromX = 1;
+ toX = 1;
+ fromY = 1;
+ toY = 1;
+
+ /* Initialize to max value as a start point */
+ *pBestCost = 0x7fffffff;
+
+ initialMV.dx = pSrcDstBestMV->dx;
+ initialMV.dy = pSrcDstBestMV->dy;
+
+ /* Looping on y- axis */
+ for (y = -fromY; y <= toY; y++)
+ {
+ /* Looping on x- axis */
+ for (x = -fromX; x <= toX; x++)
+ {
+ /* Positioning the pointer */
+ pTempSrcRefY = pSrcRefY + (nSrcRefStep * (initialMV.dy/4)) + (initialMV.dx/4);
+
+ /* Calculating the fract pel position */
+ pelPosX = (initialMV.dx % 4) + x;
+ if (pelPosX < 0)
+ {
+ pTempSrcRefY = pTempSrcRefY - 1;
+ pelPosX += 4;
+ }
+ pelPosY = (initialMV.dy % 4) + y;
+ if (pelPosY < 0)
+ {
+ pTempSrcRefY = pTempSrcRefY - (1 * nSrcRefStep);
+ pelPosY += 4;
+ }
+
+ pTempSrcOrgY = pSrcOrgY;
+
+ /* Prepare cand MV */
+ candMV.dx = initialMV.dx + x;
+ candMV.dy = initialMV.dy + y;
+
+ /* Interpolate Quater pel for the current position*/
+ armVCM4P10_Interpolate_Luma(
+ pTempSrcRefY,
+ nSrcRefStep,
+ interpolY,
+ iBlockWidth,
+ iBlockWidth,
+ iBlockHeight,
+ pelPosX,
+ pelPosY);
+
+ /* Calculate the SAD */
+ armVCCOMM_SAD(
+ pTempSrcOrgY,
+ nSrcOrgStep,
+ interpolY,
+ iBlockWidth,
+ &candSAD,
+ iBlockHeight,
+ iBlockWidth);
+
+ diffMV.dx = candMV.dx - pMVPred->dx;
+ diffMV.dy = candMV.dy - pMVPred->dy;
+
+ /* Result calculations */
+ armVCM4P10_CompareMotionCostToMV (
+ candMV.dx,
+ candMV.dy,
+ diffMV,
+ candSAD,
+ pSrcDstBestMV,
+ nLamda,
+ pBestCost);
+
+ } /* End of x- axis */
+ } /* End of y-axis */
+
+ return OMX_Sts_NoErr;
+
+}
+
+/* End of file */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DeblockChroma_I.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DeblockChroma_I.c
new file mode 100644
index 0000000..a07b1bb
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DeblockChroma_I.c
@@ -0,0 +1,107 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: omxVCM4P10_DeblockChroma_I.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * H.264 intra chroma deblock
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/**
+ * Function: omxVCM4P10_DeblockChroma_I (6.3.3.3.6)
+ *
+ * Description:
+ * Performs in-place deblocking filtering on all edges of the chroma
+ * macroblock (16x16).
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - pointer to the input macroblock; must be 8-byte aligned.
+ * srcdstStep - step of the arrays; must be a multiple of 8.
+ * pAlpha - pointer to a 2x2 array of alpha thresholds, organized as
+ * follows: {external vertical edge, internal vertical edge,
+ * external horizontal edge, internal horizontal edge }. Per
+ * [ISO14496-10] alpha values must be in the range [0,255].
+ * pBeta - pointer to a 2x2 array of Beta Thresholds, organized as follows:
+ * { external vertical edge, internal vertical edge, external
+ * horizontal edge, internal horizontal edge }. Per [ISO14496-10]
+ * beta values must be in the range [0,18].
+ * pThresholds - array of size 8x2 of Thresholds (TC0) (values for the left
+ * or above edge of each 4x2 or 2x4 block, arranged in vertical
+ * block order and then in horizontal block order); must be aligned
+ * on a 4-byte boundary. Per [ISO14496-10] values must be in the
+ * range [0,25].
+ * pBS - array of size 16x2 of BS parameters (arranged in scan block order
+ * for vertical edges and then horizontal edges); valid in the
+ * range [0,4] with the following restrictions: i) pBS[i]== 4 may
+ * occur only for 0<=i<=3, ii) pBS[i]== 4 if and only if pBS[i^3]==
+ * 4. Must be 4-byte aligned.
+ *
+ * Output Arguments:
+ *
+ * pSrcDst - pointer to filtered output macroblock.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments
+ * - one or more of the following pointers is NULL: pSrcDst, pAlpha,
+ * pBeta, pThresholds, or pBS. pSrcDst is not 8-byte aligned.
+ * either pThresholds or pBS is not 4-byte aligned.
+ * - one or more entries in the table pAlpha[0..3] is outside the range
+ * [0,255].
+ * - one or more entries in the table pBeta[0..3] is outside the range
+ * [0,18].
+ * - one or more entries in the table pThresholds[0..15]is outside of
+ * the range [0,25].
+ * - pBS is out of range, i.e., one of the following conditions is true:
+ * pBS[i]<0, pBS[i]>4, pBS[i]==4 for i>=4, or
+ * (pBS[i]==4 && pBS[i^3]!=4) for 0<=i<=3.
+ * - srcdstStep is not a multiple of 8.
+ *
+ */
+OMXResult omxVCM4P10_DeblockChroma_I(
+ OMX_U8* pSrcDst,
+ OMX_S32 srcdstStep,
+ const OMX_U8* pAlpha,
+ const OMX_U8* pBeta,
+ const OMX_U8* pThresholds,
+ const OMX_U8 *pBS
+)
+{
+ OMXResult errorCode;
+
+ armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot8ByteAligned(pSrcDst), OMX_Sts_BadArgErr);
+ armRetArgErrIf(srcdstStep & 7, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pAlpha == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pBeta == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pThresholds == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot4ByteAligned(pThresholds), OMX_Sts_BadArgErr);
+ armRetArgErrIf(pBS == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot4ByteAligned(pBS), OMX_Sts_BadArgErr);
+
+ errorCode = omxVCM4P10_FilterDeblockingChroma_VerEdge_I(
+ pSrcDst, srcdstStep, pAlpha, pBeta, pThresholds, pBS);
+
+ armRetArgErrIf(errorCode != OMX_Sts_NoErr, errorCode)
+
+ errorCode = omxVCM4P10_FilterDeblockingChroma_HorEdge_I(
+ pSrcDst, srcdstStep, pAlpha+2, pBeta+2, pThresholds+8, pBS+16);
+
+ return errorCode;
+}
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DeblockLuma_I.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DeblockLuma_I.c
new file mode 100644
index 0000000..1f3a646
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DeblockLuma_I.c
@@ -0,0 +1,109 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: omxVCM4P10_DeblockLuma_I.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * H.264 luma deblock
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+
+/**
+ * Function: omxVCM4P10_DeblockLuma_I (6.3.3.3.5)
+ *
+ * Description:
+ * This function performs in-place deblock filtering the horizontal and
+ * vertical edges of a luma macroblock (16x16).
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - pointer to the input macroblock; must be 16-byte aligned.
+ * srcdstStep - image width; must be a multiple of 16.
+ * pAlpha - pointer to a 2x2 table of alpha thresholds, organized as
+ * follows: {external vertical edge, internal vertical edge,
+ * external horizontal edge, internal horizontal edge }. Per
+ * [ISO14496-10] alpha values must be in the range [0,255].
+ * pBeta - pointer to a 2x2 table of beta thresholds, organized as follows:
+ * {external vertical edge, internal vertical edge, external
+ * horizontal edge, internal horizontal edge }. Per [ISO14496-10]
+ * beta values must be in the range [0,18].
+ * pThresholds - pointer to a 16x2 table of threshold (TC0), organized as
+ * follows: {values for the left or above edge of each 4x4 block,
+ * arranged in vertical block order and then in horizontal block
+ * order}; must be aligned on a 4-byte boundary. Per [ISO14496-10]
+ * values must be in the range [0,25].
+ * pBS - pointer to a 16x2 table of BS parameters arranged in scan block
+ * order for vertical edges and then horizontal edges; valid in the
+ * range [0,4] with the following restrictions: i) pBS[i]== 4 may
+ * occur only for 0<=i<=3, ii) pBS[i]== 4 if and only if pBS[i^3]==
+ * 4. Must be 4-byte aligned.
+ *
+ * Output Arguments:
+ *
+ * pSrcDst - pointer to filtered output macroblock.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments
+ * - one or more of the following pointers is NULL: pSrcDst, pAlpha,
+ * pBeta, pThresholds or pBS. pSrcDst is not 16-byte aligned.
+ * either pThresholds or pBS is not aligned on a 4-byte boundary.
+ * - one or more entries in the table pAlpha[0..3] is outside the range
+ * [0,255].
+ * - one or more entries in the table pBeta[0..3] is outside the range
+ * [0,18].
+ * - one or more entries in the table pThresholds[0..31]is outside of
+ * the range [0,25].
+ * - pBS is out of range, i.e., one of the following conditions is true:
+ * pBS[i]<0, pBS[i]>4, pBS[i]==4 for i>=4, or
+ * (pBS[i]==4 && pBS[i^3]!=4) for 0<=i<=3.
+ * - srcdstStep is not a multiple of 16.
+ *
+ */
+
+OMXResult omxVCM4P10_DeblockLuma_I(
+ OMX_U8* pSrcDst,
+ OMX_S32 srcdstStep,
+ const OMX_U8* pAlpha,
+ const OMX_U8* pBeta,
+ const OMX_U8* pThresholds,
+ const OMX_U8 *pBS
+)
+{
+ OMXResult errorCode;
+
+ armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot16ByteAligned(pSrcDst), OMX_Sts_BadArgErr);
+ armRetArgErrIf(srcdstStep & 15, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pAlpha == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pBeta == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pThresholds == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot4ByteAligned(pThresholds), OMX_Sts_BadArgErr);
+ armRetArgErrIf(pBS == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot4ByteAligned(pBS), OMX_Sts_BadArgErr);
+
+ errorCode = omxVCM4P10_FilterDeblockingLuma_VerEdge_I(
+ pSrcDst, srcdstStep, pAlpha, pBeta, pThresholds, pBS);
+
+ armRetArgErrIf(errorCode != OMX_Sts_NoErr, errorCode)
+
+ errorCode = omxVCM4P10_FilterDeblockingLuma_HorEdge_I(
+ pSrcDst, srcdstStep, pAlpha+2, pBeta+2, pThresholds+16, pBS+16);
+
+ return errorCode;
+}
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c
new file mode 100644
index 0000000..830ddc7
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c
@@ -0,0 +1,86 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * H.264 decode coefficients module
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/**
+ * Function: omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC (6.3.4.1.1)
+ *
+ * Description:
+ * Performs CAVLC decoding and inverse raster scan for a 2x2 block of
+ * ChromaDCLevel. The decoded coefficients in the packed position-coefficient
+ * buffer are stored in reverse zig-zag order, i.e., the first buffer element
+ * contains the last non-zero postion-coefficient pair of the block. Within
+ * each position-coefficient pair, the position entry indicates the
+ * raster-scan position of the coefficient, while the coefficient entry
+ * contains the coefficient value.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - Double pointer to current byte in bit stream buffer
+ * pOffset - Pointer to current bit position in the byte pointed to by
+ * *ppBitStream; valid in the range [0,7].
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after each block is decoded
+ * pOffset - *pOffset is updated after each block is decoded
+ * pNumCoeff - Pointer to the number of nonzero coefficients in this block
+ * ppPosCoefBuf - Double pointer to destination residual
+ * coefficient-position pair buffer. Buffer position
+ * (*ppPosCoefBuf) is updated upon return, unless there are only
+ * zero coefficients in the currently decoded block. In this case
+ * the caller is expected to bypass the transform/dequantization of
+ * the empty blocks.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr, if the function runs without error.
+ *
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - ppBitStream or pOffset is NULL.
+ * - ppPosCoefBuf or pNumCoeff is NULL.
+ * OMX_Sts_Err - if one of the following is true:
+ * - an illegal code is encountered in the bitstream
+ *
+ */
+
+OMXResult omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC (
+ const OMX_U8** ppBitStream,
+ OMX_S32* pOffset,
+ OMX_U8* pNumCoeff,
+ OMX_U8** ppPosCoefbuf
+ )
+
+{
+ armRetArgErrIf(ppBitStream==NULL , OMX_Sts_BadArgErr);
+ armRetArgErrIf(*ppBitStream==NULL , OMX_Sts_BadArgErr);
+ armRetArgErrIf(pOffset==NULL , OMX_Sts_BadArgErr);
+ armRetArgErrIf(*pOffset<0 , OMX_Sts_BadArgErr);
+ armRetArgErrIf(*pOffset>7 , OMX_Sts_BadArgErr);
+ armRetArgErrIf(pNumCoeff==NULL , OMX_Sts_BadArgErr);
+ armRetArgErrIf(ppPosCoefbuf==NULL , OMX_Sts_BadArgErr);
+ armRetArgErrIf(*ppPosCoefbuf==NULL , OMX_Sts_BadArgErr);
+
+ return armVCM4P10_DecodeCoeffsToPair(ppBitStream, pOffset, pNumCoeff,
+ ppPosCoefbuf, 4, 4);
+
+}
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DecodeCoeffsToPairCAVLC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DecodeCoeffsToPairCAVLC.c
new file mode 100644
index 0000000..7e83d1e
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DecodeCoeffsToPairCAVLC.c
@@ -0,0 +1,117 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: omxVCM4P10_DecodeCoeffsToPairCAVLC.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * H.264 decode coefficients module
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+#include "armCOMM.h"
+#include "armVC.h"
+
+/**
+ * Function: omxVCM4P10_DecodeCoeffsToPairCAVLC (6.3.4.1.2)
+ *
+ * Description:
+ * Performs CAVLC decoding and inverse zigzag scan for 4x4 block of
+ * Intra16x16DCLevel, Intra16x16ACLevel, LumaLevel, and ChromaACLevel. Inverse
+ * field scan is not supported. The decoded coefficients in the packed
+ * position-coefficient buffer are stored in reverse zig-zag order, i.e., the
+ * first buffer element contains the last non-zero postion-coefficient pair of
+ * the block. Within each position-coefficient pair, the position entry
+ * indicates the raster-scan position of the coefficient, while the
+ * coefficient entry contains the coefficient value.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream -Double pointer to current byte in bit stream buffer
+ * pOffset - Pointer to current bit position in the byte pointed to by
+ * *ppBitStream; valid in the range [0,7].
+ * sMaxNumCoeff - Maximum the number of non-zero coefficients in current
+ * block
+ * sVLCSelect - VLC table selector, obtained from the number of non-zero
+ * coefficients contained in the above and left 4x4 blocks. It is
+ * equivalent to the variable nC described in H.264 standard table
+ * 9 5, except its value can t be less than zero.
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after each block is decoded.
+ * Buffer position (*ppPosCoefBuf) is updated upon return, unless
+ * there are only zero coefficients in the currently decoded block.
+ * In this case the caller is expected to bypass the
+ * transform/dequantization of the empty blocks.
+ * pOffset - *pOffset is updated after each block is decoded
+ * pNumCoeff - Pointer to the number of nonzero coefficients in this block
+ * ppPosCoefBuf - Double pointer to destination residual
+ * coefficient-position pair buffer
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ *
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - ppBitStream or pOffset is NULL.
+ * - ppPosCoefBuf or pNumCoeff is NULL.
+ * - sMaxNumCoeff is not equal to either 15 or 16.
+ * - sVLCSelect is less than 0.
+ *
+ * OMX_Sts_Err - if one of the following is true:
+ * - an illegal code is encountered in the bitstream
+ *
+ */
+
+OMXResult omxVCM4P10_DecodeCoeffsToPairCAVLC(
+ const OMX_U8** ppBitStream,
+ OMX_S32* pOffset,
+ OMX_U8* pNumCoeff,
+ OMX_U8**ppPosCoefbuf,
+ OMX_INT sVLCSelect,
+ OMX_INT sMaxNumCoeff
+ )
+{
+ int nTable;
+
+ armRetArgErrIf(ppBitStream==NULL , OMX_Sts_BadArgErr);
+ armRetArgErrIf(*ppBitStream==NULL , OMX_Sts_BadArgErr);
+ armRetArgErrIf(pOffset==NULL , OMX_Sts_BadArgErr);
+ armRetArgErrIf(*pOffset<0 , OMX_Sts_BadArgErr);
+ armRetArgErrIf(*pOffset>7 , OMX_Sts_BadArgErr);
+ armRetArgErrIf(pNumCoeff==NULL , OMX_Sts_BadArgErr);
+ armRetArgErrIf(ppPosCoefbuf==NULL , OMX_Sts_BadArgErr);
+ armRetArgErrIf(*ppPosCoefbuf==NULL , OMX_Sts_BadArgErr);
+ armRetArgErrIf(sVLCSelect<0 , OMX_Sts_BadArgErr);
+ armRetArgErrIf(sMaxNumCoeff<15 , OMX_Sts_BadArgErr);
+ armRetArgErrIf(sMaxNumCoeff>16 , OMX_Sts_BadArgErr);
+
+ /* Find VLC table number */
+ if (sVLCSelect<2)
+ {
+ nTable = 0;
+ }
+ else if (sVLCSelect<4)
+ {
+ nTable = 1;
+ }
+ else if (sVLCSelect<8)
+ {
+ nTable = 2;
+ }
+ else /* sVLCSelect >= 8 */
+ {
+ nTable = 3;
+ }
+
+ return armVCM4P10_DecodeCoeffsToPair(ppBitStream, pOffset, pNumCoeff,
+ ppPosCoefbuf, nTable, sMaxNumCoeff);
+}
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DequantTransformResidualFromPairAndAdd.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DequantTransformResidualFromPairAndAdd.c
new file mode 100644
index 0000000..ed5a158
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DequantTransformResidualFromPairAndAdd.c
@@ -0,0 +1,145 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: omxVCM4P10_DequantTransformResidualFromPairAndAdd.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * H.264 inverse quantize and transform module
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/*
+ * Description:
+ * Dequantize Luma AC block
+ */
+
+static void DequantLumaAC4x4(
+ OMX_S16* pSrcDst,
+ OMX_INT QP
+)
+{
+ const OMX_U8 *pVRow = &armVCM4P10_VMatrix[QP%6][0];
+ int Shift = QP / 6;
+ int i;
+ OMX_S32 Value;
+
+ for (i=0; i<16; i++)
+ {
+
+ Value = (pSrcDst[i] * pVRow[armVCM4P10_PosToVCol4x4[i]]) << Shift;
+ pSrcDst[i] = (OMX_S16)Value;
+ }
+}
+
+/**
+ * Function: omxVCM4P10_DequantTransformResidualFromPairAndAdd (6.3.4.2.3)
+ *
+ * Description:
+ * Reconstruct the 4x4 residual block from coefficient-position pair buffer,
+ * perform dequantization and integer inverse transformation for 4x4 block of
+ * residuals with previous intra prediction or motion compensation data, and
+ * update the pair buffer pointer to next non-empty block. If pDC == NULL,
+ * there re 16 non-zero AC coefficients at most in the packed buffer starting
+ * from 4x4 block position 0; If pDC != NULL, there re 15 non-zero AC
+ * coefficients at most in the packet buffer starting from 4x4 block position
+ * 1.
+ *
+ * Input Arguments:
+ *
+ * ppSrc - Double pointer to residual coefficient-position pair buffer
+ * output by CALVC decoding
+ * pPred - Pointer to the predicted 4x4 block; must be aligned on a 4-byte
+ * boundary
+ * predStep - Predicted frame step size in bytes; must be a multiple of 4
+ * dstStep - Destination frame step in bytes; must be a multiple of 4
+ * pDC - Pointer to the DC coefficient of this block, NULL if it doesn't
+ * exist
+ * QP - QP Quantization parameter. It should be QpC in chroma 4x4 block
+ * decoding, otherwise it should be QpY.
+ * AC - Flag indicating if at least one non-zero AC coefficient exists
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the reconstructed 4x4 block data; must be aligned on a
+ * 4-byte boundary
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - pPred or pDst is NULL.
+ * - pPred or pDst is not 4-byte aligned.
+ * - predStep or dstStep is not a multiple of 4.
+ * - AC !=0 and Qp is not in the range of [0-51] or ppSrc == NULL.
+ * - AC ==0 && pDC ==NULL.
+ *
+ */
+
+OMXResult omxVCM4P10_DequantTransformResidualFromPairAndAdd(
+ const OMX_U8 **ppSrc,
+ const OMX_U8 *pPred,
+ const OMX_S16 *pDC,
+ OMX_U8 *pDst,
+ OMX_INT predStep,
+ OMX_INT dstStep,
+ OMX_INT QP,
+ OMX_INT AC
+)
+{
+ OMX_S16 pBuffer[16+4];
+ OMX_S16 *pDelta;
+ int i,x,y;
+
+ armRetArgErrIf(pPred == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot4ByteAligned(pPred),OMX_Sts_BadArgErr);
+ armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot4ByteAligned(pDst), OMX_Sts_BadArgErr);
+ armRetArgErrIf(predStep & 3, OMX_Sts_BadArgErr);
+ armRetArgErrIf(dstStep & 3, OMX_Sts_BadArgErr);
+ armRetArgErrIf(AC!=0 && (QP<0), OMX_Sts_BadArgErr);
+ armRetArgErrIf(AC!=0 && (QP>51), OMX_Sts_BadArgErr);
+ armRetArgErrIf(AC!=0 && ppSrc==NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(AC!=0 && *ppSrc==NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(AC==0 && pDC==NULL, OMX_Sts_BadArgErr);
+
+ pDelta = armAlignTo8Bytes(pBuffer);
+
+ for (i=0; i<16; i++)
+ {
+ pDelta[i] = 0;
+ }
+ if (AC)
+ {
+ armVCM4P10_UnpackBlock4x4(ppSrc, pDelta);
+ DequantLumaAC4x4(pDelta, QP);
+ }
+ if (pDC)
+ {
+ pDelta[0] = pDC[0];
+ }
+ armVCM4P10_TransformResidual4x4(pDelta,pDelta);
+
+ for (y=0; y<4; y++)
+ {
+ for (x=0; x<4; x++)
+ {
+ pDst[y*dstStep+x] = (OMX_U8)armClip(0,255,pPred[y*predStep+x] + pDelta[4*y+x]);
+ }
+ }
+
+ return OMX_Sts_NoErr;
+}
+
+/* End of file */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_HorEdge_I.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_HorEdge_I.c
new file mode 100644
index 0000000..75edee2
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_HorEdge_I.c
@@ -0,0 +1,130 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: omxVCM4P10_FilterDeblockingChroma_HorEdge_I.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * H.264 chroma deblock module
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/**
+ * Function: omxVCM4P10_FilterDeblockingChroma_HorEdge_I (6.3.3.3.4)
+ *
+ * Description:
+ * Performs in-place deblock filtering on the horizontal edges of the chroma
+ * macroblock (8x8).
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - pointer to the input macroblock; must be 8-byte aligned.
+ * srcdstStep - array step; must be a multiple of 8.
+ * pAlpha - array of size 2 containing alpha thresholds; the first element
+ * contains the threshold for the external horizontal edge, and the
+ * second element contains the threshold for internal horizontal
+ * edge. Per [ISO14496-10] alpha values must be in the range
+ * [0,255].
+ * pBeta - array of size 2 containing beta thresholds; the first element
+ * contains the threshold for the external horizontal edge, and the
+ * second element contains the threshold for the internal
+ * horizontal edge. Per [ISO14496-10] beta values must be in the
+ * range [0,18].
+ * pThresholds - array of size 8 containing thresholds, TC0, for the top
+ * horizontal edge of each 2x4 chroma block, arranged in horizontal
+ * block order; must be aligned on a 4-byte boundary. Per
+ * [ISO14496-10] values must be in the range [0,25].
+ * pBS - array of size 16 containing BS parameters for each 2x2 chroma
+ * block, arranged in horizontal block order; valid in the range
+ * [0,4] with the following restrictions: i) pBS[i]== 4 may occur
+ * only for 0<=i<=3, ii) pBS[i]== 4 if and only if pBS[i^3]== 4.
+ * Must be 4-byte aligned.
+ *
+ * Output Arguments:
+ *
+ * pSrcDst -Pointer to filtered output macroblock.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr, if the function runs without error.
+ *
+ * OMX_Sts_BadArgErr, if one of the following cases occurs:
+ * - any of the following pointers is NULL:
+ * pSrcDst, pAlpha, pBeta, pThresholds, or pBS.
+ * - pSrcDst is not 8-byte aligned.
+ * - srcdstStep is not a multiple of 8.
+ * - pThresholds is not 4-byte aligned.
+ * - pAlpha[0] and/or pAlpha[1] is outside the range [0,255].
+ * - pBeta[0] and/or pBeta[1] is outside the range [0,18].
+ * - One or more entries in the table pThresholds[0..7] is outside
+ * of the range [0,25].
+ * - pBS is out of range, i.e., one of the following conditions is true:
+ * pBS[i]<0, pBS[i]>4, pBS[i]==4 for i>=4, or
+ * (pBS[i]==4 && pBS[i^3]!=4) for 0<=i<=3.
+ * - pBS is not 4-byte aligned.
+ *
+ */
+
+OMXResult omxVCM4P10_FilterDeblockingChroma_HorEdge_I(
+ OMX_U8* pSrcDst,
+ OMX_S32 srcdstStep,
+ const OMX_U8* pAlpha,
+ const OMX_U8* pBeta,
+ const OMX_U8* pThresholds,
+ const OMX_U8 *pBS
+ )
+{
+ int I, X, Y, Internal=0;
+
+ armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot8ByteAligned(pSrcDst), OMX_Sts_BadArgErr);
+ armRetArgErrIf(srcdstStep & 7, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pAlpha == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pBeta == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pThresholds == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot4ByteAligned(pThresholds), OMX_Sts_BadArgErr);
+ armRetArgErrIf(pBS == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot4ByteAligned(pBS), OMX_Sts_BadArgErr);
+
+ for (Y=0; Y<8; Y+=4, Internal=1)
+ {
+ for (X=0; X<8; X++)
+ {
+ I = (X>>1)+4*(Y>>1);
+
+ armRetArgErrIf(pBS[I] > 4, OMX_Sts_BadArgErr)
+
+ armRetArgErrIf( (I > 3) && (pBS[I] == 4),
+ OMX_Sts_BadArgErr)
+
+ armRetArgErrIf( (I < 4) &&
+ ( (pBS[I] == 4) && (pBS[I^1] != 4) ),
+ OMX_Sts_BadArgErr)
+
+
+ /* Filter horizontal edge with q0 at (X,Y) */
+ armVCM4P10_DeBlockPixel(
+ pSrcDst + Y*srcdstStep + X,
+ srcdstStep,
+ pThresholds[(X>>1)+4*(Y>>2)],
+ pAlpha[Internal],
+ pBeta[Internal],
+ pBS[I],
+ 1);
+ }
+ }
+
+ return OMX_Sts_NoErr;
+}
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_VerEdge_I.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_VerEdge_I.c
new file mode 100644
index 0000000..10b2592
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_VerEdge_I.c
@@ -0,0 +1,131 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: omxVCM4P10_FilterDeblockingChroma_VerEdge_I.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * H.264 deblocking module
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/**
+ * Function: omxVCM4P10_FilterDeblockingChroma_VerEdge_I (6.3.3.3.3)
+ *
+ * Description:
+ * Performs in-place deblock filtering on four vertical edges of the chroma
+ * macroblock (8x8).
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - Pointer to the input macroblock; must be 8-byte aligned.
+ * srcdstStep - Step of the arrays; must be a multiple of 8.
+ * pAlpha - Array of size 2 of alpha thresholds (the first item is alpha
+ * threshold for external vertical edge, and the second item is for
+ * internal vertical edge); per [ISO14496-10] alpha values must be
+ * in the range [0,255].
+ * pBeta - Array of size 2 of beta thresholds (the first item is the beta
+ * threshold for the external vertical edge, and the second item is
+ * for the internal vertical edge); per [ISO14496-10] beta values
+ * must be in the range [0,18].
+ * pThresholds - Array of size 8 containing thresholds, TC0, for the left
+ * vertical edge of each 4x2 chroma block, arranged in vertical
+ * block order; must be aligned on a 4-byte boundary. Per
+ * [ISO14496-10] values must be in the range [0,25].
+ * pBS - Array of size 16 of BS parameters (values for each 2x2 chroma
+ * block, arranged in vertical block order). This parameter is the
+ * same as the pBSparameter passed into FilterDeblockLuma_VerEdge;
+ * valid in the range [0,4] with the following restrictions: i)
+ * pBS[i]== 4 may occur only for 0<=i<=3, ii) pBS[i]== 4 if and
+ * only if pBS[i^3]== 4. Must be 4 byte aligned.
+ *
+ * Output Arguments:
+ *
+ * pSrcDst -Pointer to filtered output macroblock.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr, if the function runs without error.
+ *
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - one or more of the following pointers is NULL: pSrcDst, pAlpha,
+ * pBeta, pThresholds, or pBS.
+ * - pSrcDst is not 8-byte aligned.
+ * - srcdstStep is not a multiple of 8.
+ * - pThresholds is not 4-byte aligned.
+ * - pAlpha[0] and/or pAlpha[1] is outside the range [0,255].
+ * - pBeta[0] and/or pBeta[1] is outside the range [0,18].
+ * - One or more entries in the table pThresholds[0..7] is outside
+ * of the range [0,25].
+ * - pBS is out of range, i.e., one of the following conditions is true:
+ * pBS[i]<0, pBS[i]>4, pBS[i]==4 for i>=4, or
+ * (pBS[i]==4 && pBS[i^3]!=4) for 0<=i<=3.
+ * - pBS is not 4-byte aligned.
+ *
+ */
+
+OMXResult omxVCM4P10_FilterDeblockingChroma_VerEdge_I(
+ OMX_U8* pSrcDst,
+ OMX_S32 srcdstStep,
+ const OMX_U8* pAlpha,
+ const OMX_U8* pBeta,
+ const OMX_U8* pThresholds,
+ const OMX_U8 *pBS
+ )
+{
+ int I, X, Y, Internal=0;
+
+ armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot8ByteAligned(pSrcDst), OMX_Sts_BadArgErr);
+ armRetArgErrIf(srcdstStep & 7, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pAlpha == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pBeta == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pThresholds == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot4ByteAligned(pThresholds), OMX_Sts_BadArgErr);
+ armRetArgErrIf(pBS == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot4ByteAligned(pBS), OMX_Sts_BadArgErr);
+ armRetArgErrIf(pBeta[0] > 18, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pBeta[1] > 18, OMX_Sts_BadArgErr);
+
+ for (X=0; X<8; X+=4, Internal=1)
+ {
+ for (Y=0; Y<8; Y++)
+ {
+ I = (Y>>1)+4*(X>>1);
+
+ armRetArgErrIf(pBS[I] > 4, OMX_Sts_BadArgErr);
+
+ armRetArgErrIf( (I > 3) && (pBS[I] == 4),
+ OMX_Sts_BadArgErr);
+
+ armRetArgErrIf( ( (pBS[I] == 4) && (pBS[I^3] != 4) ),
+ OMX_Sts_BadArgErr);
+ armRetArgErrIf(pThresholds[Y] > 25, OMX_Sts_BadArgErr);
+
+
+ /* Filter vertical edge with q0 at (X,Y) */
+ armVCM4P10_DeBlockPixel(
+ pSrcDst + Y*srcdstStep + X,
+ 1,
+ pThresholds[(Y>>1)+4*(X>>2)],
+ pAlpha[Internal],
+ pBeta[Internal],
+ pBS[I],
+ 1);
+ }
+ }
+
+ return OMX_Sts_NoErr;
+}
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_HorEdge_I.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_HorEdge_I.c
new file mode 100644
index 0000000..30a37da
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_HorEdge_I.c
@@ -0,0 +1,125 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: omxVCM4P10_FilterDeblockingLuma_HorEdge_I.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * H.264 luma deblock module
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/**
+ * Function: omxVCM4P10_FilterDeblockingLuma_HorEdge_I (6.3.3.3.2)
+ *
+ * Description:
+ * Performs in-place deblock filtering on four horizontal edges of the luma
+ * macroblock (16x16).
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - pointer to the input macroblock; must be 16-byte aligned.
+ * srcdstStep -s tep of the arrays; must be a multiple of 16.
+ * pAlpha - array of size 2 of alpha thresholds (the first item is the alpha
+ * threshold for the external vertical edge, and the second item is
+ * for the internal horizontal edge); per [ISO14496-10] alpha
+ * values must be in the range [0,255].
+ * pBeta - array of size 2 of beta thresholds (the first item is the beta
+ * threshold for the external horizontal edge, and the second item
+ * is for the internal horizontal edge). Per [ISO14496-10] beta
+ * values must be in the range [0,18].
+ * pThresholds - array of size 16 containing thresholds, TC0, for the top
+ * horizontal edge of each 4x4 block, arranged in horizontal block
+ * order; must be aligned on a 4-byte boundary. Per [ISO14496 10]
+ * values must be in the range [0,25].
+ * pBS - array of size 16 of BS parameters (arranged in horizontal block
+ * order); valid in the range [0,4] with the following
+ * restrictions: i) pBS[i]== 4 may occur only for 0<=i<=3, ii)
+ * pBS[i]== 4 if and only if pBS[i^3]== 4. Must be 4-byte aligned.
+ *
+ * Output Arguments:
+ *
+ * pSrcDst -Pointer to filtered output macroblock.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr, if the function runs without error.
+ *
+ * OMX_Sts_BadArgErr, if one of the following cases occurs:
+ * - one or more of the following pointers is NULL: pSrcDst, pAlpha,
+ * pBeta, pThresholds, or pBS.
+ * - either pThresholds or pBS is not aligned on a 4-byte boundary.
+ * - pSrcDst is not 16-byte aligned.
+ * - srcdstStep is not a multiple of 16.
+ * - pAlpha[0] and/or pAlpha[1] is outside the range [0,255].
+ * - pBeta[0] and/or pBeta[1] is outside the range [0,18].
+ * - One or more entries in the table pThresholds[0..15] is
+ * outside of the range [0,25].
+ * - pBS is out of range, i.e., one of the following conditions is true:
+ * pBS[i]<0, pBS[i]>4, pBS[i]==4 for i>=4, or
+ * (pBS[i]==4 && pBS[i^3]!=4) for 0<=i<=3.
+ *
+ */
+
+OMXResult omxVCM4P10_FilterDeblockingLuma_HorEdge_I(
+ OMX_U8* pSrcDst,
+ OMX_S32 srcdstStep,
+ const OMX_U8* pAlpha,
+ const OMX_U8* pBeta,
+ const OMX_U8* pThresholds,
+ const OMX_U8 *pBS
+ )
+{
+ int I, X, Y, Internal=0;
+
+ armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot8ByteAligned(pSrcDst), OMX_Sts_BadArgErr);
+ armRetArgErrIf(srcdstStep & 7, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pAlpha == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pBeta == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pThresholds == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot4ByteAligned(pThresholds), OMX_Sts_BadArgErr);
+ armRetArgErrIf(pBS == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot4ByteAligned(pBS), OMX_Sts_BadArgErr);
+
+ for (Y=0; Y<16; Y+=4, Internal=1)
+ {
+ for (X=0; X<16; X++)
+ {
+ I = (X>>2)+4*(Y>>2);
+
+ armRetArgErrIf(pBS[I] > 4, OMX_Sts_BadArgErr)
+
+ armRetArgErrIf( (I > 3) && (pBS[I] == 4),
+ OMX_Sts_BadArgErr)
+
+ armRetArgErrIf( (I < 4) &&
+ ( (pBS[I] == 4) && (pBS[I^1] != 4) ),
+ OMX_Sts_BadArgErr)
+
+ /* Filter horizontal edge with q0 at (X,Y) */
+ armVCM4P10_DeBlockPixel(
+ pSrcDst + Y*srcdstStep + X,
+ srcdstStep,
+ pThresholds[I],
+ pAlpha[Internal],
+ pBeta[Internal],
+ pBS[I],
+ 0);
+ }
+ }
+
+ return OMX_Sts_NoErr;
+}
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_VerEdge_I.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_VerEdge_I.c
new file mode 100644
index 0000000..8733427
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_VerEdge_I.c
@@ -0,0 +1,128 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: omxVCM4P10_FilterDeblockingLuma_VerEdge_I.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * H.264 luma deblock module
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/**
+ * Function: omxVCM4P10_FilterDeblockingLuma_VerEdge_I (6.3.3.3.1)
+ *
+ * Description:
+ * Performs in-place deblock filtering on four vertical edges of the luma
+ * macroblock (16x16).
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - Pointer to the input macroblock; must be 16-byte aligned.
+ * srcdstStep -Step of the arrays; must be a multiple of 16.
+ * pAlpha -Array of size 2 of alpha thresholds (the first item is the alpha
+ * threshold for the external vertical edge, and the second item is
+ * for the internal vertical edge); per [ISO14496-10] alpha values
+ * must be in the range [0,255].
+ * pBeta -Array of size 2 of beta thresholds (the first item is the beta
+ * threshold for the external vertical edge, and the second item is
+ * for the internal vertical edge); per [ISO14496-10] beta values
+ * must be in the range [0,18].
+ * pThresholds -Array of size 16 of Thresholds (TC0) (values for the left
+ * edge of each 4x4 block, arranged in vertical block order); must
+ * be aligned on a 4-byte boundary.. Per [ISO14496-10] values must
+ * be in the range [0,25].
+ * pBS -Array of size 16 of BS parameters (arranged in vertical block
+ * order); valid in the range [0,4] with the following
+ * restrictions: i) pBS[i]== 4 may occur only for 0<=i<=3, ii)
+ * pBS[i]== 4 if and only if pBS[i^3]== 4. Must be 4-byte aligned.
+ *
+ * Output Arguments:
+ *
+ * pSrcDst -Pointer to filtered output macroblock.
+ *
+ * Return Value:
+ * If the function runs without error, it returns OMX_Sts_NoErr.
+ * If one of the following cases occurs, the function returns
+ * OMX_Sts_BadArgErr:
+ * Either of the pointers in pSrcDst, pAlpha, pBeta, pThresholds, or pBS
+ * is NULL.
+ * Either pThresholds or pBS is not aligned on a 4-byte boundary.
+ * pSrcDst is not 16-byte aligned.
+ * srcdstStep is not a multiple of 16.
+ * pAlpha[0] and/or pAlpha[1] is outside the range [0,255].
+ * pBeta[0] and/or pBeta[1] is outside the range [0,18].
+ * One or more entries in the table pThresholds[0..15]is outside of the
+ * range [0,25].
+ * pBS is out of range, i.e., one of the following conditions is true:
+ * pBS[i]<0, pBS[i]>4, pBS[i]==4 for i>=4, or (pBS[i]==4 &&
+ * pBS[i^3]!=4) for 0<=i<=3.
+ *
+ */
+
+OMXResult omxVCM4P10_FilterDeblockingLuma_VerEdge_I(
+ OMX_U8* pSrcDst,
+ OMX_S32 srcdstStep,
+ const OMX_U8* pAlpha,
+ const OMX_U8* pBeta,
+ const OMX_U8* pThresholds,
+ const OMX_U8 *pBS
+ )
+{
+ int X, Y, I, Internal=0;
+
+ armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot16ByteAligned(pSrcDst),OMX_Sts_BadArgErr);
+ armRetArgErrIf(srcdstStep & 15, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pAlpha == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pBeta == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pThresholds == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot4ByteAligned(pThresholds), OMX_Sts_BadArgErr);
+ armRetArgErrIf(pBS == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot4ByteAligned(pBS), OMX_Sts_BadArgErr);
+ armRetArgErrIf(pBeta[0] > 18, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pBeta[1] > 18, OMX_Sts_BadArgErr);
+
+
+ for (X=0; X<16; X+=4, Internal=1)
+ {
+ for (Y=0; Y<16; Y++)
+ {
+ I = (Y>>2)+4*(X>>2);
+
+ armRetArgErrIf(pBS[Y] > 4, OMX_Sts_BadArgErr);
+
+ armRetArgErrIf((pBS[Y] == 4) && (Y > 3),
+ OMX_Sts_BadArgErr);
+
+ armRetArgErrIf(( (pBS[Y] == 4) && (pBS[Y^3] != 4) ),
+ OMX_Sts_BadArgErr);
+
+ armRetArgErrIf(pThresholds[Y] > 25, OMX_Sts_BadArgErr);
+
+ /* Filter vertical edge with q0 at (X,Y) */
+ armVCM4P10_DeBlockPixel(
+ pSrcDst + Y*srcdstStep + X,
+ 1,
+ pThresholds[I],
+ pAlpha[Internal],
+ pBeta[Internal],
+ pBS[I],
+ 0);
+ }
+ }
+
+ return OMX_Sts_NoErr;
+}
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_GetVLCInfo.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_GetVLCInfo.c
new file mode 100644
index 0000000..81c59d6
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_GetVLCInfo.c
@@ -0,0 +1,192 @@
+/**
+ *
+ * File Name: omxVCM4P10_GetVLCInfo.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ * Description:
+ *
+ * This function extracts run-length encoding (RLE) information
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/**
+ * Function: omxVCM4P10_GetVLCInfo (6.3.5.9.1)
+ *
+ * Description:
+ * This function extracts run-length encoding (RLE) information from the
+ * coefficient matrix. The results are returned in an OMXVCM4P10VLCInfo
+ * structure.
+ *
+ * Input Arguments:
+ *
+ * pSrcCoeff - pointer to the transform coefficient matrix. 8-byte
+ * alignment required.
+ * pScanMatrix - pointer to the scan order definition matrix. For a luma
+ * block the scan matrix should follow [ISO14496-10] section 8.5.4,
+ * and should contain the values 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13,
+ * 10, 7, 11, 14, 15. For a chroma block, the scan matrix should
+ * contain the values 0, 1, 2, 3.
+ * bAC - indicates presence of a DC coefficient; 0 = DC coefficient
+ * present, 1= DC coefficient absent.
+ * MaxNumCoef - specifies the number of coefficients contained in the
+ * transform coefficient matrix, pSrcCoeff. The value should be 16
+ * for blocks of type LUMADC, LUMAAC, LUMALEVEL, and CHROMAAC. The
+ * value should be 4 for blocks of type CHROMADC.
+ *
+ * Output Arguments:
+ *
+ * pDstVLCInfo - pointer to structure that stores information for
+ * run-length coding.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL:
+ * pSrcCoeff, pScanMatrix, pDstVLCInfo
+ * - pSrcCoeff is not aligned on an 8-byte boundary
+ *
+ */
+OMXResult omxVCM4P10_GetVLCInfo (
+ const OMX_S16* pSrcCoeff,
+ const OMX_U8* pScanMatrix,
+ OMX_U8 bAC,
+ OMX_U32 MaxNumCoef,
+ OMXVCM4P10VLCInfo* pDstVLCInfo
+)
+{
+ OMX_INT i, MinIndex;
+ OMX_S32 Value;
+ OMX_U32 Mask = 4, RunBefore;
+ OMX_S16 *pLevel;
+ OMX_U8 *pRun;
+ OMX_S16 Buf [16];
+
+ /* check for argument error */
+ armRetArgErrIf(pSrcCoeff == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(armNot8ByteAligned(pSrcCoeff), OMX_Sts_BadArgErr)
+ armRetArgErrIf(pScanMatrix == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pDstVLCInfo == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(bAC > 1, OMX_Sts_BadArgErr)
+ armRetArgErrIf(MaxNumCoef > 16, OMX_Sts_BadArgErr)
+
+ /* Initialize RLE Info structure */
+ pDstVLCInfo->uTrailing_Ones = 0;
+ pDstVLCInfo->uTrailing_One_Signs = 0;
+ pDstVLCInfo->uNumCoeffs = 0;
+ pDstVLCInfo->uTotalZeros = 0;
+
+ for (i = 0; i < 16; i++)
+ {
+ pDstVLCInfo->iLevels [i] = 0;
+ pDstVLCInfo->uRuns [i] = 0;
+ }
+
+ MinIndex = (bAC == 0 && MaxNumCoef == 15) ? 1 : 0;
+ for (i = MinIndex; i < (MaxNumCoef + MinIndex); i++)
+ {
+ /* Scan */
+ Buf [i - MinIndex] = pSrcCoeff [pScanMatrix [i]];
+ }
+
+ /* skip zeros at the end */
+ i = MaxNumCoef - 1;
+ while (!Buf [i] && i >= 0)
+ {
+ i--;
+ }
+
+ if (i < 0)
+ {
+ return OMX_Sts_NoErr;
+ }
+
+ /* Fill RLE Info structure */
+ pLevel = pDstVLCInfo->iLevels;
+ pRun = pDstVLCInfo->uRuns;
+ RunBefore = 0;
+
+ /* Handle first non zero separate */
+ pDstVLCInfo->uNumCoeffs++;
+ Value = Buf [i];
+ if (Value == 1 || Value == -1)
+ {
+ pDstVLCInfo->uTrailing_Ones++;
+
+ pDstVLCInfo->uTrailing_One_Signs |=
+ Value == -1 ? Mask : 0;
+ Mask >>= 1;
+ }
+ else
+ {
+ Value -= (Value > 0 ? 1 : -1);
+ *pLevel++ = Value;
+ Mask = 0;
+ }
+
+ /* Remaining non zero */
+ while (--i >= 0)
+ {
+ Value = Buf [i];
+ if (Value)
+ {
+ pDstVLCInfo->uNumCoeffs++;
+
+ /* Mask becomes zero after entering */
+ if (Mask &&
+ (Value == 1 ||
+ Value == -1))
+ {
+ pDstVLCInfo->uTrailing_Ones++;
+
+ pDstVLCInfo->uTrailing_One_Signs |=
+ Value == -1 ? Mask : 0;
+ Mask >>= 1;
+ *pRun++ = RunBefore;
+ RunBefore = 0;
+ }
+ else
+ {
+ /* If 3 trailing ones are not completed */
+ if (Mask)
+ {
+ Mask = 0;
+ Value -= (Value > 0 ? 1 : -1);
+ }
+ *pLevel++ = Value;
+ *pRun++ = RunBefore;
+ RunBefore = 0;
+ }
+ }
+ else
+ {
+ pDstVLCInfo->uTotalZeros++;
+ RunBefore++;
+ }
+ }
+
+ /* Update last run */
+ if (RunBefore)
+ {
+ *pRun++ = RunBefore;
+ }
+
+ return OMX_Sts_NoErr;
+}
+
+/*****************************************************************************
+ * END OF FILE
+ *****************************************************************************/
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateChroma.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateChroma.c
new file mode 100644
index 0000000..8824de2
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateChroma.c
@@ -0,0 +1,99 @@
+/**
+ *
+ * File Name: omxVCM4P10_InterpolateChroma.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ * Description:
+ * This function will calculate 1/8 Pixel interpolation for Chroma Block
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armVC.h"
+#include "armCOMM.h"
+
+
+/**
+ * Function: omxVCM4P10_InterpolateChroma (6.3.3.2.2)
+ *
+ * Description:
+ * Performs 1/8-pixel interpolation for inter chroma MB.
+ *
+ * Input Arguments:
+ *
+ * pSrc -Pointer to the source reference frame buffer
+ * srcStep -Reference frame step in bytes
+ * dstStep -Destination frame step in bytes; must be a multiple of
+ * roi.width.
+ * dx -Fractional part of horizontal motion vector component in 1/8 pixel
+ * unit; valid in the range [0,7]
+ * dy -Fractional part of vertical motion vector component in 1/8 pixel
+ * unit; valid in the range [0,7]
+ * roi -Dimension of the interpolation region; the parameters roi.width and
+ * roi.height must be equal to either 2, 4, or 8.
+ *
+ * Output Arguments:
+ *
+ * pDst -Pointer to the destination frame buffer if roi.width==2, 2-byte
+ * alignment required if roi.width==4, 4-byte alignment required
+ * if roi.width==8, 8-byte alignment required
+ *
+ * Return Value:
+ * If the function runs without error, it returns OMX_Sts_NoErr.
+ * If one of the following cases occurs, the function returns
+ * OMX_Sts_BadArgErr:
+ * pSrc or pDst is NULL.
+ * srcStep or dstStep < 8.
+ * dx or dy is out of range [0-7].
+ * roi.width or roi.height is out of range {2,4,8}.
+ * roi.width is equal to 2, but pDst is not 2-byte aligned.
+ * roi.width is equal to 4, but pDst is not 4-byte aligned.
+ * roi.width is equal to 8, but pDst is not 8 byte aligned.
+ * srcStep or dstStep is not a multiple of 8.
+ *
+ */
+
+OMXResult omxVCM4P10_InterpolateChroma (
+ const OMX_U8* pSrc,
+ OMX_S32 srcStep,
+ OMX_U8* pDst,
+ OMX_S32 dstStep,
+ OMX_S32 dx,
+ OMX_S32 dy,
+ OMXSize roi
+ )
+{
+ /* check for argument error */
+ armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(srcStep < 8, OMX_Sts_BadArgErr)
+ armRetArgErrIf(dstStep < 8, OMX_Sts_BadArgErr)
+ armRetArgErrIf(dx < 0, OMX_Sts_BadArgErr)
+ armRetArgErrIf(dx > 7, OMX_Sts_BadArgErr)
+ armRetArgErrIf(dy < 0, OMX_Sts_BadArgErr)
+ armRetArgErrIf(dy > 7, OMX_Sts_BadArgErr)
+ armRetArgErrIf((roi.width != 2) && (roi.width != 4) && (roi.width != 8), OMX_Sts_BadArgErr)
+ armRetArgErrIf((roi.height != 2) && (roi.height != 4) && (roi.height != 8), OMX_Sts_BadArgErr)
+ armRetArgErrIf((roi.width == 2) && armNot2ByteAligned(pDst), OMX_Sts_BadArgErr)
+ armRetArgErrIf((roi.width == 4) && armNot4ByteAligned(pDst), OMX_Sts_BadArgErr)
+ armRetArgErrIf((roi.width == 8) && armNot8ByteAligned(pDst), OMX_Sts_BadArgErr)
+ armRetArgErrIf(srcStep & 7, OMX_Sts_BadArgErr)
+ armRetArgErrIf(dstStep & 7, OMX_Sts_BadArgErr)
+
+ return armVCM4P10_Interpolate_Chroma
+ ((OMX_U8*)pSrc, srcStep, pDst, dstStep, roi.width, roi.height, dx, dy);
+}
+
+
+/*****************************************************************************
+ * END OF FILE
+ *****************************************************************************/
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateHalfHor_Luma.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateHalfHor_Luma.c
new file mode 100644
index 0000000..ef0befa
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateHalfHor_Luma.c
@@ -0,0 +1,124 @@
+/**
+ *
+ * File Name: omxVCM4P10_InterpolateHalfHor_Luma.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ * Description:
+ * This function will calculate Half horizontal luma interpolation
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/**
+ * Function: omxVCM4P10_InterpolateHalfHor_Luma (6.3.5.5.1)
+ *
+ * Description:
+ * This function performs interpolation for two horizontal 1/2-pel positions
+ * (-1/2,0) and (1/2, 0) - around a full-pel position.
+ *
+ * Input Arguments:
+ *
+ * pSrc - Pointer to the top-left corner of the block used to interpolate in
+ * the reconstruction frame plane.
+ * iSrcStep - Step of the source buffer.
+ * iDstStep - Step of the destination(interpolation) buffer; must be a
+ * multiple of iWidth.
+ * iWidth - Width of the current block; must be equal to either 4, 8, or 16
+ * iHeight - Height of the current block; must be equal to 4, 8, or 16
+ *
+ * Output Arguments:
+ *
+ * pDstLeft -Pointer to the interpolation buffer of the left -pel position
+ * (-1/2, 0)
+ * If iWidth==4, 4-byte alignment required.
+ * If iWidth==8, 8-byte alignment required.
+ * If iWidth==16, 16-byte alignment required.
+ * pDstRight -Pointer to the interpolation buffer of the right -pel
+ * position (1/2, 0)
+ * If iWidth==4, 4-byte alignment required.
+ * If iWidth==8, 8-byte alignment required.
+ * If iWidth==16, 16-byte alignment required.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL:
+ * pSrc, pDstLeft, or pDstRight
+ * - iWidth or iHeight have values other than 4, 8, or 16
+ * - iWidth==4 but pDstLeft and/or pDstRight is/are not aligned on a 4-byte boundary
+ * - iWidth==8 but pDstLeft and/or pDstRight is/are not aligned on a 8-byte boundary
+ * - iWidth==16 but pDstLeft and/or pDstRight is/are not aligned on a 16-byte boundary
+ * - any alignment restrictions are violated
+ *
+ */
+
+OMXResult omxVCM4P10_InterpolateHalfHor_Luma(
+ const OMX_U8* pSrc,
+ OMX_U32 iSrcStep,
+ OMX_U8* pDstLeft,
+ OMX_U8* pDstRight,
+ OMX_U32 iDstStep,
+ OMX_U32 iWidth,
+ OMX_U32 iHeight
+)
+{
+ OMXResult RetValue;
+
+ /* check for argument error */
+ armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pDstLeft == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pDstRight == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf((iWidth == 4) &&
+ armNot4ByteAligned(pDstLeft) &&
+ armNot4ByteAligned(pDstRight), OMX_Sts_BadArgErr)
+ armRetArgErrIf((iWidth == 8) &&
+ armNot8ByteAligned(pDstLeft) &&
+ armNot8ByteAligned(pDstRight), OMX_Sts_BadArgErr)
+ armRetArgErrIf((iWidth == 16) &&
+ armNot16ByteAligned(pDstLeft) &&
+ armNot16ByteAligned(pDstRight), OMX_Sts_BadArgErr)
+
+ armRetArgErrIf((iHeight != 16) && (iHeight != 8)&& (iHeight != 4), OMX_Sts_BadArgErr)
+ armRetArgErrIf((iWidth != 16) && (iWidth != 8)&& (iWidth != 4), OMX_Sts_BadArgErr)
+
+ RetValue = armVCM4P10_InterpolateHalfHor_Luma (
+ pSrc - 1,
+ iSrcStep,
+ pDstLeft,
+ iDstStep,
+ iWidth,
+ iHeight);
+
+ if (RetValue != OMX_Sts_NoErr)
+ {
+ return RetValue;
+ }
+
+ RetValue = armVCM4P10_InterpolateHalfHor_Luma (
+ pSrc,
+ iSrcStep,
+ pDstRight,
+ iDstStep,
+ iWidth,
+ iHeight);
+
+ return RetValue;
+}
+
+/*****************************************************************************
+ * END OF FILE
+ *****************************************************************************/
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateHalfVer_Luma.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateHalfVer_Luma.c
new file mode 100644
index 0000000..3560ff8
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateHalfVer_Luma.c
@@ -0,0 +1,123 @@
+/**
+ *
+ * File Name: omxVCM4P10_InterpolateHalfVer_Luma.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ * Description:
+ * This function will calculate SAD for 4x4 blocks
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+
+/**
+ * Function: omxVCM4P10_InterpolateHalfVer_Luma (6.3.5.5.2)
+ *
+ * Description:
+ * This function performs interpolation for two vertical 1/2-pel positions -
+ * (0, -1/2) and (0, 1/2) - around a full-pel position.
+ *
+ * Input Arguments:
+ *
+ * pSrc - Pointer to top-left corner of block used to interpolate in the
+ * reconstructed frame plane
+ * iSrcStep - Step of the source buffer.
+ * iDstStep - Step of the destination (interpolation) buffer; must be a
+ * multiple of iWidth.
+ * iWidth - Width of the current block; must be equal to either 4, 8, or 16
+ * iHeight - Height of the current block; must be equal to either 4, 8, or 16
+ *
+ * Output Arguments:
+ *
+ * pDstUp -Pointer to the interpolation buffer of the -pel position above
+ * the current full-pel position (0, -1/2)
+ * If iWidth==4, 4-byte alignment required.
+ * If iWidth==8, 8-byte alignment required.
+ * If iWidth==16, 16-byte alignment required.
+ * pDstDown -Pointer to the interpolation buffer of the -pel position below
+ * the current full-pel position (0, 1/2)
+ * If iWidth==4, 4-byte alignment required.
+ * If iWidth==8, 8-byte alignment required.
+ * If iWidth==16, 16-byte alignment required.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL:
+ * pSrc, pDstUp, or pDstDown
+ * - iWidth or iHeight have values other than 4, 8, or 16
+ * - iWidth==4 but pDstUp and/or pDstDown is/are not aligned on a 4-byte boundary
+ * - iWidth==8 but pDstUp and/or pDstDown is/are not aligned on a 8-byte boundary
+ * - iWidth==16 but pDstUp and/or pDstDown is/are not aligned on a 16-byte boundary
+ *
+ */
+ OMXResult omxVCM4P10_InterpolateHalfVer_Luma(
+ const OMX_U8* pSrc,
+ OMX_U32 iSrcStep,
+ OMX_U8* pDstUp,
+ OMX_U8* pDstDown,
+ OMX_U32 iDstStep,
+ OMX_U32 iWidth,
+ OMX_U32 iHeight
+)
+{
+ OMXResult RetValue;
+
+ /* check for argument error */
+ armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pDstUp == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pDstDown == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf((iWidth == 4) &&
+ armNot4ByteAligned(pDstUp) &&
+ armNot4ByteAligned(pDstDown), OMX_Sts_BadArgErr)
+ armRetArgErrIf((iWidth == 8) &&
+ armNot8ByteAligned(pDstUp) &&
+ armNot8ByteAligned(pDstDown), OMX_Sts_BadArgErr)
+ armRetArgErrIf((iWidth == 16) &&
+ armNot16ByteAligned(pDstUp) &&
+ armNot16ByteAligned(pDstDown), OMX_Sts_BadArgErr)
+
+ armRetArgErrIf((iHeight != 16) && (iHeight != 8)&& (iHeight != 4), OMX_Sts_BadArgErr)
+ armRetArgErrIf((iWidth != 16) && (iWidth != 8)&& (iWidth != 4), OMX_Sts_BadArgErr)
+
+ RetValue = armVCM4P10_InterpolateHalfVer_Luma(
+ pSrc - iSrcStep,
+ iSrcStep,
+ pDstUp,
+ iDstStep,
+ iWidth,
+ iHeight);
+
+ if (RetValue != OMX_Sts_NoErr)
+ {
+ return RetValue;
+ }
+
+ RetValue = armVCM4P10_InterpolateHalfVer_Luma(
+ pSrc,
+ iSrcStep,
+ pDstDown,
+ iDstStep,
+ iWidth,
+ iHeight);
+
+ return RetValue;
+}
+
+/*****************************************************************************
+ * END OF FILE
+ *****************************************************************************/
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateLuma.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateLuma.c
new file mode 100644
index 0000000..d233735
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateLuma.c
@@ -0,0 +1,99 @@
+/**
+ *
+ * File Name: omxVCM4P10_InterpolateLuma.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ * Description:
+ * This function will calculate Performs quarter-pixel interpolation
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armVC.h"
+#include "armCOMM.h"
+
+/**
+ * Function: omxVCM4P10_InterpolateLuma (6.3.3.2.1)
+ *
+ * Description:
+ * Performs quarter-pixel interpolation for inter luma MB. It is assumed that
+ * the frame is already padded when calling this function.
+ *
+ * Input Arguments:
+ *
+ * pSrc -Pointer to the source reference frame buffer
+ * srcStep -reference frame step, in bytes; must be a multiple of roi.width
+ * dstStep -destination frame step, in bytes; must be a multiple of
+ * roi.width
+ * dx -Fractional part of horizontal motion vector component in 1/4 pixel
+ * unit; valid in the range [0,3]
+ * dy -Fractional part of vertical motion vector y component in 1/4 pixel
+ * unit; valid in the range [0,3]
+ * roi -Dimension of the interpolation region; the parameters roi.width and
+ * roi.height must be equal to either 4, 8, or 16.
+ *
+ * Output Arguments:
+ *
+ * pDst -Pointer to the destination frame buffer if roi.width==4, 4-byte
+ * alignment required if roi.width==8, 8-byte alignment required
+ * if roi.width==16, 16-byte alignment required
+ *
+ * Return Value:
+ * If the function runs without error, it returns OMX_Sts_NoErr.
+ * If one of the following cases occurs, the function returns
+ * OMX_Sts_BadArgErr:
+ * pSrc or pDst is NULL.
+ * srcStep or dstStep < roi.width.
+ * dx or dy is out of range [0,3].
+ * roi.width or roi.height is out of range {4, 8, 16}.
+ * roi.width is equal to 4, but pDst is not 4 byte aligned.
+ * roi.width is equal to 8 or 16, but pDst is not 8 byte aligned.
+ * srcStep or dstStep is not a multiple of 8.
+ *
+ */
+
+OMXResult omxVCM4P10_InterpolateLuma (
+ const OMX_U8* pSrc,
+ OMX_S32 srcStep,
+ OMX_U8* pDst,
+ OMX_S32 dstStep,
+ OMX_S32 dx,
+ OMX_S32 dy,
+ OMXSize roi
+ )
+{
+ /* check for argument error */
+ armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(srcStep < roi.width, OMX_Sts_BadArgErr)
+ armRetArgErrIf(dstStep < roi.width, OMX_Sts_BadArgErr)
+ armRetArgErrIf(dx < 0, OMX_Sts_BadArgErr)
+ armRetArgErrIf(dx > 3, OMX_Sts_BadArgErr)
+ armRetArgErrIf(dy < 0, OMX_Sts_BadArgErr)
+ armRetArgErrIf(dy > 3, OMX_Sts_BadArgErr)
+ armRetArgErrIf((roi.width != 4) && (roi.width != 8) && (roi.width != 16), OMX_Sts_BadArgErr)
+ armRetArgErrIf((roi.height != 4) && (roi.height != 8) && (roi.height != 16), OMX_Sts_BadArgErr)
+ armRetArgErrIf((roi.width == 4) && armNot4ByteAligned(pDst), OMX_Sts_BadArgErr)
+ armRetArgErrIf((roi.width == 8) && armNot8ByteAligned(pDst), OMX_Sts_BadArgErr)
+ armRetArgErrIf((roi.width == 16) && armNot16ByteAligned(pDst), OMX_Sts_BadArgErr)
+ armRetArgErrIf(srcStep & 7, OMX_Sts_BadArgErr)
+ armRetArgErrIf(dstStep & 7, OMX_Sts_BadArgErr)
+
+ return armVCM4P10_Interpolate_Luma
+ (pSrc, srcStep, pDst, dstStep, roi.width, roi.height, dx, dy);
+
+}
+
+
+/*****************************************************************************
+ * END OF FILE
+ *****************************************************************************/
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InvTransformDequant_ChromaDC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InvTransformDequant_ChromaDC.c
new file mode 100644
index 0000000..92ba031
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InvTransformDequant_ChromaDC.c
@@ -0,0 +1,102 @@
+/**
+ *
+ * File Name: omxVCM4P10_InvTransformDequant_ChromaDC.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ * Description:
+ * This function will calculate 4x4 hadamard transform of chroma DC
+ * coefficients and quantization
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armVC.h"
+#include "armCOMM.h"
+
+/**
+ * Function: omxVCM4P10_InvTransformDequant_ChromaDC (6.3.5.6.4)
+ *
+ * Description:
+ * This function performs inverse 2x2 Hadamard transform and then dequantizes
+ * the coefficients.
+ *
+ * Input Arguments:
+ *
+ * pSrc - Pointer to the 2x2 array of the 2x2 Hadamard-transformed and
+ * quantized coefficients. 8 byte alignment required.
+ * iQP - Quantization parameter; must be in the range [0,51].
+ *
+ * Output Arguments:
+ *
+ * pDst - Pointer to inverse-transformed and dequantized coefficients.
+ * 8-byte alignment required.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL: pSrc
+ * - pSrc or pDst is not aligned on an 8-byte boundary
+ *
+ */
+OMXResult omxVCM4P10_InvTransformDequant_ChromaDC(
+ const OMX_S16* pSrc,
+ OMX_S16* pDst,
+ OMX_U32 iQP
+)
+{
+ OMX_INT i, j;
+ OMX_S32 m[2][2];
+ OMX_S32 QPer, V00, Value;
+
+ /* check for argument error */
+ armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(armNot8ByteAligned(pSrc), OMX_Sts_BadArgErr);
+ armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(armNot8ByteAligned(pDst), OMX_Sts_BadArgErr);
+ armRetArgErrIf(iQP > 51, OMX_Sts_BadArgErr)
+
+ /* Inv Hadamard Transform for 2x2 block */
+ m[0][0] = pSrc[0] + pSrc[1] + pSrc[2] + pSrc[3];
+ m[0][1] = pSrc[0] - pSrc[1] + pSrc[2] - pSrc[3];
+ m[1][0] = pSrc[0] + pSrc[1] - pSrc[2] - pSrc[3];
+ m[1][1] = pSrc[0] - pSrc[1] - pSrc[2] + pSrc[3];
+
+ /* Quantization */
+ /* Scaling */
+ QPer = iQP / 6;
+ V00 = armVCM4P10_VMatrix [iQP % 6][0];
+
+ for (j = 0; j < 2; j++)
+ {
+ for (i = 0; i < 2; i++)
+ {
+ if (QPer < 1)
+ {
+ Value = (m[j][i] * V00) >> 1;
+ }
+ else
+ {
+ Value = (m[j][i] * V00) << (QPer - 1);
+ }
+
+ pDst[j * 2 + i] = (OMX_S16) Value;
+ }
+ }
+
+ return OMX_Sts_NoErr;
+}
+
+/*****************************************************************************
+ * END OF FILE
+ *****************************************************************************/
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InvTransformDequant_LumaDC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InvTransformDequant_LumaDC.c
new file mode 100644
index 0000000..a3b1200
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InvTransformDequant_LumaDC.c
@@ -0,0 +1,128 @@
+/**
+ *
+ * File Name: omxVCM4P10_InvTransformDequant_LumaDC.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ * Description:
+ * This function will calculate 4x4 hadamard transform of luma DC coefficients
+ * and quantization
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/**
+ * Function: omxVCM4P10_InvTransformDequant_LumaDC (6.3.5.6.3)
+ *
+ * Description:
+ * This function performs inverse 4x4 Hadamard transform and then dequantizes
+ * the coefficients.
+ *
+ * Input Arguments:
+ *
+ * pSrc - Pointer to the 4x4 array of the 4x4 Hadamard-transformed and
+ * quantized coefficients. 16 byte alignment required.
+ * iQP - Quantization parameter; must be in the range [0,51].
+ *
+ * Output Arguments:
+ *
+ * pDst - Pointer to inverse-transformed and dequantized coefficients.
+ * 16-byte alignment required.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL: pSrc
+ * - pSrc or pDst is not aligned on a 16-byte boundary
+ *
+ */
+OMXResult omxVCM4P10_InvTransformDequant_LumaDC(
+ const OMX_S16* pSrc,
+ OMX_S16* pDst,
+ OMX_U32 iQP
+)
+{
+ OMX_INT i, j;
+ OMX_S32 m1[4][4], m2[4][4], Value;
+ OMX_S32 QPer, V;
+
+ /* check for argument error */
+ armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(iQP > 51, OMX_Sts_BadArgErr)
+ armRetArgErrIf(armNot16ByteAligned(pSrc), OMX_Sts_BadArgErr)
+ armRetArgErrIf(armNot16ByteAligned(pDst), OMX_Sts_BadArgErr)
+
+ /* Inv Hadamard Transform for DC Luma 4x4 block */
+ /* Horizontal */
+ for (i = 0; i < 4; i++)
+ {
+ j = i * 4;
+
+ m1[i][0] = pSrc[j + 0] + pSrc[j + 2]; /* a+c */
+ m1[i][1] = pSrc[j + 1] + pSrc[j + 3]; /* b+d */
+ m1[i][2] = pSrc[j + 0] - pSrc[j + 2]; /* a-c */
+ m1[i][3] = pSrc[j + 1] - pSrc[j + 3]; /* b-d */
+
+ m2[i][0] = m1[i][0] + m1[i][1]; /* a+b+c+d */
+ m2[i][1] = m1[i][2] + m1[i][3]; /* a+b-c-d */
+ m2[i][2] = m1[i][2] - m1[i][3]; /* a-b-c+d */
+ m2[i][3] = m1[i][0] - m1[i][1]; /* a-b+c-d */
+
+ }
+
+ /* Vertical */
+ for (i = 0; i < 4; i++)
+ {
+ m1[0][i] = m2[0][i] + m2[2][i];
+ m1[1][i] = m2[1][i] + m2[3][i];
+ m1[2][i] = m2[0][i] - m2[2][i];
+ m1[3][i] = m2[1][i] - m2[3][i];
+
+ m2[0][i] = m1[0][i] + m1[1][i];
+ m2[1][i] = m1[2][i] + m1[3][i];
+ m2[2][i] = m1[2][i] - m1[3][i];
+ m2[3][i] = m1[0][i] - m1[1][i];
+ }
+
+
+ /* Scaling */
+ QPer = iQP / 6;
+ V = armVCM4P10_VMatrix [iQP % 6][0];
+
+ for (j = 0; j < 4; j++)
+ {
+ for (i = 0; i < 4; i++)
+ {
+ if (QPer < 2)
+ {
+ Value = (m2[j][i] * V + (1 << (1 - QPer))) >> (2 - QPer);
+ }
+ else
+ {
+ Value = m2[j][i] * V * (1 << (QPer - 2));
+ }
+
+ pDst[j * 4 + i] = (OMX_S16) Value;
+
+ }
+ }
+ return OMX_Sts_NoErr;
+}
+
+/*****************************************************************************
+ * END OF FILE
+ *****************************************************************************/
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InvTransformResidualAndAdd.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InvTransformResidualAndAdd.c
new file mode 100644
index 0000000..3303997
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InvTransformResidualAndAdd.c
@@ -0,0 +1,124 @@
+/**
+ *
+ * File Name: omxVCM4P10_InvTransformResidualAndAdd.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ * Description:
+ * This function will inverse integer 4x4 transform
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/**
+ * Function: omxVCM4P10_InvTransformResidualAndAdd (6.3.5.7.1)
+ *
+ * Description:
+ * This function performs inverse an 4x4 integer transformation to produce
+ * the difference signal and then adds the difference to the prediction to get
+ * the reconstructed signal.
+ *
+ * Input Arguments:
+ *
+ * pSrcPred - Pointer to prediction signal. 4-byte alignment required.
+ * pDequantCoeff - Pointer to the transformed coefficients. 8-byte
+ * alignment required.
+ * iSrcPredStep - Step of the prediction buffer; must be a multiple of 4.
+ * iDstReconStep - Step of the destination reconstruction buffer; must be a
+ * multiple of 4.
+ * bAC - Indicate whether there is AC coefficients in the coefficients
+ * matrix.
+ *
+ * Output Arguments:
+ *
+ * pDstRecon -Pointer to the destination reconstruction buffer. 4-byte
+ * alignment required.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL:
+ * pSrcPred, pDequantCoeff, pDstRecon
+ * - pSrcPred is not aligned on a 4-byte boundary
+ * - iSrcPredStep or iDstReconStep is not a multiple of 4.
+ * - pDequantCoeff is not aligned on an 8-byte boundary
+ *
+ */
+OMXResult omxVCM4P10_InvTransformResidualAndAdd(
+ const OMX_U8* pSrcPred,
+ const OMX_S16* pDequantCoeff,
+ OMX_U8* pDstRecon,
+ OMX_U32 iSrcPredStep,
+ OMX_U32 iDstReconStep,
+ OMX_U8 bAC
+)
+{
+ OMX_INT i, j;
+ OMX_S16 In[16], Out[16];
+ OMX_S32 Value;
+
+ /* check for argument error */
+ armRetArgErrIf(pSrcPred == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(armNot4ByteAligned(pSrcPred), OMX_Sts_BadArgErr)
+ armRetArgErrIf(pDequantCoeff == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(armNot8ByteAligned(pDequantCoeff), OMX_Sts_BadArgErr)
+ armRetArgErrIf(pDstRecon == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(armNot4ByteAligned(pDstRecon), OMX_Sts_BadArgErr)
+ armRetArgErrIf(bAC > 1, OMX_Sts_BadArgErr)
+ armRetArgErrIf(iSrcPredStep == 0 || iSrcPredStep & 3, OMX_Sts_BadArgErr)
+ armRetArgErrIf(iDstReconStep == 0 || iDstReconStep & 3, OMX_Sts_BadArgErr)
+
+ if (bAC)
+ {
+ for (i = 0; i < 16; i++)
+ {
+ In[i] = pDequantCoeff [i];
+ }
+ }
+ else
+ {
+ /* Copy DC */
+ In[0] = pDequantCoeff [0];
+
+ for (i = 1; i < 16; i++)
+ {
+ In[i] = 0;
+ }
+ }
+
+ /* Residual Transform */
+ armVCM4P10_TransformResidual4x4 (Out, In);
+
+ for (j = 0; j < 4; j++)
+ {
+ for (i = 0; i < 4; i++)
+ {
+ /* Add predition */
+ Value = (OMX_S32) Out [j * 4 + i] + pSrcPred [j * iSrcPredStep + i];
+
+ /* Saturate Value to OMX_U8 */
+ Value = armClip (0, 255, Value);
+
+ pDstRecon[j * iDstReconStep + i] = (OMX_U8) Value;
+ }
+ }
+
+ return OMX_Sts_NoErr;
+}
+
+/*****************************************************************************
+ * END OF FILE
+ *****************************************************************************/
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_MEGetBufSize.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_MEGetBufSize.c
new file mode 100644
index 0000000..8c3a5c3
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_MEGetBufSize.c
@@ -0,0 +1,70 @@
+/**
+ *
+ * File Name: omxVCM4P10_MEGetBufSize.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Initialization modules for the vendor specific Motion Estimation structure.
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armVC.h"
+#include "armCOMM.h"
+
+/**
+ * Function: omxVCM4P10_MEGetBufSize (6.3.5.1.1)
+ *
+ * Description:
+ * Computes the size, in bytes, of the vendor-specific specification
+ * structure for the omxVCM4P10 motion estimation functions BlockMatch_Integer
+ * and MotionEstimationMB.
+ *
+ * Input Arguments:
+ *
+ * MEmode - motion estimation mode; available modes are defined by the
+ * enumerated type OMXVCM4P10MEMode
+ * pMEParams -motion estimation parameters
+ *
+ * Output Arguments:
+ *
+ * pSize - pointer to the number of bytes required for the motion
+ * estimation specification structure
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - pMEParams or pSize is NULL.
+ * - an invalid MEMode is specified.
+ *
+ */
+
+OMXResult omxVCM4P10_MEGetBufSize(
+ OMXVCM4P10MEMode MEMode,
+ const OMXVCM4P10MEParams *pMEParams,
+ OMX_U32 *pSize
+ )
+{
+ armRetArgErrIf(!pMEParams, OMX_Sts_BadArgErr);
+ armRetArgErrIf(!pSize, OMX_Sts_BadArgErr);
+ armRetArgErrIf((MEMode != OMX_VC_M4P10_FAST_SEARCH) &&
+ (MEMode != OMX_VC_M4P10_FULL_SEARCH), OMX_Sts_BadArgErr);
+ armRetArgErrIf((pMEParams->searchRange16x16 <= 0) ||
+ (pMEParams->searchRange8x8 <= 0) ||
+ (pMEParams->searchRange4x4 <= 0), OMX_Sts_BadArgErr);
+
+ *pSize = (OMX_INT) sizeof(ARMVCM4P10_MESpec);
+
+ return OMX_Sts_NoErr;
+}
+
+/* End of file */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_MEInit.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_MEInit.c
new file mode 100644
index 0000000..58ecc88
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_MEInit.c
@@ -0,0 +1,92 @@
+/**
+ *
+ * File Name: omxVCM4P10_MEInit.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Initialization modules for the vendor specific Motion Estimation structure.
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armVC.h"
+#include "armCOMM.h"
+
+/**
+ * Function: omxVCM4P10_MEInit (6.3.5.1.2)
+ *
+ * Description:
+ * Initializes the vendor-specific specification structure required for the
+ * omxVCM4P10 motion estimation functions: BlockMatch_Integer and
+ * MotionEstimationMB. Memory for the specification structure *pMESpec must be
+ * allocated prior to calling the function, and should be aligned on a 4-byte
+ * boundary. The number of bytes required for the specification structure can
+ * be determined using the function omxVCM4P10_MEGetBufSize. Following
+ * initialization by this function, the vendor-specific structure *pMESpec
+ * should contain an implementation-specific representation of all motion
+ * estimation parameters received via the structure pMEParams, for example
+ * searchRange16x16, searchRange8x8, etc.
+ *
+ * Input Arguments:
+ *
+ * MEmode - motion estimation mode; available modes are defined by the
+ * enumerated type OMXVCM4P10MEMode
+ * pMEParams - motion estimation parameters
+ * pMESpec - pointer to the uninitialized ME specification structure
+ *
+ * Output Arguments:
+ *
+ * pMESpec - pointer to the initialized ME specification structure
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - pMEParams or pSize is NULL.
+ * - an invalid value was specified for the parameter MEmode
+ * - a negative or zero value was specified for one of the search ranges
+ * (e.g., pMBParams >searchRange8x8, pMEParams->searchRange16x16, etc.)
+ * - either in isolation or in combination, one or more of the enables or
+ * search ranges in the structure *pMEParams were configured such
+ * that the requested behavior fails to comply with [ISO14496-10].
+ *
+ */
+
+OMXResult omxVCM4P10_MEInit(
+ OMXVCM4P10MEMode MEMode,
+ const OMXVCM4P10MEParams *pMEParams,
+ void *pMESpec
+ )
+{
+ ARMVCM4P10_MESpec *armMESpec = (ARMVCM4P10_MESpec *) pMESpec;
+
+ armRetArgErrIf(!pMEParams, OMX_Sts_BadArgErr);
+ armRetArgErrIf(!pMESpec, OMX_Sts_BadArgErr);
+ armRetArgErrIf((MEMode != OMX_VC_M4P10_FAST_SEARCH) &&
+ (MEMode != OMX_VC_M4P10_FULL_SEARCH), OMX_Sts_BadArgErr);
+ armRetArgErrIf((pMEParams->searchRange16x16 <= 0) ||
+ (pMEParams->searchRange8x8 <= 0) ||
+ (pMEParams->searchRange4x4 <= 0), OMX_Sts_BadArgErr);
+
+ armMESpec->MEParams.blockSplitEnable8x8 = pMEParams->blockSplitEnable8x8;
+ armMESpec->MEParams.blockSplitEnable4x4 = pMEParams->blockSplitEnable4x4;
+ armMESpec->MEParams.halfSearchEnable = pMEParams->halfSearchEnable;
+ armMESpec->MEParams.quarterSearchEnable = pMEParams->quarterSearchEnable;
+ armMESpec->MEParams.intraEnable4x4 = pMEParams->intraEnable4x4;
+ armMESpec->MEParams.searchRange16x16 = pMEParams->searchRange16x16;
+ armMESpec->MEParams.searchRange8x8 = pMEParams->searchRange8x8;
+ armMESpec->MEParams.searchRange4x4 = pMEParams->searchRange4x4;
+ armMESpec->MEMode = MEMode;
+
+ return OMX_Sts_NoErr;
+}
+
+/* End of file */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_MotionEstimationMB.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_MotionEstimationMB.c
new file mode 100644
index 0000000..33dbf3f
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_MotionEstimationMB.c
@@ -0,0 +1,1892 @@
+/** x
+ *
+ * File Name: omxVCM4P10_MotionEstimationMB.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ * Description:
+ * This function perform MB level motion estimation
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+#define ARM_VCM4P10_MAX_FRAMES (15)
+#define ARM_VCM4P10_MAX_4x4_SAD (0xffff)
+#define ARM_VCM4P10_MAX_MODE_VALUE (0xffffffff)
+#define ARM_VCM4P10_MAX_MODES (16)
+#define ARM_VCM4P10_MB_BLOCK_SIZE (16)
+#define ARM_VCM4P10_MEDIAN(a,b,c) (a>b?a>c?b>c?b:c:a:b>c?a>c?a:c:b)
+#define ARM_VCM4P10_SHIFT_QP (12)
+
+#define ARM_VCM4P10_MVPRED_MEDIAN (0)
+#define ARM_VCM4P10_MVPRED_L (1)
+#define ARM_VCM4P10_MVPRED_U (2)
+#define ARM_VCM4P10_MVPRED_UR (3)
+
+#define ARM_VCM4P10_MB_BLOCK_SIZE (16)
+#define ARM_VCM4P10_BLOCK_SIZE (4)
+#define ARM_VCM4P10_MAX_COST (1 << 30)
+#define ARM_VCM4P10_INVALID_BLOCK (-2)
+
+
+/**
+ * Function: armVCM4P10_CalculateBlockSAD
+ *
+ * Description:
+ * Calculate SAD value for the selected MB encoding mode and update
+ * pDstBlockSAD parameter. These SAD values are calculated 4x4 blocks at
+ * a time and in the scan order.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] pSrcMBInfo -
+ * [in] pSrcCurrBuf -
+ * [in] SrcCurrStep -
+ * [in] pSrcRefBufList-
+ * [in] SrcRefStep -
+ * [in] pSrcRecBuf -
+ * [in] SrcRecStep -
+ * [in] pRefRect -
+ * [in] pCurrPointPos -
+ * [in] Lambda -
+ * [in] pMESpec -
+ * [in] pMBInter -
+ * [in] pMBIntra -
+ * [out] pDstBlockSAD - pointer to 16 element array for SAD corresponding to 4x4 blocks
+ * Return Value:
+ * None
+ *
+ */
+
+static OMXResult armVCM4P10_CalculateBlockSAD(
+ OMXVCM4P10MBInfo *pSrcMBInfo,
+ const OMX_U8 *pSrcCurrBuf,
+ OMX_S32 SrcCurrStep,
+ const OMX_U8 *pSrcRefBufList[ARM_VCM4P10_MAX_FRAMES],
+ OMX_S32 SrcRefStep,
+ const OMX_U8 *pSrcRecBuf,
+ OMX_S32 SrcRecStep,
+ const OMXRect *pRefRect,
+ const OMXVCM4P2Coordinate *pCurrPointPos,
+ const OMXVCM4P10MBInfoPtr *pMBInter,
+ const OMXVCM4P10MBInfoPtr *pMBIntra,
+ OMX_U16 *pDstBlockSAD)
+{
+ OMX_INT InvalidSAD = 0;
+ OMX_INT i;
+
+ OMX_U8 Buffer [16*16 + 15];
+ OMX_U8 *pTempDstBuf;
+ OMX_S32 TempDstStep;
+ OMX_U8 *pTempRefBuf;
+ OMX_S32 TempRefStep;
+
+ /* Temporary buffer to store the predicted mb coefficients */
+ pTempDstBuf = armAlignTo16Bytes(Buffer);
+ TempDstStep = 16;
+
+ /* Update pDstBlockSAD if MB is a valid type */
+ if (pSrcMBInfo)
+ {
+ OMX_U32 Width=0, Height=0, MaxXPart, MaxYPart,MaxSubXPart,MaxSubYPart;
+
+ /* Depending on type of MB, do prediction and fill temp buffer */
+ switch (pSrcMBInfo->mbType)
+ {
+ case OMX_VC_P_16x16:
+ Width = 16;
+ Height = 16;
+ break;
+ case OMX_VC_P_16x8:
+ Width = 16;
+ Height = 8;
+ break;
+ case OMX_VC_P_8x16:
+ Width = 8;
+ Height = 16;
+ break;
+ case OMX_VC_P_8x8:
+ Width = 8;
+ Height = 8;
+ break;
+ case OMX_VC_INTRA_4x4:
+ {
+ /* Create predicted MB Intra4x4 mode */
+ OMX_S32 PredIntra4x4Mode [5][9];
+ OMX_S32 x, y, Block8x8, Block4x4, BlockX, BlockY;
+ OMX_U8 pSrcYBuff [(16*3)*(16*2)];
+ OMX_U8 *pSrcY;
+ OMX_S32 StepSrcY;
+ OMX_S32 availability;
+
+ for (y = 0; y < 5; y++)
+ {
+ for (x = 0; x < 9; x++)
+ {
+ /*
+ * Initialize with value of ARM_VCM4P10_INVALID_BLOCK, to mean this
+ * 4x4 block is not available
+ */
+ PredIntra4x4Mode [y][x] = ARM_VCM4P10_INVALID_BLOCK;
+ }
+ }
+
+ /* Replace ARM_VCM4P10_INVALID_BLOCK value with available MBs values*/
+ for (x = 0; x < 4; x++)
+ {
+ /* Store values of b0, b1, b2, b3 */
+ if (pMBIntra[1] != NULL)
+ {
+ PredIntra4x4Mode [0][x + 1] =
+ pMBIntra[1]->pIntra4x4PredMode[3*4 + x];
+ }
+
+ /* Store values of d0, d1, d2, d3 */
+ if (pMBIntra[3] != NULL)
+ {
+ PredIntra4x4Mode [0][x + 5] =
+ pMBIntra[3]->pIntra4x4PredMode[3*4 + x];
+ }
+ }
+
+ /* Store values of c3 */
+ if (pMBIntra[2] != NULL)
+ {
+ PredIntra4x4Mode [0][0] = pMBIntra[2]->pIntra4x4PredMode[15];
+ }
+
+ for (y = 0; y < 4; y++)
+ {
+ /* Store values of a0, a1, a2, a3 */
+ if (pMBIntra[0] != NULL)
+ {
+ PredIntra4x4Mode [y + 1][0] =
+ pMBIntra[0]->pIntra4x4PredMode[y*4 + 3];
+ }
+ }
+
+ /*
+ * Update neighbouring Pred mode array which will be used for
+ * prediction of Intra4x4 modes.
+ */
+
+ pSrcY = pSrcYBuff;
+ StepSrcY = 16 * 3;
+ for (y = 0; y < (16 * 2); y++)
+ {
+ for (x = 0; x < (16 * 3); x++)
+ {
+ pSrcY [StepSrcY * y + x] =
+ pSrcRecBuf [SrcRecStep * (y - 16) + x - 16];
+ }
+ }
+
+
+ /* for each 8x8 block */
+ for (Block8x8 = 0; Block8x8 < 4; Block8x8++)
+ {
+ /* for each 4x4 block inside 8x8 block */
+ for (Block4x4 = 0; Block4x4 < 4; Block4x4++)
+ {
+ /* Get block cordinates from 8x8 block index and 4x4 block index */
+ BlockX = ((Block8x8 & 1) << 1) + (Block4x4 & 1);
+ BlockY = ((Block8x8 >> 1) << 1) + (Block4x4 >> 1);
+
+ /* Add offset to point to start of current MB in the array pIntra4x4PredMode */
+ x = BlockX + 1;
+ y = BlockY + 1;
+
+ availability = 0;
+
+ /* Check for availability of LEFT Block */
+ if (PredIntra4x4Mode [y][x - 1] != ARM_VCM4P10_INVALID_BLOCK)
+ {
+ availability |= OMX_VC_LEFT;
+ }
+
+ /* Check for availability of UPPER Block */
+ if (PredIntra4x4Mode [y - 1][x] != ARM_VCM4P10_INVALID_BLOCK)
+ {
+ availability |= OMX_VC_UPPER;
+ }
+
+ /* Check for availability of UPPER LEFT Block */
+ if (PredIntra4x4Mode [y - 1][x - 1] != ARM_VCM4P10_INVALID_BLOCK)
+ {
+ availability |= OMX_VC_UPPER_LEFT;
+ }
+
+ PredIntra4x4Mode [y][x] = pSrcMBInfo->pIntra4x4PredMode[BlockY*4+BlockX];
+ x = BlockX * 4;
+ y = BlockY * 4;
+
+ pSrcY = pSrcYBuff + 16 * StepSrcY + 16 + y * StepSrcY + x;
+
+ omxVCM4P10_PredictIntra_4x4(
+ pSrcY - 1,
+ pSrcY - StepSrcY,
+ pSrcY - StepSrcY - 1,
+ pTempDstBuf + x + y * TempDstStep,
+ StepSrcY,
+ TempDstStep,
+ pSrcMBInfo->pIntra4x4PredMode[BlockY*4+BlockX],
+ availability);
+
+ for (BlockY=0;BlockY<4;BlockY++)
+ {
+ for(BlockX=0;BlockX<4;BlockX++)
+ {
+ pSrcY [BlockY * StepSrcY + BlockX] =
+ (OMX_U8)(*(pTempDstBuf + x + y * TempDstStep + BlockY * TempDstStep + BlockX));
+ }
+ }
+
+ }
+ }
+ break;
+ }
+ case OMX_VC_INTRA_16x16:
+ {
+ OMX_U32 MBPosX = pCurrPointPos->x >> 4;
+ OMX_U32 MBPosY = pCurrPointPos->y >> 4;
+ OMX_U32 availability = 0;
+
+ /* Check for availability of LEFT MB */
+ if ((MBPosX != 0) && (pMBIntra [0] != 0 || pMBInter [0] != 0))
+ {
+ availability |= OMX_VC_LEFT;
+ }
+
+ /* Check for availability of UP MB */
+ if ((MBPosY != 0) && (pMBIntra [1] != 0 || pMBInter [1] != 0))
+ {
+ availability |= OMX_VC_UPPER;
+ }
+
+ /* Check for availability of UP-LEFT MB */
+ if ((MBPosX > 0) && (MBPosY > 0) &&
+ (pMBIntra [2] != 0 || pMBInter [2] != 0))
+ {
+ availability |= OMX_VC_UPPER_LEFT;
+ }
+
+ omxVCM4P10_PredictIntra_16x16(
+ pSrcRecBuf - 1,
+ pSrcRecBuf - SrcRecStep,
+ pSrcRecBuf - SrcRecStep - 1,
+ pTempDstBuf,
+ SrcRecStep,
+ TempDstStep,
+ pSrcMBInfo->Intra16x16PredMode,
+ availability);
+
+ break;
+ }
+
+ case OMX_VC_INTER_SKIP:
+ case OMX_VC_PREF0_8x8:
+ case OMX_VC_INTRA_PCM:
+ default:
+ /* These cases will update pDstBlockSAD with MAX value */
+ InvalidSAD = 1;
+ break;
+ }
+
+ /* INTER MB */
+ if ((pSrcMBInfo->mbType == OMX_VC_P_16x16) ||
+ (pSrcMBInfo->mbType == OMX_VC_P_8x16) ||
+ (pSrcMBInfo->mbType == OMX_VC_P_16x8) ||
+ (pSrcMBInfo->mbType == OMX_VC_P_8x8))
+ {
+ const OMX_U8 *pTempSrcBuf;
+ OMX_S32 TempSrcStep;
+ OMX_S32 mvx,mvy;
+ OMX_U32 PartX, PartY, SubPartX, SubPartY;
+
+ TempSrcStep = SrcRefStep;
+
+ MaxXPart = 16/Width;
+ MaxYPart = 16/Height;
+
+
+ for (PartY = 0; PartY < MaxYPart; PartY++)
+ {
+ for (PartX = 0; PartX < MaxXPart; PartX++)
+ {
+
+ pTempSrcBuf = pSrcRefBufList[pSrcMBInfo->pRefL0Idx[PartY * 2 + PartX]];
+
+ if (MaxXPart == 2 && MaxYPart == 2)
+ {
+ switch (pSrcMBInfo->subMBType[PartY*2+PartX])
+ {
+ case OMX_VC_SUB_P_8x8:
+ Width = 8;
+ Height = 8;
+ break;
+ case OMX_VC_SUB_P_8x4:
+ Width = 8;
+ Height = 4;
+ break;
+ case OMX_VC_SUB_P_4x8:
+ Width = 4;
+ Height = 8;
+ break;
+ case OMX_VC_SUB_P_4x4:
+ Width = 4;
+ Height = 4;
+ break;
+ default:
+ /* Default */
+ Width = 4;
+ Height = 4;
+ break;
+ }
+
+ MaxSubXPart = 8/Width;
+ MaxSubYPart = 8/Height;
+
+ for (SubPartY = 0; SubPartY < MaxSubYPart; SubPartY++)
+ {
+ for (SubPartX = 0; SubPartX < MaxSubXPart; SubPartX++)
+ {
+ mvx = pSrcMBInfo->pMV0 [2*PartY + SubPartY][2*PartX + SubPartX].dx;
+ mvy = pSrcMBInfo->pMV0 [2*PartY + SubPartY][2*PartX + SubPartX].dy;
+ armVCM4P10_Interpolate_Luma(
+ pTempSrcBuf + (8*PartX + 4*SubPartX + (mvx/4)) + (8*PartY + 4*SubPartY + (mvy/4)) * TempSrcStep,
+ TempSrcStep,
+ pTempDstBuf + (8*PartX + 4*SubPartX) + (8*PartY + 4*SubPartY) * TempDstStep,
+ TempDstStep,
+ Width,
+ Height,
+ mvx & 3,
+ mvy & 3
+ );
+ }
+ }
+ }
+ else
+ {
+
+ mvx = pSrcMBInfo->pMV0 [2*PartY][2*PartX].dx;
+ mvy = pSrcMBInfo->pMV0 [2*PartY][2*PartX].dy;
+ armVCM4P10_Interpolate_Luma(
+ pTempSrcBuf + (8*PartX + (mvx/4)) + (8*PartY + (mvy/4)) * TempSrcStep,
+ TempSrcStep,
+ pTempDstBuf + (8*PartX) + (8*PartY) * TempDstStep,
+ TempDstStep,
+ Width,
+ Height,
+ mvx & 3,
+ mvy & 3
+ );
+
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ InvalidSAD = 1;
+ }
+
+ /* Calculate SAD from predicted buffer */
+ if (!InvalidSAD)
+ {
+ OMX_U32 x8x8, y8x8, x4x4, y4x4, Block8x8, Block4x4;
+ OMX_S32 SAD;
+
+ pTempRefBuf = pTempDstBuf;
+ TempRefStep = 16;
+
+ /* SAD for each 4x4 block in scan order */
+ for (Block8x8 = 0; Block8x8 < 4; Block8x8++)
+ {
+ x8x8 = 8*(Block8x8 & 1);
+ y8x8 = 8*(Block8x8 >> 1);
+ for (Block4x4 = 0; Block4x4 < 4; Block4x4++)
+ {
+ x4x4 = 4*(Block4x4 & 1);
+ y4x4 = 4*(Block4x4 >> 1);
+
+ armVCCOMM_SAD(
+ pSrcCurrBuf + (x8x8 + x4x4) + (y8x8 + y4x4) * SrcCurrStep,
+ SrcCurrStep,
+ pTempRefBuf + (x8x8 + x4x4) + (y8x8 + y4x4) * TempRefStep,
+ TempRefStep,
+ &SAD,
+ 4, /* Height */
+ 4); /* Width */
+ *(pDstBlockSAD + 4 * Block8x8 + Block4x4) = (SAD < 0x7fff) ? (OMX_U16) SAD : ARM_VCM4P10_MAX_MODE_VALUE;
+ }
+ }
+ }
+ else
+ {
+ /* Fill SADs with max values and return*/
+ for (i = 0; i < 16; i++)
+ {
+ pDstBlockSAD [i] = ARM_VCM4P10_MAX_4x4_SAD;
+ }
+ }
+ return OMX_Sts_NoErr;
+}
+
+
+
+/**
+ * Function: armVCM4P10_Mode4x4Decision
+ *
+ * Description:
+ * Intra 4x4 Mode decision by calculating cost for all possible modes and
+ * choosing the best mode
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] pSrcCurrBuf - Pointer to the start of current Macroblock
+ * [in] SrcCurrStep - Step size of the pointer pSrcCurrBuf
+ * [in/out] pSrcDstMBCurr - Pointer to the OMXVCM4P10MBInfo which will be updated for
+ * field pIntra4x4PredMode of the current block.
+ * [in] Block8x8 - Index 8x8 block in which current 4x4 block belongs
+ * [in] Block4x4 - Index of current 4x4 block
+ * [in/out] pPredIntra4x4SrcY - Pointer to current block location in buffer
+ * with reconstructed values. This will be modified by this
+ * function with best mode predicted values
+ * [in] StepPredIntra4x4SrcY - Step size of the pointer pPredIntra4x4SrcY
+ * [in] pIntra4x4PredMode - Array of Intra 4x4 prediction mode for the MB.
+ * Current MB modes starts at [1,1].
+ * [in] pBestCost - Cost for the Best Intra 4x4 mode
+ * Return Value:
+ * None
+ *
+ */
+static OMXVoid armVCM4P10_Mode4x4Decision (
+ const OMX_U8* pSrcCurrBuf,
+ OMX_S32 SrcCurrStep,
+ OMXVCM4P10MBInfo *pSrcDstMBCurr,
+ OMX_S32 Block8x8,
+ OMX_S32 Block4x4,
+ OMX_U8 *pPredIntra4x4SrcY,
+ OMX_S32 StepPredIntra4x4SrcY,
+ OMX_S32 pIntra4x4PredMode [][9],
+ OMX_S32 *pBestCost
+)
+{
+ OMX_S32 i, j, x, y, BlockX, BlockY, mode;
+ OMX_S32 Cost, BestCost;
+ OMX_U8 *pSrcY;
+ OMX_S32 StepSrcY;
+ OMX_S32 availability = 0;
+ OMX_U8 pPredBlock [4*4];
+ OMXResult Ret = OMX_Sts_Err;
+
+ /* Get block cordinates from 8x8 block index and 4x4 block index */
+ BlockX = ((Block8x8 & 1) << 1) + (Block4x4 & 1);
+ BlockY = ((Block8x8 >> 1) << 1) + (Block4x4 >> 1);
+
+ /* Add offset to point to start of current MB in the array pIntra4x4PredMode */
+ x = BlockX + 1;
+ y = BlockY + 1;
+
+ /* Check for availability of LEFT Block */
+ if (pIntra4x4PredMode [y][x - 1] != ARM_VCM4P10_INVALID_BLOCK)
+ {
+ availability |= OMX_VC_LEFT;
+ }
+
+ /* Check for availability of UPPER Block */
+ if (pIntra4x4PredMode [y - 1][x] != ARM_VCM4P10_INVALID_BLOCK)
+ {
+ availability |= OMX_VC_UPPER;
+ }
+
+ /* Check for availability of UPPER LEFT Block */
+ if (pIntra4x4PredMode [y - 1][x - 1] != ARM_VCM4P10_INVALID_BLOCK)
+ {
+ availability |= OMX_VC_UPPER_LEFT;
+ }
+
+ pSrcY = pPredIntra4x4SrcY +
+ StepPredIntra4x4SrcY * (BlockY << 2) +
+ (BlockX << 2);
+
+ StepSrcY = StepPredIntra4x4SrcY;
+
+ x = BlockX * 4;
+ y = BlockY * 4;
+
+ Cost = BestCost = ARM_VCM4P10_MAX_COST;
+
+ /* Go through each mode for minim cost */
+ for (mode = 0; mode < 9; mode++)
+ {
+ Ret = omxVCM4P10_PredictIntra_4x4(
+ pSrcY - 1,
+ pSrcY - StepSrcY,
+ pSrcY - StepSrcY - 1,
+ pPredBlock,
+ StepSrcY,
+ 4,
+ (OMXVCM4P10Intra4x4PredMode) mode,
+ availability);
+
+ if (Ret == OMX_Sts_NoErr)
+ {
+ armVCCOMM_SAD(
+ pSrcCurrBuf + (y * SrcCurrStep) + x,
+ SrcCurrStep,
+ pPredBlock,
+ 4,
+ &Cost,
+ 4,
+ 4);
+
+ if (Cost < BestCost)
+ {
+ BestCost = Cost;
+
+ pIntra4x4PredMode [BlockY + 1][BlockX + 1] =
+ (OMXVCM4P10Intra4x4PredMode) mode;
+ pSrcDstMBCurr->pIntra4x4PredMode [BlockY * 4 + BlockX] =
+ (OMXVCM4P10Intra4x4PredMode) mode;
+
+ for (j = 0; j < 4; j++)
+ {
+ for (i = 0; i < 4; i++)
+ {
+ pSrcY [StepSrcY * j + i] = pPredBlock [4 * j + i];
+ }
+ }
+ }
+ }
+ }
+
+ *pBestCost = BestCost;
+ return;
+}
+
+/**
+ * Function: armVCM4P10_SetMotionVectorPredictor
+ *
+ * Description:
+ * This function will do the MV Prediction for Inter MBs
+ *
+ * Parameters:
+ * [in] BlockStartX - Start X index in integer pels in current Block
+ * [in] BlockStartY - Start Y index in integer pels in current Block
+ * [in] BlockSizeX - Width of current block
+ * [in] BlockSizeY - Height of current block
+ * [in] RefFrame - Index of the reference frame for prediction
+ * [in] pRefFrArr - Pointer to Ref array storing neighbouring MVs for MV prediction
+ * [in] pMVArr - Pointer to MV array storing neighbouring MVs for MV prediction
+ * [out] pMVPred - Pointer to predicted MVs
+ * Remarks:
+ *
+ * Return Value:
+ * None
+ *
+ */
+static OMXVoid armVCM4P10_SetMotionVectorPredictor(
+ OMX_U32 BlockStartX,
+ OMX_U32 BlockStartY,
+ OMX_U32 BlockSizex,
+ OMX_U32 BlockSizey,
+ OMX_S32 RefFrame,
+ OMX_S32 pRefFrArr[][6],
+ OMXVCMotionVector pMVArr[][12],
+ OMXVCMotionVector *pMVPred
+)
+{
+ OMX_S32 RFrameL; /* Left */
+ OMX_S32 RFrameU; /* Up */
+ OMX_S32 RFrameUR; /* Up-Right */
+
+ OMX_S32 BlockX, BlockY, BlockXFr, BlockYFr, MVPredType;
+ OMX_S32 BlockXPlusOff, BlockXPlusOffFr, BlockXMin1Fr, BlockYMin1Fr;
+
+ BlockX = 4 + (BlockStartX >> 2);
+ BlockY = 4 + (BlockStartY >> 2);
+ BlockXPlusOff = BlockX + (BlockSizex >> 2);
+
+ BlockXFr = BlockX >> 1;
+ BlockYFr = BlockY >> 1;
+ BlockXMin1Fr = (BlockX - 1) >> 1;
+ BlockYMin1Fr = (BlockY - 1) >> 1;
+ BlockXPlusOffFr = BlockXPlusOff >> 1;
+
+ MVPredType = ARM_VCM4P10_MVPRED_MEDIAN;
+
+ RFrameL = pRefFrArr [BlockYFr][BlockXMin1Fr];
+ RFrameU = pRefFrArr [BlockYMin1Fr][BlockXFr];
+ RFrameUR = pRefFrArr [BlockYMin1Fr][BlockXPlusOffFr];
+
+ if (RFrameUR == ARM_VCM4P10_INVALID_BLOCK)
+ {
+ RFrameUR = pRefFrArr [BlockYMin1Fr][BlockXMin1Fr];
+ }
+
+ /*
+ * Prediction if only one of the neighbors uses the reference frame
+ * we are checking
+ */
+
+ if (RFrameL == RefFrame && RFrameU != RefFrame && RFrameUR != RefFrame)
+ {
+ MVPredType = ARM_VCM4P10_MVPRED_L;
+ }
+ else if(RFrameL != RefFrame && RFrameU == RefFrame && RFrameUR != RefFrame)
+ {
+ MVPredType = ARM_VCM4P10_MVPRED_U;
+ }
+ else if(RFrameL != RefFrame && RFrameU != RefFrame && RFrameUR == RefFrame)
+ {
+ MVPredType = ARM_VCM4P10_MVPRED_UR;
+ }
+
+ /* Directional predictions */
+ else if(BlockSizex == 8 && BlockSizey == 16)
+ {
+ if(BlockStartX == 0)
+ {
+ if(RFrameL == RefFrame)
+ {
+ MVPredType = ARM_VCM4P10_MVPRED_L;
+ }
+ }
+ else
+ {
+ if (RFrameUR == RefFrame)
+ {
+ MVPredType = ARM_VCM4P10_MVPRED_UR;
+ }
+ }
+ }
+ else if(BlockSizex == 16 && BlockSizey == 8)
+ {
+ if(BlockStartY == 0)
+ {
+ if(RFrameU == RefFrame)
+ {
+ MVPredType = ARM_VCM4P10_MVPRED_U;
+ }
+ }
+ else
+ {
+ if(RFrameL == RefFrame)
+ {
+ MVPredType = ARM_VCM4P10_MVPRED_L;
+ }
+ }
+ }
+
+ switch (MVPredType)
+ {
+ case ARM_VCM4P10_MVPRED_MEDIAN:
+ if (!(pRefFrArr [BlockYMin1Fr][BlockXMin1Fr] == ARM_VCM4P10_INVALID_BLOCK ||
+ pRefFrArr [BlockYMin1Fr][BlockXFr] == ARM_VCM4P10_INVALID_BLOCK ||
+ pRefFrArr [BlockYMin1Fr][BlockXPlusOffFr] == ARM_VCM4P10_INVALID_BLOCK))
+ {
+ pMVPred->dx = pMVArr [BlockY][BlockX - 1].dx;
+ pMVPred->dy = pMVArr [BlockY][BlockX - 1].dy;
+ }
+ else
+ {
+ pMVPred->dx =
+ ARM_VCM4P10_MEDIAN(pMVArr [BlockY][BlockX - 1].dx,
+ pMVArr [BlockY - 1][BlockX].dx,
+ pMVArr [BlockY - 1][BlockXPlusOff].dx);
+ pMVPred->dy =
+ ARM_VCM4P10_MEDIAN(pMVArr [BlockY][BlockX - 1].dy,
+ pMVArr [BlockY - 1][BlockX].dy,
+ pMVArr [BlockY - 1][BlockXPlusOff].dy);
+ }
+ break;
+
+ case ARM_VCM4P10_MVPRED_L:
+ pMVPred->dx = pMVArr [BlockY][BlockX - 1].dx;
+ pMVPred->dy = pMVArr [BlockY][BlockX - 1].dy;
+ break;
+ case ARM_VCM4P10_MVPRED_U:
+ pMVPred->dx = pMVArr [BlockY - 1][BlockX].dx;
+ pMVPred->dy = pMVArr [BlockY - 1][BlockX].dy;
+ break;
+ case ARM_VCM4P10_MVPRED_UR:
+ if (pRefFrArr [BlockYMin1Fr][BlockXPlusOffFr] != ARM_VCM4P10_INVALID_BLOCK)
+ {
+ pMVPred->dx = pMVArr [BlockY - 1][BlockXPlusOff].dx;
+ pMVPred->dy = pMVArr [BlockY - 1][BlockXPlusOff].dy;
+ }
+ else
+ {
+ pMVPred->dx = pMVArr [BlockY - 1][BlockX - 1].dx;
+ pMVPred->dy = pMVArr [BlockY - 1][BlockX - 1].dy;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return;
+}
+
+/**
+ * Function: armVCM4P10_BlockMotionSearch
+ *
+ * Description:
+ * Gets best MV for the current block
+ *
+ * Parameters:
+ * [in] pSrcCurrBuf - Pointer to the start of luma component of current Macroblock
+ * [in] SrcCurrStep - Step size for the pointer pSrcCurrBuf
+ * [in] pSrcRefY - Pointer to the start of luma component of co-located reference MB
+ * [in] nSrcRefStep - Step size for the pointer pSrcRefY
+ * [in] pRefRect Pointer to the valid reference rectangle; relative to the image origin.
+ * [in] pCurrPointPos Position of the current macroblock in the current plane.
+ * [in] pMESpec - Motion estimation structure
+ * [in] pMBInter - Array, of dimension four, containing pointers to information associated with four
+ * adjacent type INTER MBs (Left, Top, Top-Left, Top-Right).
+ * [in] nLamda - For calculating the cost
+ * [out] pBestCost - Minimum cost for encoding current block
+ * [out] pBestMV - MV corresponding to best cost
+ * [in] BlockStartX - Block start X index in integer pels
+ * [in] BlockStartY - Block start Y index in integer pels
+ * [in] BlockSizeX - Width of current block
+ * [in] BlockSizeY - Height of current block
+ * [in] RefFrame - Index of the reference frame for prediction
+ * [in] pRefFrArr - Pointer to reference frame array storing neighbouring MVs for prediction
+ * [in] pMVArr - Pointer to MV array storing neighbouring MVs for MV prediction
+ * [in] pMVPred - Pointer to MV predicted from neighbour MVs
+ * Remarks:
+ *
+ * Return Value:
+ * OMXResult
+ *
+ */
+static OMXResult armVCM4P10_BlockMotionSearch(
+ const OMX_U8* pSrcCurrBuf,
+ OMX_S32 SrcCurrStep,
+ const OMX_U8* pSrcRefY,
+ OMX_S32 nSrcRefStep,
+ const OMXRect *pRefRect,
+ const OMXVCM4P2Coordinate *pCurrPointPos,
+ void* pMESpec,
+
+ OMX_S32 nLamda,
+ OMX_S32* pBestCost,
+ OMXVCMotionVector *pBestMV,
+
+ OMX_U32 BlockStartX,
+ OMX_U32 BlockStartY,
+ OMX_U32 BlockSizeX,
+ OMX_U32 BlockSizeY,
+ OMX_S32 RefFrame,
+ OMX_S32 pRefFrArr [][6],
+ OMXVCMotionVector pMVArr [][12],
+ OMXVCMotionVector *pMVPred
+ )
+{
+
+ OMXVCMotionVector MVCalculated, MVCandidate;
+ OMX_S32 Cost;
+ OMXResult RetValue;
+ OMXVCM4P10MEParams *pMEParams;
+ OMXVCM4P2Coordinate CurrBlockPos;
+
+ /* Get Predicted Motion Vectors */
+ armVCM4P10_SetMotionVectorPredictor (
+ BlockStartX,
+ BlockStartY,
+ BlockSizeX,
+ BlockSizeY,
+ RefFrame,
+ pRefFrArr,
+ pMVArr,
+ pMVPred);
+
+ /* Initialize candidate MV */
+ MVCandidate.dx = 0;
+ MVCandidate.dy = 0;
+
+ CurrBlockPos.x = pCurrPointPos->x + BlockStartX;
+ CurrBlockPos.y = pCurrPointPos->y + BlockStartY;
+
+ /* Block Match Integer */
+ RetValue = omxVCM4P10_BlockMatch_Integer (
+ pSrcCurrBuf,
+ SrcCurrStep,
+ pSrcRefY,
+ nSrcRefStep,
+ pRefRect,
+ &CurrBlockPos,
+ BlockSizeX,
+ BlockSizeY,
+ nLamda,
+ pMVPred,
+ &MVCandidate,
+ &MVCalculated,
+ &Cost,
+ pMESpec);
+
+ /* updated BestMV*/
+ /**pBestCost = Cost;
+ pBestMV->dx = MVCalculated.dx;
+ pBestMV->dy = MVCalculated.dy;*/
+
+ pMEParams = (OMXVCM4P10MEParams *) pMESpec;
+
+ /* Block Match Half pel */
+ if (pMEParams->halfSearchEnable)
+ {
+ RetValue = omxVCM4P10_BlockMatch_Half(
+ pSrcCurrBuf,
+ SrcCurrStep,
+ pSrcRefY,
+ nSrcRefStep,
+ BlockSizeX,
+ BlockSizeY,
+ nLamda,
+ pMVPred,
+ &MVCalculated, /* input/output*/
+ &Cost);
+ }
+
+ /* Block Match Quarter pel */
+ if (pMEParams->quarterSearchEnable)
+ {
+ RetValue = omxVCM4P10_BlockMatch_Quarter(
+ pSrcCurrBuf,
+ SrcCurrStep,
+ pSrcRefY,
+ nSrcRefStep,
+ BlockSizeX,
+ BlockSizeY,
+ nLamda,
+ pMVPred,
+ &MVCalculated,
+ &Cost);
+ }
+
+ /* updated Best Cost and Best MV */
+ *pBestCost = Cost;
+ pBestMV->dx = MVCalculated.dx;
+ pBestMV->dy = MVCalculated.dy;
+
+ /*
+ * Skip MB cost calculations of 16x16 inter mode
+ */
+ return RetValue;
+}
+
+/**
+ * Function: armVCM4P10_PartitionME
+ *
+ * Description:
+ * Gets best cost for the current partition
+ *
+ * Parameters:
+ * [in] pSrcCurrBuf - Pointer to the start of luma component of current Macroblock
+ * [in] SrcCurrStep - Step size for the pointer pSrcCurrBuf
+ * [in] pSrcRefBufList - Pointer to List of ref buffer of co-located reference MB
+ * [in] nSrcRefStep - Step size for the pointer pSrcRefY
+ * [in] pRefRect Pointer to the valid reference rectangle; relative to the image origin.
+ * [in] pCurrPointPos Position of the current macroblock in the current plane.
+ * [in] pMESpec - Motion estimation structure
+ * [in] PartWidth - Width of current partition
+ * [in] PartHeight - Height of current partition
+ * [in] BlockWidth - Width of current block
+ * [in] BlockHeight - Height of current block
+ * [in] PartStartX - Partition start X index in integer pels
+ * [in] PartStartY - Partition start Y index in integer pels
+ * [in] pMVArr - Pointer to MV array storing neighbouring MVs for MV prediction
+ * [in] pRefFrArr - Pointer to reference frame array storing neighbouring MVs for prediction
+ * [in] Lambda - For calculating the cost
+ * [out] pCost - Pointer to cost for Inter MB
+ *
+ * Return Value:
+ * OMXResult
+ *
+ */
+static OMXResult armVCM4P10_PartitionME (
+ const OMX_U8* pSrcCurrBuf,
+ OMX_S32 SrcCurrStep,
+ const OMX_U8 *pSrcRefBufList[ARM_VCM4P10_MAX_FRAMES],
+ OMX_S32 SrcRefStep,
+ const OMXRect *pRefRect,
+ const OMXVCM4P2Coordinate *pCurrPointPos,
+ void* pMESpec,
+
+ OMX_S32 PartWidth,
+ OMX_S32 PartHeight,
+ OMX_S32 BlockWidth,
+ OMX_S32 BlockHeight,
+ OMX_S32 PartStartX,
+ OMX_S32 PartStartY,
+
+ OMXVCMotionVector pMVArr [][12],
+ OMX_S32 pRefFrArr [][6],
+ OMXVCMotionVector pMVPredArr [][4],
+
+ OMX_S32 Lambda,
+ OMX_S32 *pCost
+)
+{
+ OMX_U32 x, y, i, j, ref, OffX, OffY, OffSrc, OffRef;
+ OMX_S32 BlockCost, PartitionCost, BestCost;
+ OMX_S32 BestRefFrame=0;
+ OMXVCMotionVector BestMV [4][4];
+ OMXVCMotionVector BestMVPred [4][4];
+ OMXVCMotionVector MVPred;
+ OMXVCMotionVector DstMV;
+
+ BestCost = ARM_VCM4P10_MAX_COST;
+
+ for (ref = 0; ref < ARM_VCM4P10_MAX_FRAMES; ref++)
+ {
+ if (pSrcRefBufList [ref] == NULL)
+ {
+ /* No reference frame, continue */
+ continue;
+ }
+
+ PartitionCost = 0;
+
+ for (y = 0; y < PartHeight; y += BlockHeight)
+ {
+ for (x = 0; x < PartWidth; x += BlockWidth)
+ {
+ OffSrc = SrcCurrStep * (PartStartY + y) + PartStartX + x;
+ OffRef = SrcRefStep * (PartStartY + y) + PartStartX + x;
+ armVCM4P10_BlockMotionSearch (
+ pSrcCurrBuf + OffSrc,
+ SrcCurrStep,
+ pSrcRefBufList [ref] + OffRef,
+ SrcRefStep,
+ pRefRect,
+ pCurrPointPos,
+ pMESpec,
+
+ Lambda,
+ &BlockCost,
+ &DstMV,
+
+ x + PartStartX,
+ y + PartStartY,
+ BlockWidth,
+ BlockHeight,
+ ref,
+ pRefFrArr,
+ pMVArr,
+ &MVPred);
+
+ PartitionCost += BlockCost;
+
+ OffX = (PartStartX + x) >> 2;
+ OffY = (PartStartY + y) >> 2;
+
+ for (j = 0; j < (BlockHeight >> 2); j++)
+ {
+ for (i = 0; i < (BlockWidth >> 2); i++)
+ {
+ pMVArr [4 + OffY + j][4 + OffX + i].dx = DstMV.dx;
+ pMVArr [4 + OffY + j][4 + OffX + i].dy = DstMV.dy;
+ pMVPredArr [OffY + j][OffX + i].dx = MVPred.dx;
+ pMVPredArr [OffY + j][OffX + i].dy = MVPred.dy;
+ }
+ }
+
+ pRefFrArr [2 + (OffY >> 1)][2 + (OffX >> 1)] = ref;
+ for (j = 0; j < (BlockHeight >> 3); j++)
+ {
+ for (i = 0; i < (BlockWidth >> 3); i++)
+ {
+ pRefFrArr [2 + (OffY >> 1) + j][2 + (OffX >> 1) + i] = ref;
+ }
+ }
+
+ }
+ }
+
+ /*
+ * If PartitionCost is less for this reference frame, motion vectors needs to be backedup
+ */
+ if (PartitionCost <= BestCost)
+ {
+ BestCost = PartitionCost;
+ BestRefFrame = ref;
+
+ for (y = 0; y < (PartHeight/BlockHeight); y++)
+ {
+ for (x = 0; x < (PartWidth/BlockWidth); x++)
+ {
+ OffX = (PartStartX + x * BlockWidth) >> 2;
+ OffY = (PartStartY + y * BlockHeight) >> 2;
+
+ BestMV[y][x].dx = pMVArr [4 + OffY][4 + OffX].dx;
+ BestMV[y][x].dy = pMVArr [4 + OffY][4 + OffX].dy;
+ BestMVPred[y][x].dx = pMVPredArr [OffY][OffX].dx;
+ BestMVPred[y][x].dy = pMVPredArr [OffY][OffX].dy;
+ }
+ }
+ }
+
+ }
+
+ /*
+ * Copy back best reference frame, motion vectors and cost.
+ */
+ for (y = 0; y < (PartHeight/BlockHeight); y++)
+ {
+ for (x = 0; x < (PartWidth/BlockWidth); x++)
+ {
+ OffX = (PartStartX + x * BlockWidth) >> 2;
+ OffY = (PartStartY + y * BlockHeight) >> 2;
+
+ for (j = 0; j < (BlockHeight >> 2); j++)
+ {
+ for (i = 0; i < (BlockWidth >> 2); i++)
+ {
+ pMVArr [4 + OffY + j][4 + OffX + i].dx = BestMV[y][x].dx;
+ pMVArr [4 + OffY + j][4 + OffX + i].dy = BestMV[y][x].dy;
+ pMVPredArr [OffY + j][OffX + i].dx = BestMVPred[y][x].dx;
+ pMVPredArr [OffY + j][OffX + i].dy = BestMVPred[y][x].dy;
+ }
+ }
+
+ for (j = 0; j < (BlockHeight >> 3); j++)
+ {
+ for (i = 0; i < (BlockWidth >> 3); i++)
+ {
+ pRefFrArr [2 + (OffY >> 1) + j][2 + (OffX >> 1) + i] = BestRefFrame;
+ }
+ }
+ }
+ }
+
+ *pCost = BestCost;
+ return OMX_Sts_NoErr;
+
+}
+
+/**
+ * Function: armVCM4P10_Intra16x16Estimation
+ *
+ * Description:
+ * Performs MB-level motion estimation for INTER MB type and selects best motion estimation strategy from
+ * the set of modes supported in baseline profile ISO/IEC 14496-10.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] pSrcCurrBuf - Pointer to the start of luma component of current Macroblock
+ * [in] SrcCurrStep - Step size for the pointer pSrcCurrBuf
+ * [in] pSrcRecBuf - Pointer to the start of luma component of co-located reconstructed MB
+ * [in] SrcRecStep - Step size for the pointer pSrcRecBuf
+ * [in] nMBPosX - Position of MB in the frame w.r.t X axis
+ * [in] nMBPosY - Position of MB in the frame w.r.t Y axis
+ * [in] pMBInter - Array, of dimension four, containing pointers to information associated with four
+ * adjacent type INTER MBs (Left, Top, Top-Left, Top-Right).
+ * [in] pMBIntra - Array, of dimension four, containing pointers to information associated with four
+ * adjacent type INTRA MBs (Left, Top, Top-Left, Top-Right).
+ * [in/out] pSrcDstMBCurr - Pointer to information structure for the current MB. Following member should be set
+ * before calling this function
+ * [in] Lambda - For calculating the cost
+ * [out] pCost - Pointer to cost for Intra16x16
+ * Return Value:
+ * OMX_Sts_NoErr - No Error
+ * OMX_Sts_BadArgErr - Bad arguments:
+ *
+ */
+
+static OMXResult armVCM4P10_Intra16x16Estimation(
+ const OMX_U8* pSrcCurrBuf,
+ OMX_S32 SrcCurrStep,
+ const OMX_U8* pSrcRecBuf,
+ OMX_S32 SrcRecStep,
+ const OMXVCM4P2Coordinate *pCurrPointPos,
+ const OMXVCM4P10MBInfoPtr *pMBInter,
+ const OMXVCM4P10MBInfoPtr *pMBIntra,
+ OMXVCM4P10MBInfo *pSrcDstMBCurr,
+ OMX_U32 *pCost)
+{
+ OMX_U8 PredBuf [16*16 + 16];
+ OMX_U8 *pPred;
+ OMX_S32 mode;
+ OMX_S32 Cost;
+ OMX_S32 availability = 0;
+ OMXResult Ret;
+ OMXVCM4P10Intra16x16PredMode IntraMode16x16 [4] =
+ {OMX_VC_16X16_VERT, OMX_VC_16X16_HOR,
+ OMX_VC_16X16_DC, OMX_VC_16X16_PLANE};
+ OMX_U32 MBPosX = pCurrPointPos->x >> 4;
+ OMX_U32 MBPosY = pCurrPointPos->y >> 4;
+
+ pPred = armAlignTo16Bytes(PredBuf);
+
+ /* Check for availability of LEFT MB */
+ if ((MBPosX != 0) && (pMBIntra [0] != 0 || pMBInter [0] != 0))
+ {
+ availability |= OMX_VC_LEFT;
+ }
+
+ /* Check for availability of UP MB */
+ if ((MBPosY != 0) && (pMBIntra [1] != 0 || pMBInter [1] != 0))
+ {
+ availability |= OMX_VC_UPPER;
+ }
+
+ /* Check for availability of UP-LEFT MB */
+ if ((MBPosX > 0) && (MBPosY > 0) &&
+ (pMBIntra [2] != 0 || pMBInter [2] != 0))
+ {
+ availability |= OMX_VC_UPPER_LEFT;
+ }
+
+ *pCost = ARM_VCM4P10_MAX_COST;
+ for (mode = 0; mode < 4; mode++)
+ {
+ Ret = omxVCM4P10_PredictIntra_16x16(
+ pSrcRecBuf - 1,
+ pSrcRecBuf - SrcRecStep,
+ pSrcRecBuf - SrcRecStep - 1,
+ pPred,
+ SrcRecStep,
+ 16,
+ IntraMode16x16 [mode],
+ availability);
+ if (Ret == OMX_Sts_NoErr)
+ {
+ armVCCOMM_SAD(
+ pSrcCurrBuf,
+ SrcCurrStep,
+ pPred,
+ 16,
+ &Cost,
+ 16,
+ 16);
+ if (Cost < *pCost)
+ {
+ *pCost = Cost;
+ pSrcDstMBCurr->Intra16x16PredMode = IntraMode16x16 [mode];
+ }
+
+ }
+
+ }
+
+ return OMX_Sts_NoErr;
+}
+
+/**
+ * Function: armVCM4P10_Intra4x4Estimation
+ *
+ * Description:
+ * Performs MB-level motion estimation for Intra 4x4 MB type and selects
+ * the best set of modes supported in baseline profile.
+ *
+ * Parameters:
+ * [in] pSrcCurrBuf - Pointer to the start of luma component of current Macroblock
+ * [in] SrcCurrStep - Step size for the pointer pSrcCurrBuf
+ * [in] pSrcRecBuf - Pointer to the start of luma component of co-located reconstructed MB
+ * [in] SrcRecStep - Step size for the pointer pSrcRecBuf
+ * [in] nMBPosX - Position of MB in the frame w.r.t X axis
+ * [in] nMBPosY - Position of MB in the frame w.r.t Y axis
+ * [in] pMBIntra - Array, of dimension four, containing pointers to information associated with four
+ * adjacent type INTRA MBs (Left, Top, Top-Left, Top-Right).
+ * [in/out] pSrcDstMBCurr - Pointer to information structure for the current MB. Following member should be set
+ * before calling this function
+ * [in] Lambda - For calculating the cost
+ * [out] pCost - Pointer to cost for Intra4x4
+ * Return Value:
+ * OMX_Sts_NoErr - No Error
+ * OMX_Sts_BadArgErr - Bad arguments:
+ *
+ */
+
+static OMXResult armVCM4P10_Intra4x4Estimation(
+ const OMX_U8* pSrcCurrBuf,
+ OMX_S32 SrcCurrStep,
+ const OMX_U8* pSrcRecBuf,
+ OMX_S32 SrcRecStep,
+ const OMXVCM4P10MBInfoPtr *pMBIntra,
+ OMXVCM4P10MBInfo *pSrcDstMBCurr,
+ OMX_U32 *pCost)
+{
+ OMX_S32 x, y, Block4x4, Block8x8;
+ OMX_S32 Cost;
+
+ /*
+ * PredIntra4x4Mode will store prediction modes of 4x4 blocks.
+ * Modes for current MB starts at index [1][1].
+ * Modes of nighbouring MB's will be as shown below
+ * A value of ARM_VCM4P10_INVALID_BLOCK for any block in this array means
+ * that block is not available for prediction.
+ *
+ * c3 b0 b1 b2 b3 d0 d1 d2 d3
+ * a0 xx xx xx xx - - - -
+ * a1 xx xx xx xx - - - -
+ * a2 xx xx xx xx - - - -
+ * a3 xx xx xx xx - - - -
+ *
+ */
+ OMX_S32 PredIntra4x4Mode [5][9];
+
+ /*
+ * pSrcY stores re-construsted source array of size 3MB X 2MB as below
+ *
+ * MB11 MB12 MB13
+ * MB21 MB22 MB23
+ *
+ * This array will be used for local reconstruction of 4x4 blocks
+ * with best prediction mode within an MB
+ */
+ OMX_U8 pSrcY [(16*3)*(16*2)];
+ OMX_S32 StepSrcY;
+
+ /* init */
+ *pCost = 0;
+
+ for (y = 0; y < 5; y++)
+ {
+ for (x = 0; x < 9; x++)
+ {
+ /*
+ * Initialize with value of ARM_VCM4P10_INVALID_BLOCK, to mean this
+ * 4x4 block is not available
+ */
+ PredIntra4x4Mode [y][x] = ARM_VCM4P10_INVALID_BLOCK;
+ }
+ }
+
+ /* Replace ARM_VCM4P10_INVALID_BLOCK value with available MBs values*/
+ for (x = 0; x < 4; x++)
+ {
+ /* Store values of b0, b1, b2, b3 */
+ if (pMBIntra[1] != NULL)
+ {
+ PredIntra4x4Mode [0][x + 1] =
+ pMBIntra[1]->pIntra4x4PredMode[3*4 + x];
+ }
+
+ /* Store values of d0, d1, d2, d3 */
+ if (pMBIntra[3] != NULL)
+ {
+ PredIntra4x4Mode [0][x + 5] =
+ pMBIntra[3]->pIntra4x4PredMode[3*4 + x];
+ }
+ }
+
+ /* Store values of c3 */
+ if (pMBIntra[2] != NULL)
+ {
+ PredIntra4x4Mode [0][0] = pMBIntra[2]->pIntra4x4PredMode[15];
+ }
+
+ for (y = 0; y < 4; y++)
+ {
+ /* Store values of a0, a1, a2, a3 */
+ if (pMBIntra[0] != NULL)
+ {
+ PredIntra4x4Mode [y + 1][0] =
+ pMBIntra[0]->pIntra4x4PredMode[y*4 + 3];
+ }
+ }
+
+ /*
+ * Update neighbouring Pred mode array which will be used for
+ * prediction of Intra4x4 modes.
+ */
+
+ StepSrcY = 16 * 3;
+ for (y = 0; y < (16 * 2); y++)
+ {
+ for (x = 0; x < (16 * 3); x++)
+ {
+ pSrcY [StepSrcY * y + x] =
+ pSrcRecBuf [SrcRecStep * (y - 16) + x - 16];
+ }
+ }
+
+ /* for each 8x8 block */
+ for (Block8x8 = 0; Block8x8 < 4; Block8x8++)
+ {
+ /* for each 4x4 block inside 8x8 block */
+ for (Block4x4 = 0; Block4x4 < 4; Block4x4++)
+ {
+ armVCM4P10_Mode4x4Decision (
+ pSrcCurrBuf,
+ SrcCurrStep,
+ pSrcDstMBCurr,
+ Block8x8,
+ Block4x4,
+ pSrcY + 16 * StepSrcY + 16,
+ StepSrcY,
+ PredIntra4x4Mode,
+ &Cost);
+
+ *pCost += Cost;
+ }
+ }
+ return OMX_Sts_NoErr;
+}
+
+/**
+ * Function: armVCM4P10_InterMEMB
+ *
+ * Description:
+ * Performs MB-level motion estimation for INTER MB type and selects best motion estimation strategy from
+ * the set of modes supported in baseline profile ISO/IEC 14496-10.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] pSrcCurrBuf - Pointer to the start of luma component of current Macroblock
+ * [in] SrcCurrStep - Step size for the pointer pSrcCurrBuf
+ * [in] pSrcRefBufList - Pointer to the start of luma component of co-located reference MB
+ * [in] SrcRefStep - Step size for the pointer pSrcRefY
+ * [in] pRefRect Pointer to the valid reference rectangle; relative to the image origin.
+ * [in] pCurrPointPos Position of the current macroblock in the current plane.
+ * [in] pMESpec - Motion estimation structure
+ * [in] pMBInter - Array, of dimension four, containing pointers to information associated with four
+ * adjacent type INTER MBs (Left, Top, Top-Left, Top-Right).
+ * [in/out] pSrcDstMBCurr - Pointer to information structure for the current MB. Following member should be set
+ * before calling this function
+ * [in] Lambda - For calculating the cost
+ * [out] pDstCost - Pointer to cost for Inter MB
+ * Return Value:
+ * OMX_Sts_NoErr - No Error
+ * OMX_Sts_BadArgErr - Bad arguments:
+ *
+ */
+
+static OMXResult armVCM4P10_InterMEMB(
+ const OMX_U8 *pSrcCurrBuf,
+ OMX_S32 SrcCurrStep,
+ const OMX_U8 *pSrcRefBufList[ARM_VCM4P10_MAX_FRAMES],
+ OMX_S32 SrcRefStep,
+ const OMXRect *pRefRect,
+ const OMXVCM4P2Coordinate *pCurrPointPos,
+ OMX_U32 Lambda,
+ void *pMESpec,
+ const OMXVCM4P10MBInfoPtr *pMBInter,
+ OMXVCM4P10MBInfoPtr pSrcDstMBCurr,
+ OMX_U32 *pDstCost)
+{
+ OMX_S32 i, j, x, y, mode;
+ OMX_U32 Block8x8, XPerMB, YPerMB, Block2x, Block2y;
+ OMX_S32 PartStartX = 0, PartStartY = 0;
+ OMX_S32 PartWidth = 8, PartHeight = 8, BlockWidth = 4, BlockHeight = 4;
+ const OMX_U32 BlkSz [4][2] = {{4,4}, {4,8}, {8,4}};
+ const OMX_U32 PartSz [4][2] = {{8,8}, {8,16}, {16,8}, {16,16}};
+ const OMXVCM4P10SubMacroblockType
+ ModeSubMBType4x4 [] = {OMX_VC_SUB_P_4x4, OMX_VC_SUB_P_4x8,
+ OMX_VC_SUB_P_8x4, OMX_VC_SUB_P_8x8};
+ const OMXVCM4P10MacroblockType
+ ModeMBType [] = {OMX_VC_P_8x8, OMX_VC_P_8x16, OMX_VC_P_16x8, OMX_VC_P_16x16};
+
+ OMXVCM4P10MEParams *pMBOptions;
+ /*
+ * RefFrArr and MVArr will be used for temporary storage of Reference frame index and MVs
+ * It will store RefIndex and MVs of 6 MBs as shown below
+ *
+ * |------|------|------|
+ * |Tp-Lt |Top |Tp-R |
+ * | MB | MB | MB |
+ * |------|------|------|
+ * |Left | Curr | |
+ * | MB | MB | |
+ * |------|------|------|
+ */
+ OMX_S32 RefFrArr [4][6];
+ OMXVCMotionVector MVArr [8][12];
+ OMXVCMotionVector MVPredArr [4][4];
+
+ /*
+ * IndexToLoc will translate pMBInter index into spacial arrangement of MBs
+ */
+ OMX_S32 IndexToLoc [] = {2,1,3,0};
+ OMX_U32 part, MaxPart;
+ OMX_S32 Cost, MotionCost8x8 [4], MBCost, BestCost;
+
+ /*
+ * Update neighbouring MV array and Ref frame array which will be used for
+ * prediction of MVs and Ref frames.
+ */
+
+ /* Set cost to a high value */
+ Cost = BestCost = ARM_VCM4P10_MAX_COST;
+
+ for (y = 0; y < 8; y++)
+ {
+ for (x = 0; x < 12; x++)
+ {
+ i = 3 * (y >> 2) + (x >> 2);
+ if ((y < 4 || x < 4) && (pMBInter[IndexToLoc[i]] != NULL))
+ {
+ MVArr [y][x].dx =
+ pMBInter[IndexToLoc[i]]->pMV0[y % 4][x % 4].dx;
+ MVArr [y][x].dy =
+ pMBInter[IndexToLoc[i]]->pMV0[y % 4][x % 4].dy;
+ }
+ else
+ {
+ MVArr [y][x].dx = 0;
+ MVArr [y][x].dy = 0;
+ }
+ }
+ }
+
+ for (y = 0; y < 4; y++)
+ {
+ for (x = 0; x < 6; x++)
+ {
+ i = 3 * (y >> 1) + (x >> 1);
+ if ((y < 2 || x < 2) && (pMBInter[IndexToLoc[i]] != NULL))
+ {
+ RefFrArr [y][x] =
+ pMBInter[IndexToLoc[i]]->pRefL0Idx [(y % 2) * 2 + (x % 2)];
+ }
+ else
+ {
+ RefFrArr [y][x] = ARM_VCM4P10_INVALID_BLOCK;
+ }
+ }
+ }
+
+ for (y = 0; y < 4; y++)
+ {
+ for (x = 0; x < 4; x++)
+ {
+ MVPredArr [y][x].dx = 0;
+ MVPredArr [y][x].dy = 0;
+ }
+ }
+ /*
+ * Motion Estimation for 8x8 MB Partition
+ */
+
+ for (i = 0; i < 4; i++)
+ {
+ MotionCost8x8 [i] = 0;
+ }
+
+ pMBOptions = (OMXVCM4P10MEParams *) pMESpec;
+
+ if (pMBOptions->blockSplitEnable8x8 == 1 &&
+ pMBOptions->blockSplitEnable4x4 == 1)
+ {
+ pSrcDstMBCurr->mbType = OMX_VC_P_8x8;
+
+ PartWidth = PartSz [0][0];
+ PartHeight = PartSz [0][1];
+
+ /* For each 8x8 partitions */
+ for (Block8x8 = 0; Block8x8 < 4; Block8x8++)
+ {
+ PartStartX = (Block8x8 % 2) << 3;
+ PartStartY = (Block8x8 / 2) << 3;
+
+ Block2x = (Block8x8 & 1) << 1;
+ Block2y = (Block8x8 >> 1) << 1;
+
+ BestCost = ARM_VCM4P10_MAX_COST;
+ for (mode = 0; mode < 3; mode++)
+ {
+ BlockWidth = BlkSz [mode][0];
+ BlockHeight = BlkSz [mode][1];
+
+ armVCM4P10_PartitionME (
+ pSrcCurrBuf,
+ SrcCurrStep,
+ pSrcRefBufList,
+ SrcRefStep,
+ pRefRect,
+ pCurrPointPos,
+ pMESpec,
+
+ PartWidth,
+ PartHeight,
+ BlockWidth,
+ BlockHeight,
+ PartStartX,
+ PartStartY,
+
+ MVArr,
+ RefFrArr,
+ MVPredArr,
+
+ Lambda,
+ &Cost);
+
+ if (Cost <= BestCost)
+ {
+ /* Update cost */
+ BestCost = Cost;
+
+ /* Update MBCurr struct */
+ pSrcDstMBCurr->subMBType [Block8x8] = ModeSubMBType4x4 [mode];
+
+ pSrcDstMBCurr->pRefL0Idx [Block8x8] = RefFrArr [2 + (PartStartY >> 3)][2 + (PartStartX >> 3)];
+
+ /* Update pMV0 and pMVPred of MBCurr struct */
+ for (j = 0; j < 2; j++)
+ {
+ for (i = 0; i < 2; i++)
+ {
+ pSrcDstMBCurr->pMV0 [Block2y + j][Block2x + i].dx =
+ MVArr [4 + Block2y + j][4 + Block2x + i].dx;
+ pSrcDstMBCurr->pMV0 [Block2y + j][Block2x + i].dy =
+ MVArr [4 + Block2y + j][4 + Block2x + i].dy;
+
+ pSrcDstMBCurr->pMVPred [Block2y + j][Block2x + i].dx =
+ MVPredArr [Block2y + j][Block2x + i].dx;
+ pSrcDstMBCurr->pMVPred [Block2y + j][Block2x + i].dy =
+ MVPredArr [Block2y + j][Block2x + i].dy;
+ }
+ }
+ }
+ }
+
+ /* Update cost */
+ MotionCost8x8 [Block8x8] = BestCost;
+ }
+
+ /* Cost for mbType OMX_VC_P_8x8 */
+ BestCost = 0;
+ for (i = 0; i < 4; i++)
+ {
+ BestCost += MotionCost8x8 [i];
+ }
+ }
+ else
+ {
+ /* Set sub MB type to 8x8 */
+ for (i = 0; i < 4; i++)
+ {
+ pSrcDstMBCurr->subMBType [i] = OMX_VC_SUB_P_8x8;
+ }
+ }
+
+ /*
+ * Motion Estimation for 8x8, 8x16, 16x8 and 16x16 MB Partition
+ * If pMBOptions->b8x8BlockSplitEnable is 0, do only 16x16 ME (mode 3)
+ */
+ for (mode = (pMBOptions->blockSplitEnable8x8 == 1 ? 0 : 3); mode < 4; mode++)
+ {
+ BlockWidth = PartWidth = PartSz [mode][0];
+ BlockHeight = PartHeight = PartSz [mode][1];
+
+ XPerMB = 16 / PartWidth;
+ YPerMB = 16 / PartHeight;
+ MaxPart = XPerMB * YPerMB;
+
+ MBCost = 0;
+
+ /* part size 4, 2, 2 and 1 corresponding to 8x8, 8x16, 16x8 and 16x16 MB */
+ for (part = 0; part < MaxPart; part++)
+ {
+ PartStartX = (part % XPerMB) * PartWidth;
+ PartStartY = (part / XPerMB) * PartHeight;
+
+ armVCM4P10_PartitionME (
+ pSrcCurrBuf,
+ SrcCurrStep,
+ pSrcRefBufList,
+ SrcRefStep,
+ pRefRect,
+ pCurrPointPos,
+ pMESpec,
+
+ PartWidth,
+ PartHeight,
+ BlockWidth,
+ BlockHeight,
+ PartStartX,
+ PartStartY,
+
+ MVArr,
+ RefFrArr,
+ MVPredArr,
+
+ Lambda,
+ &Cost);
+
+ MBCost += Cost;
+ }
+
+ if (MBCost <= BestCost)
+ {
+ /* Update cost */
+ BestCost = MBCost;
+
+ /* Update mbType of MBCurr struct */
+ pSrcDstMBCurr->mbType = ModeMBType [mode];
+
+ /* Update pMV0 and pMVPred of MBCurr struct */
+ for (j = 0; j < 4; j++)
+ {
+ for (i = 0; i < 4; i++)
+ {
+ pSrcDstMBCurr->pMV0 [j][i].dx = MVArr [4+j][4+i].dx;
+ pSrcDstMBCurr->pMV0 [j][i].dy = MVArr [4+j][4+i].dy;
+ pSrcDstMBCurr->pMVPred [j][i].dx = MVPredArr [j][i].dx;
+ pSrcDstMBCurr->pMVPred [j][i].dy = MVPredArr [j][i].dy;
+ }
+ }
+ for (j = 0; j < 2; j++)
+ {
+ for (i = 0; i < 2; i++)
+ {
+ pSrcDstMBCurr->pRefL0Idx [j*2+i] = RefFrArr [2+j][2+i];
+ }
+ }
+ }
+
+ }
+
+ /* Update Best Cost */
+ *pDstCost = BestCost;
+
+ return OMX_Sts_NoErr;
+}
+
+/**
+ * Function: omxVCM4P10_MotionEstimationMB (6.3.5.3.1)
+ *
+ * Description:
+ * Performs MB-level motion estimation and selects best motion estimation
+ * strategy from the set of modes supported in baseline profile [ISO14496-10].
+ *
+ * Input Arguments:
+ *
+ * pSrcCurrBuf - Pointer to the current position in original picture plane;
+ * 16-byte alignment required
+ * pSrcRefBufList - Pointer to an array with 16 entries. Each entry points
+ * to the top-left corner of the co-located MB in a reference
+ * picture. The array is filled from low-to-high with valid
+ * reference frame pointers; the unused high entries should be set
+ * to NULL. Ordering of the reference frames should follow
+ * [ISO14496-10] subclause 8.2.4 Decoding Process for Reference
+ * Picture Lists. The entries must be 16-byte aligned.
+ * pSrcRecBuf - Pointer to the top-left corner of the co-located MB in the
+ * reconstructed picture; must be 16-byte aligned.
+ * SrcCurrStep - Width of the original picture plane in terms of full
+ * pixels; must be a multiple of 16.
+ * SrcRefStep - Width of the reference picture plane in terms of full
+ * pixels; must be a multiple of 16.
+ * SrcRecStep - Width of the reconstructed picture plane in terms of full
+ * pixels; must be a multiple of 16.
+ * pRefRect - Pointer to the valid reference rectangle; relative to the
+ * image origin.
+ * pCurrPointPos - Position of the current macroblock in the current plane.
+ * Lambda - Lagrange factor for computing the cost function
+ * pMESpec - Pointer to the motion estimation specification structure; must
+ * have been allocated and initialized prior to calling this
+ * function.
+ * pMBInter - Array, of dimension four, containing pointers to information
+ * associated with four adjacent type INTER MBs (Left, Top,
+ * Top-Left, Top-Right). Any pointer in the array may be set equal
+ * to NULL if the corresponding MB doesn t exist or is not of type
+ * INTER. pMBInter[0] - Pointer to left MB information pMBInter[1]
+ * - Pointer to top MB information pMBInter[2] - Pointer to
+ * top-left MB information pMBInter[3] - Pointer to top-right MB
+ * information
+ * pMBIntra - Array, of dimension four, containing pointers to information
+ * associated with four adjacent type INTRA MBs (Left, Top,
+ * Top-Left, Top-Right). Any pointer in the array may be set equal
+ * to NULL if the corresponding MB doesn t exist or is not of type
+ * INTRA. pMBIntra[0] - Pointer to left MB information pMBIntra[1]
+ * - Pointer to top MB information pMBIntra[2] - Pointer to
+ * top-left MB information pMBIntra[3] - Pointer to top-right MB
+ * information
+ * pSrcDstMBCurr - Pointer to information structure for the current MB.
+ * The following entries should be set prior to calling the
+ * function: sliceID - the number of the slice the to which the
+ * current MB belongs.
+ *
+ * Output Arguments:
+ *
+ * pDstCost - Pointer to the minimum motion cost for the current MB.
+ * pDstBlockSAD - Pointer to the array of SADs for each of the sixteen luma
+ * 4x4 blocks in each MB. The block SADs are in scan order for
+ * each MB. For implementations that cannot compute the SAD values
+ * individually, the maximum possible value (0xffff) is returned
+ * for each of the 16 block SAD entries.
+ * pSrcDstMBCurr - Pointer to updated information structure for the current
+ * MB after MB-level motion estimation has been completed. The
+ * following fields are updated by the ME function. The following
+ * parameter set quantifies the MB-level ME search results: MbType
+ * subMBType[4] pMV0[4][4] pMVPred[4][4] pRefL0Idx[4]
+ * Intra16x16PredMode pIntra4x4PredMode[4][4]
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - One of more of the following pointers is NULL: pSrcCurrBuf,
+ * pSrcRefBufList, pSrcRecBuf, pRefRect, pCurrPointPos, pMESpec,
+ * pMBInter, pMBIntra,pSrcDstMBCurr, pDstCost, pSrcRefBufList[0]
+ * - SrcRefStep, SrcRecStep are not multiples of 16
+ * - iBlockWidth or iBlockHeight are values other than 4, 8, or 16.
+ * - Any alignment restrictions are violated
+ *
+ */
+
+OMXResult omxVCM4P10_MotionEstimationMB(
+ const OMX_U8 *pSrcCurrBuf,
+ OMX_S32 SrcCurrStep,
+ const OMX_U8 *pSrcRefBufList[ARM_VCM4P10_MAX_FRAMES],
+ OMX_S32 SrcRefStep,
+ const OMX_U8 *pSrcRecBuf,
+ OMX_S32 SrcRecStep,
+ const OMXRect *pRefRect,
+ const OMXVCM4P2Coordinate *pCurrPointPos,
+ OMX_U32 Lambda,
+ void *pMESpec,
+ const OMXVCM4P10MBInfoPtr *pMBInter,
+ const OMXVCM4P10MBInfoPtr *pMBIntra,
+ OMXVCM4P10MBInfo *pSrcDstMBCurr,
+ OMX_INT *pDstCost,
+ OMX_U16 *pDstBlockSAD)
+{
+ OMX_U32 Cost, i, IntraFlag = 1;
+ OMXVCM4P10MEParams *pMEParams;
+
+ /* check for argument error */
+ armRetArgErrIf(pSrcCurrBuf == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pSrcRefBufList == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pSrcRecBuf == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pRefRect == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pCurrPointPos == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pMESpec == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pMBInter == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pMBIntra == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pSrcDstMBCurr == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pDstCost == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(SrcRefStep <= 0 || SrcRefStep & 15, OMX_Sts_BadArgErr)
+ armRetArgErrIf(SrcRecStep <= 0 || SrcRecStep & 15, OMX_Sts_BadArgErr)
+ armRetArgErrIf(SrcCurrStep <= 0 || SrcCurrStep & 15, OMX_Sts_BadArgErr)
+
+ armRetArgErrIf(armNot16ByteAligned(pSrcCurrBuf), OMX_Sts_BadArgErr)
+ armRetArgErrIf(armNot16ByteAligned(pSrcRecBuf), OMX_Sts_BadArgErr)
+
+ for (i = 0; i < ARM_VCM4P10_MAX_FRAMES; i++)
+ {
+ armRetArgErrIf(pSrcRefBufList [i] != NULL &&
+ armNot16ByteAligned(pSrcRefBufList [i]), OMX_Sts_BadArgErr)
+
+ /* Check if current MB needs INTER cost calculations */
+ if (pSrcRefBufList [i] != NULL && IntraFlag == 1)
+ {
+ IntraFlag = 0;
+ }
+ }
+
+ *pDstCost = ARM_VCM4P10_MAX_COST;
+ /*
+ * Inter cost calculations
+ */
+
+ /* check this MB can be Inter */
+ if (IntraFlag != 1)
+ {
+ armVCM4P10_InterMEMB(
+ pSrcCurrBuf,
+ SrcCurrStep,
+ pSrcRefBufList,
+ SrcRefStep,
+ pRefRect,
+ pCurrPointPos,
+ Lambda,
+ pMESpec,
+ pMBInter,
+ pSrcDstMBCurr,
+ &Cost
+ );
+
+ *pDstCost = Cost;
+ }
+
+ pMEParams = (OMXVCM4P10MEParams *)pMESpec;
+
+ if (pMEParams->intraEnable4x4 == 1)
+ {
+ /*
+ * Intra 4x4 cost calculations
+ */
+ armVCM4P10_Intra4x4Estimation(
+ pSrcCurrBuf,
+ SrcCurrStep,
+ pSrcRecBuf,
+ SrcRecStep,
+ pMBIntra,
+ pSrcDstMBCurr,
+ &Cost
+ );
+
+ if (Cost <= *pDstCost)
+ {
+ *pDstCost = Cost;
+ pSrcDstMBCurr->mbType = OMX_VC_INTRA_4x4;
+
+ }
+
+ }
+
+ /*
+ * Cost for Intra 16x16 mode
+ */
+
+ armVCM4P10_Intra16x16Estimation(
+ pSrcCurrBuf,
+ SrcCurrStep,
+ pSrcRecBuf,
+ SrcRecStep,
+ pCurrPointPos,
+ pMBInter,
+ pMBIntra,
+ pSrcDstMBCurr,
+ &Cost
+ );
+
+ if (Cost <= *pDstCost)
+ {
+ *pDstCost = Cost;
+ pSrcDstMBCurr->mbType = OMX_VC_INTRA_16x16;
+ }
+
+ /*
+ * Update pDstBlockSAD to max value
+ */
+ armVCM4P10_CalculateBlockSAD( pSrcDstMBCurr,
+ pSrcCurrBuf,
+ SrcCurrStep,
+ pSrcRefBufList,
+ SrcRefStep,
+ pSrcRecBuf,
+ SrcRecStep,
+ pRefRect,
+ pCurrPointPos,
+ pMBInter,
+ pMBIntra,
+ pDstBlockSAD);
+
+
+ return OMX_Sts_NoErr;
+}
+
+
+/*****************************************************************************
+ * END OF FILE
+ *****************************************************************************/
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_PredictIntraChroma_8x8.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_PredictIntraChroma_8x8.c
new file mode 100644
index 0000000..d6ca783
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_PredictIntraChroma_8x8.c
@@ -0,0 +1,284 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: omxVCM4P10_PredictIntraChroma_8x8.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * H.264 Chroma 8x8 intra prediction module
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/*
+ * Description:
+ * Perform DC style intra prediction, upper block has priority
+ *
+ * Parameters:
+ * [in] pSrcLeft Pointer to the buffer of 16 left coefficients:
+ * p[x, y] (x = -1, y = 0..3)
+ * [in] pSrcAbove Pointer to the buffer of 16 above coefficients:
+ * p[x,y] (x = 0..3, y = -1)
+ * [in] leftStep Step of left coefficient buffer
+ * [in] dstStep Step of the destination buffer
+ * [in] availability Neighboring 16x16 MB availability flag
+ * [out] pDst Pointer to the destination buffer
+ *
+ * Return Value:
+ * None
+ */
+
+static void armVCM4P10_PredictIntraDCUp4x4(
+ const OMX_U8* pSrcLeft,
+ const OMX_U8 *pSrcAbove,
+ OMX_U8* pDst,
+ OMX_INT leftStep,
+ OMX_INT dstStep,
+ OMX_S32 availability
+)
+{
+ int x, y, Sum=0, Count = 0;
+
+ if (availability & OMX_VC_UPPER)
+ {
+ for (x=0; x<4; x++)
+ {
+ Sum += pSrcAbove[x];
+ }
+ Count++;
+ }
+ else if (availability & OMX_VC_LEFT)
+ {
+ for (y=0; y<4; y++)
+ {
+ Sum += pSrcLeft[y*leftStep];
+ }
+ Count++;
+ }
+ if (Count==0)
+ {
+ Sum = 128;
+ }
+ else
+ {
+ Sum = (Sum + 2) >> 2;
+ }
+ for (y=0; y<4; y++)
+ {
+ for (x=0; x<4; x++)
+ {
+ pDst[y*dstStep+x] = (OMX_U8)Sum;
+ }
+ }
+}
+
+/*
+ * Description:
+ * Perform DC style intra prediction, left block has priority
+ *
+ * Parameters:
+ * [in] pSrcLeft Pointer to the buffer of 16 left coefficients:
+ * p[x, y] (x = -1, y = 0..3)
+ * [in] pSrcAbove Pointer to the buffer of 16 above coefficients:
+ * p[x,y] (x = 0..3, y = -1)
+ * [in] leftStep Step of left coefficient buffer
+ * [in] dstStep Step of the destination buffer
+ * [in] availability Neighboring 16x16 MB availability flag
+ * [out] pDst Pointer to the destination buffer
+ *
+ * Return Value:
+ * None
+ */
+
+static void armVCM4P10_PredictIntraDCLeft4x4(
+ const OMX_U8* pSrcLeft,
+ const OMX_U8 *pSrcAbove,
+ OMX_U8* pDst,
+ OMX_INT leftStep,
+ OMX_INT dstStep,
+ OMX_S32 availability
+)
+{
+ int x, y, Sum=0, Count = 0;
+
+ if (availability & OMX_VC_LEFT)
+ {
+ for (y=0; y<4; y++)
+ {
+ Sum += pSrcLeft[y*leftStep];
+ }
+ Count++;
+ }
+ else if (availability & OMX_VC_UPPER)
+ {
+ for (x=0; x<4; x++)
+ {
+ Sum += pSrcAbove[x];
+ }
+ Count++;
+ }
+ if (Count==0)
+ {
+ Sum = 128;
+ }
+ else
+ {
+ Sum = (Sum + 2) >> 2;
+ }
+ for (y=0; y<4; y++)
+ {
+ for (x=0; x<4; x++)
+ {
+ pDst[y*dstStep+x] = (OMX_U8)Sum;
+ }
+ }
+}
+
+/**
+ * Function: omxVCM4P10_PredictIntraChroma_8x8 (6.3.3.1.3)
+ *
+ * Description:
+ * Performs intra prediction for chroma samples.
+ *
+ * Input Arguments:
+ *
+ * pSrcLeft - Pointer to the buffer of 8 left pixels: p[x, y] (x = -1, y=
+ * 0..7).
+ * pSrcAbove - Pointer to the buffer of 8 above pixels: p[x,y] (x = 0..7, y
+ * = -1); must be aligned on an 8-byte boundary.
+ * pSrcAboveLeft - Pointer to the above left pixels: p[x,y] (x = -1, y = -1)
+ * leftStep - Step of left pixel buffer; must be a multiple of 8.
+ * dstStep - Step of the destination buffer; must be a multiple of 8.
+ * predMode - Intra chroma prediction mode, please refer to section 3.4.3.
+ * availability - Neighboring chroma block availability flag, please refer
+ * to "Neighboring Macroblock Availability".
+ *
+ * Output Arguments:
+ *
+ * pDst - Pointer to the destination buffer; must be aligned on an 8-byte
+ * boundary.
+ *
+ * Return Value:
+ * If the function runs without error, it returns OMX_Sts_NoErr.
+ * If any of the following cases occurs, the function returns
+ * OMX_Sts_BadArgErr:
+ * pDst is NULL.
+ * dstStep < 8 or dstStep is not a multiple of 8.
+ * leftStep is not a multiple of 8.
+ * predMode is not in the valid range of enumeration
+ * OMXVCM4P10IntraChromaPredMode.
+ * predMode is OMX_VC_CHROMA_VERT, but availability doesn't set
+ * OMX_VC_UPPER indicating p[x,-1] (x = 0..7) is not available.
+ * predMode is OMX_VC_CHROMA_HOR, but availability doesn't set OMX_VC_LEFT
+ * indicating p[-1,y] (y = 0..7) is not available.
+ * predMode is OMX_VC_CHROMA_PLANE, but availability doesn't set
+ * OMX_VC_UPPER_LEFT or OMX_VC_UPPER or OMX_VC_LEFT indicating
+ * p[x,-1](x = 0..7), or p[-1,y] (y = 0..7), or p[-1,-1] is not
+ * available.
+ * availability sets OMX_VC_UPPER, but pSrcAbove is NULL.
+ * availability sets OMX_VC_LEFT, but pSrcLeft is NULL.
+ * availability sets OMX_VC_UPPER_LEFT, but pSrcAboveLeft is NULL.
+ * either pSrcAbove or pDst is not aligned on a 8-byte boundary. Note:
+ * pSrcAbove, pSrcAbove, pSrcAboveLeft may be invalid pointer if
+ * they are not used by intra prediction implied in predMode.
+ * Note: OMX_VC_UPPER_RIGHT is not used in intra chroma
+ * prediction.
+ *
+ */
+OMXResult omxVCM4P10_PredictIntraChroma_8x8(
+ const OMX_U8* pSrcLeft,
+ const OMX_U8 *pSrcAbove,
+ const OMX_U8 *pSrcAboveLeft,
+ OMX_U8* pDst,
+ OMX_INT leftStep,
+ OMX_INT dstStep,
+ OMXVCM4P10IntraChromaPredMode predMode,
+ OMX_S32 availability
+ )
+{
+ int x, y, Sum;
+ int H, V, a, b, c;
+
+ armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(dstStep < 8, OMX_Sts_BadArgErr);
+ armRetArgErrIf((dstStep % 8) != 0, OMX_Sts_BadArgErr);
+ armRetArgErrIf((leftStep % 8) != 0, OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot8ByteAligned(pSrcAbove), OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot8ByteAligned(pDst), OMX_Sts_BadArgErr);
+ armRetArgErrIf((availability & OMX_VC_UPPER) && pSrcAbove == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf((availability & OMX_VC_LEFT ) && pSrcLeft == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf((availability & OMX_VC_UPPER_LEFT) && pSrcAboveLeft == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(predMode==OMX_VC_CHROMA_VERT && !(availability & OMX_VC_UPPER), OMX_Sts_BadArgErr);
+ armRetArgErrIf(predMode==OMX_VC_CHROMA_HOR && !(availability & OMX_VC_LEFT), OMX_Sts_BadArgErr);
+ armRetArgErrIf(predMode==OMX_VC_CHROMA_PLANE && !(availability & OMX_VC_UPPER), OMX_Sts_BadArgErr);
+ armRetArgErrIf(predMode==OMX_VC_CHROMA_PLANE && !(availability & OMX_VC_UPPER_LEFT), OMX_Sts_BadArgErr);
+ armRetArgErrIf(predMode==OMX_VC_CHROMA_PLANE && !(availability & OMX_VC_LEFT), OMX_Sts_BadArgErr);
+ armRetArgErrIf((unsigned)predMode > OMX_VC_CHROMA_PLANE, OMX_Sts_BadArgErr);
+
+ switch (predMode)
+ {
+ case OMX_VC_CHROMA_DC:
+ armVCM4P10_PredictIntraDC4x4( pSrcLeft, pSrcAbove, pDst, leftStep, dstStep, availability);
+ armVCM4P10_PredictIntraDCUp4x4( pSrcLeft, pSrcAbove+4, pDst+4, leftStep, dstStep, availability);
+ armVCM4P10_PredictIntraDCLeft4x4( pSrcLeft+4*leftStep, pSrcAbove, pDst+4*dstStep, leftStep, dstStep, availability);
+ armVCM4P10_PredictIntraDC4x4( pSrcLeft+4*leftStep, pSrcAbove+4, pDst+4+4*dstStep, leftStep, dstStep, availability);
+ break;
+
+ case OMX_VC_CHROMA_HOR:
+ for (y=0; y<8; y++)
+ {
+ for (x=0; x<8; x++)
+ {
+ pDst[y*dstStep+x] = pSrcLeft[y*leftStep];
+ }
+ }
+ break;
+
+ case OMX_VC_CHROMA_VERT:
+ for (y=0; y<8; y++)
+ {
+ for (x=0; x<8; x++)
+ {
+ pDst[y*dstStep+x] = pSrcAbove[x];
+ }
+ }
+ break;
+
+ case OMX_VC_CHROMA_PLANE:
+ H = 4*(pSrcAbove[7] - pSrcAboveLeft[0]);
+ for (x=2; x>=0; x--)
+ {
+ H += (x+1)*(pSrcAbove[4+x] - pSrcAbove[2-x]);
+ }
+ V = 4*(pSrcLeft[7*leftStep] - pSrcAboveLeft[0]);
+ for (y=2; y>=0; y--)
+ {
+ V += (y+1)*(pSrcLeft[(4+y)*leftStep] - pSrcLeft[(2-y)*leftStep]);
+ }
+ a = 16*(pSrcAbove[7] + pSrcLeft[7*leftStep]);
+ b = (17*H+16)>>5;
+ c = (17*V+16)>>5;
+ for (y=0; y<8; y++)
+ {
+ for (x=0; x<8; x++)
+ {
+ Sum = (a + b*(x-3) + c*(y-3) + 16)>>5;
+ pDst[y*dstStep+x] = (OMX_U8)armClip(0,255,Sum);
+ }
+ }
+ break;
+ }
+
+ return OMX_Sts_NoErr;
+}
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_PredictIntra_16x16.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_PredictIntra_16x16.c
new file mode 100644
index 0000000..c90cb4c
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_PredictIntra_16x16.c
@@ -0,0 +1,198 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: omxVCM4P10_PredictIntra_16x16.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * H.264 16x16 intra prediction module
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/**
+ * Function: omxVCM4P10_PredictIntra_16x16 (6.3.3.1.2)
+ *
+ * Description:
+ * Perform Intra_16x16 prediction for luma samples. If the upper-right block
+ * is not available, then duplication work should be handled inside the
+ * function. Users need not define them outside.
+ *
+ * Input Arguments:
+ *
+ * pSrcLeft - Pointer to the buffer of 16 left pixels: p[x, y] (x = -1, y =
+ * 0..15)
+ * pSrcAbove - Pointer to the buffer of 16 above pixels: p[x,y] (x = 0..15,
+ * y= -1); must be aligned on a 16-byte boundary.
+ * pSrcAboveLeft - Pointer to the above left pixels: p[x,y] (x = -1, y = -1)
+ * leftStep - Step of left pixel buffer; must be a multiple of 16.
+ * dstStep - Step of the destination buffer; must be a multiple of 16.
+ * predMode - Intra_16x16 prediction mode, please refer to section 3.4.1.
+ * availability - Neighboring 16x16 MB availability flag. Refer to
+ * section 3.4.4.
+ *
+ * Output Arguments:
+ *
+ * pDst -Pointer to the destination buffer; must be aligned on a 16-byte
+ * boundary.
+ *
+ * Return Value:
+ * If the function runs without error, it returns OMX_Sts_NoErr.
+ * If one of the following cases occurs, the function returns
+ * OMX_Sts_BadArgErr:
+ * pDst is NULL.
+ * dstStep < 16. or dstStep is not a multiple of 16.
+ * leftStep is not a multiple of 16.
+ * predMode is not in the valid range of enumeration
+ * OMXVCM4P10Intra16x16PredMode
+ * predMode is OMX_VC_16X16_VERT, but availability doesn't set
+ * OMX_VC_UPPER indicating p[x,-1] (x = 0..15) is not available.
+ * predMode is OMX_VC_16X16_HOR, but availability doesn't set OMX_VC_LEFT
+ * indicating p[-1,y] (y = 0..15) is not available.
+ * predMode is OMX_VC_16X16_PLANE, but availability doesn't set
+ * OMX_VC_UPPER_LEFT or OMX_VC_UPPER or OMX_VC_LEFT indicating
+ * p[x,-1](x = 0..15), or p[-1,y] (y = 0..15), or p[-1,-1] is not
+ * available.
+ * availability sets OMX_VC_UPPER, but pSrcAbove is NULL.
+ * availability sets OMX_VC_LEFT, but pSrcLeft is NULL.
+ * availability sets OMX_VC_UPPER_LEFT, but pSrcAboveLeft is NULL.
+ * either pSrcAbove or pDst is not aligned on a 16-byte boundary.
+ *
+ * Note:
+ * pSrcAbove, pSrcAbove, pSrcAboveLeft may be invalid pointers if
+ * they are not used by intra prediction implied in predMode.
+ * Note:
+ * OMX_VC_UPPER_RIGHT is not used in intra_16x16 luma prediction.
+ *
+ */
+OMXResult omxVCM4P10_PredictIntra_16x16(
+ const OMX_U8* pSrcLeft,
+ const OMX_U8 *pSrcAbove,
+ const OMX_U8 *pSrcAboveLeft,
+ OMX_U8* pDst,
+ OMX_INT leftStep,
+ OMX_INT dstStep,
+ OMXVCM4P10Intra16x16PredMode predMode,
+ OMX_S32 availability)
+{
+ int x,y,Sum,Count;
+ int H,V,a,b,c;
+
+ armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(dstStep < 16, OMX_Sts_BadArgErr);
+ armRetArgErrIf((dstStep % 16) != 0, OMX_Sts_BadArgErr);
+ armRetArgErrIf((leftStep % 16) != 0, OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot16ByteAligned(pSrcAbove), OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot16ByteAligned(pDst), OMX_Sts_BadArgErr);
+ armRetArgErrIf((availability & OMX_VC_UPPER) && pSrcAbove == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf((availability & OMX_VC_LEFT ) && pSrcLeft == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf((availability & OMX_VC_UPPER_LEFT) && pSrcAboveLeft == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(predMode==OMX_VC_16X16_VERT && !(availability & OMX_VC_UPPER), OMX_Sts_BadArgErr);
+ armRetArgErrIf(predMode==OMX_VC_16X16_HOR && !(availability & OMX_VC_LEFT), OMX_Sts_BadArgErr);
+ armRetArgErrIf(predMode==OMX_VC_16X16_PLANE && !(availability & OMX_VC_UPPER), OMX_Sts_BadArgErr);
+ armRetArgErrIf(predMode==OMX_VC_16X16_PLANE && !(availability & OMX_VC_UPPER_LEFT), OMX_Sts_BadArgErr);
+ armRetArgErrIf(predMode==OMX_VC_16X16_PLANE && !(availability & OMX_VC_LEFT), OMX_Sts_BadArgErr);
+ armRetArgErrIf((unsigned)predMode > OMX_VC_16X16_PLANE, OMX_Sts_BadArgErr);
+
+ switch (predMode)
+ {
+ case OMX_VC_16X16_VERT:
+ for (y=0; y<16; y++)
+ {
+ for (x=0; x<16; x++)
+ {
+ pDst[y*dstStep+x] = pSrcAbove[x];
+ }
+ }
+ break;
+
+ case OMX_VC_16X16_HOR:
+ for (y=0; y<16; y++)
+ {
+ for (x=0; x<16; x++)
+ {
+ pDst[y*dstStep+x] = pSrcLeft[y*leftStep];
+ }
+ }
+ break;
+
+ case OMX_VC_16X16_DC:
+ /* This can always be used even if no blocks available */
+ Sum = 0;
+ Count = 0;
+ if (availability & OMX_VC_LEFT)
+ {
+ for (y=0; y<16; y++)
+ {
+ Sum += pSrcLeft[y*leftStep];
+ }
+ Count++;
+ }
+ if (availability & OMX_VC_UPPER)
+ {
+ for (x=0; x<16; x++)
+ {
+ Sum += pSrcAbove[x];
+ }
+ Count++;
+ }
+ if (Count==0)
+ {
+ Sum = 128;
+ }
+ else if (Count==1)
+ {
+ Sum = (Sum + 8) >> 4;
+ }
+ else /* Count = 2 */
+ {
+ Sum = (Sum + 16) >> 5;
+ }
+ for (y=0; y<16; y++)
+ {
+ for (x=0; x<16; x++)
+ {
+ pDst[y*dstStep+x] = (OMX_U8)Sum;
+ }
+ }
+ break;
+
+ case OMX_VC_16X16_PLANE:
+ H = 8*(pSrcAbove[15] - pSrcAboveLeft[0]);
+ for (x=6; x>=0; x--)
+ {
+ H += (x+1)*(pSrcAbove[8+x] - pSrcAbove[6-x]);
+ }
+ V = 8*(pSrcLeft[15*leftStep] - pSrcAboveLeft[0]);
+ for (y=6; y>=0; y--)
+ {
+ V += (y+1)*(pSrcLeft[(8+y)*leftStep] - pSrcLeft[(6-y)*leftStep]);
+ }
+ a = 16*(pSrcAbove[15] + pSrcLeft[15*leftStep]);
+ b = (5*H+32)>>6;
+ c = (5*V+32)>>6;
+ for (y=0; y<16; y++)
+ {
+ for (x=0; x<16; x++)
+ {
+ Sum = (a + b*(x-7) + c*(y-7) + 16)>>5;
+ pDst[y*dstStep+x] = (OMX_U8)armClip(0,255,Sum);
+ }
+ }
+ break;
+ }
+
+ return OMX_Sts_NoErr;
+}
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_PredictIntra_4x4.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_PredictIntra_4x4.c
new file mode 100644
index 0000000..3fa8212
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_PredictIntra_4x4.c
@@ -0,0 +1,338 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: omxVCM4P10_PredictIntra_4x4.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * H.264 4x4 intra prediction module
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/**
+ * Function: omxVCM4P10_PredictIntra_4x4 (6.3.3.1.1)
+ *
+ * Description:
+ * Perform Intra_4x4 prediction for luma samples. If the upper-right block is
+ * not available, then duplication work should be handled inside the function.
+ * Users need not define them outside.
+ *
+ * Input Arguments:
+ *
+ * pSrcLeft - Pointer to the buffer of 4 left pixels:
+ * p[x, y] (x = -1, y = 0..3)
+ * pSrcAbove - Pointer to the buffer of 8 above pixels:
+ * p[x,y] (x = 0..7, y =-1);
+ * must be aligned on a 4-byte boundary.
+ * pSrcAboveLeft - Pointer to the above left pixels: p[x,y] (x = -1, y = -1)
+ * leftStep - Step of left pixel buffer; must be a multiple of 4.
+ * dstStep - Step of the destination buffer; must be a multiple of 4.
+ * predMode - Intra_4x4 prediction mode.
+ * availability - Neighboring 4x4 block availability flag, refer to
+ * "Neighboring Macroblock Availability" .
+ *
+ * Output Arguments:
+ *
+ * pDst - Pointer to the destination buffer; must be aligned on a 4-byte
+ * boundary.
+ *
+ * Return Value:
+ * If the function runs without error, it returns OMX_Sts_NoErr.
+ * If one of the following cases occurs, the function returns
+ * OMX_Sts_BadArgErr:
+ * pDst is NULL.
+ * dstStep < 4, or dstStep is not a multiple of 4.
+ * leftStep is not a multiple of 4.
+ * predMode is not in the valid range of enumeration
+ * OMXVCM4P10Intra4x4PredMode.
+ * predMode is OMX_VC_4x4_VERT, but availability doesn't set OMX_VC_UPPER
+ * indicating p[x,-1] (x = 0..3) is not available.
+ * predMode is OMX_VC_4x4_HOR, but availability doesn't set OMX_VC_LEFT
+ * indicating p[-1,y] (y = 0..3) is not available.
+ * predMode is OMX_VC_4x4_DIAG_DL, but availability doesn't set
+ * OMX_VC_UPPER indicating p[x, 1] (x = 0..3) is not available.
+ * predMode is OMX_VC_4x4_DIAG_DR, but availability doesn't set
+ * OMX_VC_UPPER_LEFT or OMX_VC_UPPER or OMX_VC_LEFT indicating
+ * p[x,-1] (x = 0..3), or p[-1,y] (y = 0..3) or p[-1,-1] is not
+ * available.
+ * predMode is OMX_VC_4x4_VR, but availability doesn't set
+ * OMX_VC_UPPER_LEFT or OMX_VC_UPPER or OMX_VC_LEFT indicating
+ * p[x,-1] (x = 0..3), or p[-1,y] (y = 0..3) or p[-1,-1] is not
+ * available.
+ * predMode is OMX_VC_4x4_HD, but availability doesn't set
+ * OMX_VC_UPPER_LEFT or OMX_VC_UPPER or OMX_VC_LEFT indicating
+ * p[x,-1] (x = 0..3), or p[-1,y] (y = 0..3) or p[-1,-1] is not
+ * available.
+ * predMode is OMX_VC_4x4_VL, but availability doesn't set OMX_VC_UPPER
+ * indicating p[x,-1] (x = 0..3) is not available.
+ * predMode is OMX_VC_4x4_HU, but availability doesn't set OMX_VC_LEFT
+ * indicating p[-1,y] (y = 0..3) is not available.
+ * availability sets OMX_VC_UPPER, but pSrcAbove is NULL.
+ * availability sets OMX_VC_LEFT, but pSrcLeft is NULL.
+ * availability sets OMX_VC_UPPER_LEFT, but pSrcAboveLeft is NULL.
+ * either pSrcAbove or pDst is not aligned on a 4-byte boundary.
+ *
+ * Note:
+ * pSrcAbove, pSrcAbove, pSrcAboveLeft may be invalid pointers if
+ * they are not used by intra prediction as implied in predMode.
+ *
+ */
+
+OMXResult omxVCM4P10_PredictIntra_4x4(
+ const OMX_U8* pSrcLeft,
+ const OMX_U8 *pSrcAbove,
+ const OMX_U8 *pSrcAboveLeft,
+ OMX_U8* pDst,
+ OMX_INT leftStep,
+ OMX_INT dstStep,
+ OMXVCM4P10Intra4x4PredMode predMode,
+ OMX_S32 availability
+ )
+{
+ int x, y;
+ OMX_U8 pTmp[10];
+
+ armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf((leftStep % 4) != 0, OMX_Sts_BadArgErr);
+ armRetArgErrIf((dstStep % 4) != 0, OMX_Sts_BadArgErr);
+ armRetArgErrIf((dstStep < 4), OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot4ByteAligned(pSrcAbove), OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot4ByteAligned(pDst), OMX_Sts_BadArgErr);
+ armRetArgErrIf((availability & OMX_VC_UPPER) && pSrcAbove == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf((availability & OMX_VC_LEFT ) && pSrcLeft == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf((availability & OMX_VC_UPPER_LEFT) && pSrcAboveLeft == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(predMode==OMX_VC_4X4_VERT && !(availability & OMX_VC_UPPER), OMX_Sts_BadArgErr);
+ armRetArgErrIf(predMode==OMX_VC_4X4_HOR && !(availability & OMX_VC_LEFT), OMX_Sts_BadArgErr);
+ armRetArgErrIf(predMode==OMX_VC_4X4_DIAG_DL && !(availability & OMX_VC_UPPER), OMX_Sts_BadArgErr);
+ armRetArgErrIf(predMode==OMX_VC_4X4_DIAG_DR && !(availability & OMX_VC_UPPER), OMX_Sts_BadArgErr);
+ armRetArgErrIf(predMode==OMX_VC_4X4_DIAG_DR && !(availability & OMX_VC_UPPER_LEFT), OMX_Sts_BadArgErr);
+ armRetArgErrIf(predMode==OMX_VC_4X4_DIAG_DR && !(availability & OMX_VC_LEFT), OMX_Sts_BadArgErr);
+ armRetArgErrIf(predMode==OMX_VC_4X4_VR && !(availability & OMX_VC_UPPER), OMX_Sts_BadArgErr);
+ armRetArgErrIf(predMode==OMX_VC_4X4_VR && !(availability & OMX_VC_UPPER_LEFT), OMX_Sts_BadArgErr);
+ armRetArgErrIf(predMode==OMX_VC_4X4_VR && !(availability & OMX_VC_LEFT), OMX_Sts_BadArgErr);
+ armRetArgErrIf(predMode==OMX_VC_4X4_HD && !(availability & OMX_VC_UPPER), OMX_Sts_BadArgErr);
+ armRetArgErrIf(predMode==OMX_VC_4X4_HD && !(availability & OMX_VC_UPPER_LEFT), OMX_Sts_BadArgErr);
+ armRetArgErrIf(predMode==OMX_VC_4X4_HD && !(availability & OMX_VC_LEFT), OMX_Sts_BadArgErr);
+ armRetArgErrIf(predMode==OMX_VC_4X4_VL && !(availability & OMX_VC_UPPER), OMX_Sts_BadArgErr);
+ armRetArgErrIf(predMode==OMX_VC_4X4_HU && !(availability & OMX_VC_LEFT), OMX_Sts_BadArgErr);
+ armRetArgErrIf((unsigned)predMode > OMX_VC_4X4_HU, OMX_Sts_BadArgErr);
+
+ /* Note: This code must not read the pSrc arrays unless the corresponding
+ * block is marked as available. If the block is not avaibable then pSrc
+ * may not be a valid pointer.
+ *
+ * Note: To make the code more readable we refer to the neighbouring pixels
+ * in variables named as below:
+ *
+ * UL U0 U1 U2 U3 U4 U5 U6 U7
+ * L0 xx xx xx xx
+ * L1 xx xx xx xx
+ * L2 xx xx xx xx
+ * L3 xx xx xx xx
+ */
+
+#define UL pSrcAboveLeft[0]
+#define U0 pSrcAbove[0]
+#define U1 pSrcAbove[1]
+#define U2 pSrcAbove[2]
+#define U3 pSrcAbove[3]
+#define U4 pSrcAbove[4]
+#define U5 pSrcAbove[5]
+#define U6 pSrcAbove[6]
+#define U7 pSrcAbove[7]
+#define L0 pSrcLeft[0*leftStep]
+#define L1 pSrcLeft[1*leftStep]
+#define L2 pSrcLeft[2*leftStep]
+#define L3 pSrcLeft[3*leftStep]
+
+ switch (predMode)
+ {
+ case OMX_VC_4X4_VERT:
+ for (y=0; y<4; y++)
+ {
+ pDst[y*dstStep+0] = U0;
+ pDst[y*dstStep+1] = U1;
+ pDst[y*dstStep+2] = U2;
+ pDst[y*dstStep+3] = U3;
+ }
+ break;
+
+ case OMX_VC_4X4_HOR:
+ for (x=0; x<4; x++)
+ {
+ pDst[0*dstStep+x] = L0;
+ pDst[1*dstStep+x] = L1;
+ pDst[2*dstStep+x] = L2;
+ pDst[3*dstStep+x] = L3;
+ }
+ break;
+
+ case OMX_VC_4X4_DC:
+ /* This can always be used even if no blocks available */
+ armVCM4P10_PredictIntraDC4x4(pSrcLeft, pSrcAbove, pDst, leftStep, dstStep, availability);
+ break;
+
+ case OMX_VC_4X4_DIAG_DL:
+ pTmp[0] = (OMX_U8)((U0 + 2*U1 + U2 + 2)>>2);
+ pTmp[1] = (OMX_U8)((U1 + 2*U2 + U3 + 2)>>2);
+ if (availability & OMX_VC_UPPER_RIGHT)
+ {
+ pTmp[2] = (OMX_U8)((U2 + 2*U3 + U4 + 2)>>2);
+ pTmp[3] = (OMX_U8)((U3 + 2*U4 + U5 + 2)>>2);
+ pTmp[4] = (OMX_U8)((U4 + 2*U5 + U6 + 2)>>2);
+ pTmp[5] = (OMX_U8)((U5 + 2*U6 + U7 + 2)>>2);
+ pTmp[6] = (OMX_U8)((U6 + 3*U7 + 2)>>2);
+ }
+ else
+ {
+ pTmp[2] = (OMX_U8)((U2 + 3*U3 + 2)>>2);
+ pTmp[3] = U3;
+ pTmp[4] = U3;
+ pTmp[5] = U3;
+ pTmp[6] = U3;
+ }
+ for (y=0; y<4; y++)
+ {
+ for (x=0; x<4; x++)
+ {
+ pDst[y*dstStep+x] = pTmp[x+y];
+ }
+ }
+ break;
+
+ case OMX_VC_4X4_DIAG_DR:
+ /* x-y = -3, -2, -1, 0, 1, 2, 3 */
+ pTmp[0] = (OMX_U8)((L1 + 2*L2 + L3 + 2)>>2);
+ pTmp[1] = (OMX_U8)((L0 + 2*L1 + L2 + 2)>>2);
+ pTmp[2] = (OMX_U8)((UL + 2*L0 + L1 + 2)>>2);
+ pTmp[3] = (OMX_U8)((U0 + 2*UL + L0 + 2)>>2);
+ pTmp[4] = (OMX_U8)((U1 + 2*U0 + UL + 2)>>2);
+ pTmp[5] = (OMX_U8)((U2 + 2*U1 + U0 + 2)>>2);
+ pTmp[6] = (OMX_U8)((U3 + 2*U2 + U1 + 2)>>2);
+ for (y=0; y<4; y++)
+ {
+ for (x=0; x<4; x++)
+ {
+ pDst[y*dstStep+x] = pTmp[3+x-y];
+ }
+ }
+ break;
+
+ case OMX_VC_4X4_VR:
+ /* zVR=2x-y = -3, -2, -1, 0, 1, 2, 3, 4, 5, 6
+ * x-(y>>1) = -1, -1, 0, 0, 1, 1, 2, 2, 3, 3
+ * y = 3, 2, ?, ?, ?, ?, ?, ?, 1, 0
+ */
+ pTmp[0] = (OMX_U8)((L2 + 2*L1 + L0 + 2)>>2);
+ pTmp[1] = (OMX_U8)((L1 + 2*L0 + UL + 2)>>2);
+ pTmp[2] = (OMX_U8)((L0 + 2*UL + U0 + 2)>>2);
+ pTmp[3] = (OMX_U8)((UL + U0 + 1)>>1);
+ pTmp[4] = (OMX_U8)((UL + 2*U0 + U1 + 2)>>2);
+ pTmp[5] = (OMX_U8)((U0 + U1 + 1)>>1);
+ pTmp[6] = (OMX_U8)((U0 + 2*U1 + U2 + 2)>>2);
+ pTmp[7] = (OMX_U8)((U1 + U2 + 1)>>1);
+ pTmp[8] = (OMX_U8)((U1 + 2*U2 + U3 + 2)>>2);
+ pTmp[9] = (OMX_U8)((U2 + U3 + 1)>>1);
+ for (y=0; y<4; y++)
+ {
+ for (x=0; x<4; x++)
+ {
+ pDst[y*dstStep+x] = pTmp[3+2*x-y];
+ }
+ }
+ break;
+
+ case OMX_VC_4X4_HD:
+ /* zHD=2y-x = -3 -2 -1 0 1 2 3 4 5 6
+ * y-(x>>1) = -1 -1 0 0 1 1 2 2 3 3
+ * x = 3 2 1 0
+ */
+ pTmp[0] = (OMX_U8)((U2 + 2*U1 + U0 + 2)>>2);
+ pTmp[1] = (OMX_U8)((U1 + 2*U0 + UL + 2)>>2);
+ pTmp[2] = (OMX_U8)((U0 + 2*UL + L0 + 2)>>2);
+ pTmp[3] = (OMX_U8)((UL + L0 + 1)>>1);
+ pTmp[4] = (OMX_U8)((UL + 2*L0 + L1 + 2)>>2);
+ pTmp[5] = (OMX_U8)((L0 + L1 + 1)>>1);
+ pTmp[6] = (OMX_U8)((L0 + 2*L1 + L2 + 2)>>2);
+ pTmp[7] = (OMX_U8)((L1 + L2 + 1)>>1);
+ pTmp[8] = (OMX_U8)((L1 + 2*L2 + L3 + 2)>>2);
+ pTmp[9] = (OMX_U8)((L2 + L3 + 1)>>1);
+ for (y=0; y<4; y++)
+ {
+ for (x=0; x<4; x++)
+ {
+ pDst[y*dstStep+x] = pTmp[3+2*y-x];
+ }
+ }
+ break;
+
+ case OMX_VC_4X4_VL:
+ /* Note: x+(y>>1) = (2*x+y)>>1
+ * 2x+y = 0 1 2 3 4 5 6 7 8 9
+ */
+ pTmp[0] = (OMX_U8)((U0 + U1 + 1)>>1);
+ pTmp[1] = (OMX_U8)((U0 + 2*U1 + U2 + 2)>>2);
+ pTmp[2] = (OMX_U8)((U1 + U2 + 1)>>1);
+ pTmp[3] = (OMX_U8)((U1 + 2*U2 + U3 + 2)>>2);
+ pTmp[4] = (OMX_U8)((U2 + U3 + 1)>>1);
+ if (availability & OMX_VC_UPPER_RIGHT)
+ {
+ pTmp[5] = (OMX_U8)((U2 + 2*U3 + U4 + 2)>>2);
+ pTmp[6] = (OMX_U8)((U3 + U4 + 1)>>1);
+ pTmp[7] = (OMX_U8)((U3 + 2*U4 + U5 + 2)>>2);
+ pTmp[8] = (OMX_U8)((U4 + U5 + 1)>>1);
+ pTmp[9] = (OMX_U8)((U4 + 2*U5 + U6 + 2)>>2);
+ }
+ else
+ {
+ pTmp[5] = (OMX_U8)((U2 + 3*U3 + 2)>>2);
+ pTmp[6] = U3;
+ pTmp[7] = U3;
+ pTmp[8] = U3;
+ pTmp[9] = U3;
+ }
+ for (y=0; y<4; y++)
+ {
+ for (x=0; x<4; x++)
+ {
+ pDst[y*dstStep+x] = pTmp[2*x+y];
+ }
+ }
+ break;
+
+ case OMX_VC_4X4_HU:
+ /* zHU = x+2*y */
+ pTmp[0] = (OMX_U8)((L0 + L1 + 1)>>1);
+ pTmp[1] = (OMX_U8)((L0 + 2*L1 + L2 + 2)>>2);
+ pTmp[2] = (OMX_U8)((L1 + L2 + 1)>>1);
+ pTmp[3] = (OMX_U8)((L1 + 2*L2 + L3 + 2)>>2);
+ pTmp[4] = (OMX_U8)((L2 + L3 + 1)>>1);
+ pTmp[5] = (OMX_U8)((L2 + 3*L3 + 2)>>2);
+ pTmp[6] = L3;
+ pTmp[7] = L3;
+ pTmp[8] = L3;
+ pTmp[9] = L3;
+ for (y=0; y<4; y++)
+ {
+ for (x=0; x<4; x++)
+ {
+ pDst[y*dstStep+x] = pTmp[x+2*y];
+ }
+ }
+ break;
+ }
+
+ return OMX_Sts_NoErr;
+}
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SADQuar_16x.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SADQuar_16x.c
new file mode 100644
index 0000000..c8114ee
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SADQuar_16x.c
@@ -0,0 +1,86 @@
+/**
+ *
+ * File Name: omxVCM4P10_SADQuar_16x.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ * Description:
+ * This function will calculate SAD of pSrc with average of two Ref blocks
+ * of 16x16 or 16x8
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armVC.h"
+#include "armCOMM.h"
+
+/**
+ * Function: omxVCM4P10_SADQuar_16x (6.3.5.4.4)
+ *
+ * Description:
+ * This function calculates the SAD between one block (pSrc) and the average
+ * of the other two (pSrcRef0 and pSrcRef1) for 16x16 or 16x8 blocks.
+ * Rounding is applied according to the convention (a+b+1)>>1.
+ *
+ * Input Arguments:
+ *
+ * pSrc - Pointer to the original block; must be aligned on a 16-byte
+ * boundary.
+ * pSrcRef0 - Pointer to reference block 0
+ * pSrcRef1 - Pointer to reference block 1
+ * iSrcStep - Step of the original block buffer; must be a multiple of 16
+ * iRefStep0 - Step of reference block 0
+ * iRefStep1 - Step of reference block 1
+ * iHeight - Height of the block; must be equal to either 8 or 16
+ *
+ * Output Arguments:
+ *
+ * pDstSAD -Pointer of result SAD
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - iHeight is not equal to either 8 or 16.
+ * - One of more of the following pointers is NULL: pSrc, pSrcRef0,
+ * pSrcRef1, pDstSAD.
+ * - iSrcStep is not a multiple of 16
+ * - Any alignment restrictions are violated
+ *
+ */
+OMXResult omxVCM4P10_SADQuar_16x(
+ const OMX_U8* pSrc,
+ const OMX_U8* pSrcRef0,
+ const OMX_U8* pSrcRef1,
+ OMX_U32 iSrcStep,
+ OMX_U32 iRefStep0,
+ OMX_U32 iRefStep1,
+ OMX_U32* pDstSAD,
+ OMX_U32 iHeight
+)
+{
+ /* check for argument error */
+ armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pSrcRef0 == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pSrcRef1 == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pDstSAD == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf((iHeight != 16) && (iHeight != 8), OMX_Sts_BadArgErr)
+ armRetArgErrIf(armNot16ByteAligned(pSrc), OMX_Sts_BadArgErr)
+ armRetArgErrIf((iSrcStep == 0) || (iSrcStep & 15), OMX_Sts_BadArgErr)
+
+
+ return armVCM4P10_SADQuar
+ (pSrc, pSrcRef0, pSrcRef1, iSrcStep,
+ iRefStep0, iRefStep1, pDstSAD, iHeight, 16);
+}
+
+/*****************************************************************************
+ * END OF FILE
+ *****************************************************************************/
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SADQuar_4x.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SADQuar_4x.c
new file mode 100644
index 0000000..4b330ba
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SADQuar_4x.c
@@ -0,0 +1,85 @@
+/**
+ *
+ * File Name: omxVCM4P10_SADQuar_4x.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ * Description:
+ * This function will calculate SAD of pSrc with average of two Ref blocks
+ * of 4x8 or 4x4 blocks
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armVC.h"
+#include "armCOMM.h"
+
+/**
+ * Function: omxVCM4P10_SADQuar_4x (6.3.5.4.2)
+ *
+ * Description:
+ * This function calculates the SAD between one block (pSrc) and the average
+ * of the other two (pSrcRef0 and pSrcRef1) for 4x8 or 4x4 blocks. Rounding
+ * is applied according to the convention (a+b+1)>>1.
+ *
+ * Input Arguments:
+ *
+ * pSrc - Pointer to the original block; must be aligned on a 4-byte
+ * boundary.
+ * pSrcRef0 - Pointer to reference block 0
+ * pSrcRef1 - Pointer to reference block 1
+ * iSrcStep - Step of the original block buffer; must be a multiple of 4.
+ * iRefStep0 - Step of reference block 0
+ * iRefStep1 - Step of reference block 1
+ * iHeight - Height of the block; must be equal to either 4 or 8.
+ *
+ * Output Arguments:
+ *
+ * pDstSAD - Pointer of result SAD
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - iHeight is not equal to either 4 or 8.
+ * - One of more of the following pointers is NULL: pSrc, pSrcRef0,
+ * pSrcRef1, pDstSAD.
+ * - iSrcStep is not a multiple of 4
+ * - Any alignment restrictions are violated
+ *
+ */
+OMXResult omxVCM4P10_SADQuar_4x(
+ const OMX_U8* pSrc,
+ const OMX_U8* pSrcRef0,
+ const OMX_U8* pSrcRef1,
+ OMX_U32 iSrcStep,
+ OMX_U32 iRefStep0,
+ OMX_U32 iRefStep1,
+ OMX_U32* pDstSAD,
+ OMX_U32 iHeight
+)
+{
+ /* check for argument error */
+ armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pSrcRef0 == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pSrcRef1 == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pDstSAD == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf((iHeight != 8) && (iHeight != 4), OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot4ByteAligned(pSrc), OMX_Sts_BadArgErr);
+ armRetArgErrIf((iSrcStep == 0) || (iSrcStep & 3), OMX_Sts_BadArgErr);
+
+ return armVCM4P10_SADQuar
+ (pSrc, pSrcRef0, pSrcRef1, iSrcStep,
+ iRefStep0, iRefStep1, pDstSAD, iHeight, 4);
+}
+
+/*****************************************************************************
+ * END OF FILE
+ *****************************************************************************/
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SADQuar_8x.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SADQuar_8x.c
new file mode 100644
index 0000000..c9e9c24
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SADQuar_8x.c
@@ -0,0 +1,87 @@
+/**
+ *
+ * File Name: omxVCM4P10_SADQuar_8x.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ * Description:
+ * This function will calculate SAD of pSrc with average of two Ref blocks
+ * of 8x16 or 8x8 or 8x4
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armVC.h"
+#include "armCOMM.h"
+
+/**
+ * Function: omxVCM4P10_SADQuar_8x (6.3.5.4.3)
+ *
+ * Description:
+ * This function calculates the SAD between one block (pSrc) and the average
+ * of the other two (pSrcRef0 and pSrcRef1) for 8x16, 8x8, or 8x4 blocks.
+ * Rounding is applied according to the convention (a+b+1)>>1.
+ *
+ * Input Arguments:
+ *
+ * pSrc - Pointer to the original block; must be aligned on an 8-byte
+ * boundary.
+ * pSrcRef0 - Pointer to reference block 0
+ * pSrcRef1 - Pointer to reference block 1
+ * iSrcStep - Step of the original block buffer; must be a multiple of 8.
+ * iRefStep0 - Step of reference block 0
+ * iRefStep1 - Step of reference block 1
+ * iHeight - Height of the block; must be equal either 4, 8, or 16.
+ *
+ * Output Arguments:
+ *
+ * pDstSAD - Pointer of result SAD
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - iHeight is not equal to either 4, 8, or 16.
+ * - One of more of the following pointers is NULL: pSrc, pSrcRef0,
+ * pSrcRef1, pDstSAD.
+ * - iSrcStep is not a multiple of 8
+ * - Any alignment restrictions are violated
+ *
+ */
+OMXResult omxVCM4P10_SADQuar_8x(
+ const OMX_U8* pSrc,
+ const OMX_U8* pSrcRef0,
+ const OMX_U8* pSrcRef1,
+ OMX_U32 iSrcStep,
+ OMX_U32 iRefStep0,
+ OMX_U32 iRefStep1,
+ OMX_U32* pDstSAD,
+ OMX_U32 iHeight
+)
+{
+ /* check for argument error */
+ armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pSrcRef0 == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pSrcRef1 == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pDstSAD == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf((iHeight != 16) && (iHeight != 8) &&
+ (iHeight != 4), OMX_Sts_BadArgErr)
+ armRetArgErrIf(armNot8ByteAligned(pSrc), OMX_Sts_BadArgErr)
+ armRetArgErrIf((iSrcStep == 0) || (iSrcStep & 7), OMX_Sts_BadArgErr)
+
+
+ return armVCM4P10_SADQuar
+ (pSrc, pSrcRef0, pSrcRef1, iSrcStep,
+ iRefStep0, iRefStep1, pDstSAD, iHeight, 8);
+}
+
+/*****************************************************************************
+ * END OF FILE
+ *****************************************************************************/
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SAD_4x.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SAD_4x.c
new file mode 100644
index 0000000..927c454
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SAD_4x.c
@@ -0,0 +1,77 @@
+/**
+ *
+ * File Name: omxVCM4P10_SAD_4x.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ * Description:
+ * This function will calculate SAD for 4x8 and 4x4 blocks
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armVC.h"
+#include "armCOMM.h"
+
+/**
+ * Function: omxVCM4P10_SAD_4x (6.3.5.4.1)
+ *
+ * Description:
+ * This function calculates the SAD for 4x8 and 4x4 blocks.
+ *
+ * Input Arguments:
+ *
+ * pSrcOrg -Pointer to the original block; must be aligned on a 4-byte
+ * boundary.
+ * iStepOrg -Step of the original block buffer; must be a multiple of 4.
+ * pSrcRef -Pointer to the reference block
+ * iStepRef -Step of the reference block buffer
+ * iHeight -Height of the block; must be equal to either 4 or 8.
+ *
+ * Output Arguments:
+ *
+ * pDstSAD -Pointer of result SAD
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - One of more of the following pointers is NULL:
+ * pSrcOrg, pSrcRef, or pDstSAD
+ * - iHeight is not equal to either 4 or 8.
+ * - iStepOrg is not a multiple of 4
+ * - Any alignment restrictions are violated
+ *
+ */
+OMXResult omxVCM4P10_SAD_4x(
+ const OMX_U8* pSrcOrg,
+ OMX_U32 iStepOrg,
+ const OMX_U8* pSrcRef,
+ OMX_U32 iStepRef,
+ OMX_S32* pDstSAD,
+ OMX_U32 iHeight
+)
+{
+ /* check for argument error */
+ armRetArgErrIf(pSrcOrg == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pSrcRef == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pDstSAD == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf((iHeight != 8) && (iHeight != 4), OMX_Sts_BadArgErr)
+ armRetArgErrIf(armNot4ByteAligned(pSrcOrg), OMX_Sts_BadArgErr)
+ armRetArgErrIf((iStepOrg == 0) || (iStepOrg & 3), OMX_Sts_BadArgErr)
+ armRetArgErrIf((iStepRef == 0) || (iStepRef & 3), OMX_Sts_BadArgErr)
+
+ return armVCCOMM_SAD
+ (pSrcOrg, iStepOrg, pSrcRef, iStepRef, pDstSAD, iHeight, 4);
+}
+
+/*****************************************************************************
+ * END OF FILE
+ *****************************************************************************/
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SATD_4x4.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SATD_4x4.c
new file mode 100644
index 0000000..a91ae66
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SATD_4x4.c
@@ -0,0 +1,132 @@
+/**
+ *
+ * File Name: omxVCM4P10_SATD_4x4.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ * Description:
+ * This function will calculate SAD for 4x4 blocks
+ *
+ */
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+
+/**
+ * Function: omxVCM4P10_SATD_4x4 (6.3.5.4.5)
+ *
+ * Description:
+ * This function calculates the sum of absolute transform differences (SATD)
+ * for a 4x4 block by applying a Hadamard transform to the difference block
+ * and then calculating the sum of absolute coefficient values.
+ *
+ * Input Arguments:
+ *
+ * pSrcOrg - Pointer to the original block; must be aligned on a 4-byte
+ * boundary
+ * iStepOrg - Step of the original block buffer; must be a multiple of 4
+ * pSrcRef - Pointer to the reference block; must be aligned on a 4-byte
+ * boundary
+ * iStepRef - Step of the reference block buffer; must be a multiple of 4
+ *
+ * Output Arguments:
+ *
+ * pDstSAD - pointer to the resulting SAD
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL:
+ * pSrcOrg, pSrcRef, or pDstSAD either pSrcOrg
+ * - pSrcRef is not aligned on a 4-byte boundary
+ * - iStepOrg <= 0 or iStepOrg is not a multiple of 4
+ * - iStepRef <= 0 or iStepRef is not a multiple of 4
+ *
+ */
+OMXResult omxVCM4P10_SATD_4x4(
+ const OMX_U8* pSrcOrg,
+ OMX_U32 iStepOrg,
+ const OMX_U8* pSrcRef,
+ OMX_U32 iStepRef,
+ OMX_U32* pDstSAD
+)
+{
+ OMX_INT i, j;
+ OMX_S32 SATD = 0;
+ OMX_S32 d [4][4], m1[4][4], m2[4][4];
+
+ /* check for argument error */
+ armRetArgErrIf(pSrcOrg == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pSrcRef == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pDstSAD == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf((iStepOrg == 0) || (iStepOrg & 3), OMX_Sts_BadArgErr)
+ armRetArgErrIf((iStepRef == 0) || (iStepRef & 3), OMX_Sts_BadArgErr)
+ armRetArgErrIf(armNot4ByteAligned(pSrcOrg), OMX_Sts_BadArgErr)
+ armRetArgErrIf(armNot4ByteAligned(pSrcRef), OMX_Sts_BadArgErr)
+
+ /* Calculate the difference */
+ for (j = 0; j < 4; j++)
+ {
+ for (i = 0; i < 4; i++)
+ {
+ d [j][i] = pSrcOrg [j * iStepOrg + i] - pSrcRef [j * iStepRef + i];
+ }
+ }
+
+ /* Hadamard Transfor for 4x4 block */
+
+ /* Horizontal */
+ for (i = 0; i < 4; i++)
+ {
+ m1[i][0] = d[i][0] + d[i][2]; /* a+c */
+ m1[i][1] = d[i][1] + d[i][3]; /* b+d */
+ m1[i][2] = d[i][0] - d[i][2]; /* a-c */
+ m1[i][3] = d[i][1] - d[i][3]; /* b-d */
+
+ m2[i][0] = m1[i][0] + m1[i][1]; /* a+b+c+d */
+ m2[i][1] = m1[i][2] + m1[i][3]; /* a+b-c-d */
+ m2[i][2] = m1[i][2] - m1[i][3]; /* a-b-c+d */
+ m2[i][3] = m1[i][0] - m1[i][1]; /* a-b+c-d */
+
+ }
+
+ /* Vertical */
+ for (i = 0; i < 4; i++)
+ {
+ m1[0][i] = m2[0][i] + m2[2][i];
+ m1[1][i] = m2[1][i] + m2[3][i];
+ m1[2][i] = m2[0][i] - m2[2][i];
+ m1[3][i] = m2[1][i] - m2[3][i];
+
+ m2[0][i] = m1[0][i] + m1[1][i];
+ m2[1][i] = m1[2][i] + m1[3][i];
+ m2[2][i] = m1[2][i] - m1[3][i];
+ m2[3][i] = m1[0][i] - m1[1][i];
+ }
+
+ /* calculate SAD for Transformed coefficients */
+ for (j = 0; j < 4; j++)
+ {
+ for (i = 0; i < 4; i++)
+ {
+ SATD += armAbs(m2 [j][i]);
+ }
+ }
+
+ *pDstSAD = (SATD + 1) / 2;
+
+ return OMX_Sts_NoErr;
+}
+
+/*****************************************************************************
+ * END OF FILE
+ *****************************************************************************/
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SubAndTransformQDQResidual.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SubAndTransformQDQResidual.c
new file mode 100644
index 0000000..23a5662
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SubAndTransformQDQResidual.c
@@ -0,0 +1,220 @@
+/**
+ *
+ * File Name: omxVCM4P10_SubAndTransformQDQResidual.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ * Description:
+ * This function will calculate SAD for 4x4 blocks
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/**
+ * Function: omxVCM4P10_SubAndTransformQDQResidual (6.3.5.8.1)
+ *
+ * Description:
+ * This function subtracts the prediction signal from the original signal to
+ * produce the difference signal and then performs a 4x4 integer transform and
+ * quantization. The quantized transformed coefficients are stored as
+ * pDstQuantCoeff. This function can also output dequantized coefficients or
+ * unquantized DC coefficients optionally by setting the pointers
+ * pDstDeQuantCoeff, pDCCoeff.
+ *
+ * Input Arguments:
+ *
+ * pSrcOrg - Pointer to original signal. 4-byte alignment required.
+ * pSrcPred - Pointer to prediction signal. 4-byte alignment required.
+ * iSrcOrgStep - Step of the original signal buffer; must be a multiple of
+ * 4.
+ * iSrcPredStep - Step of the prediction signal buffer; must be a multiple
+ * of 4.
+ * pNumCoeff -Number of non-zero coefficients after quantization. If this
+ * parameter is not required, it is set to NULL.
+ * nThreshSAD - Zero-block early detection threshold. If this parameter is
+ * not required, it is set to 0.
+ * iQP - Quantization parameter; must be in the range [0,51].
+ * bIntra - Indicates whether this is an INTRA block, either 1-INTRA or
+ * 0-INTER
+ *
+ * Output Arguments:
+ *
+ * pDstQuantCoeff - Pointer to the quantized transformed coefficients.
+ * 8-byte alignment required.
+ * pDstDeQuantCoeff - Pointer to the dequantized transformed coefficients
+ * if this parameter is not equal to NULL. 8-byte alignment
+ * required.
+ * pDCCoeff - Pointer to the unquantized DC coefficient if this parameter
+ * is not equal to NULL.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL:
+ * pSrcOrg, pSrcPred, pNumCoeff, pDstQuantCoeff,
+ * pDstDeQuantCoeff, pDCCoeff
+ * - pSrcOrg is not aligned on a 4-byte boundary
+ * - pSrcPred is not aligned on a 4-byte boundary
+ * - iSrcOrgStep is not a multiple of 4
+ * - iSrcPredStep is not a multiple of 4
+ * - pDstQuantCoeff or pDstDeQuantCoeff is not aligned on an 8-byte boundary
+ *
+ */
+ OMXResult omxVCM4P10_SubAndTransformQDQResidual (
+ const OMX_U8* pSrcOrg,
+ const OMX_U8* pSrcPred,
+ OMX_U32 iSrcOrgStep,
+ OMX_U32 iSrcPredStep,
+ OMX_S16* pDstQuantCoeff,
+ OMX_S16* pDstDeQuantCoeff,
+ OMX_S16* pDCCoeff,
+ OMX_S8* pNumCoeff,
+ OMX_U32 nThreshSAD,
+ OMX_U32 iQP,
+ OMX_U8 bIntra
+)
+{
+ OMX_INT i, j;
+ OMX_S8 NumCoeff = 0;
+ OMX_S16 Buf[16], m[16];
+ OMX_U32 QBits, QPper, QPmod, f;
+ OMX_S32 Value, MF, ThreshDC;
+
+ /* check for argument error */
+ armRetArgErrIf(pSrcOrg == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pDstDeQuantCoeff == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pNumCoeff == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(pDCCoeff == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(armNot4ByteAligned(pSrcOrg), OMX_Sts_BadArgErr)
+ armRetArgErrIf(pSrcPred == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(armNot4ByteAligned(pSrcPred), OMX_Sts_BadArgErr)
+ armRetArgErrIf(pDstQuantCoeff == NULL, OMX_Sts_BadArgErr)
+ armRetArgErrIf(armNot8ByteAligned(pDstQuantCoeff), OMX_Sts_BadArgErr)
+ armRetArgErrIf((pDstDeQuantCoeff != NULL) &&
+ armNot8ByteAligned(pDstDeQuantCoeff), OMX_Sts_BadArgErr)
+ armRetArgErrIf((bIntra != 0) && (bIntra != 1), OMX_Sts_BadArgErr)
+ armRetArgErrIf(iQP > 51, OMX_Sts_BadArgErr)
+ armRetArgErrIf(iSrcOrgStep == 0, OMX_Sts_BadArgErr)
+ armRetArgErrIf(iSrcPredStep == 0, OMX_Sts_BadArgErr)
+ armRetArgErrIf(iSrcOrgStep & 3, OMX_Sts_BadArgErr)
+ armRetArgErrIf(iSrcPredStep & 3, OMX_Sts_BadArgErr)
+
+ /*
+ * Zero-Block Early detection using nThreshSAD param
+ */
+
+ QPper = iQP / 6;
+ QPmod = iQP % 6;
+ QBits = 15 + QPper;
+
+ f = (1 << QBits) / (bIntra ? 3 : 6);
+
+ /* Do Zero-Block Early detection if enabled */
+ if (nThreshSAD)
+ {
+ ThreshDC = ((1 << QBits) - f) / armVCM4P10_MFMatrix[QPmod][0];
+ if (nThreshSAD < ThreshDC)
+ {
+ /* Set block to zero */
+ if (pDCCoeff != NULL)
+ {
+ *pDCCoeff = 0;
+ }
+
+ for (j = 0; j < 4; j++)
+ {
+ for (i = 0; i < 4; i++)
+ {
+ pDstQuantCoeff [4 * j + i] = 0;
+ if (pDstDeQuantCoeff != NULL)
+ {
+ pDstDeQuantCoeff [4 * j + i] = 0;
+ }
+ }
+ }
+
+ if (pNumCoeff != NULL)
+ {
+ *pNumCoeff = 0;
+ }
+ return OMX_Sts_NoErr;
+ }
+ }
+
+
+ /* Calculate difference */
+ for (j = 0; j < 4; j++)
+ {
+ for (i = 0; i < 4; i++)
+ {
+ Buf [j * 4 + i] =
+ pSrcOrg [j * iSrcOrgStep + i] - pSrcPred [j * iSrcPredStep + i];
+ }
+ }
+
+ /* Residual Transform */
+ armVCM4P10_FwdTransformResidual4x4 (m, Buf);
+
+ if (pDCCoeff != NULL)
+ {
+ /* Copy unquantized DC value into pointer */
+ *pDCCoeff = m[0];
+ }
+
+ /* Quantization */
+ for (j = 0; j < 4; j++)
+ {
+ for (i = 0; i < 4; i++)
+ {
+ MF = armVCM4P10_MFMatrix[QPmod][armVCM4P10_PosToVCol4x4[j * 4 + i]];
+ Value = armAbs(m[j * 4 + i]) * MF + f;
+ Value >>= QBits;
+ Value = m[j * 4 + i] < 0 ? -Value : Value;
+ Buf[4 * j + i] = pDstQuantCoeff [4 * j + i] = (OMX_S16)Value;
+ if ((pNumCoeff != NULL) && Value)
+ {
+ NumCoeff++;
+ }
+ }
+ }
+
+ /* Output number of non-zero Coeffs */
+ if (pNumCoeff != NULL)
+ {
+ *pNumCoeff = NumCoeff;
+ }
+
+ /* Residual Inv Transform */
+ if (pDstDeQuantCoeff != NULL)
+ {
+ /* Re Scale */
+ for (j = 0; j < 4; j++)
+ {
+ for (i = 0; i < 4; i++)
+ {
+ m [j * 4 + i] = Buf [j * 4 + i] * (1 << QPper) *
+ armVCM4P10_VMatrix[QPmod][armVCM4P10_PosToVCol4x4[j * 4 + i]];
+ }
+ }
+ armVCM4P10_TransformResidual4x4 (pDstDeQuantCoeff, m);
+ }
+
+ return OMX_Sts_NoErr;
+}
+
+/*****************************************************************************
+ * END OF FILE
+ *****************************************************************************/
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformDequantChromaDCFromPair.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformDequantChromaDCFromPair.c
new file mode 100644
index 0000000..9ad0e81
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformDequantChromaDCFromPair.c
@@ -0,0 +1,131 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: omxVCM4P10_TransformDequantChromaDCFromPair.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * H.264 inverse quantize and transform module
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/*
+ * Description:
+ * Dequantize Chroma 2x2 DC block
+ */
+
+static void DequantChromaDC2x2(
+ OMX_S16* pDst,
+ OMX_INT QP
+)
+{
+ int Shift = (QP/6)-1 ;
+ int Scale = armVCM4P10_VMatrix[QP%6][0];
+ int i, Value;
+
+ if (Shift >= 0)
+ {
+ for (i=0; i<4; i++)
+ {
+ Value = (pDst[i] * Scale) << Shift;
+ pDst[i] = (OMX_S16)Value;
+ }
+ }
+ else
+ {
+ for (i=0; i<4; i++)
+ {
+ Value = (pDst[i] * Scale) >> 1;
+ pDst[i] = (OMX_S16)Value;
+ }
+ }
+}
+
+
+/*
+ * Description:
+ * Inverse Transform DC 2x2 Coefficients
+ */
+
+static void InvTransformDC2x2(OMX_S16* pData)
+{
+ int c00 = pData[0];
+ int c01 = pData[1];
+ int c10 = pData[2];
+ int c11 = pData[3];
+
+ int d00 = c00 + c01;
+ int d01 = c00 - c01;
+ int d10 = c10 + c11;
+ int d11 = c10 - c11;
+
+ pData[0] = (OMX_S16)(d00 + d10);
+ pData[1] = (OMX_S16)(d01 + d11);
+ pData[2] = (OMX_S16)(d00 - d10);
+ pData[3] = (OMX_S16)(d01 - d11);
+}
+
+
+/**
+ * Function: omxVCM4P10_TransformDequantChromaDCFromPair (6.3.4.2.2)
+ *
+ * Description:
+ * Reconstruct the 2x2 ChromaDC block from coefficient-position pair buffer,
+ * perform integer inverse transformation, and dequantization for 2x2 chroma
+ * DC coefficients, and update the pair buffer pointer to next non-empty
+ * block.
+ *
+ * Input Arguments:
+ *
+ * ppSrc - Double pointer to residual coefficient-position pair buffer
+ * output by CALVC decoding
+ * QP - Quantization parameter QpC
+ *
+ * Output Arguments:
+ *
+ * ppSrc - *ppSrc is updated to the start of next non empty block
+ * pDst - Pointer to the reconstructed 2x2 ChromaDC coefficients buffer;
+ * must be aligned on a 4-byte boundary.
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - ppSrc or pDst is NULL.
+ * - pDst is not 4-byte aligned.
+ * - QP is not in the range of [0-51].
+ *
+ */
+
+OMXResult omxVCM4P10_TransformDequantChromaDCFromPair(
+ const OMX_U8 **ppSrc,
+ OMX_S16* pDst,
+ OMX_INT QP
+ )
+{
+ armRetArgErrIf(ppSrc == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(*ppSrc == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot4ByteAligned(pDst), OMX_Sts_BadArgErr);
+ armRetArgErrIf(QP<0, OMX_Sts_BadArgErr);
+ armRetArgErrIf(QP>51, OMX_Sts_BadArgErr);
+
+ armVCM4P10_UnpackBlock2x2(ppSrc, pDst);
+ InvTransformDC2x2(pDst);
+ DequantChromaDC2x2(pDst, QP);
+
+ return OMX_Sts_NoErr;
+}
+
+/* End of file */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformDequantLumaDCFromPair.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformDequantLumaDCFromPair.c
new file mode 100644
index 0000000..16c8be1
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformDequantLumaDCFromPair.c
@@ -0,0 +1,148 @@
+/* ----------------------------------------------------------------
+ *
+ *
+ * File Name: omxVCM4P10_TransformDequantLumaDCFromPair.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * H.264 inverse quantize and transform module
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/*
+ * Description:
+ * Dequantize Luma DC block
+ */
+
+static void DequantLumaDC4x4(
+ OMX_S16* pDst,
+ OMX_INT QP
+)
+{
+ int Shift = (QP/6)-2 ;
+ int Scale = armVCM4P10_VMatrix[QP%6][0];
+ int i, Round, Value;
+
+ if (Shift >= 0)
+ {
+ for (i=0; i<16; i++)
+ {
+ Value = (pDst[i] * Scale) << Shift;
+ pDst[i] = (OMX_S16)Value;
+ }
+ }
+ else
+ {
+ Shift = -Shift;;
+ Round = 1<<(Shift-1);
+
+ for (i=0; i<16; i++)
+ {
+ Value = (pDst[i] * Scale + Round) >> Shift;
+ pDst[i] = (OMX_S16)Value;
+ }
+ }
+}
+
+
+
+/*
+ * Description:
+ * Inverse Transform DC 4x4 Coefficients
+ */
+static void InvTransformDC4x4(OMX_S16* pData)
+{
+ int i;
+
+ /* Transform rows */
+ for (i=0; i<16; i+=4)
+ {
+ int c0 = pData[i+0];
+ int c1 = pData[i+1];
+ int c2 = pData[i+2];
+ int c3 = pData[i+3];
+ pData[i+0] = (OMX_S16)(c0+c1+c2+c3);
+ pData[i+1] = (OMX_S16)(c0+c1-c2-c3);
+ pData[i+2] = (OMX_S16)(c0-c1-c2+c3);
+ pData[i+3] = (OMX_S16)(c0-c1+c2-c3);
+ }
+
+ /* Transform columns */
+ for (i=0; i<4; i++)
+ {
+ int c0 = pData[i+0];
+ int c1 = pData[i+4];
+ int c2 = pData[i+8];
+ int c3 = pData[i+12];
+ pData[i+0] = (OMX_S16)(c0+c1+c2+c3);
+ pData[i+4] = (OMX_S16)(c0+c1-c2-c3);
+ pData[i+8] = (OMX_S16)(c0-c1-c2+c3);
+ pData[i+12] = (OMX_S16)(c0-c1+c2-c3);
+ }
+}
+
+
+/**
+ * Function: omxVCM4P10_TransformDequantLumaDCFromPair (6.3.4.2.1)
+ *
+ * Description:
+ * Reconstructs the 4x4 LumaDC block from the coefficient-position pair
+ * buffer, performs integer inverse, and dequantization for 4x4 LumaDC
+ * coefficients, and updates the pair buffer pointer to the next non-empty
+ * block.
+ *
+ * Input Arguments:
+ *
+ * ppSrc - Double pointer to residual coefficient-position pair buffer
+ * output by CALVC decoding
+ * QP - Quantization parameter QpY
+ *
+ * Output Arguments:
+ *
+ * ppSrc - *ppSrc is updated to the start of next non empty block
+ * pDst - Pointer to the reconstructed 4x4 LumaDC coefficients buffer; must
+ * be aligned on a 8-byte boundary.
+ *
+ * Return Value:
+ * OMX_Sts_NoErr, if the function runs without error.
+ * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
+ * - ppSrc or pDst is NULL.
+ * - pDst is not 8 byte aligned.
+ * - QP is not in the range of [0-51].
+ *
+ */
+
+OMXResult omxVCM4P10_TransformDequantLumaDCFromPair(
+ const OMX_U8 **ppSrc,
+ OMX_S16* pDst,
+ OMX_INT QP
+ )
+{
+ armRetArgErrIf(ppSrc == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(*ppSrc == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot8ByteAligned(pDst), OMX_Sts_BadArgErr);
+ armRetArgErrIf(QP<0, OMX_Sts_BadArgErr);
+ armRetArgErrIf(QP>51, OMX_Sts_BadArgErr);
+
+ armVCM4P10_UnpackBlock4x4(ppSrc, pDst);
+ /*InvTransformDequantLumaDC4x4(pDst, QP);*/
+ InvTransformDC4x4(pDst);
+ DequantLumaDC4x4(pDst, QP);
+
+ return OMX_Sts_NoErr;
+}
+
+/* End of file */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformQuant_ChromaDC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformQuant_ChromaDC.c
new file mode 100644
index 0000000..b5544dd
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformQuant_ChromaDC.c
@@ -0,0 +1,97 @@
+/**
+ *
+ * File Name: omxVCM4P10_TransformQuant_ChromaDC.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ * Description:
+ * This function will calculate 4x4 hadamard transform of chroma DC
+ * coefficients and quantization
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armVC.h"
+#include "armCOMM.h"
+
+/**
+ * Function: omxVCM4P10_TransformQuant_ChromaDC (6.3.5.6.1)
+ *
+ * Description:
+ * This function performs 2x2 Hadamard transform of chroma DC coefficients
+ * and then quantizes the coefficients.
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - Pointer to the 2x2 array of chroma DC coefficients. 8-byte
+ * alignment required.
+ * iQP - Quantization parameter; must be in the range [0,51].
+ * bIntra - Indicate whether this is an INTRA block. 1-INTRA, 0-INTER
+ *
+ * Output Arguments:
+ *
+ * pSrcDst - Pointer to transformed and quantized coefficients. 8-byte
+ * alignment required.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL:
+ * pSrcDst
+ * - pSrcDst is not aligned on an 8-byte boundary
+ *
+ */
+OMXResult omxVCM4P10_TransformQuant_ChromaDC(
+ OMX_S16* pSrcDst,
+ OMX_U32 iQP,
+ OMX_U8 bIntra
+)
+{
+ OMX_INT i, j;
+ OMX_S32 m[2][2];
+ OMX_S32 Value;
+ OMX_S32 QbitsPlusOne, Two_f, MF00;
+
+ /* Check for argument error */
+ armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot8ByteAligned(pSrcDst), OMX_Sts_BadArgErr);
+ armRetArgErrIf(iQP > 51, OMX_Sts_BadArgErr);
+
+ /* Hadamard Transform for 2x2 block */
+ m[0][0] = pSrcDst[0] + pSrcDst[1] + pSrcDst[2] + pSrcDst[3];
+ m[0][1] = pSrcDst[0] - pSrcDst[1] + pSrcDst[2] - pSrcDst[3];
+ m[1][0] = pSrcDst[0] + pSrcDst[1] - pSrcDst[2] - pSrcDst[3];
+ m[1][1] = pSrcDst[0] - pSrcDst[1] - pSrcDst[2] + pSrcDst[3];
+
+ /* Quantization */
+ QbitsPlusOne = ARM_M4P10_Q_OFFSET + 1 + (iQP / 6); /*floor (QP/6)*/
+ MF00 = armVCM4P10_MFMatrix [iQP % 6][0];
+
+ Two_f = (1 << QbitsPlusOne) / (bIntra ? 3 : 6); /* 3->INTRA, 6->INTER */
+
+ /* Scaling */
+ for (j = 0; j < 2; j++)
+ {
+ for (i = 0; i < 2; i++)
+ {
+ Value = (armAbs(m[j][i]) * MF00 + Two_f) >> QbitsPlusOne;
+ pSrcDst[j * 2 + i] = (OMX_S16)((m[j][i] < 0) ? -Value : Value);
+ }
+ }
+
+ return OMX_Sts_NoErr;
+}
+
+/*****************************************************************************
+ * END OF FILE
+ *****************************************************************************/
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformQuant_LumaDC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformQuant_LumaDC.c
new file mode 100644
index 0000000..2ccf7f0
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformQuant_LumaDC.c
@@ -0,0 +1,119 @@
+/**
+ *
+ * File Name: omxVCM4P10_TransformQuant_LumaDC.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ * Description:
+ * This function will calculate 4x4 hadamard transform of luma DC coefficients
+ * and quantization
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/**
+ * Function: omxVCM4P10_TransformQuant_LumaDC (6.3.5.6.2)
+ *
+ * Description:
+ * This function performs a 4x4 Hadamard transform of luma DC coefficients
+ * and then quantizes the coefficients.
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - Pointer to the 4x4 array of luma DC coefficients. 16-byte
+ * alignment required.
+ * iQP - Quantization parameter; must be in the range [0,51].
+ *
+ * Output Arguments:
+ *
+ * pSrcDst - Pointer to transformed and quantized coefficients. 16-byte
+ * alignment required.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned if any of the following
+ * conditions are true:
+ * - at least one of the following pointers is NULL: pSrcDst
+ * - pSrcDst is not aligned on an 16-byte boundary
+ *
+ */
+OMXResult omxVCM4P10_TransformQuant_LumaDC(
+ OMX_S16* pSrcDst,
+ OMX_U32 iQP
+)
+{
+ OMX_INT i, j;
+ OMX_S32 m1[4][4], m2[4][4];
+ OMX_S32 Value;
+ OMX_U32 QbitsPlusOne, Two_f, MF;
+
+ /* Check for argument error */
+ armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(armNot16ByteAligned(pSrcDst), OMX_Sts_BadArgErr);
+ armRetArgErrIf(iQP > 51, OMX_Sts_BadArgErr);
+
+ /* Hadamard Transform for 4x4 block */
+ /* Horizontal Hadamard */
+ for (i = 0; i < 4; i++)
+ {
+ j = i * 4;
+
+ m1[i][0] = pSrcDst[j + 0] + pSrcDst[j + 2]; /* a+c */
+ m1[i][1] = pSrcDst[j + 1] + pSrcDst[j + 3]; /* b+d */
+ m1[i][2] = pSrcDst[j + 0] - pSrcDst[j + 2]; /* a-c */
+ m1[i][3] = pSrcDst[j + 1] - pSrcDst[j + 3]; /* b-d */
+
+ m2[i][0] = m1[i][0] + m1[i][1]; /* a+b+c+d */
+ m2[i][1] = m1[i][2] + m1[i][3]; /* a+b-c-d */
+ m2[i][2] = m1[i][2] - m1[i][3]; /* a-b-c+d */
+ m2[i][3] = m1[i][0] - m1[i][1]; /* a-b+c-d */
+
+ }
+
+ /* Vertical */
+ for (i = 0; i < 4; i++)
+ {
+ m1[0][i] = m2[0][i] + m2[2][i];
+ m1[1][i] = m2[1][i] + m2[3][i];
+ m1[2][i] = m2[0][i] - m2[2][i];
+ m1[3][i] = m2[1][i] - m2[3][i];
+
+ m2[0][i] = m1[0][i] + m1[1][i];
+ m2[1][i] = m1[2][i] + m1[3][i];
+ m2[2][i] = m1[2][i] - m1[3][i];
+ m2[3][i] = m1[0][i] - m1[1][i];
+ }
+
+
+ /* Quantization */
+ QbitsPlusOne = ARM_M4P10_Q_OFFSET + 1 + (iQP / 6); /*floor (QP/6)*/
+ Two_f = (1 << QbitsPlusOne) / 3; /* 3->INTRA, 6->INTER */
+ MF = armVCM4P10_MFMatrix [iQP % 6][0];
+
+ /* Scaling */
+ for (j = 0; j < 4; j++)
+ {
+ for (i = 0; i < 4; i++)
+ {
+ Value = (armAbs((m2[j][i]/* + 1*/) / 2) * MF + Two_f) >> QbitsPlusOne;
+ pSrcDst[j * 4 + i] = (OMX_S16)((m2[j][i] < 0) ? -Value : Value);
+ }
+ }
+ return OMX_Sts_NoErr;
+}
+
+/*****************************************************************************
+ * END OF FILE
+ *****************************************************************************/
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/api/armVCM4P2_DCT_Table.h b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/api/armVCM4P2_DCT_Table.h
new file mode 100644
index 0000000..3255b61
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/api/armVCM4P2_DCT_Table.h
@@ -0,0 +1,30 @@
+/**
+ *
+ * File Name: armVCM4P2_DCT_Table.h
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ *
+ * File: armVCM4P2_DCT_Table.h
+ * Description: Declares Tables used for DCT/IDCT module
+ * in MP4P2 codec.
+ *
+ */
+
+#ifndef _OMXDCTTAB_H_
+#define _OMXDCTTAB_H_
+
+extern const OMX_F64 armVCM4P2_preCalcDCTCos[8][8];
+
+#endif /* _OMXDCTTAB_H_ */
+
+
+/* End of file */
+
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/api/armVCM4P2_Huff_Tables_VLC.h b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/api/armVCM4P2_Huff_Tables_VLC.h
new file mode 100644
index 0000000..92ecc05
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/api/armVCM4P2_Huff_Tables_VLC.h
@@ -0,0 +1,42 @@
+/**
+ *
+ * File Name: armVCM4P2_Huff_Tables_VLC.h
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ *
+ * File: armVCM4P2_Huff_Tables.h
+ * Description: Declares Tables used for Hufffman coding and decoding
+ * in MP4P2 codec.
+ *
+ */
+
+#ifndef _OMXHUFFTAB_H_
+#define _OMXHUFFTAB_H_
+
+extern const OMX_U8 armVCM4P2_IntraL0RunIdx[11];
+extern const ARM_VLC32 armVCM4P2_IntraVlcL0[68];
+extern const OMX_U8 armVCM4P2_IntraL1RunIdx[7];
+extern const ARM_VLC32 armVCM4P2_IntraVlcL1[36];
+extern const OMX_U8 armVCM4P2_IntraL0LMAX[15];
+extern const OMX_U8 armVCM4P2_IntraL1LMAX[21];
+extern const OMX_U8 armVCM4P2_IntraL0RMAX[27];
+extern const OMX_U8 armVCM4P2_IntraL1RMAX[8];
+extern const OMX_U8 armVCM4P2_InterL0RunIdx[12];
+extern const ARM_VLC32 armVCM4P2_InterVlcL0[59];
+extern const OMX_U8 armVCM4P2_InterL1RunIdx[3];
+extern const ARM_VLC32 armVCM4P2_InterVlcL1[45];
+extern const OMX_U8 armVCM4P2_InterL0LMAX[27];
+extern const OMX_U8 armVCM4P2_InterL1LMAX[41];
+extern const OMX_U8 armVCM4P2_InterL0RMAX[12];
+extern const OMX_U8 armVCM4P2_InterL1RMAX[3];
+extern const ARM_VLC32 armVCM4P2_aIntraDCLumaIndex[14];
+extern const ARM_VLC32 armVCM4P2_aIntraDCChromaIndex[14];
+extern const ARM_VLC32 armVCM4P2_aVlcMVD[66];
+
+#endif /* _OMXHUFFTAB_H_ */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/api/armVCM4P2_ZigZag_Tables.h b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/api/armVCM4P2_ZigZag_Tables.h
new file mode 100644
index 0000000..c75ed89
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/api/armVCM4P2_ZigZag_Tables.h
@@ -0,0 +1,25 @@
+/**
+ *
+ * File Name: armVCM4P2_ZigZag_Tables.h
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ *
+ * File: armVCM4P2_Zigzag_Tables.h
+ * Description: Declares Tables used for Zigzag scan in MP4P2 codec.
+ *
+ */
+
+#ifndef _OMXZIGZAGTAB_H_
+#define _OMXZIGZAGTAB_H_
+
+extern const OMX_U8 armVCM4P2_aClassicalZigzagScan [64];
+extern const OMX_U8 armVCM4P2_aHorizontalZigzagScan [64];
+extern const OMX_U8 armVCM4P2_aVerticalZigzagScan [64];
+
+#endif /* _OMXZIGZAGTAB_H_ */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_ACDCPredict.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_ACDCPredict.c
new file mode 100644
index 0000000..b6a396a
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_ACDCPredict.c
@@ -0,0 +1,253 @@
+/**
+ *
+ * File Name: armVCM4P2_ACDCPredict.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains module for DC/AC coefficient prediction
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+
+#include "armVC.h"
+#include "armCOMM.h"
+
+/**
+ * Function: armVCM4P2_ACDCPredict
+ *
+ * Description:
+ * Performs adaptive DC/AC coefficient prediction for an intra block. Prior
+ * to the function call, prediction direction (predDir) should be selected
+ * as specified in subclause 7.4.3.1 of ISO/IEC 14496-2.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] pSrcDst pointer to the coefficient buffer which contains
+ * the quantized coefficient residuals (PQF) of the
+ * current block
+ * [in] pPredBufRow pointer to the coefficient row buffer
+ * [in] pPredBufCol pointer to the coefficient column buffer
+ * [in] curQP quantization parameter of the current block. curQP
+ * may equal to predQP especially when the current
+ * block and the predictor block are in the same
+ * macroblock.
+ * [in] predQP quantization parameter of the predictor block
+ * [in] predDir indicates the prediction direction which takes one
+ * of the following values:
+ * OMX_VC_HORIZONTAL predict horizontally
+ * OMX_VC_VERTICAL predict vertically
+ * [in] ACPredFlag a flag indicating if AC prediction should be
+ * performed. It is equal to ac_pred_flag in the bit
+ * stream syntax of MPEG-4
+ * [in] videoComp video component type (luminance, chrominance or
+ * alpha) of the current block
+ * [in] flag This flag defines the if one wants to use this functions to
+ * calculate PQF (set 1, prediction) or QF (set 0, reconstruction)
+ * [out] pPreACPredict pointer to the predicted coefficients buffer.
+ * Filled ONLY if it is not NULL
+ * [out] pSrcDst pointer to the coefficient buffer which contains
+ * the quantized coefficients (QF) of the current
+ * block
+ * [out] pPredBufRow pointer to the updated coefficient row buffer
+ * [out] pPredBufCol pointer to the updated coefficient column buffer
+ * [out] pSumErr pointer to the updated sum of the difference
+ * between predicted and unpredicted coefficients
+ * If this is NULL, do not update
+ *
+ * Return Value:
+ * Standard OMXResult result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armVCM4P2_ACDCPredict(
+ OMX_S16 * pSrcDst,
+ OMX_S16 * pPreACPredict,
+ OMX_S16 * pPredBufRow,
+ OMX_S16 * pPredBufCol,
+ OMX_INT curQP,
+ OMX_INT predQP,
+ OMX_INT predDir,
+ OMX_INT ACPredFlag,
+ OMXVCM4P2VideoComponent videoComp,
+ OMX_U8 flag,
+ OMX_INT *pSumErr
+)
+{
+ OMX_INT dcScaler, i;
+ OMX_S16 tempPred;
+
+ /* Argument error checks */
+ armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pPredBufRow == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pPredBufCol == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(curQP <= 0, OMX_Sts_BadArgErr);
+ armRetArgErrIf(predQP <= 0, OMX_Sts_BadArgErr);
+ armRetArgErrIf((predDir != 1) && (predDir != 2), OMX_Sts_BadArgErr);
+ armRetArgErrIf(!armIs4ByteAligned(pSrcDst), OMX_Sts_BadArgErr);
+ armRetArgErrIf(!armIs4ByteAligned(pPredBufRow), OMX_Sts_BadArgErr);
+ armRetArgErrIf(!armIs4ByteAligned(pPredBufCol), OMX_Sts_BadArgErr);
+
+
+ /* Set DC scaler value to avoid some compilers giving a warning. */
+ dcScaler=0;
+
+ /* Calculate the DC scaler value */
+ if (videoComp == OMX_VC_LUMINANCE)
+ {
+ if (curQP >= 1 && curQP <= 4)
+ {
+ dcScaler = 8;
+ }
+ else if (curQP >= 5 && curQP <= 8)
+ {
+ dcScaler = 2 * curQP;
+ }
+ else if (curQP >= 9 && curQP <= 24)
+ {
+ dcScaler = curQP + 8;
+ }
+ else
+ {
+ dcScaler = (2 * curQP) - 16;
+ }
+ }
+ else if (videoComp == OMX_VC_CHROMINANCE)
+ {
+ if (curQP >= 1 && curQP <= 4)
+ {
+ dcScaler = 8;
+ }
+ else if (curQP >= 5 && curQP <= 24)
+ {
+ dcScaler = (curQP + 13)/2;
+ }
+ else
+ {
+ dcScaler = curQP - 6;
+ }
+ }
+
+ if (pPreACPredict != NULL)
+ {
+ pPreACPredict[0] = predDir;
+ }
+
+ if (predDir == OMX_VC_VERTICAL)
+ {
+ /* F[0][0]//dc_scaler */
+ tempPred = armIntDivAwayFromZero(pPredBufRow[0], dcScaler);
+ }
+ else
+ {
+ /* F[0][0]//dc_scaler */
+ tempPred = armIntDivAwayFromZero(pPredBufCol[0], dcScaler);
+ }
+
+ /* Updating the DC value to the row and col buffer */
+ *(pPredBufRow - 8) = *pPredBufCol;
+
+ if (flag)
+ {
+ /* Cal and store F[0][0] into the col buffer */
+ *pPredBufCol = pSrcDst[0] * dcScaler;
+
+ /* PQF = QF - F[0][0]//dc_scaler */
+ pSrcDst[0] -= tempPred;
+ }
+ else
+ {
+ /* QF = PQF + F[0][0]//dc_scaler */
+ pSrcDst[0] += tempPred;
+
+ /* Saturate */
+ pSrcDst[0] = armClip (-2048, 2047, pSrcDst[0]);
+
+ /* Cal and store F[0][0] into the col buffer */
+ *pPredBufCol = pSrcDst[0] * dcScaler;
+ }
+
+
+ if (ACPredFlag == 1)
+ {
+ if (predDir == OMX_VC_VERTICAL)
+ {
+ for (i = 1; i < 8; i++)
+ {
+ tempPred = armIntDivAwayFromZero \
+ (pPredBufRow[i] * predQP, curQP);
+ if (flag)
+ {
+ /* Updating QF to the row buff */
+ pPredBufRow[i] = pSrcDst[i];
+ /*PQFX[v][0] = QFX[v][0] - (QFA[v][0] * QPA) // QPX */
+ pSrcDst[i] -= tempPred;
+ /* Sum of absolute values of AC prediction error, this can
+ be used as a reference to choose whether to use
+ AC prediction */
+ *pSumErr += armAbs(pSrcDst[i]);
+ /* pPreACPredict[1~7] store the error signal
+ after AC prediction */
+ pPreACPredict[i] = pSrcDst[i];
+ }
+ else
+ {
+ /*QFX[v][0] = PQFX[v][0] + (QFA[v][0] * QPA) // QPX */
+ pSrcDst[i] += tempPred;
+
+ /* Saturate */
+ pSrcDst[i] = armClip (-2048, 2047, pSrcDst[i]);
+
+ /* Updating QF to the row buff */
+ pPredBufRow[i] = pSrcDst[i];
+ }
+ }
+ }
+ else
+ {
+ for (i = 8; i < 64; i += 8)
+ {
+ tempPred = armIntDivAwayFromZero \
+ (pPredBufCol[i>>3] * predQP, curQP);
+ if (flag)
+ {
+ /* Updating QF to col buff */
+ pPredBufCol[i>>3] = pSrcDst[i];
+ /*PQFX[0][u] = QFX[0][u] - (QFA[0][u] * QPA) // QPX */
+ pSrcDst[i] -= tempPred;
+ /* Sum of absolute values of AC prediction error, this can
+ be used as a reference to choose whether to use AC
+ prediction */
+ *pSumErr += armAbs(pSrcDst[i]);
+ /* pPreACPredict[1~7] store the error signal
+ after AC prediction */
+ pPreACPredict[i>>3] = pSrcDst[i];
+ }
+ else
+ {
+ /*QFX[0][u] = PQFX[0][u] + (QFA[0][u] * QPA) // QPX */
+ pSrcDst[i] += tempPred;
+
+ /* Saturate */
+ pSrcDst[i] = armClip (-2048, 2047, pSrcDst[i]);
+
+ /* Updating QF to col buff */
+ pPredBufCol[i>>3] = pSrcDst[i];
+ }
+ }
+ }
+ }
+
+ return OMX_Sts_NoErr;
+}
+
+/*End of File*/
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_BlockMatch_Half.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_BlockMatch_Half.c
new file mode 100644
index 0000000..1b69a33
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_BlockMatch_Half.c
@@ -0,0 +1,187 @@
+/**
+ *
+ * File Name: armVCM4P2_BlockMatch_Half.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains modules for Block matching, a full search algorithm
+ * is implemented
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armVC.h"
+#include "armCOMM.h"
+
+/**
+ * Function: armVCM4P2_BlockMatch_Half
+ *
+ * Description:
+ * Performs a 16x16 block match with half-pixel resolution. Returns the estimated
+ * motion vector and associated minimum SAD. This function estimates the half-pixel
+ * motion vector by interpolating the integer resolution motion vector referenced
+ * by the input parameter pSrcDstMV, i.e., the initial integer MV is generated
+ * externally. The input parameters pSrcRefBuf and pSearchPointRefPos should be
+ * shifted by the winning MV of 16x16 integer search prior to calling BlockMatch_Half_16x16.
+ * The function BlockMatch_Integer_16x16 may be used for integer motion estimation.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] pSrcRefBuf pointer to the reference Y plane; points to the reference MB
+ * that corresponds to the location of the current macroblock in
+ * the current plane.
+ * [in] refWidth width of the reference plane
+ * [in] pRefRect reference plane valid region rectangle
+ * [in] pSrcCurrBuf pointer to the current macroblock extracted from original plane
+ * (linear array, 256 entries); must be aligned on an 8-byte boundary.
+ * [in] pSearchPointRefPos position of the starting point for half pixel search (specified
+ * in terms of integer pixel units) in the reference plane.
+ * [in] rndVal rounding control bit for half pixel motion estimation;
+ * 0=rounding control disabled; 1=rounding control enabled
+ * [in] pSrcDstMV pointer to the initial MV estimate; typically generated during a prior
+ * 16X16 integer search and its unit is half pixel.
+ * [in] BlockSize MacroBlock Size i.e either 16x16 or 8x8.
+ * [out]pSrcDstMV pointer to estimated MV
+ * [out]pDstSAD pointer to minimum SAD
+ *
+ * Return Value:
+ * OMX_Sts_NoErr ¨C no error
+ * OMX_Sts_BadArgErr ¨C bad arguments
+ *
+ */
+
+OMXResult armVCM4P2_BlockMatch_Half(
+ const OMX_U8 *pSrcRefBuf,
+ OMX_INT refWidth,
+ const OMXRect *pRefRect,
+ const OMX_U8 *pSrcCurrBuf,
+ const OMXVCM4P2Coordinate *pSearchPointRefPos,
+ OMX_INT rndVal,
+ OMXVCMotionVector *pSrcDstMV,
+ OMX_INT *pDstSAD,
+ OMX_U8 BlockSize
+)
+{
+ OMX_INT outer, inner, count, index;
+ OMX_S16 halfPelX = 0, halfPelY = 0, x, y;
+ OMX_INT candSAD, refSAD = 0;
+ OMX_INT minSAD, fromX, toX, fromY, toY;
+ /* Offset to the reference at the begining of the bounding box */
+ const OMX_U8 *pTempSrcRefBuf;
+ OMX_U8 tempPel;
+
+ /* Argument error checks */
+ armRetArgErrIf(pSrcRefBuf == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pRefRect == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pSrcCurrBuf == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pSearchPointRefPos == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pSrcDstMV == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pDstSAD == NULL, OMX_Sts_BadArgErr);
+
+ /* Positioning the pointer */
+ pTempSrcRefBuf = pSrcRefBuf + (refWidth * (pSrcDstMV->dy/2)) + (pSrcDstMV->dx/2);
+
+ /* Copy the candidate to the temporary linear array */
+ for (outer = 0, count = 0,index = 0;
+ outer < BlockSize;
+ outer++, index += refWidth - BlockSize)
+ {
+ for (inner = 0; inner < BlockSize; inner++, count++, index++)
+ {
+ refSAD += armAbs (pTempSrcRefBuf[index] - pSrcCurrBuf[count]);
+ }
+ }
+
+ /* Set the minSad as reference SAD */
+ minSAD = refSAD;
+ *pDstSAD = refSAD;
+
+ /* Check for valid region */
+ fromX = 1;
+ toX = 1;
+ fromY = 1;
+ toY = 1;
+ if ((pSearchPointRefPos->x - 1) < pRefRect->x)
+ {
+ fromX = 0;
+ }
+
+ if ((pSearchPointRefPos->x + BlockSize + 1) > (pRefRect->x + pRefRect->width))
+ {
+ toX = 0;
+ }
+
+ if ((pSearchPointRefPos->y - 1) < pRefRect->y)
+ {
+ fromY = 0;
+ }
+
+ if ((pSearchPointRefPos->y + BlockSize + 1) > (pRefRect->y + pRefRect->height))
+ {
+ toY = 0;
+ }
+
+ /* Looping on y- axis */
+ for (y = -fromY; y <= toY; y++)
+ {
+ /* Looping on x- axis */
+ for (x = -fromX; x <= toX; x++)
+ {
+ /* check for integer position */
+ if ( x == 0 && y == 0)
+ {
+ continue;
+ }
+ /* Positioning the pointer */
+ pTempSrcRefBuf = pSrcRefBuf + (refWidth * (pSrcDstMV->dy/2))
+ + (pSrcDstMV->dx/2);
+
+ /* Interpolate the pixel and calculate the SAD*/
+ for (outer = 0, count = 0, candSAD = 0,index = 0;
+ outer < BlockSize;
+ outer++, index += refWidth - BlockSize)
+ {
+ for (inner = 0; inner < BlockSize; inner++, count++,index++)
+ {
+ tempPel = (
+ pTempSrcRefBuf[index]
+ + pTempSrcRefBuf[index + x] * armAbs(x)
+ + pTempSrcRefBuf[index + refWidth * y] * armAbs(y)
+ + pTempSrcRefBuf[index + refWidth * y + x]
+ * armAbs(x*y)
+ + armAbs (x) + armAbs (y) - rndVal
+ ) / (2 * (armAbs (x) + armAbs (y)));
+ candSAD += armAbs (tempPel - pSrcCurrBuf[count]);
+ }
+ }
+
+ /* Result calculations */
+ if (armVCM4P2_CompareMV (x, y, candSAD, halfPelX, halfPelY, minSAD))
+ {
+ *pDstSAD = candSAD;
+ minSAD = candSAD;
+ halfPelX = x;
+ halfPelY = y;
+ }
+
+ } /* End of x- axis */
+ } /* End of y-axis */
+
+ pSrcDstMV->dx += halfPelX;
+ pSrcDstMV->dy += halfPelY;
+
+ return OMX_Sts_NoErr;
+
+}
+
+/* End of file */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_BlockMatch_Integer.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_BlockMatch_Integer.c
new file mode 100644
index 0000000..77fe358
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_BlockMatch_Integer.c
@@ -0,0 +1,167 @@
+/**
+ *
+ * File Name: armVCM4P2_BlockMatch_Integer.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains modules for Block matching, a full search algorithm
+ * is implemented
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armVC.h"
+#include "armCOMM.h"
+
+/**
+ * Function: armVCM4P2_BlockMatch_Integer
+ *
+ * Description:
+ * Performs a 16x16 block search; estimates motion vector and associated minimum SAD.
+ * Both the input and output motion vectors are represented using half-pixel units, and
+ * therefore a shift left or right by 1 bit may be required, respectively, to match the
+ * input or output MVs with other functions that either generate output MVs or expect
+ * input MVs represented using integer pixel units.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] pSrcRefBuf pointer to the reference Y plane; points to the reference MB that
+ * corresponds to the location of the current macroblock in the current
+ * plane.
+ * [in] refWidth width of the reference plane
+ * [in] pRefRect pointer to the valid rectangular in reference plane. Relative to image origin.
+ * It's not limited to the image boundary, but depended on the padding. For example,
+ * if you pad 4 pixels outside the image border, then the value for left border
+ * can be -4
+ * [in] pSrcCurrBuf pointer to the current macroblock extracted from original plane (linear array,
+ * 256 entries); must be aligned on an 8-byte boundary.
+ * [in] pCurrPointPos position of the current macroblock in the current plane
+ * [in] pSrcPreMV pointer to predicted motion vector; NULL indicates no predicted MV
+ * [in] pSrcPreSAD pointer to SAD associated with the predicted MV (referenced by pSrcPreMV)
+ * [in] searchRange search range for 16X16 integer block,the units of it is full pixel,the search range
+ * is the same in all directions.It is in inclusive of the boundary and specified in
+ * terms of integer pixel units.
+ * [in] pMESpec vendor-specific motion estimation specification structure; must have been allocated
+ * and then initialized using omxVCM4P2_MEInit prior to calling the block matching
+ * function.
+ * [out] pDstMV pointer to estimated MV
+ * [out] pDstSAD pointer to minimum SAD
+ *
+ * Return Value:
+ * OMX_Sts_NoErr ¨C no error.
+ * OMX_Sts_BadArgErr ¨C bad arguments
+ *
+ */
+
+OMXResult armVCM4P2_BlockMatch_Integer(
+ const OMX_U8 *pSrcRefBuf,
+ OMX_INT refWidth,
+ const OMXRect *pRefRect,
+ const OMX_U8 *pSrcCurrBuf,
+ const OMXVCM4P2Coordinate *pCurrPointPos,
+ const OMXVCMotionVector *pSrcPreMV,
+ const OMX_INT *pSrcPreSAD,
+ void *pMESpec,
+ OMXVCMotionVector *pDstMV,
+ OMX_INT *pDstSAD,
+ OMX_U8 BlockSize
+)
+{
+
+ /* Definitions and Initializations*/
+
+ OMX_INT outer, inner, count,index;
+ OMX_INT candSAD;
+ /*(256*256 +1) this is to make the SAD max initially*/
+ OMX_INT minSAD = 0x10001, fromX, toX, fromY, toY;
+ /* Offset to the reference at the begining of the bounding box */
+ const OMX_U8 *pTempSrcRefBuf;
+ OMX_S16 x, y;
+ OMX_INT searchRange;
+
+ /* Argument error checks */
+ armRetArgErrIf(pSrcRefBuf == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pRefRect == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pSrcCurrBuf == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pCurrPointPos == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pMESpec == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pDstMV == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pDstSAD == NULL, OMX_Sts_BadArgErr);
+
+ searchRange = ((OMXVCM4P2MEParams *)pMESpec)->searchRange;
+ /* Check for valid region */
+ fromX = searchRange;
+ toX = searchRange;
+ fromY = searchRange;
+ toY = searchRange;
+
+ if ((pCurrPointPos->x - searchRange) < pRefRect->x)
+ {
+ fromX = pCurrPointPos->x - pRefRect->x;
+ }
+
+ if ((pCurrPointPos->x + BlockSize + searchRange) > (pRefRect->x + pRefRect->width))
+ {
+ toX = pRefRect->width - (pCurrPointPos->x - pRefRect->x) - BlockSize;
+ }
+
+ if ((pCurrPointPos->y - searchRange) < pRefRect->y)
+ {
+ fromY = pCurrPointPos->y - pRefRect->y;
+ }
+
+ if ((pCurrPointPos->y + BlockSize + searchRange) > (pRefRect->y + pRefRect->height))
+ {
+ toY = pRefRect->width - (pCurrPointPos->y - pRefRect->y) - BlockSize;
+ }
+
+ pDstMV->dx = -fromX;
+ pDstMV->dy = -fromY;
+ /* Looping on y- axis */
+ for (y = -fromY; y <= toY; y++)
+ {
+
+ /* Looping on x- axis */
+ for (x = -fromX; x <= toX; x++)
+ {
+ /* Positioning the pointer */
+ pTempSrcRefBuf = pSrcRefBuf + (refWidth * y) + x;
+
+ /* Calculate the SAD */
+ for (outer = 0, count = 0, index = 0, candSAD = 0;
+ outer < BlockSize;
+ outer++, index += refWidth - BlockSize)
+ {
+ for (inner = 0; inner < BlockSize; inner++, count++, index++)
+ {
+ candSAD += armAbs (pTempSrcRefBuf[index] - pSrcCurrBuf[count]);
+ }
+ }
+
+ /* Result calculations */
+ if (armVCM4P2_CompareMV (x, y, candSAD, pDstMV->dx/2, pDstMV->dy/2, minSAD))
+ {
+ *pDstSAD = candSAD;
+ minSAD = candSAD;
+ pDstMV->dx = x*2;
+ pDstMV->dy = y*2;
+ }
+
+ } /* End of x- axis */
+ } /* End of y-axis */
+
+ return OMX_Sts_NoErr;
+
+}
+
+/* End of file */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_CheckVLCEscapeMode.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_CheckVLCEscapeMode.c
new file mode 100644
index 0000000..94e8639
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_CheckVLCEscapeMode.c
@@ -0,0 +1,156 @@
+/**
+ *
+ * File Name: armVCM4P2_CheckVLCEscapeMode.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains module for VLC escape mode check
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+
+#include "armVC.h"
+#include "armCOMM.h"
+
+/**
+ * Function: armVCM4P2_CheckVLCEscapeMode
+ *
+ * Description:
+ * Performs escape mode decision based on the run, run+, level, level+ and
+ * last combinations.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] run Run value (count of zeros) to be encoded
+ * [in] level Level value (non-zero value) to be encoded
+ * [in] runPlus Calculated as runPlus = run - (RMAX + 1)
+ * [in] levelPlus Calculated as
+ * levelPlus = sign(level)*[abs(level) - LMAX]
+ * [in] maxStoreRun Max store possible (considering last and inter/intra)
+ * [in] maxRunForMultipleEntries
+ * The run value after which level
+ * will be equal to 1:
+ * (considering last and inter/intra status)
+ * [in] pRunIndexTable Run Index table defined in
+ * armVCM4P2_Huff_Tables_VLC.c
+ * (considering last and inter/intra status)
+ *
+ *
+ * Return Value:
+ * Returns an Escape mode which can take values from 0 to 3
+ * 0 --> no escape mode, 1 --> escape type 1,
+ * 1 --> escape type 2, 3 --> escape type 3, check section 7.4.1.3
+ * in the MPEG ISO standard.
+ *
+ */
+
+OMX_U8 armVCM4P2_CheckVLCEscapeMode(
+ OMX_U32 run,
+ OMX_U32 runPlus,
+ OMX_S16 level,
+ OMX_S16 levelPlus,
+ OMX_U8 maxStoreRun,
+ OMX_U8 maxRunForMultipleEntries,
+ OMX_INT shortVideoHeader,
+ const OMX_U8 *pRunIndexTable
+)
+{
+ OMX_U8 escape = 0, fMode = 0, entries;
+
+ level = armAbs (level);
+ levelPlus = armAbs (levelPlus);
+
+ /* Check for a valid entry with run, level and Last combination
+ Mode 0 check */
+ if (run <= maxStoreRun)
+ {
+ entries = pRunIndexTable[run + 1]
+ - pRunIndexTable[run];
+ if (run > maxRunForMultipleEntries)
+ {
+ entries = 1;
+ }
+ if (level > entries)
+ {
+ escape = 1;
+ }
+ }
+ else
+ {
+ escape = 1;
+ }
+ if(escape && shortVideoHeader)
+ {
+ escape = 0;
+ fMode = 4;
+ }
+ /* Check for a valid entry with run, levelPlus and Last combination
+ Mode 1 check */
+ if (escape)
+ {
+ escape = 0;
+ fMode = 1;
+ if (run <= maxStoreRun)
+ {
+ entries = pRunIndexTable[run + 1]
+ - pRunIndexTable[run];
+ if (run > maxRunForMultipleEntries)
+ {
+ entries = 1;
+ }
+ if (levelPlus > entries)
+ {
+ escape = 1;
+ }
+ }
+ else
+ {
+ escape = 1;
+ }
+ }
+
+ /* Check for a valid entry with runPlus, level and Last combination
+ Mode 2 check */
+ if (escape)
+ {
+ escape = 0;
+ fMode = 2;
+ if (runPlus <= maxStoreRun)
+ {
+ entries = pRunIndexTable[runPlus + 1]
+ - pRunIndexTable[runPlus];
+ if (runPlus > maxRunForMultipleEntries)
+ {
+ entries = 1;
+ }
+ if (level > entries)
+ {
+ escape = 1;
+ }
+ }
+ else
+ {
+ escape = 1;
+ }
+ }
+
+ /* select mode 3 --> FLC */
+ if (escape)
+ {
+ fMode = 3;
+ }
+
+ return fMode;
+}
+
+/*End of File*/
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_CompareMV.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_CompareMV.c
new file mode 100644
index 0000000..3b8845e
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_CompareMV.c
@@ -0,0 +1,71 @@
+/**
+ *
+ * File Name: armVCM4P2_CompareMV.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains module for comparing motion vectors and SAD's to decide
+ * the best MV and SAD
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+
+#include "armVC.h"
+#include "armCOMM.h"
+
+/**
+ * Function: armVCM4P2_CompareMV
+ *
+ * Description:
+ * Performs comparision of motion vectors and SAD's to decide the
+ * best MV and SAD
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] mvX x coordinate of the candidate motion vector
+ * [in] mvY y coordinate of the candidate motion vector
+ * [in] candSAD Candidate SAD
+ * [in] bestMVX x coordinate of the best motion vector
+ * [in] bestMVY y coordinate of the best motion vector
+ * [in] bestSAD best SAD
+ *
+ * Return Value:
+ * OMX_INT -- 1 to indicate that the current sad is the best
+ * 0 to indicate that it is NOT the best SAD
+ */
+
+OMX_INT armVCM4P2_CompareMV (
+ OMX_S16 mvX,
+ OMX_S16 mvY,
+ OMX_INT candSAD,
+ OMX_S16 bestMVX,
+ OMX_S16 bestMVY,
+ OMX_INT bestSAD
+)
+{
+ if (candSAD < bestSAD)
+ {
+ return 1;
+ }
+ if (candSAD > bestSAD)
+ {
+ return 0;
+ }
+ /* shorter motion vector */
+ if ( (mvX * mvX + mvY * mvY) < (bestMVX*bestMVX+bestMVY*bestMVY) )
+ {
+ return 1;
+ }
+ return 0;
+}
+
+/*End of File*/
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_DCT_Table.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_DCT_Table.c
new file mode 100644
index 0000000..a6f713e
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_DCT_Table.c
@@ -0,0 +1,112 @@
+ /**
+ *
+ * File Name: armVCM4P2_DCT_Table.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * File: armVCM4P2_DCT_Table.c
+ * Description: Contains the DCT/IDCT coefficent matrix
+ *
+ */
+
+#ifndef _OMXDCTCOSTAB_C_
+#define _OMXDCTCOSTAB_C_
+
+#include "omxtypes.h"
+#include "armOMX.h"
+
+const OMX_F64 armVCM4P2_preCalcDCTCos[8][8] =
+{
+ {
+ 0.353553390593273730,
+ 0.490392640201615220,
+ 0.461939766255643370,
+ 0.415734806151272620,
+ 0.353553390593273790,
+ 0.277785116509801140,
+ 0.191341716182544920,
+ 0.097545161008064152
+ },
+ {
+ 0.353553390593273730,
+ 0.415734806151272620,
+ 0.191341716182544920,
+ -0.097545161008064096,
+ -0.353553390593273730,
+ -0.490392640201615220,
+ -0.461939766255643420,
+ -0.277785116509801090
+ },
+ {
+ 0.353553390593273730,
+ 0.277785116509801140,
+ -0.191341716182544860,
+ -0.490392640201615220,
+ -0.353553390593273840,
+ 0.097545161008064138,
+ 0.461939766255643260,
+ 0.415734806151272730
+ },
+ {
+ 0.353553390593273730,
+ 0.097545161008064152,
+ -0.461939766255643370,
+ -0.277785116509801090,
+ 0.353553390593273680,
+ 0.415734806151272730,
+ -0.191341716182544920,
+ -0.490392640201615330
+ },
+ {
+ 0.353553390593273730,
+ -0.097545161008064096,
+ -0.461939766255643420,
+ 0.277785116509800920,
+ 0.353553390593273840,
+ -0.415734806151272620,
+ -0.191341716182545280,
+ 0.490392640201615220
+ },
+ {
+ 0.353553390593273730,
+ -0.277785116509800980,
+ -0.191341716182545170,
+ 0.490392640201615220,
+ -0.353553390593273340,
+ -0.097545161008064013,
+ 0.461939766255643370,
+ -0.415734806151272510
+ },
+ {
+ 0.353553390593273730,
+ -0.415734806151272670,
+ 0.191341716182545000,
+ 0.097545161008064388,
+ -0.353553390593273620,
+ 0.490392640201615330,
+ -0.461939766255643200,
+ 0.277785116509800760
+ },
+ {
+ 0.353553390593273730,
+ -0.490392640201615220,
+ 0.461939766255643260,
+ -0.415734806151272620,
+ 0.353553390593273290,
+ -0.277785116509800760,
+ 0.191341716182544780,
+ -0.097545161008064277
+ }
+};
+
+#endif /*_OMXDCTCOSTAB_C_*/
+
+
+/* End of file */
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_DecodeVLCZigzag_intra.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_DecodeVLCZigzag_intra.c
new file mode 100644
index 0000000..a2572e0
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_DecodeVLCZigzag_intra.c
@@ -0,0 +1,144 @@
+/**
+ *
+ * File Name: armVCM4P2_DecodeVLCZigzag_intra.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains modules for filling of the coefficient buffer
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armVC.h"
+#include "armCOMM_Bitstream.h"
+#include "armCOMM.h"
+#include "armVCM4P2_Huff_Tables_VLC.h"
+#include "armVCM4P2_ZigZag_Tables.h"
+
+
+
+/**
+ * Function: armVCM4P2_DecodeVLCZigzag_Intra
+ *
+ * Description:
+ * Performs VLC decoding and inverse zigzag scan for one intra coded block.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream pointer to the pointer to the current byte in
+ * the bitstream buffer
+ * [in] pBitOffset pointer to the bit position in the byte pointed
+ * to by *ppBitStream. *pBitOffset is valid within
+ * [0-7].
+ * [in] predDir AC prediction direction which is used to decide
+ * the zigzag scan pattern. It takes one of the
+ * following values:
+ * OMX_VC_NONE AC prediction not used;
+ * perform classical zigzag scan;
+ * OMX_VC_HORIZONTAL Horizontal prediction;
+ * perform alternate-vertical
+ * zigzag scan;
+ * OMX_VC_VERTICAL Vertical prediction;
+ * thus perform
+ * alternate-horizontal
+ * zigzag scan.
+ * [in] start start indicates whether the encoding begins with 0th element
+ * or 1st.
+ * [out] ppBitStream *ppBitStream is updated after the block is
+ * decoded, so that it points to the current byte
+ * in the bit stream buffer
+ * [out] pBitOffset *pBitOffset is updated so that it points to the
+ * current bit position in the byte pointed by
+ * *ppBitStream
+ * [out] pDst pointer to the coefficient buffer of current
+ * block. Should be 32-bit aligned
+ *
+ * Return Value:
+ * Standard OMXResult result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armVCM4P2_DecodeVLCZigzag_Intra(
+ const OMX_U8 ** ppBitStream,
+ OMX_INT * pBitOffset,
+ OMX_S16 * pDst,
+ OMX_U8 predDir,
+ OMX_INT shortVideoHeader,
+ OMX_U8 start
+)
+{
+ OMX_U8 last = 0;
+ const OMX_U8 *pZigzagTable = armVCM4P2_aClassicalZigzagScan;
+ OMXResult errorCode;
+
+ /* Argument error checks */
+ armRetArgErrIf(ppBitStream == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(*ppBitStream == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pBitOffset == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(!armIs4ByteAligned(pDst), OMX_Sts_BadArgErr);
+ armRetArgErrIf((*pBitOffset < 0) || (*pBitOffset >7), OMX_Sts_BadArgErr);
+ armRetArgErrIf((predDir > 2), OMX_Sts_BadArgErr);
+
+ switch (predDir)
+ {
+ case OMX_VC_NONE:
+ {
+ pZigzagTable = armVCM4P2_aClassicalZigzagScan;
+ break;
+ }
+
+ case OMX_VC_HORIZONTAL:
+ {
+ pZigzagTable = armVCM4P2_aVerticalZigzagScan;
+ break;
+ }
+
+ case OMX_VC_VERTICAL:
+ {
+ pZigzagTable = armVCM4P2_aHorizontalZigzagScan;
+ break;
+ }
+ }
+
+ errorCode = armVCM4P2_GetVLCBits (
+ ppBitStream,
+ pBitOffset,
+ pDst,
+ shortVideoHeader,
+ start,
+ &last,
+ 10,
+ 62,
+ 7,
+ 21,
+ armVCM4P2_IntraL0RunIdx,
+ armVCM4P2_IntraVlcL0,
+ armVCM4P2_IntraL1RunIdx,
+ armVCM4P2_IntraVlcL1,
+ armVCM4P2_IntraL0LMAX,
+ armVCM4P2_IntraL1LMAX,
+ armVCM4P2_IntraL0RMAX,
+ armVCM4P2_IntraL1RMAX,
+ pZigzagTable );
+ armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode);
+
+ if (last == 0)
+ {
+ return OMX_Sts_Err;
+ }
+ return OMX_Sts_NoErr;
+}
+
+/* End of file */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_EncodeVLCZigzag_intra.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_EncodeVLCZigzag_intra.c
new file mode 100644
index 0000000..cd6b56d
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_EncodeVLCZigzag_intra.c
@@ -0,0 +1,145 @@
+/**
+ *
+ * File Name: armVCM4P2_EncodeVLCZigzag_intra.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains modules for zigzag scanning and VLC encoding
+ * for intra block.
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armVC.h"
+#include "armCOMM_Bitstream.h"
+#include "armCOMM.h"
+#include "armVCM4P2_Huff_Tables_VLC.h"
+#include "armVCM4P2_ZigZag_Tables.h"
+
+
+
+/**
+ * Function: armVCM4P2_EncodeVLCZigzag_Intra
+ *
+ * Description:
+ * Performs zigzag scanning and VLC encoding for one intra block.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream pointer to the pointer to the current byte in
+ * the bit stream
+ * [in] pBitOffset pointer to the bit position in the byte pointed
+ * by *ppBitStream. Valid within 0 to 7.
+ * [in] pQDctBlkCoef pointer to the quantized DCT coefficient
+ * [in] predDir AC prediction direction, which is used to decide
+ * the zigzag scan pattern. This takes one of the
+ * following values:
+ * OMX_VC_NONE AC prediction not used.
+ * Performs classical zigzag
+ * scan.
+ * OMX_VC_HORIZONTAL Horizontal prediction.
+ * Performs alternate-vertical
+ * zigzag scan.
+ * OMX_VC_VERTICAL Vertical prediction.
+ * Performs alternate-horizontal
+ * zigzag scan.
+ * [in] pattern block pattern which is used to decide whether
+ * this block is encoded
+ * [in] start start indicates whether the encoding begins with 0th element
+ * or 1st.
+ * [out] ppBitStream *ppBitStream is updated after the block is encoded,
+ * so that it points to the current byte in the bit
+ * stream buffer.
+ * [out] pBitOffset *pBitOffset is updated so that it points to the
+ * current bit position in the byte pointed by
+ * *ppBitStream.
+ *
+ * Return Value:
+ * Standard OMXResult result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armVCM4P2_EncodeVLCZigzag_Intra(
+ OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ const OMX_S16 *pQDctBlkCoef,
+ OMX_U8 predDir,
+ OMX_U8 pattern,
+ OMX_INT shortVideoHeader,
+ OMX_U8 start
+)
+{
+ const OMX_U8 *pZigzagTable = armVCM4P2_aClassicalZigzagScan;
+ OMXResult errorCode;
+
+ /* Argument error checks */
+ armRetArgErrIf(ppBitStream == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(*ppBitStream == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pBitOffset == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pQDctBlkCoef == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf((*pBitOffset < 0) || (*pBitOffset >7), OMX_Sts_BadArgErr);
+ armRetArgErrIf(start > 1, OMX_Sts_BadArgErr);
+ armRetArgErrIf(predDir > 2, OMX_Sts_BadArgErr);
+
+ if (pattern)
+ {
+ switch (predDir)
+ {
+ case OMX_VC_NONE:
+ {
+ pZigzagTable = armVCM4P2_aClassicalZigzagScan;
+ break;
+ }
+
+ case OMX_VC_HORIZONTAL:
+ {
+ pZigzagTable = armVCM4P2_aVerticalZigzagScan;
+ break;
+ }
+
+ case OMX_VC_VERTICAL:
+ {
+ pZigzagTable = armVCM4P2_aHorizontalZigzagScan;
+ break;
+ }
+ }
+
+ errorCode = armVCM4P2_PutVLCBits (
+ ppBitStream,
+ pBitOffset,
+ pQDctBlkCoef,
+ shortVideoHeader,
+ start,
+ 14,
+ 20,
+ 9,
+ 6,
+ armVCM4P2_IntraL0RunIdx,
+ armVCM4P2_IntraVlcL0,
+ armVCM4P2_IntraL1RunIdx,
+ armVCM4P2_IntraVlcL1,
+ armVCM4P2_IntraL0LMAX,
+ armVCM4P2_IntraL1LMAX,
+ armVCM4P2_IntraL0RMAX,
+ armVCM4P2_IntraL1RMAX,
+ pZigzagTable
+ );
+ armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode);
+
+ } /* Pattern check ends*/
+
+ return (OMX_Sts_NoErr);
+
+}
+
+/* End of file */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_FillVLCBuffer.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_FillVLCBuffer.c
new file mode 100644
index 0000000..93c9504
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_FillVLCBuffer.c
@@ -0,0 +1,153 @@
+/**
+ *
+ * File Name: armVCM4P2_FillVLCBuffer.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains module for putting VLC bits
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+
+#include "armVC.h"
+#include "armCOMM.h"
+#include "armCOMM_Bitstream.h"
+
+/**
+ * Function: armVCM4P2_FillVLCBuffer
+ *
+ * Description:
+ * Performs calculating the VLC bits depending on the escape type and insert
+ * the same in the bitstream
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream pointer to the pointer to the current byte in
+ * the bit stream
+ * [in] pBitOffset pointer to the bit position in the byte pointed
+ * by *ppBitStream. Valid within 0 to 7
+ * [in] run Run value (count of zeros) to be encoded
+ * [in] level Level value (non-zero value) to be encoded
+ * [in] runPlus Calculated as runPlus = run - (RMAX + 1)
+ * [in] levelPlus Calculated as
+ * levelPlus = sign(level)*[abs(level) - LMAX]
+ * [in] fMode Flag indicating the escape modes
+ * [in] last status of the last flag
+ * [in] maxRunForMultipleEntries
+ * The run value after which level will be equal to 1:
+ * (considering last and inter/intra status)
+ * [in] pRunIndexTable Run Index table defined in
+ * armVCM4P2_Huff_Tables_VLC.h
+ * [in] pVlcTable VLC table defined in armVCM4P2_Huff_Tables_VLC.h
+ * [out] ppBitStream *ppBitStream is updated after the block is encoded
+ * so that it points to the current byte in the bit
+ * stream buffer.
+ * [out] pBitOffset *pBitOffset is updated so that it points to the
+ * current bit position in the byte pointed by
+ * *ppBitStream.
+ *
+ * Return Value:
+ * Standard OMXResult result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armVCM4P2_FillVLCBuffer (
+ OMX_U8 **ppBitStream,
+ OMX_INT * pBitOffset,
+ OMX_U32 run,
+ OMX_S16 level,
+ OMX_U32 runPlus,
+ OMX_S16 levelPlus,
+ OMX_U8 fMode,
+ OMX_U8 last,
+ OMX_U8 maxRunForMultipleEntries,
+ const OMX_U8 *pRunIndexTable,
+ const ARM_VLC32 *pVlcTable
+)
+{
+ OMX_INT tempIndex;
+ OMX_U32 tempRun = run, sign = 0;
+ OMX_S16 tempLevel = level;
+
+ /* Escape sequence addition */
+ if (fMode == 1)
+ {
+ armPackBits(ppBitStream, pBitOffset, 3, 7);
+ armPackBits(ppBitStream, pBitOffset, 0, 1);
+ tempLevel = levelPlus;
+
+ }
+ else if(fMode == 2)
+ {
+ armPackBits(ppBitStream, pBitOffset, 3, 7);
+ armPackBits(ppBitStream, pBitOffset, 2, 2);
+ tempRun = runPlus;
+ }
+ else if (fMode == 3)
+ {
+ armPackBits(ppBitStream, pBitOffset, 3, 7);
+ armPackBits(ppBitStream, pBitOffset, 3, 2);
+ }
+ else if (fMode == 4)
+ {
+ armPackBits(ppBitStream, pBitOffset, 3, 7);
+ armPackBits(ppBitStream, pBitOffset, (OMX_U32)last, 1);
+ armPackBits(ppBitStream, pBitOffset, tempRun, 6);
+ if((tempLevel != 0) && (tempLevel != -128))
+ {
+ armPackBits(ppBitStream, pBitOffset,
+ (OMX_U32) tempLevel, 8);
+ }
+ return OMX_Sts_NoErr;
+ }
+
+ if (tempLevel < 0)
+ {
+ sign = 1;
+ tempLevel = armAbs(tempLevel);
+ }
+ /* Putting VLC bits in the stream */
+ if (fMode < 3)
+ {
+ if (tempRun > maxRunForMultipleEntries)
+ {
+ tempIndex = pRunIndexTable [maxRunForMultipleEntries + 1] +
+ (tempRun - maxRunForMultipleEntries - 1);
+ }
+ else
+ {
+ tempIndex = pRunIndexTable [tempRun] + (tempLevel -1);
+ }
+
+ armPackVLC32 (ppBitStream, pBitOffset,
+ pVlcTable [tempIndex]);
+ armPackBits(ppBitStream, pBitOffset, (OMX_U32)sign, 1);
+ }
+ else
+ {
+ if (sign)
+ {
+ tempLevel = -tempLevel;
+ }
+ tempRun = run;
+ armPackBits(ppBitStream, pBitOffset, (OMX_U32)last, 1);
+ armPackBits(ppBitStream, pBitOffset, tempRun, 6);
+ armPackBits(ppBitStream, pBitOffset, 1, 1);
+ armPackBits(ppBitStream, pBitOffset,
+ (OMX_U32) tempLevel, 12);
+ armPackBits(ppBitStream, pBitOffset, 1, 1);
+ }
+ return OMX_Sts_NoErr;
+}
+
+/*End of File*/
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_FillVLDBuffer.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_FillVLDBuffer.c
new file mode 100644
index 0000000..1712c3a
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_FillVLDBuffer.c
@@ -0,0 +1,84 @@
+/**
+ *
+ * File Name: armVCM4P2_FillVLDBuffer.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains module for VLC get bits from the stream
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+
+#include "armVCM4P2_ZigZag_Tables.h"
+
+
+/**
+ * Function: armVCM4P2_FillVLDBuffer
+ *
+ * Description:
+ * Performs filling of the coefficient buffer according to the run, level
+ * and sign, also updates the index
+ *
+ * Parameters:
+ * [in] storeRun Stored Run value (count of zeros)
+ * [in] storeLevel Stored Level value (non-zero value)
+ * [in] sign Flag indicating the sign of level
+ * [in] last status of the last flag
+ * [in] pIndex pointer to coefficient index in 8x8 matrix
+ * [out] pIndex pointer to updated coefficient index in 8x8
+ * matrix
+ * [in] pZigzagTable pointer to the zigzag tables
+ * [out] pDst pointer to the coefficient buffer of current
+ * block. Should be 32-bit aligned
+ * Return Value:
+ * Standard OMXResult result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armVCM4P2_FillVLDBuffer(
+ OMX_U32 storeRun,
+ OMX_S16 * pDst,
+ OMX_S16 storeLevel,
+ OMX_U8 sign,
+ OMX_U8 last,
+ OMX_U8 * pIndex,
+ const OMX_U8 * pZigzagTable
+)
+{
+ /* Store the zero's as per the run length count */
+ for (;storeRun > 0; storeRun--, (*pIndex)++)
+ {
+ pDst[pZigzagTable[*pIndex]] = 0;
+ }
+ /* Store the level depending on the sign*/
+ if (sign == 1)
+ {
+ pDst[pZigzagTable[*pIndex]] = -storeLevel;
+ }
+ else
+ {
+ pDst[pZigzagTable[*pIndex]] = storeLevel;
+ }
+ (*pIndex)++;
+
+ /* If last is 1, fill the remaining elments of the buffer with zeros */
+ if (last == 1)
+ {
+ while (*pIndex < 64)
+ {
+ pDst[pZigzagTable[*pIndex]] = 0;
+ (*pIndex)++;
+ }
+ }
+
+ return OMX_Sts_NoErr;
+}
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_GetVLCBits.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_GetVLCBits.c
new file mode 100644
index 0000000..953f597
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_GetVLCBits.c
@@ -0,0 +1,278 @@
+/**
+ *
+ * File Name: armVCM4P2_GetVLCBits.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains module for VLC get bits from the stream
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+
+#include "armVC.h"
+#include "armCOMM.h"
+#include "armCOMM_Bitstream.h"
+#include "armVCM4P2_ZigZag_Tables.h"
+#include "armVCM4P2_Huff_Tables_VLC.h"
+
+
+/**
+ * Function: armVCM4P2_GetVLCBits
+ *
+ * Description:
+ * Performs escape mode decision based on the run, run+, level, level+ and
+ * last combinations.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream pointer to the pointer to the current byte in
+ * the bit stream
+ * [in] pBitOffset pointer to the bit position in the byte pointed
+ * by *ppBitStream. Valid within 0 to 7
+ * [in] start start indicates whether the encoding begins with
+ * 0th element or 1st.
+ * [in/out] pLast pointer to last status flag
+ * [in] runBeginSingleLevelEntriesL0 The run value from which level
+ * will be equal to 1: last == 0
+ * [in] IndexBeginSingleLevelEntriesL0 Array index in the VLC table
+ * pointing to the
+ * runBeginSingleLevelEntriesL0
+ * [in] runBeginSingleLevelEntriesL1 The run value from which level
+ * will be equal to 1: last == 1
+ * [in] IndexBeginSingleLevelEntriesL1 Array index in the VLC table
+ * pointing to the
+ * runBeginSingleLevelEntriesL0
+ * [in] pRunIndexTableL0 Run Index table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 0
+ * [in] pVlcTableL0 VLC table for last == 0
+ * [in] pRunIndexTableL1 Run Index table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 1
+ * [in] pVlcTableL1 VLC table for last == 1
+ * [in] pLMAXTableL0 Level MAX table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 0
+ * [in] pLMAXTableL1 Level MAX table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 1
+ * [in] pRMAXTableL0 Run MAX table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 0
+ * [in] pRMAXTableL1 Run MAX table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 1
+ * [out]pDst pointer to the coefficient buffer of current
+ * block. Should be 32-bit aligned
+ *
+ * Return Value:
+ * Standard OMXResult result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armVCM4P2_GetVLCBits (
+ const OMX_U8 **ppBitStream,
+ OMX_INT * pBitOffset,
+ OMX_S16 * pDst,
+ OMX_INT shortVideoHeader,
+ OMX_U8 start,
+ OMX_U8 * pLast,
+ OMX_U8 runBeginSingleLevelEntriesL0,
+ OMX_U8 maxIndexForMultipleEntriesL0,
+ OMX_U8 maxRunForMultipleEntriesL1,
+ OMX_U8 maxIndexForMultipleEntriesL1,
+ const OMX_U8 * pRunIndexTableL0,
+ const ARM_VLC32 *pVlcTableL0,
+ const OMX_U8 * pRunIndexTableL1,
+ const ARM_VLC32 *pVlcTableL1,
+ const OMX_U8 * pLMAXTableL0,
+ const OMX_U8 * pLMAXTableL1,
+ const OMX_U8 * pRMAXTableL0,
+ const OMX_U8 * pRMAXTableL1,
+ const OMX_U8 * pZigzagTable
+)
+{
+ OMX_U32 storeRun;
+ OMX_U8 tabIndex, markerBit;
+ OMX_S16 storeLevel;
+ OMX_U16 unpackRetIndex;
+ OMX_U8 i, fType, escape;
+ OMX_U8 sign = 0;
+
+ /* Unpacking the bitstream and RLD */
+ for (i = start; i < 64;)
+ {
+ escape = armLookAheadBits(ppBitStream, pBitOffset, 7);
+ if (escape != 3)
+ {
+ fType = 0; /* Not in escape mode */
+ }
+ else
+ {
+ armSkipBits (ppBitStream, pBitOffset, 7);
+ if(shortVideoHeader)
+ {
+ *pLast = armGetBits(ppBitStream, pBitOffset, 1);
+ storeRun = armGetBits(ppBitStream, pBitOffset, 6);
+ storeLevel = armGetBits(ppBitStream, pBitOffset, 8);
+
+ /* Ref to Table B-18 (c) in MPEG4 Standard- FLC code for */
+ /* LEVEL when short_video_header is 1, the storeLevel is */
+ /* a signed value and the sign and the unsigned value for */
+ /* storeLevel need to be extracted and passed to arm */
+ /* FillVLDBuffer function */
+
+ sign = (storeLevel & 0x80);
+ if(sign==0x80)
+ {
+ storeLevel=(storeLevel^0xff)+1;
+ sign=1;
+
+ }
+
+ armRetDataErrIf( storeLevel == 0 || sign*storeLevel == 128 , OMX_Sts_Err); /* Invalid FLC */
+ armRetDataErrIf((i + storeRun) >= 64, OMX_Sts_Err);
+ armVCM4P2_FillVLDBuffer(
+ storeRun,
+ pDst,
+ storeLevel,
+ sign,
+ *pLast,
+ &i,
+ pZigzagTable);
+ return OMX_Sts_NoErr;
+
+ }
+ if (armGetBits(ppBitStream, pBitOffset, 1))
+ {
+ if (armGetBits(ppBitStream, pBitOffset, 1))
+ {
+ fType = 3;
+ }
+ else
+ {
+ fType = 2;
+ }
+ }
+ else
+ {
+ fType = 1;
+ }
+ }
+
+ if (fType < 3)
+ {
+ unpackRetIndex = armUnPackVLC32(ppBitStream, pBitOffset,
+ pVlcTableL0);
+ if (unpackRetIndex != ARM_NO_CODEBOOK_INDEX)
+ {
+ /* Decode run and level from the index */
+ /* last = 0 */
+ *pLast = 0;
+ if (unpackRetIndex > maxIndexForMultipleEntriesL0)
+ {
+ storeLevel = 1;
+ storeRun = (unpackRetIndex - maxIndexForMultipleEntriesL0)
+ + runBeginSingleLevelEntriesL0;
+ }
+ else
+ {
+ tabIndex = 1;
+ while (pRunIndexTableL0[tabIndex] <= unpackRetIndex)
+ {
+ tabIndex++;
+ }
+ storeRun = tabIndex - 1;
+ storeLevel = unpackRetIndex - pRunIndexTableL0[tabIndex - 1] + 1;
+ }
+ sign = (OMX_U8) armGetBits(ppBitStream, pBitOffset, 1);
+
+ if (fType == 1)
+ {
+ storeLevel = (armAbs(storeLevel) + pLMAXTableL0[storeRun]);
+ }
+ else if (fType == 2)
+ {
+ storeRun = storeRun + pRMAXTableL0[storeLevel-1] + 1;
+ }
+ }
+ else
+ {
+ unpackRetIndex = armUnPackVLC32(ppBitStream, pBitOffset,
+ pVlcTableL1);
+
+ armRetDataErrIf(unpackRetIndex == ARM_NO_CODEBOOK_INDEX, OMX_Sts_Err);
+
+ /* Decode run and level from the index */
+ /* last = 1 */
+ *pLast = 1;
+ if (unpackRetIndex > maxIndexForMultipleEntriesL1)
+ {
+ storeLevel = 1;
+ storeRun = (unpackRetIndex - maxIndexForMultipleEntriesL1)
+ + maxRunForMultipleEntriesL1;
+ }
+ else
+ {
+ tabIndex = 1;
+ while (pRunIndexTableL1[tabIndex] <= unpackRetIndex)
+ {
+ tabIndex++;
+ }
+ storeRun = tabIndex - 1;
+ storeLevel = unpackRetIndex - pRunIndexTableL1[tabIndex - 1] + 1;
+ }
+ sign = (OMX_U8) armGetBits(ppBitStream, pBitOffset, 1);
+
+ if (fType == 1)
+ {
+ storeLevel = (armAbs(storeLevel) + pLMAXTableL1[storeRun]);
+ }
+ else if (fType == 2)
+ {
+ storeRun = storeRun + pRMAXTableL1[storeLevel-1] + 1;
+ }
+ }
+ armRetDataErrIf((i + storeRun) >= 64, OMX_Sts_Err);
+ armVCM4P2_FillVLDBuffer(
+ storeRun,
+ pDst,
+ storeLevel,
+ sign,
+ *pLast,
+ &i,
+ pZigzagTable);
+ }
+ else
+ {
+ *pLast = armGetBits(ppBitStream, pBitOffset, 1);
+ storeRun = armGetBits(ppBitStream, pBitOffset, 6);
+ armRetDataErrIf((i + storeRun) >= 64, OMX_Sts_Err);
+ markerBit = armGetBits(ppBitStream, pBitOffset, 1);
+ armRetDataErrIf( markerBit == 0, OMX_Sts_Err);
+ storeLevel = armGetBits(ppBitStream, pBitOffset, 12);
+ if (storeLevel & 0x800)
+ {
+ storeLevel -= 4096;
+ }
+ armRetDataErrIf( storeLevel == 0 || storeLevel == -2048 , OMX_Sts_Err); /* Invalid FLC */
+ armGetBits(ppBitStream, pBitOffset, 1);
+ armVCM4P2_FillVLDBuffer(
+ storeRun,
+ pDst,
+ storeLevel,
+ 0, /* Sign is not used, preprocessing done */
+ *pLast,
+ &i,
+ pZigzagTable);
+
+ }
+ } /* End of forloop for i */
+ return OMX_Sts_NoErr;
+}
+
+/* End of File */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_Huff_Tables_VLC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_Huff_Tables_VLC.c
new file mode 100644
index 0000000..cd7e9e4
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_Huff_Tables_VLC.c
@@ -0,0 +1,495 @@
+ /**
+ *
+ * File Name: armVCM4P2_Huff_Tables_VLC.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * File: armVCM4P2_Huff_Tables_VLC.c
+ * Description: Contains all the Huffman tables used in MPEG4 codec
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+
+#include "armCOMM_Bitstream.h"
+
+/*
+* For Intra
+* last = 0
+*/
+const OMX_U8 armVCM4P2_IntraL0RunIdx[11] =
+{
+ 0, 27, 37, 42, 46, 49, 52,
+ 55, 58, 60, 62
+};
+
+/* Entry defined for all values
+* for run = 0 to 14
+* Note: the last entry is to terminate while decoding
+*/
+const ARM_VLC32 armVCM4P2_IntraVlcL0[68] =
+{
+ {2, 2},
+ {3, 6},
+ {4, 15},
+ {5, 13},
+ {5, 12},
+ {6, 21},
+ {6, 19},
+ {6, 18},
+ {7, 23},
+ {8, 31},
+ {8, 30},
+ {8, 29},
+ {9, 37},
+ {9, 36},
+ {9, 35},
+ {9, 33},
+ {10, 33},
+ {10, 32},
+ {10, 15},
+ {10, 14},
+ {11, 7},
+ {11, 6},
+ {11, 32},
+ {11, 33},
+ {12, 80},
+ {12, 81},
+ {12, 82},
+ {4, 14},
+ {6, 20},
+ {7, 22},
+ {8, 28},
+ {9, 32},
+ {9, 31},
+ {10, 13},
+ {11, 34},
+ {12, 83},
+ {12, 85},
+ {5, 11},
+ {7, 21},
+ {9, 30},
+ {10, 12},
+ {12, 86},
+ {6, 17},
+ {8, 27},
+ {9, 29},
+ {10, 11},
+ {6, 16},
+ {9, 34},
+ {10, 10},
+ {6, 13},
+ {9, 28},
+ {10, 8},
+ {7, 18},
+ {9, 27},
+ {12, 84},
+ {7, 20},
+ {9, 26},
+ {12, 87},
+ {8, 25},
+ {10, 9},
+ {8, 24},
+ {11, 35},
+ {8, 23},
+ {9, 25},
+ {9, 24},
+ {10, 7},
+ {12, 88},
+ {0, 0}
+};
+
+/*
+* For Intra
+* last = 1
+*/
+
+const OMX_U8 armVCM4P2_IntraL1RunIdx[8] =
+{
+ 0, 8, 11, 13, 15, 17, 19, 21
+};
+
+/* Entry defined for all values
+* for run = 0 to 20
+* * Note: the last entry is to terminate while decoding
+*/
+const ARM_VLC32 armVCM4P2_IntraVlcL1[36] =
+{
+ {4, 7},
+ {6, 12},
+ {8, 22},
+ {9, 23},
+ {10, 6},
+ {11, 5},
+ {11, 4},
+ {12, 89},
+ {6, 15},
+ {9, 22},
+ {10, 5},
+ {6, 14},
+ {10, 4},
+ {7, 17},
+ {11, 36},
+ {7, 16},
+ {11, 37},
+ {7, 19},
+ {12, 90},
+ {8, 21},
+ {12, 91},
+ {8, 20},
+ {8, 19},
+ {8, 26},
+ {9, 21},
+ {9, 20},
+ {9, 19},
+ {9, 18},
+ {9, 17},
+ {11, 38},
+ {11, 39},
+ {12, 92},
+ {12, 93},
+ {12, 94},
+ {12, 95},
+ {0, 0}
+};
+
+/* LMAX table for Intra (Last == 0)*/
+const OMX_U8 armVCM4P2_IntraL0LMAX[15] =
+{
+ 27, 10, 5, 4, 3, 3, 3,
+ 3, 2, 2, 1, 1, 1, 1, 1
+};
+
+/* LMAX table for Intra (Last == 1)*/
+const OMX_U8 armVCM4P2_IntraL1LMAX[21] =
+{
+ 8, 3, 2, 2, 2, 2, 2, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+};
+
+/* RMAX table for Intra (Last == 0)
+ Level - 1 Indexed
+*/
+const OMX_U8 armVCM4P2_IntraL0RMAX[27] =
+{
+ 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
+};
+
+/* RMAX table for Intra (Last == 1)
+ Level - 1 Indexed
+*/
+const OMX_U8 armVCM4P2_IntraL1RMAX[8] =
+{
+ 20, 6, 1, 0, 0, 0, 0, 0
+};
+
+/*
+* For Inter
+* last = 0
+*/
+const OMX_U8 armVCM4P2_InterL0RunIdx[12] =
+{
+ 0, 12, 18, 22, 25, 28,
+ 31, 34, 36, 38, 40, 42
+};
+
+/* Entry defined for all values
+* for run = 0 to 26
+* Note: the last entry is to terminate while decoding
+*/
+const ARM_VLC32 armVCM4P2_InterVlcL0[59] =
+{
+ {2, 2},
+ {4, 15},
+ {6, 21},
+ {7, 23},
+ {8, 31},
+ {9, 37},
+ {9, 36},
+ {10, 33},
+ {10, 32},
+ {11, 7},
+ {11, 6},
+ {11, 32},
+ {3, 6},
+ {6, 20},
+ {8, 30},
+ {10, 15},
+ {11, 33},
+ {12, 80},
+ {4, 14},
+ {8, 29},
+ {10, 14},
+ {12, 81},
+ {5, 13},
+ {9, 35},
+ {10, 13},
+ {5, 12},
+ {9, 34},
+ {12, 82},
+ {5, 11},
+ {10, 12},
+ {12, 83},
+ {6, 19},
+ {10, 11},
+ {12, 84},
+ {6, 18},
+ {10, 10},
+ {6, 17},
+ {10, 9},
+ {6, 16},
+ {10, 8},
+ {7, 22},
+ {12, 85},
+ {7, 21},
+ {7, 20},
+ {8, 28},
+ {8, 27},
+ {9, 33},
+ {9, 32},
+ {9, 31},
+ {9, 30},
+ {9, 29},
+ {9, 28},
+ {9, 27},
+ {9, 26},
+ {11, 34},
+ {11, 35},
+ {12, 86},
+ {12, 87},
+ {0, 0}
+};
+
+
+/*
+* For Intra
+* last = 1
+*/
+
+const OMX_U8 armVCM4P2_InterL1RunIdx[3] =
+{
+ 0, 3, 5
+};
+
+/* Entry defined for all values
+* for run = 0 to 40
+* Note: the last entry is to terminate while decoding
+*/
+const ARM_VLC32 armVCM4P2_InterVlcL1[45] =
+{
+ {4, 7},
+ {9, 25},
+ {11, 5},
+ {6, 15},
+ {11, 4},
+ {6, 14},
+ {6, 13},
+ {6, 12},
+ {7, 19},
+ {7, 18},
+ {7, 17},
+ {7, 16},
+ {8, 26},
+ {8, 25},
+ {8, 24},
+ {8, 23},
+ {8, 22},
+ {8, 21},
+ {8, 20},
+ {8, 19},
+ {9, 24},
+ {9, 23},
+ {9, 22},
+ {9, 21},
+ {9, 20},
+ {9, 19},
+ {9, 18},
+ {9, 17},
+ {10, 7},
+ {10, 6},
+ {10, 5},
+ {10, 4},
+ {11, 36},
+ {11, 37},
+ {11, 38},
+ {11, 39},
+ {12, 88},
+ {12, 89},
+ {12, 90},
+ {12, 91},
+ {12, 92},
+ {12, 93},
+ {12, 94},
+ {12, 95},
+ { 0, 0}
+};
+
+/* LMAX table for Intra (Last == 0)*/
+const OMX_U8 armVCM4P2_InterL0LMAX[27] =
+{
+ 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,
+};
+
+/* LMAX table for Intra (Last == 1)*/
+const OMX_U8 armVCM4P2_InterL1LMAX[41] =
+{
+ 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,
+};
+
+/* RMAX table for Intra (Last == 0)
+ Level - 1 Indexed
+*/
+const OMX_U8 armVCM4P2_InterL0RMAX[12] =
+{
+ 26, 10, 6, 2, 1, 1,
+ 0, 0, 0, 0, 0, 0
+};
+
+/* RMAX table for Intra (Last == 1)
+ Level - 1 Indexed
+*/
+const OMX_U8 armVCM4P2_InterL1RMAX[3] =
+{
+ 40, 1, 0
+};
+
+/*
+* For Intra - Luminance
+*/
+
+const ARM_VLC32 armVCM4P2_aIntraDCLumaIndex[14] =
+{
+ {3, 3},
+ {2, 3},
+ {2, 2},
+ {3, 2},
+ {3, 1},
+ {4, 1},
+ {5, 1},
+ {6, 1},
+ {7, 1},
+ {8, 1},
+ {9, 1},
+ {10, 1},
+ {11, 1},
+ {0, 0}
+};
+
+/*
+* For Intra - Chrominance
+*/
+
+const ARM_VLC32 armVCM4P2_aIntraDCChromaIndex[14] =
+{
+ {2, 3},
+ {2, 2},
+ {2, 1},
+ {3, 1},
+ {4, 1},
+ {5, 1},
+ {6, 1},
+ {7, 1},
+ {8, 1},
+ {9, 1},
+ {10, 1},
+ {11, 1},
+ {12, 1},
+ {0, 0}
+};
+
+/*
+ * Motion vector decoding table
+ */
+
+const ARM_VLC32 armVCM4P2_aVlcMVD[66] =
+{
+ {13, 5},
+ {13, 7},
+ {12, 5},
+ {12, 7},
+ {12, 9},
+ {12, 11},
+ {12, 13},
+ {12, 15},
+ {11, 9},
+ {11, 11},
+ {11, 13},
+ {11, 15},
+ {11, 17},
+ {11, 19},
+ {11, 21},
+ {11, 23},
+ {11, 25},
+ {11, 27},
+ {11, 29},
+ {11, 31},
+ {11, 33},
+ {11, 35},
+ {10, 19},
+ {10, 21},
+ {10, 23},
+ {8, 7},
+ {8, 9},
+ {8, 11},
+ {7, 7},
+ {5, 3},
+ {4, 3},
+ {3, 3},
+ {1, 1},
+ {3, 2},
+ {4, 2},
+ {5, 2},
+ {7, 6},
+ {8, 10},
+ {8, 8},
+ {8, 6},
+ {10, 22},
+ {10, 20},
+ {10, 18},
+ {11, 34},
+ {11, 32},
+ {11, 30},
+ {11, 28},
+ {11, 26},
+ {11, 24},
+ {11, 22},
+ {11, 20},
+ {11, 18},
+ {11, 16},
+ {11, 14},
+ {11, 12},
+ {11, 10},
+ {11, 8},
+ {12, 14},
+ {12, 12},
+ {12, 10},
+ {12, 8},
+ {12, 6},
+ {12, 4},
+ {13, 6},
+ {13, 4},
+ { 0, 0}
+};
+
+/* End of file */
+
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_PutVLCBits.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_PutVLCBits.c
new file mode 100644
index 0000000..ca9efec
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_PutVLCBits.c
@@ -0,0 +1,200 @@
+/**
+ *
+ * File Name: armVCM4P2_PutVLCBits.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains module for VLC put bits to bitstream
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+
+#include "armVC.h"
+#include "armCOMM.h"
+#include "armCOMM_Bitstream.h"
+#include "armVCM4P2_ZigZag_Tables.h"
+#include "armVCM4P2_Huff_Tables_VLC.h"
+
+
+/**
+ * Function: armVCM4P2_PutVLCBits
+ *
+ * Description:
+ * Checks the type of Escape Mode and put encoded bits for
+ * quantized DCT coefficients.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] ppBitStream pointer to the pointer to the current byte in
+ * the bit stream
+ * [in] pBitOffset pointer to the bit position in the byte pointed
+ * by *ppBitStream. Valid within 0 to 7
+ * [in] shortVideoHeader binary flag indicating presence of short_video_header; escape modes 0-3 are used if shortVideoHeader==0,
+ * and escape mode 4 is used when shortVideoHeader==1.
+ * [in] start start indicates whether the encoding begins with
+ * 0th element or 1st.
+ * [in] maxStoreRunL0 Max store possible (considering last and inter/intra)
+ * for last = 0
+ * [in] maxStoreRunL1 Max store possible (considering last and inter/intra)
+ * for last = 1
+ * [in] maxRunForMultipleEntriesL0
+ * The run value after which level
+ * will be equal to 1:
+ * (considering last and inter/intra status) for last = 0
+ * [in] maxRunForMultipleEntriesL1
+ * The run value after which level
+ * will be equal to 1:
+ * (considering last and inter/intra status) for last = 1
+ * [in] pRunIndexTableL0 Run Index table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 0
+ * [in] pVlcTableL0 VLC table for last == 0
+ * [in] pRunIndexTableL1 Run Index table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 1
+ * [in] pVlcTableL1 VLC table for last == 1
+ * [in] pLMAXTableL0 Level MAX table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 0
+ * [in] pLMAXTableL1 Level MAX table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 1
+ * [in] pRMAXTableL0 Run MAX table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 0
+ * [in] pRMAXTableL1 Run MAX table defined in
+ * armVCM4P2_Huff_Tables_VLC.c for last == 1
+ * [out] pQDctBlkCoef pointer to the quantized DCT coefficient
+ * [out] ppBitStream *ppBitStream is updated after the block is encoded
+ * so that it points to the current byte in the bit
+ * stream buffer.
+ * [out] pBitOffset *pBitOffset is updated so that it points to the
+ * current bit position in the byte pointed by
+ * *ppBitStream.
+ *
+ * Return Value:
+ * Standard OMXResult result. See enumeration for possible result codes.
+ *
+ */
+
+
+OMXResult armVCM4P2_PutVLCBits (
+ OMX_U8 **ppBitStream,
+ OMX_INT * pBitOffset,
+ const OMX_S16 *pQDctBlkCoef,
+ OMX_INT shortVideoHeader,
+ OMX_U8 start,
+ OMX_U8 maxStoreRunL0,
+ OMX_U8 maxStoreRunL1,
+ OMX_U8 maxRunForMultipleEntriesL0,
+ OMX_U8 maxRunForMultipleEntriesL1,
+ const OMX_U8 * pRunIndexTableL0,
+ const ARM_VLC32 *pVlcTableL0,
+ const OMX_U8 * pRunIndexTableL1,
+ const ARM_VLC32 *pVlcTableL1,
+ const OMX_U8 * pLMAXTableL0,
+ const OMX_U8 * pLMAXTableL1,
+ const OMX_U8 * pRMAXTableL0,
+ const OMX_U8 * pRMAXTableL1,
+ const OMX_U8 * pZigzagTable
+)
+{
+
+ OMX_U32 storeRun = 0, run, storeRunPlus;
+ OMX_U8 last = 0, first = 1, fMode;
+ OMX_S16 level, storeLevel = 0, storeLevelPlus;
+ OMX_INT i;
+
+ /* RLE encoding and packing the bits into the streams */
+ for (i = start, run=0; i < 64; i++)
+ {
+ level = pQDctBlkCoef[pZigzagTable[i]];
+
+ /* Counting the run */
+ if (level == 0)
+ {
+ run++;
+ }
+
+ /* Found a non-zero coeff */
+ else
+ {
+ if (first == 0)
+ {
+ last = 0;
+
+ /* Check for a valid entry in the VLC table */
+ storeLevelPlus = armSignCheck(storeLevel) *
+ (armAbs(storeLevel) - pLMAXTableL0[storeRun]);
+ storeRunPlus = storeRun -
+ (pRMAXTableL0[armAbs(storeLevel) - 1] + 1);
+
+ fMode = armVCM4P2_CheckVLCEscapeMode(
+ storeRun,
+ storeRunPlus,
+ storeLevel,
+ storeLevelPlus,
+ maxStoreRunL0,
+ maxRunForMultipleEntriesL0,
+ shortVideoHeader,
+ pRunIndexTableL0);
+
+ armVCM4P2_FillVLCBuffer (
+ ppBitStream,
+ pBitOffset,
+ storeRun,
+ storeLevel,
+ storeRunPlus,
+ storeLevelPlus,
+ fMode,
+ last,
+ maxRunForMultipleEntriesL0,
+ pRunIndexTableL0,
+ pVlcTableL0);
+ }
+ storeLevel = level;
+ storeRun = run;
+ first = 0;
+ run = 0;
+ }
+
+ } /* end of for loop for 64 elements */
+
+ /* writing the last element */
+ last = 1;
+
+ /* Check for a valid entry in the VLC table */
+ storeLevelPlus = armSignCheck(storeLevel) *
+ (armAbs(storeLevel) - pLMAXTableL1[run]);
+ storeRunPlus = storeRun -
+ (pRMAXTableL1[armAbs(storeLevel) - 1] + 1);
+ fMode = armVCM4P2_CheckVLCEscapeMode(
+ storeRun,
+ storeRunPlus,
+ storeLevel,
+ storeLevelPlus,
+ maxStoreRunL1,
+ maxRunForMultipleEntriesL1,
+ shortVideoHeader,
+ pRunIndexTableL1);
+
+ armVCM4P2_FillVLCBuffer (
+ ppBitStream,
+ pBitOffset,
+ storeRun,
+ storeLevel,
+ storeRunPlus,
+ storeLevelPlus,
+ fMode,
+ last,
+ maxRunForMultipleEntriesL1,
+ pRunIndexTableL1,
+ pVlcTableL1);
+ return OMX_Sts_NoErr;
+}
+
+/* End of File */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_SetPredDir.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_SetPredDir.c
new file mode 100644
index 0000000..a9cd008
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_SetPredDir.c
@@ -0,0 +1,89 @@
+/**
+ *
+ * File Name: armVCM4P2_SetPredDir.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains module for detecting the prediction direction
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+
+#include "armVC.h"
+#include "armCOMM.h"
+
+/**
+ * Function: armVCM4P2_SetPredDir
+ *
+ * Description:
+ * Performs detecting the prediction direction
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] blockIndex block index indicating the component type and
+ * position as defined in subclause 6.1.3.8, of ISO/IEC
+ * 14496-2. Furthermore, indexes 6 to 9 indicate the
+ * alpha blocks spatially corresponding to luminance
+ * blocks 0 to 3 in the same macroblock.
+ * [in] pCoefBufRow pointer to the coefficient row buffer
+ * [in] pQpBuf pointer to the quantization parameter buffer
+ * [out] predQP quantization parameter of the predictor block
+ * [out] predDir indicates the prediction direction which takes one
+ * of the following values:
+ * OMX_VC_HORIZONTAL predict horizontally
+ * OMX_VC_VERTICAL predict vertically
+ *
+ * Return Value:
+ * Standard OMXResult result. See enumeration for possible result codes.
+ *
+ */
+
+OMXResult armVCM4P2_SetPredDir(
+ OMX_INT blockIndex,
+ OMX_S16 *pCoefBufRow,
+ OMX_S16 *pCoefBufCol,
+ OMX_INT *predDir,
+ OMX_INT *predQP,
+ const OMX_U8 *pQpBuf
+)
+{
+ OMX_U8 blockDCLeft;
+ OMX_U8 blockDCTop;
+ OMX_U8 blockDCTopLeft;
+
+ if (blockIndex == 3)
+ {
+ blockDCTop = *(pCoefBufCol - 8);
+ }
+ else
+ {
+ blockDCTop = *pCoefBufRow;
+ }
+ blockDCLeft = *pCoefBufCol;
+ blockDCTopLeft = *(pCoefBufRow - 8);
+
+ if (armAbs(blockDCLeft - blockDCTopLeft) < armAbs(blockDCTopLeft \
+ - blockDCTop))
+ {
+ *predDir = OMX_VC_VERTICAL;
+ *predQP = pQpBuf[1];
+ }
+ else
+ {
+ *predDir = OMX_VC_HORIZONTAL;
+ *predQP = pQpBuf[0];
+ }
+ return OMX_Sts_NoErr;
+}
+
+
+/*End of File*/
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_Zigzag_Tables.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_Zigzag_Tables.c
new file mode 100644
index 0000000..a247c69
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_Zigzag_Tables.c
@@ -0,0 +1,58 @@
+ /**
+ *
+ * File Name: armVCM4P2_Zigzag_Tables.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * File: armVCM4P2_ZigZag_Tables.c
+ * Description: Contains the zigzag tables
+ *
+ */
+
+#include "omxtypes.h"
+
+const OMX_U8 armVCM4P2_aClassicalZigzagScan [64] =
+{
+ 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
+};
+
+const OMX_U8 armVCM4P2_aHorizontalZigzagScan [64] =
+{
+ 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
+};
+
+const OMX_U8 armVCM4P2_aVerticalZigzagScan [64] =
+{
+ 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
+};
+
+
+/* End of file */
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_BlockMatch_Half_16x16.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_BlockMatch_Half_16x16.c
new file mode 100644
index 0000000..dcd3ce1
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_BlockMatch_Half_16x16.c
@@ -0,0 +1,111 @@
+/**
+ *
+ * File Name: omxVCM4P2_BlockMatch_Half_16x16.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains modules for Block matching, a full search algorithm
+ * is implemented
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armVC.h"
+#include "armCOMM.h"
+
+/**
+ * Function: omxVCM4P2_BlockMatch_Half_16x16 (6.2.4.2.3)
+ *
+ * Description:
+ * Performs a 16x16 block match with half-pixel resolution. Returns the
+ * estimated motion vector and associated minimum SAD. This function
+ * estimates the half-pixel motion vector by interpolating the integer
+ * resolution motion vector referenced by the input parameter pSrcDstMV, i.e.,
+ * the initial integer MV is generated externally. The input parameters
+ * pSrcRefBuf and pSearchPointRefPos should be shifted by the winning MV of
+ * 16x16 integer search prior to calling BlockMatch_Half_16x16. The function
+ * BlockMatch_Integer_16x16 may be used for integer motion estimation.
+ *
+ * Input Arguments:
+ *
+ * pSrcRefBuf - pointer to the reference Y plane; points to the reference
+ * macroblock that corresponds to the location of the current
+ * macroblock in the current plane.
+ * refWidth - width of the reference plane
+ * pRefRect - reference plane valid region rectangle
+ * pSrcCurrBuf - pointer to the current block in the current macroblock
+ * buffer extracted from the original plane (linear array, 256
+ * entries); must be aligned on a 16-byte boundary. The number of
+ * bytes between lines (step) is 16.
+ * pSearchPointRefPos - position of the starting point for half pixel
+ * search (specified in terms of integer pixel units) in the
+ * reference plane, i.e., the reference position pointed to by the
+ * predicted motion vector.
+ * rndVal - rounding control parameter: 0 - disabled; 1 - enabled.
+ * pSrcDstMV - pointer to the initial MV estimate; typically generated
+ * during a prior 16X16 integer search; specified in terms of
+ * half-pixel units.
+ *
+ * Output Arguments:
+ *
+ * pSrcDstMV - pointer to estimated MV
+ * pDstSAD - pointer to minimum SAD
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments. Returned if one of the following
+ * conditions is true:
+ * - at least one of the following pointers is NULL: pSrcRefBuf,
+ * pRefRect, pSrcCurrBuff, pSearchPointRefPos, pSrcDstMV.
+ * - pSrcCurrBuf is not 16-byte aligned, or
+ *
+ */
+
+OMXResult omxVCM4P2_BlockMatch_Half_16x16(
+ const OMX_U8 *pSrcRefBuf,
+ OMX_INT refWidth,
+ const OMXRect *pRefRect,
+ const OMX_U8 *pSrcCurrBuf,
+ const OMXVCM4P2Coordinate *pSearchPointRefPos,
+ OMX_INT rndVal,
+ OMXVCMotionVector *pSrcDstMV,
+ OMX_INT *pDstSAD
+)
+{
+
+ /* For a blocksize of 16x16 */
+ OMX_U8 BlockSize = 16;
+
+ /* Argument error checks */
+ armRetArgErrIf(pSrcRefBuf == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pRefRect == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pSrcCurrBuf == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pSearchPointRefPos == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pSrcDstMV == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(!armIs16ByteAligned(pSrcCurrBuf), OMX_Sts_BadArgErr);
+
+ return (armVCM4P2_BlockMatch_Half(
+ pSrcRefBuf,
+ refWidth,
+ pRefRect,
+ pSrcCurrBuf,
+ pSearchPointRefPos,
+ rndVal,
+ pSrcDstMV,
+ pDstSAD,
+ BlockSize));
+
+
+}
+
+/* End of file */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_BlockMatch_Half_8x8.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_BlockMatch_Half_8x8.c
new file mode 100644
index 0000000..6996e6d
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_BlockMatch_Half_8x8.c
@@ -0,0 +1,109 @@
+/**
+ *
+ * File Name: omxVCM4P2_BlockMatch_Half_8x8.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains modules for Block matching, a full search algorithm
+ * is implemented
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armVC.h"
+#include "armCOMM.h"
+
+
+/**
+ * Function: omxVCM4P2_BlockMatch_Half_8x8 (6.2.4.2.4)
+ *
+ * Description:
+ * Performs an 8x8 block match with half-pixel resolution. Returns the
+ * estimated motion vector and associated minimum SAD. This function
+ * estimates the half-pixel motion vector by interpolating the integer
+ * resolution motion vector referenced by the input parameter pSrcDstMV, i.e.,
+ * the initial integer MV is generated externally. The input parameters
+ * pSrcRefBuf and pSearchPointRefPos should be shifted by the winning MV of
+ * 8x8 integer search prior to calling BlockMatch_Half_8x8. The function
+ * BlockMatch_Integer_8x8 may be used for integer motion estimation.
+ *
+ * Input Arguments:
+ *
+ * pSrcRefBuf - pointer to the reference Y plane; points to the reference
+ * block that corresponds to the location of the current 8x8 block
+ * in the current plane.
+ * refWidth - width of the reference plane
+ * pRefRect - reference plane valid region rectangle
+ * pSrcCurrBuf - pointer to the current block in the current macroblock
+ * buffer extracted from the original plane (linear array, 128
+ * entries); must be aligned on a 8-byte boundary. The number of
+ * bytes between lines (step) is 16.
+ * pSearchPointRefPos - position of the starting point for half pixel
+ * search (specified in terms of integer pixel units) in the
+ * reference plane.
+ * rndVal - rounding control parameter: 0 - disabled; 1 - enabled.
+ * pSrcDstMV - pointer to the initial MV estimate; typically generated
+ * during a prior 8x8 integer search, specified in terms of
+ * half-pixel units.
+ *
+ * Output Arguments:
+ *
+ * pSrcDstMV - pointer to estimated MV
+ * pDstSAD - pointer to minimum SAD
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments. Returned if one of the following
+ * conditions is true:
+ * - at least one of the following pointers is NULL:
+ * pSrcRefBuf, pRefRect, pSrcCurrBuff, pSearchPointRefPos, pSrcDstMV
+ * - pSrcCurrBuf is not 8-byte aligned
+ *
+ */
+
+OMXResult omxVCM4P2_BlockMatch_Half_8x8(
+ const OMX_U8 *pSrcRefBuf,
+ OMX_INT refWidth,
+ const OMXRect *pRefRect,
+ const OMX_U8 *pSrcCurrBuf,
+ const OMXVCM4P2Coordinate *pSearchPointRefPos,
+ OMX_INT rndVal,
+ OMXVCMotionVector *pSrcDstMV,
+ OMX_INT *pDstSAD
+)
+{
+ /* For a blocksize of 8x8 */
+ OMX_U8 BlockSize = 8;
+
+ /* Argument error checks */
+ armRetArgErrIf(pSrcRefBuf == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pRefRect == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pSrcCurrBuf == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pSearchPointRefPos == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pSrcDstMV == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(!armIs8ByteAligned(pSrcCurrBuf), OMX_Sts_BadArgErr);
+
+ return (armVCM4P2_BlockMatch_Half(
+ pSrcRefBuf,
+ refWidth,
+ pRefRect,
+ pSrcCurrBuf,
+ pSearchPointRefPos,
+ rndVal,
+ pSrcDstMV,
+ pDstSAD,
+ BlockSize));
+
+}
+
+/* End of file */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_BlockMatch_Integer_16x16.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_BlockMatch_Integer_16x16.c
new file mode 100644
index 0000000..e714ef1
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_BlockMatch_Integer_16x16.c
@@ -0,0 +1,114 @@
+/**
+ *
+ * File Name: omxVCM4P2_BlockMatch_Integer_16x16.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains modules for Block matching, a full search algorithm
+ * is implemented
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armVC.h"
+#include "armCOMM.h"
+
+/**
+ * Function: omxVCM4P2_BlockMatch_Integer_16x16 (6.2.4.2.1)
+ *
+ * Description:
+ * Performs a 16x16 block search; estimates motion vector and associated
+ * minimum SAD. Both the input and output motion vectors are represented using
+ * half-pixel units, and therefore a shift left or right by 1 bit may be
+ * required, respectively, to match the input or output MVs with other
+ * functions that either generate output MVs or expect input MVs represented
+ * using integer pixel units.
+ *
+ * Input Arguments:
+ *
+ * pSrcRefBuf - pointer to the reference Y plane; points to the reference
+ * MB that corresponds to the location of the current macroblock in
+ * the current plane.
+ * refWidth - width of the reference plane
+ * pRefRect - pointer to the valid reference plane rectangle; coordinates
+ * are specified relative to the image origin. Rectangle
+ * boundaries may extend beyond image boundaries if the image has
+ * been padded. For example, if padding extends 4 pixels beyond
+ * frame border, then the value for the left border could be set to
+ * -4.
+ * pSrcCurrBuf - pointer to the current block in the current macroblock
+ * buffer extracted from the original plane (linear array, 256
+ * entries); must be aligned on a 16-byte boundary. The number of
+ * bytes between lines (step) is 16.
+ * pCurrPointPos - position of the current macroblock in the current plane
+ * pSrcPreMV - pointer to predicted motion vector; NULL indicates no
+ * predicted MV
+ * pSrcPreSAD - pointer to SAD associated with the predicted MV (referenced
+ * by pSrcPreMV); may be set to NULL if unavailable.
+ * pMESpec - vendor-specific motion estimation specification structure;
+ * must have been allocated and then initialized using
+ * omxVCM4P2_MEInit prior to calling the block matching function.
+ *
+ * Output Arguments:
+ *
+ * pDstMV - pointer to estimated MV
+ * pDstSAD - pointer to minimum SAD
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments. Returned if one of the following
+ * conditions is true:
+ * - at least one of the following pointers is NULL: pSrcRefBuf,
+ * pRefRect, pSrcCurrBuff, pCurrPointPos, pDstMV, pDstSAD or
+ * pMESpec, or
+ * - pSrcCurrBuf is not 16-byte aligned
+ *
+ */
+
+OMXResult omxVCM4P2_BlockMatch_Integer_16x16(
+ const OMX_U8 *pSrcRefBuf,
+ OMX_INT refWidth,
+ const OMXRect *pRefRect,
+ const OMX_U8 *pSrcCurrBuf,
+ const OMXVCM4P2Coordinate *pCurrPointPos,
+ const OMXVCMotionVector *pSrcPreMV,
+ const OMX_INT *pSrcPreSAD,
+ void *pMESpec,
+ OMXVCMotionVector *pDstMV,
+ OMX_INT *pDstSAD
+)
+{
+
+ OMX_U8 BlockSize = 16;
+
+ /* Argument error checks */
+ armRetArgErrIf(!armIs16ByteAligned(pSrcCurrBuf), OMX_Sts_BadArgErr);
+
+ return ( armVCM4P2_BlockMatch_Integer(
+ pSrcRefBuf,
+ refWidth,
+ pRefRect,
+ pSrcCurrBuf,
+ pCurrPointPos,
+ pSrcPreMV,
+ pSrcPreSAD,
+ pMESpec,
+ pDstMV,
+ pDstSAD,
+ BlockSize)
+ );
+
+
+}
+
+/* End of file */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_BlockMatch_Integer_8x8.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_BlockMatch_Integer_8x8.c
new file mode 100644
index 0000000..607e64c
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_BlockMatch_Integer_8x8.c
@@ -0,0 +1,110 @@
+/**
+ *
+ * File Name: omxVCM4P2_BlockMatch_Integer_8x8.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains modules for Block matching, a full search algorithm
+ * is implemented
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armVC.h"
+#include "armCOMM.h"
+
+/**
+ * Function: omxVCM4P2_BlockMatch_Integer_8x8 (6.2.4.2.2)
+ *
+ * Description:
+ * Performs an 8x8 block search; estimates motion vector and associated
+ * minimum SAD. Both the input and output motion vectors are represented
+ * using half-pixel units, and therefore a shift left or right by 1 bit may be
+ * required, respectively, to match the input or output MVs with other
+ * functions that either generate output MVs or expect input MVs represented
+ * using integer pixel units.
+ *
+ * Input Arguments:
+ *
+ * pSrcRefBuf - pointer to the reference Y plane; points to the reference
+ * block that corresponds to the location of the current 8x8 block
+ * in the current plane.
+ * refWidth - width of the reference plane
+ * pRefRect - pointer to the valid reference plane rectangle; coordinates
+ * are specified relative to the image origin. Rectangle
+ * boundaries may extend beyond image boundaries if the image has
+ * been padded.
+ * pSrcCurrBuf - pointer to the current block in the current macroblock
+ * buffer extracted from the original plane (linear array, 128
+ * entries); must be aligned on an 8-byte boundary. The number of
+ * bytes between lines (step) is 16 bytes.
+ * pCurrPointPos - position of the current block in the current plane
+ * pSrcPreMV - pointer to predicted motion vector; NULL indicates no
+ * predicted MV
+ * pSrcPreSAD - pointer to SAD associated with the predicted MV (referenced
+ * by pSrcPreMV); may be set to NULL if unavailable.
+ * pMESpec - vendor-specific motion estimation specification structure;
+ * must have been allocated and then initialized using
+ * omxVCM4P2_MEInit prior to calling the block matching function.
+ *
+ * Output Arguments:
+ *
+ * pDstMV - pointer to estimated MV
+ * pDstSAD - pointer to minimum SAD
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments. Returned if one of the following
+ * conditions is true:
+ * - at least one of the following pointers is NULL: pSrcRefBuf,
+ * pRefRect, pSrcCurrBuff, pCurrPointPos, pDstMV, pDstSAD or
+ * pMESpec, or
+ * - pSrcCurrBuf is not 8-byte aligned
+ *
+ */
+
+OMXResult omxVCM4P2_BlockMatch_Integer_8x8(
+ const OMX_U8 *pSrcRefBuf,
+ OMX_INT refWidth,
+ const OMXRect *pRefRect,
+ const OMX_U8 *pSrcCurrBuf,
+ const OMXVCM4P2Coordinate *pCurrPointPos,
+ const OMXVCMotionVector *pSrcPreMV,
+ const OMX_INT *pSrcPreSAD,
+ void *pMESpec,
+ OMXVCMotionVector *pDstMV,
+ OMX_INT *pDstSAD
+)
+{
+ OMX_U8 BlockSize = 8;
+
+ /* Argument error checks */
+ armRetArgErrIf(!armIs8ByteAligned(pSrcCurrBuf), OMX_Sts_BadArgErr);
+
+ return ( armVCM4P2_BlockMatch_Integer(
+ pSrcRefBuf,
+ refWidth,
+ pRefRect,
+ pSrcCurrBuf,
+ pCurrPointPos,
+ pSrcPreMV,
+ pSrcPreSAD,
+ pMESpec,
+ pDstMV,
+ pDstSAD,
+ BlockSize)
+ );
+
+}
+
+/* End of file */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DCT8x8blk.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DCT8x8blk.c
new file mode 100644
index 0000000..a077ac8
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DCT8x8blk.c
@@ -0,0 +1,87 @@
+/**
+ *
+ * File Name: omxVCM4P2_DCT8x8blk.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains modules for 8x8 block DCT
+ *
+ */
+
+#include <math.h>
+#include "omxtypes.h"
+#include "armOMX.h"
+
+#include "armCOMM.h"
+#include "armVCM4P2_DCT_Table.h"
+
+/**
+ * Function: omxVCM4P2_DCT8x8blk (6.2.4.4.1)
+ *
+ * Description:
+ * Computes a 2D forward DCT for a single 8x8 block, as defined in
+ * [ISO14496-2].
+ *
+ * Input Arguments:
+ *
+ * pSrc - pointer to the start of the linearly arranged input buffer; must
+ * be aligned on a 16-byte boundary. Input values (pixel
+ * intensities) are valid in the range [-255,255].
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the start of the linearly arranged output buffer; must
+ * be aligned on a 16-byte boundary.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments, returned if:
+ * - pSrc or pDst is NULL.
+ * - pSrc or pDst is not 16-byte aligned.
+ *
+ */
+
+OMXResult omxVCM4P2_DCT8x8blk (const OMX_S16 *pSrc, OMX_S16 *pDst)
+{
+ OMX_INT x, y, u, v;
+
+ /* Argument error checks */
+ armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(!armIs16ByteAligned(pSrc), OMX_Sts_BadArgErr);
+ armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(!armIs16ByteAligned(pDst), OMX_Sts_BadArgErr);
+
+
+ for (u = 0; u < 8; u++)
+ {
+ for (v = 0; v < 8; v++)
+ {
+ OMX_F64 sum = 0.0;
+ for (x = 0; x < 8; x++)
+ {
+ for (y = 0; y < 8; y++)
+ {
+ sum += pSrc[(x * 8) + y] *
+ armVCM4P2_preCalcDCTCos[x][u] *
+ armVCM4P2_preCalcDCTCos[y][v];
+ }
+ }
+ pDst[(u * 8) + v]= armRoundFloatToS16 (sum);
+ }
+ }
+
+ return OMX_Sts_NoErr;
+}
+
+
+
+/* End of file */
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Inter.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Inter.c
new file mode 100644
index 0000000..51f7bab
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Inter.c
@@ -0,0 +1,115 @@
+/**
+ *
+ * File Name: omxVCM4P2_DecodeBlockCoef_Inter.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains modules for inter reconstruction
+ *
+ */
+
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+
+
+/**
+ * Function: omxVCM4P2_DecodeBlockCoef_Inter (6.2.5.4.2)
+ *
+ * Description:
+ * Decodes the INTER block coefficients. This function performs inverse
+ * quantization, inverse zigzag positioning, and IDCT (with appropriate
+ * clipping on each step) on the coefficients. The results (residuals) are
+ * placed in a contiguous array of 64 elements. For INTER block, the output
+ * buffer holds the residuals for further reconstruction.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - pointer to the pointer to the current byte in the bit
+ * stream buffer. There is no boundary check for the bit stream
+ * buffer.
+ * pBitOffset - pointer to the bit position in the byte pointed to by
+ * *ppBitStream. *pBitOffset is valid within [0-7]
+ * QP - quantization parameter
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; shortVideoHeader==1 selects linear intra DC
+ * mode, and shortVideoHeader==0 selects non linear intra DC mode.
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after the block is decoded, so
+ * that it points to the current byte in the bit stream buffer
+ * pBitOffset - *pBitOffset is updated so that it points to the current bit
+ * position in the byte pointed by *ppBitStream
+ * pDst - pointer to the decoded residual buffer (a contiguous array of 64
+ * elements of OMX_S16 data type); must be aligned on a 16-byte
+ * boundary.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments, if:
+ * - At least one of the following pointers is Null:
+ * ppBitStream, *ppBitStream, pBitOffset , pDst
+ * - *pBitOffset exceeds [0,7]
+ * - QP <= 0.
+ * - pDst is not 16-byte aligned
+ * OMX_Sts_Err - status error. Refer to OMX_Sts_Err of DecodeVLCZigzag_Inter .
+ *
+ */
+OMXResult omxVCM4P2_DecodeBlockCoef_Inter(
+ const OMX_U8 ** ppBitStream,
+ OMX_INT * pBitOffset,
+ OMX_S16 * pDst,
+ OMX_INT QP,
+ OMX_INT shortVideoHeader
+)
+{
+ /* 64 elements are needed but to align it to 16 bytes need
+ 15 more elements of padding */
+ OMX_S16 tempBuf[79];
+ OMX_S16 *pTempBuf1;
+ OMXResult errorCode;
+ /* Aligning the local buffers */
+ pTempBuf1 = armAlignTo16Bytes(tempBuf);
+
+ /* Argument error checks */
+ armRetArgErrIf(ppBitStream == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(*ppBitStream == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pBitOffset == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(!armIs16ByteAligned(pDst), OMX_Sts_BadArgErr);
+ armRetArgErrIf(((QP <= 0) || (QP >= 32)), OMX_Sts_BadArgErr);
+ armRetArgErrIf(((*pBitOffset < 0) || (*pBitOffset > 7)), OMX_Sts_BadArgErr);
+
+
+ /* VLD and zigzag */
+ errorCode = omxVCM4P2_DecodeVLCZigzag_Inter(ppBitStream, pBitOffset,
+ pTempBuf1,shortVideoHeader);
+ armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode);
+
+ /* Dequantization */
+ errorCode = omxVCM4P2_QuantInvInter_I(
+ pTempBuf1,
+ QP);
+ armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode);
+
+ /* Inverse transform */
+ errorCode = omxVCM4P2_IDCT8x8blk(pTempBuf1, pDst);
+ armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode);
+
+ return OMX_Sts_NoErr;
+}
+
+/* End of file */
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Intra.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Intra.c
new file mode 100644
index 0000000..a0b2376
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Intra.c
@@ -0,0 +1,225 @@
+/**
+ *
+ * File Name: omxVCM4P2_DecodeBlockCoef_Intra.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains modules for intra reconstruction
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/**
+ * Function: omxVCM4P2_DecodeBlockCoef_Intra (6.2.5.4.1)
+ *
+ * Description:
+ * Decodes the INTRA block coefficients. Inverse quantization, inversely
+ * zigzag positioning, and IDCT, with appropriate clipping on each step, are
+ * performed on the coefficients. The results are then placed in the output
+ * frame/plane on a pixel basis. Note: This function will be used only when
+ * at least one non-zero AC coefficient of current block exists in the bit
+ * stream. The DC only condition will be handled in another function.
+ *
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - pointer to the pointer to the current byte in the bit
+ * stream buffer. There is no boundary check for the bit stream
+ * buffer.
+ * pBitOffset - pointer to the bit position in the byte pointed to by
+ * *ppBitStream. *pBitOffset is valid within [0-7].
+ * step - width of the destination plane
+ * pCoefBufRow - pointer to the coefficient row buffer; must be aligned on
+ * an 8-byte boundary.
+ * pCoefBufCol - pointer to the coefficient column buffer; must be aligned
+ * on an 8-byte boundary.
+ * curQP - quantization parameter of the macroblock which the current block
+ * belongs to
+ * pQPBuf - pointer to the quantization parameter buffer
+ * blockIndex - block index indicating the component type and position as
+ * defined in [ISO14496-2], subclause 6.1.3.8, Figure 6-5.
+ * intraDCVLC - a code determined by intra_dc_vlc_thr and QP. This allows a
+ * mechanism to switch between two VLC for coding of Intra DC
+ * coefficients as per [ISO14496-2], Table 6-21.
+ * ACPredFlag - a flag equal to ac_pred_flag (of luminance) indicating if
+ * the ac coefficients of the first row or first column are
+ * differentially coded for intra coded macroblock.
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; shortVideoHeader==1 selects linear intra DC
+ * mode, and shortVideoHeader==0 selects non linear intra DC mode.
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after the block is decoded, so
+ * that it points to the current byte in the bit stream buffer
+ * pBitOffset - *pBitOffset is updated so that it points to the current bit
+ * position in the byte pointed by *ppBitStream
+ * pDst - pointer to the block in the destination plane; must be aligned on
+ * an 8-byte boundary.
+ * pCoefBufRow - pointer to the updated coefficient row buffer.
+ * pCoefBufCol - pointer to the updated coefficient column buffer Note:
+ * The coefficient buffers must be updated in accordance with the
+ * update procedure defined in section 6.2.2.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments, if:
+ * - At least one of the following pointers is NULL:
+ * ppBitStream, *ppBitStream, pBitOffset, pCoefBufRow, pCoefBufCol,
+ * pQPBuf, pDst.
+ * - *pBitOffset exceeds [0,7]
+ * - curQP exceeds (1, 31)
+ * - blockIndex exceeds [0,5]
+ * - step is not the multiple of 8
+ * - a pointer alignment requirement was violated.
+ * OMX_Sts_Err - status error. Refer to OMX_Sts_Err of DecodeVLCZigzag_Intra.
+ *
+ */
+
+OMXResult omxVCM4P2_DecodeBlockCoef_Intra(
+ const OMX_U8 ** ppBitStream,
+ OMX_INT *pBitOffset,
+ OMX_U8 *pDst,
+ OMX_INT step,
+ OMX_S16 *pCoefBufRow,
+ OMX_S16 *pCoefBufCol,
+ OMX_U8 curQP,
+ const OMX_U8 *pQPBuf,
+ OMX_INT blockIndex,
+ OMX_INT intraDCVLC,
+ OMX_INT ACPredFlag,
+ OMX_INT shortVideoHeader
+ )
+{
+ OMX_S16 tempBuf1[79], tempBuf2[79];
+ OMX_S16 *pTempBuf1, *pTempBuf2;
+ OMX_INT predDir, predACDir, i, j, count;
+ OMX_INT predQP;
+ OMXVCM4P2VideoComponent videoComp;
+ OMXResult errorCode;
+
+ /* Argument error checks */
+ armRetArgErrIf(ppBitStream == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(*ppBitStream == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pBitOffset == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pCoefBufRow == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pCoefBufCol == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pQPBuf == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(!armIs8ByteAligned(pDst), OMX_Sts_BadArgErr);
+ armRetArgErrIf(((curQP <= 0) || (curQP >= 32)), OMX_Sts_BadArgErr);
+ armRetArgErrIf((*pBitOffset < 0) || (*pBitOffset >7), OMX_Sts_BadArgErr);
+ armRetArgErrIf((blockIndex < 0) || (blockIndex > 5), OMX_Sts_BadArgErr);
+ armRetArgErrIf((step % 8) != 0, OMX_Sts_BadArgErr);
+
+
+ /* Aligning the local buffers */
+ pTempBuf1 = armAlignTo16Bytes(tempBuf1);
+ pTempBuf2 = armAlignTo16Bytes(tempBuf2);
+
+ /* Setting the AC prediction direction and prediction direction */
+ armVCM4P2_SetPredDir(
+ blockIndex,
+ pCoefBufRow,
+ pCoefBufCol,
+ &predDir,
+ &predQP,
+ pQPBuf);
+
+ predACDir = predDir;
+
+ armRetArgErrIf(((predQP <= 0) || (predQP >= 32)), OMX_Sts_BadArgErr);
+
+ if (ACPredFlag == 0)
+ {
+ predACDir = OMX_VC_NONE;
+ }
+
+ /* Setting the videoComp */
+ if (blockIndex <= 3)
+ {
+ videoComp = OMX_VC_LUMINANCE;
+ }
+ else
+ {
+ videoComp = OMX_VC_CHROMINANCE;
+ }
+
+
+ /* VLD and zigzag */
+ if (intraDCVLC == 1)
+ {
+ errorCode = omxVCM4P2_DecodeVLCZigzag_IntraDCVLC(
+ ppBitStream,
+ pBitOffset,
+ pTempBuf1,
+ predACDir,
+ shortVideoHeader,
+ videoComp);
+ armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode);
+ }
+ else
+ {
+ errorCode = omxVCM4P2_DecodeVLCZigzag_IntraACVLC(
+ ppBitStream,
+ pBitOffset,
+ pTempBuf1,
+ predACDir,
+ shortVideoHeader);
+ armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode);
+ }
+
+ /* AC DC prediction */
+ errorCode = omxVCM4P2_PredictReconCoefIntra(
+ pTempBuf1,
+ pCoefBufRow,
+ pCoefBufCol,
+ curQP,
+ predQP,
+ predDir,
+ ACPredFlag,
+ videoComp);
+ armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode);
+
+ /* Dequantization */
+ errorCode = omxVCM4P2_QuantInvIntra_I(
+ pTempBuf1,
+ curQP,
+ videoComp,
+ shortVideoHeader);
+ armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode);
+
+ /* Inverse transform */
+ errorCode = omxVCM4P2_IDCT8x8blk (pTempBuf1, pTempBuf2);
+ armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode);
+
+ /* Placing the linear array into the destination plane and clipping
+ it to 0 to 255 */
+ for (j = 0, count = 0; j < 8; j++)
+ {
+ for(i = 0; i < 8; i++, count++)
+ {
+ pDst[i] = armClip (0, 255, pTempBuf2[count]);
+ }
+ pDst += step;
+ }
+
+ return OMX_Sts_NoErr;
+}
+
+/* End of file */
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodePadMV_PVOP.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodePadMV_PVOP.c
new file mode 100644
index 0000000..7e159b7
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodePadMV_PVOP.c
@@ -0,0 +1,243 @@
+/**
+ *
+ * File Name: omxVCM4P2_DecodePadMV_PVOP.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains module for decoding MV and padding the same
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM_Bitstream.h"
+#include "armCOMM.h"
+#include "armVCM4P2_Huff_Tables_VLC.h"
+
+
+
+/**
+ * Function: omxVCM4P2_DecodePadMV_PVOP (6.2.5.1.1)
+ *
+ * Description:
+ * Decodes and pads the four motion vectors associated with a non-intra P-VOP
+ * macroblock. For macroblocks of type OMX_VC_INTER4V, the output MV is
+ * padded as specified in [ISO14496-2], subclause 7.6.1.6. Otherwise, for
+ * macroblocks of types other than OMX_VC_INTER4V, the decoded MV is copied to
+ * all four output MV buffer entries.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - pointer to the pointer to the current byte in the bit
+ * stream buffer
+ * pBitOffset - pointer to the bit position in the byte pointed to by
+ * *ppBitStream. *pBitOffset is valid within [0-7].
+ * pSrcMVLeftMB, pSrcMVUpperMB, and pSrcMVUpperRightMB - pointers to the
+ * motion vector buffers of the macroblocks specially at the left,
+ * upper, and upper-right side of the current macroblock,
+ * respectively; a value of NULL indicates unavailability. Note:
+ * Any neighborhood macroblock outside the current VOP or video
+ * packet or outside the current GOB (when short_video_header is
+ * 1 ) for which gob_header_empty is 0 is treated as
+ * transparent, according to [ISO14496-2], subclause 7.6.5.
+ * fcodeForward - a code equal to vop_fcode_forward in MPEG-4 bit stream
+ * syntax
+ * MBType - the type of the current macroblock. If MBType is not equal to
+ * OMX_VC_INTER4V, the destination motion vector buffer is still
+ * filled with the same decoded vector.
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after the block is decoded, so
+ * that it points to the current byte in the bit stream buffer
+ * pBitOffset - *pBitOffset is updated so that it points to the current bit
+ * position in the byte pointed by *ppBitStream
+ * pDstMVCurMB - pointer to the motion vector buffer for the current
+ * macroblock; contains four decoded motion vectors
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments:
+ * - At least one of the following pointers is NULL:
+ * ppBitStream, *ppBitStream, pBitOffset, pDstMVCurMB
+ * - *pBitOffset exceeds [0,7]
+ * - fcodeForward exceeds (0,7]
+ * - MBType less than zero
+ * - motion vector buffer is not 4-byte aligned.
+ * OMX_Sts_Err - status error
+ *
+ */
+
+OMXResult omxVCM4P2_DecodePadMV_PVOP(
+ const OMX_U8 ** ppBitStream,
+ OMX_INT * pBitOffset,
+ OMXVCMotionVector * pSrcMVLeftMB,
+ OMXVCMotionVector *pSrcMVUpperMB,
+ OMXVCMotionVector * pSrcMVUpperRightMB,
+ OMXVCMotionVector * pDstMVCurMB,
+ OMX_INT fcodeForward,
+ OMXVCM4P2MacroblockType MBType
+ )
+{
+ OMXVCMotionVector diffMV;
+ OMXVCMotionVector dstMVPredME[12];
+ OMX_INT iBlk, i, count = 1;
+ OMX_S32 mvHorResidual = 1, mvVerResidual = 1, mvHorData, mvVerData;
+ OMX_S8 scaleFactor, index;
+ OMX_S16 high, low, range;
+
+
+ /* Argument error checks */
+ armRetArgErrIf(ppBitStream == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(*ppBitStream == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pBitOffset == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pDstMVCurMB == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(((*pBitOffset < 0) || (*pBitOffset > 7)), OMX_Sts_BadArgErr);
+ armRetArgErrIf(((fcodeForward < 1) || (fcodeForward > 7)), \
+ OMX_Sts_BadArgErr);
+ armRetArgErrIf(!armIs4ByteAligned(pDstMVCurMB), OMX_Sts_BadArgErr);
+
+ if ((MBType == OMX_VC_INTRA) ||
+ (MBType == OMX_VC_INTRA_Q)
+ )
+ {
+ /* All MV's are zero */
+ for (i = 0; i < 4; i++)
+ {
+ pDstMVCurMB[i].dx = 0;
+ pDstMVCurMB[i].dy = 0;
+ }
+
+ return OMX_Sts_NoErr;
+ }
+
+ if ((MBType == OMX_VC_INTER4V) || (MBType == OMX_VC_INTER4V_Q))
+ {
+ count = 4;
+ }
+ else if ((MBType == OMX_VC_INTER) || (MBType == OMX_VC_INTER_Q))
+ {
+ count = 1;
+ }
+
+ /* Calculating the scale factor */
+ scaleFactor = 1 << (fcodeForward -1);
+ high = ( 32 * scaleFactor) - 1;
+ low = ( (-32) * scaleFactor);
+ range = ( 64 * scaleFactor);
+
+ /* Huffman decoding and MV reconstruction */
+ for (iBlk = 0; iBlk < count; iBlk++)
+ {
+
+ /* Huffman decoding to get Horizontal data and residual */
+ index = armUnPackVLC32(ppBitStream, pBitOffset,
+ armVCM4P2_aVlcMVD);
+ armRetDataErrIf(index == -1, OMX_Sts_Err);
+
+ mvHorData = index - 32;
+
+ if ((fcodeForward > 1) && (mvHorData != 0))
+ {
+ mvHorResidual = (OMX_S32) armGetBits(ppBitStream,
+ pBitOffset, (fcodeForward -1));
+ }
+
+ /* Huffman decoding to get Vertical data and residual */
+ index = armUnPackVLC32(ppBitStream, pBitOffset, armVCM4P2_aVlcMVD);
+ armRetDataErrIf(index == -1, OMX_Sts_Err);
+
+ mvVerData = index - 32;
+
+ if ((fcodeForward > 1) && (mvVerData != 0))
+ {
+ mvVerResidual = (OMX_S32) armGetBits(ppBitStream,
+ pBitOffset, (fcodeForward -1));
+ }
+
+ /* Calculating the differtial MV */
+ if ( (scaleFactor == 1) || (mvHorData == 0) )
+ {
+ diffMV.dx = mvHorData;
+ }
+ else
+ {
+ diffMV.dx = ((armAbs(mvHorData) - 1) * fcodeForward)
+ + mvHorResidual + 1;
+ if (mvHorData < 0)
+ {
+ diffMV.dx = -diffMV.dx;
+ }
+ }
+
+ if ( (scaleFactor == 1) || (mvVerData == 0) )
+ {
+ diffMV.dy = mvVerData;
+ }
+ else
+ {
+ diffMV.dy = ((armAbs(mvVerData) - 1) * fcodeForward)
+ + mvVerResidual + 1;
+ if (mvVerData < 0)
+ {
+ diffMV.dy = -diffMV.dy;
+ }
+ }
+
+ /* Find the predicted vector */
+ omxVCM4P2_FindMVpred (
+ pDstMVCurMB,
+ pSrcMVLeftMB,
+ pSrcMVUpperMB,
+ pSrcMVUpperRightMB,
+ &pDstMVCurMB[iBlk],
+ dstMVPredME,
+ iBlk);
+
+ /* Adding the difference to the predicted MV to reconstruct MV */
+ pDstMVCurMB[iBlk].dx += diffMV.dx;
+ pDstMVCurMB[iBlk].dy += diffMV.dy;
+
+ /* Checking the range and keeping it within the limits */
+ if ( pDstMVCurMB[iBlk].dx < low )
+ {
+ pDstMVCurMB[iBlk].dx += range;
+ }
+ if (pDstMVCurMB[iBlk].dx > high)
+ {
+ pDstMVCurMB[iBlk].dx -= range;
+ }
+
+ if ( pDstMVCurMB[iBlk].dy < low )
+ {
+ pDstMVCurMB[iBlk].dy += range;
+ }
+ if (pDstMVCurMB[iBlk].dy > high)
+ {
+ pDstMVCurMB[iBlk].dy -= range;
+ }
+ }
+
+ if ((MBType == OMX_VC_INTER) || (MBType == OMX_VC_INTER_Q))
+ {
+ pDstMVCurMB[1] = pDstMVCurMB[0];
+ pDstMVCurMB[2] = pDstMVCurMB[0];
+ pDstMVCurMB[3] = pDstMVCurMB[0];
+ }
+
+ return OMX_Sts_NoErr;
+}
+
+
+/* End of file */
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_Inter.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_Inter.c
new file mode 100644
index 0000000..88a8d04
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_Inter.c
@@ -0,0 +1,120 @@
+/**
+ *
+ * File Name: omxVCM4P2_DecodeVLCZigzag_Inter.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains modules for zigzag scanning and VLC decoding
+ * for inter block.
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armVC.h"
+#include "armCOMM_Bitstream.h"
+#include "armCOMM.h"
+#include "armVCM4P2_Huff_Tables_VLC.h"
+#include "armVCM4P2_ZigZag_Tables.h"
+
+
+
+/**
+ * Function: omxVCM4P2_DecodeVLCZigzag_Inter (6.2.5.2.3)
+ *
+ * Description:
+ * Performs VLC decoding and inverse zigzag scan for one inter-coded block.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - double pointer to the current byte in the stream buffer
+ * pBitOffset - pointer to the next available bit in the current stream
+ * byte referenced by *ppBitStream. The parameter *pBitOffset is
+ * valid within the range [0-7].
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; escape modes 0-3 are used if
+ * shortVideoHeader==0, and escape mode 4 is used when
+ * shortVideoHeader==1.
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after the block is decoded such
+ * that it points to the current byte in the stream buffer
+ * pBitOffset - *pBitOffset is updated after decoding such that it points
+ * to the next available bit in the stream byte referenced by
+ * *ppBitStream
+ * pDst - pointer to the coefficient buffer of current block; must be
+ * 4-byte aligned.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_BadArgErr - bad arguments:
+ * - At least one of the following pointers is NULL:
+ * ppBitStream, *ppBitStream, pBitOffset, pDst
+ * - pDst is not 4-byte aligned
+ * - *pBitOffset exceeds [0,7]
+ * OMX_Sts_Err - status error, if:
+ * - At least one mark bit is equal to zero
+ * - Encountered an illegal stream code that cannot be found in the VLC table
+ * - Encountered an illegal code in the VLC FLC table
+ * - The number of coefficients is greater than 64
+ *
+ */
+
+OMXResult omxVCM4P2_DecodeVLCZigzag_Inter(
+ const OMX_U8 ** ppBitStream,
+ OMX_INT * pBitOffset,
+ OMX_S16 * pDst,
+ OMX_INT shortVideoHeader
+)
+{
+ OMX_U8 last,start = 0;
+ const OMX_U8 *pZigzagTable = armVCM4P2_aClassicalZigzagScan;
+ OMXResult errorCode;
+
+ /* Argument error checks */
+ armRetArgErrIf(ppBitStream == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(*ppBitStream == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pBitOffset == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(!armIs4ByteAligned(pDst), OMX_Sts_BadArgErr);
+
+ errorCode = armVCM4P2_GetVLCBits (
+ ppBitStream,
+ pBitOffset,
+ pDst,
+ shortVideoHeader,
+ start,
+ &last,
+ 11,
+ 42,
+ 2,
+ 5,
+ armVCM4P2_InterL0RunIdx,
+ armVCM4P2_InterVlcL0,
+ armVCM4P2_InterL1RunIdx,
+ armVCM4P2_InterVlcL1,
+ armVCM4P2_InterL0LMAX,
+ armVCM4P2_InterL1LMAX,
+ armVCM4P2_InterL0RMAX,
+ armVCM4P2_InterL1RMAX,
+ pZigzagTable );
+ armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode);
+
+ if (last == 0)
+ {
+ return OMX_Sts_Err;
+ }
+ return OMX_Sts_NoErr;
+}
+
+/* End of file */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraACVLC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraACVLC.c
new file mode 100644
index 0000000..96593d1
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraACVLC.c
@@ -0,0 +1,103 @@
+/**
+ *
+ * File Name: omxVCM4P2_DecodeVLCZigzag_IntraACVLC.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains modules for zigzag scanning and VLC decoding
+ * for intra block.
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armVC.h"
+#include "armCOMM.h"
+
+
+
+/**
+ * Function: omxVCM4P2_DecodeVLCZigzag_IntraACVLC (6.2.5.2.2)
+ *
+ * Description:
+ * Performs VLC decoding and inverse zigzag scan of AC and DC coefficients
+ * for one intra block. Two versions of the function (DCVLC and ACVLC) are
+ * provided in order to support the two different methods of processing DC
+ * coefficients, as described in [ISO14496-2], subclause 7.4.1.4, Intra DC
+ * Coefficient Decoding for the Case of Switched VLC Encoding.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - pointer to the pointer to the current byte in the
+ * bitstream buffer
+ * pBitOffset - pointer to the bit position in the current byte referenced
+ * by *ppBitStream. The parameter *pBitOffset is valid in the
+ * range [0-7]. Bit Position in one byte: |Most Least| *pBitOffset
+ * |0 1 2 3 4 5 6 7|
+ * predDir - AC prediction direction; used to select the zigzag scan
+ * pattern; takes one of the following values: OMX_VC_NONE - AC
+ * prediction not used; performs classical zigzag scan.
+ * OMX_VC_HORIZONTAL - Horizontal prediction; performs
+ * alternate-vertical zigzag scan; OMX_VC_VERTICAL - Vertical
+ * prediction; performs alternate-horizontal zigzag scan.
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; escape modes 0-3 are used if
+ * shortVideoHeader==0, and escape mode 4 is used when
+ * shortVideoHeader==1.
+ * videoComp - video component type (luminance or chrominance) of the
+ * current block
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after the block is decoded such
+ * that it points to the current byte in the bit stream buffer
+ * pBitOffset - *pBitOffset is updated such that it points to the current
+ * bit position in the byte pointed by *ppBitStream
+ * pDst - pointer to the coefficient buffer of current block; must be
+ * 4-byte aligned.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments At least one of the following
+ * pointers is NULL: ppBitStream, *ppBitStream, pBitOffset, pDst,
+ * or At least one of the following conditions is true:
+ * *pBitOffset exceeds [0,7], preDir exceeds [0,2], or pDst is
+ * not 4-byte aligned
+ * OMX_Sts_Err In DecodeVLCZigzag_IntraDCVLC, dc_size > 12 At least one of
+ * mark bits equals zero Illegal stream encountered; code cannot
+ * be located in VLC table Forbidden code encountered in the VLC
+ * FLC table The number of coefficients is greater than 64
+ *
+ */
+
+
+OMXResult omxVCM4P2_DecodeVLCZigzag_IntraACVLC(
+ const OMX_U8 ** ppBitStream,
+ OMX_INT * pBitOffset,
+ OMX_S16 * pDst,
+ OMX_U8 predDir,
+ OMX_INT shortVideoHeader
+)
+{
+ OMX_U8 start = 0;
+
+ return armVCM4P2_DecodeVLCZigzag_Intra(
+ ppBitStream,
+ pBitOffset,
+ pDst,
+ predDir,
+ shortVideoHeader,
+ start);
+}
+
+/* End of file */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraDCVLC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraDCVLC.c
new file mode 100644
index 0000000..95e00d7
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraDCVLC.c
@@ -0,0 +1,170 @@
+/**
+ *
+ * File Name: omxVCM4P2_DecodeVLCZigzag_IntraDCVLC.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains modules for zigzag scanning and VLC decoding
+ * for intra block.
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armVC.h"
+#include "armCOMM_Bitstream.h"
+#include "armCOMM.h"
+#include "armVCM4P2_Huff_Tables_VLC.h"
+#include "armVCM4P2_ZigZag_Tables.h"
+
+
+
+
+/**
+ * Function: omxVCM4P2_DecodeVLCZigzag_IntraDCVLC (6.2.5.2.2)
+ *
+ * Description:
+ * Performs VLC decoding and inverse zigzag scan of AC and DC coefficients
+ * for one intra block. Two versions of the function (DCVLC and ACVLC) are
+ * provided in order to support the two different methods of processing DC
+ * coefficients, as described in [ISO14496-2], subclause 7.4.1.4, Intra DC
+ * Coefficient Decoding for the Case of Switched VLC Encoding.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - pointer to the pointer to the current byte in the
+ * bitstream buffer
+ * pBitOffset - pointer to the bit position in the current byte referenced
+ * by *ppBitStream. The parameter *pBitOffset is valid in the
+ * range [0-7].
+ * Bit Position in one byte: |Most Least|
+ * *pBitOffset |0 1 2 3 4 5 6 7|
+ * predDir - AC prediction direction; used to select the zigzag scan
+ * pattern; takes one of the following values:
+ * - OMX_VC_NONE - AC prediction not used;
+ * performs classical zigzag scan.
+ * - OMX_VC_HORIZONTAL - Horizontal prediction;
+ * performs alternate-vertical zigzag scan;
+ * - OMX_VC_VERTICAL - Vertical prediction;
+ * performs alternate-horizontal zigzag scan.
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; escape modes 0-3 are used if
+ * shortVideoHeader==0, and escape mode 4 is used when
+ * shortVideoHeader==1.
+ * videoComp - video component type (luminance or chrominance) of the
+ * current block
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after the block is decoded such
+ * that it points to the current byte in the bit stream buffer
+ * pBitOffset - *pBitOffset is updated such that it points to the current
+ * bit position in the byte pointed by *ppBitStream
+ * pDst - pointer to the coefficient buffer of current block; must be
+ * 4-byte aligned.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments, if:
+ * - At least one of the following pointers is NULL:
+ * ppBitStream, *ppBitStream, pBitOffset, pDst
+ * - *pBitOffset exceeds [0,7]
+ * - preDir exceeds [0,2]
+ * - pDst is not 4-byte aligned
+ * OMX_Sts_Err - if:
+ * - In DecodeVLCZigzag_IntraDCVLC, dc_size > 12
+ * - At least one of mark bits equals zero
+ * - Illegal stream encountered; code cannot be located in VLC table
+ * - Forbidden code encountered in the VLC FLC table.
+ * - The number of coefficients is greater than 64
+ *
+ */
+
+OMXResult omxVCM4P2_DecodeVLCZigzag_IntraDCVLC(
+ const OMX_U8 ** ppBitStream,
+ OMX_INT * pBitOffset,
+ OMX_S16 * pDst,
+ OMX_U8 predDir,
+ OMX_INT shortVideoHeader,
+ OMXVCM4P2VideoComponent videoComp
+)
+{
+ /* Dummy initilaization to remove compilation error */
+ OMX_S8 DCValueSize = 0;
+ OMX_U16 powOfSize, fetchDCbits;
+ OMX_U8 start = 1;
+
+ /* Argument error checks */
+ armRetArgErrIf(ppBitStream == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(*ppBitStream == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pBitOffset == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(!armIs4ByteAligned(pDst), OMX_Sts_BadArgErr);
+ armRetArgErrIf((*pBitOffset < 0) || (*pBitOffset > 7), OMX_Sts_BadArgErr);
+ armRetArgErrIf((predDir > 2), OMX_Sts_BadArgErr);
+
+ /* Insert the code into the bitstream */
+ if (videoComp == OMX_VC_LUMINANCE)
+ {
+ DCValueSize = armUnPackVLC32(ppBitStream,
+ pBitOffset, armVCM4P2_aIntraDCLumaIndex);
+ }
+ else if (videoComp == OMX_VC_CHROMINANCE)
+ {
+ DCValueSize = armUnPackVLC32(ppBitStream,
+ pBitOffset, armVCM4P2_aIntraDCChromaIndex);
+ }
+ armRetDataErrIf(DCValueSize == -1, OMX_Sts_Err);
+ armRetDataErrIf(DCValueSize > 12, OMX_Sts_Err);
+
+
+ if (DCValueSize == 0)
+ {
+ pDst[0] = 0;
+ }
+ else
+ {
+ fetchDCbits = (OMX_U16) armGetBits(ppBitStream, pBitOffset, \
+ DCValueSize);
+
+ if ( (fetchDCbits >> (DCValueSize - 1)) == 0)
+ {
+ /* calulate pow */
+ powOfSize = (1 << DCValueSize);
+
+ pDst[0] = (OMX_S16) (fetchDCbits ^ (powOfSize - 1));
+ pDst[0] = -pDst[0];
+ }
+ else
+ {
+ pDst[0] = fetchDCbits;
+ }
+
+ if (DCValueSize > 8)
+ {
+ /* reading and checking the marker bit*/
+ armRetDataErrIf (armGetBits(ppBitStream, pBitOffset, 1) == 0, \
+ OMX_Sts_Err);
+ }
+ }
+
+ return armVCM4P2_DecodeVLCZigzag_Intra(
+ ppBitStream,
+ pBitOffset,
+ pDst,
+ predDir,
+ shortVideoHeader,
+ start);
+}
+
+/* End of file */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_EncodeMV.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_EncodeMV.c
new file mode 100644
index 0000000..def2b6d
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_EncodeMV.c
@@ -0,0 +1,212 @@
+/**
+ *
+ * File Name: omxVCM4P2_EncodeMV.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains module for predicting MV of MB
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armCOMM_Bitstream.h"
+#include "armVCM4P2_Huff_Tables_VLC.h"
+
+
+
+/**
+ * Function: omxVCM4P2_EncodeMV (6.2.4.5.4)
+ *
+ * Description:
+ * Predicts a motion vector for the current macroblock, encodes the
+ * difference, and writes the output to the stream buffer. The input MVs
+ * pMVCurMB, pSrcMVLeftMB, pSrcMVUpperMB, and pSrcMVUpperRightMB should lie
+ * within the ranges associated with the input parameter fcodeForward, as
+ * described in [ISO14496-2], subclause 7.6.3. This function provides a
+ * superset of the functionality associated with the function
+ * omxVCM4P2_FindMVpred.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - double pointer to the current byte in the bitstream buffer
+ * pBitOffset - index of the first free (next available) bit in the stream
+ * buffer referenced by *ppBitStream, valid in the range 0 to 7.
+ * pMVCurMB - pointer to the current macroblock motion vector; a value of
+ * NULL indicates unavailability.
+ * pSrcMVLeftMB - pointer to the source left macroblock motion vector; a
+ * value of NULLindicates unavailability.
+ * pSrcMVUpperMB - pointer to source upper macroblock motion vector; a
+ * value of NULL indicates unavailability.
+ * pSrcMVUpperRightMB - pointer to source upper right MB motion vector; a
+ * value of NULL indicates unavailability.
+ * fcodeForward - an integer with values from 1 to 7; used in encoding
+ * motion vectors related to search range, as described in
+ * [ISO14496-2], subclause 7.6.3.
+ * MBType - macro block type, valid in the range 0 to 5
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - updated pointer to the current byte in the bit stream
+ * buffer
+ * pBitOffset - updated index of the next available bit position in stream
+ * buffer referenced by *ppBitStream
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments
+ * - At least one of the following pointers is NULL: ppBitStream,
+ * *ppBitStream, pBitOffset, pMVCurMB
+ * - *pBitOffset < 0, or *pBitOffset >7.
+ * - fcodeForward <= 0, or fcodeForward > 7, or MBType < 0.
+ *
+ */
+
+OMXResult omxVCM4P2_EncodeMV(
+ OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ const OMXVCMotionVector * pMVCurMB,
+ const OMXVCMotionVector * pSrcMVLeftMB,
+ const OMXVCMotionVector * pSrcMVUpperMB,
+ const OMXVCMotionVector * pSrcMVUpperRightMB,
+ OMX_INT fcodeForward,
+ OMXVCM4P2MacroblockType MBType
+)
+{
+ OMXVCMotionVector dstMVPred, diffMV;
+ OMXVCMotionVector dstMVPredME[12];
+ /* Initialized to remove compilation warning */
+ OMX_INT iBlk, i, count = 1;
+ OMX_S32 mvHorResidual, mvVerResidual, mvHorData, mvVerData;
+ OMX_U8 scaleFactor, index;
+
+ /* Argument error checks */
+ armRetArgErrIf(ppBitStream == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(*ppBitStream == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pBitOffset == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pMVCurMB == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(((*pBitOffset < 0) || (*pBitOffset > 7)), OMX_Sts_BadArgErr);
+ armRetArgErrIf(((fcodeForward < 1) || (fcodeForward > 7)), \
+ OMX_Sts_BadArgErr);
+
+ if ((MBType == OMX_VC_INTRA) ||
+ (MBType == OMX_VC_INTRA_Q)
+ )
+ {
+ /* No candidate vectors hence make them zero */
+ for (i = 0; i < 12; i++)
+ {
+ dstMVPredME[i].dx = 0;
+ dstMVPredME[i].dy = 0;
+ }
+
+ return OMX_Sts_NoErr;
+ }
+
+ if ((MBType == OMX_VC_INTER4V) || (MBType == OMX_VC_INTER4V_Q))
+ {
+ count = 4;
+ }
+ else if ((MBType == OMX_VC_INTER) || (MBType == OMX_VC_INTER_Q))
+ {
+ count = 1;
+ }
+
+ /* Calculating the scale factor */
+ scaleFactor = 1 << (fcodeForward -1);
+
+ for (iBlk = 0; iBlk < count; iBlk++)
+ {
+
+ /* Find the predicted vector */
+ omxVCM4P2_FindMVpred (
+ pMVCurMB,
+ pSrcMVLeftMB,
+ pSrcMVUpperMB,
+ pSrcMVUpperRightMB,
+ &dstMVPred,
+ dstMVPredME,
+ iBlk );
+
+ /* Calculating the differential motion vector (diffMV) */
+ diffMV.dx = pMVCurMB[iBlk].dx - dstMVPred.dx;
+ diffMV.dy = pMVCurMB[iBlk].dy - dstMVPred.dy;
+
+ /* Calculating the mv_data and mv_residual for Horizantal MV */
+ if (diffMV.dx == 0)
+ {
+ mvHorResidual = 0;
+ mvHorData = 0;
+ }
+ else
+ {
+ mvHorResidual = ( armAbs(diffMV.dx) - 1) % scaleFactor;
+ mvHorData = (armAbs(diffMV.dx) - mvHorResidual + (scaleFactor - 1))
+ / scaleFactor;
+ if (diffMV.dx < 0)
+ {
+ mvHorData = -mvHorData;
+ }
+ }
+
+ /* Calculating the mv_data and mv_residual for Vertical MV */
+ if (diffMV.dy == 0)
+ {
+ mvVerResidual = 0;
+ mvVerData = 0;
+ }
+ else
+ {
+ mvVerResidual = ( armAbs(diffMV.dy) - 1) % scaleFactor;
+ mvVerData = (armAbs(diffMV.dy) - mvVerResidual + (scaleFactor - 1))
+ / scaleFactor;
+ if (diffMV.dy < 0)
+ {
+ mvVerData = -mvVerData;
+ }
+ }
+
+ /* Huffman encoding */
+
+ /* The index is actually calculate as
+ index = ((float) (mvHorData/2) + 16) * 2,
+ meaning the MV data is halfed and then normalized
+ to begin with zero and then doubled to take care of indexing
+ the fractional part included */
+ index = mvHorData + 32;
+ armPackVLC32 (ppBitStream, pBitOffset, armVCM4P2_aVlcMVD[index]);
+ if ((fcodeForward > 1) && (diffMV.dx != 0))
+ {
+ armPackBits (ppBitStream, pBitOffset, mvHorResidual, (fcodeForward -1));
+ }
+
+ /* The index is actually calculate as
+ index = ((float) (mvVerData/2) + 16) * 2,
+ meaning the MV data is halfed and then normalized
+ to begin with zero and then doubled to take care of indexing
+ the fractional part included */
+ index = mvVerData + 32;
+ armPackVLC32 (ppBitStream, pBitOffset, armVCM4P2_aVlcMVD[index]);
+ if ((fcodeForward > 1) && (diffMV.dy != 0))
+ {
+ armPackBits (ppBitStream, pBitOffset, mvVerResidual, (fcodeForward -1));
+ }
+ }
+
+ return OMX_Sts_NoErr;
+}
+
+
+/* End of file */
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_EncodeVLCZigzag_Inter.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_EncodeVLCZigzag_Inter.c
new file mode 100644
index 0000000..b6c73ea
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_EncodeVLCZigzag_Inter.c
@@ -0,0 +1,112 @@
+/**
+ *
+ * File Name: omxVCM4P2_EncodeVLCZigzag_Inter.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains modules for zigzag scanning and VLC encoding
+ * for inter block.
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armVC.h"
+#include "armCOMM_Bitstream.h"
+#include "armCOMM.h"
+#include "armVCM4P2_Huff_Tables_VLC.h"
+#include "armVCM4P2_ZigZag_Tables.h"
+
+
+
+/**
+ * Function: omxVCM4P2_EncodeVLCZigzag_Inter (6.2.4.5.3)
+ *
+ * Description:
+ * Performs classical zigzag scanning and VLC encoding for one inter block.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - pointer to the pointer to the current byte in the bit
+ * stream
+ * pBitOffset - pointer to the bit position in the byte pointed by
+ * *ppBitStream. Valid within 0 to 7
+ * pQDctBlkCoef - pointer to the quantized DCT coefficient
+ * pattern - block pattern which is used to decide whether this block is
+ * encoded
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; escape modes 0-3 are used if
+ * shortVideoHeader==0, and escape mode 4 is used when
+ * shortVideoHeader==1.
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after the block is encoded so that
+ * it points to the current byte in the bit stream buffer.
+ * pBitOffset - *pBitOffset is updated so that it points to the current bit
+ * position in the byte pointed by *ppBitStream.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - Bad arguments
+ * - At least one of the pointers: is NULL: ppBitStream, *ppBitStream,
+ * pBitOffset, pQDctBlkCoef
+ * - *pBitOffset < 0, or *pBitOffset >7.
+ *
+ */
+OMXResult omxVCM4P2_EncodeVLCZigzag_Inter(
+ OMX_U8 **ppBitStream,
+ OMX_INT * pBitOffset,
+ const OMX_S16 *pQDctBlkCoef,
+ OMX_U8 pattern,
+ OMX_INT shortVideoHeader
+)
+{
+ OMX_U8 start = 0;
+ const OMX_U8 *pZigzagTable = armVCM4P2_aClassicalZigzagScan;
+
+ /* Argument error checks */
+ armRetArgErrIf(ppBitStream == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(*ppBitStream == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pBitOffset == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pQDctBlkCoef == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf((*pBitOffset < 0) || (*pBitOffset >7), OMX_Sts_BadArgErr);
+
+ if (pattern)
+ {
+ armVCM4P2_PutVLCBits (
+ ppBitStream,
+ pBitOffset,
+ pQDctBlkCoef,
+ shortVideoHeader,
+ start,
+ 26,
+ 40,
+ 10,
+ 1,
+ armVCM4P2_InterL0RunIdx,
+ armVCM4P2_InterVlcL0,
+ armVCM4P2_InterL1RunIdx,
+ armVCM4P2_InterVlcL1,
+ armVCM4P2_InterL0LMAX,
+ armVCM4P2_InterL1LMAX,
+ armVCM4P2_InterL0RMAX,
+ armVCM4P2_InterL1RMAX,
+ pZigzagTable
+ );
+ } /* Pattern check ends*/
+
+ return OMX_Sts_NoErr;
+
+}
+
+/* End of file */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_EncodeVLCZigzag_IntraACVLC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_EncodeVLCZigzag_IntraACVLC.c
new file mode 100644
index 0000000..d047942
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_EncodeVLCZigzag_IntraACVLC.c
@@ -0,0 +1,97 @@
+/**
+ *
+ * File Name: omxVCM4P2_EncodeVLCZigzag_IntraACVLC.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains modules for zigzag scanning and VLC encoding
+ * for intra block.
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armVC.h"
+
+
+/**
+ * Function: omxVCM4P2_EncodeVLCZigzag_IntraACVLC (6.2.4.5.2)
+ *
+ * Description:
+ * Performs zigzag scan and VLC encoding of AC and DC coefficients for one
+ * intra block. Two versions of the function (DCVLC and ACVLC) are provided
+ * in order to support the two different methods of processing DC
+ * coefficients, as described in [ISO14496-2], subclause 7.4.1.4, Intra DC
+ * Coefficient Decoding for the Case of Switched VLC Encoding.
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - double pointer to the current byte in the bitstream
+ * pBitOffset - pointer to the bit position in the byte pointed by
+ * *ppBitStream. Valid within 0 to 7.
+ * pQDctBlkCoef - pointer to the quantized DCT coefficient
+ * predDir - AC prediction direction, which is used to decide the zigzag
+ * scan pattern; takes one of the following values:
+ * - OMX_VC_NONE - AC prediction not used.
+ * Performs classical zigzag scan.
+ * - OMX_VC_HORIZONTAL - Horizontal prediction.
+ * Performs alternate-vertical zigzag scan.
+ * - OMX_VC_VERTICAL - Vertical prediction.
+ * Performs alternate-horizontal zigzag scan.
+ * pattern - block pattern which is used to decide whether this block is
+ * encoded
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; escape modes 0-3 are used if
+ * shortVideoHeader==0, and escape mode 4 is used when
+ * shortVideoHeader==1.
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after the block is encoded, so
+ * that it points to the current byte in the bit stream buffer.
+ * pBitOffset - *pBitOffset is updated so that it points to the current bit
+ * position in the byte pointed by *ppBitStream.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - Bad arguments:
+ * - At least one of the following pointers is NULL: ppBitStream,
+ * *ppBitStream, pBitOffset, pQDctBlkCoef.
+ * - *pBitOffset < 0, or *pBitOffset >7.
+ * - PredDir is not one of: OMX_VC_NONE, OMX_VC_HORIZONTAL, or
+ * OMX_VC_VERTICAL.
+ * - VideoComp is not one component of enum OMXVCM4P2VideoComponent.
+ *
+ */
+
+OMXResult omxVCM4P2_EncodeVLCZigzag_IntraACVLC(
+ OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ const OMX_S16 *pQDctBlkCoef,
+ OMX_U8 predDir,
+ OMX_U8 pattern,
+ OMX_INT shortVideoHeader
+)
+{
+ OMX_U8 start = 0;
+
+ return armVCM4P2_EncodeVLCZigzag_Intra(
+ ppBitStream,
+ pBitOffset,
+ pQDctBlkCoef,
+ predDir,
+ pattern,
+ shortVideoHeader,
+ start);
+}
+
+/* End of file */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_EncodeVLCZigzag_IntraDCVLC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_EncodeVLCZigzag_IntraDCVLC.c
new file mode 100644
index 0000000..c57acd2
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_EncodeVLCZigzag_IntraDCVLC.c
@@ -0,0 +1,160 @@
+/**
+ *
+ * File Name: omxVCM4P2_EncodeVLCZigzag_IntraDCVLC.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains modules for zigzag scanning and VLC encoding
+ * for intra block.
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armVC.h"
+#include "armCOMM_Bitstream.h"
+#include "armCOMM.h"
+#include "armVCM4P2_Huff_Tables_VLC.h"
+#include "armVCM4P2_ZigZag_Tables.h"
+
+
+
+/**
+ * Function: omxVCM4P2_EncodeVLCZigzag_IntraDCVLC (6.2.4.5.2)
+ *
+ * Description:
+ * Performs zigzag scan and VLC encoding of AC and DC coefficients for one
+ * intra block. Two versions of the function (DCVLC and ACVLC) are provided
+ * in order to support the two different methods of processing DC
+ * coefficients, as described in [ISO14496-2], subclause 7.4.1.4, "Intra DC
+ * Coefficient Decoding for the Case of Switched VLC Encoding".
+ *
+ * Input Arguments:
+ *
+ * ppBitStream - double pointer to the current byte in the bitstream
+ * pBitOffset - pointer to the bit position in the byte pointed by
+ * *ppBitStream. Valid within 0 to 7.
+ * pQDctBlkCoef - pointer to the quantized DCT coefficient
+ * predDir - AC prediction direction, which is used to decide the zigzag
+ * scan pattern; takes one of the following values:
+ * - OMX_VC_NONE - AC prediction not used.
+ * Performs classical zigzag scan.
+ * - OMX_VC_HORIZONTAL - Horizontal prediction.
+ * Performs alternate-vertical zigzag scan.
+ * - OMX_VC_VERTICAL - Vertical prediction.
+ * Performs alternate-horizontal zigzag scan.
+ * pattern - block pattern which is used to decide whether this block is
+ * encoded
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; escape modes 0-3 are used if
+ * shortVideoHeader==0, and escape mode 4 is used when
+ * shortVideoHeader==1.
+ * videoComp - video component type (luminance, chrominance) of the current
+ * block
+ *
+ * Output Arguments:
+ *
+ * ppBitStream - *ppBitStream is updated after the block is encoded, so
+ * that it points to the current byte in the bit stream buffer.
+ * pBitOffset - *pBitOffset is updated so that it points to the current bit
+ * position in the byte pointed by *ppBitStream.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - Bad arguments:
+ * - At least one of the following pointers is NULL: ppBitStream,
+ * *ppBitStream, pBitOffset, pQDctBlkCoef.
+ * - *pBitOffset < 0, or *pBitOffset >7.
+ * - PredDir is not one of: OMX_VC_NONE, OMX_VC_HORIZONTAL, or
+ * OMX_VC_VERTICAL.
+ * - VideoComp is not one component of enum OMXVCM4P2VideoComponent.
+ *
+ */
+
+OMXResult omxVCM4P2_EncodeVLCZigzag_IntraDCVLC(
+ OMX_U8 **ppBitStream,
+ OMX_INT *pBitOffset,
+ const OMX_S16 *pQDctBlkCoef,
+ OMX_U8 predDir,
+ OMX_U8 pattern,
+ OMX_INT shortVideoHeader,
+ OMXVCM4P2VideoComponent videoComp
+)
+{
+ OMX_S16 dcValue, powOfSize;
+ OMX_U8 DCValueSize, start = 1;
+ OMX_U16 absDCValue;
+
+ /* Argument error checks */
+ armRetArgErrIf(ppBitStream == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(*ppBitStream == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pBitOffset == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pQDctBlkCoef == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf((*pBitOffset < 0) || (*pBitOffset >7), OMX_Sts_BadArgErr);
+ armRetArgErrIf((videoComp != OMX_VC_LUMINANCE) && (videoComp != OMX_VC_CHROMINANCE), OMX_Sts_BadArgErr);
+ armRetArgErrIf((predDir != OMX_VC_NONE) && (predDir != OMX_VC_HORIZONTAL) && (predDir != OMX_VC_VERTICAL) , OMX_Sts_BadArgErr);
+
+ if (pattern)
+ {
+ dcValue = pQDctBlkCoef[0];
+ absDCValue = armAbs(dcValue);
+
+ /* Find the size */
+ DCValueSize = armLogSize (absDCValue);
+ absDCValue = armAbs(dcValue);
+
+ /* Insert the code into the bitstream */
+ if (videoComp == OMX_VC_LUMINANCE)
+ {
+
+ armPackVLC32 (ppBitStream, pBitOffset,
+ armVCM4P2_aIntraDCLumaIndex[DCValueSize]);
+ }
+ else if (videoComp == OMX_VC_CHROMINANCE)
+ {
+
+ armPackVLC32 (ppBitStream, pBitOffset,
+ armVCM4P2_aIntraDCChromaIndex[DCValueSize]);
+ }
+
+ /* Additional code generation in case of negative
+ dc value the additional */
+ if (DCValueSize > 0)
+ {
+ if (dcValue < 0)
+ {
+ /* calulate 2 pow */
+ powOfSize = (1 << DCValueSize);
+
+ absDCValue = absDCValue ^ (powOfSize - 1);
+ }
+ armPackBits(ppBitStream, pBitOffset, (OMX_U32)absDCValue, \
+ DCValueSize);
+
+ if (DCValueSize > 8)
+ {
+ armPackBits(ppBitStream, pBitOffset, 1, 1);
+ }
+ }
+ }
+
+ return armVCM4P2_EncodeVLCZigzag_Intra(
+ ppBitStream,
+ pBitOffset,
+ pQDctBlkCoef,
+ predDir,
+ pattern,
+ shortVideoHeader,
+ start);
+}
+
+/* End of file */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_FindMVpred.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_FindMVpred.c
new file mode 100644
index 0000000..a0cff48
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_FindMVpred.c
@@ -0,0 +1,188 @@
+/**
+ *
+ * File Name: omxVCM4P2_FindMVpred.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains module for predicting MV of MB
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+
+/**
+ * Function: omxVCM4P2_FindMVpred (6.2.3.1.1)
+ *
+ * Description:
+ * Predicts a motion vector for the current block using the procedure
+ * specified in [ISO14496-2], subclause 7.6.5. The resulting predicted MV is
+ * returned in pDstMVPred. If the parameter pDstMVPredME if is not NULL then
+ * the set of three MV candidates used for prediction is also returned,
+ * otherwise pDstMVPredMEis NULL upon return.
+ *
+ * Input Arguments:
+ *
+ * pSrcMVCurMB - pointer to the MV buffer associated with the current Y
+ * macroblock; a value of NULL indicates unavailability.
+ * pSrcCandMV1 - pointer to the MV buffer containing the 4 MVs associated
+ * with the MB located to the left of the current MB; set to NULL
+ * if there is no MB to the left.
+ * pSrcCandMV2 - pointer to the MV buffer containing the 4 MVs associated
+ * with the MB located above the current MB; set to NULL if there
+ * is no MB located above the current MB.
+ * pSrcCandMV3 - pointer to the MV buffer containing the 4 MVs associated
+ * with the MB located to the right and above the current MB; set
+ * to NULL if there is no MB located to the above-right.
+ * iBlk - the index of block in the current macroblock
+ * pDstMVPredME - MV candidate return buffer; if set to NULL then
+ * prediction candidate MVs are not returned and pDstMVPredME will
+ * be NULL upon function return; if pDstMVPredME is non-NULL then it
+ * must point to a buffer containing sufficient space for three
+ * return MVs.
+ *
+ * Output Arguments:
+ *
+ * pDstMVPred - pointer to the predicted motion vector
+ * pDstMVPredME - if non-NULL upon input then pDstMVPredME points upon
+ * return to a buffer containing the three motion vector candidates
+ * used for prediction as specified in [ISO14496-2], subclause
+ * 7.6.5, otherwise if NULL upon input then pDstMVPredME is NULL
+ * upon output.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned under any of the following
+ * conditions:
+ * - the pointer pDstMVPred is NULL
+ * - the parameter iBlk does not fall into the range 0 <= iBlk<=3
+ *
+ */
+
+OMXResult omxVCM4P2_FindMVpred(
+ const OMXVCMotionVector* pSrcMVCurMB,
+ const OMXVCMotionVector* pSrcCandMV1,
+ const OMXVCMotionVector* pSrcCandMV2,
+ const OMXVCMotionVector* pSrcCandMV3,
+ OMXVCMotionVector* pDstMVPred,
+ OMXVCMotionVector* pDstMVPredME,
+ OMX_INT iBlk
+ )
+{
+ OMXVCMotionVector CandMV;
+ const OMXVCMotionVector *pCandMV1;
+ const OMXVCMotionVector *pCandMV2;
+ const OMXVCMotionVector *pCandMV3;
+
+ /* Argument error checks */
+ armRetArgErrIf(iBlk!=0 && pSrcMVCurMB == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pDstMVPred == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf((iBlk < 0) || (iBlk > 3), OMX_Sts_BadArgErr);
+
+ CandMV.dx = CandMV.dy = 0;
+ /* Based on the position of the block extract the motion vectors and
+ the tranperancy status */
+
+
+ /* Set the default value for these to be used if pSrcCandMV[1|2|3] == NULL */
+ pCandMV1 = pCandMV2 = pCandMV3 = &CandMV;
+
+
+ switch (iBlk)
+ {
+ case 0:
+ {
+ if(pSrcCandMV1 != NULL)
+ {
+ pCandMV1 = &pSrcCandMV1[1];
+ }
+ if(pSrcCandMV2 != NULL)
+ {
+ pCandMV2 = &pSrcCandMV2[2];
+ }
+ if(pSrcCandMV3 != NULL)
+ {
+ pCandMV3 = &pSrcCandMV3[2];
+ }
+ if ((pSrcCandMV1 == NULL) && (pSrcCandMV2 == NULL))
+ {
+ pCandMV1 = pCandMV2 = pCandMV3;
+ }
+ else if((pSrcCandMV1 == NULL) && (pSrcCandMV3 == NULL))
+ {
+ pCandMV1 = pCandMV3 = pCandMV2;
+ }
+ else if((pSrcCandMV2 == NULL) && (pSrcCandMV3 == NULL))
+ {
+ pCandMV2 = pCandMV3 = pCandMV1;
+ }
+ break;
+ }
+ case 1:
+ {
+ pCandMV1 = &pSrcMVCurMB[0];
+ if(pSrcCandMV2 != NULL)
+ {
+ pCandMV2 = &pSrcCandMV2[3];
+ }
+ if(pSrcCandMV3 != NULL)
+ {
+ pCandMV3 = &pSrcCandMV3[2];
+ }
+ if((pSrcCandMV2 == NULL) && (pSrcCandMV3 == NULL))
+ {
+ pCandMV2 = pCandMV3 = pCandMV1;
+ }
+ break;
+ }
+ case 2:
+ {
+ if(pSrcCandMV1 != NULL)
+ {
+ pCandMV1 = &pSrcCandMV1[3];
+ }
+ pCandMV2 = &pSrcMVCurMB[0];
+ pCandMV3 = &pSrcMVCurMB[1];
+ break;
+ }
+ case 3:
+ {
+ pCandMV1 = &pSrcMVCurMB[2];
+ pCandMV2 = &pSrcMVCurMB[0];
+ pCandMV3 = &pSrcMVCurMB[1];
+ break;
+ }
+ }
+
+ /* Find the median of the 3 candidate MV's */
+ pDstMVPred->dx = armMedianOf3 (pCandMV1->dx, pCandMV2->dx, pCandMV3->dx);
+ pDstMVPred->dy = armMedianOf3 (pCandMV1->dy, pCandMV2->dy, pCandMV3->dy);
+
+ if (pDstMVPredME != NULL)
+ {
+ /* Store the candidate MV's into the pDstMVPredME, these can be used
+ in the fast algorithm if implemented */
+ pDstMVPredME[0].dx = pCandMV1->dx;
+ pDstMVPredME[0].dy = pCandMV1->dy;
+ pDstMVPredME[1].dx = pCandMV2->dx;
+ pDstMVPredME[1].dy = pCandMV2->dy;
+ pDstMVPredME[2].dx = pCandMV3->dx;
+ pDstMVPredME[2].dy = pCandMV3->dy;
+ }
+
+ return OMX_Sts_NoErr;
+}
+
+
+/* End of file */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_IDCT8x8blk.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_IDCT8x8blk.c
new file mode 100644
index 0000000..1886d92
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_IDCT8x8blk.c
@@ -0,0 +1,92 @@
+/**
+ *
+ * File Name: omxVCM4P2_IDCT8x8blk.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains modules for 8x8 block IDCT
+ *
+ */
+
+
+#include <math.h>
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVCM4P2_DCT_Table.h"
+
+/**
+ * Function: omxVCM4P2_IDCT8x8blk (6.2.3.2.1)
+ *
+ * Description:
+ * Computes a 2D inverse DCT for a single 8x8 block, as defined in
+ * [ISO14496-2].
+ *
+ * Input Arguments:
+ *
+ * pSrc - pointer to the start of the linearly arranged IDCT input buffer;
+ * must be aligned on a 16-byte boundary. According to
+ * [ISO14496-2], the input coefficient values should lie within the
+ * range [-2048, 2047].
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the start of the linearly arranged IDCT output buffer;
+ * must be aligned on a 16-byte boundary.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments:
+ * - pSrc or pDst is NULL.
+ * - pSrc or pDst is not 16-byte aligned.
+ *
+ */
+OMXResult omxVCM4P2_IDCT8x8blk (const OMX_S16 *pSrc, OMX_S16 *pDst)
+{
+ OMX_INT x, y, u, v;
+
+ /* Argument error checks */
+ armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(!armIs16ByteAligned(pSrc), OMX_Sts_BadArgErr);
+ armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(!armIs16ByteAligned(pDst), OMX_Sts_BadArgErr);
+
+ for (x = 0; x < 8; x++)
+ {
+ for (y = 0; y < 8; y++)
+ {
+ OMX_F64 sum = 0.0;
+ for (u = 0; u < 8; u++)
+ {
+ for (v = 0; v < 8; v++)
+ {
+ sum += pSrc[(u * 8) + v] *
+ armVCM4P2_preCalcDCTCos[x][u] *
+ armVCM4P2_preCalcDCTCos[y][v];
+ }
+ }
+ pDst[(x * 8) + y] = (OMX_S16) floor(sum + 0.5);
+
+ /* Saturate to [-256, 255] */
+ pDst[(x * 8) + y] = armClip (
+ -256,
+ 255,
+ pDst[(x * 8) + y]);
+ }
+ }
+
+ return OMX_Sts_NoErr;
+}
+
+/* End of file */
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_MCReconBlock.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_MCReconBlock.c
new file mode 100644
index 0000000..7b3faee
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_MCReconBlock.c
@@ -0,0 +1,357 @@
+/**
+ *
+ * File Name: omxVCM4P2_MCReconBlock.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ * Description:
+ * MPEG4 motion compensation prediction for an 8x8 block using
+ * interpolation
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+
+/**
+ * Function: armVCM4P2_HalfPelVer
+ *
+ * Description:
+ * Performs half pel motion compensation for an 8x8 block using vertical
+ * interpolation described in ISO/IEC 14496-2, subclause 7.6.2.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] pSrc pointer to the block in the reference plane.
+ * [in] srcStep distance between the start of consecutive lines
+ * in the reference plane, in bytes; must be a multiple
+ * of 8.
+ * [in] rndVal rounding control parameter: 0 - disabled; 1 - enabled.
+ * [out] pDst pointer to the linaer 8x8 destination buffer;
+ *
+ */
+static OMXVoid armVCM4P2_HalfPelVer(
+ const OMX_U8 *pSrc,
+ OMX_INT srcStep,
+ OMX_U8 *pDst,
+ OMX_INT rndVal)
+{
+ const OMX_U8 *pTempSrc1;
+ const OMX_U8 *pTempSrc2;
+ OMX_INT y, x;
+
+ pTempSrc1 = pSrc;
+ pTempSrc2 = pSrc + srcStep;
+ srcStep -= 8;
+ for (y = 0; y < 8; y++)
+ {
+ for (x = 0; x < 8; x++)
+ {
+ *pDst++ = ((*pTempSrc1++ + *pTempSrc2++) + 1 - rndVal) >> 1;
+ }
+ pTempSrc1 += srcStep;
+ pTempSrc2 += srcStep;
+ }
+}
+
+/**
+ * Function: armVCM4P2_HalfPelHor
+ *
+ * Description:
+ * Performs half pel motion compensation for an 8x8 block using horizontal
+ * interpolation described in ISO/IEC 14496-2, subclause 7.6.2.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] pSrc pointer to the block in the reference plane.
+ * [in] srcStep distance between the start of consecutive lines
+ * in the reference plane, in bytes; must be a multiple
+ * of 8.
+ * [in] rndVal rounding control parameter: 0 - disabled; 1 - enabled.
+ * [out] pDst pointer to the linaer 8x8 destination buffer;
+ *
+ */
+static OMXVoid armVCM4P2_HalfPelHor(
+ const OMX_U8 *pSrc,
+ OMX_INT srcStep,
+ OMX_U8 *pDst,
+ OMX_INT rndVal)
+{
+ const OMX_U8 *pTempSrc1;
+ const OMX_U8 *pTempSrc2;
+ OMX_INT y, x;
+
+ pTempSrc1 = pSrc;
+ pTempSrc2 = pTempSrc1 + 1;
+
+ srcStep -= 8;
+ for (y=0; y<8; y++)
+ {
+ for (x=0; x<8; x++)
+ {
+ *pDst++ = ((*pTempSrc1++ + *pTempSrc2++) + 1 - rndVal) >> 1;
+ }
+ pTempSrc1 += srcStep;
+ pTempSrc2 += srcStep;
+ }
+}
+
+
+/**
+ * Function: armVCM4P2_HalfPelVerHor
+ *
+ * Description:
+ * Performs half pel motion compensation for an 8x8 block using both
+ * horizontal and vertical interpolation described in ISO/IEC 14496-2,
+ * subclause 7.6.2.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] pSrc pointer to the block in the reference plane.
+ * [in] srcStep distance between the start of consecutive lines
+ * in the reference plane, in bytes; must be a multiple
+ * of 8.
+ * [in] rndVal rounding control parameter: 0 - disabled; 1 - enabled.
+ * [out] pDst pointer to the linaer 8x8 destination buffer;
+ *
+ */
+static OMXVoid armVCM4P2_HalfPelVerHor(
+ const OMX_U8 *pSrc,
+ OMX_INT srcStep,
+ OMX_U8 *pDst,
+ OMX_INT rndVal)
+{
+ const OMX_U8 *pTempSrc1;
+ const OMX_U8 *pTempSrc2;
+ const OMX_U8 *pTempSrc3;
+ const OMX_U8 *pTempSrc4;
+ OMX_INT y, x;
+
+ pTempSrc1 = pSrc;
+ pTempSrc2 = pSrc + srcStep;
+ pTempSrc3 = pSrc + 1;
+ pTempSrc4 = pSrc + srcStep + 1;
+
+ srcStep -= 8;
+ for (y=0; y<8; y++)
+ {
+ for (x=0; x<8; x++)
+ {
+ *pDst++ = ((*pTempSrc1++ + *pTempSrc2++ + *pTempSrc3++ + *pTempSrc4++) +
+ 2 - rndVal) >> 2;
+ }
+ pTempSrc1 += srcStep;
+ pTempSrc2 += srcStep;
+ pTempSrc3 += srcStep;
+ pTempSrc4 += srcStep;
+ }
+}
+
+/**
+ * Function: armVCM4P2_MCReconBlock_NoRes
+ *
+ * Description:
+ * Do motion compensation and copy the result to the current block.
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] pSrc pointer to the block in the reference plane.
+ * [in] srcStep distance between the start of consecutive lines
+ * in the reference plane, in bytes; must be a multiple
+ * of 8.
+ * [in] dstStep distance between the start of consecutive lines in the
+ * destination plane, in bytes; must be a multiple of 8.
+ * [in] predictType bilinear interpolation type, as defined in section 6.2.1.2.
+ * [in] rndVal rounding control parameter: 0 - disabled; 1 - enabled.
+ * [out] pDst pointer to the destination buffer; must be 8-byte aligned.
+ * If prediction residuals are added then output intensities
+ * are clipped to the range [0,255].
+ *
+ */
+static OMXVoid armVCM4P2_MCReconBlock_NoRes(
+ const OMX_U8 *pSrc,
+ OMX_INT srcStep,
+ OMX_U8 *pDst,
+ OMX_INT dstStep)
+{
+ OMX_U8 x,y,count,index;
+
+ /* Copying the ref 8x8 blk to the curr blk */
+ for (y = 0, count = 0, index = 0; y < 8; y++,index += (srcStep -8), count += (dstStep - 8))
+ {
+ for (x = 0; x < 8; x++, count++,index++)
+ {
+ pDst[count] = pSrc[index];
+ }
+ }
+}
+
+/**
+ * Function: armVCM4P2_MCReconBlock_Res
+ *
+ * Description:
+ * Reconstructs INTER block by summing the motion compensation results
+ * and the results of the inverse transformation (prediction residuals).
+ * Output intensities are clipped to the range [0,255].
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] pSrc pointer to the block in the reference plane.
+ * [in] pSrcResidue pointer to a buffer containing the 16-bit prediction
+ * residuals. If the pointer is NULL,then no prediction
+ * is done, only motion compensation, i.e., the block is
+ * moved with interpolation.
+ * [in] dstStep distance between the start of consecutive lines in the
+ * destination plane, in bytes; must be a multiple of 8.
+ * [out] pDst pointer to the destination buffer; must be 8-byte aligned.
+ * If prediction residuals are added then output intensities
+ * are clipped to the range [0,255].
+ *
+ */
+static OMXVoid armVCM4P2_MCReconBlock_Res(
+ const OMX_U8 *pSrc,
+ const OMX_S16 *pSrcResidue,
+ OMX_U8 *pDst,
+ OMX_INT dstStep)
+{
+
+ OMX_U8 x,y;
+ OMX_INT temp;
+
+ for(y = 0; y < 8; y++)
+ {
+ for(x = 0; x < 8; x++)
+ {
+ temp = pSrc[x] + pSrcResidue[x];
+ pDst[x] = armClip(0,255,temp);
+ }
+ pDst += dstStep;
+ pSrc += 8;
+ pSrcResidue += 8;
+ }
+}
+
+/**
+ * Function: omxVCM4P2_MCReconBlock (6.2.5.5.1)
+ *
+ * Description:
+ * Performs motion compensation prediction for an 8x8 block using
+ * interpolation described in [ISO14496-2], subclause 7.6.2.
+ *
+ * Input Arguments:
+ *
+ * pSrc - pointer to the block in the reference plane.
+ * srcStep - distance between the start of consecutive lines in the
+ * reference plane, in bytes; must be a multiple of 8.
+ * dstStep - distance between the start of consecutive lines in the
+ * destination plane, in bytes; must be a multiple of 8.
+ * pSrcResidue - pointer to a buffer containing the 16-bit prediction
+ * residuals; must be 16-byte aligned. If the pointer is NULL, then
+ * no prediction is done, only motion compensation, i.e., the block
+ * is moved with interpolation.
+ * predictType - bilinear interpolation type, as defined in section
+ * 6.2.1.2.
+ * rndVal - rounding control parameter: 0 - disabled; 1 - enabled.
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the destination buffer; must be 8-byte aligned. If
+ * prediction residuals are added then output intensities are
+ * clipped to the range [0,255].
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; returned under any of the following
+ * conditions:
+ * - pDst is not 8-byte aligned.
+ * - pSrcResidue is not 16-byte aligned.
+ * - one or more of the following pointers is NULL: pSrc or pDst.
+ * - either srcStep or dstStep is not a multiple of 8.
+ * - invalid type specified for the parameter predictType.
+ * - the parameter rndVal is not equal either to 0 or 1.
+ *
+ */
+OMXResult omxVCM4P2_MCReconBlock(
+ const OMX_U8 *pSrc,
+ OMX_INT srcStep,
+ const OMX_S16 *pSrcResidue,
+ OMX_U8 *pDst,
+ OMX_INT dstStep,
+ OMX_INT predictType,
+ OMX_INT rndVal)
+{
+ /* Definitions and Initializations*/
+ OMX_U8 pTempDst[64];
+
+ /* Argument error checks */
+ armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(!armIs8ByteAligned(pDst), OMX_Sts_BadArgErr);
+ armRetArgErrIf(!armIs16ByteAligned(pSrcResidue), OMX_Sts_BadArgErr);
+ armRetArgErrIf(((dstStep % 8) || (srcStep % 8)), OMX_Sts_BadArgErr);
+ armRetArgErrIf(((predictType != OMX_VC_INTEGER_PIXEL) &&
+ (predictType != OMX_VC_HALF_PIXEL_X) &&
+ (predictType != OMX_VC_HALF_PIXEL_Y) &&
+ (predictType != OMX_VC_HALF_PIXEL_XY)
+ ),OMX_Sts_BadArgErr);
+ armRetArgErrIf(((rndVal != 0) && (rndVal != 1)),OMX_Sts_BadArgErr);
+
+ switch(predictType)
+ {
+ case OMX_VC_INTEGER_PIXEL:
+ armVCM4P2_MCReconBlock_NoRes(pSrc,
+ srcStep,
+ &(pTempDst[0]),
+ 8);
+ break;
+ case OMX_VC_HALF_PIXEL_X:
+ armVCM4P2_HalfPelHor(pSrc,
+ srcStep,
+ &(pTempDst[0]),
+ rndVal);
+ break;
+ case OMX_VC_HALF_PIXEL_Y:
+ armVCM4P2_HalfPelVer(pSrc,
+ srcStep,
+ &(pTempDst[0]),
+ rndVal);
+ break;
+ case OMX_VC_HALF_PIXEL_XY:
+ armVCM4P2_HalfPelVerHor(pSrc,
+ srcStep,
+ &(pTempDst[0]),
+ rndVal);
+ break;
+ }
+
+ if(pSrcResidue == NULL)
+ {
+ armVCM4P2_MCReconBlock_NoRes(&(pTempDst[0]),
+ 8,
+ pDst,
+ dstStep);
+ }
+ else
+ {
+ armVCM4P2_MCReconBlock_Res(&(pTempDst[0]),
+ pSrcResidue,
+ pDst,
+ dstStep);
+ }
+
+ return OMX_Sts_NoErr;
+}
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_MEGetBufSize.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_MEGetBufSize.c
new file mode 100644
index 0000000..a8e51da
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_MEGetBufSize.c
@@ -0,0 +1,70 @@
+/**
+ *
+ * File Name: omxVCM4P2_MEGetBufSize.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Initialization modules for the vendor specific Motion Estimation structure.
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armVC.h"
+#include "armCOMM.h"
+
+/**
+ * Function: omxVCM4P2_MEGetBufSize (6.2.4.1.1)
+ *
+ * Description:
+ * Computes the size, in bytes, of the vendor-specific specification
+ * structure for the following motion estimation functions:
+ * BlockMatch_Integer_8x8, BlockMatch_Integer_16x16, and MotionEstimationMB.
+ *
+ * Input Arguments:
+ *
+ * MEmode - motion estimation mode; available modes are defined by the
+ * enumerated type OMXVCM4P2MEMode
+ * pMEParams - motion estimation parameters
+ *
+ * Output Arguments:
+ *
+ * pSize - pointer to the number of bytes required for the specification
+ * structure
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - one or more of the following is true:
+ * - an invalid value was specified for the parameter MEmode
+ * - a negative or zero value was specified for the
+ * parameter pMEParams->searchRange
+ *
+ */
+
+OMXResult omxVCM4P2_MEGetBufSize(
+ OMXVCM4P2MEMode MEMode,
+ const OMXVCM4P2MEParams *pMEParams,
+ OMX_U32 *pSize
+ )
+{
+ armRetArgErrIf(!pMEParams, OMX_Sts_BadArgErr);
+ armRetArgErrIf(!pSize, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pMEParams->searchRange <= 0, OMX_Sts_BadArgErr);
+ armRetArgErrIf((MEMode != OMX_VC_M4P10_FAST_SEARCH) &&
+ (MEMode != OMX_VC_M4P10_FULL_SEARCH), OMX_Sts_BadArgErr);
+
+ *pSize = (OMX_INT) sizeof(ARMVCM4P2_MESpec);
+
+ return OMX_Sts_NoErr;
+}
+
+/* End of file */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_MEInit.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_MEInit.c
new file mode 100644
index 0000000..419e71a
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_MEInit.c
@@ -0,0 +1,84 @@
+/**
+ *
+ * File Name: omxVCM4P2_MEInit.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Initialization modules for the vendor specific Motion Estimation structure.
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armVC.h"
+#include "armCOMM.h"
+
+/**
+ * Function: omxVCM4P2_MEInit (6.2.4.1.2)
+ *
+ * Description:
+ * Initializes the vendor-specific specification structure required for the
+ * following motion estimation functions: BlockMatch_Integer_8x8,
+ * BlockMatch_Integer_16x16, and MotionEstimationMB. Memory for the
+ * specification structure *pMESpec must be allocated prior to calling the
+ * function, and should be aligned on a 4-byte boundary. Following
+ * initialization by this function, the vendor-specific structure *pMESpec
+ * should contain an implementation-specific representation of all motion
+ * estimation parameters received via the structure pMEParams, for example
+ * rndVal, searchRange, etc. The number of bytes required for the
+ * specification structure can be determined using the function
+ * omxVCM4P2_MEGetBufSize.
+ *
+ * Input Arguments:
+ *
+ * MEmode - motion estimation mode; available modes are defined by the
+ * enumerated type OMXVCM4P2MEMode
+ * pMEParams - motion estimation parameters
+ * pMESpec - pointer to the uninitialized ME specification structure
+ *
+ * Output Arguments:
+ *
+ * pMESpec - pointer to the initialized ME specification structure
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - one or more of the following is true:
+ * - an invalid value was specified for the parameter MEmode
+ * - a negative or zero value was specified for the
+ * parameter pMEParams->searchRange
+ *
+ */
+
+OMXResult omxVCM4P2_MEInit(
+ OMXVCM4P2MEMode MEMode,
+ const OMXVCM4P2MEParams *pMEParams,
+ void *pMESpec
+ )
+{
+ ARMVCM4P2_MESpec *armMESpec = (ARMVCM4P2_MESpec *) pMESpec;
+
+ armRetArgErrIf(!pMEParams, OMX_Sts_BadArgErr);
+ armRetArgErrIf(!pMESpec, OMX_Sts_BadArgErr);
+ armRetArgErrIf((MEMode != OMX_VC_M4P2_FAST_SEARCH) &&
+ (MEMode != OMX_VC_M4P2_FULL_SEARCH), OMX_Sts_BadArgErr);
+ armRetArgErrIf(pMEParams->searchRange <= 0, OMX_Sts_BadArgErr);
+
+ armMESpec->MEParams.searchEnable8x8 = pMEParams->searchEnable8x8;
+ armMESpec->MEParams.halfPelSearchEnable = pMEParams->halfPelSearchEnable;
+ armMESpec->MEParams.searchRange = pMEParams->searchRange;
+ armMESpec->MEParams.rndVal = pMEParams->rndVal;
+ armMESpec->MEMode = MEMode;
+
+ return OMX_Sts_NoErr;
+}
+
+/* End of file */
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_MotionEstimationMB.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_MotionEstimationMB.c
new file mode 100644
index 0000000..9549050
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_MotionEstimationMB.c
@@ -0,0 +1,630 @@
+/**
+ *
+ * File Name: omxVCM4P2_MotionEstimationMB.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains module for motion search 16x16 macroblock
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armVC.h"
+#include "armCOMM.h"
+
+/**
+ * Function: armVCM4P2_BlockMatch_16x16
+ *
+ * Description:
+ * 16x16 block match wrapper function, calls omxVCM4P2_BlockMatch_Integer_16x16.
+ * If half pel search is enabled it also calls omxVCM4P2_BlockMatch_Half_16x16
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] pSrcRefBuf pointer to the reference Y plane; points to the reference MB that
+ * corresponds to the location of the current macroblock in the current
+ * plane.
+ * [in] srcRefStep width of the reference plane
+ * [in] pRefRect pointer to the valid rectangular in reference plane. Relative to image origin.
+ * It's not limited to the image boundary, but depended on the padding. For example,
+ * if you pad 4 pixels outside the image border, then the value for left border
+ * can be -4
+ * [in] pSrcCurrBuf pointer to the current macroblock extracted from original plane (linear array,
+ * 256 entries); must be aligned on an 16-byte boundary.
+ * [in] pCurrPointPos position of the current macroblock in the current plane
+ * [in] pSrcPreMV pointer to predicted motion vector; NULL indicates no predicted MV
+ * [in] pSrcPreSAD pointer to SAD associated with the predicted MV (referenced by pSrcPreMV); may be set to NULL if unavailable.
+ * [in] pMESpec vendor-specific motion estimation specification structure; must have been allocated
+ * and then initialized using omxVCM4P2_MEInit prior to calling the block matching
+ * function.
+ * [out] pDstMV pointer to estimated MV
+ * [out] pDstSAD pointer to minimum SAD
+ * *
+ * Return Value:
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments
+ *
+ */
+static OMXResult armVCM4P2_BlockMatch_16x16(
+ const OMX_U8 *pSrcRefBuf,
+ const OMX_INT srcRefStep,
+ const OMXRect *pRefRect,
+ const OMX_U8 *pSrcCurrBuf,
+ const OMXVCM4P2Coordinate *pCurrPointPos,
+ OMXVCMotionVector *pSrcPreMV,
+ OMX_INT *pSrcPreSAD,
+ void *pMESpec,
+ OMXVCMotionVector *pDstMV,
+ OMX_INT *pDstSAD
+)
+{
+ OMXVCM4P2MEParams *pMEParams = (OMXVCM4P2MEParams *)pMESpec;
+ OMX_INT rndVal;
+
+ rndVal = pMEParams->rndVal;
+
+ omxVCM4P2_BlockMatch_Integer_16x16(
+ pSrcRefBuf,
+ srcRefStep,
+ pRefRect,
+ pSrcCurrBuf,
+ pCurrPointPos,
+ pSrcPreMV,
+ pSrcPreSAD,
+ pMEParams,
+ pDstMV,
+ pDstSAD);
+
+ if (pMEParams->halfPelSearchEnable)
+ {
+ omxVCM4P2_BlockMatch_Half_16x16(
+ pSrcRefBuf,
+ srcRefStep,
+ pRefRect,
+ pSrcCurrBuf,
+ pCurrPointPos,
+ rndVal,
+ pDstMV,
+ pDstSAD);
+ }
+
+ return OMX_Sts_NoErr;
+}
+
+/**
+ * Function: armVCM4P2_BlockMatch_8x8
+ *
+ * Description:
+ * 8x8 block match wrapper function, calls omxVCM4P2_BlockMatch_Integer_8x8.
+ * If half pel search is enabled it also calls omxVCM4P2_BlockMatch_Half_8x8
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] pSrcRefBuf pointer to the reference Y plane; points to the reference MB that
+ * corresponds to the location of the current macroblock in the current
+ * plane.
+ * [in] srcRefStep width of the reference plane
+ * [in] pRefRect pointer to the valid rectangular in reference plane. Relative to image origin.
+ * It's not limited to the image boundary, but depended on the padding. For example,
+ * if you pad 4 pixels outside the image border, then the value for left border
+ * can be -4
+ * [in] pSrcCurrBuf pointer to the current macroblock extracted from original plane (linear array,
+ * 256 entries); must be aligned on an 16-byte boundary.
+ * [in] pCurrPointPos position of the current macroblock in the current plane
+ * [in] pSrcPreMV pointer to predicted motion vector; NULL indicates no predicted MV
+ * [in] pSrcPreSAD pointer to SAD associated with the predicted MV (referenced by pSrcPreMV); may be set to NULL if unavailable.
+ * [in] pMESpec vendor-specific motion estimation specification structure; must have been allocated
+ * and then initialized using omxVCM4P2_MEInit prior to calling the block matching
+ * function.
+ * [out] pDstMV pointer to estimated MV
+ * [out] pDstSAD pointer to minimum SAD
+ * *
+ * Return Value:
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments
+ *
+ */
+static OMXResult armVCM4P2_BlockMatch_8x8(
+ const OMX_U8 *pSrcRefBuf,
+ OMX_INT srcRefStep,
+ const OMXRect *pRefRect,
+ const OMX_U8 *pSrcCurrBuf,
+ const OMXVCM4P2Coordinate *pCurrPointPos,
+ OMXVCMotionVector *pSrcPreMV,
+ OMX_INT *pSrcPreSAD,
+ void *pMESpec,
+ OMXVCMotionVector *pSrcDstMV,
+ OMX_INT *pDstSAD
+)
+{
+ OMXVCM4P2MEParams *pMEParams = (OMXVCM4P2MEParams *)pMESpec;
+ OMX_INT rndVal;
+
+ rndVal = pMEParams->rndVal;
+
+ omxVCM4P2_BlockMatch_Integer_8x8(
+ pSrcRefBuf,
+ srcRefStep,
+ pRefRect,
+ pSrcCurrBuf,
+ pCurrPointPos,
+ pSrcPreMV,
+ pSrcPreSAD,
+ pMEParams,
+ pSrcDstMV,
+ pDstSAD);
+
+ if (pMEParams->halfPelSearchEnable)
+ {
+ omxVCM4P2_BlockMatch_Half_8x8(
+ pSrcRefBuf,
+ srcRefStep,
+ pRefRect,
+ pSrcCurrBuf,
+ pCurrPointPos,
+ rndVal,
+ pSrcDstMV,
+ pDstSAD);
+ }
+
+ return OMX_Sts_NoErr;
+}
+
+
+/**
+ * Function: omxVCM4P2_MotionEstimationMB (6.2.4.3.1)
+ *
+ * Description:
+ * Performs motion search for a 16x16 macroblock. Selects best motion search
+ * strategy from among inter-1MV, inter-4MV, and intra modes. Supports
+ * integer and half pixel resolution.
+ *
+ * Input Arguments:
+ *
+ * pSrcCurrBuf - pointer to the top-left corner of the current MB in the
+ * original picture plane; must be aligned on a 16-byte boundary.
+ * The function does not expect source data outside the region
+ * bounded by the MB to be available; for example it is not
+ * necessary for the caller to guarantee the availability of
+ * pSrcCurrBuf[-SrcCurrStep], i.e., the row of pixels above the MB
+ * to be processed.
+ * srcCurrStep - width of the original picture plane, in terms of full
+ * pixels; must be a multiple of 16.
+ * pSrcRefBuf - pointer to the reference Y plane; points to the reference
+ * plane location corresponding to the location of the current
+ * macroblock in the current plane; must be aligned on a 16-byte
+ * boundary.
+ * srcRefStep - width of the reference picture plane, in terms of full
+ * pixels; must be a multiple of 16.
+ * pRefRect - reference plane valid region rectangle, specified relative to
+ * the image origin
+ * pCurrPointPos - position of the current macroblock in the current plane
+ * pMESpec - pointer to the vendor-specific motion estimation specification
+ * structure; must be allocated and then initialized using
+ * omxVCM4P2_MEInit prior to calling this function.
+ * pMBInfo - array, of dimension four, containing pointers to information
+ * associated with four nearby MBs:
+ * - pMBInfo[0] - pointer to left MB information
+ * - pMBInfo[1] - pointer to top MB information
+ * - pMBInfo[2] - pointer to top-left MB information
+ * - pMBInfo[3] - pointer to top-right MB information
+ * Any pointer in the array may be set equal to NULL if the
+ * corresponding MB doesn't exist. For each MB, the following structure
+ * members are used:
+ * - mbType - macroblock type, either OMX_VC_INTRA, OMX_VC_INTER, or
+ * OMX_VC_INTER4V
+ * - pMV0[2][2] - estimated motion vectors; represented
+ * in 1/2 pixel units
+ * - sliceID - number of the slice to which the MB belongs
+ * pSrcDstMBCurr - pointer to information structure for the current MB.
+ * The following entries should be set prior to calling the
+ * function: sliceID - the number of the slice the to which the
+ * current MB belongs. The structure elements cbpy and cbpc are
+ * ignored.
+ *
+ * Output Arguments:
+ *
+ * pSrcDstMBCurr - pointer to updated information structure for the current
+ * MB after MB-level motion estimation has been completed. The
+ * following structure members are updated by the ME function:
+ * - mbType - macroblock type: OMX_VC_INTRA, OMX_VC_INTER, or
+ * OMX_VC_INTER4V.
+ * - pMV0[2][2] - estimated motion vectors; represented in
+ * terms of 1/2 pel units.
+ * - pMVPred[2][2] - predicted motion vectors; represented
+ * in terms of 1/2 pel units.
+ * The structure members cbpy and cbpc are not updated by the function.
+ * pDstSAD - pointer to the minimum SAD for INTER1V, or sum of minimum SADs
+ * for INTER4V
+ * pDstBlockSAD - pointer to an array of SAD values for each of the four
+ * 8x8 luma blocks in the MB. The block SADs are in scan order for
+ * each MB.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments. Returned if one or more of the
+ * following conditions is true:
+ * - at least one of the following pointers is NULL: pSrcCurrBuf,
+ * pSrcRefBuf, pRefRect, pCurrPointPos, pMBInter, pMBIntra,
+ * pSrcDstMBCurr, or pDstSAD.
+ *
+ */
+
+OMXResult omxVCM4P2_MotionEstimationMB (
+ const OMX_U8 *pSrcCurrBuf,
+ OMX_S32 srcCurrStep,
+ const OMX_U8 *pSrcRefBuf,
+ OMX_S32 srcRefStep,
+ const OMXRect*pRefRect,
+ const OMXVCM4P2Coordinate *pCurrPointPos,
+ void *pMESpec,
+ const OMXVCM4P2MBInfoPtr *pMBInfo,
+ OMXVCM4P2MBInfo *pSrcDstMBCurr,
+ OMX_U16 *pDstSAD,
+ OMX_U16 *pDstBlockSAD
+)
+{
+
+ OMX_INT intraSAD, average, count, index, x, y;
+ OMXVCMotionVector dstMV16x16;
+ OMX_INT dstSAD16x16;
+ OMX_INT dstSAD8x8;
+ OMXVCM4P2MEParams *pMEParams;
+ OMXVCM4P2Coordinate TempCurrPointPos;
+ OMXVCM4P2Coordinate *pTempCurrPointPos;
+ OMX_U8 aTempSrcCurrBuf[271];
+ OMX_U8 *pTempSrcCurrBuf;
+ OMX_U8 *pDst;
+ OMX_U8 aDst[71];
+ OMX_S32 dstStep = 8;
+ OMX_INT predictType;
+ OMX_S32 Sad;
+ const OMX_U8 *pTempSrcRefBuf;
+ OMXVCMotionVector* pSrcCandMV1[4];
+ OMXVCMotionVector* pSrcCandMV2[4];
+ OMXVCMotionVector* pSrcCandMV3[4];
+
+ /* Argument error checks */
+ armRetArgErrIf(!armIs16ByteAligned(pSrcCurrBuf), OMX_Sts_BadArgErr);
+ armRetArgErrIf(!armIs16ByteAligned(pSrcRefBuf), OMX_Sts_BadArgErr);
+ armRetArgErrIf(((srcCurrStep % 16) || (srcRefStep % 16)), OMX_Sts_BadArgErr);
+ armRetArgErrIf(pSrcCurrBuf == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pSrcRefBuf == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pRefRect == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pCurrPointPos == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pSrcDstMBCurr == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pDstSAD == NULL, OMX_Sts_BadArgErr);
+
+
+ pTempCurrPointPos = &(TempCurrPointPos);
+ pTempSrcCurrBuf = armAlignTo16Bytes(aTempSrcCurrBuf);
+ pMEParams = (OMXVCM4P2MEParams *)pMESpec;
+ pTempCurrPointPos->x = pCurrPointPos->x;
+ pTempCurrPointPos->y = pCurrPointPos->y;
+ pSrcDstMBCurr->mbType = OMX_VC_INTER;
+
+ /* Preparing a linear buffer for block match */
+ for (y = 0, index = count = 0; y < 16; y++, index += srcCurrStep - 16)
+ {
+ for(x = 0; x < 16; x++, count++, index++)
+ {
+ pTempSrcCurrBuf[count] = pSrcCurrBuf[index];
+ }
+ }
+ for(y = 0, index = 0; y < 2; y++)
+ {
+ for(x = 0; x < 2; x++,index++)
+ {
+ if((pMBInfo[0] != NULL) && (pMBInfo[0]->mbType != OMX_VC_INTRA))
+ {
+ pSrcCandMV1[index] = &(pMBInfo[0]->pMV0[y][x]);
+ }
+ else
+ {
+ pSrcCandMV1[index] = NULL;
+ }
+ if((pMBInfo[1] != NULL) && (pMBInfo[1]->mbType != OMX_VC_INTRA))
+ {
+ pSrcCandMV2[index] = &(pMBInfo[1]->pMV0[y][x]);
+ }
+ else
+ {
+ pSrcCandMV2[index] = NULL;
+ }
+ if((pMBInfo[3] != NULL) && (pMBInfo[3]->mbType != OMX_VC_INTRA))
+ {
+ pSrcCandMV3[index] = &(pMBInfo[3]->pMV0[y][x]);
+ }
+ else
+ {
+ pSrcCandMV3[index] = NULL;
+ }
+ }
+ }
+ /* Calculating SAD at MV(0,0) */
+ armVCCOMM_SAD(pTempSrcCurrBuf,
+ 16,
+ pSrcRefBuf,
+ srcRefStep,
+ &Sad,
+ 16,
+ 16);
+ *pDstSAD = Sad;
+
+ /* Mode decision for NOT_CODED MB */
+ if(*pDstSAD == 0)
+ {
+ pSrcDstMBCurr->pMV0[0][0].dx = 0;
+ pSrcDstMBCurr->pMV0[0][0].dy = 0;
+ *pDstSAD = 0;
+ return OMX_Sts_NoErr;
+ }
+
+ omxVCM4P2_FindMVpred(
+ &(pSrcDstMBCurr->pMV0[0][0]),
+ pSrcCandMV1[0],
+ pSrcCandMV2[0],
+ pSrcCandMV3[0],
+ &(pSrcDstMBCurr->pMVPred[0][0]),
+ NULL,
+ 0);
+
+ /* Inter 1 MV */
+ armVCM4P2_BlockMatch_16x16(
+ pSrcRefBuf,
+ srcRefStep,
+ pRefRect,
+ pTempSrcCurrBuf,
+ pCurrPointPos,
+ &(pSrcDstMBCurr->pMVPred[0][0]),
+ NULL,
+ pMEParams,
+ &dstMV16x16,
+ &dstSAD16x16);
+
+ /* Initialize all with 1 MV values */
+ pSrcDstMBCurr->pMV0[0][0].dx = dstMV16x16.dx;
+ pSrcDstMBCurr->pMV0[0][0].dy = dstMV16x16.dy;
+ pSrcDstMBCurr->pMV0[0][1].dx = dstMV16x16.dx;
+ pSrcDstMBCurr->pMV0[0][1].dy = dstMV16x16.dy;
+ pSrcDstMBCurr->pMV0[1][0].dx = dstMV16x16.dx;
+ pSrcDstMBCurr->pMV0[1][0].dy = dstMV16x16.dy;
+ pSrcDstMBCurr->pMV0[1][1].dx = dstMV16x16.dx;
+ pSrcDstMBCurr->pMV0[1][1].dy = dstMV16x16.dy;
+
+ *pDstSAD = dstSAD16x16;
+
+ if (pMEParams->searchEnable8x8)
+ {
+ /* Inter 4MV */
+ armVCM4P2_BlockMatch_8x8 (pSrcRefBuf,
+ srcRefStep, pRefRect,
+ pTempSrcCurrBuf, pTempCurrPointPos,
+ &(pSrcDstMBCurr->pMVPred[0][0]), NULL,
+ pMEParams, &(pSrcDstMBCurr->pMV0[0][0]),
+ &dstSAD8x8
+ );
+ pDstBlockSAD[0] = dstSAD8x8;
+ *pDstSAD = dstSAD8x8;
+ pTempCurrPointPos->x += 8;
+ pSrcRefBuf += 8;
+ omxVCM4P2_FindMVpred(
+ &(pSrcDstMBCurr->pMV0[0][1]),
+ pSrcCandMV1[1],
+ pSrcCandMV2[1],
+ pSrcCandMV3[1],
+ &(pSrcDstMBCurr->pMVPred[0][1]),
+ NULL,
+ 1);
+
+ armVCM4P2_BlockMatch_8x8 (pSrcRefBuf,
+ srcRefStep, pRefRect,
+ pTempSrcCurrBuf, pTempCurrPointPos,
+ &(pSrcDstMBCurr->pMVPred[0][1]), NULL,
+ pMEParams, &(pSrcDstMBCurr->pMV0[0][1]),
+ &dstSAD8x8
+ );
+ pDstBlockSAD[1] = dstSAD8x8;
+ *pDstSAD += dstSAD8x8;
+ pTempCurrPointPos->x -= 8;
+ pTempCurrPointPos->y += 8;
+ pSrcRefBuf += (srcRefStep * 8) - 8;
+
+ omxVCM4P2_FindMVpred(
+ &(pSrcDstMBCurr->pMV0[1][0]),
+ pSrcCandMV1[2],
+ pSrcCandMV2[2],
+ pSrcCandMV3[2],
+ &(pSrcDstMBCurr->pMVPred[1][0]),
+ NULL,
+ 2);
+ armVCM4P2_BlockMatch_8x8 (pSrcRefBuf,
+ srcRefStep, pRefRect,
+ pTempSrcCurrBuf, pTempCurrPointPos,
+ &(pSrcDstMBCurr->pMVPred[1][0]), NULL,
+ pMEParams, &(pSrcDstMBCurr->pMV0[1][0]),
+ &dstSAD8x8
+ );
+ pDstBlockSAD[2] = dstSAD8x8;
+ *pDstSAD += dstSAD8x8;
+ pTempCurrPointPos->x += 8;
+ pSrcRefBuf += 8;
+ omxVCM4P2_FindMVpred(
+ &(pSrcDstMBCurr->pMV0[1][1]),
+ pSrcCandMV1[3],
+ pSrcCandMV2[3],
+ pSrcCandMV3[3],
+ &(pSrcDstMBCurr->pMVPred[1][1]),
+ NULL,
+ 3);
+ armVCM4P2_BlockMatch_8x8 (pSrcRefBuf,
+ srcRefStep, pRefRect,
+ pTempSrcCurrBuf, pTempCurrPointPos,
+ &(pSrcDstMBCurr->pMVPred[1][1]), NULL,
+ pMEParams, &(pSrcDstMBCurr->pMV0[1][1]),
+ &dstSAD8x8
+ );
+ pDstBlockSAD[3] = dstSAD8x8;
+ *pDstSAD += dstSAD8x8;
+
+
+ /* Checking if 4MV is equal to 1MV */
+ if (
+ (pSrcDstMBCurr->pMV0[0][0].dx != dstMV16x16.dx) ||
+ (pSrcDstMBCurr->pMV0[0][0].dy != dstMV16x16.dy) ||
+ (pSrcDstMBCurr->pMV0[0][1].dx != dstMV16x16.dx) ||
+ (pSrcDstMBCurr->pMV0[0][1].dy != dstMV16x16.dy) ||
+ (pSrcDstMBCurr->pMV0[1][0].dx != dstMV16x16.dx) ||
+ (pSrcDstMBCurr->pMV0[1][0].dy != dstMV16x16.dy) ||
+ (pSrcDstMBCurr->pMV0[1][1].dx != dstMV16x16.dx) ||
+ (pSrcDstMBCurr->pMV0[1][1].dy != dstMV16x16.dy)
+ )
+ {
+ /* select the 4 MV */
+ pSrcDstMBCurr->mbType = OMX_VC_INTER4V;
+ }
+ }
+
+ /* finding the error in intra mode */
+ for (count = 0, average = 0; count < 256 ; count++)
+ {
+ average = average + pTempSrcCurrBuf[count];
+ }
+ average = average/256;
+
+ intraSAD = 0;
+
+ /* Intra SAD calculation */
+ for (count = 0; count < 256 ; count++)
+ {
+ intraSAD += armAbs ((pTempSrcCurrBuf[count]) - (average));
+ }
+
+ /* Using the MPEG4 VM formula for intra/inter mode decision
+ Var < (SAD - 2*NB) where NB = N^2 is the number of pixels
+ of the macroblock.*/
+
+ if (intraSAD <= (*pDstSAD - 512))
+ {
+ pSrcDstMBCurr->mbType = OMX_VC_INTRA;
+ pSrcDstMBCurr->pMV0[0][0].dx = 0;
+ pSrcDstMBCurr->pMV0[0][0].dy = 0;
+ *pDstSAD = intraSAD;
+ pDstBlockSAD[0] = 0xFFFF;
+ pDstBlockSAD[1] = 0xFFFF;
+ pDstBlockSAD[2] = 0xFFFF;
+ pDstBlockSAD[3] = 0xFFFF;
+ }
+
+ if(pSrcDstMBCurr->mbType == OMX_VC_INTER)
+ {
+ pTempSrcRefBuf = pSrcRefBuf + (srcRefStep * dstMV16x16.dy) + dstMV16x16.dx;
+
+ if((dstMV16x16.dx & 0x1) && (dstMV16x16.dy & 0x1))
+ {
+ predictType = OMX_VC_HALF_PIXEL_XY;
+ }
+ else if(dstMV16x16.dx & 0x1)
+ {
+ predictType = OMX_VC_HALF_PIXEL_X;
+ }
+ else if(dstMV16x16.dy & 0x1)
+ {
+ predictType = OMX_VC_HALF_PIXEL_Y;
+ }
+ else
+ {
+ predictType = OMX_VC_INTEGER_PIXEL;
+ }
+
+ pDst = armAlignTo8Bytes(&(aDst[0]));
+ /* Calculating Block SAD at MV(dstMV16x16.dx,dstMV16x16.dy) */
+ /* Block 0 */
+ omxVCM4P2_MCReconBlock(pTempSrcRefBuf,
+ srcRefStep,
+ NULL,
+ pDst,
+ dstStep,
+ predictType,
+ pMEParams->rndVal);
+
+ armVCCOMM_SAD(pTempSrcCurrBuf,
+ 16,
+ pDst,
+ dstStep,
+ &Sad,
+ 8,
+ 8);
+ pDstBlockSAD[0] = Sad;
+
+ /* Block 1 */
+ omxVCM4P2_MCReconBlock(pTempSrcRefBuf + 8,
+ srcRefStep,
+ NULL,
+ pDst,
+ dstStep,
+ predictType,
+ pMEParams->rndVal);
+
+ armVCCOMM_SAD(pTempSrcCurrBuf + 8,
+ 16,
+ pDst,
+ dstStep,
+ &Sad,
+ 8,
+ 8);
+ pDstBlockSAD[1] = Sad;
+
+ /* Block 2 */
+ omxVCM4P2_MCReconBlock(pTempSrcRefBuf + (srcRefStep*8),
+ srcRefStep,
+ NULL,
+ pDst,
+ dstStep,
+ predictType,
+ pMEParams->rndVal);
+
+ armVCCOMM_SAD(pTempSrcCurrBuf + (16*8),
+ 16,
+ pDst,
+ dstStep,
+ &Sad,
+ 8,
+ 8);
+ pDstBlockSAD[2] = Sad;
+
+ /* Block 3 */
+ omxVCM4P2_MCReconBlock(pTempSrcRefBuf + (srcRefStep*8) + 8,
+ srcRefStep,
+ NULL,
+ pDst,
+ dstStep,
+ predictType,
+ pMEParams->rndVal);
+
+ armVCCOMM_SAD(pTempSrcCurrBuf + (16*8) + 8,
+ 16,
+ pDst,
+ dstStep,
+ &Sad,
+ 8,
+ 8);
+ pDstBlockSAD[3] = Sad;
+ }
+ return OMX_Sts_NoErr;
+}
+
+/* End of file */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_PredictReconCoefIntra.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_PredictReconCoefIntra.c
new file mode 100644
index 0000000..1613f47
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_PredictReconCoefIntra.c
@@ -0,0 +1,121 @@
+ /**
+ *
+ * File Name: omxVCM4P2_PredictReconCoefIntra.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * File: omxVCM4P2_PredictReconCoefIntra_S16.c
+ * Description: Contains modules for AC DC prediction
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+/**
+ * Function: omxVCM4P2_PredictReconCoefIntra (6.2.5.4.3)
+ *
+ * Description:
+ * Performs adaptive DC/AC coefficient prediction for an intra block. Prior
+ * to the function call, prediction direction (predDir) should be selected as
+ * specified in [ISO14496-2], subclause 7.4.3.1.
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - pointer to the coefficient buffer which contains the quantized
+ * coefficient residuals (PQF) of the current block; must be
+ * aligned on a 4-byte boundary. The output coefficients are
+ * saturated to the range [-2048, 2047].
+ * pPredBufRow - pointer to the coefficient row buffer; must be aligned on
+ * a 4-byte boundary.
+ * pPredBufCol - pointer to the coefficient column buffer; must be aligned
+ * on a 4-byte boundary.
+ * curQP - quantization parameter of the current block. curQP may equal to
+ * predQP especially when the current block and the predictor block
+ * are in the same macroblock.
+ * predQP - quantization parameter of the predictor block
+ * predDir - indicates the prediction direction which takes one of the
+ * following values: OMX_VC_HORIZONTAL - predict horizontally
+ * OMX_VC_VERTICAL - predict vertically
+ * ACPredFlag - a flag indicating if AC prediction should be performed. It
+ * is equal to ac_pred_flag in the bit stream syntax of MPEG-4
+ * videoComp - video component type (luminance or chrominance) of the
+ * current block
+ *
+ * Output Arguments:
+ *
+ * pSrcDst - pointer to the coefficient buffer which contains the quantized
+ * coefficients (QF) of the current block
+ * pPredBufRow - pointer to the updated coefficient row buffer
+ * pPredBufCol - pointer to the updated coefficient column buffer Note:
+ * Buffer update: Update the AC prediction buffer (both row and
+ * column buffer).
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments, if:
+ * - At least one of the pointers is NULL:
+ * pSrcDst, pPredBufRow, or pPredBufCol.
+ * - curQP <= 0,
+ * - predQP <= 0,
+ * - curQP >31,
+ * - predQP > 31,
+ * - preDir exceeds [1,2]
+ * - pSrcDst, pPredBufRow, or pPredBufCol is not 4-byte aligned.
+ *
+ */
+
+OMXResult omxVCM4P2_PredictReconCoefIntra(
+ OMX_S16 * pSrcDst,
+ OMX_S16 * pPredBufRow,
+ OMX_S16 * pPredBufCol,
+ OMX_INT curQP,
+ OMX_INT predQP,
+ OMX_INT predDir,
+ OMX_INT ACPredFlag,
+ OMXVCM4P2VideoComponent videoComp
+ )
+{
+ OMX_U8 flag;
+ /* Argument error checks */
+ armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pPredBufRow == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pPredBufCol == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(curQP <= 0, OMX_Sts_BadArgErr);
+ armRetArgErrIf(predQP <= 0, OMX_Sts_BadArgErr);
+ armRetArgErrIf(curQP > 31, OMX_Sts_BadArgErr);
+ armRetArgErrIf(predQP > 31, OMX_Sts_BadArgErr);
+ armRetArgErrIf((predDir != 1) && (predDir != 2), OMX_Sts_BadArgErr);
+ armRetArgErrIf(!armIs4ByteAligned(pSrcDst), OMX_Sts_BadArgErr);
+ armRetArgErrIf(!armIs4ByteAligned(pPredBufRow), OMX_Sts_BadArgErr);
+ armRetArgErrIf(!armIs4ByteAligned(pPredBufCol), OMX_Sts_BadArgErr);
+
+ flag = 0;
+ return armVCM4P2_ACDCPredict(
+ pSrcDst,
+ NULL,
+ pPredBufRow,
+ pPredBufCol,
+ curQP,
+ predQP,
+ predDir,
+ ACPredFlag,
+ videoComp,
+ flag,
+ NULL);
+
+}
+
+/* End of file */
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_QuantInter_I.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_QuantInter_I.c
new file mode 100644
index 0000000..5964f73
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_QuantInter_I.c
@@ -0,0 +1,117 @@
+/**
+ *
+ * File Name: omxVCM4P2_QuantInter_I.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains modules for inter Quantization
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+
+/**
+ * Function: omxVCM4P2_QuantInter_I (6.2.4.4.3)
+ *
+ * Description:
+ * Performs quantization on an inter coefficient block; supports
+ * bits_per_pixel == 8.
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - pointer to the input inter block coefficients; must be aligned
+ * on a 16-byte boundary.
+ * QP - quantization parameter (quantizer_scale)
+ * shortVideoHeader - binary flag indicating presence of short_video_header;
+ * shortVideoHeader==1 selects linear intra DC mode, and
+ * shortVideoHeader==0 selects non linear intra DC mode.
+ *
+ * Output Arguments:
+ *
+ * pSrcDst - pointer to the output (quantized) interblock coefficients.
+ * When shortVideoHeader==1, AC coefficients are saturated on the
+ * interval [-127, 127], and DC coefficients are saturated on the
+ * interval [1, 254]. When shortVideoHeader==0, AC coefficients
+ * are saturated on the interval [-2047, 2047].
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments:
+ * - pSrcDst is NULL.
+ * - QP <= 0 or QP >= 32.
+ *
+ */
+
+OMXResult omxVCM4P2_QuantInter_I(
+ OMX_S16 * pSrcDst,
+ OMX_U8 QP,
+ OMX_INT shortVideoHeader
+)
+{
+
+ /* Definitions and Initializations*/
+ OMX_INT coeffCount;
+ OMX_INT fSign;
+ OMX_INT maxClpAC = 0, minClpAC = 0;
+ OMX_INT maxClpDC = 0, minClpDC = 0;
+
+ /* Argument error checks */
+ armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(((QP <= 0) || (QP >= 32)), OMX_Sts_BadArgErr);
+ /* One argument check is delayed until we have ascertained that */
+ /* pQMatrix is not NULL. */
+
+ /* Set the Clip Range based on SVH on/off */
+ if(shortVideoHeader == 1)
+ {
+ maxClpDC = 254;
+ minClpDC = 1;
+ maxClpAC = 127;
+ minClpAC = -127;
+ }
+ else
+ {
+ maxClpDC = 2047;
+ minClpDC = -2047;
+ maxClpAC = 2047;
+ minClpAC = -2047;
+ }
+
+ /* Second Inverse quantisation method */
+ for (coeffCount = 0; coeffCount < 64; coeffCount++)
+ {
+ fSign = armSignCheck (pSrcDst[coeffCount]);
+ pSrcDst[coeffCount] = (armAbs(pSrcDst[coeffCount])
+ - (QP/2))/(2 * QP);
+ pSrcDst[coeffCount] *= fSign;
+
+ /* Clip */
+ if (coeffCount == 0)
+ {
+ pSrcDst[coeffCount] =
+ (OMX_S16) armClip (minClpDC, maxClpDC, pSrcDst[coeffCount]);
+ }
+ else
+ {
+ pSrcDst[coeffCount] =
+ (OMX_S16) armClip (minClpAC, maxClpAC, pSrcDst[coeffCount]);
+ }
+ }
+ return OMX_Sts_NoErr;
+
+}
+
+/* End of file */
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_QuantIntra_I.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_QuantIntra_I.c
new file mode 100644
index 0000000..a10da68
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_QuantIntra_I.c
@@ -0,0 +1,153 @@
+/**
+ *
+ * File Name: omxVCM4P2_QuantIntra_I.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains modules for intra Quantization
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+/**
+ * Function: omxVCM4P2_QuantIntra_I (6.2.4.4.2)
+ *
+ * Description:
+ * Performs quantization on intra block coefficients. This function supports
+ * bits_per_pixel == 8.
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - pointer to the input intra block coefficients; must be aligned
+ * on a 16-byte boundary.
+ * QP - quantization parameter (quantizer_scale).
+ * blockIndex - block index indicating the component type and position,
+ * valid in the range 0 to 5, as defined in [ISO14496-2], subclause
+ * 6.1.3.8.
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; shortVideoHeader==1 selects linear intra DC
+ * mode, and shortVideoHeader==0 selects non linear intra DC mode.
+ *
+ * Output Arguments:
+ *
+ * pSrcDst - pointer to the output (quantized) interblock coefficients.
+ * When shortVideoHeader==1, AC coefficients are saturated on the
+ * interval [-127, 127], and DC coefficients are saturated on the
+ * interval [1, 254]. When shortVideoHeader==0, AC coefficients
+ * are saturated on the interval [-2047, 2047].
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments:
+ * - pSrcDst is NULL.
+ * - blockIndex < 0 or blockIndex >= 10
+ * - QP <= 0 or QP >= 32.
+ *
+ */
+
+OMXResult omxVCM4P2_QuantIntra_I(
+ OMX_S16 * pSrcDst,
+ OMX_U8 QP,
+ OMX_INT blockIndex,
+ OMX_INT shortVideoHeader
+ )
+{
+
+ /* Definitions and Initializations*/
+ /* Initialized to remove compilation error */
+ OMX_INT dcScaler = 0, coeffCount,fSign;
+ OMX_INT maxClpAC, minClpAC;
+
+ /* Argument error checks */
+ armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(((blockIndex < 0) || (blockIndex >= 10)), OMX_Sts_BadArgErr);
+ armRetArgErrIf(((QP <= 0) || (QP >= 32)), OMX_Sts_BadArgErr);
+ /* One argument check is delayed until we have ascertained that */
+ /* pQMatrix is not NULL. */
+
+
+ /* Set the Clip Range based on SVH on/off */
+ if(shortVideoHeader == 1)
+ {
+ maxClpAC = 127;
+ minClpAC = -127;
+ dcScaler = 8;
+ /* Dequant the DC value, this applies to both the methods */
+ pSrcDst[0] = armIntDivAwayFromZero (pSrcDst[0], dcScaler);
+
+ /* Clip between 1 and 254 */
+ pSrcDst[0] = (OMX_S16) armClip (1, 254, pSrcDst[0]);
+ }
+ else
+ {
+ maxClpAC = 2047;
+ minClpAC = -2047;
+ /* Calculate the DC scaler value */
+ if ((blockIndex < 4) || (blockIndex > 5))
+ {
+ if (QP >= 1 && QP <= 4)
+ {
+ dcScaler = 8;
+ }
+ else if (QP >= 5 && QP <= 8)
+ {
+ dcScaler = 2 * QP;
+ }
+ else if (QP >= 9 && QP <= 24)
+ {
+ dcScaler = QP + 8;
+ }
+ else
+ {
+ dcScaler = (2 * QP) - 16;
+ }
+ }
+ else if (blockIndex < 6)
+ {
+ if (QP >= 1 && QP <= 4)
+ {
+ dcScaler = 8;
+ }
+ else if (QP >= 5 && QP <= 24)
+ {
+ dcScaler = (QP + 13)/2;
+ }
+ else
+ {
+ dcScaler = QP - 6;
+ }
+ }
+
+ /* Dequant the DC value, this applies to both the methods */
+ pSrcDst[0] = armIntDivAwayFromZero (pSrcDst[0], dcScaler);
+ }
+
+ /* Second Inverse quantisation method */
+ for (coeffCount = 1; coeffCount < 64; coeffCount++)
+ {
+ fSign = armSignCheck (pSrcDst[coeffCount]);
+ pSrcDst[coeffCount] = armAbs(pSrcDst[coeffCount])/(2 * QP);
+ pSrcDst[coeffCount] *= fSign;
+
+ /* Clip */
+ pSrcDst[coeffCount] =
+ (OMX_S16) armClip (minClpAC, maxClpAC, pSrcDst[coeffCount]);
+ }
+ return OMX_Sts_NoErr;
+
+}
+
+/* End of file */
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_QuantInvInter_I.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_QuantInvInter_I.c
new file mode 100644
index 0000000..6e0de5c
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_QuantInvInter_I.c
@@ -0,0 +1,96 @@
+/**
+ *
+ * File Name: omxVCM4P2_QuantInvInter_I.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains modules for inter inverse Quantization
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+
+
+/**
+ * Function: omxVCM4P2_QuantInvInter_I (6.2.5.3.2)
+ *
+ * Description:
+ * Performs the second inverse quantization mode on an intra/inter coded
+ * block. Supports bits_per_pixel = 8. The output coefficients are clipped to
+ * the range [-2048, 2047].
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - pointer to the input (quantized) intra/inter block; must be
+ * aligned on a 16-byte boundary.
+ * QP - quantization parameter (quantizer_scale)
+ * videoComp - video component type of the current block. Takes one of the
+ * following flags: OMX_VC_LUMINANCE, OMX_VC_CHROMINANCE (intra
+ * version only).
+ * shortVideoHeader - binary flag indicating presence of short_video_header
+ * (intra version only).
+ *
+ * Output Arguments:
+ *
+ * pSrcDst - pointer to the output (dequantized) intra/inter block
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; one or more of the following is
+ * true:
+ * - pSrcDst is NULL
+ * - QP <= 0 or QP >=31
+ * - videoComp is neither OMX_VC_LUMINANCE nor OMX_VC_CHROMINANCE.
+ *
+ */
+
+OMXResult omxVCM4P2_QuantInvInter_I(
+ OMX_S16 * pSrcDst,
+ OMX_INT QP
+ )
+{
+
+ OMX_INT coeffCount, Sign;
+
+ /* Argument error checks */
+ armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(((QP <= 0) || (QP >= 32)), OMX_Sts_BadArgErr);
+
+ /* Second Inverse quantisation method */
+ for (coeffCount = 0; coeffCount < 64; coeffCount++)
+ {
+ /* check sign */
+ Sign = armSignCheck (pSrcDst[coeffCount]);
+
+ /* Quantize the coeff */
+ if (QP & 0x1)
+ {
+ pSrcDst[coeffCount] = (2* armAbs(pSrcDst[coeffCount]) + 1) * QP;
+ pSrcDst[coeffCount] *= Sign;
+ }
+ else
+ {
+ pSrcDst[coeffCount] = (2* armAbs(pSrcDst[coeffCount]) + 1)
+ * QP - 1;
+ pSrcDst[coeffCount] *= Sign;
+ }
+ /* Saturate */
+ pSrcDst[coeffCount] = armClip (-2048, 2047, pSrcDst[coeffCount]);
+ }
+ return OMX_Sts_NoErr;
+}
+
+/* End of file */
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_QuantInvIntra_I.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_QuantInvIntra_I.c
new file mode 100644
index 0000000..a946d7b
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_QuantInvIntra_I.c
@@ -0,0 +1,153 @@
+/**
+ *
+ * File Name: omxVCM4P2_QuantInvIntra_I.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains modules for intra inverse Quantization
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+
+/**
+ * Function: omxVCM4P2_QuantInvIntra_I (6.2.5.3.2)
+ *
+ * Description:
+ * Performs the second inverse quantization mode on an intra/inter coded
+ * block. Supports bits_per_pixel = 8. The output coefficients are clipped to
+ * the range [-2048, 2047].
+ *
+ * Input Arguments:
+ *
+ * pSrcDst - pointer to the input (quantized) intra/inter block; must be
+ * aligned on a 16-byte boundary.
+ * QP - quantization parameter (quantizer_scale)
+ * videoComp - video component type of the current block. Takes one of the
+ * following flags: OMX_VC_LUMINANCE, OMX_VC_CHROMINANCE (intra
+ * version only).
+ * shortVideoHeader - binary flag indicating presence of short_video_header
+ * (intra version only).
+ *
+ * Output Arguments:
+ *
+ * pSrcDst - pointer to the output (dequantized) intra/inter block
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments; one or more of the following is
+ * true:
+ * - pSrcDst is NULL
+ * - QP <= 0 or QP >=31
+ * - videoComp is neither OMX_VC_LUMINANCE nor OMX_VC_CHROMINANCE.
+ *
+ */
+
+OMXResult omxVCM4P2_QuantInvIntra_I(
+ OMX_S16 * pSrcDst,
+ OMX_INT QP,
+ OMXVCM4P2VideoComponent videoComp,
+ OMX_INT shortVideoHeader
+)
+{
+
+ /* Initialized to remove compilation error */
+ OMX_INT dcScaler = 0, coeffCount, Sign;
+
+ /* Argument error checks */
+ armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(((QP <= 0) || (QP >= 32)), OMX_Sts_BadArgErr);
+ armRetArgErrIf(((videoComp != OMX_VC_LUMINANCE) && (videoComp != OMX_VC_CHROMINANCE)), OMX_Sts_BadArgErr);
+
+ /* Calculate the DC scaler value */
+
+ /* linear intra DC mode */
+ if(shortVideoHeader)
+ {
+ dcScaler = 8;
+ }
+ /* nonlinear intra DC mode */
+ else
+ {
+
+ if (videoComp == OMX_VC_LUMINANCE)
+ {
+ if (QP >= 1 && QP <= 4)
+ {
+ dcScaler = 8;
+ }
+ else if (QP >= 5 && QP <= 8)
+ {
+ dcScaler = 2 * QP;
+ }
+ else if (QP >= 9 && QP <= 24)
+ {
+ dcScaler = QP + 8;
+ }
+ else
+ {
+ dcScaler = (2 * QP) - 16;
+ }
+ }
+
+ else if (videoComp == OMX_VC_CHROMINANCE)
+ {
+ if (QP >= 1 && QP <= 4)
+ {
+ dcScaler = 8;
+ }
+ else if (QP >= 5 && QP <= 24)
+ {
+ dcScaler = (QP + 13)/2;
+ }
+ else
+ {
+ dcScaler = QP - 6;
+ }
+ }
+ }
+ /* Dequant the DC value, this applies to both the methods */
+ pSrcDst[0] = pSrcDst[0] * dcScaler;
+
+ /* Saturate */
+ pSrcDst[0] = armClip (-2048, 2047, pSrcDst[0]);
+
+ /* Second Inverse quantisation method */
+ for (coeffCount = 1; coeffCount < 64; coeffCount++)
+ {
+ /* check sign */
+ Sign = armSignCheck (pSrcDst[coeffCount]);
+
+ if (QP & 0x1)
+ {
+ pSrcDst[coeffCount] = (2* armAbs(pSrcDst[coeffCount]) + 1) * QP;
+ pSrcDst[coeffCount] *= Sign;
+ }
+ else
+ {
+ pSrcDst[coeffCount] =
+ (2* armAbs(pSrcDst[coeffCount]) + 1) * QP - 1;
+ pSrcDst[coeffCount] *= Sign;
+ }
+
+ /* Saturate */
+ pSrcDst[coeffCount] = armClip (-2048, 2047, pSrcDst[coeffCount]);
+ }
+ return OMX_Sts_NoErr;
+
+}
+
+/* End of file */
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_TransRecBlockCoef_inter.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_TransRecBlockCoef_inter.c
new file mode 100644
index 0000000..6e0c59b
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_TransRecBlockCoef_inter.c
@@ -0,0 +1,108 @@
+/**
+ *
+ * File Name: omxVCM4P2_TransRecBlockCoef_inter.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains modules DCT->quant and reconstructing the inter texture data
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+
+
+/**
+ * Function: omxVCM4P2_TransRecBlockCoef_inter (6.2.4.4.5)
+ *
+ * Description:
+ * Implements DCT, and quantizes the DCT coefficients of the inter block
+ * while reconstructing the texture residual. There is no boundary check for
+ * the bit stream buffer.
+ *
+ * Input Arguments:
+ *
+ * pSrc -pointer to the residuals to be encoded; must be aligned on an
+ * 16-byte boundary.
+ * QP - quantization parameter.
+ * shortVideoHeader - binary flag indicating presence of short_video_header;
+ * shortVideoHeader==1 selects linear intra DC mode, and
+ * shortVideoHeader==0 selects non linear intra DC mode.
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the quantized DCT coefficients buffer; must be aligned
+ * on a 16-byte boundary.
+ * pRec - pointer to the reconstructed texture residuals; must be aligned
+ * on a 16-byte boundary.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments:
+ * - At least one of the following pointers is either NULL or
+ * not 16-byte aligned:
+ * - pSrc
+ * - pDst
+ * - pRec
+ * - QP <= 0 or QP >= 32.
+ *
+ */
+
+OMXResult omxVCM4P2_TransRecBlockCoef_inter(
+ const OMX_S16 *pSrc,
+ OMX_S16 * pDst,
+ OMX_S16 * pRec,
+ OMX_U8 QP,
+ OMX_INT shortVideoHeader
+)
+{
+ /* 64 elements are needed but to align it to 16 bytes need
+ 8 more elements of padding */
+ OMX_S16 tempBuffer[72];
+ OMX_S16 *pTempBuffer;
+ OMX_INT i;
+
+ /* Aligning the local buffers */
+ pTempBuffer = armAlignTo16Bytes(tempBuffer);
+
+ /* Argument error checks */
+ armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pRec == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(!armIs16ByteAligned(pSrc), OMX_Sts_BadArgErr);
+ armRetArgErrIf(!armIs16ByteAligned(pRec), OMX_Sts_BadArgErr);
+ armRetArgErrIf(!armIs16ByteAligned(pDst), OMX_Sts_BadArgErr);
+ armRetArgErrIf(((QP <= 0) || (QP >= 32)), OMX_Sts_BadArgErr);
+
+ omxVCM4P2_DCT8x8blk (pSrc, pDst);
+ omxVCM4P2_QuantInter_I(
+ pDst,
+ QP,
+ shortVideoHeader);
+
+ for (i = 0; i < 64; i++)
+ {
+ pTempBuffer[i] = pDst[i];
+ }
+
+ omxVCM4P2_QuantInvInter_I(
+ pTempBuffer,
+ QP);
+ omxVCM4P2_IDCT8x8blk (pTempBuffer, pRec);
+
+ return OMX_Sts_NoErr;
+}
+
+/* End of file */
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_TransRecBlockCoef_intra.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_TransRecBlockCoef_intra.c
new file mode 100644
index 0000000..dd444f9
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_TransRecBlockCoef_intra.c
@@ -0,0 +1,260 @@
+/**
+ *
+ * File Name: omxVCM4P2_TransRecBlockCoef_intra.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains modules DCT->quant and reconstructing the intra texture data
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armCOMM.h"
+#include "armVC.h"
+
+
+/**
+ * Function: omxVCM4P2_TransRecBlockCoef_intra (6.2.4.4.4)
+ *
+ * Description:
+ * Quantizes the DCT coefficients, implements intra block AC/DC coefficient
+ * prediction, and reconstructs the current intra block texture for prediction
+ * on the next frame. Quantized row and column coefficients are returned in
+ * the updated coefficient buffers.
+ *
+ * Input Arguments:
+ *
+ * pSrc - pointer to the pixels of current intra block; must be aligned on
+ * an 8-byte boundary.
+ * pPredBufRow - pointer to the coefficient row buffer containing
+ * ((num_mb_per_row * 2 + 1) * 8) elements of type OMX_S16.
+ * Coefficients are organized into blocks of eight as described
+ * below (Internal Prediction Coefficient Update Procedures). The
+ * DC coefficient is first, and the remaining buffer locations
+ * contain the quantized AC coefficients. Each group of eight row
+ * buffer elements combined with one element eight elements ahead
+ * contains the coefficient predictors of the neighboring block
+ * that is spatially above or to the left of the block currently to
+ * be decoded. A negative-valued DC coefficient indicates that this
+ * neighboring block is not INTRA-coded or out of bounds, and
+ * therefore the AC and DC coefficients are invalid. Pointer must
+ * be aligned on an 8-byte boundary.
+ * pPredBufCol - pointer to the prediction coefficient column buffer
+ * containing 16 elements of type OMX_S16. Coefficients are
+ * organized as described in section 6.2.2.5. Pointer must be
+ * aligned on an 8-byte boundary.
+ * pSumErr - pointer to a flag indicating whether or not AC prediction is
+ * required; AC prediction is enabled if *pSumErr >=0, but the
+ * value is not used for coefficient prediction, i.e., the sum of
+ * absolute differences starts from 0 for each call to this
+ * function. Otherwise AC prediction is disabled if *pSumErr < 0 .
+ * blockIndex - block index indicating the component type and position, as
+ * defined in [ISO14496-2], subclause 6.1.3.8.
+ * curQp - quantization parameter of the macroblock to which the current
+ * block belongs
+ * pQpBuf - pointer to a 2-element quantization parameter buffer; pQpBuf[0]
+ * contains the quantization parameter associated with the 8x8
+ * block left of the current block (QPa), and pQpBuf[1] contains
+ * the quantization parameter associated with the 8x8 block above
+ * the current block (QPc). In the event that the corresponding
+ * block is outside of the VOP bound, the Qp value will not affect
+ * the intra prediction process, as described in [ISO14496-2],
+ * sub-clause 7.4.3.3, Adaptive AC Coefficient Prediction.
+ * srcStep - width of the source buffer; must be a multiple of 8.
+ * dstStep - width of the reconstructed destination buffer; must be a
+ * multiple of 16.
+ * shortVideoHeader - binary flag indicating presence of
+ * short_video_header; shortVideoHeader==1 selects linear intra DC
+ * mode, and shortVideoHeader==0 selects non linear intra DC mode.
+ *
+ * Output Arguments:
+ *
+ * pDst - pointer to the quantized DCT coefficient buffer; pDst[0] contains
+ * the predicted DC coefficient; the remaining entries contain the
+ * quantized AC coefficients (without prediction). The pointer
+ * pDstmust be aligned on a 16-byte boundary.
+ * pRec - pointer to the reconstructed texture; must be aligned on an
+ * 8-byte boundary.
+ * pPredBufRow - pointer to the updated coefficient row buffer
+ * pPredBufCol - pointer to the updated coefficient column buffer
+ * pPreACPredict - if prediction is enabled, the parameter points to the
+ * start of the buffer containing the coefficient differences for
+ * VLC encoding. The entry pPreACPredict[0]indicates prediction
+ * direction for the current block and takes one of the following
+ * values: OMX_VC_NONE (prediction disabled), OMX_VC_HORIZONTAL, or
+ * OMX_VC_VERTICAL. The entries
+ * pPreACPredict[1]-pPreACPredict[7]contain predicted AC
+ * coefficients. If prediction is disabled (*pSumErr<0) then the
+ * contents of this buffer are undefined upon return from the
+ * function
+ * pSumErr - pointer to the value of the accumulated AC coefficient errors,
+ * i.e., sum of the absolute differences between predicted and
+ * unpredicted AC coefficients
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - Bad arguments:
+ * - At least one of the following pointers is NULL: pSrc, pDst, pRec,
+ * pCoefBufRow, pCoefBufCol, pQpBuf, pPreACPredict, pSumErr.
+ * - blockIndex < 0 or blockIndex >= 10;
+ * - curQP <= 0 or curQP >= 32.
+ * - srcStep, or dstStep <= 0 or not a multiple of 8.
+ * - pDst is not 16-byte aligned: .
+ * - At least one of the following pointers is not 8-byte aligned:
+ * pSrc, pRec.
+ *
+ * Note: The coefficient buffers must be updated in accordance with the
+ * update procedures defined in section in 6.2.2.
+ *
+ */
+
+OMXResult omxVCM4P2_TransRecBlockCoef_intra(
+ const OMX_U8 *pSrc,
+ OMX_S16 * pDst,
+ OMX_U8 * pRec,
+ OMX_S16 *pPredBufRow,
+ OMX_S16 *pPredBufCol,
+ OMX_S16 * pPreACPredict,
+ OMX_INT *pSumErr,
+ OMX_INT blockIndex,
+ OMX_U8 curQp,
+ const OMX_U8 *pQpBuf,
+ OMX_INT srcStep,
+ OMX_INT dstStep,
+ OMX_INT shortVideoHeader
+)
+{
+ /* 64 elements are needed but to align it to 16 bytes need
+ 8 more elements of padding */
+ OMX_S16 tempBuf1[79], tempBuf2[79];
+ OMX_S16 tempBuf3[79];
+ OMX_S16 *pTempBuf1, *pTempBuf2,*pTempBuf3;
+ OMXVCM4P2VideoComponent videoComp;
+ OMX_U8 flag;
+ OMX_INT x, y, count, predDir;
+ OMX_INT predQP, ACPredFlag;
+
+
+ /* Aligning the local buffers */
+ pTempBuf1 = armAlignTo16Bytes(tempBuf1);
+ pTempBuf2 = armAlignTo16Bytes(tempBuf2);
+ pTempBuf3 = armAlignTo16Bytes(tempBuf3);
+
+ /* Argument error checks */
+ armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pRec == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(!armIs8ByteAligned(pSrc), OMX_Sts_BadArgErr);
+ armRetArgErrIf(!armIs8ByteAligned(pRec), OMX_Sts_BadArgErr);
+ armRetArgErrIf(!armIs16ByteAligned(pDst), OMX_Sts_BadArgErr);
+ armRetArgErrIf(pPredBufRow == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pPredBufCol == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pPreACPredict == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pSumErr == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pQpBuf == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf((srcStep <= 0) || (dstStep <= 0) ||
+ (dstStep & 7) || (srcStep & 7)
+ , OMX_Sts_BadArgErr);
+ armRetArgErrIf((blockIndex < 0) || (blockIndex > 9), OMX_Sts_BadArgErr);
+
+ armRetArgErrIf((curQp <= 0) || (curQp >=32), OMX_Sts_BadArgErr);
+
+
+ /* Setting the videoComp */
+ if (blockIndex <= 3)
+ {
+ videoComp = OMX_VC_LUMINANCE;
+ }
+ else
+ {
+ videoComp = OMX_VC_CHROMINANCE;
+ }
+ /* Converting from 2-d to 1-d buffer */
+ for (y = 0, count = 0; y < 8; y++)
+ {
+ for(x= 0; x < 8; x++, count++)
+ {
+ pTempBuf1[count] = pSrc[(y*srcStep) + x];
+ }
+ }
+
+ omxVCM4P2_DCT8x8blk (pTempBuf1, pTempBuf2);
+ omxVCM4P2_QuantIntra_I(
+ pTempBuf2,
+ curQp,
+ blockIndex,
+ shortVideoHeader);
+
+ /* Converting from 1-D to 2-D buffer */
+ for (y = 0, count = 0; y < 8; y++)
+ {
+ for(x = 0; x < 8; x++, count++)
+ {
+ /* storing tempbuf2 to tempbuf1 */
+ pTempBuf1[count] = pTempBuf2[count];
+ pDst[(y*dstStep) + x] = pTempBuf2[count];
+ }
+ }
+
+ /* AC and DC prediction */
+ armVCM4P2_SetPredDir(
+ blockIndex,
+ pPredBufRow,
+ pPredBufCol,
+ &predDir,
+ &predQP,
+ pQpBuf);
+
+ armRetDataErrIf(((predQP <= 0) || (predQP >= 32)), OMX_Sts_BadArgErr);
+
+ flag = 1;
+ if (*pSumErr < 0)
+ {
+ ACPredFlag = 0;
+ }
+ else
+ {
+ ACPredFlag = 1;
+ }
+
+ armVCM4P2_ACDCPredict(
+ pTempBuf2,
+ pPreACPredict,
+ pPredBufRow,
+ pPredBufCol,
+ curQp,
+ predQP,
+ predDir,
+ ACPredFlag,
+ videoComp,
+ flag,
+ pSumErr);
+
+ /* Reconstructing the texture data */
+ omxVCM4P2_QuantInvIntra_I(
+ pTempBuf1,
+ curQp,
+ videoComp,
+ shortVideoHeader);
+ omxVCM4P2_IDCT8x8blk (pTempBuf1, pTempBuf3);
+ for(count = 0; count < 64; count++)
+ {
+ pRec[count] = armMax(0,pTempBuf3[count]);
+ }
+
+ return OMX_Sts_NoErr;
+}
+
+/* End of file */
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/src/armVC_Version.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/src/armVC_Version.c
new file mode 100644
index 0000000..5d93681
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/src/armVC_Version.c
@@ -0,0 +1,6 @@
+#include "omxtypes.h"
+#include "armCOMM_Version.h"
+
+#ifdef ARM_INCLUDE_VERSION_DESCRIPTIONS
+const char * const omxVC_VersionDescription = "ARM OpenMAX DL v" ARM_VERSION_STRING " Rel=" OMX_ARM_RELEASE_TAG " Arch=" OMX_ARM_BUILD_ARCHITECTURE " Tools=" OMX_ARM_BUILD_TOOLCHAIN ;
+#endif /* ARM_INCLUDE_VERSION_DESCRIPTIONS */
diff --git a/media/libstagefright/codecs/on2/h264dec/source/DecTestBench.c b/media/libstagefright/codecs/on2/h264dec/source/DecTestBench.c
new file mode 100755
index 0000000..dcf2ef6
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/DecTestBench.c
@@ -0,0 +1,761 @@
+/*
+ * 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.
+ */
+
+#include "H264SwDecApi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/*------------------------------------------------------------------------------
+ Module defines
+------------------------------------------------------------------------------*/
+
+/* CHECK_MEMORY_USAGE prints and sums the memory allocated in calls to
+ * H264SwDecMalloc() */
+/* #define CHECK_MEMORY_USAGE */
+
+/* _NO_OUT disables output file writing */
+/* #define _NO_OUT */
+
+/* Debug prints */
+#define DEBUG(argv) printf argv
+
+/* CVS tag name for identification */
+const char tagName[256] = "$Name: FIRST_ANDROID_COPYRIGHT $";
+
+void WriteOutput(char *filename, u8 *data, u32 picSize);
+u32 NextPacket(u8 **pStrm);
+u32 CropPicture(u8 *pOutImage, u8 *pInImage,
+ u32 picWidth, u32 picHeight, CropParams *pCropParams);
+
+/* Global variables for stream handling */
+u8 *streamStop = NULL;
+u32 packetize = 0;
+u32 nalUnitStream = 0;
+FILE *foutput = NULL;
+
+#ifdef SOC_DESIGNER
+
+// Initialisation function defined in InitCache.s
+extern void cache_init(void);
+
+/*------------------------------------------------------------------------------
+
+ Function name: $Sub$$main
+
+ Purpose:
+ This function is called at the end of the C library initialisation and
+ before main. Its purpose is to do any further initialisation before the
+ application start.
+
+------------------------------------------------------------------------------*/
+int $Sub$$main(char argc, char * argv[])
+{
+ cache_init(); // does some extra setup work setting up caches
+ return $Super$$main(argc, argv); // calls the original function
+}
+#endif
+
+/*------------------------------------------------------------------------------
+
+ Function name: main
+
+ Purpose:
+ main function of decoder testbench. Provides command line interface
+ with file I/O for H.264 decoder. Prints out the usage information
+ when executed without arguments.
+
+------------------------------------------------------------------------------*/
+
+int main(int argc, char **argv)
+{
+
+ u32 i, tmp;
+ u32 maxNumPics = 0;
+ u8 *byteStrmStart;
+ u8 *imageData;
+ u8 *tmpImage = NULL;
+ u32 strmLen;
+ u32 picSize;
+ H264SwDecInst decInst;
+ H264SwDecRet ret;
+ H264SwDecInput decInput;
+ H264SwDecOutput decOutput;
+ H264SwDecPicture decPicture;
+ H264SwDecInfo decInfo;
+ H264SwDecApiVersion decVer;
+ u32 picDecodeNumber;
+ u32 picDisplayNumber;
+ u32 numErrors = 0;
+ u32 cropDisplay = 0;
+ u32 disableOutputReordering = 0;
+
+ FILE *finput;
+
+ char outFileName[256] = "";
+
+ /* Print API version number */
+ decVer = H264SwDecGetAPIVersion();
+ DEBUG(("H.264 Decoder API v%d.%d\n", decVer.major, decVer.minor));
+
+ /* Print tag name if '-T' argument present */
+ if ( argc > 1 && strcmp(argv[1], "-T") == 0 )
+ {
+ DEBUG(("%s\n", tagName));
+ return 0;
+ }
+
+ /* Check that enough command line arguments given, if not -> print usage
+ * information out */
+ if (argc < 2)
+ {
+ DEBUG((
+ "Usage: %s [-Nn] [-Ooutfile] [-P] [-U] [-C] [-R] [-T] file.h264\n",
+ argv[0]));
+ DEBUG(("\t-Nn forces decoding to stop after n pictures\n"));
+#if defined(_NO_OUT)
+ DEBUG(("\t-Ooutfile output writing disabled at compile time\n"));
+#else
+ DEBUG(("\t-Ooutfile write output to \"outfile\" (default out_wxxxhyyy.yuv)\n"));
+ DEBUG(("\t-Onone does not write output\n"));
+#endif
+ DEBUG(("\t-P packet-by-packet mode\n"));
+ DEBUG(("\t-U NAL unit stream mode\n"));
+ DEBUG(("\t-C display cropped image (default decoded image)\n"));
+ DEBUG(("\t-R disable DPB output reordering\n"));
+ DEBUG(("\t-T to print tag name and exit\n"));
+ return 0;
+ }
+
+ /* read command line arguments */
+ for (i = 1; i < (u32)(argc-1); i++)
+ {
+ if ( strncmp(argv[i], "-N", 2) == 0 )
+ {
+ maxNumPics = (u32)atoi(argv[i]+2);
+ }
+ else if ( strncmp(argv[i], "-O", 2) == 0 )
+ {
+ strcpy(outFileName, argv[i]+2);
+ }
+ else if ( strcmp(argv[i], "-P") == 0 )
+ {
+ packetize = 1;
+ }
+ else if ( strcmp(argv[i], "-U") == 0 )
+ {
+ nalUnitStream = 1;
+ }
+ else if ( strcmp(argv[i], "-C") == 0 )
+ {
+ cropDisplay = 1;
+ }
+ else if ( strcmp(argv[i], "-R") == 0 )
+ {
+ disableOutputReordering = 1;
+ }
+ }
+
+ /* open input file for reading, file name given by user. If file open
+ * fails -> exit */
+ finput = fopen(argv[argc-1],"rb");
+ if (finput == NULL)
+ {
+ DEBUG(("UNABLE TO OPEN INPUT FILE\n"));
+ return -1;
+ }
+
+ /* check size of the input file -> length of the stream in bytes */
+ fseek(finput,0L,SEEK_END);
+ strmLen = (u32)ftell(finput);
+ rewind(finput);
+
+ /* allocate memory for stream buffer. if unsuccessful -> exit */
+ byteStrmStart = (u8 *)malloc(sizeof(u8)*strmLen);
+ if (byteStrmStart == NULL)
+ {
+ DEBUG(("UNABLE TO ALLOCATE MEMORY\n"));
+ return -1;
+ }
+
+ /* read input stream from file to buffer and close input file */
+ fread(byteStrmStart, sizeof(u8), strmLen, finput);
+ fclose(finput);
+
+ /* initialize decoder. If unsuccessful -> exit */
+ ret = H264SwDecInit(&decInst, disableOutputReordering);
+ if (ret != H264SWDEC_OK)
+ {
+ DEBUG(("DECODER INITIALIZATION FAILED\n"));
+ free(byteStrmStart);
+ return -1;
+ }
+
+ /* initialize H264SwDecDecode() input structure */
+ streamStop = byteStrmStart + strmLen;
+ decInput.pStream = byteStrmStart;
+ decInput.dataLen = strmLen;
+ decInput.intraConcealmentMethod = 0;
+
+ /* get pointer to next packet and the size of packet
+ * (for packetize or nalUnitStream modes) */
+ if ( (tmp = NextPacket(&decInput.pStream)) != 0 )
+ decInput.dataLen = tmp;
+
+ picDecodeNumber = picDisplayNumber = 1;
+ /* main decoding loop */
+ do
+ {
+ /* Picture ID is the picture number in decoding order */
+ decInput.picId = picDecodeNumber;
+
+ /* call API function to perform decoding */
+ ret = H264SwDecDecode(decInst, &decInput, &decOutput);
+
+ switch(ret)
+ {
+
+ case H264SWDEC_HDRS_RDY_BUFF_NOT_EMPTY:
+ /* Stream headers were successfully decoded
+ * -> stream information is available for query now */
+
+ ret = H264SwDecGetInfo(decInst, &decInfo);
+ if (ret != H264SWDEC_OK)
+ return -1;
+
+ DEBUG(("Profile %d\n", decInfo.profile));
+
+ DEBUG(("Width %d Height %d\n",
+ decInfo.picWidth, decInfo.picHeight));
+
+ if (cropDisplay && decInfo.croppingFlag)
+ {
+ DEBUG(("Cropping params: (%d, %d) %dx%d\n",
+ decInfo.cropParams.cropLeftOffset,
+ decInfo.cropParams.cropTopOffset,
+ decInfo.cropParams.cropOutWidth,
+ decInfo.cropParams.cropOutHeight));
+
+ /* Cropped frame size in planar YUV 4:2:0 */
+ picSize = decInfo.cropParams.cropOutWidth *
+ decInfo.cropParams.cropOutHeight;
+ picSize = (3 * picSize)/2;
+ tmpImage = malloc(picSize);
+ if (tmpImage == NULL)
+ return -1;
+ }
+ else
+ {
+ /* Decoder output frame size in planar YUV 4:2:0 */
+ picSize = decInfo.picWidth * decInfo.picHeight;
+ picSize = (3 * picSize)/2;
+ }
+
+ DEBUG(("videoRange %d, matrixCoefficients %d\n",
+ decInfo.videoRange, decInfo.matrixCoefficients));
+
+ /* update H264SwDecDecode() input structure, number of bytes
+ * "consumed" is computed as difference between the new stream
+ * pointer and old stream pointer */
+ decInput.dataLen -=
+ (u32)(decOutput.pStrmCurrPos - decInput.pStream);
+ decInput.pStream = decOutput.pStrmCurrPos;
+
+ /* If -O option not used, generate default file name */
+ if (outFileName[0] == 0)
+ sprintf(outFileName, "out_w%dh%d.yuv",
+ decInfo.picWidth, decInfo.picHeight);
+ break;
+
+ case H264SWDEC_PIC_RDY_BUFF_NOT_EMPTY:
+ /* Picture is ready and more data remains in input buffer
+ * -> update H264SwDecDecode() input structure, number of bytes
+ * "consumed" is computed as difference between the new stream
+ * pointer and old stream pointer */
+ decInput.dataLen -=
+ (u32)(decOutput.pStrmCurrPos - decInput.pStream);
+ decInput.pStream = decOutput.pStrmCurrPos;
+ /* fall through */
+
+ case H264SWDEC_PIC_RDY:
+
+ /*lint -esym(644,tmpImage,picSize) variable initialized at
+ * H264SWDEC_HDRS_RDY_BUFF_NOT_EMPTY case */
+
+ if (ret == H264SWDEC_PIC_RDY)
+ decInput.dataLen = NextPacket(&decInput.pStream);
+
+ /* If enough pictures decoded -> force decoding to end
+ * by setting that no more stream is available */
+ if (maxNumPics && picDecodeNumber == maxNumPics)
+ decInput.dataLen = 0;
+
+ /* Increment decoding number for every decoded picture */
+ picDecodeNumber++;
+
+ /* use function H264SwDecNextPicture() to obtain next picture
+ * in display order. Function is called until no more images
+ * are ready for display */
+ while ( H264SwDecNextPicture(decInst, &decPicture, 0) ==
+ H264SWDEC_PIC_RDY )
+ {
+ DEBUG(("PIC %d, type %s", picDisplayNumber,
+ decPicture.isIdrPicture ? "IDR" : "NON-IDR"));
+ if (picDisplayNumber != decPicture.picId)
+ DEBUG((", decoded pic %d", decPicture.picId));
+ if (decPicture.nbrOfErrMBs)
+ {
+ DEBUG((", concealed %d\n", decPicture.nbrOfErrMBs));
+ }
+ else
+ DEBUG(("\n"));
+ fflush(stdout);
+
+ numErrors += decPicture.nbrOfErrMBs;
+
+ /* Increment display number for every displayed picture */
+ picDisplayNumber++;
+
+ /*lint -esym(644,decInfo) always initialized if pictures
+ * available for display */
+
+ /* Write output picture to file */
+ imageData = (u8*)decPicture.pOutputPicture;
+ if (cropDisplay && decInfo.croppingFlag)
+ {
+ tmp = CropPicture(tmpImage, imageData,
+ decInfo.picWidth, decInfo.picHeight,
+ &decInfo.cropParams);
+ if (tmp)
+ return -1;
+ WriteOutput(outFileName, tmpImage, picSize);
+ }
+ else
+ {
+ WriteOutput(outFileName, imageData, picSize);
+ }
+ }
+
+ break;
+
+ case H264SWDEC_STRM_PROCESSED:
+ case H264SWDEC_STRM_ERR:
+ /* Input stream was decoded but no picture is ready
+ * -> Get more data */
+ decInput.dataLen = NextPacket(&decInput.pStream);
+ break;
+
+ default:
+ DEBUG(("FATAL ERROR\n"));
+ return -1;
+
+ }
+ /* keep decoding until all data from input stream buffer consumed */
+ } while (decInput.dataLen > 0);
+
+ /* if output in display order is preferred, the decoder shall be forced
+ * to output pictures remaining in decoded picture buffer. Use function
+ * H264SwDecNextPicture() to obtain next picture in display order. Function
+ * is called until no more images are ready for display. Second parameter
+ * for the function is set to '1' to indicate that this is end of the
+ * stream and all pictures shall be output */
+ while (H264SwDecNextPicture(decInst, &decPicture, 1) == H264SWDEC_PIC_RDY)
+ {
+ DEBUG(("PIC %d, type %s", picDisplayNumber,
+ decPicture.isIdrPicture ? "IDR" : "NON-IDR"));
+ if (picDisplayNumber != decPicture.picId)
+ DEBUG((", decoded pic %d", decPicture.picId));
+ if (decPicture.nbrOfErrMBs)
+ {
+ DEBUG((", concealed %d\n", decPicture.nbrOfErrMBs));
+ }
+ else
+ DEBUG(("\n"));
+ fflush(stdout);
+
+ numErrors += decPicture.nbrOfErrMBs;
+
+ /* Increment display number for every displayed picture */
+ picDisplayNumber++;
+
+ /* Write output picture to file */
+ imageData = (u8*)decPicture.pOutputPicture;
+ if (cropDisplay && decInfo.croppingFlag)
+ {
+ tmp = CropPicture(tmpImage, imageData,
+ decInfo.picWidth, decInfo.picHeight,
+ &decInfo.cropParams);
+ if (tmp)
+ return -1;
+ WriteOutput(outFileName, tmpImage, picSize);
+ }
+ else
+ {
+ WriteOutput(outFileName, imageData, picSize);
+ }
+ }
+
+ /* release decoder instance */
+ H264SwDecRelease(decInst);
+
+ if (foutput)
+ fclose(foutput);
+
+ /* free allocated buffers */
+ free(byteStrmStart);
+ free(tmpImage);
+
+ DEBUG(("Output file: %s\n", outFileName));
+
+ DEBUG(("DECODING DONE\n"));
+ if (numErrors || picDecodeNumber == 1)
+ {
+ DEBUG(("ERRORS FOUND\n"));
+ return 1;
+ }
+
+ return 0;
+}
+
+/*------------------------------------------------------------------------------
+
+ Function name: WriteOutput
+
+ Purpose:
+ Write picture pointed by data to file. Size of the
+ picture in pixels is indicated by picSize.
+
+------------------------------------------------------------------------------*/
+void WriteOutput(char *filename, u8 *data, u32 picSize)
+{
+
+ /* foutput is global file pointer */
+ if (foutput == NULL)
+ {
+ /* open output file for writing, can be disabled with define.
+ * If file open fails -> exit */
+ if (strcmp(filename, "none") != 0)
+ {
+#if !defined(_NO_OUT)
+ foutput = fopen(filename, "wb");
+ if (foutput == NULL)
+ {
+ DEBUG(("UNABLE TO OPEN OUTPUT FILE\n"));
+ exit(100);
+ }
+#endif
+ }
+ }
+
+ if (foutput && data)
+ fwrite(data, 1, picSize, foutput);
+}
+
+/*------------------------------------------------------------------------------
+
+ Function name: NextPacket
+
+ Purpose:
+ Get the pointer to start of next packet in input stream. Uses
+ global variables 'packetize' and 'nalUnitStream' to determine the
+ decoder input stream mode and 'streamStop' to determine the end
+ of stream. There are three possible stream modes:
+ default - the whole stream at once
+ packetize - a single NAL-unit with start code prefix
+ nalUnitStream - a single NAL-unit without start code prefix
+
+ pStrm stores pointer to the start of previous decoder input and is
+ replaced with pointer to the start of the next decoder input.
+
+ Returns the packet size in bytes
+
+------------------------------------------------------------------------------*/
+u32 NextPacket(u8 **pStrm)
+{
+
+ u32 index;
+ u32 maxIndex;
+ u32 zeroCount;
+ u8 *stream;
+ u8 byte;
+ static u32 prevIndex=0;
+
+ /* For default stream mode all the stream is in first packet */
+ if (!packetize && !nalUnitStream)
+ return 0;
+
+ index = 0;
+ stream = *pStrm + prevIndex;
+ maxIndex = (u32)(streamStop - stream);
+
+ if (maxIndex == 0)
+ return(0);
+
+ /* leading zeros of first NAL unit */
+ do
+ {
+ byte = stream[index++];
+ } while (byte != 1 && index < maxIndex);
+
+ /* invalid start code prefix */
+ if (index == maxIndex || index < 3)
+ {
+ DEBUG(("INVALID BYTE STREAM\n"));
+ exit(100);
+ }
+
+ /* nalUnitStream is without start code prefix */
+ if (nalUnitStream)
+ {
+ stream += index;
+ maxIndex -= index;
+ index = 0;
+ }
+
+ zeroCount = 0;
+
+ /* Search stream for next start code prefix */
+ /*lint -e(716) while(1) used consciously */
+ while (1)
+ {
+ byte = stream[index++];
+ if (!byte)
+ zeroCount++;
+
+ if ( (byte == 0x01) && (zeroCount >= 2) )
+ {
+ /* Start code prefix has two zeros
+ * Third zero is assumed to be leading zero of next packet
+ * Fourth and more zeros are assumed to be trailing zeros of this
+ * packet */
+ if (zeroCount > 3)
+ {
+ index -= 4;
+ zeroCount -= 3;
+ }
+ else
+ {
+ index -= zeroCount+1;
+ zeroCount = 0;
+ }
+ break;
+ }
+ else if (byte)
+ zeroCount = 0;
+
+ if (index == maxIndex)
+ {
+ break;
+ }
+
+ }
+
+ /* Store pointer to the beginning of the packet */
+ *pStrm = stream;
+ prevIndex = index;
+
+ /* nalUnitStream is without trailing zeros */
+ if (nalUnitStream)
+ index -= zeroCount;
+
+ return(index);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function name: CropPicture
+
+ Purpose:
+ Perform cropping for picture. Input picture pInImage with dimensions
+ picWidth x picHeight is cropped with pCropParams and the resulting
+ picture is stored in pOutImage.
+
+------------------------------------------------------------------------------*/
+u32 CropPicture(u8 *pOutImage, u8 *pInImage,
+ u32 picWidth, u32 picHeight, CropParams *pCropParams)
+{
+
+ u32 i, j;
+ u32 outWidth, outHeight;
+ u8 *pOut, *pIn;
+
+ if (pOutImage == NULL || pInImage == NULL || pCropParams == NULL ||
+ !picWidth || !picHeight)
+ {
+ /* just to prevent lint warning, returning non-zero will result in
+ * return without freeing the memory */
+ free(pOutImage);
+ return(1);
+ }
+
+ if ( ((pCropParams->cropLeftOffset + pCropParams->cropOutWidth) >
+ picWidth ) ||
+ ((pCropParams->cropTopOffset + pCropParams->cropOutHeight) >
+ picHeight ) )
+ {
+ /* just to prevent lint warning, returning non-zero will result in
+ * return without freeing the memory */
+ free(pOutImage);
+ return(1);
+ }
+
+ outWidth = pCropParams->cropOutWidth;
+ outHeight = pCropParams->cropOutHeight;
+
+ /* Calculate starting pointer for luma */
+ pIn = pInImage + pCropParams->cropTopOffset*picWidth +
+ pCropParams->cropLeftOffset;
+ pOut = pOutImage;
+
+ /* Copy luma pixel values */
+ for (i = outHeight; i; i--)
+ {
+ for (j = outWidth; j; j--)
+ {
+ *pOut++ = *pIn++;
+ }
+ pIn += picWidth - outWidth;
+ }
+
+ outWidth >>= 1;
+ outHeight >>= 1;
+
+ /* Calculate starting pointer for cb */
+ pIn = pInImage + picWidth*picHeight +
+ pCropParams->cropTopOffset*picWidth/4 + pCropParams->cropLeftOffset/2;
+
+ /* Copy cb pixel values */
+ for (i = outHeight; i; i--)
+ {
+ for (j = outWidth; j; j--)
+ {
+ *pOut++ = *pIn++;
+ }
+ pIn += picWidth/2 - outWidth;
+ }
+
+ /* Calculate starting pointer for cr */
+ pIn = pInImage + 5*picWidth*picHeight/4 +
+ pCropParams->cropTopOffset*picWidth/4 + pCropParams->cropLeftOffset/2;
+
+ /* Copy cr pixel values */
+ for (i = outHeight; i; i--)
+ {
+ for (j = outWidth; j; j--)
+ {
+ *pOut++ = *pIn++;
+ }
+ pIn += picWidth/2 - outWidth;
+ }
+
+ return (0);
+}
+
+/*------------------------------------------------------------------------------
+
+ Function name: H264SwDecTrace
+
+ Purpose:
+ Example implementation of H264SwDecTrace function. Prototype of this
+ function is given in H264SwDecApi.h. This implementation appends
+ trace messages to file named 'dec_api.trc'.
+
+------------------------------------------------------------------------------*/
+void H264SwDecTrace(char *string)
+{
+ FILE *fp;
+
+ fp = fopen("dec_api.trc", "at");
+
+ if (!fp)
+ return;
+
+ fwrite(string, 1, strlen(string), fp);
+ fwrite("\n", 1,1, fp);
+
+ fclose(fp);
+}
+
+/*------------------------------------------------------------------------------
+
+ Function name: H264SwDecMalloc
+
+ Purpose:
+ Example implementation of H264SwDecMalloc function. Prototype of this
+ function is given in H264SwDecApi.h. This implementation uses
+ library function malloc for allocation of memory.
+
+------------------------------------------------------------------------------*/
+void* H264SwDecMalloc(u32 size)
+{
+
+#if defined(CHECK_MEMORY_USAGE)
+ /* Note that if the decoder has to free and reallocate some of the buffers
+ * the total value will be invalid */
+ static u32 numBytes = 0;
+ numBytes += size;
+ DEBUG(("Allocated %d bytes, total %d\n", size, numBytes));
+#endif
+
+ return malloc(size);
+}
+
+/*------------------------------------------------------------------------------
+
+ Function name: H264SwDecFree
+
+ Purpose:
+ Example implementation of H264SwDecFree function. Prototype of this
+ function is given in H264SwDecApi.h. This implementation uses
+ library function free for freeing of memory.
+
+------------------------------------------------------------------------------*/
+void H264SwDecFree(void *ptr)
+{
+ free(ptr);
+}
+
+/*------------------------------------------------------------------------------
+
+ Function name: H264SwDecMemcpy
+
+ Purpose:
+ Example implementation of H264SwDecMemcpy function. Prototype of this
+ function is given in H264SwDecApi.h. This implementation uses
+ library function memcpy to copy src to dest.
+
+------------------------------------------------------------------------------*/
+void H264SwDecMemcpy(void *dest, void *src, u32 count)
+{
+ memcpy(dest, src, count);
+}
+
+/*------------------------------------------------------------------------------
+
+ Function name: H264SwDecMemset
+
+ Purpose:
+ Example implementation of H264SwDecMemset function. Prototype of this
+ function is given in H264SwDecApi.h. This implementation uses
+ library function memset to set content of memory area pointed by ptr.
+
+------------------------------------------------------------------------------*/
+void H264SwDecMemset(void *ptr, i32 value, u32 count)
+{
+ memset(ptr, value, count);
+}
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/EvaluationTestBench.c b/media/libstagefright/codecs/on2/h264dec/source/EvaluationTestBench.c
new file mode 100755
index 0000000..aadc75f
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/EvaluationTestBench.c
@@ -0,0 +1,350 @@
+/*
+ * 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.
+ */
+
+#include "H264SwDecApi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+void WriteOutput(FILE *fid, u8 *data, u32 picSize);
+
+/*------------------------------------------------------------------------------
+
+ Function name: main
+
+ Purpose:
+ main function. Assuming that executable is named 'decoder' the usage
+ is as follows
+
+ decoder inputFileName
+
+ , where inputFileName shall be name of file containing h264 stream
+ data.
+
+------------------------------------------------------------------------------*/
+int main(int argc, char **argv)
+{
+
+ u8 *byteStrmStart;
+ u8 *byteStrm;
+ u32 strmLen;
+ u32 picSize;
+ H264SwDecInst decInst;
+ H264SwDecRet ret;
+ H264SwDecInput decInput;
+ H264SwDecOutput decOutput;
+ H264SwDecPicture decPicture;
+ H264SwDecInfo decInfo;
+ u32 picNumber;
+
+ FILE *finput;
+ FILE *foutput;
+
+ /* Check that enough command line arguments given, if not -> print usage
+ * information out */
+ if (argc < 2)
+ {
+ printf( "Usage: %s file.h264\n", argv[0]);
+ return -1;
+ }
+
+ /* open output file for writing, output file named out.yuv. If file open
+ * fails -> exit */
+ foutput = fopen("out.yuv", "wb");
+ if (foutput == NULL)
+ {
+ printf("UNABLE TO OPEN OUTPUT FILE\n");
+ return -1;
+ }
+
+ /* open input file for reading, file name given by user. If file open
+ * fails -> exit */
+ finput = fopen(argv[argc-1], "rb");
+ if (finput == NULL)
+ {
+ printf("UNABLE TO OPEN INPUT FILE\n");
+ return -1;
+ }
+
+ /* check size of the input file -> length of the stream in bytes */
+ fseek(finput, 0L, SEEK_END);
+ strmLen = (u32)ftell(finput);
+ rewind(finput);
+
+ /* allocate memory for stream buffer, exit if unsuccessful */
+ byteStrm = byteStrmStart = (u8 *)H264SwDecMalloc(sizeof(u8)*strmLen);
+ if (byteStrm == NULL)
+ {
+ printf("UNABLE TO ALLOCATE MEMORY\n");
+ return -1;
+ }
+
+ /* read input stream from file to buffer and close input file */
+ fread(byteStrm, sizeof(u8), strmLen, finput);
+ fclose(finput);
+
+ /* initialize decoder. If unsuccessful -> exit */
+ ret = H264SwDecInit(&decInst, 0);
+ if (ret != H264SWDEC_OK)
+ {
+ printf("DECODER INITIALIZATION FAILED\n");
+ return -1;
+ }
+
+ /* initialize H264SwDecDecode() input structure */
+ decInput.pStream = byteStrmStart;
+ decInput.dataLen = strmLen;
+ decInput.intraConcealmentMethod = 0;
+
+ picNumber = 0;
+
+ /* For performance measurements, read the start time (in seconds) here.
+ * The decoding time should be measured over several frames and after
+ * that average fps (frames/second) can be calculated.
+ *
+ * startTime = GetTime();
+ *
+ * To prevent calculating file I/O latensies as a decoding time,
+ * comment out WriteOutput function call. Also prints to stdout might
+ * consume considerable amount of cycles during measurement */
+
+ /* main decoding loop */
+ do
+ {
+ /* call API function to perform decoding */
+ ret = H264SwDecDecode(decInst, &decInput, &decOutput);
+
+ switch(ret)
+ {
+
+ case H264SWDEC_HDRS_RDY_BUFF_NOT_EMPTY:
+
+ /* picture dimensions are available for query now */
+ ret = H264SwDecGetInfo(decInst, &decInfo);
+ if (ret != H264SWDEC_OK)
+ return -1;
+
+ /* picture size in pixels */
+ picSize = decInfo.picWidth * decInfo.picHeight;
+ /* memory needed for YCbCr 4:2:0 picture in bytes */
+ picSize = (3 * picSize)/2;
+ /* memory needed for 16-bit RGB picture in bytes
+ * picSize = (decInfo.picWidth * decInfo.picHeight) * 2; */
+
+ printf("Width %d Height %d\n",
+ decInfo.picWidth, decInfo.picHeight);
+
+ /* update H264SwDecDecode() input structure, number of bytes
+ * "consumed" is computed as difference between the new stream
+ * pointer and old stream pointer */
+ decInput.dataLen -=
+ (u32)(decOutput.pStrmCurrPos - decInput.pStream);
+ decInput.pStream = decOutput.pStrmCurrPos;
+ break;
+
+ case H264SWDEC_PIC_RDY_BUFF_NOT_EMPTY:
+ case H264SWDEC_PIC_RDY:
+
+ /* update H264SwDecDecode() input structure, number of bytes
+ * "consumed" is computed as difference between the new stream
+ * pointer and old stream pointer */
+ decInput.dataLen -=
+ (u32)(decOutput.pStrmCurrPos - decInput.pStream);
+ decInput.pStream = decOutput.pStrmCurrPos;
+
+ /* use function H264SwDecNextPicture() to obtain next picture
+ * in display order. Function is called until no more images
+ * are ready for display */
+ while (H264SwDecNextPicture(decInst, &decPicture, 0) ==
+ H264SWDEC_PIC_RDY) { picNumber++;
+
+ printf("PIC %d, type %s, concealed %d\n", picNumber,
+ decPicture.isIdrPicture ? "IDR" : "NON-IDR",
+ decPicture.nbrOfErrMBs);
+ fflush(stdout);
+
+ /* Do color conversion if needed to get display image
+ * in RGB-format
+ *
+ * YuvToRgb( decPicture.pOutputPicture, pRgbPicture ); */
+
+ /* write next display image to output file */
+ WriteOutput(foutput, (u8*)decPicture.pOutputPicture,
+ picSize);
+ }
+
+ break;
+
+ case H264SWDEC_EVALUATION_LIMIT_EXCEEDED:
+ /* evaluation version of the decoder has limited decoding
+ * capabilities */
+ printf("EVALUATION LIMIT REACHED\n");
+ goto end;
+
+ default:
+ printf("UNRECOVERABLE ERROR\n");
+ return -1;
+ }
+ /* keep decoding until all data from input stream buffer consumed */
+ } while (decInput.dataLen > 0);
+
+end:
+
+ /* if output in display order is preferred, the decoder shall be forced
+ * to output pictures remaining in decoded picture buffer. Use function
+ * H264SwDecNextPicture() to obtain next picture in display order. Function
+ * is called until no more images are ready for display. Second parameter
+ * for the function is set to '1' to indicate that this is end of the
+ * stream and all pictures shall be output */
+ while (H264SwDecNextPicture(decInst, &decPicture, 1) ==
+ H264SWDEC_PIC_RDY) {
+
+ picNumber++;
+
+ printf("PIC %d, type %s, concealed %d\n", picNumber,
+ decPicture.isIdrPicture ? "IDR" : "NON-IDR",
+ decPicture.nbrOfErrMBs);
+ fflush(stdout);
+
+ /* Do color conversion if needed to get display image
+ * in RGB-format
+ *
+ * YuvToRgb( decPicture.pOutputPicture, pRgbPicture ); */
+
+ /* write next display image to output file */
+ WriteOutput(foutput, (u8*)decPicture.pOutputPicture, picSize);
+ }
+
+ /* For performance measurements, read the end time (in seconds) here.
+ *
+ * endTime = GetTime();
+ *
+ * Now the performance can be calculated as frames per second:
+ * fps = picNumber / (endTime - startTime); */
+
+
+ /* release decoder instance */
+ H264SwDecRelease(decInst);
+
+ /* close output file */
+ fclose(foutput);
+
+ /* free byte stream buffer */
+ free(byteStrmStart);
+
+ return 0;
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function name: WriteOutput
+
+ Purpose:
+ Write picture pointed by data to file pointed by fid. Size of the
+ picture in pixels is indicated by picSize.
+
+------------------------------------------------------------------------------*/
+void WriteOutput(FILE *fid, u8 *data, u32 picSize)
+{
+ fwrite(data, 1, picSize, fid);
+}
+
+/*------------------------------------------------------------------------------
+
+ Function name: H264SwDecTrace
+
+ Purpose:
+ Example implementation of H264SwDecTrace function. Prototype of this
+ function is given in H264SwDecApi.h. This implementation appends
+ trace messages to file named 'dec_api.trc'.
+
+------------------------------------------------------------------------------*/
+void H264SwDecTrace(char *string)
+{
+ FILE *fp;
+
+ fp = fopen("dec_api.trc", "at");
+
+ if (!fp)
+ return;
+
+ fwrite(string, 1, strlen(string), fp);
+ fwrite("\n", 1,1, fp);
+
+ fclose(fp);
+}
+
+/*------------------------------------------------------------------------------
+
+ Function name: H264SwDecmalloc
+
+ Purpose:
+ Example implementation of H264SwDecMalloc function. Prototype of this
+ function is given in H264SwDecApi.h. This implementation uses
+ library function malloc for allocation of memory.
+
+------------------------------------------------------------------------------*/
+void* H264SwDecMalloc(u32 size)
+{
+ return malloc(size);
+}
+
+/*------------------------------------------------------------------------------
+
+ Function name: H264SwDecFree
+
+ Purpose:
+ Example implementation of H264SwDecFree function. Prototype of this
+ function is given in H264SwDecApi.h. This implementation uses
+ library function free for freeing of memory.
+
+------------------------------------------------------------------------------*/
+void H264SwDecFree(void *ptr)
+{
+ free(ptr);
+}
+
+/*------------------------------------------------------------------------------
+
+ Function name: H264SwDecMemcpy
+
+ Purpose:
+ Example implementation of H264SwDecMemcpy function. Prototype of this
+ function is given in H264SwDecApi.h. This implementation uses
+ library function memcpy to copy src to dest.
+
+------------------------------------------------------------------------------*/
+void H264SwDecMemcpy(void *dest, void *src, u32 count)
+{
+ memcpy(dest, src, count);
+}
+
+/*------------------------------------------------------------------------------
+
+ Function name: H264SwDecMemset
+
+ Purpose:
+ Example implementation of H264SwDecMemset function. Prototype of this
+ function is given in H264SwDecApi.h. This implementation uses
+ library function memset to set content of memory area pointed by ptr.
+
+------------------------------------------------------------------------------*/
+void H264SwDecMemset(void *ptr, i32 value, u32 count)
+{
+ memset(ptr, value, count);
+}
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/H264SwDecApi.c b/media/libstagefright/codecs/on2/h264dec/source/H264SwDecApi.c
new file mode 100644
index 0000000..2bb4c4d
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/H264SwDecApi.c
@@ -0,0 +1,567 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ H264SwDecInit
+ H264SwDecGetInfo
+ H264SwDecRelease
+ H264SwDecDecode
+ H264SwDecGetAPIVersion
+ H264SwDecNextPicture
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+#include <stdlib.h>
+#include "basetype.h"
+#include "h264bsd_container.h"
+#include "H264SwDecApi.h"
+#include "h264bsd_decoder.h"
+#include "h264bsd_util.h"
+
+/*------------------------------------------------------------------------------
+ Version Information
+------------------------------------------------------------------------------*/
+
+#define H264SWDEC_MAJOR_VERSION 2
+#define H264SWDEC_MINOR_VERSION 3
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+H264DEC_TRACE Trace H264 Decoder API function calls.
+H264DEC_EVALUATION Compile evaluation version, restricts number of frames
+ that can be decoded
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+#ifdef H264DEC_TRACE
+#include <stdio.h>
+#define DEC_API_TRC(str) H264SwDecTrace(str)
+#else
+#define DEC_API_TRC(str)
+#endif
+
+#ifdef H264DEC_EVALUATION
+#define H264DEC_EVALUATION_LIMIT 500
+#endif
+
+void H264SwDecTrace(char *string) {
+}
+
+void* H264SwDecMalloc(u32 size) {
+ return malloc(size);
+}
+
+void H264SwDecFree(void *ptr) {
+ free(ptr);
+}
+
+void H264SwDecMemcpy(void *dest, void *src, u32 count) {
+ memcpy(dest, src, count);
+}
+
+void H264SwDecMemset(void *ptr, i32 value, u32 count) {
+ memset(ptr, value, count);
+}
+
+
+/*------------------------------------------------------------------------------
+
+ Function: H264SwDecInit()
+
+ Functional description:
+ Initialize decoder software. Function reserves memory for the
+ decoder instance and calls h264bsdInit to initialize the
+ instance data.
+
+ Inputs:
+ noOutputReordering flag to indicate decoder that it doesn't have
+ to try to provide output pictures in display
+ order, saves memory
+
+ Outputs:
+ decInst pointer to initialized instance is stored here
+
+ Returns:
+ H264SWDEC_OK successfully initialized the instance
+ H264SWDEC_INITFAIL initialization failed
+ H264SWDEC_PARAM_ERR invalid parameters
+ H264SWDEC_MEM_FAIL memory allocation failed
+
+------------------------------------------------------------------------------*/
+
+H264SwDecRet H264SwDecInit(H264SwDecInst *decInst, u32 noOutputReordering)
+{
+ u32 rv = 0;
+
+ decContainer_t *pDecCont;
+
+ DEC_API_TRC("H264SwDecInit#");
+
+ /* check that right shift on negative numbers is performed signed */
+ /*lint -save -e* following check causes multiple lint messages */
+ if ( ((-1)>>1) != (-1) )
+ {
+ DEC_API_TRC("H264SwDecInit# ERROR: Right shift is not signed");
+ return(H264SWDEC_INITFAIL);
+ }
+ /*lint -restore */
+
+ if (decInst == NULL)
+ {
+ DEC_API_TRC("H264SwDecInit# ERROR: decInst == NULL");
+ return(H264SWDEC_PARAM_ERR);
+ }
+
+ pDecCont = (decContainer_t *)H264SwDecMalloc(sizeof(decContainer_t));
+
+ if (pDecCont == NULL)
+ {
+ DEC_API_TRC("H264SwDecInit# ERROR: Memory allocation failed");
+ return(H264SWDEC_MEMFAIL);
+ }
+
+#ifdef H264DEC_TRACE
+ sprintf(pDecCont->str, "H264SwDecInit# decInst %p noOutputReordering %d",
+ (void*)decInst, noOutputReordering);
+ DEC_API_TRC(pDecCont->str);
+#endif
+
+ rv = h264bsdInit(&pDecCont->storage, noOutputReordering);
+ if (rv != HANTRO_OK)
+ {
+ H264SwDecRelease(pDecCont);
+ return(H264SWDEC_MEMFAIL);
+ }
+
+ pDecCont->decStat = INITIALIZED;
+ pDecCont->picNumber = 0;
+
+#ifdef H264DEC_TRACE
+ sprintf(pDecCont->str, "H264SwDecInit# OK: return %p", (void*)pDecCont);
+ DEC_API_TRC(pDecCont->str);
+#endif
+
+ *decInst = (decContainer_t *)pDecCont;
+
+ return(H264SWDEC_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: H264SwDecGetInfo()
+
+ Functional description:
+ This function provides read access to decoder information. This
+ function should not be called before H264SwDecDecode function has
+ indicated that headers are ready.
+
+ Inputs:
+ decInst decoder instance
+
+ Outputs:
+ pDecInfo pointer to info struct where data is written
+
+ Returns:
+ H264SWDEC_OK success
+ H264SWDEC_PARAM_ERR invalid parameters
+ H264SWDEC_HDRS_NOT_RDY information not available yet
+
+------------------------------------------------------------------------------*/
+
+H264SwDecRet H264SwDecGetInfo(H264SwDecInst decInst, H264SwDecInfo *pDecInfo)
+{
+
+ storage_t *pStorage;
+
+ DEC_API_TRC("H264SwDecGetInfo#");
+
+ if (decInst == NULL || pDecInfo == NULL)
+ {
+ DEC_API_TRC("H264SwDecGetInfo# ERROR: decInst or pDecInfo is NULL");
+ return(H264SWDEC_PARAM_ERR);
+ }
+
+ pStorage = &(((decContainer_t *)decInst)->storage);
+
+ if (pStorage->activeSps == NULL || pStorage->activePps == NULL)
+ {
+ DEC_API_TRC("H264SwDecGetInfo# ERROR: Headers not decoded yet");
+ return(H264SWDEC_HDRS_NOT_RDY);
+ }
+
+#ifdef H264DEC_TRACE
+ sprintf(((decContainer_t*)decInst)->str,
+ "H264SwDecGetInfo# decInst %p pDecInfo %p", decInst, (void*)pDecInfo);
+ DEC_API_TRC(((decContainer_t*)decInst)->str);
+#endif
+
+ /* h264bsdPicWidth and -Height return dimensions in macroblock units,
+ * picWidth and -Height in pixels */
+ pDecInfo->picWidth = h264bsdPicWidth(pStorage) << 4;
+ pDecInfo->picHeight = h264bsdPicHeight(pStorage) << 4;
+ pDecInfo->videoRange = h264bsdVideoRange(pStorage);
+ pDecInfo->matrixCoefficients = h264bsdMatrixCoefficients(pStorage);
+
+ h264bsdCroppingParams(pStorage,
+ &pDecInfo->croppingFlag,
+ &pDecInfo->cropParams.cropLeftOffset,
+ &pDecInfo->cropParams.cropOutWidth,
+ &pDecInfo->cropParams.cropTopOffset,
+ &pDecInfo->cropParams.cropOutHeight);
+
+ /* sample aspect ratio */
+ h264bsdSampleAspectRatio(pStorage,
+ &pDecInfo->parWidth,
+ &pDecInfo->parHeight);
+
+ /* profile */
+ pDecInfo->profile = h264bsdProfile(pStorage);
+
+ DEC_API_TRC("H264SwDecGetInfo# OK");
+
+ return(H264SWDEC_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: H264SwDecRelease()
+
+ Functional description:
+ Release the decoder instance. Function calls h264bsdShutDown to
+ release instance data and frees the memory allocated for the
+ instance.
+
+ Inputs:
+ decInst Decoder instance
+
+ Outputs:
+ none
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+void H264SwDecRelease(H264SwDecInst decInst)
+{
+
+ decContainer_t *pDecCont;
+
+ DEC_API_TRC("H264SwDecRelease#");
+
+ if (decInst == NULL)
+ {
+ DEC_API_TRC("H264SwDecRelease# ERROR: decInst == NULL");
+ return;
+ }
+
+ pDecCont = (decContainer_t*)decInst;
+
+#ifdef H264DEC_TRACE
+ sprintf(pDecCont->str, "H264SwDecRelease# decInst %p",decInst);
+ DEC_API_TRC(pDecCont->str);
+#endif
+
+ h264bsdShutdown(&pDecCont->storage);
+
+ H264SwDecFree(pDecCont);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: H264SwDecDecode
+
+ Functional description:
+ Decode stream data. Calls h264bsdDecode to do the actual decoding.
+
+ Input:
+ decInst decoder instance
+ pInput pointer to input struct
+
+ Outputs:
+ pOutput pointer to output struct
+
+ Returns:
+ H264SWDEC_NOT_INITIALIZED decoder instance not initialized yet
+ H264SWDEC_PARAM_ERR invalid parameters
+
+ H264SWDEC_STRM_PROCESSED stream buffer decoded
+ H264SWDEC_HDRS_RDY_BUFF_NOT_EMPTY headers decoded,
+ stream buffer not finished
+ H264SWDEC_PIC_RDY decoding of a picture finished
+ H264SWDEC_PIC_RDY_BUFF_NOT_EMPTY decoding of a picture finished,
+ stream buffer not finished
+ H264SWDEC_STRM_ERR serious error in decoding, no
+ valid parameter sets available
+ to decode picture data
+ H264SWDEC_EVALUATION_LIMIT_EXCEEDED this can only occur when
+ evaluation version is used,
+ max number of frames reached
+
+------------------------------------------------------------------------------*/
+
+H264SwDecRet H264SwDecDecode(H264SwDecInst decInst, H264SwDecInput *pInput,
+ H264SwDecOutput *pOutput)
+{
+
+ decContainer_t *pDecCont;
+ u32 strmLen;
+ u32 numReadBytes;
+ u8 *tmpStream;
+ u32 decResult = 0;
+ H264SwDecRet returnValue = H264SWDEC_STRM_PROCESSED;
+
+ DEC_API_TRC("H264SwDecDecode#");
+
+ /* Check that function input parameters are valid */
+ if (pInput == NULL || pOutput == NULL)
+ {
+ DEC_API_TRC("H264SwDecDecode# ERROR: pInput or pOutput is NULL");
+ return(H264SWDEC_PARAM_ERR);
+ }
+
+ if ((pInput->pStream == NULL) || (pInput->dataLen == 0))
+ {
+ DEC_API_TRC("H264SwDecDecode# ERROR: Invalid input parameters");
+ return(H264SWDEC_PARAM_ERR);
+ }
+
+ pDecCont = (decContainer_t *)decInst;
+
+ /* Check if decoder is in an incorrect mode */
+ if (decInst == NULL || pDecCont->decStat == UNINITIALIZED)
+ {
+ DEC_API_TRC("H264SwDecDecode# ERROR: Decoder not initialized");
+ return(H264SWDEC_NOT_INITIALIZED);
+ }
+
+#ifdef H264DEC_EVALUATION
+ if (pDecCont->picNumber >= H264DEC_EVALUATION_LIMIT)
+ return(H264SWDEC_EVALUATION_LIMIT_EXCEEDED);
+#endif
+
+#ifdef H264DEC_TRACE
+ sprintf(pDecCont->str, "H264SwDecDecode# decInst %p pInput %p pOutput %p",
+ decInst, (void*)pInput, (void*)pOutput);
+ DEC_API_TRC(pDecCont->str);
+#endif
+
+ pOutput->pStrmCurrPos = NULL;
+
+ numReadBytes = 0;
+ strmLen = pInput->dataLen;
+ tmpStream = pInput->pStream;
+ pDecCont->storage.intraConcealmentFlag = pInput->intraConcealmentMethod;
+
+ do
+ {
+ /* Return HDRS_RDY after DPB flush caused by new SPS */
+ if (pDecCont->decStat == NEW_HEADERS)
+ {
+ decResult = H264BSD_HDRS_RDY;
+ pDecCont->decStat = INITIALIZED;
+ }
+ else /* Continue decoding normally */
+ {
+ decResult = h264bsdDecode(&pDecCont->storage, tmpStream, strmLen,
+ pInput->picId, &numReadBytes);
+ }
+ tmpStream += numReadBytes;
+ /* check if too many bytes are read from stream */
+ if ( (i32)(strmLen - numReadBytes) >= 0 )
+ strmLen -= numReadBytes;
+ else
+ strmLen = 0;
+
+ pOutput->pStrmCurrPos = tmpStream;
+
+ switch (decResult)
+ {
+ case H264BSD_HDRS_RDY:
+
+ if(pDecCont->storage.dpb->flushed &&
+ pDecCont->storage.dpb->numOut !=
+ pDecCont->storage.dpb->outIndex)
+ {
+ /* output first all DPB stored pictures
+ * DPB flush caused by new SPS */
+ pDecCont->storage.dpb->flushed = 0;
+ pDecCont->decStat = NEW_HEADERS;
+ returnValue = H264SWDEC_PIC_RDY_BUFF_NOT_EMPTY;
+ strmLen = 0;
+ }
+ else
+ {
+ returnValue = H264SWDEC_HDRS_RDY_BUFF_NOT_EMPTY;
+ strmLen = 0;
+ }
+ break;
+
+ case H264BSD_PIC_RDY:
+ pDecCont->picNumber++;
+
+ if (strmLen == 0)
+ returnValue = H264SWDEC_PIC_RDY;
+ else
+ returnValue = H264SWDEC_PIC_RDY_BUFF_NOT_EMPTY;
+
+ strmLen = 0;
+ break;
+
+ case H264BSD_PARAM_SET_ERROR:
+ if ( !h264bsdCheckValidParamSets(&pDecCont->storage) &&
+ strmLen == 0 )
+ {
+ returnValue = H264SWDEC_STRM_ERR;
+ }
+ break;
+ case H264BSD_MEMALLOC_ERROR:
+ {
+ returnValue = H264SWDEC_MEMFAIL;
+ strmLen = 0;
+ }
+ break;
+ default:
+ break;
+ }
+
+ } while (strmLen);
+
+#ifdef H264DEC_TRACE
+ sprintf(pDecCont->str, "H264SwDecDecode# OK: DecResult %d",
+ returnValue);
+ DEC_API_TRC(pDecCont->str);
+#endif
+
+ return(returnValue);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: H264SwDecGetAPIVersion
+
+ Functional description:
+ Return version information of the API
+
+ Inputs:
+ none
+
+ Outputs:
+ none
+
+ Returns:
+ API version
+
+------------------------------------------------------------------------------*/
+
+H264SwDecApiVersion H264SwDecGetAPIVersion()
+{
+ H264SwDecApiVersion ver;
+
+ ver.major = H264SWDEC_MAJOR_VERSION;
+ ver.minor = H264SWDEC_MINOR_VERSION;
+
+ return(ver);
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: H264SwDecNextPicture
+
+ Functional description:
+ Get next picture in display order if any available.
+
+ Input:
+ decInst decoder instance.
+ flushBuffer force output of all buffered pictures
+
+ Output:
+ pOutput pointer to output structure
+
+ Returns:
+ H264SWDEC_OK no pictures available for display
+ H264SWDEC_PIC_RDY picture available for display
+ H264SWDEC_PARAM_ERR invalid parameters
+
+------------------------------------------------------------------------------*/
+
+H264SwDecRet H264SwDecNextPicture(H264SwDecInst decInst,
+ H264SwDecPicture *pOutput, u32 flushBuffer)
+{
+
+ decContainer_t *pDecCont;
+ u32 numErrMbs, isIdrPic, picId;
+ u32 *pOutPic;
+
+ DEC_API_TRC("H264SwDecNextPicture#");
+
+ if (decInst == NULL || pOutput == NULL)
+ {
+ DEC_API_TRC("H264SwDecNextPicture# ERROR: decInst or pOutput is NULL");
+ return(H264SWDEC_PARAM_ERR);
+ }
+
+ pDecCont = (decContainer_t*)decInst;
+
+#ifdef H264DEC_TRACE
+ sprintf(pDecCont->str, "H264SwDecNextPicture# decInst %p pOutput %p %s %d",
+ decInst, (void*)pOutput, "flushBuffer", flushBuffer);
+ DEC_API_TRC(pDecCont->str);
+#endif
+
+ if (flushBuffer)
+ h264bsdFlushBuffer(&pDecCont->storage);
+
+ pOutPic = (u32*)h264bsdNextOutputPicture(&pDecCont->storage, &picId,
+ &isIdrPic, &numErrMbs);
+
+ if (pOutPic == NULL)
+ {
+ DEC_API_TRC("H264SwDecNextPicture# OK: return H264SWDEC_OK");
+ return(H264SWDEC_OK);
+ }
+ else
+ {
+ pOutput->pOutputPicture = pOutPic;
+ pOutput->picId = picId;
+ pOutput->isIdrPicture = isIdrPic;
+ pOutput->nbrOfErrMBs = numErrMbs;
+ DEC_API_TRC("H264SwDecNextPicture# OK: return H264SWDEC_PIC_RDY");
+ return(H264SWDEC_PIC_RDY);
+ }
+
+}
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/TestBenchMultipleInstance.c b/media/libstagefright/codecs/on2/h264dec/source/TestBenchMultipleInstance.c
new file mode 100755
index 0000000..42170d3
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/TestBenchMultipleInstance.c
@@ -0,0 +1,531 @@
+/*
+ * 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.
+ */
+
+/* CVS tag name for identification */
+const char tagName[256] = "$Name: FIRST_ANDROID_COPYRIGHT $";
+
+#include "H264SwDecApi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define DEBUG(argv) printf argv
+
+/* _NO_OUT disables output file writing */
+#ifdef __arm
+#define _NO_OUT
+#endif
+
+/*------------------------------------------------------------------------------
+
+------------------------------------------------------------------------------*/
+void WriteOutput(FILE *fid, u8 *data, u32 picSize);
+
+u32 CropPicture(u8 *pOutImage, u8 *pInImage,
+ u32 picWidth, u32 picHeight, CropParams *pCropParams);
+
+void CropWriteOutput(FILE *fid, u8 *imageData, u32 cropDisplay,
+ H264SwDecInfo *decInfo);
+
+typedef struct
+{
+ H264SwDecInst decInst;
+ H264SwDecInput decInput;
+ H264SwDecOutput decOutput;
+ H264SwDecPicture decPicture;
+ H264SwDecInfo decInfo;
+ FILE *foutput;
+ char outFileName[256];
+ u8 *byteStrmStart;
+ u32 picNumber;
+} Decoder;
+
+
+/*------------------------------------------------------------------------------
+
+------------------------------------------------------------------------------*/
+int main(int argc, char **argv)
+{
+
+ i32 instCount, instRunning;
+ i32 i;
+ u32 maxNumPics;
+ u32 strmLen;
+ H264SwDecRet ret;
+ u32 numErrors = 0;
+ u32 cropDisplay = 0;
+ u32 disableOutputReordering = 0;
+ FILE *finput;
+ Decoder **decoder;
+ char outFileName[256] = "out.yuv";
+
+
+ if ( argc > 1 && strcmp(argv[1], "-T") == 0 )
+ {
+ fprintf(stderr, "%s\n", tagName);
+ return 0;
+ }
+
+ if (argc < 2)
+ {
+ DEBUG((
+ "Usage: %s [-Nn] [-Ooutfile] [-P] [-U] [-C] [-R] [-T] file1.264 [file2.264] .. [fileN.264]\n",
+ argv[0]));
+ DEBUG(("\t-Nn forces decoding to stop after n pictures\n"));
+#if defined(_NO_OUT)
+ DEBUG(("\t-Ooutfile output writing disabled at compile time\n"));
+#else
+ DEBUG(("\t-Ooutfile write output to \"outfile\" (default out.yuv)\n"));
+ DEBUG(("\t-Onone does not write output\n"));
+#endif
+ DEBUG(("\t-C display cropped image (default decoded image)\n"));
+ DEBUG(("\t-R disable DPB output reordering\n"));
+ DEBUG(("\t-T to print tag name and exit\n"));
+ exit(100);
+ }
+
+ instCount = argc - 1;
+
+ /* read command line arguments */
+ maxNumPics = 0;
+ for (i = 1; i < (argc-1); i++)
+ {
+ if ( strncmp(argv[i], "-N", 2) == 0 )
+ {
+ maxNumPics = (u32)atoi(argv[i]+2);
+ instCount--;
+ }
+ else if ( strncmp(argv[i], "-O", 2) == 0 )
+ {
+ strcpy(outFileName, argv[i]+2);
+ instCount--;
+ }
+ else if ( strcmp(argv[i], "-C") == 0 )
+ {
+ cropDisplay = 1;
+ instCount--;
+ }
+ else if ( strcmp(argv[i], "-R") == 0 )
+ {
+ disableOutputReordering = 1;
+ instCount--;
+ }
+ }
+
+ if (instCount < 1)
+ {
+ DEBUG(("No input files\n"));
+ exit(100);
+ }
+
+ /* allocate memory for multiple decoder instances
+ * one instance for every stream file */
+ decoder = (Decoder **)malloc(sizeof(Decoder*)*(u32)instCount);
+ if (decoder == NULL)
+ {
+ DEBUG(("Unable to allocate memory\n"));
+ exit(100);
+ }
+
+ /* prepare each decoder instance */
+ for (i = 0; i < instCount; i++)
+ {
+ decoder[i] = (Decoder *)calloc(1, sizeof(Decoder));
+
+ /* open input file */
+ finput = fopen(argv[argc-instCount+i],"rb");
+ if (finput == NULL)
+ {
+ DEBUG(("Unable to open input file <%s>\n", argv[argc-instCount+i]));
+ exit(100);
+ }
+
+ DEBUG(("Reading input file[%d] %s\n", i, argv[argc-instCount+i]));
+
+ /* read input stream to buffer */
+ fseek(finput,0L,SEEK_END);
+ strmLen = (u32)ftell(finput);
+ rewind(finput);
+ decoder[i]->byteStrmStart = (u8 *)malloc(sizeof(u8)*strmLen);
+ if (decoder[i]->byteStrmStart == NULL)
+ {
+ DEBUG(("Unable to allocate memory\n"));
+ exit(100);
+ }
+ fread(decoder[i]->byteStrmStart, sizeof(u8), strmLen, finput);
+ fclose(finput);
+
+ /* open output file */
+ if (strcmp(outFileName, "none") != 0)
+ {
+#if defined(_NO_OUT)
+ decoder[i]->foutput = NULL;
+#else
+ sprintf(decoder[i]->outFileName, "%s%i", outFileName, i);
+ decoder[i]->foutput = fopen(decoder[i]->outFileName, "wb");
+ if (decoder[i]->foutput == NULL)
+ {
+ DEBUG(("Unable to open output file\n"));
+ exit(100);
+ }
+#endif
+ }
+
+ ret = H264SwDecInit(&(decoder[i]->decInst), disableOutputReordering);
+
+ if (ret != H264SWDEC_OK)
+ {
+ DEBUG(("Init failed %d\n", ret));
+ exit(100);
+ }
+
+ decoder[i]->decInput.pStream = decoder[i]->byteStrmStart;
+ decoder[i]->decInput.dataLen = strmLen;
+ decoder[i]->decInput.intraConcealmentMethod = 0;
+
+ }
+
+ /* main decoding loop */
+ do
+ {
+ /* decode once using each instance */
+ for (i = 0; i < instCount; i++)
+ {
+ ret = H264SwDecDecode(decoder[i]->decInst,
+ &(decoder[i]->decInput),
+ &(decoder[i]->decOutput));
+
+ switch(ret)
+ {
+
+ case H264SWDEC_HDRS_RDY_BUFF_NOT_EMPTY:
+
+ ret = H264SwDecGetInfo(decoder[i]->decInst,
+ &(decoder[i]->decInfo));
+ if (ret != H264SWDEC_OK)
+ exit(1);
+
+ if (cropDisplay && decoder[i]->decInfo.croppingFlag)
+ {
+ DEBUG(("Decoder[%d] Cropping params: (%d, %d) %dx%d\n",
+ i,
+ decoder[i]->decInfo.cropParams.cropLeftOffset,
+ decoder[i]->decInfo.cropParams.cropTopOffset,
+ decoder[i]->decInfo.cropParams.cropOutWidth,
+ decoder[i]->decInfo.cropParams.cropOutHeight));
+ }
+
+ DEBUG(("Decoder[%d] Width %d Height %d\n", i,
+ decoder[i]->decInfo.picWidth,
+ decoder[i]->decInfo.picHeight));
+
+ DEBUG(("Decoder[%d] videoRange %d, matricCoefficients %d\n",
+ i, decoder[i]->decInfo.videoRange,
+ decoder[i]->decInfo.matrixCoefficients));
+ decoder[i]->decInput.dataLen -=
+ (u32)(decoder[i]->decOutput.pStrmCurrPos -
+ decoder[i]->decInput.pStream);
+ decoder[i]->decInput.pStream =
+ decoder[i]->decOutput.pStrmCurrPos;
+ break;
+
+ case H264SWDEC_PIC_RDY_BUFF_NOT_EMPTY:
+ decoder[i]->decInput.dataLen -=
+ (u32)(decoder[i]->decOutput.pStrmCurrPos -
+ decoder[i]->decInput.pStream);
+ decoder[i]->decInput.pStream =
+ decoder[i]->decOutput.pStrmCurrPos;
+ /* fall through */
+ case H264SWDEC_PIC_RDY:
+ if (ret == H264SWDEC_PIC_RDY)
+ decoder[i]->decInput.dataLen = 0;
+
+ ret = H264SwDecGetInfo(decoder[i]->decInst,
+ &(decoder[i]->decInfo));
+ if (ret != H264SWDEC_OK)
+ exit(1);
+
+ while (H264SwDecNextPicture(decoder[i]->decInst,
+ &(decoder[i]->decPicture), 0) == H264SWDEC_PIC_RDY)
+ {
+ decoder[i]->picNumber++;
+
+ numErrors += decoder[i]->decPicture.nbrOfErrMBs;
+
+ DEBUG(("Decoder[%d] PIC %d, type %s, concealed %d\n",
+ i, decoder[i]->picNumber,
+ decoder[i]->decPicture.isIdrPicture
+ ? "IDR" : "NON-IDR",
+ decoder[i]->decPicture.nbrOfErrMBs));
+ fflush(stdout);
+
+ CropWriteOutput(decoder[i]->foutput,
+ (u8*)decoder[i]->decPicture.pOutputPicture,
+ cropDisplay, &(decoder[i]->decInfo));
+ }
+
+ if (maxNumPics && decoder[i]->picNumber == maxNumPics)
+ decoder[i]->decInput.dataLen = 0;
+ break;
+
+ case H264SWDEC_STRM_PROCESSED:
+ case H264SWDEC_STRM_ERR:
+ case H264SWDEC_PARAM_ERR:
+ decoder[i]->decInput.dataLen = 0;
+ break;
+
+ default:
+ DEBUG(("Decoder[%d] FATAL ERROR\n", i));
+ exit(10);
+ break;
+
+ }
+ }
+
+ /* check if any of the instances is still running (=has more data) */
+ instRunning = instCount;
+ for (i = 0; i < instCount; i++)
+ {
+ if (decoder[i]->decInput.dataLen == 0)
+ instRunning--;
+ }
+
+ } while (instRunning);
+
+
+ /* get last frames and close each instance */
+ for (i = 0; i < instCount; i++)
+ {
+ while (H264SwDecNextPicture(decoder[i]->decInst,
+ &(decoder[i]->decPicture), 1) == H264SWDEC_PIC_RDY)
+ {
+ decoder[i]->picNumber++;
+
+ DEBUG(("Decoder[%d] PIC %d, type %s, concealed %d\n",
+ i, decoder[i]->picNumber,
+ decoder[i]->decPicture.isIdrPicture
+ ? "IDR" : "NON-IDR",
+ decoder[i]->decPicture.nbrOfErrMBs));
+ fflush(stdout);
+
+ CropWriteOutput(decoder[i]->foutput,
+ (u8*)decoder[i]->decPicture.pOutputPicture,
+ cropDisplay, &(decoder[i]->decInfo));
+ }
+
+ H264SwDecRelease(decoder[i]->decInst);
+
+ if (decoder[i]->foutput)
+ fclose(decoder[i]->foutput);
+
+ free(decoder[i]->byteStrmStart);
+
+ free(decoder[i]);
+ }
+
+ free(decoder);
+
+ if (numErrors)
+ return 1;
+ else
+ return 0;
+
+}
+
+/*------------------------------------------------------------------------------
+
+------------------------------------------------------------------------------*/
+void CropWriteOutput(FILE *foutput, u8 *imageData, u32 cropDisplay,
+ H264SwDecInfo *decInfo)
+{
+ u8 *tmpImage = NULL;
+ u32 tmp, picSize;
+
+ if (cropDisplay && decInfo->croppingFlag)
+ {
+ picSize = decInfo->cropParams.cropOutWidth *
+ decInfo->cropParams.cropOutHeight;
+ picSize = (3 * picSize)/2;
+ tmpImage = malloc(picSize);
+ if (tmpImage == NULL)
+ exit(1);
+ tmp = CropPicture(tmpImage, imageData,
+ decInfo->picWidth, decInfo->picHeight,
+ &(decInfo->cropParams));
+ if (tmp)
+ exit(1);
+ WriteOutput(foutput, tmpImage, picSize);
+ free(tmpImage);
+ }
+ else
+ {
+ picSize = decInfo->picWidth * decInfo->picHeight;
+ picSize = (3 * picSize)/2;
+ WriteOutput(foutput, imageData, picSize);
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+------------------------------------------------------------------------------*/
+void WriteOutput(FILE *fid, u8 *data, u32 picSize)
+{
+ if (fid)
+ fwrite(data, 1, picSize, fid);
+}
+
+/*------------------------------------------------------------------------------
+
+ Function name: H264SwDecTrace
+
+------------------------------------------------------------------------------*/
+void H264SwDecTrace(char *string)
+{
+ FILE *fp;
+
+ fp = fopen("dec_api.trc", "at");
+
+ if (!fp)
+ return;
+
+ fwrite(string, 1, strlen(string), fp);
+ fwrite("\n", 1,1, fp);
+
+ fclose(fp);
+}
+
+/*------------------------------------------------------------------------------
+
+ Function name: H264SwDecmalloc
+
+------------------------------------------------------------------------------*/
+void* H264SwDecMalloc(u32 size)
+{
+ return malloc(size);
+}
+
+/*------------------------------------------------------------------------------
+
+ Function name: H264SwDecFree
+
+------------------------------------------------------------------------------*/
+void H264SwDecFree(void *ptr)
+{
+ free(ptr);
+}
+
+/*------------------------------------------------------------------------------
+
+ Function name: H264SwDecMemcpy
+
+------------------------------------------------------------------------------*/
+void H264SwDecMemcpy(void *dest, void *src, u32 count)
+{
+ memcpy(dest, src, count);
+}
+
+/*------------------------------------------------------------------------------
+
+ Function name: H264SwDecMemset
+
+------------------------------------------------------------------------------*/
+void H264SwDecMemset(void *ptr, i32 value, u32 count)
+{
+ memset(ptr, value, count);
+}
+
+/*------------------------------------------------------------------------------
+
+ Function name: CropPicture
+
+------------------------------------------------------------------------------*/
+u32 CropPicture(u8 *pOutImage, u8 *pInImage,
+ u32 picWidth, u32 picHeight, CropParams *pCropParams)
+{
+
+ u32 i, j;
+ u32 outWidth, outHeight;
+ u8 *pOut, *pIn;
+
+ if (pOutImage == NULL || pInImage == NULL || pCropParams == NULL ||
+ !picWidth || !picHeight)
+ {
+ /* due to lint warning */
+ free(pOutImage);
+ return(1);
+ }
+
+ if ( ((pCropParams->cropLeftOffset + pCropParams->cropOutWidth) >
+ picWidth ) ||
+ ((pCropParams->cropTopOffset + pCropParams->cropOutHeight) >
+ picHeight ) )
+ {
+ /* due to lint warning */
+ free(pOutImage);
+ return(1);
+ }
+
+ outWidth = pCropParams->cropOutWidth;
+ outHeight = pCropParams->cropOutHeight;
+
+ pIn = pInImage + pCropParams->cropTopOffset*picWidth +
+ pCropParams->cropLeftOffset;
+ pOut = pOutImage;
+
+ /* luma */
+ for (i = outHeight; i; i--)
+ {
+ for (j = outWidth; j; j--)
+ {
+ *pOut++ = *pIn++;
+ }
+ pIn += picWidth - outWidth;
+ }
+
+ outWidth >>= 1;
+ outHeight >>= 1;
+
+ pIn = pInImage + picWidth*picHeight +
+ pCropParams->cropTopOffset*picWidth/4 + pCropParams->cropLeftOffset/2;
+
+ /* cb */
+ for (i = outHeight; i; i--)
+ {
+ for (j = outWidth; j; j--)
+ {
+ *pOut++ = *pIn++;
+ }
+ pIn += picWidth/2 - outWidth;
+ }
+
+ pIn = pInImage + 5*picWidth*picHeight/4 +
+ pCropParams->cropTopOffset*picWidth/4 + pCropParams->cropLeftOffset/2;
+
+ /* cr */
+ for (i = outHeight; i; i--)
+ {
+ for (j = outWidth; j; j--)
+ {
+ *pOut++ = *pIn++;
+ }
+ pIn += picWidth/2 - outWidth;
+ }
+
+ return (0);
+
+}
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/arm11_asm/h264bsd_interpolate_chroma_hor.s b/media/libstagefright/codecs/on2/h264dec/source/arm11_asm/h264bsd_interpolate_chroma_hor.s
new file mode 100755
index 0000000..634a484
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/arm11_asm/h264bsd_interpolate_chroma_hor.s
@@ -0,0 +1,298 @@
+; 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.
+
+;-------------------------------------------------------------------------------
+;--
+;-- Abstract : ARMv6 optimized version of h264bsdInterpolateChromaHor function
+;--
+;-------------------------------------------------------------------------------
+
+
+ IF :DEF: H264DEC_WINASM
+ ;// We dont use REQUIRE8 and PRESERVE8 for winasm
+ ELSE
+ REQUIRE8
+ PRESERVE8
+ ENDIF
+
+ AREA |.text|, CODE
+
+
+;// h264bsdInterpolateChromaHor register allocation
+
+ref RN 0
+ptrA RN 0
+
+mb RN 1
+block RN 1
+
+x0 RN 2
+count RN 2
+
+y0 RN 3
+valX RN 3
+
+width RN 4
+
+height RN 5
+tmp7 RN 5
+
+chrPW RN 6
+tmp8 RN 6
+
+tmp1 RN 7
+chrPH RN 7
+
+tmp2 RN 8
+
+tmp3 RN 9
+
+tmp4 RN 10
+
+tmp5 RN 11
+
+tmp6 RN 12
+
+c32 RN 14
+xFrac RN 14
+
+;// Function exports and imports
+
+ IMPORT h264bsdFillBlock
+
+ EXPORT h264bsdInterpolateChromaHor
+
+;// Function arguments
+;//
+;// u8 *ref, : 0xc4
+;// u8 *predPartChroma, : 0xc8
+;// i32 x0, : 0xcc
+;// i32 y0, : 0xd0
+;// u32 width, : 0xf8
+;// u32 height, : 0xfc
+;// u32 xFrac, : 0x100
+;// u32 chromaPartWidth, : 0x104
+;// u32 chromaPartHeight : 0x108
+
+h264bsdInterpolateChromaHor
+ STMFD sp!, {r0-r11,lr}
+ SUB sp, sp, #0xc4
+
+ LDR chrPW, [sp, #0x104] ;// chromaPartWidth
+ LDR width, [sp, #0xf8] ;// width
+ CMP x0, #0
+ BLT do_fill
+
+ ADD tmp6, x0, chrPW ;// tmp6 = x0+ chromaPartWidth
+ ADD tmp6, tmp6, #1 ;// tmp6 = x0 + chromaPartWidth + 1
+ CMP tmp6, width ;// x0+chromaPartWidth+1 > width
+ BHI do_fill
+
+ CMP y0, #0
+ BLT do_fill
+ LDR chrPH, [sp, #0x108] ;// chromaPartHeight
+ LDR height, [sp, #0xfc] ;// height
+ ADD tmp6, y0, chrPH ;// tmp6 = y0 + chromaPartHeight
+ CMP tmp6, height
+ BLS skip_fill
+
+do_fill
+ LDR chrPH, [sp, #0x108] ;// chromaPartHeight
+ LDR height, [sp, #0xfc] ;// height
+ ADD tmp8, chrPW, #1 ;// tmp8 = chromaPartWidth+1
+ MOV tmp2, tmp8 ;// tmp2 = chromaPartWidth+1
+ STMIA sp,{width,height,tmp8,chrPH,tmp2}
+ ADD block, sp, #0x1c ;// block
+ BL h264bsdFillBlock
+
+ LDR x0, [sp, #0xcc]
+ LDR y0, [sp, #0xd0]
+ LDR ref, [sp, #0xc4] ;// ref
+ STMIA sp,{width,height,tmp8,chrPH,tmp2}
+ ADD block, sp, #0x1c ;// block
+ MLA ref, height, width, ref ;// ref += width * height;
+ MLA block, chrPH, tmp8, block;// block + (chromaPH)*(chromaPW+1)
+ BL h264bsdFillBlock
+
+ MOV x0, #0 ;// x0 = 0
+ MOV y0, #0 ;// y0 = 0
+ STR x0, [sp, #0xcc]
+ STR y0, [sp, #0xd0]
+ ADD ref, sp, #0x1c ;// ref = block
+ STR ref, [sp, #0xc4] ;// ref
+
+ STR chrPH, [sp, #0xfc] ;// height
+ STR tmp8, [sp, #0xf8] ;// width
+ MOV width, tmp8
+ SUB chrPW, chrPW, #1
+
+skip_fill
+ MLA tmp3, y0, width, x0 ;// tmp3 = y0*width+x0
+ LDR xFrac, [sp, #0x100] ;// xFrac
+ ADD ptrA, ref, tmp3 ;// ptrA = ref + y0*width+x0
+ RSB valX, xFrac, #8 ;// valX = 8-xFrac
+
+ LDR mb, [sp, #0xc8] ;// predPartChroma
+
+
+ ;// pack values to count register
+ ;// [31:28] loop_x (chromaPartWidth-1)
+ ;// [27:24] loop_y (chromaPartHeight-1)
+ ;// [23:20] chromaPartWidth-1
+ ;// [19:16] chromaPartHeight-1
+ ;// [15:00] nothing
+
+ SUB tmp2, chrPH, #1 ;// chromaPartHeight-1
+ SUB tmp1, chrPW, #1 ;// chromaPartWidth-1
+ ADD count, count, tmp2, LSL #16 ;// chromaPartHeight-1
+ ADD count, count, tmp2, LSL #24 ;// loop_y
+ ADD count, count, tmp1, LSL #20 ;// chromaPartWidth-1
+ AND tmp2, count, #0x00F00000 ;// loop_x
+ PKHBT valX, valX, xFrac, LSL #16 ;// |xFrac|valX |
+ MOV valX, valX, LSL #3 ;// multiply by 8 in advance
+ MOV c32, #32
+
+
+ ;///////////////////////////////////////////////////////////////////////////
+ ;// Cb
+ ;///////////////////////////////////////////////////////////////////////////
+
+ ;// 2x2 pels per iteration
+ ;// bilinear vertical interpolation
+
+loop1_y
+ ADD count, count, tmp2, LSL #8
+ LDRB tmp1, [ptrA, width]
+ LDRB tmp2, [ptrA], #1
+
+loop1_x
+ LDRB tmp3, [ptrA, width]
+ LDRB tmp4, [ptrA], #1
+
+ PKHBT tmp5, tmp1, tmp3, LSL #16
+ PKHBT tmp6, tmp2, tmp4, LSL #16
+
+ LDRB tmp1, [ptrA, width]
+ LDRB tmp2, [ptrA], #1
+
+ SMLAD tmp5, tmp5, valX, c32 ;// multiply
+ SMLAD tmp6, tmp6, valX, c32 ;// multiply
+
+ PKHBT tmp7, tmp3, tmp1, LSL #16
+ PKHBT tmp8, tmp4, tmp2, LSL #16
+
+ SMLAD tmp7, tmp7, valX, c32 ;// multiply
+ SMLAD tmp8, tmp8, valX, c32 ;// multiply
+
+ MOV tmp5, tmp5, LSR #6 ;// scale down
+ STRB tmp5, [mb,#8] ;// store row 2 col 1
+
+ MOV tmp6, tmp6, LSR #6 ;// scale down
+ STRB tmp6, [mb],#1 ;// store row 1 col 1
+
+ MOV tmp7, tmp7, LSR #6 ;// scale down
+ STRB tmp7, [mb,#8] ;// store row 2 col 2
+
+ MOV tmp8, tmp8, LSR #6 ;// scale down
+ STRB tmp8, [mb],#1 ;// store row 1 col 2
+
+ SUBS count, count, #2<<28
+ BCS loop1_x
+
+ AND tmp2, count, #0x00F00000
+
+ ADDS mb, mb, #16
+ SBC mb, mb, tmp2, LSR #20
+ ADD ptrA, ptrA, width, LSL #1
+ SBC ptrA, ptrA, tmp2, LSR #20
+ SUB ptrA, ptrA, #1
+
+ ADDS count, count, #0xE << 24
+ BGE loop1_y
+
+ ;///////////////////////////////////////////////////////////////////////////
+ ;// Cr
+ ;///////////////////////////////////////////////////////////////////////////
+ LDR height, [sp,#0xfc] ;// height
+ LDR ref, [sp, #0xc4] ;// ref
+ LDR tmp1, [sp, #0xd0] ;// y0
+ LDR tmp2, [sp, #0xcc] ;// x0
+ LDR mb, [sp, #0xc8] ;// predPartChroma
+
+ ADD tmp1, height, tmp1
+ MLA tmp3, tmp1, width, tmp2
+ ADD ptrA, ref, tmp3
+ ADD mb, mb, #64
+
+ AND count, count, #0x00FFFFFF
+ AND tmp1, count, #0x000F0000
+ ADD count, count, tmp1, LSL #8
+ AND tmp2, count, #0x00F00000
+
+ ;// 2x2 pels per iteration
+ ;// bilinear vertical interpolation
+loop2_y
+ ADD count, count, tmp2, LSL #8
+ LDRB tmp1, [ptrA, width]
+ LDRB tmp2, [ptrA], #1
+
+loop2_x
+ LDRB tmp3, [ptrA, width]
+ LDRB tmp4, [ptrA], #1
+
+ PKHBT tmp5, tmp1, tmp3, LSL #16
+ PKHBT tmp6, tmp2, tmp4, LSL #16
+
+ LDRB tmp1, [ptrA, width]
+ LDRB tmp2, [ptrA], #1
+
+ SMLAD tmp5, tmp5, valX, c32 ;// multiply
+ SMLAD tmp6, tmp6, valX, c32 ;// multiply
+
+ PKHBT tmp7, tmp3, tmp1, LSL #16
+ PKHBT tmp8, tmp4, tmp2, LSL #16
+
+ SMLAD tmp7, tmp7, valX, c32 ;// multiply
+ SMLAD tmp8, tmp8, valX, c32 ;// multiply
+
+ MOV tmp5, tmp5, LSR #6 ;// scale down
+ STRB tmp5, [mb,#8] ;// store row 2 col 1
+
+ MOV tmp6, tmp6, LSR #6 ;// scale down
+ STRB tmp6, [mb],#1 ;// store row 1 col 1
+
+ MOV tmp7, tmp7, LSR #6 ;// scale down
+ STRB tmp7, [mb,#8] ;// store row 2 col 2
+
+ MOV tmp8, tmp8, LSR #6 ;// scale down
+ STRB tmp8, [mb],#1 ;// store row 1 col 2
+
+ SUBS count, count, #2<<28
+ BCS loop2_x
+
+ AND tmp2, count, #0x00F00000
+
+ ADDS mb, mb, #16
+ SBC mb, mb, tmp2, LSR #20
+ ADD ptrA, ptrA, width, LSL #1
+ SBC ptrA, ptrA, tmp2, LSR #20
+ SUB ptrA, ptrA, #1
+
+ ADDS count, count, #0xE << 24
+ BGE loop2_y
+
+ ADD sp,sp,#0xd4
+ LDMFD sp!, {r4-r11,pc}
+
+ END
diff --git a/media/libstagefright/codecs/on2/h264dec/source/arm11_asm/h264bsd_interpolate_chroma_hor_ver.s b/media/libstagefright/codecs/on2/h264dec/source/arm11_asm/h264bsd_interpolate_chroma_hor_ver.s
new file mode 100755
index 0000000..7420ad3
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/arm11_asm/h264bsd_interpolate_chroma_hor_ver.s
@@ -0,0 +1,339 @@
+; 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.
+
+;-------------------------------------------------------------------------------
+;--
+;-- Abstract : ARMv6 optimized version of h264bsdInterpolateChromaHorVer
+;-- function
+;--
+;-------------------------------------------------------------------------------
+
+
+ IF :DEF: H264DEC_WINASM
+ ;// We dont use REQUIRE8 and PRESERVE8 for winasm
+ ELSE
+ REQUIRE8
+ PRESERVE8
+ ENDIF
+
+ AREA |.text|, CODE
+
+
+;// h264bsdInterpolateChromaHorVer register allocation
+
+ref RN 0
+ptrA RN 0
+
+mb RN 1
+block RN 1
+
+x0 RN 2
+count RN 2
+
+y0 RN 3
+valY RN 3
+
+width RN 4
+
+tmp4 RN 5
+height RN 5
+
+tmp1 RN 6
+
+tmp2 RN 7
+
+tmp3 RN 8
+
+valX RN 9
+
+tmp5 RN 10
+chrPW RN 10
+
+tmp6 RN 11
+chrPH RN 11
+
+xFrac RN 12
+
+c32 RN 14
+yFrac RN 14
+
+;// function exports and imports
+
+ IMPORT h264bsdFillBlock
+
+ EXPORT h264bsdInterpolateChromaHorVer
+
+;// Function arguments
+;//
+;// u8 *ref, : 0xc4
+;// u8 *predPartChroma, : 0xc8
+;// i32 x0, : 0xcc
+;// i32 y0, : 0xd0
+;// u32 width, : 0xf8
+;// u32 height, : 0xfc
+;// u32 xFrac, : 0x100
+;// u32 yFrac, : 0x104
+;// u32 chromaPartWidth, : 0x108
+;// u32 chromaPartHeight : 0x10c
+
+h264bsdInterpolateChromaHorVer
+ STMFD sp!, {r0-r11,lr}
+ SUB sp, sp, #0xc4
+
+ LDR chrPW, [sp, #0x108] ;// chromaPartWidth
+ LDR xFrac, [sp, #0x100] ;// xFrac
+ LDR width, [sp, #0xf8] ;// width
+ CMP x0, #0
+ BLT do_fill
+
+ ADD tmp1, x0, chrPW ;// tmp1 = x0+ chromaPartWidth
+ ADD tmp1, tmp1, #1 ;// tmp1 = x0+ chromaPartWidth+1
+ CMP tmp1, width ;// x0+chromaPartWidth+1 > width
+ BHI do_fill
+
+ CMP y0, #0
+ BLT do_fill
+ LDR chrPH, [sp, #0x10c] ;// chromaPartHeight
+ LDR height, [sp, #0xfc] ;// height
+ ADD tmp1, y0, chrPH ;// tmp1 = y0 + chromaPartHeight
+ ADD tmp1, tmp1, #1 ;// tmp1 = y0 + chromaPartHeight + 1
+ CMP tmp1, height
+ BLS skip_fill
+
+do_fill
+ LDR chrPH, [sp, #0x10c] ;// chromaPartHeight
+ LDR height, [sp, #0xfc] ;// height
+ ADD tmp3, chrPW, #1 ;// tmp3 = chromaPartWidth+1
+ ADD tmp1, chrPW, #1 ;// tmp1 = chromaPartWidth+1
+ ADD tmp2, chrPH, #1 ;// tmp2 = chromaPartHeight+1
+ STMIA sp,{width,height,tmp1,tmp2,tmp3}
+ ADD block, sp, #0x1c ;// block
+ BL h264bsdFillBlock
+
+ LDR x0, [sp, #0xcc]
+ LDR y0, [sp, #0xd0]
+ LDR ref, [sp, #0xc4] ;// ref
+ STMIA sp,{width,height,tmp1,tmp2,tmp3}
+ ADD block, sp, #0x1c ;// block
+ MLA ref, height, width, ref ;// ref += width * height;
+ MLA block, tmp2, tmp1, block;// block + (chromaPW+1)*(chromaPH+1)
+ BL h264bsdFillBlock
+
+ MOV x0, #0 ;// x0 = 0
+ MOV y0, #0 ;// y0 = 0
+ STR x0, [sp, #0xcc]
+ STR y0, [sp, #0xd0]
+ ADD ref, sp, #0x1c ;// ref = block
+ STR ref, [sp, #0xc4] ;// ref
+
+ STR tmp2, [sp, #0xfc] ;// height
+ STR tmp1, [sp, #0xf8] ;// width
+ MOV width, tmp1
+
+skip_fill
+ MLA tmp3, y0, width, x0 ;// tmp3 = y0*width+x0
+ LDR yFrac, [sp, #0x104] ;// yFrac
+ LDR xFrac, [sp, #0x100]
+ ADD ptrA, ref, tmp3 ;// ptrA = ref + y0*width+x0
+ RSB valX, xFrac, #8 ;// valX = 8-xFrac
+ RSB valY, yFrac, #8 ;// valY = 8-yFrac
+
+ LDR mb, [sp, #0xc8] ;// predPartChroma
+
+
+ ;// pack values to count register
+ ;// [31:28] loop_x (chromaPartWidth-1)
+ ;// [27:24] loop_y (chromaPartHeight-1)
+ ;// [23:20] chromaPartWidth-1
+ ;// [19:16] chromaPartHeight-1
+ ;// [15:00] nothing
+
+ SUB tmp2, chrPH, #1 ;// chromaPartHeight-1
+ SUB tmp1, chrPW, #1 ;// chromaPartWidth-1
+ ADD count, count, tmp2, LSL #16 ;// chromaPartHeight-1
+ ADD count, count, tmp2, LSL #24 ;// loop_y
+ ADD count, count, tmp1, LSL #20 ;// chromaPartWidth-1
+ AND tmp2, count, #0x00F00000 ;// loop_x
+ PKHBT valY, valY, yFrac, LSL #16 ;// |yFrac|valY |
+ MOV c32, #32
+
+
+ ;///////////////////////////////////////////////////////////////////////////
+ ;// Cb
+ ;///////////////////////////////////////////////////////////////////////////
+
+ ;// 2x2 pels per iteration
+ ;// bilinear vertical and horizontal interpolation
+
+loop1_y
+ LDRB tmp1, [ptrA]
+ LDRB tmp3, [ptrA, width]
+ LDRB tmp5, [ptrA, width, LSL #1]
+
+ PKHBT tmp1, tmp1, tmp3, LSL #16 ;// |t3|t1|
+ PKHBT tmp3, tmp3, tmp5, LSL #16 ;// |t5|t3|
+
+ SMUAD tmp1, tmp1, valY ;// t1=(t1*valY + t3*yFrac)
+ SMUAD tmp3, tmp3, valY ;// t3=(t3*valY + t5*yFrac)
+
+ ADD count, count, tmp2, LSL #8
+loop1_x
+ ;// first
+ LDRB tmp2, [ptrA, #1]!
+ LDRB tmp4, [ptrA, width]
+ LDRB tmp6, [ptrA, width, LSL #1]
+
+ PKHBT tmp2, tmp2, tmp4, LSL #16 ;// |t4|t2|
+ PKHBT tmp4, tmp4, tmp6, LSL #16 ;// |t6|t4|
+
+ SMUAD tmp2, tmp2, valY ;// t2=(t2*valY + t4*yFrac)
+ MLA tmp5, tmp1, valX, c32 ;// t5=t1*valX+32
+ MLA tmp5, tmp2, xFrac, tmp5 ;// t5=t2*xFrac+t5
+
+ SMUAD tmp4, tmp4, valY ;// t4=(t4*valY + t6*yFrac)
+ MLA tmp6, tmp3, valX, c32 ;// t3=t3*valX+32
+ MLA tmp6, tmp4, xFrac, tmp6 ;// t6=t4*xFrac+t6
+
+ MOV tmp6, tmp6, LSR #6 ;// scale down
+ STRB tmp6, [mb, #8] ;// store pixel
+ MOV tmp5, tmp5, LSR #6 ;// scale down
+ STRB tmp5, [mb], #1 ;// store pixel
+
+ ;// second
+ LDRB tmp1, [ptrA, #1]!
+ LDRB tmp3, [ptrA, width]
+ LDRB tmp5, [ptrA, width, LSL #1]
+
+ PKHBT tmp1, tmp1, tmp3, LSL #16 ;// |t3|t1|
+ PKHBT tmp3, tmp3, tmp5, LSL #16 ;// |t5|t3|
+
+ SMUAD tmp1, tmp1, valY ;// t1=(t1*valY + t3*yFrac)
+ MLA tmp5, tmp1, xFrac, c32 ;// t1=t1*xFrac+32
+ MLA tmp5, tmp2, valX, tmp5 ;// t5=t2*valX+t5
+
+ SMUAD tmp3, tmp3, valY ;// t3=(t3*valY + t5*yFrac)
+ MLA tmp6, tmp3, xFrac, c32 ;// t3=t3*xFrac+32
+ MLA tmp6, tmp4, valX, tmp6 ;// t6=t4*valX+t6
+
+ MOV tmp6, tmp6, LSR #6 ;// scale down
+ STRB tmp6, [mb, #8] ;// store pixel
+ MOV tmp5, tmp5, LSR #6 ;// scale down
+ STRB tmp5, [mb], #1 ;// store pixel
+
+ SUBS count, count, #2<<28
+ BCS loop1_x
+
+ AND tmp2, count, #0x00F00000
+
+ ADDS mb, mb, #16
+ SBC mb, mb, tmp2, LSR #20
+ ADD ptrA, ptrA, width, LSL #1
+ SBC ptrA, ptrA, tmp2, LSR #20
+
+ ADDS count, count, #0xE << 24
+ BGE loop1_y
+
+ ;///////////////////////////////////////////////////////////////////////////
+ ;// Cr
+ ;///////////////////////////////////////////////////////////////////////////
+ LDR height, [sp,#0xfc] ;// height
+ LDR ref, [sp, #0xc4] ;// ref
+ LDR tmp1, [sp, #0xd0] ;// y0
+ LDR tmp2, [sp, #0xcc] ;// x0
+ LDR mb, [sp, #0xc8] ;// predPartChroma
+
+ ADD tmp1, height, tmp1
+ MLA tmp3, tmp1, width, tmp2
+ ADD ptrA, ref, tmp3
+ ADD mb, mb, #64
+
+ AND count, count, #0x00FFFFFF
+ AND tmp1, count, #0x000F0000
+ ADD count, count, tmp1, LSL #8
+ AND tmp2, count, #0x00F00000
+
+ ;// 2x2 pels per iteration
+ ;// bilinear vertical and horizontal interpolation
+loop2_y
+ LDRB tmp1, [ptrA]
+ LDRB tmp3, [ptrA, width]
+ LDRB tmp5, [ptrA, width, LSL #1]
+
+ PKHBT tmp1, tmp1, tmp3, LSL #16 ;// |t3|t1|
+ PKHBT tmp3, tmp3, tmp5, LSL #16 ;// |t5|t3|
+
+ SMUAD tmp1, tmp1, valY ;// t1=(t1*valY + t3*yFrac)
+ SMUAD tmp3, tmp3, valY ;// t3=(t3*valY + t5*yFrac)
+
+ ADD count, count, tmp2, LSL #8
+loop2_x
+ ;// first
+ LDRB tmp2, [ptrA, #1]!
+ LDRB tmp4, [ptrA, width]
+ LDRB tmp6, [ptrA, width, LSL #1]
+
+ PKHBT tmp2, tmp2, tmp4, LSL #16 ;// |t4|t2|
+ PKHBT tmp4, tmp4, tmp6, LSL #16 ;// |t6|t4|
+
+ SMUAD tmp2, tmp2, valY ;// t2=(t2*valY + t4*yFrac)
+ MLA tmp5, tmp1, valX, c32 ;// t5=t1*valX+32
+ MLA tmp5, tmp2, xFrac, tmp5 ;// t5=t2*xFrac+t5
+
+ SMUAD tmp4, tmp4, valY ;// t4=(t4*valY + t6*yFrac)
+ MLA tmp6, tmp3, valX, c32 ;// t3=t3*valX+32
+ MLA tmp6, tmp4, xFrac, tmp6 ;// t6=t4*xFrac+t6
+
+ MOV tmp6, tmp6, LSR #6 ;// scale down
+ STRB tmp6, [mb, #8] ;// store pixel
+ MOV tmp5, tmp5, LSR #6 ;// scale down
+ STRB tmp5, [mb], #1 ;// store pixel
+
+ ;// second
+ LDRB tmp1, [ptrA, #1]!
+ LDRB tmp3, [ptrA, width]
+ LDRB tmp5, [ptrA, width, LSL #1]
+
+ PKHBT tmp1, tmp1, tmp3, LSL #16 ;// |t3|t1|
+ PKHBT tmp3, tmp3, tmp5, LSL #16 ;// |t5|t3|
+
+ SMUAD tmp1, tmp1, valY ;// t1=(t1*valY + t3*yFrac)
+ MLA tmp5, tmp1, xFrac, c32 ;// t1=t1*xFrac+32
+ MLA tmp5, tmp2, valX, tmp5 ;// t5=t2*valX+t5
+
+ SMUAD tmp3, tmp3, valY ;// t3=(t3*valY + t5*yFrac)
+ MLA tmp6, tmp3, xFrac, c32 ;// t3=t3*xFrac+32
+ MLA tmp6, tmp4, valX, tmp6 ;// t6=t4*valX+t6
+
+ MOV tmp6, tmp6, LSR #6 ;// scale down
+ STRB tmp6, [mb, #8] ;// store pixel
+ MOV tmp5, tmp5, LSR #6 ;// scale down
+ STRB tmp5, [mb], #1 ;// store pixel
+
+ SUBS count, count, #2<<28
+ BCS loop2_x
+
+ AND tmp2, count, #0x00F00000
+
+ ADDS mb, mb, #16
+ SBC mb, mb, tmp2, LSR #20
+ ADD ptrA, ptrA, width, LSL #1
+ SBC ptrA, ptrA, tmp2, LSR #20
+
+ ADDS count, count, #0xE << 24
+ BGE loop2_y
+
+ ADD sp,sp,#0xd4
+ LDMFD sp!,{r4-r11,pc}
+
+ END
diff --git a/media/libstagefright/codecs/on2/h264dec/source/arm11_asm/h264bsd_interpolate_chroma_ver.s b/media/libstagefright/codecs/on2/h264dec/source/arm11_asm/h264bsd_interpolate_chroma_ver.s
new file mode 100755
index 0000000..af9df1b
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/arm11_asm/h264bsd_interpolate_chroma_ver.s
@@ -0,0 +1,288 @@
+; 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.
+
+;-------------------------------------------------------------------------------
+;--
+;-- Abstract : ARMv6 optimized version of h264bsdInterpolateChromaVer function
+;--
+;-------------------------------------------------------------------------------
+
+
+ IF :DEF: H264DEC_WINASM
+ ;// We dont use REQUIRE8 and PRESERVE8 for winasm
+ ELSE
+ REQUIRE8
+ PRESERVE8
+ ENDIF
+
+ AREA |.text|, CODE
+
+;// h264bsdInterpolateChromaVer register allocation
+
+ref RN 0
+ptrA RN 0
+
+mb RN 1
+block RN 1
+
+x0 RN 2
+count RN 2
+
+y0 RN 3
+valY RN 3
+
+width RN 4
+
+height RN 5
+tmp7 RN 5
+
+chrPW RN 6
+tmp8 RN 6
+
+tmp1 RN 7
+
+tmp2 RN 8
+
+tmp3 RN 9
+
+tmp4 RN 10
+
+tmp5 RN 11
+chrPH RN 11
+
+tmp6 RN 12
+
+c32 RN 14
+yFrac RN 14
+
+;// Function exports and imports
+
+ IMPORT h264bsdFillBlock
+
+ EXPORT h264bsdInterpolateChromaVer
+
+;// Function arguments
+;//
+;// u8 *ref, : 0xc4
+;// u8 *predPartChroma, : 0xc8
+;// i32 x0, : 0xcc
+;// i32 y0, : 0xd0
+;// u32 width, : 0xf8
+;// u32 height, : 0xfc
+;// u32 yFrac, : 0x100
+;// u32 chromaPartWidth, : 0x104
+;// u32 chromaPartHeight : 0x108
+
+h264bsdInterpolateChromaVer
+ STMFD sp!, {r0-r11,lr}
+ SUB sp, sp, #0xc4
+
+ LDR chrPW, [sp, #0x104] ;// chromaPartWidth
+ LDR width, [sp, #0xf8] ;// width
+ CMP x0, #0
+ BLT do_fill
+
+ ADD tmp1, x0, chrPW ;// tmp1 = x0+ chromaPartWidth
+ CMP tmp1, width ;// x0+chromaPartWidth > width
+ BHI do_fill
+
+ CMP y0, #0
+ BLT do_fill
+ LDR chrPH, [sp, #0x108] ;// chromaPartHeight
+ LDR height, [sp, #0xfc] ;// height
+ ADD tmp1, y0, chrPH ;// tmp1 = y0 + chromaPartHeight
+ ADD tmp1, tmp1, #1 ;// tmp1 = y0 + chromaPartHeight + 1
+ CMP tmp1, height
+ BLS skip_fill
+
+do_fill
+ LDR chrPH, [sp, #0x108] ;// chromaPartHeight
+ LDR height, [sp, #0xfc] ;// height
+ ADD tmp1, chrPH, #1 ;// tmp1 = chromaPartHeight+1
+ MOV tmp2, chrPW ;// tmp2 = chromaPartWidth
+ STMIA sp,{width,height,chrPW,tmp1,tmp2}
+ ADD block, sp, #0x1c ;// block
+ BL h264bsdFillBlock
+
+ LDR x0, [sp, #0xcc]
+ LDR y0, [sp, #0xd0]
+ LDR ref, [sp, #0xc4] ;// ref
+ STMIA sp,{width,height,chrPW,tmp1,tmp2}
+ ADD block, sp, #0x1c ;// block
+ MLA ref, height, width, ref ;// ref += width * height;
+ MLA block, chrPW, tmp1, block;// block + (chromaPW)*(chromaPH+1)
+ BL h264bsdFillBlock
+
+ MOV x0, #0 ;// x0 = 0
+ MOV y0, #0 ;// y0 = 0
+ STR x0, [sp, #0xcc]
+ STR y0, [sp, #0xd0]
+ ADD ref, sp, #0x1c ;// ref = block
+ STR ref, [sp, #0xc4] ;// ref
+
+ STR tmp1, [sp, #0xfc] ;// height
+ STR chrPW, [sp, #0xf8] ;// width
+ MOV width, chrPW
+
+skip_fill
+ MLA tmp3, y0, width, x0 ;// tmp3 = y0*width+x0
+ LDR yFrac, [sp, #0x100] ;// yFrac
+ ADD ptrA, ref, tmp3 ;// ptrA = ref + y0*width+x0
+ RSB valY, yFrac, #8 ;// valY = 8-yFrac
+
+ LDR mb, [sp, #0xc8] ;// predPartChroma
+
+
+ ;// pack values to count register
+ ;// [31:28] loop_x (chromaPartWidth-1)
+ ;// [27:24] loop_y (chromaPartHeight-1)
+ ;// [23:20] chromaPartWidth-1
+ ;// [19:16] chromaPartHeight-1
+ ;// [15:00] nothing
+
+ SUB tmp2, chrPH, #1 ;// chromaPartHeight-1
+ SUB tmp1, chrPW, #1 ;// chromaPartWidth-1
+ ADD count, count, tmp2, LSL #16 ;// chromaPartHeight-1
+ ADD count, count, tmp2, LSL #24 ;// loop_y
+ ADD count, count, tmp1, LSL #20 ;// chromaPartWidth-1
+ AND tmp2, count, #0x00F00000 ;// loop_x
+ PKHBT valY, valY, yFrac, LSL #16 ;// |yFrac|valY |
+ MOV valY, valY, LSL #3 ;// multiply by 8 in advance
+ MOV c32, #32
+
+
+ ;///////////////////////////////////////////////////////////////////////////
+ ;// Cb
+ ;///////////////////////////////////////////////////////////////////////////
+
+ ;// 2x2 pels per iteration
+ ;// bilinear vertical interpolation
+
+loop1_y
+ ADD count, count, tmp2, LSL #8
+loop1_x
+ ;// Process 2x2 block
+ LDRB tmp2, [ptrA,width] ;// 2 row, 1 col
+ LDRB tmp3, [ptrA,width, LSL #1] ;// 3 row, 1 col
+ LDRB tmp1, [ptrA],#1 ;// 1 row, 1 col
+
+ LDRB tmp5, [ptrA,width] ;// 2 row, 2 col
+ LDRB tmp6, [ptrA,width, LSL #1] ;// 3 row, 2 col
+ LDRB tmp4, [ptrA],#1 ;// 1 row, 2 col
+
+ PKHBT tmp1, tmp1, tmp2, LSL #16 ;// |B|A|
+ PKHBT tmp2, tmp2, tmp3, LSL #16 ;// |C|B|
+ PKHBT tmp4, tmp4, tmp5, LSL #16 ;// |B|A|
+
+ SMLAD tmp7, tmp2, valY, c32 ;// multiply
+ PKHBT tmp5, tmp5, tmp6, LSL #16 ;// |C|B|
+ SMLAD tmp2, tmp1, valY, c32 ;// multiply
+ SMLAD tmp8, tmp5, valY, c32 ;// multiply
+ SMLAD tmp5, tmp4, valY, c32 ;// multiply
+
+ MOV tmp7, tmp7, LSR #6 ;// scale down
+ STRB tmp7, [mb,#8] ;// store row 2 col 1
+ MOV tmp2, tmp2, LSR #6 ;// scale down
+ STRB tmp2, [mb],#1 ;// store row 1 col 1
+
+ MOV tmp8, tmp8, LSR #6 ;// scale down
+ STRB tmp8, [mb,#8] ;// store row 2 col 2
+ MOV tmp5, tmp5, LSR #6 ;// scale down
+ STRB tmp5, [mb],#1 ;// store row 1 col 2
+
+
+ SUBS count, count, #2<<28
+ BCS loop1_x
+
+ AND tmp2, count, #0x00F00000
+
+ ADDS mb, mb, #16
+ SBC mb, mb, tmp2, LSR #20
+ ADD ptrA, ptrA, width, LSL #1
+ SBC ptrA, ptrA, tmp2, LSR #20
+
+ ADDS count, count, #0xE << 24
+ BGE loop1_y
+
+ ;///////////////////////////////////////////////////////////////////////////
+ ;// Cr
+ ;///////////////////////////////////////////////////////////////////////////
+ LDR height, [sp,#0xfc] ;// height
+ LDR ref, [sp, #0xc4] ;// ref
+ LDR tmp1, [sp, #0xd0] ;// y0
+ LDR tmp2, [sp, #0xcc] ;// x0
+ LDR mb, [sp, #0xc8] ;// predPartChroma
+
+ ADD tmp1, height, tmp1
+ MLA tmp3, tmp1, width, tmp2
+ ADD ptrA, ref, tmp3
+ ADD mb, mb, #64
+
+ AND count, count, #0x00FFFFFF
+ AND tmp1, count, #0x000F0000
+ ADD count, count, tmp1, LSL #8
+ AND tmp2, count, #0x00F00000
+
+ ;// 2x2 pels per iteration
+ ;// bilinear vertical interpolation
+loop2_y
+ ADD count, count, tmp2, LSL #8
+loop2_x
+ ;// Process 2x2 block
+ LDRB tmp2, [ptrA,width] ;// 2 row, 1 col
+ LDRB tmp3, [ptrA,width, LSL #1] ;// 3 row, 1 col
+ LDRB tmp1, [ptrA],#1 ;// 1 row, 1 col
+
+ LDRB tmp5, [ptrA,width] ;// 2 row, 2 col
+ LDRB tmp6, [ptrA,width, LSL #1] ;// 3 row, 2 col
+ LDRB tmp4, [ptrA],#1 ;// 1 row, 2 col
+
+ PKHBT tmp1, tmp1, tmp2, LSL #16 ;// |B|A|
+ PKHBT tmp2, tmp2, tmp3, LSL #16 ;// |C|B|
+ PKHBT tmp4, tmp4, tmp5, LSL #16 ;// |B|A|
+
+ SMLAD tmp7, tmp2, valY, c32 ;// multiply
+ PKHBT tmp5, tmp5, tmp6, LSL #16 ;// |C|B|
+ SMLAD tmp2, tmp1, valY, c32 ;// multiply
+ SMLAD tmp8, tmp5, valY, c32 ;// multiply
+ SMLAD tmp5, tmp4, valY, c32 ;// multiply
+
+ MOV tmp7, tmp7, LSR #6 ;// scale down
+ STRB tmp7, [mb,#8] ;// store row 2 col 1
+ MOV tmp2, tmp2, LSR #6 ;// scale down
+ STRB tmp2, [mb],#1 ;// store row 1 col 1
+
+ MOV tmp8, tmp8, LSR #6 ;// scale down
+ STRB tmp8, [mb,#8] ;// store row 2 col 2
+ MOV tmp5, tmp5, LSR #6 ;// scale down
+ STRB tmp5, [mb],#1 ;// store row 1 col 2
+
+
+ SUBS count, count, #2<<28
+ BCS loop2_x
+
+ AND tmp2, count, #0x00F00000
+
+ ADDS mb, mb, #16
+ SBC mb, mb, tmp2, LSR #20
+ ADD ptrA, ptrA, width, LSL #1
+ SBC ptrA, ptrA, tmp2, LSR #20
+
+ ADDS count, count, #0xE << 24
+ BGE loop2_y
+
+ ADD sp,sp,#0xd4
+ LDMFD sp!, {r4-r11,pc}
+
+ END
diff --git a/media/libstagefright/codecs/on2/h264dec/source/arm11_asm/h264bsd_interpolate_hor_half.s b/media/libstagefright/codecs/on2/h264dec/source/arm11_asm/h264bsd_interpolate_hor_half.s
new file mode 100755
index 0000000..93968b6
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/arm11_asm/h264bsd_interpolate_hor_half.s
@@ -0,0 +1,251 @@
+; 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.
+
+;-------------------------------------------------------------------------------
+;--
+;-- Abstract : ARMv6 optimized version of h264bsdInterpolateHorHalf function
+;--
+;-------------------------------------------------------------------------------
+
+
+ IF :DEF: H264DEC_WINASM
+ ;// We dont use REQUIRE8 and PRESERVE8 for winasm
+ ELSE
+ REQUIRE8
+ PRESERVE8
+ ENDIF
+
+ AREA |.text|, CODE
+
+;// h264bsdInterpolateHorHalf register allocation
+
+ref RN 0
+
+mb RN 1
+buff RN 1
+
+count RN 2
+x0 RN 2
+
+y0 RN 3
+x_2_0 RN 3
+
+width RN 4
+x_3_1 RN 4
+
+height RN 5
+x_6_4 RN 5
+
+partW RN 6
+x_7_5 RN 6
+
+partH RN 7
+tmp1 RN 7
+
+tmp2 RN 8
+
+tmp3 RN 9
+
+tmp4 RN 10
+
+mult_20_01 RN 11
+mult_20_m5 RN 12
+
+plus16 RN 14
+
+
+;// function exports and imports
+
+ IMPORT h264bsdFillBlock
+
+ EXPORT h264bsdInterpolateHorHalf
+
+;// Horizontal filter approach
+;//
+;// Basic idea in horizontal filtering is to adjust coefficients
+;// like below. Calculation is done with 16-bit maths.
+;//
+;// Reg x_2_0 x_3_1 x_6_4 x_7_5 x_2_0
+;// [ 2 0 ] [ 3 1 ] [ 6 4 ] [ 7 5 ] [ 10 8 ] ...
+;// y_0 = 20 1 20 -5 -5 1
+;// y_1 = -5 20 1 1 20 -5
+;// y_2 = 1 -5 -5 20 1 20
+;// y_3 = 1 20 -5 -5 20 1
+
+
+h264bsdInterpolateHorHalf
+ STMFD sp!, {r0-r11, lr}
+ SUB sp, sp, #0x1e4
+
+ CMP x0, #0
+ BLT do_fill ;// (x0 < 0)
+ LDR partW, [sp,#0x220] ;// partWidth
+ ADD tmp4, x0, partW ;// (x0+partWidth)
+ ADD tmp4, tmp4, #5 ;// (y0+partW+5)
+ LDR width, [sp,#0x218] ;// width
+ CMP tmp4, width
+ BHI do_fill ;// (x0+partW)>width
+
+ CMP y0, #0
+ BLT do_fill ;// (y0 < 0)
+ LDR partH, [sp,#0x224] ;// partHeight
+ ADD tmp2, y0, partH ;// (y0+partHeight)
+ LDR height, [sp,#0x21c] ;// height
+ CMP tmp2, height
+ BLS skip_fill ;// no overfill needed
+
+
+do_fill
+ LDR partH, [sp,#0x224] ;// partHeight
+ LDR height, [sp,#0x21c] ;// height
+ LDR partW, [sp,#0x220] ;// partWidth
+ ADD tmp4, partW, #5 ;// tmp4 = partW + 5;
+ STMIB sp, {height, tmp4} ;// sp+4 = height, sp+8 = partWidth+5
+ STR partH, [sp,#0xc] ;// sp+c = partHeight
+ STR tmp4, [sp,#0x10] ;// sp+10 = partWidth+5
+ LDR width, [sp,#0x218] ;// width
+ STR width, [sp,#0] ;// sp+0 = width
+ ADD buff, sp, #0x28 ;// buff = p1[21*21/4+1]
+ BL h264bsdFillBlock
+
+ MOV x0, #0
+ STR x0,[sp,#0x1ec] ;// x0 = 0
+ STR x0,[sp,#0x1f0] ;// y0 = 0
+ ADD ref,sp,#0x28 ;// ref = p1
+ STR tmp4, [sp,#0x218] ;// width = partWidth+5
+
+
+skip_fill
+ LDR x0 ,[sp,#0x1ec] ;// x0
+ LDR y0 ,[sp,#0x1f0] ;// y0
+ LDR width, [sp,#0x218] ;// width
+ MLA tmp2, width, y0, x0 ;// y0*width+x0
+ ADD ref, ref, tmp2 ;// ref += y0*width+x0
+ ADD ref, ref, #8 ;// ref = ref+8
+ LDR mb, [sp, #0x1e8] ;// mb
+
+ ;// pack values to count register
+ ;// [31:28] loop_x (partWidth-1)
+ ;// [27:24] loop_y (partHeight-1)
+ ;// [23:20] partWidth-1
+ ;// [19:16] partHeight-1
+ ;// [15:00] width
+ MOV count, width
+ SUB partW, partW, #1;
+ SUB partH, partH, #1;
+ ADD tmp2, partH, partW, LSL #4
+ ADD count, count, tmp2, LSL #16
+
+
+ LDR mult_20_01, = 0x00140001
+ LDR mult_20_m5, = 0x0014FFFB
+ MOV plus16, #16
+ AND tmp1, count, #0x000F0000 ;// partHeight-1
+ AND tmp3, count, #0x00F00000 ;// partWidth-1
+ ADD count, count, tmp1, LSL #8
+loop_y
+ LDR x_3_1, [ref, #-8]
+ ADD count, count, tmp3, LSL #8
+ LDR x_7_5, [ref, #-4]
+ UXTB16 x_2_0, x_3_1
+ UXTB16 x_3_1, x_3_1, ROR #8
+ UXTB16 x_6_4, x_7_5
+
+loop_x
+ UXTB16 x_7_5, x_7_5, ROR #8
+
+ SMLAD tmp1, x_2_0, mult_20_01, plus16
+ SMLATB tmp3, x_2_0, mult_20_01, plus16
+ SMLATB tmp2, x_2_0, mult_20_m5, plus16
+ SMLATB tmp4, x_3_1, mult_20_01, plus16
+
+ SMLAD tmp1, x_3_1, mult_20_m5, tmp1
+ SMLATB tmp3, x_3_1, mult_20_m5, tmp3
+ SMLAD tmp2, x_3_1, mult_20_01, tmp2
+ LDR x_3_1, [ref], #4
+ SMLAD tmp4, x_6_4, mult_20_m5, tmp4
+
+ SMLABB tmp1, x_6_4, mult_20_m5, tmp1
+ SMLADX tmp3, x_6_4, mult_20_m5, tmp3
+ SMLADX tmp2, x_6_4, mult_20_01, tmp2
+ SMLADX tmp4, x_7_5, mult_20_m5, tmp4
+
+ SMLABB tmp1, x_7_5, mult_20_01, tmp1
+ UXTB16 x_2_0, x_3_1
+ SMLABB tmp2, x_7_5, mult_20_m5, tmp2
+ SMLADX tmp3, x_7_5, mult_20_01, tmp3
+ SMLABB tmp4, x_2_0, mult_20_01, tmp4
+
+ MOV tmp2, tmp2, ASR #5
+ MOV tmp1, tmp1, ASR #5
+ PKHBT tmp2, tmp2, tmp4, LSL #(16-5)
+ PKHBT tmp1, tmp1, tmp3, LSL #(16-5)
+ USAT16 tmp2, #8, tmp2
+ USAT16 tmp1, #8, tmp1
+
+ SUBS count, count, #4<<28
+ ORR tmp1, tmp1, tmp2, LSL #8
+ STR tmp1, [mb], #4
+ BCC next_y
+
+ UXTB16 x_3_1, x_3_1, ROR #8
+
+ SMLAD tmp1, x_6_4, mult_20_01, plus16
+ SMLATB tmp3, x_6_4, mult_20_01, plus16
+ SMLATB tmp2, x_6_4, mult_20_m5, plus16
+ SMLATB tmp4, x_7_5, mult_20_01, plus16
+
+ SMLAD tmp1, x_7_5, mult_20_m5, tmp1
+ SMLATB tmp3, x_7_5, mult_20_m5, tmp3
+ SMLAD tmp2, x_7_5, mult_20_01, tmp2
+ LDR x_7_5, [ref], #4
+ SMLAD tmp4, x_2_0, mult_20_m5, tmp4
+
+ SMLABB tmp1, x_2_0, mult_20_m5, tmp1
+ SMLADX tmp3, x_2_0, mult_20_m5, tmp3
+ SMLADX tmp2, x_2_0, mult_20_01, tmp2
+ SMLADX tmp4, x_3_1, mult_20_m5, tmp4
+
+ SMLABB tmp1, x_3_1, mult_20_01, tmp1
+ UXTB16 x_6_4, x_7_5
+ SMLABB tmp2, x_3_1, mult_20_m5, tmp2
+ SMLADX tmp3, x_3_1, mult_20_01, tmp3
+ SMLABB tmp4, x_6_4, mult_20_01, tmp4
+
+ MOV tmp2, tmp2, ASR #5
+ MOV tmp1, tmp1, ASR #5
+ PKHBT tmp2, tmp2, tmp4, LSL #(16-5)
+ PKHBT tmp1, tmp1, tmp3, LSL #(16-5)
+ USAT16 tmp2, #8, tmp2
+ USAT16 tmp1, #8, tmp1
+
+ SUBS count, count, #4<<28
+ ORR tmp1, tmp1, tmp2, LSL #8
+ STR tmp1, [mb], #4
+ BCS loop_x
+
+next_y
+ AND tmp3, count, #0x00F00000 ;// partWidth-1
+ SMLABB ref, count, mult_20_01, ref ;// +width
+ ADDS mb, mb, #16 ;// +16, Carry=0
+ SBC mb, mb, tmp3, LSR #20 ;// -(partWidth-1)-1
+ SBC ref, ref, tmp3, LSR #20 ;// -(partWidth-1)-1
+ ADDS count, count, #(1<<28)-(1<<24)
+ BGE loop_y
+
+ ADD sp,sp,#0x1f4
+ LDMFD sp!, {r4-r11, pc}
+
+ END
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/arm11_asm/h264bsd_interpolate_hor_quarter.s b/media/libstagefright/codecs/on2/h264dec/source/arm11_asm/h264bsd_interpolate_hor_quarter.s
new file mode 100755
index 0000000..de243d4
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/arm11_asm/h264bsd_interpolate_hor_quarter.s
@@ -0,0 +1,273 @@
+; 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.
+
+;-------------------------------------------------------------------------------
+;--
+;-- Abstract : ARMv6 optimized version of h264bsdInterpolateHorQuarter function
+;--
+;-------------------------------------------------------------------------------
+
+
+ IF :DEF: H264DEC_WINASM
+ ;// We dont use REQUIRE8 and PRESERVE8 for winasm
+ ELSE
+ REQUIRE8
+ PRESERVE8
+ ENDIF
+
+ AREA |.text|, CODE
+
+;// h264bsdInterpolateHorQuarter register allocation
+
+ref RN 0
+
+mb RN 1
+buff RN 1
+
+count RN 2
+x0 RN 2
+
+y0 RN 3
+x_2_0 RN 3
+
+width RN 4
+x_3_1 RN 4
+
+height RN 5
+x_6_4 RN 5
+
+partW RN 6
+x_7_5 RN 6
+
+partH RN 7
+tmp1 RN 7
+
+tmp2 RN 8
+
+tmp3 RN 9
+
+tmp4 RN 10
+
+mult_20_01 RN 11
+
+mult_20_m5 RN 12
+
+plus16 RN 14
+
+
+;// function exports and imports
+
+ IMPORT h264bsdFillBlock
+
+ EXPORT h264bsdInterpolateHorQuarter
+
+
+;// Horizontal filter approach
+;//
+;// Basic idea in horizontal filtering is to adjust coefficients
+;// like below. Calculation is done with 16-bit maths.
+;//
+;// Reg x_2_0 x_3_1 x_6_4 x_7_5 x_2_0
+;// [ 2 0 ] [ 3 1 ] [ 6 4 ] [ 7 5 ] [ 10 8 ] ...
+;// y_0 = 20 1 20 -5 -5 1
+;// y_1 = -5 20 1 1 20 -5
+;// y_2 = 1 -5 -5 20 1 20
+;// y_3 = 1 20 -5 -5 20 1
+
+
+h264bsdInterpolateHorQuarter
+ STMFD sp!, {r0-r11, lr}
+ SUB sp, sp, #0x1e4
+
+ CMP x0, #0
+ BLT do_fill ;// (x0 < 0)
+ LDR partW, [sp,#0x220] ;// partWidth
+ ADD tmp4, x0, partW ;// (x0+partWidth)
+ ADD tmp4, tmp4, #5 ;// (y0+partW+5)
+ LDR width, [sp,#0x218] ;// width
+ CMP tmp4, width
+ BHI do_fill ;// (x0+partW)>width
+
+ CMP y0, #0
+ BLT do_fill ;// (y0 < 0)
+ LDR partH, [sp,#0x224] ;// partHeight
+ ADD tmp2, y0, partH ;// (y0+partHeight)
+ LDR height, [sp,#0x21c] ;// height
+ CMP tmp2, height
+ BLS skip_fill ;// no overfill needed
+
+
+do_fill
+ LDR partH, [sp,#0x224] ;// partHeight
+ LDR height, [sp,#0x21c] ;// height
+ LDR partW, [sp,#0x220] ;// partWidth
+ ADD tmp4, partW, #5 ;// tmp4 = partW + 5;
+ STMIB sp, {height, tmp4} ;// sp+4 = height, sp+8 = partWidth+5
+ STR partH, [sp,#0xc] ;// sp+c = partHeight
+ STR tmp4, [sp,#0x10] ;// sp+10 = partWidth+5
+ LDR width, [sp,#0x218] ;// width
+ STR width, [sp,#0] ;// sp+0 = width
+ ADD buff, sp, #0x28 ;// buff = p1[21*21/4+1]
+ BL h264bsdFillBlock
+
+ MOV x0, #0
+ STR x0,[sp,#0x1ec] ;// x0 = 0
+ STR x0,[sp,#0x1f0] ;// y0 = 0
+ ADD ref,sp,#0x28 ;// ref = p1
+ STR tmp4, [sp,#0x218] ;// width = partWidth+5
+
+
+skip_fill
+ LDR x0 ,[sp,#0x1ec] ;// x0
+ LDR y0 ,[sp,#0x1f0] ;// y0
+ LDR width, [sp,#0x218] ;// width
+ MLA tmp2, width, y0, x0 ;// y0*width+x0
+ ADD ref, ref, tmp2 ;// ref += y0*width+x0
+ ADD ref, ref, #8 ;// ref = ref+8
+ LDR mb, [sp, #0x1e8] ;// mb
+
+ ;// pack values to count register
+ ;// [31:28] loop_x (partWidth-1)
+ ;// [27:24] loop_y (partHeight-1)
+ ;// [23:20] partWidth-1
+ ;// [19:16] partHeight-1
+ ;// [15:00] width
+ MOV count, width
+ SUB partW, partW, #1;
+ SUB partH, partH, #1;
+ ADD tmp2, partH, partW, LSL #4
+ ADD count, count, tmp2, LSL #16
+
+
+ LDR mult_20_01, = 0x00140001
+ LDR mult_20_m5, = 0x0014FFFB
+ MOV plus16, #16
+ AND tmp1, count, #0x000F0000 ;// partHeight-1
+ AND tmp3, count, #0x00F00000 ;// partWidth-1
+ ADD count, count, tmp1, LSL #8
+loop_y
+ LDR x_3_1, [ref, #-8]
+ ADD count, count, tmp3, LSL #8
+ LDR x_7_5, [ref, #-4]
+ UXTB16 x_2_0, x_3_1
+ UXTB16 x_3_1, x_3_1, ROR #8
+ UXTB16 x_6_4, x_7_5
+
+loop_x
+ UXTB16 x_7_5, x_7_5, ROR #8
+
+ SMLAD tmp1, x_2_0, mult_20_01, plus16
+ SMLATB tmp3, x_2_0, mult_20_01, plus16
+ SMLATB tmp2, x_2_0, mult_20_m5, plus16
+ SMLATB tmp4, x_3_1, mult_20_01, plus16
+
+ SMLAD tmp1, x_3_1, mult_20_m5, tmp1
+ SMLATB tmp3, x_3_1, mult_20_m5, tmp3
+ SMLAD tmp2, x_3_1, mult_20_01, tmp2
+ LDR x_3_1, [ref], #4
+ SMLAD tmp4, x_6_4, mult_20_m5, tmp4
+
+ SMLABB tmp1, x_6_4, mult_20_m5, tmp1
+ SMLADX tmp3, x_6_4, mult_20_m5, tmp3
+ SMLADX tmp2, x_6_4, mult_20_01, tmp2
+ SMLADX tmp4, x_7_5, mult_20_m5, tmp4
+
+ SMLABB tmp1, x_7_5, mult_20_01, tmp1
+ UXTB16 x_2_0, x_3_1
+ SMLABB tmp2, x_7_5, mult_20_m5, tmp2
+ SMLADX tmp3, x_7_5, mult_20_01, tmp3
+ SMLABB tmp4, x_2_0, mult_20_01, tmp4
+
+ MOV tmp2, tmp2, ASR #5
+ MOV tmp1, tmp1, ASR #5
+ PKHBT tmp2, tmp2, tmp4, LSL #(16-5)
+ PKHBT tmp1, tmp1, tmp3, LSL #(16-5)
+ LDR tmp4, [sp, #0x228]
+ USAT16 tmp2, #8, tmp2
+ USAT16 tmp1, #8, tmp1
+ SUB tmp4, tmp4, #10
+
+ SUBS count, count, #4<<28
+ LDR tmp3, [ref, tmp4]
+ ORR tmp1, tmp1, tmp2, LSL #8
+
+;// quarter pel position
+ LDR tmp2, = 0x80808080
+ MVN tmp3, tmp3
+ UHSUB8 tmp1, tmp1, tmp3
+ EOR tmp1, tmp1, tmp2
+ STR tmp1, [mb], #4
+
+ BCC next_y
+
+ UXTB16 x_3_1, x_3_1, ROR #8
+
+ SMLAD tmp1, x_6_4, mult_20_01, plus16
+ SMLATB tmp3, x_6_4, mult_20_01, plus16
+ SMLATB tmp2, x_6_4, mult_20_m5, plus16
+ SMLATB tmp4, x_7_5, mult_20_01, plus16
+
+ SMLAD tmp1, x_7_5, mult_20_m5, tmp1
+ SMLATB tmp3, x_7_5, mult_20_m5, tmp3
+ SMLAD tmp2, x_7_5, mult_20_01, tmp2
+ LDR x_7_5, [ref], #4
+ SMLAD tmp4, x_2_0, mult_20_m5, tmp4
+
+ SMLABB tmp1, x_2_0, mult_20_m5, tmp1
+ SMLADX tmp3, x_2_0, mult_20_m5, tmp3
+ SMLADX tmp2, x_2_0, mult_20_01, tmp2
+ SMLADX tmp4, x_3_1, mult_20_m5, tmp4
+
+ SMLABB tmp1, x_3_1, mult_20_01, tmp1
+ UXTB16 x_6_4, x_7_5
+ SMLABB tmp2, x_3_1, mult_20_m5, tmp2
+ SMLADX tmp3, x_3_1, mult_20_01, tmp3
+ SMLABB tmp4, x_6_4, mult_20_01, tmp4
+
+ MOV tmp2, tmp2, ASR #5
+ MOV tmp1, tmp1, ASR #5
+ PKHBT tmp2, tmp2, tmp4, LSL #(16-5)
+ PKHBT tmp1, tmp1, tmp3, LSL #(16-5)
+ LDR tmp4, [sp, #0x228]
+ USAT16 tmp2, #8, tmp2
+ USAT16 tmp1, #8, tmp1
+ SUB tmp4, tmp4, #10
+
+ SUBS count, count, #4<<28
+ LDR tmp3, [ref, tmp4]
+ ORR tmp1, tmp1, tmp2, LSL #8
+
+;// quarter pel
+ LDR tmp2, = 0x80808080
+ MVN tmp3, tmp3
+ UHSUB8 tmp1, tmp1, tmp3
+ EOR tmp1, tmp1, tmp2
+
+ STR tmp1, [mb], #4
+ BCS loop_x
+
+next_y
+ AND tmp3, count, #0x00F00000 ;// partWidth-1
+ SMLABB ref, count, mult_20_01, ref ;// +width
+ ADDS mb, mb, #16 ;// +16, Carry=0
+ SBC mb, mb, tmp3, LSR #20 ;// -(partWidth-1)-1
+ SBC ref, ref, tmp3, LSR #20 ;// -(partWidth-1)-1
+ ADDS count, count, #(1<<28)-(1<<24)
+ BGE loop_y
+
+ ADD sp,sp,#0x1f4
+ LDMFD sp!, {r4-r11, pc}
+
+ END
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/arm11_asm/h264bsd_interpolate_hor_ver_quarter.s b/media/libstagefright/codecs/on2/h264dec/source/arm11_asm/h264bsd_interpolate_hor_ver_quarter.s
new file mode 100755
index 0000000..1c79b39
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/arm11_asm/h264bsd_interpolate_hor_ver_quarter.s
@@ -0,0 +1,536 @@
+; 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.
+
+;-------------------------------------------------------------------------------
+;--
+;-- Abstract : ARMv6 optimized version of h264bsdInterpolateHorVerQuarter
+;-- function
+;--
+;-------------------------------------------------------------------------------
+
+
+ IF :DEF: H264DEC_WINASM
+ ;// We dont use REQUIRE8 and PRESERVE8 for winasm
+ ELSE
+ REQUIRE8
+ PRESERVE8
+ ENDIF
+
+ AREA |.text|, CODE
+
+;// h264bsdInterpolateHorVerQuarter register allocation
+
+ref RN 0
+
+mb RN 1
+buff RN 1
+
+count RN 2
+x0 RN 2
+
+y0 RN 3
+x_2_0 RN 3
+res RN 3
+
+x_3_1 RN 4
+tmp1 RN 4
+
+height RN 5
+x_6_4 RN 5
+tmp2 RN 5
+
+partW RN 6
+x_7_5 RN 6
+tmp3 RN 6
+
+partH RN 7
+tmp4 RN 7
+
+tmp5 RN 8
+
+tmp6 RN 9
+
+tmpa RN 10
+
+mult_20_01 RN 11
+tmpb RN 11
+
+mult_20_m5 RN 12
+width RN 12
+
+plus16 RN 14
+
+
+;// function exports and imports
+
+ IMPORT h264bsdFillBlock
+
+ EXPORT h264bsdInterpolateHorVerQuarter
+
+;// Horizontal filter approach
+;//
+;// Basic idea in horizontal filtering is to adjust coefficients
+;// like below. Calculation is done with 16-bit maths.
+;//
+;// Reg x_2_0 x_3_1 x_6_4 x_7_5 x_2_0
+;// [ 2 0 ] [ 3 1 ] [ 6 4 ] [ 7 5 ] [ 10 8 ] ...
+;// y_0 = 20 1 20 -5 -5 1
+;// y_1 = -5 20 1 1 20 -5
+;// y_2 = 1 -5 -5 20 1 20
+;// y_3 = 1 20 -5 -5 20 1
+
+
+h264bsdInterpolateHorVerQuarter
+ STMFD sp!, {r0-r11, lr}
+ SUB sp, sp, #0x1e4
+
+ CMP x0, #0
+ BLT do_fill ;// (x0 < 0)
+ LDR partW, [sp,#0x220] ;// partWidth
+ LDR width, [sp,#0x218] ;// width
+ ADD tmpa, x0, partW ;// (x0+partWidth)
+ ADD tmpa, tmpa, #5 ;// (x0+partW+5)
+ CMP tmpa, width
+ BHI do_fill ;// (x0+partW)>width
+
+ CMP y0, #0
+ BLT do_fill ;// (y0 < 0)
+ LDR partH, [sp,#0x224] ;// partHeight
+ LDR height, [sp,#0x21c] ;// height
+ ADD tmp5, y0, partH ;// (y0+partHeight)
+ ADD tmp5, tmp5, #5 ;// (y0+partH+5)
+ CMP tmp5, height
+ BLS skip_fill ;// no overfill needed
+
+
+do_fill
+ LDR partH, [sp,#0x224] ;// partHeight
+ LDR partW, [sp,#0x220] ;// partWidth
+ LDR height, [sp,#0x21c] ;// height
+ ADD tmp5, partH, #5 ;// tmp5 = partH + 5
+ ADD tmpa, partW, #5 ;// tmpa = partW + 5
+ STMIB sp, {height, tmpa} ;// sp+4 = height, sp+8 = partWidth+5
+ LDR width, [sp,#0x218] ;// width
+ STR tmp5, [sp,#0xc] ;// sp+c = partHeight+5
+ STR tmpa, [sp,#0x10] ;// sp+10 = partWidth+5
+ STR width, [sp,#0] ;// sp+0 = width
+ ADD buff, sp, #0x28 ;// buff = p1[21*21/4+1]
+ BL h264bsdFillBlock
+
+ MOV x0, #0
+ STR x0,[sp,#0x1ec] ;// x0 = 0
+ STR x0,[sp,#0x1f0] ;// y0 = 0
+ ADD ref,sp,#0x28 ;// ref = p1
+ STR tmpa, [sp,#0x218] ;// width = partWidth+5
+
+
+skip_fill
+ LDR x0 ,[sp,#0x1ec] ;// x0
+ LDR y0 ,[sp,#0x1f0] ;// y0
+ LDR width, [sp,#0x218] ;// width
+ LDR tmp6, [sp,#0x228] ;// horVerOffset
+ LDR mb, [sp, #0x1e8] ;// mb
+ MLA tmp5, width, y0, x0 ;// y0*width+x0
+ ADD ref, ref, tmp5 ;// ref += y0*width+x0
+ STR ref, [sp, #0x1e4] ;// store "ref" for vertical filtering
+ AND tmp6, tmp6, #2 ;// calculate ref for horizontal filter
+ MOV tmpa, #2
+ ADD tmp6, tmpa, tmp6, LSR #1
+ MLA ref, tmp6, width, ref
+ ADD ref, ref, #8 ;// ref = ref+8
+
+ ;// pack values to count register
+ ;// [31:28] loop_x (partWidth-1)
+ ;// [27:24] loop_y (partHeight-1)
+ ;// [23:20] partWidth-1
+ ;// [19:16] partHeight-1
+ ;// [15:00] width
+ MOV count, width
+ SUB partW, partW, #1;
+ SUB partH, partH, #1;
+ ADD tmp5, partH, partW, LSL #4
+ ADD count, count, tmp5, LSL #16
+
+
+ LDR mult_20_01, = 0x00140001 ;// constant multipliers
+ LDR mult_20_m5, = 0x0014FFFB ;// constant multipliers
+ MOV plus16, #16 ;// constant for add
+ AND tmp4, count, #0x000F0000 ;// partHeight-1
+ AND tmp6, count, #0x00F00000 ;// partWidth-1
+ ADD count, count, tmp4, LSL #8 ;// partH-1 to lower part of top byte
+
+;// HORIZONTAL PART
+
+loop_y_hor
+ LDR x_3_1, [ref, #-8]
+ ADD count, count, tmp6, LSL #8 ;// partW-1 to upper part of top byte
+ LDR x_7_5, [ref, #-4]
+ UXTB16 x_2_0, x_3_1
+ UXTB16 x_3_1, x_3_1, ROR #8
+ UXTB16 x_6_4, x_7_5
+
+loop_x_hor
+ UXTB16 x_7_5, x_7_5, ROR #8
+
+ SMLAD tmp4, x_2_0, mult_20_01, plus16
+ SMLATB tmp6, x_2_0, mult_20_01, plus16
+ SMLATB tmp5, x_2_0, mult_20_m5, plus16
+ SMLATB tmpa, x_3_1, mult_20_01, plus16
+
+ SMLAD tmp4, x_3_1, mult_20_m5, tmp4
+ SMLATB tmp6, x_3_1, mult_20_m5, tmp6
+ SMLAD tmp5, x_3_1, mult_20_01, tmp5
+ LDR x_3_1, [ref], #4
+ SMLAD tmpa, x_6_4, mult_20_m5, tmpa
+
+ SMLABB tmp4, x_6_4, mult_20_m5, tmp4
+ SMLADX tmp6, x_6_4, mult_20_m5, tmp6
+ SMLADX tmp5, x_6_4, mult_20_01, tmp5
+ SMLADX tmpa, x_7_5, mult_20_m5, tmpa
+
+ SMLABB tmp4, x_7_5, mult_20_01, tmp4
+ UXTB16 x_2_0, x_3_1
+ SMLABB tmp5, x_7_5, mult_20_m5, tmp5
+ SMLADX tmp6, x_7_5, mult_20_01, tmp6
+ SMLABB tmpa, x_2_0, mult_20_01, tmpa
+
+ MOV tmp5, tmp5, ASR #5
+ MOV tmp4, tmp4, ASR #5
+ PKHBT tmp5, tmp5, tmpa, LSL #(16-5)
+ PKHBT tmp4, tmp4, tmp6, LSL #(16-5)
+ USAT16 tmp5, #8, tmp5
+ USAT16 tmp4, #8, tmp4
+
+ SUBS count, count, #4<<28
+ ORR tmp4, tmp4, tmp5, LSL #8
+ STR tmp4, [mb], #4
+ BCC next_y_hor
+
+ UXTB16 x_3_1, x_3_1, ROR #8
+
+ SMLAD tmp4, x_6_4, mult_20_01, plus16
+ SMLATB tmp6, x_6_4, mult_20_01, plus16
+ SMLATB tmp5, x_6_4, mult_20_m5, plus16
+ SMLATB tmpa, x_7_5, mult_20_01, plus16
+
+ SMLAD tmp4, x_7_5, mult_20_m5, tmp4
+ SMLATB tmp6, x_7_5, mult_20_m5, tmp6
+ SMLAD tmp5, x_7_5, mult_20_01, tmp5
+ LDR x_7_5, [ref], #4
+ SMLAD tmpa, x_2_0, mult_20_m5, tmpa
+
+ SMLABB tmp4, x_2_0, mult_20_m5, tmp4
+ SMLADX tmp6, x_2_0, mult_20_m5, tmp6
+ SMLADX tmp5, x_2_0, mult_20_01, tmp5
+ SMLADX tmpa, x_3_1, mult_20_m5, tmpa
+
+ SMLABB tmp4, x_3_1, mult_20_01, tmp4
+ UXTB16 x_6_4, x_7_5
+ SMLABB tmp5, x_3_1, mult_20_m5, tmp5
+ SMLADX tmp6, x_3_1, mult_20_01, tmp6
+ SMLABB tmpa, x_6_4, mult_20_01, tmpa
+
+ MOV tmp5, tmp5, ASR #5
+ MOV tmp4, tmp4, ASR #5
+ PKHBT tmp5, tmp5, tmpa, LSL #(16-5)
+ PKHBT tmp4, tmp4, tmp6, LSL #(16-5)
+ USAT16 tmp5, #8, tmp5
+ USAT16 tmp4, #8, tmp4
+
+ SUBS count, count, #4<<28
+ ORR tmp4, tmp4, tmp5, LSL #8
+ STR tmp4, [mb], #4
+ BCS loop_x_hor
+
+next_y_hor
+ AND tmp6, count, #0x00F00000 ;// partWidth-1
+ SMLABB ref, count, mult_20_01, ref ;// +width
+ ADDS mb, mb, #16 ;// +16, Carry=0
+ SBC mb, mb, tmp6, LSR #20 ;// -(partWidth-1)-1
+ SBC ref, ref, tmp6, LSR #20 ;// -(partWidth-1)-1
+ ADDS count, count, #(1<<28)-(1<<24) ;// decrement counter (partW)
+ BGE loop_y_hor
+
+
+
+;// VERTICAL PART
+;//
+;// Approach to vertical interpolation
+;//
+;// Interpolation is done by using 32-bit loads and stores
+;// and by using 16 bit arithmetic. 4x4 block is processed
+;// in each round.
+;//
+;// |a_11|a_11|a_11|a_11|...|a_1n|a_1n|a_1n|a_1n|
+;// |b_11|b_11|b_11|b_11|...|b_1n|b_1n|b_1n|b_1n|
+;// |c_11|c_11|c_11|c_11|...|c_1n|c_1n|c_1n|c_1n|
+;// |d_11|d_11|d_11|d_11|...|d_1n|d_1n|d_1n|d_1n|
+;// ..
+;// ..
+;// |a_m1|a_m1|a_m1|a_m1|...
+;// |b_m1|b_m1|b_m1|b_m1|...
+;// |c_m1|c_m1|c_m1|c_m1|...
+;// |d_m1|d_m1|d_m1|d_m1|...
+
+;// Approach to bilinear interpolation to quarter pel position.
+;// 4 bytes are processed parallel
+;//
+;// algorithm (a+b+1)/2. Rouding upwards +1 can be achieved by
+;// negating second operand to get one's complement (instead of 2's)
+;// and using subtraction, EOR is used to correct sign.
+;//
+;// MVN b, b
+;// UHSUB8 a, a, b
+;// EOR a, a, 0x80808080
+
+
+ LDR ref, [sp, #0x1e4] ;// ref
+ LDR tmpa, [sp, #0x228] ;// horVerOffset
+ LDR mb, [sp, #0x1e8] ;// mb
+ LDR width, [sp, #0x218] ;// width
+ ADD ref, ref, #2 ;// calculate correct position
+ AND tmpa, tmpa, #1
+ ADD ref, ref, tmpa
+ LDR plus16, = 0x00100010 ;// +16 to lower and upperf halfwords
+ AND count, count, #0x00FFFFFF ;// partWidth-1
+
+ AND tmpa, count, #0x000F0000 ;// partHeight-1
+ ADD count, count, tmpa, LSL #8
+
+loop_y
+ ADD count, count, tmp6, LSL #8 ;// partWidth-1
+
+loop_x
+ LDR tmp1, [ref], width ;// |a4|a3|a2|a1|
+ LDR tmp2, [ref], width ;// |c4|c3|c2|c1|
+ LDR tmp3, [ref], width ;// |g4|g3|g2|g1|
+ LDR tmp4, [ref], width ;// |m4|m3|m2|m1|
+ LDR tmp5, [ref], width ;// |r4|r3|r2|r1|
+ LDR tmp6, [ref], width ;// |t4|t3|t2|t1|
+
+ ;// first four pixels
+ UXTB16 tmpa, tmp3 ;// |g3|g1|
+ UXTAB16 tmpa, tmpa, tmp4 ;// |g3+m3|g1+m1|
+ UXTB16 tmpb, tmp2 ;// |c3|c1|
+ ADD tmpa, tmpa, tmpa, LSL #2 ;// 5(G+M)
+
+ UXTAB16 tmpb, tmpb, tmp5 ;// |c3+r3|c1+r1|
+ ADD tmpa, plus16, tmpa, LSL #2 ;// 16+20(G+M)
+ UXTAB16 tmpa, tmpa, tmp1 ;// 16+20(G+M)+A
+ UXTAB16 tmpa, tmpa, tmp6 ;// 16+20(G+M)+A+T
+
+ ADD tmpb, tmpb, tmpb, LSL #2 ;// 5(C+R)
+ SSUB16 tmpa, tmpa, tmpb ;// 16+20(G+M)+(A+T)-5(C+R)
+
+ USAT16 tmpb, #13, tmpa ;// saturate
+ LDR res, = 0x00FF00FF
+ UXTB16 tmpa, tmp3, ROR #8 ;// |g4|g2|
+ UXTAB16 tmpa, tmpa, tmp4, ROR #8 ;// |g4+m4|g2+m2|
+ AND res, res, tmpb, LSR #5 ;// mask and divide by 32
+
+ ADD tmpa, tmpa, tmpa, LSL #2 ;// 5(G+M)
+ UXTB16 tmpb, tmp2, ROR #8 ;// |c4|c2|
+ ADD tmpa, plus16, tmpa, LSL #2 ;// 16+20(G+M)
+ UXTAB16 tmpb, tmpb, tmp5, ROR #8 ;// |c4+r4|c2+r2|
+ UXTAB16 tmpa, tmpa, tmp1, ROR #8 ;// 16+20(G+M)+A
+ UXTAB16 tmpa, tmpa, tmp6, ROR #8 ;// 16+20(G+M)+A+T
+
+ ADD tmpb, tmpb, tmpb, LSL #2 ;// 5(C+R)
+ SSUB16 tmpa, tmpa, tmpb ;// 16+20(G+M)+(A+T)-5(C+R)
+
+ USAT16 tmpb, #13, tmpa ;// saturate
+ LDR tmp1, [mb]
+ LDR tmpa, = 0xFF00FF00
+ MVN tmp1, tmp1
+ AND tmpa, tmpa, tmpb, LSL #3 ;// mask and divede by 32
+ ORR res, res, tmpa
+
+ LDR tmpa, = 0x80808080
+ UHSUB8 res, res, tmp1 ;// bilinear interpolation
+ LDR tmp1, [ref], width ;// load next row
+ EOR res, res, tmpa ;// correct sign
+
+ STR res, [mb], #16 ;// next row (mb)
+
+
+ ;// tmp2 = |a4|a3|a2|a1|
+ ;// tmp3 = |c4|c3|c2|c1|
+ ;// tmp4 = |g4|g3|g2|g1|
+ ;// tmp5 = |m4|m3|m2|m1|
+ ;// tmp6 = |r4|r3|r2|r1|
+ ;// tmp1 = |t4|t3|t2|t1|
+
+ ;// second four pixels
+ UXTB16 tmpa, tmp4 ;// |g3|g1|
+ UXTAB16 tmpa, tmpa, tmp5 ;// |g3+m3|g1+m1|
+ UXTB16 tmpb, tmp3 ;// |c3|c1|
+ ADD tmpa, tmpa, tmpa, LSL #2 ;// 5(G+M)
+ UXTAB16 tmpb, tmpb, tmp6 ;// |c3+r3|c1+r1|
+ ADD tmpa, plus16, tmpa, LSL #2 ;// 16+20(G+M)
+ UXTAB16 tmpa, tmpa, tmp2 ;// 16+20(G+M)+A
+ UXTAB16 tmpa, tmpa, tmp1 ;// 16+20(G+M)+A+T
+
+ ADD tmpb, tmpb, tmpb, LSL #2 ;// 5(C+R)
+ SSUB16 tmpa, tmpa, tmpb ;// 16+20(G+M)+(A+T)-5(C+R)
+
+ USAT16 tmpb, #13, tmpa ;// saturate
+ LDR res, = 0x00FF00FF
+ UXTB16 tmpa, tmp4, ROR #8 ;// |g4|g2|
+ UXTAB16 tmpa, tmpa, tmp5, ROR #8 ;// |g4+m4|g2+m2|
+ AND res, res, tmpb, LSR #5 ;// mask and divide by 32
+
+ ADD tmpa, tmpa, tmpa, LSL #2 ;// 5(G+M)
+ UXTB16 tmpb, tmp3, ROR #8 ;// |c4|c2|
+ ADD tmpa, plus16, tmpa, LSL #2 ;// 16+20(G+M)
+ UXTAB16 tmpb, tmpb, tmp6, ROR #8 ;// |c4+r4|c2+r2|
+ UXTAB16 tmpa, tmpa, tmp2, ROR #8 ;// 16+20(G+M)+A
+ UXTAB16 tmpa, tmpa, tmp1, ROR #8 ;// 16+20(G+M)+A+T
+
+ ADD tmpb, tmpb, tmpb, LSL #2 ;// 5(C+R)
+ SSUB16 tmpa, tmpa, tmpb ;// 16+20(G+M)+(A+T)-5(C+R)
+
+ USAT16 tmpb, #13, tmpa ;// saturate
+ LDR tmp2, [mb]
+ LDR tmpa, = 0xFF00FF00
+ MVN tmp2, tmp2
+
+ AND tmpa, tmpa, tmpb, LSL #3 ;// mask and divide by 32
+ ORR res, res, tmpa
+ LDR tmpa, = 0x80808080
+ UHSUB8 res, res, tmp2 ;// bilinear interpolation
+ LDR tmp2, [ref], width ;// load next row
+ EOR res, res, tmpa ;// correct sign
+ STR res, [mb], #16 ;// next row
+
+ ;// tmp3 = |a4|a3|a2|a1|
+ ;// tmp4 = |c4|c3|c2|c1|
+ ;// tmp5 = |g4|g3|g2|g1|
+ ;// tmp6 = |m4|m3|m2|m1|
+ ;// tmp1 = |r4|r3|r2|r1|
+ ;// tmp2 = |t4|t3|t2|t1|
+
+ ;// third four pixels
+ UXTB16 tmpa, tmp5 ;// |g3|g1|
+ UXTAB16 tmpa, tmpa, tmp6 ;// |g3+m3|g1+m1|
+ UXTB16 tmpb, tmp4 ;// |c3|c1|
+ ADD tmpa, tmpa, tmpa, LSL #2 ;// 5(G+M)
+ UXTAB16 tmpb, tmpb, tmp1 ;// |c3+r3|c1+r1|
+ ADD tmpa, plus16, tmpa, LSL #2 ;// 16+20(G+M)
+ UXTAB16 tmpa, tmpa, tmp3 ;// 16+20(G+M)+A
+ UXTAB16 tmpa, tmpa, tmp2 ;// 16+20(G+M)+A+T
+
+ ADD tmpb, tmpb, tmpb, LSL #2 ;// 5(C+R)
+ SSUB16 tmpa, tmpa, tmpb ;// 16+20(G+M)+(A+T)-5(C+R)
+
+ USAT16 tmpb, #13, tmpa ;// saturate
+ LDR res, = 0x00FF00FF
+ UXTB16 tmpa, tmp5, ROR #8 ;// |g4|g2|
+ UXTAB16 tmpa, tmpa, tmp6, ROR #8 ;// |g4+m4|g2+m2|
+ AND res, res, tmpb, LSR #5 ;// mask and divide by 32
+
+ ADD tmpa, tmpa, tmpa, LSL #2 ;// 5(G+M)
+ UXTB16 tmpb, tmp4, ROR #8 ;// |c4|c2|
+ ADD tmpa, plus16, tmpa, LSL #2 ;// 16+20(G+M)
+ UXTAB16 tmpb, tmpb, tmp1, ROR #8 ;// |c4+r4|c2+r2|
+ UXTAB16 tmpa, tmpa, tmp3, ROR #8 ;// 16+20(G+M)+A
+ UXTAB16 tmpa, tmpa, tmp2, ROR #8 ;// 16+20(G+M)+A+T
+
+
+ ADD tmpb, tmpb, tmpb, LSL #2 ;// 5(C+R)
+ SSUB16 tmpa, tmpa, tmpb ;// 16+20(G+M)+(A+T)-5(C+R)
+
+ USAT16 tmpb, #13, tmpa ;// saturate
+ LDR tmp3, [mb]
+ LDR tmpa, = 0xFF00FF00
+ MVN tmp3, tmp3
+
+ AND tmpa, tmpa, tmpb, LSL #3 ;// mask and divide by 32
+ ORR res, res, tmpa
+ LDR tmpa, = 0x80808080
+ UHSUB8 res, res, tmp3 ;// bilinear interpolation
+ LDR tmp3, [ref] ;// load next row
+ EOR res, res, tmpa ;// correct sign
+ STR res, [mb], #16 ;// next row
+
+ ;// tmp4 = |a4|a3|a2|a1|
+ ;// tmp5 = |c4|c3|c2|c1|
+ ;// tmp6 = |g4|g3|g2|g1|
+ ;// tmp1 = |m4|m3|m2|m1|
+ ;// tmp2 = |r4|r3|r2|r1|
+ ;// tmp3 = |t4|t3|t2|t1|
+
+ ;// fourth four pixels
+ UXTB16 tmpa, tmp6 ;// |g3|g1|
+ UXTAB16 tmpa, tmpa, tmp1 ;// |g3+m3|g1+m1|
+ UXTB16 tmpb, tmp5 ;// |c3|c1|
+ ADD tmpa, tmpa, tmpa, LSL #2 ;// 5(G+M)
+ UXTAB16 tmpb, tmpb, tmp2 ;// |c3+r3|c1+r1|
+ ADD tmpa, plus16, tmpa, LSL #2 ;// 16+20(G+M)
+ UXTAB16 tmpa, tmpa, tmp4 ;// 16+20(G+M)+A
+ UXTAB16 tmpa, tmpa, tmp3 ;// 16+20(G+M)+A+T
+
+ ADD tmpb, tmpb, tmpb, LSL #2 ;// 5(C+R)
+ SSUB16 tmpa, tmpa, tmpb ;// 16+20(G+M)+(A+T)-5(C+R)
+
+ USAT16 tmpb, #13, tmpa ;// saturate
+ LDR res, = 0x00FF00FF
+ UXTB16 tmpa, tmp6, ROR #8 ;// |g4|g2|
+ UXTAB16 tmpa, tmpa, tmp1, ROR #8 ;// |g4+m4|g2+m2|
+ AND res, res, tmpb, LSR #5 ;// mask and divide by 32
+
+ ADD tmpa, tmpa, tmpa, LSL #2 ;// 5(G+M)
+ UXTB16 tmpb, tmp5, ROR #8 ;// |c4|c2|
+ ADD tmpa, plus16, tmpa, LSL #2 ;// 16+20(G+M)
+ UXTAB16 tmpb, tmpb, tmp2, ROR #8 ;// |c4+r4|c2+r2|
+ UXTAB16 tmpa, tmpa, tmp4, ROR #8 ;// 16+20(G+M)+A
+ UXTAB16 tmpa, tmpa, tmp3, ROR #8 ;// 16+20(G+M)+A+T
+
+ ADD tmpb, tmpb, tmpb, LSL #2 ;// 5(C+R)
+ SSUB16 tmpa, tmpa, tmpb ;// 16+20(G+M)+(A+T)-5(C+R)
+
+ USAT16 tmpb, #13, tmpa ;// saturate
+ LDR tmp5, [mb]
+ LDR tmp4, = 0xFF00FF00
+ MVN tmp5, tmp5
+
+ AND tmpa, tmp4, tmpb, LSL #3 ;// mask and divide by 32
+ ORR res, res, tmpa
+ LDR tmpa, = 0x80808080
+ UHSUB8 res, res, tmp5 ;// bilinear interpolation
+
+ ;// decrement loop_x counter
+ SUBS count, count, #4<<28 ;// decrement x loop counter
+
+ ;// calculate "ref" address for next round
+ SUB ref, ref, width, LSL #3 ;// ref -= 8*width;
+ ADD ref, ref, #4 ;// next column (4 pixels)
+
+ EOR res, res, tmpa ;// correct sign
+ STR res, [mb], #-44
+
+ BCS loop_x
+
+ ADDS mb, mb, #64 ;// set Carry=0
+ ADD ref, ref, width, LSL #2 ;// ref += 4*width
+ AND tmp6, count, #0x00F00000 ;// partWidth-1
+ SBC ref, ref, tmp6, LSR #20 ;// -(partWidth-1)-1
+ SBC mb, mb, tmp6, LSR #20 ;// -(partWidth-1)-1
+
+ ADDS count, count, #0xC << 24 ;// decrement y loop counter
+ BGE loop_y
+
+ ADD sp, sp, #0x1f4
+ LDMFD sp!, {r4-r11, pc}
+
+ END
diff --git a/media/libstagefright/codecs/on2/h264dec/source/arm11_asm/h264bsd_interpolate_mid_hor.s b/media/libstagefright/codecs/on2/h264dec/source/arm11_asm/h264bsd_interpolate_mid_hor.s
new file mode 100755
index 0000000..a81aed7
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/arm11_asm/h264bsd_interpolate_mid_hor.s
@@ -0,0 +1,163 @@
+; 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.
+
+;-------------------------------------------------------------------------------
+;--
+;-- Abstract : ARMv6 optimized version horizontal part of
+;-- h264bsdInterpolateMid functions
+;--
+;-------------------------------------------------------------------------------
+
+
+ IF :DEF: H264DEC_WINASM
+ ;// We dont use REQUIRE8 and PRESERVE8 for winasm
+ ELSE
+ REQUIRE8
+ PRESERVE8
+ ENDIF
+
+ AREA |.text|, CODE
+
+
+;// Register allocation
+
+ref RN 0 ;// pointer to current position in reference image
+mb RN 1 ;// pointer to current position in interpolated mb
+count RN 2 ;// bit-packed width and count values
+
+x_2_0 RN 4
+x_3_1 RN 5
+x_6_4 RN 6
+x_7_5 RN 7
+
+tmp1 RN 8
+tmp2 RN 9
+tmp3 RN 10
+tmp4 RN 11
+
+mult_20_01 RN 12 ;// [20, 1]
+mult_20_m5 RN 14 ;// [20, -5]
+
+
+ EXPORT h264bsdInterpolateMidHorPart
+
+;// Horizontal filter approach
+;//
+;// Basic idea in horizontal filtering is to adjust coefficients
+;// like below. Calculation is done with 16-bit maths.
+;//
+;// Reg x_2_0 x_3_1 x_6_4 x_7_5 x_2_0
+;// [ 2 0 ] [ 3 1 ] [ 6 4 ] [ 7 5 ] [ 10 8 ] ...
+;// y_0 = 20 1 20 -5 -5 1
+;// y_1 = -5 20 1 1 20 -5
+;// y_2 = 1 -5 -5 20 1 20
+;// y_3 = 1 20 -5 -5 20 1
+
+
+h264bsdInterpolateMidHorPart
+ STMFD sp!, {r4-r11, lr}
+
+ ;// pack values to count register
+ ;// [31:28] loop_x (partWidth-1)
+ ;// [27:24] loop_y (partHeight-1)
+ ;// [23:20] partWidth-1
+ ;// [19:16] partHeight-1
+ ;// [15:00] width
+
+
+ LDR mult_20_01, = 0x00140001
+ LDR mult_20_m5, = 0x0014FFFB
+ AND tmp3, count, #0x000F0000 ;// partWidth-1
+loop_y
+ LDR x_3_1, [ref, #-8]
+ ADD count, count, tmp3, LSL #12
+ LDR x_7_5, [ref, #-4]
+ UXTB16 x_2_0, x_3_1
+ UXTB16 x_3_1, x_3_1, ROR #8
+ UXTB16 x_6_4, x_7_5
+
+loop_x
+ UXTB16 x_7_5, x_7_5, ROR #8
+
+ SMUAD tmp1, x_2_0, mult_20_01
+ SMULTB tmp2, x_2_0, mult_20_m5
+ SMULTB tmp3, x_2_0, mult_20_01
+ SMULTB tmp4, x_3_1, mult_20_01
+
+ SMLAD tmp1, x_3_1, mult_20_m5, tmp1
+ SMLAD tmp2, x_3_1, mult_20_01, tmp2
+ SMLATB tmp3, x_3_1, mult_20_m5, tmp3
+ LDR x_3_1, [ref], #4
+ SMLAD tmp4, x_6_4, mult_20_m5, tmp4
+
+ SMLABB tmp1, x_6_4, mult_20_m5, tmp1
+ SMLADX tmp2, x_6_4, mult_20_01, tmp2
+ SMLADX tmp3, x_6_4, mult_20_m5, tmp3
+ SMLADX tmp4, x_7_5, mult_20_m5, tmp4
+
+ SMLABB tmp1, x_7_5, mult_20_01, tmp1
+ SMLABB tmp2, x_7_5, mult_20_m5, tmp2
+ UXTB16 x_2_0, x_3_1
+ SMLADX tmp3, x_7_5, mult_20_01, tmp3
+ SMLABB tmp4, x_2_0, mult_20_01, tmp4
+
+ SUBS count, count, #4<<28
+ STR tmp1, [mb], #4
+ STR tmp2, [mb], #4
+ STR tmp3, [mb], #4
+ STR tmp4, [mb], #4
+ BCC next_y
+
+ UXTB16 x_3_1, x_3_1, ROR #8
+
+ SMUAD tmp1, x_6_4, mult_20_01
+ SMULTB tmp2, x_6_4, mult_20_m5
+ SMULTB tmp3, x_6_4, mult_20_01
+ SMULTB tmp4, x_7_5, mult_20_01
+
+ SMLAD tmp1, x_7_5, mult_20_m5, tmp1
+ SMLAD tmp2, x_7_5, mult_20_01, tmp2
+ SMLATB tmp3, x_7_5, mult_20_m5, tmp3
+ LDR x_7_5, [ref], #4
+ SMLAD tmp4, x_2_0, mult_20_m5, tmp4
+
+ SMLABB tmp1, x_2_0, mult_20_m5, tmp1
+ SMLADX tmp2, x_2_0, mult_20_01, tmp2
+ SMLADX tmp3, x_2_0, mult_20_m5, tmp3
+ SMLADX tmp4, x_3_1, mult_20_m5, tmp4
+
+ SMLABB tmp1, x_3_1, mult_20_01, tmp1
+ SMLABB tmp2, x_3_1, mult_20_m5, tmp2
+ UXTB16 x_6_4, x_7_5
+ SMLADX tmp3, x_3_1, mult_20_01, tmp3
+ SMLABB tmp4, x_6_4, mult_20_01, tmp4
+
+ SUBS count, count, #4<<28
+ STR tmp1, [mb], #4
+ STR tmp2, [mb], #4
+ STR tmp3, [mb], #4
+ STR tmp4, [mb], #4
+ BCS loop_x
+
+next_y
+ AND tmp3, count, #0x000F0000 ;// partWidth-1
+ SMLABB ref, count, mult_20_01, ref ;// +width
+ SBC ref, ref, tmp3, LSR #16 ;// -(partWidth-1)-1
+ ADDS count, count, #(1<<28)-(1<<20)
+ BGE loop_y
+
+ LDMFD sp!, {r4-r11, pc}
+
+ END
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/arm11_asm/h264bsd_interpolate_ver_half.s b/media/libstagefright/codecs/on2/h264dec/source/arm11_asm/h264bsd_interpolate_ver_half.s
new file mode 100755
index 0000000..244fc6f
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/arm11_asm/h264bsd_interpolate_ver_half.s
@@ -0,0 +1,347 @@
+; 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.
+
+;-------------------------------------------------------------------------------
+;--
+;-- Abstract : ARMv6 optimized version of h264bsdInterpolateVerHalf function
+;--
+;-------------------------------------------------------------------------------
+
+
+ IF :DEF: H264DEC_WINASM
+ ;// We dont use REQUIRE8 and PRESERVE8 for winasm
+ ELSE
+ REQUIRE8
+ PRESERVE8
+ ENDIF
+
+ AREA |.text|, CODE
+
+;// h264bsdInterpolateVerHalf register allocation
+
+ref RN 0
+
+mb RN 1
+buff RN 1
+
+count RN 2
+x0 RN 2
+
+res RN 3
+y0 RN 3
+
+tmp1 RN 4
+
+tmp2 RN 5
+height RN 5
+
+tmp3 RN 6
+partW RN 6
+
+tmp4 RN 7
+partH RN 7
+
+tmp5 RN 8
+tmp6 RN 9
+
+tmpa RN 10
+tmpb RN 11
+width RN 12
+
+plus16 RN 14
+
+
+;// function exports and imports
+
+ IMPORT h264bsdFillBlock
+
+ EXPORT h264bsdInterpolateVerHalf
+
+;// Approach to vertical interpolation
+;//
+;// Interpolation is done by using 32-bit loads and stores
+;// and by using 16 bit arithmetic. 4x4 block is processed
+;// in each round.
+;//
+;// |a_11|a_11|a_11|a_11|...|a_1n|a_1n|a_1n|a_1n|
+;// |b_11|b_11|b_11|b_11|...|b_1n|b_1n|b_1n|b_1n|
+;// |c_11|c_11|c_11|c_11|...|c_1n|c_1n|c_1n|c_1n|
+;// |d_11|d_11|d_11|d_11|...|d_1n|d_1n|d_1n|d_1n|
+;// ..
+;// ..
+;// |a_m1|a_m1|a_m1|a_m1|...
+;// |b_m1|b_m1|b_m1|b_m1|...
+;// |c_m1|c_m1|c_m1|c_m1|...
+;// |d_m1|d_m1|d_m1|d_m1|...
+
+h264bsdInterpolateVerHalf
+ STMFD sp!, {r0-r11, lr}
+ SUB sp, sp, #0x1e4
+
+ CMP x0, #0
+ BLT do_fill ;// (x0 < 0)
+ LDR partW, [sp,#0x220] ;// partWidth
+ ADD tmp5, x0, partW ;// (x0+partWidth)
+ LDR width, [sp,#0x218] ;// width
+ CMP tmp5, width
+ BHI do_fill ;// (x0+partW)>width
+
+ CMP y0, #0
+ BLT do_fill ;// (y0 < 0)
+ LDR partH, [sp,#0x224] ;// partHeight
+ ADD tmp6, y0, partH ;// (y0+partHeight)
+ ADD tmp6, tmp6, #5 ;// (y0+partH+5)
+ LDR height, [sp,#0x21c] ;// height
+ CMP tmp6, height
+ BLS skip_fill ;// no overfill needed
+
+
+do_fill
+ LDR partH, [sp,#0x224] ;// partHeight
+ ADD tmp5, partH, #5 ;// r2 = partH + 5;
+ LDR height, [sp,#0x21c] ;// height
+ LDR partW, [sp,#0x220] ;// partWidth
+ STMIB sp, {height, partW} ;// sp+4 = height, sp+8 = partWidth
+ STR tmp5, [sp,#0xc] ;// sp+c partHeight+5
+ STR partW, [sp,#0x10] ;// sp+10 = partWidth
+ LDR width, [sp,#0x218] ;// width
+ STR width, [sp,#0] ;// sp+0 = width
+ ADD buff, sp, #0x28 ;// buff = p1[21*21/4+1]
+ BL h264bsdFillBlock
+
+ MOV x0, #0
+ STR x0,[sp,#0x1ec] ;// x0 = 0
+ STR x0,[sp,#0x1f0] ;// y0 = 0
+ ADD ref,sp,#0x28 ;// ref = p1
+ STR partW, [sp,#0x218]
+
+
+skip_fill
+ LDR x0 ,[sp,#0x1ec] ;// x0
+ LDR y0 ,[sp,#0x1f0] ;// y0
+ LDR width, [sp,#0x218] ;// width
+ MLA tmp6, width, y0, x0 ;// y0*width+x0
+ ADD ref, ref, tmp6 ;// ref += y0*width+x0
+ LDR mb, [sp, #0x1e8] ;// mb
+
+ ADD count, partW, partH, LSL #16 ;// |partH|partW|
+ LDR tmp5, = 0x00010001
+ SSUB16 count, count, tmp5; ;// |partH-1|partW-1|
+ LDR plus16, = 0x00100010
+
+ AND tmp1, count, #0x000000FF ;// partWidth
+
+
+loop_y
+ ADD count, count, tmp1, LSL #24 ;// partWidth-1 to top byte
+
+loop_x
+ LDR tmp1, [ref], width ;// |a4|a3|a2|a1|
+ LDR tmp2, [ref], width ;// |c4|c3|c2|c1|
+ LDR tmp3, [ref], width ;// |g4|g3|g2|g1|
+ LDR tmp4, [ref], width ;// |m4|m3|m2|m1|
+ LDR tmp5, [ref], width ;// |r4|r3|r2|r1|
+ LDR tmp6, [ref], width ;// |t4|t3|t2|t1|
+
+ ;// first four pixels
+ UXTB16 tmpa, tmp3 ;// |g3|g1|
+ UXTAB16 tmpa, tmpa, tmp4 ;// |g3+m3|g1+m1|
+ UXTB16 tmpb, tmp2 ;// |c3|c1|
+ ADD tmpa, tmpa, tmpa, LSL #2 ;// 5(G+M)
+
+ UXTAB16 tmpb, tmpb, tmp5 ;// |c3+r3|c1+r1|
+ ADD tmpa, plus16, tmpa, LSL #2 ;// 16+20(G+M)
+ UXTAB16 tmpa, tmpa, tmp1 ;// 16+20(G+M)+A
+ UXTAB16 tmpa, tmpa, tmp6 ;// 16+20(G+M)+A+T
+
+ ADD tmpb, tmpb, tmpb, LSL #2 ;// 5(C+R)
+ SSUB16 tmpa, tmpa, tmpb ;// 16+20(G+M)+(A+T)-5(C+R)
+
+ USAT16 tmpb, #13, tmpa ;// saturate
+ LDR res, = 0x00FF00FF
+ UXTB16 tmpa, tmp3, ROR #8 ;// |g4|g2|
+ UXTAB16 tmpa, tmpa, tmp4, ROR #8 ;// |g4+m4|g2+m2|
+ AND res, res, tmpb, LSR #5 ;// mask and divide by 32
+
+ ADD tmpa, tmpa, tmpa, LSL #2 ;// 5(G+M)
+ UXTB16 tmpb, tmp2, ROR #8 ;// |c4|c2|
+ ADD tmpa, plus16, tmpa, LSL #2 ;// 16+20(G+M)
+ UXTAB16 tmpb, tmpb, tmp5, ROR #8 ;// |c4+r4|c2+r2|
+ UXTAB16 tmpa, tmpa, tmp1, ROR #8 ;// 16+20(G+M)+A
+ UXTAB16 tmpa, tmpa, tmp6, ROR #8 ;// 16+20(G+M)+A+T
+
+ ADD tmpb, tmpb, tmpb, LSL #2 ;// 5(C+R)
+ SSUB16 tmpa, tmpa, tmpb ;// 16+20(G+M)+(A+T)-5(C+R)
+
+ USAT16 tmpb, #13, tmpa ;// saturate
+ LDR tmp1, [ref], width
+ LDR tmpa, = 0xFF00FF00
+
+ AND tmpa, tmpa, tmpb, LSL #3 ;// mask and divede by 32
+ ORR res, res, tmpa
+ STR res, [mb], #16 ;// next row (mb)
+
+ ;// tmp2 = |a4|a3|a2|a1|
+ ;// tmp3 = |c4|c3|c2|c1|
+ ;// tmp4 = |g4|g3|g2|g1|
+ ;// tmp5 = |m4|m3|m2|m1|
+ ;// tmp6 = |r4|r3|r2|r1|
+ ;// tmp1 = |t4|t3|t2|t1|
+
+ ;// second four pixels
+ UXTB16 tmpa, tmp4 ;// |g3|g1|
+ UXTAB16 tmpa, tmpa, tmp5 ;// |g3+m3|g1+m1|
+ UXTB16 tmpb, tmp3 ;// |c3|c1|
+ ADD tmpa, tmpa, tmpa, LSL #2 ;// 5(G+M)
+ UXTAB16 tmpb, tmpb, tmp6 ;// |c3+r3|c1+r1|
+ ADD tmpa, plus16, tmpa, LSL #2 ;// 16+20(G+M)
+ UXTAB16 tmpa, tmpa, tmp2 ;// 16+20(G+M)+A
+ UXTAB16 tmpa, tmpa, tmp1 ;// 16+20(G+M)+A+T
+
+ ADD tmpb, tmpb, tmpb, LSL #2 ;// 5(C+R)
+ SSUB16 tmpa, tmpa, tmpb ;// 16+20(G+M)+(A+T)-5(C+R)
+
+ USAT16 tmpb, #13, tmpa ;// saturate
+ LDR res, = 0x00FF00FF
+ UXTB16 tmpa, tmp4, ROR #8 ;// |g4|g2|
+ UXTAB16 tmpa, tmpa, tmp5, ROR #8 ;// |g4+m4|g2+m2|
+ AND res, res, tmpb, LSR #5 ;// mask and divide by 32
+
+ ADD tmpa, tmpa, tmpa, LSL #2 ;// 5(G+M)
+ UXTB16 tmpb, tmp3, ROR #8 ;// |c4|c2|
+ ADD tmpa, plus16, tmpa, LSL #2 ;// 16+20(G+M)
+ UXTAB16 tmpb, tmpb, tmp6, ROR #8 ;// |c4+r4|c2+r2|
+ UXTAB16 tmpa, tmpa, tmp2, ROR #8 ;// 16+20(G+M)+A
+ UXTAB16 tmpa, tmpa, tmp1, ROR #8 ;// 16+20(G+M)+A+T
+
+ ADD tmpb, tmpb, tmpb, LSL #2 ;// 5(C+R)
+ SSUB16 tmpa, tmpa, tmpb ;// 16+20(G+M)+(A+T)-5(C+R)
+
+ USAT16 tmpb, #13, tmpa ;// saturate
+ LDR tmp2, [ref], width
+ LDR tmpa, = 0xFF00FF00
+
+ AND tmpa, tmpa, tmpb, LSL #3 ;// mask and divide by 32
+ ORR res, res, tmpa
+ STR res, [mb], #16 ;// next row
+
+ ;// tmp3 = |a4|a3|a2|a1|
+ ;// tmp4 = |c4|c3|c2|c1|
+ ;// tmp5 = |g4|g3|g2|g1|
+ ;// tmp6 = |m4|m3|m2|m1|
+ ;// tmp1 = |r4|r3|r2|r1|
+ ;// tmp2 = |t4|t3|t2|t1|
+
+ ;// third four pixels
+ UXTB16 tmpa, tmp5 ;// |g3|g1|
+ UXTAB16 tmpa, tmpa, tmp6 ;// |g3+m3|g1+m1|
+ UXTB16 tmpb, tmp4 ;// |c3|c1|
+ ADD tmpa, tmpa, tmpa, LSL #2 ;// 5(G+M)
+ UXTAB16 tmpb, tmpb, tmp1 ;// |c3+r3|c1+r1|
+ ADD tmpa, plus16, tmpa, LSL #2 ;// 16+20(G+M)
+ UXTAB16 tmpa, tmpa, tmp3 ;// 16+20(G+M)+A
+ UXTAB16 tmpa, tmpa, tmp2 ;// 16+20(G+M)+A+T
+
+ ADD tmpb, tmpb, tmpb, LSL #2 ;// 5(C+R)
+ SSUB16 tmpa, tmpa, tmpb ;// 16+20(G+M)+(A+T)-5(C+R)
+
+ USAT16 tmpb, #13, tmpa ;// saturate
+ LDR res, = 0x00FF00FF
+ UXTB16 tmpa, tmp5, ROR #8 ;// |g4|g2|
+ UXTAB16 tmpa, tmpa, tmp6, ROR #8 ;// |g4+m4|g2+m2|
+ AND res, res, tmpb, LSR #5 ;// mask and divide by 32
+
+ ADD tmpa, tmpa, tmpa, LSL #2 ;// 5(G+M)
+ UXTB16 tmpb, tmp4, ROR #8 ;// |c4|c2|
+ ADD tmpa, plus16, tmpa, LSL #2 ;// 16+20(G+M)
+ UXTAB16 tmpb, tmpb, tmp1, ROR #8 ;// |c4+r4|c2+r2|
+ UXTAB16 tmpa, tmpa, tmp3, ROR #8 ;// 16+20(G+M)+A
+ UXTAB16 tmpa, tmpa, tmp2, ROR #8 ;// 16+20(G+M)+A+T
+
+
+ ADD tmpb, tmpb, tmpb, LSL #2 ;// 5(C+R)
+ SSUB16 tmpa, tmpa, tmpb ;// 16+20(G+M)+(A+T)-5(C+R)
+
+ USAT16 tmpb, #13, tmpa ;// saturate
+ LDR tmp3, [ref]
+ LDR tmpa, = 0xFF00FF00
+
+ ;// decrement loop_x counter
+ SUBS count, count, #4<<24 ;// (partWidth-1) -= 4;
+
+ AND tmpa, tmpa, tmpb, LSL #3 ;// mask and divide by 32
+ ORR res, res, tmpa
+ STR res, [mb], #16 ;// next row
+
+ ;// tmp4 = |a4|a3|a2|a1|
+ ;// tmp5 = |c4|c3|c2|c1|
+ ;// tmp6 = |g4|g3|g2|g1|
+ ;// tmp1 = |m4|m3|m2|m1|
+ ;// tmp2 = |r4|r3|r2|r1|
+ ;// tmp3 = |t4|t3|t2|t1|
+
+ ;// fourth four pixels
+ UXTB16 tmpa, tmp6 ;// |g3|g1|
+ UXTAB16 tmpa, tmpa, tmp1 ;// |g3+m3|g1+m1|
+ UXTB16 tmpb, tmp5 ;// |c3|c1|
+ ADD tmpa, tmpa, tmpa, LSL #2 ;// 5(G+M)
+ UXTAB16 tmpb, tmpb, tmp2 ;// |c3+r3|c1+r1|
+ ADD tmpa, plus16, tmpa, LSL #2 ;// 16+20(G+M)
+ UXTAB16 tmpa, tmpa, tmp4 ;// 16+20(G+M)+A
+ UXTAB16 tmpa, tmpa, tmp3 ;// 16+20(G+M)+A+T
+
+ ADD tmpb, tmpb, tmpb, LSL #2 ;// 5(C+R)
+ SSUB16 tmpa, tmpa, tmpb ;// 16+20(G+M)+(A+T)-5(C+R)
+
+ USAT16 tmpb, #13, tmpa ;// saturate
+ LDR res, = 0x00FF00FF
+ UXTB16 tmpa, tmp6, ROR #8 ;// |g4|g2|
+ UXTAB16 tmpa, tmpa, tmp1, ROR #8 ;// |g4+m4|g2+m2|
+ AND res, res, tmpb, LSR #5 ;// mask and divide by 32
+
+ ADD tmpa, tmpa, tmpa, LSL #2 ;// 5(G+M)
+ UXTB16 tmpb, tmp5, ROR #8 ;// |c4|c2|
+ ADD tmpa, plus16, tmpa, LSL #2 ;// 16+20(G+M)
+ UXTAB16 tmpb, tmpb, tmp2, ROR #8 ;// |c4+r4|c2+r2|
+ UXTAB16 tmpa, tmpa, tmp4, ROR #8 ;// 16+20(G+M)+A
+ UXTAB16 tmpa, tmpa, tmp3, ROR #8 ;// 16+20(G+M)+A+T
+
+ ADD tmpb, tmpb, tmpb, LSL #2 ;// 5(C+R)
+ SSUB16 tmpa, tmpa, tmpb ;// 16+20(G+M)+(A+T)-5(C+R)
+
+ USAT16 tmpb, #13, tmpa ;// saturate
+ LDR tmp4, = 0xFF00FF00
+
+ ;// calculate "ref" address for next round
+ SUB ref, ref, width, LSL #3 ;// ref -= 8*width;
+ ADD ref, ref, #4; ;// next column (4 pixels)
+ AND tmpa, tmp4, tmpb, LSL #3 ;// mask and divide by 32
+ ORR res, res, tmpa
+ STR res, [mb], #-44
+
+ BCS loop_x
+
+ ADDS count, count, #252<<16 ;// (partHeight-1) -= 4;
+ ADD ref, ref, width, LSL #2 ;// ref += 4*width
+ AND tmp1, count, #0x000000FF ;// partWidth-1
+ ADD tmp2, tmp1, #1 ;// partWidth
+ SUB ref, ref, tmp2 ;// ref -= partWidth
+ ADD mb, mb, #64;
+ SUB mb, mb, tmp2; ;// mb -= partWidth
+ BGE loop_y
+
+ ADD sp,sp,#0x1f4
+ LDMFD sp!, {r4-r11, pc}
+
+ END
diff --git a/media/libstagefright/codecs/on2/h264dec/source/arm11_asm/h264bsd_interpolate_ver_quarter.s b/media/libstagefright/codecs/on2/h264dec/source/arm11_asm/h264bsd_interpolate_ver_quarter.s
new file mode 100755
index 0000000..5266c85
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/arm11_asm/h264bsd_interpolate_ver_quarter.s
@@ -0,0 +1,374 @@
+; 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.
+
+;-------------------------------------------------------------------------------
+;--
+;-- Abstract : ARMv6 optimized version of h264bsdInterpolateVerQuarter function
+;--
+;-------------------------------------------------------------------------------
+
+ IF :DEF: H264DEC_WINASM
+ ;// We dont use REQUIRE8 and PRESERVE8 for winasm
+ ELSE
+ REQUIRE8
+ PRESERVE8
+ ENDIF
+
+ AREA |.text|, CODE
+
+;// h264bsdInterpolateVerQuarter register allocation
+
+ref RN 0
+
+mb RN 1
+buff RN 1
+
+count RN 2
+x0 RN 2
+
+res RN 3
+y0 RN 3
+
+tmp1 RN 4
+
+tmp2 RN 5
+height RN 5
+
+tmp3 RN 6
+partW RN 6
+
+tmp4 RN 7
+partH RN 7
+
+tmp5 RN 8
+tmp6 RN 9
+
+tmpa RN 10
+tmpb RN 11
+width RN 12
+
+plus16 RN 14
+
+
+;// function exports and imports
+
+ IMPORT h264bsdFillBlock
+
+ EXPORT h264bsdInterpolateVerQuarter
+
+;// Approach to vertical interpolation
+;//
+;// Interpolation is done by using 32-bit loads and stores
+;// and by using 16 bit arithmetic. 4x4 block is processed
+;// in each round.
+;//
+;// |a_11|a_11|a_11|a_11|...|a_1n|a_1n|a_1n|a_1n|
+;// |b_11|b_11|b_11|b_11|...|b_1n|b_1n|b_1n|b_1n|
+;// |c_11|c_11|c_11|c_11|...|c_1n|c_1n|c_1n|c_1n|
+;// |d_11|d_11|d_11|d_11|...|d_1n|d_1n|d_1n|d_1n|
+;// ..
+;// ..
+;// |a_m1|a_m1|a_m1|a_m1|...
+;// |b_m1|b_m1|b_m1|b_m1|...
+;// |c_m1|c_m1|c_m1|c_m1|...
+;// |d_m1|d_m1|d_m1|d_m1|...
+
+h264bsdInterpolateVerQuarter
+ STMFD sp!, {r0-r11, lr}
+ SUB sp, sp, #0x1e4
+
+ CMP x0, #0
+ BLT do_fill ;// (x0 < 0)
+ LDR partW, [sp,#0x220] ;// partWidth
+ ADD tmp5, x0, partW ;// (x0+partWidth)
+ LDR width, [sp,#0x218] ;// width
+ CMP tmp5, width
+ BHI do_fill ;// (x0+partW)>width
+
+ CMP y0, #0
+ BLT do_fill ;// (y0 < 0)
+ LDR partH, [sp,#0x224] ;// partHeight
+ ADD tmp6, y0, partH ;// (y0+partHeight)
+ ADD tmp6, tmp6, #5 ;// (y0+partH+5)
+ LDR height, [sp,#0x21c] ;// height
+ CMP tmp6, height
+ BLS skip_fill ;// no overfill needed
+
+
+do_fill
+ LDR partH, [sp,#0x224] ;// partHeight
+ ADD tmp5, partH, #5 ;// r2 = partH + 5;
+ LDR height, [sp,#0x21c] ;// height
+ LDR partW, [sp,#0x220] ;// partWidth
+ STMIB sp, {height, partW} ;// sp+4 = height, sp+8 = partWidth
+ STR tmp5, [sp,#0xc] ;// sp+c partHeight+5
+ STR partW, [sp,#0x10] ;// sp+10 = partWidth
+ LDR width, [sp,#0x218] ;// width
+ STR width, [sp,#0] ;// sp+0 = width
+ ADD buff, sp, #0x28 ;// buff = p1[21*21/4+1]
+ BL h264bsdFillBlock
+
+ MOV x0, #0
+ STR x0,[sp,#0x1ec] ;// x0 = 0
+ STR x0,[sp,#0x1f0] ;// y0 = 0
+ ADD ref,sp,#0x28 ;// ref = p1
+ STR partW, [sp,#0x218]
+
+
+skip_fill
+ LDR x0 ,[sp,#0x1ec] ;// x0
+ LDR y0 ,[sp,#0x1f0] ;// y0
+ LDR width, [sp,#0x218] ;// width
+ MLA tmp6, width, y0, x0 ;// y0*width+x0
+ ADD ref, ref, tmp6 ;// ref += y0*width+x0
+ LDR mb, [sp, #0x1e8] ;// mb
+
+ ADD count, partW, partH, LSL #8 ;// |xx|xx|partH|partW|
+ LDR tmp5, = 0x00010100
+ RSB count, tmp5, count, LSL #8 ;// |xx|partH-1|partW-1|xx|
+ LDR tmp2, [sp, #0x228] ;// verOffset
+ ADD count, count, tmp2 ;// |xx|partH-1|partW-1|verOffset|
+ LDR plus16, = 0x00100010
+
+ AND tmp1, count, #0x0000FF00 ;// partWidth
+
+
+loop_y
+ ADD count, count, tmp1, LSL #16 ;// partWidth-1 to top byte
+
+loop_x
+ LDR tmp1, [ref], width ;// |a4|a3|a2|a1|
+ LDR tmp2, [ref], width ;// |c4|c3|c2|c1|
+ LDR tmp3, [ref], width ;// |g4|g3|g2|g1|
+ LDR tmp4, [ref], width ;// |m4|m3|m2|m1|
+ LDR tmp5, [ref], width ;// |r4|r3|r2|r1|
+ LDR tmp6, [ref], width ;// |t4|t3|t2|t1|
+
+ ;// first four pixels
+ UXTB16 tmpa, tmp3 ;// |g3|g1|
+ UXTAB16 tmpa, tmpa, tmp4 ;// |g3+m3|g1+m1|
+ UXTB16 tmpb, tmp2 ;// |c3|c1|
+ ADD tmpa, tmpa, tmpa, LSL #2 ;// 5(G+M)
+
+ UXTAB16 tmpb, tmpb, tmp5 ;// |c3+r3|c1+r1|
+ ADD tmpa, plus16, tmpa, LSL #2 ;// 16+20(G+M)
+ UXTAB16 tmpa, tmpa, tmp1 ;// 16+20(G+M)+A
+ UXTAB16 tmpa, tmpa, tmp6 ;// 16+20(G+M)+A+T
+
+ ADD tmpb, tmpb, tmpb, LSL #2 ;// 5(C+R)
+ SSUB16 tmpa, tmpa, tmpb ;// 16+20(G+M)+(A+T)-5(C+R)
+
+ USAT16 tmpb, #13, tmpa ;// saturate
+ LDR res, = 0x00FF00FF
+ UXTB16 tmpa, tmp3, ROR #8 ;// |g4|g2|
+ UXTAB16 tmpa, tmpa, tmp4, ROR #8 ;// |g4+m4|g2+m2|
+ AND res, res, tmpb, LSR #5 ;// mask and divide by 32
+
+ ADD tmpa, tmpa, tmpa, LSL #2 ;// 5(G+M)
+ UXTB16 tmpb, tmp2, ROR #8 ;// |c4|c2|
+ ADD tmpa, plus16, tmpa, LSL #2 ;// 16+20(G+M)
+ UXTAB16 tmpb, tmpb, tmp5, ROR #8 ;// |c4+r4|c2+r2|
+ UXTAB16 tmpa, tmpa, tmp1, ROR #8 ;// 16+20(G+M)+A
+ UXTAB16 tmpa, tmpa, tmp6, ROR #8 ;// 16+20(G+M)+A+T
+
+ ADD tmpb, tmpb, tmpb, LSL #2 ;// 5(C+R)
+ SSUB16 tmpa, tmpa, tmpb ;// 16+20(G+M)+(A+T)-5(C+R)
+
+ USAT16 tmpb, #13, tmpa ;// saturate
+ MOVS tmp1, count, LSL #31 ;// update flags (verOffset)
+ LDR tmpa, = 0xFF00FF00
+ MVNEQ tmp1, tmp3 ;// select verOffset=0
+ MVNNE tmp1, tmp4 ;// select verOffset=1
+ AND tmpa, tmpa, tmpb, LSL #3 ;// mask and divede by 32
+ ORR res, res, tmpa
+
+ LDR tmpa, = 0x80808080
+ UHSUB8 res, res, tmp1 ;// bilinear interpolation
+ LDR tmp1, [ref], width ;// load next row
+ EOR res, res, tmpa ;// correct sign
+
+ STR res, [mb], #16 ;// next row (mb)
+
+
+ ;// tmp2 = |a4|a3|a2|a1|
+ ;// tmp3 = |c4|c3|c2|c1|
+ ;// tmp4 = |g4|g3|g2|g1|
+ ;// tmp5 = |m4|m3|m2|m1|
+ ;// tmp6 = |r4|r3|r2|r1|
+ ;// tmp1 = |t4|t3|t2|t1|
+
+ ;// second four pixels
+ UXTB16 tmpa, tmp4 ;// |g3|g1|
+ UXTAB16 tmpa, tmpa, tmp5 ;// |g3+m3|g1+m1|
+ UXTB16 tmpb, tmp3 ;// |c3|c1|
+ ADD tmpa, tmpa, tmpa, LSL #2 ;// 5(G+M)
+ UXTAB16 tmpb, tmpb, tmp6 ;// |c3+r3|c1+r1|
+ ADD tmpa, plus16, tmpa, LSL #2 ;// 16+20(G+M)
+ UXTAB16 tmpa, tmpa, tmp2 ;// 16+20(G+M)+A
+ UXTAB16 tmpa, tmpa, tmp1 ;// 16+20(G+M)+A+T
+
+ ADD tmpb, tmpb, tmpb, LSL #2 ;// 5(C+R)
+ SSUB16 tmpa, tmpa, tmpb ;// 16+20(G+M)+(A+T)-5(C+R)
+
+ USAT16 tmpb, #13, tmpa ;// saturate
+ LDR res, = 0x00FF00FF
+ UXTB16 tmpa, tmp4, ROR #8 ;// |g4|g2|
+ UXTAB16 tmpa, tmpa, tmp5, ROR #8 ;// |g4+m4|g2+m2|
+ AND res, res, tmpb, LSR #5 ;// mask and divide by 32
+
+ ADD tmpa, tmpa, tmpa, LSL #2 ;// 5(G+M)
+ UXTB16 tmpb, tmp3, ROR #8 ;// |c4|c2|
+ ADD tmpa, plus16, tmpa, LSL #2 ;// 16+20(G+M)
+ UXTAB16 tmpb, tmpb, tmp6, ROR #8 ;// |c4+r4|c2+r2|
+ UXTAB16 tmpa, tmpa, tmp2, ROR #8 ;// 16+20(G+M)+A
+ UXTAB16 tmpa, tmpa, tmp1, ROR #8 ;// 16+20(G+M)+A+T
+
+ ADD tmpb, tmpb, tmpb, LSL #2 ;// 5(C+R)
+ SSUB16 tmpa, tmpa, tmpb ;// 16+20(G+M)+(A+T)-5(C+R)
+
+ USAT16 tmpb, #13, tmpa ;// saturate
+ LDR tmpa, = 0xFF00FF00
+ MVNEQ tmp2, tmp4 ;// select verOffset=0
+ MVNNE tmp2, tmp5 ;// select verOffset=1
+
+ AND tmpa, tmpa, tmpb, LSL #3 ;// mask and divide by 32
+ ORR res, res, tmpa
+ LDR tmpa, = 0x80808080
+ UHSUB8 res, res, tmp2 ;// bilinear interpolation
+ LDR tmp2, [ref], width ;// load next row
+ EOR res, res, tmpa ;// correct sign
+ STR res, [mb], #16 ;// next row
+
+ ;// tmp3 = |a4|a3|a2|a1|
+ ;// tmp4 = |c4|c3|c2|c1|
+ ;// tmp5 = |g4|g3|g2|g1|
+ ;// tmp6 = |m4|m3|m2|m1|
+ ;// tmp1 = |r4|r3|r2|r1|
+ ;// tmp2 = |t4|t3|t2|t1|
+
+ ;// third four pixels
+ UXTB16 tmpa, tmp5 ;// |g3|g1|
+ UXTAB16 tmpa, tmpa, tmp6 ;// |g3+m3|g1+m1|
+ UXTB16 tmpb, tmp4 ;// |c3|c1|
+ ADD tmpa, tmpa, tmpa, LSL #2 ;// 5(G+M)
+ UXTAB16 tmpb, tmpb, tmp1 ;// |c3+r3|c1+r1|
+ ADD tmpa, plus16, tmpa, LSL #2 ;// 16+20(G+M)
+ UXTAB16 tmpa, tmpa, tmp3 ;// 16+20(G+M)+A
+ UXTAB16 tmpa, tmpa, tmp2 ;// 16+20(G+M)+A+T
+
+ ADD tmpb, tmpb, tmpb, LSL #2 ;// 5(C+R)
+ SSUB16 tmpa, tmpa, tmpb ;// 16+20(G+M)+(A+T)-5(C+R)
+
+ USAT16 tmpb, #13, tmpa ;// saturate
+ LDR res, = 0x00FF00FF
+ UXTB16 tmpa, tmp5, ROR #8 ;// |g4|g2|
+ UXTAB16 tmpa, tmpa, tmp6, ROR #8 ;// |g4+m4|g2+m2|
+ AND res, res, tmpb, LSR #5 ;// mask and divide by 32
+
+ ADD tmpa, tmpa, tmpa, LSL #2 ;// 5(G+M)
+ UXTB16 tmpb, tmp4, ROR #8 ;// |c4|c2|
+ ADD tmpa, plus16, tmpa, LSL #2 ;// 16+20(G+M)
+ UXTAB16 tmpb, tmpb, tmp1, ROR #8 ;// |c4+r4|c2+r2|
+ UXTAB16 tmpa, tmpa, tmp3, ROR #8 ;// 16+20(G+M)+A
+ UXTAB16 tmpa, tmpa, tmp2, ROR #8 ;// 16+20(G+M)+A+T
+
+
+ ADD tmpb, tmpb, tmpb, LSL #2 ;// 5(C+R)
+ SSUB16 tmpa, tmpa, tmpb ;// 16+20(G+M)+(A+T)-5(C+R)
+
+ USAT16 tmpb, #13, tmpa ;// saturate
+ LDR tmpa, = 0xFF00FF00
+ MVNEQ tmp3, tmp5 ;// select verOffset=0
+ MVNNE tmp3, tmp6 ;// select verOffset=1
+
+ AND tmpa, tmpa, tmpb, LSL #3 ;// mask and divide by 32
+ ORR res, res, tmpa
+ LDR tmpa, = 0x80808080
+ UHSUB8 res, res, tmp3 ;// bilinear interpolation
+ LDR tmp3, [ref] ;// load next row
+ EOR res, res, tmpa ;// correct sign
+ STR res, [mb], #16 ;// next row
+
+ ;// tmp4 = |a4|a3|a2|a1|
+ ;// tmp5 = |c4|c3|c2|c1|
+ ;// tmp6 = |g4|g3|g2|g1|
+ ;// tmp1 = |m4|m3|m2|m1|
+ ;// tmp2 = |r4|r3|r2|r1|
+ ;// tmp3 = |t4|t3|t2|t1|
+
+ ;// fourth four pixels
+ UXTB16 tmpa, tmp6 ;// |g3|g1|
+ UXTAB16 tmpa, tmpa, tmp1 ;// |g3+m3|g1+m1|
+ UXTB16 tmpb, tmp5 ;// |c3|c1|
+ ADD tmpa, tmpa, tmpa, LSL #2 ;// 5(G+M)
+ UXTAB16 tmpb, tmpb, tmp2 ;// |c3+r3|c1+r1|
+ ADD tmpa, plus16, tmpa, LSL #2 ;// 16+20(G+M)
+ UXTAB16 tmpa, tmpa, tmp4 ;// 16+20(G+M)+A
+ UXTAB16 tmpa, tmpa, tmp3 ;// 16+20(G+M)+A+T
+
+ ADD tmpb, tmpb, tmpb, LSL #2 ;// 5(C+R)
+ SSUB16 tmpa, tmpa, tmpb ;// 16+20(G+M)+(A+T)-5(C+R)
+
+ USAT16 tmpb, #13, tmpa ;// saturate
+ LDR res, = 0x00FF00FF
+ UXTB16 tmpa, tmp6, ROR #8 ;// |g4|g2|
+ UXTAB16 tmpa, tmpa, tmp1, ROR #8 ;// |g4+m4|g2+m2|
+ AND res, res, tmpb, LSR #5 ;// mask and divide by 32
+
+ ADD tmpa, tmpa, tmpa, LSL #2 ;// 5(G+M)
+ UXTB16 tmpb, tmp5, ROR #8 ;// |c4|c2|
+ ADD tmpa, plus16, tmpa, LSL #2 ;// 16+20(G+M)
+ UXTAB16 tmpb, tmpb, tmp2, ROR #8 ;// |c4+r4|c2+r2|
+ UXTAB16 tmpa, tmpa, tmp4, ROR #8 ;// 16+20(G+M)+A
+ UXTAB16 tmpa, tmpa, tmp3, ROR #8 ;// 16+20(G+M)+A+T
+
+ ADD tmpb, tmpb, tmpb, LSL #2 ;// 5(C+R)
+ SSUB16 tmpa, tmpa, tmpb ;// 16+20(G+M)+(A+T)-5(C+R)
+
+ USAT16 tmpb, #13, tmpa ;// saturate
+ LDR tmp4, = 0xFF00FF00
+ MVNEQ tmp5, tmp6 ;// select verOffset=0
+ MVNNE tmp5, tmp1 ;// select verOffset=1
+
+ AND tmpa, tmp4, tmpb, LSL #3 ;// mask and divide by 32
+ ORR res, res, tmpa
+ LDR tmpa, = 0x80808080
+ UHSUB8 res, res, tmp5 ;// bilinear interpolation
+
+ ;// decrement loop_x counter
+ SUBS count, count, #4<<24 ;// (partWidth-1) -= 4;
+
+ ;// calculate "ref" address for next round
+ SUB ref, ref, width, LSL #3 ;// ref -= 8*width;
+ ADD ref, ref, #4; ;// next column (4 pixels)
+
+ EOR res, res, tmpa ;// correct sign
+ STR res, [mb], #-44
+
+ BCS loop_x
+
+ ADDS count, count, #252<<16 ;// (partHeight-1) -= 4;
+ ADD ref, ref, width, LSL #2 ;// ref += 4*width
+ AND tmp1, count, #0x0000FF00 ;// partWidth-1
+ MOV tmp2, #1
+ ADD tmp2, tmp2, tmp1, LSR #8 ;// partWidth
+ SUB ref, ref, tmp2 ;// ref -= partWidth
+ ADD mb, mb, #64;
+ SUB mb, mb, tmp2; ;// mb -= partWidth
+ BGE loop_y
+
+ ADD sp,sp,#0x1f4
+ LDMFD sp!, {r4-r11, pc}
+
+ END
diff --git a/media/libstagefright/codecs/on2/h264dec/source/arm11_asm/win_asm.bat b/media/libstagefright/codecs/on2/h264dec/source/arm11_asm/win_asm.bat
new file mode 100644
index 0000000..1b8d88c
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/arm11_asm/win_asm.bat
@@ -0,0 +1,15 @@
+echo off
+set ASMFLAGS= -checkreglist -CPU ARM1136 -PreDefine "H264DEC_WINASM SETL {TRUE}"
+set ASM="D:\Program Files\Microsoft Visual Studio 8\VC\ce\bin\x86_arm\armasm"
+echo on
+
+%ASM% %ASMFLAGS% h264bsd_interpolate_chroma_ver.s
+%ASM% %ASMFLAGS% h264bsd_interpolate_chroma_hor.s
+%ASM% %ASMFLAGS% h264bsd_interpolate_hor_half.s
+%ASM% %ASMFLAGS% h264bsd_interpolate_hor_quarter.s
+%ASM% %ASMFLAGS% h264bsd_interpolate_hor_ver_quarter.s
+%ASM% %ASMFLAGS% h264bsd_interpolate_ver_half.s
+%ASM% %ASMFLAGS% h264bsd_interpolate_ver_quarter.s
+
+rem %ASM% %ASMFLAGS% h264bsd_interpolate_chroma_hor_ver.s
+rem %ASM% %ASMFLAGS% h264bsd_interpolate_mid_hor.s
diff --git a/media/libstagefright/codecs/on2/h264dec/source/arm_neon_asm/h264bsdClearMbLayer.s b/media/libstagefright/codecs/on2/h264dec/source/arm_neon_asm/h264bsdClearMbLayer.s
new file mode 100644
index 0000000..db11654
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/arm_neon_asm/h264bsdClearMbLayer.s
@@ -0,0 +1,66 @@
+;
+; 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.
+;
+
+ REQUIRE8
+ PRESERVE8
+
+ AREA |.text|, CODE
+
+ EXPORT h264bsdClearMbLayer
+
+; Input / output registers
+pMbLayer RN 0
+size RN 1
+pTmp RN 2
+step RN 3
+
+; -- NEON registers --
+
+qZero QN Q0.U8
+
+;/*------------------------------------------------------------------------------
+;
+; Function: h264bsdClearMbLayer
+;
+; Functional description:
+;
+; Inputs:
+;
+; Outputs:
+;
+; Returns:
+;
+;------------------------------------------------------------------------------*/
+
+h264bsdClearMbLayer
+
+ VMOV qZero, #0
+ ADD pTmp, pMbLayer, #16
+ MOV step, #32
+ SUBS size, size, #64
+
+loop
+ VST1 qZero, [pMbLayer], step
+ SUBS size, size, #64
+ VST1 qZero, [pTmp], step
+ VST1 qZero, [pMbLayer], step
+ VST1 qZero, [pTmp], step
+ BCS loop
+
+ BX lr
+ END
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/arm_neon_asm/h264bsdCountLeadingZeros.s b/media/libstagefright/codecs/on2/h264dec/source/arm_neon_asm/h264bsdCountLeadingZeros.s
new file mode 100644
index 0000000..c7bd73e
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/arm_neon_asm/h264bsdCountLeadingZeros.s
@@ -0,0 +1,49 @@
+;
+; 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.
+;
+
+ REQUIRE8
+ PRESERVE8
+
+ AREA |.text|, CODE
+
+ EXPORT h264bsdCountLeadingZeros
+
+; Input / output registers
+value RN 0
+
+; -- NEON registers --
+
+;/*------------------------------------------------------------------------------
+;
+; Function: h264bsdCountLeadingZeros
+;
+; Functional description:
+;
+; Inputs:
+;
+; Outputs:
+;
+; Returns:
+;
+;------------------------------------------------------------------------------*/
+
+h264bsdCountLeadingZeros
+
+ CLZ value, value
+ BX lr
+ END
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/arm_neon_asm/h264bsdFillRow7.s b/media/libstagefright/codecs/on2/h264dec/source/arm_neon_asm/h264bsdFillRow7.s
new file mode 100644
index 0000000..5bfac92
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/arm_neon_asm/h264bsdFillRow7.s
@@ -0,0 +1,180 @@
+;
+; 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.
+;
+
+ REQUIRE8
+ PRESERVE8
+
+ AREA |.text|, CODE
+
+ EXPORT h264bsdFillRow7
+
+; Input / output registers
+
+ref RN 0
+fill RN 1
+left RN 2
+tmp2 RN 2
+center RN 3
+right RN 4
+tmp1 RN 5
+
+; -- NEON registers --
+
+qTmp0 QN Q0.U8
+qTmp1 QN Q1.U8
+dTmp0 DN D0.U8
+dTmp1 DN D1.U8
+dTmp2 DN D2.U8
+dTmp3 DN D3.U8
+
+
+;/*------------------------------------------------------------------------------
+;
+; Function: h264bsdFillRow7
+;
+; Functional description:
+;
+; Inputs:
+;
+; Outputs:
+;
+; Returns:
+;
+;------------------------------------------------------------------------------*/
+
+h264bsdFillRow7
+ PUSH {r4-r6,lr}
+ CMP left, #0
+ LDR right, [sp,#0x10]
+ BEQ switch_center
+ LDRB tmp1, [ref,#0]
+
+loop_left
+ SUBS left, left, #1
+ STRB tmp1, [fill], #1
+ BNE loop_left
+
+switch_center
+ ASR tmp2,center,#2
+ CMP tmp2,#9
+ ADDCC pc,pc,tmp2,LSL #2
+ B loop_center
+ B loop_center
+ B case_1
+ B case_2
+ B case_3
+ B case_4
+ B case_5
+ B case_6
+ B case_7
+ B case_8
+;case_8
+; LDR tmp2, [ref], #4
+; SUB center, center, #4
+; STR tmp2, [fill], #4
+;case_7
+; LDR tmp2, [ref], #4
+; SUB center, center, #4
+; STR tmp2, [fill], #4
+;case_6
+; LDR tmp2, [ref], #4
+; SUB center, center, #4
+; STR tmp2, [fill],#4
+;case_5
+; LDR tmp2, [ref], #4
+; SUB center, center, #4
+; STR tmp2, [fill],#4
+;case_4
+; LDR tmp2, [ref],#4
+; SUB center, center, #4
+; STR tmp2, [fill], #4
+;case_3
+; LDR tmp2, [ref],#4
+; SUB center, center, #4
+; STR tmp2, [fill], #4
+;case_2
+; LDR tmp2, [ref],#4
+; SUB center, center, #4
+; STR tmp2, [fill], #4
+;case_1
+; LDR tmp2, [ref],#4
+; SUB center, center, #4
+; STR tmp2, [fill], #4
+
+case_8
+ VLD1 {qTmp0, qTmp1}, [ref]!
+ SUB center, center, #32
+ VST1 qTmp0, [fill]!
+ VST1 qTmp1, [fill]!
+ B loop_center
+case_7
+ VLD1 {dTmp0,dTmp1,dTmp2}, [ref]!
+ SUB center, center, #28
+ LDR tmp2, [ref], #4
+ VST1 {dTmp0,dTmp1,dTmp2}, [fill]!
+ STR tmp2, [fill],#4
+ B loop_center
+case_6
+ VLD1 {dTmp0,dTmp1,dTmp2}, [ref]!
+ SUB center, center, #24
+ VST1 {dTmp0,dTmp1,dTmp2}, [fill]!
+ B loop_center
+case_5
+ VLD1 qTmp0, [ref]!
+ SUB center, center, #20
+ LDR tmp2, [ref], #4
+ VST1 qTmp0, [fill]!
+ STR tmp2, [fill],#4
+ B loop_center
+case_4
+ VLD1 qTmp0, [ref]!
+ SUB center, center, #16
+ VST1 qTmp0, [fill]!
+ B loop_center
+case_3
+ VLD1 dTmp0, [ref]!
+ SUB center, center, #12
+ LDR tmp2, [ref], #4
+ VST1 dTmp0, [fill]!
+ STR tmp2, [fill],#4
+ B loop_center
+case_2
+ LDR tmp2, [ref],#4
+ SUB center, center, #4
+ STR tmp2, [fill], #4
+case_1
+ LDR tmp2, [ref],#4
+ SUB center, center, #4
+ STR tmp2, [fill], #4
+
+loop_center
+ CMP center, #0
+ LDRBNE tmp2, [ref], #1
+ SUBNE center, center, #1
+ STRBNE tmp2, [fill], #1
+ BNE loop_center
+ CMP right,#0
+ POPEQ {r4-r6,pc}
+ LDRB tmp2, [ref,#-1]
+
+loop_right
+ STRB tmp2, [fill], #1
+ SUBS right, right, #1
+ BNE loop_right
+
+ POP {r4-r6,pc}
+ END
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/arm_neon_asm/h264bsdFlushBits.s b/media/libstagefright/codecs/on2/h264dec/source/arm_neon_asm/h264bsdFlushBits.s
new file mode 100644
index 0000000..21335b8
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/arm_neon_asm/h264bsdFlushBits.s
@@ -0,0 +1,82 @@
+;
+; 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.
+;
+
+ REQUIRE8
+ PRESERVE8
+
+ AREA |.text|, CODE
+
+ EXPORT h264bsdFlushBits
+
+; Input / output registers
+pStrmData RN 0
+numBits RN 1
+readBits RN 2
+strmBuffSize RN 3
+pStrmBuffStart RN 1
+pStrmCurrPos RN 2
+bitPosInWord RN 1
+
+; -- NEON registers --
+
+
+
+;/*------------------------------------------------------------------------------
+;
+; Function: h264bsdFlushBits
+;
+; Functional description:
+;
+; Inputs:
+;
+; Outputs:
+;
+; Returns:
+;
+;------------------------------------------------------------------------------*/
+
+h264bsdFlushBits
+;// PUSH {r4-r6,lr}
+
+ LDR readBits, [pStrmData, #0x10]
+ LDR strmBuffSize, [pStrmData, #0xC]
+
+ ADD readBits, readBits, numBits
+ AND bitPosInWord, readBits, #7
+
+ STR readBits, [pStrmData, #0x10]
+ STR bitPosInWord, [pStrmData, #0x8]
+
+ LDR pStrmBuffStart, [pStrmData, #0x0]
+
+ CMP readBits, strmBuffSize, LSL #3
+
+ BHI end_of_stream
+
+ ADD pStrmCurrPos, pStrmBuffStart, readBits, LSR #3
+ STR pStrmCurrPos, [pStrmData, #0x4]
+ MOV r0, #0
+ BX lr
+;// POP {r4-r6,pc}
+
+end_of_stream
+ MVN r0, #0
+ BX lr
+;// POP {r4-r6,pc}
+
+ END
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/arm_neon_asm/h264bsdWriteMacroblock.s b/media/libstagefright/codecs/on2/h264dec/source/arm_neon_asm/h264bsdWriteMacroblock.s
new file mode 100644
index 0000000..38a0781
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/arm_neon_asm/h264bsdWriteMacroblock.s
@@ -0,0 +1,152 @@
+;
+; 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.
+;
+
+ REQUIRE8
+ PRESERVE8
+
+ AREA |.text|, CODE
+
+ EXPORT h264bsdWriteMacroblock
+
+; Input / output registers
+image RN 0
+data RN 1
+width RN 2
+luma RN 3
+cb RN 4
+cr RN 5
+cwidth RN 6
+
+; -- NEON registers --
+
+qRow0 QN Q0.U8
+qRow1 QN Q1.U8
+qRow2 QN Q2.U8
+qRow3 QN Q3.U8
+qRow4 QN Q4.U8
+qRow5 QN Q5.U8
+qRow6 QN Q6.U8
+qRow7 QN Q7.U8
+qRow8 QN Q8.U8
+qRow9 QN Q9.U8
+qRow10 QN Q10.U8
+qRow11 QN Q11.U8
+qRow12 QN Q12.U8
+qRow13 QN Q13.U8
+qRow14 QN Q14.U8
+qRow15 QN Q15.U8
+
+dRow0 DN D0.U8
+dRow1 DN D1.U8
+dRow2 DN D2.U8
+dRow3 DN D3.U8
+dRow4 DN D4.U8
+dRow5 DN D5.U8
+dRow6 DN D6.U8
+dRow7 DN D7.U8
+dRow8 DN D8.U8
+dRow9 DN D9.U8
+dRow10 DN D10.U8
+dRow11 DN D11.U8
+dRow12 DN D12.U8
+dRow13 DN D13.U8
+dRow14 DN D14.U8
+dRow15 DN D15.U8
+
+;/*------------------------------------------------------------------------------
+;
+; Function: h264bsdWriteMacroblock
+;
+; Functional description:
+; Write one macroblock into the image. Both luma and chroma
+; components will be written at the same time.
+;
+; Inputs:
+; data pointer to macroblock data to be written, 256 values for
+; luma followed by 64 values for both chroma components
+;
+; Outputs:
+; image pointer to the image where the macroblock will be written
+;
+; Returns:
+; none
+;
+;------------------------------------------------------------------------------*/
+
+h264bsdWriteMacroblock
+ PUSH {r4-r6,lr}
+ VPUSH {q4-q7}
+
+ LDR width, [image, #4]
+ LDR luma, [image, #0xC]
+ LDR cb, [image, #0x10]
+ LDR cr, [image, #0x14]
+
+
+; Write luma
+ VLD1 {qRow0, qRow1}, [data]!
+ LSL width, width, #4
+ VLD1 {qRow2, qRow3}, [data]!
+ LSR cwidth, width, #1
+ VST1 {qRow0}, [luma@128], width
+ VLD1 {qRow4, qRow5}, [data]!
+ VST1 {qRow1}, [luma@128], width
+ VLD1 {qRow6, qRow7}, [data]!
+ VST1 {qRow2}, [luma@128], width
+ VLD1 {qRow8, qRow9}, [data]!
+ VST1 {qRow3}, [luma@128], width
+ VLD1 {qRow10, qRow11}, [data]!
+ VST1 {qRow4}, [luma@128], width
+ VLD1 {qRow12, qRow13}, [data]!
+ VST1 {qRow5}, [luma@128], width
+ VLD1 {qRow14, qRow15}, [data]!
+ VST1 {qRow6}, [luma@128], width
+
+ VLD1 {qRow0, qRow1}, [data]! ;cb rows 0,1,2,3
+ VST1 {qRow7}, [luma@128], width
+ VLD1 {qRow2, qRow3}, [data]! ;cb rows 4,5,6,7
+ VST1 {qRow8}, [luma@128], width
+ VLD1 {qRow4, qRow5}, [data]! ;cr rows 0,1,2,3
+ VST1 {qRow9}, [luma@128], width
+ VLD1 {qRow6, qRow7}, [data]! ;cr rows 4,5,6,7
+ VST1 {qRow10}, [luma@128], width
+ VST1 {dRow0}, [cb@64], cwidth
+ VST1 {dRow8}, [cr@64], cwidth
+ VST1 {qRow11}, [luma@128], width
+ VST1 {dRow1}, [cb@64], cwidth
+ VST1 {dRow9}, [cr@64], cwidth
+ VST1 {qRow12}, [luma@128], width
+ VST1 {dRow2}, [cb@64], cwidth
+ VST1 {dRow10}, [cr@64], cwidth
+ VST1 {qRow13}, [luma@128], width
+ VST1 {dRow3}, [cb@64], cwidth
+ VST1 {dRow11}, [cr@64], cwidth
+ VST1 {qRow14}, [luma@128], width
+ VST1 {dRow4}, [cb@64], cwidth
+ VST1 {dRow12}, [cr@64], cwidth
+ VST1 {qRow15}, [luma]
+ VST1 {dRow5}, [cb@64], cwidth
+ VST1 {dRow13}, [cr@64], cwidth
+ VST1 {dRow6}, [cb@64], cwidth
+ VST1 {dRow14}, [cr@64], cwidth
+ VST1 {dRow7}, [cb@64]
+ VST1 {dRow15}, [cr@64]
+
+ VPOP {q4-q7}
+ POP {r4-r6,pc}
+ END
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/arm_neon_asm_gcc/asm_common.S b/media/libstagefright/codecs/on2/h264dec/source/arm_neon_asm_gcc/asm_common.S
new file mode 100644
index 0000000..f39f5c4
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/arm_neon_asm_gcc/asm_common.S
@@ -0,0 +1,41 @@
+@
+@ 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.
+@
+
+
+
+
+ .macro REQUIRE8
+ .eabi_attribute 24, 1
+ .endm
+
+ .macro PRESERVE8
+ .eabi_attribute 25, 1
+ .endm
+
+
+ .macro function name, export=0
+.if \export
+ .global \name
+.endif
+ .type \name, %function
+ .func \name
+\name:
+ .endm
+
+ .macro endfunction
+ .endfunc
+ .endm
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/arm_neon_asm_gcc/h264bsdClearMbLayer.S b/media/libstagefright/codecs/on2/h264dec/source/arm_neon_asm_gcc/h264bsdClearMbLayer.S
new file mode 100644
index 0000000..c8a940e
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/arm_neon_asm_gcc/h264bsdClearMbLayer.S
@@ -0,0 +1,68 @@
+@
+@ 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.
+@
+
+#include "asm_common.S"
+
+ preserve8
+
+ .fpu neon
+ .text
+
+/* Input / output registers */
+#define pMbLayer r0
+#define size r1
+#define pTmp r2
+#define step r3
+
+/* -- NEON registers -- */
+
+#define qZero Q0.U8
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdClearMbLayer
+
+ Functional description:
+
+ Inputs:
+
+ Outputs:
+
+ Returns:
+
+------------------------------------------------------------------------------*/
+
+function h264bsdClearMbLayer, export=1
+
+ VMOV qZero, #0
+ ADD pTmp, pMbLayer, #16
+ MOV step, #32
+ SUBS size, size, #64
+
+loop:
+ VST1 {qZero}, [pMbLayer], step
+ SUBS size, size, #64
+ VST1 {qZero}, [pTmp], step
+ VST1 {qZero}, [pMbLayer], step
+ VST1 {qZero}, [pTmp], step
+ BCS loop
+
+ BX lr
+
+endfunction
+
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/arm_neon_asm_gcc/h264bsdCountLeadingZeros.S b/media/libstagefright/codecs/on2/h264dec/source/arm_neon_asm_gcc/h264bsdCountLeadingZeros.S
new file mode 100644
index 0000000..05253d0
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/arm_neon_asm_gcc/h264bsdCountLeadingZeros.S
@@ -0,0 +1,48 @@
+@
+@ 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.
+@
+#include "asm_common.S"
+
+ preserve8
+ .arm
+ .text
+
+
+/* Input / output registers */
+#define value r0
+
+/* -- NEON registers -- */
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdCountLeadingZeros
+
+ Functional description:
+
+ Inputs:
+
+ Outputs:
+
+ Returns:
+
+------------------------------------------------------------------------------*/
+
+function h264bsdCountLeadingZeros, export=1
+
+ CLZ value, value
+ BX lr
+
+endfunction
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/arm_neon_asm_gcc/h264bsdFillRow7.S b/media/libstagefright/codecs/on2/h264dec/source/arm_neon_asm_gcc/h264bsdFillRow7.S
new file mode 100644
index 0000000..6955b9a
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/arm_neon_asm_gcc/h264bsdFillRow7.S
@@ -0,0 +1,143 @@
+@
+@ 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.
+@
+
+#include "asm_common.S"
+
+ preserve8
+
+ .fpu neon
+ .text
+
+/* Input / output registers */
+
+#define ref r0
+#define fill r1
+#define left r2
+#define tmp2 r2
+#define center r3
+#define right r4
+#define tmp1 r5
+
+/* -- NEON registers -- */
+
+#define qTmp0 Q0.U8
+#define qTmp1 Q1.U8
+#define dTmp0 D0.U8
+#define dTmp1 D1.U8
+#define dTmp2 D2.U8
+#define dTmp3 D3.U8
+
+/*
+void h264bsdFillRow7(const u8 * ref, u8 * fill, i32 left, i32 center,
+ i32 right);
+*/
+
+function h264bsdFillRow7, export=1
+
+ PUSH {r4-r6,lr}
+ CMP left, #0
+ LDR right, [sp,#0x10]
+ BEQ switch_center
+ LDRB tmp1, [ref,#0]
+
+loop_left:
+ SUBS left, left, #1
+ STRB tmp1, [fill], #1
+ BNE loop_left
+
+switch_center:
+ ASR tmp2,center,#2
+ CMP tmp2,#9
+ ADDCC pc,pc,tmp2,LSL #2
+ B loop_center
+ B loop_center
+ B case_1
+ B case_2
+ B case_3
+ B case_4
+ B case_5
+ B case_6
+ B case_7
+ B case_8
+
+case_8:
+ VLD1 {qTmp0, qTmp1}, [ref]!
+ SUB center, center, #32
+ VST1 {qTmp0}, [fill]!
+ VST1 {qTmp1}, [fill]!
+ B loop_center
+case_7:
+ VLD1 {dTmp0,dTmp1,dTmp2}, [ref]!
+ SUB center, center, #28
+ LDR tmp2, [ref], #4
+ VST1 {dTmp0,dTmp1,dTmp2}, [fill]!
+ STR tmp2, [fill],#4
+ B loop_center
+case_6:
+ VLD1 {dTmp0,dTmp1,dTmp2}, [ref]!
+ SUB center, center, #24
+ VST1 {dTmp0,dTmp1,dTmp2}, [fill]!
+ B loop_center
+case_5:
+ VLD1 {qTmp0}, [ref]!
+ SUB center, center, #20
+ LDR tmp2, [ref], #4
+ VST1 {qTmp0}, [fill]!
+ STR tmp2, [fill],#4
+ B loop_center
+case_4:
+ VLD1 {qTmp0}, [ref]!
+ SUB center, center, #16
+ VST1 {qTmp0}, [fill]!
+ B loop_center
+case_3:
+ VLD1 {dTmp0}, [ref]!
+ SUB center, center, #12
+ LDR tmp2, [ref], #4
+ VST1 dTmp0, [fill]!
+ STR tmp2, [fill],#4
+ B loop_center
+case_2:
+ LDR tmp2, [ref],#4
+ SUB center, center, #4
+ STR tmp2, [fill], #4
+case_1:
+ LDR tmp2, [ref],#4
+ SUB center, center, #4
+ STR tmp2, [fill], #4
+
+loop_center:
+ CMP center, #0
+ BEQ jump
+ LDRB tmp2, [ref], #1
+ SUB center, center, #1
+ STRB tmp2, [fill], #1
+ BNE loop_center
+jump:
+ CMP right,#0
+ POPEQ {r4-r6,pc}
+ LDRB tmp2, [ref,#-1]
+
+loop_right:
+ STRB tmp2, [fill], #1
+ SUBS right, right, #1
+ BNE loop_right
+
+ POP {r4-r6,pc}
+
+endfunction
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/arm_neon_asm_gcc/h264bsdFlushBits.S b/media/libstagefright/codecs/on2/h264dec/source/arm_neon_asm_gcc/h264bsdFlushBits.S
new file mode 100644
index 0000000..b3f3191
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/arm_neon_asm_gcc/h264bsdFlushBits.S
@@ -0,0 +1,78 @@
+@
+@ 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.
+@
+
+#include "asm_common.S"
+
+ preserve8
+
+ .arm
+ .text
+
+/* Input / output registers */
+#define pStrmData r0
+#define numBits r1
+#define readBits r2
+#define strmBuffSize r3
+#define pStrmBuffStart r1
+#define pStrmCurrPos r2
+#define bitPosInWord r1
+
+/* Input / output registers */
+
+
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdFlushBits
+
+ Functional description:
+
+ Inputs:
+
+ Outputs:
+
+ Returns:
+
+------------------------------------------------------------------------------*/
+function h264bsdFlushBits, export=1
+
+ LDR readBits, [pStrmData, #0x10]
+ LDR strmBuffSize, [pStrmData, #0xC]
+
+ ADD readBits, readBits, numBits
+ AND bitPosInWord, readBits, #7
+
+ STR readBits, [pStrmData, #0x10]
+ STR bitPosInWord, [pStrmData, #0x8]
+
+ LDR pStrmBuffStart, [pStrmData, #0x0]
+
+ CMP readBits, strmBuffSize, LSL #3
+
+ BHI end_of_stream
+
+ ADD pStrmCurrPos, pStrmBuffStart, readBits, LSR #3
+ STR pStrmCurrPos, [pStrmData, #0x4]
+ MOV r0, #0
+ BX lr
+
+end_of_stream:
+ MVN r0, #0
+ BX lr
+
+endfunction
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/arm_neon_asm_gcc/h264bsdWriteMacroblock.S b/media/libstagefright/codecs/on2/h264dec/source/arm_neon_asm_gcc/h264bsdWriteMacroblock.S
new file mode 100644
index 0000000..495d560
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/arm_neon_asm_gcc/h264bsdWriteMacroblock.S
@@ -0,0 +1,157 @@
+@
+@ 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.
+@
+
+#include "asm_common.S"
+
+ require8
+ preserve8
+
+ .arm
+ .fpu neon
+ .text
+
+/* Input / output registers */
+#define image r0
+#define data r1
+#define width r2
+#define luma r3
+#define cb r4
+#define cr r5
+#define cwidth r6
+
+/* -- NEON registers -- */
+
+#define qRow0 Q0.U8
+#define qRow1 Q1.U8
+#define qRow2 Q2.U8
+#define qRow3 Q3.U8
+#define qRow4 Q4.U8
+#define qRow5 Q5.U8
+#define qRow6 Q6.U8
+#define qRow7 Q7.U8
+#define qRow8 Q8.U8
+#define qRow9 Q9.U8
+#define qRow10 Q10.U8
+#define qRow11 Q11.U8
+#define qRow12 Q12.U8
+#define qRow13 Q13.U8
+#define qRow14 Q14.U8
+#define qRow15 Q15.U8
+
+#define dRow0 D0.U8
+#define dRow1 D1.U8
+#define dRow2 D2.U8
+#define dRow3 D3.U8
+#define dRow4 D4.U8
+#define dRow5 D5.U8
+#define dRow6 D6.U8
+#define dRow7 D7.U8
+#define dRow8 D8.U8
+#define dRow9 D9.U8
+#define dRow10 D10.U8
+#define dRow11 D11.U8
+#define dRow12 D12.U8
+#define dRow13 D13.U8
+#define dRow14 D14.U8
+#define dRow15 D15.U8
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdWriteMacroblock
+
+ Functional description:
+ Write one macroblock into the image. Both luma and chroma
+ components will be written at the same time.
+
+ Inputs:
+ data pointer to macroblock data to be written, 256 values for
+ luma followed by 64 values for both chroma components
+
+ Outputs:
+ image pointer to the image where the macroblock will be written
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+function h264bsdWriteMacroblock, export=1
+ PUSH {r4-r6,lr}
+ VPUSH {q4-q7}
+
+ LDR width, [image, #4]
+ LDR luma, [image, #0xC]
+ LDR cb, [image, #0x10]
+ LDR cr, [image, #0x14]
+
+
+@ Write luma
+ VLD1 {qRow0, qRow1}, [data]!
+ LSL width, width, #4
+ VLD1 {qRow2, qRow3}, [data]!
+ LSR cwidth, width, #1
+ VST1 {qRow0}, [luma,:128], width
+ VLD1 {qRow4, qRow5}, [data]!
+ VST1 {qRow1}, [luma,:128], width
+ VLD1 {qRow6, qRow7}, [data]!
+ VST1 {qRow2}, [luma,:128], width
+ VLD1 {qRow8, qRow9}, [data]!
+ VST1 {qRow3}, [luma,:128], width
+ VLD1 {qRow10, qRow11}, [data]!
+ VST1 {qRow4}, [luma,:128], width
+ VLD1 {qRow12, qRow13}, [data]!
+ VST1 {qRow5}, [luma,:128], width
+ VLD1 {qRow14, qRow15}, [data]!
+ VST1 {qRow6}, [luma,:128], width
+
+ VLD1 {qRow0, qRow1}, [data]! ;//cb rows 0,1,2,3
+ VST1 {qRow7}, [luma,:128], width
+ VLD1 {qRow2, qRow3}, [data]! ;//cb rows 4,5,6,7
+ VST1 {qRow8}, [luma,:128], width
+ VLD1 {qRow4, qRow5}, [data]! ;//cr rows 0,1,2,3
+ VST1 {qRow9}, [luma,:128], width
+ VLD1 {qRow6, qRow7}, [data]! ;//cr rows 4,5,6,7
+ VST1 {qRow10}, [luma,:128], width
+ VST1 {dRow0}, [cb,:64], cwidth
+ VST1 {dRow8}, [cr,:64], cwidth
+ VST1 {qRow11}, [luma,:128], width
+ VST1 {dRow1}, [cb,:64], cwidth
+ VST1 {dRow9}, [cr,:64], cwidth
+ VST1 {qRow12}, [luma,:128], width
+ VST1 {dRow2}, [cb,:64], cwidth
+ VST1 {dRow10}, [cr,:64], cwidth
+ VST1 {qRow13}, [luma,:128], width
+ VST1 {dRow3}, [cb,:64], cwidth
+ VST1 {dRow11}, [cr,:64], cwidth
+ VST1 {qRow14}, [luma,:128], width
+ VST1 {dRow4}, [cb,:64], cwidth
+ VST1 {dRow12}, [cr,:64], cwidth
+ VST1 {qRow15}, [luma]
+ VST1 {dRow5}, [cb,:64], cwidth
+ VST1 {dRow13}, [cr,:64], cwidth
+ VST1 {dRow6}, [cb,:64], cwidth
+ VST1 {dRow14}, [cr,:64], cwidth
+ VST1 {dRow7}, [cb,:64]
+ VST1 {dRow15}, [cr,:64]
+
+ VPOP {q4-q7}
+ POP {r4-r6,pc}
+@ BX lr
+
+ .endfunc
+
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_byte_stream.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_byte_stream.c
new file mode 100755
index 0000000..db77f8c
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_byte_stream.c
@@ -0,0 +1,237 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ ExtractNalUnit
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_byte_stream.h"
+#include "h264bsd_util.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+#define BYTE_STREAM_ERROR 0xFFFFFFFF
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+
+ Function name: ExtractNalUnit
+
+ Functional description:
+ Extracts one NAL unit from the byte stream buffer. Removes
+ emulation prevention bytes if present. The original stream buffer
+ is used directly and is therefore modified if emulation prevention
+ bytes are present in the stream.
+
+ Stream buffer is assumed to contain either exactly one NAL unit
+ and nothing else, or one or more NAL units embedded in byte
+ stream format described in the Annex B of the standard. Function
+ detects which one is used based on the first bytes in the buffer.
+
+ Inputs:
+ pByteStream pointer to byte stream buffer
+ len length of the stream buffer (in bytes)
+
+ Outputs:
+ pStrmData stream information is stored here
+ readBytes number of bytes "consumed" from the stream buffer
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK error in byte stream
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdExtractNalUnit(u8 *pByteStream, u32 len, strmData_t *pStrmData,
+ u32 *readBytes)
+{
+
+/* Variables */
+
+ u32 i, tmp;
+ u32 byteCount,initByteCount;
+ u32 zeroCount;
+ u8 byte;
+ u32 hasEmulation = HANTRO_FALSE;
+ u32 invalidStream = HANTRO_FALSE;
+ u8 *readPtr, *writePtr;
+
+/* Code */
+
+ ASSERT(pByteStream);
+ ASSERT(len);
+ ASSERT(len < BYTE_STREAM_ERROR);
+ ASSERT(pStrmData);
+
+ /* byte stream format if starts with 0x000001 or 0x000000 */
+ if (len > 3 && pByteStream[0] == 0x00 && pByteStream[1] == 0x00 &&
+ (pByteStream[2]&0xFE) == 0x00)
+ {
+ /* search for NAL unit start point, i.e. point after first start code
+ * prefix in the stream */
+ zeroCount = byteCount = 2;
+ readPtr = pByteStream + 2;
+ /*lint -e(716) while(1) used consciously */
+ while (1)
+ {
+ byte = *readPtr++;
+ byteCount++;
+
+ if (byteCount == len)
+ {
+ /* no start code prefix found -> error */
+ *readBytes = len;
+ return(HANTRO_NOK);
+ }
+
+ if (!byte)
+ zeroCount++;
+ else if ((byte == 0x01) && (zeroCount >= 2))
+ break;
+ else
+ zeroCount = 0;
+ }
+
+ initByteCount = byteCount;
+
+ /* determine size of the NAL unit. Search for next start code prefix
+ * or end of stream and ignore possible trailing zero bytes */
+ zeroCount = 0;
+ /*lint -e(716) while(1) used consciously */
+ while (1)
+ {
+ byte = *readPtr++;
+ byteCount++;
+ if (!byte)
+ zeroCount++;
+
+ if ( (byte == 0x03) && (zeroCount == 2) )
+ {
+ hasEmulation = HANTRO_TRUE;
+ }
+
+ if ( (byte == 0x01) && (zeroCount >= 2 ) )
+ {
+ pStrmData->strmBuffSize =
+ byteCount - initByteCount - zeroCount - 1;
+ zeroCount -= MIN(zeroCount, 3);
+ break;
+ }
+ else if (byte)
+ {
+ if (zeroCount >= 3)
+ invalidStream = HANTRO_TRUE;
+ zeroCount = 0;
+ }
+
+ if (byteCount == len)
+ {
+ pStrmData->strmBuffSize = byteCount - initByteCount - zeroCount;
+ break;
+ }
+
+ }
+ }
+ /* separate NAL units as input -> just set stream params */
+ else
+ {
+ initByteCount = 0;
+ zeroCount = 0;
+ pStrmData->strmBuffSize = len;
+ hasEmulation = HANTRO_TRUE;
+ }
+
+ pStrmData->pStrmBuffStart = pByteStream + initByteCount;
+ pStrmData->pStrmCurrPos = pStrmData->pStrmBuffStart;
+ pStrmData->bitPosInWord = 0;
+ pStrmData->strmBuffReadBits = 0;
+
+ /* return number of bytes "consumed" */
+ *readBytes = pStrmData->strmBuffSize + initByteCount + zeroCount;
+
+ if (invalidStream)
+ {
+ return(HANTRO_NOK);
+ }
+
+ /* remove emulation prevention bytes before rbsp processing */
+ if (hasEmulation)
+ {
+ tmp = pStrmData->strmBuffSize;
+ readPtr = writePtr = pStrmData->pStrmBuffStart;
+ zeroCount = 0;
+ for (i = tmp; i--;)
+ {
+ if ((zeroCount == 2) && (*readPtr == 0x03))
+ {
+ /* emulation prevention byte shall be followed by one of the
+ * following bytes: 0x00, 0x01, 0x02, 0x03. This implies that
+ * emulation prevention 0x03 byte shall not be the last byte
+ * of the stream. */
+ if ( (i == 0) || (*(readPtr+1) > 0x03) )
+ return(HANTRO_NOK);
+
+ /* do not write emulation prevention byte */
+ readPtr++;
+ zeroCount = 0;
+ }
+ else
+ {
+ /* NAL unit shall not contain byte sequences 0x000000,
+ * 0x000001 or 0x000002 */
+ if ( (zeroCount == 2) && (*readPtr <= 0x02) )
+ return(HANTRO_NOK);
+
+ if (*readPtr == 0)
+ zeroCount++;
+ else
+ zeroCount = 0;
+
+ *writePtr++ = *readPtr++;
+ }
+ }
+
+ /* (readPtr - writePtr) indicates number of "removed" emulation
+ * prevention bytes -> subtract from stream buffer size */
+ pStrmData->strmBuffSize -= (u32)(readPtr - writePtr);
+ }
+
+ return(HANTRO_OK);
+
+}
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_byte_stream.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_byte_stream.h
new file mode 100755
index 0000000..36aec76
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_byte_stream.h
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_BYTE_STREAM_H
+#define H264SWDEC_BYTE_STREAM_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_stream.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+u32 h264bsdExtractNalUnit(u8 *pByteStream, u32 len, strmData_t *pStrmData,
+ u32 *readBytes);
+
+#endif /* #ifdef H264SWDEC_BYTE_STREAM_H */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_cavlc.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_cavlc.c
new file mode 100755
index 0000000..91d78bd
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_cavlc.c
@@ -0,0 +1,916 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ DecodeCoeffToken
+ DecodeLevelPrefix
+ DecodeTotalZeros
+ DecodeRunBefore
+ DecodeResidualBlockCavlc
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_cavlc.h"
+#include "h264bsd_util.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/* Following descriptions use term "information field" to represent combination
+ * of certain decoded symbol value and the length of the corresponding variable
+ * length code word. For example, total_zeros information field consists of
+ * 4 bits symbol value (bits [4,7]) along with four bits to represent length
+ * of the VLC code word (bits [0,3]) */
+
+/* macro to obtain length of the coeff token information field, bits [0,4] */
+#define LENGTH_TC(vlc) ((vlc) & 0x1F)
+/* macro to obtain length of the other information fields, bits [0,3] */
+#define LENGTH(vlc) ((vlc) & 0xF)
+/* macro to obtain code word from the information fields, bits [4,7] */
+#define INFO(vlc) (((vlc) >> 4) & 0xF) /* 4 MSB bits contain information */
+/* macro to obtain trailing ones from the coeff token information word,
+ * bits [5,10] */
+#define TRAILING_ONES(coeffToken) ((coeffToken>>5) & 0x3F)
+/* macro to obtain total coeff from the coeff token information word,
+ * bits [11,15] */
+#define TOTAL_COEFF(coeffToken) (((coeffToken) >> 11) & 0x1F)
+
+#define VLC_NOT_FOUND 0xFFFFFFFEU
+
+/* VLC tables for coeff_token. Because of long codes (max. 16 bits) some of the
+ * tables have been splitted into multiple separate tables. Each array/table
+ * element has the following structure:
+ * [5 bits for tot.coeff.] [6 bits for tr.ones] [5 bits for VLC length]
+ * If there is a 0x0000 value, it means that there is not corresponding VLC
+ * codeword for that index. */
+
+/* VLC lengths up to 6 bits, 0 <= nC < 2 */
+static const u16 coeffToken0_0[32] = {
+ 0x0000,0x0000,0x0000,0x2066,0x1026,0x0806,0x1865,0x1865,
+ 0x1043,0x1043,0x1043,0x1043,0x1043,0x1043,0x1043,0x1043,
+ 0x0822,0x0822,0x0822,0x0822,0x0822,0x0822,0x0822,0x0822,
+ 0x0822,0x0822,0x0822,0x0822,0x0822,0x0822,0x0822,0x0822};
+
+/* VLC lengths up to 10 bits, 0 <= nC < 2 */
+static const u16 coeffToken0_1[48] = {
+ 0x0000,0x0000,0x0000,0x0000,0x406a,0x304a,0x282a,0x200a,
+ 0x3869,0x3869,0x2849,0x2849,0x2029,0x2029,0x1809,0x1809,
+ 0x3068,0x3068,0x3068,0x3068,0x2048,0x2048,0x2048,0x2048,
+ 0x1828,0x1828,0x1828,0x1828,0x1008,0x1008,0x1008,0x1008,
+ 0x2867,0x2867,0x2867,0x2867,0x2867,0x2867,0x2867,0x2867,
+ 0x1847,0x1847,0x1847,0x1847,0x1847,0x1847,0x1847,0x1847};
+
+/* VLC lengths up to 14 bits, 0 <= nC < 2 */
+static const u16 coeffToken0_2[56] = {
+ 0x606e,0x584e,0x502e,0x500e,0x586e,0x504e,0x482e,0x480e,
+ 0x400d,0x400d,0x484d,0x484d,0x402d,0x402d,0x380d,0x380d,
+ 0x506d,0x506d,0x404d,0x404d,0x382d,0x382d,0x300d,0x300d,
+ 0x486b,0x486b,0x486b,0x486b,0x486b,0x486b,0x486b,0x486b,
+ 0x384b,0x384b,0x384b,0x384b,0x384b,0x384b,0x384b,0x384b,
+ 0x302b,0x302b,0x302b,0x302b,0x302b,0x302b,0x302b,0x302b,
+ 0x280b,0x280b,0x280b,0x280b,0x280b,0x280b,0x280b,0x280b};
+
+/* VLC lengths up to 16 bits, 0 <= nC < 2 */
+static const u16 coeffToken0_3[32] = {
+ 0x0000,0x0000,0x682f,0x682f,0x8010,0x8050,0x8030,0x7810,
+ 0x8070,0x7850,0x7830,0x7010,0x7870,0x7050,0x7030,0x6810,
+ 0x706f,0x706f,0x684f,0x684f,0x602f,0x602f,0x600f,0x600f,
+ 0x686f,0x686f,0x604f,0x604f,0x582f,0x582f,0x580f,0x580f};
+
+/* VLC lengths up to 6 bits, 2 <= nC < 4 */
+static const u16 coeffToken2_0[32] = {
+ 0x0000,0x0000,0x0000,0x0000,0x3866,0x2046,0x2026,0x1006,
+ 0x3066,0x1846,0x1826,0x0806,0x2865,0x2865,0x1025,0x1025,
+ 0x2064,0x2064,0x2064,0x2064,0x1864,0x1864,0x1864,0x1864,
+ 0x1043,0x1043,0x1043,0x1043,0x1043,0x1043,0x1043,0x1043};
+
+/* VLC lengths up to 9 bits, 2 <= nC < 4 */
+static const u16 coeffToken2_1[32] = {
+ 0x0000,0x0000,0x0000,0x0000,0x4869,0x3849,0x3829,0x3009,
+ 0x2808,0x2808,0x3048,0x3048,0x3028,0x3028,0x2008,0x2008,
+ 0x4067,0x4067,0x4067,0x4067,0x2847,0x2847,0x2847,0x2847,
+ 0x2827,0x2827,0x2827,0x2827,0x1807,0x1807,0x1807,0x1807};
+
+/* VLC lengths up to 14 bits, 2 <= nC < 4 */
+static const u16 coeffToken2_2[128] = {
+ 0x0000,0x0000,0x786d,0x786d,0x806e,0x804e,0x802e,0x800e,
+ 0x782e,0x780e,0x784e,0x702e,0x704d,0x704d,0x700d,0x700d,
+ 0x706d,0x706d,0x684d,0x684d,0x682d,0x682d,0x680d,0x680d,
+ 0x686d,0x686d,0x604d,0x604d,0x602d,0x602d,0x600d,0x600d,
+ 0x580c,0x580c,0x580c,0x580c,0x584c,0x584c,0x584c,0x584c,
+ 0x582c,0x582c,0x582c,0x582c,0x500c,0x500c,0x500c,0x500c,
+ 0x606c,0x606c,0x606c,0x606c,0x504c,0x504c,0x504c,0x504c,
+ 0x502c,0x502c,0x502c,0x502c,0x480c,0x480c,0x480c,0x480c,
+ 0x586b,0x586b,0x586b,0x586b,0x586b,0x586b,0x586b,0x586b,
+ 0x484b,0x484b,0x484b,0x484b,0x484b,0x484b,0x484b,0x484b,
+ 0x482b,0x482b,0x482b,0x482b,0x482b,0x482b,0x482b,0x482b,
+ 0x400b,0x400b,0x400b,0x400b,0x400b,0x400b,0x400b,0x400b,
+ 0x506b,0x506b,0x506b,0x506b,0x506b,0x506b,0x506b,0x506b,
+ 0x404b,0x404b,0x404b,0x404b,0x404b,0x404b,0x404b,0x404b,
+ 0x402b,0x402b,0x402b,0x402b,0x402b,0x402b,0x402b,0x402b,
+ 0x380b,0x380b,0x380b,0x380b,0x380b,0x380b,0x380b,0x380b};
+
+/* VLC lengths up to 6 bits, 4 <= nC < 8 */
+static const u16 coeffToken4_0[64] = {
+ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
+ 0x1806,0x3846,0x3826,0x1006,0x4866,0x3046,0x3026,0x0806,
+ 0x2825,0x2825,0x2845,0x2845,0x2025,0x2025,0x2045,0x2045,
+ 0x1825,0x1825,0x4065,0x4065,0x1845,0x1845,0x1025,0x1025,
+ 0x3864,0x3864,0x3864,0x3864,0x3064,0x3064,0x3064,0x3064,
+ 0x2864,0x2864,0x2864,0x2864,0x2064,0x2064,0x2064,0x2064,
+ 0x1864,0x1864,0x1864,0x1864,0x1044,0x1044,0x1044,0x1044,
+ 0x0824,0x0824,0x0824,0x0824,0x0004,0x0004,0x0004,0x0004};
+
+/* VLC lengths up to 10 bits, 4 <= nC < 8 */
+static const u16 coeffToken4_1[128] = {
+ 0x0000,0x800a,0x806a,0x804a,0x802a,0x780a,0x786a,0x784a,
+ 0x782a,0x700a,0x706a,0x704a,0x702a,0x680a,0x6829,0x6829,
+ 0x6009,0x6009,0x6849,0x6849,0x6029,0x6029,0x5809,0x5809,
+ 0x6869,0x6869,0x6049,0x6049,0x5829,0x5829,0x5009,0x5009,
+ 0x6068,0x6068,0x6068,0x6068,0x5848,0x5848,0x5848,0x5848,
+ 0x5028,0x5028,0x5028,0x5028,0x4808,0x4808,0x4808,0x4808,
+ 0x5868,0x5868,0x5868,0x5868,0x5048,0x5048,0x5048,0x5048,
+ 0x4828,0x4828,0x4828,0x4828,0x4008,0x4008,0x4008,0x4008,
+ 0x3807,0x3807,0x3807,0x3807,0x3807,0x3807,0x3807,0x3807,
+ 0x3007,0x3007,0x3007,0x3007,0x3007,0x3007,0x3007,0x3007,
+ 0x4847,0x4847,0x4847,0x4847,0x4847,0x4847,0x4847,0x4847,
+ 0x2807,0x2807,0x2807,0x2807,0x2807,0x2807,0x2807,0x2807,
+ 0x5067,0x5067,0x5067,0x5067,0x5067,0x5067,0x5067,0x5067,
+ 0x4047,0x4047,0x4047,0x4047,0x4047,0x4047,0x4047,0x4047,
+ 0x4027,0x4027,0x4027,0x4027,0x4027,0x4027,0x4027,0x4027,
+ 0x2007,0x2007,0x2007,0x2007,0x2007,0x2007,0x2007,0x2007};
+
+/* fixed 6 bit length VLC, nC <= 8 */
+static const u16 coeffToken8[64] = {
+ 0x0806,0x0826,0x0000,0x0006,0x1006,0x1026,0x1046,0x0000,
+ 0x1806,0x1826,0x1846,0x1866,0x2006,0x2026,0x2046,0x2066,
+ 0x2806,0x2826,0x2846,0x2866,0x3006,0x3026,0x3046,0x3066,
+ 0x3806,0x3826,0x3846,0x3866,0x4006,0x4026,0x4046,0x4066,
+ 0x4806,0x4826,0x4846,0x4866,0x5006,0x5026,0x5046,0x5066,
+ 0x5806,0x5826,0x5846,0x5866,0x6006,0x6026,0x6046,0x6066,
+ 0x6806,0x6826,0x6846,0x6866,0x7006,0x7026,0x7046,0x7066,
+ 0x7806,0x7826,0x7846,0x7866,0x8006,0x8026,0x8046,0x8066};
+
+/* VLC lengths up to 3 bits, nC == -1 */
+static const u16 coeffTokenMinus1_0[8] = {
+ 0x0000,0x1043,0x0002,0x0002,0x0821,0x0821,0x0821,0x0821};
+
+/* VLC lengths up to 8 bits, nC == -1 */
+static const u16 coeffTokenMinus1_1[32] = {
+ 0x2067,0x2067,0x2048,0x2028,0x1847,0x1847,0x1827,0x1827,
+ 0x2006,0x2006,0x2006,0x2006,0x1806,0x1806,0x1806,0x1806,
+ 0x1006,0x1006,0x1006,0x1006,0x1866,0x1866,0x1866,0x1866,
+ 0x1026,0x1026,0x1026,0x1026,0x0806,0x0806,0x0806,0x0806};
+
+/* VLC tables for total_zeros. One table containing longer code, totalZeros_1,
+ * has been broken into two separate tables. Table elements have the
+ * following structure:
+ * [4 bits for info] [4 bits for VLC length] */
+
+/* VLC lengths up to 5 bits */
+static const u8 totalZeros_1_0[32] = {
+ 0x00,0x00,0x65,0x55,0x44,0x44,0x34,0x34,
+ 0x23,0x23,0x23,0x23,0x13,0x13,0x13,0x13,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01};
+
+/* VLC lengths up to 9 bits */
+static const u8 totalZeros_1_1[32] = {
+ 0x00,0xf9,0xe9,0xd9,0xc8,0xc8,0xb8,0xb8,
+ 0xa7,0xa7,0xa7,0xa7,0x97,0x97,0x97,0x97,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x76,0x76,0x76,0x76,0x76,0x76,0x76,0x76};
+
+static const u8 totalZeros_2[64] = {
+ 0xe6,0xd6,0xc6,0xb6,0xa5,0xa5,0x95,0x95,
+ 0x84,0x84,0x84,0x84,0x74,0x74,0x74,0x74,
+ 0x64,0x64,0x64,0x64,0x54,0x54,0x54,0x54,
+ 0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x43,
+ 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03};
+
+static const u8 totalZeros_3[64] = {
+ 0xd6,0xb6,0xc5,0xc5,0xa5,0xa5,0x95,0x95,
+ 0x84,0x84,0x84,0x84,0x54,0x54,0x54,0x54,
+ 0x44,0x44,0x44,0x44,0x04,0x04,0x04,0x04,
+ 0x73,0x73,0x73,0x73,0x73,0x73,0x73,0x73,
+ 0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,
+ 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13};
+
+static const u8 totalZeros_4[32] = {
+ 0xc5,0xb5,0xa5,0x05,0x94,0x94,0x74,0x74,
+ 0x34,0x34,0x24,0x24,0x83,0x83,0x83,0x83,
+ 0x63,0x63,0x63,0x63,0x53,0x53,0x53,0x53,
+ 0x43,0x43,0x43,0x43,0x13,0x13,0x13,0x13};
+
+static const u8 totalZeros_5[32] = {
+ 0xb5,0x95,0xa4,0xa4,0x84,0x84,0x24,0x24,
+ 0x14,0x14,0x04,0x04,0x73,0x73,0x73,0x73,
+ 0x63,0x63,0x63,0x63,0x53,0x53,0x53,0x53,
+ 0x43,0x43,0x43,0x43,0x33,0x33,0x33,0x33};
+
+static const u8 totalZeros_6[64] = {
+ 0xa6,0x06,0x15,0x15,0x84,0x84,0x84,0x84,
+ 0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,
+ 0x73,0x73,0x73,0x73,0x73,0x73,0x73,0x73,
+ 0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,
+ 0x53,0x53,0x53,0x53,0x53,0x53,0x53,0x53,
+ 0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x43,
+ 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23};
+
+static const u8 totalZeros_7[64] = {
+ 0x96,0x06,0x15,0x15,0x74,0x74,0x74,0x74,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,
+ 0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x43,
+ 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,
+ 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52};
+
+static const u8 totalZeros_8[64] = {
+ 0x86,0x06,0x25,0x25,0x14,0x14,0x14,0x14,
+ 0x73,0x73,0x73,0x73,0x73,0x73,0x73,0x73,
+ 0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,
+ 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,
+ 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,
+ 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,
+ 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,
+ 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42};
+
+static const u8 totalZeros_9[64] = {
+ 0x16,0x06,0x75,0x75,0x24,0x24,0x24,0x24,
+ 0x53,0x53,0x53,0x53,0x53,0x53,0x53,0x53,
+ 0x62,0x62,0x62,0x62,0x62,0x62,0x62,0x62,
+ 0x62,0x62,0x62,0x62,0x62,0x62,0x62,0x62,
+ 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,
+ 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,
+ 0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,
+ 0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32};
+
+static const u8 totalZeros_10[32] = {
+ 0x15,0x05,0x64,0x64,0x23,0x23,0x23,0x23,
+ 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,
+ 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,
+ 0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32};
+
+static const u8 totalZeros_11[16] = {
+ 0x04,0x14,0x23,0x23,0x33,0x33,0x53,0x53,
+ 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41};
+
+static const u8 totalZeros_12[16] = {
+ 0x04,0x14,0x43,0x43,0x22,0x22,0x22,0x22,
+ 0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31};
+
+static const u8 totalZeros_13[8] = {0x03,0x13,0x32,0x32,0x21,0x21,0x21,0x21};
+
+static const u8 totalZeros_14[4] = {0x02,0x12,0x21,0x21};
+
+/* VLC tables for run_before. Table elements have the following structure:
+ * [4 bits for info] [4bits for VLC length]
+ */
+
+static const u8 runBefore_6[8] = {0x13,0x23,0x43,0x33,0x63,0x53,0x02,0x02};
+
+static const u8 runBefore_5[8] = {0x53,0x43,0x33,0x23,0x12,0x12,0x02,0x02};
+
+static const u8 runBefore_4[8] = {0x43,0x33,0x22,0x22,0x12,0x12,0x02,0x02};
+
+static const u8 runBefore_3[4] = {0x32,0x22,0x12,0x02};
+
+static const u8 runBefore_2[4] = {0x22,0x12,0x01,0x01};
+
+static const u8 runBefore_1[2] = {0x11,0x01};
+
+/* following four macros are used to handle stream buffer "cache" in the CAVLC
+ * decoding function */
+
+/* macro to initialize stream buffer cache, fills the buffer (32 bits) */
+#define BUFFER_INIT(value, bits) \
+{ \
+ bits = 32; \
+ value = h264bsdShowBits32(pStrmData); \
+}
+
+/* macro to read numBits bits from the buffer, bits will be written to
+ * outVal. Refills the buffer if not enough bits left */
+#define BUFFER_SHOW(value, bits, outVal, numBits) \
+{ \
+ if (bits < (numBits)) \
+ { \
+ if(h264bsdFlushBits(pStrmData,32-bits) == END_OF_STREAM) \
+ return(HANTRO_NOK); \
+ value = h264bsdShowBits32(pStrmData); \
+ bits = 32; \
+ } \
+ (outVal) = value >> (32 - (numBits)); \
+}
+
+/* macro to flush numBits bits from the buffer */
+#define BUFFER_FLUSH(value, bits, numBits) \
+{ \
+ value <<= (numBits); \
+ bits -= (numBits); \
+}
+
+/* macro to read and flush numBits bits from the buffer, bits will be written
+ * to outVal. Refills the buffer if not enough bits left */
+#define BUFFER_GET(value, bits, outVal, numBits) \
+{ \
+ if (bits < (numBits)) \
+ { \
+ if(h264bsdFlushBits(pStrmData,32-bits) == END_OF_STREAM) \
+ return(HANTRO_NOK); \
+ value = h264bsdShowBits32(pStrmData); \
+ bits = 32; \
+ } \
+ (outVal) = value >> (32 - (numBits)); \
+ value <<= (numBits); \
+ bits -= (numBits); \
+}
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+static u32 DecodeCoeffToken(u32 bits, u32 nc);
+
+static u32 DecodeLevelPrefix(u32 bits);
+
+static u32 DecodeTotalZeros(u32 bits, u32 totalCoeff, u32 isChromaDC);
+
+static u32 DecodeRunBefore(u32 bits,u32 zerosLeft);
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeCoeffToken
+
+ Functional description:
+ Function to decode coeff_token information field from the stream.
+
+ Inputs:
+ u32 bits next 16 stream bits
+ u32 nc nC, see standard for details
+
+ Outputs:
+ u32 information field (11 bits for value, 5 bits for length)
+
+------------------------------------------------------------------------------*/
+
+u32 DecodeCoeffToken(u32 bits, u32 nc)
+{
+
+/* Variables */
+
+ u32 value;
+
+/* Code */
+
+ /* standard defines that nc for decoding of chroma dc coefficients is -1,
+ * represented by u32 here -> -1 maps to 2^32 - 1 */
+ ASSERT(nc <= 16 || nc == (u32)(-1));
+
+ if (nc < 2)
+ {
+ if (bits >= 0x8000)
+ {
+ value = 0x0001;
+ }
+ else if (bits >= 0x0C00)
+ value = coeffToken0_0[bits >> 10];
+ else if (bits >= 0x0100)
+ value = coeffToken0_1[bits >> 6];
+ else if (bits >= 0x0020)
+ value = coeffToken0_2[(bits>>2)-8];
+ else
+ value = coeffToken0_3[bits];
+ }
+ else if (nc < 4)
+ {
+ if (bits >= 0x8000)
+ {
+ value = bits & 0x4000 ? 0x0002 : 0x0822;
+ }
+ else if (bits >= 0x1000)
+ value = coeffToken2_0[bits >> 10];
+ else if (bits >= 0x0200)
+ value = coeffToken2_1[bits >> 7];
+ else
+ value = coeffToken2_2[bits>>2];
+ }
+ else if (nc < 8)
+ {
+ value = coeffToken4_0[bits >> 10];
+ if (!value)
+ value = coeffToken4_1[bits>>6];
+ }
+ else if (nc <= 16)
+ {
+ value = coeffToken8[bits>>10];
+ }
+ else
+ {
+ value = coeffTokenMinus1_0[bits >> 13];
+ if (!value)
+ value = coeffTokenMinus1_1[bits>>8];
+ }
+
+ return(value);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeLevelPrefix
+
+ Functional description:
+ Function to decode level_prefix information field from the stream
+
+ Inputs:
+ u32 bits next 16 stream bits
+
+ Outputs:
+ u32 level_prefix information field or VLC_NOT_FOUND
+
+------------------------------------------------------------------------------*/
+
+u32 DecodeLevelPrefix(u32 bits)
+{
+
+/* Variables */
+
+ u32 numZeros;
+
+/* Code */
+
+ if (bits >= 0x8000)
+ numZeros = 0;
+ else if (bits >= 0x4000)
+ numZeros = 1;
+ else if (bits >= 0x2000)
+ numZeros = 2;
+ else if (bits >= 0x1000)
+ numZeros = 3;
+ else if (bits >= 0x0800)
+ numZeros = 4;
+ else if (bits >= 0x0400)
+ numZeros = 5;
+ else if (bits >= 0x0200)
+ numZeros = 6;
+ else if (bits >= 0x0100)
+ numZeros = 7;
+ else if (bits >= 0x0080)
+ numZeros = 8;
+ else if (bits >= 0x0040)
+ numZeros = 9;
+ else if (bits >= 0x0020)
+ numZeros = 10;
+ else if (bits >= 0x0010)
+ numZeros = 11;
+ else if (bits >= 0x0008)
+ numZeros = 12;
+ else if (bits >= 0x0004)
+ numZeros = 13;
+ else if (bits >= 0x0002)
+ numZeros = 14;
+ else if (bits >= 0x0001)
+ numZeros = 15;
+ else /* more than 15 zeros encountered which is an error */
+ return(VLC_NOT_FOUND);
+
+ return(numZeros);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeTotalZeros
+
+ Functional description:
+ Function to decode total_zeros information field from the stream
+
+ Inputs:
+ u32 bits next 9 stream bits
+ u32 totalCoeff total number of coefficients for the block
+ being decoded
+ u32 isChromaDC flag to indicate chroma DC block
+
+ Outputs:
+ u32 information field (4 bits value, 4 bits length)
+
+------------------------------------------------------------------------------*/
+
+u32 DecodeTotalZeros(u32 bits, u32 totalCoeff, u32 isChromaDC)
+{
+
+/* Variables */
+
+ u32 value = 0x0;
+
+/* Code */
+
+ ASSERT(totalCoeff);
+
+ if (!isChromaDC)
+ {
+ ASSERT(totalCoeff < 16);
+ switch (totalCoeff)
+ {
+ case 1:
+ value = totalZeros_1_0[bits >> 4];
+ if (!value)
+ value = totalZeros_1_1[bits];
+ break;
+
+ case 2:
+ value = totalZeros_2[bits >> 3];
+ break;
+
+ case 3:
+ value = totalZeros_3[bits >> 3];
+ break;
+
+ case 4:
+ value = totalZeros_4[bits >> 4];
+ break;
+
+ case 5:
+ value = totalZeros_5[bits >> 4];
+ break;
+
+ case 6:
+ value = totalZeros_6[bits >> 3];
+ break;
+
+ case 7:
+ value = totalZeros_7[bits >> 3];
+ break;
+
+ case 8:
+ value = totalZeros_8[bits >> 3];
+ break;
+
+ case 9:
+ value = totalZeros_9[bits >> 3];
+ break;
+
+ case 10:
+ value = totalZeros_10[bits >> 4];
+ break;
+
+ case 11:
+ value = totalZeros_11[bits >> 5];
+ break;
+
+ case 12:
+ value = totalZeros_12[bits >> 5];
+ break;
+
+ case 13:
+ value = totalZeros_13[bits >> 6];
+ break;
+
+ case 14:
+ value = totalZeros_14[bits >> 7];
+ break;
+
+ default: /* case 15 */
+ value = (bits >> 8) ? 0x11 : 0x01;
+ break;
+ }
+ }
+ else
+ {
+ ASSERT(totalCoeff < 4);
+ bits >>= 6;
+ if (bits > 3)
+ value = 0x01;
+ else
+ {
+ if (totalCoeff == 3)
+ value = 0x11;
+ else if (bits > 1)
+ {
+ value = 0x12;
+ }
+ else if (totalCoeff == 2)
+ value = 0x22;
+ else if (bits)
+ value = 0x23;
+ else
+ value = 0x33;
+ }
+ }
+
+ return(value);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeRunBefore
+
+ Functional description:
+ Function to decode run_before information field from the stream
+
+ Inputs:
+ u32 bits next 11 stream bits
+ u32 zerosLeft number of zeros left for the current block
+
+ Outputs:
+ u32 information field (4 bits value, 4 bits length)
+
+------------------------------------------------------------------------------*/
+
+u32 DecodeRunBefore(u32 bits, u32 zerosLeft)
+{
+
+/* Variables */
+
+ u32 value = 0x0;
+
+/* Code */
+
+ switch (zerosLeft)
+ {
+ case 1:
+ value = runBefore_1[bits>>10];
+ break;
+
+ case 2:
+ value = runBefore_2[bits>>9];
+ break;
+
+ case 3:
+ value = runBefore_3[bits>>9];
+ break;
+
+ case 4:
+ value = runBefore_4[bits>>8];
+ break;
+
+ case 5:
+ value = runBefore_5[bits>>8];
+ break;
+
+ case 6:
+ value = runBefore_6[bits>>8];
+ break;
+
+ default:
+ if (bits >= 0x100)
+ value = ((7-(bits>>8))<<4)+0x3;
+ else if (bits >= 0x80)
+ value = 0x74;
+ else if (bits >= 0x40)
+ value = 0x85;
+ else if (bits >= 0x20)
+ value = 0x96;
+ else if (bits >= 0x10)
+ value = 0xa7;
+ else if (bits >= 0x8)
+ value = 0xb8;
+ else if (bits >= 0x4)
+ value = 0xc9;
+ else if (bits >= 0x2)
+ value = 0xdA;
+ else if (bits)
+ value = 0xeB;
+ if (INFO(value) > zerosLeft)
+ value = 0;
+ break;
+ }
+
+ return(value);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeResidualBlockCavlc
+
+ Functional description:
+ Function to decode one CAVLC coded block. This corresponds to
+ syntax elements residual_block_cavlc() in the standard.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+ nc nC value
+ maxNumCoeff maximum number of residual coefficients
+
+ Outputs:
+ coeffLevel stores decoded coefficient levels
+
+ Returns:
+ numCoeffs on bits [4,11] if successful
+ coeffMap on bits [16,31] if successful, this is bit map
+ where each bit indicates if the corresponding
+ coefficient was zero (0) or non-zero (1)
+ HANTRO_NOK end of stream or error in stream
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeResidualBlockCavlc(
+ strmData_t *pStrmData,
+ i32 *coeffLevel,
+ i32 nc,
+ u32 maxNumCoeff)
+{
+
+/* Variables */
+
+ u32 i, tmp, totalCoeff, trailingOnes, suffixLength, levelPrefix;
+ u32 levelSuffix, zerosLeft, bit;
+ i32 level[16];
+ u32 run[16];
+ /* stream "cache" */
+ u32 bufferValue;
+ u32 bufferBits;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(coeffLevel);
+ ASSERT(nc > -2);
+ ASSERT(maxNumCoeff == 4 || maxNumCoeff == 15 || maxNumCoeff == 16);
+ ASSERT(VLC_NOT_FOUND != END_OF_STREAM);
+
+ /* assume that coeffLevel array has been "cleaned" by caller */
+
+ BUFFER_INIT(bufferValue, bufferBits);
+
+ /*lint -e774 disable lint warning on always false comparison */
+ BUFFER_SHOW(bufferValue, bufferBits, bit, 16);
+ /*lint +e774 */
+ tmp = DecodeCoeffToken(bit, (u32)nc);
+ if (!tmp)
+ return(HANTRO_NOK);
+ BUFFER_FLUSH(bufferValue, bufferBits, LENGTH_TC(tmp));
+
+ totalCoeff = TOTAL_COEFF(tmp);
+ if (totalCoeff > maxNumCoeff)
+ return(HANTRO_NOK);
+ trailingOnes = TRAILING_ONES(tmp);
+
+ if (totalCoeff != 0)
+ {
+ i = 0;
+ /* nonzero coefficients: +/- 1 */
+ if (trailingOnes)
+ {
+ BUFFER_GET(bufferValue, bufferBits, bit, trailingOnes);
+ tmp = 1 << (trailingOnes - 1);
+ for (; tmp; i++)
+ {
+ level[i] = bit & tmp ? -1 : 1;
+ tmp >>= 1;
+ }
+ }
+
+ /* other levels */
+ if (totalCoeff > 10 && trailingOnes < 3)
+ suffixLength = 1;
+ else
+ suffixLength = 0;
+
+ for (; i < totalCoeff; i++)
+ {
+ BUFFER_SHOW(bufferValue, bufferBits, bit, 16);
+ levelPrefix = DecodeLevelPrefix(bit);
+ if (levelPrefix == VLC_NOT_FOUND)
+ return(HANTRO_NOK);
+ BUFFER_FLUSH(bufferValue, bufferBits, levelPrefix+1);
+
+ if (levelPrefix < 14)
+ tmp = suffixLength;
+ else if (levelPrefix == 14)
+ {
+ tmp = suffixLength ? suffixLength : 4;
+ }
+ else
+ {
+ /* setting suffixLength to 1 here corresponds to adding 15
+ * to levelCode value if levelPrefix == 15 and
+ * suffixLength == 0 */
+ if (!suffixLength)
+ suffixLength = 1;
+ tmp = 12;
+ }
+
+ if (suffixLength)
+ levelPrefix <<= suffixLength;
+
+ if (tmp)
+ {
+ BUFFER_GET(bufferValue, bufferBits, levelSuffix, tmp);
+ levelPrefix += levelSuffix;
+ }
+
+ tmp = levelPrefix;
+
+ if (i == trailingOnes && trailingOnes < 3)
+ tmp += 2;
+
+ level[i] = (tmp+2)>>1;
+
+ if (suffixLength == 0)
+ suffixLength = 1;
+
+ if ((level[i] > (3 << (suffixLength - 1))) && suffixLength < 6)
+ suffixLength++;
+
+ if (tmp & 0x1)
+ level[i] = -level[i];
+ }
+
+ /* zero runs */
+ if (totalCoeff < maxNumCoeff)
+ {
+ BUFFER_SHOW(bufferValue, bufferBits, bit,9);
+ zerosLeft = DecodeTotalZeros(bit, totalCoeff,
+ (u32)(maxNumCoeff == 4));
+ if (!zerosLeft)
+ return(HANTRO_NOK);
+ BUFFER_FLUSH(bufferValue, bufferBits, LENGTH(zerosLeft));
+ zerosLeft = INFO(zerosLeft);
+ }
+ else
+ zerosLeft = 0;
+
+ for (i = 0; i < totalCoeff - 1; i++)
+ {
+ if (zerosLeft > 0)
+ {
+ BUFFER_SHOW(bufferValue, bufferBits, bit,11);
+ tmp = DecodeRunBefore(bit, zerosLeft);
+ if (!tmp)
+ return(HANTRO_NOK);
+ BUFFER_FLUSH(bufferValue, bufferBits, LENGTH(tmp));
+ run[i] = INFO(tmp);
+ zerosLeft -= run[i]++;
+ }
+ else
+ {
+ run[i] = 1;
+ }
+ }
+
+ /* combining level and run, levelSuffix variable used to hold coeffMap,
+ * i.e. bit map indicating which coefficients had non-zero value. */
+
+ /*lint -esym(771,level,run) level and run are always initialized */
+ tmp = zerosLeft;
+ coeffLevel[tmp] = level[totalCoeff-1];
+ levelSuffix = 1 << tmp;
+ for (i = totalCoeff-1; i--;)
+ {
+ tmp += run[i];
+ levelSuffix |= 1 << tmp;
+ coeffLevel[tmp] = level[i];
+ }
+
+ }
+ else
+ levelSuffix = 0;
+
+ if (h264bsdFlushBits(pStrmData, 32-bufferBits) != HANTRO_OK)
+ return(HANTRO_NOK);
+
+ return((totalCoeff << 4) | (levelSuffix << 16));
+}
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_cavlc.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_cavlc.h
new file mode 100755
index 0000000..80353d3
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_cavlc.h
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_CAVLC_H
+#define H264SWDEC_CAVLC_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_stream.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeResidualBlockCavlc(
+ strmData_t *pStrmData,
+ i32 *coeffLevel,
+ i32 nc,
+ u32 maxNumCoeff);
+
+#endif /* #ifdef H264SWDEC_CAVLC_H */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_cfg.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_cfg.h
new file mode 100755
index 0000000..2baba5a
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_cfg.h
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_CFG_H
+#define H264SWDEC_CFG_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+#define MAX_NUM_REF_PICS 16
+#define MAX_NUM_SLICE_GROUPS 8
+#define MAX_NUM_SEQ_PARAM_SETS 32
+#define MAX_NUM_PIC_PARAM_SETS 256
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+#endif /* #ifdef H264SWDEC_CFG_H */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_conceal.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_conceal.c
new file mode 100755
index 0000000..493fb9e
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_conceal.c
@@ -0,0 +1,626 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdConceal
+ ConcealMb
+ Transform
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_conceal.h"
+#include "h264bsd_util.h"
+#include "h264bsd_reconstruct.h"
+#include "h264bsd_dpb.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/*lint -e702 disable lint warning on right shift of signed quantity */
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+static u32 ConcealMb(mbStorage_t *pMb, image_t *currImage, u32 row, u32 col,
+ u32 sliceType, u8 *data);
+
+static void Transform(i32 *data);
+
+/*------------------------------------------------------------------------------
+
+ Function name: h264bsdConceal
+
+ Functional description:
+ Perform error concealment for a picture. Two types of concealment
+ is performed based on sliceType:
+ 1) copy from previous picture for P-slices.
+ 2) concealment from neighbour pixels for I-slices
+
+ I-type concealment is based on ideas presented by Jarno Tulkki.
+ The concealment algorithm determines frequency domain coefficients
+ from the neighbour pixels, applies integer transform (the same
+ transform used in the residual processing) and uses the results as
+ pixel values for concealed macroblocks. Transform produces 4x4
+ array and one pixel value has to be used for 4x4 luma blocks and
+ 2x2 chroma blocks.
+
+ Similar concealment is performed for whole picture (the choise
+ of the type is based on last successfully decoded slice header of
+ the picture but it is handled by the calling function). It is
+ acknowledged that this may result in wrong type of concealment
+ when a picture contains both types of slices. However,
+ determination of slice type macroblock-by-macroblock cannot
+ be done due to the fact that it is impossible to know to which
+ slice each corrupted (not successfully decoded) macroblock
+ belongs.
+
+ The error concealment is started by searching the first propoerly
+ decoded macroblock and concealing the row containing the macroblock
+ in question. After that all macroblocks above the row in question
+ are concealed. Finally concealment of rows below is performed.
+ The order of concealment for 4x4 picture where macroblock 9 is the
+ first properly decoded one is as follows (properly decoded
+ macroblocks marked with 'x', numbers indicating the order of
+ concealment):
+
+ 4 6 8 10
+ 3 5 7 9
+ 1 x x 2
+ 11 12 13 14
+
+ If all macroblocks of the picture are lost, the concealment is
+ copy of previous picture for P-type and setting the image to
+ constant gray (pixel value 128) for I-type.
+
+ Concealment sets quantization parameter of the concealed
+ macroblocks to value 40 and macroblock type to intra to enable
+ deblocking filter to smooth the edges of the concealed areas.
+
+ Inputs:
+ pStorage pointer to storage structure
+ currImage pointer to current image structure
+ sliceType type of the slice
+
+ Outputs:
+ currImage concealed macroblocks will be written here
+
+ Returns:
+ HANTRO_OK
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdConceal(storage_t *pStorage, image_t *currImage, u32 sliceType)
+{
+
+/* Variables */
+
+ u32 i, j;
+ u32 row, col;
+ u32 width, height;
+ u8 *refData;
+ mbStorage_t *mb;
+
+/* Code */
+
+ ASSERT(pStorage);
+ ASSERT(currImage);
+
+ DEBUG(("Concealing %s slice\n", IS_I_SLICE(sliceType) ?
+ "intra" : "inter"));
+
+ width = currImage->width;
+ height = currImage->height;
+ refData = NULL;
+ /* use reference picture with smallest available index */
+ if (IS_P_SLICE(sliceType) || (pStorage->intraConcealmentFlag != 0))
+ {
+ i = 0;
+ do
+ {
+ refData = h264bsdGetRefPicData(pStorage->dpb, i);
+ i++;
+ if (i >= 16)
+ break;
+ } while (refData == NULL);
+ }
+
+ i = row = col = 0;
+ /* find first properly decoded macroblock -> start point for concealment */
+ while (i < pStorage->picSizeInMbs && !pStorage->mb[i].decoded)
+ {
+ i++;
+ col++;
+ if (col == width)
+ {
+ row++;
+ col = 0;
+ }
+ }
+
+ /* whole picture lost -> copy previous or set grey */
+ if (i == pStorage->picSizeInMbs)
+ {
+ if ( (IS_I_SLICE(sliceType) && (pStorage->intraConcealmentFlag == 0)) ||
+ refData == NULL)
+ H264SwDecMemset(currImage->data, 128, width*height*384);
+ else
+ H264SwDecMemcpy(currImage->data, refData, width*height*384);
+
+ pStorage->numConcealedMbs = pStorage->picSizeInMbs;
+
+ /* no filtering if whole picture concealed */
+ for (i = 0; i < pStorage->picSizeInMbs; i++)
+ pStorage->mb[i].disableDeblockingFilterIdc = 1;
+
+ return(HANTRO_OK);
+ }
+
+ /* start from the row containing the first correct macroblock, conceal the
+ * row in question, all rows above that row and then continue downwards */
+ mb = pStorage->mb + row * width;
+ for (j = col; j--;)
+ {
+ ConcealMb(mb+j, currImage, row, j, sliceType, refData);
+ mb[j].decoded = 1;
+ pStorage->numConcealedMbs++;
+ }
+ for (j = col + 1; j < width; j++)
+ {
+ if (!mb[j].decoded)
+ {
+ ConcealMb(mb+j, currImage, row, j, sliceType, refData);
+ mb[j].decoded = 1;
+ pStorage->numConcealedMbs++;
+ }
+ }
+ /* if previous row(s) could not be concealed -> conceal them now */
+ if (row)
+ {
+ for (j = 0; j < width; j++)
+ {
+ i = row - 1;
+ mb = pStorage->mb + i*width + j;
+ do
+ {
+ ConcealMb(mb, currImage, i, j, sliceType, refData);
+ mb->decoded = 1;
+ pStorage->numConcealedMbs++;
+ mb -= width;
+ } while(i--);
+ }
+ }
+
+ /* process rows below the one containing the first correct macroblock */
+ for (i = row + 1; i < height; i++)
+ {
+ mb = pStorage->mb + i * width;
+
+ for (j = 0; j < width; j++)
+ {
+ if (!mb[j].decoded)
+ {
+ ConcealMb(mb+j, currImage, i, j, sliceType, refData);
+ mb[j].decoded = 1;
+ pStorage->numConcealedMbs++;
+ }
+ }
+ }
+
+ return(HANTRO_OK);
+}
+
+/*------------------------------------------------------------------------------
+
+ Function name: ConcealMb
+
+ Functional description:
+ Perform error concealment for one macroblock, location of the
+ macroblock in the picture indicated by row and col
+
+------------------------------------------------------------------------------*/
+
+u32 ConcealMb(mbStorage_t *pMb, image_t *currImage, u32 row, u32 col,
+ u32 sliceType, u8 *refData)
+{
+
+/* Variables */
+
+ u32 i, j, comp;
+ u32 hor, ver;
+ u32 mbNum;
+ u32 width, height;
+ u8 *mbPos;
+ u8 data[384];
+ u8 *pData;
+ i32 tmp;
+ i32 firstPhase[16];
+ i32 *pTmp;
+ /* neighbours above, below, left and right */
+ i32 a[4], b[4], l[4], r[4];
+ u32 A, B, L, R;
+#ifdef H264DEC_OMXDL
+ u8 fillBuff[32*21 + 15 + 32];
+ u8 *pFill;
+#endif
+/* Code */
+
+ ASSERT(pMb);
+ ASSERT(!pMb->decoded);
+ ASSERT(currImage);
+ ASSERT(col < currImage->width);
+ ASSERT(row < currImage->height);
+
+#ifdef H264DEC_OMXDL
+ pFill = ALIGN(fillBuff, 16);
+#endif
+ width = currImage->width;
+ height = currImage->height;
+ mbNum = row * width + col;
+
+ h264bsdSetCurrImageMbPointers(currImage, mbNum);
+
+ mbPos = currImage->data + row * 16 * width * 16 + col * 16;
+ A = B = L = R = HANTRO_FALSE;
+
+ /* set qpY to 40 to enable some filtering in deblocking (stetson value) */
+ pMb->qpY = 40;
+ pMb->disableDeblockingFilterIdc = 0;
+ /* mbType set to intra to perform filtering despite the values of other
+ * boundary strength determination fields */
+ pMb->mbType = I_4x4;
+ pMb->filterOffsetA = 0;
+ pMb->filterOffsetB = 0;
+ pMb->chromaQpIndexOffset = 0;
+
+ if (IS_I_SLICE(sliceType))
+ H264SwDecMemset(data, 0, sizeof(data));
+ else
+ {
+ mv_t mv = {0,0};
+ image_t refImage;
+ refImage.width = width;
+ refImage.height = height;
+ refImage.data = refData;
+ if (refImage.data)
+ {
+#ifndef H264DEC_OMXDL
+ h264bsdPredictSamples(data, &mv, &refImage, col*16, row*16,
+ 0, 0, 16, 16);
+#else
+ h264bsdPredictSamples(data, &mv, &refImage,
+ ((row*16) + ((col*16)<<16)),
+ 0x00001010, pFill);
+#endif
+ h264bsdWriteMacroblock(currImage, data);
+
+ return(HANTRO_OK);
+ }
+ else
+ H264SwDecMemset(data, 0, sizeof(data));
+ }
+
+ H264SwDecMemset(firstPhase, 0, sizeof(firstPhase));
+
+ /* counter for number of neighbours used */
+ j = 0;
+ hor = ver = 0;
+ if (row && (pMb-width)->decoded)
+ {
+ A = HANTRO_TRUE;
+ pData = mbPos - width*16;
+ a[0] = *pData++; a[0] += *pData++; a[0] += *pData++; a[0] += *pData++;
+ a[1] = *pData++; a[1] += *pData++; a[1] += *pData++; a[1] += *pData++;
+ a[2] = *pData++; a[2] += *pData++; a[2] += *pData++; a[2] += *pData++;
+ a[3] = *pData++; a[3] += *pData++; a[3] += *pData++; a[3] += *pData++;
+ j++;
+ hor++;
+ firstPhase[0] += a[0] + a[1] + a[2] + a[3];
+ firstPhase[1] += a[0] + a[1] - a[2] - a[3];
+ }
+ if ((row != height - 1) && (pMb+width)->decoded)
+ {
+ B = HANTRO_TRUE;
+ pData = mbPos + 16*width*16;
+ b[0] = *pData++; b[0] += *pData++; b[0] += *pData++; b[0] += *pData++;
+ b[1] = *pData++; b[1] += *pData++; b[1] += *pData++; b[1] += *pData++;
+ b[2] = *pData++; b[2] += *pData++; b[2] += *pData++; b[2] += *pData++;
+ b[3] = *pData++; b[3] += *pData++; b[3] += *pData++; b[3] += *pData++;
+ j++;
+ hor++;
+ firstPhase[0] += b[0] + b[1] + b[2] + b[3];
+ firstPhase[1] += b[0] + b[1] - b[2] - b[3];
+ }
+ if (col && (pMb-1)->decoded)
+ {
+ L = HANTRO_TRUE;
+ pData = mbPos - 1;
+ l[0] = pData[0]; l[0] += pData[16*width];
+ l[0] += pData[32*width]; l[0] += pData[48*width];
+ pData += 64*width;
+ l[1] = pData[0]; l[1] += pData[16*width];
+ l[1] += pData[32*width]; l[1] += pData[48*width];
+ pData += 64*width;
+ l[2] = pData[0]; l[2] += pData[16*width];
+ l[2] += pData[32*width]; l[2] += pData[48*width];
+ pData += 64*width;
+ l[3] = pData[0]; l[3] += pData[16*width];
+ l[3] += pData[32*width]; l[3] += pData[48*width];
+ j++;
+ ver++;
+ firstPhase[0] += l[0] + l[1] + l[2] + l[3];
+ firstPhase[4] += l[0] + l[1] - l[2] - l[3];
+ }
+ if ((col != width - 1) && (pMb+1)->decoded)
+ {
+ R = HANTRO_TRUE;
+ pData = mbPos + 16;
+ r[0] = pData[0]; r[0] += pData[16*width];
+ r[0] += pData[32*width]; r[0] += pData[48*width];
+ pData += 64*width;
+ r[1] = pData[0]; r[1] += pData[16*width];
+ r[1] += pData[32*width]; r[1] += pData[48*width];
+ pData += 64*width;
+ r[2] = pData[0]; r[2] += pData[16*width];
+ r[2] += pData[32*width]; r[2] += pData[48*width];
+ pData += 64*width;
+ r[3] = pData[0]; r[3] += pData[16*width];
+ r[3] += pData[32*width]; r[3] += pData[48*width];
+ j++;
+ ver++;
+ firstPhase[0] += r[0] + r[1] + r[2] + r[3];
+ firstPhase[4] += r[0] + r[1] - r[2] - r[3];
+ }
+
+ /* at least one properly decoded neighbour available */
+ ASSERT(j);
+
+ /*lint -esym(644,l,r,a,b) variable initialized above */
+ if (!hor && L && R)
+ firstPhase[1] = (l[0]+l[1]+l[2]+l[3]-r[0]-r[1]-r[2]-r[3]) >> 5;
+ else if (hor)
+ firstPhase[1] >>= (3+hor);
+
+ if (!ver && A && B)
+ firstPhase[4] = (a[0]+a[1]+a[2]+a[3]-b[0]-b[1]-b[2]-b[3]) >> 5;
+ else if (ver)
+ firstPhase[4] >>= (3+ver);
+
+ switch (j)
+ {
+ case 1:
+ firstPhase[0] >>= 4;
+ break;
+
+ case 2:
+ firstPhase[0] >>= 5;
+ break;
+
+ case 3:
+ /* approximate (firstPhase[0]*4/3)>>6 */
+ firstPhase[0] = (21 * firstPhase[0]) >> 10;
+ break;
+
+ default: /* 4 */
+ firstPhase[0] >>= 6;
+ break;
+
+ }
+
+
+ Transform(firstPhase);
+
+ for (i = 0, pData = data, pTmp = firstPhase; i < 256;)
+ {
+ tmp = pTmp[(i & 0xF)>>2];
+ /*lint -e734 CLIP1 macro results in value that fits into 8 bits */
+ *pData++ = CLIP1(tmp);
+ /*lint +e734 */
+
+ i++;
+ if (!(i & 0x3F))
+ pTmp += 4;
+ }
+
+ /* chroma components */
+ mbPos = currImage->data + width * height * 256 +
+ row * 8 * width * 8 + col * 8;
+ for (comp = 0; comp < 2; comp++)
+ {
+
+ H264SwDecMemset(firstPhase, 0, sizeof(firstPhase));
+
+ /* counter for number of neighbours used */
+ j = 0;
+ hor = ver = 0;
+ if (A)
+ {
+ pData = mbPos - width*8;
+ a[0] = *pData++; a[0] += *pData++;
+ a[1] = *pData++; a[1] += *pData++;
+ a[2] = *pData++; a[2] += *pData++;
+ a[3] = *pData++; a[3] += *pData++;
+ j++;
+ hor++;
+ firstPhase[0] += a[0] + a[1] + a[2] + a[3];
+ firstPhase[1] += a[0] + a[1] - a[2] - a[3];
+ }
+ if (B)
+ {
+ pData = mbPos + 8*width*8;
+ b[0] = *pData++; b[0] += *pData++;
+ b[1] = *pData++; b[1] += *pData++;
+ b[2] = *pData++; b[2] += *pData++;
+ b[3] = *pData++; b[3] += *pData++;
+ j++;
+ hor++;
+ firstPhase[0] += b[0] + b[1] + b[2] + b[3];
+ firstPhase[1] += b[0] + b[1] - b[2] - b[3];
+ }
+ if (L)
+ {
+ pData = mbPos - 1;
+ l[0] = pData[0]; l[0] += pData[8*width];
+ pData += 16*width;
+ l[1] = pData[0]; l[1] += pData[8*width];
+ pData += 16*width;
+ l[2] = pData[0]; l[2] += pData[8*width];
+ pData += 16*width;
+ l[3] = pData[0]; l[3] += pData[8*width];
+ j++;
+ ver++;
+ firstPhase[0] += l[0] + l[1] + l[2] + l[3];
+ firstPhase[4] += l[0] + l[1] - l[2] - l[3];
+ }
+ if (R)
+ {
+ pData = mbPos + 8;
+ r[0] = pData[0]; r[0] += pData[8*width];
+ pData += 16*width;
+ r[1] = pData[0]; r[1] += pData[8*width];
+ pData += 16*width;
+ r[2] = pData[0]; r[2] += pData[8*width];
+ pData += 16*width;
+ r[3] = pData[0]; r[3] += pData[8*width];
+ j++;
+ ver++;
+ firstPhase[0] += r[0] + r[1] + r[2] + r[3];
+ firstPhase[4] += r[0] + r[1] - r[2] - r[3];
+ }
+ if (!hor && L && R)
+ firstPhase[1] = (l[0]+l[1]+l[2]+l[3]-r[0]-r[1]-r[2]-r[3]) >> 4;
+ else if (hor)
+ firstPhase[1] >>= (2+hor);
+
+ if (!ver && A && B)
+ firstPhase[4] = (a[0]+a[1]+a[2]+a[3]-b[0]-b[1]-b[2]-b[3]) >> 4;
+ else if (ver)
+ firstPhase[4] >>= (2+ver);
+
+ switch (j)
+ {
+ case 1:
+ firstPhase[0] >>= 3;
+ break;
+
+ case 2:
+ firstPhase[0] >>= 4;
+ break;
+
+ case 3:
+ /* approximate (firstPhase[0]*4/3)>>5 */
+ firstPhase[0] = (21 * firstPhase[0]) >> 9;
+ break;
+
+ default: /* 4 */
+ firstPhase[0] >>= 5;
+ break;
+
+ }
+
+ Transform(firstPhase);
+
+ pData = data + 256 + comp*64;
+ for (i = 0, pTmp = firstPhase; i < 64;)
+ {
+ tmp = pTmp[(i & 0x7)>>1];
+ /*lint -e734 CLIP1 macro results in value that fits into 8 bits */
+ *pData++ = CLIP1(tmp);
+ /*lint +e734 */
+
+ i++;
+ if (!(i & 0xF))
+ pTmp += 4;
+ }
+
+ /* increment pointers for cr */
+ mbPos += width * height * 64;
+ }
+
+ h264bsdWriteMacroblock(currImage, data);
+
+ return(HANTRO_OK);
+
+}
+
+
+/*------------------------------------------------------------------------------
+
+ Function name: Transform
+
+ Functional description:
+ Simplified transform, assuming that only dc component and lowest
+ horizontal and lowest vertical component may be non-zero
+
+------------------------------------------------------------------------------*/
+
+void Transform(i32 *data)
+{
+
+ u32 col;
+ i32 tmp0, tmp1;
+
+ if (!data[1] && !data[4])
+ {
+ data[1] = data[2] = data[3] = data[4] = data[5] =
+ data[6] = data[7] = data[8] = data[9] = data[10] =
+ data[11] = data[12] = data[13] = data[14] = data[15] = data[0];
+ return;
+ }
+ /* first horizontal transform for rows 0 and 1 */
+ tmp0 = data[0];
+ tmp1 = data[1];
+ data[0] = tmp0 + tmp1;
+ data[1] = tmp0 + (tmp1>>1);
+ data[2] = tmp0 - (tmp1>>1);
+ data[3] = tmp0 - tmp1;
+
+ tmp0 = data[4];
+ data[5] = tmp0;
+ data[6] = tmp0;
+ data[7] = tmp0;
+
+ /* then vertical transform */
+ for (col = 4; col--; data++)
+ {
+ tmp0 = data[0];
+ tmp1 = data[4];
+ data[0] = tmp0 + tmp1;
+ data[4] = tmp0 + (tmp1>>1);
+ data[8] = tmp0 - (tmp1>>1);
+ data[12] = tmp0 - tmp1;
+ }
+
+}
+/*lint +e702 */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_conceal.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_conceal.h
new file mode 100755
index 0000000..3134670
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_conceal.h
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_CONCEAL_H
+#define H264SWDEC_CONCEAL_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_slice_header.h"
+#include "h264bsd_storage.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+u32 h264bsdConceal(storage_t *pStorage, image_t *currImage, u32 sliceType);
+
+#endif /* #ifdef H264SWDEC_CONCEAL_H */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_container.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_container.h
new file mode 100755
index 0000000..99b74a0
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_container.h
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_CONTAINER_H
+#define H264SWDEC_CONTAINER_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_storage.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+/* String length for tracing */
+#define H264DEC_TRACE_STR_LEN 100
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+typedef struct
+{
+ enum {
+ UNINITIALIZED,
+ INITIALIZED,
+ NEW_HEADERS
+ } decStat;
+
+ u32 picNumber;
+ storage_t storage;
+#ifdef H264DEC_TRACE
+ char str[H264DEC_TRACE_STR_LEN];
+#endif
+} decContainer_t;
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+#endif /* #ifdef H264SWDEC_DECCONTAINER_H */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_deblocking.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_deblocking.c
new file mode 100755
index 0000000..f8c1f76
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_deblocking.c
@@ -0,0 +1,2417 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdFilterPicture
+ FilterVerLumaEdge
+ FilterHorLumaEdge
+ FilterHorLuma
+ FilterVerChromaEdge
+ FilterHorChromaEdge
+ FilterHorChroma
+ InnerBoundaryStrength
+ EdgeBoundaryStrength
+ GetBoundaryStrengths
+ IsSliceBoundaryOnLeft
+ IsSliceBoundaryOnTop
+ GetMbFilteringFlags
+ GetLumaEdgeThresholds
+ GetChromaEdgeThresholds
+ FilterLuma
+ FilterChroma
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_util.h"
+#include "h264bsd_macroblock_layer.h"
+#include "h264bsd_deblocking.h"
+#include "h264bsd_dpb.h"
+
+#ifdef H264DEC_OMXDL
+#include "omxtypes.h"
+#include "omxVC.h"
+#include "armVC.h"
+#endif /* H264DEC_OMXDL */
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/* Switch off the following Lint messages for this file:
+ * Info 701: Shift left of signed quantity (int)
+ * Info 702: Shift right of signed quantity (int)
+ */
+/*lint -e701 -e702 */
+
+/* array of alpha values, from the standard */
+static const u8 alphas[52] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,5,6,7,8,9,10,
+ 12,13,15,17,20,22,25,28,32,36,40,45,50,56,63,71,80,90,101,113,127,144,162,
+ 182,203,226,255,255};
+
+/* array of beta values, from the standard */
+static const u8 betas[52] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,3,3,3,3,4,4,
+ 4,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18};
+
+
+
+#ifndef H264DEC_OMXDL
+/* array of tc0 values, from the standard, each triplet corresponds to a
+ * column in the table. Indexing goes as tc0[indexA][bS-1] */
+static const u8 tc0[52][3] = {
+ {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
+ {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
+ {0,0,0},{0,0,1},{0,0,1},{0,0,1},{0,0,1},{0,1,1},{0,1,1},{1,1,1},
+ {1,1,1},{1,1,1},{1,1,1},{1,1,2},{1,1,2},{1,1,2},{1,1,2},{1,2,3},
+ {1,2,3},{2,2,3},{2,2,4},{2,3,4},{2,3,4},{3,3,5},{3,4,6},{3,4,6},
+ {4,5,7},{4,5,8},{4,6,9},{5,7,10},{6,8,11},{6,8,13},{7,10,14},{8,11,16},
+ {9,12,18},{10,13,20},{11,15,23},{13,17,25}
+};
+#else
+/* array of tc0 values, from the standard, each triplet corresponds to a
+ * column in the table. Indexing goes as tc0[indexA][bS] */
+static const u8 tc0[52][5] = {
+ {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0}, {0, 0, 0, 1, 0}, {0, 0, 0, 1, 0}, {0, 0, 0, 1, 0},
+ {0, 0, 0, 1, 0}, {0, 0, 1, 1, 0}, {0, 0, 1, 1, 0}, {0, 1, 1, 1, 0},
+ {0, 1, 1, 1, 0}, {0, 1, 1, 1, 0}, {0, 1, 1, 1, 0}, {0, 1, 1, 2, 0},
+ {0, 1, 1, 2, 0}, {0, 1, 1, 2, 0}, {0, 1, 1, 2, 0}, {0, 1, 2, 3, 0},
+ {0, 1, 2, 3, 0}, {0, 2, 2, 3, 0}, {0, 2, 2, 4, 0}, {0, 2, 3, 4, 0},
+ {0, 2, 3, 4, 0}, {0, 3, 3, 5, 0}, {0, 3, 4, 6, 0}, {0, 3, 4, 6, 0},
+ {0, 4, 5, 7, 0}, {0, 4, 5, 8, 0}, {0, 4, 6, 9, 0}, {0, 5, 7, 10, 0},
+ {0, 6, 8, 11, 0}, {0, 6, 8, 13, 0}, {0, 7, 10, 14, 0},
+ {0, 8, 11, 16, 0}, {0, 9, 12, 18, 0}, {0, 10, 13, 20, 0},
+ {0, 11, 15, 23, 0}, {0, 13, 17, 25, 0}
+};
+#endif
+
+
+#ifndef H264DEC_OMXDL
+/* mapping of raster scan block index to 4x4 block index */
+static const u32 mb4x4Index[16] =
+ {0, 1, 4, 5, 2, 3, 6, 7, 8, 9, 12, 13, 10, 11, 14, 15};
+
+typedef struct {
+ const u8 *tc0;
+ u32 alpha;
+ u32 beta;
+} edgeThreshold_t;
+
+typedef struct {
+ u32 top;
+ u32 left;
+} bS_t;
+
+enum { TOP = 0, LEFT = 1, INNER = 2 };
+#endif /* H264DEC_OMXDL */
+
+#define FILTER_LEFT_EDGE 0x04
+#define FILTER_TOP_EDGE 0x02
+#define FILTER_INNER_EDGE 0x01
+
+
+/* clipping table defined in intra_prediction.c */
+extern const u8 h264bsdClip[];
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+static u32 InnerBoundaryStrength(mbStorage_t *mb1, u32 i1, u32 i2);
+
+#ifndef H264DEC_OMXDL
+static u32 EdgeBoundaryStrength(mbStorage_t *mb1, mbStorage_t *mb2,
+ u32 i1, u32 i2);
+#else
+static u32 InnerBoundaryStrength2(mbStorage_t *mb1, u32 i1, u32 i2);
+static u32 EdgeBoundaryStrengthLeft(mbStorage_t *mb1, mbStorage_t *mb2);
+static u32 EdgeBoundaryStrengthTop(mbStorage_t *mb1, mbStorage_t *mb2);
+#endif
+
+static u32 IsSliceBoundaryOnLeft(mbStorage_t *mb);
+
+static u32 IsSliceBoundaryOnTop(mbStorage_t *mb);
+
+static u32 GetMbFilteringFlags(mbStorage_t *mb);
+
+#ifndef H264DEC_OMXDL
+
+static u32 GetBoundaryStrengths(mbStorage_t *mb, bS_t *bs, u32 flags);
+
+static void FilterLuma(u8 *data, bS_t *bS, edgeThreshold_t *thresholds,
+ u32 imageWidth);
+
+static void FilterChroma(u8 *cb, u8 *cr, bS_t *bS, edgeThreshold_t *thresholds,
+ u32 imageWidth);
+
+static void FilterVerLumaEdge( u8 *data, u32 bS, edgeThreshold_t *thresholds,
+ u32 imageWidth);
+static void FilterHorLumaEdge( u8 *data, u32 bS, edgeThreshold_t *thresholds,
+ i32 imageWidth);
+static void FilterHorLuma( u8 *data, u32 bS, edgeThreshold_t *thresholds,
+ i32 imageWidth);
+
+static void FilterVerChromaEdge( u8 *data, u32 bS, edgeThreshold_t *thresholds,
+ u32 imageWidth);
+static void FilterHorChromaEdge( u8 *data, u32 bS, edgeThreshold_t *thresholds,
+ i32 imageWidth);
+static void FilterHorChroma( u8 *data, u32 bS, edgeThreshold_t *thresholds,
+ i32 imageWidth);
+
+static void GetLumaEdgeThresholds(
+ edgeThreshold_t *thresholds,
+ mbStorage_t *mb,
+ u32 filteringFlags);
+
+static void GetChromaEdgeThresholds(
+ edgeThreshold_t *thresholds,
+ mbStorage_t *mb,
+ u32 filteringFlags,
+ i32 chromaQpIndexOffset);
+
+#else /* H264DEC_OMXDL */
+
+static u32 GetBoundaryStrengths(mbStorage_t *mb, u8 (*bs)[16], u32 flags);
+
+static void GetLumaEdgeThresholds(
+ mbStorage_t *mb,
+ u8 (*alpha)[2],
+ u8 (*beta)[2],
+ u8 (*threshold)[16],
+ u8 (*bs)[16],
+ u32 filteringFlags );
+
+static void GetChromaEdgeThresholds(
+ mbStorage_t *mb,
+ u8 (*alpha)[2],
+ u8 (*beta)[2],
+ u8 (*threshold)[8],
+ u8 (*bs)[16],
+ u32 filteringFlags,
+ i32 chromaQpIndexOffset);
+
+#endif /* H264DEC_OMXDL */
+
+/*------------------------------------------------------------------------------
+
+ Function: IsSliceBoundaryOnLeft
+
+ Functional description:
+ Function to determine if there is a slice boundary on the left side
+ of a macroblock.
+
+------------------------------------------------------------------------------*/
+u32 IsSliceBoundaryOnLeft(mbStorage_t *mb)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(mb && mb->mbA);
+
+ if (mb->sliceId != mb->mbA->sliceId)
+ return(HANTRO_TRUE);
+ else
+ return(HANTRO_FALSE);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: IsSliceBoundaryOnTop
+
+ Functional description:
+ Function to determine if there is a slice boundary above the
+ current macroblock.
+
+------------------------------------------------------------------------------*/
+u32 IsSliceBoundaryOnTop(mbStorage_t *mb)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(mb && mb->mbB);
+
+ if (mb->sliceId != mb->mbB->sliceId)
+ return(HANTRO_TRUE);
+ else
+ return(HANTRO_FALSE);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: GetMbFilteringFlags
+
+ Functional description:
+ Function to determine which edges of a macroblock has to be
+ filtered. Output is a bit-wise OR of FILTER_LEFT_EDGE,
+ FILTER_TOP_EDGE and FILTER_INNER_EDGE, depending on which edges
+ shall be filtered.
+
+------------------------------------------------------------------------------*/
+u32 GetMbFilteringFlags(mbStorage_t *mb)
+{
+
+/* Variables */
+
+ u32 flags = 0;
+
+/* Code */
+
+ ASSERT(mb);
+
+ /* nothing will be filtered if disableDeblockingFilterIdc == 1 */
+ if (mb->disableDeblockingFilterIdc != 1)
+ {
+ flags |= FILTER_INNER_EDGE;
+
+ /* filterLeftMbEdgeFlag, left mb is MB_A */
+ if (mb->mbA &&
+ ((mb->disableDeblockingFilterIdc != 2) ||
+ !IsSliceBoundaryOnLeft(mb)))
+ flags |= FILTER_LEFT_EDGE;
+
+ /* filterTopMbEdgeFlag */
+ if (mb->mbB &&
+ ((mb->disableDeblockingFilterIdc != 2) ||
+ !IsSliceBoundaryOnTop(mb)))
+ flags |= FILTER_TOP_EDGE;
+ }
+
+ return(flags);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: InnerBoundaryStrength
+
+ Functional description:
+ Function to calculate boundary strength value bs for an inner
+ edge of a macroblock. Macroblock type is checked before this is
+ called -> no intra mb condition here.
+
+------------------------------------------------------------------------------*/
+u32 InnerBoundaryStrength(mbStorage_t *mb1, u32 ind1, u32 ind2)
+{
+ i32 tmp1, tmp2;
+ i32 mv1, mv2, mv3, mv4;
+
+ tmp1 = mb1->totalCoeff[ind1];
+ tmp2 = mb1->totalCoeff[ind2];
+ mv1 = mb1->mv[ind1].hor;
+ mv2 = mb1->mv[ind2].hor;
+ mv3 = mb1->mv[ind1].ver;
+ mv4 = mb1->mv[ind2].ver;
+
+ if (tmp1 || tmp2)
+ {
+ return 2;
+ }
+ else if ( (ABS(mv1 - mv2) >= 4) || (ABS(mv3 - mv4) >= 4) ||
+ (mb1->refAddr[ind1 >> 2] != mb1->refAddr[ind2 >> 2]) )
+ {
+ return 1;
+ }
+ else
+ return 0;
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: InnerBoundaryStrength2
+
+ Functional description:
+ Function to calculate boundary strength value bs for an inner
+ edge of a macroblock. The function is the same as
+ InnerBoundaryStrength but without checking totalCoeff.
+
+------------------------------------------------------------------------------*/
+u32 InnerBoundaryStrength2(mbStorage_t *mb1, u32 ind1, u32 ind2)
+{
+ i32 tmp1, tmp2, tmp3, tmp4;
+
+ tmp1 = mb1->mv[ind1].hor;
+ tmp2 = mb1->mv[ind2].hor;
+ tmp3 = mb1->mv[ind1].ver;
+ tmp4 = mb1->mv[ind2].ver;
+
+ if ( (ABS(tmp1 - tmp2) >= 4) || (ABS(tmp3 - tmp4) >= 4) ||
+ (mb1->refAddr[ind1 >> 2] != mb1->refAddr[ind2 >> 2]))
+ {
+ return 1;
+ }
+ else
+ return 0;
+}
+#ifndef H264DEC_OMXDL
+/*------------------------------------------------------------------------------
+
+ Function: EdgeBoundaryStrength
+
+ Functional description:
+ Function to calculate boundary strength value bs for left- or
+ top-most edge of a macroblock. Macroblock types are checked
+ before this is called -> no intra mb conditions here.
+
+------------------------------------------------------------------------------*/
+u32 EdgeBoundaryStrength(mbStorage_t *mb1, mbStorage_t *mb2,
+ u32 ind1, u32 ind2)
+{
+
+ if (mb1->totalCoeff[ind1] || mb2->totalCoeff[ind2])
+ {
+ return 2;
+ }
+ else if ((mb1->refAddr[ind1 >> 2] != mb2->refAddr[ind2 >> 2]) ||
+ (ABS(mb1->mv[ind1].hor - mb2->mv[ind2].hor) >= 4) ||
+ (ABS(mb1->mv[ind1].ver - mb2->mv[ind2].ver) >= 4))
+ {
+ return 1;
+ }
+ else
+ return 0;
+}
+
+#else /* H264DEC_OMXDL */
+
+/*------------------------------------------------------------------------------
+
+ Function: EdgeBoundaryStrengthTop
+
+ Functional description:
+ Function to calculate boundary strength value bs for
+ top-most edge of a macroblock. Macroblock types are checked
+ before this is called -> no intra mb conditions here.
+
+------------------------------------------------------------------------------*/
+u32 EdgeBoundaryStrengthTop(mbStorage_t *mb1, mbStorage_t *mb2)
+{
+ u32 topBs = 0;
+ u32 tmp1, tmp2, tmp3, tmp4;
+
+ tmp1 = mb1->totalCoeff[0];
+ tmp2 = mb2->totalCoeff[10];
+ tmp3 = mb1->totalCoeff[1];
+ tmp4 = mb2->totalCoeff[11];
+ if (tmp1 || tmp2)
+ {
+ topBs = 2<<0;
+ }
+ else if ((ABS(mb1->mv[0].hor - mb2->mv[10].hor) >= 4) ||
+ (ABS(mb1->mv[0].ver - mb2->mv[10].ver) >= 4) ||
+ (mb1->refAddr[0] != mb2->refAddr[10 >> 2]))
+ {
+ topBs = 1<<0;
+ }
+ tmp1 = mb1->totalCoeff[4];
+ tmp2 = mb2->totalCoeff[14];
+ if (tmp3 || tmp4)
+ {
+ topBs += 2<<8;
+ }
+ else if ((ABS(mb1->mv[1].hor - mb2->mv[11].hor) >= 4) ||
+ (ABS(mb1->mv[1].ver - mb2->mv[11].ver) >= 4) ||
+ (mb1->refAddr[0] != mb2->refAddr[11 >> 2]))
+ {
+ topBs += 1<<8;
+ }
+ tmp3 = mb1->totalCoeff[5];
+ tmp4 = mb2->totalCoeff[15];
+ if (tmp1 || tmp2)
+ {
+ topBs += 2<<16;
+ }
+ else if ((ABS(mb1->mv[4].hor - mb2->mv[14].hor) >= 4) ||
+ (ABS(mb1->mv[4].ver - mb2->mv[14].ver) >= 4) ||
+ (mb1->refAddr[4 >> 2] != mb2->refAddr[14 >> 2]))
+ {
+ topBs += 1<<16;
+ }
+ if (tmp3 || tmp4)
+ {
+ topBs += 2<<24;
+ }
+ else if ((ABS(mb1->mv[5].hor - mb2->mv[15].hor) >= 4) ||
+ (ABS(mb1->mv[5].ver - mb2->mv[15].ver) >= 4) ||
+ (mb1->refAddr[5 >> 2] != mb2->refAddr[15 >> 2]))
+ {
+ topBs += 1<<24;
+ }
+
+ return topBs;
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: EdgeBoundaryStrengthLeft
+
+ Functional description:
+ Function to calculate boundary strength value bs for left-
+ edge of a macroblock. Macroblock types are checked
+ before this is called -> no intra mb conditions here.
+
+------------------------------------------------------------------------------*/
+u32 EdgeBoundaryStrengthLeft(mbStorage_t *mb1, mbStorage_t *mb2)
+{
+ u32 leftBs = 0;
+ u32 tmp1, tmp2, tmp3, tmp4;
+
+ tmp1 = mb1->totalCoeff[0];
+ tmp2 = mb2->totalCoeff[5];
+ tmp3 = mb1->totalCoeff[2];
+ tmp4 = mb2->totalCoeff[7];
+
+ if (tmp1 || tmp2)
+ {
+ leftBs = 2<<0;
+ }
+ else if ((ABS(mb1->mv[0].hor - mb2->mv[5].hor) >= 4) ||
+ (ABS(mb1->mv[0].ver - mb2->mv[5].ver) >= 4) ||
+ (mb1->refAddr[0] != mb2->refAddr[5 >> 2]))
+ {
+ leftBs = 1<<0;
+ }
+ tmp1 = mb1->totalCoeff[8];
+ tmp2 = mb2->totalCoeff[13];
+ if (tmp3 || tmp4)
+ {
+ leftBs += 2<<8;
+ }
+ else if ((ABS(mb1->mv[2].hor - mb2->mv[7].hor) >= 4) ||
+ (ABS(mb1->mv[2].ver - mb2->mv[7].ver) >= 4) ||
+ (mb1->refAddr[0] != mb2->refAddr[7 >> 2]))
+ {
+ leftBs += 1<<8;
+ }
+ tmp3 = mb1->totalCoeff[10];
+ tmp4 = mb2->totalCoeff[15];
+ if (tmp1 || tmp2)
+ {
+ leftBs += 2<<16;
+ }
+ else if ((ABS(mb1->mv[8].hor - mb2->mv[13].hor) >= 4) ||
+ (ABS(mb1->mv[8].ver - mb2->mv[13].ver) >= 4) ||
+ (mb1->refAddr[8 >> 2] != mb2->refAddr[13 >> 2]))
+ {
+ leftBs += 1<<16;
+ }
+ if (tmp3 || tmp4)
+ {
+ leftBs += 2<<24;
+ }
+ else if ((ABS(mb1->mv[10].hor - mb2->mv[15].hor) >= 4) ||
+ (ABS(mb1->mv[10].ver - mb2->mv[15].ver) >= 4) ||
+ (mb1->refAddr[10 >> 2] != mb2->refAddr[15 >> 2]))
+ {
+ leftBs += 1<<24;
+ }
+
+ return leftBs;
+}
+#endif /* H264DEC_OMXDL */
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdFilterPicture
+
+ Functional description:
+ Perform deblocking filtering for a picture. Filter does not copy
+ the original picture anywhere but filtering is performed directly
+ on the original image. Parameters controlling the filtering process
+ are computed based on information in macroblock structures of the
+ filtered macroblock, macroblock above and macroblock on the left of
+ the filtered one.
+
+ Inputs:
+ image pointer to image to be filtered
+ mb pointer to macroblock data structure of the top-left
+ macroblock of the picture
+
+ Outputs:
+ image filtered image stored here
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+#ifndef H264DEC_OMXDL
+void h264bsdFilterPicture(
+ image_t *image,
+ mbStorage_t *mb)
+{
+
+/* Variables */
+
+ u32 flags;
+ u32 picSizeInMbs, mbRow, mbCol;
+ u32 picWidthInMbs;
+ u8 *data;
+ mbStorage_t *pMb;
+ bS_t bS[16];
+ edgeThreshold_t thresholds[3];
+
+/* Code */
+
+ ASSERT(image);
+ ASSERT(mb);
+ ASSERT(image->data);
+ ASSERT(image->width);
+ ASSERT(image->height);
+
+ picWidthInMbs = image->width;
+ data = image->data;
+ picSizeInMbs = picWidthInMbs * image->height;
+
+ pMb = mb;
+
+ for (mbRow = 0, mbCol = 0; mbRow < image->height; pMb++)
+ {
+ flags = GetMbFilteringFlags(pMb);
+
+ if (flags)
+ {
+ /* GetBoundaryStrengths function returns non-zero value if any of
+ * the bS values for the macroblock being processed was non-zero */
+ if (GetBoundaryStrengths(pMb, bS, flags))
+ {
+ /* luma */
+ GetLumaEdgeThresholds(thresholds, pMb, flags);
+ data = image->data + mbRow * picWidthInMbs * 256 + mbCol * 16;
+
+ FilterLuma((u8*)data, bS, thresholds, picWidthInMbs*16);
+
+ /* chroma */
+ GetChromaEdgeThresholds(thresholds, pMb, flags,
+ pMb->chromaQpIndexOffset);
+ data = image->data + picSizeInMbs * 256 +
+ mbRow * picWidthInMbs * 64 + mbCol * 8;
+
+ FilterChroma((u8*)data, data + 64*picSizeInMbs, bS,
+ thresholds, picWidthInMbs*8);
+
+ }
+ }
+
+ mbCol++;
+ if (mbCol == picWidthInMbs)
+ {
+ mbCol = 0;
+ mbRow++;
+ }
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: FilterVerLumaEdge
+
+ Functional description:
+ Filter one vertical 4-pixel luma edge.
+
+------------------------------------------------------------------------------*/
+void FilterVerLumaEdge(
+ u8 *data,
+ u32 bS,
+ edgeThreshold_t *thresholds,
+ u32 imageWidth)
+{
+
+/* Variables */
+
+ i32 delta, tc, tmp;
+ u32 i;
+ u8 p0, q0, p1, q1, p2, q2;
+ u32 tmpFlag;
+ const u8 *clp = h264bsdClip + 512;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(bS && bS <= 4);
+ ASSERT(thresholds);
+
+ if (bS < 4)
+ {
+ tc = thresholds->tc0[bS-1];
+ tmp = tc;
+ for (i = 4; i; i--, data += imageWidth)
+ {
+ p1 = data[-2]; p0 = data[-1];
+ q0 = data[0]; q1 = data[1];
+ if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
+ ((unsigned)ABS(p1-p0) < thresholds->beta) &&
+ ((unsigned)ABS(q1-q0) < thresholds->beta) )
+ {
+ p2 = data[-3];
+ q2 = data[2];
+
+ if ((unsigned)ABS(p2-p0) < thresholds->beta)
+ {
+ data[-2] = (u8)(p1 + CLIP3(-tc,tc,
+ (p2 + ((p0 + q0 + 1) >> 1) - (p1 << 1)) >> 1));
+ tmp++;
+ }
+
+ if ((unsigned)ABS(q2-q0) < thresholds->beta)
+ {
+ data[1] = (u8)(q1 + CLIP3(-tc,tc,
+ (q2 + ((p0 + q0 + 1) >> 1) - (q1 << 1)) >> 1));
+ tmp++;
+ }
+
+ delta = CLIP3(-tmp, tmp, ((((q0 - p0) << 2) +
+ (p1 - q1) + 4) >> 3));
+
+ p0 = clp[p0 + delta];
+ q0 = clp[q0 - delta];
+ tmp = tc;
+ data[-1] = p0;
+ data[ 0] = q0;
+ }
+ }
+ }
+ else
+ {
+ for (i = 4; i; i--, data += imageWidth)
+ {
+ p1 = data[-2]; p0 = data[-1];
+ q0 = data[0]; q1 = data[1];
+ if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
+ ((unsigned)ABS(p1-p0) < thresholds->beta) &&
+ ((unsigned)ABS(q1-q0) < thresholds->beta) )
+ {
+ tmpFlag =
+ ((unsigned)ABS(p0-q0) < ((thresholds->alpha >> 2) +2)) ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ p2 = data[-3];
+ q2 = data[2];
+
+ if (tmpFlag && (unsigned)ABS(p2-p0) < thresholds->beta)
+ {
+ tmp = p1 + p0 + q0;
+ data[-1] = (u8)((p2 + 2 * tmp + q1 + 4) >> 3);
+ data[-2] = (u8)((p2 + tmp + 2) >> 2);
+ data[-3] = (u8)((2 * data[-4] + 3 * p2 + tmp + 4) >> 3);
+ }
+ else
+ data[-1] = (2 * p1 + p0 + q1 + 2) >> 2;
+
+ if (tmpFlag && (unsigned)ABS(q2-q0) < thresholds->beta)
+ {
+ tmp = p0 + q0 + q1;
+ data[0] = (u8)((p1 + 2 * tmp + q2 + 4) >> 3);
+ data[1] = (u8)((tmp + q2 + 2) >> 2);
+ data[2] = (u8)((2 * data[3] + 3 * q2 + tmp + 4) >> 3);
+ }
+ else
+ data[0] = (u8)((2 * q1 + q0 + p1 + 2) >> 2);
+ }
+ }
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: FilterHorLumaEdge
+
+ Functional description:
+ Filter one horizontal 4-pixel luma edge
+
+------------------------------------------------------------------------------*/
+void FilterHorLumaEdge(
+ u8 *data,
+ u32 bS,
+ edgeThreshold_t *thresholds,
+ i32 imageWidth)
+{
+
+/* Variables */
+
+ i32 delta, tc, tmp;
+ u32 i;
+ u8 p0, q0, p1, q1, p2, q2;
+ const u8 *clp = h264bsdClip + 512;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(bS < 4);
+ ASSERT(thresholds);
+
+ tc = thresholds->tc0[bS-1];
+ tmp = tc;
+ for (i = 4; i; i--, data++)
+ {
+ p1 = data[-imageWidth*2]; p0 = data[-imageWidth];
+ q0 = data[0]; q1 = data[imageWidth];
+ if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
+ ((unsigned)ABS(p1-p0) < thresholds->beta) &&
+ ((unsigned)ABS(q1-q0) < thresholds->beta) )
+ {
+ p2 = data[-imageWidth*3];
+
+ if ((unsigned)ABS(p2-p0) < thresholds->beta)
+ {
+ data[-imageWidth*2] = (u8)(p1 + CLIP3(-tc,tc,
+ (p2 + ((p0 + q0 + 1) >> 1) - (p1 << 1)) >> 1));
+ tmp++;
+ }
+
+ q2 = data[imageWidth*2];
+
+ if ((unsigned)ABS(q2-q0) < thresholds->beta)
+ {
+ data[imageWidth] = (u8)(q1 + CLIP3(-tc,tc,
+ (q2 + ((p0 + q0 + 1) >> 1) - (q1 << 1)) >> 1));
+ tmp++;
+ }
+
+ delta = CLIP3(-tmp, tmp, ((((q0 - p0) << 2) +
+ (p1 - q1) + 4) >> 3));
+
+ p0 = clp[p0 + delta];
+ q0 = clp[q0 - delta];
+ tmp = tc;
+ data[-imageWidth] = p0;
+ data[ 0] = q0;
+ }
+ }
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: FilterHorLuma
+
+ Functional description:
+ Filter all four successive horizontal 4-pixel luma edges. This can
+ be done when bS is equal to all four edges.
+
+------------------------------------------------------------------------------*/
+void FilterHorLuma(
+ u8 *data,
+ u32 bS,
+ edgeThreshold_t *thresholds,
+ i32 imageWidth)
+{
+
+/* Variables */
+
+ i32 delta, tc, tmp;
+ u32 i;
+ u8 p0, q0, p1, q1, p2, q2;
+ u32 tmpFlag;
+ const u8 *clp = h264bsdClip + 512;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(bS <= 4);
+ ASSERT(thresholds);
+
+ if (bS < 4)
+ {
+ tc = thresholds->tc0[bS-1];
+ tmp = tc;
+ for (i = 16; i; i--, data++)
+ {
+ p1 = data[-imageWidth*2]; p0 = data[-imageWidth];
+ q0 = data[0]; q1 = data[imageWidth];
+ if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
+ ((unsigned)ABS(p1-p0) < thresholds->beta) &&
+ ((unsigned)ABS(q1-q0) < thresholds->beta) )
+ {
+ p2 = data[-imageWidth*3];
+
+ if ((unsigned)ABS(p2-p0) < thresholds->beta)
+ {
+ data[-imageWidth*2] = (u8)(p1 + CLIP3(-tc,tc,
+ (p2 + ((p0 + q0 + 1) >> 1) - (p1 << 1)) >> 1));
+ tmp++;
+ }
+
+ q2 = data[imageWidth*2];
+
+ if ((unsigned)ABS(q2-q0) < thresholds->beta)
+ {
+ data[imageWidth] = (u8)(q1 + CLIP3(-tc,tc,
+ (q2 + ((p0 + q0 + 1) >> 1) - (q1 << 1)) >> 1));
+ tmp++;
+ }
+
+ delta = CLIP3(-tmp, tmp, ((((q0 - p0) << 2) +
+ (p1 - q1) + 4) >> 3));
+
+ p0 = clp[p0 + delta];
+ q0 = clp[q0 - delta];
+ tmp = tc;
+ data[-imageWidth] = p0;
+ data[ 0] = q0;
+ }
+ }
+ }
+ else
+ {
+ for (i = 16; i; i--, data++)
+ {
+ p1 = data[-imageWidth*2]; p0 = data[-imageWidth];
+ q0 = data[0]; q1 = data[imageWidth];
+ if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
+ ((unsigned)ABS(p1-p0) < thresholds->beta) &&
+ ((unsigned)ABS(q1-q0) < thresholds->beta) )
+ {
+ tmpFlag = ((unsigned)ABS(p0-q0) < ((thresholds->alpha >> 2) +2))
+ ? HANTRO_TRUE : HANTRO_FALSE;
+
+ p2 = data[-imageWidth*3];
+ q2 = data[imageWidth*2];
+
+ if (tmpFlag && (unsigned)ABS(p2-p0) < thresholds->beta)
+ {
+ tmp = p1 + p0 + q0;
+ data[-imageWidth] = (u8)((p2 + 2 * tmp + q1 + 4) >> 3);
+ data[-imageWidth*2] = (u8)((p2 + tmp + 2) >> 2);
+ data[-imageWidth*3] = (u8)((2 * data[-imageWidth*4] +
+ 3 * p2 + tmp + 4) >> 3);
+ }
+ else
+ data[-imageWidth] = (u8)((2 * p1 + p0 + q1 + 2) >> 2);
+
+ if (tmpFlag && (unsigned)ABS(q2-q0) < thresholds->beta)
+ {
+ tmp = p0 + q0 + q1;
+ data[ 0] = (u8)((p1 + 2 * tmp + q2 + 4) >> 3);
+ data[imageWidth] = (u8)((tmp + q2 + 2) >> 2);
+ data[imageWidth*2] = (u8)((2 * data[imageWidth*3] +
+ 3 * q2 + tmp + 4) >> 3);
+ }
+ else
+ data[0] = (2 * q1 + q0 + p1 + 2) >> 2;
+ }
+ }
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: FilterVerChromaEdge
+
+ Functional description:
+ Filter one vertical 2-pixel chroma edge
+
+------------------------------------------------------------------------------*/
+void FilterVerChromaEdge(
+ u8 *data,
+ u32 bS,
+ edgeThreshold_t *thresholds,
+ u32 width)
+{
+
+/* Variables */
+
+ i32 delta, tc;
+ u8 p0, q0, p1, q1;
+ const u8 *clp = h264bsdClip + 512;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(bS <= 4);
+ ASSERT(thresholds);
+
+ p1 = data[-2]; p0 = data[-1];
+ q0 = data[0]; q1 = data[1];
+ if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
+ ((unsigned)ABS(p1-p0) < thresholds->beta) &&
+ ((unsigned)ABS(q1-q0) < thresholds->beta) )
+ {
+ if (bS < 4)
+ {
+ tc = thresholds->tc0[bS-1] + 1;
+ delta = CLIP3(-tc, tc, ((((q0 - p0) << 2) +
+ (p1 - q1) + 4) >> 3));
+ p0 = clp[p0 + delta];
+ q0 = clp[q0 - delta];
+ data[-1] = p0;
+ data[ 0] = q0;
+ }
+ else
+ {
+ data[-1] = (2 * p1 + p0 + q1 + 2) >> 2;
+ data[ 0] = (2 * q1 + q0 + p1 + 2) >> 2;
+ }
+ }
+ data += width;
+ p1 = data[-2]; p0 = data[-1];
+ q0 = data[0]; q1 = data[1];
+ if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
+ ((unsigned)ABS(p1-p0) < thresholds->beta) &&
+ ((unsigned)ABS(q1-q0) < thresholds->beta) )
+ {
+ if (bS < 4)
+ {
+ tc = thresholds->tc0[bS-1] + 1;
+ delta = CLIP3(-tc, tc, ((((q0 - p0) << 2) +
+ (p1 - q1) + 4) >> 3));
+ p0 = clp[p0 + delta];
+ q0 = clp[q0 - delta];
+ data[-1] = p0;
+ data[ 0] = q0;
+ }
+ else
+ {
+ data[-1] = (2 * p1 + p0 + q1 + 2) >> 2;
+ data[ 0] = (2 * q1 + q0 + p1 + 2) >> 2;
+ }
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: FilterHorChromaEdge
+
+ Functional description:
+ Filter one horizontal 2-pixel chroma edge
+
+------------------------------------------------------------------------------*/
+void FilterHorChromaEdge(
+ u8 *data,
+ u32 bS,
+ edgeThreshold_t *thresholds,
+ i32 width)
+{
+
+/* Variables */
+
+ i32 delta, tc;
+ u32 i;
+ u8 p0, q0, p1, q1;
+ const u8 *clp = h264bsdClip + 512;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(bS < 4);
+ ASSERT(thresholds);
+
+ tc = thresholds->tc0[bS-1] + 1;
+ for (i = 2; i; i--, data++)
+ {
+ p1 = data[-width*2]; p0 = data[-width];
+ q0 = data[0]; q1 = data[width];
+ if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
+ ((unsigned)ABS(p1-p0) < thresholds->beta) &&
+ ((unsigned)ABS(q1-q0) < thresholds->beta) )
+ {
+ delta = CLIP3(-tc, tc, ((((q0 - p0) << 2) +
+ (p1 - q1) + 4) >> 3));
+ p0 = clp[p0 + delta];
+ q0 = clp[q0 - delta];
+ data[-width] = p0;
+ data[ 0] = q0;
+ }
+ }
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: FilterHorChroma
+
+ Functional description:
+ Filter all four successive horizontal 2-pixel chroma edges. This
+ can be done if bS is equal for all four edges.
+
+------------------------------------------------------------------------------*/
+void FilterHorChroma(
+ u8 *data,
+ u32 bS,
+ edgeThreshold_t *thresholds,
+ i32 width)
+{
+
+/* Variables */
+
+ i32 delta, tc;
+ u32 i;
+ u8 p0, q0, p1, q1;
+ const u8 *clp = h264bsdClip + 512;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(bS <= 4);
+ ASSERT(thresholds);
+
+ if (bS < 4)
+ {
+ tc = thresholds->tc0[bS-1] + 1;
+ for (i = 8; i; i--, data++)
+ {
+ p1 = data[-width*2]; p0 = data[-width];
+ q0 = data[0]; q1 = data[width];
+ if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
+ ((unsigned)ABS(p1-p0) < thresholds->beta) &&
+ ((unsigned)ABS(q1-q0) < thresholds->beta) )
+ {
+ delta = CLIP3(-tc, tc, ((((q0 - p0) << 2) +
+ (p1 - q1) + 4) >> 3));
+ p0 = clp[p0 + delta];
+ q0 = clp[q0 - delta];
+ data[-width] = p0;
+ data[ 0] = q0;
+ }
+ }
+ }
+ else
+ {
+ for (i = 8; i; i--, data++)
+ {
+ p1 = data[-width*2]; p0 = data[-width];
+ q0 = data[0]; q1 = data[width];
+ if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
+ ((unsigned)ABS(p1-p0) < thresholds->beta) &&
+ ((unsigned)ABS(q1-q0) < thresholds->beta) )
+ {
+ data[-width] = (2 * p1 + p0 + q1 + 2) >> 2;
+ data[ 0] = (2 * q1 + q0 + p1 + 2) >> 2;
+ }
+ }
+ }
+
+}
+
+
+/*------------------------------------------------------------------------------
+
+ Function: GetBoundaryStrengths
+
+ Functional description:
+ Function to calculate boundary strengths for all edges of a
+ macroblock. Function returns HANTRO_TRUE if any of the bS values for
+ the macroblock had non-zero value, HANTRO_FALSE otherwise.
+
+------------------------------------------------------------------------------*/
+u32 GetBoundaryStrengths(mbStorage_t *mb, bS_t *bS, u32 flags)
+{
+
+/* Variables */
+
+ /* this flag is set HANTRO_TRUE as soon as any boundary strength value is
+ * non-zero */
+ u32 nonZeroBs = HANTRO_FALSE;
+
+/* Code */
+
+ ASSERT(mb);
+ ASSERT(bS);
+ ASSERT(flags);
+
+ /* top edges */
+ if (flags & FILTER_TOP_EDGE)
+ {
+ if (IS_INTRA_MB(*mb) || IS_INTRA_MB(*mb->mbB))
+ {
+ bS[0].top = bS[1].top = bS[2].top = bS[3].top = 4;
+ nonZeroBs = HANTRO_TRUE;
+ }
+ else
+ {
+ bS[0].top = EdgeBoundaryStrength(mb, mb->mbB, 0, 10);
+ bS[1].top = EdgeBoundaryStrength(mb, mb->mbB, 1, 11);
+ bS[2].top = EdgeBoundaryStrength(mb, mb->mbB, 4, 14);
+ bS[3].top = EdgeBoundaryStrength(mb, mb->mbB, 5, 15);
+ if (bS[0].top || bS[1].top || bS[2].top || bS[3].top)
+ nonZeroBs = HANTRO_TRUE;
+ }
+ }
+ else
+ {
+ bS[0].top = bS[1].top = bS[2].top = bS[3].top = 0;
+ }
+
+ /* left edges */
+ if (flags & FILTER_LEFT_EDGE)
+ {
+ if (IS_INTRA_MB(*mb) || IS_INTRA_MB(*mb->mbA))
+ {
+ bS[0].left = bS[4].left = bS[8].left = bS[12].left = 4;
+ nonZeroBs = HANTRO_TRUE;
+ }
+ else
+ {
+ bS[0].left = EdgeBoundaryStrength(mb, mb->mbA, 0, 5);
+ bS[4].left = EdgeBoundaryStrength(mb, mb->mbA, 2, 7);
+ bS[8].left = EdgeBoundaryStrength(mb, mb->mbA, 8, 13);
+ bS[12].left = EdgeBoundaryStrength(mb, mb->mbA, 10, 15);
+ if (!nonZeroBs &&
+ (bS[0].left || bS[4].left || bS[8].left || bS[12].left))
+ nonZeroBs = HANTRO_TRUE;
+ }
+ }
+ else
+ {
+ bS[0].left = bS[4].left = bS[8].left = bS[12].left = 0;
+ }
+
+ /* inner edges */
+ if (IS_INTRA_MB(*mb))
+ {
+ bS[4].top = bS[5].top = bS[6].top = bS[7].top =
+ bS[8].top = bS[9].top = bS[10].top = bS[11].top =
+ bS[12].top = bS[13].top = bS[14].top = bS[15].top = 3;
+
+ bS[1].left = bS[2].left = bS[3].left =
+ bS[5].left = bS[6].left = bS[7].left =
+ bS[9].left = bS[10].left = bS[11].left =
+ bS[13].left = bS[14].left = bS[15].left = 3;
+ nonZeroBs = HANTRO_TRUE;
+ }
+ else
+ {
+ /* 16x16 inter mb -> ref addresses or motion vectors cannot differ,
+ * only check if either of the blocks contain coefficients */
+ if (h264bsdNumMbPart(mb->mbType) == 1)
+ {
+ bS[4].top = mb->totalCoeff[2] || mb->totalCoeff[0] ? 2 : 0;
+ bS[5].top = mb->totalCoeff[3] || mb->totalCoeff[1] ? 2 : 0;
+ bS[6].top = mb->totalCoeff[6] || mb->totalCoeff[4] ? 2 : 0;
+ bS[7].top = mb->totalCoeff[7] || mb->totalCoeff[5] ? 2 : 0;
+ bS[8].top = mb->totalCoeff[8] || mb->totalCoeff[2] ? 2 : 0;
+ bS[9].top = mb->totalCoeff[9] || mb->totalCoeff[3] ? 2 : 0;
+ bS[10].top = mb->totalCoeff[12] || mb->totalCoeff[6] ? 2 : 0;
+ bS[11].top = mb->totalCoeff[13] || mb->totalCoeff[7] ? 2 : 0;
+ bS[12].top = mb->totalCoeff[10] || mb->totalCoeff[8] ? 2 : 0;
+ bS[13].top = mb->totalCoeff[11] || mb->totalCoeff[9] ? 2 : 0;
+ bS[14].top = mb->totalCoeff[14] || mb->totalCoeff[12] ? 2 : 0;
+ bS[15].top = mb->totalCoeff[15] || mb->totalCoeff[13] ? 2 : 0;
+
+ bS[1].left = mb->totalCoeff[1] || mb->totalCoeff[0] ? 2 : 0;
+ bS[2].left = mb->totalCoeff[4] || mb->totalCoeff[1] ? 2 : 0;
+ bS[3].left = mb->totalCoeff[5] || mb->totalCoeff[4] ? 2 : 0;
+ bS[5].left = mb->totalCoeff[3] || mb->totalCoeff[2] ? 2 : 0;
+ bS[6].left = mb->totalCoeff[6] || mb->totalCoeff[3] ? 2 : 0;
+ bS[7].left = mb->totalCoeff[7] || mb->totalCoeff[6] ? 2 : 0;
+ bS[9].left = mb->totalCoeff[9] || mb->totalCoeff[8] ? 2 : 0;
+ bS[10].left = mb->totalCoeff[12] || mb->totalCoeff[9] ? 2 : 0;
+ bS[11].left = mb->totalCoeff[13] || mb->totalCoeff[12] ? 2 : 0;
+ bS[13].left = mb->totalCoeff[11] || mb->totalCoeff[10] ? 2 : 0;
+ bS[14].left = mb->totalCoeff[14] || mb->totalCoeff[11] ? 2 : 0;
+ bS[15].left = mb->totalCoeff[15] || mb->totalCoeff[14] ? 2 : 0;
+ }
+ /* 16x8 inter mb -> ref addresses and motion vectors can be different
+ * only for the middle horizontal edge, for the other top edges it is
+ * enough to check whether the blocks contain coefficients or not. The
+ * same applies to all internal left edges. */
+ else if (mb->mbType == P_L0_L0_16x8)
+ {
+ bS[4].top = mb->totalCoeff[2] || mb->totalCoeff[0] ? 2 : 0;
+ bS[5].top = mb->totalCoeff[3] || mb->totalCoeff[1] ? 2 : 0;
+ bS[6].top = mb->totalCoeff[6] || mb->totalCoeff[4] ? 2 : 0;
+ bS[7].top = mb->totalCoeff[7] || mb->totalCoeff[5] ? 2 : 0;
+ bS[12].top = mb->totalCoeff[10] || mb->totalCoeff[8] ? 2 : 0;
+ bS[13].top = mb->totalCoeff[11] || mb->totalCoeff[9] ? 2 : 0;
+ bS[14].top = mb->totalCoeff[14] || mb->totalCoeff[12] ? 2 : 0;
+ bS[15].top = mb->totalCoeff[15] || mb->totalCoeff[13] ? 2 : 0;
+ bS[8].top = InnerBoundaryStrength(mb, 8, 2);
+ bS[9].top = InnerBoundaryStrength(mb, 9, 3);
+ bS[10].top = InnerBoundaryStrength(mb, 12, 6);
+ bS[11].top = InnerBoundaryStrength(mb, 13, 7);
+
+ bS[1].left = mb->totalCoeff[1] || mb->totalCoeff[0] ? 2 : 0;
+ bS[2].left = mb->totalCoeff[4] || mb->totalCoeff[1] ? 2 : 0;
+ bS[3].left = mb->totalCoeff[5] || mb->totalCoeff[4] ? 2 : 0;
+ bS[5].left = mb->totalCoeff[3] || mb->totalCoeff[2] ? 2 : 0;
+ bS[6].left = mb->totalCoeff[6] || mb->totalCoeff[3] ? 2 : 0;
+ bS[7].left = mb->totalCoeff[7] || mb->totalCoeff[6] ? 2 : 0;
+ bS[9].left = mb->totalCoeff[9] || mb->totalCoeff[8] ? 2 : 0;
+ bS[10].left = mb->totalCoeff[12] || mb->totalCoeff[9] ? 2 : 0;
+ bS[11].left = mb->totalCoeff[13] || mb->totalCoeff[12] ? 2 : 0;
+ bS[13].left = mb->totalCoeff[11] || mb->totalCoeff[10] ? 2 : 0;
+ bS[14].left = mb->totalCoeff[14] || mb->totalCoeff[11] ? 2 : 0;
+ bS[15].left = mb->totalCoeff[15] || mb->totalCoeff[14] ? 2 : 0;
+ }
+ /* 8x16 inter mb -> ref addresses and motion vectors can be different
+ * only for the middle vertical edge, for the other left edges it is
+ * enough to check whether the blocks contain coefficients or not. The
+ * same applies to all internal top edges. */
+ else if (mb->mbType == P_L0_L0_8x16)
+ {
+ bS[4].top = mb->totalCoeff[2] || mb->totalCoeff[0] ? 2 : 0;
+ bS[5].top = mb->totalCoeff[3] || mb->totalCoeff[1] ? 2 : 0;
+ bS[6].top = mb->totalCoeff[6] || mb->totalCoeff[4] ? 2 : 0;
+ bS[7].top = mb->totalCoeff[7] || mb->totalCoeff[5] ? 2 : 0;
+ bS[8].top = mb->totalCoeff[8] || mb->totalCoeff[2] ? 2 : 0;
+ bS[9].top = mb->totalCoeff[9] || mb->totalCoeff[3] ? 2 : 0;
+ bS[10].top = mb->totalCoeff[12] || mb->totalCoeff[6] ? 2 : 0;
+ bS[11].top = mb->totalCoeff[13] || mb->totalCoeff[7] ? 2 : 0;
+ bS[12].top = mb->totalCoeff[10] || mb->totalCoeff[8] ? 2 : 0;
+ bS[13].top = mb->totalCoeff[11] || mb->totalCoeff[9] ? 2 : 0;
+ bS[14].top = mb->totalCoeff[14] || mb->totalCoeff[12] ? 2 : 0;
+ bS[15].top = mb->totalCoeff[15] || mb->totalCoeff[13] ? 2 : 0;
+
+ bS[1].left = mb->totalCoeff[1] || mb->totalCoeff[0] ? 2 : 0;
+ bS[3].left = mb->totalCoeff[5] || mb->totalCoeff[4] ? 2 : 0;
+ bS[5].left = mb->totalCoeff[3] || mb->totalCoeff[2] ? 2 : 0;
+ bS[7].left = mb->totalCoeff[7] || mb->totalCoeff[6] ? 2 : 0;
+ bS[9].left = mb->totalCoeff[9] || mb->totalCoeff[8] ? 2 : 0;
+ bS[11].left = mb->totalCoeff[13] || mb->totalCoeff[12] ? 2 : 0;
+ bS[13].left = mb->totalCoeff[11] || mb->totalCoeff[10] ? 2 : 0;
+ bS[15].left = mb->totalCoeff[15] || mb->totalCoeff[14] ? 2 : 0;
+ bS[2].left = InnerBoundaryStrength(mb, 4, 1);
+ bS[6].left = InnerBoundaryStrength(mb, 6, 3);
+ bS[10].left = InnerBoundaryStrength(mb, 12, 9);
+ bS[14].left = InnerBoundaryStrength(mb, 14, 11);
+ }
+ else
+ {
+ bS[4].top =
+ InnerBoundaryStrength(mb, mb4x4Index[4], mb4x4Index[0]);
+ bS[5].top =
+ InnerBoundaryStrength(mb, mb4x4Index[5], mb4x4Index[1]);
+ bS[6].top =
+ InnerBoundaryStrength(mb, mb4x4Index[6], mb4x4Index[2]);
+ bS[7].top =
+ InnerBoundaryStrength(mb, mb4x4Index[7], mb4x4Index[3]);
+ bS[8].top =
+ InnerBoundaryStrength(mb, mb4x4Index[8], mb4x4Index[4]);
+ bS[9].top =
+ InnerBoundaryStrength(mb, mb4x4Index[9], mb4x4Index[5]);
+ bS[10].top =
+ InnerBoundaryStrength(mb, mb4x4Index[10], mb4x4Index[6]);
+ bS[11].top =
+ InnerBoundaryStrength(mb, mb4x4Index[11], mb4x4Index[7]);
+ bS[12].top =
+ InnerBoundaryStrength(mb, mb4x4Index[12], mb4x4Index[8]);
+ bS[13].top =
+ InnerBoundaryStrength(mb, mb4x4Index[13], mb4x4Index[9]);
+ bS[14].top =
+ InnerBoundaryStrength(mb, mb4x4Index[14], mb4x4Index[10]);
+ bS[15].top =
+ InnerBoundaryStrength(mb, mb4x4Index[15], mb4x4Index[11]);
+
+ bS[1].left =
+ InnerBoundaryStrength(mb, mb4x4Index[1], mb4x4Index[0]);
+ bS[2].left =
+ InnerBoundaryStrength(mb, mb4x4Index[2], mb4x4Index[1]);
+ bS[3].left =
+ InnerBoundaryStrength(mb, mb4x4Index[3], mb4x4Index[2]);
+ bS[5].left =
+ InnerBoundaryStrength(mb, mb4x4Index[5], mb4x4Index[4]);
+ bS[6].left =
+ InnerBoundaryStrength(mb, mb4x4Index[6], mb4x4Index[5]);
+ bS[7].left =
+ InnerBoundaryStrength(mb, mb4x4Index[7], mb4x4Index[6]);
+ bS[9].left =
+ InnerBoundaryStrength(mb, mb4x4Index[9], mb4x4Index[8]);
+ bS[10].left =
+ InnerBoundaryStrength(mb, mb4x4Index[10], mb4x4Index[9]);
+ bS[11].left =
+ InnerBoundaryStrength(mb, mb4x4Index[11], mb4x4Index[10]);
+ bS[13].left =
+ InnerBoundaryStrength(mb, mb4x4Index[13], mb4x4Index[12]);
+ bS[14].left =
+ InnerBoundaryStrength(mb, mb4x4Index[14], mb4x4Index[13]);
+ bS[15].left =
+ InnerBoundaryStrength(mb, mb4x4Index[15], mb4x4Index[14]);
+ }
+ if (!nonZeroBs &&
+ (bS[4].top || bS[5].top || bS[6].top || bS[7].top ||
+ bS[8].top || bS[9].top || bS[10].top || bS[11].top ||
+ bS[12].top || bS[13].top || bS[14].top || bS[15].top ||
+ bS[1].left || bS[2].left || bS[3].left ||
+ bS[5].left || bS[6].left || bS[7].left ||
+ bS[9].left || bS[10].left || bS[11].left ||
+ bS[13].left || bS[14].left || bS[15].left))
+ nonZeroBs = HANTRO_TRUE;
+ }
+
+ return(nonZeroBs);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: GetLumaEdgeThresholds
+
+ Functional description:
+ Compute alpha, beta and tc0 thresholds for inner, left and top
+ luma edges of a macroblock.
+
+------------------------------------------------------------------------------*/
+void GetLumaEdgeThresholds(
+ edgeThreshold_t *thresholds,
+ mbStorage_t *mb,
+ u32 filteringFlags)
+{
+
+/* Variables */
+
+ u32 indexA, indexB;
+ u32 qpAv, qp, qpTmp;
+
+/* Code */
+
+ ASSERT(thresholds);
+ ASSERT(mb);
+
+ qp = mb->qpY;
+
+ indexA = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetA);
+ indexB = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetB);
+
+ thresholds[INNER].alpha = alphas[indexA];
+ thresholds[INNER].beta = betas[indexB];
+ thresholds[INNER].tc0 = tc0[indexA];
+
+ if (filteringFlags & FILTER_TOP_EDGE)
+ {
+ qpTmp = mb->mbB->qpY;
+ if (qpTmp != qp)
+ {
+ qpAv = (qp + qpTmp + 1) >> 1;
+
+ indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
+ indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
+
+ thresholds[TOP].alpha = alphas[indexA];
+ thresholds[TOP].beta = betas[indexB];
+ thresholds[TOP].tc0 = tc0[indexA];
+ }
+ else
+ {
+ thresholds[TOP].alpha = thresholds[INNER].alpha;
+ thresholds[TOP].beta = thresholds[INNER].beta;
+ thresholds[TOP].tc0 = thresholds[INNER].tc0;
+ }
+ }
+ if (filteringFlags & FILTER_LEFT_EDGE)
+ {
+ qpTmp = mb->mbA->qpY;
+ if (qpTmp != qp)
+ {
+ qpAv = (qp + qpTmp + 1) >> 1;
+
+ indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
+ indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
+
+ thresholds[LEFT].alpha = alphas[indexA];
+ thresholds[LEFT].beta = betas[indexB];
+ thresholds[LEFT].tc0 = tc0[indexA];
+ }
+ else
+ {
+ thresholds[LEFT].alpha = thresholds[INNER].alpha;
+ thresholds[LEFT].beta = thresholds[INNER].beta;
+ thresholds[LEFT].tc0 = thresholds[INNER].tc0;
+ }
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: GetChromaEdgeThresholds
+
+ Functional description:
+ Compute alpha, beta and tc0 thresholds for inner, left and top
+ chroma edges of a macroblock.
+
+------------------------------------------------------------------------------*/
+void GetChromaEdgeThresholds(
+ edgeThreshold_t *thresholds,
+ mbStorage_t *mb,
+ u32 filteringFlags,
+ i32 chromaQpIndexOffset)
+{
+
+/* Variables */
+
+ u32 indexA, indexB;
+ u32 qpAv, qp, qpTmp;
+
+/* Code */
+
+ ASSERT(thresholds);
+ ASSERT(mb);
+
+ qp = mb->qpY;
+ qp = h264bsdQpC[CLIP3(0, 51, (i32)qp + chromaQpIndexOffset)];
+
+ indexA = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetA);
+ indexB = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetB);
+
+ thresholds[INNER].alpha = alphas[indexA];
+ thresholds[INNER].beta = betas[indexB];
+ thresholds[INNER].tc0 = tc0[indexA];
+
+ if (filteringFlags & FILTER_TOP_EDGE)
+ {
+ qpTmp = mb->mbB->qpY;
+ if (qpTmp != mb->qpY)
+ {
+ qpTmp = h264bsdQpC[CLIP3(0, 51, (i32)qpTmp + chromaQpIndexOffset)];
+ qpAv = (qp + qpTmp + 1) >> 1;
+
+ indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
+ indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
+
+ thresholds[TOP].alpha = alphas[indexA];
+ thresholds[TOP].beta = betas[indexB];
+ thresholds[TOP].tc0 = tc0[indexA];
+ }
+ else
+ {
+ thresholds[TOP].alpha = thresholds[INNER].alpha;
+ thresholds[TOP].beta = thresholds[INNER].beta;
+ thresholds[TOP].tc0 = thresholds[INNER].tc0;
+ }
+ }
+ if (filteringFlags & FILTER_LEFT_EDGE)
+ {
+ qpTmp = mb->mbA->qpY;
+ if (qpTmp != mb->qpY)
+ {
+ qpTmp = h264bsdQpC[CLIP3(0, 51, (i32)qpTmp + chromaQpIndexOffset)];
+ qpAv = (qp + qpTmp + 1) >> 1;
+
+ indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
+ indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
+
+ thresholds[LEFT].alpha = alphas[indexA];
+ thresholds[LEFT].beta = betas[indexB];
+ thresholds[LEFT].tc0 = tc0[indexA];
+ }
+ else
+ {
+ thresholds[LEFT].alpha = thresholds[INNER].alpha;
+ thresholds[LEFT].beta = thresholds[INNER].beta;
+ thresholds[LEFT].tc0 = thresholds[INNER].tc0;
+ }
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: FilterLuma
+
+ Functional description:
+ Function to filter all luma edges of a macroblock
+
+------------------------------------------------------------------------------*/
+void FilterLuma(
+ u8 *data,
+ bS_t *bS,
+ edgeThreshold_t *thresholds,
+ u32 width)
+{
+
+/* Variables */
+
+ u32 vblock;
+ bS_t *tmp;
+ u8 *ptr;
+ u32 offset;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(bS);
+ ASSERT(thresholds);
+
+ ptr = data;
+ tmp = bS;
+
+ offset = TOP;
+
+ /* loop block rows, perform filtering for all vertical edges of the block
+ * row first, then filter each horizontal edge of the row */
+ for (vblock = 4; vblock--;)
+ {
+ /* only perform filtering if bS is non-zero, first of the four
+ * FilterVerLumaEdge handles the left edge of the macroblock, others
+ * filter inner edges */
+ if (tmp[0].left)
+ FilterVerLumaEdge(ptr, tmp[0].left, thresholds + LEFT, width);
+ if (tmp[1].left)
+ FilterVerLumaEdge(ptr+4, tmp[1].left, thresholds + INNER, width);
+ if (tmp[2].left)
+ FilterVerLumaEdge(ptr+8, tmp[2].left, thresholds + INNER, width);
+ if (tmp[3].left)
+ FilterVerLumaEdge(ptr+12, tmp[3].left, thresholds + INNER, width);
+
+ /* if bS is equal for all horizontal edges of the row -> perform
+ * filtering with FilterHorLuma, otherwise use FilterHorLumaEdge for
+ * each edge separately. offset variable indicates top macroblock edge
+ * on the first loop round, inner edge for the other rounds */
+ if (tmp[0].top == tmp[1].top && tmp[1].top == tmp[2].top &&
+ tmp[2].top == tmp[3].top)
+ {
+ if(tmp[0].top)
+ FilterHorLuma(ptr, tmp[0].top, thresholds + offset, (i32)width);
+ }
+ else
+ {
+ if(tmp[0].top)
+ FilterHorLumaEdge(ptr, tmp[0].top, thresholds+offset,
+ (i32)width);
+ if(tmp[1].top)
+ FilterHorLumaEdge(ptr+4, tmp[1].top, thresholds+offset,
+ (i32)width);
+ if(tmp[2].top)
+ FilterHorLumaEdge(ptr+8, tmp[2].top, thresholds+offset,
+ (i32)width);
+ if(tmp[3].top)
+ FilterHorLumaEdge(ptr+12, tmp[3].top, thresholds+offset,
+ (i32)width);
+ }
+
+ /* four pixel rows ahead, i.e. next row of 4x4-blocks */
+ ptr += width*4;
+ tmp += 4;
+ offset = INNER;
+ }
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: FilterChroma
+
+ Functional description:
+ Function to filter all chroma edges of a macroblock
+
+------------------------------------------------------------------------------*/
+void FilterChroma(
+ u8 *dataCb,
+ u8 *dataCr,
+ bS_t *bS,
+ edgeThreshold_t *thresholds,
+ u32 width)
+{
+
+/* Variables */
+
+ u32 vblock;
+ bS_t *tmp;
+ u32 offset;
+
+/* Code */
+
+ ASSERT(dataCb);
+ ASSERT(dataCr);
+ ASSERT(bS);
+ ASSERT(thresholds);
+
+ tmp = bS;
+ offset = TOP;
+
+ /* loop block rows, perform filtering for all vertical edges of the block
+ * row first, then filter each horizontal edge of the row */
+ for (vblock = 0; vblock < 2; vblock++)
+ {
+ /* only perform filtering if bS is non-zero, first two of the four
+ * FilterVerChromaEdge calls handle the left edge of the macroblock,
+ * others filter the inner edge. Note that as chroma uses bS values
+ * determined for luma edges, each bS is used only for 2 pixels of
+ * a 4-pixel edge */
+ if (tmp[0].left)
+ {
+ FilterVerChromaEdge(dataCb, tmp[0].left, thresholds + LEFT, width);
+ FilterVerChromaEdge(dataCr, tmp[0].left, thresholds + LEFT, width);
+ }
+ if (tmp[4].left)
+ {
+ FilterVerChromaEdge(dataCb+2*width, tmp[4].left, thresholds + LEFT,
+ width);
+ FilterVerChromaEdge(dataCr+2*width, tmp[4].left, thresholds + LEFT,
+ width);
+ }
+ if (tmp[2].left)
+ {
+ FilterVerChromaEdge(dataCb+4, tmp[2].left, thresholds + INNER,
+ width);
+ FilterVerChromaEdge(dataCr+4, tmp[2].left, thresholds + INNER,
+ width);
+ }
+ if (tmp[6].left)
+ {
+ FilterVerChromaEdge(dataCb+2*width+4, tmp[6].left,
+ thresholds + INNER, width);
+ FilterVerChromaEdge(dataCr+2*width+4, tmp[6].left,
+ thresholds + INNER, width);
+ }
+
+ /* if bS is equal for all horizontal edges of the row -> perform
+ * filtering with FilterHorChroma, otherwise use FilterHorChromaEdge
+ * for each edge separately. offset variable indicates top macroblock
+ * edge on the first loop round, inner edge for the second */
+ if (tmp[0].top == tmp[1].top && tmp[1].top == tmp[2].top &&
+ tmp[2].top == tmp[3].top)
+ {
+ if(tmp[0].top)
+ {
+ FilterHorChroma(dataCb, tmp[0].top, thresholds+offset,
+ (i32)width);
+ FilterHorChroma(dataCr, tmp[0].top, thresholds+offset,
+ (i32)width);
+ }
+ }
+ else
+ {
+ if (tmp[0].top)
+ {
+ FilterHorChromaEdge(dataCb, tmp[0].top, thresholds+offset,
+ (i32)width);
+ FilterHorChromaEdge(dataCr, tmp[0].top, thresholds+offset,
+ (i32)width);
+ }
+ if (tmp[1].top)
+ {
+ FilterHorChromaEdge(dataCb+2, tmp[1].top, thresholds+offset,
+ (i32)width);
+ FilterHorChromaEdge(dataCr+2, tmp[1].top, thresholds+offset,
+ (i32)width);
+ }
+ if (tmp[2].top)
+ {
+ FilterHorChromaEdge(dataCb+4, tmp[2].top, thresholds+offset,
+ (i32)width);
+ FilterHorChromaEdge(dataCr+4, tmp[2].top, thresholds+offset,
+ (i32)width);
+ }
+ if (tmp[3].top)
+ {
+ FilterHorChromaEdge(dataCb+6, tmp[3].top, thresholds+offset,
+ (i32)width);
+ FilterHorChromaEdge(dataCr+6, tmp[3].top, thresholds+offset,
+ (i32)width);
+ }
+ }
+
+ tmp += 8;
+ dataCb += width*4;
+ dataCr += width*4;
+ offset = INNER;
+ }
+}
+
+#else /* H264DEC_OMXDL */
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdFilterPicture
+
+ Functional description:
+ Perform deblocking filtering for a picture. Filter does not copy
+ the original picture anywhere but filtering is performed directly
+ on the original image. Parameters controlling the filtering process
+ are computed based on information in macroblock structures of the
+ filtered macroblock, macroblock above and macroblock on the left of
+ the filtered one.
+
+ Inputs:
+ image pointer to image to be filtered
+ mb pointer to macroblock data structure of the top-left
+ macroblock of the picture
+
+ Outputs:
+ image filtered image stored here
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+/*lint --e{550} Symbol not accessed */
+void h264bsdFilterPicture(
+ image_t *image,
+ mbStorage_t *mb)
+{
+
+/* Variables */
+
+ u32 flags;
+ u32 picSizeInMbs, mbRow, mbCol;
+ u32 picWidthInMbs;
+ u8 *data;
+ mbStorage_t *pMb;
+ u8 bS[2][16];
+ u8 thresholdLuma[2][16];
+ u8 thresholdChroma[2][8];
+ u8 alpha[2][2];
+ u8 beta[2][2];
+ OMXResult res;
+
+/* Code */
+
+ ASSERT(image);
+ ASSERT(mb);
+ ASSERT(image->data);
+ ASSERT(image->width);
+ ASSERT(image->height);
+
+ picWidthInMbs = image->width;
+ data = image->data;
+ picSizeInMbs = picWidthInMbs * image->height;
+
+ pMb = mb;
+
+ for (mbRow = 0, mbCol = 0; mbRow < image->height; pMb++)
+ {
+ flags = GetMbFilteringFlags(pMb);
+
+ if (flags)
+ {
+ /* GetBoundaryStrengths function returns non-zero value if any of
+ * the bS values for the macroblock being processed was non-zero */
+ if (GetBoundaryStrengths(pMb, bS, flags))
+ {
+
+ /* Luma */
+ GetLumaEdgeThresholds(pMb,alpha,beta,thresholdLuma,bS,flags);
+ data = image->data + mbRow * picWidthInMbs * 256 + mbCol * 16;
+
+ res = omxVCM4P10_FilterDeblockingLuma_VerEdge_I( data,
+ (OMX_S32)(picWidthInMbs*16),
+ (const OMX_U8*)alpha,
+ (const OMX_U8*)beta,
+ (const OMX_U8*)thresholdLuma,
+ (const OMX_U8*)bS );
+
+ res = omxVCM4P10_FilterDeblockingLuma_HorEdge_I( data,
+ (OMX_S32)(picWidthInMbs*16),
+ (const OMX_U8*)alpha+2,
+ (const OMX_U8*)beta+2,
+ (const OMX_U8*)thresholdLuma+16,
+ (const OMX_U8*)bS+16 );
+ /* Cb */
+ GetChromaEdgeThresholds(pMb, alpha, beta, thresholdChroma,
+ bS, flags, pMb->chromaQpIndexOffset);
+ data = image->data + picSizeInMbs * 256 +
+ mbRow * picWidthInMbs * 64 + mbCol * 8;
+
+ res = omxVCM4P10_FilterDeblockingChroma_VerEdge_I( data,
+ (OMX_S32)(picWidthInMbs*8),
+ (const OMX_U8*)alpha,
+ (const OMX_U8*)beta,
+ (const OMX_U8*)thresholdChroma,
+ (const OMX_U8*)bS );
+ res = omxVCM4P10_FilterDeblockingChroma_HorEdge_I( data,
+ (OMX_S32)(picWidthInMbs*8),
+ (const OMX_U8*)alpha+2,
+ (const OMX_U8*)beta+2,
+ (const OMX_U8*)thresholdChroma+8,
+ (const OMX_U8*)bS+16 );
+ /* Cr */
+ data += (picSizeInMbs * 64);
+ res = omxVCM4P10_FilterDeblockingChroma_VerEdge_I( data,
+ (OMX_S32)(picWidthInMbs*8),
+ (const OMX_U8*)alpha,
+ (const OMX_U8*)beta,
+ (const OMX_U8*)thresholdChroma,
+ (const OMX_U8*)bS );
+ res = omxVCM4P10_FilterDeblockingChroma_HorEdge_I( data,
+ (OMX_S32)(picWidthInMbs*8),
+ (const OMX_U8*)alpha+2,
+ (const OMX_U8*)beta+2,
+ (const OMX_U8*)thresholdChroma+8,
+ (const OMX_U8*)bS+16 );
+ }
+ }
+
+ mbCol++;
+ if (mbCol == picWidthInMbs)
+ {
+ mbCol = 0;
+ mbRow++;
+ }
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: GetBoundaryStrengths
+
+ Functional description:
+ Function to calculate boundary strengths for all edges of a
+ macroblock. Function returns HANTRO_TRUE if any of the bS values for
+ the macroblock had non-zero value, HANTRO_FALSE otherwise.
+
+------------------------------------------------------------------------------*/
+u32 GetBoundaryStrengths(mbStorage_t *mb, u8 (*bS)[16], u32 flags)
+{
+
+/* Variables */
+
+ /* this flag is set HANTRO_TRUE as soon as any boundary strength value is
+ * non-zero */
+ u32 nonZeroBs = HANTRO_FALSE;
+ u32 *pTmp;
+ u32 tmp1, tmp2, isIntraMb;
+
+/* Code */
+
+ ASSERT(mb);
+ ASSERT(bS);
+ ASSERT(flags);
+
+ isIntraMb = IS_INTRA_MB(*mb);
+
+ /* top edges */
+ pTmp = (u32*)&bS[1][0];
+ if (flags & FILTER_TOP_EDGE)
+ {
+ if (isIntraMb || IS_INTRA_MB(*mb->mbB))
+ {
+ *pTmp = 0x04040404;
+ nonZeroBs = HANTRO_TRUE;
+ }
+ else
+ {
+ *pTmp = EdgeBoundaryStrengthTop(mb, mb->mbB);
+ if (*pTmp)
+ nonZeroBs = HANTRO_TRUE;
+ }
+ }
+ else
+ {
+ *pTmp = 0;
+ }
+
+ /* left edges */
+ pTmp = (u32*)&bS[0][0];
+ if (flags & FILTER_LEFT_EDGE)
+ {
+ if (isIntraMb || IS_INTRA_MB(*mb->mbA))
+ {
+ /*bS[0][0] = bS[0][1] = bS[0][2] = bS[0][3] = 4;*/
+ *pTmp = 0x04040404;
+ nonZeroBs = HANTRO_TRUE;
+ }
+ else
+ {
+ *pTmp = EdgeBoundaryStrengthLeft(mb, mb->mbA);
+ if (!nonZeroBs && *pTmp)
+ nonZeroBs = HANTRO_TRUE;
+ }
+ }
+ else
+ {
+ *pTmp = 0;
+ }
+
+ /* inner edges */
+ if (isIntraMb)
+ {
+ pTmp++;
+ *pTmp++ = 0x03030303;
+ *pTmp++ = 0x03030303;
+ *pTmp++ = 0x03030303;
+ pTmp++;
+ *pTmp++ = 0x03030303;
+ *pTmp++ = 0x03030303;
+ *pTmp = 0x03030303;
+
+ nonZeroBs = HANTRO_TRUE;
+ }
+ else
+ {
+ pTmp = (u32*)mb->totalCoeff;
+
+ /* 16x16 inter mb -> ref addresses or motion vectors cannot differ,
+ * only check if either of the blocks contain coefficients */
+ if (h264bsdNumMbPart(mb->mbType) == 1)
+ {
+ tmp1 = *pTmp++;
+ tmp2 = *pTmp++;
+ bS[1][4] = (tmp1 & 0x00FF00FF) ? 2 : 0; /* [2] || [0] */
+ bS[1][5] = (tmp1 & 0xFF00FF00) ? 2 : 0; /* [3] || [1] */
+ bS[0][4] = (tmp1 & 0x0000FFFF) ? 2 : 0; /* [1] || [0] */
+ bS[0][5] = (tmp1 & 0xFFFF0000) ? 2 : 0; /* [3] || [2] */
+
+ tmp1 = *pTmp++;
+ bS[1][6] = (tmp2 & 0x00FF00FF) ? 2 : 0; /* [6] || [4] */
+ bS[1][7] = (tmp2 & 0xFF00FF00) ? 2 : 0; /* [7] || [5] */
+ bS[0][12] = (tmp2 & 0x0000FFFF) ? 2 : 0; /* [5] || [4] */
+ bS[0][13] = (tmp2 & 0xFFFF0000) ? 2 : 0; /* [7] || [6] */
+ tmp2 = *pTmp;
+ bS[1][12] = (tmp1 & 0x00FF00FF) ? 2 : 0; /* [10] || [8] */
+ bS[1][13] = (tmp1 & 0xFF00FF00) ? 2 : 0; /* [11] || [9] */
+ bS[0][6] = (tmp1 & 0x0000FFFF) ? 2 : 0; /* [9] || [8] */
+ bS[0][7] = (tmp1 & 0xFFFF0000) ? 2 : 0; /* [11] || [10] */
+
+ bS[1][14] = (tmp2 & 0x00FF00FF) ? 2 : 0; /* [14] || [12] */
+ bS[1][15] = (tmp2 & 0xFF00FF00) ? 2 : 0; /* [15] || [13] */
+ bS[0][14] = (tmp2 & 0x0000FFFF) ? 2 : 0; /* [13] || [12] */
+ bS[0][15] = (tmp2 & 0xFFFF0000) ? 2 : 0; /* [15] || [14] */
+
+ {
+ u32 tmp3, tmp4;
+
+ tmp1 = mb->totalCoeff[8];
+ tmp2 = mb->totalCoeff[2];
+ tmp3 = mb->totalCoeff[9];
+ tmp4 = mb->totalCoeff[3];
+
+ bS[1][8] = tmp1 || tmp2 ? 2 : 0;
+ tmp1 = mb->totalCoeff[12];
+ tmp2 = mb->totalCoeff[6];
+ bS[1][9] = tmp3 || tmp4 ? 2 : 0;
+ tmp3 = mb->totalCoeff[13];
+ tmp4 = mb->totalCoeff[7];
+ bS[1][10] = tmp1 || tmp2 ? 2 : 0;
+ tmp1 = mb->totalCoeff[4];
+ tmp2 = mb->totalCoeff[1];
+ bS[1][11] = tmp3 || tmp4 ? 2 : 0;
+ tmp3 = mb->totalCoeff[6];
+ tmp4 = mb->totalCoeff[3];
+ bS[0][8] = tmp1 || tmp2 ? 2 : 0;
+ tmp1 = mb->totalCoeff[12];
+ tmp2 = mb->totalCoeff[9];
+ bS[0][9] = tmp3 || tmp4 ? 2 : 0;
+ tmp3 = mb->totalCoeff[14];
+ tmp4 = mb->totalCoeff[11];
+ bS[0][10] = tmp1 || tmp2 ? 2 : 0;
+ bS[0][11] = tmp3 || tmp4 ? 2 : 0;
+ }
+ }
+
+ /* 16x8 inter mb -> ref addresses and motion vectors can be different
+ * only for the middle horizontal edge, for the other top edges it is
+ * enough to check whether the blocks contain coefficients or not. The
+ * same applies to all internal left edges. */
+ else if (mb->mbType == P_L0_L0_16x8)
+ {
+ tmp1 = *pTmp++;
+ tmp2 = *pTmp++;
+ bS[1][4] = (tmp1 & 0x00FF00FF) ? 2 : 0; /* [2] || [0] */
+ bS[1][5] = (tmp1 & 0xFF00FF00) ? 2 : 0; /* [3] || [1] */
+ bS[0][4] = (tmp1 & 0x0000FFFF) ? 2 : 0; /* [1] || [0] */
+ bS[0][5] = (tmp1 & 0xFFFF0000) ? 2 : 0; /* [3] || [2] */
+ tmp1 = *pTmp++;
+ bS[1][6] = (tmp2 & 0x00FF00FF) ? 2 : 0; /* [6] || [4] */
+ bS[1][7] = (tmp2 & 0xFF00FF00) ? 2 : 0; /* [7] || [5] */
+ bS[0][12] = (tmp2 & 0x0000FFFF) ? 2 : 0; /* [5] || [4] */
+ bS[0][13] = (tmp2 & 0xFFFF0000) ? 2 : 0; /* [7] || [6] */
+ tmp2 = *pTmp;
+ bS[1][12] = (tmp1 & 0x00FF00FF) ? 2 : 0; /* [10] || [8] */
+ bS[1][13] = (tmp1 & 0xFF00FF00) ? 2 : 0; /* [11] || [9] */
+ bS[0][6] = (tmp1 & 0x0000FFFF) ? 2 : 0; /* [9] || [8] */
+ bS[0][7] = (tmp1 & 0xFFFF0000) ? 2 : 0; /* [11] || [10] */
+
+ bS[1][14] = (tmp2 & 0x00FF00FF) ? 2 : 0; /* [14] || [12] */
+ bS[1][15] = (tmp2 & 0xFF00FF00) ? 2 : 0; /* [15] || [13] */
+ bS[0][14] = (tmp2 & 0x0000FFFF) ? 2 : 0; /* [13] || [12] */
+ bS[0][15] = (tmp2 & 0xFFFF0000) ? 2 : 0; /* [15] || [14] */
+
+ bS[1][8] = (u8)InnerBoundaryStrength(mb, 8, 2);
+ bS[1][9] = (u8)InnerBoundaryStrength(mb, 9, 3);
+ bS[1][10] = (u8)InnerBoundaryStrength(mb, 12, 6);
+ bS[1][11] = (u8)InnerBoundaryStrength(mb, 13, 7);
+
+ {
+ u32 tmp3, tmp4;
+
+ tmp1 = mb->totalCoeff[4];
+ tmp2 = mb->totalCoeff[1];
+ tmp3 = mb->totalCoeff[6];
+ tmp4 = mb->totalCoeff[3];
+ bS[0][8] = tmp1 || tmp2 ? 2 : 0;
+ tmp1 = mb->totalCoeff[12];
+ tmp2 = mb->totalCoeff[9];
+ bS[0][9] = tmp3 || tmp4 ? 2 : 0;
+ tmp3 = mb->totalCoeff[14];
+ tmp4 = mb->totalCoeff[11];
+ bS[0][10] = tmp1 || tmp2 ? 2 : 0;
+ bS[0][11] = tmp3 || tmp4 ? 2 : 0;
+ }
+ }
+ /* 8x16 inter mb -> ref addresses and motion vectors can be different
+ * only for the middle vertical edge, for the other left edges it is
+ * enough to check whether the blocks contain coefficients or not. The
+ * same applies to all internal top edges. */
+ else if (mb->mbType == P_L0_L0_8x16)
+ {
+ tmp1 = *pTmp++;
+ tmp2 = *pTmp++;
+ bS[1][4] = (tmp1 & 0x00FF00FF) ? 2 : 0; /* [2] || [0] */
+ bS[1][5] = (tmp1 & 0xFF00FF00) ? 2 : 0; /* [3] || [1] */
+ bS[0][4] = (tmp1 & 0x0000FFFF) ? 2 : 0; /* [1] || [0] */
+ bS[0][5] = (tmp1 & 0xFFFF0000) ? 2 : 0; /* [3] || [2] */
+ tmp1 = *pTmp++;
+ bS[1][6] = (tmp2 & 0x00FF00FF) ? 2 : 0; /* [6] || [4] */
+ bS[1][7] = (tmp2 & 0xFF00FF00) ? 2 : 0; /* [7] || [5] */
+ bS[0][12] = (tmp2 & 0x0000FFFF) ? 2 : 0; /* [5] || [4] */
+ bS[0][13] = (tmp2 & 0xFFFF0000) ? 2 : 0; /* [7] || [6] */
+ tmp2 = *pTmp;
+ bS[1][12] = (tmp1 & 0x00FF00FF) ? 2 : 0; /* [10] || [8] */
+ bS[1][13] = (tmp1 & 0xFF00FF00) ? 2 : 0; /* [11] || [9] */
+ bS[0][6] = (tmp1 & 0x0000FFFF) ? 2 : 0; /* [9] || [8] */
+ bS[0][7] = (tmp1 & 0xFFFF0000) ? 2 : 0; /* [11] || [10] */
+
+ bS[1][14] = (tmp2 & 0x00FF00FF) ? 2 : 0; /* [14] || [12] */
+ bS[1][15] = (tmp2 & 0xFF00FF00) ? 2 : 0; /* [15] || [13] */
+ bS[0][14] = (tmp2 & 0x0000FFFF) ? 2 : 0; /* [13] || [12] */
+ bS[0][15] = (tmp2 & 0xFFFF0000) ? 2 : 0; /* [15] || [14] */
+
+ bS[0][8] = (u8)InnerBoundaryStrength(mb, 4, 1);
+ bS[0][9] = (u8)InnerBoundaryStrength(mb, 6, 3);
+ bS[0][10] = (u8)InnerBoundaryStrength(mb, 12, 9);
+ bS[0][11] = (u8)InnerBoundaryStrength(mb, 14, 11);
+
+ {
+ u32 tmp3, tmp4;
+
+ tmp1 = mb->totalCoeff[8];
+ tmp2 = mb->totalCoeff[2];
+ tmp3 = mb->totalCoeff[9];
+ tmp4 = mb->totalCoeff[3];
+ bS[1][8] = tmp1 || tmp2 ? 2 : 0;
+ tmp1 = mb->totalCoeff[12];
+ tmp2 = mb->totalCoeff[6];
+ bS[1][9] = tmp3 || tmp4 ? 2 : 0;
+ tmp3 = mb->totalCoeff[13];
+ tmp4 = mb->totalCoeff[7];
+ bS[1][10] = tmp1 || tmp2 ? 2 : 0;
+ bS[1][11] = tmp3 || tmp4 ? 2 : 0;
+ }
+ }
+ else
+ {
+ tmp1 = *pTmp++;
+ bS[1][4] = (tmp1 & 0x00FF00FF) ? 2 : (u8)InnerBoundaryStrength2(mb, 2, 0);
+ bS[1][5] = (tmp1 & 0xFF00FF00) ? 2 : (u8)InnerBoundaryStrength2(mb, 3, 1);
+ bS[0][4] = (tmp1 & 0x0000FFFF) ? 2 : (u8)InnerBoundaryStrength2(mb, 1, 0);
+ bS[0][5] = (tmp1 & 0xFFFF0000) ? 2 : (u8)InnerBoundaryStrength2(mb, 3, 2);
+ tmp1 = *pTmp++;
+ bS[1][6] = (tmp1 & 0x00FF00FF) ? 2 : (u8)InnerBoundaryStrength2(mb, 6, 4);
+ bS[1][7] = (tmp1 & 0xFF00FF00) ? 2 : (u8)InnerBoundaryStrength2(mb, 7, 5);
+ bS[0][12] = (tmp1 & 0x0000FFFF) ? 2 : (u8)InnerBoundaryStrength2(mb, 5, 4);
+ bS[0][13] = (tmp1 & 0xFFFF0000) ? 2 : (u8)InnerBoundaryStrength2(mb, 7, 6);
+ tmp1 = *pTmp++;
+ bS[1][12] = (tmp1 & 0x00FF00FF) ? 2 : (u8)InnerBoundaryStrength2(mb, 10, 8);
+ bS[1][13] = (tmp1 & 0xFF00FF00) ? 2 : (u8)InnerBoundaryStrength2(mb, 11, 9);
+ bS[0][6] = (tmp1 & 0x0000FFFF) ? 2 : (u8)InnerBoundaryStrength2(mb, 9, 8);
+ bS[0][7] = (tmp1 & 0xFFFF0000) ? 2 : (u8)InnerBoundaryStrength2(mb, 11, 10);
+ tmp1 = *pTmp;
+ bS[1][14] = (tmp1 & 0x00FF00FF) ? 2 : (u8)InnerBoundaryStrength2(mb, 14, 12);
+ bS[1][15] = (tmp1 & 0xFF00FF00) ? 2 : (u8)InnerBoundaryStrength2(mb, 15, 13);
+ bS[0][14] = (tmp1 & 0x0000FFFF) ? 2 : (u8)InnerBoundaryStrength2(mb, 13, 12);
+ bS[0][15] = (tmp1 & 0xFFFF0000) ? 2 : (u8)InnerBoundaryStrength2(mb, 15, 14);
+
+ bS[1][8] = (u8)InnerBoundaryStrength(mb, 8, 2);
+ bS[1][9] = (u8)InnerBoundaryStrength(mb, 9, 3);
+ bS[1][10] = (u8)InnerBoundaryStrength(mb, 12, 6);
+ bS[1][11] = (u8)InnerBoundaryStrength(mb, 13, 7);
+
+ bS[0][8] = (u8)InnerBoundaryStrength(mb, 4, 1);
+ bS[0][9] = (u8)InnerBoundaryStrength(mb, 6, 3);
+ bS[0][10] = (u8)InnerBoundaryStrength(mb, 12, 9);
+ bS[0][11] = (u8)InnerBoundaryStrength(mb, 14, 11);
+ }
+ pTmp = (u32*)&bS[0][0];
+ if (!nonZeroBs && (pTmp[1] || pTmp[2] || pTmp[3] ||
+ pTmp[5] || pTmp[6] || pTmp[7]) )
+ {
+ nonZeroBs = HANTRO_TRUE;
+ }
+ }
+
+ return(nonZeroBs);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: GetLumaEdgeThresholds
+
+ Functional description:
+ Compute alpha, beta and tc0 thresholds for inner, left and top
+ luma edges of a macroblock.
+
+------------------------------------------------------------------------------*/
+void GetLumaEdgeThresholds(
+ mbStorage_t *mb,
+ u8 (*alpha)[2],
+ u8 (*beta)[2],
+ u8 (*threshold)[16],
+ u8 (*bs)[16],
+ u32 filteringFlags )
+{
+
+/* Variables */
+
+ u32 indexA, indexB;
+ u32 qpAv, qp, qpTmp;
+ u32 i;
+
+/* Code */
+
+ ASSERT(threshold);
+ ASSERT(bs);
+ ASSERT(beta);
+ ASSERT(alpha);
+ ASSERT(mb);
+
+ qp = mb->qpY;
+
+ indexA = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetA);
+ indexB = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetB);
+
+ /* Internal edge values */
+ alpha[0][1] = alphas[indexA];
+ alpha[1][1] = alphas[indexA];
+ alpha[1][0] = alphas[indexA];
+ alpha[0][0] = alphas[indexA];
+ beta[0][1] = betas[indexB];
+ beta[1][1] = betas[indexB];
+ beta[1][0] = betas[indexB];
+ beta[0][0] = betas[indexB];
+
+ /* vertical scan order */
+ for (i = 0; i < 2; i++)
+ {
+ u32 t1, t2;
+
+ t1 = bs[i][0];
+ t2 = bs[i][1];
+ threshold[i][0] = (t1) ? tc0[indexA][t1] : 0;
+ t1 = bs[i][2];
+ threshold[i][1] = (t2) ? tc0[indexA][t2] : 0;
+ t2 = bs[i][3];
+ threshold[i][2] = (t1) ? tc0[indexA][t1] : 0;
+ t1 = bs[i][4];
+ threshold[i][3] = (t2) ? tc0[indexA][t2] : 0;
+ t2 = bs[i][5];
+ threshold[i][4] = (t1) ? tc0[indexA][t1] : 0;
+ t1 = bs[i][6];
+ threshold[i][5] = (t2) ? tc0[indexA][t2] : 0;
+ t2 = bs[i][7];
+ threshold[i][6] = (t1) ? tc0[indexA][t1] : 0;
+ t1 = bs[i][8];
+ threshold[i][7] = (t2) ? tc0[indexA][t2] : 0;
+ t2 = bs[i][9];
+ threshold[i][8] = (t1) ? tc0[indexA][t1] : 0;
+ t1 = bs[i][10];
+ threshold[i][9] = (t2) ? tc0[indexA][t2] : 0;
+ t2 = bs[i][11];
+ threshold[i][10] = (t1) ? tc0[indexA][t1] : 0;
+ t1 = bs[i][12];
+ threshold[i][11] = (t2) ? tc0[indexA][t2] : 0;
+ t2 = bs[i][13];
+ threshold[i][12] = (t1) ? tc0[indexA][t1] : 0;
+ t1 = bs[i][14];
+ threshold[i][13] = (t2) ? tc0[indexA][t2] : 0;
+ t2 = bs[i][15];
+ threshold[i][14] = (t1) ? tc0[indexA][t1] : 0;
+ threshold[i][15] = (t2) ? tc0[indexA][t2] : 0;
+ }
+
+ if (filteringFlags & FILTER_TOP_EDGE)
+ {
+ qpTmp = mb->mbB->qpY;
+ if (qpTmp != qp)
+ {
+ u32 t1, t2, t3, t4;
+ qpAv = (qp + qpTmp + 1) >> 1;
+
+ indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
+ indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
+
+ alpha[1][0] = alphas[indexA];
+ beta[1][0] = betas[indexB];
+ t1 = bs[1][0];
+ t2 = bs[1][1];
+ t3 = bs[1][2];
+ t4 = bs[1][3];
+ threshold[1][0] = (t1 && (t1 < 4)) ? tc0[indexA][t1] : 0;
+ threshold[1][1] = (t2 && (t2 < 4)) ? tc0[indexA][t2] : 0;
+ threshold[1][2] = (t3 && (t3 < 4)) ? tc0[indexA][t3] : 0;
+ threshold[1][3] = (t4 && (t4 < 4)) ? tc0[indexA][t4] : 0;
+ }
+ }
+ if (filteringFlags & FILTER_LEFT_EDGE)
+ {
+ qpTmp = mb->mbA->qpY;
+ if (qpTmp != qp)
+ {
+ qpAv = (qp + qpTmp + 1) >> 1;
+
+ indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
+ indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
+
+ alpha[0][0] = alphas[indexA];
+ beta[0][0] = betas[indexB];
+ threshold[0][0] = (bs[0][0] && (bs[0][0] < 4)) ? tc0[indexA][bs[0][0]] : 0;
+ threshold[0][1] = (bs[0][1] && (bs[0][1] < 4)) ? tc0[indexA][bs[0][1]] : 0;
+ threshold[0][2] = (bs[0][2] && (bs[0][2] < 4)) ? tc0[indexA][bs[0][2]] : 0;
+ threshold[0][3] = (bs[0][3] && (bs[0][3] < 4)) ? tc0[indexA][bs[0][3]] : 0;
+ }
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: GetChromaEdgeThresholds
+
+ Functional description:
+ Compute alpha, beta and tc0 thresholds for inner, left and top
+ chroma edges of a macroblock.
+
+------------------------------------------------------------------------------*/
+void GetChromaEdgeThresholds(
+ mbStorage_t *mb,
+ u8 (*alpha)[2],
+ u8 (*beta)[2],
+ u8 (*threshold)[8],
+ u8 (*bs)[16],
+ u32 filteringFlags,
+ i32 chromaQpIndexOffset)
+{
+
+/* Variables */
+
+ u32 indexA, indexB;
+ u32 qpAv, qp, qpTmp;
+ u32 i;
+
+/* Code */
+
+ ASSERT(threshold);
+ ASSERT(bs);
+ ASSERT(beta);
+ ASSERT(alpha);
+ ASSERT(mb);
+ ASSERT(mb);
+
+ qp = mb->qpY;
+ qp = h264bsdQpC[CLIP3(0, 51, (i32)qp + chromaQpIndexOffset)];
+
+ indexA = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetA);
+ indexB = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetB);
+
+ alpha[0][1] = alphas[indexA];
+ alpha[1][1] = alphas[indexA];
+ alpha[1][0] = alphas[indexA];
+ alpha[0][0] = alphas[indexA];
+ beta[0][1] = betas[indexB];
+ beta[1][1] = betas[indexB];
+ beta[1][0] = betas[indexB];
+ beta[0][0] = betas[indexB];
+
+ for (i = 0; i < 2; i++)
+ {
+ u32 t1, t2;
+
+ t1 = bs[i][0];
+ t2 = bs[i][1];
+ threshold[i][0] = (t1) ? tc0[indexA][t1] : 0;
+ t1 = bs[i][2];
+ threshold[i][1] = (t2) ? tc0[indexA][t2] : 0;
+ t2 = bs[i][3];
+ threshold[i][2] = (t1) ? tc0[indexA][t1] : 0;
+ t1 = bs[i][8];
+ threshold[i][3] = (t2) ? tc0[indexA][t2] : 0;
+ t2 = bs[i][9];
+ threshold[i][4] = (t1) ? tc0[indexA][t1] : 0;
+ t1 = bs[i][10];
+ threshold[i][5] = (t2) ? tc0[indexA][t2] : 0;
+ t2 = bs[i][11];
+ threshold[i][6] = (t1) ? tc0[indexA][t1] : 0;
+ threshold[i][7] = (t2) ? tc0[indexA][t2] : 0;
+ }
+
+ if (filteringFlags & FILTER_TOP_EDGE)
+ {
+ qpTmp = mb->mbB->qpY;
+ if (qpTmp != mb->qpY)
+ {
+ u32 t1, t2, t3, t4;
+ qpTmp = h264bsdQpC[CLIP3(0, 51, (i32)qpTmp + chromaQpIndexOffset)];
+ qpAv = (qp + qpTmp + 1) >> 1;
+
+ indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
+ indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
+
+ alpha[1][0] = alphas[indexA];
+ beta[1][0] = betas[indexB];
+
+ t1 = bs[1][0];
+ t2 = bs[1][1];
+ t3 = bs[1][2];
+ t4 = bs[1][3];
+ threshold[1][0] = (t1) ? tc0[indexA][t1] : 0;
+ threshold[1][1] = (t2) ? tc0[indexA][t2] : 0;
+ threshold[1][2] = (t3) ? tc0[indexA][t3] : 0;
+ threshold[1][3] = (t4) ? tc0[indexA][t4] : 0;
+ }
+ }
+ if (filteringFlags & FILTER_LEFT_EDGE)
+ {
+ qpTmp = mb->mbA->qpY;
+ if (qpTmp != mb->qpY)
+ {
+
+ qpTmp = h264bsdQpC[CLIP3(0, 51, (i32)qpTmp + chromaQpIndexOffset)];
+ qpAv = (qp + qpTmp + 1) >> 1;
+
+ indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
+ indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
+
+ alpha[0][0] = alphas[indexA];
+ beta[0][0] = betas[indexB];
+ threshold[0][0] = (bs[0][0]) ? tc0[indexA][bs[0][0]] : 0;
+ threshold[0][1] = (bs[0][1]) ? tc0[indexA][bs[0][1]] : 0;
+ threshold[0][2] = (bs[0][2]) ? tc0[indexA][bs[0][2]] : 0;
+ threshold[0][3] = (bs[0][3]) ? tc0[indexA][bs[0][3]] : 0;
+ }
+ }
+
+}
+
+#endif /* H264DEC_OMXDL */
+
+/*lint +e701 +e702 */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_deblocking.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_deblocking.h
new file mode 100755
index 0000000..2571dda
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_deblocking.h
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_DEBLOCKING_H
+#define H264SWDEC_DEBLOCKING_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_image.h"
+#include "h264bsd_macroblock_layer.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+void h264bsdFilterPicture(
+ image_t *image,
+ mbStorage_t *mb);
+
+#endif /* #ifdef H264SWDEC_DEBLOCKING_H */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_decoder.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_decoder.c
new file mode 100644
index 0000000..a816871
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_decoder.c
@@ -0,0 +1,961 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdInit
+ h264bsdDecode
+ h264bsdShutdown
+ h264bsdCurrentImage
+ h264bsdNextOutputPicture
+ h264bsdPicWidth
+ h264bsdPicHeight
+ h264bsdFlushBuffer
+ h264bsdCheckValidParamSets
+ h264bsdVideoRange
+ h264bsdMatrixCoefficients
+ h264bsdCroppingParams
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_decoder.h"
+#include "h264bsd_nal_unit.h"
+#include "h264bsd_byte_stream.h"
+#include "h264bsd_seq_param_set.h"
+#include "h264bsd_pic_param_set.h"
+#include "h264bsd_slice_header.h"
+#include "h264bsd_slice_data.h"
+#include "h264bsd_neighbour.h"
+#include "h264bsd_util.h"
+#include "h264bsd_dpb.h"
+#include "h264bsd_deblocking.h"
+#include "h264bsd_conceal.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+
+ Function name: h264bsdInit
+
+ Functional description:
+ Initialize the decoder.
+
+ Inputs:
+ noOutputReordering flag to indicate the decoder that it does not
+ have to perform reordering of display images.
+
+ Outputs:
+ pStorage pointer to initialized storage structure
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdInit(storage_t *pStorage, u32 noOutputReordering)
+{
+
+/* Variables */
+ u32 size;
+/* Code */
+
+ ASSERT(pStorage);
+
+ h264bsdInitStorage(pStorage);
+
+ /* allocate mbLayer to be next multiple of 64 to enable use of
+ * specific NEON optimized "memset" for clearing the structure */
+ size = (sizeof(macroblockLayer_t) + 63) & ~0x3F;
+
+ pStorage->mbLayer = (macroblockLayer_t*)H264SwDecMalloc(size);
+ if (!pStorage->mbLayer)
+ return HANTRO_NOK;
+
+ if (noOutputReordering)
+ pStorage->noReordering = HANTRO_TRUE;
+
+ return HANTRO_OK;
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdDecode
+
+ Functional description:
+ Decode a NAL unit. This function calls other modules to perform
+ tasks like
+ * extract and decode NAL unit from the byte stream
+ * decode parameter sets
+ * decode slice header and slice data
+ * conceal errors in the picture
+ * perform deblocking filtering
+
+ This function contains top level control logic of the decoder.
+
+ Inputs:
+ pStorage pointer to storage data structure
+ byteStrm pointer to stream buffer given by application
+ len length of the buffer in bytes
+ picId identifier for a picture, assigned by the
+ application
+
+ Outputs:
+ readBytes number of bytes read from the stream is stored
+ here
+
+ Returns:
+ H264BSD_RDY decoding finished, nothing special
+ H264BSD_PIC_RDY decoding of a picture finished
+ H264BSD_HDRS_RDY param sets activated, information like
+ picture dimensions etc can be read
+ H264BSD_ERROR error in decoding
+ H264BSD_PARAM_SET_ERROR serius error in decoding, failed to
+ activate param sets
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecode(storage_t *pStorage, u8 *byteStrm, u32 len, u32 picId,
+ u32 *readBytes)
+{
+
+/* Variables */
+
+ u32 tmp, ppsId, spsId;
+ i32 picOrderCnt;
+ nalUnit_t nalUnit;
+ seqParamSet_t seqParamSet;
+ picParamSet_t picParamSet;
+ strmData_t strm;
+ u32 accessUnitBoundaryFlag = HANTRO_FALSE;
+ u32 picReady = HANTRO_FALSE;
+
+/* Code */
+
+ ASSERT(pStorage);
+ ASSERT(byteStrm);
+ ASSERT(len);
+ ASSERT(readBytes);
+
+ /* if previous buffer was not finished and same pointer given -> skip NAL
+ * unit extraction */
+ if (pStorage->prevBufNotFinished && byteStrm == pStorage->prevBufPointer)
+ {
+ strm = pStorage->strm[0];
+ strm.pStrmCurrPos = strm.pStrmBuffStart;
+ strm.strmBuffReadBits = strm.bitPosInWord = 0;
+ *readBytes = pStorage->prevBytesConsumed;
+ }
+ else
+ {
+ tmp = h264bsdExtractNalUnit(byteStrm, len, &strm, readBytes);
+ if (tmp != HANTRO_OK)
+ {
+ EPRINT("BYTE_STREAM");
+ return(H264BSD_ERROR);
+ }
+ /* store stream */
+ pStorage->strm[0] = strm;
+ pStorage->prevBytesConsumed = *readBytes;
+ pStorage->prevBufPointer = byteStrm;
+ }
+ pStorage->prevBufNotFinished = HANTRO_FALSE;
+
+ tmp = h264bsdDecodeNalUnit(&strm, &nalUnit);
+ if (tmp != HANTRO_OK)
+ {
+ EPRINT("NAL_UNIT");
+ return(H264BSD_ERROR);
+ }
+
+ /* Discard unspecified, reserved, SPS extension and auxiliary picture slices */
+ if(nalUnit.nalUnitType == 0 || nalUnit.nalUnitType >= 13)
+ {
+ DEBUG(("DISCARDED NAL (UNSPECIFIED, REGISTERED, SPS ext or AUX slice)\n"));
+ return(H264BSD_RDY);
+ }
+
+ tmp = h264bsdCheckAccessUnitBoundary(
+ &strm,
+ &nalUnit,
+ pStorage,
+ &accessUnitBoundaryFlag);
+ if (tmp != HANTRO_OK)
+ {
+ EPRINT("ACCESS UNIT BOUNDARY CHECK");
+ if (tmp == PARAM_SET_ERROR)
+ return(H264BSD_PARAM_SET_ERROR);
+ else
+ return(H264BSD_ERROR);
+ }
+
+ if ( accessUnitBoundaryFlag )
+ {
+ DEBUG(("Access unit boundary\n"));
+ /* conceal if picture started and param sets activated */
+ if (pStorage->picStarted && pStorage->activeSps != NULL)
+ {
+ DEBUG(("CONCEALING..."));
+
+ /* return error if second phase of
+ * initialization is not completed */
+ if (pStorage->pendingActivation)
+ {
+ EPRINT("Pending activation not completed");
+ return (H264BSD_ERROR);
+ }
+
+ if (!pStorage->validSliceInAccessUnit)
+ {
+ pStorage->currImage->data =
+ h264bsdAllocateDpbImage(pStorage->dpb);
+ h264bsdInitRefPicList(pStorage->dpb);
+ tmp = h264bsdConceal(pStorage, pStorage->currImage, P_SLICE);
+ }
+ else
+ tmp = h264bsdConceal(pStorage, pStorage->currImage,
+ pStorage->sliceHeader->sliceType);
+
+ picReady = HANTRO_TRUE;
+
+ /* current NAL unit should be decoded on next activation -> set
+ * readBytes to 0 */
+ *readBytes = 0;
+ pStorage->prevBufNotFinished = HANTRO_TRUE;
+ DEBUG(("...DONE\n"));
+ }
+ else
+ {
+ pStorage->validSliceInAccessUnit = HANTRO_FALSE;
+ }
+ pStorage->skipRedundantSlices = HANTRO_FALSE;
+ }
+
+ if (!picReady)
+ {
+ switch (nalUnit.nalUnitType)
+ {
+ case NAL_SEQ_PARAM_SET:
+ DEBUG(("SEQ PARAM SET\n"));
+ tmp = h264bsdDecodeSeqParamSet(&strm, &seqParamSet);
+ if (tmp != HANTRO_OK)
+ {
+ EPRINT("SEQ_PARAM_SET");
+ FREE(seqParamSet.offsetForRefFrame);
+ FREE(seqParamSet.vuiParameters);
+ return(H264BSD_ERROR);
+ }
+ tmp = h264bsdStoreSeqParamSet(pStorage, &seqParamSet);
+ break;
+
+ case NAL_PIC_PARAM_SET:
+ DEBUG(("PIC PARAM SET\n"));
+ tmp = h264bsdDecodePicParamSet(&strm, &picParamSet);
+ if (tmp != HANTRO_OK)
+ {
+ EPRINT("PIC_PARAM_SET");
+ FREE(picParamSet.runLength);
+ FREE(picParamSet.topLeft);
+ FREE(picParamSet.bottomRight);
+ FREE(picParamSet.sliceGroupId);
+ return(H264BSD_ERROR);
+ }
+ tmp = h264bsdStorePicParamSet(pStorage, &picParamSet);
+ break;
+
+ case NAL_CODED_SLICE_IDR:
+ DEBUG(("IDR "));
+ /* fall through */
+ case NAL_CODED_SLICE:
+ DEBUG(("SLICE HEADER\n"));
+
+ /* picture successfully finished and still decoding same old
+ * access unit -> no need to decode redundant slices */
+ if (pStorage->skipRedundantSlices)
+ return(H264BSD_RDY);
+
+ pStorage->picStarted = HANTRO_TRUE;
+
+ if (h264bsdIsStartOfPicture(pStorage))
+ {
+ pStorage->numConcealedMbs = 0;
+ pStorage->currentPicId = picId;
+
+ tmp = h264bsdCheckPpsId(&strm, &ppsId);
+ ASSERT(tmp == HANTRO_OK);
+ /* store old activeSpsId and return headers ready
+ * indication if activeSps changes */
+ spsId = pStorage->activeSpsId;
+ tmp = h264bsdActivateParamSets(pStorage, ppsId,
+ IS_IDR_NAL_UNIT(&nalUnit) ?
+ HANTRO_TRUE : HANTRO_FALSE);
+ if (tmp != HANTRO_OK)
+ {
+ EPRINT("Param set activation");
+ pStorage->activePpsId = MAX_NUM_PIC_PARAM_SETS;
+ pStorage->activePps = NULL;
+ pStorage->activeSpsId = MAX_NUM_SEQ_PARAM_SETS;
+ pStorage->activeSps = NULL;
+ pStorage->pendingActivation = HANTRO_FALSE;
+
+ if(tmp == MEMORY_ALLOCATION_ERROR)
+ {
+ return H264BSD_MEMALLOC_ERROR;
+ }
+ else
+ return(H264BSD_PARAM_SET_ERROR);
+ }
+
+ if (spsId != pStorage->activeSpsId)
+ {
+ seqParamSet_t *oldSPS = NULL;
+ seqParamSet_t *newSPS = pStorage->activeSps;
+ u32 noOutputOfPriorPicsFlag = 1;
+
+ if(pStorage->oldSpsId < MAX_NUM_SEQ_PARAM_SETS)
+ {
+ oldSPS = pStorage->sps[pStorage->oldSpsId];
+ }
+
+ *readBytes = 0;
+ pStorage->prevBufNotFinished = HANTRO_TRUE;
+
+
+ if(nalUnit.nalUnitType == NAL_CODED_SLICE_IDR)
+ {
+ tmp =
+ h264bsdCheckPriorPicsFlag(&noOutputOfPriorPicsFlag,
+ &strm, newSPS,
+ pStorage->activePps,
+ nalUnit.nalUnitType);
+ }
+ else
+ {
+ tmp = HANTRO_NOK;
+ }
+
+ if((tmp != HANTRO_OK) ||
+ (noOutputOfPriorPicsFlag != 0) ||
+ (pStorage->dpb->noReordering) ||
+ (oldSPS == NULL) ||
+ (oldSPS->picWidthInMbs != newSPS->picWidthInMbs) ||
+ (oldSPS->picHeightInMbs != newSPS->picHeightInMbs) ||
+ (oldSPS->maxDpbSize != newSPS->maxDpbSize))
+ {
+ pStorage->dpb->flushed = 0;
+ }
+ else
+ {
+ h264bsdFlushDpb(pStorage->dpb);
+ }
+
+ pStorage->oldSpsId = pStorage->activeSpsId;
+
+ return(H264BSD_HDRS_RDY);
+ }
+ }
+
+ /* return error if second phase of
+ * initialization is not completed */
+ if (pStorage->pendingActivation)
+ {
+ EPRINT("Pending activation not completed");
+ return (H264BSD_ERROR);
+ }
+ tmp = h264bsdDecodeSliceHeader(&strm, pStorage->sliceHeader + 1,
+ pStorage->activeSps, pStorage->activePps, &nalUnit);
+ if (tmp != HANTRO_OK)
+ {
+ EPRINT("SLICE_HEADER");
+ return(H264BSD_ERROR);
+ }
+ if (h264bsdIsStartOfPicture(pStorage))
+ {
+ if (!IS_IDR_NAL_UNIT(&nalUnit))
+ {
+ tmp = h264bsdCheckGapsInFrameNum(pStorage->dpb,
+ pStorage->sliceHeader[1].frameNum,
+ nalUnit.nalRefIdc != 0 ?
+ HANTRO_TRUE : HANTRO_FALSE,
+ pStorage->activeSps->
+ gapsInFrameNumValueAllowedFlag);
+ if (tmp != HANTRO_OK)
+ {
+ EPRINT("Gaps in frame num");
+ return(H264BSD_ERROR);
+ }
+ }
+ pStorage->currImage->data =
+ h264bsdAllocateDpbImage(pStorage->dpb);
+ }
+
+ /* store slice header to storage if successfully decoded */
+ pStorage->sliceHeader[0] = pStorage->sliceHeader[1];
+ pStorage->validSliceInAccessUnit = HANTRO_TRUE;
+ pStorage->prevNalUnit[0] = nalUnit;
+
+ h264bsdComputeSliceGroupMap(pStorage,
+ pStorage->sliceHeader->sliceGroupChangeCycle);
+
+ h264bsdInitRefPicList(pStorage->dpb);
+ tmp = h264bsdReorderRefPicList(pStorage->dpb,
+ &pStorage->sliceHeader->refPicListReordering,
+ pStorage->sliceHeader->frameNum,
+ pStorage->sliceHeader->numRefIdxL0Active);
+ if (tmp != HANTRO_OK)
+ {
+ EPRINT("Reordering");
+ return(H264BSD_ERROR);
+ }
+
+ DEBUG(("SLICE DATA, FIRST %d\n",
+ pStorage->sliceHeader->firstMbInSlice));
+ tmp = h264bsdDecodeSliceData(&strm, pStorage,
+ pStorage->currImage, pStorage->sliceHeader);
+ if (tmp != HANTRO_OK)
+ {
+ EPRINT("SLICE_DATA");
+ h264bsdMarkSliceCorrupted(pStorage,
+ pStorage->sliceHeader->firstMbInSlice);
+ return(H264BSD_ERROR);
+ }
+
+ if (h264bsdIsEndOfPicture(pStorage))
+ {
+ picReady = HANTRO_TRUE;
+ pStorage->skipRedundantSlices = HANTRO_TRUE;
+ }
+ break;
+
+ case NAL_SEI:
+ DEBUG(("SEI MESSAGE, NOT DECODED"));
+ break;
+
+ default:
+ DEBUG(("NOT IMPLEMENTED YET %d\n",nalUnit.nalUnitType));
+ }
+ }
+
+ if (picReady)
+ {
+ h264bsdFilterPicture(pStorage->currImage, pStorage->mb);
+
+ h264bsdResetStorage(pStorage);
+
+ picOrderCnt = h264bsdDecodePicOrderCnt(pStorage->poc,
+ pStorage->activeSps, pStorage->sliceHeader, pStorage->prevNalUnit);
+
+ if (pStorage->validSliceInAccessUnit)
+ {
+ if (pStorage->prevNalUnit->nalRefIdc)
+ {
+ tmp = h264bsdMarkDecRefPic(pStorage->dpb,
+ &pStorage->sliceHeader->decRefPicMarking,
+ pStorage->currImage, pStorage->sliceHeader->frameNum,
+ picOrderCnt,
+ IS_IDR_NAL_UNIT(pStorage->prevNalUnit) ?
+ HANTRO_TRUE : HANTRO_FALSE,
+ pStorage->currentPicId, pStorage->numConcealedMbs);
+ }
+ /* non-reference picture, just store for possible display
+ * reordering */
+ else
+ {
+ tmp = h264bsdMarkDecRefPic(pStorage->dpb, NULL,
+ pStorage->currImage, pStorage->sliceHeader->frameNum,
+ picOrderCnt,
+ IS_IDR_NAL_UNIT(pStorage->prevNalUnit) ?
+ HANTRO_TRUE : HANTRO_FALSE,
+ pStorage->currentPicId, pStorage->numConcealedMbs);
+ }
+ }
+
+ pStorage->picStarted = HANTRO_FALSE;
+ pStorage->validSliceInAccessUnit = HANTRO_FALSE;
+
+ return(H264BSD_PIC_RDY);
+ }
+ else
+ return(H264BSD_RDY);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdShutdown
+
+ Functional description:
+ Shutdown a decoder instance. Function frees all the memories
+ allocated for the decoder instance.
+
+ Inputs:
+ pStorage pointer to storage data structure
+
+ Returns:
+ none
+
+
+------------------------------------------------------------------------------*/
+
+void h264bsdShutdown(storage_t *pStorage)
+{
+
+/* Variables */
+
+ u32 i;
+
+/* Code */
+
+ ASSERT(pStorage);
+
+ for (i = 0; i < MAX_NUM_SEQ_PARAM_SETS; i++)
+ {
+ if (pStorage->sps[i])
+ {
+ FREE(pStorage->sps[i]->offsetForRefFrame);
+ FREE(pStorage->sps[i]->vuiParameters);
+ FREE(pStorage->sps[i]);
+ }
+ }
+
+ for (i = 0; i < MAX_NUM_PIC_PARAM_SETS; i++)
+ {
+ if (pStorage->pps[i])
+ {
+ FREE(pStorage->pps[i]->runLength);
+ FREE(pStorage->pps[i]->topLeft);
+ FREE(pStorage->pps[i]->bottomRight);
+ FREE(pStorage->pps[i]->sliceGroupId);
+ FREE(pStorage->pps[i]);
+ }
+ }
+
+ FREE(pStorage->mbLayer);
+ FREE(pStorage->mb);
+ FREE(pStorage->sliceGroupMap);
+
+ h264bsdFreeDpb(pStorage->dpb);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdNextOutputPicture
+
+ Functional description:
+ Get next output picture in display order.
+
+ Inputs:
+ pStorage pointer to storage data structure
+
+ Outputs:
+ picId identifier of the picture will be stored here
+ isIdrPic IDR flag of the picture will be stored here
+ numErrMbs number of concealed macroblocks in the picture
+ will be stored here
+
+ Returns:
+ pointer to the picture data
+ NULL if no pictures available for display
+
+------------------------------------------------------------------------------*/
+
+u8* h264bsdNextOutputPicture(storage_t *pStorage, u32 *picId, u32 *isIdrPic,
+ u32 *numErrMbs)
+{
+
+/* Variables */
+
+ dpbOutPicture_t *pOut;
+
+/* Code */
+
+ ASSERT(pStorage);
+
+ pOut = h264bsdDpbOutputPicture(pStorage->dpb);
+
+ if (pOut != NULL)
+ {
+ *picId = pOut->picId;
+ *isIdrPic = pOut->isIdr;
+ *numErrMbs = pOut->numErrMbs;
+ return (pOut->data);
+ }
+ else
+ return(NULL);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdPicWidth
+
+ Functional description:
+ Get width of the picture in macroblocks
+
+ Inputs:
+ pStorage pointer to storage data structure
+
+ Outputs:
+ none
+
+ Returns:
+ picture width
+ 0 if parameters sets not yet activated
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdPicWidth(storage_t *pStorage)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(pStorage);
+
+ if (pStorage->activeSps)
+ return(pStorage->activeSps->picWidthInMbs);
+ else
+ return(0);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdPicHeight
+
+ Functional description:
+ Get height of the picture in macroblocks
+
+ Inputs:
+ pStorage pointer to storage data structure
+
+ Outputs:
+ none
+
+ Returns:
+ picture width
+ 0 if parameters sets not yet activated
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdPicHeight(storage_t *pStorage)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(pStorage);
+
+ if (pStorage->activeSps)
+ return(pStorage->activeSps->picHeightInMbs);
+ else
+ return(0);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdFlushBuffer
+
+ Functional description:
+ Flush the decoded picture buffer, see dpb.c for details
+
+ Inputs:
+ pStorage pointer to storage data structure
+
+------------------------------------------------------------------------------*/
+
+void h264bsdFlushBuffer(storage_t *pStorage)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(pStorage);
+
+ h264bsdFlushDpb(pStorage->dpb);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdCheckValidParamSets
+
+ Functional description:
+ Check if any valid parameter set combinations (SPS/PPS) exists.
+
+ Inputs:
+ pStorage pointer to storage structure
+
+ Returns:
+ 1 at least one valid SPS/PPS combination found
+ 0 no valid param set combinations found
+
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdCheckValidParamSets(storage_t *pStorage)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(pStorage);
+
+ return(h264bsdValidParamSets(pStorage) == HANTRO_OK ? 1 : 0);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdVideoRange
+
+ Functional description:
+ Get value of video_full_range_flag received in the VUI data.
+
+ Inputs:
+ pStorage pointer to storage structure
+
+ Returns:
+ 1 video_full_range_flag received and value is 1
+ 0 otherwise
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdVideoRange(storage_t *pStorage)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(pStorage);
+
+ if (pStorage->activeSps && pStorage->activeSps->vuiParametersPresentFlag &&
+ pStorage->activeSps->vuiParameters &&
+ pStorage->activeSps->vuiParameters->videoSignalTypePresentFlag &&
+ pStorage->activeSps->vuiParameters->videoFullRangeFlag)
+ return(1);
+ else /* default value of video_full_range_flag is 0 */
+ return(0);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdMatrixCoefficients
+
+ Functional description:
+ Get value of matrix_coefficients received in the VUI data
+
+ Inputs:
+ pStorage pointer to storage structure
+
+ Outputs:
+ value of matrix_coefficients if received
+ 2 otherwise (this is the default value)
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdMatrixCoefficients(storage_t *pStorage)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(pStorage);
+
+ if (pStorage->activeSps && pStorage->activeSps->vuiParametersPresentFlag &&
+ pStorage->activeSps->vuiParameters &&
+ pStorage->activeSps->vuiParameters->videoSignalTypePresentFlag &&
+ pStorage->activeSps->vuiParameters->colourDescriptionPresentFlag)
+ return(pStorage->activeSps->vuiParameters->matrixCoefficients);
+ else /* default unspecified */
+ return(2);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: hh264bsdCroppingParams
+
+ Functional description:
+ Get cropping parameters of the active SPS
+
+ Inputs:
+ pStorage pointer to storage structure
+
+ Outputs:
+ croppingFlag flag indicating if cropping params present is
+ stored here
+ leftOffset cropping left offset in pixels is stored here
+ width width of the image after cropping is stored here
+ topOffset cropping top offset in pixels is stored here
+ height height of the image after cropping is stored here
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+void h264bsdCroppingParams(storage_t *pStorage, u32 *croppingFlag,
+ u32 *leftOffset, u32 *width, u32 *topOffset, u32 *height)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(pStorage);
+
+ if (pStorage->activeSps && pStorage->activeSps->frameCroppingFlag)
+ {
+ *croppingFlag = 1;
+ *leftOffset = 2 * pStorage->activeSps->frameCropLeftOffset;
+ *width = 16 * pStorage->activeSps->picWidthInMbs -
+ 2 * (pStorage->activeSps->frameCropLeftOffset +
+ pStorage->activeSps->frameCropRightOffset);
+ *topOffset = 2 * pStorage->activeSps->frameCropTopOffset;
+ *height = 16 * pStorage->activeSps->picHeightInMbs -
+ 2 * (pStorage->activeSps->frameCropTopOffset +
+ pStorage->activeSps->frameCropBottomOffset);
+ }
+ else
+ {
+ *croppingFlag = 0;
+ *leftOffset = 0;
+ *width = 0;
+ *topOffset = 0;
+ *height = 0;
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdSampleAspectRatio
+
+ Functional description:
+ Get aspect ratio received in the VUI data
+
+ Inputs:
+ pStorage pointer to storage structure
+
+ Outputs:
+ sarWidth sample aspect ratio height
+ sarHeight sample aspect ratio width
+
+------------------------------------------------------------------------------*/
+
+void h264bsdSampleAspectRatio(storage_t *pStorage, u32 *sarWidth, u32 *sarHeight)
+{
+
+/* Variables */
+ u32 w = 1;
+ u32 h = 1;
+/* Code */
+
+ ASSERT(pStorage);
+
+
+ if (pStorage->activeSps &&
+ pStorage->activeSps->vuiParametersPresentFlag &&
+ pStorage->activeSps->vuiParameters &&
+ pStorage->activeSps->vuiParameters->aspectRatioPresentFlag )
+ {
+ switch (pStorage->activeSps->vuiParameters->aspectRatioIdc)
+ {
+ case ASPECT_RATIO_UNSPECIFIED: w = 0; h = 0; break;
+ case ASPECT_RATIO_1_1: w = 1; h = 1; break;
+ case ASPECT_RATIO_12_11: w = 12; h = 11; break;
+ case ASPECT_RATIO_10_11: w = 10; h = 11; break;
+ case ASPECT_RATIO_16_11: w = 16; h = 11; break;
+ case ASPECT_RATIO_40_33: w = 40; h = 33; break;
+ case ASPECT_RATIO_24_11: w = 24; h = 11; break;
+ case ASPECT_RATIO_20_11: w = 20; h = 11; break;
+ case ASPECT_RATIO_32_11: w = 32; h = 11; break;
+ case ASPECT_RATIO_80_33: w = 80; h = 33; break;
+ case ASPECT_RATIO_18_11: w = 18; h = 11; break;
+ case ASPECT_RATIO_15_11: w = 15; h = 11; break;
+ case ASPECT_RATIO_64_33: w = 64; h = 33; break;
+ case ASPECT_RATIO_160_99: w = 160; h = 99; break;
+ case ASPECT_RATIO_EXTENDED_SAR:
+ w = pStorage->activeSps->vuiParameters->sarWidth;
+ h = pStorage->activeSps->vuiParameters->sarHeight;
+ if ((w == 0) || (h == 0))
+ w = h = 0;
+ break;
+ default:
+ w = 0;
+ h = 0;
+ break;
+ }
+ }
+
+ /* set aspect ratio*/
+ *sarWidth = w;
+ *sarHeight = h;
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdProfile
+
+ Functional description:
+ Get profile information from active SPS
+
+ Inputs:
+ pStorage pointer to storage structure
+
+ Outputs:
+ profile current profile
+
+------------------------------------------------------------------------------*/
+u32 h264bsdProfile(storage_t *pStorage)
+{
+ if (pStorage->activeSps)
+ return pStorage->activeSps->profileIdc;
+ else
+ return 0;
+}
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_decoder.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_decoder.h
new file mode 100644
index 0000000..8336523
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_decoder.h
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_DECODER_H
+#define H264SWDEC_DECODER_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_storage.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+/* enumerated return values of the functions */
+enum {
+ H264BSD_RDY,
+ H264BSD_PIC_RDY,
+ H264BSD_HDRS_RDY,
+ H264BSD_ERROR,
+ H264BSD_PARAM_SET_ERROR,
+ H264BSD_MEMALLOC_ERROR
+};
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+u32 h264bsdInit(storage_t *pStorage, u32 noOutputReordering);
+u32 h264bsdDecode(storage_t *pStorage, u8 *byteStrm, u32 len, u32 picId,
+ u32 *readBytes);
+void h264bsdShutdown(storage_t *pStorage);
+
+u8* h264bsdNextOutputPicture(storage_t *pStorage, u32 *picId, u32 *isIdrPic,
+ u32 *numErrMbs);
+
+u32 h264bsdPicWidth(storage_t *pStorage);
+u32 h264bsdPicHeight(storage_t *pStorage);
+u32 h264bsdVideoRange(storage_t *pStorage);
+u32 h264bsdMatrixCoefficients(storage_t *pStorage);
+void h264bsdCroppingParams(storage_t *pStorage, u32 *croppingFlag,
+ u32 *left, u32 *width, u32 *top, u32 *height);
+void h264bsdSampleAspectRatio(storage_t *pStorage,
+ u32 *sarWidth, u32 *sarHeight);
+u32 h264bsdCheckValidParamSets(storage_t *pStorage);
+
+void h264bsdFlushBuffer(storage_t *pStorage);
+
+u32 h264bsdProfile(storage_t *pStorage);
+
+#endif /* #ifdef H264SWDEC_DECODER_H */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_dpb.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_dpb.c
new file mode 100755
index 0000000..9517d0a
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_dpb.c
@@ -0,0 +1,1584 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ ComparePictures
+ h264bsdReorderRefPicList
+ Mmcop1
+ Mmcop2
+ Mmcop3
+ Mmcop4
+ Mmcop5
+ Mmcop6
+ h264bsdMarkDecRefPic
+ h264bsdGetRefPicData
+ h264bsdAllocateDpbImage
+ SlidingWindowRefPicMarking
+ h264bsdInitDpb
+ h264bsdResetDpb
+ h264bsdInitRefPicList
+ FindDpbPic
+ SetPicNums
+ h264bsdCheckGapsInFrameNum
+ FindSmallestPicOrderCnt
+ OutputPicture
+ h264bsdDpbOutputPicture
+ h264bsdFlushDpb
+ h264bsdFreeDpb
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_cfg.h"
+#include "h264bsd_dpb.h"
+#include "h264bsd_slice_header.h"
+#include "h264bsd_image.h"
+#include "h264bsd_util.h"
+#include "basetype.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/* macros to determine picture status. Note that IS_SHORT_TERM macro returns
+ * true also for non-existing pictures because non-existing pictures are
+ * regarded short term pictures according to H.264 standard */
+#define IS_REFERENCE(a) ((a).status)
+#define IS_EXISTING(a) ((a).status > NON_EXISTING)
+#define IS_SHORT_TERM(a) \
+ ((a).status == NON_EXISTING || (a).status == SHORT_TERM)
+#define IS_LONG_TERM(a) ((a).status == LONG_TERM)
+
+/* macro to set a picture unused for reference */
+#define SET_UNUSED(a) (a).status = UNUSED;
+
+#define MAX_NUM_REF_IDX_L0_ACTIVE 16
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+static i32 ComparePictures(const void *ptr1, const void *ptr2);
+
+static u32 Mmcop1(dpbStorage_t *dpb, u32 currPicNum, u32 differenceOfPicNums);
+
+static u32 Mmcop2(dpbStorage_t *dpb, u32 longTermPicNum);
+
+static u32 Mmcop3(dpbStorage_t *dpb, u32 currPicNum, u32 differenceOfPicNums,
+ u32 longTermFrameIdx);
+
+static u32 Mmcop4(dpbStorage_t *dpb, u32 maxLongTermFrameIdx);
+
+static u32 Mmcop5(dpbStorage_t *dpb);
+
+static u32 Mmcop6(dpbStorage_t *dpb, u32 frameNum, i32 picOrderCnt,
+ u32 longTermFrameIdx);
+
+static u32 SlidingWindowRefPicMarking(dpbStorage_t *dpb);
+
+static i32 FindDpbPic(dpbStorage_t *dpb, i32 picNum, u32 isShortTerm);
+
+static void SetPicNums(dpbStorage_t *dpb, u32 currFrameNum);
+
+static dpbPicture_t* FindSmallestPicOrderCnt(dpbStorage_t *dpb);
+
+static u32 OutputPicture(dpbStorage_t *dpb);
+
+static void ShellSort(dpbPicture_t *pPic, u32 num);
+
+/*------------------------------------------------------------------------------
+
+ Function: ComparePictures
+
+ Functional description:
+ Function to compare dpb pictures, used by the ShellSort() function.
+ Order of the pictures after sorting shall be as follows:
+ 1) short term reference pictures starting with the largest
+ picNum
+ 2) long term reference pictures starting with the smallest
+ longTermPicNum
+ 3) pictures unused for reference but needed for display
+ 4) other pictures
+
+ Returns:
+ -1 pic 1 is greater than pic 2
+ 0 equal from comparison point of view
+ 1 pic 2 is greater then pic 1
+
+------------------------------------------------------------------------------*/
+
+static i32 ComparePictures(const void *ptr1, const void *ptr2)
+{
+
+/* Variables */
+
+ dpbPicture_t *pic1, *pic2;
+
+/* Code */
+
+ ASSERT(ptr1);
+ ASSERT(ptr2);
+
+ pic1 = (dpbPicture_t*)ptr1;
+ pic2 = (dpbPicture_t*)ptr2;
+
+ /* both are non-reference pictures, check if needed for display */
+ if (!IS_REFERENCE(*pic1) && !IS_REFERENCE(*pic2))
+ {
+ if (pic1->toBeDisplayed && !pic2->toBeDisplayed)
+ return(-1);
+ else if (!pic1->toBeDisplayed && pic2->toBeDisplayed)
+ return(1);
+ else
+ return(0);
+ }
+ /* only pic 1 needed for reference -> greater */
+ else if (!IS_REFERENCE(*pic2))
+ return(-1);
+ /* only pic 2 needed for reference -> greater */
+ else if (!IS_REFERENCE(*pic1))
+ return(1);
+ /* both are short term reference pictures -> check picNum */
+ else if (IS_SHORT_TERM(*pic1) && IS_SHORT_TERM(*pic2))
+ {
+ if (pic1->picNum > pic2->picNum)
+ return(-1);
+ else if (pic1->picNum < pic2->picNum)
+ return(1);
+ else
+ return(0);
+ }
+ /* only pic 1 is short term -> greater */
+ else if (IS_SHORT_TERM(*pic1))
+ return(-1);
+ /* only pic 2 is short term -> greater */
+ else if (IS_SHORT_TERM(*pic2))
+ return(1);
+ /* both are long term reference pictures -> check picNum (contains the
+ * longTermPicNum */
+ else
+ {
+ if (pic1->picNum > pic2->picNum)
+ return(1);
+ else if (pic1->picNum < pic2->picNum)
+ return(-1);
+ else
+ return(0);
+ }
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdReorderRefPicList
+
+ Functional description:
+ Function to perform reference picture list reordering based on
+ reordering commands received in the slice header. See details
+ of the process in the H.264 standard.
+
+ Inputs:
+ dpb pointer to dpb storage structure
+ order pointer to reordering commands
+ currFrameNum current frame number
+ numRefIdxActive number of active reference indices for current
+ picture
+
+ Outputs:
+ dpb 'list' field of the structure reordered
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK if non-existing pictures referred to in the
+ reordering commands
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdReorderRefPicList(
+ dpbStorage_t *dpb,
+ refPicListReordering_t *order,
+ u32 currFrameNum,
+ u32 numRefIdxActive)
+{
+
+/* Variables */
+
+ u32 i, j, k, picNumPred, refIdx;
+ i32 picNum, picNumNoWrap, index;
+ u32 isShortTerm;
+
+/* Code */
+
+ ASSERT(order);
+ ASSERT(currFrameNum <= dpb->maxFrameNum);
+ ASSERT(numRefIdxActive <= MAX_NUM_REF_IDX_L0_ACTIVE);
+
+ /* set dpb picture numbers for sorting */
+ SetPicNums(dpb, currFrameNum);
+
+ if (!order->refPicListReorderingFlagL0)
+ return(HANTRO_OK);
+
+ refIdx = 0;
+ picNumPred = currFrameNum;
+
+ i = 0;
+ while (order->command[i].reorderingOfPicNumsIdc < 3)
+ {
+ /* short term */
+ if (order->command[i].reorderingOfPicNumsIdc < 2)
+ {
+ if (order->command[i].reorderingOfPicNumsIdc == 0)
+ {
+ picNumNoWrap =
+ (i32)picNumPred - (i32)order->command[i].absDiffPicNum;
+ if (picNumNoWrap < 0)
+ picNumNoWrap += (i32)dpb->maxFrameNum;
+ }
+ else
+ {
+ picNumNoWrap =
+ (i32)(picNumPred + order->command[i].absDiffPicNum);
+ if (picNumNoWrap >= (i32)dpb->maxFrameNum)
+ picNumNoWrap -= (i32)dpb->maxFrameNum;
+ }
+ picNumPred = (u32)picNumNoWrap;
+ picNum = picNumNoWrap;
+ if ((u32)picNumNoWrap > currFrameNum)
+ picNum -= (i32)dpb->maxFrameNum;
+ isShortTerm = HANTRO_TRUE;
+ }
+ /* long term */
+ else
+ {
+ picNum = (i32)order->command[i].longTermPicNum;
+ isShortTerm = HANTRO_FALSE;
+
+ }
+ /* find corresponding picture from dpb */
+ index = FindDpbPic(dpb, picNum, isShortTerm);
+ if (index < 0 || !IS_EXISTING(dpb->buffer[index]))
+ return(HANTRO_NOK);
+
+ /* shift pictures */
+ for (j = numRefIdxActive; j > refIdx; j--)
+ dpb->list[j] = dpb->list[j-1];
+ /* put picture into the list */
+ dpb->list[refIdx++] = &dpb->buffer[index];
+ /* remove later references to the same picture */
+ for (j = k = refIdx; j <= numRefIdxActive; j++)
+ if(dpb->list[j] != &dpb->buffer[index])
+ dpb->list[k++] = dpb->list[j];
+
+ i++;
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Mmcop1
+
+ Functional description:
+ Function to mark a short-term reference picture unused for
+ reference, memory_management_control_operation equal to 1
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK failure, picture does not exist in the buffer
+
+------------------------------------------------------------------------------*/
+
+static u32 Mmcop1(dpbStorage_t *dpb, u32 currPicNum, u32 differenceOfPicNums)
+{
+
+/* Variables */
+
+ i32 index, picNum;
+
+/* Code */
+
+ ASSERT(currPicNum < dpb->maxFrameNum);
+
+ picNum = (i32)currPicNum - (i32)differenceOfPicNums;
+
+ index = FindDpbPic(dpb, picNum, HANTRO_TRUE);
+ if (index < 0)
+ return(HANTRO_NOK);
+
+ SET_UNUSED(dpb->buffer[index]);
+ dpb->numRefFrames--;
+ if (!dpb->buffer[index].toBeDisplayed)
+ dpb->fullness--;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Mmcop2
+
+ Functional description:
+ Function to mark a long-term reference picture unused for
+ reference, memory_management_control_operation equal to 2
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK failure, picture does not exist in the buffer
+
+------------------------------------------------------------------------------*/
+
+static u32 Mmcop2(dpbStorage_t *dpb, u32 longTermPicNum)
+{
+
+/* Variables */
+
+ i32 index;
+
+/* Code */
+
+ index = FindDpbPic(dpb, (i32)longTermPicNum, HANTRO_FALSE);
+ if (index < 0)
+ return(HANTRO_NOK);
+
+ SET_UNUSED(dpb->buffer[index]);
+ dpb->numRefFrames--;
+ if (!dpb->buffer[index].toBeDisplayed)
+ dpb->fullness--;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Mmcop3
+
+ Functional description:
+ Function to assing a longTermFrameIdx to a short-term reference
+ frame (i.e. to change it to a long-term reference picture),
+ memory_management_control_operation equal to 3
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK failure, short-term picture does not exist in the
+ buffer or is a non-existing picture, or invalid
+ longTermFrameIdx given
+
+------------------------------------------------------------------------------*/
+
+static u32 Mmcop3(dpbStorage_t *dpb, u32 currPicNum, u32 differenceOfPicNums,
+ u32 longTermFrameIdx)
+{
+
+/* Variables */
+
+ i32 index, picNum;
+ u32 i;
+
+/* Code */
+
+ ASSERT(dpb);
+ ASSERT(currPicNum < dpb->maxFrameNum);
+
+ if ( (dpb->maxLongTermFrameIdx == NO_LONG_TERM_FRAME_INDICES) ||
+ (longTermFrameIdx > dpb->maxLongTermFrameIdx) )
+ return(HANTRO_NOK);
+
+ /* check if a long term picture with the same longTermFrameIdx already
+ * exist and remove it if necessary */
+ for (i = 0; i < dpb->maxRefFrames; i++)
+ if (IS_LONG_TERM(dpb->buffer[i]) &&
+ (u32)dpb->buffer[i].picNum == longTermFrameIdx)
+ {
+ SET_UNUSED(dpb->buffer[i]);
+ dpb->numRefFrames--;
+ if (!dpb->buffer[i].toBeDisplayed)
+ dpb->fullness--;
+ break;
+ }
+
+ picNum = (i32)currPicNum - (i32)differenceOfPicNums;
+
+ index = FindDpbPic(dpb, picNum, HANTRO_TRUE);
+ if (index < 0)
+ return(HANTRO_NOK);
+ if (!IS_EXISTING(dpb->buffer[index]))
+ return(HANTRO_NOK);
+
+ dpb->buffer[index].status = LONG_TERM;
+ dpb->buffer[index].picNum = (i32)longTermFrameIdx;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Mmcop4
+
+ Functional description:
+ Function to set maxLongTermFrameIdx,
+ memory_management_control_operation equal to 4
+
+ Returns:
+ HANTRO_OK success
+
+------------------------------------------------------------------------------*/
+
+static u32 Mmcop4(dpbStorage_t *dpb, u32 maxLongTermFrameIdx)
+{
+
+/* Variables */
+
+ u32 i;
+
+/* Code */
+
+ dpb->maxLongTermFrameIdx = maxLongTermFrameIdx;
+
+ for (i = 0; i < dpb->maxRefFrames; i++)
+ if (IS_LONG_TERM(dpb->buffer[i]) &&
+ ( ((u32)dpb->buffer[i].picNum > maxLongTermFrameIdx) ||
+ (dpb->maxLongTermFrameIdx == NO_LONG_TERM_FRAME_INDICES) ) )
+ {
+ SET_UNUSED(dpb->buffer[i]);
+ dpb->numRefFrames--;
+ if (!dpb->buffer[i].toBeDisplayed)
+ dpb->fullness--;
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Mmcop5
+
+ Functional description:
+ Function to mark all reference pictures unused for reference and
+ set maxLongTermFrameIdx to NO_LONG_TERM_FRAME_INDICES,
+ memory_management_control_operation equal to 5. Function flushes
+ the buffer and places all pictures that are needed for display into
+ the output buffer.
+
+ Returns:
+ HANTRO_OK success
+
+------------------------------------------------------------------------------*/
+
+static u32 Mmcop5(dpbStorage_t *dpb)
+{
+
+/* Variables */
+
+ u32 i;
+
+/* Code */
+
+ for (i = 0; i < 16; i++)
+ {
+ if (IS_REFERENCE(dpb->buffer[i]))
+ {
+ SET_UNUSED(dpb->buffer[i]);
+ if (!dpb->buffer[i].toBeDisplayed)
+ dpb->fullness--;
+ }
+ }
+
+ /* output all pictures */
+ while (OutputPicture(dpb) == HANTRO_OK)
+ ;
+ dpb->numRefFrames = 0;
+ dpb->maxLongTermFrameIdx = NO_LONG_TERM_FRAME_INDICES;
+ dpb->prevRefFrameNum = 0;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Mmcop6
+
+ Functional description:
+ Function to assign longTermFrameIdx to the current picture,
+ memory_management_control_operation equal to 6
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK invalid longTermFrameIdx or no room for current
+ picture in the buffer
+
+------------------------------------------------------------------------------*/
+
+static u32 Mmcop6(dpbStorage_t *dpb, u32 frameNum, i32 picOrderCnt,
+ u32 longTermFrameIdx)
+{
+
+/* Variables */
+
+ u32 i;
+
+/* Code */
+
+ ASSERT(frameNum < dpb->maxFrameNum);
+
+ if ( (dpb->maxLongTermFrameIdx == NO_LONG_TERM_FRAME_INDICES) ||
+ (longTermFrameIdx > dpb->maxLongTermFrameIdx) )
+ return(HANTRO_NOK);
+
+ /* check if a long term picture with the same longTermFrameIdx already
+ * exist and remove it if necessary */
+ for (i = 0; i < dpb->maxRefFrames; i++)
+ if (IS_LONG_TERM(dpb->buffer[i]) &&
+ (u32)dpb->buffer[i].picNum == longTermFrameIdx)
+ {
+ SET_UNUSED(dpb->buffer[i]);
+ dpb->numRefFrames--;
+ if (!dpb->buffer[i].toBeDisplayed)
+ dpb->fullness--;
+ break;
+ }
+
+ if (dpb->numRefFrames < dpb->maxRefFrames)
+ {
+ dpb->currentOut->frameNum = frameNum;
+ dpb->currentOut->picNum = (i32)longTermFrameIdx;
+ dpb->currentOut->picOrderCnt = picOrderCnt;
+ dpb->currentOut->status = LONG_TERM;
+ if (dpb->noReordering)
+ dpb->currentOut->toBeDisplayed = HANTRO_FALSE;
+ else
+ dpb->currentOut->toBeDisplayed = HANTRO_TRUE;
+ dpb->numRefFrames++;
+ dpb->fullness++;
+ return(HANTRO_OK);
+ }
+ /* if there is no room, return an error */
+ else
+ return(HANTRO_NOK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdMarkDecRefPic
+
+ Functional description:
+ Function to perform reference picture marking process. This
+ function should be called both for reference and non-reference
+ pictures. Non-reference pictures shall have mark pointer set to
+ NULL.
+
+ Inputs:
+ dpb pointer to the DPB data structure
+ mark pointer to reference picture marking commands
+ image pointer to current picture to be placed in the buffer
+ frameNum frame number of the current picture
+ picOrderCnt picture order count for the current picture
+ isIdr flag to indicate if the current picture is an
+ IDR picture
+ currentPicId identifier for the current picture, from the
+ application, stored along with the picture
+ numErrMbs number of concealed macroblocks in the current
+ picture, stored along with the picture
+
+ Outputs:
+ dpb 'buffer' modified, possible output frames placed into
+ 'outBuf'
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK failure
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdMarkDecRefPic(
+ dpbStorage_t *dpb,
+ decRefPicMarking_t *mark,
+ image_t *image,
+ u32 frameNum,
+ i32 picOrderCnt,
+ u32 isIdr,
+ u32 currentPicId,
+ u32 numErrMbs)
+{
+
+/* Variables */
+
+ u32 i, status;
+ u32 markedAsLongTerm;
+ u32 toBeDisplayed;
+
+/* Code */
+
+ ASSERT(dpb);
+ ASSERT(mark || !isIdr);
+ ASSERT(!isIdr || (frameNum == 0 && picOrderCnt == 0));
+ ASSERT(frameNum < dpb->maxFrameNum);
+
+ if (image->data != dpb->currentOut->data)
+ {
+ EPRINT("TRYING TO MARK NON-ALLOCATED IMAGE");
+ return(HANTRO_NOK);
+ }
+
+ dpb->lastContainsMmco5 = HANTRO_FALSE;
+ status = HANTRO_OK;
+
+ toBeDisplayed = dpb->noReordering ? HANTRO_FALSE : HANTRO_TRUE;
+
+ /* non-reference picture, stored for display reordering purposes */
+ if (mark == NULL)
+ {
+ dpb->currentOut->status = UNUSED;
+ dpb->currentOut->frameNum = frameNum;
+ dpb->currentOut->picNum = (i32)frameNum;
+ dpb->currentOut->picOrderCnt = picOrderCnt;
+ dpb->currentOut->toBeDisplayed = toBeDisplayed;
+ if (!dpb->noReordering)
+ dpb->fullness++;
+ }
+ /* IDR picture */
+ else if (isIdr)
+ {
+
+ /* h264bsdCheckGapsInFrameNum not called for IDR pictures -> have to
+ * reset numOut and outIndex here */
+ dpb->numOut = dpb->outIndex = 0;
+
+ /* flush the buffer */
+ Mmcop5(dpb);
+ /* if noOutputOfPriorPicsFlag was set -> the pictures preceding the
+ * IDR picture shall not be output -> set output buffer empty */
+ if (mark->noOutputOfPriorPicsFlag || dpb->noReordering)
+ {
+ dpb->numOut = 0;
+ dpb->outIndex = 0;
+ }
+
+ if (mark->longTermReferenceFlag)
+ {
+ dpb->currentOut->status = LONG_TERM;
+ dpb->maxLongTermFrameIdx = 0;
+ }
+ else
+ {
+ dpb->currentOut->status = SHORT_TERM;
+ dpb->maxLongTermFrameIdx = NO_LONG_TERM_FRAME_INDICES;
+ }
+ dpb->currentOut->frameNum = 0;
+ dpb->currentOut->picNum = 0;
+ dpb->currentOut->picOrderCnt = 0;
+ dpb->currentOut->toBeDisplayed = toBeDisplayed;
+ dpb->fullness = 1;
+ dpb->numRefFrames = 1;
+ }
+ /* reference picture */
+ else
+ {
+ markedAsLongTerm = HANTRO_FALSE;
+ if (mark->adaptiveRefPicMarkingModeFlag)
+ {
+ i = 0;
+ while (mark->operation[i].memoryManagementControlOperation)
+ {
+ switch (mark->operation[i].memoryManagementControlOperation)
+ {
+ case 1:
+ status = Mmcop1(
+ dpb,
+ frameNum,
+ mark->operation[i].differenceOfPicNums);
+ break;
+
+ case 2:
+ status = Mmcop2(dpb, mark->operation[i].longTermPicNum);
+ break;
+
+ case 3:
+ status = Mmcop3(
+ dpb,
+ frameNum,
+ mark->operation[i].differenceOfPicNums,
+ mark->operation[i].longTermFrameIdx);
+ break;
+
+ case 4:
+ status = Mmcop4(
+ dpb,
+ mark->operation[i].maxLongTermFrameIdx);
+ break;
+
+ case 5:
+ status = Mmcop5(dpb);
+ dpb->lastContainsMmco5 = HANTRO_TRUE;
+ frameNum = 0;
+ break;
+
+ case 6:
+ status = Mmcop6(
+ dpb,
+ frameNum,
+ picOrderCnt,
+ mark->operation[i].longTermFrameIdx);
+ if (status == HANTRO_OK)
+ markedAsLongTerm = HANTRO_TRUE;
+ break;
+
+ default: /* invalid memory management control operation */
+ status = HANTRO_NOK;
+ break;
+ }
+ if (status != HANTRO_OK)
+ {
+ break;
+ }
+ i++;
+ }
+ }
+ else
+ {
+ status = SlidingWindowRefPicMarking(dpb);
+ }
+ /* if current picture was not marked as long-term reference by
+ * memory management control operation 6 -> mark current as short
+ * term and insert it into dpb (if there is room) */
+ if (!markedAsLongTerm)
+ {
+ if (dpb->numRefFrames < dpb->maxRefFrames)
+ {
+ dpb->currentOut->frameNum = frameNum;
+ dpb->currentOut->picNum = (i32)frameNum;
+ dpb->currentOut->picOrderCnt = picOrderCnt;
+ dpb->currentOut->status = SHORT_TERM;
+ dpb->currentOut->toBeDisplayed = toBeDisplayed;
+ dpb->fullness++;
+ dpb->numRefFrames++;
+ }
+ /* no room */
+ else
+ {
+ status = HANTRO_NOK;
+ }
+ }
+ }
+
+ dpb->currentOut->isIdr = isIdr;
+ dpb->currentOut->picId = currentPicId;
+ dpb->currentOut->numErrMbs = numErrMbs;
+
+ /* dpb was initialized to not to reorder the pictures -> output current
+ * picture immediately */
+ if (dpb->noReordering)
+ {
+ ASSERT(dpb->numOut == 0);
+ ASSERT(dpb->outIndex == 0);
+ dpb->outBuf[dpb->numOut].data = dpb->currentOut->data;
+ dpb->outBuf[dpb->numOut].isIdr = dpb->currentOut->isIdr;
+ dpb->outBuf[dpb->numOut].picId = dpb->currentOut->picId;
+ dpb->outBuf[dpb->numOut].numErrMbs = dpb->currentOut->numErrMbs;
+ dpb->numOut++;
+ }
+ else
+ {
+ /* output pictures if buffer full */
+ while (dpb->fullness > dpb->dpbSize)
+ {
+ i = OutputPicture(dpb);
+ ASSERT(i == HANTRO_OK);
+ }
+ }
+
+ /* sort dpb */
+ ShellSort(dpb->buffer, dpb->dpbSize+1);
+
+ return(status);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdGetRefPicData
+
+ Functional description:
+ Function to get reference picture data from the reference picture
+ list
+
+ Returns:
+ pointer to desired reference picture data
+ NULL if invalid index or non-existing picture referred
+
+------------------------------------------------------------------------------*/
+
+u8* h264bsdGetRefPicData(dpbStorage_t *dpb, u32 index)
+{
+
+/* Variables */
+
+/* Code */
+
+ if(index > 16 || dpb->list[index] == NULL)
+ return(NULL);
+ else if(!IS_EXISTING(*dpb->list[index]))
+ return(NULL);
+ else
+ return(dpb->list[index]->data);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdAllocateDpbImage
+
+ Functional description:
+ function to allocate memory for a image. This function does not
+ really allocate any memory but reserves one of the buffer
+ positions for decoding of current picture
+
+ Returns:
+ pointer to memory area for the image
+
+
+------------------------------------------------------------------------------*/
+
+u8* h264bsdAllocateDpbImage(dpbStorage_t *dpb)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT( !dpb->buffer[dpb->dpbSize].toBeDisplayed &&
+ !IS_REFERENCE(dpb->buffer[dpb->dpbSize]) );
+ ASSERT(dpb->fullness <= dpb->dpbSize);
+
+ dpb->currentOut = dpb->buffer + dpb->dpbSize;
+
+ return(dpb->currentOut->data);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: SlidingWindowRefPicMarking
+
+ Functional description:
+ Function to perform sliding window refence picture marking process.
+
+ Outputs:
+ HANTRO_OK success
+ HANTRO_NOK failure, no short-term reference frame found that
+ could be marked unused
+
+
+------------------------------------------------------------------------------*/
+
+static u32 SlidingWindowRefPicMarking(dpbStorage_t *dpb)
+{
+
+/* Variables */
+
+ i32 index, picNum;
+ u32 i;
+
+/* Code */
+
+ if (dpb->numRefFrames < dpb->maxRefFrames)
+ {
+ return(HANTRO_OK);
+ }
+ else
+ {
+ index = -1;
+ picNum = 0;
+ /* find the oldest short term picture */
+ for (i = 0; i < dpb->numRefFrames; i++)
+ if (IS_SHORT_TERM(dpb->buffer[i]))
+ if (dpb->buffer[i].picNum < picNum || index == -1)
+ {
+ index = (i32)i;
+ picNum = dpb->buffer[i].picNum;
+ }
+ if (index >= 0)
+ {
+ SET_UNUSED(dpb->buffer[index]);
+ dpb->numRefFrames--;
+ if (!dpb->buffer[index].toBeDisplayed)
+ dpb->fullness--;
+
+ return(HANTRO_OK);
+ }
+ }
+
+ return(HANTRO_NOK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdInitDpb
+
+ Functional description:
+ Function to initialize DPB. Reserves memories for the buffer,
+ reference picture list and output buffer. dpbSize indicates
+ the maximum DPB size indicated by the levelIdc in the stream.
+ If noReordering flag is FALSE the DPB stores dpbSize pictures
+ for display reordering purposes. On the other hand, if the
+ flag is TRUE the DPB only stores maxRefFrames reference pictures
+ and outputs all the pictures immediately.
+
+ Inputs:
+ picSizeInMbs picture size in macroblocks
+ dpbSize size of the DPB (number of pictures)
+ maxRefFrames max number of reference frames
+ maxFrameNum max frame number
+ noReordering flag to indicate that DPB does not have to
+ prepare to reorder frames for display
+
+ Outputs:
+ dpb pointer to dpb data storage
+
+ Returns:
+ HANTRO_OK success
+ MEMORY_ALLOCATION_ERROR if memory allocation failed
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdInitDpb(
+ dpbStorage_t *dpb,
+ u32 picSizeInMbs,
+ u32 dpbSize,
+ u32 maxRefFrames,
+ u32 maxFrameNum,
+ u32 noReordering)
+{
+
+/* Variables */
+
+ u32 i;
+
+/* Code */
+
+ ASSERT(picSizeInMbs);
+ ASSERT(maxRefFrames <= MAX_NUM_REF_PICS);
+ ASSERT(maxRefFrames <= dpbSize);
+ ASSERT(maxFrameNum);
+ ASSERT(dpbSize);
+
+ dpb->maxLongTermFrameIdx = NO_LONG_TERM_FRAME_INDICES;
+ dpb->maxRefFrames = MAX(maxRefFrames, 1);
+ if (noReordering)
+ dpb->dpbSize = dpb->maxRefFrames;
+ else
+ dpb->dpbSize = dpbSize;
+ dpb->maxFrameNum = maxFrameNum;
+ dpb->noReordering = noReordering;
+ dpb->fullness = 0;
+ dpb->numRefFrames = 0;
+ dpb->prevRefFrameNum = 0;
+
+ ALLOCATE(dpb->buffer, MAX_NUM_REF_IDX_L0_ACTIVE + 1, dpbPicture_t);
+ if (dpb->buffer == NULL)
+ return(MEMORY_ALLOCATION_ERROR);
+ H264SwDecMemset(dpb->buffer, 0,
+ (MAX_NUM_REF_IDX_L0_ACTIVE + 1)*sizeof(dpbPicture_t));
+ for (i = 0; i < dpb->dpbSize + 1; i++)
+ {
+ /* Allocate needed amount of memory, which is:
+ * image size + 32 + 15, where 32 cames from the fact that in ARM OpenMax
+ * DL implementation Functions may read beyond the end of an array,
+ * by a maximum of 32 bytes. And +15 cames for the need to align memory
+ * to 16-byte boundary */
+ ALLOCATE(dpb->buffer[i].pAllocatedData, (picSizeInMbs*384 + 32+15), u8);
+ if (dpb->buffer[i].pAllocatedData == NULL)
+ return(MEMORY_ALLOCATION_ERROR);
+
+ dpb->buffer[i].data = ALIGN(dpb->buffer[i].pAllocatedData, 16);
+ }
+
+ ALLOCATE(dpb->list, MAX_NUM_REF_IDX_L0_ACTIVE + 1, dpbPicture_t*);
+ ALLOCATE(dpb->outBuf, dpb->dpbSize+1, dpbOutPicture_t);
+
+ if (dpb->list == NULL || dpb->outBuf == NULL)
+ return(MEMORY_ALLOCATION_ERROR);
+
+ H264SwDecMemset(dpb->list, 0,
+ ((MAX_NUM_REF_IDX_L0_ACTIVE + 1) * sizeof(dpbPicture_t*)) );
+
+ dpb->numOut = dpb->outIndex = 0;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdResetDpb
+
+ Functional description:
+ Function to reset DPB. This function should be called when an IDR
+ slice (other than the first) activates new sequence parameter set.
+ Function calls h264bsdFreeDpb to free old allocated memories and
+ h264bsdInitDpb to re-initialize the DPB. Same inputs, outputs and
+ returns as for h264bsdInitDpb.
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdResetDpb(
+ dpbStorage_t *dpb,
+ u32 picSizeInMbs,
+ u32 dpbSize,
+ u32 maxRefFrames,
+ u32 maxFrameNum,
+ u32 noReordering)
+{
+
+/* Code */
+
+ ASSERT(picSizeInMbs);
+ ASSERT(maxRefFrames <= MAX_NUM_REF_PICS);
+ ASSERT(maxRefFrames <= dpbSize);
+ ASSERT(maxFrameNum);
+ ASSERT(dpbSize);
+
+ h264bsdFreeDpb(dpb);
+
+ return h264bsdInitDpb(dpb, picSizeInMbs, dpbSize, maxRefFrames,
+ maxFrameNum, noReordering);
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdInitRefPicList
+
+ Functional description:
+ Function to initialize reference picture list. Function just
+ sets pointers in the list according to pictures in the buffer.
+ The buffer is assumed to contain pictures sorted according to
+ what the H.264 standard says about initial reference picture list.
+
+ Inputs:
+ dpb pointer to dpb data structure
+
+ Outputs:
+ dpb 'list' field initialized
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+void h264bsdInitRefPicList(dpbStorage_t *dpb)
+{
+
+/* Variables */
+
+ u32 i;
+
+/* Code */
+
+ for (i = 0; i < dpb->numRefFrames; i++)
+ dpb->list[i] = &dpb->buffer[i];
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: FindDpbPic
+
+ Functional description:
+ Function to find a reference picture from the buffer. The picture
+ to be found is identified by picNum and isShortTerm flag.
+
+ Returns:
+ index of the picture in the buffer
+ -1 if the specified picture was not found in the buffer
+
+------------------------------------------------------------------------------*/
+
+static i32 FindDpbPic(dpbStorage_t *dpb, i32 picNum, u32 isShortTerm)
+{
+
+/* Variables */
+
+ u32 i = 0;
+ u32 found = HANTRO_FALSE;
+
+/* Code */
+
+ if (isShortTerm)
+ {
+ while (i < dpb->maxRefFrames && !found)
+ {
+ if (IS_SHORT_TERM(dpb->buffer[i]) &&
+ dpb->buffer[i].picNum == picNum)
+ found = HANTRO_TRUE;
+ else
+ i++;
+ }
+ }
+ else
+ {
+ ASSERT(picNum >= 0);
+ while (i < dpb->maxRefFrames && !found)
+ {
+ if (IS_LONG_TERM(dpb->buffer[i]) &&
+ dpb->buffer[i].picNum == picNum)
+ found = HANTRO_TRUE;
+ else
+ i++;
+ }
+ }
+
+ if (found)
+ return((i32)i);
+ else
+ return(-1);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: SetPicNums
+
+ Functional description:
+ Function to set picNum values for short-term pictures in the
+ buffer. Numbering of pictures is based on frame numbers and as
+ frame numbers are modulo maxFrameNum -> frame numbers of older
+ pictures in the buffer may be bigger than the currFrameNum.
+ picNums will be set so that current frame has the largest picNum
+ and all the short-term frames in the buffer will get smaller picNum
+ representing their "distance" from the current frame. This
+ function kind of maps the modulo arithmetic back to normal.
+
+------------------------------------------------------------------------------*/
+
+static void SetPicNums(dpbStorage_t *dpb, u32 currFrameNum)
+{
+
+/* Variables */
+
+ u32 i;
+ i32 frameNumWrap;
+
+/* Code */
+
+ ASSERT(dpb);
+ ASSERT(currFrameNum < dpb->maxFrameNum);
+
+ for (i = 0; i < dpb->numRefFrames; i++)
+ if (IS_SHORT_TERM(dpb->buffer[i]))
+ {
+ if (dpb->buffer[i].frameNum > currFrameNum)
+ frameNumWrap =
+ (i32)dpb->buffer[i].frameNum - (i32)dpb->maxFrameNum;
+ else
+ frameNumWrap = (i32)dpb->buffer[i].frameNum;
+ dpb->buffer[i].picNum = frameNumWrap;
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdCheckGapsInFrameNum
+
+ Functional description:
+ Function to check gaps in frame_num and generate non-existing
+ (short term) reference pictures if necessary. This function should
+ be called only for non-IDR pictures.
+
+ Inputs:
+ dpb pointer to dpb data structure
+ frameNum frame number of the current picture
+ isRefPic flag to indicate if current picture is a reference or
+ non-reference picture
+ gapsAllowed Flag which indicates active SPS stance on whether
+ to allow gaps
+
+ Outputs:
+ dpb 'buffer' possibly modified by inserting non-existing
+ pictures with sliding window marking process
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK error in sliding window reference picture marking or
+ frameNum equal to previous reference frame used for
+ a reference picture
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdCheckGapsInFrameNum(dpbStorage_t *dpb, u32 frameNum, u32 isRefPic,
+ u32 gapsAllowed)
+{
+
+/* Variables */
+
+ u32 unUsedShortTermFrameNum;
+ u8 *tmp;
+
+/* Code */
+
+ ASSERT(dpb);
+ ASSERT(dpb->fullness <= dpb->dpbSize);
+ ASSERT(frameNum < dpb->maxFrameNum);
+
+ dpb->numOut = 0;
+ dpb->outIndex = 0;
+
+ if(!gapsAllowed)
+ return(HANTRO_OK);
+
+ if ( (frameNum != dpb->prevRefFrameNum) &&
+ (frameNum != ((dpb->prevRefFrameNum + 1) % dpb->maxFrameNum)))
+ {
+
+ unUsedShortTermFrameNum = (dpb->prevRefFrameNum + 1) % dpb->maxFrameNum;
+
+ /* store data pointer of last buffer position to be used as next
+ * "allocated" data pointer if last buffer position after this process
+ * contains data pointer located in outBuf (buffer placed in the output
+ * shall not be overwritten by the current picture) */
+ tmp = dpb->buffer[dpb->dpbSize].data;
+ do
+ {
+ SetPicNums(dpb, unUsedShortTermFrameNum);
+
+ if (SlidingWindowRefPicMarking(dpb) != HANTRO_OK)
+ {
+ return(HANTRO_NOK);
+ }
+
+ /* output pictures if buffer full */
+ while (dpb->fullness >= dpb->dpbSize)
+ {
+#ifdef _ASSERT_USED
+ ASSERT(!dpb->noReordering);
+ ASSERT(OutputPicture(dpb) == HANTRO_OK);
+#else
+ OutputPicture(dpb);
+#endif
+ }
+
+ /* add to end of list */
+ ASSERT( !dpb->buffer[dpb->dpbSize].toBeDisplayed &&
+ !IS_REFERENCE(dpb->buffer[dpb->dpbSize]) );
+ dpb->buffer[dpb->dpbSize].status = NON_EXISTING;
+ dpb->buffer[dpb->dpbSize].frameNum = unUsedShortTermFrameNum;
+ dpb->buffer[dpb->dpbSize].picNum = (i32)unUsedShortTermFrameNum;
+ dpb->buffer[dpb->dpbSize].picOrderCnt = 0;
+ dpb->buffer[dpb->dpbSize].toBeDisplayed = HANTRO_FALSE;
+ dpb->fullness++;
+ dpb->numRefFrames++;
+
+ /* sort the buffer */
+ ShellSort(dpb->buffer, dpb->dpbSize+1);
+
+ unUsedShortTermFrameNum = (unUsedShortTermFrameNum + 1) %
+ dpb->maxFrameNum;
+
+ } while (unUsedShortTermFrameNum != frameNum);
+
+ /* pictures placed in output buffer -> check that 'data' in
+ * buffer position dpbSize is not in the output buffer (this will be
+ * "allocated" by h264bsdAllocateDpbImage). If it is -> exchange data
+ * pointer with the one stored in the beginning */
+ if (dpb->numOut)
+ {
+ u32 i;
+
+ for (i = 0; i < dpb->numOut; i++)
+ {
+ if (dpb->outBuf[i].data == dpb->buffer[dpb->dpbSize].data)
+ {
+ /* find buffer position containing data pointer stored in
+ * tmp */
+ for (i = 0; i < dpb->dpbSize; i++)
+ {
+ if (dpb->buffer[i].data == tmp)
+ {
+ dpb->buffer[i].data =
+ dpb->buffer[dpb->dpbSize].data;
+ dpb->buffer[dpb->dpbSize].data = tmp;
+ break;
+ }
+ }
+ ASSERT(i < dpb->dpbSize);
+ break;
+ }
+ }
+ }
+ }
+ /* frameNum for reference pictures shall not be the same as for previous
+ * reference picture, otherwise accesses to pictures in the buffer cannot
+ * be solved unambiguously */
+ else if (isRefPic && frameNum == dpb->prevRefFrameNum)
+ {
+ return(HANTRO_NOK);
+ }
+
+ /* save current frame_num in prevRefFrameNum. For non-reference frame
+ * prevFrameNum is set to frame number of last non-existing frame above */
+ if (isRefPic)
+ dpb->prevRefFrameNum = frameNum;
+ else if (frameNum != dpb->prevRefFrameNum)
+ {
+ dpb->prevRefFrameNum =
+ (frameNum + dpb->maxFrameNum - 1) % dpb->maxFrameNum;
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: FindSmallestPicOrderCnt
+
+ Functional description:
+ Function to find picture with smallest picture order count. This
+ will be the next picture in display order.
+
+ Returns:
+ pointer to the picture, NULL if no pictures to be displayed
+
+------------------------------------------------------------------------------*/
+
+dpbPicture_t* FindSmallestPicOrderCnt(dpbStorage_t *dpb)
+{
+
+/* Variables */
+
+ u32 i;
+ i32 picOrderCnt;
+ dpbPicture_t *tmp;
+
+/* Code */
+
+ ASSERT(dpb);
+
+ picOrderCnt = 0x7FFFFFFF;
+ tmp = NULL;
+
+ for (i = 0; i <= dpb->dpbSize; i++)
+ {
+ if (dpb->buffer[i].toBeDisplayed &&
+ (dpb->buffer[i].picOrderCnt < picOrderCnt))
+ {
+ tmp = dpb->buffer + i;
+ picOrderCnt = dpb->buffer[i].picOrderCnt;
+ }
+ }
+
+ return(tmp);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: OutputPicture
+
+ Functional description:
+ Function to put next display order picture into the output buffer.
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK no pictures to display
+
+------------------------------------------------------------------------------*/
+
+u32 OutputPicture(dpbStorage_t *dpb)
+{
+
+/* Variables */
+
+ dpbPicture_t *tmp;
+
+/* Code */
+
+ ASSERT(dpb);
+
+ if (dpb->noReordering)
+ return(HANTRO_NOK);
+
+ tmp = FindSmallestPicOrderCnt(dpb);
+
+ /* no pictures to be displayed */
+ if (tmp == NULL)
+ return(HANTRO_NOK);
+
+ dpb->outBuf[dpb->numOut].data = tmp->data;
+ dpb->outBuf[dpb->numOut].isIdr = tmp->isIdr;
+ dpb->outBuf[dpb->numOut].picId = tmp->picId;
+ dpb->outBuf[dpb->numOut].numErrMbs = tmp->numErrMbs;
+ dpb->numOut++;
+
+ tmp->toBeDisplayed = HANTRO_FALSE;
+ if (!IS_REFERENCE(*tmp))
+ {
+ dpb->fullness--;
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdDpbOutputPicture
+
+ Functional description:
+ Function to get next display order picture from the output buffer.
+
+ Return:
+ pointer to output picture structure, NULL if no pictures to
+ display
+
+------------------------------------------------------------------------------*/
+
+dpbOutPicture_t* h264bsdDpbOutputPicture(dpbStorage_t *dpb)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(dpb);
+
+ if (dpb->outIndex < dpb->numOut)
+ return(dpb->outBuf + dpb->outIndex++);
+ else
+ return(NULL);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdFlushDpb
+
+ Functional description:
+ Function to flush the DPB. Function puts all pictures needed for
+ display into the output buffer. This function shall be called in
+ the end of the stream to obtain pictures buffered for display
+ re-ordering purposes.
+
+------------------------------------------------------------------------------*/
+
+void h264bsdFlushDpb(dpbStorage_t *dpb)
+{
+
+ /* don't do anything if buffer not reserved */
+ if (dpb->buffer)
+ {
+ dpb->flushed = 1;
+ /* output all pictures */
+ while (OutputPicture(dpb) == HANTRO_OK)
+ ;
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdFreeDpb
+
+ Functional description:
+ Function to free memories reserved for the DPB.
+
+------------------------------------------------------------------------------*/
+
+void h264bsdFreeDpb(dpbStorage_t *dpb)
+{
+
+/* Variables */
+
+ u32 i;
+
+/* Code */
+
+ ASSERT(dpb);
+
+ if (dpb->buffer)
+ {
+ for (i = 0; i < dpb->dpbSize+1; i++)
+ {
+ FREE(dpb->buffer[i].pAllocatedData);
+ }
+ }
+ FREE(dpb->buffer);
+ FREE(dpb->list);
+ FREE(dpb->outBuf);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: ShellSort
+
+ Functional description:
+ Sort pictures in the buffer. Function implements Shell's method,
+ i.e. diminishing increment sort. See e.g. "Numerical Recipes in C"
+ for more information.
+
+------------------------------------------------------------------------------*/
+
+static void ShellSort(dpbPicture_t *pPic, u32 num)
+{
+
+ u32 i, j;
+ u32 step;
+ dpbPicture_t tmpPic;
+
+ step = 7;
+
+ while (step)
+ {
+ for (i = step; i < num; i++)
+ {
+ tmpPic = pPic[i];
+ j = i;
+ while (j >= step && ComparePictures(pPic + j - step, &tmpPic) > 0)
+ {
+ pPic[j] = pPic[j-step];
+ j -= step;
+ }
+ pPic[j] = tmpPic;
+ }
+ step >>= 1;
+ }
+
+}
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_dpb.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_dpb.h
new file mode 100755
index 0000000..0e25084
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_dpb.h
@@ -0,0 +1,149 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_DPB_H
+#define H264SWDEC_DPB_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_slice_header.h"
+#include "h264bsd_image.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+/* enumeration to represent status of buffered image */
+typedef enum {
+ UNUSED = 0,
+ NON_EXISTING,
+ SHORT_TERM,
+ LONG_TERM
+} dpbPictureStatus_e;
+
+/* structure to represent a buffered picture */
+typedef struct {
+ u8 *data; /* 16-byte aligned pointer of pAllocatedData */
+ u8 *pAllocatedData; /* allocated picture pointer; (size + 15) bytes */
+ i32 picNum;
+ u32 frameNum;
+ i32 picOrderCnt;
+ dpbPictureStatus_e status;
+ u32 toBeDisplayed;
+ u32 picId;
+ u32 numErrMbs;
+ u32 isIdr;
+} dpbPicture_t;
+
+/* structure to represent display image output from the buffer */
+typedef struct {
+ u8 *data;
+ u32 picId;
+ u32 numErrMbs;
+ u32 isIdr;
+} dpbOutPicture_t;
+
+/* structure to represent DPB */
+typedef struct {
+ dpbPicture_t *buffer;
+ dpbPicture_t **list;
+ dpbPicture_t *currentOut;
+ dpbOutPicture_t *outBuf;
+ u32 numOut;
+ u32 outIndex;
+ u32 maxRefFrames;
+ u32 dpbSize;
+ u32 maxFrameNum;
+ u32 maxLongTermFrameIdx;
+ u32 numRefFrames;
+ u32 fullness;
+ u32 prevRefFrameNum;
+ u32 lastContainsMmco5;
+ u32 noReordering;
+ u32 flushed;
+} dpbStorage_t;
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+u32 h264bsdInitDpb(
+ dpbStorage_t *dpb,
+ u32 picSizeInMbs,
+ u32 dpbSize,
+ u32 numRefFrames,
+ u32 maxFrameNum,
+ u32 noReordering);
+
+u32 h264bsdResetDpb(
+ dpbStorage_t *dpb,
+ u32 picSizeInMbs,
+ u32 dpbSize,
+ u32 numRefFrames,
+ u32 maxFrameNum,
+ u32 noReordering);
+
+void h264bsdInitRefPicList(dpbStorage_t *dpb);
+
+u8* h264bsdAllocateDpbImage(dpbStorage_t *dpb);
+
+u8* h264bsdGetRefPicData(dpbStorage_t *dpb, u32 index);
+
+u32 h264bsdReorderRefPicList(
+ dpbStorage_t *dpb,
+ refPicListReordering_t *order,
+ u32 currFrameNum,
+ u32 numRefIdxActive);
+
+u32 h264bsdMarkDecRefPic(
+ dpbStorage_t *dpb,
+ decRefPicMarking_t *mark,
+ image_t *image,
+ u32 frameNum,
+ i32 picOrderCnt,
+ u32 isIdr,
+ u32 picId,
+ u32 numErrMbs);
+
+u32 h264bsdCheckGapsInFrameNum(dpbStorage_t *dpb, u32 frameNum, u32 isRefPic,
+ u32 gapsAllowed);
+
+dpbOutPicture_t* h264bsdDpbOutputPicture(dpbStorage_t *dpb);
+
+void h264bsdFlushDpb(dpbStorage_t *dpb);
+
+void h264bsdFreeDpb(dpbStorage_t *dpb);
+
+#endif /* #ifdef H264SWDEC_DPB_H */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_image.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_image.c
new file mode 100755
index 0000000..7b92870
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_image.c
@@ -0,0 +1,345 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdWriteMacroblock
+ h264bsdWriteOutputBlocks
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_image.h"
+#include "h264bsd_util.h"
+#include "h264bsd_neighbour.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/* x- and y-coordinates for each block, defined in h264bsd_intra_prediction.c */
+extern const u32 h264bsdBlockX[];
+extern const u32 h264bsdBlockY[];
+
+/* clipping table, defined in h264bsd_intra_prediction.c */
+extern const u8 h264bsdClip[];
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdWriteMacroblock
+
+ Functional description:
+ Write one macroblock into the image. Both luma and chroma
+ components will be written at the same time.
+
+ Inputs:
+ data pointer to macroblock data to be written, 256 values for
+ luma followed by 64 values for both chroma components
+
+ Outputs:
+ image pointer to the image where the macroblock will be written
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+#ifndef H264DEC_NEON
+void h264bsdWriteMacroblock(image_t *image, u8 *data)
+{
+
+/* Variables */
+
+ u32 i;
+ u32 width;
+ u32 *lum, *cb, *cr;
+ u32 *ptr;
+ u32 tmp1, tmp2;
+
+/* Code */
+
+ ASSERT(image);
+ ASSERT(data);
+ ASSERT(!((u32)data&0x3));
+
+ width = image->width;
+
+ /*lint -save -e826 lum, cb and cr used to copy 4 bytes at the time, disable
+ * "area too small" info message */
+ lum = (u32*)image->luma;
+ cb = (u32*)image->cb;
+ cr = (u32*)image->cr;
+ ASSERT(!((u32)lum&0x3));
+ ASSERT(!((u32)cb&0x3));
+ ASSERT(!((u32)cr&0x3));
+
+ ptr = (u32*)data;
+
+ width *= 4;
+ for (i = 16; i ; i--)
+ {
+ tmp1 = *ptr++;
+ tmp2 = *ptr++;
+ *lum++ = tmp1;
+ *lum++ = tmp2;
+ tmp1 = *ptr++;
+ tmp2 = *ptr++;
+ *lum++ = tmp1;
+ *lum++ = tmp2;
+ lum += width-4;
+ }
+
+ width >>= 1;
+ for (i = 8; i ; i--)
+ {
+ tmp1 = *ptr++;
+ tmp2 = *ptr++;
+ *cb++ = tmp1;
+ *cb++ = tmp2;
+ cb += width-2;
+ }
+
+ for (i = 8; i ; i--)
+ {
+ tmp1 = *ptr++;
+ tmp2 = *ptr++;
+ *cr++ = tmp1;
+ *cr++ = tmp2;
+ cr += width-2;
+ }
+
+}
+#endif
+#ifndef H264DEC_OMXDL
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdWriteOutputBlocks
+
+ Functional description:
+ Write one macroblock into the image. Prediction for the macroblock
+ and the residual are given separately and will be combined while
+ writing the data to the image
+
+ Inputs:
+ data pointer to macroblock prediction data, 256 values for
+ luma followed by 64 values for both chroma components
+ mbNum number of the macroblock
+ residual pointer to residual data, 16 16-element arrays for luma
+ followed by 4 16-element arrays for both chroma
+ components
+
+ Outputs:
+ image pointer to the image where the data will be written
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+void h264bsdWriteOutputBlocks(image_t *image, u32 mbNum, u8 *data,
+ i32 residual[][16])
+{
+
+/* Variables */
+
+ u32 i;
+ u32 picWidth, picSize;
+ u8 *lum, *cb, *cr;
+ u8 *imageBlock;
+ u8 *tmp;
+ u32 row, col;
+ u32 block;
+ u32 x, y;
+ i32 *pRes;
+ i32 tmp1, tmp2, tmp3, tmp4;
+ const u8 *clp = h264bsdClip + 512;
+
+/* Code */
+
+ ASSERT(image);
+ ASSERT(data);
+ ASSERT(mbNum < image->width * image->height);
+ ASSERT(!((u32)data&0x3));
+
+ /* Image size in macroblocks */
+ picWidth = image->width;
+ picSize = picWidth * image->height;
+ row = mbNum / picWidth;
+ col = mbNum % picWidth;
+
+ /* Output macroblock position in output picture */
+ lum = (image->data + row * picWidth * 256 + col * 16);
+ cb = (image->data + picSize * 256 + row * picWidth * 64 + col * 8);
+ cr = (cb + picSize * 64);
+
+ picWidth *= 16;
+
+ for (block = 0; block < 16; block++)
+ {
+ x = h264bsdBlockX[block];
+ y = h264bsdBlockY[block];
+
+ pRes = residual[block];
+
+ ASSERT(pRes);
+
+ tmp = data + y*16 + x;
+ imageBlock = lum + y*picWidth + x;
+
+ ASSERT(!((u32)tmp&0x3));
+ ASSERT(!((u32)imageBlock&0x3));
+
+ if (IS_RESIDUAL_EMPTY(pRes))
+ {
+ /*lint -e826 */
+ i32 *in32 = (i32*)tmp;
+ i32 *out32 = (i32*)imageBlock;
+
+ /* Residual is zero => copy prediction block to output */
+ tmp1 = *in32; in32 += 4;
+ tmp2 = *in32; in32 += 4;
+ *out32 = tmp1; out32 += picWidth/4;
+ *out32 = tmp2; out32 += picWidth/4;
+ tmp1 = *in32; in32 += 4;
+ tmp2 = *in32;
+ *out32 = tmp1; out32 += picWidth/4;
+ *out32 = tmp2;
+ }
+ else
+ {
+
+ RANGE_CHECK_ARRAY(pRes, -512, 511, 16);
+
+ /* Calculate image = prediction + residual
+ * Process four pixels in a loop */
+ for (i = 4; i; i--)
+ {
+ tmp1 = tmp[0];
+ tmp2 = *pRes++;
+ tmp3 = tmp[1];
+ tmp1 = clp[tmp1 + tmp2];
+ tmp4 = *pRes++;
+ imageBlock[0] = (u8)tmp1;
+ tmp3 = clp[tmp3 + tmp4];
+ tmp1 = tmp[2];
+ tmp2 = *pRes++;
+ imageBlock[1] = (u8)tmp3;
+ tmp1 = clp[tmp1 + tmp2];
+ tmp3 = tmp[3];
+ tmp4 = *pRes++;
+ imageBlock[2] = (u8)tmp1;
+ tmp3 = clp[tmp3 + tmp4];
+ tmp += 16;
+ imageBlock[3] = (u8)tmp3;
+ imageBlock += picWidth;
+ }
+ }
+
+ }
+
+ picWidth /= 2;
+
+ for (block = 16; block <= 23; block++)
+ {
+ x = h264bsdBlockX[block & 0x3];
+ y = h264bsdBlockY[block & 0x3];
+
+ pRes = residual[block];
+
+ ASSERT(pRes);
+
+ tmp = data + 256;
+ imageBlock = cb;
+
+ if (block >= 20)
+ {
+ imageBlock = cr;
+ tmp += 64;
+ }
+
+ tmp += y*8 + x;
+ imageBlock += y*picWidth + x;
+
+ ASSERT(!((u32)tmp&0x3));
+ ASSERT(!((u32)imageBlock&0x3));
+
+ if (IS_RESIDUAL_EMPTY(pRes))
+ {
+ /*lint -e826 */
+ i32 *in32 = (i32*)tmp;
+ i32 *out32 = (i32*)imageBlock;
+
+ /* Residual is zero => copy prediction block to output */
+ tmp1 = *in32; in32 += 2;
+ tmp2 = *in32; in32 += 2;
+ *out32 = tmp1; out32 += picWidth/4;
+ *out32 = tmp2; out32 += picWidth/4;
+ tmp1 = *in32; in32 += 2;
+ tmp2 = *in32;
+ *out32 = tmp1; out32 += picWidth/4;
+ *out32 = tmp2;
+ }
+ else
+ {
+
+ RANGE_CHECK_ARRAY(pRes, -512, 511, 16);
+
+ for (i = 4; i; i--)
+ {
+ tmp1 = tmp[0];
+ tmp2 = *pRes++;
+ tmp3 = tmp[1];
+ tmp1 = clp[tmp1 + tmp2];
+ tmp4 = *pRes++;
+ imageBlock[0] = (u8)tmp1;
+ tmp3 = clp[tmp3 + tmp4];
+ tmp1 = tmp[2];
+ tmp2 = *pRes++;
+ imageBlock[1] = (u8)tmp3;
+ tmp1 = clp[tmp1 + tmp2];
+ tmp3 = tmp[3];
+ tmp4 = *pRes++;
+ imageBlock[2] = (u8)tmp1;
+ tmp3 = clp[tmp3 + tmp4];
+ tmp += 8;
+ imageBlock[3] = (u8)tmp3;
+ imageBlock += picWidth;
+ }
+ }
+ }
+
+}
+#endif /* H264DEC_OMXDL */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_image.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_image.h
new file mode 100755
index 0000000..ed7c18c
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_image.h
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_IMAGE_H
+#define H264SWDEC_IMAGE_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+typedef struct
+{
+ u8 *data;
+ u32 width;
+ u32 height;
+ /* current MB's components */
+ u8 *luma;
+ u8 *cb;
+ u8 *cr;
+} image_t;
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+void h264bsdWriteMacroblock(image_t *image, u8 *data);
+
+#ifndef H264DEC_OMXDL
+void h264bsdWriteOutputBlocks(image_t *image, u32 mbNum, u8 *data,
+ i32 residual[][16]);
+#endif
+
+#endif /* #ifdef H264SWDEC_IMAGE_H */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_inter_prediction.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_inter_prediction.c
new file mode 100755
index 0000000..2a81c4a
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_inter_prediction.c
@@ -0,0 +1,1027 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdInterPrediction
+ MvPrediction16x16
+ MvPrediction16x8
+ MvPrediction8x16
+ MvPrediction8x8
+ MvPrediction
+ MedianFilter
+ GetInterNeighbour
+ GetPredictionMv
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_inter_prediction.h"
+#include "h264bsd_neighbour.h"
+#include "h264bsd_util.h"
+#include "h264bsd_reconstruct.h"
+#include "h264bsd_dpb.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+typedef struct
+{
+ u32 available;
+ u32 refIndex;
+ mv_t mv;
+} interNeighbour_t;
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+static u32 MvPrediction16x16(mbStorage_t *pMb, mbPred_t *mbPred,
+ dpbStorage_t *dpb);
+static u32 MvPrediction16x8(mbStorage_t *pMb, mbPred_t *mbPred,
+ dpbStorage_t *dpb);
+static u32 MvPrediction8x16(mbStorage_t *pMb, mbPred_t *mbPred,
+ dpbStorage_t *dpb);
+static u32 MvPrediction8x8(mbStorage_t *pMb, subMbPred_t *subMbPred,
+ dpbStorage_t *dpb);
+static u32 MvPrediction(mbStorage_t *pMb, subMbPred_t *subMbPred,
+ u32 mbPartIdx, u32 subMbPartIdx);
+static i32 MedianFilter(i32 a, i32 b, i32 c);
+
+static void GetInterNeighbour(u32 sliceId, mbStorage_t *nMb,
+ interNeighbour_t *n, u32 index);
+static void GetPredictionMv(mv_t *mv, interNeighbour_t *a, u32 refIndex);
+
+static const neighbour_t N_A_SUB_PART[4][4][4] = {
+ { { {MB_A,5}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_A,5}, {MB_A,7}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_A,5}, {MB_CURR,0}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_A,5}, {MB_CURR,0}, {MB_A,7}, {MB_CURR,2} } },
+
+ { { {MB_CURR,1}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,1}, {MB_CURR,3}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,1}, {MB_CURR,4}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,1}, {MB_CURR,4}, {MB_CURR,3}, {MB_CURR,6} } },
+
+ { { {MB_A,13}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_A,13}, {MB_A,15}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_A,13}, {MB_CURR,8}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_A,13}, {MB_CURR,8}, {MB_A,15}, {MB_CURR,10} } },
+
+ { { {MB_CURR,9}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,9}, {MB_CURR,11}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,9}, {MB_CURR,12}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,9}, {MB_CURR,12}, {MB_CURR,11}, {MB_CURR,14} } } };
+
+static const neighbour_t N_B_SUB_PART[4][4][4] = {
+ { { {MB_B,10}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_B,10}, {MB_CURR,0}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_B,10}, {MB_B,11}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_B,10}, {MB_B,11}, {MB_CURR,0}, {MB_CURR,1} } },
+
+ { { {MB_B,14}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_B,14}, {MB_CURR,4}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_B,14}, {MB_B,15}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_B,14}, {MB_B,15}, {MB_CURR,4}, {MB_CURR,5} } },
+
+ { { {MB_CURR,2}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,2}, {MB_CURR,8}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,2}, {MB_CURR,3}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,2}, {MB_CURR,3}, {MB_CURR,8}, {MB_CURR,9} } },
+
+ { { {MB_CURR,6}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,6}, {MB_CURR,12}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,6}, {MB_CURR,7}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,6}, {MB_CURR,7}, {MB_CURR,12}, {MB_CURR,13} } } };
+
+static const neighbour_t N_C_SUB_PART[4][4][4] = {
+ { { {MB_B,14}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_B,14}, {MB_NA,4}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_B,11}, {MB_B,14}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_B,11}, {MB_B,14}, {MB_CURR,1}, {MB_NA,4} } },
+
+ { { {MB_C,10}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_C,10}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_B,15}, {MB_C,10}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_B,15}, {MB_C,10}, {MB_CURR,5}, {MB_NA,0} } },
+
+ { { {MB_CURR,6}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,6}, {MB_NA,12}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,3}, {MB_CURR,6}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,3}, {MB_CURR,6}, {MB_CURR,9}, {MB_NA,12} } },
+
+ { { {MB_NA,2}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_NA,2}, {MB_NA,8}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,7}, {MB_NA,2}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,7}, {MB_NA,2}, {MB_CURR,13}, {MB_NA,8} } } };
+
+static const neighbour_t N_D_SUB_PART[4][4][4] = {
+ { { {MB_D,15}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_D,15}, {MB_A,5}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_D,15}, {MB_B,10}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_D,15}, {MB_B,10}, {MB_A,5}, {MB_CURR,0} } },
+
+ { { {MB_B,11}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_B,11}, {MB_CURR,1}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_B,11}, {MB_B,14}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_B,11}, {MB_B,14}, {MB_CURR,1}, {MB_CURR,4} } },
+
+ { { {MB_A,7}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_A,7}, {MB_A,13}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_A,7}, {MB_CURR,2}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_A,7}, {MB_CURR,2}, {MB_A,13}, {MB_CURR,8} } },
+
+ { { {MB_CURR,3}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,3}, {MB_CURR,9}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,3}, {MB_CURR,6}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,3}, {MB_CURR,6}, {MB_CURR,9}, {MB_CURR,12} } } };
+
+
+#ifdef H264DEC_OMXDL
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdInterPrediction
+
+ Functional description:
+ Processes one inter macroblock. Performs motion vector prediction
+ and reconstructs prediction macroblock. Writes the final macroblock
+ (prediction + residual) into the output image (currImage)
+
+ Inputs:
+ pMb pointer to macroblock specific information
+ pMbLayer pointer to current macroblock data from stream
+ dpb pointer to decoded picture buffer
+ mbNum current macroblock number
+ currImage pointer to output image
+ data pointer where predicted macroblock will be stored
+
+ Outputs:
+ pMb structure is updated with current macroblock
+ currImage current macroblock is written into image
+ data prediction is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK error in motion vector prediction
+
+------------------------------------------------------------------------------*/
+u32 h264bsdInterPrediction(mbStorage_t *pMb, macroblockLayer_t *pMbLayer,
+ dpbStorage_t *dpb, u32 mbNum, image_t *currImage, u8 *data)
+{
+
+/* Variables */
+
+ u32 i;
+ u32 x, y;
+ u32 colAndRow;
+ subMbPartMode_e subPartMode;
+ image_t refImage;
+ u8 fillBuff[32*21 + 15 + 32];
+ u8 *pFill;
+ u32 tmp;
+/* Code */
+
+ ASSERT(pMb);
+ ASSERT(h264bsdMbPartPredMode(pMb->mbType) == PRED_MODE_INTER);
+ ASSERT(pMbLayer);
+
+ /* 16-byte alignment */
+ pFill = ALIGN(fillBuff, 16);
+
+ /* set row bits 15:0 */
+ colAndRow = mbNum / currImage->width;
+ /*set col to bits 31:16 */
+ colAndRow += (mbNum - colAndRow * currImage->width) << 16;
+ colAndRow <<= 4;
+
+ refImage.width = currImage->width;
+ refImage.height = currImage->height;
+
+ switch (pMb->mbType)
+ {
+ case P_Skip:
+ case P_L0_16x16:
+ if (MvPrediction16x16(pMb, &pMbLayer->mbPred, dpb) != HANTRO_OK)
+ return(HANTRO_NOK);
+ refImage.data = pMb->refAddr[0];
+ tmp = (0<<24) + (0<<16) + (16<<8) + 16;
+ h264bsdPredictSamples(data, pMb->mv, &refImage,
+ colAndRow, tmp, pFill);
+ break;
+
+ case P_L0_L0_16x8:
+ if ( MvPrediction16x8(pMb, &pMbLayer->mbPred, dpb) != HANTRO_OK)
+ return(HANTRO_NOK);
+ refImage.data = pMb->refAddr[0];
+ tmp = (0<<24) + (0<<16) + (16<<8) + 8;
+ h264bsdPredictSamples(data, pMb->mv, &refImage,
+ colAndRow, tmp, pFill);
+
+ refImage.data = pMb->refAddr[2];
+ tmp = (0<<24) + (8<<16) + (16<<8) + 8;
+ h264bsdPredictSamples(data, pMb->mv+8, &refImage,
+ colAndRow, tmp, pFill);
+ break;
+
+ case P_L0_L0_8x16:
+ if ( MvPrediction8x16(pMb, &pMbLayer->mbPred, dpb) != HANTRO_OK)
+ return(HANTRO_NOK);
+ refImage.data = pMb->refAddr[0];
+ tmp = (0<<24) + (0<<16) + (8<<8) + 16;
+ h264bsdPredictSamples(data, pMb->mv, &refImage,
+ colAndRow, tmp, pFill);
+ refImage.data = pMb->refAddr[1];
+ tmp = (8<<24) + (0<<16) + (8<<8) + 16;
+ h264bsdPredictSamples(data, pMb->mv+4, &refImage,
+ colAndRow, tmp, pFill);
+ break;
+
+ default: /* P_8x8 and P_8x8ref0 */
+ if ( MvPrediction8x8(pMb, &pMbLayer->subMbPred, dpb) != HANTRO_OK)
+ return(HANTRO_NOK);
+ for (i = 0; i < 4; i++)
+ {
+ refImage.data = pMb->refAddr[i];
+ subPartMode =
+ h264bsdSubMbPartMode(pMbLayer->subMbPred.subMbType[i]);
+ x = i & 0x1 ? 8 : 0;
+ y = i < 2 ? 0 : 8;
+ switch (subPartMode)
+ {
+ case MB_SP_8x8:
+ tmp = (x<<24) + (y<<16) + (8<<8) + 8;
+ h264bsdPredictSamples(data, pMb->mv+4*i, &refImage,
+ colAndRow, tmp, pFill);
+ break;
+
+ case MB_SP_8x4:
+ tmp = (x<<24) + (y<<16) + (8<<8) + 4;
+ h264bsdPredictSamples(data, pMb->mv+4*i, &refImage,
+ colAndRow, tmp, pFill);
+ tmp = (x<<24) + ((y+4)<<16) + (8<<8) + 4;
+ h264bsdPredictSamples(data, pMb->mv+4*i+2, &refImage,
+ colAndRow, tmp, pFill);
+ break;
+
+ case MB_SP_4x8:
+ tmp = (x<<24) + (y<<16) + (4<<8) + 8;
+ h264bsdPredictSamples(data, pMb->mv+4*i, &refImage,
+ colAndRow, tmp, pFill);
+ tmp = ((x+4)<<24) + (y<<16) + (4<<8) + 8;
+ h264bsdPredictSamples(data, pMb->mv+4*i+1, &refImage,
+ colAndRow, tmp, pFill);
+ break;
+
+ default:
+ tmp = (x<<24) + (y<<16) + (4<<8) + 4;
+ h264bsdPredictSamples(data, pMb->mv+4*i, &refImage,
+ colAndRow, tmp, pFill);
+ tmp = ((x+4)<<24) + (y<<16) + (4<<8) + 4;
+ h264bsdPredictSamples(data, pMb->mv+4*i+1, &refImage,
+ colAndRow, tmp, pFill);
+ tmp = (x<<24) + ((y+4)<<16) + (4<<8) + 4;
+ h264bsdPredictSamples(data, pMb->mv+4*i+2, &refImage,
+ colAndRow, tmp, pFill);
+ tmp = ((x+4)<<24) + ((y+4)<<16) + (4<<8) + 4;
+ h264bsdPredictSamples(data, pMb->mv+4*i+3, &refImage,
+ colAndRow, tmp, pFill);
+ break;
+ }
+ }
+ break;
+ }
+
+ /* if decoded flag > 1 -> mb has already been successfully decoded and
+ * written to output -> do not write again */
+ if (pMb->decoded > 1)
+ return HANTRO_OK;
+
+ return(HANTRO_OK);
+}
+
+#else /* H264DEC_OMXDL */
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdInterPrediction
+
+ Functional description:
+ Processes one inter macroblock. Performs motion vector prediction
+ and reconstructs prediction macroblock. Writes the final macroblock
+ (prediction + residual) into the output image (currImage)
+
+ Inputs:
+ pMb pointer to macroblock specific information
+ pMbLayer pointer to current macroblock data from stream
+ dpb pointer to decoded picture buffer
+ mbNum current macroblock number
+ currImage pointer to output image
+ data pointer where predicted macroblock will be stored
+
+ Outputs:
+ pMb structure is updated with current macroblock
+ currImage current macroblock is written into image
+ data prediction is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK error in motion vector prediction
+
+------------------------------------------------------------------------------*/
+u32 h264bsdInterPrediction(mbStorage_t *pMb, macroblockLayer_t *pMbLayer,
+ dpbStorage_t *dpb, u32 mbNum, image_t *currImage, u8 *data)
+{
+
+/* Variables */
+
+ u32 i;
+ u32 x, y;
+ u32 row, col;
+ subMbPartMode_e subPartMode;
+ image_t refImage;
+
+/* Code */
+
+ ASSERT(pMb);
+ ASSERT(h264bsdMbPartPredMode(pMb->mbType) == PRED_MODE_INTER);
+ ASSERT(pMbLayer);
+
+ row = mbNum / currImage->width;
+ col = mbNum - row * currImage->width;
+ row *= 16;
+ col *= 16;
+
+ refImage.width = currImage->width;
+ refImage.height = currImage->height;
+
+ switch (pMb->mbType)
+ {
+ case P_Skip:
+ case P_L0_16x16:
+ if (MvPrediction16x16(pMb, &pMbLayer->mbPred, dpb) != HANTRO_OK)
+ return(HANTRO_NOK);
+ refImage.data = pMb->refAddr[0];
+ h264bsdPredictSamples(data, pMb->mv, &refImage, col, row, 0, 0,
+ 16, 16);
+ break;
+
+ case P_L0_L0_16x8:
+ if ( MvPrediction16x8(pMb, &pMbLayer->mbPred, dpb) != HANTRO_OK)
+ return(HANTRO_NOK);
+ refImage.data = pMb->refAddr[0];
+ h264bsdPredictSamples(data, pMb->mv, &refImage, col, row, 0, 0,
+ 16, 8);
+ refImage.data = pMb->refAddr[2];
+ h264bsdPredictSamples(data, pMb->mv+8, &refImage, col, row, 0, 8,
+ 16, 8);
+ break;
+
+ case P_L0_L0_8x16:
+ if ( MvPrediction8x16(pMb, &pMbLayer->mbPred, dpb) != HANTRO_OK)
+ return(HANTRO_NOK);
+ refImage.data = pMb->refAddr[0];
+ h264bsdPredictSamples(data, pMb->mv, &refImage, col, row, 0, 0,
+ 8, 16);
+ refImage.data = pMb->refAddr[1];
+ h264bsdPredictSamples(data, pMb->mv+4, &refImage, col, row, 8, 0,
+ 8, 16);
+ break;
+
+ default: /* P_8x8 and P_8x8ref0 */
+ if ( MvPrediction8x8(pMb, &pMbLayer->subMbPred, dpb) != HANTRO_OK)
+ return(HANTRO_NOK);
+ for (i = 0; i < 4; i++)
+ {
+ refImage.data = pMb->refAddr[i];
+ subPartMode =
+ h264bsdSubMbPartMode(pMbLayer->subMbPred.subMbType[i]);
+ x = i & 0x1 ? 8 : 0;
+ y = i < 2 ? 0 : 8;
+ switch (subPartMode)
+ {
+ case MB_SP_8x8:
+ h264bsdPredictSamples(data, pMb->mv+4*i, &refImage,
+ col, row, x, y, 8, 8);
+ break;
+
+ case MB_SP_8x4:
+ h264bsdPredictSamples(data, pMb->mv+4*i, &refImage,
+ col, row, x, y, 8, 4);
+ h264bsdPredictSamples(data, pMb->mv+4*i+2, &refImage,
+ col, row, x, y+4, 8, 4);
+ break;
+
+ case MB_SP_4x8:
+ h264bsdPredictSamples(data, pMb->mv+4*i, &refImage,
+ col, row, x, y, 4, 8);
+ h264bsdPredictSamples(data, pMb->mv+4*i+1, &refImage,
+ col, row, x+4, y, 4, 8);
+ break;
+
+ default:
+ h264bsdPredictSamples(data, pMb->mv+4*i, &refImage,
+ col, row, x, y, 4, 4);
+ h264bsdPredictSamples(data, pMb->mv+4*i+1, &refImage,
+ col, row, x+4, y, 4, 4);
+ h264bsdPredictSamples(data, pMb->mv+4*i+2, &refImage,
+ col, row, x, y+4, 4, 4);
+ h264bsdPredictSamples(data, pMb->mv+4*i+3, &refImage,
+ col, row, x+4, y+4, 4, 4);
+ break;
+ }
+ }
+ break;
+ }
+
+ /* if decoded flag > 1 -> mb has already been successfully decoded and
+ * written to output -> do not write again */
+ if (pMb->decoded > 1)
+ return HANTRO_OK;
+
+ if (pMb->mbType != P_Skip)
+ {
+ h264bsdWriteOutputBlocks(currImage, mbNum, data,
+ pMbLayer->residual.level);
+ }
+ else
+ {
+ h264bsdWriteMacroblock(currImage, data);
+ }
+
+ return(HANTRO_OK);
+}
+#endif /* H264DEC_OMXDL */
+
+/*------------------------------------------------------------------------------
+
+ Function: MvPrediction16x16
+
+ Functional description:
+ Motion vector prediction for 16x16 partition mode
+
+------------------------------------------------------------------------------*/
+
+u32 MvPrediction16x16(mbStorage_t *pMb, mbPred_t *mbPred, dpbStorage_t *dpb)
+{
+
+/* Variables */
+
+ mv_t mv;
+ mv_t mvPred;
+ interNeighbour_t a[3]; /* A, B, C */
+ u32 refIndex;
+ u8 *tmp;
+ u32 *tmpMv1, *tmpMv2;
+
+/* Code */
+
+ refIndex = mbPred->refIdxL0[0];
+
+ GetInterNeighbour(pMb->sliceId, pMb->mbA, a, 5);
+ GetInterNeighbour(pMb->sliceId, pMb->mbB, a+1, 10);
+ /*lint --e(740) Unusual pointer cast (incompatible indirect types) */
+ tmpMv1 = (u32*)(&a[0].mv); /* we test just that both MVs are zero */
+ /*lint --e(740) */
+ tmpMv2 = (u32*)(&a[1].mv); /* i.e. a[0].mv.hor == 0 && a[0].mv.ver == 0 */
+ if (pMb->mbType == P_Skip &&
+ (!a[0].available || !a[1].available ||
+ ( a[0].refIndex == 0 && ((u32)(*tmpMv1) == 0) ) ||
+ ( a[1].refIndex == 0 && ((u32)(*tmpMv2) == 0) )))
+ {
+ mv.hor = mv.ver = 0;
+ }
+ else
+ {
+ mv = mbPred->mvdL0[0];
+ GetInterNeighbour(pMb->sliceId, pMb->mbC, a+2, 10);
+ if (!a[2].available)
+ {
+ GetInterNeighbour(pMb->sliceId, pMb->mbD, a+2, 15);
+ }
+
+ GetPredictionMv(&mvPred, a, refIndex);
+
+ mv.hor += mvPred.hor;
+ mv.ver += mvPred.ver;
+
+ /* horizontal motion vector range [-2048, 2047.75] */
+ if ((u32)(i32)(mv.hor+8192) >= (16384))
+ return(HANTRO_NOK);
+
+ /* vertical motion vector range [-512, 511.75]
+ * (smaller for low levels) */
+ if ((u32)(i32)(mv.ver+2048) >= (4096))
+ return(HANTRO_NOK);
+ }
+
+ tmp = h264bsdGetRefPicData(dpb, refIndex);
+ if (tmp == NULL)
+ return(HANTRO_NOK);
+
+ pMb->mv[0] = pMb->mv[1] = pMb->mv[2] = pMb->mv[3] =
+ pMb->mv[4] = pMb->mv[5] = pMb->mv[6] = pMb->mv[7] =
+ pMb->mv[8] = pMb->mv[9] = pMb->mv[10] = pMb->mv[11] =
+ pMb->mv[12] = pMb->mv[13] = pMb->mv[14] = pMb->mv[15] = mv;
+
+ pMb->refPic[0] = refIndex;
+ pMb->refPic[1] = refIndex;
+ pMb->refPic[2] = refIndex;
+ pMb->refPic[3] = refIndex;
+ pMb->refAddr[0] = tmp;
+ pMb->refAddr[1] = tmp;
+ pMb->refAddr[2] = tmp;
+ pMb->refAddr[3] = tmp;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: MvPrediction16x8
+
+ Functional description:
+ Motion vector prediction for 16x8 partition mode
+
+------------------------------------------------------------------------------*/
+
+u32 MvPrediction16x8(mbStorage_t *pMb, mbPred_t *mbPred, dpbStorage_t *dpb)
+{
+
+/* Variables */
+
+ mv_t mv;
+ mv_t mvPred;
+ interNeighbour_t a[3]; /* A, B, C */
+ u32 refIndex;
+ u8 *tmp;
+
+/* Code */
+
+ mv = mbPred->mvdL0[0];
+ refIndex = mbPred->refIdxL0[0];
+
+ GetInterNeighbour(pMb->sliceId, pMb->mbB, a+1, 10);
+
+ if (a[1].refIndex == refIndex)
+ mvPred = a[1].mv;
+ else
+ {
+ GetInterNeighbour(pMb->sliceId, pMb->mbA, a, 5);
+ GetInterNeighbour(pMb->sliceId, pMb->mbC, a+2, 10);
+ if (!a[2].available)
+ {
+ GetInterNeighbour(pMb->sliceId, pMb->mbD, a+2, 15);
+ }
+
+ GetPredictionMv(&mvPred, a, refIndex);
+
+ }
+ mv.hor += mvPred.hor;
+ mv.ver += mvPred.ver;
+
+ /* horizontal motion vector range [-2048, 2047.75] */
+ if ((u32)(i32)(mv.hor+8192) >= (16384))
+ return(HANTRO_NOK);
+
+ /* vertical motion vector range [-512, 511.75] (smaller for low levels) */
+ if ((u32)(i32)(mv.ver+2048) >= (4096))
+ return(HANTRO_NOK);
+
+ tmp = h264bsdGetRefPicData(dpb, refIndex);
+ if (tmp == NULL)
+ return(HANTRO_NOK);
+
+ pMb->mv[0] = pMb->mv[1] = pMb->mv[2] = pMb->mv[3] =
+ pMb->mv[4] = pMb->mv[5] = pMb->mv[6] = pMb->mv[7] = mv;
+ pMb->refPic[0] = refIndex;
+ pMb->refPic[1] = refIndex;
+ pMb->refAddr[0] = tmp;
+ pMb->refAddr[1] = tmp;
+
+ mv = mbPred->mvdL0[1];
+ refIndex = mbPred->refIdxL0[1];
+
+ GetInterNeighbour(pMb->sliceId, pMb->mbA, a, 13);
+ if (a[0].refIndex == refIndex)
+ mvPred = a[0].mv;
+ else
+ {
+ a[1].available = HANTRO_TRUE;
+ a[1].refIndex = pMb->refPic[0];
+ a[1].mv = pMb->mv[0];
+
+ /* c is not available */
+ GetInterNeighbour(pMb->sliceId, pMb->mbA, a+2, 7);
+
+ GetPredictionMv(&mvPred, a, refIndex);
+
+ }
+ mv.hor += mvPred.hor;
+ mv.ver += mvPred.ver;
+
+ /* horizontal motion vector range [-2048, 2047.75] */
+ if ((u32)(i32)(mv.hor+8192) >= (16384))
+ return(HANTRO_NOK);
+
+ /* vertical motion vector range [-512, 511.75] (smaller for low levels) */
+ if ((u32)(i32)(mv.ver+2048) >= (4096))
+ return(HANTRO_NOK);
+
+ tmp = h264bsdGetRefPicData(dpb, refIndex);
+ if (tmp == NULL)
+ return(HANTRO_NOK);
+
+ pMb->mv[8] = pMb->mv[9] = pMb->mv[10] = pMb->mv[11] =
+ pMb->mv[12] = pMb->mv[13] = pMb->mv[14] = pMb->mv[15] = mv;
+ pMb->refPic[2] = refIndex;
+ pMb->refPic[3] = refIndex;
+ pMb->refAddr[2] = tmp;
+ pMb->refAddr[3] = tmp;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: MvPrediction8x16
+
+ Functional description:
+ Motion vector prediction for 8x16 partition mode
+
+------------------------------------------------------------------------------*/
+
+u32 MvPrediction8x16(mbStorage_t *pMb, mbPred_t *mbPred, dpbStorage_t *dpb)
+{
+
+/* Variables */
+
+ mv_t mv;
+ mv_t mvPred;
+ interNeighbour_t a[3]; /* A, B, C */
+ u32 refIndex;
+ u8 *tmp;
+
+/* Code */
+
+ mv = mbPred->mvdL0[0];
+ refIndex = mbPred->refIdxL0[0];
+
+ GetInterNeighbour(pMb->sliceId, pMb->mbA, a, 5);
+
+ if (a[0].refIndex == refIndex)
+ mvPred = a[0].mv;
+ else
+ {
+ GetInterNeighbour(pMb->sliceId, pMb->mbB, a+1, 10);
+ GetInterNeighbour(pMb->sliceId, pMb->mbB, a+2, 14);
+ if (!a[2].available)
+ {
+ GetInterNeighbour(pMb->sliceId, pMb->mbD, a+2, 15);
+ }
+
+ GetPredictionMv(&mvPred, a, refIndex);
+
+ }
+ mv.hor += mvPred.hor;
+ mv.ver += mvPred.ver;
+
+ /* horizontal motion vector range [-2048, 2047.75] */
+ if ((u32)(i32)(mv.hor+8192) >= (16384))
+ return(HANTRO_NOK);
+
+ /* vertical motion vector range [-512, 511.75] (smaller for low levels) */
+ if ((u32)(i32)(mv.ver+2048) >= (4096))
+ return(HANTRO_NOK);
+
+ tmp = h264bsdGetRefPicData(dpb, refIndex);
+ if (tmp == NULL)
+ return(HANTRO_NOK);
+
+ pMb->mv[0] = pMb->mv[1] = pMb->mv[2] = pMb->mv[3] =
+ pMb->mv[8] = pMb->mv[9] = pMb->mv[10] = pMb->mv[11] = mv;
+ pMb->refPic[0] = refIndex;
+ pMb->refPic[2] = refIndex;
+ pMb->refAddr[0] = tmp;
+ pMb->refAddr[2] = tmp;
+
+ mv = mbPred->mvdL0[1];
+ refIndex = mbPred->refIdxL0[1];
+
+ GetInterNeighbour(pMb->sliceId, pMb->mbC, a+2, 10);
+ if (!a[2].available)
+ {
+ GetInterNeighbour(pMb->sliceId, pMb->mbB, a+2, 11);
+ }
+ if (a[2].refIndex == refIndex)
+ mvPred = a[2].mv;
+ else
+ {
+ a[0].available = HANTRO_TRUE;
+ a[0].refIndex = pMb->refPic[0];
+ a[0].mv = pMb->mv[0];
+
+ GetInterNeighbour(pMb->sliceId, pMb->mbB, a+1, 14);
+
+ GetPredictionMv(&mvPred, a, refIndex);
+
+ }
+ mv.hor += mvPred.hor;
+ mv.ver += mvPred.ver;
+
+ /* horizontal motion vector range [-2048, 2047.75] */
+ if ((u32)(i32)(mv.hor+8192) >= (16384))
+ return(HANTRO_NOK);
+
+ /* vertical motion vector range [-512, 511.75] (smaller for low levels) */
+ if ((u32)(i32)(mv.ver+2048) >= (4096))
+ return(HANTRO_NOK);
+
+ tmp = h264bsdGetRefPicData(dpb, refIndex);
+ if (tmp == NULL)
+ return(HANTRO_NOK);
+
+ pMb->mv[4] = pMb->mv[5] = pMb->mv[6] = pMb->mv[7] =
+ pMb->mv[12] = pMb->mv[13] = pMb->mv[14] = pMb->mv[15] = mv;
+ pMb->refPic[1] = refIndex;
+ pMb->refPic[3] = refIndex;
+ pMb->refAddr[1] = tmp;
+ pMb->refAddr[3] = tmp;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: MvPrediction8x8
+
+ Functional description:
+ Motion vector prediction for 8x8 partition mode
+
+------------------------------------------------------------------------------*/
+
+u32 MvPrediction8x8(mbStorage_t *pMb, subMbPred_t *subMbPred, dpbStorage_t *dpb)
+{
+
+/* Variables */
+
+ u32 i, j;
+ u32 numSubMbPart;
+
+/* Code */
+
+ for (i = 0; i < 4; i++)
+ {
+ numSubMbPart = h264bsdNumSubMbPart(subMbPred->subMbType[i]);
+ pMb->refPic[i] = subMbPred->refIdxL0[i];
+ pMb->refAddr[i] = h264bsdGetRefPicData(dpb, subMbPred->refIdxL0[i]);
+ if (pMb->refAddr[i] == NULL)
+ return(HANTRO_NOK);
+ for (j = 0; j < numSubMbPart; j++)
+ {
+ if (MvPrediction(pMb, subMbPred, i, j) != HANTRO_OK)
+ return(HANTRO_NOK);
+ }
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: MvPrediction
+
+ Functional description:
+ Perform motion vector prediction for sub-partition
+
+------------------------------------------------------------------------------*/
+
+u32 MvPrediction(mbStorage_t *pMb, subMbPred_t *subMbPred, u32 mbPartIdx,
+ u32 subMbPartIdx)
+{
+
+/* Variables */
+
+ mv_t mv, mvPred;
+ u32 refIndex;
+ subMbPartMode_e subMbPartMode;
+ const neighbour_t *n;
+ mbStorage_t *nMb;
+ interNeighbour_t a[3]; /* A, B, C */
+
+/* Code */
+
+ mv = subMbPred->mvdL0[mbPartIdx][subMbPartIdx];
+ subMbPartMode = h264bsdSubMbPartMode(subMbPred->subMbType[mbPartIdx]);
+ refIndex = subMbPred->refIdxL0[mbPartIdx];
+
+ n = N_A_SUB_PART[mbPartIdx][subMbPartMode]+subMbPartIdx;
+ nMb = h264bsdGetNeighbourMb(pMb, n->mb);
+ GetInterNeighbour(pMb->sliceId, nMb, a, n->index);
+
+ n = N_B_SUB_PART[mbPartIdx][subMbPartMode]+subMbPartIdx;
+ nMb = h264bsdGetNeighbourMb(pMb, n->mb);
+ GetInterNeighbour(pMb->sliceId, nMb, a+1, n->index);
+
+ n = N_C_SUB_PART[mbPartIdx][subMbPartMode]+subMbPartIdx;
+ nMb = h264bsdGetNeighbourMb(pMb, n->mb);
+ GetInterNeighbour(pMb->sliceId, nMb, a+2, n->index);
+
+ if (!a[2].available)
+ {
+ n = N_D_SUB_PART[mbPartIdx][subMbPartMode]+subMbPartIdx;
+ nMb = h264bsdGetNeighbourMb(pMb, n->mb);
+ GetInterNeighbour(pMb->sliceId, nMb, a+2, n->index);
+ }
+
+ GetPredictionMv(&mvPred, a, refIndex);
+
+ mv.hor += mvPred.hor;
+ mv.ver += mvPred.ver;
+
+ /* horizontal motion vector range [-2048, 2047.75] */
+ if (((u32)(i32)(mv.hor+8192) >= (16384)))
+ return(HANTRO_NOK);
+
+ /* vertical motion vector range [-512, 511.75] (smaller for low levels) */
+ if (((u32)(i32)(mv.ver+2048) >= (4096)))
+ return(HANTRO_NOK);
+
+ switch (subMbPartMode)
+ {
+ case MB_SP_8x8:
+ pMb->mv[4*mbPartIdx] = mv;
+ pMb->mv[4*mbPartIdx + 1] = mv;
+ pMb->mv[4*mbPartIdx + 2] = mv;
+ pMb->mv[4*mbPartIdx + 3] = mv;
+ break;
+
+ case MB_SP_8x4:
+ pMb->mv[4*mbPartIdx + 2*subMbPartIdx] = mv;
+ pMb->mv[4*mbPartIdx + 2*subMbPartIdx + 1] = mv;
+ break;
+
+ case MB_SP_4x8:
+ pMb->mv[4*mbPartIdx + subMbPartIdx] = mv;
+ pMb->mv[4*mbPartIdx + subMbPartIdx + 2] = mv;
+ break;
+
+ case MB_SP_4x4:
+ pMb->mv[4*mbPartIdx + subMbPartIdx] = mv;
+ break;
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: MedianFilter
+
+ Functional description:
+ Median filtering for motion vector prediction
+
+------------------------------------------------------------------------------*/
+
+i32 MedianFilter(i32 a, i32 b, i32 c)
+{
+
+/* Variables */
+
+ i32 max,min,med;
+
+/* Code */
+
+ max = min = med = a;
+ if (b > max)
+ {
+ max = b;
+ }
+ else if (b < min)
+ {
+ min = b;
+ }
+ if (c > max)
+ {
+ med = max;
+ }
+ else if (c < min)
+ {
+ med = min;
+ }
+ else
+ {
+ med = c;
+ }
+
+ return(med);
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: GetInterNeighbour
+
+ Functional description:
+ Get availability, reference index and motion vector of a neighbour
+
+------------------------------------------------------------------------------*/
+
+void GetInterNeighbour(u32 sliceId, mbStorage_t *nMb,
+ interNeighbour_t *n, u32 index)
+{
+
+ n->available = HANTRO_FALSE;
+ n->refIndex = 0xFFFFFFFF;
+ n->mv.hor = n->mv.ver = 0;
+
+ if (nMb && (sliceId == nMb->sliceId))
+ {
+ u32 tmp;
+ mv_t tmpMv;
+
+ tmp = nMb->mbType;
+ n->available = HANTRO_TRUE;
+ /* MbPartPredMode "inlined" */
+ if (tmp <= P_8x8ref0)
+ {
+ tmpMv = nMb->mv[index];
+ tmp = nMb->refPic[index>>2];
+ n->refIndex = tmp;
+ n->mv = tmpMv;
+ }
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: GetPredictionMv
+
+ Functional description:
+ Compute motion vector predictor based on neighbours A, B and C
+
+------------------------------------------------------------------------------*/
+
+void GetPredictionMv(mv_t *mv, interNeighbour_t *a, u32 refIndex)
+{
+
+ if ( a[1].available || a[2].available || !a[0].available)
+ {
+ u32 isA, isB, isC;
+ isA = (a[0].refIndex == refIndex) ? HANTRO_TRUE : HANTRO_FALSE;
+ isB = (a[1].refIndex == refIndex) ? HANTRO_TRUE : HANTRO_FALSE;
+ isC = (a[2].refIndex == refIndex) ? HANTRO_TRUE : HANTRO_FALSE;
+
+ if (((u32)isA+(u32)isB+(u32)isC) != 1)
+ {
+ mv->hor = (i16)MedianFilter(a[0].mv.hor, a[1].mv.hor, a[2].mv.hor);
+ mv->ver = (i16)MedianFilter(a[0].mv.ver, a[1].mv.ver, a[2].mv.ver);
+ }
+ else if (isA)
+ *mv = a[0].mv;
+ else if (isB)
+ *mv = a[1].mv;
+ else
+ *mv = a[2].mv;
+ }
+ else
+ {
+ *mv = a[0].mv;
+ }
+
+}
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_inter_prediction.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_inter_prediction.h
new file mode 100755
index 0000000..94dee25
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_inter_prediction.h
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_INTER_PREDICTION_H
+#define H264SWDEC_INTER_PREDICTION_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_image.h"
+#include "h264bsd_macroblock_layer.h"
+#include "h264bsd_dpb.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+u32 h264bsdInterPrediction(mbStorage_t *pMb, macroblockLayer_t *pMbLayer,
+ dpbStorage_t *dpb, u32 mbNum, image_t *image, u8 *data);
+
+#endif /* #ifdef H264SWDEC_INTER_PREDICTION_H */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_intra_prediction.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_intra_prediction.c
new file mode 100755
index 0000000..15eabfb
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_intra_prediction.c
@@ -0,0 +1,1937 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdIntraPrediction
+ h264bsdGetNeighbourPels
+ h264bsdIntra16x16Prediction
+ h264bsdIntra4x4Prediction
+ h264bsdIntraChromaPrediction
+ h264bsdAddResidual
+ Intra16x16VerticalPrediction
+ Intra16x16HorizontalPrediction
+ Intra16x16DcPrediction
+ Intra16x16PlanePrediction
+ IntraChromaDcPrediction
+ IntraChromaHorizontalPrediction
+ IntraChromaVerticalPrediction
+ IntraChromaPlanePrediction
+ Get4x4NeighbourPels
+ Write4x4To16x16
+ Intra4x4VerticalPrediction
+ Intra4x4HorizontalPrediction
+ Intra4x4DcPrediction
+ Intra4x4DiagonalDownLeftPrediction
+ Intra4x4DiagonalDownRightPrediction
+ Intra4x4VerticalRightPrediction
+ Intra4x4HorizontalDownPrediction
+ Intra4x4VerticalLeftPrediction
+ Intra4x4HorizontalUpPrediction
+ DetermineIntra4x4PredMode
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_intra_prediction.h"
+#include "h264bsd_util.h"
+#include "h264bsd_macroblock_layer.h"
+#include "h264bsd_neighbour.h"
+#include "h264bsd_image.h"
+
+#ifdef H264DEC_OMXDL
+#include "omxtypes.h"
+#include "omxVC.h"
+#endif /* H264DEC_OMXDL */
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/* Switch off the following Lint messages for this file:
+ * Info 702: Shift right of signed quantity (int)
+ */
+/*lint -e702 */
+
+
+/* x- and y-coordinates for each block */
+const u32 h264bsdBlockX[16] =
+ { 0, 4, 0, 4, 8, 12, 8, 12, 0, 4, 0, 4, 8, 12, 8, 12 };
+const u32 h264bsdBlockY[16] =
+ { 0, 0, 4, 4, 0, 0, 4, 4, 8, 8, 12, 12, 8, 8, 12, 12 };
+
+const u8 h264bsdClip[1280] =
+{
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
+ 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
+ 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
+ 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
+ 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
+ 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
+ 96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
+ 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
+ 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
+ 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
+ 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
+ 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
+ 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
+ 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
+ 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
+ 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
+};
+
+#ifndef H264DEC_OMXDL
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+static void Get4x4NeighbourPels(u8 *a, u8 *l, u8 *data, u8 *above, u8 *left,
+ u32 blockNum);
+static void Intra16x16VerticalPrediction(u8 *data, u8 *above);
+static void Intra16x16HorizontalPrediction(u8 *data, u8 *left);
+static void Intra16x16DcPrediction(u8 *data, u8 *above, u8 *left,
+ u32 A, u32 B);
+static void Intra16x16PlanePrediction(u8 *data, u8 *above, u8 *left);
+static void IntraChromaDcPrediction(u8 *data, u8 *above, u8 *left,
+ u32 A, u32 B);
+static void IntraChromaHorizontalPrediction(u8 *data, u8 *left);
+static void IntraChromaVerticalPrediction(u8 *data, u8 *above);
+static void IntraChromaPlanePrediction(u8 *data, u8 *above, u8 *left);
+
+static void Intra4x4VerticalPrediction(u8 *data, u8 *above);
+static void Intra4x4HorizontalPrediction(u8 *data, u8 *left);
+static void Intra4x4DcPrediction(u8 *data, u8 *above, u8 *left, u32 A, u32 B);
+static void Intra4x4DiagonalDownLeftPrediction(u8 *data, u8 *above);
+static void Intra4x4DiagonalDownRightPrediction(u8 *data, u8 *above, u8 *left);
+static void Intra4x4VerticalRightPrediction(u8 *data, u8 *above, u8 *left);
+static void Intra4x4HorizontalDownPrediction(u8 *data, u8 *above, u8 *left);
+static void Intra4x4VerticalLeftPrediction(u8 *data, u8 *above);
+static void Intra4x4HorizontalUpPrediction(u8 *data, u8 *left);
+void h264bsdAddResidual(u8 *data, i32 *residual, u32 blockNum);
+
+static void Write4x4To16x16(u8 *data, u8 *data4x4, u32 blockNum);
+#endif /* H264DEC_OMXDL */
+
+static u32 DetermineIntra4x4PredMode(macroblockLayer_t *pMbLayer,
+ u32 available, neighbour_t *nA, neighbour_t *nB, u32 index,
+ mbStorage_t *nMbA, mbStorage_t *nMbB);
+
+
+#ifdef H264DEC_OMXDL
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdIntra16x16Prediction
+
+ Functional description:
+ Perform intra 16x16 prediction mode for luma pixels and add
+ residual into prediction. The resulting luma pixels are
+ stored in macroblock array 'data'.
+
+------------------------------------------------------------------------------*/
+u32 h264bsdIntra16x16Prediction(mbStorage_t *pMb, u8 *data, u8 *ptr,
+ u32 width, u32 constrainedIntraPred)
+{
+
+/* Variables */
+
+ u32 availableA, availableB, availableD;
+ OMXResult omxRes;
+
+/* Code */
+ ASSERT(pMb);
+ ASSERT(data);
+ ASSERT(ptr);
+ ASSERT(h264bsdPredModeIntra16x16(pMb->mbType) < 4);
+
+ availableA = h264bsdIsNeighbourAvailable(pMb, pMb->mbA);
+ if (availableA && constrainedIntraPred &&
+ (h264bsdMbPartPredMode(pMb->mbA->mbType) == PRED_MODE_INTER))
+ availableA = HANTRO_FALSE;
+ availableB = h264bsdIsNeighbourAvailable(pMb, pMb->mbB);
+ if (availableB && constrainedIntraPred &&
+ (h264bsdMbPartPredMode(pMb->mbB->mbType) == PRED_MODE_INTER))
+ availableB = HANTRO_FALSE;
+ availableD = h264bsdIsNeighbourAvailable(pMb, pMb->mbD);
+ if (availableD && constrainedIntraPred &&
+ (h264bsdMbPartPredMode(pMb->mbD->mbType) == PRED_MODE_INTER))
+ availableD = HANTRO_FALSE;
+
+ omxRes = omxVCM4P10_PredictIntra_16x16( (ptr-1),
+ (ptr - width),
+ (ptr - width-1),
+ data,
+ (i32)width,
+ 16,
+ (OMXVCM4P10Intra16x16PredMode)
+ h264bsdPredModeIntra16x16(pMb->mbType),
+ (i32)(availableB + (availableA<<1) +
+ (availableD<<5)) );
+ if (omxRes != OMX_Sts_NoErr)
+ return HANTRO_NOK;
+ else
+ return(HANTRO_OK);
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdIntra4x4Prediction
+
+ Functional description:
+ Perform intra 4x4 prediction for luma pixels and add residual
+ into prediction. The resulting luma pixels are stored in
+ macroblock array 'data'. The intra 4x4 prediction mode for each
+ block is stored in 'pMb' structure.
+
+------------------------------------------------------------------------------*/
+u32 h264bsdIntra4x4Prediction(mbStorage_t *pMb, u8 *data,
+ macroblockLayer_t *mbLayer,
+ u8 *ptr, u32 width,
+ u32 constrainedIntraPred, u32 block)
+{
+
+/* Variables */
+ u32 mode;
+ neighbour_t neighbour, neighbourB;
+ mbStorage_t *nMb, *nMb2;
+ u32 availableA, availableB, availableC, availableD;
+
+ OMXResult omxRes;
+ u32 x, y;
+ u8 *l, *a, *al;
+/* Code */
+ ASSERT(pMb);
+ ASSERT(data);
+ ASSERT(mbLayer);
+ ASSERT(ptr);
+ ASSERT(pMb->intra4x4PredMode[block] < 9);
+
+ neighbour = *h264bsdNeighbour4x4BlockA(block);
+ nMb = h264bsdGetNeighbourMb(pMb, neighbour.mb);
+ availableA = h264bsdIsNeighbourAvailable(pMb, nMb);
+ if (availableA && constrainedIntraPred &&
+ ( h264bsdMbPartPredMode(nMb->mbType) == PRED_MODE_INTER) )
+ {
+ availableA = HANTRO_FALSE;
+ }
+
+ neighbourB = *h264bsdNeighbour4x4BlockB(block);
+ nMb2 = h264bsdGetNeighbourMb(pMb, neighbourB.mb);
+ availableB = h264bsdIsNeighbourAvailable(pMb, nMb2);
+ if (availableB && constrainedIntraPred &&
+ ( h264bsdMbPartPredMode(nMb2->mbType) == PRED_MODE_INTER) )
+ {
+ availableB = HANTRO_FALSE;
+ }
+
+ mode = DetermineIntra4x4PredMode(mbLayer,
+ (u32)(availableA && availableB),
+ &neighbour, &neighbourB, block, nMb, nMb2);
+ pMb->intra4x4PredMode[block] = (u8)mode;
+
+ neighbour = *h264bsdNeighbour4x4BlockC(block);
+ nMb = h264bsdGetNeighbourMb(pMb, neighbour.mb);
+ availableC = h264bsdIsNeighbourAvailable(pMb, nMb);
+ if (availableC && constrainedIntraPred &&
+ ( h264bsdMbPartPredMode(nMb->mbType) == PRED_MODE_INTER) )
+ {
+ availableC = HANTRO_FALSE;
+ }
+
+ neighbour = *h264bsdNeighbour4x4BlockD(block);
+ nMb = h264bsdGetNeighbourMb(pMb, neighbour.mb);
+ availableD = h264bsdIsNeighbourAvailable(pMb, nMb);
+ if (availableD && constrainedIntraPred &&
+ ( h264bsdMbPartPredMode(nMb->mbType) == PRED_MODE_INTER) )
+ {
+ availableD = HANTRO_FALSE;
+ }
+
+ x = h264bsdBlockX[block];
+ y = h264bsdBlockY[block];
+
+ if (y == 0)
+ a = ptr - width + x;
+ else
+ a = data-16;
+
+ if (x == 0)
+ l = ptr + y * width -1;
+ else
+ {
+ l = data-1;
+ width = 16;
+ }
+
+ if (x == 0)
+ al = l-width;
+ else
+ al = a-1;
+
+ omxRes = omxVCM4P10_PredictIntra_4x4( l,
+ a,
+ al,
+ data,
+ (i32)width,
+ 16,
+ (OMXVCM4P10Intra4x4PredMode)mode,
+ (i32)(availableB +
+ (availableA<<1) +
+ (availableD<<5) +
+ (availableC<<6)) );
+ if (omxRes != OMX_Sts_NoErr)
+ return HANTRO_NOK;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdIntraChromaPrediction
+
+ Functional description:
+ Perform intra prediction for chroma pixels and add residual
+ into prediction. The resulting chroma pixels are stored in 'data'.
+
+------------------------------------------------------------------------------*/
+u32 h264bsdIntraChromaPrediction(mbStorage_t *pMb, u8 *data, image_t *image,
+ u32 predMode, u32 constrainedIntraPred)
+{
+
+/* Variables */
+
+ u32 availableA, availableB, availableD;
+ OMXResult omxRes;
+ u8 *ptr;
+ u32 width;
+
+/* Code */
+ ASSERT(pMb);
+ ASSERT(data);
+ ASSERT(image);
+ ASSERT(predMode < 4);
+
+ availableA = h264bsdIsNeighbourAvailable(pMb, pMb->mbA);
+ if (availableA && constrainedIntraPred &&
+ (h264bsdMbPartPredMode(pMb->mbA->mbType) == PRED_MODE_INTER))
+ availableA = HANTRO_FALSE;
+ availableB = h264bsdIsNeighbourAvailable(pMb, pMb->mbB);
+ if (availableB && constrainedIntraPred &&
+ (h264bsdMbPartPredMode(pMb->mbB->mbType) == PRED_MODE_INTER))
+ availableB = HANTRO_FALSE;
+ availableD = h264bsdIsNeighbourAvailable(pMb, pMb->mbD);
+ if (availableD && constrainedIntraPred &&
+ (h264bsdMbPartPredMode(pMb->mbD->mbType) == PRED_MODE_INTER))
+ availableD = HANTRO_FALSE;
+
+ ptr = image->cb;
+ width = image->width*8;
+
+ omxRes = omxVCM4P10_PredictIntraChroma_8x8( (ptr-1),
+ (ptr - width),
+ (ptr - width -1),
+ data,
+ (i32)width,
+ 8,
+ (OMXVCM4P10IntraChromaPredMode)
+ predMode,
+ (i32)(availableB +
+ (availableA<<1) +
+ (availableD<<5)) );
+ if (omxRes != OMX_Sts_NoErr)
+ return HANTRO_NOK;
+
+ /* advance pointers */
+ data += 64;
+ ptr = image->cr;
+
+ omxRes = omxVCM4P10_PredictIntraChroma_8x8( (ptr-1),
+ (ptr - width),
+ (ptr - width -1),
+ data,
+ (i32)width,
+ 8,
+ (OMXVCM4P10IntraChromaPredMode)
+ predMode,
+ (i32)(availableB +
+ (availableA<<1) +
+ (availableD<<5)) );
+ if (omxRes != OMX_Sts_NoErr)
+ return HANTRO_NOK;
+
+ return(HANTRO_OK);
+
+}
+
+
+#else /* H264DEC_OMXDL */
+
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdIntraPrediction
+
+ Functional description:
+ Processes one intra macroblock. Performs intra prediction using
+ specified prediction mode. Writes the final macroblock
+ (prediction + residual) into the output image (image)
+
+ Inputs:
+ pMb pointer to macroblock specific information
+ mbLayer pointer to current macroblock data from stream
+ image pointer to output image
+ mbNum current macroblock number
+ constrainedIntraPred flag specifying if neighbouring inter
+ macroblocks are used in intra prediction
+ data pointer where output macroblock will be stored
+
+ Outputs:
+ pMb structure is updated with current macroblock
+ image current macroblock is written into image
+ data current macroblock is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK error in intra prediction
+
+------------------------------------------------------------------------------*/
+u32 h264bsdIntraPrediction(mbStorage_t *pMb, macroblockLayer_t *mbLayer,
+ image_t *image, u32 mbNum, u32 constrainedIntraPred, u8 *data)
+{
+
+/* Variables */
+
+ /* pelAbove and pelLeft contain samples above and left to the current
+ * macroblock. Above array contains also sample above-left to the current
+ * mb as well as 4 samples above-right to the current mb (latter only for
+ * luma) */
+ /* lumD + lumB + lumC + cbD + cbB + crD + crB */
+ u8 pelAbove[1 + 16 + 4 + 1 + 8 + 1 + 8];
+ /* lumA + cbA + crA */
+ u8 pelLeft[16 + 8 + 8];
+ u32 tmp;
+
+/* Code */
+
+ ASSERT(pMb);
+ ASSERT(image);
+ ASSERT(mbNum < image->width * image->height);
+ ASSERT(h264bsdMbPartPredMode(pMb->mbType) != PRED_MODE_INTER);
+
+ h264bsdGetNeighbourPels(image, pelAbove, pelLeft, mbNum);
+
+ if (h264bsdMbPartPredMode(pMb->mbType) == PRED_MODE_INTRA16x16)
+ {
+ tmp = h264bsdIntra16x16Prediction(pMb, data, mbLayer->residual.level,
+ pelAbove, pelLeft, constrainedIntraPred);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+ else
+ {
+ tmp = h264bsdIntra4x4Prediction(pMb, data, mbLayer,
+ pelAbove, pelLeft, constrainedIntraPred);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+
+ tmp = h264bsdIntraChromaPrediction(pMb, data + 256,
+ mbLayer->residual.level+16, pelAbove + 21, pelLeft + 16,
+ mbLayer->mbPred.intraChromaPredMode, constrainedIntraPred);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* if decoded flag > 1 -> mb has already been successfully decoded and
+ * written to output -> do not write again */
+ if (pMb->decoded > 1)
+ return HANTRO_OK;
+
+ h264bsdWriteMacroblock(image, data);
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdGetNeighbourPels
+
+ Functional description:
+ Get pixel values from neighbouring macroblocks into 'above'
+ and 'left' arrays.
+
+------------------------------------------------------------------------------*/
+
+void h264bsdGetNeighbourPels(image_t *image, u8 *above, u8 *left, u32 mbNum)
+{
+
+/* Variables */
+
+ u32 i;
+ u32 width, picSize;
+ u8 *ptr, *tmp;
+ u32 row, col;
+
+/* Code */
+
+ ASSERT(image);
+ ASSERT(above);
+ ASSERT(left);
+ ASSERT(mbNum < image->width * image->height);
+
+ if (!mbNum)
+ return;
+
+ width = image->width;
+ picSize = width * image->height;
+ row = mbNum / width;
+ col = mbNum - row * width;
+
+ width *= 16;
+ ptr = image->data + row * 16 * width + col * 16;
+
+ /* note that luma samples above-right to current macroblock do not make
+ * sense when current mb is the right-most mb in a row. Same applies to
+ * sample above-left if col is zero. However, usage of pels in prediction
+ * is controlled by neighbour availability information in actual prediction
+ * process */
+ if (row)
+ {
+ tmp = ptr - (width + 1);
+ for (i = 21; i--;)
+ *above++ = *tmp++;
+ }
+
+ if (col)
+ {
+ ptr--;
+ for (i = 16; i--; ptr+=width)
+ *left++ = *ptr;
+ }
+
+ width >>= 1;
+ ptr = image->data + picSize * 256 + row * 8 * width + col * 8;
+
+ if (row)
+ {
+ tmp = ptr - (width + 1);
+ for (i = 9; i--;)
+ *above++ = *tmp++;
+ tmp += (picSize * 64) - 9;
+ for (i = 9; i--;)
+ *above++ = *tmp++;
+ }
+
+ if (col)
+ {
+ ptr--;
+ for (i = 8; i--; ptr+=width)
+ *left++ = *ptr;
+ ptr += (picSize * 64) - 8 * width;
+ for (i = 8; i--; ptr+=width)
+ *left++ = *ptr;
+ }
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Intra16x16Prediction
+
+ Functional description:
+ Perform intra 16x16 prediction mode for luma pixels and add
+ residual into prediction. The resulting luma pixels are
+ stored in macroblock array 'data'.
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdIntra16x16Prediction(mbStorage_t *pMb, u8 *data, i32 residual[][16],
+ u8 *above, u8 *left, u32 constrainedIntraPred)
+{
+
+/* Variables */
+
+ u32 i;
+ u32 availableA, availableB, availableD;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(residual);
+ ASSERT(above);
+ ASSERT(left);
+ ASSERT(h264bsdPredModeIntra16x16(pMb->mbType) < 4);
+
+ availableA = h264bsdIsNeighbourAvailable(pMb, pMb->mbA);
+ if (availableA && constrainedIntraPred &&
+ (h264bsdMbPartPredMode(pMb->mbA->mbType) == PRED_MODE_INTER))
+ availableA = HANTRO_FALSE;
+ availableB = h264bsdIsNeighbourAvailable(pMb, pMb->mbB);
+ if (availableB && constrainedIntraPred &&
+ (h264bsdMbPartPredMode(pMb->mbB->mbType) == PRED_MODE_INTER))
+ availableB = HANTRO_FALSE;
+ availableD = h264bsdIsNeighbourAvailable(pMb, pMb->mbD);
+ if (availableD && constrainedIntraPred &&
+ (h264bsdMbPartPredMode(pMb->mbD->mbType) == PRED_MODE_INTER))
+ availableD = HANTRO_FALSE;
+
+ switch(h264bsdPredModeIntra16x16(pMb->mbType))
+ {
+ case 0: /* Intra_16x16_Vertical */
+ if (!availableB)
+ return(HANTRO_NOK);
+ Intra16x16VerticalPrediction(data, above+1);
+ break;
+
+ case 1: /* Intra_16x16_Horizontal */
+ if (!availableA)
+ return(HANTRO_NOK);
+ Intra16x16HorizontalPrediction(data, left);
+ break;
+
+ case 2: /* Intra_16x16_DC */
+ Intra16x16DcPrediction(data, above+1, left, availableA, availableB);
+ break;
+
+ default: /* case 3: Intra_16x16_Plane */
+ if (!availableA || !availableB || !availableD)
+ return(HANTRO_NOK);
+ Intra16x16PlanePrediction(data, above+1, left);
+ break;
+ }
+ /* add residual */
+ for (i = 0; i < 16; i++)
+ h264bsdAddResidual(data, residual[i], i);
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Intra4x4Prediction
+
+ Functional description:
+ Perform intra 4x4 prediction for luma pixels and add residual
+ into prediction. The resulting luma pixels are stored in
+ macroblock array 'data'. The intra 4x4 prediction mode for each
+ block is stored in 'pMb' structure.
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdIntra4x4Prediction(mbStorage_t *pMb, u8 *data,
+ macroblockLayer_t *mbLayer, u8 *above,
+ u8 *left, u32 constrainedIntraPred)
+{
+
+/* Variables */
+
+ u32 block;
+ u32 mode;
+ neighbour_t neighbour, neighbourB;
+ mbStorage_t *nMb, *nMb2;
+ u8 a[1 + 4 + 4], l[1 + 4];
+ u32 data4x4[4];
+ u32 availableA, availableB, availableC, availableD;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(mbLayer);
+ ASSERT(above);
+ ASSERT(left);
+
+ for (block = 0; block < 16; block++)
+ {
+
+ ASSERT(pMb->intra4x4PredMode[block] < 9);
+
+ neighbour = *h264bsdNeighbour4x4BlockA(block);
+ nMb = h264bsdGetNeighbourMb(pMb, neighbour.mb);
+ availableA = h264bsdIsNeighbourAvailable(pMb, nMb);
+ if (availableA && constrainedIntraPred &&
+ ( h264bsdMbPartPredMode(nMb->mbType) == PRED_MODE_INTER) )
+ {
+ availableA = HANTRO_FALSE;
+ }
+
+ neighbourB = *h264bsdNeighbour4x4BlockB(block);
+ nMb2 = h264bsdGetNeighbourMb(pMb, neighbourB.mb);
+ availableB = h264bsdIsNeighbourAvailable(pMb, nMb2);
+ if (availableB && constrainedIntraPred &&
+ ( h264bsdMbPartPredMode(nMb2->mbType) == PRED_MODE_INTER) )
+ {
+ availableB = HANTRO_FALSE;
+ }
+
+ mode = DetermineIntra4x4PredMode(mbLayer,
+ (u32)(availableA && availableB),
+ &neighbour, &neighbourB, block, nMb, nMb2);
+ pMb->intra4x4PredMode[block] = (u8)mode;
+
+ neighbour = *h264bsdNeighbour4x4BlockC(block);
+ nMb = h264bsdGetNeighbourMb(pMb, neighbour.mb);
+ availableC = h264bsdIsNeighbourAvailable(pMb, nMb);
+ if (availableC && constrainedIntraPred &&
+ ( h264bsdMbPartPredMode(nMb->mbType) == PRED_MODE_INTER) )
+ {
+ availableC = HANTRO_FALSE;
+ }
+
+ neighbour = *h264bsdNeighbour4x4BlockD(block);
+ nMb = h264bsdGetNeighbourMb(pMb, neighbour.mb);
+ availableD = h264bsdIsNeighbourAvailable(pMb, nMb);
+ if (availableD && constrainedIntraPred &&
+ ( h264bsdMbPartPredMode(nMb->mbType) == PRED_MODE_INTER) )
+ {
+ availableD = HANTRO_FALSE;
+ }
+
+ Get4x4NeighbourPels(a, l, data, above, left, block);
+
+ switch(mode)
+ {
+ case 0: /* Intra_4x4_Vertical */
+ if (!availableB)
+ return(HANTRO_NOK);
+ Intra4x4VerticalPrediction((u8*)data4x4, a + 1);
+ break;
+ case 1: /* Intra_4x4_Horizontal */
+ if (!availableA)
+ return(HANTRO_NOK);
+ Intra4x4HorizontalPrediction((u8*)data4x4, l + 1);
+ break;
+ case 2: /* Intra_4x4_DC */
+ Intra4x4DcPrediction((u8*)data4x4, a + 1, l + 1,
+ availableA, availableB);
+ break;
+ case 3: /* Intra_4x4_Diagonal_Down_Left */
+ if (!availableB)
+ return(HANTRO_NOK);
+ if (!availableC)
+ {
+ a[5] = a[6] = a[7] = a[8] = a[4];
+ }
+ Intra4x4DiagonalDownLeftPrediction((u8*)data4x4, a + 1);
+ break;
+ case 4: /* Intra_4x4_Diagonal_Down_Right */
+ if (!availableA || !availableB || !availableD)
+ return(HANTRO_NOK);
+ Intra4x4DiagonalDownRightPrediction((u8*)data4x4, a + 1, l + 1);
+ break;
+ case 5: /* Intra_4x4_Vertical_Right */
+ if (!availableA || !availableB || !availableD)
+ return(HANTRO_NOK);
+ Intra4x4VerticalRightPrediction((u8*)data4x4, a + 1, l + 1);
+ break;
+ case 6: /* Intra_4x4_Horizontal_Down */
+ if (!availableA || !availableB || !availableD)
+ return(HANTRO_NOK);
+ Intra4x4HorizontalDownPrediction((u8*)data4x4, a + 1, l + 1);
+ break;
+ case 7: /* Intra_4x4_Vertical_Left */
+ if (!availableB)
+ return(HANTRO_NOK);
+ if (!availableC)
+ {
+ a[5] = a[6] = a[7] = a[8] = a[4];
+ }
+ Intra4x4VerticalLeftPrediction((u8*)data4x4, a + 1);
+ break;
+ default: /* case 8 Intra_4x4_Horizontal_Up */
+ if (!availableA)
+ return(HANTRO_NOK);
+ Intra4x4HorizontalUpPrediction((u8*)data4x4, l + 1);
+ break;
+ }
+
+ Write4x4To16x16(data, (u8*)data4x4, block);
+ h264bsdAddResidual(data, mbLayer->residual.level[block], block);
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: IntraChromaPrediction
+
+ Functional description:
+ Perform intra prediction for chroma pixels and add residual
+ into prediction. The resulting chroma pixels are stored in 'data'.
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdIntraChromaPrediction(mbStorage_t *pMb, u8 *data, i32 residual[][16],
+ u8 *above, u8 *left, u32 predMode, u32 constrainedIntraPred)
+{
+
+/* Variables */
+
+ u32 i, comp, block;
+ u32 availableA, availableB, availableD;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(residual);
+ ASSERT(above);
+ ASSERT(left);
+ ASSERT(predMode < 4);
+
+ availableA = h264bsdIsNeighbourAvailable(pMb, pMb->mbA);
+ if (availableA && constrainedIntraPred &&
+ (h264bsdMbPartPredMode(pMb->mbA->mbType) == PRED_MODE_INTER))
+ availableA = HANTRO_FALSE;
+ availableB = h264bsdIsNeighbourAvailable(pMb, pMb->mbB);
+ if (availableB && constrainedIntraPred &&
+ (h264bsdMbPartPredMode(pMb->mbB->mbType) == PRED_MODE_INTER))
+ availableB = HANTRO_FALSE;
+ availableD = h264bsdIsNeighbourAvailable(pMb, pMb->mbD);
+ if (availableD && constrainedIntraPred &&
+ (h264bsdMbPartPredMode(pMb->mbD->mbType) == PRED_MODE_INTER))
+ availableD = HANTRO_FALSE;
+
+ for (comp = 0, block = 16; comp < 2; comp++)
+ {
+ switch(predMode)
+ {
+ case 0: /* Intra_Chroma_DC */
+ IntraChromaDcPrediction(data, above+1, left, availableA,
+ availableB);
+ break;
+
+ case 1: /* Intra_Chroma_Horizontal */
+ if (!availableA)
+ return(HANTRO_NOK);
+ IntraChromaHorizontalPrediction(data, left);
+ break;
+
+ case 2: /* Intra_Chroma_Vertical */
+ if (!availableB)
+ return(HANTRO_NOK);
+ IntraChromaVerticalPrediction(data, above+1);
+
+ break;
+
+ default: /* case 3: Intra_Chroma_Plane */
+ if (!availableA || !availableB || !availableD)
+ return(HANTRO_NOK);
+ IntraChromaPlanePrediction(data, above+1, left);
+ break;
+ }
+ for (i = 0; i < 4; i++, block++)
+ h264bsdAddResidual(data, residual[i], block);
+
+ /* advance pointers */
+ data += 64;
+ above += 9;
+ left += 8;
+ residual += 4;
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdAddResidual
+
+ Functional description:
+ Add residual of a block into prediction in macroblock array 'data'.
+ The result (residual + prediction) is stored in 'data'.
+
+------------------------------------------------------------------------------*/
+#ifndef H264DEC_OMXDL
+void h264bsdAddResidual(u8 *data, i32 *residual, u32 blockNum)
+{
+
+/* Variables */
+
+ u32 i;
+ u32 x, y;
+ u32 width;
+ i32 tmp1, tmp2, tmp3, tmp4;
+ u8 *tmp;
+ const u8 *clp = h264bsdClip + 512;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(residual);
+ ASSERT(blockNum < 16 + 4 + 4);
+
+ if (IS_RESIDUAL_EMPTY(residual))
+ return;
+
+ RANGE_CHECK_ARRAY(residual, -512, 511, 16);
+
+ if (blockNum < 16)
+ {
+ width = 16;
+ x = h264bsdBlockX[blockNum];
+ y = h264bsdBlockY[blockNum];
+ }
+ else
+ {
+ width = 8;
+ x = h264bsdBlockX[blockNum & 0x3];
+ y = h264bsdBlockY[blockNum & 0x3];
+ }
+
+ tmp = data + y*width + x;
+ for (i = 4; i; i--)
+ {
+ tmp1 = *residual++;
+ tmp2 = tmp[0];
+ tmp3 = *residual++;
+ tmp4 = tmp[1];
+
+ tmp[0] = clp[tmp1 + tmp2];
+
+ tmp1 = *residual++;
+ tmp2 = tmp[2];
+
+ tmp[1] = clp[tmp3 + tmp4];
+
+ tmp3 = *residual++;
+ tmp4 = tmp[3];
+
+ tmp1 = clp[tmp1 + tmp2];
+ tmp3 = clp[tmp3 + tmp4];
+ tmp[2] = (u8)tmp1;
+ tmp[3] = (u8)tmp3;
+
+ tmp += width;
+ }
+
+}
+#endif
+/*------------------------------------------------------------------------------
+
+ Function: Intra16x16VerticalPrediction
+
+ Functional description:
+ Perform intra 16x16 vertical prediction mode.
+
+------------------------------------------------------------------------------*/
+
+void Intra16x16VerticalPrediction(u8 *data, u8 *above)
+{
+
+/* Variables */
+
+ u32 i, j;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(above);
+
+ for (i = 0; i < 16; i++)
+ {
+ for (j = 0; j < 16; j++)
+ {
+ *data++ = above[j];
+ }
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Intra16x16HorizontalPrediction
+
+ Functional description:
+ Perform intra 16x16 horizontal prediction mode.
+
+------------------------------------------------------------------------------*/
+
+void Intra16x16HorizontalPrediction(u8 *data, u8 *left)
+{
+
+/* Variables */
+
+ u32 i, j;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(left);
+
+ for (i = 0; i < 16; i++)
+ {
+ for (j = 0; j < 16; j++)
+ {
+ *data++ = left[i];
+ }
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Intra16x16DcPrediction
+
+ Functional description:
+ Perform intra 16x16 DC prediction mode.
+
+------------------------------------------------------------------------------*/
+
+void Intra16x16DcPrediction(u8 *data, u8 *above, u8 *left, u32 availableA,
+ u32 availableB)
+{
+
+/* Variables */
+
+ u32 i, tmp;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(above);
+ ASSERT(left);
+
+ if (availableA && availableB)
+ {
+ for (i = 0, tmp = 0; i < 16; i++)
+ tmp += above[i] + left[i];
+ tmp = (tmp + 16) >> 5;
+ }
+ else if (availableA)
+ {
+ for (i = 0, tmp = 0; i < 16; i++)
+ tmp += left[i];
+ tmp = (tmp + 8) >> 4;
+ }
+ else if (availableB)
+ {
+ for (i = 0, tmp = 0; i < 16; i++)
+ tmp += above[i];
+ tmp = (tmp + 8) >> 4;
+ }
+ /* neither A nor B available */
+ else
+ {
+ tmp = 128;
+ }
+ for (i = 0; i < 256; i++)
+ data[i] = (u8)tmp;
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Intra16x16PlanePrediction
+
+ Functional description:
+ Perform intra 16x16 plane prediction mode.
+
+------------------------------------------------------------------------------*/
+
+void Intra16x16PlanePrediction(u8 *data, u8 *above, u8 *left)
+{
+
+/* Variables */
+
+ u32 i, j;
+ i32 a, b, c;
+ i32 tmp;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(above);
+ ASSERT(left);
+
+ a = 16 * (above[15] + left[15]);
+
+ for (i = 0, b = 0; i < 8; i++)
+ b += ((i32)i + 1) * (above[8+i] - above[6-i]);
+ b = (5 * b + 32) >> 6;
+
+ for (i = 0, c = 0; i < 7; i++)
+ c += ((i32)i + 1) * (left[8+i] - left[6-i]);
+ /* p[-1,-1] has to be accessed through above pointer */
+ c += ((i32)i + 1) * (left[8+i] - above[-1]);
+ c = (5 * c + 32) >> 6;
+
+ for (i = 0; i < 16; i++)
+ {
+ for (j = 0; j < 16; j++)
+ {
+ tmp = (a + b * ((i32)j - 7) + c * ((i32)i - 7) + 16) >> 5;
+ data[i*16+j] = (u8)CLIP1(tmp);
+ }
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: IntraChromaDcPrediction
+
+ Functional description:
+ Perform intra chroma DC prediction mode.
+
+------------------------------------------------------------------------------*/
+
+void IntraChromaDcPrediction(u8 *data, u8 *above, u8 *left, u32 availableA,
+ u32 availableB)
+{
+
+/* Variables */
+
+ u32 i;
+ u32 tmp1, tmp2;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(above);
+ ASSERT(left);
+
+ /* y = 0..3 */
+ if (availableA && availableB)
+ {
+ tmp1 = above[0] + above[1] + above[2] + above[3] +
+ left[0] + left[1] + left[2] + left[3];
+ tmp1 = (tmp1 + 4) >> 3;
+ tmp2 = (above[4] + above[5] + above[6] + above[7] + 2) >> 2;
+ }
+ else if (availableB)
+ {
+ tmp1 = (above[0] + above[1] + above[2] + above[3] + 2) >> 2;
+ tmp2 = (above[4] + above[5] + above[6] + above[7] + 2) >> 2;
+ }
+ else if (availableA)
+ {
+ tmp1 = (left[0] + left[1] + left[2] + left[3] + 2) >> 2;
+ tmp2 = tmp1;
+ }
+ /* neither A nor B available */
+ else
+ {
+ tmp1 = tmp2 = 128;
+ }
+
+ ASSERT(tmp1 < 256 && tmp2 < 256);
+ for (i = 4; i--;)
+ {
+ *data++ = (u8)tmp1;
+ *data++ = (u8)tmp1;
+ *data++ = (u8)tmp1;
+ *data++ = (u8)tmp1;
+ *data++ = (u8)tmp2;
+ *data++ = (u8)tmp2;
+ *data++ = (u8)tmp2;
+ *data++ = (u8)tmp2;
+ }
+
+ /* y = 4...7 */
+ if (availableA)
+ {
+ tmp1 = (left[4] + left[5] + left[6] + left[7] + 2) >> 2;
+ if (availableB)
+ {
+ tmp2 = above[4] + above[5] + above[6] + above[7] +
+ left[4] + left[5] + left[6] + left[7];
+ tmp2 = (tmp2 + 4) >> 3;
+ }
+ else
+ tmp2 = tmp1;
+ }
+ else if (availableB)
+ {
+ tmp1 = (above[0] + above[1] + above[2] + above[3] + 2) >> 2;
+ tmp2 = (above[4] + above[5] + above[6] + above[7] + 2) >> 2;
+ }
+ else
+ {
+ tmp1 = tmp2 = 128;
+ }
+
+ ASSERT(tmp1 < 256 && tmp2 < 256);
+ for (i = 4; i--;)
+ {
+ *data++ = (u8)tmp1;
+ *data++ = (u8)tmp1;
+ *data++ = (u8)tmp1;
+ *data++ = (u8)tmp1;
+ *data++ = (u8)tmp2;
+ *data++ = (u8)tmp2;
+ *data++ = (u8)tmp2;
+ *data++ = (u8)tmp2;
+ }
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: IntraChromaHorizontalPrediction
+
+ Functional description:
+ Perform intra chroma horizontal prediction mode.
+
+------------------------------------------------------------------------------*/
+
+void IntraChromaHorizontalPrediction(u8 *data, u8 *left)
+{
+
+/* Variables */
+
+ u32 i;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(left);
+
+ for (i = 8; i--;)
+ {
+ *data++ = *left;
+ *data++ = *left;
+ *data++ = *left;
+ *data++ = *left;
+ *data++ = *left;
+ *data++ = *left;
+ *data++ = *left;
+ *data++ = *left++;
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: IntraChromaVerticalPrediction
+
+ Functional description:
+ Perform intra chroma vertical prediction mode.
+
+------------------------------------------------------------------------------*/
+
+void IntraChromaVerticalPrediction(u8 *data, u8 *above)
+{
+
+/* Variables */
+
+ u32 i;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(above);
+
+ for (i = 8; i--;data++/*above-=8*/)
+ {
+ data[0] = *above;
+ data[8] = *above;
+ data[16] = *above;
+ data[24] = *above;
+ data[32] = *above;
+ data[40] = *above;
+ data[48] = *above;
+ data[56] = *above++;
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: IntraChromaPlanePrediction
+
+ Functional description:
+ Perform intra chroma plane prediction mode.
+
+------------------------------------------------------------------------------*/
+
+void IntraChromaPlanePrediction(u8 *data, u8 *above, u8 *left)
+{
+
+/* Variables */
+
+ u32 i;
+ i32 a, b, c;
+ i32 tmp;
+ const u8 *clp = h264bsdClip + 512;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(above);
+ ASSERT(left);
+
+ a = 16 * (above[7] + left[7]);
+
+ b = (above[4] - above[2]) + 2 * (above[5] - above[1])
+ + 3 * (above[6] - above[0]) + 4 * (above[7] - above[-1]);
+ b = (17 * b + 16) >> 5;
+
+ /* p[-1,-1] has to be accessed through above pointer */
+ c = (left[4] - left[2]) + 2 * (left[5] - left[1])
+ + 3 * (left[6] - left[0]) + 4 * (left[7] - above[-1]);
+ c = (17 * c + 16) >> 5;
+
+ /*a += 16;*/
+ a = a - 3 * c + 16;
+ for (i = 8; i--; a += c)
+ {
+ tmp = (a - 3 * b);
+ *data++ = clp[tmp>>5];
+ tmp += b;
+ *data++ = clp[tmp>>5];
+ tmp += b;
+ *data++ = clp[tmp>>5];
+ tmp += b;
+ *data++ = clp[tmp>>5];
+ tmp += b;
+ *data++ = clp[tmp>>5];
+ tmp += b;
+ *data++ = clp[tmp>>5];
+ tmp += b;
+ *data++ = clp[tmp>>5];
+ tmp += b;
+ *data++ = clp[tmp>>5];
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Get4x4NeighbourPels
+
+ Functional description:
+ Get neighbouring pixels of a 4x4 block into 'a' and 'l'.
+
+------------------------------------------------------------------------------*/
+
+void Get4x4NeighbourPels(u8 *a, u8 *l, u8 *data, u8 *above, u8 *left,
+ u32 blockNum)
+{
+
+/* Variables */
+
+ u32 x, y;
+ u8 t1, t2;
+
+/* Code */
+
+ ASSERT(a);
+ ASSERT(l);
+ ASSERT(data);
+ ASSERT(above);
+ ASSERT(left);
+ ASSERT(blockNum < 16);
+
+ x = h264bsdBlockX[blockNum];
+ y = h264bsdBlockY[blockNum];
+
+ /* A and D */
+ if (x == 0)
+ {
+ t1 = left[y ];
+ t2 = left[y + 1];
+ l[1] = t1;
+ l[2] = t2;
+ t1 = left[y + 2];
+ t2 = left[y + 3];
+ l[3] = t1;
+ l[4] = t2;
+ }
+ else
+ {
+ t1 = data[y * 16 + x - 1 ];
+ t2 = data[y * 16 + x - 1 + 16];
+ l[1] = t1;
+ l[2] = t2;
+ t1 = data[y * 16 + x - 1 + 32];
+ t2 = data[y * 16 + x - 1 + 48];
+ l[3] = t1;
+ l[4] = t2;
+ }
+
+ /* B, C and D */
+ if (y == 0)
+ {
+ t1 = above[x ];
+ t2 = above[x ];
+ l[0] = t1;
+ a[0] = t2;
+ t1 = above[x + 1];
+ t2 = above[x + 2];
+ a[1] = t1;
+ a[2] = t2;
+ t1 = above[x + 3];
+ t2 = above[x + 4];
+ a[3] = t1;
+ a[4] = t2;
+ t1 = above[x + 5];
+ t2 = above[x + 6];
+ a[5] = t1;
+ a[6] = t2;
+ t1 = above[x + 7];
+ t2 = above[x + 8];
+ a[7] = t1;
+ a[8] = t2;
+ }
+ else
+ {
+ t1 = data[(y - 1) * 16 + x ];
+ t2 = data[(y - 1) * 16 + x + 1];
+ a[1] = t1;
+ a[2] = t2;
+ t1 = data[(y - 1) * 16 + x + 2];
+ t2 = data[(y - 1) * 16 + x + 3];
+ a[3] = t1;
+ a[4] = t2;
+ t1 = data[(y - 1) * 16 + x + 4];
+ t2 = data[(y - 1) * 16 + x + 5];
+ a[5] = t1;
+ a[6] = t2;
+ t1 = data[(y - 1) * 16 + x + 6];
+ t2 = data[(y - 1) * 16 + x + 7];
+ a[7] = t1;
+ a[8] = t2;
+
+ if (x == 0)
+ l[0] = a[0] = left[y-1];
+ else
+ l[0] = a[0] = data[(y - 1) * 16 + x - 1];
+ }
+}
+
+
+/*------------------------------------------------------------------------------
+
+ Function: Intra4x4VerticalPrediction
+
+ Functional description:
+ Perform intra 4x4 vertical prediction mode.
+
+------------------------------------------------------------------------------*/
+
+void Intra4x4VerticalPrediction(u8 *data, u8 *above)
+{
+
+/* Variables */
+
+ u8 t1, t2;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(above);
+
+ t1 = above[0];
+ t2 = above[1];
+ data[0] = data[4] = data[8] = data[12] = t1;
+ data[1] = data[5] = data[9] = data[13] = t2;
+ t1 = above[2];
+ t2 = above[3];
+ data[2] = data[6] = data[10] = data[14] = t1;
+ data[3] = data[7] = data[11] = data[15] = t2;
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Intra4x4HorizontalPrediction
+
+ Functional description:
+ Perform intra 4x4 horizontal prediction mode.
+
+------------------------------------------------------------------------------*/
+
+void Intra4x4HorizontalPrediction(u8 *data, u8 *left)
+{
+
+/* Variables */
+
+ u8 t1, t2;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(left);
+
+ t1 = left[0];
+ t2 = left[1];
+ data[0] = data[1] = data[2] = data[3] = t1;
+ data[4] = data[5] = data[6] = data[7] = t2;
+ t1 = left[2];
+ t2 = left[3];
+ data[8] = data[9] = data[10] = data[11] = t1;
+ data[12] = data[13] = data[14] = data[15] = t2;
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Intra4x4DcPrediction
+
+ Functional description:
+ Perform intra 4x4 DC prediction mode.
+
+------------------------------------------------------------------------------*/
+
+void Intra4x4DcPrediction(u8 *data, u8 *above, u8 *left, u32 availableA,
+ u32 availableB)
+{
+
+/* Variables */
+
+ u32 tmp;
+ u8 t1, t2, t3, t4;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(above);
+ ASSERT(left);
+
+ if (availableA && availableB)
+ {
+ t1 = above[0]; t2 = above[1]; t3 = above[2]; t4 = above[3];
+ tmp = t1 + t2 + t3 + t4;
+ t1 = left[0]; t2 = left[1]; t3 = left[2]; t4 = left[3];
+ tmp += t1 + t2 + t3 + t4;
+ tmp = (tmp + 4) >> 3;
+ }
+ else if (availableA)
+ {
+ t1 = left[0]; t2 = left[1]; t3 = left[2]; t4 = left[3];
+ tmp = (t1 + t2 + t3 + t4 + 2) >> 2;
+ }
+ else if (availableB)
+ {
+ t1 = above[0]; t2 = above[1]; t3 = above[2]; t4 = above[3];
+ tmp = (t1 + t2 + t3 + t4 + 2) >> 2;
+ }
+ else
+ {
+ tmp = 128;
+ }
+
+ ASSERT(tmp < 256);
+ data[0] = data[1] = data[2] = data[3] =
+ data[4] = data[5] = data[6] = data[7] =
+ data[8] = data[9] = data[10] = data[11] =
+ data[12] = data[13] = data[14] = data[15] = (u8)tmp;
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Intra4x4DiagonalDownLeftPrediction
+
+ Functional description:
+ Perform intra 4x4 diagonal down-left prediction mode.
+
+------------------------------------------------------------------------------*/
+
+void Intra4x4DiagonalDownLeftPrediction(u8 *data, u8 *above)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(above);
+
+ data[ 0] = (above[0] + 2 * above[1] + above[2] + 2) >> 2;
+ data[ 1] = (above[1] + 2 * above[2] + above[3] + 2) >> 2;
+ data[ 4] = (above[1] + 2 * above[2] + above[3] + 2) >> 2;
+ data[ 2] = (above[2] + 2 * above[3] + above[4] + 2) >> 2;
+ data[ 5] = (above[2] + 2 * above[3] + above[4] + 2) >> 2;
+ data[ 8] = (above[2] + 2 * above[3] + above[4] + 2) >> 2;
+ data[ 3] = (above[3] + 2 * above[4] + above[5] + 2) >> 2;
+ data[ 6] = (above[3] + 2 * above[4] + above[5] + 2) >> 2;
+ data[ 9] = (above[3] + 2 * above[4] + above[5] + 2) >> 2;
+ data[12] = (above[3] + 2 * above[4] + above[5] + 2) >> 2;
+ data[ 7] = (above[4] + 2 * above[5] + above[6] + 2) >> 2;
+ data[10] = (above[4] + 2 * above[5] + above[6] + 2) >> 2;
+ data[13] = (above[4] + 2 * above[5] + above[6] + 2) >> 2;
+ data[11] = (above[5] + 2 * above[6] + above[7] + 2) >> 2;
+ data[14] = (above[5] + 2 * above[6] + above[7] + 2) >> 2;
+ data[15] = (above[6] + 3 * above[7] + 2) >> 2;
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Intra4x4DiagonalDownRightPrediction
+
+ Functional description:
+ Perform intra 4x4 diagonal down-right prediction mode.
+
+------------------------------------------------------------------------------*/
+
+void Intra4x4DiagonalDownRightPrediction(u8 *data, u8 *above, u8 *left)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(above);
+ ASSERT(left);
+
+ data[ 0] = (above[0] + 2 * above[-1] + left[0] + 2) >> 2;
+ data[ 5] = (above[0] + 2 * above[-1] + left[0] + 2) >> 2;
+ data[10] = (above[0] + 2 * above[-1] + left[0] + 2) >> 2;
+ data[15] = (above[0] + 2 * above[-1] + left[0] + 2) >> 2;
+ data[ 1] = (above[-1] + 2 * above[0] + above[1] + 2) >> 2;
+ data[ 6] = (above[-1] + 2 * above[0] + above[1] + 2) >> 2;
+ data[11] = (above[-1] + 2 * above[0] + above[1] + 2) >> 2;
+ data[ 2] = (above[0] + 2 * above[1] + above[2] + 2) >> 2;
+ data[ 7] = (above[0] + 2 * above[1] + above[2] + 2) >> 2;
+ data[ 3] = (above[1] + 2 * above[2] + above[3] + 2) >> 2;
+ data[ 4] = (left[-1] + 2 * left[0] + left[1] + 2) >> 2;
+ data[ 9] = (left[-1] + 2 * left[0] + left[1] + 2) >> 2;
+ data[14] = (left[-1] + 2 * left[0] + left[1] + 2) >> 2;
+ data[ 8] = (left[0] + 2 * left[1] + left[2] + 2) >> 2;
+ data[13] = (left[0] + 2 * left[1] + left[2] + 2) >> 2;
+ data[12] = (left[1] + 2 * left[2] + left[3] + 2) >> 2;
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Intra4x4VerticalRightPrediction
+
+ Functional description:
+ Perform intra 4x4 vertical right prediction mode.
+
+------------------------------------------------------------------------------*/
+
+void Intra4x4VerticalRightPrediction(u8 *data, u8 *above, u8 *left)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(above);
+ ASSERT(left);
+
+ data[ 0] = (above[-1] + above[0] + 1) >> 1;
+ data[ 9] = (above[-1] + above[0] + 1) >> 1;
+ data[ 5] = (above[-1] + 2 * above[0] + above[1] + 2) >> 2;
+ data[14] = (above[-1] + 2 * above[0] + above[1] + 2) >> 2;
+ data[ 4] = (above[0] + 2 * above[-1] + left[0] + 2) >> 2;
+ data[13] = (above[0] + 2 * above[-1] + left[0] + 2) >> 2;
+ data[ 1] = (above[0] + above[1] + 1) >> 1;
+ data[10] = (above[0] + above[1] + 1) >> 1;
+ data[ 6] = (above[0] + 2 * above[1] + above[2] + 2) >> 2;
+ data[15] = (above[0] + 2 * above[1] + above[2] + 2) >> 2;
+ data[ 2] = (above[1] + above[2] + 1) >> 1;
+ data[11] = (above[1] + above[2] + 1) >> 1;
+ data[ 7] = (above[1] + 2 * above[2] + above[3] + 2) >> 2;
+ data[ 3] = (above[2] + above[3] + 1) >> 1;
+ data[ 8] = (left[1] + 2 * left[0] + left[-1] + 2) >> 2;
+ data[12] = (left[2] + 2 * left[1] + left[0] + 2) >> 2;
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Intra4x4HorizontalDownPrediction
+
+ Functional description:
+ Perform intra 4x4 horizontal down prediction mode.
+
+------------------------------------------------------------------------------*/
+
+void Intra4x4HorizontalDownPrediction(u8 *data, u8 *above, u8 *left)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(above);
+ ASSERT(left);
+
+ data[ 0] = (left[-1] + left[0] + 1) >> 1;
+ data[ 6] = (left[-1] + left[0] + 1) >> 1;
+ data[ 5] = (left[-1] + 2 * left[0] + left[1] + 2) >> 2;
+ data[11] = (left[-1] + 2 * left[0] + left[1] + 2) >> 2;
+ data[ 4] = (left[0] + left[1] + 1) >> 1;
+ data[10] = (left[0] + left[1] + 1) >> 1;
+ data[ 9] = (left[0] + 2 * left[1] + left[2] + 2) >> 2;
+ data[15] = (left[0] + 2 * left[1] + left[2] + 2) >> 2;
+ data[ 8] = (left[1] + left[2] + 1) >> 1;
+ data[14] = (left[1] + left[2] + 1) >> 1;
+ data[13] = (left[1] + 2 * left[2] + left[3] + 2) >> 2;
+ data[12] = (left[2] + left[3] + 1) >> 1;
+ data[ 1] = (above[0] + 2 * above[-1] + left[0] + 2) >> 2;
+ data[ 7] = (above[0] + 2 * above[-1] + left[0] + 2) >> 2;
+ data[ 2] = (above[1] + 2 * above[0] + above[-1] + 2) >> 2;
+ data[ 3] = (above[2] + 2 * above[1] + above[0] + 2) >> 2;
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Intra4x4VerticalLeftPrediction
+
+ Functional description:
+ Perform intra 4x4 vertical left prediction mode.
+
+------------------------------------------------------------------------------*/
+
+void Intra4x4VerticalLeftPrediction(u8 *data, u8 *above)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(above);
+
+ data[ 0] = (above[0] + above[1] + 1) >> 1;
+ data[ 1] = (above[1] + above[2] + 1) >> 1;
+ data[ 2] = (above[2] + above[3] + 1) >> 1;
+ data[ 3] = (above[3] + above[4] + 1) >> 1;
+ data[ 4] = (above[0] + 2 * above[1] + above[2] + 2) >> 2;
+ data[ 5] = (above[1] + 2 * above[2] + above[3] + 2) >> 2;
+ data[ 6] = (above[2] + 2 * above[3] + above[4] + 2) >> 2;
+ data[ 7] = (above[3] + 2 * above[4] + above[5] + 2) >> 2;
+ data[ 8] = (above[1] + above[2] + 1) >> 1;
+ data[ 9] = (above[2] + above[3] + 1) >> 1;
+ data[10] = (above[3] + above[4] + 1) >> 1;
+ data[11] = (above[4] + above[5] + 1) >> 1;
+ data[12] = (above[1] + 2 * above[2] + above[3] + 2) >> 2;
+ data[13] = (above[2] + 2 * above[3] + above[4] + 2) >> 2;
+ data[14] = (above[3] + 2 * above[4] + above[5] + 2) >> 2;
+ data[15] = (above[4] + 2 * above[5] + above[6] + 2) >> 2;
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Intra4x4HorizontalUpPrediction
+
+ Functional description:
+ Perform intra 4x4 horizontal up prediction mode.
+
+------------------------------------------------------------------------------*/
+
+void Intra4x4HorizontalUpPrediction(u8 *data, u8 *left)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(left);
+
+ data[ 0] = (left[0] + left[1] + 1) >> 1;
+ data[ 1] = (left[0] + 2 * left[1] + left[2] + 2) >> 2;
+ data[ 2] = (left[1] + left[2] + 1) >> 1;
+ data[ 3] = (left[1] + 2 * left[2] + left[3] + 2) >> 2;
+ data[ 4] = (left[1] + left[2] + 1) >> 1;
+ data[ 5] = (left[1] + 2 * left[2] + left[3] + 2) >> 2;
+ data[ 6] = (left[2] + left[3] + 1) >> 1;
+ data[ 7] = (left[2] + 3 * left[3] + 2) >> 2;
+ data[ 8] = (left[2] + left[3] + 1) >> 1;
+ data[ 9] = (left[2] + 3 * left[3] + 2) >> 2;
+ data[10] = left[3];
+ data[11] = left[3];
+ data[12] = left[3];
+ data[13] = left[3];
+ data[14] = left[3];
+ data[15] = left[3];
+
+}
+
+#endif /* H264DEC_OMXDL */
+
+/*------------------------------------------------------------------------------
+
+ Function: Write4x4To16x16
+
+ Functional description:
+ Write a 4x4 block (data4x4) into correct position
+ in 16x16 macroblock (data).
+
+------------------------------------------------------------------------------*/
+
+void Write4x4To16x16(u8 *data, u8 *data4x4, u32 blockNum)
+{
+
+/* Variables */
+
+ u32 x, y;
+ u32 *in32, *out32;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(data4x4);
+ ASSERT(blockNum < 16);
+
+ x = h264bsdBlockX[blockNum];
+ y = h264bsdBlockY[blockNum];
+
+ data += y*16+x;
+
+ ASSERT(((u32)data&0x3) == 0);
+
+ /*lint --e(826) */
+ out32 = (u32 *)data;
+ /*lint --e(826) */
+ in32 = (u32 *)data4x4;
+
+ out32[0] = *in32++;
+ out32[4] = *in32++;
+ out32[8] = *in32++;
+ out32[12] = *in32++;
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DetermineIntra4x4PredMode
+
+ Functional description:
+ Returns the intra 4x4 prediction mode of a block based on the
+ neighbouring macroblocks and information parsed from stream.
+
+------------------------------------------------------------------------------*/
+
+u32 DetermineIntra4x4PredMode(macroblockLayer_t *pMbLayer,
+ u32 available, neighbour_t *nA, neighbour_t *nB, u32 index,
+ mbStorage_t *nMbA, mbStorage_t *nMbB)
+{
+
+/* Variables */
+
+ u32 mode1, mode2;
+ mbStorage_t *pMb;
+
+/* Code */
+
+ ASSERT(pMbLayer);
+
+ /* dc only prediction? */
+ if (!available)
+ mode1 = 2;
+ else
+ {
+ pMb = nMbA;
+ if (h264bsdMbPartPredMode(pMb->mbType) == PRED_MODE_INTRA4x4)
+ {
+ mode1 = pMb->intra4x4PredMode[nA->index];
+ }
+ else
+ mode1 = 2;
+
+ pMb = nMbB;
+ if (h264bsdMbPartPredMode(pMb->mbType) == PRED_MODE_INTRA4x4)
+ {
+ mode2 = pMb->intra4x4PredMode[nB->index];
+ }
+ else
+ mode2 = 2;
+
+ mode1 = MIN(mode1, mode2);
+ }
+
+ if (!pMbLayer->mbPred.prevIntra4x4PredModeFlag[index])
+ {
+ if (pMbLayer->mbPred.remIntra4x4PredMode[index] < mode1)
+ {
+ mode1 = pMbLayer->mbPred.remIntra4x4PredMode[index];
+ }
+ else
+ {
+ mode1 = pMbLayer->mbPred.remIntra4x4PredMode[index] + 1;
+ }
+ }
+
+ return(mode1);
+}
+
+
+/*lint +e702 */
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_intra_prediction.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_intra_prediction.h
new file mode 100755
index 0000000..4652bd5
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_intra_prediction.h
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_INTRA_PREDICTION_H
+#define H264SWDEC_INTRA_PREDICTION_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_image.h"
+#include "h264bsd_macroblock_layer.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+#ifndef H264DEC_OMXDL
+u32 h264bsdIntraPrediction(mbStorage_t *pMb, macroblockLayer_t *mbLayer,
+ image_t *image, u32 mbNum, u32 constrainedIntraPred, u8 *data);
+
+u32 h264bsdIntra4x4Prediction(mbStorage_t *pMb, u8 *data,
+ macroblockLayer_t *mbLayer,
+ u8 *above, u8 *left, u32 constrainedIntraPred);
+u32 h264bsdIntra16x16Prediction(mbStorage_t *pMb, u8 *data, i32 residual[][16],
+ u8 *above, u8 *left, u32 constrainedIntraPred);
+
+u32 h264bsdIntraChromaPrediction(mbStorage_t *pMb, u8 *data, i32 residual[][16],
+ u8 *above, u8 *left, u32 predMode, u32 constrainedIntraPred);
+
+void h264bsdGetNeighbourPels(image_t *image, u8 *above, u8 *left, u32 mbNum);
+
+#else
+
+u32 h264bsdIntra4x4Prediction(mbStorage_t *pMb, u8 *data,
+ macroblockLayer_t *mbLayer,
+ u8 *pImage, u32 width,
+ u32 constrainedIntraPred, u32 block);
+
+u32 h264bsdIntra16x16Prediction(mbStorage_t *pMb, u8 *data, u8 *pImage,
+ u32 width, u32 constrainedIntraPred);
+
+u32 h264bsdIntraChromaPrediction(mbStorage_t *pMb, u8 *data, image_t *image,
+ u32 predMode, u32 constrainedIntraPred);
+
+#endif
+
+#endif /* #ifdef H264SWDEC_INTRA_PREDICTION_H */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_macroblock_layer.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_macroblock_layer.c
new file mode 100755
index 0000000..2b3e7f0
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_macroblock_layer.c
@@ -0,0 +1,1446 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdDecodeMacroblockLayer
+ h264bsdMbPartPredMode
+ h264bsdNumMbPart
+ h264bsdNumSubMbPart
+ DecodeMbPred
+ DecodeSubMbPred
+ DecodeResidual
+ DetermineNc
+ CbpIntra16x16
+ h264bsdPredModeIntra16x16
+ h264bsdDecodeMacroblock
+ ProcessResidual
+ h264bsdSubMbPartMode
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_macroblock_layer.h"
+#include "h264bsd_slice_header.h"
+#include "h264bsd_util.h"
+#include "h264bsd_vlc.h"
+#include "h264bsd_cavlc.h"
+#include "h264bsd_nal_unit.h"
+#include "h264bsd_neighbour.h"
+#include "h264bsd_transform.h"
+#include "h264bsd_intra_prediction.h"
+#include "h264bsd_inter_prediction.h"
+
+#ifdef H264DEC_OMXDL
+#include "omxtypes.h"
+#include "omxVC.h"
+#include "armVC.h"
+#endif /* H264DEC_OMXDL */
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+#ifdef H264DEC_OMXDL
+static const u32 chromaIndex[8] = { 256, 260, 288, 292, 320, 324, 352, 356 };
+static const u32 lumaIndex[16] = { 0, 4, 64, 68,
+ 8, 12, 72, 76,
+ 128, 132, 192, 196,
+ 136, 140, 200, 204 };
+#endif
+/* mapping of dc coefficients array to luma blocks */
+static const u32 dcCoeffIndex[16] =
+ {0, 1, 4, 5, 2, 3, 6, 7, 8, 9, 12, 13, 10, 11, 14, 15};
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+static u32 DecodeMbPred(strmData_t *pStrmData, mbPred_t *pMbPred,
+ mbType_e mbType, u32 numRefIdxActive);
+static u32 DecodeSubMbPred(strmData_t *pStrmData, subMbPred_t *pSubMbPred,
+ mbType_e mbType, u32 numRefIdxActive);
+static u32 DecodeResidual(strmData_t *pStrmData, residual_t *pResidual,
+ mbStorage_t *pMb, mbType_e mbType, u32 codedBlockPattern);
+
+#ifdef H264DEC_OMXDL
+static u32 DetermineNc(mbStorage_t *pMb, u32 blockIndex, u8 *pTotalCoeff);
+#else
+static u32 DetermineNc(mbStorage_t *pMb, u32 blockIndex, i16 *pTotalCoeff);
+#endif
+
+static u32 CbpIntra16x16(mbType_e mbType);
+#ifdef H264DEC_OMXDL
+static u32 ProcessIntra4x4Residual(mbStorage_t *pMb, u8 *data, u32 constrainedIntraPred,
+ macroblockLayer_t *mbLayer, const u8 **pSrc, image_t *image);
+static u32 ProcessChromaResidual(mbStorage_t *pMb, u8 *data, const u8 **pSrc );
+static u32 ProcessIntra16x16Residual(mbStorage_t *pMb, u8 *data, u32 constrainedIntraPred,
+ u32 intraChromaPredMode, const u8 **pSrc, image_t *image);
+
+
+#else
+static u32 ProcessResidual(mbStorage_t *pMb, i32 residualLevel[][16], u32 *);
+#endif
+
+/*------------------------------------------------------------------------------
+
+ Function name: h264bsdDecodeMacroblockLayer
+
+ Functional description:
+ Parse macroblock specific information from bit stream.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+ pMb pointer to macroblock storage structure
+ sliceType type of the current slice
+ numRefIdxActive maximum reference index
+
+ Outputs:
+ pMbLayer stores the macroblock data parsed from stream
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK end of stream or error in stream
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeMacroblockLayer(strmData_t *pStrmData,
+ macroblockLayer_t *pMbLayer, mbStorage_t *pMb, u32 sliceType,
+ u32 numRefIdxActive)
+{
+
+/* Variables */
+
+ u32 tmp, i, value;
+ i32 itmp;
+ mbPartPredMode_e partMode;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pMbLayer);
+
+#ifdef H264DEC_NEON
+ h264bsdClearMbLayer(pMbLayer, ((sizeof(macroblockLayer_t) + 63) & ~0x3F));
+#else
+ H264SwDecMemset(pMbLayer, 0, sizeof(macroblockLayer_t));
+#endif
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+
+ if (IS_I_SLICE(sliceType))
+ {
+ if ((value + 6) > 31 || tmp != HANTRO_OK)
+ return(HANTRO_NOK);
+ pMbLayer->mbType = (mbType_e)(value + 6);
+ }
+ else
+ {
+ if ((value + 1) > 31 || tmp != HANTRO_OK)
+ return(HANTRO_NOK);
+ pMbLayer->mbType = (mbType_e)(value + 1);
+ }
+
+ if (pMbLayer->mbType == I_PCM)
+ {
+ i32 *level;
+ while( !h264bsdIsByteAligned(pStrmData) )
+ {
+ /* pcm_alignment_zero_bit */
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp)
+ return(HANTRO_NOK);
+ }
+
+ level = pMbLayer->residual.level[0];
+ for (i = 0; i < 384; i++)
+ {
+ value = h264bsdGetBits(pStrmData, 8);
+ if (value == END_OF_STREAM)
+ return(HANTRO_NOK);
+ *level++ = (i32)value;
+ }
+ }
+ else
+ {
+ partMode = h264bsdMbPartPredMode(pMbLayer->mbType);
+ if ( (partMode == PRED_MODE_INTER) &&
+ (h264bsdNumMbPart(pMbLayer->mbType) == 4) )
+ {
+ tmp = DecodeSubMbPred(pStrmData, &pMbLayer->subMbPred,
+ pMbLayer->mbType, numRefIdxActive);
+ }
+ else
+ {
+ tmp = DecodeMbPred(pStrmData, &pMbLayer->mbPred,
+ pMbLayer->mbType, numRefIdxActive);
+ }
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ if (partMode != PRED_MODE_INTRA16x16)
+ {
+ tmp = h264bsdDecodeExpGolombMapped(pStrmData, &value,
+ (u32)(partMode == PRED_MODE_INTRA4x4));
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pMbLayer->codedBlockPattern = value;
+ }
+ else
+ {
+ pMbLayer->codedBlockPattern = CbpIntra16x16(pMbLayer->mbType);
+ }
+
+ if ( pMbLayer->codedBlockPattern ||
+ (partMode == PRED_MODE_INTRA16x16) )
+ {
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
+ if (tmp != HANTRO_OK || (itmp < -26) || (itmp > 25) )
+ return(HANTRO_NOK);
+ pMbLayer->mbQpDelta = itmp;
+
+ tmp = DecodeResidual(pStrmData, &pMbLayer->residual, pMb,
+ pMbLayer->mbType, pMbLayer->codedBlockPattern);
+
+ pStrmData->strmBuffReadBits =
+ (u32)(pStrmData->pStrmCurrPos - pStrmData->pStrmBuffStart) * 8 +
+ pStrmData->bitPosInWord;
+
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdMbPartPredMode
+
+ Functional description:
+ Returns the prediction mode of a macroblock type
+
+------------------------------------------------------------------------------*/
+
+mbPartPredMode_e h264bsdMbPartPredMode(mbType_e mbType)
+{
+
+/* Variables */
+
+
+/* Code */
+
+ ASSERT(mbType <= 31);
+
+ if ((mbType <= P_8x8ref0))
+ return(PRED_MODE_INTER);
+ else if (mbType == I_4x4)
+ return(PRED_MODE_INTRA4x4);
+ else
+ return(PRED_MODE_INTRA16x16);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdNumMbPart
+
+ Functional description:
+ Returns the amount of macroblock partitions in a macroblock type
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdNumMbPart(mbType_e mbType)
+{
+
+/* Variables */
+
+
+/* Code */
+
+ ASSERT(h264bsdMbPartPredMode(mbType) == PRED_MODE_INTER);
+
+ switch (mbType)
+ {
+ case P_L0_16x16:
+ case P_Skip:
+ return(1);
+
+ case P_L0_L0_16x8:
+ case P_L0_L0_8x16:
+ return(2);
+
+ /* P_8x8 or P_8x8ref0 */
+ default:
+ return(4);
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdNumSubMbPart
+
+ Functional description:
+ Returns the amount of sub-partitions in a sub-macroblock type
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdNumSubMbPart(subMbType_e subMbType)
+{
+
+/* Variables */
+
+
+/* Code */
+
+ ASSERT(subMbType <= P_L0_4x4);
+
+ switch (subMbType)
+ {
+ case P_L0_8x8:
+ return(1);
+
+ case P_L0_8x4:
+ case P_L0_4x8:
+ return(2);
+
+ /* P_L0_4x4 */
+ default:
+ return(4);
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeMbPred
+
+ Functional description:
+ Parse macroblock prediction information from bit stream and store
+ in 'pMbPred'.
+
+------------------------------------------------------------------------------*/
+
+u32 DecodeMbPred(strmData_t *pStrmData, mbPred_t *pMbPred, mbType_e mbType,
+ u32 numRefIdxActive)
+{
+
+/* Variables */
+
+ u32 tmp, i, j, value;
+ i32 itmp;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pMbPred);
+
+ switch (h264bsdMbPartPredMode(mbType))
+ {
+ case PRED_MODE_INTER: /* PRED_MODE_INTER */
+ if (numRefIdxActive > 1)
+ {
+ for (i = h264bsdNumMbPart(mbType), j = 0; i--; j++)
+ {
+ tmp = h264bsdDecodeExpGolombTruncated(pStrmData, &value,
+ (u32)(numRefIdxActive > 2));
+ if (tmp != HANTRO_OK || value >= numRefIdxActive)
+ return(HANTRO_NOK);
+
+ pMbPred->refIdxL0[j] = value;
+ }
+ }
+
+ for (i = h264bsdNumMbPart(mbType), j = 0; i--; j++)
+ {
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pMbPred->mvdL0[j].hor = (i16)itmp;
+
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pMbPred->mvdL0[j].ver = (i16)itmp;
+ }
+ break;
+
+ case PRED_MODE_INTRA4x4:
+ for (itmp = 0, i = 0; itmp < 2; itmp++)
+ {
+ value = h264bsdShowBits32(pStrmData);
+ tmp = 0;
+ for (j = 8; j--; i++)
+ {
+ pMbPred->prevIntra4x4PredModeFlag[i] =
+ value & 0x80000000 ? HANTRO_TRUE : HANTRO_FALSE;
+ value <<= 1;
+ if (!pMbPred->prevIntra4x4PredModeFlag[i])
+ {
+ pMbPred->remIntra4x4PredMode[i] = value>>29;
+ value <<= 3;
+ tmp++;
+ }
+ }
+ if (h264bsdFlushBits(pStrmData, 8 + 3*tmp) == END_OF_STREAM)
+ return(HANTRO_NOK);
+ }
+ /* fall-through */
+
+ case PRED_MODE_INTRA16x16:
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK || value > 3)
+ return(HANTRO_NOK);
+ pMbPred->intraChromaPredMode = value;
+ break;
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeSubMbPred
+
+ Functional description:
+ Parse sub-macroblock prediction information from bit stream and
+ store in 'pMbPred'.
+
+------------------------------------------------------------------------------*/
+
+u32 DecodeSubMbPred(strmData_t *pStrmData, subMbPred_t *pSubMbPred,
+ mbType_e mbType, u32 numRefIdxActive)
+{
+
+/* Variables */
+
+ u32 tmp, i, j, value;
+ i32 itmp;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pSubMbPred);
+ ASSERT(h264bsdMbPartPredMode(mbType) == PRED_MODE_INTER);
+
+ for (i = 0; i < 4; i++)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK || value > 3)
+ return(HANTRO_NOK);
+ pSubMbPred->subMbType[i] = (subMbType_e)value;
+ }
+
+ if ( (numRefIdxActive > 1) && (mbType != P_8x8ref0) )
+ {
+ for (i = 0; i < 4; i++)
+ {
+ tmp = h264bsdDecodeExpGolombTruncated(pStrmData, &value,
+ (u32)(numRefIdxActive > 2));
+ if (tmp != HANTRO_OK || value >= numRefIdxActive)
+ return(HANTRO_NOK);
+ pSubMbPred->refIdxL0[i] = value;
+ }
+ }
+
+ for (i = 0; i < 4; i++)
+ {
+ j = 0;
+ for (value = h264bsdNumSubMbPart(pSubMbPred->subMbType[i]);
+ value--; j++)
+ {
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pSubMbPred->mvdL0[i][j].hor = (i16)itmp;
+
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pSubMbPred->mvdL0[i][j].ver = (i16)itmp;
+ }
+ }
+
+ return(HANTRO_OK);
+
+}
+
+#ifdef H264DEC_OMXDL
+/*------------------------------------------------------------------------------
+
+ Function: DecodeResidual
+
+ Functional description:
+ Parse residual information from bit stream and store in 'pResidual'.
+
+------------------------------------------------------------------------------*/
+
+u32 DecodeResidual(strmData_t *pStrmData, residual_t *pResidual,
+ mbStorage_t *pMb, mbType_e mbType, u32 codedBlockPattern)
+{
+
+/* Variables */
+
+ u32 i, j;
+ u32 blockCoded;
+ u32 blockIndex;
+ u32 is16x16;
+ OMX_INT nc;
+ OMXResult omxRes;
+ OMX_U8 *pPosCoefBuf;
+
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pResidual);
+
+ pPosCoefBuf = pResidual->posCoefBuf;
+
+ /* luma DC is at index 24 */
+ if (h264bsdMbPartPredMode(mbType) == PRED_MODE_INTRA16x16)
+ {
+ nc = (OMX_INT)DetermineNc(pMb, 0, pResidual->totalCoeff);
+#ifndef H264DEC_NEON
+ omxRes = omxVCM4P10_DecodeCoeffsToPairCAVLC(
+ (const OMX_U8 **) (&pStrmData->pStrmCurrPos),
+ (OMX_S32*) (&pStrmData->bitPosInWord),
+ &pResidual->totalCoeff[24],
+ &pPosCoefBuf,
+ nc,
+ 16);
+#else
+ omxRes = armVCM4P10_DecodeCoeffsToPair(
+ (const OMX_U8 **) (&pStrmData->pStrmCurrPos),
+ (OMX_S32*) (&pStrmData->bitPosInWord),
+ &pResidual->totalCoeff[24],
+ &pPosCoefBuf,
+ nc,
+ 16);
+#endif
+ if (omxRes != OMX_Sts_NoErr)
+ return(HANTRO_NOK);
+ is16x16 = HANTRO_TRUE;
+ }
+ else
+ is16x16 = HANTRO_FALSE;
+
+ for (i = 4, blockIndex = 0; i--;)
+ {
+ /* luma cbp in bits 0-3 */
+ blockCoded = codedBlockPattern & 0x1;
+ codedBlockPattern >>= 1;
+ if (blockCoded)
+ {
+ for (j = 4; j--; blockIndex++)
+ {
+ nc = (OMX_INT)DetermineNc(pMb,blockIndex,pResidual->totalCoeff);
+ if (is16x16)
+ {
+#ifndef H264DEC_NEON
+ omxRes = omxVCM4P10_DecodeCoeffsToPairCAVLC(
+ (const OMX_U8 **) (&pStrmData->pStrmCurrPos),
+ (OMX_S32*) (&pStrmData->bitPosInWord),
+ &pResidual->totalCoeff[blockIndex],
+ &pPosCoefBuf,
+ nc,
+ 15);
+#else
+ omxRes = armVCM4P10_DecodeCoeffsToPair(
+ (const OMX_U8 **) (&pStrmData->pStrmCurrPos),
+ (OMX_S32*) (&pStrmData->bitPosInWord),
+ &pResidual->totalCoeff[blockIndex],
+ &pPosCoefBuf,
+ nc,
+ 15);
+#endif
+ }
+ else
+ {
+#ifndef H264DEC_NEON
+ omxRes = omxVCM4P10_DecodeCoeffsToPairCAVLC(
+ (const OMX_U8 **) (&pStrmData->pStrmCurrPos),
+ (OMX_S32*) (&pStrmData->bitPosInWord),
+ &pResidual->totalCoeff[blockIndex],
+ &pPosCoefBuf,
+ nc,
+ 16);
+#else
+ omxRes = armVCM4P10_DecodeCoeffsToPair(
+ (const OMX_U8 **) (&pStrmData->pStrmCurrPos),
+ (OMX_S32*) (&pStrmData->bitPosInWord),
+ &pResidual->totalCoeff[blockIndex],
+ &pPosCoefBuf,
+ nc,
+ 16);
+#endif
+ }
+ if (omxRes != OMX_Sts_NoErr)
+ return(HANTRO_NOK);
+ }
+ }
+ else
+ blockIndex += 4;
+ }
+
+ /* chroma DC block are at indices 25 and 26 */
+ blockCoded = codedBlockPattern & 0x3;
+ if (blockCoded)
+ {
+#ifndef H264DEC_NEON
+ omxRes = omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC(
+ (const OMX_U8**) (&pStrmData->pStrmCurrPos),
+ (OMX_S32*) (&pStrmData->bitPosInWord),
+ &pResidual->totalCoeff[25],
+ &pPosCoefBuf);
+#else
+ omxRes = armVCM4P10_DecodeCoeffsToPair(
+ (const OMX_U8**) (&pStrmData->pStrmCurrPos),
+ (OMX_S32*) (&pStrmData->bitPosInWord),
+ &pResidual->totalCoeff[25],
+ &pPosCoefBuf,
+ 17,
+ 4);
+#endif
+ if (omxRes != OMX_Sts_NoErr)
+ return(HANTRO_NOK);
+#ifndef H264DEC_NEON
+ omxRes = omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC(
+ (const OMX_U8**) (&pStrmData->pStrmCurrPos),
+ (OMX_S32*) (&pStrmData->bitPosInWord),
+ &pResidual->totalCoeff[26],
+ &pPosCoefBuf);
+#else
+ omxRes = armVCM4P10_DecodeCoeffsToPair(
+ (const OMX_U8**) (&pStrmData->pStrmCurrPos),
+ (OMX_S32*) (&pStrmData->bitPosInWord),
+ &pResidual->totalCoeff[26],
+ &pPosCoefBuf,
+ 17,
+ 4);
+#endif
+ if (omxRes != OMX_Sts_NoErr)
+ return(HANTRO_NOK);
+ }
+
+ /* chroma AC */
+ blockCoded = codedBlockPattern & 0x2;
+ if (blockCoded)
+ {
+ for (i = 8; i--;blockIndex++)
+ {
+ nc = (OMX_INT)DetermineNc(pMb, blockIndex, pResidual->totalCoeff);
+#ifndef H264DEC_NEON
+ omxRes = omxVCM4P10_DecodeCoeffsToPairCAVLC(
+ (const OMX_U8 **) (&pStrmData->pStrmCurrPos),
+ (OMX_S32*) (&pStrmData->bitPosInWord),
+ &pResidual->totalCoeff[blockIndex],
+ &pPosCoefBuf,
+ nc,
+ 15);
+#else
+ omxRes = armVCM4P10_DecodeCoeffsToPair(
+ (const OMX_U8 **) (&pStrmData->pStrmCurrPos),
+ (OMX_S32*) (&pStrmData->bitPosInWord),
+ &pResidual->totalCoeff[blockIndex],
+ &pPosCoefBuf,
+ nc,
+ 15);
+#endif
+ if (omxRes != OMX_Sts_NoErr)
+ return(HANTRO_NOK);
+ }
+ }
+
+ return(HANTRO_OK);
+
+}
+
+#else
+/*------------------------------------------------------------------------------
+
+ Function: DecodeResidual
+
+ Functional description:
+ Parse residual information from bit stream and store in 'pResidual'.
+
+------------------------------------------------------------------------------*/
+
+u32 DecodeResidual(strmData_t *pStrmData, residual_t *pResidual,
+ mbStorage_t *pMb, mbType_e mbType, u32 codedBlockPattern)
+{
+
+/* Variables */
+
+ u32 i, j, tmp;
+ i32 nc;
+ u32 blockCoded;
+ u32 blockIndex;
+ u32 is16x16;
+ i32 (*level)[16];
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pResidual);
+
+ level = pResidual->level;
+
+ /* luma DC is at index 24 */
+ if (h264bsdMbPartPredMode(mbType) == PRED_MODE_INTRA16x16)
+ {
+ nc = (i32)DetermineNc(pMb, 0, pResidual->totalCoeff);
+ tmp = h264bsdDecodeResidualBlockCavlc(pStrmData, level[24], nc, 16);
+ if ((tmp & 0xF) != HANTRO_OK)
+ return(tmp);
+ pResidual->totalCoeff[24] = (tmp >> 4) & 0xFF;
+ is16x16 = HANTRO_TRUE;
+ }
+ else
+ is16x16 = HANTRO_FALSE;
+
+ for (i = 4, blockIndex = 0; i--;)
+ {
+ /* luma cbp in bits 0-3 */
+ blockCoded = codedBlockPattern & 0x1;
+ codedBlockPattern >>= 1;
+ if (blockCoded)
+ {
+ for (j = 4; j--; blockIndex++)
+ {
+ nc = (i32)DetermineNc(pMb, blockIndex, pResidual->totalCoeff);
+ if (is16x16)
+ {
+ tmp = h264bsdDecodeResidualBlockCavlc(pStrmData,
+ level[blockIndex] + 1, nc, 15);
+ pResidual->coeffMap[blockIndex] = tmp >> 15;
+ }
+ else
+ {
+ tmp = h264bsdDecodeResidualBlockCavlc(pStrmData,
+ level[blockIndex], nc, 16);
+ pResidual->coeffMap[blockIndex] = tmp >> 16;
+ }
+ if ((tmp & 0xF) != HANTRO_OK)
+ return(tmp);
+ pResidual->totalCoeff[blockIndex] = (tmp >> 4) & 0xFF;
+ }
+ }
+ else
+ blockIndex += 4;
+ }
+
+ /* chroma DC block are at indices 25 and 26 */
+ blockCoded = codedBlockPattern & 0x3;
+ if (blockCoded)
+ {
+ tmp = h264bsdDecodeResidualBlockCavlc(pStrmData, level[25], -1, 4);
+ if ((tmp & 0xF) != HANTRO_OK)
+ return(tmp);
+ pResidual->totalCoeff[25] = (tmp >> 4) & 0xFF;
+ tmp = h264bsdDecodeResidualBlockCavlc(pStrmData, level[25]+4, -1, 4);
+ if ((tmp & 0xF) != HANTRO_OK)
+ return(tmp);
+ pResidual->totalCoeff[26] = (tmp >> 4) & 0xFF;
+ }
+
+ /* chroma AC */
+ blockCoded = codedBlockPattern & 0x2;
+ if (blockCoded)
+ {
+ for (i = 8; i--;blockIndex++)
+ {
+ nc = (i32)DetermineNc(pMb, blockIndex, pResidual->totalCoeff);
+ tmp = h264bsdDecodeResidualBlockCavlc(pStrmData,
+ level[blockIndex] + 1, nc, 15);
+ if ((tmp & 0xF) != HANTRO_OK)
+ return(tmp);
+ pResidual->totalCoeff[blockIndex] = (tmp >> 4) & 0xFF;
+ pResidual->coeffMap[blockIndex] = (tmp >> 15);
+ }
+ }
+
+ return(HANTRO_OK);
+
+}
+#endif
+
+/*------------------------------------------------------------------------------
+
+ Function: DetermineNc
+
+ Functional description:
+ Returns the nC of a block.
+
+------------------------------------------------------------------------------*/
+#ifdef H264DEC_OMXDL
+u32 DetermineNc(mbStorage_t *pMb, u32 blockIndex, u8 *pTotalCoeff)
+#else
+u32 DetermineNc(mbStorage_t *pMb, u32 blockIndex, i16 *pTotalCoeff)
+#endif
+{
+/*lint -e702 */
+/* Variables */
+
+ u32 tmp;
+ i32 n;
+ const neighbour_t *neighbourA, *neighbourB;
+ u8 neighbourAindex, neighbourBindex;
+
+/* Code */
+
+ ASSERT(blockIndex < 24);
+
+ /* if neighbour block belongs to current macroblock totalCoeff array
+ * mbStorage has not been set/updated yet -> use pTotalCoeff */
+ neighbourA = h264bsdNeighbour4x4BlockA(blockIndex);
+ neighbourB = h264bsdNeighbour4x4BlockB(blockIndex);
+ neighbourAindex = neighbourA->index;
+ neighbourBindex = neighbourB->index;
+ if (neighbourA->mb == MB_CURR && neighbourB->mb == MB_CURR)
+ {
+ n = (pTotalCoeff[neighbourAindex] +
+ pTotalCoeff[neighbourBindex] + 1)>>1;
+ }
+ else if (neighbourA->mb == MB_CURR)
+ {
+ n = pTotalCoeff[neighbourAindex];
+ if (h264bsdIsNeighbourAvailable(pMb, pMb->mbB))
+ {
+ n = (n + pMb->mbB->totalCoeff[neighbourBindex] + 1) >> 1;
+ }
+ }
+ else if (neighbourB->mb == MB_CURR)
+ {
+ n = pTotalCoeff[neighbourBindex];
+ if (h264bsdIsNeighbourAvailable(pMb, pMb->mbA))
+ {
+ n = (n + pMb->mbA->totalCoeff[neighbourAindex] + 1) >> 1;
+ }
+ }
+ else
+ {
+ n = tmp = 0;
+ if (h264bsdIsNeighbourAvailable(pMb, pMb->mbA))
+ {
+ n = pMb->mbA->totalCoeff[neighbourAindex];
+ tmp = 1;
+ }
+ if (h264bsdIsNeighbourAvailable(pMb, pMb->mbB))
+ {
+ if (tmp)
+ n = (n + pMb->mbB->totalCoeff[neighbourBindex] + 1) >> 1;
+ else
+ n = pMb->mbB->totalCoeff[neighbourBindex];
+ }
+ }
+ return((u32)n);
+/*lint +e702 */
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: CbpIntra16x16
+
+ Functional description:
+ Returns the coded block pattern for intra 16x16 macroblock.
+
+------------------------------------------------------------------------------*/
+
+u32 CbpIntra16x16(mbType_e mbType)
+{
+
+/* Variables */
+
+ u32 cbp;
+ u32 tmp;
+
+/* Code */
+
+ ASSERT(mbType >= I_16x16_0_0_0 && mbType <= I_16x16_3_2_1);
+
+ if (mbType >= I_16x16_0_0_1)
+ cbp = 15;
+ else
+ cbp = 0;
+
+ /* tmp is 0 for I_16x16_0_0_0 mb type */
+ /* ignore lint warning on arithmetic on enum's */
+ tmp = /*lint -e(656)*/(mbType - I_16x16_0_0_0) >> 2;
+ if (tmp > 2)
+ tmp -= 3;
+
+ cbp += tmp << 4;
+
+ return(cbp);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdPredModeIntra16x16
+
+ Functional description:
+ Returns the prediction mode for intra 16x16 macroblock.
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdPredModeIntra16x16(mbType_e mbType)
+{
+
+/* Variables */
+
+ u32 tmp;
+
+/* Code */
+
+ ASSERT(mbType >= I_16x16_0_0_0 && mbType <= I_16x16_3_2_1);
+
+ /* tmp is 0 for I_16x16_0_0_0 mb type */
+ /* ignore lint warning on arithmetic on enum's */
+ tmp = /*lint -e(656)*/(mbType - I_16x16_0_0_0);
+
+ return(tmp & 0x3);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdDecodeMacroblock
+
+ Functional description:
+ Decode one macroblock and write into output image.
+
+ Inputs:
+ pMb pointer to macroblock specific information
+ mbLayer pointer to current macroblock data from stream
+ currImage pointer to output image
+ dpb pointer to decoded picture buffer
+ qpY pointer to slice QP
+ mbNum current macroblock number
+ constrainedIntraPred flag specifying if neighbouring inter
+ macroblocks are used in intra prediction
+
+ Outputs:
+ pMb structure is updated with current macroblock
+ currImage decoded macroblock is written into output image
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK error in macroblock decoding
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeMacroblock(mbStorage_t *pMb, macroblockLayer_t *pMbLayer,
+ image_t *currImage, dpbStorage_t *dpb, i32 *qpY, u32 mbNum,
+ u32 constrainedIntraPredFlag, u8* data)
+{
+
+/* Variables */
+
+ u32 i, tmp;
+ mbType_e mbType;
+#ifdef H264DEC_OMXDL
+ const u8 *pSrc;
+#endif
+/* Code */
+
+ ASSERT(pMb);
+ ASSERT(pMbLayer);
+ ASSERT(currImage);
+ ASSERT(qpY && *qpY < 52);
+ ASSERT(mbNum < currImage->width*currImage->height);
+
+ mbType = pMbLayer->mbType;
+ pMb->mbType = mbType;
+
+ pMb->decoded++;
+
+ h264bsdSetCurrImageMbPointers(currImage, mbNum);
+
+ if (mbType == I_PCM)
+ {
+ u8 *pData = (u8*)data;
+#ifdef H264DEC_OMXDL
+ u8 *tot = pMb->totalCoeff;
+#else
+ i16 *tot = pMb->totalCoeff;
+#endif
+ i32 *lev = pMbLayer->residual.level[0];
+
+ pMb->qpY = 0;
+
+ /* if decoded flag > 1 -> mb has already been successfully decoded and
+ * written to output -> do not write again */
+ if (pMb->decoded > 1)
+ {
+ for (i = 24; i--;)
+ *tot++ = 16;
+ return HANTRO_OK;
+ }
+
+ for (i = 24; i--;)
+ {
+ *tot++ = 16;
+ for (tmp = 16; tmp--;)
+ *pData++ = (u8)(*lev++);
+ }
+ h264bsdWriteMacroblock(currImage, (u8*)data);
+
+ return(HANTRO_OK);
+ }
+ else
+ {
+#ifdef H264DEC_OMXDL
+ if (h264bsdMbPartPredMode(mbType) == PRED_MODE_INTER)
+ {
+ tmp = h264bsdInterPrediction(pMb, pMbLayer, dpb, mbNum,
+ currImage, (u8*)data);
+ if (tmp != HANTRO_OK) return (tmp);
+ }
+#endif
+ if (mbType != P_Skip)
+ {
+ H264SwDecMemcpy(pMb->totalCoeff,
+ pMbLayer->residual.totalCoeff,
+ 27*sizeof(*pMb->totalCoeff));
+
+ /* update qpY */
+ if (pMbLayer->mbQpDelta)
+ {
+ *qpY = *qpY + pMbLayer->mbQpDelta;
+ if (*qpY < 0) *qpY += 52;
+ else if (*qpY >= 52) *qpY -= 52;
+ }
+ pMb->qpY = (u32)*qpY;
+
+#ifdef H264DEC_OMXDL
+ pSrc = pMbLayer->residual.posCoefBuf;
+
+ if (h264bsdMbPartPredMode(mbType) == PRED_MODE_INTER)
+ {
+ OMXResult res;
+ u8 *p;
+ u8 *totalCoeff = pMb->totalCoeff;
+
+ for (i = 0; i < 16; i++, totalCoeff++)
+ {
+ p = data + lumaIndex[i];
+ if (*totalCoeff)
+ {
+ res = omxVCM4P10_DequantTransformResidualFromPairAndAdd(
+ &pSrc, p, 0, p, 16, 16, *qpY, *totalCoeff);
+ if (res != OMX_Sts_NoErr)
+ return (HANTRO_NOK);
+ }
+ }
+
+ }
+ else if (h264bsdMbPartPredMode(mbType) == PRED_MODE_INTRA4x4)
+ {
+ tmp = ProcessIntra4x4Residual(pMb,
+ data,
+ constrainedIntraPredFlag,
+ pMbLayer,
+ &pSrc,
+ currImage);
+ if (tmp != HANTRO_OK)
+ return (tmp);
+ }
+ else if (h264bsdMbPartPredMode(mbType) == PRED_MODE_INTRA16x16)
+ {
+ tmp = ProcessIntra16x16Residual(pMb,
+ data,
+ constrainedIntraPredFlag,
+ pMbLayer->mbPred.intraChromaPredMode,
+ &pSrc,
+ currImage);
+ if (tmp != HANTRO_OK)
+ return (tmp);
+ }
+
+ tmp = ProcessChromaResidual(pMb, data, &pSrc);
+
+#else
+ tmp = ProcessResidual(pMb, pMbLayer->residual.level,
+ pMbLayer->residual.coeffMap);
+#endif
+ if (tmp != HANTRO_OK)
+ return (tmp);
+ }
+ else
+ {
+ H264SwDecMemset(pMb->totalCoeff, 0, 27*sizeof(*pMb->totalCoeff));
+ pMb->qpY = (u32)*qpY;
+ }
+#ifdef H264DEC_OMXDL
+ /* if decoded flag > 1 -> mb has already been successfully decoded and
+ * written to output -> do not write again */
+ if (pMb->decoded > 1)
+ return HANTRO_OK;
+
+ h264bsdWriteMacroblock(currImage, data);
+#else
+ if (h264bsdMbPartPredMode(mbType) != PRED_MODE_INTER)
+ {
+ tmp = h264bsdIntraPrediction(pMb, pMbLayer, currImage, mbNum,
+ constrainedIntraPredFlag, (u8*)data);
+ if (tmp != HANTRO_OK) return (tmp);
+ }
+ else
+ {
+ tmp = h264bsdInterPrediction(pMb, pMbLayer, dpb, mbNum,
+ currImage, (u8*)data);
+ if (tmp != HANTRO_OK) return (tmp);
+ }
+#endif
+ }
+
+ return HANTRO_OK;
+}
+
+
+#ifdef H264DEC_OMXDL
+
+/*------------------------------------------------------------------------------
+
+ Function: ProcessChromaResidual
+
+ Functional description:
+ Process the residual data of chroma with
+ inverse quantization and inverse transform.
+
+------------------------------------------------------------------------------*/
+u32 ProcessChromaResidual(mbStorage_t *pMb, u8 *data, const u8 **pSrc )
+{
+ u32 i;
+ u32 chromaQp;
+ i16 *pDc;
+ i16 dc[4 + 4] = {0,0,0,0,0,0,0,0};
+ u8 *totalCoeff;
+ OMXResult result;
+ u8 *p;
+
+ /* chroma DC processing. First chroma dc block is block with index 25 */
+ chromaQp =
+ h264bsdQpC[CLIP3(0, 51, (i32)pMb->qpY + pMb->chromaQpIndexOffset)];
+
+ if (pMb->totalCoeff[25])
+ {
+ pDc = dc;
+ result = omxVCM4P10_TransformDequantChromaDCFromPair(
+ pSrc,
+ pDc,
+ (i32)chromaQp);
+ if (result != OMX_Sts_NoErr)
+ return (HANTRO_NOK);
+ }
+ if (pMb->totalCoeff[26])
+ {
+ pDc = dc+4;
+ result = omxVCM4P10_TransformDequantChromaDCFromPair(
+ pSrc,
+ pDc,
+ (i32)chromaQp);
+ if (result != OMX_Sts_NoErr)
+ return (HANTRO_NOK);
+ }
+
+ pDc = dc;
+ totalCoeff = pMb->totalCoeff + 16;
+ for (i = 0; i < 8; i++, pDc++, totalCoeff++)
+ {
+ /* chroma prediction */
+ if (*totalCoeff || *pDc)
+ {
+ p = data + chromaIndex[i];
+ result = omxVCM4P10_DequantTransformResidualFromPairAndAdd(
+ pSrc,
+ p,
+ pDc,
+ p,
+ 8,
+ 8,
+ (i32)chromaQp,
+ *totalCoeff);
+ if (result != OMX_Sts_NoErr)
+ return (HANTRO_NOK);
+ }
+ }
+
+ return(HANTRO_OK);
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: ProcessIntra16x16Residual
+
+ Functional description:
+ Process the residual data of luma with
+ inverse quantization and inverse transform.
+
+------------------------------------------------------------------------------*/
+u32 ProcessIntra16x16Residual(mbStorage_t *pMb,
+ u8 *data,
+ u32 constrainedIntraPred,
+ u32 intraChromaPredMode,
+ const u8** pSrc,
+ image_t *image)
+{
+ u32 i;
+ i16 *pDc;
+ i16 dc[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+ u8 *totalCoeff;
+ OMXResult result;
+ u8 *p;
+
+ totalCoeff = pMb->totalCoeff;
+
+ if (totalCoeff[24])
+ {
+ pDc = dc;
+ result = omxVCM4P10_TransformDequantLumaDCFromPair(
+ pSrc,
+ pDc,
+ (i32)pMb->qpY);
+ if (result != OMX_Sts_NoErr)
+ return (HANTRO_NOK);
+ }
+ /* Intra 16x16 pred */
+ if (h264bsdIntra16x16Prediction(pMb, data, image->luma,
+ image->width*16, constrainedIntraPred) != HANTRO_OK)
+ return(HANTRO_NOK);
+ for (i = 0; i < 16; i++, totalCoeff++)
+ {
+ p = data + lumaIndex[i];
+ pDc = &dc[dcCoeffIndex[i]];
+ if (*totalCoeff || *pDc)
+ {
+ result = omxVCM4P10_DequantTransformResidualFromPairAndAdd(
+ pSrc,
+ p,
+ pDc,
+ p,
+ 16,
+ 16,
+ (i32)pMb->qpY,
+ *totalCoeff);
+ if (result != OMX_Sts_NoErr)
+ return (HANTRO_NOK);
+ }
+ }
+
+ if (h264bsdIntraChromaPrediction(pMb, data + 256,
+ image,
+ intraChromaPredMode,
+ constrainedIntraPred) != HANTRO_OK)
+ return(HANTRO_NOK);
+
+ return HANTRO_OK;
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: ProcessIntra4x4Residual
+
+ Functional description:
+ Process the residual data of luma with
+ inverse quantization and inverse transform.
+
+------------------------------------------------------------------------------*/
+u32 ProcessIntra4x4Residual(mbStorage_t *pMb,
+ u8 *data,
+ u32 constrainedIntraPred,
+ macroblockLayer_t *mbLayer,
+ const u8 **pSrc,
+ image_t *image)
+{
+ u32 i;
+ u8 *totalCoeff;
+ OMXResult result;
+ u8 *p;
+
+ totalCoeff = pMb->totalCoeff;
+
+ for (i = 0; i < 16; i++, totalCoeff++)
+ {
+ p = data + lumaIndex[i];
+ if (h264bsdIntra4x4Prediction(pMb, p, mbLayer, image->luma,
+ image->width*16, constrainedIntraPred, i) != HANTRO_OK)
+ return(HANTRO_NOK);
+
+ if (*totalCoeff)
+ {
+ result = omxVCM4P10_DequantTransformResidualFromPairAndAdd(
+ pSrc,
+ p,
+ NULL,
+ p,
+ 16,
+ 16,
+ (i32)pMb->qpY,
+ *totalCoeff);
+ if (result != OMX_Sts_NoErr)
+ return (HANTRO_NOK);
+ }
+ }
+
+ if (h264bsdIntraChromaPrediction(pMb, data + 256,
+ image,
+ mbLayer->mbPred.intraChromaPredMode,
+ constrainedIntraPred) != HANTRO_OK)
+ return(HANTRO_NOK);
+
+ return HANTRO_OK;
+}
+
+#else /* H264DEC_OMXDL */
+
+/*------------------------------------------------------------------------------
+
+ Function: ProcessResidual
+
+ Functional description:
+ Process the residual data of one macroblock with
+ inverse quantization and inverse transform.
+
+------------------------------------------------------------------------------*/
+
+u32 ProcessResidual(mbStorage_t *pMb, i32 residualLevel[][16], u32 *coeffMap)
+{
+
+/* Variables */
+
+ u32 i;
+ u32 chromaQp;
+ i32 (*blockData)[16];
+ i32 (*blockDc)[16];
+ i16 *totalCoeff;
+ i32 *chromaDc;
+ const u32 *dcCoeffIdx;
+
+/* Code */
+
+ ASSERT(pMb);
+ ASSERT(residualLevel);
+
+ /* set pointers to DC coefficient blocks */
+ blockDc = residualLevel + 24;
+
+ blockData = residualLevel;
+ totalCoeff = pMb->totalCoeff;
+ if (h264bsdMbPartPredMode(pMb->mbType) == PRED_MODE_INTRA16x16)
+ {
+ if (totalCoeff[24])
+ {
+ h264bsdProcessLumaDc(*blockDc, pMb->qpY);
+ }
+ dcCoeffIdx = dcCoeffIndex;
+
+ for (i = 16; i--; blockData++, totalCoeff++, coeffMap++)
+ {
+ /* set dc coefficient of luma block */
+ (*blockData)[0] = (*blockDc)[*dcCoeffIdx++];
+ if ((*blockData)[0] || *totalCoeff)
+ {
+ if (h264bsdProcessBlock(*blockData, pMb->qpY, 1, *coeffMap) !=
+ HANTRO_OK)
+ return(HANTRO_NOK);
+ }
+ else
+ MARK_RESIDUAL_EMPTY(*blockData);
+ }
+ }
+ else
+ {
+ for (i = 16; i--; blockData++, totalCoeff++, coeffMap++)
+ {
+ if (*totalCoeff)
+ {
+ if (h264bsdProcessBlock(*blockData, pMb->qpY, 0, *coeffMap) !=
+ HANTRO_OK)
+ return(HANTRO_NOK);
+ }
+ else
+ MARK_RESIDUAL_EMPTY(*blockData);
+ }
+ }
+
+ /* chroma DC processing. First chroma dc block is block with index 25 */
+ chromaQp =
+ h264bsdQpC[CLIP3(0, 51, (i32)pMb->qpY + pMb->chromaQpIndexOffset)];
+ if (pMb->totalCoeff[25] || pMb->totalCoeff[26])
+ h264bsdProcessChromaDc(residualLevel[25], chromaQp);
+ chromaDc = residualLevel[25];
+ for (i = 8; i--; blockData++, totalCoeff++, coeffMap++)
+ {
+ /* set dc coefficient of chroma block */
+ (*blockData)[0] = *chromaDc++;
+ if ((*blockData)[0] || *totalCoeff)
+ {
+ if (h264bsdProcessBlock(*blockData, chromaQp, 1,*coeffMap) !=
+ HANTRO_OK)
+ return(HANTRO_NOK);
+ }
+ else
+ MARK_RESIDUAL_EMPTY(*blockData);
+ }
+
+ return(HANTRO_OK);
+}
+#endif /* H264DEC_OMXDL */
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdSubMbPartMode
+
+ Functional description:
+ Returns the macroblock's sub-partition mode.
+
+------------------------------------------------------------------------------*/
+
+subMbPartMode_e h264bsdSubMbPartMode(subMbType_e subMbType)
+{
+
+/* Variables */
+
+
+/* Code */
+
+ ASSERT(subMbType < 4);
+
+ return((subMbPartMode_e)subMbType);
+
+}
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_macroblock_layer.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_macroblock_layer.h
new file mode 100755
index 0000000..32bc340
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_macroblock_layer.h
@@ -0,0 +1,212 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_MACROBLOCK_LAYER_H
+#define H264SWDEC_MACROBLOCK_LAYER_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_stream.h"
+#include "h264bsd_image.h"
+#include "h264bsd_dpb.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+/* Macro to determine if a mb is an intra mb */
+#define IS_INTRA_MB(a) ((a).mbType > 5)
+
+/* Macro to determine if a mb is an I_PCM mb */
+#define IS_I_PCM_MB(a) ((a).mbType == 31)
+
+typedef enum {
+ P_Skip = 0,
+ P_L0_16x16 = 1,
+ P_L0_L0_16x8 = 2,
+ P_L0_L0_8x16 = 3,
+ P_8x8 = 4,
+ P_8x8ref0 = 5,
+ I_4x4 = 6,
+ I_16x16_0_0_0 = 7,
+ I_16x16_1_0_0 = 8,
+ I_16x16_2_0_0 = 9,
+ I_16x16_3_0_0 = 10,
+ I_16x16_0_1_0 = 11,
+ I_16x16_1_1_0 = 12,
+ I_16x16_2_1_0 = 13,
+ I_16x16_3_1_0 = 14,
+ I_16x16_0_2_0 = 15,
+ I_16x16_1_2_0 = 16,
+ I_16x16_2_2_0 = 17,
+ I_16x16_3_2_0 = 18,
+ I_16x16_0_0_1 = 19,
+ I_16x16_1_0_1 = 20,
+ I_16x16_2_0_1 = 21,
+ I_16x16_3_0_1 = 22,
+ I_16x16_0_1_1 = 23,
+ I_16x16_1_1_1 = 24,
+ I_16x16_2_1_1 = 25,
+ I_16x16_3_1_1 = 26,
+ I_16x16_0_2_1 = 27,
+ I_16x16_1_2_1 = 28,
+ I_16x16_2_2_1 = 29,
+ I_16x16_3_2_1 = 30,
+ I_PCM = 31
+} mbType_e;
+
+typedef enum {
+ P_L0_8x8 = 0,
+ P_L0_8x4 = 1,
+ P_L0_4x8 = 2,
+ P_L0_4x4 = 3
+} subMbType_e;
+
+typedef enum {
+ MB_P_16x16 = 0,
+ MB_P_16x8,
+ MB_P_8x16,
+ MB_P_8x8
+} mbPartMode_e;
+
+typedef enum {
+ MB_SP_8x8 = 0,
+ MB_SP_8x4,
+ MB_SP_4x8,
+ MB_SP_4x4
+} subMbPartMode_e;
+
+typedef enum {
+ PRED_MODE_INTRA4x4 = 0,
+ PRED_MODE_INTRA16x16 ,
+ PRED_MODE_INTER
+} mbPartPredMode_e;
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+typedef struct
+{
+ /* MvPrediction16x16 assumes that MVs are 16bits */
+ i16 hor;
+ i16 ver;
+} mv_t;
+
+typedef struct
+{
+ u32 prevIntra4x4PredModeFlag[16];
+ u32 remIntra4x4PredMode[16];
+ u32 intraChromaPredMode;
+ u32 refIdxL0[4];
+ mv_t mvdL0[4];
+} mbPred_t;
+
+typedef struct
+{
+ subMbType_e subMbType[4];
+ u32 refIdxL0[4];
+ mv_t mvdL0[4][4];
+} subMbPred_t;
+
+typedef struct
+{
+#ifdef H264DEC_OMXDL
+ u8 posCoefBuf[27*16*3];
+ u8 totalCoeff[27];
+#else
+ i16 totalCoeff[27];
+#endif
+ i32 level[26][16];
+ u32 coeffMap[24];
+} residual_t;
+
+typedef struct
+{
+ mbType_e mbType;
+ u32 codedBlockPattern;
+ i32 mbQpDelta;
+ mbPred_t mbPred;
+ subMbPred_t subMbPred;
+ residual_t residual;
+} macroblockLayer_t;
+
+typedef struct mbStorage
+{
+ mbType_e mbType;
+ u32 sliceId;
+ u32 disableDeblockingFilterIdc;
+ i32 filterOffsetA;
+ i32 filterOffsetB;
+ u32 qpY;
+ i32 chromaQpIndexOffset;
+#ifdef H264DEC_OMXDL
+ u8 totalCoeff[27];
+#else
+ i16 totalCoeff[27];
+#endif
+ u8 intra4x4PredMode[16];
+ u32 refPic[4];
+ u8* refAddr[4];
+ mv_t mv[16];
+ u32 decoded;
+ struct mbStorage *mbA;
+ struct mbStorage *mbB;
+ struct mbStorage *mbC;
+ struct mbStorage *mbD;
+} mbStorage_t;
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeMacroblockLayer(strmData_t *pStrmData,
+ macroblockLayer_t *pMbLayer, mbStorage_t *pMb, u32 sliceType,
+ u32 numRefIdxActive);
+
+u32 h264bsdNumMbPart(mbType_e mbType);
+u32 h264bsdNumSubMbPart(subMbType_e subMbType);
+
+subMbPartMode_e h264bsdSubMbPartMode(subMbType_e subMbType);
+
+u32 h264bsdDecodeMacroblock(mbStorage_t *pMb, macroblockLayer_t *pMbLayer,
+ image_t *currImage, dpbStorage_t *dpb, i32 *qpY, u32 mbNum,
+ u32 constrainedIntraPredFlag, u8* data);
+
+u32 h264bsdPredModeIntra16x16(mbType_e mbType);
+
+mbPartPredMode_e h264bsdMbPartPredMode(mbType_e mbType);
+#ifdef H264DEC_NEON
+u32 h264bsdClearMbLayer(macroblockLayer_t *pMbLayer, u32 size);
+#endif
+
+#endif /* #ifdef H264SWDEC_MACROBLOCK_LAYER_H */
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_nal_unit.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_nal_unit.c
new file mode 100755
index 0000000..e44c43a
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_nal_unit.c
@@ -0,0 +1,117 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdDecodeNalUnit
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_nal_unit.h"
+#include "h264bsd_util.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+
+ Function name: h264bsdDecodeNalUnit
+
+ Functional description:
+ Decode NAL unit header information
+
+ Inputs:
+ pStrmData pointer to stream data structure
+
+ Outputs:
+ pNalUnit NAL unit header information is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK invalid NAL unit header information
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeNalUnit(strmData_t *pStrmData, nalUnit_t *pNalUnit)
+{
+
+/* Variables */
+
+ u32 tmp;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pNalUnit);
+ ASSERT(pStrmData->bitPosInWord == 0);
+
+ /* forbidden_zero_bit (not checked to be zero, errors ignored) */
+ tmp = h264bsdGetBits(pStrmData, 1);
+ /* Assuming that NAL unit starts from byte boundary > don't have to check
+ * following 7 bits for END_OF_STREAM */
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+
+ tmp = h264bsdGetBits(pStrmData, 2);
+ pNalUnit->nalRefIdc = tmp;
+
+ tmp = h264bsdGetBits(pStrmData, 5);
+ pNalUnit->nalUnitType = (nalUnitType_e)tmp;
+
+ /* data partitioning NAL units not supported */
+ if ( (tmp == 2) || (tmp == 3) || (tmp == 4) )
+ {
+ return(HANTRO_NOK);
+ }
+
+ /* nal_ref_idc shall not be zero for these nal_unit_types */
+ if ( ( (tmp == NAL_SEQ_PARAM_SET) || (tmp == NAL_PIC_PARAM_SET) ||
+ (tmp == NAL_CODED_SLICE_IDR) ) && (pNalUnit->nalRefIdc == 0) )
+ {
+ return(HANTRO_NOK);
+ }
+ /* nal_ref_idc shall be zero for these nal_unit_types */
+ else if ( ( (tmp == NAL_SEI) || (tmp == NAL_ACCESS_UNIT_DELIMITER) ||
+ (tmp == NAL_END_OF_SEQUENCE) || (tmp == NAL_END_OF_STREAM) ||
+ (tmp == NAL_FILLER_DATA) ) && (pNalUnit->nalRefIdc != 0) )
+ {
+ return(HANTRO_NOK);
+ }
+
+ return(HANTRO_OK);
+
+}
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_nal_unit.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_nal_unit.h
new file mode 100755
index 0000000..38957bf
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_nal_unit.h
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_NAL_UNIT_H
+#define H264SWDEC_NAL_UNIT_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_stream.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+/* macro to determine if NAL unit pointed by pNalUnit contains an IDR slice */
+#define IS_IDR_NAL_UNIT(pNalUnit) \
+ ((pNalUnit)->nalUnitType == NAL_CODED_SLICE_IDR)
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+typedef enum {
+ NAL_CODED_SLICE = 1,
+ NAL_CODED_SLICE_IDR = 5,
+ NAL_SEI = 6,
+ NAL_SEQ_PARAM_SET = 7,
+ NAL_PIC_PARAM_SET = 8,
+ NAL_ACCESS_UNIT_DELIMITER = 9,
+ NAL_END_OF_SEQUENCE = 10,
+ NAL_END_OF_STREAM = 11,
+ NAL_FILLER_DATA = 12,
+ NAL_MAX_TYPE_VALUE = 31
+} nalUnitType_e;
+
+typedef struct
+{
+ nalUnitType_e nalUnitType;
+ u32 nalRefIdc;
+} nalUnit_t;
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeNalUnit(strmData_t *pStrmData, nalUnit_t *pNalUnit);
+
+#endif /* #ifdef H264SWDEC_NAL_UNIT_H */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_neighbour.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_neighbour.c
new file mode 100755
index 0000000..ce5eeff
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_neighbour.c
@@ -0,0 +1,382 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdInitMbNeighbours
+ h264bsdGetNeighbourMb
+ h264bsdNeighbour4x4BlockA
+ h264bsdNeighbour4x4BlockB
+ h264bsdNeighbour4x4BlockC
+ h264bsdNeighbour4x4BlockD
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_neighbour.h"
+#include "h264bsd_util.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/* Following four tables indicate neighbours of each block of a macroblock.
+ * First 16 values are for luma blocks, next 4 values for Cb and last 4
+ * values for Cr. Elements of the table indicate to which macroblock the
+ * neighbour block belongs and the index of the neighbour block in question.
+ * Indexing of the blocks goes as follows
+ *
+ * Y Cb Cr
+ * 0 1 4 5 16 17 20 21
+ * 2 3 6 7 18 19 22 23
+ * 8 9 12 13
+ * 10 11 14 15
+ */
+
+/* left neighbour for each block */
+static const neighbour_t N_A_4x4B[24] = {
+ {MB_A,5}, {MB_CURR,0}, {MB_A,7}, {MB_CURR,2},
+ {MB_CURR,1}, {MB_CURR,4}, {MB_CURR,3}, {MB_CURR,6},
+ {MB_A,13}, {MB_CURR,8}, {MB_A,15}, {MB_CURR,10},
+ {MB_CURR,9}, {MB_CURR,12},{MB_CURR,11},{MB_CURR,14},
+ {MB_A,17}, {MB_CURR,16},{MB_A,19}, {MB_CURR,18},
+ {MB_A,21}, {MB_CURR,20},{MB_A,23}, {MB_CURR,22} };
+
+/* above neighbour for each block */
+static const neighbour_t N_B_4x4B[24] = {
+ {MB_B,10}, {MB_B,11}, {MB_CURR,0}, {MB_CURR,1},
+ {MB_B,14}, {MB_B,15}, {MB_CURR,4}, {MB_CURR,5},
+ {MB_CURR,2}, {MB_CURR,3}, {MB_CURR,8}, {MB_CURR,9},
+ {MB_CURR,6}, {MB_CURR,7}, {MB_CURR,12},{MB_CURR,13},
+ {MB_B,18}, {MB_B,19}, {MB_CURR,16},{MB_CURR,17},
+ {MB_B,22}, {MB_B,23}, {MB_CURR,20},{MB_CURR,21} };
+
+/* above-right neighbour for each block */
+static const neighbour_t N_C_4x4B[24] = {
+ {MB_B,11}, {MB_B,14}, {MB_CURR,1}, {MB_NA,4},
+ {MB_B,15}, {MB_C,10}, {MB_CURR,5}, {MB_NA,0},
+ {MB_CURR,3}, {MB_CURR,6}, {MB_CURR,9}, {MB_NA,12},
+ {MB_CURR,7}, {MB_NA,2}, {MB_CURR,13},{MB_NA,8},
+ {MB_B,19}, {MB_C,18}, {MB_CURR,17},{MB_NA,16},
+ {MB_B,23}, {MB_C,22}, {MB_CURR,21},{MB_NA,20} };
+
+/* above-left neighbour for each block */
+static const neighbour_t N_D_4x4B[24] = {
+ {MB_D,15}, {MB_B,10}, {MB_A,5}, {MB_CURR,0},
+ {MB_B,11}, {MB_B,14}, {MB_CURR,1}, {MB_CURR,4},
+ {MB_A,7}, {MB_CURR,2}, {MB_A,13}, {MB_CURR,8},
+ {MB_CURR,3}, {MB_CURR,6}, {MB_CURR,9}, {MB_CURR,12},
+ {MB_D,19}, {MB_B,18}, {MB_A,17}, {MB_CURR,16},
+ {MB_D,23}, {MB_B,22}, {MB_A,21}, {MB_CURR,20} };
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdInitMbNeighbours
+
+ Functional description:
+ Initialize macroblock neighbours. Function sets neighbour
+ macroblock pointers in macroblock structures to point to
+ macroblocks on the left, above, above-right and above-left.
+ Pointers are set NULL if the neighbour does not fit into the
+ picture.
+
+ Inputs:
+ picWidth width of the picture in macroblocks
+ picSizeInMbs no need to clarify
+
+ Outputs:
+ pMbStorage neighbour pointers of each mbStorage structure
+ stored here
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+void h264bsdInitMbNeighbours(mbStorage_t *pMbStorage, u32 picWidth,
+ u32 picSizeInMbs)
+{
+
+/* Variables */
+
+ u32 i, row, col;
+
+/* Code */
+
+ ASSERT(pMbStorage);
+ ASSERT(picWidth);
+ ASSERT(picWidth <= picSizeInMbs);
+ ASSERT(((picSizeInMbs / picWidth) * picWidth) == picSizeInMbs);
+
+ row = col = 0;
+
+ for (i = 0; i < picSizeInMbs; i++)
+ {
+
+ if (col)
+ pMbStorage[i].mbA = pMbStorage + i - 1;
+ else
+ pMbStorage[i].mbA = NULL;
+
+ if (row)
+ pMbStorage[i].mbB = pMbStorage + i - picWidth;
+ else
+ pMbStorage[i].mbB = NULL;
+
+ if (row && (col < picWidth - 1))
+ pMbStorage[i].mbC = pMbStorage + i - (picWidth - 1);
+ else
+ pMbStorage[i].mbC = NULL;
+
+ if (row && col)
+ pMbStorage[i].mbD = pMbStorage + i - (picWidth + 1);
+ else
+ pMbStorage[i].mbD = NULL;
+
+ col++;
+ if (col == picWidth)
+ {
+ col = 0;
+ row++;
+ }
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdGetNeighbourMb
+
+ Functional description:
+ Get pointer to neighbour macroblock.
+
+ Inputs:
+ pMb pointer to macroblock structure of the macroblock
+ whose neighbour is wanted
+ neighbour indicates which neighbour is wanted
+
+ Outputs:
+ none
+
+ Returns:
+ pointer to neighbour macroblock
+ NULL if not available
+
+------------------------------------------------------------------------------*/
+
+mbStorage_t* h264bsdGetNeighbourMb(mbStorage_t *pMb, neighbourMb_e neighbour)
+{
+
+/* Variables */
+
+
+/* Code */
+
+ ASSERT((neighbour <= MB_CURR) || (neighbour == MB_NA));
+
+ if (neighbour == MB_A)
+ return(pMb->mbA);
+ else if (neighbour == MB_B)
+ return(pMb->mbB);
+ else if (neighbour == MB_C)
+ return(pMb->mbC);
+ else if (neighbour == MB_D)
+ return(pMb->mbD);
+ else if (neighbour == MB_CURR)
+ return(pMb);
+ else
+ return(NULL);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdNeighbour4x4BlockA
+
+ Functional description:
+ Get left neighbour of the block. Function returns pointer to
+ the table defined in the beginning of the file.
+
+ Inputs:
+ blockIndex indicates the block whose neighbours are wanted
+
+ Outputs:
+
+ Returns:
+ pointer to neighbour structure
+
+------------------------------------------------------------------------------*/
+
+const neighbour_t* h264bsdNeighbour4x4BlockA(u32 blockIndex)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(blockIndex < 24);
+
+ return(N_A_4x4B+blockIndex);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdNeighbour4x4BlockB
+
+ Functional description:
+ Get above neighbour of the block. Function returns pointer to
+ the table defined in the beginning of the file.
+
+ Inputs:
+ blockIndex indicates the block whose neighbours are wanted
+
+ Outputs:
+
+ Returns:
+ pointer to neighbour structure
+
+------------------------------------------------------------------------------*/
+
+const neighbour_t* h264bsdNeighbour4x4BlockB(u32 blockIndex)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(blockIndex < 24);
+
+ return(N_B_4x4B+blockIndex);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdNeighbour4x4BlockC
+
+ Functional description:
+ Get above-right neighbour of the block. Function returns pointer
+ to the table defined in the beginning of the file.
+
+ Inputs:
+ blockIndex indicates the block whose neighbours are wanted
+
+ Outputs:
+
+ Returns:
+ pointer to neighbour structure
+
+------------------------------------------------------------------------------*/
+
+const neighbour_t* h264bsdNeighbour4x4BlockC(u32 blockIndex)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(blockIndex < 24);
+
+ return(N_C_4x4B+blockIndex);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdNeighbour4x4BlockD
+
+ Functional description:
+ Get above-left neighbour of the block. Function returns pointer to
+ the table defined in the beginning of the file.
+
+ Inputs:
+ blockIndex indicates the block whose neighbours are wanted
+
+ Outputs:
+
+ Returns:
+ pointer to neighbour structure
+
+------------------------------------------------------------------------------*/
+
+const neighbour_t* h264bsdNeighbour4x4BlockD(u32 blockIndex)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(blockIndex < 24);
+
+ return(N_D_4x4B+blockIndex);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdIsNeighbourAvailable
+
+ Functional description:
+ Check if neighbour macroblock is available. Neighbour macroblock
+ is considered available if it is within the picture and belongs
+ to the same slice as the current macroblock.
+
+ Inputs:
+ pMb pointer to the current macroblock
+ pNeighbour pointer to the neighbour macroblock
+
+ Outputs:
+ none
+
+ Returns:
+ TRUE neighbour is available
+ FALSE neighbour is not available
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdIsNeighbourAvailable(mbStorage_t *pMb, mbStorage_t *pNeighbour)
+{
+
+/* Variables */
+
+/* Code */
+
+ if ( (pNeighbour == NULL) || (pMb->sliceId != pNeighbour->sliceId) )
+ return(HANTRO_FALSE);
+ else
+ return(HANTRO_TRUE);
+
+}
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_neighbour.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_neighbour.h
new file mode 100755
index 0000000..fce0ad1
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_neighbour.h
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_NEIGHBOUR_H
+#define H264SWDEC_NEIGHBOUR_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_macroblock_layer.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+typedef enum {
+ MB_A = 0,
+ MB_B,
+ MB_C,
+ MB_D,
+ MB_CURR,
+ MB_NA = 0xFF
+} neighbourMb_e;
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+typedef struct
+{
+ neighbourMb_e mb;
+ u8 index;
+} neighbour_t;
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+void h264bsdInitMbNeighbours(mbStorage_t *pMbStorage, u32 picWidth,
+ u32 picSizeInMbs);
+
+mbStorage_t* h264bsdGetNeighbourMb(mbStorage_t *pMb, neighbourMb_e neighbour);
+
+u32 h264bsdIsNeighbourAvailable(mbStorage_t *pMb, mbStorage_t *pNeighbour);
+
+const neighbour_t* h264bsdNeighbour4x4BlockA(u32 blockIndex);
+const neighbour_t* h264bsdNeighbour4x4BlockB(u32 blockIndex);
+const neighbour_t* h264bsdNeighbour4x4BlockC(u32 blockIndex);
+const neighbour_t* h264bsdNeighbour4x4BlockD(u32 blockIndex);
+
+#endif /* #ifdef H264SWDEC_NEIGHBOUR_H */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_pic_order_cnt.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_pic_order_cnt.c
new file mode 100755
index 0000000..fb23352
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_pic_order_cnt.c
@@ -0,0 +1,347 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdDecodePicOrderCnt
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_util.h"
+#include "h264bsd_pic_order_cnt.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdDecodePicOrderCnt
+
+ Functional description:
+ Compute picture order count for a picture. Function implements
+ computation of all POC types (0, 1 and 2), type is obtained from
+ sps. See standard for description of the POC types and how POC is
+ computed for each type.
+
+ Function returns the minimum of top field and bottom field pic
+ order counts.
+
+ Inputs:
+ poc pointer to previous results
+ sps pointer to sequence parameter set
+ slicHeader pointer to current slice header, frame number and
+ other params needed for POC computation
+ pNalUnit pointer to current NAL unit structrue, function needs
+ to know if this is an IDR picture and also if this is
+ a reference picture
+
+ Outputs:
+ poc results stored here for computation of next POC
+
+ Returns:
+ picture order count
+
+------------------------------------------------------------------------------*/
+
+i32 h264bsdDecodePicOrderCnt(pocStorage_t *poc, seqParamSet_t *sps,
+ sliceHeader_t *pSliceHeader, nalUnit_t *pNalUnit)
+{
+
+/* Variables */
+
+ u32 i;
+ i32 picOrderCnt;
+ u32 frameNumOffset, absFrameNum, picOrderCntCycleCnt;
+ u32 frameNumInPicOrderCntCycle;
+ i32 expectedDeltaPicOrderCntCycle;
+ u32 containsMmco5;
+
+/* Code */
+
+ ASSERT(poc);
+ ASSERT(sps);
+ ASSERT(pSliceHeader);
+ ASSERT(pNalUnit);
+ ASSERT(sps->picOrderCntType <= 2);
+
+#if 0
+ /* JanSa: I don't think this is necessary, don't see any reason to
+ * increment prevFrameNum one by one instead of one big increment.
+ * However, standard specifies that this should be done -> if someone
+ * figures out any case when the outcome would be different for step by
+ * step increment, this part of the code should be enabled */
+
+ /* if there was a gap in frame numbering and picOrderCntType is 1 or 2 ->
+ * "compute" pic order counts for non-existing frames. These are not
+ * actually computed, but process needs to be done to update the
+ * prevFrameNum and prevFrameNumOffset */
+ if ( sps->picOrderCntType > 0 &&
+ pSliceHeader->frameNum != poc->prevFrameNum &&
+ pSliceHeader->frameNum != ((poc->prevFrameNum + 1) % sps->maxFrameNum))
+ {
+
+ /* use variable i for unUsedShortTermFrameNum */
+ i = (poc->prevFrameNum + 1) % sps->maxFrameNum;
+
+ do
+ {
+ if (poc->prevFrameNum > i)
+ frameNumOffset = poc->prevFrameNumOffset + sps->maxFrameNum;
+ else
+ frameNumOffset = poc->prevFrameNumOffset;
+
+ poc->prevFrameNumOffset = frameNumOffset;
+ poc->prevFrameNum = i;
+
+ i = (i + 1) % sps->maxFrameNum;
+
+ } while (i != pSliceHeader->frameNum);
+ }
+#endif
+
+ /* check if current slice includes mmco equal to 5 */
+ containsMmco5 = HANTRO_FALSE;
+ if (pSliceHeader->decRefPicMarking.adaptiveRefPicMarkingModeFlag)
+ {
+ i = 0;
+ while (pSliceHeader->decRefPicMarking.operation[i].
+ memoryManagementControlOperation)
+ {
+ if (pSliceHeader->decRefPicMarking.operation[i].
+ memoryManagementControlOperation == 5)
+ {
+ containsMmco5 = HANTRO_TRUE;
+ break;
+ }
+ i++;
+ }
+ }
+ switch (sps->picOrderCntType)
+ {
+
+ case 0:
+ /* set prevPicOrderCnt values for IDR frame */
+ if (IS_IDR_NAL_UNIT(pNalUnit))
+ {
+ poc->prevPicOrderCntMsb = 0;
+ poc->prevPicOrderCntLsb = 0;
+ }
+
+ /* compute picOrderCntMsb (stored in picOrderCnt variable) */
+ if ( (pSliceHeader->picOrderCntLsb < poc->prevPicOrderCntLsb) &&
+ ((poc->prevPicOrderCntLsb - pSliceHeader->picOrderCntLsb) >=
+ sps->maxPicOrderCntLsb/2) )
+ {
+ picOrderCnt = poc->prevPicOrderCntMsb +
+ (i32)sps->maxPicOrderCntLsb;
+ }
+ else if ((pSliceHeader->picOrderCntLsb > poc->prevPicOrderCntLsb) &&
+ ((pSliceHeader->picOrderCntLsb - poc->prevPicOrderCntLsb) >
+ sps->maxPicOrderCntLsb/2) )
+ {
+ picOrderCnt = poc->prevPicOrderCntMsb -
+ (i32)sps->maxPicOrderCntLsb;
+ }
+ else
+ picOrderCnt = poc->prevPicOrderCntMsb;
+
+ /* standard specifies that prevPicOrderCntMsb is from previous
+ * rererence frame -> replace old value only if current frame is
+ * rererence frame */
+ if (pNalUnit->nalRefIdc)
+ poc->prevPicOrderCntMsb = picOrderCnt;
+
+ /* compute top field order cnt (stored in picOrderCnt) */
+ picOrderCnt += (i32)pSliceHeader->picOrderCntLsb;
+
+ /* if delta for bottom field is negative -> bottom will be the
+ * minimum pic order count */
+ if (pSliceHeader->deltaPicOrderCntBottom < 0)
+ picOrderCnt += pSliceHeader->deltaPicOrderCntBottom;
+
+ /* standard specifies that prevPicOrderCntLsb is from previous
+ * rererence frame -> replace old value only if current frame is
+ * rererence frame */
+ if (pNalUnit->nalRefIdc)
+ {
+ /* if current frame contains mmco5 -> modify values to be
+ * stored */
+ if (containsMmco5)
+ {
+ poc->prevPicOrderCntMsb = 0;
+ /* prevPicOrderCntLsb should be the top field picOrderCnt
+ * if previous frame included mmco5. Top field picOrderCnt
+ * for frames containing mmco5 is obtained by subtracting
+ * the picOrderCnt from original top field order count ->
+ * value is zero if top field was the minimum, i.e. delta
+ * for bottom was positive, otherwise value is
+ * -deltaPicOrderCntBottom */
+ if (pSliceHeader->deltaPicOrderCntBottom < 0)
+ poc->prevPicOrderCntLsb =
+ (u32)(-pSliceHeader->deltaPicOrderCntBottom);
+ else
+ poc->prevPicOrderCntLsb = 0;
+ picOrderCnt = 0;
+ }
+ else
+ {
+ poc->prevPicOrderCntLsb = pSliceHeader->picOrderCntLsb;
+ }
+ }
+
+ break;
+
+ case 1:
+
+ /* step 1 (in the description in the standard) */
+ if (IS_IDR_NAL_UNIT(pNalUnit))
+ frameNumOffset = 0;
+ else if (poc->prevFrameNum > pSliceHeader->frameNum)
+ frameNumOffset = poc->prevFrameNumOffset + sps->maxFrameNum;
+ else
+ frameNumOffset = poc->prevFrameNumOffset;
+
+ /* step 2 */
+ if (sps->numRefFramesInPicOrderCntCycle)
+ absFrameNum = frameNumOffset + pSliceHeader->frameNum;
+ else
+ absFrameNum = 0;
+
+ if (pNalUnit->nalRefIdc == 0 && absFrameNum > 0)
+ absFrameNum -= 1;
+
+ /* step 3 */
+ if (absFrameNum > 0)
+ {
+ picOrderCntCycleCnt =
+ (absFrameNum - 1)/sps->numRefFramesInPicOrderCntCycle;
+ frameNumInPicOrderCntCycle =
+ (absFrameNum - 1)%sps->numRefFramesInPicOrderCntCycle;
+ }
+
+ /* step 4 */
+ expectedDeltaPicOrderCntCycle = 0;
+ for (i = 0; i < sps->numRefFramesInPicOrderCntCycle; i++)
+ expectedDeltaPicOrderCntCycle += sps->offsetForRefFrame[i];
+
+ /* step 5 (picOrderCnt used to store expectedPicOrderCnt) */
+ /*lint -esym(644,picOrderCntCycleCnt) always initialized */
+ /*lint -esym(644,frameNumInPicOrderCntCycle) always initialized */
+ if (absFrameNum > 0)
+ {
+ picOrderCnt =
+ (i32)picOrderCntCycleCnt * expectedDeltaPicOrderCntCycle;
+ for (i = 0; i <= frameNumInPicOrderCntCycle; i++)
+ picOrderCnt += sps->offsetForRefFrame[i];
+ }
+ else
+ picOrderCnt = 0;
+
+ if (pNalUnit->nalRefIdc == 0)
+ picOrderCnt += sps->offsetForNonRefPic;
+
+ /* step 6 (picOrderCnt is top field order cnt if delta for bottom
+ * is positive, otherwise it is bottom field order cnt) */
+ picOrderCnt += pSliceHeader->deltaPicOrderCnt[0];
+
+ if ( (sps->offsetForTopToBottomField +
+ pSliceHeader->deltaPicOrderCnt[1]) < 0 )
+ {
+ picOrderCnt += sps->offsetForTopToBottomField +
+ pSliceHeader->deltaPicOrderCnt[1];
+ }
+
+ /* if current picture contains mmco5 -> set prevFrameNumOffset and
+ * prevFrameNum to 0 for computation of picOrderCnt of next
+ * frame, otherwise store frameNum and frameNumOffset to poc
+ * structure */
+ if (!containsMmco5)
+ {
+ poc->prevFrameNumOffset = frameNumOffset;
+ poc->prevFrameNum = pSliceHeader->frameNum;
+ }
+ else
+ {
+ poc->prevFrameNumOffset = 0;
+ poc->prevFrameNum = 0;
+ picOrderCnt = 0;
+ }
+ break;
+
+ default: /* case 2 */
+ /* derive frameNumOffset */
+ if (IS_IDR_NAL_UNIT(pNalUnit))
+ frameNumOffset = 0;
+ else if (poc->prevFrameNum > pSliceHeader->frameNum)
+ frameNumOffset = poc->prevFrameNumOffset + sps->maxFrameNum;
+ else
+ frameNumOffset = poc->prevFrameNumOffset;
+
+ /* derive picOrderCnt (type 2 has same value for top and bottom
+ * field order cnts) */
+ if (IS_IDR_NAL_UNIT(pNalUnit))
+ picOrderCnt = 0;
+ else if (pNalUnit->nalRefIdc == 0)
+ picOrderCnt =
+ 2 * (i32)(frameNumOffset + pSliceHeader->frameNum) - 1;
+ else
+ picOrderCnt =
+ 2 * (i32)(frameNumOffset + pSliceHeader->frameNum);
+
+ /* if current picture contains mmco5 -> set prevFrameNumOffset and
+ * prevFrameNum to 0 for computation of picOrderCnt of next
+ * frame, otherwise store frameNum and frameNumOffset to poc
+ * structure */
+ if (!containsMmco5)
+ {
+ poc->prevFrameNumOffset = frameNumOffset;
+ poc->prevFrameNum = pSliceHeader->frameNum;
+ }
+ else
+ {
+ poc->prevFrameNumOffset = 0;
+ poc->prevFrameNum = 0;
+ picOrderCnt = 0;
+ }
+ break;
+
+ }
+
+ /*lint -esym(644,picOrderCnt) always initialized */
+ return(picOrderCnt);
+
+}
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_pic_order_cnt.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_pic_order_cnt.h
new file mode 100755
index 0000000..19741eb
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_pic_order_cnt.h
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_PIC_ORDER_CNT_H
+#define H264SWDEC_PIC_ORDER_CNT_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_seq_param_set.h"
+#include "h264bsd_slice_header.h"
+#include "h264bsd_nal_unit.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+/* structure to store information computed for previous picture, needed for
+ * POC computation of a picture. Two first fields for POC type 0, last two
+ * for types 1 and 2 */
+typedef struct
+{
+ u32 prevPicOrderCntLsb;
+ i32 prevPicOrderCntMsb;
+ u32 prevFrameNum;
+ u32 prevFrameNumOffset;
+} pocStorage_t;
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+i32 h264bsdDecodePicOrderCnt(pocStorage_t *poc, seqParamSet_t *sps,
+ sliceHeader_t *sliceHeader, nalUnit_t *pNalUnit);
+
+#endif /* #ifdef H264SWDEC_PIC_ORDER_CNT_H */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_pic_param_set.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_pic_param_set.c
new file mode 100755
index 0000000..e04dea4
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_pic_param_set.c
@@ -0,0 +1,335 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdDecodePicParamSet
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_pic_param_set.h"
+#include "h264bsd_util.h"
+#include "h264bsd_vlc.h"
+#include "h264bsd_cfg.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/* lookup table for ceil(log2(numSliceGroups)), i.e. number of bits needed to
+ * represent range [0, numSliceGroups)
+ *
+ * NOTE: if MAX_NUM_SLICE_GROUPS is higher than 8 this table has to be resized
+ * accordingly */
+static const u32 CeilLog2NumSliceGroups[8] = {1, 1, 2, 2, 3, 3, 3, 3};
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+
+ Function name: h264bsdDecodePicParamSet
+
+ Functional description:
+ Decode picture parameter set information from the stream.
+
+ Function allocates memory for
+ - run lengths if slice group map type is 0
+ - top-left and bottom-right arrays if map type is 2
+ - for slice group ids if map type is 6
+
+ Validity of some of the slice group mapping information depends
+ on the image dimensions which are not known here. Therefore the
+ validity has to be checked afterwards, currently in the parameter
+ set activation phase.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+
+ Outputs:
+ pPicParamSet decoded information is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK failure, invalid information or end of stream
+ MEMORY_ALLOCATION_ERROR for memory allocation failure
+
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodePicParamSet(strmData_t *pStrmData, picParamSet_t *pPicParamSet)
+{
+
+/* Variables */
+
+ u32 tmp, i, value;
+ i32 itmp;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pPicParamSet);
+
+
+ H264SwDecMemset(pPicParamSet, 0, sizeof(picParamSet_t));
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pPicParamSet->picParameterSetId);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pPicParamSet->picParameterSetId >= MAX_NUM_PIC_PARAM_SETS)
+ {
+ EPRINT("pic_parameter_set_id");
+ return(HANTRO_NOK);
+ }
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pPicParamSet->seqParameterSetId);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pPicParamSet->seqParameterSetId >= MAX_NUM_SEQ_PARAM_SETS)
+ {
+ EPRINT("seq_param_set_id");
+ return(HANTRO_NOK);
+ }
+
+ /* entropy_coding_mode_flag, shall be 0 for baseline profile */
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp)
+ {
+ EPRINT("entropy_coding_mode_flag");
+ return(HANTRO_NOK);
+ }
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pPicParamSet->picOrderPresentFlag = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
+
+ /* num_slice_groups_minus1 */
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pPicParamSet->numSliceGroups = value + 1;
+ if (pPicParamSet->numSliceGroups > MAX_NUM_SLICE_GROUPS)
+ {
+ EPRINT("num_slice_groups_minus1");
+ return(HANTRO_NOK);
+ }
+
+ /* decode slice group mapping information if more than one slice groups */
+ if (pPicParamSet->numSliceGroups > 1)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pPicParamSet->sliceGroupMapType);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pPicParamSet->sliceGroupMapType > 6)
+ {
+ EPRINT("slice_group_map_type");
+ return(HANTRO_NOK);
+ }
+
+ if (pPicParamSet->sliceGroupMapType == 0)
+ {
+ ALLOCATE(pPicParamSet->runLength,
+ pPicParamSet->numSliceGroups, u32);
+ if (pPicParamSet->runLength == NULL)
+ return(MEMORY_ALLOCATION_ERROR);
+ for (i = 0; i < pPicParamSet->numSliceGroups; i++)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pPicParamSet->runLength[i] = value+1;
+ /* param values checked in CheckPps() */
+ }
+ }
+ else if (pPicParamSet->sliceGroupMapType == 2)
+ {
+ ALLOCATE(pPicParamSet->topLeft,
+ pPicParamSet->numSliceGroups - 1, u32);
+ ALLOCATE(pPicParamSet->bottomRight,
+ pPicParamSet->numSliceGroups - 1, u32);
+ if (pPicParamSet->topLeft == NULL ||
+ pPicParamSet->bottomRight == NULL)
+ return(MEMORY_ALLOCATION_ERROR);
+ for (i = 0; i < pPicParamSet->numSliceGroups - 1; i++)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pPicParamSet->topLeft[i] = value;
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pPicParamSet->bottomRight[i] = value;
+ /* param values checked in CheckPps() */
+ }
+ }
+ else if ( (pPicParamSet->sliceGroupMapType == 3) ||
+ (pPicParamSet->sliceGroupMapType == 4) ||
+ (pPicParamSet->sliceGroupMapType == 5) )
+ {
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pPicParamSet->sliceGroupChangeDirectionFlag =
+ (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pPicParamSet->sliceGroupChangeRate = value + 1;
+ /* param value checked in CheckPps() */
+ }
+ else if (pPicParamSet->sliceGroupMapType == 6)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pPicParamSet->picSizeInMapUnits = value + 1;
+
+ ALLOCATE(pPicParamSet->sliceGroupId,
+ pPicParamSet->picSizeInMapUnits, u32);
+ if (pPicParamSet->sliceGroupId == NULL)
+ return(MEMORY_ALLOCATION_ERROR);
+
+ /* determine number of bits needed to represent range
+ * [0, numSliceGroups) */
+ tmp = CeilLog2NumSliceGroups[pPicParamSet->numSliceGroups-1];
+
+ for (i = 0; i < pPicParamSet->picSizeInMapUnits; i++)
+ {
+ pPicParamSet->sliceGroupId[i] = h264bsdGetBits(pStrmData, tmp);
+ if ( pPicParamSet->sliceGroupId[i] >=
+ pPicParamSet->numSliceGroups )
+ {
+ EPRINT("slice_group_id");
+ return(HANTRO_NOK);
+ }
+ }
+ }
+ }
+
+ /* num_ref_idx_l0_active_minus1 */
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (value > 31)
+ {
+ EPRINT("num_ref_idx_l0_active_minus1");
+ return(HANTRO_NOK);
+ }
+ pPicParamSet->numRefIdxL0Active = value + 1;
+
+ /* num_ref_idx_l1_active_minus1 */
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (value > 31)
+ {
+ EPRINT("num_ref_idx_l1_active_minus1");
+ return(HANTRO_NOK);
+ }
+
+ /* weighted_pred_flag, this shall be 0 for baseline profile */
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp)
+ {
+ EPRINT("weighted_pred_flag");
+ return(HANTRO_NOK);
+ }
+
+ /* weighted_bipred_idc */
+ tmp = h264bsdGetBits(pStrmData, 2);
+ if (tmp > 2)
+ {
+ EPRINT("weighted_bipred_idc");
+ return(HANTRO_NOK);
+ }
+
+ /* pic_init_qp_minus26 */
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if ((itmp < -26) || (itmp > 25))
+ {
+ EPRINT("pic_init_qp_minus26");
+ return(HANTRO_NOK);
+ }
+ pPicParamSet->picInitQp = (u32)(itmp + 26);
+
+ /* pic_init_qs_minus26 */
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if ((itmp < -26) || (itmp > 25))
+ {
+ EPRINT("pic_init_qs_minus26");
+ return(HANTRO_NOK);
+ }
+
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if ((itmp < -12) || (itmp > 12))
+ {
+ EPRINT("chroma_qp_index_offset");
+ return(HANTRO_NOK);
+ }
+ pPicParamSet->chromaQpIndexOffset = itmp;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pPicParamSet->deblockingFilterControlPresentFlag =
+ (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pPicParamSet->constrainedIntraPredFlag = (tmp == 1) ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pPicParamSet->redundantPicCntPresentFlag = (tmp == 1) ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdRbspTrailingBits(pStrmData);
+
+ /* ignore possible errors in trailing bits of parameters sets */
+ return(HANTRO_OK);
+
+}
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_pic_param_set.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_pic_param_set.h
new file mode 100755
index 0000000..6328638
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_pic_param_set.h
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_PIC_PARAM_SET_H
+#define H264SWDEC_PIC_PARAM_SET_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_stream.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+/* data structure to store PPS information decoded from the stream */
+typedef struct
+{
+ u32 picParameterSetId;
+ u32 seqParameterSetId;
+ u32 picOrderPresentFlag;
+ u32 numSliceGroups;
+ u32 sliceGroupMapType;
+ u32 *runLength;
+ u32 *topLeft;
+ u32 *bottomRight;
+ u32 sliceGroupChangeDirectionFlag;
+ u32 sliceGroupChangeRate;
+ u32 picSizeInMapUnits;
+ u32 *sliceGroupId;
+ u32 numRefIdxL0Active;
+ u32 picInitQp;
+ i32 chromaQpIndexOffset;
+ u32 deblockingFilterControlPresentFlag;
+ u32 constrainedIntraPredFlag;
+ u32 redundantPicCntPresentFlag;
+} picParamSet_t;
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodePicParamSet(strmData_t *pStrmData,
+ picParamSet_t *pPicParamSet);
+
+#endif /* #ifdef H264SWDEC_PIC_PARAM_SET_H */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_reconstruct.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_reconstruct.c
new file mode 100755
index 0000000..c948776
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_reconstruct.c
@@ -0,0 +1,2315 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_reconstruct.h"
+#include "h264bsd_macroblock_layer.h"
+#include "h264bsd_image.h"
+#include "h264bsd_util.h"
+
+#ifdef H264DEC_OMXDL
+#include "omxtypes.h"
+#include "omxVC.h"
+#include "armVC.h"
+#endif /* H264DEC_OMXDL */
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/* Switch off the following Lint messages for this file:
+ * Info 701: Shift left of signed quantity (int)
+ * Info 702: Shift right of signed quantity (int)
+ */
+/*lint -e701 -e702 */
+
+/* Luma fractional-sample positions
+ *
+ * G a b c H
+ * d e f g
+ * h i j k m
+ * n p q r
+ * M s N
+ *
+ * G, H, M and N are integer sample positions
+ * a-s are fractional samples that need to be interpolated.
+ */
+#ifndef H264DEC_OMXDL
+static const u32 lumaFracPos[4][4] = {
+ /* G d h n a e i p b f j q c g k r */
+ {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}, {12, 13, 14, 15}};
+#endif /* H264DEC_OMXDL */
+
+/* clipping table, defined in h264bsd_intra_prediction.c */
+extern const u8 h264bsdClip[];
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+#ifndef H264DEC_OMXDL
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdInterpolateChromaHor
+
+ Functional description:
+ This function performs chroma interpolation in horizontal direction.
+ Overfilling is done only if needed. Reference image (pRef) is
+ read at correct position and the predicted part is written to
+ macroblock's chrominance (predPartChroma)
+ Inputs:
+ pRef pointer to reference frame Cb top-left corner
+ x0 integer x-coordinate for prediction
+ y0 integer y-coordinate for prediction
+ width width of the reference frame chrominance in pixels
+ height height of the reference frame chrominance in pixels
+ xFrac horizontal fraction for prediction in 1/8 pixels
+ chromaPartWidth width of the predicted part in pixels
+ chromaPartHeight height of the predicted part in pixels
+ Outputs:
+ predPartChroma pointer where predicted part is written
+
+------------------------------------------------------------------------------*/
+#ifndef H264DEC_ARM11
+void h264bsdInterpolateChromaHor(
+ u8 *pRef,
+ u8 *predPartChroma,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 xFrac,
+ u32 chromaPartWidth,
+ u32 chromaPartHeight)
+{
+
+/* Variables */
+
+ u32 x, y, tmp1, tmp2, tmp3, tmp4, c, val;
+ u8 *ptrA, *cbr;
+ u32 comp;
+ u8 block[9*8*2];
+
+/* Code */
+
+ ASSERT(predPartChroma);
+ ASSERT(chromaPartWidth);
+ ASSERT(chromaPartHeight);
+ ASSERT(xFrac < 8);
+ ASSERT(pRef);
+
+ if ((x0 < 0) || ((u32)x0+chromaPartWidth+1 > width) ||
+ (y0 < 0) || ((u32)y0+chromaPartHeight > height))
+ {
+ h264bsdFillBlock(pRef, block, x0, y0, width, height,
+ chromaPartWidth + 1, chromaPartHeight, chromaPartWidth + 1);
+ pRef += width * height;
+ h264bsdFillBlock(pRef, block + (chromaPartWidth+1)*chromaPartHeight,
+ x0, y0, width, height, chromaPartWidth + 1,
+ chromaPartHeight, chromaPartWidth + 1);
+
+ pRef = block;
+ x0 = 0;
+ y0 = 0;
+ width = chromaPartWidth+1;
+ height = chromaPartHeight;
+ }
+
+ val = 8 - xFrac;
+
+ for (comp = 0; comp <= 1; comp++)
+ {
+
+ ptrA = pRef + (comp * height + (u32)y0) * width + x0;
+ cbr = predPartChroma + comp * 8 * 8;
+
+ /* 2x2 pels per iteration
+ * bilinear horizontal interpolation */
+ for (y = (chromaPartHeight >> 1); y; y--)
+ {
+ for (x = (chromaPartWidth >> 1); x; x--)
+ {
+ tmp1 = ptrA[width];
+ tmp2 = *ptrA++;
+ tmp3 = ptrA[width];
+ tmp4 = *ptrA++;
+ c = ((val * tmp1 + xFrac * tmp3) << 3) + 32;
+ c >>= 6;
+ cbr[8] = (u8)c;
+ c = ((val * tmp2 + xFrac * tmp4) << 3) + 32;
+ c >>= 6;
+ *cbr++ = (u8)c;
+ tmp1 = ptrA[width];
+ tmp2 = *ptrA;
+ c = ((val * tmp3 + xFrac * tmp1) << 3) + 32;
+ c >>= 6;
+ cbr[8] = (u8)c;
+ c = ((val * tmp4 + xFrac * tmp2) << 3) + 32;
+ c >>= 6;
+ *cbr++ = (u8)c;
+ }
+ cbr += 2*8 - chromaPartWidth;
+ ptrA += 2*width - chromaPartWidth;
+ }
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdInterpolateChromaVer
+
+ Functional description:
+ This function performs chroma interpolation in vertical direction.
+ Overfilling is done only if needed. Reference image (pRef) is
+ read at correct position and the predicted part is written to
+ macroblock's chrominance (predPartChroma)
+
+------------------------------------------------------------------------------*/
+
+void h264bsdInterpolateChromaVer(
+ u8 *pRef,
+ u8 *predPartChroma,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 yFrac,
+ u32 chromaPartWidth,
+ u32 chromaPartHeight)
+{
+
+/* Variables */
+
+ u32 x, y, tmp1, tmp2, tmp3, c, val;
+ u8 *ptrA, *cbr;
+ u32 comp;
+ u8 block[9*8*2];
+
+/* Code */
+
+ ASSERT(predPartChroma);
+ ASSERT(chromaPartWidth);
+ ASSERT(chromaPartHeight);
+ ASSERT(yFrac < 8);
+ ASSERT(pRef);
+
+ if ((x0 < 0) || ((u32)x0+chromaPartWidth > width) ||
+ (y0 < 0) || ((u32)y0+chromaPartHeight+1 > height))
+ {
+ h264bsdFillBlock(pRef, block, x0, y0, width, height, chromaPartWidth,
+ chromaPartHeight + 1, chromaPartWidth);
+ pRef += width * height;
+ h264bsdFillBlock(pRef, block + chromaPartWidth*(chromaPartHeight+1),
+ x0, y0, width, height, chromaPartWidth,
+ chromaPartHeight + 1, chromaPartWidth);
+
+ pRef = block;
+ x0 = 0;
+ y0 = 0;
+ width = chromaPartWidth;
+ height = chromaPartHeight+1;
+ }
+
+ val = 8 - yFrac;
+
+ for (comp = 0; comp <= 1; comp++)
+ {
+
+ ptrA = pRef + (comp * height + (u32)y0) * width + x0;
+ cbr = predPartChroma + comp * 8 * 8;
+
+ /* 2x2 pels per iteration
+ * bilinear vertical interpolation */
+ for (y = (chromaPartHeight >> 1); y; y--)
+ {
+ for (x = (chromaPartWidth >> 1); x; x--)
+ {
+ tmp3 = ptrA[width*2];
+ tmp2 = ptrA[width];
+ tmp1 = *ptrA++;
+ c = ((val * tmp2 + yFrac * tmp3) << 3) + 32;
+ c >>= 6;
+ cbr[8] = (u8)c;
+ c = ((val * tmp1 + yFrac * tmp2) << 3) + 32;
+ c >>= 6;
+ *cbr++ = (u8)c;
+ tmp3 = ptrA[width*2];
+ tmp2 = ptrA[width];
+ tmp1 = *ptrA++;
+ c = ((val * tmp2 + yFrac * tmp3) << 3) + 32;
+ c >>= 6;
+ cbr[8] = (u8)c;
+ c = ((val * tmp1 + yFrac * tmp2) << 3) + 32;
+ c >>= 6;
+ *cbr++ = (u8)c;
+ }
+ cbr += 2*8 - chromaPartWidth;
+ ptrA += 2*width - chromaPartWidth;
+ }
+ }
+
+}
+#endif
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdInterpolateChromaHorVer
+
+ Functional description:
+ This function performs chroma interpolation in horizontal and
+ vertical direction. Overfilling is done only if needed. Reference
+ image (ref) is read at correct position and the predicted part
+ is written to macroblock's chrominance (predPartChroma)
+
+------------------------------------------------------------------------------*/
+
+void h264bsdInterpolateChromaHorVer(
+ u8 *ref,
+ u8 *predPartChroma,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 xFrac,
+ u32 yFrac,
+ u32 chromaPartWidth,
+ u32 chromaPartHeight)
+{
+ u8 block[9*9*2];
+ u32 x, y, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, valX, valY, plus32 = 32;
+ u32 comp;
+ u8 *ptrA, *cbr;
+
+/* Code */
+
+ ASSERT(predPartChroma);
+ ASSERT(chromaPartWidth);
+ ASSERT(chromaPartHeight);
+ ASSERT(xFrac < 8);
+ ASSERT(yFrac < 8);
+ ASSERT(ref);
+
+ if ((x0 < 0) || ((u32)x0+chromaPartWidth+1 > width) ||
+ (y0 < 0) || ((u32)y0+chromaPartHeight+1 > height))
+ {
+ h264bsdFillBlock(ref, block, x0, y0, width, height,
+ chromaPartWidth + 1, chromaPartHeight + 1, chromaPartWidth + 1);
+ ref += width * height;
+ h264bsdFillBlock(ref, block + (chromaPartWidth+1)*(chromaPartHeight+1),
+ x0, y0, width, height, chromaPartWidth + 1,
+ chromaPartHeight + 1, chromaPartWidth + 1);
+
+ ref = block;
+ x0 = 0;
+ y0 = 0;
+ width = chromaPartWidth+1;
+ height = chromaPartHeight+1;
+ }
+
+ valX = 8 - xFrac;
+ valY = 8 - yFrac;
+
+ for (comp = 0; comp <= 1; comp++)
+ {
+
+ ptrA = ref + (comp * height + (u32)y0) * width + x0;
+ cbr = predPartChroma + comp * 8 * 8;
+
+ /* 2x2 pels per iteration
+ * bilinear vertical and horizontal interpolation */
+ for (y = (chromaPartHeight >> 1); y; y--)
+ {
+ tmp1 = *ptrA;
+ tmp3 = ptrA[width];
+ tmp5 = ptrA[width*2];
+ tmp1 *= valY;
+ tmp1 += tmp3 * yFrac;
+ tmp3 *= valY;
+ tmp3 += tmp5 * yFrac;
+ for (x = (chromaPartWidth >> 1); x; x--)
+ {
+ tmp2 = *++ptrA;
+ tmp4 = ptrA[width];
+ tmp6 = ptrA[width*2];
+ tmp2 *= valY;
+ tmp2 += tmp4 * yFrac;
+ tmp4 *= valY;
+ tmp4 += tmp6 * yFrac;
+ tmp1 = tmp1 * valX + plus32;
+ tmp3 = tmp3 * valX + plus32;
+ tmp1 += tmp2 * xFrac;
+ tmp1 >>= 6;
+ tmp3 += tmp4 * xFrac;
+ tmp3 >>= 6;
+ cbr[8] = (u8)tmp3;
+ *cbr++ = (u8)tmp1;
+
+ tmp1 = *++ptrA;
+ tmp3 = ptrA[width];
+ tmp5 = ptrA[width*2];
+ tmp1 *= valY;
+ tmp1 += tmp3 * yFrac;
+ tmp3 *= valY;
+ tmp3 += tmp5 * yFrac;
+ tmp2 = tmp2 * valX + plus32;
+ tmp4 = tmp4 * valX + plus32;
+ tmp2 += tmp1 * xFrac;
+ tmp2 >>= 6;
+ tmp4 += tmp3 * xFrac;
+ tmp4 >>= 6;
+ cbr[8] = (u8)tmp4;
+ *cbr++ = (u8)tmp2;
+ }
+ cbr += 2*8 - chromaPartWidth;
+ ptrA += 2*width - chromaPartWidth;
+ }
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: PredictChroma
+
+ Functional description:
+ Top level chroma prediction function that calls the appropriate
+ interpolation function. The output is written to macroblock array.
+
+------------------------------------------------------------------------------*/
+
+static void PredictChroma(
+ u8 *mbPartChroma,
+ u32 xAL,
+ u32 yAL,
+ u32 partWidth,
+ u32 partHeight,
+ mv_t *mv,
+ image_t *refPic)
+{
+
+/* Variables */
+
+ u32 xFrac, yFrac, width, height, chromaPartWidth, chromaPartHeight;
+ i32 xInt, yInt;
+ u8 *ref;
+
+/* Code */
+
+ ASSERT(mv);
+ ASSERT(refPic);
+ ASSERT(refPic->data);
+ ASSERT(refPic->width);
+ ASSERT(refPic->height);
+
+ width = 8 * refPic->width;
+ height = 8 * refPic->height;
+
+ xInt = (xAL >> 1) + (mv->hor >> 3);
+ yInt = (yAL >> 1) + (mv->ver >> 3);
+ xFrac = mv->hor & 0x7;
+ yFrac = mv->ver & 0x7;
+
+ chromaPartWidth = partWidth >> 1;
+ chromaPartHeight = partHeight >> 1;
+ ref = refPic->data + 256 * refPic->width * refPic->height;
+
+ if (xFrac && yFrac)
+ {
+ h264bsdInterpolateChromaHorVer(ref, mbPartChroma, xInt, yInt, width,
+ height, xFrac, yFrac, chromaPartWidth, chromaPartHeight);
+ }
+ else if (xFrac)
+ {
+ h264bsdInterpolateChromaHor(ref, mbPartChroma, xInt, yInt, width,
+ height, xFrac, chromaPartWidth, chromaPartHeight);
+ }
+ else if (yFrac)
+ {
+ h264bsdInterpolateChromaVer(ref, mbPartChroma, xInt, yInt, width,
+ height, yFrac, chromaPartWidth, chromaPartHeight);
+ }
+ else
+ {
+ h264bsdFillBlock(ref, mbPartChroma, xInt, yInt, width, height,
+ chromaPartWidth, chromaPartHeight, 8);
+ ref += width * height;
+ h264bsdFillBlock(ref, mbPartChroma + 8*8, xInt, yInt, width, height,
+ chromaPartWidth, chromaPartHeight, 8);
+ }
+
+}
+
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdInterpolateVerHalf
+
+ Functional description:
+ Function to perform vertical interpolation of pixel position 'h'
+ for a block. Overfilling is done only if needed. Reference
+ image (ref) is read at correct position and the predicted part
+ is written to macroblock array (mb)
+
+------------------------------------------------------------------------------*/
+#ifndef H264DEC_ARM11
+void h264bsdInterpolateVerHalf(
+ u8 *ref,
+ u8 *mb,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 partWidth,
+ u32 partHeight)
+{
+ u32 p1[21*21/4+1];
+ u32 i, j;
+ i32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+ u8 *ptrC, *ptrV;
+ const u8 *clp = h264bsdClip + 512;
+
+ /* Code */
+
+ ASSERT(ref);
+ ASSERT(mb);
+
+ if ((x0 < 0) || ((u32)x0+partWidth > width) ||
+ (y0 < 0) || ((u32)y0+partHeight+5 > height))
+ {
+ h264bsdFillBlock(ref, (u8*)p1, x0, y0, width, height,
+ partWidth, partHeight+5, partWidth);
+
+ x0 = 0;
+ y0 = 0;
+ ref = (u8*)p1;
+ width = partWidth;
+ }
+
+ ref += (u32)y0 * width + (u32)x0;
+
+ ptrC = ref + width;
+ ptrV = ptrC + 5*width;
+
+ /* 4 pixels per iteration, interpolate using 5 vertical samples */
+ for (i = (partHeight >> 2); i; i--)
+ {
+ /* h1 = (16 + A + 16(G+M) + 4(G+M) - 4(C+R) - (C+R) + T) >> 5 */
+ for (j = partWidth; j; j--)
+ {
+ tmp4 = ptrV[-(i32)width*2];
+ tmp5 = ptrV[-(i32)width];
+ tmp1 = ptrV[width];
+ tmp2 = ptrV[width*2];
+ tmp6 = *ptrV++;
+
+ tmp7 = tmp4 + tmp1;
+ tmp2 -= (tmp7 << 2);
+ tmp2 -= tmp7;
+ tmp2 += 16;
+ tmp7 = tmp5 + tmp6;
+ tmp3 = ptrC[width*2];
+ tmp2 += (tmp7 << 4);
+ tmp2 += (tmp7 << 2);
+ tmp2 += tmp3;
+ tmp2 = clp[tmp2>>5];
+ tmp1 += 16;
+ mb[48] = (u8)tmp2;
+
+ tmp7 = tmp3 + tmp6;
+ tmp1 -= (tmp7 << 2);
+ tmp1 -= tmp7;
+ tmp7 = tmp4 + tmp5;
+ tmp2 = ptrC[width];
+ tmp1 += (tmp7 << 4);
+ tmp1 += (tmp7 << 2);
+ tmp1 += tmp2;
+ tmp1 = clp[tmp1>>5];
+ tmp6 += 16;
+ mb[32] = (u8)tmp1;
+
+ tmp7 = tmp2 + tmp5;
+ tmp6 -= (tmp7 << 2);
+ tmp6 -= tmp7;
+ tmp7 = tmp4 + tmp3;
+ tmp1 = *ptrC;
+ tmp6 += (tmp7 << 4);
+ tmp6 += (tmp7 << 2);
+ tmp6 += tmp1;
+ tmp6 = clp[tmp6>>5];
+ tmp5 += 16;
+ mb[16] = (u8)tmp6;
+
+ tmp1 += tmp4;
+ tmp5 -= (tmp1 << 2);
+ tmp5 -= tmp1;
+ tmp3 += tmp2;
+ tmp6 = ptrC[-(i32)width];
+ tmp5 += (tmp3 << 4);
+ tmp5 += (tmp3 << 2);
+ tmp5 += tmp6;
+ tmp5 = clp[tmp5>>5];
+ *mb++ = (u8)tmp5;
+ ptrC++;
+ }
+ ptrC += 4*width - partWidth;
+ ptrV += 4*width - partWidth;
+ mb += 4*16 - partWidth;
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdInterpolateVerQuarter
+
+ Functional description:
+ Function to perform vertical interpolation of pixel position 'd'
+ or 'n' for a block. Overfilling is done only if needed. Reference
+ image (ref) is read at correct position and the predicted part
+ is written to macroblock array (mb)
+
+------------------------------------------------------------------------------*/
+
+void h264bsdInterpolateVerQuarter(
+ u8 *ref,
+ u8 *mb,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 partWidth,
+ u32 partHeight,
+ u32 verOffset) /* 0 for pixel d, 1 for pixel n */
+{
+ u32 p1[21*21/4+1];
+ u32 i, j;
+ i32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+ u8 *ptrC, *ptrV, *ptrInt;
+ const u8 *clp = h264bsdClip + 512;
+
+ /* Code */
+
+ ASSERT(ref);
+ ASSERT(mb);
+
+ if ((x0 < 0) || ((u32)x0+partWidth > width) ||
+ (y0 < 0) || ((u32)y0+partHeight+5 > height))
+ {
+ h264bsdFillBlock(ref, (u8*)p1, x0, y0, width, height,
+ partWidth, partHeight+5, partWidth);
+
+ x0 = 0;
+ y0 = 0;
+ ref = (u8*)p1;
+ width = partWidth;
+ }
+
+ ref += (u32)y0 * width + (u32)x0;
+
+ ptrC = ref + width;
+ ptrV = ptrC + 5*width;
+
+ /* Pointer to integer sample position, either M or R */
+ ptrInt = ptrC + (2+verOffset)*width;
+
+ /* 4 pixels per iteration
+ * interpolate using 5 vertical samples and average between
+ * interpolated value and integer sample value */
+ for (i = (partHeight >> 2); i; i--)
+ {
+ /* h1 = (16 + A + 16(G+M) + 4(G+M) - 4(C+R) - (C+R) + T) >> 5 */
+ for (j = partWidth; j; j--)
+ {
+ tmp4 = ptrV[-(i32)width*2];
+ tmp5 = ptrV[-(i32)width];
+ tmp1 = ptrV[width];
+ tmp2 = ptrV[width*2];
+ tmp6 = *ptrV++;
+
+ tmp7 = tmp4 + tmp1;
+ tmp2 -= (tmp7 << 2);
+ tmp2 -= tmp7;
+ tmp2 += 16;
+ tmp7 = tmp5 + tmp6;
+ tmp3 = ptrC[width*2];
+ tmp2 += (tmp7 << 4);
+ tmp2 += (tmp7 << 2);
+ tmp2 += tmp3;
+ tmp2 = clp[tmp2>>5];
+ tmp7 = ptrInt[width*2];
+ tmp1 += 16;
+ tmp2++;
+ mb[48] = (u8)((tmp2 + tmp7) >> 1);
+
+ tmp7 = tmp3 + tmp6;
+ tmp1 -= (tmp7 << 2);
+ tmp1 -= tmp7;
+ tmp7 = tmp4 + tmp5;
+ tmp2 = ptrC[width];
+ tmp1 += (tmp7 << 4);
+ tmp1 += (tmp7 << 2);
+ tmp1 += tmp2;
+ tmp1 = clp[tmp1>>5];
+ tmp7 = ptrInt[width];
+ tmp6 += 16;
+ tmp1++;
+ mb[32] = (u8)((tmp1 + tmp7) >> 1);
+
+ tmp7 = tmp2 + tmp5;
+ tmp6 -= (tmp7 << 2);
+ tmp6 -= tmp7;
+ tmp7 = tmp4 + tmp3;
+ tmp1 = *ptrC;
+ tmp6 += (tmp7 << 4);
+ tmp6 += (tmp7 << 2);
+ tmp6 += tmp1;
+ tmp6 = clp[tmp6>>5];
+ tmp7 = *ptrInt;
+ tmp5 += 16;
+ tmp6++;
+ mb[16] = (u8)((tmp6 + tmp7) >> 1);
+
+ tmp1 += tmp4;
+ tmp5 -= (tmp1 << 2);
+ tmp5 -= tmp1;
+ tmp3 += tmp2;
+ tmp6 = ptrC[-(i32)width];
+ tmp5 += (tmp3 << 4);
+ tmp5 += (tmp3 << 2);
+ tmp5 += tmp6;
+ tmp5 = clp[tmp5>>5];
+ tmp7 = ptrInt[-(i32)width];
+ tmp5++;
+ *mb++ = (u8)((tmp5 + tmp7) >> 1);
+ ptrC++;
+ ptrInt++;
+ }
+ ptrC += 4*width - partWidth;
+ ptrV += 4*width - partWidth;
+ ptrInt += 4*width - partWidth;
+ mb += 4*16 - partWidth;
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdInterpolateHorHalf
+
+ Functional description:
+ Function to perform horizontal interpolation of pixel position 'b'
+ for a block. Overfilling is done only if needed. Reference
+ image (ref) is read at correct position and the predicted part
+ is written to macroblock array (mb)
+
+------------------------------------------------------------------------------*/
+
+void h264bsdInterpolateHorHalf(
+ u8 *ref,
+ u8 *mb,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 partWidth,
+ u32 partHeight)
+{
+ u32 p1[21*21/4+1];
+ u8 *ptrJ;
+ u32 x, y;
+ i32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+ const u8 *clp = h264bsdClip + 512;
+
+ /* Code */
+
+ ASSERT(ref);
+ ASSERT(mb);
+ ASSERT((partWidth&0x3) == 0);
+ ASSERT((partHeight&0x3) == 0);
+
+ if ((x0 < 0) || ((u32)x0+partWidth+5 > width) ||
+ (y0 < 0) || ((u32)y0+partHeight > height))
+ {
+ h264bsdFillBlock(ref, (u8*)p1, x0, y0, width, height,
+ partWidth+5, partHeight, partWidth+5);
+
+ x0 = 0;
+ y0 = 0;
+ ref = (u8*)p1;
+ width = partWidth + 5;
+ }
+
+ ref += (u32)y0 * width + (u32)x0;
+
+ ptrJ = ref + 5;
+
+ for (y = partHeight; y; y--)
+ {
+ tmp6 = *(ptrJ - 5);
+ tmp5 = *(ptrJ - 4);
+ tmp4 = *(ptrJ - 3);
+ tmp3 = *(ptrJ - 2);
+ tmp2 = *(ptrJ - 1);
+
+ /* calculate 4 pels per iteration */
+ for (x = (partWidth >> 2); x; x--)
+ {
+ /* First pixel */
+ tmp6 += 16;
+ tmp7 = tmp3 + tmp4;
+ tmp6 += (tmp7 << 4);
+ tmp6 += (tmp7 << 2);
+ tmp7 = tmp2 + tmp5;
+ tmp1 = *ptrJ++;
+ tmp6 -= (tmp7 << 2);
+ tmp6 -= tmp7;
+ tmp6 += tmp1;
+ tmp6 = clp[tmp6>>5];
+ /* Second pixel */
+ tmp5 += 16;
+ tmp7 = tmp2 + tmp3;
+ *mb++ = (u8)tmp6;
+ tmp5 += (tmp7 << 4);
+ tmp5 += (tmp7 << 2);
+ tmp7 = tmp1 + tmp4;
+ tmp6 = *ptrJ++;
+ tmp5 -= (tmp7 << 2);
+ tmp5 -= tmp7;
+ tmp5 += tmp6;
+ tmp5 = clp[tmp5>>5];
+ /* Third pixel */
+ tmp4 += 16;
+ tmp7 = tmp1 + tmp2;
+ *mb++ = (u8)tmp5;
+ tmp4 += (tmp7 << 4);
+ tmp4 += (tmp7 << 2);
+ tmp7 = tmp6 + tmp3;
+ tmp5 = *ptrJ++;
+ tmp4 -= (tmp7 << 2);
+ tmp4 -= tmp7;
+ tmp4 += tmp5;
+ tmp4 = clp[tmp4>>5];
+ /* Fourth pixel */
+ tmp3 += 16;
+ tmp7 = tmp6 + tmp1;
+ *mb++ = (u8)tmp4;
+ tmp3 += (tmp7 << 4);
+ tmp3 += (tmp7 << 2);
+ tmp7 = tmp5 + tmp2;
+ tmp4 = *ptrJ++;
+ tmp3 -= (tmp7 << 2);
+ tmp3 -= tmp7;
+ tmp3 += tmp4;
+ tmp3 = clp[tmp3>>5];
+ tmp7 = tmp4;
+ tmp4 = tmp6;
+ tmp6 = tmp2;
+ tmp2 = tmp7;
+ *mb++ = (u8)tmp3;
+ tmp3 = tmp5;
+ tmp5 = tmp1;
+ }
+ ptrJ += width - partWidth;
+ mb += 16 - partWidth;
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdInterpolateHorQuarter
+
+ Functional description:
+ Function to perform horizontal interpolation of pixel position 'a'
+ or 'c' for a block. Overfilling is done only if needed. Reference
+ image (ref) is read at correct position and the predicted part
+ is written to macroblock array (mb)
+
+------------------------------------------------------------------------------*/
+
+void h264bsdInterpolateHorQuarter(
+ u8 *ref,
+ u8 *mb,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 partWidth,
+ u32 partHeight,
+ u32 horOffset) /* 0 for pixel a, 1 for pixel c */
+{
+ u32 p1[21*21/4+1];
+ u8 *ptrJ;
+ u32 x, y;
+ i32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+ const u8 *clp = h264bsdClip + 512;
+
+ /* Code */
+
+ ASSERT(ref);
+ ASSERT(mb);
+
+ if ((x0 < 0) || ((u32)x0+partWidth+5 > width) ||
+ (y0 < 0) || ((u32)y0+partHeight > height))
+ {
+ h264bsdFillBlock(ref, (u8*)p1, x0, y0, width, height,
+ partWidth+5, partHeight, partWidth+5);
+
+ x0 = 0;
+ y0 = 0;
+ ref = (u8*)p1;
+ width = partWidth + 5;
+ }
+
+ ref += (u32)y0 * width + (u32)x0;
+
+ ptrJ = ref + 5;
+
+ for (y = partHeight; y; y--)
+ {
+ tmp6 = *(ptrJ - 5);
+ tmp5 = *(ptrJ - 4);
+ tmp4 = *(ptrJ - 3);
+ tmp3 = *(ptrJ - 2);
+ tmp2 = *(ptrJ - 1);
+
+ /* calculate 4 pels per iteration */
+ for (x = (partWidth >> 2); x; x--)
+ {
+ /* First pixel */
+ tmp6 += 16;
+ tmp7 = tmp3 + tmp4;
+ tmp6 += (tmp7 << 4);
+ tmp6 += (tmp7 << 2);
+ tmp7 = tmp2 + tmp5;
+ tmp1 = *ptrJ++;
+ tmp6 -= (tmp7 << 2);
+ tmp6 -= tmp7;
+ tmp6 += tmp1;
+ tmp6 = clp[tmp6>>5];
+ tmp5 += 16;
+ if (!horOffset)
+ tmp6 += tmp4;
+ else
+ tmp6 += tmp3;
+ *mb++ = (u8)((tmp6 + 1) >> 1);
+ /* Second pixel */
+ tmp7 = tmp2 + tmp3;
+ tmp5 += (tmp7 << 4);
+ tmp5 += (tmp7 << 2);
+ tmp7 = tmp1 + tmp4;
+ tmp6 = *ptrJ++;
+ tmp5 -= (tmp7 << 2);
+ tmp5 -= tmp7;
+ tmp5 += tmp6;
+ tmp5 = clp[tmp5>>5];
+ tmp4 += 16;
+ if (!horOffset)
+ tmp5 += tmp3;
+ else
+ tmp5 += tmp2;
+ *mb++ = (u8)((tmp5 + 1) >> 1);
+ /* Third pixel */
+ tmp7 = tmp1 + tmp2;
+ tmp4 += (tmp7 << 4);
+ tmp4 += (tmp7 << 2);
+ tmp7 = tmp6 + tmp3;
+ tmp5 = *ptrJ++;
+ tmp4 -= (tmp7 << 2);
+ tmp4 -= tmp7;
+ tmp4 += tmp5;
+ tmp4 = clp[tmp4>>5];
+ tmp3 += 16;
+ if (!horOffset)
+ tmp4 += tmp2;
+ else
+ tmp4 += tmp1;
+ *mb++ = (u8)((tmp4 + 1) >> 1);
+ /* Fourth pixel */
+ tmp7 = tmp6 + tmp1;
+ tmp3 += (tmp7 << 4);
+ tmp3 += (tmp7 << 2);
+ tmp7 = tmp5 + tmp2;
+ tmp4 = *ptrJ++;
+ tmp3 -= (tmp7 << 2);
+ tmp3 -= tmp7;
+ tmp3 += tmp4;
+ tmp3 = clp[tmp3>>5];
+ if (!horOffset)
+ tmp3 += tmp1;
+ else
+ tmp3 += tmp6;
+ *mb++ = (u8)((tmp3 + 1) >> 1);
+ tmp3 = tmp5;
+ tmp5 = tmp1;
+ tmp7 = tmp4;
+ tmp4 = tmp6;
+ tmp6 = tmp2;
+ tmp2 = tmp7;
+ }
+ ptrJ += width - partWidth;
+ mb += 16 - partWidth;
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdInterpolateHorVerQuarter
+
+ Functional description:
+ Function to perform horizontal and vertical interpolation of pixel
+ position 'e', 'g', 'p' or 'r' for a block. Overfilling is done only
+ if needed. Reference image (ref) is read at correct position and
+ the predicted part is written to macroblock array (mb)
+
+------------------------------------------------------------------------------*/
+
+void h264bsdInterpolateHorVerQuarter(
+ u8 *ref,
+ u8 *mb,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 partWidth,
+ u32 partHeight,
+ u32 horVerOffset) /* 0 for pixel e, 1 for pixel g,
+ 2 for pixel p, 3 for pixel r */
+{
+ u32 p1[21*21/4+1];
+ u8 *ptrC, *ptrJ, *ptrV;
+ u32 x, y;
+ i32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+ const u8 *clp = h264bsdClip + 512;
+
+ /* Code */
+
+ ASSERT(ref);
+ ASSERT(mb);
+
+ if ((x0 < 0) || ((u32)x0+partWidth+5 > width) ||
+ (y0 < 0) || ((u32)y0+partHeight+5 > height))
+ {
+ h264bsdFillBlock(ref, (u8*)p1, x0, y0, width, height,
+ partWidth+5, partHeight+5, partWidth+5);
+
+ x0 = 0;
+ y0 = 0;
+ ref = (u8*)p1;
+ width = partWidth+5;
+ }
+
+ /* Ref points to G + (-2, -2) */
+ ref += (u32)y0 * width + (u32)x0;
+
+ /* ptrJ points to either J or Q, depending on vertical offset */
+ ptrJ = ref + (((horVerOffset & 0x2) >> 1) + 2) * width + 5;
+
+ /* ptrC points to either C or D, depending on horizontal offset */
+ ptrC = ref + width + 2 + (horVerOffset & 0x1);
+
+ for (y = partHeight; y; y--)
+ {
+ tmp6 = *(ptrJ - 5);
+ tmp5 = *(ptrJ - 4);
+ tmp4 = *(ptrJ - 3);
+ tmp3 = *(ptrJ - 2);
+ tmp2 = *(ptrJ - 1);
+
+ /* Horizontal interpolation, calculate 4 pels per iteration */
+ for (x = (partWidth >> 2); x; x--)
+ {
+ /* First pixel */
+ tmp6 += 16;
+ tmp7 = tmp3 + tmp4;
+ tmp6 += (tmp7 << 4);
+ tmp6 += (tmp7 << 2);
+ tmp7 = tmp2 + tmp5;
+ tmp1 = *ptrJ++;
+ tmp6 -= (tmp7 << 2);
+ tmp6 -= tmp7;
+ tmp6 += tmp1;
+ tmp6 = clp[tmp6>>5];
+ /* Second pixel */
+ tmp5 += 16;
+ tmp7 = tmp2 + tmp3;
+ *mb++ = (u8)tmp6;
+ tmp5 += (tmp7 << 4);
+ tmp5 += (tmp7 << 2);
+ tmp7 = tmp1 + tmp4;
+ tmp6 = *ptrJ++;
+ tmp5 -= (tmp7 << 2);
+ tmp5 -= tmp7;
+ tmp5 += tmp6;
+ tmp5 = clp[tmp5>>5];
+ /* Third pixel */
+ tmp4 += 16;
+ tmp7 = tmp1 + tmp2;
+ *mb++ = (u8)tmp5;
+ tmp4 += (tmp7 << 4);
+ tmp4 += (tmp7 << 2);
+ tmp7 = tmp6 + tmp3;
+ tmp5 = *ptrJ++;
+ tmp4 -= (tmp7 << 2);
+ tmp4 -= tmp7;
+ tmp4 += tmp5;
+ tmp4 = clp[tmp4>>5];
+ /* Fourth pixel */
+ tmp3 += 16;
+ tmp7 = tmp6 + tmp1;
+ *mb++ = (u8)tmp4;
+ tmp3 += (tmp7 << 4);
+ tmp3 += (tmp7 << 2);
+ tmp7 = tmp5 + tmp2;
+ tmp4 = *ptrJ++;
+ tmp3 -= (tmp7 << 2);
+ tmp3 -= tmp7;
+ tmp3 += tmp4;
+ tmp3 = clp[tmp3>>5];
+ tmp7 = tmp4;
+ tmp4 = tmp6;
+ tmp6 = tmp2;
+ tmp2 = tmp7;
+ *mb++ = (u8)tmp3;
+ tmp3 = tmp5;
+ tmp5 = tmp1;
+ }
+ ptrJ += width - partWidth;
+ mb += 16 - partWidth;
+ }
+
+ mb -= 16*partHeight;
+ ptrV = ptrC + 5*width;
+
+ for (y = (partHeight >> 2); y; y--)
+ {
+ /* Vertical interpolation and averaging, 4 pels per iteration */
+ for (x = partWidth; x; x--)
+ {
+ tmp4 = ptrV[-(i32)width*2];
+ tmp5 = ptrV[-(i32)width];
+ tmp1 = ptrV[width];
+ tmp2 = ptrV[width*2];
+ tmp6 = *ptrV++;
+
+ tmp7 = tmp4 + tmp1;
+ tmp2 -= (tmp7 << 2);
+ tmp2 -= tmp7;
+ tmp2 += 16;
+ tmp7 = tmp5 + tmp6;
+ tmp3 = ptrC[width*2];
+ tmp2 += (tmp7 << 4);
+ tmp2 += (tmp7 << 2);
+ tmp2 += tmp3;
+ tmp7 = clp[tmp2>>5];
+ tmp2 = mb[48];
+ tmp1 += 16;
+ tmp7++;
+ mb[48] = (u8)((tmp2 + tmp7) >> 1);
+
+ tmp7 = tmp3 + tmp6;
+ tmp1 -= (tmp7 << 2);
+ tmp1 -= tmp7;
+ tmp7 = tmp4 + tmp5;
+ tmp2 = ptrC[width];
+ tmp1 += (tmp7 << 4);
+ tmp1 += (tmp7 << 2);
+ tmp1 += tmp2;
+ tmp7 = clp[tmp1>>5];
+ tmp1 = mb[32];
+ tmp6 += 16;
+ tmp7++;
+ mb[32] = (u8)((tmp1 + tmp7) >> 1);
+
+ tmp1 = *ptrC;
+ tmp7 = tmp2 + tmp5;
+ tmp6 -= (tmp7 << 2);
+ tmp6 -= tmp7;
+ tmp7 = tmp4 + tmp3;
+ tmp6 += (tmp7 << 4);
+ tmp6 += (tmp7 << 2);
+ tmp6 += tmp1;
+ tmp7 = clp[tmp6>>5];
+ tmp6 = mb[16];
+ tmp5 += 16;
+ tmp7++;
+ mb[16] = (u8)((tmp6 + tmp7) >> 1);
+
+ tmp6 = ptrC[-(i32)width];
+ tmp1 += tmp4;
+ tmp5 -= (tmp1 << 2);
+ tmp5 -= tmp1;
+ tmp3 += tmp2;
+ tmp5 += (tmp3 << 4);
+ tmp5 += (tmp3 << 2);
+ tmp5 += tmp6;
+ tmp7 = clp[tmp5>>5];
+ tmp5 = *mb;
+ tmp7++;
+ *mb++ = (u8)((tmp5 + tmp7) >> 1);
+ ptrC++;
+
+ }
+ ptrC += 4*width - partWidth;
+ ptrV += 4*width - partWidth;
+ mb += 4*16 - partWidth;
+ }
+
+}
+#endif
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdInterpolateMidHalf
+
+ Functional description:
+ Function to perform horizontal and vertical interpolation of pixel
+ position 'j' for a block. Overfilling is done only if needed.
+ Reference image (ref) is read at correct position and the predicted
+ part is written to macroblock array (mb)
+
+------------------------------------------------------------------------------*/
+
+void h264bsdInterpolateMidHalf(
+ u8 *ref,
+ u8 *mb,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 partWidth,
+ u32 partHeight)
+{
+ u32 p1[21*21/4+1];
+ u32 x, y;
+ i32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+ i32 *ptrC, *ptrV, *b1;
+ u8 *ptrJ;
+ i32 table[21*16];
+ const u8 *clp = h264bsdClip + 512;
+
+ /* Code */
+
+ ASSERT(ref);
+ ASSERT(mb);
+
+ if ((x0 < 0) || ((u32)x0+partWidth+5 > width) ||
+ (y0 < 0) || ((u32)y0+partHeight+5 > height))
+ {
+ h264bsdFillBlock(ref, (u8*)p1, x0, y0, width, height,
+ partWidth+5, partHeight+5, partWidth+5);
+
+ x0 = 0;
+ y0 = 0;
+ ref = (u8*)p1;
+ width = partWidth+5;
+ }
+
+ ref += (u32)y0 * width + (u32)x0;
+
+ b1 = table;
+ ptrJ = ref + 5;
+
+ /* First step: calculate intermediate values for
+ * horizontal interpolation */
+ for (y = partHeight + 5; y; y--)
+ {
+ tmp6 = *(ptrJ - 5);
+ tmp5 = *(ptrJ - 4);
+ tmp4 = *(ptrJ - 3);
+ tmp3 = *(ptrJ - 2);
+ tmp2 = *(ptrJ - 1);
+
+ /* 4 pels per iteration */
+ for (x = (partWidth >> 2); x; x--)
+ {
+ /* First pixel */
+ tmp7 = tmp3 + tmp4;
+ tmp6 += (tmp7 << 4);
+ tmp6 += (tmp7 << 2);
+ tmp7 = tmp2 + tmp5;
+ tmp1 = *ptrJ++;
+ tmp6 -= (tmp7 << 2);
+ tmp6 -= tmp7;
+ tmp6 += tmp1;
+ *b1++ = tmp6;
+ /* Second pixel */
+ tmp7 = tmp2 + tmp3;
+ tmp5 += (tmp7 << 4);
+ tmp5 += (tmp7 << 2);
+ tmp7 = tmp1 + tmp4;
+ tmp6 = *ptrJ++;
+ tmp5 -= (tmp7 << 2);
+ tmp5 -= tmp7;
+ tmp5 += tmp6;
+ *b1++ = tmp5;
+ /* Third pixel */
+ tmp7 = tmp1 + tmp2;
+ tmp4 += (tmp7 << 4);
+ tmp4 += (tmp7 << 2);
+ tmp7 = tmp6 + tmp3;
+ tmp5 = *ptrJ++;
+ tmp4 -= (tmp7 << 2);
+ tmp4 -= tmp7;
+ tmp4 += tmp5;
+ *b1++ = tmp4;
+ /* Fourth pixel */
+ tmp7 = tmp6 + tmp1;
+ tmp3 += (tmp7 << 4);
+ tmp3 += (tmp7 << 2);
+ tmp7 = tmp5 + tmp2;
+ tmp4 = *ptrJ++;
+ tmp3 -= (tmp7 << 2);
+ tmp3 -= tmp7;
+ tmp3 += tmp4;
+ *b1++ = tmp3;
+ tmp7 = tmp4;
+ tmp4 = tmp6;
+ tmp6 = tmp2;
+ tmp2 = tmp7;
+ tmp3 = tmp5;
+ tmp5 = tmp1;
+ }
+ ptrJ += width - partWidth;
+ }
+
+ /* Second step: calculate vertical interpolation */
+ ptrC = table + partWidth;
+ ptrV = ptrC + 5*partWidth;
+ for (y = (partHeight >> 2); y; y--)
+ {
+ /* 4 pels per iteration */
+ for (x = partWidth; x; x--)
+ {
+ tmp4 = ptrV[-(i32)partWidth*2];
+ tmp5 = ptrV[-(i32)partWidth];
+ tmp1 = ptrV[partWidth];
+ tmp2 = ptrV[partWidth*2];
+ tmp6 = *ptrV++;
+
+ tmp7 = tmp4 + tmp1;
+ tmp2 -= (tmp7 << 2);
+ tmp2 -= tmp7;
+ tmp2 += 512;
+ tmp7 = tmp5 + tmp6;
+ tmp3 = ptrC[partWidth*2];
+ tmp2 += (tmp7 << 4);
+ tmp2 += (tmp7 << 2);
+ tmp2 += tmp3;
+ tmp7 = clp[tmp2>>10];
+ tmp1 += 512;
+ mb[48] = (u8)tmp7;
+
+ tmp7 = tmp3 + tmp6;
+ tmp1 -= (tmp7 << 2);
+ tmp1 -= tmp7;
+ tmp7 = tmp4 + tmp5;
+ tmp2 = ptrC[partWidth];
+ tmp1 += (tmp7 << 4);
+ tmp1 += (tmp7 << 2);
+ tmp1 += tmp2;
+ tmp7 = clp[tmp1>>10];
+ tmp6 += 512;
+ mb[32] = (u8)tmp7;
+
+ tmp1 = *ptrC;
+ tmp7 = tmp2 + tmp5;
+ tmp6 -= (tmp7 << 2);
+ tmp6 -= tmp7;
+ tmp7 = tmp4 + tmp3;
+ tmp6 += (tmp7 << 4);
+ tmp6 += (tmp7 << 2);
+ tmp6 += tmp1;
+ tmp7 = clp[tmp6>>10];
+ tmp5 += 512;
+ mb[16] = (u8)tmp7;
+
+ tmp6 = ptrC[-(i32)partWidth];
+ tmp1 += tmp4;
+ tmp5 -= (tmp1 << 2);
+ tmp5 -= tmp1;
+ tmp3 += tmp2;
+ tmp5 += (tmp3 << 4);
+ tmp5 += (tmp3 << 2);
+ tmp5 += tmp6;
+ tmp7 = clp[tmp5>>10];
+ *mb++ = (u8)tmp7;
+ ptrC++;
+ }
+ mb += 4*16 - partWidth;
+ ptrC += 3*partWidth;
+ ptrV += 3*partWidth;
+ }
+
+}
+
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdInterpolateMidVerQuarter
+
+ Functional description:
+ Function to perform horizontal and vertical interpolation of pixel
+ position 'f' or 'q' for a block. Overfilling is done only if needed.
+ Reference image (ref) is read at correct position and the predicted
+ part is written to macroblock array (mb)
+
+------------------------------------------------------------------------------*/
+
+void h264bsdInterpolateMidVerQuarter(
+ u8 *ref,
+ u8 *mb,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 partWidth,
+ u32 partHeight,
+ u32 verOffset) /* 0 for pixel f, 1 for pixel q */
+{
+ u32 p1[21*21/4+1];
+ u32 x, y;
+ i32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+ i32 *ptrC, *ptrV, *ptrInt, *b1;
+ u8 *ptrJ;
+ i32 table[21*16];
+ const u8 *clp = h264bsdClip + 512;
+
+ /* Code */
+
+ ASSERT(ref);
+ ASSERT(mb);
+
+ if ((x0 < 0) || ((u32)x0+partWidth+5 > width) ||
+ (y0 < 0) || ((u32)y0+partHeight+5 > height))
+ {
+ h264bsdFillBlock(ref, (u8*)p1, x0, y0, width, height,
+ partWidth+5, partHeight+5, partWidth+5);
+
+ x0 = 0;
+ y0 = 0;
+ ref = (u8*)p1;
+ width = partWidth+5;
+ }
+
+ ref += (u32)y0 * width + (u32)x0;
+
+ b1 = table;
+ ptrJ = ref + 5;
+
+ /* First step: calculate intermediate values for
+ * horizontal interpolation */
+ for (y = partHeight + 5; y; y--)
+ {
+ tmp6 = *(ptrJ - 5);
+ tmp5 = *(ptrJ - 4);
+ tmp4 = *(ptrJ - 3);
+ tmp3 = *(ptrJ - 2);
+ tmp2 = *(ptrJ - 1);
+ for (x = (partWidth >> 2); x; x--)
+ {
+ /* First pixel */
+ tmp7 = tmp3 + tmp4;
+ tmp6 += (tmp7 << 4);
+ tmp6 += (tmp7 << 2);
+ tmp7 = tmp2 + tmp5;
+ tmp1 = *ptrJ++;
+ tmp6 -= (tmp7 << 2);
+ tmp6 -= tmp7;
+ tmp6 += tmp1;
+ *b1++ = tmp6;
+ /* Second pixel */
+ tmp7 = tmp2 + tmp3;
+ tmp5 += (tmp7 << 4);
+ tmp5 += (tmp7 << 2);
+ tmp7 = tmp1 + tmp4;
+ tmp6 = *ptrJ++;
+ tmp5 -= (tmp7 << 2);
+ tmp5 -= tmp7;
+ tmp5 += tmp6;
+ *b1++ = tmp5;
+ /* Third pixel */
+ tmp7 = tmp1 + tmp2;
+ tmp4 += (tmp7 << 4);
+ tmp4 += (tmp7 << 2);
+ tmp7 = tmp6 + tmp3;
+ tmp5 = *ptrJ++;
+ tmp4 -= (tmp7 << 2);
+ tmp4 -= tmp7;
+ tmp4 += tmp5;
+ *b1++ = tmp4;
+ /* Fourth pixel */
+ tmp7 = tmp6 + tmp1;
+ tmp3 += (tmp7 << 4);
+ tmp3 += (tmp7 << 2);
+ tmp7 = tmp5 + tmp2;
+ tmp4 = *ptrJ++;
+ tmp3 -= (tmp7 << 2);
+ tmp3 -= tmp7;
+ tmp3 += tmp4;
+ *b1++ = tmp3;
+ tmp7 = tmp4;
+ tmp4 = tmp6;
+ tmp6 = tmp2;
+ tmp2 = tmp7;
+ tmp3 = tmp5;
+ tmp5 = tmp1;
+ }
+ ptrJ += width - partWidth;
+ }
+
+ /* Second step: calculate vertical interpolation and average */
+ ptrC = table + partWidth;
+ ptrV = ptrC + 5*partWidth;
+ /* Pointer to integer sample position, either M or R */
+ ptrInt = ptrC + (2+verOffset)*partWidth;
+ for (y = (partHeight >> 2); y; y--)
+ {
+ for (x = partWidth; x; x--)
+ {
+ tmp4 = ptrV[-(i32)partWidth*2];
+ tmp5 = ptrV[-(i32)partWidth];
+ tmp1 = ptrV[partWidth];
+ tmp2 = ptrV[partWidth*2];
+ tmp6 = *ptrV++;
+
+ tmp7 = tmp4 + tmp1;
+ tmp2 -= (tmp7 << 2);
+ tmp2 -= tmp7;
+ tmp2 += 512;
+ tmp7 = tmp5 + tmp6;
+ tmp3 = ptrC[partWidth*2];
+ tmp2 += (tmp7 << 4);
+ tmp2 += (tmp7 << 2);
+ tmp7 = ptrInt[partWidth*2];
+ tmp2 += tmp3;
+ tmp2 = clp[tmp2>>10];
+ tmp7 += 16;
+ tmp7 = clp[tmp7>>5];
+ tmp1 += 512;
+ tmp2++;
+ mb[48] = (u8)((tmp7 + tmp2) >> 1);
+
+ tmp7 = tmp3 + tmp6;
+ tmp1 -= (tmp7 << 2);
+ tmp1 -= tmp7;
+ tmp7 = tmp4 + tmp5;
+ tmp2 = ptrC[partWidth];
+ tmp1 += (tmp7 << 4);
+ tmp1 += (tmp7 << 2);
+ tmp7 = ptrInt[partWidth];
+ tmp1 += tmp2;
+ tmp1 = clp[tmp1>>10];
+ tmp7 += 16;
+ tmp7 = clp[tmp7>>5];
+ tmp6 += 512;
+ tmp1++;
+ mb[32] = (u8)((tmp7 + tmp1) >> 1);
+
+ tmp1 = *ptrC;
+ tmp7 = tmp2 + tmp5;
+ tmp6 -= (tmp7 << 2);
+ tmp6 -= tmp7;
+ tmp7 = tmp4 + tmp3;
+ tmp6 += (tmp7 << 4);
+ tmp6 += (tmp7 << 2);
+ tmp7 = *ptrInt;
+ tmp6 += tmp1;
+ tmp6 = clp[tmp6>>10];
+ tmp7 += 16;
+ tmp7 = clp[tmp7>>5];
+ tmp5 += 512;
+ tmp6++;
+ mb[16] = (u8)((tmp7 + tmp6) >> 1);
+
+ tmp6 = ptrC[-(i32)partWidth];
+ tmp1 += tmp4;
+ tmp5 -= (tmp1 << 2);
+ tmp5 -= tmp1;
+ tmp3 += tmp2;
+ tmp5 += (tmp3 << 4);
+ tmp5 += (tmp3 << 2);
+ tmp7 = ptrInt[-(i32)partWidth];
+ tmp5 += tmp6;
+ tmp5 = clp[tmp5>>10];
+ tmp7 += 16;
+ tmp7 = clp[tmp7>>5];
+ tmp5++;
+ *mb++ = (u8)((tmp7 + tmp5) >> 1);
+ ptrC++;
+ ptrInt++;
+ }
+ mb += 4*16 - partWidth;
+ ptrC += 3*partWidth;
+ ptrV += 3*partWidth;
+ ptrInt += 3*partWidth;
+ }
+
+}
+
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdInterpolateMidHorQuarter
+
+ Functional description:
+ Function to perform horizontal and vertical interpolation of pixel
+ position 'i' or 'k' for a block. Overfilling is done only if needed.
+ Reference image (ref) is read at correct position and the predicted
+ part is written to macroblock array (mb)
+
+------------------------------------------------------------------------------*/
+
+void h264bsdInterpolateMidHorQuarter(
+ u8 *ref,
+ u8 *mb,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 partWidth,
+ u32 partHeight,
+ u32 horOffset) /* 0 for pixel i, 1 for pixel k */
+{
+ u32 p1[21*21/4+1];
+ u32 x, y;
+ i32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+ i32 *ptrJ, *ptrInt, *h1;
+ u8 *ptrC, *ptrV;
+ i32 table[21*16];
+ i32 tableWidth = (i32)partWidth+5;
+ const u8 *clp = h264bsdClip + 512;
+
+ /* Code */
+
+ ASSERT(ref);
+ ASSERT(mb);
+
+ if ((x0 < 0) || ((u32)x0+partWidth+5 > width) ||
+ (y0 < 0) || ((u32)y0+partHeight+5 > height))
+ {
+ h264bsdFillBlock(ref, (u8*)p1, x0, y0, width, height,
+ partWidth+5, partHeight+5, partWidth+5);
+
+ x0 = 0;
+ y0 = 0;
+ ref = (u8*)p1;
+ width = partWidth+5;
+ }
+
+ ref += (u32)y0 * width + (u32)x0;
+
+ h1 = table + tableWidth;
+ ptrC = ref + width;
+ ptrV = ptrC + 5*width;
+
+ /* First step: calculate intermediate values for
+ * vertical interpolation */
+ for (y = (partHeight >> 2); y; y--)
+ {
+ for (x = (u32)tableWidth; x; x--)
+ {
+ tmp4 = ptrV[-(i32)width*2];
+ tmp5 = ptrV[-(i32)width];
+ tmp1 = ptrV[width];
+ tmp2 = ptrV[width*2];
+ tmp6 = *ptrV++;
+
+ tmp7 = tmp4 + tmp1;
+ tmp2 -= (tmp7 << 2);
+ tmp2 -= tmp7;
+ tmp7 = tmp5 + tmp6;
+ tmp3 = ptrC[width*2];
+ tmp2 += (tmp7 << 4);
+ tmp2 += (tmp7 << 2);
+ tmp2 += tmp3;
+ h1[tableWidth*2] = tmp2;
+
+ tmp7 = tmp3 + tmp6;
+ tmp1 -= (tmp7 << 2);
+ tmp1 -= tmp7;
+ tmp7 = tmp4 + tmp5;
+ tmp2 = ptrC[width];
+ tmp1 += (tmp7 << 4);
+ tmp1 += (tmp7 << 2);
+ tmp1 += tmp2;
+ h1[tableWidth] = tmp1;
+
+ tmp1 = *ptrC;
+ tmp7 = tmp2 + tmp5;
+ tmp6 -= (tmp7 << 2);
+ tmp6 -= tmp7;
+ tmp7 = tmp4 + tmp3;
+ tmp6 += (tmp7 << 4);
+ tmp6 += (tmp7 << 2);
+ tmp6 += tmp1;
+ *h1 = tmp6;
+
+ tmp6 = ptrC[-(i32)width];
+ tmp1 += tmp4;
+ tmp5 -= (tmp1 << 2);
+ tmp5 -= tmp1;
+ tmp3 += tmp2;
+ tmp5 += (tmp3 << 4);
+ tmp5 += (tmp3 << 2);
+ tmp5 += tmp6;
+ h1[-tableWidth] = tmp5;
+ h1++;
+ ptrC++;
+ }
+ ptrC += 4*width - partWidth - 5;
+ ptrV += 4*width - partWidth - 5;
+ h1 += 3*tableWidth;
+ }
+
+ /* Second step: calculate horizontal interpolation and average */
+ ptrJ = table + 5;
+ /* Pointer to integer sample position, either G or H */
+ ptrInt = table + 2 + horOffset;
+ for (y = partHeight; y; y--)
+ {
+ tmp6 = *(ptrJ - 5);
+ tmp5 = *(ptrJ - 4);
+ tmp4 = *(ptrJ - 3);
+ tmp3 = *(ptrJ - 2);
+ tmp2 = *(ptrJ - 1);
+ for (x = (partWidth>>2); x; x--)
+ {
+ /* First pixel */
+ tmp6 += 512;
+ tmp7 = tmp3 + tmp4;
+ tmp6 += (tmp7 << 4);
+ tmp6 += (tmp7 << 2);
+ tmp7 = tmp2 + tmp5;
+ tmp1 = *ptrJ++;
+ tmp6 -= (tmp7 << 2);
+ tmp6 -= tmp7;
+ tmp7 = *ptrInt++;
+ tmp6 += tmp1;
+ tmp6 = clp[tmp6 >> 10];
+ tmp7 += 16;
+ tmp7 = clp[tmp7 >> 5];
+ tmp5 += 512;
+ tmp6++;
+ *mb++ = (u8)((tmp6 + tmp7) >> 1);
+ /* Second pixel */
+ tmp7 = tmp2 + tmp3;
+ tmp5 += (tmp7 << 4);
+ tmp5 += (tmp7 << 2);
+ tmp7 = tmp1 + tmp4;
+ tmp6 = *ptrJ++;
+ tmp5 -= (tmp7 << 2);
+ tmp5 -= tmp7;
+ tmp7 = *ptrInt++;
+ tmp5 += tmp6;
+ tmp5 = clp[tmp5 >> 10];
+ tmp7 += 16;
+ tmp7 = clp[tmp7 >> 5];
+ tmp4 += 512;
+ tmp5++;
+ *mb++ = (u8)((tmp5 + tmp7) >> 1);
+ /* Third pixel */
+ tmp7 = tmp1 + tmp2;
+ tmp4 += (tmp7 << 4);
+ tmp4 += (tmp7 << 2);
+ tmp7 = tmp6 + tmp3;
+ tmp5 = *ptrJ++;
+ tmp4 -= (tmp7 << 2);
+ tmp4 -= tmp7;
+ tmp7 = *ptrInt++;
+ tmp4 += tmp5;
+ tmp4 = clp[tmp4 >> 10];
+ tmp7 += 16;
+ tmp7 = clp[tmp7 >> 5];
+ tmp3 += 512;
+ tmp4++;
+ *mb++ = (u8)((tmp4 + tmp7) >> 1);
+ /* Fourth pixel */
+ tmp7 = tmp6 + tmp1;
+ tmp3 += (tmp7 << 4);
+ tmp3 += (tmp7 << 2);
+ tmp7 = tmp5 + tmp2;
+ tmp4 = *ptrJ++;
+ tmp3 -= (tmp7 << 2);
+ tmp3 -= tmp7;
+ tmp7 = *ptrInt++;
+ tmp3 += tmp4;
+ tmp3 = clp[tmp3 >> 10];
+ tmp7 += 16;
+ tmp7 = clp[tmp7 >> 5];
+ tmp3++;
+ *mb++ = (u8)((tmp3 + tmp7) >> 1);
+ tmp3 = tmp5;
+ tmp5 = tmp1;
+ tmp7 = tmp4;
+ tmp4 = tmp6;
+ tmp6 = tmp2;
+ tmp2 = tmp7;
+ }
+ ptrJ += 5;
+ ptrInt += 5;
+ mb += 16 - partWidth;
+ }
+
+}
+
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdPredictSamples
+
+ Functional description:
+ This function reconstructs a prediction for a macroblock partition.
+ The prediction is either copied or interpolated using the reference
+ frame and the motion vector. Both luminance and chrominance parts are
+ predicted. The prediction is stored in given macroblock array (data).
+ Inputs:
+ data pointer to macroblock array (384 bytes) for output
+ mv pointer to motion vector used for prediction
+ refPic pointer to reference picture structure
+ xA x-coordinate for current macroblock
+ yA y-coordinate for current macroblock
+ partX x-offset for partition in macroblock
+ partY y-offset for partition in macroblock
+ partWidth width of partition
+ partHeight height of partition
+ Outputs:
+ data macroblock array (16x16+8x8+8x8) where predicted
+ partition is stored at correct position
+
+------------------------------------------------------------------------------*/
+
+void h264bsdPredictSamples(
+ u8 *data,
+ mv_t *mv,
+ image_t *refPic,
+ u32 xA,
+ u32 yA,
+ u32 partX,
+ u32 partY,
+ u32 partWidth,
+ u32 partHeight)
+
+{
+
+/* Variables */
+
+ u32 xFrac, yFrac, width, height;
+ i32 xInt, yInt;
+ u8 *lumaPartData;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(mv);
+ ASSERT(partWidth);
+ ASSERT(partHeight);
+ ASSERT(refPic);
+ ASSERT(refPic->data);
+ ASSERT(refPic->width);
+ ASSERT(refPic->height);
+
+ /* luma */
+ lumaPartData = data + 16*partY + partX;
+
+ xFrac = mv->hor & 0x3;
+ yFrac = mv->ver & 0x3;
+
+ width = 16 * refPic->width;
+ height = 16 * refPic->height;
+
+ xInt = (i32)xA + (i32)partX + (mv->hor >> 2);
+ yInt = (i32)yA + (i32)partY + (mv->ver >> 2);
+
+ ASSERT(lumaFracPos[xFrac][yFrac] < 16);
+
+ switch (lumaFracPos[xFrac][yFrac])
+ {
+ case 0: /* G */
+ h264bsdFillBlock(refPic->data, lumaPartData,
+ xInt,yInt,width,height,partWidth,partHeight,16);
+ break;
+ case 1: /* d */
+ h264bsdInterpolateVerQuarter(refPic->data, lumaPartData,
+ xInt, yInt-2, width, height, partWidth, partHeight, 0);
+ break;
+ case 2: /* h */
+ h264bsdInterpolateVerHalf(refPic->data, lumaPartData,
+ xInt, yInt-2, width, height, partWidth, partHeight);
+ break;
+ case 3: /* n */
+ h264bsdInterpolateVerQuarter(refPic->data, lumaPartData,
+ xInt, yInt-2, width, height, partWidth, partHeight, 1);
+ break;
+ case 4: /* a */
+ h264bsdInterpolateHorQuarter(refPic->data, lumaPartData,
+ xInt-2, yInt, width, height, partWidth, partHeight, 0);
+ break;
+ case 5: /* e */
+ h264bsdInterpolateHorVerQuarter(refPic->data, lumaPartData,
+ xInt-2, yInt-2, width, height, partWidth, partHeight, 0);
+ break;
+ case 6: /* i */
+ h264bsdInterpolateMidHorQuarter(refPic->data, lumaPartData,
+ xInt-2, yInt-2, width, height, partWidth, partHeight, 0);
+ break;
+ case 7: /* p */
+ h264bsdInterpolateHorVerQuarter(refPic->data, lumaPartData,
+ xInt-2, yInt-2, width, height, partWidth, partHeight, 2);
+ break;
+ case 8: /* b */
+ h264bsdInterpolateHorHalf(refPic->data, lumaPartData,
+ xInt-2, yInt, width, height, partWidth, partHeight);
+ break;
+ case 9: /* f */
+ h264bsdInterpolateMidVerQuarter(refPic->data, lumaPartData,
+ xInt-2, yInt-2, width, height, partWidth, partHeight, 0);
+ break;
+ case 10: /* j */
+ h264bsdInterpolateMidHalf(refPic->data, lumaPartData,
+ xInt-2, yInt-2, width, height, partWidth, partHeight);
+ break;
+ case 11: /* q */
+ h264bsdInterpolateMidVerQuarter(refPic->data, lumaPartData,
+ xInt-2, yInt-2, width, height, partWidth, partHeight, 1);
+ break;
+ case 12: /* c */
+ h264bsdInterpolateHorQuarter(refPic->data, lumaPartData,
+ xInt-2, yInt, width, height, partWidth, partHeight, 1);
+ break;
+ case 13: /* g */
+ h264bsdInterpolateHorVerQuarter(refPic->data, lumaPartData,
+ xInt-2, yInt-2, width, height, partWidth, partHeight, 1);
+ break;
+ case 14: /* k */
+ h264bsdInterpolateMidHorQuarter(refPic->data, lumaPartData,
+ xInt-2, yInt-2, width, height, partWidth, partHeight, 1);
+ break;
+ default: /* case 15, r */
+ h264bsdInterpolateHorVerQuarter(refPic->data, lumaPartData,
+ xInt-2, yInt-2, width, height, partWidth, partHeight, 3);
+ break;
+ }
+
+ /* chroma */
+ PredictChroma(
+ data + 16*16 + (partY>>1)*8 + (partX>>1),
+ xA + partX,
+ yA + partY,
+ partWidth,
+ partHeight,
+ mv,
+ refPic);
+
+}
+
+#else /* H264DEC_OMXDL */
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdPredictSamples
+
+ Functional description:
+ This function reconstructs a prediction for a macroblock partition.
+ The prediction is either copied or interpolated using the reference
+ frame and the motion vector. Both luminance and chrominance parts are
+ predicted. The prediction is stored in given macroblock array (data).
+ Inputs:
+ data pointer to macroblock array (384 bytes) for output
+ mv pointer to motion vector used for prediction
+ refPic pointer to reference picture structure
+ xA x-coordinate for current macroblock
+ yA y-coordinate for current macroblock
+ partX x-offset for partition in macroblock
+ partY y-offset for partition in macroblock
+ partWidth width of partition
+ partHeight height of partition
+ Outputs:
+ data macroblock array (16x16+8x8+8x8) where predicted
+ partition is stored at correct position
+
+------------------------------------------------------------------------------*/
+
+/*lint -e{550} Symbol 'res' not accessed */
+void h264bsdPredictSamples(
+ u8 *data,
+ mv_t *mv,
+ image_t *refPic,
+ u32 colAndRow,
+ u32 part,
+ u8 *pFill)
+
+{
+
+/* Variables */
+
+ u32 xFrac, yFrac;
+ u32 width, height;
+ i32 xInt, yInt, x0, y0;
+ u8 *partData, *ref;
+ OMXSize roi;
+ u32 fillWidth;
+ u32 fillHeight;
+ OMXResult res;
+ u32 xA, yA;
+ u32 partX, partY;
+ u32 partWidth, partHeight;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(mv);
+ ASSERT(refPic);
+ ASSERT(refPic->data);
+ ASSERT(refPic->width);
+ ASSERT(refPic->height);
+
+ xA = (colAndRow & 0xFFFF0000) >> 16;
+ yA = (colAndRow & 0x0000FFFF);
+
+ partX = (part & 0xFF000000) >> 24;
+ partY = (part & 0x00FF0000) >> 16;
+ partWidth = (part & 0x0000FF00) >> 8;
+ partHeight = (part & 0x000000FF);
+
+ ASSERT(partWidth);
+ ASSERT(partHeight);
+
+ /* luma */
+ partData = data + 16*partY + partX;
+
+ xFrac = mv->hor & 0x3;
+ yFrac = mv->ver & 0x3;
+
+ width = 16 * refPic->width;
+ height = 16 * refPic->height;
+
+ xInt = (i32)xA + (i32)partX + (mv->hor >> 2);
+ yInt = (i32)yA + (i32)partY + (mv->ver >> 2);
+
+ x0 = (xFrac) ? xInt-2 : xInt;
+ y0 = (yFrac) ? yInt-2 : yInt;
+
+ if (xFrac)
+ {
+ if (partWidth == 16)
+ fillWidth = 32;
+ else
+ fillWidth = 16;
+ }
+ else
+ fillWidth = (partWidth*2);
+ if (yFrac)
+ fillHeight = partHeight+5;
+ else
+ fillHeight = partHeight;
+
+
+ if ((x0 < 0) || ((u32)x0+fillWidth > width) ||
+ (y0 < 0) || ((u32)y0+fillHeight > height))
+ {
+ h264bsdFillBlock(refPic->data, (u8*)pFill, x0, y0, width, height,
+ fillWidth, fillHeight, fillWidth);
+
+ x0 = 0;
+ y0 = 0;
+ ref = pFill;
+ width = fillWidth;
+ if (yFrac)
+ ref += 2*width;
+ if (xFrac)
+ ref += 2;
+ }
+ else
+ {
+ /*lint --e(737) Loss of sign */
+ ref = refPic->data + yInt*width + xInt;
+ }
+ /* Luma interpolation */
+ roi.width = (i32)partWidth;
+ roi.height = (i32)partHeight;
+
+ res = omxVCM4P10_InterpolateLuma(ref, (i32)width, partData, 16,
+ (i32)xFrac, (i32)yFrac, roi);
+ ASSERT(res == 0);
+
+ /* Chroma */
+ width = 8 * refPic->width;
+ height = 8 * refPic->height;
+
+ x0 = ((xA + partX) >> 1) + (mv->hor >> 3);
+ y0 = ((yA + partY) >> 1) + (mv->ver >> 3);
+ xFrac = mv->hor & 0x7;
+ yFrac = mv->ver & 0x7;
+
+ ref = refPic->data + 256 * refPic->width * refPic->height;
+
+ roi.width = (i32)(partWidth >> 1);
+ fillWidth = ((partWidth >> 1) + 8) & ~0x7;
+ roi.height = (i32)(partHeight >> 1);
+ fillHeight = (partHeight >> 1) + 1;
+
+ if ((x0 < 0) || ((u32)x0+fillWidth > width) ||
+ (y0 < 0) || ((u32)y0+fillHeight > height))
+ {
+ h264bsdFillBlock(ref, pFill, x0, y0, width, height,
+ fillWidth, fillHeight, fillWidth);
+ ref += width * height;
+ h264bsdFillBlock(ref, pFill + fillWidth*fillHeight,
+ x0, y0, width, height, fillWidth,
+ fillHeight, fillWidth);
+
+ ref = pFill;
+ x0 = 0;
+ y0 = 0;
+ width = fillWidth;
+ height = fillHeight;
+ }
+
+ partData = data + 16*16 + (partY>>1)*8 + (partX>>1);
+
+ /* Chroma interpolation */
+ /*lint --e(737) Loss of sign */
+ ref += y0 * width + x0;
+ res = armVCM4P10_Interpolate_Chroma(ref, width, partData, 8,
+ (u32)roi.width, (u32)roi.height, xFrac, yFrac);
+ ASSERT(res == 0);
+ partData += 8 * 8;
+ ref += height * width;
+ res = armVCM4P10_Interpolate_Chroma(ref, width, partData, 8,
+ (u32)roi.width, (u32)roi.height, xFrac, yFrac);
+ ASSERT(res == 0);
+
+}
+
+#endif /* H264DEC_OMXDL */
+
+
+/*------------------------------------------------------------------------------
+
+ Function: FillRow1
+
+ Functional description:
+ This function gets a row of reference pels in a 'normal' case when no
+ overfilling is necessary.
+
+------------------------------------------------------------------------------*/
+
+static void FillRow1(
+ u8 *ref,
+ u8 *fill,
+ i32 left,
+ i32 center,
+ i32 right)
+{
+
+ ASSERT(ref);
+ ASSERT(fill);
+
+ H264SwDecMemcpy(fill, ref, (u32)center);
+
+ /*lint -e(715) */
+}
+
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdFillRow7
+
+ Functional description:
+ This function gets a row of reference pels when horizontal coordinate
+ is partly negative or partly greater than reference picture width
+ (overfilling some pels on left and/or right edge).
+ Inputs:
+ ref pointer to reference samples
+ left amount of pixels to overfill on left-edge
+ center amount of pixels to copy
+ right amount of pixels to overfill on right-edge
+ Outputs:
+ fill pointer where samples are stored
+
+------------------------------------------------------------------------------*/
+#ifndef H264DEC_NEON
+void h264bsdFillRow7(
+ u8 *ref,
+ u8 *fill,
+ i32 left,
+ i32 center,
+ i32 right)
+{
+ u8 tmp;
+
+ ASSERT(ref);
+ ASSERT(fill);
+
+ if (left)
+ tmp = *ref;
+
+ for ( ; left; left--)
+ /*lint -esym(644,tmp) tmp is initialized if used */
+ *fill++ = tmp;
+
+ for ( ; center; center--)
+ *fill++ = *ref++;
+
+ if (right)
+ tmp = ref[-1];
+
+ for ( ; right; right--)
+ /*lint -esym(644,tmp) tmp is initialized if used */
+ *fill++ = tmp;
+}
+#endif
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdFillBlock
+
+ Functional description:
+ This function gets a block of reference pels. It determines whether
+ overfilling is needed or not and repeatedly calls an appropriate
+ function (by using a function pointer) that fills one row the block.
+ Inputs:
+ ref pointer to reference frame
+ x0 x-coordinate for block
+ y0 y-coordinate for block
+ width width of reference frame
+ height height of reference frame
+ blockWidth width of block
+ blockHeight height of block
+ fillScanLength length of a line in output array (pixels)
+ Outputs:
+ fill pointer to array where output block is written
+
+------------------------------------------------------------------------------*/
+
+void h264bsdFillBlock(
+ u8 *ref,
+ u8 *fill,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 blockWidth,
+ u32 blockHeight,
+ u32 fillScanLength)
+
+{
+
+/* Variables */
+
+ i32 xstop, ystop;
+ void (*fp)(u8*, u8*, i32, i32, i32);
+ i32 left, x, right;
+ i32 top, y, bottom;
+
+/* Code */
+
+ ASSERT(ref);
+ ASSERT(fill);
+ ASSERT(width);
+ ASSERT(height);
+ ASSERT(fill);
+ ASSERT(blockWidth);
+ ASSERT(blockHeight);
+
+ xstop = x0 + (i32)blockWidth;
+ ystop = y0 + (i32)blockHeight;
+
+ /* Choose correct function whether overfilling on left-edge or right-edge
+ * is needed or not */
+ if (x0 >= 0 && xstop <= (i32)width)
+ fp = FillRow1;
+ else
+ fp = h264bsdFillRow7;
+
+ if (ystop < 0)
+ y0 = -(i32)blockHeight;
+
+ if (xstop < 0)
+ x0 = -(i32)blockWidth;
+
+ if (y0 > (i32)height)
+ y0 = (i32)height;
+
+ if (x0 > (i32)width)
+ x0 = (i32)width;
+
+ xstop = x0 + (i32)blockWidth;
+ ystop = y0 + (i32)blockHeight;
+
+ if (x0 > 0)
+ ref += x0;
+
+ if (y0 > 0)
+ ref += y0 * (i32)width;
+
+ left = x0 < 0 ? -x0 : 0;
+ right = xstop > (i32)width ? xstop - (i32)width : 0;
+ x = (i32)blockWidth - left - right;
+
+ top = y0 < 0 ? -y0 : 0;
+ bottom = ystop > (i32)height ? ystop - (i32)height : 0;
+ y = (i32)blockHeight - top - bottom;
+
+ /* Top-overfilling */
+ for ( ; top; top-- )
+ {
+ (*fp)(ref, fill, left, x, right);
+ fill += fillScanLength;
+ }
+
+ /* Lines inside reference image */
+ for ( ; y; y-- )
+ {
+ (*fp)(ref, fill, left, x, right);
+ ref += width;
+ fill += fillScanLength;
+ }
+
+ ref -= width;
+
+ /* Bottom-overfilling */
+ for ( ; bottom; bottom-- )
+ {
+ (*fp)(ref, fill, left, x, right);
+ fill += fillScanLength;
+ }
+}
+
+/*lint +e701 +e702 */
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_reconstruct.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_reconstruct.h
new file mode 100755
index 0000000..5a1a140
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_reconstruct.h
@@ -0,0 +1,210 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_RECONSTRUCT_H
+#define H264SWDEC_RECONSTRUCT_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_macroblock_layer.h"
+#include "h264bsd_image.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+#ifndef H264DEC_OMXDL
+void h264bsdPredictSamples(
+ u8 *data,
+ mv_t *mv,
+ image_t *refPic,
+ u32 xA,
+ u32 yA,
+ u32 partX,
+ u32 partY,
+ u32 partWidth,
+ u32 partHeight);
+#else
+void h264bsdPredictSamples(
+ u8 *data,
+ mv_t *mv,
+ image_t *refPic,
+ u32 colAndRow,/* packaged data | column | row |*/
+ u32 part, /* packaged data |partX|partY|partWidth|partHeight|*/
+ u8 *pFill);
+#endif
+
+void h264bsdFillBlock(
+ u8 * ref,
+ u8 * fill,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 blockWidth,
+ u32 blockHeight,
+ u32 fillScanLength);
+
+void h264bsdInterpolateChromaHor(
+ u8 *pRef,
+ u8 *predPartChroma,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 xFrac,
+ u32 chromaPartWidth,
+ u32 chromaPartHeight);
+
+void h264bsdInterpolateChromaVer(
+ u8 *pRef,
+ u8 *predPartChroma,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 yFrac,
+ u32 chromaPartWidth,
+ u32 chromaPartHeight);
+
+void h264bsdInterpolateChromaHorVer(
+ u8 *ref,
+ u8 *predPartChroma,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 xFrac,
+ u32 yFrac,
+ u32 chromaPartWidth,
+ u32 chromaPartHeight);
+
+void h264bsdInterpolateVerHalf(
+ u8 *ref,
+ u8 *mb,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 partWidth,
+ u32 partHeight);
+
+void h264bsdInterpolateVerQuarter(
+ u8 *ref,
+ u8 *mb,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 partWidth,
+ u32 partHeight,
+ u32 verOffset);
+
+void h264bsdInterpolateHorHalf(
+ u8 *ref,
+ u8 *mb,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 partWidth,
+ u32 partHeight);
+
+void h264bsdInterpolateHorQuarter(
+ u8 *ref,
+ u8 *mb,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 partWidth,
+ u32 partHeight,
+ u32 horOffset);
+
+void h264bsdInterpolateHorVerQuarter(
+ u8 *ref,
+ u8 *mb,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 partWidth,
+ u32 partHeight,
+ u32 horVerOffset);
+
+void h264bsdInterpolateMidHalf(
+ u8 *ref,
+ u8 *mb,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 partWidth,
+ u32 partHeight);
+
+void h264bsdInterpolateMidVerQuarter(
+ u8 *ref,
+ u8 *mb,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 partWidth,
+ u32 partHeight,
+ u32 verOffset);
+
+void h264bsdInterpolateMidHorQuarter(
+ u8 *ref,
+ u8 *mb,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 partWidth,
+ u32 partHeight,
+ u32 horOffset);
+
+
+void h264bsdFillRow7(
+ u8 *ref,
+ u8 *fill,
+ i32 left,
+ i32 center,
+ i32 right);
+
+#endif /* #ifdef H264SWDEC_RECONSTRUCT_H */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_sei.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_sei.c
new file mode 100755
index 0000000..0756c47
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_sei.c
@@ -0,0 +1,1692 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdDecodeSeiMessage
+ DecodeBufferingPeriod
+ DecodePictureTiming
+ DecodePanScanRectangle
+ DecodeFillerPayload
+ DecodeUserDataRegisteredITuTT35
+ DecodeUserDataUnregistered
+ DecodeRecoveryPoint
+ DecodeDecRefPicMarkingRepetition
+ DecodeSparePic
+ DecodeSceneInfo
+ DecodeSubSeqInfo
+ DecodeSubSeqLayerCharacteristics
+ DecodeSubSeqCharacteristics
+ DecodeFullFrameFreeze
+ DecodeFullFrameSnapshot
+ DecodeProgressiveRefinementSegmentStart
+ DecodeProgressiveRefinementSegmentEnd
+ DecodeMotionConstrainedSliceGroupSet
+ DecodeReservedSeiMessage
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_sei.h"
+#include "basetype.h"
+#include "h264bsd_util.h"
+#include "h264bsd_stream.h"
+#include "h264bsd_vlc.h"
+#include "h264bsd_seq_param_set.h"
+#include "h264bsd_slice_header.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+static const u32 numClockTS[9] = {1,1,1,2,2,3,3,2,3};
+static const u32 ceilLog2NumSliceGroups[9] = {0,1,1,2,2,3,3,3,3};
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+static u32 DecodeBufferingPeriod(
+ strmData_t *pStrmData,
+ seiBufferingPeriod_t *pBufferingPeriod,
+ u32 cpbCnt,
+ u32 initialCpbRemovalDelayLength,
+ u32 nalHrdBpPresentFlag,
+ u32 vclHrdBpPresentFlag);
+
+static u32 DecodePictureTiming(
+ strmData_t *pStrmData,
+ seiPicTiming_t *pPicTiming,
+ u32 cpbRemovalDelayLength,
+ u32 dpbOutputDelayLength,
+ u32 timeOffsetLength,
+ u32 cpbDpbDelaysPresentFlag,
+ u32 picStructPresentFlag);
+
+static u32 DecodePanScanRectangle(
+ strmData_t *pStrmData,
+ seiPanScanRect_t *pPanScanRectangle);
+
+static u32 DecodeFillerPayload(strmData_t *pStrmData, u32 payloadSize);
+
+static u32 DecodeUserDataRegisteredITuTT35(
+ strmData_t *pStrmData,
+ seiUserDataRegisteredItuTT35_t *pUserDataRegisteredItuTT35,
+ u32 payloadSize);
+
+static u32 DecodeUserDataUnregistered(
+ strmData_t *pStrmData,
+ seiUserDataUnregistered_t *pUserDataUnregistered,
+ u32 payloadSize);
+
+static u32 DecodeRecoveryPoint(
+ strmData_t *pStrmData,
+ seiRecoveryPoint_t *pRecoveryPoint);
+
+static u32 DecodeDecRefPicMarkingRepetition(
+ strmData_t *pStrmData,
+ seiDecRefPicMarkingRepetition_t *pDecRefPicMarkingRepetition,
+ u32 numRefFrames);
+
+static u32 DecodeSparePic(
+ strmData_t *pStrmData,
+ seiSparePic_t *pSparePic,
+ u32 picSizeInMapUnits);
+
+static u32 DecodeSceneInfo(
+ strmData_t *pStrmData,
+ seiSceneInfo_t *pSceneInfo);
+
+static u32 DecodeSubSeqInfo(
+ strmData_t *pStrmData,
+ seiSubSeqInfo_t *pSubSeqInfo);
+
+static u32 DecodeSubSeqLayerCharacteristics(
+ strmData_t *pStrmData,
+ seiSubSeqLayerCharacteristics_t *pSubSeqLayerCharacteristics);
+
+static u32 DecodeSubSeqCharacteristics(
+ strmData_t *pStrmData,
+ seiSubSeqCharacteristics_t *pSubSeqCharacteristics);
+
+static u32 DecodeFullFrameFreeze(
+ strmData_t *pStrmData,
+ seiFullFrameFreeze_t *pFullFrameFreeze);
+
+static u32 DecodeFullFrameSnapshot(
+ strmData_t *pStrmData,
+ seiFullFrameSnapshot_t *pFullFrameSnapshot);
+
+static u32 DecodeProgressiveRefinementSegmentStart(
+ strmData_t *pStrmData,
+ seiProgressiveRefinementSegmentStart_t *pProgressiveRefinementSegmentStart);
+
+static u32 DecodeProgressiveRefinementSegmentEnd(
+ strmData_t *pStrmData,
+ seiProgressiveRefinementSegmentEnd_t *pProgressiveRefinementSegmentEnd);
+
+static u32 DecodeMotionConstrainedSliceGroupSet(
+ strmData_t *pStrmData,
+ seiMotionConstrainedSliceGroupSet_t *pMotionConstrainedSliceGroupSet,
+ u32 numSliceGroups);
+
+static u32 DecodeReservedSeiMessage(
+ strmData_t *pStrmData,
+ seiReservedSeiMessage_t *pReservedSeiMessage,
+ u32 payloadSize);
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdDecodeSeiMessage
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeSeiMessage(
+ strmData_t *pStrmData,
+ seqParamSet_t *pSeqParamSet,
+ seiMessage_t *pSeiMessage,
+ u32 numSliceGroups)
+{
+
+/* Variables */
+
+ u32 tmp, payloadType, payloadSize, status;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pSeiMessage);
+
+
+ H264SwDecMemset(pSeiMessage, 0, sizeof(seiMessage_t));
+
+ do
+ {
+ payloadType = 0;
+ while((tmp = h264bsdGetBits(pStrmData, 8)) == 0xFF)
+ {
+ payloadType += 255;
+ }
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ payloadType += tmp;
+
+ payloadSize = 0;
+ while((tmp = h264bsdGetBits(pStrmData, 8)) == 0xFF)
+ {
+ payloadSize += 255;
+ }
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ payloadSize += tmp;
+
+ pSeiMessage->payloadType = payloadType;
+
+ switch (payloadType)
+ {
+ case 0:
+ ASSERT(pSeqParamSet);
+ status = DecodeBufferingPeriod(
+ pStrmData,
+ &pSeiMessage->bufferingPeriod,
+ pSeqParamSet->vuiParameters->vclHrdParameters.cpbCnt,
+ pSeqParamSet->vuiParameters->vclHrdParameters.
+ initialCpbRemovalDelayLength,
+ pSeqParamSet->vuiParameters->nalHrdParametersPresentFlag,
+ pSeqParamSet->vuiParameters->vclHrdParametersPresentFlag);
+ break;
+
+ case 1:
+ ASSERT(pSeqParamSet->vuiParametersPresentFlag);
+ status = DecodePictureTiming(
+ pStrmData,
+ &pSeiMessage->picTiming,
+ pSeqParamSet->vuiParameters->vclHrdParameters.
+ cpbRemovalDelayLength,
+ pSeqParamSet->vuiParameters->vclHrdParameters.
+ dpbOutputDelayLength,
+ pSeqParamSet->vuiParameters->vclHrdParameters.
+ timeOffsetLength,
+ pSeqParamSet->vuiParameters->nalHrdParametersPresentFlag ||
+ pSeqParamSet->vuiParameters->vclHrdParametersPresentFlag ?
+ HANTRO_TRUE : HANTRO_FALSE,
+ pSeqParamSet->vuiParameters->picStructPresentFlag);
+ break;
+
+ case 2:
+ status = DecodePanScanRectangle(
+ pStrmData,
+ &pSeiMessage->panScanRect);
+ break;
+
+ case 3:
+ status = DecodeFillerPayload(pStrmData, payloadSize);
+ break;
+
+ case 4:
+ status = DecodeUserDataRegisteredITuTT35(
+ pStrmData,
+ &pSeiMessage->userDataRegisteredItuTT35,
+ payloadSize);
+ break;
+
+ case 5:
+ status = DecodeUserDataUnregistered(
+ pStrmData,
+ &pSeiMessage->userDataUnregistered,
+ payloadSize);
+ break;
+
+ case 6:
+ status = DecodeRecoveryPoint(
+ pStrmData,
+ &pSeiMessage->recoveryPoint);
+ break;
+
+ case 7:
+ status = DecodeDecRefPicMarkingRepetition(
+ pStrmData,
+ &pSeiMessage->decRefPicMarkingRepetition,
+ pSeqParamSet->numRefFrames);
+ break;
+
+ case 8:
+ ASSERT(pSeqParamSet);
+ status = DecodeSparePic(
+ pStrmData,
+ &pSeiMessage->sparePic,
+ pSeqParamSet->picWidthInMbs * pSeqParamSet->picHeightInMbs);
+ break;
+
+ case 9:
+ status = DecodeSceneInfo(
+ pStrmData,
+ &pSeiMessage->sceneInfo);
+ break;
+
+ case 10:
+ status = DecodeSubSeqInfo(
+ pStrmData,
+ &pSeiMessage->subSeqInfo);
+ break;
+
+ case 11:
+ status = DecodeSubSeqLayerCharacteristics(
+ pStrmData,
+ &pSeiMessage->subSeqLayerCharacteristics);
+ break;
+
+ case 12:
+ status = DecodeSubSeqCharacteristics(
+ pStrmData,
+ &pSeiMessage->subSeqCharacteristics);
+ break;
+
+ case 13:
+ status = DecodeFullFrameFreeze(
+ pStrmData,
+ &pSeiMessage->fullFrameFreeze);
+ break;
+
+ case 14: /* This SEI does not contain data, what to do ??? */
+ status = HANTRO_OK;
+ break;
+
+ case 15:
+ status = DecodeFullFrameSnapshot(
+ pStrmData,
+ &pSeiMessage->fullFrameSnapshot);
+ break;
+
+ case 16:
+ status = DecodeProgressiveRefinementSegmentStart(
+ pStrmData,
+ &pSeiMessage->progressiveRefinementSegmentStart);
+ break;
+
+ case 17:
+ status = DecodeProgressiveRefinementSegmentEnd(
+ pStrmData,
+ &pSeiMessage->progressiveRefinementSegmentEnd);
+ break;
+
+ case 18:
+ ASSERT(numSliceGroups);
+ status = DecodeMotionConstrainedSliceGroupSet(
+ pStrmData,
+ &pSeiMessage->motionConstrainedSliceGroupSet,
+ numSliceGroups);
+ break;
+
+ default:
+ status = DecodeReservedSeiMessage(
+ pStrmData,
+ &pSeiMessage->reservedSeiMessage,
+ payloadSize);
+ break;
+ }
+
+ if (status != HANTRO_OK)
+ return(status);
+
+ while (!h264bsdIsByteAligned(pStrmData))
+ {
+ if (h264bsdGetBits(pStrmData, 1) != 1)
+ return(HANTRO_NOK);
+ while (!h264bsdIsByteAligned(pStrmData))
+ {
+ if (h264bsdGetBits(pStrmData, 1) != 0)
+ return(HANTRO_NOK);
+ }
+ }
+ } while (h264bsdMoreRbspData(pStrmData));
+
+ return(h264bsdRbspTrailingBits(pStrmData));
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeBufferingPeriod
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+------------------------------------------------------------------------------*/
+
+static u32 DecodeBufferingPeriod(
+ strmData_t *pStrmData,
+ seiBufferingPeriod_t *pBufferingPeriod,
+ u32 cpbCnt,
+ u32 initialCpbRemovalDelayLength,
+ u32 nalHrdBpPresentFlag,
+ u32 vclHrdBpPresentFlag)
+{
+
+/* Variables */
+
+ u32 tmp, i;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pBufferingPeriod);
+ ASSERT(cpbCnt);
+ ASSERT(initialCpbRemovalDelayLength);
+
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pBufferingPeriod->seqParameterSetId);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pBufferingPeriod->seqParameterSetId > 31)
+ return(HANTRO_NOK);
+
+ if (nalHrdBpPresentFlag)
+ {
+ for (i = 0; i < cpbCnt; i++)
+ {
+ tmp = h264bsdGetBits(pStrmData, initialCpbRemovalDelayLength);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ if (tmp == 0)
+ return(HANTRO_NOK);
+ pBufferingPeriod->initialCpbRemovalDelay[i] = tmp;
+
+ tmp = h264bsdGetBits(pStrmData, initialCpbRemovalDelayLength);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pBufferingPeriod->initialCpbRemovalDelayOffset[i] = tmp;
+ }
+ }
+
+ if (vclHrdBpPresentFlag)
+ {
+ for (i = 0; i < cpbCnt; i++)
+ {
+ tmp = h264bsdGetBits(pStrmData, initialCpbRemovalDelayLength);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pBufferingPeriod->initialCpbRemovalDelay[i] = tmp;
+
+ tmp = h264bsdGetBits(pStrmData, initialCpbRemovalDelayLength);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pBufferingPeriod->initialCpbRemovalDelayOffset[i] = tmp;
+ }
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodePictureTiming
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+------------------------------------------------------------------------------*/
+
+static u32 DecodePictureTiming(
+ strmData_t *pStrmData,
+ seiPicTiming_t *pPicTiming,
+ u32 cpbRemovalDelayLength,
+ u32 dpbOutputDelayLength,
+ u32 timeOffsetLength,
+ u32 cpbDpbDelaysPresentFlag,
+ u32 picStructPresentFlag)
+{
+
+/* Variables */
+
+ u32 tmp, i;
+ i32 itmp;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pPicTiming);
+
+
+ if (cpbDpbDelaysPresentFlag)
+ {
+ tmp = h264bsdGetBits(pStrmData, cpbRemovalDelayLength);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pPicTiming->cpbRemovalDelay = tmp;
+
+ tmp = h264bsdGetBits(pStrmData, dpbOutputDelayLength);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pPicTiming->dpbOutputDelay = tmp;
+ }
+
+ if (picStructPresentFlag)
+ {
+ tmp = h264bsdGetBits(pStrmData, 4);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ if (tmp > 8)
+ return(HANTRO_NOK);
+ pPicTiming->picStruct = tmp;
+
+ for (i = 0; i < numClockTS[pPicTiming->picStruct]; i++)
+ {
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pPicTiming->clockTimeStampFlag[i] = tmp == 1 ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ if (pPicTiming->clockTimeStampFlag[i])
+ {
+ tmp = h264bsdGetBits(pStrmData, 2);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pPicTiming->ctType[i] = tmp;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pPicTiming->nuitFieldBasedFlag[i] = tmp == 1 ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdGetBits(pStrmData, 5);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ if (tmp > 6)
+ return(HANTRO_NOK);
+ pPicTiming->countingType[i] = tmp;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pPicTiming->fullTimeStampFlag[i] = tmp == 1 ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pPicTiming->discontinuityFlag[i] = tmp == 1 ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pPicTiming->cntDroppedFlag[i] = tmp == 1 ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdGetBits(pStrmData, 8);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pPicTiming->nFrames[i] = tmp;
+
+ if (pPicTiming->fullTimeStampFlag[i])
+ {
+ tmp = h264bsdGetBits(pStrmData, 6);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ if (tmp > 59)
+ return(HANTRO_NOK);
+ pPicTiming->secondsValue[i] = tmp;
+
+ tmp = h264bsdGetBits(pStrmData, 6);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ if (tmp > 59)
+ return(HANTRO_NOK);
+ pPicTiming->minutesValue[i] = tmp;
+
+ tmp = h264bsdGetBits(pStrmData, 5);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ if (tmp > 23)
+ return(HANTRO_NOK);
+ pPicTiming->hoursValue[i] = tmp;
+ }
+ else
+ {
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pPicTiming->secondsFlag[i] = tmp == 1 ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ if (pPicTiming->secondsFlag[i])
+ {
+ tmp = h264bsdGetBits(pStrmData, 6);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ if (tmp > 59)
+ return(HANTRO_NOK);
+ pPicTiming->secondsValue[i] = tmp;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pPicTiming->minutesFlag[i] = tmp == 1 ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ if (pPicTiming->minutesFlag[i])
+ {
+ tmp = h264bsdGetBits(pStrmData, 6);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ if (tmp > 59)
+ return(HANTRO_NOK);
+ pPicTiming->minutesValue[i] = tmp;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pPicTiming->hoursFlag[i] = tmp == 1 ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ if (pPicTiming->hoursFlag[i])
+ {
+ tmp = h264bsdGetBits(pStrmData, 5);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ if (tmp > 23)
+ return(HANTRO_NOK);
+ pPicTiming->hoursValue[i] = tmp;
+ }
+ }
+ }
+ }
+ if (timeOffsetLength)
+ {
+ tmp = h264bsdGetBits(pStrmData, timeOffsetLength);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ itmp = (i32)tmp;
+ /* following "converts" timeOffsetLength-bit signed
+ * integer into i32 */
+ /*lint -save -e701 -e702 */
+ itmp <<= (32 - timeOffsetLength);
+ itmp >>= (32 - timeOffsetLength);
+ /*lint -restore */
+ pPicTiming->timeOffset[i] = itmp;
+ }
+ else
+ pPicTiming->timeOffset[i] = 0;
+ }
+ }
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodePanScanRectangle
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+------------------------------------------------------------------------------*/
+
+static u32 DecodePanScanRectangle(
+ strmData_t *pStrmData,
+ seiPanScanRect_t *pPanScanRectangle)
+{
+
+/* Variables */
+
+ u32 tmp, i;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pPanScanRectangle);
+
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pPanScanRectangle->panScanRectId);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pPanScanRectangle->panScanRectCancelFlag = tmp == 1 ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ if (!pPanScanRectangle->panScanRectCancelFlag)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pPanScanRectangle->panScanCnt);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pPanScanRectangle->panScanCnt > 2)
+ return(HANTRO_NOK);
+ pPanScanRectangle->panScanCnt++;
+
+ for (i = 0; i < pPanScanRectangle->panScanCnt; i++)
+ {
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData,
+ &pPanScanRectangle->panScanRectLeftOffset[i]);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData,
+ &pPanScanRectangle->panScanRectRightOffset[i]);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData,
+ &pPanScanRectangle->panScanRectTopOffset[i]);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData,
+ &pPanScanRectangle->panScanRectBottomOffset[i]);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pPanScanRectangle->panScanRectRepetitionPeriod);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pPanScanRectangle->panScanRectRepetitionPeriod > 16384)
+ return(HANTRO_NOK);
+ if (pPanScanRectangle->panScanCnt > 1 &&
+ pPanScanRectangle->panScanRectRepetitionPeriod > 1)
+ return(HANTRO_NOK);
+ }
+
+ return(HANTRO_OK);
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeFillerPayload
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+------------------------------------------------------------------------------*/
+
+static u32 DecodeFillerPayload(strmData_t *pStrmData, u32 payloadSize)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(pStrmData);
+
+
+ if (payloadSize)
+ if (h264bsdFlushBits(pStrmData, 8 * payloadSize) == END_OF_STREAM)
+ return(HANTRO_NOK);
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeUserDataRegisteredITuTT35
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+------------------------------------------------------------------------------*/
+
+static u32 DecodeUserDataRegisteredITuTT35(
+ strmData_t *pStrmData,
+ seiUserDataRegisteredItuTT35_t *pUserDataRegisteredItuTT35,
+ u32 payloadSize)
+{
+
+/* Variables */
+
+ u32 tmp, i, j;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pUserDataRegisteredItuTT35);
+ ASSERT(payloadSize);
+
+ tmp = h264bsdGetBits(pStrmData, 8);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pUserDataRegisteredItuTT35->ituTT35CountryCode = tmp;
+
+ if (pUserDataRegisteredItuTT35->ituTT35CountryCode != 0xFF)
+ i = 1;
+ else
+ {
+ tmp = h264bsdGetBits(pStrmData, 8);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pUserDataRegisteredItuTT35->ituTT35CountryCodeExtensionByte = tmp;
+ i = 2;
+ }
+
+ /* where corresponding FREE() ??? */
+ ALLOCATE(pUserDataRegisteredItuTT35->ituTT35PayloadByte,payloadSize-i,u8);
+ pUserDataRegisteredItuTT35->numPayloadBytes = payloadSize - i;
+ if (pUserDataRegisteredItuTT35->ituTT35PayloadByte == NULL)
+ return(MEMORY_ALLOCATION_ERROR);
+
+ j = 0;
+ do
+ {
+ tmp = h264bsdGetBits(pStrmData, 8);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pUserDataRegisteredItuTT35->ituTT35PayloadByte[j] = (u8)tmp;
+ i++;
+ j++;
+ } while (i < payloadSize);
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeUserDataUnregistered
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+------------------------------------------------------------------------------*/
+
+static u32 DecodeUserDataUnregistered(
+ strmData_t *pStrmData,
+ seiUserDataUnregistered_t *pUserDataUnregistered,
+ u32 payloadSize)
+{
+
+/* Variables */
+
+ u32 i, tmp;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pUserDataUnregistered);
+
+
+ for (i = 0; i < 4; i++)
+ {
+ pUserDataUnregistered->uuidIsoIec11578[i] = h264bsdShowBits32(pStrmData);
+ if (h264bsdFlushBits(pStrmData,32) == END_OF_STREAM)
+ return(HANTRO_NOK);
+ }
+
+ /* where corresponding FREE() ??? */
+ ALLOCATE(pUserDataUnregistered->userDataPayloadByte, payloadSize - 16, u8);
+ if (pUserDataUnregistered->userDataPayloadByte == NULL)
+ return(MEMORY_ALLOCATION_ERROR);
+
+ pUserDataUnregistered->numPayloadBytes = payloadSize - 16;
+
+ for (i = 0; i < payloadSize - 16; i++)
+ {
+ tmp = h264bsdGetBits(pStrmData, 8);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pUserDataUnregistered->userDataPayloadByte[i] = (u8)tmp;
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeRecoveryPoint
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+------------------------------------------------------------------------------*/
+
+static u32 DecodeRecoveryPoint(
+ strmData_t *pStrmData,
+ seiRecoveryPoint_t *pRecoveryPoint)
+{
+
+/* Variables */
+
+ u32 tmp;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pRecoveryPoint);
+
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pRecoveryPoint->recoveryFrameCnt);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pRecoveryPoint->exactMatchFlag = tmp == 1 ? HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pRecoveryPoint->brokenLinkFlag = tmp == 1 ? HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdGetBits(pStrmData, 2);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ if (tmp > 2)
+ return(HANTRO_NOK);
+ pRecoveryPoint->changingSliceGroupIdc = tmp;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeDecRefPicMarkingRepetition
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+------------------------------------------------------------------------------*/
+
+static u32 DecodeDecRefPicMarkingRepetition(
+ strmData_t *pStrmData,
+ seiDecRefPicMarkingRepetition_t *pDecRefPicMarkingRepetition,
+ u32 numRefFrames)
+{
+
+/* Variables */
+
+ u32 tmp;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pDecRefPicMarkingRepetition);
+
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pDecRefPicMarkingRepetition->originalIdrFlag = tmp == 1 ? HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pDecRefPicMarkingRepetition->originalFrameNum);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* frame_mbs_only_flag assumed always true so some field related syntax
+ * elements are skipped, see H.264 standard */
+ tmp = h264bsdDecRefPicMarking(pStrmData,
+ &pDecRefPicMarkingRepetition->decRefPicMarking, NAL_SEI, numRefFrames);
+
+ return(tmp);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeSparePic
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+------------------------------------------------------------------------------*/
+
+static u32 DecodeSparePic(
+ strmData_t *pStrmData,
+ seiSparePic_t *pSparePic,
+ u32 picSizeInMapUnits)
+{
+
+/* Variables */
+
+ u32 tmp, i, j, mapUnitCnt;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pSparePic);
+
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSparePic->targetFrameNum);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSparePic->spareFieldFlag = tmp == 1 ? HANTRO_TRUE : HANTRO_FALSE;
+ /* do not accept fields */
+ if (pSparePic->spareFieldFlag)
+ return(HANTRO_NOK);
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &pSparePic->numSparePics);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pSparePic->numSparePics++;
+ if (pSparePic->numSparePics > MAX_NUM_SPARE_PICS)
+ return(HANTRO_NOK);
+
+ for (i = 0; i < pSparePic->numSparePics; i++)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSparePic->deltaSpareFrameNum[i]);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSparePic->spareAreaIdc[i]);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pSparePic->spareAreaIdc[i] > 2)
+ return(HANTRO_NOK);
+
+ if (pSparePic->spareAreaIdc[i] == 1)
+ {
+ /* where corresponding FREE() ??? */
+ ALLOCATE(pSparePic->spareUnitFlag[i], picSizeInMapUnits, u32);
+ if (pSparePic->spareUnitFlag[i] == NULL)
+ return(MEMORY_ALLOCATION_ERROR);
+ pSparePic->zeroRunLength[i] = NULL;
+
+ for (j = 0; j < picSizeInMapUnits; j++)
+ {
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSparePic->spareUnitFlag[i][j] = tmp == 1 ?
+ HANTRO_TRUE : HANTRO_FALSE;
+ }
+ }
+ else if (pSparePic->spareAreaIdc[i] == 2)
+ {
+ /* where corresponding FREE() ??? */
+ ALLOCATE(pSparePic->zeroRunLength[i], picSizeInMapUnits, u32);
+ if (pSparePic->zeroRunLength[i] == NULL)
+ return(MEMORY_ALLOCATION_ERROR);
+ pSparePic->spareUnitFlag[i] = NULL;
+
+ for (j = 0, mapUnitCnt = 0; mapUnitCnt < picSizeInMapUnits; j++)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSparePic->zeroRunLength[i][j]);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ mapUnitCnt += pSparePic->zeroRunLength[i][j] + 1;
+ }
+ }
+ }
+
+ /* set rest to null */
+ for (i = pSparePic->numSparePics; i < MAX_NUM_SPARE_PICS; i++)
+ {
+ pSparePic->spareUnitFlag[i] = NULL;
+ pSparePic->zeroRunLength[i] = NULL;
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeSceneInfo
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+------------------------------------------------------------------------------*/
+
+static u32 DecodeSceneInfo(
+ strmData_t *pStrmData,
+ seiSceneInfo_t *pSceneInfo)
+{
+
+/* Variables */
+
+ u32 tmp;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pSceneInfo);
+
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSceneInfo->sceneInfoPresentFlag = tmp == 1 ? HANTRO_TRUE : HANTRO_FALSE;
+
+ if (pSceneInfo->sceneInfoPresentFlag)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &pSceneInfo->sceneId);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSceneInfo->sceneTransitionType);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pSceneInfo->sceneTransitionType > 6)
+ return(HANTRO_NOK);
+
+ if (pSceneInfo->sceneTransitionType)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSceneInfo->secondSceneId);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeSubSeqInfo
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+-----------------------------------------------------------------------------*/
+
+static u32 DecodeSubSeqInfo(
+ strmData_t *pStrmData,
+ seiSubSeqInfo_t *pSubSeqInfo)
+{
+
+/* Variables */
+
+ u32 tmp;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pSubSeqInfo);
+
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSubSeqInfo->subSeqLayerNum);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pSubSeqInfo->subSeqLayerNum > 255)
+ return(HANTRO_NOK);
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &pSubSeqInfo->subSeqId);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pSubSeqInfo->subSeqId > 65535)
+ return(HANTRO_NOK);
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSubSeqInfo->firstRefPicFlag = tmp == 1 ? HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSubSeqInfo->leadingNonRefPicFlag = tmp == 1 ? HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSubSeqInfo->lastPicFlag = tmp == 1 ? HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSubSeqInfo->subSeqFrameNumFlag = tmp == 1 ? HANTRO_TRUE : HANTRO_FALSE;
+
+ if (pSubSeqInfo->subSeqFrameNumFlag)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSubSeqInfo->subSeqFrameNum);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeSubSeqLayerCharacteristics
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+------------------------------------------------------------------------------*/
+
+static u32 DecodeSubSeqLayerCharacteristics(
+ strmData_t *pStrmData,
+ seiSubSeqLayerCharacteristics_t *pSubSeqLayerCharacteristics)
+{
+
+/* Variables */
+
+ u32 tmp, i;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pSubSeqLayerCharacteristics);
+
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSubSeqLayerCharacteristics->numSubSeqLayers);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pSubSeqLayerCharacteristics->numSubSeqLayers++;
+ if (pSubSeqLayerCharacteristics->numSubSeqLayers > MAX_NUM_SUB_SEQ_LAYERS)
+ return(HANTRO_NOK);
+
+ for (i = 0; i < pSubSeqLayerCharacteristics->numSubSeqLayers; i++)
+ {
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSubSeqLayerCharacteristics->accurateStatisticsFlag[i] =
+ tmp == 1 ? HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdGetBits(pStrmData, 16);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSubSeqLayerCharacteristics->averageBitRate[i] = tmp;
+
+ tmp = h264bsdGetBits(pStrmData, 16);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSubSeqLayerCharacteristics->averageFrameRate[i] = tmp;
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeSubSeqCharacteristics
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+------------------------------------------------------------------------------*/
+
+static u32 DecodeSubSeqCharacteristics(
+ strmData_t *pStrmData,
+ seiSubSeqCharacteristics_t *pSubSeqCharacteristics)
+{
+
+/* Variables */
+
+ u32 tmp, i;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pSubSeqCharacteristics);
+
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSubSeqCharacteristics->subSeqLayerNum);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pSubSeqCharacteristics->subSeqLayerNum > MAX_NUM_SUB_SEQ_LAYERS-1)
+ return(HANTRO_NOK);
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSubSeqCharacteristics->subSeqId);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pSubSeqCharacteristics->subSeqId > 65535)
+ return(HANTRO_NOK);
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSubSeqCharacteristics->durationFlag = tmp == 1 ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ if (pSubSeqCharacteristics->durationFlag)
+ {
+ pSubSeqCharacteristics->subSeqDuration = h264bsdShowBits32(pStrmData);
+ if (h264bsdFlushBits(pStrmData,32) == END_OF_STREAM)
+ return(HANTRO_NOK);
+ }
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSubSeqCharacteristics->averageRateFlag = tmp == 1 ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ if (pSubSeqCharacteristics->averageRateFlag)
+ {
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSubSeqCharacteristics->accurateStatisticsFlag =
+ tmp == 1 ? HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdGetBits(pStrmData, 16);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSubSeqCharacteristics->averageBitRate = tmp;
+
+ tmp = h264bsdGetBits(pStrmData, 16);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSubSeqCharacteristics->averageFrameRate = tmp;
+ }
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSubSeqCharacteristics->numReferencedSubseqs);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pSubSeqCharacteristics->numReferencedSubseqs > MAX_NUM_SUB_SEQ_LAYERS-1)
+ return(HANTRO_NOK);
+
+ for (i = 0; i < pSubSeqCharacteristics->numReferencedSubseqs; i++)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSubSeqCharacteristics->refSubSeqLayerNum[i]);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSubSeqCharacteristics->refSubSeqId[i]);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSubSeqCharacteristics->refSubSeqDirection[i] = tmp;
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeFullFrameFreeze
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+------------------------------------------------------------------------------*/
+
+static u32 DecodeFullFrameFreeze(
+ strmData_t *pStrmData,
+ seiFullFrameFreeze_t *pFullFrameFreeze)
+{
+
+/* Variables */
+
+ u32 tmp;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pFullFrameFreeze);
+
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pFullFrameFreeze->fullFrameFreezeRepetitionPeriod);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pFullFrameFreeze->fullFrameFreezeRepetitionPeriod > 16384)
+ return(HANTRO_NOK);
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeFullFrameSnapshot
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+------------------------------------------------------------------------------*/
+
+static u32 DecodeFullFrameSnapshot(
+ strmData_t *pStrmData,
+ seiFullFrameSnapshot_t *pFullFrameSnapshot)
+{
+
+/* Variables */
+
+ u32 tmp;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pFullFrameSnapshot);
+
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pFullFrameSnapshot->snapShotId);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeProgressiveRefinementSegmentStart
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+------------------------------------------------------------------------------*/
+
+static u32 DecodeProgressiveRefinementSegmentStart(
+ strmData_t *pStrmData,
+ seiProgressiveRefinementSegmentStart_t *pProgressiveRefinementSegmentStart)
+{
+
+/* Variables */
+
+ u32 tmp;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pProgressiveRefinementSegmentStart);
+
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pProgressiveRefinementSegmentStart->progressiveRefinementId);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pProgressiveRefinementSegmentStart->numRefinementSteps);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pProgressiveRefinementSegmentStart->numRefinementSteps++;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeProgressiveRefinementSegmentEnd
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+------------------------------------------------------------------------------*/
+
+static u32 DecodeProgressiveRefinementSegmentEnd(
+ strmData_t *pStrmData,
+ seiProgressiveRefinementSegmentEnd_t *pProgressiveRefinementSegmentEnd)
+{
+
+/* Variables */
+
+ u32 tmp;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pProgressiveRefinementSegmentEnd);
+
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pProgressiveRefinementSegmentEnd->progressiveRefinementId);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeMotionConstrainedSliceGroupSet
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+------------------------------------------------------------------------------*/
+
+static u32 DecodeMotionConstrainedSliceGroupSet(
+ strmData_t *pStrmData,
+ seiMotionConstrainedSliceGroupSet_t *pMotionConstrainedSliceGroupSet,
+ u32 numSliceGroups)
+{
+
+/* Variables */
+
+ u32 tmp,i;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pMotionConstrainedSliceGroupSet);
+ ASSERT(numSliceGroups < MAX_NUM_SLICE_GROUPS);
+
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pMotionConstrainedSliceGroupSet->numSliceGroupsInSet);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pMotionConstrainedSliceGroupSet->numSliceGroupsInSet++;
+ if (pMotionConstrainedSliceGroupSet->numSliceGroupsInSet > numSliceGroups)
+ return(HANTRO_NOK);
+
+ for (i = 0; i < pMotionConstrainedSliceGroupSet->numSliceGroupsInSet; i++)
+ {
+ tmp = h264bsdGetBits(pStrmData,
+ ceilLog2NumSliceGroups[numSliceGroups]);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pMotionConstrainedSliceGroupSet->sliceGroupId[i] = tmp;
+ if (pMotionConstrainedSliceGroupSet->sliceGroupId[i] >
+ pMotionConstrainedSliceGroupSet->numSliceGroupsInSet-1)
+ return(HANTRO_NOK);
+ }
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pMotionConstrainedSliceGroupSet->exactSampleValueMatchFlag =
+ tmp == 1 ? HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pMotionConstrainedSliceGroupSet->panScanRectFlag = tmp == 1 ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ if (pMotionConstrainedSliceGroupSet->panScanRectFlag)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pMotionConstrainedSliceGroupSet->panScanRectId);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeReservedSeiMessage
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+------------------------------------------------------------------------------*/
+
+static u32 DecodeReservedSeiMessage(
+ strmData_t *pStrmData,
+ seiReservedSeiMessage_t *pReservedSeiMessage,
+ u32 payloadSize)
+{
+
+/* Variables */
+
+ u32 i, tmp;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pReservedSeiMessage);
+
+
+ /* where corresponding FREE() ??? */
+ ALLOCATE(pReservedSeiMessage->reservedSeiMessagePayloadByte,payloadSize,u8);
+ if (pReservedSeiMessage->reservedSeiMessagePayloadByte == NULL)
+ return(MEMORY_ALLOCATION_ERROR);
+
+ pReservedSeiMessage->numPayloadBytes = payloadSize;
+
+ for (i = 0; i < payloadSize; i++)
+ {
+ tmp = h264bsdGetBits(pStrmData,8);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pReservedSeiMessage->reservedSeiMessagePayloadByte[i] = (u8)tmp;
+ }
+
+ return(HANTRO_OK);
+
+}
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_sei.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_sei.h
new file mode 100755
index 0000000..efe543a
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_sei.h
@@ -0,0 +1,252 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_SEI_H
+#define H264SWDEC_SEI_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_stream.h"
+#include "h264bsd_slice_header.h"
+#include "h264bsd_seq_param_set.h"
+#include "h264bsd_vui.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+#define MAX_PAN_SCAN_CNT 32
+#define MAX_NUM_SPARE_PICS 16
+#define MAX_NUM_CLOCK_TS 3
+#define MAX_NUM_SUB_SEQ_LAYERS 256
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+typedef struct
+{
+ u32 seqParameterSetId;
+ u32 initialCpbRemovalDelay[MAX_CPB_CNT];
+ u32 initialCpbRemovalDelayOffset[MAX_CPB_CNT];
+} seiBufferingPeriod_t;
+
+typedef struct
+{
+ u32 cpbRemovalDelay;
+ u32 dpbOutputDelay;
+ u32 picStruct;
+ u32 clockTimeStampFlag[MAX_NUM_CLOCK_TS];
+ u32 clockTimeStamp[MAX_NUM_CLOCK_TS];
+ u32 ctType[MAX_NUM_CLOCK_TS];
+ u32 nuitFieldBasedFlag[MAX_NUM_CLOCK_TS];
+ u32 countingType[MAX_NUM_CLOCK_TS];
+ u32 fullTimeStampFlag[MAX_NUM_CLOCK_TS];
+ u32 discontinuityFlag[MAX_NUM_CLOCK_TS];
+ u32 cntDroppedFlag[MAX_NUM_CLOCK_TS];
+ u32 nFrames[MAX_NUM_CLOCK_TS];
+ u32 secondsFlag[MAX_NUM_CLOCK_TS];
+ u32 secondsValue[MAX_NUM_CLOCK_TS];
+ u32 minutesFlag[MAX_NUM_CLOCK_TS];
+ u32 minutesValue[MAX_NUM_CLOCK_TS];
+ u32 hoursFlag[MAX_NUM_CLOCK_TS];
+ u32 hoursValue[MAX_NUM_CLOCK_TS];
+ i32 timeOffset[MAX_NUM_CLOCK_TS];
+} seiPicTiming_t;
+
+typedef struct
+{
+ u32 panScanRectId;
+ u32 panScanRectCancelFlag;
+ u32 panScanCnt;
+ i32 panScanRectLeftOffset[MAX_PAN_SCAN_CNT];
+ i32 panScanRectRightOffset[MAX_PAN_SCAN_CNT];
+ i32 panScanRectTopOffset[MAX_PAN_SCAN_CNT];
+ i32 panScanRectBottomOffset[MAX_PAN_SCAN_CNT];
+ u32 panScanRectRepetitionPeriod;
+} seiPanScanRect_t;
+
+typedef struct
+{
+ u32 ituTT35CountryCode;
+ u32 ituTT35CountryCodeExtensionByte;
+ u8 *ituTT35PayloadByte;
+ u32 numPayloadBytes;
+} seiUserDataRegisteredItuTT35_t;
+
+typedef struct
+{
+ u32 uuidIsoIec11578[4];
+ u8 *userDataPayloadByte;
+ u32 numPayloadBytes;
+} seiUserDataUnregistered_t;
+
+typedef struct
+{
+ u32 recoveryFrameCnt;
+ u32 exactMatchFlag;
+ u32 brokenLinkFlag;
+ u32 changingSliceGroupIdc;
+} seiRecoveryPoint_t;
+
+typedef struct
+{
+ u32 originalIdrFlag;
+ u32 originalFrameNum;
+ decRefPicMarking_t decRefPicMarking;
+} seiDecRefPicMarkingRepetition_t;
+
+typedef struct
+{
+ u32 targetFrameNum;
+ u32 spareFieldFlag;
+ u32 targetBottomFieldFlag;
+ u32 numSparePics;
+ u32 deltaSpareFrameNum[MAX_NUM_SPARE_PICS];
+ u32 spareBottomFieldFlag[MAX_NUM_SPARE_PICS];
+ u32 spareAreaIdc[MAX_NUM_SPARE_PICS];
+ u32 *spareUnitFlag[MAX_NUM_SPARE_PICS];
+ u32 *zeroRunLength[MAX_NUM_SPARE_PICS];
+} seiSparePic_t;
+
+typedef struct
+{
+ u32 sceneInfoPresentFlag;
+ u32 sceneId;
+ u32 sceneTransitionType;
+ u32 secondSceneId;
+} seiSceneInfo_t;
+
+typedef struct
+{
+ u32 subSeqLayerNum;
+ u32 subSeqId;
+ u32 firstRefPicFlag;
+ u32 leadingNonRefPicFlag;
+ u32 lastPicFlag;
+ u32 subSeqFrameNumFlag;
+ u32 subSeqFrameNum;
+} seiSubSeqInfo_t;
+
+typedef struct
+{
+ u32 numSubSeqLayers;
+ u32 accurateStatisticsFlag[MAX_NUM_SUB_SEQ_LAYERS];
+ u32 averageBitRate[MAX_NUM_SUB_SEQ_LAYERS];
+ u32 averageFrameRate[MAX_NUM_SUB_SEQ_LAYERS];
+} seiSubSeqLayerCharacteristics_t;
+
+typedef struct
+{
+ u32 subSeqLayerNum;
+ u32 subSeqId;
+ u32 durationFlag;
+ u32 subSeqDuration;
+ u32 averageRateFlag;
+ u32 accurateStatisticsFlag;
+ u32 averageBitRate;
+ u32 averageFrameRate;
+ u32 numReferencedSubseqs;
+ u32 refSubSeqLayerNum[MAX_NUM_SUB_SEQ_LAYERS];
+ u32 refSubSeqId[MAX_NUM_SUB_SEQ_LAYERS];
+ u32 refSubSeqDirection[MAX_NUM_SUB_SEQ_LAYERS];
+} seiSubSeqCharacteristics_t;
+
+typedef struct
+{
+ u32 fullFrameFreezeRepetitionPeriod;
+} seiFullFrameFreeze_t;
+
+typedef struct
+{
+ u32 snapShotId;
+} seiFullFrameSnapshot_t;
+
+typedef struct
+{
+ u32 progressiveRefinementId;
+ u32 numRefinementSteps;
+} seiProgressiveRefinementSegmentStart_t;
+
+typedef struct
+{
+ u32 progressiveRefinementId;
+} seiProgressiveRefinementSegmentEnd_t;
+
+typedef struct
+{
+ u32 numSliceGroupsInSet;
+ u32 sliceGroupId[MAX_NUM_SLICE_GROUPS];
+ u32 exactSampleValueMatchFlag;
+ u32 panScanRectFlag;
+ u32 panScanRectId;
+} seiMotionConstrainedSliceGroupSet_t;
+
+typedef struct
+{
+ u8 *reservedSeiMessagePayloadByte;
+ u32 numPayloadBytes;
+} seiReservedSeiMessage_t;
+
+typedef struct
+{
+ u32 payloadType;
+ seiBufferingPeriod_t bufferingPeriod;
+ seiPicTiming_t picTiming;
+ seiPanScanRect_t panScanRect;
+ seiUserDataRegisteredItuTT35_t userDataRegisteredItuTT35;
+ seiUserDataUnregistered_t userDataUnregistered;
+ seiRecoveryPoint_t recoveryPoint;
+ seiDecRefPicMarkingRepetition_t decRefPicMarkingRepetition;
+ seiSparePic_t sparePic;
+ seiSceneInfo_t sceneInfo;
+ seiSubSeqInfo_t subSeqInfo;
+ seiSubSeqLayerCharacteristics_t subSeqLayerCharacteristics;
+ seiSubSeqCharacteristics_t subSeqCharacteristics;
+ seiFullFrameFreeze_t fullFrameFreeze;
+ seiFullFrameSnapshot_t fullFrameSnapshot;
+ seiProgressiveRefinementSegmentStart_t progressiveRefinementSegmentStart;
+ seiProgressiveRefinementSegmentEnd_t progressiveRefinementSegmentEnd;
+ seiMotionConstrainedSliceGroupSet_t motionConstrainedSliceGroupSet;
+ seiReservedSeiMessage_t reservedSeiMessage;
+} seiMessage_t;
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeSeiMessage(
+ strmData_t *pStrmData,
+ seqParamSet_t *pSeqParamSet,
+ seiMessage_t *pSeiMessage,
+ u32 numSliceGroups);
+
+#endif /* #ifdef H264SWDEC_SEI_H */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_seq_param_set.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_seq_param_set.c
new file mode 100644
index 0000000..751051a
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_seq_param_set.c
@@ -0,0 +1,577 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdDecodeSeqParamSet
+ GetDpbSize
+ h264bsdCompareSeqParamSets
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_seq_param_set.h"
+#include "h264bsd_util.h"
+#include "h264bsd_vlc.h"
+#include "h264bsd_vui.h"
+#include "h264bsd_cfg.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/* enumeration to indicate invalid return value from the GetDpbSize function */
+enum {INVALID_DPB_SIZE = 0x7FFFFFFF};
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+static u32 GetDpbSize(u32 picSizeInMbs, u32 levelIdc);
+
+/*------------------------------------------------------------------------------
+
+ Function name: h264bsdDecodeSeqParamSet
+
+ Functional description:
+ Decode sequence parameter set information from the stream.
+
+ Function allocates memory for offsetForRefFrame array if
+ picture order count type is 1 and numRefFramesInPicOrderCntCycle
+ is greater than zero.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+
+ Outputs:
+ pSeqParamSet decoded information is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK failure, invalid information or end of stream
+ MEMORY_ALLOCATION_ERROR for memory allocation failure
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeSeqParamSet(strmData_t *pStrmData, seqParamSet_t *pSeqParamSet)
+{
+
+/* Variables */
+
+ u32 tmp, i, value;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pSeqParamSet);
+
+ H264SwDecMemset(pSeqParamSet, 0, sizeof(seqParamSet_t));
+
+ /* profile_idc */
+ tmp = h264bsdGetBits(pStrmData, 8);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ if (tmp != 66)
+ {
+ DEBUG(("NOT BASELINE PROFILE %d\n", tmp));
+ }
+ pSeqParamSet->profileIdc = tmp;
+
+ /* constrained_set0_flag */
+ tmp = h264bsdGetBits(pStrmData, 1);
+ /* constrained_set1_flag */
+ tmp = h264bsdGetBits(pStrmData, 1);
+ /* constrained_set2_flag */
+ tmp = h264bsdGetBits(pStrmData, 1);
+
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+
+ /* reserved_zero_5bits, values of these bits shall be ignored */
+ tmp = h264bsdGetBits(pStrmData, 5);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+
+ tmp = h264bsdGetBits(pStrmData, 8);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSeqParamSet->levelIdc = tmp;
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSeqParamSet->seqParameterSetId);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pSeqParamSet->seqParameterSetId >= MAX_NUM_SEQ_PARAM_SETS)
+ {
+ EPRINT("seq_param_set_id");
+ return(HANTRO_NOK);
+ }
+
+ /* log2_max_frame_num_minus4 */
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (value > 12)
+ {
+ EPRINT("log2_max_frame_num_minus4");
+ return(HANTRO_NOK);
+ }
+ /* maxFrameNum = 2^(log2_max_frame_num_minus4 + 4) */
+ pSeqParamSet->maxFrameNum = 1 << (value+4);
+
+ /* valid POC types are 0, 1 and 2 */
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (value > 2)
+ {
+ EPRINT("pic_order_cnt_type");
+ return(HANTRO_NOK);
+ }
+ pSeqParamSet->picOrderCntType = value;
+
+ if (pSeqParamSet->picOrderCntType == 0)
+ {
+ /* log2_max_pic_order_cnt_lsb_minus4 */
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (value > 12)
+ {
+ EPRINT("log2_max_pic_order_cnt_lsb_minus4");
+ return(HANTRO_NOK);
+ }
+ /* maxPicOrderCntLsb = 2^(log2_max_pic_order_cnt_lsb_minus4 + 4) */
+ pSeqParamSet->maxPicOrderCntLsb = 1 << (value+4);
+ }
+ else if (pSeqParamSet->picOrderCntType == 1)
+ {
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSeqParamSet->deltaPicOrderAlwaysZeroFlag = (tmp == 1) ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData,
+ &pSeqParamSet->offsetForNonRefPic);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData,
+ &pSeqParamSet->offsetForTopToBottomField);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSeqParamSet->numRefFramesInPicOrderCntCycle);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pSeqParamSet->numRefFramesInPicOrderCntCycle > 255)
+ {
+ EPRINT("num_ref_frames_in_pic_order_cnt_cycle");
+ return(HANTRO_NOK);
+ }
+
+ if (pSeqParamSet->numRefFramesInPicOrderCntCycle)
+ {
+ /* NOTE: This has to be freed somewhere! */
+ ALLOCATE(pSeqParamSet->offsetForRefFrame,
+ pSeqParamSet->numRefFramesInPicOrderCntCycle, i32);
+ if (pSeqParamSet->offsetForRefFrame == NULL)
+ return(MEMORY_ALLOCATION_ERROR);
+
+ for (i = 0; i < pSeqParamSet->numRefFramesInPicOrderCntCycle; i++)
+ {
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData,
+ pSeqParamSet->offsetForRefFrame + i);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+ }
+ else
+ {
+ pSeqParamSet->offsetForRefFrame = NULL;
+ }
+ }
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSeqParamSet->numRefFrames);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pSeqParamSet->numRefFrames > MAX_NUM_REF_PICS)
+ {
+ EPRINT("num_ref_frames");
+ return(HANTRO_NOK);
+ }
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSeqParamSet->gapsInFrameNumValueAllowedFlag = (tmp == 1) ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pSeqParamSet->picWidthInMbs = value + 1;
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pSeqParamSet->picHeightInMbs = value + 1;
+
+ /* frame_mbs_only_flag, shall be 1 for baseline profile */
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ if (!tmp)
+ {
+ EPRINT("frame_mbs_only_flag");
+ return(HANTRO_NOK);
+ }
+
+ /* direct_8x8_inference_flag */
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSeqParamSet->frameCroppingFlag = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
+
+ if (pSeqParamSet->frameCroppingFlag)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSeqParamSet->frameCropLeftOffset);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSeqParamSet->frameCropRightOffset);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSeqParamSet->frameCropTopOffset);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSeqParamSet->frameCropBottomOffset);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* check that frame cropping params are valid, parameters shall
+ * specify non-negative area within the original picture */
+ if ( ( (i32)pSeqParamSet->frameCropLeftOffset >
+ ( 8 * (i32)pSeqParamSet->picWidthInMbs -
+ ((i32)pSeqParamSet->frameCropRightOffset + 1) ) ) ||
+ ( (i32)pSeqParamSet->frameCropTopOffset >
+ ( 8 * (i32)pSeqParamSet->picHeightInMbs -
+ ((i32)pSeqParamSet->frameCropBottomOffset + 1) ) ) )
+ {
+ EPRINT("frame_cropping");
+ return(HANTRO_NOK);
+ }
+ }
+
+ /* check that image dimensions and levelIdc match */
+ tmp = pSeqParamSet->picWidthInMbs * pSeqParamSet->picHeightInMbs;
+ value = GetDpbSize(tmp, pSeqParamSet->levelIdc);
+ if (value == INVALID_DPB_SIZE || pSeqParamSet->numRefFrames > value)
+ {
+ DEBUG(("WARNING! Invalid DPB size based on SPS Level!\n"));
+ DEBUG(("WARNING! Using num_ref_frames =%d for DPB size!\n",
+ pSeqParamSet->numRefFrames));
+ value = pSeqParamSet->numRefFrames;
+ }
+ pSeqParamSet->maxDpbSize = value;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSeqParamSet->vuiParametersPresentFlag = (tmp == 1) ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ /* VUI */
+ if (pSeqParamSet->vuiParametersPresentFlag)
+ {
+ ALLOCATE(pSeqParamSet->vuiParameters, 1, vuiParameters_t);
+ if (pSeqParamSet->vuiParameters == NULL)
+ return(MEMORY_ALLOCATION_ERROR);
+ tmp = h264bsdDecodeVuiParameters(pStrmData,
+ pSeqParamSet->vuiParameters);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ /* check numReorderFrames and maxDecFrameBuffering */
+ if (pSeqParamSet->vuiParameters->bitstreamRestrictionFlag)
+ {
+ if (pSeqParamSet->vuiParameters->numReorderFrames >
+ pSeqParamSet->vuiParameters->maxDecFrameBuffering ||
+ pSeqParamSet->vuiParameters->maxDecFrameBuffering <
+ pSeqParamSet->numRefFrames ||
+ pSeqParamSet->vuiParameters->maxDecFrameBuffering >
+ pSeqParamSet->maxDpbSize)
+ {
+ return(HANTRO_NOK);
+ }
+
+ /* standard says that "the sequence shall not require a DPB with
+ * size of more than max(1, maxDecFrameBuffering) */
+ pSeqParamSet->maxDpbSize =
+ MAX(1, pSeqParamSet->vuiParameters->maxDecFrameBuffering);
+ }
+ }
+
+ tmp = h264bsdRbspTrailingBits(pStrmData);
+
+ /* ignore possible errors in trailing bits of parameters sets */
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: GetDpbSize
+
+ Functional description:
+ Get size of the DPB in frames. Size is determined based on the
+ picture size and MaxDPB for the specified level. These determine
+ how many pictures may fit into to the buffer. However, the size
+ is also limited to a maximum of 16 frames and therefore function
+ returns the minimum of the determined size and 16.
+
+ Inputs:
+ picSizeInMbs number of macroblocks in the picture
+ levelIdc indicates the level
+
+ Outputs:
+ none
+
+ Returns:
+ size of the DPB in frames
+ INVALID_DPB_SIZE when invalid levelIdc specified or picSizeInMbs
+ is higher than supported by the level in question
+
+------------------------------------------------------------------------------*/
+
+u32 GetDpbSize(u32 picSizeInMbs, u32 levelIdc)
+{
+
+/* Variables */
+
+ u32 tmp;
+ u32 maxPicSizeInMbs;
+
+/* Code */
+
+ ASSERT(picSizeInMbs);
+
+ /* use tmp as the size of the DPB in bytes, computes as 1024 * MaxDPB
+ * (from table A-1 in Annex A) */
+ switch (levelIdc)
+ {
+ case 10:
+ tmp = 152064;
+ maxPicSizeInMbs = 99;
+ break;
+
+ case 11:
+ tmp = 345600;
+ maxPicSizeInMbs = 396;
+ break;
+
+ case 12:
+ tmp = 912384;
+ maxPicSizeInMbs = 396;
+ break;
+
+ case 13:
+ tmp = 912384;
+ maxPicSizeInMbs = 396;
+ break;
+
+ case 20:
+ tmp = 912384;
+ maxPicSizeInMbs = 396;
+ break;
+
+ case 21:
+ tmp = 1824768;
+ maxPicSizeInMbs = 792;
+ break;
+
+ case 22:
+ tmp = 3110400;
+ maxPicSizeInMbs = 1620;
+ break;
+
+ case 30:
+ tmp = 3110400;
+ maxPicSizeInMbs = 1620;
+ break;
+
+ case 31:
+ tmp = 6912000;
+ maxPicSizeInMbs = 3600;
+ break;
+
+ case 32:
+ tmp = 7864320;
+ maxPicSizeInMbs = 5120;
+ break;
+
+ case 40:
+ tmp = 12582912;
+ maxPicSizeInMbs = 8192;
+ break;
+
+ case 41:
+ tmp = 12582912;
+ maxPicSizeInMbs = 8192;
+ break;
+
+ case 42:
+ tmp = 34816*384;
+ maxPicSizeInMbs = 8704;
+ break;
+
+ case 50:
+ /* standard says 42301440 here, but corrigendum "corrects" this to
+ * 42393600 */
+ tmp = 42393600;
+ maxPicSizeInMbs = 22080;
+ break;
+
+ case 51:
+ tmp = 70778880;
+ maxPicSizeInMbs = 36864;
+ break;
+
+ default:
+ return(INVALID_DPB_SIZE);
+ }
+
+ /* this is not "correct" return value! However, it results in error in
+ * decoding and this was easiest place to check picture size */
+ if (picSizeInMbs > maxPicSizeInMbs)
+ return(INVALID_DPB_SIZE);
+
+ tmp /= (picSizeInMbs*384);
+
+ return(MIN(tmp, 16));
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function name: h264bsdCompareSeqParamSets
+
+ Functional description:
+ Compare two sequence parameter sets.
+
+ Inputs:
+ pSps1 pointer to a sequence parameter set
+ pSps2 pointer to another sequence parameter set
+
+ Outputs:
+ 0 sequence parameter sets are equal
+ 1 otherwise
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdCompareSeqParamSets(seqParamSet_t *pSps1, seqParamSet_t *pSps2)
+{
+
+/* Variables */
+
+ u32 i;
+
+/* Code */
+
+ ASSERT(pSps1);
+ ASSERT(pSps2);
+
+ /* first compare parameters whose existence does not depend on other
+ * parameters and only compare the rest of the params if these are equal */
+ if (pSps1->profileIdc == pSps2->profileIdc &&
+ pSps1->levelIdc == pSps2->levelIdc &&
+ pSps1->maxFrameNum == pSps2->maxFrameNum &&
+ pSps1->picOrderCntType == pSps2->picOrderCntType &&
+ pSps1->numRefFrames == pSps2->numRefFrames &&
+ pSps1->gapsInFrameNumValueAllowedFlag ==
+ pSps2->gapsInFrameNumValueAllowedFlag &&
+ pSps1->picWidthInMbs == pSps2->picWidthInMbs &&
+ pSps1->picHeightInMbs == pSps2->picHeightInMbs &&
+ pSps1->frameCroppingFlag == pSps2->frameCroppingFlag &&
+ pSps1->vuiParametersPresentFlag == pSps2->vuiParametersPresentFlag)
+ {
+ if (pSps1->picOrderCntType == 0)
+ {
+ if (pSps1->maxPicOrderCntLsb != pSps2->maxPicOrderCntLsb)
+ return 1;
+ }
+ else if (pSps1->picOrderCntType == 1)
+ {
+ if (pSps1->deltaPicOrderAlwaysZeroFlag !=
+ pSps2->deltaPicOrderAlwaysZeroFlag ||
+ pSps1->offsetForNonRefPic != pSps2->offsetForNonRefPic ||
+ pSps1->offsetForTopToBottomField !=
+ pSps2->offsetForTopToBottomField ||
+ pSps1->numRefFramesInPicOrderCntCycle !=
+ pSps2->numRefFramesInPicOrderCntCycle)
+ {
+ return 1;
+ }
+ else
+ {
+ for (i = 0; i < pSps1->numRefFramesInPicOrderCntCycle; i++)
+ if (pSps1->offsetForRefFrame[i] !=
+ pSps2->offsetForRefFrame[i])
+ {
+ return 1;
+ }
+ }
+ }
+ if (pSps1->frameCroppingFlag)
+ {
+ if (pSps1->frameCropLeftOffset != pSps2->frameCropLeftOffset ||
+ pSps1->frameCropRightOffset != pSps2->frameCropRightOffset ||
+ pSps1->frameCropTopOffset != pSps2->frameCropTopOffset ||
+ pSps1->frameCropBottomOffset != pSps2->frameCropBottomOffset)
+ {
+ return 1;
+ }
+ }
+
+ return 0;
+ }
+
+ return 1;
+}
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_seq_param_set.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_seq_param_set.h
new file mode 100755
index 0000000..e18df94
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_seq_param_set.h
@@ -0,0 +1,86 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_SEQ_PARAM_SET_H
+#define H264SWDEC_SEQ_PARAM_SET_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_stream.h"
+#include "h264bsd_vui.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+/* structure to store sequence parameter set information decoded from the
+ * stream */
+typedef struct
+{
+ u32 profileIdc;
+ u32 levelIdc;
+ u32 seqParameterSetId;
+ u32 maxFrameNum;
+ u32 picOrderCntType;
+ u32 maxPicOrderCntLsb;
+ u32 deltaPicOrderAlwaysZeroFlag;
+ i32 offsetForNonRefPic;
+ i32 offsetForTopToBottomField;
+ u32 numRefFramesInPicOrderCntCycle;
+ i32 *offsetForRefFrame;
+ u32 numRefFrames;
+ u32 gapsInFrameNumValueAllowedFlag;
+ u32 picWidthInMbs;
+ u32 picHeightInMbs;
+ u32 frameCroppingFlag;
+ u32 frameCropLeftOffset;
+ u32 frameCropRightOffset;
+ u32 frameCropTopOffset;
+ u32 frameCropBottomOffset;
+ u32 vuiParametersPresentFlag;
+ vuiParameters_t *vuiParameters;
+ u32 maxDpbSize;
+} seqParamSet_t;
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeSeqParamSet(strmData_t *pStrmData,
+ seqParamSet_t *pSeqParamSet);
+
+u32 h264bsdCompareSeqParamSets(seqParamSet_t *pSps1, seqParamSet_t *pSps2);
+
+#endif /* #ifdef H264SWDEC_SEQ_PARAM_SET_H */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_data.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_data.c
new file mode 100755
index 0000000..c288d4b
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_data.c
@@ -0,0 +1,354 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdDecodeSliceData
+ SetMbParams
+ h264bsdMarkSliceCorrupted
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_slice_data.h"
+#include "h264bsd_util.h"
+#include "h264bsd_vlc.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+static void SetMbParams(mbStorage_t *pMb, sliceHeader_t *pSlice, u32 sliceId,
+ i32 chromaQpIndexOffset);
+
+/*------------------------------------------------------------------------------
+
+ 5.1 Function name: h264bsdDecodeSliceData
+
+ Functional description:
+ Decode one slice. Function decodes stream data, i.e. macroblocks
+ and possible skip_run fields. h264bsdDecodeMacroblock function is
+ called to handle all other macroblock related processing.
+ Macroblock to slice group mapping is considered when next
+ macroblock to process is determined (h264bsdNextMbAddress function)
+ map
+
+ Inputs:
+ pStrmData pointer to stream data structure
+ pStorage pointer to storage structure
+ currImage pointer to current processed picture, needed for
+ intra prediction of the macroblocks
+ pSliceHeader pointer to slice header of the current slice
+
+ Outputs:
+ currImage processed macroblocks are written to current image
+ pStorage mbStorage structure of each processed macroblock
+ is updated here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK invalid stream data
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeSliceData(strmData_t *pStrmData, storage_t *pStorage,
+ image_t *currImage, sliceHeader_t *pSliceHeader)
+{
+
+/* Variables */
+
+ u8 mbData[384 + 15 + 32];
+ u8 *data;
+ u32 tmp;
+ u32 skipRun;
+ u32 prevSkipped;
+ u32 currMbAddr;
+ u32 moreMbs;
+ u32 mbCount;
+ i32 qpY;
+ macroblockLayer_t *mbLayer;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pSliceHeader);
+ ASSERT(pStorage);
+ ASSERT(pSliceHeader->firstMbInSlice < pStorage->picSizeInMbs);
+
+ /* ensure 16-byte alignment */
+ data = (u8*)ALIGN(mbData, 16);
+
+ mbLayer = pStorage->mbLayer;
+
+ currMbAddr = pSliceHeader->firstMbInSlice;
+ skipRun = 0;
+ prevSkipped = HANTRO_FALSE;
+
+ /* increment slice index, will be one for decoding of the first slice of
+ * the picture */
+ pStorage->slice->sliceId++;
+
+ /* lastMbAddr stores address of the macroblock that was last successfully
+ * decoded, needed for error handling */
+ pStorage->slice->lastMbAddr = 0;
+
+ mbCount = 0;
+ /* initial quantization parameter for the slice is obtained as the sum of
+ * initial QP for the picture and sliceQpDelta for the current slice */
+ qpY = (i32)pStorage->activePps->picInitQp + pSliceHeader->sliceQpDelta;
+ do
+ {
+ /* primary picture and already decoded macroblock -> error */
+ if (!pSliceHeader->redundantPicCnt && pStorage->mb[currMbAddr].decoded)
+ {
+ EPRINT("Primary and already decoded");
+ return(HANTRO_NOK);
+ }
+
+ SetMbParams(pStorage->mb + currMbAddr, pSliceHeader,
+ pStorage->slice->sliceId, pStorage->activePps->chromaQpIndexOffset);
+
+ if (!IS_I_SLICE(pSliceHeader->sliceType))
+ {
+ if (!prevSkipped)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &skipRun);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ /* skip_run shall be less than or equal to number of
+ * macroblocks left */
+ if (skipRun > (pStorage->picSizeInMbs - currMbAddr))
+ {
+ EPRINT("skip_run");
+ return(HANTRO_NOK);
+ }
+ if (skipRun)
+ {
+ prevSkipped = HANTRO_TRUE;
+ H264SwDecMemset(&mbLayer->mbPred, 0, sizeof(mbPred_t));
+ /* mark current macroblock skipped */
+ mbLayer->mbType = P_Skip;
+ }
+ }
+ }
+
+ if (skipRun)
+ {
+ DEBUG(("Skipping macroblock %d\n", currMbAddr));
+ skipRun--;
+ }
+ else
+ {
+ prevSkipped = HANTRO_FALSE;
+ tmp = h264bsdDecodeMacroblockLayer(pStrmData, mbLayer,
+ pStorage->mb + currMbAddr, pSliceHeader->sliceType,
+ pSliceHeader->numRefIdxL0Active);
+ if (tmp != HANTRO_OK)
+ {
+ EPRINT("macroblock_layer");
+ return(tmp);
+ }
+ }
+
+ tmp = h264bsdDecodeMacroblock(pStorage->mb + currMbAddr, mbLayer,
+ currImage, pStorage->dpb, &qpY, currMbAddr,
+ pStorage->activePps->constrainedIntraPredFlag, data);
+ if (tmp != HANTRO_OK)
+ {
+ EPRINT("MACRO_BLOCK");
+ return(tmp);
+ }
+
+ /* increment macroblock count only for macroblocks that were decoded
+ * for the first time (redundant slices) */
+ if (pStorage->mb[currMbAddr].decoded == 1)
+ mbCount++;
+
+ /* keep on processing as long as there is stream data left or
+ * processing of macroblocks to be skipped based on the last skipRun is
+ * not finished */
+ moreMbs = (h264bsdMoreRbspData(pStrmData) || skipRun) ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ /* lastMbAddr is only updated for intra slices (all macroblocks of
+ * inter slices will be lost in case of an error) */
+ if (IS_I_SLICE(pSliceHeader->sliceType))
+ pStorage->slice->lastMbAddr = currMbAddr;
+
+ currMbAddr = h264bsdNextMbAddress(pStorage->sliceGroupMap,
+ pStorage->picSizeInMbs, currMbAddr);
+ /* data left in the buffer but no more macroblocks for current slice
+ * group -> error */
+ if (moreMbs && !currMbAddr)
+ {
+ EPRINT("Next mb address");
+ return(HANTRO_NOK);
+ }
+
+ } while (moreMbs);
+
+ if ((pStorage->slice->numDecodedMbs + mbCount) > pStorage->picSizeInMbs)
+ {
+ EPRINT("Num decoded mbs");
+ return(HANTRO_NOK);
+ }
+
+ pStorage->slice->numDecodedMbs += mbCount;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ 5.2 Function: SetMbParams
+
+ Functional description:
+ Set macroblock parameters that remain constant for this slice
+
+ Inputs:
+ pSlice pointer to current slice header
+ sliceId id of the current slice
+ chromaQpIndexOffset
+
+ Outputs:
+ pMb pointer to macroblock structure which is updated
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+void SetMbParams(mbStorage_t *pMb, sliceHeader_t *pSlice, u32 sliceId,
+ i32 chromaQpIndexOffset)
+{
+
+/* Variables */
+ u32 tmp1;
+ i32 tmp2, tmp3;
+
+/* Code */
+
+ tmp1 = pSlice->disableDeblockingFilterIdc;
+ tmp2 = pSlice->sliceAlphaC0Offset;
+ tmp3 = pSlice->sliceBetaOffset;
+ pMb->sliceId = sliceId;
+ pMb->disableDeblockingFilterIdc = tmp1;
+ pMb->filterOffsetA = tmp2;
+ pMb->filterOffsetB = tmp3;
+ pMb->chromaQpIndexOffset = chromaQpIndexOffset;
+
+}
+
+/*------------------------------------------------------------------------------
+
+ 5.3 Function name: h264bsdMarkSliceCorrupted
+
+ Functional description:
+ Mark macroblocks of the slice corrupted. If lastMbAddr in the slice
+ storage is set -> picWidhtInMbs (or at least 10) macroblocks back
+ from the lastMbAddr are marked corrupted. However, if lastMbAddr
+ is not set -> all macroblocks of the slice are marked.
+
+ Inputs:
+ pStorage pointer to storage structure
+ firstMbInSlice address of the first macroblock in the slice, this
+ identifies the slice to be marked corrupted
+
+ Outputs:
+ pStorage mbStorage for the corrupted macroblocks updated
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+void h264bsdMarkSliceCorrupted(storage_t *pStorage, u32 firstMbInSlice)
+{
+
+/* Variables */
+
+ u32 tmp, i;
+ u32 sliceId;
+ u32 currMbAddr;
+
+/* Code */
+
+ ASSERT(pStorage);
+ ASSERT(firstMbInSlice < pStorage->picSizeInMbs);
+
+ currMbAddr = firstMbInSlice;
+
+ sliceId = pStorage->slice->sliceId;
+
+ /* DecodeSliceData sets lastMbAddr for I slices -> if it was set, go back
+ * MAX(picWidthInMbs, 10) macroblocks and start marking from there */
+ if (pStorage->slice->lastMbAddr)
+ {
+ ASSERT(pStorage->mb[pStorage->slice->lastMbAddr].sliceId == sliceId);
+ i = pStorage->slice->lastMbAddr - 1;
+ tmp = 0;
+ while (i > currMbAddr)
+ {
+ if (pStorage->mb[i].sliceId == sliceId)
+ {
+ tmp++;
+ if (tmp >= MAX(pStorage->activeSps->picWidthInMbs, 10))
+ break;
+ }
+ i--;
+ }
+ currMbAddr = i;
+ }
+
+ do
+ {
+
+ if ( (pStorage->mb[currMbAddr].sliceId == sliceId) &&
+ (pStorage->mb[currMbAddr].decoded) )
+ {
+ pStorage->mb[currMbAddr].decoded--;
+ }
+ else
+ {
+ break;
+ }
+
+ currMbAddr = h264bsdNextMbAddress(pStorage->sliceGroupMap,
+ pStorage->picSizeInMbs, currMbAddr);
+
+ } while (currMbAddr);
+
+}
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_data.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_data.h
new file mode 100755
index 0000000..f23d49e
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_data.h
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_SLICE_DATA_H
+#define H264SWDEC_SLICE_DATA_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_stream.h"
+#include "h264bsd_cfg.h"
+#include "h264bsd_slice_header.h"
+#include "h264bsd_storage.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeSliceData(strmData_t *pStrmData, storage_t *pStorage,
+ image_t *currImage, sliceHeader_t *pSliceHeader);
+
+void h264bsdMarkSliceCorrupted(storage_t *pStorage, u32 firstMbInSlice);
+
+#endif /* #ifdef H264SWDEC_SLICE_DATA_H */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_group_map.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_group_map.c
new file mode 100755
index 0000000..7cbb534
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_group_map.c
@@ -0,0 +1,589 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ DecodeInterleavedMap
+ DecodeDispersedMap
+ DecodeForegroundLeftOverMap
+ DecodeBoxOutMap
+ DecodeRasterScanMap
+ DecodeWipeMap
+ h264bsdDecodeSliceGroupMap
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_slice_group_map.h"
+#include "h264bsd_cfg.h"
+#include "h264bsd_pic_param_set.h"
+#include "h264bsd_util.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+static void DecodeInterleavedMap(
+ u32 *map,
+ u32 numSliceGroups,
+ u32 *runLength,
+ u32 picSize);
+
+static void DecodeDispersedMap(
+ u32 *map,
+ u32 numSliceGroups,
+ u32 picWidth,
+ u32 picHeight);
+
+static void DecodeForegroundLeftOverMap(
+ u32 *map,
+ u32 numSliceGroups,
+ u32 *topLeft,
+ u32 *bottomRight,
+ u32 picWidth,
+ u32 picHeight);
+
+static void DecodeBoxOutMap(
+ u32 *map,
+ u32 sliceGroupChangeDirectionFlag,
+ u32 unitsInSliceGroup0,
+ u32 picWidth,
+ u32 picHeight);
+
+static void DecodeRasterScanMap(
+ u32 *map,
+ u32 sliceGroupChangeDirectionFlag,
+ u32 sizeOfUpperLeftGroup,
+ u32 picSize);
+
+static void DecodeWipeMap(
+ u32 *map,
+ u32 sliceGroupChangeDirectionFlag,
+ u32 sizeOfUpperLeftGroup,
+ u32 picWidth,
+ u32 picHeight);
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeInterleavedMap
+
+ Functional description:
+ Function to decode interleaved slice group map type, i.e. slice
+ group map type 0.
+
+ Inputs:
+ map pointer to the map
+ numSliceGroups number of slice groups
+ runLength run_length[] values for each slice group
+ picSize picture size in macroblocks
+
+ Outputs:
+ map slice group map is stored here
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+void DecodeInterleavedMap(
+ u32 *map,
+ u32 numSliceGroups,
+ u32 *runLength,
+ u32 picSize)
+{
+
+/* Variables */
+
+ u32 i,j, group;
+
+/* Code */
+
+ ASSERT(map);
+ ASSERT(numSliceGroups >= 1 && numSliceGroups <= MAX_NUM_SLICE_GROUPS);
+ ASSERT(runLength);
+
+ i = 0;
+
+ do {
+ for (group = 0; group < numSliceGroups && i < picSize;
+ i += runLength[group++])
+ {
+ ASSERT(runLength[group] <= picSize);
+ for (j = 0; j < runLength[group] && i + j < picSize; j++)
+ map[i+j] = group;
+ }
+ } while (i < picSize);
+
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeDispersedMap
+
+ Functional description:
+ Function to decode dispersed slice group map type, i.e. slice
+ group map type 1.
+
+ Inputs:
+ map pointer to the map
+ numSliceGroups number of slice groups
+ picWidth picture width in macroblocks
+ picHeight picture height in macroblocks
+
+ Outputs:
+ map slice group map is stored here
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+void DecodeDispersedMap(
+ u32 *map,
+ u32 numSliceGroups,
+ u32 picWidth,
+ u32 picHeight)
+{
+
+/* Variables */
+
+ u32 i, picSize;
+
+/* Code */
+
+ ASSERT(map);
+ ASSERT(numSliceGroups >= 1 && numSliceGroups <= MAX_NUM_SLICE_GROUPS);
+ ASSERT(picWidth);
+ ASSERT(picHeight);
+
+ picSize = picWidth * picHeight;
+
+ for (i = 0; i < picSize; i++)
+ map[i] = ((i % picWidth) + (((i / picWidth) * numSliceGroups) >> 1)) %
+ numSliceGroups;
+
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeForegroundLeftOverMap
+
+ Functional description:
+ Function to decode foreground with left-over slice group map type,
+ i.e. slice group map type 2.
+
+ Inputs:
+ map pointer to the map
+ numSliceGroups number of slice groups
+ topLeft top_left[] values
+ bottomRight bottom_right[] values
+ picWidth picture width in macroblocks
+ picHeight picture height in macroblocks
+
+ Outputs:
+ map slice group map is stored here
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+void DecodeForegroundLeftOverMap(
+ u32 *map,
+ u32 numSliceGroups,
+ u32 *topLeft,
+ u32 *bottomRight,
+ u32 picWidth,
+ u32 picHeight)
+{
+
+/* Variables */
+
+ u32 i,y,x,yTopLeft,yBottomRight,xTopLeft,xBottomRight, picSize;
+ u32 group;
+
+/* Code */
+
+ ASSERT(map);
+ ASSERT(numSliceGroups >= 1 && numSliceGroups <= MAX_NUM_SLICE_GROUPS);
+ ASSERT(topLeft);
+ ASSERT(bottomRight);
+ ASSERT(picWidth);
+ ASSERT(picHeight);
+
+ picSize = picWidth * picHeight;
+
+ for (i = 0; i < picSize; i++)
+ map[i] = numSliceGroups - 1;
+
+ for (group = numSliceGroups - 1; group--; )
+ {
+ ASSERT( topLeft[group] <= bottomRight[group] &&
+ bottomRight[group] < picSize );
+ yTopLeft = topLeft[group] / picWidth;
+ xTopLeft = topLeft[group] % picWidth;
+ yBottomRight = bottomRight[group] / picWidth;
+ xBottomRight = bottomRight[group] % picWidth;
+ ASSERT(xTopLeft <= xBottomRight);
+
+ for (y = yTopLeft; y <= yBottomRight; y++)
+ for (x = xTopLeft; x <= xBottomRight; x++)
+ map[ y * picWidth + x ] = group;
+ }
+
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeBoxOutMap
+
+ Functional description:
+ Function to decode box-out slice group map type, i.e. slice group
+ map type 3.
+
+ Inputs:
+ map pointer to the map
+ sliceGroupChangeDirectionFlag slice_group_change_direction_flag
+ unitsInSliceGroup0 mbs on slice group 0
+ picWidth picture width in macroblocks
+ picHeight picture height in macroblocks
+
+ Outputs:
+ map slice group map is stored here
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+void DecodeBoxOutMap(
+ u32 *map,
+ u32 sliceGroupChangeDirectionFlag,
+ u32 unitsInSliceGroup0,
+ u32 picWidth,
+ u32 picHeight)
+{
+
+/* Variables */
+
+ u32 i, k, picSize;
+ i32 x, y, xDir, yDir, leftBound, topBound, rightBound, bottomBound;
+ u32 mapUnitVacant;
+
+/* Code */
+
+ ASSERT(map);
+ ASSERT(picWidth);
+ ASSERT(picHeight);
+
+ picSize = picWidth * picHeight;
+ ASSERT(unitsInSliceGroup0 <= picSize);
+
+ for (i = 0; i < picSize; i++)
+ map[i] = 1;
+
+ x = (picWidth - (u32)sliceGroupChangeDirectionFlag) >> 1;
+ y = (picHeight - (u32)sliceGroupChangeDirectionFlag) >> 1;
+
+ leftBound = x;
+ topBound = y;
+
+ rightBound = x;
+ bottomBound = y;
+
+ xDir = (i32)sliceGroupChangeDirectionFlag - 1;
+ yDir = (i32)sliceGroupChangeDirectionFlag;
+
+ for (k = 0; k < unitsInSliceGroup0; k += mapUnitVacant ? 1 : 0)
+ {
+ mapUnitVacant = (map[ (u32)y * picWidth + (u32)x ] == 1) ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ if (mapUnitVacant)
+ map[ (u32)y * picWidth + (u32)x ] = 0;
+
+ if (xDir == -1 && x == leftBound)
+ {
+ leftBound = MAX(leftBound - 1, 0);
+ x = leftBound;
+ xDir = 0;
+ yDir = 2 * (i32)sliceGroupChangeDirectionFlag - 1;
+ }
+ else if (xDir == 1 && x == rightBound)
+ {
+ rightBound = MIN(rightBound + 1, (i32)picWidth - 1);
+ x = rightBound;
+ xDir = 0;
+ yDir = 1 - 2 * (i32)sliceGroupChangeDirectionFlag;
+ }
+ else if (yDir == -1 && y == topBound)
+ {
+ topBound = MAX(topBound - 1, 0);
+ y = topBound;
+ xDir = 1 - 2 * (i32)sliceGroupChangeDirectionFlag;
+ yDir = 0;
+ }
+ else if (yDir == 1 && y == bottomBound)
+ {
+ bottomBound = MIN(bottomBound + 1, (i32)picHeight - 1);
+ y = bottomBound;
+ xDir = 2 * (i32)sliceGroupChangeDirectionFlag - 1;
+ yDir = 0;
+ }
+ else
+ {
+ x += xDir;
+ y += yDir;
+ }
+ }
+
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeRasterScanMap
+
+ Functional description:
+ Function to decode raster scan slice group map type, i.e. slice
+ group map type 4.
+
+ Inputs:
+ map pointer to the map
+ sliceGroupChangeDirectionFlag slice_group_change_direction_flag
+ sizeOfUpperLeftGroup mbs in upperLeftGroup
+ picSize picture size in macroblocks
+
+ Outputs:
+ map slice group map is stored here
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+void DecodeRasterScanMap(
+ u32 *map,
+ u32 sliceGroupChangeDirectionFlag,
+ u32 sizeOfUpperLeftGroup,
+ u32 picSize)
+{
+
+/* Variables */
+
+ u32 i;
+
+/* Code */
+
+ ASSERT(map);
+ ASSERT(picSize);
+ ASSERT(sizeOfUpperLeftGroup <= picSize);
+
+ for (i = 0; i < picSize; i++)
+ if (i < sizeOfUpperLeftGroup)
+ map[i] = (u32)sliceGroupChangeDirectionFlag;
+ else
+ map[i] = 1 - (u32)sliceGroupChangeDirectionFlag;
+
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeWipeMap
+
+ Functional description:
+ Function to decode wipe slice group map type, i.e. slice group map
+ type 5.
+
+ Inputs:
+ sliceGroupChangeDirectionFlag slice_group_change_direction_flag
+ sizeOfUpperLeftGroup mbs in upperLeftGroup
+ picWidth picture width in macroblocks
+ picHeight picture height in macroblocks
+
+ Outputs:
+ map slice group map is stored here
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+void DecodeWipeMap(
+ u32 *map,
+ u32 sliceGroupChangeDirectionFlag,
+ u32 sizeOfUpperLeftGroup,
+ u32 picWidth,
+ u32 picHeight)
+{
+
+/* Variables */
+
+ u32 i,j,k;
+
+/* Code */
+
+ ASSERT(map);
+ ASSERT(picWidth);
+ ASSERT(picHeight);
+ ASSERT(sizeOfUpperLeftGroup <= picWidth * picHeight);
+
+ k = 0;
+ for (j = 0; j < picWidth; j++)
+ for (i = 0; i < picHeight; i++)
+ if (k++ < sizeOfUpperLeftGroup)
+ map[ i * picWidth + j ] = (u32)sliceGroupChangeDirectionFlag;
+ else
+ map[ i * picWidth + j ] = 1 -
+ (u32)sliceGroupChangeDirectionFlag;
+
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdDecodeSliceGroupMap
+
+ Functional description:
+ Function to decode macroblock to slice group map. Construction
+ of different slice group map types is handled by separate
+ functions defined above. See standard for details how slice group
+ maps are computed.
+
+ Inputs:
+ pps active picture parameter set
+ sliceGroupChangeCycle slice_group_change_cycle
+ picWidth picture width in macroblocks
+ picHeight picture height in macroblocks
+
+ Outputs:
+ map slice group map is stored here
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+void h264bsdDecodeSliceGroupMap(
+ u32 *map,
+ picParamSet_t *pps,
+ u32 sliceGroupChangeCycle,
+ u32 picWidth,
+ u32 picHeight)
+{
+
+/* Variables */
+
+ u32 i, picSize, unitsInSliceGroup0 = 0, sizeOfUpperLeftGroup = 0;
+
+/* Code */
+
+ ASSERT(map);
+ ASSERT(pps);
+ ASSERT(picWidth);
+ ASSERT(picHeight);
+ ASSERT(pps->sliceGroupMapType < 7);
+
+ picSize = picWidth * picHeight;
+
+ /* just one slice group -> all macroblocks belong to group 0 */
+ if (pps->numSliceGroups == 1)
+ {
+ H264SwDecMemset(map, 0, picSize * sizeof(u32));
+ return;
+ }
+
+ if (pps->sliceGroupMapType > 2 && pps->sliceGroupMapType < 6)
+ {
+ ASSERT(pps->sliceGroupChangeRate &&
+ pps->sliceGroupChangeRate <= picSize);
+
+ unitsInSliceGroup0 =
+ MIN(sliceGroupChangeCycle * pps->sliceGroupChangeRate, picSize);
+
+ if (pps->sliceGroupMapType == 4 || pps->sliceGroupMapType == 5)
+ sizeOfUpperLeftGroup = pps->sliceGroupChangeDirectionFlag ?
+ (picSize - unitsInSliceGroup0) : unitsInSliceGroup0;
+ }
+
+ switch (pps->sliceGroupMapType)
+ {
+ case 0:
+ DecodeInterleavedMap(map, pps->numSliceGroups,
+ pps->runLength, picSize);
+ break;
+
+ case 1:
+ DecodeDispersedMap(map, pps->numSliceGroups, picWidth,
+ picHeight);
+ break;
+
+ case 2:
+ DecodeForegroundLeftOverMap(map, pps->numSliceGroups,
+ pps->topLeft, pps->bottomRight, picWidth, picHeight);
+ break;
+
+ case 3:
+ DecodeBoxOutMap(map, pps->sliceGroupChangeDirectionFlag,
+ unitsInSliceGroup0, picWidth, picHeight);
+ break;
+
+ case 4:
+ DecodeRasterScanMap(map,
+ pps->sliceGroupChangeDirectionFlag, sizeOfUpperLeftGroup,
+ picSize);
+ break;
+
+ case 5:
+ DecodeWipeMap(map, pps->sliceGroupChangeDirectionFlag,
+ sizeOfUpperLeftGroup, picWidth, picHeight);
+ break;
+
+ default:
+ ASSERT(pps->sliceGroupId);
+ for (i = 0; i < picSize; i++)
+ {
+ ASSERT(pps->sliceGroupId[i] < pps->numSliceGroups);
+ map[i] = pps->sliceGroupId[i];
+ }
+ break;
+ }
+
+}
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_group_map.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_group_map.h
new file mode 100755
index 0000000..4bcb6f2
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_group_map.h
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_SLICE_GROUP_MAP_H
+#define H264SWDEC_SLICE_GROUP_MAP_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_pic_param_set.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+void h264bsdDecodeSliceGroupMap(
+ u32 *map,
+ picParamSet_t *pps,
+ u32 sliceGroupChangeCycle,
+ u32 picWidth,
+ u32 picHeight);
+
+#endif /* #ifdef H264SWDEC_SLICE_GROUP_MAP_H */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_header.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_header.c
new file mode 100755
index 0000000..a7c6f64
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_header.c
@@ -0,0 +1,1511 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdDecodeSliceHeader
+ NumSliceGroupChangeCycleBits
+ RefPicListReordering
+ DecRefPicMarking
+ CheckPpsId
+ CheckFrameNum
+ CheckIdrPicId
+ CheckPicOrderCntLsb
+ CheckDeltaPicOrderCntBottom
+ CheckDeltaPicOrderCnt
+ CheckRedundantPicCnt
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_slice_header.h"
+#include "h264bsd_util.h"
+#include "h264bsd_vlc.h"
+#include "h264bsd_nal_unit.h"
+#include "h264bsd_dpb.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+static u32 RefPicListReordering(strmData_t *, refPicListReordering_t *,
+ u32, u32);
+
+static u32 NumSliceGroupChangeCycleBits(u32 picSizeInMbs,
+ u32 sliceGroupChangeRate);
+
+static u32 DecRefPicMarking(strmData_t *pStrmData,
+ decRefPicMarking_t *pDecRefPicMarking, nalUnitType_e nalUnitType,
+ u32 numRefFrames);
+
+
+/*------------------------------------------------------------------------------
+
+ Function name: h264bsdDecodeSliceHeader
+
+ Functional description:
+ Decode slice header data from the stream.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+ pSeqParamSet pointer to active sequence parameter set
+ pPicParamSet pointer to active picture parameter set
+ pNalUnit pointer to current NAL unit structure
+
+ Outputs:
+ pSliceHeader decoded data is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK invalid stream data or end of stream
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeSliceHeader(strmData_t *pStrmData, sliceHeader_t *pSliceHeader,
+ seqParamSet_t *pSeqParamSet, picParamSet_t *pPicParamSet,
+ nalUnit_t *pNalUnit)
+{
+
+/* Variables */
+
+ u32 tmp, i, value;
+ i32 itmp;
+ u32 picSizeInMbs;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pSliceHeader);
+ ASSERT(pSeqParamSet);
+ ASSERT(pPicParamSet);
+ ASSERT( pNalUnit->nalUnitType == NAL_CODED_SLICE ||
+ pNalUnit->nalUnitType == NAL_CODED_SLICE_IDR );
+
+
+ H264SwDecMemset(pSliceHeader, 0, sizeof(sliceHeader_t));
+
+ picSizeInMbs = pSeqParamSet->picWidthInMbs * pSeqParamSet->picHeightInMbs;
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pSliceHeader->firstMbInSlice = value;
+ if (value >= picSizeInMbs)
+ {
+ EPRINT("first_mb_in_slice");
+ return(HANTRO_NOK);
+ }
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pSliceHeader->sliceType = value;
+ /* slice type has to be either I or P slice. P slice is not allowed when
+ * current NAL unit is an IDR NAL unit or num_ref_frames is 0 */
+ if ( !IS_I_SLICE(pSliceHeader->sliceType) &&
+ ( !IS_P_SLICE(pSliceHeader->sliceType) ||
+ IS_IDR_NAL_UNIT(pNalUnit) ||
+ !pSeqParamSet->numRefFrames ) )
+ {
+ EPRINT("slice_type");
+ return(HANTRO_NOK);
+ }
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pSliceHeader->picParameterSetId = value;
+ if (pSliceHeader->picParameterSetId != pPicParamSet->picParameterSetId)
+ {
+ EPRINT("pic_parameter_set_id");
+ return(HANTRO_NOK);
+ }
+
+ /* log2(maxFrameNum) -> num bits to represent frame_num */
+ i = 0;
+ while (pSeqParamSet->maxFrameNum >> i)
+ i++;
+ i--;
+
+ tmp = h264bsdGetBits(pStrmData, i);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ if (IS_IDR_NAL_UNIT(pNalUnit) && tmp != 0)
+ {
+ EPRINT("frame_num");
+ return(HANTRO_NOK);
+ }
+ pSliceHeader->frameNum = tmp;
+
+ if (IS_IDR_NAL_UNIT(pNalUnit))
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pSliceHeader->idrPicId = value;
+ if (value > 65535)
+ {
+ EPRINT("idr_pic_id");
+ return(HANTRO_NOK);
+ }
+ }
+
+ if (pSeqParamSet->picOrderCntType == 0)
+ {
+ /* log2(maxPicOrderCntLsb) -> num bits to represent pic_order_cnt_lsb */
+ i = 0;
+ while (pSeqParamSet->maxPicOrderCntLsb >> i)
+ i++;
+ i--;
+
+ tmp = h264bsdGetBits(pStrmData, i);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSliceHeader->picOrderCntLsb = tmp;
+
+ if (pPicParamSet->picOrderPresentFlag)
+ {
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pSliceHeader->deltaPicOrderCntBottom = itmp;
+ }
+
+ /* check that picOrderCnt for IDR picture will be zero. See
+ * DecodePicOrderCnt function to understand the logic here */
+ if ( IS_IDR_NAL_UNIT(pNalUnit) &&
+ ( (pSliceHeader->picOrderCntLsb >
+ pSeqParamSet->maxPicOrderCntLsb/2) ||
+ MIN((i32)pSliceHeader->picOrderCntLsb,
+ (i32)pSliceHeader->picOrderCntLsb +
+ pSliceHeader->deltaPicOrderCntBottom) != 0 ) )
+ {
+ return(HANTRO_NOK);
+ }
+ }
+
+ if ( (pSeqParamSet->picOrderCntType == 1) &&
+ !pSeqParamSet->deltaPicOrderAlwaysZeroFlag )
+ {
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pSliceHeader->deltaPicOrderCnt[0] = itmp;
+
+ if (pPicParamSet->picOrderPresentFlag)
+ {
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pSliceHeader->deltaPicOrderCnt[1] = itmp;
+ }
+
+ /* check that picOrderCnt for IDR picture will be zero. See
+ * DecodePicOrderCnt function to understand the logic here */
+ if ( IS_IDR_NAL_UNIT(pNalUnit) &&
+ MIN(pSliceHeader->deltaPicOrderCnt[0],
+ pSliceHeader->deltaPicOrderCnt[0] +
+ pSeqParamSet->offsetForTopToBottomField +
+ pSliceHeader->deltaPicOrderCnt[1]) != 0)
+ {
+ return(HANTRO_NOK);
+ }
+ }
+
+ if (pPicParamSet->redundantPicCntPresentFlag)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pSliceHeader->redundantPicCnt = value;
+ if (value > 127)
+ {
+ EPRINT("redundant_pic_cnt");
+ return(HANTRO_NOK);
+ }
+ }
+
+ if (IS_P_SLICE(pSliceHeader->sliceType))
+ {
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSliceHeader->numRefIdxActiveOverrideFlag = tmp;
+
+ if (pSliceHeader->numRefIdxActiveOverrideFlag)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (value > 15)
+ {
+ EPRINT("num_ref_idx_l0_active_minus1");
+ return(HANTRO_NOK);
+ }
+ pSliceHeader->numRefIdxL0Active = value + 1;
+ }
+ /* set numRefIdxL0Active from pic param set */
+ else
+ {
+ /* if value (minus1) in picture parameter set exceeds 15 it should
+ * have been overridden here */
+ if (pPicParamSet->numRefIdxL0Active > 16)
+ {
+ EPRINT("num_ref_idx_active_override_flag");
+ return(HANTRO_NOK);
+ }
+ pSliceHeader->numRefIdxL0Active = pPicParamSet->numRefIdxL0Active;
+ }
+ }
+
+ if (IS_P_SLICE(pSliceHeader->sliceType))
+ {
+ tmp = RefPicListReordering(pStrmData,
+ &pSliceHeader->refPicListReordering,
+ pSliceHeader->numRefIdxL0Active,
+ pSeqParamSet->maxFrameNum);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+
+ if (pNalUnit->nalRefIdc != 0)
+ {
+ tmp = DecRefPicMarking(pStrmData, &pSliceHeader->decRefPicMarking,
+ pNalUnit->nalUnitType, pSeqParamSet->numRefFrames);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+
+ /* decode sliceQpDelta and check that initial QP for the slice will be on
+ * the range [0, 51] */
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pSliceHeader->sliceQpDelta = itmp;
+ itmp += (i32)pPicParamSet->picInitQp;
+ if ( (itmp < 0) || (itmp > 51) )
+ {
+ EPRINT("slice_qp_delta");
+ return(HANTRO_NOK);
+ }
+
+ if (pPicParamSet->deblockingFilterControlPresentFlag)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pSliceHeader->disableDeblockingFilterIdc = value;
+ if (pSliceHeader->disableDeblockingFilterIdc > 2)
+ {
+ EPRINT("disable_deblocking_filter_idc");
+ return(HANTRO_NOK);
+ }
+
+ if (pSliceHeader->disableDeblockingFilterIdc != 1)
+ {
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if ( (itmp < -6) || (itmp > 6) )
+ {
+ EPRINT("slice_alpha_c0_offset_div2");
+ return(HANTRO_NOK);
+ }
+ pSliceHeader->sliceAlphaC0Offset = itmp * 2;
+
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if ( (itmp < -6) || (itmp > 6) )
+ {
+ EPRINT("slice_beta_offset_div2");
+ return(HANTRO_NOK);
+ }
+ pSliceHeader->sliceBetaOffset = itmp * 2;
+ }
+ }
+
+ if ( (pPicParamSet->numSliceGroups > 1) &&
+ (pPicParamSet->sliceGroupMapType >= 3) &&
+ (pPicParamSet->sliceGroupMapType <= 5) )
+ {
+ /* set tmp to number of bits used to represent slice_group_change_cycle
+ * in the stream */
+ tmp = NumSliceGroupChangeCycleBits(picSizeInMbs,
+ pPicParamSet->sliceGroupChangeRate);
+ value = h264bsdGetBits(pStrmData, tmp);
+ if (value == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSliceHeader->sliceGroupChangeCycle = value;
+
+ /* corresponds to tmp = Ceil(picSizeInMbs / sliceGroupChangeRate) */
+ tmp = (picSizeInMbs + pPicParamSet->sliceGroupChangeRate - 1) /
+ pPicParamSet->sliceGroupChangeRate;
+ if (pSliceHeader->sliceGroupChangeCycle > tmp)
+ {
+ EPRINT("slice_group_change_cycle");
+ return(HANTRO_NOK);
+ }
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: NumSliceGroupChangeCycleBits
+
+ Functional description:
+ Determine number of bits needed to represent
+ slice_group_change_cycle in the stream. The standard states that
+ slice_group_change_cycle is represented by
+ Ceil( Log2( (picSizeInMbs / sliceGroupChangeRate) + 1) )
+
+ bits. Division "/" in the equation is non-truncating division.
+
+ Inputs:
+ picSizeInMbs picture size in macroblocks
+ sliceGroupChangeRate
+
+ Outputs:
+ none
+
+ Returns:
+ number of bits needed
+
+------------------------------------------------------------------------------*/
+
+u32 NumSliceGroupChangeCycleBits(u32 picSizeInMbs, u32 sliceGroupChangeRate)
+{
+
+/* Variables */
+
+ u32 tmp,numBits,mask;
+
+/* Code */
+
+ ASSERT(picSizeInMbs);
+ ASSERT(sliceGroupChangeRate);
+ ASSERT(sliceGroupChangeRate <= picSizeInMbs);
+
+ /* compute (picSizeInMbs / sliceGroupChangeRate + 1), rounded up */
+ if (picSizeInMbs % sliceGroupChangeRate)
+ tmp = 2 + picSizeInMbs/sliceGroupChangeRate;
+ else
+ tmp = 1 + picSizeInMbs/sliceGroupChangeRate;
+
+ numBits = 0;
+ mask = ~0U;
+
+ /* set numBits to position of right-most non-zero bit */
+ while (tmp & (mask<<++numBits))
+ ;
+ numBits--;
+
+ /* add one more bit if value greater than 2^numBits */
+ if (tmp & ((1<<numBits)-1))
+ numBits++;
+
+ return(numBits);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: RefPicListReordering
+
+ Functional description:
+ Decode reference picture list reordering syntax elements from
+ the stream. Max number of reordering commands is numRefIdxActive.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+ numRefIdxActive number of active reference indices to be used for
+ current slice
+ maxPicNum maxFrameNum from the active SPS
+
+ Outputs:
+ pRefPicListReordering decoded data is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK invalid stream data
+
+------------------------------------------------------------------------------*/
+
+u32 RefPicListReordering(strmData_t *pStrmData,
+ refPicListReordering_t *pRefPicListReordering, u32 numRefIdxActive,
+ u32 maxPicNum)
+{
+
+/* Variables */
+
+ u32 tmp, value, i;
+ u32 command;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pRefPicListReordering);
+ ASSERT(numRefIdxActive);
+ ASSERT(maxPicNum);
+
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+
+ pRefPicListReordering->refPicListReorderingFlagL0 = tmp;
+
+ if (pRefPicListReordering->refPicListReorderingFlagL0)
+ {
+ i = 0;
+
+ do
+ {
+ if (i > numRefIdxActive)
+ {
+ EPRINT("Too many reordering commands");
+ return(HANTRO_NOK);
+ }
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &command);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (command > 3)
+ {
+ EPRINT("reordering_of_pic_nums_idc");
+ return(HANTRO_NOK);
+ }
+
+ pRefPicListReordering->command[i].reorderingOfPicNumsIdc = command;
+
+ if ((command == 0) || (command == 1))
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (value >= maxPicNum)
+ {
+ EPRINT("abs_diff_pic_num_minus1");
+ return(HANTRO_NOK);
+ }
+ pRefPicListReordering->command[i].absDiffPicNum = value + 1;
+ }
+ else if (command == 2)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pRefPicListReordering->command[i].longTermPicNum = value;
+ }
+ i++;
+ } while (command != 3);
+
+ /* there shall be at least one reordering command if
+ * refPicListReorderingFlagL0 was set */
+ if (i == 1)
+ {
+ EPRINT("ref_pic_list_reordering");
+ return(HANTRO_NOK);
+ }
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecRefPicMarking
+
+ Functional description:
+ Decode decoded reference picture marking syntax elements from
+ the stream.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+ nalUnitType type of the current NAL unit
+ numRefFrames max number of reference frames from the active SPS
+
+ Outputs:
+ pDecRefPicMarking decoded data is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK invalid stream data
+
+------------------------------------------------------------------------------*/
+
+u32 DecRefPicMarking(strmData_t *pStrmData,
+ decRefPicMarking_t *pDecRefPicMarking, nalUnitType_e nalUnitType,
+ u32 numRefFrames)
+{
+
+/* Variables */
+
+ u32 tmp, value;
+ u32 i;
+ u32 operation;
+ /* variables for error checking purposes, store number of memory
+ * management operations of certain type */
+ u32 num4 = 0, num5 = 0, num6 = 0, num1to3 = 0;
+
+/* Code */
+
+ ASSERT( nalUnitType == NAL_CODED_SLICE_IDR ||
+ nalUnitType == NAL_CODED_SLICE ||
+ nalUnitType == NAL_SEI );
+
+
+ if (nalUnitType == NAL_CODED_SLICE_IDR)
+ {
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pDecRefPicMarking->noOutputOfPriorPicsFlag = tmp;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pDecRefPicMarking->longTermReferenceFlag = tmp;
+ if (!numRefFrames && pDecRefPicMarking->longTermReferenceFlag)
+ {
+ EPRINT("long_term_reference_flag");
+ return(HANTRO_NOK);
+ }
+ }
+ else
+ {
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pDecRefPicMarking->adaptiveRefPicMarkingModeFlag = tmp;
+ if (pDecRefPicMarking->adaptiveRefPicMarkingModeFlag)
+ {
+ i = 0;
+ do
+ {
+ /* see explanation of the MAX_NUM_MMC_OPERATIONS in
+ * slice_header.h */
+ if (i > (2 * numRefFrames + 2))
+ {
+ EPRINT("Too many management operations");
+ return(HANTRO_NOK);
+ }
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &operation);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (operation > 6)
+ {
+ EPRINT("memory_management_control_operation");
+ return(HANTRO_NOK);
+ }
+
+ pDecRefPicMarking->operation[i].
+ memoryManagementControlOperation = operation;
+ if ((operation == 1) || (operation == 3))
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pDecRefPicMarking->operation[i].differenceOfPicNums =
+ value + 1;
+ }
+ if (operation == 2)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pDecRefPicMarking->operation[i].longTermPicNum = value;
+ }
+ if ((operation == 3) || (operation == 6))
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pDecRefPicMarking->operation[i].longTermFrameIdx =
+ value;
+ }
+ if (operation == 4)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ /* value shall be in range [0, numRefFrames] */
+ if (value > numRefFrames)
+ {
+ EPRINT("max_long_term_frame_idx_plus1");
+ return(HANTRO_NOK);
+ }
+ if (value == 0)
+ {
+ pDecRefPicMarking->operation[i].
+ maxLongTermFrameIdx =
+ NO_LONG_TERM_FRAME_INDICES;
+ }
+ else
+ {
+ pDecRefPicMarking->operation[i].
+ maxLongTermFrameIdx = value - 1;
+ }
+ num4++;
+ }
+ if (operation == 5)
+ {
+ num5++;
+ }
+ if (operation && operation <= 3)
+ num1to3++;
+ if (operation == 6)
+ num6++;
+
+ i++;
+ } while (operation != 0);
+
+ /* error checking */
+ if (num4 > 1 || num5 > 1 || num6 > 1 || (num1to3 && num5))
+ return(HANTRO_NOK);
+
+ }
+ }
+
+ return(HANTRO_OK);
+}
+
+/*------------------------------------------------------------------------------
+
+ Function name: h264bsdCheckPpsId
+
+ Functional description:
+ Peek value of pic_parameter_set_id from the slice header. Function
+ does not modify current stream positions but copies the stream
+ data structure to tmp structure which is used while accessing
+ stream data.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+
+ Outputs:
+ picParamSetId value is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK invalid stream data
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdCheckPpsId(strmData_t *pStrmData, u32 *picParamSetId)
+{
+
+/* Variables */
+
+ u32 tmp, value;
+ strmData_t tmpStrmData[1];
+
+/* Code */
+
+ ASSERT(pStrmData);
+
+ /* don't touch original stream position params */
+ *tmpStrmData = *pStrmData;
+
+ /* first_mb_in_slice */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* slice_type */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (value >= MAX_NUM_PIC_PARAM_SETS)
+ return(HANTRO_NOK);
+
+ *picParamSetId = value;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdCheckFrameNum
+
+ Functional description:
+ Peek value of frame_num from the slice header. Function does not
+ modify current stream positions but copies the stream data
+ structure to tmp structure which is used while accessing stream
+ data.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+ maxFrameNum
+
+ Outputs:
+ frameNum value is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK invalid stream data
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdCheckFrameNum(
+ strmData_t *pStrmData,
+ u32 maxFrameNum,
+ u32 *frameNum)
+{
+
+/* Variables */
+
+ u32 tmp, value, i;
+ strmData_t tmpStrmData[1];
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(maxFrameNum);
+ ASSERT(frameNum);
+
+ /* don't touch original stream position params */
+ *tmpStrmData = *pStrmData;
+
+ /* skip first_mb_in_slice */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* skip slice_type */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* skip pic_parameter_set_id */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* log2(maxFrameNum) -> num bits to represent frame_num */
+ i = 0;
+ while (maxFrameNum >> i)
+ i++;
+ i--;
+
+ /* frame_num */
+ tmp = h264bsdGetBits(tmpStrmData, i);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ *frameNum = tmp;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdCheckIdrPicId
+
+ Functional description:
+ Peek value of idr_pic_id from the slice header. Function does not
+ modify current stream positions but copies the stream data
+ structure to tmp structure which is used while accessing stream
+ data.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+ maxFrameNum max frame number from active SPS
+ nalUnitType type of the current NAL unit
+
+ Outputs:
+ idrPicId value is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK invalid stream data
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdCheckIdrPicId(
+ strmData_t *pStrmData,
+ u32 maxFrameNum,
+ nalUnitType_e nalUnitType,
+ u32 *idrPicId)
+{
+
+/* Variables */
+
+ u32 tmp, value, i;
+ strmData_t tmpStrmData[1];
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(maxFrameNum);
+ ASSERT(idrPicId);
+
+ /* nalUnitType must be equal to 5 because otherwise idrPicId is not
+ * present */
+ if (nalUnitType != NAL_CODED_SLICE_IDR)
+ return(HANTRO_NOK);
+
+ /* don't touch original stream position params */
+ *tmpStrmData = *pStrmData;
+
+ /* skip first_mb_in_slice */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* skip slice_type */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* skip pic_parameter_set_id */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* log2(maxFrameNum) -> num bits to represent frame_num */
+ i = 0;
+ while (maxFrameNum >> i)
+ i++;
+ i--;
+
+ /* skip frame_num */
+ tmp = h264bsdGetBits(tmpStrmData, i);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+
+ /* idr_pic_id */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, idrPicId);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdCheckPicOrderCntLsb
+
+ Functional description:
+ Peek value of pic_order_cnt_lsb from the slice header. Function
+ does not modify current stream positions but copies the stream
+ data structure to tmp structure which is used while accessing
+ stream data.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+ pSeqParamSet pointer to active SPS
+ nalUnitType type of the current NAL unit
+
+ Outputs:
+ picOrderCntLsb value is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK invalid stream data
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdCheckPicOrderCntLsb(
+ strmData_t *pStrmData,
+ seqParamSet_t *pSeqParamSet,
+ nalUnitType_e nalUnitType,
+ u32 *picOrderCntLsb)
+{
+
+/* Variables */
+
+ u32 tmp, value, i;
+ strmData_t tmpStrmData[1];
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pSeqParamSet);
+ ASSERT(picOrderCntLsb);
+
+ /* picOrderCntType must be equal to 0 */
+ ASSERT(pSeqParamSet->picOrderCntType == 0);
+ ASSERT(pSeqParamSet->maxFrameNum);
+ ASSERT(pSeqParamSet->maxPicOrderCntLsb);
+
+ /* don't touch original stream position params */
+ *tmpStrmData = *pStrmData;
+
+ /* skip first_mb_in_slice */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* skip slice_type */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* skip pic_parameter_set_id */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* log2(maxFrameNum) -> num bits to represent frame_num */
+ i = 0;
+ while (pSeqParamSet->maxFrameNum >> i)
+ i++;
+ i--;
+
+ /* skip frame_num */
+ tmp = h264bsdGetBits(tmpStrmData, i);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+
+ /* skip idr_pic_id when necessary */
+ if (nalUnitType == NAL_CODED_SLICE_IDR)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+
+ /* log2(maxPicOrderCntLsb) -> num bits to represent pic_order_cnt_lsb */
+ i = 0;
+ while (pSeqParamSet->maxPicOrderCntLsb >> i)
+ i++;
+ i--;
+
+ /* pic_order_cnt_lsb */
+ tmp = h264bsdGetBits(tmpStrmData, i);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ *picOrderCntLsb = tmp;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdCheckDeltaPicOrderCntBottom
+
+ Functional description:
+ Peek value of delta_pic_order_cnt_bottom from the slice header.
+ Function does not modify current stream positions but copies the
+ stream data structure to tmp structure which is used while
+ accessing stream data.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+ pSeqParamSet pointer to active SPS
+ nalUnitType type of the current NAL unit
+
+ Outputs:
+ deltaPicOrderCntBottom value is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK invalid stream data
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdCheckDeltaPicOrderCntBottom(
+ strmData_t *pStrmData,
+ seqParamSet_t *pSeqParamSet,
+ nalUnitType_e nalUnitType,
+ i32 *deltaPicOrderCntBottom)
+{
+
+/* Variables */
+
+ u32 tmp, value, i;
+ strmData_t tmpStrmData[1];
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pSeqParamSet);
+ ASSERT(deltaPicOrderCntBottom);
+
+ /* picOrderCntType must be equal to 0 and picOrderPresentFlag must be TRUE
+ * */
+ ASSERT(pSeqParamSet->picOrderCntType == 0);
+ ASSERT(pSeqParamSet->maxFrameNum);
+ ASSERT(pSeqParamSet->maxPicOrderCntLsb);
+
+ /* don't touch original stream position params */
+ *tmpStrmData = *pStrmData;
+
+ /* skip first_mb_in_slice */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* skip slice_type */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* skip pic_parameter_set_id */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* log2(maxFrameNum) -> num bits to represent frame_num */
+ i = 0;
+ while (pSeqParamSet->maxFrameNum >> i)
+ i++;
+ i--;
+
+ /* skip frame_num */
+ tmp = h264bsdGetBits(tmpStrmData, i);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+
+ /* skip idr_pic_id when necessary */
+ if (nalUnitType == NAL_CODED_SLICE_IDR)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+
+ /* log2(maxPicOrderCntLsb) -> num bits to represent pic_order_cnt_lsb */
+ i = 0;
+ while (pSeqParamSet->maxPicOrderCntLsb >> i)
+ i++;
+ i--;
+
+ /* skip pic_order_cnt_lsb */
+ tmp = h264bsdGetBits(tmpStrmData, i);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+
+ /* delta_pic_order_cnt_bottom */
+ tmp = h264bsdDecodeExpGolombSigned(tmpStrmData, deltaPicOrderCntBottom);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdCheckDeltaPicOrderCnt
+
+ Functional description:
+ Peek values delta_pic_order_cnt[0] and delta_pic_order_cnt[1]
+ from the slice header. Function does not modify current stream
+ positions but copies the stream data structure to tmp structure
+ which is used while accessing stream data.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+ pSeqParamSet pointer to active SPS
+ nalUnitType type of the current NAL unit
+ picOrderPresentFlag flag indicating if delta_pic_order_cnt[1]
+ is present in the stream
+
+ Outputs:
+ deltaPicOrderCnt values are stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK invalid stream data
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdCheckDeltaPicOrderCnt(
+ strmData_t *pStrmData,
+ seqParamSet_t *pSeqParamSet,
+ nalUnitType_e nalUnitType,
+ u32 picOrderPresentFlag,
+ i32 *deltaPicOrderCnt)
+{
+
+/* Variables */
+
+ u32 tmp, value, i;
+ strmData_t tmpStrmData[1];
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pSeqParamSet);
+ ASSERT(deltaPicOrderCnt);
+
+ /* picOrderCntType must be equal to 1 and deltaPicOrderAlwaysZeroFlag must
+ * be FALSE */
+ ASSERT(pSeqParamSet->picOrderCntType == 1);
+ ASSERT(!pSeqParamSet->deltaPicOrderAlwaysZeroFlag);
+ ASSERT(pSeqParamSet->maxFrameNum);
+
+ /* don't touch original stream position params */
+ *tmpStrmData = *pStrmData;
+
+ /* skip first_mb_in_slice */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* skip slice_type */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* skip pic_parameter_set_id */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* log2(maxFrameNum) -> num bits to represent frame_num */
+ i = 0;
+ while (pSeqParamSet->maxFrameNum >> i)
+ i++;
+ i--;
+
+ /* skip frame_num */
+ tmp = h264bsdGetBits(tmpStrmData, i);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+
+ /* skip idr_pic_id when necessary */
+ if (nalUnitType == NAL_CODED_SLICE_IDR)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+
+ /* delta_pic_order_cnt[0] */
+ tmp = h264bsdDecodeExpGolombSigned(tmpStrmData, &deltaPicOrderCnt[0]);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* delta_pic_order_cnt[1] if present */
+ if (picOrderPresentFlag)
+ {
+ tmp = h264bsdDecodeExpGolombSigned(tmpStrmData, &deltaPicOrderCnt[1]);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdCheckRedundantPicCnt
+
+ Functional description:
+ Peek value of redundant_pic_cnt from the slice header. Function
+ does not modify current stream positions but copies the stream
+ data structure to tmp structure which is used while accessing
+ stream data.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+ pSeqParamSet pointer to active SPS
+ pPicParamSet pointer to active PPS
+ nalUnitType type of the current NAL unit
+
+ Outputs:
+ redundantPicCnt value is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK invalid stream data
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdCheckRedundantPicCnt(
+ strmData_t *pStrmData,
+ seqParamSet_t *pSeqParamSet,
+ picParamSet_t *pPicParamSet,
+ nalUnitType_e nalUnitType,
+ u32 *redundantPicCnt)
+{
+
+/* Variables */
+
+ u32 tmp, value, i;
+ i32 ivalue;
+ strmData_t tmpStrmData[1];
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pSeqParamSet);
+ ASSERT(pPicParamSet);
+ ASSERT(redundantPicCnt);
+
+ /* redundant_pic_cnt_flag must be TRUE */
+ ASSERT(pPicParamSet->redundantPicCntPresentFlag);
+ ASSERT(pSeqParamSet->maxFrameNum);
+ ASSERT(pSeqParamSet->picOrderCntType > 0 ||
+ pSeqParamSet->maxPicOrderCntLsb);
+
+ /* don't touch original stream position params */
+ *tmpStrmData = *pStrmData;
+
+ /* skip first_mb_in_slice */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* skip slice_type */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* skip pic_parameter_set_id */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* log2(maxFrameNum) -> num bits to represent frame_num */
+ i = 0;
+ while (pSeqParamSet->maxFrameNum >> i)
+ i++;
+ i--;
+
+ /* skip frame_num */
+ tmp = h264bsdGetBits(tmpStrmData, i);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+
+ /* skip idr_pic_id when necessary */
+ if (nalUnitType == NAL_CODED_SLICE_IDR)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+
+ if (pSeqParamSet->picOrderCntType == 0)
+ {
+ /* log2(maxPicOrderCntLsb) -> num bits to represent pic_order_cnt_lsb */
+ i = 0;
+ while (pSeqParamSet->maxPicOrderCntLsb >> i)
+ i++;
+ i--;
+
+ /* pic_order_cnt_lsb */
+ tmp = h264bsdGetBits(tmpStrmData, i);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+
+ if (pPicParamSet->picOrderPresentFlag)
+ {
+ /* skip delta_pic_order_cnt_bottom */
+ tmp = h264bsdDecodeExpGolombSigned(tmpStrmData, &ivalue);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+ }
+
+ if (pSeqParamSet->picOrderCntType == 1 &&
+ !pSeqParamSet->deltaPicOrderAlwaysZeroFlag)
+ {
+ /* delta_pic_order_cnt[0] */
+ tmp = h264bsdDecodeExpGolombSigned(tmpStrmData, &ivalue);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* delta_pic_order_cnt[1] if present */
+ if (pPicParamSet->picOrderPresentFlag)
+ {
+ tmp = h264bsdDecodeExpGolombSigned(tmpStrmData, &ivalue);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+ }
+
+ /* redundant_pic_cnt */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, redundantPicCnt);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ return(HANTRO_OK);
+
+}
+
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdCheckPriorPicsFlag
+
+ Functional description:
+ Peek value of no_output_of_prior_pics_flag from the slice header.
+ Function does not modify current stream positions but copies
+ the stream data structure to tmp structure which is used while
+ accessing stream data.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+ pSeqParamSet pointer to active SPS
+ pPicParamSet pointer to active PPS
+ nalUnitType type of the current NAL unit
+
+ Outputs:
+ noOutputOfPriorPicsFlag value is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK invalid stream data
+
+------------------------------------------------------------------------------*/
+/*lint -e715 disable lint info nalUnitType not referenced */
+u32 h264bsdCheckPriorPicsFlag(u32 * noOutputOfPriorPicsFlag,
+ const strmData_t * pStrmData,
+ const seqParamSet_t * pSeqParamSet,
+ const picParamSet_t * pPicParamSet,
+ nalUnitType_e nalUnitType)
+{
+/* Variables */
+
+ u32 tmp, value, i;
+ i32 ivalue;
+ strmData_t tmpStrmData[1];
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pSeqParamSet);
+ ASSERT(pPicParamSet);
+ ASSERT(noOutputOfPriorPicsFlag);
+
+ /* must be IDR lsice */
+ ASSERT(nalUnitType == NAL_CODED_SLICE_IDR);
+
+ /* don't touch original stream position params */
+ *tmpStrmData = *pStrmData;
+
+ /* skip first_mb_in_slice */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if(tmp != HANTRO_OK)
+ return (tmp);
+
+ /* slice_type */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if(tmp != HANTRO_OK)
+ return (tmp);
+
+ /* skip pic_parameter_set_id */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if(tmp != HANTRO_OK)
+ return (tmp);
+
+ /* log2(maxFrameNum) -> num bits to represent frame_num */
+ i = 0;
+ while(pSeqParamSet->maxFrameNum >> i)
+ i++;
+ i--;
+
+ /* skip frame_num */
+ tmp = h264bsdGetBits(tmpStrmData, i);
+ if(tmp == END_OF_STREAM)
+ return (HANTRO_NOK);
+
+ /* skip idr_pic_id */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if(tmp != HANTRO_OK)
+ return (tmp);
+
+ if(pSeqParamSet->picOrderCntType == 0)
+ {
+ /* log2(maxPicOrderCntLsb) -> num bits to represent pic_order_cnt_lsb */
+ i = 0;
+ while(pSeqParamSet->maxPicOrderCntLsb >> i)
+ i++;
+ i--;
+
+ /* skip pic_order_cnt_lsb */
+ tmp = h264bsdGetBits(tmpStrmData, i);
+ if(tmp == END_OF_STREAM)
+ return (HANTRO_NOK);
+
+ if(pPicParamSet->picOrderPresentFlag)
+ {
+ /* skip delta_pic_order_cnt_bottom */
+ tmp = h264bsdDecodeExpGolombSigned(tmpStrmData, &ivalue);
+ if(tmp != HANTRO_OK)
+ return (tmp);
+ }
+ }
+
+ if(pSeqParamSet->picOrderCntType == 1 &&
+ !pSeqParamSet->deltaPicOrderAlwaysZeroFlag)
+ {
+ /* skip delta_pic_order_cnt[0] */
+ tmp = h264bsdDecodeExpGolombSigned(tmpStrmData, &ivalue);
+ if(tmp != HANTRO_OK)
+ return (tmp);
+
+ /* skip delta_pic_order_cnt[1] if present */
+ if(pPicParamSet->picOrderPresentFlag)
+ {
+ tmp = h264bsdDecodeExpGolombSigned(tmpStrmData, &ivalue);
+ if(tmp != HANTRO_OK)
+ return (tmp);
+ }
+ }
+
+ /* skip redundant_pic_cnt */
+ if(pPicParamSet->redundantPicCntPresentFlag)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if(tmp != HANTRO_OK)
+ return (tmp);
+ }
+
+ *noOutputOfPriorPicsFlag = h264bsdGetBits(tmpStrmData, 1);
+ if(*noOutputOfPriorPicsFlag == END_OF_STREAM)
+ return (HANTRO_NOK);
+
+ return (HANTRO_OK);
+
+}
+/*lint +e715 */
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_header.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_header.h
new file mode 100755
index 0000000..198898a
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_header.h
@@ -0,0 +1,186 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_SLICE_HEADER_H
+#define H264SWDEC_SLICE_HEADER_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_stream.h"
+#include "h264bsd_cfg.h"
+#include "h264bsd_seq_param_set.h"
+#include "h264bsd_pic_param_set.h"
+#include "h264bsd_nal_unit.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+enum {
+ P_SLICE = 0,
+ I_SLICE = 2
+};
+
+enum {NO_LONG_TERM_FRAME_INDICES = 0xFFFF};
+
+/* macro to determine if slice is an inter slice, sliceTypes 0 and 5 */
+#define IS_P_SLICE(sliceType) (((sliceType) == P_SLICE) || \
+ ((sliceType) == P_SLICE + 5))
+
+/* macro to determine if slice is an intra slice, sliceTypes 2 and 7 */
+#define IS_I_SLICE(sliceType) (((sliceType) == I_SLICE) || \
+ ((sliceType) == I_SLICE + 5))
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+/* structure to store data of one reference picture list reordering operation */
+typedef struct
+{
+ u32 reorderingOfPicNumsIdc;
+ u32 absDiffPicNum;
+ u32 longTermPicNum;
+} refPicListReorderingOperation_t;
+
+/* structure to store reference picture list reordering operations */
+typedef struct
+{
+ u32 refPicListReorderingFlagL0;
+ refPicListReorderingOperation_t command[MAX_NUM_REF_PICS+1];
+} refPicListReordering_t;
+
+/* structure to store data of one DPB memory management control operation */
+typedef struct
+{
+ u32 memoryManagementControlOperation;
+ u32 differenceOfPicNums;
+ u32 longTermPicNum;
+ u32 longTermFrameIdx;
+ u32 maxLongTermFrameIdx;
+} memoryManagementOperation_t;
+
+/* worst case scenario: all MAX_NUM_REF_PICS pictures in the buffer are
+ * short term pictures, each one of them is first marked as long term
+ * reference picture which is then marked as unused for reference.
+ * Additionally, max long-term frame index is set and current picture is
+ * marked as long term reference picture. Last position reserved for
+ * end memory_management_control_operation command */
+#define MAX_NUM_MMC_OPERATIONS (2*MAX_NUM_REF_PICS+2+1)
+
+/* structure to store decoded reference picture marking data */
+typedef struct
+{
+ u32 noOutputOfPriorPicsFlag;
+ u32 longTermReferenceFlag;
+ u32 adaptiveRefPicMarkingModeFlag;
+ memoryManagementOperation_t operation[MAX_NUM_MMC_OPERATIONS];
+} decRefPicMarking_t;
+
+/* structure to store slice header data decoded from the stream */
+typedef struct
+{
+ u32 firstMbInSlice;
+ u32 sliceType;
+ u32 picParameterSetId;
+ u32 frameNum;
+ u32 idrPicId;
+ u32 picOrderCntLsb;
+ i32 deltaPicOrderCntBottom;
+ i32 deltaPicOrderCnt[2];
+ u32 redundantPicCnt;
+ u32 numRefIdxActiveOverrideFlag;
+ u32 numRefIdxL0Active;
+ i32 sliceQpDelta;
+ u32 disableDeblockingFilterIdc;
+ i32 sliceAlphaC0Offset;
+ i32 sliceBetaOffset;
+ u32 sliceGroupChangeCycle;
+ refPicListReordering_t refPicListReordering;
+ decRefPicMarking_t decRefPicMarking;
+} sliceHeader_t;
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeSliceHeader(strmData_t *pStrmData,
+ sliceHeader_t *pSliceHeader,
+ seqParamSet_t *pSeqParamSet,
+ picParamSet_t *pPicParamSet,
+ nalUnit_t *pNalUnit);
+
+u32 h264bsdCheckPpsId(strmData_t *pStrmData, u32 *ppsId);
+
+u32 h264bsdCheckFrameNum(
+ strmData_t *pStrmData,
+ u32 maxFrameNum,
+ u32 *frameNum);
+
+u32 h264bsdCheckIdrPicId(
+ strmData_t *pStrmData,
+ u32 maxFrameNum,
+ nalUnitType_e nalUnitType,
+ u32 *idrPicId);
+
+u32 h264bsdCheckPicOrderCntLsb(
+ strmData_t *pStrmData,
+ seqParamSet_t *pSeqParamSet,
+ nalUnitType_e nalUnitType,
+ u32 *picOrderCntLsb);
+
+u32 h264bsdCheckDeltaPicOrderCntBottom(
+ strmData_t *pStrmData,
+ seqParamSet_t *pSeqParamSet,
+ nalUnitType_e nalUnitType,
+ i32 *deltaPicOrderCntBottom);
+
+u32 h264bsdCheckDeltaPicOrderCnt(
+ strmData_t *pStrmData,
+ seqParamSet_t *pSeqParamSet,
+ nalUnitType_e nalUnitType,
+ u32 picOrderPresentFlag,
+ i32 *deltaPicOrderCnt);
+
+u32 h264bsdCheckRedundantPicCnt(
+ strmData_t *pStrmData,
+ seqParamSet_t *pSeqParamSet,
+ picParamSet_t *pPicParamSet,
+ nalUnitType_e nalUnitType,
+ u32 *redundantPicCnt);
+
+u32 h264bsdCheckPriorPicsFlag(u32 * noOutputOfPriorPicsFlag,
+ const strmData_t * pStrmData,
+ const seqParamSet_t * pSeqParamSet,
+ const picParamSet_t * pPicParamSet,
+ nalUnitType_e nalUnitType);
+
+#endif /* #ifdef H264SWDEC_SLICE_HEADER_H */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_storage.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_storage.c
new file mode 100755
index 0000000..3234754
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_storage.c
@@ -0,0 +1,888 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdInitStorage
+ h264bsdStoreSeqParamSet
+ h264bsdStorePicParamSet
+ h264bsdActivateParamSets
+ h264bsdResetStorage
+ h264bsdIsStartOfPicture
+ h264bsdIsEndOfPicture
+ h264bsdComputeSliceGroupMap
+ h264bsdCheckAccessUnitBoundary
+ CheckPps
+ h264bsdValidParamSets
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_storage.h"
+#include "h264bsd_util.h"
+#include "h264bsd_neighbour.h"
+#include "h264bsd_slice_group_map.h"
+#include "h264bsd_dpb.h"
+#include "h264bsd_nal_unit.h"
+#include "h264bsd_slice_header.h"
+#include "h264bsd_seq_param_set.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+static u32 CheckPps(picParamSet_t *pps, seqParamSet_t *sps);
+
+/*------------------------------------------------------------------------------
+
+ Function name: h264bsdInitStorage
+
+ Functional description:
+ Initialize storage structure. Sets contents of the storage to '0'
+ except for the active parameter set ids, which are initialized
+ to invalid values.
+
+ Inputs:
+
+ Outputs:
+ pStorage initialized data stored here
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+void h264bsdInitStorage(storage_t *pStorage)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(pStorage);
+
+ H264SwDecMemset(pStorage, 0, sizeof(storage_t));
+
+ pStorage->activeSpsId = MAX_NUM_SEQ_PARAM_SETS;
+ pStorage->activePpsId = MAX_NUM_PIC_PARAM_SETS;
+
+ pStorage->aub->firstCallFlag = HANTRO_TRUE;
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdStoreSeqParamSet
+
+ Functional description:
+ Store sequence parameter set into the storage. If active SPS is
+ overwritten -> check if contents changes and if it does, set
+ parameters to force reactivation of parameter sets
+
+ Inputs:
+ pStorage pointer to storage structure
+ pSeqParamSet pointer to param set to be stored
+
+ Outputs:
+ none
+
+ Returns:
+ HANTRO_OK success
+ MEMORY_ALLOCATION_ERROR failure in memory allocation
+
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdStoreSeqParamSet(storage_t *pStorage, seqParamSet_t *pSeqParamSet)
+{
+
+/* Variables */
+
+ u32 id;
+
+/* Code */
+
+ ASSERT(pStorage);
+ ASSERT(pSeqParamSet);
+ ASSERT(pSeqParamSet->seqParameterSetId < MAX_NUM_SEQ_PARAM_SETS);
+
+ id = pSeqParamSet->seqParameterSetId;
+
+ /* seq parameter set with id not used before -> allocate memory */
+ if (pStorage->sps[id] == NULL)
+ {
+ ALLOCATE(pStorage->sps[id], 1, seqParamSet_t);
+ if (pStorage->sps[id] == NULL)
+ return(MEMORY_ALLOCATION_ERROR);
+ }
+ /* sequence parameter set with id equal to id of active sps */
+ else if (id == pStorage->activeSpsId)
+ {
+ /* if seq parameter set contents changes
+ * -> overwrite and re-activate when next IDR picture decoded
+ * ids of active param sets set to invalid values to force
+ * re-activation. Memories allocated for old sps freed
+ * otherwise free memeries allocated for just decoded sps and
+ * continue */
+ if (h264bsdCompareSeqParamSets(pSeqParamSet, pStorage->activeSps) != 0)
+ {
+ FREE(pStorage->sps[id]->offsetForRefFrame);
+ FREE(pStorage->sps[id]->vuiParameters);
+ pStorage->activeSpsId = MAX_NUM_SEQ_PARAM_SETS + 1;
+ pStorage->activePpsId = MAX_NUM_PIC_PARAM_SETS + 1;
+ pStorage->activeSps = NULL;
+ pStorage->activePps = NULL;
+ }
+ else
+ {
+ FREE(pSeqParamSet->offsetForRefFrame);
+ FREE(pSeqParamSet->vuiParameters);
+ return(HANTRO_OK);
+ }
+ }
+ /* overwrite seq param set other than active one -> free memories
+ * allocated for old param set */
+ else
+ {
+ FREE(pStorage->sps[id]->offsetForRefFrame);
+ FREE(pStorage->sps[id]->vuiParameters);
+ }
+
+ *pStorage->sps[id] = *pSeqParamSet;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdStorePicParamSet
+
+ Functional description:
+ Store picture parameter set into the storage. If active PPS is
+ overwritten -> check if active SPS changes and if it does -> set
+ parameters to force reactivation of parameter sets
+
+ Inputs:
+ pStorage pointer to storage structure
+ pPicParamSet pointer to param set to be stored
+
+ Outputs:
+ none
+
+ Returns:
+ HANTRO_OK success
+ MEMORY_ALLOCATION_ERROR failure in memory allocation
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdStorePicParamSet(storage_t *pStorage, picParamSet_t *pPicParamSet)
+{
+
+/* Variables */
+
+ u32 id;
+
+/* Code */
+
+ ASSERT(pStorage);
+ ASSERT(pPicParamSet);
+ ASSERT(pPicParamSet->picParameterSetId < MAX_NUM_PIC_PARAM_SETS);
+ ASSERT(pPicParamSet->seqParameterSetId < MAX_NUM_SEQ_PARAM_SETS);
+
+ id = pPicParamSet->picParameterSetId;
+
+ /* pic parameter set with id not used before -> allocate memory */
+ if (pStorage->pps[id] == NULL)
+ {
+ ALLOCATE(pStorage->pps[id], 1, picParamSet_t);
+ if (pStorage->pps[id] == NULL)
+ return(MEMORY_ALLOCATION_ERROR);
+ }
+ /* picture parameter set with id equal to id of active pps */
+ else if (id == pStorage->activePpsId)
+ {
+ /* check whether seq param set changes, force re-activation of
+ * param set if it does. Set activeSpsId to invalid value to
+ * accomplish this */
+ if (pPicParamSet->seqParameterSetId != pStorage->activeSpsId)
+ {
+ pStorage->activePpsId = MAX_NUM_PIC_PARAM_SETS + 1;
+ }
+ /* free memories allocated for old param set */
+ FREE(pStorage->pps[id]->runLength);
+ FREE(pStorage->pps[id]->topLeft);
+ FREE(pStorage->pps[id]->bottomRight);
+ FREE(pStorage->pps[id]->sliceGroupId);
+ }
+ /* overwrite pic param set other than active one -> free memories
+ * allocated for old param set */
+ else
+ {
+ FREE(pStorage->pps[id]->runLength);
+ FREE(pStorage->pps[id]->topLeft);
+ FREE(pStorage->pps[id]->bottomRight);
+ FREE(pStorage->pps[id]->sliceGroupId);
+ }
+
+ *pStorage->pps[id] = *pPicParamSet;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdActivateParamSets
+
+ Functional description:
+ Activate certain SPS/PPS combination. This function shall be
+ called in the beginning of each picture. Picture parameter set
+ can be changed as wanted, but sequence parameter set may only be
+ changed when the starting picture is an IDR picture.
+
+ When new SPS is activated the function allocates memory for
+ macroblock storages and slice group map and (re-)initializes the
+ decoded picture buffer. If this is not the first activation the old
+ allocations are freed and FreeDpb called before new allocations.
+
+ Inputs:
+ pStorage pointer to storage data structure
+ ppsId identifies the PPS to be activated, SPS id obtained
+ from the PPS
+ isIdr flag to indicate if the picture is an IDR picture
+
+ Outputs:
+ none
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK non-existing or invalid param set combination,
+ trying to change SPS with non-IDR picture
+ MEMORY_ALLOCATION_ERROR failure in memory allocation
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdActivateParamSets(storage_t *pStorage, u32 ppsId, u32 isIdr)
+{
+
+/* Variables */
+
+ u32 tmp;
+ u32 flag;
+
+/* Code */
+
+ ASSERT(pStorage);
+ ASSERT(ppsId < MAX_NUM_PIC_PARAM_SETS);
+
+ /* check that pps and corresponding sps exist */
+ if ( (pStorage->pps[ppsId] == NULL) ||
+ (pStorage->sps[pStorage->pps[ppsId]->seqParameterSetId] == NULL) )
+ {
+ return(HANTRO_NOK);
+ }
+
+ /* check that pps parameters do not violate picture size constraints */
+ tmp = CheckPps(pStorage->pps[ppsId],
+ pStorage->sps[pStorage->pps[ppsId]->seqParameterSetId]);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* first activation part1 */
+ if (pStorage->activePpsId == MAX_NUM_PIC_PARAM_SETS)
+ {
+ pStorage->activePpsId = ppsId;
+ pStorage->activePps = pStorage->pps[ppsId];
+ pStorage->activeSpsId = pStorage->activePps->seqParameterSetId;
+ pStorage->activeSps = pStorage->sps[pStorage->activeSpsId];
+ pStorage->picSizeInMbs =
+ pStorage->activeSps->picWidthInMbs *
+ pStorage->activeSps->picHeightInMbs;
+
+ pStorage->currImage->width = pStorage->activeSps->picWidthInMbs;
+ pStorage->currImage->height = pStorage->activeSps->picHeightInMbs;
+
+ pStorage->pendingActivation = HANTRO_TRUE;
+ }
+ /* first activation part2 */
+ else if (pStorage->pendingActivation)
+ {
+ pStorage->pendingActivation = HANTRO_FALSE;
+
+ FREE(pStorage->mb);
+ FREE(pStorage->sliceGroupMap);
+
+ ALLOCATE(pStorage->mb, pStorage->picSizeInMbs, mbStorage_t);
+ ALLOCATE(pStorage->sliceGroupMap, pStorage->picSizeInMbs, u32);
+ if (pStorage->mb == NULL || pStorage->sliceGroupMap == NULL)
+ return(MEMORY_ALLOCATION_ERROR);
+
+ H264SwDecMemset(pStorage->mb, 0,
+ pStorage->picSizeInMbs * sizeof(mbStorage_t));
+
+ h264bsdInitMbNeighbours(pStorage->mb,
+ pStorage->activeSps->picWidthInMbs,
+ pStorage->picSizeInMbs);
+
+ /* dpb output reordering disabled if
+ * 1) application set noReordering flag
+ * 2) POC type equal to 2
+ * 3) num_reorder_frames in vui equal to 0 */
+ if ( pStorage->noReordering ||
+ pStorage->activeSps->picOrderCntType == 2 ||
+ (pStorage->activeSps->vuiParametersPresentFlag &&
+ pStorage->activeSps->vuiParameters->bitstreamRestrictionFlag &&
+ !pStorage->activeSps->vuiParameters->numReorderFrames) )
+ flag = HANTRO_TRUE;
+ else
+ flag = HANTRO_FALSE;
+
+ tmp = h264bsdResetDpb(pStorage->dpb,
+ pStorage->activeSps->picWidthInMbs *
+ pStorage->activeSps->picHeightInMbs,
+ pStorage->activeSps->maxDpbSize,
+ pStorage->activeSps->numRefFrames,
+ pStorage->activeSps->maxFrameNum,
+ flag);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+ else if (ppsId != pStorage->activePpsId)
+ {
+ /* sequence parameter set shall not change but before an IDR picture */
+ if (pStorage->pps[ppsId]->seqParameterSetId != pStorage->activeSpsId)
+ {
+ DEBUG(("SEQ PARAM SET CHANGING...\n"));
+ if (isIdr)
+ {
+ pStorage->activePpsId = ppsId;
+ pStorage->activePps = pStorage->pps[ppsId];
+ pStorage->activeSpsId = pStorage->activePps->seqParameterSetId;
+ pStorage->activeSps = pStorage->sps[pStorage->activeSpsId];
+ pStorage->picSizeInMbs =
+ pStorage->activeSps->picWidthInMbs *
+ pStorage->activeSps->picHeightInMbs;
+
+ pStorage->currImage->width = pStorage->activeSps->picWidthInMbs;
+ pStorage->currImage->height =
+ pStorage->activeSps->picHeightInMbs;
+
+ pStorage->pendingActivation = HANTRO_TRUE;
+ }
+ else
+ {
+ DEBUG(("TRYING TO CHANGE SPS IN NON-IDR SLICE\n"));
+ return(HANTRO_NOK);
+ }
+ }
+ else
+ {
+ pStorage->activePpsId = ppsId;
+ pStorage->activePps = pStorage->pps[ppsId];
+ }
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdResetStorage
+
+ Functional description:
+ Reset contents of the storage. This should be called before
+ processing of new image is started.
+
+ Inputs:
+ pStorage pointer to storage structure
+
+ Outputs:
+ none
+
+ Returns:
+ none
+
+
+------------------------------------------------------------------------------*/
+
+void h264bsdResetStorage(storage_t *pStorage)
+{
+
+/* Variables */
+
+ u32 i;
+
+/* Code */
+
+ ASSERT(pStorage);
+
+ pStorage->slice->numDecodedMbs = 0;
+ pStorage->slice->sliceId = 0;
+
+ for (i = 0; i < pStorage->picSizeInMbs; i++)
+ {
+ pStorage->mb[i].sliceId = 0;
+ pStorage->mb[i].decoded = 0;
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdIsStartOfPicture
+
+ Functional description:
+ Determine if the decoder is in the start of a picture. This
+ information is needed to decide if h264bsdActivateParamSets and
+ h264bsdCheckGapsInFrameNum functions should be called. Function
+ considers that new picture is starting if no slice headers
+ have been successfully decoded for the current access unit.
+
+ Inputs:
+ pStorage pointer to storage structure
+
+ Outputs:
+ none
+
+ Returns:
+ HANTRO_TRUE new picture is starting
+ HANTRO_FALSE not starting
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdIsStartOfPicture(storage_t *pStorage)
+{
+
+/* Variables */
+
+
+/* Code */
+
+ if (pStorage->validSliceInAccessUnit == HANTRO_FALSE)
+ return(HANTRO_TRUE);
+ else
+ return(HANTRO_FALSE);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdIsEndOfPicture
+
+ Functional description:
+ Determine if the decoder is in the end of a picture. This
+ information is needed to determine when deblocking filtering
+ and reference picture marking processes should be performed.
+
+ If the decoder is processing primary slices the return value
+ is determined by checking the value of numDecodedMbs in the
+ storage. On the other hand, if the decoder is processing
+ redundant slices the numDecodedMbs may not contain valid
+ informationa and each macroblock has to be checked separately.
+
+ Inputs:
+ pStorage pointer to storage structure
+
+ Outputs:
+ none
+
+ Returns:
+ HANTRO_TRUE end of picture
+ HANTRO_FALSE noup
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdIsEndOfPicture(storage_t *pStorage)
+{
+
+/* Variables */
+
+ u32 i, tmp;
+
+/* Code */
+
+ /* primary picture */
+ if (!pStorage->sliceHeader[0].redundantPicCnt)
+ {
+ if (pStorage->slice->numDecodedMbs == pStorage->picSizeInMbs)
+ return(HANTRO_TRUE);
+ }
+ else
+ {
+ for (i = 0, tmp = 0; i < pStorage->picSizeInMbs; i++)
+ tmp += pStorage->mb[i].decoded ? 1 : 0;
+
+ if (tmp == pStorage->picSizeInMbs)
+ return(HANTRO_TRUE);
+ }
+
+ return(HANTRO_FALSE);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdComputeSliceGroupMap
+
+ Functional description:
+ Compute slice group map. Just call h264bsdDecodeSliceGroupMap with
+ appropriate parameters.
+
+ Inputs:
+ pStorage pointer to storage structure
+ sliceGroupChangeCycle
+
+ Outputs:
+ none
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+void h264bsdComputeSliceGroupMap(storage_t *pStorage, u32 sliceGroupChangeCycle)
+{
+
+/* Variables */
+
+
+/* Code */
+
+ h264bsdDecodeSliceGroupMap(pStorage->sliceGroupMap,
+ pStorage->activePps, sliceGroupChangeCycle,
+ pStorage->activeSps->picWidthInMbs,
+ pStorage->activeSps->picHeightInMbs);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdCheckAccessUnitBoundary
+
+ Functional description:
+ Check if next NAL unit starts a new access unit. Following
+ conditions specify start of a new access unit:
+
+ -NAL unit types 6-11, 13-18 (e.g. SPS, PPS)
+
+ following conditions checked only for slice NAL units, values
+ compared to ones obtained from previous slice:
+
+ -NAL unit type differs (slice / IDR slice)
+ -frame_num differs
+ -nal_ref_idc differs and one of the values is 0
+ -POC information differs
+ -both are IDR slices and idr_pic_id differs
+
+ Inputs:
+ strm pointer to stream data structure
+ nuNext pointer to NAL unit structure
+ storage pointer to storage structure
+
+ Outputs:
+ accessUnitBoundaryFlag the result is stored here, TRUE for
+ access unit boundary, FALSE otherwise
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK failure, invalid stream data
+ PARAM_SET_ERROR invalid param set usage
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdCheckAccessUnitBoundary(
+ strmData_t *strm,
+ nalUnit_t *nuNext,
+ storage_t *storage,
+ u32 *accessUnitBoundaryFlag)
+{
+
+/* Variables */
+
+ u32 tmp, ppsId, frameNum, idrPicId, picOrderCntLsb;
+ i32 deltaPicOrderCntBottom, deltaPicOrderCnt[2];
+ seqParamSet_t *sps;
+ picParamSet_t *pps;
+
+/* Code */
+
+ ASSERT(strm);
+ ASSERT(nuNext);
+ ASSERT(storage);
+ ASSERT(storage->sps);
+ ASSERT(storage->pps);
+
+ /* initialize default output to FALSE */
+ *accessUnitBoundaryFlag = HANTRO_FALSE;
+
+ if ( ( (nuNext->nalUnitType > 5) && (nuNext->nalUnitType < 12) ) ||
+ ( (nuNext->nalUnitType > 12) && (nuNext->nalUnitType <= 18) ) )
+ {
+ *accessUnitBoundaryFlag = HANTRO_TRUE;
+ return(HANTRO_OK);
+ }
+ else if ( nuNext->nalUnitType != NAL_CODED_SLICE &&
+ nuNext->nalUnitType != NAL_CODED_SLICE_IDR )
+ {
+ return(HANTRO_OK);
+ }
+
+ /* check if this is the very first call to this function */
+ if (storage->aub->firstCallFlag)
+ {
+ *accessUnitBoundaryFlag = HANTRO_TRUE;
+ storage->aub->firstCallFlag = HANTRO_FALSE;
+ }
+
+ /* get picture parameter set id */
+ tmp = h264bsdCheckPpsId(strm, &ppsId);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* store sps and pps in separate pointers just to make names shorter */
+ pps = storage->pps[ppsId];
+ if ( pps == NULL || storage->sps[pps->seqParameterSetId] == NULL ||
+ (storage->activeSpsId != MAX_NUM_SEQ_PARAM_SETS &&
+ pps->seqParameterSetId != storage->activeSpsId &&
+ nuNext->nalUnitType != NAL_CODED_SLICE_IDR) )
+ return(PARAM_SET_ERROR);
+ sps = storage->sps[pps->seqParameterSetId];
+
+ if (storage->aub->nuPrev->nalRefIdc != nuNext->nalRefIdc &&
+ (storage->aub->nuPrev->nalRefIdc == 0 || nuNext->nalRefIdc == 0))
+ *accessUnitBoundaryFlag = HANTRO_TRUE;
+
+ if ((storage->aub->nuPrev->nalUnitType == NAL_CODED_SLICE_IDR &&
+ nuNext->nalUnitType != NAL_CODED_SLICE_IDR) ||
+ (storage->aub->nuPrev->nalUnitType != NAL_CODED_SLICE_IDR &&
+ nuNext->nalUnitType == NAL_CODED_SLICE_IDR))
+ *accessUnitBoundaryFlag = HANTRO_TRUE;
+
+ tmp = h264bsdCheckFrameNum(strm, sps->maxFrameNum, &frameNum);
+ if (tmp != HANTRO_OK)
+ return(HANTRO_NOK);
+
+ if (storage->aub->prevFrameNum != frameNum)
+ {
+ storage->aub->prevFrameNum = frameNum;
+ *accessUnitBoundaryFlag = HANTRO_TRUE;
+ }
+
+ if (nuNext->nalUnitType == NAL_CODED_SLICE_IDR)
+ {
+ tmp = h264bsdCheckIdrPicId(strm, sps->maxFrameNum, nuNext->nalUnitType,
+ &idrPicId);
+ if (tmp != HANTRO_OK)
+ return(HANTRO_NOK);
+
+ if (storage->aub->nuPrev->nalUnitType == NAL_CODED_SLICE_IDR &&
+ storage->aub->prevIdrPicId != idrPicId)
+ *accessUnitBoundaryFlag = HANTRO_TRUE;
+
+ storage->aub->prevIdrPicId = idrPicId;
+ }
+
+ if (sps->picOrderCntType == 0)
+ {
+ tmp = h264bsdCheckPicOrderCntLsb(strm, sps, nuNext->nalUnitType,
+ &picOrderCntLsb);
+ if (tmp != HANTRO_OK)
+ return(HANTRO_NOK);
+
+ if (storage->aub->prevPicOrderCntLsb != picOrderCntLsb)
+ {
+ storage->aub->prevPicOrderCntLsb = picOrderCntLsb;
+ *accessUnitBoundaryFlag = HANTRO_TRUE;
+ }
+
+ if (pps->picOrderPresentFlag)
+ {
+ tmp = h264bsdCheckDeltaPicOrderCntBottom(strm, sps,
+ nuNext->nalUnitType, &deltaPicOrderCntBottom);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ if (storage->aub->prevDeltaPicOrderCntBottom !=
+ deltaPicOrderCntBottom)
+ {
+ storage->aub->prevDeltaPicOrderCntBottom =
+ deltaPicOrderCntBottom;
+ *accessUnitBoundaryFlag = HANTRO_TRUE;
+ }
+ }
+ }
+ else if (sps->picOrderCntType == 1 && !sps->deltaPicOrderAlwaysZeroFlag)
+ {
+ tmp = h264bsdCheckDeltaPicOrderCnt(strm, sps, nuNext->nalUnitType,
+ pps->picOrderPresentFlag, deltaPicOrderCnt);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ if (storage->aub->prevDeltaPicOrderCnt[0] != deltaPicOrderCnt[0])
+ {
+ storage->aub->prevDeltaPicOrderCnt[0] = deltaPicOrderCnt[0];
+ *accessUnitBoundaryFlag = HANTRO_TRUE;
+ }
+
+ if (pps->picOrderPresentFlag)
+ if (storage->aub->prevDeltaPicOrderCnt[1] != deltaPicOrderCnt[1])
+ {
+ storage->aub->prevDeltaPicOrderCnt[1] = deltaPicOrderCnt[1];
+ *accessUnitBoundaryFlag = HANTRO_TRUE;
+ }
+ }
+
+ *storage->aub->nuPrev = *nuNext;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: CheckPps
+
+ Functional description:
+ Check picture parameter set. Contents of the picture parameter
+ set information that depends on the image dimensions is checked
+ against the dimensions in the sps.
+
+ Inputs:
+ pps pointer to picture paramter set
+ sps pointer to sequence parameter set
+
+ Outputs:
+ none
+
+ Returns:
+ HANTRO_OK everything ok
+ HANTRO_NOK invalid data in picture parameter set
+
+------------------------------------------------------------------------------*/
+u32 CheckPps(picParamSet_t *pps, seqParamSet_t *sps)
+{
+
+ u32 i;
+ u32 picSize;
+
+ picSize = sps->picWidthInMbs * sps->picHeightInMbs;
+
+ /* check slice group params */
+ if (pps->numSliceGroups > 1)
+ {
+ if (pps->sliceGroupMapType == 0)
+ {
+ ASSERT(pps->runLength);
+ for (i = 0; i < pps->numSliceGroups; i++)
+ {
+ if (pps->runLength[i] > picSize)
+ return(HANTRO_NOK);
+ }
+ }
+ else if (pps->sliceGroupMapType == 2)
+ {
+ ASSERT(pps->topLeft);
+ ASSERT(pps->bottomRight);
+ for (i = 0; i < pps->numSliceGroups-1; i++)
+ {
+ if (pps->topLeft[i] > pps->bottomRight[i] ||
+ pps->bottomRight[i] >= picSize)
+ return(HANTRO_NOK);
+
+ if ( (pps->topLeft[i] % sps->picWidthInMbs) >
+ (pps->bottomRight[i] % sps->picWidthInMbs) )
+ return(HANTRO_NOK);
+ }
+ }
+ else if (pps->sliceGroupMapType > 2 && pps->sliceGroupMapType < 6)
+ {
+ if (pps->sliceGroupChangeRate > picSize)
+ return(HANTRO_NOK);
+ }
+ else if (pps->sliceGroupMapType == 6 &&
+ pps->picSizeInMapUnits < picSize)
+ return(HANTRO_NOK);
+ }
+
+ return(HANTRO_OK);
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdValidParamSets
+
+ Functional description:
+ Check if any valid SPS/PPS combination exists in the storage.
+ Function tries each PPS in the buffer and checks if corresponding
+ SPS exists and calls CheckPps to determine if the PPS conforms
+ to image dimensions of the SPS.
+
+ Inputs:
+ pStorage pointer to storage structure
+
+ Outputs:
+ HANTRO_OK there is at least one valid combination
+ HANTRO_NOK no valid combinations found
+
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdValidParamSets(storage_t *pStorage)
+{
+
+/* Variables */
+
+ u32 i;
+
+/* Code */
+
+ ASSERT(pStorage);
+
+ for (i = 0; i < MAX_NUM_PIC_PARAM_SETS; i++)
+ {
+ if ( pStorage->pps[i] &&
+ pStorage->sps[pStorage->pps[i]->seqParameterSetId] &&
+ CheckPps(pStorage->pps[i],
+ pStorage->sps[pStorage->pps[i]->seqParameterSetId]) ==
+ HANTRO_OK)
+ {
+ return(HANTRO_OK);
+ }
+ }
+
+ return(HANTRO_NOK);
+
+}
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_storage.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_storage.h
new file mode 100755
index 0000000..ba3b2da
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_storage.h
@@ -0,0 +1,174 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_STORAGE_H
+#define H264SWDEC_STORAGE_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_cfg.h"
+#include "h264bsd_seq_param_set.h"
+#include "h264bsd_pic_param_set.h"
+#include "h264bsd_macroblock_layer.h"
+#include "h264bsd_nal_unit.h"
+#include "h264bsd_slice_header.h"
+#include "h264bsd_seq_param_set.h"
+#include "h264bsd_dpb.h"
+#include "h264bsd_pic_order_cnt.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+typedef struct
+{
+ u32 sliceId;
+ u32 numDecodedMbs;
+ u32 lastMbAddr;
+} sliceStorage_t;
+
+/* structure to store parameters needed for access unit boundary checking */
+typedef struct
+{
+ nalUnit_t nuPrev[1];
+ u32 prevFrameNum;
+ u32 prevIdrPicId;
+ u32 prevPicOrderCntLsb;
+ i32 prevDeltaPicOrderCntBottom;
+ i32 prevDeltaPicOrderCnt[2];
+ u32 firstCallFlag;
+} aubCheck_t;
+
+/* storage data structure, holds all data of a decoder instance */
+typedef struct
+{
+ /* active paramet set ids and pointers */
+ u32 oldSpsId;
+ u32 activePpsId;
+ u32 activeSpsId;
+ picParamSet_t *activePps;
+ seqParamSet_t *activeSps;
+ seqParamSet_t *sps[MAX_NUM_SEQ_PARAM_SETS];
+ picParamSet_t *pps[MAX_NUM_PIC_PARAM_SETS];
+
+ /* current slice group map, recomputed for each slice */
+ u32 *sliceGroupMap;
+
+ u32 picSizeInMbs;
+
+ /* this flag is set after all macroblocks of a picture successfully
+ * decoded -> redundant slices not decoded */
+ u32 skipRedundantSlices;
+ u32 picStarted;
+
+ /* flag to indicate if current access unit contains any valid slices */
+ u32 validSliceInAccessUnit;
+
+ /* store information needed for handling of slice decoding */
+ sliceStorage_t slice[1];
+
+ /* number of concealed macroblocks in the current image */
+ u32 numConcealedMbs;
+
+ /* picId given by application */
+ u32 currentPicId;
+
+ /* macroblock specific storages, size determined by image dimensions */
+ mbStorage_t *mb;
+
+ /* flag to store noOutputReordering flag set by the application */
+ u32 noReordering;
+
+ /* DPB */
+ dpbStorage_t dpb[1];
+
+ /* structure to store picture order count related information */
+ pocStorage_t poc[1];
+
+ /* access unit boundary checking related data */
+ aubCheck_t aub[1];
+
+ /* current processed image */
+ image_t currImage[1];
+
+ /* last valid NAL unit header is stored here */
+ nalUnit_t prevNalUnit[1];
+
+ /* slice header, second structure used as a temporary storage while
+ * decoding slice header, first one stores last successfully decoded
+ * slice header */
+ sliceHeader_t sliceHeader[2];
+
+ /* fields to store old stream buffer pointers, needed when only part of
+ * a stream buffer is processed by h264bsdDecode function */
+ u32 prevBufNotFinished;
+ u8 *prevBufPointer;
+ u32 prevBytesConsumed;
+ strmData_t strm[1];
+
+ /* macroblock layer structure, there is no need to store this but it
+ * would have increased the stack size excessively and needed to be
+ * allocated from head -> easiest to put it here */
+ macroblockLayer_t *mbLayer;
+
+ u32 pendingActivation; /* Activate parameter sets after returning
+ HEADERS_RDY to the user */
+ u32 intraConcealmentFlag; /* 0 gray picture for corrupted intra
+ 1 previous frame used if available */
+} storage_t;
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+void h264bsdInitStorage(storage_t *pStorage);
+void h264bsdResetStorage(storage_t *pStorage);
+u32 h264bsdIsStartOfPicture(storage_t *pStorage);
+u32 h264bsdIsEndOfPicture(storage_t *pStorage);
+u32 h264bsdStoreSeqParamSet(storage_t *pStorage, seqParamSet_t *pSeqParamSet);
+u32 h264bsdStorePicParamSet(storage_t *pStorage, picParamSet_t *pPicParamSet);
+u32 h264bsdActivateParamSets(storage_t *pStorage, u32 ppsId, u32 isIdr);
+void h264bsdComputeSliceGroupMap(storage_t *pStorage,
+ u32 sliceGroupChangeCycle);
+
+u32 h264bsdCheckAccessUnitBoundary(
+ strmData_t *strm,
+ nalUnit_t *nuNext,
+ storage_t *storage,
+ u32 *accessUnitBoundaryFlag);
+
+u32 h264bsdValidParamSets(storage_t *pStorage);
+
+#endif /* #ifdef H264SWDEC_STORAGE_H */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_stream.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_stream.c
new file mode 100755
index 0000000..20d1083
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_stream.c
@@ -0,0 +1,242 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdGetBits
+ h264bsdShowBits32
+ h264bsdFlushBits
+ h264bsdIsByteAligned
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_util.h"
+#include "h264bsd_stream.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdGetBits
+
+ Functional description:
+ Read and remove bits from the stream buffer.
+
+ Input:
+ pStrmData pointer to stream data structure
+ numBits number of bits to read
+
+ Output:
+ none
+
+ Returns:
+ bits read from stream
+ END_OF_STREAM if not enough bits left
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdGetBits(strmData_t *pStrmData, u32 numBits)
+{
+
+ u32 out;
+
+ ASSERT(pStrmData);
+ ASSERT(numBits < 32);
+
+ out = h264bsdShowBits32(pStrmData) >> (32 - numBits);
+
+ if (h264bsdFlushBits(pStrmData, numBits) == HANTRO_OK)
+ {
+ return(out);
+ }
+ else
+ {
+ return(END_OF_STREAM);
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdShowBits32
+
+ Functional description:
+ Read 32 bits from the stream buffer. Buffer is left as it is, i.e.
+ no bits are removed. First bit read from the stream is the MSB of
+ the return value. If there is not enough bits in the buffer ->
+ bits beyong the end of the stream are set to '0' in the return
+ value.
+
+ Input:
+ pStrmData pointer to stream data structure
+
+ Output:
+ none
+
+ Returns:
+ bits read from stream
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdShowBits32(strmData_t *pStrmData)
+{
+
+ i32 bits, shift;
+ u32 out;
+ u8 *pStrm;
+
+ ASSERT(pStrmData);
+ ASSERT(pStrmData->pStrmCurrPos);
+ ASSERT(pStrmData->bitPosInWord < 8);
+ ASSERT(pStrmData->bitPosInWord ==
+ (pStrmData->strmBuffReadBits & 0x7));
+
+ pStrm = pStrmData->pStrmCurrPos;
+
+ /* number of bits left in the buffer */
+ bits = (i32)pStrmData->strmBuffSize*8 - (i32)pStrmData->strmBuffReadBits;
+
+ /* at least 32-bits in the buffer */
+ if (bits >= 32)
+ {
+ u32 bitPosInWord = pStrmData->bitPosInWord;
+ out = ((u32)pStrm[0] << 24) | ((u32)pStrm[1] << 16) |
+ ((u32)pStrm[2] << 8) | ((u32)pStrm[3]);
+
+ if (bitPosInWord)
+ {
+ u32 byte = (u32)pStrm[4];
+ u32 tmp = (8-bitPosInWord);
+ out <<= bitPosInWord;
+ out |= byte>>tmp;
+ }
+ return (out);
+ }
+ /* at least one bit in the buffer */
+ else if (bits > 0)
+ {
+ shift = (i32)(24 + pStrmData->bitPosInWord);
+ out = (u32)(*pStrm++) << shift;
+ bits -= (i32)(8 - pStrmData->bitPosInWord);
+ while (bits > 0)
+ {
+ shift -= 8;
+ out |= (u32)(*pStrm++) << shift;
+ bits -= 8;
+ }
+ return (out);
+ }
+ else
+ return (0);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdFlushBits
+
+ Functional description:
+ Remove bits from the stream buffer
+
+ Input:
+ pStrmData pointer to stream data structure
+ numBits number of bits to remove
+
+ Output:
+ none
+
+ Returns:
+ HANTRO_OK success
+ END_OF_STREAM not enough bits left
+
+------------------------------------------------------------------------------*/
+#ifndef H264DEC_NEON
+u32 h264bsdFlushBits(strmData_t *pStrmData, u32 numBits)
+{
+
+ ASSERT(pStrmData);
+ ASSERT(pStrmData->pStrmBuffStart);
+ ASSERT(pStrmData->pStrmCurrPos);
+ ASSERT(pStrmData->bitPosInWord < 8);
+ ASSERT(pStrmData->bitPosInWord == (pStrmData->strmBuffReadBits & 0x7));
+
+ pStrmData->strmBuffReadBits += numBits;
+ pStrmData->bitPosInWord = pStrmData->strmBuffReadBits & 0x7;
+ if ( (pStrmData->strmBuffReadBits ) <= (8*pStrmData->strmBuffSize) )
+ {
+ pStrmData->pStrmCurrPos = pStrmData->pStrmBuffStart +
+ (pStrmData->strmBuffReadBits >> 3);
+ return(HANTRO_OK);
+ }
+ else
+ return(END_OF_STREAM);
+
+}
+#endif
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdIsByteAligned
+
+ Functional description:
+ Check if current stream position is byte aligned.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+
+ Outputs:
+ none
+
+ Returns:
+ TRUE stream is byte aligned
+ FALSE stream is not byte aligned
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdIsByteAligned(strmData_t *pStrmData)
+{
+
+/* Variables */
+
+/* Code */
+
+ if (!pStrmData->bitPosInWord)
+ return(HANTRO_TRUE);
+ else
+ return(HANTRO_FALSE);
+
+}
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_stream.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_stream.h
new file mode 100755
index 0000000..4404b66
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_stream.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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_STREAM_H
+#define H264SWDEC_STREAM_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+typedef struct
+{
+ u8 *pStrmBuffStart; /* pointer to start of stream buffer */
+ u8 *pStrmCurrPos; /* current read address in stream buffer */
+ u32 bitPosInWord; /* bit position in stream buffer byte */
+ u32 strmBuffSize; /* size of stream buffer (bytes) */
+ u32 strmBuffReadBits; /* number of bits read from stream buffer */
+} strmData_t;
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+u32 h264bsdGetBits(strmData_t *pStrmData, u32 numBits);
+
+u32 h264bsdShowBits32(strmData_t *pStrmData);
+
+u32 h264bsdFlushBits(strmData_t *pStrmData, u32 numBits);
+
+u32 h264bsdIsByteAligned(strmData_t *);
+
+#endif /* #ifdef H264SWDEC_STREAM_H */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_transform.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_transform.c
new file mode 100755
index 0000000..4eb6dd0
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_transform.c
@@ -0,0 +1,402 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdProcessBlock
+ h264bsdProcessLumaDc
+ h264bsdProcessChromaDc
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_transform.h"
+#include "h264bsd_util.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/* Switch off the following Lint messages for this file:
+ * Info 701: Shift left of signed quantity (int)
+ * Info 702: Shift right of signed quantity (int)
+ */
+/*lint -e701 -e702 */
+
+/* LevelScale function */
+static const i32 levelScale[6][3] = {
+ {10,13,16}, {11,14,18}, {13,16,20}, {14,18,23}, {16,20,25}, {18,23,29}};
+
+/* qp % 6 as a function of qp */
+static const u8 qpMod6[52] = {0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,
+ 0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3};
+
+/* qp / 6 as a function of qp */
+static const u8 qpDiv6[52] = {0,0,0,0,0,0,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,
+ 4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,8,8,8,8};
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdProcessBlock
+
+ Functional description:
+ Function performs inverse zig-zag scan, inverse scaling and
+ inverse transform for a luma or a chroma residual block
+
+ Inputs:
+ data pointer to data to be processed
+ qp quantization parameter
+ skip skip processing of data[0], set to non-zero value
+ if dc coeff hanled separately
+ coeffMap 16 lsb's indicate which coeffs are non-zero,
+ bit 0 (lsb) for coeff 0, bit 1 for coeff 1 etc.
+
+ Outputs:
+ data processed data
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK processed data not in valid range [-512, 511]
+
+------------------------------------------------------------------------------*/
+u32 h264bsdProcessBlock(i32 *data, u32 qp, u32 skip, u32 coeffMap)
+{
+
+/* Variables */
+
+ i32 tmp0, tmp1, tmp2, tmp3;
+ i32 d1, d2, d3;
+ u32 row,col;
+ u32 qpDiv;
+ i32 *ptr;
+
+/* Code */
+
+ qpDiv = qpDiv6[qp];
+ tmp1 = levelScale[qpMod6[qp]][0] << qpDiv;
+ tmp2 = levelScale[qpMod6[qp]][1] << qpDiv;
+ tmp3 = levelScale[qpMod6[qp]][2] << qpDiv;
+
+ if (!skip)
+ data[0] = (data[0] * tmp1);
+
+ /* at least one of the rows 1, 2 or 3 contain non-zero coeffs, mask takes
+ * the scanning order into account */
+ if (coeffMap & 0xFF9C)
+ {
+ /* do the zig-zag scan and inverse quantization */
+ d1 = data[1];
+ d2 = data[14];
+ d3 = data[15];
+ data[1] = (d1 * tmp2);
+ data[14] = (d2 * tmp2);
+ data[15] = (d3 * tmp3);
+
+ d1 = data[2];
+ d2 = data[5];
+ d3 = data[4];
+ data[4] = (d1 * tmp2);
+ data[2] = (d2 * tmp1);
+ data[5] = (d3 * tmp3);
+
+ d1 = data[8];
+ d2 = data[3];
+ d3 = data[6];
+ tmp0 = (d1 * tmp2);
+ data[8] = (d2 * tmp1);
+ data[3] = (d3 * tmp2);
+ d1 = data[7];
+ d2 = data[12];
+ d3 = data[9];
+ data[6] = (d1 * tmp2);
+ data[7] = (d2 * tmp3);
+ data[12] = (d3 * tmp2);
+ data[9] = tmp0;
+
+ d1 = data[10];
+ d2 = data[11];
+ d3 = data[13];
+ data[13] = (d1 * tmp3);
+ data[10] = (d2 * tmp1);
+ data[11] = (d3 * tmp2);
+
+ /* horizontal transform */
+ for (row = 4, ptr = data; row--; ptr += 4)
+ {
+ tmp0 = ptr[0] + ptr[2];
+ tmp1 = ptr[0] - ptr[2];
+ tmp2 = (ptr[1] >> 1) - ptr[3];
+ tmp3 = ptr[1] + (ptr[3] >> 1);
+ ptr[0] = tmp0 + tmp3;
+ ptr[1] = tmp1 + tmp2;
+ ptr[2] = tmp1 - tmp2;
+ ptr[3] = tmp0 - tmp3;
+ }
+
+ /*lint +e661 +e662*/
+ /* then vertical transform */
+ for (col = 4; col--; data++)
+ {
+ tmp0 = data[0] + data[8];
+ tmp1 = data[0] - data[8];
+ tmp2 = (data[4] >> 1) - data[12];
+ tmp3 = data[4] + (data[12] >> 1);
+ data[0 ] = (tmp0 + tmp3 + 32)>>6;
+ data[4 ] = (tmp1 + tmp2 + 32)>>6;
+ data[8 ] = (tmp1 - tmp2 + 32)>>6;
+ data[12] = (tmp0 - tmp3 + 32)>>6;
+ /* check that each value is in the range [-512,511] */
+ if (((u32)(data[0] + 512) > 1023) ||
+ ((u32)(data[4] + 512) > 1023) ||
+ ((u32)(data[8] + 512) > 1023) ||
+ ((u32)(data[12] + 512) > 1023) )
+ return(HANTRO_NOK);
+ }
+ }
+ else /* rows 1, 2 and 3 are zero */
+ {
+ /* only dc-coeff is non-zero, i.e. coeffs at original positions
+ * 1, 5 and 6 are zero */
+ if ((coeffMap & 0x62) == 0)
+ {
+ tmp0 = (data[0] + 32) >> 6;
+ /* check that value is in the range [-512,511] */
+ if ((u32)(tmp0 + 512) > 1023)
+ return(HANTRO_NOK);
+ data[0] = data[1] = data[2] = data[3] = data[4] = data[5] =
+ data[6] = data[7] = data[8] = data[9] = data[10] =
+ data[11] = data[12] = data[13] = data[14] = data[15] =
+ tmp0;
+ }
+ else /* at least one of the coeffs 1, 5 or 6 is non-zero */
+ {
+ data[1] = (data[1] * tmp2);
+ data[2] = (data[5] * tmp1);
+ data[3] = (data[6] * tmp2);
+ tmp0 = data[0] + data[2];
+ tmp1 = data[0] - data[2];
+ tmp2 = (data[1] >> 1) - data[3];
+ tmp3 = data[1] + (data[3] >> 1);
+ data[0] = (tmp0 + tmp3 + 32)>>6;
+ data[1] = (tmp1 + tmp2 + 32)>>6;
+ data[2] = (tmp1 - tmp2 + 32)>>6;
+ data[3] = (tmp0 - tmp3 + 32)>>6;
+ data[4] = data[8] = data[12] = data[0];
+ data[5] = data[9] = data[13] = data[1];
+ data[6] = data[10] = data[14] = data[2];
+ data[7] = data[11] = data[15] = data[3];
+ /* check that each value is in the range [-512,511] */
+ if (((u32)(data[0] + 512) > 1023) ||
+ ((u32)(data[1] + 512) > 1023) ||
+ ((u32)(data[2] + 512) > 1023) ||
+ ((u32)(data[3] + 512) > 1023) )
+ return(HANTRO_NOK);
+ }
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdProcessLumaDc
+
+ Functional description:
+ Function performs inverse zig-zag scan, inverse transform and
+ inverse scaling for a luma DC coefficients block
+
+ Inputs:
+ data pointer to data to be processed
+ qp quantization parameter
+
+ Outputs:
+ data processed data
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+void h264bsdProcessLumaDc(i32 *data, u32 qp)
+{
+
+/* Variables */
+
+ i32 tmp0, tmp1, tmp2, tmp3;
+ u32 row,col;
+ u32 qpMod, qpDiv;
+ i32 levScale;
+ i32 *ptr;
+
+/* Code */
+
+ qpMod = qpMod6[qp];
+ qpDiv = qpDiv6[qp];
+
+ /* zig-zag scan */
+ tmp0 = data[2];
+ data[2] = data[5];
+ data[5] = data[4];
+ data[4] = tmp0;
+
+ tmp0 = data[8];
+ data[8] = data[3];
+ data[3] = data[6];
+ data[6] = data[7];
+ data[7] = data[12];
+ data[12] = data[9];
+ data[9] = tmp0;
+
+ tmp0 = data[10];
+ data[10] = data[11];
+ data[11] = data[13];
+ data[13] = tmp0;
+
+ /* horizontal transform */
+ for (row = 4, ptr = data; row--; ptr += 4)
+ {
+ tmp0 = ptr[0] + ptr[2];
+ tmp1 = ptr[0] - ptr[2];
+ tmp2 = ptr[1] - ptr[3];
+ tmp3 = ptr[1] + ptr[3];
+ ptr[0] = tmp0 + tmp3;
+ ptr[1] = tmp1 + tmp2;
+ ptr[2] = tmp1 - tmp2;
+ ptr[3] = tmp0 - tmp3;
+ }
+
+ /*lint +e661 +e662*/
+ /* then vertical transform and inverse scaling */
+ levScale = levelScale[ qpMod ][0];
+ if (qp >= 12)
+ {
+ levScale <<= (qpDiv-2);
+ for (col = 4; col--; data++)
+ {
+ tmp0 = data[0] + data[8 ];
+ tmp1 = data[0] - data[8 ];
+ tmp2 = data[4] - data[12];
+ tmp3 = data[4] + data[12];
+ data[0 ] = ((tmp0 + tmp3)*levScale);
+ data[4 ] = ((tmp1 + tmp2)*levScale);
+ data[8 ] = ((tmp1 - tmp2)*levScale);
+ data[12] = ((tmp0 - tmp3)*levScale);
+ }
+ }
+ else
+ {
+ i32 tmp;
+ tmp = ((1 - qpDiv) == 0) ? 1 : 2;
+ for (col = 4; col--; data++)
+ {
+ tmp0 = data[0] + data[8 ];
+ tmp1 = data[0] - data[8 ];
+ tmp2 = data[4] - data[12];
+ tmp3 = data[4] + data[12];
+ data[0 ] = ((tmp0 + tmp3)*levScale+tmp) >> (2-qpDiv);
+ data[4 ] = ((tmp1 + tmp2)*levScale+tmp) >> (2-qpDiv);
+ data[8 ] = ((tmp1 - tmp2)*levScale+tmp) >> (2-qpDiv);
+ data[12] = ((tmp0 - tmp3)*levScale+tmp) >> (2-qpDiv);
+ }
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdProcessChromaDc
+
+ Functional description:
+ Function performs inverse transform and inverse scaling for a
+ chroma DC coefficients block
+
+ Inputs:
+ data pointer to data to be processed
+ qp quantization parameter
+
+ Outputs:
+ data processed data
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+void h264bsdProcessChromaDc(i32 *data, u32 qp)
+{
+
+/* Variables */
+
+ i32 tmp0, tmp1, tmp2, tmp3;
+ u32 qpDiv;
+ i32 levScale;
+ u32 levShift;
+
+/* Code */
+
+ qpDiv = qpDiv6[qp];
+ levScale = levelScale[ qpMod6[qp] ][0];
+
+ if (qp >= 6)
+ {
+ levScale <<= (qpDiv-1);
+ levShift = 0;
+ }
+ else
+ {
+ levShift = 1;
+ }
+
+ tmp0 = data[0] + data[2];
+ tmp1 = data[0] - data[2];
+ tmp2 = data[1] - data[3];
+ tmp3 = data[1] + data[3];
+ data[0] = ((tmp0 + tmp3) * levScale) >> levShift;
+ data[1] = ((tmp0 - tmp3) * levScale) >> levShift;
+ data[2] = ((tmp1 + tmp2) * levScale) >> levShift;
+ data[3] = ((tmp1 - tmp2) * levScale) >> levShift;
+ tmp0 = data[4] + data[6];
+ tmp1 = data[4] - data[6];
+ tmp2 = data[5] - data[7];
+ tmp3 = data[5] + data[7];
+ data[4] = ((tmp0 + tmp3) * levScale) >> levShift;
+ data[5] = ((tmp0 - tmp3) * levScale) >> levShift;
+ data[6] = ((tmp1 + tmp2) * levScale) >> levShift;
+ data[7] = ((tmp1 - tmp2) * levScale) >> levShift;
+
+}
+
+/*lint +e701 +e702 */
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_transform.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_transform.h
new file mode 100755
index 0000000..4f41a23
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_transform.h
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_TRANSFORM_H
+#define H264SWDEC_TRANSFORM_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+u32 h264bsdProcessBlock(i32 *data, u32 qp, u32 skip, u32 coeffMap);
+void h264bsdProcessLumaDc(i32 *data, u32 qp);
+void h264bsdProcessChromaDc(i32 *data, u32 qp);
+
+#endif /* #ifdef H264SWDEC_TRANSFORM_H */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_util.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_util.c
new file mode 100755
index 0000000..53b2fd8
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_util.c
@@ -0,0 +1,286 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdCountLeadingZeros
+ h264bsdRbspTrailingBits
+ h264bsdMoreRbspData
+ h264bsdNextMbAddress
+ h264bsdSetCurrImageMbPointers
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_util.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/* look-up table for expected values of stuffing bits */
+static const u32 stuffingTable[8] = {0x1,0x2,0x4,0x8,0x10,0x20,0x40,0x80};
+
+/* look-up table for chroma quantization parameter as a function of luma QP */
+const u32 h264bsdQpC[52] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,
+ 20,21,22,23,24,25,26,27,28,29,29,30,31,32,32,33,34,34,35,35,36,36,37,37,37,
+ 38,38,38,39,39,39,39};
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+
+ 5.1 Function: h264bsdCountLeadingZeros
+
+ Functional description:
+ Count leading zeros in a code word. Code word is assumed to be
+ right-aligned, last bit of the code word in the lsb of the value.
+
+ Inputs:
+ value code word
+ length number of bits in the code word
+
+ Outputs:
+ none
+
+ Returns:
+ number of leading zeros in the code word
+
+------------------------------------------------------------------------------*/
+#ifndef H264DEC_NEON
+u32 h264bsdCountLeadingZeros(u32 value, u32 length)
+{
+
+/* Variables */
+
+ u32 zeros = 0;
+ u32 mask = 1 << (length - 1);
+
+/* Code */
+
+ ASSERT(length <= 32);
+
+ while (mask && !(value & mask))
+ {
+ zeros++;
+ mask >>= 1;
+ }
+ return(zeros);
+
+}
+#endif
+/*------------------------------------------------------------------------------
+
+ 5.2 Function: h264bsdRbspTrailingBits
+
+ Functional description:
+ Check Raw Byte Stream Payload (RBSP) trailing bits, i.e. stuffing.
+ Rest of the current byte (whole byte if allready byte aligned)
+ in the stream buffer shall contain a '1' bit followed by zero or
+ more '0' bits.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+
+ Outputs:
+ none
+
+ Returns:
+ HANTRO_OK RBSP trailing bits found
+ HANTRO_NOK otherwise
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdRbspTrailingBits(strmData_t *pStrmData)
+{
+
+/* Variables */
+
+ u32 stuffing;
+ u32 stuffingLength;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pStrmData->bitPosInWord < 8);
+
+ stuffingLength = 8 - pStrmData->bitPosInWord;
+
+ stuffing = h264bsdGetBits(pStrmData, stuffingLength);
+ if (stuffing == END_OF_STREAM)
+ return(HANTRO_NOK);
+
+ if (stuffing != stuffingTable[stuffingLength - 1])
+ return(HANTRO_NOK);
+ else
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ 5.3 Function: h264bsdMoreRbspData
+
+ Functional description:
+ Check if there is more data in the current RBSP. The standard
+ defines this function so that there is more data if
+ -more than 8 bits left or
+ -last bits are not RBSP trailing bits
+
+ Inputs:
+ pStrmData pointer to stream data structure
+
+ Outputs:
+ none
+
+ Returns:
+ HANTRO_TRUE there is more data
+ HANTRO_FALSE no more data
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdMoreRbspData(strmData_t *pStrmData)
+{
+
+/* Variables */
+
+ u32 bits;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pStrmData->strmBuffReadBits <= 8 * pStrmData->strmBuffSize);
+
+ bits = pStrmData->strmBuffSize * 8 - pStrmData->strmBuffReadBits;
+
+ if (bits == 0)
+ return(HANTRO_FALSE);
+
+ if ( (bits > 8) ||
+ ((h264bsdShowBits32(pStrmData)>>(32-bits)) != (1 << (bits-1))) )
+ return(HANTRO_TRUE);
+ else
+ return(HANTRO_FALSE);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ 5.4 Function: h264bsdNextMbAddress
+
+ Functional description:
+ Get address of the next macroblock in the current slice group.
+
+ Inputs:
+ pSliceGroupMap slice group for each macroblock
+ picSizeInMbs size of the picture
+ currMbAddr where to start
+
+ Outputs:
+ none
+
+ Returns:
+ address of the next macroblock
+ 0 if none of the following macroblocks belong to same slice
+ group as currMbAddr
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdNextMbAddress(u32 *pSliceGroupMap, u32 picSizeInMbs, u32 currMbAddr)
+{
+
+/* Variables */
+
+ u32 i, sliceGroup, tmp;
+
+/* Code */
+
+ ASSERT(pSliceGroupMap);
+ ASSERT(picSizeInMbs);
+ ASSERT(currMbAddr < picSizeInMbs);
+
+ sliceGroup = pSliceGroupMap[currMbAddr];
+
+ i = currMbAddr + 1;
+ tmp = pSliceGroupMap[i];
+ while ((i < picSizeInMbs) && (tmp != sliceGroup))
+ {
+ i++;
+ tmp = pSliceGroupMap[i];
+ }
+
+ if (i == picSizeInMbs)
+ i = 0;
+
+ return(i);
+
+}
+
+
+/*------------------------------------------------------------------------------
+
+ 5.5 Function: h264bsdSetCurrImageMbPointers
+
+ Functional description:
+ Set luma and chroma pointers in image_t for current MB
+
+ Inputs:
+ image Current image
+ mbNum number of current MB
+
+ Outputs:
+ none
+
+ Returns:
+ none
+------------------------------------------------------------------------------*/
+void h264bsdSetCurrImageMbPointers(image_t *image, u32 mbNum)
+{
+ u32 width, height;
+ u32 picSize;
+ u32 row, col;
+ u32 tmp;
+
+ width = image->width;
+ height = image->height;
+ row = mbNum / width;
+ col = mbNum % width;
+
+ tmp = row * width;
+ picSize = width * height;
+
+ image->luma = (u8*)(image->data + col * 16 + tmp * 256);
+ image->cb = (u8*)(image->data + picSize * 256 + tmp * 64 + col * 8);
+ image->cr = (u8*)(image->cb + picSize * 64);
+}
+
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_util.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_util.h
new file mode 100755
index 0000000..cb3adda
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_util.h
@@ -0,0 +1,178 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_UTIL_H
+#define H264SWDEC_UTIL_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#ifdef _ASSERT_USED
+#include <assert.h>
+#endif
+
+#include "H264SwDecApi.h"
+
+#if defined(_RANGE_CHECK) || defined(_DEBUG_PRINT) || defined(_ERROR_PRINT)
+#include <stdio.h>
+#endif
+
+#include "basetype.h"
+#include "h264bsd_stream.h"
+#include "h264bsd_image.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+#define HANTRO_OK 0
+#define HANTRO_NOK 1
+
+#define HANTRO_TRUE (1)
+#define HANTRO_FALSE (0)
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#define MEMORY_ALLOCATION_ERROR 0xFFFF
+#define PARAM_SET_ERROR 0xFFF0
+
+/* value to be returned by GetBits if stream buffer is empty */
+#define END_OF_STREAM 0xFFFFFFFFU
+
+#define EMPTY_RESIDUAL_INDICATOR 0xFFFFFF
+
+/* macro to mark a residual block empty, i.e. contain zero coefficients */
+#define MARK_RESIDUAL_EMPTY(residual) ((residual)[0] = EMPTY_RESIDUAL_INDICATOR)
+/* macro to check if residual block is empty */
+#define IS_RESIDUAL_EMPTY(residual) ((residual)[0] == EMPTY_RESIDUAL_INDICATOR)
+
+/* macro for assertion, used only if compiler flag _ASSERT_USED is defined */
+#ifdef _ASSERT_USED
+#define ASSERT(expr) assert(expr)
+#else
+#define ASSERT(expr)
+#endif
+
+/* macro for range checking an value, used only if compiler flag _RANGE_CHECK
+ * is defined */
+#ifdef _RANGE_CHECK
+#define RANGE_CHECK(value, minBound, maxBound) \
+{ \
+ if ((value) < (minBound) || (value) > (maxBound)) \
+ fprintf(stderr, "Warning: Value exceeds given limit(s)!\n"); \
+}
+#else
+#define RANGE_CHECK(value, minBound, maxBound)
+#endif
+
+/* macro for range checking an array, used only if compiler flag _RANGE_CHECK
+ * is defined */
+#ifdef _RANGE_CHECK
+#define RANGE_CHECK_ARRAY(array, minBound, maxBound, length) \
+{ \
+ i32 i; \
+ for (i = 0; i < (length); i++) \
+ if ((array)[i] < (minBound) || (array)[i] > (maxBound)) \
+ fprintf(stderr,"Warning: Value [%d] exceeds given limit(s)!\n",i); \
+}
+#else
+#define RANGE_CHECK_ARRAY(array, minBound, maxBound, length)
+#endif
+
+/* macro for debug printing, used only if compiler flag _DEBUG_PRINT is
+ * defined */
+#ifdef _DEBUG_PRINT
+#define DEBUG(args) printf args
+#else
+#define DEBUG(args)
+#endif
+
+/* macro for error printing, used only if compiler flag _ERROR_PRINT is
+ * defined */
+#ifdef _ERROR_PRINT
+#define EPRINT(msg) fprintf(stderr,"ERROR: %s\n",msg)
+#else
+#define EPRINT(msg)
+#endif
+
+/* macro to get smaller of two values */
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+
+/* macro to get greater of two values */
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+
+/* macro to get absolute value */
+#define ABS(a) (((a) < 0) ? -(a) : (a))
+
+/* macro to clip a value z, so that x <= z =< y */
+#define CLIP3(x,y,z) (((z) < (x)) ? (x) : (((z) > (y)) ? (y) : (z)))
+
+/* macro to clip a value z, so that 0 <= z =< 255 */
+#define CLIP1(z) (((z) < 0) ? 0 : (((z) > 255) ? 255 : (z)))
+
+/* macro to allocate memory */
+#define ALLOCATE(ptr, count, type) \
+{ \
+ (ptr) = H264SwDecMalloc((count) * sizeof(type)); \
+}
+
+/* macro to free allocated memory */
+#define FREE(ptr) \
+{ \
+ H264SwDecFree((ptr)); (ptr) = NULL; \
+}
+
+#define ALIGN(ptr, bytePos) \
+ (ptr + ( ((bytePos - (int)ptr) & (bytePos - 1)) / sizeof(*ptr) ))
+
+extern const u32 h264bsdQpC[52];
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+#ifndef H264DEC_NEON
+u32 h264bsdCountLeadingZeros(u32 value, u32 length);
+#else
+u32 h264bsdCountLeadingZeros(u32 value);
+#endif
+u32 h264bsdRbspTrailingBits(strmData_t *strmData);
+
+u32 h264bsdMoreRbspData(strmData_t *strmData);
+
+u32 h264bsdNextMbAddress(u32 *pSliceGroupMap, u32 picSizeInMbs, u32 currMbAddr);
+
+void h264bsdSetCurrImageMbPointers(image_t *image, u32 mbNum);
+
+#endif /* #ifdef H264SWDEC_UTIL_H */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_vlc.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_vlc.c
new file mode 100755
index 0000000..060f35e
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_vlc.c
@@ -0,0 +1,391 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdDecodeExpGolombUnsigned
+ h264bsdDecodeExpGolombSigned
+ h264bsdDecodeExpGolombMapped
+ h264bsdDecodeExpGolombTruncated
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_vlc.h"
+#include "basetype.h"
+#include "h264bsd_stream.h"
+#include "h264bsd_util.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/* definition of special code num, this along with the return value is used
+ * to handle code num in the range [0, 2^32] in the DecodeExpGolombUnsigned
+ * function */
+#define BIG_CODE_NUM 0xFFFFFFFFU
+
+/* Mapping tables for coded_block_pattern, used for decoding of mapped
+ * Exp-Golomb codes */
+static const u8 codedBlockPatternIntra4x4[48] = {
+ 47,31,15,0,23,27,29,30,7,11,13,14,39,43,45,46,16,3,5,10,12,19,21,26,28,35,
+ 37,42,44,1,2,4,8,17,18,20,24,6,9,22,25,32,33,34,36,40,38,41};
+
+static const u8 codedBlockPatternInter[48] = {
+ 0,16,1,2,4,8,32,3,5,10,12,15,47,7,11,13,14,6,9,31,35,37,42,44,33,34,36,40,
+ 39,43,45,46,17,18,20,24,19,21,26,28,23,27,29,30,22,25,38,41};
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+
+ 5.1 Function: h264bsdDecodeExpGolombUnsigned
+
+ Functional description:
+ Decode unsigned Exp-Golomb code. This is the same as codeNum used
+ in other Exp-Golomb code mappings. Code num (i.e. the decoded
+ symbol) is determined as
+
+ codeNum = 2^leadingZeros - 1 + GetBits(leadingZeros)
+
+ Normal decoded symbols are in the range [0, 2^32 - 2]. Symbol
+ 2^32-1 is indicated by BIG_CODE_NUM with return value HANTRO_OK
+ while symbol 2^32 is indicated by BIG_CODE_NUM with return value
+ HANTRO_NOK. These two symbols are special cases with code length
+ of 65, i.e. 32 '0' bits, a '1' bit, and either 0 or 1 represented
+ by 32 bits.
+
+ Symbol 2^32 is out of unsigned 32-bit range but is needed for
+ DecodeExpGolombSigned to express value -2^31.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+
+ Outputs:
+ codeNum decoded code word is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK failure, no valid code word found, note exception
+ with BIG_CODE_NUM
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeExpGolombUnsigned(strmData_t *pStrmData, u32 *codeNum)
+{
+
+/* Variables */
+
+ u32 bits, numZeros;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(codeNum);
+
+ bits = h264bsdShowBits32(pStrmData);
+
+ /* first bit is 1 -> code length 1 */
+ if (bits >= 0x80000000)
+ {
+ h264bsdFlushBits(pStrmData, 1);
+ *codeNum = 0;
+ return(HANTRO_OK);
+ }
+ /* second bit is 1 -> code length 3 */
+ else if (bits >= 0x40000000)
+ {
+ if (h264bsdFlushBits(pStrmData, 3) == END_OF_STREAM)
+ return(HANTRO_NOK);
+ *codeNum = 1 + ((bits >> 29) & 0x1);
+ return(HANTRO_OK);
+ }
+ /* third bit is 1 -> code length 5 */
+ else if (bits >= 0x20000000)
+ {
+ if (h264bsdFlushBits(pStrmData, 5) == END_OF_STREAM)
+ return(HANTRO_NOK);
+ *codeNum = 3 + ((bits >> 27) & 0x3);
+ return(HANTRO_OK);
+ }
+ /* fourth bit is 1 -> code length 7 */
+ else if (bits >= 0x10000000)
+ {
+ if (h264bsdFlushBits(pStrmData, 7) == END_OF_STREAM)
+ return(HANTRO_NOK);
+ *codeNum = 7 + ((bits >> 25) & 0x7);
+ return(HANTRO_OK);
+ }
+ /* other code lengths */
+ else
+ {
+#ifndef H264DEC_NEON
+ numZeros = 4 + h264bsdCountLeadingZeros(bits, 28);
+#else
+ numZeros = h264bsdCountLeadingZeros(bits);
+#endif
+ /* all 32 bits are zero */
+ if (numZeros == 32)
+ {
+ *codeNum = 0;
+ h264bsdFlushBits(pStrmData,32);
+ bits = h264bsdGetBits(pStrmData, 1);
+ /* check 33rd bit, must be 1 */
+ if (bits == 1)
+ {
+ /* cannot use h264bsdGetBits, limited to 31 bits */
+ bits = h264bsdShowBits32(pStrmData);
+ if (h264bsdFlushBits(pStrmData, 32) == END_OF_STREAM)
+ return(HANTRO_NOK);
+ /* code num 2^32 - 1, needed for unsigned mapping */
+ if (bits == 0)
+ {
+ *codeNum = BIG_CODE_NUM;
+ return(HANTRO_OK);
+ }
+ /* code num 2^32, needed for unsigned mapping
+ * (results in -2^31) */
+ else if (bits == 1)
+ {
+ *codeNum = BIG_CODE_NUM;
+ return(HANTRO_NOK);
+ }
+ }
+ /* if more zeros than 32, it is an error */
+ return(HANTRO_NOK);
+ }
+ else
+ h264bsdFlushBits(pStrmData,numZeros+1);
+
+ bits = h264bsdGetBits(pStrmData, numZeros);
+ if (bits == END_OF_STREAM)
+ return(HANTRO_NOK);
+
+ *codeNum = (1 << numZeros) - 1 + bits;
+
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ 5.2 Function: h264bsdDecodeExpGolombSigned
+
+ Functional description:
+ Decode signed Exp-Golomb code. Code num is determined by
+ h264bsdDecodeExpGolombUnsigned and then mapped to signed
+ representation as
+
+ symbol = (-1)^(codeNum+1) * (codeNum+1)/2
+
+ Signed symbols shall be in the range [-2^31, 2^31 - 1]. Symbol
+ -2^31 is obtained when codeNum is 2^32, which cannot be expressed
+ by unsigned 32-bit value. This is signaled as a special case from
+ the h264bsdDecodeExpGolombUnsigned by setting codeNum to
+ BIG_CODE_NUM and returning HANTRO_NOK status.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+
+ Outputs:
+ value decoded code word is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK failure, no valid code word found
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeExpGolombSigned(strmData_t *pStrmData, i32 *value)
+{
+
+/* Variables */
+
+ u32 status, codeNum = 0;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(value);
+
+ status = h264bsdDecodeExpGolombUnsigned(pStrmData, &codeNum);
+
+ if (codeNum == BIG_CODE_NUM)
+ {
+ /* BIG_CODE_NUM and HANTRO_OK status means codeNum 2^32-1 which would
+ * result in signed integer valued 2^31 (i.e. out of 32-bit signed
+ * integer range) */
+ if (status == HANTRO_OK)
+ return(HANTRO_NOK);
+ /* BIG_CODE_NUM and HANTRO_NOK status means codeNum 2^32 which results
+ * in signed integer valued -2^31 */
+ else
+ {
+ *value = (i32)(2147483648U);
+ return (HANTRO_OK);
+ }
+ }
+ else if (status == HANTRO_OK)
+ {
+ /* (-1)^(codeNum+1) results in positive sign if codeNum is odd,
+ * negative when it is even. (codeNum+1)/2 is obtained as
+ * (codeNum+1)>>1 when value is positive and as (-codeNum)>>1 for
+ * negative value */
+ /*lint -e702 */
+ *value = (codeNum & 0x1) ? (i32)((codeNum + 1) >> 1) :
+ -(i32)((codeNum + 1) >> 1);
+ /*lint +e702 */
+ return(HANTRO_OK);
+ }
+
+ return(HANTRO_NOK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ 5.3 Function: h264bsdDecodeExpGolombMapped
+
+ Functional description:
+ Decode mapped Exp-Golomb code. Code num is determined by
+ h264bsdDecodeExpGolombUnsigned and then mapped to codedBlockPattern
+ either for intra or inter macroblock. The mapping is implemented by
+ look-up tables defined in the beginning of the file.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+ isIntra flag to indicate if intra or inter mapping is to
+ be used
+
+ Outputs:
+ value decoded code word is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK failure, no valid code word found
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeExpGolombMapped(strmData_t *pStrmData, u32 *value,
+ u32 isIntra)
+{
+
+/* Variables */
+
+ u32 status, codeNum;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(value);
+
+ status = h264bsdDecodeExpGolombUnsigned(pStrmData, &codeNum);
+
+ if (status != HANTRO_OK)
+ return (HANTRO_NOK);
+ else
+ {
+ /* range of valid codeNums [0,47] */
+ if (codeNum > 47)
+ return (HANTRO_NOK);
+ if (isIntra)
+ *value = codedBlockPatternIntra4x4[codeNum];
+ else
+ *value = codedBlockPatternInter[codeNum];
+ return(HANTRO_OK);
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ 5.4 Function: h264bsdDecodeExpGolombTruncated
+
+ Functional description:
+ Decode truncated Exp-Golomb code. greaterThanOne flag indicates
+ the range of the symbol to be decoded as follows:
+ FALSE -> [0,1]
+ TRUE -> [0,2^32-1]
+
+ If flag is false the decoding is performed by reading one bit
+ from the stream with h264bsdGetBits and mapping this to decoded
+ symbol as
+ symbol = bit ? 0 : 1
+
+ Otherwise, i.e. when flag is TRUE, code num is determined by
+ h264bsdDecodeExpGolombUnsigned and this is used as the decoded
+ symbol.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+ greaterThanOne flag to indicate if range is wider than [0,1]
+
+ Outputs:
+ value decoded code word is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK failure, no valid code word found
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeExpGolombTruncated(
+ strmData_t *pStrmData,
+ u32 *value,
+ u32 greaterThanOne)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(value);
+
+ if (greaterThanOne)
+ {
+ return(h264bsdDecodeExpGolombUnsigned(pStrmData, value));
+ }
+ else
+ {
+ *value = h264bsdGetBits(pStrmData,1);
+ if (*value == END_OF_STREAM)
+ return (HANTRO_NOK);
+ *value ^= 0x1;
+ }
+
+ return (HANTRO_OK);
+
+}
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_vlc.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_vlc.h
new file mode 100755
index 0000000..4c16773
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_vlc.h
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_VLC_H
+#define H264SWDEC_VLC_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_stream.h"
+#include "h264bsd_transform.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeExpGolombUnsigned(strmData_t *pStrmData, u32 *value);
+
+u32 h264bsdDecodeExpGolombSigned(strmData_t *pStrmData, i32 *value);
+
+u32 h264bsdDecodeExpGolombMapped(strmData_t *pStrmData, u32 *value,
+ u32 isIntra);
+
+u32 h264bsdDecodeExpGolombTruncated(strmData_t *pStrmData, u32 *value,
+ u32 greaterThanOne);
+
+#endif /* #ifdef H264SWDEC_VLC_H */
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_vui.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_vui.c
new file mode 100755
index 0000000..4a9335a
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_vui.c
@@ -0,0 +1,490 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdDecodeVuiParameters
+ DecodeHrdParameters
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_vui.h"
+#include "basetype.h"
+#include "h264bsd_vlc.h"
+#include "h264bsd_stream.h"
+#include "h264bsd_util.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+#define MAX_DPB_SIZE 16
+#define MAX_BR 240000 /* for level 5.1 */
+#define MAX_CPB 240000 /* for level 5.1 */
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+static u32 DecodeHrdParameters(
+ strmData_t *pStrmData,
+ hrdParameters_t *pHrdParameters);
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdDecodeVuiParameters
+
+ Functional description:
+ Decode VUI parameters from the stream. See standard for details.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+
+ Outputs:
+ pVuiParameters decoded information is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK invalid stream data or end of stream
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeVuiParameters(strmData_t *pStrmData,
+ vuiParameters_t *pVuiParameters)
+{
+
+/* Variables */
+
+ u32 tmp;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pVuiParameters);
+
+ H264SwDecMemset(pVuiParameters, 0, sizeof(vuiParameters_t));
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->aspectRatioPresentFlag = (tmp == 1) ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ if (pVuiParameters->aspectRatioPresentFlag)
+ {
+ tmp = h264bsdGetBits(pStrmData, 8);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->aspectRatioIdc = tmp;
+
+ if (pVuiParameters->aspectRatioIdc == ASPECT_RATIO_EXTENDED_SAR)
+ {
+ tmp = h264bsdGetBits(pStrmData, 16);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->sarWidth = tmp;
+
+ tmp = h264bsdGetBits(pStrmData, 16);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->sarHeight = tmp;
+ }
+ }
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->overscanInfoPresentFlag = (tmp == 1) ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ if (pVuiParameters->overscanInfoPresentFlag)
+ {
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->overscanAppropriateFlag = (tmp == 1) ?
+ HANTRO_TRUE : HANTRO_FALSE;
+ }
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->videoSignalTypePresentFlag = (tmp == 1) ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ if (pVuiParameters->videoSignalTypePresentFlag)
+ {
+ tmp = h264bsdGetBits(pStrmData, 3);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->videoFormat = tmp;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->videoFullRangeFlag = (tmp == 1) ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->colourDescriptionPresentFlag =
+ (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
+
+ if (pVuiParameters->colourDescriptionPresentFlag)
+ {
+ tmp = h264bsdGetBits(pStrmData, 8);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->colourPrimaries = tmp;
+
+ tmp = h264bsdGetBits(pStrmData, 8);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->transferCharacteristics = tmp;
+
+ tmp = h264bsdGetBits(pStrmData, 8);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->matrixCoefficients = tmp;
+ }
+ else
+ {
+ pVuiParameters->colourPrimaries = 2;
+ pVuiParameters->transferCharacteristics = 2;
+ pVuiParameters->matrixCoefficients = 2;
+ }
+ }
+ else
+ {
+ pVuiParameters->videoFormat = 5;
+ pVuiParameters->colourPrimaries = 2;
+ pVuiParameters->transferCharacteristics = 2;
+ pVuiParameters->matrixCoefficients = 2;
+ }
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->chromaLocInfoPresentFlag =
+ (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
+
+ if (pVuiParameters->chromaLocInfoPresentFlag)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pVuiParameters->chromaSampleLocTypeTopField);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pVuiParameters->chromaSampleLocTypeTopField > 5)
+ return(HANTRO_NOK);
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pVuiParameters->chromaSampleLocTypeBottomField);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pVuiParameters->chromaSampleLocTypeBottomField > 5)
+ return(HANTRO_NOK);
+ }
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->timingInfoPresentFlag =
+ (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
+
+ if (pVuiParameters->timingInfoPresentFlag)
+ {
+ tmp = h264bsdShowBits32(pStrmData);
+ if (h264bsdFlushBits(pStrmData, 32) == END_OF_STREAM)
+ return(HANTRO_NOK);
+ if (tmp == 0)
+ return(HANTRO_NOK);
+ pVuiParameters->numUnitsInTick = tmp;
+
+ tmp = h264bsdShowBits32(pStrmData);
+ if (h264bsdFlushBits(pStrmData, 32) == END_OF_STREAM)
+ return(HANTRO_NOK);
+ if (tmp == 0)
+ return(HANTRO_NOK);
+ pVuiParameters->timeScale = tmp;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->fixedFrameRateFlag =
+ (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
+ }
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->nalHrdParametersPresentFlag =
+ (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
+
+ if (pVuiParameters->nalHrdParametersPresentFlag)
+ {
+ tmp = DecodeHrdParameters(pStrmData, &pVuiParameters->nalHrdParameters);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+ else
+ {
+ pVuiParameters->nalHrdParameters.cpbCnt = 1;
+ /* MaxBR and MaxCPB should be the values correspondig to the levelIdc
+ * in the SPS containing these VUI parameters. However, these values
+ * are not used anywhere and maximum for any level will be used here */
+ pVuiParameters->nalHrdParameters.bitRateValue[0] = 1200 * MAX_BR + 1;
+ pVuiParameters->nalHrdParameters.cpbSizeValue[0] = 1200 * MAX_CPB + 1;
+ pVuiParameters->nalHrdParameters.initialCpbRemovalDelayLength = 24;
+ pVuiParameters->nalHrdParameters.cpbRemovalDelayLength = 24;
+ pVuiParameters->nalHrdParameters.dpbOutputDelayLength = 24;
+ pVuiParameters->nalHrdParameters.timeOffsetLength = 24;
+ }
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->vclHrdParametersPresentFlag =
+ (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
+
+ if (pVuiParameters->vclHrdParametersPresentFlag)
+ {
+ tmp = DecodeHrdParameters(pStrmData, &pVuiParameters->vclHrdParameters);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+ else
+ {
+ pVuiParameters->vclHrdParameters.cpbCnt = 1;
+ /* MaxBR and MaxCPB should be the values correspondig to the levelIdc
+ * in the SPS containing these VUI parameters. However, these values
+ * are not used anywhere and maximum for any level will be used here */
+ pVuiParameters->vclHrdParameters.bitRateValue[0] = 1000 * MAX_BR + 1;
+ pVuiParameters->vclHrdParameters.cpbSizeValue[0] = 1000 * MAX_CPB + 1;
+ pVuiParameters->vclHrdParameters.initialCpbRemovalDelayLength = 24;
+ pVuiParameters->vclHrdParameters.cpbRemovalDelayLength = 24;
+ pVuiParameters->vclHrdParameters.dpbOutputDelayLength = 24;
+ pVuiParameters->vclHrdParameters.timeOffsetLength = 24;
+ }
+
+ if (pVuiParameters->nalHrdParametersPresentFlag ||
+ pVuiParameters->vclHrdParametersPresentFlag)
+ {
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->lowDelayHrdFlag =
+ (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
+ }
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->picStructPresentFlag =
+ (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->bitstreamRestrictionFlag =
+ (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
+
+ if (pVuiParameters->bitstreamRestrictionFlag)
+ {
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->motionVectorsOverPicBoundariesFlag =
+ (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pVuiParameters->maxBytesPerPicDenom);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pVuiParameters->maxBytesPerPicDenom > 16)
+ return(HANTRO_NOK);
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pVuiParameters->maxBitsPerMbDenom);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pVuiParameters->maxBitsPerMbDenom > 16)
+ return(HANTRO_NOK);
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pVuiParameters->log2MaxMvLengthHorizontal);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pVuiParameters->log2MaxMvLengthHorizontal > 16)
+ return(HANTRO_NOK);
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pVuiParameters->log2MaxMvLengthVertical);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pVuiParameters->log2MaxMvLengthVertical > 16)
+ return(HANTRO_NOK);
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pVuiParameters->numReorderFrames);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pVuiParameters->maxDecFrameBuffering);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+ else
+ {
+ pVuiParameters->motionVectorsOverPicBoundariesFlag = HANTRO_TRUE;
+ pVuiParameters->maxBytesPerPicDenom = 2;
+ pVuiParameters->maxBitsPerMbDenom = 1;
+ pVuiParameters->log2MaxMvLengthHorizontal = 16;
+ pVuiParameters->log2MaxMvLengthVertical = 16;
+ pVuiParameters->numReorderFrames = MAX_DPB_SIZE;
+ pVuiParameters->maxDecFrameBuffering = MAX_DPB_SIZE;
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeHrdParameters
+
+ Functional description:
+ Decode HRD parameters from the stream. See standard for details.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+
+ Outputs:
+ pHrdParameters decoded information is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK invalid stream data
+
+------------------------------------------------------------------------------*/
+
+static u32 DecodeHrdParameters(
+ strmData_t *pStrmData,
+ hrdParameters_t *pHrdParameters)
+{
+
+/* Variables */
+
+ u32 tmp, i;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pHrdParameters);
+
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &pHrdParameters->cpbCnt);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ /* cpbCount = cpb_cnt_minus1 + 1 */
+ pHrdParameters->cpbCnt++;
+ if (pHrdParameters->cpbCnt > MAX_CPB_CNT)
+ return(HANTRO_NOK);
+
+ tmp = h264bsdGetBits(pStrmData, 4);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pHrdParameters->bitRateScale = tmp;
+
+ tmp = h264bsdGetBits(pStrmData, 4);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pHrdParameters->cpbSizeScale = tmp;
+
+ for (i = 0; i < pHrdParameters->cpbCnt; i++)
+ {
+ /* bit_rate_value_minus1 in the range [0, 2^32 - 2] */
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pHrdParameters->bitRateValue[i]);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pHrdParameters->bitRateValue[i] > 4294967294U)
+ return(HANTRO_NOK);
+ pHrdParameters->bitRateValue[i]++;
+ /* this may result in overflow, but this value is not used for
+ * anything */
+ pHrdParameters->bitRateValue[i] *=
+ 1 << (6 + pHrdParameters->bitRateScale);
+
+ /* cpb_size_value_minus1 in the range [0, 2^32 - 2] */
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pHrdParameters->cpbSizeValue[i]);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pHrdParameters->cpbSizeValue[i] > 4294967294U)
+ return(HANTRO_NOK);
+ pHrdParameters->cpbSizeValue[i]++;
+ /* this may result in overflow, but this value is not used for
+ * anything */
+ pHrdParameters->cpbSizeValue[i] *=
+ 1 << (4 + pHrdParameters->cpbSizeScale);
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pHrdParameters->cbrFlag[i] = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
+ }
+
+ tmp = h264bsdGetBits(pStrmData, 5);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pHrdParameters->initialCpbRemovalDelayLength = tmp + 1;
+
+ tmp = h264bsdGetBits(pStrmData, 5);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pHrdParameters->cpbRemovalDelayLength = tmp + 1;
+
+ tmp = h264bsdGetBits(pStrmData, 5);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pHrdParameters->dpbOutputDelayLength = tmp + 1;
+
+ tmp = h264bsdGetBits(pStrmData, 5);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pHrdParameters->timeOffsetLength = tmp;
+
+ return(HANTRO_OK);
+
+}
+
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_vui.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_vui.h
new file mode 100755
index 0000000..05d52a4
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_vui.h
@@ -0,0 +1,130 @@
+/*
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_VUI_H
+#define H264SWDEC_VUI_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_stream.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+#define MAX_CPB_CNT 32
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+/* enumerated sample aspect ratios, ASPECT_RATIO_M_N means M:N */
+enum
+{
+ ASPECT_RATIO_UNSPECIFIED = 0,
+ ASPECT_RATIO_1_1,
+ ASPECT_RATIO_12_11,
+ ASPECT_RATIO_10_11,
+ ASPECT_RATIO_16_11,
+ ASPECT_RATIO_40_33,
+ ASPECT_RATIO_24_11,
+ ASPECT_RATIO_20_11,
+ ASPECT_RATIO_32_11,
+ ASPECT_RATIO_80_33,
+ ASPECT_RATIO_18_11,
+ ASPECT_RATIO_15_11,
+ ASPECT_RATIO_64_33,
+ ASPECT_RATIO_160_99,
+ ASPECT_RATIO_EXTENDED_SAR = 255
+};
+
+/* structure to store Hypothetical Reference Decoder (HRD) parameters */
+typedef struct
+{
+ u32 cpbCnt;
+ u32 bitRateScale;
+ u32 cpbSizeScale;
+ u32 bitRateValue[MAX_CPB_CNT];
+ u32 cpbSizeValue[MAX_CPB_CNT];
+ u32 cbrFlag[MAX_CPB_CNT];
+ u32 initialCpbRemovalDelayLength;
+ u32 cpbRemovalDelayLength;
+ u32 dpbOutputDelayLength;
+ u32 timeOffsetLength;
+} hrdParameters_t;
+
+/* storage for VUI parameters */
+typedef struct
+{
+ u32 aspectRatioPresentFlag;
+ u32 aspectRatioIdc;
+ u32 sarWidth;
+ u32 sarHeight;
+ u32 overscanInfoPresentFlag;
+ u32 overscanAppropriateFlag;
+ u32 videoSignalTypePresentFlag;
+ u32 videoFormat;
+ u32 videoFullRangeFlag;
+ u32 colourDescriptionPresentFlag;
+ u32 colourPrimaries;
+ u32 transferCharacteristics;
+ u32 matrixCoefficients;
+ u32 chromaLocInfoPresentFlag;
+ u32 chromaSampleLocTypeTopField;
+ u32 chromaSampleLocTypeBottomField;
+ u32 timingInfoPresentFlag;
+ u32 numUnitsInTick;
+ u32 timeScale;
+ u32 fixedFrameRateFlag;
+ u32 nalHrdParametersPresentFlag;
+ hrdParameters_t nalHrdParameters;
+ u32 vclHrdParametersPresentFlag;
+ hrdParameters_t vclHrdParameters;
+ u32 lowDelayHrdFlag;
+ u32 picStructPresentFlag;
+ u32 bitstreamRestrictionFlag;
+ u32 motionVectorsOverPicBoundariesFlag;
+ u32 maxBytesPerPicDenom;
+ u32 maxBitsPerMbDenom;
+ u32 log2MaxMvLengthHorizontal;
+ u32 log2MaxMvLengthVertical;
+ u32 numReorderFrames;
+ u32 maxDecFrameBuffering;
+} vuiParameters_t;
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeVuiParameters(strmData_t *pStrmData,
+ vuiParameters_t *pVuiParameters);
+
+#endif /* #ifdef H264SWDEC_VUI_H */
+
diff --git a/media/libstagefright/codecs/vorbis/dec/Android.mk b/media/libstagefright/codecs/vorbis/dec/Android.mk
index 5c768c8..f33f3ac 100644
--- a/media/libstagefright/codecs/vorbis/dec/Android.mk
+++ b/media/libstagefright/codecs/vorbis/dec/Android.mk
@@ -2,12 +2,19 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
- VorbisDecoder.cpp \
+ SoftVorbis.cpp
LOCAL_C_INCLUDES := \
+ external/tremolo \
frameworks/base/media/libstagefright/include \
- external/tremolo
+ frameworks/base/include/media/stagefright/openmax \
-LOCAL_MODULE := libstagefright_vorbisdec
+LOCAL_SHARED_LIBRARIES := \
+ libvorbisidec libstagefright libstagefright_omx \
+ libstagefright_foundation libutils
-include $(BUILD_STATIC_LIBRARY)
+LOCAL_MODULE := libstagefright_soft_vorbisdec
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_SHARED_LIBRARY)
+
diff --git a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
new file mode 100644
index 0000000..4091111
--- /dev/null
+++ b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
@@ -0,0 +1,445 @@
+/*
+ * Copyright (C) 2011 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 "SoftVorbis"
+#include <utils/Log.h>
+
+#include "SoftVorbis.h"
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/MediaDefs.h>
+
+extern "C" {
+ #include <Tremolo/codec_internal.h>
+
+ int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb);
+ int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb);
+ int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb);
+}
+
+namespace android {
+
+template<class T>
+static void InitOMXParams(T *params) {
+ params->nSize = sizeof(T);
+ params->nVersion.s.nVersionMajor = 1;
+ params->nVersion.s.nVersionMinor = 0;
+ params->nVersion.s.nRevision = 0;
+ params->nVersion.s.nStep = 0;
+}
+
+SoftVorbis::SoftVorbis(
+ const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component)
+ : SimpleSoftOMXComponent(name, callbacks, appData, component),
+ mInputBufferCount(0),
+ mState(NULL),
+ mVi(NULL),
+ mAnchorTimeUs(0),
+ mNumFramesOutput(0),
+ mNumFramesLeftOnPage(-1),
+ mOutputPortSettingsChange(NONE) {
+ initPorts();
+ CHECK_EQ(initDecoder(), (status_t)OK);
+}
+
+SoftVorbis::~SoftVorbis() {
+ if (mState != NULL) {
+ vorbis_dsp_clear(mState);
+ delete mState;
+ mState = NULL;
+ }
+
+ if (mVi != NULL) {
+ vorbis_info_clear(mVi);
+ delete mVi;
+ mVi = NULL;
+ }
+}
+
+void SoftVorbis::initPorts() {
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ InitOMXParams(&def);
+
+ def.nPortIndex = 0;
+ def.eDir = OMX_DirInput;
+ def.nBufferCountMin = kNumBuffers;
+ def.nBufferCountActual = def.nBufferCountMin;
+ def.nBufferSize = 8192;
+ def.bEnabled = OMX_TRUE;
+ def.bPopulated = OMX_FALSE;
+ def.eDomain = OMX_PortDomainAudio;
+ def.bBuffersContiguous = OMX_FALSE;
+ def.nBufferAlignment = 1;
+
+ def.format.audio.cMIMEType =
+ const_cast<char *>(MEDIA_MIMETYPE_AUDIO_VORBIS);
+
+ def.format.audio.pNativeRender = NULL;
+ def.format.audio.bFlagErrorConcealment = OMX_FALSE;
+ def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
+
+ addPort(def);
+
+ def.nPortIndex = 1;
+ def.eDir = OMX_DirOutput;
+ def.nBufferCountMin = kNumBuffers;
+ def.nBufferCountActual = def.nBufferCountMin;
+ def.nBufferSize = kMaxNumSamplesPerBuffer * sizeof(int16_t);
+ def.bEnabled = OMX_TRUE;
+ def.bPopulated = OMX_FALSE;
+ def.eDomain = OMX_PortDomainAudio;
+ def.bBuffersContiguous = OMX_FALSE;
+ def.nBufferAlignment = 2;
+
+ def.format.audio.cMIMEType = const_cast<char *>("audio/raw");
+ def.format.audio.pNativeRender = NULL;
+ def.format.audio.bFlagErrorConcealment = OMX_FALSE;
+ def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
+
+ addPort(def);
+}
+
+status_t SoftVorbis::initDecoder() {
+ return OK;
+}
+
+OMX_ERRORTYPE SoftVorbis::internalGetParameter(
+ OMX_INDEXTYPE index, OMX_PTR params) {
+ switch (index) {
+ case OMX_IndexParamAudioVorbis:
+ {
+ OMX_AUDIO_PARAM_VORBISTYPE *vorbisParams =
+ (OMX_AUDIO_PARAM_VORBISTYPE *)params;
+
+ if (vorbisParams->nPortIndex != 0) {
+ return OMX_ErrorUndefined;
+ }
+
+ vorbisParams->nBitRate = 0;
+ vorbisParams->nMinBitRate = 0;
+ vorbisParams->nMaxBitRate = 0;
+ vorbisParams->nAudioBandWidth = 0;
+ vorbisParams->nQuality = 3;
+ vorbisParams->bManaged = OMX_FALSE;
+ vorbisParams->bDownmix = OMX_FALSE;
+
+ if (!isConfigured()) {
+ vorbisParams->nChannels = 1;
+ vorbisParams->nSampleRate = 44100;
+ } else {
+ vorbisParams->nChannels = mVi->channels;
+ vorbisParams->nSampleRate = mVi->rate;
+ vorbisParams->nBitRate = mVi->bitrate_nominal;
+ vorbisParams->nMinBitRate = mVi->bitrate_lower;
+ vorbisParams->nMaxBitRate = mVi->bitrate_upper;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ case OMX_IndexParamAudioPcm:
+ {
+ OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
+ (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
+
+ if (pcmParams->nPortIndex != 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ pcmParams->eNumData = OMX_NumericalDataSigned;
+ pcmParams->eEndian = OMX_EndianBig;
+ pcmParams->bInterleaved = OMX_TRUE;
+ pcmParams->nBitPerSample = 16;
+ pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
+ pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
+ pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
+
+ if (!isConfigured()) {
+ pcmParams->nChannels = 1;
+ pcmParams->nSamplingRate = 44100;
+ } else {
+ pcmParams->nChannels = mVi->channels;
+ pcmParams->nSamplingRate = mVi->rate;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ default:
+ return SimpleSoftOMXComponent::internalGetParameter(index, params);
+ }
+}
+
+OMX_ERRORTYPE SoftVorbis::internalSetParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params) {
+ switch (index) {
+ case OMX_IndexParamStandardComponentRole:
+ {
+ const OMX_PARAM_COMPONENTROLETYPE *roleParams =
+ (const OMX_PARAM_COMPONENTROLETYPE *)params;
+
+ if (strncmp((const char *)roleParams->cRole,
+ "audio_decoder.vorbis",
+ OMX_MAX_STRINGNAME_SIZE - 1)) {
+ return OMX_ErrorUndefined;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ case OMX_IndexParamAudioVorbis:
+ {
+ const OMX_AUDIO_PARAM_VORBISTYPE *vorbisParams =
+ (const OMX_AUDIO_PARAM_VORBISTYPE *)params;
+
+ if (vorbisParams->nPortIndex != 0) {
+ return OMX_ErrorUndefined;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ default:
+ return SimpleSoftOMXComponent::internalSetParameter(index, params);
+ }
+}
+
+bool SoftVorbis::isConfigured() const {
+ return mInputBufferCount >= 2;
+}
+
+static void makeBitReader(
+ const void *data, size_t size,
+ ogg_buffer *buf, ogg_reference *ref, oggpack_buffer *bits) {
+ buf->data = (uint8_t *)data;
+ buf->size = size;
+ buf->refcount = 1;
+ buf->ptr.owner = NULL;
+
+ ref->buffer = buf;
+ ref->begin = 0;
+ ref->length = size;
+ ref->next = NULL;
+
+ oggpack_readinit(bits, ref);
+}
+
+void SoftVorbis::onQueueFilled(OMX_U32 portIndex) {
+ List<BufferInfo *> &inQueue = getPortQueue(0);
+ List<BufferInfo *> &outQueue = getPortQueue(1);
+
+ if (mOutputPortSettingsChange != NONE) {
+ return;
+ }
+
+ if (portIndex == 0 && mInputBufferCount < 2) {
+ BufferInfo *info = *inQueue.begin();
+ OMX_BUFFERHEADERTYPE *header = info->mHeader;
+
+ const uint8_t *data = header->pBuffer + header->nOffset;
+ size_t size = header->nFilledLen;
+
+ ogg_buffer buf;
+ ogg_reference ref;
+ oggpack_buffer bits;
+
+ makeBitReader(
+ (const uint8_t *)data + 7, size - 7,
+ &buf, &ref, &bits);
+
+ if (mInputBufferCount == 0) {
+ CHECK(mVi == NULL);
+ mVi = new vorbis_info;
+ vorbis_info_init(mVi);
+
+ CHECK_EQ(0, _vorbis_unpack_info(mVi, &bits));
+ } else {
+ CHECK_EQ(0, _vorbis_unpack_books(mVi, &bits));
+
+ CHECK(mState == NULL);
+ mState = new vorbis_dsp_state;
+ CHECK_EQ(0, vorbis_dsp_init(mState, mVi));
+
+ notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
+ mOutputPortSettingsChange = AWAITING_DISABLED;
+ }
+
+ inQueue.erase(inQueue.begin());
+ info->mOwnedByUs = false;
+ notifyEmptyBufferDone(header);
+
+ ++mInputBufferCount;
+
+ return;
+ }
+
+ while (!inQueue.empty() && !outQueue.empty()) {
+ BufferInfo *inInfo = *inQueue.begin();
+ OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
+
+ BufferInfo *outInfo = *outQueue.begin();
+ OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
+
+ if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
+ inQueue.erase(inQueue.begin());
+ inInfo->mOwnedByUs = false;
+ notifyEmptyBufferDone(inHeader);
+
+ outHeader->nFilledLen = 0;
+ outHeader->nFlags = OMX_BUFFERFLAG_EOS;
+
+ outQueue.erase(outQueue.begin());
+ outInfo->mOwnedByUs = false;
+ notifyFillBufferDone(outHeader);
+ return;
+ }
+
+ int32_t numPageSamples;
+ CHECK_GE(inHeader->nFilledLen, sizeof(numPageSamples));
+ memcpy(&numPageSamples,
+ inHeader->pBuffer
+ + inHeader->nOffset + inHeader->nFilledLen - 4,
+ sizeof(numPageSamples));
+
+ if (numPageSamples >= 0) {
+ mNumFramesLeftOnPage = numPageSamples;
+ }
+
+ if (inHeader->nOffset == 0) {
+ mAnchorTimeUs = inHeader->nTimeStamp;
+ mNumFramesOutput = 0;
+ }
+
+ inHeader->nFilledLen -= sizeof(numPageSamples);;
+
+ ogg_buffer buf;
+ buf.data = inHeader->pBuffer + inHeader->nOffset;
+ buf.size = inHeader->nFilledLen;
+ buf.refcount = 1;
+ buf.ptr.owner = NULL;
+
+ ogg_reference ref;
+ ref.buffer = &buf;
+ ref.begin = 0;
+ ref.length = buf.size;
+ ref.next = NULL;
+
+ ogg_packet pack;
+ pack.packet = &ref;
+ pack.bytes = ref.length;
+ pack.b_o_s = 0;
+ pack.e_o_s = 0;
+ pack.granulepos = 0;
+ pack.packetno = 0;
+
+ int numFrames = 0;
+
+ int err = vorbis_dsp_synthesis(mState, &pack, 1);
+ if (err != 0) {
+ LOGW("vorbis_dsp_synthesis returned %d", err);
+ } else {
+ numFrames = vorbis_dsp_pcmout(
+ mState, (int16_t *)outHeader->pBuffer,
+ kMaxNumSamplesPerBuffer);
+
+ if (numFrames < 0) {
+ LOGE("vorbis_dsp_pcmout returned %d", numFrames);
+ numFrames = 0;
+ }
+ }
+
+ if (mNumFramesLeftOnPage >= 0) {
+ if (numFrames > mNumFramesLeftOnPage) {
+ LOGV("discarding %d frames at end of page",
+ numFrames - mNumFramesLeftOnPage);
+ numFrames = mNumFramesLeftOnPage;
+ }
+ mNumFramesLeftOnPage -= numFrames;
+ }
+
+ outHeader->nFilledLen = numFrames * sizeof(int16_t) * mVi->channels;
+ outHeader->nOffset = 0;
+ outHeader->nFlags = 0;
+
+ outHeader->nTimeStamp =
+ mAnchorTimeUs
+ + (mNumFramesOutput * 1000000ll) / mVi->rate;
+
+ mNumFramesOutput += numFrames;
+
+ inInfo->mOwnedByUs = false;
+ inQueue.erase(inQueue.begin());
+ inInfo = NULL;
+ notifyEmptyBufferDone(inHeader);
+ inHeader = NULL;
+
+ outInfo->mOwnedByUs = false;
+ outQueue.erase(outQueue.begin());
+ outInfo = NULL;
+ notifyFillBufferDone(outHeader);
+ outHeader = NULL;
+
+ ++mInputBufferCount;
+ }
+}
+
+void SoftVorbis::onPortFlushCompleted(OMX_U32 portIndex) {
+ if (portIndex == 0 && mState != NULL) {
+ // Make sure that the next buffer output does not still
+ // depend on fragments from the last one decoded.
+
+ mNumFramesOutput = 0;
+ vorbis_dsp_restart(mState);
+ }
+}
+
+void SoftVorbis::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
+ if (portIndex != 1) {
+ return;
+ }
+
+ switch (mOutputPortSettingsChange) {
+ case NONE:
+ break;
+
+ case AWAITING_DISABLED:
+ {
+ CHECK(!enabled);
+ mOutputPortSettingsChange = AWAITING_ENABLED;
+ break;
+ }
+
+ default:
+ {
+ CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED);
+ CHECK(enabled);
+ mOutputPortSettingsChange = NONE;
+ break;
+ }
+ }
+}
+
+} // namespace android
+
+android::SoftOMXComponent *createSoftOMXComponent(
+ const char *name, const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData, OMX_COMPONENTTYPE **component) {
+ return new android::SoftVorbis(name, callbacks, appData, component);
+}
diff --git a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.h b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.h
new file mode 100644
index 0000000..e252f55
--- /dev/null
+++ b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2011 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 SOFT_VORBIS_H_
+
+#define SOFT_VORBIS_H_
+
+#include "SimpleSoftOMXComponent.h"
+
+struct vorbis_dsp_state;
+struct vorbis_info;
+
+namespace android {
+
+struct SoftVorbis : public SimpleSoftOMXComponent {
+ SoftVorbis(const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component);
+
+protected:
+ virtual ~SoftVorbis();
+
+ virtual OMX_ERRORTYPE internalGetParameter(
+ OMX_INDEXTYPE index, OMX_PTR params);
+
+ virtual OMX_ERRORTYPE internalSetParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params);
+
+ virtual void onQueueFilled(OMX_U32 portIndex);
+ virtual void onPortFlushCompleted(OMX_U32 portIndex);
+ virtual void onPortEnableCompleted(OMX_U32 portIndex, bool enabled);
+
+private:
+ enum {
+ kNumBuffers = 4,
+ kMaxNumSamplesPerBuffer = 8192 * 2
+ };
+
+ size_t mInputBufferCount;
+
+ vorbis_dsp_state *mState;
+ vorbis_info *mVi;
+
+ int64_t mAnchorTimeUs;
+ int64_t mNumFramesOutput;
+ int32_t mNumFramesLeftOnPage;
+
+ enum {
+ NONE,
+ AWAITING_DISABLED,
+ AWAITING_ENABLED
+ } mOutputPortSettingsChange;
+
+ void initPorts();
+ status_t initDecoder();
+ bool isConfigured() const;
+
+ DISALLOW_EVIL_CONSTRUCTORS(SoftVorbis);
+};
+
+} // namespace android
+
+#endif // SOFT_VORBIS_H_
+
diff --git a/media/libstagefright/codecs/vorbis/dec/VorbisDecoder.cpp b/media/libstagefright/codecs/vorbis/dec/VorbisDecoder.cpp
deleted file mode 100644
index e14fb95..0000000
--- a/media/libstagefright/codecs/vorbis/dec/VorbisDecoder.cpp
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * Copyright (C) 2010 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 "VorbisDecoder"
-#include <utils/Log.h>
-
-#include "VorbisDecoder.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>
-
-extern "C" {
- #include <Tremolo/codec_internal.h>
-
- int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb);
- int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb);
- int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb);
-}
-
-namespace android {
-
-VorbisDecoder::VorbisDecoder(const sp<MediaSource> &source)
- : mSource(source),
- mStarted(false),
- mBufferGroup(NULL),
- mAnchorTimeUs(0),
- mNumFramesOutput(0),
- mState(NULL),
- mVi(NULL) {
- sp<MetaData> srcFormat = mSource->getFormat();
- CHECK(srcFormat->findInt32(kKeyChannelCount, &mNumChannels));
- CHECK(srcFormat->findInt32(kKeySampleRate, &mSampleRate));
-}
-
-VorbisDecoder::~VorbisDecoder() {
- if (mStarted) {
- stop();
- }
-}
-
-static void makeBitReader(
- const void *data, size_t size,
- ogg_buffer *buf, ogg_reference *ref, oggpack_buffer *bits) {
- buf->data = (uint8_t *)data;
- buf->size = size;
- buf->refcount = 1;
- buf->ptr.owner = NULL;
-
- ref->buffer = buf;
- ref->begin = 0;
- ref->length = size;
- ref->next = NULL;
-
- oggpack_readinit(bits, ref);
-}
-
-status_t VorbisDecoder::start(MetaData *params) {
- CHECK(!mStarted);
-
- mBufferGroup = new MediaBufferGroup;
- mBufferGroup->add_buffer(
- new MediaBuffer(kMaxNumSamplesPerBuffer * sizeof(int16_t)));
-
- mSource->start();
-
- sp<MetaData> meta = mSource->getFormat();
-
- mVi = new vorbis_info;
- vorbis_info_init(mVi);
-
- ///////////////////////////////////////////////////////////////////////////
-
- uint32_t type;
- const void *data;
- size_t size;
- CHECK(meta->findData(kKeyVorbisInfo, &type, &data, &size));
-
- ogg_buffer buf;
- ogg_reference ref;
- oggpack_buffer bits;
- makeBitReader((const uint8_t *)data + 7, size - 7, &buf, &ref, &bits);
- CHECK_EQ(0, _vorbis_unpack_info(mVi, &bits));
-
- ///////////////////////////////////////////////////////////////////////////
-
- CHECK(meta->findData(kKeyVorbisBooks, &type, &data, &size));
-
- makeBitReader((const uint8_t *)data + 7, size - 7, &buf, &ref, &bits);
- CHECK_EQ(0, _vorbis_unpack_books(mVi, &bits));
-
- ///////////////////////////////////////////////////////////////////////////
-
- mState = new vorbis_dsp_state;
- CHECK_EQ(0, vorbis_dsp_init(mState, mVi));
-
- mAnchorTimeUs = 0;
- mNumFramesOutput = 0;
-
- // If the source never limits the number of valid frames contained
- // in the input data, we'll assume that all of the decoded frames are
- // valid.
- mNumFramesLeftOnPage = -1;
-
- mStarted = true;
-
- return OK;
-}
-
-status_t VorbisDecoder::stop() {
- CHECK(mStarted);
-
- vorbis_dsp_clear(mState);
- delete mState;
- mState = NULL;
-
- vorbis_info_clear(mVi);
- delete mVi;
- mVi = NULL;
-
- delete mBufferGroup;
- mBufferGroup = NULL;
-
- mSource->stop();
-
- mStarted = false;
-
- return OK;
-}
-
-sp<MetaData> VorbisDecoder::getFormat() {
- sp<MetaData> srcFormat = mSource->getFormat();
-
- sp<MetaData> meta = new MetaData;
- meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
- meta->setInt32(kKeyChannelCount, mNumChannels);
- meta->setInt32(kKeySampleRate, mSampleRate);
-
- int64_t durationUs;
- if (srcFormat->findInt64(kKeyDuration, &durationUs)) {
- meta->setInt64(kKeyDuration, durationUs);
- }
-
- meta->setCString(kKeyDecoderComponent, "VorbisDecoder");
-
- return meta;
-}
-
-int VorbisDecoder::decodePacket(MediaBuffer *packet, MediaBuffer *out) {
- ogg_buffer buf;
- buf.data = (uint8_t *)packet->data() + packet->range_offset();
- buf.size = packet->range_length();
- buf.refcount = 1;
- buf.ptr.owner = NULL;
-
- ogg_reference ref;
- ref.buffer = &buf;
- ref.begin = 0;
- ref.length = packet->range_length();
- ref.next = NULL;
-
- ogg_packet pack;
- pack.packet = &ref;
- pack.bytes = packet->range_length();
- pack.b_o_s = 0;
- pack.e_o_s = 0;
- pack.granulepos = 0;
- pack.packetno = 0;
-
- int numFrames = 0;
-
- int err = vorbis_dsp_synthesis(mState, &pack, 1);
- if (err != 0) {
- LOGW("vorbis_dsp_synthesis returned %d", err);
- } else {
- numFrames = vorbis_dsp_pcmout(
- mState, (int16_t *)out->data(), kMaxNumSamplesPerBuffer);
-
- if (numFrames < 0) {
- LOGE("vorbis_dsp_pcmout returned %d", numFrames);
- numFrames = 0;
- }
- }
-
- if (mNumFramesLeftOnPage >= 0) {
- if (numFrames > mNumFramesLeftOnPage) {
- LOGV("discarding %d frames at end of page",
- numFrames - mNumFramesLeftOnPage);
- numFrames = mNumFramesLeftOnPage;
- }
- mNumFramesLeftOnPage -= numFrames;
- }
-
- out->set_range(0, numFrames * sizeof(int16_t) * mNumChannels);
-
- return numFrames;
-}
-
-status_t VorbisDecoder::read(
- MediaBuffer **out, const ReadOptions *options) {
- status_t err;
-
- *out = NULL;
-
- int64_t seekTimeUs;
- ReadOptions::SeekMode mode;
- if (options && options->getSeekTo(&seekTimeUs, &mode)) {
- CHECK(seekTimeUs >= 0);
-
- mNumFramesOutput = 0;
- vorbis_dsp_restart(mState);
- } else {
- seekTimeUs = -1;
- }
-
- MediaBuffer *inputBuffer;
- err = mSource->read(&inputBuffer, options);
-
- if (err != OK) {
- return ERROR_END_OF_STREAM;
- }
-
- int64_t timeUs;
- if (inputBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) {
- mAnchorTimeUs = timeUs;
- mNumFramesOutput = 0;
- } else {
- // We must have a new timestamp after seeking.
- CHECK(seekTimeUs < 0);
- }
-
- int32_t numPageSamples;
- if (inputBuffer->meta_data()->findInt32(
- kKeyValidSamples, &numPageSamples)) {
- CHECK(numPageSamples >= 0);
- mNumFramesLeftOnPage = numPageSamples;
- }
-
- MediaBuffer *outputBuffer;
- CHECK_EQ(mBufferGroup->acquire_buffer(&outputBuffer), OK);
-
- int numFrames = decodePacket(inputBuffer, outputBuffer);
-
- inputBuffer->release();
- inputBuffer = NULL;
-
- outputBuffer->meta_data()->setInt64(
- kKeyTime,
- mAnchorTimeUs
- + (mNumFramesOutput * 1000000ll) / mSampleRate);
-
- mNumFramesOutput += numFrames;
-
- *out = outputBuffer;
-
- return OK;
-}
-
-} // namespace android
diff --git a/media/libstagefright/colorconversion/ColorConverter.cpp b/media/libstagefright/colorconversion/ColorConverter.cpp
index 3b92e5d..5cc3f78 100644
--- a/media/libstagefright/colorconversion/ColorConverter.cpp
+++ b/media/libstagefright/colorconversion/ColorConverter.cpp
@@ -14,14 +14,16 @@
* limitations under the License.
*/
+//#define LOG_NDEBUG 0
+#define LOG_TAG "ColorConverter"
+#include <utils/Log.h>
+
#include <media/stagefright/ColorConverter.h>
#include <media/stagefright/MediaDebug.h>
#include <media/stagefright/MediaErrors.h>
namespace android {
-static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00;
-
ColorConverter::ColorConverter(
OMX_COLOR_FORMATTYPE from, OMX_COLOR_FORMATTYPE to)
: mSrcFormat(from),
@@ -44,6 +46,7 @@
case OMX_COLOR_FormatCbYCrY:
case OMX_QCOM_COLOR_FormatYVU420SemiPlanar:
case OMX_COLOR_FormatYUV420SemiPlanar:
+ case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar:
return true;
default:
@@ -115,6 +118,10 @@
err = convertYUV420SemiPlanar(src, dst);
break;
+ case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar:
+ err = convertTIYUV420PackedSemiPlanar(src, dst);
+ break;
+
default:
{
CHECK(!"Should not be here. Unknown color conversion.");
@@ -187,8 +194,7 @@
status_t ColorConverter::convertYUV420Planar(
const BitmapParams &src, const BitmapParams &dst) {
- if (!((dst.mWidth & 1) == 0
- && (src.mCropLeft & 1) == 0
+ if (!((src.mCropLeft & 1) == 0
&& src.cropWidth() == dst.cropWidth()
&& src.cropHeight() == dst.cropHeight())) {
return ERROR_UNSUPPORTED;
@@ -196,8 +202,8 @@
uint8_t *kAdjustedClip = initClip();
- uint32_t *dst_ptr = (uint32_t *)dst.mBits
- + (dst.mCropTop * dst.mWidth + dst.mCropLeft) / 2;
+ uint16_t *dst_ptr = (uint16_t *)dst.mBits
+ + dst.mCropTop * dst.mWidth + dst.mCropLeft;
const uint8_t *src_y =
(const uint8_t *)src.mBits + src.mCropTop * src.mWidth + src.mCropLeft;
@@ -260,7 +266,11 @@
| ((kAdjustedClip[g2] >> 2) << 5)
| (kAdjustedClip[b2] >> 3);
- dst_ptr[x / 2] = (rgb2 << 16) | rgb1;
+ if (x + 1 < src.cropWidth()) {
+ *(uint32_t *)(&dst_ptr[x]) = (rgb2 << 16) | rgb1;
+ } else {
+ dst_ptr[x] = rgb1;
+ }
}
src_y += src.mWidth;
@@ -270,7 +280,7 @@
src_v += src.mWidth / 2;
}
- dst_ptr += dst.mWidth / 2;
+ dst_ptr += dst.mWidth;
}
return OK;
@@ -416,6 +426,73 @@
return OK;
}
+status_t ColorConverter::convertTIYUV420PackedSemiPlanar(
+ const BitmapParams &src, const BitmapParams &dst) {
+ uint8_t *kAdjustedClip = initClip();
+
+ if (!((dst.mWidth & 3) == 0
+ && (src.mCropLeft & 1) == 0
+ && src.cropWidth() == dst.cropWidth()
+ && src.cropHeight() == dst.cropHeight())) {
+ return ERROR_UNSUPPORTED;
+ }
+
+ uint32_t *dst_ptr = (uint32_t *)dst.mBits
+ + (dst.mCropTop * dst.mWidth + dst.mCropLeft) / 2;
+
+ const uint8_t *src_y = (const uint8_t *)src.mBits;
+
+ const uint8_t *src_u =
+ (const uint8_t *)src_y + src.mWidth * (src.mHeight - src.mCropTop / 2);
+
+ for (size_t y = 0; y < src.cropHeight(); ++y) {
+ for (size_t x = 0; x < src.cropWidth(); x += 2) {
+ signed y1 = (signed)src_y[x] - 16;
+ signed y2 = (signed)src_y[x + 1] - 16;
+
+ signed u = (signed)src_u[x & ~1] - 128;
+ signed v = (signed)src_u[(x & ~1) + 1] - 128;
+
+ signed u_b = u * 517;
+ signed u_g = -u * 100;
+ signed v_g = -v * 208;
+ signed v_r = v * 409;
+
+ signed tmp1 = y1 * 298;
+ signed b1 = (tmp1 + u_b) / 256;
+ signed g1 = (tmp1 + v_g + u_g) / 256;
+ signed r1 = (tmp1 + v_r) / 256;
+
+ signed tmp2 = y2 * 298;
+ signed b2 = (tmp2 + u_b) / 256;
+ signed g2 = (tmp2 + v_g + u_g) / 256;
+ signed r2 = (tmp2 + v_r) / 256;
+
+ uint32_t rgb1 =
+ ((kAdjustedClip[r1] >> 3) << 11)
+ | ((kAdjustedClip[g1] >> 2) << 5)
+ | (kAdjustedClip[b1] >> 3);
+
+ uint32_t rgb2 =
+ ((kAdjustedClip[r2] >> 3) << 11)
+ | ((kAdjustedClip[g2] >> 2) << 5)
+ | (kAdjustedClip[b2] >> 3);
+
+ dst_ptr[x / 2] = (rgb2 << 16) | rgb1;
+ }
+
+ src_y += src.mWidth;
+
+ if (y & 1) {
+ src_u += src.mWidth;
+ }
+
+ dst_ptr += dst.mWidth / 2;
+ }
+
+ return OK;
+}
+
uint8_t *ColorConverter::initClip() {
static const signed kClipMin = -278;
static const signed kClipMax = 535;
diff --git a/media/libstagefright/colorconversion/SoftwareRenderer.cpp b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
index 31afc43..3246021 100644
--- a/media/libstagefright/colorconversion/SoftwareRenderer.cpp
+++ b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
@@ -50,15 +50,31 @@
mCropBottom = mHeight - 1;
}
+ mCropWidth = mCropRight - mCropLeft + 1;
+ mCropHeight = mCropBottom - mCropTop + 1;
+
int32_t rotationDegrees;
if (!meta->findInt32(kKeyRotation, &rotationDegrees)) {
rotationDegrees = 0;
}
int halFormat;
+ size_t bufWidth, bufHeight;
+
switch (mColorFormat) {
+ case OMX_COLOR_FormatYUV420Planar:
+ case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar:
+ {
+ halFormat = HAL_PIXEL_FORMAT_YV12;
+ bufWidth = (mCropWidth + 1) & ~1;
+ bufHeight = (mCropHeight + 1) & ~1;
+ break;
+ }
+
default:
halFormat = HAL_PIXEL_FORMAT_RGB_565;
+ bufWidth = mCropWidth;
+ bufHeight = mCropHeight;
mConverter = new ColorConverter(
mColorFormat, OMX_COLOR_Format16bitRGB565);
@@ -67,8 +83,8 @@
}
CHECK(mNativeWindow != NULL);
- CHECK(mWidth > 0);
- CHECK(mHeight > 0);
+ CHECK(mCropWidth > 0);
+ CHECK(mCropHeight > 0);
CHECK(mConverter == NULL || mConverter->isValid());
CHECK_EQ(0,
@@ -77,13 +93,16 @@
GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN
| GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP));
- CHECK_EQ(0, native_window_set_buffer_count(mNativeWindow.get(), 2));
+ CHECK_EQ(0,
+ native_window_set_scaling_mode(
+ mNativeWindow.get(),
+ NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW));
// Width must be multiple of 32???
CHECK_EQ(0, native_window_set_buffers_geometry(
mNativeWindow.get(),
- mCropRight - mCropLeft + 1,
- mCropBottom - mCropTop + 1,
+ bufWidth,
+ bufHeight,
halFormat));
uint32_t transform;
@@ -106,9 +125,14 @@
mConverter = NULL;
}
+static int ALIGN(int x, int y) {
+ // y must be a power of 2.
+ return (x + y - 1) & ~(y - 1);
+}
+
void SoftwareRenderer::render(
const void *data, size_t size, void *platformPrivate) {
- android_native_buffer_t *buf;
+ ANativeWindowBuffer *buf;
int err;
if ((err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf)) != 0) {
LOGW("Surface::dequeueBuffer returned error %d", err);
@@ -119,7 +143,7 @@
GraphicBufferMapper &mapper = GraphicBufferMapper::get();
- Rect bounds(mWidth, mHeight);
+ Rect bounds(mCropWidth, mCropHeight);
void *dst;
CHECK_EQ(0, mapper.lock(
@@ -132,11 +156,70 @@
mCropLeft, mCropTop, mCropRight, mCropBottom,
dst,
buf->stride, buf->height,
- 0, 0,
- mCropRight - mCropLeft,
- mCropBottom - mCropTop);
+ 0, 0, mCropWidth - 1, mCropHeight - 1);
+ } else if (mColorFormat == OMX_COLOR_FormatYUV420Planar) {
+ const uint8_t *src_y = (const uint8_t *)data;
+ const uint8_t *src_u = (const uint8_t *)data + mWidth * mHeight;
+ const uint8_t *src_v = src_u + (mWidth / 2 * mHeight / 2);
+
+ uint8_t *dst_y = (uint8_t *)dst;
+ size_t dst_y_size = buf->stride * buf->height;
+ size_t dst_c_stride = ALIGN(buf->stride / 2, 16);
+ size_t dst_c_size = dst_c_stride * buf->height / 2;
+ uint8_t *dst_v = dst_y + dst_y_size;
+ uint8_t *dst_u = dst_v + dst_c_size;
+
+ for (int y = 0; y < mCropHeight; ++y) {
+ memcpy(dst_y, src_y, mCropWidth);
+
+ src_y += mWidth;
+ dst_y += buf->stride;
+ }
+
+ for (int y = 0; y < (mCropHeight + 1) / 2; ++y) {
+ memcpy(dst_u, src_u, (mCropWidth + 1) / 2);
+ memcpy(dst_v, src_v, (mCropWidth + 1) / 2);
+
+ src_u += mWidth / 2;
+ src_v += mWidth / 2;
+ dst_u += dst_c_stride;
+ dst_v += dst_c_stride;
+ }
} else {
- TRESPASS();
+ CHECK_EQ(mColorFormat, OMX_TI_COLOR_FormatYUV420PackedSemiPlanar);
+
+ const uint8_t *src_y =
+ (const uint8_t *)data;
+
+ const uint8_t *src_uv =
+ (const uint8_t *)data + mWidth * (mHeight - mCropTop / 2);
+
+ uint8_t *dst_y = (uint8_t *)dst;
+
+ size_t dst_y_size = buf->stride * buf->height;
+ size_t dst_c_stride = ALIGN(buf->stride / 2, 16);
+ size_t dst_c_size = dst_c_stride * buf->height / 2;
+ uint8_t *dst_v = dst_y + dst_y_size;
+ uint8_t *dst_u = dst_v + dst_c_size;
+
+ for (int y = 0; y < mCropHeight; ++y) {
+ memcpy(dst_y, src_y, mCropWidth);
+
+ src_y += mWidth;
+ dst_y += buf->stride;
+ }
+
+ for (int y = 0; y < (mCropHeight + 1) / 2; ++y) {
+ size_t tmp = (mCropWidth + 1) / 2;
+ for (size_t x = 0; x < tmp; ++x) {
+ dst_u[x] = src_uv[2 * x];
+ dst_v[x] = src_uv[2 * x + 1];
+ }
+
+ src_uv += mWidth;
+ dst_u += dst_c_stride;
+ dst_v += dst_c_stride;
+ }
}
CHECK_EQ(0, mapper.unlock(buf->handle));
diff --git a/media/libstagefright/foundation/ALooper.cpp b/media/libstagefright/foundation/ALooper.cpp
index b7087f8..a5b316d 100644
--- a/media/libstagefright/foundation/ALooper.cpp
+++ b/media/libstagefright/foundation/ALooper.cpp
@@ -33,18 +33,30 @@
struct ALooper::LooperThread : public Thread {
LooperThread(ALooper *looper, bool canCallJava)
: Thread(canCallJava),
- mLooper(looper) {
+ mLooper(looper),
+ mThreadId(NULL) {
+ }
+
+ virtual status_t readyToRun() {
+ mThreadId = androidGetThreadId();
+
+ return Thread::readyToRun();
}
virtual bool threadLoop() {
return mLooper->loop();
}
+ bool isCurrentThread() const {
+ return mThreadId == androidGetThreadId();
+ }
+
protected:
virtual ~LooperThread() {}
private:
ALooper *mLooper;
+ android_thread_id_t mThreadId;
DISALLOW_EVIL_CONSTRUCTORS(LooperThread);
};
@@ -136,7 +148,9 @@
mQueueChangedCondition.signal();
- if (!runningLocally) {
+ if (!runningLocally && !thread->isCurrentThread()) {
+ // If not running locally and this thread _is_ the looper thread,
+ // the loop() function will return and never be called again.
thread->requestExitAndWait();
}
@@ -197,6 +211,11 @@
gLooperRoster.deliverMessage(event.mMessage);
+ // NOTE: It's important to note that at this point our "ALooper" object
+ // may no longer exist (its final reference may have gone away while
+ // delivering the message). We have made sure, however, that loop()
+ // won't be called again.
+
return true;
}
diff --git a/media/libstagefright/foundation/Android.mk b/media/libstagefright/foundation/Android.mk
index 4e07f6f..d5025a1 100644
--- a/media/libstagefright/foundation/Android.mk
+++ b/media/libstagefright/foundation/Android.mk
@@ -25,6 +25,6 @@
LOCAL_MODULE:= libstagefright_foundation
-LOCAL_PRELINK_MODULE:= false
+
include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp
index f0cd6a0..f67cdac 100644
--- a/media/libstagefright/httplive/LiveSession.cpp
+++ b/media/libstagefright/httplive/LiveSession.cpp
@@ -23,7 +23,7 @@
#include "LiveDataSource.h"
#include "include/M3UParser.h"
-#include "include/NuHTTPDataSource.h"
+#include "include/HTTPBase.h"
#include <cutils/properties.h>
#include <media/stagefright/foundation/hexdump.h>
@@ -36,18 +36,19 @@
#include <ctype.h>
#include <openssl/aes.h>
+#include <openssl/md5.h>
namespace android {
-const int64_t LiveSession::kMaxPlaylistAgeUs = 15000000ll;
-
-LiveSession::LiveSession(uint32_t flags)
+LiveSession::LiveSession(uint32_t flags, bool uidValid, uid_t uid)
: mFlags(flags),
+ mUIDValid(uidValid),
+ mUID(uid),
mDataSource(new LiveDataSource),
mHTTPDataSource(
- new NuHTTPDataSource(
+ HTTPBase::Create(
(mFlags & kFlagIncognito)
- ? NuHTTPDataSource::kFlagIncognito
+ ? HTTPBase::kFlagIncognito
: 0)),
mPrevBandwidthIndex(-1),
mLastPlaylistFetchTimeUs(-1),
@@ -57,7 +58,11 @@
mDurationUs(-1),
mSeekDone(false),
mDisconnectPending(false),
- mMonitorQueueGeneration(0) {
+ mMonitorQueueGeneration(0),
+ mRefreshState(INITIAL_MINIMUM_RELOAD_DELAY) {
+ if (mUIDValid) {
+ mHTTPDataSource->setUID(mUID);
+ }
}
LiveSession::~LiveSession() {
@@ -67,9 +72,17 @@
return mDataSource;
}
-void LiveSession::connect(const char *url) {
+void LiveSession::connect(
+ const char *url, const KeyedVector<String8, String8> *headers) {
sp<AMessage> msg = new AMessage(kWhatConnect, id());
msg->setString("url", url);
+
+ if (headers != NULL) {
+ msg->setPointer(
+ "headers",
+ new KeyedVector<String8, String8>(*headers));
+ }
+
msg->post();
}
@@ -144,6 +157,16 @@
AString url;
CHECK(msg->findString("url", &url));
+ KeyedVector<String8, String8> *headers = NULL;
+ if (!msg->findPointer("headers", (void **)&headers)) {
+ mExtraHeaders.clear();
+ } else {
+ mExtraHeaders = *headers;
+
+ delete headers;
+ headers = NULL;
+ }
+
if (!(mFlags & kFlagIncognito)) {
LOGI("onConnect '%s'", url.c_str());
} else {
@@ -152,7 +175,8 @@
mMasterURL = url;
- sp<M3UParser> playlist = fetchPlaylist(url.c_str());
+ bool dummy;
+ sp<M3UParser> playlist = fetchPlaylist(url.c_str(), &dummy);
if (playlist == NULL) {
LOGE("unable to fetch master playlist '%s'.", url.c_str());
@@ -210,7 +234,8 @@
}
}
- status_t err = mHTTPDataSource->connect(url);
+ status_t err = mHTTPDataSource->connect(
+ url, mExtraHeaders.isEmpty() ? NULL : &mExtraHeaders);
if (err != OK) {
return err;
@@ -265,7 +290,9 @@
return OK;
}
-sp<M3UParser> LiveSession::fetchPlaylist(const char *url) {
+sp<M3UParser> LiveSession::fetchPlaylist(const char *url, bool *unchanged) {
+ *unchanged = false;
+
sp<ABuffer> buffer;
status_t err = fetchFile(url, &buffer);
@@ -273,10 +300,44 @@
return NULL;
}
+ // MD5 functionality is not available on the simulator, treat all
+ // playlists as changed.
+
+#if defined(HAVE_ANDROID_OS)
+ uint8_t hash[16];
+
+ MD5_CTX m;
+ MD5_Init(&m);
+ MD5_Update(&m, buffer->data(), buffer->size());
+
+ MD5_Final(hash, &m);
+
+ if (mPlaylist != NULL && !memcmp(hash, mPlaylistHash, 16)) {
+ // playlist unchanged
+
+ if (mRefreshState != THIRD_UNCHANGED_RELOAD_ATTEMPT) {
+ mRefreshState = (RefreshState)(mRefreshState + 1);
+ }
+
+ *unchanged = true;
+
+ LOGV("Playlist unchanged, refresh state is now %d",
+ (int)mRefreshState);
+
+ return NULL;
+ }
+
+ memcpy(mPlaylistHash, hash, sizeof(hash));
+
+ mRefreshState = INITIAL_MINIMUM_RELOAD_DELAY;
+#endif
+
sp<M3UParser> playlist =
new M3UParser(url, buffer->data(), buffer->size());
if (playlist->initCheck() != OK) {
+ LOGE("failed to parse .m3u8 playlist");
+
return NULL;
}
@@ -358,6 +419,63 @@
return index;
}
+bool LiveSession::timeToRefreshPlaylist(int64_t nowUs) const {
+ if (mPlaylist == NULL) {
+ CHECK_EQ((int)mRefreshState, (int)INITIAL_MINIMUM_RELOAD_DELAY);
+ return true;
+ }
+
+ int32_t targetDurationSecs;
+ CHECK(mPlaylist->meta()->findInt32("target-duration", &targetDurationSecs));
+
+ int64_t targetDurationUs = targetDurationSecs * 1000000ll;
+
+ int64_t minPlaylistAgeUs;
+
+ switch (mRefreshState) {
+ case INITIAL_MINIMUM_RELOAD_DELAY:
+ {
+ size_t n = mPlaylist->size();
+ if (n > 0) {
+ sp<AMessage> itemMeta;
+ CHECK(mPlaylist->itemAt(n - 1, NULL /* uri */, &itemMeta));
+
+ int64_t itemDurationUs;
+ CHECK(itemMeta->findInt64("durationUs", &itemDurationUs));
+
+ minPlaylistAgeUs = itemDurationUs;
+ break;
+ }
+
+ // fall through
+ }
+
+ case FIRST_UNCHANGED_RELOAD_ATTEMPT:
+ {
+ minPlaylistAgeUs = targetDurationUs / 2;
+ break;
+ }
+
+ case SECOND_UNCHANGED_RELOAD_ATTEMPT:
+ {
+ minPlaylistAgeUs = (targetDurationUs * 3) / 2;
+ break;
+ }
+
+ case THIRD_UNCHANGED_RELOAD_ATTEMPT:
+ {
+ minPlaylistAgeUs = targetDurationUs * 3;
+ break;
+ }
+
+ default:
+ TRESPASS();
+ break;
+ }
+
+ return mLastPlaylistFetchTimeUs + minPlaylistAgeUs <= nowUs;
+}
+
void LiveSession::onDownloadNext() {
size_t bandwidthIndex = getBandwidthIndex();
@@ -366,8 +484,7 @@
if (mLastPlaylistFetchTimeUs < 0
|| (ssize_t)bandwidthIndex != mPrevBandwidthIndex
- || (!mPlaylist->isComplete()
- && mLastPlaylistFetchTimeUs + kMaxPlaylistAgeUs <= nowUs)) {
+ || (!mPlaylist->isComplete() && timeToRefreshPlaylist(nowUs))) {
AString url;
if (mBandwidthItems.size() > 0) {
url = mBandwidthItems.editItemAt(bandwidthIndex).mURI;
@@ -377,23 +494,44 @@
bool firstTime = (mPlaylist == NULL);
- mPlaylist = fetchPlaylist(url.c_str());
- if (mPlaylist == NULL) {
- LOGE("failed to load playlist at url '%s'", url.c_str());
- mDataSource->queueEOS(ERROR_IO);
- return;
+ if ((ssize_t)bandwidthIndex != mPrevBandwidthIndex) {
+ // If we switch bandwidths, do not pay any heed to whether
+ // playlists changed since the last time...
+ mPlaylist.clear();
+ }
+
+ bool unchanged;
+ sp<M3UParser> playlist = fetchPlaylist(url.c_str(), &unchanged);
+ if (playlist == NULL) {
+ if (unchanged) {
+ // We succeeded in fetching the playlist, but it was
+ // unchanged from the last time we tried.
+ } else {
+ LOGE("failed to load playlist at url '%s'", url.c_str());
+ mDataSource->queueEOS(ERROR_IO);
+ return;
+ }
+ } else {
+ mPlaylist = playlist;
}
if (firstTime) {
Mutex::Autolock autoLock(mLock);
- int32_t targetDuration;
- if (!mPlaylist->isComplete()
- || !mPlaylist->meta()->findInt32(
- "target-duration", &targetDuration)) {
+ if (!mPlaylist->isComplete()) {
mDurationUs = -1;
} else {
- mDurationUs = 1000000ll * targetDuration * mPlaylist->size();
+ mDurationUs = 0;
+ for (size_t i = 0; i < mPlaylist->size(); ++i) {
+ sp<AMessage> itemMeta;
+ CHECK(mPlaylist->itemAt(
+ i, NULL /* uri */, &itemMeta));
+
+ int64_t itemDurationUs;
+ CHECK(itemMeta->findInt64("durationUs", &itemDurationUs));
+
+ mDurationUs += itemDurationUs;
+ }
}
}
@@ -406,18 +544,31 @@
firstSeqNumberInPlaylist = 0;
}
+ bool seekDiscontinuity = false;
bool explicitDiscontinuity = false;
bool bandwidthChanged = false;
if (mSeekTimeUs >= 0) {
- int32_t targetDuration;
- if (mPlaylist->isComplete() &&
- mPlaylist->meta()->findInt32(
- "target-duration", &targetDuration)) {
- int64_t seekTimeSecs = (mSeekTimeUs + 500000ll) / 1000000ll;
- int64_t index = seekTimeSecs / targetDuration;
+ if (mPlaylist->isComplete()) {
+ size_t index = 0;
+ int64_t segmentStartUs = 0;
+ while (index < mPlaylist->size()) {
+ sp<AMessage> itemMeta;
+ CHECK(mPlaylist->itemAt(
+ index, NULL /* uri */, &itemMeta));
- if (index >= 0 && index < mPlaylist->size()) {
+ int64_t itemDurationUs;
+ CHECK(itemMeta->findInt64("durationUs", &itemDurationUs));
+
+ if (mSeekTimeUs < segmentStartUs + itemDurationUs) {
+ break;
+ }
+
+ segmentStartUs += itemDurationUs;
+ ++index;
+ }
+
+ if (index < mPlaylist->size()) {
int32_t newSeqNumber = firstSeqNumberInPlaylist + index;
if (newSeqNumber != mSeqNumber) {
@@ -430,10 +581,10 @@
// reseting the data source will have had the
// side effect of discarding any previously queued
// bandwidth change discontinuity.
- // Therefore we'll need to treat these explicit
+ // Therefore we'll need to treat these seek
// discontinuities as involving a bandwidth change
// even if they aren't directly.
- explicitDiscontinuity = true;
+ seekDiscontinuity = true;
bandwidthChanged = true;
}
}
@@ -447,11 +598,7 @@
}
if (mSeqNumber < 0) {
- if (mPlaylist->isComplete()) {
- mSeqNumber = firstSeqNumberInPlaylist;
- } else {
- mSeqNumber = firstSeqNumberInPlaylist + mPlaylist->size() / 2;
- }
+ mSeqNumber = firstSeqNumberInPlaylist;
}
int32_t lastSeqNumberInPlaylist =
@@ -470,23 +617,32 @@
goto rinse_repeat;
}
- if (!mPlaylist->isComplete()
- && mSeqNumber > lastSeqNumberInPlaylist
- && mNumRetries < kMaxNumRetries) {
+ if (!mPlaylist->isComplete() && mNumRetries < kMaxNumRetries) {
++mNumRetries;
- mLastPlaylistFetchTimeUs = -1;
- postMonitorQueue(3000000ll);
+ if (mSeqNumber > lastSeqNumberInPlaylist) {
+ mLastPlaylistFetchTimeUs = -1;
+ postMonitorQueue(3000000ll);
+ return;
+ }
+
+ // we've missed the boat, let's start from the lowest sequence
+ // number available and signal a discontinuity.
+
+ LOGI("We've missed the boat, restarting playback.");
+ mSeqNumber = lastSeqNumberInPlaylist;
+ explicitDiscontinuity = true;
+
+ // fall through
+ } else {
+ LOGE("Cannot find sequence number %d in playlist "
+ "(contains %d - %d)",
+ mSeqNumber, firstSeqNumberInPlaylist,
+ firstSeqNumberInPlaylist + mPlaylist->size() - 1);
+
+ mDataSource->queueEOS(ERROR_END_OF_STREAM);
return;
}
-
- LOGE("Cannot find sequence number %d in playlist "
- "(contains %d - %d)",
- mSeqNumber, firstSeqNumberInPlaylist,
- firstSeqNumberInPlaylist + mPlaylist->size() - 1);
-
- mDataSource->queueEOS(ERROR_END_OF_STREAM);
- return;
}
mNumRetries = 0;
@@ -554,15 +710,17 @@
bandwidthChanged = false;
}
- if (explicitDiscontinuity || bandwidthChanged) {
+ if (seekDiscontinuity || explicitDiscontinuity || bandwidthChanged) {
// Signal discontinuity.
- LOGI("queueing discontinuity (explicit=%d, bandwidthChanged=%d)",
- explicitDiscontinuity, bandwidthChanged);
+ LOGI("queueing discontinuity (seek=%d, explicit=%d, bandwidthChanged=%d)",
+ seekDiscontinuity, explicitDiscontinuity, bandwidthChanged);
sp<ABuffer> tmp = new ABuffer(188);
memset(tmp->data(), 0, tmp->size());
- tmp->data()[1] = bandwidthChanged;
+
+ // signal a 'hard' discontinuity for explicit or bandwidthChanged.
+ tmp->data()[1] = (explicitDiscontinuity || bandwidthChanged) ? 1 : 0;
mDataSource->queueBuffer(tmp);
}
@@ -625,8 +783,20 @@
} else {
key = new ABuffer(16);
- sp<NuHTTPDataSource> keySource = new NuHTTPDataSource;
- status_t err = keySource->connect(keyURI.c_str());
+ sp<HTTPBase> keySource =
+ HTTPBase::Create(
+ (mFlags & kFlagIncognito)
+ ? HTTPBase::kFlagIncognito
+ : 0);
+
+ if (mUIDValid) {
+ keySource->setUID(mUID);
+ }
+
+ status_t err =
+ keySource->connect(
+ keyURI.c_str(),
+ mExtraHeaders.isEmpty() ? NULL : &mExtraHeaders);
if (err == OK) {
size_t offset = 0;
diff --git a/media/libstagefright/httplive/M3UParser.cpp b/media/libstagefright/httplive/M3UParser.cpp
index 2eb180a..9df9f59 100644
--- a/media/libstagefright/httplive/M3UParser.cpp
+++ b/media/libstagefright/httplive/M3UParser.cpp
@@ -64,14 +64,21 @@
}
bool M3UParser::itemAt(size_t index, AString *uri, sp<AMessage> *meta) {
- uri->clear();
- if (meta) { *meta = NULL; }
+ if (uri) {
+ uri->clear();
+ }
+
+ if (meta) {
+ *meta = NULL;
+ }
if (index >= mItems.size()) {
return false;
}
- *uri = mItems.itemAt(index).mURI;
+ if (uri) {
+ *uri = mItems.itemAt(index).mURI;
+ }
if (meta) {
*meta = mItems.itemAt(index).mMeta;
@@ -99,21 +106,38 @@
return true;
}
- size_t n = strlen(baseURL);
- if (baseURL[n - 1] == '/') {
- out->setTo(baseURL);
- out->append(url);
- } else {
- const char *slashPos = strrchr(baseURL, '/');
+ if (url[0] == '/') {
+ // URL is an absolute path.
- if (slashPos > &baseURL[6]) {
- out->setTo(baseURL, slashPos - baseURL);
+ char *protocolEnd = strstr(baseURL, "//") + 2;
+ char *pathStart = strchr(protocolEnd, '/');
+
+ if (pathStart != NULL) {
+ out->setTo(baseURL, pathStart - baseURL);
} else {
out->setTo(baseURL);
}
- out->append("/");
out->append(url);
+ } else {
+ // URL is a relative path
+
+ size_t n = strlen(baseURL);
+ if (baseURL[n - 1] == '/') {
+ out->setTo(baseURL);
+ out->append(url);
+ } else {
+ const char *slashPos = strrchr(baseURL, '/');
+
+ if (slashPos > &baseURL[6]) {
+ out->setTo(baseURL, slashPos - baseURL);
+ } else {
+ out->setTo(baseURL);
+ }
+
+ out->append("/");
+ out->append(url);
+ }
}
LOGV("base:'%s', url:'%s' => '%s'", baseURL, url, out->c_str());
@@ -179,7 +203,7 @@
if (mIsVariantPlaylist) {
return ERROR_MALFORMED;
}
- err = parseMetaData(line, &itemMeta, "duration");
+ err = parseMetaDataDuration(line, &itemMeta, "durationUs");
} else if (line.startsWith("#EXT-X-DISCONTINUITY")) {
if (mIsVariantPlaylist) {
return ERROR_MALFORMED;
@@ -203,9 +227,9 @@
if (!line.startsWith("#")) {
if (!mIsVariantPlaylist) {
- int32_t durationSecs;
+ int64_t durationUs;
if (itemMeta == NULL
- || !itemMeta->findInt32("duration", &durationSecs)) {
+ || !itemMeta->findInt64("durationUs", &durationUs)) {
return ERROR_MALFORMED;
}
}
@@ -252,6 +276,30 @@
}
// static
+status_t M3UParser::parseMetaDataDuration(
+ const AString &line, sp<AMessage> *meta, const char *key) {
+ ssize_t colonPos = line.find(":");
+
+ if (colonPos < 0) {
+ return ERROR_MALFORMED;
+ }
+
+ double x;
+ status_t err = ParseDouble(line.c_str() + colonPos + 1, &x);
+
+ if (err != OK) {
+ return err;
+ }
+
+ if (meta->get() == NULL) {
+ *meta = new AMessage;
+ }
+ (*meta)->setInt64(key, (int64_t)x * 1E6);
+
+ return OK;
+}
+
+// static
status_t M3UParser::parseStreamInf(
const AString &line, sp<AMessage> *meta) {
ssize_t colonPos = line.find(":");
@@ -412,4 +460,18 @@
return OK;
}
+// static
+status_t M3UParser::ParseDouble(const char *s, double *x) {
+ char *end;
+ double dval = strtod(s, &end);
+
+ if (end == s || (*end != '\0' && *end != ',')) {
+ return ERROR_MALFORMED;
+ }
+
+ *x = dval;
+
+ return OK;
+}
+
} // namespace android
diff --git a/media/libstagefright/include/ARTSPController.h b/media/libstagefright/include/ARTSPController.h
index ce7ffe5..2bd5be6 100644
--- a/media/libstagefright/include/ARTSPController.h
+++ b/media/libstagefright/include/ARTSPController.h
@@ -30,6 +30,8 @@
struct ARTSPController : public MediaExtractor {
ARTSPController(const sp<ALooper> &looper);
+ void setUID(uid_t uid);
+
status_t connect(const char *url);
void disconnect();
@@ -80,6 +82,9 @@
sp<MyHandler> mHandler;
sp<AHandlerReflector<ARTSPController> > mReflector;
+ bool mUIDValid;
+ uid_t mUID;
+
void (*mSeekDoneCb)(void *);
void *mSeekDoneCookie;
int64_t mLastSeekCompletedTimeUs;
diff --git a/media/libstagefright/include/AVIExtractor.h b/media/libstagefright/include/AVIExtractor.h
new file mode 100644
index 0000000..375a94d
--- /dev/null
+++ b/media/libstagefright/include/AVIExtractor.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2011 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 AVI_EXTRACTOR_H_
+
+#define AVI_EXTRACTOR_H_
+
+#include <media/stagefright/foundation/ABase.h>
+#include <media/stagefright/MediaExtractor.h>
+#include <media/stagefright/MediaSource.h>
+#include <utils/Vector.h>
+
+namespace android {
+
+struct AVIExtractor : public MediaExtractor {
+ AVIExtractor(const sp<DataSource> &dataSource);
+
+ virtual size_t countTracks();
+
+ virtual sp<MediaSource> getTrack(size_t index);
+
+ virtual sp<MetaData> getTrackMetaData(
+ size_t index, uint32_t flags);
+
+ virtual sp<MetaData> getMetaData();
+
+protected:
+ virtual ~AVIExtractor();
+
+private:
+ struct AVISource;
+
+ struct SampleInfo {
+ uint32_t mOffset;
+ bool mIsKey;
+ };
+
+ struct Track {
+ sp<MetaData> mMeta;
+ Vector<SampleInfo> mSamples;
+ uint32_t mRate;
+ uint32_t mScale;
+
+ enum Kind {
+ AUDIO,
+ VIDEO,
+ OTHER
+
+ } mKind;
+
+ size_t mNumSyncSamples;
+ size_t mThumbnailSampleSize;
+ ssize_t mThumbnailSampleIndex;
+ size_t mMaxSampleSize;
+ };
+
+ sp<DataSource> mDataSource;
+ status_t mInitCheck;
+ Vector<Track> mTracks;
+
+ off64_t mMovieOffset;
+ bool mFoundIndex;
+ bool mOffsetsAreAbsolute;
+
+ ssize_t parseChunk(off64_t offset, off64_t size, int depth = 0);
+ status_t parseStreamHeader(off64_t offset, size_t size);
+ status_t parseStreamFormat(off64_t offset, size_t size);
+ status_t parseIndex(off64_t offset, size_t size);
+
+ status_t parseHeaders();
+
+ status_t getSampleInfo(
+ size_t trackIndex, size_t sampleIndex,
+ off64_t *offset, size_t *size, bool *isKey);
+
+ status_t getSampleIndexAtTime(
+ size_t trackIndex,
+ int64_t timeUs, MediaSource::ReadOptions::SeekMode mode,
+ size_t *sampleIndex) const;
+
+ status_t addMPEG4CodecSpecificData(size_t trackIndex);
+
+ static bool IsCorrectChunkType(
+ ssize_t trackIndex, Track::Kind kind, uint32_t chunkType);
+
+ DISALLOW_EVIL_CONSTRUCTORS(AVIExtractor);
+};
+
+class String8;
+struct AMessage;
+
+bool SniffAVI(
+ const sp<DataSource> &source, String8 *mimeType, float *confidence,
+ sp<AMessage> *);
+
+} // namespace android
+
+#endif // AVI_EXTRACTOR_H_
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index 3a21f25..95f2ae8 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -18,7 +18,7 @@
#define AWESOME_PLAYER_H_
-#include "NuHTTPDataSource.h"
+#include "HTTPBase.h"
#include "TimedEventQueue.h"
#include <media/MediaPlayerInterface.h>
@@ -44,6 +44,7 @@
class DrmManagerClinet;
class DecryptHandle;
+class TimedTextPlayer;
struct WVMExtractor;
struct AwesomeRenderer : public RefBase {
@@ -61,6 +62,7 @@
~AwesomePlayer();
void setListener(const wp<MediaPlayerBase> &listener);
+ void setUID(uid_t uid);
status_t setDataSource(
const char *uri,
@@ -90,53 +92,67 @@
status_t getDuration(int64_t *durationUs);
status_t getPosition(int64_t *positionUs);
+ status_t setParameter(int key, const Parcel &request);
+ status_t getParameter(int key, Parcel *reply);
+ status_t setCacheStatCollectFreq(const Parcel &request);
+
status_t seekTo(int64_t timeUs);
// This is a mask of MediaExtractor::Flags.
uint32_t flags() const;
- void postAudioEOS();
+ void postAudioEOS(int64_t delayUs = 0ll);
void postAudioSeekComplete();
+ status_t setTimedTextTrackIndex(int32_t index);
+
+ status_t dump(int fd, const Vector<String16> &args) const;
+
private:
friend struct AwesomeEvent;
friend struct PreviewPlayer;
enum {
- PLAYING = 1,
- LOOPING = 2,
- FIRST_FRAME = 4,
- PREPARING = 8,
- PREPARED = 16,
- AT_EOS = 32,
- PREPARE_CANCELLED = 64,
- CACHE_UNDERRUN = 128,
- AUDIO_AT_EOS = 256,
- VIDEO_AT_EOS = 512,
- AUTO_LOOPING = 1024,
+ PLAYING = 0x01,
+ LOOPING = 0x02,
+ FIRST_FRAME = 0x04,
+ PREPARING = 0x08,
+ PREPARED = 0x10,
+ AT_EOS = 0x20,
+ PREPARE_CANCELLED = 0x40,
+ CACHE_UNDERRUN = 0x80,
+ AUDIO_AT_EOS = 0x0100,
+ VIDEO_AT_EOS = 0x0200,
+ AUTO_LOOPING = 0x0400,
// We are basically done preparing but are currently buffering
// sufficient data to begin playback and finish the preparation phase
// for good.
- PREPARING_CONNECTED = 2048,
+ PREPARING_CONNECTED = 0x0800,
// We're triggering a single video event to display the first frame
// after the seekpoint.
- SEEK_PREVIEW = 4096,
+ SEEK_PREVIEW = 0x1000,
- AUDIO_RUNNING = 8192,
- AUDIOPLAYER_STARTED = 16384,
+ AUDIO_RUNNING = 0x2000,
+ AUDIOPLAYER_STARTED = 0x4000,
- INCOGNITO = 32768,
+ INCOGNITO = 0x8000,
+
+ TEXT_RUNNING = 0x10000,
+ TEXTPLAYER_STARTED = 0x20000,
};
mutable Mutex mLock;
Mutex mMiscStateLock;
+ mutable Mutex mStatsLock;
OMXClient mClient;
TimedEventQueue mQueue;
bool mQueueStarted;
wp<MediaPlayerBase> mListener;
+ bool mUIDValid;
+ uid_t mUID;
sp<Surface> mSurface;
sp<ANativeWindow> mNativeWindow;
@@ -165,7 +181,6 @@
uint32_t mFlags;
uint32_t mExtractorFlags;
- uint32_t mSinceLastDropped;
int64_t mTimeSourceDeltaUs;
int64_t mVideoTimeUs;
@@ -205,13 +220,13 @@
void postVideoEvent_l(int64_t delayUs = -1);
void postBufferingEvent_l();
void postStreamDoneEvent_l(status_t status);
- void postCheckAudioStatusEvent_l();
+ void postCheckAudioStatusEvent_l(int64_t delayUs);
void postVideoLagEvent_l();
status_t play_l();
MediaBuffer *mVideoBuffer;
- sp<NuHTTPDataSource> mConnectingDataSource;
+ sp<HTTPBase> mConnectingDataSource;
sp<NuCachedSource2> mCachedSource;
sp<ALooper> mLooper;
@@ -219,7 +234,11 @@
sp<ARTSPController> mConnectingRTSPController;
DrmManagerClient *mDrmManagerClient;
- DecryptHandle *mDecryptHandle;
+ sp<DecryptHandle> mDecryptHandle;
+
+ int64_t mLastVideoTimeUs;
+ TimedTextPlayer *mTextPlayer;
+ mutable Mutex mTimedTextLock;
sp<WVMExtractor> mWVMExtractor;
@@ -244,6 +263,8 @@
void setVideoSource(sp<MediaSource> source);
status_t initVideoDecoder(uint32_t flags = 0);
+ void addTextSource(sp<MediaSource> source);
+
void onStreamDone();
void notifyListener_l(int msg, int ext1 = 0, int ext2 = 0);
@@ -270,9 +291,41 @@
void finishSeekIfNecessary(int64_t videoTimeUs);
void ensureCacheIsFetching_l();
- status_t startAudioPlayer_l();
+ status_t startAudioPlayer_l(bool sendErrorNotification = true);
+ void postAudioSeekComplete_l();
+
+ void shutdownVideoDecoder_l();
+ void setNativeWindow_l(const sp<ANativeWindow> &native);
bool isStreamingHTTP() const;
+ void sendCacheStats();
+
+ enum FlagMode {
+ SET,
+ CLEAR,
+ ASSIGN
+ };
+ void modifyFlags(unsigned value, FlagMode mode);
+
+ struct TrackStat {
+ String8 mMIME;
+ String8 mDecoderName;
+ };
+
+ // protected by mStatsLock
+ struct Stats {
+ int mFd;
+ String8 mURI;
+ int64_t mBitrate;
+ ssize_t mAudioTrackIndex;
+ ssize_t mVideoTrackIndex;
+ int64_t mNumVideoFramesDecoded;
+ int64_t mNumVideoFramesDropped;
+ int32_t mVideoWidth;
+ int32_t mVideoHeight;
+ uint32_t mFlags;
+ Vector<TrackStat> mTracks;
+ } mStats;
AwesomePlayer(const AwesomePlayer &);
AwesomePlayer &operator=(const AwesomePlayer &);
diff --git a/media/libstagefright/include/ChromiumHTTPDataSource.h b/media/libstagefright/include/ChromiumHTTPDataSource.h
new file mode 100644
index 0000000..18f8913
--- /dev/null
+++ b/media/libstagefright/include/ChromiumHTTPDataSource.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2011 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 CHROME_HTTP_DATA_SOURCE_H_
+
+#define CHROME_HTTP_DATA_SOURCE_H_
+
+#include <media/stagefright/foundation/AString.h>
+#include <utils/threads.h>
+
+#include "HTTPBase.h"
+
+namespace android {
+
+struct SfDelegate;
+
+struct ChromiumHTTPDataSource : public HTTPBase {
+ ChromiumHTTPDataSource(uint32_t flags = 0);
+
+ virtual status_t connect(
+ const char *uri,
+ const KeyedVector<String8, String8> *headers = NULL,
+ off64_t offset = 0);
+
+ virtual void disconnect();
+
+ virtual status_t initCheck() const;
+
+ virtual ssize_t readAt(off64_t offset, void *data, size_t size);
+ virtual status_t getSize(off64_t *size);
+ virtual uint32_t flags();
+
+ virtual sp<DecryptHandle> DrmInitialization();
+
+ virtual void getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client);
+
+ virtual String8 getUri();
+
+ virtual String8 getMIMEType() const;
+
+ virtual status_t reconnectAtOffset(off64_t offset);
+
+protected:
+ virtual ~ChromiumHTTPDataSource();
+
+private:
+ friend struct SfDelegate;
+
+ enum State {
+ DISCONNECTED,
+ CONNECTING,
+ CONNECTED,
+ READING,
+ DISCONNECTING
+ };
+
+ const uint32_t mFlags;
+
+ mutable Mutex mLock;
+ Condition mCondition;
+
+ State mState;
+
+ SfDelegate *mDelegate;
+
+ AString mURI;
+ KeyedVector<String8, String8> mHeaders;
+
+ off64_t mCurrentOffset;
+
+ // Any connection error or the result of a read operation
+ // (for the lattter this is the number of bytes read, if successful).
+ ssize_t mIOResult;
+
+ int64_t mContentSize;
+
+ String8 mContentType;
+
+ sp<DecryptHandle> mDecryptHandle;
+ DrmManagerClient *mDrmManagerClient;
+
+ void disconnect_l();
+
+ status_t connect_l(
+ const char *uri,
+ const KeyedVector<String8, String8> *headers,
+ off64_t offset);
+
+ static void InitiateRead(
+ ChromiumHTTPDataSource *me, void *data, size_t size);
+
+ void initiateRead(void *data, size_t size);
+
+ void onConnectionEstablished(
+ int64_t contentSize, const char *contentType);
+
+ void onConnectionFailed(status_t err);
+ void onReadCompleted(ssize_t size);
+ void onDisconnectComplete();
+
+ void clearDRMState_l();
+
+ DISALLOW_EVIL_CONSTRUCTORS(ChromiumHTTPDataSource);
+};
+
+} // namespace android
+
+#endif // CHROME_HTTP_DATA_SOURCE_H_
diff --git a/media/libstagefright/include/DRMExtractor.h b/media/libstagefright/include/DRMExtractor.h
index 9881cc1..b4e4afb 100644
--- a/media/libstagefright/include/DRMExtractor.h
+++ b/media/libstagefright/include/DRMExtractor.h
@@ -45,7 +45,7 @@
sp<DataSource> mDataSource;
sp<MediaExtractor> mOriginalExtractor;
- DecryptHandle* mDecryptHandle;
+ sp<DecryptHandle> mDecryptHandle;
DrmManagerClient* mDrmManagerClient;
DRMExtractor(const DRMExtractor &);
diff --git a/media/libstagefright/include/HTTPBase.h b/media/libstagefright/include/HTTPBase.h
new file mode 100644
index 0000000..0e9af69
--- /dev/null
+++ b/media/libstagefright/include/HTTPBase.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2011 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 HTTP_BASE_H_
+
+#define HTTP_BASE_H_
+
+#include <media/stagefright/foundation/ABase.h>
+#include <media/stagefright/DataSource.h>
+#include <media/stagefright/MediaErrors.h>
+#include <utils/threads.h>
+
+namespace android {
+
+struct HTTPBase : public DataSource {
+ enum Flags {
+ // Don't log any URLs.
+ kFlagIncognito = 1
+ };
+
+ HTTPBase();
+
+ virtual status_t connect(
+ const char *uri,
+ const KeyedVector<String8, String8> *headers = NULL,
+ off64_t offset = 0) = 0;
+
+ virtual void disconnect() = 0;
+
+ // Returns true if bandwidth could successfully be estimated,
+ // false otherwise.
+ virtual bool estimateBandwidth(int32_t *bandwidth_bps);
+
+ virtual status_t getEstimatedBandwidthKbps(int32_t *kbps);
+
+ virtual status_t setBandwidthStatCollectFreq(int32_t freqMs);
+
+ void setUID(uid_t uid);
+ bool getUID(uid_t *uid) const;
+
+ static sp<HTTPBase> Create(uint32_t flags = 0);
+
+ static void RegisterSocketUser(int s, uid_t uid);
+
+protected:
+ void addBandwidthMeasurement(size_t numBytes, int64_t delayUs);
+
+private:
+ struct BandwidthEntry {
+ int64_t mDelayUs;
+ size_t mNumBytes;
+ };
+
+ Mutex mLock;
+
+ List<BandwidthEntry> mBandwidthHistory;
+ size_t mNumBandwidthHistoryItems;
+ int64_t mTotalTransferTimeUs;
+ size_t mTotalTransferBytes;
+
+ enum {
+ kMinBandwidthCollectFreqMs = 1000, // 1 second
+ kMaxBandwidthCollectFreqMs = 60000, // one minute
+ };
+
+ int64_t mPrevBandwidthMeasureTimeUs;
+ int32_t mPrevEstimatedBandWidthKbps;
+ int32_t mBandWidthCollectFreqMs;
+
+ bool mUIDValid;
+ uid_t mUID;
+
+ DISALLOW_EVIL_CONSTRUCTORS(HTTPBase);
+};
+
+} // namespace android
+
+#endif // HTTP_BASE_H_
diff --git a/media/libstagefright/include/HTTPStream.h b/media/libstagefright/include/HTTPStream.h
deleted file mode 100644
index 09e6a5f..0000000
--- a/media/libstagefright/include/HTTPStream.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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 HTTP_STREAM_H_
-
-#define HTTP_STREAM_H_
-
-#include <sys/types.h>
-
-#include <media/stagefright/foundation/AString.h>
-#include <media/stagefright/MediaErrors.h>
-#include <utils/KeyedVector.h>
-#include <utils/threads.h>
-
-namespace android {
-
-class HTTPStream {
-public:
- HTTPStream();
- ~HTTPStream();
-
- status_t connect(const char *server, int port = -1, bool https = false);
- status_t disconnect();
-
- status_t send(const char *data, size_t size);
-
- // Assumes data is a '\0' terminated string.
- status_t send(const char *data);
-
- // Receive up to "size" bytes of data.
- ssize_t receive(void *data, size_t size);
-
- status_t receive_header(int *http_status);
-
- // The header key used to retrieve the status line.
- static const char *kStatusKey;
-
- bool find_header_value(
- const AString &key, AString *value) const;
-
- // Pass a negative value to disable the timeout.
- void setReceiveTimeout(int seconds);
-
- // Receive a line of data terminated by CRLF, line will be '\0' terminated
- // _excluding_ the termianting CRLF.
- status_t receive_line(char *line, size_t size);
-
-private:
- enum State {
- READY,
- CONNECTING,
- CONNECTED
- };
-
- State mState;
- Mutex mLock;
- int mSocket;
-
- KeyedVector<AString, AString> mHeaders;
-
- void *mSSLContext;
- void *mSSL;
-
- HTTPStream(const HTTPStream &);
- HTTPStream &operator=(const HTTPStream &);
-};
-
-} // namespace android
-
-#endif // HTTP_STREAM_H_
diff --git a/media/libstagefright/include/LiveSession.h b/media/libstagefright/include/LiveSession.h
index 3fe5d4e..116ed0e 100644
--- a/media/libstagefright/include/LiveSession.h
+++ b/media/libstagefright/include/LiveSession.h
@@ -20,24 +20,29 @@
#include <media/stagefright/foundation/AHandler.h>
+#include <utils/String8.h>
+
namespace android {
struct ABuffer;
struct DataSource;
struct LiveDataSource;
struct M3UParser;
-struct NuHTTPDataSource;
+struct HTTPBase;
struct LiveSession : public AHandler {
enum Flags {
// Don't log any URLs.
kFlagIncognito = 1,
};
- LiveSession(uint32_t flags = 0);
+ LiveSession(uint32_t flags = 0, bool uidValid = false, uid_t uid = 0);
sp<DataSource> getDataSource();
- void connect(const char *url);
+ void connect(
+ const char *url,
+ const KeyedVector<String8, String8> *headers = NULL);
+
void disconnect();
// Blocks until seek is complete.
@@ -57,8 +62,6 @@
kMaxNumRetries = 5,
};
- static const int64_t kMaxPlaylistAgeUs;
-
enum {
kWhatConnect = 'conn',
kWhatDisconnect = 'disc',
@@ -72,12 +75,16 @@
};
uint32_t mFlags;
+ bool mUIDValid;
+ uid_t mUID;
sp<LiveDataSource> mDataSource;
- sp<NuHTTPDataSource> mHTTPDataSource;
+ sp<HTTPBase> mHTTPDataSource;
AString mMasterURL;
+ KeyedVector<String8, String8> mExtraHeaders;
+
Vector<BandwidthItem> mBandwidthItems;
KeyedVector<AString, sp<ABuffer> > mAESKeyForURI;
@@ -97,6 +104,16 @@
int32_t mMonitorQueueGeneration;
+ enum RefreshState {
+ INITIAL_MINIMUM_RELOAD_DELAY,
+ FIRST_UNCHANGED_RELOAD_ATTEMPT,
+ SECOND_UNCHANGED_RELOAD_ATTEMPT,
+ THIRD_UNCHANGED_RELOAD_ATTEMPT
+ };
+ RefreshState mRefreshState;
+
+ uint8_t mPlaylistHash[16];
+
void onConnect(const sp<AMessage> &msg);
void onDisconnect();
void onDownloadNext();
@@ -104,7 +121,7 @@
void onSeek(const sp<AMessage> &msg);
status_t fetchFile(const char *url, sp<ABuffer> *out);
- sp<M3UParser> fetchPlaylist(const char *url);
+ sp<M3UParser> fetchPlaylist(const char *url, bool *unchanged);
size_t getBandwidthIndex();
status_t decryptBuffer(
@@ -112,6 +129,8 @@
void postMonitorQueue(int64_t delayUs = 0);
+ bool timeToRefreshPlaylist(int64_t nowUs) const;
+
static int SortByBandwidth(const BandwidthItem *, const BandwidthItem *);
DISALLOW_EVIL_CONSTRUCTORS(LiveSession);
diff --git a/media/libstagefright/include/M3UParser.h b/media/libstagefright/include/M3UParser.h
index 63895b4..478582d 100644
--- a/media/libstagefright/include/M3UParser.h
+++ b/media/libstagefright/include/M3UParser.h
@@ -63,6 +63,9 @@
static status_t parseMetaData(
const AString &line, sp<AMessage> *meta, const char *key);
+ static status_t parseMetaDataDuration(
+ const AString &line, sp<AMessage> *meta, const char *key);
+
static status_t parseStreamInf(
const AString &line, sp<AMessage> *meta);
@@ -70,6 +73,7 @@
const AString &line, sp<AMessage> *meta, const AString &baseURI);
static status_t ParseInt32(const char *s, int32_t *x);
+ static status_t ParseDouble(const char *s, double *x);
DISALLOW_EVIL_CONSTRUCTORS(M3UParser);
};
diff --git a/media/libstagefright/include/MP3Extractor.h b/media/libstagefright/include/MP3Extractor.h
index ef71b8f..c83d9e8 100644
--- a/media/libstagefright/include/MP3Extractor.h
+++ b/media/libstagefright/include/MP3Extractor.h
@@ -39,11 +39,6 @@
virtual sp<MetaData> getMetaData();
- static bool get_mp3_frame_size(
- uint32_t header, size_t *frame_size,
- int *out_sampling_rate = NULL, int *out_channels = NULL,
- int *out_bitrate = NULL);
-
private:
status_t mInitCheck;
diff --git a/media/libstagefright/include/MPEG4Extractor.h b/media/libstagefright/include/MPEG4Extractor.h
index 04e8a6a..eae62c6 100644
--- a/media/libstagefright/include/MPEG4Extractor.h
+++ b/media/libstagefright/include/MPEG4Extractor.h
@@ -40,7 +40,6 @@
virtual sp<MetaData> getMetaData();
// for DRM
- virtual void setDrmFlag(bool flag);
virtual char* getDrmTrackInfo(size_t trackID, int *len);
protected:
@@ -57,7 +56,7 @@
};
sp<DataSource> mDataSource;
- bool mHaveMetadata;
+ status_t mInitCheck;
bool mHasVideo;
Track *mFirstTrack, *mLastTrack;
@@ -90,6 +89,8 @@
status_t parseTrackHeader(off64_t data_offset, off64_t data_size);
+ Track *findTrackByMimePrefix(const char *mimePrefix);
+
MPEG4Extractor(const MPEG4Extractor &);
MPEG4Extractor &operator=(const MPEG4Extractor &);
};
diff --git a/media/libstagefright/include/NuCachedSource2.h b/media/libstagefright/include/NuCachedSource2.h
index 022804c..22b2855 100644
--- a/media/libstagefright/include/NuCachedSource2.h
+++ b/media/libstagefright/include/NuCachedSource2.h
@@ -37,9 +37,12 @@
virtual status_t getSize(off64_t *size);
virtual uint32_t flags();
- virtual DecryptHandle* DrmInitialization();
- virtual void getDrmInfo(DecryptHandle **handle, DrmManagerClient **client);
+ virtual sp<DecryptHandle> DrmInitialization();
+ virtual void getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client);
virtual String8 getUri();
+
+ virtual String8 getMIMEType() const;
+
////////////////////////////////////////////////////////////////////////////
size_t cachedSize();
@@ -47,6 +50,12 @@
void resumeFetchingIfNecessary();
+ // The following methods are supported only if the
+ // data source is HTTP-based; otherwise, ERROR_UNSUPPORTED
+ // is returned.
+ status_t getEstimatedBandwidthKbps(int32_t *kbps);
+ status_t setCacheStatCollectFreq(int32_t freqMs);
+
protected:
virtual ~NuCachedSource2();
@@ -68,6 +77,10 @@
kWhatRead = 'read',
};
+ enum {
+ kMaxNumRetries = 10,
+ };
+
sp<DataSource> mSource;
sp<AHandlerReflector<NuCachedSource2> > mReflector;
sp<ALooper> mLooper;
@@ -84,6 +97,8 @@
bool mFetching;
int64_t mLastFetchTimeUs;
+ int32_t mNumRetriesLeft;
+
void onMessageReceived(const sp<AMessage> &msg);
void onFetch();
void onRead(const sp<AMessage> &msg);
@@ -93,7 +108,9 @@
status_t seekInternal_l(off64_t offset);
size_t approxDataRemaining_l(status_t *finalStatus);
- void restartPrefetcherIfNecessary_l(bool ignoreLowWaterThreshold = false);
+
+ void restartPrefetcherIfNecessary_l(
+ bool ignoreLowWaterThreshold = false, bool force = false);
DISALLOW_EVIL_CONSTRUCTORS(NuCachedSource2);
};
diff --git a/media/libstagefright/include/NuHTTPDataSource.h b/media/libstagefright/include/NuHTTPDataSource.h
deleted file mode 100644
index 2569568..0000000
--- a/media/libstagefright/include/NuHTTPDataSource.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2010 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 NU_HTTP_DATA_SOURCE_H_
-
-#define NU_HTTP_DATA_SOURCE_H_
-
-#include <media/stagefright/DataSource.h>
-#include <utils/List.h>
-#include <utils/String8.h>
-#include <utils/threads.h>
-
-#include "HTTPStream.h"
-
-namespace android {
-
-struct NuHTTPDataSource : public DataSource {
- enum Flags {
- // Don't log any URLs.
- kFlagIncognito = 1
- };
- NuHTTPDataSource(uint32_t flags = 0);
-
- status_t connect(
- const char *uri,
- const KeyedVector<String8, String8> *headers = NULL,
- off64_t offset = 0);
-
- void disconnect();
-
- virtual status_t initCheck() const;
-
- virtual ssize_t readAt(off64_t offset, void *data, size_t size);
- virtual status_t getSize(off64_t *size);
- virtual uint32_t flags();
-
- // Returns true if bandwidth could successfully be estimated,
- // false otherwise.
- bool estimateBandwidth(int32_t *bandwidth_bps);
-
- virtual DecryptHandle* DrmInitialization();
- virtual void getDrmInfo(DecryptHandle **handle, DrmManagerClient **client);
- virtual String8 getUri();
-
-protected:
- virtual ~NuHTTPDataSource();
-
-private:
- enum State {
- DISCONNECTED,
- CONNECTING,
- CONNECTED
- };
-
- struct BandwidthEntry {
- int64_t mDelayUs;
- size_t mNumBytes;
- };
-
- Mutex mLock;
-
- uint32_t mFlags;
-
- State mState;
-
- String8 mHost;
- unsigned mPort;
- String8 mPath;
- bool mHTTPS;
- String8 mHeaders;
- String8 mUri;
-
- HTTPStream mHTTP;
- off64_t mOffset;
- off64_t mContentLength;
- bool mContentLengthValid;
- bool mHasChunkedTransferEncoding;
-
- // The number of data bytes in the current chunk before any subsequent
- // chunk header (or -1 if no more chunks).
- ssize_t mChunkDataBytesLeft;
-
- List<BandwidthEntry> mBandwidthHistory;
- size_t mNumBandwidthHistoryItems;
- int64_t mTotalTransferTimeUs;
- size_t mTotalTransferBytes;
-
- DecryptHandle *mDecryptHandle;
- DrmManagerClient *mDrmManagerClient;
-
- status_t connect(
- const char *uri, const String8 &headers, off64_t offset);
-
- status_t connect(
- const char *host, unsigned port, const char *path,
- bool https,
- const String8 &headers,
- off64_t offset);
-
- // Read up to "size" bytes of data, respect transfer encoding.
- ssize_t internalRead(void *data, size_t size);
-
- void applyTimeoutResponse();
- void addBandwidthMeasurement_l(size_t numBytes, int64_t delayUs);
-
- static void MakeFullHeaders(
- const KeyedVector<String8, String8> *overrides,
- String8 *headers);
-
- NuHTTPDataSource(const NuHTTPDataSource &);
- NuHTTPDataSource &operator=(const NuHTTPDataSource &);
-};
-
-} // namespace android
-
-#endif // NU_HTTP_DATA_SOURCE_H_
diff --git a/media/libstagefright/include/OMX.h b/media/libstagefright/include/OMX.h
index ec3e5fa..d54b1c1 100644
--- a/media/libstagefright/include/OMX.h
+++ b/media/libstagefright/include/OMX.h
@@ -121,6 +121,7 @@
virtual ~OMX();
private:
+ struct CallbackDispatcherThread;
struct CallbackDispatcher;
Mutex mLock;
diff --git a/media/libstagefright/include/OMXNodeInstance.h b/media/libstagefright/include/OMXNodeInstance.h
index ca2578f..1ccf50d 100644
--- a/media/libstagefright/include/OMXNodeInstance.h
+++ b/media/libstagefright/include/OMXNodeInstance.h
@@ -109,7 +109,9 @@
void addActiveBuffer(OMX_U32 portIndex, OMX::buffer_id id);
void removeActiveBuffer(OMX_U32 portIndex, OMX::buffer_id id);
void freeActiveBuffers();
-
+ status_t useGraphicBuffer2_l(
+ OMX_U32 portIndex, const sp<GraphicBuffer> &graphicBuffer,
+ OMX::buffer_id *buffer);
static OMX_ERRORTYPE OnEvent(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_PTR pAppData,
diff --git a/media/libstagefright/include/SampleTable.h b/media/libstagefright/include/SampleTable.h
index 2f95de9..f44e0a2 100644
--- a/media/libstagefright/include/SampleTable.h
+++ b/media/libstagefright/include/SampleTable.h
@@ -63,7 +63,7 @@
uint32_t sampleIndex,
off64_t *offset,
size_t *size,
- uint32_t *decodingTime,
+ uint32_t *compositionTime,
bool *isSyncSample = NULL);
enum {
@@ -107,6 +107,12 @@
uint32_t mTimeToSampleCount;
uint32_t *mTimeToSample;
+ struct SampleTimeEntry {
+ uint32_t mSampleIndex;
+ uint32_t mCompositionTime;
+ };
+ SampleTimeEntry *mSampleTimeEntries;
+
uint32_t *mCompositionTimeDeltaEntries;
size_t mNumCompositionTimeDeltaEntries;
@@ -130,6 +136,10 @@
uint32_t getCompositionTimeOffset(uint32_t sampleIndex) const;
+ static int CompareIncreasingTime(const void *, const void *);
+
+ void buildSampleEntriesTable();
+
SampleTable(const SampleTable &);
SampleTable &operator=(const SampleTable &);
};
diff --git a/media/libstagefright/include/SimpleSoftOMXComponent.h b/media/libstagefright/include/SimpleSoftOMXComponent.h
new file mode 100644
index 0000000..50cd275
--- /dev/null
+++ b/media/libstagefright/include/SimpleSoftOMXComponent.h
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2011 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 SIMPLE_SOFT_OMX_COMPONENT_H_
+
+#define SIMPLE_SOFT_OMX_COMPONENT_H_
+
+#include "SoftOMXComponent.h"
+
+#include <media/stagefright/foundation/AHandlerReflector.h>
+#include <utils/RefBase.h>
+#include <utils/threads.h>
+#include <utils/Vector.h>
+
+namespace android {
+
+struct ALooper;
+
+struct SimpleSoftOMXComponent : public SoftOMXComponent {
+ SimpleSoftOMXComponent(
+ const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component);
+
+ virtual void prepareForDestruction();
+
+ void onMessageReceived(const sp<AMessage> &msg);
+
+protected:
+ struct BufferInfo {
+ OMX_BUFFERHEADERTYPE *mHeader;
+ bool mOwnedByUs;
+ };
+
+ struct PortInfo {
+ OMX_PARAM_PORTDEFINITIONTYPE mDef;
+ Vector<BufferInfo> mBuffers;
+ List<BufferInfo *> mQueue;
+
+ enum {
+ NONE,
+ DISABLING,
+ ENABLING,
+ } mTransition;
+ };
+
+ void addPort(const OMX_PARAM_PORTDEFINITIONTYPE &def);
+
+ virtual OMX_ERRORTYPE internalGetParameter(
+ OMX_INDEXTYPE index, OMX_PTR params);
+
+ virtual OMX_ERRORTYPE internalSetParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params);
+
+ virtual void onQueueFilled(OMX_U32 portIndex);
+ List<BufferInfo *> &getPortQueue(OMX_U32 portIndex);
+
+ virtual void onPortFlushCompleted(OMX_U32 portIndex);
+ virtual void onPortEnableCompleted(OMX_U32 portIndex, bool enabled);
+
+ PortInfo *editPortInfo(OMX_U32 portIndex);
+
+private:
+ enum {
+ kWhatSendCommand,
+ kWhatEmptyThisBuffer,
+ kWhatFillThisBuffer,
+ };
+
+ Mutex mLock;
+
+ sp<ALooper> mLooper;
+ sp<AHandlerReflector<SimpleSoftOMXComponent> > mHandler;
+
+ OMX_STATETYPE mState;
+ OMX_STATETYPE mTargetState;
+
+ Vector<PortInfo> mPorts;
+
+ bool isSetParameterAllowed(
+ OMX_INDEXTYPE index, const OMX_PTR params) const;
+
+ virtual OMX_ERRORTYPE sendCommand(
+ OMX_COMMANDTYPE cmd, OMX_U32 param, OMX_PTR data);
+
+ virtual OMX_ERRORTYPE getParameter(
+ OMX_INDEXTYPE index, OMX_PTR params);
+
+ virtual OMX_ERRORTYPE setParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params);
+
+ virtual OMX_ERRORTYPE useBuffer(
+ OMX_BUFFERHEADERTYPE **buffer,
+ OMX_U32 portIndex,
+ OMX_PTR appPrivate,
+ OMX_U32 size,
+ OMX_U8 *ptr);
+
+ virtual OMX_ERRORTYPE allocateBuffer(
+ OMX_BUFFERHEADERTYPE **buffer,
+ OMX_U32 portIndex,
+ OMX_PTR appPrivate,
+ OMX_U32 size);
+
+ virtual OMX_ERRORTYPE freeBuffer(
+ OMX_U32 portIndex,
+ OMX_BUFFERHEADERTYPE *buffer);
+
+ virtual OMX_ERRORTYPE emptyThisBuffer(
+ OMX_BUFFERHEADERTYPE *buffer);
+
+ virtual OMX_ERRORTYPE fillThisBuffer(
+ OMX_BUFFERHEADERTYPE *buffer);
+
+ virtual OMX_ERRORTYPE getState(OMX_STATETYPE *state);
+
+ void onSendCommand(OMX_COMMANDTYPE cmd, OMX_U32 param);
+ void onChangeState(OMX_STATETYPE state);
+ void onPortEnable(OMX_U32 portIndex, bool enable);
+ void onPortFlush(OMX_U32 portIndex, bool sendFlushComplete);
+
+ void checkTransitions();
+
+ DISALLOW_EVIL_CONSTRUCTORS(SimpleSoftOMXComponent);
+};
+
+} // namespace android
+
+#endif // SIMPLE_SOFT_OMX_COMPONENT_H_
diff --git a/media/libstagefright/include/SoftOMXComponent.h b/media/libstagefright/include/SoftOMXComponent.h
new file mode 100644
index 0000000..a808611
--- /dev/null
+++ b/media/libstagefright/include/SoftOMXComponent.h
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2011 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 SOFT_OMX_COMPONENT_H_
+
+#define SOFT_OMX_COMPONENT_H_
+
+#include <media/stagefright/foundation/ABase.h>
+#include <media/stagefright/foundation/AString.h>
+#include <utils/RefBase.h>
+
+#include <OMX_Component.h>
+
+namespace android {
+
+struct SoftOMXComponent : public RefBase {
+ SoftOMXComponent(
+ const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component);
+
+ virtual OMX_ERRORTYPE initCheck() const;
+
+ void setLibHandle(void *libHandle);
+ void *libHandle() const;
+
+ virtual void prepareForDestruction() {}
+
+protected:
+ virtual ~SoftOMXComponent();
+
+ const char *name() const;
+
+ void notify(
+ OMX_EVENTTYPE event,
+ OMX_U32 data1, OMX_U32 data2, OMX_PTR data);
+
+ void notifyEmptyBufferDone(OMX_BUFFERHEADERTYPE *header);
+ void notifyFillBufferDone(OMX_BUFFERHEADERTYPE *header);
+
+ virtual OMX_ERRORTYPE sendCommand(
+ OMX_COMMANDTYPE cmd, OMX_U32 param, OMX_PTR data);
+
+ virtual OMX_ERRORTYPE getParameter(
+ OMX_INDEXTYPE index, OMX_PTR params);
+
+ virtual OMX_ERRORTYPE setParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params);
+
+ virtual OMX_ERRORTYPE getConfig(
+ OMX_INDEXTYPE index, OMX_PTR params);
+
+ virtual OMX_ERRORTYPE setConfig(
+ OMX_INDEXTYPE index, const OMX_PTR params);
+
+ virtual OMX_ERRORTYPE getExtensionIndex(
+ const char *name, OMX_INDEXTYPE *index);
+
+ virtual OMX_ERRORTYPE useBuffer(
+ OMX_BUFFERHEADERTYPE **buffer,
+ OMX_U32 portIndex,
+ OMX_PTR appPrivate,
+ OMX_U32 size,
+ OMX_U8 *ptr);
+
+ virtual OMX_ERRORTYPE allocateBuffer(
+ OMX_BUFFERHEADERTYPE **buffer,
+ OMX_U32 portIndex,
+ OMX_PTR appPrivate,
+ OMX_U32 size);
+
+ virtual OMX_ERRORTYPE freeBuffer(
+ OMX_U32 portIndex,
+ OMX_BUFFERHEADERTYPE *buffer);
+
+ virtual OMX_ERRORTYPE emptyThisBuffer(
+ OMX_BUFFERHEADERTYPE *buffer);
+
+ virtual OMX_ERRORTYPE fillThisBuffer(
+ OMX_BUFFERHEADERTYPE *buffer);
+
+ virtual OMX_ERRORTYPE getState(OMX_STATETYPE *state);
+
+private:
+ AString mName;
+ const OMX_CALLBACKTYPE *mCallbacks;
+ OMX_COMPONENTTYPE *mComponent;
+
+ void *mLibHandle;
+
+ static OMX_ERRORTYPE SendCommandWrapper(
+ OMX_HANDLETYPE component,
+ OMX_COMMANDTYPE cmd,
+ OMX_U32 param,
+ OMX_PTR data);
+
+ static OMX_ERRORTYPE GetParameterWrapper(
+ OMX_HANDLETYPE component,
+ OMX_INDEXTYPE index,
+ OMX_PTR params);
+
+ static OMX_ERRORTYPE SetParameterWrapper(
+ OMX_HANDLETYPE component,
+ OMX_INDEXTYPE index,
+ OMX_PTR params);
+
+ static OMX_ERRORTYPE GetConfigWrapper(
+ OMX_HANDLETYPE component,
+ OMX_INDEXTYPE index,
+ OMX_PTR params);
+
+ static OMX_ERRORTYPE SetConfigWrapper(
+ OMX_HANDLETYPE component,
+ OMX_INDEXTYPE index,
+ OMX_PTR params);
+
+ static OMX_ERRORTYPE GetExtensionIndexWrapper(
+ OMX_HANDLETYPE component,
+ OMX_STRING name,
+ OMX_INDEXTYPE *index);
+
+ static OMX_ERRORTYPE UseBufferWrapper(
+ OMX_HANDLETYPE component,
+ OMX_BUFFERHEADERTYPE **buffer,
+ OMX_U32 portIndex,
+ OMX_PTR appPrivate,
+ OMX_U32 size,
+ OMX_U8 *ptr);
+
+ static OMX_ERRORTYPE AllocateBufferWrapper(
+ OMX_HANDLETYPE component,
+ OMX_BUFFERHEADERTYPE **buffer,
+ OMX_U32 portIndex,
+ OMX_PTR appPrivate,
+ OMX_U32 size);
+
+ static OMX_ERRORTYPE FreeBufferWrapper(
+ OMX_HANDLETYPE component,
+ OMX_U32 portIndex,
+ OMX_BUFFERHEADERTYPE *buffer);
+
+ static OMX_ERRORTYPE EmptyThisBufferWrapper(
+ OMX_HANDLETYPE component,
+ OMX_BUFFERHEADERTYPE *buffer);
+
+ static OMX_ERRORTYPE FillThisBufferWrapper(
+ OMX_HANDLETYPE component,
+ OMX_BUFFERHEADERTYPE *buffer);
+
+ static OMX_ERRORTYPE GetStateWrapper(
+ OMX_HANDLETYPE component,
+ OMX_STATETYPE *state);
+
+ DISALLOW_EVIL_CONSTRUCTORS(SoftOMXComponent);
+};
+
+} // namespace android
+
+#endif // SOFT_OMX_COMPONENT_H_
diff --git a/media/libstagefright/include/SoftwareRenderer.h b/media/libstagefright/include/SoftwareRenderer.h
index 78037b9..8f2ea95 100644
--- a/media/libstagefright/include/SoftwareRenderer.h
+++ b/media/libstagefright/include/SoftwareRenderer.h
@@ -47,6 +47,7 @@
sp<ANativeWindow> mNativeWindow;
int32_t mWidth, mHeight;
int32_t mCropLeft, mCropTop, mCropRight, mCropBottom;
+ int32_t mCropWidth, mCropHeight;
SoftwareRenderer(const SoftwareRenderer &);
SoftwareRenderer &operator=(const SoftwareRenderer &);
diff --git a/media/libstagefright/include/StagefrightMetadataRetriever.h b/media/libstagefright/include/StagefrightMetadataRetriever.h
index 07b1ec8..b02ed0e 100644
--- a/media/libstagefright/include/StagefrightMetadataRetriever.h
+++ b/media/libstagefright/include/StagefrightMetadataRetriever.h
@@ -32,7 +32,10 @@
StagefrightMetadataRetriever();
virtual ~StagefrightMetadataRetriever();
- virtual status_t setDataSource(const char *url);
+ virtual status_t setDataSource(
+ const char *url,
+ const KeyedVector<String8, String8> *headers);
+
virtual status_t setDataSource(int fd, int64_t offset, int64_t length);
virtual VideoFrame *getFrameAtTime(int64_t timeUs, int option);
diff --git a/media/libstagefright/include/ThreadedSource.h b/media/libstagefright/include/ThreadedSource.h
deleted file mode 100644
index c67295c..0000000
--- a/media/libstagefright/include/ThreadedSource.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2010 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 THREADED_SOURCE_H_
-
-#define THREADED_SOURCE_H_
-
-#include <media/stagefright/foundation/ABase.h>
-#include <media/stagefright/foundation/AHandlerReflector.h>
-#include <media/stagefright/foundation/ALooper.h>
-#include <media/stagefright/MediaSource.h>
-#include <utils/threads.h>
-
-namespace android {
-
-struct ThreadedSource : public MediaSource {
- ThreadedSource(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 onMessageReceived(const sp<AMessage> &msg);
-
-protected:
- virtual ~ThreadedSource();
-
-private:
- enum {
- kWhatDecodeMore = 'deco',
- kWhatSeek = 'seek',
- };
-
- sp<MediaSource> mSource;
- sp<AHandlerReflector<ThreadedSource> > mReflector;
- sp<ALooper> mLooper;
-
- Mutex mLock;
- Condition mCondition;
- List<MediaBuffer *> mQueue;
- status_t mFinalResult;
- bool mDecodePending;
- bool mStarted;
-
- int64_t mSeekTimeUs;
- ReadOptions::SeekMode mSeekMode;
-
- void postDecodeMore_l();
- void clearQueue_l();
-
- DISALLOW_EVIL_CONSTRUCTORS(ThreadedSource);
-};
-
-} // namespace android
-
-#endif // THREADED_SOURCE_H_
diff --git a/media/libstagefright/include/XINGSeeker.h b/media/libstagefright/include/XINGSeeker.h
index d5a484e..ec5bd9b 100644
--- a/media/libstagefright/include/XINGSeeker.h
+++ b/media/libstagefright/include/XINGSeeker.h
@@ -37,7 +37,7 @@
int32_t mSizeBytes;
// TOC entries in XING header. Skip the first one since it's always 0.
- char mTableOfContents[99];
+ unsigned char mTableOfContents[99];
XINGSeeker();
diff --git a/media/libstagefright/include/avc_utils.h b/media/libstagefright/include/avc_utils.h
index afff824..15cd4d4 100644
--- a/media/libstagefright/include/avc_utils.h
+++ b/media/libstagefright/include/avc_utils.h
@@ -57,6 +57,16 @@
unsigned profile, unsigned sampling_freq_index,
unsigned channel_configuration);
+// Given an MPEG4 video VOL-header chunk (starting with 0x00 0x00 0x01 0x2?)
+// parse it and fill in dimensions, returns true iff successful.
+bool ExtractDimensionsFromVOLHeader(
+ const uint8_t *data, size_t size, int32_t *width, int32_t *height);
+
+bool GetMPEGAudioFrameSize(
+ uint32_t header, size_t *frame_size,
+ int *out_sampling_rate = NULL, int *out_channels = NULL,
+ int *out_bitrate = NULL, int *out_num_samples = NULL);
+
} // namespace android
#endif // AVC_UTILS_H_
diff --git a/media/libstagefright/matroska/MatroskaExtractor.cpp b/media/libstagefright/matroska/MatroskaExtractor.cpp
index 642835a..e1b9991 100644
--- a/media/libstagefright/matroska/MatroskaExtractor.cpp
+++ b/media/libstagefright/matroska/MatroskaExtractor.cpp
@@ -60,7 +60,10 @@
virtual int Length(long long* total, long long* available) {
off64_t size;
if (mSource->getSize(&size) != OK) {
- return -1;
+ *total = -1;
+ *available = (long long)((1ull << 63) - 1);
+
+ return 0;
}
if (total) {
@@ -84,7 +87,7 @@
////////////////////////////////////////////////////////////////////////////////
struct BlockIterator {
- BlockIterator(mkvparser::Segment *segment, unsigned long trackNum);
+ BlockIterator(MatroskaExtractor *extractor, unsigned long trackNum);
bool eos() const;
@@ -96,11 +99,14 @@
int64_t blockTimeUs() const;
private:
- mkvparser::Segment *mSegment;
+ MatroskaExtractor *mExtractor;
unsigned long mTrackNum;
- mkvparser::Cluster *mCluster;
+ const mkvparser::Cluster *mCluster;
const mkvparser::BlockEntry *mBlockEntry;
+ long mBlockEntryIndex;
+
+ void advance_l();
BlockIterator(const BlockIterator &);
BlockIterator &operator=(const BlockIterator &);
@@ -150,7 +156,7 @@
: mExtractor(extractor),
mTrackIndex(index),
mType(OTHER),
- mBlockIter(mExtractor->mSegment,
+ mBlockIter(mExtractor.get(),
mExtractor->mTracks.itemAt(index).mTrackNum),
mNALSizeLen(0) {
sp<MetaData> meta = mExtractor->mTracks.itemAt(index).mMeta;
@@ -199,11 +205,12 @@
////////////////////////////////////////////////////////////////////////////////
BlockIterator::BlockIterator(
- mkvparser::Segment *segment, unsigned long trackNum)
- : mSegment(segment),
+ MatroskaExtractor *extractor, unsigned long trackNum)
+ : mExtractor(extractor),
mTrackNum(trackNum),
mCluster(NULL),
- mBlockEntry(NULL) {
+ mBlockEntry(NULL),
+ mBlockEntryIndex(0) {
reset();
}
@@ -212,45 +219,100 @@
}
void BlockIterator::advance() {
- while (!eos()) {
- if (mBlockEntry != NULL) {
- mBlockEntry = mCluster->GetNext(mBlockEntry);
- } else if (mCluster != NULL) {
- mCluster = mSegment->GetNext(mCluster);
+ Mutex::Autolock autoLock(mExtractor->mLock);
+ advance_l();
+}
- if (eos()) {
+void BlockIterator::advance_l() {
+ for (;;) {
+ long res = mCluster->GetEntry(mBlockEntryIndex, mBlockEntry);
+ LOGV("GetEntry returned %ld", res);
+
+ long long pos;
+ long len;
+ if (res < 0) {
+ // Need to parse this cluster some more
+
+ CHECK_EQ(res, mkvparser::E_BUFFER_NOT_FULL);
+
+ res = mCluster->Parse(pos, len);
+ LOGV("Parse returned %ld", res);
+
+ if (res < 0) {
+ // I/O error
+
+ LOGE("Cluster::Parse returned result %ld", res);
+
+ mCluster = NULL;
break;
}
- mBlockEntry = mCluster->GetFirst();
+ continue;
+ } else if (res == 0) {
+ // We're done with this cluster
+
+ const mkvparser::Cluster *nextCluster;
+ res = mExtractor->mSegment->ParseNext(
+ mCluster, nextCluster, pos, len);
+ LOGV("ParseNext returned %ld", res);
+
+ if (res > 0) {
+ // EOF
+
+ mCluster = NULL;
+ break;
+ }
+
+ CHECK_EQ(res, 0);
+ CHECK(nextCluster != NULL);
+ CHECK(!nextCluster->EOS());
+
+ mCluster = nextCluster;
+
+ res = mCluster->Parse(pos, len);
+ LOGV("Parse (2) returned %ld", res);
+ CHECK_GE(res, 0);
+
+ mBlockEntryIndex = 0;
+ continue;
}
- if (mBlockEntry != NULL
- && mBlockEntry->GetBlock()->GetTrackNumber() == mTrackNum) {
+ CHECK(mBlockEntry != NULL);
+ CHECK(mBlockEntry->GetBlock() != NULL);
+ ++mBlockEntryIndex;
+
+ if (mBlockEntry->GetBlock()->GetTrackNumber() == mTrackNum) {
break;
}
}
}
void BlockIterator::reset() {
- mCluster = mSegment->GetFirst();
- mBlockEntry = mCluster->GetFirst();
+ Mutex::Autolock autoLock(mExtractor->mLock);
- while (!eos() && block()->GetTrackNumber() != mTrackNum) {
- advance();
- }
+ mCluster = mExtractor->mSegment->GetFirst();
+ mBlockEntry = NULL;
+ mBlockEntryIndex = 0;
+
+ do {
+ advance_l();
+ } while (!eos() && block()->GetTrackNumber() != mTrackNum);
}
void BlockIterator::seek(int64_t seekTimeUs) {
- mCluster = mSegment->FindCluster(seekTimeUs * 1000ll);
- mBlockEntry = mCluster != NULL ? mCluster->GetFirst() : NULL;
+ Mutex::Autolock autoLock(mExtractor->mLock);
- while (!eos() && block()->GetTrackNumber() != mTrackNum) {
- advance();
+ mCluster = mExtractor->mSegment->FindCluster(seekTimeUs * 1000ll);
+ mBlockEntry = NULL;
+ mBlockEntryIndex = 0;
+
+ do {
+ advance_l();
}
+ while (!eos() && block()->GetTrackNumber() != mTrackNum);
while (!eos() && !mBlockEntry->GetBlock()->IsKey()) {
- advance();
+ advance_l();
}
}
@@ -291,16 +353,6 @@
}
}
-#define BAIL(err) \
- do { \
- if (bigbuf) { \
- bigbuf->release(); \
- bigbuf = NULL; \
- } \
- \
- return err; \
- } while (0)
-
status_t MatroskaSource::readBlock() {
CHECK(mPendingFrames.empty());
@@ -310,181 +362,39 @@
const mkvparser::Block *block = mBlockIter.block();
- size_t size = block->GetSize();
int64_t timeUs = mBlockIter.blockTimeUs();
- int32_t isSync = block->IsKey();
- MediaBuffer *bigbuf = new MediaBuffer(size);
+ for (int i = 0; i < block->GetFrameCount(); ++i) {
+ const mkvparser::Block::Frame &frame = block->GetFrame(i);
- long res = block->Read(
- mExtractor->mReader, (unsigned char *)bigbuf->data());
+ MediaBuffer *mbuf = new MediaBuffer(frame.len);
+ mbuf->meta_data()->setInt64(kKeyTime, timeUs);
+ mbuf->meta_data()->setInt32(kKeyIsSyncFrame, block->IsKey());
- if (res != 0) {
- bigbuf->release();
- bigbuf = NULL;
+ long n = frame.Read(mExtractor->mReader, (unsigned char *)mbuf->data());
+ if (n != 0) {
+ mPendingFrames.clear();
- return ERROR_END_OF_STREAM;
+ mBlockIter.advance();
+ return ERROR_IO;
+ }
+
+ mPendingFrames.push_back(mbuf);
}
mBlockIter.advance();
- bigbuf->meta_data()->setInt64(kKeyTime, timeUs);
- bigbuf->meta_data()->setInt32(kKeyIsSyncFrame, isSync);
-
- unsigned lacing = (block->Flags() >> 1) & 3;
-
- if (lacing == 0) {
- mPendingFrames.push_back(bigbuf);
- return OK;
- }
-
- LOGV("lacing = %u, size = %d", lacing, size);
-
- const uint8_t *data = (const uint8_t *)bigbuf->data();
- // hexdump(data, size);
-
- if (size == 0) {
- BAIL(ERROR_MALFORMED);
- }
-
- unsigned numFrames = (unsigned)data[0] + 1;
- ++data;
- --size;
-
- Vector<uint64_t> frameSizes;
-
- switch (lacing) {
- case 1: // Xiph
- {
- for (size_t i = 0; i < numFrames - 1; ++i) {
- size_t frameSize = 0;
- uint8_t byte;
- do {
- if (size == 0) {
- BAIL(ERROR_MALFORMED);
- }
- byte = data[0];
- ++data;
- --size;
-
- frameSize += byte;
- } while (byte == 0xff);
-
- frameSizes.push(frameSize);
- }
-
- break;
- }
-
- case 2: // fixed-size
- {
- if ((size % numFrames) != 0) {
- BAIL(ERROR_MALFORMED);
- }
-
- size_t frameSize = size / numFrames;
- for (size_t i = 0; i < numFrames - 1; ++i) {
- frameSizes.push(frameSize);
- }
-
- break;
- }
-
- case 3: // EBML
- {
- uint64_t lastFrameSize = 0;
- for (size_t i = 0; i < numFrames - 1; ++i) {
- uint8_t byte;
-
- if (size == 0) {
- BAIL(ERROR_MALFORMED);
- }
- byte = data[0];
- ++data;
- --size;
-
- size_t numLeadingZeroes = clz(byte);
-
- uint64_t frameSize = byte & ~(0x80 >> numLeadingZeroes);
- for (size_t j = 0; j < numLeadingZeroes; ++j) {
- if (size == 0) {
- BAIL(ERROR_MALFORMED);
- }
-
- frameSize = frameSize << 8;
- frameSize |= data[0];
- ++data;
- --size;
- }
-
- if (i == 0) {
- frameSizes.push(frameSize);
- } else {
- size_t shift =
- 7 - numLeadingZeroes + 8 * numLeadingZeroes;
-
- int64_t delta =
- (int64_t)frameSize - (1ll << (shift - 1)) + 1;
-
- frameSize = lastFrameSize + delta;
-
- frameSizes.push(frameSize);
- }
-
- lastFrameSize = frameSize;
- }
- break;
- }
-
- default:
- TRESPASS();
- }
-
-#if 0
- AString out;
- for (size_t i = 0; i < frameSizes.size(); ++i) {
- if (i > 0) {
- out.append(", ");
- }
- out.append(StringPrintf("%llu", frameSizes.itemAt(i)));
- }
- LOGV("sizes = [%s]", out.c_str());
-#endif
-
- for (size_t i = 0; i < frameSizes.size(); ++i) {
- uint64_t frameSize = frameSizes.itemAt(i);
-
- if (size < frameSize) {
- BAIL(ERROR_MALFORMED);
- }
-
- MediaBuffer *mbuf = new MediaBuffer(frameSize);
- mbuf->meta_data()->setInt64(kKeyTime, timeUs);
- mbuf->meta_data()->setInt32(kKeyIsSyncFrame, isSync);
- memcpy(mbuf->data(), data, frameSize);
- mPendingFrames.push_back(mbuf);
-
- data += frameSize;
- size -= frameSize;
- }
-
- size_t offset = bigbuf->range_length() - size;
- bigbuf->set_range(offset, size);
-
- mPendingFrames.push_back(bigbuf);
-
return OK;
}
-#undef BAIL
-
status_t MatroskaSource::read(
MediaBuffer **out, const ReadOptions *options) {
*out = NULL;
int64_t seekTimeUs;
ReadOptions::SeekMode mode;
- if (options && options->getSeekTo(&seekTimeUs, &mode)) {
+ if (options && options->getSeekTo(&seekTimeUs, &mode)
+ && !mExtractor->isLiveStreaming()) {
clearPendingFrames();
mBlockIter.seek(seekTimeUs);
}
@@ -584,6 +494,13 @@
mReader(new DataSourceReader(mDataSource)),
mSegment(NULL),
mExtractedThumbnails(false) {
+ off64_t size;
+ mIsLiveStreaming =
+ (mDataSource->flags()
+ & (DataSource::kWantsPrefetching
+ | DataSource::kIsCachingDataSource))
+ && mDataSource->getSize(&size) != OK;
+
mkvparser::EBMLHeader ebmlHeader;
long long pos;
if (ebmlHeader.Parse(mReader, pos) < 0) {
@@ -598,7 +515,16 @@
return;
}
- ret = mSegment->Load();
+ if (isLiveStreaming()) {
+ ret = mSegment->ParseHeaders();
+ CHECK_EQ(ret, 0);
+
+ long len;
+ ret = mSegment->LoadCluster(pos, len);
+ CHECK_EQ(ret, 0);
+ } else {
+ ret = mSegment->Load();
+ }
if (ret < 0) {
delete mSegment;
@@ -635,7 +561,8 @@
return NULL;
}
- if ((flags & kIncludeExtensiveMetaData) && !mExtractedThumbnails) {
+ if ((flags & kIncludeExtensiveMetaData) && !mExtractedThumbnails
+ && !isLiveStreaming()) {
findThumbnails();
mExtractedThumbnails = true;
}
@@ -643,6 +570,10 @@
return mTracks.itemAt(index).mMeta;
}
+bool MatroskaExtractor::isLiveStreaming() const {
+ return mIsLiveStreaming;
+}
+
static void addESDSFromAudioSpecificInfo(
const sp<MetaData> &meta, const void *asi, size_t asiSize) {
static const uint8_t kStaticESDS[] = {
@@ -800,7 +731,7 @@
continue;
}
- BlockIterator iter(mSegment, info->mTrackNum);
+ BlockIterator iter(this, info->mTrackNum);
int32_t i = 0;
int64_t thumbnailTimeUs = 0;
size_t maxBlockSize = 0;
@@ -808,7 +739,11 @@
if (iter.block()->IsKey()) {
++i;
- size_t blockSize = iter.block()->GetSize();
+ size_t blockSize = 0;
+ for (int i = 0; i < iter.block()->GetFrameCount(); ++i) {
+ blockSize += iter.block()->GetFrame(i).len;
+ }
+
if (blockSize > maxBlockSize) {
maxBlockSize = blockSize;
thumbnailTimeUs = iter.blockTimeUs();
@@ -827,6 +762,15 @@
return meta;
}
+uint32_t MatroskaExtractor::flags() const {
+ uint32_t x = CAN_PAUSE;
+ if (!isLiveStreaming()) {
+ x |= CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK;
+ }
+
+ return x;
+}
+
bool SniffMatroska(
const sp<DataSource> &source, String8 *mimeType, float *confidence,
sp<AMessage> *) {
diff --git a/media/libstagefright/matroska/MatroskaExtractor.h b/media/libstagefright/matroska/MatroskaExtractor.h
index fa20b84..38ebd61 100644
--- a/media/libstagefright/matroska/MatroskaExtractor.h
+++ b/media/libstagefright/matroska/MatroskaExtractor.h
@@ -20,6 +20,7 @@
#include <media/stagefright/MediaExtractor.h>
#include <utils/Vector.h>
+#include <utils/threads.h>
namespace mkvparser {
struct Segment;
@@ -45,26 +46,34 @@
virtual sp<MetaData> getMetaData();
+ virtual uint32_t flags() const;
+
protected:
virtual ~MatroskaExtractor();
private:
friend struct MatroskaSource;
+ friend struct BlockIterator;
struct TrackInfo {
unsigned long mTrackNum;
sp<MetaData> mMeta;
};
+
+ Mutex mLock;
Vector<TrackInfo> mTracks;
sp<DataSource> mDataSource;
DataSourceReader *mReader;
mkvparser::Segment *mSegment;
bool mExtractedThumbnails;
+ bool mIsLiveStreaming;
void addTracks();
void findThumbnails();
+ bool isLiveStreaming() const;
+
MatroskaExtractor(const MatroskaExtractor &);
MatroskaExtractor &operator=(const MatroskaExtractor &);
};
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index 7d4bc6e..5bbc2b4 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -44,7 +44,7 @@
static const size_t kTSPacketSize = 188;
struct ATSParser::Program : public RefBase {
- Program(ATSParser *parser, unsigned programMapPID);
+ Program(ATSParser *parser, unsigned programNumber, unsigned programMapPID);
bool parsePID(
unsigned pid, unsigned payload_unit_start_indicator,
@@ -63,8 +63,15 @@
return mFirstPTSValid;
}
+ unsigned number() const { return mProgramNumber; }
+
+ void updateProgramMapPID(unsigned programMapPID) {
+ mProgramMapPID = programMapPID;
+ }
+
private:
ATSParser *mParser;
+ unsigned mProgramNumber;
unsigned mProgramMapPID;
KeyedVector<unsigned, sp<Stream> > mStreams;
bool mFirstPTSValid;
@@ -107,7 +114,7 @@
DiscontinuityType mPendingDiscontinuity;
sp<AMessage> mPendingDiscontinuityExtra;
- ElementaryStreamQueue mQueue;
+ ElementaryStreamQueue *mQueue;
void flush();
void parsePES(ABitReader *br);
@@ -126,11 +133,14 @@
////////////////////////////////////////////////////////////////////////////////
-ATSParser::Program::Program(ATSParser *parser, unsigned programMapPID)
+ATSParser::Program::Program(
+ ATSParser *parser, unsigned programNumber, unsigned programMapPID)
: mParser(parser),
+ mProgramNumber(programNumber),
mProgramMapPID(programMapPID),
mFirstPTSValid(false),
mFirstPTS(0) {
+ LOGV("new program number %u", programNumber);
}
bool ATSParser::Program::parsePID(
@@ -299,7 +309,7 @@
}
sp<MediaSource> ATSParser::Program::getSource(SourceType type) {
- size_t index = (type == MPEG2ADTS_AUDIO) ? 0 : 0;
+ size_t index = (type == AUDIO) ? 0 : 0;
for (size_t i = 0; i < mStreams.size(); ++i) {
sp<MediaSource> source = mStreams.editValueAt(i)->getSource(type);
@@ -338,14 +348,43 @@
mBuffer(new ABuffer(192 * 1024)),
mPayloadStarted(false),
mPendingDiscontinuity(DISCONTINUITY_NONE),
- mQueue(streamType == 0x1b
- ? ElementaryStreamQueue::H264 : ElementaryStreamQueue::AAC) {
+ mQueue(NULL) {
mBuffer->setRange(0, 0);
+ switch (mStreamType) {
+ case STREAMTYPE_H264:
+ mQueue = new ElementaryStreamQueue(ElementaryStreamQueue::H264);
+ break;
+ case STREAMTYPE_MPEG2_AUDIO_ATDS:
+ mQueue = new ElementaryStreamQueue(ElementaryStreamQueue::AAC);
+ break;
+ case STREAMTYPE_MPEG1_AUDIO:
+ case STREAMTYPE_MPEG2_AUDIO:
+ mQueue = new ElementaryStreamQueue(
+ ElementaryStreamQueue::MPEG_AUDIO);
+ break;
+
+ case STREAMTYPE_MPEG1_VIDEO:
+ case STREAMTYPE_MPEG2_VIDEO:
+ mQueue = new ElementaryStreamQueue(
+ ElementaryStreamQueue::MPEG_VIDEO);
+ break;
+
+ case STREAMTYPE_MPEG4_VIDEO:
+ mQueue = new ElementaryStreamQueue(
+ ElementaryStreamQueue::MPEG4_VIDEO);
+ break;
+
+ default:
+ break;
+ }
+
LOGV("new stream PID 0x%02x, type 0x%02x", elementaryPID, streamType);
}
ATSParser::Stream::~Stream() {
+ delete mQueue;
+ mQueue = NULL;
}
void ATSParser::Stream::parse(
@@ -397,7 +436,7 @@
{
bool isASeek = (type == DISCONTINUITY_SEEK);
- mQueue.clear(!isASeek);
+ mQueue->clear(!isASeek);
uint64_t resumeAtPTS;
if (extra != NULL
@@ -444,6 +483,12 @@
LOGV("packet_startcode_prefix = 0x%08x", packet_startcode_prefix);
+ if (packet_startcode_prefix != 1) {
+ LOGV("Supposedly payload_unit_start=1 unit does not start "
+ "with startcode.");
+ return;
+ }
+
CHECK_EQ(packet_startcode_prefix, 0x000001u);
unsigned stream_id = br->getBits(8);
@@ -611,22 +656,28 @@
const uint8_t *data, size_t size) {
LOGV("onPayloadData mStreamType=0x%02x", mStreamType);
+ if (mQueue == NULL) {
+ return;
+ }
+
CHECK(PTS_DTS_flags == 2 || PTS_DTS_flags == 3);
int64_t timeUs = mProgram->convertPTSToTimestamp(PTS);
- status_t err = mQueue.appendData(data, size, timeUs);
+ status_t err = mQueue->appendData(data, size, timeUs);
if (err != OK) {
return;
}
sp<ABuffer> accessUnit;
- while ((accessUnit = mQueue.dequeueAccessUnit()) != NULL) {
+ while ((accessUnit = mQueue->dequeueAccessUnit()) != NULL) {
if (mSource == NULL) {
- sp<MetaData> meta = mQueue.getFormat();
+ sp<MetaData> meta = mQueue->getFormat();
if (meta != NULL) {
- LOGV("created source!");
+ LOGV("Stream PID 0x%08x of type 0x%02x now has data.",
+ mElementaryPID, mStreamType);
+
mSource = new AnotherPacketSource(meta);
if (mPendingDiscontinuity != DISCONTINUITY_NONE) {
@@ -638,13 +689,13 @@
mSource->queueAccessUnit(accessUnit);
}
- } else if (mQueue.getFormat() != NULL) {
+ } else if (mQueue->getFormat() != NULL) {
// After a discontinuity we invalidate the queue's format
// and won't enqueue any access units to the source until
// the queue has reestablished the new format.
if (mSource->getFormat() == NULL) {
- mSource->setFormat(mQueue.getFormat());
+ mSource->setFormat(mQueue->getFormat());
}
mSource->queueAccessUnit(accessUnit);
}
@@ -652,9 +703,30 @@
}
sp<MediaSource> ATSParser::Stream::getSource(SourceType type) {
- if ((type == AVC_VIDEO && mStreamType == 0x1b)
- || (type == MPEG2ADTS_AUDIO && mStreamType == 0x0f)) {
- return mSource;
+ switch (type) {
+ case VIDEO:
+ {
+ if (mStreamType == STREAMTYPE_H264
+ || mStreamType == STREAMTYPE_MPEG1_VIDEO
+ || mStreamType == STREAMTYPE_MPEG2_VIDEO
+ || mStreamType == STREAMTYPE_MPEG4_VIDEO) {
+ return mSource;
+ }
+ break;
+ }
+
+ case AUDIO:
+ {
+ if (mStreamType == STREAMTYPE_MPEG1_AUDIO
+ || mStreamType == STREAMTYPE_MPEG2_AUDIO
+ || mStreamType == STREAMTYPE_MPEG2_AUDIO_ATDS) {
+ return mSource;
+ }
+ break;
+ }
+
+ default:
+ break;
}
return NULL;
@@ -729,7 +801,21 @@
LOGV(" program_map_PID = 0x%04x", programMapPID);
- mPrograms.push(new Program(this, programMapPID));
+ bool found = false;
+ for (size_t index = 0; index < mPrograms.size(); ++index) {
+ const sp<Program> &program = mPrograms.itemAt(index);
+
+ if (program->number() == program_number) {
+ program->updateProgramMapPID(programMapPID);
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ mPrograms.push(
+ new Program(this, program_number, programMapPID));
+ }
}
}
@@ -805,8 +891,16 @@
}
sp<MediaSource> ATSParser::getSource(SourceType type) {
+ int which = -1; // any
+
for (size_t i = 0; i < mPrograms.size(); ++i) {
- sp<MediaSource> source = mPrograms.editItemAt(i)->getSource(type);
+ const sp<Program> &program = mPrograms.editItemAt(i);
+
+ if (which >= 0 && (int)program->number() != which) {
+ continue;
+ }
+
+ sp<MediaSource> source = program->getSource(type);
if (source != NULL) {
return source;
diff --git a/media/libstagefright/mpeg2ts/ATSParser.h b/media/libstagefright/mpeg2ts/ATSParser.h
index 3936f05..1e6451d 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.h
+++ b/media/libstagefright/mpeg2ts/ATSParser.h
@@ -48,8 +48,8 @@
void signalEOS(status_t finalResult);
enum SourceType {
- AVC_VIDEO,
- MPEG2ADTS_AUDIO
+ VIDEO,
+ AUDIO
};
sp<MediaSource> getSource(SourceType type);
@@ -59,6 +59,17 @@
virtual ~ATSParser();
private:
+ enum {
+ // From ISO/IEC 13818-1: 2000 (E), Table 2-29
+ STREAMTYPE_MPEG1_VIDEO = 0x01,
+ STREAMTYPE_MPEG2_VIDEO = 0x02,
+ STREAMTYPE_MPEG1_AUDIO = 0x03,
+ STREAMTYPE_MPEG2_AUDIO = 0x04,
+ STREAMTYPE_MPEG2_AUDIO_ATDS = 0x0f,
+ STREAMTYPE_MPEG4_VIDEO = 0x10,
+ STREAMTYPE_H264 = 0x1b,
+ };
+
struct Program;
struct Stream;
diff --git a/media/libstagefright/mpeg2ts/ESQueue.cpp b/media/libstagefright/mpeg2ts/ESQueue.cpp
index dcaf9f7..f8a1d84 100644
--- a/media/libstagefright/mpeg2ts/ESQueue.cpp
+++ b/media/libstagefright/mpeg2ts/ESQueue.cpp
@@ -27,6 +27,7 @@
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MetaData.h>
+#include <media/stagefright/Utils.h>
#include "include/avc_utils.h"
@@ -79,11 +80,49 @@
return true;
}
+static bool IsSeeminglyValidMPEGAudioHeader(const uint8_t *ptr, size_t size) {
+ if (size < 3) {
+ // Not enough data to verify header.
+ return false;
+ }
+
+ if (ptr[0] != 0xff || (ptr[1] >> 5) != 0x07) {
+ return false;
+ }
+
+ unsigned ID = (ptr[1] >> 3) & 3;
+
+ if (ID == 1) {
+ return false; // reserved
+ }
+
+ unsigned layer = (ptr[1] >> 1) & 3;
+
+ if (layer == 0) {
+ return false; // reserved
+ }
+
+ unsigned bitrateIndex = (ptr[2] >> 4);
+
+ if (bitrateIndex == 0x0f) {
+ return false; // reserved
+ }
+
+ unsigned samplingRateIndex = (ptr[2] >> 2) & 3;
+
+ if (samplingRateIndex == 3) {
+ return false; // reserved
+ }
+
+ return true;
+}
+
status_t ElementaryStreamQueue::appendData(
const void *data, size_t size, int64_t timeUs) {
if (mBuffer == NULL || mBuffer->size() == 0) {
switch (mMode) {
case H264:
+ case MPEG_VIDEO:
{
#if 0
if (size < 4 || memcmp("\x00\x00\x00\x01", data, 4)) {
@@ -105,7 +144,40 @@
}
if (startOffset > 0) {
- LOGI("found something resembling an H.264 syncword at "
+ LOGI("found something resembling an H.264/MPEG syncword at "
+ "offset %ld",
+ startOffset);
+ }
+
+ data = &ptr[startOffset];
+ size -= startOffset;
+#endif
+ break;
+ }
+
+ case MPEG4_VIDEO:
+ {
+#if 0
+ if (size < 3 || memcmp("\x00\x00\x01", data, 3)) {
+ return ERROR_MALFORMED;
+ }
+#else
+ uint8_t *ptr = (uint8_t *)data;
+
+ ssize_t startOffset = -1;
+ for (size_t i = 0; i + 2 < size; ++i) {
+ if (!memcmp("\x00\x00\x01", &ptr[i], 3)) {
+ startOffset = i;
+ break;
+ }
+ }
+
+ if (startOffset < 0) {
+ return ERROR_MALFORMED;
+ }
+
+ if (startOffset > 0) {
+ LOGI("found something resembling an H.264/MPEG syncword at "
"offset %ld",
startOffset);
}
@@ -148,6 +220,33 @@
break;
}
+ case MPEG_AUDIO:
+ {
+ uint8_t *ptr = (uint8_t *)data;
+
+ ssize_t startOffset = -1;
+ for (size_t i = 0; i < size; ++i) {
+ if (IsSeeminglyValidMPEGAudioHeader(&ptr[i], size - i)) {
+ startOffset = i;
+ break;
+ }
+ }
+
+ if (startOffset < 0) {
+ return ERROR_MALFORMED;
+ }
+
+ if (startOffset > 0) {
+ LOGI("found something resembling an MPEG audio "
+ "syncword at offset %ld",
+ startOffset);
+ }
+
+ data = &ptr[startOffset];
+ size -= startOffset;
+ break;
+ }
+
default:
TRESPASS();
break;
@@ -190,11 +289,18 @@
}
sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnit() {
- if (mMode == H264) {
- return dequeueAccessUnitH264();
- } else {
- CHECK_EQ((unsigned)mMode, (unsigned)AAC);
- return dequeueAccessUnitAAC();
+ switch (mMode) {
+ case H264:
+ return dequeueAccessUnitH264();
+ case AAC:
+ return dequeueAccessUnitAAC();
+ case MPEG_VIDEO:
+ return dequeueAccessUnitMPEGVideo();
+ case MPEG4_VIDEO:
+ return dequeueAccessUnitMPEG4Video();
+ default:
+ CHECK_EQ((unsigned)mMode, (unsigned)MPEG_AUDIO);
+ return dequeueAccessUnitMPEGAudio();
}
}
@@ -455,4 +561,371 @@
return NULL;
}
+sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEGAudio() {
+ const uint8_t *data = mBuffer->data();
+ size_t size = mBuffer->size();
+
+ if (size < 4) {
+ return NULL;
+ }
+
+ uint32_t header = U32_AT(data);
+
+ size_t frameSize;
+ int samplingRate, numChannels, bitrate, numSamples;
+ CHECK(GetMPEGAudioFrameSize(
+ header, &frameSize, &samplingRate, &numChannels,
+ &bitrate, &numSamples));
+
+ if (size < frameSize) {
+ return NULL;
+ }
+
+ sp<ABuffer> accessUnit = new ABuffer(frameSize);
+ memcpy(accessUnit->data(), data, frameSize);
+
+ memmove(mBuffer->data(),
+ mBuffer->data() + frameSize,
+ mBuffer->size() - frameSize);
+
+ mBuffer->setRange(0, mBuffer->size() - frameSize);
+
+ int64_t timeUs = fetchTimestamp(frameSize);
+ CHECK_GE(timeUs, 0ll);
+
+ accessUnit->meta()->setInt64("timeUs", timeUs);
+
+ if (mFormat == NULL) {
+ mFormat = new MetaData;
+ mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
+ mFormat->setInt32(kKeySampleRate, samplingRate);
+ mFormat->setInt32(kKeyChannelCount, numChannels);
+ }
+
+ return accessUnit;
+}
+
+static void EncodeSize14(uint8_t **_ptr, size_t size) {
+ CHECK_LE(size, 0x3fff);
+
+ uint8_t *ptr = *_ptr;
+
+ *ptr++ = 0x80 | (size >> 7);
+ *ptr++ = size & 0x7f;
+
+ *_ptr = ptr;
+}
+
+static sp<ABuffer> MakeMPEGVideoESDS(const sp<ABuffer> &csd) {
+ sp<ABuffer> esds = new ABuffer(csd->size() + 25);
+
+ uint8_t *ptr = esds->data();
+ *ptr++ = 0x03;
+ EncodeSize14(&ptr, 22 + csd->size());
+
+ *ptr++ = 0x00; // ES_ID
+ *ptr++ = 0x00;
+
+ *ptr++ = 0x00; // streamDependenceFlag, URL_Flag, OCRstreamFlag
+
+ *ptr++ = 0x04;
+ EncodeSize14(&ptr, 16 + csd->size());
+
+ *ptr++ = 0x40; // Audio ISO/IEC 14496-3
+
+ for (size_t i = 0; i < 12; ++i) {
+ *ptr++ = 0x00;
+ }
+
+ *ptr++ = 0x05;
+ EncodeSize14(&ptr, csd->size());
+
+ memcpy(ptr, csd->data(), csd->size());
+
+ return esds;
+}
+
+sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEGVideo() {
+ const uint8_t *data = mBuffer->data();
+ size_t size = mBuffer->size();
+
+ bool sawPictureStart = false;
+ int pprevStartCode = -1;
+ int prevStartCode = -1;
+ int currentStartCode = -1;
+
+ size_t offset = 0;
+ while (offset + 3 < size) {
+ if (memcmp(&data[offset], "\x00\x00\x01", 3)) {
+ ++offset;
+ continue;
+ }
+
+ pprevStartCode = prevStartCode;
+ prevStartCode = currentStartCode;
+ currentStartCode = data[offset + 3];
+
+ if (currentStartCode == 0xb3 && mFormat == NULL) {
+ memmove(mBuffer->data(), mBuffer->data() + offset, size - offset);
+ size -= offset;
+ (void)fetchTimestamp(offset);
+ offset = 0;
+ mBuffer->setRange(0, size);
+ }
+
+ if ((prevStartCode == 0xb3 && currentStartCode != 0xb5)
+ || (pprevStartCode == 0xb3 && prevStartCode == 0xb5)) {
+ // seqHeader without/with extension
+
+ if (mFormat == NULL) {
+ CHECK_GE(size, 7u);
+
+ unsigned width =
+ (data[4] << 4) | data[5] >> 4;
+
+ unsigned height =
+ ((data[5] & 0x0f) << 8) | data[6];
+
+ mFormat = new MetaData;
+ mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG2);
+ mFormat->setInt32(kKeyWidth, width);
+ mFormat->setInt32(kKeyHeight, height);
+
+ LOGI("found MPEG2 video codec config (%d x %d)", width, height);
+
+ sp<ABuffer> csd = new ABuffer(offset);
+ memcpy(csd->data(), data, offset);
+
+ memmove(mBuffer->data(),
+ mBuffer->data() + offset,
+ mBuffer->size() - offset);
+
+ mBuffer->setRange(0, mBuffer->size() - offset);
+ size -= offset;
+ (void)fetchTimestamp(offset);
+ offset = 0;
+
+ // hexdump(csd->data(), csd->size());
+
+ sp<ABuffer> esds = MakeMPEGVideoESDS(csd);
+ mFormat->setData(
+ kKeyESDS, kTypeESDS, esds->data(), esds->size());
+
+ return NULL;
+ }
+ }
+
+ if (mFormat != NULL && currentStartCode == 0x00) {
+ // Picture start
+
+ if (!sawPictureStart) {
+ sawPictureStart = true;
+ } else {
+ sp<ABuffer> accessUnit = new ABuffer(offset);
+ memcpy(accessUnit->data(), data, offset);
+
+ memmove(mBuffer->data(),
+ mBuffer->data() + offset,
+ mBuffer->size() - offset);
+
+ mBuffer->setRange(0, mBuffer->size() - offset);
+
+ int64_t timeUs = fetchTimestamp(offset);
+ CHECK_GE(timeUs, 0ll);
+
+ offset = 0;
+
+ accessUnit->meta()->setInt64("timeUs", timeUs);
+
+ LOGV("returning MPEG video access unit at time %lld us",
+ timeUs);
+
+ // hexdump(accessUnit->data(), accessUnit->size());
+
+ return accessUnit;
+ }
+ }
+
+ ++offset;
+ }
+
+ return NULL;
+}
+
+static ssize_t getNextChunkSize(
+ const uint8_t *data, size_t size) {
+ static const char kStartCode[] = "\x00\x00\x01";
+
+ if (size < 3) {
+ return -EAGAIN;
+ }
+
+ if (memcmp(kStartCode, data, 3)) {
+ TRESPASS();
+ }
+
+ size_t offset = 3;
+ while (offset + 2 < size) {
+ if (!memcmp(&data[offset], kStartCode, 3)) {
+ return offset;
+ }
+
+ ++offset;
+ }
+
+ return -EAGAIN;
+}
+
+sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEG4Video() {
+ uint8_t *data = mBuffer->data();
+ size_t size = mBuffer->size();
+
+ enum {
+ SKIP_TO_VISUAL_OBJECT_SEQ_START,
+ EXPECT_VISUAL_OBJECT_START,
+ EXPECT_VO_START,
+ EXPECT_VOL_START,
+ WAIT_FOR_VOP_START,
+ SKIP_TO_VOP_START,
+
+ } state;
+
+ if (mFormat == NULL) {
+ state = SKIP_TO_VISUAL_OBJECT_SEQ_START;
+ } else {
+ state = SKIP_TO_VOP_START;
+ }
+
+ int32_t width = -1, height = -1;
+
+ size_t offset = 0;
+ ssize_t chunkSize;
+ while ((chunkSize = getNextChunkSize(
+ &data[offset], size - offset)) > 0) {
+ bool discard = false;
+
+ unsigned chunkType = data[offset + 3];
+
+ switch (state) {
+ case SKIP_TO_VISUAL_OBJECT_SEQ_START:
+ {
+ if (chunkType == 0xb0) {
+ // Discard anything before this marker.
+
+ state = EXPECT_VISUAL_OBJECT_START;
+ } else {
+ discard = true;
+ }
+ break;
+ }
+
+ case EXPECT_VISUAL_OBJECT_START:
+ {
+ CHECK_EQ(chunkType, 0xb5);
+ state = EXPECT_VO_START;
+ break;
+ }
+
+ case EXPECT_VO_START:
+ {
+ CHECK_LE(chunkType, 0x1f);
+ state = EXPECT_VOL_START;
+ break;
+ }
+
+ case EXPECT_VOL_START:
+ {
+ CHECK((chunkType & 0xf0) == 0x20);
+
+ CHECK(ExtractDimensionsFromVOLHeader(
+ &data[offset], chunkSize,
+ &width, &height));
+
+ state = WAIT_FOR_VOP_START;
+ break;
+ }
+
+ case WAIT_FOR_VOP_START:
+ {
+ if (chunkType == 0xb3 || chunkType == 0xb6) {
+ // group of VOP or VOP start.
+
+ mFormat = new MetaData;
+ mFormat->setCString(
+ kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
+
+ mFormat->setInt32(kKeyWidth, width);
+ mFormat->setInt32(kKeyHeight, height);
+
+ LOGI("found MPEG4 video codec config (%d x %d)",
+ width, height);
+
+ sp<ABuffer> csd = new ABuffer(offset);
+ memcpy(csd->data(), data, offset);
+
+ // hexdump(csd->data(), csd->size());
+
+ sp<ABuffer> esds = MakeMPEGVideoESDS(csd);
+ mFormat->setData(
+ kKeyESDS, kTypeESDS,
+ esds->data(), esds->size());
+
+ discard = true;
+ state = SKIP_TO_VOP_START;
+ }
+
+ break;
+ }
+
+ case SKIP_TO_VOP_START:
+ {
+ if (chunkType == 0xb6) {
+ offset += chunkSize;
+
+ sp<ABuffer> accessUnit = new ABuffer(offset);
+ memcpy(accessUnit->data(), data, offset);
+
+ memmove(data, &data[offset], size - offset);
+ size -= offset;
+ mBuffer->setRange(0, size);
+
+ int64_t timeUs = fetchTimestamp(offset);
+ CHECK_GE(timeUs, 0ll);
+
+ offset = 0;
+
+ accessUnit->meta()->setInt64("timeUs", timeUs);
+
+ LOGV("returning MPEG4 video access unit at time %lld us",
+ timeUs);
+
+ // hexdump(accessUnit->data(), accessUnit->size());
+
+ return accessUnit;
+ } else if (chunkType != 0xb3) {
+ offset += chunkSize;
+ discard = true;
+ }
+
+ break;
+ }
+
+ default:
+ TRESPASS();
+ }
+
+ if (discard) {
+ (void)fetchTimestamp(offset);
+ memmove(data, &data[offset], size - offset);
+ size -= offset;
+ offset = 0;
+ mBuffer->setRange(0, size);
+ } else {
+ offset += chunkSize;
+ }
+ }
+
+ return NULL;
+}
+
} // namespace android
diff --git a/media/libstagefright/mpeg2ts/ESQueue.h b/media/libstagefright/mpeg2ts/ESQueue.h
index 153cfe6..4035ed3 100644
--- a/media/libstagefright/mpeg2ts/ESQueue.h
+++ b/media/libstagefright/mpeg2ts/ESQueue.h
@@ -31,7 +31,10 @@
struct ElementaryStreamQueue {
enum Mode {
H264,
- AAC
+ AAC,
+ MPEG_AUDIO,
+ MPEG_VIDEO,
+ MPEG4_VIDEO,
};
ElementaryStreamQueue(Mode mode);
@@ -57,6 +60,9 @@
sp<ABuffer> dequeueAccessUnitH264();
sp<ABuffer> dequeueAccessUnitAAC();
+ sp<ABuffer> dequeueAccessUnitMPEGAudio();
+ sp<ABuffer> dequeueAccessUnitMPEGVideo();
+ sp<ABuffer> dequeueAccessUnitMPEG4Video();
// consume a logical (compressed) access unit of size "size",
// returns its timestamp in us (or -1 if no time information).
diff --git a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
index dfec47f..8250ad1 100644
--- a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
+++ b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
@@ -175,7 +175,7 @@
if (!haveVideo) {
sp<AnotherPacketSource> impl =
(AnotherPacketSource *)mParser->getSource(
- ATSParser::AVC_VIDEO).get();
+ ATSParser::VIDEO).get();
if (impl != NULL) {
haveVideo = true;
@@ -186,7 +186,7 @@
if (!haveAudio) {
sp<AnotherPacketSource> impl =
(AnotherPacketSource *)mParser->getSource(
- ATSParser::MPEG2ADTS_AUDIO).get();
+ ATSParser::AUDIO).get();
if (impl != NULL) {
haveAudio = true;
@@ -194,7 +194,7 @@
}
}
- if (++numPacketsParsed > 2500) {
+ if (++numPacketsParsed > 10000) {
break;
}
}
diff --git a/media/libstagefright/omx/Android.mk b/media/libstagefright/omx/Android.mk
index 6e069c8..d844f3d 100644
--- a/media/libstagefright/omx/Android.mk
+++ b/media/libstagefright/omx/Android.mk
@@ -1,53 +1,34 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
-ifneq ($(BUILD_WITHOUT_PV),true)
-# Set up the OpenCore variables.
-include external/opencore/Config.mk
-LOCAL_C_INCLUDES := $(PV_INCLUDES)
-LOCAL_CFLAGS := $(PV_CFLAGS_MINUS_VISIBILITY)
-endif
-
LOCAL_C_INCLUDES += $(JNI_H_INCLUDE)
LOCAL_SRC_FILES:= \
- OMX.cpp \
+ OMX.cpp \
OMXComponentBase.cpp \
+ OMXMaster.cpp \
OMXNodeInstance.cpp \
- OMXMaster.cpp
+ SimpleSoftOMXComponent.cpp \
+ SoftOMXComponent.cpp \
+ SoftOMXPlugin.cpp \
-ifneq ($(BUILD_WITHOUT_PV),true)
-LOCAL_SRC_FILES += \
- OMXPVCodecsPlugin.cpp
-else
-LOCAL_CFLAGS += -DNO_OPENCORE
-endif
+LOCAL_C_INCLUDES += \
+ frameworks/base/media/libstagefright \
+ $(TOP)/frameworks/base/include/media/stagefright/openmax
-LOCAL_C_INCLUDES += $(TOP)/frameworks/base/include/media/stagefright/openmax
-
-LOCAL_SHARED_LIBRARIES := \
- libbinder \
- libmedia \
- libutils \
- libui \
- libcutils \
-
-ifneq ($(BUILD_WITHOUT_PV),true)
-LOCAL_SHARED_LIBRARIES += \
- libopencore_common
-endif
-
-ifeq ($(TARGET_OS)-$(TARGET_SIMULATOR),linux-true)
- LOCAL_LDLIBS += -lpthread -ldl
-endif
-
-ifneq ($(TARGET_SIMULATOR),true)
-LOCAL_SHARED_LIBRARIES += libdl
-endif
+LOCAL_SHARED_LIBRARIES := \
+ libbinder \
+ libmedia \
+ libutils \
+ libui \
+ libcutils \
+ libstagefright_foundation \
+ libdl
LOCAL_MODULE:= libstagefright_omx
include $(BUILD_SHARED_LIBRARY)
-include $(call all-makefiles-under,$(LOCAL_PATH))
+################################################################################
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index 4b1c3a7..bc24dbb 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -20,9 +20,6 @@
#include <dlfcn.h>
-#include <sys/prctl.h>
-#include <sys/resource.h>
-
#include "../include/OMX.h"
#include "../include/OMXNodeInstance.h"
@@ -39,11 +36,32 @@
////////////////////////////////////////////////////////////////////////////////
+// This provides the underlying Thread used by CallbackDispatcher.
+// Note that deriving CallbackDispatcher from Thread does not work.
+
+struct OMX::CallbackDispatcherThread : public Thread {
+ CallbackDispatcherThread(CallbackDispatcher *dispatcher)
+ : mDispatcher(dispatcher) {
+ }
+
+private:
+ CallbackDispatcher *mDispatcher;
+
+ bool threadLoop();
+
+ CallbackDispatcherThread(const CallbackDispatcherThread &);
+ CallbackDispatcherThread &operator=(const CallbackDispatcherThread &);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
struct OMX::CallbackDispatcher : public RefBase {
CallbackDispatcher(OMXNodeInstance *owner);
void post(const omx_message &msg);
+ bool loop();
+
protected:
virtual ~CallbackDispatcher();
@@ -55,13 +73,10 @@
Condition mQueueChanged;
List<omx_message> mQueue;
- pthread_t mThread;
+ sp<CallbackDispatcherThread> mThread;
void dispatch(const omx_message &msg);
- static void *ThreadWrapper(void *me);
- void threadEntry();
-
CallbackDispatcher(const CallbackDispatcher &);
CallbackDispatcher &operator=(const CallbackDispatcher &);
};
@@ -69,13 +84,8 @@
OMX::CallbackDispatcher::CallbackDispatcher(OMXNodeInstance *owner)
: mOwner(owner),
mDone(false) {
- pthread_attr_t attr;
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-
- pthread_create(&mThread, &attr, ThreadWrapper, this);
-
- pthread_attr_destroy(&attr);
+ mThread = new CallbackDispatcherThread(this);
+ mThread->run("OMXCallbackDisp", ANDROID_PRIORITY_AUDIO);
}
OMX::CallbackDispatcher::~CallbackDispatcher() {
@@ -86,11 +96,14 @@
mQueueChanged.signal();
}
- // Don't call join on myself
- CHECK(mThread != pthread_self());
-
- void *dummy;
- pthread_join(mThread, &dummy);
+ // A join on self can happen if the last ref to CallbackDispatcher
+ // is released within the CallbackDispatcherThread loop
+ status_t status = mThread->join();
+ if (status != WOULD_BLOCK) {
+ // Other than join to self, the only other error return codes are
+ // whatever readyToRun() returns, and we don't override that
+ CHECK_EQ(status, NO_ERROR);
+ }
}
void OMX::CallbackDispatcher::post(const omx_message &msg) {
@@ -108,17 +121,7 @@
mOwner->onMessage(msg);
}
-// static
-void *OMX::CallbackDispatcher::ThreadWrapper(void *me) {
- static_cast<CallbackDispatcher *>(me)->threadEntry();
-
- return NULL;
-}
-
-void OMX::CallbackDispatcher::threadEntry() {
- setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_AUDIO);
- prctl(PR_SET_NAME, (unsigned long)"OMXCallbackDisp", 0, 0, 0);
-
+bool OMX::CallbackDispatcher::loop() {
for (;;) {
omx_message msg;
@@ -138,6 +141,14 @@
dispatch(msg);
}
+
+ return false;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+bool OMX::CallbackDispatcherThread::threadLoop() {
+ return mDispatcher->loop();
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/media/libstagefright/omx/OMXMaster.cpp b/media/libstagefright/omx/OMXMaster.cpp
index 56b169a..c8278ab 100644
--- a/media/libstagefright/omx/OMXMaster.cpp
+++ b/media/libstagefright/omx/OMXMaster.cpp
@@ -20,23 +20,18 @@
#include "OMXMaster.h"
+#include "SoftOMXPlugin.h"
+
#include <dlfcn.h>
#include <media/stagefright/MediaDebug.h>
-#ifndef NO_OPENCORE
-#include "OMXPVCodecsPlugin.h"
-#endif
-
namespace android {
OMXMaster::OMXMaster()
: mVendorLibHandle(NULL) {
addVendorPlugin();
-
-#ifndef NO_OPENCORE
- addPlugin(new OMXPVCodecsPlugin);
-#endif
+ addPlugin(new SoftOMXPlugin);
}
OMXMaster::~OMXMaster() {
@@ -49,7 +44,11 @@
}
void OMXMaster::addVendorPlugin() {
- mVendorLibHandle = dlopen("libstagefrighthw.so", RTLD_NOW);
+ addPlugin("libstagefrighthw.so");
+}
+
+void OMXMaster::addPlugin(const char *libname) {
+ mVendorLibHandle = dlopen(libname, RTLD_NOW);
if (mVendorLibHandle == NULL) {
return;
@@ -58,6 +57,9 @@
typedef OMXPluginBase *(*CreateOMXPluginFunc)();
CreateOMXPluginFunc createOMXPlugin =
(CreateOMXPluginFunc)dlsym(
+ mVendorLibHandle, "createOMXPlugin");
+ if (!createOMXPlugin)
+ createOMXPlugin = (CreateOMXPluginFunc)dlsym(
mVendorLibHandle, "_ZN7android15createOMXPluginEv");
if (createOMXPlugin) {
@@ -87,17 +89,29 @@
mPluginByComponentName.add(name8, plugin);
}
- CHECK_EQ(err, OMX_ErrorNoMore);
+
+ if (err != OMX_ErrorNoMore) {
+ LOGE("OMX plugin failed w/ error 0x%08x after registering %d "
+ "components", err, mPluginByComponentName.size());
+ }
}
void OMXMaster::clearPlugins() {
Mutex::Autolock autoLock(mLock);
+ typedef void (*DestroyOMXPluginFunc)(OMXPluginBase*);
+ DestroyOMXPluginFunc destroyOMXPlugin =
+ (DestroyOMXPluginFunc)dlsym(
+ mVendorLibHandle, "destroyOMXPlugin");
+
mPluginByComponentName.clear();
for (List<OMXPluginBase *>::iterator it = mPlugins.begin();
- it != mPlugins.end(); ++it) {
- delete *it;
+ it != mPlugins.end(); ++it) {
+ if (destroyOMXPlugin)
+ destroyOMXPlugin(*it);
+ else
+ delete *it;
*it = NULL;
}
diff --git a/media/libstagefright/omx/OMXMaster.h b/media/libstagefright/omx/OMXMaster.h
index 7ba8d18..feee1f9 100644
--- a/media/libstagefright/omx/OMXMaster.h
+++ b/media/libstagefright/omx/OMXMaster.h
@@ -58,6 +58,7 @@
void *mVendorLibHandle;
void addVendorPlugin();
+ void addPlugin(const char *libname);
void addPlugin(OMXPluginBase *plugin);
void clearPlugins();
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index 6cbd599..12ab941 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#define LOG_NDEBUG 0
+//#define LOG_NDEBUG 0
#define LOG_TAG "OMXNodeInstance"
#include <utils/Log.h>
@@ -234,6 +234,7 @@
Mutex::Autolock autoLock(mLock);
OMX_ERRORTYPE err = OMX_GetParameter(mHandle, index, params);
+
return StatusFromOMXError(err);
}
@@ -405,12 +406,77 @@
return OK;
}
+status_t OMXNodeInstance::useGraphicBuffer2_l(
+ OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer,
+ OMX::buffer_id *buffer) {
+
+ // port definition
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ def.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
+ def.nVersion.s.nVersionMajor = 1;
+ def.nVersion.s.nVersionMinor = 0;
+ def.nVersion.s.nRevision = 0;
+ def.nVersion.s.nStep = 0;
+ def.nPortIndex = portIndex;
+ OMX_ERRORTYPE err = OMX_GetParameter(mHandle, OMX_IndexParamPortDefinition, &def);
+ if (err != OK)
+ {
+ LOGE("%s::%d:Error getting OMX_IndexParamPortDefinition", __FUNCTION__, __LINE__);
+ return err;
+ }
+
+ BufferMeta *bufferMeta = new BufferMeta(graphicBuffer);
+
+ OMX_BUFFERHEADERTYPE *header = NULL;
+ OMX_U8* bufferHandle = const_cast<OMX_U8*>(
+ reinterpret_cast<const OMX_U8*>(graphicBuffer->handle));
+
+ err = OMX_UseBuffer(
+ mHandle,
+ &header,
+ portIndex,
+ bufferMeta,
+ def.nBufferSize,
+ bufferHandle);
+
+ if (err != OMX_ErrorNone) {
+ LOGE("OMX_UseBuffer failed with error %d (0x%08x)", err, err);
+ delete bufferMeta;
+ bufferMeta = NULL;
+ *buffer = 0;
+ return UNKNOWN_ERROR;
+ }
+
+ CHECK_EQ(header->pBuffer, bufferHandle);
+ CHECK_EQ(header->pAppPrivate, bufferMeta);
+
+ *buffer = header;
+
+ addActiveBuffer(portIndex, *buffer);
+
+ return OK;
+}
+
+// XXX: This function is here for backwards compatibility. Once the OMX
+// implementations have been updated this can be removed and useGraphicBuffer2
+// can be renamed to useGraphicBuffer.
status_t OMXNodeInstance::useGraphicBuffer(
OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer,
OMX::buffer_id *buffer) {
Mutex::Autolock autoLock(mLock);
+ // See if the newer version of the extension is present.
OMX_INDEXTYPE index;
+ if (OMX_GetExtensionIndex(
+ mHandle,
+ const_cast<OMX_STRING>("OMX.google.android.index.useAndroidNativeBuffer2"),
+ &index) == OMX_ErrorNone) {
+ return useGraphicBuffer2_l(portIndex, graphicBuffer, buffer);
+ }
+
+ LOGW("Falling back to the deprecated useAndroidNativeBuffer support. You "
+ "should switch to the useAndroidNativeBuffer2 extension.");
+
OMX_ERRORTYPE err = OMX_GetExtensionIndex(
mHandle,
const_cast<OMX_STRING>("OMX.google.android.index.useAndroidNativeBuffer"),
diff --git a/media/libstagefright/omx/OMXPVCodecsPlugin.cpp b/media/libstagefright/omx/OMXPVCodecsPlugin.cpp
deleted file mode 100644
index d1f5be3..0000000
--- a/media/libstagefright/omx/OMXPVCodecsPlugin.cpp
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * 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.
- */
-
-#include "OMXPVCodecsPlugin.h"
-
-#include "pv_omxcore.h"
-
-#include <media/stagefright/MediaDebug.h>
-
-namespace android {
-
-OMXPVCodecsPlugin::OMXPVCodecsPlugin() {
- OMX_MasterInit();
-}
-
-OMXPVCodecsPlugin::~OMXPVCodecsPlugin() {
- OMX_MasterDeinit();
-}
-
-OMX_ERRORTYPE OMXPVCodecsPlugin::makeComponentInstance(
- const char *name,
- const OMX_CALLBACKTYPE *callbacks,
- OMX_PTR appData,
- OMX_COMPONENTTYPE **component) {
- return OMX_MasterGetHandle(
- reinterpret_cast<OMX_HANDLETYPE *>(component),
- const_cast<char *>(name),
- appData,
- const_cast<OMX_CALLBACKTYPE *>(callbacks));
-}
-
-OMX_ERRORTYPE OMXPVCodecsPlugin::destroyComponentInstance(
- OMX_COMPONENTTYPE *component) {
- return OMX_MasterFreeHandle(component);
-}
-
-OMX_ERRORTYPE OMXPVCodecsPlugin::enumerateComponents(
- OMX_STRING name,
- size_t size,
- OMX_U32 index) {
- return OMX_MasterComponentNameEnum(name, size, index);
-}
-
-OMX_ERRORTYPE OMXPVCodecsPlugin::getRolesOfComponent(
- const char *name,
- Vector<String8> *roles) {
- roles->clear();
-
- OMX_U32 numRoles;
- OMX_ERRORTYPE err =
- OMX_MasterGetRolesOfComponent(
- const_cast<char *>(name),
- &numRoles,
- NULL);
-
- if (err != OMX_ErrorNone) {
- return err;
- }
-
- if (numRoles > 0) {
- OMX_U8 **array = new OMX_U8 *[numRoles];
- for (OMX_U32 i = 0; i < numRoles; ++i) {
- array[i] = new OMX_U8[OMX_MAX_STRINGNAME_SIZE];
- }
-
- OMX_U32 numRoles2;
- err = OMX_MasterGetRolesOfComponent(
- const_cast<char *>(name), &numRoles2, array);
-
- CHECK_EQ(err, OMX_ErrorNone);
- CHECK_EQ(numRoles, numRoles2);
-
- for (OMX_U32 i = 0; i < numRoles; ++i) {
- String8 s((const char *)array[i]);
- roles->push(s);
-
- delete[] array[i];
- array[i] = NULL;
- }
-
- delete[] array;
- array = NULL;
- }
-
- return OMX_ErrorNone;
-}
-
-} // namespace android
diff --git a/media/libstagefright/omx/OMXPVCodecsPlugin.h b/media/libstagefright/omx/OMXPVCodecsPlugin.h
deleted file mode 100644
index c133232..0000000
--- a/media/libstagefright/omx/OMXPVCodecsPlugin.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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 OMX_PV_CODECS_PLUGIN_H_
-
-#define OMX_PV_CODECS_PLUGIN_H_
-
-#include <media/stagefright/OMXPluginBase.h>
-
-namespace android {
-
-struct OMXPVCodecsPlugin : public OMXPluginBase {
- OMXPVCodecsPlugin();
- virtual ~OMXPVCodecsPlugin();
-
- virtual OMX_ERRORTYPE makeComponentInstance(
- const char *name,
- const OMX_CALLBACKTYPE *callbacks,
- OMX_PTR appData,
- OMX_COMPONENTTYPE **component);
-
- virtual OMX_ERRORTYPE destroyComponentInstance(
- OMX_COMPONENTTYPE *component);
-
- virtual OMX_ERRORTYPE enumerateComponents(
- OMX_STRING name,
- size_t size,
- OMX_U32 index);
-
- virtual OMX_ERRORTYPE getRolesOfComponent(
- const char *name,
- Vector<String8> *roles);
-
-private:
- OMXPVCodecsPlugin(const OMXPVCodecsPlugin &);
- OMXPVCodecsPlugin &operator=(const OMXPVCodecsPlugin &);
-};
-
-} // namespace android
-
-#endif // OMX_PV_CODECS_PLUGIN_H_
diff --git a/media/libstagefright/omx/SimpleSoftOMXComponent.cpp b/media/libstagefright/omx/SimpleSoftOMXComponent.cpp
new file mode 100644
index 0000000..f7330f3
--- /dev/null
+++ b/media/libstagefright/omx/SimpleSoftOMXComponent.cpp
@@ -0,0 +1,644 @@
+/*
+ * Copyright (C) 2011 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 "SimpleSoftOMXComponent"
+#include <utils/Log.h>
+
+#include "include/SimpleSoftOMXComponent.h"
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/ALooper.h>
+#include <media/stagefright/foundation/AMessage.h>
+
+namespace android {
+
+SimpleSoftOMXComponent::SimpleSoftOMXComponent(
+ const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component)
+ : SoftOMXComponent(name, callbacks, appData, component),
+ mLooper(new ALooper),
+ mHandler(new AHandlerReflector<SimpleSoftOMXComponent>(this)),
+ mState(OMX_StateLoaded),
+ mTargetState(OMX_StateLoaded) {
+ mLooper->setName(name);
+ mLooper->registerHandler(mHandler);
+
+ mLooper->start(
+ false, // runOnCallingThread
+ false, // canCallJava
+ PRIORITY_AUDIO);
+}
+
+void SimpleSoftOMXComponent::prepareForDestruction() {
+ // The looper's queue may still contain messages referencing this
+ // object. Make sure those are flushed before returning so that
+ // a subsequent dlunload() does not pull out the rug from under us.
+
+ mLooper->unregisterHandler(mHandler->id());
+ mLooper->stop();
+}
+
+OMX_ERRORTYPE SimpleSoftOMXComponent::sendCommand(
+ OMX_COMMANDTYPE cmd, OMX_U32 param, OMX_PTR data) {
+ CHECK(data == NULL);
+
+ sp<AMessage> msg = new AMessage(kWhatSendCommand, mHandler->id());
+ msg->setInt32("cmd", cmd);
+ msg->setInt32("param", param);
+ msg->post();
+
+ return OMX_ErrorNone;
+}
+
+bool SimpleSoftOMXComponent::isSetParameterAllowed(
+ OMX_INDEXTYPE index, const OMX_PTR params) const {
+ if (mState == OMX_StateLoaded) {
+ return true;
+ }
+
+ OMX_U32 portIndex;
+
+ switch (index) {
+ case OMX_IndexParamPortDefinition:
+ {
+ portIndex = ((OMX_PARAM_PORTDEFINITIONTYPE *)params)->nPortIndex;
+ break;
+ }
+
+ case OMX_IndexParamAudioPcm:
+ {
+ portIndex = ((OMX_AUDIO_PARAM_PCMMODETYPE *)params)->nPortIndex;
+ break;
+ }
+
+ case OMX_IndexParamAudioAac:
+ {
+ portIndex = ((OMX_AUDIO_PARAM_AACPROFILETYPE *)params)->nPortIndex;
+ break;
+ }
+
+ default:
+ return false;
+ }
+
+ CHECK(portIndex < mPorts.size());
+
+ return !mPorts.itemAt(portIndex).mDef.bEnabled;
+}
+
+OMX_ERRORTYPE SimpleSoftOMXComponent::getParameter(
+ OMX_INDEXTYPE index, OMX_PTR params) {
+ Mutex::Autolock autoLock(mLock);
+ return internalGetParameter(index, params);
+}
+
+OMX_ERRORTYPE SimpleSoftOMXComponent::setParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params) {
+ Mutex::Autolock autoLock(mLock);
+
+ CHECK(isSetParameterAllowed(index, params));
+
+ return internalSetParameter(index, params);
+}
+
+OMX_ERRORTYPE SimpleSoftOMXComponent::internalGetParameter(
+ OMX_INDEXTYPE index, OMX_PTR params) {
+ switch (index) {
+ case OMX_IndexParamPortDefinition:
+ {
+ OMX_PARAM_PORTDEFINITIONTYPE *defParams =
+ (OMX_PARAM_PORTDEFINITIONTYPE *)params;
+
+ if (defParams->nPortIndex >= mPorts.size()
+ || defParams->nSize
+ != sizeof(OMX_PARAM_PORTDEFINITIONTYPE)) {
+ return OMX_ErrorUndefined;
+ }
+
+ const PortInfo *port =
+ &mPorts.itemAt(defParams->nPortIndex);
+
+ memcpy(defParams, &port->mDef, sizeof(port->mDef));
+
+ return OMX_ErrorNone;
+ }
+
+ default:
+ return OMX_ErrorUnsupportedIndex;
+ }
+}
+
+OMX_ERRORTYPE SimpleSoftOMXComponent::internalSetParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params) {
+ switch (index) {
+ case OMX_IndexParamPortDefinition:
+ {
+ OMX_PARAM_PORTDEFINITIONTYPE *defParams =
+ (OMX_PARAM_PORTDEFINITIONTYPE *)params;
+
+ if (defParams->nPortIndex >= mPorts.size()
+ || defParams->nSize
+ != sizeof(OMX_PARAM_PORTDEFINITIONTYPE)) {
+ return OMX_ErrorUndefined;
+ }
+
+ PortInfo *port =
+ &mPorts.editItemAt(defParams->nPortIndex);
+
+ if (defParams->nBufferSize != port->mDef.nBufferSize) {
+ CHECK_GE(defParams->nBufferSize, port->mDef.nBufferSize);
+ port->mDef.nBufferSize = defParams->nBufferSize;
+ }
+
+ if (defParams->nBufferCountActual
+ != port->mDef.nBufferCountActual) {
+ CHECK_GE(defParams->nBufferCountActual,
+ port->mDef.nBufferCountMin);
+
+ port->mDef.nBufferCountActual = defParams->nBufferCountActual;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ default:
+ return OMX_ErrorUnsupportedIndex;
+ }
+}
+
+OMX_ERRORTYPE SimpleSoftOMXComponent::useBuffer(
+ OMX_BUFFERHEADERTYPE **header,
+ OMX_U32 portIndex,
+ OMX_PTR appPrivate,
+ OMX_U32 size,
+ OMX_U8 *ptr) {
+ Mutex::Autolock autoLock(mLock);
+ CHECK_LT(portIndex, mPorts.size());
+
+ *header = new OMX_BUFFERHEADERTYPE;
+ (*header)->nSize = sizeof(OMX_BUFFERHEADERTYPE);
+ (*header)->nVersion.s.nVersionMajor = 1;
+ (*header)->nVersion.s.nVersionMinor = 0;
+ (*header)->nVersion.s.nRevision = 0;
+ (*header)->nVersion.s.nStep = 0;
+ (*header)->pBuffer = ptr;
+ (*header)->nAllocLen = size;
+ (*header)->nFilledLen = 0;
+ (*header)->nOffset = 0;
+ (*header)->pAppPrivate = appPrivate;
+ (*header)->pPlatformPrivate = NULL;
+ (*header)->pInputPortPrivate = NULL;
+ (*header)->pOutputPortPrivate = NULL;
+ (*header)->hMarkTargetComponent = NULL;
+ (*header)->pMarkData = NULL;
+ (*header)->nTickCount = 0;
+ (*header)->nTimeStamp = 0;
+ (*header)->nFlags = 0;
+ (*header)->nOutputPortIndex = portIndex;
+ (*header)->nInputPortIndex = portIndex;
+
+ PortInfo *port = &mPorts.editItemAt(portIndex);
+
+ CHECK(mState == OMX_StateLoaded || port->mDef.bEnabled == OMX_FALSE);
+
+ CHECK_LT(port->mBuffers.size(), port->mDef.nBufferCountActual);
+
+ port->mBuffers.push();
+
+ BufferInfo *buffer =
+ &port->mBuffers.editItemAt(port->mBuffers.size() - 1);
+
+ buffer->mHeader = *header;
+ buffer->mOwnedByUs = false;
+
+ if (port->mBuffers.size() == port->mDef.nBufferCountActual) {
+ port->mDef.bPopulated = OMX_TRUE;
+ checkTransitions();
+ }
+
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE SimpleSoftOMXComponent::allocateBuffer(
+ OMX_BUFFERHEADERTYPE **header,
+ OMX_U32 portIndex,
+ OMX_PTR appPrivate,
+ OMX_U32 size) {
+ OMX_U8 *ptr = new OMX_U8[size];
+
+ OMX_ERRORTYPE err =
+ useBuffer(header, portIndex, appPrivate, size, ptr);
+
+ if (err != OMX_ErrorNone) {
+ delete[] ptr;
+ ptr = NULL;
+
+ return err;
+ }
+
+ CHECK((*header)->pPlatformPrivate == NULL);
+ (*header)->pPlatformPrivate = ptr;
+
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE SimpleSoftOMXComponent::freeBuffer(
+ OMX_U32 portIndex,
+ OMX_BUFFERHEADERTYPE *header) {
+ Mutex::Autolock autoLock(mLock);
+
+ CHECK_LT(portIndex, mPorts.size());
+
+ PortInfo *port = &mPorts.editItemAt(portIndex);
+
+#if 0 // XXX
+ CHECK((mState == OMX_StateIdle && mTargetState == OMX_StateLoaded)
+ || port->mDef.bEnabled == OMX_FALSE);
+#endif
+
+ bool found = false;
+ for (size_t i = 0; i < port->mBuffers.size(); ++i) {
+ BufferInfo *buffer = &port->mBuffers.editItemAt(i);
+
+ if (buffer->mHeader == header) {
+ CHECK(!buffer->mOwnedByUs);
+
+ if (header->pPlatformPrivate != NULL) {
+ // This buffer's data was allocated by us.
+ CHECK(header->pPlatformPrivate == header->pBuffer);
+
+ delete[] header->pBuffer;
+ header->pBuffer = NULL;
+ }
+
+ delete header;
+ header = NULL;
+
+ port->mBuffers.removeAt(i);
+ port->mDef.bPopulated = OMX_FALSE;
+
+ checkTransitions();
+
+ found = true;
+ break;
+ }
+ }
+
+ CHECK(found);
+
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE SimpleSoftOMXComponent::emptyThisBuffer(
+ OMX_BUFFERHEADERTYPE *buffer) {
+ sp<AMessage> msg = new AMessage(kWhatEmptyThisBuffer, mHandler->id());
+ msg->setPointer("header", buffer);
+ msg->post();
+
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE SimpleSoftOMXComponent::fillThisBuffer(
+ OMX_BUFFERHEADERTYPE *buffer) {
+ sp<AMessage> msg = new AMessage(kWhatFillThisBuffer, mHandler->id());
+ msg->setPointer("header", buffer);
+ msg->post();
+
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE SimpleSoftOMXComponent::getState(OMX_STATETYPE *state) {
+ Mutex::Autolock autoLock(mLock);
+
+ *state = mState;
+
+ return OMX_ErrorNone;
+}
+
+void SimpleSoftOMXComponent::onMessageReceived(const sp<AMessage> &msg) {
+ Mutex::Autolock autoLock(mLock);
+
+ switch (msg->what()) {
+ case kWhatSendCommand:
+ {
+ int32_t cmd, param;
+ CHECK(msg->findInt32("cmd", &cmd));
+ CHECK(msg->findInt32("param", ¶m));
+
+ onSendCommand((OMX_COMMANDTYPE)cmd, (OMX_U32)param);
+ break;
+ }
+
+ case kWhatEmptyThisBuffer:
+ case kWhatFillThisBuffer:
+ {
+ OMX_BUFFERHEADERTYPE *header;
+ CHECK(msg->findPointer("header", (void **)&header));
+
+ CHECK(mState == OMX_StateExecuting && mTargetState == mState);
+
+ bool found = false;
+ for (size_t i = 0; i < mPorts.size(); ++i) {
+ PortInfo *port = &mPorts.editItemAt(i);
+
+ for (size_t j = 0; j < port->mBuffers.size(); ++j) {
+ BufferInfo *buffer = &port->mBuffers.editItemAt(j);
+
+ if (buffer->mHeader == header) {
+ CHECK(!buffer->mOwnedByUs);
+
+ buffer->mOwnedByUs = true;
+
+ CHECK((msg->what() == kWhatEmptyThisBuffer
+ && port->mDef.eDir == OMX_DirInput)
+ || (port->mDef.eDir == OMX_DirOutput));
+
+ port->mQueue.push_back(buffer);
+ onQueueFilled(i);
+
+ found = true;
+ break;
+ }
+ }
+ }
+
+ CHECK(found);
+ break;
+ }
+
+ default:
+ TRESPASS();
+ break;
+ }
+}
+
+void SimpleSoftOMXComponent::onSendCommand(
+ OMX_COMMANDTYPE cmd, OMX_U32 param) {
+ switch (cmd) {
+ case OMX_CommandStateSet:
+ {
+ onChangeState((OMX_STATETYPE)param);
+ break;
+ }
+
+ case OMX_CommandPortEnable:
+ case OMX_CommandPortDisable:
+ {
+ onPortEnable(param, cmd == OMX_CommandPortEnable);
+ break;
+ }
+
+ case OMX_CommandFlush:
+ {
+ onPortFlush(param, true /* sendFlushComplete */);
+ break;
+ }
+
+ default:
+ TRESPASS();
+ break;
+ }
+}
+
+void SimpleSoftOMXComponent::onChangeState(OMX_STATETYPE state) {
+ // We shouldn't be in a state transition already.
+ CHECK_EQ((int)mState, (int)mTargetState);
+
+ switch (mState) {
+ case OMX_StateLoaded:
+ CHECK_EQ((int)state, (int)OMX_StateIdle);
+ break;
+ case OMX_StateIdle:
+ CHECK(state == OMX_StateLoaded || state == OMX_StateExecuting);
+ break;
+ case OMX_StateExecuting:
+ {
+ CHECK_EQ((int)state, (int)OMX_StateIdle);
+
+ for (size_t i = 0; i < mPorts.size(); ++i) {
+ onPortFlush(i, false /* sendFlushComplete */);
+ }
+
+ mState = OMX_StateIdle;
+ notify(OMX_EventCmdComplete, OMX_CommandStateSet, state, NULL);
+ break;
+ }
+
+ default:
+ TRESPASS();
+ }
+
+ mTargetState = state;
+
+ checkTransitions();
+}
+
+void SimpleSoftOMXComponent::onPortEnable(OMX_U32 portIndex, bool enable) {
+ CHECK_LT(portIndex, mPorts.size());
+
+ PortInfo *port = &mPorts.editItemAt(portIndex);
+ CHECK_EQ((int)port->mTransition, (int)PortInfo::NONE);
+ CHECK(port->mDef.bEnabled == !enable);
+
+ if (!enable) {
+ port->mDef.bEnabled = OMX_FALSE;
+ port->mTransition = PortInfo::DISABLING;
+
+ for (size_t i = 0; i < port->mBuffers.size(); ++i) {
+ BufferInfo *buffer = &port->mBuffers.editItemAt(i);
+
+ if (buffer->mOwnedByUs) {
+ buffer->mOwnedByUs = false;
+
+ if (port->mDef.eDir == OMX_DirInput) {
+ notifyEmptyBufferDone(buffer->mHeader);
+ } else {
+ CHECK_EQ(port->mDef.eDir, OMX_DirOutput);
+ notifyFillBufferDone(buffer->mHeader);
+ }
+ }
+ }
+
+ port->mQueue.clear();
+ } else {
+ port->mTransition = PortInfo::ENABLING;
+ }
+
+ checkTransitions();
+}
+
+void SimpleSoftOMXComponent::onPortFlush(
+ OMX_U32 portIndex, bool sendFlushComplete) {
+ if (portIndex == OMX_ALL) {
+ for (size_t i = 0; i < mPorts.size(); ++i) {
+ onPortFlush(i, sendFlushComplete);
+ }
+
+ if (sendFlushComplete) {
+ notify(OMX_EventCmdComplete, OMX_CommandFlush, OMX_ALL, NULL);
+ }
+
+ return;
+ }
+
+ CHECK_LT(portIndex, mPorts.size());
+
+ PortInfo *port = &mPorts.editItemAt(portIndex);
+ CHECK_EQ((int)port->mTransition, (int)PortInfo::NONE);
+
+ for (size_t i = 0; i < port->mBuffers.size(); ++i) {
+ BufferInfo *buffer = &port->mBuffers.editItemAt(i);
+
+ if (!buffer->mOwnedByUs) {
+ continue;
+ }
+
+ buffer->mHeader->nFilledLen = 0;
+ buffer->mHeader->nOffset = 0;
+ buffer->mHeader->nFlags = 0;
+
+ buffer->mOwnedByUs = false;
+
+ if (port->mDef.eDir == OMX_DirInput) {
+ notifyEmptyBufferDone(buffer->mHeader);
+ } else {
+ CHECK_EQ(port->mDef.eDir, OMX_DirOutput);
+
+ notifyFillBufferDone(buffer->mHeader);
+ }
+ }
+
+ port->mQueue.clear();
+
+ if (sendFlushComplete) {
+ notify(OMX_EventCmdComplete, OMX_CommandFlush, portIndex, NULL);
+
+ onPortFlushCompleted(portIndex);
+ }
+}
+
+void SimpleSoftOMXComponent::checkTransitions() {
+ if (mState != mTargetState) {
+ bool transitionComplete = true;
+
+ if (mState == OMX_StateLoaded) {
+ CHECK_EQ((int)mTargetState, (int)OMX_StateIdle);
+
+ for (size_t i = 0; i < mPorts.size(); ++i) {
+ const PortInfo &port = mPorts.itemAt(i);
+ if (port.mDef.bEnabled == OMX_FALSE) {
+ continue;
+ }
+
+ if (port.mDef.bPopulated == OMX_FALSE) {
+ transitionComplete = false;
+ break;
+ }
+ }
+ } else if (mTargetState == OMX_StateLoaded) {
+ CHECK_EQ((int)mState, (int)OMX_StateIdle);
+
+ for (size_t i = 0; i < mPorts.size(); ++i) {
+ const PortInfo &port = mPorts.itemAt(i);
+ if (port.mDef.bEnabled == OMX_FALSE) {
+ continue;
+ }
+
+ size_t n = port.mBuffers.size();
+
+ if (n > 0) {
+ CHECK_LE(n, port.mDef.nBufferCountActual);
+
+ if (n == port.mDef.nBufferCountActual) {
+ CHECK_EQ((int)port.mDef.bPopulated, (int)OMX_TRUE);
+ } else {
+ CHECK_EQ((int)port.mDef.bPopulated, (int)OMX_FALSE);
+ }
+
+ transitionComplete = false;
+ break;
+ }
+ }
+ }
+
+ if (transitionComplete) {
+ mState = mTargetState;
+
+ notify(OMX_EventCmdComplete, OMX_CommandStateSet, mState, NULL);
+ }
+ }
+
+ for (size_t i = 0; i < mPorts.size(); ++i) {
+ PortInfo *port = &mPorts.editItemAt(i);
+
+ if (port->mTransition == PortInfo::DISABLING) {
+ if (port->mBuffers.empty()) {
+ LOGV("Port %d now disabled.", i);
+
+ port->mTransition = PortInfo::NONE;
+ notify(OMX_EventCmdComplete, OMX_CommandPortDisable, i, NULL);
+
+ onPortEnableCompleted(i, false /* enabled */);
+ }
+ } else if (port->mTransition == PortInfo::ENABLING) {
+ if (port->mDef.bPopulated == OMX_TRUE) {
+ LOGV("Port %d now enabled.", i);
+
+ port->mTransition = PortInfo::NONE;
+ port->mDef.bEnabled = OMX_TRUE;
+ notify(OMX_EventCmdComplete, OMX_CommandPortEnable, i, NULL);
+
+ onPortEnableCompleted(i, true /* enabled */);
+ }
+ }
+ }
+}
+
+void SimpleSoftOMXComponent::addPort(const OMX_PARAM_PORTDEFINITIONTYPE &def) {
+ CHECK_EQ(def.nPortIndex, mPorts.size());
+
+ mPorts.push();
+ PortInfo *info = &mPorts.editItemAt(mPorts.size() - 1);
+ info->mDef = def;
+ info->mTransition = PortInfo::NONE;
+}
+
+void SimpleSoftOMXComponent::onQueueFilled(OMX_U32 portIndex) {
+}
+
+void SimpleSoftOMXComponent::onPortFlushCompleted(OMX_U32 portIndex) {
+}
+
+void SimpleSoftOMXComponent::onPortEnableCompleted(
+ OMX_U32 portIndex, bool enabled) {
+}
+
+List<SimpleSoftOMXComponent::BufferInfo *> &
+SimpleSoftOMXComponent::getPortQueue(OMX_U32 portIndex) {
+ CHECK_LT(portIndex, mPorts.size());
+ return mPorts.editItemAt(portIndex).mQueue;
+}
+
+SimpleSoftOMXComponent::PortInfo *SimpleSoftOMXComponent::editPortInfo(
+ OMX_U32 portIndex) {
+ CHECK_LT(portIndex, mPorts.size());
+ return &mPorts.editItemAt(portIndex);
+}
+
+} // namespace android
diff --git a/media/libstagefright/omx/SoftOMXComponent.cpp b/media/libstagefright/omx/SoftOMXComponent.cpp
new file mode 100644
index 0000000..b1c34dc
--- /dev/null
+++ b/media/libstagefright/omx/SoftOMXComponent.cpp
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2011 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 "SoftOMXComponent"
+#include <utils/Log.h>
+
+#include "include/SoftOMXComponent.h"
+
+#include <media/stagefright/foundation/ADebug.h>
+
+namespace android {
+
+SoftOMXComponent::SoftOMXComponent(
+ const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component)
+ : mName(name),
+ mCallbacks(callbacks),
+ mComponent(new OMX_COMPONENTTYPE),
+ mLibHandle(NULL) {
+ mComponent->nSize = sizeof(*mComponent);
+ mComponent->nVersion.s.nVersionMajor = 1;
+ mComponent->nVersion.s.nVersionMinor = 0;
+ mComponent->nVersion.s.nRevision = 0;
+ mComponent->nVersion.s.nStep = 0;
+ mComponent->pComponentPrivate = this;
+ mComponent->pApplicationPrivate = appData;
+
+ mComponent->GetComponentVersion = NULL;
+ mComponent->SendCommand = SendCommandWrapper;
+ mComponent->GetParameter = GetParameterWrapper;
+ mComponent->SetParameter = SetParameterWrapper;
+ mComponent->GetConfig = GetConfigWrapper;
+ mComponent->SetConfig = SetConfigWrapper;
+ mComponent->GetExtensionIndex = GetExtensionIndexWrapper;
+ mComponent->GetState = GetStateWrapper;
+ mComponent->ComponentTunnelRequest = NULL;
+ mComponent->UseBuffer = UseBufferWrapper;
+ mComponent->AllocateBuffer = AllocateBufferWrapper;
+ mComponent->FreeBuffer = FreeBufferWrapper;
+ mComponent->EmptyThisBuffer = EmptyThisBufferWrapper;
+ mComponent->FillThisBuffer = FillThisBufferWrapper;
+ mComponent->SetCallbacks = NULL;
+ mComponent->ComponentDeInit = NULL;
+ mComponent->UseEGLImage = NULL;
+ mComponent->ComponentRoleEnum = NULL;
+
+ *component = mComponent;
+}
+
+SoftOMXComponent::~SoftOMXComponent() {
+ delete mComponent;
+ mComponent = NULL;
+}
+
+void SoftOMXComponent::setLibHandle(void *libHandle) {
+ CHECK(libHandle != NULL);
+ mLibHandle = libHandle;
+}
+
+void *SoftOMXComponent::libHandle() const {
+ return mLibHandle;
+}
+
+OMX_ERRORTYPE SoftOMXComponent::initCheck() const {
+ return OMX_ErrorNone;
+}
+
+const char *SoftOMXComponent::name() const {
+ return mName.c_str();
+}
+
+void SoftOMXComponent::notify(
+ OMX_EVENTTYPE event,
+ OMX_U32 data1, OMX_U32 data2, OMX_PTR data) {
+ (*mCallbacks->EventHandler)(
+ mComponent,
+ mComponent->pApplicationPrivate,
+ event,
+ data1,
+ data2,
+ data);
+}
+
+void SoftOMXComponent::notifyEmptyBufferDone(OMX_BUFFERHEADERTYPE *header) {
+ (*mCallbacks->EmptyBufferDone)(
+ mComponent, mComponent->pApplicationPrivate, header);
+}
+
+void SoftOMXComponent::notifyFillBufferDone(OMX_BUFFERHEADERTYPE *header) {
+ (*mCallbacks->FillBufferDone)(
+ mComponent, mComponent->pApplicationPrivate, header);
+}
+
+// static
+OMX_ERRORTYPE SoftOMXComponent::SendCommandWrapper(
+ OMX_HANDLETYPE component,
+ OMX_COMMANDTYPE cmd,
+ OMX_U32 param,
+ OMX_PTR data) {
+ SoftOMXComponent *me =
+ (SoftOMXComponent *)
+ ((OMX_COMPONENTTYPE *)component)->pComponentPrivate;
+
+ return me->sendCommand(cmd, param, data);
+}
+
+// static
+OMX_ERRORTYPE SoftOMXComponent::GetParameterWrapper(
+ OMX_HANDLETYPE component,
+ OMX_INDEXTYPE index,
+ OMX_PTR params) {
+ SoftOMXComponent *me =
+ (SoftOMXComponent *)
+ ((OMX_COMPONENTTYPE *)component)->pComponentPrivate;
+
+ return me->getParameter(index, params);
+}
+
+// static
+OMX_ERRORTYPE SoftOMXComponent::SetParameterWrapper(
+ OMX_HANDLETYPE component,
+ OMX_INDEXTYPE index,
+ OMX_PTR params) {
+ SoftOMXComponent *me =
+ (SoftOMXComponent *)
+ ((OMX_COMPONENTTYPE *)component)->pComponentPrivate;
+
+ return me->setParameter(index, params);
+}
+
+// static
+OMX_ERRORTYPE SoftOMXComponent::GetConfigWrapper(
+ OMX_HANDLETYPE component,
+ OMX_INDEXTYPE index,
+ OMX_PTR params) {
+ SoftOMXComponent *me =
+ (SoftOMXComponent *)
+ ((OMX_COMPONENTTYPE *)component)->pComponentPrivate;
+
+ return me->getConfig(index, params);
+}
+
+// static
+OMX_ERRORTYPE SoftOMXComponent::SetConfigWrapper(
+ OMX_HANDLETYPE component,
+ OMX_INDEXTYPE index,
+ OMX_PTR params) {
+ SoftOMXComponent *me =
+ (SoftOMXComponent *)
+ ((OMX_COMPONENTTYPE *)component)->pComponentPrivate;
+
+ return me->setConfig(index, params);
+}
+
+// static
+OMX_ERRORTYPE SoftOMXComponent::GetExtensionIndexWrapper(
+ OMX_HANDLETYPE component,
+ OMX_STRING name,
+ OMX_INDEXTYPE *index) {
+ SoftOMXComponent *me =
+ (SoftOMXComponent *)
+ ((OMX_COMPONENTTYPE *)component)->pComponentPrivate;
+
+ return me->getExtensionIndex(name, index);
+}
+
+// static
+OMX_ERRORTYPE SoftOMXComponent::UseBufferWrapper(
+ OMX_HANDLETYPE component,
+ OMX_BUFFERHEADERTYPE **buffer,
+ OMX_U32 portIndex,
+ OMX_PTR appPrivate,
+ OMX_U32 size,
+ OMX_U8 *ptr) {
+ SoftOMXComponent *me =
+ (SoftOMXComponent *)
+ ((OMX_COMPONENTTYPE *)component)->pComponentPrivate;
+
+ return me->useBuffer(buffer, portIndex, appPrivate, size, ptr);
+}
+
+// static
+OMX_ERRORTYPE SoftOMXComponent::AllocateBufferWrapper(
+ OMX_HANDLETYPE component,
+ OMX_BUFFERHEADERTYPE **buffer,
+ OMX_U32 portIndex,
+ OMX_PTR appPrivate,
+ OMX_U32 size) {
+ SoftOMXComponent *me =
+ (SoftOMXComponent *)
+ ((OMX_COMPONENTTYPE *)component)->pComponentPrivate;
+
+ return me->allocateBuffer(buffer, portIndex, appPrivate, size);
+}
+
+// static
+OMX_ERRORTYPE SoftOMXComponent::FreeBufferWrapper(
+ OMX_HANDLETYPE component,
+ OMX_U32 portIndex,
+ OMX_BUFFERHEADERTYPE *buffer) {
+ SoftOMXComponent *me =
+ (SoftOMXComponent *)
+ ((OMX_COMPONENTTYPE *)component)->pComponentPrivate;
+
+ return me->freeBuffer(portIndex, buffer);
+}
+
+// static
+OMX_ERRORTYPE SoftOMXComponent::EmptyThisBufferWrapper(
+ OMX_HANDLETYPE component,
+ OMX_BUFFERHEADERTYPE *buffer) {
+ SoftOMXComponent *me =
+ (SoftOMXComponent *)
+ ((OMX_COMPONENTTYPE *)component)->pComponentPrivate;
+
+ return me->emptyThisBuffer(buffer);
+}
+
+// static
+OMX_ERRORTYPE SoftOMXComponent::FillThisBufferWrapper(
+ OMX_HANDLETYPE component,
+ OMX_BUFFERHEADERTYPE *buffer) {
+ SoftOMXComponent *me =
+ (SoftOMXComponent *)
+ ((OMX_COMPONENTTYPE *)component)->pComponentPrivate;
+
+ return me->fillThisBuffer(buffer);
+}
+
+// static
+OMX_ERRORTYPE SoftOMXComponent::GetStateWrapper(
+ OMX_HANDLETYPE component,
+ OMX_STATETYPE *state) {
+ SoftOMXComponent *me =
+ (SoftOMXComponent *)
+ ((OMX_COMPONENTTYPE *)component)->pComponentPrivate;
+
+ return me->getState(state);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+OMX_ERRORTYPE SoftOMXComponent::sendCommand(
+ OMX_COMMANDTYPE cmd, OMX_U32 param, OMX_PTR data) {
+ return OMX_ErrorUndefined;
+}
+
+OMX_ERRORTYPE SoftOMXComponent::getParameter(
+ OMX_INDEXTYPE index, OMX_PTR params) {
+ return OMX_ErrorUndefined;
+}
+
+OMX_ERRORTYPE SoftOMXComponent::setParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params) {
+ return OMX_ErrorUndefined;
+}
+
+OMX_ERRORTYPE SoftOMXComponent::getConfig(
+ OMX_INDEXTYPE index, OMX_PTR params) {
+ return OMX_ErrorUndefined;
+}
+
+OMX_ERRORTYPE SoftOMXComponent::setConfig(
+ OMX_INDEXTYPE index, const OMX_PTR params) {
+ return OMX_ErrorUndefined;
+}
+
+OMX_ERRORTYPE SoftOMXComponent::getExtensionIndex(
+ const char *name, OMX_INDEXTYPE *index) {
+ return OMX_ErrorUndefined;
+}
+
+OMX_ERRORTYPE SoftOMXComponent::useBuffer(
+ OMX_BUFFERHEADERTYPE **buffer,
+ OMX_U32 portIndex,
+ OMX_PTR appPrivate,
+ OMX_U32 size,
+ OMX_U8 *ptr) {
+ return OMX_ErrorUndefined;
+}
+
+OMX_ERRORTYPE SoftOMXComponent::allocateBuffer(
+ OMX_BUFFERHEADERTYPE **buffer,
+ OMX_U32 portIndex,
+ OMX_PTR appPrivate,
+ OMX_U32 size) {
+ return OMX_ErrorUndefined;
+}
+
+OMX_ERRORTYPE SoftOMXComponent::freeBuffer(
+ OMX_U32 portIndex,
+ OMX_BUFFERHEADERTYPE *buffer) {
+ return OMX_ErrorUndefined;
+}
+
+OMX_ERRORTYPE SoftOMXComponent::emptyThisBuffer(
+ OMX_BUFFERHEADERTYPE *buffer) {
+ return OMX_ErrorUndefined;
+}
+
+OMX_ERRORTYPE SoftOMXComponent::fillThisBuffer(
+ OMX_BUFFERHEADERTYPE *buffer) {
+ return OMX_ErrorUndefined;
+}
+
+OMX_ERRORTYPE SoftOMXComponent::getState(OMX_STATETYPE *state) {
+ return OMX_ErrorUndefined;
+}
+
+} // namespace android
diff --git a/media/libstagefright/omx/SoftOMXPlugin.cpp b/media/libstagefright/omx/SoftOMXPlugin.cpp
new file mode 100644
index 0000000..1e33f05
--- /dev/null
+++ b/media/libstagefright/omx/SoftOMXPlugin.cpp
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2011 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 "SoftOMXPlugin"
+#include <utils/Log.h>
+
+#include "SoftOMXPlugin.h"
+#include "include/SoftOMXComponent.h"
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/AString.h>
+
+#include <dlfcn.h>
+
+namespace android {
+
+static const struct {
+ const char *mName;
+ const char *mLibNameSuffix;
+ const char *mRole;
+
+} kComponents[] = {
+ { "OMX.google.aac.decoder", "aacdec", "audio_decoder.aac" },
+ { "OMX.google.amrnb.decoder", "amrdec", "audio_decoder.amrnb" },
+ { "OMX.google.amrwb.decoder", "amrdec", "audio_decoder.amrwb" },
+ { "OMX.google.h264.decoder", "h264dec", "video_decoder.avc" },
+ { "OMX.google.g711.alaw.decoder", "g711dec", "audio_decoder.g711alaw" },
+ { "OMX.google.g711.mlaw.decoder", "g711dec", "audio_decoder.g711mlaw" },
+ { "OMX.google.h263.decoder", "mpeg4dec", "video_decoder.h263" },
+ { "OMX.google.mpeg4.decoder", "mpeg4dec", "video_decoder.mpeg4" },
+ { "OMX.google.mp3.decoder", "mp3dec", "audio_decoder.mp3" },
+ { "OMX.google.vorbis.decoder", "vorbisdec", "audio_decoder.vorbis" },
+ { "OMX.google.vpx.decoder", "vpxdec", "video_decoder.vpx" },
+};
+
+static const size_t kNumComponents =
+ sizeof(kComponents) / sizeof(kComponents[0]);
+
+SoftOMXPlugin::SoftOMXPlugin() {
+}
+
+OMX_ERRORTYPE SoftOMXPlugin::makeComponentInstance(
+ const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component) {
+ LOGV("makeComponentInstance '%s'", name);
+
+ for (size_t i = 0; i < kNumComponents; ++i) {
+ if (strcmp(name, kComponents[i].mName)) {
+ continue;
+ }
+
+ AString libName = "libstagefright_soft_";
+ libName.append(kComponents[i].mLibNameSuffix);
+ libName.append(".so");
+
+ void *libHandle = dlopen(libName.c_str(), RTLD_NOW);
+
+ if (libHandle == NULL) {
+ LOGE("unable to dlopen %s", libName.c_str());
+
+ return OMX_ErrorComponentNotFound;
+ }
+
+ typedef SoftOMXComponent *(*CreateSoftOMXComponentFunc)(
+ const char *, const OMX_CALLBACKTYPE *,
+ OMX_PTR, OMX_COMPONENTTYPE **);
+
+ CreateSoftOMXComponentFunc createSoftOMXComponent =
+ (CreateSoftOMXComponentFunc)dlsym(
+ libHandle,
+ "_Z22createSoftOMXComponentPKcPK16OMX_CALLBACKTYPE"
+ "PvPP17OMX_COMPONENTTYPE");
+
+ if (createSoftOMXComponent == NULL) {
+ dlclose(libHandle);
+ libHandle = NULL;
+
+ return OMX_ErrorComponentNotFound;
+ }
+
+ sp<SoftOMXComponent> codec =
+ (*createSoftOMXComponent)(name, callbacks, appData, component);
+
+ if (codec == NULL) {
+ dlclose(libHandle);
+ libHandle = NULL;
+
+ return OMX_ErrorInsufficientResources;
+ }
+
+ OMX_ERRORTYPE err = codec->initCheck();
+ if (err != OMX_ErrorNone) {
+ dlclose(libHandle);
+ libHandle = NULL;
+
+ return err;
+ }
+
+ codec->incStrong(this);
+ codec->setLibHandle(libHandle);
+
+ return OMX_ErrorNone;
+ }
+
+ return OMX_ErrorInvalidComponentName;
+}
+
+OMX_ERRORTYPE SoftOMXPlugin::destroyComponentInstance(
+ OMX_COMPONENTTYPE *component) {
+ SoftOMXComponent *me =
+ (SoftOMXComponent *)
+ ((OMX_COMPONENTTYPE *)component)->pComponentPrivate;
+
+ me->prepareForDestruction();
+
+ void *libHandle = me->libHandle();
+
+ CHECK_EQ(me->getStrongCount(), 1);
+ me->decStrong(this);
+ me = NULL;
+
+ dlclose(libHandle);
+ libHandle = NULL;
+
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE SoftOMXPlugin::enumerateComponents(
+ OMX_STRING name,
+ size_t size,
+ OMX_U32 index) {
+ if (index >= kNumComponents) {
+ return OMX_ErrorNoMore;
+ }
+
+ strcpy(name, kComponents[index].mName);
+
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE SoftOMXPlugin::getRolesOfComponent(
+ const char *name,
+ Vector<String8> *roles) {
+ for (size_t i = 0; i < kNumComponents; ++i) {
+ if (strcmp(name, kComponents[i].mName)) {
+ continue;
+ }
+
+ roles->clear();
+ roles->push(String8(kComponents[i].mRole));
+
+ return OMX_ErrorNone;
+ }
+
+ return OMX_ErrorInvalidComponentName;
+}
+
+} // namespace android
diff --git a/media/libstagefright/omx/SoftOMXPlugin.h b/media/libstagefright/omx/SoftOMXPlugin.h
new file mode 100644
index 0000000..f93c323
--- /dev/null
+++ b/media/libstagefright/omx/SoftOMXPlugin.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2011 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 SOFT_OMX_PLUGIN_H_
+
+#define SOFT_OMX_PLUGIN_H_
+
+#include <media/stagefright/foundation/ABase.h>
+#include <media/stagefright/OMXPluginBase.h>
+
+namespace android {
+
+struct SoftOMXPlugin : public OMXPluginBase {
+ SoftOMXPlugin();
+
+ virtual OMX_ERRORTYPE makeComponentInstance(
+ const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component);
+
+ virtual OMX_ERRORTYPE destroyComponentInstance(
+ OMX_COMPONENTTYPE *component);
+
+ virtual OMX_ERRORTYPE enumerateComponents(
+ OMX_STRING name,
+ size_t size,
+ OMX_U32 index);
+
+ virtual OMX_ERRORTYPE getRolesOfComponent(
+ const char *name,
+ Vector<String8> *roles);
+
+private:
+ DISALLOW_EVIL_CONSTRUCTORS(SoftOMXPlugin);
+};
+
+} // namespace android
+
+#endif // SOFT_OMX_PLUGIN_H_
diff --git a/media/libstagefright/omx/tests/OMXHarness.cpp b/media/libstagefright/omx/tests/OMXHarness.cpp
index 4f28855..d4354db 100644
--- a/media/libstagefright/omx/tests/OMXHarness.cpp
+++ b/media/libstagefright/omx/tests/OMXHarness.cpp
@@ -29,6 +29,7 @@
#include <media/stagefright/DataSource.h>
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MediaExtractor.h>
#include <media/stagefright/MediaSource.h>
@@ -454,6 +455,7 @@
{ "video_decoder.avc", "video/avc" },
{ "video_decoder.mpeg4", "video/mp4v-es" },
{ "video_decoder.h263", "video/3gpp" },
+ { "video_decoder.vpx", "video/x-vnd.on2.vp8" },
// we appear to use this as a synonym to amrnb.
{ "audio_decoder.amr", "audio/3gpp" },
@@ -461,7 +463,10 @@
{ "audio_decoder.amrnb", "audio/3gpp" },
{ "audio_decoder.amrwb", "audio/amr-wb" },
{ "audio_decoder.aac", "audio/mp4a-latm" },
- { "audio_decoder.mp3", "audio/mpeg" }
+ { "audio_decoder.mp3", "audio/mpeg" },
+ { "audio_decoder.vorbis", "audio/vorbis" },
+ { "audio_decoder.g711alaw", MEDIA_MIMETYPE_AUDIO_G711_ALAW },
+ { "audio_decoder.g711mlaw", MEDIA_MIMETYPE_AUDIO_G711_MLAW },
};
for (size_t i = 0; i < sizeof(kRoleToMime) / sizeof(kRoleToMime[0]); ++i) {
@@ -480,21 +485,23 @@
};
static const MimeToURL kMimeToURL[] = {
{ "video/avc",
- "file:///sdcard/media_api/video/H264_AAC.3gp" },
- { "video/mp4v-es", "file:///sdcard/media_api/video/gingerkids.MP4" },
+ "file:///sdcard/media_api/video/H264_500_AAC_128.3gp" },
+ { "video/mp4v-es", "file:///sdcard/media_api/video/MPEG4_320_AAC_64.mp4" },
{ "video/3gpp",
"file:///sdcard/media_api/video/H263_500_AMRNB_12.3gp" },
{ "audio/3gpp",
"file:///sdcard/media_api/video/H263_500_AMRNB_12.3gp" },
- { "audio/amr-wb",
- "file:///sdcard/media_api/music_perf/AMRWB/"
- "NIN_AMR-WB_15.85kbps_16kbps.amr" },
+ { "audio/amr-wb", NULL },
{ "audio/mp4a-latm",
- "file:///sdcard/media_api/music_perf/AAC/"
- "WC_AAC_80kbps_32khz_Stereo_1pCBR_SSE.mp4" },
+ "file:///sdcard/media_api/video/H263_56_AAC_24.3gp" },
{ "audio/mpeg",
- "file:///sdcard/media_api/music_perf/MP3/"
- "WC_256kbps_44.1khz_mono_CBR_DPA.mp3" }
+ "file:///sdcard/media_api/music/MP3_48KHz_128kbps_s_1_17_CBR.mp3" },
+ { "audio/vorbis", NULL },
+ { "video/x-vnd.on2.vp8",
+ "file:///sdcard/media_api/video/big-buck-bunny_trailer.webm" },
+ { MEDIA_MIMETYPE_AUDIO_G711_ALAW, "file:///sdcard/M1F1-Alaw-AFsp.wav" },
+ { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
+ "file:///sdcard/M1F1-mulaw-AFsp.wav" },
};
for (size_t i = 0; i < sizeof(kMimeToURL) / sizeof(kMimeToURL[0]); ++i) {
@@ -626,8 +633,10 @@
requestedSeekTimeUs, requestedSeekTimeUs / 1E6);
}
- MediaBuffer *buffer;
- options.setSeekTo(requestedSeekTimeUs);
+ MediaBuffer *buffer = NULL;
+ options.setSeekTo(
+ requestedSeekTimeUs, MediaSource::ReadOptions::SEEK_NEXT_SYNC);
+
if (seekSource->read(&buffer, &options) != OK) {
CHECK_EQ(buffer, NULL);
actualSeekTimeUs = -1;
@@ -746,6 +755,10 @@
const IOMX::ComponentInfo &info = *it;
const char *componentName = info.mName.string();
+ if (strncmp(componentName, "OMX.google.", 11)) {
+ continue;
+ }
+
for (List<String8>::const_iterator role_it = info.mRoles.begin();
role_it != info.mRoles.end(); ++role_it) {
const char *componentRole = (*role_it).string();
diff --git a/media/libstagefright/rtsp/APacketSource.cpp b/media/libstagefright/rtsp/APacketSource.cpp
index 6819fef..a02591f 100644
--- a/media/libstagefright/rtsp/APacketSource.cpp
+++ b/media/libstagefright/rtsp/APacketSource.cpp
@@ -329,7 +329,7 @@
return dst;
}
-static bool ExtractDimensionsFromVOLHeader(
+static bool ExtractDimensionsMPEG4Config(
const sp<ABuffer> &config, int32_t *width, int32_t *height) {
*width = 0;
*height = 0;
@@ -352,87 +352,11 @@
return false;
}
- ABitReader br(&ptr[offset + 4], config->size() - offset - 4);
- br.skipBits(1); // random_accessible_vol
- unsigned video_object_type_indication = br.getBits(8);
-
- CHECK_NE(video_object_type_indication,
- 0x21u /* Fine Granularity Scalable */);
-
- unsigned video_object_layer_verid;
- unsigned video_object_layer_priority;
- if (br.getBits(1)) {
- video_object_layer_verid = br.getBits(4);
- video_object_layer_priority = br.getBits(3);
- }
- unsigned aspect_ratio_info = br.getBits(4);
- if (aspect_ratio_info == 0x0f /* extended PAR */) {
- br.skipBits(8); // par_width
- br.skipBits(8); // par_height
- }
- if (br.getBits(1)) { // vol_control_parameters
- br.skipBits(2); // chroma_format
- br.skipBits(1); // low_delay
- if (br.getBits(1)) { // vbv_parameters
- br.skipBits(15); // first_half_bit_rate
- CHECK(br.getBits(1)); // marker_bit
- br.skipBits(15); // latter_half_bit_rate
- CHECK(br.getBits(1)); // marker_bit
- br.skipBits(15); // first_half_vbv_buffer_size
- CHECK(br.getBits(1)); // marker_bit
- br.skipBits(3); // latter_half_vbv_buffer_size
- br.skipBits(11); // first_half_vbv_occupancy
- CHECK(br.getBits(1)); // marker_bit
- br.skipBits(15); // latter_half_vbv_occupancy
- CHECK(br.getBits(1)); // marker_bit
- }
- }
- unsigned video_object_layer_shape = br.getBits(2);
- CHECK_EQ(video_object_layer_shape, 0x00u /* rectangular */);
-
- CHECK(br.getBits(1)); // marker_bit
- unsigned vop_time_increment_resolution = br.getBits(16);
- CHECK(br.getBits(1)); // marker_bit
-
- if (br.getBits(1)) { // fixed_vop_rate
- // range [0..vop_time_increment_resolution)
-
- // vop_time_increment_resolution
- // 2 => 0..1, 1 bit
- // 3 => 0..2, 2 bits
- // 4 => 0..3, 2 bits
- // 5 => 0..4, 3 bits
- // ...
-
- CHECK_GT(vop_time_increment_resolution, 0u);
- --vop_time_increment_resolution;
-
- unsigned numBits = 0;
- while (vop_time_increment_resolution > 0) {
- ++numBits;
- vop_time_increment_resolution >>= 1;
- }
-
- br.skipBits(numBits); // fixed_vop_time_increment
- }
-
- CHECK(br.getBits(1)); // marker_bit
- unsigned video_object_layer_width = br.getBits(13);
- CHECK(br.getBits(1)); // marker_bit
- unsigned video_object_layer_height = br.getBits(13);
- CHECK(br.getBits(1)); // marker_bit
-
- unsigned interlaced = br.getBits(1);
-
- *width = video_object_layer_width;
- *height = video_object_layer_height;
-
- LOGI("VOL dimensions = %dx%d", *width, *height);
-
- return true;
+ return ExtractDimensionsFromVOLHeader(
+ &ptr[offset], config->size() - offset, width, height);
}
-sp<ABuffer> MakeMPEG4VideoCodecSpecificData(
+static sp<ABuffer> MakeMPEG4VideoCodecSpecificData(
const char *params, int32_t *width, int32_t *height) {
*width = 0;
*height = 0;
@@ -443,10 +367,12 @@
sp<ABuffer> config = decodeHex(val);
CHECK(config != NULL);
- if (!ExtractDimensionsFromVOLHeader(config, width, height)) {
+ if (!ExtractDimensionsMPEG4Config(config, width, height)) {
return NULL;
}
+ LOGI("VOL dimensions = %dx%d", *width, *height);
+
size_t len1 = config->size() + GetSizeWidth(config->size()) + 1;
size_t len2 = len1 + GetSizeWidth(len1) + 1 + 13;
size_t len3 = len2 + GetSizeWidth(len2) + 1 + 3;
diff --git a/media/libstagefright/rtsp/ARTSPConnection.cpp b/media/libstagefright/rtsp/ARTSPConnection.cpp
index 0740515..b398c9d 100644
--- a/media/libstagefright/rtsp/ARTSPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTSPConnection.cpp
@@ -20,6 +20,8 @@
#include "ARTSPConnection.h"
+#include <cutils/properties.h>
+
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
@@ -32,18 +34,23 @@
#include <openssl/md5.h>
#include <sys/socket.h>
+#include "HTTPBase.h"
+
namespace android {
// static
const int64_t ARTSPConnection::kSelectTimeoutUs = 1000ll;
-ARTSPConnection::ARTSPConnection()
- : mState(DISCONNECTED),
+ARTSPConnection::ARTSPConnection(bool uidValid, uid_t uid)
+ : mUIDValid(uidValid),
+ mUID(uid),
+ mState(DISCONNECTED),
mAuthType(NONE),
mSocket(-1),
mConnectionID(0),
mNextCSeq(0),
mReceiveResponseEventPending(false) {
+ MakeUserAgent(&mUserAgent);
}
ARTSPConnection::~ARTSPConnection() {
@@ -243,6 +250,10 @@
mSocket = socket(AF_INET, SOCK_STREAM, 0);
+ if (mUIDValid) {
+ HTTPBase::RegisterSocketUser(mSocket, mUID);
+ }
+
MakeSocketBlocking(mSocket, false);
struct sockaddr_in remote;
@@ -378,6 +389,7 @@
reply->setString("original-request", request.c_str(), request.size());
addAuthentication(&request);
+ addUserAgent(&request);
// Find the boundary between headers and the body.
ssize_t i = request.find("\r\n\r\n");
@@ -979,4 +991,27 @@
#endif
}
+// static
+void ARTSPConnection::MakeUserAgent(AString *userAgent) {
+ userAgent->clear();
+ userAgent->setTo("User-Agent: stagefright/1.1 (Linux;Android ");
+
+#if (PROPERTY_VALUE_MAX < 8)
+#error "PROPERTY_VALUE_MAX must be at least 8"
+#endif
+
+ char value[PROPERTY_VALUE_MAX];
+ property_get("ro.build.version.release", value, "Unknown");
+ userAgent->append(value);
+ userAgent->append(")\r\n");
+}
+
+void ARTSPConnection::addUserAgent(AString *request) const {
+ // Find the boundary between headers and the body.
+ ssize_t i = request->find("\r\n\r\n");
+ CHECK_GE(i, 0);
+
+ request->insert(mUserAgent, i + 2);
+}
+
} // namespace android
diff --git a/media/libstagefright/rtsp/ARTSPConnection.h b/media/libstagefright/rtsp/ARTSPConnection.h
index 0fecf3c6..5cb84fd 100644
--- a/media/libstagefright/rtsp/ARTSPConnection.h
+++ b/media/libstagefright/rtsp/ARTSPConnection.h
@@ -33,7 +33,7 @@
};
struct ARTSPConnection : public AHandler {
- ARTSPConnection();
+ ARTSPConnection(bool uidValid = false, uid_t uid = 0);
void connect(const char *url, const sp<AMessage> &reply);
void disconnect(const sp<AMessage> &reply);
@@ -74,6 +74,8 @@
static const int64_t kSelectTimeoutUs;
+ bool mUIDValid;
+ uid_t mUID;
State mState;
AString mUser, mPass;
AuthType mAuthType;
@@ -87,6 +89,8 @@
sp<AMessage> mObserveBinaryMessage;
+ AString mUserAgent;
+
void onConnect(const sp<AMessage> &msg);
void onDisconnect(const sp<AMessage> &msg);
void onCompleteConnection(const sp<AMessage> &msg);
@@ -106,6 +110,8 @@
bool parseAuthMethod(const sp<ARTSPResponse> &response);
void addAuthentication(AString *request);
+ void addUserAgent(AString *request) const;
+
status_t findPendingRequest(
const sp<ARTSPResponse> &response, ssize_t *index) const;
@@ -114,6 +120,8 @@
static bool ParseSingleUnsignedLong(
const char *from, unsigned long *x);
+ static void MakeUserAgent(AString *userAgent);
+
DISALLOW_EVIL_CONSTRUCTORS(ARTSPConnection);
};
diff --git a/media/libstagefright/rtsp/ARTSPController.cpp b/media/libstagefright/rtsp/ARTSPController.cpp
index 1328d2e..2ebae7e 100644
--- a/media/libstagefright/rtsp/ARTSPController.cpp
+++ b/media/libstagefright/rtsp/ARTSPController.cpp
@@ -28,6 +28,7 @@
ARTSPController::ARTSPController(const sp<ALooper> &looper)
: mState(DISCONNECTED),
mLooper(looper),
+ mUIDValid(false),
mSeekDoneCb(NULL),
mSeekDoneCookie(NULL),
mLastSeekCompletedTimeUs(-1) {
@@ -40,6 +41,11 @@
mLooper->unregisterHandler(mReflector->id());
}
+void ARTSPController::setUID(uid_t uid) {
+ mUIDValid = true;
+ mUID = uid;
+}
+
status_t ARTSPController::connect(const char *url) {
Mutex::Autolock autoLock(mLock);
@@ -49,7 +55,7 @@
sp<AMessage> msg = new AMessage(kWhatConnectDone, mReflector->id());
- mHandler = new MyHandler(url, mLooper);
+ mHandler = new MyHandler(url, mLooper, mUIDValid, mUID);
mState = CONNECTING;
diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h
index d15d9c5..71d68f6 100644
--- a/media/libstagefright/rtsp/MyHandler.h
+++ b/media/libstagefright/rtsp/MyHandler.h
@@ -40,6 +40,8 @@
#include <sys/socket.h>
#include <netdb.h>
+#include "HTTPBase.h"
+
// If no access units are received within 5 secs, assume that the rtp
// stream has ended and signal end of stream.
static int64_t kAccessUnitTimeoutUs = 5000000ll;
@@ -92,10 +94,14 @@
}
struct MyHandler : public AHandler {
- MyHandler(const char *url, const sp<ALooper> &looper)
- : mLooper(looper),
+ MyHandler(
+ const char *url, const sp<ALooper> &looper,
+ bool uidValid = false, uid_t uid = 0)
+ : mUIDValid(uidValid),
+ mUID(uid),
+ mLooper(looper),
mNetLooper(new ALooper),
- mConn(new ARTSPConnection),
+ mConn(new ARTSPConnection(mUIDValid, mUID)),
mRTPConn(new ARTPConnection),
mOriginalSessionURL(url),
mSessionURL(url),
@@ -1078,6 +1084,8 @@
List<sp<ABuffer> > mPackets;
};
+ bool mUIDValid;
+ uid_t mUID;
sp<ALooper> mLooper;
sp<ALooper> mNetLooper;
sp<ARTSPConnection> mConn;
@@ -1172,6 +1180,11 @@
ARTPConnection::MakePortPair(
&info->mRTPSocket, &info->mRTCPSocket, &rtpPort);
+ if (mUIDValid) {
+ HTTPBase::RegisterSocketUser(info->mRTPSocket, mUID);
+ HTTPBase::RegisterSocketUser(info->mRTCPSocket, mUID);
+ }
+
request.append("Transport: RTP/AVP/UDP;unicast;client_port=");
request.append(rtpPort);
request.append("-");
diff --git a/media/libstagefright/tests/Android.mk b/media/libstagefright/tests/Android.mk
new file mode 100644
index 0000000..3ea8f39
--- /dev/null
+++ b/media/libstagefright/tests/Android.mk
@@ -0,0 +1,53 @@
+# Build the unit tests.
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+ifneq ($(TARGET_SIMULATOR),true)
+
+LOCAL_MODULE := SurfaceMediaSource_test
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := \
+ SurfaceMediaSource_test.cpp \
+ DummyRecorder.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+ libEGL \
+ libGLESv2 \
+ libandroid \
+ libbinder \
+ libcutils \
+ libgui \
+ libstlport \
+ libui \
+ libutils \
+ libstagefright \
+ libstagefright_omx \
+ libstagefright_foundation \
+
+LOCAL_STATIC_LIBRARIES := \
+ libgtest \
+ libgtest_main \
+
+LOCAL_C_INCLUDES := \
+ bionic \
+ bionic/libstdc++/include \
+ external/gtest/include \
+ external/stlport/stlport \
+ frameworks/base/media/libstagefright \
+ frameworks/base/media/libstagefright/include \
+ $(TOP)/frameworks/base/include/media/stagefright/openmax \
+
+include $(BUILD_EXECUTABLE)
+
+endif
+
+# Include subdirectory makefiles
+# ============================================================
+
+# If we're building with ONE_SHOT_MAKEFILE (mm, mmm), then what the framework
+# team really wants is to build the stuff defined by this makefile.
+ifeq (,$(ONE_SHOT_MAKEFILE))
+include $(call first-makefiles-under,$(LOCAL_PATH))
+endif
diff --git a/media/libstagefright/tests/DummyRecorder.cpp b/media/libstagefright/tests/DummyRecorder.cpp
new file mode 100644
index 0000000..8d75d6b
--- /dev/null
+++ b/media/libstagefright/tests/DummyRecorder.cpp
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2011 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_TAG "DummyRecorder"
+// #define LOG_NDEBUG 0
+
+#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/MediaSource.h>
+#include "DummyRecorder.h"
+
+#include <utils/Log.h>
+
+namespace android {
+
+// static
+void *DummyRecorder::threadWrapper(void *pthis) {
+ LOGV("ThreadWrapper: %p", pthis);
+ DummyRecorder *writer = static_cast<DummyRecorder *>(pthis);
+ writer->readFromSource();
+ return NULL;
+}
+
+
+status_t DummyRecorder::start() {
+ LOGV("Start");
+ mStarted = true;
+
+ mSource->start();
+
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+ int err = pthread_create(&mThread, &attr, threadWrapper, this);
+ pthread_attr_destroy(&attr);
+
+ if (err) {
+ LOGE("Error creating thread!");
+ return -ENODEV;
+ }
+ return OK;
+}
+
+
+status_t DummyRecorder::stop() {
+ LOGV("Stop");
+ mStarted = false;
+
+ mSource->stop();
+ void *dummy;
+ pthread_join(mThread, &dummy);
+ status_t err = (status_t) dummy;
+
+ LOGV("Ending the reading thread");
+ return err;
+}
+
+// pretend to read the source buffers
+void DummyRecorder::readFromSource() {
+ LOGV("ReadFromSource");
+ if (!mStarted) {
+ return;
+ }
+
+ status_t err = OK;
+ MediaBuffer *buffer;
+ LOGV("A fake writer accessing the frames");
+ while (mStarted && (err = mSource->read(&buffer)) == OK){
+ // if not getting a valid buffer from source, then exit
+ if (buffer == NULL) {
+ return;
+ }
+ buffer->release();
+ buffer = NULL;
+ }
+}
+
+
+} // end of namespace android
diff --git a/media/libstagefright/tests/DummyRecorder.h b/media/libstagefright/tests/DummyRecorder.h
new file mode 100644
index 0000000..1cbea1b
--- /dev/null
+++ b/media/libstagefright/tests/DummyRecorder.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2011 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 DUMMY_RECORDER_H_
+#define DUMMY_RECORDER_H_
+
+#include <pthread.h>
+#include <utils/String8.h>
+#include <media/stagefright/foundation/ABase.h>
+
+
+namespace android {
+
+class MediaSource;
+class MediaBuffer;
+
+class DummyRecorder {
+ public:
+ // The media source from which this will receive frames
+ sp<MediaSource> mSource;
+ bool mStarted;
+ pthread_t mThread;
+
+ status_t start();
+ status_t stop();
+
+ // actual entry point for the thread
+ void readFromSource();
+
+ // static function to wrap the actual thread entry point
+ static void *threadWrapper(void *pthis);
+
+ DummyRecorder(const sp<MediaSource> &source) : mSource(source)
+ , mStarted(false) {}
+ ~DummyRecorder( ) {}
+
+ private:
+
+ DISALLOW_EVIL_CONSTRUCTORS(DummyRecorder);
+};
+
+} // end of namespace android
+#endif
+
+
diff --git a/media/libstagefright/tests/SurfaceMediaSource_test.cpp b/media/libstagefright/tests/SurfaceMediaSource_test.cpp
new file mode 100644
index 0000000..5b32b68
--- /dev/null
+++ b/media/libstagefright/tests/SurfaceMediaSource_test.cpp
@@ -0,0 +1,349 @@
+/*
+ * Copyright (C) 2011 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_TAG "SurfaceMediaSource_test"
+// #define LOG_NDEBUG 0
+
+#include <gtest/gtest.h>
+#include <utils/String8.h>
+#include <utils/Errors.h>
+
+#include <media/stagefright/SurfaceMediaSource.h>
+
+#include <gui/SurfaceTextureClient.h>
+#include <ui/GraphicBuffer.h>
+#include <surfaceflinger/ISurfaceComposer.h>
+#include <surfaceflinger/Surface.h>
+#include <surfaceflinger/SurfaceComposerClient.h>
+
+#include <binder/ProcessState.h>
+#include <ui/FramebufferNativeWindow.h>
+
+#include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/MPEG4Writer.h>
+#include <media/stagefright/OMXClient.h>
+#include <media/stagefright/OMXCodec.h>
+#include <OMX_Component.h>
+
+#include "DummyRecorder.h"
+
+namespace android {
+
+
+class SurfaceMediaSourceTest : public ::testing::Test {
+public:
+
+ SurfaceMediaSourceTest( ): mYuvTexWidth(64), mYuvTexHeight(66) { }
+ sp<MPEG4Writer> setUpWriter(OMXClient &client );
+ void oneBufferPass(int width, int height );
+ static void fillYV12Buffer(uint8_t* buf, int w, int h, int stride) ;
+ static void fillYV12BufferRect(uint8_t* buf, int w, int h,
+ int stride, const android_native_rect_t& rect) ;
+protected:
+
+ virtual void SetUp() {
+ android::ProcessState::self()->startThreadPool();
+ mSMS = new SurfaceMediaSource(mYuvTexWidth, mYuvTexHeight);
+ mSMS->setSynchronousMode(true);
+ mSTC = new SurfaceTextureClient(mSMS);
+ mANW = mSTC;
+
+ }
+
+
+ virtual void TearDown() {
+ mSMS.clear();
+ mSTC.clear();
+ mANW.clear();
+ }
+
+ const int mYuvTexWidth;
+ const int mYuvTexHeight;
+
+ sp<SurfaceMediaSource> mSMS;
+ sp<SurfaceTextureClient> mSTC;
+ sp<ANativeWindow> mANW;
+
+};
+
+void SurfaceMediaSourceTest::oneBufferPass(int width, int height ) {
+ LOGV("One Buffer Pass");
+ ANativeWindowBuffer* anb;
+ ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
+ ASSERT_TRUE(anb != NULL);
+
+ sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
+ ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer()));
+
+ // Fill the buffer with the a checkerboard pattern
+ uint8_t* img = NULL;
+ buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
+ SurfaceMediaSourceTest::fillYV12Buffer(img, width, height, buf->getStride());
+ buf->unlock();
+
+ ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
+}
+
+sp<MPEG4Writer> SurfaceMediaSourceTest::setUpWriter(OMXClient &client ) {
+ // Writing to a file
+ const char *fileName = "/sdcard/outputSurfEnc.mp4";
+ sp<MetaData> enc_meta = new MetaData;
+ enc_meta->setInt32(kKeyBitRate, 300000);
+ enc_meta->setInt32(kKeyFrameRate, 30);
+
+ enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
+
+ sp<MetaData> meta = mSMS->getFormat();
+
+ int32_t width, height, stride, sliceHeight, colorFormat;
+ CHECK(meta->findInt32(kKeyWidth, &width));
+ CHECK(meta->findInt32(kKeyHeight, &height));
+ CHECK(meta->findInt32(kKeyStride, &stride));
+ CHECK(meta->findInt32(kKeySliceHeight, &sliceHeight));
+ CHECK(meta->findInt32(kKeyColorFormat, &colorFormat));
+
+ enc_meta->setInt32(kKeyWidth, width);
+ enc_meta->setInt32(kKeyHeight, height);
+ enc_meta->setInt32(kKeyIFramesInterval, 1);
+ enc_meta->setInt32(kKeyStride, stride);
+ enc_meta->setInt32(kKeySliceHeight, sliceHeight);
+ // TODO: overwriting the colorformat since the format set by GRAlloc
+ // could be wrong or not be read by OMX
+ enc_meta->setInt32(kKeyColorFormat, OMX_COLOR_FormatYUV420Planar);
+
+
+ sp<MediaSource> encoder =
+ OMXCodec::Create(
+ client.interface(), enc_meta, true /* createEncoder */, mSMS);
+
+ sp<MPEG4Writer> writer = new MPEG4Writer(fileName);
+ writer->addSource(encoder);
+
+ return writer;
+}
+
+// Fill a YV12 buffer with a multi-colored checkerboard pattern
+void SurfaceMediaSourceTest::fillYV12Buffer(uint8_t* buf, int w, int h, int stride) {
+ const int blockWidth = w > 16 ? w / 16 : 1;
+ const int blockHeight = h > 16 ? h / 16 : 1;
+ const int yuvTexOffsetY = 0;
+ int yuvTexStrideY = stride;
+ int yuvTexOffsetV = yuvTexStrideY * h;
+ int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
+ int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * h/2;
+ int yuvTexStrideU = yuvTexStrideV;
+ for (int x = 0; x < w; x++) {
+ for (int y = 0; y < h; y++) {
+ int parityX = (x / blockWidth) & 1;
+ int parityY = (y / blockHeight) & 1;
+ unsigned char intensity = (parityX ^ parityY) ? 63 : 191;
+ buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = intensity;
+ if (x < w / 2 && y < h / 2) {
+ buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = intensity;
+ if (x * 2 < w / 2 && y * 2 < h / 2) {
+ buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 0] =
+ buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 1] =
+ buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 0] =
+ buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 1] =
+ intensity;
+ }
+ }
+ }
+ }
+}
+
+// Fill a YV12 buffer with red outside a given rectangle and green inside it.
+void SurfaceMediaSourceTest::fillYV12BufferRect(uint8_t* buf, int w,
+ int h, int stride, const android_native_rect_t& rect) {
+ const int yuvTexOffsetY = 0;
+ int yuvTexStrideY = stride;
+ int yuvTexOffsetV = yuvTexStrideY * h;
+ int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
+ int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * h/2;
+ int yuvTexStrideU = yuvTexStrideV;
+ for (int x = 0; x < w; x++) {
+ for (int y = 0; y < h; y++) {
+ bool inside = rect.left <= x && x < rect.right &&
+ rect.top <= y && y < rect.bottom;
+ buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = inside ? 240 : 64;
+ if (x < w / 2 && y < h / 2) {
+ bool inside = rect.left <= 2*x && 2*x < rect.right &&
+ rect.top <= 2*y && 2*y < rect.bottom;
+ buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = 16;
+ buf[yuvTexOffsetV + (y * yuvTexStrideV) + x] =
+ inside ? 16 : 255;
+ }
+ }
+ }
+} ///////// End of class SurfaceMediaSourceTest
+
+///////////////////////////////////////////////////////////////////
+// Class to imitate the recording /////////////////////////////
+// ////////////////////////////////////////////////////////////////
+struct SimpleDummyRecorder {
+ sp<MediaSource> mSource;
+
+ SimpleDummyRecorder
+ (const sp<MediaSource> &source): mSource(source) {}
+
+ status_t start() { return mSource->start();}
+ status_t stop() { return mSource->stop();}
+
+ // fakes reading from a media source
+ status_t readFromSource() {
+ MediaBuffer *buffer;
+ status_t err = mSource->read(&buffer);
+ if (err != OK) {
+ return err;
+ }
+ buffer->release();
+ buffer = NULL;
+ return OK;
+ }
+};
+
+///////////////////////////////////////////////////////////////////
+// TESTS
+// Just pass one buffer from the native_window to the SurfaceMediaSource
+TEST_F(SurfaceMediaSourceTest, EncodingFromCpuFilledYV12BufferNpotOneBufferPass) {
+ LOGV("Testing OneBufferPass ******************************");
+
+ ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
+ 0, 0, HAL_PIXEL_FORMAT_YV12));
+ ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
+ GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+
+ oneBufferPass(mYuvTexWidth, mYuvTexHeight);
+}
+
+// Pass the buffer with the wrong height and weight and should not be accepted
+TEST_F(SurfaceMediaSourceTest, EncodingFromCpuFilledYV12BufferNpotWrongSizeBufferPass) {
+ LOGV("Testing Wrong size BufferPass ******************************");
+
+ // setting the client side buffer size different than the server size
+ ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
+ 10, 10, HAL_PIXEL_FORMAT_YV12));
+ ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
+ GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+
+ ANativeWindowBuffer* anb;
+
+ // make sure we get an error back when dequeuing!
+ ASSERT_NE(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
+}
+
+
+// pass multiple buffers from the native_window the SurfaceMediaSource
+// A dummy writer is used to simulate actual MPEG4Writer
+TEST_F(SurfaceMediaSourceTest, EncodingFromCpuFilledYV12BufferNpotMultiBufferPass) {
+ LOGV("Testing MultiBufferPass, Dummy Recorder *********************");
+ ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
+ 0, 0, HAL_PIXEL_FORMAT_YV12));
+ ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
+ GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+
+ SimpleDummyRecorder writer(mSMS);
+ writer.start();
+
+ int32_t nFramesCount = 0;
+ while (nFramesCount < 300) {
+ oneBufferPass(mYuvTexWidth, mYuvTexHeight);
+
+ ASSERT_EQ(NO_ERROR, writer.readFromSource());
+
+ nFramesCount++;
+ }
+ writer.stop();
+}
+
+// Delayed pass of multiple buffers from the native_window the SurfaceMediaSource
+// A dummy writer is used to simulate actual MPEG4Writer
+TEST_F(SurfaceMediaSourceTest, EncodingFromCpuFilledYV12BufferNpotMultiBufferPassLag) {
+ LOGV("Testing MultiBufferPass, Dummy Recorder Lagging **************");
+
+ ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
+ 0, 0, HAL_PIXEL_FORMAT_YV12));
+ ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
+ GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+
+ SimpleDummyRecorder writer(mSMS);
+ writer.start();
+
+ int32_t nFramesCount = 1;
+ const int FRAMES_LAG = mSMS->getBufferCount() - 1;
+ while (nFramesCount <= 300) {
+ oneBufferPass(mYuvTexWidth, mYuvTexHeight);
+ // Forcing the writer to lag behind a few frames
+ if (nFramesCount > FRAMES_LAG) {
+ ASSERT_EQ(NO_ERROR, writer.readFromSource());
+ }
+ nFramesCount++;
+ }
+ writer.stop();
+}
+
+// pass multiple buffers from the native_window the SurfaceMediaSource
+// A dummy writer (MULTITHREADED) is used to simulate actual MPEG4Writer
+TEST_F(SurfaceMediaSourceTest, EncodingFromCpuFilledYV12BufferNpotMultiBufferPassThreaded) {
+ LOGV("Testing MultiBufferPass, Dummy Recorder Multi-Threaded **********");
+ ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
+ 0, 0, HAL_PIXEL_FORMAT_YV12));
+ ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
+ GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+
+ DummyRecorder writer(mSMS);
+ writer.start();
+
+ int32_t nFramesCount = 0;
+ while (nFramesCount <= 300) {
+ oneBufferPass(mYuvTexWidth, mYuvTexHeight);
+
+ nFramesCount++;
+ }
+ writer.stop();
+}
+
+// Test to examine the actual encoding. Temporarily disabled till the
+// colorformat and encoding from GRAlloc data is resolved
+TEST_F(SurfaceMediaSourceTest, DISABLED_EncodingFromCpuFilledYV12BufferNpotWrite) {
+ LOGV("Testing the whole pipeline with actual Recorder");
+ ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
+ 0, 0, HAL_PIXEL_FORMAT_YV12));
+ ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
+ GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+ OMXClient client;
+ CHECK_EQ(OK, client.connect());
+
+ sp<MPEG4Writer> writer = setUpWriter(client);
+ int64_t start = systemTime();
+ CHECK_EQ(OK, writer->start());
+
+ int32_t nFramesCount = 0;
+ while (nFramesCount <= 300) {
+ oneBufferPass(mYuvTexWidth, mYuvTexHeight);
+ nFramesCount++;
+ }
+
+ CHECK_EQ(OK, writer->stop());
+ writer.clear();
+ int64_t end = systemTime();
+ client.disconnect();
+}
+
+
+} // namespace android
diff --git a/media/libstagefright/timedtext/Android.mk b/media/libstagefright/timedtext/Android.mk
new file mode 100644
index 0000000..59d0e15
--- /dev/null
+++ b/media/libstagefright/timedtext/Android.mk
@@ -0,0 +1,17 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ TextDescriptions.cpp \
+ TimedTextParser.cpp \
+ TimedTextPlayer.cpp
+
+LOCAL_CFLAGS += -Wno-multichar
+LOCAL_C_INCLUDES:= \
+ $(JNI_H_INCLUDE) \
+ $(TOP)/frameworks/base/media/libstagefright \
+ $(TOP)/frameworks/base/include/media/stagefright/openmax
+
+LOCAL_MODULE:= libstagefright_timedtext
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/media/libstagefright/timedtext/TextDescriptions.cpp b/media/libstagefright/timedtext/TextDescriptions.cpp
new file mode 100644
index 0000000..f9c1fe0
--- /dev/null
+++ b/media/libstagefright/timedtext/TextDescriptions.cpp
@@ -0,0 +1,385 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#include "TextDescriptions.h"
+#include <media/stagefright/Utils.h>
+#include <media/stagefright/MediaErrors.h>
+
+namespace android {
+
+TextDescriptions::TextDescriptions() {
+}
+
+status_t TextDescriptions::getParcelOfDescriptions(
+ const uint8_t *data, ssize_t size,
+ uint32_t flags, int timeMs, Parcel *parcel) {
+ parcel->freeData();
+
+ if (flags & IN_BAND_TEXT_3GPP) {
+ if (flags & GLOBAL_DESCRIPTIONS) {
+ return extract3GPPGlobalDescriptions(data, size, parcel, 0);
+ } else if (flags & LOCAL_DESCRIPTIONS) {
+ return extract3GPPLocalDescriptions(data, size, timeMs, parcel, 0);
+ }
+ } else if (flags & OUT_OF_BAND_TEXT_SRT) {
+ if (flags & LOCAL_DESCRIPTIONS) {
+ return extractSRTLocalDescriptions(data, size, timeMs, parcel);
+ }
+ }
+
+ return ERROR_UNSUPPORTED;
+}
+
+// Parse the SRT text sample, and store the timing and text sample in a Parcel.
+// The Parcel will be sent to MediaPlayer.java through event, and will be
+// parsed in TimedText.java.
+status_t TextDescriptions::extractSRTLocalDescriptions(
+ const uint8_t *data, ssize_t size, int timeMs, Parcel *parcel) {
+ parcel->writeInt32(KEY_LOCAL_SETTING);
+ parcel->writeInt32(KEY_START_TIME);
+ parcel->writeInt32(timeMs);
+
+ parcel->writeInt32(KEY_STRUCT_TEXT);
+ // write the size of the text sample
+ parcel->writeInt32(size);
+ // write the text sample as a byte array
+ parcel->writeInt32(size);
+ parcel->write(data, size);
+
+ return OK;
+}
+
+// Extract the local 3GPP display descriptions. 3GPP local descriptions
+// are appended to the text sample if any. The descriptions could include
+// information such as text styles, highlights, karaoke and so on. They
+// are contained in different boxes, such as 'styl' box contains text
+// styles, and 'krok' box contains karaoke timing and positions.
+status_t TextDescriptions::extract3GPPLocalDescriptions(
+ const uint8_t *data, ssize_t size,
+ int timeMs, Parcel *parcel, int depth) {
+ if (depth == 0) {
+ parcel->writeInt32(KEY_LOCAL_SETTING);
+
+ // write start time to display this text sample
+ parcel->writeInt32(KEY_START_TIME);
+ parcel->writeInt32(timeMs);
+
+ ssize_t textLen = (*data) << 8 | (*(data + 1));
+
+ // write text sample length and text sample itself
+ parcel->writeInt32(KEY_STRUCT_TEXT);
+ parcel->writeInt32(textLen);
+ parcel->writeInt32(textLen);
+ parcel->write(data + 2, textLen);
+
+ if (size > textLen) {
+ data += (textLen + 2);
+ size -= (textLen + 2);
+ } else {
+ return OK;
+ }
+ }
+
+ const uint8_t *tmpData = data;
+ ssize_t chunkSize = U32_AT(tmpData);
+ uint32_t chunkType = U32_AT(tmpData + 4);
+
+ if (chunkSize <= 0) {
+ return OK;
+ }
+
+ tmpData += 8;
+
+ switch(chunkType) {
+ // 'styl' box specifies the style of the text.
+ case FOURCC('s', 't', 'y', 'l'):
+ {
+ uint16_t count = U16_AT(tmpData);
+
+ tmpData += 2;
+
+ for (int i = 0; i < count; i++) {
+ parcel->writeInt32(KEY_STRUCT_STYLE_LIST);
+ parcel->writeInt32(KEY_START_CHAR);
+ parcel->writeInt32(U16_AT(tmpData));
+
+ parcel->writeInt32(KEY_END_CHAR);
+ parcel->writeInt32(U16_AT(tmpData + 2));
+
+ parcel->writeInt32(KEY_FONT_ID);
+ parcel->writeInt32(U16_AT(tmpData + 4));
+
+ parcel->writeInt32(KEY_STYLE_FLAGS);
+ parcel->writeInt32(*(tmpData + 6));
+
+ parcel->writeInt32(KEY_FONT_SIZE);
+ parcel->writeInt32(*(tmpData + 7));
+
+ parcel->writeInt32(KEY_TEXT_COLOR_RGBA);
+ uint32_t rgba = *(tmpData + 8) << 24 | *(tmpData + 9) << 16
+ | *(tmpData + 10) << 8 | *(tmpData + 11);
+ parcel->writeInt32(rgba);
+
+ tmpData += 12;
+ }
+
+ break;
+ }
+ // 'krok' box. The number of highlight events is specified, and each
+ // event is specified by a starting and ending char offset and an end
+ // time for the event.
+ case FOURCC('k', 'r', 'o', 'k'):
+ {
+
+ parcel->writeInt32(KEY_STRUCT_KARAOKE_LIST);
+
+ int startTime = U32_AT(tmpData);
+ uint16_t count = U16_AT(tmpData + 4);
+ parcel->writeInt32(count);
+
+ tmpData += 6;
+ int lastEndTime = 0;
+
+ for (int i = 0; i < count; i++) {
+ parcel->writeInt32(startTime + lastEndTime);
+
+ lastEndTime = U32_AT(tmpData);
+ parcel->writeInt32(lastEndTime);
+
+ parcel->writeInt32(U16_AT(tmpData + 4));
+ parcel->writeInt32(U16_AT(tmpData + 6));
+
+ tmpData += 8;
+ }
+
+ break;
+ }
+ // 'hlit' box specifies highlighted text
+ case FOURCC('h', 'l', 'i', 't'):
+ {
+ parcel->writeInt32(KEY_STRUCT_HIGHLIGHT_LIST);
+
+ // the start char offset to highlight
+ parcel->writeInt32(U16_AT(tmpData));
+ // the last char offset to highlight
+ parcel->writeInt32(U16_AT(tmpData + 2));
+
+ break;
+ }
+ // 'hclr' box specifies the RGBA color: 8 bits each of
+ // red, green, blue, and an alpha(transparency) value
+ case FOURCC('h', 'c', 'l', 'r'):
+ {
+ parcel->writeInt32(KEY_HIGHLIGHT_COLOR_RGBA);
+
+ uint32_t rgba = *(tmpData) << 24 | *(tmpData + 1) << 16
+ | *(tmpData + 2) << 8 | *(tmpData + 3);
+ parcel->writeInt32(rgba);
+
+ break;
+ }
+ // 'dlay' box specifies a delay after a scroll in and/or
+ // before scroll out.
+ case FOURCC('d', 'l', 'a', 'y'):
+ {
+ parcel->writeInt32(KEY_SCROLL_DELAY);
+
+ uint32_t delay = *(tmpData) << 24 | *(tmpData + 1) << 16
+ | *(tmpData + 2) << 8 | *(tmpData + 3);
+ parcel->writeInt32(delay);
+
+ break;
+ }
+ // 'href' box for hyper text link
+ case FOURCC('h', 'r', 'e', 'f'):
+ {
+ parcel->writeInt32(KEY_STRUCT_HYPER_TEXT_LIST);
+
+ // the start offset of the text to be linked
+ parcel->writeInt32(U16_AT(tmpData));
+ // the end offset of the text
+ parcel->writeInt32(U16_AT(tmpData + 2));
+
+ // the number of bytes in the following URL
+ int len = *(tmpData + 4);
+ parcel->writeInt32(len);
+
+ // the linked-to URL
+ parcel->writeInt32(len);
+ parcel->write(tmpData + 5, len);
+
+ tmpData += (5 + len);
+
+ // the number of bytes in the following "alt" string
+ len = *tmpData;
+ parcel->writeInt32(len);
+
+ // an "alt" string for user display
+ parcel->writeInt32(len);
+ parcel->write(tmpData + 1, len);
+
+ break;
+ }
+ // 'tbox' box to indicate the position of the text with values
+ // of top, left, bottom and right
+ case FOURCC('t', 'b', 'o', 'x'):
+ {
+ parcel->writeInt32(KEY_STRUCT_TEXT_POS);
+ parcel->writeInt32(U16_AT(tmpData));
+ parcel->writeInt32(U16_AT(tmpData + 2));
+ parcel->writeInt32(U16_AT(tmpData + 4));
+ parcel->writeInt32(U16_AT(tmpData + 6));
+
+ break;
+ }
+ // 'blnk' to specify the char range to be blinked
+ case FOURCC('b', 'l', 'n', 'k'):
+ {
+ parcel->writeInt32(KEY_STRUCT_BLINKING_TEXT_LIST);
+
+ // start char offset
+ parcel->writeInt32(U16_AT(tmpData));
+ // end char offset
+ parcel->writeInt32(U16_AT(tmpData + 2));
+
+ break;
+ }
+ // 'twrp' box specifies text wrap behavior. If the value if 0x00,
+ // then no wrap. If it's 0x01, then automatic 'soft' wrap is enabled.
+ // 0x02-0xff are reserved.
+ case FOURCC('t', 'w', 'r', 'p'):
+ {
+ parcel->writeInt32(KEY_WRAP_TEXT);
+ parcel->writeInt32(*tmpData);
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ if (size > chunkSize) {
+ data += chunkSize;
+ size -= chunkSize;
+ // continue to parse next box
+ return extract3GPPLocalDescriptions(data, size, 0, parcel, 1);
+ }
+
+ return OK;
+}
+
+// To extract box 'tx3g' defined in 3GPP TS 26.245, and store it in a Parcel
+status_t TextDescriptions::extract3GPPGlobalDescriptions(
+ const uint8_t *data, ssize_t size, Parcel *parcel, int depth) {
+
+ ssize_t chunkSize = U32_AT(data);
+ uint32_t chunkType = U32_AT(data + 4);
+ const uint8_t *tmpData = data;
+ tmpData += 8;
+
+ if (size < chunkSize) {
+ return OK;
+ }
+
+ if (depth == 0) {
+ parcel->writeInt32(KEY_GLOBAL_SETTING);
+ }
+ switch(chunkType) {
+ case FOURCC('t', 'x', '3', 'g'):
+ {
+ tmpData += 8; // skip the first 8 bytes
+ parcel->writeInt32(KEY_DISPLAY_FLAGS);
+ parcel->writeInt32(U32_AT(tmpData));
+
+ parcel->writeInt32(KEY_STRUCT_JUSTIFICATION);
+ parcel->writeInt32(tmpData[4]);
+ parcel->writeInt32(tmpData[5]);
+
+ parcel->writeInt32(KEY_BACKGROUND_COLOR_RGBA);
+ uint32_t rgba = *(tmpData + 6) << 24 | *(tmpData + 7) << 16
+ | *(tmpData + 8) << 8 | *(tmpData + 9);
+ parcel->writeInt32(rgba);
+
+ tmpData += 10;
+ parcel->writeInt32(KEY_STRUCT_TEXT_POS);
+ parcel->writeInt32(U16_AT(tmpData));
+ parcel->writeInt32(U16_AT(tmpData + 2));
+ parcel->writeInt32(U16_AT(tmpData + 4));
+ parcel->writeInt32(U16_AT(tmpData + 6));
+
+ tmpData += 8;
+ parcel->writeInt32(KEY_STRUCT_STYLE_LIST);
+ parcel->writeInt32(KEY_START_CHAR);
+ parcel->writeInt32(U16_AT(tmpData));
+
+ parcel->writeInt32(KEY_END_CHAR);
+ parcel->writeInt32(U16_AT(tmpData + 2));
+
+ parcel->writeInt32(KEY_FONT_ID);
+ parcel->writeInt32(U16_AT(tmpData + 4));
+
+ parcel->writeInt32(KEY_STYLE_FLAGS);
+ parcel->writeInt32(*(tmpData + 6));
+
+ parcel->writeInt32(KEY_FONT_SIZE);
+ parcel->writeInt32(*(tmpData + 7));
+
+ parcel->writeInt32(KEY_TEXT_COLOR_RGBA);
+ rgba = *(tmpData + 8) << 24 | *(tmpData + 9) << 16
+ | *(tmpData + 10) << 8 | *(tmpData + 11);
+ parcel->writeInt32(rgba);
+
+ tmpData += 12;
+ parcel->writeInt32(KEY_STRUCT_FONT_LIST);
+ uint16_t count = U16_AT(tmpData);
+ parcel->writeInt32(count);
+
+ tmpData += 2;
+ for (int i = 0; i < count; i++) {
+ // font ID
+ parcel->writeInt32(U16_AT(tmpData));
+
+ // font name length
+ parcel->writeInt32(*(tmpData + 2));
+
+ int len = *(tmpData + 2);
+
+ parcel->write(tmpData + 3, len);
+ tmpData += 3 + len;
+ }
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ data += chunkSize;
+ size -= chunkSize;
+
+ if (size > 0) {
+ // continue to extract next 'tx3g'
+ return extract3GPPGlobalDescriptions(data, size, parcel, 1);
+ }
+
+ return OK;
+}
+
+} // namespace android
diff --git a/media/libstagefright/timedtext/TextDescriptions.h b/media/libstagefright/timedtext/TextDescriptions.h
new file mode 100644
index 0000000..0144917
--- /dev/null
+++ b/media/libstagefright/timedtext/TextDescriptions.h
@@ -0,0 +1,84 @@
+ /*
+ * Copyright (C) 2011 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 TEXT_DESCRIPTIONS_H_
+
+#define TEXT_DESCRIPTIONS_H_
+
+#include <binder/Parcel.h>
+#include <media/stagefright/foundation/ABase.h>
+
+namespace android {
+
+class TextDescriptions {
+public:
+ enum {
+ IN_BAND_TEXT_3GPP = 0x01,
+ OUT_OF_BAND_TEXT_SRT = 0x02,
+
+ GLOBAL_DESCRIPTIONS = 0x100,
+ LOCAL_DESCRIPTIONS = 0x200,
+ };
+
+ static status_t getParcelOfDescriptions(
+ const uint8_t *data, ssize_t size,
+ uint32_t flags, int timeMs, Parcel *parcel);
+private:
+ TextDescriptions();
+
+ enum {
+ // These keys must be in sync with the keys in TimedText.java
+ KEY_DISPLAY_FLAGS = 1, // int
+ KEY_STYLE_FLAGS = 2, // int
+ KEY_BACKGROUND_COLOR_RGBA = 3, // int
+ KEY_HIGHLIGHT_COLOR_RGBA = 4, // int
+ KEY_SCROLL_DELAY = 5, // int
+ KEY_WRAP_TEXT = 6, // int
+ KEY_START_TIME = 7, // int
+ KEY_STRUCT_BLINKING_TEXT_LIST = 8, // List<CharPos>
+ KEY_STRUCT_FONT_LIST = 9, // List<Font>
+ KEY_STRUCT_HIGHLIGHT_LIST = 10, // List<CharPos>
+ KEY_STRUCT_HYPER_TEXT_LIST = 11, // List<HyperText>
+ KEY_STRUCT_KARAOKE_LIST = 12, // List<Karaoke>
+ KEY_STRUCT_STYLE_LIST = 13, // List<Style>
+ KEY_STRUCT_TEXT_POS = 14, // TextPos
+ KEY_STRUCT_JUSTIFICATION = 15, // Justification
+ KEY_STRUCT_TEXT = 16, // Text
+
+ KEY_GLOBAL_SETTING = 101,
+ KEY_LOCAL_SETTING = 102,
+ KEY_START_CHAR = 103,
+ KEY_END_CHAR = 104,
+ KEY_FONT_ID = 105,
+ KEY_FONT_SIZE = 106,
+ KEY_TEXT_COLOR_RGBA = 107,
+ };
+
+ static status_t extractSRTLocalDescriptions(
+ const uint8_t *data, ssize_t size,
+ int timeMs, Parcel *parcel);
+ static status_t extract3GPPGlobalDescriptions(
+ const uint8_t *data, ssize_t size,
+ Parcel *parcel, int depth);
+ static status_t extract3GPPLocalDescriptions(
+ const uint8_t *data, ssize_t size,
+ int timeMs, Parcel *parcel, int depth);
+
+ DISALLOW_EVIL_CONSTRUCTORS(TextDescriptions);
+};
+
+} // namespace android
+#endif // TEXT_DESCRIPTIONS_H_
diff --git a/media/libstagefright/timedtext/TimedTextParser.cpp b/media/libstagefright/timedtext/TimedTextParser.cpp
new file mode 100644
index 0000000..0bada16
--- /dev/null
+++ b/media/libstagefright/timedtext/TimedTextParser.cpp
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#include "TimedTextParser.h"
+#include <media/stagefright/DataSource.h>
+
+namespace android {
+
+TimedTextParser::TimedTextParser()
+ : mDataSource(NULL),
+ mOffset(0),
+ mIndex(0) {
+}
+
+TimedTextParser::~TimedTextParser() {
+ reset();
+}
+
+status_t TimedTextParser::init(
+ const sp<DataSource> &dataSource, FileType fileType) {
+ mDataSource = dataSource;
+ mFileType = fileType;
+
+ status_t err;
+ if ((err = scanFile()) != OK) {
+ reset();
+ return err;
+ }
+
+ return OK;
+}
+
+void TimedTextParser::reset() {
+ mDataSource.clear();
+ mTextVector.clear();
+ mOffset = 0;
+ mIndex = 0;
+}
+
+// scan the text file to get start/stop time and the
+// offset of each piece of text content
+status_t TimedTextParser::scanFile() {
+ if (mFileType != OUT_OF_BAND_FILE_SRT) {
+ return ERROR_UNSUPPORTED;
+ }
+
+ off64_t offset = 0;
+ int64_t startTimeUs;
+ bool endOfFile = false;
+
+ while (!endOfFile) {
+ TextInfo info;
+ status_t err = getNextInSrtFileFormat(&offset, &startTimeUs, &info);
+
+ if (err != OK) {
+ if (err == ERROR_END_OF_STREAM) {
+ endOfFile = true;
+ } else {
+ return err;
+ }
+ } else {
+ mTextVector.add(startTimeUs, info);
+ }
+ }
+
+ if (mTextVector.isEmpty()) {
+ return ERROR_MALFORMED;
+ }
+ return OK;
+}
+
+// read one line started from *offset and store it into data.
+status_t TimedTextParser::readNextLine(off64_t *offset, AString *data) {
+ char character;
+
+ data->clear();
+
+ while (true) {
+ ssize_t err;
+ if ((err = mDataSource->readAt(*offset, &character, 1)) < 1) {
+ if (err == 0) {
+ return ERROR_END_OF_STREAM;
+ }
+ return ERROR_IO;
+ }
+
+ (*offset) ++;
+
+ // a line could end with CR, LF or CR + LF
+ if (character == 10) {
+ break;
+ } else if (character == 13) {
+ if ((err = mDataSource->readAt(*offset, &character, 1)) < 1) {
+ if (err == 0) { // end of the stream
+ return OK;
+ }
+ return ERROR_IO;
+ }
+
+ (*offset) ++;
+
+ if (character != 10) {
+ (*offset) --;
+ }
+ break;
+ }
+
+ data->append(character);
+ }
+
+ return OK;
+}
+
+/* SRT format:
+ * Subtitle number
+ * Start time --> End time
+ * Text of subtitle (one or more lines)
+ * Blank line
+ *
+ * .srt file example:
+ * 1
+ * 00:00:20,000 --> 00:00:24,400
+ * Altocumulus clouds occur between six thousand
+ *
+ * 2
+ * 00:00:24,600 --> 00:00:27,800
+ * and twenty thousand feet above ground level.
+ */
+status_t TimedTextParser::getNextInSrtFileFormat(
+ off64_t *offset, int64_t *startTimeUs, TextInfo *info) {
+ AString data;
+ status_t err;
+ if ((err = readNextLine(offset, &data)) != OK) {
+ return err;
+ }
+
+ // to skip the first line
+ if ((err = readNextLine(offset, &data)) != OK) {
+ return err;
+ }
+
+ int hour1, hour2, min1, min2, sec1, sec2, msec1, msec2;
+ // the start time format is: hours:minutes:seconds,milliseconds
+ // 00:00:24,600 --> 00:00:27,800
+ if (sscanf(data.c_str(), "%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d",
+ &hour1, &min1, &sec1, &msec1, &hour2, &min2, &sec2, &msec2) != 8) {
+ return ERROR_MALFORMED;
+ }
+
+ *startTimeUs = ((hour1 * 3600 + min1 * 60 + sec1) * 1000 + msec1) * 1000ll;
+ info->endTimeUs = ((hour2 * 3600 + min2 * 60 + sec2) * 1000 + msec2) * 1000ll;
+ if (info->endTimeUs <= *startTimeUs) {
+ return ERROR_MALFORMED;
+ }
+
+ info->offset = *offset;
+
+ bool needMoreData = true;
+ while (needMoreData) {
+ if ((err = readNextLine(offset, &data)) != OK) {
+ if (err == ERROR_END_OF_STREAM) {
+ needMoreData = false;
+ } else {
+ return err;
+ }
+ }
+
+ if (needMoreData) {
+ data.trim();
+ if (data.empty()) {
+ // it's an empty line used to separate two subtitles
+ needMoreData = false;
+ }
+ }
+ }
+
+ info->textLen = *offset - info->offset;
+
+ return OK;
+}
+
+status_t TimedTextParser::getText(
+ AString *text, int64_t *startTimeUs, int64_t *endTimeUs,
+ const MediaSource::ReadOptions *options) {
+ Mutex::Autolock autoLock(mLock);
+
+ text->clear();
+
+ int64_t seekTimeUs;
+ MediaSource::ReadOptions::SeekMode mode;
+ if (options && options->getSeekTo(&seekTimeUs, &mode)) {
+ int64_t lastEndTimeUs = mTextVector.valueAt(mTextVector.size() - 1).endTimeUs;
+ int64_t firstStartTimeUs = mTextVector.keyAt(0);
+
+ if (seekTimeUs < 0 || seekTimeUs > lastEndTimeUs) {
+ return ERROR_OUT_OF_RANGE;
+ } else if (seekTimeUs < firstStartTimeUs) {
+ mIndex = 0;
+ } else {
+ // binary search
+ ssize_t low = 0;
+ ssize_t high = mTextVector.size() - 1;
+ ssize_t mid = 0;
+ int64_t currTimeUs;
+
+ while (low <= high) {
+ mid = low + (high - low)/2;
+ currTimeUs = mTextVector.keyAt(mid);
+ const int diff = currTimeUs - seekTimeUs;
+
+ if (diff == 0) {
+ break;
+ } else if (diff < 0) {
+ low = mid + 1;
+ } else {
+ if ((high == mid + 1)
+ && (seekTimeUs < mTextVector.keyAt(high))) {
+ break;
+ }
+ high = mid - 1;
+ }
+ }
+
+ mIndex = mid;
+ }
+ }
+
+ TextInfo info = mTextVector.valueAt(mIndex);
+ *startTimeUs = mTextVector.keyAt(mIndex);
+ *endTimeUs = info.endTimeUs;
+ mIndex ++;
+
+ char *str = new char[info.textLen];
+ if (mDataSource->readAt(info.offset, str, info.textLen) < info.textLen) {
+ delete[] str;
+ return ERROR_IO;
+ }
+
+ text->append(str, info.textLen);
+ delete[] str;
+ return OK;
+}
+
+} // namespace android
diff --git a/media/libstagefright/timedtext/TimedTextParser.h b/media/libstagefright/timedtext/TimedTextParser.h
new file mode 100644
index 0000000..44774c2
--- /dev/null
+++ b/media/libstagefright/timedtext/TimedTextParser.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2011 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 TIMED_TEXT_PARSER_H_
+
+#define TIMED_TEXT_PARSER_H_
+
+#include <media/MediaPlayerInterface.h>
+#include <media/stagefright/foundation/ABase.h>
+#include <media/stagefright/foundation/AString.h>
+#include <media/stagefright/MediaSource.h>
+
+namespace android {
+
+class DataSource;
+
+class TimedTextParser : public RefBase {
+public:
+ TimedTextParser();
+ virtual ~TimedTextParser();
+
+ enum FileType {
+ OUT_OF_BAND_FILE_SRT = 1,
+ };
+
+ status_t getText(AString *text, int64_t *startTimeUs, int64_t *endTimeUs,
+ const MediaSource::ReadOptions *options = NULL);
+ status_t init(const sp<DataSource> &dataSource, FileType fileType);
+ void reset();
+
+private:
+ Mutex mLock;
+
+ sp<DataSource> mDataSource;
+ off64_t mOffset;
+
+ struct TextInfo {
+ int64_t endTimeUs;
+ // the offset of the text in the original file
+ off64_t offset;
+ int textLen;
+ };
+
+ int mIndex;
+ FileType mFileType;
+
+ // the key indicated the start time of the text
+ KeyedVector<int64_t, TextInfo> mTextVector;
+
+ status_t getNextInSrtFileFormat(
+ off64_t *offset, int64_t *startTimeUs, TextInfo *info);
+ status_t readNextLine(off64_t *offset, AString *data);
+
+ status_t scanFile();
+
+ DISALLOW_EVIL_CONSTRUCTORS(TimedTextParser);
+};
+
+} // namespace android
+
+#endif // TIMED_TEXT_PARSER_H_
+
diff --git a/media/libstagefright/timedtext/TimedTextPlayer.cpp b/media/libstagefright/timedtext/TimedTextPlayer.cpp
new file mode 100644
index 0000000..7c8a747
--- /dev/null
+++ b/media/libstagefright/timedtext/TimedTextPlayer.cpp
@@ -0,0 +1,416 @@
+ /*
+ * Copyright (C) 2011 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 "TimedTextPlayer"
+#include <utils/Log.h>
+
+#include <binder/IPCThreadState.h>
+
+#include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/MediaSource.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/FileSource.h>
+#include <media/stagefright/Utils.h>
+
+#include "include/AwesomePlayer.h"
+#include "TimedTextPlayer.h"
+#include "TimedTextParser.h"
+#include "TextDescriptions.h"
+
+namespace android {
+
+struct TimedTextEvent : public TimedEventQueue::Event {
+ TimedTextEvent(
+ TimedTextPlayer *player,
+ void (TimedTextPlayer::*method)())
+ : mPlayer(player),
+ mMethod(method) {
+ }
+
+protected:
+ virtual ~TimedTextEvent() {}
+
+ virtual void fire(TimedEventQueue *queue, int64_t /* now_us */) {
+ (mPlayer->*mMethod)();
+ }
+
+private:
+ TimedTextPlayer *mPlayer;
+ void (TimedTextPlayer::*mMethod)();
+
+ TimedTextEvent(const TimedTextEvent &);
+ TimedTextEvent &operator=(const TimedTextEvent &);
+};
+
+TimedTextPlayer::TimedTextPlayer(
+ AwesomePlayer *observer,
+ const wp<MediaPlayerBase> &listener,
+ TimedEventQueue *queue)
+ : mSource(NULL),
+ mOutOfBandSource(NULL),
+ mSeekTimeUs(0),
+ mStarted(false),
+ mTextEventPending(false),
+ mQueue(queue),
+ mListener(listener),
+ mObserver(observer),
+ mTextBuffer(NULL),
+ mTextParser(NULL),
+ mTextType(kNoText) {
+ mTextEvent = new TimedTextEvent(this, &TimedTextPlayer::onTextEvent);
+}
+
+TimedTextPlayer::~TimedTextPlayer() {
+ if (mStarted) {
+ reset();
+ }
+
+ mTextTrackVector.clear();
+ mTextOutOfBandVector.clear();
+}
+
+status_t TimedTextPlayer::start(uint8_t index) {
+ CHECK(!mStarted);
+
+ if (index >=
+ mTextTrackVector.size() + mTextOutOfBandVector.size()) {
+ LOGE("Incorrect text track index: %d", index);
+ return BAD_VALUE;
+ }
+
+ status_t err;
+ if (index < mTextTrackVector.size()) { // start an in-band text
+ mSource = mTextTrackVector.itemAt(index);
+
+ err = mSource->start();
+
+ if (err != OK) {
+ return err;
+ }
+ mTextType = kInBandText;
+ } else { // start an out-of-band text
+ OutOfBandText text =
+ mTextOutOfBandVector.itemAt(index - mTextTrackVector.size());
+
+ mOutOfBandSource = text.source;
+ TimedTextParser::FileType fileType = text.type;
+
+ if (mTextParser == NULL) {
+ mTextParser = new TimedTextParser();
+ }
+
+ if ((err = mTextParser->init(mOutOfBandSource, fileType)) != OK) {
+ return err;
+ }
+ mTextType = kOutOfBandText;
+ }
+
+ // send sample description format
+ if ((err = extractAndSendGlobalDescriptions()) != OK) {
+ return err;
+ }
+
+ int64_t positionUs;
+ mObserver->getPosition(&positionUs);
+ seekTo(positionUs);
+
+ postTextEvent();
+
+ mStarted = true;
+
+ return OK;
+}
+
+void TimedTextPlayer::pause() {
+ CHECK(mStarted);
+
+ cancelTextEvent();
+}
+
+void TimedTextPlayer::resume() {
+ CHECK(mStarted);
+
+ postTextEvent();
+}
+
+void TimedTextPlayer::reset() {
+ CHECK(mStarted);
+
+ // send an empty text to clear the screen
+ notifyListener(MEDIA_TIMED_TEXT);
+
+ cancelTextEvent();
+
+ mSeeking = false;
+ mStarted = false;
+
+ if (mTextType == kInBandText) {
+ if (mTextBuffer != NULL) {
+ mTextBuffer->release();
+ mTextBuffer = NULL;
+ }
+
+ if (mSource != NULL) {
+ mSource->stop();
+ mSource.clear();
+ mSource = NULL;
+ }
+ } else {
+ if (mTextParser != NULL) {
+ mTextParser.clear();
+ mTextParser = NULL;
+ }
+ if (mOutOfBandSource != NULL) {
+ mOutOfBandSource.clear();
+ mOutOfBandSource = NULL;
+ }
+ }
+}
+
+status_t TimedTextPlayer::seekTo(int64_t time_us) {
+ Mutex::Autolock autoLock(mLock);
+
+ mSeeking = true;
+ mSeekTimeUs = time_us;
+
+ postTextEvent();
+
+ return OK;
+}
+
+status_t TimedTextPlayer::setTimedTextTrackIndex(int32_t index) {
+ if (index >=
+ (int)(mTextTrackVector.size() + mTextOutOfBandVector.size())) {
+ return BAD_VALUE;
+ }
+
+ if (mStarted) {
+ reset();
+ }
+
+ if (index >= 0) {
+ return start(index);
+ }
+ return OK;
+}
+
+void TimedTextPlayer::onTextEvent() {
+ Mutex::Autolock autoLock(mLock);
+
+ if (!mTextEventPending) {
+ return;
+ }
+ mTextEventPending = false;
+
+ if (mData.dataSize() > 0) {
+ notifyListener(MEDIA_TIMED_TEXT, &mData);
+ mData.freeData();
+ }
+
+ MediaSource::ReadOptions options;
+ if (mSeeking) {
+ options.setSeekTo(mSeekTimeUs,
+ MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
+ mSeeking = false;
+
+ notifyListener(MEDIA_TIMED_TEXT); //empty text to clear the screen
+ }
+
+ int64_t positionUs, timeUs;
+ mObserver->getPosition(&positionUs);
+
+ if (mTextType == kInBandText) {
+ if (mSource->read(&mTextBuffer, &options) != OK) {
+ return;
+ }
+
+ mTextBuffer->meta_data()->findInt64(kKeyTime, &timeUs);
+ } else {
+ int64_t endTimeUs;
+ if (mTextParser->getText(
+ &mText, &timeUs, &endTimeUs, &options) != OK) {
+ return;
+ }
+ }
+
+ if (timeUs > 0) {
+ extractAndAppendLocalDescriptions(timeUs);
+ }
+
+ if (mTextType == kInBandText) {
+ if (mTextBuffer != NULL) {
+ mTextBuffer->release();
+ mTextBuffer = NULL;
+ }
+ } else {
+ mText.clear();
+ }
+
+ //send the text now
+ if (timeUs <= positionUs + 100000ll) {
+ postTextEvent();
+ } else {
+ postTextEvent(timeUs - positionUs - 100000ll);
+ }
+}
+
+void TimedTextPlayer::postTextEvent(int64_t delayUs) {
+ if (mTextEventPending) {
+ return;
+ }
+
+ mTextEventPending = true;
+ mQueue->postEventWithDelay(mTextEvent, delayUs < 0 ? 10000 : delayUs);
+}
+
+void TimedTextPlayer::cancelTextEvent() {
+ mQueue->cancelEvent(mTextEvent->eventID());
+ mTextEventPending = false;
+}
+
+void TimedTextPlayer::addTextSource(sp<MediaSource> source) {
+ Mutex::Autolock autoLock(mLock);
+ mTextTrackVector.add(source);
+}
+
+status_t TimedTextPlayer::setParameter(int key, const Parcel &request) {
+ Mutex::Autolock autoLock(mLock);
+
+ if (key == KEY_PARAMETER_TIMED_TEXT_ADD_OUT_OF_BAND_SOURCE) {
+ const String16 uri16 = request.readString16();
+ String8 uri = String8(uri16);
+ KeyedVector<String8, String8> headers;
+
+ // To support local subtitle file only for now
+ if (strncasecmp("file://", uri.string(), 7)) {
+ return INVALID_OPERATION;
+ }
+ sp<DataSource> dataSource =
+ DataSource::CreateFromURI(uri, &headers);
+ status_t err = dataSource->initCheck();
+
+ if (err != OK) {
+ return err;
+ }
+
+ OutOfBandText text;
+ text.source = dataSource;
+ if (uri.getPathExtension() == String8(".srt")) {
+ text.type = TimedTextParser::OUT_OF_BAND_FILE_SRT;
+ } else {
+ return ERROR_UNSUPPORTED;
+ }
+
+ mTextOutOfBandVector.add(text);
+
+ return OK;
+ }
+ return INVALID_OPERATION;
+}
+
+void TimedTextPlayer::notifyListener(int msg, const Parcel *parcel) {
+ if (mListener != NULL) {
+ sp<MediaPlayerBase> listener = mListener.promote();
+
+ if (listener != NULL) {
+ if (parcel && (parcel->dataSize() > 0)) {
+ listener->sendEvent(msg, 0, 0, parcel);
+ } else { // send an empty timed text to clear the screen
+ listener->sendEvent(msg);
+ }
+ }
+ }
+}
+
+// Each text sample consists of a string of text, optionally with sample
+// modifier description. The modifier description could specify a new
+// text style for the string of text. These descriptions are present only
+// if they are needed. This method is used to extract the modifier
+// description and append it at the end of the text.
+status_t TimedTextPlayer::extractAndAppendLocalDescriptions(int64_t timeUs) {
+ const void *data;
+ size_t size = 0;
+ int32_t flag = TextDescriptions::LOCAL_DESCRIPTIONS;
+
+ if (mTextType == kInBandText) {
+ const char *mime;
+ CHECK(mSource->getFormat()->findCString(kKeyMIMEType, &mime));
+
+ if (!strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP)) {
+ flag |= TextDescriptions::IN_BAND_TEXT_3GPP;
+ data = mTextBuffer->data();
+ size = mTextBuffer->size();
+ } else {
+ // support 3GPP only for now
+ return ERROR_UNSUPPORTED;
+ }
+ } else {
+ data = mText.c_str();
+ size = mText.size();
+ flag |= TextDescriptions::OUT_OF_BAND_TEXT_SRT;
+ }
+
+ if ((size > 0) && (flag != TextDescriptions::LOCAL_DESCRIPTIONS)) {
+ mData.freeData();
+ return TextDescriptions::getParcelOfDescriptions(
+ (const uint8_t *)data, size, flag, timeUs / 1000, &mData);
+ }
+
+ return OK;
+}
+
+// To extract and send the global text descriptions for all the text samples
+// in the text track or text file.
+status_t TimedTextPlayer::extractAndSendGlobalDescriptions() {
+ const void *data;
+ size_t size = 0;
+ int32_t flag = TextDescriptions::GLOBAL_DESCRIPTIONS;
+
+ if (mTextType == kInBandText) {
+ const char *mime;
+ CHECK(mSource->getFormat()->findCString(kKeyMIMEType, &mime));
+
+ // support 3GPP only for now
+ if (!strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP)) {
+ uint32_t type;
+ // get the 'tx3g' box content. This box contains the text descriptions
+ // used to render the text track
+ if (!mSource->getFormat()->findData(
+ kKeyTextFormatData, &type, &data, &size)) {
+ return ERROR_MALFORMED;
+ }
+
+ flag |= TextDescriptions::IN_BAND_TEXT_3GPP;
+ }
+ }
+
+ if ((size > 0) && (flag != TextDescriptions::GLOBAL_DESCRIPTIONS)) {
+ Parcel parcel;
+ if (TextDescriptions::getParcelOfDescriptions(
+ (const uint8_t *)data, size, flag, 0, &parcel) == OK) {
+ if (parcel.dataSize() > 0) {
+ notifyListener(MEDIA_TIMED_TEXT, &parcel);
+ }
+ }
+ }
+
+ return OK;
+}
+}
diff --git a/media/libstagefright/timedtext/TimedTextPlayer.h b/media/libstagefright/timedtext/TimedTextPlayer.h
new file mode 100644
index 0000000..a744db5
--- /dev/null
+++ b/media/libstagefright/timedtext/TimedTextPlayer.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2011 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 TIMEDTEXT_PLAYER_H_
+
+#define TIMEDTEXT_PLAYER_H_
+
+#include <media/MediaPlayerInterface.h>
+#include <media/stagefright/foundation/ABase.h>
+#include <media/stagefright/foundation/AString.h>
+
+#include "include/TimedEventQueue.h"
+#include "TimedTextParser.h"
+
+namespace android {
+
+class MediaSource;
+class AwesomePlayer;
+class MediaBuffer;
+
+class TimedTextPlayer {
+public:
+ TimedTextPlayer(AwesomePlayer *observer,
+ const wp<MediaPlayerBase> &listener,
+ TimedEventQueue *queue);
+
+ virtual ~TimedTextPlayer();
+
+ // index: the index of the text track which will
+ // be turned on
+ status_t start(uint8_t index);
+
+ void pause();
+
+ void resume();
+
+ status_t seekTo(int64_t time_us);
+
+ void addTextSource(sp<MediaSource> source);
+
+ status_t setTimedTextTrackIndex(int32_t index);
+ status_t setParameter(int key, const Parcel &request);
+
+private:
+ enum TextType {
+ kNoText = 0,
+ kInBandText = 1,
+ kOutOfBandText = 2,
+ };
+
+ Mutex mLock;
+
+ sp<MediaSource> mSource;
+ sp<DataSource> mOutOfBandSource;
+
+ bool mSeeking;
+ int64_t mSeekTimeUs;
+
+ bool mStarted;
+
+ sp<TimedEventQueue::Event> mTextEvent;
+ bool mTextEventPending;
+
+ TimedEventQueue *mQueue;
+
+ wp<MediaPlayerBase> mListener;
+ AwesomePlayer *mObserver;
+
+ MediaBuffer *mTextBuffer;
+ Parcel mData;
+
+ // for in-band timed text
+ Vector<sp<MediaSource> > mTextTrackVector;
+
+ // for out-of-band timed text
+ struct OutOfBandText {
+ TimedTextParser::FileType type;
+ sp<DataSource> source;
+ };
+ Vector<OutOfBandText > mTextOutOfBandVector;
+
+ sp<TimedTextParser> mTextParser;
+ AString mText;
+
+ TextType mTextType;
+
+ void reset();
+
+ void onTextEvent();
+ void postTextEvent(int64_t delayUs = -1);
+ void cancelTextEvent();
+
+ void notifyListener(int msg, const Parcel *parcel = NULL);
+
+ status_t extractAndAppendLocalDescriptions(int64_t timeUs);
+ status_t extractAndSendGlobalDescriptions();
+
+ DISALLOW_EVIL_CONSTRUCTORS(TimedTextPlayer);
+};
+
+} // namespace android
+
+#endif // TIMEDTEXT_PLAYER_H_
diff --git a/media/libstagefright/yuv/Android.mk b/media/libstagefright/yuv/Android.mk
index 7697e3c..a4253f6 100644
--- a/media/libstagefright/yuv/Android.mk
+++ b/media/libstagefright/yuv/Android.mk
@@ -10,6 +10,6 @@
LOCAL_MODULE:= libstagefright_yuv
-LOCAL_PRELINK_MODULE := false
+
include $(BUILD_SHARED_LIBRARY)
diff --git a/media/mtp/Android.mk b/media/mtp/Android.mk
index c25285e..e590bab 100644
--- a/media/mtp/Android.mk
+++ b/media/mtp/Android.mk
@@ -16,8 +16,6 @@
LOCAL_PATH:= $(call my-dir)
-ifneq ($(TARGET_SIMULATOR),true)
-
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
@@ -45,8 +43,6 @@
include $(BUILD_SHARED_LIBRARY)
-endif
-
ifeq ($(HOST_OS),linux)
include $(CLEAR_VARS)
diff --git a/media/mtp/MtpDataPacket.cpp b/media/mtp/MtpDataPacket.cpp
index 817eac0..20225ba 100644
--- a/media/mtp/MtpDataPacket.cpp
+++ b/media/mtp/MtpDataPacket.cpp
@@ -345,56 +345,28 @@
#ifdef MTP_DEVICE
int MtpDataPacket::read(int fd) {
- // first read the header
- int ret = ::read(fd, mBuffer, MTP_CONTAINER_HEADER_SIZE);
- if (ret != MTP_CONTAINER_HEADER_SIZE)
+ int ret = ::read(fd, mBuffer, mBufferSize);
+ if (ret < MTP_CONTAINER_HEADER_SIZE)
return -1;
- // then the following data
- int total = MtpPacket::getUInt32(MTP_CONTAINER_LENGTH_OFFSET);
- allocate(total);
- int remaining = total - MTP_CONTAINER_HEADER_SIZE;
- ret = ::read(fd, &mBuffer[0] + MTP_CONTAINER_HEADER_SIZE, remaining);
- if (ret != remaining)
- return -1;
-
- mPacketSize = total;
+ mPacketSize = ret;
mOffset = MTP_CONTAINER_HEADER_SIZE;
- return total;
-}
-
-int MtpDataPacket::readDataHeader(int fd) {
- int ret = ::read(fd, mBuffer, MTP_CONTAINER_HEADER_SIZE);
- if (ret > 0)
- mPacketSize = ret;
- else
- mPacketSize = 0;
return ret;
}
int MtpDataPacket::write(int fd) {
MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, mPacketSize);
MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA);
- // send header separately from data
- int ret = ::write(fd, mBuffer, MTP_CONTAINER_HEADER_SIZE);
- if (ret == MTP_CONTAINER_HEADER_SIZE)
- ret = ::write(fd, mBuffer + MTP_CONTAINER_HEADER_SIZE,
- mPacketSize - MTP_CONTAINER_HEADER_SIZE);
- return (ret < 0 ? ret : 0);
-}
-
-int MtpDataPacket::writeDataHeader(int fd, uint32_t length) {
- MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, length);
- MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA);
- int ret = ::write(fd, mBuffer, MTP_CONTAINER_HEADER_SIZE);
+ int ret = ::write(fd, mBuffer, mPacketSize);
return (ret < 0 ? ret : 0);
}
int MtpDataPacket::writeData(int fd, void* data, uint32_t length) {
- MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, length + MTP_CONTAINER_HEADER_SIZE);
+ allocate(length);
+ memcpy(mBuffer + MTP_CONTAINER_HEADER_SIZE, data, length);
+ length += MTP_CONTAINER_HEADER_SIZE;
+ MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, length);
MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA);
- int ret = ::write(fd, mBuffer, MTP_CONTAINER_HEADER_SIZE);
- if (ret == MTP_CONTAINER_HEADER_SIZE)
- ret = ::write(fd, data, length);
+ int ret = ::write(fd, mBuffer, length);
return (ret < 0 ? ret : 0);
}
diff --git a/media/mtp/MtpDataPacket.h b/media/mtp/MtpDataPacket.h
index 8a08948..2b81063 100644
--- a/media/mtp/MtpDataPacket.h
+++ b/media/mtp/MtpDataPacket.h
@@ -41,6 +41,7 @@
void setOperationCode(MtpOperationCode code);
void setTransactionID(MtpTransactionID id);
+ inline const uint8_t* getData() const { return mBuffer + MTP_CONTAINER_HEADER_SIZE; }
inline uint8_t getUInt8() { return (uint8_t)mBuffer[mOffset++]; }
inline int8_t getInt8() { return (int8_t)mBuffer[mOffset++]; }
uint16_t getUInt16();
@@ -95,11 +96,9 @@
#ifdef MTP_DEVICE
// fill our buffer with data from the given file descriptor
int read(int fd);
- int readDataHeader(int fd);
// write our data to the given file descriptor
int write(int fd);
- int writeDataHeader(int fd, uint32_t length);
int writeData(int fd, void* data, uint32_t length);
#endif
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index 4a8fd3e..a9b539b 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -95,10 +95,11 @@
MTP_EVENT_STORE_REMOVED,
};
-MtpServer::MtpServer(int fd, MtpDatabase* database,
+MtpServer::MtpServer(int fd, MtpDatabase* database, bool ptp,
int fileGroup, int filePerm, int directoryPerm)
: mFD(fd),
mDatabase(database),
+ mPtp(ptp),
mFileGroup(fileGroup),
mFilePermission(filePerm),
mDirectoryPermission(directoryPerm),
@@ -236,6 +237,8 @@
if (mSessionOpen)
mDatabase->sessionEnded();
+ close(fd);
+ mFD = -1;
}
void MtpServer::sendObjectAdded(MtpObjectHandle handle) {
@@ -426,9 +429,20 @@
// fill in device info
mData.putUInt16(MTP_STANDARD_VERSION);
- mData.putUInt32(6); // MTP Vendor Extension ID
+ if (mPtp) {
+ mData.putUInt32(0);
+ } else {
+ // MTP Vendor Extension ID
+ mData.putUInt32(6);
+ }
mData.putUInt16(MTP_STANDARD_VERSION);
- string.set("microsoft.com: 1.0; android.com: 1.0;");
+ if (mPtp) {
+ // no extensions
+ string.set("");
+ } else {
+ // MTP extensions
+ string.set("microsoft.com: 1.0; android.com: 1.0;");
+ }
mData.putString(string); // MTP Extensions
mData.putUInt16(0); //Functional Mode
mData.putAUInt16(kSupportedOperationCodes,
@@ -533,12 +547,10 @@
MtpStorageID storageID = mRequest.getParameter(1); // 0xFFFFFFFF for all storage
MtpObjectFormat format = mRequest.getParameter(2); // 0 for all formats
MtpObjectHandle parent = mRequest.getParameter(3); // 0xFFFFFFFF for objects with no parent
- // 0x00000000 for all objects?
+ // 0x00000000 for all objects
if (!hasStorage(storageID))
return MTP_RESPONSE_INVALID_STORAGE_ID;
- if (parent == 0xFFFFFFFF)
- parent = 0;
MtpObjectHandleList* handles = mDatabase->getObjectList(storageID, format, parent);
mData.putAUInt32(handles);
@@ -552,11 +564,9 @@
MtpStorageID storageID = mRequest.getParameter(1); // 0xFFFFFFFF for all storage
MtpObjectFormat format = mRequest.getParameter(2); // 0 for all formats
MtpObjectHandle parent = mRequest.getParameter(3); // 0xFFFFFFFF for objects with no parent
- // 0x00000000 for all objects?
+ // 0x00000000 for all objects
if (!hasStorage(storageID))
return MTP_RESPONSE_INVALID_STORAGE_ID;
- if (parent == 0xFFFFFFFF)
- parent = 0;
int count = mDatabase->getNumObjects(storageID, format, parent);
if (count >= 0) {
@@ -721,14 +731,12 @@
}
mfr.offset = 0;
mfr.length = fileLength;
-
- // send data header
- mData.setOperationCode(mRequest.getOperationCode());
- mData.setTransactionID(mRequest.getTransactionID());
- mData.writeDataHeader(mFD, fileLength + MTP_CONTAINER_HEADER_SIZE);
+ mfr.command = mRequest.getOperationCode();
+ mfr.transaction_id = mRequest.getTransactionID();
// then transfer the file
- int ret = ioctl(mFD, MTP_SEND_FILE, (unsigned long)&mfr);
+ int ret = ioctl(mFD, MTP_SEND_FILE_WITH_HEADER, (unsigned long)&mfr);
+ LOGV("MTP_SEND_FILE_WITH_HEADER returned %d\n", ret);
close(mfr.fd);
if (ret < 0) {
if (errno == ECANCELED)
@@ -788,15 +796,13 @@
}
mfr.offset = offset;
mfr.length = length;
+ mfr.command = mRequest.getOperationCode();
+ mfr.transaction_id = mRequest.getTransactionID();
mResponse.setParameter(1, length);
- // send data header
- mData.setOperationCode(mRequest.getOperationCode());
- mData.setTransactionID(mRequest.getTransactionID());
- mData.writeDataHeader(mFD, length + MTP_CONTAINER_HEADER_SIZE);
-
- // then transfer the file
- int ret = ioctl(mFD, MTP_SEND_FILE, (unsigned long)&mfr);
+ // transfer the file
+ int ret = ioctl(mFD, MTP_SEND_FILE_WITH_HEADER, (unsigned long)&mfr);
+ LOGV("MTP_SEND_FILE_WITH_HEADER returned %d\n", ret);
close(mfr.fd);
if (ret < 0) {
if (errno == ECANCELED)
@@ -863,6 +869,14 @@
// check space first
if (mSendObjectFileSize > storage->getFreeSpace())
return MTP_RESPONSE_STORAGE_FULL;
+ uint64_t maxFileSize = storage->getMaxFileSize();
+ // check storage max file size
+ if (maxFileSize != 0) {
+ // if mSendObjectFileSize is 0xFFFFFFFF, then all we know is the file size
+ // is >= 0xFFFFFFFF
+ if (mSendObjectFileSize > maxFileSize || mSendObjectFileSize == 0xFFFFFFFF)
+ return MTP_RESPONSE_OBJECT_TOO_LARGE;
+ }
LOGD("path: %s parent: %d storageID: %08X", (const char*)path, parent, storageID);
MtpObjectHandle handle = mDatabase->beginSendObject((const char*)path,
@@ -900,7 +914,7 @@
return MTP_RESPONSE_GENERAL_ERROR;
MtpResponseCode result = MTP_RESPONSE_OK;
mode_t mask;
- int ret;
+ int ret, initialData;
if (mSendObjectHandle == kInvalidObjectHandle) {
LOGE("Expected SendObjectInfo before SendObject");
@@ -908,12 +922,13 @@
goto done;
}
- // read the header
- ret = mData.readDataHeader(mFD);
- // FIXME - check for errors here.
-
- // reset so we don't attempt to send this back
- mData.reset();
+ // read the header, and possibly some data
+ ret = mData.read(mFD);
+ if (ret < MTP_CONTAINER_HEADER_SIZE) {
+ result = MTP_RESPONSE_GENERAL_ERROR;
+ goto done;
+ }
+ initialData = ret - MTP_CONTAINER_HEADER_SIZE;
mtp_file_range mfr;
mfr.fd = open(mSendObjectFilePath, O_RDWR | O_CREAT | O_TRUNC);
@@ -927,16 +942,20 @@
fchmod(mfr.fd, mFilePermission);
umask(mask);
- mfr.offset = 0;
- mfr.length = mSendObjectFileSize;
+ if (initialData > 0)
+ ret = write(mfr.fd, mData.getData(), initialData);
- LOGV("receiving %s\n", (const char *)mSendObjectFilePath);
- // transfer the file
- ret = ioctl(mFD, MTP_RECEIVE_FILE, (unsigned long)&mfr);
+ if (mSendObjectFileSize - initialData > 0) {
+ mfr.offset = initialData;
+ mfr.length = mSendObjectFileSize - initialData;
+
+ LOGV("receiving %s\n", (const char *)mSendObjectFilePath);
+ // transfer the file
+ ret = ioctl(mFD, MTP_RECEIVE_FILE, (unsigned long)&mfr);
+ LOGV("MTP_RECEIVE_FILE returned %d\n", ret);
+ }
close(mfr.fd);
- LOGV("MTP_RECEIVE_FILE returned %d", ret);
-
if (ret < 0) {
unlink(mSendObjectFilePath);
if (errno == ECANCELED)
@@ -946,6 +965,9 @@
}
done:
+ // reset so we don't attempt to send the data back
+ mData.reset();
+
mDatabase->endSendObject(mSendObjectFilePath, mSendObjectHandle, mSendObjectFormat,
result == MTP_RESPONSE_OK);
mSendObjectHandle = kInvalidObjectHandle;
@@ -1078,23 +1100,31 @@
return MTP_RESPONSE_GENERAL_ERROR;
}
- // read the header
- int ret = mData.readDataHeader(mFD);
- // FIXME - check for errors here.
-
- // reset so we don't attempt to send this back
- mData.reset();
-
const char* filePath = (const char *)edit->mPath;
- LOGV("receiving partial %s %lld %ld\n", filePath, offset, length);
- mtp_file_range mfr;
- mfr.fd = edit->mFD;
- mfr.offset = offset;
- mfr.length = length;
+ LOGV("receiving partial %s %lld %lld\n", filePath, offset, length);
- // transfer the file
- ret = ioctl(mFD, MTP_RECEIVE_FILE, (unsigned long)&mfr);
- LOGV("MTP_RECEIVE_FILE returned %d", ret);
+ // read the header, and possibly some data
+ int ret = mData.read(mFD);
+ if (ret < MTP_CONTAINER_HEADER_SIZE)
+ return MTP_RESPONSE_GENERAL_ERROR;
+ int initialData = ret - MTP_CONTAINER_HEADER_SIZE;
+
+ if (initialData > 0) {
+ ret = write(edit->mFD, mData.getData(), initialData);
+ offset += initialData;
+ length -= initialData;
+ }
+
+ if (length > 0) {
+ mtp_file_range mfr;
+ mfr.fd = edit->mFD;
+ mfr.offset = offset;
+ mfr.length = length;
+
+ // transfer the file
+ ret = ioctl(mFD, MTP_RECEIVE_FILE, (unsigned long)&mfr);
+ LOGV("MTP_RECEIVE_FILE returned %d", ret);
+ }
if (ret < 0) {
mResponse.setParameter(1, 0);
if (errno == ECANCELED)
@@ -1102,6 +1132,9 @@
else
return MTP_RESPONSE_GENERAL_ERROR;
}
+
+ // reset so we don't attempt to send this back
+ mData.reset();
mResponse.setParameter(1, length);
uint64_t end = offset + length;
if (end > edit->mSize) {
diff --git a/media/mtp/MtpServer.h b/media/mtp/MtpServer.h
index 859a18e..dfa8258 100644
--- a/media/mtp/MtpServer.h
+++ b/media/mtp/MtpServer.h
@@ -39,6 +39,9 @@
MtpDatabase* mDatabase;
+ // appear as a PTP device
+ bool mPtp;
+
// group to own new files and folders
int mFileGroup;
// permissions for new files and directories
@@ -87,7 +90,7 @@
Vector<ObjectEdit*> mObjectEditList;
public:
- MtpServer(int fd, MtpDatabase* database,
+ MtpServer(int fd, MtpDatabase* database, bool ptp,
int fileGroup, int filePerm, int directoryPerm);
virtual ~MtpServer();
diff --git a/media/mtp/MtpStorage.cpp b/media/mtp/MtpStorage.cpp
index fef8066..941e303 100644
--- a/media/mtp/MtpStorage.cpp
+++ b/media/mtp/MtpStorage.cpp
@@ -33,11 +33,13 @@
namespace android {
MtpStorage::MtpStorage(MtpStorageID id, const char* filePath,
- const char* description, uint64_t reserveSpace, bool removable)
+ const char* description, uint64_t reserveSpace,
+ bool removable, uint64_t maxFileSize)
: mStorageID(id),
mFilePath(filePath),
mDescription(description),
mMaxCapacity(0),
+ mMaxFileSize(maxFileSize),
mReserveSpace(reserveSpace),
mRemovable(removable)
{
diff --git a/media/mtp/MtpStorage.h b/media/mtp/MtpStorage.h
index 3e4f40d..e5a2e57 100644
--- a/media/mtp/MtpStorage.h
+++ b/media/mtp/MtpStorage.h
@@ -31,6 +31,7 @@
MtpString mFilePath;
MtpString mDescription;
uint64_t mMaxCapacity;
+ uint64_t mMaxFileSize;
// amount of free space to leave unallocated
uint64_t mReserveSpace;
bool mRemovable;
@@ -38,7 +39,7 @@
public:
MtpStorage(MtpStorageID id, const char* filePath,
const char* description, uint64_t reserveSpace,
- bool removable);
+ bool removable, uint64_t maxFileSize);
virtual ~MtpStorage();
inline MtpStorageID getStorageID() const { return mStorageID; }
@@ -50,6 +51,7 @@
const char* getDescription() const;
inline const char* getPath() const { return (const char *)mFilePath; }
inline bool isRemovable() const { return mRemovable; }
+ inline uint64_t getMaxFileSize() const { return mMaxFileSize; }
};
}; // namespace android
diff --git a/services/audioflinger/A2dpAudioInterface.cpp b/services/audioflinger/A2dpAudioInterface.cpp
deleted file mode 100644
index d926cb1..0000000
--- a/services/audioflinger/A2dpAudioInterface.cpp
+++ /dev/null
@@ -1,498 +0,0 @@
-/*
- * Copyright (C) 2008 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.
- */
-
-#include <math.h>
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "A2dpAudioInterface"
-#include <utils/Log.h>
-#include <utils/String8.h>
-
-#include "A2dpAudioInterface.h"
-#include "audio/liba2dp.h"
-#include <hardware_legacy/power.h>
-
-namespace android {
-
-static const char *sA2dpWakeLock = "A2dpOutputStream";
-#define MAX_WRITE_RETRIES 5
-
-// ----------------------------------------------------------------------------
-
-//AudioHardwareInterface* A2dpAudioInterface::createA2dpInterface()
-//{
-// AudioHardwareInterface* hw = 0;
-//
-// hw = AudioHardwareInterface::create();
-// LOGD("new A2dpAudioInterface(hw: %p)", hw);
-// hw = new A2dpAudioInterface(hw);
-// return hw;
-//}
-
-A2dpAudioInterface::A2dpAudioInterface(AudioHardwareInterface* hw) :
- mOutput(0), mHardwareInterface(hw), mBluetoothEnabled(true), mSuspended(false)
-{
-}
-
-A2dpAudioInterface::~A2dpAudioInterface()
-{
- closeOutputStream((AudioStreamOut *)mOutput);
- delete mHardwareInterface;
-}
-
-status_t A2dpAudioInterface::initCheck()
-{
- if (mHardwareInterface == 0) return NO_INIT;
- return mHardwareInterface->initCheck();
-}
-
-AudioStreamOut* A2dpAudioInterface::openOutputStream(
- uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status)
-{
- if (!AudioSystem::isA2dpDevice((AudioSystem::audio_devices)devices)) {
- LOGV("A2dpAudioInterface::openOutputStream() open HW device: %x", devices);
- return mHardwareInterface->openOutputStream(devices, format, channels, sampleRate, status);
- }
-
- status_t err = 0;
-
- // only one output stream allowed
- if (mOutput) {
- if (status)
- *status = -1;
- return NULL;
- }
-
- // create new output stream
- A2dpAudioStreamOut* out = new A2dpAudioStreamOut();
- if ((err = out->set(devices, format, channels, sampleRate)) == NO_ERROR) {
- mOutput = out;
- mOutput->setBluetoothEnabled(mBluetoothEnabled);
- mOutput->setSuspended(mSuspended);
- } else {
- delete out;
- }
-
- if (status)
- *status = err;
- return mOutput;
-}
-
-void A2dpAudioInterface::closeOutputStream(AudioStreamOut* out) {
- if (mOutput == 0 || mOutput != out) {
- mHardwareInterface->closeOutputStream(out);
- }
- else {
- delete mOutput;
- mOutput = 0;
- }
-}
-
-
-AudioStreamIn* A2dpAudioInterface::openInputStream(
- uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status,
- AudioSystem::audio_in_acoustics acoustics)
-{
- return mHardwareInterface->openInputStream(devices, format, channels, sampleRate, status, acoustics);
-}
-
-void A2dpAudioInterface::closeInputStream(AudioStreamIn* in)
-{
- return mHardwareInterface->closeInputStream(in);
-}
-
-status_t A2dpAudioInterface::setMode(int mode)
-{
- return mHardwareInterface->setMode(mode);
-}
-
-status_t A2dpAudioInterface::setMicMute(bool state)
-{
- return mHardwareInterface->setMicMute(state);
-}
-
-status_t A2dpAudioInterface::getMicMute(bool* state)
-{
- return mHardwareInterface->getMicMute(state);
-}
-
-status_t A2dpAudioInterface::setParameters(const String8& keyValuePairs)
-{
- AudioParameter param = AudioParameter(keyValuePairs);
- String8 value;
- String8 key;
- status_t status = NO_ERROR;
-
- LOGV("setParameters() %s", keyValuePairs.string());
-
- key = "bluetooth_enabled";
- if (param.get(key, value) == NO_ERROR) {
- mBluetoothEnabled = (value == "true");
- if (mOutput) {
- mOutput->setBluetoothEnabled(mBluetoothEnabled);
- }
- param.remove(key);
- }
- key = String8("A2dpSuspended");
- if (param.get(key, value) == NO_ERROR) {
- mSuspended = (value == "true");
- if (mOutput) {
- mOutput->setSuspended(mSuspended);
- }
- param.remove(key);
- }
-
- if (param.size()) {
- status_t hwStatus = mHardwareInterface->setParameters(param.toString());
- if (status == NO_ERROR) {
- status = hwStatus;
- }
- }
-
- return status;
-}
-
-String8 A2dpAudioInterface::getParameters(const String8& keys)
-{
- AudioParameter param = AudioParameter(keys);
- AudioParameter a2dpParam = AudioParameter();
- String8 value;
- String8 key;
-
- key = "bluetooth_enabled";
- if (param.get(key, value) == NO_ERROR) {
- value = mBluetoothEnabled ? "true" : "false";
- a2dpParam.add(key, value);
- param.remove(key);
- }
- key = "A2dpSuspended";
- if (param.get(key, value) == NO_ERROR) {
- value = mSuspended ? "true" : "false";
- a2dpParam.add(key, value);
- param.remove(key);
- }
-
- String8 keyValuePairs = a2dpParam.toString();
-
- if (param.size()) {
- if (keyValuePairs != "") {
- keyValuePairs += ";";
- }
- keyValuePairs += mHardwareInterface->getParameters(param.toString());
- }
-
- LOGV("getParameters() %s", keyValuePairs.string());
- return keyValuePairs;
-}
-
-size_t A2dpAudioInterface::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
-{
- return mHardwareInterface->getInputBufferSize(sampleRate, format, channelCount);
-}
-
-status_t A2dpAudioInterface::setVoiceVolume(float v)
-{
- return mHardwareInterface->setVoiceVolume(v);
-}
-
-status_t A2dpAudioInterface::setMasterVolume(float v)
-{
- return mHardwareInterface->setMasterVolume(v);
-}
-
-status_t A2dpAudioInterface::dump(int fd, const Vector<String16>& args)
-{
- return mHardwareInterface->dumpState(fd, args);
-}
-
-// ----------------------------------------------------------------------------
-
-A2dpAudioInterface::A2dpAudioStreamOut::A2dpAudioStreamOut() :
- mFd(-1), mStandby(true), mStartCount(0), mRetryCount(0), mData(NULL),
- // assume BT enabled to start, this is safe because its only the
- // enabled->disabled transition we are worried about
- mBluetoothEnabled(true), mDevice(0), mClosing(false), mSuspended(false)
-{
- // use any address by default
- strcpy(mA2dpAddress, "00:00:00:00:00:00");
- init();
-}
-
-status_t A2dpAudioInterface::A2dpAudioStreamOut::set(
- uint32_t device, int *pFormat, uint32_t *pChannels, uint32_t *pRate)
-{
- int lFormat = pFormat ? *pFormat : 0;
- uint32_t lChannels = pChannels ? *pChannels : 0;
- uint32_t lRate = pRate ? *pRate : 0;
-
- LOGD("A2dpAudioStreamOut::set %x, %d, %d, %d\n", device, lFormat, lChannels, lRate);
-
- // fix up defaults
- if (lFormat == 0) lFormat = format();
- if (lChannels == 0) lChannels = channels();
- if (lRate == 0) lRate = sampleRate();
-
- // check values
- if ((lFormat != format()) ||
- (lChannels != channels()) ||
- (lRate != sampleRate())){
- if (pFormat) *pFormat = format();
- if (pChannels) *pChannels = channels();
- if (pRate) *pRate = sampleRate();
- return BAD_VALUE;
- }
-
- if (pFormat) *pFormat = lFormat;
- if (pChannels) *pChannels = lChannels;
- if (pRate) *pRate = lRate;
-
- mDevice = device;
- mBufferDurationUs = ((bufferSize() * 1000 )/ frameSize() / sampleRate()) * 1000;
- return NO_ERROR;
-}
-
-A2dpAudioInterface::A2dpAudioStreamOut::~A2dpAudioStreamOut()
-{
- LOGV("A2dpAudioStreamOut destructor");
- close();
- LOGV("A2dpAudioStreamOut destructor returning from close()");
-}
-
-ssize_t A2dpAudioInterface::A2dpAudioStreamOut::write(const void* buffer, size_t bytes)
-{
- status_t status = -1;
- {
- Mutex::Autolock lock(mLock);
-
- size_t remaining = bytes;
-
- if (!mBluetoothEnabled || mClosing || mSuspended) {
- LOGV("A2dpAudioStreamOut::write(), but bluetooth disabled \
- mBluetoothEnabled %d, mClosing %d, mSuspended %d",
- mBluetoothEnabled, mClosing, mSuspended);
- goto Error;
- }
-
- if (mStandby) {
- acquire_wake_lock (PARTIAL_WAKE_LOCK, sA2dpWakeLock);
- mStandby = false;
- mLastWriteTime = systemTime();
- }
-
- status = init();
- if (status < 0)
- goto Error;
-
- int retries = MAX_WRITE_RETRIES;
- while (remaining > 0 && retries) {
- status = a2dp_write(mData, buffer, remaining);
- if (status < 0) {
- LOGE("a2dp_write failed err: %d\n", status);
- goto Error;
- }
- if (status == 0) {
- retries--;
- }
- remaining -= status;
- buffer = (char *)buffer + status;
- }
-
- // if A2DP sink runs abnormally fast, sleep a little so that audioflinger mixer thread
- // does no spin and starve other threads.
- // NOTE: It is likely that the A2DP headset is being disconnected
- nsecs_t now = systemTime();
- if ((uint32_t)ns2us(now - mLastWriteTime) < (mBufferDurationUs >> 2)) {
- LOGV("A2DP sink runs too fast");
- usleep(mBufferDurationUs - (uint32_t)ns2us(now - mLastWriteTime));
- }
- mLastWriteTime = now;
- return bytes;
-
- }
-Error:
-
- standby();
-
- // Simulate audio output timing in case of error
- usleep(mBufferDurationUs);
-
- return status;
-}
-
-status_t A2dpAudioInterface::A2dpAudioStreamOut::init()
-{
- if (!mData) {
- status_t status = a2dp_init(44100, 2, &mData);
- if (status < 0) {
- LOGE("a2dp_init failed err: %d\n", status);
- mData = NULL;
- return status;
- }
- a2dp_set_sink(mData, mA2dpAddress);
- }
-
- return 0;
-}
-
-status_t A2dpAudioInterface::A2dpAudioStreamOut::standby()
-{
- Mutex::Autolock lock(mLock);
- return standby_l();
-}
-
-status_t A2dpAudioInterface::A2dpAudioStreamOut::standby_l()
-{
- int result = NO_ERROR;
-
- if (!mStandby) {
- LOGV_IF(mClosing || !mBluetoothEnabled, "Standby skip stop: closing %d enabled %d",
- mClosing, mBluetoothEnabled);
- if (!mClosing && mBluetoothEnabled) {
- result = a2dp_stop(mData);
- }
- release_wake_lock(sA2dpWakeLock);
- mStandby = true;
- }
-
- return result;
-}
-
-status_t A2dpAudioInterface::A2dpAudioStreamOut::setParameters(const String8& keyValuePairs)
-{
- AudioParameter param = AudioParameter(keyValuePairs);
- String8 value;
- String8 key = String8("a2dp_sink_address");
- status_t status = NO_ERROR;
- int device;
- LOGV("A2dpAudioStreamOut::setParameters() %s", keyValuePairs.string());
-
- if (param.get(key, value) == NO_ERROR) {
- if (value.length() != strlen("00:00:00:00:00:00")) {
- status = BAD_VALUE;
- } else {
- setAddress(value.string());
- }
- param.remove(key);
- }
- key = String8("closing");
- if (param.get(key, value) == NO_ERROR) {
- mClosing = (value == "true");
- if (mClosing) {
- standby();
- }
- param.remove(key);
- }
- key = AudioParameter::keyRouting;
- if (param.getInt(key, device) == NO_ERROR) {
- if (AudioSystem::isA2dpDevice((AudioSystem::audio_devices)device)) {
- mDevice = device;
- status = NO_ERROR;
- } else {
- status = BAD_VALUE;
- }
- param.remove(key);
- }
-
- if (param.size()) {
- status = BAD_VALUE;
- }
- return status;
-}
-
-String8 A2dpAudioInterface::A2dpAudioStreamOut::getParameters(const String8& keys)
-{
- AudioParameter param = AudioParameter(keys);
- String8 value;
- String8 key = String8("a2dp_sink_address");
-
- if (param.get(key, value) == NO_ERROR) {
- value = mA2dpAddress;
- param.add(key, value);
- }
- key = AudioParameter::keyRouting;
- if (param.get(key, value) == NO_ERROR) {
- param.addInt(key, (int)mDevice);
- }
-
- LOGV("A2dpAudioStreamOut::getParameters() %s", param.toString().string());
- return param.toString();
-}
-
-status_t A2dpAudioInterface::A2dpAudioStreamOut::setAddress(const char* address)
-{
- Mutex::Autolock lock(mLock);
-
- if (strlen(address) != strlen("00:00:00:00:00:00"))
- return -EINVAL;
-
- strcpy(mA2dpAddress, address);
- if (mData)
- a2dp_set_sink(mData, mA2dpAddress);
-
- return NO_ERROR;
-}
-
-status_t A2dpAudioInterface::A2dpAudioStreamOut::setBluetoothEnabled(bool enabled)
-{
- LOGD("setBluetoothEnabled %d", enabled);
-
- Mutex::Autolock lock(mLock);
-
- mBluetoothEnabled = enabled;
- if (!enabled) {
- return close_l();
- }
- return NO_ERROR;
-}
-
-status_t A2dpAudioInterface::A2dpAudioStreamOut::setSuspended(bool onOff)
-{
- LOGV("setSuspended %d", onOff);
- mSuspended = onOff;
- standby();
- return NO_ERROR;
-}
-
-status_t A2dpAudioInterface::A2dpAudioStreamOut::close()
-{
- Mutex::Autolock lock(mLock);
- LOGV("A2dpAudioStreamOut::close() calling close_l()");
- return close_l();
-}
-
-status_t A2dpAudioInterface::A2dpAudioStreamOut::close_l()
-{
- standby_l();
- if (mData) {
- LOGV("A2dpAudioStreamOut::close_l() calling a2dp_cleanup(mData)");
- a2dp_cleanup(mData);
- mData = NULL;
- }
- return NO_ERROR;
-}
-
-status_t A2dpAudioInterface::A2dpAudioStreamOut::dump(int fd, const Vector<String16>& args)
-{
- return NO_ERROR;
-}
-
-status_t A2dpAudioInterface::A2dpAudioStreamOut::getRenderPosition(uint32_t *driverFrames)
-{
- //TODO: enable when supported by driver
- return INVALID_OPERATION;
-}
-
-}; // namespace android
diff --git a/services/audioflinger/A2dpAudioInterface.h b/services/audioflinger/A2dpAudioInterface.h
deleted file mode 100644
index dbe2c6a..0000000
--- a/services/audioflinger/A2dpAudioInterface.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2008 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 A2DP_AUDIO_HARDWARE_H
-#define A2DP_AUDIO_HARDWARE_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/threads.h>
-
-#include <hardware_legacy/AudioHardwareBase.h>
-
-
-namespace android {
-
-class A2dpAudioInterface : public AudioHardwareBase
-{
- class A2dpAudioStreamOut;
-
-public:
- A2dpAudioInterface(AudioHardwareInterface* hw);
- virtual ~A2dpAudioInterface();
- virtual status_t initCheck();
-
- virtual status_t setVoiceVolume(float volume);
- virtual status_t setMasterVolume(float volume);
-
- virtual status_t setMode(int mode);
-
- // mic mute
- virtual status_t setMicMute(bool state);
- virtual status_t getMicMute(bool* state);
-
- virtual status_t setParameters(const String8& keyValuePairs);
- virtual String8 getParameters(const String8& keys);
-
- virtual size_t getInputBufferSize(uint32_t sampleRate, int format, int channelCount);
-
- // create I/O streams
- virtual AudioStreamOut* openOutputStream(
- uint32_t devices,
- int *format=0,
- uint32_t *channels=0,
- uint32_t *sampleRate=0,
- status_t *status=0);
- virtual void closeOutputStream(AudioStreamOut* out);
-
- virtual AudioStreamIn* openInputStream(
- uint32_t devices,
- int *format,
- uint32_t *channels,
- uint32_t *sampleRate,
- status_t *status,
- AudioSystem::audio_in_acoustics acoustics);
- virtual void closeInputStream(AudioStreamIn* in);
-// static AudioHardwareInterface* createA2dpInterface();
-
-protected:
- virtual status_t dump(int fd, const Vector<String16>& args);
-
-private:
- class A2dpAudioStreamOut : public AudioStreamOut {
- public:
- A2dpAudioStreamOut();
- virtual ~A2dpAudioStreamOut();
- status_t set(uint32_t device,
- int *pFormat,
- uint32_t *pChannels,
- uint32_t *pRate);
- virtual uint32_t sampleRate() const { return 44100; }
- // SBC codec wants a multiple of 512
- virtual size_t bufferSize() const { return 512 * 20; }
- virtual uint32_t channels() const { return AudioSystem::CHANNEL_OUT_STEREO; }
- virtual int format() const { return AudioSystem::PCM_16_BIT; }
- virtual uint32_t latency() const { return ((1000*bufferSize())/frameSize())/sampleRate() + 200; }
- virtual status_t setVolume(float left, float right) { return INVALID_OPERATION; }
- virtual ssize_t write(const void* buffer, size_t bytes);
- status_t standby();
- virtual status_t dump(int fd, const Vector<String16>& args);
- virtual status_t setParameters(const String8& keyValuePairs);
- virtual String8 getParameters(const String8& keys);
- virtual status_t getRenderPosition(uint32_t *dspFrames);
-
- private:
- friend class A2dpAudioInterface;
- status_t init();
- status_t close();
- status_t close_l();
- status_t setAddress(const char* address);
- status_t setBluetoothEnabled(bool enabled);
- status_t setSuspended(bool onOff);
- status_t standby_l();
-
- private:
- int mFd;
- bool mStandby;
- int mStartCount;
- int mRetryCount;
- char mA2dpAddress[20];
- void* mData;
- Mutex mLock;
- bool mBluetoothEnabled;
- uint32_t mDevice;
- bool mClosing;
- bool mSuspended;
- nsecs_t mLastWriteTime;
- uint32_t mBufferDurationUs;
- };
-
- friend class A2dpAudioStreamOut;
-
- A2dpAudioStreamOut* mOutput;
- AudioHardwareInterface *mHardwareInterface;
- char mA2dpAddress[20];
- bool mBluetoothEnabled;
- bool mSuspended;
-};
-
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // A2DP_AUDIO_HARDWARE_H
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
index 69a4adc..fa49592 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -1,77 +1,5 @@
LOCAL_PATH:= $(call my-dir)
-#AUDIO_POLICY_TEST := true
-#ENABLE_AUDIO_DUMP := true
-
-include $(CLEAR_VARS)
-
-
-ifeq ($(AUDIO_POLICY_TEST),true)
- ENABLE_AUDIO_DUMP := true
-endif
-
-
-LOCAL_SRC_FILES:= \
- AudioHardwareGeneric.cpp \
- AudioHardwareStub.cpp \
- AudioHardwareInterface.cpp
-
-ifeq ($(ENABLE_AUDIO_DUMP),true)
- LOCAL_SRC_FILES += AudioDumpInterface.cpp
- LOCAL_CFLAGS += -DENABLE_AUDIO_DUMP
-endif
-
-LOCAL_SHARED_LIBRARIES := \
- libcutils \
- libutils \
- libbinder \
- libmedia \
- libhardware_legacy
-
-ifeq ($(strip $(BOARD_USES_GENERIC_AUDIO)),true)
- LOCAL_CFLAGS += -DGENERIC_AUDIO
-endif
-
-LOCAL_MODULE:= libaudiointerface
-
-ifeq ($(BOARD_HAVE_BLUETOOTH),true)
- LOCAL_SRC_FILES += A2dpAudioInterface.cpp
- LOCAL_SHARED_LIBRARIES += liba2dp
- LOCAL_CFLAGS += -DWITH_BLUETOOTH -DWITH_A2DP
- LOCAL_C_INCLUDES += $(call include-path-for, bluez)
-endif
-
-include $(BUILD_STATIC_LIBRARY)
-
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- AudioPolicyManagerBase.cpp
-
-LOCAL_SHARED_LIBRARIES := \
- libcutils \
- libutils \
- libmedia
-
-ifeq ($(TARGET_SIMULATOR),true)
- LOCAL_LDLIBS += -ldl
-else
- LOCAL_SHARED_LIBRARIES += libdl
-endif
-
-LOCAL_MODULE:= libaudiopolicybase
-
-ifeq ($(BOARD_HAVE_BLUETOOTH),true)
- LOCAL_CFLAGS += -DWITH_A2DP
-endif
-
-ifeq ($(AUDIO_POLICY_TEST),true)
- LOCAL_CFLAGS += -DAUDIO_POLICY_TEST
-endif
-
-include $(BUILD_STATIC_LIBRARY)
-
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
@@ -82,42 +10,24 @@
AudioResamplerCubic.cpp.arm \
AudioPolicyService.cpp
+LOCAL_C_INCLUDES := \
+ system/media/audio_effects/include
+
LOCAL_SHARED_LIBRARIES := \
libcutils \
libutils \
libbinder \
libmedia \
+ libhardware \
libhardware_legacy \
- libeffects
+ libeffects \
+ libdl \
+ libpowermanager
-ifeq ($(strip $(BOARD_USES_GENERIC_AUDIO)),true)
- LOCAL_STATIC_LIBRARIES += libaudiointerface libaudiopolicybase
- LOCAL_CFLAGS += -DGENERIC_AUDIO
-else
- LOCAL_SHARED_LIBRARIES += libaudio libaudiopolicy
-endif
-
-ifeq ($(TARGET_SIMULATOR),true)
- LOCAL_LDLIBS += -ldl
-else
- LOCAL_SHARED_LIBRARIES += libdl
-endif
+LOCAL_STATIC_LIBRARIES := \
+ libcpustats \
+ libmedia_helper
LOCAL_MODULE:= libaudioflinger
-ifeq ($(BOARD_HAVE_BLUETOOTH),true)
- LOCAL_CFLAGS += -DWITH_BLUETOOTH -DWITH_A2DP
- LOCAL_SHARED_LIBRARIES += liba2dp
-endif
-
-ifeq ($(AUDIO_POLICY_TEST),true)
- LOCAL_CFLAGS += -DAUDIO_POLICY_TEST
-endif
-
-ifeq ($(TARGET_SIMULATOR),true)
- ifeq ($(HOST_OS),linux)
- LOCAL_LDLIBS += -lrt -lpthread
- endif
-endif
-
include $(BUILD_SHARED_LIBRARY)
diff --git a/services/audioflinger/AudioDumpInterface.cpp b/services/audioflinger/AudioDumpInterface.cpp
deleted file mode 100644
index 6c11114..0000000
--- a/services/audioflinger/AudioDumpInterface.cpp
+++ /dev/null
@@ -1,573 +0,0 @@
-/* //device/servers/AudioFlinger/AudioDumpInterface.cpp
-**
-** Copyright 2008, 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_TAG "AudioFlingerDump"
-//#define LOG_NDEBUG 0
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <utils/Log.h>
-
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "AudioDumpInterface.h"
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-AudioDumpInterface::AudioDumpInterface(AudioHardwareInterface* hw)
- : mPolicyCommands(String8("")), mFileName(String8(""))
-{
- if(hw == 0) {
- LOGE("Dump construct hw = 0");
- }
- mFinalInterface = hw;
- LOGV("Constructor %p, mFinalInterface %p", this, mFinalInterface);
-}
-
-
-AudioDumpInterface::~AudioDumpInterface()
-{
- for (size_t i = 0; i < mOutputs.size(); i++) {
- closeOutputStream((AudioStreamOut *)mOutputs[i]);
- }
-
- for (size_t i = 0; i < mInputs.size(); i++) {
- closeInputStream((AudioStreamIn *)mInputs[i]);
- }
-
- if(mFinalInterface) delete mFinalInterface;
-}
-
-
-AudioStreamOut* AudioDumpInterface::openOutputStream(
- uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status)
-{
- AudioStreamOut* outFinal = NULL;
- int lFormat = AudioSystem::PCM_16_BIT;
- uint32_t lChannels = AudioSystem::CHANNEL_OUT_STEREO;
- uint32_t lRate = 44100;
-
-
- outFinal = mFinalInterface->openOutputStream(devices, format, channels, sampleRate, status);
- if (outFinal != 0) {
- lFormat = outFinal->format();
- lChannels = outFinal->channels();
- lRate = outFinal->sampleRate();
- } else {
- if (format != 0) {
- if (*format != 0) {
- lFormat = *format;
- } else {
- *format = lFormat;
- }
- }
- if (channels != 0) {
- if (*channels != 0) {
- lChannels = *channels;
- } else {
- *channels = lChannels;
- }
- }
- if (sampleRate != 0) {
- if (*sampleRate != 0) {
- lRate = *sampleRate;
- } else {
- *sampleRate = lRate;
- }
- }
- if (status) *status = NO_ERROR;
- }
- LOGV("openOutputStream(), outFinal %p", outFinal);
-
- AudioStreamOutDump *dumOutput = new AudioStreamOutDump(this, mOutputs.size(), outFinal,
- devices, lFormat, lChannels, lRate);
- mOutputs.add(dumOutput);
-
- return dumOutput;
-}
-
-void AudioDumpInterface::closeOutputStream(AudioStreamOut* out)
-{
- AudioStreamOutDump *dumpOut = (AudioStreamOutDump *)out;
-
- if (mOutputs.indexOf(dumpOut) < 0) {
- LOGW("Attempt to close invalid output stream");
- return;
- }
-
- LOGV("closeOutputStream() output %p", out);
-
- dumpOut->standby();
- if (dumpOut->finalStream() != NULL) {
- mFinalInterface->closeOutputStream(dumpOut->finalStream());
- }
-
- mOutputs.remove(dumpOut);
- delete dumpOut;
-}
-
-AudioStreamIn* AudioDumpInterface::openInputStream(uint32_t devices, int *format, uint32_t *channels,
- uint32_t *sampleRate, status_t *status, AudioSystem::audio_in_acoustics acoustics)
-{
- AudioStreamIn* inFinal = NULL;
- int lFormat = AudioSystem::PCM_16_BIT;
- uint32_t lChannels = AudioSystem::CHANNEL_IN_MONO;
- uint32_t lRate = 8000;
-
- inFinal = mFinalInterface->openInputStream(devices, format, channels, sampleRate, status, acoustics);
- if (inFinal != 0) {
- lFormat = inFinal->format();
- lChannels = inFinal->channels();
- lRate = inFinal->sampleRate();
- } else {
- if (format != 0) {
- if (*format != 0) {
- lFormat = *format;
- } else {
- *format = lFormat;
- }
- }
- if (channels != 0) {
- if (*channels != 0) {
- lChannels = *channels;
- } else {
- *channels = lChannels;
- }
- }
- if (sampleRate != 0) {
- if (*sampleRate != 0) {
- lRate = *sampleRate;
- } else {
- *sampleRate = lRate;
- }
- }
- if (status) *status = NO_ERROR;
- }
- LOGV("openInputStream(), inFinal %p", inFinal);
-
- AudioStreamInDump *dumInput = new AudioStreamInDump(this, mInputs.size(), inFinal,
- devices, lFormat, lChannels, lRate);
- mInputs.add(dumInput);
-
- return dumInput;
-}
-void AudioDumpInterface::closeInputStream(AudioStreamIn* in)
-{
- AudioStreamInDump *dumpIn = (AudioStreamInDump *)in;
-
- if (mInputs.indexOf(dumpIn) < 0) {
- LOGW("Attempt to close invalid input stream");
- return;
- }
- dumpIn->standby();
- if (dumpIn->finalStream() != NULL) {
- mFinalInterface->closeInputStream(dumpIn->finalStream());
- }
-
- mInputs.remove(dumpIn);
- delete dumpIn;
-}
-
-
-status_t AudioDumpInterface::setParameters(const String8& keyValuePairs)
-{
- AudioParameter param = AudioParameter(keyValuePairs);
- String8 value;
- int valueInt;
- LOGV("setParameters %s", keyValuePairs.string());
-
- if (param.get(String8("test_cmd_file_name"), value) == NO_ERROR) {
- mFileName = value;
- param.remove(String8("test_cmd_file_name"));
- }
- if (param.get(String8("test_cmd_policy"), value) == NO_ERROR) {
- Mutex::Autolock _l(mLock);
- param.remove(String8("test_cmd_policy"));
- mPolicyCommands = param.toString();
- LOGV("test_cmd_policy command %s written", mPolicyCommands.string());
- return NO_ERROR;
- }
-
- if (mFinalInterface != 0 ) return mFinalInterface->setParameters(keyValuePairs);
- return NO_ERROR;
-}
-
-String8 AudioDumpInterface::getParameters(const String8& keys)
-{
- AudioParameter param = AudioParameter(keys);
- AudioParameter response;
- String8 value;
-
-// LOGV("getParameters %s", keys.string());
- if (param.get(String8("test_cmd_policy"), value) == NO_ERROR) {
- Mutex::Autolock _l(mLock);
- if (mPolicyCommands.length() != 0) {
- response = AudioParameter(mPolicyCommands);
- response.addInt(String8("test_cmd_policy"), 1);
- } else {
- response.addInt(String8("test_cmd_policy"), 0);
- }
- param.remove(String8("test_cmd_policy"));
-// LOGV("test_cmd_policy command %s read", mPolicyCommands.string());
- }
-
- if (param.get(String8("test_cmd_file_name"), value) == NO_ERROR) {
- response.add(String8("test_cmd_file_name"), mFileName);
- param.remove(String8("test_cmd_file_name"));
- }
-
- String8 keyValuePairs = response.toString();
-
- if (param.size() && mFinalInterface != 0 ) {
- keyValuePairs += ";";
- keyValuePairs += mFinalInterface->getParameters(param.toString());
- }
-
- return keyValuePairs;
-}
-
-status_t AudioDumpInterface::setMode(int mode)
-{
- return mFinalInterface->setMode(mode);
-}
-
-size_t AudioDumpInterface::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
-{
- return mFinalInterface->getInputBufferSize(sampleRate, format, channelCount);
-}
-
-// ----------------------------------------------------------------------------
-
-AudioStreamOutDump::AudioStreamOutDump(AudioDumpInterface *interface,
- int id,
- AudioStreamOut* finalStream,
- uint32_t devices,
- int format,
- uint32_t channels,
- uint32_t sampleRate)
- : mInterface(interface), mId(id),
- mSampleRate(sampleRate), mFormat(format), mChannels(channels), mLatency(0), mDevice(devices),
- mBufferSize(1024), mFinalStream(finalStream), mFile(0), mFileCount(0)
-{
- LOGV("AudioStreamOutDump Constructor %p, mInterface %p, mFinalStream %p", this, mInterface, mFinalStream);
-}
-
-
-AudioStreamOutDump::~AudioStreamOutDump()
-{
- LOGV("AudioStreamOutDump destructor");
- Close();
-}
-
-ssize_t AudioStreamOutDump::write(const void* buffer, size_t bytes)
-{
- ssize_t ret;
-
- if (mFinalStream) {
- ret = mFinalStream->write(buffer, bytes);
- } else {
- usleep((((bytes * 1000) / frameSize()) / sampleRate()) * 1000);
- ret = bytes;
- }
- if(!mFile) {
- if (mInterface->fileName() != "") {
- char name[255];
- sprintf(name, "%s_out_%d_%d.pcm", mInterface->fileName().string(), mId, ++mFileCount);
- mFile = fopen(name, "wb");
- LOGV("Opening dump file %s, fh %p", name, mFile);
- }
- }
- if (mFile) {
- fwrite(buffer, bytes, 1, mFile);
- }
- return ret;
-}
-
-status_t AudioStreamOutDump::standby()
-{
- LOGV("AudioStreamOutDump standby(), mFile %p, mFinalStream %p", mFile, mFinalStream);
-
- Close();
- if (mFinalStream != 0 ) return mFinalStream->standby();
- return NO_ERROR;
-}
-
-uint32_t AudioStreamOutDump::sampleRate() const
-{
- if (mFinalStream != 0 ) return mFinalStream->sampleRate();
- return mSampleRate;
-}
-
-size_t AudioStreamOutDump::bufferSize() const
-{
- if (mFinalStream != 0 ) return mFinalStream->bufferSize();
- return mBufferSize;
-}
-
-uint32_t AudioStreamOutDump::channels() const
-{
- if (mFinalStream != 0 ) return mFinalStream->channels();
- return mChannels;
-}
-int AudioStreamOutDump::format() const
-{
- if (mFinalStream != 0 ) return mFinalStream->format();
- return mFormat;
-}
-uint32_t AudioStreamOutDump::latency() const
-{
- if (mFinalStream != 0 ) return mFinalStream->latency();
- return 0;
-}
-status_t AudioStreamOutDump::setVolume(float left, float right)
-{
- if (mFinalStream != 0 ) return mFinalStream->setVolume(left, right);
- return NO_ERROR;
-}
-status_t AudioStreamOutDump::setParameters(const String8& keyValuePairs)
-{
- LOGV("AudioStreamOutDump::setParameters %s", keyValuePairs.string());
-
- if (mFinalStream != 0 ) {
- return mFinalStream->setParameters(keyValuePairs);
- }
-
- AudioParameter param = AudioParameter(keyValuePairs);
- String8 value;
- int valueInt;
- status_t status = NO_ERROR;
-
- if (param.getInt(String8("set_id"), valueInt) == NO_ERROR) {
- mId = valueInt;
- }
-
- if (param.getInt(String8("format"), valueInt) == NO_ERROR) {
- if (mFile == 0) {
- mFormat = valueInt;
- } else {
- status = INVALID_OPERATION;
- }
- }
- if (param.getInt(String8("channels"), valueInt) == NO_ERROR) {
- if (valueInt == AudioSystem::CHANNEL_OUT_STEREO || valueInt == AudioSystem::CHANNEL_OUT_MONO) {
- mChannels = valueInt;
- } else {
- status = BAD_VALUE;
- }
- }
- if (param.getInt(String8("sampling_rate"), valueInt) == NO_ERROR) {
- if (valueInt > 0 && valueInt <= 48000) {
- if (mFile == 0) {
- mSampleRate = valueInt;
- } else {
- status = INVALID_OPERATION;
- }
- } else {
- status = BAD_VALUE;
- }
- }
- return status;
-}
-
-String8 AudioStreamOutDump::getParameters(const String8& keys)
-{
- if (mFinalStream != 0 ) return mFinalStream->getParameters(keys);
-
- AudioParameter param = AudioParameter(keys);
- return param.toString();
-}
-
-status_t AudioStreamOutDump::dump(int fd, const Vector<String16>& args)
-{
- if (mFinalStream != 0 ) return mFinalStream->dump(fd, args);
- return NO_ERROR;
-}
-
-void AudioStreamOutDump::Close()
-{
- if(mFile) {
- fclose(mFile);
- mFile = 0;
- }
-}
-
-status_t AudioStreamOutDump::getRenderPosition(uint32_t *dspFrames)
-{
- if (mFinalStream != 0 ) return mFinalStream->getRenderPosition(dspFrames);
- return INVALID_OPERATION;
-}
-
-// ----------------------------------------------------------------------------
-
-AudioStreamInDump::AudioStreamInDump(AudioDumpInterface *interface,
- int id,
- AudioStreamIn* finalStream,
- uint32_t devices,
- int format,
- uint32_t channels,
- uint32_t sampleRate)
- : mInterface(interface), mId(id),
- mSampleRate(sampleRate), mFormat(format), mChannels(channels), mDevice(devices),
- mBufferSize(1024), mFinalStream(finalStream), mFile(0), mFileCount(0)
-{
- LOGV("AudioStreamInDump Constructor %p, mInterface %p, mFinalStream %p", this, mInterface, mFinalStream);
-}
-
-
-AudioStreamInDump::~AudioStreamInDump()
-{
- Close();
-}
-
-ssize_t AudioStreamInDump::read(void* buffer, ssize_t bytes)
-{
- ssize_t ret;
-
- if (mFinalStream) {
- ret = mFinalStream->read(buffer, bytes);
- if(!mFile) {
- if (mInterface->fileName() != "") {
- char name[255];
- sprintf(name, "%s_in_%d_%d.pcm", mInterface->fileName().string(), mId, ++mFileCount);
- mFile = fopen(name, "wb");
- LOGV("Opening input dump file %s, fh %p", name, mFile);
- }
- }
- if (mFile) {
- fwrite(buffer, bytes, 1, mFile);
- }
- } else {
- usleep((((bytes * 1000) / frameSize()) / sampleRate()) * 1000);
- ret = bytes;
- if(!mFile) {
- char name[255];
- strcpy(name, "/sdcard/music/sine440");
- if (channels() == AudioSystem::CHANNEL_IN_MONO) {
- strcat(name, "_mo");
- } else {
- strcat(name, "_st");
- }
- if (format() == AudioSystem::PCM_16_BIT) {
- strcat(name, "_16b");
- } else {
- strcat(name, "_8b");
- }
- if (sampleRate() < 16000) {
- strcat(name, "_8k");
- } else if (sampleRate() < 32000) {
- strcat(name, "_22k");
- } else if (sampleRate() < 48000) {
- strcat(name, "_44k");
- } else {
- strcat(name, "_48k");
- }
- strcat(name, ".wav");
- mFile = fopen(name, "rb");
- LOGV("Opening input read file %s, fh %p", name, mFile);
- if (mFile) {
- fseek(mFile, AUDIO_DUMP_WAVE_HDR_SIZE, SEEK_SET);
- }
- }
- if (mFile) {
- ssize_t bytesRead = fread(buffer, bytes, 1, mFile);
- if (bytesRead >=0 && bytesRead < bytes) {
- fseek(mFile, AUDIO_DUMP_WAVE_HDR_SIZE, SEEK_SET);
- fread((uint8_t *)buffer+bytesRead, bytes-bytesRead, 1, mFile);
- }
- }
- }
-
- return ret;
-}
-
-status_t AudioStreamInDump::standby()
-{
- LOGV("AudioStreamInDump standby(), mFile %p, mFinalStream %p", mFile, mFinalStream);
-
- Close();
- if (mFinalStream != 0 ) return mFinalStream->standby();
- return NO_ERROR;
-}
-
-status_t AudioStreamInDump::setGain(float gain)
-{
- if (mFinalStream != 0 ) return mFinalStream->setGain(gain);
- return NO_ERROR;
-}
-
-uint32_t AudioStreamInDump::sampleRate() const
-{
- if (mFinalStream != 0 ) return mFinalStream->sampleRate();
- return mSampleRate;
-}
-
-size_t AudioStreamInDump::bufferSize() const
-{
- if (mFinalStream != 0 ) return mFinalStream->bufferSize();
- return mBufferSize;
-}
-
-uint32_t AudioStreamInDump::channels() const
-{
- if (mFinalStream != 0 ) return mFinalStream->channels();
- return mChannels;
-}
-
-int AudioStreamInDump::format() const
-{
- if (mFinalStream != 0 ) return mFinalStream->format();
- return mFormat;
-}
-
-status_t AudioStreamInDump::setParameters(const String8& keyValuePairs)
-{
- LOGV("AudioStreamInDump::setParameters()");
- if (mFinalStream != 0 ) return mFinalStream->setParameters(keyValuePairs);
- return NO_ERROR;
-}
-
-String8 AudioStreamInDump::getParameters(const String8& keys)
-{
- if (mFinalStream != 0 ) return mFinalStream->getParameters(keys);
-
- AudioParameter param = AudioParameter(keys);
- return param.toString();
-}
-
-unsigned int AudioStreamInDump::getInputFramesLost() const
-{
- if (mFinalStream != 0 ) return mFinalStream->getInputFramesLost();
- return 0;
-}
-
-status_t AudioStreamInDump::dump(int fd, const Vector<String16>& args)
-{
- if (mFinalStream != 0 ) return mFinalStream->dump(fd, args);
- return NO_ERROR;
-}
-
-void AudioStreamInDump::Close()
-{
- if(mFile) {
- fclose(mFile);
- mFile = 0;
- }
-}
-}; // namespace android
diff --git a/services/audioflinger/AudioDumpInterface.h b/services/audioflinger/AudioDumpInterface.h
deleted file mode 100644
index 814ce5f..0000000
--- a/services/audioflinger/AudioDumpInterface.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/* //device/servers/AudioFlinger/AudioDumpInterface.h
-**
-** Copyright 2008, 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 ANDROID_AUDIO_DUMP_INTERFACE_H
-#define ANDROID_AUDIO_DUMP_INTERFACE_H
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <utils/String8.h>
-#include <utils/SortedVector.h>
-
-#include <hardware_legacy/AudioHardwareBase.h>
-
-namespace android {
-
-#define AUDIO_DUMP_WAVE_HDR_SIZE 44
-
-class AudioDumpInterface;
-
-class AudioStreamOutDump : public AudioStreamOut {
-public:
- AudioStreamOutDump(AudioDumpInterface *interface,
- int id,
- AudioStreamOut* finalStream,
- uint32_t devices,
- int format,
- uint32_t channels,
- uint32_t sampleRate);
- ~AudioStreamOutDump();
-
- virtual ssize_t write(const void* buffer, size_t bytes);
- virtual uint32_t sampleRate() const;
- virtual size_t bufferSize() const;
- virtual uint32_t channels() const;
- virtual int format() const;
- virtual uint32_t latency() const;
- virtual status_t setVolume(float left, float right);
- virtual status_t standby();
- virtual status_t setParameters(const String8& keyValuePairs);
- virtual String8 getParameters(const String8& keys);
- virtual status_t dump(int fd, const Vector<String16>& args);
- void Close(void);
- AudioStreamOut* finalStream() { return mFinalStream; }
- uint32_t device() { return mDevice; }
- int getId() { return mId; }
- virtual status_t getRenderPosition(uint32_t *dspFrames);
-
-private:
- AudioDumpInterface *mInterface;
- int mId;
- uint32_t mSampleRate; //
- uint32_t mFormat; //
- uint32_t mChannels; // output configuration
- uint32_t mLatency; //
- uint32_t mDevice; // current device this output is routed to
- size_t mBufferSize;
- AudioStreamOut *mFinalStream;
- FILE *mFile; // output file
- int mFileCount;
-};
-
-class AudioStreamInDump : public AudioStreamIn {
-public:
- AudioStreamInDump(AudioDumpInterface *interface,
- int id,
- AudioStreamIn* finalStream,
- uint32_t devices,
- int format,
- uint32_t channels,
- uint32_t sampleRate);
- ~AudioStreamInDump();
-
- virtual uint32_t sampleRate() const;
- virtual size_t bufferSize() const;
- virtual uint32_t channels() const;
- virtual int format() const;
-
- virtual status_t setGain(float gain);
- virtual ssize_t read(void* buffer, ssize_t bytes);
- virtual status_t standby();
- virtual status_t setParameters(const String8& keyValuePairs);
- virtual String8 getParameters(const String8& keys);
- virtual unsigned int getInputFramesLost() const;
- virtual status_t dump(int fd, const Vector<String16>& args);
- void Close(void);
- AudioStreamIn* finalStream() { return mFinalStream; }
- uint32_t device() { return mDevice; }
-
-private:
- AudioDumpInterface *mInterface;
- int mId;
- uint32_t mSampleRate; //
- uint32_t mFormat; //
- uint32_t mChannels; // output configuration
- uint32_t mDevice; // current device this output is routed to
- size_t mBufferSize;
- AudioStreamIn *mFinalStream;
- FILE *mFile; // output file
- int mFileCount;
-};
-
-class AudioDumpInterface : public AudioHardwareBase
-{
-
-public:
- AudioDumpInterface(AudioHardwareInterface* hw);
- virtual AudioStreamOut* openOutputStream(
- uint32_t devices,
- int *format=0,
- uint32_t *channels=0,
- uint32_t *sampleRate=0,
- status_t *status=0);
- virtual void closeOutputStream(AudioStreamOut* out);
-
- virtual ~AudioDumpInterface();
-
- virtual status_t initCheck()
- {return mFinalInterface->initCheck();}
- virtual status_t setVoiceVolume(float volume)
- {return mFinalInterface->setVoiceVolume(volume);}
- virtual status_t setMasterVolume(float volume)
- {return mFinalInterface->setMasterVolume(volume);}
-
- virtual status_t setMode(int mode);
-
- // mic mute
- virtual status_t setMicMute(bool state)
- {return mFinalInterface->setMicMute(state);}
- virtual status_t getMicMute(bool* state)
- {return mFinalInterface->getMicMute(state);}
-
- virtual status_t setParameters(const String8& keyValuePairs);
- virtual String8 getParameters(const String8& keys);
-
- virtual size_t getInputBufferSize(uint32_t sampleRate, int format, int channelCount);
-
- virtual AudioStreamIn* openInputStream(uint32_t devices, int *format, uint32_t *channels,
- uint32_t *sampleRate, status_t *status, AudioSystem::audio_in_acoustics acoustics);
- virtual void closeInputStream(AudioStreamIn* in);
-
- virtual status_t dump(int fd, const Vector<String16>& args) { return mFinalInterface->dumpState(fd, args); }
-
- String8 fileName() const { return mFileName; }
-protected:
-
- AudioHardwareInterface *mFinalInterface;
- SortedVector<AudioStreamOutDump *> mOutputs;
- SortedVector<AudioStreamInDump *> mInputs;
- Mutex mLock;
- String8 mPolicyCommands;
- String8 mFileName;
-};
-
-}; // namespace android
-
-#endif // ANDROID_AUDIO_DUMP_INTERFACE_H
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index dff9f33..2355d5c 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -31,7 +31,9 @@
#include <binder/IPCThreadState.h>
#include <utils/String16.h>
#include <utils/threads.h>
+#include <utils/Atomic.h>
+#include <cutils/bitops.h>
#include <cutils/properties.h>
#include <media/AudioTrack.h>
@@ -40,28 +42,24 @@
#include <private/media/AudioTrackShared.h>
#include <private/media/AudioEffectShared.h>
-#include <hardware_legacy/AudioHardwareInterface.h>
+
+#include <system/audio.h>
+#include <hardware/audio.h>
#include "AudioMixer.h"
#include "AudioFlinger.h"
-#ifdef WITH_A2DP
-#include "A2dpAudioInterface.h"
-#endif
-
#include <media/EffectsFactoryApi.h>
-#include <media/EffectVisualizerApi.h>
+#include <audio_effects/effect_visualizer.h>
+#include <audio_effects/effect_ns.h>
+#include <audio_effects/effect_aec.h>
-// ----------------------------------------------------------------------------
-// the sim build doesn't have gettid
-
-#ifndef HAVE_GETTID
-# define gettid getpid
-#endif
+#include <cpustats/ThreadCpuUsage.h>
+#include <powermanager/PowerManager.h>
+// #define DEBUG_CPU_USAGE 10 // log statistics every n wall clock seconds
// ----------------------------------------------------------------------------
-extern const char * const gEffectLibPath;
namespace android {
@@ -86,41 +84,23 @@
static const nsecs_t kWarningThrottle = seconds(5);
-
-#define AUDIOFLINGER_SECURITY_ENABLED 1
+// RecordThread loop sleep time upon application overrun or audio HAL read error
+static const int kRecordThreadSleepUs = 5000;
// ----------------------------------------------------------------------------
static bool recordingAllowed() {
-#ifndef HAVE_ANDROID_OS
- return true;
-#endif
-#if AUDIOFLINGER_SECURITY_ENABLED
if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
bool ok = checkCallingPermission(String16("android.permission.RECORD_AUDIO"));
if (!ok) LOGE("Request requires android.permission.RECORD_AUDIO");
return ok;
-#else
- if (!checkCallingPermission(String16("android.permission.RECORD_AUDIO")))
- LOGW("WARNING: Need to add android.permission.RECORD_AUDIO to manifest");
- return true;
-#endif
}
static bool settingsAllowed() {
-#ifndef HAVE_ANDROID_OS
- return true;
-#endif
-#if AUDIOFLINGER_SECURITY_ENABLED
if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
bool ok = checkCallingPermission(String16("android.permission.MODIFY_AUDIO_SETTINGS"));
if (!ok) LOGE("Request requires android.permission.MODIFY_AUDIO_SETTINGS");
return ok;
-#else
- if (!checkCallingPermission(String16("android.permission.MODIFY_AUDIO_SETTINGS")))
- LOGW("WARNING: Need to add android.permission.MODIFY_AUDIO_SETTINGS to manifest");
- return true;
-#endif
}
// To collect the amplifier usage
@@ -136,34 +116,110 @@
service->addBatteryData(params);
}
+static int load_audio_interface(const char *if_name, const hw_module_t **mod,
+ audio_hw_device_t **dev)
+{
+ int rc;
+
+ rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, mod);
+ if (rc)
+ goto out;
+
+ rc = audio_hw_device_open(*mod, dev);
+ LOGE_IF(rc, "couldn't open audio hw device in %s.%s (%s)",
+ AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc));
+ if (rc)
+ goto out;
+
+ return 0;
+
+out:
+ *mod = NULL;
+ *dev = NULL;
+ return rc;
+}
+
+static const char *audio_interfaces[] = {
+ "primary",
+ "a2dp",
+ "usb",
+};
+#define ARRAY_SIZE(x) (sizeof((x))/sizeof(((x)[0])))
+
// ----------------------------------------------------------------------------
AudioFlinger::AudioFlinger()
: BnAudioFlinger(),
- mAudioHardware(0), mMasterVolume(1.0f), mMasterMute(false), mNextUniqueId(1)
+ mPrimaryHardwareDev(0), mMasterVolume(1.0f), mMasterMute(false), mNextUniqueId(1),
+ mBtNrec(false)
{
+}
+
+void AudioFlinger::onFirstRef()
+{
+ int rc = 0;
+
Mutex::Autolock _l(mLock);
+ /* TODO: move all this work into an Init() function */
mHardwareStatus = AUDIO_HW_IDLE;
- mAudioHardware = AudioHardwareInterface::create();
+ for (size_t i = 0; i < ARRAY_SIZE(audio_interfaces); i++) {
+ const hw_module_t *mod;
+ audio_hw_device_t *dev;
+
+ rc = load_audio_interface(audio_interfaces[i], &mod, &dev);
+ if (rc)
+ continue;
+
+ LOGI("Loaded %s audio interface from %s (%s)", audio_interfaces[i],
+ mod->name, mod->id);
+ mAudioHwDevs.push(dev);
+
+ if (!mPrimaryHardwareDev) {
+ mPrimaryHardwareDev = dev;
+ LOGI("Using '%s' (%s.%s) as the primary audio interface",
+ mod->name, mod->id, audio_interfaces[i]);
+ }
+ }
mHardwareStatus = AUDIO_HW_INIT;
- if (mAudioHardware->initCheck() == NO_ERROR) {
- AutoMutex lock(mHardwareLock);
- mMode = AudioSystem::MODE_NORMAL;
- mHardwareStatus = AUDIO_HW_SET_MODE;
- mAudioHardware->setMode(mMode);
- mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
- mAudioHardware->setMasterVolume(1.0f);
- mHardwareStatus = AUDIO_HW_IDLE;
- } else {
- LOGE("Couldn't even initialize the stubbed audio hardware!");
+
+ if (!mPrimaryHardwareDev || mAudioHwDevs.size() == 0) {
+ LOGE("Primary audio interface not found");
+ return;
}
+
+ for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
+ audio_hw_device_t *dev = mAudioHwDevs[i];
+
+ mHardwareStatus = AUDIO_HW_INIT;
+ rc = dev->init_check(dev);
+ if (rc == 0) {
+ AutoMutex lock(mHardwareLock);
+
+ mMode = AUDIO_MODE_NORMAL;
+ mHardwareStatus = AUDIO_HW_SET_MODE;
+ dev->set_mode(dev, mMode);
+ mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
+ dev->set_master_volume(dev, 1.0f);
+ mHardwareStatus = AUDIO_HW_IDLE;
+ }
+ }
+}
+
+status_t AudioFlinger::initCheck() const
+{
+ Mutex::Autolock _l(mLock);
+ if (mPrimaryHardwareDev == NULL || mAudioHwDevs.size() == 0)
+ return NO_INIT;
+ return NO_ERROR;
}
AudioFlinger::~AudioFlinger()
{
+ int num_devs = mAudioHwDevs.size();
+
while (!mRecordThreads.isEmpty()) {
// closeInput() will remove first entry from mRecordThreads
closeInput(mRecordThreads.keyAt(0));
@@ -172,12 +228,24 @@
// closeOutput() will remove first entry from mPlaybackThreads
closeOutput(mPlaybackThreads.keyAt(0));
}
- if (mAudioHardware) {
- delete mAudioHardware;
+
+ for (int i = 0; i < num_devs; i++) {
+ audio_hw_device_t *dev = mAudioHwDevs[i];
+ audio_hw_device_close(dev);
}
+ mAudioHwDevs.clear();
}
-
+audio_hw_device_t* AudioFlinger::findSuitableHwDev_l(uint32_t devices)
+{
+ /* first matching HW device is returned */
+ for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
+ audio_hw_device_t *dev = mAudioHwDevs[i];
+ if ((dev->get_supported_devices(dev) & devices) == devices)
+ return dev;
+ }
+ return NULL;
+}
status_t AudioFlinger::dumpClients(int fd, const Vector<String16>& args)
{
@@ -276,8 +344,10 @@
mRecordThreads.valueAt(i)->dump(fd, args);
}
- if (mAudioHardware) {
- mAudioHardware->dumpState(fd, args);
+ // dump all hardware devs
+ for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
+ audio_hw_device_t *dev = mAudioHwDevs[i];
+ dev->dump(dev, fd);
}
if (locked) mLock.unlock();
}
@@ -292,8 +362,8 @@
pid_t pid,
int streamType,
uint32_t sampleRate,
- int format,
- int channelCount,
+ uint32_t format,
+ uint32_t channelMask,
int frameCount,
uint32_t flags,
const sp<IMemory>& sharedBuffer,
@@ -308,7 +378,7 @@
status_t lStatus;
int lSessionId;
- if (streamType >= AudioSystem::NUM_STREAM_TYPES) {
+ if (streamType >= AUDIO_STREAM_CNT) {
LOGE("invalid stream type");
lStatus = BAD_VALUE;
goto Exit;
@@ -334,7 +404,7 @@
}
LOGV("createTrack() sessionId: %d", (sessionId == NULL) ? -2 : *sessionId);
- if (sessionId != NULL && *sessionId != AudioSystem::SESSION_OUTPUT_MIX) {
+ if (sessionId != NULL && *sessionId != AUDIO_SESSION_OUTPUT_MIX) {
for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
sp<PlaybackThread> t = mPlaybackThreads.valueAt(i);
if (mPlaybackThreads.keyAt(i) != output) {
@@ -353,7 +423,7 @@
lSessionId = *sessionId;
} else {
// if no audio session id is provided, create one here
- lSessionId = nextUniqueId_l();
+ lSessionId = nextUniqueId();
if (sessionId != NULL) {
*sessionId = lSessionId;
}
@@ -361,7 +431,7 @@
LOGV("createTrack() lSessionId: %d", lSessionId);
track = thread->createTrack_l(client, streamType, sampleRate, format,
- channelCount, frameCount, sharedBuffer, lSessionId, &lStatus);
+ channelMask, frameCount, sharedBuffer, lSessionId, &lStatus);
// move effect chain to this output thread if an effect on same session was waiting
// for a track to be created
@@ -409,7 +479,7 @@
return thread->channelCount();
}
-int AudioFlinger::format(int output) const
+uint32_t AudioFlinger::format(int output) const
{
Mutex::Autolock _l(mLock);
PlaybackThread *thread = checkPlaybackThread_l(output);
@@ -453,7 +523,7 @@
{ // scope for the lock
AutoMutex lock(mHardwareLock);
mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
- if (mAudioHardware->setMasterVolume(value) == NO_ERROR) {
+ if (mPrimaryHardwareDev->set_master_volume(mPrimaryHardwareDev, value) == NO_ERROR) {
value = 1.0f;
}
mHardwareStatus = AUDIO_HW_IDLE;
@@ -475,7 +545,7 @@
if (!settingsAllowed()) {
return PERMISSION_DENIED;
}
- if ((mode < 0) || (mode >= AudioSystem::NUM_MODES)) {
+ if ((mode < 0) || (mode >= AUDIO_MODE_CNT)) {
LOGW("Illegal value: setMode(%d)", mode);
return BAD_VALUE;
}
@@ -483,7 +553,7 @@
{ // scope for the lock
AutoMutex lock(mHardwareLock);
mHardwareStatus = AUDIO_HW_SET_MODE;
- ret = mAudioHardware->setMode(mode);
+ ret = mPrimaryHardwareDev->set_mode(mPrimaryHardwareDev, mode);
mHardwareStatus = AUDIO_HW_IDLE;
}
@@ -506,16 +576,16 @@
AutoMutex lock(mHardwareLock);
mHardwareStatus = AUDIO_HW_SET_MIC_MUTE;
- status_t ret = mAudioHardware->setMicMute(state);
+ status_t ret = mPrimaryHardwareDev->set_mic_mute(mPrimaryHardwareDev, state);
mHardwareStatus = AUDIO_HW_IDLE;
return ret;
}
bool AudioFlinger::getMicMute() const
{
- bool state = AudioSystem::MODE_INVALID;
+ bool state = AUDIO_MODE_INVALID;
mHardwareStatus = AUDIO_HW_GET_MIC_MUTE;
- mAudioHardware->getMicMute(&state);
+ mPrimaryHardwareDev->get_mic_mute(mPrimaryHardwareDev, &state);
mHardwareStatus = AUDIO_HW_IDLE;
return state;
}
@@ -552,7 +622,7 @@
return PERMISSION_DENIED;
}
- if (stream < 0 || uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES) {
+ if (stream < 0 || uint32_t(stream) >= AUDIO_STREAM_CNT) {
return BAD_VALUE;
}
@@ -585,8 +655,8 @@
return PERMISSION_DENIED;
}
- if (stream < 0 || uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES ||
- uint32_t(stream) == AudioSystem::ENFORCED_AUDIBLE) {
+ if (stream < 0 || uint32_t(stream) >= AUDIO_STREAM_CNT ||
+ uint32_t(stream) == AUDIO_STREAM_ENFORCED_AUDIBLE) {
return BAD_VALUE;
}
@@ -600,7 +670,7 @@
float AudioFlinger::streamVolume(int stream, int output) const
{
- if (stream < 0 || uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES) {
+ if (stream < 0 || uint32_t(stream) >= AUDIO_STREAM_CNT) {
return 0.0f;
}
@@ -621,7 +691,7 @@
bool AudioFlinger::streamMute(int stream) const
{
- if (stream < 0 || stream >= (int)AudioSystem::NUM_STREAM_TYPES) {
+ if (stream < 0 || stream >= (int)AUDIO_STREAM_CNT) {
return true;
}
@@ -643,9 +713,39 @@
if (ioHandle == 0) {
AutoMutex lock(mHardwareLock);
mHardwareStatus = AUDIO_SET_PARAMETER;
- result = mAudioHardware->setParameters(keyValuePairs);
+ status_t final_result = NO_ERROR;
+ for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
+ audio_hw_device_t *dev = mAudioHwDevs[i];
+ result = dev->set_parameters(dev, keyValuePairs.string());
+ final_result = result ?: final_result;
+ }
mHardwareStatus = AUDIO_HW_IDLE;
- return result;
+ // disable AEC and NS if the device is a BT SCO headset supporting those pre processings
+ AudioParameter param = AudioParameter(keyValuePairs);
+ String8 value;
+ if (param.get(String8(AUDIO_PARAMETER_KEY_BT_NREC), value) == NO_ERROR) {
+ Mutex::Autolock _l(mLock);
+ bool btNrec = (value == AUDIO_PARAMETER_VALUE_ON);
+ if (mBtNrec != btNrec) {
+ for (size_t i = 0; i < mRecordThreads.size(); i++) {
+ sp<RecordThread> thread = mRecordThreads.valueAt(i);
+ RecordThread::RecordTrack *track = thread->track();
+ if (track != NULL) {
+ audio_devices_t device = (audio_devices_t)(
+ thread->device() & AUDIO_DEVICE_IN_ALL);
+ bool suspend = audio_is_bluetooth_sco_device(device) && btNrec;
+ thread->setEffectSuspended(FX_IID_AEC,
+ suspend,
+ track->sessionId());
+ thread->setEffectSuspended(FX_IID_NS,
+ suspend,
+ track->sessionId());
+ }
+ }
+ mBtNrec = btNrec;
+ }
+ }
+ return final_result;
}
// hold a strong ref on thread in case closeOutput() or closeInput() is called
@@ -656,6 +756,15 @@
thread = checkPlaybackThread_l(ioHandle);
if (thread == NULL) {
thread = checkRecordThread_l(ioHandle);
+ } else if (thread.get() == primaryPlaybackThread_l()) {
+ // indicate output device change to all input threads for pre processing
+ AudioParameter param = AudioParameter(keyValuePairs);
+ int value;
+ if (param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR) {
+ for (size_t i = 0; i < mRecordThreads.size(); i++) {
+ mRecordThreads.valueAt(i)->setParameters(keyValuePairs);
+ }
+ }
}
}
if (thread != NULL) {
@@ -671,7 +780,15 @@
// ioHandle, keys.string(), gettid(), IPCThreadState::self()->getCallingPid());
if (ioHandle == 0) {
- return mAudioHardware->getParameters(keys);
+ String8 out_s8;
+
+ for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
+ audio_hw_device_t *dev = mAudioHwDevs[i];
+ char *s = dev->get_parameters(dev, keys.string());
+ out_s8 += String8(s);
+ free(s);
+ }
+ return out_s8;
}
Mutex::Autolock _l(mLock);
@@ -689,7 +806,7 @@
size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
{
- return mAudioHardware->getInputBufferSize(sampleRate, format, channelCount);
+ return mPrimaryHardwareDev->get_input_buffer_size(mPrimaryHardwareDev, sampleRate, format, channelCount);
}
unsigned int AudioFlinger::getInputFramesLost(int ioHandle)
@@ -716,7 +833,7 @@
AutoMutex lock(mHardwareLock);
mHardwareStatus = AUDIO_SET_VOICE_VOLUME;
- status_t ret = mAudioHardware->setVoiceVolume(value);
+ status_t ret = mPrimaryHardwareDev->set_voice_volume(mPrimaryHardwareDev, value);
mHardwareStatus = AUDIO_HW_IDLE;
return ret;
@@ -796,17 +913,21 @@
// ----------------------------------------------------------------------------
-AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, int id)
+AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, int id, uint32_t device)
: Thread(false),
mAudioFlinger(audioFlinger), mSampleRate(0), mFrameCount(0), mChannelCount(0),
- mFrameSize(1), mFormat(0), mStandby(false), mId(id), mExiting(false)
+ mFrameSize(1), mFormat(0), mStandby(false), mId(id), mExiting(false),
+ mDevice(device)
{
+ mDeathRecipient = new PMDeathRecipient(this);
}
AudioFlinger::ThreadBase::~ThreadBase()
{
mParamCond.broadcast();
mNewParameters.clear();
+ // do not lock the mutex in destructor
+ releaseWakeLock_l();
}
void AudioFlinger::ThreadBase::exit()
@@ -835,7 +956,7 @@
return (int)mChannelCount;
}
-int AudioFlinger::ThreadBase::format() const
+uint32_t AudioFlinger::ThreadBase::format() const
{
return mFormat;
}
@@ -921,6 +1042,8 @@
result.append(buffer);
snprintf(buffer, SIZE, "Channel Count: %d\n", mChannelCount);
result.append(buffer);
+ snprintf(buffer, SIZE, "Channel Mask: 0x%08x\n", mChannelMask);
+ result.append(buffer);
snprintf(buffer, SIZE, "Format: %d\n", mFormat);
result.append(buffer);
snprintf(buffer, SIZE, "Frame size: %d\n", mFrameSize);
@@ -953,21 +1076,240 @@
return NO_ERROR;
}
+status_t AudioFlinger::ThreadBase::dumpEffectChains(int fd, const Vector<String16>& args)
+{
+ const size_t SIZE = 256;
+ char buffer[SIZE];
+ String8 result;
+
+ snprintf(buffer, SIZE, "\n- %d Effect Chains:\n", mEffectChains.size());
+ write(fd, buffer, strlen(buffer));
+
+ for (size_t i = 0; i < mEffectChains.size(); ++i) {
+ sp<EffectChain> chain = mEffectChains[i];
+ if (chain != 0) {
+ chain->dump(fd, args);
+ }
+ }
+ return NO_ERROR;
+}
+
+void AudioFlinger::ThreadBase::acquireWakeLock()
+{
+ Mutex::Autolock _l(mLock);
+ acquireWakeLock_l();
+}
+
+void AudioFlinger::ThreadBase::acquireWakeLock_l()
+{
+ if (mPowerManager == 0) {
+ // use checkService() to avoid blocking if power service is not up yet
+ sp<IBinder> binder =
+ defaultServiceManager()->checkService(String16("power"));
+ if (binder == 0) {
+ LOGW("Thread %s cannot connect to the power manager service", mName);
+ } else {
+ mPowerManager = interface_cast<IPowerManager>(binder);
+ binder->linkToDeath(mDeathRecipient);
+ }
+ }
+ if (mPowerManager != 0) {
+ sp<IBinder> binder = new BBinder();
+ status_t status = mPowerManager->acquireWakeLock(POWERMANAGER_PARTIAL_WAKE_LOCK,
+ binder,
+ String16(mName));
+ if (status == NO_ERROR) {
+ mWakeLockToken = binder;
+ }
+ LOGV("acquireWakeLock_l() %s status %d", mName, status);
+ }
+}
+
+void AudioFlinger::ThreadBase::releaseWakeLock()
+{
+ Mutex::Autolock _l(mLock);
+ releaseWakeLock_l();
+}
+
+void AudioFlinger::ThreadBase::releaseWakeLock_l()
+{
+ if (mWakeLockToken != 0) {
+ LOGV("releaseWakeLock_l() %s", mName);
+ if (mPowerManager != 0) {
+ mPowerManager->releaseWakeLock(mWakeLockToken, 0);
+ }
+ mWakeLockToken.clear();
+ }
+}
+
+void AudioFlinger::ThreadBase::clearPowerManager()
+{
+ Mutex::Autolock _l(mLock);
+ releaseWakeLock_l();
+ mPowerManager.clear();
+}
+
+void AudioFlinger::ThreadBase::PMDeathRecipient::binderDied(const wp<IBinder>& who)
+{
+ sp<ThreadBase> thread = mThread.promote();
+ if (thread != 0) {
+ thread->clearPowerManager();
+ }
+ LOGW("power manager service died !!!");
+}
+
+void AudioFlinger::ThreadBase::setEffectSuspended(
+ const effect_uuid_t *type, bool suspend, int sessionId)
+{
+ Mutex::Autolock _l(mLock);
+ setEffectSuspended_l(type, suspend, sessionId);
+}
+
+void AudioFlinger::ThreadBase::setEffectSuspended_l(
+ const effect_uuid_t *type, bool suspend, int sessionId)
+{
+ sp<EffectChain> chain;
+ chain = getEffectChain_l(sessionId);
+ if (chain != 0) {
+ if (type != NULL) {
+ chain->setEffectSuspended_l(type, suspend);
+ } else {
+ chain->setEffectSuspendedAll_l(suspend);
+ }
+ }
+
+ updateSuspendedSessions_l(type, suspend, sessionId);
+}
+
+void AudioFlinger::ThreadBase::checkSuspendOnAddEffectChain_l(const sp<EffectChain>& chain)
+{
+ int index = mSuspendedSessions.indexOfKey(chain->sessionId());
+ if (index < 0) {
+ return;
+ }
+
+ KeyedVector <int, sp<SuspendedSessionDesc> > sessionEffects =
+ mSuspendedSessions.editValueAt(index);
+
+ for (size_t i = 0; i < sessionEffects.size(); i++) {
+ sp <SuspendedSessionDesc> desc = sessionEffects.valueAt(i);
+ for (int j = 0; j < desc->mRefCount; j++) {
+ if (sessionEffects.keyAt(i) == EffectChain::kKeyForSuspendAll) {
+ chain->setEffectSuspendedAll_l(true);
+ } else {
+ LOGV("checkSuspendOnAddEffectChain_l() suspending effects %08x",
+ desc->mType.timeLow);
+ chain->setEffectSuspended_l(&desc->mType, true);
+ }
+ }
+ }
+}
+
+void AudioFlinger::ThreadBase::updateSuspendedSessionsOnRemoveEffectChain_l(
+ const sp<EffectChain>& chain)
+{
+ int index = mSuspendedSessions.indexOfKey(chain->sessionId());
+ if (index < 0) {
+ return;
+ }
+ LOGV("updateSuspendedSessionsOnRemoveEffectChain_l() removed suspended session %d",
+ chain->sessionId());
+ mSuspendedSessions.removeItemsAt(index);
+}
+
+void AudioFlinger::ThreadBase::updateSuspendedSessions_l(const effect_uuid_t *type,
+ bool suspend,
+ int sessionId)
+{
+ int index = mSuspendedSessions.indexOfKey(sessionId);
+
+ KeyedVector <int, sp<SuspendedSessionDesc> > sessionEffects;
+
+ if (suspend) {
+ if (index >= 0) {
+ sessionEffects = mSuspendedSessions.editValueAt(index);
+ } else {
+ mSuspendedSessions.add(sessionId, sessionEffects);
+ }
+ } else {
+ if (index < 0) {
+ return;
+ }
+ sessionEffects = mSuspendedSessions.editValueAt(index);
+ }
+
+
+ int key = EffectChain::kKeyForSuspendAll;
+ if (type != NULL) {
+ key = type->timeLow;
+ }
+ index = sessionEffects.indexOfKey(key);
+
+ sp <SuspendedSessionDesc> desc;
+ if (suspend) {
+ if (index >= 0) {
+ desc = sessionEffects.valueAt(index);
+ } else {
+ desc = new SuspendedSessionDesc();
+ if (type != NULL) {
+ memcpy(&desc->mType, type, sizeof(effect_uuid_t));
+ }
+ sessionEffects.add(key, desc);
+ LOGV("updateSuspendedSessions_l() suspend adding effect %08x", key);
+ }
+ desc->mRefCount++;
+ } else {
+ if (index < 0) {
+ return;
+ }
+ desc = sessionEffects.valueAt(index);
+ if (--desc->mRefCount == 0) {
+ LOGV("updateSuspendedSessions_l() restore removing effect %08x", key);
+ sessionEffects.removeItemsAt(index);
+ if (sessionEffects.isEmpty()) {
+ LOGV("updateSuspendedSessions_l() restore removing session %d",
+ sessionId);
+ mSuspendedSessions.removeItem(sessionId);
+ }
+ }
+ }
+ if (!sessionEffects.isEmpty()) {
+ mSuspendedSessions.replaceValueFor(sessionId, sessionEffects);
+ }
+}
+
+void AudioFlinger::ThreadBase::checkSuspendOnEffectEnabled(const sp<EffectModule>& effect,
+ bool enabled,
+ int sessionId)
+{
+ Mutex::Autolock _l(mLock);
+
+ // TODO: implement PlaybackThread or RecordThread specific behavior here
+
+ sp<EffectChain> chain = getEffectChain_l(sessionId);
+ if (chain != 0) {
+ chain->checkSuspendOnEffectEnabled(effect, enabled);
+ }
+}
// ----------------------------------------------------------------------------
-AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id, uint32_t device)
- : ThreadBase(audioFlinger, id),
+AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinger,
+ AudioStreamOut* output,
+ int id,
+ uint32_t device)
+ : ThreadBase(audioFlinger, id, device),
mMixBuffer(0), mSuspended(0), mBytesWritten(0), mOutput(output),
- mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false),
- mDevice(device)
+ mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false)
{
+ snprintf(mName, kNameLength, "AudioOut_%d", id);
+
readOutputParameters();
mMasterVolume = mAudioFlinger->masterVolume();
mMasterMute = mAudioFlinger->masterMute();
- for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
+ for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
mStreamTypes[stream].volume = mAudioFlinger->streamVolumeInternal(stream);
mStreamTypes[stream].mute = mAudioFlinger->streamMute(stream);
}
@@ -994,7 +1336,7 @@
snprintf(buffer, SIZE, "Output thread %p tracks\n", this);
result.append(buffer);
- result.append(" Name Clien Typ Fmt Chn Session Buf S M F SRate LeftV RighV Serv User Main buf Aux Buf\n");
+ result.append(" Name Clien Typ Fmt Chn mask Session Buf S M F SRate LeftV RighV Serv User Main buf Aux Buf\n");
for (size_t i = 0; i < mTracks.size(); ++i) {
sp<Track> track = mTracks[i];
if (track != 0) {
@@ -1005,7 +1347,7 @@
snprintf(buffer, SIZE, "Output thread %p active tracks\n", this);
result.append(buffer);
- result.append(" Name Clien Typ Fmt Chn Session Buf S M F SRate LeftV RighV Serv User Main buf Aux Buf\n");
+ result.append(" Name Clien Typ Fmt Chn mask Session Buf S M F SRate LeftV RighV Serv User Main buf Aux Buf\n");
for (size_t i = 0; i < mActiveTracks.size(); ++i) {
wp<Track> wTrack = mActiveTracks[i];
if (wTrack != 0) {
@@ -1020,24 +1362,6 @@
return NO_ERROR;
}
-status_t AudioFlinger::PlaybackThread::dumpEffectChains(int fd, const Vector<String16>& args)
-{
- const size_t SIZE = 256;
- char buffer[SIZE];
- String8 result;
-
- snprintf(buffer, SIZE, "\n- %d Effect Chains:\n", mEffectChains.size());
- write(fd, buffer, strlen(buffer));
-
- for (size_t i = 0; i < mEffectChains.size(); ++i) {
- sp<EffectChain> chain = mEffectChains[i];
- if (chain != 0) {
- chain->dump(fd, args);
- }
- }
- return NO_ERROR;
-}
-
status_t AudioFlinger::PlaybackThread::dumpInternals(int fd, const Vector<String16>& args)
{
const size_t SIZE = 256;
@@ -1078,12 +1402,7 @@
void AudioFlinger::PlaybackThread::onFirstRef()
{
- const size_t SIZE = 256;
- char buffer[SIZE];
-
- snprintf(buffer, SIZE, "Playback Thread %p", this);
-
- run(buffer, ANDROID_PRIORITY_URGENT_AUDIO);
+ run(mName, ANDROID_PRIORITY_URGENT_AUDIO);
}
// PlaybackThread::createTrack_l() must be called with AudioFlinger::mLock held
@@ -1091,8 +1410,8 @@
const sp<AudioFlinger::Client>& client,
int streamType,
uint32_t sampleRate,
- int format,
- int channelCount,
+ uint32_t format,
+ uint32_t channelMask,
int frameCount,
const sp<IMemory>& sharedBuffer,
int sessionId,
@@ -1102,11 +1421,14 @@
status_t lStatus;
if (mType == DIRECT) {
- if (sampleRate != mSampleRate || format != mFormat || channelCount != (int)mChannelCount) {
- LOGE("createTrack_l() Bad parameter: sampleRate %d format %d, channelCount %d for output %p",
- sampleRate, format, channelCount, mOutput);
- lStatus = BAD_VALUE;
- goto Exit;
+ if ((format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_PCM) {
+ if (sampleRate != mSampleRate || format != mFormat || channelMask != mChannelMask) {
+ LOGE("createTrack_l() Bad parameter: sampleRate %d format %d, channelMask 0x%08x \""
+ "for output %p with format %d",
+ sampleRate, format, channelMask, mOutput, mFormat);
+ lStatus = BAD_VALUE;
+ goto Exit;
+ }
}
} else {
// Resampler implementation limits input sampling rate to 2 x output sampling rate.
@@ -1117,9 +1439,9 @@
}
}
- if (mOutput == 0) {
+ lStatus = initCheck();
+ if (lStatus != NO_ERROR) {
LOGE("Audio driver not initialized.");
- lStatus = NO_INIT;
goto Exit;
}
@@ -1130,12 +1452,12 @@
// conflicts will happen when tracks are moved from one output to another by audio policy
// manager
uint32_t strategy =
- AudioSystem::getStrategyForStream((AudioSystem::stream_type)streamType);
+ AudioSystem::getStrategyForStream((audio_stream_type_t)streamType);
for (size_t i = 0; i < mTracks.size(); ++i) {
sp<Track> t = mTracks[i];
if (t != 0) {
if (sessionId == t->sessionId() &&
- strategy != AudioSystem::getStrategyForStream((AudioSystem::stream_type)t->type())) {
+ strategy != AudioSystem::getStrategyForStream((audio_stream_type_t)t->type())) {
lStatus = BAD_VALUE;
goto Exit;
}
@@ -1143,7 +1465,7 @@
}
track = new Track(this, client, streamType, sampleRate, format,
- channelCount, frameCount, sharedBuffer, sessionId);
+ channelMask, frameCount, sharedBuffer, sessionId);
if (track->getCblk() == NULL || track->name() < 0) {
lStatus = NO_MEMORY;
goto Exit;
@@ -1154,7 +1476,8 @@
if (chain != 0) {
LOGV("createTrack_l() setting main buffer %p", chain->inBuffer());
track->setMainBuffer(chain->inBuffer());
- chain->setStrategy(AudioSystem::getStrategyForStream((AudioSystem::stream_type)track->type()));
+ chain->setStrategy(AudioSystem::getStrategyForStream((audio_stream_type_t)track->type()));
+ chain->incTrackCnt();
}
}
lStatus = NO_ERROR;
@@ -1169,7 +1492,7 @@
uint32_t AudioFlinger::PlaybackThread::latency() const
{
if (mOutput) {
- return mOutput->latency();
+ return mOutput->stream->get_latency(mOutput->stream);
}
else {
return 0;
@@ -1238,7 +1561,7 @@
sp<EffectChain> chain = getEffectChain_l(track->sessionId());
if (chain != 0) {
LOGV("addTrack_l() starting track on chain %p for session %d", chain.get(), track->sessionId());
- chain->startTrack();
+ chain->incActiveTrackCnt();
}
}
@@ -1256,14 +1579,29 @@
{
track->mState = TrackBase::TERMINATED;
if (mActiveTracks.indexOf(track) < 0) {
- mTracks.remove(track);
- deleteTrackName_l(track->name());
+ removeTrack_l(track);
+ }
+}
+
+void AudioFlinger::PlaybackThread::removeTrack_l(const sp<Track>& track)
+{
+ mTracks.remove(track);
+ deleteTrackName_l(track->name());
+ sp<EffectChain> chain = getEffectChain_l(track->sessionId());
+ if (chain != 0) {
+ chain->decTrackCnt();
}
}
String8 AudioFlinger::PlaybackThread::getParameters(const String8& keys)
{
- return mOutput->getParameters(keys);
+ String8 out_s8;
+ char *s;
+
+ s = mOutput->stream->common.get_parameters(&mOutput->stream->common, keys.string());
+ out_s8 = String8(s);
+ free(s);
+ return out_s8;
}
// destroyTrack_l() must be called with AudioFlinger::mLock held
@@ -1276,7 +1614,7 @@
switch (event) {
case AudioSystem::OUTPUT_OPENED:
case AudioSystem::OUTPUT_CONFIG_CHANGED:
- desc.channels = mChannels;
+ desc.channels = mChannelMask;
desc.samplingRate = mSampleRate;
desc.format = mFormat;
desc.frameCount = mFrameCount;
@@ -1295,12 +1633,12 @@
void AudioFlinger::PlaybackThread::readOutputParameters()
{
- mSampleRate = mOutput->sampleRate();
- mChannels = mOutput->channels();
- mChannelCount = (uint16_t)AudioSystem::popCount(mChannels);
- mFormat = mOutput->format();
- mFrameSize = (uint16_t)mOutput->frameSize();
- mFrameCount = mOutput->bufferSize() / mFrameSize;
+ mSampleRate = mOutput->stream->common.get_sample_rate(&mOutput->stream->common);
+ mChannelMask = mOutput->stream->common.get_channels(&mOutput->stream->common);
+ mChannelCount = (uint16_t)popcount(mChannelMask);
+ mFormat = mOutput->stream->common.get_format(&mOutput->stream->common);
+ mFrameSize = (uint16_t)audio_stream_frame_size(&mOutput->stream->common);
+ mFrameCount = mOutput->stream->common.get_buffer_size(&mOutput->stream->common) / mFrameSize;
// FIXME - Current mixer implementation only supports stereo output: Always
// Allocate a stereo buffer even if HW output is mono.
@@ -1325,12 +1663,12 @@
if (halFrames == 0 || dspFrames == 0) {
return BAD_VALUE;
}
- if (mOutput == 0) {
+ if (initCheck() != NO_ERROR) {
return INVALID_OPERATION;
}
- *halFrames = mBytesWritten/mOutput->frameSize();
+ *halFrames = mBytesWritten / audio_stream_frame_size(&mOutput->stream->common);
- return mOutput->getRenderPosition(dspFrames);
+ return mOutput->stream->get_render_position(mOutput->stream, dspFrames);
}
uint32_t AudioFlinger::PlaybackThread::hasAudioSession(int sessionId)
@@ -1355,49 +1693,21 @@
uint32_t AudioFlinger::PlaybackThread::getStrategyForSession_l(int sessionId)
{
- // session AudioSystem::SESSION_OUTPUT_MIX is placed in same strategy as MUSIC stream so that
+ // session AUDIO_SESSION_OUTPUT_MIX is placed in same strategy as MUSIC stream so that
// it is moved to correct output by audio policy manager when A2DP is connected or disconnected
- if (sessionId == AudioSystem::SESSION_OUTPUT_MIX) {
- return AudioSystem::getStrategyForStream(AudioSystem::MUSIC);
+ if (sessionId == AUDIO_SESSION_OUTPUT_MIX) {
+ return AudioSystem::getStrategyForStream(AUDIO_STREAM_MUSIC);
}
for (size_t i = 0; i < mTracks.size(); i++) {
sp<Track> track = mTracks[i];
if (sessionId == track->sessionId() &&
!(track->mCblk->flags & CBLK_INVALID_MSK)) {
- return AudioSystem::getStrategyForStream((AudioSystem::stream_type) track->type());
+ return AudioSystem::getStrategyForStream((audio_stream_type_t) track->type());
}
}
- return AudioSystem::getStrategyForStream(AudioSystem::MUSIC);
+ return AudioSystem::getStrategyForStream(AUDIO_STREAM_MUSIC);
}
-sp<AudioFlinger::EffectChain> AudioFlinger::PlaybackThread::getEffectChain(int sessionId)
-{
- Mutex::Autolock _l(mLock);
- return getEffectChain_l(sessionId);
-}
-
-sp<AudioFlinger::EffectChain> AudioFlinger::PlaybackThread::getEffectChain_l(int sessionId)
-{
- sp<EffectChain> chain;
-
- size_t size = mEffectChains.size();
- for (size_t i = 0; i < size; i++) {
- if (mEffectChains[i]->sessionId() == sessionId) {
- chain = mEffectChains[i];
- break;
- }
- }
- return chain;
-}
-
-void AudioFlinger::PlaybackThread::setMode(uint32_t mode)
-{
- Mutex::Autolock _l(mLock);
- size_t size = mEffectChains.size();
- for (size_t i = 0; i < size; i++) {
- mEffectChains[i]->setMode_l(mode);
- }
-}
// ----------------------------------------------------------------------------
@@ -1405,7 +1715,7 @@
: PlaybackThread(audioFlinger, output, id, device),
mAudioMixer(0)
{
- mType = PlaybackThread::MIXER;
+ mType = ThreadBase::MIXER;
mAudioMixer = new AudioMixer(mFrameCount, mSampleRate);
// FIXME - Current mixer implementation only supports stereo output
@@ -1434,9 +1744,42 @@
uint32_t idleSleepTime = idleSleepTimeUs();
uint32_t sleepTime = idleSleepTime;
Vector< sp<EffectChain> > effectChains;
+#ifdef DEBUG_CPU_USAGE
+ ThreadCpuUsage cpu;
+ const CentralTendencyStatistics& stats = cpu.statistics();
+#endif
+
+ acquireWakeLock();
while (!exitPending())
{
+#ifdef DEBUG_CPU_USAGE
+ cpu.sampleAndEnable();
+ unsigned n = stats.n();
+ // cpu.elapsed() is expensive, so don't call it every loop
+ if ((n & 127) == 1) {
+ long long elapsed = cpu.elapsed();
+ if (elapsed >= DEBUG_CPU_USAGE * 1000000000LL) {
+ double perLoop = elapsed / (double) n;
+ double perLoop100 = perLoop * 0.01;
+ double mean = stats.mean();
+ double stddev = stats.stddev();
+ double minimum = stats.minimum();
+ double maximum = stats.maximum();
+ cpu.resetStatistics();
+ LOGI("CPU usage over past %.1f secs (%u mixer loops at %.1f mean ms per loop):\n us per mix loop: mean=%.0f stddev=%.0f min=%.0f max=%.0f\n %% of wall: mean=%.1f stddev=%.1f min=%.1f max=%.1f",
+ elapsed * .000000001, n, perLoop * .000001,
+ mean * .001,
+ stddev * .001,
+ minimum * .001,
+ maximum * .001,
+ mean / perLoop100,
+ stddev / perLoop100,
+ minimum / perLoop100,
+ maximum / perLoop100);
+ }
+ }
+#endif
processConfigEvents();
mixerStatus = MIXER_IDLE;
@@ -1460,7 +1803,7 @@
mSuspended) {
if (!mStandby) {
LOGV("Audio hardware entering standby, mixer %p, mSuspended %d\n", this, mSuspended);
- mOutput->standby();
+ mOutput->stream->common.standby(&mOutput->stream->common);
mStandby = true;
mBytesWritten = 0;
}
@@ -1471,10 +1814,12 @@
if (exitPending()) break;
+ releaseWakeLock_l();
// wait until we have something to do...
LOGV("MixerThread %p TID %d going to sleep\n", this, gettid());
mWaitWorkCV.wait(mLock);
LOGV("MixerThread %p TID %d waking up\n", this, gettid());
+ acquireWakeLock_l();
if (mMasterMute == false) {
char value[PROPERTY_VALUE_MAX];
@@ -1537,7 +1882,7 @@
mInWrite = true;
mBytesWritten += mixBufferSize;
- int bytesWritten = (int)mOutput->write(mMixBuffer, mixBufferSize);
+ int bytesWritten = (int)mOutput->stream->write(mOutput->stream, mMixBuffer, mixBufferSize);
if (bytesWritten < 0) mBytesWritten -= mixBufferSize;
mNumWrites++;
mInWrite = false;
@@ -1572,9 +1917,11 @@
}
if (!mStandby) {
- mOutput->standby();
+ mOutput->stream->common.standby(&mOutput->stream->common);
}
+ releaseWakeLock();
+
LOGV("MixerThread %p exiting", this);
return false;
}
@@ -1596,7 +1943,7 @@
masterVolume = 0;
}
// Delegate master volume control to effect in output mix effect chain if needed
- sp<EffectChain> chain = getEffectChain_l(AudioSystem::SESSION_OUTPUT_MIX);
+ sp<EffectChain> chain = getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX);
if (chain != 0) {
uint32_t v = (uint32_t)(masterVolume * (1 << 24));
chain->setVolume_l(&v, &v);
@@ -1707,7 +2054,7 @@
AudioMixer::FORMAT, (void *)track->format());
mAudioMixer->setParameter(
AudioMixer::TRACK,
- AudioMixer::CHANNEL_COUNT, (void *)track->channelCount());
+ AudioMixer::CHANNEL_MASK, (void *)track->channelMask());
mAudioMixer->setParameter(
AudioMixer::RESAMPLE,
AudioMixer::SAMPLE_RATE,
@@ -1738,7 +2085,7 @@
LOGV("BUFFER TIMEOUT: remove(%d) from active list on thread %p", track->name(), this);
tracksToRemove->add(track);
// indicate to client process that the track was disabled because of underrun
- cblk->flags |= CBLK_DISABLED_ON;
+ android_atomic_or(CBLK_DISABLED_ON, &cblk->flags);
} else if (mixerStatus != MIXER_TRACKS_READY) {
mixerStatus = MIXER_TRACKS_ENABLED;
}
@@ -1757,12 +2104,11 @@
chain = getEffectChain_l(track->sessionId());
if (chain != 0) {
LOGV("stopping track on chain %p for session Id: %d", chain.get(), track->sessionId());
- chain->stopTrack();
+ chain->decActiveTrackCnt();
}
}
if (track->isTerminated()) {
- mTracks.remove(track);
- deleteTrackName_l(track->mName);
+ removeTrack_l(track);
}
}
}
@@ -1787,10 +2133,8 @@
for (size_t i = 0; i < size; i++) {
sp<Track> t = mTracks[i];
if (t->type() == streamType) {
- t->mCblk->lock.lock();
- t->mCblk->flags |= CBLK_INVALID_ON;
+ android_atomic_or(CBLK_INVALID_ON, &t->mCblk->flags);
t->mCblk->cv.signal();
- t->mCblk->lock.unlock();
}
}
}
@@ -1824,14 +2168,14 @@
reconfig = true;
}
if (param.getInt(String8(AudioParameter::keyFormat), value) == NO_ERROR) {
- if (value != AudioSystem::PCM_16_BIT) {
+ if (value != AUDIO_FORMAT_PCM_16_BIT) {
status = BAD_VALUE;
} else {
reconfig = true;
}
}
if (param.getInt(String8(AudioParameter::keyChannels), value) == NO_ERROR) {
- if (value != AudioSystem::CHANNEL_OUT_STEREO) {
+ if (value != AUDIO_CHANNEL_OUT_STEREO) {
status = BAD_VALUE;
} else {
reconfig = true;
@@ -1850,15 +2194,15 @@
if (param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR) {
// when changing the audio output device, call addBatteryData to notify
// the change
- if (mDevice != value) {
+ if ((int)mDevice != value) {
uint32_t params = 0;
// check whether speaker is on
- if (value & AudioSystem::DEVICE_OUT_SPEAKER) {
+ if (value & AUDIO_DEVICE_OUT_SPEAKER) {
params |= IMediaPlayerService::kBatteryDataSpeakerOn;
}
int deviceWithoutSpeaker
- = AudioSystem::DEVICE_OUT_ALL & ~AudioSystem::DEVICE_OUT_SPEAKER;
+ = AUDIO_DEVICE_OUT_ALL & ~AUDIO_DEVICE_OUT_SPEAKER;
// check if any other device (except speaker) is on
if (value & deviceWithoutSpeaker ) {
params |= IMediaPlayerService::kBatteryDataOtherAudioDeviceOn;
@@ -1878,12 +2222,14 @@
}
if (status == NO_ERROR) {
- status = mOutput->setParameters(keyValuePair);
+ status = mOutput->stream->common.set_parameters(&mOutput->stream->common,
+ keyValuePair.string());
if (!mStandby && status == INVALID_OPERATION) {
- mOutput->standby();
+ mOutput->stream->common.standby(&mOutput->stream->common);
mStandby = true;
mBytesWritten = 0;
- status = mOutput->setParameters(keyValuePair);
+ status = mOutput->stream->common.set_parameters(&mOutput->stream->common,
+ keyValuePair.string());
}
if (status == NO_ERROR && reconfig) {
delete mAudioMixer;
@@ -1927,7 +2273,7 @@
uint32_t AudioFlinger::MixerThread::activeSleepTimeUs()
{
- return (uint32_t)(mOutput->latency() * 1000) / 2;
+ return (uint32_t)(mOutput->stream->get_latency(mOutput->stream) * 1000) / 2;
}
uint32_t AudioFlinger::MixerThread::idleSleepTimeUs()
@@ -1944,7 +2290,7 @@
AudioFlinger::DirectOutputThread::DirectOutputThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id, uint32_t device)
: PlaybackThread(audioFlinger, output, id, device)
{
- mType = PlaybackThread::DIRECT;
+ mType = ThreadBase::DIRECT;
}
AudioFlinger::DirectOutputThread::~DirectOutputThread()
@@ -1977,12 +2323,12 @@
void AudioFlinger::DirectOutputThread::applyVolume(uint16_t leftVol, uint16_t rightVol, bool ramp)
{
// Do not apply volume on compressed audio
- if (!AudioSystem::isLinearPCM(mFormat)) {
+ if (!audio_is_linear_pcm(mFormat)) {
return;
}
// convert to signed 16 bit before volume calculation
- if (mFormat == AudioSystem::PCM_8_BIT) {
+ if (mFormat == AUDIO_FORMAT_PCM_8_BIT) {
size_t count = mFrameCount * mChannelCount;
uint8_t *src = (uint8_t *)mMixBuffer + count-1;
int16_t *dst = mMixBuffer + count-1;
@@ -2035,7 +2381,7 @@
}
// convert back to unsigned 8 bit after volume calculation
- if (mFormat == AudioSystem::PCM_8_BIT) {
+ if (mFormat == AUDIO_FORMAT_PCM_8_BIT) {
size_t count = mFrameCount * mChannelCount;
int16_t *src = mMixBuffer;
uint8_t *dst = (uint8_t *)mMixBuffer;
@@ -2063,6 +2409,8 @@
// hardware resources as soon as possible
nsecs_t standbyDelay = microseconds(activeSleepTime*2);
+ acquireWakeLock();
+
while (!exitPending())
{
bool rampVolume;
@@ -2091,7 +2439,7 @@
// wait until we have something to do...
if (!mStandby) {
LOGV("Audio hardware entering standby, mixer %p\n", this);
- mOutput->standby();
+ mOutput->stream->common.standby(&mOutput->stream->common);
mStandby = true;
mBytesWritten = 0;
}
@@ -2102,9 +2450,11 @@
if (exitPending()) break;
+ releaseWakeLock_l();
LOGV("DirectOutputThread %p TID %d going to sleep\n", this, gettid());
mWaitWorkCV.wait(mLock);
LOGV("DirectOutputThread %p TID %d waking up in active mode\n", this, gettid());
+ acquireWakeLock_l();
if (mMasterMute == false) {
char value[PROPERTY_VALUE_MAX];
@@ -2176,7 +2526,7 @@
// If audio HAL implements volume control,
// force software volume to nominal value
- if (mOutput->setVolume(left, right) == NO_ERROR) {
+ if (mOutput->stream->set_volume(mOutput->stream, left, right) == NO_ERROR) {
left = 1.0f;
right = 1.0f;
}
@@ -2240,11 +2590,10 @@
if (!effectChains.isEmpty()) {
LOGV("stopping track on chain %p for session Id: %d", effectChains[0].get(),
trackToRemove->sessionId());
- effectChains[0]->stopTrack();
+ effectChains[0]->decActiveTrackCnt();
}
if (trackToRemove->isTerminated()) {
- mTracks.remove(trackToRemove);
- deleteTrackName_l(trackToRemove->mName);
+ removeTrack_l(trackToRemove);
}
}
@@ -2277,7 +2626,7 @@
} else {
sleepTime = idleSleepTime;
}
- } else if (mBytesWritten != 0 && AudioSystem::isLinearPCM(mFormat)) {
+ } else if (mBytesWritten != 0 && audio_is_linear_pcm(mFormat)) {
memset (mMixBuffer, 0, mFrameCount * mFrameSize);
sleepTime = 0;
}
@@ -2299,7 +2648,7 @@
mLastWriteTime = systemTime();
mInWrite = true;
mBytesWritten += mixBufferSize;
- int bytesWritten = (int)mOutput->write(mMixBuffer, mixBufferSize);
+ int bytesWritten = (int)mOutput->stream->write(mOutput->stream, mMixBuffer, mixBufferSize);
if (bytesWritten < 0) mBytesWritten -= mixBufferSize;
mNumWrites++;
mInWrite = false;
@@ -2321,9 +2670,11 @@
}
if (!mStandby) {
- mOutput->standby();
+ mOutput->stream->common.standby(&mOutput->stream->common);
}
+ releaseWakeLock();
+
LOGV("DirectOutputThread %p exiting", this);
return false;
}
@@ -2361,12 +2712,14 @@
}
}
if (status == NO_ERROR) {
- status = mOutput->setParameters(keyValuePair);
+ status = mOutput->stream->common.set_parameters(&mOutput->stream->common,
+ keyValuePair.string());
if (!mStandby && status == INVALID_OPERATION) {
- mOutput->standby();
+ mOutput->stream->common.standby(&mOutput->stream->common);
mStandby = true;
mBytesWritten = 0;
- status = mOutput->setParameters(keyValuePair);
+ status = mOutput->stream->common.set_parameters(&mOutput->stream->common,
+ keyValuePair.string());
}
if (status == NO_ERROR && reconfig) {
readOutputParameters();
@@ -2386,8 +2739,8 @@
uint32_t AudioFlinger::DirectOutputThread::activeSleepTimeUs()
{
uint32_t time;
- if (AudioSystem::isLinearPCM(mFormat)) {
- time = (uint32_t)(mOutput->latency() * 1000) / 2;
+ if (audio_is_linear_pcm(mFormat)) {
+ time = (uint32_t)(mOutput->stream->get_latency(mOutput->stream) * 1000) / 2;
} else {
time = 10000;
}
@@ -2397,7 +2750,7 @@
uint32_t AudioFlinger::DirectOutputThread::idleSleepTimeUs()
{
uint32_t time;
- if (AudioSystem::isLinearPCM(mFormat)) {
+ if (audio_is_linear_pcm(mFormat)) {
time = (uint32_t)(((mFrameCount * 1000) / mSampleRate) * 1000) / 2;
} else {
time = 10000;
@@ -2408,7 +2761,7 @@
uint32_t AudioFlinger::DirectOutputThread::suspendSleepTimeUs()
{
uint32_t time;
- if (AudioSystem::isLinearPCM(mFormat)) {
+ if (audio_is_linear_pcm(mFormat)) {
time = (uint32_t)(((mFrameCount * 1000) / mSampleRate) * 1000);
} else {
time = 10000;
@@ -2422,7 +2775,7 @@
AudioFlinger::DuplicatingThread::DuplicatingThread(const sp<AudioFlinger>& audioFlinger, AudioFlinger::MixerThread* mainThread, int id)
: MixerThread(audioFlinger, mainThread->getOutput(), id, mainThread->device()), mWaitTimeMs(UINT_MAX)
{
- mType = PlaybackThread::DUPLICATING;
+ mType = ThreadBase::DUPLICATING;
addOutputTrack(mainThread);
}
@@ -2447,6 +2800,8 @@
uint32_t sleepTime = idleSleepTime;
Vector< sp<EffectChain> > effectChains;
+ acquireWakeLock();
+
while (!exitPending())
{
processConfigEvents();
@@ -2487,9 +2842,12 @@
if (exitPending()) break;
+ releaseWakeLock_l();
LOGV("DuplicatingThread %p TID %d going to sleep\n", this, gettid());
mWaitWorkCV.wait(mLock);
LOGV("DuplicatingThread %p TID %d waking up\n", this, gettid());
+ acquireWakeLock_l();
+
if (mMasterMute == false) {
char value[PROPERTY_VALUE_MAX];
property_get("ro.audio.silent", value, "0");
@@ -2576,6 +2934,8 @@
effectChains.clear();
}
+ releaseWakeLock();
+
return false;
}
@@ -2586,10 +2946,10 @@
this,
mSampleRate,
mFormat,
- mChannelCount,
+ mChannelMask,
frameCount);
if (outputTrack->cblk() != NULL) {
- thread->setStreamVolume(AudioSystem::NUM_STREAM_TYPES, 1.0f);
+ thread->setStreamVolume(AUDIO_STREAM_CNT, 1.0f);
mOutputTracks.add(outputTrack);
LOGV("addOutputTrack() track %p, on thread %p", outputTrack, thread);
updateWaitTime();
@@ -2654,8 +3014,8 @@
const wp<ThreadBase>& thread,
const sp<Client>& client,
uint32_t sampleRate,
- int format,
- int channelCount,
+ uint32_t format,
+ uint32_t channelMask,
int frameCount,
uint32_t flags,
const sp<IMemory>& sharedBuffer,
@@ -2675,6 +3035,7 @@
// LOGD("Creating track with %d buffers @ %d bytes", bufferCount, bufferSize);
size_t size = sizeof(audio_track_cblk_t);
+ uint8_t channelCount = popcount(channelMask);
size_t bufferSize = frameCount*channelCount*sizeof(int16_t);
if (sharedBuffer == 0) {
size += bufferSize;
@@ -2689,7 +3050,8 @@
// clear all buffers
mCblk->frameCount = frameCount;
mCblk->sampleRate = sampleRate;
- mCblk->channelCount = (uint8_t)channelCount;
+ mChannelCount = channelCount;
+ mChannelMask = channelMask;
if (sharedBuffer == 0) {
mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));
@@ -2713,7 +3075,8 @@
// clear all buffers
mCblk->frameCount = frameCount;
mCblk->sampleRate = sampleRate;
- mCblk->channelCount = (uint8_t)channelCount;
+ mChannelCount = channelCount;
+ mChannelMask = channelMask;
mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));
// Force underrun condition to avoid false underrun callback until first data is
@@ -2780,7 +3143,11 @@
}
int AudioFlinger::ThreadBase::TrackBase::channelCount() const {
- return (int)mCblk->channelCount;
+ return (const int)mChannelCount;
+}
+
+uint32_t AudioFlinger::ThreadBase::TrackBase::channelMask() const {
+ return mChannelMask;
}
void* AudioFlinger::ThreadBase::TrackBase::getBuffer(uint32_t offset, uint32_t frames) const {
@@ -2792,9 +3159,9 @@
if (bufferStart < mBuffer || bufferStart > bufferEnd || bufferEnd > mBufferEnd ||
((unsigned long)bufferStart & (unsigned long)(cblk->frameSize - 1))) {
LOGE("TrackBase::getBuffer buffer out of range:\n start: %p, end %p , mBuffer %p mBufferEnd %p\n \
- server %d, serverBase %d, user %d, userBase %d, channelCount %d",
+ server %d, serverBase %d, user %d, userBase %d",
bufferStart, bufferEnd, mBuffer, mBufferEnd,
- cblk->server, cblk->serverBase, cblk->user, cblk->userBase, cblk->channelCount);
+ cblk->server, cblk->serverBase, cblk->user, cblk->userBase);
return 0;
}
@@ -2809,12 +3176,12 @@
const sp<Client>& client,
int streamType,
uint32_t sampleRate,
- int format,
- int channelCount,
+ uint32_t format,
+ uint32_t channelMask,
int frameCount,
const sp<IMemory>& sharedBuffer,
int sessionId)
- : TrackBase(thread, client, sampleRate, format, channelCount, frameCount, 0, sharedBuffer, sessionId),
+ : TrackBase(thread, client, sampleRate, format, channelMask, frameCount, 0, sharedBuffer, sessionId),
mMute(false), mSharedBuffer(sharedBuffer), mName(-1), mMainBuffer(NULL), mAuxBuffer(NULL),
mAuxEffectId(0), mHasVolumeController(false)
{
@@ -2834,7 +3201,7 @@
mStreamType = streamType;
// NOTE: audio_track_cblk_t::frameSize for 8 bit PCM data is based on a sample size of
// 16 bit because data is converted to 16 bit before being stored in buffer by AudioTrack
- mCblk->frameSize = AudioSystem::isLinearPCM(format) ? channelCount * sizeof(int16_t) : sizeof(int8_t);
+ mCblk->frameSize = audio_is_linear_pcm(format) ? mChannelCount * sizeof(int16_t) : sizeof(uint8_t);
}
}
@@ -2865,7 +3232,7 @@
if (!isOutputTrack()) {
if (mState == ACTIVE || mState == RESUMING) {
AudioSystem::stopOutput(thread->id(),
- (AudioSystem::stream_type)mStreamType,
+ (audio_stream_type_t)mStreamType,
mSessionId);
// to track the speaker usage
@@ -2882,12 +3249,12 @@
void AudioFlinger::PlaybackThread::Track::dump(char* buffer, size_t size)
{
- snprintf(buffer, size, " %05d %05d %03u %03u %03u %05u %04u %1d %1d %1d %05u %05u %05u 0x%08x 0x%08x 0x%08x 0x%08x\n",
+ snprintf(buffer, size, " %05d %05d %03u %03u 0x%08x %05u %04u %1d %1d %1d %05u %05u %05u 0x%08x 0x%08x 0x%08x 0x%08x\n",
mName - AudioMixer::TRACK0,
(mClient == NULL) ? getpid() : mClient->pid(),
mStreamType,
mFormat,
- mCblk->channelCount,
+ mChannelMask,
mSessionId,
mFrameCount,
mState,
@@ -2949,7 +3316,7 @@
if (mCblk->framesReady() >= mCblk->frameCount ||
(mCblk->flags & CBLK_FORCEREADY_MSK)) {
mFillingUpStatus = FS_FILLED;
- mCblk->flags &= ~CBLK_FORCEREADY_MSK;
+ android_atomic_and(~CBLK_FORCEREADY_MSK, &mCblk->flags);
return true;
}
return false;
@@ -2977,7 +3344,7 @@
if (!isOutputTrack() && state != ACTIVE && state != RESUMING) {
thread->mLock.unlock();
status = AudioSystem::startOutput(thread->id(),
- (AudioSystem::stream_type)mStreamType,
+ (audio_stream_type_t)mStreamType,
mSessionId);
thread->mLock.lock();
@@ -3017,7 +3384,7 @@
if (!isOutputTrack() && (state == ACTIVE || state == RESUMING)) {
thread->mLock.unlock();
AudioSystem::stopOutput(thread->id(),
- (AudioSystem::stream_type)mStreamType,
+ (audio_stream_type_t)mStreamType,
mSessionId);
thread->mLock.lock();
@@ -3039,7 +3406,7 @@
if (!isOutputTrack()) {
thread->mLock.unlock();
AudioSystem::stopOutput(thread->id(),
- (AudioSystem::stream_type)mStreamType,
+ (audio_stream_type_t)mStreamType,
mSessionId);
thread->mLock.lock();
@@ -3063,14 +3430,12 @@
// STOPPED state
mState = STOPPED;
- mCblk->lock.lock();
- // NOTE: reset() will reset cblk->user and cblk->server with
- // the risk that at the same time, the AudioMixer is trying to read
- // data. In this case, getNextBuffer() would return a NULL pointer
- // as audio buffer => the AudioMixer code MUST always test that pointer
- // returned by getNextBuffer() is not NULL!
- reset();
- mCblk->lock.unlock();
+ // do not reset the track if it is still in the process of being stopped or paused.
+ // this will be done by prepareTracks_l() when the track is stopped.
+ PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
+ if (playbackThread->mActiveTracks.indexOf(this) < 0) {
+ reset();
+ }
}
}
@@ -3082,8 +3447,8 @@
TrackBase::reset();
// Force underrun condition to avoid false underrun callback until first data is
// written to buffer
- mCblk->flags |= CBLK_UNDERRUN_ON;
- mCblk->flags &= ~CBLK_FORCEREADY_MSK;
+ android_atomic_and(~CBLK_FORCEREADY_MSK, &mCblk->flags);
+ android_atomic_or(CBLK_UNDERRUN_ON, &mCblk->flags);
mFillingUpStatus = FS_FILLING;
mResetDone = true;
}
@@ -3124,21 +3489,21 @@
const wp<ThreadBase>& thread,
const sp<Client>& client,
uint32_t sampleRate,
- int format,
- int channelCount,
+ uint32_t format,
+ uint32_t channelMask,
int frameCount,
uint32_t flags,
int sessionId)
: TrackBase(thread, client, sampleRate, format,
- channelCount, frameCount, flags, 0, sessionId),
+ channelMask, frameCount, flags, 0, sessionId),
mOverflow(false)
{
if (mCblk != NULL) {
LOGV("RecordTrack constructor, size %d", (int)mBufferEnd - (int)mBuffer);
- if (format == AudioSystem::PCM_16_BIT) {
- mCblk->frameSize = channelCount * sizeof(int16_t);
- } else if (format == AudioSystem::PCM_8_BIT) {
- mCblk->frameSize = channelCount * sizeof(int8_t);
+ if (format == AUDIO_FORMAT_PCM_16_BIT) {
+ mCblk->frameSize = mChannelCount * sizeof(int16_t);
+ } else if (format == AUDIO_FORMAT_PCM_8_BIT) {
+ mCblk->frameSize = mChannelCount * sizeof(int8_t);
} else {
mCblk->frameSize = sizeof(int8_t);
}
@@ -3212,16 +3577,16 @@
TrackBase::reset();
// Force overerrun condition to avoid false overrun callback until first data is
// read from buffer
- mCblk->flags |= CBLK_UNDERRUN_ON;
+ android_atomic_or(CBLK_UNDERRUN_ON, &mCblk->flags);
}
}
void AudioFlinger::RecordThread::RecordTrack::dump(char* buffer, size_t size)
{
- snprintf(buffer, size, " %05d %03u %03u %05d %04u %01d %05u %08x %08x\n",
+ snprintf(buffer, size, " %05d %03u 0x%08x %05d %04u %01d %05u %08x %08x\n",
(mClient == NULL) ? getpid() : mClient->pid(),
mFormat,
- mCblk->channelCount,
+ mChannelMask,
mSessionId,
mFrameCount,
mState,
@@ -3237,10 +3602,10 @@
const wp<ThreadBase>& thread,
DuplicatingThread *sourceThread,
uint32_t sampleRate,
- int format,
- int channelCount,
+ uint32_t format,
+ uint32_t channelMask,
int frameCount)
- : Track(thread, NULL, AudioSystem::NUM_STREAM_TYPES, sampleRate, format, channelCount, frameCount, NULL, 0),
+ : Track(thread, NULL, AUDIO_STREAM_CNT, sampleRate, format, channelMask, frameCount, NULL, 0),
mActive(false), mSourceThread(sourceThread)
{
@@ -3251,8 +3616,10 @@
mCblk->volume[0] = mCblk->volume[1] = 0x1000;
mOutBuffer.frameCount = 0;
playbackThread->mTracks.add(this);
- LOGV("OutputTrack constructor mCblk %p, mBuffer %p, mCblk->buffers %p, mCblk->frameCount %d, mCblk->sampleRate %d, mCblk->channelCount %d mBufferEnd %p",
- mCblk, mBuffer, mCblk->buffers, mCblk->frameCount, mCblk->sampleRate, mCblk->channelCount, mBufferEnd);
+ LOGV("OutputTrack constructor mCblk %p, mBuffer %p, mCblk->buffers %p, " \
+ "mCblk->frameCount %d, mCblk->sampleRate %d, mChannelMask 0x%08x mBufferEnd %p",
+ mCblk, mBuffer, mCblk->buffers,
+ mCblk->frameCount, mCblk->sampleRate, mChannelMask, mBufferEnd);
} else {
LOGW("Error creating output track on thread %p", playbackThread);
}
@@ -3287,7 +3654,7 @@
{
Buffer *pInBuffer;
Buffer inBuffer;
- uint32_t channelCount = mCblk->channelCount;
+ uint32_t channelCount = mChannelCount;
bool outputBufferFull = false;
inBuffer.frameCount = frames;
inBuffer.i16 = data;
@@ -3572,8 +3939,8 @@
pid_t pid,
int input,
uint32_t sampleRate,
- int format,
- int channelCount,
+ uint32_t format,
+ uint32_t channelMask,
int frameCount,
uint32_t flags,
int *sessionId,
@@ -3612,24 +3979,29 @@
}
// If no audio session id is provided, create one here
- if (sessionId != NULL && *sessionId != AudioSystem::SESSION_OUTPUT_MIX) {
+ if (sessionId != NULL && *sessionId != AUDIO_SESSION_OUTPUT_MIX) {
lSessionId = *sessionId;
} else {
- lSessionId = nextUniqueId_l();
+ lSessionId = nextUniqueId();
if (sessionId != NULL) {
*sessionId = lSessionId;
}
}
// create new record track. The record track uses one track in mHardwareMixerThread by convention.
- recordTrack = new RecordThread::RecordTrack(thread, client, sampleRate,
- format, channelCount, frameCount, flags, lSessionId);
+ recordTrack = thread->createRecordTrack_l(client,
+ sampleRate,
+ format,
+ channelMask,
+ frameCount,
+ flags,
+ lSessionId,
+ &lStatus);
}
- if (recordTrack->getCblk() == NULL) {
+ if (lStatus != NO_ERROR) {
// remove local strong reference to Client before deleting the RecordTrack so that the Client
// destructor is called by the TrackBase destructor with mLock held
client.clear();
recordTrack.clear();
- lStatus = NO_MEMORY;
goto Exit;
}
@@ -3678,11 +4050,20 @@
// ----------------------------------------------------------------------------
-AudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger, AudioStreamIn *input, uint32_t sampleRate, uint32_t channels, int id) :
- ThreadBase(audioFlinger, id),
- mInput(input), mResampler(0), mRsmpOutBuffer(0), mRsmpInBuffer(0)
+AudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger,
+ AudioStreamIn *input,
+ uint32_t sampleRate,
+ uint32_t channels,
+ int id,
+ uint32_t device) :
+ ThreadBase(audioFlinger, id, device),
+ mInput(input), mTrack(NULL), mResampler(0), mRsmpOutBuffer(0), mRsmpInBuffer(0)
{
- mReqChannelCount = AudioSystem::popCount(channels);
+ mType = ThreadBase::RECORD;
+
+ snprintf(mName, kNameLength, "AudioIn_%d", id);
+
+ mReqChannelCount = popcount(channels);
mReqSampleRate = sampleRate;
readInputParameters();
}
@@ -3699,21 +4080,19 @@
void AudioFlinger::RecordThread::onFirstRef()
{
- const size_t SIZE = 256;
- char buffer[SIZE];
-
- snprintf(buffer, SIZE, "Record Thread %p", this);
-
- run(buffer, PRIORITY_URGENT_AUDIO);
+ run(mName, PRIORITY_URGENT_AUDIO);
}
bool AudioFlinger::RecordThread::threadLoop()
{
AudioBufferProvider::Buffer buffer;
sp<RecordTrack> activeTrack;
+ Vector< sp<EffectChain> > effectChains;
nsecs_t lastWarning = 0;
+ acquireWakeLock();
+
// start recording
while (!exitPending()) {
@@ -3724,22 +4103,24 @@
checkForNewParameters_l();
if (mActiveTrack == 0 && mConfigEvents.isEmpty()) {
if (!mStandby) {
- mInput->standby();
+ mInput->stream->common.standby(&mInput->stream->common);
mStandby = true;
}
if (exitPending()) break;
+ releaseWakeLock_l();
LOGV("RecordThread: loop stopping");
// go to sleep
mWaitWorkCV.wait(mLock);
LOGV("RecordThread: loop starting");
+ acquireWakeLock_l();
continue;
}
if (mActiveTrack != 0) {
if (mActiveTrack->mState == TrackBase::PAUSING) {
if (!mStandby) {
- mInput->standby();
+ mInput->stream->common.standby(&mInput->stream->common);
mStandby = true;
}
mActiveTrack.clear();
@@ -3761,14 +4142,20 @@
mStandby = false;
}
}
+ lockEffectChains_l(effectChains);
}
if (mActiveTrack != 0) {
if (mActiveTrack->mState != TrackBase::ACTIVE &&
mActiveTrack->mState != TrackBase::RESUMING) {
- usleep(5000);
+ unlockEffectChains(effectChains);
+ usleep(kRecordThreadSleepUs);
continue;
}
+ for (size_t i = 0; i < effectChains.size(); i ++) {
+ effectChains[i]->process_l();
+ }
+
buffer.frameCount = mFrameCount;
if (LIKELY(mActiveTrack->getNextBuffer(&buffer) == NO_ERROR)) {
size_t framesOut = buffer.frameCount;
@@ -3784,7 +4171,7 @@
mRsmpInIndex += framesIn;
framesOut -= framesIn;
if ((int)mChannelCount == mReqChannelCount ||
- mFormat != AudioSystem::PCM_16_BIT) {
+ mFormat != AUDIO_FORMAT_PCM_16_BIT) {
memcpy(dst, src, framesIn * mFrameSize);
} else {
int16_t *src16 = (int16_t *)src;
@@ -3804,11 +4191,11 @@
}
if (framesOut && mFrameCount == mRsmpInIndex) {
if (framesOut == mFrameCount &&
- ((int)mChannelCount == mReqChannelCount || mFormat != AudioSystem::PCM_16_BIT)) {
- mBytesRead = mInput->read(buffer.raw, mInputBytes);
+ ((int)mChannelCount == mReqChannelCount || mFormat != AUDIO_FORMAT_PCM_16_BIT)) {
+ mBytesRead = mInput->stream->read(mInput->stream, buffer.raw, mInputBytes);
framesOut = 0;
} else {
- mBytesRead = mInput->read(mRsmpInBuffer, mInputBytes);
+ mBytesRead = mInput->stream->read(mInput->stream, mRsmpInBuffer, mInputBytes);
mRsmpInIndex = 0;
}
if (mBytesRead < 0) {
@@ -3816,8 +4203,8 @@
if (mActiveTrack->mState == TrackBase::ACTIVE) {
// Force input into standby so that it tries to
// recover at next read attempt
- mInput->standby();
- usleep(5000);
+ mInput->stream->common.standby(&mInput->stream->common);
+ usleep(kRecordThreadSleepUs);
}
mRsmpInIndex = mFrameCount;
framesOut = 0;
@@ -3865,22 +4252,74 @@
// Release the processor for a while before asking for a new buffer.
// This will give the application more chance to read from the buffer and
// clear the overflow.
- usleep(5000);
+ usleep(kRecordThreadSleepUs);
}
}
+ // enable changes in effect chain
+ unlockEffectChains(effectChains);
+ effectChains.clear();
}
if (!mStandby) {
- mInput->standby();
+ mInput->stream->common.standby(&mInput->stream->common);
}
mActiveTrack.clear();
mStartStopCond.broadcast();
+ releaseWakeLock();
+
LOGV("RecordThread %p exiting", this);
return false;
}
+
+sp<AudioFlinger::RecordThread::RecordTrack> AudioFlinger::RecordThread::createRecordTrack_l(
+ const sp<AudioFlinger::Client>& client,
+ uint32_t sampleRate,
+ int format,
+ int channelMask,
+ int frameCount,
+ uint32_t flags,
+ int sessionId,
+ status_t *status)
+{
+ sp<RecordTrack> track;
+ status_t lStatus;
+
+ lStatus = initCheck();
+ if (lStatus != NO_ERROR) {
+ LOGE("Audio driver not initialized.");
+ goto Exit;
+ }
+
+ { // scope for mLock
+ Mutex::Autolock _l(mLock);
+
+ track = new RecordTrack(this, client, sampleRate,
+ format, channelMask, frameCount, flags, sessionId);
+
+ if (track->getCblk() == NULL) {
+ lStatus = NO_MEMORY;
+ goto Exit;
+ }
+
+ mTrack = track.get();
+ // disable AEC and NS if the device is a BT SCO headset supporting those pre processings
+ bool suspend = audio_is_bluetooth_sco_device(
+ (audio_devices_t)(mDevice & AUDIO_DEVICE_IN_ALL)) && mAudioFlinger->btNrec();
+ setEffectSuspended_l(FX_IID_AEC, suspend, sessionId);
+ setEffectSuspended_l(FX_IID_NS, suspend, sessionId);
+ }
+ lStatus = NO_ERROR;
+
+Exit:
+ if (status) {
+ *status = lStatus;
+ }
+ return track;
+}
+
status_t AudioFlinger::RecordThread::start(RecordThread::RecordTrack* recordTrack)
{
LOGV("RecordThread::start");
@@ -3970,7 +4409,7 @@
if (mActiveTrack != 0) {
result.append("Active Track:\n");
- result.append(" Clien Fmt Chn Session Buf S SRate Serv User\n");
+ result.append(" Clien Fmt Chn mask Session Buf S SRate Serv User\n");
mActiveTrack->dump(buffer, SIZE);
result.append(buffer);
@@ -3992,6 +4431,7 @@
write(fd, result.string(), result.size());
dumpBase(fd, args);
+ dumpEffectChains(fd, args);
return NO_ERROR;
}
@@ -4003,14 +4443,14 @@
int channelCount;
if (framesReady == 0) {
- mBytesRead = mInput->read(mRsmpInBuffer, mInputBytes);
+ mBytesRead = mInput->stream->read(mInput->stream, mRsmpInBuffer, mInputBytes);
if (mBytesRead < 0) {
LOGE("RecordThread::getNextBuffer() Error reading audio input");
if (mActiveTrack->mState == TrackBase::ACTIVE) {
// Force input into standby so that it tries to
// recover at next read attempt
- mInput->standby();
- usleep(5000);
+ mInput->stream->common.standby(&mInput->stream->common);
+ usleep(kRecordThreadSleepUs);
}
buffer->raw = 0;
buffer->frameCount = 0;
@@ -4062,7 +4502,7 @@
reconfig = true;
}
if (param.getInt(String8(AudioParameter::keyChannels), value) == NO_ERROR) {
- reqChannelCount = AudioSystem::popCount(value);
+ reqChannelCount = popcount(value);
reconfig = true;
}
if (param.getInt(String8(AudioParameter::keyFrameCount), value) == NO_ERROR) {
@@ -4075,17 +4515,43 @@
reconfig = true;
}
}
+ if (param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR) {
+ // forward device change to effects that have requested to be
+ // aware of attached audio device.
+ for (size_t i = 0; i < mEffectChains.size(); i++) {
+ mEffectChains[i]->setDevice_l(value);
+ }
+ // store input device and output device but do not forward output device to audio HAL.
+ // Note that status is ignored by the caller for output device
+ // (see AudioFlinger::setParameters()
+ if (value & AUDIO_DEVICE_OUT_ALL) {
+ mDevice &= (uint32_t)~(value & AUDIO_DEVICE_OUT_ALL);
+ status = BAD_VALUE;
+ } else {
+ mDevice &= (uint32_t)~(value & AUDIO_DEVICE_IN_ALL);
+ // disable AEC and NS if the device is a BT SCO headset supporting those pre processings
+ if (mTrack != NULL) {
+ bool suspend = audio_is_bluetooth_sco_device(
+ (audio_devices_t)value) && mAudioFlinger->btNrec();
+ setEffectSuspended_l(FX_IID_AEC, suspend, mTrack->sessionId());
+ setEffectSuspended_l(FX_IID_NS, suspend, mTrack->sessionId());
+ }
+ }
+ mDevice |= (uint32_t)value;
+ }
if (status == NO_ERROR) {
- status = mInput->setParameters(keyValuePair);
+ status = mInput->stream->common.set_parameters(&mInput->stream->common, keyValuePair.string());
if (status == INVALID_OPERATION) {
- mInput->standby();
- status = mInput->setParameters(keyValuePair);
+ mInput->stream->common.standby(&mInput->stream->common);
+ status = mInput->stream->common.set_parameters(&mInput->stream->common, keyValuePair.string());
}
if (reconfig) {
if (status == BAD_VALUE &&
- reqFormat == mInput->format() && reqFormat == AudioSystem::PCM_16_BIT &&
- ((int)mInput->sampleRate() <= 2 * reqSamplingRate) &&
- (AudioSystem::popCount(mInput->channels()) < 3) && (reqChannelCount < 3)) {
+ reqFormat == mInput->stream->common.get_format(&mInput->stream->common) &&
+ reqFormat == AUDIO_FORMAT_PCM_16_BIT &&
+ ((int)mInput->stream->common.get_sample_rate(&mInput->stream->common) <= (2 * reqSamplingRate)) &&
+ (popcount(mInput->stream->common.get_channels(&mInput->stream->common)) < 3) &&
+ (reqChannelCount < 3)) {
status = NO_ERROR;
}
if (status == NO_ERROR) {
@@ -4106,7 +4572,13 @@
String8 AudioFlinger::RecordThread::getParameters(const String8& keys)
{
- return mInput->getParameters(keys);
+ char *s;
+ String8 out_s8;
+
+ s = mInput->stream->common.get_parameters(&mInput->stream->common, keys.string());
+ out_s8 = String8(s);
+ free(s);
+ return out_s8;
}
void AudioFlinger::RecordThread::audioConfigChanged_l(int event, int param) {
@@ -4116,7 +4588,7 @@
switch (event) {
case AudioSystem::INPUT_OPENED:
case AudioSystem::INPUT_CONFIG_CHANGED:
- desc.channels = mChannels;
+ desc.channels = mChannelMask;
desc.samplingRate = mSampleRate;
desc.format = mFormat;
desc.frameCount = mFrameCount;
@@ -4138,12 +4610,12 @@
if (mResampler) delete mResampler;
mResampler = 0;
- mSampleRate = mInput->sampleRate();
- mChannels = mInput->channels();
- mChannelCount = (uint16_t)AudioSystem::popCount(mChannels);
- mFormat = mInput->format();
- mFrameSize = (uint16_t)mInput->frameSize();
- mInputBytes = mInput->bufferSize();
+ mSampleRate = mInput->stream->common.get_sample_rate(&mInput->stream->common);
+ mChannelMask = mInput->stream->common.get_channels(&mInput->stream->common);
+ mChannelCount = (uint16_t)popcount(mChannelMask);
+ mFormat = mInput->stream->common.get_format(&mInput->stream->common);
+ mFrameSize = (uint16_t)audio_stream_frame_size(&mInput->stream->common);
+ mInputBytes = mInput->stream->common.get_buffer_size(&mInput->stream->common);
mFrameCount = mInputBytes / mFrameSize;
mRsmpInBuffer = new int16_t[mFrameCount * mChannelCount];
@@ -4173,7 +4645,28 @@
unsigned int AudioFlinger::RecordThread::getInputFramesLost()
{
- return mInput->getInputFramesLost();
+ return mInput->stream->get_input_frames_lost(mInput->stream);
+}
+
+uint32_t AudioFlinger::RecordThread::hasAudioSession(int sessionId)
+{
+ Mutex::Autolock _l(mLock);
+ uint32_t result = 0;
+ if (getEffectChain_l(sessionId) != 0) {
+ result = EFFECT_SESSION;
+ }
+
+ if (mTrack != NULL && sessionId == mTrack->sessionId()) {
+ result |= TRACK_SESSION;
+ }
+
+ return result;
+}
+
+AudioFlinger::RecordThread::RecordTrack* AudioFlinger::RecordThread::track()
+{
+ Mutex::Autolock _l(mLock);
+ return mTrack;
}
// ----------------------------------------------------------------------------
@@ -4192,6 +4685,8 @@
uint32_t format = pFormat ? *pFormat : 0;
uint32_t channels = pChannels ? *pChannels : 0;
uint32_t latency = pLatencyMs ? *pLatencyMs : 0;
+ audio_stream_out_t *outStream;
+ audio_hw_device_t *outHwDev;
LOGV("openOutput(), Device %x, SamplingRate %d, Format %d, Channels %x, flags %x",
pDevices ? *pDevices : 0,
@@ -4203,26 +4698,30 @@
if (pDevices == NULL || *pDevices == 0) {
return 0;
}
+
Mutex::Autolock _l(mLock);
- AudioStreamOut *output = mAudioHardware->openOutputStream(*pDevices,
- (int *)&format,
- &channels,
- &samplingRate,
- &status);
+ outHwDev = findSuitableHwDev_l(*pDevices);
+ if (outHwDev == NULL)
+ return 0;
+
+ status = outHwDev->open_output_stream(outHwDev, *pDevices, (int *)&format,
+ &channels, &samplingRate, &outStream);
LOGV("openOutput() openOutputStream returned output %p, SamplingRate %d, Format %d, Channels %x, status %d",
- output,
+ outStream,
samplingRate,
format,
channels,
status);
mHardwareStatus = AUDIO_HW_IDLE;
- if (output != 0) {
- int id = nextUniqueId_l();
- if ((flags & AudioSystem::OUTPUT_FLAG_DIRECT) ||
- (format != AudioSystem::PCM_16_BIT) ||
- (channels != AudioSystem::CHANNEL_OUT_STEREO)) {
+ if (outStream != NULL) {
+ AudioStreamOut *output = new AudioStreamOut(outHwDev, outStream);
+ int id = nextUniqueId();
+
+ if ((flags & AUDIO_POLICY_OUTPUT_FLAG_DIRECT) ||
+ (format != AUDIO_FORMAT_PCM_16_BIT) ||
+ (channels != AUDIO_CHANNEL_OUT_STEREO)) {
thread = new DirectOutputThread(this, output, id, *pDevices);
LOGV("openOutput() created direct output: ID %d thread %p", id, thread);
} else {
@@ -4255,7 +4754,7 @@
return 0;
}
- int id = nextUniqueId_l();
+ int id = nextUniqueId();
DuplicatingThread *thread = new DuplicatingThread(this, thread1, id);
thread->addOutputTrack(thread2);
mPlaybackThreads.add(id, thread);
@@ -4278,9 +4777,9 @@
LOGV("closeOutput() %d", output);
- if (thread->type() == PlaybackThread::MIXER) {
+ if (thread->type() == ThreadBase::MIXER) {
for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
- if (mPlaybackThreads.valueAt(i)->type() == PlaybackThread::DUPLICATING) {
+ if (mPlaybackThreads.valueAt(i)->type() == ThreadBase::DUPLICATING) {
DuplicatingThread *dupThread = (DuplicatingThread *)mPlaybackThreads.valueAt(i).get();
dupThread->removeOutputTrack((MixerThread *)thread.get());
}
@@ -4292,8 +4791,10 @@
}
thread->exit();
- if (thread->type() != PlaybackThread::DUPLICATING) {
- mAudioHardware->closeOutputStream(thread->getOutput());
+ if (thread->type() != ThreadBase::DUPLICATING) {
+ AudioStreamOut *out = thread->getOutput();
+ out->hwDev->close_output_stream(out->hwDev, out->stream);
+ delete out;
}
return NO_ERROR;
}
@@ -4343,20 +4844,25 @@
uint32_t reqSamplingRate = samplingRate;
uint32_t reqFormat = format;
uint32_t reqChannels = channels;
+ audio_stream_in_t *inStream;
+ audio_hw_device_t *inHwDev;
if (pDevices == NULL || *pDevices == 0) {
return 0;
}
+
Mutex::Autolock _l(mLock);
- AudioStreamIn *input = mAudioHardware->openInputStream(*pDevices,
- (int *)&format,
- &channels,
- &samplingRate,
- &status,
- (AudioSystem::audio_in_acoustics)acoustics);
+ inHwDev = findSuitableHwDev_l(*pDevices);
+ if (inHwDev == NULL)
+ return 0;
+
+ status = inHwDev->open_input_stream(inHwDev, *pDevices, (int *)&format,
+ &channels, &samplingRate,
+ (audio_in_acoustics_t)acoustics,
+ &inStream);
LOGV("openInput() openInputStream returned input %p, SamplingRate %d, Format %d, Channels %x, acoustics %x, status %d",
- input,
+ inStream,
samplingRate,
format,
channels,
@@ -4366,30 +4872,38 @@
// If the input could not be opened with the requested parameters and we can handle the conversion internally,
// try to open again with the proposed parameters. The AudioFlinger can resample the input and do mono to stereo
// or stereo to mono conversions on 16 bit PCM inputs.
- if (input == 0 && status == BAD_VALUE &&
- reqFormat == format && format == AudioSystem::PCM_16_BIT &&
+ if (inStream == NULL && status == BAD_VALUE &&
+ reqFormat == format && format == AUDIO_FORMAT_PCM_16_BIT &&
(samplingRate <= 2 * reqSamplingRate) &&
- (AudioSystem::popCount(channels) < 3) && (AudioSystem::popCount(reqChannels) < 3)) {
+ (popcount(channels) < 3) && (popcount(reqChannels) < 3)) {
LOGV("openInput() reopening with proposed sampling rate and channels");
- input = mAudioHardware->openInputStream(*pDevices,
- (int *)&format,
- &channels,
- &samplingRate,
- &status,
- (AudioSystem::audio_in_acoustics)acoustics);
+ status = inHwDev->open_input_stream(inHwDev, *pDevices, (int *)&format,
+ &channels, &samplingRate,
+ (audio_in_acoustics_t)acoustics,
+ &inStream);
}
- if (input != 0) {
- int id = nextUniqueId_l();
- // Start record thread
- thread = new RecordThread(this, input, reqSamplingRate, reqChannels, id);
+ if (inStream != NULL) {
+ AudioStreamIn *input = new AudioStreamIn(inHwDev, inStream);
+
+ int id = nextUniqueId();
+ // Start record thread
+ // RecorThread require both input and output device indication to forward to audio
+ // pre processing modules
+ uint32_t device = (*pDevices) | primaryOutputDevice_l();
+ thread = new RecordThread(this,
+ input,
+ reqSamplingRate,
+ reqChannels,
+ id,
+ device);
mRecordThreads.add(id, thread);
LOGV("openInput() created record thread: ID %d thread %p", id, thread);
if (pSamplingRate) *pSamplingRate = reqSamplingRate;
if (pFormat) *pFormat = format;
if (pChannels) *pChannels = reqChannels;
- input->standby();
+ input->stream->common.standby(&input->stream->common);
// notify client processes of the new input creation
thread->audioConfigChanged_l(AudioSystem::INPUT_OPENED);
@@ -4418,7 +4932,9 @@
}
thread->exit();
- mAudioHardware->closeInputStream(thread->getInput());
+ AudioStreamIn *in = thread->getInput();
+ in->hwDev->close_input_stream(in->hwDev, in->stream);
+ delete in;
return NO_ERROR;
}
@@ -4438,7 +4954,7 @@
for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
PlaybackThread *thread = mPlaybackThreads.valueAt(i).get();
if (thread != dstThread &&
- thread->type() != PlaybackThread::DIRECT) {
+ thread->type() != ThreadBase::DIRECT) {
MixerThread *srcThread = (MixerThread *)thread;
srcThread->invalidateTracks(stream);
}
@@ -4450,8 +4966,7 @@
int AudioFlinger::newAudioSessionId()
{
- AutoMutex _l(mLock);
- return nextUniqueId_l();
+ return nextUniqueId();
}
// checkPlaybackThread_l() must be called with AudioFlinger::mLock held
@@ -4469,7 +4984,7 @@
{
PlaybackThread *thread = checkPlaybackThread_l(output);
if (thread != NULL) {
- if (thread->type() == PlaybackThread::DIRECT) {
+ if (thread->type() == ThreadBase::DIRECT) {
thread = NULL;
}
}
@@ -4486,43 +5001,39 @@
return thread;
}
-// nextUniqueId_l() must be called with AudioFlinger::mLock held
-int AudioFlinger::nextUniqueId_l()
+uint32_t AudioFlinger::nextUniqueId()
{
- return mNextUniqueId++;
+ return android_atomic_inc(&mNextUniqueId);
}
+AudioFlinger::PlaybackThread *AudioFlinger::primaryPlaybackThread_l()
+{
+ for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
+ PlaybackThread *thread = mPlaybackThreads.valueAt(i).get();
+ if (thread->getOutput()->hwDev == mPrimaryHardwareDev) {
+ return thread;
+ }
+ }
+ return NULL;
+}
+
+uint32_t AudioFlinger::primaryOutputDevice_l()
+{
+ PlaybackThread *thread = primaryPlaybackThread_l();
+
+ if (thread == NULL) {
+ return 0;
+ }
+
+ return thread->device();
+}
+
+
// ----------------------------------------------------------------------------
// Effect management
// ----------------------------------------------------------------------------
-status_t AudioFlinger::loadEffectLibrary(const char *libPath, int *handle)
-{
- // check calling permissions
- if (!settingsAllowed()) {
- return PERMISSION_DENIED;
- }
- // only allow libraries loaded from /system/lib/soundfx for now
- if (strncmp(gEffectLibPath, libPath, strlen(gEffectLibPath)) != 0) {
- return PERMISSION_DENIED;
- }
-
- Mutex::Autolock _l(mLock);
- return EffectLoadLibrary(libPath, handle);
-}
-
-status_t AudioFlinger::unloadEffectLibrary(int handle)
-{
- // check calling permissions
- if (!settingsAllowed()) {
- return PERMISSION_DENIED;
- }
-
- Mutex::Autolock _l(mLock);
- return EffectUnloadLibrary(handle);
-}
-
status_t AudioFlinger::queryNumberEffects(uint32_t *numEffects)
{
Mutex::Autolock _l(mLock);
@@ -4542,15 +5053,11 @@
}
-// this UUID must match the one defined in media/libeffects/EffectVisualizer.cpp
-static const effect_uuid_t VISUALIZATION_UUID_ =
- {0xd069d9e0, 0x8329, 0x11df, 0x9168, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
-
sp<IEffect> AudioFlinger::createEffect(pid_t pid,
effect_descriptor_t *pDesc,
const sp<IEffectClient>& effectClient,
int32_t priority,
- int output,
+ int io,
int sessionId,
status_t *status,
int *id,
@@ -4558,13 +5065,12 @@
{
status_t lStatus = NO_ERROR;
sp<EffectHandle> handle;
- effect_interface_t itfe;
effect_descriptor_t desc;
sp<Client> client;
wp<Client> wclient;
- LOGV("createEffect pid %d, client %p, priority %d, sessionId %d, output %d",
- pid, effectClient.get(), priority, sessionId, output);
+ LOGV("createEffect pid %d, client %p, priority %d, sessionId %d, io %d",
+ pid, effectClient.get(), priority, sessionId, io);
if (pDesc == NULL) {
lStatus = BAD_VALUE;
@@ -4572,37 +5078,29 @@
}
// check audio settings permission for global effects
- if (sessionId == AudioSystem::SESSION_OUTPUT_MIX && !settingsAllowed()) {
+ if (sessionId == AUDIO_SESSION_OUTPUT_MIX && !settingsAllowed()) {
lStatus = PERMISSION_DENIED;
goto Exit;
}
- // Session AudioSystem::SESSION_OUTPUT_STAGE is reserved for output stage effects
+ // Session AUDIO_SESSION_OUTPUT_STAGE is reserved for output stage effects
// that can only be created by audio policy manager (running in same process)
- if (sessionId == AudioSystem::SESSION_OUTPUT_STAGE && getpid() != pid) {
+ if (sessionId == AUDIO_SESSION_OUTPUT_STAGE && getpid() != pid) {
lStatus = PERMISSION_DENIED;
goto Exit;
}
- // check recording permission for visualizer
- if ((memcmp(&pDesc->type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0 ||
- memcmp(&pDesc->uuid, &VISUALIZATION_UUID_, sizeof(effect_uuid_t)) == 0) &&
- !recordingAllowed()) {
- lStatus = PERMISSION_DENIED;
- goto Exit;
- }
-
- if (output == 0) {
- if (sessionId == AudioSystem::SESSION_OUTPUT_STAGE) {
+ if (io == 0) {
+ if (sessionId == AUDIO_SESSION_OUTPUT_STAGE) {
// output must be specified by AudioPolicyManager when using session
- // AudioSystem::SESSION_OUTPUT_STAGE
+ // AUDIO_SESSION_OUTPUT_STAGE
lStatus = BAD_VALUE;
goto Exit;
- } else if (sessionId == AudioSystem::SESSION_OUTPUT_MIX) {
+ } else if (sessionId == AUDIO_SESSION_OUTPUT_MIX) {
// if the output returned by getOutputForEffect() is removed before we lock the
- // mutex below, the call to checkPlaybackThread_l(output) below will detect it
+ // mutex below, the call to checkPlaybackThread_l(io) below will detect it
// and we will exit safely
- output = AudioSystem::getOutputForEffect(&desc);
+ io = AudioSystem::getOutputForEffect(&desc);
}
}
@@ -4646,7 +5144,7 @@
// an auxiliary version of this effect type is available
found = true;
memcpy(&d, &desc, sizeof(effect_descriptor_t));
- if (sessionId != AudioSystem::SESSION_OUTPUT_MIX ||
+ if (sessionId != AUDIO_SESSION_OUTPUT_MIX ||
(desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
break;
}
@@ -4659,19 +5157,26 @@
}
// For same effect type, chose auxiliary version over insert version if
// connect to output mix (Compliance to OpenSL ES)
- if (sessionId == AudioSystem::SESSION_OUTPUT_MIX &&
+ if (sessionId == AUDIO_SESSION_OUTPUT_MIX &&
(d.flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_AUXILIARY) {
memcpy(&desc, &d, sizeof(effect_descriptor_t));
}
}
// Do not allow auxiliary effects on a session different from 0 (output mix)
- if (sessionId != AudioSystem::SESSION_OUTPUT_MIX &&
+ if (sessionId != AUDIO_SESSION_OUTPUT_MIX &&
(desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
lStatus = INVALID_OPERATION;
goto Exit;
}
+ // check recording permission for visualizer
+ if ((memcmp(&desc.type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0) &&
+ !recordingAllowed()) {
+ lStatus = PERMISSION_DENIED;
+ goto Exit;
+ }
+
// return effect descriptor
memcpy(pDesc, &desc, sizeof(effect_descriptor_t));
@@ -4679,30 +5184,40 @@
// output threads.
// If output is 0 here, sessionId is neither SESSION_OUTPUT_STAGE nor SESSION_OUTPUT_MIX
// because of code checking output when entering the function.
- if (output == 0) {
+ // Note: io is never 0 when creating an effect on an input
+ if (io == 0) {
// look for the thread where the specified audio session is present
for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
if (mPlaybackThreads.valueAt(i)->hasAudioSession(sessionId) != 0) {
- output = mPlaybackThreads.keyAt(i);
+ io = mPlaybackThreads.keyAt(i);
break;
}
}
+ if (io == 0) {
+ for (size_t i = 0; i < mRecordThreads.size(); i++) {
+ if (mRecordThreads.valueAt(i)->hasAudioSession(sessionId) != 0) {
+ io = mRecordThreads.keyAt(i);
+ break;
+ }
+ }
+ }
// If no output thread contains the requested session ID, default to
// first output. The effect chain will be moved to the correct output
// thread when a track with the same session ID is created
- if (output == 0 && mPlaybackThreads.size()) {
- output = mPlaybackThreads.keyAt(0);
+ if (io == 0 && mPlaybackThreads.size()) {
+ io = mPlaybackThreads.keyAt(0);
+ }
+ LOGV("createEffect() got io %d for effect %s", io, desc.name);
+ }
+ ThreadBase *thread = checkRecordThread_l(io);
+ if (thread == NULL) {
+ thread = checkPlaybackThread_l(io);
+ if (thread == NULL) {
+ LOGE("createEffect() unknown output thread");
+ lStatus = BAD_VALUE;
+ goto Exit;
}
}
- LOGV("createEffect() got output %d for effect %s", output, desc.name);
- PlaybackThread *thread = checkPlaybackThread_l(output);
- if (thread == NULL) {
- LOGE("createEffect() unknown output thread");
- lStatus = BAD_VALUE;
- goto Exit;
- }
-
- // TODO: allow attachment of effect to inputs
wclient = mClients.valueFor(pid);
@@ -4728,10 +5243,10 @@
return handle;
}
-status_t AudioFlinger::moveEffects(int session, int srcOutput, int dstOutput)
+status_t AudioFlinger::moveEffects(int sessionId, int srcOutput, int dstOutput)
{
LOGV("moveEffects() session %d, srcOutput %d, dstOutput %d",
- session, srcOutput, dstOutput);
+ sessionId, srcOutput, dstOutput);
Mutex::Autolock _l(mLock);
if (srcOutput == dstOutput) {
LOGW("moveEffects() same dst and src outputs %d", dstOutput);
@@ -4750,24 +5265,24 @@
Mutex::Autolock _dl(dstThread->mLock);
Mutex::Autolock _sl(srcThread->mLock);
- moveEffectChain_l(session, srcThread, dstThread, false);
+ moveEffectChain_l(sessionId, srcThread, dstThread, false);
return NO_ERROR;
}
// moveEffectChain_l mustbe called with both srcThread and dstThread mLocks held
-status_t AudioFlinger::moveEffectChain_l(int session,
+status_t AudioFlinger::moveEffectChain_l(int sessionId,
AudioFlinger::PlaybackThread *srcThread,
AudioFlinger::PlaybackThread *dstThread,
bool reRegister)
{
LOGV("moveEffectChain_l() session %d from thread %p to thread %p",
- session, srcThread, dstThread);
+ sessionId, srcThread, dstThread);
- sp<EffectChain> chain = srcThread->getEffectChain_l(session);
+ sp<EffectChain> chain = srcThread->getEffectChain_l(sessionId);
if (chain == 0) {
LOGW("moveEffectChain_l() effect chain for session %d not on source thread %p",
- session, srcThread);
+ sessionId, srcThread);
return INVALID_OPERATION;
}
@@ -4802,7 +5317,7 @@
AudioSystem::registerEffect(&effect->desc(),
dstOutput,
strategy,
- session,
+ sessionId,
effect->id());
}
effect = chain->getEffectFromId_l(0);
@@ -4811,8 +5326,9 @@
return NO_ERROR;
}
+
// PlaybackThread::createEffect_l() must be called with AudioFlinger::mLock held
-sp<AudioFlinger::EffectHandle> AudioFlinger::PlaybackThread::createEffect_l(
+sp<AudioFlinger::EffectHandle> AudioFlinger::ThreadBase::createEffect_l(
const sp<AudioFlinger::Client>& client,
const sp<IEffectClient>& effectClient,
int32_t priority,
@@ -4825,35 +5341,35 @@
sp<EffectModule> effect;
sp<EffectHandle> handle;
status_t lStatus;
- sp<Track> track;
sp<EffectChain> chain;
bool chainCreated = false;
bool effectCreated = false;
bool effectRegistered = false;
- if (mOutput == 0) {
+ lStatus = initCheck();
+ if (lStatus != NO_ERROR) {
LOGW("createEffect_l() Audio driver not initialized.");
- lStatus = NO_INIT;
- goto Exit;
- }
-
- // Do not allow auxiliary effect on session other than 0
- if ((desc->flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY &&
- sessionId != AudioSystem::SESSION_OUTPUT_MIX) {
- LOGW("createEffect_l() Cannot add auxiliary effect %s to session %d",
- desc->name, sessionId);
- lStatus = BAD_VALUE;
goto Exit;
}
// Do not allow effects with session ID 0 on direct output or duplicating threads
// TODO: add rule for hw accelerated effects on direct outputs with non PCM format
- if (sessionId == AudioSystem::SESSION_OUTPUT_MIX && mType != MIXER) {
+ if (sessionId == AUDIO_SESSION_OUTPUT_MIX && mType != MIXER) {
LOGW("createEffect_l() Cannot add auxiliary effect %s to session %d",
desc->name, sessionId);
lStatus = BAD_VALUE;
goto Exit;
}
+ // Only Pre processor effects are allowed on input threads and only on input threads
+ if ((mType == RECORD &&
+ (desc->flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_PRE_PROC) ||
+ (mType != RECORD &&
+ (desc->flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC)) {
+ LOGW("createEffect_l() effect %s (flags %08x) created on wrong thread type %d",
+ desc->name, desc->flags, mType);
+ lStatus = BAD_VALUE;
+ goto Exit;
+ }
LOGV("createEffect_l() thread %p effect %s on session %d", this, desc->name, sessionId);
@@ -4876,7 +5392,7 @@
LOGV("createEffect_l() got effect %p on chain %p", effect == 0 ? 0 : effect.get(), chain.get());
if (effect == 0) {
- int id = mAudioFlinger->nextUniqueId_l();
+ int id = mAudioFlinger->nextUniqueId();
// Check CPU and memory usage
lStatus = AudioSystem::registerEffect(desc, mId, chain->strategy(), sessionId, id);
if (lStatus != NO_ERROR) {
@@ -4927,9 +5443,20 @@
return handle;
}
+sp<AudioFlinger::EffectModule> AudioFlinger::ThreadBase::getEffect_l(int sessionId, int effectId)
+{
+ sp<EffectModule> effect;
+
+ sp<EffectChain> chain = getEffectChain_l(sessionId);
+ if (chain != 0) {
+ effect = chain->getEffectFromId_l(effectId);
+ }
+ return effect;
+}
+
// PlaybackThread::addEffect_l() must be called with AudioFlinger::mLock and
// PlaybackThread::mLock held
-status_t AudioFlinger::PlaybackThread::addEffect_l(const sp<EffectModule>& effect)
+status_t AudioFlinger::ThreadBase::addEffect_l(const sp<EffectModule>& effect)
{
// check for existing effect chain with the requested audio session
int sessionId = effect->sessionId();
@@ -4965,7 +5492,7 @@
return NO_ERROR;
}
-void AudioFlinger::PlaybackThread::removeEffect_l(const sp<EffectModule>& effect) {
+void AudioFlinger::ThreadBase::removeEffect_l(const sp<EffectModule>& effect) {
LOGV("removeEffect_l() %p effect %p", this, effect.get());
effect_descriptor_t desc = effect->desc();
@@ -4984,8 +5511,55 @@
}
}
-void AudioFlinger::PlaybackThread::disconnectEffect(const sp<EffectModule>& effect,
+void AudioFlinger::ThreadBase::lockEffectChains_l(
+ Vector<sp <AudioFlinger::EffectChain> >& effectChains)
+{
+ effectChains = mEffectChains;
+ for (size_t i = 0; i < mEffectChains.size(); i++) {
+ mEffectChains[i]->lock();
+ }
+}
+
+void AudioFlinger::ThreadBase::unlockEffectChains(
+ Vector<sp <AudioFlinger::EffectChain> >& effectChains)
+{
+ for (size_t i = 0; i < effectChains.size(); i++) {
+ effectChains[i]->unlock();
+ }
+}
+
+sp<AudioFlinger::EffectChain> AudioFlinger::ThreadBase::getEffectChain(int sessionId)
+{
+ Mutex::Autolock _l(mLock);
+ return getEffectChain_l(sessionId);
+}
+
+sp<AudioFlinger::EffectChain> AudioFlinger::ThreadBase::getEffectChain_l(int sessionId)
+{
+ sp<EffectChain> chain;
+
+ size_t size = mEffectChains.size();
+ for (size_t i = 0; i < size; i++) {
+ if (mEffectChains[i]->sessionId() == sessionId) {
+ chain = mEffectChains[i];
+ break;
+ }
+ }
+ return chain;
+}
+
+void AudioFlinger::ThreadBase::setMode(uint32_t mode)
+{
+ Mutex::Autolock _l(mLock);
+ size_t size = mEffectChains.size();
+ for (size_t i = 0; i < size; i++) {
+ mEffectChains[i]->setMode_l(mode);
+ }
+}
+
+void AudioFlinger::ThreadBase::disconnectEffect(const sp<EffectModule>& effect,
const wp<EffectHandle>& handle) {
+
Mutex::Autolock _l(mLock);
LOGV("disconnectEffect() %p effect %p", this, effect.get());
// delete the effect module if removing last handle on it
@@ -5019,6 +5593,7 @@
if (session == track->sessionId()) {
LOGV("addEffectChain_l() track->setMainBuffer track %p buffer %p", track.get(), buffer);
track->setMainBuffer(buffer);
+ chain->incTrackCnt();
}
}
@@ -5028,20 +5603,20 @@
if (track == 0) continue;
if (session == track->sessionId()) {
LOGV("addEffectChain_l() activating track %p on session %d", track.get(), session);
- chain->startTrack();
+ chain->incActiveTrackCnt();
}
}
}
chain->setInBuffer(buffer, ownsBuffer);
chain->setOutBuffer(mMixBuffer);
- // Effect chain for session AudioSystem::SESSION_OUTPUT_STAGE is inserted at end of effect
+ // Effect chain for session AUDIO_SESSION_OUTPUT_STAGE is inserted at end of effect
// chains list in order to be processed last as it contains output stage effects
- // Effect chain for session AudioSystem::SESSION_OUTPUT_MIX is inserted before
- // session AudioSystem::SESSION_OUTPUT_STAGE to be processed
+ // Effect chain for session AUDIO_SESSION_OUTPUT_MIX is inserted before
+ // session AUDIO_SESSION_OUTPUT_STAGE to be processed
// after track specific effects and before output stage
- // It is therefore mandatory that AudioSystem::SESSION_OUTPUT_MIX == 0 and
- // that AudioSystem::SESSION_OUTPUT_STAGE < AudioSystem::SESSION_OUTPUT_MIX
+ // It is therefore mandatory that AUDIO_SESSION_OUTPUT_MIX == 0 and
+ // that AUDIO_SESSION_OUTPUT_STAGE < AUDIO_SESSION_OUTPUT_MIX
// Effect chain for other sessions are inserted at beginning of effect
// chains list to be processed before output mix effects. Relative order between other
// sessions is not important
@@ -5051,6 +5626,7 @@
if (mEffectChains[i]->sessionId() < session) break;
}
mEffectChains.insertAt(chain, i);
+ checkSuspendOnAddEffectChain_l(chain);
return NO_ERROR;
}
@@ -5063,12 +5639,25 @@
for (size_t i = 0; i < mEffectChains.size(); i++) {
if (chain == mEffectChains[i]) {
+ updateSuspendedSessionsOnRemoveEffectChain_l(chain);
mEffectChains.removeAt(i);
+ // detach all active tracks from the chain
+ for (size_t i = 0 ; i < mActiveTracks.size() ; ++i) {
+ sp<Track> track = mActiveTracks[i].promote();
+ if (track == 0) continue;
+ if (session == track->sessionId()) {
+ LOGV("removeEffectChain_l(): stopping track on chain %p for session Id: %d",
+ chain.get(), session);
+ chain->decActiveTrackCnt();
+ }
+ }
+
// detach all tracks with same session ID from this chain
for (size_t i = 0; i < mTracks.size(); ++i) {
sp<Track> track = mTracks[i];
if (session == track->sessionId()) {
track->setMainBuffer(mMixBuffer);
+ chain->decTrackCnt();
}
}
break;
@@ -5077,35 +5666,6 @@
return mEffectChains.size();
}
-void AudioFlinger::PlaybackThread::lockEffectChains_l(
- Vector<sp <AudioFlinger::EffectChain> >& effectChains)
-{
- effectChains = mEffectChains;
- for (size_t i = 0; i < mEffectChains.size(); i++) {
- mEffectChains[i]->lock();
- }
-}
-
-void AudioFlinger::PlaybackThread::unlockEffectChains(
- Vector<sp <AudioFlinger::EffectChain> >& effectChains)
-{
- for (size_t i = 0; i < effectChains.size(); i++) {
- effectChains[i]->unlock();
- }
-}
-
-
-sp<AudioFlinger::EffectModule> AudioFlinger::PlaybackThread::getEffect_l(int sessionId, int effectId)
-{
- sp<EffectModule> effect;
-
- sp<EffectChain> chain = getEffectChain_l(sessionId);
- if (chain != 0) {
- effect = chain->getEffectFromId_l(effectId);
- }
- return effect;
-}
-
status_t AudioFlinger::PlaybackThread::attachAuxEffect(
const sp<AudioFlinger::PlaybackThread::Track> track, int EffectId)
{
@@ -5121,8 +5681,8 @@
if (EffectId == 0) {
track->setAuxBuffer(0, NULL);
} else {
- // Auxiliary effects are always in audio session AudioSystem::SESSION_OUTPUT_MIX
- sp<EffectModule> effect = getEffect_l(AudioSystem::SESSION_OUTPUT_MIX, EffectId);
+ // Auxiliary effects are always in audio session AUDIO_SESSION_OUTPUT_MIX
+ sp<EffectModule> effect = getEffect_l(AUDIO_SESSION_OUTPUT_MIX, EffectId);
if (effect != 0) {
if ((effect->desc().flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
track->setAuxBuffer(EffectId, (int32_t *)effect->inBuffer());
@@ -5146,6 +5706,37 @@
}
}
+status_t AudioFlinger::RecordThread::addEffectChain_l(const sp<EffectChain>& chain)
+{
+ // only one chain per input thread
+ if (mEffectChains.size() != 0) {
+ return INVALID_OPERATION;
+ }
+ LOGV("addEffectChain_l() %p on thread %p", chain.get(), this);
+
+ chain->setInBuffer(NULL);
+ chain->setOutBuffer(NULL);
+
+ checkSuspendOnAddEffectChain_l(chain);
+
+ mEffectChains.add(chain);
+
+ return NO_ERROR;
+}
+
+size_t AudioFlinger::RecordThread::removeEffectChain_l(const sp<EffectChain>& chain)
+{
+ LOGV("removeEffectChain_l() %p from thread %p", chain.get(), this);
+ LOGW_IF(mEffectChains.size() != 1,
+ "removeEffectChain_l() %p invalid chain size %d on thread %p",
+ chain.get(), mEffectChains.size(), this);
+ if (mEffectChains.size() == 1) {
+ updateSuspendedSessionsOnRemoveEffectChain_l(chain);
+ mEffectChains.removeAt(0);
+ }
+ return 0;
+}
+
// ----------------------------------------------------------------------------
// EffectModule implementation
// ----------------------------------------------------------------------------
@@ -5159,7 +5750,7 @@
int id,
int sessionId)
: mThread(wThread), mChain(chain), mId(id), mSessionId(sessionId), mEffectInterface(NULL),
- mStatus(NO_INIT), mState(IDLE)
+ mStatus(NO_INIT), mState(IDLE), mSuspended(false)
{
LOGV("Constructor %p", this);
int lStatus;
@@ -5167,12 +5758,11 @@
if (thread == 0) {
return;
}
- PlaybackThread *p = (PlaybackThread *)thread.get();
memcpy(&mDescriptor, desc, sizeof(effect_descriptor_t));
// create effect engine from effect factory
- mStatus = EffectCreate(&desc->uuid, sessionId, p->id(), &mEffectInterface);
+ mStatus = EffectCreate(&desc->uuid, sessionId, thread->id(), &mEffectInterface);
if (mStatus != NO_ERROR) {
return;
@@ -5195,6 +5785,13 @@
{
LOGV("Destructor %p", this);
if (mEffectInterface != NULL) {
+ if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC ||
+ (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC) {
+ sp<ThreadBase> thread = mThread.promote();
+ if (thread != 0) {
+ thread->stream()->remove_audio_effect(thread->stream(), mEffectInterface);
+ }
+ }
// release effect engine
EffectRelease(mEffectInterface);
}
@@ -5217,14 +5814,17 @@
}
// if inserted in first place, move effect control from previous owner to this handle
if (i == 0) {
+ bool enabled = false;
if (h != 0) {
- h->setControl(false, true);
+ enabled = h->enabled();
+ h->setControl(false/*hasControl*/, true /*signal*/, enabled /*enabled*/);
}
- handle->setControl(true, false);
+ handle->setControl(true /*hasControl*/, false /*signal*/, enabled /*enabled*/);
status = NO_ERROR;
} else {
status = ALREADY_EXISTS;
}
+ LOGV("addHandle() %p added handle %p in position %d", this, handle.get(), i);
mHandles.insertAt(handle, i);
return status;
}
@@ -5240,38 +5840,56 @@
if (i == size) {
return size;
}
+ LOGV("removeHandle() %p removed handle %p in position %d", this, handle.unsafe_get(), i);
+
+ bool enabled = false;
+ EffectHandle *hdl = handle.unsafe_get();
+ if (hdl) {
+ LOGV("removeHandle() unsafe_get OK");
+ enabled = hdl->enabled();
+ }
mHandles.removeAt(i);
size = mHandles.size();
// if removed from first place, move effect control from this handle to next in line
if (i == 0 && size != 0) {
sp<EffectHandle> h = mHandles[0].promote();
if (h != 0) {
- h->setControl(true, true);
+ h->setControl(true /*hasControl*/, true /*signal*/ , enabled /*enabled*/);
}
}
- // Release effect engine here so that it is done immediately. Otherwise it will be released
- // by the destructor when the last strong reference on the this object is released which can
- // happen after next process is called on this effect.
- if (size == 0 && mEffectInterface != NULL) {
- // release effect engine
- EffectRelease(mEffectInterface);
- mEffectInterface = NULL;
+ // Prevent calls to process() and other functions on effect interface from now on.
+ // The effect engine will be released by the destructor when the last strong reference on
+ // this object is released which can happen after next process is called.
+ if (size == 0) {
+ mState = DESTROYED;
}
return size;
}
+sp<AudioFlinger::EffectHandle> AudioFlinger::EffectModule::controlHandle()
+{
+ Mutex::Autolock _l(mLock);
+ sp<EffectHandle> handle;
+ if (mHandles.size() != 0) {
+ handle = mHandles[0].promote();
+ }
+ return handle;
+}
+
+
+
void AudioFlinger::EffectModule::disconnect(const wp<EffectHandle>& handle)
{
+ LOGV("disconnect() %p handle %p ", this, handle.unsafe_get());
// keep a strong reference on this EffectModule to avoid calling the
// destructor before we exit
sp<EffectModule> keep(this);
{
sp<ThreadBase> thread = mThread.promote();
if (thread != 0) {
- PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
- playbackThread->disconnectEffect(keep, handle);
+ thread->disconnectEffect(keep, handle);
}
}
}
@@ -5307,7 +5925,7 @@
mState = IDLE;
}
break;
- default: //IDLE , ACTIVE
+ default: //IDLE , ACTIVE, DESTROYED
break;
}
}
@@ -5316,7 +5934,7 @@
{
Mutex::Autolock _l(mLock);
- if (mEffectInterface == NULL ||
+ if (mState == DESTROYED || mEffectInterface == NULL ||
mConfig.inputCfg.buffer.raw == NULL ||
mConfig.outputCfg.buffer.raw == NULL) {
return;
@@ -5350,7 +5968,7 @@
// If an insert effect is idle and input buffer is different from output buffer,
// accumulate input onto output
sp<EffectChain> chain = mChain.promote();
- if (chain != 0 && chain->activeTracks() != 0) {
+ if (chain != 0 && chain->activeTrackCnt() != 0) {
size_t frameCnt = mConfig.inputCfg.buffer.frameCount * 2; //always stereo here
int16_t *in = mConfig.inputCfg.buffer.s16;
int16_t *out = mConfig.outputCfg.buffer.s16;
@@ -5383,19 +6001,19 @@
// TODO: handle configuration of effects replacing track process
if (thread->channelCount() == 1) {
- channels = CHANNEL_MONO;
+ channels = AUDIO_CHANNEL_OUT_MONO;
} else {
- channels = CHANNEL_STEREO;
+ channels = AUDIO_CHANNEL_OUT_STEREO;
}
if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
- mConfig.inputCfg.channels = CHANNEL_MONO;
+ mConfig.inputCfg.channels = AUDIO_CHANNEL_OUT_MONO;
} else {
mConfig.inputCfg.channels = channels;
}
mConfig.outputCfg.channels = channels;
- mConfig.inputCfg.format = SAMPLE_FORMAT_PCM_S15;
- mConfig.outputCfg.format = SAMPLE_FORMAT_PCM_S15;
+ mConfig.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
+ mConfig.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
mConfig.inputCfg.samplingRate = thread->sampleRate();
mConfig.outputCfg.samplingRate = mConfig.inputCfg.samplingRate;
mConfig.inputCfg.bufferProvider.cookie = NULL;
@@ -5406,7 +6024,7 @@
mConfig.outputCfg.bufferProvider.releaseBuffer = NULL;
mConfig.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
// Insert effect:
- // - in session AudioSystem::SESSION_OUTPUT_MIX or AudioSystem::SESSION_OUTPUT_STAGE,
+ // - in session AUDIO_SESSION_OUTPUT_MIX or AUDIO_SESSION_OUTPUT_STAGE,
// always overwrites output buffer: input buffer == output buffer
// - in other sessions:
// last effect in the chain accumulates in output buffer: input buffer != output buffer
@@ -5481,9 +6099,23 @@
if (status == 0) {
status = cmdStatus;
}
+ if (status == 0 &&
+ ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC ||
+ (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC)) {
+ sp<ThreadBase> thread = mThread.promote();
+ if (thread != 0) {
+ thread->stream()->add_audio_effect(thread->stream(), mEffectInterface);
+ }
+ }
return status;
}
+status_t AudioFlinger::EffectModule::stop()
+{
+ Mutex::Autolock _l(mLock);
+ return stop_l();
+}
+
status_t AudioFlinger::EffectModule::stop_l()
{
if (mEffectInterface == NULL) {
@@ -5500,6 +6132,14 @@
if (status == 0) {
status = cmdStatus;
}
+ if (status == 0 &&
+ ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC ||
+ (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC)) {
+ sp<ThreadBase> thread = mThread.promote();
+ if (thread != 0) {
+ thread->stream()->remove_audio_effect(thread->stream(), mEffectInterface);
+ }
+ }
return status;
}
@@ -5512,7 +6152,7 @@
Mutex::Autolock _l(mLock);
// LOGV("command(), cmdCode: %d, mEffectInterface: %p", cmdCode, mEffectInterface);
- if (mEffectInterface == NULL) {
+ if (mState == DESTROYED || mEffectInterface == NULL) {
return NO_INIT;
}
status_t status = (*mEffectInterface)->command(mEffectInterface,
@@ -5561,6 +6201,8 @@
case ACTIVE:
mState = STOPPING;
break;
+ case DESTROYED:
+ return NO_ERROR; // simply ignore as we are being destroyed
}
for (size_t i = 1; i < mHandles.size(); i++) {
sp<EffectHandle> h = mHandles[i].promote();
@@ -5582,6 +6224,7 @@
case IDLE:
case STOPPING:
case STOPPED:
+ case DESTROYED:
default:
return false;
}
@@ -5597,6 +6240,7 @@
return true;
case IDLE:
case STARTING:
+ case DESTROYED:
default:
return false;
}
@@ -5639,22 +6283,41 @@
{
Mutex::Autolock _l(mLock);
status_t status = NO_ERROR;
- if ((mDescriptor.flags & EFFECT_FLAG_DEVICE_MASK) == EFFECT_FLAG_DEVICE_IND) {
- // convert device bit field from AudioSystem to EffectApi format.
- device = deviceAudioSystemToEffectApi(device);
- if (device == 0) {
- return BAD_VALUE;
+ if (device && (mDescriptor.flags & EFFECT_FLAG_DEVICE_MASK) == EFFECT_FLAG_DEVICE_IND) {
+ // audio pre processing modules on RecordThread can receive both output and
+ // input device indication in the same call
+ uint32_t dev = device & AUDIO_DEVICE_OUT_ALL;
+ if (dev) {
+ status_t cmdStatus;
+ uint32_t size = sizeof(status_t);
+
+ status = (*mEffectInterface)->command(mEffectInterface,
+ EFFECT_CMD_SET_DEVICE,
+ sizeof(uint32_t),
+ &dev,
+ &size,
+ &cmdStatus);
+ if (status == NO_ERROR) {
+ status = cmdStatus;
+ }
}
- status_t cmdStatus;
- uint32_t size = sizeof(status_t);
- status = (*mEffectInterface)->command(mEffectInterface,
- EFFECT_CMD_SET_DEVICE,
- sizeof(uint32_t),
- &device,
- &size,
- &cmdStatus);
- if (status == NO_ERROR) {
- status = cmdStatus;
+ dev = device & AUDIO_DEVICE_IN_ALL;
+ if (dev) {
+ status_t cmdStatus;
+ uint32_t size = sizeof(status_t);
+
+ status_t status2 = (*mEffectInterface)->command(mEffectInterface,
+ EFFECT_CMD_SET_INPUT_DEVICE,
+ sizeof(uint32_t),
+ &dev,
+ &size,
+ &cmdStatus);
+ if (status2 == NO_ERROR) {
+ status2 = cmdStatus;
+ }
+ if (status == NO_ERROR) {
+ status = status2;
+ }
}
}
return status;
@@ -5665,17 +6328,12 @@
Mutex::Autolock _l(mLock);
status_t status = NO_ERROR;
if ((mDescriptor.flags & EFFECT_FLAG_AUDIO_MODE_MASK) == EFFECT_FLAG_AUDIO_MODE_IND) {
- // convert audio mode from AudioSystem to EffectApi format.
- int effectMode = modeAudioSystemToEffectApi(mode);
- if (effectMode < 0) {
- return BAD_VALUE;
- }
status_t cmdStatus;
uint32_t size = sizeof(status_t);
status = (*mEffectInterface)->command(mEffectInterface,
EFFECT_CMD_SET_AUDIO_MODE,
sizeof(int),
- &effectMode,
+ &mode,
&size,
&cmdStatus);
if (status == NO_ERROR) {
@@ -5685,51 +6343,15 @@
return status;
}
-// update this table when AudioSystem::audio_devices or audio_device_e (in EffectApi.h) are modified
-const uint32_t AudioFlinger::EffectModule::sDeviceConvTable[] = {
- DEVICE_EARPIECE, // AudioSystem::DEVICE_OUT_EARPIECE
- DEVICE_SPEAKER, // AudioSystem::DEVICE_OUT_SPEAKER
- DEVICE_WIRED_HEADSET, // case AudioSystem::DEVICE_OUT_WIRED_HEADSET
- DEVICE_WIRED_HEADPHONE, // AudioSystem::DEVICE_OUT_WIRED_HEADPHONE
- DEVICE_BLUETOOTH_SCO, // AudioSystem::DEVICE_OUT_BLUETOOTH_SCO
- DEVICE_BLUETOOTH_SCO_HEADSET, // AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET
- DEVICE_BLUETOOTH_SCO_CARKIT, // AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT
- DEVICE_BLUETOOTH_A2DP, // AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP
- DEVICE_BLUETOOTH_A2DP_HEADPHONES, // AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES
- DEVICE_BLUETOOTH_A2DP_SPEAKER, // AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER
- DEVICE_AUX_DIGITAL // AudioSystem::DEVICE_OUT_AUX_DIGITAL
-};
-
-uint32_t AudioFlinger::EffectModule::deviceAudioSystemToEffectApi(uint32_t device)
+void AudioFlinger::EffectModule::setSuspended(bool suspended)
{
- uint32_t deviceOut = 0;
- while (device) {
- const uint32_t i = 31 - __builtin_clz(device);
- device &= ~(1 << i);
- if (i >= sizeof(sDeviceConvTable)/sizeof(uint32_t)) {
- LOGE("device convertion error for AudioSystem device 0x%08x", device);
- return 0;
- }
- deviceOut |= (uint32_t)sDeviceConvTable[i];
- }
- return deviceOut;
+ Mutex::Autolock _l(mLock);
+ mSuspended = suspended;
}
-
-// update this table when AudioSystem::audio_mode or audio_mode_e (in EffectApi.h) are modified
-const uint32_t AudioFlinger::EffectModule::sModeConvTable[] = {
- AUDIO_EFFECT_MODE_NORMAL, // AudioSystem::MODE_NORMAL
- AUDIO_EFFECT_MODE_RINGTONE, // AudioSystem::MODE_RINGTONE
- AUDIO_EFFECT_MODE_IN_CALL, // AudioSystem::MODE_IN_CALL
- AUDIO_EFFECT_MODE_IN_CALL // AudioSystem::MODE_IN_COMMUNICATION, same conversion as for MODE_IN_CALL
-};
-
-int AudioFlinger::EffectModule::modeAudioSystemToEffectApi(uint32_t mode)
+bool AudioFlinger::EffectModule::suspended()
{
- int modeOut = -1;
- if (mode < sizeof(sModeConvTable) / sizeof(uint32_t)) {
- modeOut = (int)sModeConvTable[mode];
- }
- return modeOut;
+ Mutex::Autolock _l(mLock);
+ return mSuspended;
}
status_t AudioFlinger::EffectModule::dump(int fd, const Vector<String16>& args)
@@ -5763,7 +6385,7 @@
mDescriptor.type.clockSeq, mDescriptor.type.node[0], mDescriptor.type.node[1],mDescriptor.type.node[2],
mDescriptor.type.node[3],mDescriptor.type.node[4],mDescriptor.type.node[5]);
result.append(buffer);
- snprintf(buffer, SIZE, "\t\t- apiVersion: %04X\n\t\t- flags: %08X\n",
+ snprintf(buffer, SIZE, "\t\t- apiVersion: %08X\n\t\t- flags: %08X\n",
mDescriptor.apiVersion,
mDescriptor.flags);
result.append(buffer);
@@ -5828,7 +6450,8 @@
const sp<IEffectClient>& effectClient,
int32_t priority)
: BnEffect(),
- mEffect(effect), mEffectClient(effectClient), mClient(client), mPriority(priority), mHasControl(false)
+ mEffect(effect), mEffectClient(effectClient), mClient(client),
+ mPriority(priority), mHasControl(false), mEnabled(false)
{
LOGV("constructor %p", this);
@@ -5851,30 +6474,66 @@
{
LOGV("Destructor %p", this);
disconnect();
+ LOGV("Destructor DONE %p", this);
}
status_t AudioFlinger::EffectHandle::enable()
{
+ LOGV("enable %p", this);
if (!mHasControl) return INVALID_OPERATION;
if (mEffect == 0) return DEAD_OBJECT;
+ mEnabled = true;
+
+ sp<ThreadBase> thread = mEffect->thread().promote();
+ if (thread != 0) {
+ thread->checkSuspendOnEffectEnabled(mEffect, true, mEffect->sessionId());
+ }
+
+ // checkSuspendOnEffectEnabled() can suspend this same effect when enabled
+ if (mEffect->suspended()) {
+ return NO_ERROR;
+ }
+
return mEffect->setEnabled(true);
}
status_t AudioFlinger::EffectHandle::disable()
{
+ LOGV("disable %p", this);
if (!mHasControl) return INVALID_OPERATION;
- if (mEffect == NULL) return DEAD_OBJECT;
+ if (mEffect == 0) return DEAD_OBJECT;
- return mEffect->setEnabled(false);
+ mEnabled = false;
+
+ if (mEffect->suspended()) {
+ return NO_ERROR;
+ }
+
+ status_t status = mEffect->setEnabled(false);
+
+ sp<ThreadBase> thread = mEffect->thread().promote();
+ if (thread != 0) {
+ thread->checkSuspendOnEffectEnabled(mEffect, false, mEffect->sessionId());
+ }
+
+ return status;
}
void AudioFlinger::EffectHandle::disconnect()
{
+ LOGV("disconnect %p", this);
if (mEffect == 0) {
return;
}
+
mEffect->disconnect(this);
+
+ sp<ThreadBase> thread = mEffect->thread().promote();
+ if (thread != 0) {
+ thread->checkSuspendOnEffectEnabled(mEffect, false, mEffect->sessionId());
+ }
+
// release sp on module => module destructor can be called now
mEffect.clear();
if (mCblk) {
@@ -5966,11 +6625,13 @@
return mCblkMemory;
}
-void AudioFlinger::EffectHandle::setControl(bool hasControl, bool signal)
+void AudioFlinger::EffectHandle::setControl(bool hasControl, bool signal, bool enabled)
{
LOGV("setControl %p control %d", this, hasControl);
mHasControl = hasControl;
+ mEnabled = enabled;
+
if (signal && mEffectClient != 0) {
mEffectClient->controlStatusChanged(hasControl);
}
@@ -6026,11 +6687,11 @@
AudioFlinger::EffectChain::EffectChain(const wp<ThreadBase>& wThread,
int sessionId)
- : mThread(wThread), mSessionId(sessionId), mActiveTrackCnt(0), mOwnInBuffer(false),
- mVolumeCtrlIdx(-1), mLeftVolume(UINT_MAX), mRightVolume(UINT_MAX),
- mNewLeftVolume(UINT_MAX), mNewRightVolume(UINT_MAX)
+ : mThread(wThread), mSessionId(sessionId), mActiveTrackCnt(0), mTrackCnt(0),
+ mOwnInBuffer(false), mVolumeCtrlIdx(-1), mLeftVolume(UINT_MAX), mRightVolume(UINT_MAX),
+ mNewLeftVolume(UINT_MAX), mNewRightVolume(UINT_MAX)
{
- mStrategy = AudioSystem::getStrategyForStream(AudioSystem::MUSIC);
+ mStrategy = AudioSystem::getStrategyForStream(AUDIO_STREAM_MUSIC);
}
AudioFlinger::EffectChain::~EffectChain()
@@ -6041,7 +6702,7 @@
}
-// getEffectFromDesc_l() must be called with PlaybackThread::mLock held
+// getEffectFromDesc_l() must be called with ThreadBase::mLock held
sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromDesc_l(effect_descriptor_t *descriptor)
{
sp<EffectModule> effect;
@@ -6056,7 +6717,7 @@
return effect;
}
-// getEffectFromId_l() must be called with PlaybackThread::mLock held
+// getEffectFromId_l() must be called with ThreadBase::mLock held
sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromId_l(int id)
{
sp<EffectModule> effect;
@@ -6072,6 +6733,22 @@
return effect;
}
+// getEffectFromType_l() must be called with ThreadBase::mLock held
+sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromType_l(
+ const effect_uuid_t *type)
+{
+ sp<EffectModule> effect;
+ size_t size = mEffects.size();
+
+ for (size_t i = 0; i < size; i++) {
+ if (memcmp(&mEffects[i]->desc().type, type, sizeof(effect_uuid_t)) == 0) {
+ effect = mEffects[i];
+ break;
+ }
+ }
+ return effect;
+}
+
// Must be called with EffectChain::mLock locked
void AudioFlinger::EffectChain::process_l()
{
@@ -6080,13 +6757,19 @@
LOGW("process_l(): cannot promote mixer thread");
return;
}
- PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
- bool isGlobalSession = (mSessionId == AudioSystem::SESSION_OUTPUT_MIX) ||
- (mSessionId == AudioSystem::SESSION_OUTPUT_STAGE);
+ bool isGlobalSession = (mSessionId == AUDIO_SESSION_OUTPUT_MIX) ||
+ (mSessionId == AUDIO_SESSION_OUTPUT_STAGE);
bool tracksOnSession = false;
if (!isGlobalSession) {
- tracksOnSession =
- playbackThread->hasAudioSession(mSessionId) & PlaybackThread::TRACK_SESSION;
+ tracksOnSession = (trackCnt() != 0);
+ }
+
+ // if no track is active, input buffer must be cleared here as the mixer process
+ // will not do it
+ if (tracksOnSession &&
+ activeTrackCnt() == 0) {
+ size_t numSamples = thread->frameCount() * thread->channelCount();
+ memset(mInBuffer, 0, numSamples * sizeof(int16_t));
}
size_t size = mEffects.size();
@@ -6099,13 +6782,6 @@
for (size_t i = 0; i < size; i++) {
mEffects[i]->updateState();
}
- // if no track is active, input buffer must be cleared here as the mixer process
- // will not do it
- if (tracksOnSession &&
- activeTracks() == 0) {
- size_t numSamples = playbackThread->frameCount() * playbackThread->channelCount();
- memset(mInBuffer, 0, numSamples * sizeof(int16_t));
- }
}
// addEffect_l() must be called with PlaybackThread::mLock held
@@ -6232,6 +6908,10 @@
for (i = 0; i < size; i++) {
if (effect == mEffects[i]) {
+ // calling stop here will remove pre-processing effect from the audio HAL.
+ // This is safe as we hold the EffectChain mutex which guarantees that we are not in
+ // the middle of a read from audio HAL
+ mEffects[i]->stop();
if (type == EFFECT_FLAG_TYPE_AUXILIARY) {
delete[] effect->inBuffer();
} else {
@@ -6363,6 +7043,166 @@
return NO_ERROR;
}
+// must be called with ThreadBase::mLock held
+void AudioFlinger::EffectChain::setEffectSuspended_l(
+ const effect_uuid_t *type, bool suspend)
+{
+ sp<SuspendedEffectDesc> desc;
+ // use effect type UUID timelow as key as there is no real risk of identical
+ // timeLow fields among effect type UUIDs.
+ int index = mSuspendedEffects.indexOfKey(type->timeLow);
+ if (suspend) {
+ if (index >= 0) {
+ desc = mSuspendedEffects.valueAt(index);
+ } else {
+ desc = new SuspendedEffectDesc();
+ memcpy(&desc->mType, type, sizeof(effect_uuid_t));
+ mSuspendedEffects.add(type->timeLow, desc);
+ LOGV("setEffectSuspended_l() add entry for %08x", type->timeLow);
+ }
+ if (desc->mRefCount++ == 0) {
+ sp<EffectModule> effect = getEffectIfEnabled(type);
+ if (effect != 0) {
+ desc->mEffect = effect;
+ effect->setSuspended(true);
+ effect->setEnabled(false);
+ }
+ }
+ } else {
+ if (index < 0) {
+ return;
+ }
+ desc = mSuspendedEffects.valueAt(index);
+ if (desc->mRefCount <= 0) {
+ LOGW("setEffectSuspended_l() restore refcount should not be 0 %d", desc->mRefCount);
+ desc->mRefCount = 1;
+ }
+ if (--desc->mRefCount == 0) {
+ LOGV("setEffectSuspended_l() remove entry for %08x", mSuspendedEffects.keyAt(index));
+ if (desc->mEffect != 0) {
+ sp<EffectModule> effect = desc->mEffect.promote();
+ if (effect != 0) {
+ effect->setSuspended(false);
+ sp<EffectHandle> handle = effect->controlHandle();
+ if (handle != 0) {
+ effect->setEnabled(handle->enabled());
+ }
+ }
+ desc->mEffect.clear();
+ }
+ mSuspendedEffects.removeItemsAt(index);
+ }
+ }
+}
+
+// must be called with ThreadBase::mLock held
+void AudioFlinger::EffectChain::setEffectSuspendedAll_l(bool suspend)
+{
+ sp<SuspendedEffectDesc> desc;
+
+ int index = mSuspendedEffects.indexOfKey((int)kKeyForSuspendAll);
+ if (suspend) {
+ if (index >= 0) {
+ desc = mSuspendedEffects.valueAt(index);
+ } else {
+ desc = new SuspendedEffectDesc();
+ mSuspendedEffects.add((int)kKeyForSuspendAll, desc);
+ LOGV("setEffectSuspendedAll_l() add entry for 0");
+ }
+ if (desc->mRefCount++ == 0) {
+ Vector< sp<EffectModule> > effects = getSuspendEligibleEffects();
+ for (size_t i = 0; i < effects.size(); i++) {
+ setEffectSuspended_l(&effects[i]->desc().type, true);
+ }
+ }
+ } else {
+ if (index < 0) {
+ return;
+ }
+ desc = mSuspendedEffects.valueAt(index);
+ if (desc->mRefCount <= 0) {
+ LOGW("setEffectSuspendedAll_l() restore refcount should not be 0 %d", desc->mRefCount);
+ desc->mRefCount = 1;
+ }
+ if (--desc->mRefCount == 0) {
+ Vector<const effect_uuid_t *> types;
+ for (size_t i = 0; i < mSuspendedEffects.size(); i++) {
+ if (mSuspendedEffects.keyAt(i) == (int)kKeyForSuspendAll) {
+ continue;
+ }
+ types.add(&mSuspendedEffects.valueAt(i)->mType);
+ }
+ for (size_t i = 0; i < types.size(); i++) {
+ setEffectSuspended_l(types[i], false);
+ }
+ LOGV("setEffectSuspendedAll_l() remove entry for %08x", mSuspendedEffects.keyAt(index));
+ mSuspendedEffects.removeItem((int)kKeyForSuspendAll);
+ }
+ }
+}
+
+Vector< sp<AudioFlinger::EffectModule> > AudioFlinger::EffectChain::getSuspendEligibleEffects()
+{
+ Vector< sp<EffectModule> > effects;
+ for (size_t i = 0; i < mEffects.size(); i++) {
+ effect_descriptor_t desc = mEffects[i]->desc();
+ // auxiliary effects and vizualizer are never suspended on output mix
+ if ((mSessionId == AUDIO_SESSION_OUTPUT_MIX) && (
+ ((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) ||
+ (memcmp(&desc.type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0))) {
+ continue;
+ }
+ effects.add(mEffects[i]);
+ }
+ return effects;
+}
+
+sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectIfEnabled(
+ const effect_uuid_t *type)
+{
+ sp<EffectModule> effect;
+ effect = getEffectFromType_l(type);
+ if (effect != 0 && !effect->isEnabled()) {
+ effect.clear();
+ }
+ return effect;
+}
+
+void AudioFlinger::EffectChain::checkSuspendOnEffectEnabled(const sp<EffectModule>& effect,
+ bool enabled)
+{
+ int index = mSuspendedEffects.indexOfKey(effect->desc().type.timeLow);
+ if (enabled) {
+ if (index < 0) {
+ // if the effect is not suspend check if all effects are suspended
+ index = mSuspendedEffects.indexOfKey((int)kKeyForSuspendAll);
+ if (index < 0) {
+ return;
+ }
+ setEffectSuspended_l(&effect->desc().type, enabled);
+ index = mSuspendedEffects.indexOfKey(effect->desc().type.timeLow);
+ }
+ LOGV("checkSuspendOnEffectEnabled() enable suspending fx %08x",
+ effect->desc().type.timeLow);
+ sp<SuspendedEffectDesc> desc = mSuspendedEffects.valueAt(index);
+ // if effect is requested to suspended but was not yet enabled, supend it now.
+ if (desc->mEffect == 0) {
+ desc->mEffect = effect;
+ effect->setEnabled(false);
+ effect->setSuspended(true);
+ }
+ } else {
+ if (index < 0) {
+ return;
+ }
+ LOGV("checkSuspendOnEffectEnabled() disable restoring fx %08x",
+ effect->desc().type.timeLow);
+ sp<SuspendedEffectDesc> desc = mSuspendedEffects.valueAt(index);
+ desc->mEffect.clear();
+ effect->setSuspended(false);
+ }
+}
+
#undef LOG_TAG
#define LOG_TAG "AudioFlinger"
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index ec3d202..791341a 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -32,15 +32,19 @@
#include <utils/Errors.h>
#include <utils/threads.h>
#include <utils/SortedVector.h>
+#include <utils/TypeHelpers.h>
#include <utils/Vector.h>
#include <binder/BinderService.h>
#include <binder/MemoryDealer.h>
-#include <hardware_legacy/AudioHardwareInterface.h>
+#include <system/audio.h>
+#include <hardware/audio.h>
#include "AudioBufferProvider.h"
+#include <powermanager/IPowerManager.h>
+
namespace android {
class audio_track_cblk_t;
@@ -49,7 +53,6 @@
class AudioBuffer;
class AudioResampler;
-
// ----------------------------------------------------------------------------
#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
@@ -75,8 +78,8 @@
pid_t pid,
int streamType,
uint32_t sampleRate,
- int format,
- int channelCount,
+ uint32_t format,
+ uint32_t channelMask,
int frameCount,
uint32_t flags,
const sp<IMemory>& sharedBuffer,
@@ -86,7 +89,7 @@
virtual uint32_t sampleRate(int output) const;
virtual int channelCount(int output) const;
- virtual int format(int output) const;
+ virtual uint32_t format(int output) const;
virtual size_t frameCount(int output) const;
virtual uint32_t latency(int output) const;
@@ -146,10 +149,6 @@
virtual int newAudioSessionId();
- virtual status_t loadEffectLibrary(const char *libPath, int *handle);
-
- virtual status_t unloadEffectLibrary(int handle);
-
virtual status_t queryNumberEffects(uint32_t *numEffects);
virtual status_t queryEffect(uint32_t index, effect_descriptor_t *descriptor);
@@ -160,13 +159,13 @@
effect_descriptor_t *pDesc,
const sp<IEffectClient>& effectClient,
int32_t priority,
- int output,
+ int io,
int sessionId,
status_t *status,
int *id,
int *enabled);
- virtual status_t moveEffects(int session, int srcOutput, int dstOutput);
+ virtual status_t moveEffects(int sessionId, int srcOutput, int dstOutput);
enum hardware_call_state {
AUDIO_HW_IDLE = 0,
@@ -192,8 +191,8 @@
pid_t pid,
int input,
uint32_t sampleRate,
- int format,
- int channelCount,
+ uint32_t format,
+ uint32_t channelMask,
int frameCount,
uint32_t flags,
int *sessionId,
@@ -207,10 +206,15 @@
uint32_t getMode() { return mMode; }
+ bool btNrec() { return mBtNrec; }
+
private:
AudioFlinger();
virtual ~AudioFlinger();
+ status_t initCheck() const;
+ virtual void onFirstRef();
+ audio_hw_device_t* findSuitableHwDev_l(uint32_t devices);
// Internal dump utilites.
status_t dumpPermissionDenial(int fd, const Vector<String16>& args);
@@ -268,13 +272,26 @@
class EffectModule;
class EffectHandle;
class EffectChain;
+ struct AudioStreamOut;
+ struct AudioStreamIn;
class ThreadBase : public Thread {
public:
- ThreadBase (const sp<AudioFlinger>& audioFlinger, int id);
+ ThreadBase (const sp<AudioFlinger>& audioFlinger, int id, uint32_t device);
virtual ~ThreadBase();
+
+ enum type {
+ MIXER, // Thread class is MixerThread
+ DIRECT, // Thread class is DirectOutputThread
+ DUPLICATING, // Thread class is DuplicatingThread
+ RECORD // Thread class is RecordThread
+ };
+
status_t dumpBase(int fd, const Vector<String16>& args);
+ status_t dumpEffectChains(int fd, const Vector<String16>& args);
+
+ void clearPowerManager();
// base for record and playback
class TrackBase : public AudioBufferProvider, public RefBase {
@@ -299,8 +316,8 @@
TrackBase(const wp<ThreadBase>& thread,
const sp<Client>& client,
uint32_t sampleRate,
- int format,
- int channelCount,
+ uint32_t format,
+ uint32_t channelMask,
int frameCount,
uint32_t flags,
const sp<IMemory>& sharedBuffer,
@@ -327,12 +344,14 @@
virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) = 0;
virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);
- int format() const {
+ uint32_t format() const {
return mFormat;
}
int channelCount() const ;
+ uint32_t channelMask() const;
+
int sampleRate() const;
void* getBuffer(uint32_t offset, uint32_t frames) const;
@@ -358,9 +377,11 @@
// we don't really need a lock for these
int mState;
int mClientTid;
- uint8_t mFormat;
+ uint32_t mFormat;
uint32_t mFlags;
int mSessionId;
+ uint8_t mChannelCount;
+ uint32_t mChannelMask;
};
class ConfigEvent {
@@ -371,9 +392,26 @@
int mParam;
};
+ class PMDeathRecipient : public IBinder::DeathRecipient {
+ public:
+ PMDeathRecipient(const wp<ThreadBase>& thread) : mThread(thread) {}
+ virtual ~PMDeathRecipient() {}
+
+ // IBinder::DeathRecipient
+ virtual void binderDied(const wp<IBinder>& who);
+
+ private:
+ PMDeathRecipient(const PMDeathRecipient&);
+ PMDeathRecipient& operator = (const PMDeathRecipient&);
+
+ wp<ThreadBase> mThread;
+ };
+
+ virtual status_t initCheck() const = 0;
+ int type() const { return mType; }
uint32_t sampleRate() const;
int channelCount() const;
- int format() const;
+ uint32_t format() const;
size_t frameCount() const;
void wakeUp() { mWaitWorkCV.broadcast(); }
void exit();
@@ -386,11 +424,101 @@
void processConfigEvents();
int id() const { return mId;}
bool standby() { return mStandby; }
+ uint32_t device() { return mDevice; }
+ virtual audio_stream_t* stream() = 0;
+
+ sp<EffectHandle> createEffect_l(
+ const sp<AudioFlinger::Client>& client,
+ const sp<IEffectClient>& effectClient,
+ int32_t priority,
+ int sessionId,
+ effect_descriptor_t *desc,
+ int *enabled,
+ status_t *status);
+ void disconnectEffect(const sp< EffectModule>& effect,
+ const wp<EffectHandle>& handle);
+
+ // return values for hasAudioSession (bit field)
+ enum effect_state {
+ EFFECT_SESSION = 0x1, // the audio session corresponds to at least one
+ // effect
+ TRACK_SESSION = 0x2 // the audio session corresponds to at least one
+ // track
+ };
+
+ // get effect chain corresponding to session Id.
+ sp<EffectChain> getEffectChain(int sessionId);
+ // same as getEffectChain() but must be called with ThreadBase mutex locked
+ sp<EffectChain> getEffectChain_l(int sessionId);
+ // add an effect chain to the chain list (mEffectChains)
+ virtual status_t addEffectChain_l(const sp<EffectChain>& chain) = 0;
+ // remove an effect chain from the chain list (mEffectChains)
+ virtual size_t removeEffectChain_l(const sp<EffectChain>& chain) = 0;
+ // lock mall effect chains Mutexes. Must be called before releasing the
+ // ThreadBase mutex before processing the mixer and effects. This guarantees the
+ // integrity of the chains during the process.
+ void lockEffectChains_l(Vector<sp <EffectChain> >& effectChains);
+ // unlock effect chains after process
+ void unlockEffectChains(Vector<sp <EffectChain> >& effectChains);
+ // set audio mode to all effect chains
+ void setMode(uint32_t mode);
+ // get effect module with corresponding ID on specified audio session
+ sp<AudioFlinger::EffectModule> getEffect_l(int sessionId, int effectId);
+ // add and effect module. Also creates the effect chain is none exists for
+ // the effects audio session
+ status_t addEffect_l(const sp< EffectModule>& effect);
+ // remove and effect module. Also removes the effect chain is this was the last
+ // effect
+ void removeEffect_l(const sp< EffectModule>& effect);
+ // detach all tracks connected to an auxiliary effect
+ virtual void detachAuxEffect_l(int effectId) {}
+ // returns either EFFECT_SESSION if effects on this audio session exist in one
+ // chain, or TRACK_SESSION if tracks on this audio session exist, or both
+ virtual uint32_t hasAudioSession(int sessionId) = 0;
+ // the value returned by default implementation is not important as the
+ // strategy is only meaningful for PlaybackThread which implements this method
+ virtual uint32_t getStrategyForSession_l(int sessionId) { return 0; }
+
+ // suspend or restore effect according to the type of effect passed. a NULL
+ // type pointer means suspend all effects in the session
+ void setEffectSuspended(const effect_uuid_t *type,
+ bool suspend,
+ int sessionId = AUDIO_SESSION_OUTPUT_MIX);
+ // check if some effects must be suspended/restored when an effect is enabled
+ // or disabled
+ virtual void checkSuspendOnEffectEnabled(const sp<EffectModule>& effect,
+ bool enabled,
+ int sessionId = AUDIO_SESSION_OUTPUT_MIX);
mutable Mutex mLock;
protected:
+ // entry describing an effect being suspended in mSuspendedSessions keyed vector
+ class SuspendedSessionDesc : public RefBase {
+ public:
+ SuspendedSessionDesc() : mRefCount(0) {}
+
+ int mRefCount; // number of active suspend requests
+ effect_uuid_t mType; // effect type UUID
+ };
+
+ void acquireWakeLock();
+ void acquireWakeLock_l();
+ void releaseWakeLock();
+ void releaseWakeLock_l();
+ void setEffectSuspended_l(const effect_uuid_t *type,
+ bool suspend,
+ int sessionId = AUDIO_SESSION_OUTPUT_MIX);
+ // updated mSuspendedSessions when an effect suspended or restored
+ void updateSuspendedSessions_l(const effect_uuid_t *type,
+ bool suspend,
+ int sessionId);
+ // check if some effects must be suspended when an effect chain is added
+ void checkSuspendOnAddEffectChain_l(const sp<EffectChain>& chain);
+ // updated mSuspendedSessions when an effect chain is removed
+ void updateSuspendedSessionsOnRemoveEffectChain_l(const sp<EffectChain>& chain);
+
friend class Track;
friend class TrackBase;
friend class PlaybackThread;
@@ -400,14 +528,15 @@
friend class RecordThread;
friend class RecordTrack;
+ int mType;
Condition mWaitWorkCV;
sp<AudioFlinger> mAudioFlinger;
uint32_t mSampleRate;
size_t mFrameCount;
- uint32_t mChannels;
+ uint32_t mChannelMask;
uint16_t mChannelCount;
uint16_t mFrameSize;
- int mFormat;
+ uint32_t mFormat;
Condition mParamCond;
Vector<String8> mNewParameters;
status_t mParamStatus;
@@ -415,18 +544,23 @@
bool mStandby;
int mId;
bool mExiting;
+ Vector< sp<EffectChain> > mEffectChains;
+ uint32_t mDevice; // output device for PlaybackThread
+ // input + output devices for RecordThread
+ static const int kNameLength = 32;
+ char mName[kNameLength];
+ sp<IPowerManager> mPowerManager;
+ sp<IBinder> mWakeLockToken;
+ sp<PMDeathRecipient> mDeathRecipient;
+ // list of suspended effects per session and per type. The first vector is
+ // keyed by session ID, the second by type UUID timeLow field
+ KeyedVector< int, KeyedVector< int, sp<SuspendedSessionDesc> > > mSuspendedSessions;
};
// --- PlaybackThread ---
class PlaybackThread : public ThreadBase {
public:
- enum type {
- MIXER,
- DIRECT,
- DUPLICATING
- };
-
enum mixer_state {
MIXER_IDLE,
MIXER_TRACKS_ENABLED,
@@ -440,8 +574,8 @@
const sp<Client>& client,
int streamType,
uint32_t sampleRate,
- int format,
- int channelCount,
+ uint32_t format,
+ uint32_t channelMask,
int frameCount,
const sp<IMemory>& sharedBuffer,
int sessionId);
@@ -495,7 +629,7 @@
void reset();
bool isOutputTrack() const {
- return (mStreamType == AudioSystem::NUM_STREAM_TYPES);
+ return (mStreamType == AUDIO_STREAM_CNT);
}
// we don't really need a lock for these
@@ -528,8 +662,8 @@
OutputTrack( const wp<ThreadBase>& thread,
DuplicatingThread *sourceThread,
uint32_t sampleRate,
- int format,
- int channelCount,
+ uint32_t format,
+ uint32_t channelMask,
int frameCount);
~OutputTrack();
@@ -563,6 +697,8 @@
virtual status_t readyToRun();
virtual void onFirstRef();
+ virtual status_t initCheck() const { return (mOutput == 0) ? NO_INIT : NO_ERROR; }
+
virtual uint32_t latency() const;
virtual status_t setMasterVolume(float value);
@@ -581,16 +717,16 @@
const sp<AudioFlinger::Client>& client,
int streamType,
uint32_t sampleRate,
- int format,
- int channelCount,
+ uint32_t format,
+ uint32_t channelMask,
int frameCount,
const sp<IMemory>& sharedBuffer,
int sessionId,
status_t *status);
AudioStreamOut* getOutput() { return mOutput; }
+ virtual audio_stream_t* stream() { return &mOutput->stream->common; }
- virtual int type() const { return mType; }
void suspend() { mSuspended++; }
void restore() { if (mSuspended) mSuspended--; }
bool isSuspended() { return (mSuspended != 0); }
@@ -599,45 +735,16 @@
virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames);
int16_t *mixBuffer() { return mMixBuffer; };
- sp<EffectHandle> createEffect_l(
- const sp<AudioFlinger::Client>& client,
- const sp<IEffectClient>& effectClient,
- int32_t priority,
- int sessionId,
- effect_descriptor_t *desc,
- int *enabled,
- status_t *status);
- void disconnectEffect(const sp< EffectModule>& effect,
- const wp<EffectHandle>& handle);
-
- // return values for hasAudioSession (bit field)
- enum effect_state {
- EFFECT_SESSION = 0x1, // the audio session corresponds to at least one
- // effect
- TRACK_SESSION = 0x2 // the audio session corresponds to at least one
- // track
- };
-
- uint32_t hasAudioSession(int sessionId);
- sp<EffectChain> getEffectChain(int sessionId);
- sp<EffectChain> getEffectChain_l(int sessionId);
- status_t addEffectChain_l(const sp<EffectChain>& chain);
- size_t removeEffectChain_l(const sp<EffectChain>& chain);
- void lockEffectChains_l(Vector<sp <EffectChain> >& effectChains);
- void unlockEffectChains(Vector<sp <EffectChain> >& effectChains);
-
- sp<AudioFlinger::EffectModule> getEffect_l(int sessionId, int effectId);
- void detachAuxEffect_l(int effectId);
+ virtual void detachAuxEffect_l(int effectId);
status_t attachAuxEffect(const sp<AudioFlinger::PlaybackThread::Track> track,
int EffectId);
status_t attachAuxEffect_l(const sp<AudioFlinger::PlaybackThread::Track> track,
int EffectId);
- void setMode(uint32_t mode);
- status_t addEffect_l(const sp< EffectModule>& effect);
- void removeEffect_l(const sp< EffectModule>& effect);
-
- uint32_t getStrategyForSession_l(int sessionId);
+ virtual status_t addEffectChain_l(const sp<EffectChain>& chain);
+ virtual size_t removeEffectChain_l(const sp<EffectChain>& chain);
+ virtual uint32_t hasAudioSession(int sessionId);
+ virtual uint32_t getStrategyForSession_l(int sessionId);
struct stream_type_t {
stream_type_t()
@@ -650,7 +757,6 @@
};
protected:
- int mType;
int16_t* mMixBuffer;
int mSuspended;
int mBytesWritten;
@@ -678,26 +784,22 @@
status_t addTrack_l(const sp<Track>& track);
void destroyTrack_l(const sp<Track>& track);
+ void removeTrack_l(const sp<Track>& track);
void readOutputParameters();
- uint32_t device() { return mDevice; }
-
virtual status_t dumpInternals(int fd, const Vector<String16>& args);
status_t dumpTracks(int fd, const Vector<String16>& args);
- status_t dumpEffectChains(int fd, const Vector<String16>& args);
SortedVector< sp<Track> > mTracks;
// mStreamTypes[] uses 1 additionnal stream type internally for the OutputTrack used by DuplicatingThread
- stream_type_t mStreamTypes[AudioSystem::NUM_STREAM_TYPES + 1];
+ stream_type_t mStreamTypes[AUDIO_STREAM_CNT + 1];
AudioStreamOut* mOutput;
float mMasterVolume;
nsecs_t mLastWriteTime;
int mNumWrites;
int mNumDelayedWrites;
bool mInWrite;
- Vector< sp<EffectChain> > mEffectChains;
- uint32_t mDevice;
};
class MixerThread : public PlaybackThread {
@@ -781,11 +883,13 @@
float streamVolumeInternal(int stream) const { return mStreamTypes[stream].volume; }
void audioConfigChanged_l(int event, int ioHandle, void *param2);
- int nextUniqueId_l();
- status_t moveEffectChain_l(int session,
+ uint32_t nextUniqueId();
+ status_t moveEffectChain_l(int sessionId,
AudioFlinger::PlaybackThread *srcThread,
AudioFlinger::PlaybackThread *dstThread,
bool reRegister);
+ PlaybackThread *primaryPlaybackThread_l();
+ uint32_t primaryOutputDevice_l();
friend class AudioBuffer;
@@ -826,8 +930,8 @@
RecordTrack(const wp<ThreadBase>& thread,
const sp<Client>& client,
uint32_t sampleRate,
- int format,
- int channelCount,
+ uint32_t format,
+ uint32_t channelMask,
int frameCount,
uint32_t flags,
int sessionId);
@@ -840,6 +944,7 @@
bool setOverflow() { bool tmp = mOverflow; mOverflow = true; return tmp; }
void dump(char* buffer, size_t size);
+
private:
friend class AudioFlinger;
friend class RecordThread;
@@ -857,17 +962,30 @@
AudioStreamIn *input,
uint32_t sampleRate,
uint32_t channels,
- int id);
+ int id,
+ uint32_t device);
~RecordThread();
virtual bool threadLoop();
virtual status_t readyToRun() { return NO_ERROR; }
virtual void onFirstRef();
+ virtual status_t initCheck() const { return (mInput == 0) ? NO_INIT : NO_ERROR; }
+ sp<AudioFlinger::RecordThread::RecordTrack> createRecordTrack_l(
+ const sp<AudioFlinger::Client>& client,
+ uint32_t sampleRate,
+ int format,
+ int channelMask,
+ int frameCount,
+ uint32_t flags,
+ int sessionId,
+ status_t *status);
+
status_t start(RecordTrack* recordTrack);
void stop(RecordTrack* recordTrack);
status_t dump(int fd, const Vector<String16>& args);
AudioStreamIn* getInput() { return mInput; }
+ virtual audio_stream_t* stream() { return &mInput->stream->common; }
virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer);
virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);
@@ -877,9 +995,15 @@
void readInputParameters();
virtual unsigned int getInputFramesLost();
+ virtual status_t addEffectChain_l(const sp<EffectChain>& chain);
+ virtual size_t removeEffectChain_l(const sp<EffectChain>& chain);
+ virtual uint32_t hasAudioSession(int sessionId);
+ RecordTrack* track();
+
private:
RecordThread();
AudioStreamIn *mInput;
+ RecordTrack* mTrack;
sp<RecordTrack> mActiveTrack;
Condition mStartStopCond;
AudioResampler *mResampler;
@@ -936,7 +1060,8 @@
STARTING,
ACTIVE,
STOPPING,
- STOPPED
+ STOPPED,
+ DESTROYED
};
int id() { return mId; }
@@ -970,6 +1095,7 @@
int16_t *outBuffer() { return mConfig.outputCfg.buffer.s16; }
void setChain(const wp<EffectChain>& chain) { mChain = chain; }
void setThread(const wp<ThreadBase>& thread) { mThread = thread; }
+ wp<ThreadBase>& thread() { return mThread; }
status_t addHandle(sp<EffectHandle>& handle);
void disconnect(const wp<EffectHandle>& handle);
@@ -981,6 +1107,11 @@
status_t setDevice(uint32_t device);
status_t setVolume(uint32_t *left, uint32_t *right, bool controller);
status_t setMode(uint32_t mode);
+ status_t stop();
+ void setSuspended(bool suspended);
+ bool suspended();
+
+ sp<EffectHandle> controlHandle();
status_t dump(int fd, const Vector<String16>& args);
@@ -995,14 +1126,6 @@
status_t start_l();
status_t stop_l();
- // update this table when AudioSystem::audio_devices or audio_device_e (in EffectApi.h) are modified
- static const uint32_t sDeviceConvTable[];
- static uint32_t deviceAudioSystemToEffectApi(uint32_t device);
-
- // update this table when AudioSystem::audio_mode or audio_mode_e (in EffectApi.h) are modified
- static const uint32_t sModeConvTable[];
- static int modeAudioSystemToEffectApi(uint32_t mode);
-
Mutex mLock; // mutex for process, commands and handles list protection
wp<ThreadBase> mThread; // parent thread
wp<EffectChain> mChain; // parent effect chain
@@ -1010,13 +1133,14 @@
int mSessionId; // audio session ID
effect_descriptor_t mDescriptor;// effect descriptor received from effect engine
effect_config_t mConfig; // input and output audio configuration
- effect_interface_t mEffectInterface; // Effect module C API
+ effect_handle_t mEffectInterface; // Effect module C API
status_t mStatus; // initialization status
uint32_t mState; // current activation state (effect_state)
Vector< wp<EffectHandle> > mHandles; // list of client handles
uint32_t mMaxDisableWaitCnt; // maximum grace period before forcing an effect off after
// sending disable command.
uint32_t mDisableWaitCnt; // current process() calls count during disable period.
+ bool mSuspended; // effect is suspended: temporarily disabled by framework
};
// The EffectHandle class implements the IEffect interface. It provides resources
@@ -1049,13 +1173,17 @@
// Give or take control of effect module
- void setControl(bool hasControl, bool signal);
+ // - hasControl: true if control is given, false if removed
+ // - signal: true client app should be signaled of change, false otherwise
+ // - enabled: state of the effect when control is passed
+ void setControl(bool hasControl, bool signal, bool enabled);
void commandExecuted(uint32_t cmdCode,
uint32_t cmdSize,
void *pCmdData,
uint32_t replySize,
void *pReplyData);
void setEnabled(bool enabled);
+ bool enabled() { return mEnabled; }
// Getters
int id() { return mEffect->id(); }
@@ -1078,6 +1206,8 @@
uint8_t* mBuffer; // pointer to parameter area in shared memory
int mPriority; // client application priority to control the effect
bool mHasControl; // true if this handle is controlling the effect
+ bool mEnabled; // cached enable state: needed when the effect is
+ // restored after being suspended
};
// the EffectChain class represents a group of effects associated to one audio session.
@@ -1092,6 +1222,10 @@
EffectChain(const wp<ThreadBase>& wThread, int sessionId);
~EffectChain();
+ // special key used for an entry in mSuspendedEffects keyed vector
+ // corresponding to a suspend all request.
+ static const int kKeyForSuspendAll = 0;
+
void process_l();
void lock() {
@@ -1104,12 +1238,12 @@
status_t addEffect_l(const sp<EffectModule>& handle);
size_t removeEffect_l(const sp<EffectModule>& handle);
- int sessionId() {
- return mSessionId;
- }
+ int sessionId() { return mSessionId; }
+ void setSessionId(int sessionId) { mSessionId = sessionId; }
sp<EffectModule> getEffectFromDesc_l(effect_descriptor_t *descriptor);
sp<EffectModule> getEffectFromId_l(int id);
+ sp<EffectModule> getEffectFromType_l(const effect_uuid_t *type);
bool setVolume_l(uint32_t *left, uint32_t *right);
void setDevice_l(uint32_t device);
void setMode_l(uint32_t mode);
@@ -1128,14 +1262,27 @@
return mOutBuffer;
}
- void startTrack() {mActiveTrackCnt++;}
- void stopTrack() {mActiveTrackCnt--;}
- int activeTracks() { return mActiveTrackCnt;}
+ void incTrackCnt() { android_atomic_inc(&mTrackCnt); }
+ void decTrackCnt() { android_atomic_dec(&mTrackCnt); }
+ int32_t trackCnt() { return mTrackCnt;}
+
+ void incActiveTrackCnt() { android_atomic_inc(&mActiveTrackCnt); }
+ void decActiveTrackCnt() { android_atomic_dec(&mActiveTrackCnt); }
+ int32_t activeTrackCnt() { return mActiveTrackCnt;}
uint32_t strategy() { return mStrategy; }
void setStrategy(uint32_t strategy)
{ mStrategy = strategy; }
+ // suspend effect of the given type
+ void setEffectSuspended_l(const effect_uuid_t *type,
+ bool suspend);
+ // suspend all eligible effects
+ void setEffectSuspendedAll_l(bool suspend);
+ // check if effects should be suspend or restored when a given effect is enable or disabled
+ virtual void checkSuspendOnEffectEnabled(const sp<EffectModule>& effect,
+ bool enabled);
+
status_t dump(int fd, const Vector<String16>& args);
protected:
@@ -1143,13 +1290,29 @@
EffectChain(const EffectChain&);
EffectChain& operator =(const EffectChain&);
+ class SuspendedEffectDesc : public RefBase {
+ public:
+ SuspendedEffectDesc() : mRefCount(0) {}
+
+ int mRefCount;
+ effect_uuid_t mType;
+ wp<EffectModule> mEffect;
+ };
+
+ // get a list of effect modules to suspend when an effect of the type
+ // passed is enabled.
+ Vector< sp<EffectModule> > getSuspendEligibleEffects();
+ // get an effect module if it is currently enable
+ sp<EffectModule> getEffectIfEnabled(const effect_uuid_t *type);
+
wp<ThreadBase> mThread; // parent mixer thread
Mutex mLock; // mutex protecting effect list
Vector<sp<EffectModule> > mEffects; // list of effect modules
int mSessionId; // audio session ID
int16_t *mInBuffer; // chain input buffer
int16_t *mOutBuffer; // chain output buffer
- int mActiveTrackCnt; // number of active tracks connected
+ volatile int32_t mActiveTrackCnt; // number of active tracks connected
+ volatile int32_t mTrackCnt; // number of tracks connected
bool mOwnInBuffer; // true if the chain owns its input buffer
int mVolumeCtrlIdx; // index of insert effect having control over volume
uint32_t mLeftVolume; // previous volume on left channel
@@ -1157,23 +1320,43 @@
uint32_t mNewLeftVolume; // new volume on left channel
uint32_t mNewRightVolume; // new volume on right channel
uint32_t mStrategy; // strategy for this effect chain
+ // mSuspendedEffects lists all effect currently suspended in the chain
+ // use effect type UUID timelow field as key. There is no real risk of identical
+ // timeLow fields among effect type UUIDs.
+ KeyedVector< int, sp<SuspendedEffectDesc> > mSuspendedEffects;
+ };
+
+ struct AudioStreamOut {
+ audio_hw_device_t *hwDev;
+ audio_stream_out_t *stream;
+
+ AudioStreamOut(audio_hw_device_t *dev, audio_stream_out_t *out) :
+ hwDev(dev), stream(out) {}
+ };
+
+ struct AudioStreamIn {
+ audio_hw_device_t *hwDev;
+ audio_stream_in_t *stream;
+
+ AudioStreamIn(audio_hw_device_t *dev, audio_stream_in_t *in) :
+ hwDev(dev), stream(in) {}
};
friend class RecordThread;
friend class PlaybackThread;
-
mutable Mutex mLock;
DefaultKeyedVector< pid_t, wp<Client> > mClients;
mutable Mutex mHardwareLock;
- AudioHardwareInterface* mAudioHardware;
+ audio_hw_device_t* mPrimaryHardwareDev;
+ Vector<audio_hw_device_t*> mAudioHwDevs;
mutable int mHardwareStatus;
DefaultKeyedVector< int, sp<PlaybackThread> > mPlaybackThreads;
- PlaybackThread::stream_type_t mStreamTypes[AudioSystem::NUM_STREAM_TYPES];
+ PlaybackThread::stream_type_t mStreamTypes[AUDIO_STREAM_CNT];
float mMasterVolume;
bool mMasterMute;
@@ -1181,10 +1364,12 @@
DefaultKeyedVector< pid_t, sp<NotificationClient> > mNotificationClients;
volatile int32_t mNextUniqueId;
- uint32_t mMode;
+ uint32_t mMode;
+ bool mBtNrec;
};
+
// ----------------------------------------------------------------------------
}; // namespace android
diff --git a/services/audioflinger/AudioHardwareGeneric.cpp b/services/audioflinger/AudioHardwareGeneric.cpp
deleted file mode 100644
index d63c031..0000000
--- a/services/audioflinger/AudioHardwareGeneric.cpp
+++ /dev/null
@@ -1,411 +0,0 @@
-/*
-**
-** Copyright 2007, 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.
-*/
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sched.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-
-#define LOG_TAG "AudioHardware"
-#include <utils/Log.h>
-#include <utils/String8.h>
-
-#include "AudioHardwareGeneric.h"
-#include <media/AudioRecord.h>
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-static char const * const kAudioDeviceName = "/dev/eac";
-
-// ----------------------------------------------------------------------------
-
-AudioHardwareGeneric::AudioHardwareGeneric()
- : mOutput(0), mInput(0), mFd(-1), mMicMute(false)
-{
- mFd = ::open(kAudioDeviceName, O_RDWR);
-}
-
-AudioHardwareGeneric::~AudioHardwareGeneric()
-{
- if (mFd >= 0) ::close(mFd);
- closeOutputStream((AudioStreamOut *)mOutput);
- closeInputStream((AudioStreamIn *)mInput);
-}
-
-status_t AudioHardwareGeneric::initCheck()
-{
- if (mFd >= 0) {
- if (::access(kAudioDeviceName, O_RDWR) == NO_ERROR)
- return NO_ERROR;
- }
- return NO_INIT;
-}
-
-AudioStreamOut* AudioHardwareGeneric::openOutputStream(
- uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status)
-{
- AutoMutex lock(mLock);
-
- // only one output stream allowed
- if (mOutput) {
- if (status) {
- *status = INVALID_OPERATION;
- }
- return 0;
- }
-
- // create new output stream
- AudioStreamOutGeneric* out = new AudioStreamOutGeneric();
- status_t lStatus = out->set(this, mFd, devices, format, channels, sampleRate);
- if (status) {
- *status = lStatus;
- }
- if (lStatus == NO_ERROR) {
- mOutput = out;
- } else {
- delete out;
- }
- return mOutput;
-}
-
-void AudioHardwareGeneric::closeOutputStream(AudioStreamOut* out) {
- if (mOutput && out == mOutput) {
- delete mOutput;
- mOutput = 0;
- }
-}
-
-AudioStreamIn* AudioHardwareGeneric::openInputStream(
- uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate,
- status_t *status, AudioSystem::audio_in_acoustics acoustics)
-{
- // check for valid input source
- if (!AudioSystem::isInputDevice((AudioSystem::audio_devices)devices)) {
- return 0;
- }
-
- AutoMutex lock(mLock);
-
- // only one input stream allowed
- if (mInput) {
- if (status) {
- *status = INVALID_OPERATION;
- }
- return 0;
- }
-
- // create new output stream
- AudioStreamInGeneric* in = new AudioStreamInGeneric();
- status_t lStatus = in->set(this, mFd, devices, format, channels, sampleRate, acoustics);
- if (status) {
- *status = lStatus;
- }
- if (lStatus == NO_ERROR) {
- mInput = in;
- } else {
- delete in;
- }
- return mInput;
-}
-
-void AudioHardwareGeneric::closeInputStream(AudioStreamIn* in) {
- if (mInput && in == mInput) {
- delete mInput;
- mInput = 0;
- }
-}
-
-status_t AudioHardwareGeneric::setVoiceVolume(float v)
-{
- // Implement: set voice volume
- return NO_ERROR;
-}
-
-status_t AudioHardwareGeneric::setMasterVolume(float v)
-{
- // Implement: set master volume
- // return error - software mixer will handle it
- return INVALID_OPERATION;
-}
-
-status_t AudioHardwareGeneric::setMicMute(bool state)
-{
- mMicMute = state;
- return NO_ERROR;
-}
-
-status_t AudioHardwareGeneric::getMicMute(bool* state)
-{
- *state = mMicMute;
- return NO_ERROR;
-}
-
-status_t AudioHardwareGeneric::dumpInternals(int fd, const Vector<String16>& args)
-{
- const size_t SIZE = 256;
- char buffer[SIZE];
- String8 result;
- result.append("AudioHardwareGeneric::dumpInternals\n");
- snprintf(buffer, SIZE, "\tmFd: %d mMicMute: %s\n", mFd, mMicMute? "true": "false");
- result.append(buffer);
- ::write(fd, result.string(), result.size());
- return NO_ERROR;
-}
-
-status_t AudioHardwareGeneric::dump(int fd, const Vector<String16>& args)
-{
- dumpInternals(fd, args);
- if (mInput) {
- mInput->dump(fd, args);
- }
- if (mOutput) {
- mOutput->dump(fd, args);
- }
- return NO_ERROR;
-}
-
-// ----------------------------------------------------------------------------
-
-status_t AudioStreamOutGeneric::set(
- AudioHardwareGeneric *hw,
- int fd,
- uint32_t devices,
- int *pFormat,
- uint32_t *pChannels,
- uint32_t *pRate)
-{
- int lFormat = pFormat ? *pFormat : 0;
- uint32_t lChannels = pChannels ? *pChannels : 0;
- uint32_t lRate = pRate ? *pRate : 0;
-
- // fix up defaults
- if (lFormat == 0) lFormat = format();
- if (lChannels == 0) lChannels = channels();
- if (lRate == 0) lRate = sampleRate();
-
- // check values
- if ((lFormat != format()) ||
- (lChannels != channels()) ||
- (lRate != sampleRate())) {
- if (pFormat) *pFormat = format();
- if (pChannels) *pChannels = channels();
- if (pRate) *pRate = sampleRate();
- return BAD_VALUE;
- }
-
- if (pFormat) *pFormat = lFormat;
- if (pChannels) *pChannels = lChannels;
- if (pRate) *pRate = lRate;
-
- mAudioHardware = hw;
- mFd = fd;
- mDevice = devices;
- return NO_ERROR;
-}
-
-AudioStreamOutGeneric::~AudioStreamOutGeneric()
-{
-}
-
-ssize_t AudioStreamOutGeneric::write(const void* buffer, size_t bytes)
-{
- Mutex::Autolock _l(mLock);
- return ssize_t(::write(mFd, buffer, bytes));
-}
-
-status_t AudioStreamOutGeneric::standby()
-{
- // Implement: audio hardware to standby mode
- return NO_ERROR;
-}
-
-status_t AudioStreamOutGeneric::dump(int fd, const Vector<String16>& args)
-{
- const size_t SIZE = 256;
- char buffer[SIZE];
- String8 result;
- snprintf(buffer, SIZE, "AudioStreamOutGeneric::dump\n");
- result.append(buffer);
- snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
- result.append(buffer);
- snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
- result.append(buffer);
- snprintf(buffer, SIZE, "\tchannels: %d\n", channels());
- result.append(buffer);
- snprintf(buffer, SIZE, "\tformat: %d\n", format());
- result.append(buffer);
- snprintf(buffer, SIZE, "\tdevice: %d\n", mDevice);
- result.append(buffer);
- snprintf(buffer, SIZE, "\tmAudioHardware: %p\n", mAudioHardware);
- result.append(buffer);
- snprintf(buffer, SIZE, "\tmFd: %d\n", mFd);
- result.append(buffer);
- ::write(fd, result.string(), result.size());
- return NO_ERROR;
-}
-
-status_t AudioStreamOutGeneric::setParameters(const String8& keyValuePairs)
-{
- AudioParameter param = AudioParameter(keyValuePairs);
- String8 key = String8(AudioParameter::keyRouting);
- status_t status = NO_ERROR;
- int device;
- LOGV("setParameters() %s", keyValuePairs.string());
-
- if (param.getInt(key, device) == NO_ERROR) {
- mDevice = device;
- param.remove(key);
- }
-
- if (param.size()) {
- status = BAD_VALUE;
- }
- return status;
-}
-
-String8 AudioStreamOutGeneric::getParameters(const String8& keys)
-{
- AudioParameter param = AudioParameter(keys);
- String8 value;
- String8 key = String8(AudioParameter::keyRouting);
-
- if (param.get(key, value) == NO_ERROR) {
- param.addInt(key, (int)mDevice);
- }
-
- LOGV("getParameters() %s", param.toString().string());
- return param.toString();
-}
-
-status_t AudioStreamOutGeneric::getRenderPosition(uint32_t *dspFrames)
-{
- return INVALID_OPERATION;
-}
-
-// ----------------------------------------------------------------------------
-
-// record functions
-status_t AudioStreamInGeneric::set(
- AudioHardwareGeneric *hw,
- int fd,
- uint32_t devices,
- int *pFormat,
- uint32_t *pChannels,
- uint32_t *pRate,
- AudioSystem::audio_in_acoustics acoustics)
-{
- if (pFormat == 0 || pChannels == 0 || pRate == 0) return BAD_VALUE;
- LOGV("AudioStreamInGeneric::set(%p, %d, %d, %d, %u)", hw, fd, *pFormat, *pChannels, *pRate);
- // check values
- if ((*pFormat != format()) ||
- (*pChannels != channels()) ||
- (*pRate != sampleRate())) {
- LOGE("Error opening input channel");
- *pFormat = format();
- *pChannels = channels();
- *pRate = sampleRate();
- return BAD_VALUE;
- }
-
- mAudioHardware = hw;
- mFd = fd;
- mDevice = devices;
- return NO_ERROR;
-}
-
-AudioStreamInGeneric::~AudioStreamInGeneric()
-{
-}
-
-ssize_t AudioStreamInGeneric::read(void* buffer, ssize_t bytes)
-{
- AutoMutex lock(mLock);
- if (mFd < 0) {
- LOGE("Attempt to read from unopened device");
- return NO_INIT;
- }
- return ::read(mFd, buffer, bytes);
-}
-
-status_t AudioStreamInGeneric::dump(int fd, const Vector<String16>& args)
-{
- const size_t SIZE = 256;
- char buffer[SIZE];
- String8 result;
- snprintf(buffer, SIZE, "AudioStreamInGeneric::dump\n");
- result.append(buffer);
- snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
- result.append(buffer);
- snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
- result.append(buffer);
- snprintf(buffer, SIZE, "\tchannels: %d\n", channels());
- result.append(buffer);
- snprintf(buffer, SIZE, "\tformat: %d\n", format());
- result.append(buffer);
- snprintf(buffer, SIZE, "\tdevice: %d\n", mDevice);
- result.append(buffer);
- snprintf(buffer, SIZE, "\tmAudioHardware: %p\n", mAudioHardware);
- result.append(buffer);
- snprintf(buffer, SIZE, "\tmFd: %d\n", mFd);
- result.append(buffer);
- ::write(fd, result.string(), result.size());
- return NO_ERROR;
-}
-
-status_t AudioStreamInGeneric::setParameters(const String8& keyValuePairs)
-{
- AudioParameter param = AudioParameter(keyValuePairs);
- String8 key = String8(AudioParameter::keyRouting);
- status_t status = NO_ERROR;
- int device;
- LOGV("setParameters() %s", keyValuePairs.string());
-
- if (param.getInt(key, device) == NO_ERROR) {
- mDevice = device;
- param.remove(key);
- }
-
- if (param.size()) {
- status = BAD_VALUE;
- }
- return status;
-}
-
-String8 AudioStreamInGeneric::getParameters(const String8& keys)
-{
- AudioParameter param = AudioParameter(keys);
- String8 value;
- String8 key = String8(AudioParameter::keyRouting);
-
- if (param.get(key, value) == NO_ERROR) {
- param.addInt(key, (int)mDevice);
- }
-
- LOGV("getParameters() %s", param.toString().string());
- return param.toString();
-}
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/services/audioflinger/AudioHardwareGeneric.h b/services/audioflinger/AudioHardwareGeneric.h
deleted file mode 100644
index aa4e78d..0000000
--- a/services/audioflinger/AudioHardwareGeneric.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
-**
-** Copyright 2007, 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 ANDROID_AUDIO_HARDWARE_GENERIC_H
-#define ANDROID_AUDIO_HARDWARE_GENERIC_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/threads.h>
-
-#include <hardware_legacy/AudioHardwareBase.h>
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-class AudioHardwareGeneric;
-
-class AudioStreamOutGeneric : public AudioStreamOut {
-public:
- AudioStreamOutGeneric() : mAudioHardware(0), mFd(-1) {}
- virtual ~AudioStreamOutGeneric();
-
- virtual status_t set(
- AudioHardwareGeneric *hw,
- int mFd,
- uint32_t devices,
- int *pFormat,
- uint32_t *pChannels,
- uint32_t *pRate);
-
- virtual uint32_t sampleRate() const { return 44100; }
- virtual size_t bufferSize() const { return 4096; }
- virtual uint32_t channels() const { return AudioSystem::CHANNEL_OUT_STEREO; }
- virtual int format() const { return AudioSystem::PCM_16_BIT; }
- virtual uint32_t latency() const { return 20; }
- virtual status_t setVolume(float left, float right) { return INVALID_OPERATION; }
- virtual ssize_t write(const void* buffer, size_t bytes);
- virtual status_t standby();
- virtual status_t dump(int fd, const Vector<String16>& args);
- virtual status_t setParameters(const String8& keyValuePairs);
- virtual String8 getParameters(const String8& keys);
- virtual status_t getRenderPosition(uint32_t *dspFrames);
-
-private:
- AudioHardwareGeneric *mAudioHardware;
- Mutex mLock;
- int mFd;
- uint32_t mDevice;
-};
-
-class AudioStreamInGeneric : public AudioStreamIn {
-public:
- AudioStreamInGeneric() : mAudioHardware(0), mFd(-1) {}
- virtual ~AudioStreamInGeneric();
-
- virtual status_t set(
- AudioHardwareGeneric *hw,
- int mFd,
- uint32_t devices,
- int *pFormat,
- uint32_t *pChannels,
- uint32_t *pRate,
- AudioSystem::audio_in_acoustics acoustics);
-
- virtual uint32_t sampleRate() const { return 8000; }
- virtual size_t bufferSize() const { return 320; }
- virtual uint32_t channels() const { return AudioSystem::CHANNEL_IN_MONO; }
- virtual int format() const { return AudioSystem::PCM_16_BIT; }
- virtual status_t setGain(float gain) { return INVALID_OPERATION; }
- virtual ssize_t read(void* buffer, ssize_t bytes);
- virtual status_t dump(int fd, const Vector<String16>& args);
- virtual status_t standby() { return NO_ERROR; }
- virtual status_t setParameters(const String8& keyValuePairs);
- virtual String8 getParameters(const String8& keys);
- virtual unsigned int getInputFramesLost() const { return 0; }
-
-private:
- AudioHardwareGeneric *mAudioHardware;
- Mutex mLock;
- int mFd;
- uint32_t mDevice;
-};
-
-
-class AudioHardwareGeneric : public AudioHardwareBase
-{
-public:
- AudioHardwareGeneric();
- virtual ~AudioHardwareGeneric();
- virtual status_t initCheck();
- virtual status_t setVoiceVolume(float volume);
- virtual status_t setMasterVolume(float volume);
-
- // mic mute
- virtual status_t setMicMute(bool state);
- virtual status_t getMicMute(bool* state);
-
- // create I/O streams
- virtual AudioStreamOut* openOutputStream(
- uint32_t devices,
- int *format=0,
- uint32_t *channels=0,
- uint32_t *sampleRate=0,
- status_t *status=0);
- virtual void closeOutputStream(AudioStreamOut* out);
-
- virtual AudioStreamIn* openInputStream(
- uint32_t devices,
- int *format,
- uint32_t *channels,
- uint32_t *sampleRate,
- status_t *status,
- AudioSystem::audio_in_acoustics acoustics);
- virtual void closeInputStream(AudioStreamIn* in);
-
- void closeOutputStream(AudioStreamOutGeneric* out);
- void closeInputStream(AudioStreamInGeneric* in);
-protected:
- virtual status_t dump(int fd, const Vector<String16>& args);
-
-private:
- status_t dumpInternals(int fd, const Vector<String16>& args);
-
- Mutex mLock;
- AudioStreamOutGeneric *mOutput;
- AudioStreamInGeneric *mInput;
- int mFd;
- bool mMicMute;
-};
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_AUDIO_HARDWARE_GENERIC_H
diff --git a/services/audioflinger/AudioHardwareInterface.cpp b/services/audioflinger/AudioHardwareInterface.cpp
deleted file mode 100644
index f58e4c0..0000000
--- a/services/audioflinger/AudioHardwareInterface.cpp
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
-**
-** Copyright 2007, 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.
-*/
-
-#include <cutils/properties.h>
-#include <string.h>
-#include <unistd.h>
-//#define LOG_NDEBUG 0
-
-#define LOG_TAG "AudioHardwareInterface"
-#include <utils/Log.h>
-#include <utils/String8.h>
-
-#include "AudioHardwareStub.h"
-#include "AudioHardwareGeneric.h"
-#ifdef WITH_A2DP
-#include "A2dpAudioInterface.h"
-#endif
-
-#ifdef ENABLE_AUDIO_DUMP
-#include "AudioDumpInterface.h"
-#endif
-
-
-// change to 1 to log routing calls
-#define LOG_ROUTING_CALLS 1
-
-namespace android {
-
-#if LOG_ROUTING_CALLS
-static const char* routingModeStrings[] =
-{
- "OUT OF RANGE",
- "INVALID",
- "CURRENT",
- "NORMAL",
- "RINGTONE",
- "IN_CALL",
- "IN_COMMUNICATION"
-};
-
-static const char* routeNone = "NONE";
-
-static const char* displayMode(int mode)
-{
- if ((mode < AudioSystem::MODE_INVALID) || (mode >= AudioSystem::NUM_MODES))
- return routingModeStrings[0];
- return routingModeStrings[mode+3];
-}
-#endif
-
-// ----------------------------------------------------------------------------
-
-AudioHardwareInterface* AudioHardwareInterface::create()
-{
- /*
- * FIXME: This code needs to instantiate the correct audio device
- * interface. For now - we use compile-time switches.
- */
- AudioHardwareInterface* hw = 0;
- char value[PROPERTY_VALUE_MAX];
-
-#ifdef GENERIC_AUDIO
- hw = new AudioHardwareGeneric();
-#else
- // if running in emulation - use the emulator driver
- if (property_get("ro.kernel.qemu", value, 0)) {
- LOGD("Running in emulation - using generic audio driver");
- hw = new AudioHardwareGeneric();
- }
- else {
- LOGV("Creating Vendor Specific AudioHardware");
- hw = createAudioHardware();
- }
-#endif
- if (hw->initCheck() != NO_ERROR) {
- LOGW("Using stubbed audio hardware. No sound will be produced.");
- delete hw;
- hw = new AudioHardwareStub();
- }
-
-#ifdef WITH_A2DP
- hw = new A2dpAudioInterface(hw);
-#endif
-
-#ifdef ENABLE_AUDIO_DUMP
- // This code adds a record of buffers in a file to write calls made by AudioFlinger.
- // It replaces the current AudioHardwareInterface object by an intermediate one which
- // will record buffers in a file (after sending them to hardware) for testing purpose.
- // This feature is enabled by defining symbol ENABLE_AUDIO_DUMP.
- // The output file is set with setParameters("test_cmd_file_name=<name>"). Pause are not recorded in the file.
- LOGV("opening PCM dump interface");
- hw = new AudioDumpInterface(hw); // replace interface
-#endif
- return hw;
-}
-
-AudioStreamOut::~AudioStreamOut()
-{
-}
-
-AudioStreamIn::~AudioStreamIn() {}
-
-AudioHardwareBase::AudioHardwareBase()
-{
- mMode = 0;
-}
-
-status_t AudioHardwareBase::setMode(int mode)
-{
-#if LOG_ROUTING_CALLS
- LOGD("setMode(%s)", displayMode(mode));
-#endif
- if ((mode < 0) || (mode >= AudioSystem::NUM_MODES))
- return BAD_VALUE;
- if (mMode == mode)
- return ALREADY_EXISTS;
- mMode = mode;
- return NO_ERROR;
-}
-
-// default implementation
-status_t AudioHardwareBase::setParameters(const String8& keyValuePairs)
-{
- return NO_ERROR;
-}
-
-// default implementation
-String8 AudioHardwareBase::getParameters(const String8& keys)
-{
- AudioParameter param = AudioParameter(keys);
- return param.toString();
-}
-
-// default implementation
-size_t AudioHardwareBase::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
-{
- if (sampleRate != 8000) {
- LOGW("getInputBufferSize bad sampling rate: %d", sampleRate);
- return 0;
- }
- if (format != AudioSystem::PCM_16_BIT) {
- LOGW("getInputBufferSize bad format: %d", format);
- return 0;
- }
- if (channelCount != 1) {
- LOGW("getInputBufferSize bad channel count: %d", channelCount);
- return 0;
- }
-
- return 320;
-}
-
-status_t AudioHardwareBase::dumpState(int fd, const Vector<String16>& args)
-{
- const size_t SIZE = 256;
- char buffer[SIZE];
- String8 result;
- snprintf(buffer, SIZE, "AudioHardwareBase::dumpState\n");
- result.append(buffer);
- snprintf(buffer, SIZE, "\tmMode: %d\n", mMode);
- result.append(buffer);
- ::write(fd, result.string(), result.size());
- dump(fd, args); // Dump the state of the concrete child.
- return NO_ERROR;
-}
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/services/audioflinger/AudioHardwareStub.cpp b/services/audioflinger/AudioHardwareStub.cpp
deleted file mode 100644
index d481150..0000000
--- a/services/audioflinger/AudioHardwareStub.cpp
+++ /dev/null
@@ -1,209 +0,0 @@
-/* //device/servers/AudioFlinger/AudioHardwareStub.cpp
-**
-** Copyright 2007, 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.
-*/
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <utils/String8.h>
-
-#include "AudioHardwareStub.h"
-#include <media/AudioRecord.h>
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-AudioHardwareStub::AudioHardwareStub() : mMicMute(false)
-{
-}
-
-AudioHardwareStub::~AudioHardwareStub()
-{
-}
-
-status_t AudioHardwareStub::initCheck()
-{
- return NO_ERROR;
-}
-
-AudioStreamOut* AudioHardwareStub::openOutputStream(
- uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status)
-{
- AudioStreamOutStub* out = new AudioStreamOutStub();
- status_t lStatus = out->set(format, channels, sampleRate);
- if (status) {
- *status = lStatus;
- }
- if (lStatus == NO_ERROR)
- return out;
- delete out;
- return 0;
-}
-
-void AudioHardwareStub::closeOutputStream(AudioStreamOut* out)
-{
- delete out;
-}
-
-AudioStreamIn* AudioHardwareStub::openInputStream(
- uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate,
- status_t *status, AudioSystem::audio_in_acoustics acoustics)
-{
- // check for valid input source
- if (!AudioSystem::isInputDevice((AudioSystem::audio_devices)devices)) {
- return 0;
- }
-
- AudioStreamInStub* in = new AudioStreamInStub();
- status_t lStatus = in->set(format, channels, sampleRate, acoustics);
- if (status) {
- *status = lStatus;
- }
- if (lStatus == NO_ERROR)
- return in;
- delete in;
- return 0;
-}
-
-void AudioHardwareStub::closeInputStream(AudioStreamIn* in)
-{
- delete in;
-}
-
-status_t AudioHardwareStub::setVoiceVolume(float volume)
-{
- return NO_ERROR;
-}
-
-status_t AudioHardwareStub::setMasterVolume(float volume)
-{
- return NO_ERROR;
-}
-
-status_t AudioHardwareStub::dumpInternals(int fd, const Vector<String16>& args)
-{
- const size_t SIZE = 256;
- char buffer[SIZE];
- String8 result;
- result.append("AudioHardwareStub::dumpInternals\n");
- snprintf(buffer, SIZE, "\tmMicMute: %s\n", mMicMute? "true": "false");
- result.append(buffer);
- ::write(fd, result.string(), result.size());
- return NO_ERROR;
-}
-
-status_t AudioHardwareStub::dump(int fd, const Vector<String16>& args)
-{
- dumpInternals(fd, args);
- return NO_ERROR;
-}
-
-// ----------------------------------------------------------------------------
-
-status_t AudioStreamOutStub::set(int *pFormat, uint32_t *pChannels, uint32_t *pRate)
-{
- if (pFormat) *pFormat = format();
- if (pChannels) *pChannels = channels();
- if (pRate) *pRate = sampleRate();
-
- return NO_ERROR;
-}
-
-ssize_t AudioStreamOutStub::write(const void* buffer, size_t bytes)
-{
- // fake timing for audio output
- usleep(bytes * 1000000 / sizeof(int16_t) / AudioSystem::popCount(channels()) / sampleRate());
- return bytes;
-}
-
-status_t AudioStreamOutStub::standby()
-{
- return NO_ERROR;
-}
-
-status_t AudioStreamOutStub::dump(int fd, const Vector<String16>& args)
-{
- const size_t SIZE = 256;
- char buffer[SIZE];
- String8 result;
- snprintf(buffer, SIZE, "AudioStreamOutStub::dump\n");
- snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
- snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
- snprintf(buffer, SIZE, "\tchannels: %d\n", channels());
- snprintf(buffer, SIZE, "\tformat: %d\n", format());
- result.append(buffer);
- ::write(fd, result.string(), result.size());
- return NO_ERROR;
-}
-
-String8 AudioStreamOutStub::getParameters(const String8& keys)
-{
- AudioParameter param = AudioParameter(keys);
- return param.toString();
-}
-
-status_t AudioStreamOutStub::getRenderPosition(uint32_t *dspFrames)
-{
- return INVALID_OPERATION;
-}
-
-// ----------------------------------------------------------------------------
-
-status_t AudioStreamInStub::set(int *pFormat, uint32_t *pChannels, uint32_t *pRate,
- AudioSystem::audio_in_acoustics acoustics)
-{
- return NO_ERROR;
-}
-
-ssize_t AudioStreamInStub::read(void* buffer, ssize_t bytes)
-{
- // fake timing for audio input
- usleep(bytes * 1000000 / sizeof(int16_t) / AudioSystem::popCount(channels()) / sampleRate());
- memset(buffer, 0, bytes);
- return bytes;
-}
-
-status_t AudioStreamInStub::dump(int fd, const Vector<String16>& args)
-{
- const size_t SIZE = 256;
- char buffer[SIZE];
- String8 result;
- snprintf(buffer, SIZE, "AudioStreamInStub::dump\n");
- result.append(buffer);
- snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
- result.append(buffer);
- snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
- result.append(buffer);
- snprintf(buffer, SIZE, "\tchannels: %d\n", channels());
- result.append(buffer);
- snprintf(buffer, SIZE, "\tformat: %d\n", format());
- result.append(buffer);
- ::write(fd, result.string(), result.size());
- return NO_ERROR;
-}
-
-String8 AudioStreamInStub::getParameters(const String8& keys)
-{
- AudioParameter param = AudioParameter(keys);
- return param.toString();
-}
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/services/audioflinger/AudioHardwareStub.h b/services/audioflinger/AudioHardwareStub.h
deleted file mode 100644
index 06a29de..0000000
--- a/services/audioflinger/AudioHardwareStub.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/* //device/servers/AudioFlinger/AudioHardwareStub.h
-**
-** Copyright 2007, 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 ANDROID_AUDIO_HARDWARE_STUB_H
-#define ANDROID_AUDIO_HARDWARE_STUB_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <hardware_legacy/AudioHardwareBase.h>
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-class AudioStreamOutStub : public AudioStreamOut {
-public:
- virtual status_t set(int *pFormat, uint32_t *pChannels, uint32_t *pRate);
- virtual uint32_t sampleRate() const { return 44100; }
- virtual size_t bufferSize() const { return 4096; }
- virtual uint32_t channels() const { return AudioSystem::CHANNEL_OUT_STEREO; }
- virtual int format() const { return AudioSystem::PCM_16_BIT; }
- virtual uint32_t latency() const { return 0; }
- virtual status_t setVolume(float left, float right) { return NO_ERROR; }
- virtual ssize_t write(const void* buffer, size_t bytes);
- virtual status_t standby();
- virtual status_t dump(int fd, const Vector<String16>& args);
- virtual status_t setParameters(const String8& keyValuePairs) { return NO_ERROR;}
- virtual String8 getParameters(const String8& keys);
- virtual status_t getRenderPosition(uint32_t *dspFrames);
-};
-
-class AudioStreamInStub : public AudioStreamIn {
-public:
- virtual status_t set(int *pFormat, uint32_t *pChannels, uint32_t *pRate, AudioSystem::audio_in_acoustics acoustics);
- virtual uint32_t sampleRate() const { return 8000; }
- virtual size_t bufferSize() const { return 320; }
- virtual uint32_t channels() const { return AudioSystem::CHANNEL_IN_MONO; }
- virtual int format() const { return AudioSystem::PCM_16_BIT; }
- virtual status_t setGain(float gain) { return NO_ERROR; }
- virtual ssize_t read(void* buffer, ssize_t bytes);
- virtual status_t dump(int fd, const Vector<String16>& args);
- virtual status_t standby() { return NO_ERROR; }
- virtual status_t setParameters(const String8& keyValuePairs) { return NO_ERROR;}
- virtual String8 getParameters(const String8& keys);
- virtual unsigned int getInputFramesLost() const { return 0; }
-};
-
-class AudioHardwareStub : public AudioHardwareBase
-{
-public:
- AudioHardwareStub();
- virtual ~AudioHardwareStub();
- virtual status_t initCheck();
- virtual status_t setVoiceVolume(float volume);
- virtual status_t setMasterVolume(float volume);
-
- // mic mute
- virtual status_t setMicMute(bool state) { mMicMute = state; return NO_ERROR; }
- virtual status_t getMicMute(bool* state) { *state = mMicMute ; return NO_ERROR; }
-
- // create I/O streams
- virtual AudioStreamOut* openOutputStream(
- uint32_t devices,
- int *format=0,
- uint32_t *channels=0,
- uint32_t *sampleRate=0,
- status_t *status=0);
- virtual void closeOutputStream(AudioStreamOut* out);
-
- virtual AudioStreamIn* openInputStream(
- uint32_t devices,
- int *format,
- uint32_t *channels,
- uint32_t *sampleRate,
- status_t *status,
- AudioSystem::audio_in_acoustics acoustics);
- virtual void closeInputStream(AudioStreamIn* in);
-
-protected:
- virtual status_t dump(int fd, const Vector<String16>& args);
-
- bool mMicMute;
-private:
- status_t dumpInternals(int fd, const Vector<String16>& args);
-};
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_AUDIO_HARDWARE_STUB_H
diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp
index 50dcda7..6e9319d 100644
--- a/services/audioflinger/AudioMixer.cpp
+++ b/services/audioflinger/AudioMixer.cpp
@@ -26,6 +26,10 @@
#include <utils/Errors.h>
#include <utils/Log.h>
+#include <cutils/bitops.h>
+
+#include <system/audio.h>
+
#include "AudioMixer.h"
namespace android {
@@ -61,6 +65,7 @@
t->channelCount = 2;
t->enabled = 0;
t->format = 16;
+ t->channelMask = AUDIO_CHANNEL_OUT_STEREO;
t->buffer.raw = 0;
t->bufferProvider = 0;
t->hook = 0;
@@ -180,13 +185,18 @@
switch (target) {
case TRACK:
- if (name == CHANNEL_COUNT) {
- if ((uint32_t(valueInt) <= MAX_NUM_CHANNELS) && (valueInt)) {
- if (mState.tracks[ mActiveTrack ].channelCount != valueInt) {
- mState.tracks[ mActiveTrack ].channelCount = valueInt;
- LOGV("setParameter(TRACK, CHANNEL_COUNT, %d)", valueInt);
+ if (name == CHANNEL_MASK) {
+ uint32_t mask = (uint32_t)value;
+ if (mState.tracks[ mActiveTrack ].channelMask != mask) {
+ uint8_t channelCount = popcount(mask);
+ if ((channelCount <= MAX_NUM_CHANNELS) && (channelCount)) {
+ mState.tracks[ mActiveTrack ].channelMask = mask;
+ mState.tracks[ mActiveTrack ].channelCount = channelCount;
+ LOGV("setParameter(TRACK, CHANNEL_MASK, %x)", mask);
invalidateState(1<<mActiveTrack);
+ return NO_ERROR;
}
+ } else {
return NO_ERROR;
}
}
diff --git a/services/audioflinger/AudioMixer.h b/services/audioflinger/AudioMixer.h
index 88408a7..75c9170 100644
--- a/services/audioflinger/AudioMixer.h
+++ b/services/audioflinger/AudioMixer.h
@@ -61,7 +61,7 @@
// set Parameter names
// for target TRACK
- CHANNEL_COUNT = 0x4000,
+ CHANNEL_MASK = 0x4000,
FORMAT = 0x4001,
MAIN_BUFFER = 0x4002,
AUX_BUFFER = 0x4003,
@@ -150,6 +150,7 @@
uint8_t enabled : 1;
uint8_t reserved0 : 3;
uint8_t format;
+ uint32_t channelMask;
AudioBufferProvider* bufferProvider;
mutable AudioBufferProvider::Buffer buffer;
diff --git a/services/audioflinger/AudioPolicyManagerBase.cpp b/services/audioflinger/AudioPolicyManagerBase.cpp
deleted file mode 100644
index f5e7343..0000000
--- a/services/audioflinger/AudioPolicyManagerBase.cpp
+++ /dev/null
@@ -1,2286 +0,0 @@
-/*
- * 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_TAG "AudioPolicyManagerBase"
-//#define LOG_NDEBUG 0
-#include <utils/Log.h>
-#include <hardware_legacy/AudioPolicyManagerBase.h>
-#include <media/mediarecorder.h>
-#include <math.h>
-
-namespace android {
-
-
-// ----------------------------------------------------------------------------
-// AudioPolicyInterface implementation
-// ----------------------------------------------------------------------------
-
-
-status_t AudioPolicyManagerBase::setDeviceConnectionState(AudioSystem::audio_devices device,
- AudioSystem::device_connection_state state,
- const char *device_address)
-{
-
- LOGV("setDeviceConnectionState() device: %x, state %d, address %s", device, state, device_address);
-
- // connect/disconnect only 1 device at a time
- if (AudioSystem::popCount(device) != 1) return BAD_VALUE;
-
- if (strlen(device_address) >= MAX_DEVICE_ADDRESS_LEN) {
- LOGE("setDeviceConnectionState() invalid address: %s", device_address);
- return BAD_VALUE;
- }
-
- // handle output devices
- if (AudioSystem::isOutputDevice(device)) {
-
-#ifndef WITH_A2DP
- if (AudioSystem::isA2dpDevice(device)) {
- LOGE("setDeviceConnectionState() invalid device: %x", device);
- return BAD_VALUE;
- }
-#endif
-
- switch (state)
- {
- // handle output device connection
- case AudioSystem::DEVICE_STATE_AVAILABLE:
- if (mAvailableOutputDevices & device) {
- LOGW("setDeviceConnectionState() device already connected: %x", device);
- return INVALID_OPERATION;
- }
- LOGV("setDeviceConnectionState() connecting device %x", device);
-
- // register new device as available
- mAvailableOutputDevices |= device;
-
-#ifdef WITH_A2DP
- // handle A2DP device connection
- if (AudioSystem::isA2dpDevice(device)) {
- status_t status = handleA2dpConnection(device, device_address);
- if (status != NO_ERROR) {
- mAvailableOutputDevices &= ~device;
- return status;
- }
- } else
-#endif
- {
- if (AudioSystem::isBluetoothScoDevice(device)) {
- LOGV("setDeviceConnectionState() BT SCO device, address %s", device_address);
- // keep track of SCO device address
- mScoDeviceAddress = String8(device_address, MAX_DEVICE_ADDRESS_LEN);
- }
- }
- break;
- // handle output device disconnection
- case AudioSystem::DEVICE_STATE_UNAVAILABLE: {
- if (!(mAvailableOutputDevices & device)) {
- LOGW("setDeviceConnectionState() device not connected: %x", device);
- return INVALID_OPERATION;
- }
-
-
- LOGV("setDeviceConnectionState() disconnecting device %x", device);
- // remove device from available output devices
- mAvailableOutputDevices &= ~device;
-
-#ifdef WITH_A2DP
- // handle A2DP device disconnection
- if (AudioSystem::isA2dpDevice(device)) {
- status_t status = handleA2dpDisconnection(device, device_address);
- if (status != NO_ERROR) {
- mAvailableOutputDevices |= device;
- return status;
- }
- } else
-#endif
- {
- if (AudioSystem::isBluetoothScoDevice(device)) {
- mScoDeviceAddress = "";
- }
- }
- } break;
-
- default:
- LOGE("setDeviceConnectionState() invalid state: %x", state);
- return BAD_VALUE;
- }
-
- // request routing change if necessary
- uint32_t newDevice = getNewDevice(mHardwareOutput, false);
-#ifdef WITH_A2DP
- checkA2dpSuspend();
- checkOutputForAllStrategies();
- // A2DP outputs must be closed after checkOutputForAllStrategies() is executed
- if (state == AudioSystem::DEVICE_STATE_UNAVAILABLE && AudioSystem::isA2dpDevice(device)) {
- closeA2dpOutputs();
- }
-#endif
- updateDeviceForStrategy();
- setOutputDevice(mHardwareOutput, newDevice);
-
- if (device == AudioSystem::DEVICE_OUT_WIRED_HEADSET) {
- device = AudioSystem::DEVICE_IN_WIRED_HEADSET;
- } else if (device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO ||
- device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET ||
- device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT) {
- device = AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET;
- } else {
- return NO_ERROR;
- }
- }
- // handle input devices
- if (AudioSystem::isInputDevice(device)) {
-
- switch (state)
- {
- // handle input device connection
- case AudioSystem::DEVICE_STATE_AVAILABLE: {
- if (mAvailableInputDevices & device) {
- LOGW("setDeviceConnectionState() device already connected: %d", device);
- return INVALID_OPERATION;
- }
- mAvailableInputDevices |= device;
- }
- break;
-
- // handle input device disconnection
- case AudioSystem::DEVICE_STATE_UNAVAILABLE: {
- if (!(mAvailableInputDevices & device)) {
- LOGW("setDeviceConnectionState() device not connected: %d", device);
- return INVALID_OPERATION;
- }
- mAvailableInputDevices &= ~device;
- } break;
-
- default:
- LOGE("setDeviceConnectionState() invalid state: %x", state);
- return BAD_VALUE;
- }
-
- audio_io_handle_t activeInput = getActiveInput();
- if (activeInput != 0) {
- AudioInputDescriptor *inputDesc = mInputs.valueFor(activeInput);
- uint32_t newDevice = getDeviceForInputSource(inputDesc->mInputSource);
- if (newDevice != inputDesc->mDevice) {
- LOGV("setDeviceConnectionState() changing device from %x to %x for input %d",
- inputDesc->mDevice, newDevice, activeInput);
- inputDesc->mDevice = newDevice;
- AudioParameter param = AudioParameter();
- param.addInt(String8(AudioParameter::keyRouting), (int)newDevice);
- mpClientInterface->setParameters(activeInput, param.toString());
- }
- }
-
- return NO_ERROR;
- }
-
- LOGW("setDeviceConnectionState() invalid device: %x", device);
- return BAD_VALUE;
-}
-
-AudioSystem::device_connection_state AudioPolicyManagerBase::getDeviceConnectionState(AudioSystem::audio_devices device,
- const char *device_address)
-{
- AudioSystem::device_connection_state state = AudioSystem::DEVICE_STATE_UNAVAILABLE;
- String8 address = String8(device_address);
- if (AudioSystem::isOutputDevice(device)) {
- if (device & mAvailableOutputDevices) {
-#ifdef WITH_A2DP
- if (AudioSystem::isA2dpDevice(device) &&
- address != "" && mA2dpDeviceAddress != address) {
- return state;
- }
-#endif
- if (AudioSystem::isBluetoothScoDevice(device) &&
- address != "" && mScoDeviceAddress != address) {
- return state;
- }
- state = AudioSystem::DEVICE_STATE_AVAILABLE;
- }
- } else if (AudioSystem::isInputDevice(device)) {
- if (device & mAvailableInputDevices) {
- state = AudioSystem::DEVICE_STATE_AVAILABLE;
- }
- }
-
- return state;
-}
-
-void AudioPolicyManagerBase::setPhoneState(int state)
-{
- LOGV("setPhoneState() state %d", state);
- uint32_t newDevice = 0;
- if (state < 0 || state >= AudioSystem::NUM_MODES) {
- LOGW("setPhoneState() invalid state %d", state);
- return;
- }
-
- if (state == mPhoneState ) {
- LOGW("setPhoneState() setting same state %d", state);
- return;
- }
-
- // if leaving call state, handle special case of active streams
- // pertaining to sonification strategy see handleIncallSonification()
- if (isInCall()) {
- LOGV("setPhoneState() in call state management: new state is %d", state);
- for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
- handleIncallSonification(stream, false, true);
- }
- }
-
- // store previous phone state for management of sonification strategy below
- int oldState = mPhoneState;
- mPhoneState = state;
- bool force = false;
-
- // are we entering or starting a call
- if (!isStateInCall(oldState) && isStateInCall(state)) {
- LOGV(" Entering call in setPhoneState()");
- // force routing command to audio hardware when starting a call
- // even if no device change is needed
- force = true;
- } else if (isStateInCall(oldState) && !isStateInCall(state)) {
- LOGV(" Exiting call in setPhoneState()");
- // force routing command to audio hardware when exiting a call
- // even if no device change is needed
- force = true;
- } else if (isStateInCall(state) && (state != oldState)) {
- LOGV(" Switching between telephony and VoIP in setPhoneState()");
- // force routing command to audio hardware when switching between telephony and VoIP
- // even if no device change is needed
- force = true;
- }
-
- // check for device and output changes triggered by new phone state
- newDevice = getNewDevice(mHardwareOutput, false);
-#ifdef WITH_A2DP
- checkA2dpSuspend();
- checkOutputForAllStrategies();
-#endif
- updateDeviceForStrategy();
-
- AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mHardwareOutput);
-
- // force routing command to audio hardware when ending call
- // even if no device change is needed
- if (isStateInCall(oldState) && newDevice == 0) {
- newDevice = hwOutputDesc->device();
- }
-
- // when changing from ring tone to in call mode, mute the ringing tone
- // immediately and delay the route change to avoid sending the ring tone
- // tail into the earpiece or headset.
- int delayMs = 0;
- if (isStateInCall(state) && oldState == AudioSystem::MODE_RINGTONE) {
- // delay the device change command by twice the output latency to have some margin
- // and be sure that audio buffers not yet affected by the mute are out when
- // we actually apply the route change
- delayMs = hwOutputDesc->mLatency*2;
- setStreamMute(AudioSystem::RING, true, mHardwareOutput);
- }
-
- // change routing is necessary
- setOutputDevice(mHardwareOutput, newDevice, force, delayMs);
-
- // if entering in call state, handle special case of active streams
- // pertaining to sonification strategy see handleIncallSonification()
- if (isStateInCall(state)) {
- LOGV("setPhoneState() in call state management: new state is %d", state);
- // unmute the ringing tone after a sufficient delay if it was muted before
- // setting output device above
- if (oldState == AudioSystem::MODE_RINGTONE) {
- setStreamMute(AudioSystem::RING, false, mHardwareOutput, MUTE_TIME_MS);
- }
- for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
- handleIncallSonification(stream, true, true);
- }
- }
-
- // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE
- if (state == AudioSystem::MODE_RINGTONE &&
- isStreamActive(AudioSystem::MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) {
- mLimitRingtoneVolume = true;
- } else {
- mLimitRingtoneVolume = false;
- }
-}
-
-void AudioPolicyManagerBase::setRingerMode(uint32_t mode, uint32_t mask)
-{
- LOGV("setRingerMode() mode %x, mask %x", mode, mask);
-
- mRingerMode = mode;
-}
-
-void AudioPolicyManagerBase::setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config)
-{
- LOGV("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mPhoneState);
-
- bool forceVolumeReeval = false;
- switch(usage) {
- case AudioSystem::FOR_COMMUNICATION:
- if (config != AudioSystem::FORCE_SPEAKER && config != AudioSystem::FORCE_BT_SCO &&
- config != AudioSystem::FORCE_NONE) {
- LOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config);
- return;
- }
- forceVolumeReeval = true;
- mForceUse[usage] = config;
- break;
- case AudioSystem::FOR_MEDIA:
- if (config != AudioSystem::FORCE_HEADPHONES && config != AudioSystem::FORCE_BT_A2DP &&
- config != AudioSystem::FORCE_WIRED_ACCESSORY &&
- config != AudioSystem::FORCE_ANALOG_DOCK &&
- config != AudioSystem::FORCE_DIGITAL_DOCK && config != AudioSystem::FORCE_NONE) {
- LOGW("setForceUse() invalid config %d for FOR_MEDIA", config);
- return;
- }
- mForceUse[usage] = config;
- break;
- case AudioSystem::FOR_RECORD:
- if (config != AudioSystem::FORCE_BT_SCO && config != AudioSystem::FORCE_WIRED_ACCESSORY &&
- config != AudioSystem::FORCE_NONE) {
- LOGW("setForceUse() invalid config %d for FOR_RECORD", config);
- return;
- }
- mForceUse[usage] = config;
- break;
- case AudioSystem::FOR_DOCK:
- if (config != AudioSystem::FORCE_NONE && config != AudioSystem::FORCE_BT_CAR_DOCK &&
- config != AudioSystem::FORCE_BT_DESK_DOCK &&
- config != AudioSystem::FORCE_WIRED_ACCESSORY &&
- config != AudioSystem::FORCE_ANALOG_DOCK &&
- config != AudioSystem::FORCE_DIGITAL_DOCK) {
- LOGW("setForceUse() invalid config %d for FOR_DOCK", config);
- }
- forceVolumeReeval = true;
- mForceUse[usage] = config;
- break;
- default:
- LOGW("setForceUse() invalid usage %d", usage);
- break;
- }
-
- // check for device and output changes triggered by new phone state
- uint32_t newDevice = getNewDevice(mHardwareOutput, false);
-#ifdef WITH_A2DP
- checkA2dpSuspend();
- checkOutputForAllStrategies();
-#endif
- updateDeviceForStrategy();
- setOutputDevice(mHardwareOutput, newDevice);
- if (forceVolumeReeval) {
- applyStreamVolumes(mHardwareOutput, newDevice, 0, true);
- }
-
- audio_io_handle_t activeInput = getActiveInput();
- if (activeInput != 0) {
- AudioInputDescriptor *inputDesc = mInputs.valueFor(activeInput);
- newDevice = getDeviceForInputSource(inputDesc->mInputSource);
- if (newDevice != inputDesc->mDevice) {
- LOGV("setForceUse() changing device from %x to %x for input %d",
- inputDesc->mDevice, newDevice, activeInput);
- inputDesc->mDevice = newDevice;
- AudioParameter param = AudioParameter();
- param.addInt(String8(AudioParameter::keyRouting), (int)newDevice);
- mpClientInterface->setParameters(activeInput, param.toString());
- }
- }
-
-}
-
-AudioSystem::forced_config AudioPolicyManagerBase::getForceUse(AudioSystem::force_use usage)
-{
- return mForceUse[usage];
-}
-
-void AudioPolicyManagerBase::setSystemProperty(const char* property, const char* value)
-{
- LOGV("setSystemProperty() property %s, value %s", property, value);
- if (strcmp(property, "ro.camera.sound.forced") == 0) {
- if (atoi(value)) {
- LOGV("ENFORCED_AUDIBLE cannot be muted");
- mStreams[AudioSystem::ENFORCED_AUDIBLE].mCanBeMuted = false;
- } else {
- LOGV("ENFORCED_AUDIBLE can be muted");
- mStreams[AudioSystem::ENFORCED_AUDIBLE].mCanBeMuted = true;
- }
- }
-}
-
-audio_io_handle_t AudioPolicyManagerBase::getOutput(AudioSystem::stream_type stream,
- uint32_t samplingRate,
- uint32_t format,
- uint32_t channels,
- AudioSystem::output_flags flags)
-{
- audio_io_handle_t output = 0;
- uint32_t latency = 0;
- routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream);
- uint32_t device = getDeviceForStrategy(strategy);
- LOGV("getOutput() stream %d, samplingRate %d, format %d, channels %x, flags %x", stream, samplingRate, format, channels, flags);
-
-#ifdef AUDIO_POLICY_TEST
- if (mCurOutput != 0) {
- LOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channels %x, mDirectOutput %d",
- mCurOutput, mTestSamplingRate, mTestFormat, mTestChannels, mDirectOutput);
-
- if (mTestOutputs[mCurOutput] == 0) {
- LOGV("getOutput() opening test output");
- AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor();
- outputDesc->mDevice = mTestDevice;
- outputDesc->mSamplingRate = mTestSamplingRate;
- outputDesc->mFormat = mTestFormat;
- outputDesc->mChannels = mTestChannels;
- outputDesc->mLatency = mTestLatencyMs;
- outputDesc->mFlags = (AudioSystem::output_flags)(mDirectOutput ? AudioSystem::OUTPUT_FLAG_DIRECT : 0);
- outputDesc->mRefCount[stream] = 0;
- mTestOutputs[mCurOutput] = mpClientInterface->openOutput(&outputDesc->mDevice,
- &outputDesc->mSamplingRate,
- &outputDesc->mFormat,
- &outputDesc->mChannels,
- &outputDesc->mLatency,
- outputDesc->mFlags);
- if (mTestOutputs[mCurOutput]) {
- AudioParameter outputCmd = AudioParameter();
- outputCmd.addInt(String8("set_id"),mCurOutput);
- mpClientInterface->setParameters(mTestOutputs[mCurOutput],outputCmd.toString());
- addOutput(mTestOutputs[mCurOutput], outputDesc);
- }
- }
- return mTestOutputs[mCurOutput];
- }
-#endif //AUDIO_POLICY_TEST
-
- // open a direct output if required by specified parameters
- if (needsDirectOuput(stream, samplingRate, format, channels, flags, device)) {
-
- LOGV("getOutput() opening direct output device %x", device);
- AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor();
- outputDesc->mDevice = device;
- outputDesc->mSamplingRate = samplingRate;
- outputDesc->mFormat = format;
- outputDesc->mChannels = channels;
- outputDesc->mLatency = 0;
- outputDesc->mFlags = (AudioSystem::output_flags)(flags | AudioSystem::OUTPUT_FLAG_DIRECT);
- outputDesc->mRefCount[stream] = 0;
- outputDesc->mStopTime[stream] = 0;
- output = mpClientInterface->openOutput(&outputDesc->mDevice,
- &outputDesc->mSamplingRate,
- &outputDesc->mFormat,
- &outputDesc->mChannels,
- &outputDesc->mLatency,
- outputDesc->mFlags);
-
- // only accept an output with the requeted parameters
- if (output == 0 ||
- (samplingRate != 0 && samplingRate != outputDesc->mSamplingRate) ||
- (format != 0 && format != outputDesc->mFormat) ||
- (channels != 0 && channels != outputDesc->mChannels)) {
- LOGV("getOutput() failed opening direct output: samplingRate %d, format %d, channels %d",
- samplingRate, format, channels);
- if (output != 0) {
- mpClientInterface->closeOutput(output);
- }
- delete outputDesc;
- return 0;
- }
- addOutput(output, outputDesc);
- return output;
- }
-
- if (channels != 0 && channels != AudioSystem::CHANNEL_OUT_MONO &&
- channels != AudioSystem::CHANNEL_OUT_STEREO) {
- return 0;
- }
- // open a non direct output
-
- // get which output is suitable for the specified stream. The actual routing change will happen
- // when startOutput() will be called
- uint32_t a2dpDevice = device & AudioSystem::DEVICE_OUT_ALL_A2DP;
- if (AudioSystem::popCount((AudioSystem::audio_devices)device) == 2) {
-#ifdef WITH_A2DP
- if (a2dpUsedForSonification() && a2dpDevice != 0) {
- // if playing on 2 devices among which one is A2DP, use duplicated output
- LOGV("getOutput() using duplicated output");
- LOGW_IF((mA2dpOutput == 0), "getOutput() A2DP device in multiple %x selected but A2DP output not opened", device);
- output = mDuplicatedOutput;
- } else
-#endif
- {
- // if playing on 2 devices among which none is A2DP, use hardware output
- output = mHardwareOutput;
- }
- LOGV("getOutput() using output %d for 2 devices %x", output, device);
- } else {
-#ifdef WITH_A2DP
- if (a2dpDevice != 0) {
- // if playing on A2DP device, use a2dp output
- LOGW_IF((mA2dpOutput == 0), "getOutput() A2DP device %x selected but A2DP output not opened", device);
- output = mA2dpOutput;
- } else
-#endif
- {
- // if playing on not A2DP device, use hardware output
- output = mHardwareOutput;
- }
- }
-
-
- LOGW_IF((output ==0), "getOutput() could not find output for stream %d, samplingRate %d, format %d, channels %x, flags %x",
- stream, samplingRate, format, channels, flags);
-
- return output;
-}
-
-status_t AudioPolicyManagerBase::startOutput(audio_io_handle_t output,
- AudioSystem::stream_type stream,
- int session)
-{
- LOGV("startOutput() output %d, stream %d, session %d", output, stream, session);
- ssize_t index = mOutputs.indexOfKey(output);
- if (index < 0) {
- LOGW("startOutput() unknow output %d", output);
- return BAD_VALUE;
- }
-
- AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
- routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream);
-
-#ifdef WITH_A2DP
- if (mA2dpOutput != 0 && !a2dpUsedForSonification() && strategy == STRATEGY_SONIFICATION) {
- setStrategyMute(STRATEGY_MEDIA, true, mA2dpOutput);
- }
-#endif
-
- // incremenent usage count for this stream on the requested output:
- // NOTE that the usage count is the same for duplicated output and hardware output which is
- // necassary for a correct control of hardware output routing by startOutput() and stopOutput()
- outputDesc->changeRefCount(stream, 1);
-
- setOutputDevice(output, getNewDevice(output));
-
- // handle special case for sonification while in call
- if (isInCall()) {
- handleIncallSonification(stream, true, false);
- }
-
- // apply volume rules for current stream and device if necessary
- checkAndSetVolume(stream, mStreams[stream].mIndexCur, output, outputDesc->device());
-
- return NO_ERROR;
-}
-
-status_t AudioPolicyManagerBase::stopOutput(audio_io_handle_t output,
- AudioSystem::stream_type stream,
- int session)
-{
- LOGV("stopOutput() output %d, stream %d, session %d", output, stream, session);
- ssize_t index = mOutputs.indexOfKey(output);
- if (index < 0) {
- LOGW("stopOutput() unknow output %d", output);
- return BAD_VALUE;
- }
-
- AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
- routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream);
-
- // handle special case for sonification while in call
- if (isInCall()) {
- handleIncallSonification(stream, false, false);
- }
-
- if (outputDesc->mRefCount[stream] > 0) {
- // decrement usage count of this stream on the output
- outputDesc->changeRefCount(stream, -1);
- // store time at which the stream was stopped - see isStreamActive()
- outputDesc->mStopTime[stream] = systemTime();
-
- setOutputDevice(output, getNewDevice(output), false, outputDesc->mLatency*2);
-
-#ifdef WITH_A2DP
- if (mA2dpOutput != 0 && !a2dpUsedForSonification() &&
- strategy == STRATEGY_SONIFICATION) {
- setStrategyMute(STRATEGY_MEDIA,
- false,
- mA2dpOutput,
- mOutputs.valueFor(mHardwareOutput)->mLatency*2);
- }
-#endif
- if (output != mHardwareOutput) {
- setOutputDevice(mHardwareOutput, getNewDevice(mHardwareOutput), true);
- }
- return NO_ERROR;
- } else {
- LOGW("stopOutput() refcount is already 0 for output %d", output);
- return INVALID_OPERATION;
- }
-}
-
-void AudioPolicyManagerBase::releaseOutput(audio_io_handle_t output)
-{
- LOGV("releaseOutput() %d", output);
- ssize_t index = mOutputs.indexOfKey(output);
- if (index < 0) {
- LOGW("releaseOutput() releasing unknown output %d", output);
- return;
- }
-
-#ifdef AUDIO_POLICY_TEST
- int testIndex = testOutputIndex(output);
- if (testIndex != 0) {
- AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
- if (outputDesc->refCount() == 0) {
- mpClientInterface->closeOutput(output);
- delete mOutputs.valueAt(index);
- mOutputs.removeItem(output);
- mTestOutputs[testIndex] = 0;
- }
- return;
- }
-#endif //AUDIO_POLICY_TEST
-
- if (mOutputs.valueAt(index)->mFlags & AudioSystem::OUTPUT_FLAG_DIRECT) {
- mpClientInterface->closeOutput(output);
- delete mOutputs.valueAt(index);
- mOutputs.removeItem(output);
- }
-}
-
-audio_io_handle_t AudioPolicyManagerBase::getInput(int inputSource,
- uint32_t samplingRate,
- uint32_t format,
- uint32_t channels,
- AudioSystem::audio_in_acoustics acoustics)
-{
- audio_io_handle_t input = 0;
- uint32_t device = getDeviceForInputSource(inputSource);
-
- LOGV("getInput() inputSource %d, samplingRate %d, format %d, channels %x, acoustics %x", inputSource, samplingRate, format, channels, acoustics);
-
- if (device == 0) {
- return 0;
- }
-
- // adapt channel selection to input source
- switch(inputSource) {
- case AUDIO_SOURCE_VOICE_UPLINK:
- channels = AudioSystem::CHANNEL_IN_VOICE_UPLINK;
- break;
- case AUDIO_SOURCE_VOICE_DOWNLINK:
- channels = AudioSystem::CHANNEL_IN_VOICE_DNLINK;
- break;
- case AUDIO_SOURCE_VOICE_CALL:
- channels = (AudioSystem::CHANNEL_IN_VOICE_UPLINK | AudioSystem::CHANNEL_IN_VOICE_DNLINK);
- break;
- default:
- break;
- }
-
- AudioInputDescriptor *inputDesc = new AudioInputDescriptor();
-
- inputDesc->mInputSource = inputSource;
- inputDesc->mDevice = device;
- inputDesc->mSamplingRate = samplingRate;
- inputDesc->mFormat = format;
- inputDesc->mChannels = channels;
- inputDesc->mAcoustics = acoustics;
- inputDesc->mRefCount = 0;
- input = mpClientInterface->openInput(&inputDesc->mDevice,
- &inputDesc->mSamplingRate,
- &inputDesc->mFormat,
- &inputDesc->mChannels,
- inputDesc->mAcoustics);
-
- // only accept input with the exact requested set of parameters
- if (input == 0 ||
- (samplingRate != inputDesc->mSamplingRate) ||
- (format != inputDesc->mFormat) ||
- (channels != inputDesc->mChannels)) {
- LOGV("getInput() failed opening input: samplingRate %d, format %d, channels %d",
- samplingRate, format, channels);
- if (input != 0) {
- mpClientInterface->closeInput(input);
- }
- delete inputDesc;
- return 0;
- }
- mInputs.add(input, inputDesc);
- return input;
-}
-
-status_t AudioPolicyManagerBase::startInput(audio_io_handle_t input)
-{
- LOGV("startInput() input %d", input);
- ssize_t index = mInputs.indexOfKey(input);
- if (index < 0) {
- LOGW("startInput() unknow input %d", input);
- return BAD_VALUE;
- }
- AudioInputDescriptor *inputDesc = mInputs.valueAt(index);
-
-#ifdef AUDIO_POLICY_TEST
- if (mTestInput == 0)
-#endif //AUDIO_POLICY_TEST
- {
- // refuse 2 active AudioRecord clients at the same time
- if (getActiveInput() != 0) {
- LOGW("startInput() input %d failed: other input already started", input);
- return INVALID_OPERATION;
- }
- }
-
- AudioParameter param = AudioParameter();
- param.addInt(String8(AudioParameter::keyRouting), (int)inputDesc->mDevice);
-
- param.addInt(String8(AudioParameter::keyInputSource), (int)inputDesc->mInputSource);
- LOGV("AudioPolicyManager::startInput() input source = %d", inputDesc->mInputSource);
-
- mpClientInterface->setParameters(input, param.toString());
-
- inputDesc->mRefCount = 1;
- return NO_ERROR;
-}
-
-status_t AudioPolicyManagerBase::stopInput(audio_io_handle_t input)
-{
- LOGV("stopInput() input %d", input);
- ssize_t index = mInputs.indexOfKey(input);
- if (index < 0) {
- LOGW("stopInput() unknow input %d", input);
- return BAD_VALUE;
- }
- AudioInputDescriptor *inputDesc = mInputs.valueAt(index);
-
- if (inputDesc->mRefCount == 0) {
- LOGW("stopInput() input %d already stopped", input);
- return INVALID_OPERATION;
- } else {
- AudioParameter param = AudioParameter();
- param.addInt(String8(AudioParameter::keyRouting), 0);
- mpClientInterface->setParameters(input, param.toString());
- inputDesc->mRefCount = 0;
- return NO_ERROR;
- }
-}
-
-void AudioPolicyManagerBase::releaseInput(audio_io_handle_t input)
-{
- LOGV("releaseInput() %d", input);
- ssize_t index = mInputs.indexOfKey(input);
- if (index < 0) {
- LOGW("releaseInput() releasing unknown input %d", input);
- return;
- }
- mpClientInterface->closeInput(input);
- delete mInputs.valueAt(index);
- mInputs.removeItem(input);
- LOGV("releaseInput() exit");
-}
-
-void AudioPolicyManagerBase::initStreamVolume(AudioSystem::stream_type stream,
- int indexMin,
- int indexMax)
-{
- LOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax);
- if (indexMin < 0 || indexMin >= indexMax) {
- LOGW("initStreamVolume() invalid index limits for stream %d, min %d, max %d", stream , indexMin, indexMax);
- return;
- }
- mStreams[stream].mIndexMin = indexMin;
- mStreams[stream].mIndexMax = indexMax;
-}
-
-status_t AudioPolicyManagerBase::setStreamVolumeIndex(AudioSystem::stream_type stream, int index)
-{
-
- if ((index < mStreams[stream].mIndexMin) || (index > mStreams[stream].mIndexMax)) {
- return BAD_VALUE;
- }
-
- // Force max volume if stream cannot be muted
- if (!mStreams[stream].mCanBeMuted) index = mStreams[stream].mIndexMax;
-
- LOGV("setStreamVolumeIndex() stream %d, index %d", stream, index);
- mStreams[stream].mIndexCur = index;
-
- // compute and apply stream volume on all outputs according to connected device
- status_t status = NO_ERROR;
- for (size_t i = 0; i < mOutputs.size(); i++) {
- status_t volStatus = checkAndSetVolume(stream, index, mOutputs.keyAt(i), mOutputs.valueAt(i)->device());
- if (volStatus != NO_ERROR) {
- status = volStatus;
- }
- }
- return status;
-}
-
-status_t AudioPolicyManagerBase::getStreamVolumeIndex(AudioSystem::stream_type stream, int *index)
-{
- if (index == 0) {
- return BAD_VALUE;
- }
- LOGV("getStreamVolumeIndex() stream %d", stream);
- *index = mStreams[stream].mIndexCur;
- return NO_ERROR;
-}
-
-audio_io_handle_t AudioPolicyManagerBase::getOutputForEffect(effect_descriptor_t *desc)
-{
- LOGV("getOutputForEffect()");
- // apply simple rule where global effects are attached to the same output as MUSIC streams
- return getOutput(AudioSystem::MUSIC);
-}
-
-status_t AudioPolicyManagerBase::registerEffect(effect_descriptor_t *desc,
- audio_io_handle_t output,
- uint32_t strategy,
- int session,
- int id)
-{
- ssize_t index = mOutputs.indexOfKey(output);
- if (index < 0) {
- LOGW("registerEffect() unknown output %d", output);
- return INVALID_OPERATION;
- }
-
- if (mTotalEffectsCpuLoad + desc->cpuLoad > getMaxEffectsCpuLoad()) {
- LOGW("registerEffect() CPU Load limit exceeded for Fx %s, CPU %f MIPS",
- desc->name, (float)desc->cpuLoad/10);
- return INVALID_OPERATION;
- }
- if (mTotalEffectsMemory + desc->memoryUsage > getMaxEffectsMemory()) {
- LOGW("registerEffect() memory limit exceeded for Fx %s, Memory %d KB",
- desc->name, desc->memoryUsage);
- return INVALID_OPERATION;
- }
- mTotalEffectsCpuLoad += desc->cpuLoad;
- mTotalEffectsMemory += desc->memoryUsage;
- LOGV("registerEffect() effect %s, output %d, strategy %d session %d id %d",
- desc->name, output, strategy, session, id);
-
- LOGV("registerEffect() CPU %d, memory %d", desc->cpuLoad, desc->memoryUsage);
- LOGV(" total CPU %d, total memory %d", mTotalEffectsCpuLoad, mTotalEffectsMemory);
-
- EffectDescriptor *pDesc = new EffectDescriptor();
- memcpy (&pDesc->mDesc, desc, sizeof(effect_descriptor_t));
- pDesc->mOutput = output;
- pDesc->mStrategy = (routing_strategy)strategy;
- pDesc->mSession = session;
- mEffects.add(id, pDesc);
-
- return NO_ERROR;
-}
-
-status_t AudioPolicyManagerBase::unregisterEffect(int id)
-{
- ssize_t index = mEffects.indexOfKey(id);
- if (index < 0) {
- LOGW("unregisterEffect() unknown effect ID %d", id);
- return INVALID_OPERATION;
- }
-
- EffectDescriptor *pDesc = mEffects.valueAt(index);
-
- if (mTotalEffectsCpuLoad < pDesc->mDesc.cpuLoad) {
- LOGW("unregisterEffect() CPU load %d too high for total %d",
- pDesc->mDesc.cpuLoad, mTotalEffectsCpuLoad);
- pDesc->mDesc.cpuLoad = mTotalEffectsCpuLoad;
- }
- mTotalEffectsCpuLoad -= pDesc->mDesc.cpuLoad;
- if (mTotalEffectsMemory < pDesc->mDesc.memoryUsage) {
- LOGW("unregisterEffect() memory %d too big for total %d",
- pDesc->mDesc.memoryUsage, mTotalEffectsMemory);
- pDesc->mDesc.memoryUsage = mTotalEffectsMemory;
- }
- mTotalEffectsMemory -= pDesc->mDesc.memoryUsage;
- LOGV("unregisterEffect() effect %s, ID %d, CPU %d, memory %d",
- pDesc->mDesc.name, id, pDesc->mDesc.cpuLoad, pDesc->mDesc.memoryUsage);
- LOGV(" total CPU %d, total memory %d", mTotalEffectsCpuLoad, mTotalEffectsMemory);
-
- mEffects.removeItem(id);
- delete pDesc;
-
- return NO_ERROR;
-}
-
-bool AudioPolicyManagerBase::isStreamActive(int stream, uint32_t inPastMs) const
-{
- nsecs_t sysTime = systemTime();
- for (size_t i = 0; i < mOutputs.size(); i++) {
- if (mOutputs.valueAt(i)->mRefCount[stream] != 0 ||
- ns2ms(sysTime - mOutputs.valueAt(i)->mStopTime[stream]) < inPastMs) {
- return true;
- }
- }
- return false;
-}
-
-
-status_t AudioPolicyManagerBase::dump(int fd)
-{
- const size_t SIZE = 256;
- char buffer[SIZE];
- String8 result;
-
- snprintf(buffer, SIZE, "\nAudioPolicyManager Dump: %p\n", this);
- result.append(buffer);
- snprintf(buffer, SIZE, " Hardware Output: %d\n", mHardwareOutput);
- result.append(buffer);
-#ifdef WITH_A2DP
- snprintf(buffer, SIZE, " A2DP Output: %d\n", mA2dpOutput);
- result.append(buffer);
- snprintf(buffer, SIZE, " Duplicated Output: %d\n", mDuplicatedOutput);
- result.append(buffer);
- snprintf(buffer, SIZE, " A2DP device address: %s\n", mA2dpDeviceAddress.string());
- result.append(buffer);
-#endif
- snprintf(buffer, SIZE, " SCO device address: %s\n", mScoDeviceAddress.string());
- result.append(buffer);
- snprintf(buffer, SIZE, " Output devices: %08x\n", mAvailableOutputDevices);
- result.append(buffer);
- snprintf(buffer, SIZE, " Input devices: %08x\n", mAvailableInputDevices);
- result.append(buffer);
- snprintf(buffer, SIZE, " Phone state: %d\n", mPhoneState);
- result.append(buffer);
- snprintf(buffer, SIZE, " Ringer mode: %d\n", mRingerMode);
- result.append(buffer);
- snprintf(buffer, SIZE, " Force use for communications %d\n", mForceUse[AudioSystem::FOR_COMMUNICATION]);
- result.append(buffer);
- snprintf(buffer, SIZE, " Force use for media %d\n", mForceUse[AudioSystem::FOR_MEDIA]);
- result.append(buffer);
- snprintf(buffer, SIZE, " Force use for record %d\n", mForceUse[AudioSystem::FOR_RECORD]);
- result.append(buffer);
- snprintf(buffer, SIZE, " Force use for dock %d\n", mForceUse[AudioSystem::FOR_DOCK]);
- result.append(buffer);
- write(fd, result.string(), result.size());
-
- snprintf(buffer, SIZE, "\nOutputs dump:\n");
- write(fd, buffer, strlen(buffer));
- for (size_t i = 0; i < mOutputs.size(); i++) {
- snprintf(buffer, SIZE, "- Output %d dump:\n", mOutputs.keyAt(i));
- write(fd, buffer, strlen(buffer));
- mOutputs.valueAt(i)->dump(fd);
- }
-
- snprintf(buffer, SIZE, "\nInputs dump:\n");
- write(fd, buffer, strlen(buffer));
- for (size_t i = 0; i < mInputs.size(); i++) {
- snprintf(buffer, SIZE, "- Input %d dump:\n", mInputs.keyAt(i));
- write(fd, buffer, strlen(buffer));
- mInputs.valueAt(i)->dump(fd);
- }
-
- snprintf(buffer, SIZE, "\nStreams dump:\n");
- write(fd, buffer, strlen(buffer));
- snprintf(buffer, SIZE, " Stream Index Min Index Max Index Cur Can be muted\n");
- write(fd, buffer, strlen(buffer));
- for (size_t i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) {
- snprintf(buffer, SIZE, " %02d", i);
- mStreams[i].dump(buffer + 3, SIZE);
- write(fd, buffer, strlen(buffer));
- }
-
- snprintf(buffer, SIZE, "\nTotal Effects CPU: %f MIPS, Total Effects memory: %d KB\n",
- (float)mTotalEffectsCpuLoad/10, mTotalEffectsMemory);
- write(fd, buffer, strlen(buffer));
-
- snprintf(buffer, SIZE, "Registered effects:\n");
- write(fd, buffer, strlen(buffer));
- for (size_t i = 0; i < mEffects.size(); i++) {
- snprintf(buffer, SIZE, "- Effect %d dump:\n", mEffects.keyAt(i));
- write(fd, buffer, strlen(buffer));
- mEffects.valueAt(i)->dump(fd);
- }
-
-
- return NO_ERROR;
-}
-
-// ----------------------------------------------------------------------------
-// AudioPolicyManagerBase
-// ----------------------------------------------------------------------------
-
-AudioPolicyManagerBase::AudioPolicyManagerBase(AudioPolicyClientInterface *clientInterface)
- :
-#ifdef AUDIO_POLICY_TEST
- Thread(false),
-#endif //AUDIO_POLICY_TEST
- mPhoneState(AudioSystem::MODE_NORMAL), mRingerMode(0),
- mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
- mTotalEffectsCpuLoad(0), mTotalEffectsMemory(0),
- mA2dpSuspended(false)
-{
- mpClientInterface = clientInterface;
-
- for (int i = 0; i < AudioSystem::NUM_FORCE_USE; i++) {
- mForceUse[i] = AudioSystem::FORCE_NONE;
- }
-
- initializeVolumeCurves();
-
- // devices available by default are speaker, ear piece and microphone
- mAvailableOutputDevices = AudioSystem::DEVICE_OUT_EARPIECE |
- AudioSystem::DEVICE_OUT_SPEAKER;
- mAvailableInputDevices = AudioSystem::DEVICE_IN_BUILTIN_MIC;
-
-#ifdef WITH_A2DP
- mA2dpOutput = 0;
- mDuplicatedOutput = 0;
- mA2dpDeviceAddress = String8("");
-#endif
- mScoDeviceAddress = String8("");
-
- // open hardware output
- AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor();
- outputDesc->mDevice = (uint32_t)AudioSystem::DEVICE_OUT_SPEAKER;
- mHardwareOutput = mpClientInterface->openOutput(&outputDesc->mDevice,
- &outputDesc->mSamplingRate,
- &outputDesc->mFormat,
- &outputDesc->mChannels,
- &outputDesc->mLatency,
- outputDesc->mFlags);
-
- if (mHardwareOutput == 0) {
- LOGE("Failed to initialize hardware output stream, samplingRate: %d, format %d, channels %d",
- outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannels);
- } else {
- addOutput(mHardwareOutput, outputDesc);
- setOutputDevice(mHardwareOutput, (uint32_t)AudioSystem::DEVICE_OUT_SPEAKER, true);
- //TODO: configure audio effect output stage here
- }
-
- updateDeviceForStrategy();
-#ifdef AUDIO_POLICY_TEST
- if (mHardwareOutput != 0) {
- AudioParameter outputCmd = AudioParameter();
- outputCmd.addInt(String8("set_id"), 0);
- mpClientInterface->setParameters(mHardwareOutput, outputCmd.toString());
-
- mTestDevice = AudioSystem::DEVICE_OUT_SPEAKER;
- mTestSamplingRate = 44100;
- mTestFormat = AudioSystem::PCM_16_BIT;
- mTestChannels = AudioSystem::CHANNEL_OUT_STEREO;
- mTestLatencyMs = 0;
- mCurOutput = 0;
- mDirectOutput = false;
- for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {
- mTestOutputs[i] = 0;
- }
-
- const size_t SIZE = 256;
- char buffer[SIZE];
- snprintf(buffer, SIZE, "AudioPolicyManagerTest");
- run(buffer, ANDROID_PRIORITY_AUDIO);
- }
-#endif //AUDIO_POLICY_TEST
-}
-
-AudioPolicyManagerBase::~AudioPolicyManagerBase()
-{
-#ifdef AUDIO_POLICY_TEST
- exit();
-#endif //AUDIO_POLICY_TEST
- for (size_t i = 0; i < mOutputs.size(); i++) {
- mpClientInterface->closeOutput(mOutputs.keyAt(i));
- delete mOutputs.valueAt(i);
- }
- mOutputs.clear();
- for (size_t i = 0; i < mInputs.size(); i++) {
- mpClientInterface->closeInput(mInputs.keyAt(i));
- delete mInputs.valueAt(i);
- }
- mInputs.clear();
-}
-
-status_t AudioPolicyManagerBase::initCheck()
-{
- return (mHardwareOutput == 0) ? NO_INIT : NO_ERROR;
-}
-
-#ifdef AUDIO_POLICY_TEST
-bool AudioPolicyManagerBase::threadLoop()
-{
- LOGV("entering threadLoop()");
- while (!exitPending())
- {
- String8 command;
- int valueInt;
- String8 value;
-
- Mutex::Autolock _l(mLock);
- mWaitWorkCV.waitRelative(mLock, milliseconds(50));
-
- command = mpClientInterface->getParameters(0, String8("test_cmd_policy"));
- AudioParameter param = AudioParameter(command);
-
- if (param.getInt(String8("test_cmd_policy"), valueInt) == NO_ERROR &&
- valueInt != 0) {
- LOGV("Test command %s received", command.string());
- String8 target;
- if (param.get(String8("target"), target) != NO_ERROR) {
- target = "Manager";
- }
- if (param.getInt(String8("test_cmd_policy_output"), valueInt) == NO_ERROR) {
- param.remove(String8("test_cmd_policy_output"));
- mCurOutput = valueInt;
- }
- if (param.get(String8("test_cmd_policy_direct"), value) == NO_ERROR) {
- param.remove(String8("test_cmd_policy_direct"));
- if (value == "false") {
- mDirectOutput = false;
- } else if (value == "true") {
- mDirectOutput = true;
- }
- }
- if (param.getInt(String8("test_cmd_policy_input"), valueInt) == NO_ERROR) {
- param.remove(String8("test_cmd_policy_input"));
- mTestInput = valueInt;
- }
-
- if (param.get(String8("test_cmd_policy_format"), value) == NO_ERROR) {
- param.remove(String8("test_cmd_policy_format"));
- int format = AudioSystem::INVALID_FORMAT;
- if (value == "PCM 16 bits") {
- format = AudioSystem::PCM_16_BIT;
- } else if (value == "PCM 8 bits") {
- format = AudioSystem::PCM_8_BIT;
- } else if (value == "Compressed MP3") {
- format = AudioSystem::MP3;
- }
- if (format != AudioSystem::INVALID_FORMAT) {
- if (target == "Manager") {
- mTestFormat = format;
- } else if (mTestOutputs[mCurOutput] != 0) {
- AudioParameter outputParam = AudioParameter();
- outputParam.addInt(String8("format"), format);
- mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
- }
- }
- }
- if (param.get(String8("test_cmd_policy_channels"), value) == NO_ERROR) {
- param.remove(String8("test_cmd_policy_channels"));
- int channels = 0;
-
- if (value == "Channels Stereo") {
- channels = AudioSystem::CHANNEL_OUT_STEREO;
- } else if (value == "Channels Mono") {
- channels = AudioSystem::CHANNEL_OUT_MONO;
- }
- if (channels != 0) {
- if (target == "Manager") {
- mTestChannels = channels;
- } else if (mTestOutputs[mCurOutput] != 0) {
- AudioParameter outputParam = AudioParameter();
- outputParam.addInt(String8("channels"), channels);
- mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
- }
- }
- }
- if (param.getInt(String8("test_cmd_policy_sampleRate"), valueInt) == NO_ERROR) {
- param.remove(String8("test_cmd_policy_sampleRate"));
- if (valueInt >= 0 && valueInt <= 96000) {
- int samplingRate = valueInt;
- if (target == "Manager") {
- mTestSamplingRate = samplingRate;
- } else if (mTestOutputs[mCurOutput] != 0) {
- AudioParameter outputParam = AudioParameter();
- outputParam.addInt(String8("sampling_rate"), samplingRate);
- mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
- }
- }
- }
-
- if (param.get(String8("test_cmd_policy_reopen"), value) == NO_ERROR) {
- param.remove(String8("test_cmd_policy_reopen"));
-
- mpClientInterface->closeOutput(mHardwareOutput);
- delete mOutputs.valueFor(mHardwareOutput);
- mOutputs.removeItem(mHardwareOutput);
-
- AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor();
- outputDesc->mDevice = (uint32_t)AudioSystem::DEVICE_OUT_SPEAKER;
- mHardwareOutput = mpClientInterface->openOutput(&outputDesc->mDevice,
- &outputDesc->mSamplingRate,
- &outputDesc->mFormat,
- &outputDesc->mChannels,
- &outputDesc->mLatency,
- outputDesc->mFlags);
- if (mHardwareOutput == 0) {
- LOGE("Failed to reopen hardware output stream, samplingRate: %d, format %d, channels %d",
- outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannels);
- } else {
- AudioParameter outputCmd = AudioParameter();
- outputCmd.addInt(String8("set_id"), 0);
- mpClientInterface->setParameters(mHardwareOutput, outputCmd.toString());
- addOutput(mHardwareOutput, outputDesc);
- }
- }
-
-
- mpClientInterface->setParameters(0, String8("test_cmd_policy="));
- }
- }
- return false;
-}
-
-void AudioPolicyManagerBase::exit()
-{
- {
- AutoMutex _l(mLock);
- requestExit();
- mWaitWorkCV.signal();
- }
- requestExitAndWait();
-}
-
-int AudioPolicyManagerBase::testOutputIndex(audio_io_handle_t output)
-{
- for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {
- if (output == mTestOutputs[i]) return i;
- }
- return 0;
-}
-#endif //AUDIO_POLICY_TEST
-
-// ---
-
-void AudioPolicyManagerBase::addOutput(audio_io_handle_t id, AudioOutputDescriptor *outputDesc)
-{
- outputDesc->mId = id;
- mOutputs.add(id, outputDesc);
-}
-
-
-#ifdef WITH_A2DP
-status_t AudioPolicyManagerBase::handleA2dpConnection(AudioSystem::audio_devices device,
- const char *device_address)
-{
- // when an A2DP device is connected, open an A2DP and a duplicated output
- LOGV("opening A2DP output for device %s", device_address);
- AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor();
- outputDesc->mDevice = device;
- mA2dpOutput = mpClientInterface->openOutput(&outputDesc->mDevice,
- &outputDesc->mSamplingRate,
- &outputDesc->mFormat,
- &outputDesc->mChannels,
- &outputDesc->mLatency,
- outputDesc->mFlags);
- if (mA2dpOutput) {
- // add A2DP output descriptor
- addOutput(mA2dpOutput, outputDesc);
-
- //TODO: configure audio effect output stage here
-
- // set initial stream volume for A2DP device
- applyStreamVolumes(mA2dpOutput, device);
- if (a2dpUsedForSonification()) {
- mDuplicatedOutput = mpClientInterface->openDuplicateOutput(mA2dpOutput, mHardwareOutput);
- }
- if (mDuplicatedOutput != 0 ||
- !a2dpUsedForSonification()) {
- // If both A2DP and duplicated outputs are open, send device address to A2DP hardware
- // interface
- AudioParameter param;
- param.add(String8("a2dp_sink_address"), String8(device_address));
- mpClientInterface->setParameters(mA2dpOutput, param.toString());
- mA2dpDeviceAddress = String8(device_address, MAX_DEVICE_ADDRESS_LEN);
-
- if (a2dpUsedForSonification()) {
- // add duplicated output descriptor
- AudioOutputDescriptor *dupOutputDesc = new AudioOutputDescriptor();
- dupOutputDesc->mOutput1 = mOutputs.valueFor(mHardwareOutput);
- dupOutputDesc->mOutput2 = mOutputs.valueFor(mA2dpOutput);
- dupOutputDesc->mSamplingRate = outputDesc->mSamplingRate;
- dupOutputDesc->mFormat = outputDesc->mFormat;
- dupOutputDesc->mChannels = outputDesc->mChannels;
- dupOutputDesc->mLatency = outputDesc->mLatency;
- addOutput(mDuplicatedOutput, dupOutputDesc);
- applyStreamVolumes(mDuplicatedOutput, device);
- }
- } else {
- LOGW("getOutput() could not open duplicated output for %d and %d",
- mHardwareOutput, mA2dpOutput);
- mpClientInterface->closeOutput(mA2dpOutput);
- mOutputs.removeItem(mA2dpOutput);
- mA2dpOutput = 0;
- delete outputDesc;
- return NO_INIT;
- }
- } else {
- LOGW("setDeviceConnectionState() could not open A2DP output for device %x", device);
- delete outputDesc;
- return NO_INIT;
- }
- AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mHardwareOutput);
-
- if (!a2dpUsedForSonification()) {
- // mute music on A2DP output if a notification or ringtone is playing
- uint32_t refCount = hwOutputDesc->strategyRefCount(STRATEGY_SONIFICATION);
- for (uint32_t i = 0; i < refCount; i++) {
- setStrategyMute(STRATEGY_MEDIA, true, mA2dpOutput);
- }
- }
-
- mA2dpSuspended = false;
-
- return NO_ERROR;
-}
-
-status_t AudioPolicyManagerBase::handleA2dpDisconnection(AudioSystem::audio_devices device,
- const char *device_address)
-{
- if (mA2dpOutput == 0) {
- LOGW("setDeviceConnectionState() disconnecting A2DP and no A2DP output!");
- return INVALID_OPERATION;
- }
-
- if (mA2dpDeviceAddress != device_address) {
- LOGW("setDeviceConnectionState() disconnecting unknow A2DP sink address %s", device_address);
- return INVALID_OPERATION;
- }
-
- // mute media strategy to avoid outputting sound on hardware output while music stream
- // is switched from A2DP output and before music is paused by music application
- setStrategyMute(STRATEGY_MEDIA, true, mHardwareOutput);
- setStrategyMute(STRATEGY_MEDIA, false, mHardwareOutput, MUTE_TIME_MS);
-
- if (!a2dpUsedForSonification()) {
- // unmute music on A2DP output if a notification or ringtone is playing
- uint32_t refCount = mOutputs.valueFor(mHardwareOutput)->strategyRefCount(STRATEGY_SONIFICATION);
- for (uint32_t i = 0; i < refCount; i++) {
- setStrategyMute(STRATEGY_MEDIA, false, mA2dpOutput);
- }
- }
- mA2dpDeviceAddress = "";
- mA2dpSuspended = false;
- return NO_ERROR;
-}
-
-void AudioPolicyManagerBase::closeA2dpOutputs()
-{
-
- LOGV("setDeviceConnectionState() closing A2DP and duplicated output!");
-
- if (mDuplicatedOutput != 0) {
- AudioOutputDescriptor *dupOutputDesc = mOutputs.valueFor(mDuplicatedOutput);
- AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mHardwareOutput);
- // As all active tracks on duplicated output will be deleted,
- // and as they were also referenced on hardware output, the reference
- // count for their stream type must be adjusted accordingly on
- // hardware output.
- for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
- int refCount = dupOutputDesc->mRefCount[i];
- hwOutputDesc->changeRefCount((AudioSystem::stream_type)i,-refCount);
- }
-
- mpClientInterface->closeOutput(mDuplicatedOutput);
- delete mOutputs.valueFor(mDuplicatedOutput);
- mOutputs.removeItem(mDuplicatedOutput);
- mDuplicatedOutput = 0;
- }
- if (mA2dpOutput != 0) {
- AudioParameter param;
- param.add(String8("closing"), String8("true"));
- mpClientInterface->setParameters(mA2dpOutput, param.toString());
-
- mpClientInterface->closeOutput(mA2dpOutput);
- delete mOutputs.valueFor(mA2dpOutput);
- mOutputs.removeItem(mA2dpOutput);
- mA2dpOutput = 0;
- }
-}
-
-void AudioPolicyManagerBase::checkOutputForStrategy(routing_strategy strategy)
-{
- uint32_t prevDevice = getDeviceForStrategy(strategy);
- uint32_t curDevice = getDeviceForStrategy(strategy, false);
- bool a2dpWasUsed = AudioSystem::isA2dpDevice((AudioSystem::audio_devices)(prevDevice & ~AudioSystem::DEVICE_OUT_SPEAKER));
- bool a2dpIsUsed = AudioSystem::isA2dpDevice((AudioSystem::audio_devices)(curDevice & ~AudioSystem::DEVICE_OUT_SPEAKER));
- audio_io_handle_t srcOutput = 0;
- audio_io_handle_t dstOutput = 0;
-
- if (a2dpWasUsed && !a2dpIsUsed) {
- bool dupUsed = a2dpUsedForSonification() && a2dpWasUsed && (AudioSystem::popCount(prevDevice) == 2);
- dstOutput = mHardwareOutput;
- if (dupUsed) {
- LOGV("checkOutputForStrategy() moving strategy %d from duplicated", strategy);
- srcOutput = mDuplicatedOutput;
- } else {
- LOGV("checkOutputForStrategy() moving strategy %d from a2dp", strategy);
- srcOutput = mA2dpOutput;
- }
- }
- if (a2dpIsUsed && !a2dpWasUsed) {
- bool dupUsed = a2dpUsedForSonification() && a2dpIsUsed && (AudioSystem::popCount(curDevice) == 2);
- srcOutput = mHardwareOutput;
- if (dupUsed) {
- LOGV("checkOutputForStrategy() moving strategy %d to duplicated", strategy);
- dstOutput = mDuplicatedOutput;
- } else {
- LOGV("checkOutputForStrategy() moving strategy %d to a2dp", strategy);
- dstOutput = mA2dpOutput;
- }
- }
-
- if (srcOutput != 0 && dstOutput != 0) {
- // Move effects associated to this strategy from previous output to new output
- for (size_t i = 0; i < mEffects.size(); i++) {
- EffectDescriptor *desc = mEffects.valueAt(i);
- if (desc->mSession != AudioSystem::SESSION_OUTPUT_STAGE &&
- desc->mStrategy == strategy &&
- desc->mOutput == srcOutput) {
- LOGV("checkOutputForStrategy() moving effect %d to output %d", mEffects.keyAt(i), dstOutput);
- mpClientInterface->moveEffects(desc->mSession, srcOutput, dstOutput);
- desc->mOutput = dstOutput;
- }
- }
- // Move tracks associated to this strategy from previous output to new output
- for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
- if (getStrategy((AudioSystem::stream_type)i) == strategy) {
- mpClientInterface->setStreamOutput((AudioSystem::stream_type)i, dstOutput);
- }
- }
- }
-}
-
-void AudioPolicyManagerBase::checkOutputForAllStrategies()
-{
- checkOutputForStrategy(STRATEGY_PHONE);
- checkOutputForStrategy(STRATEGY_SONIFICATION);
- checkOutputForStrategy(STRATEGY_MEDIA);
- checkOutputForStrategy(STRATEGY_DTMF);
-}
-
-void AudioPolicyManagerBase::checkA2dpSuspend()
-{
- // suspend A2DP output if:
- // (NOT already suspended) &&
- // ((SCO device is connected &&
- // (forced usage for communication || for record is SCO))) ||
- // (phone state is ringing || in call)
- //
- // restore A2DP output if:
- // (Already suspended) &&
- // ((SCO device is NOT connected ||
- // (forced usage NOT for communication && NOT for record is SCO))) &&
- // (phone state is NOT ringing && NOT in call)
- //
- if (mA2dpOutput == 0) {
- return;
- }
-
- if (mA2dpSuspended) {
- if (((mScoDeviceAddress == "") ||
- ((mForceUse[AudioSystem::FOR_COMMUNICATION] != AudioSystem::FORCE_BT_SCO) &&
- (mForceUse[AudioSystem::FOR_RECORD] != AudioSystem::FORCE_BT_SCO))) &&
- ((mPhoneState != AudioSystem::MODE_IN_CALL) &&
- (mPhoneState != AudioSystem::MODE_RINGTONE))) {
-
- mpClientInterface->restoreOutput(mA2dpOutput);
- mA2dpSuspended = false;
- }
- } else {
- if (((mScoDeviceAddress != "") &&
- ((mForceUse[AudioSystem::FOR_COMMUNICATION] == AudioSystem::FORCE_BT_SCO) ||
- (mForceUse[AudioSystem::FOR_RECORD] == AudioSystem::FORCE_BT_SCO))) ||
- ((mPhoneState == AudioSystem::MODE_IN_CALL) ||
- (mPhoneState == AudioSystem::MODE_RINGTONE))) {
-
- mpClientInterface->suspendOutput(mA2dpOutput);
- mA2dpSuspended = true;
- }
- }
-}
-
-
-#endif
-
-uint32_t AudioPolicyManagerBase::getNewDevice(audio_io_handle_t output, bool fromCache)
-{
- uint32_t device = 0;
-
- AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
- // check the following by order of priority to request a routing change if necessary:
- // 1: we are in call or the strategy phone is active on the hardware output:
- // use device for strategy phone
- // 2: the strategy sonification is active on the hardware output:
- // use device for strategy sonification
- // 3: the strategy media is active on the hardware output:
- // use device for strategy media
- // 4: the strategy DTMF is active on the hardware output:
- // use device for strategy DTMF
- if (isInCall() ||
- outputDesc->isUsedByStrategy(STRATEGY_PHONE)) {
- device = getDeviceForStrategy(STRATEGY_PHONE, fromCache);
- } else if (outputDesc->isUsedByStrategy(STRATEGY_SONIFICATION)) {
- device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache);
- } else if (outputDesc->isUsedByStrategy(STRATEGY_MEDIA)) {
- device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache);
- } else if (outputDesc->isUsedByStrategy(STRATEGY_DTMF)) {
- device = getDeviceForStrategy(STRATEGY_DTMF, fromCache);
- }
-
- LOGV("getNewDevice() selected device %x", device);
- return device;
-}
-
-uint32_t AudioPolicyManagerBase::getStrategyForStream(AudioSystem::stream_type stream) {
- return (uint32_t)getStrategy(stream);
-}
-
-uint32_t AudioPolicyManagerBase::getDevicesForStream(AudioSystem::stream_type stream) {
- uint32_t devices;
- // By checking the range of stream before calling getStrategy, we avoid
- // getStrategy's behavior for invalid streams. getStrategy would do a LOGE
- // and then return STRATEGY_MEDIA, but we want to return the empty set.
- if (stream < (AudioSystem::stream_type) 0 || stream >= AudioSystem::NUM_STREAM_TYPES) {
- devices = 0;
- } else {
- AudioPolicyManagerBase::routing_strategy strategy = getStrategy(stream);
- devices = getDeviceForStrategy(strategy, true);
- }
- return devices;
-}
-
-AudioPolicyManagerBase::routing_strategy AudioPolicyManagerBase::getStrategy(
- AudioSystem::stream_type stream) {
- // stream to strategy mapping
- switch (stream) {
- case AudioSystem::VOICE_CALL:
- case AudioSystem::BLUETOOTH_SCO:
- return STRATEGY_PHONE;
- case AudioSystem::RING:
- case AudioSystem::NOTIFICATION:
- case AudioSystem::ALARM:
- case AudioSystem::ENFORCED_AUDIBLE:
- return STRATEGY_SONIFICATION;
- case AudioSystem::DTMF:
- return STRATEGY_DTMF;
- default:
- LOGE("unknown stream type");
- case AudioSystem::SYSTEM:
- // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
- // while key clicks are played produces a poor result
- case AudioSystem::TTS:
- case AudioSystem::MUSIC:
- return STRATEGY_MEDIA;
- }
-}
-
-uint32_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy strategy, bool fromCache)
-{
- uint32_t device = 0;
-
- if (fromCache) {
- LOGV("getDeviceForStrategy() from cache strategy %d, device %x", strategy, mDeviceForStrategy[strategy]);
- return mDeviceForStrategy[strategy];
- }
-
- switch (strategy) {
- case STRATEGY_DTMF:
- if (!isInCall()) {
- // when off call, DTMF strategy follows the same rules as MEDIA strategy
- device = getDeviceForStrategy(STRATEGY_MEDIA, false);
- break;
- }
- // when in call, DTMF and PHONE strategies follow the same rules
- // FALL THROUGH
-
- case STRATEGY_PHONE:
- // for phone strategy, we first consider the forced use and then the available devices by order
- // of priority
- switch (mForceUse[AudioSystem::FOR_COMMUNICATION]) {
- case AudioSystem::FORCE_BT_SCO:
- if (!isInCall() || strategy != STRATEGY_DTMF) {
- device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
- if (device) break;
- }
- device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
- if (device) break;
- device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO;
- if (device) break;
- // if SCO device is requested but no SCO device is available, fall back to default case
- // FALL THROUGH
-
- default: // FORCE_NONE
- device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE;
- if (device) break;
- device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET;
- if (device) break;
-#ifdef WITH_A2DP
- // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
- if (!isInCall() && !mA2dpSuspended) {
- device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP;
- if (device) break;
- device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
- if (device) break;
- }
-#endif
- device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_AUX_DIGITAL;
- if (device) break;
- device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET;
- if (device) break;
- device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET;
- if (device) break;
- device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_EARPIECE;
- if (device == 0) {
- LOGE("getDeviceForStrategy() earpiece device not found");
- }
- break;
-
- case AudioSystem::FORCE_SPEAKER:
-#ifdef WITH_A2DP
- // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to
- // A2DP speaker when forcing to speaker output
- if (!isInCall() && !mA2dpSuspended) {
- device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
- if (device) break;
- }
-#endif
- device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_AUX_DIGITAL;
- if (device) break;
- device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET;
- if (device) break;
- device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET;
- if (device) break;
- device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
- if (device == 0) {
- LOGE("getDeviceForStrategy() speaker device not found");
- }
- break;
- }
- break;
-
- case STRATEGY_SONIFICATION:
-
- // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by
- // handleIncallSonification().
- if (isInCall()) {
- device = getDeviceForStrategy(STRATEGY_PHONE, false);
- break;
- }
- device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
- if (device == 0) {
- LOGE("getDeviceForStrategy() speaker device not found");
- }
- // The second device used for sonification is the same as the device used by media strategy
- // FALL THROUGH
-
- case STRATEGY_MEDIA: {
- uint32_t device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE;
- if (device2 == 0) {
- device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET;
- }
-#ifdef WITH_A2DP
- if ((mA2dpOutput != 0) && !mA2dpSuspended &&
- (strategy != STRATEGY_SONIFICATION || a2dpUsedForSonification())) {
- if (device2 == 0) {
- device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP;
- }
- if (device2 == 0) {
- device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
- }
- if (device2 == 0) {
- device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
- }
- }
-#endif
- if (device2 == 0) {
- device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_AUX_DIGITAL;
- }
- if (device2 == 0) {
- device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET;
- }
- if (device2 == 0) {
- device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET;
- }
- if (device2 == 0) {
- device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
- }
-
- // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION, 0 otherwise
- device |= device2;
- if (device == 0) {
- LOGE("getDeviceForStrategy() speaker device not found");
- }
- } break;
-
- default:
- LOGW("getDeviceForStrategy() unknown strategy: %d", strategy);
- break;
- }
-
- LOGV("getDeviceForStrategy() strategy %d, device %x", strategy, device);
- return device;
-}
-
-void AudioPolicyManagerBase::updateDeviceForStrategy()
-{
- for (int i = 0; i < NUM_STRATEGIES; i++) {
- mDeviceForStrategy[i] = getDeviceForStrategy((routing_strategy)i, false);
- }
-}
-
-void AudioPolicyManagerBase::setOutputDevice(audio_io_handle_t output, uint32_t device, bool force, int delayMs)
-{
- LOGV("setOutputDevice() output %d device %x delayMs %d", output, device, delayMs);
- AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
-
-
- if (outputDesc->isDuplicated()) {
- setOutputDevice(outputDesc->mOutput1->mId, device, force, delayMs);
- setOutputDevice(outputDesc->mOutput2->mId, device, force, delayMs);
- return;
- }
-#ifdef WITH_A2DP
- // filter devices according to output selected
- if (output == mA2dpOutput) {
- device &= AudioSystem::DEVICE_OUT_ALL_A2DP;
- } else {
- device &= ~AudioSystem::DEVICE_OUT_ALL_A2DP;
- }
-#endif
-
- uint32_t prevDevice = (uint32_t)outputDesc->device();
- // Do not change the routing if:
- // - the requestede device is 0
- // - the requested device is the same as current device and force is not specified.
- // Doing this check here allows the caller to call setOutputDevice() without conditions
- if ((device == 0 || device == prevDevice) && !force) {
- LOGV("setOutputDevice() setting same device %x or null device for output %d", device, output);
- return;
- }
-
- outputDesc->mDevice = device;
- // mute media streams if both speaker and headset are selected
- if (output == mHardwareOutput && AudioSystem::popCount(device) == 2) {
- setStrategyMute(STRATEGY_MEDIA, true, output);
- // wait for the PCM output buffers to empty before proceeding with the rest of the command
- usleep(outputDesc->mLatency*2*1000);
- }
-
- // do the routing
- AudioParameter param = AudioParameter();
- param.addInt(String8(AudioParameter::keyRouting), (int)device);
- mpClientInterface->setParameters(mHardwareOutput, param.toString(), delayMs);
- // update stream volumes according to new device
- applyStreamVolumes(output, device, delayMs);
-
- // if changing from a combined headset + speaker route, unmute media streams
- if (output == mHardwareOutput && AudioSystem::popCount(prevDevice) == 2) {
- setStrategyMute(STRATEGY_MEDIA, false, output, delayMs);
- }
-}
-
-uint32_t AudioPolicyManagerBase::getDeviceForInputSource(int inputSource)
-{
- uint32_t device;
-
- switch(inputSource) {
- case AUDIO_SOURCE_DEFAULT:
- case AUDIO_SOURCE_MIC:
- case AUDIO_SOURCE_VOICE_RECOGNITION:
- case AUDIO_SOURCE_VOICE_COMMUNICATION:
- if (mForceUse[AudioSystem::FOR_RECORD] == AudioSystem::FORCE_BT_SCO &&
- mAvailableInputDevices & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
- device = AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET;
- } else if (mAvailableInputDevices & AudioSystem::DEVICE_IN_WIRED_HEADSET) {
- device = AudioSystem::DEVICE_IN_WIRED_HEADSET;
- } else {
- device = AudioSystem::DEVICE_IN_BUILTIN_MIC;
- }
- break;
- case AUDIO_SOURCE_CAMCORDER:
- if (hasBackMicrophone()) {
- device = AudioSystem::DEVICE_IN_BACK_MIC;
- } else {
- device = AudioSystem::DEVICE_IN_BUILTIN_MIC;
- }
- break;
- case AUDIO_SOURCE_VOICE_UPLINK:
- case AUDIO_SOURCE_VOICE_DOWNLINK:
- case AUDIO_SOURCE_VOICE_CALL:
- device = AudioSystem::DEVICE_IN_VOICE_CALL;
- break;
- default:
- LOGW("getInput() invalid input source %d", inputSource);
- device = 0;
- break;
- }
- LOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device);
- return device;
-}
-
-audio_io_handle_t AudioPolicyManagerBase::getActiveInput()
-{
- for (size_t i = 0; i < mInputs.size(); i++) {
- if (mInputs.valueAt(i)->mRefCount > 0) {
- return mInputs.keyAt(i);
- }
- }
- return 0;
-}
-
-float AudioPolicyManagerBase::volIndexToAmpl(uint32_t device, const StreamDescriptor& streamDesc,
- int indexInUi) {
- // the volume index in the UI is relative to the min and max volume indices for this stream type
- int nbSteps = 1 + streamDesc.mVolIndex[StreamDescriptor::VOLMAX] -
- streamDesc.mVolIndex[StreamDescriptor::VOLMIN];
- int volIdx = (nbSteps * (indexInUi - streamDesc.mIndexMin)) /
- (streamDesc.mIndexMax - streamDesc.mIndexMin);
-
- // find what part of the curve this index volume belongs to, or if it's out of bounds
- int segment = 0;
- if (volIdx < streamDesc.mVolIndex[StreamDescriptor::VOLMIN]) { // out of bounds
- return 0.0f;
- } else if (volIdx < streamDesc.mVolIndex[StreamDescriptor::VOLKNEE1]) {
- segment = 0;
- } else if (volIdx < streamDesc.mVolIndex[StreamDescriptor::VOLKNEE2]) {
- segment = 1;
- } else if (volIdx <= streamDesc.mVolIndex[StreamDescriptor::VOLMAX]) {
- segment = 2;
- } else { // out of bounds
- return 1.0f;
- }
-
- // linear interpolation in the attenuation table in dB
- float decibels = streamDesc.mVolDbAtt[segment] +
- ((float)(volIdx - streamDesc.mVolIndex[segment])) *
- ( (streamDesc.mVolDbAtt[segment+1] - streamDesc.mVolDbAtt[segment]) /
- ((float)(streamDesc.mVolIndex[segment+1] - streamDesc.mVolIndex[segment])) );
-
- float amplification = exp( decibels * 0.115129f); // exp( dB * ln(10) / 20 )
-
- LOGV("VOLUME vol index=[%d %d %d], dB=[%.1f %.1f %.1f] ampl=%.5f",
- streamDesc.mVolIndex[segment], volIdx, streamDesc.mVolIndex[segment+1],
- streamDesc.mVolDbAtt[segment], decibels, streamDesc.mVolDbAtt[segment+1],
- amplification);
-
- return amplification;
-}
-
-void AudioPolicyManagerBase::initializeVolumeCurves() {
- // initialize the volume curves to a (-49.5 - 0 dB) attenuation in 0.5dB steps
- for (int i=0 ; i< AudioSystem::NUM_STREAM_TYPES ; i++) {
- mStreams[i].mVolIndex[StreamDescriptor::VOLMIN] = 1;
- mStreams[i].mVolDbAtt[StreamDescriptor::VOLMIN] = -49.5f;
- mStreams[i].mVolIndex[StreamDescriptor::VOLKNEE1] = 33;
- mStreams[i].mVolDbAtt[StreamDescriptor::VOLKNEE1] = -33.5f;
- mStreams[i].mVolIndex[StreamDescriptor::VOLKNEE2] = 66;
- mStreams[i].mVolDbAtt[StreamDescriptor::VOLKNEE2] = -17.0f;
- // here we use 100 steps to avoid rounding errors
- // when computing the volume in volIndexToAmpl()
- mStreams[i].mVolIndex[StreamDescriptor::VOLMAX] = 100;
- mStreams[i].mVolDbAtt[StreamDescriptor::VOLMAX] = 0.0f;
- }
-
- // Modification for music: more attenuation for lower volumes, finer steps at high volumes
- mStreams[AudioSystem::MUSIC].mVolIndex[StreamDescriptor::VOLMIN] = 1;
- mStreams[AudioSystem::MUSIC].mVolDbAtt[StreamDescriptor::VOLMIN] = -58.0f;
- mStreams[AudioSystem::MUSIC].mVolIndex[StreamDescriptor::VOLKNEE1] = 20;
- mStreams[AudioSystem::MUSIC].mVolDbAtt[StreamDescriptor::VOLKNEE1] = -40.0f;
- mStreams[AudioSystem::MUSIC].mVolIndex[StreamDescriptor::VOLKNEE2] = 60;
- mStreams[AudioSystem::MUSIC].mVolDbAtt[StreamDescriptor::VOLKNEE2] = -17.0f;
- mStreams[AudioSystem::MUSIC].mVolIndex[StreamDescriptor::VOLMAX] = 100;
- mStreams[AudioSystem::MUSIC].mVolDbAtt[StreamDescriptor::VOLMAX] = 0.0f;
-}
-
-float AudioPolicyManagerBase::computeVolume(int stream, int index, audio_io_handle_t output, uint32_t device)
-{
- float volume = 1.0;
- AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
- StreamDescriptor &streamDesc = mStreams[stream];
-
- if (device == 0) {
- device = outputDesc->device();
- }
-
- // if volume is not 0 (not muted), force media volume to max on digital output
- if (stream == AudioSystem::MUSIC &&
- index != mStreams[stream].mIndexMin &&
- device == AudioSystem::DEVICE_OUT_AUX_DIGITAL) {
- return 1.0;
- }
-
- volume = volIndexToAmpl(device, streamDesc, index);
-
- // if a headset is connected, apply the following rules to ring tones and notifications
- // to avoid sound level bursts in user's ears:
- // - always attenuate ring tones and notifications volume by 6dB
- // - if music is playing, always limit the volume to current music volume,
- // with a minimum threshold at -36dB so that notification is always perceived.
- if ((device &
- (AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP |
- AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
- AudioSystem::DEVICE_OUT_WIRED_HEADSET |
- AudioSystem::DEVICE_OUT_WIRED_HEADPHONE)) &&
- ((getStrategy((AudioSystem::stream_type)stream) == STRATEGY_SONIFICATION) ||
- (stream == AudioSystem::SYSTEM)) &&
- streamDesc.mCanBeMuted) {
- volume *= SONIFICATION_HEADSET_VOLUME_FACTOR;
- // when the phone is ringing we must consider that music could have been paused just before
- // by the music application and behave as if music was active if the last music track was
- // just stopped
- if (outputDesc->mRefCount[AudioSystem::MUSIC] || mLimitRingtoneVolume) {
- float musicVol = computeVolume(AudioSystem::MUSIC, mStreams[AudioSystem::MUSIC].mIndexCur, output, device);
- float minVol = (musicVol > SONIFICATION_HEADSET_VOLUME_MIN) ? musicVol : SONIFICATION_HEADSET_VOLUME_MIN;
- if (volume > minVol) {
- volume = minVol;
- LOGV("computeVolume limiting volume to %f musicVol %f", minVol, musicVol);
- }
- }
- }
-
- return volume;
-}
-
-status_t AudioPolicyManagerBase::checkAndSetVolume(int stream, int index, audio_io_handle_t output, uint32_t device, int delayMs, bool force)
-{
-
- // do not change actual stream volume if the stream is muted
- if (mOutputs.valueFor(output)->mMuteCount[stream] != 0) {
- LOGV("checkAndSetVolume() stream %d muted count %d", stream, mOutputs.valueFor(output)->mMuteCount[stream]);
- return NO_ERROR;
- }
-
- // do not change in call volume if bluetooth is connected and vice versa
- if ((stream == AudioSystem::VOICE_CALL && mForceUse[AudioSystem::FOR_COMMUNICATION] == AudioSystem::FORCE_BT_SCO) ||
- (stream == AudioSystem::BLUETOOTH_SCO && mForceUse[AudioSystem::FOR_COMMUNICATION] != AudioSystem::FORCE_BT_SCO)) {
- LOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm",
- stream, mForceUse[AudioSystem::FOR_COMMUNICATION]);
- return INVALID_OPERATION;
- }
-
- float volume = computeVolume(stream, index, output, device);
- // We actually change the volume if:
- // - the float value returned by computeVolume() changed
- // - the force flag is set
- if (volume != mOutputs.valueFor(output)->mCurVolume[stream] ||
- force) {
- mOutputs.valueFor(output)->mCurVolume[stream] = volume;
- LOGV("setStreamVolume() for output %d stream %d, volume %f, delay %d", output, stream, volume, delayMs);
- if (stream == AudioSystem::VOICE_CALL ||
- stream == AudioSystem::DTMF ||
- stream == AudioSystem::BLUETOOTH_SCO) {
- // offset value to reflect actual hardware volume that never reaches 0
- // 1% corresponds roughly to first step in VOICE_CALL stream volume setting (see AudioService.java)
- volume = 0.01 + 0.99 * volume;
- // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is
- // enabled
- if (stream == AudioSystem::BLUETOOTH_SCO) {
- mpClientInterface->setStreamVolume(AudioSystem::VOICE_CALL, volume, output, delayMs);
- }
- }
-
- mpClientInterface->setStreamVolume((AudioSystem::stream_type)stream, volume, output, delayMs);
- }
-
- if (stream == AudioSystem::VOICE_CALL ||
- stream == AudioSystem::BLUETOOTH_SCO) {
- float voiceVolume;
- // Force voice volume to max for bluetooth SCO as volume is managed by the headset
- if (stream == AudioSystem::VOICE_CALL) {
- voiceVolume = (float)index/(float)mStreams[stream].mIndexMax;
- } else {
- voiceVolume = 1.0;
- }
-
- if (voiceVolume != mLastVoiceVolume && output == mHardwareOutput) {
- mpClientInterface->setVoiceVolume(voiceVolume, delayMs);
- mLastVoiceVolume = voiceVolume;
- }
- }
-
- return NO_ERROR;
-}
-
-void AudioPolicyManagerBase::applyStreamVolumes(audio_io_handle_t output, uint32_t device, int delayMs, bool force)
-{
- LOGV("applyStreamVolumes() for output %d and device %x", output, device);
-
- for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
- checkAndSetVolume(stream, mStreams[stream].mIndexCur, output, device, delayMs, force);
- }
-}
-
-void AudioPolicyManagerBase::setStrategyMute(routing_strategy strategy, bool on, audio_io_handle_t output, int delayMs)
-{
- LOGV("setStrategyMute() strategy %d, mute %d, output %d", strategy, on, output);
- for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
- if (getStrategy((AudioSystem::stream_type)stream) == strategy) {
- setStreamMute(stream, on, output, delayMs);
- }
- }
-}
-
-void AudioPolicyManagerBase::setStreamMute(int stream, bool on, audio_io_handle_t output, int delayMs)
-{
- StreamDescriptor &streamDesc = mStreams[stream];
- AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
-
- LOGV("setStreamMute() stream %d, mute %d, output %d, mMuteCount %d", stream, on, output, outputDesc->mMuteCount[stream]);
-
- if (on) {
- if (outputDesc->mMuteCount[stream] == 0) {
- if (streamDesc.mCanBeMuted) {
- checkAndSetVolume(stream, 0, output, outputDesc->device(), delayMs);
- }
- }
- // increment mMuteCount after calling checkAndSetVolume() so that volume change is not ignored
- outputDesc->mMuteCount[stream]++;
- } else {
- if (outputDesc->mMuteCount[stream] == 0) {
- LOGW("setStreamMute() unmuting non muted stream!");
- return;
- }
- if (--outputDesc->mMuteCount[stream] == 0) {
- checkAndSetVolume(stream, streamDesc.mIndexCur, output, outputDesc->device(), delayMs);
- }
- }
-}
-
-void AudioPolicyManagerBase::handleIncallSonification(int stream, bool starting, bool stateChange)
-{
- // if the stream pertains to sonification strategy and we are in call we must
- // mute the stream if it is low visibility. If it is high visibility, we must play a tone
- // in the device used for phone strategy and play the tone if the selected device does not
- // interfere with the device used for phone strategy
- // if stateChange is true, we are called from setPhoneState() and we must mute or unmute as
- // many times as there are active tracks on the output
-
- if (getStrategy((AudioSystem::stream_type)stream) == STRATEGY_SONIFICATION) {
- AudioOutputDescriptor *outputDesc = mOutputs.valueFor(mHardwareOutput);
- LOGV("handleIncallSonification() stream %d starting %d device %x stateChange %d",
- stream, starting, outputDesc->mDevice, stateChange);
- if (outputDesc->mRefCount[stream]) {
- int muteCount = 1;
- if (stateChange) {
- muteCount = outputDesc->mRefCount[stream];
- }
- if (AudioSystem::isLowVisibility((AudioSystem::stream_type)stream)) {
- LOGV("handleIncallSonification() low visibility, muteCount %d", muteCount);
- for (int i = 0; i < muteCount; i++) {
- setStreamMute(stream, starting, mHardwareOutput);
- }
- } else {
- LOGV("handleIncallSonification() high visibility");
- if (outputDesc->device() & getDeviceForStrategy(STRATEGY_PHONE)) {
- LOGV("handleIncallSonification() high visibility muted, muteCount %d", muteCount);
- for (int i = 0; i < muteCount; i++) {
- setStreamMute(stream, starting, mHardwareOutput);
- }
- }
- if (starting) {
- mpClientInterface->startTone(ToneGenerator::TONE_SUP_CALL_WAITING, AudioSystem::VOICE_CALL);
- } else {
- mpClientInterface->stopTone();
- }
- }
- }
- }
-}
-
-bool AudioPolicyManagerBase::isInCall()
-{
- return isStateInCall(mPhoneState);
-}
-
-bool AudioPolicyManagerBase::isStateInCall(int state) {
- return ((state == AudioSystem::MODE_IN_CALL) ||
- (state == AudioSystem::MODE_IN_COMMUNICATION));
-}
-
-bool AudioPolicyManagerBase::needsDirectOuput(AudioSystem::stream_type stream,
- uint32_t samplingRate,
- uint32_t format,
- uint32_t channels,
- AudioSystem::output_flags flags,
- uint32_t device)
-{
- return ((flags & AudioSystem::OUTPUT_FLAG_DIRECT) ||
- (format !=0 && !AudioSystem::isLinearPCM(format)));
-}
-
-uint32_t AudioPolicyManagerBase::getMaxEffectsCpuLoad()
-{
- return MAX_EFFECTS_CPU_LOAD;
-}
-
-uint32_t AudioPolicyManagerBase::getMaxEffectsMemory()
-{
- return MAX_EFFECTS_MEMORY;
-}
-
-// --- AudioOutputDescriptor class implementation
-
-AudioPolicyManagerBase::AudioOutputDescriptor::AudioOutputDescriptor()
- : mId(0), mSamplingRate(0), mFormat(0), mChannels(0), mLatency(0),
- mFlags((AudioSystem::output_flags)0), mDevice(0), mOutput1(0), mOutput2(0)
-{
- // clear usage count for all stream types
- for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) {
- mRefCount[i] = 0;
- mCurVolume[i] = -1.0;
- mMuteCount[i] = 0;
- mStopTime[i] = 0;
- }
-}
-
-uint32_t AudioPolicyManagerBase::AudioOutputDescriptor::device()
-{
- uint32_t device = 0;
- if (isDuplicated()) {
- device = mOutput1->mDevice | mOutput2->mDevice;
- } else {
- device = mDevice;
- }
- return device;
-}
-
-void AudioPolicyManagerBase::AudioOutputDescriptor::changeRefCount(AudioSystem::stream_type stream, int delta)
-{
- // forward usage count change to attached outputs
- if (isDuplicated()) {
- mOutput1->changeRefCount(stream, delta);
- mOutput2->changeRefCount(stream, delta);
- }
- if ((delta + (int)mRefCount[stream]) < 0) {
- LOGW("changeRefCount() invalid delta %d for stream %d, refCount %d", delta, stream, mRefCount[stream]);
- mRefCount[stream] = 0;
- return;
- }
- mRefCount[stream] += delta;
- LOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]);
-}
-
-uint32_t AudioPolicyManagerBase::AudioOutputDescriptor::refCount()
-{
- uint32_t refcount = 0;
- for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
- refcount += mRefCount[i];
- }
- return refcount;
-}
-
-uint32_t AudioPolicyManagerBase::AudioOutputDescriptor::strategyRefCount(routing_strategy strategy)
-{
- uint32_t refCount = 0;
- for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
- if (getStrategy((AudioSystem::stream_type)i) == strategy) {
- refCount += mRefCount[i];
- }
- }
- return refCount;
-}
-
-status_t AudioPolicyManagerBase::AudioOutputDescriptor::dump(int fd)
-{
- const size_t SIZE = 256;
- char buffer[SIZE];
- String8 result;
-
- snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
- result.append(buffer);
- snprintf(buffer, SIZE, " Format: %d\n", mFormat);
- result.append(buffer);
- snprintf(buffer, SIZE, " Channels: %08x\n", mChannels);
- result.append(buffer);
- snprintf(buffer, SIZE, " Latency: %d\n", mLatency);
- result.append(buffer);
- snprintf(buffer, SIZE, " Flags %08x\n", mFlags);
- result.append(buffer);
- snprintf(buffer, SIZE, " Devices %08x\n", device());
- result.append(buffer);
- snprintf(buffer, SIZE, " Stream volume refCount muteCount\n");
- result.append(buffer);
- for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) {
- snprintf(buffer, SIZE, " %02d %.03f %02d %02d\n", i, mCurVolume[i], mRefCount[i], mMuteCount[i]);
- result.append(buffer);
- }
- write(fd, result.string(), result.size());
-
- return NO_ERROR;
-}
-
-// --- AudioInputDescriptor class implementation
-
-AudioPolicyManagerBase::AudioInputDescriptor::AudioInputDescriptor()
- : mSamplingRate(0), mFormat(0), mChannels(0),
- mAcoustics((AudioSystem::audio_in_acoustics)0), mDevice(0), mRefCount(0)
-{
-}
-
-status_t AudioPolicyManagerBase::AudioInputDescriptor::dump(int fd)
-{
- const size_t SIZE = 256;
- char buffer[SIZE];
- String8 result;
-
- snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
- result.append(buffer);
- snprintf(buffer, SIZE, " Format: %d\n", mFormat);
- result.append(buffer);
- snprintf(buffer, SIZE, " Channels: %08x\n", mChannels);
- result.append(buffer);
- snprintf(buffer, SIZE, " Acoustics %08x\n", mAcoustics);
- result.append(buffer);
- snprintf(buffer, SIZE, " Devices %08x\n", mDevice);
- result.append(buffer);
- snprintf(buffer, SIZE, " Ref Count %d\n", mRefCount);
- result.append(buffer);
- write(fd, result.string(), result.size());
-
- return NO_ERROR;
-}
-
-// --- StreamDescriptor class implementation
-
-void AudioPolicyManagerBase::StreamDescriptor::dump(char* buffer, size_t size)
-{
- snprintf(buffer, size, " %02d %02d %02d %d\n",
- mIndexMin,
- mIndexMax,
- mIndexCur,
- mCanBeMuted);
-}
-
-// --- EffectDescriptor class implementation
-
-status_t AudioPolicyManagerBase::EffectDescriptor::dump(int fd)
-{
- const size_t SIZE = 256;
- char buffer[SIZE];
- String8 result;
-
- snprintf(buffer, SIZE, " Output: %d\n", mOutput);
- result.append(buffer);
- snprintf(buffer, SIZE, " Strategy: %d\n", mStrategy);
- result.append(buffer);
- snprintf(buffer, SIZE, " Session: %d\n", mSession);
- result.append(buffer);
- snprintf(buffer, SIZE, " Name: %s\n", mDesc.name);
- result.append(buffer);
- write(fd, result.string(), result.size());
-
- return NO_ERROR;
-}
-
-
-
-}; // namespace android
diff --git a/services/audioflinger/AudioPolicyService.cpp b/services/audioflinger/AudioPolicyService.cpp
index b614c48..6d06d83 100644
--- a/services/audioflinger/AudioPolicyService.cpp
+++ b/services/audioflinger/AudioPolicyService.cpp
@@ -30,21 +30,20 @@
#include <utils/String16.h>
#include <utils/threads.h>
#include "AudioPolicyService.h"
-#include <hardware_legacy/AudioPolicyManagerBase.h>
#include <cutils/properties.h>
#include <dlfcn.h>
#include <hardware_legacy/power.h>
+#include <media/AudioEffect.h>
+#include <media/EffectsFactoryApi.h>
-// ----------------------------------------------------------------------------
-// the sim build doesn't have gettid
-
-#ifndef HAVE_GETTID
-# define gettid getpid
-#endif
+#include <hardware/hardware.h>
+#include <system/audio.h>
+#include <system/audio_policy.h>
+#include <hardware/audio_policy.h>
+#include <audio_effects/audio_effects_conf.h>
namespace android {
-
static const char *kDeadlockedString = "AudioPolicyService may be deadlocked\n";
static const char *kCmdDeadlockedString = "AudioPolicyService command thread may be deadlocked\n";
@@ -52,21 +51,25 @@
static const int kDumpLockSleep = 20000;
static bool checkPermission() {
-#ifndef HAVE_ANDROID_OS
- return true;
-#endif
if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
bool ok = checkCallingPermission(String16("android.permission.MODIFY_AUDIO_SETTINGS"));
if (!ok) LOGE("Request requires android.permission.MODIFY_AUDIO_SETTINGS");
return ok;
}
+namespace {
+ extern struct audio_policy_service_ops aps_ops;
+};
+
// ----------------------------------------------------------------------------
AudioPolicyService::AudioPolicyService()
- : BnAudioPolicyService() , mpPolicyManager(NULL)
+ : BnAudioPolicyService() , mpAudioPolicyDev(NULL) , mpAudioPolicy(NULL)
{
char value[PROPERTY_VALUE_MAX];
+ const struct hw_module_t *module;
+ int forced_val;
+ int rc;
Mutex::Autolock _l(mLock);
@@ -75,32 +78,38 @@
// start audio commands thread
mAudioCommandThread = new AudioCommandThread(String8("ApmCommandThread"));
-#if (defined GENERIC_AUDIO) || (defined AUDIO_POLICY_TEST)
- mpPolicyManager = new AudioPolicyManagerBase(this);
- LOGV("build for GENERIC_AUDIO - using generic audio policy");
-#else
- // if running in emulation - use the emulator driver
- if (property_get("ro.kernel.qemu", value, 0)) {
- LOGV("Running in emulation - using generic audio policy");
- mpPolicyManager = new AudioPolicyManagerBase(this);
- }
- else {
- LOGV("Using hardware specific audio policy");
- mpPolicyManager = createAudioPolicyManager(this);
- }
-#endif
+ /* instantiate the audio policy manager */
+ rc = hw_get_module(AUDIO_POLICY_HARDWARE_MODULE_ID, &module);
+ if (rc)
+ return;
- if ((mpPolicyManager != NULL) && (mpPolicyManager->initCheck() != NO_ERROR)) {
- delete mpPolicyManager;
- mpPolicyManager = NULL;
- }
+ rc = audio_policy_dev_open(module, &mpAudioPolicyDev);
+ LOGE_IF(rc, "couldn't open audio policy device (%s)", strerror(-rc));
+ if (rc)
+ return;
- if (mpPolicyManager == NULL) {
- LOGE("Could not create AudioPolicyManager");
- } else {
- // load properties
- property_get("ro.camera.sound.forced", value, "0");
- mpPolicyManager->setSystemProperty("ro.camera.sound.forced", value);
+ rc = mpAudioPolicyDev->create_audio_policy(mpAudioPolicyDev, &aps_ops, this,
+ &mpAudioPolicy);
+ LOGE_IF(rc, "couldn't create audio policy (%s)", strerror(-rc));
+ if (rc)
+ return;
+
+ rc = mpAudioPolicy->init_check(mpAudioPolicy);
+ LOGE_IF(rc, "couldn't init_check the audio policy (%s)", strerror(-rc));
+ if (rc)
+ return;
+
+ property_get("ro.camera.sound.forced", value, "0");
+ forced_val = strtol(value, NULL, 0);
+ mpAudioPolicy->set_can_mute_enforced_audible(mpAudioPolicy, !forced_val);
+
+ LOGI("Loaded audio policy from %s (%s)", module->name, module->id);
+
+ // load audio pre processing modules
+ if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) {
+ loadPreProcessorConfig(AUDIO_EFFECT_VENDOR_CONFIG_FILE);
+ } else if (access(AUDIO_EFFECT_DEFAULT_CONFIG_FILE, R_OK) == 0) {
+ loadPreProcessorConfig(AUDIO_EFFECT_DEFAULT_CONFIG_FILE);
}
}
@@ -111,57 +120,84 @@
mAudioCommandThread->exit();
mAudioCommandThread.clear();
- if (mpPolicyManager) {
- delete mpPolicyManager;
+
+ // release audio pre processing resources
+ for (size_t i = 0; i < mInputSources.size(); i++) {
+ InputSourceDesc *source = mInputSources.valueAt(i);
+ Vector <EffectDesc *> effects = source->mEffects;
+ for (size_t j = 0; j < effects.size(); j++) {
+ delete effects[j]->mName;
+ Vector <effect_param_t *> params = effects[j]->mParams;
+ for (size_t k = 0; k < params.size(); k++) {
+ delete params[k];
+ }
+ params.clear();
+ delete effects[j];
+ }
+ effects.clear();
+ delete source;
}
+ mInputSources.clear();
+
+ for (size_t i = 0; i < mInputs.size(); i++) {
+ mInputs.valueAt(i)->mEffects.clear();
+ delete mInputs.valueAt(i);
+ }
+ mInputs.clear();
+
+ if (mpAudioPolicy && mpAudioPolicyDev)
+ mpAudioPolicyDev->destroy_audio_policy(mpAudioPolicyDev, mpAudioPolicy);
+ if (mpAudioPolicyDev)
+ audio_policy_dev_close(mpAudioPolicyDev);
}
-
-status_t AudioPolicyService::setDeviceConnectionState(AudioSystem::audio_devices device,
- AudioSystem::device_connection_state state,
+status_t AudioPolicyService::setDeviceConnectionState(audio_devices_t device,
+ audio_policy_dev_state_t state,
const char *device_address)
{
- if (mpPolicyManager == NULL) {
+ if (mpAudioPolicy == NULL) {
return NO_INIT;
}
if (!checkPermission()) {
return PERMISSION_DENIED;
}
- if (!AudioSystem::isOutputDevice(device) && !AudioSystem::isInputDevice(device)) {
+ if (!audio_is_output_device(device) && !audio_is_input_device(device)) {
return BAD_VALUE;
}
- if (state != AudioSystem::DEVICE_STATE_AVAILABLE &&
- state != AudioSystem::DEVICE_STATE_UNAVAILABLE) {
+ if (state != AUDIO_POLICY_DEVICE_STATE_AVAILABLE &&
+ state != AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) {
return BAD_VALUE;
}
LOGV("setDeviceConnectionState() tid %d", gettid());
Mutex::Autolock _l(mLock);
- return mpPolicyManager->setDeviceConnectionState(device, state, device_address);
+ return mpAudioPolicy->set_device_connection_state(mpAudioPolicy, device,
+ state, device_address);
}
-AudioSystem::device_connection_state AudioPolicyService::getDeviceConnectionState(
- AudioSystem::audio_devices device,
+audio_policy_dev_state_t AudioPolicyService::getDeviceConnectionState(
+ audio_devices_t device,
const char *device_address)
{
- if (mpPolicyManager == NULL) {
- return AudioSystem::DEVICE_STATE_UNAVAILABLE;
+ if (mpAudioPolicy == NULL) {
+ return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
}
if (!checkPermission()) {
- return AudioSystem::DEVICE_STATE_UNAVAILABLE;
+ return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
}
- return mpPolicyManager->getDeviceConnectionState(device, device_address);
+ return mpAudioPolicy->get_device_connection_state(mpAudioPolicy, device,
+ device_address);
}
status_t AudioPolicyService::setPhoneState(int state)
{
- if (mpPolicyManager == NULL) {
+ if (mpAudioPolicy == NULL) {
return NO_INIT;
}
if (!checkPermission()) {
return PERMISSION_DENIED;
}
- if (state < 0 || state >= AudioSystem::NUM_MODES) {
+ if (state < 0 || state >= AUDIO_MODE_CNT) {
return BAD_VALUE;
}
@@ -171,244 +207,331 @@
AudioSystem::setMode(state);
Mutex::Autolock _l(mLock);
- mpPolicyManager->setPhoneState(state);
+ mpAudioPolicy->set_phone_state(mpAudioPolicy, state);
return NO_ERROR;
}
status_t AudioPolicyService::setRingerMode(uint32_t mode, uint32_t mask)
{
- if (mpPolicyManager == NULL) {
+ if (mpAudioPolicy == NULL) {
return NO_INIT;
}
if (!checkPermission()) {
return PERMISSION_DENIED;
}
- mpPolicyManager->setRingerMode(mode, mask);
+ mpAudioPolicy->set_ringer_mode(mpAudioPolicy, mode, mask);
return NO_ERROR;
}
-status_t AudioPolicyService::setForceUse(AudioSystem::force_use usage,
- AudioSystem::forced_config config)
+status_t AudioPolicyService::setForceUse(audio_policy_force_use_t usage,
+ audio_policy_forced_cfg_t config)
{
- if (mpPolicyManager == NULL) {
+ if (mpAudioPolicy == NULL) {
return NO_INIT;
}
if (!checkPermission()) {
return PERMISSION_DENIED;
}
- if (usage < 0 || usage >= AudioSystem::NUM_FORCE_USE) {
+ if (usage < 0 || usage >= AUDIO_POLICY_FORCE_USE_CNT) {
return BAD_VALUE;
}
- if (config < 0 || config >= AudioSystem::NUM_FORCE_CONFIG) {
+ if (config < 0 || config >= AUDIO_POLICY_FORCE_CFG_CNT) {
return BAD_VALUE;
}
LOGV("setForceUse() tid %d", gettid());
Mutex::Autolock _l(mLock);
- mpPolicyManager->setForceUse(usage, config);
+ mpAudioPolicy->set_force_use(mpAudioPolicy, usage, config);
return NO_ERROR;
}
-AudioSystem::forced_config AudioPolicyService::getForceUse(AudioSystem::force_use usage)
+audio_policy_forced_cfg_t AudioPolicyService::getForceUse(audio_policy_force_use_t usage)
{
- if (mpPolicyManager == NULL) {
- return AudioSystem::FORCE_NONE;
+ if (mpAudioPolicy == NULL) {
+ return AUDIO_POLICY_FORCE_NONE;
}
if (!checkPermission()) {
- return AudioSystem::FORCE_NONE;
+ return AUDIO_POLICY_FORCE_NONE;
}
- if (usage < 0 || usage >= AudioSystem::NUM_FORCE_USE) {
- return AudioSystem::FORCE_NONE;
+ if (usage < 0 || usage >= AUDIO_POLICY_FORCE_USE_CNT) {
+ return AUDIO_POLICY_FORCE_NONE;
}
- return mpPolicyManager->getForceUse(usage);
+ return mpAudioPolicy->get_force_use(mpAudioPolicy, usage);
}
-audio_io_handle_t AudioPolicyService::getOutput(AudioSystem::stream_type stream,
+audio_io_handle_t AudioPolicyService::getOutput(audio_stream_type_t stream,
uint32_t samplingRate,
uint32_t format,
uint32_t channels,
- AudioSystem::output_flags flags)
+ audio_policy_output_flags_t flags)
{
- if (mpPolicyManager == NULL) {
+ if (mpAudioPolicy == NULL) {
return 0;
}
LOGV("getOutput() tid %d", gettid());
Mutex::Autolock _l(mLock);
- return mpPolicyManager->getOutput(stream, samplingRate, format, channels, flags);
+ return mpAudioPolicy->get_output(mpAudioPolicy, stream, samplingRate, format, channels, flags);
}
status_t AudioPolicyService::startOutput(audio_io_handle_t output,
- AudioSystem::stream_type stream,
+ audio_stream_type_t stream,
int session)
{
- if (mpPolicyManager == NULL) {
+ if (mpAudioPolicy == NULL) {
return NO_INIT;
}
LOGV("startOutput() tid %d", gettid());
Mutex::Autolock _l(mLock);
- return mpPolicyManager->startOutput(output, stream, session);
+ return mpAudioPolicy->start_output(mpAudioPolicy, output, stream, session);
}
status_t AudioPolicyService::stopOutput(audio_io_handle_t output,
- AudioSystem::stream_type stream,
+ audio_stream_type_t stream,
int session)
{
- if (mpPolicyManager == NULL) {
+ if (mpAudioPolicy == NULL) {
return NO_INIT;
}
LOGV("stopOutput() tid %d", gettid());
Mutex::Autolock _l(mLock);
- return mpPolicyManager->stopOutput(output, stream, session);
+ return mpAudioPolicy->stop_output(mpAudioPolicy, output, stream, session);
}
void AudioPolicyService::releaseOutput(audio_io_handle_t output)
{
- if (mpPolicyManager == NULL) {
+ if (mpAudioPolicy == NULL) {
return;
}
LOGV("releaseOutput() tid %d", gettid());
Mutex::Autolock _l(mLock);
- mpPolicyManager->releaseOutput(output);
+ mpAudioPolicy->release_output(mpAudioPolicy, output);
}
audio_io_handle_t AudioPolicyService::getInput(int inputSource,
uint32_t samplingRate,
uint32_t format,
uint32_t channels,
- AudioSystem::audio_in_acoustics acoustics)
+ audio_in_acoustics_t acoustics,
+ int audioSession)
{
- if (mpPolicyManager == NULL) {
+ if (mpAudioPolicy == NULL) {
return 0;
}
Mutex::Autolock _l(mLock);
- return mpPolicyManager->getInput(inputSource, samplingRate, format, channels, acoustics);
+ audio_io_handle_t input = mpAudioPolicy->get_input(mpAudioPolicy, inputSource, samplingRate,
+ format, channels, acoustics);
+
+ if (input == 0) {
+ return input;
+ }
+ // create audio pre processors according to input source
+ ssize_t index = mInputSources.indexOfKey((audio_source_t)inputSource);
+ if (index < 0) {
+ return input;
+ }
+ ssize_t idx = mInputs.indexOfKey(input);
+ InputDesc *inputDesc;
+ if (idx < 0) {
+ inputDesc = new InputDesc();
+ inputDesc->mSessionId = audioSession;
+ mInputs.add(input, inputDesc);
+ } else {
+ inputDesc = mInputs.valueAt(idx);
+ }
+
+ Vector <EffectDesc *> effects = mInputSources.valueAt(index)->mEffects;
+ for (size_t i = 0; i < effects.size(); i++) {
+ EffectDesc *effect = effects[i];
+ sp<AudioEffect> fx = new AudioEffect(NULL, &effect->mUuid, -1, 0, 0, audioSession, input);
+ status_t status = fx->initCheck();
+ if (status != NO_ERROR && status != ALREADY_EXISTS) {
+ LOGW("Failed to create Fx %s on input %d", effect->mName, input);
+ // fx goes out of scope and strong ref on AudioEffect is released
+ continue;
+ }
+ for (size_t j = 0; j < effect->mParams.size(); j++) {
+ fx->setParameter(effect->mParams[j]);
+ }
+ inputDesc->mEffects.add(fx);
+ }
+ setPreProcessorEnabled(inputDesc, true);
+ return input;
}
status_t AudioPolicyService::startInput(audio_io_handle_t input)
{
- if (mpPolicyManager == NULL) {
+ if (mpAudioPolicy == NULL) {
return NO_INIT;
}
Mutex::Autolock _l(mLock);
- return mpPolicyManager->startInput(input);
+
+ return mpAudioPolicy->start_input(mpAudioPolicy, input);
}
status_t AudioPolicyService::stopInput(audio_io_handle_t input)
{
- if (mpPolicyManager == NULL) {
+ if (mpAudioPolicy == NULL) {
return NO_INIT;
}
Mutex::Autolock _l(mLock);
- return mpPolicyManager->stopInput(input);
+
+ return mpAudioPolicy->stop_input(mpAudioPolicy, input);
}
void AudioPolicyService::releaseInput(audio_io_handle_t input)
{
- if (mpPolicyManager == NULL) {
+ if (mpAudioPolicy == NULL) {
return;
}
Mutex::Autolock _l(mLock);
- mpPolicyManager->releaseInput(input);
+ mpAudioPolicy->release_input(mpAudioPolicy, input);
+
+ ssize_t index = mInputs.indexOfKey(input);
+ if (index < 0) {
+ return;
+ }
+ InputDesc *inputDesc = mInputs.valueAt(index);
+ setPreProcessorEnabled(inputDesc, false);
+ inputDesc->mEffects.clear();
+ delete inputDesc;
+ mInputs.removeItemsAt(index);
}
-status_t AudioPolicyService::initStreamVolume(AudioSystem::stream_type stream,
+status_t AudioPolicyService::initStreamVolume(audio_stream_type_t stream,
int indexMin,
int indexMax)
{
- if (mpPolicyManager == NULL) {
+ if (mpAudioPolicy == NULL) {
return NO_INIT;
}
if (!checkPermission()) {
return PERMISSION_DENIED;
}
- if (stream < 0 || stream >= AudioSystem::NUM_STREAM_TYPES) {
+ if (stream < 0 || stream >= AUDIO_STREAM_CNT) {
return BAD_VALUE;
}
- mpPolicyManager->initStreamVolume(stream, indexMin, indexMax);
+ mpAudioPolicy->init_stream_volume(mpAudioPolicy, stream, indexMin, indexMax);
return NO_ERROR;
}
-status_t AudioPolicyService::setStreamVolumeIndex(AudioSystem::stream_type stream, int index)
+status_t AudioPolicyService::setStreamVolumeIndex(audio_stream_type_t stream, int index)
{
- if (mpPolicyManager == NULL) {
+ if (mpAudioPolicy == NULL) {
return NO_INIT;
}
if (!checkPermission()) {
return PERMISSION_DENIED;
}
- if (stream < 0 || stream >= AudioSystem::NUM_STREAM_TYPES) {
+ if (stream < 0 || stream >= AUDIO_STREAM_CNT) {
return BAD_VALUE;
}
- return mpPolicyManager->setStreamVolumeIndex(stream, index);
+ return mpAudioPolicy->set_stream_volume_index(mpAudioPolicy, stream, index);
}
-status_t AudioPolicyService::getStreamVolumeIndex(AudioSystem::stream_type stream, int *index)
+status_t AudioPolicyService::getStreamVolumeIndex(audio_stream_type_t stream, int *index)
{
- if (mpPolicyManager == NULL) {
+ if (mpAudioPolicy == NULL) {
return NO_INIT;
}
if (!checkPermission()) {
return PERMISSION_DENIED;
}
- if (stream < 0 || stream >= AudioSystem::NUM_STREAM_TYPES) {
+ if (stream < 0 || stream >= AUDIO_STREAM_CNT) {
return BAD_VALUE;
}
- return mpPolicyManager->getStreamVolumeIndex(stream, index);
+ return mpAudioPolicy->get_stream_volume_index(mpAudioPolicy, stream, index);
}
-uint32_t AudioPolicyService::getStrategyForStream(AudioSystem::stream_type stream)
+uint32_t AudioPolicyService::getStrategyForStream(audio_stream_type_t stream)
{
- if (mpPolicyManager == NULL) {
+ if (mpAudioPolicy == NULL) {
return 0;
}
- return mpPolicyManager->getStrategyForStream(stream);
+ return mpAudioPolicy->get_strategy_for_stream(mpAudioPolicy, stream);
}
-uint32_t AudioPolicyService::getDevicesForStream(AudioSystem::stream_type stream)
+uint32_t AudioPolicyService::getDevicesForStream(audio_stream_type_t stream)
{
- if (mpPolicyManager == NULL) {
+ if (mpAudioPolicy == NULL) {
return 0;
}
- return mpPolicyManager->getDevicesForStream(stream);
+ return mpAudioPolicy->get_devices_for_stream(mpAudioPolicy, stream);
}
audio_io_handle_t AudioPolicyService::getOutputForEffect(effect_descriptor_t *desc)
{
- if (mpPolicyManager == NULL) {
+ if (mpAudioPolicy == NULL) {
return NO_INIT;
}
Mutex::Autolock _l(mLock);
- return mpPolicyManager->getOutputForEffect(desc);
+ return mpAudioPolicy->get_output_for_effect(mpAudioPolicy, desc);
}
status_t AudioPolicyService::registerEffect(effect_descriptor_t *desc,
- audio_io_handle_t output,
+ audio_io_handle_t io,
uint32_t strategy,
int session,
int id)
{
- if (mpPolicyManager == NULL) {
+ if (mpAudioPolicy == NULL) {
return NO_INIT;
}
- return mpPolicyManager->registerEffect(desc, output, strategy, session, id);
+ return mpAudioPolicy->register_effect(mpAudioPolicy, desc, io, strategy, session, id);
}
status_t AudioPolicyService::unregisterEffect(int id)
{
- if (mpPolicyManager == NULL) {
+ if (mpAudioPolicy == NULL) {
return NO_INIT;
}
- return mpPolicyManager->unregisterEffect(id);
+ return mpAudioPolicy->unregister_effect(mpAudioPolicy, id);
}
bool AudioPolicyService::isStreamActive(int stream, uint32_t inPastMs) const
{
- if (mpPolicyManager == NULL) {
+ if (mpAudioPolicy == NULL) {
return 0;
}
Mutex::Autolock _l(mLock);
- return mpPolicyManager->isStreamActive(stream, inPastMs);
+ return mpAudioPolicy->is_stream_active(mpAudioPolicy, stream, inPastMs);
+}
+
+status_t AudioPolicyService::queryDefaultPreProcessing(int audioSession,
+ effect_descriptor_t *descriptors,
+ uint32_t *count)
+{
+
+ if (mpAudioPolicy == NULL) {
+ *count = 0;
+ return NO_INIT;
+ }
+ Mutex::Autolock _l(mLock);
+ status_t status = NO_ERROR;
+
+ size_t index;
+ for (index = 0; index < mInputs.size(); index++) {
+ if (mInputs.valueAt(index)->mSessionId == audioSession) {
+ break;
+ }
+ }
+ if (index == mInputs.size()) {
+ *count = 0;
+ return BAD_VALUE;
+ }
+ Vector< sp<AudioEffect> > effects = mInputs.valueAt(index)->mEffects;
+
+ for (size_t i = 0; i < effects.size(); i++) {
+ effect_descriptor_t desc = effects[i]->descriptor();
+ if (i < *count) {
+ memcpy(descriptors + i, &desc, sizeof(effect_descriptor_t));
+ }
+ }
+ if (effects.size() > *count) {
+ status = NO_MEMORY;
+ }
+ *count = effects.size();
+ return status;
}
void AudioPolicyService::binderDied(const wp<IBinder>& who) {
@@ -435,7 +558,7 @@
char buffer[SIZE];
String8 result;
- snprintf(buffer, SIZE, "PolicyManager Interface: %p\n", mpPolicyManager);
+ snprintf(buffer, SIZE, "PolicyManager Interface: %p\n", mpAudioPolicy);
result.append(buffer);
snprintf(buffer, SIZE, "Command Thread: %p\n", mAudioCommandThread.get());
result.append(buffer);
@@ -465,8 +588,8 @@
mTonePlaybackThread->dump(fd);
}
- if (mpPolicyManager) {
- mpPolicyManager->dump(fd);
+ if (mpAudioPolicy) {
+ mpAudioPolicy->dump(mpAudioPolicy, fd);
}
if (locked) mLock.unlock();
@@ -488,6 +611,15 @@
return NO_ERROR;
}
+void AudioPolicyService::setPreProcessorEnabled(InputDesc *inputDesc, bool enabled)
+{
+ Vector<sp<AudioEffect> > fxVector = inputDesc->mEffects;
+ for (size_t i = 0; i < fxVector.size(); i++) {
+ sp<AudioEffect> fx = fxVector.itemAt(i);
+ fx->setEnabled(enabled);
+ }
+}
+
status_t AudioPolicyService::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
@@ -495,154 +627,6 @@
}
-// ----------------------------------------------------------------------------
-// AudioPolicyClientInterface implementation
-// ----------------------------------------------------------------------------
-
-
-audio_io_handle_t AudioPolicyService::openOutput(uint32_t *pDevices,
- uint32_t *pSamplingRate,
- uint32_t *pFormat,
- uint32_t *pChannels,
- uint32_t *pLatencyMs,
- AudioSystem::output_flags flags)
-{
- sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
- if (af == 0) {
- LOGW("openOutput() could not get AudioFlinger");
- return 0;
- }
-
- return af->openOutput(pDevices,
- pSamplingRate,
- (uint32_t *)pFormat,
- pChannels,
- pLatencyMs,
- flags);
-}
-
-audio_io_handle_t AudioPolicyService::openDuplicateOutput(audio_io_handle_t output1,
- audio_io_handle_t output2)
-{
- sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
- if (af == 0) {
- LOGW("openDuplicateOutput() could not get AudioFlinger");
- return 0;
- }
- return af->openDuplicateOutput(output1, output2);
-}
-
-status_t AudioPolicyService::closeOutput(audio_io_handle_t output)
-{
- sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
- if (af == 0) return PERMISSION_DENIED;
-
- return af->closeOutput(output);
-}
-
-
-status_t AudioPolicyService::suspendOutput(audio_io_handle_t output)
-{
- sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
- if (af == 0) {
- LOGW("suspendOutput() could not get AudioFlinger");
- return PERMISSION_DENIED;
- }
-
- return af->suspendOutput(output);
-}
-
-status_t AudioPolicyService::restoreOutput(audio_io_handle_t output)
-{
- sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
- if (af == 0) {
- LOGW("restoreOutput() could not get AudioFlinger");
- return PERMISSION_DENIED;
- }
-
- return af->restoreOutput(output);
-}
-
-audio_io_handle_t AudioPolicyService::openInput(uint32_t *pDevices,
- uint32_t *pSamplingRate,
- uint32_t *pFormat,
- uint32_t *pChannels,
- uint32_t acoustics)
-{
- sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
- if (af == 0) {
- LOGW("openInput() could not get AudioFlinger");
- return 0;
- }
-
- return af->openInput(pDevices, pSamplingRate, (uint32_t *)pFormat, pChannels, acoustics);
-}
-
-status_t AudioPolicyService::closeInput(audio_io_handle_t input)
-{
- sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
- if (af == 0) return PERMISSION_DENIED;
-
- return af->closeInput(input);
-}
-
-status_t AudioPolicyService::setStreamVolume(AudioSystem::stream_type stream,
- float volume,
- audio_io_handle_t output,
- int delayMs)
-{
- return mAudioCommandThread->volumeCommand((int)stream, volume, (int)output, delayMs);
-}
-
-status_t AudioPolicyService::setStreamOutput(AudioSystem::stream_type stream,
- audio_io_handle_t output)
-{
- sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
- if (af == 0) return PERMISSION_DENIED;
-
- return af->setStreamOutput(stream, output);
-}
-
-status_t AudioPolicyService::moveEffects(int session, audio_io_handle_t srcOutput,
- audio_io_handle_t dstOutput)
-{
- sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
- if (af == 0) return PERMISSION_DENIED;
-
- return af->moveEffects(session, (int)srcOutput, (int)dstOutput);
-}
-
-void AudioPolicyService::setParameters(audio_io_handle_t ioHandle,
- const String8& keyValuePairs,
- int delayMs)
-{
- mAudioCommandThread->parametersCommand((int)ioHandle, keyValuePairs, delayMs);
-}
-
-String8 AudioPolicyService::getParameters(audio_io_handle_t ioHandle, const String8& keys)
-{
- String8 result = AudioSystem::getParameters(ioHandle, keys);
- return result;
-}
-
-status_t AudioPolicyService::startTone(ToneGenerator::tone_type tone,
- AudioSystem::stream_type stream)
-{
- mTonePlaybackThread->startToneCommand(tone, stream);
- return NO_ERROR;
-}
-
-status_t AudioPolicyService::stopTone()
-{
- mTonePlaybackThread->stopToneCommand();
- return NO_ERROR;
-}
-
-status_t AudioPolicyService::setVoiceVolume(float volume, int delayMs)
-{
- return mAudioCommandThread->voiceVolumeCommand(volume, delayMs);
-}
-
// ----------- AudioPolicyService::AudioCommandThread implementation ----------
AudioPolicyService::AudioCommandThread::AudioCommandThread(String8 name)
@@ -859,7 +843,7 @@
}
status_t AudioPolicyService::AudioCommandThread::parametersCommand(int ioHandle,
- const String8& keyValuePairs,
+ const char *keyValuePairs,
int delayMs)
{
status_t status = NO_ERROR;
@@ -868,7 +852,7 @@
command->mCommand = SET_PARAMETERS;
ParametersData *data = new ParametersData();
data->mIO = ioHandle;
- data->mKeyValuePairs = keyValuePairs;
+ data->mKeyValuePairs = String8(keyValuePairs);
command->mParam = data;
if (delayMs == 0) {
command->mWaitStatus = true;
@@ -878,7 +862,7 @@
Mutex::Autolock _l(mLock);
insertCommand_l(command, delayMs);
LOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d",
- keyValuePairs.string(), ioHandle, delayMs);
+ keyValuePairs, ioHandle, delayMs);
mWaitWorkCV.signal();
if (command->mWaitStatus) {
command->mCond.wait(mLock);
@@ -1023,4 +1007,520 @@
mParam);
}
+/******* helpers for the service_ops callbacks defined below *********/
+void AudioPolicyService::setParameters(audio_io_handle_t ioHandle,
+ const char *keyValuePairs,
+ int delayMs)
+{
+ mAudioCommandThread->parametersCommand((int)ioHandle, keyValuePairs,
+ delayMs);
+}
+
+int AudioPolicyService::setStreamVolume(audio_stream_type_t stream,
+ float volume,
+ audio_io_handle_t output,
+ int delayMs)
+{
+ return (int)mAudioCommandThread->volumeCommand((int)stream, volume,
+ (int)output, delayMs);
+}
+
+int AudioPolicyService::startTone(audio_policy_tone_t tone,
+ audio_stream_type_t stream)
+{
+ if (tone != AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION)
+ LOGE("startTone: illegal tone requested (%d)", tone);
+ if (stream != AUDIO_STREAM_VOICE_CALL)
+ LOGE("startTone: illegal stream (%d) requested for tone %d", stream,
+ tone);
+ mTonePlaybackThread->startToneCommand(ToneGenerator::TONE_SUP_CALL_WAITING,
+ AUDIO_STREAM_VOICE_CALL);
+ return 0;
+}
+
+int AudioPolicyService::stopTone()
+{
+ mTonePlaybackThread->stopToneCommand();
+ return 0;
+}
+
+int AudioPolicyService::setVoiceVolume(float volume, int delayMs)
+{
+ return (int)mAudioCommandThread->voiceVolumeCommand(volume, delayMs);
+}
+
+// ----------------------------------------------------------------------------
+// Audio pre-processing configuration
+// ----------------------------------------------------------------------------
+
+const char *AudioPolicyService::kInputSourceNames[AUDIO_SOURCE_CNT -1] = {
+ MIC_SRC_TAG,
+ VOICE_UL_SRC_TAG,
+ VOICE_DL_SRC_TAG,
+ VOICE_CALL_SRC_TAG,
+ CAMCORDER_SRC_TAG,
+ VOICE_REC_SRC_TAG,
+ VOICE_COMM_SRC_TAG
+};
+
+// returns the audio_source_t enum corresponding to the input source name or
+// AUDIO_SOURCE_CNT is no match found
+audio_source_t AudioPolicyService::inputSourceNameToEnum(const char *name)
+{
+ int i;
+ for (i = AUDIO_SOURCE_MIC; i < AUDIO_SOURCE_CNT; i++) {
+ if (strcmp(name, kInputSourceNames[i - AUDIO_SOURCE_MIC]) == 0) {
+ LOGV("inputSourceNameToEnum found source %s %d", name, i);
+ break;
+ }
+ }
+ return (audio_source_t)i;
+}
+
+size_t AudioPolicyService::growParamSize(char *param,
+ size_t size,
+ size_t *curSize,
+ size_t *totSize)
+{
+ // *curSize is at least sizeof(effect_param_t) + 2 * sizeof(int)
+ size_t pos = ((*curSize - 1 ) / size + 1) * size;
+
+ if (pos + size > *totSize) {
+ while (pos + size > *totSize) {
+ *totSize += ((*totSize + 7) / 8) * 4;
+ }
+ param = (char *)realloc(param, *totSize);
+ }
+ *curSize = pos + size;
+ return pos;
+}
+
+size_t AudioPolicyService::readParamValue(cnode *node,
+ char *param,
+ size_t *curSize,
+ size_t *totSize)
+{
+ if (strncmp(node->name, SHORT_TAG, sizeof(SHORT_TAG) + 1) == 0) {
+ size_t pos = growParamSize(param, sizeof(short), curSize, totSize);
+ *(short *)((char *)param + pos) = (short)atoi(node->value);
+ LOGV("readParamValue() reading short %d", *(short *)((char *)param + pos));
+ return sizeof(short);
+ } else if (strncmp(node->name, INT_TAG, sizeof(INT_TAG) + 1) == 0) {
+ size_t pos = growParamSize(param, sizeof(int), curSize, totSize);
+ *(int *)((char *)param + pos) = atoi(node->value);
+ LOGV("readParamValue() reading int %d", *(int *)((char *)param + pos));
+ return sizeof(int);
+ } else if (strncmp(node->name, FLOAT_TAG, sizeof(FLOAT_TAG) + 1) == 0) {
+ size_t pos = growParamSize(param, sizeof(float), curSize, totSize);
+ *(float *)((char *)param + pos) = (float)atof(node->value);
+ LOGV("readParamValue() reading float %f",*(float *)((char *)param + pos));
+ return sizeof(float);
+ } else if (strncmp(node->name, BOOL_TAG, sizeof(BOOL_TAG) + 1) == 0) {
+ size_t pos = growParamSize(param, sizeof(bool), curSize, totSize);
+ if (strncmp(node->value, "false", strlen("false") + 1) == 0) {
+ *(bool *)((char *)param + pos) = false;
+ } else {
+ *(bool *)((char *)param + pos) = true;
+ }
+ LOGV("readParamValue() reading bool %s",*(bool *)((char *)param + pos) ? "true" : "false");
+ return sizeof(bool);
+ } else if (strncmp(node->name, STRING_TAG, sizeof(STRING_TAG) + 1) == 0) {
+ size_t len = strnlen(node->value, EFFECT_STRING_LEN_MAX);
+ if (*curSize + len + 1 > *totSize) {
+ *totSize = *curSize + len + 1;
+ param = (char *)realloc(param, *totSize);
+ }
+ strncpy(param + *curSize, node->value, len);
+ *curSize += len;
+ param[*curSize] = '\0';
+ LOGV("readParamValue() reading string %s", param + *curSize - len);
+ return len;
+ }
+ LOGW("readParamValue() unknown param type %s", node->name);
+ return 0;
+}
+
+effect_param_t *AudioPolicyService::loadEffectParameter(cnode *root)
+{
+ cnode *param;
+ cnode *value;
+ size_t curSize = sizeof(effect_param_t);
+ size_t totSize = sizeof(effect_param_t) + 2 * sizeof(int);
+ effect_param_t *fx_param = (effect_param_t *)malloc(totSize);
+
+ param = config_find(root, PARAM_TAG);
+ value = config_find(root, VALUE_TAG);
+ if (param == NULL && value == NULL) {
+ // try to parse simple parameter form {int int}
+ param = root->first_child;
+ if (param) {
+ // Note: that a pair of random strings is read as 0 0
+ int *ptr = (int *)fx_param->data;
+ int *ptr2 = (int *)((char *)param + sizeof(effect_param_t));
+ LOGW("loadEffectParameter() ptr %p ptr2 %p", ptr, ptr2);
+ *ptr++ = atoi(param->name);
+ *ptr = atoi(param->value);
+ fx_param->psize = sizeof(int);
+ fx_param->vsize = sizeof(int);
+ return fx_param;
+ }
+ }
+ if (param == NULL || value == NULL) {
+ LOGW("loadEffectParameter() invalid parameter description %s", root->name);
+ goto error;
+ }
+
+ fx_param->psize = 0;
+ param = param->first_child;
+ while (param) {
+ LOGV("loadEffectParameter() reading param of type %s", param->name);
+ size_t size = readParamValue(param, (char *)fx_param, &curSize, &totSize);
+ if (size == 0) {
+ goto error;
+ }
+ fx_param->psize += size;
+ param = param->next;
+ }
+
+ // align start of value field on 32 bit boundary
+ curSize = ((curSize - 1 ) / sizeof(int) + 1) * sizeof(int);
+
+ fx_param->vsize = 0;
+ value = value->first_child;
+ while (value) {
+ LOGV("loadEffectParameter() reading value of type %s", value->name);
+ size_t size = readParamValue(value, (char *)fx_param, &curSize, &totSize);
+ if (size == 0) {
+ goto error;
+ }
+ fx_param->vsize += size;
+ value = value->next;
+ }
+
+ return fx_param;
+
+error:
+ delete fx_param;
+ return NULL;
+}
+
+void AudioPolicyService::loadEffectParameters(cnode *root, Vector <effect_param_t *>& params)
+{
+ cnode *node = root->first_child;
+ while (node) {
+ LOGV("loadEffectParameters() loading param %s", node->name);
+ effect_param_t *param = loadEffectParameter(node);
+ if (param == NULL) {
+ node = node->next;
+ continue;
+ }
+ params.add(param);
+ node = node->next;
+ }
+}
+
+AudioPolicyService::InputSourceDesc *AudioPolicyService::loadInputSource(
+ cnode *root,
+ const Vector <EffectDesc *>& effects)
+{
+ cnode *node = root->first_child;
+ if (node == NULL) {
+ LOGW("loadInputSource() empty element %s", root->name);
+ return NULL;
+ }
+ InputSourceDesc *source = new InputSourceDesc();
+ while (node) {
+ size_t i;
+ for (i = 0; i < effects.size(); i++) {
+ if (strncmp(effects[i]->mName, node->name, EFFECT_STRING_LEN_MAX) == 0) {
+ LOGV("loadInputSource() found effect %s in list", node->name);
+ break;
+ }
+ }
+ if (i == effects.size()) {
+ LOGV("loadInputSource() effect %s not in list", node->name);
+ node = node->next;
+ continue;
+ }
+ EffectDesc *effect = new EffectDesc(*effects[i]);
+ loadEffectParameters(node, effect->mParams);
+ LOGV("loadInputSource() adding effect %s uuid %08x", effect->mName, effect->mUuid.timeLow);
+ source->mEffects.add(effect);
+ node = node->next;
+ }
+ if (source->mEffects.size() == 0) {
+ LOGW("loadInputSource() no valid effects found in source %s", root->name);
+ delete source;
+ return NULL;
+ }
+ return source;
+}
+
+status_t AudioPolicyService::loadInputSources(cnode *root, const Vector <EffectDesc *>& effects)
+{
+ cnode *node = config_find(root, PREPROCESSING_TAG);
+ if (node == NULL) {
+ return -ENOENT;
+ }
+ node = node->first_child;
+ while (node) {
+ audio_source_t source = inputSourceNameToEnum(node->name);
+ if (source == AUDIO_SOURCE_CNT) {
+ LOGW("loadInputSources() invalid input source %s", node->name);
+ node = node->next;
+ continue;
+ }
+ LOGV("loadInputSources() loading input source %s", node->name);
+ InputSourceDesc *desc = loadInputSource(node, effects);
+ if (desc == NULL) {
+ node = node->next;
+ continue;
+ }
+ mInputSources.add(source, desc);
+ node = node->next;
+ }
+ return NO_ERROR;
+}
+
+AudioPolicyService::EffectDesc *AudioPolicyService::loadEffect(cnode *root)
+{
+ cnode *node = config_find(root, UUID_TAG);
+ if (node == NULL) {
+ return NULL;
+ }
+ effect_uuid_t uuid;
+ if (AudioEffect::stringToGuid(node->value, &uuid) != NO_ERROR) {
+ LOGW("loadEffect() invalid uuid %s", node->value);
+ return NULL;
+ }
+ EffectDesc *effect = new EffectDesc();
+ effect->mName = strdup(root->name);
+ memcpy(&effect->mUuid, &uuid, sizeof(effect_uuid_t));
+
+ return effect;
+}
+
+status_t AudioPolicyService::loadEffects(cnode *root, Vector <EffectDesc *>& effects)
+{
+ cnode *node = config_find(root, EFFECTS_TAG);
+ if (node == NULL) {
+ return -ENOENT;
+ }
+ node = node->first_child;
+ while (node) {
+ LOGV("loadEffects() loading effect %s", node->name);
+ EffectDesc *effect = loadEffect(node);
+ if (effect == NULL) {
+ node = node->next;
+ continue;
+ }
+ effects.add(effect);
+ node = node->next;
+ }
+ return NO_ERROR;
+}
+
+status_t AudioPolicyService::loadPreProcessorConfig(const char *path)
+{
+ cnode *root;
+ char *data;
+
+ data = (char *)load_file(path, NULL);
+ if (data == NULL) {
+ return -ENODEV;
+ }
+ root = config_node("", "");
+ config_load(root, data);
+
+ Vector <EffectDesc *> effects;
+ loadEffects(root, effects);
+ loadInputSources(root, effects);
+
+ config_free(root);
+ free(root);
+ free(data);
+
+ return NO_ERROR;
+}
+
+/* implementation of the interface to the policy manager */
+extern "C" {
+
+static audio_io_handle_t aps_open_output(void *service,
+ uint32_t *pDevices,
+ uint32_t *pSamplingRate,
+ uint32_t *pFormat,
+ uint32_t *pChannels,
+ uint32_t *pLatencyMs,
+ audio_policy_output_flags_t flags)
+{
+ sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+ if (af == NULL) {
+ LOGW("%s: could not get AudioFlinger", __func__);
+ return 0;
+ }
+
+ return af->openOutput(pDevices, pSamplingRate, pFormat, pChannels,
+ pLatencyMs, flags);
+}
+
+static audio_io_handle_t aps_open_dup_output(void *service,
+ audio_io_handle_t output1,
+ audio_io_handle_t output2)
+{
+ sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+ if (af == NULL) {
+ LOGW("%s: could not get AudioFlinger", __func__);
+ return 0;
+ }
+ return af->openDuplicateOutput(output1, output2);
+}
+
+static int aps_close_output(void *service, audio_io_handle_t output)
+{
+ sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+ if (af == NULL)
+ return PERMISSION_DENIED;
+
+ return af->closeOutput(output);
+}
+
+static int aps_suspend_output(void *service, audio_io_handle_t output)
+{
+ sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+ if (af == NULL) {
+ LOGW("%s: could not get AudioFlinger", __func__);
+ return PERMISSION_DENIED;
+ }
+
+ return af->suspendOutput(output);
+}
+
+static int aps_restore_output(void *service, audio_io_handle_t output)
+{
+ sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+ if (af == NULL) {
+ LOGW("%s: could not get AudioFlinger", __func__);
+ return PERMISSION_DENIED;
+ }
+
+ return af->restoreOutput(output);
+}
+
+static audio_io_handle_t aps_open_input(void *service,
+ uint32_t *pDevices,
+ uint32_t *pSamplingRate,
+ uint32_t *pFormat,
+ uint32_t *pChannels,
+ uint32_t acoustics)
+{
+ sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+ if (af == NULL) {
+ LOGW("%s: could not get AudioFlinger", __func__);
+ return 0;
+ }
+
+ return af->openInput(pDevices, pSamplingRate, pFormat, pChannels,
+ acoustics);
+}
+
+static int aps_close_input(void *service, audio_io_handle_t input)
+{
+ sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+ if (af == NULL)
+ return PERMISSION_DENIED;
+
+ return af->closeInput(input);
+}
+
+static int aps_set_stream_output(void *service, audio_stream_type_t stream,
+ audio_io_handle_t output)
+{
+ sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+ if (af == NULL)
+ return PERMISSION_DENIED;
+
+ return af->setStreamOutput(stream, output);
+}
+
+static int aps_move_effects(void *service, int session,
+ audio_io_handle_t src_output,
+ audio_io_handle_t dst_output)
+{
+ sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+ if (af == NULL)
+ return PERMISSION_DENIED;
+
+ return af->moveEffects(session, (int)src_output, (int)dst_output);
+}
+
+static char * aps_get_parameters(void *service, audio_io_handle_t io_handle,
+ const char *keys)
+{
+ String8 result = AudioSystem::getParameters(io_handle, String8(keys));
+ return strdup(result.string());
+}
+
+static void aps_set_parameters(void *service, audio_io_handle_t io_handle,
+ const char *kv_pairs, int delay_ms)
+{
+ AudioPolicyService *audioPolicyService = (AudioPolicyService *)service;
+
+ audioPolicyService->setParameters(io_handle, kv_pairs, delay_ms);
+}
+
+static int aps_set_stream_volume(void *service, audio_stream_type_t stream,
+ float volume, audio_io_handle_t output,
+ int delay_ms)
+{
+ AudioPolicyService *audioPolicyService = (AudioPolicyService *)service;
+
+ return audioPolicyService->setStreamVolume(stream, volume, output,
+ delay_ms);
+}
+
+static int aps_start_tone(void *service, audio_policy_tone_t tone,
+ audio_stream_type_t stream)
+{
+ AudioPolicyService *audioPolicyService = (AudioPolicyService *)service;
+
+ return audioPolicyService->startTone(tone, stream);
+}
+
+static int aps_stop_tone(void *service)
+{
+ AudioPolicyService *audioPolicyService = (AudioPolicyService *)service;
+
+ return audioPolicyService->stopTone();
+}
+
+static int aps_set_voice_volume(void *service, float volume, int delay_ms)
+{
+ AudioPolicyService *audioPolicyService = (AudioPolicyService *)service;
+
+ return audioPolicyService->setVoiceVolume(volume, delay_ms);
+}
+
+}; // extern "C"
+
+namespace {
+ struct audio_policy_service_ops aps_ops = {
+ open_output : aps_open_output,
+ open_duplicate_output : aps_open_dup_output,
+ close_output : aps_close_output,
+ suspend_output : aps_suspend_output,
+ restore_output : aps_restore_output,
+ open_input : aps_open_input,
+ close_input : aps_close_input,
+ set_stream_volume : aps_set_stream_volume,
+ set_stream_output : aps_set_stream_output,
+ set_parameters : aps_set_parameters,
+ get_parameters : aps_get_parameters,
+ start_tone : aps_start_tone,
+ stop_tone : aps_stop_tone,
+ set_voice_volume : aps_set_voice_volume,
+ move_effects : aps_move_effects,
+ };
+}; // namespace <unnamed>
+
}; // namespace android
diff --git a/services/audioflinger/AudioPolicyService.h b/services/audioflinger/AudioPolicyService.h
index faad893..834b794 100644
--- a/services/audioflinger/AudioPolicyService.h
+++ b/services/audioflinger/AudioPolicyService.h
@@ -17,11 +17,17 @@
#ifndef ANDROID_AUDIOPOLICYSERVICE_H
#define ANDROID_AUDIOPOLICYSERVICE_H
-#include <media/IAudioPolicyService.h>
-#include <hardware_legacy/AudioPolicyInterface.h>
-#include <media/ToneGenerator.h>
+#include <cutils/misc.h>
+#include <cutils/config_utils.h>
#include <utils/Vector.h>
+#include <utils/SortedVector.h>
#include <binder/BinderService.h>
+#include <system/audio.h>
+#include <system/audio_policy.h>
+#include <hardware/audio_policy.h>
+#include <media/IAudioPolicyService.h>
+#include <media/ToneGenerator.h>
+#include <media/AudioEffect.h>
namespace android {
@@ -32,7 +38,7 @@
class AudioPolicyService :
public BinderService<AudioPolicyService>,
public BnAudioPolicyService,
- public AudioPolicyClientInterface,
+// public AudioPolicyClientInterface,
public IBinder::DeathRecipient
{
friend class BinderService<AudioPolicyService>;
@@ -47,56 +53,60 @@
// BnAudioPolicyService (see AudioPolicyInterface for method descriptions)
//
- virtual status_t setDeviceConnectionState(AudioSystem::audio_devices device,
- AudioSystem::device_connection_state state,
+ virtual status_t setDeviceConnectionState(audio_devices_t device,
+ audio_policy_dev_state_t state,
const char *device_address);
- virtual AudioSystem::device_connection_state getDeviceConnectionState(
- AudioSystem::audio_devices device,
+ virtual audio_policy_dev_state_t getDeviceConnectionState(
+ audio_devices_t device,
const char *device_address);
virtual status_t setPhoneState(int state);
virtual status_t setRingerMode(uint32_t mode, uint32_t mask);
- virtual status_t setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config);
- virtual AudioSystem::forced_config getForceUse(AudioSystem::force_use usage);
- virtual audio_io_handle_t getOutput(AudioSystem::stream_type stream,
+ virtual status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config);
+ virtual audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage);
+ virtual audio_io_handle_t getOutput(audio_stream_type_t stream,
uint32_t samplingRate = 0,
- uint32_t format = AudioSystem::FORMAT_DEFAULT,
+ uint32_t format = AUDIO_FORMAT_DEFAULT,
uint32_t channels = 0,
- AudioSystem::output_flags flags =
- AudioSystem::OUTPUT_FLAG_INDIRECT);
+ audio_policy_output_flags_t flags =
+ AUDIO_POLICY_OUTPUT_FLAG_INDIRECT);
virtual status_t startOutput(audio_io_handle_t output,
- AudioSystem::stream_type stream,
+ audio_stream_type_t stream,
int session = 0);
virtual status_t stopOutput(audio_io_handle_t output,
- AudioSystem::stream_type stream,
+ audio_stream_type_t stream,
int session = 0);
virtual void releaseOutput(audio_io_handle_t output);
virtual audio_io_handle_t getInput(int inputSource,
uint32_t samplingRate = 0,
- uint32_t format = AudioSystem::FORMAT_DEFAULT,
+ uint32_t format = AUDIO_FORMAT_DEFAULT,
uint32_t channels = 0,
- AudioSystem::audio_in_acoustics acoustics =
- (AudioSystem::audio_in_acoustics)0);
+ audio_in_acoustics_t acoustics =
+ (audio_in_acoustics_t)0,
+ int audioSession = 0);
virtual status_t startInput(audio_io_handle_t input);
virtual status_t stopInput(audio_io_handle_t input);
virtual void releaseInput(audio_io_handle_t input);
- virtual status_t initStreamVolume(AudioSystem::stream_type stream,
+ virtual status_t initStreamVolume(audio_stream_type_t stream,
int indexMin,
int indexMax);
- virtual status_t setStreamVolumeIndex(AudioSystem::stream_type stream, int index);
- virtual status_t getStreamVolumeIndex(AudioSystem::stream_type stream, int *index);
+ virtual status_t setStreamVolumeIndex(audio_stream_type_t stream, int index);
+ virtual status_t getStreamVolumeIndex(audio_stream_type_t stream, int *index);
- virtual uint32_t getStrategyForStream(AudioSystem::stream_type stream);
- virtual uint32_t getDevicesForStream(AudioSystem::stream_type stream);
+ virtual uint32_t getStrategyForStream(audio_stream_type_t stream);
+ virtual uint32_t getDevicesForStream(audio_stream_type_t stream);
virtual audio_io_handle_t getOutputForEffect(effect_descriptor_t *desc);
virtual status_t registerEffect(effect_descriptor_t *desc,
- audio_io_handle_t output,
+ audio_io_handle_t io,
uint32_t strategy,
int session,
int id);
virtual status_t unregisterEffect(int id);
virtual bool isStreamActive(int stream, uint32_t inPastMs = 0) const;
+ virtual status_t queryDefaultPreProcessing(int audioSession,
+ effect_descriptor_t *descriptors,
+ uint32_t *count);
virtual status_t onTransact(
uint32_t code,
const Parcel& data,
@@ -107,40 +117,21 @@
virtual void binderDied(const wp<IBinder>& who);
//
- // AudioPolicyClientInterface
+ // Helpers for the struct audio_policy_service_ops implementation.
+ // This is used by the audio policy manager for certain operations that
+ // are implemented by the policy service.
//
- virtual audio_io_handle_t openOutput(uint32_t *pDevices,
- uint32_t *pSamplingRate,
- uint32_t *pFormat,
- uint32_t *pChannels,
- uint32_t *pLatencyMs,
- AudioSystem::output_flags flags);
- virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1,
- audio_io_handle_t output2);
- virtual status_t closeOutput(audio_io_handle_t output);
- virtual status_t suspendOutput(audio_io_handle_t output);
- virtual status_t restoreOutput(audio_io_handle_t output);
- virtual audio_io_handle_t openInput(uint32_t *pDevices,
- uint32_t *pSamplingRate,
- uint32_t *pFormat,
- uint32_t *pChannels,
- uint32_t acoustics);
- virtual status_t closeInput(audio_io_handle_t input);
- virtual status_t setStreamVolume(AudioSystem::stream_type stream,
+ virtual void setParameters(audio_io_handle_t ioHandle,
+ const char *keyValuePairs,
+ int delayMs);
+
+ virtual status_t setStreamVolume(audio_stream_type_t stream,
float volume,
audio_io_handle_t output,
int delayMs = 0);
- virtual status_t setStreamOutput(AudioSystem::stream_type stream, audio_io_handle_t output);
- virtual void setParameters(audio_io_handle_t ioHandle,
- const String8& keyValuePairs,
- int delayMs = 0);
- virtual String8 getParameters(audio_io_handle_t ioHandle, const String8& keys);
- virtual status_t startTone(ToneGenerator::tone_type tone, AudioSystem::stream_type stream);
+ virtual status_t startTone(audio_policy_tone_t tone, audio_stream_type_t stream);
virtual status_t stopTone();
virtual status_t setVoiceVolume(float volume, int delayMs = 0);
- virtual status_t moveEffects(int session,
- audio_io_handle_t srcOutput,
- audio_io_handle_t dstOutput);
private:
AudioPolicyService();
@@ -180,7 +171,7 @@
void startToneCommand(int type = 0, int stream = 0);
void stopToneCommand();
status_t volumeCommand(int stream, float volume, int output, int delayMs = 0);
- status_t parametersCommand(int ioHandle, const String8& keyValuePairs, int delayMs = 0);
+ status_t parametersCommand(int ioHandle, const char *keyValuePairs, int delayMs = 0);
status_t voiceVolumeCommand(float volume, int delayMs = 0);
void insertCommand_l(AudioCommand *command, int delayMs = 0);
@@ -234,15 +225,63 @@
String8 mName; // string used by wake lock fo delayed commands
};
+ class EffectDesc {
+ public:
+ EffectDesc() {}
+ virtual ~EffectDesc() {}
+ char *mName;
+ effect_uuid_t mUuid;
+ Vector <effect_param_t *> mParams;
+ };
+
+ class InputSourceDesc {
+ public:
+ InputSourceDesc() {}
+ virtual ~InputSourceDesc() {}
+ Vector <EffectDesc *> mEffects;
+ };
+
+
+ class InputDesc {
+ public:
+ InputDesc() {}
+ virtual ~InputDesc() {}
+ int mSessionId;
+ Vector< sp<AudioEffect> >mEffects;
+ };
+
+ static const char *kInputSourceNames[AUDIO_SOURCE_CNT -1];
+
+ void setPreProcessorEnabled(InputDesc *inputDesc, bool enabled);
+ status_t loadPreProcessorConfig(const char *path);
+ status_t loadEffects(cnode *root, Vector <EffectDesc *>& effects);
+ EffectDesc *loadEffect(cnode *root);
+ status_t loadInputSources(cnode *root, const Vector <EffectDesc *>& effects);
+ audio_source_t inputSourceNameToEnum(const char *name);
+ InputSourceDesc *loadInputSource(cnode *root, const Vector <EffectDesc *>& effects);
+ void loadEffectParameters(cnode *root, Vector <effect_param_t *>& params);
+ effect_param_t *loadEffectParameter(cnode *root);
+ size_t readParamValue(cnode *node,
+ char *param,
+ size_t *curSize,
+ size_t *totSize);
+ size_t growParamSize(char *param,
+ size_t size,
+ size_t *curSize,
+ size_t *totSize);
+
// Internal dump utilities.
status_t dumpPermissionDenial(int fd);
mutable Mutex mLock; // prevents concurrent access to AudioPolicy manager functions changing
// device connection state or routing
- AudioPolicyInterface* mpPolicyManager; // the platform specific policy manager
sp <AudioCommandThread> mAudioCommandThread; // audio commands thread
sp <AudioCommandThread> mTonePlaybackThread; // tone playback thread
+ struct audio_policy_device *mpAudioPolicyDev;
+ struct audio_policy *mpAudioPolicy;
+ KeyedVector< audio_source_t, InputSourceDesc* > mInputSources;
+ KeyedVector< audio_io_handle_t, InputDesc* > mInputs;
};
}; // namespace android
diff --git a/services/audioflinger/AudioResamplerCubic.cpp b/services/audioflinger/AudioResamplerCubic.cpp
index 1d247bd..4d721f6 100644
--- a/services/audioflinger/AudioResamplerCubic.cpp
+++ b/services/audioflinger/AudioResamplerCubic.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#define LOG_TAG "AudioSRC"
+
#include <stdint.h>
#include <string.h>
#include <sys/types.h>
@@ -22,8 +24,6 @@
#include "AudioResampler.h"
#include "AudioResamplerCubic.h"
-#define LOG_TAG "AudioSRC"
-
namespace android {
// ----------------------------------------------------------------------------
diff --git a/services/camera/libcameraservice/Android.mk b/services/camera/libcameraservice/Android.mk
index b52fc69..e35435e 100644
--- a/services/camera/libcameraservice/Android.mk
+++ b/services/camera/libcameraservice/Android.mk
@@ -1,38 +1,5 @@
LOCAL_PATH:= $(call my-dir)
-# Set USE_CAMERA_STUB if you don't want to use the hardware camera.
-
-# force these builds to use camera stub only
-ifneq ($(filter sooner generic sim,$(TARGET_DEVICE)),)
- USE_CAMERA_STUB:=true
-endif
-
-ifeq ($(USE_CAMERA_STUB),)
- USE_CAMERA_STUB:=false
-endif
-
-ifeq ($(USE_CAMERA_STUB),true)
-#
-# libcamerastub
-#
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- CameraHardwareStub.cpp \
- FakeCamera.cpp
-
-LOCAL_MODULE:= libcamerastub
-
-ifeq ($(TARGET_SIMULATOR),true)
-LOCAL_CFLAGS += -DSINGLE_PROCESS
-endif
-
-LOCAL_SHARED_LIBRARIES:= libui
-
-include $(BUILD_STATIC_LIBRARY)
-endif # USE_CAMERA_STUB
-
#
# libcameraservice
#
@@ -49,19 +16,9 @@
libcutils \
libmedia \
libcamera_client \
- libsurfaceflinger_client \
- libgui
+ libgui \
+ libhardware
LOCAL_MODULE:= libcameraservice
-ifeq ($(TARGET_SIMULATOR),true)
-LOCAL_CFLAGS += -DSINGLE_PROCESS
-endif
-
-ifeq ($(USE_CAMERA_STUB), true)
-LOCAL_STATIC_LIBRARIES += libcamerastub
-else
-LOCAL_SHARED_LIBRARIES += libcamera
-endif
-
include $(BUILD_SHARED_LIBRARY)
diff --git a/services/camera/libcameraservice/CameraHardwareInterface.h b/services/camera/libcameraservice/CameraHardwareInterface.h
new file mode 100644
index 0000000..31544b3
--- /dev/null
+++ b/services/camera/libcameraservice/CameraHardwareInterface.h
@@ -0,0 +1,682 @@
+/*
+ * Copyright (C) 2008 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 ANDROID_HARDWARE_CAMERA_HARDWARE_INTERFACE_H
+#define ANDROID_HARDWARE_CAMERA_HARDWARE_INTERFACE_H
+
+#include <binder/IMemory.h>
+#include <binder/MemoryBase.h>
+#include <binder/MemoryHeapBase.h>
+#include <utils/RefBase.h>
+#include <surfaceflinger/ISurface.h>
+#include <ui/android_native_buffer.h>
+#include <ui/GraphicBuffer.h>
+#include <camera/Camera.h>
+#include <camera/CameraParameters.h>
+#include <system/window.h>
+#include <hardware/camera.h>
+
+namespace android {
+
+typedef void (*notify_callback)(int32_t msgType,
+ int32_t ext1,
+ int32_t ext2,
+ void* user);
+
+typedef void (*data_callback)(int32_t msgType,
+ const sp<IMemory> &dataPtr,
+ camera_frame_metadata_t *metadata,
+ void* user);
+
+typedef void (*data_callback_timestamp)(nsecs_t timestamp,
+ int32_t msgType,
+ const sp<IMemory> &dataPtr,
+ void *user);
+
+/**
+ * CameraHardwareInterface.h defines the interface to the
+ * camera hardware abstraction layer, used for setting and getting
+ * parameters, live previewing, and taking pictures.
+ *
+ * It is a referenced counted interface with RefBase as its base class.
+ * CameraService calls openCameraHardware() to retrieve a strong pointer to the
+ * instance of this interface and may be called multiple times. The
+ * following steps describe a typical sequence:
+ *
+ * -# After CameraService calls openCameraHardware(), getParameters() and
+ * setParameters() are used to initialize the camera instance.
+ * CameraService calls getPreviewHeap() to establish access to the
+ * preview heap so it can be registered with SurfaceFlinger for
+ * efficient display updating while in preview mode.
+ * -# startPreview() is called. The camera instance then periodically
+ * sends the message CAMERA_MSG_PREVIEW_FRAME (if enabled) each time
+ * a new preview frame is available. If data callback code needs to use
+ * this memory after returning, it must copy the data.
+ *
+ * Prior to taking a picture, CameraService calls autofocus(). When auto
+ * focusing has completed, the camera instance sends a CAMERA_MSG_FOCUS notification,
+ * which informs the application whether focusing was successful. The camera instance
+ * only sends this message once and it is up to the application to call autoFocus()
+ * again if refocusing is desired.
+ *
+ * CameraService calls takePicture() to request the camera instance take a
+ * picture. At this point, if a shutter, postview, raw, and/or compressed callback
+ * is desired, the corresponding message must be enabled. As with CAMERA_MSG_PREVIEW_FRAME,
+ * any memory provided in a data callback must be copied if it's needed after returning.
+ */
+
+class CameraHardwareInterface : public virtual RefBase {
+public:
+ CameraHardwareInterface(hw_module_t *module, const char *name)
+ {
+ mDevice = 0;
+ mName = name;
+ LOGI("Opening camera %s, this %p", name, this);
+ int rc = module->methods->open(module, name,
+ (hw_device_t **)&mDevice);
+ if (rc != OK)
+ LOGE("Could not open camera %s: %d", name, rc);
+ initHalPreviewWindow();
+ }
+
+ ~CameraHardwareInterface()
+ {
+ LOGI("Destroying camera %s", mName.string());
+ int rc = mDevice->common.close(&mDevice->common);
+ if (rc != OK)
+ LOGE("Could not close camera %s: %d", mName.string(), rc);
+ }
+
+ /** Set the ANativeWindow to which preview frames are sent */
+ status_t setPreviewWindow(const sp<ANativeWindow>& buf)
+ {
+ LOGV("%s(%s) buf %p", __FUNCTION__, mName.string(), buf.get());
+
+ if (mDevice->ops->set_preview_window) {
+ mPreviewWindow = buf;
+ mHalPreviewWindow.user = this;
+ LOGV("%s &mHalPreviewWindow %p mHalPreviewWindow.user %p", __FUNCTION__,
+ &mHalPreviewWindow, mHalPreviewWindow.user);
+ return mDevice->ops->set_preview_window(mDevice,
+ buf.get() ? &mHalPreviewWindow.nw : 0);
+ }
+ return INVALID_OPERATION;
+ }
+
+ /** Set the notification and data callbacks */
+ void setCallbacks(notify_callback notify_cb,
+ data_callback data_cb,
+ data_callback_timestamp data_cb_timestamp,
+ void* user)
+ {
+ mNotifyCb = notify_cb;
+ mDataCb = data_cb;
+ mDataCbTimestamp = data_cb_timestamp;
+ mCbUser = user;
+
+ LOGV("%s(%s)", __FUNCTION__, mName.string());
+
+ if (mDevice->ops->set_callbacks) {
+ mDevice->ops->set_callbacks(mDevice,
+ __notify_cb,
+ __data_cb,
+ __data_cb_timestamp,
+ __get_memory,
+ this);
+ }
+ }
+
+ /**
+ * The following three functions all take a msgtype,
+ * which is a bitmask of the messages defined in
+ * include/ui/Camera.h
+ */
+
+ /**
+ * Enable a message, or set of messages.
+ */
+ void enableMsgType(int32_t msgType)
+ {
+ LOGV("%s(%s)", __FUNCTION__, mName.string());
+ if (mDevice->ops->enable_msg_type)
+ mDevice->ops->enable_msg_type(mDevice, msgType);
+ }
+
+ /**
+ * Disable a message, or a set of messages.
+ *
+ * Once received a call to disableMsgType(CAMERA_MSG_VIDEO_FRAME), camera hal
+ * should not rely on its client to call releaseRecordingFrame() to release
+ * video recording frames sent out by the cameral hal before and after the
+ * disableMsgType(CAMERA_MSG_VIDEO_FRAME) call. Camera hal clients must not
+ * modify/access any video recording frame after calling
+ * disableMsgType(CAMERA_MSG_VIDEO_FRAME).
+ */
+ void disableMsgType(int32_t msgType)
+ {
+ LOGV("%s(%s)", __FUNCTION__, mName.string());
+ if (mDevice->ops->disable_msg_type)
+ mDevice->ops->disable_msg_type(mDevice, msgType);
+ }
+
+ /**
+ * Query whether a message, or a set of messages, is enabled.
+ * Note that this is operates as an AND, if any of the messages
+ * queried are off, this will return false.
+ */
+ int msgTypeEnabled(int32_t msgType)
+ {
+ LOGV("%s(%s)", __FUNCTION__, mName.string());
+ if (mDevice->ops->msg_type_enabled)
+ return mDevice->ops->msg_type_enabled(mDevice, msgType);
+ return false;
+ }
+
+ /**
+ * Start preview mode.
+ */
+ status_t startPreview()
+ {
+ LOGV("%s(%s)", __FUNCTION__, mName.string());
+ if (mDevice->ops->start_preview)
+ return mDevice->ops->start_preview(mDevice);
+ return INVALID_OPERATION;
+ }
+
+ /**
+ * Stop a previously started preview.
+ */
+ void stopPreview()
+ {
+ LOGV("%s(%s)", __FUNCTION__, mName.string());
+ if (mDevice->ops->stop_preview)
+ mDevice->ops->stop_preview(mDevice);
+ }
+
+ /**
+ * Returns true if preview is enabled.
+ */
+ int previewEnabled()
+ {
+ LOGV("%s(%s)", __FUNCTION__, mName.string());
+ if (mDevice->ops->preview_enabled)
+ return mDevice->ops->preview_enabled(mDevice);
+ return false;
+ }
+
+ /**
+ * Request the camera hal to store meta data or real YUV data in
+ * the video buffers send out via CAMERA_MSG_VIDEO_FRRAME for a
+ * recording session. If it is not called, the default camera
+ * hal behavior is to store real YUV data in the video buffers.
+ *
+ * This method should be called before startRecording() in order
+ * to be effective.
+ *
+ * If meta data is stored in the video buffers, it is up to the
+ * receiver of the video buffers to interpret the contents and
+ * to find the actual frame data with the help of the meta data
+ * in the buffer. How this is done is outside of the scope of
+ * this method.
+ *
+ * Some camera hal may not support storing meta data in the video
+ * buffers, but all camera hal should support storing real YUV data
+ * in the video buffers. If the camera hal does not support storing
+ * the meta data in the video buffers when it is requested to do
+ * do, INVALID_OPERATION must be returned. It is very useful for
+ * the camera hal to pass meta data rather than the actual frame
+ * data directly to the video encoder, since the amount of the
+ * uncompressed frame data can be very large if video size is large.
+ *
+ * @param enable if true to instruct the camera hal to store
+ * meta data in the video buffers; false to instruct
+ * the camera hal to store real YUV data in the video
+ * buffers.
+ *
+ * @return OK on success.
+ */
+
+ status_t storeMetaDataInBuffers(int enable)
+ {
+ LOGV("%s(%s)", __FUNCTION__, mName.string());
+ if (mDevice->ops->store_meta_data_in_buffers)
+ return mDevice->ops->store_meta_data_in_buffers(mDevice, enable);
+ return enable ? INVALID_OPERATION: OK;
+ }
+
+ /**
+ * Start record mode. When a record image is available a CAMERA_MSG_VIDEO_FRAME
+ * message is sent with the corresponding frame. Every record frame must be released
+ * by a cameral hal client via releaseRecordingFrame() before the client calls
+ * disableMsgType(CAMERA_MSG_VIDEO_FRAME). After the client calls
+ * disableMsgType(CAMERA_MSG_VIDEO_FRAME), it is camera hal's responsibility
+ * to manage the life-cycle of the video recording frames, and the client must
+ * not modify/access any video recording frames.
+ */
+ status_t startRecording()
+ {
+ LOGV("%s(%s)", __FUNCTION__, mName.string());
+ if (mDevice->ops->start_recording)
+ return mDevice->ops->start_recording(mDevice);
+ return INVALID_OPERATION;
+ }
+
+ /**
+ * Stop a previously started recording.
+ */
+ void stopRecording()
+ {
+ LOGV("%s(%s)", __FUNCTION__, mName.string());
+ if (mDevice->ops->stop_recording)
+ mDevice->ops->stop_recording(mDevice);
+ }
+
+ /**
+ * Returns true if recording is enabled.
+ */
+ int recordingEnabled()
+ {
+ LOGV("%s(%s)", __FUNCTION__, mName.string());
+ if (mDevice->ops->recording_enabled)
+ return mDevice->ops->recording_enabled(mDevice);
+ return false;
+ }
+
+ /**
+ * Release a record frame previously returned by CAMERA_MSG_VIDEO_FRAME.
+ *
+ * It is camera hal client's responsibility to release video recording
+ * frames sent out by the camera hal before the camera hal receives
+ * a call to disableMsgType(CAMERA_MSG_VIDEO_FRAME). After it receives
+ * the call to disableMsgType(CAMERA_MSG_VIDEO_FRAME), it is camera hal's
+ * responsibility of managing the life-cycle of the video recording
+ * frames.
+ */
+ void releaseRecordingFrame(const sp<IMemory>& mem)
+ {
+ LOGV("%s(%s)", __FUNCTION__, mName.string());
+ if (mDevice->ops->release_recording_frame) {
+ ssize_t offset;
+ size_t size;
+ sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
+ void *data = ((uint8_t *)heap->base()) + offset;
+ return mDevice->ops->release_recording_frame(mDevice, data);
+ }
+ }
+
+ /**
+ * Start auto focus, the notification callback routine is called
+ * with CAMERA_MSG_FOCUS once when focusing is complete. autoFocus()
+ * will be called again if another auto focus is needed.
+ */
+ status_t autoFocus()
+ {
+ LOGV("%s(%s)", __FUNCTION__, mName.string());
+ if (mDevice->ops->auto_focus)
+ return mDevice->ops->auto_focus(mDevice);
+ return INVALID_OPERATION;
+ }
+
+ /**
+ * Cancels auto-focus function. If the auto-focus is still in progress,
+ * this function will cancel it. Whether the auto-focus is in progress
+ * or not, this function will return the focus position to the default.
+ * If the camera does not support auto-focus, this is a no-op.
+ */
+ status_t cancelAutoFocus()
+ {
+ LOGV("%s(%s)", __FUNCTION__, mName.string());
+ if (mDevice->ops->cancel_auto_focus)
+ return mDevice->ops->cancel_auto_focus(mDevice);
+ return INVALID_OPERATION;
+ }
+
+ /**
+ * Take a picture.
+ */
+ status_t takePicture()
+ {
+ LOGV("%s(%s)", __FUNCTION__, mName.string());
+ if (mDevice->ops->take_picture)
+ return mDevice->ops->take_picture(mDevice);
+ return INVALID_OPERATION;
+ }
+
+ /**
+ * Cancel a picture that was started with takePicture. Calling this
+ * method when no picture is being taken is a no-op.
+ */
+ status_t cancelPicture()
+ {
+ LOGV("%s(%s)", __FUNCTION__, mName.string());
+ if (mDevice->ops->cancel_picture)
+ return mDevice->ops->cancel_picture(mDevice);
+ return INVALID_OPERATION;
+ }
+
+ /**
+ * Set the camera parameters. This returns BAD_VALUE if any parameter is
+ * invalid or not supported. */
+ status_t setParameters(const CameraParameters ¶ms)
+ {
+ LOGV("%s(%s)", __FUNCTION__, mName.string());
+ if (mDevice->ops->set_parameters)
+ return mDevice->ops->set_parameters(mDevice,
+ params.flatten().string());
+ return INVALID_OPERATION;
+ }
+
+ /** Return the camera parameters. */
+ CameraParameters getParameters() const
+ {
+ LOGV("%s(%s)", __FUNCTION__, mName.string());
+ CameraParameters parms;
+ if (mDevice->ops->get_parameters) {
+ char *temp = mDevice->ops->get_parameters(mDevice);
+ String8 str_parms(temp);
+ if (mDevice->ops->put_parameters)
+ mDevice->ops->put_parameters(mDevice, temp);
+ else
+ free(temp);
+ parms.unflatten(str_parms);
+ }
+ return parms;
+ }
+
+ /**
+ * Send command to camera driver.
+ */
+ status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
+ {
+ LOGV("%s(%s)", __FUNCTION__, mName.string());
+ if (mDevice->ops->send_command)
+ return mDevice->ops->send_command(mDevice, cmd, arg1, arg2);
+ return INVALID_OPERATION;
+ }
+
+ /**
+ * Release the hardware resources owned by this object. Note that this is
+ * *not* done in the destructor.
+ */
+ void release() {
+ LOGV("%s(%s)", __FUNCTION__, mName.string());
+ if (mDevice->ops->release)
+ mDevice->ops->release(mDevice);
+ }
+
+ /**
+ * Dump state of the camera hardware
+ */
+ status_t dump(int fd, const Vector<String16>& args) const
+ {
+ LOGV("%s(%s)", __FUNCTION__, mName.string());
+ if (mDevice->ops->dump)
+ return mDevice->ops->dump(mDevice, fd);
+ return OK; // It's fine if the HAL doesn't implement dump()
+ }
+
+private:
+ camera_device_t *mDevice;
+ String8 mName;
+
+ static void __notify_cb(int32_t msg_type, int32_t ext1,
+ int32_t ext2, void *user)
+ {
+ LOGV("%s", __FUNCTION__);
+ CameraHardwareInterface *__this =
+ static_cast<CameraHardwareInterface *>(user);
+ __this->mNotifyCb(msg_type, ext1, ext2, __this->mCbUser);
+ }
+
+ static void __data_cb(int32_t msg_type,
+ const camera_memory_t *data, unsigned int index,
+ camera_frame_metadata_t *metadata,
+ void *user)
+ {
+ LOGV("%s", __FUNCTION__);
+ CameraHardwareInterface *__this =
+ static_cast<CameraHardwareInterface *>(user);
+ sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory *>(data->handle));
+ if (index >= mem->mNumBufs) {
+ LOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
+ index, mem->mNumBufs);
+ return;
+ }
+ __this->mDataCb(msg_type, mem->mBuffers[index], metadata, __this->mCbUser);
+ }
+
+ static void __data_cb_timestamp(nsecs_t timestamp, int32_t msg_type,
+ const camera_memory_t *data, unsigned index,
+ void *user)
+ {
+ LOGV("%s", __FUNCTION__);
+ CameraHardwareInterface *__this =
+ static_cast<CameraHardwareInterface *>(user);
+ // Start refcounting the heap object from here on. When the clients
+ // drop all references, it will be destroyed (as well as the enclosed
+ // MemoryHeapBase.
+ sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory *>(data->handle));
+ if (index >= mem->mNumBufs) {
+ LOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
+ index, mem->mNumBufs);
+ return;
+ }
+ __this->mDataCbTimestamp(timestamp, msg_type, mem->mBuffers[index], __this->mCbUser);
+ }
+
+ // This is a utility class that combines a MemoryHeapBase and a MemoryBase
+ // in one. Since we tend to use them in a one-to-one relationship, this is
+ // handy.
+
+ class CameraHeapMemory : public RefBase {
+ public:
+ CameraHeapMemory(int fd, size_t buf_size, uint_t num_buffers = 1) :
+ mBufSize(buf_size),
+ mNumBufs(num_buffers)
+ {
+ mHeap = new MemoryHeapBase(fd, buf_size * num_buffers);
+ commonInitialization();
+ }
+
+ CameraHeapMemory(size_t buf_size, uint_t num_buffers = 1) :
+ mBufSize(buf_size),
+ mNumBufs(num_buffers)
+ {
+ mHeap = new MemoryHeapBase(buf_size * num_buffers);
+ commonInitialization();
+ }
+
+ void commonInitialization()
+ {
+ handle.data = mHeap->base();
+ handle.size = mBufSize * mNumBufs;
+ handle.handle = this;
+
+ mBuffers = new sp<MemoryBase>[mNumBufs];
+ for (uint_t i = 0; i < mNumBufs; i++)
+ mBuffers[i] = new MemoryBase(mHeap,
+ i * mBufSize,
+ mBufSize);
+
+ handle.release = __put_memory;
+ }
+
+ virtual ~CameraHeapMemory()
+ {
+ delete [] mBuffers;
+ }
+
+ size_t mBufSize;
+ uint_t mNumBufs;
+ sp<MemoryHeapBase> mHeap;
+ sp<MemoryBase> *mBuffers;
+
+ camera_memory_t handle;
+ };
+
+ static camera_memory_t* __get_memory(int fd, size_t buf_size, uint_t num_bufs,
+ void *user __attribute__((unused)))
+ {
+ CameraHeapMemory *mem;
+ if (fd < 0)
+ mem = new CameraHeapMemory(buf_size, num_bufs);
+ else
+ mem = new CameraHeapMemory(fd, buf_size, num_bufs);
+ mem->incStrong(mem);
+ return &mem->handle;
+ }
+
+ static void __put_memory(camera_memory_t *data)
+ {
+ if (!data)
+ return;
+
+ CameraHeapMemory *mem = static_cast<CameraHeapMemory *>(data->handle);
+ mem->decStrong(mem);
+ }
+
+ static ANativeWindow *__to_anw(void *user)
+ {
+ CameraHardwareInterface *__this =
+ reinterpret_cast<CameraHardwareInterface *>(user);
+ return __this->mPreviewWindow.get();
+ }
+#define anw(n) __to_anw(((struct camera_preview_window *)n)->user)
+
+ static int __dequeue_buffer(struct preview_stream_ops* w,
+ buffer_handle_t** buffer, int *stride)
+ {
+ int rc;
+ ANativeWindow *a = anw(w);
+ ANativeWindowBuffer* anb;
+ rc = a->dequeueBuffer(a, &anb);
+ if (!rc) {
+ *buffer = &anb->handle;
+ *stride = anb->stride;
+ }
+ return rc;
+ }
+
+#ifndef container_of
+#define container_of(ptr, type, member) ({ \
+ const typeof(((type *) 0)->member) *__mptr = (ptr); \
+ (type *) ((char *) __mptr - (char *)(&((type *)0)->member)); })
+#endif
+
+ static int __lock_buffer(struct preview_stream_ops* w,
+ buffer_handle_t* buffer)
+ {
+ ANativeWindow *a = anw(w);
+ return a->lockBuffer(a,
+ container_of(buffer, ANativeWindowBuffer, handle));
+ }
+
+ static int __enqueue_buffer(struct preview_stream_ops* w,
+ buffer_handle_t* buffer)
+ {
+ ANativeWindow *a = anw(w);
+ return a->queueBuffer(a,
+ container_of(buffer, ANativeWindowBuffer, handle));
+ }
+
+ static int __cancel_buffer(struct preview_stream_ops* w,
+ buffer_handle_t* buffer)
+ {
+ ANativeWindow *a = anw(w);
+ return a->cancelBuffer(a,
+ container_of(buffer, ANativeWindowBuffer, handle));
+ }
+
+ static int __set_buffer_count(struct preview_stream_ops* w, int count)
+ {
+ ANativeWindow *a = anw(w);
+ return native_window_set_buffer_count(a, count);
+ }
+
+ static int __set_buffers_geometry(struct preview_stream_ops* w,
+ int width, int height, int format)
+ {
+ ANativeWindow *a = anw(w);
+ return native_window_set_buffers_geometry(a,
+ width, height, format);
+ }
+
+ static int __set_crop(struct preview_stream_ops *w,
+ int left, int top, int right, int bottom)
+ {
+ ANativeWindow *a = anw(w);
+ android_native_rect_t crop;
+ crop.left = left;
+ crop.top = top;
+ crop.right = right;
+ crop.bottom = bottom;
+ return native_window_set_crop(a, &crop);
+ }
+
+ static int __set_usage(struct preview_stream_ops* w, int usage)
+ {
+ ANativeWindow *a = anw(w);
+ return native_window_set_usage(a, usage);
+ }
+
+ static int __set_swap_interval(struct preview_stream_ops *w, int interval)
+ {
+ ANativeWindow *a = anw(w);
+ return a->setSwapInterval(a, interval);
+ }
+
+ static int __get_min_undequeued_buffer_count(
+ const struct preview_stream_ops *w,
+ int *count)
+ {
+ ANativeWindow *a = anw(w);
+ return a->query(a, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, count);
+ }
+
+ void initHalPreviewWindow()
+ {
+ mHalPreviewWindow.nw.cancel_buffer = __cancel_buffer;
+ mHalPreviewWindow.nw.lock_buffer = __lock_buffer;
+ mHalPreviewWindow.nw.dequeue_buffer = __dequeue_buffer;
+ mHalPreviewWindow.nw.enqueue_buffer = __enqueue_buffer;
+ mHalPreviewWindow.nw.set_buffer_count = __set_buffer_count;
+ mHalPreviewWindow.nw.set_buffers_geometry = __set_buffers_geometry;
+ mHalPreviewWindow.nw.set_crop = __set_crop;
+ mHalPreviewWindow.nw.set_usage = __set_usage;
+ mHalPreviewWindow.nw.set_swap_interval = __set_swap_interval;
+
+ mHalPreviewWindow.nw.get_min_undequeued_buffer_count =
+ __get_min_undequeued_buffer_count;
+ }
+
+ sp<ANativeWindow> mPreviewWindow;
+
+ struct camera_preview_window {
+ struct preview_stream_ops nw;
+ void *user;
+ };
+
+ struct camera_preview_window mHalPreviewWindow;
+
+ notify_callback mNotifyCb;
+ data_callback mDataCb;
+ data_callback_timestamp mDataCbTimestamp;
+ void *mCbUser;
+};
+
+}; // namespace android
+
+#endif
diff --git a/services/camera/libcameraservice/CameraHardwareStub.cpp b/services/camera/libcameraservice/CameraHardwareStub.cpp
index 07b5a37..863f19e 100644
--- a/services/camera/libcameraservice/CameraHardwareStub.cpp
+++ b/services/camera/libcameraservice/CameraHardwareStub.cpp
@@ -180,7 +180,7 @@
// Notify the client of a new frame.
if (mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME)
- mDataCb(CAMERA_MSG_PREVIEW_FRAME, buffer, mCallbackCookie);
+ mDataCb(CAMERA_MSG_PREVIEW_FRAME, buffer, NULL, mCallbackCookie);
// Advance the buffer pointer.
mCurrentPreviewFrame = (mCurrentPreviewFrame + 1) % kBufferCount;
@@ -290,14 +290,14 @@
sp<MemoryBase> mem = new MemoryBase(mRawHeap, 0, w * h * 3 / 2);
FakeCamera cam(w, h);
cam.getNextFrameAsYuv420((uint8_t *)mRawHeap->base());
- mDataCb(CAMERA_MSG_RAW_IMAGE, mem, mCallbackCookie);
+ mDataCb(CAMERA_MSG_RAW_IMAGE, mem, NULL, mCallbackCookie);
}
if (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE) {
sp<MemoryHeapBase> heap = new MemoryHeapBase(kCannedJpegSize);
sp<MemoryBase> mem = new MemoryBase(heap, 0, kCannedJpegSize);
memcpy(heap->base(), kCannedJpeg, kCannedJpegSize);
- mDataCb(CAMERA_MSG_COMPRESSED_IMAGE, mem, mCallbackCookie);
+ mDataCb(CAMERA_MSG_COMPRESSED_IMAGE, mem, NULL, mCallbackCookie);
}
return NO_ERROR;
}
diff --git a/services/camera/libcameraservice/CameraHardwareStub.h b/services/camera/libcameraservice/CameraHardwareStub.h
index 9b66a76..c6d8756 100644
--- a/services/camera/libcameraservice/CameraHardwareStub.h
+++ b/services/camera/libcameraservice/CameraHardwareStub.h
@@ -73,14 +73,7 @@
CameraHardwareStub* mHardware;
public:
PreviewThread(CameraHardwareStub* hw) :
-#ifdef SINGLE_PROCESS
- // In single process mode this thread needs to be a java thread,
- // since we won't be calling through the binder.
- Thread(true),
-#else
- Thread(false),
-#endif
- mHardware(hw) { }
+ Thread(false), mHardware(hw) { }
virtual void onFirstRef() {
run("CameraPreviewThread", PRIORITY_URGENT_DISPLAY);
}
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index a09e16b..e193be0 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -16,6 +16,7 @@
*/
#define LOG_TAG "CameraService"
+//#define LOG_NDEBUG 0
#include <stdio.h>
#include <sys/types.h>
@@ -37,6 +38,7 @@
#include <utils/String16.h>
#include "CameraService.h"
+#include "CameraHardwareInterface.h"
namespace android {
@@ -69,24 +71,34 @@
static CameraService *gCameraService;
CameraService::CameraService()
-:mSoundRef(0)
+:mSoundRef(0), mModule(0)
{
LOGI("CameraService started (pid=%d)", getpid());
-
- mNumberOfCameras = HAL_getNumberOfCameras();
- if (mNumberOfCameras > MAX_CAMERAS) {
- LOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
- mNumberOfCameras, MAX_CAMERAS);
- mNumberOfCameras = MAX_CAMERAS;
- }
-
- for (int i = 0; i < mNumberOfCameras; i++) {
- setCameraFree(i);
- }
-
gCameraService = this;
}
+void CameraService::onFirstRef()
+{
+ BnCameraService::onFirstRef();
+
+ if (hw_get_module(CAMERA_HARDWARE_MODULE_ID,
+ (const hw_module_t **)&mModule) < 0) {
+ LOGE("Could not load camera HAL module");
+ mNumberOfCameras = 0;
+ }
+ else {
+ mNumberOfCameras = mModule->get_number_of_cameras();
+ if (mNumberOfCameras > MAX_CAMERAS) {
+ LOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
+ mNumberOfCameras, MAX_CAMERAS);
+ mNumberOfCameras = MAX_CAMERAS;
+ }
+ for (int i = 0; i < mNumberOfCameras; i++) {
+ setCameraFree(i);
+ }
+ }
+}
+
CameraService::~CameraService() {
for (int i = 0; i < mNumberOfCameras; i++) {
if (mBusy[i]) {
@@ -103,12 +115,19 @@
status_t CameraService::getCameraInfo(int cameraId,
struct CameraInfo* cameraInfo) {
+ if (!mModule) {
+ return NO_INIT;
+ }
+
if (cameraId < 0 || cameraId >= mNumberOfCameras) {
return BAD_VALUE;
}
- HAL_getCameraInfo(cameraId, cameraInfo);
- return OK;
+ struct camera_info info;
+ status_t rc = mModule->get_camera_info(cameraId, &info);
+ cameraInfo->facing = info.facing;
+ cameraInfo->orientation = info.orientation;
+ return rc;
}
sp<ICamera> CameraService::connect(
@@ -116,6 +135,11 @@
int callingPid = getCallingPid();
LOG1("CameraService::connect E (pid %d, id %d)", callingPid, cameraId);
+ if (!mModule) {
+ LOGE("Camera HAL module not loaded");
+ return NULL;
+ }
+
sp<Client> client;
if (cameraId < 0 || cameraId >= mNumberOfCameras) {
LOGE("CameraService::connect X (pid %d) rejected (invalid cameraId %d).",
@@ -123,6 +147,14 @@
return NULL;
}
+ char value[PROPERTY_VALUE_MAX];
+ property_get("sys.secpolicy.camera.disabled", value, "0");
+ if (strcmp(value, "1") == 0) {
+ // Camera is disabled by DevicePolicyManager.
+ LOGI("Camera is disabled. connect X (pid %d) rejected", callingPid);
+ return NULL;
+ }
+
Mutex::Autolock lock(mServiceLock);
if (mClient[cameraId] != 0) {
client = mClient[cameraId].promote();
@@ -146,15 +178,19 @@
return NULL;
}
- sp<CameraHardwareInterface> hardware = HAL_openCameraHardware(cameraId);
- if (hardware == NULL) {
- LOGE("Fail to open camera hardware (id=%d)", cameraId);
+ struct camera_info info;
+ if (mModule->get_camera_info(cameraId, &info) != OK) {
+ LOGE("Invalid camera id %d", cameraId);
return NULL;
}
- CameraInfo info;
- HAL_getCameraInfo(cameraId, &info);
- client = new Client(this, cameraClient, hardware, cameraId, info.facing,
- callingPid);
+
+ char camera_device_name[10];
+ snprintf(camera_device_name, sizeof(camera_device_name), "%d", cameraId);
+
+ client = new Client(this, cameraClient,
+ new CameraHardwareInterface(&mModule->common,
+ camera_device_name),
+ cameraId, info.facing, callingPid);
mClient[cameraId] = client;
LOG1("CameraService::connect X");
return client;
@@ -244,7 +280,7 @@
static MediaPlayer* newMediaPlayer(const char *file) {
MediaPlayer* mp = new MediaPlayer();
if (mp->setDataSource(file, NULL) == NO_ERROR) {
- mp->setAudioStreamType(AudioSystem::ENFORCED_AUDIBLE);
+ mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
mp->prepare();
} else {
LOGE("Failed to load CameraService sounds: %s", file);
@@ -283,7 +319,7 @@
// do not play the sound if stream volume is 0
// (typically because ringer mode is silent).
int index;
- AudioSystem::getStreamVolumeIndex(AudioSystem::ENFORCED_AUDIBLE, &index);
+ AudioSystem::getStreamVolumeIndex(AUDIO_STREAM_ENFORCED_AUDIBLE, &index);
if (index != 0) {
player->seekTo(0);
player->start();
@@ -314,13 +350,12 @@
dataCallbackTimestamp,
(void *)cameraId);
- // Enable zoom, error, and focus messages by default
- enableMsgType(CAMERA_MSG_ERROR |
- CAMERA_MSG_ZOOM |
- CAMERA_MSG_FOCUS);
+ // Enable zoom, error, focus, and metadata messages by default
+ enableMsgType(CAMERA_MSG_ERROR | CAMERA_MSG_ZOOM | CAMERA_MSG_FOCUS |
+ CAMERA_MSG_PREVIEW_METADATA);
// Callback is disabled by default
- mPreviewCallbackFlag = FRAME_CALLBACK_FLAG_NOOP;
+ mPreviewCallbackFlag = CAMERA_FRAME_CALLBACK_FLAG_NOOP;
mOrientation = getOrientation(0, mCameraFacing == CAMERA_FACING_FRONT);
mPlayShutterSound = true;
cameraService->setCameraBusy(cameraId);
@@ -384,6 +419,10 @@
// allow anyone to use camera (after they lock the camera)
status_t result = checkPid();
if (result == NO_ERROR) {
+ if (mHardware->recordingEnabled()) {
+ LOGE("Not allowed to unlock camera during recording.");
+ return INVALID_OPERATION;
+ }
mClientPid = 0;
LOG1("clear mCameraClient (pid %d)", callingPid);
// we need to remove the reference to ICameraClient so that when the app
@@ -410,7 +449,7 @@
return NO_ERROR;
}
- mPreviewCallbackFlag = FRAME_CALLBACK_FLAG_NOOP;
+ mPreviewCallbackFlag = CAMERA_FRAME_CALLBACK_FLAG_NOOP;
mClientPid = callingPid;
mCameraClient = client;
@@ -418,6 +457,17 @@
return NO_ERROR;
}
+static void disconnectWindow(const sp<ANativeWindow>& window) {
+ if (window != 0) {
+ status_t result = native_window_api_disconnect(window.get(),
+ NATIVE_WINDOW_API_CAMERA);
+ if (result != NO_ERROR) {
+ LOGW("native_window_api_disconnect failed: %s (%d)", strerror(-result),
+ result);
+ }
+ }
+}
+
void CameraService::Client::disconnect() {
int callingPid = getCallingPid();
LOG1("disconnect E (pid %d)", callingPid);
@@ -449,6 +499,7 @@
// Release the held ANativeWindow resources.
if (mPreviewWindow != 0) {
+ disconnectWindow(mPreviewWindow);
mPreviewWindow = 0;
mHardware->setPreviewWindow(mPreviewWindow);
}
@@ -462,77 +513,73 @@
// ----------------------------------------------------------------------------
-// set the Surface that the preview will use
-status_t CameraService::Client::setPreviewDisplay(const sp<Surface>& surface) {
- LOG1("setPreviewDisplay(%p) (pid %d)", surface.get(), getCallingPid());
+status_t CameraService::Client::setPreviewWindow(const sp<IBinder>& binder,
+ const sp<ANativeWindow>& window) {
Mutex::Autolock lock(mLock);
status_t result = checkPidAndHardware();
if (result != NO_ERROR) return result;
- result = NO_ERROR;
-
// return if no change in surface.
- // asBinder() is safe on NULL (returns NULL)
- if (getISurface(surface)->asBinder() == mSurface) {
- return result;
+ if (binder == mSurface) {
+ return NO_ERROR;
}
- if (mSurface != 0) {
- LOG1("clearing old preview surface %p", mSurface.get());
- }
- mSurface = getISurface(surface)->asBinder();
- mPreviewWindow = surface;
-
- // If preview has been already started, register preview
- // buffers now.
- if (mHardware->previewEnabled()) {
- if (mPreviewWindow != 0) {
- native_window_set_buffers_transform(mPreviewWindow.get(),
- mOrientation);
- result = mHardware->setPreviewWindow(mPreviewWindow);
+ if (window != 0) {
+ result = native_window_api_connect(window.get(), NATIVE_WINDOW_API_CAMERA);
+ if (result != NO_ERROR) {
+ LOGE("native_window_api_connect failed: %s (%d)", strerror(-result),
+ result);
+ return result;
}
}
+ // If preview has been already started, register preview buffers now.
+ if (mHardware->previewEnabled()) {
+ if (window != 0) {
+ native_window_set_scaling_mode(window.get(),
+ NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
+ native_window_set_buffers_transform(window.get(), mOrientation);
+ result = mHardware->setPreviewWindow(window);
+ }
+ }
+
+ if (result == NO_ERROR) {
+ // Everything has succeeded. Disconnect the old window and remember the
+ // new window.
+ disconnectWindow(mPreviewWindow);
+ mSurface = binder;
+ mPreviewWindow = window;
+ } else {
+ // Something went wrong after we connected to the new window, so
+ // disconnect here.
+ disconnectWindow(window);
+ }
+
return result;
}
+// set the Surface that the preview will use
+status_t CameraService::Client::setPreviewDisplay(const sp<Surface>& surface) {
+ LOG1("setPreviewDisplay(%p) (pid %d)", surface.get(), getCallingPid());
+
+ sp<IBinder> binder(surface != 0 ? surface->asBinder() : 0);
+ sp<ANativeWindow> window(surface);
+ return setPreviewWindow(binder, window);
+}
+
// set the SurfaceTexture that the preview will use
status_t CameraService::Client::setPreviewTexture(
const sp<ISurfaceTexture>& surfaceTexture) {
LOG1("setPreviewTexture(%p) (pid %d)", surfaceTexture.get(),
getCallingPid());
- Mutex::Autolock lock(mLock);
- status_t result = checkPidAndHardware();
- if (result != NO_ERROR) return result;
- // return if no change in surface.
- // asBinder() is safe on NULL (returns NULL)
- if (surfaceTexture->asBinder() == mSurface) {
- return result;
- }
-
- if (mSurface != 0) {
- LOG1("clearing old preview surface %p", mSurface.get());
- }
- mSurface = surfaceTexture->asBinder();
+ sp<IBinder> binder;
+ sp<ANativeWindow> window;
if (surfaceTexture != 0) {
- mPreviewWindow = new SurfaceTextureClient(surfaceTexture);
- } else {
- mPreviewWindow = 0;
+ binder = surfaceTexture->asBinder();
+ window = new SurfaceTextureClient(surfaceTexture);
}
-
- // If preview has been already started, set overlay or register preview
- // buffers now.
- if (mHardware->previewEnabled()) {
- // XXX: What if the new preview window is 0?
- if (mPreviewWindow != 0) {
- native_window_set_buffers_transform(mPreviewWindow.get(),
- mOrientation);
- result = mHardware->setPreviewWindow(mPreviewWindow);
- }
- }
-
- return result;
+ return setPreviewWindow(binder, window);
}
// set the preview callback flag to affect how the received frames from
@@ -543,7 +590,7 @@
if (checkPidAndHardware() != NO_ERROR) return;
mPreviewCallbackFlag = callback_flag;
- if (mPreviewCallbackFlag & FRAME_CALLBACK_FLAG_ENABLE_MASK) {
+ if (mPreviewCallbackFlag & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) {
enableMsgType(CAMERA_MSG_PREVIEW_FRAME);
} else {
disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
@@ -597,6 +644,8 @@
}
if (mPreviewWindow != 0) {
+ native_window_set_scaling_mode(mPreviewWindow.get(),
+ NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
native_window_set_buffers_transform(mPreviewWindow.get(),
mOrientation);
}
@@ -666,20 +715,6 @@
mHardware->releaseRecordingFrame(mem);
}
-int32_t CameraService::Client::getNumberOfVideoBuffers() const {
- LOG1("getNumberOfVideoBuffers");
- Mutex::Autolock lock(mLock);
- if (checkPidAndHardware() != NO_ERROR) return 0;
- return mHardware->getNumberOfVideoBuffers();
-}
-
-sp<IMemory> CameraService::Client::getVideoBuffer(int32_t index) const {
- LOG1("getVideoBuffer: %d", index);
- Mutex::Autolock lock(mLock);
- if (checkPidAndHardware() != NO_ERROR) return 0;
- return mHardware->getVideoBuffer(index);
-}
-
status_t CameraService::Client::storeMetaDataInBuffers(bool enabled)
{
LOG1("storeMetaDataInBuffers: %s", enabled? "true": "false");
@@ -734,6 +769,11 @@
status_t result = checkPidAndHardware();
if (result != NO_ERROR) return result;
+ if (mHardware->recordingEnabled()) {
+ LOGE("Cannot take picture during recording.");
+ return INVALID_OPERATION;
+ }
+
if ((msgType & CAMERA_MSG_RAW_IMAGE) &&
(msgType & CAMERA_MSG_RAW_IMAGE_NOTIFY)) {
LOGE("CAMERA_MSG_RAW_IMAGE and CAMERA_MSG_RAW_IMAGE_NOTIFY"
@@ -938,7 +978,7 @@
switch (msgType) {
case CAMERA_MSG_SHUTTER:
// ext1 is the dimension of the yuv picture.
- client->handleShutter((image_rect_type *)ext1);
+ client->handleShutter();
break;
default:
client->handleGenericNotify(msgType, ext1, ext2);
@@ -947,22 +987,22 @@
}
void CameraService::Client::dataCallback(int32_t msgType,
- const sp<IMemory>& dataPtr, void* user) {
+ const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata, void* user) {
LOG2("dataCallback(%d)", msgType);
sp<Client> client = getClientFromCookie(user);
if (client == 0) return;
if (!client->lockIfMessageWanted(msgType)) return;
- if (dataPtr == 0) {
+ if (dataPtr == 0 && metadata == NULL) {
LOGE("Null data returned in data callback");
client->handleGenericNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
return;
}
- switch (msgType) {
+ switch (msgType & ~CAMERA_MSG_PREVIEW_METADATA) {
case CAMERA_MSG_PREVIEW_FRAME:
- client->handlePreviewData(dataPtr);
+ client->handlePreviewData(msgType, dataPtr, metadata);
break;
case CAMERA_MSG_POSTVIEW_FRAME:
client->handlePostview(dataPtr);
@@ -974,7 +1014,7 @@
client->handleCompressedPicture(dataPtr);
break;
default:
- client->handleGenericData(msgType, dataPtr);
+ client->handleGenericData(msgType, dataPtr, metadata);
break;
}
}
@@ -997,9 +1037,7 @@
}
// snapshot taken callback
-// "size" is the width and height of yuv picture for registerBuffer.
-// If it is NULL, use the picture size from parameters.
-void CameraService::Client::handleShutter(image_rect_type *size) {
+void CameraService::Client::handleShutter(void) {
if (mPlayShutterSound) {
mCameraService->playSound(SOUND_SHUTTER);
}
@@ -1016,7 +1054,9 @@
}
// preview callback - frame buffer update
-void CameraService::Client::handlePreviewData(const sp<IMemory>& mem) {
+void CameraService::Client::handlePreviewData(int32_t msgType,
+ const sp<IMemory>& mem,
+ camera_frame_metadata_t *metadata) {
ssize_t offset;
size_t size;
sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
@@ -1025,7 +1065,7 @@
int flags = mPreviewCallbackFlag;
// is callback enabled?
- if (!(flags & FRAME_CALLBACK_FLAG_ENABLE_MASK)) {
+ if (!(flags & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK)) {
// If the enable bit is off, the copy-out and one-shot bits are ignored
LOG2("frame callback is disabled");
mLock.unlock();
@@ -1036,23 +1076,23 @@
sp<ICameraClient> c = mCameraClient;
// clear callback flags if no client or one-shot mode
- if (c == 0 || (mPreviewCallbackFlag & FRAME_CALLBACK_FLAG_ONE_SHOT_MASK)) {
+ if (c == 0 || (mPreviewCallbackFlag & CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK)) {
LOG2("Disable preview callback");
- mPreviewCallbackFlag &= ~(FRAME_CALLBACK_FLAG_ONE_SHOT_MASK |
- FRAME_CALLBACK_FLAG_COPY_OUT_MASK |
- FRAME_CALLBACK_FLAG_ENABLE_MASK);
+ mPreviewCallbackFlag &= ~(CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK |
+ CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK |
+ CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK);
disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
}
if (c != 0) {
// Is the received frame copied out or not?
- if (flags & FRAME_CALLBACK_FLAG_COPY_OUT_MASK) {
+ if (flags & CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK) {
LOG2("frame is copied");
- copyFrameAndPostCopiedFrame(c, heap, offset, size);
+ copyFrameAndPostCopiedFrame(msgType, c, heap, offset, size, metadata);
} else {
LOG2("frame is forwarded");
mLock.unlock();
- c->dataCallback(CAMERA_MSG_PREVIEW_FRAME, mem);
+ c->dataCallback(msgType, mem, metadata);
}
} else {
mLock.unlock();
@@ -1066,7 +1106,7 @@
sp<ICameraClient> c = mCameraClient;
mLock.unlock();
if (c != 0) {
- c->dataCallback(CAMERA_MSG_POSTVIEW_FRAME, mem);
+ c->dataCallback(CAMERA_MSG_POSTVIEW_FRAME, mem, NULL);
}
}
@@ -1081,7 +1121,7 @@
sp<ICameraClient> c = mCameraClient;
mLock.unlock();
if (c != 0) {
- c->dataCallback(CAMERA_MSG_RAW_IMAGE, mem);
+ c->dataCallback(CAMERA_MSG_RAW_IMAGE, mem, NULL);
}
}
@@ -1092,7 +1132,7 @@
sp<ICameraClient> c = mCameraClient;
mLock.unlock();
if (c != 0) {
- c->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mem);
+ c->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mem, NULL);
}
}
@@ -1107,11 +1147,11 @@
}
void CameraService::Client::handleGenericData(int32_t msgType,
- const sp<IMemory>& dataPtr) {
+ const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata) {
sp<ICameraClient> c = mCameraClient;
mLock.unlock();
if (c != 0) {
- c->dataCallback(msgType, dataPtr);
+ c->dataCallback(msgType, dataPtr, metadata);
}
}
@@ -1125,8 +1165,9 @@
}
void CameraService::Client::copyFrameAndPostCopiedFrame(
- const sp<ICameraClient>& client, const sp<IMemoryHeap>& heap,
- size_t offset, size_t size) {
+ int32_t msgType, const sp<ICameraClient>& client,
+ const sp<IMemoryHeap>& heap, size_t offset, size_t size,
+ camera_frame_metadata_t *metadata) {
LOG2("copyFrameAndPostCopiedFrame");
// It is necessary to copy out of pmem before sending this to
// the callback. For efficiency, reuse the same MemoryHeapBase
@@ -1158,7 +1199,7 @@
}
mLock.unlock();
- client->dataCallback(CAMERA_MSG_PREVIEW_FRAME, frame);
+ client->dataCallback(msgType, frame, metadata);
}
int CameraService::Client::getOrientation(int degrees, bool mirror) {
@@ -1257,12 +1298,4 @@
return NO_ERROR;
}
-sp<ISurface> CameraService::getISurface(const sp<Surface>& surface) {
- if (surface != 0) {
- return surface->getISurface();
- } else {
- return sp<ISurface>(0);
- }
-}
-
}; // namespace android
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 1c43b00..57abf83 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -19,9 +19,8 @@
#define ANDROID_SERVERS_CAMERA_CAMERASERVICE_H
#include <binder/BinderService.h>
-
#include <camera/ICameraService.h>
-#include <camera/CameraHardwareInterface.h>
+#include <hardware/camera.h>
/* This needs to be increased if we can have more cameras */
#define MAX_CAMERAS 2
@@ -30,6 +29,7 @@
class MemoryHeapBase;
class MediaPlayer;
+class CameraHardwareInterface;
class CameraService :
public BinderService<CameraService>,
@@ -53,6 +53,7 @@
virtual status_t dump(int fd, const Vector<String16>& args);
virtual status_t onTransact(uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags);
+ virtual void onFirstRef();
enum sound_kind {
SOUND_SHUTTER = 0,
@@ -79,12 +80,6 @@
sp<MediaPlayer> mSoundPlayer[NUM_SOUNDS];
int mSoundRef; // reference count (release all MediaPlayer when 0)
- // Used by Client objects to extract the ISurface from a Surface object.
- // This is used because making Client a friend class of Surface would
- // require including this header in Surface.h since Client is a nested
- // class.
- static sp<ISurface> getISurface(const sp<Surface>& surface);
-
class Client : public BnCamera
{
public:
@@ -99,8 +94,6 @@
virtual status_t startPreview();
virtual void stopPreview();
virtual bool previewEnabled();
- virtual int32_t getNumberOfVideoBuffers() const;
- virtual sp<IMemory> getVideoBuffer(int32_t index) const;
virtual status_t storeMetaDataInBuffers(bool enabled);
virtual status_t startRecording();
virtual void stopRecording();
@@ -147,27 +140,36 @@
// these are static callback functions
static void notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2, void* user);
- static void dataCallback(int32_t msgType, const sp<IMemory>& dataPtr, void* user);
+ static void dataCallback(int32_t msgType, const sp<IMemory>& dataPtr,
+ camera_frame_metadata_t *metadata, void* user);
static void dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr, void* user);
// convert client from cookie
static sp<Client> getClientFromCookie(void* user);
// handlers for messages
- void handleShutter(image_rect_type *size);
- void handlePreviewData(const sp<IMemory>& mem);
+ void handleShutter(void);
+ void handlePreviewData(int32_t msgType, const sp<IMemory>& mem,
+ camera_frame_metadata_t *metadata);
void handlePostview(const sp<IMemory>& mem);
void handleRawPicture(const sp<IMemory>& mem);
void handleCompressedPicture(const sp<IMemory>& mem);
void handleGenericNotify(int32_t msgType, int32_t ext1, int32_t ext2);
- void handleGenericData(int32_t msgType, const sp<IMemory>& dataPtr);
+ void handleGenericData(int32_t msgType, const sp<IMemory>& dataPtr,
+ camera_frame_metadata_t *metadata);
void handleGenericDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);
void copyFrameAndPostCopiedFrame(
+ int32_t msgType,
const sp<ICameraClient>& client,
const sp<IMemoryHeap>& heap,
- size_t offset, size_t size);
+ size_t offset, size_t size,
+ camera_frame_metadata_t *metadata);
int getOrientation(int orientation, bool mirror);
+ status_t setPreviewWindow(
+ const sp<IBinder>& binder,
+ const sp<ANativeWindow>& window);
+
// these are initialized in the constructor.
sp<CameraService> mCameraService; // immutable after constructor
sp<ICameraClient> mCameraClient;
@@ -207,6 +209,8 @@
// is found to be disabled. It returns true if mLock is grabbed.
bool lockIfMessageWanted(int32_t msgType);
};
+
+ camera_module_t *mModule;
};
} // namespace android
diff --git a/services/camera/tests/CameraServiceTest/Android.mk b/services/camera/tests/CameraServiceTest/Android.mk
index cf4e42f..cf7302a 100644
--- a/services/camera/tests/CameraServiceTest/Android.mk
+++ b/services/camera/tests/CameraServiceTest/Android.mk
@@ -19,7 +19,7 @@
libutils \
libui \
libcamera_client \
- libsurfaceflinger_client
+ libgui
# Disable it because the ISurface interface may change, and before we have a
# chance to fix this test, we don't want to break normal builds.
diff --git a/services/camera/tests/CameraServiceTest/CameraServiceTest.cpp b/services/camera/tests/CameraServiceTest/CameraServiceTest.cpp
index 8a228fd..e390ae2 100644
--- a/services/camera/tests/CameraServiceTest/CameraServiceTest.cpp
+++ b/services/camera/tests/CameraServiceTest/CameraServiceTest.cpp
@@ -29,7 +29,6 @@
#include <camera/ICamera.h>
#include <camera/ICameraClient.h>
#include <camera/ICameraService.h>
-#include <ui/Overlay.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>
@@ -311,8 +310,6 @@
virtual status_t registerBuffers(const BufferHeap& buffers);
virtual void postBuffer(ssize_t offset);
virtual void unregisterBuffers();
- virtual sp<OverlayRef> createOverlay(
- uint32_t w, uint32_t h, int32_t format, int32_t orientation);
virtual sp<GraphicBuffer> requestBuffer(int bufferIdx, int usage);
virtual status_t setBufferCount(int bufferCount);
@@ -381,13 +378,6 @@
}
}
-sp<OverlayRef> MSurface::createOverlay(uint32_t w, uint32_t h, int32_t format,
- int32_t orientation) {
- // Not implemented.
- ASSERT(0);
- return NULL;
-}
-
//
// Utilities to use the Holder service
//
@@ -830,10 +820,10 @@
ASSERT(c->previewEnabled() == true);
sleep(2);
c->stopPreview();
- if ((v & FRAME_CALLBACK_FLAG_ENABLE_MASK) == 0) {
+ if ((v & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) == 0) {
cc->assertData(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::EQ, 0);
} else {
- if ((v & FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) == 0) {
+ if ((v & CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) == 0) {
cc->assertData(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::GE, 10);
} else {
cc->assertData(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::EQ, 1);
@@ -849,7 +839,7 @@
ASSERT(c->recordingEnabled() == false);
sp<MSurface> surface = new MSurface();
ASSERT(c->setPreviewDisplay(surface) == NO_ERROR);
- c->setPreviewCallbackFlag(FRAME_CALLBACK_FLAG_ENABLE_MASK);
+ c->setPreviewCallbackFlag(CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK);
cc->setReleaser(c.get());
c->startRecording();
ASSERT(c->recordingEnabled() == true);
@@ -870,7 +860,7 @@
CameraParameters param(c->getParameters());
param.setPreviewSize(w, h);
- c->setPreviewCallbackFlag(FRAME_CALLBACK_FLAG_ENABLE_MASK);
+ c->setPreviewCallbackFlag(CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK);
c->setParameters(param.flatten());
c->startPreview();