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 3 // found in the LICENSE file. 4 5 #include "content/renderer/media/android/audio_decoder_android.h" 6 7 #include <errno.h> 8 #include <fcntl.h> 9 #include <limits.h> 10 #include <sys/mman.h> 11 #include <unistd.h> 12 #include <vector> 13 14 #include "base/file_descriptor_posix.h" 15 #include "base/logging.h" 16 #include "base/memory/shared_memory.h" 17 #include "base/posix/eintr_wrapper.h" 18 #include "content/common/view_messages.h" 19 #include "media/base/android/webaudio_media_codec_info.h" 20 #include "media/base/audio_bus.h" 21 #include "media/base/limits.h" 22 #include "third_party/WebKit/public/platform/WebAudioBus.h" 23 24 namespace content { 25 26 class AudioDecoderIO { 27 public: 28 AudioDecoderIO(const char* data, size_t data_size); 29 ~AudioDecoderIO(); 30 bool ShareEncodedToProcess(base::SharedMemoryHandle* handle); 31 32 // Returns true if AudioDecoderIO was successfully created. 33 bool IsValid() const; 34 35 int read_fd() const { return read_fd_; } 36 int write_fd() const { return write_fd_; } 37 38 private: 39 // Shared memory that will hold the encoded audio data. This is 40 // used by MediaCodec for decoding. 41 base::SharedMemory encoded_shared_memory_; 42 43 // A pipe used to communicate with MediaCodec. MediaCodec owns 44 // write_fd_ and writes to it. 45 int read_fd_; 46 int write_fd_; 47 48 DISALLOW_COPY_AND_ASSIGN(AudioDecoderIO); 49 }; 50 51 AudioDecoderIO::AudioDecoderIO(const char* data, size_t data_size) 52 : read_fd_(-1), 53 write_fd_(-1) { 54 55 if (!data || !data_size || data_size > 0x80000000) 56 return; 57 58 // Create the shared memory and copy our data to it so that 59 // MediaCodec can access it. 60 encoded_shared_memory_.CreateAndMapAnonymous(data_size); 61 62 if (!encoded_shared_memory_.memory()) 63 return; 64 65 memcpy(encoded_shared_memory_.memory(), data, data_size); 66 67 // Create a pipe for reading/writing the decoded PCM data 68 int pipefd[2]; 69 70 if (pipe(pipefd)) 71 return; 72 73 read_fd_ = pipefd[0]; 74 write_fd_ = pipefd[1]; 75 } 76 77 AudioDecoderIO::~AudioDecoderIO() { 78 // Close the read end of the pipe. The write end should have been 79 // closed by MediaCodec. 80 if (read_fd_ >= 0 && close(read_fd_)) { 81 DVLOG(1) << "Cannot close read fd " << read_fd_ 82 << ": " << strerror(errno); 83 } 84 } 85 86 bool AudioDecoderIO::IsValid() const { 87 return read_fd_ >= 0 && write_fd_ >= 0 && 88 encoded_shared_memory_.memory(); 89 } 90 91 bool AudioDecoderIO::ShareEncodedToProcess(base::SharedMemoryHandle* handle) { 92 return encoded_shared_memory_.ShareToProcess( 93 base::Process::Current().handle(), 94 handle); 95 } 96 97 static float ConvertSampleToFloat(int16_t sample) { 98 const float kMaxScale = 1.0f / std::numeric_limits<int16_t>::max(); 99 const float kMinScale = -1.0f / std::numeric_limits<int16_t>::min(); 100 101 return sample * (sample < 0 ? kMinScale : kMaxScale); 102 } 103 104 // A basic WAVE file decoder. See 105 // https://ccrma.stanford.edu/courses/422/projects/WaveFormat/ for a 106 // basic guide to the WAVE file format. 107 class WAVEDecoder { 108 public: 109 WAVEDecoder(const uint8* data, size_t data_size); 110 ~WAVEDecoder(); 111 112 // Try to decode the data as a WAVE file. If the data is a supported 113 // WAVE file, |destination_bus| is filled with the decoded data and 114 // DecodeWAVEFile returns true. Otherwise, DecodeWAVEFile returns 115 // false. 116 bool DecodeWAVEFile(WebKit::WebAudioBus* destination_bus); 117 118 private: 119 // Minimum number of bytes in a WAVE file to hold all of the data we 120 // need to interpret it as a WAVE file. 121 static const unsigned kMinimumWAVLength = 44; 122 123 // Number of bytes in the chunk ID field. 124 static const unsigned kChunkIDLength = 4; 125 126 // Number of bytes in the chunk size field. 127 static const unsigned kChunkSizeLength = 4; 128 129 // Number of bytes in the format field of the "RIFF" chunk. 130 static const unsigned kFormatFieldLength = 4; 131 132 // Number of bytes in a valid "fmt" chunk. 133 static const unsigned kFMTChunkLength = 16; 134 135 // Supported audio format in a WAVE file. 136 // TODO(rtoy): Consider supporting other formats here, if necessary. 137 static const int16_t kAudioFormatPCM = 1; 138 139 // Maximum number (inclusive) of bytes per sample supported by this 140 // decoder. 141 static const unsigned kMaximumBytesPerSample = 3; 142 143 // Read an unsigned integer of |length| bytes from |buffer|. The 144 // integer is interpreted as being in little-endian order. 145 uint32_t ReadUnsignedInteger(const uint8_t* buffer, size_t length); 146 147 // Read a PCM sample from the WAVE data at |pcm_data|. 148 int16_t ReadPCMSample(const uint8_t* pcm_data); 149 150 // Read a WAVE chunk header including the chunk ID and chunk size. 151 // Returns false if the header could not be read. 152 bool ReadChunkHeader(); 153 154 // Read and parse the "fmt" chunk. Returns false if the fmt chunk 155 // could not be read or contained unsupported formats. 156 bool ReadFMTChunk(); 157 158 // Read data chunk and save it to |destination_bus|. Returns false 159 // if the data chunk could not be read correctly. 160 bool CopyDataChunkToBus(WebKit::WebAudioBus* destination_bus); 161 162 // The WAVE chunk ID that identifies the chunk. 163 uint8_t chunk_id_[kChunkIDLength]; 164 165 // The number of bytes in the data portion of the chunk. 166 size_t chunk_size_; 167 168 // The current position within the WAVE file. 169 const uint8_t* buffer_; 170 171 // Points one byte past the end of the in-memory WAVE file. Used for 172 // detecting if we've reached the end of the file. 173 const uint8_t* buffer_end_; 174 175 size_t bytes_per_sample_; 176 177 uint16_t number_of_channels_; 178 179 // Sample rate of the WAVE data, in Hz. 180 uint32_t sample_rate_; 181 182 DISALLOW_COPY_AND_ASSIGN(WAVEDecoder); 183 }; 184 185 WAVEDecoder::WAVEDecoder(const uint8_t* encoded_data, size_t data_size) 186 : buffer_(encoded_data), 187 buffer_end_(encoded_data + 1), 188 bytes_per_sample_(0), 189 number_of_channels_(0), 190 sample_rate_(0) { 191 if (buffer_ + data_size > buffer_) 192 buffer_end_ = buffer_ + data_size; 193 } 194 195 WAVEDecoder::~WAVEDecoder() {} 196 197 uint32_t WAVEDecoder::ReadUnsignedInteger(const uint8_t* buffer, 198 size_t length) { 199 unsigned value = 0; 200 201 if (length == 0 || length > sizeof(value)) { 202 DCHECK(false) << "ReadUnsignedInteger: Invalid length: " << length; 203 return 0; 204 } 205 206 // All integer fields in a WAVE file are little-endian. 207 for (size_t k = length; k > 0; --k) 208 value = (value << 8) + buffer[k - 1]; 209 210 return value; 211 } 212 213 int16_t WAVEDecoder::ReadPCMSample(const uint8_t* pcm_data) { 214 uint32_t unsigned_sample = ReadUnsignedInteger(pcm_data, bytes_per_sample_); 215 int16_t sample; 216 217 // Convert the unsigned data into a 16-bit PCM sample. 218 switch (bytes_per_sample_) { 219 case 1: 220 sample = (unsigned_sample - 128) << 8; 221 break; 222 case 2: 223 sample = static_cast<int16_t>(unsigned_sample); 224 break; 225 case 3: 226 // Android currently converts 24-bit WAVE data into 16-bit 227 // samples by taking the high-order 16 bits without rounding. 228 // We do the same here for consistency. 229 sample = static_cast<int16_t>(unsigned_sample >> 8); 230 break; 231 default: 232 sample = 0; 233 break; 234 } 235 return sample; 236 } 237 238 bool WAVEDecoder::ReadChunkHeader() { 239 if (buffer_ + kChunkIDLength + kChunkSizeLength >= buffer_end_) 240 return false; 241 242 memcpy(chunk_id_, buffer_, kChunkIDLength); 243 244 chunk_size_ = ReadUnsignedInteger(buffer_ + kChunkIDLength, kChunkSizeLength); 245 246 // Adjust for padding 247 if (chunk_size_ % 2) 248 ++chunk_size_; 249 250 return true; 251 } 252 253 bool WAVEDecoder::ReadFMTChunk() { 254 // The fmt chunk has basic info about the format of the audio 255 // data. Only a basic PCM format is supported. 256 if (chunk_size_ < kFMTChunkLength) { 257 DVLOG(1) << "FMT chunk too short: " << chunk_size_; 258 return 0; 259 } 260 261 uint16_t audio_format = ReadUnsignedInteger(buffer_, 2); 262 263 if (audio_format != kAudioFormatPCM) { 264 DVLOG(1) << "Audio format not supported: " << audio_format; 265 return false; 266 } 267 268 number_of_channels_ = ReadUnsignedInteger(buffer_ + 2, 2); 269 sample_rate_ = ReadUnsignedInteger(buffer_ + 4, 4); 270 unsigned bits_per_sample = ReadUnsignedInteger(buffer_ + 14, 2); 271 272 // Sanity checks. 273 274 if (!number_of_channels_ || 275 number_of_channels_ > media::limits::kMaxChannels) { 276 DVLOG(1) << "Unsupported number of channels: " << number_of_channels_; 277 return false; 278 } 279 280 if (sample_rate_ < media::limits::kMinSampleRate || 281 sample_rate_ > media::limits::kMaxSampleRate) { 282 DVLOG(1) << "Unsupported sample rate: " << sample_rate_; 283 return false; 284 } 285 286 // We only support 8, 16, and 24 bits per sample. 287 if (bits_per_sample == 8 || bits_per_sample == 16 || bits_per_sample == 24) { 288 bytes_per_sample_ = bits_per_sample / 8; 289 return true; 290 } 291 292 DVLOG(1) << "Unsupported bits per sample: " << bits_per_sample; 293 return false; 294 } 295 296 bool WAVEDecoder::CopyDataChunkToBus(WebKit::WebAudioBus* destination_bus) { 297 // The data chunk contains the audio data itself. 298 if (!bytes_per_sample_ || bytes_per_sample_ > kMaximumBytesPerSample) { 299 DVLOG(1) << "WARNING: data chunk without preceeding fmt chunk," 300 << " or invalid bytes per sample."; 301 return false; 302 } 303 304 VLOG(0) << "Decoding WAVE file: " << number_of_channels_ << " channels, " 305 << sample_rate_ << " kHz, " 306 << chunk_size_ / bytes_per_sample_ / number_of_channels_ 307 << " frames, " << 8 * bytes_per_sample_ << " bits/sample"; 308 309 // Create the destination bus of the appropriate size and then decode 310 // the data into the bus. 311 size_t number_of_frames = 312 chunk_size_ / bytes_per_sample_ / number_of_channels_; 313 314 destination_bus->initialize( 315 number_of_channels_, number_of_frames, sample_rate_); 316 317 for (size_t m = 0; m < number_of_frames; ++m) { 318 for (uint16_t k = 0; k < number_of_channels_; ++k) { 319 int16_t sample = ReadPCMSample(buffer_); 320 321 buffer_ += bytes_per_sample_; 322 destination_bus->channelData(k)[m] = ConvertSampleToFloat(sample); 323 } 324 } 325 326 return true; 327 } 328 329 bool WAVEDecoder::DecodeWAVEFile(WebKit::WebAudioBus* destination_bus) { 330 // Parse and decode WAVE file. If we can't parse it, return false. 331 332 if (buffer_ + kMinimumWAVLength > buffer_end_) { 333 DVLOG(1) << "Buffer too small to contain full WAVE header: "; 334 return false; 335 } 336 337 // Do we have a RIFF file? 338 ReadChunkHeader(); 339 if (memcmp(chunk_id_, "RIFF", kChunkIDLength) != 0) { 340 DVLOG(1) << "RIFF missing"; 341 return false; 342 } 343 buffer_ += kChunkIDLength + kChunkSizeLength; 344 345 // Check the format field of the RIFF chunk 346 memcpy(chunk_id_, buffer_, kFormatFieldLength); 347 if (memcmp(chunk_id_, "WAVE", kFormatFieldLength) != 0) { 348 DVLOG(1) << "Invalid WAVE file: missing WAVE header"; 349 return false; 350 } 351 // Advance past the format field 352 buffer_ += kFormatFieldLength; 353 354 // We have a WAVE file. Start parsing the chunks. 355 356 while (buffer_ < buffer_end_) { 357 if (!ReadChunkHeader()) { 358 DVLOG(1) << "Couldn't read chunk header"; 359 return false; 360 } 361 362 // Consume the chunk ID and chunk size 363 buffer_ += kChunkIDLength + kChunkSizeLength; 364 365 // Make sure we can read all chunk_size bytes. 366 if (buffer_ + chunk_size_ > buffer_end_) { 367 DVLOG(1) << "Insufficient bytes to read chunk of size " << chunk_size_; 368 return false; 369 } 370 371 if (memcmp(chunk_id_, "fmt ", kChunkIDLength) == 0) { 372 if (!ReadFMTChunk()) 373 return false; 374 } else if (memcmp(chunk_id_, "data", kChunkIDLength) == 0) { 375 // Return after reading the data chunk, whether we succeeded or 376 // not. 377 return CopyDataChunkToBus(destination_bus); 378 } else { 379 // Ignore these chunks that we don't know about. 380 VLOG(0) << "Ignoring WAVE chunk `" << chunk_id_ << "' size " 381 << chunk_size_; 382 } 383 384 // Advance to next chunk. 385 buffer_ += chunk_size_; 386 } 387 388 // If we get here, that means we didn't find a data chunk, so we 389 // couldn't handle this WAVE file. 390 391 return false; 392 } 393 394 // The number of frames is known so preallocate the destination 395 // bus and copy the pcm data to the destination bus as it's being 396 // received. 397 static void CopyPcmDataToBus(int input_fd, 398 WebKit::WebAudioBus* destination_bus, 399 size_t number_of_frames, 400 unsigned number_of_channels, 401 double file_sample_rate) { 402 destination_bus->initialize(number_of_channels, 403 number_of_frames, 404 file_sample_rate); 405 406 int16_t pipe_data[PIPE_BUF / sizeof(int16_t)]; 407 size_t decoded_frames = 0; 408 ssize_t nread; 409 410 while ((nread = HANDLE_EINTR(read(input_fd, pipe_data, sizeof(pipe_data)))) > 411 0) { 412 size_t samples_in_pipe = nread / sizeof(int16_t); 413 for (size_t m = 0; m < samples_in_pipe; m += number_of_channels) { 414 if (decoded_frames >= number_of_frames) 415 break; 416 417 for (size_t k = 0; k < number_of_channels; ++k) { 418 int16_t sample = pipe_data[m + k]; 419 destination_bus->channelData(k)[decoded_frames] = 420 ConvertSampleToFloat(sample); 421 } 422 ++decoded_frames; 423 } 424 } 425 } 426 427 // The number of frames is unknown, so keep reading and buffering 428 // until there's no more data and then copy the data to the 429 // destination bus. 430 static void BufferAndCopyPcmDataToBus(int input_fd, 431 WebKit::WebAudioBus* destination_bus, 432 unsigned number_of_channels, 433 double file_sample_rate) { 434 int16_t pipe_data[PIPE_BUF / sizeof(int16_t)]; 435 std::vector<int16_t> decoded_samples; 436 ssize_t nread; 437 438 while ((nread = HANDLE_EINTR(read(input_fd, pipe_data, sizeof(pipe_data)))) > 439 0) { 440 size_t samples_in_pipe = nread / sizeof(int16_t); 441 if (decoded_samples.size() + samples_in_pipe > decoded_samples.capacity()) { 442 decoded_samples.reserve(std::max(samples_in_pipe, 443 2 * decoded_samples.capacity())); 444 } 445 std::copy(pipe_data, 446 pipe_data + samples_in_pipe, 447 back_inserter(decoded_samples)); 448 } 449 450 DVLOG(1) << "Total samples read = " << decoded_samples.size(); 451 452 // Convert the samples and save them in the audio bus. 453 size_t number_of_samples = decoded_samples.size(); 454 size_t number_of_frames = decoded_samples.size() / number_of_channels; 455 size_t decoded_frames = 0; 456 457 destination_bus->initialize(number_of_channels, 458 number_of_frames, 459 file_sample_rate); 460 461 for (size_t m = 0; m < number_of_samples; m += number_of_channels) { 462 for (size_t k = 0; k < number_of_channels; ++k) { 463 int16_t sample = decoded_samples[m + k]; 464 destination_bus->channelData(k)[decoded_frames] = 465 ConvertSampleToFloat(sample); 466 } 467 ++decoded_frames; 468 } 469 } 470 471 static bool TryWAVEFileDecoder(WebKit::WebAudioBus* destination_bus, 472 const uint8_t* encoded_data, 473 size_t data_size) { 474 WAVEDecoder decoder(encoded_data, data_size); 475 476 return decoder.DecodeWAVEFile(destination_bus); 477 } 478 479 // To decode audio data, we want to use the Android MediaCodec class. 480 // But this can't run in a sandboxed process so we need initiate the 481 // request to MediaCodec in the browser. To do this, we create a 482 // shared memory buffer that holds the audio data. We send a message 483 // to the browser to start the decoder using this buffer and one end 484 // of a pipe. The MediaCodec class will decode the data from the 485 // shared memory and write the PCM samples back to us over a pipe. 486 bool DecodeAudioFileData(WebKit::WebAudioBus* destination_bus, const char* data, 487 size_t data_size, double sample_rate, 488 scoped_refptr<ThreadSafeSender> sender) { 489 // Try to decode the data as a WAVE file first. If it can't be 490 // decoded, use MediaCodec. See crbug.com/259048. 491 if (TryWAVEFileDecoder( 492 destination_bus, reinterpret_cast<const uint8_t*>(data), data_size)) { 493 return true; 494 } 495 496 AudioDecoderIO audio_decoder(data, data_size); 497 498 if (!audio_decoder.IsValid()) 499 return false; 500 501 base::SharedMemoryHandle encoded_data_handle; 502 audio_decoder.ShareEncodedToProcess(&encoded_data_handle); 503 base::FileDescriptor fd(audio_decoder.write_fd(), true); 504 505 DVLOG(1) << "DecodeAudioFileData: Starting MediaCodec"; 506 507 // Start MediaCodec processing in the browser which will read from 508 // encoded_data_handle for our shared memory and write the decoded 509 // PCM samples (16-bit integer) to our pipe. 510 511 sender->Send(new ViewHostMsg_RunWebAudioMediaCodec( 512 encoded_data_handle, fd, data_size)); 513 514 // First, read the number of channels, the sample rate, and the 515 // number of frames and a flag indicating if the file is an 516 // ogg/vorbis file. This must be coordinated with 517 // WebAudioMediaCodecBridge! 518 // 519 // If we know the number of samples, we can create the destination 520 // bus directly and do the conversion directly to the bus instead of 521 // buffering up everything before saving the data to the bus. 522 523 int input_fd = audio_decoder.read_fd(); 524 struct media::WebAudioMediaCodecInfo info; 525 526 DVLOG(1) << "Reading audio file info from fd " << input_fd; 527 ssize_t nread = HANDLE_EINTR(read(input_fd, &info, sizeof(info))); 528 DVLOG(1) << "read: " << nread << " bytes:\n" 529 << " 0: number of channels = " << info.channel_count << "\n" 530 << " 1: sample rate = " << info.sample_rate << "\n" 531 << " 2: number of frames = " << info.number_of_frames << "\n"; 532 533 if (nread != sizeof(info)) 534 return false; 535 536 unsigned number_of_channels = info.channel_count; 537 double file_sample_rate = static_cast<double>(info.sample_rate); 538 size_t number_of_frames = info.number_of_frames; 539 540 // Sanity checks 541 if (!number_of_channels || 542 number_of_channels > media::limits::kMaxChannels || 543 file_sample_rate < media::limits::kMinSampleRate || 544 file_sample_rate > media::limits::kMaxSampleRate) { 545 return false; 546 } 547 548 if (number_of_frames > 0) { 549 CopyPcmDataToBus(input_fd, 550 destination_bus, 551 number_of_frames, 552 number_of_channels, 553 file_sample_rate); 554 } else { 555 BufferAndCopyPcmDataToBus(input_fd, 556 destination_bus, 557 number_of_channels, 558 file_sample_rate); 559 } 560 561 return true; 562 } 563 564 } // namespace content 565