Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(117)

Side by Side Diff: chromecast/media/cma/ipc_streamer/av_streamer_proxy.cc

Issue 2300993003: CmaRenderer is dead. Long live MojoRenderer. (Closed)
Patch Set: update OWNERS file Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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 "chromecast/media/cma/ipc_streamer/av_streamer_proxy.h"
6
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/single_thread_task_runner.h"
10 #include "base/threading/thread_task_runner_handle.h"
11 #include "chromecast/media/cma/base/coded_frame_provider.h"
12 #include "chromecast/media/cma/base/decoder_buffer_base.h"
13 #include "chromecast/media/cma/ipc/media_memory_chunk.h"
14 #include "chromecast/media/cma/ipc/media_message.h"
15 #include "chromecast/media/cma/ipc/media_message_fifo.h"
16 #include "chromecast/media/cma/ipc/media_message_type.h"
17 #include "chromecast/media/cma/ipc_streamer/audio_decoder_config_marshaller.h"
18 #include "chromecast/media/cma/ipc_streamer/decoder_buffer_base_marshaller.h"
19 #include "chromecast/media/cma/ipc_streamer/video_decoder_config_marshaller.h"
20
21 namespace chromecast {
22 namespace media {
23
24 AvStreamerProxy::AvStreamerProxy()
25 : is_running_(false),
26 pending_read_(false),
27 pending_av_data_(false),
28 weak_factory_(this) {
29 weak_this_ = weak_factory_.GetWeakPtr();
30 thread_checker_.DetachFromThread();
31 }
32
33 AvStreamerProxy::~AvStreamerProxy() {
34 DCHECK(thread_checker_.CalledOnValidThread());
35 }
36
37 void AvStreamerProxy::SetCodedFrameProvider(
38 std::unique_ptr<CodedFrameProvider> frame_provider) {
39 DCHECK(thread_checker_.CalledOnValidThread());
40 DCHECK(!frame_provider_);
41 frame_provider_.reset(frame_provider.release());
42 }
43
44 void AvStreamerProxy::SetMediaMessageFifo(
45 std::unique_ptr<MediaMessageFifo> fifo) {
46 DCHECK(thread_checker_.CalledOnValidThread());
47 DCHECK(!fifo_);
48 fifo_.reset(fifo.release());
49 }
50
51 void AvStreamerProxy::Start() {
52 DCHECK(!is_running_);
53
54 is_running_ = true;
55 RequestBufferIfNeeded();
56 }
57
58 void AvStreamerProxy::StopAndFlush(const base::Closure& done_cb) {
59 DCHECK(thread_checker_.CalledOnValidThread());
60 DCHECK(!done_cb.is_null());
61
62 pending_av_data_ = false;
63 pending_audio_config_ = ::media::AudioDecoderConfig();
64 pending_video_config_ = ::media::VideoDecoderConfig();
65 pending_buffer_ = scoped_refptr<DecoderBufferBase>();
66
67 pending_read_ = false;
68 is_running_ = false;
69
70 // If there's another pending Flush, for example, the pipeline is stopped
71 // while another seek is pending, then we don't need to call Flush again. Save
72 // the callback and fire it later when Flush is done.
73 pending_stop_flush_cb_list_.push_back(done_cb);
74 if (pending_stop_flush_cb_list_.size() == 1) {
75 frame_provider_->Flush(
76 base::Bind(&AvStreamerProxy::OnStopAndFlushDone, weak_this_));
77 }
78 }
79
80 void AvStreamerProxy::OnStopAndFlushDone() {
81 DCHECK(thread_checker_.CalledOnValidThread());
82
83 // Flush is done. Fire all the "flush done" callbacks in order. This is
84 // necessary to guarantee proper state transition in pipeline.
85 for (const auto& cb : pending_stop_flush_cb_list_) {
86 cb.Run();
87 }
88 pending_stop_flush_cb_list_.clear();
89 }
90
91 void AvStreamerProxy::OnFifoReadEvent() {
92 DCHECK(thread_checker_.CalledOnValidThread());
93
94 // Some enough space might have been released
95 // to accommodate the pending data.
96 if (pending_av_data_)
97 ProcessPendingData();
98 }
99
100 void AvStreamerProxy::RequestBufferIfNeeded() {
101 DCHECK(thread_checker_.CalledOnValidThread());
102
103 if (!is_running_ || pending_read_ || pending_av_data_)
104 return;
105
106 // |frame_provider_| is assumed to run on the same message loop.
107 // Add a BindToCurrentLoop if that's not the case in the future.
108 pending_read_ = true;
109 frame_provider_->Read(base::Bind(&AvStreamerProxy::OnNewBuffer, weak_this_));
110 }
111
112 void AvStreamerProxy::OnNewBuffer(
113 const scoped_refptr<DecoderBufferBase>& buffer,
114 const ::media::AudioDecoderConfig& audio_config,
115 const ::media::VideoDecoderConfig& video_config) {
116 DCHECK(thread_checker_.CalledOnValidThread());
117
118 pending_read_ = false;
119
120 if (buffer->end_of_stream())
121 is_running_ = false;
122
123 DCHECK(!pending_av_data_);
124 pending_av_data_ = true;
125
126 pending_buffer_ = buffer;
127 pending_audio_config_ = audio_config;
128 pending_video_config_ = video_config;
129
130 ProcessPendingData();
131 }
132
133 void AvStreamerProxy::ProcessPendingData() {
134 if (pending_audio_config_.IsValidConfig()) {
135 if (!SendAudioDecoderConfig(pending_audio_config_))
136 return;
137 pending_audio_config_ = ::media::AudioDecoderConfig();
138 }
139
140 if (pending_video_config_.IsValidConfig()) {
141 if (!SendVideoDecoderConfig(pending_video_config_))
142 return;
143 pending_video_config_ = ::media::VideoDecoderConfig();
144 }
145
146 if (pending_buffer_.get()) {
147 if (!SendBuffer(pending_buffer_))
148 return;
149 pending_buffer_ = scoped_refptr<DecoderBufferBase>();
150 }
151
152 pending_av_data_ = false;
153 base::ThreadTaskRunnerHandle::Get()->PostTask(
154 FROM_HERE,
155 base::Bind(&AvStreamerProxy::RequestBufferIfNeeded, weak_this_));
156 }
157
158 bool AvStreamerProxy::SendAudioDecoderConfig(
159 const ::media::AudioDecoderConfig& config) {
160 // Create a dummy message to calculate first the message size.
161 std::unique_ptr<MediaMessage> dummy_msg(
162 MediaMessage::CreateDummyMessage(AudioConfigMediaMsg));
163 AudioDecoderConfigMarshaller::Write(config, dummy_msg.get());
164
165 // Create the real message and write the actual content.
166 std::unique_ptr<MediaMessage> msg(MediaMessage::CreateMessage(
167 AudioConfigMediaMsg, base::Bind(&MediaMessageFifo::ReserveMemory,
168 base::Unretained(fifo_.get())),
169 dummy_msg->content_size()));
170 if (!msg)
171 return false;
172
173 AudioDecoderConfigMarshaller::Write(config, msg.get());
174 return true;
175 }
176
177 bool AvStreamerProxy::SendVideoDecoderConfig(
178 const ::media::VideoDecoderConfig& config) {
179 // Create a dummy message to calculate first the message size.
180 std::unique_ptr<MediaMessage> dummy_msg(
181 MediaMessage::CreateDummyMessage(VideoConfigMediaMsg));
182 VideoDecoderConfigMarshaller::Write(config, dummy_msg.get());
183
184 // Create the real message and write the actual content.
185 std::unique_ptr<MediaMessage> msg(MediaMessage::CreateMessage(
186 VideoConfigMediaMsg, base::Bind(&MediaMessageFifo::ReserveMemory,
187 base::Unretained(fifo_.get())),
188 dummy_msg->content_size()));
189 if (!msg)
190 return false;
191
192 VideoDecoderConfigMarshaller::Write(config, msg.get());
193 return true;
194 }
195
196 bool AvStreamerProxy::SendBuffer(
197 const scoped_refptr<DecoderBufferBase>& buffer) {
198 // Create a dummy message to calculate first the message size.
199 std::unique_ptr<MediaMessage> dummy_msg(
200 MediaMessage::CreateDummyMessage(FrameMediaMsg));
201 DecoderBufferBaseMarshaller::Write(buffer, dummy_msg.get());
202
203 // Create the real message and write the actual content.
204 std::unique_ptr<MediaMessage> msg(MediaMessage::CreateMessage(
205 FrameMediaMsg, base::Bind(&MediaMessageFifo::ReserveMemory,
206 base::Unretained(fifo_.get())),
207 dummy_msg->content_size()));
208 if (!msg)
209 return false;
210
211 DecoderBufferBaseMarshaller::Write(buffer, msg.get());
212 return true;
213 }
214
215 } // namespace media
216 } // namespace chromecast
OLDNEW
« no previous file with comments | « chromecast/media/cma/ipc_streamer/av_streamer_proxy.h ('k') | chromecast/media/cma/ipc_streamer/av_streamer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698