audio_decoder_opus.cc 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. // Copyright (c) 2012 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. #include "remoting/codec/audio_decoder_opus.h"
  5. #include <stdint.h>
  6. #include "base/logging.h"
  7. #include "base/time/time.h"
  8. #include "remoting/proto/audio.pb.h"
  9. #include "third_party/opus/src/include/opus.h"
  10. namespace remoting {
  11. namespace {
  12. // Maximum size of an Opus frame in milliseconds.
  13. const int kMaxFrameSizeMs = 120;
  14. // Hosts will never generate more than 100 frames in a single packet.
  15. const int kMaxFramesPerPacket = 100;
  16. const AudioPacket::SamplingRate kSamplingRate =
  17. AudioPacket::SAMPLING_RATE_48000;
  18. } // namespace
  19. AudioDecoderOpus::AudioDecoderOpus()
  20. : sampling_rate_(0), channels_(0), decoder_(nullptr) {}
  21. AudioDecoderOpus::~AudioDecoderOpus() {
  22. DestroyDecoder();
  23. }
  24. void AudioDecoderOpus::InitDecoder() {
  25. DCHECK(!decoder_);
  26. int error;
  27. decoder_ = opus_decoder_create(kSamplingRate, channels_, &error);
  28. if (!decoder_) {
  29. LOG(ERROR) << "Failed to create OPUS decoder; Error code: " << error;
  30. }
  31. }
  32. void AudioDecoderOpus::DestroyDecoder() {
  33. if (decoder_) {
  34. opus_decoder_destroy(decoder_);
  35. decoder_ = nullptr;
  36. }
  37. }
  38. bool AudioDecoderOpus::ResetForPacket(AudioPacket* packet) {
  39. if (packet->channels() != channels_ ||
  40. packet->sampling_rate() != sampling_rate_) {
  41. DestroyDecoder();
  42. channels_ = packet->channels();
  43. sampling_rate_ = packet->sampling_rate();
  44. if (channels_ <= 0 || channels_ > 2 ||
  45. sampling_rate_ != kSamplingRate) {
  46. LOG(WARNING) << "Unsupported OPUS parameters: "
  47. << channels_ << " channels with "
  48. << sampling_rate_ << " samples per second.";
  49. return false;
  50. }
  51. }
  52. if (!decoder_) {
  53. InitDecoder();
  54. }
  55. return decoder_ != nullptr;
  56. }
  57. std::unique_ptr<AudioPacket> AudioDecoderOpus::Decode(
  58. std::unique_ptr<AudioPacket> packet) {
  59. if (packet->encoding() != AudioPacket::ENCODING_OPUS) {
  60. LOG(WARNING) << "Received an audio packet with encoding "
  61. << packet->encoding() << " when an OPUS packet was expected.";
  62. return nullptr;
  63. }
  64. if (packet->data_size() > kMaxFramesPerPacket) {
  65. LOG(WARNING) << "Received an packet with too many frames.";
  66. return nullptr;
  67. }
  68. if (!ResetForPacket(packet.get())) {
  69. return nullptr;
  70. }
  71. // Create a new packet of decoded data.
  72. std::unique_ptr<AudioPacket> decoded_packet(new AudioPacket());
  73. decoded_packet->set_encoding(AudioPacket::ENCODING_RAW);
  74. decoded_packet->set_sampling_rate(kSamplingRate);
  75. decoded_packet->set_bytes_per_sample(AudioPacket::BYTES_PER_SAMPLE_2);
  76. decoded_packet->set_channels(packet->channels());
  77. int max_frame_samples = kMaxFrameSizeMs * kSamplingRate /
  78. base::Time::kMillisecondsPerSecond;
  79. int max_frame_bytes = max_frame_samples * channels_ *
  80. decoded_packet->bytes_per_sample();
  81. std::string* decoded_data = decoded_packet->add_data();
  82. decoded_data->resize(packet->data_size() * max_frame_bytes);
  83. int buffer_pos = 0;
  84. for (int i = 0; i < packet->data_size(); ++i) {
  85. int16_t* pcm_buffer =
  86. reinterpret_cast<int16_t*>(std::data(*decoded_data) + buffer_pos);
  87. CHECK_LE(buffer_pos + max_frame_bytes,
  88. static_cast<int>(decoded_data->size()));
  89. std::string* frame = packet->mutable_data(i);
  90. unsigned char* frame_data =
  91. reinterpret_cast<unsigned char*>(std::data(*frame));
  92. int result = opus_decode(decoder_, frame_data, frame->size(),
  93. pcm_buffer, max_frame_samples, 0);
  94. if (result < 0) {
  95. LOG(ERROR) << "Failed decoding Opus frame. Error code: " << result;
  96. DestroyDecoder();
  97. return nullptr;
  98. }
  99. buffer_pos += result * packet->channels() *
  100. decoded_packet->bytes_per_sample();
  101. }
  102. if (!buffer_pos) {
  103. return nullptr;
  104. }
  105. decoded_data->resize(buffer_pos);
  106. return decoded_packet;
  107. }
  108. } // namespace remoting