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"
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"
16 // The LocalVideoFrameInput class posts all incoming video frames to the main
17 // cast thread for processing.
18 class LocalVideoFrameInput
: public VideoFrameInput
{
20 LocalVideoFrameInput(scoped_refptr
<CastEnvironment
> cast_environment
,
21 base::WeakPtr
<VideoSender
> video_sender
)
22 : cast_environment_(cast_environment
), video_sender_(video_sender
) {}
24 virtual void InsertRawVideoFrame(
25 const scoped_refptr
<media::VideoFrame
>& video_frame
,
26 const base::TimeTicks
& capture_time
) override
{
27 cast_environment_
->PostTask(CastEnvironment::MAIN
,
29 base::Bind(&VideoSender::InsertRawVideoFrame
,
36 virtual ~LocalVideoFrameInput() {}
39 friend class base::RefCountedThreadSafe
<LocalVideoFrameInput
>;
41 scoped_refptr
<CastEnvironment
> cast_environment_
;
42 base::WeakPtr
<VideoSender
> video_sender_
;
44 DISALLOW_COPY_AND_ASSIGN(LocalVideoFrameInput
);
47 // The LocalAudioFrameInput class posts all incoming audio frames to the main
48 // cast thread for processing. Therefore frames can be inserted from any thread.
49 class LocalAudioFrameInput
: public AudioFrameInput
{
51 LocalAudioFrameInput(scoped_refptr
<CastEnvironment
> cast_environment
,
52 base::WeakPtr
<AudioSender
> audio_sender
)
53 : cast_environment_(cast_environment
), audio_sender_(audio_sender
) {}
55 virtual void InsertAudio(scoped_ptr
<AudioBus
> audio_bus
,
56 const base::TimeTicks
& recorded_time
) override
{
57 cast_environment_
->PostTask(CastEnvironment::MAIN
,
59 base::Bind(&AudioSender::InsertAudio
,
61 base::Passed(&audio_bus
),
66 virtual ~LocalAudioFrameInput() {}
69 friend class base::RefCountedThreadSafe
<LocalAudioFrameInput
>;
71 scoped_refptr
<CastEnvironment
> cast_environment_
;
72 base::WeakPtr
<AudioSender
> audio_sender_
;
74 DISALLOW_COPY_AND_ASSIGN(LocalAudioFrameInput
);
77 scoped_ptr
<CastSender
> CastSender::Create(
78 scoped_refptr
<CastEnvironment
> cast_environment
,
79 CastTransportSender
* const transport_sender
) {
80 CHECK(cast_environment
.get());
81 return scoped_ptr
<CastSender
>(
82 new CastSenderImpl(cast_environment
, transport_sender
));
85 CastSenderImpl::CastSenderImpl(
86 scoped_refptr
<CastEnvironment
> cast_environment
,
87 CastTransportSender
* const transport_sender
)
88 : cast_environment_(cast_environment
),
89 transport_sender_(transport_sender
),
91 CHECK(cast_environment
.get());
94 void CastSenderImpl::InitializeAudio(
95 const AudioSenderConfig
& audio_config
,
96 const CastInitializationCallback
& cast_initialization_cb
) {
97 DCHECK(cast_environment_
->CurrentlyOn(CastEnvironment::MAIN
));
98 CHECK(audio_config
.use_external_encoder
||
99 cast_environment_
->HasAudioThread());
101 VLOG(1) << "CastSenderImpl@" << this << "::InitializeAudio()";
104 new AudioSender(cast_environment_
, audio_config
, transport_sender_
));
106 const CastInitializationStatus status
= audio_sender_
->InitializationResult();
107 if (status
== STATUS_AUDIO_INITIALIZED
) {
109 new LocalAudioFrameInput(cast_environment_
, audio_sender_
->AsWeakPtr());
111 cast_initialization_cb
.Run(status
);
113 DCHECK(audio_sender_
->GetTargetPlayoutDelay() ==
114 video_sender_
->GetTargetPlayoutDelay());
118 void CastSenderImpl::InitializeVideo(
119 const VideoSenderConfig
& video_config
,
120 const CastInitializationCallback
& cast_initialization_cb
,
121 const CreateVideoEncodeAcceleratorCallback
& create_vea_cb
,
122 const CreateVideoEncodeMemoryCallback
& create_video_encode_mem_cb
) {
123 DCHECK(cast_environment_
->CurrentlyOn(CastEnvironment::MAIN
));
124 CHECK(video_config
.use_external_encoder
||
125 cast_environment_
->HasVideoThread());
127 VLOG(1) << "CastSenderImpl@" << this << "::InitializeVideo()";
129 video_sender_
.reset(new VideoSender(
132 base::Bind(&CastSenderImpl::OnVideoInitialized
,
133 weak_factory_
.GetWeakPtr(), cast_initialization_cb
),
135 create_video_encode_mem_cb
,
137 base::Bind(&CastSenderImpl::SetTargetPlayoutDelay
,
138 weak_factory_
.GetWeakPtr())));
140 DCHECK(audio_sender_
->GetTargetPlayoutDelay() ==
141 video_sender_
->GetTargetPlayoutDelay());
145 CastSenderImpl::~CastSenderImpl() {
146 VLOG(1) << "CastSenderImpl@" << this << "::~CastSenderImpl()";
149 scoped_refptr
<AudioFrameInput
> CastSenderImpl::audio_frame_input() {
150 return audio_frame_input_
;
153 scoped_refptr
<VideoFrameInput
> CastSenderImpl::video_frame_input() {
154 return video_frame_input_
;
157 void CastSenderImpl::SetTargetPlayoutDelay(
158 base::TimeDelta new_target_playout_delay
) {
159 VLOG(1) << "CastSenderImpl@" << this << "::SetTargetPlayoutDelay("
160 << new_target_playout_delay
.InMilliseconds() << " ms)";
162 audio_sender_
->SetTargetPlayoutDelay(new_target_playout_delay
);
165 video_sender_
->SetTargetPlayoutDelay(new_target_playout_delay
);
169 void CastSenderImpl::OnVideoInitialized(
170 const CastInitializationCallback
& initialization_cb
,
171 media::cast::CastInitializationStatus result
) {
172 DCHECK(cast_environment_
->CurrentlyOn(CastEnvironment::MAIN
));
174 new LocalVideoFrameInput(cast_environment_
, video_sender_
->AsWeakPtr());
175 initialization_cb
.Run(result
);