blob: 53818d64b72f0f20a13549d97e44102667803714 [file] [log] [blame]
/*
* 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 "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