diff options
Diffstat (limited to 'media/tests/omxjpegdecoder/omx_jpeg_decoder.cpp')
-rw-r--r-- | media/tests/omxjpegdecoder/omx_jpeg_decoder.cpp | 197 |
1 files changed, 197 insertions, 0 deletions
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; +} |