michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef FAKE_MEDIA_STREAMIMPL_H_ michael@0: #define FAKE_MEDIA_STREAMIMPL_H_ michael@0: michael@0: #include "FakeMediaStreams.h" michael@0: michael@0: #include "nspr.h" michael@0: #include "nsError.h" michael@0: michael@0: void LogTime(AsyncLatencyLogger::LatencyLogIndex index, uint64_t b, int64_t c) {} michael@0: void LogLatency(AsyncLatencyLogger::LatencyLogIndex index, uint64_t b, int64_t c) {} michael@0: michael@0: static const int AUDIO_BUFFER_SIZE = 1600; michael@0: static const int NUM_CHANNELS = 2; michael@0: michael@0: NS_IMPL_ISUPPORTS(Fake_DOMMediaStream, nsIDOMMediaStream) michael@0: michael@0: // Fake_SourceMediaStream michael@0: nsresult Fake_SourceMediaStream::Start() { michael@0: mTimer = do_CreateInstance(NS_TIMER_CONTRACTID); michael@0: if (!mTimer) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: mTimer->InitWithCallback(mPeriodic, 100, nsITimer::TYPE_REPEATING_SLACK); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult Fake_SourceMediaStream::Stop() { michael@0: mozilla::MutexAutoLock lock(mMutex); michael@0: if (mTimer) michael@0: mTimer->Cancel(); michael@0: mPeriodic->Detach(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: void Fake_SourceMediaStream::Periodic() { michael@0: mozilla::MutexAutoLock lock(mMutex); michael@0: // Pull more audio-samples iff pulling is enabled michael@0: // and we are not asked by the signaling agent to stop michael@0: //pulling data. michael@0: if (mPullEnabled && !mStop) { michael@0: for (std::set::iterator it = michael@0: mListeners.begin(); it != mListeners.end(); ++it) { michael@0: mDesiredTime += 10; michael@0: (*it)->NotifyPull(nullptr, mozilla::MillisecondsToMediaTime(mDesiredTime)); michael@0: } michael@0: } michael@0: } michael@0: michael@0: // Fake_MediaStreamBase michael@0: nsresult Fake_MediaStreamBase::Start() { michael@0: mTimer = do_CreateInstance(NS_TIMER_CONTRACTID); michael@0: if (!mTimer) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: mTimer->InitWithCallback(mPeriodic, 100, nsITimer::TYPE_REPEATING_SLACK); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult Fake_MediaStreamBase::Stop() { michael@0: // Lock the mutex so that we know that after this michael@0: // has returned, periodic will not be firing again michael@0: // and so it's safe to destruct. michael@0: mozilla::MutexAutoLock lock(mMutex); michael@0: mTimer->Cancel(); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: // Fake_AudioStreamSource michael@0: void Fake_AudioStreamSource::Periodic() { michael@0: mozilla::MutexAutoLock lock(mMutex); michael@0: //Are we asked to stop pumping audio samples ? michael@0: if(mStop) { michael@0: return; michael@0: } michael@0: //Generate Signed 16 Bit Audio samples michael@0: nsRefPtr samples = michael@0: mozilla::SharedBuffer::Create(AUDIO_BUFFER_SIZE * NUM_CHANNELS * sizeof(int16_t)); michael@0: int16_t* data = reinterpret_cast(samples->Data()); michael@0: for(int i=0; i<(1600*2); i++) { michael@0: //saw tooth audio sample michael@0: data[i] = ((mCount % 8) * 4000) - (7*4000)/2; michael@0: mCount++; michael@0: } michael@0: michael@0: mozilla::AudioSegment segment; michael@0: nsAutoTArray channels; michael@0: channels.AppendElement(data); michael@0: segment.AppendFrames(samples.forget(), channels, AUDIO_BUFFER_SIZE); michael@0: michael@0: for(std::set::iterator it = mListeners.begin(); michael@0: it != mListeners.end(); ++it) { michael@0: (*it)->NotifyQueuedTrackChanges(nullptr, // Graph michael@0: 0, // TrackID michael@0: 16000, // Rate (hz) michael@0: 0, // Offset TODO(ekr@rtfm.com) fix michael@0: 0, // ??? michael@0: segment); michael@0: } michael@0: } michael@0: michael@0: michael@0: // Fake_MediaPeriodic michael@0: NS_IMPL_ISUPPORTS(Fake_MediaPeriodic, nsITimerCallback) michael@0: michael@0: NS_IMETHODIMP michael@0: Fake_MediaPeriodic::Notify(nsITimer *timer) { michael@0: if (mStream) michael@0: mStream->Periodic(); michael@0: ++mCount; michael@0: return NS_OK; michael@0: } michael@0: michael@0: michael@0: #if 0 michael@0: #define WIDTH 320 michael@0: #define HEIGHT 240 michael@0: #define RATE USECS_PER_S michael@0: #define USECS_PER_S 1000000 michael@0: #define FPS 10 michael@0: michael@0: NS_IMETHODIMP michael@0: Fake_VideoStreamSource::Notify(nsITimer* aTimer) michael@0: { michael@0: #if 0 michael@0: mozilla::layers::BufferRecycleBin bin; michael@0: michael@0: nsRefPtr image = new michael@0: mozilla::layers::PlanarYCbCrImage(&bin); michael@0: michael@0: const uint8_t lumaBpp = 8; michael@0: const uint8_t chromaBpp = 4; michael@0: michael@0: int len = ((WIDTH * HEIGHT) * 3 / 2); michael@0: uint8_t* frame = (uint8_t*) PR_Malloc(len); michael@0: memset(frame, 0x80, len); // Gray michael@0: michael@0: mozilla::layers::PlanarYCbCrData data; michael@0: data.mYChannel = frame; michael@0: data.mYSize = gfxIntSize(WIDTH, HEIGHT); michael@0: data.mYStride = WIDTH * lumaBpp / 8.0; michael@0: data.mCbCrStride = WIDTH * chromaBpp / 8.0; michael@0: data.mCbChannel = frame + HEIGHT * data.mYStride; michael@0: data.mCrChannel = data.mCbChannel + HEIGHT * data.mCbCrStride / 2; michael@0: data.mCbCrSize = gfxIntSize(WIDTH / 2, HEIGHT / 2); michael@0: data.mPicX = 0; michael@0: data.mPicY = 0; michael@0: data.mPicSize = gfxIntSize(WIDTH, HEIGHT); michael@0: data.mStereoMode = mozilla::layers::StereoMode::MONO; michael@0: michael@0: mozilla::VideoSegment segment; michael@0: segment.AppendFrame(image.forget(), USECS_PER_S / FPS, gfxIntSize(WIDTH, HEIGHT)); michael@0: michael@0: // TODO(ekr@rtfm.com): are we leaking? michael@0: #endif michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: michael@0: #if 0 michael@0: // Fake up buffer recycle bin michael@0: mozilla::layers::BufferRecycleBin::BufferRecycleBin() : michael@0: mLock("mozilla.layers.BufferRecycleBin.mLock") { michael@0: } michael@0: michael@0: void mozilla::layers::BufferRecycleBin::RecycleBuffer(uint8_t* buffer, uint32_t size) { michael@0: PR_Free(buffer); michael@0: } michael@0: michael@0: uint8_t *mozilla::layers::BufferRecycleBin::GetBuffer(uint32_t size) { michael@0: return (uint8_t *)PR_MALLOC(size); michael@0: } michael@0: michael@0: // YCbCrImage constructor (from ImageLayers.cpp) michael@0: mozilla::layers::PlanarYCbCrImage::PlanarYCbCrImage(BufferRecycleBin *aRecycleBin) michael@0: : Image(nsnull, ImageFormat::PLANAR_YCBCR) michael@0: , mBufferSize(0) michael@0: , mRecycleBin(aRecycleBin) michael@0: { michael@0: } michael@0: michael@0: michael@0: #endif michael@0: #endif michael@0: michael@0: michael@0: #endif