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

[WIP] LIB: The video stream/context are also using the abstract things

parent 53f310ab
Aucune branche associée trouvée
Aucune étiquette associée trouvée
1 requête de fusion!18Implement the VivyDocument specification
...@@ -82,7 +82,7 @@ protected: ...@@ -82,7 +82,7 @@ protected:
} }
public: public:
virtual ~AbstractMediaStream() noexcept = default; virtual ~AbstractMediaStream() noexcept {}
int getStreamIndex() const noexcept { return streamIndexInContext; } int getStreamIndex() const noexcept { return streamIndexInContext; }
QString getName() const noexcept { return QString::fromUtf8(codec->name); } QString getName() const noexcept { return QString::fromUtf8(codec->name); }
AVCodecID getCodecId() const noexcept { return codecId; } AVCodecID getCodecId() const noexcept { return codecId; }
......
...@@ -6,45 +6,31 @@ ...@@ -6,45 +6,31 @@
using namespace Vivy; using namespace Vivy;
VideoContext::VideoContext(const QString &path) VideoStream::VideoStream(AVCodec *streamCodec, AVFormatContext *formatArg, AVStream *streamArg,
: filePath(path) 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) { QJsonObject
throw std::runtime_error("failed to get video stream info"); VideoStream::getProperties() const noexcept
{
return Super::getProperties();
} }
// Populate all the stream indexes VideoContext::VideoContext(const QString &path)
for (uint i = 0; i < format->nb_streams; ++i) { : Super(path)
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 QJsonDocument
defaultStreamIndex = av_find_best_stream(formatPtr, AVMEDIA_TYPE_VIDEO, VideoContext::getProperties() const noexcept
-1, // Let AV find one stream {
-1, // We don't want related streams return Super::getProperties();
nullptr, 0);
if (defaultStreamIndex < 0) {
qCritical() << "Could not find the best video stream";
} }
qDebug() << "Opened video context for" << path << "with duration" << formatPtr->duration QString
<< "and default stream index" << defaultStreamIndex; VideoContext::getElementName() const noexcept
{
return "Video" + Super::getElementName();
} }
...@@ -21,68 +21,38 @@ extern "C" { ...@@ -21,68 +21,38 @@ extern "C" {
namespace Vivy 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 // Hold all the data for a video stream. Should only be owned by the parent
// VideoContext instance. // VideoContext instance.
class Stream final { class VideoStream final : public AbstractMediaStream<AVMEDIA_TYPE_VIDEO> {
VIVY_UNMOVABLE_OBJECT(Stream) VIVY_UNMOVABLE_OBJECT(VideoStream)
using Super = AbstractMediaStream<AVMEDIA_TYPE_VIDEO>;
public: public:
Stream(AVCodec *, AVFormatContext *, AVStream *, int index); VideoStream(AVCodec *, AVFormatContext *, AVStream *, int index);
~Stream() noexcept; ~VideoStream() noexcept override = default;
size_t getWidth() const noexcept; size_t getWidth() const noexcept;
size_t getHeight() const noexcept; size_t getHeight() const noexcept;
size_t getDuration() const noexcept; size_t getDuration() const noexcept;
size_t getFramesPerSecond() const noexcept; size_t getFramesPerSecond() const noexcept;
QJsonObject getProperties() const noexcept; QJsonObject getProperties() const noexcept override;
static inline Utils::DeleterFunctionType<AVCodecContext> codecContexteleter = static inline Utils::DeleterFunctionType<AVCodecContext> codecContexteleter =
std::bind_front(Utils::freePPtrIfNotNull<AVCodecContext>, avcodec_free_context); std::bind_front(Utils::freePPtrIfNotNull<AVCodecContext>, avcodec_free_context);
using AVCodecContextPtr = std::unique_ptr<AVCodecContext, decltype(codecContexteleter)>;
private: 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>; // Like an audio context, but for videos.
using StreamWeakPtr = std::weak_ptr<Stream>; class VideoContext final : public AbstractMediaContext<VideoStream> {
VIVY_UNMOVABLE_OBJECT(VideoContext)
using Super = AbstractMediaContext<VideoStream>;
public: public:
VideoContext(const QString &path); VideoContext(const QString &path);
StreamWeakPtr getStream(int) const noexcept; QString getElementName() const noexcept override;
StreamWeakPtr getDefaultStream() const noexcept; QJsonDocument getProperties() const noexcept override;
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.
Veuillez vous inscrire ou vous pour commenter