bug 822956: Handle audio chunks that aren't 10ms in duration r=ekr

This commit is contained in:
Maire Reavy 2013-01-03 18:37:55 -05:00
parent 241adf9d26
commit fbc9c3a8b2
2 changed files with 72 additions and 4 deletions

View File

@ -691,8 +691,66 @@ void MediaPipelineTransmit::PipelineListener::ProcessAudioChunk(
}
}
MOZ_MTLOG(PR_LOG_DEBUG, "Sending an audio frame");
conduit->SendAudioFrame(samples.get(), chunk.mDuration, rate, 0);
MOZ_ASSERT(!(rate%100)); // rate should be a multiple of 100
// Check if the rate has changed since the last time we came through
// I realize it may be overkill to check if the rate has changed, but
// I believe it is possible (e.g. if we change sources) and it costs us
// very little to handle this case
if (samplenum_10ms_ != rate/100) {
// Determine number of samples in 10 ms from the rate:
samplenum_10ms_ = rate/100;
// If we switch sample rates (e.g. if we switch codecs),
// we throw away what was in the sample_10ms_buffer at the old rate
samples_10ms_buffer_ = new int16_t[samplenum_10ms_];
buffer_current_ = 0;
}
// Vars to handle the non-sunny-day case (where the audio chunks
// we got are not multiples of 10ms OR there were samples left over
// from the last run)
int64_t chunk_remaining;
int64_t tocpy;
int16_t *samples_tmp = samples.get();
chunk_remaining = chunk.mDuration;
MOZ_ASSERT(chunk_remaining >= 0);
if (buffer_current_) {
tocpy = std::min(chunk_remaining, samplenum_10ms_ - buffer_current_);
memcpy(&samples_10ms_buffer_[buffer_current_], samples_tmp, tocpy * sizeof(int16_t));
buffer_current_ += tocpy;
samples_tmp += tocpy;
chunk_remaining -= tocpy;
if (buffer_current_ == samplenum_10ms_) {
// Send out the audio buffer we just finished filling
conduit->SendAudioFrame(samples_10ms_buffer_, samplenum_10ms_, rate, 0);
buffer_current_ = 0;
} else {
// We still don't have enough data to send a buffer
return;
}
}
// Now send (more) frames if there is more than 10ms of input left
tocpy = (chunk_remaining / samplenum_10ms_) * samplenum_10ms_;
if (tocpy > 0) {
conduit->SendAudioFrame(samples_tmp, tocpy, rate, 0);
samples_tmp += tocpy;
chunk_remaining = chunk.mDuration - tocpy;
}
// Copy what remains for the next run
MOZ_ASSERT(chunk_remaining < samplenum_10ms_);
if (chunk_remaining) {
memcpy(samples_10ms_buffer_, samples_tmp, chunk_remaining * sizeof(int16_t));
buffer_current_ = chunk_remaining;
}
}
#ifdef MOZILLA_INTERNAL_API

View File

@ -253,9 +253,10 @@ class MediaPipelineTransmit : public MediaPipeline {
class PipelineListener : public MediaStreamListener {
public:
PipelineListener(const RefPtr<MediaSessionConduit>& conduit)
: conduit_(conduit), active_(false) {}
: conduit_(conduit), active_(false), samples_10ms_buffer_(nullptr),
buffer_current_(0), samplenum_10ms_(0){}
// XXX. This is not thread-safe but the hazard is just
// XXX. This is not thread-safe but the hazard is just
// that active_ = true takes a while to propagate. Revisit
// when 823600 lands.
void SetActive(bool active) { active_ = active; }
@ -277,6 +278,15 @@ class MediaPipelineTransmit : public MediaPipeline {
#endif
RefPtr<MediaSessionConduit> conduit_;
volatile bool active_;
// These vars handle breaking audio samples into exact 10ms chunks:
// The buffer of 10ms audio samples that we will send once full
// (can be carried over from one call to another).
nsAutoArrayPtr<int16_t> samples_10ms_buffer_;
// The location of the pointer within that buffer (in units of samples).
int64_t buffer_current_;
// The number of samples in a 10ms audio chunk.
int64_t samplenum_10ms_;
};
private: