Chromium Code Reviews| Index: media/gpu/video_decode_accelerator_unittest.cc |
| diff --git a/media/gpu/video_decode_accelerator_unittest.cc b/media/gpu/video_decode_accelerator_unittest.cc |
| index cb1bed901e50501a91a6555ef0af4702444692a7..7175b08df73768215d6ea59604191de743e6c3eb 100644 |
| --- a/media/gpu/video_decode_accelerator_unittest.cc |
| +++ b/media/gpu/video_decode_accelerator_unittest.cc |
| @@ -150,6 +150,8 @@ VideoDecodeAcceleratorTestEnvironment* g_env; |
| // Magic constants for differentiating the reasons for NotifyResetDone being |
| // called. |
| enum ResetPoint { |
| + // Reset() right after calling Flush() (before getting NotifyFlushDone()). |
| + RESET_BEFORE_NOTIFY_FLUSH_DONE = -5, |
| // Reset() just after calling Decode() with a fragment containing config info. |
| RESET_AFTER_FIRST_CONFIG_INFO = -4, |
| START_OF_STREAM_RESET = -3, |
| @@ -462,6 +464,9 @@ class GLRenderingVDAClient |
| int num_skipped_fragments() { return num_skipped_fragments_; } |
| int num_queued_fragments() { return num_queued_fragments_; } |
| int num_decoded_frames() { return num_decoded_frames_; } |
| + int num_decoded_frames_before_reset() { |
| + return num_decoded_frames_before_reset_; |
| + } |
| double frames_per_second(); |
| // Return the median of the decode time of all decoded frames. |
| base::TimeDelta decode_time_median(); |
| @@ -476,6 +481,8 @@ class GLRenderingVDAClient |
| // Delete the associated decoder helper. |
| void DeleteDecoder(); |
| + // Reset the associated decoder helpr. |
|
wuchengli
2017/03/02 09:44:04
helper
johnylin1
2017/03/07 07:44:16
Done.
|
| + void ResetDecoder(); |
| // Compute & return the first encoded bytes (including a start frame) to send |
| // to the decoder, starting at |start_pos| and returning one fragment. Skips |
| @@ -513,6 +520,7 @@ class GLRenderingVDAClient |
| int num_skipped_fragments_; |
| int num_queued_fragments_; |
| int num_decoded_frames_; |
| + int num_decoded_frames_before_reset_; |
| int num_done_bitstream_buffers_; |
| base::TimeTicks initialize_done_ticks_; |
| VideoCodecProfile profile_; |
| @@ -594,6 +602,7 @@ GLRenderingVDAClient::GLRenderingVDAClient( |
| num_skipped_fragments_(0), |
| num_queued_fragments_(0), |
| num_decoded_frames_(0), |
| + num_decoded_frames_before_reset_(0), |
| num_done_bitstream_buffers_(0), |
| fake_decoder_(fake_decoder), |
| texture_target_(0), |
| @@ -807,6 +816,15 @@ void GLRenderingVDAClient::ReturnPicture(int32_t picture_buffer_id) { |
| } |
| } |
| +void GLRenderingVDAClient::ResetDecoder() { |
|
wuchengli
2017/03/02 09:44:05
The name is not very good. There are three other d
wuchengli
2017/03/02 10:07:12
As discussed, let's use ResetDecoderAfterFlush.
johnylin1
2017/03/07 07:44:16
Done.
|
| + --remaining_play_throughs_; |
| + DCHECK_GE(remaining_play_throughs_, 0); |
| + num_decoded_frames_before_reset_ = num_decoded_frames_; |
|
wuchengli
2017/03/02 10:07:12
It's more consistent to set num_decoded_frames_bef
johnylin1
2017/03/07 07:44:16
After discussed, we gonna add this check after ref
|
| + decoder_->Reset(); |
| + if (state_ == CS_FLUSHED) |
|
wuchengli
2017/03/02 09:44:04
I don't understand. Why do we need this line?
wuchengli
2017/03/02 10:07:11
As discussed, this can be removed.
johnylin1
2017/03/07 07:44:16
Done.
|
| + SetState(CS_RESETTING); |
| +} |
| + |
| void GLRenderingVDAClient::NotifyEndOfBitstreamBuffer( |
| int32_t bitstream_buffer_id) { |
| if (decoder_deleted()) |
| @@ -824,6 +842,10 @@ void GLRenderingVDAClient::NotifyEndOfBitstreamBuffer( |
| if (state_ != CS_FLUSHING) { |
| decoder_->Flush(); |
| SetState(CS_FLUSHING); |
| + if (reset_after_frame_num_ == RESET_BEFORE_NOTIFY_FLUSH_DONE) { |
| + SetState(CS_FLUSHED); |
| + ResetDecoder(); |
| + } |
| } |
| } else if (decode_calls_per_second_ == 0) { |
| DecodeNextFragment(); |
| @@ -834,13 +856,16 @@ void GLRenderingVDAClient::NotifyFlushDone() { |
| if (decoder_deleted()) |
| return; |
| - SetState(CS_FLUSHED); |
| - --remaining_play_throughs_; |
| - DCHECK_GE(remaining_play_throughs_, 0); |
| - if (decoder_deleted()) |
| + if (reset_after_frame_num_ == RESET_BEFORE_NOTIFY_FLUSH_DONE) { |
| + // In ResetBeforeNotifyFlushDone case client is not necessary to wait for |
| + // NotifyFlushDone(). But if client gets, it should be always before |
|
wuchengli
2017/03/02 09:44:05
s/gets/gets here/
johnylin1
2017/03/07 07:44:16
Done.
|
| + // NotifyResetDone(). |
| + LOG_ASSERT(state_ == CS_RESETTING); |
|
wuchengli
2017/03/02 09:44:04
When state_ != CS_RESETTING, it can be a bug of dr
johnylin1
2017/03/07 07:44:16
Done.
|
| return; |
| - decoder_->Reset(); |
| - SetState(CS_RESETTING); |
| + } |
| + |
| + SetState(CS_FLUSHED); |
| + ResetDecoder(); |
| } |
| void GLRenderingVDAClient::NotifyResetDone() { |
| @@ -1463,8 +1488,13 @@ TEST_P(VideoDecodeAcceleratorParamTest, TestSimpleDecode) { |
| // could still be returned until resetting done. |
| if (video_file->reset_after_frame_num > 0) |
| EXPECT_GE(client->num_decoded_frames(), video_file->num_frames); |
| - else |
| + // In ResetBeforeNotifyFlushDone case the decoded frames may be less than |
| + // the video frames because decoder is reset before flush done. |
| + else if (video_file->reset_after_frame_num != |
| + RESET_BEFORE_NOTIFY_FLUSH_DONE) |
| EXPECT_EQ(client->num_decoded_frames(), video_file->num_frames); |
| + EXPECT_GE(client->num_decoded_frames(), |
| + client->num_decoded_frames_before_reset()); |
| } |
| if (reset_point == END_OF_STREAM_RESET) { |
| EXPECT_EQ(video_file->num_fragments, client->num_skipped_fragments() + |
| @@ -1566,6 +1596,18 @@ INSTANTIATE_TEST_CASE_P( |
| false, |
| false))); |
| +// Test Reset() immediately after Flush() and before NotifyFlushDone(). |
| +INSTANTIATE_TEST_CASE_P( |
| + ResetBeforeNotifyFlushDone, |
| + VideoDecodeAcceleratorParamTest, |
| + ::testing::Values(std::make_tuple(1, |
| + 1, |
| + 1, |
| + RESET_BEFORE_NOTIFY_FLUSH_DONE, |
| + CS_RESET, |
| + false, |
| + false))); |
| + |
| // Test that Reset() mid-stream works fine and doesn't affect decoding even when |
| // Decode() calls are made during the reset. |
| INSTANTIATE_TEST_CASE_P( |