Commit 0b17ce95 authored by Martin Tobias Holmedahl Sandsmark's avatar Martin Tobias Holmedahl Sandsmark Committed by Méven Car
Browse files

Implement image transforms

Should really just throw out 90% of the old "upstream" code and decode
straight to a QImage. Would improve the performance and significantly
slim down the codebase.

Code stolen from myself:
    https://invent.kde.org/sandsmark/qt-ffmpeg-imageplugin/-/blob/master/ffmpegimageplugin.cpp#L468-493

CCBUG: 404898
parent 0a14c863
......@@ -7,6 +7,8 @@
#include "imagewriter.h"
#include <iostream>
extern void qt_imageTransform(QImage &src, QImageIOHandler::Transformations transforms);
using namespace std;
namespace ffmpegthumbnailer
......@@ -16,7 +18,7 @@ ImageWriter::ImageWriter()
{
}
void ImageWriter::writeFrame(VideoFrame& frame, QImage& image)
void ImageWriter::writeFrame(VideoFrame& frame, QImage& image, const QImageIOHandler::Transformations transformations)
{
QImage previewImage(frame.width, frame.height, QImage::Format_RGB888);
for (quint32 y = 0; y < frame.height; y++) {
......@@ -24,6 +26,8 @@ void ImageWriter::writeFrame(VideoFrame& frame, QImage& image)
memcpy(previewImage.scanLine(y), &frame.frameData[y*frame.lineSize], frame.width*3);
}
qt_imageTransform(previewImage, transformations);
image = previewImage;
}
}
......@@ -11,6 +11,7 @@
#include <string>
#include <inttypes.h>
#include <QImage>
#include <QImageIOHandler>
namespace ffmpegthumbnailer
{
......@@ -21,7 +22,7 @@ public:
ImageWriter();
virtual ~ImageWriter() {}
virtual void writeFrame(VideoFrame& frame, QImage& image);
virtual void writeFrame(VideoFrame& frame, QImage& image, const QImageIOHandler::Transformations transformations);
};
}
......
......@@ -5,12 +5,14 @@
*/
#include "moviedecoder.h"
#include "ffmpegthumbs_debug.h"
#include <QDebug>
#include <QFileInfo>
extern "C" {
#include <libswscale/swscale.h>
#include <libavutil/display.h>
#include <libavutil/imgutils.h>
}
......@@ -90,6 +92,7 @@ void MovieDecoder::destroy()
avcodec_close(m_pVideoCodecContext);
m_pVideoCodecContext = nullptr;
}
m_pVideoStream = nullptr;
if ((!m_FormatContextWasGiven) && m_pFormatContext) {
avformat_close_input(&m_pFormatContext);
......@@ -131,7 +134,8 @@ bool MovieDecoder::initializeVideo()
}
m_pVideoCodecContext = avcodec_alloc_context3(m_pVideoCodec);
avcodec_parameters_to_context(m_pVideoCodecContext, m_pFormatContext->streams[m_VideoStream]->codecpar);
m_pVideoStream = m_pFormatContext->streams[m_VideoStream];
avcodec_parameters_to_context(m_pVideoCodecContext, m_pVideoStream->codecpar);
if (m_pVideoCodec == nullptr) {
// set to nullptr, otherwise avcodec_close(m_pVideoCodecContext) crashes
......@@ -251,6 +255,41 @@ bool MovieDecoder::decodeVideoPacket()
return true;
}
QImageIOHandler::Transformations MovieDecoder::transformations()
{
QImageIOHandler::Transformations ret = QImageIOHandler::TransformationNone;
if (!m_pVideoStream) {
qCWarning(ffmpegthumbs_LOG) << "No video stream!";
return ret;
}
for (int i=0; i<m_pVideoStream->nb_side_data; i++) {
if (m_pVideoStream->side_data[i].type != AV_PKT_DATA_DISPLAYMATRIX) {
continue;
}
if (m_pVideoStream->side_data[i].size != sizeof(int32_t) * 9) {
qCWarning(ffmpegthumbs_LOG) << "Invalid display matrix size" << m_pVideoStream->side_data[i].size << "expected" << sizeof(int32_t) * 9;
continue;
}
int32_t *matrix = reinterpret_cast<int32_t*>(m_pVideoStream->side_data[i].data);
double rotation = av_display_rotation_get(matrix);
if (qFuzzyCompare(rotation, 0.)) {
ret |= QImageIOHandler::TransformationNone;
} else if (qFuzzyCompare(rotation, 90.)) {
ret |= QImageIOHandler::TransformationRotate270;
} else if (qFuzzyCompare(rotation, 180.) || qFuzzyCompare(rotation, -180.)) {
ret |= QImageIOHandler::TransformationRotate180;
} else if (qFuzzyCompare(rotation, -90.)) {
ret |= QImageIOHandler::TransformationRotate90;
} else {
qCWarning(ffmpegthumbs_LOG) << "Unhandled rotation" << rotation;
continue;
}
}
return ret;
}
bool MovieDecoder::getVideoPacket()
{
bool framesAvailable = true;
......
......@@ -9,6 +9,7 @@
#include "videoframe.h"
#include <QString>
#include <QImageIOHandler>
extern "C" {
#include <libavcodec/avcodec.h>
......@@ -40,6 +41,8 @@ public:
void destroy();
bool getInitialized();
QImageIOHandler::Transformations transformations();
private:
bool initializeVideo();
......
......@@ -107,7 +107,7 @@ void VideoThumbnailer::generateThumbnail(const QString& videoFile, ImageWriter&
}
applyFilters(videoFrame);
imageWriter.writeFrame(videoFrame, image);
imageWriter.writeFrame(videoFrame, image, movieDecoder.transformations());
}
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment