Skip to content

Commit

Permalink
去掉不常见的tonemap算法,与ffmpeg对齐;
Browse files Browse the repository at this point in the history
整理滤镜部分代码;
  • Loading branch information
RealChuan committed Nov 22, 2023
1 parent 8ec2fc0 commit 8c03273
Show file tree
Hide file tree
Showing 20 changed files with 314 additions and 204 deletions.
2 changes: 2 additions & 0 deletions ffmpeg/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ set(PROJECT_SOURCES
event/seekevent.hpp
event/trackevent.hpp
event/valueevent.hpp
filter/filter.cc
filter/filter.hpp
filter/filtercontext.cc
filter/filtercontext.hpp
filter/filtergraph.cc
Expand Down
8 changes: 4 additions & 4 deletions ffmpeg/audiofifo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ class AudioFifo : public QObject
explicit AudioFifo(CodecContext *ctx, QObject *parent = nullptr);
~AudioFifo() override;

bool realloc(int nb_samples);
auto realloc(int nb_samples) -> bool;

bool write(void **data, int nb_samples);
bool read(void **data, int nb_samples);
auto write(void **data, int nb_samples) -> bool;
auto read(void **data, int nb_samples) -> bool;

int size() const;
auto size() const -> int;

private:
class AudioFifoPrivtate;
Expand Down
36 changes: 20 additions & 16 deletions ffmpeg/audioframeconverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,19 +121,23 @@ AudioFrameConverter::AudioFrameConverter(CodecContext *codecCtx,
{
d_ptr->format = format;
d_ptr->avSampleFormat = getAVSampleFormat(d_ptr->format.sampleFormat());
auto channelLayout = getChannelLayout(d_ptr->format.channelConfig());
auto *avCodecCtx = codecCtx->avCodecCtx();
d_ptr->swrContext = swr_alloc_set_opts(d_ptr->swrContext,
channelLayout,
d_ptr->avSampleFormat,
d_ptr->format.sampleRate(),
avCodecCtx->ch_layout.u.mask,
avCodecCtx->sample_fmt,
avCodecCtx->sample_rate,
0,
nullptr);

int ret = swr_init(d_ptr->swrContext);
AVChannelLayout channelLayout = {AV_CHANNEL_ORDER_UNSPEC};
av_channel_layout_default(&channelLayout, d_ptr->format.channelCount());
// av_channel_layout_from_mask(&channelLayout, getChannelLayout(d_ptr->format.channelConfig()));
auto ret = swr_alloc_set_opts2(&d_ptr->swrContext,
&channelLayout,
d_ptr->avSampleFormat,
d_ptr->format.sampleRate(),
&avCodecCtx->ch_layout,
avCodecCtx->sample_fmt,
avCodecCtx->sample_rate,
0,
nullptr);
if (ret != 0) {
SET_ERROR_CODE(ret);
}
ret = swr_init(d_ptr->swrContext);
if (ret < 0) {
SET_ERROR_CODE(ret);
}
Expand Down Expand Up @@ -186,8 +190,8 @@ auto getAudioFormatFromCodecCtx(CodecContext *codecCtx, int &sampleSize) -> QAud
autioFormat.setChannelCount(ctx->ch_layout.nb_channels);
//autioFormat.setByteOrder(QAudioFormat::LittleEndian);

if (ctx->channel_layout <= 0) {
ctx->channel_layout = getChannaLayoutFromChannalCount(ctx->ch_layout.nb_channels);
if (ctx->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC) {
av_channel_layout_default(&ctx->ch_layout, ctx->ch_layout.nb_channels);
}
auto channelConfig = getChannelConfig(ctx->ch_layout.u.mask);
if (channelConfig == QAudioFormat::ChannelConfigUnknown) {
Expand Down Expand Up @@ -221,8 +225,8 @@ auto getAudioFormatFromCodecCtx(CodecContext *codecCtx, int &sampleSize) -> QAud
sampleSize = 8 * av_get_bytes_per_sample(AV_SAMPLE_FMT_S16);
}

qInfo() << "Current Audio parameters:" << ctx->sample_rate << ctx->channels
<< ctx->channel_layout << ctx->sample_fmt;
qInfo() << "Current Audio parameters:" << ctx->sample_rate << ctx->ch_layout.nb_channels
<< ctx->ch_layout.u.mask << ctx->sample_fmt;
qInfo() << autioFormat << autioFormat.channelConfig();

return autioFormat;
Expand Down
2 changes: 2 additions & 0 deletions ffmpeg/avcontextinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ class FFMPEG_EXPORT AVContextInfo : public QObject
QScopedPointer<AVContextInfoPrivate> d_ptr;
};

using AVContextInfoPtr = QSharedPointer<AVContextInfo>;

} // namespace Ffmpeg

#endif // AVCONTEXTINFO_H
143 changes: 143 additions & 0 deletions ffmpeg/filter/filter.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
#include "filter.hpp"
#include "filtercontext.hpp"
#include "filtergraph.hpp"
#include "filterinout.hpp"

#include <ffmpeg/avcontextinfo.h>
#include <ffmpeg/codeccontext.h>
#include <ffmpeg/frame.hpp>

#include <QDebug>

extern "C" {
#include <libavcodec/avcodec.h>
#include <libavfilter/avfilter.h>
}

namespace Ffmpeg {

class Filter::FilterPrivate
{
public:
explicit FilterPrivate(Filter *q)
: q_ptr(q)
{
filterGraph = new FilterGraph(q_ptr);
}

void initVideoFilter(Frame *frame)
{
auto *avCodecCtx = decContextInfo->codecCtx()->avCodecCtx();
buffersrcCtx = new FilterContext("buffer", q_ptr);
buffersinkCtx = new FilterContext("buffersink", q_ptr);
auto timeBase = decContextInfo->timebase();
auto args
= QString::asprintf("video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
avCodecCtx->width,
avCodecCtx->height,
frame->avFrame()->format, //dec_ctx->pix_fmt,
timeBase.num,
timeBase.den,
avCodecCtx->sample_aspect_ratio.num,
avCodecCtx->sample_aspect_ratio.den);
qDebug() << "Video filter in args:" << args;

create(args);
}

void initAudioFilter()
{
auto *avCodecCtx = decContextInfo->codecCtx()->avCodecCtx();
buffersrcCtx = new FilterContext("abuffer", q_ptr);
buffersinkCtx = new FilterContext("abuffersink", q_ptr);
if (avCodecCtx->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC) {
av_channel_layout_default(&avCodecCtx->ch_layout, avCodecCtx->ch_layout.nb_channels);
}
char buf[64];
av_channel_layout_describe(&avCodecCtx->ch_layout, buf, sizeof(buf));
auto args = QString::asprintf(
"time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=%s" PRIx64,
1,
avCodecCtx->sample_rate,
avCodecCtx->sample_rate,
av_get_sample_fmt_name(avCodecCtx->sample_fmt),
buf);
qDebug() << "Audio filter in args:" << args;

create(args);
}

void create(const QString &args)
{
buffersrcCtx->create("in", args, filterGraph);
buffersinkCtx->create("out", "", filterGraph);
}

void config(const QString &filterSpec)
{
QScopedPointer<FilterInOut> fliterOutPtr(new FilterInOut);
QScopedPointer<FilterInOut> fliterInPtr(new FilterInOut);
auto *outputs = fliterOutPtr->avFilterInOut();
auto *inputs = fliterInPtr->avFilterInOut();
/* Endpoints for the filter graph. */
outputs->name = av_strdup("in");
outputs->filter_ctx = buffersrcCtx->avFilterContext();
outputs->pad_idx = 0;
outputs->next = nullptr;

inputs->name = av_strdup("out");
inputs->filter_ctx = buffersinkCtx->avFilterContext();
inputs->pad_idx = 0;
inputs->next = nullptr;

filterGraph->parse(filterSpec, fliterInPtr.data(), fliterOutPtr.data());
filterGraph->config();

// if (!(enc_ctx->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)) {
// buffersink_ctx->buffersink_setFrameSize(enc_ctx->frame_size);
// }
}

Filter *q_ptr;

AVContextInfo *decContextInfo;
FilterContext *buffersrcCtx;
FilterContext *buffersinkCtx;
FilterGraph *filterGraph;
};

Filter::Filter(AVContextInfo *decContextInfo, QObject *parent)
: QObject{parent}
, d_ptr(new FilterPrivate(this))
{
d_ptr->decContextInfo = decContextInfo;
}

Filter::~Filter() = default;

auto Filter::init(Frame *frame) -> bool
{
switch (d_ptr->decContextInfo->mediaType()) {
case AVMEDIA_TYPE_AUDIO: d_ptr->initAudioFilter(); break;
case AVMEDIA_TYPE_VIDEO: d_ptr->initVideoFilter(frame); break;
default: return false;
}

return true;
}

auto Filter::filterFrame(Frame *frame) -> QVector<FramePtr>
{
QVector<FramePtr> framepPtrs{};
if (d_ptr->buffersrcCtx->buffersrcAddFrameFlags(frame)) {
return framepPtrs;
}
std::unique_ptr<Frame> framePtr(new Frame);
while (d_ptr->buffersinkCtx->buffersinkGetFrame(framePtr.get())) {
framePtr->setPictType(AV_PICTURE_TYPE_NONE);
framepPtrs.emplace_back(framePtr.release());
}
return framepPtrs;
}

} // namespace Ffmpeg
29 changes: 29 additions & 0 deletions ffmpeg/filter/filter.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#ifndef FILTER_HPP
#define FILTER_HPP

#include "frame.hpp"
#include <QObject>

namespace Ffmpeg {

class AVContextInfo;
class Frame;
class Filter : public QObject
{
Q_OBJECT
public:
explicit Filter(AVContextInfo *decContextInfo, QObject *parent = nullptr);
~Filter() override;

auto init(Frame *frame) -> bool;

auto filterFrame(Frame *frame) -> QVector<FramePtr>;

private:
class FilterPrivate;
QScopedPointer<FilterPrivate> d_ptr;
};

} // namespace Ffmpeg

#endif // FILTER_HPP
2 changes: 2 additions & 0 deletions ffmpeg/filter/filter.pri
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
HEADERS += \
$$PWD/filter.hpp \
$$PWD/filtercontext.hpp \
$$PWD/filtergraph.hpp \
$$PWD/filterinout.hpp

SOURCES += \
$$PWD/filter.cc \
$$PWD/filtercontext.cc \
$$PWD/filtergraph.cc \
$$PWD/filterinout.cc
17 changes: 9 additions & 8 deletions ffmpeg/filter/filtercontext.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace Ffmpeg {
class FilterContext::FilterContextPrivate
{
public:
FilterContextPrivate(FilterContext *q)
explicit FilterContextPrivate(FilterContext *q)
: q_ptr(q)
{}

Expand All @@ -40,14 +40,15 @@ FilterContext::FilterContext(const QString &name, QObject *parent)
d_ptr->createFilter(name);
}

FilterContext::~FilterContext() {}
FilterContext::~FilterContext() = default;

bool FilterContext::isValid()
auto FilterContext::isValid() -> bool
{
return nullptr != d_ptr->filter;
}

bool FilterContext::create(const QString &name, const QString &args, FilterGraph *filterGraph)
auto FilterContext::create(const QString &name, const QString &args, FilterGraph *filterGraph)
-> bool
{
auto ret = avfilter_graph_create_filter(&d_ptr->filterContext,
d_ptr->filter,
Expand All @@ -58,15 +59,15 @@ bool FilterContext::create(const QString &name, const QString &args, FilterGraph
ERROR_RETURN(ret)
}

bool FilterContext::buffersrc_addFrameFlags(Frame *frame)
auto FilterContext::buffersrcAddFrameFlags(Frame *frame) -> bool
{
auto ret = av_buffersrc_add_frame_flags(d_ptr->filterContext,
frame->avFrame(),
AV_BUFFERSRC_FLAG_KEEP_REF | AV_BUFFERSRC_FLAG_PUSH);
ERROR_RETURN(ret)
}

bool FilterContext::buffersink_getFrame(Frame *frame)
auto FilterContext::buffersinkGetFrame(Frame *frame) -> bool
{
auto ret = av_buffersink_get_frame(d_ptr->filterContext, frame->avFrame());
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
Expand All @@ -75,12 +76,12 @@ bool FilterContext::buffersink_getFrame(Frame *frame)
ERROR_RETURN(ret)
}

void FilterContext::buffersink_setFrameSize(int size)
void FilterContext::buffersinkSetFrameSize(int size)
{
av_buffersink_set_frame_size(d_ptr->filterContext, size);
}

AVFilterContext *FilterContext::avFilterContext()
auto FilterContext::avFilterContext() -> AVFilterContext *
{
return d_ptr->filterContext;
}
Expand Down
14 changes: 7 additions & 7 deletions ffmpeg/filter/filtercontext.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,17 @@ class FilterContext : public QObject
// Video: {buffer, buffersink}
// Audio: {abuffer, abuffersink}
explicit FilterContext(const QString &name, QObject *parent = nullptr);
~FilterContext();
~FilterContext() override;

bool isValid();
auto isValid() -> bool;

bool create(const QString &name, const QString &args, FilterGraph *filterGraph);
auto create(const QString &name, const QString &args, FilterGraph *filterGraph) -> bool;

bool buffersrc_addFrameFlags(Frame *frame);
bool buffersink_getFrame(Frame *frame);
void buffersink_setFrameSize(int size);
auto buffersrcAddFrameFlags(Frame *frame) -> bool;
auto buffersinkGetFrame(Frame *frame) -> bool;
void buffersinkSetFrameSize(int size);

AVFilterContext *avFilterContext();
auto avFilterContext() -> AVFilterContext *;

private:
class FilterContextPrivate;
Expand Down
Loading

0 comments on commit 8c03273

Please sign in to comment.