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

Side by Side Diff: media/renderers/video_renderer_impl.cc

Issue 1873513003: Add video-rendering to mojo media pipeline. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: addressed comments Created 4 years, 8 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
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/renderers/video_renderer_impl.h" 5 #include "media/renderers/video_renderer_impl.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback.h" 10 #include "base/callback.h"
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 start_timestamp_ = timestamp; 119 start_timestamp_ = timestamp;
120 AttemptRead_Locked(); 120 AttemptRead_Locked();
121 } 121 }
122 122
123 void VideoRendererImpl::Initialize( 123 void VideoRendererImpl::Initialize(
124 DemuxerStream* stream, 124 DemuxerStream* stream,
125 const PipelineStatusCB& init_cb, 125 const PipelineStatusCB& init_cb,
126 CdmContext* cdm_context, 126 CdmContext* cdm_context,
127 const StatisticsCB& statistics_cb, 127 const StatisticsCB& statistics_cb,
128 const BufferingStateCB& buffering_state_cb, 128 const BufferingStateCB& buffering_state_cb,
129 const NaturalSizeChangedCB& natural_size_changed_cb,
129 const base::Closure& ended_cb, 130 const base::Closure& ended_cb,
130 const PipelineStatusCB& error_cb, 131 const PipelineStatusCB& error_cb,
131 const TimeSource::WallClockTimeCB& wall_clock_time_cb, 132 const TimeSource::WallClockTimeCB& wall_clock_time_cb,
132 const base::Closure& waiting_for_decryption_key_cb) { 133 const base::Closure& waiting_for_decryption_key_cb) {
133 DCHECK(task_runner_->BelongsToCurrentThread()); 134 DCHECK(task_runner_->BelongsToCurrentThread());
134 base::AutoLock auto_lock(lock_); 135 base::AutoLock auto_lock(lock_);
135 DCHECK(stream); 136 DCHECK(stream);
136 DCHECK_EQ(stream->type(), DemuxerStream::VIDEO); 137 DCHECK_EQ(stream->type(), DemuxerStream::VIDEO);
137 DCHECK(!init_cb.is_null()); 138 DCHECK(!init_cb.is_null());
138 DCHECK(!statistics_cb.is_null()); 139 DCHECK(!statistics_cb.is_null());
(...skipping 12 matching lines...) Expand all
151 MEDIA_LOG(DEBUG, media_log_) << "Video rendering in low delay mode."; 152 MEDIA_LOG(DEBUG, media_log_) << "Video rendering in low delay mode.";
152 153
153 // Always post |init_cb_| because |this| could be destroyed if initialization 154 // Always post |init_cb_| because |this| could be destroyed if initialization
154 // failed. 155 // failed.
155 init_cb_ = BindToCurrentLoop(init_cb); 156 init_cb_ = BindToCurrentLoop(init_cb);
156 157
157 // Always post |buffering_state_cb_| because it may otherwise invoke reentrant 158 // Always post |buffering_state_cb_| because it may otherwise invoke reentrant
158 // calls to OnTimeStateChanged() under lock, which can deadlock the compositor 159 // calls to OnTimeStateChanged() under lock, which can deadlock the compositor
159 // and media threads. 160 // and media threads.
160 buffering_state_cb_ = BindToCurrentLoop(buffering_state_cb); 161 buffering_state_cb_ = BindToCurrentLoop(buffering_state_cb);
161 162 natural_size_changed_cb_ = natural_size_changed_cb;
162 statistics_cb_ = statistics_cb; 163 statistics_cb_ = statistics_cb;
163 ended_cb_ = ended_cb; 164 ended_cb_ = ended_cb;
164 error_cb_ = error_cb; 165 error_cb_ = error_cb;
165 wall_clock_time_cb_ = wall_clock_time_cb; 166 wall_clock_time_cb_ = wall_clock_time_cb;
166 state_ = kInitializing; 167 state_ = kInitializing;
167 168
168 video_frame_stream_->Initialize( 169 video_frame_stream_->Initialize(
169 stream, base::Bind(&VideoRendererImpl::OnVideoFrameStreamInitialized, 170 stream, base::Bind(&VideoRendererImpl::OnVideoFrameStreamInitialized,
170 weak_factory_.GetWeakPtr()), 171 weak_factory_.GetWeakPtr()),
171 cdm_context, statistics_cb, waiting_for_decryption_key_cb); 172 cdm_context, statistics_cb, waiting_for_decryption_key_cb);
172 } 173 }
173 174
174 scoped_refptr<VideoFrame> VideoRendererImpl::Render( 175 scoped_refptr<VideoFrame> VideoRendererImpl::Render(
175 base::TimeTicks deadline_min, 176 base::TimeTicks deadline_min,
176 base::TimeTicks deadline_max, 177 base::TimeTicks deadline_max,
177 bool background_rendering) { 178 bool background_rendering) {
178 base::AutoLock auto_lock(lock_); 179 base::AutoLock auto_lock(lock_);
179 DCHECK_EQ(state_, kPlaying); 180 DCHECK_EQ(state_, kPlaying);
180 181
181 size_t frames_dropped = 0; 182 size_t frames_dropped = 0;
182 scoped_refptr<VideoFrame> result = 183 scoped_refptr<VideoFrame> result =
183 algorithm_->Render(deadline_min, deadline_max, &frames_dropped); 184 algorithm_->Render(deadline_min, deadline_max, &frames_dropped);
184 185
185 // Due to how the |algorithm_| holds frames, this should never be null if 186 // Due to how the |algorithm_| holds frames, this should never be null if
186 // we've had a proper startup sequence. 187 // we've had a proper startup sequence.
187 DCHECK(result); 188 DCHECK(result);
188 189
190 if (last_frame_natural_size_ != result->natural_size()) {
191 last_frame_natural_size_ = result->natural_size();
192 task_runner_->PostTask(FROM_HERE, base::Bind(natural_size_changed_cb_,
193 last_frame_natural_size_));
194 }
195
189 // Declare HAVE_NOTHING if we reach a state where we can't progress playback 196 // Declare HAVE_NOTHING if we reach a state where we can't progress playback
190 // any further. We don't want to do this if we've already done so, reached 197 // any further. We don't want to do this if we've already done so, reached
191 // end of stream, or have frames available. We also don't want to do this in 198 // end of stream, or have frames available. We also don't want to do this in
192 // background rendering mode unless this isn't the first background render 199 // background rendering mode unless this isn't the first background render
193 // tick and we haven't seen any decoded frames since the last one. 200 // tick and we haven't seen any decoded frames since the last one.
194 // 201 //
195 // We use the inverse of |render_first_frame_and_stop_| as a proxy for the 202 // We use the inverse of |render_first_frame_and_stop_| as a proxy for the
196 // value of |time_progressing_| here since we can't access it from the 203 // value of |time_progressing_| here since we can't access it from the
197 // compositor thread. If we're here (in Render()) the sink must have been 204 // compositor thread. If we're here (in Render()) the sink must have been
198 // started -- but if it was started only to render the first frame and stop, 205 // started -- but if it was started only to render the first frame and stop,
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 FROM_HERE, base::Bind(&VideoRendererImpl::MaybeStopSinkAfterFirstPaint, 243 FROM_HERE, base::Bind(&VideoRendererImpl::MaybeStopSinkAfterFirstPaint,
237 weak_factory_.GetWeakPtr()), 244 weak_factory_.GetWeakPtr()),
238 base::TimeDelta::FromMilliseconds(250)); 245 base::TimeDelta::FromMilliseconds(250));
239 } 246 }
240 247
241 // Always post this task, it will acquire new frames if necessary and since it 248 // Always post this task, it will acquire new frames if necessary and since it
242 // happens on another thread, even if we don't have room in the queue now, by 249 // happens on another thread, even if we don't have room in the queue now, by
243 // the time it runs (may be delayed up to 50ms for complex decodes!) we might. 250 // the time it runs (may be delayed up to 50ms for complex decodes!) we might.
244 task_runner_->PostTask(FROM_HERE, base::Bind(&VideoRendererImpl::AttemptRead, 251 task_runner_->PostTask(FROM_HERE, base::Bind(&VideoRendererImpl::AttemptRead,
245 weak_factory_.GetWeakPtr())); 252 weak_factory_.GetWeakPtr()));
246
247 return result; 253 return result;
248 } 254 }
249 255
250 void VideoRendererImpl::OnFrameDropped() { 256 void VideoRendererImpl::OnFrameDropped() {
251 base::AutoLock auto_lock(lock_); 257 base::AutoLock auto_lock(lock_);
252 algorithm_->OnLastFrameDropped(); 258 algorithm_->OnLastFrameDropped();
253 } 259 }
254 260
255 void VideoRendererImpl::OnVideoFrameStreamInitialized(bool success) { 261 void VideoRendererImpl::OnVideoFrameStreamInitialized(bool success) {
256 DCHECK(task_runner_->BelongsToCurrentThread()); 262 DCHECK(task_runner_->BelongsToCurrentThread());
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
633 std::vector<base::TimeTicks> current_time; 639 std::vector<base::TimeTicks> current_time;
634 wall_clock_time_cb_.Run(std::vector<base::TimeDelta>(), &current_time); 640 wall_clock_time_cb_.Run(std::vector<base::TimeDelta>(), &current_time);
635 return current_time[0]; 641 return current_time[0];
636 } 642 }
637 643
638 bool VideoRendererImpl::IsBeforeStartTime(base::TimeDelta timestamp) { 644 bool VideoRendererImpl::IsBeforeStartTime(base::TimeDelta timestamp) {
639 return timestamp + video_frame_stream_->AverageDuration() < start_timestamp_; 645 return timestamp + video_frame_stream_->AverageDuration() < start_timestamp_;
640 } 646 }
641 647
642 } // namespace media 648 } // namespace media
OLDNEW
« media/base/pipeline_status.h ('K') | « media/renderers/video_renderer_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698