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 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |