Skip to content
Permalink
Browse files

VAAPI: Add picture control support.

Tested with the splitted desktop VDPAU backend (the Intel VAAPI driver
does not support picture controls).
  • Loading branch information
Mark Kendall
Mark Kendall committed Jun 18, 2011
1 parent 54d1f0e commit 8b0883e9b7d8a722e31856e37c2b33b615a7d337
@@ -214,13 +214,16 @@ VAAPIContext::VAAPIContext(MythCodecID codec)
m_vaProfile(VAProfileMPEG2Main)/* ?? */,
m_vaEntrypoint(VAEntrypointEncSlice),
m_pix_fmt(PIX_FMT_YUV420P), m_numSurfaces(NUM_VAAPI_BUFFERS),
m_surfaces(NULL), m_surfaceData(NULL)
m_surfaces(NULL), m_surfaceData(NULL), m_pictureAttributes(NULL),
m_pictureAttributeCount(0)
{
memset(&m_ctx, 0, sizeof(vaapi_context));
}

VAAPIContext::~VAAPIContext()
{
delete [] m_pictureAttributes;

ClearGLXSurfaces();

if (m_display)
@@ -275,6 +278,123 @@ bool VAAPIContext::CreateDisplay(QSize size)
return ok;
}

void VAAPIContext::InitPictureAttributes(VideoColourSpace &colourspace)
{
if (!m_display)
return;
if (!m_display->m_va_disp)
return;

delete [] m_pictureAttributes;
m_pictureAttributeCount = 0;
int supported_controls = kPictureAttributeSupported_None;
QList<VADisplayAttribute> supported;
int num = vaMaxNumDisplayAttributes(m_display->m_va_disp);
VADisplayAttribute* attribs = new VADisplayAttribute[num];

int actual = 0;
INIT_ST
va_status = vaQueryDisplayAttributes(m_display->m_va_disp, attribs, &actual);
CHECK_ST

for (int i = 0; i < actual; i++)
{
int type = attribs[i].type;
if ((attribs[i].flags & VA_DISPLAY_ATTRIB_SETTABLE) &&
(type == VADisplayAttribBrightness ||
type == VADisplayAttribContrast ||
type == VADisplayAttribHue ||
type == VADisplayAttribSaturation))
{
supported.push_back(attribs[i]);
if (type == VADisplayAttribBrightness)
supported_controls += kPictureAttributeSupported_Brightness;
if (type == VADisplayAttribHue)
supported_controls += kPictureAttributeSupported_Hue;
if (type == VADisplayAttribContrast)
supported_controls += kPictureAttributeSupported_Contrast;
if (type == VADisplayAttribSaturation)
supported_controls += kPictureAttributeSupported_Colour;
}
}

colourspace.SetSupportedAttributes((PictureAttributeSupported)supported_controls);
delete [] attribs;

if (!supported.size())
return;

m_pictureAttributeCount = supported.size();
m_pictureAttributes = new VADisplayAttribute[m_pictureAttributeCount];
for (int i = 0; i < m_pictureAttributeCount; i++)
m_pictureAttributes[i] = supported.at(i);

if (supported_controls & kPictureAttributeSupported_Brightness)
SetPictureAttribute(kPictureAttribute_Brightness,
colourspace.GetPictureAttribute(kPictureAttribute_Brightness));
if (supported_controls & kPictureAttributeSupported_Hue)
SetPictureAttribute(kPictureAttribute_Hue,
colourspace.GetPictureAttribute(kPictureAttribute_Hue));
if (supported_controls & kPictureAttributeSupported_Contrast)
SetPictureAttribute(kPictureAttribute_Contrast,
colourspace.GetPictureAttribute(kPictureAttribute_Contrast));
if (supported_controls & kPictureAttributeSupported_Colour)
SetPictureAttribute(kPictureAttribute_Colour,
colourspace.GetPictureAttribute(kPictureAttribute_Colour));
}

int VAAPIContext::SetPictureAttribute(PictureAttribute attribute, int newValue)
{
if (!m_display)
return newValue;
if (!m_display->m_va_disp)
return newValue;

VADisplayAttribType attrib = VADisplayAttribBrightness;
switch (attribute)
{
case kPictureAttribute_Brightness:
attrib = VADisplayAttribBrightness;
break;
case kPictureAttribute_Contrast:
attrib = VADisplayAttribContrast;
break;
case kPictureAttribute_Hue:
attrib = VADisplayAttribHue;
break;
case kPictureAttribute_Colour:
attrib = VADisplayAttribSaturation;
break;
default:
return -1;
}

bool found = false;
for (int i = 0; i < m_pictureAttributeCount; i++)
{
if (m_pictureAttributes[i].type == attrib)
{
int min = m_pictureAttributes[i].min_value;
int max = m_pictureAttributes[i].max_value;
int val = min + (int)(((float)newValue / 100.0) * (max - min));
m_pictureAttributes[i].value = val;
found = true;
break;
}
}

if (found)
{
INIT_ST
va_status = vaSetDisplayAttributes(m_display->m_va_disp,
m_pictureAttributes,
m_pictureAttributeCount);
CHECK_ST
return newValue;
}
return -1;
}

bool VAAPIContext::CreateBuffers(void)
{
bool ok = true;
@@ -5,6 +5,7 @@ extern "C" {
#include "libavcodec/vaapi.h"
}
#include "va/va_glx.h"
#include "videocolourspace.h"

struct vaapi_surface
{
@@ -39,6 +40,8 @@ class VAAPIContext
bool InitProfiles(void);
bool InitBuffers(void);
bool InitContext(void);
void InitPictureAttributes(VideoColourSpace &colourspace);
int SetPictureAttribute(PictureAttribute attribute, int newValue);

vaapi_context m_ctx;
MythCodecID m_codec;
@@ -51,6 +54,8 @@ class VAAPIContext
VASurfaceID *m_surfaces;
vaapi_surface *m_surfaceData;
QHash<uint, void*> m_glxSurfaces;
VADisplayAttribute* m_pictureAttributes;
int m_pictureAttributeCount;
};

#endif // VAAPICONTEXT_H
@@ -608,7 +608,7 @@ int VideoOutputOpenGL::SetPictureAttribute(PictureAttribute attribute,
if (!gl_context)
return -1;

return videoColourSpace.SetPictureAttribute(attribute, newValue);
return VideoOutput::SetPictureAttribute(attribute, newValue);
}

bool VideoOutputOpenGL::SetupDeinterlace(
@@ -31,8 +31,8 @@ class VideoOutputOpenGL : public VideoOutput
void DrawUnusedRects(bool) { }
void Zoom(ZoomDirection direction);
void MoveResize(void);
int SetPictureAttribute(PictureAttribute attribute, int newValue);
void InitPictureAttributes(void);
virtual int SetPictureAttribute(PictureAttribute attribute, int newValue);
virtual void InitPictureAttributes(void);
static QStringList GetAllowedRenderers(MythCodecID myth_codec_id,
const QSize &video_dim);
void EmbedInWidget(const QRect &rect);
@@ -139,6 +139,7 @@ bool VideoOutputOpenGLVAAPI::CreateVAAPIContext(QSize size)
m_ctx->GetVideoSurface(i),
FMT_VAAPI);
}
InitPictureAttributes();
return ok;
}

@@ -208,6 +209,26 @@ bool VideoOutputOpenGLVAAPI::SetupDeinterlace(bool i, const QString& ovrf)
return m_deinterlacing;
}

void VideoOutputOpenGLVAAPI::InitPictureAttributes(void)
{
if (codec_is_vaapi(video_codec_id))
{
if (m_ctx)
m_ctx->InitPictureAttributes(videoColourSpace);
return;
}
VideoOutputOpenGL::InitPictureAttributes();
}

int VideoOutputOpenGLVAAPI::SetPictureAttribute(PictureAttribute attribute,
int newValue)
{
int val = newValue;
if (codec_is_vaapi(video_codec_id) && m_ctx)
val = m_ctx->SetPictureAttribute(attribute, newValue);
return VideoOutput::SetPictureAttribute(attribute, val);
}

void VideoOutputOpenGLVAAPI::ProcessFrame(VideoFrame *frame, OSD *osd,
FilterChain *filterList,
const PIPMap &pipPlayers,
@@ -32,7 +32,8 @@ class VideoOutputOpenGLVAAPI : public VideoOutputOpenGL
bool ApproveDeintFilter(const QString& filtername) const;
bool SetDeinterlacingEnabled(bool enable);
bool SetupDeinterlace(bool i, const QString& ovrf="");
void InitPictureAttributes(void) { }
virtual void InitPictureAttributes(void);
virtual int SetPictureAttribute(PictureAttribute attribute, int newValue);

static QStringList GetAllowedRenderers(MythCodecID myth_codec_id,
const QSize &video_dim);

0 comments on commit 8b0883e

Please sign in to comment.
You can’t perform that action at this time.