diff options
Diffstat (limited to 'media/tests')
-rw-r--r-- | media/tests/omxjpegdecoder/Android.mk | 55 | ||||
-rw-r--r-- | media/tests/omxjpegdecoder/SkOmxPixelRef.cpp | 46 | ||||
-rw-r--r-- | media/tests/omxjpegdecoder/SkOmxPixelRef.h | 51 | ||||
-rw-r--r-- | media/tests/omxjpegdecoder/StreamSource.cpp | 53 | ||||
-rw-r--r-- | media/tests/omxjpegdecoder/StreamSource.h | 52 | ||||
-rw-r--r-- | media/tests/omxjpegdecoder/jpeg_decoder_bench.cpp | 115 | ||||
-rw-r--r-- | media/tests/omxjpegdecoder/omx_jpeg_decoder.cpp | 197 | ||||
-rw-r--r-- | media/tests/omxjpegdecoder/omx_jpeg_decoder.h | 62 |
8 files changed, 631 insertions, 0 deletions
diff --git a/media/tests/omxjpegdecoder/Android.mk b/media/tests/omxjpegdecoder/Android.mk new file mode 100644 index 0000000..e989078 --- /dev/null +++ b/media/tests/omxjpegdecoder/Android.mk @@ -0,0 +1,55 @@ +# 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. +ifeq ($(BUILD_WITH_FULL_STAGEFRIGHT),true) + +LOCAL_PATH:= $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + omx_jpeg_decoder.cpp \ + jpeg_decoder_bench.cpp \ + SkOmxPixelRef.cpp \ + StreamSource.cpp + + +# add external/skia/src/images/SkImageDecoder_libjpeg.cpp +LOCAL_SRC_FILES += \ + ../../../../../external/skia/src/images/SkImageDecoder_libjpeg.cpp + +LOCAL_SHARED_LIBRARIES := \ + libcutils \ + libskia \ + libstagefright + +LOCAL_C_INCLUDES := \ + $(JNI_H_INCLUDE) \ + $(TOP)/external/jpeg \ + $(TOP)/external/skia/include/config \ + $(TOP)/external/skia/include/core \ + $(TOP)/external/skia/include/images \ + $(TOP)/external/skia/include/utils \ + $(TOP)/external/skia/include/effects \ + $(TOP)/frameworks/base/media/libstagefright \ + $(TOP)/external/opencore/extern_libs_v2/khronos/openmax/include \ + $(TOP)/frameworks/base/include/ \ + $(TOP)/frameworks/base/ + +LOCAL_MODULE := jpeg_bench + +LOCAL_MODULE_TAGS := optional + +include $(BUILD_EXECUTABLE) + +endif diff --git a/media/tests/omxjpegdecoder/SkOmxPixelRef.cpp b/media/tests/omxjpegdecoder/SkOmxPixelRef.cpp new file mode 100644 index 0000000..3acc0ee --- /dev/null +++ b/media/tests/omxjpegdecoder/SkOmxPixelRef.cpp @@ -0,0 +1,46 @@ +/* + * 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 <media/stagefright/MediaDebug.h> +#include <SkBitmap.h> + +#include "SkOmxPixelRef.h" + +using namespace android; + +SkOmxPixelRef::SkOmxPixelRef(SkColorTable* ctable, MediaBuffer* buffer, + sp<OMXCodec> decoder) { + mBuffer = buffer; + mDecoder = decoder; + mSize = buffer->size(); + mCTable = ctable; + SkSafeRef(mCTable); +} + +SkOmxPixelRef::~SkOmxPixelRef() { + mBuffer->release(); + CHECK_EQ(mDecoder->stop(), OK); + SkSafeUnref(mCTable); +} + +void* SkOmxPixelRef::onLockPixels(SkColorTable** ct) { + *ct = mCTable; + return mBuffer->data(); +} + +void SkOmxPixelRef::onUnlockPixels() { + // nothing to do +} diff --git a/media/tests/omxjpegdecoder/SkOmxPixelRef.h b/media/tests/omxjpegdecoder/SkOmxPixelRef.h new file mode 100644 index 0000000..4ab5a73 --- /dev/null +++ b/media/tests/omxjpegdecoder/SkOmxPixelRef.h @@ -0,0 +1,51 @@ +/* + * 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 SKOMXPIXELREF_DEFINED +#define SKOMXPIXELREF_DEFINED + +#include <media/stagefright/MediaBuffer.h> +#include <media/stagefright/OMXClient.h> +#include <media/stagefright/OMXCodec.h> +#include <SkPixelRef.h> + +namespace android { + +class SkOmxPixelRef : public SkPixelRef { +public: + SkOmxPixelRef(SkColorTable* ctable, MediaBuffer* buffer, + sp<OMXCodec> decoder); + virtual ~SkOmxPixelRef(); + + //! Return the allocation size for the pixels + size_t getSize() const { return mSize; } + +protected: + // overrides from SkPixelRef + virtual void* onLockPixels(SkColorTable**); + virtual void onUnlockPixels(); + +private: + MediaBuffer* mBuffer; + sp<OMXCodec> mDecoder; + size_t mSize; + SkColorTable* mCTable; + + typedef SkPixelRef INHERITED; +}; + +} // namespace android +#endif // SKOMXPIXELREF_DEFINED diff --git a/media/tests/omxjpegdecoder/StreamSource.cpp b/media/tests/omxjpegdecoder/StreamSource.cpp new file mode 100644 index 0000000..76aa85b --- /dev/null +++ b/media/tests/omxjpegdecoder/StreamSource.cpp @@ -0,0 +1,53 @@ +/* + * 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 <media/stagefright/MediaDebug.h> + +#include "StreamSource.h" + +namespace android { + +StreamSource::StreamSource(SkStream *stream) + : mStream(stream) { + CHECK(stream != NULL); + mSize = stream->getLength(); +} + +StreamSource::~StreamSource() { + delete mStream; + mStream = NULL; +} + +status_t StreamSource::initCheck() const { + return mStream != NULL ? OK : NO_INIT; +} + +ssize_t StreamSource::readAt(off_t offset, void *data, size_t size) { + Mutex::Autolock autoLock(mLock); + + mStream->rewind(); + mStream->skip(offset); + ssize_t result = mStream->read(data, size); + + return result; +} + +status_t StreamSource::getSize(off_t *size) { + *size = mSize; + return OK; +} + +} // namespace android diff --git a/media/tests/omxjpegdecoder/StreamSource.h b/media/tests/omxjpegdecoder/StreamSource.h new file mode 100644 index 0000000..c1ed5bf --- /dev/null +++ b/media/tests/omxjpegdecoder/StreamSource.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 STREAM_SOURCE_H_ + +#define STREAM_SOURCE_H_ + +#include <stdio.h> + +#include <core/SkStream.h> +#include <media/stagefright/DataSource.h> +#include <media/stagefright/MediaErrors.h> +#include <utils/threads.h> + +namespace android { + +class StreamSource : public DataSource { +public: + // Pass the ownership of SkStream to StreamSource. + StreamSource(SkStream *SkStream); + virtual status_t initCheck() const; + virtual ssize_t readAt(off_t offset, void *data, size_t size); + virtual status_t getSize(off_t *size); + +protected: + virtual ~StreamSource(); + +private: + SkStream *mStream; + size_t mSize; + Mutex mLock; + + StreamSource(const StreamSource &); + StreamSource &operator=(const StreamSource &); +}; + +} // namespace android + +#endif // STREAM_SOURCE_H_ diff --git a/media/tests/omxjpegdecoder/jpeg_decoder_bench.cpp b/media/tests/omxjpegdecoder/jpeg_decoder_bench.cpp new file mode 100644 index 0000000..78b89ca --- /dev/null +++ b/media/tests/omxjpegdecoder/jpeg_decoder_bench.cpp @@ -0,0 +1,115 @@ +/* + * 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 "OmxJpegDecoder" +#include <sys/time.h> +#include <utils/Log.h> + +#include <binder/ProcessState.h> + +#include "SkBitmap.h" +#include "SkImageDecoder.h" +#include "SkStream.h" +#include "omx_jpeg_decoder.h" + +class SkJPEGImageDecoder : public SkImageDecoder { +public: + virtual Format getFormat() const { + return kJPEG_Format; + } + +protected: + virtual bool onDecode(SkStream* stream, SkBitmap* bm, + SkBitmap::Config pref, Mode); +}; + +int nullObjectReturn(const char msg[]) { + if (msg) { + SkDebugf("--- %s\n", msg); + } + return -1; +} + +static int64_t getNowUs() { + struct timeval tv; + gettimeofday(&tv, NULL); + + return tv.tv_usec + (int64_t) tv.tv_sec * 1000000; +} + +int testDecodeBounds(SkImageDecoder* decoder, SkStream* stream, + SkBitmap* bitmap) { + int64_t startTime = getNowUs(); + SkBitmap::Config prefConfig = SkBitmap::kARGB_8888_Config; + SkImageDecoder::Mode decodeMode = SkImageDecoder::kDecodeBounds_Mode; + + // Decode the input stream and then use the bitmap. + if (!decoder->decode(stream, bitmap, prefConfig, decodeMode)) { + return nullObjectReturn("decoder->decode returned false"); + } else { + int64_t delay = getNowUs() - startTime; + printf("WidthxHeight: %dx%d\n", bitmap->width(), bitmap->height()); + printf("Decoding Time in BoundsMode %.1f msec.\n", delay / 1000.0f); + return 0; + } +} + +int testDecodePixels(SkImageDecoder* decoder, SkStream* stream, + SkBitmap* bitmap) { + int64_t startTime = getNowUs(); + SkBitmap::Config prefConfig = SkBitmap::kARGB_8888_Config; + SkImageDecoder::Mode decodeMode = SkImageDecoder::kDecodePixels_Mode; + + // Decode the input stream and then use the bitmap. + if (!decoder->decode(stream, bitmap, prefConfig, decodeMode)) { + return nullObjectReturn("decoder->decode returned false"); + } else { + int64_t delay = getNowUs() - startTime; + printf("Decoding Time in PixelsMode %.1f msec.\n", delay / 1000.0f); + char* filename = "/sdcard/omxJpegDecodedBitmap.rgba"; + return storeBitmapToFile(bitmap, filename); + } +} + +int testDecoder(SkImageDecoder* decoder, char* filename) { + // test DecodeMode == Pixels + SkStream* stream = new SkFILEStream(filename); + SkBitmap* bitmap = new SkBitmap; + testDecodePixels(decoder, stream, bitmap); + delete bitmap; + + // test DecodeMode == Bounds + stream = new SkFILEStream(filename); + bitmap = new SkBitmap; + testDecodeBounds(decoder, stream, bitmap); + delete bitmap; + + delete decoder; + return 0; +} + +int main(int argc, char** argv) { + android::ProcessState::self()->startThreadPool(); + + printf("Decoding jpeg with libjpeg...\n"); + SkJPEGImageDecoder* libjpeg = new SkJPEGImageDecoder; + testDecoder(libjpeg, argv[1]); + + printf("\nDecoding jpeg with OMX...\n"); + OmxJpegImageDecoder* omx = new OmxJpegImageDecoder; + testDecoder(omx, argv[1]); + return 0; +} diff --git a/media/tests/omxjpegdecoder/omx_jpeg_decoder.cpp b/media/tests/omxjpegdecoder/omx_jpeg_decoder.cpp new file mode 100644 index 0000000..8d02f46 --- /dev/null +++ b/media/tests/omxjpegdecoder/omx_jpeg_decoder.cpp @@ -0,0 +1,197 @@ +/* + * 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 "OmxJpegDecoder" +#include <sys/time.h> +#include <utils/Log.h> + +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <binder/IServiceManager.h> +#include <binder/ProcessState.h> +#include <media/IMediaPlayerService.h> +#include <media/stagefright/MediaDebug.h> +#include <media/stagefright/MediaSource.h> +#include <media/stagefright/MetaData.h> +#include <media/stagefright/OMXClient.h> +#include <media/stagefright/OMXCodec.h> +#include <SkMallocPixelRef.h> + +#include "omx_jpeg_decoder.h" +#include "SkOmxPixelRef.h" +#include "StreamSource.h" + +using namespace android; + +static void getJpegOutput(MediaBuffer* buffer, char* filename) { + int size = buffer->range_length(); + int offset = buffer->range_offset(); + FILE *pFile = fopen(filename, "w+"); + + if (pFile == NULL) { + printf("Error: cannot open %s.\n", filename); + } else { + char* data = (char*) buffer->data(); + data += offset; + while (size > 0) { + int numChars = fwrite(data, sizeof(char), 1024, pFile); + int numBytes = numChars * sizeof(char); + size -= numBytes; + data += numBytes; + } + fclose(pFile); + } + return; +} + +extern int storeBitmapToFile(SkBitmap* bitmap, char* filename) { + bitmap->lockPixels(); + void* data = bitmap->getPixels(); + int size = bitmap->getSize(); + FILE* fp = fopen(filename, "w+"); + + if (NULL == fp) { + printf("Cannot open the output file! \n"); + return -1; + } else { + while (size > 0) { + int numChars = fwrite(data, sizeof(char), 1024, fp); + int numBytes = numChars * sizeof(char); + size -= numBytes; + data += numBytes; + } + fclose(fp); + } + return 0; +} + +static int64_t getNowUs() { + struct timeval tv; + gettimeofday(&tv, NULL); + + return (int64_t)tv.tv_usec + tv.tv_sec * 1000000; +} + +OmxJpegImageDecoder::OmxJpegImageDecoder() { + status_t err = mClient.connect(); + CHECK_EQ(err, OK); +} + +OmxJpegImageDecoder::~OmxJpegImageDecoder() { + mClient.disconnect(); +} + +bool OmxJpegImageDecoder::onDecode(SkStream* stream, + SkBitmap* bm, SkBitmap::Config pref, Mode mode) { + sp<MediaSource> source = prepareMediaSource(stream); + sp<MetaData> meta = source->getFormat(); + int width; + int height; + meta->findInt32(kKeyWidth, &width); + meta->findInt32(kKeyHeight, &height); + configBitmapSize(bm, pref, width, height); + + // mode == DecodeBounds + if (mode == SkImageDecoder::kDecodeBounds_Mode) { + return true; + } + + // mode == DecodePixels + if (!this->allocPixelRef(bm, NULL)) { + LOGI(LOG_TAG, "Cannot allocPixelRef()!"); + return false; + } + + sp<OMXCodec> decoder = getDecoder(&mClient, source); + return decodeSource(decoder, source, bm); +} + +JPEGSource* OmxJpegImageDecoder::prepareMediaSource(SkStream* stream) { + DataSource::RegisterDefaultSniffers(); + sp<DataSource> dataSource = new StreamSource(stream); + return new JPEGSource(dataSource); +} + +sp<OMXCodec> OmxJpegImageDecoder::getDecoder( + OMXClient *client, const sp<MediaSource>& source) { + sp<MetaData> meta = source->getFormat(); + sp<OMXCodec> decoder = OMXCodec::Create( + client->interface(), meta, false /* createEncoder */, source); + + CHECK(decoder != NULL); + return decoder; +} + +bool OmxJpegImageDecoder::decodeSource(sp<OMXCodec> decoder, + const sp<MediaSource>& source, SkBitmap* bm) { + status_t rt = decoder->start(); + if (rt != OK) { + LOGE(LOG_TAG, "Cannot start OMX Decoder!"); + return false; + } + int64_t startTime = getNowUs(); + MediaBuffer *buffer; + + // decode source + status_t err = decoder->read(&buffer, NULL); + int64_t duration = getNowUs() - startTime; + + if (err != OK) { + CHECK_EQ(buffer, NULL); + } + printf("Duration in decoder->read(): %.1f (msecs). \n", + duration / 1E3 ); + + /* Mark the code for now, since we attend to copy buffer to SkBitmap. + // Install pixelRef to Bitmap. + installPixelRef(buffer, decoder, bm);*/ + + // Copy pixels from buffer to bm. + // May need to check buffer->rawBytes() == bm->rawBytes(). + CHECK_EQ(buffer->size(), bm->getSize()); + memcpy(bm->getPixels(), buffer->data(), buffer->size()); + buffer->release(); + decoder->stop(); + + return true; +} + +void OmxJpegImageDecoder::installPixelRef(MediaBuffer *buffer, sp<OMXCodec> decoder, + SkBitmap* bm) { + + // set bm's pixelref based on the data in buffer. + SkAutoLockPixels alp(*bm); + SkPixelRef* pr = new SkOmxPixelRef(NULL, buffer, decoder); + bm->setPixelRef(pr)->unref(); + bm->lockPixels(); + return; +} + +void OmxJpegImageDecoder::configBitmapSize(SkBitmap* bm, SkBitmap::Config pref, + int width, int height) { + bm->setConfig(getColorSpaceConfig(pref), width, height); + bm->setIsOpaque(true); +} + +SkBitmap::Config OmxJpegImageDecoder::getColorSpaceConfig( + SkBitmap::Config pref) { + + // Set the color space to ARGB_8888 for now + // because of limitation in hardware support. + return SkBitmap::kARGB_8888_Config; +} diff --git a/media/tests/omxjpegdecoder/omx_jpeg_decoder.h b/media/tests/omxjpegdecoder/omx_jpeg_decoder.h new file mode 100644 index 0000000..21e2ae6 --- /dev/null +++ b/media/tests/omxjpegdecoder/omx_jpeg_decoder.h @@ -0,0 +1,62 @@ +/* + * 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 OMXJPEGIMAGEDECODER +#define OMXJPEGIMAGEDECODER + +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <media/stagefright/JPEGSource.h> +#include <media/stagefright/MediaSource.h> +#include <media/stagefright/OMXClient.h> +#include <media/stagefright/OMXCodec.h> +#include <SkImageDecoder.h> +#include <SkStream.h> + +using namespace android; + +extern int storeBitmapToFile(SkBitmap* bitmap, char* filename); + +class OmxJpegImageDecoder : public SkImageDecoder { +public: + OmxJpegImageDecoder(); + ~OmxJpegImageDecoder(); + + virtual Format getFormat() const { + return kJPEG_Format; + } + +protected: + virtual bool onDecode(SkStream* stream, SkBitmap* bm, + SkBitmap::Config pref, Mode mode); + +private: + JPEGSource* prepareMediaSource(SkStream* stream); + sp<OMXCodec> getDecoder(OMXClient* client, const sp<MediaSource>& source); + bool decodeSource(sp<OMXCodec> decoder, const sp<MediaSource>& source, + SkBitmap* bm); + void installPixelRef(MediaBuffer* buffer, sp<OMXCodec> decoder, + SkBitmap* bm); + void configBitmapSize(SkBitmap* bm, SkBitmap::Config pref, int width, + int height); + SkBitmap::Config getColorSpaceConfig(SkBitmap::Config pref); + + OMXClient mClient; +}; + +#endif |