mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 844248 - Add a custom media stream for camera preview. r=roc
This commit is contained in:
parent
7c086cdcb5
commit
ebcd1fab7b
@ -303,20 +303,20 @@ public:
|
||||
// a single audio output stream is used; the volumes are combined.
|
||||
// Currently only the first enabled audio track is played.
|
||||
// XXX change this so all enabled audio tracks are mixed and played.
|
||||
void AddAudioOutput(void* aKey);
|
||||
void SetAudioOutputVolume(void* aKey, float aVolume);
|
||||
void RemoveAudioOutput(void* aKey);
|
||||
virtual void AddAudioOutput(void* aKey);
|
||||
virtual void SetAudioOutputVolume(void* aKey, float aVolume);
|
||||
virtual void RemoveAudioOutput(void* aKey);
|
||||
// Since a stream can be played multiple ways, we need to be able to
|
||||
// play to multiple VideoFrameContainers.
|
||||
// Only the first enabled video track is played.
|
||||
void AddVideoOutput(VideoFrameContainer* aContainer);
|
||||
void RemoveVideoOutput(VideoFrameContainer* aContainer);
|
||||
virtual void AddVideoOutput(VideoFrameContainer* aContainer);
|
||||
virtual void RemoveVideoOutput(VideoFrameContainer* aContainer);
|
||||
// Explicitly block. Useful for example if a media element is pausing
|
||||
// and we need to stop its stream emitting its buffered data.
|
||||
void ChangeExplicitBlockerCount(int32_t aDelta);
|
||||
virtual void ChangeExplicitBlockerCount(int32_t aDelta);
|
||||
// Events will be dispatched by calling methods of aListener.
|
||||
void AddListener(MediaStreamListener* aListener);
|
||||
void RemoveListener(MediaStreamListener* aListener);
|
||||
virtual void AddListener(MediaStreamListener* aListener);
|
||||
virtual void RemoveListener(MediaStreamListener* aListener);
|
||||
// Events will be dispatched by calling methods of aListener. It is the
|
||||
// responsibility of the caller to remove aListener before it is destroyed.
|
||||
void AddMainThreadListener(MainThreadMediaStreamListener* aListener)
|
||||
@ -332,7 +332,7 @@ public:
|
||||
mMainThreadListeners.RemoveElement(aListener);
|
||||
}
|
||||
// Signal that the client is done with this MediaStream. It will be deleted later.
|
||||
void Destroy();
|
||||
virtual void Destroy();
|
||||
// Returns the main-thread's view of how much data has been processed by
|
||||
// this stream.
|
||||
StreamTime GetCurrentTime()
|
||||
|
111
dom/camera/CameraPreviewMediaStream.cpp
Normal file
111
dom/camera/CameraPreviewMediaStream.cpp
Normal file
@ -0,0 +1,111 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "CameraPreviewMediaStream.h"
|
||||
|
||||
using namespace mozilla::layers;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
void
|
||||
CameraPreviewMediaStream::AddAudioOutput(void* aKey)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
CameraPreviewMediaStream::SetAudioOutputVolume(void* aKey, float aVolume)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
CameraPreviewMediaStream::RemoveAudioOutput(void* aKey)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
CameraPreviewMediaStream::AddVideoOutput(VideoFrameContainer* aContainer)
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
nsRefPtr<VideoFrameContainer> container = aContainer;
|
||||
AddVideoOutputImpl(container.forget());
|
||||
|
||||
if (mVideoOutputs.Length() > 1) {
|
||||
return;
|
||||
}
|
||||
MediaStreamGraph* gm = MediaStreamGraph::GetInstance();
|
||||
mIsConsumed = true;
|
||||
for (uint32_t j = 0; j < mListeners.Length(); ++j) {
|
||||
MediaStreamListener* l = mListeners[j];
|
||||
l->NotifyConsumptionChanged(gm, MediaStreamListener::CONSUMED);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CameraPreviewMediaStream::RemoveVideoOutput(VideoFrameContainer* aContainer)
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
RemoveVideoOutputImpl(aContainer);
|
||||
|
||||
if (!mVideoOutputs.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
MediaStreamGraph* gm = MediaStreamGraph::GetInstance();
|
||||
mIsConsumed = false;
|
||||
for (uint32_t j = 0; j < mListeners.Length(); ++j) {
|
||||
MediaStreamListener* l = mListeners[j];
|
||||
l->NotifyConsumptionChanged(gm, MediaStreamListener::NOT_CONSUMED);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CameraPreviewMediaStream::ChangeExplicitBlockerCount(int32_t aDelta)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
CameraPreviewMediaStream::AddListener(MediaStreamListener* aListener)
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
||||
MediaStreamGraph* gm = MediaStreamGraph::GetInstance();
|
||||
MediaStreamListener* listener = *mListeners.AppendElement() = aListener;
|
||||
listener->NotifyBlockingChanged(gm, MediaStreamListener::UNBLOCKED);
|
||||
}
|
||||
|
||||
void
|
||||
CameraPreviewMediaStream::RemoveListener(MediaStreamListener* aListener)
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
||||
MediaStreamGraph* gm = MediaStreamGraph::GetInstance();
|
||||
nsRefPtr<MediaStreamListener> listener(aListener);
|
||||
mListeners.RemoveElement(aListener);
|
||||
listener->NotifyRemoved(gm);
|
||||
}
|
||||
|
||||
void
|
||||
CameraPreviewMediaStream::Destroy()
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
DestroyImpl();
|
||||
}
|
||||
|
||||
void
|
||||
CameraPreviewMediaStream::SetCurrentFrame(const gfxIntSize& aIntrinsicSize, Image* aImage)
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
||||
TimeStamp now = TimeStamp::Now();
|
||||
for (uint32_t i = 0; i < mVideoOutputs.Length(); ++i) {
|
||||
VideoFrameContainer* output = mVideoOutputs[i];
|
||||
output->SetCurrentFrame(aIntrinsicSize, aImage, now);
|
||||
nsCOMPtr<nsIRunnable> event =
|
||||
NS_NewRunnableMethod(output, &VideoFrameContainer::Invalidate);
|
||||
NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
55
dom/camera/CameraPreviewMediaStream.h
Normal file
55
dom/camera/CameraPreviewMediaStream.h
Normal file
@ -0,0 +1,55 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef DOM_CAMERA_CAMERAPREVIEWMEDIASTREAM_H
|
||||
#define DOM_CAMERA_CAMERAPREVIEWMEDIASTREAM_H
|
||||
|
||||
#include "VideoFrameContainer.h"
|
||||
#include "MediaStreamGraph.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
/**
|
||||
* This is a stream for camere preview.
|
||||
*
|
||||
* XXX It is a temporary fix of SourceMediaStream.
|
||||
* A camera preview requests no delay and no buffering stream.
|
||||
* But the SourceMediaStream do not support it.
|
||||
*/
|
||||
class CameraPreviewMediaStream : public MediaStream {
|
||||
typedef mozilla::layers::Image Image;
|
||||
|
||||
public:
|
||||
CameraPreviewMediaStream(DOMMediaStream* aWrapper) :
|
||||
MediaStream(aWrapper),
|
||||
mMutex("mozilla::camera::CameraPreviewMediaStream")
|
||||
{
|
||||
mIsConsumed = false;
|
||||
}
|
||||
|
||||
virtual void AddAudioOutput(void* aKey);
|
||||
virtual void SetAudioOutputVolume(void* aKey, float aVolume);
|
||||
virtual void RemoveAudioOutput(void* aKey);
|
||||
virtual void AddVideoOutput(VideoFrameContainer* aContainer);
|
||||
virtual void RemoveVideoOutput(VideoFrameContainer* aContainer);
|
||||
virtual void ChangeExplicitBlockerCount(int32_t aDelta);
|
||||
virtual void AddListener(MediaStreamListener* aListener);
|
||||
virtual void RemoveListener(MediaStreamListener* aListener);
|
||||
virtual void Destroy();
|
||||
|
||||
// Call these on any thread.
|
||||
void SetCurrentFrame(const gfxIntSize& aIntrinsicSize, Image* aImage);
|
||||
|
||||
protected:
|
||||
// mMutex protects all the class' fields.
|
||||
// This class is not registered to MediaStreamGraph.
|
||||
// It needs to protect all the fields.
|
||||
Mutex mMutex;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif // DOM_CAMERA_CAMERAPREVIEWMEDIASTREAM_H
|
@ -155,17 +155,13 @@ DOMCameraPreview::DOMCameraPreview(nsGlobalWindow* aWindow,
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p : mWidth=%d, mHeight=%d, mFramesPerSecond=%d\n", __func__, __LINE__, this, mWidth, mHeight, mFramesPerSecond);
|
||||
|
||||
mImageContainer = LayerManager::CreateImageContainer();
|
||||
MediaStreamGraph* gm = MediaStreamGraph::GetInstance();
|
||||
mStream = gm->CreateSourceStream(this);
|
||||
mWindow = aWindow;
|
||||
mInput = GetStream()->AsSourceStream();
|
||||
mInput = new CameraPreviewMediaStream(this);
|
||||
mStream = mInput;
|
||||
|
||||
mListener = new DOMCameraPreviewListener(this);
|
||||
mInput->AddListener(mListener);
|
||||
|
||||
mInput->AddTrack(TRACK_VIDEO, mFramesPerSecond, 0, new VideoSegment());
|
||||
mInput->AdvanceKnownTracksTime(MEDIA_TIME_MAX);
|
||||
|
||||
if (aWindow->GetExtantDoc()) {
|
||||
CombineWithPrincipal(aWindow->GetExtantDoc()->NodePrincipal());
|
||||
}
|
||||
@ -180,7 +176,7 @@ DOMCameraPreview::~DOMCameraPreview()
|
||||
bool
|
||||
DOMCameraPreview::HaveEnoughBuffered()
|
||||
{
|
||||
return mInput->HaveEnoughBuffered(TRACK_VIDEO);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -198,9 +194,7 @@ DOMCameraPreview::ReceiveFrame(void* aBuffer, ImageFormat aFormat, FrameBuilder
|
||||
nsRefPtr<Image> image = mImageContainer->CreateImage(&format, 1);
|
||||
aBuilder(image, aBuffer, mWidth, mHeight);
|
||||
|
||||
// AppendFrame() takes over image's reference
|
||||
mVideoSegment.AppendFrame(image.forget(), 1, gfxIntSize(mWidth, mHeight));
|
||||
mInput->AppendToTrack(TRACK_VIDEO, &mVideoSegment);
|
||||
mInput->SetCurrentFrame(gfxIntSize(mWidth, mHeight), image);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -261,8 +255,8 @@ DOMCameraPreview::StopPreview()
|
||||
DOM_CAMERA_LOGI("Stopping preview stream\n");
|
||||
DOM_CAMERA_SETSTATE(STOPPING);
|
||||
mCameraControl->StopPreview();
|
||||
mInput->EndTrack(TRACK_VIDEO);
|
||||
mInput->Finish();
|
||||
//mInput->EndTrack(TRACK_VIDEO);
|
||||
//mInput->Finish();
|
||||
}
|
||||
|
||||
void
|
||||
@ -272,8 +266,8 @@ DOMCameraPreview::SetStateStopped()
|
||||
|
||||
// see bug 809259 and bug 817367.
|
||||
if (mState != STOPPING) {
|
||||
mInput->EndTrack(TRACK_VIDEO);
|
||||
mInput->Finish();
|
||||
//mInput->EndTrack(TRACK_VIDEO);
|
||||
//mInput->Finish();
|
||||
}
|
||||
DOM_CAMERA_SETSTATE(STOPPED);
|
||||
DOM_CAMERA_LOGI("Preview stream stopped\n");
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "StreamBuffer.h"
|
||||
#include "ICameraControl.h"
|
||||
#include "DOMMediaStream.h"
|
||||
#include "CameraPreviewMediaStream.h"
|
||||
#include "CameraCommon.h"
|
||||
|
||||
class nsGlobalWindow;
|
||||
@ -77,7 +78,7 @@ protected:
|
||||
uint32_t mWidth;
|
||||
uint32_t mHeight;
|
||||
uint32_t mFramesPerSecond;
|
||||
SourceMediaStream* mInput;
|
||||
CameraPreviewMediaStream* mInput;
|
||||
nsRefPtr<mozilla::layers::ImageContainer> mImageContainer;
|
||||
VideoSegment mVideoSegment;
|
||||
uint32_t mFrameCount;
|
||||
|
@ -23,6 +23,7 @@ CPPSRCS = \
|
||||
DOMCameraCapabilities.cpp \
|
||||
CameraControlImpl.cpp \
|
||||
CameraRecorderProfiles.cpp \
|
||||
CameraPreviewMediaStream.cpp \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(MOZ_B2G_CAMERA),1)
|
||||
|
Loading…
Reference in New Issue
Block a user