Add an orientation parameter for overlay, so we can do camera preview in portrait mode.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -182,6 +182,7 @@ private:
|
||||
sp<CameraService> mCameraService;
|
||||
sp<ISurface> mSurface;
|
||||
int mPreviewCallbackFlag;
|
||||
int mOrientation;
|
||||
|
||||
sp<MediaPlayer> mMediaPlayerClick;
|
||||
sp<MediaPlayer> mMediaPlayerBeep;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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() {
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ class Transform
|
||||
public:
|
||||
Transform();
|
||||
Transform(const Transform& other);
|
||||
Transform(int32_t flags);
|
||||
~Transform();
|
||||
|
||||
enum orientation_flags {
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user