本文整理汇总了C++中CheckedInt64类的典型用法代码示例。如果您正苦于以下问题:C++ CheckedInt64类的具体用法?C++ CheckedInt64怎么用?C++ CheckedInt64使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了CheckedInt64类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: GADM_LOG
nsresult
GonkAudioDecoderManager::CreateAudioData(int64_t aStreamOffset, AudioData **v) {
if (!(mAudioBuffer != nullptr && mAudioBuffer->data() != nullptr)) {
GADM_LOG("Audio Buffer is not valid!");
return NS_ERROR_UNEXPECTED;
}
int64_t timeUs;
if (!mAudioBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) {
return NS_ERROR_UNEXPECTED;
}
if (mAudioBuffer->range_length() == 0) {
// Some decoders may return spurious empty buffers that we just want to ignore
// quoted from Android's AwesomePlayer.cpp
ReleaseAudioBuffer();
return NS_ERROR_NOT_AVAILABLE;
}
if (mLastDecodedTime > timeUs) {
ReleaseAudioBuffer();
GADM_LOG("Output decoded sample time is revert. time=%lld", timeUs);
MOZ_ASSERT(false);
return NS_ERROR_NOT_AVAILABLE;
}
mLastDecodedTime = timeUs;
const uint8_t *data = static_cast<const uint8_t*>(mAudioBuffer->data());
size_t dataOffset = mAudioBuffer->range_offset();
size_t size = mAudioBuffer->range_length();
nsAutoArrayPtr<AudioDataValue> buffer(new AudioDataValue[size/2]);
memcpy(buffer.get(), data+dataOffset, size);
uint32_t frames = size / (2 * mAudioChannels);
CheckedInt64 duration = FramesToUsecs(frames, mAudioRate);
if (!duration.isValid()) {
return NS_ERROR_UNEXPECTED;
}
nsRefPtr<AudioData> audioData = new AudioData(aStreamOffset,
timeUs,
duration.value(),
frames,
buffer.forget(),
mAudioChannels,
mAudioRate);
ReleaseAudioBuffer();
audioData.forget(v);
return NS_OK;
}
示例2: ParseSize
// Makes sure that aStart and aEnd is less then or equal to aSize and greater
// than 0
static void
ParseSize(int64_t aSize, int64_t& aStart, int64_t& aEnd)
{
CheckedInt64 newStartOffset = aStart;
if (aStart < -aSize) {
newStartOffset = 0;
}
else if (aStart < 0) {
newStartOffset += aSize;
}
else if (aStart > aSize) {
newStartOffset = aSize;
}
CheckedInt64 newEndOffset = aEnd;
if (aEnd < -aSize) {
newEndOffset = 0;
}
else if (aEnd < 0) {
newEndOffset += aSize;
}
else if (aEnd > aSize) {
newEndOffset = aSize;
}
if (!newStartOffset.isValid() || !newEndOffset.isValid() ||
newStartOffset.value() >= newEndOffset.value()) {
aStart = aEnd = 0;
}
else {
aStart = newStartOffset.value();
aEnd = newEndOffset.value();
}
}
示例3: GADM_LOG
nsresult
GonkAudioDecoderManager::CreateAudioData(MediaBuffer* aBuffer, int64_t aStreamOffset)
{
if (!(aBuffer != nullptr && aBuffer->data() != nullptr)) {
GADM_LOG("Audio Buffer is not valid!");
return NS_ERROR_UNEXPECTED;
}
int64_t timeUs;
if (!aBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) {
return NS_ERROR_UNEXPECTED;
}
if (aBuffer->range_length() == 0) {
// Some decoders may return spurious empty buffers that we just want to ignore
// quoted from Android's AwesomePlayer.cpp
return NS_ERROR_NOT_AVAILABLE;
}
if (mLastTime > timeUs) {
GADM_LOG("Output decoded sample time is revert. time=%lld", timeUs);
MOZ_ASSERT(false);
return NS_ERROR_NOT_AVAILABLE;
}
mLastTime = timeUs;
const uint8_t *data = static_cast<const uint8_t*>(aBuffer->data());
size_t dataOffset = aBuffer->range_offset();
size_t size = aBuffer->range_length();
uint32_t frames = size / (2 * mAudioChannels);
CheckedInt64 duration = FramesToUsecs(frames, mAudioRate);
if (!duration.isValid()) {
return NS_ERROR_UNEXPECTED;
}
typedef AudioCompactor::NativeCopy OmxCopy;
mAudioCompactor.Push(aStreamOffset,
timeUs,
mAudioRate,
frames,
mAudioChannels,
OmxCopy(data+dataOffset,
size,
mAudioChannels));
return NS_OK;
}
示例4: TH_VERSION_CHECK
int64_t TheoraState::Time(th_info* aInfo, int64_t aGranulepos)
{
if (aGranulepos < 0 || aInfo->fps_numerator == 0) {
return -1;
}
// Implementation of th_granule_frame inlined here to operate
// on the th_info structure instead of the theora_state.
int shift = aInfo->keyframe_granule_shift;
ogg_int64_t iframe = aGranulepos >> shift;
ogg_int64_t pframe = aGranulepos - (iframe << shift);
int64_t frameno = iframe + pframe - TH_VERSION_CHECK(aInfo, 3, 2, 1);
CheckedInt64 t = ((CheckedInt64(frameno) + 1) * USECS_PER_S) * aInfo->fps_denominator;
if (!t.isValid())
return -1;
t /= aInfo->fps_numerator;
return t.isValid() ? t.value() : -1;
}
示例5: Create
MediaData* Create(const media::TimeUnit& aDTS,
const media::TimeUnit& aDuration,
int64_t aOffsetInStream)
{
// Convert duration to frames. We add 1 to duration to account for
// rounding errors, so we get a consistent tone.
CheckedInt64 frames =
UsecsToFrames(aDuration.ToMicroseconds()+1, mSampleRate);
if (!frames.isValid() ||
!mChannelCount ||
!mSampleRate ||
frames.value() > (UINT32_MAX / mChannelCount)) {
return nullptr;
}
AudioDataValue* samples = new AudioDataValue[frames.value() * mChannelCount];
// Fill the sound buffer with an A4 tone.
static const float pi = 3.14159265f;
static const float noteHz = 440.0f;
for (int i = 0; i < frames.value(); i++) {
float f = sin(2 * pi * noteHz * mFrameSum / mSampleRate);
for (unsigned c = 0; c < mChannelCount; c++) {
samples[i * mChannelCount + c] = AudioDataValue(f);
}
mFrameSum++;
}
return new AudioData(aOffsetInStream,
aDTS.ToMicroseconds(),
aDuration.ToMicroseconds(),
uint32_t(frames.value()),
samples,
mChannelCount,
mSampleRate);
}
示例6: NS_ASSERTION
bool
DecodedAudioDataSink::PlayAudio()
{
// See if there's a gap in the audio. If there is, push silence into the
// audio hardware, so we can play across the gap.
// Calculate the timestamp of the next chunk of audio in numbers of
// samples.
NS_ASSERTION(AudioQueue().GetSize() > 0, "Should have data to play");
CheckedInt64 sampleTime = UsecsToFrames(AudioQueue().PeekFront()->mTime, mInfo.mRate);
// Calculate the number of frames that have been pushed onto the audio hardware.
CheckedInt64 playedFrames = UsecsToFrames(mStartTime, mInfo.mRate) +
static_cast<int64_t>(mWritten);
CheckedInt64 missingFrames = sampleTime - playedFrames;
if (!missingFrames.isValid() || !sampleTime.isValid()) {
NS_WARNING("Int overflow adding in AudioLoop");
return false;
}
if (missingFrames.value() > AUDIO_FUZZ_FRAMES) {
// The next audio chunk begins some time after the end of the last chunk
// we pushed to the audio hardware. We must push silence into the audio
// hardware so that the next audio chunk begins playback at the correct
// time.
missingFrames = std::min<int64_t>(UINT32_MAX, missingFrames.value());
mWritten += PlaySilence(static_cast<uint32_t>(missingFrames.value()));
} else {
mWritten += PlayFromAudioQueue();
}
return true;
}
示例7: AssertOnAudioThread
void
AudioSink::AudioLoop()
{
AssertOnAudioThread();
SINK_LOG("AudioLoop started");
if (NS_FAILED(InitializeAudioStream())) {
NS_WARNING("Initializing AudioStream failed.");
mStateMachine->DispatchOnAudioSinkError();
return;
}
while (1) {
{
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
WaitForAudioToPlay();
if (!IsPlaybackContinuing()) {
break;
}
}
// See if there's a gap in the audio. If there is, push silence into the
// audio hardware, so we can play across the gap.
// Calculate the timestamp of the next chunk of audio in numbers of
// samples.
NS_ASSERTION(AudioQueue().GetSize() > 0, "Should have data to play");
CheckedInt64 sampleTime = UsecsToFrames(AudioQueue().PeekFront()->mTime, mInfo.mRate);
// Calculate the number of frames that have been pushed onto the audio hardware.
CheckedInt64 playedFrames = UsecsToFrames(mStartTime, mInfo.mRate) + mWritten;
CheckedInt64 missingFrames = sampleTime - playedFrames;
if (!missingFrames.isValid() || !sampleTime.isValid()) {
NS_WARNING("Int overflow adding in AudioLoop");
break;
}
if (missingFrames.value() > AUDIO_FUZZ_FRAMES) {
// The next audio chunk begins some time after the end of the last chunk
// we pushed to the audio hardware. We must push silence into the audio
// hardware so that the next audio chunk begins playback at the correct
// time.
missingFrames = std::min<int64_t>(UINT32_MAX, missingFrames.value());
mWritten += PlaySilence(static_cast<uint32_t>(missingFrames.value()));
} else {
mWritten += PlayFromAudioQueue();
}
int64_t endTime = GetEndTime();
if (endTime != -1) {
mOnAudioEndTimeUpdateTask->Dispatch(endTime);
}
}
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
MOZ_ASSERT(mStopAudioThread || AudioQueue().AtEndOfStream());
if (!mStopAudioThread && mPlaying) {
Drain();
}
SINK_LOG("AudioLoop complete");
Cleanup();
SINK_LOG("AudioLoop exit");
}
示例8: CheckedInt64
PRInt64
nsTheoraState::MaxKeyframeOffset()
{
// Determine the maximum time in microseconds by which a key frame could
// offset for the theora bitstream. Theora granulepos encode time as:
// ((key_frame_number << granule_shift) + frame_offset).
// Therefore the maximum possible time by which any frame could be offset
// from a keyframe is the duration of (1 << granule_shift) - 1) frames.
PRInt64 frameDuration;
// Max number of frames keyframe could possibly be offset.
PRInt64 keyframeDiff = (1 << mInfo.keyframe_granule_shift) - 1;
// Length of frame in usecs.
CheckedInt64 d = CheckedInt64(mInfo.fps_denominator) * USECS_PER_S;
if (!d.valid())
d = 0;
frameDuration = d.value() / mInfo.fps_numerator;
// Total time in usecs keyframe can be offset from any given frame.
return frameDuration * keyframeDiff;
}
示例9: MOZ_ASSERT
void
AudioSink::NotifyAudioNeeded()
{
MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn(),
"Not called from the owner's thread");
// Always ensure we have two processed frames pending to allow for processing
// latency.
while (mAudioQueue.GetSize() && (mAudioQueue.IsFinished() ||
mProcessedQueueLength < LOW_AUDIO_USECS ||
mProcessedQueue.GetSize() < 2)) {
RefPtr<AudioData> data = mAudioQueue.PopFront();
// Ignore the element with 0 frames and try next.
if (!data->mFrames) {
continue;
}
if (!mConverter ||
(data->mRate != mConverter->InputConfig().Rate() ||
data->mChannels != mConverter->InputConfig().Channels())) {
SINK_LOG_V("Audio format changed from %[email protected]%uHz to %[email protected]%uHz",
mConverter? mConverter->InputConfig().Channels() : 0,
mConverter ? mConverter->InputConfig().Rate() : 0,
data->mChannels, data->mRate);
DrainConverter();
// mFramesParsed indicates the current playtime in frames at the current
// input sampling rate. Recalculate it per the new sampling rate.
if (mFramesParsed) {
// We minimize overflow.
uint32_t oldRate = mConverter->InputConfig().Rate();
uint32_t newRate = data->mRate;
CheckedInt64 result = SaferMultDiv(mFramesParsed, newRate, oldRate);
if (!result.isValid()) {
NS_WARNING("Int overflow in AudioSink");
mErrored = true;
return;
}
mFramesParsed = result.value();
}
mConverter =
MakeUnique<AudioConverter>(
AudioConfig(data->mChannels, data->mRate),
AudioConfig(mOutputChannels, mOutputRate));
}
// See if there's a gap in the audio. If there is, push silence into the
// audio hardware, so we can play across the gap.
// Calculate the timestamp of the next chunk of audio in numbers of
// samples.
CheckedInt64 sampleTime =
TimeUnitToFrames(data->mTime - mStartTime, data->mRate);
// Calculate the number of frames that have been pushed onto the audio hardware.
CheckedInt64 missingFrames = sampleTime - mFramesParsed;
if (!missingFrames.isValid()) {
NS_WARNING("Int overflow in AudioSink");
mErrored = true;
return;
}
if (missingFrames.value() > AUDIO_FUZZ_FRAMES) {
// The next audio packet begins some time after the end of the last packet
// we pushed to the audio hardware. We must push silence into the audio
// hardware so that the next audio packet begins playback at the correct
// time.
missingFrames = std::min<int64_t>(INT32_MAX, missingFrames.value());
mFramesParsed += missingFrames.value();
RefPtr<AudioData> silenceData;
AlignedAudioBuffer silenceBuffer(missingFrames.value() * data->mChannels);
if (!silenceBuffer) {
NS_WARNING("OOM in AudioSink");
mErrored = true;
return;
}
if (mConverter->InputConfig() != mConverter->OutputConfig()) {
AlignedAudioBuffer convertedData =
mConverter->Process(AudioSampleBuffer(Move(silenceBuffer))).Forget();
silenceData = CreateAudioFromBuffer(Move(convertedData), data);
} else {
silenceData = CreateAudioFromBuffer(Move(silenceBuffer), data);
}
PushProcessedAudio(silenceData);
}
mLastEndTime = data->GetEndTime();
mFramesParsed += data->mFrames;
if (mConverter->InputConfig() != mConverter->OutputConfig()) {
// We must ensure that the size in the buffer contains exactly the number
// of frames, in case one of the audio producer over allocated the buffer.
AlignedAudioBuffer buffer(Move(data->mAudioData));
buffer.SetLength(size_t(data->mFrames) * data->mChannels);
AlignedAudioBuffer convertedData =
mConverter->Process(AudioSampleBuffer(Move(buffer))).Forget();
//.........这里部分代码省略.........
示例10: MOZ_ASSERT
bool WebMReader::DecodeAudioPacket(NesteggPacketHolder* aHolder)
{
MOZ_ASSERT(OnTaskQueue());
int r = 0;
unsigned int count = 0;
r = nestegg_packet_count(aHolder->Packet(), &count);
if (r == -1) {
return false;
}
int64_t tstamp = aHolder->Timestamp();
if (mAudioStartUsec == -1) {
// This is the first audio chunk. Assume the start time of our decode
// is the start of this chunk.
mAudioStartUsec = tstamp;
}
// If there's a gap between the start of this audio chunk and the end of
// the previous audio chunk, we need to increment the packet count so that
// the vorbis decode doesn't use data from before the gap to help decode
// from after the gap.
CheckedInt64 tstamp_frames = UsecsToFrames(tstamp, mInfo.mAudio.mRate);
CheckedInt64 decoded_frames = UsecsToFrames(mAudioStartUsec,
mInfo.mAudio.mRate);
if (!tstamp_frames.isValid() || !decoded_frames.isValid()) {
NS_WARNING("Int overflow converting WebM times to frames");
return false;
}
decoded_frames += mAudioFrames;
if (!decoded_frames.isValid()) {
NS_WARNING("Int overflow adding decoded_frames");
return false;
}
if (tstamp_frames.value() > decoded_frames.value()) {
#ifdef DEBUG
int64_t gap_frames = tstamp_frames.value() - decoded_frames.value();
CheckedInt64 usecs = FramesToUsecs(gap_frames, mInfo.mAudio.mRate);
LOG(LogLevel::Debug, ("WebMReader detected gap of %lld, %lld frames, in audio",
usecs.isValid() ? usecs.value() : -1,
gap_frames));
#endif
mAudioStartUsec = tstamp;
mAudioFrames = 0;
}
int32_t total_frames = 0;
for (uint32_t i = 0; i < count; ++i) {
unsigned char* data;
size_t length;
r = nestegg_packet_data(aHolder->Packet(), i, &data, &length);
if (r == -1) {
return false;
}
int64_t discardPadding = 0;
(void) nestegg_packet_discard_padding(aHolder->Packet(), &discardPadding);
if (!mAudioDecoder->Decode(data, length, aHolder->Offset(), tstamp, discardPadding, &total_frames)) {
mHitAudioDecodeError = true;
return false;
}
}
mAudioFrames += total_frames;
return true;
}
示例11: MOZ_ASSERT
MediaResult
VorbisDataDecoder::DoDecode(MediaRawData* aSample)
{
MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
const unsigned char* aData = aSample->Data();
size_t aLength = aSample->Size();
int64_t aOffset = aSample->mOffset;
uint64_t aTstampUsecs = aSample->mTime;
int64_t aTotalFrames = 0;
MOZ_ASSERT(mPacketCount >= 3);
if (!mLastFrameTime || mLastFrameTime.ref() != aSample->mTime) {
// We are starting a new block.
mFrames = 0;
mLastFrameTime = Some(aSample->mTime);
}
ogg_packet pkt = InitVorbisPacket(aData, aLength, false, aSample->mEOS,
aSample->mTimecode, mPacketCount++);
int err = vorbis_synthesis(&mVorbisBlock, &pkt);
if (err) {
return MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
RESULT_DETAIL("vorbis_synthesis:%d", err));
}
err = vorbis_synthesis_blockin(&mVorbisDsp, &mVorbisBlock);
if (err) {
return MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
RESULT_DETAIL("vorbis_synthesis_blockin:%d", err));
}
VorbisPCMValue** pcm = 0;
int32_t frames = vorbis_synthesis_pcmout(&mVorbisDsp, &pcm);
if (frames == 0) {
return NS_OK;
}
while (frames > 0) {
uint32_t channels = mVorbisDsp.vi->channels;
uint32_t rate = mVorbisDsp.vi->rate;
AlignedAudioBuffer buffer(frames*channels);
if (!buffer) {
return MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__);
}
for (uint32_t j = 0; j < channels; ++j) {
VorbisPCMValue* channel = pcm[j];
for (uint32_t i = 0; i < uint32_t(frames); ++i) {
buffer[i*channels + j] = MOZ_CONVERT_VORBIS_SAMPLE(channel[i]);
}
}
CheckedInt64 duration = FramesToUsecs(frames, rate);
if (!duration.isValid()) {
return MediaResult(NS_ERROR_DOM_MEDIA_OVERFLOW_ERR,
RESULT_DETAIL("Overflow converting audio duration"));
}
CheckedInt64 total_duration = FramesToUsecs(mFrames, rate);
if (!total_duration.isValid()) {
return MediaResult(
NS_ERROR_DOM_MEDIA_OVERFLOW_ERR,
RESULT_DETAIL("Overflow converting audio total_duration"));
}
CheckedInt64 time = total_duration + aTstampUsecs;
if (!time.isValid()) {
return MediaResult(
NS_ERROR_DOM_MEDIA_OVERFLOW_ERR,
RESULT_DETAIL("Overflow adding total_duration and aTstampUsecs"));
};
if (!mAudioConverter) {
AudioConfig in(AudioConfig::ChannelLayout(channels, VorbisLayout(channels)),
rate);
AudioConfig out(channels, rate);
if (!in.IsValid() || !out.IsValid()) {
return MediaResult(
NS_ERROR_DOM_MEDIA_FATAL_ERR,
RESULT_DETAIL("Invalid channel layout:%u", channels));
}
mAudioConverter = MakeUnique<AudioConverter>(in, out);
}
MOZ_ASSERT(mAudioConverter->CanWorkInPlace());
AudioSampleBuffer data(Move(buffer));
data = mAudioConverter->Process(Move(data));
aTotalFrames += frames;
mCallback->Output(new AudioData(aOffset,
time.value(),
duration.value(),
frames,
data.Forget(),
channels,
rate));
mFrames += frames;
err = vorbis_synthesis_read(&mVorbisDsp, frames);
if (err) {
return MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
RESULT_DETAIL("vorbis_synthesis_read:%d", err));
//.........这里部分代码省略.........
示例12: SendStreamAudio
static void
SendStreamAudio(DecodedStreamData* aStream, int64_t aStartTime,
MediaData* aData, AudioSegment* aOutput,
uint32_t aRate, double aVolume)
{
MOZ_ASSERT(aData);
AudioData* audio = aData->As<AudioData>();
// This logic has to mimic AudioSink closely to make sure we write
// the exact same silences
CheckedInt64 audioWrittenOffset = aStream->mAudioFramesWritten +
UsecsToFrames(aStartTime, aRate);
CheckedInt64 frameOffset = UsecsToFrames(audio->mTime, aRate);
if (!audioWrittenOffset.isValid() ||
!frameOffset.isValid() ||
// ignore packet that we've already processed
frameOffset.value() + audio->mFrames <= audioWrittenOffset.value()) {
return;
}
if (audioWrittenOffset.value() < frameOffset.value()) {
int64_t silentFrames = frameOffset.value() - audioWrittenOffset.value();
// Write silence to catch up
AudioSegment silence;
silence.InsertNullDataAtStart(silentFrames);
aStream->mAudioFramesWritten += silentFrames;
audioWrittenOffset += silentFrames;
aOutput->AppendFrom(&silence);
}
MOZ_ASSERT(audioWrittenOffset.value() >= frameOffset.value());
int64_t offset = audioWrittenOffset.value() - frameOffset.value();
size_t framesToWrite = audio->mFrames - offset;
audio->EnsureAudioBuffer();
nsRefPtr<SharedBuffer> buffer = audio->mAudioBuffer;
AudioDataValue* bufferData = static_cast<AudioDataValue*>(buffer->Data());
nsAutoTArray<const AudioDataValue*, 2> channels;
for (uint32_t i = 0; i < audio->mChannels; ++i) {
channels.AppendElement(bufferData + i * audio->mFrames + offset);
}
aOutput->AppendFrames(buffer.forget(), channels, framesToWrite);
aStream->mAudioFramesWritten += framesToWrite;
aOutput->ApplyVolume(aVolume);
aStream->mNextAudioTime = audio->GetEndTime();
}
示例13: MOZ_ASSERT
int
VorbisDataDecoder::DoDecode(MediaRawData* aSample)
{
const unsigned char* aData = aSample->Data();
size_t aLength = aSample->Size();
int64_t aOffset = aSample->mOffset;
uint64_t aTstampUsecs = aSample->mTime;
int64_t aTotalFrames = 0;
MOZ_ASSERT(mPacketCount >= 3);
if (!mLastFrameTime || mLastFrameTime.ref() != aSample->mTime) {
// We are starting a new block.
mFrames = 0;
mLastFrameTime = Some(aSample->mTime);
}
ogg_packet pkt = InitVorbisPacket(aData, aLength, false, false, -1, mPacketCount++);
bool first_packet = mPacketCount == 4;
if (vorbis_synthesis(&mVorbisBlock, &pkt) != 0) {
return -1;
}
if (vorbis_synthesis_blockin(&mVorbisDsp,
&mVorbisBlock) != 0) {
return -1;
}
VorbisPCMValue** pcm = 0;
int32_t frames = vorbis_synthesis_pcmout(&mVorbisDsp, &pcm);
// If the first packet of audio in the media produces no data, we
// still need to produce an AudioData for it so that the correct media
// start time is calculated. Otherwise we'd end up with a media start
// time derived from the timecode of the first packet that produced
// data.
if (frames == 0 && first_packet) {
mCallback->Output(new AudioData(aOffset,
aTstampUsecs,
0,
0,
nullptr,
mVorbisDsp.vi->channels,
mVorbisDsp.vi->rate));
}
while (frames > 0) {
uint32_t channels = mVorbisDsp.vi->channels;
auto buffer = MakeUnique<AudioDataValue[]>(frames*channels);
for (uint32_t j = 0; j < channels; ++j) {
VorbisPCMValue* channel = pcm[j];
for (uint32_t i = 0; i < uint32_t(frames); ++i) {
buffer[i*channels + j] = MOZ_CONVERT_VORBIS_SAMPLE(channel[i]);
}
}
CheckedInt64 duration = FramesToUsecs(frames, mVorbisDsp.vi->rate);
if (!duration.isValid()) {
NS_WARNING("Int overflow converting WebM audio duration");
return -1;
}
CheckedInt64 total_duration = FramesToUsecs(mFrames,
mVorbisDsp.vi->rate);
if (!total_duration.isValid()) {
NS_WARNING("Int overflow converting WebM audio total_duration");
return -1;
}
CheckedInt64 time = total_duration + aTstampUsecs;
if (!time.isValid()) {
NS_WARNING("Int overflow adding total_duration and aTstampUsecs");
return -1;
};
aTotalFrames += frames;
mCallback->Output(new AudioData(aOffset,
time.value(),
duration.value(),
frames,
Move(buffer),
mVorbisDsp.vi->channels,
mVorbisDsp.vi->rate));
mFrames += frames;
if (vorbis_synthesis_read(&mVorbisDsp, frames) != 0) {
return -1;
}
frames = vorbis_synthesis_pcmout(&mVorbisDsp, &pcm);
}
return aTotalFrames > 0 ? 1 : 0;
}
示例14: MOZ_ASSERT
bool
WaveReader::LoadAllChunks(nsAutoPtr<dom::HTMLMediaElement::MetadataTags> &aTags)
{
// Chunks are always word (two byte) aligned.
MOZ_ASSERT(mDecoder->GetResource()->Tell() % 2 == 0,
"LoadAllChunks called with unaligned resource");
bool loadFormatChunk = false;
bool findDataOffset = false;
for (;;) {
static const unsigned int CHUNK_HEADER_SIZE = 8;
char chunkHeader[CHUNK_HEADER_SIZE];
const char* p = chunkHeader;
if (!ReadAll(chunkHeader, sizeof(chunkHeader))) {
return false;
}
static_assert(sizeof(uint32_t) * 2 <= CHUNK_HEADER_SIZE,
"Reads would overflow chunkHeader buffer.");
uint32_t magic = ReadUint32BE(&p);
uint32_t chunkSize = ReadUint32LE(&p);
int64_t chunkStart = GetPosition();
switch (magic) {
case FRMT_CHUNK_MAGIC:
loadFormatChunk = LoadFormatChunk(chunkSize);
if (!loadFormatChunk) {
return false;
}
break;
case LIST_CHUNK_MAGIC:
if (!aTags) {
LoadListChunk(chunkSize, aTags);
}
break;
case DATA_CHUNK_MAGIC:
findDataOffset = FindDataOffset(chunkSize);
return loadFormatChunk && findDataOffset;
default:
break;
}
// RIFF chunks are two-byte aligned, so round up if necessary.
chunkSize += chunkSize % 2;
// Move forward to next chunk
CheckedInt64 forward = CheckedInt64(chunkStart) + chunkSize - GetPosition();
if (!forward.isValid() || forward.value() < 0) {
return false;
}
static const int64_t MAX_CHUNK_SIZE = 1 << 16;
static_assert(uint64_t(MAX_CHUNK_SIZE) < UINT_MAX / sizeof(char),
"MAX_CHUNK_SIZE too large for enumerator.");
nsAutoArrayPtr<char> chunk(new char[MAX_CHUNK_SIZE]);
while (forward.value() > 0) {
int64_t size = std::min(forward.value(), MAX_CHUNK_SIZE);
if (!ReadAll(chunk.get(), size)) {
return false;
}
forward -= size;
}
}
return false;
}
示例15: NS_ASSERTION
bool SkeletonState::DecodeIndex(ogg_packet* aPacket)
{
NS_ASSERTION(aPacket->bytes >= SKELETON_4_0_MIN_INDEX_LEN,
"Index must be at least minimum size");
if (!mActive) {
return false;
}
uint32_t serialno = LittleEndian::readUint32(aPacket->packet + INDEX_SERIALNO_OFFSET);
int64_t numKeyPoints = LittleEndian::readInt64(aPacket->packet + INDEX_NUM_KEYPOINTS_OFFSET);
int64_t endTime = 0, startTime = 0;
const unsigned char* p = aPacket->packet;
int64_t timeDenom = LittleEndian::readInt64(aPacket->packet + INDEX_TIME_DENOM_OFFSET);
if (timeDenom == 0) {
LOG(PR_LOG_DEBUG, ("Ogg Skeleton Index packet for stream %u has 0 "
"timestamp denominator.", serialno));
return (mActive = false);
}
// Extract the start time.
CheckedInt64 t = CheckedInt64(LittleEndian::readInt64(p + INDEX_FIRST_NUMER_OFFSET)) * USECS_PER_S;
if (!t.isValid()) {
return (mActive = false);
} else {
startTime = t.value() / timeDenom;
}
// Extract the end time.
t = LittleEndian::readInt64(p + INDEX_LAST_NUMER_OFFSET) * USECS_PER_S;
if (!t.isValid()) {
return (mActive = false);
} else {
endTime = t.value() / timeDenom;
}
// Check the numKeyPoints value read, ensure we're not going to run out of
// memory while trying to decode the index packet.
CheckedInt64 minPacketSize = (CheckedInt64(numKeyPoints) * MIN_KEY_POINT_SIZE) + INDEX_KEYPOINT_OFFSET;
if (!minPacketSize.isValid())
{
return (mActive = false);
}
int64_t sizeofIndex = aPacket->bytes - INDEX_KEYPOINT_OFFSET;
int64_t maxNumKeyPoints = sizeofIndex / MIN_KEY_POINT_SIZE;
if (aPacket->bytes < minPacketSize.value() ||
numKeyPoints > maxNumKeyPoints ||
numKeyPoints < 0)
{
// Packet size is less than the theoretical minimum size, or the packet is
// claiming to store more keypoints than it's capable of storing. This means
// that the numKeyPoints field is too large or small for the packet to
// possibly contain as many packets as it claims to, so the numKeyPoints
// field is possibly malicious. Don't try decoding this index, we may run
// out of memory.
LOG(PR_LOG_DEBUG, ("Possibly malicious number of key points reported "
"(%lld) in index packet for stream %u.",
numKeyPoints,
serialno));
return (mActive = false);
}
nsAutoPtr<nsKeyFrameIndex> keyPoints(new nsKeyFrameIndex(startTime, endTime));
p = aPacket->packet + INDEX_KEYPOINT_OFFSET;
const unsigned char* limit = aPacket->packet + aPacket->bytes;
int64_t numKeyPointsRead = 0;
CheckedInt64 offset = 0;
CheckedInt64 time = 0;
while (p < limit &&
numKeyPointsRead < numKeyPoints)
{
int64_t delta = 0;
p = ReadVariableLengthInt(p, limit, delta);
offset += delta;
if (p == limit ||
!offset.isValid() ||
offset.value() > mLength ||
offset.value() < 0)
{
return (mActive = false);
}
p = ReadVariableLengthInt(p, limit, delta);
time += delta;
if (!time.isValid() ||
time.value() > endTime ||
time.value() < startTime)
{
return (mActive = false);
}
CheckedInt64 timeUsecs = time * USECS_PER_S;
if (!timeUsecs.isValid())
return mActive = false;
timeUsecs /= timeDenom;
keyPoints->Add(offset.value(), timeUsecs.value());
numKeyPointsRead++;
}
//.........这里部分代码省略.........