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(blink::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(blink::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(blink::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(blink::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 blink::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 // number_of_frames is only an estimate. Resize the buffer with the 427 // actual number of received frames. 428 if (decoded_frames < number_of_frames) 429 destination_bus->resizeSmaller(decoded_frames); 430 } 431 432 // The number of frames is unknown, so keep reading and buffering 433 // until there's no more data and then copy the data to the 434 // destination bus. 435 static void BufferAndCopyPcmDataToBus(int input_fd, 436 blink::WebAudioBus* destination_bus, 437 unsigned number_of_channels, 438 double file_sample_rate) { 439 int16_t pipe_data[PIPE_BUF / sizeof(int16_t)]; 440 std::vector<int16_t> decoded_samples; 441 ssize_t nread; 442 443 while ((nread = HANDLE_EINTR(read(input_fd, pipe_data, sizeof(pipe_data)))) > 444 0) { 445 size_t samples_in_pipe = nread / sizeof(int16_t); 446 if (decoded_samples.size() + samples_in_pipe > decoded_samples.capacity()) { 447 decoded_samples.reserve(std::max(samples_in_pipe, 448 2 * decoded_samples.capacity())); 449 } 450 std::copy(pipe_data, 451 pipe_data + samples_in_pipe, 452 back_inserter(decoded_samples)); 453 } 454 455 DVLOG(1) << "Total samples read = " << decoded_samples.size(); 456 457 // Convert the samples and save them in the audio bus. 458 size_t number_of_samples = decoded_samples.size(); 459 size_t number_of_frames = decoded_samples.size() / number_of_channels; 460 size_t decoded_frames = 0; 461 462 destination_bus->initialize(number_of_channels, 463 number_of_frames, 464 file_sample_rate); 465 466 for (size_t m = 0; m < number_of_samples; m += number_of_channels) { 467 for (size_t k = 0; k < number_of_channels; ++k) { 468 int16_t sample = decoded_samples[m + k]; 469 destination_bus->channelData(k)[decoded_frames] = 470 ConvertSampleToFloat(sample); 471 } 472 ++decoded_frames; 473 } 474 475 // number_of_frames is only an estimate. Resize the buffer with the 476 // actual number of received frames. 477 if (decoded_frames < number_of_frames) 478 destination_bus->resizeSmaller(decoded_frames); 479 } 480 481 static bool TryWAVEFileDecoder(blink::WebAudioBus* destination_bus, 482 const uint8_t* encoded_data, 483 size_t data_size) { 484 WAVEDecoder decoder(encoded_data, data_size); 485 486 return decoder.DecodeWAVEFile(destination_bus); 487 } 488 489 // To decode audio data, we want to use the Android MediaCodec class. 490 // But this can't run in a sandboxed process so we need initiate the 491 // request to MediaCodec in the browser. To do this, we create a 492 // shared memory buffer that holds the audio data. We send a message 493 // to the browser to start the decoder using this buffer and one end 494 // of a pipe. The MediaCodec class will decode the data from the 495 // shared memory and write the PCM samples back to us over a pipe. 496 bool DecodeAudioFileData(blink::WebAudioBus* destination_bus, const char* data, 497 size_t data_size, double sample_rate, 498 scoped_refptr<ThreadSafeSender> sender) { 499 // Try to decode the data as a WAVE file first. If it can't be 500 // decoded, use MediaCodec. See crbug.com/259048. 501 if (TryWAVEFileDecoder( 502 destination_bus, reinterpret_cast<const uint8_t*>(data), data_size)) { 503 return true; 504 } 505 506 AudioDecoderIO audio_decoder(data, data_size); 507 508 if (!audio_decoder.IsValid()) 509 return false; 510 511 base::SharedMemoryHandle encoded_data_handle; 512 audio_decoder.ShareEncodedToProcess(&encoded_data_handle); 513 base::FileDescriptor fd(audio_decoder.write_fd(), true); 514 515 DVLOG(1) << "DecodeAudioFileData: Starting MediaCodec"; 516 517 // Start MediaCodec processing in the browser which will read from 518 // encoded_data_handle for our shared memory and write the decoded 519 // PCM samples (16-bit integer) to our pipe. 520 521 sender->Send(new ViewHostMsg_RunWebAudioMediaCodec( 522 encoded_data_handle, fd, data_size)); 523 524 // First, read the number of channels, the sample rate, and the 525 // number of frames and a flag indicating if the file is an 526 // ogg/vorbis file. This must be coordinated with 527 // WebAudioMediaCodecBridge! 528 // 529 // If we know the number of samples, we can create the destination 530 // bus directly and do the conversion directly to the bus instead of 531 // buffering up everything before saving the data to the bus. 532 533 int input_fd = audio_decoder.read_fd(); 534 struct media::WebAudioMediaCodecInfo info; 535 536 DVLOG(1) << "Reading audio file info from fd " << input_fd; 537 ssize_t nread = HANDLE_EINTR(read(input_fd, &info, sizeof(info))); 538 DVLOG(1) << "read: " << nread << " bytes:\n" 539 << " 0: number of channels = " << info.channel_count << "\n" 540 << " 1: sample rate = " << info.sample_rate << "\n" 541 << " 2: number of frames = " << info.number_of_frames << "\n"; 542 543 if (nread != sizeof(info)) 544 return false; 545 546 unsigned number_of_channels = info.channel_count; 547 double file_sample_rate = static_cast<double>(info.sample_rate); 548 size_t number_of_frames = info.number_of_frames; 549 550 // Sanity checks 551 if (!number_of_channels || 552 number_of_channels > media::limits::kMaxChannels || 553 file_sample_rate < media::limits::kMinSampleRate || 554 file_sample_rate > media::limits::kMaxSampleRate) { 555 return false; 556 } 557 558 if (number_of_frames > 0) { 559 CopyPcmDataToBus(input_fd, 560 destination_bus, 561 number_of_frames, 562 number_of_channels, 563 file_sample_rate); 564 } else { 565 BufferAndCopyPcmDataToBus(input_fd, 566 destination_bus, 567 number_of_channels, 568 file_sample_rate); 569 } 570 571 return true; 572 } 573 574 } // namespace content 575