Skip to content

Commit

Permalink
优化truehd音频播放;
Browse files Browse the repository at this point in the history
  • Loading branch information
RealChuan committed Oct 30, 2023
1 parent 838570a commit 05a5a9e
Show file tree
Hide file tree
Showing 16 changed files with 84 additions and 65 deletions.
48 changes: 25 additions & 23 deletions ffmpeg/avcontextinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ AVContextInfo::AVContextInfo(QObject *parent)
, d_ptr(new AVContextInfoPrivate(this))
{}

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

CodecContext *AVContextInfo::codecCtx()
auto AVContextInfo::codecCtx() -> CodecContext *
{
return d_ptr->codecCtx.data();
}
Expand All @@ -97,12 +97,12 @@ void AVContextInfo::setIndex(int index)
d_ptr->streamIndex = index;
}

int AVContextInfo::index()
auto AVContextInfo::index() -> int
{
return d_ptr->streamIndex;
}

bool AVContextInfo::isIndexVaild()
auto AVContextInfo::isIndexVaild() -> bool
{
return d_ptr->streamIndex != Error_Index;
}
Expand All @@ -114,12 +114,12 @@ void AVContextInfo::setStream(AVStream *stream)
// d_ptr->printMetaData();
}

AVStream *AVContextInfo::stream()
auto AVContextInfo::stream() -> AVStream *
{
return d_ptr->stream;
}

bool AVContextInfo::initDecoder(const AVRational &frameRate)
auto AVContextInfo::initDecoder(const AVRational &frameRate) -> bool
{
Q_ASSERT(d_ptr->stream != nullptr);
const char *typeStr = av_get_media_type_string(d_ptr->stream->codecpar->codec_type);
Expand All @@ -144,7 +144,7 @@ bool AVContextInfo::initDecoder(const AVRational &frameRate)
return true;
}

bool AVContextInfo::initEncoder(AVCodecID codecId)
auto AVContextInfo::initEncoder(AVCodecID codecId) -> bool
{
auto encodec = avcodec_find_encoder(codecId);
if (!encodec) {
Expand All @@ -155,7 +155,7 @@ bool AVContextInfo::initEncoder(AVCodecID codecId)
return true;
}

bool AVContextInfo::initEncoder(const QString &name)
auto AVContextInfo::initEncoder(const QString &name) -> bool
{
auto encodec = avcodec_find_encoder_by_name(name.toLocal8Bit().constData());
if (!encodec) {
Expand All @@ -166,7 +166,7 @@ bool AVContextInfo::initEncoder(const QString &name)
return true;
}

bool AVContextInfo::openCodec(GpuType type)
auto AVContextInfo::openCodec(GpuType type) -> bool
{
d_ptr->gpuType = type;
if (mediaType() == AVMEDIA_TYPE_VIDEO) {
Expand All @@ -192,13 +192,14 @@ bool AVContextInfo::openCodec(GpuType type)
return true;
}

bool AVContextInfo::decodeSubtitle2(const QSharedPointer<Subtitle> &subtitlePtr,
const QSharedPointer<Packet> &packetPtr)
auto AVContextInfo::decodeSubtitle2(const QSharedPointer<Subtitle> &subtitlePtr,
const QSharedPointer<Packet> &packetPtr) -> bool
{
return d_ptr->codecCtx->decodeSubtitle2(subtitlePtr.data(), packetPtr.data());
}

std::vector<QSharedPointer<Frame>> AVContextInfo::decodeFrame(const QSharedPointer<Packet> &packetPtr)
auto AVContextInfo::decodeFrame(const QSharedPointer<Packet> &packetPtr)
-> std::vector<QSharedPointer<Frame>>
{
std::vector<FramePtr> framePtrs;
if (!d_ptr->codecCtx->sendPacket(packetPtr.data())) {
Expand All @@ -219,7 +220,8 @@ std::vector<QSharedPointer<Frame>> AVContextInfo::decodeFrame(const QSharedPoint
return framePtrs;
}

std::vector<QSharedPointer<Packet>> AVContextInfo::encodeFrame(const QSharedPointer<Frame> &framePtr)
auto AVContextInfo::encodeFrame(const QSharedPointer<Frame> &framePtr)
-> std::vector<QSharedPointer<Packet>>
{
std::vector<PacketPtr> packetPtrs{};
auto frame_tmp_ptr = framePtr;
Expand All @@ -242,52 +244,52 @@ std::vector<QSharedPointer<Packet>> AVContextInfo::encodeFrame(const QSharedPoin
return packetPtrs;
}

double AVContextInfo::calTimebase() const
auto AVContextInfo::calTimebase() const -> double
{
return av_q2d(d_ptr->stream->time_base);
}

AVRational AVContextInfo::timebase() const
auto AVContextInfo::timebase() const -> AVRational
{
return d_ptr->stream->time_base;
}

double AVContextInfo::fps() const
auto AVContextInfo::fps() const -> double
{
return av_q2d(d_ptr->stream->avg_frame_rate);
}

qint64 AVContextInfo::fames() const
auto AVContextInfo::fames() const -> qint64
{
return d_ptr->stream->nb_frames;
}

QSize AVContextInfo::resolutionRatio() const
auto AVContextInfo::resolutionRatio() const -> QSize
{
return {d_ptr->stream->codecpar->width, d_ptr->stream->codecpar->height};
}

AVMediaType AVContextInfo::mediaType() const
auto AVContextInfo::mediaType() const -> AVMediaType
{
return d_ptr->stream->codecpar->codec_type;
}

QString AVContextInfo::mediaTypeString() const
auto AVContextInfo::mediaTypeString() const -> QString
{
return av_get_media_type_string(mediaType());
}

bool AVContextInfo::isDecoder() const
auto AVContextInfo::isDecoder() const -> bool
{
return d_ptr->codecCtx->isDecoder();
}

AVContextInfo::GpuType AVContextInfo::gpuType() const
auto AVContextInfo::gpuType() const -> AVContextInfo::GpuType
{
return d_ptr->gpuType;
}

AVPixelFormat AVContextInfo::pixfmt() const
auto AVContextInfo::pixfmt() const -> AVPixelFormat
{
if (d_ptr->gpuType == GpuEncode && mediaType() == AVMEDIA_TYPE_VIDEO
&& d_ptr->hardWareEncodePtr->isVaild()) {
Expand Down
4 changes: 2 additions & 2 deletions ffmpeg/avcontextinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ class FFMPEG_EXPORT AVContextInfo : public QObject
auto openCodec(GpuType type = NotUseGpu) -> bool;

// sendPacket and receiveFrame
std::vector<QSharedPointer<Frame>> decodeFrame(const QSharedPointer<Packet> &packetPtr);
std::vector<QSharedPointer<Packet>> encodeFrame(const QSharedPointer<Frame> &framePtr);
auto decodeFrame(const QSharedPointer<Packet> &packetPtr) -> std::vector<QSharedPointer<Frame>>;
auto encodeFrame(const QSharedPointer<Frame> &framePtr) -> std::vector<QSharedPointer<Packet>>;
auto decodeSubtitle2(const QSharedPointer<Subtitle> &subtitlePtr,
const QSharedPointer<Packet> &packetPtr) -> bool;

Expand Down
2 changes: 1 addition & 1 deletion ffmpeg/averrormanager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class FFMPEG_EXPORT AVErrorManager : public QObject

void setErrorCode(int errorCode);
[[nodiscard]] auto lastErrorString() const -> QString;
[[nodiscard]] QVector<int> errorCodes() const;
[[nodiscard]] auto errorCodes() const -> QVector<int>;

signals:
void error(const Ffmpeg::AVError &avError);
Expand Down
6 changes: 3 additions & 3 deletions ffmpeg/codeccontext.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ class CodecContext : public QObject
[[nodiscard]] auto size() const -> QSize;

void setQuailty(int quailty);
[[nodiscard]] QPair<int, int> quantizer() const;
[[nodiscard]] auto quantizer() const -> QPair<int, int>;

[[nodiscard]] QVector<AVPixelFormat> supportPixFmts() const;
[[nodiscard]] QVector<AVSampleFormat> supportSampleFmts() const;
[[nodiscard]] auto supportPixFmts() const -> QVector<AVPixelFormat>;
[[nodiscard]] auto supportSampleFmts() const -> QVector<AVSampleFormat>;

// Set before open, Soft solution is effective
void setThreadCount(int threadCount);
Expand Down
20 changes: 17 additions & 3 deletions ffmpeg/decoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,24 @@
#include "avcontextinfo.h"
#include "formatcontext.h"

extern "C" {
#include <libavformat/avformat.h>
}

namespace Ffmpeg {

static const auto s_waitQueueEmptyMilliseconds = 50;
static const auto s_frameQueueSize = 25; // for truehd codec, maybe need more, maybe 500
static constexpr auto s_waitQueueEmptyMilliseconds = 50;
static constexpr auto s_videoQueueSize = 10;
// For truehd audio, the queue size should be large enough
static constexpr auto s_audioQueueSize = 200;

template<typename T>
class Decoder : public QThread
{
public:
explicit Decoder(QObject *parent = nullptr)
: QThread(parent)
, m_queue(s_frameQueueSize)
, m_queue(s_videoQueueSize)
{}
~Decoder() override = default;

Expand All @@ -32,6 +38,14 @@ class Decoder : public QThread
m_formatContext = formatContext;
m_contextInfo = contextInfo;
m_runing = true;
if (!m_contextInfo->isIndexVaild()) {
return;
}
if (m_contextInfo->stream()->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
m_queue.setMaxSize(s_audioQueueSize);
} else {
m_queue.setMaxSize(s_videoQueueSize);
}
start();
}

Expand Down
12 changes: 6 additions & 6 deletions ffmpeg/formatcontext.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,19 @@ class FFMPEG_EXPORT FormatContext : public QObject
auto stream(int index) -> AVStream *; //音频流
auto createStream() -> AVStream *;

[[nodiscard]] QVector<StreamInfo> audioTracks() const;
[[nodiscard]] QVector<StreamInfo> vidioTracks() const;
[[nodiscard]] QVector<StreamInfo> subtitleTracks() const;
[[nodiscard]] QVector<StreamInfo> attachmentTracks() const;
[[nodiscard]] auto audioTracks() const -> QVector<StreamInfo>;
[[nodiscard]] auto vidioTracks() const -> QVector<StreamInfo>;
[[nodiscard]] auto subtitleTracks() const -> QVector<StreamInfo>;
[[nodiscard]] auto attachmentTracks() const -> QVector<StreamInfo>;

[[nodiscard]] auto findBestStreamIndex(AVMediaType type) const -> int;
// 丢弃除indexs中包含的音视频流,优化av_read_frame性能
void discardStreamExcluded(QVector<int> indexs);

auto seekFirstFrame() -> bool;
auto seek(qint64 timestamp) -> bool;
auto seek(qint64 timestamp, bool forward) -> bool; // microsecond
auto seekFrame(int index, qint64 timestamp) -> bool; // microsecond
auto seek(qint64 timestamp, bool forward) -> bool; // microsecond
auto seekFrame(int index, qint64 timestamp) -> bool; // microsecond

auto readFrame(Packet *packet) -> bool;

Expand Down
7 changes: 3 additions & 4 deletions ffmpeg/gpu/hardwareencode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,10 @@ class HardWareEncode : public QObject

auto initEncoder(const AVCodec *encoder) -> bool;
auto initHardWareDevice(CodecContext *codecContext) -> bool;
QSharedPointer<Frame> transToGpu(CodecContext *codecContext,
QSharedPointer<Frame> inPtr,
bool &ok);
auto transToGpu(CodecContext *codecContext, QSharedPointer<Frame> inPtr, bool &ok)
-> QSharedPointer<Frame>;

[[nodiscard]] AVPixelFormat swFormat() const;
[[nodiscard]] auto swFormat() const -> AVPixelFormat;

auto isVaild() -> bool;

Expand Down
16 changes: 8 additions & 8 deletions ffmpeg/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ class Player::PlayerPrivate
addPropertyChangeEventEvent(new MediaStateEvent(mediaState));
}

[[nodiscard]] QSize resolutionRatio() const
[[nodiscard]] auto resolutionRatio() const -> QSize
{
return videoInfo->isIndexVaild() ? videoInfo->resolutionRatio() : QSize();
}
Expand Down Expand Up @@ -601,7 +601,7 @@ auto Player::fames() const -> qint64
return d_ptr->videoInfo->isIndexVaild() ? d_ptr->videoInfo->fames() : 0;
}

QSize Player::resolutionRatio() const
auto Player::resolutionRatio() const -> QSize
{
return d_ptr->resolutionRatio();
}
Expand Down Expand Up @@ -633,7 +633,7 @@ void Player::setVideoRenders(QVector<VideoRender *> videoRenders)
d_ptr->subtitleDecoder->setVideoRenders(videoRenders);
}

QVector<VideoRender *> Player::videoRenders()
auto Player::videoRenders() -> QVector<VideoRender *>
{
return d_ptr->videoRenders;
}
Expand All @@ -643,17 +643,17 @@ void Player::setPropertyEventQueueMaxSize(size_t size)
d_ptr->maxPropertyEventQueueSize.store(size);
}

size_t Player::propertEventyQueueMaxSize() const
auto Player::propertEventyQueueMaxSize() const -> size_t
{
return d_ptr->maxPropertyEventQueueSize.load();
}

size_t Player::propertyChangeEventSize() const
auto Player::propertyChangeEventSize() const -> size_t
{
return d_ptr->propertyChangeEventQueue.size();
}

PropertyChangeEventPtr Player::takePropertyChangeEvent()
auto Player::takePropertyChangeEvent() -> PropertyChangeEventPtr
{
return d_ptr->propertyChangeEventQueue.take();
}
Expand All @@ -663,12 +663,12 @@ void Player::setEventQueueMaxSize(size_t size)
d_ptr->maxEventQueueSize.store(size);
}

size_t Player::eventQueueMaxSize() const
auto Player::eventQueueMaxSize() const -> size_t
{
return d_ptr->maxEventQueueSize.load();
}

[[nodiscard]] size_t Player::eventSize() const
[[nodiscard]] auto Player::eventSize() const -> size_t
{
return d_ptr->eventQueue.size();
}
Expand Down
12 changes: 6 additions & 6 deletions ffmpeg/player.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,16 @@ class FFMPEG_EXPORT Player : public QThread
[[nodiscard]] auto subtitleIndex() const -> int;

void setVideoRenders(QVector<VideoRender *> videoRenders);
QVector<VideoRender *> videoRenders();
auto videoRenders() -> QVector<VideoRender *>;

void setPropertyEventQueueMaxSize(size_t size);
[[nodiscard]] size_t propertEventyQueueMaxSize() const;
[[nodiscard]] size_t propertyChangeEventSize() const;
PropertyChangeEventPtr takePropertyChangeEvent();
[[nodiscard]] auto propertEventyQueueMaxSize() const -> size_t;
[[nodiscard]] auto propertyChangeEventSize() const -> size_t;
auto takePropertyChangeEvent() -> PropertyChangeEventPtr;

void setEventQueueMaxSize(size_t size);
[[nodiscard]] size_t eventQueueMaxSize() const;
[[nodiscard]] size_t eventSize() const;
[[nodiscard]] auto eventQueueMaxSize() const -> size_t;
[[nodiscard]] auto eventSize() const -> size_t;
auto addEvent(const EventPtr &eventPtr) -> bool;

public slots:
Expand Down
6 changes: 5 additions & 1 deletion ffmpeg/subtitle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ class Subtitle::SubtitlePrivate
image = QImage(videoResolutionRatio, QImage::Format_RGBA8888);
image.fill(Qt::transparent);
QPainter painter(&image);
painter.setRenderHints(painter.renderHints() | QPainter::Antialiasing
| QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
for (size_t i = 0; i < subtitle.num_rects; i++) {
auto sub_rect = subtitle.rects[i];

Expand Down Expand Up @@ -180,7 +182,7 @@ void Subtitle::setAssDataInfoList(const AssDataInfoList &list)
d_ptr->assList = list;
}

AssDataInfoList Subtitle::list() const
auto Subtitle::list() const -> AssDataInfoList
{
return d_ptr->assList;
}
Expand All @@ -193,6 +195,8 @@ auto Subtitle::generateImage() const -> QImage
d_ptr->image = QImage(d_ptr->videoResolutionRatio, QImage::Format_RGBA8888);
d_ptr->image.fill(Qt::transparent);
QPainter painter(&d_ptr->image);
painter.setRenderHints(painter.renderHints() | QPainter::Antialiasing
| QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
for (const auto &data : qAsConst(d_ptr->assList)) {
auto rect = data.rect();
QImage image((uchar *) data.rgba().constData(),
Expand Down
2 changes: 1 addition & 1 deletion ffmpeg/subtitle.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class FFMPEG_EXPORT Subtitle : public QObject

auto resolveAss(Ass *ass) -> bool;
void setAssDataInfoList(const AssDataInfoList &list);
[[nodiscard]] AssDataInfoList list() const;
[[nodiscard]] auto list() const -> AssDataInfoList;

[[nodiscard]] auto generateImage() const -> QImage;
[[nodiscard]] auto image() const -> QImage;
Expand Down
Loading

0 comments on commit 05a5a9e

Please sign in to comment.