Bug 717026 - Ensure libsydneyaudio windows block size is an even multiple of channels*frame_size. r=kinetik

This commit is contained in:
Chris Pearce 2012-01-19 14:11:51 +13:00
Родитель bdf9362d41
Коммит 3333e53c6b
2 изменённых файлов: 16 добавлений и 10 удалений

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

@ -631,7 +631,6 @@ void nsBuiltinDecoderStateMachine::AudioLoop()
LOG(PR_LOG_DEBUG, ("%p Begun audio thread/loop", mDecoder.get()));
PRInt64 audioDuration = 0;
PRInt64 audioStartTime = -1;
PRInt64 framesWritten = 0;
PRUint32 channels, rate;
double volume = -1;
bool setVolume;
@ -746,6 +745,7 @@ void nsBuiltinDecoderStateMachine::AudioLoop()
break;
}
PRInt64 framesWritten = 0;
if (missingFrames > 0) {
// 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
@ -780,18 +780,22 @@ void nsBuiltinDecoderStateMachine::AudioLoop()
bool seeking = false;
{
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
if (framesWritten < minWriteFrames) {
// We've not written minWriteFrames in the last write, the audio
// may not start playing. Write silence to ensure we've got enough
// written to start playback.
PRInt64 minToWrite = minWriteFrames - framesWritten;
if (minToWrite < PR_UINT32_MAX / channels) {
PRInt64 unplayedFrames = audioDuration % minWriteFrames;
if (minWriteFrames > 1 && unplayedFrames > 0) {
// Sound is written by libsydneyaudio to the hardware in blocks of
// frames of size minWriteFrames. So if the number of frames we've
// written isn't an exact multiple of minWriteFrames, we'll have
// left over audio data which hasn't yet been written to the hardware,
// and so that audio will not start playing. Write silence to ensure
// the last block gets pushed to hardware, so that playback starts.
PRInt64 framesToWrite = minWriteFrames - unplayedFrames;
if (framesToWrite < PR_UINT32_MAX / channels) {
// Write silence manually rather than using PlaySilence(), so that
// the AudioAPI doesn't get a copy of the audio frames.
PRUint32 numSamples = minToWrite * channels;
PRUint32 numSamples = framesToWrite * channels;
nsAutoArrayPtr<AudioDataValue> buf(new AudioDataValue[numSamples]);
memset(buf.get(), 0, numSamples * sizeof(AudioDataValue));
mAudioStream->Write(buf, minToWrite);
mAudioStream->Write(buf, framesToWrite);
}
}

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

@ -169,10 +169,12 @@ int sa_stream_create_pcm(sa_stream_t **s,
_s->deviceName = DEFAULT_DEVICE_NAME;
_s->device = DEFAULT_DEVICE;
_s->playing = 0;
_s->blockSize = BYTES_PER_SAMPLE * ((rate * nchannels * BLOCK_DURATION_MS) / 1000);
_s->blockSize = BYTES_PER_SAMPLE * nchannels * ((rate * BLOCK_DURATION_MS) / 1000);
/* Other parts of the code assumes that the block size is evenly
divisible by 2. */
assert((_s->blockSize & 1) != 1);
assert((_s->blockSize % BYTES_PER_SAMPLE) == 0);
assert(((_s->blockSize / BYTES_PER_SAMPLE) % nchannels) == 0);
*s = _s;
return SA_SUCCESS;
}