Skip to content
Extraits de code Groupes Projets
Vérifiée Valider fc32cbf9 rédigé par Kubat's avatar Kubat
Parcourir les fichiers

[WIP] Begin implementation of VideoContext

parent 4cdb4e9d
Aucune branche associée trouvée
Aucune étiquette associée trouvée
1 requête de fusion!18Implement the VivyDocument specification
#include "Video.hh"
#include "Utils.hh"
#include <QJsonObject>
#include <QJsonArray>
using namespace Vivy;
VideoContext::VideoContext(const QString &path)
: filePath(path)
{
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");
}
// 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));
}
}
// 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";
}
qDebug() << "Opened video context for" << path << "with duration" << formatPtr->duration
<< "and default stream index" << defaultStreamIndex;
}
#pragma once
#ifndef __cplusplus
#error "This is a C++ header"
#endif
extern "C" {
#include <libavutil/opt.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswresample/swresample.h>
#include <libavcodec/avfft.h>
#include <memory.h>
}
#include "Utils.hh"
#include <QtGlobal>
#include <QMap>
#include <QVector>
#include <QString>
namespace Vivy
{
class VideoContext;
// Like an audio context, but for videos.
class VideoContext final {
VIVY_UNMOVABLE_OBJECT(VideoContext)
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;
QJsonObject getProperties() const noexcept;
static inline Utils::DeleterFunctionType<AVCodecContext> codecContexteleter =
std::bind_front(Utils::freePPtrIfNotNull<AVCodecContext>, avcodec_free_context);
using AVCodecContextPtr = std::unique_ptr<AVCodecContext, decltype(codecContexteleter)>;
private:
AVCodecID codecId{ AV_CODEC_ID_NONE };
AVCodec *codec{ nullptr };
AVCodecParameters *codecParams{ nullptr };
AVCodecContextPtr codecContext{ nullptr };
AVStream *videoStream{ nullptr };
int streamIndexInVideoContext;
};
using StreamPtr = std::shared_ptr<Stream>;
using StreamWeakPtr = std::weak_ptr<Stream>;
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 };
};
};
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter