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:
35
include/media/stagefright/HardwareAPI.h
Normal file
35
include/media/stagefright/HardwareAPI.h
Normal 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_
|
||||
|
@ -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_
|
@ -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_
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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
|
@ -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
|
||||
|
Reference in New Issue
Block a user