Bug 801693 - Plumb video recorder state-change (error, size/length limit) handling. r=jst
This commit is contained in:
@@ -26,6 +26,7 @@ CameraControlImpl::CameraControlImpl(uint32_t aCameraId, nsIThread* aCameraThrea
|
|||||||
, mStartRecordingOnErrorCb(nullptr)
|
, mStartRecordingOnErrorCb(nullptr)
|
||||||
, mOnShutterCb(nullptr)
|
, mOnShutterCb(nullptr)
|
||||||
, mOnClosedCb(nullptr)
|
, mOnClosedCb(nullptr)
|
||||||
|
, mOnRecorderStateChangeCb(nullptr)
|
||||||
{
|
{
|
||||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||||
}
|
}
|
||||||
@@ -221,6 +222,20 @@ CameraControlImpl::Get(nsICameraClosedCallback** aOnClosed)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
CameraControlImpl::Set(nsICameraRecorderStateChange* aOnRecorderStateChange)
|
||||||
|
{
|
||||||
|
mOnRecorderStateChangeCb = aOnRecorderStateChange;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
CameraControlImpl::Get(nsICameraRecorderStateChange** aOnRecorderStateChange)
|
||||||
|
{
|
||||||
|
*aOnRecorderStateChange = mOnRecorderStateChangeCb;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
already_AddRefed<RecorderProfileManager>
|
already_AddRefed<RecorderProfileManager>
|
||||||
CameraControlImpl::GetRecorderProfileManager()
|
CameraControlImpl::GetRecorderProfileManager()
|
||||||
{
|
{
|
||||||
@@ -239,6 +254,7 @@ CameraControlImpl::Shutdown()
|
|||||||
mStartRecordingOnErrorCb = nullptr;
|
mStartRecordingOnErrorCb = nullptr;
|
||||||
mOnShutterCb = nullptr;
|
mOnShutterCb = nullptr;
|
||||||
mOnClosedCb = nullptr;
|
mOnClosedCb = nullptr;
|
||||||
|
mOnRecorderStateChangeCb = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -279,6 +295,18 @@ CameraControlImpl::OnClosed()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CameraControlImpl::OnRecorderStateChange(const nsString& aStateMsg, int32_t aStatus, int32_t aTrackNumber)
|
||||||
|
{
|
||||||
|
DOM_CAMERA_LOGI("OnRecorderStateChange: '%s'\n", NS_ConvertUTF16toUTF8(aStateMsg).get());
|
||||||
|
|
||||||
|
nsCOMPtr<nsIRunnable> onRecorderStateChange = new CameraRecorderStateChange(mOnRecorderStateChangeCb, aStateMsg, aStatus, aTrackNumber, mWindowId);
|
||||||
|
nsresult rv = NS_DispatchToMainThread(onRecorderStateChange);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
DOM_CAMERA_LOGE("Failed to dispatch onRecorderStateChange event to main thread (%d)\n", rv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
CameraControlImpl::GetPreviewStream(CameraSize aSize, nsICameraPreviewStreamCallback* onSuccess, nsICameraErrorCallback* onError)
|
CameraControlImpl::GetPreviewStream(CameraSize aSize, nsICameraPreviewStreamCallback* onSuccess, nsICameraErrorCallback* onError)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -67,6 +67,8 @@ public:
|
|||||||
nsresult Get(nsICameraShutterCallback** aOnShutter);
|
nsresult Get(nsICameraShutterCallback** aOnShutter);
|
||||||
nsresult Set(nsICameraClosedCallback* aOnClosed);
|
nsresult Set(nsICameraClosedCallback* aOnClosed);
|
||||||
nsresult Get(nsICameraClosedCallback** aOnClosed);
|
nsresult Get(nsICameraClosedCallback** aOnClosed);
|
||||||
|
nsresult Set(nsICameraRecorderStateChange* aOnRecorderStateChange);
|
||||||
|
nsresult Get(nsICameraRecorderStateChange** aOnRecorderStateChange);
|
||||||
|
|
||||||
nsresult SetFocusAreas(JSContext* aCx, const JS::Value& aValue)
|
nsresult SetFocusAreas(JSContext* aCx, const JS::Value& aValue)
|
||||||
{
|
{
|
||||||
@@ -96,6 +98,7 @@ public:
|
|||||||
bool ReceiveFrame(void* aBuffer, ImageFormat aFormat, FrameBuilder aBuilder);
|
bool ReceiveFrame(void* aBuffer, ImageFormat aFormat, FrameBuilder aBuilder);
|
||||||
void OnShutter();
|
void OnShutter();
|
||||||
void OnClosed();
|
void OnClosed();
|
||||||
|
void OnRecorderStateChange(const nsString& aStateMsg, int32_t aStatus, int32_t aTrackNumber);
|
||||||
|
|
||||||
uint64_t GetWindowId()
|
uint64_t GetWindowId()
|
||||||
{
|
{
|
||||||
@@ -145,6 +148,7 @@ protected:
|
|||||||
nsCOMPtr<nsICameraErrorCallback> mStartRecordingOnErrorCb;
|
nsCOMPtr<nsICameraErrorCallback> mStartRecordingOnErrorCb;
|
||||||
nsCOMPtr<nsICameraShutterCallback> mOnShutterCb;
|
nsCOMPtr<nsICameraShutterCallback> mOnShutterCb;
|
||||||
nsCOMPtr<nsICameraClosedCallback> mOnClosedCb;
|
nsCOMPtr<nsICameraClosedCallback> mOnClosedCb;
|
||||||
|
nsCOMPtr<nsICameraRecorderStateChange> mOnRecorderStateChangeCb;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CameraControlImpl(const CameraControlImpl&) MOZ_DELETE;
|
CameraControlImpl(const CameraControlImpl&) MOZ_DELETE;
|
||||||
@@ -607,6 +611,37 @@ public:
|
|||||||
nsCOMPtr<nsICameraErrorCallback> mOnErrorCb;
|
nsCOMPtr<nsICameraErrorCallback> mOnErrorCb;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Error result runnable
|
||||||
|
class CameraRecorderStateChange : public nsRunnable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CameraRecorderStateChange(nsICameraRecorderStateChange* onStateChange, const nsString& aStateMsg, int32_t aStatus, int32_t aTrackNumber, uint64_t aWindowId)
|
||||||
|
: mOnStateChangeCb(onStateChange)
|
||||||
|
, mStateMsg(aStateMsg)
|
||||||
|
, mStatus(aStatus)
|
||||||
|
, mTrackNumber(aTrackNumber)
|
||||||
|
, mWindowId(aWindowId)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
NS_IMETHOD Run()
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
if (mOnStateChangeCb && nsDOMCameraManager::IsWindowStillActive(mWindowId)) {
|
||||||
|
// For now, just pass the state message and swallow mStatus and mTrackNumber
|
||||||
|
mOnStateChangeCb->HandleStateChange(mStateMsg);
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
nsCOMPtr<nsICameraRecorderStateChange> mOnStateChangeCb;
|
||||||
|
const nsString mStateMsg;
|
||||||
|
int32_t mStatus;
|
||||||
|
int32_t mTrackNumber;
|
||||||
|
uint64_t mWindowId;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
#endif // DOM_CAMERA_CAMERACONTROLIMPL_H
|
#endif // DOM_CAMERA_CAMERACONTROLIMPL_H
|
||||||
|
|||||||
@@ -229,6 +229,18 @@ nsDOMCameraControl::SetOnClosed(nsICameraClosedCallback* aOnClosed)
|
|||||||
return mCameraControl->Set(aOnClosed);
|
return mCameraControl->Set(aOnClosed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* attribute nsICameraRecorderStateChange onRecorderStateChange; */
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMCameraControl::GetOnRecorderStateChange(nsICameraRecorderStateChange** aOnRecorderStateChange)
|
||||||
|
{
|
||||||
|
return mCameraControl->Get(aOnRecorderStateChange);
|
||||||
|
}
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMCameraControl::SetOnRecorderStateChange(nsICameraRecorderStateChange* aOnRecorderStateChange)
|
||||||
|
{
|
||||||
|
return mCameraControl->Set(aOnRecorderStateChange);
|
||||||
|
}
|
||||||
|
|
||||||
/* [implicit_jscontext] void startRecording (in jsval aOptions, in nsIDOMDeviceStorage storageArea, in DOMString filename, in nsICameraStartRecordingCallback onSuccess, [optional] in nsICameraErrorCallback onError); */
|
/* [implicit_jscontext] void startRecording (in jsval aOptions, in nsIDOMDeviceStorage storageArea, in DOMString filename, in nsICameraStartRecordingCallback onSuccess, [optional] in nsICameraErrorCallback onError); */
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsDOMCameraControl::StartRecording(const JS::Value& aOptions, nsIDOMDeviceStorage* storageArea, const nsAString& filename, nsICameraStartRecordingCallback* onSuccess, nsICameraErrorCallback* onError, JSContext* cx)
|
nsDOMCameraControl::StartRecording(const JS::Value& aOptions, nsIDOMDeviceStorage* storageArea, const nsAString& filename, nsICameraStartRecordingCallback* onSuccess, nsICameraErrorCallback* onError, JSContext* cx)
|
||||||
@@ -237,6 +249,11 @@ nsDOMCameraControl::StartRecording(const JS::Value& aOptions, nsIDOMDeviceStorag
|
|||||||
NS_ENSURE_TRUE(storageArea, NS_ERROR_INVALID_ARG);
|
NS_ENSURE_TRUE(storageArea, NS_ERROR_INVALID_ARG);
|
||||||
|
|
||||||
CameraStartRecordingOptions options;
|
CameraStartRecordingOptions options;
|
||||||
|
|
||||||
|
// Default values, until the dictionary parser can handle them.
|
||||||
|
options.rotation = 0;
|
||||||
|
options.maxFileSizeBytes = 0;
|
||||||
|
options.maxVideoLengthMs = 0;
|
||||||
nsresult rv = options.Init(cx, &aOptions);
|
nsresult rv = options.Init(cx, &aOptions);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#include "nsThread.h"
|
#include "nsThread.h"
|
||||||
#include <media/MediaProfiles.h>
|
#include <media/MediaProfiles.h>
|
||||||
#include "mozilla/FileUtils.h"
|
#include "mozilla/FileUtils.h"
|
||||||
|
#include <media/mediaplayer.h>
|
||||||
#include "nsDirectoryServiceDefs.h" // for NS_GetSpecialDirectory
|
#include "nsDirectoryServiceDefs.h" // for NS_GetSpecialDirectory
|
||||||
#include "nsPrintfCString.h"
|
#include "nsPrintfCString.h"
|
||||||
#include "DOMCameraManager.h"
|
#include "DOMCameraManager.h"
|
||||||
@@ -741,7 +742,7 @@ nsGonkCameraControl::StartRecordingImpl(StartRecordingTask* aStartRecording)
|
|||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult rv = SetupRecording(fd);
|
nsresult rv = SetupRecording(fd, aStartRecording->mOptions.maxFileSizeBytes, aStartRecording->mOptions.maxVideoLengthMs);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
if (mRecorder->start() != OK) {
|
if (mRecorder->start() != OK) {
|
||||||
@@ -914,8 +915,154 @@ nsGonkCameraControl::SetupVideoMode(const nsAString& aProfile)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class GonkRecorderListener : public IMediaRecorderClient
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GonkRecorderListener(nsGonkCameraControl* aCameraControl)
|
||||||
|
: mCameraControl(aCameraControl)
|
||||||
|
{
|
||||||
|
DOM_CAMERA_LOGT("%s:%d : this=%p, aCameraControl=%p\n", __func__, __LINE__, this, mCameraControl.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
void notify(int msg, int ext1, int ext2)
|
||||||
|
{
|
||||||
|
if (mCameraControl) {
|
||||||
|
mCameraControl->HandleRecorderEvent(msg, ext1, ext2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IBinder* onAsBinder()
|
||||||
|
{
|
||||||
|
DOM_CAMERA_LOGE("onAsBinder() called, should NEVER get called!\n");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
~GonkRecorderListener() { }
|
||||||
|
nsRefPtr<nsGonkCameraControl> mCameraControl;
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
nsGonkCameraControl::HandleRecorderEvent(int msg, int ext1, int ext2)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Refer to base/include/media/mediarecorder.h for a complete list
|
||||||
|
* of error and info message codes. There are duplicate values
|
||||||
|
* within the status/error code space, as determined by code inspection:
|
||||||
|
*
|
||||||
|
* +------- msg
|
||||||
|
* | +----- ext1
|
||||||
|
* | | +--- ext2
|
||||||
|
* V V V
|
||||||
|
* 1 MEDIA_RECORDER_EVENT_ERROR
|
||||||
|
* 1 MEDIA_RECORDER_ERROR_UNKNOWN
|
||||||
|
* [3] ERROR_MALFORMED
|
||||||
|
* 100 mediaplayer.h::MEDIA_ERROR_SERVER_DIED
|
||||||
|
* 0 <always zero>
|
||||||
|
* 2 MEDIA_RECORDER_EVENT_INFO
|
||||||
|
* 800 MEDIA_RECORDER_INFO_MAX_DURATION_REACHED
|
||||||
|
* 0 <always zero>
|
||||||
|
* 801 MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED
|
||||||
|
* 0 <always zero>
|
||||||
|
* 1000 MEDIA_RECORDER_TRACK_INFO_COMPLETION_STATUS[1b]
|
||||||
|
* [3] UNKNOWN_ERROR, etc.
|
||||||
|
* 100 MEDIA_ERROR[4]
|
||||||
|
* 100 mediaplayer.h::MEDIA_ERROR_SERVER_DIED
|
||||||
|
* 0 <always zero>
|
||||||
|
* 100 MEDIA_RECORDER_TRACK_EVENT_ERROR
|
||||||
|
* 100 MEDIA_RECORDER_TRACK_ERROR_GENERAL[1a]
|
||||||
|
* [3] UNKNOWN_ERROR, etc.
|
||||||
|
* 200 MEDIA_RECORDER_ERROR_VIDEO_NO_SYNC_FRAME[2]
|
||||||
|
* ? <unknown>
|
||||||
|
* 101 MEDIA_RECORDER_TRACK_EVENT_INFO
|
||||||
|
* 1000 MEDIA_RECORDER_TRACK_INFO_COMPLETION_STATUS[1a]
|
||||||
|
* [3] UNKNOWN_ERROR, etc.
|
||||||
|
* N see mediarecorder.h::media_recorder_info_type[5]
|
||||||
|
*
|
||||||
|
* 1. a) High 4 bits are the track number, the next 12 bits are reserved,
|
||||||
|
* and the final 16 bits are the actual error code (above).
|
||||||
|
* b) But not in this case.
|
||||||
|
* 2. Never actually used in AOSP code?
|
||||||
|
* 3. Specific error codes are from utils/Errors.h and/or
|
||||||
|
* include/media/stagefright/MediaErrors.h.
|
||||||
|
* 4. Only in frameworks/base/media/libmedia/mediaplayer.cpp.
|
||||||
|
* 5. These are mostly informational and we can ignore them; note that
|
||||||
|
* although the MEDIA_RECORDER_INFO_MAX_DURATION_REACHED and
|
||||||
|
* MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED values are defined in this
|
||||||
|
* enum, they are used with different ext1 codes. /o\
|
||||||
|
*/
|
||||||
|
int trackNum = -1; // no track
|
||||||
|
|
||||||
|
switch (msg) {
|
||||||
|
// Recorder-related events
|
||||||
|
case MEDIA_RECORDER_EVENT_INFO:
|
||||||
|
switch (ext1) {
|
||||||
|
case MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED:
|
||||||
|
DOM_CAMERA_LOGI("recorder-event : info: maximum file size reached\n");
|
||||||
|
OnRecorderStateChange(NS_LITERAL_STRING("FileSizeLimitReached"), ext2, trackNum);
|
||||||
|
return;
|
||||||
|
|
||||||
|
case MEDIA_RECORDER_INFO_MAX_DURATION_REACHED:
|
||||||
|
DOM_CAMERA_LOGI("recorder-event : info: maximum video duration reached\n");
|
||||||
|
OnRecorderStateChange(NS_LITERAL_STRING("VideoLengthLimitReached"), ext2, trackNum);
|
||||||
|
return;
|
||||||
|
|
||||||
|
case MEDIA_RECORDER_TRACK_INFO_COMPLETION_STATUS:
|
||||||
|
DOM_CAMERA_LOGI("recorder-event : info: track completed\n");
|
||||||
|
OnRecorderStateChange(NS_LITERAL_STRING("TrackCompleted"), ext2, trackNum);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MEDIA_RECORDER_EVENT_ERROR:
|
||||||
|
switch (ext1) {
|
||||||
|
case MEDIA_RECORDER_ERROR_UNKNOWN:
|
||||||
|
DOM_CAMERA_LOGE("recorder-event : recorder-error: %d (0x%08x)\n", ext2, ext2);
|
||||||
|
OnRecorderStateChange(NS_LITERAL_STRING("MediaRecorderFailed"), ext2, trackNum);
|
||||||
|
return;
|
||||||
|
|
||||||
|
case MEDIA_ERROR_SERVER_DIED:
|
||||||
|
DOM_CAMERA_LOGE("recorder-event : recorder-error: server died\n");
|
||||||
|
OnRecorderStateChange(NS_LITERAL_STRING("MediaServerFailed"), ext2, trackNum);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Track-related events, see note 1(a) above.
|
||||||
|
case MEDIA_RECORDER_TRACK_EVENT_INFO:
|
||||||
|
trackNum = (ext1 & 0xF0000000) >> 28;
|
||||||
|
ext1 &= 0xFFFF;
|
||||||
|
switch (ext1) {
|
||||||
|
case MEDIA_RECORDER_TRACK_INFO_COMPLETION_STATUS:
|
||||||
|
if (ext2 == OK) {
|
||||||
|
DOM_CAMERA_LOGI("recorder-event : track-complete: track %d, %d (0x%08x)\n", trackNum, ext2, ext2);
|
||||||
|
OnRecorderStateChange(NS_LITERAL_STRING("TrackCompleted"), ext2, trackNum);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
DOM_CAMERA_LOGE("recorder-event : track-error: track %d, %d (0x%08x)\n", trackNum, ext2, ext2);
|
||||||
|
OnRecorderStateChange(NS_LITERAL_STRING("TrackFailed"), ext2, trackNum);
|
||||||
|
return;
|
||||||
|
|
||||||
|
case MEDIA_RECORDER_TRACK_INFO_PROGRESS_IN_TIME:
|
||||||
|
DOM_CAMERA_LOGI("recorder-event : track-info: progress in time: %d ms\n", ext2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MEDIA_RECORDER_TRACK_EVENT_ERROR:
|
||||||
|
trackNum = (ext1 & 0xF0000000) >> 28;
|
||||||
|
ext1 &= 0xFFFF;
|
||||||
|
DOM_CAMERA_LOGE("recorder-event : track-error: track %d, %d (0x%08x)\n", trackNum, ext2, ext2);
|
||||||
|
OnRecorderStateChange(NS_LITERAL_STRING("TrackFailed"), ext2, trackNum);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// All unhandled cases wind up here
|
||||||
|
DOM_CAMERA_LOGW("recorder-event : unhandled: msg=%d, ext1=%d, ext2=%d\n", msg, ext1, ext2);
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsGonkCameraControl::SetupRecording(int aFd, int aMaxFileSizeBytes, int aMaxVideoLengthMs)
|
nsGonkCameraControl::SetupRecording(int aFd, int64_t aMaxFileSizeBytes, int64_t aMaxVideoLengthMs)
|
||||||
{
|
{
|
||||||
// choosing a size big enough to hold the params
|
// choosing a size big enough to hold the params
|
||||||
const size_t SIZE = 256;
|
const size_t SIZE = 256;
|
||||||
@@ -929,15 +1076,25 @@ nsGonkCameraControl::SetupRecording(int aFd, int aMaxFileSizeBytes, int aMaxVide
|
|||||||
|
|
||||||
CHECK_SETARG(mRecorder->setCameraHandle((int32_t)mHwHandle));
|
CHECK_SETARG(mRecorder->setCameraHandle((int32_t)mHwHandle));
|
||||||
|
|
||||||
snprintf(buffer, SIZE, "max-duration=%d", aMaxVideoLengthMs);
|
DOM_CAMERA_LOGI("maxVideoLengthMs=%lld\n", aMaxVideoLengthMs);
|
||||||
|
if (aMaxVideoLengthMs == 0) {
|
||||||
|
aMaxVideoLengthMs = -1;
|
||||||
|
}
|
||||||
|
snprintf(buffer, SIZE, "max-duration=%lld", aMaxVideoLengthMs);
|
||||||
CHECK_SETARG(mRecorder->setParameters(String8(buffer)));
|
CHECK_SETARG(mRecorder->setParameters(String8(buffer)));
|
||||||
|
|
||||||
snprintf(buffer, SIZE, "max-duration=%d", aMaxFileSizeBytes);
|
DOM_CAMERA_LOGI("maxFileSizeBytes=%lld\n", aMaxFileSizeBytes);
|
||||||
|
if (aMaxFileSizeBytes == 0) {
|
||||||
|
aMaxFileSizeBytes = -1;
|
||||||
|
}
|
||||||
|
snprintf(buffer, SIZE, "max-filesize=%lld", aMaxFileSizeBytes);
|
||||||
CHECK_SETARG(mRecorder->setParameters(String8(buffer)));
|
CHECK_SETARG(mRecorder->setParameters(String8(buffer)));
|
||||||
|
|
||||||
snprintf(buffer, SIZE, "video-param-rotation-angle-degrees=%d", mVideoRotation);
|
snprintf(buffer, SIZE, "video-param-rotation-angle-degrees=%d", mVideoRotation);
|
||||||
CHECK_SETARG(mRecorder->setParameters(String8(buffer)));
|
CHECK_SETARG(mRecorder->setParameters(String8(buffer)));
|
||||||
|
|
||||||
|
CHECK_SETARG(mRecorder->setListener(new GonkRecorderListener(this)));
|
||||||
|
|
||||||
// recording API needs file descriptor of output file
|
// recording API needs file descriptor of output file
|
||||||
CHECK_SETARG(mRecorder->setOutputFile(aFd, 0, 0));
|
CHECK_SETARG(mRecorder->setOutputFile(aFd, 0, 0));
|
||||||
CHECK_SETARG(mRecorder->prepare());
|
CHECK_SETARG(mRecorder->prepare());
|
||||||
|
|||||||
@@ -54,11 +54,12 @@ public:
|
|||||||
nsresult GetVideoSizes(nsTArray<CameraSize>& aVideoSizes);
|
nsresult GetVideoSizes(nsTArray<CameraSize>& aVideoSizes);
|
||||||
nsresult PushParameters();
|
nsresult PushParameters();
|
||||||
|
|
||||||
nsresult SetupRecording(int aFd, int aMaxFileSizeBytes = -1, int aMaxVideoLengthMs = -1);
|
nsresult SetupRecording(int aFd, int64_t aMaxFileSizeBytes = -1, int64_t aMaxVideoLengthMs = -1);
|
||||||
nsresult SetupVideoMode(const nsAString& aProfile);
|
nsresult SetupVideoMode(const nsAString& aProfile);
|
||||||
|
|
||||||
void AutoFocusComplete(bool aSuccess);
|
void AutoFocusComplete(bool aSuccess);
|
||||||
void TakePictureComplete(uint8_t* aData, uint32_t aLength);
|
void TakePictureComplete(uint8_t* aData, uint32_t aLength);
|
||||||
|
void HandleRecorderEvent(int msg, int ext1, int ext2);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
~nsGonkCameraControl();
|
~nsGonkCameraControl();
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ public:
|
|||||||
virtual nsresult Get(nsICameraShutterCallback** aOnShutter) = 0;
|
virtual nsresult Get(nsICameraShutterCallback** aOnShutter) = 0;
|
||||||
virtual nsresult Set(nsICameraClosedCallback* aOnClosed) = 0;
|
virtual nsresult Set(nsICameraClosedCallback* aOnClosed) = 0;
|
||||||
virtual nsresult Get(nsICameraClosedCallback** aOnClosed) = 0;
|
virtual nsresult Get(nsICameraClosedCallback** aOnClosed) = 0;
|
||||||
|
virtual nsresult Set(nsICameraRecorderStateChange* aOnRecorderStateChange) = 0;
|
||||||
|
virtual nsresult Get(nsICameraRecorderStateChange** aOnRecorderStateChange) = 0;
|
||||||
virtual nsresult SetFocusAreas(JSContext* aCx, const JS::Value& aValue) = 0;
|
virtual nsresult SetFocusAreas(JSContext* aCx, const JS::Value& aValue) = 0;
|
||||||
virtual nsresult SetMeteringAreas(JSContext* aCx, const JS::Value& aValue) = 0;
|
virtual nsresult SetMeteringAreas(JSContext* aCx, const JS::Value& aValue) = 0;
|
||||||
virtual nsresult GetVideoSizes(nsTArray<CameraSize>& aVideoSizes) = 0;
|
virtual nsresult GetVideoSizes(nsTArray<CameraSize>& aVideoSizes) = 0;
|
||||||
|
|||||||
@@ -195,8 +195,8 @@ dictionary CameraRecorderOptions
|
|||||||
dictionary CameraStartRecordingOptions
|
dictionary CameraStartRecordingOptions
|
||||||
{
|
{
|
||||||
long rotation;
|
long rotation;
|
||||||
long maxFileSizeBytes;
|
long long maxFileSizeBytes;
|
||||||
long maxVideoLengthMs;
|
long long maxVideoLengthMs;
|
||||||
};
|
};
|
||||||
|
|
||||||
[scriptable, function, uuid(0444a687-4bc9-462c-8246-5423f0fe46a4)]
|
[scriptable, function, uuid(0444a687-4bc9-462c-8246-5423f0fe46a4)]
|
||||||
@@ -235,6 +235,12 @@ interface nsICameraClosedCallback : nsISupports
|
|||||||
void handleEvent();
|
void handleEvent();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
[scriptable, function, uuid(550d675a-257d-4713-8b3d-0da53eba68fc)]
|
||||||
|
interface nsICameraRecorderStateChange : nsISupports
|
||||||
|
{
|
||||||
|
void handleStateChange(in DOMString newState);
|
||||||
|
};
|
||||||
|
|
||||||
[scriptable, function, uuid(a302c6c9-3776-4d1d-a395-f4105d47c3d3)]
|
[scriptable, function, uuid(a302c6c9-3776-4d1d-a395-f4105d47c3d3)]
|
||||||
interface nsICameraErrorCallback : nsISupports
|
interface nsICameraErrorCallback : nsISupports
|
||||||
{
|
{
|
||||||
@@ -245,7 +251,7 @@ interface nsICameraErrorCallback : nsISupports
|
|||||||
attributes here affect the preview, any pictures taken, and/or
|
attributes here affect the preview, any pictures taken, and/or
|
||||||
any video recorded by the camera.
|
any video recorded by the camera.
|
||||||
*/
|
*/
|
||||||
[scriptable, uuid(0f206acd-196b-4bdf-8198-44c1a0cd1998)]
|
[scriptable, uuid(70f45209-b69b-4937-bbac-57d82600e2af)]
|
||||||
interface nsICameraControl : nsISupports
|
interface nsICameraControl : nsISupports
|
||||||
{
|
{
|
||||||
readonly attribute nsICameraCapabilities capabilities;
|
readonly attribute nsICameraCapabilities capabilities;
|
||||||
@@ -341,6 +347,11 @@ interface nsICameraControl : nsISupports
|
|||||||
recent call to get the camera. */
|
recent call to get the camera. */
|
||||||
attribute nsICameraClosedCallback onClosed;
|
attribute nsICameraClosedCallback onClosed;
|
||||||
|
|
||||||
|
/* the function to call when the recorder changes state, either because
|
||||||
|
the recording process encountered an error, or because one of the
|
||||||
|
recording limits (see CameraStartRecordingOptions) was reached. */
|
||||||
|
attribute nsICameraRecorderStateChange onRecorderStateChange;
|
||||||
|
|
||||||
/* tell the camera to attempt to focus the image */
|
/* tell the camera to attempt to focus the image */
|
||||||
void autoFocus(in nsICameraAutoFocusCallback onSuccess, [optional] in nsICameraErrorCallback onError);
|
void autoFocus(in nsICameraAutoFocusCallback onSuccess, [optional] in nsICameraErrorCallback onError);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user