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.
5 #include "base/logging.h"
6 #include "media/cast/audio_receiver/audio_decoder.h"
8 #include "third_party/webrtc/modules/audio_coding/main/interface/audio_coding_module.h"
9 #include "third_party/webrtc/modules/interface/module_common_types.h"
14 AudioDecoder::AudioDecoder(const AudioReceiverConfig
& audio_config
)
15 : audio_decoder_(webrtc::AudioCodingModule::Create(0)),
16 have_received_packets_(false) {
17 audio_decoder_
->InitializeReceiver();
19 webrtc::CodecInst receive_codec
;
20 switch (audio_config
.codec
) {
22 receive_codec
.pltype
= audio_config
.rtp_payload_type
;
23 strncpy(receive_codec
.plname
, "L16", 4);
24 receive_codec
.plfreq
= audio_config
.frequency
;
25 receive_codec
.pacsize
= -1;
26 receive_codec
.channels
= audio_config
.channels
;
27 receive_codec
.rate
= -1;
30 receive_codec
.pltype
= audio_config
.rtp_payload_type
;
31 strncpy(receive_codec
.plname
, "opus", 5);
32 receive_codec
.plfreq
= audio_config
.frequency
;
33 receive_codec
.pacsize
= -1;
34 receive_codec
.channels
= audio_config
.channels
;
35 receive_codec
.rate
= -1;
38 DCHECK(false) << "Codec must be specified for audio decoder";
41 if (audio_decoder_
->RegisterReceiveCodec(receive_codec
) != 0) {
42 DCHECK(false) << "Failed to register receive codec";
45 audio_decoder_
->SetMaximumPlayoutDelay(audio_config
.rtp_max_delay_ms
);
46 audio_decoder_
->SetPlayoutMode(webrtc::streaming
);
49 AudioDecoder::~AudioDecoder() {}
51 bool AudioDecoder::GetRawAudioFrame(int number_of_10ms_blocks
,
52 int desired_frequency
,
53 PcmAudioFrame
* audio_frame
,
54 uint32
* rtp_timestamp
) {
55 if (!have_received_packets_
) return false;
57 audio_frame
->samples
.clear();
59 for (int i
= 0; i
< number_of_10ms_blocks
; ++i
) {
60 webrtc::AudioFrame webrtc_audio_frame
;
61 if (0 != audio_decoder_
->PlayoutData10Ms(desired_frequency
,
62 &webrtc_audio_frame
)) {
65 if (webrtc_audio_frame
.speech_type_
== webrtc::AudioFrame::kPLCCNG
||
66 webrtc_audio_frame
.speech_type_
== webrtc::AudioFrame::kUndefined
) {
67 // We are only interested in real decoded audio.
70 audio_frame
->frequency
= webrtc_audio_frame
.sample_rate_hz_
;
71 audio_frame
->channels
= webrtc_audio_frame
.num_channels_
;
74 // Use the timestamp from the first 10ms block.
75 if (0 != audio_decoder_
->PlayoutTimestamp(rtp_timestamp
)) {
79 int samples_per_10ms
= webrtc_audio_frame
.samples_per_channel_
;
81 audio_frame
->samples
.insert(
82 audio_frame
->samples
.end(),
83 &webrtc_audio_frame
.data_
[0],
84 &webrtc_audio_frame
.data_
[samples_per_10ms
* audio_frame
->channels
]);
89 void AudioDecoder::IncomingParsedRtpPacket(const uint8
* payload_data
,
91 const RtpCastHeader
& rtp_header
) {
92 DCHECK_LE(payload_size
, kIpPacketSize
);
93 audio_decoder_
->IncomingPacket(payload_data
, static_cast<int32
>(payload_size
),
95 have_received_packets_
= true;