summaryrefslogtreecommitdiffstats
path: root/media/audio/null_audio_sink.cc
diff options
context:
space:
mode:
authordalecurtis@google.com <dalecurtis@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-01 23:22:14 +0000
committerdalecurtis@google.com <dalecurtis@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-01 23:22:14 +0000
commit532f5ce2dad3f5b49166ec0a21a7f9d875605bdb (patch)
treee0d54371949f055c642b41ccc30c30a4e8d07036 /media/audio/null_audio_sink.cc
parent5252c891ca0f5e1fad81adcd86d7889ecf0abc9f (diff)
downloadchromium_src-532f5ce2dad3f5b49166ec0a21a7f9d875605bdb.zip
chromium_src-532f5ce2dad3f5b49166ec0a21a7f9d875605bdb.tar.gz
chromium_src-532f5ce2dad3f5b49166ec0a21a7f9d875605bdb.tar.bz2
Fix audio hashing. Split hash tests out of normal test.
The previous hashing code didn't work for a few reasons: - Underflow situations (valgrind, etc) would result in different hashes due to silence we output during underflow. - Hashing was endian specific, so tests would fail on ARM. - Each FillBufferTask hashed all the audio data for all channels each time, which breaks when frames_recieved varies under load. The above have been fixed: - Hash tests are split out into new BasicPlaybackHashed test. - Underflow is now disabled for audio hash testing. - Hashes are computed in little-endian byte order. - A separate hash context is maintained for each channel and only reduced to a single hash at the end. BUG=129284 TEST=media_unittests under valgrind/tsan. Review URL: https://chromiumcodereview.appspot.com/10444120 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@140123 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/audio/null_audio_sink.cc')
-rw-r--r--media/audio/null_audio_sink.cc38
1 files changed, 28 insertions, 10 deletions
diff --git a/media/audio/null_audio_sink.cc b/media/audio/null_audio_sink.cc
index b6a921c..b2674fb 100644
--- a/media/audio/null_audio_sink.cc
+++ b/media/audio/null_audio_sink.cc
@@ -6,6 +6,7 @@
#include "base/bind.h"
#include "base/stringprintf.h"
+#include "base/sys_byteorder.h"
#include "base/threading/platform_thread.h"
namespace media {
@@ -30,6 +31,12 @@ void NullAudioSink::Initialize(const AudioParameters& params,
audio_data_.push_back(channel_data);
}
+ if (hash_audio_for_testing_) {
+ md5_channel_contexts_.reset(new base::MD5Context[params.channels()]);
+ for (int i = 0; i < params.channels(); i++)
+ base::MD5Init(&md5_channel_contexts_[i]);
+ }
+
callback_ = callback;
initialized_ = true;
}
@@ -93,15 +100,18 @@ void NullAudioSink::FillBufferTask() {
int frames_per_millisecond =
params_.sample_rate() / base::Time::kMillisecondsPerSecond;
- if (hash_audio_for_testing_) {
+ if (hash_audio_for_testing_ && frames_received > 0) {
+ DCHECK_EQ(sizeof(float), sizeof(uint32));
int channels = audio_data_.size();
- // Include hash of channel count in case frames_received == 0.
- base::MD5Update(&md5_context_, base::StringPiece(
- base::StringPrintf("%d", channels)));
- for (int channel_index = 0; channel_index < channels; ++channel_index) {
- base::MD5Update(&md5_context_, base::StringPiece(
- reinterpret_cast<char*>(audio_data_[channel_index]),
- sizeof(float) * frames_received));
+ for (int channel_idx = 0; channel_idx < channels; ++channel_idx) {
+ for (int frame_idx = 0; frame_idx < frames_received; frame_idx++) {
+ // Convert float to uint32 w/o conversion loss.
+ uint32 frame = base::ByteSwapToLE32(*reinterpret_cast<uint32*>(
+ &audio_data_[channel_idx][frame_idx]));
+ base::MD5Update(
+ &md5_channel_contexts_[channel_idx], base::StringPiece(
+ reinterpret_cast<char*>(&frame), sizeof(frame)));
+ }
}
}
@@ -121,14 +131,22 @@ void NullAudioSink::FillBufferTask() {
}
void NullAudioSink::StartAudioHashForTesting() {
+ DCHECK(!initialized_);
hash_audio_for_testing_ = true;
- base::MD5Init(&md5_context_);
}
std::string NullAudioSink::GetAudioHashForTesting() {
DCHECK(hash_audio_for_testing_);
+
+ // Hash all channels into the first channel.
base::MD5Digest digest;
- base::MD5Final(&digest, &md5_context_);
+ for (size_t i = 1; i < audio_data_.size(); i++) {
+ base::MD5Final(&digest, &md5_channel_contexts_[i]);
+ base::MD5Update(&md5_channel_contexts_[0], base::StringPiece(
+ reinterpret_cast<char*>(&digest), sizeof(base::MD5Digest)));
+ }
+
+ base::MD5Final(&digest, &md5_channel_contexts_[0]);
return base::MD5DigestToBase16(digest);
}