Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(732)

Side by Side Diff: media/audio/sounds/wav_audio_handler.cc

Issue 1453233002: Improve input handling for WaveAudioHandler. (Closed) Base URL: https://chromium.googlesource.com/chromium/src@master
Patch Set: Correct typo Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/audio/sounds/wav_audio_handler.h" 5 #include "media/audio/sounds/wav_audio_handler.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cstring> 8 #include <cstring>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 result = base::ByteSwap(result); 48 result = base::ByteSwap(result);
49 #endif 49 #endif
50 return result; 50 return result;
51 } 51 }
52 52
53 } // namespace 53 } // namespace
54 54
55 namespace media { 55 namespace media {
56 56
57 WavAudioHandler::WavAudioHandler(const base::StringPiece& wav_data) 57 WavAudioHandler::WavAudioHandler(const base::StringPiece& wav_data)
58 : num_channels_(0), sample_rate_(0), bits_per_sample_(0), total_frames_(0) { 58 : is_valid_(false),
59 CHECK_LE(kWavFileHeaderSize, wav_data.size()) << "wav data is too small"; 59 num_channels_(0),
60 CHECK(wav_data.starts_with(kChunkId) && 60 sample_rate_(0),
61 memcmp(wav_data.data() + 8, kFormat, 4) == 0) 61 bits_per_sample_(0),
62 << "incorrect wav header"; 62 total_frames_(0) {
63 if (wav_data.size() < kWavFileHeaderSize) {
64 LOG(ERROR) << "wav_data is too small";
65 return;
66 }
67 if (!wav_data.starts_with(kChunkId) ||
68 memcmp(wav_data.data() + 8, kFormat, 4) != 0) {
69 LOG(ERROR) << "incorrect wav header";
70 return;
71 }
63 72
64 uint32 total_length = std::min(ReadInt<uint32>(wav_data, 4), 73 uint32 total_length = std::min(ReadInt<uint32>(wav_data, 4),
65 static_cast<uint32>(wav_data.size())); 74 static_cast<uint32>(wav_data.size()));
66 uint32 offset = kWavFileHeaderSize; 75 uint32 offset = kWavFileHeaderSize;
67 while (offset < total_length) { 76 while (offset < total_length) {
68 const int length = ParseSubChunk(wav_data.substr(offset)); 77 const int length = ParseSubChunk(wav_data.substr(offset));
69 CHECK_LE(0, length) << "can't parse wav sub-chunk"; 78 if (length < 0) {
79 LOG(ERROR) << "can't parse wav sub-chunk";
80 ResetAll();
81 return;
82 }
70 offset += length; 83 offset += length;
71 } 84 }
72 85
86 if (num_channels_ == 0u || bits_per_sample_ == 0u || sample_rate_ == 0u) {
tommi (sloooow) - chröme 2015/11/17 20:48:39 nit: could this expression be is_valid() or do we
slan 2015/11/17 21:50:16 Done.
87 LOG(ERROR) << "Format is invalid. "
88 << "num_channels: " << num_channels_ << " "
89 << "sample_rate: " << sample_rate_ << " "
90 << "bits_per_sample: " << bits_per_sample_;
91 ResetAll();
92 return;
93 }
94
95 // The audio chunk has parsed successfully.
96 is_valid_ = true;
73 total_frames_ = data_.size() * 8 / num_channels_ / bits_per_sample_; 97 total_frames_ = data_.size() * 8 / num_channels_ / bits_per_sample_;
74 } 98 }
75 99
76 WavAudioHandler::~WavAudioHandler() {} 100 WavAudioHandler::~WavAudioHandler() {}
77 101
78 bool WavAudioHandler::AtEnd(size_t cursor) const { 102 bool WavAudioHandler::AtEnd(size_t cursor) const {
79 return data_.size() <= cursor; 103 return is_valid_ ? data_.size() <= cursor : true;
tommi (sloooow) - chröme 2015/11/17 20:48:39 nit: could also do return !is_valid() || data_.siz
slan 2015/11/17 21:50:16 In practice, this object should not be used if is_
tommi (sloooow) - chröme 2015/11/18 11:52:58 That sounds like a good idea to me and would simpl
80 } 104 }
81 105
82 bool WavAudioHandler::CopyTo(AudioBus* bus, 106 bool WavAudioHandler::CopyTo(AudioBus* bus,
83 size_t cursor, 107 size_t cursor,
84 size_t* bytes_written) const { 108 size_t* bytes_written) const {
85 if (!bus) 109 if (!is_valid_ || !bus)
86 return false; 110 return false;
87 if (bus->channels() != num_channels_) { 111 if (bus->channels() != num_channels_) {
88 DVLOG(1) << "Number of channels mismatch."; 112 DVLOG(1) << "Number of channels mismatch.";
89 return false; 113 return false;
90 } 114 }
91 if (AtEnd(cursor)) { 115 if (AtEnd(cursor)) {
92 bus->Zero(); 116 bus->Zero();
93 return true; 117 return true;
94 } 118 }
95 const int bytes_per_frame = num_channels_ * bits_per_sample_ / 8; 119 const int bytes_per_frame = num_channels_ * bits_per_sample_ / 8;
96 const int remaining_frames = (data_.size() - cursor) / bytes_per_frame; 120 const int remaining_frames = (data_.size() - cursor) / bytes_per_frame;
97 const int frames = std::min(bus->frames(), remaining_frames); 121 const int frames = std::min(bus->frames(), remaining_frames);
98 122
99 bus->FromInterleaved(data_.data() + cursor, frames, bits_per_sample_ / 8); 123 bus->FromInterleaved(data_.data() + cursor, frames, bits_per_sample_ / 8);
100 *bytes_written = frames * bytes_per_frame; 124 *bytes_written = frames * bytes_per_frame;
101 bus->ZeroFramesPartial(frames, bus->frames() - frames); 125 bus->ZeroFramesPartial(frames, bus->frames() - frames);
102 return true; 126 return true;
103 } 127 }
104 128
105 base::TimeDelta WavAudioHandler::GetDuration() const { 129 base::TimeDelta WavAudioHandler::GetDuration() const {
106 return base::TimeDelta::FromSecondsD(total_frames_ / 130 return is_valid_ ? base::TimeDelta::FromSecondsD(
107 static_cast<double>(sample_rate_)); 131 total_frames_ / static_cast<double>(sample_rate_))
132 : base::TimeDelta();
108 } 133 }
109 134
110 int WavAudioHandler::ParseSubChunk(const base::StringPiece& data) { 135 int WavAudioHandler::ParseSubChunk(const base::StringPiece& data) {
111 if (data.size() < kChunkHeaderSize) 136 if (data.size() < kChunkHeaderSize)
112 return data.size(); 137 return data.size();
113 uint32 chunk_length = ReadInt<uint32>(data, 4); 138 uint32 chunk_length = ReadInt<uint32>(data, 4);
114 if (data.starts_with(kSubchunk1Id)) { 139 if (data.starts_with(kSubchunk1Id)) {
115 if (!ParseFmtChunk(data.substr(kChunkHeaderSize, chunk_length))) 140 if (!ParseFmtChunk(data.substr(kChunkHeaderSize, chunk_length)))
116 return -1; 141 return -1;
117 } else if (data.starts_with(kSubchunk2Id)) { 142 } else if (data.starts_with(kSubchunk2Id)) {
(...skipping 15 matching lines...) Expand all
133 sample_rate_ = ReadInt<uint32>(data, kSampleRateOffset); 158 sample_rate_ = ReadInt<uint32>(data, kSampleRateOffset);
134 bits_per_sample_ = ReadInt<uint16>(data, kBitsPerSampleOffset); 159 bits_per_sample_ = ReadInt<uint16>(data, kBitsPerSampleOffset);
135 return true; 160 return true;
136 } 161 }
137 162
138 bool WavAudioHandler::ParseDataChunk(const base::StringPiece& data) { 163 bool WavAudioHandler::ParseDataChunk(const base::StringPiece& data) {
139 data_ = data; 164 data_ = data;
140 return true; 165 return true;
141 } 166 }
142 167
168 void WavAudioHandler::ResetAll() {
169 DCHECK(!is_valid_);
170 data_ = base::StringPiece();
tommi (sloooow) - chröme 2015/11/17 20:48:39 another potential implementation for is_valid();
slan 2015/11/17 21:50:16 I like the idea you left above. Theoretically, we
171 num_channels_ = 0u;
172 sample_rate_ = 0u;
173 bits_per_sample_ = 0u;
174 total_frames_ = 0u;
175 }
176
143 } // namespace media 177 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698