From 9899853a9d62ea60769ec18e815a1cf8313c6749 Mon Sep 17 00:00:00 2001 From: Youngwoo Cho Date: Tue, 19 Dec 2023 12:01:54 +0900 Subject: [PATCH] [0.3.158] Add tests and fix not displaying window to unittest - add tests : seek, playback rate : separate by visual verification - fix display window : change playerTCWindow to singleton Change-Id: Icf6623af534202a9e8dbc320e62b22b7d3621d95 Signed-off-by: Youngwoo Cho --- unittest/playerTCInfo.hpp | 4 ++ unittest/playerTCWindow.hpp | 100 ++++++++++++++++++--------- unittest/player_ut.cpp | 165 ++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 221 insertions(+), 48 deletions(-) diff --git a/unittest/playerTCInfo.hpp b/unittest/playerTCInfo.hpp index eaf74d3..6e6a599 100644 --- a/unittest/playerTCInfo.hpp +++ b/unittest/playerTCInfo.hpp @@ -47,6 +47,10 @@ struct tcInfos { } video; }; +std::ostream& operator << (std::ostream &os, const tcInfos &tcInfos_) { + return (os << tcInfos_.filePath); +} + class playerTCInfo { private: diff --git a/unittest/playerTCWindow.hpp b/unittest/playerTCWindow.hpp index 1ecdffd..58bc384 100644 --- a/unittest/playerTCWindow.hpp +++ b/unittest/playerTCWindow.hpp @@ -20,57 +20,89 @@ #include +#define PACKAGE_NAME "player_ut" + namespace playerUTInfo { namespace { +class PlayerTCWindow; + +static std::unique_ptr ptr; -class playerTCWindow +class PlayerTCWindow { public: - playerTCWindow() { - elm_init(0, NULL); - _create(); - } + ~PlayerTCWindow(); - ~playerTCWindow() { - _destroy(); - elm_shutdown(); - } + PlayerTCWindow(const PlayerTCWindow& rhs) = delete; + PlayerTCWindow& operator=(const PlayerTCWindow& rhs) = delete; + + static PlayerTCWindow& Instance(); + static void WindowThread(PlayerTCWindow* tcWindow); - Evas_Object* getEvasObject() { return _evasObject; } + Evas_Object* getEvasObject() { return _evasObjectWin; } private: - Evas_Object* _evasObject = nullptr; + PlayerTCWindow(); + + void createWindow_(); - void _create(); - void _destroy(); + Evas_Object* _evasObjectWin = nullptr; + bool thread_init_done_ = false; + std::thread thread_; }; -void playerTCWindow::_create() -{ +PlayerTCWindow& PlayerTCWindow::Instance() { + if (!ptr.get()) ptr.reset(new PlayerTCWindow()); + return *(ptr.get()); +} + +PlayerTCWindow::PlayerTCWindow() { + thread_ = std::thread(PlayerTCWindow::WindowThread, this); + while (!thread_init_done_) { + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + std::cout << "PlayerTCWindow()" << std::endl; +} + +PlayerTCWindow::~PlayerTCWindow() { + ecore_thread_main_loop_begin(); + elm_exit(); + ecore_thread_main_loop_end(); + thread_.join(); + std::cout << "~PlayerTCWindow()" << std::endl; +} + +void PlayerTCWindow::WindowThread(PlayerTCWindow* tcWindow) { + elm_init(1, NULL); + tcWindow->createWindow_(); + tcWindow->thread_init_done_ = true; + elm_run(); + elm_shutdown(); +} + +void PlayerTCWindow::createWindow_() { int w = 0; int h = 0; - elm_config_accel_preference_set("opengl"); - _evasObject = elm_win_add(NULL, "player_ut", ELM_WIN_BASIC); - assert(_evasObject && "window is NULL."); - - elm_win_title_set(_evasObject, "player_ut"); - elm_win_borderless_set(_evasObject, EINA_TRUE); - elm_win_screen_size_get(_evasObject, NULL, NULL, &w, &h); - evas_object_resize(_evasObject, w, h); - elm_win_autodel_set(_evasObject, EINA_TRUE); - elm_win_alpha_set(_evasObject, EINA_TRUE); - elm_win_activate(_evasObject); - evas_object_show(_evasObject); -} + ecore_thread_main_loop_begin(); -void playerTCWindow::_destroy() -{ - if (_evasObject) { - evas_object_del(_evasObject); - _evasObject = nullptr; - } + _evasObjectWin = elm_win_add(NULL, PACKAGE_NAME, ELM_WIN_BASIC); + assert(_evasObjectWin); + + elm_win_title_set(_evasObjectWin, PACKAGE_NAME); + elm_win_autodel_set(_evasObjectWin, EINA_TRUE); + elm_win_aux_hint_add(_evasObjectWin, "wm.policy.win.user.geometry", "1"); + + elm_win_screen_size_get(_evasObjectWin, NULL, NULL, &w, &h); + std::cout << "width, height: " << w << ", " << h << std::endl; + evas_object_move(_evasObjectWin, 0, 0); + evas_object_resize(_evasObjectWin, w, h); + evas_object_show(_evasObjectWin); + + ecore_thread_main_loop_end(); + + std::cout << "Window [" << _evasObjectWin << "]" << std::endl; } } diff --git a/unittest/player_ut.cpp b/unittest/player_ut.cpp index b30672b..3bd6d40 100644 --- a/unittest/player_ut.cpp +++ b/unittest/player_ut.cpp @@ -30,23 +30,53 @@ using namespace playerUTInfo; class PlayerContentsTest : public ::testing::TestWithParam { public: + PlayerContentsTest() : tcWindow_(PlayerTCWindow::Instance()) { } + virtual void SetUp() override { + ASSERT_EQ(player_create(&_player), PLAYER_ERROR_NONE); + std::cout << "SetUp()" << std::endl; - _tcWindow = std::make_shared(); } virtual void TearDown() override { + ASSERT_EQ(player_destroy(_player), PLAYER_ERROR_NONE); + std::cout << "TearDown()" << std::endl; } - player_h _player; + int TestSetPlayPosition(int milliseconds, bool accurate) { + _seek_done = false; + return player_set_play_position(_player, milliseconds, accurate, seek_completed_cb, this); + } - std::shared_ptr GetAppWindow() { - return _tcWindow; + static void seek_completed_cb(void *user_data) { + auto test_ = static_cast(user_data); + std::unique_lock lk(test_->_seek_done_m); + test_->_seek_done = true; + std::cout << "seek_completed_cb()" << std::endl; + lk.unlock(); + test_->_seek_done_cv.notify_all(); } + bool WaitForSeek() { + std::unique_lock lk(_seek_done_m); + std::cout << "WaitForSeek start" << std::endl; + if (!_seek_done) { + _seek_done_cv.wait_for(lk, std::chrono::seconds(10), + [this]() -> bool { return _seek_done; }); + } + std::cout << "WaitForSeek stop" << std::endl; + return _seek_done; + } + +public: + player_h _player {}; + PlayerTCWindow& tcWindow_; + private: - std::shared_ptr _tcWindow; + std::mutex _seek_done_m; + std::condition_variable _seek_done_cv; + bool _seek_done = true; }; TEST_P(PlayerContentsTest, contents_test_p) { @@ -62,14 +92,15 @@ TEST_P(PlayerContentsTest, contents_test_p) { int h = 0; tcInfos _tcInfos = GetParam(); + std::cout << "dir: " << _tcInfos << std::endl; - auto tcWindow = GetAppWindow(); + ecore_thread_main_loop_begin(); + ASSERT_EQ(player_set_display(_player, PLAYER_DISPLAY_TYPE_OVERLAY, tcWindow_.getEvasObject()), PLAYER_ERROR_NONE); + ecore_thread_main_loop_end(); - ASSERT_EQ(player_create(&_player), PLAYER_ERROR_NONE); - EXPECT_EQ(player_set_display(_player, PLAYER_DISPLAY_TYPE_OVERLAY, tcWindow->getEvasObject()), PLAYER_ERROR_NONE); + ASSERT_EQ(player_set_uri(_player, _tcInfos.filePath.c_str()), PLAYER_ERROR_NONE); + ASSERT_EQ(player_prepare(_player), PLAYER_ERROR_NONE); - EXPECT_EQ(player_set_uri(_player, _tcInfos.filePath.c_str()), PLAYER_ERROR_NONE); - EXPECT_EQ(player_prepare(_player), PLAYER_ERROR_NONE); EXPECT_EQ(player_get_duration(_player, &duration), PLAYER_ERROR_NONE); EXPECT_EQ(duration, _tcInfos.totalDuration); @@ -98,15 +129,121 @@ TEST_P(PlayerContentsTest, contents_test_p) { free(video_codec); EXPECT_EQ(player_start(_player), PLAYER_ERROR_NONE); - std::this_thread::sleep_for(std::chrono::milliseconds(5000)); + std::this_thread::sleep_for(std::chrono::seconds(1)); - EXPECT_EQ(player_stop(_player), PLAYER_ERROR_NONE); + std::cout << "playback rate 0.5" << std::endl; + EXPECT_EQ(player_set_playback_rate(_player, 0.5), PLAYER_ERROR_NONE); + std::cout << "playback rate 2.0" << std::endl; + EXPECT_EQ(player_set_playback_rate(_player, 2.0), PLAYER_ERROR_NONE); + + std::cout << "playback rate 1.0" << std::endl; + EXPECT_EQ(player_set_playback_rate(_player, 1.0), PLAYER_ERROR_NONE); + + std::cout << "seek to " << duration / 4 << " with accurate 0" << std::endl; + int ret = TestSetPlayPosition(duration / 4, 0); + EXPECT_EQ(ret, PLAYER_ERROR_NONE); + if (ret == PLAYER_ERROR_NONE) { + EXPECT_TRUE(WaitForSeek()); + } + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + + std::cout << "seek to " << duration / 2 << " with accurate 1" << std::endl; + ret = TestSetPlayPosition(duration / 2, 1); + EXPECT_EQ(ret, PLAYER_ERROR_NONE); + if (ret == PLAYER_ERROR_NONE) { + EXPECT_TRUE(WaitForSeek()); + } + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + + EXPECT_EQ(player_stop(_player), PLAYER_ERROR_NONE); EXPECT_EQ(player_unprepare(_player), PLAYER_ERROR_NONE); - EXPECT_EQ(player_destroy(_player), PLAYER_ERROR_NONE); +} + +TEST_P(PlayerContentsTest, DISABLED_visual_verify_contents_test_p) { + int duration = 0; + int sample_rate = 0; + int channel = 0; + int bit_rate = 0; + int fps = 0; + int v_bit_rate = 0; + char *audio_codec = NULL; + char *video_codec = NULL; + int w = 0; + int h = 0; + + tcInfos _tcInfos = GetParam(); + std::cout << "dir: " << _tcInfos << std::endl; + + ecore_thread_main_loop_begin(); + ASSERT_EQ(player_set_display(_player, PLAYER_DISPLAY_TYPE_OVERLAY, tcWindow_.getEvasObject()), PLAYER_ERROR_NONE); + ecore_thread_main_loop_end(); + + ASSERT_EQ(player_set_uri(_player, _tcInfos.filePath.c_str()), PLAYER_ERROR_NONE); + ASSERT_EQ(player_prepare(_player), PLAYER_ERROR_NONE); + + EXPECT_EQ(player_get_duration(_player, &duration), PLAYER_ERROR_NONE); + EXPECT_EQ(duration, _tcInfos.totalDuration); + EXPECT_EQ(player_get_audio_stream_info(_player, &sample_rate, &channel, &bit_rate), PLAYER_ERROR_NONE); + EXPECT_EQ(sample_rate, _tcInfos.audio.sampleRate); + EXPECT_EQ(channel, _tcInfos.audio.channels); + EXPECT_EQ(bit_rate, _tcInfos.audio.bitrate); + + EXPECT_EQ(player_get_video_stream_info(_player, &fps, &v_bit_rate), PLAYER_ERROR_NONE); + EXPECT_EQ(fps, _tcInfos.video.fps); + EXPECT_EQ(v_bit_rate, _tcInfos.video.bitrate); + + EXPECT_EQ(player_get_video_size(_player, &w, &h), PLAYER_ERROR_NONE); + EXPECT_EQ(w, _tcInfos.video.width); + EXPECT_EQ(h, _tcInfos.video.height); + + EXPECT_EQ(player_get_codec_info(_player, &audio_codec, &video_codec), PLAYER_ERROR_NONE); + std::string audioCodecName = audio_codec; + EXPECT_NE(audioCodecName.find(_tcInfos.audio.codecName), std::string::npos); + if (audio_codec) + free(audio_codec); + + std::string videoCodecName = video_codec; + EXPECT_NE(videoCodecName.find(_tcInfos.video.codecName), std::string::npos); + if (video_codec) + free(video_codec); + + EXPECT_EQ(player_start(_player), PLAYER_ERROR_NONE); + std::this_thread::sleep_for(std::chrono::seconds(3)); + + std::cout << "playback rate 0.5" << std::endl; + EXPECT_EQ(player_set_playback_rate(_player, 0.5), PLAYER_ERROR_NONE); + std::this_thread::sleep_for(std::chrono::seconds(2)); + + std::cout << "playback rate 2.0" << std::endl; + EXPECT_EQ(player_set_playback_rate(_player, 2.0), PLAYER_ERROR_NONE); + std::this_thread::sleep_for(std::chrono::seconds(2)); + + std::cout << "playback rate 1.0" << std::endl; + EXPECT_EQ(player_set_playback_rate(_player, 1.0), PLAYER_ERROR_NONE); + std::this_thread::sleep_for(std::chrono::seconds(2)); + + std::cout << "seek to " << duration / 4 << " with accurate 0" << std::endl; + int ret = TestSetPlayPosition(duration / 4, 0); + EXPECT_EQ(ret, PLAYER_ERROR_NONE); + if (ret == PLAYER_ERROR_NONE) { + EXPECT_TRUE(WaitForSeek()); + } + std::this_thread::sleep_for(std::chrono::seconds(3)); + + std::cout << "seek to " << duration / 2 << " with accurate 1" << std::endl; + ret = TestSetPlayPosition(duration / 2, 1); + EXPECT_EQ(ret, PLAYER_ERROR_NONE); + if (ret == PLAYER_ERROR_NONE) { + EXPECT_TRUE(WaitForSeek()); + } + std::this_thread::sleep_for(std::chrono::seconds(3)); + + EXPECT_EQ(player_stop(_player), PLAYER_ERROR_NONE); + EXPECT_EQ(player_unprepare(_player), PLAYER_ERROR_NONE); } INSTANTIATE_TEST_SUITE_P(PlayerContentsTestFull, PlayerContentsTest, - ::testing::ValuesIn(playerTCInfo("codec").getTCInfos()) + ::testing::ValuesIn(playerTCInfo("TestContents").getTCInfos()) ); \ No newline at end of file -- 2.7.4