| 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 |