From eb088b897396389de0152c8f004f1a861fe60cc1 Mon Sep 17 00:00:00 2001 From: Kubat <mael.martin31@gmail.com> Date: Fri, 27 Aug 2021 11:34:11 +0200 Subject: [PATCH] [WIP] LIB: The video stream/context are also using the abstract things --- src/Lib/AbstractMediaContext.hh | 2 +- src/Lib/Video.cc | 58 ++++++++++--------------- src/Lib/Video.hh | 76 ++++++++++----------------------- 3 files changed, 46 insertions(+), 90 deletions(-) diff --git a/src/Lib/AbstractMediaContext.hh b/src/Lib/AbstractMediaContext.hh index bc896bfc..1267b175 100644 --- a/src/Lib/AbstractMediaContext.hh +++ b/src/Lib/AbstractMediaContext.hh @@ -82,7 +82,7 @@ protected: } public: - virtual ~AbstractMediaStream() noexcept = default; + virtual ~AbstractMediaStream() noexcept {} int getStreamIndex() const noexcept { return streamIndexInContext; } QString getName() const noexcept { return QString::fromUtf8(codec->name); } AVCodecID getCodecId() const noexcept { return codecId; } diff --git a/src/Lib/Video.cc b/src/Lib/Video.cc index d6fe6e57..390b82a7 100644 --- a/src/Lib/Video.cc +++ b/src/Lib/Video.cc @@ -6,45 +6,31 @@ using namespace Vivy; -VideoContext::VideoContext(const QString &path) - : filePath(path) +VideoStream::VideoStream(AVCodec *streamCodec, AVFormatContext *formatArg, AVStream *streamArg, + int index) + : Super(streamCodec, formatArg, streamArg, index) { - if (!format) - throw std::runtime_error("out of memory, can't create allocate the AVFormatContext"); - - const std::string stdFilename = filePath.toStdString(); - const char *filename = stdFilename.c_str(); - AVFormatContext *formatPtr = format.get(); - - // Get info from video file - if (avformat_open_input(&formatPtr, filename, nullptr, nullptr) != 0) { - [[maybe_unused]] void *relatedOnFailure = format.release(); // freed by avformat_open_input - throw std::runtime_error("failed to open file"); - } +} - if (avformat_find_stream_info(formatPtr, nullptr) < 0) { - throw std::runtime_error("failed to get video stream info"); - } +QJsonObject +VideoStream::getProperties() const noexcept +{ + return Super::getProperties(); +} - // Populate all the stream indexes - for (uint i = 0; i < format->nb_streams; ++i) { - AVStream *itFormat = format->streams[i]; - AVCodecParameters *params = itFormat->codecpar; - AVCodec *streamCodec = avcodec_find_decoder(params->codec_id); - if (streamCodec && streamCodec->type == AVMEDIA_TYPE_VIDEO) { - videoStreams.insert(i, std::make_shared<Stream>(streamCodec, formatPtr, itFormat, i)); - } - } +VideoContext::VideoContext(const QString &path) + : Super(path) +{ +} - // Get the default stream - defaultStreamIndex = av_find_best_stream(formatPtr, AVMEDIA_TYPE_VIDEO, - -1, // Let AV find one stream - -1, // We don't want related streams - nullptr, 0); - if (defaultStreamIndex < 0) { - qCritical() << "Could not find the best video stream"; - } +QJsonDocument +VideoContext::getProperties() const noexcept +{ + return Super::getProperties(); +} - qDebug() << "Opened video context for" << path << "with duration" << formatPtr->duration - << "and default stream index" << defaultStreamIndex; +QString +VideoContext::getElementName() const noexcept +{ + return "Video" + Super::getElementName(); } diff --git a/src/Lib/Video.hh b/src/Lib/Video.hh index 8dbb4758..e0826f0c 100644 --- a/src/Lib/Video.hh +++ b/src/Lib/Video.hh @@ -21,68 +21,38 @@ extern "C" { namespace Vivy { -class VideoContext; - -// Like an audio context, but for videos. -class VideoContext final { - VIVY_UNMOVABLE_OBJECT(VideoContext) +// Hold all the data for a video stream. Should only be owned by the parent +// VideoContext instance. +class VideoStream final : public AbstractMediaStream<AVMEDIA_TYPE_VIDEO> { + VIVY_UNMOVABLE_OBJECT(VideoStream) + using Super = AbstractMediaStream<AVMEDIA_TYPE_VIDEO>; public: - // Hold all the data for a video stream. Should only be owned by the parent - // VideoContext instance. - class Stream final { - VIVY_UNMOVABLE_OBJECT(Stream) - - public: - Stream(AVCodec *, AVFormatContext *, AVStream *, int index); - ~Stream() noexcept; - - size_t getWidth() const noexcept; - size_t getHeight() const noexcept; - size_t getDuration() const noexcept; - size_t getFramesPerSecond() const noexcept; + VideoStream(AVCodec *, AVFormatContext *, AVStream *, int index); + ~VideoStream() noexcept override = default; - QJsonObject getProperties() const noexcept; + size_t getWidth() const noexcept; + size_t getHeight() const noexcept; + size_t getDuration() const noexcept; + size_t getFramesPerSecond() const noexcept; - static inline Utils::DeleterFunctionType<AVCodecContext> codecContexteleter = - std::bind_front(Utils::freePPtrIfNotNull<AVCodecContext>, avcodec_free_context); + QJsonObject getProperties() const noexcept override; - using AVCodecContextPtr = std::unique_ptr<AVCodecContext, decltype(codecContexteleter)>; + static inline Utils::DeleterFunctionType<AVCodecContext> codecContexteleter = + std::bind_front(Utils::freePPtrIfNotNull<AVCodecContext>, avcodec_free_context); - private: - AVCodecID codecId{ AV_CODEC_ID_NONE }; - AVCodec *codec{ nullptr }; - AVCodecParameters *codecParams{ nullptr }; - AVCodecContextPtr codecContext{ nullptr }; - - AVStream *videoStream{ nullptr }; - - int streamIndexInVideoContext; - }; +private: +}; - using StreamPtr = std::shared_ptr<Stream>; - using StreamWeakPtr = std::weak_ptr<Stream>; +// Like an audio context, but for videos. +class VideoContext final : public AbstractMediaContext<VideoStream> { + VIVY_UNMOVABLE_OBJECT(VideoContext) + using Super = AbstractMediaContext<VideoStream>; public: VideoContext(const QString &path); - StreamWeakPtr getStream(int) const noexcept; - StreamWeakPtr getDefaultStream() const noexcept; - - QString getElementName() const noexcept; - QJsonDocument getProperties() const noexcept; - -private: - static inline Utils::DeleterFunctionType<AVFormatContext> avFormatContextDeleter = - std::bind_front(Utils::freePtrIfNotNull<AVFormatContext>, avformat_free_context); - using AVFormatContextPtr = std::unique_ptr<AVFormatContext, decltype(avFormatContextDeleter)>; - AVFormatContextPtr format{ avformat_alloc_context(), avFormatContextDeleter }; - - const QString filePath; - QMap<uint, StreamPtr> videoStreams{}; - - int defaultStreamIndex{ -1 }; - - StreamPtr spareNullSreamPtr{ nullptr }; -}; + QString getElementName() const noexcept override; + QJsonDocument getProperties() const noexcept override; }; +} -- GitLab