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

Side by Side Diff: content/common/gpu/media/video_decode_accelerator_unittest.cc

Issue 10808058: Add support for VP8 decode to OmxVideoDecodeAccelerator, for HW that supports it. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: scherkus comments. Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 #error The VideoAccelerator tests are not supported on this platform. 53 #error The VideoAccelerator tests are not supported on this platform.
54 #endif // defined(OS_WIN) 54 #endif // defined(OS_WIN)
55 55
56 using media::VideoDecodeAccelerator; 56 using media::VideoDecodeAccelerator;
57 using video_test_util::RenderingHelper; 57 using video_test_util::RenderingHelper;
58 58
59 namespace { 59 namespace {
60 60
61 // Values optionally filled in from flags; see main() below. 61 // Values optionally filled in from flags; see main() below.
62 // The syntax of this variable is: 62 // The syntax of this variable is:
63 // filename:width:height:numframes:numNALUs:minFPSwithRender:minFPSnoRender 63 // filename:width:height:numframes:numfragments:minFPSwithRender:minFPSnoRender
64 // where only the first field is required. Value details: 64 // where only the first field is required. Value details:
65 // - |filename| must be an h264 Annex B (NAL) stream. 65 // - |filename| must be an h264 Annex B (NAL) stream or an IVF VP8 stream.
66 // - |width| and |height| are in pixels. 66 // - |width| and |height| are in pixels.
67 // - |numframes| is the number of picture frames in the file. 67 // - |numframes| is the number of picture frames in the file.
68 // - |numNALUs| is the number of NAL units in the stream. 68 // - |numfragments| NALU (h264) or frame (VP8) count in the stream.
69 // - |minFPSwithRender| and |minFPSnoRender| are minimum frames/second speeds 69 // - |minFPSwithRender| and |minFPSnoRender| are minimum frames/second speeds
70 // expected to be achieved with and without rendering to the screen, resp. 70 // expected to be achieved with and without rendering to the screen, resp.
71 // (the latter tests just decode speed). 71 // (the latter tests just decode speed).
72 // - |profile| is the media::H264Profile set during Initialization. 72 // - |profile| is the media::VideoCodecProfile set during Initialization.
73 // An empty value for a numeric field means "ignore". 73 // An empty value for a numeric field means "ignore".
74 #if defined(OS_MACOSX) 74 #if defined(OS_MACOSX)
75 const FilePath::CharType* test_video_data = 75 const FilePath::CharType* test_video_data =
76 FILE_PATH_LITERAL("test-25fps_high.h264:1280:720:250:252:50:100:4"); 76 FILE_PATH_LITERAL("test-25fps_high.h264:1280:720:250:252:50:100:4");
77 #else 77 #else
78 // TODO(fischman): figure out how to support multiple test videos per run (needs
79 // to refactor where ParseTestVideoData is called). For now just make it easy
80 // to replace which file is used by commenting/uncommenting these lines:
78 const FilePath::CharType* test_video_data = 81 const FilePath::CharType* test_video_data =
82 // FILE_PATH_LITERAL("test-25fps.vp8:320:240:250:250:50:175:11");
79 FILE_PATH_LITERAL("test-25fps.h264:320:240:250:258:50:175:1"); 83 FILE_PATH_LITERAL("test-25fps.h264:320:240:250:258:50:175:1");
80 #endif 84 #endif
81 85
82 // Parse |data| into its constituent parts and set the various output fields 86 // Parse |data| into its constituent parts and set the various output fields
83 // accordingly. CHECK-fails on unexpected or missing required data. 87 // accordingly. CHECK-fails on unexpected or missing required data.
84 // Unspecified optional fields are set to -1. 88 // Unspecified optional fields are set to -1.
85 void ParseTestVideoData(FilePath::StringType data, 89 void ParseTestVideoData(FilePath::StringType data,
86 FilePath::StringType* file_name, 90 FilePath::StringType* file_name,
87 int* width, int* height, 91 int* width, int* height,
88 int* num_frames, 92 int* num_frames,
89 int* num_NALUs, 93 int* num_fragments,
90 int* min_fps_render, 94 int* min_fps_render,
91 int* min_fps_no_render, 95 int* min_fps_no_render,
92 int* profile) { 96 int* profile) {
93 std::vector<FilePath::StringType> elements; 97 std::vector<FilePath::StringType> elements;
94 base::SplitString(data, ':', &elements); 98 base::SplitString(data, ':', &elements);
95 CHECK_GE(elements.size(), 1U) << data; 99 CHECK_GE(elements.size(), 1U) << data;
96 CHECK_LE(elements.size(), 8U) << data; 100 CHECK_LE(elements.size(), 8U) << data;
97 *file_name = elements[0]; 101 *file_name = elements[0];
98 *width = *height = *num_frames = *num_NALUs = -1; 102 *width = *height = *num_frames = *num_fragments = -1;
99 *min_fps_render = *min_fps_no_render = -1; 103 *min_fps_render = *min_fps_no_render = -1;
100 *profile = -1; 104 *profile = -1;
101 if (!elements[1].empty()) 105 if (!elements[1].empty())
102 CHECK(base::StringToInt(elements[1], width)); 106 CHECK(base::StringToInt(elements[1], width));
103 if (!elements[2].empty()) 107 if (!elements[2].empty())
104 CHECK(base::StringToInt(elements[2], height)); 108 CHECK(base::StringToInt(elements[2], height));
105 if (!elements[3].empty()) 109 if (!elements[3].empty())
106 CHECK(base::StringToInt(elements[3], num_frames)); 110 CHECK(base::StringToInt(elements[3], num_frames));
107 if (!elements[4].empty()) 111 if (!elements[4].empty())
108 CHECK(base::StringToInt(elements[4], num_NALUs)); 112 CHECK(base::StringToInt(elements[4], num_fragments));
109 if (!elements[5].empty()) 113 if (!elements[5].empty())
110 CHECK(base::StringToInt(elements[5], min_fps_render)); 114 CHECK(base::StringToInt(elements[5], min_fps_render));
111 if (!elements[6].empty()) 115 if (!elements[6].empty())
112 CHECK(base::StringToInt(elements[6], min_fps_no_render)); 116 CHECK(base::StringToInt(elements[6], min_fps_no_render));
113 if (!elements[7].empty()) 117 if (!elements[7].empty())
114 CHECK(base::StringToInt(elements[7], profile)); 118 CHECK(base::StringToInt(elements[7], profile));
115 } 119 }
116 120
117 // State of the GLRenderingVDAClient below. Order matters here as the test 121 // State of the GLRenderingVDAClient below. Order matters here as the test
118 // makes assumptions about it. 122 // makes assumptions about it.
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 MID_STREAM_RESET = -2, 178 MID_STREAM_RESET = -2,
175 END_OF_STREAM_RESET = -1 179 END_OF_STREAM_RESET = -1
176 }; 180 };
177 181
178 // Client that can accept callbacks from a VideoDecodeAccelerator and is used by 182 // Client that can accept callbacks from a VideoDecodeAccelerator and is used by
179 // the TESTs below. 183 // the TESTs below.
180 class GLRenderingVDAClient : public VideoDecodeAccelerator::Client { 184 class GLRenderingVDAClient : public VideoDecodeAccelerator::Client {
181 public: 185 public:
182 // Doesn't take ownership of |rendering_helper| or |note|, which must outlive 186 // Doesn't take ownership of |rendering_helper| or |note|, which must outlive
183 // |*this|. 187 // |*this|.
188 // |num_fragments_per_decode| counts NALUs for h264 and frames for VP8.
184 // |num_play_throughs| indicates how many times to play through the video. 189 // |num_play_throughs| indicates how many times to play through the video.
185 // |reset_after_frame_num| can be a frame number >=0 indicating a mid-stream 190 // |reset_after_frame_num| can be a frame number >=0 indicating a mid-stream
186 // Reset() should be done after that frame number is delivered, or 191 // Reset() should be done after that frame number is delivered, or
187 // END_OF_STREAM_RESET to indicate no mid-stream Reset(). 192 // END_OF_STREAM_RESET to indicate no mid-stream Reset().
188 // |delete_decoder_state| indicates when the underlying decoder should be 193 // |delete_decoder_state| indicates when the underlying decoder should be
189 // Destroy()'d and deleted and can take values: N<0: delete after -N Decode() 194 // Destroy()'d and deleted and can take values: N<0: delete after -N Decode()
190 // calls have been made, N>=0 means interpret as ClientState. 195 // calls have been made, N>=0 means interpret as ClientState.
191 // Both |reset_after_frame_num| & |delete_decoder_state| apply only to the 196 // Both |reset_after_frame_num| & |delete_decoder_state| apply only to the
192 // last play-through (governed by |num_play_throughs|). 197 // last play-through (governed by |num_play_throughs|).
193 GLRenderingVDAClient(RenderingHelper* rendering_helper, 198 GLRenderingVDAClient(RenderingHelper* rendering_helper,
194 int rendering_window_id, 199 int rendering_window_id,
195 ClientStateNotification* note, 200 ClientStateNotification* note,
196 const std::string& encoded_data, 201 const std::string& encoded_data,
197 int num_NALUs_per_decode, 202 int num_fragments_per_decode,
198 int num_in_flight_decodes, 203 int num_in_flight_decodes,
199 int num_play_throughs, 204 int num_play_throughs,
200 int reset_after_frame_num, 205 int reset_after_frame_num,
201 int delete_decoder_state, 206 int delete_decoder_state,
202 int frame_width, 207 int frame_width,
203 int frame_height, 208 int frame_height,
204 int profile); 209 int profile);
205 virtual ~GLRenderingVDAClient(); 210 virtual ~GLRenderingVDAClient();
206 void CreateDecoder(); 211 void CreateDecoder();
207 212
(...skipping 19 matching lines...) Expand all
227 bool decoder_deleted() { return !decoder_.get(); } 232 bool decoder_deleted() { return !decoder_.get(); }
228 233
229 private: 234 private:
230 typedef std::map<int, media::PictureBuffer*> PictureBufferById; 235 typedef std::map<int, media::PictureBuffer*> PictureBufferById;
231 236
232 void SetState(ClientState new_state); 237 void SetState(ClientState new_state);
233 238
234 // Delete the associated OMX decoder helper. 239 // Delete the associated OMX decoder helper.
235 void DeleteDecoder(); 240 void DeleteDecoder();
236 241
237 // Compute & return in |*end_pos| the end position for the next batch of NALUs 242 // Compute & return in |*end_pos| the end position for the next batch of
238 // to ship to the decoder (based on |start_pos| & |num_NALUs_per_decode_|). 243 // fragments to ship to the decoder (based on |start_pos| &
239 void GetRangeForNextNALUs(size_t start_pos, size_t* end_pos); 244 // |num_fragments_per_decode_|).
245 void GetRangeForNextFragments(size_t start_pos, size_t* end_pos);
246 // Helpers for GetRangeForNextFragments above.
247 void GetRangeForNextNALUs(size_t start_pos, size_t* end_pos); // For h.264.
248 void GetRangeForNextFrames(size_t start_pos, size_t* end_pos); // For VP8.
240 249
241 // Request decode of the next batch of NALUs in the encoded data. 250 // Request decode of the next batch of fragments in the encoded data.
242 void DecodeNextNALUs(); 251 void DecodeNextFragments();
243 252
244 RenderingHelper* rendering_helper_; 253 RenderingHelper* rendering_helper_;
245 int rendering_window_id_; 254 int rendering_window_id_;
246 std::string encoded_data_; 255 std::string encoded_data_;
247 const int num_NALUs_per_decode_; 256 const int num_fragments_per_decode_;
248 const int num_in_flight_decodes_; 257 const int num_in_flight_decodes_;
249 int outstanding_decodes_; 258 int outstanding_decodes_;
250 size_t encoded_data_next_pos_to_decode_; 259 size_t encoded_data_next_pos_to_decode_;
251 int next_bitstream_buffer_id_; 260 int next_bitstream_buffer_id_;
252 ClientStateNotification* note_; 261 ClientStateNotification* note_;
253 scoped_ptr<VideoDecodeAccelerator> decoder_; 262 scoped_ptr<VideoDecodeAccelerator> decoder_;
254 std::set<int> outstanding_texture_ids_; 263 std::set<int> outstanding_texture_ids_;
255 int remaining_play_throughs_; 264 int remaining_play_throughs_;
256 int reset_after_frame_num_; 265 int reset_after_frame_num_;
257 int delete_decoder_state_; 266 int delete_decoder_state_;
258 ClientState state_; 267 ClientState state_;
259 int num_decoded_frames_; 268 int num_decoded_frames_;
260 int num_done_bitstream_buffers_; 269 int num_done_bitstream_buffers_;
261 PictureBufferById picture_buffers_by_id_; 270 PictureBufferById picture_buffers_by_id_;
262 base::TimeTicks initialize_done_ticks_; 271 base::TimeTicks initialize_done_ticks_;
263 base::TimeTicks last_frame_delivered_ticks_; 272 base::TimeTicks last_frame_delivered_ticks_;
264 int profile_; 273 int profile_;
265 }; 274 };
266 275
267 GLRenderingVDAClient::GLRenderingVDAClient( 276 GLRenderingVDAClient::GLRenderingVDAClient(
268 RenderingHelper* rendering_helper, 277 RenderingHelper* rendering_helper,
269 int rendering_window_id, 278 int rendering_window_id,
270 ClientStateNotification* note, 279 ClientStateNotification* note,
271 const std::string& encoded_data, 280 const std::string& encoded_data,
272 int num_NALUs_per_decode, 281 int num_fragments_per_decode,
273 int num_in_flight_decodes, 282 int num_in_flight_decodes,
274 int num_play_throughs, 283 int num_play_throughs,
275 int reset_after_frame_num, 284 int reset_after_frame_num,
276 int delete_decoder_state, 285 int delete_decoder_state,
277 int frame_width, 286 int frame_width,
278 int frame_height, 287 int frame_height,
279 int profile) 288 int profile)
280 : rendering_helper_(rendering_helper), 289 : rendering_helper_(rendering_helper),
281 rendering_window_id_(rendering_window_id), 290 rendering_window_id_(rendering_window_id),
282 encoded_data_(encoded_data), num_NALUs_per_decode_(num_NALUs_per_decode), 291 encoded_data_(encoded_data),
292 num_fragments_per_decode_(num_fragments_per_decode),
283 num_in_flight_decodes_(num_in_flight_decodes), outstanding_decodes_(0), 293 num_in_flight_decodes_(num_in_flight_decodes), outstanding_decodes_(0),
284 encoded_data_next_pos_to_decode_(0), next_bitstream_buffer_id_(0), 294 encoded_data_next_pos_to_decode_(0), next_bitstream_buffer_id_(0),
285 note_(note), 295 note_(note),
286 remaining_play_throughs_(num_play_throughs), 296 remaining_play_throughs_(num_play_throughs),
287 reset_after_frame_num_(reset_after_frame_num), 297 reset_after_frame_num_(reset_after_frame_num),
288 delete_decoder_state_(delete_decoder_state), 298 delete_decoder_state_(delete_decoder_state),
289 state_(CS_CREATED), 299 state_(CS_CREATED),
290 num_decoded_frames_(0), num_done_bitstream_buffers_(0), 300 num_decoded_frames_(0), num_done_bitstream_buffers_(0),
291 profile_(profile) { 301 profile_(profile) {
292 CHECK_GT(num_NALUs_per_decode, 0); 302 CHECK_GT(num_fragments_per_decode, 0);
293 CHECK_GT(num_in_flight_decodes, 0); 303 CHECK_GT(num_in_flight_decodes, 0);
294 CHECK_GT(num_play_throughs, 0); 304 CHECK_GT(num_play_throughs, 0);
295 } 305 }
296 306
297 GLRenderingVDAClient::~GLRenderingVDAClient() { 307 GLRenderingVDAClient::~GLRenderingVDAClient() {
298 DeleteDecoder(); // Clean up in case of expected error. 308 DeleteDecoder(); // Clean up in case of expected error.
299 CHECK(decoder_deleted()); 309 CHECK(decoder_deleted());
300 STLDeleteValues(&picture_buffers_by_id_); 310 STLDeleteValues(&picture_buffers_by_id_);
301 SetState(CS_DESTROYED); 311 SetState(CS_DESTROYED);
302 } 312 }
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 } 385 }
376 386
377 void GLRenderingVDAClient::PictureReady(const media::Picture& picture) { 387 void GLRenderingVDAClient::PictureReady(const media::Picture& picture) {
378 // We shouldn't be getting pictures delivered after Reset has completed. 388 // We shouldn't be getting pictures delivered after Reset has completed.
379 CHECK_LT(state_, CS_RESET); 389 CHECK_LT(state_, CS_RESET);
380 390
381 if (decoder_deleted()) 391 if (decoder_deleted())
382 return; 392 return;
383 last_frame_delivered_ticks_ = base::TimeTicks::Now(); 393 last_frame_delivered_ticks_ = base::TimeTicks::Now();
384 394
385 // Because we feed the decoder a limited number of NALUs at a time, we can be 395 // Because we feed the decoder a limited number of fragments at a time, we can
386 // sure that the bitstream buffer from which a frame comes has a limited 396 // be sure that the bitstream buffer from which a frame comes has a limited
387 // range. Assert that. 397 // range. Assert that.
388 CHECK_GE((picture.bitstream_buffer_id() + 1) * num_NALUs_per_decode_, 398 CHECK_GE((picture.bitstream_buffer_id() + 1) * num_fragments_per_decode_,
389 num_decoded_frames_); 399 num_decoded_frames_);
390 CHECK_LE(picture.bitstream_buffer_id(), next_bitstream_buffer_id_); 400 CHECK_LE(picture.bitstream_buffer_id(), next_bitstream_buffer_id_);
391 ++num_decoded_frames_; 401 ++num_decoded_frames_;
392 402
393 // Mid-stream reset applies only to the last play-through per constructor 403 // Mid-stream reset applies only to the last play-through per constructor
394 // comment. 404 // comment.
395 if (remaining_play_throughs_ == 1 && 405 if (remaining_play_throughs_ == 1 &&
396 reset_after_frame_num_ == num_decoded_frames_) { 406 reset_after_frame_num_ == num_decoded_frames_) {
397 reset_after_frame_num_ = MID_STREAM_RESET; 407 reset_after_frame_num_ = MID_STREAM_RESET;
398 decoder_->Reset(); 408 decoder_->Reset();
399 // Re-start decoding from the beginning of the stream to avoid needing to 409 // Re-start decoding from the beginning of the stream to avoid needing to
400 // know how to find I-frames and so on in this test. 410 // know how to find I-frames and so on in this test.
401 encoded_data_next_pos_to_decode_ = 0; 411 encoded_data_next_pos_to_decode_ = 0;
402 } 412 }
403 413
404 media::PictureBuffer* picture_buffer = 414 media::PictureBuffer* picture_buffer =
405 picture_buffers_by_id_[picture.picture_buffer_id()]; 415 picture_buffers_by_id_[picture.picture_buffer_id()];
406 CHECK(picture_buffer); 416 CHECK(picture_buffer);
407 rendering_helper_->RenderTexture(picture_buffer->texture_id()); 417 rendering_helper_->RenderTexture(picture_buffer->texture_id());
408 418
409 decoder_->ReusePictureBuffer(picture.picture_buffer_id()); 419 decoder_->ReusePictureBuffer(picture.picture_buffer_id());
410 } 420 }
411 421
412 void GLRenderingVDAClient::NotifyInitializeDone() { 422 void GLRenderingVDAClient::NotifyInitializeDone() {
413 SetState(CS_INITIALIZED); 423 SetState(CS_INITIALIZED);
414 initialize_done_ticks_ = base::TimeTicks::Now(); 424 initialize_done_ticks_ = base::TimeTicks::Now();
415 for (int i = 0; i < num_in_flight_decodes_; ++i) 425 for (int i = 0; i < num_in_flight_decodes_; ++i)
416 DecodeNextNALUs(); 426 DecodeNextFragments();
417 DCHECK_EQ(outstanding_decodes_, num_in_flight_decodes_); 427 DCHECK_EQ(outstanding_decodes_, num_in_flight_decodes_);
418 } 428 }
419 429
420 void GLRenderingVDAClient::NotifyEndOfBitstreamBuffer( 430 void GLRenderingVDAClient::NotifyEndOfBitstreamBuffer(
421 int32 bitstream_buffer_id) { 431 int32 bitstream_buffer_id) {
422 // TODO(fischman): this test currently relies on this notification to make 432 // TODO(fischman): this test currently relies on this notification to make
423 // forward progress during a Reset(). But the VDA::Reset() API doesn't 433 // forward progress during a Reset(). But the VDA::Reset() API doesn't
424 // guarantee this, so stop relying on it (and remove the notifications from 434 // guarantee this, so stop relying on it (and remove the notifications from
425 // VaapiVideoDecodeAccelerator::FinishReset()). 435 // VaapiVideoDecodeAccelerator::FinishReset()).
426 ++num_done_bitstream_buffers_; 436 ++num_done_bitstream_buffers_;
427 --outstanding_decodes_; 437 --outstanding_decodes_;
428 DecodeNextNALUs(); 438 DecodeNextFragments();
429 } 439 }
430 440
431 void GLRenderingVDAClient::NotifyFlushDone() { 441 void GLRenderingVDAClient::NotifyFlushDone() {
432 if (decoder_deleted()) 442 if (decoder_deleted())
433 return; 443 return;
434 SetState(CS_FLUSHED); 444 SetState(CS_FLUSHED);
435 --remaining_play_throughs_; 445 --remaining_play_throughs_;
436 DCHECK_GE(remaining_play_throughs_, 0); 446 DCHECK_GE(remaining_play_throughs_, 0);
437 if (decoder_deleted()) 447 if (decoder_deleted())
438 return; 448 return;
439 decoder_->Reset(); 449 decoder_->Reset();
440 SetState(CS_RESETTING); 450 SetState(CS_RESETTING);
441 } 451 }
442 452
443 void GLRenderingVDAClient::NotifyResetDone() { 453 void GLRenderingVDAClient::NotifyResetDone() {
444 if (decoder_deleted()) 454 if (decoder_deleted())
445 return; 455 return;
446 456
447 if (reset_after_frame_num_ == MID_STREAM_RESET) { 457 if (reset_after_frame_num_ == MID_STREAM_RESET) {
448 reset_after_frame_num_ = END_OF_STREAM_RESET; 458 reset_after_frame_num_ = END_OF_STREAM_RESET;
449 DecodeNextNALUs(); 459 DecodeNextFragments();
450 return; 460 return;
451 } 461 }
452 462
453 if (remaining_play_throughs_) { 463 if (remaining_play_throughs_) {
454 encoded_data_next_pos_to_decode_ = 0; 464 encoded_data_next_pos_to_decode_ = 0;
455 NotifyInitializeDone(); 465 NotifyInitializeDone();
456 return; 466 return;
457 } 467 }
458 468
459 SetState(CS_RESET); 469 SetState(CS_RESET);
(...skipping 28 matching lines...) Expand all
488 for (std::set<int>::iterator it = outstanding_texture_ids_.begin(); 498 for (std::set<int>::iterator it = outstanding_texture_ids_.begin();
489 it != outstanding_texture_ids_.end(); ++it) { 499 it != outstanding_texture_ids_.end(); ++it) {
490 rendering_helper_->DeleteTexture(*it); 500 rendering_helper_->DeleteTexture(*it);
491 } 501 }
492 outstanding_texture_ids_.clear(); 502 outstanding_texture_ids_.clear();
493 // Cascade through the rest of the states to simplify test code below. 503 // Cascade through the rest of the states to simplify test code below.
494 for (int i = state_ + 1; i < CS_MAX; ++i) 504 for (int i = state_ + 1; i < CS_MAX; ++i)
495 SetState(static_cast<ClientState>(i)); 505 SetState(static_cast<ClientState>(i));
496 } 506 }
497 507
508 void GLRenderingVDAClient::GetRangeForNextFragments(
509 size_t start_pos, size_t* end_pos) {
510 if (profile_ < media::H264PROFILE_MAX) {
511 GetRangeForNextNALUs(start_pos, end_pos);
512 return;
513 }
514 DCHECK_LE(profile_, media::VP8PROFILE_MAX);
515 GetRangeForNextFrames(start_pos, end_pos);
516 }
517
498 void GLRenderingVDAClient::GetRangeForNextNALUs( 518 void GLRenderingVDAClient::GetRangeForNextNALUs(
499 size_t start_pos, size_t* end_pos) { 519 size_t start_pos, size_t* end_pos) {
500 *end_pos = start_pos; 520 *end_pos = start_pos;
501 CHECK(LookingAtNAL(encoded_data_, start_pos)); 521 CHECK(LookingAtNAL(encoded_data_, start_pos));
502 for (int i = 0; i < num_NALUs_per_decode_; ++i) { 522 for (int i = 0; i < num_fragments_per_decode_; ++i) {
503 *end_pos += 4; 523 *end_pos += 4;
504 while (*end_pos + 3 < encoded_data_.size() && 524 while (*end_pos + 3 < encoded_data_.size() &&
505 !LookingAtNAL(encoded_data_, *end_pos)) { 525 !LookingAtNAL(encoded_data_, *end_pos)) {
506 ++*end_pos; 526 ++*end_pos;
507 } 527 }
508 if (*end_pos + 3 >= encoded_data_.size()) { 528 if (*end_pos + 3 >= encoded_data_.size()) {
509 *end_pos = encoded_data_.size(); 529 *end_pos = encoded_data_.size();
510 return; 530 return;
511 } 531 }
512 } 532 }
513 } 533 }
514 534
515 void GLRenderingVDAClient::DecodeNextNALUs() { 535 void GLRenderingVDAClient::GetRangeForNextFrames(
536 size_t start_pos, size_t* end_pos) {
537 // Helpful description: http://wiki.multimedia.cx/index.php?title=IVF
538 *end_pos = start_pos;
539 if (start_pos == 0)
540 *end_pos = 32;
Pawel Osciak 2012/07/22 15:08:17 Do you think you should be sending the IVF header
Ami GONE FROM CHROMIUM 2012/07/22 23:18:29 Merely omitting the 32-byte header doesn't change
541 for (int i = 0; i < num_fragments_per_decode_; ++i) {
542 uint32 frame_size = *reinterpret_cast<uint32*>(&encoded_data_[*end_pos]);
Pawel Osciak 2012/07/22 15:08:17 I'm assuming you are ok segfaulting here on errone
Ami GONE FROM CHROMIUM 2012/07/22 23:18:29 Yes, being a test binary I'm fine with that.
543 *end_pos += 12; // Skip frame header.
544 *end_pos += frame_size;
545 if (*end_pos + 12 >= encoded_data_.size())
546 return;
547 }
548 }
549
550 void GLRenderingVDAClient::DecodeNextFragments() {
516 if (decoder_deleted()) 551 if (decoder_deleted())
517 return; 552 return;
518 if (encoded_data_next_pos_to_decode_ == encoded_data_.size()) { 553 if (encoded_data_next_pos_to_decode_ == encoded_data_.size()) {
519 if (outstanding_decodes_ == 0) { 554 if (outstanding_decodes_ == 0) {
520 decoder_->Flush(); 555 decoder_->Flush();
521 SetState(CS_FLUSHING); 556 SetState(CS_FLUSHING);
522 } 557 }
523 return; 558 return;
524 } 559 }
525 size_t start_pos = encoded_data_next_pos_to_decode_; 560 size_t start_pos = encoded_data_next_pos_to_decode_;
526 size_t end_pos; 561 size_t end_pos;
527 GetRangeForNextNALUs(start_pos, &end_pos); 562 GetRangeForNextFragments(start_pos, &end_pos);
528 563
529 // Populate the shared memory buffer w/ the NALU, duplicate its handle, and 564 // Populate the shared memory buffer w/ the fragments, duplicate its handle,
530 // hand it off to the decoder. 565 // and hand it off to the decoder.
531 base::SharedMemory shm; 566 base::SharedMemory shm;
532 CHECK(shm.CreateAndMapAnonymous(end_pos - start_pos)) 567 CHECK(shm.CreateAndMapAnonymous(end_pos - start_pos))
533 << start_pos << ", " << end_pos; 568 << start_pos << ", " << end_pos;
534 memcpy(shm.memory(), encoded_data_.data() + start_pos, end_pos - start_pos); 569 memcpy(shm.memory(), encoded_data_.data() + start_pos, end_pos - start_pos);
535 base::SharedMemoryHandle dup_handle; 570 base::SharedMemoryHandle dup_handle;
536 CHECK(shm.ShareToProcess(base::Process::Current().handle(), &dup_handle)); 571 CHECK(shm.ShareToProcess(base::Process::Current().handle(), &dup_handle));
537 media::BitstreamBuffer bitstream_buffer( 572 media::BitstreamBuffer bitstream_buffer(
538 next_bitstream_buffer_id_++, dup_handle, end_pos - start_pos); 573 next_bitstream_buffer_id_++, dup_handle, end_pos - start_pos);
539 decoder_->Decode(bitstream_buffer); 574 decoder_->Decode(bitstream_buffer);
540 ++outstanding_decodes_; 575 ++outstanding_decodes_;
541 encoded_data_next_pos_to_decode_ = end_pos; 576 encoded_data_next_pos_to_decode_ = end_pos;
542 577
543 if (!remaining_play_throughs_ && 578 if (!remaining_play_throughs_ &&
544 -delete_decoder_state_ == next_bitstream_buffer_id_) { 579 -delete_decoder_state_ == next_bitstream_buffer_id_) {
545 DeleteDecoder(); 580 DeleteDecoder();
546 } 581 }
547 } 582 }
548 583
549 double GLRenderingVDAClient::frames_per_second() { 584 double GLRenderingVDAClient::frames_per_second() {
550 base::TimeDelta delta = last_frame_delivered_ticks_ - initialize_done_ticks_; 585 base::TimeDelta delta = last_frame_delivered_ticks_ - initialize_done_ticks_;
551 if (delta.InSecondsF() == 0) 586 if (delta.InSecondsF() == 0)
552 return 0; 587 return 0;
553 return num_decoded_frames_ / delta.InSecondsF(); 588 return num_decoded_frames_ / delta.InSecondsF();
554 } 589 }
555 590
556 // Test parameters: 591 // Test parameters:
557 // - Number of NALUs per Decode() call. 592 // - Number of fragments per Decode() call.
558 // - Number of concurrent decoders. 593 // - Number of concurrent decoders.
559 // - Number of concurrent in-flight Decode() calls per decoder. 594 // - Number of concurrent in-flight Decode() calls per decoder.
560 // - Number of play-throughs. 595 // - Number of play-throughs.
561 // - reset_after_frame_num: see GLRenderingVDAClient ctor. 596 // - reset_after_frame_num: see GLRenderingVDAClient ctor.
562 // - delete_decoder_phase: see GLRenderingVDAClient ctor. 597 // - delete_decoder_phase: see GLRenderingVDAClient ctor.
563 class VideoDecodeAcceleratorTest 598 class VideoDecodeAcceleratorTest
564 : public ::testing::TestWithParam< 599 : public ::testing::TestWithParam<
565 Tuple6<int, int, int, int, ResetPoint, ClientState> > { 600 Tuple6<int, int, int, int, ResetPoint, ClientState> > {
566 }; 601 };
567 602
(...skipping 29 matching lines...) Expand all
597 632
598 // Test the most straightforward case possible: data is decoded from a single 633 // Test the most straightforward case possible: data is decoded from a single
599 // chunk and rendered to the screen. 634 // chunk and rendered to the screen.
600 TEST_P(VideoDecodeAcceleratorTest, TestSimpleDecode) { 635 TEST_P(VideoDecodeAcceleratorTest, TestSimpleDecode) {
601 // Can be useful for debugging VLOGs from OVDA. 636 // Can be useful for debugging VLOGs from OVDA.
602 // logging::SetMinLogLevel(-1); 637 // logging::SetMinLogLevel(-1);
603 638
604 // Required for Thread to work. Not used otherwise. 639 // Required for Thread to work. Not used otherwise.
605 base::ShadowingAtExitManager at_exit_manager; 640 base::ShadowingAtExitManager at_exit_manager;
606 641
607 const int num_NALUs_per_decode = GetParam().a; 642 const int num_fragments_per_decode = GetParam().a;
608 const size_t num_concurrent_decoders = GetParam().b; 643 const size_t num_concurrent_decoders = GetParam().b;
609 const size_t num_in_flight_decodes = GetParam().c; 644 const size_t num_in_flight_decodes = GetParam().c;
610 const int num_play_throughs = GetParam().d; 645 const int num_play_throughs = GetParam().d;
611 const int reset_after_frame_num = GetParam().e; 646 const int reset_after_frame_num = GetParam().e;
612 const int delete_decoder_state = GetParam().f; 647 const int delete_decoder_state = GetParam().f;
613 648
614 FilePath::StringType test_video_file; 649 FilePath::StringType test_video_file;
615 int frame_width, frame_height; 650 int frame_width, frame_height;
616 int num_frames, num_NALUs, min_fps_render, min_fps_no_render, profile; 651 int num_frames, num_fragments, min_fps_render, min_fps_no_render, profile;
617 ParseTestVideoData(test_video_data, &test_video_file, &frame_width, 652 ParseTestVideoData(test_video_data, &test_video_file, &frame_width,
618 &frame_height, &num_frames, &num_NALUs, 653 &frame_height, &num_frames, &num_fragments,
619 &min_fps_render, &min_fps_no_render, &profile); 654 &min_fps_render, &min_fps_no_render, &profile);
620 min_fps_render /= num_concurrent_decoders; 655 min_fps_render /= num_concurrent_decoders;
621 min_fps_no_render /= num_concurrent_decoders; 656 min_fps_no_render /= num_concurrent_decoders;
622 657
623 // If we reset mid-stream and start playback over, account for frames that are 658 // If we reset mid-stream and start playback over, account for frames that are
624 // decoded twice in our expectations. 659 // decoded twice in our expectations.
625 if (num_frames > 0 && reset_after_frame_num >= 0) 660 if (num_frames > 0 && reset_after_frame_num >= 0)
626 num_frames += reset_after_frame_num; 661 num_frames += reset_after_frame_num;
627 662
628 // Suppress GL swapping in all but a few tests, to cut down overall test 663 // Suppress GL swapping in all but a few tests, to cut down overall test
629 // runtime. 664 // runtime.
630 const bool suppress_swap_to_display = num_NALUs_per_decode > 1; 665 const bool suppress_swap_to_display = num_fragments_per_decode > 1;
631 666
632 std::vector<ClientStateNotification*> notes(num_concurrent_decoders, NULL); 667 std::vector<ClientStateNotification*> notes(num_concurrent_decoders, NULL);
633 std::vector<GLRenderingVDAClient*> clients(num_concurrent_decoders, NULL); 668 std::vector<GLRenderingVDAClient*> clients(num_concurrent_decoders, NULL);
634 669
635 // Read in the video data. 670 // Read in the video data.
636 std::string data_str; 671 std::string data_str;
637 CHECK(file_util::ReadFileToString(FilePath(test_video_file), &data_str)) 672 CHECK(file_util::ReadFileToString(FilePath(test_video_file), &data_str))
638 << "test_video_file: " << FilePath(test_video_file).MaybeAsASCII(); 673 << "test_video_file: " << FilePath(test_video_file).MaybeAsASCII();
639 674
640 // Initialize the rendering helper. 675 // Initialize the rendering helper.
(...skipping 16 matching lines...) Expand all
657 base::Unretained(rendering_helper.get()), 692 base::Unretained(rendering_helper.get()),
658 suppress_swap_to_display, num_concurrent_decoders, 693 suppress_swap_to_display, num_concurrent_decoders,
659 frame_width, frame_height, &done)); 694 frame_width, frame_height, &done));
660 done.Wait(); 695 done.Wait();
661 696
662 // First kick off all the decoders. 697 // First kick off all the decoders.
663 for (size_t index = 0; index < num_concurrent_decoders; ++index) { 698 for (size_t index = 0; index < num_concurrent_decoders; ++index) {
664 ClientStateNotification* note = new ClientStateNotification(); 699 ClientStateNotification* note = new ClientStateNotification();
665 notes[index] = note; 700 notes[index] = note;
666 GLRenderingVDAClient* client = new GLRenderingVDAClient( 701 GLRenderingVDAClient* client = new GLRenderingVDAClient(
667 rendering_helper.get(), index, note, data_str, num_NALUs_per_decode, 702 rendering_helper.get(), index, note, data_str, num_fragments_per_decode,
668 num_in_flight_decodes, num_play_throughs, reset_after_frame_num, 703 num_in_flight_decodes, num_play_throughs, reset_after_frame_num,
669 delete_decoder_state, frame_width, frame_height, profile); 704 delete_decoder_state, frame_width, frame_height, profile);
670 clients[index] = client; 705 clients[index] = client;
671 706
672 rendering_thread.message_loop()->PostTask( 707 rendering_thread.message_loop()->PostTask(
673 FROM_HERE, 708 FROM_HERE,
674 base::Bind(&GLRenderingVDAClient::CreateDecoder, 709 base::Bind(&GLRenderingVDAClient::CreateDecoder,
675 base::Unretained(client))); 710 base::Unretained(client)));
676 711
677 ASSERT_EQ(note->Wait(), CS_DECODER_SET); 712 ASSERT_EQ(note->Wait(), CS_DECODER_SET);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
718 // Finally assert that decoding went as expected. 753 // Finally assert that decoding went as expected.
719 for (size_t i = 0; i < num_concurrent_decoders && 754 for (size_t i = 0; i < num_concurrent_decoders &&
720 !skip_performance_and_correctness_checks; ++i) { 755 !skip_performance_and_correctness_checks; ++i) {
721 // We can only make performance/correctness assertions if the decoder was 756 // We can only make performance/correctness assertions if the decoder was
722 // allowed to finish. 757 // allowed to finish.
723 if (delete_decoder_state < CS_FLUSHED) 758 if (delete_decoder_state < CS_FLUSHED)
724 continue; 759 continue;
725 GLRenderingVDAClient* client = clients[i]; 760 GLRenderingVDAClient* client = clients[i];
726 if (num_frames > 0) 761 if (num_frames > 0)
727 EXPECT_EQ(client->num_decoded_frames(), num_frames); 762 EXPECT_EQ(client->num_decoded_frames(), num_frames);
728 if (num_NALUs > 0 && reset_after_frame_num < 0) { 763 if (num_fragments > 0 && reset_after_frame_num < 0) {
729 EXPECT_EQ(client->num_done_bitstream_buffers(), 764 EXPECT_EQ(client->num_done_bitstream_buffers(),
730 ceil(static_cast<double>(num_NALUs) / num_NALUs_per_decode)); 765 ceil(static_cast<double>(num_fragments) /
766 num_fragments_per_decode));
731 } 767 }
732 LOG(INFO) << "Decoder " << i << " fps: " << client->frames_per_second(); 768 LOG(INFO) << "Decoder " << i << " fps: " << client->frames_per_second();
733 int min_fps = suppress_swap_to_display ? min_fps_no_render : min_fps_render; 769 int min_fps = suppress_swap_to_display ? min_fps_no_render : min_fps_render;
734 if (min_fps > 0) 770 if (min_fps > 0)
735 EXPECT_GT(client->frames_per_second(), min_fps); 771 EXPECT_GT(client->frames_per_second(), min_fps);
736 } 772 }
737 773
738 rendering_thread.message_loop()->PostTask( 774 rendering_thread.message_loop()->PostTask(
739 FROM_HERE, 775 FROM_HERE,
740 base::Bind(&STLDeleteElements<std::vector<GLRenderingVDAClient*> >, 776 base::Bind(&STLDeleteElements<std::vector<GLRenderingVDAClient*> >,
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
777 MakeTuple(1, 1, 1, 1, END_OF_STREAM_RESET, CS_RESETTING), 813 MakeTuple(1, 1, 1, 1, END_OF_STREAM_RESET, CS_RESETTING),
778 MakeTuple(1, 1, 1, 1, END_OF_STREAM_RESET, CS_RESET), 814 MakeTuple(1, 1, 1, 1, END_OF_STREAM_RESET, CS_RESET),
779 MakeTuple(1, 1, 1, 1, END_OF_STREAM_RESET, 815 MakeTuple(1, 1, 1, 1, END_OF_STREAM_RESET,
780 static_cast<ClientState>(-1)), 816 static_cast<ClientState>(-1)),
781 MakeTuple(1, 1, 1, 1, END_OF_STREAM_RESET, 817 MakeTuple(1, 1, 1, 1, END_OF_STREAM_RESET,
782 static_cast<ClientState>(-10)), 818 static_cast<ClientState>(-10)),
783 MakeTuple(1, 1, 1, 1, END_OF_STREAM_RESET, 819 MakeTuple(1, 1, 1, 1, END_OF_STREAM_RESET,
784 static_cast<ClientState>(-100)))); 820 static_cast<ClientState>(-100))));
785 821
786 // Test that decoding various variation works: multiple concurrent decoders and 822 // Test that decoding various variation works: multiple concurrent decoders and
787 // multiple NALUs per Decode() call. 823 // multiple fragments per Decode() call.
788 INSTANTIATE_TEST_CASE_P( 824 INSTANTIATE_TEST_CASE_P(
789 DecodeVariations, VideoDecodeAcceleratorTest, 825 DecodeVariations, VideoDecodeAcceleratorTest,
790 ::testing::Values( 826 ::testing::Values(
791 MakeTuple(1, 1, 1, 1, END_OF_STREAM_RESET, CS_RESET), 827 MakeTuple(1, 1, 1, 1, END_OF_STREAM_RESET, CS_RESET),
792 MakeTuple(1, 1, 10, 1, END_OF_STREAM_RESET, CS_RESET), 828 MakeTuple(1, 1, 10, 1, END_OF_STREAM_RESET, CS_RESET),
793 // Tests queuing. 829 // Tests queuing.
794 MakeTuple(1, 1, 15, 1, END_OF_STREAM_RESET, CS_RESET), 830 MakeTuple(1, 1, 15, 1, END_OF_STREAM_RESET, CS_RESET),
795 // +0 hack below to promote enum to int. 831 // +0 hack below to promote enum to int.
796 MakeTuple(1, kMinSupportedNumConcurrentDecoders + 0, 1, 1, 832 MakeTuple(1, kMinSupportedNumConcurrentDecoders + 0, 1, 1,
797 END_OF_STREAM_RESET, CS_RESET), 833 END_OF_STREAM_RESET, CS_RESET),
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
855 891
856 base::ShadowingAtExitManager at_exit_manager; 892 base::ShadowingAtExitManager at_exit_manager;
857 RenderingHelper::InitializePlatform(); 893 RenderingHelper::InitializePlatform();
858 894
859 #if defined(OS_WIN) 895 #if defined(OS_WIN)
860 DXVAVideoDecodeAccelerator::PreSandboxInitialization(); 896 DXVAVideoDecodeAccelerator::PreSandboxInitialization();
861 #endif 897 #endif
862 898
863 return RUN_ALL_TESTS(); 899 return RUN_ALL_TESTS();
864 } 900 }
OLDNEW
« no previous file with comments | « content/common/gpu/media/omx_video_decode_accelerator.cc ('k') | content/common/gpu/testdata/README » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698