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

Side by Side Diff: media/base/android/video_media_codec_decoder.cc

Issue 1682923003: Rename browser side MediaCodec-based decoders (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Reformatted to make bots happy Created 4 years, 10 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
« no previous file with comments | « media/base/android/video_media_codec_decoder.h ('k') | media/media.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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/base/android/media_codec_video_decoder.h" 5 #include "media/base/android/video_media_codec_decoder.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "media/base/android/media_statistics.h" 11 #include "media/base/android/media_statistics.h"
12 #include "media/base/android/sdk_media_codec_bridge.h" 12 #include "media/base/android/sdk_media_codec_bridge.h"
13 #include "media/base/demuxer_stream.h" 13 #include "media/base/demuxer_stream.h"
14 #include "media/base/timestamp_constants.h" 14 #include "media/base/timestamp_constants.h"
15 15
16 namespace media { 16 namespace media {
17 17
18 namespace { 18 namespace {
19 const int kDelayForStandAloneEOS = 2; // milliseconds 19 const int kDelayForStandAloneEOS = 2; // milliseconds
20 } 20 }
21 21
22 MediaCodecVideoDecoder::MediaCodecVideoDecoder( 22 VideoMediaCodecDecoder::VideoMediaCodecDecoder(
23 const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner, 23 const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
24 FrameStatistics* frame_statistics, 24 FrameStatistics* frame_statistics,
25 const base::Closure& request_data_cb, 25 const base::Closure& request_data_cb,
26 const base::Closure& starvation_cb, 26 const base::Closure& starvation_cb,
27 const base::Closure& decoder_drained_cb, 27 const base::Closure& decoder_drained_cb,
28 const base::Closure& stop_done_cb, 28 const base::Closure& stop_done_cb,
29 const base::Closure& waiting_for_decryption_key_cb, 29 const base::Closure& waiting_for_decryption_key_cb,
30 const base::Closure& error_cb, 30 const base::Closure& error_cb,
31 const SetTimeCallback& update_current_time_cb, 31 const SetTimeCallback& update_current_time_cb,
32 const VideoSizeChangedCallback& video_size_changed_cb) 32 const VideoSizeChangedCallback& video_size_changed_cb)
33 : MediaCodecDecoder("VideoDecoder", 33 : MediaCodecDecoder("VideoDecoder",
34 media_task_runner, 34 media_task_runner,
35 frame_statistics, 35 frame_statistics,
36 request_data_cb, 36 request_data_cb,
37 starvation_cb, 37 starvation_cb,
38 decoder_drained_cb, 38 decoder_drained_cb,
39 stop_done_cb, 39 stop_done_cb,
40 waiting_for_decryption_key_cb, 40 waiting_for_decryption_key_cb,
41 error_cb), 41 error_cb),
42 is_protected_surface_required_(false), 42 is_protected_surface_required_(false),
43 update_current_time_cb_(update_current_time_cb), 43 update_current_time_cb_(update_current_time_cb),
44 video_size_changed_cb_(video_size_changed_cb) { 44 video_size_changed_cb_(video_size_changed_cb) {}
45 }
46 45
47 MediaCodecVideoDecoder::~MediaCodecVideoDecoder() { 46 VideoMediaCodecDecoder::~VideoMediaCodecDecoder() {
48 DCHECK(media_task_runner_->BelongsToCurrentThread()); 47 DCHECK(media_task_runner_->BelongsToCurrentThread());
49 DVLOG(1) << "VideoDecoder::~VideoDecoder()"; 48 DVLOG(1) << "VideoDecoder::~VideoDecoder()";
50 ReleaseDecoderResources(); 49 ReleaseDecoderResources();
51 } 50 }
52 51
53 const char* MediaCodecVideoDecoder::class_name() const { 52 const char* VideoMediaCodecDecoder::class_name() const {
54 return "VideoDecoder"; 53 return "VideoDecoder";
55 } 54 }
56 55
57 bool MediaCodecVideoDecoder::HasStream() const { 56 bool VideoMediaCodecDecoder::HasStream() const {
58 DCHECK(media_task_runner_->BelongsToCurrentThread()); 57 DCHECK(media_task_runner_->BelongsToCurrentThread());
59 58
60 return configs_.video_codec != kUnknownVideoCodec; 59 return configs_.video_codec != kUnknownVideoCodec;
61 } 60 }
62 61
63 void MediaCodecVideoDecoder::SetDemuxerConfigs(const DemuxerConfigs& configs) { 62 void VideoMediaCodecDecoder::SetDemuxerConfigs(const DemuxerConfigs& configs) {
64 DVLOG(1) << class_name() << "::" << __FUNCTION__ << " " << configs; 63 DVLOG(1) << class_name() << "::" << __FUNCTION__ << " " << configs;
65 64
66 configs_ = configs; 65 configs_ = configs;
67 66
68 if (video_size_.IsEmpty()) { 67 if (video_size_.IsEmpty()) {
69 video_size_ = configs_.video_size; 68 video_size_ = configs_.video_size;
70 media_task_runner_->PostTask( 69 media_task_runner_->PostTask(
71 FROM_HERE, base::Bind(video_size_changed_cb_, video_size_)); 70 FROM_HERE, base::Bind(video_size_changed_cb_, video_size_));
72 } 71 }
73 } 72 }
74 73
75 bool MediaCodecVideoDecoder::IsContentEncrypted() const { 74 bool VideoMediaCodecDecoder::IsContentEncrypted() const {
76 // Make sure SetDemuxerConfigs() as been called. 75 // Make sure SetDemuxerConfigs() as been called.
77 DCHECK(configs_.video_codec != kUnknownVideoCodec); 76 DCHECK(configs_.video_codec != kUnknownVideoCodec);
78 return configs_.is_video_encrypted; 77 return configs_.is_video_encrypted;
79 } 78 }
80 79
81 void MediaCodecVideoDecoder::ReleaseDecoderResources() { 80 void VideoMediaCodecDecoder::ReleaseDecoderResources() {
82 DCHECK(media_task_runner_->BelongsToCurrentThread()); 81 DCHECK(media_task_runner_->BelongsToCurrentThread());
83 DVLOG(1) << class_name() << "::" << __FUNCTION__; 82 DVLOG(1) << class_name() << "::" << __FUNCTION__;
84 83
85 DoEmergencyStop(); 84 DoEmergencyStop();
86 85
87 ReleaseMediaCodec(); 86 ReleaseMediaCodec();
88 87
89 surface_ = gfx::ScopedJavaSurface(); 88 surface_ = gfx::ScopedJavaSurface();
90 } 89 }
91 90
92 void MediaCodecVideoDecoder::ReleaseMediaCodec() { 91 void VideoMediaCodecDecoder::ReleaseMediaCodec() {
93 DCHECK(media_task_runner_->BelongsToCurrentThread()); 92 DCHECK(media_task_runner_->BelongsToCurrentThread());
94 93
95 MediaCodecDecoder::ReleaseMediaCodec(); 94 MediaCodecDecoder::ReleaseMediaCodec();
96 delayed_buffers_.clear(); 95 delayed_buffers_.clear();
97 } 96 }
98 97
99 void MediaCodecVideoDecoder::SetVideoSurface(gfx::ScopedJavaSurface surface) { 98 void VideoMediaCodecDecoder::SetVideoSurface(gfx::ScopedJavaSurface surface) {
100 DCHECK(media_task_runner_->BelongsToCurrentThread()); 99 DCHECK(media_task_runner_->BelongsToCurrentThread());
101 100
102 DVLOG(1) << class_name() << "::" << __FUNCTION__ 101 DVLOG(1) << class_name() << "::" << __FUNCTION__
103 << (surface.IsEmpty() ? " empty" : " non-empty"); 102 << (surface.IsEmpty() ? " empty" : " non-empty");
104 103
105 surface_ = std::move(surface); 104 surface_ = std::move(surface);
106 105
107 needs_reconfigure_ = true; 106 needs_reconfigure_ = true;
108 } 107 }
109 108
110 bool MediaCodecVideoDecoder::HasVideoSurface() const { 109 bool VideoMediaCodecDecoder::HasVideoSurface() const {
111 DCHECK(media_task_runner_->BelongsToCurrentThread()); 110 DCHECK(media_task_runner_->BelongsToCurrentThread());
112 111
113 return !surface_.IsEmpty(); 112 return !surface_.IsEmpty();
114 } 113 }
115 114
116 void MediaCodecVideoDecoder::SetProtectedSurfaceRequired(bool value) { 115 void VideoMediaCodecDecoder::SetProtectedSurfaceRequired(bool value) {
117 DCHECK(media_task_runner_->BelongsToCurrentThread()); 116 DCHECK(media_task_runner_->BelongsToCurrentThread());
118 117
119 is_protected_surface_required_ = value; 118 is_protected_surface_required_ = value;
120 } 119 }
121 120
122 bool MediaCodecVideoDecoder::IsProtectedSurfaceRequired() const { 121 bool VideoMediaCodecDecoder::IsProtectedSurfaceRequired() const {
123 DCHECK(media_task_runner_->BelongsToCurrentThread()); 122 DCHECK(media_task_runner_->BelongsToCurrentThread());
124 123
125 return is_protected_surface_required_; 124 return is_protected_surface_required_;
126 } 125 }
127 126
128 bool MediaCodecVideoDecoder::IsCodecReconfigureNeeded( 127 bool VideoMediaCodecDecoder::IsCodecReconfigureNeeded(
129 const DemuxerConfigs& next) const { 128 const DemuxerConfigs& next) const {
130 if (always_reconfigure_for_tests_) 129 if (always_reconfigure_for_tests_)
131 return true; 130 return true;
132 131
133 if (configs_.video_codec != next.video_codec || 132 if (configs_.video_codec != next.video_codec ||
134 configs_.is_video_encrypted != next.is_video_encrypted) { 133 configs_.is_video_encrypted != next.is_video_encrypted) {
135 return true; 134 return true;
136 } 135 }
137 136
138 // Only size changes below this point 137 // Only size changes below this point
139 138
140 if (configs_.video_size.width() == next.video_size.width() && 139 if (configs_.video_size.width() == next.video_size.width() &&
141 configs_.video_size.height() == next.video_size.height()) { 140 configs_.video_size.height() == next.video_size.height()) {
142 return false; // i.e. configs_ == next 141 return false; // i.e. configs_ == next
143 } 142 }
144 143
145 return !static_cast<VideoCodecBridge*>(media_codec_bridge_.get()) 144 return !static_cast<VideoCodecBridge*>(media_codec_bridge_.get())
146 ->IsAdaptivePlaybackSupported(next.video_size.width(), 145 ->IsAdaptivePlaybackSupported(next.video_size.width(),
147 next.video_size.height()); 146 next.video_size.height());
148 } 147 }
149 148
150 MediaCodecDecoder::ConfigStatus MediaCodecVideoDecoder::ConfigureInternal( 149 MediaCodecDecoder::ConfigStatus VideoMediaCodecDecoder::ConfigureInternal(
151 jobject media_crypto) { 150 jobject media_crypto) {
152 DCHECK(media_task_runner_->BelongsToCurrentThread()); 151 DCHECK(media_task_runner_->BelongsToCurrentThread());
153 152
154 DVLOG(1) << class_name() << "::" << __FUNCTION__; 153 DVLOG(1) << class_name() << "::" << __FUNCTION__;
155 154
156 // If we cannot find a key frame in cache, the browser seek is needed. 155 // If we cannot find a key frame in cache, the browser seek is needed.
157 if (!au_queue_.RewindToLastKeyFrame()) { 156 if (!au_queue_.RewindToLastKeyFrame()) {
158 DVLOG(1) << class_name() << "::" << __FUNCTION__ << " key frame required"; 157 DVLOG(1) << class_name() << "::" << __FUNCTION__ << " key frame required";
159 return kConfigKeyFrameRequired; 158 return kConfigKeyFrameRequired;
160 } 159 }
161 160
162 if (configs_.video_codec == kUnknownVideoCodec) { 161 if (configs_.video_codec == kUnknownVideoCodec) {
163 DVLOG(0) << class_name() << "::" << __FUNCTION__ 162 DVLOG(0) << class_name() << "::" << __FUNCTION__
164 << ": configuration parameters are required"; 163 << ": configuration parameters are required";
165 return kConfigFailure; 164 return kConfigFailure;
166 } 165 }
167 166
168 if (surface_.IsEmpty()) { 167 if (surface_.IsEmpty()) {
169 DVLOG(0) << class_name() << "::" << __FUNCTION__ << ": surface is required"; 168 DVLOG(0) << class_name() << "::" << __FUNCTION__ << ": surface is required";
170 return kConfigFailure; 169 return kConfigFailure;
171 } 170 }
172 171
173 bool is_secure = IsContentEncrypted() && is_protected_surface_required_; 172 bool is_secure = IsContentEncrypted() && is_protected_surface_required_;
174 173
175 media_codec_bridge_.reset(VideoCodecBridge::CreateDecoder( 174 media_codec_bridge_.reset(VideoCodecBridge::CreateDecoder(
176 configs_.video_codec, 175 configs_.video_codec, is_secure, configs_.video_size,
177 is_secure, 176 surface_.j_surface().obj(), media_crypto));
178 configs_.video_size,
179 surface_.j_surface().obj(),
180 media_crypto));
181 177
182 if (!media_codec_bridge_) { 178 if (!media_codec_bridge_) {
183 DVLOG(0) << class_name() << "::" << __FUNCTION__ 179 DVLOG(0) << class_name() << "::" << __FUNCTION__
184 << " failed: cannot create video codec"; 180 << " failed: cannot create video codec";
185 return kConfigFailure; 181 return kConfigFailure;
186 } 182 }
187 183
188 DVLOG(0) << class_name() << "::" << __FUNCTION__ << " succeeded"; 184 DVLOG(0) << class_name() << "::" << __FUNCTION__ << " succeeded";
189 185
190 if (!codec_created_for_tests_cb_.is_null()) 186 if (!codec_created_for_tests_cb_.is_null())
191 media_task_runner_->PostTask(FROM_HERE, codec_created_for_tests_cb_); 187 media_task_runner_->PostTask(FROM_HERE, codec_created_for_tests_cb_);
192 188
193 return kConfigOk; 189 return kConfigOk;
194 } 190 }
195 191
196 void MediaCodecVideoDecoder::AssociateCurrentTimeWithPTS(base::TimeDelta pts) { 192 void VideoMediaCodecDecoder::AssociateCurrentTimeWithPTS(base::TimeDelta pts) {
197 DCHECK(media_task_runner_->BelongsToCurrentThread()); 193 DCHECK(media_task_runner_->BelongsToCurrentThread());
198 194
199 DVLOG(1) << class_name() << "::" << __FUNCTION__ << " pts:" << pts; 195 DVLOG(1) << class_name() << "::" << __FUNCTION__ << " pts:" << pts;
200 196
201 start_time_ticks_ = base::TimeTicks::Now(); 197 start_time_ticks_ = base::TimeTicks::Now();
202 start_pts_ = pts; 198 start_pts_ = pts;
203 last_seen_pts_ = pts; 199 last_seen_pts_ = pts;
204 } 200 }
205 201
206 void MediaCodecVideoDecoder::DissociatePTSFromTime() { 202 void VideoMediaCodecDecoder::DissociatePTSFromTime() {
207 DCHECK(media_task_runner_->BelongsToCurrentThread()); 203 DCHECK(media_task_runner_->BelongsToCurrentThread());
208 204
209 start_pts_ = last_seen_pts_ = kNoTimestamp(); 205 start_pts_ = last_seen_pts_ = kNoTimestamp();
210 } 206 }
211 207
212 void MediaCodecVideoDecoder::OnOutputFormatChanged() { 208 void VideoMediaCodecDecoder::OnOutputFormatChanged() {
213 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); 209 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
214 210
215 gfx::Size prev_size = video_size_; 211 gfx::Size prev_size = video_size_;
216 212
217 // See b/18224769. The values reported from MediaCodecBridge::GetOutputFormat 213 // See b/18224769. The values reported from MediaCodecBridge::GetOutputFormat
218 // correspond to the actual video frame size, but this is not necessarily the 214 // correspond to the actual video frame size, but this is not necessarily the
219 // size that should be output. 215 // size that should be output.
220 video_size_ = configs_.video_size; 216 video_size_ = configs_.video_size;
221 if (video_size_ != prev_size) { 217 if (video_size_ != prev_size) {
222 media_task_runner_->PostTask( 218 media_task_runner_->PostTask(
223 FROM_HERE, base::Bind(video_size_changed_cb_, video_size_)); 219 FROM_HERE, base::Bind(video_size_changed_cb_, video_size_));
224 } 220 }
225 } 221 }
226 222
227 void MediaCodecVideoDecoder::Render(int buffer_index, 223 void VideoMediaCodecDecoder::Render(int buffer_index,
228 size_t offset, 224 size_t offset,
229 size_t size, 225 size_t size,
230 RenderMode render_mode, 226 RenderMode render_mode,
231 base::TimeDelta pts, 227 base::TimeDelta pts,
232 bool eos_encountered) { 228 bool eos_encountered) {
233 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); 229 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
234 230
235 DVLOG(2) << class_name() << "::" << __FUNCTION__ << " pts:" << pts 231 DVLOG(2) << class_name() << "::" << __FUNCTION__ << " pts:" << pts
236 << (eos_encountered ? " EOS " : " ") << AsString(render_mode); 232 << (eos_encountered ? " EOS " : " ") << AsString(render_mode);
237 233
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 288
293 // Render late frames immediately. 289 // Render late frames immediately.
294 ReleaseOutputBuffer(buffer_index, pts, render, update_time, 290 ReleaseOutputBuffer(buffer_index, pts, render, update_time,
295 eos_encountered); 291 eos_encountered);
296 return; 292 return;
297 } 293 }
298 294
299 delayed_buffers_.insert(buffer_index); 295 delayed_buffers_.insert(buffer_index);
300 296
301 decoder_thread_.task_runner()->PostDelayedTask( 297 decoder_thread_.task_runner()->PostDelayedTask(
302 FROM_HERE, base::Bind(&MediaCodecVideoDecoder::ReleaseOutputBuffer, 298 FROM_HERE, base::Bind(&VideoMediaCodecDecoder::ReleaseOutputBuffer,
303 base::Unretained(this), buffer_index, pts, render, 299 base::Unretained(this), buffer_index, pts, render,
304 update_time, eos_encountered), 300 update_time, eos_encountered),
305 time_to_render); 301 time_to_render);
306 } 302 }
307 303
308 int MediaCodecVideoDecoder::NumDelayedRenderTasks() const { 304 int VideoMediaCodecDecoder::NumDelayedRenderTasks() const {
309 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); 305 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
310 306
311 return delayed_buffers_.size(); 307 return delayed_buffers_.size();
312 } 308 }
313 309
314 void MediaCodecVideoDecoder::ReleaseDelayedBuffers() { 310 void VideoMediaCodecDecoder::ReleaseDelayedBuffers() {
315 // Media thread 311 // Media thread
316 // Called when there is no decoder thread 312 // Called when there is no decoder thread
317 for (int index : delayed_buffers_) 313 for (int index : delayed_buffers_)
318 media_codec_bridge_->ReleaseOutputBuffer(index, false); 314 media_codec_bridge_->ReleaseOutputBuffer(index, false);
319 315
320 delayed_buffers_.clear(); 316 delayed_buffers_.clear();
321 } 317 }
322 318
323 #ifndef NDEBUG 319 #ifndef NDEBUG
324 void MediaCodecVideoDecoder::VerifyUnitIsKeyFrame( 320 void VideoMediaCodecDecoder::VerifyUnitIsKeyFrame(
325 const AccessUnit* unit) const { 321 const AccessUnit* unit) const {
326 // The first video frame in a sequence must be a key frame or stand-alone EOS. 322 // The first video frame in a sequence must be a key frame or stand-alone EOS.
327 DCHECK(unit); 323 DCHECK(unit);
328 bool stand_alone_eos = unit->is_end_of_stream && unit->data.empty(); 324 bool stand_alone_eos = unit->is_end_of_stream && unit->data.empty();
329 DCHECK(stand_alone_eos || unit->is_key_frame); 325 DCHECK(stand_alone_eos || unit->is_key_frame);
330 } 326 }
331 #endif 327 #endif
332 328
333 void MediaCodecVideoDecoder::ReleaseOutputBuffer(int buffer_index, 329 void VideoMediaCodecDecoder::ReleaseOutputBuffer(int buffer_index,
334 base::TimeDelta pts, 330 base::TimeDelta pts,
335 bool render, 331 bool render,
336 bool update_time, 332 bool update_time,
337 bool eos_encountered) { 333 bool eos_encountered) {
338 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); 334 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
339 335
340 DVLOG(2) << class_name() << "::" << __FUNCTION__ << " pts:" << pts; 336 DVLOG(2) << class_name() << "::" << __FUNCTION__ << " pts:" << pts;
341 337
342 // Do not render if we are in emergency stop, there might be no surface. 338 // Do not render if we are in emergency stop, there might be no surface.
343 if (InEmergencyStop()) 339 if (InEmergencyStop())
344 render = false; 340 render = false;
345 341
346 media_codec_bridge_->ReleaseOutputBuffer(buffer_index, render); 342 media_codec_bridge_->ReleaseOutputBuffer(buffer_index, render);
347 343
348 delayed_buffers_.erase(buffer_index); 344 delayed_buffers_.erase(buffer_index);
349 345
350 CheckLastFrame(eos_encountered, !delayed_buffers_.empty()); 346 CheckLastFrame(eos_encountered, !delayed_buffers_.empty());
351 347
352 // |update_current_time_cb_| might be null if there is audio stream. 348 // |update_current_time_cb_| might be null if there is audio stream.
353 // Do not update current time for stand-alone EOS frames. 349 // Do not update current time for stand-alone EOS frames.
354 if (!update_current_time_cb_.is_null() && update_time) { 350 if (!update_current_time_cb_.is_null() && update_time) {
355 media_task_runner_->PostTask( 351 media_task_runner_->PostTask(
356 FROM_HERE, base::Bind(update_current_time_cb_, pts, pts, false)); 352 FROM_HERE, base::Bind(update_current_time_cb_, pts, pts, false));
357 } 353 }
358 } 354 }
359 355
360 } // namespace media 356 } // namespace media
OLDNEW
« no previous file with comments | « media/base/android/video_media_codec_decoder.h ('k') | media/media.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698