Chromium Code Reviews| 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 |
| 11 // to be written sequentially and wait for the decode client to see certain | 11 // to be written sequentially and wait for the decode client to see certain |
| 12 // state transitions. | 12 // state transitions. |
| 13 // - GLRenderingVDAClient is a VideoDecodeAccelerator::Client implementation | 13 // - GLRenderingVDAClient is a VideoDecodeAccelerator::Client implementation |
| 14 // - Finally actual TEST cases are at the bottom of this file, using the above | 14 // - Finally actual TEST cases are at the bottom of this file, using the above |
| 15 // infrastructure. | 15 // infrastructure. |
| 16 | 16 |
| 17 #include <fcntl.h> | 17 #include <fcntl.h> |
| 18 #include <sys/stat.h> | 18 #include <sys/stat.h> |
| 19 #include <sys/types.h> | 19 #include <sys/types.h> |
| 20 #include <deque> | 20 #include <deque> |
| 21 #include <map> | |
| 21 | 22 |
| 22 // Include gtest.h out of order because <X11/X.h> #define's Bool & None, which | 23 // Include gtest.h out of order because <X11/X.h> #define's Bool & None, which |
| 23 // gtest uses as struct names (inside a namespace). This means that | 24 // gtest uses as struct names (inside a namespace). This means that |
| 24 // #include'ing gtest after anything that pulls in X.h fails to compile. | 25 // #include'ing gtest after anything that pulls in X.h fails to compile. |
| 25 // This is http://code.google.com/p/googletest/issues/detail?id=371 | 26 // This is http://code.google.com/p/googletest/issues/detail?id=371 |
| 26 #include "testing/gtest/include/gtest/gtest.h" | 27 #include "testing/gtest/include/gtest/gtest.h" |
| 27 | 28 |
| 28 #include "base/at_exit.h" | 29 #include "base/at_exit.h" |
| 29 #include "base/bind.h" | 30 #include "base/bind.h" |
| 30 #include "base/command_line.h" | 31 #include "base/command_line.h" |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 82 // - |minFPSwithRender| and |minFPSnoRender| are minimum frames/second speeds | 83 // - |minFPSwithRender| and |minFPSnoRender| are minimum frames/second speeds |
| 83 // expected to be achieved with and without rendering to the screen, resp. | 84 // expected to be achieved with and without rendering to the screen, resp. |
| 84 // (the latter tests just decode speed). | 85 // (the latter tests just decode speed). |
| 85 // - |profile| is the media::VideoCodecProfile set during Initialization. | 86 // - |profile| is the media::VideoCodecProfile set during Initialization. |
| 86 // An empty value for a numeric field means "ignore". | 87 // An empty value for a numeric field means "ignore". |
| 87 const base::FilePath::CharType* g_test_video_data = | 88 const base::FilePath::CharType* g_test_video_data = |
| 88 // FILE_PATH_LITERAL("test-25fps.vp8:320:240:250:250:50:175:11"); | 89 // FILE_PATH_LITERAL("test-25fps.vp8:320:240:250:250:50:175:11"); |
| 89 FILE_PATH_LITERAL("test-25fps.h264:320:240:250:258:50:175:1"); | 90 FILE_PATH_LITERAL("test-25fps.h264:320:240:250:258:50:175:1"); |
| 90 | 91 |
| 91 // The path of the frame delivery time log. We can enable the log and specify | 92 // The path of the frame delivery time log. We can enable the log and specify |
| 92 // the filename by the "--frame_delivery_log" switch. | 93 // the filename by the "--frame_delivery_log" or "--output_log" switch. |
| 93 const base::FilePath::CharType* g_frame_delivery_log = NULL; | 94 const base::FilePath::CharType* g_output_log = NULL; |
| 94 | 95 |
| 95 // The value is set by the switch "--rendering_fps". | 96 // The value is set by the switch "--rendering_fps". |
| 96 double g_rendering_fps = 0; | 97 double g_rendering_fps = 0; |
| 97 | 98 |
| 98 // Disable rendering, the value is set by the switch "--disable_rendering". | 99 // Disable rendering, the value is set by the switch "--disable_rendering". |
| 99 bool g_disable_rendering = false; | 100 bool g_disable_rendering = false; |
| 100 | 101 |
| 101 // Magic constants for differentiating the reasons for NotifyResetDone being | 102 // Magic constants for differentiating the reasons for NotifyResetDone being |
| 102 // called. | 103 // called. |
| 103 enum ResetPoint { | 104 enum ResetPoint { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 136 }; | 137 }; |
| 137 | 138 |
| 138 // Presumed minimal display size. | 139 // Presumed minimal display size. |
| 139 // We subtract one pixel from the width because some ARM chromebooks do not | 140 // We subtract one pixel from the width because some ARM chromebooks do not |
| 140 // support two fullscreen app running at the same time. See crbug.com/270064. | 141 // support two fullscreen app running at the same time. See crbug.com/270064. |
| 141 const gfx::Size kThumbnailsDisplaySize(1366 - 1, 768); | 142 const gfx::Size kThumbnailsDisplaySize(1366 - 1, 768); |
| 142 const gfx::Size kThumbnailsPageSize(1600, 1200); | 143 const gfx::Size kThumbnailsPageSize(1600, 1200); |
| 143 const gfx::Size kThumbnailSize(160, 120); | 144 const gfx::Size kThumbnailSize(160, 120); |
| 144 const int kMD5StringLength = 32; | 145 const int kMD5StringLength = 32; |
| 145 | 146 |
| 146 // Parse |data| into its constituent parts, set the various output fields | |
| 147 // accordingly, and read in video stream. CHECK-fails on unexpected or | |
| 148 // missing required data. Unspecified optional fields are set to -1. | |
| 149 void ParseAndReadTestVideoData(base::FilePath::StringType data, | |
| 150 size_t num_concurrent_decoders, | |
| 151 int reset_point, | |
| 152 std::vector<TestVideoFile*>* test_video_files) { | |
| 153 std::vector<base::FilePath::StringType> entries; | |
| 154 base::SplitString(data, ';', &entries); | |
| 155 CHECK_GE(entries.size(), 1U) << data; | |
| 156 for (size_t index = 0; index < entries.size(); ++index) { | |
| 157 std::vector<base::FilePath::StringType> fields; | |
| 158 base::SplitString(entries[index], ':', &fields); | |
| 159 CHECK_GE(fields.size(), 1U) << entries[index]; | |
| 160 CHECK_LE(fields.size(), 8U) << entries[index]; | |
| 161 TestVideoFile* video_file = new TestVideoFile(fields[0]); | |
| 162 if (!fields[1].empty()) | |
| 163 CHECK(base::StringToInt(fields[1], &video_file->width)); | |
| 164 if (!fields[2].empty()) | |
| 165 CHECK(base::StringToInt(fields[2], &video_file->height)); | |
| 166 if (!fields[3].empty()) { | |
| 167 CHECK(base::StringToInt(fields[3], &video_file->num_frames)); | |
| 168 // If we reset mid-stream and start playback over, account for frames | |
| 169 // that are decoded twice in our expectations. | |
| 170 if (video_file->num_frames > 0 && reset_point == MID_STREAM_RESET) { | |
| 171 // Reset should not go beyond the last frame; reset after the first | |
| 172 // frame for short videos. | |
| 173 video_file->reset_after_frame_num = kMaxResetAfterFrameNum; | |
| 174 if (video_file->num_frames <= kMaxResetAfterFrameNum) | |
| 175 video_file->reset_after_frame_num = 1; | |
| 176 video_file->num_frames += video_file->reset_after_frame_num; | |
| 177 } else { | |
| 178 video_file->reset_after_frame_num = reset_point; | |
| 179 } | |
| 180 } | |
| 181 if (!fields[4].empty()) | |
| 182 CHECK(base::StringToInt(fields[4], &video_file->num_fragments)); | |
| 183 if (!fields[5].empty()) { | |
| 184 CHECK(base::StringToInt(fields[5], &video_file->min_fps_render)); | |
| 185 video_file->min_fps_render /= num_concurrent_decoders; | |
| 186 } | |
| 187 if (!fields[6].empty()) { | |
| 188 CHECK(base::StringToInt(fields[6], &video_file->min_fps_no_render)); | |
| 189 video_file->min_fps_no_render /= num_concurrent_decoders; | |
| 190 } | |
| 191 if (!fields[7].empty()) | |
| 192 CHECK(base::StringToInt(fields[7], &video_file->profile)); | |
| 193 | |
| 194 // Read in the video data. | |
| 195 base::FilePath filepath(video_file->file_name); | |
| 196 CHECK(base::ReadFileToString(filepath, &video_file->data_str)) | |
| 197 << "test_video_file: " << filepath.MaybeAsASCII(); | |
| 198 | |
| 199 test_video_files->push_back(video_file); | |
| 200 } | |
| 201 } | |
| 202 | |
| 203 // Read in golden MD5s for the thumbnailed rendering of this video | 147 // Read in golden MD5s for the thumbnailed rendering of this video |
| 204 void ReadGoldenThumbnailMD5s(const TestVideoFile* video_file, | 148 void ReadGoldenThumbnailMD5s(const TestVideoFile* video_file, |
| 205 std::vector<std::string>* md5_strings) { | 149 std::vector<std::string>* md5_strings) { |
| 206 base::FilePath filepath(video_file->file_name); | 150 base::FilePath filepath(video_file->file_name); |
| 207 filepath = filepath.AddExtension(FILE_PATH_LITERAL(".md5")); | 151 filepath = filepath.AddExtension(FILE_PATH_LITERAL(".md5")); |
| 208 std::string all_md5s; | 152 std::string all_md5s; |
| 209 base::ReadFileToString(filepath, &all_md5s); | 153 base::ReadFileToString(filepath, &all_md5s); |
| 210 base::SplitString(all_md5s, '\n', md5_strings); | 154 base::SplitString(all_md5s, '\n', md5_strings); |
| 211 // Check these are legitimate MD5s. | 155 // Check these are legitimate MD5s. |
| 212 for (std::vector<std::string>::iterator md5_string = md5_strings->begin(); | 156 for (std::vector<std::string>::iterator md5_string = md5_strings->begin(); |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 406 // |delete_decoder_state| indicates when the underlying decoder should be | 350 // |delete_decoder_state| indicates when the underlying decoder should be |
| 407 // Destroy()'d and deleted and can take values: N<0: delete after -N Decode() | 351 // Destroy()'d and deleted and can take values: N<0: delete after -N Decode() |
| 408 // calls have been made, N>=0 means interpret as ClientState. | 352 // calls have been made, N>=0 means interpret as ClientState. |
| 409 // Both |reset_after_frame_num| & |delete_decoder_state| apply only to the | 353 // Both |reset_after_frame_num| & |delete_decoder_state| apply only to the |
| 410 // last play-through (governed by |num_play_throughs|). | 354 // last play-through (governed by |num_play_throughs|). |
| 411 // |rendering_fps| indicates the target rendering fps. 0 means no target fps | 355 // |rendering_fps| indicates the target rendering fps. 0 means no target fps |
| 412 // and it would render as fast as possible. | 356 // and it would render as fast as possible. |
| 413 // |suppress_rendering| indicates GL rendering is suppressed or not. | 357 // |suppress_rendering| indicates GL rendering is suppressed or not. |
| 414 // After |delay_reuse_after_frame_num| frame has been delivered, the client | 358 // After |delay_reuse_after_frame_num| frame has been delivered, the client |
| 415 // will start delaying the call to ReusePictureBuffer() for kReuseDelay. | 359 // will start delaying the call to ReusePictureBuffer() for kReuseDelay. |
| 360 // |decode_fps| is the number of VDA::Decode calls per second. | |
| 416 GLRenderingVDAClient(RenderingHelper* rendering_helper, | 361 GLRenderingVDAClient(RenderingHelper* rendering_helper, |
| 417 int rendering_window_id, | 362 int rendering_window_id, |
| 418 ClientStateNotification<ClientState>* note, | 363 ClientStateNotification<ClientState>* note, |
| 419 const std::string& encoded_data, | 364 const std::string& encoded_data, |
| 420 int num_in_flight_decodes, | 365 int num_in_flight_decodes, |
| 421 int num_play_throughs, | 366 int num_play_throughs, |
| 422 int reset_after_frame_num, | 367 int reset_after_frame_num, |
| 423 int delete_decoder_state, | 368 int delete_decoder_state, |
| 424 int frame_width, | 369 int frame_width, |
| 425 int frame_height, | 370 int frame_height, |
| 426 int profile, | 371 int profile, |
| 427 double rendering_fps, | 372 double rendering_fps, |
| 428 bool suppress_rendering, | 373 bool suppress_rendering, |
| 429 int delay_reuse_after_frame_num); | 374 int delay_reuse_after_frame_num, |
| 375 int decode_fps); | |
| 430 virtual ~GLRenderingVDAClient(); | 376 virtual ~GLRenderingVDAClient(); |
| 431 void CreateDecoder(); | 377 void CreateAndStartDecoder(); |
| 432 | 378 |
| 433 // VideoDecodeAccelerator::Client implementation. | 379 // VideoDecodeAccelerator::Client implementation. |
| 434 // The heart of the Client. | 380 // The heart of the Client. |
| 435 virtual void ProvidePictureBuffers(uint32 requested_num_of_buffers, | 381 virtual void ProvidePictureBuffers(uint32 requested_num_of_buffers, |
| 436 const gfx::Size& dimensions, | 382 const gfx::Size& dimensions, |
| 437 uint32 texture_target) OVERRIDE; | 383 uint32 texture_target) OVERRIDE; |
| 438 virtual void DismissPictureBuffer(int32 picture_buffer_id) OVERRIDE; | 384 virtual void DismissPictureBuffer(int32 picture_buffer_id) OVERRIDE; |
| 439 virtual void PictureReady(const media::Picture& picture) OVERRIDE; | 385 virtual void PictureReady(const media::Picture& picture) OVERRIDE; |
| 440 // Simple state changes. | 386 // Simple state changes. |
| 441 virtual void NotifyInitializeDone() OVERRIDE; | 387 virtual void NotifyInitializeDone() OVERRIDE; |
| 442 virtual void NotifyEndOfBitstreamBuffer(int32 bitstream_buffer_id) OVERRIDE; | 388 virtual void NotifyEndOfBitstreamBuffer(int32 bitstream_buffer_id) OVERRIDE; |
| 443 virtual void NotifyFlushDone() OVERRIDE; | 389 virtual void NotifyFlushDone() OVERRIDE; |
| 444 virtual void NotifyResetDone() OVERRIDE; | 390 virtual void NotifyResetDone() OVERRIDE; |
| 445 virtual void NotifyError(VideoDecodeAccelerator::Error error) OVERRIDE; | 391 virtual void NotifyError(VideoDecodeAccelerator::Error error) OVERRIDE; |
| 446 | 392 |
| 447 void OutputFrameDeliveryTimes(base::PlatformFile output); | 393 void OutputFrameDeliveryTimes(base::PlatformFile output); |
| 448 | 394 |
| 449 void NotifyFrameDropped(int32 picture_buffer_id); | 395 void NotifyFrameDropped(int32 picture_buffer_id); |
| 450 | 396 |
| 451 // Simple getters for inspecting the state of the Client. | 397 // Simple getters for inspecting the state of the Client. |
| 452 int num_done_bitstream_buffers() { return num_done_bitstream_buffers_; } | 398 int num_done_bitstream_buffers() { return num_done_bitstream_buffers_; } |
| 453 int num_skipped_fragments() { return num_skipped_fragments_; } | 399 int num_skipped_fragments() { return num_skipped_fragments_; } |
| 454 int num_queued_fragments() { return num_queued_fragments_; } | 400 int num_queued_fragments() { return num_queued_fragments_; } |
| 455 int num_decoded_frames(); | 401 int num_decoded_frames(); |
| 456 double frames_per_second(); | 402 double frames_per_second(); |
| 403 // Returns the average decode time in milli-seconds. | |
| 404 int avg_decode_time(); | |
| 457 bool decoder_deleted() { return !decoder_.get(); } | 405 bool decoder_deleted() { return !decoder_.get(); } |
| 458 | 406 |
| 459 private: | 407 private: |
| 460 typedef std::map<int, media::PictureBuffer*> PictureBufferById; | 408 typedef std::map<int, media::PictureBuffer*> PictureBufferById; |
| 461 | 409 |
| 462 void SetState(ClientState new_state); | 410 void SetState(ClientState new_state); |
| 463 | 411 |
| 464 // Delete the associated decoder helper. | 412 // Delete the associated decoder helper. |
| 465 void DeleteDecoder(); | 413 void DeleteDecoder(); |
| 466 | 414 |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 497 int num_queued_fragments_; | 445 int num_queued_fragments_; |
| 498 int num_decoded_frames_; | 446 int num_decoded_frames_; |
| 499 int num_done_bitstream_buffers_; | 447 int num_done_bitstream_buffers_; |
| 500 PictureBufferById picture_buffers_by_id_; | 448 PictureBufferById picture_buffers_by_id_; |
| 501 base::TimeTicks initialize_done_ticks_; | 449 base::TimeTicks initialize_done_ticks_; |
| 502 int profile_; | 450 int profile_; |
| 503 bool suppress_rendering_; | 451 bool suppress_rendering_; |
| 504 std::vector<base::TimeTicks> frame_delivery_times_; | 452 std::vector<base::TimeTicks> frame_delivery_times_; |
| 505 int delay_reuse_after_frame_num_; | 453 int delay_reuse_after_frame_num_; |
| 506 scoped_ptr<ThrottlingVDAClient> throttling_client_; | 454 scoped_ptr<ThrottlingVDAClient> throttling_client_; |
| 455 // A map from bitstream buffer id to the decode start time of the buffer. | |
| 456 std::map<int, base::TimeTicks> decode_start_time_; | |
| 457 // The sum of the decode time of all decoded frames in microseconds. | |
| 458 int64 total_decode_time_; | |
| 459 // The number of VDA::Decode calls per second. This is to simulate webrtc. | |
| 460 int decode_fps_; | |
| 507 | 461 |
| 508 DISALLOW_IMPLICIT_CONSTRUCTORS(GLRenderingVDAClient); | 462 DISALLOW_IMPLICIT_CONSTRUCTORS(GLRenderingVDAClient); |
| 509 }; | 463 }; |
| 510 | 464 |
| 511 GLRenderingVDAClient::GLRenderingVDAClient( | 465 GLRenderingVDAClient::GLRenderingVDAClient( |
| 512 RenderingHelper* rendering_helper, | 466 RenderingHelper* rendering_helper, |
| 513 int rendering_window_id, | 467 int rendering_window_id, |
| 514 ClientStateNotification<ClientState>* note, | 468 ClientStateNotification<ClientState>* note, |
| 515 const std::string& encoded_data, | 469 const std::string& encoded_data, |
| 516 int num_in_flight_decodes, | 470 int num_in_flight_decodes, |
| 517 int num_play_throughs, | 471 int num_play_throughs, |
| 518 int reset_after_frame_num, | 472 int reset_after_frame_num, |
| 519 int delete_decoder_state, | 473 int delete_decoder_state, |
| 520 int frame_width, | 474 int frame_width, |
| 521 int frame_height, | 475 int frame_height, |
| 522 int profile, | 476 int profile, |
| 523 double rendering_fps, | 477 double rendering_fps, |
| 524 bool suppress_rendering, | 478 bool suppress_rendering, |
| 525 int delay_reuse_after_frame_num) | 479 int delay_reuse_after_frame_num, |
| 480 int decode_fps) | |
| 526 : rendering_helper_(rendering_helper), | 481 : rendering_helper_(rendering_helper), |
| 527 rendering_window_id_(rendering_window_id), | 482 rendering_window_id_(rendering_window_id), |
| 528 encoded_data_(encoded_data), | 483 encoded_data_(encoded_data), |
| 529 num_in_flight_decodes_(num_in_flight_decodes), | 484 num_in_flight_decodes_(num_in_flight_decodes), |
| 530 outstanding_decodes_(0), | 485 outstanding_decodes_(0), |
| 531 encoded_data_next_pos_to_decode_(0), | 486 encoded_data_next_pos_to_decode_(0), |
| 532 next_bitstream_buffer_id_(0), | 487 next_bitstream_buffer_id_(0), |
| 533 note_(note), | 488 note_(note), |
| 534 remaining_play_throughs_(num_play_throughs), | 489 remaining_play_throughs_(num_play_throughs), |
| 535 reset_after_frame_num_(reset_after_frame_num), | 490 reset_after_frame_num_(reset_after_frame_num), |
| 536 delete_decoder_state_(delete_decoder_state), | 491 delete_decoder_state_(delete_decoder_state), |
| 537 state_(CS_CREATED), | 492 state_(CS_CREATED), |
| 538 num_skipped_fragments_(0), | 493 num_skipped_fragments_(0), |
| 539 num_queued_fragments_(0), | 494 num_queued_fragments_(0), |
| 540 num_decoded_frames_(0), | 495 num_decoded_frames_(0), |
| 541 num_done_bitstream_buffers_(0), | 496 num_done_bitstream_buffers_(0), |
| 542 profile_(profile), | 497 profile_(profile), |
| 543 suppress_rendering_(suppress_rendering), | 498 suppress_rendering_(suppress_rendering), |
| 544 delay_reuse_after_frame_num_(delay_reuse_after_frame_num) { | 499 delay_reuse_after_frame_num_(delay_reuse_after_frame_num), |
| 500 total_decode_time_(0), | |
| 501 decode_fps_(decode_fps) { | |
| 545 CHECK_GT(num_in_flight_decodes, 0); | 502 CHECK_GT(num_in_flight_decodes, 0); |
| 546 CHECK_GT(num_play_throughs, 0); | 503 CHECK_GT(num_play_throughs, 0); |
| 547 CHECK_GE(rendering_fps, 0); | 504 CHECK_GE(rendering_fps, 0); |
| 505 // |num_in_flight_decodes_| is not supported when decode fps > 0. | |
| 506 if (decode_fps_ > 0) | |
| 507 CHECK_EQ(1, num_in_flight_decodes_); | |
| 548 if (rendering_fps > 0) | 508 if (rendering_fps > 0) |
| 549 throttling_client_.reset(new ThrottlingVDAClient( | 509 throttling_client_.reset(new ThrottlingVDAClient( |
| 550 this, | 510 this, |
| 551 rendering_fps, | 511 rendering_fps, |
| 552 base::Bind(&GLRenderingVDAClient::NotifyFrameDropped, | 512 base::Bind(&GLRenderingVDAClient::NotifyFrameDropped, |
| 553 base::Unretained(this)))); | 513 base::Unretained(this)))); |
| 554 } | 514 } |
| 555 | 515 |
| 556 GLRenderingVDAClient::~GLRenderingVDAClient() { | 516 GLRenderingVDAClient::~GLRenderingVDAClient() { |
| 557 DeleteDecoder(); // Clean up in case of expected error. | 517 DeleteDecoder(); // Clean up in case of expected error. |
| 558 CHECK(decoder_deleted()); | 518 CHECK(decoder_deleted()); |
| 559 STLDeleteValues(&picture_buffers_by_id_); | 519 STLDeleteValues(&picture_buffers_by_id_); |
| 560 SetState(CS_DESTROYED); | 520 SetState(CS_DESTROYED); |
| 561 } | 521 } |
| 562 | 522 |
| 563 static bool DoNothingReturnTrue() { return true; } | 523 static bool DoNothingReturnTrue() { return true; } |
| 564 | 524 |
| 565 void GLRenderingVDAClient::CreateDecoder() { | 525 void GLRenderingVDAClient::CreateAndStartDecoder() { |
| 566 CHECK(decoder_deleted()); | 526 CHECK(decoder_deleted()); |
| 567 CHECK(!decoder_.get()); | 527 CHECK(!decoder_.get()); |
| 568 | 528 |
| 569 VideoDecodeAccelerator::Client* client = this; | 529 VideoDecodeAccelerator::Client* client = this; |
| 570 base::WeakPtr<VideoDecodeAccelerator::Client> weak_client = AsWeakPtr(); | 530 base::WeakPtr<VideoDecodeAccelerator::Client> weak_client = AsWeakPtr(); |
| 571 if (throttling_client_) { | 531 if (throttling_client_) { |
| 572 client = throttling_client_.get(); | 532 client = throttling_client_.get(); |
| 573 weak_client = throttling_client_->AsWeakPtr(); | 533 weak_client = throttling_client_->AsWeakPtr(); |
| 574 } | 534 } |
| 575 #if defined(OS_WIN) | 535 #if defined(OS_WIN) |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 638 picture_buffers_by_id_.erase(it); | 598 picture_buffers_by_id_.erase(it); |
| 639 } | 599 } |
| 640 | 600 |
| 641 void GLRenderingVDAClient::PictureReady(const media::Picture& picture) { | 601 void GLRenderingVDAClient::PictureReady(const media::Picture& picture) { |
| 642 // We shouldn't be getting pictures delivered after Reset has completed. | 602 // We shouldn't be getting pictures delivered after Reset has completed. |
| 643 CHECK_LT(state_, CS_RESET); | 603 CHECK_LT(state_, CS_RESET); |
| 644 | 604 |
| 645 if (decoder_deleted()) | 605 if (decoder_deleted()) |
| 646 return; | 606 return; |
| 647 | 607 |
| 648 frame_delivery_times_.push_back(base::TimeTicks::Now()); | 608 base::TimeTicks now = base::TimeTicks::Now(); |
| 609 frame_delivery_times_.push_back(now); | |
| 610 // Add the decode time of this buffer. | |
| 611 std::map<int, base::TimeTicks>::iterator it; | |
| 612 it = decode_start_time_.find(picture.bitstream_buffer_id()); | |
|
Owen Lin
2013/11/04 10:20:04
merge these two lines ?
wuchengli
2013/11/04 10:44:29
Done.
| |
| 613 ASSERT_NE(decode_start_time_.end(), it); | |
| 614 total_decode_time_ += (now - it->second).InMicroseconds(); | |
| 615 decode_start_time_.erase(it); | |
| 649 | 616 |
| 650 CHECK_LE(picture.bitstream_buffer_id(), next_bitstream_buffer_id_); | 617 CHECK_LE(picture.bitstream_buffer_id(), next_bitstream_buffer_id_); |
| 651 ++num_decoded_frames_; | 618 ++num_decoded_frames_; |
| 652 | 619 |
| 653 // Mid-stream reset applies only to the last play-through per constructor | 620 // Mid-stream reset applies only to the last play-through per constructor |
| 654 // comment. | 621 // comment. |
| 655 if (remaining_play_throughs_ == 1 && | 622 if (remaining_play_throughs_ == 1 && |
| 656 reset_after_frame_num_ == num_decoded_frames()) { | 623 reset_after_frame_num_ == num_decoded_frames()) { |
| 657 reset_after_frame_num_ = MID_STREAM_RESET; | 624 reset_after_frame_num_ = MID_STREAM_RESET; |
| 658 decoder_->Reset(); | 625 decoder_->Reset(); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 695 } | 662 } |
| 696 | 663 |
| 697 void GLRenderingVDAClient::NotifyEndOfBitstreamBuffer( | 664 void GLRenderingVDAClient::NotifyEndOfBitstreamBuffer( |
| 698 int32 bitstream_buffer_id) { | 665 int32 bitstream_buffer_id) { |
| 699 // TODO(fischman): this test currently relies on this notification to make | 666 // TODO(fischman): this test currently relies on this notification to make |
| 700 // forward progress during a Reset(). But the VDA::Reset() API doesn't | 667 // forward progress during a Reset(). But the VDA::Reset() API doesn't |
| 701 // guarantee this, so stop relying on it (and remove the notifications from | 668 // guarantee this, so stop relying on it (and remove the notifications from |
| 702 // VaapiVideoDecodeAccelerator::FinishReset()). | 669 // VaapiVideoDecodeAccelerator::FinishReset()). |
| 703 ++num_done_bitstream_buffers_; | 670 ++num_done_bitstream_buffers_; |
| 704 --outstanding_decodes_; | 671 --outstanding_decodes_; |
| 705 DecodeNextFragment(); | 672 if (decode_fps_ == 0) |
| 673 DecodeNextFragment(); | |
| 706 } | 674 } |
| 707 | 675 |
| 708 void GLRenderingVDAClient::NotifyFlushDone() { | 676 void GLRenderingVDAClient::NotifyFlushDone() { |
| 709 if (decoder_deleted()) | 677 if (decoder_deleted()) |
| 710 return; | 678 return; |
| 711 SetState(CS_FLUSHED); | 679 SetState(CS_FLUSHED); |
| 712 --remaining_play_throughs_; | 680 --remaining_play_throughs_; |
| 713 DCHECK_GE(remaining_play_throughs_, 0); | 681 DCHECK_GE(remaining_play_throughs_, 0); |
| 714 if (decoder_deleted()) | 682 if (decoder_deleted()) |
| 715 return; | 683 return; |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 877 | 845 |
| 878 // Populate the shared memory buffer w/ the fragment, duplicate its handle, | 846 // Populate the shared memory buffer w/ the fragment, duplicate its handle, |
| 879 // and hand it off to the decoder. | 847 // and hand it off to the decoder. |
| 880 base::SharedMemory shm; | 848 base::SharedMemory shm; |
| 881 CHECK(shm.CreateAndMapAnonymous(next_fragment_size)); | 849 CHECK(shm.CreateAndMapAnonymous(next_fragment_size)); |
| 882 memcpy(shm.memory(), next_fragment_bytes.data(), next_fragment_size); | 850 memcpy(shm.memory(), next_fragment_bytes.data(), next_fragment_size); |
| 883 base::SharedMemoryHandle dup_handle; | 851 base::SharedMemoryHandle dup_handle; |
| 884 CHECK(shm.ShareToProcess(base::Process::Current().handle(), &dup_handle)); | 852 CHECK(shm.ShareToProcess(base::Process::Current().handle(), &dup_handle)); |
| 885 media::BitstreamBuffer bitstream_buffer( | 853 media::BitstreamBuffer bitstream_buffer( |
| 886 next_bitstream_buffer_id_, dup_handle, next_fragment_size); | 854 next_bitstream_buffer_id_, dup_handle, next_fragment_size); |
| 855 decode_start_time_[next_bitstream_buffer_id_] = base::TimeTicks::Now(); | |
| 887 // Mask against 30 bits, to avoid (undefined) wraparound on signed integer. | 856 // Mask against 30 bits, to avoid (undefined) wraparound on signed integer. |
| 888 next_bitstream_buffer_id_ = (next_bitstream_buffer_id_ + 1) & 0x3FFFFFFF; | 857 next_bitstream_buffer_id_ = (next_bitstream_buffer_id_ + 1) & 0x3FFFFFFF; |
| 889 decoder_->Decode(bitstream_buffer); | 858 decoder_->Decode(bitstream_buffer); |
| 890 ++outstanding_decodes_; | 859 ++outstanding_decodes_; |
| 891 encoded_data_next_pos_to_decode_ = end_pos; | 860 encoded_data_next_pos_to_decode_ = end_pos; |
| 892 | 861 |
| 893 if (!remaining_play_throughs_ && | 862 if (!remaining_play_throughs_ && |
| 894 -delete_decoder_state_ == next_bitstream_buffer_id_) { | 863 -delete_decoder_state_ == next_bitstream_buffer_id_) { |
| 895 DeleteDecoder(); | 864 DeleteDecoder(); |
| 896 } | 865 } |
| 866 | |
| 867 if (decode_fps_ > 0) { | |
| 868 base::MessageLoop::current()->PostDelayedTask( | |
| 869 FROM_HERE, | |
| 870 base::Bind(&GLRenderingVDAClient::DecodeNextFragment, AsWeakPtr()), | |
| 871 base::TimeDelta::FromMilliseconds(1000 / decode_fps_)); | |
|
Owen Lin
2013/11/04 10:20:04
base::TimeDelta::FromSeconds(1) / decode_fps_
wuchengli
2013/11/04 10:44:29
Done.
| |
| 872 } | |
| 897 } | 873 } |
| 898 | 874 |
| 899 int GLRenderingVDAClient::num_decoded_frames() { | 875 int GLRenderingVDAClient::num_decoded_frames() { |
| 900 return throttling_client_ ? throttling_client_->num_decoded_frames() | 876 return throttling_client_ ? throttling_client_->num_decoded_frames() |
| 901 : num_decoded_frames_; | 877 : num_decoded_frames_; |
| 902 } | 878 } |
| 903 | 879 |
| 904 double GLRenderingVDAClient::frames_per_second() { | 880 double GLRenderingVDAClient::frames_per_second() { |
| 905 base::TimeDelta delta = frame_delivery_times_.back() - initialize_done_ticks_; | 881 base::TimeDelta delta = frame_delivery_times_.back() - initialize_done_ticks_; |
| 906 if (delta.InSecondsF() == 0) | 882 if (delta.InSecondsF() == 0) |
| 907 return 0; | 883 return 0; |
| 908 return num_decoded_frames() / delta.InSecondsF(); | 884 return num_decoded_frames() / delta.InSecondsF(); |
| 909 } | 885 } |
| 910 | 886 |
| 887 int GLRenderingVDAClient::avg_decode_time() { | |
| 888 if (num_decoded_frames() == 0) | |
| 889 return 0; | |
| 890 return total_decode_time_ / num_decoded_frames() / 1000; | |
|
Owen Lin
2013/11/04 10:20:04
Why 1000 ?
May be you should use TimeTicks for "
wuchengli
2013/11/04 10:44:29
Done. Changed to |decode_start_time_| vector.
| |
| 891 } | |
| 892 | |
| 893 class VideoDecodeAcceleratorTest : public ::testing::Test { | |
| 894 protected: | |
| 895 VideoDecodeAcceleratorTest(); | |
| 896 virtual void SetUp(); | |
| 897 virtual void TearDown(); | |
| 898 | |
| 899 // Parse |data| into its constituent parts, set the various output fields | |
| 900 // accordingly, and read in video stream. CHECK-fails on unexpected or | |
| 901 // missing required data. Unspecified optional fields are set to -1. | |
| 902 void ParseAndReadTestVideoData(base::FilePath::StringType data, | |
| 903 std::vector<TestVideoFile*>* test_video_files); | |
| 904 void UpdateVideoFileParam(const std::vector<TestVideoFile*>& test_video_files, | |
| 905 size_t num_concurrent_decoders, | |
| 906 int reset_point); | |
| 907 void InitializeRenderingHelper(const RenderingHelperParams& helper_params); | |
| 908 void CreateAndStartDecoder(GLRenderingVDAClient* client, | |
| 909 ClientStateNotification<ClientState>* note); | |
| 910 void WaitUntilDecodeFinish(ClientStateNotification<ClientState>* note); | |
| 911 void WaitUntilIdle(); | |
| 912 void OutputLogFile(const base::FilePath::CharType* log_path, | |
| 913 const std::string& content); | |
| 914 | |
| 915 std::vector<TestVideoFile*> test_video_files_; | |
| 916 RenderingHelper rendering_helper_; | |
| 917 scoped_refptr<base::MessageLoopProxy> rendering_loop_proxy_; | |
| 918 | |
| 919 private: | |
| 920 base::Thread rendering_thread_; | |
| 921 // Required for Thread to work. Not used otherwise. | |
| 922 base::ShadowingAtExitManager at_exit_manager_; | |
| 923 | |
| 924 DISALLOW_COPY_AND_ASSIGN(VideoDecodeAcceleratorTest); | |
| 925 }; | |
| 926 | |
| 927 VideoDecodeAcceleratorTest::VideoDecodeAcceleratorTest() | |
| 928 : rendering_thread_("GLRenderingVDAClientThread") {} | |
| 929 | |
| 930 void VideoDecodeAcceleratorTest::SetUp() { | |
| 931 ParseAndReadTestVideoData(g_test_video_data, &test_video_files_); | |
| 932 | |
| 933 // Initialize the rendering helper. | |
| 934 base::Thread::Options options; | |
| 935 options.message_loop_type = base::MessageLoop::TYPE_DEFAULT; | |
| 936 #if defined(OS_WIN) | |
| 937 // For windows the decoding thread initializes the media foundation decoder | |
| 938 // which uses COM. We need the thread to be a UI thread. | |
| 939 options.message_loop_type = base::MessageLoop::TYPE_UI; | |
| 940 #endif // OS_WIN | |
| 941 | |
| 942 rendering_thread_.StartWithOptions(options); | |
| 943 rendering_loop_proxy_ = rendering_thread_.message_loop_proxy(); | |
| 944 } | |
| 945 | |
| 946 void VideoDecodeAcceleratorTest::TearDown() { | |
| 947 rendering_loop_proxy_->PostTask( | |
| 948 FROM_HERE, | |
| 949 base::Bind(&STLDeleteElements<std::vector<TestVideoFile*> >, | |
| 950 &test_video_files_)); | |
| 951 | |
| 952 base::WaitableEvent done(false, false); | |
| 953 rendering_loop_proxy_->PostTask( | |
| 954 FROM_HERE, | |
| 955 base::Bind(&RenderingHelper::UnInitialize, | |
| 956 base::Unretained(&rendering_helper_), | |
| 957 &done)); | |
| 958 done.Wait(); | |
| 959 | |
| 960 rendering_thread_.Stop(); | |
| 961 } | |
| 962 | |
| 963 void VideoDecodeAcceleratorTest::ParseAndReadTestVideoData( | |
| 964 base::FilePath::StringType data, | |
| 965 std::vector<TestVideoFile*>* test_video_files) { | |
| 966 std::vector<base::FilePath::StringType> entries; | |
| 967 base::SplitString(data, ';', &entries); | |
| 968 CHECK_GE(entries.size(), 1U) << data; | |
| 969 for (size_t index = 0; index < entries.size(); ++index) { | |
| 970 std::vector<base::FilePath::StringType> fields; | |
| 971 base::SplitString(entries[index], ':', &fields); | |
| 972 CHECK_GE(fields.size(), 1U) << entries[index]; | |
| 973 CHECK_LE(fields.size(), 8U) << entries[index]; | |
| 974 TestVideoFile* video_file = new TestVideoFile(fields[0]); | |
| 975 if (!fields[1].empty()) | |
| 976 CHECK(base::StringToInt(fields[1], &video_file->width)); | |
| 977 if (!fields[2].empty()) | |
| 978 CHECK(base::StringToInt(fields[2], &video_file->height)); | |
| 979 if (!fields[3].empty()) | |
| 980 CHECK(base::StringToInt(fields[3], &video_file->num_frames)); | |
| 981 if (!fields[4].empty()) | |
| 982 CHECK(base::StringToInt(fields[4], &video_file->num_fragments)); | |
| 983 if (!fields[5].empty()) | |
| 984 CHECK(base::StringToInt(fields[5], &video_file->min_fps_render)); | |
| 985 if (!fields[6].empty()) | |
| 986 CHECK(base::StringToInt(fields[6], &video_file->min_fps_no_render)); | |
| 987 if (!fields[7].empty()) | |
| 988 CHECK(base::StringToInt(fields[7], &video_file->profile)); | |
| 989 | |
| 990 // Read in the video data. | |
| 991 base::FilePath filepath(video_file->file_name); | |
| 992 CHECK(base::ReadFileToString(filepath, &video_file->data_str)) | |
| 993 << "test_video_file: " << filepath.MaybeAsASCII(); | |
| 994 | |
| 995 test_video_files->push_back(video_file); | |
| 996 } | |
| 997 } | |
| 998 | |
| 999 void VideoDecodeAcceleratorTest::UpdateVideoFileParam( | |
| 1000 const std::vector<TestVideoFile*>& test_video_files, | |
| 1001 size_t num_concurrent_decoders, | |
| 1002 int reset_point) { | |
| 1003 for (size_t i = 0; i < test_video_files.size(); i++) { | |
| 1004 TestVideoFile* video_file = test_video_files[i]; | |
| 1005 if (video_file->num_frames > 0 && reset_point == MID_STREAM_RESET) { | |
| 1006 // Reset should not go beyond the last frame; reset after the first | |
| 1007 // frame for short videos. | |
| 1008 video_file->reset_after_frame_num = kMaxResetAfterFrameNum; | |
| 1009 if (video_file->num_frames <= kMaxResetAfterFrameNum) | |
| 1010 video_file->reset_after_frame_num = 1; | |
| 1011 video_file->num_frames += video_file->reset_after_frame_num; | |
| 1012 } | |
| 1013 if (video_file->min_fps_render != -1) | |
| 1014 video_file->min_fps_render /= num_concurrent_decoders; | |
| 1015 if (video_file->min_fps_no_render != -1) | |
| 1016 video_file->min_fps_no_render /= num_concurrent_decoders; | |
| 1017 } | |
| 1018 } | |
| 1019 | |
| 1020 void VideoDecodeAcceleratorTest::InitializeRenderingHelper( | |
| 1021 const RenderingHelperParams& helper_params) { | |
| 1022 base::WaitableEvent done(false, false); | |
| 1023 rendering_loop_proxy_->PostTask( | |
| 1024 FROM_HERE, | |
| 1025 base::Bind(&RenderingHelper::Initialize, | |
| 1026 base::Unretained(&rendering_helper_), | |
| 1027 helper_params, | |
| 1028 &done)); | |
| 1029 done.Wait(); | |
| 1030 } | |
| 1031 | |
| 1032 void VideoDecodeAcceleratorTest::CreateAndStartDecoder( | |
| 1033 GLRenderingVDAClient* client, | |
| 1034 ClientStateNotification<ClientState>* note) { | |
| 1035 rendering_loop_proxy_->PostTask( | |
| 1036 FROM_HERE, | |
| 1037 base::Bind(&GLRenderingVDAClient::CreateAndStartDecoder, | |
| 1038 base::Unretained(client))); | |
| 1039 ASSERT_EQ(note->Wait(), CS_DECODER_SET); | |
| 1040 } | |
| 1041 | |
| 1042 void VideoDecodeAcceleratorTest::WaitUntilDecodeFinish( | |
| 1043 ClientStateNotification<ClientState>* note) { | |
| 1044 for (int i = 0; i < CS_MAX; i++) { | |
| 1045 if (note->Wait() == CS_DESTROYED) | |
| 1046 break; | |
| 1047 } | |
| 1048 } | |
| 1049 | |
| 1050 void VideoDecodeAcceleratorTest::WaitUntilIdle() { | |
| 1051 base::WaitableEvent done(false, false); | |
| 1052 rendering_loop_proxy_->PostTask( | |
| 1053 FROM_HERE, | |
| 1054 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&done))); | |
| 1055 done.Wait(); | |
| 1056 } | |
| 1057 | |
| 1058 void VideoDecodeAcceleratorTest::OutputLogFile( | |
| 1059 const base::FilePath::CharType* log_path, | |
| 1060 const std::string& content) { | |
| 1061 base::PlatformFile file = base::CreatePlatformFile( | |
| 1062 base::FilePath(log_path), | |
| 1063 base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE, | |
| 1064 NULL, | |
| 1065 NULL); | |
| 1066 base::WritePlatformFileAtCurrentPos(file, content.data(), content.length()); | |
| 1067 base::ClosePlatformFile(file); | |
| 1068 } | |
| 1069 | |
| 911 // Test parameters: | 1070 // Test parameters: |
| 912 // - Number of concurrent decoders. | 1071 // - Number of concurrent decoders. |
| 913 // - Number of concurrent in-flight Decode() calls per decoder. | 1072 // - Number of concurrent in-flight Decode() calls per decoder. |
| 914 // - Number of play-throughs. | 1073 // - Number of play-throughs. |
| 915 // - reset_after_frame_num: see GLRenderingVDAClient ctor. | 1074 // - reset_after_frame_num: see GLRenderingVDAClient ctor. |
| 916 // - delete_decoder_phase: see GLRenderingVDAClient ctor. | 1075 // - delete_decoder_phase: see GLRenderingVDAClient ctor. |
| 917 // - whether to test slow rendering by delaying ReusePictureBuffer(). | 1076 // - whether to test slow rendering by delaying ReusePictureBuffer(). |
| 918 // - whether the video frames are rendered as thumbnails. | 1077 // - whether the video frames are rendered as thumbnails. |
| 919 class VideoDecodeAcceleratorTest | 1078 class VideoDecodeAcceleratorParamTest |
| 920 : public ::testing::TestWithParam< | 1079 : public VideoDecodeAcceleratorTest, |
| 921 Tuple7<int, int, int, ResetPoint, ClientState, bool, bool> > { | 1080 public ::testing::WithParamInterface< |
| 1081 Tuple7<int, int, int, ResetPoint, ClientState, bool, bool> > { | |
| 922 }; | 1082 }; |
| 923 | 1083 |
| 924 // Helper so that gtest failures emit a more readable version of the tuple than | 1084 // Helper so that gtest failures emit a more readable version of the tuple than |
| 925 // its byte representation. | 1085 // its byte representation. |
| 926 ::std::ostream& operator<<( | 1086 ::std::ostream& operator<<( |
| 927 ::std::ostream& os, | 1087 ::std::ostream& os, |
| 928 const Tuple7<int, int, int, ResetPoint, ClientState, bool, bool>& t) { | 1088 const Tuple7<int, int, int, ResetPoint, ClientState, bool, bool>& t) { |
| 929 return os << t.a << ", " << t.b << ", " << t.c << ", " << t.d << ", " << t.e | 1089 return os << t.a << ", " << t.b << ", " << t.c << ", " << t.d << ", " << t.e |
| 930 << ", " << t.f << ", " << t.g; | 1090 << ", " << t.f << ", " << t.g; |
| 931 } | 1091 } |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 943 << ", instead of " << expected_state; | 1103 << ", instead of " << expected_state; |
| 944 } | 1104 } |
| 945 | 1105 |
| 946 // We assert a minimal number of concurrent decoders we expect to succeed. | 1106 // We assert a minimal number of concurrent decoders we expect to succeed. |
| 947 // Different platforms can support more concurrent decoders, so we don't assert | 1107 // Different platforms can support more concurrent decoders, so we don't assert |
| 948 // failure above this. | 1108 // failure above this. |
| 949 enum { kMinSupportedNumConcurrentDecoders = 3 }; | 1109 enum { kMinSupportedNumConcurrentDecoders = 3 }; |
| 950 | 1110 |
| 951 // Test the most straightforward case possible: data is decoded from a single | 1111 // Test the most straightforward case possible: data is decoded from a single |
| 952 // chunk and rendered to the screen. | 1112 // chunk and rendered to the screen. |
| 953 TEST_P(VideoDecodeAcceleratorTest, TestSimpleDecode) { | 1113 TEST_P(VideoDecodeAcceleratorParamTest, TestSimpleDecode) { |
| 954 // Required for Thread to work. Not used otherwise. | |
| 955 base::ShadowingAtExitManager at_exit_manager; | |
| 956 | |
| 957 const size_t num_concurrent_decoders = GetParam().a; | 1114 const size_t num_concurrent_decoders = GetParam().a; |
| 958 const size_t num_in_flight_decodes = GetParam().b; | 1115 const size_t num_in_flight_decodes = GetParam().b; |
| 959 const int num_play_throughs = GetParam().c; | 1116 const int num_play_throughs = GetParam().c; |
| 960 const int reset_point = GetParam().d; | 1117 const int reset_point = GetParam().d; |
| 961 const int delete_decoder_state = GetParam().e; | 1118 const int delete_decoder_state = GetParam().e; |
| 962 bool test_reuse_delay = GetParam().f; | 1119 bool test_reuse_delay = GetParam().f; |
| 963 const bool render_as_thumbnails = GetParam().g; | 1120 const bool render_as_thumbnails = GetParam().g; |
| 964 | 1121 |
| 965 std::vector<TestVideoFile*> test_video_files; | 1122 UpdateVideoFileParam(test_video_files_, num_concurrent_decoders, reset_point); |
| 966 ParseAndReadTestVideoData(g_test_video_data, | |
| 967 num_concurrent_decoders, | |
| 968 reset_point, | |
| 969 &test_video_files); | |
| 970 | 1123 |
| 971 // Suppress GL rendering for all tests when the "--disable_rendering" is set. | 1124 // Suppress GL rendering for all tests when the "--disable_rendering" is set. |
| 972 const bool suppress_rendering = g_disable_rendering; | 1125 const bool suppress_rendering = g_disable_rendering; |
| 973 | 1126 |
| 974 std::vector<ClientStateNotification<ClientState>*> | 1127 std::vector<ClientStateNotification<ClientState>*> |
| 975 notes(num_concurrent_decoders, NULL); | 1128 notes(num_concurrent_decoders, NULL); |
| 976 std::vector<GLRenderingVDAClient*> clients(num_concurrent_decoders, NULL); | 1129 std::vector<GLRenderingVDAClient*> clients(num_concurrent_decoders, NULL); |
| 977 | 1130 |
| 978 // Initialize the rendering helper. | |
| 979 base::Thread rendering_thread("GLRenderingVDAClientThread"); | |
| 980 base::Thread::Options options; | |
| 981 options.message_loop_type = base::MessageLoop::TYPE_DEFAULT; | |
| 982 #if defined(OS_WIN) | |
| 983 // For windows the decoding thread initializes the media foundation decoder | |
| 984 // which uses COM. We need the thread to be a UI thread. | |
| 985 options.message_loop_type = base::MessageLoop::TYPE_UI; | |
| 986 #endif // OS_WIN | |
| 987 | |
| 988 rendering_thread.StartWithOptions(options); | |
| 989 RenderingHelper rendering_helper; | |
| 990 | |
| 991 base::WaitableEvent done(false, false); | |
| 992 RenderingHelperParams helper_params; | 1131 RenderingHelperParams helper_params; |
| 993 helper_params.num_windows = num_concurrent_decoders; | 1132 helper_params.num_windows = num_concurrent_decoders; |
| 994 helper_params.render_as_thumbnails = render_as_thumbnails; | 1133 helper_params.render_as_thumbnails = render_as_thumbnails; |
| 995 if (render_as_thumbnails) { | 1134 if (render_as_thumbnails) { |
| 996 // Only one decoder is supported with thumbnail rendering | 1135 // Only one decoder is supported with thumbnail rendering |
| 997 CHECK_EQ(num_concurrent_decoders, 1U); | 1136 CHECK_EQ(num_concurrent_decoders, 1U); |
| 998 gfx::Size frame_size(test_video_files[0]->width, | 1137 gfx::Size frame_size(test_video_files_[0]->width, |
| 999 test_video_files[0]->height); | 1138 test_video_files_[0]->height); |
| 1000 helper_params.frame_dimensions.push_back(frame_size); | 1139 helper_params.frame_dimensions.push_back(frame_size); |
| 1001 helper_params.window_dimensions.push_back(kThumbnailsDisplaySize); | 1140 helper_params.window_dimensions.push_back(kThumbnailsDisplaySize); |
| 1002 helper_params.thumbnails_page_size = kThumbnailsPageSize; | 1141 helper_params.thumbnails_page_size = kThumbnailsPageSize; |
| 1003 helper_params.thumbnail_size = kThumbnailSize; | 1142 helper_params.thumbnail_size = kThumbnailSize; |
| 1004 } else { | 1143 } else { |
| 1005 for (size_t index = 0; index < test_video_files.size(); ++index) { | 1144 for (size_t index = 0; index < test_video_files_.size(); ++index) { |
| 1006 gfx::Size frame_size(test_video_files[index]->width, | 1145 gfx::Size frame_size(test_video_files_[index]->width, |
| 1007 test_video_files[index]->height); | 1146 test_video_files_[index]->height); |
| 1008 helper_params.frame_dimensions.push_back(frame_size); | 1147 helper_params.frame_dimensions.push_back(frame_size); |
| 1009 helper_params.window_dimensions.push_back(frame_size); | 1148 helper_params.window_dimensions.push_back(frame_size); |
| 1010 } | 1149 } |
| 1011 } | 1150 } |
| 1012 rendering_thread.message_loop()->PostTask( | 1151 InitializeRenderingHelper(helper_params); |
| 1013 FROM_HERE, | |
| 1014 base::Bind(&RenderingHelper::Initialize, | |
| 1015 base::Unretained(&rendering_helper), | |
| 1016 helper_params, | |
| 1017 &done)); | |
| 1018 done.Wait(); | |
| 1019 | 1152 |
| 1020 // First kick off all the decoders. | 1153 // First kick off all the decoders. |
| 1021 for (size_t index = 0; index < num_concurrent_decoders; ++index) { | 1154 for (size_t index = 0; index < num_concurrent_decoders; ++index) { |
| 1022 TestVideoFile* video_file = | 1155 TestVideoFile* video_file = |
| 1023 test_video_files[index % test_video_files.size()]; | 1156 test_video_files_[index % test_video_files_.size()]; |
| 1024 ClientStateNotification<ClientState>* note = | 1157 ClientStateNotification<ClientState>* note = |
| 1025 new ClientStateNotification<ClientState>(); | 1158 new ClientStateNotification<ClientState>(); |
| 1026 notes[index] = note; | 1159 notes[index] = note; |
| 1027 | 1160 |
| 1028 int delay_after_frame_num = std::numeric_limits<int>::max(); | 1161 int delay_after_frame_num = std::numeric_limits<int>::max(); |
| 1029 if (test_reuse_delay && | 1162 if (test_reuse_delay && |
| 1030 kMaxFramesToDelayReuse * 2 < video_file->num_frames) { | 1163 kMaxFramesToDelayReuse * 2 < video_file->num_frames) { |
| 1031 delay_after_frame_num = video_file->num_frames - kMaxFramesToDelayReuse; | 1164 delay_after_frame_num = video_file->num_frames - kMaxFramesToDelayReuse; |
| 1032 } | 1165 } |
| 1033 | 1166 |
| 1034 GLRenderingVDAClient* client = | 1167 GLRenderingVDAClient* client = |
| 1035 new GLRenderingVDAClient(&rendering_helper, | 1168 new GLRenderingVDAClient(&rendering_helper_, |
| 1036 index, | 1169 index, |
| 1037 note, | 1170 note, |
| 1038 video_file->data_str, | 1171 video_file->data_str, |
| 1039 num_in_flight_decodes, | 1172 num_in_flight_decodes, |
| 1040 num_play_throughs, | 1173 num_play_throughs, |
| 1041 video_file->reset_after_frame_num, | 1174 video_file->reset_after_frame_num, |
| 1042 delete_decoder_state, | 1175 delete_decoder_state, |
| 1043 video_file->width, | 1176 video_file->width, |
| 1044 video_file->height, | 1177 video_file->height, |
| 1045 video_file->profile, | 1178 video_file->profile, |
| 1046 g_rendering_fps, | 1179 g_rendering_fps, |
| 1047 suppress_rendering, | 1180 suppress_rendering, |
| 1048 delay_after_frame_num); | 1181 delay_after_frame_num, |
| 1182 0); | |
| 1049 clients[index] = client; | 1183 clients[index] = client; |
| 1050 | 1184 |
| 1051 rendering_thread.message_loop()->PostTask( | 1185 CreateAndStartDecoder(client, note); |
| 1052 FROM_HERE, | |
| 1053 base::Bind(&GLRenderingVDAClient::CreateDecoder, | |
| 1054 base::Unretained(client))); | |
| 1055 | |
| 1056 ASSERT_EQ(note->Wait(), CS_DECODER_SET); | |
| 1057 } | 1186 } |
| 1058 // Then wait for all the decodes to finish. | 1187 // Then wait for all the decodes to finish. |
| 1059 // Only check performance & correctness later if we play through only once. | 1188 // Only check performance & correctness later if we play through only once. |
| 1060 bool skip_performance_and_correctness_checks = num_play_throughs > 1; | 1189 bool skip_performance_and_correctness_checks = num_play_throughs > 1; |
| 1061 for (size_t i = 0; i < num_concurrent_decoders; ++i) { | 1190 for (size_t i = 0; i < num_concurrent_decoders; ++i) { |
| 1062 ClientStateNotification<ClientState>* note = notes[i]; | 1191 ClientStateNotification<ClientState>* note = notes[i]; |
| 1063 ClientState state = note->Wait(); | 1192 ClientState state = note->Wait(); |
| 1064 if (state != CS_INITIALIZED) { | 1193 if (state != CS_INITIALIZED) { |
| 1065 skip_performance_and_correctness_checks = true; | 1194 skip_performance_and_correctness_checks = true; |
| 1066 // We expect initialization to fail only when more than the supported | 1195 // We expect initialization to fail only when more than the supported |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 1095 AssertWaitForStateOrDeleted(note, clients[i], CS_DESTROYED)); | 1224 AssertWaitForStateOrDeleted(note, clients[i], CS_DESTROYED)); |
| 1096 } | 1225 } |
| 1097 // Finally assert that decoding went as expected. | 1226 // Finally assert that decoding went as expected. |
| 1098 for (size_t i = 0; i < num_concurrent_decoders && | 1227 for (size_t i = 0; i < num_concurrent_decoders && |
| 1099 !skip_performance_and_correctness_checks; ++i) { | 1228 !skip_performance_and_correctness_checks; ++i) { |
| 1100 // We can only make performance/correctness assertions if the decoder was | 1229 // We can only make performance/correctness assertions if the decoder was |
| 1101 // allowed to finish. | 1230 // allowed to finish. |
| 1102 if (delete_decoder_state < CS_FLUSHED) | 1231 if (delete_decoder_state < CS_FLUSHED) |
| 1103 continue; | 1232 continue; |
| 1104 GLRenderingVDAClient* client = clients[i]; | 1233 GLRenderingVDAClient* client = clients[i]; |
| 1105 TestVideoFile* video_file = test_video_files[i % test_video_files.size()]; | 1234 TestVideoFile* video_file = test_video_files_[i % test_video_files_.size()]; |
| 1106 if (video_file->num_frames > 0) { | 1235 if (video_file->num_frames > 0) { |
| 1107 // Expect the decoded frames may be more than the video frames as frames | 1236 // Expect the decoded frames may be more than the video frames as frames |
| 1108 // could still be returned until resetting done. | 1237 // could still be returned until resetting done. |
| 1109 if (video_file->reset_after_frame_num > 0) | 1238 if (video_file->reset_after_frame_num > 0) |
| 1110 EXPECT_GE(client->num_decoded_frames(), video_file->num_frames); | 1239 EXPECT_GE(client->num_decoded_frames(), video_file->num_frames); |
| 1111 else | 1240 else |
| 1112 EXPECT_EQ(client->num_decoded_frames(), video_file->num_frames); | 1241 EXPECT_EQ(client->num_decoded_frames(), video_file->num_frames); |
| 1113 } | 1242 } |
| 1114 if (reset_point == END_OF_STREAM_RESET) { | 1243 if (reset_point == END_OF_STREAM_RESET) { |
| 1115 EXPECT_EQ(video_file->num_fragments, client->num_skipped_fragments() + | 1244 EXPECT_EQ(video_file->num_fragments, client->num_skipped_fragments() + |
| 1116 client->num_queued_fragments()); | 1245 client->num_queued_fragments()); |
| 1117 EXPECT_EQ(client->num_done_bitstream_buffers(), | 1246 EXPECT_EQ(client->num_done_bitstream_buffers(), |
| 1118 client->num_queued_fragments()); | 1247 client->num_queued_fragments()); |
| 1119 } | 1248 } |
| 1120 LOG(INFO) << "Decoder " << i << " fps: " << client->frames_per_second(); | 1249 LOG(INFO) << "Decoder " << i << " fps: " << client->frames_per_second(); |
| 1121 if (!render_as_thumbnails) { | 1250 if (!render_as_thumbnails) { |
| 1122 int min_fps = suppress_rendering ? | 1251 int min_fps = suppress_rendering ? |
| 1123 video_file->min_fps_no_render : video_file->min_fps_render; | 1252 video_file->min_fps_no_render : video_file->min_fps_render; |
| 1124 if (min_fps > 0 && !test_reuse_delay) | 1253 if (min_fps > 0 && !test_reuse_delay) |
| 1125 EXPECT_GT(client->frames_per_second(), min_fps); | 1254 EXPECT_GT(client->frames_per_second(), min_fps); |
| 1126 } | 1255 } |
| 1127 } | 1256 } |
| 1128 | 1257 |
| 1129 if (render_as_thumbnails) { | 1258 if (render_as_thumbnails) { |
| 1130 std::vector<unsigned char> rgb; | 1259 std::vector<unsigned char> rgb; |
| 1131 bool alpha_solid; | 1260 bool alpha_solid; |
| 1132 rendering_thread.message_loop()->PostTask( | 1261 base::WaitableEvent done(false, false); |
| 1262 rendering_loop_proxy_->PostTask( | |
| 1133 FROM_HERE, | 1263 FROM_HERE, |
| 1134 base::Bind(&RenderingHelper::GetThumbnailsAsRGB, | 1264 base::Bind(&RenderingHelper::GetThumbnailsAsRGB, |
| 1135 base::Unretained(&rendering_helper), | 1265 base::Unretained(&rendering_helper_), |
| 1136 &rgb, &alpha_solid, &done)); | 1266 &rgb, &alpha_solid, &done)); |
| 1137 done.Wait(); | 1267 done.Wait(); |
| 1138 | 1268 |
| 1139 std::vector<std::string> golden_md5s; | 1269 std::vector<std::string> golden_md5s; |
| 1140 std::string md5_string = base::MD5String( | 1270 std::string md5_string = base::MD5String( |
| 1141 base::StringPiece(reinterpret_cast<char*>(&rgb[0]), rgb.size())); | 1271 base::StringPiece(reinterpret_cast<char*>(&rgb[0]), rgb.size())); |
| 1142 ReadGoldenThumbnailMD5s(test_video_files[0], &golden_md5s); | 1272 ReadGoldenThumbnailMD5s(test_video_files_[0], &golden_md5s); |
| 1143 std::vector<std::string>::iterator match = | 1273 std::vector<std::string>::iterator match = |
| 1144 find(golden_md5s.begin(), golden_md5s.end(), md5_string); | 1274 find(golden_md5s.begin(), golden_md5s.end(), md5_string); |
| 1145 if (match == golden_md5s.end()) { | 1275 if (match == golden_md5s.end()) { |
| 1146 // Convert raw RGB into PNG for export. | 1276 // Convert raw RGB into PNG for export. |
| 1147 std::vector<unsigned char> png; | 1277 std::vector<unsigned char> png; |
| 1148 gfx::PNGCodec::Encode(&rgb[0], | 1278 gfx::PNGCodec::Encode(&rgb[0], |
| 1149 gfx::PNGCodec::FORMAT_RGB, | 1279 gfx::PNGCodec::FORMAT_RGB, |
| 1150 kThumbnailsPageSize, | 1280 kThumbnailsPageSize, |
| 1151 kThumbnailsPageSize.width() * 3, | 1281 kThumbnailsPageSize.width() * 3, |
| 1152 true, | 1282 true, |
| 1153 std::vector<gfx::PNGCodec::Comment>(), | 1283 std::vector<gfx::PNGCodec::Comment>(), |
| 1154 &png); | 1284 &png); |
| 1155 | 1285 |
| 1156 LOG(ERROR) << "Unknown thumbnails MD5: " << md5_string; | 1286 LOG(ERROR) << "Unknown thumbnails MD5: " << md5_string; |
| 1157 | 1287 |
| 1158 base::FilePath filepath(test_video_files[0]->file_name); | 1288 base::FilePath filepath(test_video_files_[0]->file_name); |
| 1159 filepath = filepath.AddExtension(FILE_PATH_LITERAL(".bad_thumbnails")); | 1289 filepath = filepath.AddExtension(FILE_PATH_LITERAL(".bad_thumbnails")); |
| 1160 filepath = filepath.AddExtension(FILE_PATH_LITERAL(".png")); | 1290 filepath = filepath.AddExtension(FILE_PATH_LITERAL(".png")); |
| 1161 int num_bytes = file_util::WriteFile(filepath, | 1291 int num_bytes = file_util::WriteFile(filepath, |
| 1162 reinterpret_cast<char*>(&png[0]), | 1292 reinterpret_cast<char*>(&png[0]), |
| 1163 png.size()); | 1293 png.size()); |
| 1164 ASSERT_EQ(num_bytes, static_cast<int>(png.size())); | 1294 ASSERT_EQ(num_bytes, static_cast<int>(png.size())); |
| 1165 } | 1295 } |
| 1166 ASSERT_NE(match, golden_md5s.end()); | 1296 ASSERT_NE(match, golden_md5s.end()); |
| 1167 EXPECT_EQ(alpha_solid, true) << "RGBA frame had incorrect alpha"; | 1297 EXPECT_EQ(alpha_solid, true) << "RGBA frame had incorrect alpha"; |
| 1168 } | 1298 } |
| 1169 | 1299 |
| 1170 // Output the frame delivery time to file | 1300 // Output the frame delivery time to file |
| 1171 // We can only make performance/correctness assertions if the decoder was | 1301 // We can only make performance/correctness assertions if the decoder was |
| 1172 // allowed to finish. | 1302 // allowed to finish. |
| 1173 if (g_frame_delivery_log != NULL && delete_decoder_state >= CS_FLUSHED) { | 1303 if (g_output_log != NULL && delete_decoder_state >= CS_FLUSHED) { |
| 1174 base::PlatformFile output_file = base::CreatePlatformFile( | 1304 base::PlatformFile output_file = base::CreatePlatformFile( |
| 1175 base::FilePath(g_frame_delivery_log), | 1305 base::FilePath(g_output_log), |
| 1176 base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE, | 1306 base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE, |
| 1177 NULL, | 1307 NULL, |
| 1178 NULL); | 1308 NULL); |
| 1179 for (size_t i = 0; i < num_concurrent_decoders; ++i) { | 1309 for (size_t i = 0; i < num_concurrent_decoders; ++i) { |
| 1180 clients[i]->OutputFrameDeliveryTimes(output_file); | 1310 clients[i]->OutputFrameDeliveryTimes(output_file); |
| 1181 } | 1311 } |
| 1182 base::ClosePlatformFile(output_file); | 1312 base::ClosePlatformFile(output_file); |
| 1183 } | 1313 } |
| 1184 | 1314 |
| 1185 rendering_thread.message_loop()->PostTask( | 1315 rendering_loop_proxy_->PostTask( |
| 1186 FROM_HERE, | 1316 FROM_HERE, |
| 1187 base::Bind(&STLDeleteElements<std::vector<GLRenderingVDAClient*> >, | 1317 base::Bind(&STLDeleteElements<std::vector<GLRenderingVDAClient*> >, |
| 1188 &clients)); | 1318 &clients)); |
| 1189 rendering_thread.message_loop()->PostTask( | 1319 rendering_loop_proxy_->PostTask( |
| 1190 FROM_HERE, | 1320 FROM_HERE, |
| 1191 base::Bind(&STLDeleteElements< | 1321 base::Bind(&STLDeleteElements< |
| 1192 std::vector<ClientStateNotification<ClientState>*> >, | 1322 std::vector<ClientStateNotification<ClientState>*> >, |
| 1193 ¬es)); | 1323 ¬es)); |
| 1194 rendering_thread.message_loop()->PostTask( | 1324 WaitUntilIdle(); |
| 1195 FROM_HERE, | |
| 1196 base::Bind(&STLDeleteElements<std::vector<TestVideoFile*> >, | |
| 1197 &test_video_files)); | |
| 1198 rendering_thread.message_loop()->PostTask( | |
| 1199 FROM_HERE, | |
| 1200 base::Bind(&RenderingHelper::UnInitialize, | |
| 1201 base::Unretained(&rendering_helper), | |
| 1202 &done)); | |
| 1203 done.Wait(); | |
| 1204 rendering_thread.Stop(); | |
| 1205 }; | 1325 }; |
| 1206 | 1326 |
| 1207 // Test that replay after EOS works fine. | 1327 // Test that replay after EOS works fine. |
| 1208 INSTANTIATE_TEST_CASE_P( | 1328 INSTANTIATE_TEST_CASE_P( |
| 1209 ReplayAfterEOS, VideoDecodeAcceleratorTest, | 1329 ReplayAfterEOS, VideoDecodeAcceleratorParamTest, |
| 1210 ::testing::Values( | 1330 ::testing::Values( |
| 1211 MakeTuple(1, 1, 4, END_OF_STREAM_RESET, CS_RESET, false, false))); | 1331 MakeTuple(1, 1, 4, END_OF_STREAM_RESET, CS_RESET, false, false))); |
| 1212 | 1332 |
| 1213 // This hangs on Exynos, preventing further testing and wasting test machine | 1333 // This hangs on Exynos, preventing further testing and wasting test machine |
| 1214 // time. | 1334 // time. |
| 1215 // TODO(ihf): Enable again once http://crbug.com/269754 is fixed. | 1335 // TODO(ihf): Enable again once http://crbug.com/269754 is fixed. |
| 1216 #if defined(ARCH_CPU_X86_FAMILY) | 1336 #if defined(ARCH_CPU_X86_FAMILY) |
| 1217 // Test that Reset() before the first Decode() works fine. | 1337 // Test that Reset() before the first Decode() works fine. |
| 1218 INSTANTIATE_TEST_CASE_P( | 1338 INSTANTIATE_TEST_CASE_P( |
| 1219 ResetBeforeDecode, VideoDecodeAcceleratorTest, | 1339 ResetBeforeDecode, VideoDecodeAcceleratorParamTest, |
| 1220 ::testing::Values( | 1340 ::testing::Values( |
| 1221 MakeTuple(1, 1, 1, START_OF_STREAM_RESET, CS_RESET, false, false))); | 1341 MakeTuple(1, 1, 1, START_OF_STREAM_RESET, CS_RESET, false, false))); |
| 1222 #endif // ARCH_CPU_X86_FAMILY | 1342 #endif // ARCH_CPU_X86_FAMILY |
| 1223 | 1343 |
| 1224 // Test that Reset() mid-stream works fine and doesn't affect decoding even when | 1344 // Test that Reset() mid-stream works fine and doesn't affect decoding even when |
| 1225 // Decode() calls are made during the reset. | 1345 // Decode() calls are made during the reset. |
| 1226 INSTANTIATE_TEST_CASE_P( | 1346 INSTANTIATE_TEST_CASE_P( |
| 1227 MidStreamReset, VideoDecodeAcceleratorTest, | 1347 MidStreamReset, VideoDecodeAcceleratorParamTest, |
| 1228 ::testing::Values( | 1348 ::testing::Values( |
| 1229 MakeTuple(1, 1, 1, MID_STREAM_RESET, CS_RESET, false, false))); | 1349 MakeTuple(1, 1, 1, MID_STREAM_RESET, CS_RESET, false, false))); |
| 1230 | 1350 |
| 1231 INSTANTIATE_TEST_CASE_P( | 1351 INSTANTIATE_TEST_CASE_P( |
| 1232 SlowRendering, VideoDecodeAcceleratorTest, | 1352 SlowRendering, VideoDecodeAcceleratorParamTest, |
| 1233 ::testing::Values( | 1353 ::testing::Values( |
| 1234 MakeTuple(1, 1, 1, END_OF_STREAM_RESET, CS_RESET, true, false))); | 1354 MakeTuple(1, 1, 1, END_OF_STREAM_RESET, CS_RESET, true, false))); |
| 1235 | 1355 |
| 1236 // Test that Destroy() mid-stream works fine (primarily this is testing that no | 1356 // Test that Destroy() mid-stream works fine (primarily this is testing that no |
| 1237 // crashes occur). | 1357 // crashes occur). |
| 1238 INSTANTIATE_TEST_CASE_P( | 1358 INSTANTIATE_TEST_CASE_P( |
| 1239 TearDownTiming, VideoDecodeAcceleratorTest, | 1359 TearDownTiming, VideoDecodeAcceleratorParamTest, |
| 1240 ::testing::Values( | 1360 ::testing::Values( |
| 1241 MakeTuple(1, 1, 1, END_OF_STREAM_RESET, CS_DECODER_SET, false, false), | 1361 MakeTuple(1, 1, 1, END_OF_STREAM_RESET, CS_DECODER_SET, false, false), |
| 1242 MakeTuple(1, 1, 1, END_OF_STREAM_RESET, CS_INITIALIZED, false, false), | 1362 MakeTuple(1, 1, 1, END_OF_STREAM_RESET, CS_INITIALIZED, false, false), |
| 1243 MakeTuple(1, 1, 1, END_OF_STREAM_RESET, CS_FLUSHING, false, false), | 1363 MakeTuple(1, 1, 1, END_OF_STREAM_RESET, CS_FLUSHING, false, false), |
| 1244 MakeTuple(1, 1, 1, END_OF_STREAM_RESET, CS_FLUSHED, false, false), | 1364 MakeTuple(1, 1, 1, END_OF_STREAM_RESET, CS_FLUSHED, false, false), |
| 1245 MakeTuple(1, 1, 1, END_OF_STREAM_RESET, CS_RESETTING, false, false), | 1365 MakeTuple(1, 1, 1, END_OF_STREAM_RESET, CS_RESETTING, false, false), |
| 1246 MakeTuple(1, 1, 1, END_OF_STREAM_RESET, CS_RESET, false, false), | 1366 MakeTuple(1, 1, 1, END_OF_STREAM_RESET, CS_RESET, false, false), |
| 1247 MakeTuple(1, 1, 1, END_OF_STREAM_RESET, | 1367 MakeTuple(1, 1, 1, END_OF_STREAM_RESET, |
| 1248 static_cast<ClientState>(-1), false, false), | 1368 static_cast<ClientState>(-1), false, false), |
| 1249 MakeTuple(1, 1, 1, END_OF_STREAM_RESET, | 1369 MakeTuple(1, 1, 1, END_OF_STREAM_RESET, |
| 1250 static_cast<ClientState>(-10), false, false), | 1370 static_cast<ClientState>(-10), false, false), |
| 1251 MakeTuple(1, 1, 1, END_OF_STREAM_RESET, | 1371 MakeTuple(1, 1, 1, END_OF_STREAM_RESET, |
| 1252 static_cast<ClientState>(-100), false, false))); | 1372 static_cast<ClientState>(-100), false, false))); |
| 1253 | 1373 |
| 1254 // Test that decoding various variation works with multiple in-flight decodes. | 1374 // Test that decoding various variation works with multiple in-flight decodes. |
| 1255 INSTANTIATE_TEST_CASE_P( | 1375 INSTANTIATE_TEST_CASE_P( |
| 1256 DecodeVariations, VideoDecodeAcceleratorTest, | 1376 DecodeVariations, VideoDecodeAcceleratorParamTest, |
| 1257 ::testing::Values( | 1377 ::testing::Values( |
| 1258 MakeTuple(1, 1, 1, END_OF_STREAM_RESET, CS_RESET, false, false), | 1378 MakeTuple(1, 1, 1, END_OF_STREAM_RESET, CS_RESET, false, false), |
| 1259 MakeTuple(1, 10, 1, END_OF_STREAM_RESET, CS_RESET, false, false), | 1379 MakeTuple(1, 10, 1, END_OF_STREAM_RESET, CS_RESET, false, false), |
| 1260 // Tests queuing. | 1380 // Tests queuing. |
| 1261 MakeTuple(1, 15, 1, END_OF_STREAM_RESET, CS_RESET, false, false))); | 1381 MakeTuple(1, 15, 1, END_OF_STREAM_RESET, CS_RESET, false, false))); |
| 1262 | 1382 |
| 1263 // Find out how many concurrent decoders can go before we exhaust system | 1383 // Find out how many concurrent decoders can go before we exhaust system |
| 1264 // resources. | 1384 // resources. |
| 1265 INSTANTIATE_TEST_CASE_P( | 1385 INSTANTIATE_TEST_CASE_P( |
| 1266 ResourceExhaustion, VideoDecodeAcceleratorTest, | 1386 ResourceExhaustion, VideoDecodeAcceleratorParamTest, |
| 1267 ::testing::Values( | 1387 ::testing::Values( |
| 1268 // +0 hack below to promote enum to int. | 1388 // +0 hack below to promote enum to int. |
| 1269 MakeTuple(kMinSupportedNumConcurrentDecoders + 0, 1, 1, | 1389 MakeTuple(kMinSupportedNumConcurrentDecoders + 0, 1, 1, |
| 1270 END_OF_STREAM_RESET, CS_RESET, false, false), | 1390 END_OF_STREAM_RESET, CS_RESET, false, false), |
| 1271 MakeTuple(kMinSupportedNumConcurrentDecoders + 1, 1, 1, | 1391 MakeTuple(kMinSupportedNumConcurrentDecoders + 1, 1, 1, |
| 1272 END_OF_STREAM_RESET, CS_RESET, false, false))); | 1392 END_OF_STREAM_RESET, CS_RESET, false, false))); |
| 1273 | 1393 |
| 1274 // Thumbnailing test | 1394 // Thumbnailing test |
| 1275 INSTANTIATE_TEST_CASE_P( | 1395 INSTANTIATE_TEST_CASE_P( |
| 1276 Thumbnail, VideoDecodeAcceleratorTest, | 1396 Thumbnail, VideoDecodeAcceleratorParamTest, |
| 1277 ::testing::Values( | 1397 ::testing::Values( |
| 1278 MakeTuple(1, 1, 1, END_OF_STREAM_RESET, CS_RESET, false, true))); | 1398 MakeTuple(1, 1, 1, END_OF_STREAM_RESET, CS_RESET, false, true))); |
| 1279 | 1399 |
| 1400 TEST_F(VideoDecodeAcceleratorTest, TestDecodeTime) { | |
| 1401 RenderingHelperParams helper_params; | |
| 1402 gfx::Size frame_size(test_video_files_[0]->width, | |
| 1403 test_video_files_[0]->height); | |
| 1404 helper_params.frame_dimensions.push_back(frame_size); | |
| 1405 helper_params.window_dimensions.push_back(frame_size); | |
| 1406 InitializeRenderingHelper(helper_params); | |
| 1407 | |
| 1408 ClientStateNotification<ClientState>* note = | |
| 1409 new ClientStateNotification<ClientState>(); | |
| 1410 GLRenderingVDAClient* client = | |
| 1411 new GLRenderingVDAClient(&rendering_helper_, | |
| 1412 0, | |
| 1413 note, | |
| 1414 test_video_files_[0]->data_str, | |
| 1415 1, | |
| 1416 1, | |
| 1417 test_video_files_[0]->reset_after_frame_num, | |
| 1418 CS_RESET, | |
| 1419 test_video_files_[0]->width, | |
| 1420 test_video_files_[0]->height, | |
| 1421 test_video_files_[0]->profile, | |
| 1422 g_rendering_fps, | |
| 1423 true, | |
| 1424 std::numeric_limits<int>::max(), | |
| 1425 30); // Use 30 fps to simulate webrtc. | |
|
Owen Lin
2013/11/04 10:20:04
It sounds like a parameter.
wuchengli
2013/11/04 10:44:29
There is no use case yet. But I changed it to a co
| |
| 1426 CreateAndStartDecoder(client, note); | |
| 1427 WaitUntilDecodeFinish(note); | |
| 1428 | |
| 1429 std::string output_string = | |
| 1430 base::StringPrintf("Avg decode time (ms)=%d", client->avg_decode_time()); | |
| 1431 LOG(INFO) << output_string; | |
| 1432 ASSERT_GT(client->avg_decode_time(), 0); | |
| 1433 ASSERT_LT(client->avg_decode_time(), 100); | |
| 1434 | |
| 1435 if (g_output_log != NULL) | |
| 1436 OutputLogFile(g_output_log, output_string); | |
| 1437 | |
| 1438 rendering_loop_proxy_->DeleteSoon(FROM_HERE, client); | |
| 1439 rendering_loop_proxy_->DeleteSoon(FROM_HERE, note); | |
| 1440 WaitUntilIdle(); | |
| 1441 }; | |
| 1442 | |
| 1280 // TODO(fischman, vrk): add more tests! In particular: | 1443 // TODO(fischman, vrk): add more tests! In particular: |
| 1281 // - Test life-cycle: Seek/Stop/Pause/Play for a single decoder. | 1444 // - Test life-cycle: Seek/Stop/Pause/Play for a single decoder. |
| 1282 // - Test alternate configurations | 1445 // - Test alternate configurations |
| 1283 // - Test failure conditions. | 1446 // - Test failure conditions. |
| 1284 // - Test frame size changes mid-stream | 1447 // - Test frame size changes mid-stream |
| 1285 | 1448 |
| 1286 } // namespace | 1449 } // namespace |
| 1287 } // namespace content | 1450 } // namespace content |
| 1288 | 1451 |
| 1289 int main(int argc, char **argv) { | 1452 int main(int argc, char **argv) { |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 1300 CommandLine* cmd_line = CommandLine::ForCurrentProcess(); | 1463 CommandLine* cmd_line = CommandLine::ForCurrentProcess(); |
| 1301 DCHECK(cmd_line); | 1464 DCHECK(cmd_line); |
| 1302 | 1465 |
| 1303 CommandLine::SwitchMap switches = cmd_line->GetSwitches(); | 1466 CommandLine::SwitchMap switches = cmd_line->GetSwitches(); |
| 1304 for (CommandLine::SwitchMap::const_iterator it = switches.begin(); | 1467 for (CommandLine::SwitchMap::const_iterator it = switches.begin(); |
| 1305 it != switches.end(); ++it) { | 1468 it != switches.end(); ++it) { |
| 1306 if (it->first == "test_video_data") { | 1469 if (it->first == "test_video_data") { |
| 1307 content::g_test_video_data = it->second.c_str(); | 1470 content::g_test_video_data = it->second.c_str(); |
| 1308 continue; | 1471 continue; |
| 1309 } | 1472 } |
| 1473 // TODO(wuchengli): remove this after CrOS test changes to output_log. | |
| 1310 if (it->first == "frame_delivery_log") { | 1474 if (it->first == "frame_delivery_log") { |
| 1311 content::g_frame_delivery_log = it->second.c_str(); | 1475 content::g_output_log = it->second.c_str(); |
| 1476 continue; | |
| 1477 } | |
| 1478 if (it->first == "output_log") { | |
| 1479 content::g_output_log = it->second.c_str(); | |
| 1312 continue; | 1480 continue; |
| 1313 } | 1481 } |
| 1314 if (it->first == "rendering_fps") { | 1482 if (it->first == "rendering_fps") { |
| 1315 // On Windows, CommandLine::StringType is wstring. We need to convert | 1483 // On Windows, CommandLine::StringType is wstring. We need to convert |
| 1316 // it to std::string first | 1484 // it to std::string first |
| 1317 std::string input(it->second.begin(), it->second.end()); | 1485 std::string input(it->second.begin(), it->second.end()); |
| 1318 CHECK(base::StringToDouble(input, &content::g_rendering_fps)); | 1486 CHECK(base::StringToDouble(input, &content::g_rendering_fps)); |
| 1319 continue; | 1487 continue; |
| 1320 } | 1488 } |
| 1321 if (it->first == "disable_rendering") { | 1489 if (it->first == "disable_rendering") { |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1334 #elif defined(OS_CHROMEOS) | 1502 #elif defined(OS_CHROMEOS) |
| 1335 #if defined(ARCH_CPU_ARMEL) | 1503 #if defined(ARCH_CPU_ARMEL) |
| 1336 content::ExynosVideoDecodeAccelerator::PreSandboxInitialization(); | 1504 content::ExynosVideoDecodeAccelerator::PreSandboxInitialization(); |
| 1337 #elif defined(ARCH_CPU_X86_FAMILY) | 1505 #elif defined(ARCH_CPU_X86_FAMILY) |
| 1338 content::VaapiWrapper::PreSandboxInitialization(); | 1506 content::VaapiWrapper::PreSandboxInitialization(); |
| 1339 #endif // ARCH_CPU_ARMEL | 1507 #endif // ARCH_CPU_ARMEL |
| 1340 #endif // OS_CHROMEOS | 1508 #endif // OS_CHROMEOS |
| 1341 | 1509 |
| 1342 return RUN_ALL_TESTS(); | 1510 return RUN_ALL_TESTS(); |
| 1343 } | 1511 } |
| OLD | NEW |