Bug 1201363 - MediaStreamVideoSink for MediaRecorder case. r=jesup

Add MediaStreamVideoRecorderSink into MediaEncorder. In this patch, I still keep use duration to pass to TrackEncoders. Don't want to make this bug too big and out of control. We can file a new bug to change TrackEncoders use TimeStamp only.

MozReview-Commit-ID: KGftzulZynj

--HG--
extra : amend_source : 90fd7ddab4ecda4b95cd77c705cfb29692782de9
This commit is contained in:
Chia-hung Tai 2016-06-15 16:48:44 +01:00
Родитель 3d269ad415
Коммит 7d3f0cf614
11 изменённых файлов: 197 добавлений и 95 удалений

Просмотреть файл

@ -295,8 +295,10 @@ class MediaRecorder::Session: public nsIObserver,
class TracksAvailableCallback : public OnTracksAvailableCallback
{
public:
explicit TracksAvailableCallback(Session *aSession)
: mSession(aSession) {}
explicit TracksAvailableCallback(Session *aSession, TrackRate aTrackRate)
: mSession(aSession)
, mTrackRate(aTrackRate) {}
virtual void NotifyTracksAvailable(DOMMediaStream* aStream)
{
if (mSession->mStopIssued) {
@ -347,10 +349,11 @@ class MediaRecorder::Session: public nsIObserver,
}
LOG(LogLevel::Debug, ("Session.NotifyTracksAvailable track type = (%d)", trackTypes));
mSession->InitEncoder(trackTypes);
mSession->InitEncoder(trackTypes, mTrackRate);
}
private:
RefPtr<Session> mSession;
TrackRate mTrackRate;
};
// Main thread task.
// To delete RecordingSession object.
@ -412,6 +415,7 @@ public:
, mIsStartEventFired(false)
, mIsRegisterProfiler(false)
, mNeedSessionEndTask(true)
, mSelectedVideoTrackID(TRACK_NONE)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_COUNT_CTOR(MediaRecorder::Session);
@ -467,6 +471,7 @@ public:
// Create a Track Union Stream
MediaStreamGraph* gm = mRecorder->GetSourceMediaStream()->Graph();
TrackRate trackRate = gm->GraphRate();
mTrackUnionStream = gm->CreateTrackUnionStream();
MOZ_ASSERT(mTrackUnionStream, "CreateTrackUnionStream failed");
@ -477,7 +482,7 @@ public:
// Get the available tracks from the DOMMediaStream.
// The callback will report back tracks that we have to connect to
// mTrackUnionStream and listen to principal changes on.
TracksAvailableCallback* tracksAvailableCallback = new TracksAvailableCallback(this);
TracksAvailableCallback* tracksAvailableCallback = new TracksAvailableCallback(this, trackRate);
domStream->OnTracksAvailable(tracksAvailableCallback);
} else {
// Check that we may access the audio node's content.
@ -493,7 +498,7 @@ public:
MOZ_ASSERT(mInputPorts[mInputPorts.Length()-1]);
// Web Audio node has only audio.
InitEncoder(ContainerWriter::CREATE_AUDIO_TRACK);
InitEncoder(ContainerWriter::CREATE_AUDIO_TRACK, trackRate);
}
}
@ -734,7 +739,7 @@ private:
return perm == nsIPermissionManager::ALLOW_ACTION;
}
void InitEncoder(uint8_t aTrackTypes)
void InitEncoder(uint8_t aTrackTypes, TrackRate aTrackRate)
{
LOG(LogLevel::Debug, ("Session.InitEncoder %p", this));
MOZ_ASSERT(NS_IsMainThread());
@ -752,19 +757,19 @@ private:
mRecorder->GetAudioBitrate(),
mRecorder->GetVideoBitrate(),
mRecorder->GetBitrate(),
aTrackTypes);
aTrackTypes, aTrackRate);
} else if (mRecorder->mMimeType.EqualsLiteral(AUDIO_3GPP2) && CheckPermission("audio-capture:3gpp2")) {
mEncoder = MediaEncoder::CreateEncoder(NS_LITERAL_STRING(AUDIO_3GPP2),
mRecorder->GetAudioBitrate(),
mRecorder->GetVideoBitrate(),
mRecorder->GetBitrate(),
aTrackTypes);
aTrackTypes, aTrackRate);
} else {
mEncoder = MediaEncoder::CreateEncoder(NS_LITERAL_STRING(""),
mRecorder->GetAudioBitrate(),
mRecorder->GetVideoBitrate(),
mRecorder->GetBitrate(),
aTrackTypes);
aTrackTypes, aTrackRate);
}
if (!mEncoder) {
@ -781,13 +786,25 @@ private:
DoSessionEndTask(NS_OK);
return;
}
mTrackUnionStream->AddListener(mEncoder);
// Try to use direct listeners if possible
mTrackUnionStream->AddListener(mEncoder.get());
nsTArray<RefPtr<mozilla::dom::VideoStreamTrack>> videoTracks;
DOMMediaStream* domStream = mRecorder->Stream();
if (domStream) {
domStream->GetVideoTracks(videoTracks);
if (!videoTracks.IsEmpty()) {
// Right now, the MediaRecorder hasn't dealt with multiple video track
// issues. So we just bind with the first video track. Bug 1276928 is
// the following.
videoTracks[0]->AddDirectListener(mEncoder->GetVideoSink());
}
}
// Try to use direct listeners if possible
if (domStream && domStream->GetInputStream()) {
mInputStream = domStream->GetInputStream()->AsSourceStream();
if (mInputStream) {
mInputStream->AddDirectListener(mEncoder);
mInputStream->AddDirectListener(mEncoder.get());
mEncoder->SetDirectConnect(true);
}
}
@ -847,7 +864,7 @@ private:
{
if (mInputStream) {
if (mEncoder) {
mInputStream->RemoveDirectListener(mEncoder);
mInputStream->RemoveDirectListener(mEncoder.get());
}
mInputStream = nullptr;
}
@ -858,8 +875,13 @@ private:
mInputPorts.Clear();
if (mTrackUnionStream) {
// Sometimes the MediaEncoder might be initialized fail and go to
// |CleanupStreams|. So the mEncoder might be a nullptr in this case.
if (mEncoder && mSelectedVideoTrackID != TRACK_NONE) {
mTrackUnionStream->RemoveVideoOutput(mEncoder->GetVideoSink(), mSelectedVideoTrackID);
}
if (mEncoder) {
mTrackUnionStream->RemoveListener(mEncoder);
mTrackUnionStream->RemoveListener(mEncoder.get());
}
mTrackUnionStream->Destroy();
mTrackUnionStream = nullptr;
@ -948,6 +970,7 @@ private:
// ExtractRunnable/DestroyRunnable will end the session.
// Main thread only.
bool mNeedSessionEndTask;
TrackID mSelectedVideoTrackID;
};
NS_IMPL_ISUPPORTS(MediaRecorder::Session, nsIObserver)

Просмотреть файл

@ -33,6 +33,13 @@ mozilla::LazyLogModule gMediaEncoderLog("MediaEncoder");
namespace mozilla {
void
MediaStreamVideoRecorderSink::SetCurrentFrames(const VideoSegment& aSegment)
{
MOZ_ASSERT(mVideoEncoder);
mVideoEncoder->SetCurrentFrames(aSegment);
}
void
MediaEncoder::SetDirectConnect(bool aConnected)
{
@ -53,8 +60,9 @@ MediaEncoder::NotifyRealtimeData(MediaStreamGraph* aGraph,
mAudioEncoder->NotifyQueuedTrackChanges(aGraph, aID,
aTrackOffset, aTrackEvents,
aRealtimeMedia);
} else if (mVideoEncoder && aRealtimeMedia.GetType() == MediaSegment::VIDEO) {
} else if (mVideoEncoder &&
aRealtimeMedia.GetType() == MediaSegment::VIDEO &&
aTrackEvents != TrackEventCommand::TRACK_EVENT_NONE) {
mVideoEncoder->NotifyQueuedTrackChanges(aGraph, aID,
aTrackOffset, aTrackEvents,
aRealtimeMedia);
@ -141,7 +149,8 @@ MediaEncoder::NotifyEvent(MediaStreamGraph* aGraph,
already_AddRefed<MediaEncoder>
MediaEncoder::CreateEncoder(const nsAString& aMIMEType, uint32_t aAudioBitrate,
uint32_t aVideoBitrate, uint32_t aBitrate,
uint8_t aTrackTypes)
uint8_t aTrackTypes,
TrackRate aTrackRate)
{
PROFILER_LABEL("MediaEncoder", "CreateEncoder",
js::ProfileEntry::Category::OTHER);
@ -164,7 +173,7 @@ MediaEncoder::CreateEncoder(const nsAString& aMIMEType, uint32_t aAudioBitrate,
audioEncoder = new OpusTrackEncoder();
NS_ENSURE_TRUE(audioEncoder, nullptr);
}
videoEncoder = new VP8TrackEncoder();
videoEncoder = new VP8TrackEncoder(aTrackRate);
writer = new WebMWriter(aTrackTypes);
NS_ENSURE_TRUE(writer, nullptr);
NS_ENSURE_TRUE(videoEncoder, nullptr);
@ -179,7 +188,7 @@ MediaEncoder::CreateEncoder(const nsAString& aMIMEType, uint32_t aAudioBitrate,
audioEncoder = new OmxAACAudioTrackEncoder();
NS_ENSURE_TRUE(audioEncoder, nullptr);
}
videoEncoder = new OmxVideoTrackEncoder();
videoEncoder = new OmxVideoTrackEncoder(aTrackRate);
writer = new ISOMediaWriter(aTrackTypes);
NS_ENSURE_TRUE(writer, nullptr);
NS_ENSURE_TRUE(videoEncoder, nullptr);

Просмотреть файл

@ -9,15 +9,32 @@
#include "mozilla/DebugOnly.h"
#include "TrackEncoder.h"
#include "ContainerWriter.h"
#include "CubebUtils.h"
#include "MediaStreamGraph.h"
#include "MediaStreamListener.h"
#include "nsAutoPtr.h"
#include "MediaStreamVideoSink.h"
#include "nsIMemoryReporter.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/Atomics.h"
namespace mozilla {
class MediaStreamVideoRecorderSink : public MediaStreamVideoSink
{
public:
explicit MediaStreamVideoRecorderSink(VideoTrackEncoder* aEncoder)
: mVideoEncoder(aEncoder) {}
// MediaStreamVideoSink methods
virtual void SetCurrentFrames(const VideoSegment& aSegment) override;
virtual void ClearFrames() override {}
private:
virtual ~MediaStreamVideoRecorderSink() {}
VideoTrackEncoder* mVideoEncoder;
};
/**
* MediaEncoder is the framework of encoding module, it controls and manages
* procedures between ContainerWriter and TrackEncoder. ContainerWriter packs
@ -54,6 +71,7 @@ namespace mozilla {
*/
class MediaEncoder : public DirectMediaStreamListener
{
friend class MediaStreamVideoRecorderSink;
public :
enum {
ENCODE_METADDATA,
@ -72,6 +90,7 @@ public :
: mWriter(aWriter)
, mAudioEncoder(aAudioEncoder)
, mVideoEncoder(aVideoEncoder)
, mVideoSink(new MediaStreamVideoRecorderSink(mVideoEncoder))
, mStartTime(TimeStamp::Now())
, mMIMEType(aMIMEType)
, mSizeOfBuffer(0)
@ -155,7 +174,8 @@ public :
static already_AddRefed<MediaEncoder> CreateEncoder(const nsAString& aMIMEType,
uint32_t aAudioBitrate, uint32_t aVideoBitrate,
uint32_t aBitrate,
uint8_t aTrackTypes = ContainerWriter::CREATE_AUDIO_TRACK);
uint8_t aTrackTypes = ContainerWriter::CREATE_AUDIO_TRACK,
TrackRate aTrackRate = CubebUtils::PreferredSampleRate());
/**
* Encodes the raw track data and returns the final container data. Assuming
* it is called on a single worker thread. The buffer of container data is
@ -208,6 +228,10 @@ public :
*/
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
MediaStreamVideoRecorderSink* GetVideoSink() {
return mVideoSink.get();
}
private:
// Get encoded data from trackEncoder and write to muxer
nsresult WriteEncodedDataToMuxer(TrackEncoder *aTrackEncoder);
@ -216,6 +240,7 @@ private:
nsAutoPtr<ContainerWriter> mWriter;
nsAutoPtr<AudioTrackEncoder> mAudioEncoder;
nsAutoPtr<VideoTrackEncoder> mVideoEncoder;
RefPtr<MediaStreamVideoRecorderSink> mVideoSink;
TimeStamp mStartTime;
nsString mMIMEType;
int64_t mSizeOfBuffer;

Просмотреть файл

@ -26,8 +26,8 @@ namespace mozilla {
#define ENCODER_CONFIG_FRAME_RATE 30 // fps
#define GET_ENCODED_VIDEO_FRAME_TIMEOUT 100000 // microseconds
OmxVideoTrackEncoder::OmxVideoTrackEncoder()
: VideoTrackEncoder()
OmxVideoTrackEncoder::OmxVideoTrackEncoder(TrackRate aTrackRate)
: VideoTrackEncoder(aTrackRate)
{}
OmxVideoTrackEncoder::~OmxVideoTrackEncoder()
@ -35,11 +35,10 @@ OmxVideoTrackEncoder::~OmxVideoTrackEncoder()
nsresult
OmxVideoTrackEncoder::Init(int aWidth, int aHeight, int aDisplayWidth,
int aDisplayHeight, TrackRate aTrackRate)
int aDisplayHeight)
{
mFrameWidth = aWidth;
mFrameHeight = aHeight;
mTrackRate = aTrackRate;
mDisplayWidth = aDisplayWidth;
mDisplayHeight = aDisplayHeight;

Просмотреть файл

@ -27,7 +27,7 @@ namespace mozilla {
class OmxVideoTrackEncoder: public VideoTrackEncoder
{
public:
OmxVideoTrackEncoder();
explicit OmxVideoTrackEncoder(TrackRate aTrackRate);
~OmxVideoTrackEncoder();
already_AddRefed<TrackMetadataBase> GetMetadata() override;
@ -36,8 +36,7 @@ public:
protected:
nsresult Init(int aWidth, int aHeight,
int aDisplayWidth, int aDisplayHeight,
TrackRate aTrackRate) override;
int aDisplayWidth, int aDisplayHeight) override;
private:
nsAutoPtr<android::OMXVideoEncoder> mEncoder;

Просмотреть файл

@ -192,6 +192,46 @@ AudioTrackEncoder::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) cons
return mRawSegment.SizeOfExcludingThis(aMallocSizeOf);
}
void
VideoTrackEncoder::Init(const VideoSegment& aSegment)
{
if (mInitialized) {
return;
}
mInitCounter++;
TRACK_LOG(LogLevel::Debug, ("Init the video encoder %d times", mInitCounter));
VideoSegment::ConstChunkIterator iter(aSegment);
while (!iter.IsEnded()) {
VideoChunk chunk = *iter;
if (!chunk.IsNull()) {
gfx::IntSize imgsize = chunk.mFrame.GetImage()->GetSize();
gfx::IntSize intrinsicSize = chunk.mFrame.GetIntrinsicSize();
nsresult rv = Init(imgsize.width, imgsize.height,
intrinsicSize.width, intrinsicSize.height);
if (NS_FAILED(rv)) {
LOG("[VideoTrackEncoder]: Fail to initialize the encoder!");
NotifyCancel();
}
break;
}
iter.Next();
}
}
void
VideoTrackEncoder::SetCurrentFrames(const VideoSegment& aSegment)
{
if (mCanceled) {
return;
}
Init(aSegment);
AppendVideoSegment(aSegment);
}
void
VideoTrackEncoder::NotifyQueuedTrackChanges(MediaStreamGraph* aGraph,
TrackID aID,
@ -203,40 +243,15 @@ VideoTrackEncoder::NotifyQueuedTrackChanges(MediaStreamGraph* aGraph,
return;
}
if (!(aTrackEvents == TRACK_EVENT_CREATED ||
aTrackEvents == TRACK_EVENT_ENDED)) {
return;
}
const VideoSegment& video = static_cast<const VideoSegment&>(aQueuedMedia);
// Check and initialize parameters for codec encoder.
if (!mInitialized) {
mInitCounter++;
TRACK_LOG(LogLevel::Debug, ("Init the video encoder %d times", mInitCounter));
VideoSegment::ChunkIterator iter(const_cast<VideoSegment&>(video));
while (!iter.IsEnded()) {
VideoChunk chunk = *iter;
if (!chunk.IsNull()) {
gfx::IntSize imgsize = chunk.mFrame.GetImage()->GetSize();
gfx::IntSize intrinsicSize = chunk.mFrame.GetIntrinsicSize();
nsresult rv = Init(imgsize.width, imgsize.height,
intrinsicSize.width, intrinsicSize.height,
aGraph->GraphRate());
if (NS_FAILED(rv)) {
LOG("[VideoTrackEncoder]: Fail to initialize the encoder!");
NotifyCancel();
}
break;
}
iter.Next();
}
mNotInitDuration += aQueuedMedia.GetDuration();
if (!mInitialized &&
(mNotInitDuration / aGraph->GraphRate() > INIT_FAILED_DURATION) &&
mInitCounter > 1) {
LOG("[VideoTrackEncoder]: Initialize failed for 30s.");
NotifyEndOfStream();
return;
}
}
Init(video);
AppendVideoSegment(video);
@ -244,6 +259,7 @@ VideoTrackEncoder::NotifyQueuedTrackChanges(MediaStreamGraph* aGraph,
if (aTrackEvents == TrackEventCommand::TRACK_EVENT_ENDED) {
LOG("[VideoTrackEncoder]: Receive TRACK_EVENT_ENDED .");
NotifyEndOfStream();
mFirstFrame = true;
}
}
@ -266,6 +282,20 @@ VideoTrackEncoder::AppendVideoSegment(const VideoSegment& aSegment)
if ((mLastFrame != chunk.mFrame) ||
(mLastFrameDuration >= mTrackRate)) {
RefPtr<layers::Image> image = chunk.mFrame.GetImage();
// Fixme: see bug 1290777. We should remove the useage of duration here and
// in |GetEncodedTrack|.
StreamTime duration;
if (mFirstFrame)
{
duration = chunk.GetDuration();
mFirstFrame = false;
} else {
MOZ_ASSERT(chunk.mTimeStamp >= mLastFrameTimeStamp);
TimeDuration timeDuration = chunk.mTimeStamp - mLastFrameTimeStamp;
duration = SecondsToMediaTime(timeDuration.ToSeconds());
}
// Because we may get chunks with a null image (due to input blocking),
// accumulate duration and give it to the next frame that arrives.
// Canonically incorrect - the duration should go to the previous frame
@ -274,12 +304,13 @@ VideoTrackEncoder::AppendVideoSegment(const VideoSegment& aSegment)
// in with each frame.
if (image) {
mRawSegment.AppendFrame(image.forget(),
mLastFrameDuration,
duration,
chunk.mFrame.GetIntrinsicSize(),
PRINCIPAL_HANDLE_NONE,
chunk.mFrame.GetForceBlack());
mLastFrameDuration = 0;
}
mLastFrameTimeStamp = chunk.mTimeStamp;
}
mLastFrame.TakeFrom(&chunk.mFrame);
iter.Next();
@ -299,7 +330,7 @@ VideoTrackEncoder::NotifyEndOfStream()
// encoder with default frame width, frame height, and track rate.
if (!mCanceled && !mInitialized) {
Init(DEFAULT_FRAME_WIDTH, DEFAULT_FRAME_HEIGHT,
DEFAULT_FRAME_WIDTH, DEFAULT_FRAME_HEIGHT, DEFAULT_TRACK_RATE);
DEFAULT_FRAME_WIDTH, DEFAULT_FRAME_HEIGHT);
}
ReentrantMonitorAutoEnter mon(mReentrantMonitor);

Просмотреть файл

@ -248,16 +248,18 @@ protected:
class VideoTrackEncoder : public TrackEncoder
{
public:
VideoTrackEncoder()
explicit VideoTrackEncoder(TrackRate aTrackRate)
: TrackEncoder()
, mFrameWidth(0)
, mFrameHeight(0)
, mDisplayWidth(0)
, mDisplayHeight(0)
, mTrackRate(0)
, mTrackRate(aTrackRate)
, mTotalFrameDuration(0)
, mLastFrameDuration(0)
, mVideoBitrate(0)
, mLastFrameTimeStamp(TimeStamp::Now())
, mFirstFrame(true)
{}
/**
@ -277,6 +279,18 @@ public:
{
mVideoBitrate = aBitrate;
}
void Init(const VideoSegment& aSegment);
void SetCurrentFrames(const VideoSegment& aSegment);
StreamTime SecondsToMediaTime(double aS) const
{
NS_ASSERTION(0 <= aS && aS <= TRACK_TICKS_MAX/TRACK_RATE_MAX,
"Bad seconds");
return mTrackRate * aS;
}
protected:
/**
* Initialized the video encoder. In order to collect the value of width and
@ -286,7 +300,7 @@ protected:
* and this method is called on the MediaStramGraph thread.
*/
virtual nsresult Init(int aWidth, int aHeight, int aDisplayWidth,
int aDisplayHeight, TrackRate aTrackRate) = 0;
int aDisplayHeight) = 0;
/**
* Appends source video frames to mRawSegment. We only append the source chunk
@ -345,6 +359,10 @@ protected:
VideoSegment mRawSegment;
uint32_t mVideoBitrate;
private:
TimeStamp mLastFrameTimeStamp;
bool mFirstFrame;
};
} // namespace mozilla

Просмотреть файл

@ -28,8 +28,8 @@ LazyLogModule gVP8TrackEncoderLog("VP8TrackEncoder");
using namespace mozilla::gfx;
using namespace mozilla::layers;
VP8TrackEncoder::VP8TrackEncoder()
: VideoTrackEncoder()
VP8TrackEncoder::VP8TrackEncoder(TrackRate aTrackRate)
: VideoTrackEncoder(aTrackRate)
, mEncodedFrameDuration(0)
, mEncodedTimestamp(0)
, mRemainingTicks(0)
@ -53,16 +53,14 @@ VP8TrackEncoder::~VP8TrackEncoder()
nsresult
VP8TrackEncoder::Init(int32_t aWidth, int32_t aHeight, int32_t aDisplayWidth,
int32_t aDisplayHeight,TrackRate aTrackRate)
int32_t aDisplayHeight)
{
if (aWidth < 1 || aHeight < 1 || aDisplayWidth < 1 || aDisplayHeight < 1
|| aTrackRate <= 0) {
if (aWidth < 1 || aHeight < 1 || aDisplayWidth < 1 || aDisplayHeight < 1) {
return NS_ERROR_FAILURE;
}
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
mTrackRate = aTrackRate;
mEncodedFrameRate = DEFAULT_ENCODE_FRAMERATE;
mEncodedFrameDuration = mTrackRate / mEncodedFrameRate;
mFrameWidth = aWidth;

Просмотреть файл

@ -29,7 +29,7 @@ class VP8TrackEncoder : public VideoTrackEncoder
SKIP_FRAME, // Skip the next frame.
};
public:
VP8TrackEncoder();
explicit VP8TrackEncoder(TrackRate aTrackRate);
virtual ~VP8TrackEncoder();
already_AddRefed<TrackMetadataBase> GetMetadata() final override;
@ -38,8 +38,7 @@ public:
protected:
nsresult Init(int32_t aWidth, int32_t aHeight,
int32_t aDisplayWidth, int32_t aDisplayHeight,
TrackRate aTrackRate) final override;
int32_t aDisplayWidth, int32_t aDisplayHeight) final override;
private:
// Calculate the target frame's encoded duration.

Просмотреть файл

@ -175,22 +175,23 @@ struct InitParam {
bool mShouldSucceed; // This parameter should cause success or fail result
int mWidth; // frame width
int mHeight; // frame height
mozilla::TrackRate mTrackRate; // track rate. 90K is the most commond track rate.
};
class TestVP8TrackEncoder: public VP8TrackEncoder
{
public:
explicit TestVP8TrackEncoder(TrackRate aTrackRate = 90000)
: VP8TrackEncoder(aTrackRate) {}
::testing::AssertionResult TestInit(const InitParam &aParam)
{
nsresult result = Init(aParam.mWidth, aParam.mHeight, aParam.mWidth, aParam.mHeight, aParam.mTrackRate);
nsresult result = Init(aParam.mWidth, aParam.mHeight, aParam.mWidth, aParam.mHeight);
if (((NS_FAILED(result) && aParam.mShouldSucceed)) || (NS_SUCCEEDED(result) && !aParam.mShouldSucceed))
{
return ::testing::AssertionFailure()
<< " width = " << aParam.mWidth
<< " height = " << aParam.mHeight
<< " TrackRate = " << aParam.mTrackRate << ".";
<< " height = " << aParam.mHeight;
}
else
{
@ -204,17 +205,15 @@ TEST(VP8VideoTrackEncoder, Initialization)
{
InitParam params[] = {
// Failure cases.
{ false, 640, 480, 0 }, // Trackrate should be larger than 1.
{ false, 640, 480, -1 }, // Trackrate should be larger than 1.
{ false, 0, 0, 90000 }, // Height/ width should be larger than 1.
{ false, 0, 1, 90000 }, // Height/ width should be larger than 1.
{ false, 1, 0, 90000}, // Height/ width should be larger than 1.
{ false, 0, 0}, // Height/ width should be larger than 1.
{ false, 0, 1}, // Height/ width should be larger than 1.
{ false, 1, 0}, // Height/ width should be larger than 1.
// Success cases
{ true, 640, 480, 90000}, // Standard VGA
{ true, 800, 480, 90000}, // Standard WVGA
{ true, 960, 540, 90000}, // Standard qHD
{ true, 1280, 720, 90000} // Standard HD
{ true, 640, 480}, // Standard VGA
{ true, 800, 480}, // Standard WVGA
{ true, 960, 540}, // Standard qHD
{ true, 1280, 720} // Standard HD
};
for (size_t i = 0; i < ArrayLength(params); i++)
@ -229,10 +228,10 @@ TEST(VP8VideoTrackEncoder, FetchMetaData)
{
InitParam params[] = {
// Success cases
{ true, 640, 480, 90000}, // Standard VGA
{ true, 800, 480, 90000}, // Standard WVGA
{ true, 960, 540, 90000}, // Standard qHD
{ true, 1280, 720, 90000} // Standard HD
{ true, 640, 480}, // Standard VGA
{ true, 800, 480}, // Standard WVGA
{ true, 960, 540}, // Standard qHD
{ true, 1280, 720} // Standard HD
};
for (size_t i = 0; i < ArrayLength(params); i++)
@ -254,7 +253,7 @@ TEST(VP8VideoTrackEncoder, FrameEncode)
{
// Initiate VP8 encoder
TestVP8TrackEncoder encoder;
InitParam param = {true, 640, 480, 90000};
InitParam param = {true, 640, 480};
encoder.TestInit(param);
// Create YUV images as source.
@ -288,7 +287,7 @@ TEST(VP8VideoTrackEncoder, EncodeComplete)
{
// Initiate VP8 encoder
TestVP8TrackEncoder encoder;
InitParam param = {true, 640, 480, 90000};
InitParam param = {true, 640, 480};
encoder.TestInit(param);
// track end notification.

Просмотреть файл

@ -28,11 +28,13 @@ public:
class WebMVP8TrackEncoder: public VP8TrackEncoder
{
public:
explicit WebMVP8TrackEncoder(TrackRate aTrackRate = 90000)
: VP8TrackEncoder(aTrackRate) {}
bool TestVP8Creation(int32_t aWidth, int32_t aHeight, int32_t aDisplayWidth,
int32_t aDisplayHeight, TrackRate aTrackRate)
int32_t aDisplayHeight)
{
if (NS_SUCCEEDED(Init(aWidth, aHeight, aDisplayWidth, aDisplayHeight,
aTrackRate))) {
if (NS_SUCCEEDED(Init(aWidth, aHeight, aDisplayWidth, aDisplayHeight))) {
return true;
}
return false;
@ -60,7 +62,7 @@ public:
int32_t aDisplayHeight,TrackRate aTrackRate) {
WebMVP8TrackEncoder vp8Encoder;
EXPECT_TRUE(vp8Encoder.TestVP8Creation(aWidth, aHeight, aDisplayWidth,
aDisplayHeight, aTrackRate));
aDisplayHeight));
RefPtr<TrackMetadataBase> vp8Meta = vp8Encoder.GetMetadata();
SetMetadata(vp8Meta);
}