Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / media / cast / test / utility / in_process_receiver.cc
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.
4
5 #include "media/cast/test/utility/in_process_receiver.h"
6
7 #include "base/bind_helpers.h"
8 #include "base/synchronization/waitable_event.h"
9 #include "base/time/time.h"
10 #include "media/base/video_frame.h"
11 #include "media/cast/cast_config.h"
12 #include "media/cast/cast_environment.h"
13 #include "media/cast/cast_receiver.h"
14 #include "media/cast/transport/cast_transport_config.h"
15 #include "media/cast/transport/transport/udp_transport.h"
16
17 using media::cast::transport::CastTransportStatus;
18 using media::cast::transport::UdpTransport;
19
20 namespace media {
21 namespace cast {
22
23 InProcessReceiver::InProcessReceiver(
24     const scoped_refptr<CastEnvironment>& cast_environment,
25     const net::IPEndPoint& local_end_point,
26     const net::IPEndPoint& remote_end_point,
27     const AudioReceiverConfig& audio_config,
28     const VideoReceiverConfig& video_config)
29     : cast_environment_(cast_environment),
30       local_end_point_(local_end_point),
31       remote_end_point_(remote_end_point),
32       audio_config_(audio_config),
33       video_config_(video_config),
34       weak_factory_(this) {}
35
36 InProcessReceiver::~InProcessReceiver() {
37   Stop();
38 }
39
40 void InProcessReceiver::Start() {
41   cast_environment_->PostTask(CastEnvironment::MAIN,
42                               FROM_HERE,
43                               base::Bind(&InProcessReceiver::StartOnMainThread,
44                                          base::Unretained(this)));
45 }
46
47 void InProcessReceiver::Stop() {
48   base::WaitableEvent event(false, false);
49   if (cast_environment_->CurrentlyOn(CastEnvironment::MAIN)) {
50     StopOnMainThread(&event);
51   } else {
52     cast_environment_->PostTask(CastEnvironment::MAIN,
53                                 FROM_HERE,
54                                 base::Bind(&InProcessReceiver::StopOnMainThread,
55                                            base::Unretained(this),
56                                            &event));
57     event.Wait();
58   }
59 }
60
61 void InProcessReceiver::StopOnMainThread(base::WaitableEvent* event) {
62   DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
63   cast_receiver_.reset(NULL);
64   transport_.reset(NULL);
65   weak_factory_.InvalidateWeakPtrs();
66   event->Signal();
67 }
68
69 void InProcessReceiver::UpdateCastTransportStatus(CastTransportStatus status) {
70   LOG_IF(ERROR, status == media::cast::transport::TRANSPORT_SOCKET_ERROR)
71       << "Transport socket error occurred.  InProcessReceiver is likely dead.";
72   VLOG(1) << "CastTransportStatus is now " << status;
73 }
74
75 void InProcessReceiver::StartOnMainThread() {
76   DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
77
78   DCHECK(!transport_ && !cast_receiver_);
79   transport_.reset(
80       new UdpTransport(NULL,
81                        cast_environment_->GetTaskRunner(CastEnvironment::MAIN),
82                        local_end_point_,
83                        remote_end_point_,
84                        base::Bind(&InProcessReceiver::UpdateCastTransportStatus,
85                                   base::Unretained(this))));
86   cast_receiver_ = CastReceiver::Create(
87       cast_environment_, audio_config_, video_config_, transport_.get());
88
89   // TODO(hubbe): Make the cast receiver do this automatically.
90   transport_->StartReceiving(cast_receiver_->packet_receiver());
91
92   PullNextAudioFrame();
93   PullNextVideoFrame();
94 }
95
96 void InProcessReceiver::GotAudioFrame(scoped_ptr<AudioBus> audio_frame,
97                                       const base::TimeTicks& playout_time,
98                                       bool is_continuous) {
99   DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
100   if (audio_frame.get())
101     OnAudioFrame(audio_frame.Pass(), playout_time, is_continuous);
102   PullNextAudioFrame();
103 }
104
105 void InProcessReceiver::GotVideoFrame(
106     const scoped_refptr<VideoFrame>& video_frame,
107     const base::TimeTicks& playout_time,
108     bool is_continuous) {
109   DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
110   if (video_frame)
111     OnVideoFrame(video_frame, playout_time, is_continuous);
112   PullNextVideoFrame();
113 }
114
115 void InProcessReceiver::PullNextAudioFrame() {
116   DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
117   cast_receiver_->frame_receiver()->GetRawAudioFrame(
118       base::Bind(&InProcessReceiver::GotAudioFrame,
119                  weak_factory_.GetWeakPtr()));
120 }
121
122 void InProcessReceiver::PullNextVideoFrame() {
123   DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
124   cast_receiver_->frame_receiver()->GetRawVideoFrame(base::Bind(
125       &InProcessReceiver::GotVideoFrame, weak_factory_.GetWeakPtr()));
126 }
127
128 }  // namespace cast
129 }  // namespace media