summaryrefslogtreecommitdiffstats
path: root/media/base/audio_buffer.cc
diff options
context:
space:
mode:
authordalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-03 02:08:23 +0000
committerdalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-03 02:08:23 +0000
commita6c2d93ff440b7693f35f7fc576f5818c638e6da (patch)
tree470f103d972769bfb9d4382019ae841a77e0b247 /media/base/audio_buffer.cc
parentec37323959db7c1d7b388dc08b1d318ddb46ec06 (diff)
downloadchromium_src-a6c2d93ff440b7693f35f7fc576f5818c638e6da.zip
chromium_src-a6c2d93ff440b7693f35f7fc576f5818c638e6da.tar.gz
chromium_src-a6c2d93ff440b7693f35f7fc576f5818c638e6da.tar.bz2
Support start trimming post-decoding. Use it with FFmpegDemuxer.
FFmpeg has packet side data indicating how many frames should be trimmed after decoding, we should use it to improve playback of mp3 and aac audio via <audio> tag. Specifically: - AudioBuffer:TrimRange(start,end) is now supported. - DecoderBuffer:discard_padding() is now a pair of (front, back) which indicates how much to trim off the front and rear of the data corresponding to the encoded buffer. - AudioDiscardHelper has been updated to implement this trimming. - FFmpegDemuxer inserts FFmpeg's skip_samples into DecoderBuffer. This change paves the way for MediaSource to use this feature to implement gapless playback support. BUG=360961 TEST=new unittests! NOTRY=true Review URL: https://codereview.chromium.org/251893002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@268002 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/base/audio_buffer.cc')
-rw-r--r--media/base/audio_buffer.cc43
1 files changed, 43 insertions, 0 deletions
diff --git a/media/base/audio_buffer.cc b/media/base/audio_buffer.cc
index 08bb1e3..33d4ecb 100644
--- a/media/base/audio_buffer.cc
+++ b/media/base/audio_buffer.cc
@@ -266,4 +266,47 @@ void AudioBuffer::TrimEnd(int frames_to_trim) {
duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_);
}
+void AudioBuffer::TrimRange(int start, int end) {
+ CHECK_GE(start, 0);
+ CHECK_LE(end, adjusted_frame_count_);
+
+ const int frames_to_trim = end - start;
+ CHECK_GE(frames_to_trim, 0);
+ CHECK_LE(frames_to_trim, adjusted_frame_count_);
+
+ const int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format_);
+ const int frames_to_copy = adjusted_frame_count_ - end;
+ if (frames_to_copy > 0) {
+ switch (sample_format_) {
+ case kSampleFormatPlanarS16:
+ case kSampleFormatPlanarF32:
+ // Planar data must be shifted per channel.
+ for (int ch = 0; ch < channel_count_; ++ch) {
+ memmove(channel_data_[ch] + (trim_start_ + start) * bytes_per_channel,
+ channel_data_[ch] + (trim_start_ + end) * bytes_per_channel,
+ bytes_per_channel * frames_to_copy);
+ }
+ break;
+ case kSampleFormatU8:
+ case kSampleFormatS16:
+ case kSampleFormatS32:
+ case kSampleFormatF32: {
+ // Interleaved data can be shifted all at once.
+ const int frame_size = channel_count_ * bytes_per_channel;
+ memmove(channel_data_[0] + (trim_start_ + start) * frame_size,
+ channel_data_[0] + (trim_start_ + end) * frame_size,
+ frame_size * frames_to_copy);
+ break;
+ }
+ case kUnknownSampleFormat:
+ NOTREACHED() << "Invalid sample format!";
+ }
+ } else {
+ CHECK_EQ(frames_to_copy, 0);
+ }
+
+ // Trim the leftover data off the end of the buffer and update duration.
+ TrimEnd(frames_to_trim);
+}
+
} // namespace media