mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1030007 - Throttle updating the preview window when CPU low and/or encoder falls behind. r=mikeh, r=cpearce
This commit is contained in:
parent
9213c02ced
commit
072944be8a
@ -66,15 +66,22 @@ nsresult MediaOmxReader::Init(MediaDecoderReader* aCloneDonor)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaOmxReader::Shutdown()
|
void MediaOmxReader::ReleaseDecoder()
|
||||||
{
|
{
|
||||||
ReleaseMediaResources();
|
|
||||||
if (mOmxDecoder.get()) {
|
if (mOmxDecoder.get()) {
|
||||||
mOmxDecoder->ReleaseDecoder();
|
mOmxDecoder->ReleaseDecoder();
|
||||||
}
|
}
|
||||||
mOmxDecoder.clear();
|
mOmxDecoder.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MediaOmxReader::Shutdown()
|
||||||
|
{
|
||||||
|
ReleaseMediaResources();
|
||||||
|
nsCOMPtr<nsIRunnable> event =
|
||||||
|
NS_NewRunnableMethod(this, &MediaOmxReader::ReleaseDecoder);
|
||||||
|
NS_DispatchToMainThread(event);
|
||||||
|
}
|
||||||
|
|
||||||
bool MediaOmxReader::IsWaitingMediaResources()
|
bool MediaOmxReader::IsWaitingMediaResources()
|
||||||
{
|
{
|
||||||
if (!mOmxDecoder.get()) {
|
if (!mOmxDecoder.get()) {
|
||||||
|
@ -104,6 +104,8 @@ public:
|
|||||||
// ANDROID_VERSION < 19
|
// ANDROID_VERSION < 19
|
||||||
void CheckAudioOffload();
|
void CheckAudioOffload();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void ReleaseDecoder();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
@ -248,6 +248,20 @@ CameraControlImpl::OnPreviewStateChange(CameraControlListener::PreviewState aNew
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CameraControlImpl::OnRateLimitPreview(bool aLimit)
|
||||||
|
{
|
||||||
|
// This function runs on neither the Main Thread nor the Camera Thread.
|
||||||
|
RwLockAutoEnterRead lock(mListenerLock);
|
||||||
|
|
||||||
|
DOM_CAMERA_LOGI("OnRateLimitPreview: %d\n", aLimit);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < mListeners.Length(); ++i) {
|
||||||
|
CameraControlListener* l = mListeners[i];
|
||||||
|
l->OnRateLimitPreview(aLimit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CameraControlImpl::OnNewPreviewFrame(layers::Image* aImage, uint32_t aWidth, uint32_t aHeight)
|
CameraControlImpl::OnNewPreviewFrame(layers::Image* aImage, uint32_t aWidth, uint32_t aHeight)
|
||||||
{
|
{
|
||||||
|
@ -67,6 +67,7 @@ protected:
|
|||||||
void OnFacesDetected(const nsTArray<Face>& aFaces);
|
void OnFacesDetected(const nsTArray<Face>& aFaces);
|
||||||
void OnTakePictureComplete(uint8_t* aData, uint32_t aLength, const nsAString& aMimeType);
|
void OnTakePictureComplete(uint8_t* aData, uint32_t aLength, const nsAString& aMimeType);
|
||||||
|
|
||||||
|
void OnRateLimitPreview(bool aLimit);
|
||||||
bool OnNewPreviewFrame(layers::Image* aImage, uint32_t aWidth, uint32_t aHeight);
|
bool OnNewPreviewFrame(layers::Image* aImage, uint32_t aWidth, uint32_t aHeight);
|
||||||
void OnRecorderStateChange(CameraControlListener::RecorderState aState,
|
void OnRecorderStateChange(CameraControlListener::RecorderState aState,
|
||||||
int32_t aStatus = -1, int32_t aTrackNumber = -1);
|
int32_t aStatus = -1, int32_t aTrackNumber = -1);
|
||||||
|
@ -64,6 +64,7 @@ public:
|
|||||||
virtual void OnRecorderStateChange(RecorderState aState, int32_t aStatus, int32_t aTrackNum) { }
|
virtual void OnRecorderStateChange(RecorderState aState, int32_t aStatus, int32_t aTrackNum) { }
|
||||||
|
|
||||||
virtual void OnShutter() { }
|
virtual void OnShutter() { }
|
||||||
|
virtual void OnRateLimitPreview(bool aLimit) { }
|
||||||
virtual bool OnNewPreviewFrame(layers::Image* aFrame, uint32_t aWidth, uint32_t aHeight)
|
virtual bool OnNewPreviewFrame(layers::Image* aFrame, uint32_t aWidth, uint32_t aHeight)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -4,6 +4,15 @@
|
|||||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "CameraPreviewMediaStream.h"
|
#include "CameraPreviewMediaStream.h"
|
||||||
|
#include "CameraCommon.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum number of outstanding invalidates before we start to drop frames;
|
||||||
|
* if we hit this threshold, it is an indicator that the main thread is
|
||||||
|
* either very busy or the device is busy elsewhere (e.g. encoding or
|
||||||
|
* persisting video data).
|
||||||
|
*/
|
||||||
|
#define MAX_INVALIDATE_PENDING 4
|
||||||
|
|
||||||
using namespace mozilla::layers;
|
using namespace mozilla::layers;
|
||||||
using namespace mozilla::dom;
|
using namespace mozilla::dom;
|
||||||
@ -13,7 +22,9 @@ namespace mozilla {
|
|||||||
CameraPreviewMediaStream::CameraPreviewMediaStream(DOMMediaStream* aWrapper)
|
CameraPreviewMediaStream::CameraPreviewMediaStream(DOMMediaStream* aWrapper)
|
||||||
: MediaStream(aWrapper)
|
: MediaStream(aWrapper)
|
||||||
, mMutex("mozilla::camera::CameraPreviewMediaStream")
|
, mMutex("mozilla::camera::CameraPreviewMediaStream")
|
||||||
, mFrameCallback(nullptr)
|
, mInvalidatePending(0)
|
||||||
|
, mDiscardedFrames(0)
|
||||||
|
, mRateLimit(false)
|
||||||
{
|
{
|
||||||
SetGraphImpl(MediaStreamGraph::GetInstance());
|
SetGraphImpl(MediaStreamGraph::GetInstance());
|
||||||
mIsConsumed = false;
|
mIsConsumed = false;
|
||||||
@ -103,22 +114,53 @@ CameraPreviewMediaStream::Destroy()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CameraPreviewMediaStream::SetCurrentFrame(const gfxIntSize& aIntrinsicSize, Image* aImage)
|
CameraPreviewMediaStream::Invalidate()
|
||||||
{
|
{
|
||||||
MutexAutoLock lock(mMutex);
|
MutexAutoLock lock(mMutex);
|
||||||
|
--mInvalidatePending;
|
||||||
TimeStamp now = TimeStamp::Now();
|
for (nsTArray<nsRefPtr<VideoFrameContainer> >::size_type i = 0; i < mVideoOutputs.Length(); ++i) {
|
||||||
for (uint32_t i = 0; i < mVideoOutputs.Length(); ++i) {
|
|
||||||
VideoFrameContainer* output = mVideoOutputs[i];
|
VideoFrameContainer* output = mVideoOutputs[i];
|
||||||
output->SetCurrentFrame(aIntrinsicSize, aImage, now);
|
output->Invalidate();
|
||||||
nsCOMPtr<nsIRunnable> event =
|
}
|
||||||
NS_NewRunnableMethod(output, &VideoFrameContainer::Invalidate);
|
}
|
||||||
NS_DispatchToMainThread(event);
|
|
||||||
|
void
|
||||||
|
CameraPreviewMediaStream::RateLimit(bool aLimit)
|
||||||
|
{
|
||||||
|
mRateLimit = aLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CameraPreviewMediaStream::SetCurrentFrame(const gfxIntSize& aIntrinsicSize, Image* aImage)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
MutexAutoLock lock(mMutex);
|
||||||
|
|
||||||
|
if (mInvalidatePending > 0) {
|
||||||
|
if (mRateLimit || mInvalidatePending > MAX_INVALIDATE_PENDING) {
|
||||||
|
++mDiscardedFrames;
|
||||||
|
DOM_CAMERA_LOGW("Discard preview frame %d, %d invalidation(s) pending",
|
||||||
|
mDiscardedFrames, mInvalidatePending);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DOM_CAMERA_LOGI("Update preview frame, %d invalidation(s) pending",
|
||||||
|
mInvalidatePending);
|
||||||
|
}
|
||||||
|
mDiscardedFrames = 0;
|
||||||
|
|
||||||
|
TimeStamp now = TimeStamp::Now();
|
||||||
|
for (nsTArray<nsRefPtr<VideoFrameContainer> >::size_type i = 0; i < mVideoOutputs.Length(); ++i) {
|
||||||
|
VideoFrameContainer* output = mVideoOutputs[i];
|
||||||
|
output->SetCurrentFrame(aIntrinsicSize, aImage, now);
|
||||||
|
}
|
||||||
|
|
||||||
|
++mInvalidatePending;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mFrameCallback) {
|
nsCOMPtr<nsIRunnable> event =
|
||||||
mFrameCallback->OnNewFrame(aIntrinsicSize, aImage);
|
NS_NewRunnableMethod(this, &CameraPreviewMediaStream::Invalidate);
|
||||||
}
|
NS_DispatchToMainThread(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -126,7 +168,7 @@ CameraPreviewMediaStream::ClearCurrentFrame()
|
|||||||
{
|
{
|
||||||
MutexAutoLock lock(mMutex);
|
MutexAutoLock lock(mMutex);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < mVideoOutputs.Length(); ++i) {
|
for (nsTArray<nsRefPtr<VideoFrameContainer> >::size_type i = 0; i < mVideoOutputs.Length(); ++i) {
|
||||||
VideoFrameContainer* output = mVideoOutputs[i];
|
VideoFrameContainer* output = mVideoOutputs[i];
|
||||||
output->ClearCurrentFrame();
|
output->ClearCurrentFrame();
|
||||||
nsCOMPtr<nsIRunnable> event =
|
nsCOMPtr<nsIRunnable> event =
|
||||||
|
@ -11,13 +11,8 @@
|
|||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
class CameraPreviewFrameCallback {
|
|
||||||
public:
|
|
||||||
virtual void OnNewFrame(const gfxIntSize& aIntrinsicSize, layers::Image* aImage) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a stream for camere preview.
|
* This is a stream for camera preview.
|
||||||
*
|
*
|
||||||
* XXX It is a temporary fix of SourceMediaStream.
|
* XXX It is a temporary fix of SourceMediaStream.
|
||||||
* A camera preview requests no delay and no buffering stream.
|
* A camera preview requests no delay and no buffering stream.
|
||||||
@ -40,20 +35,21 @@ public:
|
|||||||
virtual void RemoveListener(MediaStreamListener* aListener) MOZ_OVERRIDE;
|
virtual void RemoveListener(MediaStreamListener* aListener) MOZ_OVERRIDE;
|
||||||
virtual void Destroy();
|
virtual void Destroy();
|
||||||
|
|
||||||
|
void Invalidate();
|
||||||
|
|
||||||
// Call these on any thread.
|
// Call these on any thread.
|
||||||
void SetCurrentFrame(const gfxIntSize& aIntrinsicSize, Image* aImage);
|
void SetCurrentFrame(const gfxIntSize& aIntrinsicSize, Image* aImage);
|
||||||
void ClearCurrentFrame();
|
void ClearCurrentFrame();
|
||||||
|
void RateLimit(bool aLimit);
|
||||||
void SetFrameCallback(CameraPreviewFrameCallback* aCallback) {
|
|
||||||
mFrameCallback = aCallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// mMutex protects all the class' fields.
|
// mMutex protects all the class' fields.
|
||||||
// This class is not registered to MediaStreamGraph.
|
// This class is not registered to MediaStreamGraph.
|
||||||
// It needs to protect all the fields.
|
// It needs to protect all the fields.
|
||||||
Mutex mMutex;
|
Mutex mMutex;
|
||||||
CameraPreviewFrameCallback* mFrameCallback;
|
int32_t mInvalidatePending;
|
||||||
|
uint32_t mDiscardedFrames;
|
||||||
|
bool mRateLimit;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -214,7 +214,7 @@ protected:
|
|||||||
DOMCameraControlListener* mListener;
|
DOMCameraControlListener* mListener;
|
||||||
|
|
||||||
// our viewfinder stream
|
// our viewfinder stream
|
||||||
CameraPreviewMediaStream* mInput;
|
nsRefPtr<CameraPreviewMediaStream> mInput;
|
||||||
|
|
||||||
// set once when this object is created
|
// set once when this object is created
|
||||||
nsCOMPtr<nsPIDOMWindow> mWindow;
|
nsCOMPtr<nsPIDOMWindow> mWindow;
|
||||||
|
@ -287,6 +287,12 @@ DOMCameraControlListener::OnShutter()
|
|||||||
NS_DispatchToMainThread(new Callback(mDOMCameraControl));
|
NS_DispatchToMainThread(new Callback(mDOMCameraControl));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DOMCameraControlListener::OnRateLimitPreview(bool aLimit)
|
||||||
|
{
|
||||||
|
mStream->RateLimit(aLimit);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
DOMCameraControlListener::OnNewPreviewFrame(layers::Image* aImage, uint32_t aWidth, uint32_t aHeight)
|
DOMCameraControlListener::OnNewPreviewFrame(layers::Image* aImage, uint32_t aWidth, uint32_t aHeight)
|
||||||
{
|
{
|
||||||
|
@ -28,6 +28,7 @@ public:
|
|||||||
virtual void OnRecorderStateChange(RecorderState aState, int32_t aStatus, int32_t aTrackNum) MOZ_OVERRIDE;
|
virtual void OnRecorderStateChange(RecorderState aState, int32_t aStatus, int32_t aTrackNum) MOZ_OVERRIDE;
|
||||||
virtual void OnConfigurationChange(const CameraListenerConfiguration& aConfiguration) MOZ_OVERRIDE;
|
virtual void OnConfigurationChange(const CameraListenerConfiguration& aConfiguration) MOZ_OVERRIDE;
|
||||||
virtual void OnShutter() MOZ_OVERRIDE;
|
virtual void OnShutter() MOZ_OVERRIDE;
|
||||||
|
virtual void OnRateLimitPreview(bool aLimit) MOZ_OVERRIDE;
|
||||||
virtual bool OnNewPreviewFrame(layers::Image* aImage, uint32_t aWidth, uint32_t aHeight) MOZ_OVERRIDE;
|
virtual bool OnNewPreviewFrame(layers::Image* aImage, uint32_t aWidth, uint32_t aHeight) MOZ_OVERRIDE;
|
||||||
virtual void OnUserError(UserContext aContext, nsresult aError) MOZ_OVERRIDE;
|
virtual void OnUserError(UserContext aContext, nsresult aError) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
@ -1682,6 +1682,12 @@ nsGonkCameraControl::GetRecorderProfileManagerImpl()
|
|||||||
return profileMgr.forget();
|
return profileMgr.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsGonkCameraControl::OnRateLimitPreview(bool aLimit)
|
||||||
|
{
|
||||||
|
CameraControlImpl::OnRateLimitPreview(aLimit);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsGonkCameraControl::OnNewPreviewFrame(layers::TextureClient* aBuffer)
|
nsGonkCameraControl::OnNewPreviewFrame(layers::TextureClient* aBuffer)
|
||||||
{
|
{
|
||||||
@ -1744,6 +1750,12 @@ OnFacesDetected(nsGonkCameraControl* gc, camera_frame_metadata_t* aMetaData)
|
|||||||
gc->OnFacesDetected(aMetaData);
|
gc->OnFacesDetected(aMetaData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
OnRateLimitPreview(nsGonkCameraControl* gc, bool aLimit)
|
||||||
|
{
|
||||||
|
gc->OnRateLimitPreview(aLimit);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
OnNewPreviewFrame(nsGonkCameraControl* gc, layers::TextureClient* aBuffer)
|
OnNewPreviewFrame(nsGonkCameraControl* gc, layers::TextureClient* aBuffer)
|
||||||
{
|
{
|
||||||
|
@ -52,10 +52,11 @@ public:
|
|||||||
void OnFacesDetected(camera_frame_metadata_t* aMetaData);
|
void OnFacesDetected(camera_frame_metadata_t* aMetaData);
|
||||||
void OnTakePictureComplete(uint8_t* aData, uint32_t aLength);
|
void OnTakePictureComplete(uint8_t* aData, uint32_t aLength);
|
||||||
void OnTakePictureError();
|
void OnTakePictureError();
|
||||||
|
void OnRateLimitPreview(bool aLimit);
|
||||||
void OnNewPreviewFrame(layers::TextureClient* aBuffer);
|
void OnNewPreviewFrame(layers::TextureClient* aBuffer);
|
||||||
void OnRecorderEvent(int msg, int ext1, int ext2);
|
void OnRecorderEvent(int msg, int ext1, int ext2);
|
||||||
void OnSystemError(CameraControlListener::SystemContext aWhere, nsresult aError);
|
void OnSystemError(CameraControlListener::SystemContext aWhere, nsresult aError);
|
||||||
|
|
||||||
// See ICameraControl.h for getter/setter return values.
|
// See ICameraControl.h for getter/setter return values.
|
||||||
virtual nsresult Set(uint32_t aKey, const nsAString& aValue) MOZ_OVERRIDE;
|
virtual nsresult Set(uint32_t aKey, const nsAString& aValue) MOZ_OVERRIDE;
|
||||||
virtual nsresult Get(uint32_t aKey, nsAString& aValue) MOZ_OVERRIDE;
|
virtual nsresult Get(uint32_t aKey, nsAString& aValue) MOZ_OVERRIDE;
|
||||||
@ -84,6 +85,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
~nsGonkCameraControl();
|
~nsGonkCameraControl();
|
||||||
|
|
||||||
|
using CameraControlImpl::OnRateLimitPreview;
|
||||||
using CameraControlImpl::OnNewPreviewFrame;
|
using CameraControlImpl::OnNewPreviewFrame;
|
||||||
using CameraControlImpl::OnAutoFocusComplete;
|
using CameraControlImpl::OnAutoFocusComplete;
|
||||||
using CameraControlImpl::OnFacesDetected;
|
using CameraControlImpl::OnFacesDetected;
|
||||||
@ -178,6 +180,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// camera driver callbacks
|
// camera driver callbacks
|
||||||
|
void OnRateLimitPreview(nsGonkCameraControl* gc, bool aLimit);
|
||||||
void OnTakePictureComplete(nsGonkCameraControl* gc, uint8_t* aData, uint32_t aLength);
|
void OnTakePictureComplete(nsGonkCameraControl* gc, uint8_t* aData, uint32_t aLength);
|
||||||
void OnTakePictureError(nsGonkCameraControl* gc);
|
void OnTakePictureError(nsGonkCameraControl* gc);
|
||||||
void OnAutoFocusComplete(nsGonkCameraControl* gc, bool aSuccess);
|
void OnAutoFocusComplete(nsGonkCameraControl* gc, bool aSuccess);
|
||||||
|
@ -44,6 +44,12 @@ GonkCameraHardware::GonkCameraHardware(mozilla::nsGonkCameraControl* aTarget, ui
|
|||||||
DOM_CAMERA_LOGT("%s:%d : this=%p (aTarget=%p)\n", __func__, __LINE__, (void*)this, (void*)aTarget);
|
DOM_CAMERA_LOGT("%s:%d : this=%p (aTarget=%p)\n", __func__, __LINE__, (void*)this, (void*)aTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GonkCameraHardware::OnRateLimitPreview(bool aLimit)
|
||||||
|
{
|
||||||
|
::OnRateLimitPreview(mTarget, aLimit);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
GonkCameraHardware::OnNewFrame()
|
GonkCameraHardware::OnNewFrame()
|
||||||
{
|
{
|
||||||
|
@ -55,6 +55,8 @@ public:
|
|||||||
static sp<GonkCameraHardware> Connect(mozilla::nsGonkCameraControl* aTarget, uint32_t aCameraId);
|
static sp<GonkCameraHardware> Connect(mozilla::nsGonkCameraControl* aTarget, uint32_t aCameraId);
|
||||||
virtual void Close();
|
virtual void Close();
|
||||||
|
|
||||||
|
virtual void OnRateLimitPreview(bool aLimit);
|
||||||
|
|
||||||
// derived from GonkNativeWindowNewFrameCallback
|
// derived from GonkNativeWindowNewFrameCallback
|
||||||
virtual void OnNewFrame() MOZ_OVERRIDE;
|
virtual void OnNewFrame() MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
@ -170,6 +170,7 @@ GonkCameraSource::GonkCameraSource(
|
|||||||
mStarted(false),
|
mStarted(false),
|
||||||
mNumFramesEncoded(0),
|
mNumFramesEncoded(0),
|
||||||
mTimeBetweenFrameCaptureUs(0),
|
mTimeBetweenFrameCaptureUs(0),
|
||||||
|
mRateLimit(false),
|
||||||
mFirstFrameTimeUs(0),
|
mFirstFrameTimeUs(0),
|
||||||
mNumFramesDropped(0),
|
mNumFramesDropped(0),
|
||||||
mNumGlitches(0),
|
mNumGlitches(0),
|
||||||
@ -589,6 +590,10 @@ status_t GonkCameraSource::reset() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
stopCameraRecording();
|
stopCameraRecording();
|
||||||
|
if (mRateLimit) {
|
||||||
|
mRateLimit = false;
|
||||||
|
mCameraHw->OnRateLimitPreview(false);
|
||||||
|
}
|
||||||
releaseCamera();
|
releaseCamera();
|
||||||
|
|
||||||
if (mCollectStats) {
|
if (mCollectStats) {
|
||||||
@ -692,51 +697,65 @@ status_t GonkCameraSource::read(
|
|||||||
|
|
||||||
void GonkCameraSource::dataCallbackTimestamp(int64_t timestampUs,
|
void GonkCameraSource::dataCallbackTimestamp(int64_t timestampUs,
|
||||||
int32_t msgType, const sp<IMemory> &data) {
|
int32_t msgType, const sp<IMemory> &data) {
|
||||||
|
bool rateLimit;
|
||||||
|
bool prevRateLimit;
|
||||||
CS_LOGV("dataCallbackTimestamp: timestamp %lld us", timestampUs);
|
CS_LOGV("dataCallbackTimestamp: timestamp %lld us", timestampUs);
|
||||||
Mutex::Autolock autoLock(mLock);
|
{
|
||||||
if (!mStarted || (mNumFramesReceived == 0 && timestampUs < mStartTimeUs)) {
|
Mutex::Autolock autoLock(mLock);
|
||||||
CS_LOGV("Drop frame at %lld/%lld us", timestampUs, mStartTimeUs);
|
if (!mStarted || (mNumFramesReceived == 0 && timestampUs < mStartTimeUs)) {
|
||||||
releaseOneRecordingFrame(data);
|
CS_LOGV("Drop frame at %lld/%lld us", timestampUs, mStartTimeUs);
|
||||||
return;
|
releaseOneRecordingFrame(data);
|
||||||
}
|
return;
|
||||||
|
|
||||||
if (mNumFramesReceived > 0) {
|
|
||||||
CHECK(timestampUs > mLastFrameTimestampUs);
|
|
||||||
if (timestampUs - mLastFrameTimestampUs > mGlitchDurationThresholdUs) {
|
|
||||||
++mNumGlitches;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// May need to skip frame or modify timestamp. Currently implemented
|
if (mNumFramesReceived > 0) {
|
||||||
// by the subclass CameraSourceTimeLapse.
|
CHECK(timestampUs > mLastFrameTimestampUs);
|
||||||
if (skipCurrentFrame(timestampUs)) {
|
if (timestampUs - mLastFrameTimestampUs > mGlitchDurationThresholdUs) {
|
||||||
releaseOneRecordingFrame(data);
|
++mNumGlitches;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mLastFrameTimestampUs = timestampUs;
|
|
||||||
if (mNumFramesReceived == 0) {
|
|
||||||
mFirstFrameTimeUs = timestampUs;
|
|
||||||
// Initial delay
|
|
||||||
if (mStartTimeUs > 0) {
|
|
||||||
if (timestampUs < mStartTimeUs) {
|
|
||||||
// Frame was captured before recording was started
|
|
||||||
// Drop it without updating the statistical data.
|
|
||||||
releaseOneRecordingFrame(data);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
mStartTimeUs = timestampUs - mStartTimeUs;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
++mNumFramesReceived;
|
|
||||||
|
|
||||||
CHECK(data != NULL && data->size() > 0);
|
// May need to skip frame or modify timestamp. Currently implemented
|
||||||
mFramesReceived.push_back(data);
|
// by the subclass CameraSourceTimeLapse.
|
||||||
int64_t timeUs = mStartTimeUs + (timestampUs - mFirstFrameTimeUs);
|
if (skipCurrentFrame(timestampUs)) {
|
||||||
mFrameTimes.push_back(timeUs);
|
releaseOneRecordingFrame(data);
|
||||||
CS_LOGV("initial delay: %lld, current time stamp: %lld",
|
return;
|
||||||
mStartTimeUs, timeUs);
|
}
|
||||||
mFrameAvailableCondition.signal();
|
|
||||||
|
mLastFrameTimestampUs = timestampUs;
|
||||||
|
if (mNumFramesReceived == 0) {
|
||||||
|
mFirstFrameTimeUs = timestampUs;
|
||||||
|
// Initial delay
|
||||||
|
if (mStartTimeUs > 0) {
|
||||||
|
if (timestampUs < mStartTimeUs) {
|
||||||
|
// Frame was captured before recording was started
|
||||||
|
// Drop it without updating the statistical data.
|
||||||
|
releaseOneRecordingFrame(data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mStartTimeUs = timestampUs - mStartTimeUs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++mNumFramesReceived;
|
||||||
|
|
||||||
|
// If a backlog is building up in the receive queue, we are likely
|
||||||
|
// resource constrained and we need to throttle
|
||||||
|
prevRateLimit = mRateLimit;
|
||||||
|
rateLimit = mFramesReceived.empty();
|
||||||
|
mRateLimit = rateLimit;
|
||||||
|
|
||||||
|
CHECK(data != NULL && data->size() > 0);
|
||||||
|
mFramesReceived.push_back(data);
|
||||||
|
int64_t timeUs = mStartTimeUs + (timestampUs - mFirstFrameTimeUs);
|
||||||
|
mFrameTimes.push_back(timeUs);
|
||||||
|
CS_LOGV("initial delay: %lld, current time stamp: %lld",
|
||||||
|
mStartTimeUs, timeUs);
|
||||||
|
mFrameAvailableCondition.signal();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(prevRateLimit != rateLimit) {
|
||||||
|
mCameraHw->OnRateLimitPreview(rateLimit);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GonkCameraSource::isMetaDataStoredInVideoBuffers() const {
|
bool GonkCameraSource::isMetaDataStoredInVideoBuffers() const {
|
||||||
|
@ -127,6 +127,7 @@ private:
|
|||||||
List<sp<IMemory> > mFramesReceived;
|
List<sp<IMemory> > mFramesReceived;
|
||||||
List<sp<IMemory> > mFramesBeingEncoded;
|
List<sp<IMemory> > mFramesBeingEncoded;
|
||||||
List<int64_t> mFrameTimes;
|
List<int64_t> mFrameTimes;
|
||||||
|
bool mRateLimit;
|
||||||
|
|
||||||
int64_t mFirstFrameTimeUs;
|
int64_t mFirstFrameTimeUs;
|
||||||
int32_t mNumFramesDropped;
|
int32_t mNumFramesDropped;
|
||||||
|
Loading…
Reference in New Issue
Block a user