diff --git a/CMakeLists.txt b/CMakeLists.txt index 7901c7dd..2fe7225b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,17 +18,14 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) include_directories(${PROJECT_BINARY_DIR}) include_directories(${PROJECT_SOURCE_DIR}) - message(STATUS ${CMAKE_CXX_FLAGS}) option(DOTEST "option for test" OFF) - -if(DOTEST) +# Auto enable tests on Debug mode. +if(DOTEST OR (${CMAKE_BUILD_TYPE} MATCHES "Debug")) add_subdirectory(tests) endif() - - add_subdirectory(libimageviewer) add_subdirectory(libimagevisualresult) diff --git a/libimageviewer/service/ffmpegvideothumbnailer.cpp b/libimageviewer/service/ffmpegvideothumbnailer.cpp index 1ddc0ebe..71013d08 100644 --- a/libimageviewer/service/ffmpegvideothumbnailer.cpp +++ b/libimageviewer/service/ffmpegvideothumbnailer.cpp @@ -31,9 +31,68 @@ static video_thumbnailer *m_video_thumbnailer = nullptr; //解析成功标记 static bool resolveSuccessed = false; +/** + @brief 根据传入的库名称 \a strlib 查找 LibrariesPath 目录下的动态库, + 并返回查找到的库名称,这个函数是由于 QLibrary 不会对带后缀的库(*.so.4.11) + 查找而提供的。 + 例如: + 当环境中仅提供 libffmpegthumbnailer.so.4 而不存在 libffmpegthumbnailer.so 时, + QLibrary 抛出错误,此函数会返回 libffmpegthumbnailer.so.4 的名称。 + */ +static QString libPath(const QString &strlib) +{ + QDir dir; + QString path = QLibraryInfo::location(QLibraryInfo::LibrariesPath); + dir.setPath(path); + QStringList list = dir.entryList(QStringList() << (strlib + "*"), QDir::NoDotAndDotDot | QDir::Files); //filter name with strlib + if (list.contains(strlib)) { + return strlib; + } else { + list.sort(); + } + + if (list.size() > 0) { + return list.last(); + } else { + return QString(); + } +} + +/** + @return 初始化 ffmpeg 视频缩略图库并返回是否成功加载。 + 将尝试查找 ffmpegthumbnailer 并解析暴露函数, + + @warning libffmpegthumbnailer.so.4 只对应软件包 libffmpegthumbnailer4v5 , + 若后续软件包更新,需要考虑能否正常查找对应动态库。 + */ bool initFFmpegVideoThumbnailer() { + if (resolveSuccessed) { + return true; + } + + // 没有显式调用 unload() ,动态库会保存在内存中,直到程序结束。resolve() 在内部会自动调用 load() 加载。 QLibrary library("libffmpegthumbnailer.so.4"); + if (!library.load()) { + qWarning() << QString("Find libffmpegthumbnailer.so failed by default, error: %1").arg(library.errorString()); + + // 默认查找失败,尝试手动查找目录 + QString findLib = libPath("libffmpegthumbnailer.so"); + if (findLib.isEmpty()) { + qWarning() << QString("Can not find libffmpegthumbnailer.so, LibrariesPath: %1") + .arg(QLibraryInfo::location(QLibraryInfo::LibrariesPath)); + return false; + } else { + qInfo() << QString("Current find ffmpegthumbnailer lib is %1, LibrariesPath: %2").arg(findLib) + .arg(QLibraryInfo::location(QLibraryInfo::LibrariesPath)); + } + + library.setFileName(findLib); + if (!library.load()) { + qWarning() << QString("Find libffmpegthumbnailer.so failed by find path, error: %1").arg(library.errorString()); + return false; + } + } m_creat_video_thumbnailer = reinterpret_cast(library.resolve("video_thumbnailer_create")); m_mvideo_thumbnailer_destroy = reinterpret_cast(library.resolve("video_thumbnailer_destroy")); @@ -43,7 +102,6 @@ bool initFFmpegVideoThumbnailer() if (nullptr == m_creat_video_thumbnailer) { qWarning() << QString("Resolve libffmpegthumbnailer.so data failed, %1").arg(library.errorString()); - resolveSuccessed = false; return false; } m_video_thumbnailer = m_creat_video_thumbnailer(); @@ -53,15 +111,19 @@ bool initFFmpegVideoThumbnailer() || m_mvideo_thumbnailer_destroy_image_data == nullptr || m_mvideo_thumbnailer_generate_thumbnail_to_buffer == nullptr || m_video_thumbnailer == nullptr) { - resolveSuccessed = false; + qWarning() << QString("Resolve libffmpegthumbnailer.so create video thumbnailer failed, %1") + .arg(library.errorString()); return false; } resolveSuccessed = true; - return true; } +/** + @return 根据传入文件路径 \a url 创建视频缩略图并返回,若未成功解析 libffmpegthumbnailer.so + 动态库,将返回空图片 + */ QImage runFFmpegVideoThumbnailer(const QUrl &url) { if (!resolveSuccessed) { diff --git a/tests/test_ffmpegvideothumbnailer.cpp b/tests/test_ffmpegvideothumbnailer.cpp new file mode 100644 index 00000000..8d94463b --- /dev/null +++ b/tests/test_ffmpegvideothumbnailer.cpp @@ -0,0 +1,44 @@ +// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include +#include + +#include "service/ffmpegvideothumbnailer.h" + +class ut_ffmpegvideothumbnailer : public testing::Test +{ +public: + void SetUp() override; + void TearDown() override; + + bool foundLib = false; +}; + +void ut_ffmpegvideothumbnailer::SetUp() +{ + QString path = QLibraryInfo::location(QLibraryInfo::LibrariesPath); + QStringList libList = QDir(path).entryList({"libffmpegthumbnailer.so*"}, QDir::NoDotAndDotDot | QDir::Files); + + foundLib = !libList.isEmpty(); +} + +void ut_ffmpegvideothumbnailer::TearDown() {} + +TEST_F(ut_ffmpegvideothumbnailer, initFFmpegVideoThumbnailer) +{ + bool ret = initFFmpegVideoThumbnailer(); + ASSERT_EQ(ret, foundLib); +} + +TEST_F(ut_ffmpegvideothumbnailer, runFFmpegVideoThumbnailer) +{ + QImage image = runFFmpegVideoThumbnailer(QUrl()); + ASSERT_TRUE(image.isNull()); + + QString localFile("/usr/share/wallpapers/deepin/abc-123.jpg"); + image = runFFmpegVideoThumbnailer(QUrl::fromLocalFile(localFile)); + bool exceptExists = QFile::exists(localFile) && foundLib; + ASSERT_EQ(exceptExists, !image.isNull()); +} diff --git a/tests/test_movieservice.cpp b/tests/test_movieservice.cpp index c207c75a..427a528e 100644 --- a/tests/test_movieservice.cpp +++ b/tests/test_movieservice.cpp @@ -39,7 +39,7 @@ TEST(movieservice, movieCover) auto image_1 = MovieService::instance()->getMovieCover(QUrl::fromLocalFile(filePath), QApplication::applicationDirPath() + QDir::separator()); //分接口 - auto image_2 = MovieService::instance()->getMovieCover_gstreamer(QUrl::fromLocalFile(filePath)); + auto image_2 = MovieService::instance()->getMovieCover_ffmpegthumbnailerlib(QUrl::fromLocalFile(filePath)); auto image_3 = MovieService::instance()->getMovieCover_ffmpegthumbnailer(QUrl::fromLocalFile(filePath), QApplication::applicationDirPath() + QDir::separator()); //简单判断