mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 14:22:01 +00:00
Merge b2ginbound to central, a=merge
This commit is contained in:
commit
fc6203de4a
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="60489c1ff8c5d1633fc4837d4f8019623d4e1940"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="d9d99f32762975a370f1abd34a3512bd6fe29111"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="60489c1ff8c5d1633fc4837d4f8019623d4e1940"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="d9d99f32762975a370f1abd34a3512bd6fe29111"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
@ -19,7 +19,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="60489c1ff8c5d1633fc4837d4f8019623d4e1940"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d9d99f32762975a370f1abd34a3512bd6fe29111"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="2d58f4b9206b50b8fda0d5036da6f0c62608db7c"/>
|
||||
|
@ -17,7 +17,7 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="60489c1ff8c5d1633fc4837d4f8019623d4e1940"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="d9d99f32762975a370f1abd34a3512bd6fe29111"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="bfdb6348725a33bdcdc4e17999cb500be6beedb5"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="a6f9a1245d98c51172c15afecb9ade1a6ca511e2"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="60489c1ff8c5d1633fc4837d4f8019623d4e1940"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="d9d99f32762975a370f1abd34a3512bd6fe29111"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="05a36844c1046a1eb07d5b1325f85ed741f961ea">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="60489c1ff8c5d1633fc4837d4f8019623d4e1940"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="d9d99f32762975a370f1abd34a3512bd6fe29111"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
@ -19,7 +19,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="60489c1ff8c5d1633fc4837d4f8019623d4e1940"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d9d99f32762975a370f1abd34a3512bd6fe29111"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="2d58f4b9206b50b8fda0d5036da6f0c62608db7c"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="60489c1ff8c5d1633fc4837d4f8019623d4e1940"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="d9d99f32762975a370f1abd34a3512bd6fe29111"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
@ -1,9 +1,9 @@
|
||||
{
|
||||
"git": {
|
||||
"git_revision": "60489c1ff8c5d1633fc4837d4f8019623d4e1940",
|
||||
"git_revision": "d9d99f32762975a370f1abd34a3512bd6fe29111",
|
||||
"remote": "https://git.mozilla.org/releases/gaia.git",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "43de6ab8b9790809ac7b4d80bf060a2976a88417",
|
||||
"revision": "a1b18f9a9e869b1ae261a064a7dd174d59169fb9",
|
||||
"repo_path": "integration/gaia-central"
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="60489c1ff8c5d1633fc4837d4f8019623d4e1940"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="d9d99f32762975a370f1abd34a3512bd6fe29111"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="bfdb6348725a33bdcdc4e17999cb500be6beedb5"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="a6f9a1245d98c51172c15afecb9ade1a6ca511e2"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="05a36844c1046a1eb07d5b1325f85ed741f961ea">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="60489c1ff8c5d1633fc4837d4f8019623d4e1940"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="d9d99f32762975a370f1abd34a3512bd6fe29111"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
@ -298,6 +298,8 @@ CameraControlImpl::OnUserError(CameraControlListener::UserContext aContext,
|
||||
"TakePicture",
|
||||
"StartRecording",
|
||||
"StopRecording",
|
||||
"PauseRecording",
|
||||
"ResumeRecording",
|
||||
"SetConfiguration",
|
||||
"StartPreview",
|
||||
"StopPreview",
|
||||
@ -602,6 +604,48 @@ CameraControlImpl::StopRecording()
|
||||
return Dispatch(new Message(this, CameraControlListener::kInStopRecording));
|
||||
}
|
||||
|
||||
nsresult
|
||||
CameraControlImpl::PauseRecording()
|
||||
{
|
||||
class Message : public ControlMessage
|
||||
{
|
||||
public:
|
||||
Message(CameraControlImpl* aCameraControl,
|
||||
CameraControlListener::UserContext aContext)
|
||||
: ControlMessage(aCameraControl, aContext)
|
||||
{ }
|
||||
|
||||
nsresult
|
||||
RunImpl() override
|
||||
{
|
||||
return mCameraControl->PauseRecordingImpl();
|
||||
}
|
||||
};
|
||||
|
||||
return Dispatch(new Message(this, CameraControlListener::kInPauseRecording));
|
||||
}
|
||||
|
||||
nsresult
|
||||
CameraControlImpl::ResumeRecording()
|
||||
{
|
||||
class Message : public ControlMessage
|
||||
{
|
||||
public:
|
||||
Message(CameraControlImpl* aCameraControl,
|
||||
CameraControlListener::UserContext aContext)
|
||||
: ControlMessage(aCameraControl, aContext)
|
||||
{ }
|
||||
|
||||
nsresult
|
||||
RunImpl() override
|
||||
{
|
||||
return mCameraControl->ResumeRecordingImpl();
|
||||
}
|
||||
};
|
||||
|
||||
return Dispatch(new Message(this, CameraControlListener::kInResumeRecording));
|
||||
}
|
||||
|
||||
nsresult
|
||||
CameraControlImpl::StartPreview()
|
||||
{
|
||||
|
@ -48,6 +48,8 @@ public:
|
||||
virtual nsresult StartRecording(DeviceStorageFileDescriptor* aFileDescriptor,
|
||||
const StartRecordingOptions* aOptions) override;
|
||||
virtual nsresult StopRecording() override;
|
||||
virtual nsresult PauseRecording() override;
|
||||
virtual nsresult ResumeRecording() override;
|
||||
virtual nsresult ResumeContinuousFocus() override;
|
||||
|
||||
// Event handlers called directly from outside this class.
|
||||
@ -121,6 +123,8 @@ protected:
|
||||
virtual nsresult StartRecordingImpl(DeviceStorageFileDescriptor* aFileDescriptor,
|
||||
const StartRecordingOptions* aOptions) = 0;
|
||||
virtual nsresult StopRecordingImpl() = 0;
|
||||
virtual nsresult PauseRecordingImpl() = 0;
|
||||
virtual nsresult ResumeRecordingImpl() = 0;
|
||||
virtual nsresult ResumeContinuousFocusImpl() = 0;
|
||||
virtual nsresult PushParametersImpl() = 0;
|
||||
virtual nsresult PullParametersImpl() = 0;
|
||||
|
@ -64,6 +64,8 @@ public:
|
||||
{
|
||||
kRecorderStopped,
|
||||
kRecorderStarted,
|
||||
kRecorderPaused,
|
||||
kRecorderResumed,
|
||||
kPosterCreated,
|
||||
kPosterFailed,
|
||||
#ifdef MOZ_B2G_CAMERA
|
||||
@ -109,6 +111,8 @@ public:
|
||||
kInTakePicture,
|
||||
kInStartRecording,
|
||||
kInStopRecording,
|
||||
kInPauseRecording,
|
||||
kInResumeRecording,
|
||||
kInSetConfiguration,
|
||||
kInStartPreview,
|
||||
kInStopPreview,
|
||||
|
@ -890,6 +890,24 @@ nsDOMCameraControl::StopRecording(ErrorResult& aRv)
|
||||
aRv = mCameraControl->StopRecording();
|
||||
}
|
||||
|
||||
void
|
||||
nsDOMCameraControl::PauseRecording(ErrorResult& aRv)
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
THROW_IF_NO_CAMERACONTROL();
|
||||
|
||||
aRv = mCameraControl->PauseRecording();
|
||||
}
|
||||
|
||||
void
|
||||
nsDOMCameraControl::ResumeRecording(ErrorResult& aRv)
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
THROW_IF_NO_CAMERACONTROL();
|
||||
|
||||
aRv = mCameraControl->ResumeRecording();
|
||||
}
|
||||
|
||||
void
|
||||
nsDOMCameraControl::ResumePreview(ErrorResult& aRv)
|
||||
{
|
||||
@ -1400,6 +1418,14 @@ nsDOMCameraControl::OnRecorderStateChange(CameraControlListener::RecorderState a
|
||||
mOptions.mPosterStorageArea = nullptr;
|
||||
break;
|
||||
|
||||
case CameraControlListener::kRecorderPaused:
|
||||
state = NS_LITERAL_STRING("Paused");
|
||||
break;
|
||||
|
||||
case CameraControlListener::kRecorderResumed:
|
||||
state = NS_LITERAL_STRING("Resumed");
|
||||
break;
|
||||
|
||||
#ifdef MOZ_B2G_CAMERA
|
||||
case CameraControlListener::kFileSizeLimitReached:
|
||||
state = NS_LITERAL_STRING("FileSizeLimitReached");
|
||||
@ -1656,6 +1682,18 @@ nsDOMCameraControl::OnUserError(CameraControlListener::UserContext aContext, nsr
|
||||
NS_WARNING("Failed to stop recording");
|
||||
return;
|
||||
|
||||
case CameraControlListener::kInPauseRecording:
|
||||
// This method doesn't have any callbacks, so all we can do is log the
|
||||
// failure. This only happens after the hardware has been released.
|
||||
NS_WARNING("Failed to pause recording");
|
||||
return;
|
||||
|
||||
case CameraControlListener::kInResumeRecording:
|
||||
// This method doesn't have any callbacks, so all we can do is log the
|
||||
// failure. This only happens after the hardware has been released.
|
||||
NS_WARNING("Failed to resume recording");
|
||||
return;
|
||||
|
||||
case CameraControlListener::kInStartPreview:
|
||||
// This method doesn't have any callbacks, so all we can do is log the
|
||||
// failure. This only happens after the hardware has been released.
|
||||
|
@ -120,6 +120,8 @@ public:
|
||||
const nsAString& filename,
|
||||
ErrorResult& aRv);
|
||||
void StopRecording(ErrorResult& aRv);
|
||||
void PauseRecording(ErrorResult& aRv);
|
||||
void ResumeRecording(ErrorResult& aRv);
|
||||
void ResumePreview(ErrorResult& aRv);
|
||||
already_AddRefed<dom::Promise> ReleaseHardware(ErrorResult& aRv);
|
||||
void ResumeContinuousFocus(ErrorResult& aRv);
|
||||
|
@ -1323,6 +1323,48 @@ nsGonkCameraControl::StopRecordingImpl()
|
||||
return NS_DispatchToMainThread(new RecordingComplete(mVideoFile.forget()));
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGonkCameraControl::PauseRecordingImpl()
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(mRecorderMonitor);
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
if (!mRecorder) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
int err = mRecorder->pause();
|
||||
switch (err) {
|
||||
case OK:
|
||||
break;
|
||||
case INVALID_OPERATION:
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
default:
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
#endif
|
||||
OnRecorderStateChange(CameraControlListener::kRecorderPaused);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGonkCameraControl::ResumeRecordingImpl()
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(mRecorderMonitor);
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
if (!mRecorder) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
if (mRecorder->resume() != OK) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
#endif
|
||||
OnRecorderStateChange(CameraControlListener::kRecorderResumed);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGonkCameraControl::ResumeContinuousFocusImpl()
|
||||
{
|
||||
|
@ -138,6 +138,8 @@ protected:
|
||||
virtual nsresult StartRecordingImpl(DeviceStorageFileDescriptor* aFileDescriptor,
|
||||
const StartRecordingOptions* aOptions = nullptr) override;
|
||||
virtual nsresult StopRecordingImpl() override;
|
||||
virtual nsresult PauseRecordingImpl() override;
|
||||
virtual nsresult ResumeRecordingImpl() override;
|
||||
virtual nsresult ResumeContinuousFocusImpl() override;
|
||||
virtual nsresult PushParametersImpl() override;
|
||||
virtual nsresult PullParametersImpl() override;
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "CameraCommon.h"
|
||||
#include "GonkCameraSource.h"
|
||||
#include "GonkRecorder.h"
|
||||
#include "mozilla/CondVar.h"
|
||||
|
||||
#define RE_LOGD(fmt, ...) DOM_CAMERA_LOGA("[%s:%d]" fmt,__FILE__,__LINE__, ## __VA_ARGS__)
|
||||
#define RE_LOGV(fmt, ...) DOM_CAMERA_LOGI("[%s:%d]" fmt,__FILE__,__LINE__, ## __VA_ARGS__)
|
||||
@ -58,6 +59,132 @@
|
||||
#define RES_720P (720 * 1280)
|
||||
namespace android {
|
||||
|
||||
struct GonkRecorder::WrappedMediaSource : MediaSource {
|
||||
public:
|
||||
WrappedMediaSource(const sp<MediaSource> &encoder);
|
||||
status_t start(MetaData *params = NULL) override;
|
||||
status_t stop() override;
|
||||
sp<MetaData> getFormat() override;
|
||||
status_t read(MediaBuffer **buffer, const ReadOptions *options = NULL) override;
|
||||
void block();
|
||||
status_t resume();
|
||||
|
||||
protected:
|
||||
virtual ~WrappedMediaSource() {};
|
||||
|
||||
private:
|
||||
WrappedMediaSource(const WrappedMediaSource &);
|
||||
WrappedMediaSource &operator=(const WrappedMediaSource &);
|
||||
|
||||
sp<MediaSource> mEncoder;
|
||||
mozilla::Mutex mMutex;
|
||||
mozilla::CondVar mCondVar;
|
||||
bool mWait;
|
||||
bool mResume;
|
||||
status_t mResumeStatus;
|
||||
};
|
||||
|
||||
GonkRecorder::WrappedMediaSource::WrappedMediaSource(const sp<MediaSource> &encoder)
|
||||
: mEncoder(encoder)
|
||||
, mMutex("GonkRecorder::WrappedMediaSource::mMutex")
|
||||
, mCondVar(mMutex, "GonkRecorder::WrappedMediaSource::mCondVar")
|
||||
, mWait(false)
|
||||
, mResume(false)
|
||||
, mResumeStatus(UNKNOWN_ERROR)
|
||||
{
|
||||
}
|
||||
|
||||
status_t
|
||||
GonkRecorder::WrappedMediaSource::start(MetaData *params)
|
||||
{
|
||||
return mEncoder->start(params);
|
||||
}
|
||||
|
||||
status_t
|
||||
GonkRecorder::WrappedMediaSource::stop()
|
||||
{
|
||||
{
|
||||
// Ensure the writer thread is not blocked first.
|
||||
MutexAutoLock lock(mMutex);
|
||||
mWait = false;
|
||||
mCondVar.Notify();
|
||||
}
|
||||
return mEncoder->stop();
|
||||
}
|
||||
|
||||
sp<MetaData>
|
||||
GonkRecorder::WrappedMediaSource::getFormat()
|
||||
{
|
||||
return mEncoder->getFormat();
|
||||
}
|
||||
|
||||
status_t
|
||||
GonkRecorder::WrappedMediaSource::read(MediaBuffer **buffer, const ReadOptions *options)
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
while (mWait) {
|
||||
mCondVar.Wait();
|
||||
}
|
||||
|
||||
status_t rv = UNKNOWN_ERROR;
|
||||
MediaBuffer *buf = NULL;
|
||||
|
||||
do {
|
||||
rv = mEncoder->read(&buf, options);
|
||||
if (!mResume) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (rv != OK || !buf) {
|
||||
mResume = false;
|
||||
mResumeStatus = UNKNOWN_ERROR;
|
||||
mCondVar.Notify();
|
||||
break;
|
||||
}
|
||||
|
||||
int32_t isSync = 0;
|
||||
buf->meta_data()->findInt32(kKeyIsSyncFrame, &isSync);
|
||||
if (isSync) {
|
||||
mResume = false;
|
||||
mResumeStatus = OK;
|
||||
mCondVar.Notify();
|
||||
break;
|
||||
}
|
||||
|
||||
buf->release();
|
||||
buf = NULL;
|
||||
} while(true);
|
||||
|
||||
*buffer = buf;
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
GonkRecorder::WrappedMediaSource::block()
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
mWait = true;
|
||||
}
|
||||
|
||||
status_t
|
||||
GonkRecorder::WrappedMediaSource::resume()
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
if (!mWait) {
|
||||
return UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
mWait = false;
|
||||
mResume = true;
|
||||
mCondVar.Notify();
|
||||
|
||||
do {
|
||||
mCondVar.Wait();
|
||||
} while(mResume);
|
||||
|
||||
return mResumeStatus;
|
||||
}
|
||||
|
||||
GonkRecorder::GonkRecorder()
|
||||
: mWriter(NULL),
|
||||
mOutputFd(-1),
|
||||
@ -1500,11 +1627,13 @@ status_t GonkRecorder::setupMPEG4Recording(
|
||||
int32_t videoWidth, int32_t videoHeight,
|
||||
int32_t videoBitRate,
|
||||
int32_t *totalBitRate,
|
||||
sp<MediaWriter> *mediaWriter) {
|
||||
sp<MediaWriter> *mediaWriter,
|
||||
sp<WrappedMediaSource> *mediaSource) {
|
||||
mediaWriter->clear();
|
||||
*totalBitRate = 0;
|
||||
status_t err = OK;
|
||||
sp<MediaWriter> writer = new MPEG4Writer(outputFd);
|
||||
sp<WrappedMediaSource> writerSource;
|
||||
|
||||
if (mVideoSource < VIDEO_SOURCE_LIST_END) {
|
||||
|
||||
@ -1520,7 +1649,10 @@ status_t GonkRecorder::setupMPEG4Recording(
|
||||
return err;
|
||||
}
|
||||
|
||||
writer->addSource(encoder);
|
||||
sp<GonkCameraSource> cameraSource = reinterpret_cast<GonkCameraSource *>(mediaSource.get());
|
||||
writerSource = new WrappedMediaSource(encoder);
|
||||
|
||||
writer->addSource(writerSource);
|
||||
*totalBitRate += videoBitRate;
|
||||
}
|
||||
|
||||
@ -1556,6 +1688,7 @@ status_t GonkRecorder::setupMPEG4Recording(
|
||||
|
||||
writer->setListener(mListener);
|
||||
*mediaWriter = writer;
|
||||
*mediaSource = writerSource;
|
||||
return OK;
|
||||
}
|
||||
|
||||
@ -1587,7 +1720,8 @@ status_t GonkRecorder::startMPEG4Recording() {
|
||||
int32_t totalBitRate;
|
||||
status_t err = setupMPEG4Recording(
|
||||
mOutputFd, mVideoWidth, mVideoHeight,
|
||||
mVideoBitRate, &totalBitRate, &mWriter);
|
||||
mVideoBitRate, &totalBitRate, &mWriter,
|
||||
&mWriterSource);
|
||||
if (err != OK) {
|
||||
return err;
|
||||
}
|
||||
@ -1616,20 +1750,56 @@ status_t GonkRecorder::pause() {
|
||||
if (mWriter == NULL) {
|
||||
return UNKNOWN_ERROR;
|
||||
}
|
||||
mWriter->pause();
|
||||
|
||||
if (mStarted) {
|
||||
if (!mStarted) {
|
||||
return OK;
|
||||
}
|
||||
// Pause is not properly supported by all writers although
|
||||
// for B2G we only currently use 3GPP/MPEG4
|
||||
int err = INVALID_OPERATION;
|
||||
switch (mOutputFormat) {
|
||||
case OUTPUT_FORMAT_DEFAULT:
|
||||
case OUTPUT_FORMAT_THREE_GPP:
|
||||
case OUTPUT_FORMAT_MPEG_4:
|
||||
err = mWriter->pause();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (err == OK) {
|
||||
mStarted = false;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
return OK;
|
||||
status_t GonkRecorder::resume() {
|
||||
RE_LOGV("resume");
|
||||
if (mWriter == NULL) {
|
||||
return UNKNOWN_ERROR;
|
||||
}
|
||||
if (mStarted) {
|
||||
return OK;
|
||||
}
|
||||
/* While the writer is paused, it will continue to pull frames
|
||||
from the encoder. This ensures continuity on the timestamps of
|
||||
the encoded frames, etc. When we want to resume however, we must
|
||||
ensure that the first read frame is a key frame. */
|
||||
mWriterSource->block();
|
||||
int err = mWriter->start(NULL);
|
||||
if (err != OK) {
|
||||
return err;
|
||||
}
|
||||
err = mWriterSource->resume();
|
||||
if (err == OK) {
|
||||
mStarted = true;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
status_t GonkRecorder::stop() {
|
||||
RE_LOGV("stop");
|
||||
status_t err = OK;
|
||||
|
||||
mWriterSource.clear();
|
||||
if (mWriter != NULL) {
|
||||
err = mWriter->stop();
|
||||
mWriter.clear();
|
||||
|
@ -63,6 +63,7 @@ struct GonkRecorder {
|
||||
virtual status_t prepare();
|
||||
virtual status_t start();
|
||||
virtual status_t pause();
|
||||
virtual status_t resume();
|
||||
virtual status_t stop();
|
||||
virtual status_t close();
|
||||
virtual status_t reset();
|
||||
@ -74,10 +75,13 @@ protected:
|
||||
virtual ~GonkRecorder();
|
||||
|
||||
private:
|
||||
struct WrappedMediaSource;
|
||||
|
||||
sp<IMediaRecorderClient> mListener;
|
||||
String16 mClientName;
|
||||
uid_t mClientUid;
|
||||
sp<MediaWriter> mWriter;
|
||||
sp<WrappedMediaSource> mWriterSource;
|
||||
int mOutputFd;
|
||||
sp<AudioSource> mAudioSourceNode;
|
||||
|
||||
@ -127,7 +131,8 @@ private:
|
||||
int32_t videoWidth, int32_t videoHeight,
|
||||
int32_t videoBitRate,
|
||||
int32_t *totalBitRate,
|
||||
sp<MediaWriter> *mediaWriter);
|
||||
sp<MediaWriter> *mediaWriter,
|
||||
sp<WrappedMediaSource> *mediaSource);
|
||||
void setupMPEG4MetaData(int64_t startTimeUs, int32_t totalBitRate,
|
||||
sp<MetaData> *meta);
|
||||
status_t startMPEG4Recording();
|
||||
|
@ -256,6 +256,8 @@ public:
|
||||
virtual nsresult StartRecording(DeviceStorageFileDescriptor* aFileDescriptor,
|
||||
const StartRecordingOptions* aOptions = nullptr) = 0;
|
||||
virtual nsresult StopRecording() = 0;
|
||||
virtual nsresult PauseRecording() = 0;
|
||||
virtual nsresult ResumeRecording() = 0;
|
||||
virtual nsresult StartFaceDetection() = 0;
|
||||
virtual nsresult StopFaceDetection() = 0;
|
||||
virtual nsresult ResumeContinuousFocus() = 0;
|
||||
|
@ -80,6 +80,8 @@ function CameraTestSuite() {
|
||||
this.rejectTakePicture = this._rejectTakePicture.bind(this);
|
||||
this.rejectStartRecording = this._rejectStartRecording.bind(this);
|
||||
this.rejectStopRecording = this._rejectStopRecording.bind(this);
|
||||
this.rejectPauseRecording = this._rejectPauseRecording.bind(this);
|
||||
this.rejectResumeRecording = this._rejectResumeRecording.bind(this);
|
||||
this.rejectPreviewStarted = this._rejectPreviewStarted.bind(this);
|
||||
|
||||
var self = this;
|
||||
@ -409,6 +411,14 @@ CameraTestSuite.prototype = {
|
||||
return this.logError('stop recording failed', e);
|
||||
},
|
||||
|
||||
_rejectPauseRecording: function(e) {
|
||||
return this.logError('pause recording failed', e);
|
||||
},
|
||||
|
||||
_rejectResumeRecording: function(e) {
|
||||
return this.logError('resume recording failed', e);
|
||||
},
|
||||
|
||||
_rejectPreviewStarted: function(e) {
|
||||
return this.logError('preview start failed', e);
|
||||
},
|
||||
|
@ -45,6 +45,50 @@ suite.test('recording', function() {
|
||||
return Promise.all([domPromise, eventPromise]);
|
||||
}
|
||||
|
||||
function pauseRecording(p) {
|
||||
var eventPromise = new Promise(function(resolve, reject) {
|
||||
function onEvent(evt) {
|
||||
ok(evt.newState === 'Paused', 'recorder state change event = ' + evt.newState);
|
||||
suite.camera.removeEventListener('recorderstatechange', onEvent);
|
||||
resolve();
|
||||
}
|
||||
suite.camera.addEventListener('recorderstatechange', onEvent);
|
||||
});
|
||||
|
||||
var domPromise = new Promise(function(resolve, reject) {
|
||||
try {
|
||||
suite.camera.pauseRecording();
|
||||
resolve();
|
||||
} catch(e) {
|
||||
reject(e);
|
||||
}
|
||||
});
|
||||
|
||||
return Promise.all([domPromise, eventPromise]);
|
||||
}
|
||||
|
||||
function resumeRecording(p) {
|
||||
var eventPromise = new Promise(function(resolve, reject) {
|
||||
function onEvent(evt) {
|
||||
ok(evt.newState === 'Resumed', 'recorder state change event = ' + evt.newState);
|
||||
suite.camera.removeEventListener('recorderstatechange', onEvent);
|
||||
resolve();
|
||||
}
|
||||
suite.camera.addEventListener('recorderstatechange', onEvent);
|
||||
});
|
||||
|
||||
var domPromise = new Promise(function(resolve, reject) {
|
||||
try {
|
||||
suite.camera.resumeRecording();
|
||||
resolve();
|
||||
} catch(e) {
|
||||
reject(e);
|
||||
}
|
||||
});
|
||||
|
||||
return Promise.all([domPromise, eventPromise]);
|
||||
}
|
||||
|
||||
function stopRecording(p) {
|
||||
var eventPromise = new Promise(function(resolve, reject) {
|
||||
function onEvent(evt) {
|
||||
@ -70,7 +114,9 @@ suite.test('recording', function() {
|
||||
return suite.getCamera(undefined, baseConfig)
|
||||
.then(cleanup, suite.rejectGetCamera)
|
||||
.then(startRecording)
|
||||
.then(stopRecording, suite.rejectStartRecording)
|
||||
.then(pauseRecording, suite.rejectStartRecording)
|
||||
.then(resumeRecording, suite.rejectPauseRecording)
|
||||
.then(stopRecording, suite.rejectResumeRecording)
|
||||
.catch(suite.rejectStopRecording);
|
||||
});
|
||||
|
||||
|
@ -249,7 +249,19 @@ interface CameraControl : MediaStream
|
||||
recording limits (see CameraStartRecordingOptions) was reached.
|
||||
|
||||
event type is CameraStateChangeEvent where:
|
||||
'newState' is the new recorder state */
|
||||
'newState' is one of the following states:
|
||||
'Started' if the recording has begun capturing data
|
||||
'Stopped' when the recording has completed (success and failure)
|
||||
'Paused' if the recording is paused
|
||||
'Resumed' if the recording is resumed after pausing
|
||||
'PosterCreated' if a poster was requested and created
|
||||
'PosterFailed' if a poster was requested and failed to create
|
||||
'FileSizeLimitReached' if stopped due to file size limit
|
||||
'VideoLengthLimitReached' if stopped due to a time limit
|
||||
'TrackCompleted' if audio or video track complete when stopping
|
||||
'TrackFailed' if audio or video track incomplete when stopping
|
||||
'MediaRecorderFailed' if failed due to local error
|
||||
'MediaServerFailed' if failed due to media server
|
||||
attribute EventHandler onrecorderstatechange;
|
||||
|
||||
/* the event dispatched when the viewfinder stops or starts,
|
||||
@ -346,10 +358,21 @@ interface CameraControl : MediaStream
|
||||
DeviceStorage storageArea,
|
||||
DOMString filename);
|
||||
|
||||
/* stop precording video. */
|
||||
/* stop recording video. */
|
||||
[Throws]
|
||||
void stopRecording();
|
||||
|
||||
/* pause recording video. The camera remains active but audio and video
|
||||
frames are no longer saved in the output file. If called when not
|
||||
recording or already paused, it fails silently. */
|
||||
[Throws]
|
||||
void pauseRecording();
|
||||
|
||||
/* resume recording video while paused. If called when not recording or
|
||||
not paused, it fails silently. */
|
||||
[Throws]
|
||||
void resumeRecording();
|
||||
|
||||
/* call in or after the takePicture() onSuccess callback to
|
||||
resume the camera preview stream. */
|
||||
[Throws]
|
||||
|
@ -21,7 +21,7 @@ RUN git config --global user.email "mozilla@example.com" && \
|
||||
git config --global user.name "mozilla"
|
||||
|
||||
# VCS Tools
|
||||
RUN npm install -g taskcluster-vcs@2.3.6
|
||||
RUN npm install -g taskcluster-vcs@2.3.8
|
||||
|
||||
# TODO enable worker
|
||||
# TODO volume mount permissions will be an issue
|
||||
|
@ -1 +1 @@
|
||||
0.5.6
|
||||
0.5.7
|
||||
|
@ -1,4 +1,4 @@
|
||||
FROM quay.io/djmitche/ubuntu-build:0.0.4
|
||||
FROM taskcluster/ubuntu-build:0.0.5
|
||||
MAINTAINER Morgan Reece Phillips <winter2718@gmail.com>
|
||||
|
||||
# Add build scripts; these are the entry points from the taskcluster worker, and
|
||||
|
@ -1 +1 @@
|
||||
quay.io/djmitche
|
||||
taskcluster
|
||||
|
@ -1 +1 @@
|
||||
0.0.22
|
||||
0.0.23
|
||||
|
@ -1,4 +1,4 @@
|
||||
FROM quay.io/djmitche/ubuntu32-build:0.0.4
|
||||
FROM taskcluster/ubuntu32-build:0.0.5
|
||||
MAINTAINER Morgan Reece Phillips <winter2718@gmail.com>
|
||||
|
||||
# Add build scripts; these are the entry points from the taskcluster worker, and
|
||||
|
@ -1 +1 @@
|
||||
quay.io/djmitche
|
||||
taskcluster
|
||||
|
@ -1 +1 @@
|
||||
0.0.2
|
||||
0.0.3
|
||||
|
@ -31,7 +31,7 @@ RUN git config --global user.email "mozilla@example.com" && \
|
||||
|
||||
|
||||
# Get node packages
|
||||
RUN npm install -g taskcluster-vcs@2.3.1
|
||||
RUN npm install -g taskcluster-vcs@2.3.8
|
||||
|
||||
WORKDIR /home/worker
|
||||
|
||||
|
@ -1 +1 @@
|
||||
0.0.4
|
||||
0.0.5
|
||||
|
@ -18,7 +18,7 @@ RUN chmod u+x /usr/local/bin/linux64-minidump_stackwalk
|
||||
RUN apt-get install -y python-pip && pip install virtualenv;
|
||||
RUN mkdir Documents; mkdir Pictures; mkdir Music; mkdir Videos; mkdir artifacts
|
||||
RUN npm install -g npm@^2.0.0
|
||||
RUN npm install -g taskcluster-vcs@2.3.4
|
||||
RUN npm install -g taskcluster-vcs@2.3.8
|
||||
RUN npm install -g taskcluster-npm-cache@1.1.14
|
||||
RUN rm -Rf .cache && mkdir -p .cache
|
||||
ENV PATH $PATH:/home/worker/bin
|
||||
|
@ -1 +1 @@
|
||||
0.3.5
|
||||
0.3.6
|
||||
|
@ -11,7 +11,7 @@ RUN bash /tmp/system-setup.sh
|
||||
# configure git and install tc-vcs
|
||||
RUN git config --global user.email "nobody@mozilla.com" && \
|
||||
git config --global user.name "mozilla"
|
||||
RUN npm install -g taskcluster-vcs@2.3.6
|
||||
RUN npm install -g taskcluster-vcs@2.3.8
|
||||
|
||||
# Ensure that build specific dependencies live in a single layer
|
||||
ADD build-setup.sh /tmp/build-setup.sh
|
||||
|
@ -1 +1 @@
|
||||
quay.io/djmitche
|
||||
taskcluster
|
||||
|
@ -1 +1 @@
|
||||
0.0.4
|
||||
0.0.5
|
||||
|
@ -11,7 +11,7 @@ RUN bash /tmp/system-setup.sh
|
||||
# configure git and install tc-vcs
|
||||
RUN git config --global user.email "nobody@mozilla.com" && \
|
||||
git config --global user.name "mozilla"
|
||||
RUN npm install -g taskcluster-vcs@2.3.6
|
||||
RUN npm install -g taskcluster-vcs@2.3.8
|
||||
|
||||
# Ensure that build specific dependencies live in a single layer
|
||||
ADD build-setup.sh /tmp/build-setup.sh
|
||||
|
@ -1 +1 @@
|
||||
quay.io/djmitche
|
||||
taskcluster
|
||||
|
@ -1 +1 @@
|
||||
0.0.4
|
||||
0.0.5
|
||||
|
Loading…
Reference in New Issue
Block a user