diff options
author | dalecurtis <dalecurtis@chromium.org> | 2016-01-06 11:48:00 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-01-06 19:49:08 +0000 |
commit | c0baf4af90ffad9436aa0c432d70365e28559219 (patch) | |
tree | aeadce6c64ba8cef57a7a3aeb2ac3fd5ac019e7c | |
parent | f0107588610d8beec57308c7820ca25b4f9d47b8 (diff) | |
download | chromium_src-c0baf4af90ffad9436aa0c432d70365e28559219.zip chromium_src-c0baf4af90ffad9436aa0c432d70365e28559219.tar.gz chromium_src-c0baf4af90ffad9436aa0c432d70365e28559219.tar.bz2 |
Replace WebAudio MediaCodec usage with FFmpeg. A ~4x improvement.
Now that ffmpeg is linked in for project spitzer (issue 507834) we
can use it for audio decoding on Android; this provides a more
secure (all decoding in the renderer) and faster decoding experience
for WebAudio users.
Using the demo page from the linked bug, the improvements are:
apk size: -2162 bytes
aac decode: 12.9 seconds -> 3.7 seconds (~3.5x speedup)
ogg decode: 15.7 seconds -> 3.8 seconds (~4.1x speedup)
BUG=424174, 570711, 570788
TEST=existing layout tests all pass.
Review URL: https://codereview.chromium.org/1565623002
Cr-Commit-Position: refs/heads/master@{#367881}
21 files changed, 0 insertions, 1302 deletions
diff --git a/content/browser/renderer_host/render_message_filter.cc b/content/browser/renderer_host/render_message_filter.cc index d422083..44114fd 100644 --- a/content/browser/renderer_host/render_message_filter.cc +++ b/content/browser/renderer_host/render_message_filter.cc @@ -79,7 +79,6 @@ #if defined(OS_ANDROID) #include "content/browser/media/android/media_throttler.h" -#include "media/base/android/webaudio_media_codec_bridge.h" #endif #if defined(OS_MACOSX) @@ -101,13 +100,6 @@ base::LazyInstance<gfx::ColorProfile>::Leaky g_color_profile = LAZY_INSTANCE_INITIALIZER; #endif -#if defined(OS_ANDROID) -void CloseWebAudioFileDescriptor(int fd) { - if (close(fd)) - VLOG(1) << "Couldn't close output webaudio fd: " << strerror(errno); -} -#endif - } // namespace RenderMessageFilter::RenderMessageFilter( @@ -202,9 +194,6 @@ bool RenderMessageFilter::OnMessageReceived(const IPC::Message& message) { OnGetMonitorColorProfile) #endif IPC_MESSAGE_HANDLER(ViewHostMsg_MediaLogEvents, OnMediaLogEvents) -#if defined(OS_ANDROID) - IPC_MESSAGE_HANDLER(ViewHostMsg_RunWebAudioMediaCodec, OnWebAudioMediaCodec) -#endif IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() @@ -610,32 +599,6 @@ void RenderMessageFilter::OnMediaLogEvents( media_internals_->OnMediaEvents(render_process_id_, events); } -#if defined(OS_ANDROID) -void RenderMessageFilter::OnWebAudioMediaCodec( - base::SharedMemoryHandle encoded_data_handle, - base::FileDescriptor pcm_output, - uint32_t data_size) { - if (!MediaThrottler::GetInstance()->RequestDecoderResources()) { - base::WorkerPool::PostTask( - FROM_HERE, - base::Bind(&CloseWebAudioFileDescriptor, pcm_output.fd), - true); - VLOG(1) << "Cannot decode audio data due to throttling"; - } else { - // Let a WorkerPool handle this request since the WebAudio - // MediaCodec bridge is slow and can block while sending the data to - // the renderer. - base::WorkerPool::PostTask( - FROM_HERE, - base::Bind(&media::WebAudioMediaCodecBridge::RunWebAudioMediaCodec, - encoded_data_handle, pcm_output, data_size, - base::Bind(&MediaThrottler::OnDecodeRequestFinished, - base::Unretained(MediaThrottler::GetInstance()))), - true); - } -} -#endif - void RenderMessageFilter::OnAllocateGpuMemoryBuffer(gfx::GpuMemoryBufferId id, uint32_t width, uint32_t height, diff --git a/content/browser/renderer_host/render_message_filter.h b/content/browser/renderer_host/render_message_filter.h index b87ad3f..f8307a9 100644 --- a/content/browser/renderer_host/render_message_filter.h +++ b/content/browser/renderer_host/render_message_filter.h @@ -205,12 +205,6 @@ class CONTENT_EXPORT RenderMessageFilter : public BrowserMessageFilter { bool CheckBenchmarkingEnabled() const; bool CheckPreparsedJsCachingEnabled() const; -#if defined(OS_ANDROID) - void OnWebAudioMediaCodec(base::SharedMemoryHandle encoded_data_handle, - base::FileDescriptor pcm_output, - uint32_t data_size); -#endif - void OnAllocateGpuMemoryBuffer(gfx::GpuMemoryBufferId id, uint32_t width, uint32_t height, diff --git a/content/common/view_messages.h b/content/common/view_messages.h index 1d0cb0c..5b5e578 100644 --- a/content/common/view_messages.h +++ b/content/common/view_messages.h @@ -1389,12 +1389,6 @@ IPC_MESSAGE_ROUTED2(ViewHostMsg_StartContentIntent, GURL /* content_url */, bool /* is_main_frame */) -// This message runs the MediaCodec for decoding audio for webaudio. -IPC_MESSAGE_CONTROL3(ViewHostMsg_RunWebAudioMediaCodec, - base::SharedMemoryHandle /* encoded_data_handle */, - base::FileDescriptor /* pcm_output */, - uint32_t /* data_size*/) - // Reply to the ViewMsg_ExtractSmartClipData message. IPC_MESSAGE_ROUTED3(ViewHostMsg_SmartClipDataExtracted, base::string16 /* text */, diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi index ba139df..c0f6449 100644 --- a/content/content_renderer.gypi +++ b/content/content_renderer.gypi @@ -261,8 +261,6 @@ 'renderer/manifest/manifest_uma_util.h', 'renderer/media/aec_dump_message_filter.cc', 'renderer/media/aec_dump_message_filter.h', - 'renderer/media/android/audio_decoder_android.cc', - 'renderer/media/android/audio_decoder_android.h', 'renderer/media/android/media_info_loader.cc', 'renderer/media/android/media_info_loader.h', 'renderer/media/android/media_source_delegate.cc', @@ -811,9 +809,6 @@ ], }], ['OS=="android"', { - 'sources!': [ - 'renderer/media/audio_decoder.cc', - ], 'sources': [ 'renderer/external_popup_menu.cc', 'renderer/external_popup_menu.h', diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index 3e262d7..0ab1cb8 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn @@ -93,7 +93,6 @@ source_set("renderer") { } if (is_android) { - sources -= [ "media/audio_decoder.cc" ] sources += [ "external_popup_menu.cc", "external_popup_menu.h", diff --git a/content/renderer/media/android/audio_decoder_android.cc b/content/renderer/media/android/audio_decoder_android.cc deleted file mode 100644 index 2601fea..0000000 --- a/content/renderer/media/android/audio_decoder_android.cc +++ /dev/null @@ -1,596 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/renderer/media/android/audio_decoder_android.h" - -#include <errno.h> -#include <fcntl.h> -#include <limits.h> -#include <stdint.h> -#include <sys/mman.h> -#include <unistd.h> -#include <vector> - -#include "base/file_descriptor_posix.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/memory/shared_memory.h" -#include "base/posix/eintr_wrapper.h" -#include "base/process/process_handle.h" -#include "content/common/view_messages.h" -#include "media/base/android/webaudio_media_codec_info.h" -#include "media/base/audio_bus.h" -#include "media/base/limits.h" -#include "third_party/WebKit/public/platform/WebAudioBus.h" - -namespace content { - -class AudioDecoderIO { - public: - AudioDecoderIO(const char* data, size_t data_size); - ~AudioDecoderIO(); - bool ShareEncodedToProcess(base::SharedMemoryHandle* handle); - - // Returns true if AudioDecoderIO was successfully created. - bool IsValid() const; - - int read_fd() const { return read_fd_; } - int write_fd() const { return write_fd_; } - - private: - // Shared memory that will hold the encoded audio data. This is - // used by MediaCodec for decoding. - base::SharedMemory encoded_shared_memory_; - - // A pipe used to communicate with MediaCodec. MediaCodec owns - // write_fd_ and writes to it. - int read_fd_; - int write_fd_; - - DISALLOW_COPY_AND_ASSIGN(AudioDecoderIO); -}; - -AudioDecoderIO::AudioDecoderIO(const char* data, size_t data_size) - : read_fd_(-1), - write_fd_(-1) { - - if (!data || !data_size || data_size > 0x80000000) - return; - - // Create the shared memory and copy our data to it so that - // MediaCodec can access it. - encoded_shared_memory_.CreateAndMapAnonymous(data_size); - - if (!encoded_shared_memory_.memory()) - return; - - memcpy(encoded_shared_memory_.memory(), data, data_size); - - // Create a pipe for reading/writing the decoded PCM data - int pipefd[2]; - - if (pipe(pipefd)) - return; - - read_fd_ = pipefd[0]; - write_fd_ = pipefd[1]; -} - -AudioDecoderIO::~AudioDecoderIO() { - // Close the read end of the pipe. The write end should have been - // closed by MediaCodec. - if (read_fd_ >= 0 && close(read_fd_)) { - DVLOG(1) << "Cannot close read fd " << read_fd_ - << ": " << strerror(errno); - } -} - -bool AudioDecoderIO::IsValid() const { - return read_fd_ >= 0 && write_fd_ >= 0 && - encoded_shared_memory_.memory(); -} - -bool AudioDecoderIO::ShareEncodedToProcess(base::SharedMemoryHandle* handle) { - return encoded_shared_memory_.ShareToProcess(base::GetCurrentProcessHandle(), - handle); -} - -static float ConvertSampleToFloat(int16_t sample) { - const float kMaxScale = 1.0f / std::numeric_limits<int16_t>::max(); - const float kMinScale = -1.0f / std::numeric_limits<int16_t>::min(); - - return sample * (sample < 0 ? kMinScale : kMaxScale); -} - -// A basic WAVE file decoder. See -// https://ccrma.stanford.edu/courses/422/projects/WaveFormat/ for a -// basic guide to the WAVE file format. -class WAVEDecoder { - public: - WAVEDecoder(const uint8_t* data, size_t data_size); - ~WAVEDecoder(); - - // Try to decode the data as a WAVE file. If the data is a supported - // WAVE file, |destination_bus| is filled with the decoded data and - // DecodeWAVEFile returns true. Otherwise, DecodeWAVEFile returns - // false. - bool DecodeWAVEFile(blink::WebAudioBus* destination_bus); - - private: - // Minimum number of bytes in a WAVE file to hold all of the data we - // need to interpret it as a WAVE file. - static const unsigned kMinimumWAVLength = 44; - - // Number of bytes in the chunk ID field. - static const unsigned kChunkIDLength = 4; - - // Number of bytes in the chunk size field. - static const unsigned kChunkSizeLength = 4; - - // Number of bytes in the format field of the "RIFF" chunk. - static const unsigned kFormatFieldLength = 4; - - // Number of bytes in a valid "fmt" chunk. - static const unsigned kFMTChunkLength = 16; - - // Supported audio format in a WAVE file. - // TODO(rtoy): Consider supporting other formats here, if necessary. - static const int16_t kAudioFormatPCM = 1; - - // Maximum number (inclusive) of bytes per sample supported by this - // decoder. - static const unsigned kMaximumBytesPerSample = 3; - - // Read an unsigned integer of |length| bytes from |buffer|. The - // integer is interpreted as being in little-endian order. - uint32_t ReadUnsignedInteger(const uint8_t* buffer, size_t length); - - // Read a PCM sample from the WAVE data at |pcm_data|. - int16_t ReadPCMSample(const uint8_t* pcm_data); - - // Read a WAVE chunk header including the chunk ID and chunk size. - // Returns false if the header could not be read. - bool ReadChunkHeader(); - - // Read and parse the "fmt" chunk. Returns false if the fmt chunk - // could not be read or contained unsupported formats. - bool ReadFMTChunk(); - - // Read data chunk and save it to |destination_bus|. Returns false - // if the data chunk could not be read correctly. - bool CopyDataChunkToBus(blink::WebAudioBus* destination_bus); - - // The WAVE chunk ID that identifies the chunk. - uint8_t chunk_id_[kChunkIDLength]; - - // The number of bytes in the data portion of the chunk. - size_t chunk_size_; - - // The total number of bytes in the encoded data. - size_t data_size_; - - // The current position within the WAVE file. - const uint8_t* buffer_; - - // Points one byte past the end of the in-memory WAVE file. Used for - // detecting if we've reached the end of the file. - const uint8_t* buffer_end_; - - size_t bytes_per_sample_; - - uint16_t number_of_channels_; - - // Sample rate of the WAVE data, in Hz. - uint32_t sample_rate_; - - DISALLOW_COPY_AND_ASSIGN(WAVEDecoder); -}; - -WAVEDecoder::WAVEDecoder(const uint8_t* encoded_data, size_t data_size) - : data_size_(data_size), - buffer_(encoded_data), - buffer_end_(encoded_data + 1), - bytes_per_sample_(0), - number_of_channels_(0), - sample_rate_(0) { - if (buffer_ + data_size > buffer_) - buffer_end_ = buffer_ + data_size; -} - -WAVEDecoder::~WAVEDecoder() {} - -uint32_t WAVEDecoder::ReadUnsignedInteger(const uint8_t* buffer, - size_t length) { - unsigned value = 0; - - if (length == 0 || length > sizeof(value)) { - DCHECK(false) << "ReadUnsignedInteger: Invalid length: " << length; - return 0; - } - - // All integer fields in a WAVE file are little-endian. - for (size_t k = length; k > 0; --k) - value = (value << 8) + buffer[k - 1]; - - return value; -} - -int16_t WAVEDecoder::ReadPCMSample(const uint8_t* pcm_data) { - uint32_t unsigned_sample = ReadUnsignedInteger(pcm_data, bytes_per_sample_); - int16_t sample; - - // Convert the unsigned data into a 16-bit PCM sample. - switch (bytes_per_sample_) { - case 1: - sample = (unsigned_sample - 128) << 8; - break; - case 2: - sample = static_cast<int16_t>(unsigned_sample); - break; - case 3: - // Android currently converts 24-bit WAVE data into 16-bit - // samples by taking the high-order 16 bits without rounding. - // We do the same here for consistency. - sample = static_cast<int16_t>(unsigned_sample >> 8); - break; - default: - sample = 0; - break; - } - return sample; -} - -bool WAVEDecoder::ReadChunkHeader() { - if (buffer_ + kChunkIDLength + kChunkSizeLength >= buffer_end_) - return false; - - memcpy(chunk_id_, buffer_, kChunkIDLength); - - chunk_size_ = ReadUnsignedInteger(buffer_ + kChunkIDLength, kChunkSizeLength); - - // Adjust for padding - if (chunk_size_ % 2) - ++chunk_size_; - - // Check for completely bogus chunk size. - if (chunk_size_ > data_size_) - return false; - - return true; -} - -bool WAVEDecoder::ReadFMTChunk() { - // The fmt chunk has basic info about the format of the audio - // data. Only a basic PCM format is supported. - if (chunk_size_ < kFMTChunkLength) { - DVLOG(1) << "FMT chunk too short: " << chunk_size_; - return 0; - } - - uint16_t audio_format = ReadUnsignedInteger(buffer_, 2); - - if (audio_format != kAudioFormatPCM) { - DVLOG(1) << "Audio format not supported: " << audio_format; - return false; - } - - number_of_channels_ = ReadUnsignedInteger(buffer_ + 2, 2); - sample_rate_ = ReadUnsignedInteger(buffer_ + 4, 4); - unsigned bits_per_sample = ReadUnsignedInteger(buffer_ + 14, 2); - - // Sanity checks. - - if (!number_of_channels_ || - number_of_channels_ > media::limits::kMaxChannels) { - DVLOG(1) << "Unsupported number of channels: " << number_of_channels_; - return false; - } - - if (sample_rate_ < media::limits::kMinSampleRate || - sample_rate_ > media::limits::kMaxSampleRate) { - DVLOG(1) << "Unsupported sample rate: " << sample_rate_; - return false; - } - - // We only support 8, 16, and 24 bits per sample. - if (bits_per_sample == 8 || bits_per_sample == 16 || bits_per_sample == 24) { - bytes_per_sample_ = bits_per_sample / 8; - return true; - } - - DVLOG(1) << "Unsupported bits per sample: " << bits_per_sample; - return false; -} - -bool WAVEDecoder::CopyDataChunkToBus(blink::WebAudioBus* destination_bus) { - // The data chunk contains the audio data itself. - if (!bytes_per_sample_ || bytes_per_sample_ > kMaximumBytesPerSample) { - DVLOG(1) << "WARNING: data chunk without preceeding fmt chunk," - << " or invalid bytes per sample."; - return false; - } - - DVLOG(0) << "Decoding WAVE file: " << number_of_channels_ << " channels, " - << sample_rate_ << " kHz, " - << chunk_size_ / bytes_per_sample_ / number_of_channels_ - << " frames, " << 8 * bytes_per_sample_ << " bits/sample"; - - // Create the destination bus of the appropriate size and then decode - // the data into the bus. - size_t number_of_frames = - chunk_size_ / bytes_per_sample_ / number_of_channels_; - - destination_bus->initialize( - number_of_channels_, number_of_frames, sample_rate_); - - for (size_t m = 0; m < number_of_frames; ++m) { - for (uint16_t k = 0; k < number_of_channels_; ++k) { - int16_t sample = ReadPCMSample(buffer_); - - buffer_ += bytes_per_sample_; - destination_bus->channelData(k)[m] = ConvertSampleToFloat(sample); - } - } - - return true; -} - -bool WAVEDecoder::DecodeWAVEFile(blink::WebAudioBus* destination_bus) { - // Parse and decode WAVE file. If we can't parse it, return false. - - if (buffer_ + kMinimumWAVLength > buffer_end_) { - DVLOG(1) << "Buffer too small to contain full WAVE header: "; - return false; - } - - // Do we have a RIFF file? - ReadChunkHeader(); - if (memcmp(chunk_id_, "RIFF", kChunkIDLength) != 0) { - DVLOG(1) << "RIFF missing"; - return false; - } - buffer_ += kChunkIDLength + kChunkSizeLength; - - // Check the format field of the RIFF chunk - memcpy(chunk_id_, buffer_, kFormatFieldLength); - if (memcmp(chunk_id_, "WAVE", kFormatFieldLength) != 0) { - DVLOG(1) << "Invalid WAVE file: missing WAVE header"; - return false; - } - // Advance past the format field - buffer_ += kFormatFieldLength; - - // We have a WAVE file. Start parsing the chunks. - - while (buffer_ < buffer_end_) { - if (!ReadChunkHeader()) { - DVLOG(1) << "Couldn't read chunk header"; - return false; - } - - // Consume the chunk ID and chunk size - buffer_ += kChunkIDLength + kChunkSizeLength; - - // Make sure we can read all chunk_size bytes. - if (buffer_ + chunk_size_ > buffer_end_) { - DVLOG(1) << "Insufficient bytes to read chunk of size " << chunk_size_; - return false; - } - - if (memcmp(chunk_id_, "fmt ", kChunkIDLength) == 0) { - if (!ReadFMTChunk()) - return false; - } else if (memcmp(chunk_id_, "data", kChunkIDLength) == 0) { - // Return after reading the data chunk, whether we succeeded or - // not. - return CopyDataChunkToBus(destination_bus); - } else { - // Ignore these chunks that we don't know about. - DVLOG(0) << "Ignoring WAVE chunk `" << chunk_id_ << "' size " - << chunk_size_; - } - - // Advance to next chunk. - buffer_ += chunk_size_; - } - - // If we get here, that means we didn't find a data chunk, so we - // couldn't handle this WAVE file. - - return false; -} - -// The number of frames is known so preallocate the destination -// bus and copy the pcm data to the destination bus as it's being -// received. -static void CopyPcmDataToBus(int input_fd, - blink::WebAudioBus* destination_bus, - size_t number_of_frames, - unsigned number_of_channels, - double file_sample_rate) { - destination_bus->initialize(number_of_channels, - number_of_frames, - file_sample_rate); - - int16_t pipe_data[PIPE_BUF / sizeof(int16_t)]; - size_t decoded_frames = 0; - size_t current_sample_in_frame = 0; - ssize_t nread; - - while ((nread = HANDLE_EINTR(read(input_fd, pipe_data, sizeof(pipe_data)))) > - 0) { - size_t samples_in_pipe = nread / sizeof(int16_t); - - // The pipe may not contain a whole number of frames. This is - // especially true if the number of channels is greater than - // 2. Thus, keep track of which sample in a frame is being - // processed, so we handle the boundary at the end of the pipe - // correctly. - for (size_t m = 0; m < samples_in_pipe; ++m) { - if (decoded_frames >= number_of_frames) - break; - - destination_bus->channelData(current_sample_in_frame)[decoded_frames] = - ConvertSampleToFloat(pipe_data[m]); - ++current_sample_in_frame; - - if (current_sample_in_frame >= number_of_channels) { - current_sample_in_frame = 0; - ++decoded_frames; - } - } - } - - // number_of_frames is only an estimate. Resize the buffer with the - // actual number of received frames. - if (decoded_frames < number_of_frames) - destination_bus->resizeSmaller(decoded_frames); -} - -// The number of frames is unknown, so keep reading and buffering -// until there's no more data and then copy the data to the -// destination bus. -static void BufferAndCopyPcmDataToBus(int input_fd, - blink::WebAudioBus* destination_bus, - unsigned number_of_channels, - double file_sample_rate) { - int16_t pipe_data[PIPE_BUF / sizeof(int16_t)]; - std::vector<int16_t> decoded_samples; - ssize_t nread; - - while ((nread = HANDLE_EINTR(read(input_fd, pipe_data, sizeof(pipe_data)))) > - 0) { - size_t samples_in_pipe = nread / sizeof(int16_t); - if (decoded_samples.size() + samples_in_pipe > decoded_samples.capacity()) { - decoded_samples.reserve(std::max(samples_in_pipe, - 2 * decoded_samples.capacity())); - } - std::copy(pipe_data, - pipe_data + samples_in_pipe, - back_inserter(decoded_samples)); - } - - DVLOG(1) << "Total samples read = " << decoded_samples.size(); - - // Convert the samples and save them in the audio bus. - size_t number_of_samples = decoded_samples.size(); - size_t number_of_frames = decoded_samples.size() / number_of_channels; - size_t decoded_frames = 0; - - destination_bus->initialize(number_of_channels, - number_of_frames, - file_sample_rate); - - for (size_t m = 0; m < number_of_samples; m += number_of_channels) { - if (decoded_frames >= number_of_frames) - break; - - for (size_t k = 0; k < number_of_channels; ++k) { - int16_t sample = decoded_samples[m + k]; - destination_bus->channelData(k)[decoded_frames] = - ConvertSampleToFloat(sample); - } - ++decoded_frames; - } - - // number_of_frames is only an estimate. Resize the buffer with the - // actual number of received frames. - if (decoded_frames < number_of_frames) - destination_bus->resizeSmaller(decoded_frames); -} - -static bool TryWAVEFileDecoder(blink::WebAudioBus* destination_bus, - const uint8_t* encoded_data, - size_t data_size) { - WAVEDecoder decoder(encoded_data, data_size); - - return decoder.DecodeWAVEFile(destination_bus); -} - -// To decode audio data, we want to use the Android MediaCodec class. -// But this can't run in a sandboxed process so we need initiate the -// request to MediaCodec in the browser. To do this, we create a -// shared memory buffer that holds the audio data. We send a message -// to the browser to start the decoder using this buffer and one end -// of a pipe. The MediaCodec class will decode the data from the -// shared memory and write the PCM samples back to us over a pipe. -bool DecodeAudioFileData(blink::WebAudioBus* destination_bus, const char* data, - size_t data_size, - scoped_refptr<ThreadSafeSender> sender) { - // Try to decode the data as a WAVE file first. If it can't be - // decoded, use MediaCodec. See crbug.com/259048. - if (TryWAVEFileDecoder( - destination_bus, reinterpret_cast<const uint8_t*>(data), data_size)) { - return true; - } - - AudioDecoderIO audio_decoder(data, data_size); - - if (!audio_decoder.IsValid()) - return false; - - base::SharedMemoryHandle encoded_data_handle; - audio_decoder.ShareEncodedToProcess(&encoded_data_handle); - base::FileDescriptor fd(audio_decoder.write_fd(), true); - - DVLOG(1) << "DecodeAudioFileData: Starting MediaCodec"; - - // Start MediaCodec processing in the browser which will read from - // encoded_data_handle for our shared memory and write the decoded - // PCM samples (16-bit integer) to our pipe. - - sender->Send(new ViewHostMsg_RunWebAudioMediaCodec( - encoded_data_handle, fd, data_size)); - - // First, read the number of channels, the sample rate, and the - // number of frames and a flag indicating if the file is an - // ogg/vorbis file. This must be coordinated with - // WebAudioMediaCodecBridge! - // - // If we know the number of samples, we can create the destination - // bus directly and do the conversion directly to the bus instead of - // buffering up everything before saving the data to the bus. - - int input_fd = audio_decoder.read_fd(); - struct media::WebAudioMediaCodecInfo info; - - DVLOG(1) << "Reading audio file info from fd " << input_fd; - ssize_t nread = HANDLE_EINTR(read(input_fd, &info, sizeof(info))); - DVLOG(1) << "read: " << nread << " bytes:\n" - << " 0: number of channels = " << info.channel_count << "\n" - << " 1: sample rate = " << info.sample_rate << "\n" - << " 2: number of frames = " << info.number_of_frames << "\n"; - - if (nread != sizeof(info)) - return false; - - unsigned number_of_channels = info.channel_count; - double file_sample_rate = static_cast<double>(info.sample_rate); - size_t number_of_frames = info.number_of_frames; - - // Sanity checks - if (!number_of_channels || - number_of_channels > media::limits::kMaxChannels || - file_sample_rate < media::limits::kMinSampleRate || - file_sample_rate > media::limits::kMaxSampleRate) { - return false; - } - - if (number_of_frames > 0) { - CopyPcmDataToBus(input_fd, - destination_bus, - number_of_frames, - number_of_channels, - file_sample_rate); - } else { - BufferAndCopyPcmDataToBus(input_fd, - destination_bus, - number_of_channels, - file_sample_rate); - } - - return true; -} - -} // namespace content diff --git a/content/renderer/media/android/audio_decoder_android.h b/content/renderer/media/android/audio_decoder_android.h deleted file mode 100644 index 3f4c45b..0000000 --- a/content/renderer/media/android/audio_decoder_android.h +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_RENDERER_MEDIA_ANDROID_AUDIO_DECODER_ANDROID_H_ -#define CONTENT_RENDERER_MEDIA_ANDROID_AUDIO_DECODER_ANDROID_H_ - -#include <stddef.h> - -#include "content/child/thread_safe_sender.h" - -namespace blink { -class WebAudioBus; -} - -namespace content { - -bool DecodeAudioFileData(blink::WebAudioBus* destination_bus, - const char* data, - size_t data_size, - scoped_refptr<ThreadSafeSender> sender); - -} // namespace content - -#endif // CONTENT_RENDERER_MEDIA_ANDROID_AUDIO_DECODER_ANDROID_H_ diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc index c2acbad..2bffb25 100644 --- a/content/renderer/renderer_blink_platform_impl.cc +++ b/content/renderer/renderer_blink_platform_impl.cc @@ -98,7 +98,6 @@ #if defined(OS_ANDROID) #include "content/renderer/android/synchronous_compositor_factory.h" -#include "content/renderer/media/android/audio_decoder_android.h" #include "gpu/blink/webgraphicscontext3d_in_process_command_buffer_impl.h" #endif @@ -753,17 +752,6 @@ WebAudioDevice* RendererBlinkPlatformImpl::createAudioDevice( return new RendererWebAudioDeviceImpl(params, callback, session_id); } -#if defined(OS_ANDROID) -bool RendererBlinkPlatformImpl::loadAudioResource( - blink::WebAudioBus* destination_bus, - const char* audio_file_data, - size_t data_size) { - return DecodeAudioFileData(destination_bus, - audio_file_data, - data_size, - thread_safe_sender_); -} -#else bool RendererBlinkPlatformImpl::loadAudioResource( blink::WebAudioBus* destination_bus, const char* audio_file_data, @@ -771,7 +759,6 @@ bool RendererBlinkPlatformImpl::loadAudioResource( return DecodeAudioFileData( destination_bus, audio_file_data, data_size); } -#endif // defined(OS_ANDROID) //------------------------------------------------------------------------------ diff --git a/media/base/android/BUILD.gn b/media/base/android/BUILD.gn index 75c6717..54d8074 100644 --- a/media/base/android/BUILD.gn +++ b/media/base/android/BUILD.gn @@ -64,9 +64,6 @@ source_set("android") { "sdk_media_codec_bridge.h", "video_decoder_job.cc", "video_decoder_job.h", - "webaudio_media_codec_bridge.cc", - "webaudio_media_codec_bridge.h", - "webaudio_media_codec_info.h", ] configs += [ "//media:media_config", @@ -114,7 +111,6 @@ generate_jni("media_jni_headers") { "java/src/org/chromium/media/MediaDrmBridge.java", "java/src/org/chromium/media/MediaPlayerBridge.java", "java/src/org/chromium/media/MediaPlayerListener.java", - "java/src/org/chromium/media/WebAudioMediaCodecBridge.java", ] jni_package = "media" } diff --git a/media/base/android/java/src/org/chromium/media/WebAudioMediaCodecBridge.java b/media/base/android/java/src/org/chromium/media/WebAudioMediaCodecBridge.java deleted file mode 100644 index abc394c..0000000 --- a/media/base/android/java/src/org/chromium/media/WebAudioMediaCodecBridge.java +++ /dev/null @@ -1,293 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.media; - -import android.content.Context; -import android.media.MediaCodec; -import android.media.MediaCodec.BufferInfo; -import android.media.MediaExtractor; -import android.media.MediaFormat; -import android.os.ParcelFileDescriptor; - -import org.chromium.base.Log; -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; - -import java.io.File; -import java.nio.ByteBuffer; - -@JNINamespace("media") -class WebAudioMediaCodecBridge { - private static final String TAG = "cr.media"; - // TODO(rtoy): What is the correct timeout value for reading - // from a file in memory? - static final long TIMEOUT_MICROSECONDS = 500; - @CalledByNative - private static String createTempFile(Context ctx) throws java.io.IOException { - File outputDirectory = ctx.getCacheDir(); - File outputFile = File.createTempFile("webaudio", ".dat", outputDirectory); - return outputFile.getAbsolutePath(); - } - - @SuppressWarnings("deprecation") - @CalledByNative - private static boolean decodeAudioFile(Context ctx, long nativeMediaCodecBridge, - int inputFD, long dataSize) { - - if (dataSize < 0 || dataSize > 0x7fffffff) return false; - - MediaExtractor extractor = new MediaExtractor(); - - ParcelFileDescriptor encodedFD; - encodedFD = ParcelFileDescriptor.adoptFd(inputFD); - try { - extractor.setDataSource(encodedFD.getFileDescriptor(), 0, dataSize); - } catch (Exception e) { - e.printStackTrace(); - encodedFD.detachFd(); - return false; - } - - if (extractor.getTrackCount() <= 0) { - encodedFD.detachFd(); - return false; - } - - MediaFormat format = extractor.getTrackFormat(0); - - // If we are unable to get the input channel count, the sample - // rate or the mime type for any reason, just give up. - // Without these, we don't know what to do. - - int inputChannelCount; - try { - // Number of channels specified in the file - inputChannelCount = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT); - } catch (Exception e) { - // Give up. - Log.w(TAG, "Unable to determine number of channels"); - encodedFD.detachFd(); - return false; - } - - // Number of channels the decoder will provide. (Not - // necessarily the same as inputChannelCount. See - // crbug.com/266006.) - int outputChannelCount = inputChannelCount; - - int sampleRate; - try { - sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE); - } catch (Exception e) { - // Give up. - Log.w(TAG, "Unable to determine sample rate"); - encodedFD.detachFd(); - return false; - } - - String mime; - try { - mime = format.getString(MediaFormat.KEY_MIME); - } catch (Exception e) { - // Give up. - Log.w(TAG, "Unable to determine type of encoding used by the file"); - encodedFD.detachFd(); - return false; - } - - long durationMicroseconds = 0; - if (format.containsKey(MediaFormat.KEY_DURATION)) { - try { - durationMicroseconds = format.getLong(MediaFormat.KEY_DURATION); - } catch (Exception e) { - Log.d(TAG, "Cannot get duration"); - } - } - - // If the duration is too long, set to 0 to force the caller - // not to preallocate space. See crbug.com/326856. - // FIXME: What should be the limit? We're arbitrarily using - // about 2148 sec (35.8 min). - if (durationMicroseconds > 0x7fffffff) { - durationMicroseconds = 0; - } - - Log.d(TAG, "Initial: Tracks: %d Format: %s", extractor.getTrackCount(), format); - - // Create decoder - MediaCodec codec; - try { - codec = MediaCodec.createDecoderByType(mime); - } catch (Exception e) { - Log.w(TAG, "Failed to create MediaCodec for mime type: %s", mime); - encodedFD.detachFd(); - return false; - } - - try { - codec.configure(format, null /* surface */, null /* crypto */, 0 /* flags */); - } catch (Exception e) { - Log.w(TAG, "Unable to configure codec for format " + format, e); - encodedFD.detachFd(); - return false; - } - try { - codec.start(); - } catch (Exception e) { - Log.w(TAG, "Unable to start()", e); - encodedFD.detachFd(); - return false; - } - - ByteBuffer[] codecInputBuffers; - try { - codecInputBuffers = codec.getInputBuffers(); - } catch (Exception e) { - Log.w(TAG, "getInputBuffers() failed", e); - encodedFD.detachFd(); - return false; - } - ByteBuffer[] codecOutputBuffers; - try { - codecOutputBuffers = codec.getOutputBuffers(); - } catch (Exception e) { - Log.w(TAG, "getOutputBuffers() failed", e); - encodedFD.detachFd(); - return false; - } - - // A track must be selected and will be used to read samples. - extractor.selectTrack(0); - - boolean sawInputEOS = false; - boolean sawOutputEOS = false; - boolean destinationInitialized = false; - boolean decodedSuccessfully = true; - - // Keep processing until the output is done. - while (!sawOutputEOS) { - if (!sawInputEOS) { - // Input side - int inputBufIndex; - try { - inputBufIndex = codec.dequeueInputBuffer(TIMEOUT_MICROSECONDS); - } catch (Exception e) { - Log.w(TAG, "dequeueInputBuffer(%d) failed.", TIMEOUT_MICROSECONDS, e); - decodedSuccessfully = false; - break; - } - - if (inputBufIndex >= 0) { - ByteBuffer dstBuf = codecInputBuffers[inputBufIndex]; - int sampleSize; - - try { - sampleSize = extractor.readSampleData(dstBuf, 0); - } catch (Exception e) { - Log.w(TAG, "readSampleData failed."); - decodedSuccessfully = false; - break; - } - - long presentationTimeMicroSec = 0; - - if (sampleSize < 0) { - sawInputEOS = true; - sampleSize = 0; - } else { - presentationTimeMicroSec = extractor.getSampleTime(); - } - - try { - codec.queueInputBuffer(inputBufIndex, - 0, /* offset */ - sampleSize, - presentationTimeMicroSec, - sawInputEOS ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0); - } catch (Exception e) { - Log.w(TAG, "queueInputBuffer(%d, 0, %d, %d, %d) failed.", - inputBufIndex, sampleSize, presentationTimeMicroSec, - (sawInputEOS ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0), e); - decodedSuccessfully = false; - break; - } - - if (!sawInputEOS) { - extractor.advance(); - } - } - } - - // Output side - MediaCodec.BufferInfo info = new BufferInfo(); - final int outputBufIndex; - - try { - outputBufIndex = codec.dequeueOutputBuffer(info, TIMEOUT_MICROSECONDS); - } catch (Exception e) { - Log.w(TAG, "dequeueOutputBuffer(%s, %d) failed", info, TIMEOUT_MICROSECONDS); - e.printStackTrace(); - decodedSuccessfully = false; - break; - } - - if (outputBufIndex >= 0) { - ByteBuffer buf = codecOutputBuffers[outputBufIndex]; - - if (!destinationInitialized) { - // Initialize the destination as late as possible to - // catch any changes in format. But be sure to - // initialize it BEFORE we send any decoded audio, - // and only initialize once. - Log.d(TAG, "Final: Rate: %d Channels: %d Mime: %s Duration: %d microsec", - sampleRate, inputChannelCount, mime, durationMicroseconds); - - nativeInitializeDestination(nativeMediaCodecBridge, - inputChannelCount, - sampleRate, - durationMicroseconds); - destinationInitialized = true; - } - - if (destinationInitialized && info.size > 0) { - nativeOnChunkDecoded(nativeMediaCodecBridge, buf, info.size, - inputChannelCount, outputChannelCount); - } - - buf.clear(); - codec.releaseOutputBuffer(outputBufIndex, false /* render */); - - if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { - sawOutputEOS = true; - } - } else if (outputBufIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) { - codecOutputBuffers = codec.getOutputBuffers(); - } else if (outputBufIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { - MediaFormat newFormat = codec.getOutputFormat(); - outputChannelCount = newFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT); - sampleRate = newFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE); - Log.d(TAG, "output format changed to " + newFormat); - } - } - - encodedFD.detachFd(); - - codec.stop(); - codec.release(); - codec = null; - - return decodedSuccessfully; - } - - private static native void nativeOnChunkDecoded( - long nativeWebAudioMediaCodecBridge, ByteBuffer buf, int size, - int inputChannelCount, int outputChannelCount); - - private static native void nativeInitializeDestination( - long nativeWebAudioMediaCodecBridge, - int inputChannelCount, - int sampleRate, - long durationMicroseconds); -} diff --git a/media/base/android/media_jni_registrar.cc b/media/base/android/media_jni_registrar.cc index 375748e..e230784 100644 --- a/media/base/android/media_jni_registrar.cc +++ b/media/base/android/media_jni_registrar.cc @@ -15,7 +15,6 @@ #include "media/base/android/media_player_bridge.h" #include "media/base/android/media_player_listener.h" #include "media/base/android/sdk_media_codec_bridge.h" -#include "media/base/android/webaudio_media_codec_bridge.h" #include "media/capture/video/android/video_capture_device_android.h" #include "media/capture/video/android/video_capture_device_factory_android.h" @@ -33,8 +32,6 @@ static base::android::RegistrationMethod kMediaRegisteredMethods[] = { VideoCaptureDeviceAndroid::RegisterVideoCaptureDevice}, {"VideoCaptureDeviceFactory", VideoCaptureDeviceFactoryAndroid::RegisterVideoCaptureDeviceFactory}, - {"WebAudioMediaCodecBridge", - WebAudioMediaCodecBridge::RegisterWebAudioMediaCodecBridge}, }; bool RegisterJni(JNIEnv* env) { diff --git a/media/base/android/webaudio_media_codec_bridge.cc b/media/base/android/webaudio_media_codec_bridge.cc deleted file mode 100644 index c38ba75..0000000 --- a/media/base/android/webaudio_media_codec_bridge.cc +++ /dev/null @@ -1,202 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "media/base/android/webaudio_media_codec_bridge.h" - -#include <errno.h> -#include <fcntl.h> -#include <stddef.h> -#include <string.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <unistd.h> -#include <vector> - -#include "base/android/context_utils.h" -#include "base/android/jni_android.h" -#include "base/android/jni_array.h" -#include "base/android/jni_string.h" -#include "base/files/scoped_file.h" -#include "base/logging.h" -#include "base/posix/eintr_wrapper.h" -#include "jni/WebAudioMediaCodecBridge_jni.h" -#include "media/base/android/webaudio_media_codec_info.h" - -using base::android::AttachCurrentThread; - -namespace media { - -void WebAudioMediaCodecBridge::RunWebAudioMediaCodec( - base::SharedMemoryHandle encoded_audio_handle, - base::FileDescriptor pcm_output, - uint32_t data_size, - base::Closure on_decode_finished_cb) { - WebAudioMediaCodecBridge bridge( - encoded_audio_handle, pcm_output, data_size); - - bridge.DecodeInMemoryAudioFile(); - on_decode_finished_cb.Run(); -} - -WebAudioMediaCodecBridge::WebAudioMediaCodecBridge( - base::SharedMemoryHandle encoded_audio_handle, - base::FileDescriptor pcm_output, - uint32_t data_size) - : encoded_audio_handle_(encoded_audio_handle), - pcm_output_(pcm_output.fd), - data_size_(data_size) { - DVLOG(1) << "WebAudioMediaCodecBridge start **********************" - << " output fd = " << pcm_output.fd; -} - -WebAudioMediaCodecBridge::~WebAudioMediaCodecBridge() { - if (close(pcm_output_)) { - DVLOG(1) << "Couldn't close output fd " << pcm_output_ - << ": " << strerror(errno); - } -} - -int WebAudioMediaCodecBridge::SaveEncodedAudioToFile( - JNIEnv* env, - jobject context) { - // Create a temporary file where we can save the encoded audio data. - std::string temporaryFile = - base::android::ConvertJavaStringToUTF8( - env, - Java_WebAudioMediaCodecBridge_createTempFile(env, context).obj()); - - // Open the file and unlink it, so that it will be actually removed - // when we close the file. - base::ScopedFD fd(open(temporaryFile.c_str(), O_RDWR)); - if (unlink(temporaryFile.c_str())) { - VLOG(0) << "Couldn't unlink temp file " << temporaryFile - << ": " << strerror(errno); - } - - if (!fd.is_valid()) { - return -1; - } - - // Create a local mapping of the shared memory containing the - // encoded audio data, and save the contents to the temporary file. - base::SharedMemory encoded_data(encoded_audio_handle_, true); - - if (!encoded_data.Map(data_size_)) { - VLOG(0) << "Unable to map shared memory!"; - return -1; - } - - if (static_cast<uint32_t>(write(fd.get(), encoded_data.memory(), data_size_)) - != data_size_) { - VLOG(0) << "Failed to write all audio data to temp file!"; - return -1; - } - - lseek(fd.get(), 0, SEEK_SET); - - return fd.release(); -} - -bool WebAudioMediaCodecBridge::DecodeInMemoryAudioFile() { - JNIEnv* env = AttachCurrentThread(); - CHECK(env); - - jobject context = base::android::GetApplicationContext(); - - int sourceFd = SaveEncodedAudioToFile(env, context); - - if (sourceFd < 0) - return false; - - jboolean decoded = Java_WebAudioMediaCodecBridge_decodeAudioFile( - env, - context, - reinterpret_cast<intptr_t>(this), - sourceFd, - data_size_); - - close(sourceFd); - - DVLOG(1) << "decoded = " << (decoded ? "true" : "false"); - - return decoded; -} - -void WebAudioMediaCodecBridge::InitializeDestination( - JNIEnv* env, - const JavaParamRef<jobject>& /*java object*/, - jint channel_count, - jint sample_rate, - jlong duration_microsec) { - // Send information about this audio file: number of channels, - // sample rate (Hz), and the number of frames. - struct WebAudioMediaCodecInfo info = { - static_cast<unsigned long>(channel_count), - static_cast<unsigned long>(sample_rate), - // The number of frames is the duration of the file - // (in microseconds) times the sample rate. - static_cast<unsigned long>( - 0.5 + (duration_microsec * 0.000001 * - sample_rate)) - }; - - DVLOG(1) << "InitializeDestination:" - << " channel count = " << channel_count - << " rate = " << sample_rate - << " duration = " << duration_microsec << " microsec"; - - HANDLE_EINTR(write(pcm_output_, &info, sizeof(info))); -} - -void WebAudioMediaCodecBridge::OnChunkDecoded( - JNIEnv* env, - const JavaParamRef<jobject>& /*java object*/, - const JavaParamRef<jobject>& buf, - jint buf_size, - jint input_channel_count, - jint output_channel_count) { - if (buf_size <= 0 || !buf) - return; - - int8_t* buffer = - static_cast<int8_t*>(env->GetDirectBufferAddress(buf)); - size_t count = static_cast<size_t>(buf_size); - std::vector<int16_t> decoded_data; - - if (input_channel_count == 1 && output_channel_count == 2) { - // See crbug.com/266006. The file has one channel, but the - // decoder decided to return two channels. To be consistent with - // the number of channels in the file, only send one channel (the - // first). - int16_t* data = static_cast<int16_t*>(env->GetDirectBufferAddress(buf)); - int frame_count = buf_size / sizeof(*data) / 2; - - decoded_data.resize(frame_count); - for (int k = 0; k < frame_count; ++k) { - decoded_data[k] = *data; - data += 2; - } - buffer = reinterpret_cast<int8_t*>(decoded_data.data()); - DCHECK(buffer); - count = frame_count * sizeof(*data); - } - - // Write out the data to the pipe in small chunks if necessary. - while (count > 0) { - int bytes_to_write = (count >= PIPE_BUF) ? PIPE_BUF : count; - ssize_t bytes_written = HANDLE_EINTR(write(pcm_output_, - buffer, - bytes_to_write)); - if (bytes_written == -1) - break; - count -= bytes_written; - buffer += bytes_written; - } -} - -bool WebAudioMediaCodecBridge::RegisterWebAudioMediaCodecBridge(JNIEnv* env) { - return RegisterNativesImpl(env); -} - -} // namespace diff --git a/media/base/android/webaudio_media_codec_bridge.h b/media/base/android/webaudio_media_codec_bridge.h deleted file mode 100644 index cd40843..0000000 --- a/media/base/android/webaudio_media_codec_bridge.h +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MEDIA_BASE_ANDROID_WEBAUDIO_MEDIA_CODEC_BRIDGE_H_ -#define MEDIA_BASE_ANDROID_WEBAUDIO_MEDIA_CODEC_BRIDGE_H_ - -#include <jni.h> -#include <stdint.h> - -#include "base/android/scoped_java_ref.h" -#include "base/callback.h" -#include "base/file_descriptor_posix.h" -#include "base/macros.h" -#include "base/memory/shared_memory.h" -#include "media/base/media_export.h" - -namespace media { - -// This class serves as a bridge for native code to call Java -// functions in the Android MediaCodec class. See -// http://developer.android.com/reference/android/media/MediaCodec.html. -class MEDIA_EXPORT WebAudioMediaCodecBridge { - public: - // Create the bridge with the given file descriptors. We read from - // |encoded_audio_handle| to get the encoded audio data. Audio file - // information and decoded PCM samples are written to |pcm_output|. - // We also take ownership of |pcm_output|. - WebAudioMediaCodecBridge(base::SharedMemoryHandle encoded_audio_handle, - base::FileDescriptor pcm_output, - uint32_t data_size); - ~WebAudioMediaCodecBridge(); - - // Inform JNI about this bridge. Returns true if registration - // succeeded. - static bool RegisterWebAudioMediaCodecBridge(JNIEnv* env); - - // Start MediaCodec to process the encoded data in - // |encoded_audio_handle|. The PCM samples are sent to |pcm_output|. - static void RunWebAudioMediaCodec( - base::SharedMemoryHandle encoded_audio_handle, - base::FileDescriptor pcm_output, - uint32_t data_size, - base::Closure on_decode_finished_cb); - - void OnChunkDecoded( - JNIEnv* env, - const base::android::JavaParamRef<jobject>& /*java object*/, - const base::android::JavaParamRef<jobject>& buf, - jint buf_size, - jint input_channel_count, - jint output_channel_count); - - void InitializeDestination( - JNIEnv* env, - const base::android::JavaParamRef<jobject>& /*java object*/, - jint channel_count, - jint sample_rate, - jlong duration_us); - - private: - // Handles MediaCodec processing of the encoded data in - // |encoded_audio_handle_| and sends the pcm data to |pcm_output_|. - // Returns true if decoding was successful. - bool DecodeInMemoryAudioFile(); - - // Save encoded audio data to a temporary file and return the file - // descriptor to that file. -1 is returned if the audio data could - // not be saved for any reason. - int SaveEncodedAudioToFile(JNIEnv*, jobject); - - // The encoded audio data is read from this file descriptor for the - // shared memory that holds the encoded data. - base::SharedMemoryHandle encoded_audio_handle_; - - // The audio file information and decoded pcm data are written to - // this file descriptor. We take ownership of this descriptor. - int pcm_output_; - - // The length of the encoded data. - uint32_t data_size_; - - DISALLOW_COPY_AND_ASSIGN(WebAudioMediaCodecBridge); -}; - -} // namespace media -#endif // MEDIA_BASE_ANDROID_WEBAUDIO_MEDIA_CODEC_BRIDGE_H_ diff --git a/media/base/android/webaudio_media_codec_info.h b/media/base/android/webaudio_media_codec_info.h deleted file mode 100644 index 423af91..0000000 --- a/media/base/android/webaudio_media_codec_info.h +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MEDIA_BASE_ANDROID_WEBAUDIO_MEDIA_CODEC_INFO_H_ -#define MEDIA_BASE_ANDROID_WEBAUDIO_MEDIA_CODEC_INFO_H_ - -namespace media { - -// This structure holds the information about the audio file -// determined by MediaCodec that is needed by the audio decoder to -// create the necessary destination bus. -struct WebAudioMediaCodecInfo { - unsigned long channel_count; - unsigned long sample_rate; - unsigned long number_of_frames; -}; - -} // namespace media -#endif // MEDIA_BASE_ANDROID_WEBAUDIO_MEDIA_CODEC_INFO_H_ diff --git a/media/media.gyp b/media/media.gyp index 3cbb74f..ba3c87e 100644 --- a/media/media.gyp +++ b/media/media.gyp @@ -1823,7 +1823,6 @@ 'base/android/java/src/org/chromium/media/MediaDrmBridge.java', 'base/android/java/src/org/chromium/media/MediaPlayerBridge.java', 'base/android/java/src/org/chromium/media/MediaPlayerListener.java', - 'base/android/java/src/org/chromium/media/WebAudioMediaCodecBridge.java', ], 'variables': { 'jni_gen_package': 'media', @@ -1901,9 +1900,6 @@ 'base/android/sdk_media_codec_bridge.h', 'base/android/video_decoder_job.cc', 'base/android/video_decoder_job.h', - 'base/android/webaudio_media_codec_bridge.cc', - 'base/android/webaudio_media_codec_bridge.h', - 'base/android/webaudio_media_codec_info.h', ], 'conditions': [ # Only 64 bit builds are using android-21 NDK library, check common.gypi diff --git a/third_party/WebKit/LayoutTests/platform/android/webaudio/codec-tests/aac/vbr-128kbps-44khz-expected.wav b/third_party/WebKit/LayoutTests/platform/android/webaudio/codec-tests/aac/vbr-128kbps-44khz-expected.wav Binary files differdeleted file mode 100644 index 101fe59..0000000 --- a/third_party/WebKit/LayoutTests/platform/android/webaudio/codec-tests/aac/vbr-128kbps-44khz-expected.wav +++ /dev/null diff --git a/third_party/WebKit/LayoutTests/platform/android/webaudio/codec-tests/mp3/128kbps-44khz-expected.wav b/third_party/WebKit/LayoutTests/platform/android/webaudio/codec-tests/mp3/128kbps-44khz-expected.wav Binary files differdeleted file mode 100644 index 839cc6a..0000000 --- a/third_party/WebKit/LayoutTests/platform/android/webaudio/codec-tests/mp3/128kbps-44khz-expected.wav +++ /dev/null diff --git a/third_party/WebKit/LayoutTests/platform/android/webaudio/codec-tests/vorbis/vbr-128kbps-44khz-expected.wav b/third_party/WebKit/LayoutTests/platform/android/webaudio/codec-tests/vorbis/vbr-128kbps-44khz-expected.wav Binary files differdeleted file mode 100644 index 47589fb7..0000000 --- a/third_party/WebKit/LayoutTests/platform/android/webaudio/codec-tests/vorbis/vbr-128kbps-44khz-expected.wav +++ /dev/null diff --git a/third_party/WebKit/LayoutTests/platform/android/webaudio/codec-tests/vorbis/vbr-70kbps-44khz-expected.wav b/third_party/WebKit/LayoutTests/platform/android/webaudio/codec-tests/vorbis/vbr-70kbps-44khz-expected.wav Binary files differdeleted file mode 100644 index 2a68ec5..0000000 --- a/third_party/WebKit/LayoutTests/platform/android/webaudio/codec-tests/vorbis/vbr-70kbps-44khz-expected.wav +++ /dev/null diff --git a/third_party/WebKit/LayoutTests/platform/android/webaudio/codec-tests/vorbis/vbr-96kbps-44khz-expected.wav b/third_party/WebKit/LayoutTests/platform/android/webaudio/codec-tests/vorbis/vbr-96kbps-44khz-expected.wav Binary files differdeleted file mode 100644 index 12d546b..0000000 --- a/third_party/WebKit/LayoutTests/platform/android/webaudio/codec-tests/vorbis/vbr-96kbps-44khz-expected.wav +++ /dev/null diff --git a/third_party/WebKit/LayoutTests/platform/android/webaudio/codec-tests/wav/24bit-22khz-resample-expected.wav b/third_party/WebKit/LayoutTests/platform/android/webaudio/codec-tests/wav/24bit-22khz-resample-expected.wav Binary files differdeleted file mode 100644 index db1aa4a..0000000 --- a/third_party/WebKit/LayoutTests/platform/android/webaudio/codec-tests/wav/24bit-22khz-resample-expected.wav +++ /dev/null |