Add an orientation parameter for overlay, so we can do camera preview in portrait mode.

This commit is contained in:
Chih-Chung Chang
2010-01-21 17:31:06 -08:00
parent 177b580f56
commit e1ceec234c
12 changed files with 55 additions and 33 deletions

View File

@@ -235,6 +235,7 @@ CameraService::Client::Client(const sp<CameraService>& cameraService,
// Callback is disabled by default
mPreviewCallbackFlag = FRAME_CALLBACK_FLAG_NOOP;
mOrientation = 0;
cameraService->incUsers();
LOGV("Client::Client X (pid %d)", callingPid);
}
@@ -570,7 +571,8 @@ status_t CameraService::Client::setOverlay()
// wait in the createOverlay call if the previous overlay is in the
// process of being destroyed.
for (int retry = 0; retry < 50; ++retry) {
mOverlayRef = mSurface->createOverlay(w, h, OVERLAY_FORMAT_DEFAULT);
mOverlayRef = mSurface->createOverlay(w, h, OVERLAY_FORMAT_DEFAULT,
mOrientation);
if (mOverlayRef != NULL) break;
LOGW("Overlay create failed - retrying");
usleep(20000);
@@ -601,15 +603,9 @@ status_t CameraService::Client::registerPreviewBuffers()
CameraParameters params(mHardware->getParameters());
params.getPreviewSize(&w, &h);
uint32_t transform = 0;
if (params.getOrientation() ==
CameraParameters::CAMERA_ORIENTATION_PORTRAIT) {
LOGV("portrait mode");
transform = ISurface::BufferHeap::ROT_90;
}
ISurface::BufferHeap buffers(w, h, w, h,
PIXEL_FORMAT_YCbCr_420_SP,
transform,
mOrientation,
0,
mHardware->getPreviewHeap());
@@ -919,12 +915,6 @@ void CameraService::Client::handleShutter(
if (mSurface != 0 && !mUseOverlay) {
int w, h;
CameraParameters params(mHardware->getParameters());
uint32_t transform = 0;
if (params.getOrientation() == CameraParameters::CAMERA_ORIENTATION_PORTRAIT) {
LOGV("portrait mode");
transform = ISurface::BufferHeap::ROT_90;
}
if (size == NULL) {
params.getPictureSize(&w, &h);
} else {
@@ -935,7 +925,7 @@ void CameraService::Client::handleShutter(
LOGV("Snapshot image width=%d, height=%d", w, h);
}
ISurface::BufferHeap buffers(w, h, w, h,
PIXEL_FORMAT_YCbCr_420_SP, transform, 0, mHardware->getRawHeap());
PIXEL_FORMAT_YCbCr_420_SP, mOrientation, 0, mHardware->getRawHeap());
mSurface->registerBuffers(buffers);
}
@@ -1200,6 +1190,15 @@ status_t CameraService::Client::setParameters(const String8& params)
}
CameraParameters p(params);
// The orientation parameter is actually for CameraService, not for the camera driver.
if (p.getOrientation() == CameraParameters::CAMERA_ORIENTATION_PORTRAIT) {
LOGV("portrait mode");
mOrientation = ISurface::BufferHeap::ROT_90;
} else {
mOrientation = 0;
}
return mHardware->setParameters(p);
}

View File

@@ -182,6 +182,7 @@ private:
sp<CameraService> mCameraService;
sp<ISurface> mSurface;
int mPreviewCallbackFlag;
int mOrientation;
sp<MediaPlayer> mMediaPlayerClick;
sp<MediaPlayer> mMediaPlayerBeep;

View File

@@ -283,7 +283,7 @@ public:
virtual void postBuffer(ssize_t offset);
virtual void unregisterBuffers();
virtual sp<OverlayRef> createOverlay(
uint32_t w, uint32_t h, int32_t format);
uint32_t w, uint32_t h, int32_t format, int32_t orientation);
virtual sp<GraphicBuffer> requestBuffer(int bufferIdx, int usage);
// new functions
@@ -346,7 +346,8 @@ void MSurface::waitUntil(int c0, int c1, int c2) {
}
}
sp<OverlayRef> MSurface::createOverlay(uint32_t w, uint32_t h, int32_t format) {
sp<OverlayRef> MSurface::createOverlay(uint32_t w, uint32_t h, int32_t format,
int32_t orientation) {
// We don't expect this to be called in current hardware.
ASSERT(0);
sp<OverlayRef> dummy;

View File

@@ -86,7 +86,7 @@ public:
virtual void unregisterBuffers() = 0;
virtual sp<OverlayRef> createOverlay(
uint32_t w, uint32_t h, int32_t format) = 0;
uint32_t w, uint32_t h, int32_t format, int32_t orientation) = 0;
};
// ----------------------------------------------------------------------------

View File

@@ -809,7 +809,7 @@ void LayerBaseClient::Surface::unregisterBuffers()
}
sp<OverlayRef> LayerBaseClient::Surface::createOverlay(
uint32_t w, uint32_t h, int32_t format)
uint32_t w, uint32_t h, int32_t format, int32_t orientation)
{
return NULL;
};

View File

@@ -351,7 +351,7 @@ public:
virtual void postBuffer(ssize_t offset);
virtual void unregisterBuffers();
virtual sp<OverlayRef> createOverlay(uint32_t w, uint32_t h,
int32_t format);
int32_t format, int32_t orientation);
protected:
friend class LayerBaseClient;

View File

@@ -182,14 +182,15 @@ status_t LayerBuffer::registerBuffers(const ISurface::BufferHeap& buffers)
/**
* This creates an "overlay" source for this surface
*/
sp<OverlayRef> LayerBuffer::createOverlay(uint32_t w, uint32_t h, int32_t f)
sp<OverlayRef> LayerBuffer::createOverlay(uint32_t w, uint32_t h, int32_t f,
int32_t orientation)
{
sp<OverlayRef> result;
Mutex::Autolock _l(mLock);
if (mSource != 0)
return result;
sp<OverlaySource> source = new OverlaySource(*this, &result, w, h, f);
sp<OverlaySource> source = new OverlaySource(*this, &result, w, h, f, orientation);
if (result != 0) {
mSource = source;
}
@@ -248,11 +249,11 @@ void LayerBuffer::SurfaceLayerBuffer::unregisterBuffers()
}
sp<OverlayRef> LayerBuffer::SurfaceLayerBuffer::createOverlay(
uint32_t w, uint32_t h, int32_t format) {
uint32_t w, uint32_t h, int32_t format, int32_t orientation) {
sp<OverlayRef> result;
sp<LayerBuffer> owner(getOwner());
if (owner != 0)
result = owner->createOverlay(w, h, format);
result = owner->createOverlay(w, h, format, orientation);
return result;
}
@@ -600,9 +601,9 @@ void LayerBuffer::BufferSource::clearTempBufferImage() const
LayerBuffer::OverlaySource::OverlaySource(LayerBuffer& layer,
sp<OverlayRef>* overlayRef,
uint32_t w, uint32_t h, int32_t format)
uint32_t w, uint32_t h, int32_t format, int32_t orientation)
: Source(layer), mVisibilityChanged(false),
mOverlay(0), mOverlayHandle(0), mOverlayDevice(0)
mOverlay(0), mOverlayHandle(0), mOverlayDevice(0), mOrientation(orientation)
{
overlay_control_device_t* overlay_dev = mLayer.mFlinger->getOverlayEngine();
if (overlay_dev == NULL) {
@@ -684,8 +685,12 @@ void LayerBuffer::OverlaySource::onVisibilityResolved(
if (mOverlay) {
overlay_control_device_t* overlay_dev = mOverlayDevice;
overlay_dev->setPosition(overlay_dev, mOverlay, x,y,w,h);
// we need to combine the layer orientation and the
// user-requested orientation.
Transform finalTransform = Transform(mOrientation) *
Transform(mLayer.getOrientation());
overlay_dev->setParameter(overlay_dev, mOverlay,
OVERLAY_TRANSFORM, mLayer.getOrientation());
OVERLAY_TRANSFORM, finalTransform.getOrientation());
overlay_dev->commit(overlay_dev, mOverlay);
}
}

View File

@@ -74,7 +74,8 @@ public:
status_t registerBuffers(const ISurface::BufferHeap& buffers);
void postBuffer(ssize_t offset);
void unregisterBuffers();
sp<OverlayRef> createOverlay(uint32_t w, uint32_t h, int32_t format);
sp<OverlayRef> createOverlay(uint32_t w, uint32_t h, int32_t format,
int32_t orientation);
sp<Source> getSource() const;
sp<Source> clearSource();
@@ -150,7 +151,7 @@ private:
public:
OverlaySource(LayerBuffer& layer,
sp<OverlayRef>* overlayRef,
uint32_t w, uint32_t h, int32_t format);
uint32_t w, uint32_t h, int32_t format, int32_t orientation);
virtual ~OverlaySource();
virtual void onDraw(const Region& clip) const;
virtual void onTransaction(uint32_t flags);
@@ -183,6 +184,7 @@ private:
int32_t mFormat;
int32_t mWidthStride;
int32_t mHeightStride;
int32_t mOrientation;
mutable Mutex mOverlaySourceLock;
bool mInitialized;
};
@@ -200,7 +202,7 @@ private:
virtual void unregisterBuffers();
virtual sp<OverlayRef> createOverlay(
uint32_t w, uint32_t h, int32_t format);
uint32_t w, uint32_t h, int32_t format, int32_t orientation);
private:
sp<LayerBuffer> getOwner() const {
return static_cast<LayerBuffer*>(Surface::getOwner().get());

View File

@@ -42,6 +42,17 @@ Transform::Transform(const Transform& other)
{
}
Transform::Transform(int32_t flags) {
mTransform.reset();
int sx = (flags & FLIP_H) ? -1 : 1;
int sy = (flags & FLIP_V) ? -1 : 1;
if (flags & ROT_90) {
this->set(0, -sy, sx, 0);
} else {
this->set(sx, 0, 0, sy);
}
}
Transform::~Transform() {
}

View File

@@ -38,6 +38,7 @@ class Transform
public:
Transform();
Transform(const Transform& other);
Transform(int32_t flags);
~Transform();
enum orientation_flags {

View File

@@ -115,13 +115,14 @@ public:
}
virtual sp<OverlayRef> createOverlay(
uint32_t w, uint32_t h, int32_t format)
uint32_t w, uint32_t h, int32_t format, int32_t orientation)
{
Parcel data, reply;
data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
data.writeInt32(w);
data.writeInt32(h);
data.writeInt32(format);
data.writeInt32(orientation);
remote()->transact(CREATE_OVERLAY, data, &reply);
return OverlayRef::readFromParcel(reply);
}
@@ -173,7 +174,8 @@ status_t BnSurface::onTransact(
int w = data.readInt32();
int h = data.readInt32();
int f = data.readInt32();
sp<OverlayRef> o = createOverlay(w, h, f);
int orientation = data.readInt32();
sp<OverlayRef> o = createOverlay(w, h, f, orientation);
return OverlayRef::writeToParcel(reply, o);
} break;
default:

View File

@@ -56,7 +56,7 @@ struct DummySurface : public BnSurface {
virtual void unregisterBuffers() {}
virtual sp<OverlayRef> createOverlay(
uint32_t w, uint32_t h, int32_t format) {
uint32_t w, uint32_t h, int32_t format, int32_t orientation) {
return NULL;
}