first commit

This commit is contained in:
2026-02-21 17:11:31 +09:00
commit 18b4338361
4001 changed files with 365464 additions and 0 deletions

View File

@@ -0,0 +1,308 @@
/******************************************************************************
QtAV: Multimedia framework based on Qt and FFmpeg
Copyright (C) 2012-2016 Wang Bin <wbsecg1@gmail.com>
* This file is part of QtAV (from 2013)
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
******************************************************************************/
/*!
* DO NOT appear qDebug, qWanring etc in Logger.cpp! They are undefined and redefined to QtAV:Internal::Logger.xxx
*/
// we need LogLevel so must include QtAV_Global.h
#include <QtCore/QString>
#include <QtCore/QMutex>
#include "_fav_constants.h"
#include "Logger.h"
#ifndef QTAV_NO_LOG_LEVEL
void ffmpeg_version_print();
namespace FAV {
namespace Internal {
static QString gQtAVLogTag = QString();
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
typedef Logger::Context QMessageLogger;
#endif
static void log_helper(QtMsgType msgType, const QMessageLogger *qlog, const char* msg, va_list ap) {
static QMutex m;
QMutexLocker lock(&m);
Q_UNUSED(lock);
static int repeat = 0;
static QString last_msg;
static QtMsgType last_type = QtDebugMsg;
QString qmsg(gQtAVLogTag);
QString formated;
if (msg) {
formated = QString().vsprintf(msg, ap);
}
// repeate check
if (last_type == msgType && last_msg == formated) {
repeat++;
return;
}
if (repeat > 0) {
// print repeat message and current message
qmsg = QStringLiteral("%1(repeat %2)%3\n%4%5")
.arg(qmsg).arg(repeat).arg(last_msg).arg(qmsg).arg(formated);
} else {
qmsg += formated;
}
repeat = 0;
last_type = msgType;
last_msg = formated;
// qt_message_output is a public api
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
qt_message_output(msgType, qmsg.toUtf8().constData());
return;
#else
if (!qlog) {
QMessageLogContext ctx;
qt_message_output(msgType, ctx, qmsg);
return;
}
#endif
#ifndef QT_NO_DEBUG_STREAM
if (msgType == QtWarningMsg)
qlog->warning() << qmsg;
else if (msgType == QtCriticalMsg)
qlog->critical() << qmsg;
else if (msgType == QtFatalMsg)
qlog->fatal("%s", qmsg.toUtf8().constData());
else
qlog->debug() << qmsg;
#else
if (msgType == QtFatalMsg)
qlog->fatal("%s", qmsg.toUtf8().constData());
#endif //
}
// macro does not support A::##X
void Logger::debug(const char *msg, ...) const
{
#if (OFF_OTHER_DEBUG)
Q_UNUSED(msg)
#else
QtAVDebug d; // initialize something. e.g. environment check
Q_UNUSED(d);
const int v = (int)logLevel();
if (v <= (int)LogOff)
return;
if (v > (int)LogDebug && v < (int)LogAll)
return;
va_list ap;
va_start(ap, msg);
// can not use ctx.debug() <<... because QT_NO_DEBUG_STREAM maybe defined
log_helper(QtDebugMsg, &ctx, msg, ap);
va_end(ap);
#endif
}
void Logger::warning(const char *msg, ...) const
{
QtAVDebug d; // initialize something. e.g. environment check
Q_UNUSED(d);
const int v = (int)logLevel();
if (v <= (int)LogOff)
return;
if (v > (int)LogWarning && v < (int)LogAll)
return;
va_list ap;
va_start(ap, msg);
log_helper(QtWarningMsg, &ctx, msg, ap);
va_end(ap);
}
void Logger::critical(const char *msg, ...) const
{
QtAVDebug d; // initialize something. e.g. environment check
Q_UNUSED(d);
const int v = (int)logLevel();
if (v <= (int)LogOff)
return;
if (v > (int)LogCritical && v < (int)LogAll)
return;
va_list ap;
va_start(ap, msg);
log_helper(QtCriticalMsg, &ctx, msg, ap);
va_end(ap);
}
void Logger::fatal(const char *msg, ...) const Q_DECL_NOTHROW
{
QtAVDebug d; // initialize something. e.g. environment check
Q_UNUSED(d);
const int v = (int)logLevel();
/*
if (v <= (int)LogOff)
abort();
if (v > (int)LogFatal && v < (int)LogAll)
abort();
*/
if (v > (int)LogOff) {
va_list ap;
va_start(ap, msg);
log_helper(QtFatalMsg, &ctx, msg, ap);
va_end(ap);
}
abort();
}
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
#ifndef QT_NO_DEBUG_STREAM
// internal used by Logger::fatal(const char*,...) with log level checked, so always do things here
void Logger::Context::fatal(const char *msg, ...) const Q_DECL_NOTHROW
{
va_list ap;
va_start(ap, msg);
QString qmsg;
if (msg)
qmsg += QString().vsprintf(msg, ap);
qt_message_output(QtFatalMsg, qmsg.toUtf8().constData());
va_end(ap);
abort();
}
#endif //QT_NO_DEBUG_STREAM
#endif //QT_VERSION
#ifndef QT_NO_DEBUG_STREAM
// will print message in ~QDebug()
// can not use QDebug on stack. It must lives in QtAVDebug
QtAVDebug Logger::debug() const
{
QtAVDebug d(QtDebugMsg); //// initialize something. e.g. environment check
const int v = (int)logLevel();
if (v <= (int)LogOff)
return d;
if (v <= (int)LogDebug || v >= (int)LogAll)
d.setQDebug(new QDebug(ctx.debug()));
return d; //ref > 0
}
QtAVDebug Logger::warning() const
{
QtAVDebug d(QtWarningMsg);
const int v = (int)logLevel();
if (v <= (int)LogOff)
return d;
if (v <= (int)LogWarning || v >= (int)LogAll)
d.setQDebug(new QDebug(ctx.warning()));
return d;
}
QtAVDebug Logger::critical() const
{
QtAVDebug d(QtCriticalMsg);
const int v = (int)logLevel();
if (v <= (int)LogOff)
return d;
if (v <= (int)LogCritical || v >= (int)LogAll)
d.setQDebug(new QDebug(ctx.critical()));
return d;
}
// no QMessageLogger::fatal()
#endif //QT_NO_DEBUG_STREAM
bool isLogLevelSet();
void print_library_info();
QtAVDebug::QtAVDebug(QtMsgType t, QDebug *d)
: type(t)
, dbg(0)
{
if (d)
setQDebug(d); // call *dbg << gQtAVLogTag
static bool sFirstRun = true;
if (!sFirstRun)
return;
sFirstRun = false;
printf("%s\n", aboutQtAV_PlainText().toUtf8().constData());
// check environment var and call other functions at first Qt logging call
// always override setLogLevel()
QByteArray env = qgetenv("QTAV_LOG_LEVEL");
if (env.isEmpty())
env = qgetenv("QTAV_LOG");
if (!env.isEmpty()) {
bool ok = false;
const int level = env.toInt(&ok);
if (ok) {
if (level < (int)LogOff)
setLogLevel(LogOff);
else if (level > (int)LogAll)
setLogLevel(LogAll);
else
setLogLevel((LogLevel)level);
} else {
env = env.toLower();
if (env.endsWith("off"))
setLogLevel(LogOff);
else if (env.endsWith("debug"))
setLogLevel(LogDebug);
else if (env.endsWith("warning"))
setLogLevel(LogWarning);
else if (env.endsWith("critical"))
setLogLevel(LogCritical);
else if (env.endsWith("fatal"))
setLogLevel(LogFatal);
else if (env.endsWith("all") || env.endsWith("default"))
setLogLevel(LogAll);
}
}
env = qgetenv("QTAV_LOG_TAG");
if (!env.isEmpty()) {
gQtAVLogTag = QString::fromUtf8(env);
}
if ((int)logLevel() > (int)LogOff) {
print_library_info();
}
}
QtAVDebug::~QtAVDebug()
{
}
void QtAVDebug::setQDebug(QDebug *d)
{
dbg = QSharedPointer<QDebug>(d);
if (dbg && !gQtAVLogTag.isEmpty()) {
*dbg << gQtAVLogTag;
}
}
#if 0
QtAVDebug debug(const char *msg, ...)
{
if ((int)logLevel() > (int)Debug && logLevel() != All) {
return QtAVDebug();
}
va_list ap;
va_start(ap, msg); // use variable arg list
QMessageLogContext ctx;
log_helper(QtDebugMsg, &ctx, msg, ap);
va_end(ap);
return QtAVDebug();
}
#endif
} //namespace Internal
} // namespace FAV
#endif //QTAV_NO_LOG_LEVEL