- add sources.
[platform/framework/web/crosswalk.git] / src / media / cast / audio_receiver / audio_decoder.cc
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 "base/logging.h"
6 #include "media/cast/audio_receiver/audio_decoder.h"
7
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"
10
11 namespace media {
12 namespace cast {
13
14 AudioDecoder::AudioDecoder(const AudioReceiverConfig& audio_config)
15     : audio_decoder_(webrtc::AudioCodingModule::Create(0)),
16       have_received_packets_(false) {
17   audio_decoder_->InitializeReceiver();
18
19   webrtc::CodecInst receive_codec;
20   switch (audio_config.codec) {
21     case kPcm16:
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;
28       break;
29     case kOpus:
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;
36       break;
37     case kExternalAudio:
38       DCHECK(false) << "Codec must be specified for audio decoder";
39       break;
40   }
41   if (audio_decoder_->RegisterReceiveCodec(receive_codec) != 0) {
42     DCHECK(false) << "Failed to register receive codec";
43   }
44
45   audio_decoder_->SetMaximumPlayoutDelay(audio_config.rtp_max_delay_ms);
46   audio_decoder_->SetPlayoutMode(webrtc::streaming);
47 }
48
49 AudioDecoder::~AudioDecoder() {}
50
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;
56
57   audio_frame->samples.clear();
58
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)) {
63       return false;
64     }
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.
68       return false;
69     }
70     audio_frame->frequency = webrtc_audio_frame.sample_rate_hz_;
71     audio_frame->channels = webrtc_audio_frame.num_channels_;
72
73     if (i == 0) {
74       // Use the timestamp from the first 10ms block.
75       if (0 != audio_decoder_->PlayoutTimestamp(rtp_timestamp)) {
76         return false;
77       }
78     }
79     int samples_per_10ms = webrtc_audio_frame.samples_per_channel_;
80
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]);
85   }
86   return true;
87 }
88
89 void AudioDecoder::IncomingParsedRtpPacket(const uint8* payload_data,
90                                            size_t payload_size,
91                                            const RtpCastHeader& rtp_header) {
92   DCHECK_LE(payload_size, kIpPacketSize);
93   audio_decoder_->IncomingPacket(payload_data, static_cast<int32>(payload_size),
94                                  rtp_header.webrtc);
95   have_received_packets_ = true;
96 }
97
98 }  // namespace cast
99 }  // namespace media