diff options
Diffstat (limited to 'media/libstagefright/omx/QComHardwareRenderer.cpp')
-rw-r--r-- | media/libstagefright/omx/QComHardwareRenderer.cpp | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/media/libstagefright/omx/QComHardwareRenderer.cpp b/media/libstagefright/omx/QComHardwareRenderer.cpp new file mode 100644 index 0000000..5a23792 --- /dev/null +++ b/media/libstagefright/omx/QComHardwareRenderer.cpp @@ -0,0 +1,139 @@ +/* + * 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. + */ + +#undef NDEBUG +#include <assert.h> + +#include <binder/MemoryHeapBase.h> +#include <binder/MemoryHeapPmem.h> +#include <media/stagefright/QComHardwareRenderer.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) { + assert(mISurface.get() != NULL); + assert(mDecodedWidth > 0); + assert(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); +} + +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"); + + mMemoryHeap = new MemoryHeapPmem(master, 0); + mMemoryHeap->slap(); + + ISurface::BufferHeap bufferHeap( + mDisplayWidth, mDisplayHeight, + mDecodedWidth, mDecodedHeight, + PIXEL_FORMAT_YCbCr_420_SP, + mMemoryHeap); + + status_t err = mISurface->registerBuffers(bufferHeap); + assert(err == OK); +} + +} // namespace android |