Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 65 additions & 3 deletions libimageviewer/service/ffmpegvideothumbnailer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<mvideo_thumbnailer_create>(library.resolve("video_thumbnailer_create"));
m_mvideo_thumbnailer_destroy = reinterpret_cast<mvideo_thumbnailer_destroy>(library.resolve("video_thumbnailer_destroy"));
Expand All @@ -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();
Expand All @@ -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) {
Expand Down
44 changes: 44 additions & 0 deletions tests/test_ffmpegvideothumbnailer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

#include <QtTest/QtTest>

Check warning on line 5 in tests/test_ffmpegvideothumbnailer.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QtTest/QtTest> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 5 in tests/test_ffmpegvideothumbnailer.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <QtTest/QtTest> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <gtest/gtest.h>

Check warning on line 6 in tests/test_ffmpegvideothumbnailer.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <gtest/gtest.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 6 in tests/test_ffmpegvideothumbnailer.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <gtest/gtest.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

#include "service/ffmpegvideothumbnailer.h"

Check warning on line 8 in tests/test_ffmpegvideothumbnailer.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "service/ffmpegvideothumbnailer.h" not found.

Check warning on line 8 in tests/test_ffmpegvideothumbnailer.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: "service/ffmpegvideothumbnailer.h" not found.

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());
}
Loading