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 "chrome/renderer/media/cast_session_delegate.h"
7 #include "base/logging.h"
8 #include "base/message_loop/message_loop_proxy.h"
9 #include "content/public/renderer/p2p_socket_client.h"
10 #include "content/public/renderer/render_thread.h"
11 #include "media/cast/cast_config.h"
12 #include "media/cast/cast_environment.h"
13 #include "media/cast/cast_sender.h"
14 #include "media/cast/logging/logging_defines.h"
16 using media::cast::AudioSenderConfig
;
17 using media::cast::CastEnvironment
;
18 using media::cast::CastSender
;
19 using media::cast::VideoSenderConfig
;
21 CastSessionDelegate::CastSessionDelegate()
22 : audio_encode_thread_("CastAudioEncodeThread"),
23 video_encode_thread_("CastVideoEncodeThread"),
24 audio_configured_(false),
25 video_configured_(false),
26 io_message_loop_proxy_(
27 content::RenderThread::Get()->GetIOMessageLoopProxy()) {
30 CastSessionDelegate::~CastSessionDelegate() {
31 DCHECK(io_message_loop_proxy_
->BelongsToCurrentThread());
34 void CastSessionDelegate::StartAudio(
35 const AudioSenderConfig
& config
,
36 const FrameInputAvailableCallback
& callback
) {
37 DCHECK(io_message_loop_proxy_
->BelongsToCurrentThread());
39 audio_configured_
= true;
40 audio_config_
= config
;
41 frame_input_available_callbacks_
.push_back(callback
);
42 StartSendingInternal();
45 void CastSessionDelegate::StartSending(const SendPacketCallback
& callback
) {
46 DCHECK(io_message_loop_proxy_
->BelongsToCurrentThread());
48 send_packet_callback_
= callback
;
49 StartSendingInternal();
52 void CastSessionDelegate::StartVideo(
53 const VideoSenderConfig
& config
,
54 const FrameInputAvailableCallback
& callback
) {
55 DCHECK(io_message_loop_proxy_
->BelongsToCurrentThread());
57 video_configured_
= true;
58 video_config_
= config
;
59 frame_input_available_callbacks_
.push_back(callback
);
60 StartSendingInternal();
63 void CastSessionDelegate::StartSendingInternal() {
64 DCHECK(io_message_loop_proxy_
->BelongsToCurrentThread());
66 if (cast_environment_
)
68 if (!audio_configured_
|| !video_configured_
)
71 audio_encode_thread_
.Start();
72 video_encode_thread_
.Start();
74 // CastSender uses the renderer's IO thread as the main thread. This reduces
75 // thread hopping for incoming video frames and outgoing network packets.
76 // There's no need to decode so no thread assigned for decoding.
77 // Get default logging: All disabled.
78 cast_environment_
= new CastEnvironment(
80 base::MessageLoopProxy::current(),
81 audio_encode_thread_
.message_loop_proxy(),
83 video_encode_thread_
.message_loop_proxy(),
85 base::MessageLoopProxy::current(),
86 media::cast::GetDefaultCastLoggingConfig());
88 // TODO(hclam): Implement VideoEncoderController to configure hardware
90 cast_sender_
.reset(CastSender::CreateCastSender(
97 for (size_t i
= 0; i
< frame_input_available_callbacks_
.size(); ++i
) {
98 frame_input_available_callbacks_
[i
].Run(
99 cast_sender_
->frame_input());
101 frame_input_available_callbacks_
.clear();
104 // media::cast::PacketSender Implementation
105 bool CastSessionDelegate::SendPacket(
106 const media::cast::Packet
& packet
) {
107 if (send_packet_callback_
.is_null())
109 send_packet_callback_
.Run(
110 *reinterpret_cast<const std::vector
<char> *>(&packet
));
114 bool CastSessionDelegate::SendPackets(
115 const media::cast::PacketList
& packets
) {
116 // TODO(hubbe): Add ability to send multiple packets in one IPC message.
117 for (size_t i
= 0; i
< packets
.size(); i
++) {
118 SendPacket(packets
[i
]);
123 void CastSessionDelegate::ReceivePacket(const std::vector
<char>& packet
) {
124 uint8
*packet_copy
= new uint8
[packet
.size()];
125 memcpy(packet_copy
, &packet
[0], packet
.size());
126 cast_sender_
->packet_receiver()->ReceivedPacket(
129 base::Bind(&media::cast::transport::PacketReceiver::DeletePacket
,