Skip to content

Commit

Permalink
Merge pull request #505 from vladyslav-arzhanov/codec_opts
Browse files Browse the repository at this point in the history
Provide QAVPlayer::setCodecOptions API
  • Loading branch information
valbok authored Dec 9, 2024
2 parents 79105ca + 6093d04 commit 60b9426
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 6 deletions.
4 changes: 2 additions & 2 deletions src/QtAVPlayer/qavcodec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ void QAVCodec::setCodec(const AVCodec *c)
d_func()->codec = c;
}

bool QAVCodec::open(AVStream *stream)
bool QAVCodec::open(AVStream *stream, AVDictionary** opts)
{
Q_D(QAVCodec);

Expand All @@ -67,7 +67,7 @@ bool QAVCodec::open(AVStream *stream)

av_opt_set_int(d->avctx, "refcounted_frames", true, 0);
av_opt_set_int(d->avctx, "threads", 1, 0);
ret = avcodec_open2(d->avctx, d->codec, nullptr);
ret = avcodec_open2(d->avctx, d->codec, opts);
if (ret < 0) {
qWarning() << "Could not open the codec:" << d->codec->name << ret;
return false;
Expand Down
6 changes: 5 additions & 1 deletion src/QtAVPlayer/qavcodec_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
#include <QtAVPlayer/qtavplayerglobal.h>
#include <memory>

extern "C" {
#include <libavutil/dict.h>
}

QT_BEGIN_NAMESPACE

struct AVCodec;
Expand All @@ -35,7 +39,7 @@ class QAVCodec
public:
virtual ~QAVCodec();

bool open(AVStream *stream);
bool open(AVStream *stream, AVDictionary** opts = NULL);
AVCodecContext *avctx() const;
void setCodec(const AVCodec *c);
const AVCodec *codec() const;
Expand Down
26 changes: 23 additions & 3 deletions src/QtAVPlayer/qavdemuxer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ class QAVDemuxerPrivate
QString inputFormat;
QString inputVideoCodec;
QMap<QString, QString> inputOptions;
QMap<QString, QString> videoCodecOptions;

bool eof = false;
QList<QAVPacket> packets;
Expand Down Expand Up @@ -181,7 +182,7 @@ void QAVDemuxer::abort(bool stop)
d->abortRequest = stop;
}

static int setup_video_codec(const QString &inputVideoCodec, AVStream *stream, QAVVideoCodec &codec)
static int setup_video_codec(const QString &inputVideoCodec, AVStream *stream, QAVVideoCodec &codec, AVDictionary **codecOpts)
{
const AVCodec *videoCodec = nullptr;
if (!inputVideoCodec.isEmpty()) {
Expand Down Expand Up @@ -243,7 +244,7 @@ static int setup_video_codec(const QString &inputVideoCodec, AVStream *stream, Q
}

// Open codec after hwdevices
if (!codec.open(stream)) {
if (!codec.open(stream, codecOpts)) {
qWarning() << "Could not open video codec for stream";
return AVERROR(EINVAL);
}
Expand Down Expand Up @@ -455,13 +456,18 @@ int QAVDemuxer::resetCodecs()
qWarning() << "Could not find codecpar";
return AVERROR(EINVAL);
}

const AVMediaType type = d->ctx->streams[i]->codecpar->codec_type;
switch (type) {
case AVMEDIA_TYPE_VIDEO:
{
QAVDictionaryHolder opts;
for (const auto & key: d->videoCodecOptions.keys())
av_dict_set(&opts.dict, key.toUtf8().constData(), d->videoCodecOptions[key].toUtf8().constData(), 0);

QSharedPointer<QAVCodec> codec(new QAVVideoCodec);
d->availableStreams.push_back({ int(i), d->ctx, codec });
ret = setup_video_codec(d->inputVideoCodec, d->ctx->streams[i], *static_cast<QAVVideoCodec *>(codec.data()));
ret = setup_video_codec(d->inputVideoCodec, d->ctx->streams[i], *static_cast<QAVVideoCodec *>(codec.data()), &opts.dict);
} break;
case AVMEDIA_TYPE_AUDIO:
d->availableStreams.push_back({ int(i), d->ctx, QSharedPointer<QAVCodec>(new QAVAudioCodec) });
Expand Down Expand Up @@ -871,6 +877,20 @@ void QAVDemuxer::setInputOptions(const QMap<QString, QString> &opts)
d->inputOptions = opts;
}

QMap<QString, QString> QAVDemuxer::videoCodecOptions() const
{
Q_D(const QAVDemuxer);
QMutexLocker locker(&d->mutex);
return d->videoCodecOptions;
}

void QAVDemuxer::setVideoCodecOptions(const QMap<QString, QString> &opts)
{
Q_D(QAVDemuxer);
QMutexLocker locker(&d->mutex);
d->videoCodecOptions = opts;
}

void QAVDemuxer::onFrameSent(const QAVStreamFrame &frame)
{
Q_D(QAVDemuxer);
Expand Down
3 changes: 3 additions & 0 deletions src/QtAVPlayer/qavdemuxer_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ class QAVDemuxer
QMap<QString, QString> inputOptions() const;
void setInputOptions(const QMap<QString, QString> &opts);

QMap<QString, QString> videoCodecOptions() const;
void setVideoCodecOptions(const QMap<QString, QString> &opts);

void onFrameSent(const QAVStreamFrame &frame);
QAVStream::Progress progress(const QAVStream &s) const;

Expand Down
18 changes: 18 additions & 0 deletions src/QtAVPlayer/qavplayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1319,6 +1319,24 @@ void QAVPlayer::setInputOptions(const QMap<QString, QString> &opts)
Q_EMIT inputOptionsChanged(opts);
}

QMap<QString, QString> QAVPlayer::videoCodecOptions() const
{
Q_D(const QAVPlayer);
return d->demuxer.videoCodecOptions();
}

void QAVPlayer::setVideoCodecOptions(const QMap<QString, QString> &opts)
{
Q_D(QAVPlayer);

auto current = videoCodecOptions();
if (opts == current)
return;

qCDebug(lcAVPlayer) << __FUNCTION__ << ":" << current << "->" << opts;
d->demuxer.setVideoCodecOptions(opts);
Q_EMIT videoCodecOptionsChanged(opts);
}

/*!
* \brief Use to set log level of FFmpeg backend
Expand Down
4 changes: 4 additions & 0 deletions src/QtAVPlayer/qavplayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ class QAVPlayer : public QObject
QMap<QString, QString> inputOptions() const;
void setInputOptions(const QMap<QString, QString> &opts);

QMap<QString, QString> videoCodecOptions() const;
void setVideoCodecOptions(const QMap<QString, QString> &opts);

QAVStream::Progress progress(const QAVStream &stream) const;

public Q_SLOTS:
Expand Down Expand Up @@ -134,6 +137,7 @@ public Q_SLOTS:
void inputFormatChanged(const QString &format);
void inputVideoCodecChanged(const QString &codec);
void inputOptionsChanged(const QMap<QString, QString> &opts);
void videoCodecOptionsChanged(const QMap<QString, QString> &opts);

void videoFrame(const QAVVideoFrame &frame);
void audioFrame(const QAVAudioFrame &frame);
Expand Down

0 comments on commit 60b9426

Please sign in to comment.