OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 // The bulk of this file is support code; sorry about that. Here's an overview | 5 // The bulk of this file is support code; sorry about that. Here's an overview |
6 // to hopefully help readers of this code: | 6 // to hopefully help readers of this code: |
7 // - RenderingHelper is charged with interacting with X11/{EGL/GLES2,GLX/GL} or | 7 // - RenderingHelper is charged with interacting with X11/{EGL/GLES2,GLX/GL} or |
8 // Win/EGL. | 8 // Win/EGL. |
9 // - ClientState is an enum for the state of the decode client used by the test. | 9 // - ClientState is an enum for the state of the decode client used by the test. |
10 // - ClientStateNotification is a barrier abstraction that allows the test code | 10 // - ClientStateNotification is a barrier abstraction that allows the test code |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 const base::FilePath::CharType* g_test_video_data = | 92 const base::FilePath::CharType* g_test_video_data = |
93 // FILE_PATH_LITERAL("test-25fps.vp8:320:240:250:250:50:175:11"); | 93 // FILE_PATH_LITERAL("test-25fps.vp8:320:240:250:250:50:175:11"); |
94 FILE_PATH_LITERAL("test-25fps.h264:320:240:250:258:50:175:1"); | 94 FILE_PATH_LITERAL("test-25fps.h264:320:240:250:258:50:175:1"); |
95 | 95 |
96 // The file path of the test output log. This is used to communicate the test | 96 // The file path of the test output log. This is used to communicate the test |
97 // results to CrOS autotests. We can enable the log and specify the filename by | 97 // results to CrOS autotests. We can enable the log and specify the filename by |
98 // the "--output_log" switch. | 98 // the "--output_log" switch. |
99 const base::FilePath::CharType* g_output_log = NULL; | 99 const base::FilePath::CharType* g_output_log = NULL; |
100 | 100 |
101 // The value is set by the switch "--rendering_fps". | 101 // The value is set by the switch "--rendering_fps". |
102 double g_rendering_fps = 0; | 102 double g_rendering_fps = 60; |
103 | |
104 // Disable rendering, the value is set by the switch "--disable_rendering". | |
105 bool g_disable_rendering = false; | |
106 | 103 |
107 // Magic constants for differentiating the reasons for NotifyResetDone being | 104 // Magic constants for differentiating the reasons for NotifyResetDone being |
108 // called. | 105 // called. |
109 enum ResetPoint { | 106 enum ResetPoint { |
110 // Reset() just after calling Decode() with a fragment containing config info. | 107 // Reset() just after calling Decode() with a fragment containing config info. |
111 RESET_AFTER_FIRST_CONFIG_INFO = -4, | 108 RESET_AFTER_FIRST_CONFIG_INFO = -4, |
112 START_OF_STREAM_RESET = -3, | 109 START_OF_STREAM_RESET = -3, |
113 MID_STREAM_RESET = -2, | 110 MID_STREAM_RESET = -2, |
114 END_OF_STREAM_RESET = -1 | 111 END_OF_STREAM_RESET = -1 |
115 }; | 112 }; |
(...skipping 22 matching lines...) Expand all Loading... |
138 int height; | 135 int height; |
139 int num_frames; | 136 int num_frames; |
140 int num_fragments; | 137 int num_fragments; |
141 int min_fps_render; | 138 int min_fps_render; |
142 int min_fps_no_render; | 139 int min_fps_no_render; |
143 media::VideoCodecProfile profile; | 140 media::VideoCodecProfile profile; |
144 int reset_after_frame_num; | 141 int reset_after_frame_num; |
145 std::string data_str; | 142 std::string data_str; |
146 }; | 143 }; |
147 | 144 |
148 // Presumed minimal display size. | 145 const gfx::Size kThumbnailsDisplaySize(1366, 768); |
149 // We subtract one pixel from the width because some ARM chromebooks do not | |
150 // support two fullscreen app running at the same time. See crbug.com/270064. | |
151 const gfx::Size kThumbnailsDisplaySize(1366 - 1, 768); | |
152 const gfx::Size kThumbnailsPageSize(1600, 1200); | 146 const gfx::Size kThumbnailsPageSize(1600, 1200); |
153 const gfx::Size kThumbnailSize(160, 120); | 147 const gfx::Size kThumbnailSize(160, 120); |
154 const int kMD5StringLength = 32; | 148 const int kMD5StringLength = 32; |
155 | 149 |
156 // Read in golden MD5s for the thumbnailed rendering of this video | 150 // Read in golden MD5s for the thumbnailed rendering of this video |
157 void ReadGoldenThumbnailMD5s(const TestVideoFile* video_file, | 151 void ReadGoldenThumbnailMD5s(const TestVideoFile* video_file, |
158 std::vector<std::string>* md5_strings) { | 152 std::vector<std::string>* md5_strings) { |
159 base::FilePath filepath(video_file->file_name); | 153 base::FilePath filepath(video_file->file_name); |
160 filepath = filepath.AddExtension(FILE_PATH_LITERAL(".md5")); | 154 filepath = filepath.AddExtension(FILE_PATH_LITERAL(".md5")); |
161 std::string all_md5s; | 155 std::string all_md5s; |
(...skipping 27 matching lines...) Expand all Loading... |
189 CS_INITIALIZED = 2, | 183 CS_INITIALIZED = 2, |
190 CS_FLUSHING = 3, | 184 CS_FLUSHING = 3, |
191 CS_FLUSHED = 4, | 185 CS_FLUSHED = 4, |
192 CS_RESETTING = 5, | 186 CS_RESETTING = 5, |
193 CS_RESET = 6, | 187 CS_RESET = 6, |
194 CS_ERROR = 7, | 188 CS_ERROR = 7, |
195 CS_DESTROYED = 8, | 189 CS_DESTROYED = 8, |
196 CS_MAX, // Must be last entry. | 190 CS_MAX, // Must be last entry. |
197 }; | 191 }; |
198 | 192 |
199 // A wrapper client that throttles the PictureReady callbacks to a given rate. | |
200 // It may drops or queues frame to deliver them on time. | |
201 class ThrottlingVDAClient : public VideoDecodeAccelerator::Client, | |
202 public base::SupportsWeakPtr<ThrottlingVDAClient> { | |
203 public: | |
204 // Callback invoked whan the picture is dropped and should be reused for | |
205 // the decoder again. | |
206 typedef base::Callback<void(int32 picture_buffer_id)> ReusePictureCB; | |
207 | |
208 ThrottlingVDAClient(VideoDecodeAccelerator::Client* client, | |
209 double fps, | |
210 ReusePictureCB reuse_picture_cb); | |
211 virtual ~ThrottlingVDAClient(); | |
212 | |
213 // VideoDecodeAccelerator::Client implementation | |
214 virtual void ProvidePictureBuffers(uint32 requested_num_of_buffers, | |
215 const gfx::Size& dimensions, | |
216 uint32 texture_target) OVERRIDE; | |
217 virtual void DismissPictureBuffer(int32 picture_buffer_id) OVERRIDE; | |
218 virtual void PictureReady(const media::Picture& picture) OVERRIDE; | |
219 virtual void NotifyEndOfBitstreamBuffer(int32 bitstream_buffer_id) OVERRIDE; | |
220 virtual void NotifyFlushDone() OVERRIDE; | |
221 virtual void NotifyResetDone() OVERRIDE; | |
222 virtual void NotifyError(VideoDecodeAccelerator::Error error) OVERRIDE; | |
223 | |
224 int num_decoded_frames() { return num_decoded_frames_; } | |
225 | |
226 private: | |
227 | |
228 void CallClientPictureReady(int version); | |
229 | |
230 VideoDecodeAccelerator::Client* client_; | |
231 ReusePictureCB reuse_picture_cb_; | |
232 base::TimeTicks next_frame_delivered_time_; | |
233 base::TimeDelta frame_duration_; | |
234 | |
235 int num_decoded_frames_; | |
236 int stream_version_; | |
237 std::deque<media::Picture> pending_pictures_; | |
238 | |
239 DISALLOW_IMPLICIT_CONSTRUCTORS(ThrottlingVDAClient); | |
240 }; | |
241 | |
242 ThrottlingVDAClient::ThrottlingVDAClient(VideoDecodeAccelerator::Client* client, | |
243 double fps, | |
244 ReusePictureCB reuse_picture_cb) | |
245 : client_(client), | |
246 reuse_picture_cb_(reuse_picture_cb), | |
247 num_decoded_frames_(0), | |
248 stream_version_(0) { | |
249 CHECK(client_); | |
250 CHECK_GT(fps, 0); | |
251 frame_duration_ = base::TimeDelta::FromSeconds(1) / fps; | |
252 } | |
253 | |
254 ThrottlingVDAClient::~ThrottlingVDAClient() {} | |
255 | |
256 void ThrottlingVDAClient::ProvidePictureBuffers(uint32 requested_num_of_buffers, | |
257 const gfx::Size& dimensions, | |
258 uint32 texture_target) { | |
259 client_->ProvidePictureBuffers( | |
260 requested_num_of_buffers, dimensions, texture_target); | |
261 } | |
262 | |
263 void ThrottlingVDAClient::DismissPictureBuffer(int32 picture_buffer_id) { | |
264 client_->DismissPictureBuffer(picture_buffer_id); | |
265 } | |
266 | |
267 void ThrottlingVDAClient::PictureReady(const media::Picture& picture) { | |
268 ++num_decoded_frames_; | |
269 | |
270 if (pending_pictures_.empty()) { | |
271 base::TimeDelta delay = | |
272 next_frame_delivered_time_.is_null() | |
273 ? base::TimeDelta() | |
274 : next_frame_delivered_time_ - base::TimeTicks::Now(); | |
275 base::MessageLoop::current()->PostDelayedTask( | |
276 FROM_HERE, | |
277 base::Bind(&ThrottlingVDAClient::CallClientPictureReady, | |
278 AsWeakPtr(), | |
279 stream_version_), | |
280 delay); | |
281 } | |
282 pending_pictures_.push_back(picture); | |
283 } | |
284 | |
285 void ThrottlingVDAClient::CallClientPictureReady(int version) { | |
286 // Just return if we have reset the decoder | |
287 if (version != stream_version_) | |
288 return; | |
289 | |
290 base::TimeTicks now = base::TimeTicks::Now(); | |
291 | |
292 if (next_frame_delivered_time_.is_null()) | |
293 next_frame_delivered_time_ = now; | |
294 | |
295 if (next_frame_delivered_time_ + frame_duration_ < now) { | |
296 // Too late, drop the frame | |
297 reuse_picture_cb_.Run(pending_pictures_.front().picture_buffer_id()); | |
298 } else { | |
299 client_->PictureReady(pending_pictures_.front()); | |
300 } | |
301 | |
302 pending_pictures_.pop_front(); | |
303 next_frame_delivered_time_ += frame_duration_; | |
304 if (!pending_pictures_.empty()) { | |
305 base::MessageLoop::current()->PostDelayedTask( | |
306 FROM_HERE, | |
307 base::Bind(&ThrottlingVDAClient::CallClientPictureReady, | |
308 AsWeakPtr(), | |
309 stream_version_), | |
310 next_frame_delivered_time_ - base::TimeTicks::Now()); | |
311 } | |
312 } | |
313 | |
314 void ThrottlingVDAClient::NotifyEndOfBitstreamBuffer( | |
315 int32 bitstream_buffer_id) { | |
316 client_->NotifyEndOfBitstreamBuffer(bitstream_buffer_id); | |
317 } | |
318 | |
319 void ThrottlingVDAClient::NotifyFlushDone() { | |
320 if (!pending_pictures_.empty()) { | |
321 base::MessageLoop::current()->PostDelayedTask( | |
322 FROM_HERE, | |
323 base::Bind(&ThrottlingVDAClient::NotifyFlushDone, | |
324 base::Unretained(this)), | |
325 next_frame_delivered_time_ - base::TimeTicks::Now()); | |
326 return; | |
327 } | |
328 client_->NotifyFlushDone(); | |
329 } | |
330 | |
331 void ThrottlingVDAClient::NotifyResetDone() { | |
332 ++stream_version_; | |
333 while (!pending_pictures_.empty()) { | |
334 reuse_picture_cb_.Run(pending_pictures_.front().picture_buffer_id()); | |
335 pending_pictures_.pop_front(); | |
336 } | |
337 next_frame_delivered_time_ = base::TimeTicks(); | |
338 client_->NotifyResetDone(); | |
339 } | |
340 | |
341 void ThrottlingVDAClient::NotifyError(VideoDecodeAccelerator::Error error) { | |
342 client_->NotifyError(error); | |
343 } | |
344 | |
345 // Client that can accept callbacks from a VideoDecodeAccelerator and is used by | 193 // Client that can accept callbacks from a VideoDecodeAccelerator and is used by |
346 // the TESTs below. | 194 // the TESTs below. |
347 class GLRenderingVDAClient | 195 class GLRenderingVDAClient |
348 : public VideoDecodeAccelerator::Client, | 196 : public VideoDecodeAccelerator::Client, |
| 197 public RenderingHelper::Client, |
349 public base::SupportsWeakPtr<GLRenderingVDAClient> { | 198 public base::SupportsWeakPtr<GLRenderingVDAClient> { |
350 public: | 199 public: |
351 // Doesn't take ownership of |rendering_helper| or |note|, which must outlive | 200 // Doesn't take ownership of |rendering_helper| or |note|, which must outlive |
352 // |*this|. | 201 // |*this|. |
353 // |num_play_throughs| indicates how many times to play through the video. | 202 // |num_play_throughs| indicates how many times to play through the video. |
354 // |reset_after_frame_num| can be a frame number >=0 indicating a mid-stream | 203 // |reset_after_frame_num| can be a frame number >=0 indicating a mid-stream |
355 // Reset() should be done after that frame number is delivered, or | 204 // Reset() should be done after that frame number is delivered, or |
356 // END_OF_STREAM_RESET to indicate no mid-stream Reset(). | 205 // END_OF_STREAM_RESET to indicate no mid-stream Reset(). |
357 // |delete_decoder_state| indicates when the underlying decoder should be | 206 // |delete_decoder_state| indicates when the underlying decoder should be |
358 // Destroy()'d and deleted and can take values: N<0: delete after -N Decode() | 207 // Destroy()'d and deleted and can take values: N<0: delete after -N Decode() |
359 // calls have been made, N>=0 means interpret as ClientState. | 208 // calls have been made, N>=0 means interpret as ClientState. |
360 // Both |reset_after_frame_num| & |delete_decoder_state| apply only to the | 209 // Both |reset_after_frame_num| & |delete_decoder_state| apply only to the |
361 // last play-through (governed by |num_play_throughs|). | 210 // last play-through (governed by |num_play_throughs|). |
362 // |rendering_fps| indicates the target rendering fps. 0 means no target fps | 211 // |suppress_rendering| indicates GL rendering is supressed or not. |
363 // and it would render as fast as possible. | |
364 // |suppress_rendering| indicates GL rendering is suppressed or not. | |
365 // After |delay_reuse_after_frame_num| frame has been delivered, the client | 212 // After |delay_reuse_after_frame_num| frame has been delivered, the client |
366 // will start delaying the call to ReusePictureBuffer() for kReuseDelay. | 213 // will start delaying the call to ReusePictureBuffer() for kReuseDelay. |
367 // |decode_calls_per_second| is the number of VDA::Decode calls per second. | 214 // |decode_calls_per_second| is the number of VDA::Decode calls per second. |
368 // If |decode_calls_per_second| > 0, |num_in_flight_decodes| must be 1. | 215 // If |decode_calls_per_second| > 0, |num_in_flight_decodes| must be 1. |
369 GLRenderingVDAClient(RenderingHelper* rendering_helper, | 216 GLRenderingVDAClient(RenderingHelper* rendering_helper, |
370 int rendering_window_id, | 217 int rendering_window_id, |
371 ClientStateNotification<ClientState>* note, | 218 ClientStateNotification<ClientState>* note, |
372 const std::string& encoded_data, | 219 const std::string& encoded_data, |
373 int num_in_flight_decodes, | 220 int num_in_flight_decodes, |
374 int num_play_throughs, | 221 int num_play_throughs, |
375 int reset_after_frame_num, | 222 int reset_after_frame_num, |
376 int delete_decoder_state, | 223 int delete_decoder_state, |
377 int frame_width, | 224 int frame_width, |
378 int frame_height, | 225 int frame_height, |
379 media::VideoCodecProfile profile, | 226 media::VideoCodecProfile profile, |
380 double rendering_fps, | |
381 bool suppress_rendering, | 227 bool suppress_rendering, |
382 int delay_reuse_after_frame_num, | 228 int delay_reuse_after_frame_num, |
383 int decode_calls_per_second); | 229 int decode_calls_per_second, |
| 230 bool render_as_thumbnails); |
384 virtual ~GLRenderingVDAClient(); | 231 virtual ~GLRenderingVDAClient(); |
385 void CreateAndStartDecoder(); | 232 void CreateAndStartDecoder(); |
386 | 233 |
387 // VideoDecodeAccelerator::Client implementation. | 234 // VideoDecodeAccelerator::Client implementation. |
388 // The heart of the Client. | 235 // The heart of the Client. |
389 virtual void ProvidePictureBuffers(uint32 requested_num_of_buffers, | 236 virtual void ProvidePictureBuffers(uint32 requested_num_of_buffers, |
390 const gfx::Size& dimensions, | 237 const gfx::Size& dimensions, |
391 uint32 texture_target) OVERRIDE; | 238 uint32 texture_target) OVERRIDE; |
392 virtual void DismissPictureBuffer(int32 picture_buffer_id) OVERRIDE; | 239 virtual void DismissPictureBuffer(int32 picture_buffer_id) OVERRIDE; |
393 virtual void PictureReady(const media::Picture& picture) OVERRIDE; | 240 virtual void PictureReady(const media::Picture& picture) OVERRIDE; |
394 // Simple state changes. | 241 // Simple state changes. |
395 virtual void NotifyEndOfBitstreamBuffer(int32 bitstream_buffer_id) OVERRIDE; | 242 virtual void NotifyEndOfBitstreamBuffer(int32 bitstream_buffer_id) OVERRIDE; |
396 virtual void NotifyFlushDone() OVERRIDE; | 243 virtual void NotifyFlushDone() OVERRIDE; |
397 virtual void NotifyResetDone() OVERRIDE; | 244 virtual void NotifyResetDone() OVERRIDE; |
398 virtual void NotifyError(VideoDecodeAccelerator::Error error) OVERRIDE; | 245 virtual void NotifyError(VideoDecodeAccelerator::Error error) OVERRIDE; |
399 | 246 |
| 247 // RenderingHelper::Client implementation. |
| 248 virtual void RenderContent(RenderingHelper*) OVERRIDE; |
| 249 |
400 void OutputFrameDeliveryTimes(base::File* output); | 250 void OutputFrameDeliveryTimes(base::File* output); |
401 | 251 |
402 void NotifyFrameDropped(int32 picture_buffer_id); | 252 void NotifyFrameDropped(int32 picture_buffer_id); |
403 | 253 |
404 // Simple getters for inspecting the state of the Client. | 254 // Simple getters for inspecting the state of the Client. |
405 int num_done_bitstream_buffers() { return num_done_bitstream_buffers_; } | 255 int num_done_bitstream_buffers() { return num_done_bitstream_buffers_; } |
406 int num_skipped_fragments() { return num_skipped_fragments_; } | 256 int num_skipped_fragments() { return num_skipped_fragments_; } |
407 int num_queued_fragments() { return num_queued_fragments_; } | 257 int num_queued_fragments() { return num_queued_fragments_; } |
408 int num_decoded_frames(); | 258 int num_decoded_frames() { return num_decoded_frames_; } |
409 double frames_per_second(); | 259 double frames_per_second(); |
410 // Return the median of the decode time of all decoded frames. | 260 // Return the median of the decode time of all decoded frames. |
411 base::TimeDelta decode_time_median(); | 261 base::TimeDelta decode_time_median(); |
412 bool decoder_deleted() { return !decoder_.get(); } | 262 bool decoder_deleted() { return !decoder_.get(); } |
413 | 263 |
414 private: | 264 private: |
415 typedef std::map<int, media::PictureBuffer*> PictureBufferById; | 265 typedef std::map<int, media::PictureBuffer*> PictureBufferById; |
416 | 266 |
417 void SetState(ClientState new_state); | 267 void SetState(ClientState new_state); |
418 void FinishInitialization(); | 268 void FinishInitialization(); |
| 269 void ReturnPicture(int32 picture_buffer_id); |
419 | 270 |
420 // Delete the associated decoder helper. | 271 // Delete the associated decoder helper. |
421 void DeleteDecoder(); | 272 void DeleteDecoder(); |
422 | 273 |
423 // Compute & return the first encoded bytes (including a start frame) to send | 274 // Compute & return the first encoded bytes (including a start frame) to send |
424 // to the decoder, starting at |start_pos| and returning one fragment. Skips | 275 // to the decoder, starting at |start_pos| and returning one fragment. Skips |
425 // to the first decodable position. | 276 // to the first decodable position. |
426 std::string GetBytesForFirstFragment(size_t start_pos, size_t* end_pos); | 277 std::string GetBytesForFirstFragment(size_t start_pos, size_t* end_pos); |
427 // Compute & return the encoded bytes of next fragment to send to the decoder | 278 // Compute & return the encoded bytes of next fragment to send to the decoder |
428 // (based on |start_pos|). | 279 // (based on |start_pos|). |
(...skipping 26 matching lines...) Expand all Loading... |
455 int num_queued_fragments_; | 306 int num_queued_fragments_; |
456 int num_decoded_frames_; | 307 int num_decoded_frames_; |
457 int num_done_bitstream_buffers_; | 308 int num_done_bitstream_buffers_; |
458 PictureBufferById picture_buffers_by_id_; | 309 PictureBufferById picture_buffers_by_id_; |
459 base::TimeTicks initialize_done_ticks_; | 310 base::TimeTicks initialize_done_ticks_; |
460 media::VideoCodecProfile profile_; | 311 media::VideoCodecProfile profile_; |
461 GLenum texture_target_; | 312 GLenum texture_target_; |
462 bool suppress_rendering_; | 313 bool suppress_rendering_; |
463 std::vector<base::TimeTicks> frame_delivery_times_; | 314 std::vector<base::TimeTicks> frame_delivery_times_; |
464 int delay_reuse_after_frame_num_; | 315 int delay_reuse_after_frame_num_; |
465 scoped_ptr<ThrottlingVDAClient> throttling_client_; | |
466 // A map from bitstream buffer id to the decode start time of the buffer. | 316 // A map from bitstream buffer id to the decode start time of the buffer. |
467 std::map<int, base::TimeTicks> decode_start_time_; | 317 std::map<int, base::TimeTicks> decode_start_time_; |
468 // The decode time of all decoded frames. | 318 // The decode time of all decoded frames. |
469 std::vector<base::TimeDelta> decode_time_; | 319 std::vector<base::TimeDelta> decode_time_; |
470 // The number of VDA::Decode calls per second. This is to simulate webrtc. | 320 // The number of VDA::Decode calls per second. This is to simulate webrtc. |
471 int decode_calls_per_second_; | 321 int decode_calls_per_second_; |
472 // The id of the picture which is being hold for displayed. | 322 bool render_as_thumbnails_; |
473 int on_hold_picture_buffer_id_; | 323 bool pending_picture_updated_; |
| 324 std::deque<int32> pending_picture_buffer_ids_; |
474 | 325 |
475 DISALLOW_IMPLICIT_CONSTRUCTORS(GLRenderingVDAClient); | 326 DISALLOW_IMPLICIT_CONSTRUCTORS(GLRenderingVDAClient); |
476 }; | 327 }; |
477 | 328 |
478 GLRenderingVDAClient::GLRenderingVDAClient( | 329 GLRenderingVDAClient::GLRenderingVDAClient( |
479 RenderingHelper* rendering_helper, | 330 RenderingHelper* rendering_helper, |
480 int rendering_window_id, | 331 int rendering_window_id, |
481 ClientStateNotification<ClientState>* note, | 332 ClientStateNotification<ClientState>* note, |
482 const std::string& encoded_data, | 333 const std::string& encoded_data, |
483 int num_in_flight_decodes, | 334 int num_in_flight_decodes, |
484 int num_play_throughs, | 335 int num_play_throughs, |
485 int reset_after_frame_num, | 336 int reset_after_frame_num, |
486 int delete_decoder_state, | 337 int delete_decoder_state, |
487 int frame_width, | 338 int frame_width, |
488 int frame_height, | 339 int frame_height, |
489 media::VideoCodecProfile profile, | 340 media::VideoCodecProfile profile, |
490 double rendering_fps, | |
491 bool suppress_rendering, | 341 bool suppress_rendering, |
492 int delay_reuse_after_frame_num, | 342 int delay_reuse_after_frame_num, |
493 int decode_calls_per_second) | 343 int decode_calls_per_second, |
| 344 bool render_as_thumbnails) |
494 : rendering_helper_(rendering_helper), | 345 : rendering_helper_(rendering_helper), |
495 rendering_window_id_(rendering_window_id), | 346 rendering_window_id_(rendering_window_id), |
496 encoded_data_(encoded_data), | 347 encoded_data_(encoded_data), |
497 num_in_flight_decodes_(num_in_flight_decodes), | 348 num_in_flight_decodes_(num_in_flight_decodes), |
498 outstanding_decodes_(0), | 349 outstanding_decodes_(0), |
499 encoded_data_next_pos_to_decode_(0), | 350 encoded_data_next_pos_to_decode_(0), |
500 next_bitstream_buffer_id_(0), | 351 next_bitstream_buffer_id_(0), |
501 note_(note), | 352 note_(note), |
502 remaining_play_throughs_(num_play_throughs), | 353 remaining_play_throughs_(num_play_throughs), |
503 reset_after_frame_num_(reset_after_frame_num), | 354 reset_after_frame_num_(reset_after_frame_num), |
504 delete_decoder_state_(delete_decoder_state), | 355 delete_decoder_state_(delete_decoder_state), |
505 state_(CS_CREATED), | 356 state_(CS_CREATED), |
506 num_skipped_fragments_(0), | 357 num_skipped_fragments_(0), |
507 num_queued_fragments_(0), | 358 num_queued_fragments_(0), |
508 num_decoded_frames_(0), | 359 num_decoded_frames_(0), |
509 num_done_bitstream_buffers_(0), | 360 num_done_bitstream_buffers_(0), |
510 texture_target_(0), | 361 texture_target_(0), |
511 suppress_rendering_(suppress_rendering), | 362 suppress_rendering_(suppress_rendering), |
512 delay_reuse_after_frame_num_(delay_reuse_after_frame_num), | 363 delay_reuse_after_frame_num_(delay_reuse_after_frame_num), |
513 decode_calls_per_second_(decode_calls_per_second), | 364 decode_calls_per_second_(decode_calls_per_second), |
514 on_hold_picture_buffer_id_(-1) { | 365 render_as_thumbnails_(render_as_thumbnails), |
| 366 pending_picture_updated_(true) { |
515 CHECK_GT(num_in_flight_decodes, 0); | 367 CHECK_GT(num_in_flight_decodes, 0); |
516 CHECK_GT(num_play_throughs, 0); | 368 CHECK_GT(num_play_throughs, 0); |
517 CHECK_GE(rendering_fps, 0); | |
518 // |num_in_flight_decodes_| is unsupported if |decode_calls_per_second_| > 0. | 369 // |num_in_flight_decodes_| is unsupported if |decode_calls_per_second_| > 0. |
519 if (decode_calls_per_second_ > 0) | 370 if (decode_calls_per_second_ > 0) |
520 CHECK_EQ(1, num_in_flight_decodes_); | 371 CHECK_EQ(1, num_in_flight_decodes_); |
521 | 372 |
522 // Default to H264 baseline if no profile provided. | 373 // Default to H264 baseline if no profile provided. |
523 profile_ = (profile != media::VIDEO_CODEC_PROFILE_UNKNOWN | 374 profile_ = (profile != media::VIDEO_CODEC_PROFILE_UNKNOWN |
524 ? profile | 375 ? profile |
525 : media::H264PROFILE_BASELINE); | 376 : media::H264PROFILE_BASELINE); |
526 | |
527 if (rendering_fps > 0) | |
528 throttling_client_.reset(new ThrottlingVDAClient( | |
529 this, | |
530 rendering_fps, | |
531 base::Bind(&GLRenderingVDAClient::NotifyFrameDropped, | |
532 base::Unretained(this)))); | |
533 } | 377 } |
534 | 378 |
535 GLRenderingVDAClient::~GLRenderingVDAClient() { | 379 GLRenderingVDAClient::~GLRenderingVDAClient() { |
536 DeleteDecoder(); // Clean up in case of expected error. | 380 DeleteDecoder(); // Clean up in case of expected error. |
537 CHECK(decoder_deleted()); | 381 CHECK(decoder_deleted()); |
538 STLDeleteValues(&picture_buffers_by_id_); | 382 STLDeleteValues(&picture_buffers_by_id_); |
539 SetState(CS_DESTROYED); | 383 SetState(CS_DESTROYED); |
540 } | 384 } |
541 | 385 |
542 static bool DoNothingReturnTrue() { return true; } | 386 static bool DoNothingReturnTrue() { return true; } |
543 | 387 |
544 void GLRenderingVDAClient::CreateAndStartDecoder() { | 388 void GLRenderingVDAClient::CreateAndStartDecoder() { |
545 CHECK(decoder_deleted()); | 389 CHECK(decoder_deleted()); |
546 CHECK(!decoder_.get()); | 390 CHECK(!decoder_.get()); |
547 | 391 |
548 VideoDecodeAccelerator::Client* client = this; | 392 VideoDecodeAccelerator::Client* client = this; |
549 base::WeakPtr<VideoDecodeAccelerator::Client> weak_client = AsWeakPtr(); | 393 base::WeakPtr<VideoDecodeAccelerator::Client> weak_client = AsWeakPtr(); |
550 if (throttling_client_) { | |
551 client = throttling_client_.get(); | |
552 weak_client = throttling_client_->AsWeakPtr(); | |
553 } | |
554 #if defined(OS_WIN) | 394 #if defined(OS_WIN) |
555 decoder_.reset( | 395 decoder_.reset( |
556 new DXVAVideoDecodeAccelerator(base::Bind(&DoNothingReturnTrue))); | 396 new DXVAVideoDecodeAccelerator(base::Bind(&DoNothingReturnTrue))); |
557 #elif defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) | 397 #elif defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) |
558 | 398 |
559 scoped_ptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder); | 399 scoped_ptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder); |
560 if (!device.get()) { | 400 if (!device.get()) { |
561 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); | 401 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); |
562 return; | 402 return; |
563 } | 403 } |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
614 void GLRenderingVDAClient::DismissPictureBuffer(int32 picture_buffer_id) { | 454 void GLRenderingVDAClient::DismissPictureBuffer(int32 picture_buffer_id) { |
615 PictureBufferById::iterator it = | 455 PictureBufferById::iterator it = |
616 picture_buffers_by_id_.find(picture_buffer_id); | 456 picture_buffers_by_id_.find(picture_buffer_id); |
617 CHECK(it != picture_buffers_by_id_.end()); | 457 CHECK(it != picture_buffers_by_id_.end()); |
618 CHECK_EQ(outstanding_texture_ids_.erase(it->second->texture_id()), 1U); | 458 CHECK_EQ(outstanding_texture_ids_.erase(it->second->texture_id()), 1U); |
619 rendering_helper_->DeleteTexture(it->second->texture_id()); | 459 rendering_helper_->DeleteTexture(it->second->texture_id()); |
620 delete it->second; | 460 delete it->second; |
621 picture_buffers_by_id_.erase(it); | 461 picture_buffers_by_id_.erase(it); |
622 } | 462 } |
623 | 463 |
| 464 void GLRenderingVDAClient::RenderContent(RenderingHelper*) { |
| 465 CHECK(!render_as_thumbnails_); |
| 466 |
| 467 // No decoded texture for rendering yet, just skip. |
| 468 if (pending_picture_buffer_ids_.size() == 0) |
| 469 return; |
| 470 |
| 471 int32 buffer_id = pending_picture_buffer_ids_.front(); |
| 472 media::PictureBuffer* picture_buffer = picture_buffers_by_id_[buffer_id]; |
| 473 |
| 474 CHECK(picture_buffer); |
| 475 if (!pending_picture_updated_) { |
| 476 // Frame dropped, just redraw the last texture. |
| 477 rendering_helper_->RenderTexture(texture_target_, |
| 478 picture_buffer->texture_id()); |
| 479 return; |
| 480 } |
| 481 |
| 482 base::TimeTicks now = base::TimeTicks::Now(); |
| 483 frame_delivery_times_.push_back(now); |
| 484 |
| 485 rendering_helper_->RenderTexture(texture_target_, |
| 486 picture_buffer->texture_id()); |
| 487 |
| 488 if (pending_picture_buffer_ids_.size() == 1) { |
| 489 pending_picture_updated_ = false; |
| 490 } else { |
| 491 pending_picture_buffer_ids_.pop_front(); |
| 492 ReturnPicture(buffer_id); |
| 493 } |
| 494 } |
| 495 |
624 void GLRenderingVDAClient::PictureReady(const media::Picture& picture) { | 496 void GLRenderingVDAClient::PictureReady(const media::Picture& picture) { |
625 // We shouldn't be getting pictures delivered after Reset has completed. | 497 // We shouldn't be getting pictures delivered after Reset has completed. |
626 CHECK_LT(state_, CS_RESET); | 498 CHECK_LT(state_, CS_RESET); |
627 | 499 |
628 if (decoder_deleted()) | 500 if (decoder_deleted()) |
629 return; | 501 return; |
630 | 502 |
631 base::TimeTicks now = base::TimeTicks::Now(); | 503 base::TimeTicks now = base::TimeTicks::Now(); |
632 frame_delivery_times_.push_back(now); | |
633 // Save the decode time of this picture. | 504 // Save the decode time of this picture. |
634 std::map<int, base::TimeTicks>::iterator it = | 505 std::map<int, base::TimeTicks>::iterator it = |
635 decode_start_time_.find(picture.bitstream_buffer_id()); | 506 decode_start_time_.find(picture.bitstream_buffer_id()); |
636 ASSERT_NE(decode_start_time_.end(), it); | 507 ASSERT_NE(decode_start_time_.end(), it); |
637 decode_time_.push_back(now - it->second); | 508 decode_time_.push_back(now - it->second); |
638 decode_start_time_.erase(it); | 509 decode_start_time_.erase(it); |
639 | 510 |
640 CHECK_LE(picture.bitstream_buffer_id(), next_bitstream_buffer_id_); | 511 CHECK_LE(picture.bitstream_buffer_id(), next_bitstream_buffer_id_); |
641 ++num_decoded_frames_; | 512 ++num_decoded_frames_; |
642 | 513 |
643 // Mid-stream reset applies only to the last play-through per constructor | 514 // Mid-stream reset applies only to the last play-through per constructor |
644 // comment. | 515 // comment. |
645 if (remaining_play_throughs_ == 1 && | 516 if (remaining_play_throughs_ == 1 && |
646 reset_after_frame_num_ == num_decoded_frames()) { | 517 reset_after_frame_num_ == num_decoded_frames_) { |
647 reset_after_frame_num_ = MID_STREAM_RESET; | 518 reset_after_frame_num_ = MID_STREAM_RESET; |
648 decoder_->Reset(); | 519 decoder_->Reset(); |
649 // Re-start decoding from the beginning of the stream to avoid needing to | 520 // Re-start decoding from the beginning of the stream to avoid needing to |
650 // know how to find I-frames and so on in this test. | 521 // know how to find I-frames and so on in this test. |
651 encoded_data_next_pos_to_decode_ = 0; | 522 encoded_data_next_pos_to_decode_ = 0; |
652 } | 523 } |
653 | 524 |
654 media::PictureBuffer* picture_buffer = | 525 if (render_as_thumbnails_) { |
655 picture_buffers_by_id_[picture.picture_buffer_id()]; | 526 frame_delivery_times_.push_back(now); |
656 CHECK(picture_buffer); | 527 media::PictureBuffer* picture_buffer = |
| 528 picture_buffers_by_id_[picture.picture_buffer_id()]; |
| 529 CHECK(picture_buffer); |
| 530 rendering_helper_->RenderThumbnail(texture_target_, |
| 531 picture_buffer->texture_id()); |
| 532 ReturnPicture(picture.picture_buffer_id()); |
| 533 } else if (!suppress_rendering_) { |
| 534 // Keep the picture for rendering. |
| 535 pending_picture_buffer_ids_.push_back(picture.picture_buffer_id()); |
| 536 if (pending_picture_buffer_ids_.size() > 1 && !pending_picture_updated_) { |
| 537 ReturnPicture(pending_picture_buffer_ids_.front()); |
| 538 pending_picture_buffer_ids_.pop_front(); |
| 539 pending_picture_updated_ = true; |
| 540 } |
| 541 } else { |
| 542 frame_delivery_times_.push_back(now); |
| 543 ReturnPicture(picture.picture_buffer_id()); |
| 544 } |
| 545 } |
657 | 546 |
658 int released_picture_buffer_id = picture.picture_buffer_id(); | 547 void GLRenderingVDAClient::ReturnPicture(int32 picture_buffer_id) { |
659 if (!suppress_rendering_) { | 548 if (decoder_deleted()) |
660 // Replace with the last holding picture buffer. | |
661 std::swap(released_picture_buffer_id, on_hold_picture_buffer_id_); | |
662 rendering_helper_->RenderTexture(texture_target_, | |
663 picture_buffer->texture_id()); | |
664 } | |
665 | |
666 if (released_picture_buffer_id < 0) | |
667 return; | 549 return; |
668 | 550 if (num_decoded_frames_ > delay_reuse_after_frame_num_) { |
669 if ((num_decoded_frames() > delay_reuse_after_frame_num_)) { | |
670 base::MessageLoop::current()->PostDelayedTask( | 551 base::MessageLoop::current()->PostDelayedTask( |
671 FROM_HERE, | 552 FROM_HERE, |
672 base::Bind(&VideoDecodeAccelerator::ReusePictureBuffer, | 553 base::Bind(&VideoDecodeAccelerator::ReusePictureBuffer, |
673 weak_decoder_factory_->GetWeakPtr(), | 554 weak_decoder_factory_->GetWeakPtr(), |
674 released_picture_buffer_id), | 555 picture_buffer_id), |
675 kReuseDelay); | 556 kReuseDelay); |
676 } else { | 557 } else { |
677 decoder_->ReusePictureBuffer(released_picture_buffer_id); | 558 decoder_->ReusePictureBuffer(picture_buffer_id); |
678 } | 559 } |
679 } | 560 } |
680 | 561 |
681 void GLRenderingVDAClient::NotifyEndOfBitstreamBuffer( | 562 void GLRenderingVDAClient::NotifyEndOfBitstreamBuffer( |
682 int32 bitstream_buffer_id) { | 563 int32 bitstream_buffer_id) { |
683 // TODO(fischman): this test currently relies on this notification to make | 564 // TODO(fischman): this test currently relies on this notification to make |
684 // forward progress during a Reset(). But the VDA::Reset() API doesn't | 565 // forward progress during a Reset(). But the VDA::Reset() API doesn't |
685 // guarantee this, so stop relying on it (and remove the notifications from | 566 // guarantee this, so stop relying on it (and remove the notifications from |
686 // VaapiVideoDecodeAccelerator::FinishReset()). | 567 // VaapiVideoDecodeAccelerator::FinishReset()). |
687 ++num_done_bitstream_buffers_; | 568 ++num_done_bitstream_buffers_; |
(...skipping 11 matching lines...) Expand all Loading... |
699 DCHECK_GE(remaining_play_throughs_, 0); | 580 DCHECK_GE(remaining_play_throughs_, 0); |
700 if (decoder_deleted()) | 581 if (decoder_deleted()) |
701 return; | 582 return; |
702 decoder_->Reset(); | 583 decoder_->Reset(); |
703 SetState(CS_RESETTING); | 584 SetState(CS_RESETTING); |
704 } | 585 } |
705 | 586 |
706 void GLRenderingVDAClient::NotifyResetDone() { | 587 void GLRenderingVDAClient::NotifyResetDone() { |
707 if (decoder_deleted()) | 588 if (decoder_deleted()) |
708 return; | 589 return; |
| 590 |
| 591 // Clear pending_pictures and reuse them. |
| 592 while (!pending_picture_buffer_ids_.empty()) { |
| 593 decoder_->ReusePictureBuffer(pending_picture_buffer_ids_.front()); |
| 594 pending_picture_buffer_ids_.pop_front(); |
| 595 } |
| 596 pending_picture_updated_ = true; |
| 597 |
709 if (reset_after_frame_num_ == MID_STREAM_RESET) { | 598 if (reset_after_frame_num_ == MID_STREAM_RESET) { |
710 reset_after_frame_num_ = END_OF_STREAM_RESET; | 599 reset_after_frame_num_ = END_OF_STREAM_RESET; |
711 DecodeNextFragment(); | 600 DecodeNextFragment(); |
712 return; | 601 return; |
713 } else if (reset_after_frame_num_ == START_OF_STREAM_RESET) { | 602 } else if (reset_after_frame_num_ == START_OF_STREAM_RESET) { |
714 reset_after_frame_num_ = END_OF_STREAM_RESET; | 603 reset_after_frame_num_ = END_OF_STREAM_RESET; |
715 for (int i = 0; i < num_in_flight_decodes_; ++i) | 604 for (int i = 0; i < num_in_flight_decodes_; ++i) |
716 DecodeNextFragment(); | 605 DecodeNextFragment(); |
717 return; | 606 return; |
718 } | 607 } |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
941 } | 830 } |
942 | 831 |
943 if (decode_calls_per_second_ > 0) { | 832 if (decode_calls_per_second_ > 0) { |
944 base::MessageLoop::current()->PostDelayedTask( | 833 base::MessageLoop::current()->PostDelayedTask( |
945 FROM_HERE, | 834 FROM_HERE, |
946 base::Bind(&GLRenderingVDAClient::DecodeNextFragment, AsWeakPtr()), | 835 base::Bind(&GLRenderingVDAClient::DecodeNextFragment, AsWeakPtr()), |
947 base::TimeDelta::FromSeconds(1) / decode_calls_per_second_); | 836 base::TimeDelta::FromSeconds(1) / decode_calls_per_second_); |
948 } | 837 } |
949 } | 838 } |
950 | 839 |
951 int GLRenderingVDAClient::num_decoded_frames() { | |
952 return throttling_client_ ? throttling_client_->num_decoded_frames() | |
953 : num_decoded_frames_; | |
954 } | |
955 | |
956 double GLRenderingVDAClient::frames_per_second() { | 840 double GLRenderingVDAClient::frames_per_second() { |
957 base::TimeDelta delta = frame_delivery_times_.back() - initialize_done_ticks_; | 841 base::TimeDelta delta = frame_delivery_times_.back() - initialize_done_ticks_; |
958 return num_decoded_frames() / delta.InSecondsF(); | 842 return num_decoded_frames_ / delta.InSecondsF(); |
959 } | 843 } |
960 | 844 |
961 base::TimeDelta GLRenderingVDAClient::decode_time_median() { | 845 base::TimeDelta GLRenderingVDAClient::decode_time_median() { |
962 if (decode_time_.size() == 0) | 846 if (decode_time_.size() == 0) |
963 return base::TimeDelta(); | 847 return base::TimeDelta(); |
964 std::sort(decode_time_.begin(), decode_time_.end()); | 848 std::sort(decode_time_.begin(), decode_time_.end()); |
965 int index = decode_time_.size() / 2; | 849 int index = decode_time_.size() / 2; |
966 if (decode_time_.size() % 2 != 0) | 850 if (decode_time_.size() % 2 != 0) |
967 return decode_time_[index]; | 851 return decode_time_[index]; |
968 | 852 |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1202 const size_t num_in_flight_decodes = GetParam().b; | 1086 const size_t num_in_flight_decodes = GetParam().b; |
1203 const int num_play_throughs = GetParam().c; | 1087 const int num_play_throughs = GetParam().c; |
1204 const int reset_point = GetParam().d; | 1088 const int reset_point = GetParam().d; |
1205 const int delete_decoder_state = GetParam().e; | 1089 const int delete_decoder_state = GetParam().e; |
1206 bool test_reuse_delay = GetParam().f; | 1090 bool test_reuse_delay = GetParam().f; |
1207 const bool render_as_thumbnails = GetParam().g; | 1091 const bool render_as_thumbnails = GetParam().g; |
1208 | 1092 |
1209 UpdateTestVideoFileParams( | 1093 UpdateTestVideoFileParams( |
1210 num_concurrent_decoders, reset_point, &test_video_files_); | 1094 num_concurrent_decoders, reset_point, &test_video_files_); |
1211 | 1095 |
1212 // Suppress GL rendering for all tests when the "--disable_rendering" is set. | 1096 // Suppress GL rendering for all tests when the "--rendering_fps" is 0. |
1213 const bool suppress_rendering = g_disable_rendering; | 1097 const bool suppress_rendering = g_rendering_fps == 0; |
1214 | 1098 |
1215 std::vector<ClientStateNotification<ClientState>*> | 1099 std::vector<ClientStateNotification<ClientState>*> |
1216 notes(num_concurrent_decoders, NULL); | 1100 notes(num_concurrent_decoders, NULL); |
1217 std::vector<GLRenderingVDAClient*> clients(num_concurrent_decoders, NULL); | 1101 std::vector<GLRenderingVDAClient*> clients(num_concurrent_decoders, NULL); |
1218 | 1102 |
1219 RenderingHelperParams helper_params; | 1103 RenderingHelperParams helper_params; |
| 1104 helper_params.rendering_fps = g_rendering_fps; |
1220 helper_params.num_windows = num_concurrent_decoders; | 1105 helper_params.num_windows = num_concurrent_decoders; |
1221 helper_params.render_as_thumbnails = render_as_thumbnails; | 1106 helper_params.render_as_thumbnails = render_as_thumbnails; |
1222 if (render_as_thumbnails) { | 1107 if (render_as_thumbnails) { |
1223 // Only one decoder is supported with thumbnail rendering | 1108 // Only one decoder is supported with thumbnail rendering |
1224 CHECK_EQ(num_concurrent_decoders, 1U); | 1109 CHECK_EQ(num_concurrent_decoders, 1U); |
1225 gfx::Size frame_size(test_video_files_[0]->width, | 1110 gfx::Size frame_size(test_video_files_[0]->width, |
1226 test_video_files_[0]->height); | 1111 test_video_files_[0]->height); |
1227 helper_params.frame_dimensions.push_back(frame_size); | 1112 helper_params.frame_dimensions.push_back(frame_size); |
1228 helper_params.window_dimensions.push_back(kThumbnailsDisplaySize); | 1113 helper_params.window_dimensions.push_back(kThumbnailsDisplaySize); |
1229 helper_params.thumbnails_page_size = kThumbnailsPageSize; | 1114 helper_params.thumbnails_page_size = kThumbnailsPageSize; |
1230 helper_params.thumbnail_size = kThumbnailSize; | 1115 helper_params.thumbnail_size = kThumbnailSize; |
1231 } else { | 1116 } else { |
1232 for (size_t index = 0; index < test_video_files_.size(); ++index) { | 1117 for (size_t index = 0; index < test_video_files_.size(); ++index) { |
1233 gfx::Size frame_size(test_video_files_[index]->width, | 1118 gfx::Size frame_size(test_video_files_[index]->width, |
1234 test_video_files_[index]->height); | 1119 test_video_files_[index]->height); |
1235 helper_params.frame_dimensions.push_back(frame_size); | 1120 helper_params.frame_dimensions.push_back(frame_size); |
1236 helper_params.window_dimensions.push_back(frame_size); | 1121 helper_params.window_dimensions.push_back(frame_size); |
1237 } | 1122 } |
1238 } | 1123 } |
1239 InitializeRenderingHelper(helper_params); | |
1240 | 1124 |
1241 // First kick off all the decoders. | 1125 // First kick off all the decoders. |
1242 for (size_t index = 0; index < num_concurrent_decoders; ++index) { | 1126 for (size_t index = 0; index < num_concurrent_decoders; ++index) { |
1243 TestVideoFile* video_file = | 1127 TestVideoFile* video_file = |
1244 test_video_files_[index % test_video_files_.size()]; | 1128 test_video_files_[index % test_video_files_.size()]; |
1245 ClientStateNotification<ClientState>* note = | 1129 ClientStateNotification<ClientState>* note = |
1246 new ClientStateNotification<ClientState>(); | 1130 new ClientStateNotification<ClientState>(); |
1247 notes[index] = note; | 1131 notes[index] = note; |
1248 | 1132 |
1249 int delay_after_frame_num = std::numeric_limits<int>::max(); | 1133 int delay_after_frame_num = std::numeric_limits<int>::max(); |
1250 if (test_reuse_delay && | 1134 if (test_reuse_delay && |
1251 kMaxFramesToDelayReuse * 2 < video_file->num_frames) { | 1135 kMaxFramesToDelayReuse * 2 < video_file->num_frames) { |
1252 delay_after_frame_num = video_file->num_frames - kMaxFramesToDelayReuse; | 1136 delay_after_frame_num = video_file->num_frames - kMaxFramesToDelayReuse; |
1253 } | 1137 } |
1254 | 1138 |
1255 GLRenderingVDAClient* client = | 1139 GLRenderingVDAClient* client = |
1256 new GLRenderingVDAClient(&rendering_helper_, | 1140 new GLRenderingVDAClient(&rendering_helper_, |
1257 index, | 1141 index, |
1258 note, | 1142 note, |
1259 video_file->data_str, | 1143 video_file->data_str, |
1260 num_in_flight_decodes, | 1144 num_in_flight_decodes, |
1261 num_play_throughs, | 1145 num_play_throughs, |
1262 video_file->reset_after_frame_num, | 1146 video_file->reset_after_frame_num, |
1263 delete_decoder_state, | 1147 delete_decoder_state, |
1264 video_file->width, | 1148 video_file->width, |
1265 video_file->height, | 1149 video_file->height, |
1266 video_file->profile, | 1150 video_file->profile, |
1267 g_rendering_fps, | |
1268 suppress_rendering, | 1151 suppress_rendering, |
1269 delay_after_frame_num, | 1152 delay_after_frame_num, |
1270 0); | 1153 0, |
| 1154 render_as_thumbnails); |
| 1155 |
1271 clients[index] = client; | 1156 clients[index] = client; |
| 1157 helper_params.clients.push_back(client->AsWeakPtr()); |
| 1158 } |
1272 | 1159 |
1273 CreateAndStartDecoder(client, note); | 1160 InitializeRenderingHelper(helper_params); |
| 1161 |
| 1162 for (size_t index = 0; index < num_concurrent_decoders; ++index) { |
| 1163 CreateAndStartDecoder(clients[index], notes[index]); |
1274 } | 1164 } |
| 1165 |
1275 // Then wait for all the decodes to finish. | 1166 // Then wait for all the decodes to finish. |
1276 // Only check performance & correctness later if we play through only once. | 1167 // Only check performance & correctness later if we play through only once. |
1277 bool skip_performance_and_correctness_checks = num_play_throughs > 1; | 1168 bool skip_performance_and_correctness_checks = num_play_throughs > 1; |
1278 for (size_t i = 0; i < num_concurrent_decoders; ++i) { | 1169 for (size_t i = 0; i < num_concurrent_decoders; ++i) { |
1279 ClientStateNotification<ClientState>* note = notes[i]; | 1170 ClientStateNotification<ClientState>* note = notes[i]; |
1280 ClientState state = note->Wait(); | 1171 ClientState state = note->Wait(); |
1281 if (state != CS_INITIALIZED) { | 1172 if (state != CS_INITIALIZED) { |
1282 skip_performance_and_correctness_checks = true; | 1173 skip_performance_and_correctness_checks = true; |
1283 // We expect initialization to fail only when more than the supported | 1174 // We expect initialization to fail only when more than the supported |
1284 // number of decoders is instantiated. Assert here that something else | 1175 // number of decoders is instantiated. Assert here that something else |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1481 // Thumbnailing test | 1372 // Thumbnailing test |
1482 INSTANTIATE_TEST_CASE_P( | 1373 INSTANTIATE_TEST_CASE_P( |
1483 Thumbnail, VideoDecodeAcceleratorParamTest, | 1374 Thumbnail, VideoDecodeAcceleratorParamTest, |
1484 ::testing::Values( | 1375 ::testing::Values( |
1485 MakeTuple(1, 1, 1, END_OF_STREAM_RESET, CS_RESET, false, true))); | 1376 MakeTuple(1, 1, 1, END_OF_STREAM_RESET, CS_RESET, false, true))); |
1486 | 1377 |
1487 // Measure the median of the decode time when VDA::Decode is called 30 times per | 1378 // Measure the median of the decode time when VDA::Decode is called 30 times per |
1488 // second. | 1379 // second. |
1489 TEST_F(VideoDecodeAcceleratorTest, TestDecodeTimeMedian) { | 1380 TEST_F(VideoDecodeAcceleratorTest, TestDecodeTimeMedian) { |
1490 RenderingHelperParams helper_params; | 1381 RenderingHelperParams helper_params; |
| 1382 |
| 1383 // Disable rendering by setting the rendering_fps = 0. |
| 1384 helper_params.rendering_fps = 0; |
1491 helper_params.num_windows = 1; | 1385 helper_params.num_windows = 1; |
1492 helper_params.render_as_thumbnails = false; | 1386 helper_params.render_as_thumbnails = false; |
1493 gfx::Size frame_size(test_video_files_[0]->width, | 1387 gfx::Size frame_size(test_video_files_[0]->width, |
1494 test_video_files_[0]->height); | 1388 test_video_files_[0]->height); |
1495 helper_params.frame_dimensions.push_back(frame_size); | 1389 helper_params.frame_dimensions.push_back(frame_size); |
1496 helper_params.window_dimensions.push_back(frame_size); | 1390 helper_params.window_dimensions.push_back(frame_size); |
1497 InitializeRenderingHelper(helper_params); | |
1498 | 1391 |
1499 ClientStateNotification<ClientState>* note = | 1392 ClientStateNotification<ClientState>* note = |
1500 new ClientStateNotification<ClientState>(); | 1393 new ClientStateNotification<ClientState>(); |
1501 GLRenderingVDAClient* client = | 1394 GLRenderingVDAClient* client = |
1502 new GLRenderingVDAClient(&rendering_helper_, | 1395 new GLRenderingVDAClient(&rendering_helper_, |
1503 0, | 1396 0, |
1504 note, | 1397 note, |
1505 test_video_files_[0]->data_str, | 1398 test_video_files_[0]->data_str, |
1506 1, | 1399 1, |
1507 1, | 1400 1, |
1508 test_video_files_[0]->reset_after_frame_num, | 1401 test_video_files_[0]->reset_after_frame_num, |
1509 CS_RESET, | 1402 CS_RESET, |
1510 test_video_files_[0]->width, | 1403 test_video_files_[0]->width, |
1511 test_video_files_[0]->height, | 1404 test_video_files_[0]->height, |
1512 test_video_files_[0]->profile, | 1405 test_video_files_[0]->profile, |
1513 g_rendering_fps, | |
1514 true, | 1406 true, |
1515 std::numeric_limits<int>::max(), | 1407 std::numeric_limits<int>::max(), |
1516 kWebRtcDecodeCallsPerSecond); | 1408 kWebRtcDecodeCallsPerSecond, |
| 1409 false /* render_as_thumbnail */); |
| 1410 helper_params.clients.push_back(client->AsWeakPtr()); |
| 1411 InitializeRenderingHelper(helper_params); |
1517 CreateAndStartDecoder(client, note); | 1412 CreateAndStartDecoder(client, note); |
1518 WaitUntilDecodeFinish(note); | 1413 WaitUntilDecodeFinish(note); |
1519 | 1414 |
1520 base::TimeDelta decode_time_median = client->decode_time_median(); | 1415 base::TimeDelta decode_time_median = client->decode_time_median(); |
1521 std::string output_string = | 1416 std::string output_string = |
1522 base::StringPrintf("Decode time median: %" PRId64 " us", | 1417 base::StringPrintf("Decode time median: %" PRId64 " us", |
1523 decode_time_median.InMicroseconds()); | 1418 decode_time_median.InMicroseconds()); |
1524 LOG(INFO) << output_string; | 1419 LOG(INFO) << output_string; |
1525 | 1420 |
1526 if (g_output_log != NULL) | 1421 if (g_output_log != NULL) |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1564 content::g_output_log = it->second.c_str(); | 1459 content::g_output_log = it->second.c_str(); |
1565 continue; | 1460 continue; |
1566 } | 1461 } |
1567 if (it->first == "rendering_fps") { | 1462 if (it->first == "rendering_fps") { |
1568 // On Windows, CommandLine::StringType is wstring. We need to convert | 1463 // On Windows, CommandLine::StringType is wstring. We need to convert |
1569 // it to std::string first | 1464 // it to std::string first |
1570 std::string input(it->second.begin(), it->second.end()); | 1465 std::string input(it->second.begin(), it->second.end()); |
1571 CHECK(base::StringToDouble(input, &content::g_rendering_fps)); | 1466 CHECK(base::StringToDouble(input, &content::g_rendering_fps)); |
1572 continue; | 1467 continue; |
1573 } | 1468 } |
| 1469 // TODO(owenlin): Remove this flag once it is not used in autotest. |
1574 if (it->first == "disable_rendering") { | 1470 if (it->first == "disable_rendering") { |
1575 content::g_disable_rendering = true; | 1471 content::g_rendering_fps = 0; |
1576 continue; | 1472 continue; |
1577 } | 1473 } |
1578 if (it->first == "v" || it->first == "vmodule") | 1474 if (it->first == "v" || it->first == "vmodule") |
1579 continue; | 1475 continue; |
1580 LOG(FATAL) << "Unexpected switch: " << it->first << ":" << it->second; | 1476 LOG(FATAL) << "Unexpected switch: " << it->first << ":" << it->second; |
1581 } | 1477 } |
1582 | 1478 |
1583 base::ShadowingAtExitManager at_exit_manager; | 1479 base::ShadowingAtExitManager at_exit_manager; |
1584 | 1480 |
1585 return RUN_ALL_TESTS(); | 1481 return RUN_ALL_TESTS(); |
1586 } | 1482 } |
OLD | NEW |