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"
12 #include "media/cast/net/rtcp/rtcp_receiver.h"
17 // The LocalVideoFrameInput class posts all incoming video frames to the main
18 // cast thread for processing.
19 class LocalVideoFrameInput
: public VideoFrameInput
{
21 LocalVideoFrameInput(scoped_refptr
<CastEnvironment
> cast_environment
,
22 base::WeakPtr
<VideoSender
> video_sender
)
23 : cast_environment_(cast_environment
), video_sender_(video_sender
) {}
25 virtual void InsertRawVideoFrame(
26 const scoped_refptr
<media::VideoFrame
>& video_frame
,
27 const base::TimeTicks
& capture_time
) OVERRIDE
{
28 cast_environment_
->PostTask(CastEnvironment::MAIN
,
30 base::Bind(&VideoSender::InsertRawVideoFrame
,
37 virtual ~LocalVideoFrameInput() {}
40 friend class base::RefCountedThreadSafe
<LocalVideoFrameInput
>;
42 scoped_refptr
<CastEnvironment
> cast_environment_
;
43 base::WeakPtr
<VideoSender
> video_sender_
;
45 DISALLOW_COPY_AND_ASSIGN(LocalVideoFrameInput
);
48 // The LocalAudioFrameInput class posts all incoming audio frames to the main
49 // cast thread for processing. Therefore frames can be inserted from any thread.
50 class LocalAudioFrameInput
: public AudioFrameInput
{
52 LocalAudioFrameInput(scoped_refptr
<CastEnvironment
> cast_environment
,
53 base::WeakPtr
<AudioSender
> audio_sender
)
54 : cast_environment_(cast_environment
), audio_sender_(audio_sender
) {}
56 virtual void InsertAudio(scoped_ptr
<AudioBus
> audio_bus
,
57 const base::TimeTicks
& recorded_time
) OVERRIDE
{
58 cast_environment_
->PostTask(CastEnvironment::MAIN
,
60 base::Bind(&AudioSender::InsertAudio
,
62 base::Passed(&audio_bus
),
67 virtual ~LocalAudioFrameInput() {}
70 friend class base::RefCountedThreadSafe
<LocalAudioFrameInput
>;
72 scoped_refptr
<CastEnvironment
> cast_environment_
;
73 base::WeakPtr
<AudioSender
> audio_sender_
;
75 DISALLOW_COPY_AND_ASSIGN(LocalAudioFrameInput
);
78 scoped_ptr
<CastSender
> CastSender::Create(
79 scoped_refptr
<CastEnvironment
> cast_environment
,
80 CastTransportSender
* const transport_sender
) {
81 CHECK(cast_environment
);
82 return scoped_ptr
<CastSender
>(
83 new CastSenderImpl(cast_environment
, transport_sender
));
86 CastSenderImpl::CastSenderImpl(
87 scoped_refptr
<CastEnvironment
> cast_environment
,
88 CastTransportSender
* const transport_sender
)
89 : cast_environment_(cast_environment
),
90 transport_sender_(transport_sender
),
92 CHECK(cast_environment
);
95 void CastSenderImpl::InitializeAudio(
96 const AudioSenderConfig
& audio_config
,
97 const CastInitializationCallback
& cast_initialization_cb
) {
98 DCHECK(cast_environment_
->CurrentlyOn(CastEnvironment::MAIN
));
99 CHECK(audio_config
.use_external_encoder
||
100 cast_environment_
->HasAudioThread());
102 VLOG(1) << "CastSenderImpl@" << this << "::InitializeAudio()";
105 new AudioSender(cast_environment_
, audio_config
, transport_sender_
));
107 const CastInitializationStatus status
= audio_sender_
->InitializationResult();
108 if (status
== STATUS_AUDIO_INITIALIZED
) {
109 ssrc_of_audio_sender_
= audio_config
.incoming_feedback_ssrc
;
111 new LocalAudioFrameInput(cast_environment_
, audio_sender_
->AsWeakPtr());
113 cast_initialization_cb
.Run(status
);
116 void CastSenderImpl::InitializeVideo(
117 const VideoSenderConfig
& video_config
,
118 const CastInitializationCallback
& cast_initialization_cb
,
119 const CreateVideoEncodeAcceleratorCallback
& create_vea_cb
,
120 const CreateVideoEncodeMemoryCallback
& create_video_encode_mem_cb
) {
121 DCHECK(cast_environment_
->CurrentlyOn(CastEnvironment::MAIN
));
122 CHECK(video_config
.use_external_encoder
||
123 cast_environment_
->HasVideoThread());
125 VLOG(1) << "CastSenderImpl@" << this << "::InitializeVideo()";
127 video_sender_
.reset(new VideoSender(cast_environment_
,
130 create_video_encode_mem_cb
,
133 const CastInitializationStatus status
= video_sender_
->InitializationResult();
134 if (status
== STATUS_VIDEO_INITIALIZED
) {
135 ssrc_of_video_sender_
= video_config
.incoming_feedback_ssrc
;
137 new LocalVideoFrameInput(cast_environment_
, video_sender_
->AsWeakPtr());
139 cast_initialization_cb
.Run(status
);
142 CastSenderImpl::~CastSenderImpl() {
143 VLOG(1) << "CastSenderImpl@" << this << "::~CastSenderImpl()";
146 scoped_refptr
<AudioFrameInput
> CastSenderImpl::audio_frame_input() {
147 return audio_frame_input_
;
150 scoped_refptr
<VideoFrameInput
> CastSenderImpl::video_frame_input() {
151 return video_frame_input_
;