Files
oak-editor/decoders/pixelformatconverter.h
T

145 lines
3.8 KiB
C++

#ifndef PIXELFORMATCONVERTER_H
#define PIXELFORMATCONVERTER_H
extern "C" {
#include <libavutil/pixfmt.h>
}
#include <QMutex>
#include <QThread>
#include <QWaitCondition>
#include "rendering/pixelformats.h"
class PixFmtConvertThread : public QThread {
public:
PixFmtConvertThread();
virtual void run() override;
void Convert(uint8_t** input_buffer,
int* input_linesize,
const int &width,
const int &line_start,
const int &line_count,
AVPixelFormat input_fmt,
void* output_buffer,
olive::PixelFormat output_fmt);
void WaitUntilComplete();
void Cancel();
private:
// Main processing function
void Process();
// Threading variables
QWaitCondition wait_cond_;
QMutex mutex_;
QMutex mutex2_;
bool cancelled_;
// Input variables for conversion
uint8_t** input_buffer_;
int* input_linesize_;
int width_;
int line_start_;
int line_count_;
AVPixelFormat input_fmt_;
// Output variables for conversion
void* output_buffer_;
olive::PixelFormat output_fmt_;
};
/**
* @brief The PixelFormatConverter class
*
* A background process for optimized conversion of frames to Olive's internal pipeline format. It is designed as a
* replacement of FFmpeg's swscale for all pixel format conversions. It's main advantages over swscale are:
*
* * Support for floating-point pixel formats
* * Better control over the conversion from YCbCr to RGB
* * Multithreaded by design
*
* In the old system, frame pixel formats were converted twice - once to RGBA32 or RGBA64 by swscale, then a second
* time to RGBA16F or RGBA32F by OpenGL. In addition to the aforementioned advantages, a future goal of this class is to
* reduce those two steps to one.
*/
class PixelFormatConverter
{
public:
PixelFormatConverter();
~PixelFormatConverter();
/**
* @brief Converts data from FFmpeg (or equivalent data) to data ready for Olive's buffer
*
* @param input_buffer
*
* The buffer of data to convert. This can be fed AVFrame->data directly.
*
* @param input_linesize
*
* The linesize of the data to convert. This can be fed AVFrame->linesize directly.
*
* @param width
*
* Width of the frame. This will be the same in the output buffer.
*
* @param height
*
* Height of the frame. This will be the same in the output buffer.
*
* @param input_fmt
*
* Expects a value from the AVPixelFormat enum.
*
* @param output_buffer
*
* The buffer to place the converted data. This function does NOT allocate data, this must be done beforehand.
* The helper function GetBufferSize() can be used to determine the minimum size (in bytes) that this buffer
* needs to have allocated for this function to be successful.
*
* @param output_fmt
*
* The format to convert to. Must be a member of the olive::PixelFormat enum.
*/
void AVFrameToPipeline(uint8_t** input_buffer,
int* input_linesize,
const int &width,
const int &height,
AVPixelFormat input_fmt,
void* output_buffer,
olive::PixelFormat output_fmt);
/**
* @brief Returns the minimum buffer size (in bytes) necessary for a given format, width, and height.
*
* @param format
*
* The format of the data the buffer should contain. Must be a member of the olive::PixelFormat enum.
*
* @param width
*
* The width (in pixels) of the buffer.
*
* @param height
*
* The height (in pixels) of the buffer.
*/
static int GetBufferSize(olive::PixelFormat format, const int& width, const int& height);
private:
QMutex mutex_;
QVector<PixFmtConvertThread*> threads_;
};
namespace olive {
extern PixelFormatConverter* pix_fmt_conv;
}
#endif // PIXELFORMATCONVERTER_H