Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / media / cast / cast_sender_impl.cc
blob9c6266c32b661c09368d22ee17c7af1b2beba526
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 "media/cast/cast_sender_impl.h"
7 #include "base/bind.h"
8 #include "base/callback.h"
9 #include "base/logging.h"
10 #include "base/message_loop/message_loop.h"
11 #include "media/base/video_frame.h"
12 #include "media/cast/sender/video_frame_factory.h"
14 namespace media {
15 namespace cast {
17 // The LocalVideoFrameInput class posts all incoming video frames to the main
18 // cast thread for processing.
19 class LocalVideoFrameInput : public VideoFrameInput {
20 public:
21 LocalVideoFrameInput(scoped_refptr<CastEnvironment> cast_environment,
22 base::WeakPtr<VideoSender> video_sender)
23 : cast_environment_(cast_environment),
24 video_sender_(video_sender),
25 video_frame_factory_(
26 video_sender.get() ?
27 video_sender->CreateVideoFrameFactory().release() : nullptr) {}
29 void InsertRawVideoFrame(const scoped_refptr<media::VideoFrame>& video_frame,
30 const base::TimeTicks& capture_time) final {
31 cast_environment_->PostTask(CastEnvironment::MAIN,
32 FROM_HERE,
33 base::Bind(&VideoSender::InsertRawVideoFrame,
34 video_sender_,
35 video_frame,
36 capture_time));
39 scoped_refptr<VideoFrame> MaybeCreateOptimizedFrame(
40 const gfx::Size& frame_size,
41 base::TimeDelta timestamp) final {
42 return video_frame_factory_ ?
43 video_frame_factory_->MaybeCreateFrame(frame_size, timestamp) : nullptr;
46 bool CanCreateOptimizedFrames() const final {
47 return video_frame_factory_.get() != nullptr;
50 protected:
51 ~LocalVideoFrameInput() final {}
53 private:
54 friend class base::RefCountedThreadSafe<LocalVideoFrameInput>;
56 const scoped_refptr<CastEnvironment> cast_environment_;
57 const base::WeakPtr<VideoSender> video_sender_;
58 const scoped_ptr<VideoFrameFactory> video_frame_factory_;
60 DISALLOW_COPY_AND_ASSIGN(LocalVideoFrameInput);
63 // The LocalAudioFrameInput class posts all incoming audio frames to the main
64 // cast thread for processing. Therefore frames can be inserted from any thread.
65 class LocalAudioFrameInput : public AudioFrameInput {
66 public:
67 LocalAudioFrameInput(scoped_refptr<CastEnvironment> cast_environment,
68 base::WeakPtr<AudioSender> audio_sender)
69 : cast_environment_(cast_environment), audio_sender_(audio_sender) {}
71 void InsertAudio(scoped_ptr<AudioBus> audio_bus,
72 const base::TimeTicks& recorded_time) final {
73 cast_environment_->PostTask(CastEnvironment::MAIN,
74 FROM_HERE,
75 base::Bind(&AudioSender::InsertAudio,
76 audio_sender_,
77 base::Passed(&audio_bus),
78 recorded_time));
81 protected:
82 ~LocalAudioFrameInput() final {}
84 private:
85 friend class base::RefCountedThreadSafe<LocalAudioFrameInput>;
87 scoped_refptr<CastEnvironment> cast_environment_;
88 base::WeakPtr<AudioSender> audio_sender_;
90 DISALLOW_COPY_AND_ASSIGN(LocalAudioFrameInput);
93 scoped_ptr<CastSender> CastSender::Create(
94 scoped_refptr<CastEnvironment> cast_environment,
95 CastTransportSender* const transport_sender) {
96 CHECK(cast_environment.get());
97 return scoped_ptr<CastSender>(
98 new CastSenderImpl(cast_environment, transport_sender));
101 CastSenderImpl::CastSenderImpl(
102 scoped_refptr<CastEnvironment> cast_environment,
103 CastTransportSender* const transport_sender)
104 : cast_environment_(cast_environment),
105 transport_sender_(transport_sender),
106 weak_factory_(this) {
107 CHECK(cast_environment.get());
110 void CastSenderImpl::InitializeAudio(
111 const AudioSenderConfig& audio_config,
112 const StatusChangeCallback& status_change_cb) {
113 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
114 CHECK(audio_config.use_external_encoder ||
115 cast_environment_->HasAudioThread());
117 VLOG(1) << "CastSenderImpl@" << this << "::InitializeAudio()";
119 audio_sender_.reset(
120 new AudioSender(cast_environment_,
121 audio_config,
122 base::Bind(&CastSenderImpl::OnAudioStatusChange,
123 weak_factory_.GetWeakPtr(),
124 status_change_cb),
125 transport_sender_));
126 if (video_sender_) {
127 DCHECK(audio_sender_->GetTargetPlayoutDelay() ==
128 video_sender_->GetTargetPlayoutDelay());
132 void CastSenderImpl::InitializeVideo(
133 const VideoSenderConfig& video_config,
134 const StatusChangeCallback& status_change_cb,
135 const CreateVideoEncodeAcceleratorCallback& create_vea_cb,
136 const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb) {
137 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
139 VLOG(1) << "CastSenderImpl@" << this << "::InitializeVideo()";
141 video_sender_.reset(new VideoSender(
142 cast_environment_,
143 video_config,
144 base::Bind(&CastSenderImpl::OnVideoStatusChange,
145 weak_factory_.GetWeakPtr(),
146 status_change_cb),
147 create_vea_cb,
148 create_video_encode_mem_cb,
149 transport_sender_,
150 base::Bind(&CastSenderImpl::SetTargetPlayoutDelay,
151 weak_factory_.GetWeakPtr())));
152 if (audio_sender_) {
153 DCHECK(audio_sender_->GetTargetPlayoutDelay() ==
154 video_sender_->GetTargetPlayoutDelay());
158 CastSenderImpl::~CastSenderImpl() {
159 VLOG(1) << "CastSenderImpl@" << this << "::~CastSenderImpl()";
162 scoped_refptr<AudioFrameInput> CastSenderImpl::audio_frame_input() {
163 return audio_frame_input_;
166 scoped_refptr<VideoFrameInput> CastSenderImpl::video_frame_input() {
167 return video_frame_input_;
170 void CastSenderImpl::SetTargetPlayoutDelay(
171 base::TimeDelta new_target_playout_delay) {
172 VLOG(1) << "CastSenderImpl@" << this << "::SetTargetPlayoutDelay("
173 << new_target_playout_delay.InMilliseconds() << " ms)";
174 if (audio_sender_) {
175 audio_sender_->SetTargetPlayoutDelay(new_target_playout_delay);
177 if (video_sender_) {
178 video_sender_->SetTargetPlayoutDelay(new_target_playout_delay);
182 void CastSenderImpl::OnAudioStatusChange(
183 const StatusChangeCallback& status_change_cb,
184 OperationalStatus status) {
185 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
186 if (status == STATUS_INITIALIZED && !audio_frame_input_) {
187 audio_frame_input_ =
188 new LocalAudioFrameInput(cast_environment_, audio_sender_->AsWeakPtr());
190 status_change_cb.Run(status);
193 void CastSenderImpl::OnVideoStatusChange(
194 const StatusChangeCallback& status_change_cb,
195 OperationalStatus status) {
196 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
197 if (status == STATUS_INITIALIZED && !video_frame_input_) {
198 video_frame_input_ =
199 new LocalVideoFrameInput(cast_environment_, video_sender_->AsWeakPtr());
201 status_change_cb.Run(status);
204 } // namespace cast
205 } // namespace media