am d0f3228d: resolved conflicts for merge of c66d53f9 to eclair-mr2

Merge commit 'd0f3228daa9ea26ec959cb79451e6f150648bce8' into eclair-mr2-plus-aosp

* commit 'd0f3228daa9ea26ec959cb79451e6f150648bce8':
  Delegate the platform dependent hardware renderer implementation to a shared library provided by the vendor.
This commit is contained in:
Andreas Huber
2009-11-12 10:43:31 -08:00
committed by Android Git Automerger
7 changed files with 69 additions and 416 deletions

View File

@ -0,0 +1,35 @@
/*
* 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 HARDWARE_API_H_
#define HARDWARE_API_H_
#include <media/stagefright/VideoRenderer.h>
#include <ui/ISurface.h>
#include <utils/RefBase.h>
#include <OMX_Component.h>
extern android::VideoRenderer *createRenderer(
const android::sp<android::ISurface> &surface,
const char *componentName,
OMX_COLOR_FORMATTYPE colorFormat,
size_t displayWidth, size_t displayHeight,
size_t decodedWidth, size_t decodedHeight);
#endif // HARDWARE_API_H_

View File

@ -1,57 +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 QCOM_HARDWARE_RENDERER_H_
#define QCOM_HARDWARE_RENDERER_H_
#include <media/stagefright/VideoRenderer.h>
#include <utils/RefBase.h>
namespace android {
class ISurface;
class MemoryHeapPmem;
class QComHardwareRenderer : public VideoRenderer {
public:
QComHardwareRenderer(
const sp<ISurface> &surface,
size_t displayWidth, size_t displayHeight,
size_t decodedWidth, size_t decodedHeight);
virtual ~QComHardwareRenderer();
virtual void render(
const void *data, size_t size, void *platformPrivate);
private:
sp<ISurface> mISurface;
size_t mDisplayWidth, mDisplayHeight;
size_t mDecodedWidth, mDecodedHeight;
size_t mFrameSize;
sp<MemoryHeapPmem> mMemoryHeap;
bool getOffset(void *platformPrivate, size_t *offset);
void publishBuffers(uint32_t pmem_fd);
QComHardwareRenderer(const QComHardwareRenderer &);
QComHardwareRenderer &operator=(const QComHardwareRenderer &);
};
} // namespace android
#endif // QCOM_HARDWARE_RENDERER_H_

View File

@ -1,59 +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 TI_HARDWARE_RENDERER_H_
#define TI_HARDWARE_RENDERER_H_
#include <media/stagefright/VideoRenderer.h>
#include <utils/RefBase.h>
#include <utils/Vector.h>
namespace android {
class ISurface;
class Overlay;
class TIHardwareRenderer : public VideoRenderer {
public:
TIHardwareRenderer(
const sp<ISurface> &surface,
size_t displayWidth, size_t displayHeight,
size_t decodedWidth, size_t decodedHeight);
virtual ~TIHardwareRenderer();
virtual void render(
const void *data, size_t size, void *platformPrivate);
private:
sp<ISurface> mISurface;
size_t mDisplayWidth, mDisplayHeight;
size_t mDecodedWidth, mDecodedHeight;
size_t mFrameSize;
sp<Overlay> mOverlay;
Vector<void *> mOverlayAddresses;
bool mIsFirstFrame;
size_t mIndex;
TIHardwareRenderer(const TIHardwareRenderer &);
TIHardwareRenderer &operator=(const TIHardwareRenderer &);
};
} // namespace android
#endif // TI_HARDWARE_RENDERER_H_

View File

@ -6,16 +6,13 @@ include external/opencore/Config.mk
LOCAL_C_INCLUDES := $(PV_INCLUDES)
LOCAL_CFLAGS := $(PV_CFLAGS_MINUS_VISIBILITY)
LOCAL_C_INCLUDES += $(TOP)/hardware/ti/omap3/liboverlay
LOCAL_C_INCLUDES += $(JNI_H_INCLUDE)
LOCAL_SRC_FILES:= \
ColorConverter.cpp \
OMX.cpp \
OMXNodeInstance.cpp \
QComHardwareRenderer.cpp \
SoftwareRenderer.cpp \
TIHardwareRenderer.cpp
SoftwareRenderer.cpp
LOCAL_SHARED_LIBRARIES := \
libbinder \
@ -26,7 +23,11 @@ LOCAL_SHARED_LIBRARIES := \
libopencore_common
ifeq ($(TARGET_OS)-$(TARGET_SIMULATOR),linux-true)
LOCAL_LDLIBS += -lpthread
LOCAL_LDLIBS += -lpthread -ldl
endif
ifneq ($(TARGET_SIMULATOR),true)
LOCAL_SHARED_LIBRARIES += libdl
endif
LOCAL_PRELINK_MODULE:= false

View File

@ -24,9 +24,7 @@
#include "pv_omxcore.h"
#include "../include/OMXNodeInstance.h"
#include "../include/QComHardwareRenderer.h"
#include "../include/SoftwareRenderer.h"
#include "../include/TIHardwareRenderer.h"
#include <binder/IMemory.h>
#include <media/stagefright/MediaDebug.h>
@ -431,27 +429,37 @@ sp<IOMXRenderer> OMX::createRenderer(
OMX_COLOR_FORMATTYPE colorFormat,
size_t encodedWidth, size_t encodedHeight,
size_t displayWidth, size_t displayHeight) {
Mutex::Autolock autoLock(mLock);
VideoRenderer *impl = NULL;
static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00;
static void *libHandle = NULL;
if (colorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar
&& !strncmp(componentName, "OMX.qcom.video.decoder.", 23)) {
LOGW("Using QComHardwareRenderer.");
impl =
new QComHardwareRenderer(
surface,
displayWidth, displayHeight,
encodedWidth, encodedHeight);
} else if (colorFormat == OMX_COLOR_FormatCbYCrY
&& !strcmp(componentName, "OMX.TI.Video.Decoder")) {
LOGW("Using TIHardwareRenderer.");
impl =
new TIHardwareRenderer(
surface,
displayWidth, displayHeight,
encodedWidth, encodedHeight);
} else {
if (!libHandle) {
libHandle = dlopen("libstagefrighthw.so", RTLD_NOW);
}
if (libHandle) {
typedef VideoRenderer *(*CreateRendererFunc)(
const sp<ISurface> &surface,
const char *componentName,
OMX_COLOR_FORMATTYPE colorFormat,
size_t displayWidth, size_t displayHeight,
size_t decodedWidth, size_t decodedHeight);
CreateRendererFunc func =
(CreateRendererFunc)dlsym(
libHandle,
"_Z14createRendererRKN7android2spINS_8ISurfaceEEEPKc20"
"OMX_COLOR_FORMATTYPEjjjj");
if (func) {
impl = (*func)(surface, componentName, colorFormat,
displayWidth, displayHeight, encodedWidth, encodedHeight);
}
}
if (!impl) {
LOGW("Using software renderer.");
impl = new SoftwareRenderer(
colorFormat,

View File

@ -1,144 +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/QComHardwareRenderer.h"
#include <binder/MemoryHeapBase.h>
#include <binder/MemoryHeapPmem.h>
#include <media/stagefright/MediaDebug.h>
#include <ui/ISurface.h>
namespace android {
////////////////////////////////////////////////////////////////////////////////
typedef struct PLATFORM_PRIVATE_ENTRY
{
/* Entry type */
uint32_t type;
/* Pointer to platform specific entry */
void *entry;
} PLATFORM_PRIVATE_ENTRY;
typedef struct PLATFORM_PRIVATE_LIST
{
/* Number of entries */
uint32_t nEntries;
/* Pointer to array of platform specific entries *
* Contiguous block of PLATFORM_PRIVATE_ENTRY elements */
PLATFORM_PRIVATE_ENTRY *entryList;
} PLATFORM_PRIVATE_LIST;
// data structures for tunneling buffers
typedef struct PLATFORM_PRIVATE_PMEM_INFO
{
/* pmem file descriptor */
uint32_t pmem_fd;
uint32_t offset;
} PLATFORM_PRIVATE_PMEM_INFO;
#define PLATFORM_PRIVATE_PMEM 1
QComHardwareRenderer::QComHardwareRenderer(
const sp<ISurface> &surface,
size_t displayWidth, size_t displayHeight,
size_t decodedWidth, size_t decodedHeight)
: mISurface(surface),
mDisplayWidth(displayWidth),
mDisplayHeight(displayHeight),
mDecodedWidth(decodedWidth),
mDecodedHeight(decodedHeight),
mFrameSize((mDecodedWidth * mDecodedHeight * 3) / 2) {
CHECK(mISurface.get() != NULL);
CHECK(mDecodedWidth > 0);
CHECK(mDecodedHeight > 0);
}
QComHardwareRenderer::~QComHardwareRenderer() {
mISurface->unregisterBuffers();
}
void QComHardwareRenderer::render(
const void *data, size_t size, void *platformPrivate) {
size_t offset;
if (!getOffset(platformPrivate, &offset)) {
return;
}
mISurface->postBuffer(offset);
// Since we cannot tell how long it'll take until surface flinger
// has displayed the data onscreen, we'll just have to guess...
// We must not return the buffer to the decoder before it's been displayed.
usleep(25000);
}
bool QComHardwareRenderer::getOffset(void *platformPrivate, size_t *offset) {
*offset = 0;
PLATFORM_PRIVATE_LIST *list = (PLATFORM_PRIVATE_LIST *)platformPrivate;
for (uint32_t i = 0; i < list->nEntries; ++i) {
if (list->entryList[i].type != PLATFORM_PRIVATE_PMEM) {
continue;
}
PLATFORM_PRIVATE_PMEM_INFO *info =
(PLATFORM_PRIVATE_PMEM_INFO *)list->entryList[i].entry;
if (info != NULL) {
if (mMemoryHeap.get() == NULL) {
publishBuffers(info->pmem_fd);
}
if (mMemoryHeap.get() == NULL) {
return false;
}
*offset = info->offset;
return true;
}
}
return false;
}
void QComHardwareRenderer::publishBuffers(uint32_t pmem_fd) {
sp<MemoryHeapBase> master =
reinterpret_cast<MemoryHeapBase *>(pmem_fd);
master->setDevice("/dev/pmem");
uint32_t heap_flags = master->getFlags() & MemoryHeapBase::NO_CACHING;
mMemoryHeap = new MemoryHeapPmem(master, heap_flags);
mMemoryHeap->slap();
ISurface::BufferHeap bufferHeap(
mDisplayWidth, mDisplayHeight,
mDecodedWidth, mDecodedHeight,
PIXEL_FORMAT_YCbCr_420_SP,
mMemoryHeap);
status_t err = mISurface->registerBuffers(bufferHeap);
CHECK_EQ(err, OK);
}
} // namespace android

View File

@ -1,131 +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 "TIHardwareRenderer"
#include <utils/Log.h>
#include "../include/TIHardwareRenderer.h"
#include <media/stagefright/MediaDebug.h>
#include <ui/ISurface.h>
#include <ui/Overlay.h>
#include "v4l2_utils.h"
#define CACHEABLE_BUFFERS 0x1
namespace android {
////////////////////////////////////////////////////////////////////////////////
TIHardwareRenderer::TIHardwareRenderer(
const sp<ISurface> &surface,
size_t displayWidth, size_t displayHeight,
size_t decodedWidth, size_t decodedHeight)
: mISurface(surface),
mDisplayWidth(displayWidth),
mDisplayHeight(displayHeight),
mDecodedWidth(decodedWidth),
mDecodedHeight(decodedHeight),
mFrameSize(mDecodedWidth * mDecodedHeight * 2),
mIsFirstFrame(true),
mIndex(0) {
CHECK(mISurface.get() != NULL);
CHECK(mDecodedWidth > 0);
CHECK(mDecodedHeight > 0);
sp<OverlayRef> ref = mISurface->createOverlay(
mDisplayWidth, mDisplayHeight, OVERLAY_FORMAT_CbYCrY_422_I);
if (ref.get() == NULL) {
LOGE("Unable to create the overlay!");
return;
}
mOverlay = new Overlay(ref);
mOverlay->setParameter(CACHEABLE_BUFFERS, 0);
for (size_t i = 0; i < (size_t)mOverlay->getBufferCount(); ++i) {
mapping_data_t *data =
(mapping_data_t *)mOverlay->getBufferAddress((void *)i);
mOverlayAddresses.push(data->ptr);
}
}
TIHardwareRenderer::~TIHardwareRenderer() {
if (mOverlay.get() != NULL) {
mOverlay->destroy();
mOverlay.clear();
// XXX apparently destroying an overlay is an asynchronous process...
sleep(1);
}
}
void TIHardwareRenderer::render(
const void *data, size_t size, void *platformPrivate) {
// CHECK_EQ(size, mFrameSize);
if (mOverlay.get() == NULL) {
return;
}
#if 0
size_t i = 0;
for (; i < mOverlayAddresses.size(); ++i) {
if (mOverlayAddresses[i] == data) {
break;
}
if (mIsFirstFrame) {
LOGI("overlay buffer #%d: %p", i, mOverlayAddresses[i]);
}
}
if (i == mOverlayAddresses.size()) {
LOGE("No suitable overlay buffer found.");
return;
}
mOverlay->queueBuffer((void *)i);
overlay_buffer_t overlay_buffer;
if (!mIsFirstFrame) {
CHECK_EQ(mOverlay->dequeueBuffer(&overlay_buffer), OK);
} else {
mIsFirstFrame = false;
}
#else
memcpy(mOverlayAddresses[mIndex], data, size);
mOverlay->queueBuffer((void *)mIndex);
if (++mIndex == mOverlayAddresses.size()) {
mIndex = 0;
}
overlay_buffer_t overlay_buffer;
if (!mIsFirstFrame) {
CHECK_EQ(mOverlay->dequeueBuffer(&overlay_buffer), OK);
} else {
mIsFirstFrame = false;
}
#endif
}
} // namespace android