summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2010-05-24 14:38:02 -0700
committerAndreas Huber <andih@google.com>2010-05-24 14:38:02 -0700
commit4d1265cd007b9754d0645bc4fb95701140a45648 (patch)
tree4e23c4db5564c42b79cb0636241583f0d2a6866e /media
parent6b19faca7040ba4ef67637801926ead2559c22e9 (diff)
downloadframeworks_av-4d1265cd007b9754d0645bc4fb95701140a45648.zip
frameworks_av-4d1265cd007b9754d0645bc4fb95701140a45648.tar.gz
frameworks_av-4d1265cd007b9754d0645bc4fb95701140a45648.tar.bz2
Squashed commit of the following:
commit a2194ecc341fa0c530d0007d8561286c8b8f2d15 Author: Andreas Huber <andih@google.com> Date: Fri May 21 12:50:09 2010 -0700 Instead of including the libvpx libraries prebuilt in our tree, build them from sources. Change-Id: I5ec57decf1200cf9137fe13ff77d06f47950c3d7 commit 711098ca3f16800a22ccdb26a07e57e471cca438 Author: Andreas Huber <andih@google.com> Date: Thu May 20 15:00:27 2010 -0700 Support for VPX/VP8 decoding in stagefright Change-Id: I16d93faf3f56a5f8ec39c14367704469f914db9e related-to-bug: 2483739 Change-Id: Ibc124f6af540c2715cb2325151eecdd6edf085ec
Diffstat (limited to 'media')
-rw-r--r--media/libstagefright/Android.mk2
-rw-r--r--media/libstagefright/OMXCodec.cpp4
-rw-r--r--media/libstagefright/codecs/on2/Android.mk4
-rw-r--r--media/libstagefright/codecs/on2/dec/Android.mk16
-rw-r--r--media/libstagefright/codecs/on2/dec/VPXDecoder.cpp230
-rw-r--r--media/libstagefright/include/VPXDecoder.h60
6 files changed, 316 insertions, 0 deletions
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 681943f..8d15013 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -77,6 +77,8 @@ LOCAL_STATIC_LIBRARIES := \
libstagefright_mp3dec \
libstagefright_vorbisdec \
libstagefright_matroska \
+ libstagefright_vpxdec \
+ libvpx \
LOCAL_SHARED_LIBRARIES += \
libstagefright_amrnb_common \
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 928a6c8..66011ca 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -28,6 +28,7 @@
#include "include/M4vH263Decoder.h"
#include "include/MP3Decoder.h"
#include "include/VorbisDecoder.h"
+#include "include/VPXDecoder.h"
#include "include/ESDS.h"
@@ -76,6 +77,7 @@ FACTORY_CREATE(AACDecoder)
FACTORY_CREATE(AVCDecoder)
FACTORY_CREATE(M4vH263Decoder)
FACTORY_CREATE(VorbisDecoder)
+FACTORY_CREATE(VPXDecoder)
FACTORY_CREATE_ENCODER(AMRNBEncoder)
FACTORY_CREATE_ENCODER(AMRWBEncoder)
FACTORY_CREATE_ENCODER(AACEncoder)
@@ -118,6 +120,7 @@ static sp<MediaSource> InstantiateSoftwareCodec(
FACTORY_REF(AVCDecoder)
FACTORY_REF(M4vH263Decoder)
FACTORY_REF(VorbisDecoder)
+ FACTORY_REF(VPXDecoder)
};
for (size_t i = 0;
i < sizeof(kFactoryInfo) / sizeof(kFactoryInfo[0]); ++i) {
@@ -158,6 +161,7 @@ static const CodecInfo kDecoderInfo[] = {
{ MEDIA_MIMETYPE_VIDEO_AVC, "AVCDecoder" },
// { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.PV.avcdec" },
{ MEDIA_MIMETYPE_AUDIO_VORBIS, "VorbisDecoder" },
+ { MEDIA_MIMETYPE_VIDEO_VPX, "VPXDecoder" },
};
static const CodecInfo kEncoderInfo[] = {
diff --git a/media/libstagefright/codecs/on2/Android.mk b/media/libstagefright/codecs/on2/Android.mk
new file mode 100644
index 0000000..2e43120
--- /dev/null
+++ b/media/libstagefright/codecs/on2/Android.mk
@@ -0,0 +1,4 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/media/libstagefright/codecs/on2/dec/Android.mk b/media/libstagefright/codecs/on2/dec/Android.mk
new file mode 100644
index 0000000..03dfb75
--- /dev/null
+++ b/media/libstagefright/codecs/on2/dec/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ VPXDecoder.cpp
+
+LOCAL_MODULE := libstagefright_vpxdec
+
+LOCAL_C_INCLUDES := \
+ $(TOP)/frameworks/base/media/libstagefright/include \
+ $(TOP)/external/opencore/extern_libs_v2/khronos/openmax/include \
+ $(TOP)/external/libvpx \
+ $(TOP)/external/libvpx/vpx_codec \
+ $(TOP)/external/libvpx/vpx_ports
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/media/libstagefright/codecs/on2/dec/VPXDecoder.cpp b/media/libstagefright/codecs/on2/dec/VPXDecoder.cpp
new file mode 100644
index 0000000..bad8956
--- /dev/null
+++ b/media/libstagefright/codecs/on2/dec/VPXDecoder.cpp
@@ -0,0 +1,230 @@
+/*
+ * 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_codec/vpx_decoder.h"
+#include "vp8/vp8dx.h"
+
+namespace android {
+
+VPXDecoder::VPXDecoder(const sp<MediaSource> &source)
+ : mSource(source),
+ mStarted(false),
+ mBufferSize(0),
+ mCtx(NULL),
+ mBufferGroup(NULL) {
+ 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;
+ if (vpx_codec_dec_init(
+ (vpx_codec_ctx_t *)mCtx, &vpx_codec_vp8_dx_algo, NULL, 0)) {
+ LOGE("on2 decoder failed to initialize.");
+
+ mSource->stop();
+
+ return UNKNOWN_ERROR;
+ }
+
+ mBufferGroup = new MediaBufferGroup;
+ mBufferGroup->add_buffer(new MediaBuffer(mBufferSize));
+ mBufferGroup->add_buffer(new MediaBuffer(mBufferSize));
+
+ 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;
+
+ 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 (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;
+
+ vpx_codec_iter_t iter = NULL;
+ vpx_image_t *img = vpx_codec_get_frame((vpx_codec_ctx_t *)mCtx, &iter);
+
+ if (img == NULL) {
+ LOGI("on2 decoder did not return a frame.");
+
+ *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/include/VPXDecoder.h b/media/libstagefright/include/VPXDecoder.h
new file mode 100644
index 0000000..550c612
--- /dev/null
+++ b/media/libstagefright/include/VPXDecoder.h
@@ -0,0 +1,60 @@
+/*
+ * 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 VPX_DECODER_H_
+
+#define VPX_DECODER_H_
+
+#include <media/stagefright/MediaSource.h>
+#include <utils/Vector.h>
+
+namespace android {
+
+struct MediaBufferGroup;
+
+struct VPXDecoder : public MediaSource {
+ VPXDecoder(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);
+
+protected:
+ virtual ~VPXDecoder();
+
+private:
+ sp<MediaSource> mSource;
+ bool mStarted;
+ int32_t mWidth, mHeight;
+ size_t mBufferSize;
+
+ void *mCtx;
+ MediaBufferGroup *mBufferGroup;
+
+ sp<MetaData> mFormat;
+
+ VPXDecoder(const VPXDecoder &);
+ VPXDecoder &operator=(const VPXDecoder &);
+};
+
+} // namespace android
+
+#endif // VPX_DECODER_H_
+