Bug 779351 - Camera needs to get/configure the SourceMediaStream on the main thread, r=roc

This commit is contained in:
Mike Habicher 2012-08-01 14:21:27 -04:00
parent 61c5acf48f
commit 7db1f300b0
6 changed files with 48 additions and 27 deletions

View File

@ -398,9 +398,7 @@ nsCameraControl::GetPreviewStream(const JS::Value& aOptions, nsICameraPreviewStr
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIRunnable> getPreviewStreamTask = new GetPreviewStreamTask(this, size, onSuccess, onError);
mCameraThread->Dispatch(getPreviewStreamTask, NS_DISPATCH_NORMAL);
return NS_OK;
return NS_DispatchToMainThread(getPreviewStreamTask);
}
/* void autoFocus (in nsICameraAutoFocusCallback onSuccess, [optional] in nsICameraErrorCallback onError); */

View File

@ -62,12 +62,13 @@ protected:
nsCOMPtr<CameraPreview> mPreview;
};
CameraPreview::CameraPreview(PRUint32 aWidth, PRUint32 aHeight)
CameraPreview::CameraPreview(nsIThread* aCameraThread, PRUint32 aWidth, PRUint32 aHeight)
: nsDOMMediaStream()
, mWidth(aWidth)
, mHeight(aHeight)
, mFramesPerSecond(0)
, mFrameCount(0)
, mCameraThread(aCameraThread)
{
DOM_CAMERA_LOGI("%s:%d : mWidth=%d, mHeight=%d : this=%p\n", __func__, __LINE__, mWidth, mHeight, this);
@ -86,13 +87,27 @@ CameraPreview::SetFrameRate(PRUint32 aFramesPerSecond)
mInput->AdvanceKnownTracksTime(MEDIA_TIME_MAX);
}
void
CameraPreview::Start()
{
nsCOMPtr<nsIRunnable> cameraPreviewControl = NS_NewRunnableMethod(this, &CameraPreview::StartImpl);
nsresult rv = mCameraThread->Dispatch(cameraPreviewControl, NS_DISPATCH_NORMAL);
if (NS_FAILED(rv)) {
DOM_CAMERA_LOGE("failed to start camera preview (%d)\n", rv);
}
}
void
CameraPreview::Stop()
{
nsCOMPtr<nsIRunnable> cameraPreviewControl = NS_NewRunnableMethod(this, &CameraPreview::StopImpl);
nsresult rv = mCameraThread->Dispatch(cameraPreviewControl, NS_DISPATCH_NORMAL);
if (NS_FAILED(rv)) {
DOM_CAMERA_LOGE("failed to stop camera preview (%d)\n", rv);
}
}
CameraPreview::~CameraPreview()
{
DOM_CAMERA_LOGI("%s:%d : this=%p\n", __func__, __LINE__, this);
/**
* We _must_ remember to call RemoveListener on this before destroying this,
* else the media framework will trigger a double-free.
*/
DOM_CAMERA_LOGI("%s:%d : this=%p\n", __func__, __LINE__, this);
}

View File

@ -23,7 +23,7 @@ class CameraPreview : public nsDOMMediaStream
public:
NS_DECL_ISUPPORTS
CameraPreview(PRUint32 aWidth, PRUint32 aHeight);
CameraPreview(nsIThread* aCameraThread, PRUint32 aWidth, PRUint32 aHeight);
void SetFrameRate(PRUint32 aFramesPerSecond);
@ -32,8 +32,11 @@ public:
return nsDOMMediaStream::GetCurrentTime(aCurrentTime);
}
virtual void Start() = 0;
virtual void Stop() = 0;
void Start();
void Stop();
virtual nsresult StartImpl() = 0;
virtual nsresult StopImpl() = 0;
protected:
virtual ~CameraPreview();
@ -45,6 +48,7 @@ protected:
nsRefPtr<mozilla::layers::ImageContainer> mImageContainer;
VideoSegment mVideoSegment;
PRUint32 mFrameCount;
nsCOMPtr<nsIThread> mCameraThread;
enum { TRACK_VIDEO = 1 };

View File

@ -414,7 +414,7 @@ nsGonkCameraControl::GetPreviewStreamImpl(GetPreviewStreamTask* aGetPreviewStrea
nsresult rv;
if (!preview) {
preview = new GonkCameraPreview(mHwHandle, aGetPreviewStream->mSize.width, aGetPreviewStream->mSize.height);
preview = new GonkCameraPreview(mCameraThread, mHwHandle, aGetPreviewStream->mSize.width, aGetPreviewStream->mSize.height);
if (!preview) {
if (aGetPreviewStream->mOnErrorCb) {
rv = NS_DispatchToMainThread(new CameraErrorResult(aGetPreviewStream->mOnErrorCb, NS_LITERAL_STRING("OUT_OF_MEMORY")));

View File

@ -162,8 +162,8 @@ GonkCameraPreview::ReceiveFrame(PRUint8 *aData, PRUint32 aLength)
}
}
void
GonkCameraPreview::Start()
nsresult
GonkCameraPreview::StartImpl()
{
DOM_CAMERA_LOGI("%s:%d : this=%p\n", __func__, __LINE__, this);
@ -177,21 +177,25 @@ GonkCameraPreview::Start()
GonkCameraHardware::GetPreviewSize(mHwHandle, &mWidth, &mHeight);
SetFrameRate(GonkCameraHardware::GetFps(mHwHandle));
if (GonkCameraHardware::StartPreview(mHwHandle) == OK) {
// GetPreviewFormat() must be called after StartPreview().
mFormat = GonkCameraHardware::GetPreviewFormat(mHwHandle);
DOM_CAMERA_LOGI("preview stream is (actually!) %d x %d (w x h), %d frames per second, format %d\n", mWidth, mHeight, mFramesPerSecond, mFormat);
} else {
if (GonkCameraHardware::StartPreview(mHwHandle) != OK) {
DOM_CAMERA_LOGE("%s: failed to start preview\n", __func__);
return NS_ERROR_FAILURE;
}
// GetPreviewFormat() must be called after StartPreview().
mFormat = GonkCameraHardware::GetPreviewFormat(mHwHandle);
DOM_CAMERA_LOGI("preview stream is (actually!) %d x %d (w x h), %d frames per second, format %d\n", mWidth, mHeight, mFramesPerSecond, mFormat);
return NS_OK;
}
void
GonkCameraPreview::Stop()
nsresult
GonkCameraPreview::StopImpl()
{
DOM_CAMERA_LOGI("%s:%d : this=%p\n", __func__, __LINE__, this);
GonkCameraHardware::StopPreview(mHwHandle);
mInput->EndTrack(TRACK_VIDEO);
mInput->Finish();
return NS_OK;
}

View File

@ -27,8 +27,8 @@ namespace mozilla {
class GonkCameraPreview : public CameraPreview
{
public:
GonkCameraPreview(PRUint32 aHwHandle, PRUint32 aWidth, PRUint32 aHeight)
: CameraPreview(aWidth, aHeight)
GonkCameraPreview(nsIThread* aCameraThread, PRUint32 aHwHandle, PRUint32 aWidth, PRUint32 aHeight)
: CameraPreview(aCameraThread, aWidth, aHeight)
, mHwHandle(aHwHandle)
, mDiscardedFrameCount(0)
, mFormat(GonkCameraHardware::PREVIEW_FORMAT_UNKNOWN)
@ -36,8 +36,8 @@ public:
void ReceiveFrame(PRUint8 *aData, PRUint32 aLength);
void Start();
void Stop();
nsresult StartImpl();
nsresult StopImpl();
protected:
~GonkCameraPreview()