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

Unified Diff: media/gpu/video_decode_accelerator_unittest.cc

Issue 2596193005: vda unittest: delete GLRenderingVDAClient in correct thread (Closed)
Patch Set: vda unittest: delete GLRenderingVDAClient in correct thread Created 4 years 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 ed295a15010ef587332d2e6d5a0879537fab00d7..9ea874a5f016f07cf96018bb1fc34adb1efc1fe3 100644
--- a/media/gpu/video_decode_accelerator_unittest.cc
+++ b/media/gpu/video_decode_accelerator_unittest.cc
@@ -206,15 +206,15 @@ void ReadGoldenThumbnailMD5s(const TestVideoFile* video_file,
if (md5_string.at(0) == '#')
continue;
- LOG_ASSERT(static_cast<int>(md5_string.length()) == kMD5StringLength)
- << md5_string;
+ LOG_IF(WARNING, static_cast<int>(md5_string.length()) != kMD5StringLength)
+ << "MD5 length error: " << md5_string;
bool hex_only = std::count_if(md5_string.begin(), md5_string.end(),
isxdigit) == kMD5StringLength;
- LOG_ASSERT(hex_only) << md5_string;
+ LOG_IF(WARNING, !hex_only) << "MD5 includes non-hex char: " << md5_string;
}
- LOG_ASSERT(md5_strings->size() >= 1U) << " MD5 checksum file ("
- << filepath.MaybeAsASCII()
- << ") missing or empty.";
+ LOG_IF(ERROR, md5_strings->size() < 1U) << " MD5 checksum file ("
Owen Lin 2016/12/27 07:32:44 == 0 Why this one is error and others are just war
johnylin1 2016/12/27 14:02:06 My opinion is "missing file" will definitely make
wuchengli 2017/01/03 09:10:11 +1. Use LOG_IF(ERROR, for consistency because it's
johnylin1 2017/01/04 15:34:36 Done.
+ << filepath.MaybeAsASCII()
+ << ") missing or empty.";
}
// State of the GLRenderingVDAClient below. Order matters here as the test
@@ -1280,20 +1280,53 @@ void VideoDecodeAcceleratorTest::OutputLogFile(
class VideoDecodeAcceleratorParamTest
: public VideoDecodeAcceleratorTest,
public ::testing::WithParamInterface<
- std::tuple<int, int, int, ResetPoint, ClientState, bool, bool>> {};
+ std::tuple<int, int, int, ResetPoint, ClientState, bool, bool>> {
+ protected:
+ using NotesVector =
+ std::vector<std::unique_ptr<ClientStateNotification<ClientState>>>;
+ using ClientsVector = std::vector<std::unique_ptr<GLRenderingVDAClient>>;
+
+ // Delete all GLRenderingClient objects in their own thread.
+ void DeleteClientsAndNotes(ClientsVector clients, NotesVector notes);
+};
+
+void VideoDecodeAcceleratorParamTest::DeleteClientsAndNotes(
wuchengli 2017/01/03 09:10:12 This can be renamed to VideoDecodeAcceleratorParam
johnylin1 2017/01/04 15:34:36 Sounds great. I override TearDown() in VideoDecode
+ ClientsVector clients,
+ NotesVector notes) {
+ std::unique_ptr<ClientsVector> clients2(new ClientsVector);
+ clients2->swap(clients);
+ std::unique_ptr<NotesVector> notes2(new NotesVector);
+ notes2->swap(notes);
+
+ // |clients| must be deleted first because |clients| use |notes2|.
+ g_env->GetRenderingTaskRunner()->PostTask(
+ FROM_HERE, base::Bind(&Delete<ClientsVector>, base::Passed(&clients2)));
+
+ g_env->GetRenderingTaskRunner()->PostTask(
+ FROM_HERE, base::Bind(&Delete<NotesVector>, base::Passed(&notes2)));
+
+ WaitUntilIdle();
+}
// Wait for |note| to report a state and if it's not |expected_state| then
-// assert |client| has deleted its decoder.
+// expect |client| has deleted its decoder and set terminate_ealy.
static void AssertWaitForStateOrDeleted(
ClientStateNotification<ClientState>* note,
GLRenderingVDAClient* client,
+ bool* terminate_early,
ClientState expected_state) {
+ // If terminate_early is true it means something is already wrong of decoder,
+ // we should bypass all latter state checks.
+ if (*terminate_early)
+ return;
ClientState state = note->Wait();
if (state == expected_state)
return;
- ASSERT_TRUE(client->decoder_deleted())
- << "Decoder not deleted but Wait() returned " << state
- << ", instead of " << expected_state;
+ if (!client->decoder_deleted()) {
+ LOG(ERROR) << "Decoder not deleted but Wait() returned " << state
+ << ", instead of " << expected_state;
+ *terminate_early = true;
+ }
}
// We assert a minimal number of concurrent decoders we expect to succeed.
@@ -1324,9 +1357,6 @@ TEST_P(VideoDecodeAcceleratorParamTest, TestSimpleDecode) {
// Suppress GL rendering for all tests when the "--rendering_fps" is 0.
const bool suppress_rendering = g_rendering_fps == 0;
- using NotesVector =
- std::vector<std::unique_ptr<ClientStateNotification<ClientState>>>;
- using ClientsVector = std::vector<std::unique_ptr<GLRenderingVDAClient>>;
NotesVector notes(num_concurrent_decoders);
ClientsVector clients(num_concurrent_decoders);
@@ -1380,42 +1410,60 @@ TEST_P(VideoDecodeAcceleratorParamTest, TestSimpleDecode) {
// Then wait for all the decodes to finish.
// Only check performance & correctness later if we play through only once.
bool skip_performance_and_correctness_checks = num_play_throughs > 1;
+ bool terminate_early = false;
Owen Lin 2016/12/27 07:32:44 Instead, can we have a helper function which retur
johnylin1 2017/01/04 15:34:36 This is no longer needed since we gonna delete cli
for (size_t i = 0; i < num_concurrent_decoders; ++i) {
ClientStateNotification<ClientState>* note = notes[i].get();
ClientState state = note->Wait();
if (state != CS_INITIALIZED) {
skip_performance_and_correctness_checks = true;
// We expect initialization to fail only when more than the supported
- // number of decoders is instantiated. Assert here that something else
- // didn't trigger failure.
- ASSERT_GT(num_concurrent_decoders,
- static_cast<size_t>(kMinSupportedNumConcurrentDecoders));
+ // number of decoders is instantiated. Break the loop and then terminate
+ // test gracefully that something else didn't trigger failure. Do not use
+ // assertion otherwise clients won't be deleted in the correct thread.
+ if (num_concurrent_decoders <=
+ static_cast<size_t>(kMinSupportedNumConcurrentDecoders)) {
+ LOG(ERROR) << "Initialization failed while the number of decoders "
+ << "is still supportable. num_concurrent_decoders = "
+ << num_concurrent_decoders;
+ terminate_early = true;
+ break;
+ }
continue;
}
- ASSERT_EQ(state, CS_INITIALIZED);
for (int n = 0; n < num_play_throughs; ++n) {
// For play-throughs other than the first, we expect initialization to
// succeed unconditionally.
if (n > 0) {
ASSERT_NO_FATAL_FAILURE(AssertWaitForStateOrDeleted(
- note, clients[i].get(), CS_INITIALIZED));
+ note, clients[i].get(), &terminate_early, CS_INITIALIZED));
}
// InitializeDone kicks off decoding inside the client, so we just need to
// wait for Flush.
- ASSERT_NO_FATAL_FAILURE(
- AssertWaitForStateOrDeleted(note, clients[i].get(), CS_FLUSHING));
- ASSERT_NO_FATAL_FAILURE(
- AssertWaitForStateOrDeleted(note, clients[i].get(), CS_FLUSHED));
+ ASSERT_NO_FATAL_FAILURE(AssertWaitForStateOrDeleted(
+ note, clients[i].get(), &terminate_early, CS_FLUSHING));
+ ASSERT_NO_FATAL_FAILURE(AssertWaitForStateOrDeleted(
+ note, clients[i].get(), &terminate_early, CS_FLUSHED));
// FlushDone requests Reset().
- ASSERT_NO_FATAL_FAILURE(
- AssertWaitForStateOrDeleted(note, clients[i].get(), CS_RESETTING));
+ ASSERT_NO_FATAL_FAILURE(AssertWaitForStateOrDeleted(
+ note, clients[i].get(), &terminate_early, CS_RESETTING));
}
- ASSERT_NO_FATAL_FAILURE(
- AssertWaitForStateOrDeleted(note, clients[i].get(), CS_RESET));
+ ASSERT_NO_FATAL_FAILURE(AssertWaitForStateOrDeleted(
+ note, clients[i].get(), &terminate_early, CS_RESET));
// ResetDone requests Destroy().
- ASSERT_NO_FATAL_FAILURE(
- AssertWaitForStateOrDeleted(note, clients[i].get(), CS_DESTROYED));
+ ASSERT_NO_FATAL_FAILURE(AssertWaitForStateOrDeleted(
+ note, clients[i].get(), &terminate_early, CS_DESTROYED));
+ // Break the loop and terminate test gracefully if there is already
+ // something wrong.
+ if (terminate_early)
+ break;
}
+ // There is already something wrong and should delete clients and then stop
+ // testing.
+ if (terminate_early) {
+ DeleteClientsAndNotes(std::move(clients), std::move(notes));
Owen Lin 2016/12/27 07:32:44 To me, it looks like the main issue here is to cal
johnylin1 2016/12/30 12:38:37 I got another idea is to delete clients and notes
johnylin1 2017/01/04 15:34:36 Override TearDown() is even better and also makes
+ }
+ ASSERT_FALSE(terminate_early) << "Test is terminated due to failure above.";
+
// Finally assert that decoding went as expected.
for (size_t i = 0;
i < num_concurrent_decoders && !skip_performance_and_correctness_checks;
@@ -1485,9 +1533,9 @@ TEST_P(VideoDecodeAcceleratorParamTest, TestSimpleDecode) {
filepath = filepath.AddExtension(FILE_PATH_LITERAL(".png"));
int num_bytes = base::WriteFile(
filepath, reinterpret_cast<char*>(&png[0]), png.size());
- ASSERT_EQ(num_bytes, static_cast<int>(png.size()));
+ EXPECT_EQ(num_bytes, static_cast<int>(png.size()));
}
- ASSERT_NE(match, golden_md5s.end());
+ EXPECT_NE(match, golden_md5s.end());
EXPECT_EQ(alpha_solid, true) << "RGBA frame had incorrect alpha";
}
@@ -1503,19 +1551,7 @@ TEST_P(VideoDecodeAcceleratorParamTest, TestSimpleDecode) {
}
}
- std::unique_ptr<ClientsVector> clients2(new ClientsVector);
- clients2->swap(clients);
- std::unique_ptr<NotesVector> notes2(new NotesVector);
- notes2->swap(notes);
-
- // |clients| must be deleted first because |clients| use |notes2|.
- g_env->GetRenderingTaskRunner()->PostTask(
- FROM_HERE, base::Bind(&Delete<ClientsVector>, base::Passed(&clients2)));
-
- g_env->GetRenderingTaskRunner()->PostTask(
- FROM_HERE, base::Bind(&Delete<NotesVector>, base::Passed(&notes2)));
-
- WaitUntilIdle();
+ DeleteClientsAndNotes(std::move(clients), std::move(notes));
};
// Test that replay after EOS works fine.
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698