first commit
This commit is contained in:
498
project/fm_viewer/fav/VideoDecoderFFmpeg.cpp
Normal file
498
project/fm_viewer/fav/VideoDecoderFFmpeg.cpp
Normal file
@@ -0,0 +1,498 @@
|
||||
/******************************************************************************
|
||||
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
|
||||
******************************************************************************/
|
||||
#include "VideoDecoderFFmpegBase.h"
|
||||
#include "AVCompat.h"
|
||||
#include "factory.h"
|
||||
#include "version.h"
|
||||
#include "Logger.h"
|
||||
|
||||
#define REMOVE_FFMPEG_HW 1
|
||||
|
||||
/*!
|
||||
* options (properties) are from libavcodec/options_table.h
|
||||
* enum name here must convert to lower case to fit the names in avcodec. done in AVDecoder.setOptions()
|
||||
* Don't use lower case here because the value name may be "default" in avcodec which is a keyword of C++
|
||||
*/
|
||||
|
||||
namespace FAV {
|
||||
|
||||
class VideoDecoderFFmpegPrivate;
|
||||
class VideoDecoderFFmpeg : public VideoDecoderFFmpegBase
|
||||
{
|
||||
Q_OBJECT
|
||||
DPTR_DECLARE_PRIVATE(VideoDecoderFFmpeg)
|
||||
Q_PROPERTY(QString codecName READ codecName WRITE setCodecName NOTIFY codecNameChanged)
|
||||
#if !(REMOVE_FFMPEG_HW)
|
||||
Q_PROPERTY(QString hwaccel READ hwaccel WRITE setHwaccel NOTIFY hwaccelChanged)
|
||||
#endif
|
||||
Q_PROPERTY(DiscardType skip_loop_filter READ skipLoopFilter WRITE setSkipLoopFilter)
|
||||
Q_PROPERTY(DiscardType skip_idct READ skipIDCT WRITE setSkipIDCT)
|
||||
// Force a strict standard compliance when encoding (accepted values: -2 to 2)
|
||||
//Q_PROPERTY(StrictType strict READ strict WRITE setStrict)
|
||||
Q_PROPERTY(DiscardType skip_frame READ skipFrame WRITE setSkipFrame)
|
||||
Q_PROPERTY(int threads READ threads WRITE setThreads) // 0 is auto
|
||||
Q_PROPERTY(ThreadFlags thread_type READ threadFlags WRITE setThreadFlags)
|
||||
Q_PROPERTY(MotionVectorVisFlags vismv READ motionVectorVisFlags WRITE setMotionVectorVisFlags)
|
||||
//Q_PROPERTY(BugFlags bug READ bugFlags WRITE setBugFlags)
|
||||
Q_ENUMS(StrictType)
|
||||
Q_ENUMS(DiscardType)
|
||||
Q_ENUMS(ThreadFlag)
|
||||
Q_FLAGS(ThreadFlags)
|
||||
Q_ENUMS(MotionVectorVisFlag)
|
||||
Q_FLAGS(MotionVectorVisFlags)
|
||||
Q_ENUMS(BugFlag)
|
||||
Q_FLAGS(BugFlags)
|
||||
public:
|
||||
enum StrictType {
|
||||
Very = FF_COMPLIANCE_VERY_STRICT,
|
||||
Strict = FF_COMPLIANCE_STRICT,
|
||||
Normal = FF_COMPLIANCE_NORMAL, //default
|
||||
Unofficial = FF_COMPLIANCE_UNOFFICIAL,
|
||||
Experimental = FF_COMPLIANCE_EXPERIMENTAL
|
||||
};
|
||||
|
||||
enum DiscardType { // TODO: discard_type
|
||||
None = AVDISCARD_NONE,
|
||||
Default = AVDISCARD_DEFAULT, //default
|
||||
NoRef = AVDISCARD_NONREF,
|
||||
Bidir = AVDISCARD_BIDIR,
|
||||
NoKey = AVDISCARD_NONKEY,
|
||||
All = AVDISCARD_ALL
|
||||
};
|
||||
|
||||
enum ThreadFlag {
|
||||
DefaultType = FF_THREAD_SLICE | FF_THREAD_FRAME,//default
|
||||
Slice = FF_THREAD_SLICE,
|
||||
Frame = FF_THREAD_FRAME
|
||||
};
|
||||
Q_DECLARE_FLAGS(ThreadFlags, ThreadFlag)
|
||||
// flags. visualize motion vectors (MVs)
|
||||
enum MotionVectorVisFlag {
|
||||
No = 0, //default
|
||||
PF = FF_DEBUG_VIS_MV_P_FOR,
|
||||
BF = FF_DEBUG_VIS_MV_B_FOR,
|
||||
BB = FF_DEBUG_VIS_MV_B_BACK
|
||||
};
|
||||
Q_DECLARE_FLAGS(MotionVectorVisFlags, MotionVectorVisFlag)
|
||||
enum BugFlag {
|
||||
autodetect = FF_BUG_AUTODETECT, //default
|
||||
#if FF_API_OLD_MSMPEG4
|
||||
//old_msmpeg4 = FF_BUG_OLD_MSMPEG4, //moc does not support PP?
|
||||
#endif
|
||||
xvid_ilace = FF_BUG_XVID_ILACE,
|
||||
ump4 = FF_BUG_UMP4,
|
||||
no_padding = FF_BUG_NO_PADDING,
|
||||
amv = FF_BUG_AMV,
|
||||
#if FF_API_AC_VLC
|
||||
//ac_vlc = FF_BUG_AC_VLC, //moc does not support PP?
|
||||
#endif
|
||||
qpel_chroma = FF_BUG_QPEL_CHROMA,
|
||||
std_qpel = FF_BUG_QPEL_CHROMA2,
|
||||
direct_blocksize = FF_BUG_DIRECT_BLOCKSIZE,
|
||||
edge = FF_BUG_EDGE,
|
||||
hpel_chroma = FF_BUG_HPEL_CHROMA,
|
||||
dc_clip = FF_BUG_DC_CLIP,
|
||||
ms = FF_BUG_MS,
|
||||
trunc = FF_BUG_TRUNCATED
|
||||
};
|
||||
Q_DECLARE_FLAGS(BugFlags, BugFlag)
|
||||
|
||||
static VideoDecoder* createMMAL() {
|
||||
VideoDecoderFFmpeg *vd = new VideoDecoderFFmpeg();
|
||||
vd->setProperty("hwaccel", "mmal");
|
||||
return vd;
|
||||
}
|
||||
static VideoDecoder* createQSV() {
|
||||
VideoDecoderFFmpeg *vd = new VideoDecoderFFmpeg();
|
||||
vd->setProperty("hwaccel", "qsv");
|
||||
return vd;
|
||||
}
|
||||
static VideoDecoder* createCrystalHD() {
|
||||
VideoDecoderFFmpeg *vd = new VideoDecoderFFmpeg();
|
||||
vd->setProperty("hwaccel", "crystalhd");
|
||||
return vd;
|
||||
}
|
||||
#if !(REMOVE_FFMPEG_HW)
|
||||
static void registerHWA() {
|
||||
#if defined(Q_OS_WIN32) || (defined(Q_OS_LINUX) && !defined(Q_PROCESSOR_ARM) && !defined(QT_ARCH_ARM))
|
||||
VideoDecoder::Register(VideoDecoderId_QSV, createQSV, "QSV");
|
||||
#endif
|
||||
#ifdef Q_OS_LINUX
|
||||
#if defined(Q_PROCESSOR_ARM)/*qt5*/ || defined(QT_ARCH_ARM) /*qt4*/
|
||||
VideoDecoder::Register(VideoDecoderId_MMAL, createMMAL, "MMAL");
|
||||
#else
|
||||
VideoDecoder::Register(VideoDecoderId_CrystalHD, createCrystalHD, "CrystalHD");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#endif // REMOVE_FFMPEG_HW
|
||||
VideoDecoderFFmpeg();
|
||||
VideoDecoderId id() const Q_DECL_OVERRIDE Q_DECL_FINAL;
|
||||
QString description() const Q_DECL_OVERRIDE Q_DECL_FINAL
|
||||
{
|
||||
const int patch = QTAV_VERSION_PATCH(avcodec_version());
|
||||
return QStringLiteral("%1 avcodec %2.%3.%4")
|
||||
.arg(patch>=100?QStringLiteral("FFmpeg"):QStringLiteral("Libav"))
|
||||
.arg(QTAV_VERSION_MAJOR(avcodec_version())).arg(QTAV_VERSION_MINOR(avcodec_version())).arg(patch);
|
||||
}
|
||||
virtual VideoFrame frame() Q_DECL_OVERRIDE Q_DECL_FINAL;
|
||||
|
||||
// TODO: av_opt_set in setter
|
||||
void setSkipLoopFilter(DiscardType value);
|
||||
DiscardType skipLoopFilter() const;
|
||||
void setSkipIDCT(DiscardType value);
|
||||
DiscardType skipIDCT() const;
|
||||
void setStrict(StrictType value);
|
||||
StrictType strict() const;
|
||||
void setSkipFrame(DiscardType value);
|
||||
DiscardType skipFrame() const;
|
||||
void setThreads(int value);
|
||||
int threads() const;
|
||||
void setThreadFlags(ThreadFlags value);
|
||||
ThreadFlags threadFlags() const;
|
||||
void setMotionVectorVisFlags(MotionVectorVisFlags value);
|
||||
MotionVectorVisFlags motionVectorVisFlags() const;
|
||||
void setBugFlags(BugFlags value);
|
||||
BugFlags bugFlags() const;
|
||||
#if !(REMOVE_FFMPEG_HW)
|
||||
void setHwaccel(const QString& value);
|
||||
QString hwaccel() const;
|
||||
#endif
|
||||
Q_SIGNALS:
|
||||
void codecNameChanged() Q_DECL_OVERRIDE;
|
||||
#if !(REMOVE_FFMPEG_HW)
|
||||
void hwaccelChanged();
|
||||
#endif
|
||||
};
|
||||
|
||||
extern VideoDecoderId VideoDecoderId_FFmpeg;
|
||||
FACTORY_REGISTER(VideoDecoder, FFmpeg, "FFmpeg")
|
||||
|
||||
#if !(REMOVE_FFMPEG_HW)
|
||||
void RegisterFFmpegHWA_Man() {
|
||||
VideoDecoderFFmpeg::registerHWA();
|
||||
}
|
||||
|
||||
namespace {
|
||||
static const struct factory_register_FFmpegHWA {
|
||||
inline factory_register_FFmpegHWA() {
|
||||
VideoDecoderFFmpeg::registerHWA();
|
||||
}
|
||||
} sInit_FFmpegHWA;
|
||||
}
|
||||
#endif // #if !(REMOVE_FFMPEG_HW)
|
||||
|
||||
class VideoDecoderFFmpegPrivate Q_DECL_FINAL: public VideoDecoderFFmpegBasePrivate
|
||||
{
|
||||
public:
|
||||
VideoDecoderFFmpegPrivate():
|
||||
VideoDecoderFFmpegBasePrivate()
|
||||
, skip_loop_filter(VideoDecoderFFmpeg::Default)
|
||||
, skip_idct(VideoDecoderFFmpeg::Default)
|
||||
, strict(VideoDecoderFFmpeg::Normal)
|
||||
, skip_frame(VideoDecoderFFmpeg::Default)
|
||||
, thread_type(VideoDecoderFFmpeg::DefaultType) //
|
||||
, threads(0)
|
||||
, debug_mv(VideoDecoderFFmpeg::No)
|
||||
, bug(VideoDecoderFFmpeg::autodetect)
|
||||
{
|
||||
|
||||
}
|
||||
bool open() Q_DECL_OVERRIDE
|
||||
{
|
||||
av_opt_set_int(codec_ctx, "skip_loop_filter", (int64_t)skip_loop_filter, 0);
|
||||
av_opt_set_int(codec_ctx, "skip_idct", (int64_t)skip_idct, 0);
|
||||
av_opt_set_int(codec_ctx, "strict", (int64_t)strict, 0);
|
||||
av_opt_set_int(codec_ctx, "skip_frame", (int64_t)skip_frame, 0);
|
||||
av_opt_set_int(codec_ctx, "threads", (int64_t)threads, 0);
|
||||
av_opt_set_int(codec_ctx, "thread_type", (int64_t)thread_type, 0);
|
||||
av_opt_set_int(codec_ctx, "vismv", (int64_t)debug_mv, 0);
|
||||
av_opt_set_int(codec_ctx, "bug", (int64_t)bug, 0);
|
||||
|
||||
//qInfo() << "thread_type:" << thread_type;
|
||||
//CODEC_FLAG_EMU_EDGE: deprecated in ffmpeg >=? & libav>=10. always set by ffmpeg
|
||||
#if 0
|
||||
if (fast) {
|
||||
codec_ctx->flags2 |= CODEC_FLAG2_FAST; // TODO:
|
||||
} else {
|
||||
//codec_ctx->flags2 &= ~CODEC_FLAG2_FAST; //ffplay has no this
|
||||
}
|
||||
// lavfilter
|
||||
//codec_ctx->slice_flags |= SLICE_FLAG_ALLOW_FIELD; //lavfilter
|
||||
//codec_ctx->strict_std_compliance = FF_COMPLIANCE_STRICT;
|
||||
codec_ctx->thread_safe_callbacks = true;
|
||||
switch (codec_ctx->codec_id) {
|
||||
case QTAV_CODEC_ID(MPEG4):
|
||||
case QTAV_CODEC_ID(H263):
|
||||
codec_ctx->thread_type = 0;
|
||||
break;
|
||||
case QTAV_CODEC_ID(MPEG1VIDEO):
|
||||
case QTAV_CODEC_ID(MPEG2VIDEO):
|
||||
codec_ctx->thread_type &= ~FF_THREAD_SLICE;
|
||||
/* fall through */
|
||||
# if (LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55, 1, 0))
|
||||
case QTAV_CODEC_ID(H264):
|
||||
case QTAV_CODEC_ID(VC1):
|
||||
case QTAV_CODEC_ID(WMV3):
|
||||
codec_ctx->thread_type &= ~FF_THREAD_FRAME;
|
||||
# endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
int skip_loop_filter;
|
||||
int skip_idct;
|
||||
int strict;
|
||||
int skip_frame;
|
||||
int thread_type;
|
||||
int threads;
|
||||
int debug_mv;
|
||||
int bug;
|
||||
QString hwa;
|
||||
};
|
||||
|
||||
VideoDecoderFFmpeg::VideoDecoderFFmpeg():
|
||||
VideoDecoderFFmpegBase(*new VideoDecoderFFmpegPrivate())
|
||||
{
|
||||
// dynamic properties about static property details. used by UI
|
||||
// format: detail_property
|
||||
setProperty("detail_skip_loop_filter", "Skipping the loop filter (aka deblocking) usually has determinal effect on quality. However it provides a big speedup for hi definition streams");
|
||||
// like skip_frame
|
||||
setProperty("detail_skip_idct", "Force skipping of idct to speed up decoding for frame types (-1=None, "
|
||||
"0=Default, 1=B-frames, 2=P-frames, 3=B+P frames, 4=all frames)");
|
||||
setProperty("detail_skip_frame","Force skipping frames for speed up decoding.");
|
||||
setProperty("detail_threads", QString("%1\n%2\n%3")
|
||||
.arg("Number of decoding threads. Set before open. Maybe no effect for some decoders")
|
||||
.arg("0: auto")
|
||||
.arg("1: single thread decoding"));
|
||||
}
|
||||
|
||||
VideoDecoderId VideoDecoderFFmpeg::id() const
|
||||
{
|
||||
#if !(REMOVE_FFMPEG_HW)
|
||||
DPTR_D(const VideoDecoderFFmpeg);
|
||||
if (d.hwa == QLatin1String("mmal"))
|
||||
return VideoDecoderId_MMAL;
|
||||
if (d.hwa == QLatin1String("qsv"))
|
||||
return VideoDecoderId_QSV;
|
||||
if (d.hwa == QLatin1String("crystalhd"))
|
||||
return VideoDecoderId_CrystalHD;
|
||||
#endif
|
||||
return VideoDecoderId_FFmpeg;
|
||||
}
|
||||
#if (1)
|
||||
VideoFrame VideoDecoderFFmpeg::frame()
|
||||
{
|
||||
DPTR_D(VideoDecoderFFmpeg);
|
||||
if (d.frame->width <= 0 || d.frame->height <= 0 || !d.codec_ctx)
|
||||
return VideoFrame();
|
||||
|
||||
// it's safe if width, height, pixfmt will not change, only data change
|
||||
VideoFrame frame(d.frame->width, d.frame->height, VideoFormat((int)d.codec_ctx->pix_fmt));
|
||||
frame.setDisplayAspectRatio(d.getDAR(d.frame));
|
||||
frame.setBits(d.frame->data);
|
||||
frame.setBytesPerLine(d.frame->linesize);
|
||||
// in s. TODO: what about AVFrame.pts? av_frame_get_best_effort_timestamp? move to VideoFrame::from(AVFrame*)
|
||||
//frame.setTimestamp((double)d.frame->pkt_pts/1000.0);
|
||||
//qInfo() << "### SETPTS:" << d.frame->pkt_pts << d.frame->pts << "DTS:" << d.frame->pkt_dts << __FUNCTION__;
|
||||
frame.setPTS((double)d.frame->pkt_pts/1000.0);
|
||||
frame.setDuration(((double)d.frame->pkt_duration)/1000.0); // 2024/02/07 추가 KEYFRAME 도 추가가능..
|
||||
|
||||
frame.setMetaData(QStringLiteral("avbuf"), QVariant::fromValue(AVFrameBuffersRef(new AVFrameBuffers(d.frame))));
|
||||
d.updateColorDetails(&frame);
|
||||
if (frame.format().hasPalette()) {
|
||||
frame.setMetaData(QStringLiteral("pallete"), QByteArray((const char*)d.frame->data[1], 256*4));
|
||||
}
|
||||
return frame;
|
||||
}
|
||||
#else
|
||||
VideoFrame VideoDecoderFFmpeg::frame()
|
||||
{
|
||||
DPTR_D(VideoDecoderFFmpeg);
|
||||
if (!d.codec_ctx)
|
||||
return VideoFrame();
|
||||
|
||||
if(d.frame->width == 0)
|
||||
{
|
||||
d.frame->width = 1280;
|
||||
d.frame->height = 720;
|
||||
d.frame->linesize[0] = 1280;
|
||||
d.frame->linesize[1] = 640;
|
||||
d.frame->linesize[2] = 640;
|
||||
|
||||
}
|
||||
|
||||
//qDebug() << "format" << (int)(d.codec_ctx->pix_fmt) << "width" << d.frame->width << "height" << d.frame->height;
|
||||
|
||||
|
||||
VideoFrame frame(d.frame->width, d.frame->height, VideoFormat((int)0)); // VideoFormat::Format_YUV420P
|
||||
|
||||
// it's safe if width, height, pixfmt will not change, only data change
|
||||
// VideoFrame frame(d.frame->width, d.frame->height, VideoFormat((int)d.codec_ctx->pix_fmt));
|
||||
frame.setDisplayAspectRatio(d.getDAR(d.frame));
|
||||
frame.setBits(d.frame->data);
|
||||
frame.setBytesPerLine(d.frame->linesize);
|
||||
// in s. TODO: what about AVFrame.pts? av_frame_get_best_effort_timestamp? move to VideoFrame::from(AVFrame*)
|
||||
frame.setTimestamp((double)d.frame->pkt_pts/1000.0);
|
||||
frame.setMetaData(QStringLiteral("avbuf"), QVariant::fromValue(AVFrameBuffersRef(new AVFrameBuffers(d.frame))));
|
||||
d.updateColorDetails(&frame);
|
||||
if (frame.format().hasPalette()) {
|
||||
frame.setMetaData(QStringLiteral("pallete"), QByteArray((const char*)d.frame->data[1], 256*4));
|
||||
}
|
||||
return frame;
|
||||
}
|
||||
#endif
|
||||
void VideoDecoderFFmpeg::setSkipLoopFilter(DiscardType value)
|
||||
{
|
||||
DPTR_D(VideoDecoderFFmpeg);
|
||||
d.skip_loop_filter = value;
|
||||
if (d.codec_ctx)
|
||||
av_opt_set_int(d.codec_ctx, "skip_loop_filter", (int64_t)value, 0);
|
||||
}
|
||||
|
||||
VideoDecoderFFmpeg::DiscardType VideoDecoderFFmpeg::skipLoopFilter() const
|
||||
{
|
||||
return (DiscardType)d_func().skip_loop_filter;
|
||||
}
|
||||
|
||||
void VideoDecoderFFmpeg::setSkipIDCT(DiscardType value)
|
||||
{
|
||||
DPTR_D(VideoDecoderFFmpeg);
|
||||
d.skip_idct = (int)value;
|
||||
if (d.codec_ctx)
|
||||
av_opt_set_int(d.codec_ctx, "skip_idct", (int64_t)value, 0);
|
||||
}
|
||||
|
||||
VideoDecoderFFmpeg::DiscardType VideoDecoderFFmpeg::skipIDCT() const
|
||||
{
|
||||
return (DiscardType)d_func().skip_idct;
|
||||
}
|
||||
|
||||
void VideoDecoderFFmpeg::setStrict(StrictType value)
|
||||
{
|
||||
DPTR_D(VideoDecoderFFmpeg);
|
||||
d.strict = (int)value;
|
||||
if (d.codec_ctx)
|
||||
av_opt_set_int(d.codec_ctx, "strict", int64_t(value), 0);
|
||||
}
|
||||
|
||||
VideoDecoderFFmpeg::StrictType VideoDecoderFFmpeg::strict() const
|
||||
{
|
||||
return (StrictType)d_func().strict;
|
||||
}
|
||||
|
||||
void VideoDecoderFFmpeg::setSkipFrame(DiscardType value)
|
||||
{
|
||||
DPTR_D(VideoDecoderFFmpeg);
|
||||
d.skip_frame = (int)value;
|
||||
if (d.codec_ctx)
|
||||
av_opt_set_int(d.codec_ctx, "skip_frame", (int64_t)value, 0);
|
||||
}
|
||||
|
||||
VideoDecoderFFmpeg::DiscardType VideoDecoderFFmpeg::skipFrame() const
|
||||
{
|
||||
return (DiscardType)d_func().skip_frame;
|
||||
}
|
||||
|
||||
void VideoDecoderFFmpeg::setThreads(int value)
|
||||
{
|
||||
DPTR_D(VideoDecoderFFmpeg);
|
||||
d.threads = value;
|
||||
if (d.codec_ctx)
|
||||
av_opt_set_int(d.codec_ctx, "threads", (int64_t)value, 0);
|
||||
}
|
||||
|
||||
int VideoDecoderFFmpeg::threads() const
|
||||
{
|
||||
return d_func().threads;
|
||||
}
|
||||
|
||||
void VideoDecoderFFmpeg::setThreadFlags(ThreadFlags value)
|
||||
{
|
||||
DPTR_D(VideoDecoderFFmpeg);
|
||||
d.thread_type = (int)value;
|
||||
if (d.codec_ctx)
|
||||
av_opt_set_int(d.codec_ctx, "thread_type", (int64_t)value, 0);
|
||||
}
|
||||
|
||||
VideoDecoderFFmpeg::ThreadFlags VideoDecoderFFmpeg::threadFlags() const
|
||||
{
|
||||
return (ThreadFlags)d_func().thread_type;
|
||||
}
|
||||
|
||||
void VideoDecoderFFmpeg::setMotionVectorVisFlags(MotionVectorVisFlags value)
|
||||
{
|
||||
DPTR_D(VideoDecoderFFmpeg);
|
||||
d.debug_mv = (int)value;
|
||||
if (d.codec_ctx)
|
||||
av_opt_set_int(d.codec_ctx, "vismv", (int64_t)value, 0);
|
||||
}
|
||||
|
||||
VideoDecoderFFmpeg::MotionVectorVisFlags VideoDecoderFFmpeg::motionVectorVisFlags() const
|
||||
{
|
||||
return (MotionVectorVisFlags)d_func().debug_mv;
|
||||
}
|
||||
|
||||
void VideoDecoderFFmpeg::setBugFlags(BugFlags value)
|
||||
{
|
||||
DPTR_D(VideoDecoderFFmpeg);
|
||||
d.bug = (int)value;
|
||||
if (d.codec_ctx)
|
||||
av_opt_set_int(d.codec_ctx, "bug", (int64_t)value, 0);
|
||||
}
|
||||
|
||||
VideoDecoderFFmpeg::BugFlags VideoDecoderFFmpeg::bugFlags() const
|
||||
{
|
||||
return (BugFlags)d_func().bug;
|
||||
}
|
||||
#if !(REMOVE_FFMPEG_HW)
|
||||
void VideoDecoderFFmpeg::setHwaccel(const QString &value)
|
||||
{
|
||||
DPTR_D(VideoDecoderFFmpeg);
|
||||
if (d.hwa == value)
|
||||
return;
|
||||
d.hwa = value.toLower();
|
||||
Q_EMIT hwaccelChanged();
|
||||
}
|
||||
|
||||
QString VideoDecoderFFmpeg::hwaccel() const
|
||||
{
|
||||
return d_func().hwa;
|
||||
}
|
||||
#endif
|
||||
void i18n()
|
||||
{
|
||||
"codecName";
|
||||
"skip_loop_filter";
|
||||
"skip_idct";
|
||||
"strict";
|
||||
"skip_frame";
|
||||
"threads";
|
||||
"thread_type";
|
||||
"vismv";
|
||||
"bug";
|
||||
}
|
||||
} //namespace FAV
|
||||
|
||||
#include "VideoDecoderFFmpeg.moc"
|
||||
Reference in New Issue
Block a user