Bug 803471 - Part 5c - Cange GonkCamera to use android::Camera. r=mhabicher

This commit is contained in:
Sotaro Ikeda 2013-03-08 14:43:33 -05:00
parent 269dd694f1
commit 102ee3682a
8 changed files with 203 additions and 350 deletions

View File

@ -21,7 +21,6 @@
#include <errno.h>
#include <libgen.h>
#include "base/basictypes.h"
#include "libcameraservice/CameraHardwareInterface.h"
#include "camera/CameraParameters.h"
#include "nsCOMPtr.h"
#include "nsDOMClassInfo.h"
@ -194,7 +193,6 @@ public:
// Construct nsGonkCameraControl on the main thread.
nsGonkCameraControl::nsGonkCameraControl(uint32_t aCameraId, nsIThread* aCameraThread, nsDOMCameraControl* aDOMCameraControl, nsICameraGetCameraCallback* onSuccess, nsICameraErrorCallback* onError, uint64_t aWindowId)
: CameraControlImpl(aCameraId, aCameraThread, aWindowId)
, mHwHandle(0)
, mExposureCompensationMin(0.0)
, mExposureCompensationStep(0.0)
, mDeferConfigUpdate(false)
@ -230,8 +228,8 @@ void nsGonkCameraControl::DispatchInit(nsDOMCameraControl* aDOMCameraControl, ns
nsresult
nsGonkCameraControl::Init()
{
mHwHandle = GonkCameraHardware::GetHandle(this, mCameraId);
DOM_CAMERA_LOGI("Initializing camera %d (this=%p, mHwHandle=%d)\n", mCameraId, this, mHwHandle);
mCameraHw = GonkCameraHardware::Connect(this, mCameraId);
DOM_CAMERA_LOGI("Initializing camera %d (this=%p, mCameraHw=%p)\n", mCameraId, this, mCameraHw.get());
// Initialize our camera configuration database.
PullParametersImpl();
@ -282,12 +280,12 @@ nsGonkCameraControl::Init()
DOM_CAMERA_LOGI(" - maximum metering areas: %d\n", mMaxMeteringAreas);
DOM_CAMERA_LOGI(" - maximum focus areas: %d\n", mMaxFocusAreas);
return mHwHandle != 0 ? NS_OK : NS_ERROR_FAILURE;
return mCameraHw.get() != nullptr ? NS_OK : NS_ERROR_FAILURE;
}
nsGonkCameraControl::~nsGonkCameraControl()
{
DOM_CAMERA_LOGT("%s:%d : this=%p, mHwHandle = %d\n", __func__, __LINE__, this, mHwHandle);
DOM_CAMERA_LOGT("%s:%d : this=%p, mCameraHw = %p\n", __func__, __LINE__, this, mCameraHw.get());
ReleaseHardwareImpl(nullptr);
if (mRwLock) {
@ -653,7 +651,7 @@ nsGonkCameraControl::StartPreviewImpl(StartPreviewTask* aStartPreview)
}
DOM_CAMERA_LOGI("%s: starting preview (mDOMPreview=%p)\n", __func__, mDOMPreview);
if (GonkCameraHardware::StartPreview(mHwHandle) != OK) {
if (mCameraHw->StartPreview() != OK) {
DOM_CAMERA_LOGE("%s: failed to start preview\n", __func__);
return NS_ERROR_FAILURE;
}
@ -672,7 +670,7 @@ nsGonkCameraControl::StopPreviewInternal(bool aForced)
// StopPreview() is a synchronous call--it doesn't return
// until the camera preview thread exits.
if (mDOMPreview) {
GonkCameraHardware::StopPreview(mHwHandle);
mCameraHw->StopPreview();
mDOMPreview->Stopped(aForced);
mDOMPreview = nullptr;
}
@ -690,13 +688,13 @@ nsresult
nsGonkCameraControl::AutoFocusImpl(AutoFocusTask* aAutoFocus)
{
if (aAutoFocus->mCancel) {
GonkCameraHardware::CancelAutoFocus(mHwHandle);
mCameraHw->CancelAutoFocus();
}
mAutoFocusOnSuccessCb = aAutoFocus->mOnSuccessCb;
mAutoFocusOnErrorCb = aAutoFocus->mOnErrorCb;
if (GonkCameraHardware::AutoFocus(mHwHandle) != OK) {
if (mCameraHw->AutoFocus() != OK) {
return NS_ERROR_FAILURE;
}
return NS_OK;
@ -745,7 +743,7 @@ nsresult
nsGonkCameraControl::TakePictureImpl(TakePictureTask* aTakePicture)
{
if (aTakePicture->mCancel) {
GonkCameraHardware::CancelTakePicture(mHwHandle);
mCameraHw->CancelTakePicture();
}
mTakePictureOnSuccessCb = aTakePicture->mOnSuccessCb;
@ -780,7 +778,7 @@ nsGonkCameraControl::TakePictureImpl(TakePictureTask* aTakePicture)
// Convert 'rotation' to a positive value from 0..270 degrees, in steps of 90.
uint32_t r = static_cast<uint32_t>(aTakePicture->mRotation);
r += GonkCameraHardware::GetSensorOrientation(mHwHandle);
r += mCameraHw->GetSensorOrientation();
r %= 360;
r += 45;
r /= 90;
@ -836,7 +834,7 @@ nsGonkCameraControl::TakePictureImpl(TakePictureTask* aTakePicture)
mDeferConfigUpdate = false;
PushParameters();
if (GonkCameraHardware::TakePicture(mHwHandle) != OK) {
if (mCameraHw->TakePicture() != OK) {
return NS_ERROR_FAILURE;
}
return NS_OK;
@ -847,7 +845,7 @@ nsGonkCameraControl::PushParametersImpl()
{
DOM_CAMERA_LOGI("Pushing camera parameters\n");
RwAutoLockRead lock(mRwLock);
if (GonkCameraHardware::PushParameters(mHwHandle, mParams) != OK) {
if (mCameraHw->PushParameters(mParams) != OK) {
return NS_ERROR_FAILURE;
}
@ -859,7 +857,7 @@ nsGonkCameraControl::PullParametersImpl()
{
DOM_CAMERA_LOGI("Pulling camera parameters\n");
RwAutoLockWrite lock(mRwLock);
GonkCameraHardware::PullParameters(mHwHandle, mParams);
mCameraHw->PullParameters(mParams);
return NS_OK;
}
@ -1256,7 +1254,7 @@ nsGonkCameraControl::SetupRecording(int aFd, int aRotation, int64_t aMaxFileSize
nsresult rv = mRecorderProfile->ConfigureRecorder(mRecorder);
NS_ENSURE_SUCCESS(rv, rv);
CHECK_SETARG(mRecorder->setCameraHandle((int32_t)mHwHandle));
CHECK_SETARG(mRecorder->setCamera(mCameraHw));
DOM_CAMERA_LOGI("maxVideoLengthMs=%lld\n", aMaxVideoLengthMs);
if (aMaxVideoLengthMs == 0) {
@ -1274,7 +1272,7 @@ nsGonkCameraControl::SetupRecording(int aFd, int aRotation, int64_t aMaxFileSize
// adjust rotation by camera sensor offset
int r = aRotation;
r += GonkCameraHardware::GetSensorOrientation(mHwHandle, GonkCameraHardware::RAW_SENSOR_ORIENTATION);
r += mCameraHw->GetSensorOrientation(GonkCameraHardware::RAW_SENSOR_ORIENTATION);
r %= 360;
r += 45;
r /= 90;
@ -1338,7 +1336,10 @@ nsGonkCameraControl::ReleaseHardwareImpl(ReleaseHardwareTask* aReleaseHardware)
StopPreviewInternal(true /* forced */);
// release the hardware handle
GonkCameraHardware::ReleaseHandle(mHwHandle, true /* unregister */);
if (mCameraHw.get()){
mCameraHw->Close();
mCameraHw.clear();
}
if (aReleaseHardware) {
nsCOMPtr<nsIRunnable> releaseHardwareResult = new ReleaseHardwareResult(aReleaseHardware->mOnSuccessCb, mWindowId);

View File

@ -26,6 +26,13 @@
#include "CameraControlImpl.h"
#include "CameraCommon.h"
#include "GonkRecorder.h"
#include "GonkCameraHwMgr.h"
namespace android {
class GonkCameraHardware;
class MediaProfiles;
class GonkRecorder;
}
namespace mozilla {
@ -83,7 +90,7 @@ protected:
void SetPreviewSize(uint32_t aWidth, uint32_t aHeight);
void SetupThumbnail(uint32_t aPictureWidth, uint32_t aPictureHeight, uint32_t aPercentQuality);
uint32_t mHwHandle;
android::sp<android::GonkCameraHardware> mCameraHw;
double mExposureCompensationMin;
double mExposureCompensationStep;
bool mDeferConfigUpdate;

View File

@ -14,12 +14,15 @@
* limitations under the License.
*/
#include <binder/IPCThreadState.h>
#include <sys/system_properties.h>
#include "base/basictypes.h"
#include "nsDebug.h"
#include "GonkCameraControl.h"
#include "GonkCameraHwMgr.h"
#include "GonkNativeWindow.h"
#include "CameraCommon.h"
#include <sys/system_properties.h>
using namespace mozilla;
using namespace mozilla::layers;
@ -47,13 +50,15 @@ static __inline void timespecSubtract(struct timespec* a, struct timespec* b)
}
#endif
GonkCameraHardware::GonkCameraHardware(GonkCamera* aTarget, uint32_t aCamera)
: mCamera(aCamera)
GonkCameraHardware::GonkCameraHardware(mozilla::nsGonkCameraControl* aTarget, uint32_t aCameraId, const sp<Camera>& aCamera)
: mCameraId(aCameraId)
, mClosing(false)
, mMonitor("GonkCameraHardware.Monitor")
, mNumFrames(0)
, mCamera(aCamera)
, mTarget(aTarget)
, mInitialized(false)
, mSensorOrientation(0)
{
DOM_CAMERA_LOGT( "%s:%d : this=%p (aTarget=%p)\n", __func__, __LINE__, (void*)this, (void*)aTarget );
Init();
@ -65,60 +70,39 @@ GonkCameraHardware::OnNewFrame()
if (mClosing) {
return;
}
GonkNativeWindow* window = static_cast<GonkNativeWindow*>(mWindow.get());
nsRefPtr<GraphicBufferLocked> buffer = window->getCurrentBuffer();
nsRefPtr<GraphicBufferLocked> buffer = mNativeWindow->getCurrentBuffer();
ReceiveFrame(mTarget, buffer);
}
// Android data callback
void
GonkCameraHardware::DataCallback(int32_t aMsgType, const sp<IMemory> &aDataPtr, camera_frame_metadata_t* aMetadata, void* aUser)
GonkCameraHardware::postData(int32_t aMsgType, const sp<IMemory>& aDataPtr, camera_frame_metadata_t* metadata)
{
GonkCameraHardware* hw = GetHardware((uint32_t)aUser);
if (!hw) {
DOM_CAMERA_LOGW("%s:aUser = %d resolved to no camera hw\n", __func__, (uint32_t)aUser);
return;
}
if (hw->mClosing) {
if (mClosing) {
return;
}
GonkCamera* camera = hw->mTarget;
if (camera) {
switch (aMsgType) {
case CAMERA_MSG_PREVIEW_FRAME:
// Do nothing
break;
switch (aMsgType) {
case CAMERA_MSG_PREVIEW_FRAME:
// Do nothing
break;
case CAMERA_MSG_COMPRESSED_IMAGE:
ReceiveImage(camera, (uint8_t*)aDataPtr->pointer(), aDataPtr->size());
break;
case CAMERA_MSG_COMPRESSED_IMAGE:
ReceiveImage(mTarget, (uint8_t*)aDataPtr->pointer(), aDataPtr->size());
break;
default:
DOM_CAMERA_LOGE("Unhandled data callback event %d\n", aMsgType);
break;
}
} else {
DOM_CAMERA_LOGW("%s: hw = %p (camera = NULL)\n", __func__, hw);
default:
DOM_CAMERA_LOGE("Unhandled data callback event %d\n", aMsgType);
break;
}
}
// Android notify callback
void
GonkCameraHardware::NotifyCallback(int32_t aMsgType, int32_t ext1, int32_t ext2, void* aUser)
GonkCameraHardware::notify(int32_t aMsgType, int32_t ext1, int32_t ext2)
{
bool bSuccess;
GonkCameraHardware* hw = GetHardware((uint32_t)aUser);
if (!hw) {
DOM_CAMERA_LOGW("%s:aUser = %d resolved to no camera hw\n", __func__, (uint32_t)aUser);
return;
}
if (hw->mClosing) {
return;
}
GonkCamera* camera = hw->mTarget;
if (!camera) {
if (mClosing) {
return;
}
@ -131,11 +115,11 @@ GonkCameraHardware::NotifyCallback(int32_t aMsgType, int32_t ext1, int32_t ext2,
DOM_CAMERA_LOGW("Autofocus failed");
bSuccess = false;
}
AutoFocusComplete(camera, bSuccess);
AutoFocusComplete(mTarget, bSuccess);
break;
case CAMERA_MSG_SHUTTER:
OnShutter(camera);
OnShutter(mTarget);
break;
default:
@ -145,30 +129,19 @@ GonkCameraHardware::NotifyCallback(int32_t aMsgType, int32_t ext1, int32_t ext2,
}
void
GonkCameraHardware::DataCallbackTimestamp(nsecs_t aTimestamp, int32_t aMsgType, const sp<IMemory> &aDataPtr, void* aUser)
GonkCameraHardware::postDataTimestamp(nsecs_t aTimestamp, int32_t aMsgType, const sp<IMemory>& aDataPtr)
{
DOM_CAMERA_LOGI("%s",__func__);
GonkCameraHardware* hw = GetHardware((uint32_t)aUser);
if (!hw) {
DOM_CAMERA_LOGE("%s:aUser = %d resolved to no camera hw\n", __func__, (uint32_t)aUser);
return;
}
if (hw->mClosing) {
if (mClosing) {
return;
}
sp<GonkCameraListener> listener;
{
//TODO
//Mutex::Autolock _l(hw->mLock);
listener = hw->mListener;
}
if (listener.get()) {
if (mListener.get()) {
DOM_CAMERA_LOGI("Listener registered, posting recording frame!");
listener->postDataTimestamp(aTimestamp, aMsgType, aDataPtr);
mListener->postDataTimestamp(aTimestamp, aMsgType, aDataPtr);
} else {
DOM_CAMERA_LOGW("No listener was set. Drop a recording frame.");
hw->mHardware->releaseRecordingFrame(aDataPtr);
mCamera->releaseRecordingFrame(aDataPtr);
}
}
@ -177,22 +150,13 @@ GonkCameraHardware::Init()
{
DOM_CAMERA_LOGT("%s: this=%p\n", __func__, (void* )this);
if (hw_get_module(CAMERA_HARDWARE_MODULE_ID, (const hw_module_t**)&mModule) < 0) {
return;
}
char cameraDeviceName[4];
snprintf(cameraDeviceName, sizeof(cameraDeviceName), "%d", mCamera);
mHardware = new CameraHardwareInterface(cameraDeviceName);
if (mHardware->initialize(&mModule->common) != OK) {
mHardware.clear();
return;
}
struct camera_info info;
int rv = mModule->get_camera_info(mCamera, &info);
CameraInfo info;
int rv = Camera::getCameraInfo(mCameraId, &info);
if (rv != 0) {
DOM_CAMERA_LOGE("%s: failed to get CameraInfo mCameraId %d\n", __func__, mCameraId);
return;
}
}
mRawSensorOrientation = info.orientation;
mSensorOrientation = mRawSensorOrientation;
@ -201,7 +165,7 @@ GonkCameraHardware::Init()
char propname[PROP_NAME_MAX];
char prop[PROP_VALUE_MAX];
int offset = 0;
snprintf(propname, sizeof(propname), "ro.moz.cam.%d.sensor_offset", mCamera);
snprintf(propname, sizeof(propname), "ro.moz.cam.%d.sensor_offset", mCameraId);
if (__system_property_get(propname, prop) > 0) {
offset = clamped(atoi(prop), 0, 270);
mSensorOrientation += offset;
@ -209,17 +173,47 @@ GonkCameraHardware::Init()
}
DOM_CAMERA_LOGI("Sensor orientation: base=%d, offset=%d, final=%d\n", info.orientation, offset, mSensorOrientation);
if (sHwHandle == 0) {
sHwHandle = 1; // don't use 0
}
mHardware->setCallbacks(GonkCameraHardware::NotifyCallback, GonkCameraHardware::DataCallback, GonkCameraHardware::DataCallbackTimestamp, (void*)sHwHandle);
mNativeWindow = new GonkNativeWindow();
mNativeWindow->setNewFrameCallback(this);
mCamera->setListener(this);
mCamera->setPreviewTexture(mNativeWindow);
mInitialized = true;
}
sp<GonkCameraHardware>
GonkCameraHardware::Connect(mozilla::nsGonkCameraControl* aTarget, uint32_t aCameraId)
{
sp<Camera> camera = Camera::connect(aCameraId);
if (camera.get() == nullptr) {
return nullptr;
}
sp<GonkCameraHardware> cameraHardware = new GonkCameraHardware(aTarget, aCameraId, camera);
return cameraHardware;
}
void
GonkCameraHardware::Close()
{
DOM_CAMERA_LOGT( "%s:%d : this=%p\n", __func__, __LINE__, (void*)this );
mClosing = true;
mCamera->stopPreview();
mCamera->disconnect();
if (mNativeWindow.get()) {
mNativeWindow->abandon();
}
mCamera.clear();
mNativeWindow.clear();
// Ensure that ICamera's destructor is actually executed
IPCThreadState::self()->flushCommands();
}
GonkCameraHardware::~GonkCameraHardware()
{
DOM_CAMERA_LOGT( "%s:%d : this=%p\n", __func__, __LINE__, (void*)this );
sHw = nullptr;
mCamera.clear();
mNativeWindow.clear();
/**
* Trigger the OnClosed event; the upper layers can't do anything
@ -230,67 +224,17 @@ GonkCameraHardware::~GonkCameraHardware()
}
}
GonkCameraHardware* GonkCameraHardware::sHw = nullptr;
uint32_t GonkCameraHardware::sHwHandle = 0;
void
GonkCameraHardware::ReleaseHandle(uint32_t aHwHandle,
bool aUnregisterTarget = false)
{
GonkCameraHardware* hw = GetHardware(aHwHandle);
DOM_CAMERA_LOGI("%s: aHwHandle = %d, hw = %p (sHwHandle = %d)\n", __func__, aHwHandle, (void*)hw, sHwHandle);
if (!hw) {
return;
}
DOM_CAMERA_LOGT("%s: before: sHwHandle = %d\n", __func__, sHwHandle);
sHwHandle += 1; // invalidate old handles before deleting
hw->mClosing = true;
hw->mHardware->disableMsgType(CAMERA_MSG_ALL_MSGS);
hw->mHardware->stopPreview();
hw->mHardware->release();
GonkNativeWindow* window = static_cast<GonkNativeWindow*>(hw->mWindow.get());
if (window) {
window->abandon();
}
DOM_CAMERA_LOGT("%s: after: sHwHandle = %d\n", __func__, sHwHandle);
if (aUnregisterTarget) {
hw->mTarget = nullptr;
}
delete hw; // destroy the camera hardware instance
}
uint32_t
GonkCameraHardware::GetHandle(GonkCamera* aTarget, uint32_t aCamera)
{
ReleaseHandle(sHwHandle);
sHw = new GonkCameraHardware(aTarget, aCamera);
if (sHw->IsInitialized()) {
return sHwHandle;
}
DOM_CAMERA_LOGE("failed to initialize camera hardware\n");
delete sHw;
sHw = nullptr;
return 0;
}
int
GonkCameraHardware::GetSensorOrientation(uint32_t aHwHandle, uint32_t aType)
GonkCameraHardware::GetSensorOrientation(uint32_t aType)
{
DOM_CAMERA_LOGI("%s: aHwHandle = %d\n", __func__, aHwHandle);
GonkCameraHardware* hw = GetHardware(aHwHandle);
if (!hw) {
return 0;
}
DOM_CAMERA_LOGI("%s\n", __func__);
switch (aType) {
case OFFSET_SENSOR_ORIENTATION:
return hw->mSensorOrientation;
return mSensorOrientation;
case RAW_SENSOR_ORIENTATION:
return hw->mRawSensorOrientation;
return mRawSensorOrientation;
default:
DOM_CAMERA_LOGE("%s:%d : unknown aType=%d\n", __func__, __LINE__, aType);
@ -299,133 +243,66 @@ GonkCameraHardware::GetSensorOrientation(uint32_t aHwHandle, uint32_t aType)
}
int
GonkCameraHardware::AutoFocus(uint32_t aHwHandle)
GonkCameraHardware::AutoFocus()
{
DOM_CAMERA_LOGI("%s: aHwHandle = %d\n", __func__, aHwHandle);
GonkCameraHardware* hw = GetHardware(aHwHandle);
if (!hw) {
return DEAD_OBJECT;
}
hw->mHardware->enableMsgType(CAMERA_MSG_FOCUS);
return hw->mHardware->autoFocus();
DOM_CAMERA_LOGI("%s\n", __func__);
return mCamera->autoFocus();
}
void
GonkCameraHardware::CancelAutoFocus(uint32_t aHwHandle)
GonkCameraHardware::CancelAutoFocus()
{
DOM_CAMERA_LOGI("%s: aHwHandle = %d\n", __func__, aHwHandle);
GonkCameraHardware* hw = GetHardware(aHwHandle);
if (hw) {
hw->mHardware->cancelAutoFocus();
}
DOM_CAMERA_LOGI("%s\n", __func__);
mCamera->cancelAutoFocus();
}
int
GonkCameraHardware::TakePicture(uint32_t aHwHandle)
GonkCameraHardware::TakePicture()
{
GonkCameraHardware* hw = GetHardware(aHwHandle);
if (!hw) {
return DEAD_OBJECT;
}
hw->mHardware->enableMsgType(CAMERA_MSG_COMPRESSED_IMAGE);
return hw->mHardware->takePicture();
return mCamera->takePicture(CAMERA_MSG_SHUTTER | CAMERA_MSG_COMPRESSED_IMAGE);
}
void
GonkCameraHardware::CancelTakePicture(uint32_t aHwHandle)
GonkCameraHardware::CancelTakePicture()
{
GonkCameraHardware* hw = GetHardware(aHwHandle);
if (hw) {
hw->mHardware->cancelPicture();
}
DOM_CAMERA_LOGW("%s: android::Camera do not provide this capability\n", __func__);
}
int
GonkCameraHardware::PushParameters(uint32_t aHwHandle, const CameraParameters& aParams)
GonkCameraHardware::PushParameters(const CameraParameters& aParams)
{
GonkCameraHardware* hw = GetHardware(aHwHandle);
if (!hw) {
return DEAD_OBJECT;
}
return hw->mHardware->setParameters(aParams);
String8 s = aParams.flatten();
return mCamera->setParameters(s);
}
void
GonkCameraHardware::PullParameters(uint32_t aHwHandle, CameraParameters& aParams)
GonkCameraHardware::PullParameters(CameraParameters& aParams)
{
GonkCameraHardware* hw = GetHardware(aHwHandle);
if (hw) {
aParams = hw->mHardware->getParameters();
}
const String8 s = mCamera->getParameters();
aParams.unflatten(s);
}
int
GonkCameraHardware::StartPreview()
{
if (!mWindow.get()) {
mWindow = new GonkNativeWindow(this);
mHardware->setPreviewWindow(mWindow);
}
mHardware->enableMsgType(CAMERA_MSG_PREVIEW_FRAME);
return mHardware->startPreview();
}
int
GonkCameraHardware::StartPreview(uint32_t aHwHandle)
{
GonkCameraHardware* hw = GetHardware(aHwHandle);
DOM_CAMERA_LOGI("%s : aHwHandle = %d, hw = %p\n", __func__, aHwHandle, hw);
if (!hw) {
return DEAD_OBJECT;
}
return hw->StartPreview();
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
return mCamera->startPreview();
}
void
GonkCameraHardware::StopPreview(uint32_t aHwHandle)
GonkCameraHardware::StopPreview()
{
GonkCameraHardware* hw = GetHardware(aHwHandle);
DOM_CAMERA_LOGI("%s : aHwHandle = %d, hw = %p\n", __func__, aHwHandle, hw);
if (hw) {
// Must disable messages first; else some drivers will silently discard
// the stopPreview() request, which can lead to crashes and other
// Very Bad Things that are Hard To Diagnose.
hw->mHardware->disableMsgType(CAMERA_MSG_ALL_MSGS);
hw->mHardware->stopPreview();
}
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
return mCamera->stopPreview();
}
int
GonkCameraHardware::StartRecording(uint32_t aHwHandle)
GonkCameraHardware::StartRecording()
{
DOM_CAMERA_LOGI("%s: aHwHandle = %d\n", __func__, aHwHandle);
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
int rv = OK;
GonkCameraHardware* hw = GetHardware(aHwHandle);
if (!hw) {
return DEAD_OBJECT;
}
if (hw->mHardware->recordingEnabled()) {
return OK;
}
if (!hw->mHardware->previewEnabled()) {
DOM_CAMERA_LOGW("Preview was not enabled, enabling now!\n");
rv = StartPreview(aHwHandle);
if (rv != OK) {
return rv;
}
}
// start recording mode
hw->mHardware->enableMsgType(CAMERA_MSG_VIDEO_FRAME);
DOM_CAMERA_LOGI("Calling hw->startRecording\n");
rv = hw->mHardware->startRecording();
rv = mCamera->startRecording();
if (rv != OK) {
DOM_CAMERA_LOGE("mHardware->startRecording() failed with status %d", rv);
}
@ -433,47 +310,28 @@ GonkCameraHardware::StartRecording(uint32_t aHwHandle)
}
int
GonkCameraHardware::StopRecording(uint32_t aHwHandle)
GonkCameraHardware::StopRecording()
{
DOM_CAMERA_LOGI("%s: aHwHandle = %d\n", __func__, aHwHandle);
GonkCameraHardware* hw = GetHardware(aHwHandle);
if (!hw) {
return DEAD_OBJECT;
}
hw->mHardware->disableMsgType(CAMERA_MSG_VIDEO_FRAME);
hw->mHardware->stopRecording();
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
mCamera->stopRecording();
return OK;
}
int
GonkCameraHardware::SetListener(uint32_t aHwHandle, const sp<GonkCameraListener>& aListener)
GonkCameraHardware::SetListener(const sp<GonkCameraListener>& aListener)
{
GonkCameraHardware* hw = GetHardware(aHwHandle);
if (!hw) {
return DEAD_OBJECT;
}
hw->mListener = aListener;
mListener = aListener;
return OK;
}
void
GonkCameraHardware::ReleaseRecordingFrame(uint32_t aHwHandle, const sp<IMemory>& aFrame)
GonkCameraHardware::ReleaseRecordingFrame(const sp<IMemory>& aFrame)
{
GonkCameraHardware* hw = GetHardware(aHwHandle);
if (hw) {
hw->mHardware->releaseRecordingFrame(aFrame);
}
mCamera->releaseRecordingFrame(aFrame);
}
int
GonkCameraHardware::StoreMetaDataInBuffers(uint32_t aHwHandle, bool aEnabled)
GonkCameraHardware::StoreMetaDataInBuffers(bool aEnabled)
{
GonkCameraHardware* hw = GetHardware(aHwHandle);
if (!hw) {
return DEAD_OBJECT;
}
return hw->mHardware->storeMetaDataInBuffers(aEnabled);
return mCamera->storeMetaDataInBuffers(aEnabled);
}

View File

@ -17,16 +17,17 @@
#ifndef DOM_CAMERA_GONKCAMERAHWMGR_H
#define DOM_CAMERA_GONKCAMERAHWMGR_H
#include "libcameraservice/CameraHardwareInterface.h"
#include "binder/IMemory.h"
#include "mozilla/ReentrantMonitor.h"
#include "GonkCameraListener.h"
#include <binder/IMemory.h>
#include <camera/Camera.h>
#include <camera/CameraParameters.h>
#include <utils/threads.h>
#include "GonkCameraControl.h"
#include "CameraCommon.h"
#include "GonkCameraListener.h"
#include "GonkNativeWindow.h"
#include "mozilla/ReentrantMonitor.h"
// config
#define GIHM_TIMING_RECEIVEFRAME 0
@ -34,25 +35,30 @@
namespace mozilla {
class nsGonkCameraControl;
}
typedef class nsGonkCameraControl GonkCamera;
namespace android {
class GonkCameraHardware : android::GonkNativeWindowNewFrameCallback
class GonkCameraHardware : public GonkNativeWindowNewFrameCallback
, public CameraListener
{
protected:
GonkCameraHardware(GonkCamera* aTarget, uint32_t aCamera);
~GonkCameraHardware();
GonkCameraHardware(mozilla::nsGonkCameraControl* aTarget, uint32_t aCameraId, const sp<Camera>& aCamera);
virtual ~GonkCameraHardware();
void Init();
static void DataCallback(int32_t aMsgType, const android::sp<android::IMemory> &aDataPtr, camera_frame_metadata_t* aMetadata, void* aUser);
static void NotifyCallback(int32_t aMsgType, int32_t ext1, int32_t ext2, void* aUser);
static void DataCallbackTimestamp(nsecs_t aTimestamp, int32_t aMsgType, const android::sp<android::IMemory>& aDataPtr, void* aUser);
public:
static sp<GonkCameraHardware> Connect(mozilla::nsGonkCameraControl* aTarget, uint32_t aCameraId);
void Close();
// derived from GonkNativeWindowNewFrameCallback
virtual void OnNewFrame() MOZ_OVERRIDE;
static void ReleaseHandle(uint32_t aHwHandle, bool aUnregisterTarget);
static uint32_t GetHandle(GonkCamera* aTarget, uint32_t aCamera);
// derived from CameraListener
virtual void notify(int32_t aMsgType, int32_t ext1, int32_t ext2);
virtual void postData(int32_t aMsgType, const sp<IMemory>& aDataPtr, camera_frame_metadata_t* metadata);
virtual void postDataTimestamp(nsecs_t aTimestamp, int32_t aMsgType, const sp<IMemory>& aDataPtr);
/**
* The physical orientation of the camera sensor: 0, 90, 180, or 270.
@ -72,55 +78,36 @@ public:
RAW_SENSOR_ORIENTATION,
OFFSET_SENSOR_ORIENTATION
};
static int GetSensorOrientation(uint32_t aHwHandle, uint32_t aType = OFFSET_SENSOR_ORIENTATION);
int GetSensorOrientation(uint32_t aType = OFFSET_SENSOR_ORIENTATION);
static int AutoFocus(uint32_t aHwHandle);
static void CancelAutoFocus(uint32_t aHwHandle);
static int TakePicture(uint32_t aHwHandle);
static void CancelTakePicture(uint32_t aHwHandle);
static int StartPreview(uint32_t aHwHandle);
static void StopPreview(uint32_t aHwHandle);
static int PushParameters(uint32_t aHwHandle, const android::CameraParameters& aParams);
static void PullParameters(uint32_t aHwHandle, android::CameraParameters& aParams);
static int StartRecording(uint32_t aHwHandle);
static int StopRecording(uint32_t aHwHandle);
static int SetListener(uint32_t aHwHandle, const android::sp<android::GonkCameraListener>& aListener);
static void ReleaseRecordingFrame(uint32_t aHwHandle, const android::sp<android::IMemory>& aFrame);
static int StoreMetaDataInBuffers(uint32_t aHwHandle, bool aEnabled);
int AutoFocus();
void CancelAutoFocus();
int TakePicture();
void CancelTakePicture();
int StartPreview();
void StopPreview();
int PushParameters(const CameraParameters& aParams);
void PullParameters(CameraParameters& aParams);
int StartRecording();
int StopRecording();
int SetListener(const sp<GonkCameraListener>& aListener);
void ReleaseRecordingFrame(const sp<IMemory>& aFrame);
int StoreMetaDataInBuffers(bool aEnabled);
protected:
static GonkCameraHardware* sHw;
static uint32_t sHwHandle;
static GonkCameraHardware* GetHardware(uint32_t aHwHandle)
{
if (aHwHandle == sHwHandle) {
/**
* In the initial case, sHw will be null and sHwHandle will be 0,
* so even if this function is called with aHwHandle = 0, the
* result will still be null.
*/
return sHw;
}
return nullptr;
}
// Instance wrapper to make member function access easier.
int StartPreview();
uint32_t mCamera;
uint32_t mCameraId;
bool mClosing;
mozilla::ReentrantMonitor mMonitor;
uint32_t mNumFrames;
android::sp<android::CameraHardwareInterface> mHardware;
GonkCamera* mTarget;
camera_module_t* mModule;
android::sp<ANativeWindow> mWindow;
sp<Camera> mCamera;
mozilla::nsGonkCameraControl* mTarget;
sp<GonkNativeWindow> mNativeWindow;
#if GIHM_TIMING_OVERALL
struct timespec mStart;
struct timespec mAutoFocusStart;
#endif
android::sp<android::GonkCameraListener> mListener;
sp<GonkCameraListener> mListener;
bool mInitialized;
int mRawSensorOrientation;
int mSensorOrientation;
@ -135,6 +122,6 @@ private:
GonkCameraHardware& operator=(const GonkCameraHardware&) MOZ_DELETE;
};
} // namespace mozilla
} // namespace android
#endif // GONK_IMPL_HW_MGR_H

View File

@ -18,7 +18,7 @@
#define GONK_CAMERA_LISTENER_H
#include <utils/Timers.h>
#include "libcameraservice/CameraHardwareInterface.h"
#include <camera/Camera.h>
namespace android {

View File

@ -14,8 +14,9 @@
* limitations under the License.
*/
#include <camera/Camera.h>
#include "jsapi.h"
#include "libcameraservice/CameraHardwareInterface.h"
#include "GonkCameraControl.h"
#include "DOMCameraManager.h"
#include "CameraCommon.h"
@ -27,24 +28,22 @@ NS_IMETHODIMP
nsDOMCameraManager::GetListOfCameras(JSContext* cx, JS::Value* _retval)
{
JSObject* a = JS_NewArrayObject(cx, 0, nullptr);
camera_module_t* module;
uint32_t index = 0;
uint32_t count;
int32_t count;
if (!a) {
DOM_CAMERA_LOGE("getListOfCameras : Could not create array object");
return NS_ERROR_OUT_OF_MEMORY;
}
if (hw_get_module(CAMERA_HARDWARE_MODULE_ID, (const hw_module_t**)&module) < 0) {
DOM_CAMERA_LOGE("getListOfCameras : Could not load camera HAL module");
count = android::Camera::getNumberOfCameras();
if (count <= 0) {
return NS_ERROR_NOT_AVAILABLE;
}
count = module->get_number_of_cameras();
DOM_CAMERA_LOGI("getListOfCameras : get_number_of_cameras() returned %d\n", count);
while (count--) {
struct camera_info info;
int rv = module->get_camera_info(count, &info);
android::CameraInfo info;
int rv = android::Camera::getCameraInfo(count, &info);
if (rv != 0) {
DOM_CAMERA_LOGE("getListOfCameras : get_camera_info(%d) failed: %d\n", count, rv);
continue;

View File

@ -125,23 +125,24 @@ static int32_t getColorFormat(const char* colorFormat) {
}
GonkCameraSource *GonkCameraSource::Create(
int32_t cameraHandle,
const sp<GonkCameraHardware>& aCameraHw,
Size videoSize,
int32_t frameRate,
bool storeMetaDataInVideoBuffers) {
GonkCameraSource *source = new GonkCameraSource(cameraHandle,
GonkCameraSource *source = new GonkCameraSource(aCameraHw,
videoSize, frameRate,
storeMetaDataInVideoBuffers);
return source;
}
GonkCameraSource::GonkCameraSource(
int32_t cameraHandle,
const sp<GonkCameraHardware>& aCameraHw,
Size videoSize,
int32_t frameRate,
bool storeMetaDataInVideoBuffers)
: mCameraFlags(0),
: mCameraHw(aCameraHw),
mCameraFlags(0),
mVideoFrameRate(-1),
mNumFramesReceived(0),
mLastFrameTimestampUs(0),
@ -156,8 +157,6 @@ GonkCameraSource::GonkCameraSource(
mVideoSize.width = -1;
mVideoSize.height = -1;
mCameraHandle = cameraHandle;
mInitCheck = init(
videoSize, frameRate,
storeMetaDataInVideoBuffers);
@ -310,7 +309,7 @@ status_t GonkCameraSource::configureCamera(
if (isCameraParamChanged) {
// Either frame rate or frame size needs to be changed.
if (OK != GonkCameraHardware::PushParameters(mCameraHandle,*params)) {
if (OK != mCameraHw->PushParameters(*params)) {
LOGE("Could not change settings."
" Someone else is using camera ?");
return -EBUSY;
@ -434,7 +433,7 @@ status_t GonkCameraSource::init(
//TODO: need to do something here to check the sanity of camera
CameraParameters params;
GonkCameraHardware::PullParameters(mCameraHandle, params);
mCameraHw->PullParameters(params);
if ((err = isCameraColorFormatSupported(params)) != OK) {
return err;
}
@ -449,7 +448,7 @@ status_t GonkCameraSource::init(
// Check on video frame size and frame rate.
CameraParameters newCameraParams;
GonkCameraHardware::PullParameters(mCameraHandle, newCameraParams);
mCameraHw->PullParameters(newCameraParams);
if ((err = checkVideoSize(newCameraParams,
videoSize.width, videoSize.height)) != OK) {
return err;
@ -460,9 +459,9 @@ status_t GonkCameraSource::init(
// By default, do not store metadata in video buffers
mIsMetaDataStoredInVideoBuffers = false;
GonkCameraHardware::StoreMetaDataInBuffers(mCameraHandle, false);
mCameraHw->StoreMetaDataInBuffers(false);
if (storeMetaDataInVideoBuffers) {
if (OK == GonkCameraHardware::StoreMetaDataInBuffers(mCameraHandle, true)) {
if (OK == mCameraHw->StoreMetaDataInBuffers(true)) {
mIsMetaDataStoredInVideoBuffers = true;
}
}
@ -515,7 +514,7 @@ GonkCameraSource::~GonkCameraSource() {
int GonkCameraSource::startCameraRecording() {
LOGV("startCameraRecording");
return GonkCameraHardware::StartRecording(mCameraHandle);
return mCameraHw->StartRecording();
}
status_t GonkCameraSource::start(MetaData *meta) {
@ -542,7 +541,7 @@ status_t GonkCameraSource::start(MetaData *meta) {
}
// Register a listener with GonkCameraHardware so that we can get callbacks
GonkCameraHardware::SetListener(mCameraHandle, new GonkCameraSourceListener(this));
mCameraHw->SetListener(new GonkCameraSourceListener(this));
rv = startCameraRecording();
@ -552,7 +551,7 @@ status_t GonkCameraSource::start(MetaData *meta) {
void GonkCameraSource::stopCameraRecording() {
LOGV("stopCameraRecording");
GonkCameraHardware::StopRecording(mCameraHandle);
mCameraHw->StopRecording();
}
void GonkCameraSource::releaseCamera() {
@ -595,7 +594,7 @@ status_t GonkCameraSource::stop() {
void GonkCameraSource::releaseRecordingFrame(const sp<IMemory>& frame) {
LOGV("releaseRecordingFrame");
GonkCameraHardware::ReleaseRecordingFrame(mCameraHandle, frame);
mCameraHw->ReleaseRecordingFrame(frame);
}
void GonkCameraSource::releaseQueuedFrames() {

View File

@ -25,6 +25,8 @@
#include <utils/RefBase.h>
#include <utils/threads.h>
#include "GonkCameraHwMgr.h"
namespace android {
class IMemory;
@ -33,7 +35,7 @@ class GonkCameraSourceListener;
class GonkCameraSource : public MediaSource, public MediaBufferObserver {
public:
static GonkCameraSource *Create(int32_t cameraHandle,
static GonkCameraSource *Create(const sp<GonkCameraHardware>& aCameraHw,
Size videoSize,
int32_t frameRate,
bool storeMetaDataInVideoBuffers = false);
@ -98,7 +100,7 @@ protected:
// Time between capture of two frames.
int64_t mTimeBetweenFrameCaptureUs;
GonkCameraSource(int32_t cameraHandle,
GonkCameraSource(const sp<GonkCameraHardware>& aCameraHw,
Size videoSize, int32_t frameRate,
bool storeMetaDataInVideoBuffers = false);
@ -132,7 +134,7 @@ private:
int64_t mGlitchDurationThresholdUs;
bool mCollectStats;
bool mIsMetaDataStoredInVideoBuffers;
int32_t mCameraHandle;
sp<GonkCameraHardware> mCameraHw;
void releaseQueuedFrames();
void releaseOneRecordingFrame(const sp<IMemory>& frame);