author | Timothy B. Terriberry <tterribe@vt.edu> |
Tue, 27 Nov 2012 16:15:55 -0800 (2012-11-28) | |
changeset 114306 | d9634ee8c1cc2aeedecef274a4d3d36585da886d |
parent 114305 | c8766443985c6c82b3f35253bad3fb0a8d55dbfd |
child 114307 | db5b030c100a1a92dbe74cf1fc0d8579b6187259 |
push id | 18681 |
push user | tterriberry@mozilla.com |
push date | Wed, 28 Nov 2012 00:23:43 +0000 (2012-11-28) |
treeherder | mozilla-inbound@d9634ee8c1cc [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jesup |
bugs | 815825 |
milestone | 20.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
content/media/webrtc/MediaEngineDefault.cpp | file | annotate | diff | comparison | revisions | |
content/media/webrtc/MediaEngineDefault.h | file | annotate | diff | comparison | revisions |
--- a/content/media/webrtc/MediaEngineDefault.cpp +++ b/content/media/webrtc/MediaEngineDefault.cpp @@ -80,16 +80,49 @@ MediaEngineDefaultVideoSource::Deallocat } const MediaEngineVideoOptions * MediaEngineDefaultVideoSource::GetOptions() { return &mOpts; } +static void AllocateSolidColorFrame(layers::PlanarYCbCrImage::Data& aData, + int aWidth, int aHeight, + int aY, int aCb, int aCr) +{ + MOZ_ASSERT(!(aWidth&1)); + MOZ_ASSERT(!(aHeight&1)); + // Allocate a single frame with a solid color + int yLen = aWidth*aHeight; + int cbLen = yLen>>2; + int crLen = cbLen; + uint8_t* frame = (uint8_t*) PR_Malloc(yLen+cbLen+crLen); + memset(frame, aY, yLen); + memset(frame+yLen, aCb, cbLen); + memset(frame+yLen+cbLen, aCr, crLen); + + aData.mYChannel = frame; + aData.mYSize = gfxIntSize(aWidth, aHeight); + aData.mYStride = aWidth; + aData.mCbCrStride = aWidth>>1; + aData.mCbChannel = frame + yLen; + aData.mCrChannel = aData.mCbChannel + cbLen; + aData.mCbCrSize = gfxIntSize(aWidth>>1, aHeight>>1); + aData.mPicX = 0; + aData.mPicY = 0; + aData.mPicSize = gfxIntSize(aWidth, aHeight); + aData.mStereoMode = STEREO_MODE_MONO; +} + +static void ReleaseFrame(layers::PlanarYCbCrImage::Data& aData) +{ + PR_Free(aData.mYChannel); +} + nsresult MediaEngineDefaultVideoSource::Start(SourceMediaStream* aStream, TrackID aID) { if (mState != kAllocated) { return NS_ERROR_FAILURE; } mTimer = do_CreateInstance(NS_TIMER_CONTRACTID); @@ -99,41 +132,26 @@ MediaEngineDefaultVideoSource::Start(Sou mSource = aStream; // Allocate a single blank Image ImageFormat format = PLANAR_YCBCR; mImageContainer = layers::LayerManager::CreateImageContainer(); nsRefPtr<layers::Image> image = mImageContainer->CreateImage(&format, 1); - - int len = ((DEFAULT_WIDTH * DEFAULT_HEIGHT) * 3 / 2); mImage = static_cast<layers::PlanarYCbCrImage*>(image.get()); - uint8_t* frame = (uint8_t*) PR_Malloc(len); - memset(frame, 0x80, len); // Gray - - const uint8_t lumaBpp = 8; - const uint8_t chromaBpp = 4; layers::PlanarYCbCrImage::Data data; - data.mYChannel = frame; - data.mYSize = gfxIntSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); - data.mYStride = DEFAULT_WIDTH * lumaBpp / 8.0; - data.mCbCrStride = DEFAULT_WIDTH * chromaBpp / 8.0; - data.mCbChannel = frame + DEFAULT_HEIGHT * data.mYStride; - data.mCrChannel = data.mCbChannel + DEFAULT_HEIGHT * data.mCbCrStride / 2; - data.mCbCrSize = gfxIntSize(DEFAULT_WIDTH / 2, DEFAULT_HEIGHT / 2); - data.mPicX = 0; - data.mPicY = 0; - data.mPicSize = gfxIntSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); - data.mStereoMode = STEREO_MODE_MONO; - + // Allocate a single blank Image + mCb = 16; + mCr = 16; + AllocateSolidColorFrame(data, DEFAULT_WIDTH, DEFAULT_HEIGHT, 0x80, mCb, mCr); // SetData copies data, so we can free the frame mImage->SetData(data); - PR_Free(frame); + ReleaseFrame(data); // AddTrack takes ownership of segment VideoSegment *segment = new VideoSegment(); segment->AppendFrame(image.forget(), USECS_PER_S / DEFAULT_FPS, gfxIntSize(DEFAULT_WIDTH, DEFAULT_HEIGHT)); mSource->AddTrack(aID, VIDEO_RATE, 0, segment); // We aren't going to add any more tracks mSource->AdvanceKnownTracksTime(STREAM_TIME_MAX); @@ -190,20 +208,53 @@ MediaEngineDefaultVideoSource::Snapshot( NS_ADDREF(*aFile = new nsDOMFileFile(file)); return NS_OK; #endif } NS_IMETHODIMP MediaEngineDefaultVideoSource::Notify(nsITimer* aTimer) { - VideoSegment segment; + // Update the target color + if (mCr <= 16) { + if (mCb < 240) { + mCb++; + } else { + mCr++; + } + } else if (mCb >= 240) { + if (mCr < 240) { + mCr++; + } else { + mCb--; + } + } else if (mCr >= 240) { + if (mCb > 16) { + mCb--; + } else { + mCr--; + } + } else { + mCr--; + } - nsRefPtr<layers::PlanarYCbCrImage> image = mImage; - segment.AppendFrame(image.forget(), USECS_PER_S / DEFAULT_FPS, gfxIntSize(DEFAULT_WIDTH, DEFAULT_HEIGHT)); + // Allocate a single solid color image + ImageFormat format = PLANAR_YCBCR; + nsRefPtr<layers::Image> image = mImageContainer->CreateImage(&format, 1); + nsRefPtr<layers::PlanarYCbCrImage> ycbcr_image = + static_cast<layers::PlanarYCbCrImage*>(image.get()); + layers::PlanarYCbCrImage::Data data; + AllocateSolidColorFrame(data, DEFAULT_WIDTH, DEFAULT_HEIGHT, 0x80, mCb, mCr); + ycbcr_image->SetData(data); + // SetData copies data, so we can free the frame + ReleaseFrame(data); + + // AddTrack takes ownership of segment + VideoSegment segment; + segment.AppendFrame(ycbcr_image.forget(), USECS_PER_S / DEFAULT_FPS, gfxIntSize(DEFAULT_WIDTH, DEFAULT_HEIGHT)); mSource->AppendToTrack(mTrackID, &segment); return NS_OK; } void MediaEngineDefaultVideoSource::NotifyPull(MediaStreamGraph* aGraph, StreamTime aDesiredTime)
--- a/content/media/webrtc/MediaEngineDefault.h +++ b/content/media/webrtc/MediaEngineDefault.h @@ -58,16 +58,18 @@ public: protected: TrackID mTrackID; nsCOMPtr<nsITimer> mTimer; nsRefPtr<layers::ImageContainer> mImageContainer; SourceMediaStream* mSource; layers::PlanarYCbCrImage* mImage; static const MediaEngineVideoOptions mOpts; + int mCb; + int mCr; }; class MediaEngineDefaultAudioSource : public nsITimerCallback, public MediaEngineAudioSource { public: MediaEngineDefaultAudioSource(); ~MediaEngineDefaultAudioSource();