1 // Copyright 2014 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/test/utility/in_process_receiver.h"
7 #include "base/bind_helpers.h"
8 #include "base/synchronization/waitable_event.h"
9 #include "base/time/time.h"
10 #include "base/values.h"
11 #include "media/base/video_frame.h"
12 #include "media/cast/cast_config.h"
13 #include "media/cast/cast_environment.h"
14 #include "media/cast/cast_receiver.h"
15 #include "media/cast/net/cast_transport_config.h"
16 #include "media/cast/net/udp_transport.h"
18 using media::cast::CastTransportStatus
;
19 using media::cast::UdpTransport
;
24 InProcessReceiver::InProcessReceiver(
25 const scoped_refptr
<CastEnvironment
>& cast_environment
,
26 const net::IPEndPoint
& local_end_point
,
27 const net::IPEndPoint
& remote_end_point
,
28 const FrameReceiverConfig
& audio_config
,
29 const FrameReceiverConfig
& video_config
)
30 : cast_environment_(cast_environment
),
31 local_end_point_(local_end_point
),
32 remote_end_point_(remote_end_point
),
33 audio_config_(audio_config
),
34 video_config_(video_config
),
35 weak_factory_(this) {}
37 InProcessReceiver::~InProcessReceiver() {
41 void InProcessReceiver::Start() {
42 cast_environment_
->PostTask(CastEnvironment::MAIN
,
44 base::Bind(&InProcessReceiver::StartOnMainThread
,
45 base::Unretained(this)));
48 void InProcessReceiver::Stop() {
49 base::WaitableEvent
event(false, false);
50 if (cast_environment_
->CurrentlyOn(CastEnvironment::MAIN
)) {
51 StopOnMainThread(&event
);
53 cast_environment_
->PostTask(CastEnvironment::MAIN
,
55 base::Bind(&InProcessReceiver::StopOnMainThread
,
56 base::Unretained(this),
62 void InProcessReceiver::StopOnMainThread(base::WaitableEvent
* event
) {
63 DCHECK(cast_environment_
->CurrentlyOn(CastEnvironment::MAIN
));
64 cast_receiver_
.reset(NULL
);
65 transport_
.reset(NULL
);
66 weak_factory_
.InvalidateWeakPtrs();
70 void InProcessReceiver::UpdateCastTransportStatus(CastTransportStatus status
) {
71 LOG_IF(ERROR
, status
== media::cast::TRANSPORT_SOCKET_ERROR
)
72 << "Transport socket error occurred. InProcessReceiver is likely dead.";
73 VLOG(1) << "CastTransportStatus is now " << status
;
76 void InProcessReceiver::StartOnMainThread() {
77 DCHECK(cast_environment_
->CurrentlyOn(CastEnvironment::MAIN
));
79 DCHECK(!transport_
&& !cast_receiver_
);
81 transport_
= CastTransportSender::Create(
83 cast_environment_
->Clock(),
86 scoped_ptr
<base::DictionaryValue
>(new base::DictionaryValue
),
87 base::Bind(&InProcessReceiver::UpdateCastTransportStatus
,
88 base::Unretained(this)),
89 BulkRawEventsCallback(),
91 base::Bind(&InProcessReceiver::ReceivePacket
,
92 base::Unretained(this)),
93 cast_environment_
->GetTaskRunner(CastEnvironment::MAIN
));
95 cast_receiver_
= CastReceiver::Create(
96 cast_environment_
, audio_config_
, video_config_
, transport_
.get());
102 void InProcessReceiver::GotAudioFrame(scoped_ptr
<AudioBus
> audio_frame
,
103 const base::TimeTicks
& playout_time
,
104 bool is_continuous
) {
105 DCHECK(cast_environment_
->CurrentlyOn(CastEnvironment::MAIN
));
106 if (audio_frame
.get())
107 OnAudioFrame(audio_frame
.Pass(), playout_time
, is_continuous
);
108 PullNextAudioFrame();
111 void InProcessReceiver::GotVideoFrame(
112 const scoped_refptr
<VideoFrame
>& video_frame
,
113 const base::TimeTicks
& playout_time
,
114 bool is_continuous
) {
115 DCHECK(cast_environment_
->CurrentlyOn(CastEnvironment::MAIN
));
116 if (video_frame
.get())
117 OnVideoFrame(video_frame
, playout_time
, is_continuous
);
118 PullNextVideoFrame();
121 void InProcessReceiver::PullNextAudioFrame() {
122 DCHECK(cast_environment_
->CurrentlyOn(CastEnvironment::MAIN
));
123 cast_receiver_
->RequestDecodedAudioFrame(
124 base::Bind(&InProcessReceiver::GotAudioFrame
,
125 weak_factory_
.GetWeakPtr()));
128 void InProcessReceiver::PullNextVideoFrame() {
129 DCHECK(cast_environment_
->CurrentlyOn(CastEnvironment::MAIN
));
130 cast_receiver_
->RequestDecodedVideoFrame(base::Bind(
131 &InProcessReceiver::GotVideoFrame
, weak_factory_
.GetWeakPtr()));
134 void InProcessReceiver::ReceivePacket(scoped_ptr
<Packet
> packet
) {
135 // TODO(Hubbe): Make an InsertPacket method instead.
136 cast_receiver_
->ReceivePacket(packet
.Pass());