/* * 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 #include "TIHardwareRenderer.h" #include #include #include #include "v4l2_utils.h" #define CACHEABLE_BUFFERS 0x1 namespace android { //////////////////////////////////////////////////////////////////////////////// TIHardwareRenderer::TIHardwareRenderer( const sp &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 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