Files
fmviewer3/project/fm_viewer/fav/ImageConverterFF.cpp
2026-02-21 17:11:31 +09:00

134 lines
4.6 KiB
C++

/******************************************************************************
ImageConverterFF: Image resizing & color model convertion using FFmpeg swscale
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 "ImageConverter.h"
#include "ImageConverter_p.h"
#include "AVCompat.h"
#include "mkid.h"
#include "factory.h"
#include "Logger.h"
namespace FAV {
ImageConverterId ImageConverterId_FF = mkid::id32base36_6<'F', 'F', 'm', 'p', 'e', 'g'>::value;
FACTORY_REGISTER(ImageConverter, FF, "FFmpeg")
class ImageConverterFFPrivate Q_DECL_FINAL: public ImageConverterPrivate
{
public:
ImageConverterFFPrivate()
: sws_ctx(0)
, update_eq(true)
{}
~ImageConverterFFPrivate() {
if (sws_ctx) {
sws_freeContext(sws_ctx);
sws_ctx = 0;
}
}
virtual bool setupColorspaceDetails(bool force = true) Q_DECL_FINAL;
SwsContext *sws_ctx;
bool update_eq;
};
ImageConverterFF::ImageConverterFF()
:ImageConverter(*new ImageConverterFFPrivate())
{
}
bool ImageConverterFF::check() const
{
if (!ImageConverter::check())
return false;
DPTR_D(const ImageConverterFF);
if (sws_isSupportedInput((AVPixelFormat)d.fmt_in) <= 0) {
qWarning("Input pixel format not supported (%s)", av_get_pix_fmt_name((AVPixelFormat)d.fmt_in));
return false;
}
if (sws_isSupportedOutput((AVPixelFormat)d.fmt_out) <= 0) {
qWarning("Output pixel format not supported (%s)", av_get_pix_fmt_name((AVPixelFormat)d.fmt_out));
return false;
}
return true;
}
bool ImageConverterFF::convert(const quint8 *const src[], const int srcStride[], quint8 *const dst[], const int dstStride[])
{
DPTR_D(ImageConverterFF);
//Check out dimension. equals to in dimension if not setted. TODO: move to another common func
if (d.w_out == 0 || d.h_out == 0) {
if (d.w_in == 0 || d.h_in == 0)
return false;
setOutSize(d.w_in, d.h_in);
}
//TODO: move those code to prepare()
d.sws_ctx = sws_getCachedContext(d.sws_ctx
, d.w_in, d.h_in, (AVPixelFormat)d.fmt_in
, d.w_out, d.h_out, (AVPixelFormat)d.fmt_out
, (d.w_in == d.w_out && d.h_in == d.h_out) ? SWS_POINT : SWS_FAST_BILINEAR //SWS_BICUBIC
, NULL, NULL, NULL
);
//int64_t flags = SWS_CPU_CAPS_SSE2 | SWS_CPU_CAPS_MMX | SWS_CPU_CAPS_MMX2;
//av_opt_set_int(d.sws_ctx, "sws_flags", flags, 0);
if (!d.sws_ctx)
return false;
d.setupColorspaceDetails(false);
int result_h = sws_scale(d.sws_ctx, src, srcStride, 0, d.h_in, dst, dstStride);
if (result_h != d.h_out) {
qDebug("convert failed: %d, %d", result_h, d.h_out);
return false;
}
Q_UNUSED(result_h);
for (int i = 0; i < d.pitchs.size(); ++i) {
d.bits[i] = dst[i];
d.pitchs[i] = dstStride[i];
}
return true;
}
bool ImageConverterFFPrivate::setupColorspaceDetails(bool force)
{
if (!sws_ctx) {
update_eq = true;
return false;
}
if (force)
update_eq = true;
if (!update_eq) {
return true;
}
const int srcRange = range_in == ColorRange_Limited ? 0 : 1;
int dstRange = range_out == ColorRange_Limited ? 0 : 1;
// TODO: color space
bool supported = sws_setColorspaceDetails(sws_ctx, sws_getCoefficients(SWS_CS_DEFAULT)
, srcRange, sws_getCoefficients(SWS_CS_DEFAULT)
, dstRange
, ((brightness << 16) + 50)/100
, (((contrast + 100) << 16) + 50)/100
, (((saturation + 100) << 16) + 50)/100
) >= 0;
//sws_init_context(d.sws_ctx, NULL, NULL);
update_eq = false;
return supported;
}
} //namespace FAV