1d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// found in the LICENSE file.
4d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
5d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "media/cast/audio_receiver/audio_receiver.h"
6d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
7d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/bind.h"
8d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/logging.h"
9d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/message_loop/message_loop.h"
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "crypto/encryptor.h"
11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "crypto/symmetric_key.h"
12d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "media/cast/audio_receiver/audio_decoder.h"
13d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "media/cast/framer/framer.h"
14d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "media/cast/rtcp/rtcp.h"
15d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "media/cast/rtp_receiver/rtp_receiver.h"
16d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Max time we wait until an audio frame is due to be played out is released.
184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)static const int64 kMaxAudioFrameWaitMs = 20;
194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)static const int64 kMinSchedulingDelayMs = 1;
20d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
21d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace media {
22d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace cast {
23d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)DecodedAudioCallbackData::DecodedAudioCallbackData()
25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    : number_of_10ms_blocks(0),
26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      desired_frequency(0),
27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      callback() {}
28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
29a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)DecodedAudioCallbackData::~DecodedAudioCallbackData() {}
30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
31d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Local implementation of RtpData (defined in rtp_rtcp_defines.h).
32d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Used to pass payload data into the audio receiver.
33d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class LocalRtpAudioData : public RtpData {
34d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public:
351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  explicit LocalRtpAudioData(AudioReceiver* audio_receiver)
361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      : audio_receiver_(audio_receiver) {}
37d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
38d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  virtual void OnReceivedPayloadData(
39d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      const uint8* payload_data,
408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      size_t payload_size,
41d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      const RtpCastHeader* rtp_header) OVERRIDE {
42d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    audio_receiver_->IncomingParsedRtpPacket(payload_data, payload_size,
43d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                             *rtp_header);
44d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
45d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
46d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private:
47d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  AudioReceiver* audio_receiver_;
48d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)};
49d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
50d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Local implementation of RtpPayloadFeedback (defined in rtp_defines.h)
51d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Used to convey cast-specific feedback from receiver to sender.
52d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class LocalRtpAudioFeedback : public RtpPayloadFeedback {
53d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public:
54d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  explicit LocalRtpAudioFeedback(AudioReceiver* audio_receiver)
55d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      : audio_receiver_(audio_receiver) {
56d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
57d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
58d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  virtual void CastFeedback(const RtcpCastMessage& cast_message) OVERRIDE {
59d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    audio_receiver_->CastFeedback(cast_message);
60d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
61d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
62d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private:
63d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  AudioReceiver* audio_receiver_;
64d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)};
65d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
66d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class LocalRtpReceiverStatistics : public RtpReceiverStatistics {
67d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public:
68d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  explicit LocalRtpReceiverStatistics(RtpReceiver* rtp_receiver)
69d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)     : rtp_receiver_(rtp_receiver) {
70d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
71d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
72d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  virtual void GetStatistics(uint8* fraction_lost,
73d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                             uint32* cumulative_lost,  // 24 bits valid.
74d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                             uint32* extended_high_sequence_number,
75d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                             uint32* jitter) OVERRIDE {
76d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    rtp_receiver_->GetStatistics(fraction_lost,
77d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                 cumulative_lost,
78d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                 extended_high_sequence_number,
79d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                 jitter);
80d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
81d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
82d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private:
83d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  RtpReceiver* rtp_receiver_;
84d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)};
85d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)AudioReceiver::AudioReceiver(scoped_refptr<CastEnvironment> cast_environment,
87d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                             const AudioReceiverConfig& audio_config,
88d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                             PacedPacketSender* const packet_sender)
894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    : cast_environment_(cast_environment),
90d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      codec_(audio_config.codec),
91d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      frequency_(audio_config.frequency),
92d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      audio_buffer_(),
93d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      audio_decoder_(),
94d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      time_offset_(),
95d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      weak_factory_(this) {
96d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  target_delay_delta_ =
97d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      base::TimeDelta::FromMilliseconds(audio_config.rtp_max_delay_ms);
981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  incoming_payload_callback_.reset(new LocalRtpAudioData(this));
99d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  incoming_payload_feedback_.reset(new LocalRtpAudioFeedback(this));
100d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (audio_config.use_external_decoder) {
1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    audio_buffer_.reset(new Framer(cast_environment->Clock(),
1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                   incoming_payload_feedback_.get(),
1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                   audio_config.incoming_ssrc,
1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                   true,
1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                   0));
106d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  } else {
107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    audio_decoder_.reset(new AudioDecoder(cast_environment,
108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                          audio_config,
109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                          incoming_payload_feedback_.get()));
110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (audio_config.aes_iv_mask.size() == kAesKeySize &&
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      audio_config.aes_key.size() == kAesKeySize) {
113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    iv_mask_ = audio_config.aes_iv_mask;
114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    crypto::SymmetricKey* key = crypto::SymmetricKey::Import(
115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        crypto::SymmetricKey::AES, audio_config.aes_key);
116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    decryptor_.reset(new crypto::Encryptor());
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    decryptor_->Init(key, crypto::Encryptor::CTR, std::string());
118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } else if (audio_config.aes_iv_mask.size() != 0 ||
119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)             audio_config.aes_key.size() != 0) {
120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK(false) << "Invalid crypto configuration";
121d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  rtp_receiver_.reset(new RtpReceiver(cast_environment->Clock(),
1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                      &audio_config,
1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                      NULL,
1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                      incoming_payload_callback_.get()));
127d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  rtp_audio_receiver_statistics_.reset(
128d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      new LocalRtpReceiverStatistics(rtp_receiver_.get()));
129d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  base::TimeDelta rtcp_interval_delta =
130d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      base::TimeDelta::FromMilliseconds(audio_config.rtcp_interval);
131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  rtcp_.reset(new Rtcp(cast_environment,
1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                       NULL,
1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                       packet_sender,
1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                       NULL,
1354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                       rtp_audio_receiver_statistics_.get(),
1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                       audio_config.rtcp_mode,
1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                       rtcp_interval_delta,
1384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                       audio_config.feedback_ssrc,
139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       audio_config.incoming_ssrc,
1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                       audio_config.rtcp_c_name));
141d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
142d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
143d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)AudioReceiver::~AudioReceiver() {}
144d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AudioReceiver::InitializeTimers() {
146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ScheduleNextRtcpReport();
148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ScheduleNextCastMessage();
149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
151d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void AudioReceiver::IncomingParsedRtpPacket(const uint8* payload_data,
1528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                            size_t payload_size,
153d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                            const RtpCastHeader& rtp_header) {
154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  cast_environment_->Logging()->InsertPacketEvent(kPacketReceived,
156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      rtp_header.webrtc.header.timestamp, rtp_header.frame_id,
157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      rtp_header.packet_id, rtp_header.max_packet_id, payload_size);
158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // TODO(pwestin): update this as video to refresh over time.
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
1611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (time_first_incoming_packet_.is_null()) {
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    InitializeTimers();
1631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    first_incoming_rtp_timestamp_ = rtp_header.webrtc.header.timestamp;
1641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    time_first_incoming_packet_ =  cast_environment_->Clock()->NowTicks();
1651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
1661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
167d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (audio_decoder_) {
168d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    DCHECK(!audio_buffer_) << "Invalid internal state";
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    std::string plaintext(reinterpret_cast<const char*>(payload_data),
170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                          payload_size);
171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (decryptor_) {
172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      plaintext.clear();
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      if (!decryptor_->SetCounter(GetAesNonce(rtp_header.frame_id, iv_mask_))) {
174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        NOTREACHED() << "Failed to set counter";
175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        return;
176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      }
177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      if (!decryptor_->Decrypt(base::StringPiece(reinterpret_cast<const char*>(
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          payload_data), payload_size), &plaintext)) {
179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        VLOG(0) << "Decryption error";
180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        return;
181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      }
182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    audio_decoder_->IncomingParsedRtpPacket(
184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        reinterpret_cast<const uint8*>(plaintext.data()), plaintext.size(),
185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        rtp_header);
186a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (!queued_decoded_callbacks_.empty()) {
187a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      DecodedAudioCallbackData decoded_data = queued_decoded_callbacks_.front();
188a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      queued_decoded_callbacks_.pop_front();
189a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      cast_environment_->PostTask(CastEnvironment::AUDIO_DECODER, FROM_HERE,
190d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)        base::Bind(&AudioReceiver::DecodeAudioFrameThread,
191d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)                   base::Unretained(this),
192d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)                   decoded_data.number_of_10ms_blocks,
193d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)                   decoded_data.desired_frequency,
194d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)                   decoded_data.callback));
195a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
196d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
197d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
198a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(audio_buffer_) << "Invalid internal state";
2004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(!audio_decoder_) << "Invalid internal state";
201a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  bool complete = audio_buffer_->InsertPacket(payload_data, payload_size,
2034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                              rtp_header);
2044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!complete) return;  // Audio frame not complete; wait for more packets.
205a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (queued_encoded_callbacks_.empty()) return;
2064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  AudioFrameEncodedCallback callback = queued_encoded_callbacks_.front();
2074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  queued_encoded_callbacks_.pop_front();
2084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
2094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      base::Bind(&AudioReceiver::GetEncodedAudioFrame,
210a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      weak_factory_.GetWeakPtr(), callback));
211d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
212d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
213d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void AudioReceiver::GetRawAudioFrame(int number_of_10ms_blocks,
2144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      int desired_frequency, const AudioFrameDecodedCallback& callback) {
215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
216d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DCHECK(audio_decoder_) << "Invalid function call in this configuration";
217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // TODO(pwestin): we can skip this function by posting direct to the decoder.
2184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  cast_environment_->PostTask(CastEnvironment::AUDIO_DECODER, FROM_HERE,
2194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      base::Bind(&AudioReceiver::DecodeAudioFrameThread,
220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                 base::Unretained(this),
2214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                 number_of_10ms_blocks,
2224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                 desired_frequency,
2234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                 callback));
224d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
225d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
226d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void AudioReceiver::DecodeAudioFrameThread(
227d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    int number_of_10ms_blocks,
228d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    int desired_frequency,
229d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    const AudioFrameDecodedCallback callback) {
2304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::AUDIO_DECODER));
231d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // TODO(mikhal): Allow the application to allocate this memory.
232d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  scoped_ptr<PcmAudioFrame> audio_frame(new PcmAudioFrame());
233d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
234d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  uint32 rtp_timestamp = 0;
235d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!audio_decoder_->GetRawAudioFrame(number_of_10ms_blocks,
236d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                        desired_frequency,
237d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                        audio_frame.get(),
238d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                        &rtp_timestamp)) {
239a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    DecodedAudioCallbackData callback_data;
240a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    callback_data.number_of_10ms_blocks = number_of_10ms_blocks;
241a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    callback_data.desired_frequency = desired_frequency;
242a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    callback_data.callback = callback;
243a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    queued_decoded_callbacks_.push_back(callback_data);
244d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
245d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
2464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::TimeTicks now = cast_environment_->Clock()->NowTicks();
247a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
248a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
249a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      base::Bind(&AudioReceiver::ReturnDecodedFrameWithPlayoutDelay,
250a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      base::Unretained(this), base::Passed(&audio_frame), rtp_timestamp,
251a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      callback));
252a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
253a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
254a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void AudioReceiver::ReturnDecodedFrameWithPlayoutDelay(
255a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    scoped_ptr<PcmAudioFrame> audio_frame, uint32 rtp_timestamp,
256a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const AudioFrameDecodedCallback callback) {
257a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
258a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  cast_environment_->Logging()->InsertFrameEvent(kAudioFrameDecoded,
259a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      rtp_timestamp, kFrameIdUnknown);
260a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
261a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::TimeTicks now = cast_environment_->Clock()->NowTicks();
262a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::TimeTicks playout_time = GetPlayoutTime(now, rtp_timestamp);
263d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  cast_environment_->Logging()->InsertFrameEventWithDelay(kAudioPlayoutDelay,
265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      rtp_timestamp, kFrameIdUnknown, playout_time - now);
266f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
267a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Frame is ready - Send back to the caller.
2684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
269a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      base::Bind(callback, base::Passed(&audio_frame), playout_time));
270d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
271d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
2724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void AudioReceiver::PlayoutTimeout() {
273f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
2740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  DCHECK(audio_buffer_) << "Invalid function call in this configuration";
2754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (queued_encoded_callbacks_.empty()) {
2764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Already released by incoming packet.
2774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
2784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
279d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  uint32 rtp_timestamp = 0;
280d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  bool next_frame = false;
2814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_ptr<EncodedAudioFrame> encoded_frame(new EncodedAudioFrame());
2824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!audio_buffer_->GetEncodedAudioFrame(encoded_frame.get(),
284d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                           &rtp_timestamp, &next_frame)) {
2854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // We have no audio frames. Wait for new packet(s).
2861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Since the application can post multiple AudioFrameEncodedCallback and
2871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // we only check the next frame to play out we might have multiple timeout
2881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // events firing after each other; however this should be a rare event.
2891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    VLOG(1) << "Failed to retrieved a complete frame at this point in time";
2904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
291d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (decryptor_ && !DecryptAudioFrame(&encoded_frame)) {
294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Logging already done.
295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
296f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (PostEncodedAudioFrame(queued_encoded_callbacks_.front(), rtp_timestamp,
2991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                            next_frame, &encoded_frame)) {
3001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Call succeed remove callback from list.
3011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    queued_encoded_callbacks_.pop_front();
3021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
3034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
3044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void AudioReceiver::GetEncodedAudioFrame(
3064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const AudioFrameEncodedCallback& callback) {
307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
3084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(audio_buffer_) << "Invalid function call in this configuration";
3094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  uint32 rtp_timestamp = 0;
3114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  bool next_frame = false;
3124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_ptr<EncodedAudioFrame> encoded_frame(new EncodedAudioFrame());
3134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!audio_buffer_->GetEncodedAudioFrame(encoded_frame.get(),
3154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                           &rtp_timestamp, &next_frame)) {
3164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // We have no audio frames. Wait for new packet(s).
3174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    VLOG(1) << "Wait for more audio packets in frame";
3184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    queued_encoded_callbacks_.push_back(callback);
3194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
320d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
321f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (decryptor_ && !DecryptAudioFrame(&encoded_frame)) {
322f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Logging already done.
323f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    queued_encoded_callbacks_.push_back(callback);
324f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
3261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!PostEncodedAudioFrame(callback, rtp_timestamp, next_frame,
3271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                             &encoded_frame)) {
3281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // We have an audio frame; however we are missing packets and we have time
3291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // to wait for new packet(s).
3301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    queued_encoded_callbacks_.push_back(callback);
3311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
332d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
333d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
3341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool AudioReceiver::PostEncodedAudioFrame(
3354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const AudioFrameEncodedCallback& callback,
3364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    uint32 rtp_timestamp,
3374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    bool next_frame,
3384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    scoped_ptr<EncodedAudioFrame>* encoded_frame) {
339f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
3400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  DCHECK(audio_buffer_) << "Invalid function call in this configuration";
341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::TimeTicks now = cast_environment_->Clock()->NowTicks();
3434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::TimeTicks playout_time = GetPlayoutTime(now, rtp_timestamp);
3444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::TimeDelta time_until_playout = playout_time - now;
3454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::TimeDelta min_wait_delta =
3464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      base::TimeDelta::FromMilliseconds(kMaxAudioFrameWaitMs);
3474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!next_frame && (time_until_playout  > min_wait_delta)) {
3494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    base::TimeDelta time_until_release = time_until_playout - min_wait_delta;
3504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    cast_environment_->PostDelayedTask(CastEnvironment::MAIN, FROM_HERE,
3514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        base::Bind(&AudioReceiver::PlayoutTimeout, weak_factory_.GetWeakPtr()),
3524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        time_until_release);
3534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    VLOG(1) << "Wait until time to playout:"
3544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            << time_until_release.InMilliseconds();
3551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return false;
3564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
3574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  (*encoded_frame)->codec = codec_;
3584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  audio_buffer_->ReleaseFrame((*encoded_frame)->frame_id);
3594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
3614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      base::Bind(callback, base::Passed(encoded_frame), playout_time));
3621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return true;
363d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
364d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
3658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void AudioReceiver::IncomingPacket(const uint8* packet, size_t length,
3664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                   const base::Closure callback) {
367f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
368d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  bool rtcp_packet = Rtcp::IsRtcpPacket(packet, length);
369d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!rtcp_packet) {
370d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    rtp_receiver_->ReceivedPacket(packet, length);
371d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  } else {
372d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    rtcp_->IncomingRtcpPacket(packet, length);
373d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
3744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, callback);
375d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
376d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
377d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void AudioReceiver::CastFeedback(const RtcpCastMessage& cast_message) {
378f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // TODO(pwestin): add logging.
379f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  rtcp_->SendRtcpFromRtpReceiver(&cast_message, NULL);
380d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
381d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
382d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)base::TimeTicks AudioReceiver::GetPlayoutTime(base::TimeTicks now,
383d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                              uint32 rtp_timestamp) {
384f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
385d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Senders time in ms when this frame was recorded.
386d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Note: the senders clock and our local clock might not be synced.
387d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  base::TimeTicks rtp_timestamp_in_ticks;
3884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (time_offset_ == base::TimeDelta()) {
389d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (rtcp_->RtpTimestampInSenderTime(frequency_,
3901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                        first_incoming_rtp_timestamp_,
391d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                        &rtp_timestamp_in_ticks)) {
3921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      time_offset_ = time_first_incoming_packet_ - rtp_timestamp_in_ticks;
393d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    } else {
394d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      // We have not received any RTCP to sync the stream play it out as soon as
395d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      // possible.
3961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      uint32 rtp_timestamp_diff = rtp_timestamp - first_incoming_rtp_timestamp_;
397d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
398d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      int frequency_khz = frequency_ / 1000;
399d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      base::TimeDelta rtp_time_diff_delta =
400d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          base::TimeDelta::FromMilliseconds(rtp_timestamp_diff / frequency_khz);
4011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      base::TimeDelta time_diff_delta = now - time_first_incoming_packet_;
4024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
403d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)      return now + std::max(rtp_time_diff_delta - time_diff_delta,
404d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)                            base::TimeDelta());
405d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
406d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
407d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  // This can fail if we have not received any RTCP packets in a long time.
408d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  return rtcp_->RtpTimestampInSenderTime(frequency_, rtp_timestamp,
409d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)                                         &rtp_timestamp_in_ticks) ?
410d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    rtp_timestamp_in_ticks + time_offset_ + target_delay_delta_ :
411d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    now;
412d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
413d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
414f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool AudioReceiver::DecryptAudioFrame(
415f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<EncodedAudioFrame>* audio_frame) {
416f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(decryptor_) << "Invalid state";
417f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!decryptor_->SetCounter(GetAesNonce((*audio_frame)->frame_id,
419f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                          iv_mask_))) {
420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    NOTREACHED() << "Failed to set counter";
421f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return false;
422f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
423f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string decrypted_audio_data;
424f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!decryptor_->Decrypt((*audio_frame)->data, &decrypted_audio_data)) {
425f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    VLOG(0) << "Decryption error";
426f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Give up on this frame, release it from jitter buffer.
427f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    audio_buffer_->ReleaseFrame((*audio_frame)->frame_id);
428f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return false;
429f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
430f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  (*audio_frame)->data.swap(decrypted_audio_data);
431f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return true;
432f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
433f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
434d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void AudioReceiver::ScheduleNextRtcpReport() {
435f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
4364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::TimeDelta time_to_send = rtcp_->TimeToSendNextRtcpReport() -
4374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      cast_environment_->Clock()->NowTicks();
438d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
439d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  time_to_send = std::max(time_to_send,
440d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      base::TimeDelta::FromMilliseconds(kMinSchedulingDelayMs));
441d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
4424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  cast_environment_->PostDelayedTask(CastEnvironment::MAIN, FROM_HERE,
443d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      base::Bind(&AudioReceiver::SendNextRtcpReport,
444d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      weak_factory_.GetWeakPtr()), time_to_send);
445d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
446d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
447d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void AudioReceiver::SendNextRtcpReport() {
448f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
449f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // TODO(pwestin): add logging.
450f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  rtcp_->SendRtcpFromRtpReceiver(NULL, NULL);
451d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  ScheduleNextRtcpReport();
452d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
453d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
4540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Cast messages should be sent within a maximum interval. Schedule a call
4550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// if not triggered elsewhere, e.g. by the cast message_builder.
4560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void AudioReceiver::ScheduleNextCastMessage() {
457f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
458a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::TimeTicks send_time;
4590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (audio_buffer_) {
4600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    audio_buffer_->TimeToSendNextCastMessage(&send_time);
461a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  } else if (audio_decoder_) {
462a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    audio_decoder_->TimeToSendNextCastMessage(&send_time);
463a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  } else {
464a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    NOTREACHED();
4650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
466a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::TimeDelta time_to_send = send_time -
467a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      cast_environment_->Clock()->NowTicks();
468a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  time_to_send = std::max(time_to_send,
469a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(kMinSchedulingDelayMs));
470a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  cast_environment_->PostDelayedTask(CastEnvironment::MAIN, FROM_HERE,
471a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      base::Bind(&AudioReceiver::SendNextCastMessage,
472a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 weak_factory_.GetWeakPtr()), time_to_send);
4730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
4740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
4750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void AudioReceiver::SendNextCastMessage() {
476f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
477a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
478a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (audio_buffer_) {
479a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // Will only send a message if it is time.
480a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    audio_buffer_->SendCastMessage();
481a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
482a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (audio_decoder_) {
483a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // Will only send a message if it is time.
484a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    audio_decoder_->SendCastMessage();
485a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
4860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ScheduleNextCastMessage();
4870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
4880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
489d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}  // namespace cast
490d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}  // namespace media
491