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.
5 #include "remoting/codec/audio_decoder_opus.h"
7 #include "base/logging.h"
8 #include "base/stl_util.h"
9 #include "base/time/time.h"
10 #include "remoting/proto/audio.pb.h"
11 #include "third_party/opus/src/include/opus.h"
17 // Maximum size of an Opus frame in milliseconds.
18 const int kMaxFrameSizeMs
= 120;
20 // Hosts will never generate more than 100 frames in a single packet.
21 const int kMaxFramesPerPacket
= 100;
23 const AudioPacket::SamplingRate kSamplingRate
=
24 AudioPacket::SAMPLING_RATE_48000
;
28 AudioDecoderOpus::AudioDecoderOpus()
29 : sampling_rate_(0), channels_(0), decoder_(nullptr) {}
31 AudioDecoderOpus::~AudioDecoderOpus() {
35 void AudioDecoderOpus::InitDecoder() {
38 decoder_
= opus_decoder_create(kSamplingRate
, channels_
, &error
);
40 LOG(ERROR
) << "Failed to create OPUS decoder; Error code: " << error
;
44 void AudioDecoderOpus::DestroyDecoder() {
46 opus_decoder_destroy(decoder_
);
51 bool AudioDecoderOpus::ResetForPacket(AudioPacket
* packet
) {
52 if (packet
->channels() != channels_
||
53 packet
->sampling_rate() != sampling_rate_
) {
56 channels_
= packet
->channels();
57 sampling_rate_
= packet
->sampling_rate();
59 if (channels_
<= 0 || channels_
> 2 ||
60 sampling_rate_
!= kSamplingRate
) {
61 LOG(WARNING
) << "Unsupported OPUS parameters: "
62 << channels_
<< " channels with "
63 << sampling_rate_
<< " samples per second.";
72 return decoder_
!= nullptr;
76 scoped_ptr
<AudioPacket
> AudioDecoderOpus::Decode(
77 scoped_ptr
<AudioPacket
> packet
) {
78 if (packet
->encoding() != AudioPacket::ENCODING_OPUS
) {
79 LOG(WARNING
) << "Received an audio packet with encoding "
80 << packet
->encoding() << " when an OPUS packet was expected.";
83 if (packet
->data_size() > kMaxFramesPerPacket
) {
84 LOG(WARNING
) << "Received an packet with too many frames.";
88 if (!ResetForPacket(packet
.get())) {
92 // Create a new packet of decoded data.
93 scoped_ptr
<AudioPacket
> decoded_packet(new AudioPacket());
94 decoded_packet
->set_encoding(AudioPacket::ENCODING_RAW
);
95 decoded_packet
->set_sampling_rate(kSamplingRate
);
96 decoded_packet
->set_bytes_per_sample(AudioPacket::BYTES_PER_SAMPLE_2
);
97 decoded_packet
->set_channels(packet
->channels());
99 int max_frame_samples
= kMaxFrameSizeMs
* kSamplingRate
/
100 base::Time::kMillisecondsPerSecond
;
101 int max_frame_bytes
= max_frame_samples
* channels_
*
102 decoded_packet
->bytes_per_sample();
104 std::string
* decoded_data
= decoded_packet
->add_data();
105 decoded_data
->resize(packet
->data_size() * max_frame_bytes
);
108 for (int i
= 0; i
< packet
->data_size(); ++i
) {
110 reinterpret_cast<int16
*>(string_as_array(decoded_data
) + buffer_pos
);
111 CHECK_LE(buffer_pos
+ max_frame_bytes
,
112 static_cast<int>(decoded_data
->size()));
113 std::string
* frame
= packet
->mutable_data(i
);
114 unsigned char* frame_data
=
115 reinterpret_cast<unsigned char*>(string_as_array(frame
));
116 int result
= opus_decode(decoder_
, frame_data
, frame
->size(),
117 pcm_buffer
, max_frame_samples
, 0);
119 LOG(ERROR
) << "Failed decoding Opus frame. Error code: " << result
;
124 buffer_pos
+= result
* packet
->channels() *
125 decoded_packet
->bytes_per_sample();
132 decoded_data
->resize(buffer_pos
);
134 return decoded_packet
.Pass();
137 } // namespace remoting