Skip to content

Commit

Permalink
优化 代码;
Browse files Browse the repository at this point in the history
  • Loading branch information
RealChuan committed Mar 15, 2024
1 parent ea15fb6 commit 23bc1a2
Show file tree
Hide file tree
Showing 12 changed files with 255 additions and 165 deletions.
6 changes: 5 additions & 1 deletion examples/transcoder/audioencodermodel.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ class AudioEncoderModel::AudioEncoderModelPrivate
QStringList headers;

QIcon removeIcon = qApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton);

const int bitrateOffset = 1000;
};

AudioEncoderModel::AudioEncoderModel(QObject *parent)
Expand Down Expand Up @@ -118,7 +120,9 @@ auto AudioEncoderModel::setData(const QModelIndex &index, const QVariant &value,
}
} break;
case Property::Bitrate:
data.maxBitrate = data.minBitrate = data.bitrate = value.toInt();
data.bitrate = value.toInt();
data.minBitrate = qMax(0, data.bitrate - d_ptr->bitrateOffset);
data.maxBitrate = data.bitrate + d_ptr->bitrateOffset;
emit dataChanged(index, index);
break;
case Property::SampleRate:
Expand Down
2 changes: 2 additions & 0 deletions examples/transcoder/mainwindow.cc
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,8 @@ void MainWindow::onStart()
d_ptr->statusWidget->setStatus(tr("Start"));

d_ptr->fpsTimer->stop();

d_ptr->transcoder->parseInputFile();
}
}

Expand Down
18 changes: 14 additions & 4 deletions examples/transcoder/outputwidget.cc
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,26 @@ void OutPutWidget::onBrowse()
d_ptr->outLineEdit->setText(filePath);
}

void OutPutWidget::onOpenFolder()
{
auto path = d_ptr->outLineEdit->text().trimmed();
QDesktopServices::openUrl(QUrl(QFileInfo(path).absolutePath()));
}

void OutPutWidget::setupUI()
{
auto *button = new QToolButton(this);
button->setText(tr("Browse"));
connect(button, &QToolButton::clicked, this, &OutPutWidget::onBrowse);
auto *browseButton = new QToolButton(this);
browseButton->setText(tr("Browse"));
connect(browseButton, &QToolButton::clicked, this, &OutPutWidget::onBrowse);
auto *openButton = new QToolButton(this);
openButton->setText(tr("Open Folder"));
connect(openButton, &QToolButton::clicked, this, &OutPutWidget::onOpenFolder);

auto *layout = new QHBoxLayout(this);
layout->addWidget(new QLabel(tr("Save File:"), this));
layout->addWidget(d_ptr->outLineEdit);
layout->addWidget(button);
layout->addWidget(browseButton);
layout->addWidget(openButton);
}

void OutPutWidget::buildConnect() {}
1 change: 1 addition & 0 deletions examples/transcoder/outputwidget.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class OutPutWidget : public QWidget

private slots:
void onBrowse();
void onOpenFolder();

private:
void setupUI();
Expand Down
135 changes: 94 additions & 41 deletions examples/transcoder/videoencoderwidget.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,58 @@ class VideoEncoderWidget::VideoEncoderWidgetPrivate
q_ptr);
gpuDecodeCbx->setChecked(true);

initInvailedGroupBox();
initCrf();
initBitrateGroupBox();
initSizeGroupBox();

init();
}

void initInvailedGroupBox()
{
presetCbx = CommonWidgets::createComboBox(q_ptr);
tuneCbx = CommonWidgets::createComboBox(q_ptr);
profileCbx = CommonWidgets::createComboBox(q_ptr);
}

void initCrf()
{
crfRadioButton = new QRadioButton(QCoreApplication::translate("VideoEncoderWidgetPrivate",
"Crf:"),
q_ptr);
crfSbx = new QSpinBox(q_ptr);
crfSbx->setToolTip(
QCoreApplication::translate("VideoEncoderWidgetPrivate", "smaller -> better"));
QCoreApplication::translate("VideoEncoderWidgetPrivate", "bigger -> better"));
}

void initBitrateGroupBox()
{
bitrateRadioButton
= new QRadioButton(QCoreApplication::translate("VideoEncoderWidgetPrivate", "Bitrate:"),
q_ptr);
bitrateWidget = new QWidget(q_ptr);
minBitrateSbx = new QSpinBox(q_ptr);
minBitrateSbx->setRange(0, INT_MAX);
bitrateSbx = new QSpinBox(q_ptr);
bitrateSbx->setRange(0, INT_MAX);
maxBitrateSbx = new QSpinBox(q_ptr);
maxBitrateSbx->setRange(0, INT_MAX);

presetCbx = new QComboBox(q_ptr);
presetCbx->setView(new QListView(presetCbx));
tuneCbx = new QComboBox(q_ptr);
tuneCbx->setView(new QListView(tuneCbx));
profileCbx = new QComboBox(q_ptr);
profileCbx->setView(new QListView(profileCbx));
auto *bitrateLayout = new QFormLayout(bitrateWidget);
bitrateLayout->setContentsMargins(QMargins());
bitrateLayout->addRow(QCoreApplication::translate("VideoEncoderWidgetPrivate",
"Min Bitrate:"),
minBitrateSbx);
bitrateLayout->addRow(QCoreApplication::translate("VideoEncoderWidgetPrivate", "Bitrate:"),
bitrateSbx);
bitrateLayout->addRow(QCoreApplication::translate("VideoEncoderWidgetPrivate",
"Max Bitrate:"),
maxBitrateSbx);
}

void initSizeGroupBox()
{
widthSbx = new QSpinBox(q_ptr);
widthSbx->setRange(0, INT_MAX);
heightSbx = new QSpinBox(q_ptr);
Expand All @@ -47,15 +88,6 @@ class VideoEncoderWidget::VideoEncoderWidgetPrivate
"Keep aspect ratio:"),
q_ptr);
aspectCheckBox->setChecked(true);

minBitrateSbx = new QSpinBox(q_ptr);
minBitrateSbx->setRange(0, INT_MAX);
maxBitrateSbx = new QSpinBox(q_ptr);
maxBitrateSbx->setRange(0, INT_MAX);
bitrateSbx = new QSpinBox(q_ptr);
bitrateSbx->setRange(0, INT_MAX);

init();
}

void calBitrate() const
Expand Down Expand Up @@ -95,18 +127,22 @@ class VideoEncoderWidget::VideoEncoderWidgetPrivate
QComboBox *videoEncoderCbx;
QCheckBox *gpuDecodeCbx;

QRadioButton *crfRadioButton;
QSpinBox *crfSbx;
QComboBox *presetCbx;
QComboBox *tuneCbx;
QComboBox *profileCbx;

QRadioButton *bitrateRadioButton;
QWidget *bitrateWidget;
QSpinBox *minBitrateSbx;
QSpinBox *bitrateSbx;
QSpinBox *maxBitrateSbx;

QSpinBox *widthSbx;
QSpinBox *heightSbx;
QCheckBox *aspectCheckBox;

QSpinBox *minBitrateSbx;
QSpinBox *maxBitrateSbx;
QSpinBox *bitrateSbx;
QComboBox *presetCbx;
QComboBox *tuneCbx;
QComboBox *profileCbx;

Ffmpeg::EncodeContext decodeContext;
};
Expand All @@ -118,6 +154,7 @@ VideoEncoderWidget::VideoEncoderWidget(QWidget *parent)
setupUI();
buildConnect();
onEncoderChanged();
d_ptr->crfRadioButton->click();
}

VideoEncoderWidget::~VideoEncoderWidget() = default;
Expand All @@ -132,7 +169,8 @@ auto VideoEncoderWidget::encodeContext() const -> Ffmpeg::EncodeContext
encodeContext.minBitrate = d_ptr->minBitrateSbx->value();
encodeContext.maxBitrate = d_ptr->maxBitrateSbx->value();
encodeContext.bitrate = d_ptr->bitrateSbx->value();
encodeContext.crf = d_ptr->crfSbx->value();
encodeContext.crf = d_ptr->crfRadioButton->isChecked() ? d_ptr->crfSbx->value()
: Ffmpeg::EncodeLimit::invalid_crf;
encodeContext.preset = d_ptr->presetCbx->currentText();
encodeContext.tune = d_ptr->tuneCbx->currentText();
// encodeContext.profile = d_ptr->profileCbx->currentText();
Expand Down Expand Up @@ -160,12 +198,16 @@ void VideoEncoderWidget::setDecodeContext(const Ffmpeg::EncodeContext &decodeCon
d_ptr->widthSbx->blockSignals(false);
d_ptr->heightSbx->blockSignals(false);

if (decodeContext.maxBitrate <= 0) {
if (decodeContext.bitrate <= 0) {
d_ptr->calBitrate();
} else {
d_ptr->minBitrateSbx->setValue(decodeContext.minBitrate);
d_ptr->maxBitrateSbx->setValue(decodeContext.maxBitrate);
d_ptr->bitrateSbx->setValue(decodeContext.bitrate);
if (decodeContext.maxBitrate <= 0) {
d_ptr->maxBitrateSbx->setValue(decodeContext.bitrate);
}
if (decodeContext.minBitrate <= 0) {
d_ptr->minBitrateSbx->setValue(decodeContext.bitrate);
}
}

d_ptr->decodeContext = decodeContext;
Expand Down Expand Up @@ -211,6 +253,13 @@ void VideoEncoderWidget::onVideoHeightChanged()
d_ptr->calBitrate();
}

void VideoEncoderWidget::onQualityTypeChanged()
{
auto enabled = d_ptr->crfRadioButton->isChecked();
d_ptr->crfSbx->setEnabled(enabled);
d_ptr->bitrateWidget->setEnabled(!enabled);
}

void VideoEncoderWidget::setupUI()
{
auto *codecLayout = new QHBoxLayout;
Expand All @@ -220,30 +269,28 @@ void VideoEncoderWidget::setupUI()
codecLayout->addStretch();
codecLayout->addWidget(d_ptr->gpuDecodeCbx);

auto *invailedGroupBox = new QGroupBox(tr("Invalid setting"), this);
auto *invailedLayout = new QFormLayout(invailedGroupBox);
invailedLayout->addRow(tr("Crf:"), d_ptr->crfSbx);
invailedLayout->addRow(tr("Preset:"), d_ptr->presetCbx);
invailedLayout->addRow(tr("Tune:"), d_ptr->tuneCbx);
invailedLayout->addRow(tr("Profile:"), d_ptr->profileCbx);

auto *sizeGroupBox = new QGroupBox(tr("Size"), this);
auto *sizeLayout = new QFormLayout(sizeGroupBox);
sizeLayout->addRow(tr("Width:"), d_ptr->widthSbx);
sizeLayout->addRow(tr("Height:"), d_ptr->heightSbx);
sizeLayout->addRow(d_ptr->aspectCheckBox);

auto *bitrateGroupBox = new QGroupBox(tr("Bitrate"), this);
auto *bitrateLayout = new QFormLayout(bitrateGroupBox);
bitrateLayout->addRow(tr("Min Bitrate:"), d_ptr->minBitrateSbx);
bitrateLayout->addRow(tr("Max Bitrate:"), d_ptr->maxBitrateSbx);
bitrateLayout->addRow(tr("Bitrate:"), d_ptr->bitrateSbx);
auto *invailedGroupBox = new QGroupBox(tr("Invalid setting"), this);
auto *invailedLayout = new QFormLayout(invailedGroupBox);
invailedLayout->addRow(tr("Preset:"), d_ptr->presetCbx);
invailedLayout->addRow(tr("Tune:"), d_ptr->tuneCbx);
invailedLayout->addRow(tr("Profile:"), d_ptr->profileCbx);

auto *qualityGroupBox = new QGroupBox(tr("Quality"), this);
auto *qualityLayout = new QFormLayout(qualityGroupBox);
qualityLayout->addRow(d_ptr->crfRadioButton, d_ptr->crfSbx);
qualityLayout->addRow(d_ptr->bitrateRadioButton, d_ptr->bitrateWidget);

auto *layout = new QGridLayout(this);
layout->addLayout(codecLayout, 0, 0, 1, 2);
layout->addWidget(invailedGroupBox, 1, 0, 2, 1);
layout->addWidget(sizeGroupBox, 1, 1, 1, 1);
layout->addWidget(bitrateGroupBox, 2, 1, 1, 1);
layout->addWidget(sizeGroupBox, 1, 0, 1, 1);
layout->addWidget(qualityGroupBox, 2, 0, 1, 1);
layout->addWidget(invailedGroupBox, 1, 1, 2, 1);
}

void VideoEncoderWidget::buildConnect()
Expand All @@ -264,4 +311,10 @@ void VideoEncoderWidget::buildConnect()
&QCheckBox::stateChanged,
this,
&VideoEncoderWidget::onVideoWidthChanged);

auto *buttonGroup = new QButtonGroup(this);
buttonGroup->setExclusive(true);
buttonGroup->addButton(d_ptr->crfRadioButton);
buttonGroup->addButton(d_ptr->bitrateRadioButton);
connect(buttonGroup, &QButtonGroup::idClicked, this, &VideoEncoderWidget::onQualityTypeChanged);
}
3 changes: 2 additions & 1 deletion examples/transcoder/videoencoderwidget.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,13 @@ class VideoEncoderWidget : public QWidget
void setDecodeContext(const Ffmpeg::EncodeContext &decodeContext);
[[nodiscard]] auto encodeContext() const -> Ffmpeg::EncodeContext;

bool isGpuDecode() const;
[[nodiscard]] auto isGpuDecode() const -> bool;

private slots:
void onEncoderChanged();
void onVideoWidthChanged();
void onVideoHeightChanged();
void onQualityTypeChanged();

private:
void setupUI();
Expand Down
9 changes: 7 additions & 2 deletions ffmpeg/codeccontext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ class CodecContext::CodecContextPrivate
void initVideoEncoderOptions(const EncodeContext &encodeContext)
{
double crf = encodeContext.crf;
if (crf == EncodeLimit::invalid_crf) {
return;
}

Q_ASSERT(codecCtx->codec_type == AVMEDIA_TYPE_VIDEO);
Q_ASSERT(crf >= EncodeLimit::crf_min && crf <= EncodeLimit::crf_max);
Expand Down Expand Up @@ -146,9 +149,11 @@ class CodecContext::CodecContextPrivate
av_dict_set(&encodeOptions, "qp_b", qualityB.toUtf8().data(), 0);
}
} else if (codecName.contains("_mf")) { // ffmpeg mf编码器
auto quality = QString::number(crf, 'f', 2);
// why quality bigger is better?
// https://trac.ffmpeg.org/wiki/Encode/H.264
int quality = qMin(100, static_cast<int>(crf * 2));
av_dict_set(&encodeOptions, "rate_control", "quality", 0);
av_dict_set(&encodeOptions, "quality", quality.toUtf8().data(), 0);
av_dict_set(&encodeOptions, "quality", QString::number(quality).toUtf8().data(), 0);
// av_dict_set(&encodeOptions, "hw_encoding", "1", 0);
} else {
codecCtx->flags |= AV_CODEC_FLAG_QSCALE;
Expand Down
10 changes: 10 additions & 0 deletions ffmpeg/encodecontext.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ namespace Ffmpeg {

EncodeContext::EncodeContext(AVStream *stream, AVContextInfo *info)
{
auto *codecpar = stream->codecpar;
auto *avCodecContext = info->codecCtx()->avCodecCtx();
const auto *codec = avCodecContext->codec;
streamIndex = stream->index;
Expand All @@ -21,10 +22,19 @@ EncodeContext::EncodeContext(AVStream *stream, AVContextInfo *info)
maxBitrate = avCodecContext->rc_max_rate;
bitrate = avCodecContext->bit_rate;
if (bitrate <= 0) {
bitrate = codecpar->bit_rate;
}
if (bitrate <= 0 && mediaType == AVMEDIA_TYPE_AUDIO) {
bitrate = 512000;
}
size = {avCodecContext->width, avCodecContext->height};
if (!size.isValid()) {
size = {codecpar->width, codecpar->height};
}
sampleRate = avCodecContext->sample_rate;
if (sampleRate <= 0) {
sampleRate = codecpar->sample_rate;
}

if (!setEncoderName(QString::fromUtf8(codec->name))) {
setEncoderName(codec->id);
Expand Down
3 changes: 2 additions & 1 deletion ffmpeg/encodecontext.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ namespace EncodeLimit {

static const int crf_min = 0;
static const int crf_max = 51;
static const int invalid_crf= -999;

static const QStringList presets = QStringList{"ultrafast",
"superfast",
Expand Down Expand Up @@ -64,7 +65,7 @@ struct FFMPEG_EXPORT EncodeContext
qint64 bitrate = -1;

int threadCount = -1;
int crf = 18;
int crf = 35;

// video
QSize size = {-1, -1};
Expand Down
Loading

0 comments on commit 23bc1a2

Please sign in to comment.