Bug 1014393 - Update EncodedFrame class to more closely resemble MediaData class. r=pehrsons

This changes EncodedFrame to behave more like MediaData, so that EncodedFrame
can be used with the MediaQueue data structure. It also provides a somewhat
more consistent interface across media data types.

Differential Revision: https://phabricator.services.mozilla.com/D35386

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Bryce Van Dyk 2019-07-31 11:29:07 +00:00
Родитель 7ad3574edc
Коммит 472dabf14c
9 изменённых файлов: 145 добавлений и 139 удалений

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

@ -7,6 +7,7 @@
#define EncodedFrame_h_
#include "nsISupportsImpl.h"
#include "VideoUtils.h"
namespace mozilla {
@ -14,7 +15,7 @@ namespace mozilla {
class EncodedFrame final {
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(EncodedFrame)
public:
EncodedFrame() : mTimeStamp(0), mDuration(0), mFrameType(UNKNOWN) {}
EncodedFrame() : mTime(0), mDuration(0), mFrameType(UNKNOWN) {}
enum FrameType {
VP8_I_FRAME, // VP8 intraframe
VP8_P_FRAME, // VP8 predicted frame
@ -34,14 +35,28 @@ class EncodedFrame final {
return NS_ERROR_FAILURE;
}
const nsTArray<uint8_t>& GetFrameData() const { return mFrameData; }
uint64_t GetTimeStamp() const { return mTimeStamp; }
void SetTimeStamp(uint64_t aTimeStamp) { mTimeStamp = aTimeStamp; }
// Timestamp in microseconds
uint64_t mTime;
// The playback duration of this packet. The unit is determined by the use
// case. For VP8 the unit should be microseconds. For opus this is the number
// of samples.
uint64_t mDuration;
// Represent what is in the FrameData
FrameType mFrameType;
uint64_t GetDuration() const { return mDuration; }
void SetDuration(uint64_t aDuration) { mDuration = aDuration; }
FrameType GetFrameType() const { return mFrameType; }
void SetFrameType(FrameType aFrameType) { mFrameType = aFrameType; }
uint64_t GetEndTime() const {
// Defend against untested types. This assert can be removed but we want
// to make sure other types are correctly accounted for.
MOZ_ASSERT(mFrameType == OPUS_AUDIO_FRAME || mFrameType == VP8_I_FRAME ||
mFrameType == VP8_P_FRAME);
if (mFrameType == OPUS_AUDIO_FRAME) {
// See bug 1356054 for discussion around standardization of time units
// (can remove videoutils import when this goes)
return mTime + FramesToUsecs(mDuration, 48000).value();
} else {
return mTime + mDuration;
}
}
private:
// Private destructor, to discourage deletion outside of Release():
@ -49,11 +64,6 @@ class EncodedFrame final {
// Encoded data
nsTArray<uint8_t> mFrameData;
uint64_t mTimeStamp;
// The playback duration of this packet in number of samples
uint64_t mDuration;
// Represent what is in the FrameData
FrameType mFrameType;
};
} // namespace mozilla

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

@ -918,8 +918,8 @@ nsresult MediaEncoder::EncodeData() {
return rv;
}
for (const RefPtr<EncodedFrame>& frame : mEncodedAudioFrames) {
if (frame->GetFrameType() == EncodedFrame::FrameType::OPUS_AUDIO_FRAME) {
frame->SetTimeStamp(frame->GetTimeStamp() + mAudioCodecDelay);
if (frame->mFrameType == EncodedFrame::FrameType::OPUS_AUDIO_FRAME) {
frame->mTime += mAudioCodecDelay;
}
}
}

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

@ -326,7 +326,7 @@ nsresult OpusTrackEncoder::GetEncodedTrack(
MOZ_ASSERT(frameCopied <= 3844, "frameCopied exceeded expected range");
RefPtr<EncodedFrame> audiodata = new EncodedFrame();
audiodata->SetFrameType(EncodedFrame::OPUS_AUDIO_FRAME);
audiodata->mFrameType = EncodedFrame::OPUS_AUDIO_FRAME;
int framesInPCM = frameCopied;
if (mResampler) {
AutoTArray<AudioDataValue, 9600> resamplingDest;
@ -368,10 +368,10 @@ nsresult OpusTrackEncoder::GetEncodedTrack(
mResampledLeftover.Length());
// This is always at 48000Hz.
framesInPCM = framesLeft + outframesToCopy;
audiodata->SetDuration(framesInPCM);
audiodata->mDuration = framesInPCM;
} else {
// The ogg time stamping and pre-skip is always timed at 48000.
audiodata->SetDuration(frameCopied * (kOpusSamplingRate / mSamplingRate));
audiodata->mDuration = frameCopied * (kOpusSamplingRate / mSamplingRate);
}
// Remove the raw data which has been pulled to pcm buffer.
@ -423,7 +423,7 @@ nsresult OpusTrackEncoder::GetEncodedTrack(
audiodata->SwapInFrameData(frameData);
// timestamp should be the time of the first sample
audiodata->SetTimeStamp(mOutputTimeStamp);
audiodata->mTime = mOutputTimeStamp;
mOutputTimeStamp +=
FramesToUsecs(GetPacketDuration(), kOpusSamplingRate).value();
LOG("[Opus] mOutputTimeStamp %lld.", mOutputTimeStamp);

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

@ -250,7 +250,7 @@ nsresult VP8TrackEncoder::GetEncodedPartitions(
if (!frameData.IsEmpty()) {
// Copy the encoded data to aData.
EncodedFrame* videoData = new EncodedFrame();
videoData->SetFrameType(frameType);
videoData->mFrameType = frameType;
// Convert the timestamp and duration to Usecs.
CheckedInt64 timestamp = FramesToUsecs(pkt->data.frame.pts, mTrackRate);
@ -258,7 +258,7 @@ nsresult VP8TrackEncoder::GetEncodedPartitions(
NS_ERROR("Microsecond timestamp overflow");
return NS_ERROR_DOM_MEDIA_OVERFLOW_ERR;
}
videoData->SetTimeStamp((uint64_t)timestamp.value());
videoData->mTime = (uint64_t)timestamp.value();
mExtractedDuration += pkt->data.frame.duration;
if (!mExtractedDuration.isValid()) {
@ -280,13 +280,12 @@ nsresult VP8TrackEncoder::GetEncodedPartitions(
}
mExtractedDurationUs = totalDuration;
videoData->SetDuration((uint64_t)duration.value());
videoData->mDuration = (uint64_t)duration.value();
videoData->SwapInFrameData(frameData);
VP8LOG(LogLevel::Verbose,
"GetEncodedPartitions TimeStamp %" PRIu64 ", Duration %" PRIu64
", FrameType %d",
videoData->GetTimeStamp(), videoData->GetDuration(),
videoData->GetFrameType());
videoData->mTime, videoData->mDuration, videoData->mFrameType);
aData.AppendElement(videoData);
}
@ -527,8 +526,7 @@ nsresult VP8TrackEncoder::GetEncodedTrack(
NS_ERROR("skipped duration overflow");
return NS_ERROR_DOM_MEDIA_OVERFLOW_ERR;
}
last->SetDuration(last->GetDuration() +
(static_cast<uint64_t>(skippedDuration.value())));
last->mDuration += static_cast<uint64_t>(skippedDuration.value());
}
}

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

@ -229,7 +229,7 @@ TEST(OpusAudioTrackEncoder, FrameEncode)
// Verify that encoded data is 5 seconds long.
uint64_t totalDuration = 0;
for (auto& frame : frames) {
totalDuration += frame->GetDuration();
totalDuration += frame->mDuration;
}
// 44100 as used above gets resampled to 48000 for opus.
const uint64_t five = 48000 * 5;

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

@ -174,11 +174,11 @@ TEST(VP8VideoTrackEncoder, SingleFrameEncode)
const size_t oneElement = 1;
ASSERT_EQ(oneElement, frames.Length());
EXPECT_EQ(EncodedFrame::VP8_I_FRAME, frames[0]->GetFrameType())
EXPECT_EQ(EncodedFrame::VP8_I_FRAME, frames[0]->mFrameType)
<< "We only have one frame, so it should be a keyframe";
const uint64_t halfSecond = PR_USEC_PER_SEC / 2;
EXPECT_EQ(halfSecond, frames[0]->GetDuration());
EXPECT_EQ(halfSecond, frames[0]->mDuration);
}
// Test that encoding a couple of identical images gives useful output.
@ -211,7 +211,7 @@ TEST(VP8VideoTrackEncoder, SameFrameEncode)
// Verify total duration being 1.5s.
uint64_t totalDuration = 0;
for (auto& frame : frames) {
totalDuration += frame->GetDuration();
totalDuration += frame->mDuration;
}
const uint64_t oneAndAHalf = (PR_USEC_PER_SEC / 2) * 3;
EXPECT_EQ(oneAndAHalf, totalDuration);
@ -247,7 +247,7 @@ TEST(VP8VideoTrackEncoder, SkippedFrames)
// Verify total duration being 100 * 1ms = 100ms.
uint64_t totalDuration = 0;
for (auto& frame : frames) {
totalDuration += frame->GetDuration();
totalDuration += frame->mDuration;
}
const uint64_t hundredMillis = PR_USEC_PER_SEC / 10;
EXPECT_EQ(hundredMillis, totalDuration);
@ -289,7 +289,7 @@ TEST(VP8VideoTrackEncoder, RoundingErrorFramesEncode)
// Verify total duration being 1s.
uint64_t totalDuration = 0;
for (auto& frame : frames) {
totalDuration += frame->GetDuration();
totalDuration += frame->mDuration;
}
const uint64_t oneSecond = PR_USEC_PER_SEC;
EXPECT_EQ(oneSecond, totalDuration);
@ -331,8 +331,8 @@ TEST(VP8VideoTrackEncoder, TimestampFrameEncode)
uint64_t totalDuration = 0;
size_t i = 0;
for (auto& frame : frames) {
EXPECT_EQ(expectedDurations[i++], frame->GetDuration());
totalDuration += frame->GetDuration();
EXPECT_EQ(expectedDurations[i++], frame->mDuration);
totalDuration += frame->mDuration;
}
const uint64_t pointThree = (PR_USEC_PER_SEC / 10) * 3;
EXPECT_EQ(pointThree, totalDuration);
@ -380,8 +380,8 @@ TEST(VP8VideoTrackEncoder, DriftingFrameEncode)
uint64_t totalDuration = 0;
size_t i = 0;
for (auto& frame : frames) {
EXPECT_EQ(expectedDurations[i++], frame->GetDuration());
totalDuration += frame->GetDuration();
EXPECT_EQ(expectedDurations[i++], frame->mDuration);
totalDuration += frame->mDuration;
}
const uint64_t pointSix = (PR_USEC_PER_SEC / 10) * 6;
EXPECT_EQ(pointSix, totalDuration);
@ -443,7 +443,7 @@ TEST(VP8VideoTrackEncoder, Suspended)
uint64_t totalDuration = 0;
for (auto& frame : frames) {
totalDuration += frame->GetDuration();
totalDuration += frame->mDuration;
}
const uint64_t pointTwo = (PR_USEC_PER_SEC / 10) * 2;
EXPECT_EQ(pointTwo, totalDuration);
@ -493,7 +493,7 @@ TEST(VP8VideoTrackEncoder, SuspendedUntilEnd)
uint64_t totalDuration = 0;
for (auto& frame : frames) {
totalDuration += frame->GetDuration();
totalDuration += frame->mDuration;
}
const uint64_t pointOne = PR_USEC_PER_SEC / 10;
EXPECT_EQ(pointOne, totalDuration);
@ -576,7 +576,7 @@ TEST(VP8VideoTrackEncoder, SuspendedBeginning)
uint64_t totalDuration = 0;
for (auto& frame : frames) {
totalDuration += frame->GetDuration();
totalDuration += frame->mDuration;
}
const uint64_t half = PR_USEC_PER_SEC / 2;
EXPECT_EQ(half, totalDuration);
@ -627,9 +627,9 @@ TEST(VP8VideoTrackEncoder, SuspendedOverlap)
const uint64_t two = 2;
ASSERT_EQ(two, frames.Length());
const uint64_t pointFive = (PR_USEC_PER_SEC / 10) * 5;
EXPECT_EQ(pointFive, frames[0]->GetDuration());
EXPECT_EQ(pointFive, frames[0]->mDuration);
const uint64_t pointSeven = (PR_USEC_PER_SEC / 10) * 7;
EXPECT_EQ(pointSeven, frames[1]->GetDuration());
EXPECT_EQ(pointSeven, frames[1]->mDuration);
}
// Test that ending a track in the middle of already pushed data works.
@ -657,7 +657,7 @@ TEST(VP8VideoTrackEncoder, PrematureEnding)
uint64_t totalDuration = 0;
for (auto& frame : frames) {
totalDuration += frame->GetDuration();
totalDuration += frame->mDuration;
}
const uint64_t half = PR_USEC_PER_SEC / 2;
EXPECT_EQ(half, totalDuration);
@ -689,7 +689,7 @@ TEST(VP8VideoTrackEncoder, DelayedStart)
uint64_t totalDuration = 0;
for (auto& frame : frames) {
totalDuration += frame->GetDuration();
totalDuration += frame->mDuration;
}
const uint64_t half = PR_USEC_PER_SEC / 2;
EXPECT_EQ(half, totalDuration);
@ -722,7 +722,7 @@ TEST(VP8VideoTrackEncoder, DelayedStartOtherEventOrder)
uint64_t totalDuration = 0;
for (auto& frame : frames) {
totalDuration += frame->GetDuration();
totalDuration += frame->mDuration;
}
const uint64_t half = PR_USEC_PER_SEC / 2;
EXPECT_EQ(half, totalDuration);
@ -754,7 +754,7 @@ TEST(VP8VideoTrackEncoder, VeryDelayedStart)
uint64_t totalDuration = 0;
for (auto& frame : frames) {
totalDuration += frame->GetDuration();
totalDuration += frame->mDuration;
}
const uint64_t half = PR_USEC_PER_SEC / 2;
EXPECT_EQ(half, totalDuration);
@ -790,7 +790,7 @@ TEST(VP8VideoTrackEncoder, LongFramesReEncoded)
uint64_t totalDuration = 0;
for (auto& frame : frames) {
totalDuration += frame->GetDuration();
totalDuration += frame->mDuration;
}
const uint64_t oneSec = PR_USEC_PER_SEC;
EXPECT_EQ(oneSec, totalDuration);
@ -807,7 +807,7 @@ TEST(VP8VideoTrackEncoder, LongFramesReEncoded)
uint64_t totalDuration = 0;
for (auto& frame : frames) {
totalDuration += frame->GetDuration();
totalDuration += frame->mDuration;
}
const uint64_t tenSec = PR_USEC_PER_SEC * 10;
EXPECT_EQ(tenSec, totalDuration);
@ -860,28 +860,28 @@ TEST(VP8VideoTrackEncoder, ShortKeyFrameInterval)
ASSERT_EQ(6UL, frames.Length());
// [0, 400ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 400UL, frames[0]->GetDuration());
EXPECT_EQ(EncodedFrame::VP8_I_FRAME, frames[0]->GetFrameType());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 400UL, frames[0]->mDuration);
EXPECT_EQ(EncodedFrame::VP8_I_FRAME, frames[0]->mFrameType);
// [400ms, 600ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 200UL, frames[1]->GetDuration());
EXPECT_EQ(EncodedFrame::VP8_P_FRAME, frames[1]->GetFrameType());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 200UL, frames[1]->mDuration);
EXPECT_EQ(EncodedFrame::VP8_P_FRAME, frames[1]->mFrameType);
// [600ms, 750ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 150UL, frames[2]->GetDuration());
EXPECT_EQ(EncodedFrame::VP8_I_FRAME, frames[2]->GetFrameType());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 150UL, frames[2]->mDuration);
EXPECT_EQ(EncodedFrame::VP8_I_FRAME, frames[2]->mFrameType);
// [750ms, 900ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 150UL, frames[3]->GetDuration());
EXPECT_EQ(EncodedFrame::VP8_P_FRAME, frames[3]->GetFrameType());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 150UL, frames[3]->mDuration);
EXPECT_EQ(EncodedFrame::VP8_P_FRAME, frames[3]->mFrameType);
// [900ms, 1100ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 200UL, frames[4]->GetDuration());
EXPECT_EQ(EncodedFrame::VP8_P_FRAME, frames[4]->GetFrameType());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 200UL, frames[4]->mDuration);
EXPECT_EQ(EncodedFrame::VP8_P_FRAME, frames[4]->mFrameType);
// [1100ms, 1200ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 100UL, frames[5]->GetDuration());
EXPECT_EQ(EncodedFrame::VP8_I_FRAME, frames[5]->GetFrameType());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 100UL, frames[5]->mDuration);
EXPECT_EQ(EncodedFrame::VP8_I_FRAME, frames[5]->mFrameType);
}
// Test that an encoding with a defined key frame interval encodes keyframes
@ -929,28 +929,28 @@ TEST(VP8VideoTrackEncoder, LongKeyFrameInterval)
ASSERT_EQ(6UL, frames.Length());
// [0, 600ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 600UL, frames[0]->GetDuration());
EXPECT_EQ(EncodedFrame::VP8_I_FRAME, frames[0]->GetFrameType());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 600UL, frames[0]->mDuration);
EXPECT_EQ(EncodedFrame::VP8_I_FRAME, frames[0]->mFrameType);
// [600ms, 900ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 300UL, frames[1]->GetDuration());
EXPECT_EQ(EncodedFrame::VP8_P_FRAME, frames[1]->GetFrameType());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 300UL, frames[1]->mDuration);
EXPECT_EQ(EncodedFrame::VP8_P_FRAME, frames[1]->mFrameType);
// [900ms, 1100ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 200UL, frames[2]->GetDuration());
EXPECT_EQ(EncodedFrame::VP8_P_FRAME, frames[2]->GetFrameType());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 200UL, frames[2]->mDuration);
EXPECT_EQ(EncodedFrame::VP8_P_FRAME, frames[2]->mFrameType);
// [1100ms, 1900ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 800UL, frames[3]->GetDuration());
EXPECT_EQ(EncodedFrame::VP8_I_FRAME, frames[3]->GetFrameType());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 800UL, frames[3]->mDuration);
EXPECT_EQ(EncodedFrame::VP8_I_FRAME, frames[3]->mFrameType);
// [1900ms, 2100ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 200UL, frames[4]->GetDuration());
EXPECT_EQ(EncodedFrame::VP8_P_FRAME, frames[4]->GetFrameType());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 200UL, frames[4]->mDuration);
EXPECT_EQ(EncodedFrame::VP8_P_FRAME, frames[4]->mFrameType);
// [2100ms, 2200ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 100UL, frames[5]->GetDuration());
EXPECT_EQ(EncodedFrame::VP8_I_FRAME, frames[5]->GetFrameType());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 100UL, frames[5]->mDuration);
EXPECT_EQ(EncodedFrame::VP8_I_FRAME, frames[5]->mFrameType);
}
// Test that an encoding with no defined key frame interval encodes keyframes
@ -996,28 +996,28 @@ TEST(VP8VideoTrackEncoder, DefaultKeyFrameInterval)
ASSERT_EQ(6UL, frames.Length());
// [0, 600ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 600UL, frames[0]->GetDuration());
EXPECT_EQ(EncodedFrame::VP8_I_FRAME, frames[0]->GetFrameType());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 600UL, frames[0]->mDuration);
EXPECT_EQ(EncodedFrame::VP8_I_FRAME, frames[0]->mFrameType);
// [600ms, 900ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 300UL, frames[1]->GetDuration());
EXPECT_EQ(EncodedFrame::VP8_P_FRAME, frames[1]->GetFrameType());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 300UL, frames[1]->mDuration);
EXPECT_EQ(EncodedFrame::VP8_P_FRAME, frames[1]->mFrameType);
// [900ms, 1100ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 200UL, frames[2]->GetDuration());
EXPECT_EQ(EncodedFrame::VP8_P_FRAME, frames[2]->GetFrameType());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 200UL, frames[2]->mDuration);
EXPECT_EQ(EncodedFrame::VP8_P_FRAME, frames[2]->mFrameType);
// [1100ms, 1900ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 800UL, frames[3]->GetDuration());
EXPECT_EQ(EncodedFrame::VP8_I_FRAME, frames[3]->GetFrameType());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 800UL, frames[3]->mDuration);
EXPECT_EQ(EncodedFrame::VP8_I_FRAME, frames[3]->mFrameType);
// [1900ms, 2100ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 200UL, frames[4]->GetDuration());
EXPECT_EQ(EncodedFrame::VP8_P_FRAME, frames[4]->GetFrameType());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 200UL, frames[4]->mDuration);
EXPECT_EQ(EncodedFrame::VP8_P_FRAME, frames[4]->mFrameType);
// [2100ms, 2200ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 100UL, frames[5]->GetDuration());
EXPECT_EQ(EncodedFrame::VP8_I_FRAME, frames[5]->GetFrameType());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 100UL, frames[5]->mDuration);
EXPECT_EQ(EncodedFrame::VP8_I_FRAME, frames[5]->mFrameType);
}
// Test that an encoding where the key frame interval is updated dynamically
@ -1133,60 +1133,60 @@ TEST(VP8VideoTrackEncoder, DynamicKeyFrameIntervalChanges)
ASSERT_EQ(14UL, frames.Length());
// [0, 100ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 100UL, frames[0]->GetDuration());
EXPECT_EQ(EncodedFrame::VP8_I_FRAME, frames[0]->GetFrameType());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 100UL, frames[0]->mDuration);
EXPECT_EQ(EncodedFrame::VP8_I_FRAME, frames[0]->mFrameType);
// [100ms, 120ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 20UL, frames[1]->GetDuration());
EXPECT_EQ(EncodedFrame::VP8_I_FRAME, frames[1]->GetFrameType());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 20UL, frames[1]->mDuration);
EXPECT_EQ(EncodedFrame::VP8_I_FRAME, frames[1]->mFrameType);
// [120ms, 130ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 10UL, frames[2]->GetDuration());
EXPECT_EQ(EncodedFrame::VP8_P_FRAME, frames[2]->GetFrameType());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 10UL, frames[2]->mDuration);
EXPECT_EQ(EncodedFrame::VP8_P_FRAME, frames[2]->mFrameType);
// [130ms, 200ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 70UL, frames[3]->GetDuration());
EXPECT_EQ(EncodedFrame::VP8_P_FRAME, frames[3]->GetFrameType());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 70UL, frames[3]->mDuration);
EXPECT_EQ(EncodedFrame::VP8_P_FRAME, frames[3]->mFrameType);
// [200ms, 300ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 100UL, frames[4]->GetDuration());
EXPECT_EQ(EncodedFrame::VP8_I_FRAME, frames[4]->GetFrameType());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 100UL, frames[4]->mDuration);
EXPECT_EQ(EncodedFrame::VP8_I_FRAME, frames[4]->mFrameType);
// [300ms, 500ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 200UL, frames[5]->GetDuration());
EXPECT_EQ(EncodedFrame::VP8_I_FRAME, frames[5]->GetFrameType());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 200UL, frames[5]->mDuration);
EXPECT_EQ(EncodedFrame::VP8_I_FRAME, frames[5]->mFrameType);
// [500ms, 1300ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 800UL, frames[6]->GetDuration());
EXPECT_EQ(EncodedFrame::VP8_P_FRAME, frames[6]->GetFrameType());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 800UL, frames[6]->mDuration);
EXPECT_EQ(EncodedFrame::VP8_P_FRAME, frames[6]->mFrameType);
// [1300ms, 1400ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 100UL, frames[7]->GetDuration());
EXPECT_EQ(EncodedFrame::VP8_I_FRAME, frames[7]->GetFrameType());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 100UL, frames[7]->mDuration);
EXPECT_EQ(EncodedFrame::VP8_I_FRAME, frames[7]->mFrameType);
// [1400ms, 2400ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 1000UL, frames[8]->GetDuration());
EXPECT_EQ(EncodedFrame::VP8_P_FRAME, frames[8]->GetFrameType());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 1000UL, frames[8]->mDuration);
EXPECT_EQ(EncodedFrame::VP8_P_FRAME, frames[8]->mFrameType);
// [2400ms, 2500ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 100UL, frames[9]->GetDuration());
EXPECT_EQ(EncodedFrame::VP8_I_FRAME, frames[9]->GetFrameType());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 100UL, frames[9]->mDuration);
EXPECT_EQ(EncodedFrame::VP8_I_FRAME, frames[9]->mFrameType);
// [2500ms, 2600ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 100UL, frames[10]->GetDuration());
EXPECT_EQ(EncodedFrame::VP8_P_FRAME, frames[10]->GetFrameType());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 100UL, frames[10]->mDuration);
EXPECT_EQ(EncodedFrame::VP8_P_FRAME, frames[10]->mFrameType);
// [2600ms, 2800ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 200UL, frames[11]->GetDuration());
EXPECT_EQ(EncodedFrame::VP8_I_FRAME, frames[11]->GetFrameType());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 200UL, frames[11]->mDuration);
EXPECT_EQ(EncodedFrame::VP8_I_FRAME, frames[11]->mFrameType);
// [2800ms, 2900ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 100UL, frames[12]->GetDuration());
EXPECT_EQ(EncodedFrame::VP8_I_FRAME, frames[12]->GetFrameType());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 100UL, frames[12]->mDuration);
EXPECT_EQ(EncodedFrame::VP8_I_FRAME, frames[12]->mFrameType);
// [2900ms, 3000ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 100UL, frames[13]->GetDuration());
EXPECT_EQ(EncodedFrame::VP8_P_FRAME, frames[13]->GetFrameType());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 100UL, frames[13]->mDuration);
EXPECT_EQ(EncodedFrame::VP8_P_FRAME, frames[13]->mFrameType);
}
// Test that an encoding which is disabled on a frame timestamp encodes
@ -1227,10 +1227,10 @@ TEST(VP8VideoTrackEncoder, DisableOnFrameTime)
ASSERT_EQ(2UL, frames.Length());
// [0, 100ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 100UL, frames[0]->GetDuration());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 100UL, frames[0]->mDuration);
// [100ms, 200ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 100UL, frames[1]->GetDuration());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 100UL, frames[1]->mDuration);
}
// Test that an encoding which is disabled between two frame timestamps encodes
@ -1268,13 +1268,13 @@ TEST(VP8VideoTrackEncoder, DisableBetweenFrames)
ASSERT_EQ(3UL, frames.Length());
// [0, 50ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 50UL, frames[0]->GetDuration());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 50UL, frames[0]->mDuration);
// [50ms, 100ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 50UL, frames[1]->GetDuration());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 50UL, frames[1]->mDuration);
// [100ms, 200ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 100UL, frames[2]->GetDuration());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 100UL, frames[2]->mDuration);
}
// Test that an encoding which is enabled on a frame timestamp encodes
@ -1317,10 +1317,10 @@ TEST(VP8VideoTrackEncoder, EnableOnFrameTime)
ASSERT_EQ(2UL, frames.Length());
// [0, 100ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 100UL, frames[0]->GetDuration());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 100UL, frames[0]->mDuration);
// [100ms, 200ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 100UL, frames[1]->GetDuration());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 100UL, frames[1]->mDuration);
}
// Test that an encoding which is enabled between two frame timestamps encodes
@ -1360,13 +1360,13 @@ TEST(VP8VideoTrackEncoder, EnableBetweenFrames)
ASSERT_EQ(3UL, frames.Length());
// [0, 50ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 50UL, frames[0]->GetDuration());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 50UL, frames[0]->mDuration);
// [50ms, 100ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 50UL, frames[1]->GetDuration());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 50UL, frames[1]->mDuration);
// [100ms, 200ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 100UL, frames[2]->GetDuration());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 100UL, frames[2]->mDuration);
}
// Test that making time go backwards removes any future frames in the encoder.
@ -1428,16 +1428,16 @@ TEST(VP8VideoTrackEncoder, BackwardsTimeResets)
ASSERT_EQ(4UL, frames.Length());
// [0, 100ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 100UL, frames[0]->GetDuration());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 100UL, frames[0]->mDuration);
// [100ms, 150ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 50UL, frames[1]->GetDuration());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 50UL, frames[1]->mDuration);
// [150ms, 250ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 100UL, frames[2]->GetDuration());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 100UL, frames[2]->mDuration);
// [250ms, 300ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 50UL, frames[3]->GetDuration());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 50UL, frames[3]->mDuration);
}
// Test that trying to encode a null image removes any future frames in the
@ -1500,13 +1500,13 @@ TEST(VP8VideoTrackEncoder, NullImageResets)
ASSERT_EQ(3UL, frames.Length());
// [0, 100ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 100UL, frames[0]->GetDuration());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 100UL, frames[0]->mDuration);
// [100ms, 250ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 150UL, frames[1]->GetDuration());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 150UL, frames[1]->mDuration);
// [250ms, 300ms)
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 50UL, frames[2]->GetDuration());
EXPECT_EQ(PR_USEC_PER_SEC / 1000 * 50UL, frames[2]->mDuration);
}
// EOS test

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

@ -74,9 +74,9 @@ class TestWebMWriter : public WebMWriter {
RefPtr<EncodedFrame> videoData = new EncodedFrame();
// Create dummy frame data.
frameData.SetLength(FIXED_FRAMESIZE);
videoData->SetFrameType(aFrameType);
videoData->SetTimeStamp(mTimestamp);
videoData->SetDuration(aDuration);
videoData->mFrameType = aFrameType;
videoData->mTime = mTimestamp;
videoData->mDuration = aDuration;
videoData->SwapInFrameData(frameData);
encodedVideoData.AppendElement(videoData);
WriteEncodedTrack(encodedVideoData, 0);

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

@ -52,14 +52,14 @@ nsresult OggWriter::WriteEncodedTrack(
uint32_t len = aData.Length();
for (uint32_t i = 0; i < len; i++) {
if (aData[i]->GetFrameType() != EncodedFrame::OPUS_AUDIO_FRAME) {
if (aData[i]->mFrameType != EncodedFrame::OPUS_AUDIO_FRAME) {
LOG("[OggWriter] wrong encoded data type!");
return NS_ERROR_FAILURE;
}
// only pass END_OF_STREAM on the last frame!
nsresult rv = WriteEncodedData(
aData[i]->GetFrameData(), aData[i]->GetDuration(),
aData[i]->GetFrameData(), aData[i]->mDuration,
i < len - 1 ? (aFlags & ~ContainerWriter::END_OF_STREAM) : aFlags);
if (NS_FAILED(rv)) {
LOG("%p Failed to WriteEncodedTrack!", this);

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

@ -115,7 +115,7 @@ void EbmlComposer::WriteSimpleBlock(EncodedFrame* aFrame) {
EbmlGlobal ebml;
ebml.offset = 0;
auto frameType = aFrame->GetFrameType();
auto frameType = aFrame->mFrameType;
const bool isVP8IFrame = (frameType == EncodedFrame::FrameType::VP8_I_FRAME);
const bool isVP8PFrame = (frameType == EncodedFrame::FrameType::VP8_P_FRAME);
const bool isOpus = (frameType == EncodedFrame::FrameType::OPUS_AUDIO_FRAME);
@ -129,8 +129,7 @@ void EbmlComposer::WriteSimpleBlock(EncodedFrame* aFrame) {
return;
}
int64_t timeCode =
aFrame->GetTimeStamp() / ((int)PR_USEC_PER_MSEC) - mClusterTimecode;
int64_t timeCode = aFrame->mTime / ((int)PR_USEC_PER_MSEC) - mClusterTimecode;
if (!mHasVideo && timeCode >= FLUSH_AUDIO_ONLY_AFTER_MS) {
MOZ_ASSERT(mHasAudio);
@ -155,12 +154,11 @@ void EbmlComposer::WriteSimpleBlock(EncodedFrame* aFrame) {
mClusterHeaderIndex = mClusters.Length() - 1;
mClusterLengthLoc = ebmlLoc.offset;
// if timeCode didn't under/overflow before, it shouldn't after this
mClusterTimecode = aFrame->GetTimeStamp() / PR_USEC_PER_MSEC;
mClusterTimecode = aFrame->mTime / PR_USEC_PER_MSEC;
Ebml_SerializeUnsigned(&ebml, Timecode, mClusterTimecode);
// Can't under-/overflow now
timeCode =
aFrame->GetTimeStamp() / ((int)PR_USEC_PER_MSEC) - mClusterTimecode;
timeCode = aFrame->mTime / ((int)PR_USEC_PER_MSEC) - mClusterTimecode;
mWritingCluster = true;
}