ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / chromecast / media / cma / ipc_streamer / av_streamer_proxy.cc
blob6bc25edc3865f4baacadf15271c67318afc84a9b
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 "chromecast/media/cma/ipc_streamer/av_streamer_proxy.h"
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/message_loop/message_loop_proxy.h"
10 #include "chromecast/media/cma/base/coded_frame_provider.h"
11 #include "chromecast/media/cma/base/decoder_buffer_base.h"
12 #include "chromecast/media/cma/ipc/media_memory_chunk.h"
13 #include "chromecast/media/cma/ipc/media_message.h"
14 #include "chromecast/media/cma/ipc/media_message_fifo.h"
15 #include "chromecast/media/cma/ipc/media_message_type.h"
16 #include "chromecast/media/cma/ipc_streamer/audio_decoder_config_marshaller.h"
17 #include "chromecast/media/cma/ipc_streamer/decoder_buffer_base_marshaller.h"
18 #include "chromecast/media/cma/ipc_streamer/video_decoder_config_marshaller.h"
20 namespace chromecast {
21 namespace media {
23 AvStreamerProxy::AvStreamerProxy()
24 : is_running_(false),
25 pending_read_(false),
26 pending_av_data_(false),
27 weak_factory_(this) {
28 weak_this_ = weak_factory_.GetWeakPtr();
29 thread_checker_.DetachFromThread();
32 AvStreamerProxy::~AvStreamerProxy() {
33 DCHECK(thread_checker_.CalledOnValidThread());
36 void AvStreamerProxy::SetCodedFrameProvider(
37 scoped_ptr<CodedFrameProvider> frame_provider) {
38 DCHECK(thread_checker_.CalledOnValidThread());
39 DCHECK(!frame_provider_);
40 frame_provider_.reset(frame_provider.release());
43 void AvStreamerProxy::SetMediaMessageFifo(
44 scoped_ptr<MediaMessageFifo> fifo) {
45 DCHECK(thread_checker_.CalledOnValidThread());
46 DCHECK(!fifo_);
47 fifo_.reset(fifo.release());
50 void AvStreamerProxy::Start() {
51 DCHECK(!is_running_);
53 is_running_ = true;
54 RequestBufferIfNeeded();
57 void AvStreamerProxy::StopAndFlush(const base::Closure& done_cb) {
58 is_running_ = false;
60 pending_av_data_ = false;
61 pending_audio_config_ = ::media::AudioDecoderConfig();
62 pending_video_config_ = ::media::VideoDecoderConfig();
63 pending_buffer_ = scoped_refptr<DecoderBufferBase>();
65 pending_read_ = false;
66 frame_provider_->Flush(done_cb);
69 void AvStreamerProxy::OnFifoReadEvent() {
70 DCHECK(thread_checker_.CalledOnValidThread());
72 // Some enough space might have been released
73 // to accommodate the pending data.
74 if (pending_av_data_)
75 ProcessPendingData();
78 void AvStreamerProxy::RequestBufferIfNeeded() {
79 DCHECK(thread_checker_.CalledOnValidThread());
81 if (!is_running_ || pending_read_ || pending_av_data_)
82 return;
84 // |frame_provider_| is assumed to run on the same message loop.
85 // Add a BindToCurrentLoop if that's not the case in the future.
86 pending_read_ = true;
87 frame_provider_->Read(base::Bind(&AvStreamerProxy::OnNewBuffer, weak_this_));
90 void AvStreamerProxy::OnNewBuffer(
91 const scoped_refptr<DecoderBufferBase>& buffer,
92 const ::media::AudioDecoderConfig& audio_config,
93 const ::media::VideoDecoderConfig& video_config) {
94 DCHECK(thread_checker_.CalledOnValidThread());
96 pending_read_ = false;
98 if (buffer->end_of_stream())
99 is_running_ = false;
101 DCHECK(!pending_av_data_);
102 pending_av_data_ = true;
104 pending_buffer_ = buffer;
105 pending_audio_config_ = audio_config;
106 pending_video_config_ = video_config;
108 ProcessPendingData();
111 void AvStreamerProxy::ProcessPendingData() {
112 if (pending_audio_config_.IsValidConfig()) {
113 if (!SendAudioDecoderConfig(pending_audio_config_))
114 return;
115 pending_audio_config_ = ::media::AudioDecoderConfig();
118 if (pending_video_config_.IsValidConfig()) {
119 if (!SendVideoDecoderConfig(pending_video_config_))
120 return;
121 pending_video_config_ = ::media::VideoDecoderConfig();
124 if (pending_buffer_.get()) {
125 if (!SendBuffer(pending_buffer_))
126 return;
127 pending_buffer_ = scoped_refptr<DecoderBufferBase>();
130 pending_av_data_ = false;
131 base::MessageLoopProxy::current()->PostTask(
132 FROM_HERE,
133 base::Bind(&AvStreamerProxy::RequestBufferIfNeeded, weak_this_));
136 bool AvStreamerProxy::SendAudioDecoderConfig(
137 const ::media::AudioDecoderConfig& config) {
138 // Create a dummy message to calculate first the message size.
139 scoped_ptr<MediaMessage> dummy_msg(
140 MediaMessage::CreateDummyMessage(AudioConfigMediaMsg));
141 AudioDecoderConfigMarshaller::Write(config, dummy_msg.get());
143 // Create the real message and write the actual content.
144 scoped_ptr<MediaMessage> msg(
145 MediaMessage::CreateMessage(
146 AudioConfigMediaMsg,
147 base::Bind(&MediaMessageFifo::ReserveMemory,
148 base::Unretained(fifo_.get())),
149 dummy_msg->content_size()));
150 if (!msg)
151 return false;
153 AudioDecoderConfigMarshaller::Write(config, msg.get());
154 return true;
157 bool AvStreamerProxy::SendVideoDecoderConfig(
158 const ::media::VideoDecoderConfig& config) {
159 // Create a dummy message to calculate first the message size.
160 scoped_ptr<MediaMessage> dummy_msg(
161 MediaMessage::CreateDummyMessage(VideoConfigMediaMsg));
162 VideoDecoderConfigMarshaller::Write(config, dummy_msg.get());
164 // Create the real message and write the actual content.
165 scoped_ptr<MediaMessage> msg(
166 MediaMessage::CreateMessage(
167 VideoConfigMediaMsg,
168 base::Bind(&MediaMessageFifo::ReserveMemory,
169 base::Unretained(fifo_.get())),
170 dummy_msg->content_size()));
171 if (!msg)
172 return false;
174 VideoDecoderConfigMarshaller::Write(config, msg.get());
175 return true;
178 bool AvStreamerProxy::SendBuffer(
179 const scoped_refptr<DecoderBufferBase>& buffer) {
180 // Create a dummy message to calculate first the message size.
181 scoped_ptr<MediaMessage> dummy_msg(
182 MediaMessage::CreateDummyMessage(FrameMediaMsg));
183 DecoderBufferBaseMarshaller::Write(buffer, dummy_msg.get());
185 // Create the real message and write the actual content.
186 scoped_ptr<MediaMessage> msg(
187 MediaMessage::CreateMessage(
188 FrameMediaMsg,
189 base::Bind(&MediaMessageFifo::ReserveMemory,
190 base::Unretained(fifo_.get())),
191 dummy_msg->content_size()));
192 if (!msg)
193 return false;
195 DecoderBufferBaseMarshaller::Write(buffer, msg.get());
196 return true;
199 } // namespace media
200 } // namespace chromecast