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 |
| (...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. |
|
Ami GONE FROM CHROMIUM
2014/05/28 16:09:26
s/supressed/suppressed/
| |
| 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_; |
| 322 bool render_as_thumbnails_; | |
| 323 bool pending_picture_updated_; | |
| 324 std::deque<int32> pending_picture_buffer_ids_; | |
| 472 | 325 |
| 473 DISALLOW_IMPLICIT_CONSTRUCTORS(GLRenderingVDAClient); | 326 DISALLOW_IMPLICIT_CONSTRUCTORS(GLRenderingVDAClient); |
| 474 }; | 327 }; |
| 475 | 328 |
| 476 GLRenderingVDAClient::GLRenderingVDAClient( | 329 GLRenderingVDAClient::GLRenderingVDAClient( |
| 477 RenderingHelper* rendering_helper, | 330 RenderingHelper* rendering_helper, |
| 478 int rendering_window_id, | 331 int rendering_window_id, |
| 479 ClientStateNotification<ClientState>* note, | 332 ClientStateNotification<ClientState>* note, |
| 480 const std::string& encoded_data, | 333 const std::string& encoded_data, |
| 481 int num_in_flight_decodes, | 334 int num_in_flight_decodes, |
| 482 int num_play_throughs, | 335 int num_play_throughs, |
| 483 int reset_after_frame_num, | 336 int reset_after_frame_num, |
| 484 int delete_decoder_state, | 337 int delete_decoder_state, |
| 485 int frame_width, | 338 int frame_width, |
| 486 int frame_height, | 339 int frame_height, |
| 487 media::VideoCodecProfile profile, | 340 media::VideoCodecProfile profile, |
| 488 double rendering_fps, | |
| 489 bool suppress_rendering, | 341 bool suppress_rendering, |
| 490 int delay_reuse_after_frame_num, | 342 int delay_reuse_after_frame_num, |
| 491 int decode_calls_per_second) | 343 int decode_calls_per_second, |
| 344 bool render_as_thumbnails) | |
| 492 : rendering_helper_(rendering_helper), | 345 : rendering_helper_(rendering_helper), |
| 493 rendering_window_id_(rendering_window_id), | 346 rendering_window_id_(rendering_window_id), |
| 494 encoded_data_(encoded_data), | 347 encoded_data_(encoded_data), |
| 495 num_in_flight_decodes_(num_in_flight_decodes), | 348 num_in_flight_decodes_(num_in_flight_decodes), |
| 496 outstanding_decodes_(0), | 349 outstanding_decodes_(0), |
| 497 encoded_data_next_pos_to_decode_(0), | 350 encoded_data_next_pos_to_decode_(0), |
| 498 next_bitstream_buffer_id_(0), | 351 next_bitstream_buffer_id_(0), |
| 499 note_(note), | 352 note_(note), |
| 500 remaining_play_throughs_(num_play_throughs), | 353 remaining_play_throughs_(num_play_throughs), |
| 501 reset_after_frame_num_(reset_after_frame_num), | 354 reset_after_frame_num_(reset_after_frame_num), |
| 502 delete_decoder_state_(delete_decoder_state), | 355 delete_decoder_state_(delete_decoder_state), |
| 503 state_(CS_CREATED), | 356 state_(CS_CREATED), |
| 504 num_skipped_fragments_(0), | 357 num_skipped_fragments_(0), |
| 505 num_queued_fragments_(0), | 358 num_queued_fragments_(0), |
| 506 num_decoded_frames_(0), | 359 num_decoded_frames_(0), |
| 507 num_done_bitstream_buffers_(0), | 360 num_done_bitstream_buffers_(0), |
| 508 texture_target_(0), | 361 texture_target_(0), |
| 509 suppress_rendering_(suppress_rendering), | 362 suppress_rendering_(suppress_rendering), |
| 510 delay_reuse_after_frame_num_(delay_reuse_after_frame_num), | 363 delay_reuse_after_frame_num_(delay_reuse_after_frame_num), |
| 511 decode_calls_per_second_(decode_calls_per_second) { | 364 decode_calls_per_second_(decode_calls_per_second), |
| 365 render_as_thumbnails_(render_as_thumbnails), | |
| 366 pending_picture_updated_(true) { | |
| 512 CHECK_GT(num_in_flight_decodes, 0); | 367 CHECK_GT(num_in_flight_decodes, 0); |
| 513 CHECK_GT(num_play_throughs, 0); | 368 CHECK_GT(num_play_throughs, 0); |
| 514 CHECK_GE(rendering_fps, 0); | |
| 515 // |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. |
| 516 if (decode_calls_per_second_ > 0) | 370 if (decode_calls_per_second_ > 0) |
| 517 CHECK_EQ(1, num_in_flight_decodes_); | 371 CHECK_EQ(1, num_in_flight_decodes_); |
| 518 | 372 |
| 519 // Default to H264 baseline if no profile provided. | 373 // Default to H264 baseline if no profile provided. |
| 520 profile_ = (profile != media::VIDEO_CODEC_PROFILE_UNKNOWN | 374 profile_ = (profile != media::VIDEO_CODEC_PROFILE_UNKNOWN |
| 521 ? profile | 375 ? profile |
| 522 : media::H264PROFILE_BASELINE); | 376 : media::H264PROFILE_BASELINE); |
| 523 | |
| 524 if (rendering_fps > 0) | |
| 525 throttling_client_.reset(new ThrottlingVDAClient( | |
| 526 this, | |
| 527 rendering_fps, | |
| 528 base::Bind(&GLRenderingVDAClient::NotifyFrameDropped, | |
| 529 base::Unretained(this)))); | |
| 530 } | 377 } |
| 531 | 378 |
| 532 GLRenderingVDAClient::~GLRenderingVDAClient() { | 379 GLRenderingVDAClient::~GLRenderingVDAClient() { |
| 533 DeleteDecoder(); // Clean up in case of expected error. | 380 DeleteDecoder(); // Clean up in case of expected error. |
| 534 CHECK(decoder_deleted()); | 381 CHECK(decoder_deleted()); |
| 535 STLDeleteValues(&picture_buffers_by_id_); | 382 STLDeleteValues(&picture_buffers_by_id_); |
| 536 SetState(CS_DESTROYED); | 383 SetState(CS_DESTROYED); |
| 537 } | 384 } |
| 538 | 385 |
| 539 static bool DoNothingReturnTrue() { return true; } | 386 static bool DoNothingReturnTrue() { return true; } |
| 540 | 387 |
| 541 void GLRenderingVDAClient::CreateAndStartDecoder() { | 388 void GLRenderingVDAClient::CreateAndStartDecoder() { |
| 542 CHECK(decoder_deleted()); | 389 CHECK(decoder_deleted()); |
| 543 CHECK(!decoder_.get()); | 390 CHECK(!decoder_.get()); |
| 544 | 391 |
| 545 VideoDecodeAccelerator::Client* client = this; | 392 VideoDecodeAccelerator::Client* client = this; |
| 546 base::WeakPtr<VideoDecodeAccelerator::Client> weak_client = AsWeakPtr(); | 393 base::WeakPtr<VideoDecodeAccelerator::Client> weak_client = AsWeakPtr(); |
| 547 if (throttling_client_) { | |
| 548 client = throttling_client_.get(); | |
| 549 weak_client = throttling_client_->AsWeakPtr(); | |
| 550 } | |
| 551 #if defined(OS_WIN) | 394 #if defined(OS_WIN) |
| 552 decoder_.reset( | 395 decoder_.reset( |
| 553 new DXVAVideoDecodeAccelerator(base::Bind(&DoNothingReturnTrue))); | 396 new DXVAVideoDecodeAccelerator(base::Bind(&DoNothingReturnTrue))); |
| 554 #elif defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) | 397 #elif defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) |
| 555 | 398 |
| 556 scoped_ptr<V4L2Device> device = V4L2Device::Create( | 399 scoped_ptr<V4L2Device> device = V4L2Device::Create( |
| 557 static_cast<EGLContext>(rendering_helper_->GetGLContext())); | 400 static_cast<EGLContext>(rendering_helper_->GetGLContext())); |
| 558 if (!device.get()) { | 401 if (!device.get()) { |
| 559 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); | 402 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); |
| 560 return; | 403 return; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 611 void GLRenderingVDAClient::DismissPictureBuffer(int32 picture_buffer_id) { | 454 void GLRenderingVDAClient::DismissPictureBuffer(int32 picture_buffer_id) { |
| 612 PictureBufferById::iterator it = | 455 PictureBufferById::iterator it = |
| 613 picture_buffers_by_id_.find(picture_buffer_id); | 456 picture_buffers_by_id_.find(picture_buffer_id); |
| 614 CHECK(it != picture_buffers_by_id_.end()); | 457 CHECK(it != picture_buffers_by_id_.end()); |
| 615 CHECK_EQ(outstanding_texture_ids_.erase(it->second->texture_id()), 1U); | 458 CHECK_EQ(outstanding_texture_ids_.erase(it->second->texture_id()), 1U); |
| 616 rendering_helper_->DeleteTexture(it->second->texture_id()); | 459 rendering_helper_->DeleteTexture(it->second->texture_id()); |
| 617 delete it->second; | 460 delete it->second; |
| 618 picture_buffers_by_id_.erase(it); | 461 picture_buffers_by_id_.erase(it); |
| 619 } | 462 } |
| 620 | 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 | |
| 621 void GLRenderingVDAClient::PictureReady(const media::Picture& picture) { | 496 void GLRenderingVDAClient::PictureReady(const media::Picture& picture) { |
| 622 // We shouldn't be getting pictures delivered after Reset has completed. | 497 // We shouldn't be getting pictures delivered after Reset has completed. |
| 623 CHECK_LT(state_, CS_RESET); | 498 CHECK_LT(state_, CS_RESET); |
| 624 | 499 |
| 625 if (decoder_deleted()) | 500 if (decoder_deleted()) |
| 626 return; | 501 return; |
| 627 | 502 |
| 628 base::TimeTicks now = base::TimeTicks::Now(); | 503 base::TimeTicks now = base::TimeTicks::Now(); |
| 629 frame_delivery_times_.push_back(now); | |
| 630 // Save the decode time of this picture. | 504 // Save the decode time of this picture. |
| 631 std::map<int, base::TimeTicks>::iterator it = | 505 std::map<int, base::TimeTicks>::iterator it = |
| 632 decode_start_time_.find(picture.bitstream_buffer_id()); | 506 decode_start_time_.find(picture.bitstream_buffer_id()); |
| 633 ASSERT_NE(decode_start_time_.end(), it); | 507 ASSERT_NE(decode_start_time_.end(), it); |
| 634 decode_time_.push_back(now - it->second); | 508 decode_time_.push_back(now - it->second); |
| 635 decode_start_time_.erase(it); | 509 decode_start_time_.erase(it); |
| 636 | 510 |
| 637 CHECK_LE(picture.bitstream_buffer_id(), next_bitstream_buffer_id_); | 511 CHECK_LE(picture.bitstream_buffer_id(), next_bitstream_buffer_id_); |
| 638 ++num_decoded_frames_; | 512 ++num_decoded_frames_; |
| 639 | 513 |
| 640 // 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 |
| 641 // comment. | 515 // comment. |
| 642 if (remaining_play_throughs_ == 1 && | 516 if (remaining_play_throughs_ == 1 && |
| 643 reset_after_frame_num_ == num_decoded_frames()) { | 517 reset_after_frame_num_ == num_decoded_frames_) { |
| 644 reset_after_frame_num_ = MID_STREAM_RESET; | 518 reset_after_frame_num_ = MID_STREAM_RESET; |
| 645 decoder_->Reset(); | 519 decoder_->Reset(); |
| 646 // 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 |
| 647 // 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. |
| 648 encoded_data_next_pos_to_decode_ = 0; | 522 encoded_data_next_pos_to_decode_ = 0; |
| 649 } | 523 } |
| 650 | 524 |
| 651 media::PictureBuffer* picture_buffer = | 525 if (render_as_thumbnails_) { |
| 652 picture_buffers_by_id_[picture.picture_buffer_id()]; | 526 frame_delivery_times_.push_back(now); |
| 653 CHECK(picture_buffer); | 527 media::PictureBuffer* picture_buffer = |
| 654 if (!suppress_rendering_) { | 528 picture_buffers_by_id_[picture.picture_buffer_id()]; |
| 655 rendering_helper_->RenderTexture(texture_target_, | 529 CHECK(picture_buffer); |
| 656 picture_buffer->texture_id()); | 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()); | |
| 657 } | 544 } |
| 545 } | |
| 658 | 546 |
| 659 if (num_decoded_frames() > delay_reuse_after_frame_num_) { | 547 void GLRenderingVDAClient::ReturnPicture(int32 picture_buffer_id) { |
| 548 if (decoder_deleted()) | |
| 549 return; | |
| 550 if (num_decoded_frames_ > delay_reuse_after_frame_num_) { | |
| 660 base::MessageLoop::current()->PostDelayedTask( | 551 base::MessageLoop::current()->PostDelayedTask( |
| 661 FROM_HERE, | 552 FROM_HERE, |
| 662 base::Bind(&VideoDecodeAccelerator::ReusePictureBuffer, | 553 base::Bind(&VideoDecodeAccelerator::ReusePictureBuffer, |
| 663 weak_decoder_factory_->GetWeakPtr(), | 554 weak_decoder_factory_->GetWeakPtr(), |
| 664 picture.picture_buffer_id()), | 555 picture_buffer_id), |
| 665 kReuseDelay); | 556 kReuseDelay); |
| 666 } else { | 557 } else { |
| 667 decoder_->ReusePictureBuffer(picture.picture_buffer_id()); | 558 decoder_->ReusePictureBuffer(picture_buffer_id); |
| 668 } | 559 } |
| 669 } | 560 } |
| 670 | 561 |
| 671 void GLRenderingVDAClient::NotifyEndOfBitstreamBuffer( | 562 void GLRenderingVDAClient::NotifyEndOfBitstreamBuffer( |
| 672 int32 bitstream_buffer_id) { | 563 int32 bitstream_buffer_id) { |
| 673 // TODO(fischman): this test currently relies on this notification to make | 564 // TODO(fischman): this test currently relies on this notification to make |
| 674 // 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 |
| 675 // 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 |
| 676 // VaapiVideoDecodeAccelerator::FinishReset()). | 567 // VaapiVideoDecodeAccelerator::FinishReset()). |
| 677 ++num_done_bitstream_buffers_; | 568 ++num_done_bitstream_buffers_; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 689 if (decoder_deleted()) | 580 if (decoder_deleted()) |
| 690 return; | 581 return; |
| 691 decoder_->Reset(); | 582 decoder_->Reset(); |
| 692 SetState(CS_RESETTING); | 583 SetState(CS_RESETTING); |
| 693 } | 584 } |
| 694 | 585 |
| 695 void GLRenderingVDAClient::NotifyResetDone() { | 586 void GLRenderingVDAClient::NotifyResetDone() { |
| 696 if (decoder_deleted()) | 587 if (decoder_deleted()) |
| 697 return; | 588 return; |
| 698 | 589 |
| 590 // Clear pending_pictures and reuse them. | |
| 591 while (!pending_picture_buffer_ids_.empty()) { | |
| 592 decoder_->ReusePictureBuffer(pending_picture_buffer_ids_.front()); | |
| 593 pending_picture_buffer_ids_.pop_front(); | |
| 594 } | |
| 595 pending_picture_updated_ = true; | |
| 596 | |
| 699 if (reset_after_frame_num_ == MID_STREAM_RESET) { | 597 if (reset_after_frame_num_ == MID_STREAM_RESET) { |
| 700 reset_after_frame_num_ = END_OF_STREAM_RESET; | 598 reset_after_frame_num_ = END_OF_STREAM_RESET; |
| 701 DecodeNextFragment(); | 599 DecodeNextFragment(); |
| 702 return; | 600 return; |
| 703 } else if (reset_after_frame_num_ == START_OF_STREAM_RESET) { | 601 } else if (reset_after_frame_num_ == START_OF_STREAM_RESET) { |
| 704 reset_after_frame_num_ = END_OF_STREAM_RESET; | 602 reset_after_frame_num_ = END_OF_STREAM_RESET; |
| 705 for (int i = 0; i < num_in_flight_decodes_; ++i) | 603 for (int i = 0; i < num_in_flight_decodes_; ++i) |
| 706 DecodeNextFragment(); | 604 DecodeNextFragment(); |
| 707 return; | 605 return; |
| 708 } | 606 } |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 931 } | 829 } |
| 932 | 830 |
| 933 if (decode_calls_per_second_ > 0) { | 831 if (decode_calls_per_second_ > 0) { |
| 934 base::MessageLoop::current()->PostDelayedTask( | 832 base::MessageLoop::current()->PostDelayedTask( |
| 935 FROM_HERE, | 833 FROM_HERE, |
| 936 base::Bind(&GLRenderingVDAClient::DecodeNextFragment, AsWeakPtr()), | 834 base::Bind(&GLRenderingVDAClient::DecodeNextFragment, AsWeakPtr()), |
| 937 base::TimeDelta::FromSeconds(1) / decode_calls_per_second_); | 835 base::TimeDelta::FromSeconds(1) / decode_calls_per_second_); |
| 938 } | 836 } |
| 939 } | 837 } |
| 940 | 838 |
| 941 int GLRenderingVDAClient::num_decoded_frames() { | |
| 942 return throttling_client_ ? throttling_client_->num_decoded_frames() | |
| 943 : num_decoded_frames_; | |
| 944 } | |
| 945 | |
| 946 double GLRenderingVDAClient::frames_per_second() { | 839 double GLRenderingVDAClient::frames_per_second() { |
| 947 base::TimeDelta delta = frame_delivery_times_.back() - initialize_done_ticks_; | 840 base::TimeDelta delta = frame_delivery_times_.back() - initialize_done_ticks_; |
| 948 return num_decoded_frames() / delta.InSecondsF(); | 841 return num_decoded_frames_ / delta.InSecondsF(); |
| 949 } | 842 } |
| 950 | 843 |
| 951 base::TimeDelta GLRenderingVDAClient::decode_time_median() { | 844 base::TimeDelta GLRenderingVDAClient::decode_time_median() { |
| 952 if (decode_time_.size() == 0) | 845 if (decode_time_.size() == 0) |
| 953 return base::TimeDelta(); | 846 return base::TimeDelta(); |
| 954 std::sort(decode_time_.begin(), decode_time_.end()); | 847 std::sort(decode_time_.begin(), decode_time_.end()); |
| 955 int index = decode_time_.size() / 2; | 848 int index = decode_time_.size() / 2; |
| 956 if (decode_time_.size() % 2 != 0) | 849 if (decode_time_.size() % 2 != 0) |
| 957 return decode_time_[index]; | 850 return decode_time_[index]; |
| 958 | 851 |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1192 const size_t num_in_flight_decodes = GetParam().b; | 1085 const size_t num_in_flight_decodes = GetParam().b; |
| 1193 const int num_play_throughs = GetParam().c; | 1086 const int num_play_throughs = GetParam().c; |
| 1194 const int reset_point = GetParam().d; | 1087 const int reset_point = GetParam().d; |
| 1195 const int delete_decoder_state = GetParam().e; | 1088 const int delete_decoder_state = GetParam().e; |
| 1196 bool test_reuse_delay = GetParam().f; | 1089 bool test_reuse_delay = GetParam().f; |
| 1197 const bool render_as_thumbnails = GetParam().g; | 1090 const bool render_as_thumbnails = GetParam().g; |
| 1198 | 1091 |
| 1199 UpdateTestVideoFileParams( | 1092 UpdateTestVideoFileParams( |
| 1200 num_concurrent_decoders, reset_point, &test_video_files_); | 1093 num_concurrent_decoders, reset_point, &test_video_files_); |
| 1201 | 1094 |
| 1202 // Suppress GL rendering for all tests when the "--disable_rendering" is set. | 1095 // Suppress GL rendering for all tests when the "--rendering_fps" is 0. |
| 1203 const bool suppress_rendering = g_disable_rendering; | 1096 const bool suppress_rendering = g_rendering_fps == 0; |
| 1204 | 1097 |
| 1205 std::vector<ClientStateNotification<ClientState>*> | 1098 std::vector<ClientStateNotification<ClientState>*> |
| 1206 notes(num_concurrent_decoders, NULL); | 1099 notes(num_concurrent_decoders, NULL); |
| 1207 std::vector<GLRenderingVDAClient*> clients(num_concurrent_decoders, NULL); | 1100 std::vector<GLRenderingVDAClient*> clients(num_concurrent_decoders, NULL); |
| 1208 | 1101 |
| 1209 RenderingHelperParams helper_params; | 1102 RenderingHelperParams helper_params; |
| 1103 helper_params.rendering_fps = g_rendering_fps; | |
| 1210 helper_params.num_windows = num_concurrent_decoders; | 1104 helper_params.num_windows = num_concurrent_decoders; |
| 1211 helper_params.render_as_thumbnails = render_as_thumbnails; | 1105 helper_params.render_as_thumbnails = render_as_thumbnails; |
| 1212 if (render_as_thumbnails) { | 1106 if (render_as_thumbnails) { |
| 1213 // Only one decoder is supported with thumbnail rendering | 1107 // Only one decoder is supported with thumbnail rendering |
| 1214 CHECK_EQ(num_concurrent_decoders, 1U); | 1108 CHECK_EQ(num_concurrent_decoders, 1U); |
| 1215 gfx::Size frame_size(test_video_files_[0]->width, | 1109 gfx::Size frame_size(test_video_files_[0]->width, |
| 1216 test_video_files_[0]->height); | 1110 test_video_files_[0]->height); |
| 1217 helper_params.frame_dimensions.push_back(frame_size); | 1111 helper_params.frame_dimensions.push_back(frame_size); |
| 1218 helper_params.window_dimensions.push_back(kThumbnailsDisplaySize); | 1112 helper_params.window_dimensions.push_back(kThumbnailsDisplaySize); |
| 1219 helper_params.thumbnails_page_size = kThumbnailsPageSize; | 1113 helper_params.thumbnails_page_size = kThumbnailsPageSize; |
| 1220 helper_params.thumbnail_size = kThumbnailSize; | 1114 helper_params.thumbnail_size = kThumbnailSize; |
| 1221 } else { | 1115 } else { |
| 1222 for (size_t index = 0; index < test_video_files_.size(); ++index) { | 1116 for (size_t index = 0; index < test_video_files_.size(); ++index) { |
| 1223 gfx::Size frame_size(test_video_files_[index]->width, | 1117 gfx::Size frame_size(test_video_files_[index]->width, |
| 1224 test_video_files_[index]->height); | 1118 test_video_files_[index]->height); |
| 1225 helper_params.frame_dimensions.push_back(frame_size); | 1119 helper_params.frame_dimensions.push_back(frame_size); |
| 1226 helper_params.window_dimensions.push_back(frame_size); | 1120 helper_params.window_dimensions.push_back(frame_size); |
| 1227 } | 1121 } |
| 1228 } | 1122 } |
| 1229 InitializeRenderingHelper(helper_params); | |
| 1230 | 1123 |
| 1231 // First kick off all the decoders. | 1124 // First kick off all the decoders. |
| 1232 for (size_t index = 0; index < num_concurrent_decoders; ++index) { | 1125 for (size_t index = 0; index < num_concurrent_decoders; ++index) { |
| 1233 TestVideoFile* video_file = | 1126 TestVideoFile* video_file = |
| 1234 test_video_files_[index % test_video_files_.size()]; | 1127 test_video_files_[index % test_video_files_.size()]; |
| 1235 ClientStateNotification<ClientState>* note = | 1128 ClientStateNotification<ClientState>* note = |
| 1236 new ClientStateNotification<ClientState>(); | 1129 new ClientStateNotification<ClientState>(); |
| 1237 notes[index] = note; | 1130 notes[index] = note; |
| 1238 | 1131 |
| 1239 int delay_after_frame_num = std::numeric_limits<int>::max(); | 1132 int delay_after_frame_num = std::numeric_limits<int>::max(); |
| 1240 if (test_reuse_delay && | 1133 if (test_reuse_delay && |
| 1241 kMaxFramesToDelayReuse * 2 < video_file->num_frames) { | 1134 kMaxFramesToDelayReuse * 2 < video_file->num_frames) { |
| 1242 delay_after_frame_num = video_file->num_frames - kMaxFramesToDelayReuse; | 1135 delay_after_frame_num = video_file->num_frames - kMaxFramesToDelayReuse; |
| 1243 } | 1136 } |
| 1244 | 1137 |
| 1245 GLRenderingVDAClient* client = | 1138 GLRenderingVDAClient* client = |
| 1246 new GLRenderingVDAClient(&rendering_helper_, | 1139 new GLRenderingVDAClient(&rendering_helper_, |
| 1247 index, | 1140 index, |
| 1248 note, | 1141 note, |
| 1249 video_file->data_str, | 1142 video_file->data_str, |
| 1250 num_in_flight_decodes, | 1143 num_in_flight_decodes, |
| 1251 num_play_throughs, | 1144 num_play_throughs, |
| 1252 video_file->reset_after_frame_num, | 1145 video_file->reset_after_frame_num, |
| 1253 delete_decoder_state, | 1146 delete_decoder_state, |
| 1254 video_file->width, | 1147 video_file->width, |
| 1255 video_file->height, | 1148 video_file->height, |
| 1256 video_file->profile, | 1149 video_file->profile, |
| 1257 g_rendering_fps, | |
| 1258 suppress_rendering, | 1150 suppress_rendering, |
| 1259 delay_after_frame_num, | 1151 delay_after_frame_num, |
| 1260 0); | 1152 0, |
| 1153 render_as_thumbnails); | |
| 1154 | |
| 1261 clients[index] = client; | 1155 clients[index] = client; |
| 1156 helper_params.clients.push_back(client->AsWeakPtr()); | |
| 1157 } | |
| 1262 | 1158 |
| 1263 CreateAndStartDecoder(client, note); | 1159 InitializeRenderingHelper(helper_params); |
| 1160 | |
| 1161 for (size_t index = 0; index < num_concurrent_decoders; ++index) { | |
| 1162 CreateAndStartDecoder(clients[index], notes[index]); | |
| 1264 } | 1163 } |
| 1164 | |
| 1265 // Then wait for all the decodes to finish. | 1165 // Then wait for all the decodes to finish. |
| 1266 // Only check performance & correctness later if we play through only once. | 1166 // Only check performance & correctness later if we play through only once. |
| 1267 bool skip_performance_and_correctness_checks = num_play_throughs > 1; | 1167 bool skip_performance_and_correctness_checks = num_play_throughs > 1; |
| 1268 for (size_t i = 0; i < num_concurrent_decoders; ++i) { | 1168 for (size_t i = 0; i < num_concurrent_decoders; ++i) { |
| 1269 ClientStateNotification<ClientState>* note = notes[i]; | 1169 ClientStateNotification<ClientState>* note = notes[i]; |
| 1270 ClientState state = note->Wait(); | 1170 ClientState state = note->Wait(); |
| 1271 if (state != CS_INITIALIZED) { | 1171 if (state != CS_INITIALIZED) { |
| 1272 skip_performance_and_correctness_checks = true; | 1172 skip_performance_and_correctness_checks = true; |
| 1273 // We expect initialization to fail only when more than the supported | 1173 // We expect initialization to fail only when more than the supported |
| 1274 // number of decoders is instantiated. Assert here that something else | 1174 // number of decoders is instantiated. Assert here that something else |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1471 // Thumbnailing test | 1371 // Thumbnailing test |
| 1472 INSTANTIATE_TEST_CASE_P( | 1372 INSTANTIATE_TEST_CASE_P( |
| 1473 Thumbnail, VideoDecodeAcceleratorParamTest, | 1373 Thumbnail, VideoDecodeAcceleratorParamTest, |
| 1474 ::testing::Values( | 1374 ::testing::Values( |
| 1475 MakeTuple(1, 1, 1, END_OF_STREAM_RESET, CS_RESET, false, true))); | 1375 MakeTuple(1, 1, 1, END_OF_STREAM_RESET, CS_RESET, false, true))); |
| 1476 | 1376 |
| 1477 // Measure the median of the decode time when VDA::Decode is called 30 times per | 1377 // Measure the median of the decode time when VDA::Decode is called 30 times per |
| 1478 // second. | 1378 // second. |
| 1479 TEST_F(VideoDecodeAcceleratorTest, TestDecodeTimeMedian) { | 1379 TEST_F(VideoDecodeAcceleratorTest, TestDecodeTimeMedian) { |
| 1480 RenderingHelperParams helper_params; | 1380 RenderingHelperParams helper_params; |
| 1381 | |
| 1382 // Disable rendering by setting the rendering_fps = 0. | |
| 1383 helper_params.rendering_fps = 0; | |
| 1481 helper_params.num_windows = 1; | 1384 helper_params.num_windows = 1; |
| 1482 helper_params.render_as_thumbnails = false; | 1385 helper_params.render_as_thumbnails = false; |
| 1483 gfx::Size frame_size(test_video_files_[0]->width, | 1386 gfx::Size frame_size(test_video_files_[0]->width, |
| 1484 test_video_files_[0]->height); | 1387 test_video_files_[0]->height); |
| 1485 helper_params.frame_dimensions.push_back(frame_size); | 1388 helper_params.frame_dimensions.push_back(frame_size); |
| 1486 helper_params.window_dimensions.push_back(frame_size); | 1389 helper_params.window_dimensions.push_back(frame_size); |
| 1487 InitializeRenderingHelper(helper_params); | |
| 1488 | 1390 |
| 1489 ClientStateNotification<ClientState>* note = | 1391 ClientStateNotification<ClientState>* note = |
| 1490 new ClientStateNotification<ClientState>(); | 1392 new ClientStateNotification<ClientState>(); |
| 1491 GLRenderingVDAClient* client = | 1393 GLRenderingVDAClient* client = |
| 1492 new GLRenderingVDAClient(&rendering_helper_, | 1394 new GLRenderingVDAClient(&rendering_helper_, |
| 1493 0, | 1395 0, |
| 1494 note, | 1396 note, |
| 1495 test_video_files_[0]->data_str, | 1397 test_video_files_[0]->data_str, |
| 1496 1, | 1398 1, |
| 1497 1, | 1399 1, |
| 1498 test_video_files_[0]->reset_after_frame_num, | 1400 test_video_files_[0]->reset_after_frame_num, |
| 1499 CS_RESET, | 1401 CS_RESET, |
| 1500 test_video_files_[0]->width, | 1402 test_video_files_[0]->width, |
| 1501 test_video_files_[0]->height, | 1403 test_video_files_[0]->height, |
| 1502 test_video_files_[0]->profile, | 1404 test_video_files_[0]->profile, |
| 1503 g_rendering_fps, | |
| 1504 true, | 1405 true, |
| 1505 std::numeric_limits<int>::max(), | 1406 std::numeric_limits<int>::max(), |
| 1506 kWebRtcDecodeCallsPerSecond); | 1407 kWebRtcDecodeCallsPerSecond, |
| 1408 false /* render_as_thumbnail */); | |
| 1409 helper_params.clients.push_back(client->AsWeakPtr()); | |
| 1410 InitializeRenderingHelper(helper_params); | |
| 1507 CreateAndStartDecoder(client, note); | 1411 CreateAndStartDecoder(client, note); |
| 1508 WaitUntilDecodeFinish(note); | 1412 WaitUntilDecodeFinish(note); |
| 1509 | 1413 |
| 1510 base::TimeDelta decode_time_median = client->decode_time_median(); | 1414 base::TimeDelta decode_time_median = client->decode_time_median(); |
| 1511 std::string output_string = | 1415 std::string output_string = |
| 1512 base::StringPrintf("Decode time median: %" PRId64 " us", | 1416 base::StringPrintf("Decode time median: %" PRId64 " us", |
| 1513 decode_time_median.InMicroseconds()); | 1417 decode_time_median.InMicroseconds()); |
| 1514 LOG(INFO) << output_string; | 1418 LOG(INFO) << output_string; |
| 1515 | 1419 |
| 1516 if (g_output_log != NULL) | 1420 if (g_output_log != NULL) |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1554 content::g_output_log = it->second.c_str(); | 1458 content::g_output_log = it->second.c_str(); |
| 1555 continue; | 1459 continue; |
| 1556 } | 1460 } |
| 1557 if (it->first == "rendering_fps") { | 1461 if (it->first == "rendering_fps") { |
| 1558 // On Windows, CommandLine::StringType is wstring. We need to convert | 1462 // On Windows, CommandLine::StringType is wstring. We need to convert |
| 1559 // it to std::string first | 1463 // it to std::string first |
| 1560 std::string input(it->second.begin(), it->second.end()); | 1464 std::string input(it->second.begin(), it->second.end()); |
| 1561 CHECK(base::StringToDouble(input, &content::g_rendering_fps)); | 1465 CHECK(base::StringToDouble(input, &content::g_rendering_fps)); |
| 1562 continue; | 1466 continue; |
| 1563 } | 1467 } |
| 1468 // TODO(owenlin): Remove this flag once it is not used in autotest. | |
| 1564 if (it->first == "disable_rendering") { | 1469 if (it->first == "disable_rendering") { |
| 1565 content::g_disable_rendering = true; | 1470 content::g_rendering_fps = 0; |
| 1566 continue; | 1471 continue; |
| 1567 } | 1472 } |
| 1568 if (it->first == "v" || it->first == "vmodule") | 1473 if (it->first == "v" || it->first == "vmodule") |
| 1569 continue; | 1474 continue; |
| 1570 LOG(FATAL) << "Unexpected switch: " << it->first << ":" << it->second; | 1475 LOG(FATAL) << "Unexpected switch: " << it->first << ":" << it->second; |
| 1571 } | 1476 } |
| 1572 | 1477 |
| 1573 base::ShadowingAtExitManager at_exit_manager; | 1478 base::ShadowingAtExitManager at_exit_manager; |
| 1574 | 1479 |
| 1575 return RUN_ALL_TESTS(); | 1480 return RUN_ALL_TESTS(); |
| 1576 } | 1481 } |
| OLD | NEW |