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

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

Issue 10828022: Strip IVF headers from VP8 streams before sending them to the OMX decoder. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 4 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 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 bool decoder_deleted() { return !decoder_.get(); } 232 bool decoder_deleted() { return !decoder_.get(); }
233 233
234 private: 234 private:
235 typedef std::map<int, media::PictureBuffer*> PictureBufferById; 235 typedef std::map<int, media::PictureBuffer*> PictureBufferById;
236 236
237 void SetState(ClientState new_state); 237 void SetState(ClientState new_state);
238 238
239 // Delete the associated OMX decoder helper. 239 // Delete the associated OMX decoder helper.
240 void DeleteDecoder(); 240 void DeleteDecoder();
241 241
242 // Compute & return in |*end_pos| the end position for the next batch of 242 // Compute & return the next encoded bytes to send to the decoder (based on
243 // fragments to ship to the decoder (based on |start_pos| & 243 // |start_pos| & |num_fragments_per_decode_|).
244 // |num_fragments_per_decode_|). 244 std::string GetBytesForNextFragments(size_t start_pos, size_t* end_pos);
245 void GetRangeForNextFragments(size_t start_pos, size_t* end_pos);
246 // Helpers for GetRangeForNextFragments above. 245 // Helpers for GetRangeForNextFragments above.
247 void GetRangeForNextNALUs(size_t start_pos, size_t* end_pos); // For h.264. 246 void GetBytesForNextNALUs(size_t start_pos, size_t* end_pos); // For h.264.
248 void GetRangeForNextFrames(size_t start_pos, size_t* end_pos); // For VP8. 247 std::string GetBytesForNextFrames(
248 size_t start_pos, size_t* end_pos); // For VP8.
249 249
250 // Request decode of the next batch of fragments in the encoded data. 250 // Request decode of the next batch of fragments in the encoded data.
251 void DecodeNextFragments(); 251 void DecodeNextFragments();
252 252
253 RenderingHelper* rendering_helper_; 253 RenderingHelper* rendering_helper_;
254 int rendering_window_id_; 254 int rendering_window_id_;
255 std::string encoded_data_; 255 std::string encoded_data_;
256 const int num_fragments_per_decode_; 256 const int num_fragments_per_decode_;
257 const int num_in_flight_decodes_; 257 const int num_in_flight_decodes_;
258 int outstanding_decodes_; 258 int outstanding_decodes_;
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 } 385 }
386 386
387 void GLRenderingVDAClient::PictureReady(const media::Picture& picture) { 387 void GLRenderingVDAClient::PictureReady(const media::Picture& picture) {
388 // We shouldn't be getting pictures delivered after Reset has completed. 388 // We shouldn't be getting pictures delivered after Reset has completed.
389 CHECK_LT(state_, CS_RESET); 389 CHECK_LT(state_, CS_RESET);
390 390
391 if (decoder_deleted()) 391 if (decoder_deleted())
392 return; 392 return;
393 last_frame_delivered_ticks_ = base::TimeTicks::Now(); 393 last_frame_delivered_ticks_ = base::TimeTicks::Now();
394 394
395 // Because we feed the decoder a limited number of fragments at a time, we can
396 // be sure that the bitstream buffer from which a frame comes has a limited
397 // range. Assert that.
Ami GONE FROM CHROMIUM 2012/07/25 22:41:15 More crack removal. This logic relied on the deco
398 CHECK_GE((picture.bitstream_buffer_id() + 1) * num_fragments_per_decode_,
399 num_decoded_frames_);
400 CHECK_LE(picture.bitstream_buffer_id(), next_bitstream_buffer_id_); 395 CHECK_LE(picture.bitstream_buffer_id(), next_bitstream_buffer_id_);
401 ++num_decoded_frames_; 396 ++num_decoded_frames_;
402 397
403 // Mid-stream reset applies only to the last play-through per constructor 398 // Mid-stream reset applies only to the last play-through per constructor
404 // comment. 399 // comment.
405 if (remaining_play_throughs_ == 1 && 400 if (remaining_play_throughs_ == 1 &&
406 reset_after_frame_num_ == num_decoded_frames_) { 401 reset_after_frame_num_ == num_decoded_frames_) {
407 reset_after_frame_num_ = MID_STREAM_RESET; 402 reset_after_frame_num_ = MID_STREAM_RESET;
408 decoder_->Reset(); 403 decoder_->Reset();
409 // Re-start decoding from the beginning of the stream to avoid needing to 404 // Re-start decoding from the beginning of the stream to avoid needing to
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 for (std::set<int>::iterator it = outstanding_texture_ids_.begin(); 493 for (std::set<int>::iterator it = outstanding_texture_ids_.begin();
499 it != outstanding_texture_ids_.end(); ++it) { 494 it != outstanding_texture_ids_.end(); ++it) {
500 rendering_helper_->DeleteTexture(*it); 495 rendering_helper_->DeleteTexture(*it);
501 } 496 }
502 outstanding_texture_ids_.clear(); 497 outstanding_texture_ids_.clear();
503 // Cascade through the rest of the states to simplify test code below. 498 // Cascade through the rest of the states to simplify test code below.
504 for (int i = state_ + 1; i < CS_MAX; ++i) 499 for (int i = state_ + 1; i < CS_MAX; ++i)
505 SetState(static_cast<ClientState>(i)); 500 SetState(static_cast<ClientState>(i));
506 } 501 }
507 502
508 void GLRenderingVDAClient::GetRangeForNextFragments( 503 std::string GLRenderingVDAClient::GetBytesForNextFragments(
509 size_t start_pos, size_t* end_pos) { 504 size_t start_pos, size_t* end_pos) {
510 if (profile_ < media::H264PROFILE_MAX) { 505 if (profile_ < media::H264PROFILE_MAX) {
511 GetRangeForNextNALUs(start_pos, end_pos); 506 GetBytesForNextNALUs(start_pos, end_pos);
512 return; 507 return encoded_data_.substr(start_pos, *end_pos - start_pos);
513 } 508 }
514 DCHECK_LE(profile_, media::VP8PROFILE_MAX); 509 DCHECK_LE(profile_, media::VP8PROFILE_MAX);
515 GetRangeForNextFrames(start_pos, end_pos); 510 return GetBytesForNextFrames(start_pos, end_pos);
516 } 511 }
517 512
518 void GLRenderingVDAClient::GetRangeForNextNALUs( 513 void GLRenderingVDAClient::GetBytesForNextNALUs(
519 size_t start_pos, size_t* end_pos) { 514 size_t start_pos, size_t* end_pos) {
520 *end_pos = start_pos; 515 *end_pos = start_pos;
521 CHECK(LookingAtNAL(encoded_data_, start_pos)); 516 CHECK(LookingAtNAL(encoded_data_, start_pos));
522 for (int i = 0; i < num_fragments_per_decode_; ++i) { 517 for (int i = 0; i < num_fragments_per_decode_; ++i) {
523 *end_pos += 4; 518 *end_pos += 4;
524 while (*end_pos + 3 < encoded_data_.size() && 519 while (*end_pos + 3 < encoded_data_.size() &&
525 !LookingAtNAL(encoded_data_, *end_pos)) { 520 !LookingAtNAL(encoded_data_, *end_pos)) {
526 ++*end_pos; 521 ++*end_pos;
527 } 522 }
528 if (*end_pos + 3 >= encoded_data_.size()) { 523 if (*end_pos + 3 >= encoded_data_.size()) {
529 *end_pos = encoded_data_.size(); 524 *end_pos = encoded_data_.size();
530 return; 525 return;
531 } 526 }
532 } 527 }
533 } 528 }
534 529
535 void GLRenderingVDAClient::GetRangeForNextFrames( 530 std::string GLRenderingVDAClient::GetBytesForNextFrames(
536 size_t start_pos, size_t* end_pos) { 531 size_t start_pos, size_t* end_pos) {
537 // Helpful description: http://wiki.multimedia.cx/index.php?title=IVF 532 // Helpful description: http://wiki.multimedia.cx/index.php?title=IVF
533 std::string bytes;
534 if (start_pos == 0)
535 start_pos = 32; // Skip IVF header.
538 *end_pos = start_pos; 536 *end_pos = start_pos;
539 if (start_pos == 0)
540 *end_pos = 32;
541 for (int i = 0; i < num_fragments_per_decode_; ++i) { 537 for (int i = 0; i < num_fragments_per_decode_; ++i) {
542 uint32 frame_size = *reinterpret_cast<uint32*>(&encoded_data_[*end_pos]); 538 uint32 frame_size = *reinterpret_cast<uint32*>(&encoded_data_[*end_pos]);
543 *end_pos += 12; // Skip frame header. 539 *end_pos += 12; // Skip frame header.
540 bytes.append(encoded_data_.substr(*end_pos, *end_pos + frame_size));
544 *end_pos += frame_size; 541 *end_pos += frame_size;
545 if (*end_pos + 12 >= encoded_data_.size()) 542 if (*end_pos + 12 >= encoded_data_.size())
546 return; 543 return bytes;
547 } 544 }
545 return bytes;
548 } 546 }
549 547
550 void GLRenderingVDAClient::DecodeNextFragments() { 548 void GLRenderingVDAClient::DecodeNextFragments() {
551 if (decoder_deleted()) 549 if (decoder_deleted())
552 return; 550 return;
553 if (encoded_data_next_pos_to_decode_ == encoded_data_.size()) { 551 if (encoded_data_next_pos_to_decode_ == encoded_data_.size()) {
554 if (outstanding_decodes_ == 0) { 552 if (outstanding_decodes_ == 0) {
555 decoder_->Flush(); 553 decoder_->Flush();
556 SetState(CS_FLUSHING); 554 SetState(CS_FLUSHING);
557 } 555 }
558 return; 556 return;
559 } 557 }
560 size_t start_pos = encoded_data_next_pos_to_decode_;
561 size_t end_pos; 558 size_t end_pos;
562 GetRangeForNextFragments(start_pos, &end_pos); 559 std::string next_fragment_bytes =
560 GetBytesForNextFragments(encoded_data_next_pos_to_decode_, &end_pos);
561 size_t next_fragment_size = next_fragment_bytes.size();
563 562
564 // Populate the shared memory buffer w/ the fragments, duplicate its handle, 563 // Populate the shared memory buffer w/ the fragments, duplicate its handle,
565 // and hand it off to the decoder. 564 // and hand it off to the decoder.
566 base::SharedMemory shm; 565 base::SharedMemory shm;
567 CHECK(shm.CreateAndMapAnonymous(end_pos - start_pos)) 566 CHECK(shm.CreateAndMapAnonymous(next_fragment_size));
568 << start_pos << ", " << end_pos; 567 memcpy(shm.memory(), next_fragment_bytes.data(), next_fragment_size);
569 memcpy(shm.memory(), encoded_data_.data() + start_pos, end_pos - start_pos);
570 base::SharedMemoryHandle dup_handle; 568 base::SharedMemoryHandle dup_handle;
571 CHECK(shm.ShareToProcess(base::Process::Current().handle(), &dup_handle)); 569 CHECK(shm.ShareToProcess(base::Process::Current().handle(), &dup_handle));
572 media::BitstreamBuffer bitstream_buffer( 570 media::BitstreamBuffer bitstream_buffer(
573 next_bitstream_buffer_id_++, dup_handle, end_pos - start_pos); 571 next_bitstream_buffer_id_++, dup_handle, next_fragment_size);
574 decoder_->Decode(bitstream_buffer); 572 decoder_->Decode(bitstream_buffer);
575 ++outstanding_decodes_; 573 ++outstanding_decodes_;
576 encoded_data_next_pos_to_decode_ = end_pos; 574 encoded_data_next_pos_to_decode_ = end_pos;
577 575
578 if (!remaining_play_throughs_ && 576 if (!remaining_play_throughs_ &&
579 -delete_decoder_state_ == next_bitstream_buffer_id_) { 577 -delete_decoder_state_ == next_bitstream_buffer_id_) {
580 DeleteDecoder(); 578 DeleteDecoder();
581 } 579 }
582 } 580 }
583 581
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
891 889
892 base::ShadowingAtExitManager at_exit_manager; 890 base::ShadowingAtExitManager at_exit_manager;
893 RenderingHelper::InitializePlatform(); 891 RenderingHelper::InitializePlatform();
894 892
895 #if defined(OS_WIN) 893 #if defined(OS_WIN)
896 DXVAVideoDecodeAccelerator::PreSandboxInitialization(); 894 DXVAVideoDecodeAccelerator::PreSandboxInitialization();
897 #endif 895 #endif
898 896
899 return RUN_ALL_TESTS(); 897 return RUN_ALL_TESTS();
900 } 898 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698