various: pixel optimizations
Several things are accomplished in this commit, including: - Use OIIO instead of our own functions for pixel format conversions (cleaner code/less for us to maintain) - Fold all PixelService functions into the PixelFormat class (cleaner code) - Moved OpenGL pixel definitions to OpenGL classes and out of the global classes. - Add support for RGB buffers as well as RGBA (optimization)
This commit is contained in:
@@ -3,7 +3,9 @@
|
||||
AVPixelFormat FFmpegCommon::GetCompatiblePixelFormat(const AVPixelFormat &pix_fmt)
|
||||
{
|
||||
AVPixelFormat possible_pix_fmts[] = {
|
||||
AV_PIX_FMT_RGB24,
|
||||
AV_PIX_FMT_RGBA,
|
||||
AV_PIX_FMT_RGB48,
|
||||
AV_PIX_FMT_RGBA64,
|
||||
AV_PIX_FMT_NONE
|
||||
};
|
||||
@@ -73,8 +75,14 @@ AVPixelFormat FFmpegCommon::GetFFmpegPixelFormat(const PixelFormat::Format &pix_
|
||||
return AV_PIX_FMT_RGBA;
|
||||
case PixelFormat::PIX_FMT_RGBA16U:
|
||||
return AV_PIX_FMT_RGBA64;
|
||||
case PixelFormat::PIX_FMT_RGB8:
|
||||
return AV_PIX_FMT_RGB24;
|
||||
case PixelFormat::PIX_FMT_RGB16U:
|
||||
return AV_PIX_FMT_RGB48;
|
||||
case PixelFormat::PIX_FMT_RGBA16F:
|
||||
case PixelFormat::PIX_FMT_RGBA32F:
|
||||
case PixelFormat::PIX_FMT_RGB16F:
|
||||
case PixelFormat::PIX_FMT_RGB32F:
|
||||
case PixelFormat::PIX_FMT_INVALID:
|
||||
case PixelFormat::PIX_FMT_COUNT:
|
||||
break;
|
||||
@@ -86,8 +94,14 @@ AVPixelFormat FFmpegCommon::GetFFmpegPixelFormat(const PixelFormat::Format &pix_
|
||||
PixelFormat::Format FFmpegCommon::GetCompatiblePixelFormat(const PixelFormat::Format &pix_fmt)
|
||||
{
|
||||
switch (pix_fmt) {
|
||||
case PixelFormat::PIX_FMT_RGB8:
|
||||
return PixelFormat::PIX_FMT_RGB8;
|
||||
case PixelFormat::PIX_FMT_RGBA8:
|
||||
return PixelFormat::PIX_FMT_RGBA8;
|
||||
case PixelFormat::PIX_FMT_RGB16U:
|
||||
case PixelFormat::PIX_FMT_RGB16F:
|
||||
case PixelFormat::PIX_FMT_RGB32F:
|
||||
return PixelFormat::PIX_FMT_RGB16U;
|
||||
case PixelFormat::PIX_FMT_RGBA16U:
|
||||
case PixelFormat::PIX_FMT_RGBA16F:
|
||||
case PixelFormat::PIX_FMT_RGBA32F:
|
||||
|
||||
@@ -40,7 +40,7 @@ extern "C" {
|
||||
#include "common/timecodefunctions.h"
|
||||
#include "ffmpegcommon.h"
|
||||
#include "render/diskmanager.h"
|
||||
#include "render/pixelservice.h"
|
||||
#include "render/pixelformat.h"
|
||||
|
||||
FFmpegDecoder::FFmpegDecoder() :
|
||||
fmt_ctx_(nullptr),
|
||||
@@ -154,11 +154,20 @@ bool FFmpegDecoder::Open()
|
||||
|
||||
// Determine which Olive native pixel format we retrieved
|
||||
// Note that FFmpeg doesn't support float formats
|
||||
if (ideal_pix_fmt_ == AV_PIX_FMT_RGBA) {
|
||||
switch (ideal_pix_fmt_) {
|
||||
case AV_PIX_FMT_RGB24:
|
||||
native_pix_fmt_ = PixelFormat::PIX_FMT_RGB8;
|
||||
break;
|
||||
case AV_PIX_FMT_RGBA:
|
||||
native_pix_fmt_ = PixelFormat::PIX_FMT_RGBA8;
|
||||
} else if (ideal_pix_fmt_ == AV_PIX_FMT_RGBA64) {
|
||||
break;
|
||||
case AV_PIX_FMT_RGB48:
|
||||
native_pix_fmt_ = PixelFormat::PIX_FMT_RGB16U;
|
||||
break;
|
||||
case AV_PIX_FMT_RGBA64:
|
||||
native_pix_fmt_ = PixelFormat::PIX_FMT_RGBA16U;
|
||||
} else {
|
||||
break;
|
||||
default:
|
||||
// We should never get here, but just in case...
|
||||
qFatal("Invalid output format");
|
||||
}
|
||||
@@ -378,7 +387,7 @@ FramePtr FFmpegDecoder::RetrieveVideo(const rational &timecode)
|
||||
|
||||
// Convert frame to RGBA for the rest of the pipeline
|
||||
uint8_t* output_data = reinterpret_cast<uint8_t*>(working_frame_converted->data());
|
||||
int output_linesize = working_frame_converted->width() * kRGBAChannels * PixelService::BytesPerChannel(native_pix_fmt_);
|
||||
int output_linesize = working_frame_converted->width() * PixelFormat::ChannelCount(native_pix_fmt_) * PixelFormat::BytesPerChannel(native_pix_fmt_);
|
||||
|
||||
sws_scale(scale_ctx_,
|
||||
working_frame->data,
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include <QFile>
|
||||
|
||||
#include "ffmpegcommon.h"
|
||||
#include "render/pixelservice.h"
|
||||
#include "render/pixelformat.h"
|
||||
|
||||
FFmpegEncoder::FFmpegEncoder(const EncodingParams ¶ms) :
|
||||
Encoder(params),
|
||||
@@ -188,12 +188,12 @@ void FFmpegEncoder::WriteInternal(FramePtr frame)
|
||||
|
||||
// We may need to convert this frame to a frame that swscale will understand
|
||||
if (frame->format() != video_conversion_fmt_) {
|
||||
frame = PixelService::ConvertPixelFormat(frame, video_conversion_fmt_);
|
||||
frame = PixelFormat::ConvertPixelFormat(frame, video_conversion_fmt_);
|
||||
}
|
||||
|
||||
// Use swscale context to convert formats/linesizes
|
||||
input_data = frame->const_data();
|
||||
input_linesize = frame->width() * PixelService::BytesPerPixel(video_conversion_fmt_);
|
||||
input_linesize = frame->width() * PixelFormat::BytesPerPixel(video_conversion_fmt_);
|
||||
error_code = sws_scale(video_scale_ctx_,
|
||||
reinterpret_cast<const uint8_t**>(&input_data),
|
||||
&input_linesize,
|
||||
|
||||
+1
-3
@@ -23,8 +23,6 @@
|
||||
#include <QDebug>
|
||||
#include <QtGlobal>
|
||||
|
||||
#include "render/pixelservice.h"
|
||||
|
||||
Frame::Frame() :
|
||||
width_(0),
|
||||
height_(0),
|
||||
@@ -139,7 +137,7 @@ void Frame::allocate()
|
||||
{
|
||||
// Assume this frame is intended to be a video frame
|
||||
if (width_ > 0 && height_ > 0) {
|
||||
data_.resize(PixelService::GetBufferSize(static_cast<PixelFormat::Format>(format_), width_, height_));
|
||||
data_.resize(PixelFormat::GetBufferSize(static_cast<PixelFormat::Format>(format_), width_, height_));
|
||||
} else if (sample_count_ > 0) {
|
||||
data_.resize(audio_params_.samples_to_bytes(sample_count_));
|
||||
}
|
||||
|
||||
@@ -115,25 +115,24 @@ bool OIIODecoder::Open()
|
||||
width_ = spec.width;
|
||||
height_ = spec.height;
|
||||
|
||||
is_rgba_ = (spec.nchannels == kRGBAChannels);
|
||||
|
||||
// Weirdly, switch statement doesn't work correctly here
|
||||
if (spec.format == OIIO::TypeDesc::UINT8) {
|
||||
pix_fmt_ = PixelFormat::PIX_FMT_RGBA8;
|
||||
pix_fmt_ = is_rgba_ ? PixelFormat::PIX_FMT_RGBA8 : PixelFormat::PIX_FMT_RGB8;
|
||||
} else if (spec.format == OIIO::TypeDesc::UINT16) {
|
||||
pix_fmt_ = PixelFormat::PIX_FMT_RGBA16U;
|
||||
pix_fmt_ = is_rgba_ ? PixelFormat::PIX_FMT_RGBA16U : PixelFormat::PIX_FMT_RGB16U;
|
||||
} else if (spec.format == OIIO::TypeDesc::HALF) {
|
||||
pix_fmt_ = PixelFormat::PIX_FMT_RGBA16F;
|
||||
pix_fmt_ = is_rgba_ ? PixelFormat::PIX_FMT_RGBA16F : PixelFormat::PIX_FMT_RGB16F;
|
||||
} else if (spec.format == OIIO::TypeDesc::FLOAT) {
|
||||
pix_fmt_ = PixelFormat::PIX_FMT_RGBA32F;
|
||||
pix_fmt_ = is_rgba_ ? PixelFormat::PIX_FMT_RGBA32F : PixelFormat::PIX_FMT_RGB32F;
|
||||
} else {
|
||||
qWarning() << "Failed to convert OIIO::ImageDesc to native pixel format";
|
||||
return false;
|
||||
}
|
||||
|
||||
// FIXME: Many OIIO pixel formats are not handled here
|
||||
|
||||
is_rgba_ = (spec.nchannels == kRGBAChannels);
|
||||
|
||||
pix_fmt_info_ = PixelService::GetPixelFormatInfo(static_cast<PixelFormat::Format>(pix_fmt_));
|
||||
type_ = PixelFormat::GetOIIOTypeDesc(pix_fmt_);
|
||||
|
||||
open_ = true;
|
||||
|
||||
@@ -170,12 +169,7 @@ FramePtr OIIODecoder::RetrieveVideo(const rational &timecode)
|
||||
frame_->allocate();
|
||||
|
||||
// Use the native format to determine what format OIIO should return
|
||||
// FIXME: Behavior of RGB images as opposed to RGBA?
|
||||
image_->read_image(pix_fmt_info_.oiio_desc, frame_->data());
|
||||
|
||||
if (!is_rgba_) {
|
||||
PixelService::ConvertRGBtoRGBA(frame_);
|
||||
}
|
||||
image_->read_image(type_, frame_->data());
|
||||
}
|
||||
|
||||
return frame_;
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include <OpenImageIO/imageio.h>
|
||||
|
||||
#include "codec/decoder.h"
|
||||
#include "render/pixelservice.h"
|
||||
#include "render/pixelformat.h"
|
||||
|
||||
class OIIODecoder : public Decoder
|
||||
{
|
||||
@@ -57,7 +57,7 @@ private:
|
||||
|
||||
PixelFormat::Format pix_fmt_;
|
||||
|
||||
PixelFormat::Info pix_fmt_info_;
|
||||
OIIO::TypeDesc type_;
|
||||
|
||||
bool is_rgba_;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user