mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 752351: Implement fallback media engine; r=jesup
This commit is contained in:
parent
d10bc8a30b
commit
cc12330ae4
@ -22,6 +22,7 @@ EXPORTS = \
|
||||
AudioSegment.h \
|
||||
FileBlockCache.h \
|
||||
MediaEngine.h \
|
||||
MediaEngineDefault.h \
|
||||
MediaResource.h \
|
||||
MediaSegment.h \
|
||||
MediaStreamGraph.h \
|
||||
@ -43,6 +44,7 @@ EXPORTS = \
|
||||
CPPSRCS = \
|
||||
AudioSegment.cpp \
|
||||
FileBlockCache.cpp \
|
||||
MediaEngineDefault.cpp \
|
||||
MediaResource.cpp \
|
||||
MediaStreamGraph.cpp \
|
||||
nsAudioAvailableEventManager.cpp \
|
||||
|
288
content/media/MediaEngineDefault.cpp
Normal file
288
content/media/MediaEngineDefault.cpp
Normal file
@ -0,0 +1,288 @@
|
||||
/* 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 "MediaEngineDefault.h"
|
||||
|
||||
#define WIDTH 320
|
||||
#define HEIGHT 240
|
||||
#define FPS 10
|
||||
#define CHANNELS 1
|
||||
#define RATE USECS_PER_S
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(MediaEngineDefaultVideoSource, nsITimerCallback)
|
||||
/**
|
||||
* Default video source.
|
||||
*/
|
||||
void
|
||||
MediaEngineDefaultVideoSource::GetName(nsAString& aName)
|
||||
{
|
||||
aName.Assign(NS_LITERAL_STRING("Default Video Device"));
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
MediaEngineDefaultVideoSource::GetUUID(nsAString& aUUID)
|
||||
{
|
||||
aUUID.Assign(NS_LITERAL_STRING("1041FCBD-3F12-4F7B-9E9B-1EC556DD5676"));
|
||||
return;
|
||||
}
|
||||
|
||||
already_AddRefed<nsDOMMediaStream>
|
||||
MediaEngineDefaultVideoSource::Allocate()
|
||||
{
|
||||
if (mState != kReleased) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mState = kAllocated;
|
||||
return nsDOMMediaStream::CreateInputStream();
|
||||
}
|
||||
|
||||
nsresult
|
||||
MediaEngineDefaultVideoSource::Deallocate()
|
||||
{
|
||||
if (mState != kStopped && mState != kAllocated) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mState = kReleased;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
MediaEngineVideoOptions
|
||||
MediaEngineDefaultVideoSource::GetOptions()
|
||||
{
|
||||
MediaEngineVideoOptions aOpts;
|
||||
aOpts.mWidth = WIDTH;
|
||||
aOpts.mHeight = HEIGHT;
|
||||
aOpts.mMaxFPS = FPS;
|
||||
aOpts.codecType = kVideoCodecI420;
|
||||
return aOpts;
|
||||
}
|
||||
|
||||
nsresult
|
||||
MediaEngineDefaultVideoSource::Start(SourceMediaStream* aStream, TrackID aID)
|
||||
{
|
||||
if (mState != kAllocated) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
|
||||
if (!mTimer) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mSource = aStream;
|
||||
|
||||
// Allocate a single blank Image
|
||||
layers::Image::Format format = layers::Image::PLANAR_YCBCR;
|
||||
mImageContainer = layers::LayerManager::CreateImageContainer();
|
||||
|
||||
nsRefPtr<layers::Image> image = mImageContainer->CreateImage(&format, 1);
|
||||
|
||||
int len = ((WIDTH * HEIGHT) * 3 / 2);
|
||||
mImage = static_cast<layers::PlanarYCbCrImage*>(image.get());
|
||||
PRUint8* frame = (PRUint8*) PR_Malloc(len);
|
||||
memset(frame, 0x80, len); // Gray
|
||||
|
||||
const PRUint8 lumaBpp = 8;
|
||||
const PRUint8 chromaBpp = 4;
|
||||
|
||||
layers::PlanarYCbCrImage::Data data;
|
||||
data.mYChannel = frame;
|
||||
data.mYSize = gfxIntSize(WIDTH, HEIGHT);
|
||||
data.mYStride = WIDTH * lumaBpp / 8.0;
|
||||
data.mCbCrStride = WIDTH * chromaBpp / 8.0;
|
||||
data.mCbChannel = frame + HEIGHT * data.mYStride;
|
||||
data.mCrChannel = data.mCbChannel + HEIGHT * data.mCbCrStride / 2;
|
||||
data.mCbCrSize = gfxIntSize(WIDTH / 2, HEIGHT / 2);
|
||||
data.mPicX = 0;
|
||||
data.mPicY = 0;
|
||||
data.mPicSize = gfxIntSize(WIDTH, HEIGHT);
|
||||
data.mStereoMode = layers::STEREO_MODE_MONO;
|
||||
|
||||
// SetData copies data, so we can free the frame
|
||||
mImage->SetData(data);
|
||||
PR_Free(frame);
|
||||
|
||||
|
||||
// AddTrack takes ownership of segment
|
||||
VideoSegment *segment = new VideoSegment();
|
||||
segment->AppendFrame(image.forget(), USECS_PER_S / FPS, gfxIntSize(WIDTH, HEIGHT));
|
||||
mSource->AddTrack(aID, RATE, 0, segment);
|
||||
|
||||
// We aren't going to add any more tracks
|
||||
mSource->AdvanceKnownTracksTime(STREAM_TIME_MAX);
|
||||
|
||||
// Remember TrackID so we can end it later
|
||||
mTrackID = aID;
|
||||
|
||||
// Start timer for subsequent frames
|
||||
mTimer->InitWithCallback(this, 1000 / FPS, nsITimer::TYPE_REPEATING_SLACK);
|
||||
mState = kStarted;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
MediaEngineDefaultVideoSource::Stop()
|
||||
{
|
||||
if (mState != kStarted) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (!mTimer) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mTimer->Cancel();
|
||||
mTimer = NULL;
|
||||
|
||||
mSource->EndTrack(mTrackID);
|
||||
mSource->Finish();
|
||||
|
||||
mState = kStopped;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
MediaEngineDefaultVideoSource::Snapshot(PRUint32 aDuration, nsIDOMFile** aFile)
|
||||
{
|
||||
*aFile = nsnull;
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MediaEngineDefaultVideoSource::Notify(nsITimer* aTimer)
|
||||
{
|
||||
VideoSegment segment;
|
||||
|
||||
nsRefPtr<layers::PlanarYCbCrImage> image = mImage;
|
||||
segment.AppendFrame(image.forget(), USECS_PER_S / FPS, gfxIntSize(WIDTH, HEIGHT));
|
||||
mSource->AppendToTrack(mTrackID, &segment);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(MediaEngineDefaultAudioSource, nsITimerCallback)
|
||||
/**
|
||||
* Default audio source.
|
||||
*/
|
||||
void
|
||||
MediaEngineDefaultAudioSource::GetName(nsAString& aName)
|
||||
{
|
||||
aName.Assign(NS_LITERAL_STRING("Default Audio Device"));
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
MediaEngineDefaultAudioSource::GetUUID(nsAString& aUUID)
|
||||
{
|
||||
aUUID.Assign(NS_LITERAL_STRING("B7CBD7C1-53EF-42F9-8353-73F61C70C092"));
|
||||
return;
|
||||
}
|
||||
|
||||
already_AddRefed<nsDOMMediaStream>
|
||||
MediaEngineDefaultAudioSource::Allocate()
|
||||
{
|
||||
if (mState != kReleased) {
|
||||
return NULL;
|
||||
}
|
||||
mState = kAllocated;
|
||||
return nsDOMMediaStream::CreateInputStream();
|
||||
}
|
||||
|
||||
nsresult
|
||||
MediaEngineDefaultAudioSource::Deallocate()
|
||||
{
|
||||
if (mState != kStopped && mState != kAllocated) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mState = kReleased;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
MediaEngineDefaultAudioSource::Start(SourceMediaStream* aStream, TrackID aID)
|
||||
{
|
||||
if (mState != kAllocated) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
|
||||
if (!mTimer) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mSource = aStream;
|
||||
|
||||
// AddTrack will take ownership of segment
|
||||
AudioSegment* segment = new AudioSegment();
|
||||
segment->Init(CHANNELS);
|
||||
mSource->AddTrack(aID, RATE, 0, segment);
|
||||
|
||||
// We aren't going to add any more tracks
|
||||
mSource->AdvanceKnownTracksTime(STREAM_TIME_MAX);
|
||||
|
||||
// Remember TrackID so we can finish later
|
||||
mTrackID = aID;
|
||||
|
||||
// 1 Audio frame per Video frame
|
||||
mTimer->InitWithCallback(this, 1000 / FPS, nsITimer::TYPE_REPEATING_SLACK);
|
||||
mState = kStarted;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
MediaEngineDefaultAudioSource::Stop()
|
||||
{
|
||||
if (mState != kStarted) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (!mTimer) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mTimer->Cancel();
|
||||
mTimer = NULL;
|
||||
|
||||
mSource->EndTrack(mTrackID);
|
||||
mSource->Finish();
|
||||
|
||||
mState = kStopped;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
MediaEngineDefaultAudioSource::Snapshot(PRUint32 aDuration, nsIDOMFile** aFile)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MediaEngineDefaultAudioSource::Notify(nsITimer* aTimer)
|
||||
{
|
||||
AudioSegment segment;
|
||||
segment.Init(CHANNELS);
|
||||
segment.InsertNullDataAtStart(1);
|
||||
|
||||
mSource->AppendToTrack(mTrackID, &segment);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
MediaEngineDefault::EnumerateVideoDevices(nsTArray<nsRefPtr<MediaEngineVideoSource> >* aVSources) {
|
||||
aVSources->AppendElement(mVSource);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
MediaEngineDefault::EnumerateAudioDevices(nsTArray<nsRefPtr<MediaEngineAudioSource> >* aASources) {
|
||||
aASources->AppendElement(mASource);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
115
content/media/MediaEngineDefault.h
Normal file
115
content/media/MediaEngineDefault.h
Normal file
@ -0,0 +1,115 @@
|
||||
/* 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 MEDIAENGINEDEFAULT_H_
|
||||
#define MEDIAENGINEDEFAULT_H_
|
||||
|
||||
#include "prmem.h"
|
||||
#include "nsITimer.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsDOMMediaStream.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
|
||||
#include "Layers.h"
|
||||
#include "VideoUtils.h"
|
||||
#include "MediaEngine.h"
|
||||
#include "ImageLayers.h"
|
||||
#include "VideoSegment.h"
|
||||
#include "AudioSegment.h"
|
||||
#include "StreamBuffer.h"
|
||||
#include "MediaStreamGraph.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
/**
|
||||
* The default implementation of the MediaEngine interface.
|
||||
*/
|
||||
|
||||
enum DefaultEngineState {
|
||||
kAllocated,
|
||||
kStarted,
|
||||
kStopped,
|
||||
kReleased
|
||||
};
|
||||
|
||||
class MediaEngineDefaultVideoSource : public nsITimerCallback,
|
||||
public MediaEngineVideoSource
|
||||
{
|
||||
public:
|
||||
MediaEngineDefaultVideoSource() : mTimer(nsnull), mState(kReleased) {}
|
||||
~MediaEngineDefaultVideoSource(){};
|
||||
|
||||
virtual void GetName(nsAString&);
|
||||
virtual void GetUUID(nsAString&);
|
||||
|
||||
virtual MediaEngineVideoOptions GetOptions();
|
||||
virtual already_AddRefed<nsDOMMediaStream> Allocate();
|
||||
|
||||
virtual nsresult Deallocate();
|
||||
virtual nsresult Start(SourceMediaStream*, TrackID);
|
||||
virtual nsresult Stop();
|
||||
virtual nsresult Snapshot(PRUint32 aDuration, nsIDOMFile** aFile);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSITIMERCALLBACK
|
||||
|
||||
protected:
|
||||
TrackID mTrackID;
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
nsRefPtr<layers::ImageContainer> mImageContainer;
|
||||
|
||||
DefaultEngineState mState;
|
||||
SourceMediaStream* mSource;
|
||||
layers::PlanarYCbCrImage* mImage;
|
||||
};
|
||||
|
||||
class MediaEngineDefaultAudioSource : public nsITimerCallback,
|
||||
public MediaEngineAudioSource
|
||||
{
|
||||
public:
|
||||
MediaEngineDefaultAudioSource() : mTimer(nsnull), mState(kReleased) {}
|
||||
~MediaEngineDefaultAudioSource(){};
|
||||
|
||||
virtual void GetName(nsAString&);
|
||||
virtual void GetUUID(nsAString&);
|
||||
|
||||
virtual already_AddRefed<nsDOMMediaStream> Allocate();
|
||||
|
||||
virtual nsresult Deallocate();
|
||||
virtual nsresult Start(SourceMediaStream*, TrackID);
|
||||
virtual nsresult Stop();
|
||||
virtual nsresult Snapshot(PRUint32 aDuration, nsIDOMFile** aFile);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSITIMERCALLBACK
|
||||
|
||||
protected:
|
||||
TrackID mTrackID;
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
|
||||
DefaultEngineState mState;
|
||||
SourceMediaStream* mSource;
|
||||
};
|
||||
|
||||
class MediaEngineDefault : public MediaEngine
|
||||
{
|
||||
public:
|
||||
MediaEngineDefault() {
|
||||
mVSource = new MediaEngineDefaultVideoSource();
|
||||
mASource = new MediaEngineDefaultAudioSource();
|
||||
}
|
||||
~MediaEngineDefault() {}
|
||||
|
||||
virtual void EnumerateVideoDevices(nsTArray<nsRefPtr<MediaEngineVideoSource> >*);
|
||||
virtual void EnumerateAudioDevices(nsTArray<nsRefPtr<MediaEngineAudioSource> >*);
|
||||
|
||||
private:
|
||||
nsRefPtr<MediaEngineVideoSource> mVSource;
|
||||
nsRefPtr<MediaEngineAudioSource> mASource;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* NSMEDIAENGINEDEFAULT_H_ */
|
Loading…
Reference in New Issue
Block a user