File indexing completed on 2024-04-14 04:44:05

0001 /*
0002     SPDX-FileCopyrightText: 2010 Dirk Vanden Boer <dirk.vdb@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #ifndef MOVIEDECODER_H
0008 #define MOVIEDECODER_H
0009 
0010 #include "videoframe.h"
0011 #include <QString>
0012 #include <QImageIOHandler>
0013 
0014 extern "C" {
0015 #include <libavcodec/avcodec.h>
0016 #include <libavformat/avformat.h>
0017 #include <libavfilter/avfilter.h>
0018 #include <libavfilter/buffersrc.h>
0019 #include <libavfilter/buffersink.h>
0020 }
0021 
0022 namespace ffmpegthumbnailer
0023 {
0024 
0025 class MovieDecoder
0026 {
0027 public:
0028     explicit MovieDecoder(const QString& filename, AVFormatContext* pavContext = nullptr);
0029     ~MovieDecoder();
0030 
0031     QString getCodec();
0032     void seek(int timeInSeconds);
0033     bool decodeVideoFrame();
0034     void getScaledVideoFrame(int scaledSize, bool maintainAspectRatio, VideoFrame& videoFrame);
0035 
0036     int getWidth();
0037     int getHeight();
0038     int getDuration();
0039 
0040     void initialize(const QString& filename);
0041     void destroy();
0042     bool getInitialized();
0043 
0044     QImageIOHandler::Transformations transformations();
0045 
0046 private:
0047     bool initializeVideo();
0048 
0049     bool decodeVideoPacket();
0050     bool getVideoPacket();
0051     void convertAndScaleFrame(AVPixelFormat format, int scaledSize, bool maintainAspectRatio, int& scaledWidth, int& scaledHeight);
0052     void createAVFrame(AVFrame** avFrame, quint8** frameBuffer, int width, int height, AVPixelFormat format);
0053     void calculateDimensions(int squareSize, bool maintainAspectRatio, int& destWidth, int& destHeight);
0054 
0055     void deleteFilterGraph();
0056     bool initFilterGraph(enum AVPixelFormat pixfmt, int width, int height);
0057     bool processFilterGraph(AVFrame *dst, const AVFrame *src, enum AVPixelFormat pixfmt, int width, int height);
0058 
0059 private:
0060     int                     m_VideoStream;
0061     AVFormatContext*        m_pFormatContext;
0062     AVCodecContext*         m_pVideoCodecContext;
0063 #if LIBAVCODEC_VERSION_MAJOR < 59
0064     AVCodec*                m_pVideoCodec;
0065 #else
0066     const AVCodec*          m_pVideoCodec;
0067 #endif
0068     AVStream*               m_pVideoStream;
0069     AVFrame*                m_pFrame;
0070     quint8*                 m_pFrameBuffer;
0071     AVPacket*               m_pPacket;
0072     bool                    m_FormatContextWasGiven;
0073     bool                    m_AllowSeek;
0074     bool                    m_initialized;
0075     AVFilterContext*        m_bufferSinkContext;
0076     AVFilterContext*        m_bufferSourceContext;
0077     AVFilterGraph*          m_filterGraph;
0078     AVFrame*                m_filterFrame;
0079     int                     m_lastWidth;
0080     int                     m_lastHeight;
0081     enum AVPixelFormat      m_lastPixfmt;
0082 };
0083 
0084 }
0085 
0086 #endif