Merge change 5892
* changes: Hardware overlay support
This commit is contained in:
@@ -227,6 +227,8 @@ CameraService::Client::Client(const sp<CameraService>& cameraService,
|
||||
|
||||
mMediaPlayerClick = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
|
||||
mMediaPlayerBeep = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
|
||||
mOverlayW = 0;
|
||||
mOverlayH = 0;
|
||||
|
||||
// Callback is disabled by default
|
||||
mPreviewCallbackFlag = FRAME_CALLBACK_FLAG_NOOP;
|
||||
@@ -399,6 +401,11 @@ void CameraService::Client::disconnect()
|
||||
mHardware->cancelPicture(true, true, true);
|
||||
// Release the hardware resources.
|
||||
mHardware->release();
|
||||
// Release the held overlay resources.
|
||||
if (mUseOverlay)
|
||||
{
|
||||
mOverlayRef = 0;
|
||||
}
|
||||
mHardware.clear();
|
||||
|
||||
mCameraService->removeClient(mCameraClient);
|
||||
@@ -420,11 +427,21 @@ status_t CameraService::Client::setPreviewDisplay(const sp<ISurface>& surface)
|
||||
result = NO_ERROR;
|
||||
// asBinder() is safe on NULL (returns NULL)
|
||||
if (surface->asBinder() != mSurface->asBinder()) {
|
||||
if (mSurface != 0 && !mUseOverlay) {
|
||||
if (mSurface != 0) {
|
||||
LOGD("clearing old preview surface %p", mSurface.get());
|
||||
mSurface->unregisterBuffers();
|
||||
if ( !mUseOverlay)
|
||||
{
|
||||
mSurface->unregisterBuffers();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Force the destruction of any previous overlay
|
||||
sp<Overlay> dummy;
|
||||
mHardware->setOverlay( dummy );
|
||||
}
|
||||
}
|
||||
mSurface = surface;
|
||||
mOverlayRef = 0;
|
||||
// If preview has been already started, set overlay or register preview
|
||||
// buffers now.
|
||||
if (mHardware->previewEnabled()) {
|
||||
@@ -520,8 +537,8 @@ status_t CameraService::Client::setOverlay()
|
||||
|
||||
const char *format = params.getPreviewFormat();
|
||||
int fmt;
|
||||
if (!strcmp(format, "yuv422i"))
|
||||
fmt = OVERLAY_FORMAT_YCbCr_422_I;
|
||||
if (!strcmp(format, "yuv422i-yuyv"))
|
||||
fmt = OVERLAY_FORMAT_YCbYCr_422_I;
|
||||
else if (!strcmp(format, "rgb565"))
|
||||
fmt = OVERLAY_FORMAT_RGB_565;
|
||||
else {
|
||||
@@ -529,16 +546,35 @@ status_t CameraService::Client::setOverlay()
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ( w != mOverlayW || h != mOverlayH )
|
||||
{
|
||||
// Force the destruction of any previous overlay
|
||||
sp<Overlay> dummy;
|
||||
mHardware->setOverlay( dummy );
|
||||
mOverlayRef = 0;
|
||||
}
|
||||
|
||||
status_t ret = NO_ERROR;
|
||||
if (mSurface != 0) {
|
||||
sp<OverlayRef> ref = mSurface->createOverlay(w, h, fmt);
|
||||
ret = mHardware->setOverlay(new Overlay(ref));
|
||||
if (mOverlayRef.get() == NULL) {
|
||||
mOverlayRef = mSurface->createOverlay(w, h, fmt);
|
||||
if ( mOverlayRef.get() == NULL )
|
||||
{
|
||||
LOGE("Overlay Creation Failed!");
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = mHardware->setOverlay(new Overlay(mOverlayRef));
|
||||
}
|
||||
} else {
|
||||
ret = mHardware->setOverlay(NULL);
|
||||
}
|
||||
if (ret != NO_ERROR) {
|
||||
LOGE("mHardware->setOverlay() failed with status %d\n", ret);
|
||||
}
|
||||
|
||||
mOverlayW = w;
|
||||
mOverlayH = h;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1092,6 +1128,7 @@ void CameraService::Client::postPreviewFrame(const sp<IMemory>& mem)
|
||||
ssize_t offset;
|
||||
size_t size;
|
||||
sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
|
||||
if ( !mUseOverlay )
|
||||
{
|
||||
Mutex::Autolock surfaceLock(mSurfaceLock);
|
||||
if (mSurface != NULL) {
|
||||
|
||||
@@ -189,6 +189,10 @@ private:
|
||||
sp<CameraHardwareInterface> mHardware;
|
||||
pid_t mClientPid;
|
||||
bool mUseOverlay;
|
||||
|
||||
sp<OverlayRef> mOverlayRef;
|
||||
int mOverlayW;
|
||||
int mOverlayH;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
@@ -82,6 +82,10 @@ public:
|
||||
/* release the overlay buffer and post it */
|
||||
status_t queueBuffer(overlay_buffer_t buffer);
|
||||
|
||||
status_t setCrop(uint32_t x, uint32_t y, uint32_t w, uint32_t h) ;
|
||||
|
||||
status_t getCrop(uint32_t* x, uint32_t* y, uint32_t* w, uint32_t* h) ;
|
||||
|
||||
/* returns the address of a given buffer if supported, NULL otherwise. */
|
||||
void* getBufferAddress(overlay_buffer_t buffer);
|
||||
|
||||
|
||||
@@ -59,6 +59,18 @@ status_t Overlay::queueBuffer(overlay_buffer_t buffer)
|
||||
return mOverlayData->queueBuffer(mOverlayData, buffer);
|
||||
}
|
||||
|
||||
status_t Overlay::setCrop(uint32_t x, uint32_t y, uint32_t w, uint32_t h)
|
||||
{
|
||||
if (mStatus != NO_ERROR) return mStatus;
|
||||
return mOverlayData->setCrop(mOverlayData, x, y, w, h);
|
||||
}
|
||||
|
||||
status_t Overlay::getCrop(uint32_t* x, uint32_t* y, uint32_t* w, uint32_t* h)
|
||||
{
|
||||
if (mStatus != NO_ERROR) return mStatus;
|
||||
return mOverlayData->getCrop(mOverlayData, x, y, w, h);
|
||||
}
|
||||
|
||||
int32_t Overlay::getBufferCount() const
|
||||
{
|
||||
if (mStatus != NO_ERROR) return mStatus;
|
||||
@@ -73,6 +85,15 @@ void* Overlay::getBufferAddress(overlay_buffer_t buffer)
|
||||
|
||||
void Overlay::destroy() {
|
||||
if (mStatus != NO_ERROR) return;
|
||||
|
||||
// Must delete the objects in reverse creation order, thus the
|
||||
// data side must be closed first and then the destroy send to
|
||||
// the control side.
|
||||
if (mOverlayData) {
|
||||
overlay_data_close(mOverlayData);
|
||||
mOverlayData = NULL;
|
||||
}
|
||||
|
||||
mOverlayRef->mOverlayChannel->destroy();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user