Bug 1294753: Flush WebM clusters if the timecode offset will over/underflow r=rillian

This commit is contained in:
Randell Jesup 2016-08-18 00:31:13 -04:00
Родитель 56574d1bf8
Коммит b7952dd505
1 изменённых файлов: 18 добавлений и 3 удалений

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

@ -10,6 +10,7 @@
#include "libmkv/EbmlWriter.h"
#include "libmkv/WebMElement.h"
#include "prtime.h"
#include "limits.h"
namespace mozilla {
@ -124,33 +125,47 @@ EbmlComposer::WriteSimpleBlock(EncodedFrame* aFrame)
ebml.offset = 0;
auto frameType = aFrame->GetFrameType();
bool flush = false;
bool isVP8IFrame = (frameType == EncodedFrame::FrameType::VP8_I_FRAME);
if (isVP8IFrame) {
FinishCluster();
flush = true;
} else {
// Force it to calculate timecode using signed math via cast
int64_t timeCode = (aFrame->GetTimeStamp() / ((int) PR_USEC_PER_MSEC) - mClusterTimecode) +
(mCodecDelay / PR_NSEC_PER_MSEC);
if (timeCode < SHRT_MIN || timeCode > SHRT_MAX ) {
// We're probably going to overflow (or underflow) the timeCode value later!
FinishCluster();
flush = true;
}
}
auto block = mClusterBuffs.AppendElement();
block->SetLength(aFrame->GetFrameData().Length() + DEFAULT_HEADER_SIZE);
ebml.buf = block->Elements();
if (isVP8IFrame) {
if (flush) {
EbmlLoc ebmlLoc;
Ebml_StartSubElement(&ebml, &ebmlLoc, Cluster);
MOZ_ASSERT(mClusterBuffs.Length() > 0);
// current cluster header array index
mClusterHeaderIndex = mClusterBuffs.Length() - 1;
mClusterLengthLoc = ebmlLoc.offset;
// if timeCode didn't under/overflow before, it shouldn't after this
mClusterTimecode = aFrame->GetTimeStamp() / PR_USEC_PER_MSEC;
Ebml_SerializeUnsigned(&ebml, Timecode, mClusterTimecode);
mFlushState |= FLUSH_CLUSTER;
}
bool isOpus = (frameType == EncodedFrame::FrameType::OPUS_AUDIO_FRAME);
short timeCode = aFrame->GetTimeStamp() / PR_USEC_PER_MSEC - mClusterTimecode;
// Can't underflow/overflow now
int64_t timeCode = aFrame->GetTimeStamp() / ((int) PR_USEC_PER_MSEC) - mClusterTimecode;
if (isOpus) {
timeCode += mCodecDelay / PR_NSEC_PER_MSEC;
}
writeSimpleBlock(&ebml, isOpus ? 0x2 : 0x1, timeCode, isVP8IFrame,
MOZ_ASSERT(timeCode >= SHRT_MIN && timeCode <= SHRT_MAX);
writeSimpleBlock(&ebml, isOpus ? 0x2 : 0x1, static_cast<short>(timeCode), isVP8IFrame,
0, 0, (unsigned char*)aFrame->GetFrameData().Elements(),
aFrame->GetFrameData().Length());
MOZ_ASSERT(ebml.offset <= DEFAULT_HEADER_SIZE +