first commit
This commit is contained in:
455
project/fm_viewer/fav/_fav_constants.cpp
Normal file
455
project/fm_viewer/fav/_fav_constants.cpp
Normal file
@@ -0,0 +1,455 @@
|
||||
/******************************************************************************
|
||||
QtAV: Multimedia framework based on Qt and FFmpeg
|
||||
Copyright (C) 2012-2016 Wang Bin <wbsecg1@gmail.com>
|
||||
|
||||
* This file is part of QtAV
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
******************************************************************************/
|
||||
|
||||
#include "_fav_constants.h"
|
||||
#include <QtCore/QLibraryInfo>
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QRegExp>
|
||||
#include "version.h"
|
||||
#include "AVCompat.h"
|
||||
#include "internal.h"
|
||||
#include "Logger.h"
|
||||
|
||||
#if (PLAY_SYNC_FIX2)
|
||||
#include <QElapsedTimer>
|
||||
QElapsedTimer g_et;
|
||||
#endif // #if (PLAY_SYNC_FIX2)
|
||||
|
||||
unsigned QtAV_Version()
|
||||
{
|
||||
return QTAV_VERSION;
|
||||
}
|
||||
|
||||
QString QtAV_Version_String()
|
||||
{
|
||||
// vs<2015: C2308: concatenating mismatched strings for QStringLiteral("a" "b")
|
||||
return QString::fromLatin1(QTAV_VERSION_STR);
|
||||
}
|
||||
|
||||
#define QTAV_VERSION_STR_LONG QTAV_VERSION_STR "(" __DATE__ ", " __TIME__ ")"
|
||||
|
||||
QString QtAV_Version_String_Long()
|
||||
{
|
||||
return QString::fromLatin1(QTAV_VERSION_STR_LONG);
|
||||
}
|
||||
|
||||
int g_SkipCount = 0; // none
|
||||
|
||||
int g_firstCorruptFrameSkipWait = 10; // 10ms
|
||||
|
||||
namespace FAV {
|
||||
|
||||
namespace Internal {
|
||||
// disable logging for release. you can manually enable it.
|
||||
#if defined(QT_NO_DEBUG)// && !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(Q_OS_WINRT)
|
||||
static FAV::LogLevel gLogLevel = FAV::LogOff;
|
||||
#else
|
||||
static FAV::LogLevel gLogLevel = FAV::LogAll; // LogOff; //LogAll,LogOff;
|
||||
#endif
|
||||
static bool gLogLevelSet = false;
|
||||
bool isLogLevelSet() { return gLogLevelSet;}
|
||||
static int gAVLogLevel = AV_LOG_ERROR;//AV_LOG_ERROR;//AV_LOG_ERROR, AV_LOG_QUIET;// AV_LOG_TRACE;//AV_LOG_INFO;
|
||||
} //namespace Internal
|
||||
|
||||
//TODO: auto add new depend libraries information
|
||||
QString aboutFFmpeg_PlainText()
|
||||
{
|
||||
return aboutFFmpeg_HTML().remove(QRegExp(QStringLiteral("<[^>]*>")));
|
||||
}
|
||||
|
||||
namespace Internal {
|
||||
typedef struct depend_component {
|
||||
const char* lib;
|
||||
unsigned build_version;
|
||||
unsigned rt_version;
|
||||
const char *config;
|
||||
const char *license;
|
||||
} depend_component;
|
||||
|
||||
static unsigned get_qt_version() {
|
||||
int major = 0, minor = 0, patch = 0;
|
||||
if (sscanf(qVersion(), "%d.%d.%d", &major, &minor, &patch) != 3)
|
||||
qWarning("Can not recognize Qt runtime version");
|
||||
return QT_VERSION_CHECK(major, minor, patch);
|
||||
}
|
||||
|
||||
static const depend_component* get_depend_component(const depend_component* info = 0)
|
||||
{
|
||||
// DO NOT use QStringLiteral here because the install script use strings to search "Qt-" in the library. QStringLiteral will place it in .ro and strings can not find it
|
||||
static const QByteArray qt_license(QLibraryInfo::licensee().prepend(QLatin1String("Qt-" QT_VERSION_STR " licensee: ")).toUtf8());
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 3, 0)
|
||||
static const char* qt_build_info = get_qt_version() >= QT_VERSION_CHECK(5, 3, 0) ? QLibraryInfo::build() : "";
|
||||
#else
|
||||
static const char* qt_build_info = "";
|
||||
#endif
|
||||
static const depend_component components[] = {
|
||||
{ "Qt", QT_VERSION, get_qt_version(), qt_build_info, qt_license.constData() },
|
||||
//TODO: auto check loaded libraries
|
||||
#define FF_COMPONENT(name, NAME) #name, LIB##NAME##_VERSION_INT, name##_version(), name##_configuration(), name##_license()
|
||||
{ FF_COMPONENT(avutil, AVUTIL) },
|
||||
{ FF_COMPONENT(avcodec, AVCODEC) },
|
||||
{ FF_COMPONENT(avformat, AVFORMAT) },
|
||||
#if QTAV_HAVE(AVFILTER)
|
||||
{ FF_COMPONENT(avfilter, AVFILTER) },
|
||||
#endif //QTAV_HAVE(AVFILTER)
|
||||
#if QTAV_HAVE(AVDEVICE)
|
||||
{ FF_COMPONENT(avdevice, AVDEVICE) },
|
||||
#endif //QTAV_HAVE(AVDEVICE)
|
||||
#if QTAV_HAVE(AVRESAMPLE)
|
||||
{ FF_COMPONENT(avresample, AVRESAMPLE) },
|
||||
#endif //QTAV_HAVE(AVRESAMPLE)
|
||||
#if QTAV_HAVE(SWRESAMPLE)
|
||||
{ FF_COMPONENT(swresample, SWRESAMPLE) },
|
||||
#endif //QTAV_HAVE(SWRESAMPLE)
|
||||
{ FF_COMPONENT(swscale, SWSCALE) },
|
||||
#undef FF_COMPONENT
|
||||
{ 0, 0, 0, 0, 0 }
|
||||
};
|
||||
if (!info)
|
||||
return &components[0];
|
||||
// invalid input ptr
|
||||
if (((ptrdiff_t)info - (ptrdiff_t)(&components[0]))%sizeof(depend_component))
|
||||
return 0;
|
||||
const depend_component *next = info;
|
||||
next++;
|
||||
if (!next->lib)
|
||||
return 0;
|
||||
return next;
|
||||
}
|
||||
|
||||
void print_library_info()
|
||||
{
|
||||
//qDebug() << aboutQtAV_PlainText().toUtf8().constData();
|
||||
const depend_component* info = Internal::get_depend_component(0);
|
||||
while (info) {
|
||||
if (!qstrcmp(info->lib, "avutil"))
|
||||
qDebug("FFmpeg/Libav configuration: %s", info->config);
|
||||
qDebug("Build with %s-%u.%u.%u"
|
||||
, info->lib
|
||||
, QTAV_VERSION_MAJOR(info->build_version)
|
||||
, QTAV_VERSION_MINOR(info->build_version)
|
||||
, QTAV_VERSION_PATCH(info->build_version)
|
||||
);
|
||||
unsigned rt_version = info->rt_version;
|
||||
if (info->build_version != rt_version) {
|
||||
qWarning("Warning: %s runtime version %u.%u.%u mismatch!"
|
||||
, info->lib
|
||||
, QTAV_VERSION_MAJOR(rt_version)
|
||||
, QTAV_VERSION_MINOR(rt_version)
|
||||
, QTAV_VERSION_PATCH(rt_version)
|
||||
);
|
||||
}
|
||||
info = Internal::get_depend_component(info);
|
||||
}
|
||||
}
|
||||
|
||||
} //namespace Internal
|
||||
|
||||
QString aboutFFmpeg_HTML()
|
||||
{
|
||||
QString text = QStringLiteral("<h3>FFmpeg/Libav</h3>\n");
|
||||
const Internal::depend_component* info = Internal::get_depend_component(0);
|
||||
while (info) {
|
||||
text += QStringLiteral("<h4>%1: %2-%3.%4.%5</h4>\n")
|
||||
.arg("Build version")
|
||||
.arg(QLatin1String(info->lib))
|
||||
.arg(QTAV_VERSION_MAJOR(info->build_version))
|
||||
.arg(QTAV_VERSION_MINOR(info->build_version))
|
||||
.arg(QTAV_VERSION_PATCH(info->build_version))
|
||||
;
|
||||
unsigned rt_version = info->rt_version;
|
||||
if (info->build_version != rt_version) {
|
||||
text += QStringLiteral("<h4 style='color:#ff0000;'>%1: %2.%3.%4</h4>\n")
|
||||
.arg("Runtime version")
|
||||
.arg(QTAV_VERSION_MAJOR(rt_version))
|
||||
.arg(QTAV_VERSION_MINOR(rt_version))
|
||||
.arg(QTAV_VERSION_PATCH(rt_version))
|
||||
;
|
||||
}
|
||||
text += QStringLiteral("<p>%1</p>\n<p>%2</p>\n").arg(QString::fromUtf8(info->config)).arg(QString::fromUtf8(info->license));
|
||||
info = Internal::get_depend_component(info);
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
QString aboutQtAV_PlainText()
|
||||
{
|
||||
return aboutQtAV_HTML().remove(QRegExp(QStringLiteral("<[^>]*>")));
|
||||
}
|
||||
|
||||
QString aboutQtAV_HTML()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
void setLogLevel(LogLevel value)
|
||||
{
|
||||
Internal::gLogLevelSet = true;
|
||||
Internal::gLogLevel = value;
|
||||
}
|
||||
|
||||
LogLevel logLevel()
|
||||
{
|
||||
return (LogLevel)Internal::gLogLevel;
|
||||
}
|
||||
|
||||
void setFFmpegLogHandler(void (*callback)(void *, int, const char *, va_list))
|
||||
{
|
||||
// libav does not check null callback
|
||||
if (!callback)
|
||||
callback = av_log_default_callback;
|
||||
av_log_set_callback(callback);
|
||||
}
|
||||
|
||||
void setFFmpegLogLevel(const QByteArray &level)
|
||||
{
|
||||
if (level.isEmpty())
|
||||
return;
|
||||
bool ok = false;
|
||||
const int value = level.toInt(&ok);
|
||||
if ((ok && value == 0) || level == "off" || level == "quiet")
|
||||
Internal::gAVLogLevel = AV_LOG_QUIET;
|
||||
else if (level == "panic")
|
||||
Internal::gAVLogLevel = AV_LOG_PANIC;
|
||||
else if (level == "fatal")
|
||||
Internal::gAVLogLevel = AV_LOG_FATAL;
|
||||
else if (level == "error")
|
||||
Internal::gAVLogLevel = AV_LOG_ERROR;
|
||||
else if (level.startsWith("warn"))
|
||||
Internal::gAVLogLevel = AV_LOG_WARNING;
|
||||
else if (level == "info")
|
||||
Internal::gAVLogLevel = AV_LOG_INFO;
|
||||
else if (level == "verbose")
|
||||
Internal::gAVLogLevel = AV_LOG_VERBOSE;
|
||||
else if (level == "debug")
|
||||
Internal::gAVLogLevel = AV_LOG_DEBUG;
|
||||
#ifdef AV_LOG_TRACE
|
||||
else if (level == "trace")
|
||||
Internal::gAVLogLevel = AV_LOG_TRACE;
|
||||
#endif
|
||||
else
|
||||
Internal::gAVLogLevel = AV_LOG_INFO;
|
||||
av_log_set_level(Internal::gAVLogLevel);
|
||||
}
|
||||
|
||||
static void qtav_ffmpeg_log_callback(void* ctx, int level,const char* fmt, va_list vl)
|
||||
{
|
||||
// AV_LOG_DEBUG is used by ffmpeg developers
|
||||
if (level > Internal::gAVLogLevel)
|
||||
return;
|
||||
AVClass *c = ctx ? *(AVClass**)ctx : 0;
|
||||
QString qmsg = QString().sprintf("[FFmpeg:%s] ", c ? c->item_name(ctx) : "?") + QString().vsprintf(fmt, vl);
|
||||
qmsg = qmsg.trimmed();
|
||||
if (level > AV_LOG_WARNING)
|
||||
qDebug() << qPrintable(qmsg);
|
||||
else if (level > AV_LOG_PANIC)
|
||||
qWarning() << qPrintable(qmsg);
|
||||
}
|
||||
|
||||
QString avformatOptions()
|
||||
{
|
||||
static QString opts;
|
||||
if (!opts.isEmpty())
|
||||
return opts;
|
||||
void* obj = const_cast<void*>(reinterpret_cast<const void*>(avformat_get_class()));
|
||||
opts = Internal::optionsToString((void*)&obj);
|
||||
opts.append(ushort('\n'));
|
||||
av_register_all();
|
||||
AVInputFormat *i = NULL;
|
||||
while ((i = av_iformat_next(i))) {
|
||||
QString opt(Internal::optionsToString((void*)&i->priv_class).trimmed());
|
||||
if (opt.isEmpty())
|
||||
continue;
|
||||
opts.append(QStringLiteral("options for input format %1:\n%2\n\n")
|
||||
.arg(QLatin1String(i->name))
|
||||
.arg(opt));
|
||||
}
|
||||
AVOutputFormat *o = NULL;
|
||||
while ((o = av_oformat_next(o))) {
|
||||
QString opt(Internal::optionsToString((void*)&o->priv_class).trimmed());
|
||||
if (opt.isEmpty())
|
||||
continue;
|
||||
opts.append(QStringLiteral("options for output format %1:\n%2\n\n")
|
||||
.arg(QLatin1String(o->name))
|
||||
.arg(opt));
|
||||
}
|
||||
return opts;
|
||||
}
|
||||
|
||||
QString avcodecOptions()
|
||||
{
|
||||
static QString opts;
|
||||
if (!opts.isEmpty())
|
||||
return opts;
|
||||
void* obj = const_cast<void*>(reinterpret_cast<const void*>(avcodec_get_class()));
|
||||
opts = Internal::optionsToString((void*)&obj);
|
||||
opts.append(ushort('\n'));
|
||||
avcodec_register_all();
|
||||
AVCodec* c = NULL;
|
||||
while ((c=av_codec_next(c))) {
|
||||
QString opt(Internal::optionsToString((void*)&c->priv_class).trimmed());
|
||||
if (opt.isEmpty())
|
||||
continue;
|
||||
opts.append(QStringLiteral("Options for codec %1:\n%2\n\n").arg(QLatin1String(c->name)).arg(opt));
|
||||
}
|
||||
return opts;
|
||||
}
|
||||
|
||||
#if 0
|
||||
const QStringList& supportedInputMimeTypes()
|
||||
{
|
||||
static QStringList mimes;
|
||||
if (!mimes.isEmpty())
|
||||
return mimes;
|
||||
av_register_all(); // MUST register all input/output formats
|
||||
AVOutputFormat *i = av_oformat_next(NULL);
|
||||
QStringList list;
|
||||
while (i) {
|
||||
list << QString(i->mime_type).split(QLatin1Char(','), QString::SkipEmptyParts);
|
||||
i = av_oformat_next(i);
|
||||
}
|
||||
foreach (const QString& v, list) {
|
||||
mimes.append(v.trimmed());
|
||||
}
|
||||
mimes.removeDuplicates();
|
||||
return mimes;
|
||||
}
|
||||
|
||||
static QStringList s_audio_mimes, s_video_mimes, s_subtitle_mimes;
|
||||
static void init_supported_codec_info() {
|
||||
const AVCodecDescriptor* cd = avcodec_descriptor_next(NULL);
|
||||
while (cd) {
|
||||
QStringList list;
|
||||
if (cd->mime_types) {
|
||||
for (int i = 0; cd->mime_types[i]; ++i) {
|
||||
list.append(QString(cd->mime_types[i]).trimmed());
|
||||
}
|
||||
}
|
||||
switch (cd->type) {
|
||||
case AVMEDIA_TYPE_AUDIO:
|
||||
s_audio_mimes << list;
|
||||
break;
|
||||
case AVMEDIA_TYPE_VIDEO:
|
||||
s_video_mimes << list;
|
||||
case AVMEDIA_TYPE_SUBTITLE:
|
||||
s_subtitle_mimes << list;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
cd = avcodec_descriptor_next(cd);
|
||||
}
|
||||
s_audio_mimes.removeDuplicates();
|
||||
s_video_mimes.removeDuplicates();
|
||||
s_subtitle_mimes.removeDuplicates();
|
||||
}
|
||||
const QStringList& supportedAudioMimeTypes()
|
||||
{
|
||||
if (s_audio_mimes.isEmpty())
|
||||
init_supported_codec_info();
|
||||
return s_audio_mimes;
|
||||
}
|
||||
|
||||
const QStringList& supportedVideoMimeTypes()
|
||||
{
|
||||
if (s_video_mimes.isEmpty())
|
||||
init_supported_codec_info();
|
||||
return s_video_mimes;
|
||||
}
|
||||
// TODO: subtitleprocessor support
|
||||
const QStringList& supportedSubtitleMimeTypes()
|
||||
{
|
||||
if (s_subtitle_mimes.isEmpty())
|
||||
init_supported_codec_info();
|
||||
return s_subtitle_mimes;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* AVColorSpace:
|
||||
* libav11 libavutil54.3.0 pixfmt.h, ffmpeg2.1*libavutil52.48.101 frame.h
|
||||
* ffmpeg2.5 pixfmt.h. AVFrame.colorspace
|
||||
* earlier versions: avcodec.h, avctx.colorspace
|
||||
*/
|
||||
ColorSpace colorSpaceFromFFmpeg(AVColorSpace cs)
|
||||
{
|
||||
switch (cs) {
|
||||
// from ffmpeg: order of coefficients is actually GBR
|
||||
case AVCOL_SPC_RGB: return ColorSpace_GBR;
|
||||
case AVCOL_SPC_BT709: return ColorSpace_BT709;
|
||||
case AVCOL_SPC_BT470BG: return ColorSpace_BT601;
|
||||
case AVCOL_SPC_SMPTE170M: return ColorSpace_BT601;
|
||||
default: return ColorSpace_Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
ColorRange colorRangeFromFFmpeg(AVColorRange cr)
|
||||
{
|
||||
switch (cr) {
|
||||
case AVCOL_RANGE_MPEG: return ColorRange_Limited;
|
||||
case AVCOL_RANGE_JPEG: return ColorRange_Full;
|
||||
default: return ColorRange_Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
static const struct RegisterMetaTypes {
|
||||
RegisterMetaTypes() {
|
||||
qRegisterMetaType<FAV::MediaStatus>("FAV::MediaStatus");
|
||||
}
|
||||
} _registerMetaTypes;
|
||||
}
|
||||
|
||||
// TODO: static link. move all into 1
|
||||
namespace {
|
||||
class InitFFmpegLog {
|
||||
public:
|
||||
InitFFmpegLog() {
|
||||
setFFmpegLogHandler(qtav_ffmpeg_log_callback);
|
||||
FAV::setFFmpegLogLevel(qgetenv("QTAV_FFMPEG_LOG").toLower());
|
||||
}
|
||||
};
|
||||
InitFFmpegLog fflog;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Initialize Qt Resource System when the library is built
|
||||
// statically
|
||||
static void initResources() {
|
||||
#if (PLAYER_ONLY_LIBRARY_MODE)
|
||||
Q_INIT_RESOURCE(shaders_lib);
|
||||
#else // SUPPORT_LIBRARY_MODE
|
||||
Q_INIT_RESOURCE(shaders);
|
||||
#endif // SUPPORT_LIBRARY_MODE
|
||||
//Q_INIT_RESOURCE(FAV);
|
||||
}
|
||||
|
||||
namespace {
|
||||
class ResourceLoader {
|
||||
public:
|
||||
ResourceLoader() { initResources(); }
|
||||
};
|
||||
|
||||
ResourceLoader FAV_QRCLoader;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user