am a581a776: Merge "Squashed commit of the following:" into kraken

This commit is contained in:
Andreas Huber
2010-05-26 11:22:49 -07:00
committed by Android Git Automerger
6 changed files with 316 additions and 0 deletions

View File

@ -77,6 +77,8 @@ LOCAL_STATIC_LIBRARIES := \
libstagefright_mp3dec \
libstagefright_vorbisdec \
libstagefright_matroska \
libstagefright_vpxdec \
libvpx \
LOCAL_SHARED_LIBRARIES += \
libstagefright_amrnb_common \

View File

@ -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[] = {

View File

@ -0,0 +1,4 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
include $(call all-makefiles-under,$(LOCAL_PATH))

View File

@ -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)

View File

@ -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

View File

@ -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_