Merge branch 'master' into hashremoval

This commit is contained in:
itsmattkc
2022-05-22 16:59:35 -07:00
6 changed files with 69 additions and 47 deletions
+1 -1
View File
@@ -186,7 +186,7 @@ public:
*/
bool RetrieveVideo(TexturePtr destination, const rational& timecode, const RetrieveVideoParams& divider, const QAtomicInt *cancelled = nullptr);
virtual VideoParams GetParamsForTexture(const Decoder::RetrieveVideoParams &p) const
virtual VideoParams GetParamsForTexture(const Decoder::RetrieveVideoParams &p)
{
return VideoParams();
}
+44 -25
View File
@@ -26,6 +26,7 @@ extern "C" {
#include <libavfilter/buffersrc.h>
#include <libavformat/avformat.h>
#include <libavutil/imgutils.h>
#include <libavutil/opt.h>
#include <libavutil/pixdesc.h>
}
@@ -54,6 +55,8 @@ FFmpegDecoder::FFmpegDecoder() :
filter_graph_(nullptr),
buffersrc_ctx_(nullptr),
buffersink_ctx_(nullptr),
input_fmt_(AV_PIX_FMT_NONE),
native_pix_fmt_(VideoParams::kFormatInvalid),
working_frame_(nullptr),
working_packet_(nullptr),
is_working_(false),
@@ -70,22 +73,6 @@ bool FFmpegDecoder::OpenInternal()
// Store one second in the source's timebase
second_ts_ = qRound64(av_q2d(av_inv_q(s->time_base)));
if (s->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
// Get an Olive compatible AVPixelFormat
ideal_pix_fmt_ = FFmpegUtils::GetCompatiblePixelFormat(static_cast<AVPixelFormat>(s->codecpar->format));
// Determine which Olive native pixel format we retrieved
// Note that FFmpeg doesn't support float formats
native_pix_fmt_ = GetNativePixelFormat(ideal_pix_fmt_);
native_channel_count_ = GetNativeChannelCount(ideal_pix_fmt_);
if (native_pix_fmt_ == VideoParams::kFormatInvalid
|| native_channel_count_ == 0) {
qCritical() << "Failed to find valid native pixel format for" << ideal_pix_fmt_;
return false;
}
}
working_frame_ = av_frame_alloc();
working_packet_ = av_packet_alloc();
@@ -154,7 +141,7 @@ bool FFmpegDecoder::OpenInternal()
bool FFmpegDecoder::RetrieveVideoInternal(TexturePtr destination, const rational &timecode, const RetrieveVideoParams &params, const QAtomicInt *cancelled)
{
if (AVFramePtr f = RetrieveFrame(timecode, cancelled)) {
if (InitScaler(params)) {
if (InitScaler(f.get(), params)) {
int r;
r = av_buffersrc_add_frame_flags(buffersrc_ctx_, f.get(), AV_BUFFERSRC_FLAG_KEEP_REF);
if (r < 0) {
@@ -193,6 +180,9 @@ void FFmpegDecoder::CloseInternal()
FreeScaler();
instance_.Close();
input_fmt_ = AV_PIX_FMT_NONE;
native_pix_fmt_ = VideoParams::kFormatInvalid;
}
QString FFmpegDecoder::id() const
@@ -239,6 +229,8 @@ FootageDescription FFmpegDecoder::Probe(const QString &filename, const QAtomicIn
if (avstream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
AVPixelFormat compatible_pix_fmt = AV_PIX_FMT_NONE;
bool image_is_still = false;
rational pixel_aspect_ratio;
rational frame_rate;
@@ -271,6 +263,9 @@ FootageDescription FFmpegDecoder::Probe(const QString &filename, const QAtomicIn
frame_rate = av_guess_frame_rate(instance.fmt_ctx(),
instance.avstream(),
frame);
compatible_pix_fmt = FFmpegUtils::GetCompatiblePixelFormat(static_cast<AVPixelFormat>(avstream->codecpar->format));
qDebug() << "GOT IT FROM FRAME" << compatible_pix_fmt;
}
// Read second frame
@@ -309,8 +304,6 @@ FootageDescription FFmpegDecoder::Probe(const QString &filename, const QAtomicIn
av_packet_free(&pkt);
}
AVPixelFormat compatible_pix_fmt = FFmpegUtils::GetCompatiblePixelFormat(static_cast<AVPixelFormat>(avstream->codecpar->format));
VideoParams stream;
stream.set_stream_index(i);
stream.set_width(avstream->codecpar->width);
@@ -781,9 +774,9 @@ AVFramePtr FFmpegDecoder::RetrieveFrame(const rational& time, const QAtomicInt *
return return_frame;
}
bool FFmpegDecoder::InitScaler(const RetrieveVideoParams& params)
bool FFmpegDecoder::InitScaler(AVFrame *input, const RetrieveVideoParams& params)
{
if (params == filter_params_ && filter_graph_) {
if (params == filter_params_ && filter_graph_ && input_fmt_ == input->format) {
// We have an appropriate filter for these parameters, just return true
return true;
}
@@ -794,6 +787,24 @@ bool FFmpegDecoder::InitScaler(const RetrieveVideoParams& params)
// Set our params to this
filter_params_ = params;
input_fmt_ = static_cast<AVPixelFormat>(input->format);
if (input_fmt_ == AV_PIX_FMT_NONE) {
return false;
}
// Get an Olive compatible AVPixelFormat
AVPixelFormat ideal_pix_fmt = FFmpegUtils::GetCompatiblePixelFormat(static_cast<AVPixelFormat>(input_fmt_));
// Determine which Olive native pixel format we retrieved
// Note that FFmpeg doesn't support float formats
native_pix_fmt_ = GetNativePixelFormat(ideal_pix_fmt);
native_channel_count_ = GetNativeChannelCount(ideal_pix_fmt);
if (native_pix_fmt_ == VideoParams::kFormatInvalid
|| native_channel_count_ == 0) {
qCritical() << "Failed to find valid native pixel format for" << ideal_pix_fmt;
return false;
}
// Allocate filter graph
filter_graph_ = avfilter_graph_alloc();
@@ -813,7 +824,7 @@ bool FFmpegDecoder::InitScaler(const RetrieveVideoParams& params)
snprintf(filter_args, kFilterArgSz, "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
src_width,
src_height,
s->codecpar->format,
input->format,
s->time_base.num,
s->time_base.den,
s->codecpar->sample_aspect_ratio.num,
@@ -862,10 +873,10 @@ bool FFmpegDecoder::InitScaler(const RetrieveVideoParams& params)
}
// Add format filter if necessary
if (ideal_pix_fmt_ != s->codecpar->format) {
if (ideal_pix_fmt != input->format) {
AVFilterContext* format_filter;
snprintf(filter_args, kFilterArgSz, "pix_fmts=%u", ideal_pix_fmt_);
snprintf(filter_args, kFilterArgSz, "pix_fmts=%u", ideal_pix_fmt);
avfilter_graph_create_filter(&format_filter, avfilter_get_by_name("format"), "format", filter_args, nullptr, filter_graph_);
@@ -936,8 +947,16 @@ void FFmpegDecoder::RemoveFirstFrame()
cache_at_zero_ = false;
}
VideoParams FFmpegDecoder::GetParamsForTexture(const Decoder::RetrieveVideoParams &p) const
VideoParams FFmpegDecoder::GetParamsForTexture(const Decoder::RetrieveVideoParams &p)
{
if (native_pix_fmt_ == VideoParams::kFormatInvalid) {
if (instance_.IsOpen()) {
instance_.GetFrame(working_packet_, working_frame_);
InitScaler(working_frame_, p);
av_frame_unref(working_frame_);
}
}
return VideoParams(instance_.avstream()->codecpar->width,
instance_.avstream()->codecpar->height,
native_pix_fmt_,
+8 -3
View File
@@ -66,7 +66,7 @@ public:
virtual FootageDescription Probe(const QString &filename, const QAtomicInt *cancelled) const override;
virtual VideoParams GetParamsForTexture(const Decoder::RetrieveVideoParams &p) const override;
virtual VideoParams GetParamsForTexture(const Decoder::RetrieveVideoParams &p) override;
protected:
virtual bool OpenInternal() override;
@@ -87,6 +87,11 @@ private:
bool Open(const char* filename, int stream_index);
bool IsOpen() const
{
return fmt_ctx_;
}
void Close();
/**
@@ -134,7 +139,7 @@ private:
*/
static QString FFmpegError(int error_code);
bool InitScaler(const RetrieveVideoParams &params);
bool InitScaler(AVFrame *input, const RetrieveVideoParams &params);
void FreeScaler();
static VideoParams::Format GetNativePixelFormat(AVPixelFormat pix_fmt);
@@ -156,7 +161,7 @@ private:
AVFilterGraph* filter_graph_;
AVFilterContext* buffersrc_ctx_;
AVFilterContext* buffersink_ctx_;
AVPixelFormat ideal_pix_fmt_;
AVPixelFormat input_fmt_;
VideoParams::Format native_pix_fmt_;
int native_channel_count_;
+7 -7
View File
@@ -117,15 +117,15 @@ FootageDescription OIIODecoder::Probe(const QString &filename, const QAtomicInt*
return desc;
}
VideoParams OIIODecoder::GetParamsForTexture(const RetrieveVideoParams &p) const
VideoParams OIIODecoder::GetParamsForTexture(const RetrieveVideoParams &p)
{
return VideoParams(buffer_->spec().width,
buffer_->spec().height,
pix_fmt_,
channel_count_,
OIIOUtils::GetPixelAspectRatioFromOIIO(buffer_->spec()),
VideoParams::kInterlaceNone, // FIXME: Does OIIO deinterlace for us?
p.divider);
buffer_->spec().height,
pix_fmt_,
channel_count_,
OIIOUtils::GetPixelAspectRatioFromOIIO(buffer_->spec()),
VideoParams::kInterlaceNone, // FIXME: Does OIIO deinterlace for us?
p.divider);
}
bool OIIODecoder::OpenInternal()
+1 -1
View File
@@ -42,7 +42,7 @@ public:
virtual FootageDescription Probe(const QString& filename, const QAtomicInt* cancelled) const override;
virtual VideoParams GetParamsForTexture(const Decoder::RetrieveVideoParams &p) const override;
virtual VideoParams GetParamsForTexture(const Decoder::RetrieveVideoParams &p) override;
protected:
virtual bool OpenInternal() override;
+8 -10
View File
@@ -109,22 +109,20 @@ void TimeBasedView::ZoomIntoCursorPosition(QWheelEvent *event, double scale_mult
}
if (!only_vertical) {
double new_x_scale = GetScale() * scale_multiplier;
int new_x_scroll = qRound(double(cursor_pos.x() + horizontalScrollBar()->value()) / GetScale() * new_x_scale - cursor_pos.x());
emit ScaleChanged(new_x_scale);
double old_scale = GetScale();
emit ScaleChanged(old_scale * scale_multiplier);
// Use GetScale so that if this value was clamped, we don't erroneously use an unclamped value
int new_x_scroll = qRound(double(cursor_pos.x() + horizontalScrollBar()->value()) / old_scale * GetScale() - cursor_pos.x());
horizontalScrollBar()->setValue(new_x_scroll);
}
if (!only_horizontal) {
double new_y_scale = GetYScale() * scale_multiplier;
int new_y_scroll = qRound(double(cursor_pos.y() + verticalScrollBar()->value()) / GetYScale() * new_y_scale - cursor_pos.y());
SetYScale(new_y_scale);
double old_y_scale = GetYScale();
SetYScale(old_y_scale * scale_multiplier);
// Use GetYScale so that if this value was clamped, we don't erroneously use an unclamped value
int new_y_scroll = qRound(double(cursor_pos.y() + verticalScrollBar()->value()) / old_y_scale * GetYScale() - cursor_pos.y());
verticalScrollBar()->setValue(new_y_scroll);
}
}