Skip to content

Commit

Permalink
[mmalrenderer] Switch to using transform flags for 3d modes
Browse files Browse the repository at this point in the history
  • Loading branch information
popcornmix committed Oct 6, 2015
1 parent 4d34d68 commit 50a94e5
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 130 deletions.
10 changes: 10 additions & 0 deletions addons/resource.language.en_gb/resources/strings.po
Expand Up @@ -18195,6 +18195,16 @@ msgctxt "#38111"
msgid "This option decodes frames for both eyes of MVC video. Disabling may improve performance if you don't require 3D"
msgstr ""

#: system/settings/rbp.xml
msgctxt "#38112"
msgid "Use Full HD HDMI modes for 3D"
msgstr ""

#: system/settings/rbp.xml
msgctxt "#38113"
msgid "This option uses frame-packing to output full resolution for 3D through HDMI"
msgstr ""

#: system/settings/settings.xml
msgctxt "#38103"
msgid "Extract thumbnails from video files"
Expand Down
8 changes: 8 additions & 0 deletions system/settings/rbp.xml
Expand Up @@ -33,6 +33,14 @@
<default>true</default>
<control type="toggle" />
</setting>
<setting id="videoplayer.framepacking" type="boolean" label="38112" help="38113">
<dependencies>
<dependency type="enable" setting="videoplayer.supportmvc">true</dependency>
</dependencies>
<level>2</level>
<default>true</default>
<control type="toggle" />
</setting>
</group>
</category>
<category id="myvideos">
Expand Down
92 changes: 26 additions & 66 deletions xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp
Expand Up @@ -445,11 +445,7 @@ void CMMALRenderer::RenderUpdate(bool clear, DWORD flags, DWORD alpha)
return;
}

if (g_graphicsContext.GetStereoMode())
g_graphicsContext.SetStereoView(RENDER_STEREO_VIEW_LEFT);
ManageDisplay();
if (g_graphicsContext.GetStereoMode())
g_graphicsContext.SetStereoView(RENDER_STEREO_VIEW_OFF);

// if running bypass, then the player might need the src/dst rects
// for sizing video playback on a layer other than the gles layer.
Expand Down Expand Up @@ -671,10 +667,8 @@ EINTERLACEMETHOD CMMALRenderer::AutoInterlaceMethod()

void CMMALRenderer::SetVideoRect(const CRect& InSrcRect, const CRect& InDestRect)
{
// we get called twice a frame for left/right. Can ignore the rights.
if (g_graphicsContext.GetStereoView() == RENDER_STEREO_VIEW_RIGHT)
return;
CSingleLock lock(m_sharedSection);
assert(g_graphicsContext.GetStereoView() != RENDER_STEREO_VIEW_RIGHT);

if (!m_vout_input)
return;
Expand Down Expand Up @@ -716,41 +710,10 @@ void CMMALRenderer::SetVideoRect(const CRect& InSrcRect, const CRect& InDestRect
CRect gui(0, 0, CDisplaySettings::GetInstance().GetResolutionInfo(res).iWidth, CDisplaySettings::GetInstance().GetResolutionInfo(res).iHeight);
CRect display(0, 0, CDisplaySettings::GetInstance().GetResolutionInfo(res).iScreenWidth, CDisplaySettings::GetInstance().GetResolutionInfo(res).iScreenHeight);

if (display_stereo_mode != RENDER_STEREO_MODE_OFF && display_stereo_mode != RENDER_STEREO_MODE_MONO)
switch (video_stereo_mode)
{
case RENDER_STEREO_MODE_SPLIT_VERTICAL:
// optimisation - use simpler display mode in common case of unscaled 3d with same display mode
if (video_stereo_mode == display_stereo_mode && DestRect.x1 == 0.0f && DestRect.x2 * 2.0f == gui.Width() && !stereo_invert)
{
SrcRect.x2 *= 2.0f;
DestRect.x2 *= 2.0f;
video_stereo_mode = RENDER_STEREO_MODE_OFF;
display_stereo_mode = RENDER_STEREO_MODE_OFF;
}
else if (display_stereo_mode == RENDER_STEREO_MODE_ANAGLYPH_RED_CYAN || display_stereo_mode == RENDER_STEREO_MODE_ANAGLYPH_GREEN_MAGENTA || display_stereo_mode == RENDER_STEREO_MODE_ANAGLYPH_YELLOW_BLUE)
{
SrcRect.x2 *= 2.0f;
}
break;

case RENDER_STEREO_MODE_SPLIT_HORIZONTAL:
// optimisation - use simpler display mode in common case of unscaled 3d with same display mode
if (video_stereo_mode == display_stereo_mode && DestRect.y1 == 0.0f && DestRect.y2 * 2.0f == gui.Height() && !stereo_invert)
{
SrcRect.y2 *= 2.0f;
DestRect.y2 *= 2.0f;
video_stereo_mode = RENDER_STEREO_MODE_OFF;
display_stereo_mode = RENDER_STEREO_MODE_OFF;
}
else if (display_stereo_mode == RENDER_STEREO_MODE_ANAGLYPH_RED_CYAN || display_stereo_mode == RENDER_STEREO_MODE_ANAGLYPH_GREEN_MAGENTA || display_stereo_mode == RENDER_STEREO_MODE_ANAGLYPH_YELLOW_BLUE)
{
SrcRect.y2 *= 2.0f;
}
break;

default: break;
}
if (display_stereo_mode == RENDER_STEREO_MODE_SPLIT_VERTICAL)
DestRect.x2 *= 2.0f;
else if (display_stereo_mode == RENDER_STEREO_MODE_SPLIT_HORIZONTAL)
DestRect.y2 *= 2.0f;

if (gui != display)
{
Expand All @@ -765,7 +728,7 @@ void CMMALRenderer::SetVideoRect(const CRect& InSrcRect, const CRect& InDestRect
MMAL_DISPLAYREGION_T region;
memset(&region, 0, sizeof region);

region.set = MMAL_DISPLAY_SET_DEST_RECT|MMAL_DISPLAY_SET_SRC_RECT|MMAL_DISPLAY_SET_FULLSCREEN|MMAL_DISPLAY_SET_NOASPECT|MMAL_DISPLAY_SET_MODE;
region.set = MMAL_DISPLAY_SET_DEST_RECT|MMAL_DISPLAY_SET_SRC_RECT|MMAL_DISPLAY_SET_FULLSCREEN|MMAL_DISPLAY_SET_NOASPECT|MMAL_DISPLAY_SET_MODE|MMAL_DISPLAY_SET_TRANSFORM;
region.dest_rect.x = lrintf(DestRect.x1);
region.dest_rect.y = lrintf(DestRect.y1);
region.dest_rect.width = lrintf(DestRect.Width());
Expand All @@ -778,35 +741,32 @@ void CMMALRenderer::SetVideoRect(const CRect& InSrcRect, const CRect& InDestRect

region.fullscreen = MMAL_FALSE;
region.noaspect = MMAL_TRUE;
region.mode = MMAL_DISPLAY_MODE_LETTERBOX;

if (m_renderOrientation == 90)
region.transform = MMAL_DISPLAY_ROT90;
else if (m_renderOrientation == 180)
region.transform = MMAL_DISPLAY_ROT180;
else if (m_renderOrientation == 270)
region.transform = MMAL_DISPLAY_ROT270;
else
region.transform = MMAL_DISPLAY_ROT0;

if (m_renderOrientation)
{
region.set |= MMAL_DISPLAY_SET_TRANSFORM;
if (m_renderOrientation == 90)
region.transform = MMAL_DISPLAY_ROT90;
else if (m_renderOrientation == 180)
region.transform = MMAL_DISPLAY_ROT180;
else if (m_renderOrientation == 270)
region.transform = MMAL_DISPLAY_ROT270;
else assert(0);
}

if (video_stereo_mode == RENDER_STEREO_MODE_SPLIT_HORIZONTAL && display_stereo_mode == RENDER_STEREO_MODE_SPLIT_HORIZONTAL)
region.mode = MMAL_DISPLAY_MODE_STEREO_TOP_TO_TOP;
else if (video_stereo_mode == RENDER_STEREO_MODE_SPLIT_HORIZONTAL && display_stereo_mode == RENDER_STEREO_MODE_SPLIT_VERTICAL)
region.mode = MMAL_DISPLAY_MODE_STEREO_TOP_TO_LEFT;
else if (video_stereo_mode == RENDER_STEREO_MODE_SPLIT_VERTICAL && display_stereo_mode == RENDER_STEREO_MODE_SPLIT_HORIZONTAL)
region.mode = MMAL_DISPLAY_MODE_STEREO_LEFT_TO_TOP;
else if (video_stereo_mode == RENDER_STEREO_MODE_SPLIT_VERTICAL && display_stereo_mode == RENDER_STEREO_MODE_SPLIT_VERTICAL)
region.mode = MMAL_DISPLAY_MODE_STEREO_LEFT_TO_LEFT;
if (m_video_stereo_mode == RENDER_STEREO_MODE_SPLIT_HORIZONTAL)
region.transform = (MMAL_DISPLAYTRANSFORM_T)(region.transform | DISPMANX_STEREOSCOPIC_TB);
else if (m_video_stereo_mode == RENDER_STEREO_MODE_SPLIT_VERTICAL)
region.transform = (MMAL_DISPLAYTRANSFORM_T)(region.transform | DISPMANX_STEREOSCOPIC_SBS);
else
region.mode = MMAL_DISPLAY_MODE_LETTERBOX;
region.transform = (MMAL_DISPLAYTRANSFORM_T)(region.transform | DISPMANX_STEREOSCOPIC_MONO);

if (m_StereoInvert)
region.transform = (MMAL_DISPLAYTRANSFORM_T)(region.transform | DISPMANX_STEREOSCOPIC_INVERT);

MMAL_STATUS_T status = mmal_util_set_display_region(m_vout_input, &region);
if (status != MMAL_SUCCESS)
CLog::Log(LOGERROR, "%s::%s Failed to set display region (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));

CLog::Log(LOGDEBUG, "%s::%s %d,%d,%d,%d -> %d,%d,%d,%d mode:%d", CLASSNAME, __func__,
CLog::Log(LOGDEBUG, "%s::%s %d,%d,%d,%d -> %d,%d,%d,%d t:%x", CLASSNAME, __func__,
region.src_rect.x, region.src_rect.y, region.src_rect.width, region.src_rect.height,
region.dest_rect.x, region.dest_rect.y, region.dest_rect.width, region.dest_rect.height, region.mode);
region.dest_rect.x, region.dest_rect.y, region.dest_rect.width, region.dest_rect.height, region.transform);
}
46 changes: 6 additions & 40 deletions xbmc/cores/omxplayer/OMXPlayerVideo.cpp
Expand Up @@ -641,9 +641,7 @@ int OMXPlayerVideo::GetFreeSpace()

void OMXPlayerVideo::SetVideoRect(const CRect &InSrcRect, const CRect &InDestRect)
{
// we get called twice a frame for left/right. Can ignore the rights.
if (g_graphicsContext.GetStereoView() == RENDER_STEREO_VIEW_RIGHT)
return;
assert(g_graphicsContext.GetStereoView() != RENDER_STEREO_VIEW_RIGHT);

CRect SrcRect = InSrcRect, DestRect = InDestRect;
unsigned flags = GetStereoModeFlags(GetStereoMode());
Expand Down Expand Up @@ -683,42 +681,10 @@ void OMXPlayerVideo::SetVideoRect(const CRect &InSrcRect, const CRect &InDestRec
CRect gui(0, 0, CDisplaySettings::GetInstance().GetResolutionInfo(res).iWidth, CDisplaySettings::GetInstance().GetResolutionInfo(res).iHeight);
CRect display(0, 0, CDisplaySettings::GetInstance().GetResolutionInfo(res).iScreenWidth, CDisplaySettings::GetInstance().GetResolutionInfo(res).iScreenHeight);

switch (video_stereo_mode)
{
case RENDER_STEREO_MODE_SPLIT_VERTICAL:
// optimisation - use simpler display mode in common case of unscaled 3d with same display mode
if (video_stereo_mode == display_stereo_mode && DestRect.x1 == 0.0f && DestRect.x2 * 2.0f == gui.Width() && !stereo_invert)
{
SrcRect.x2 *= 2.0f;
DestRect.x2 *= 2.0f;
video_stereo_mode = RENDER_STEREO_MODE_OFF;
display_stereo_mode = RENDER_STEREO_MODE_OFF;
}
else if (stereo_invert)
{
SrcRect.x1 += m_hints.width / 2;
SrcRect.x2 += m_hints.width / 2;
}
break;

case RENDER_STEREO_MODE_SPLIT_HORIZONTAL:
// optimisation - use simpler display mode in common case of unscaled 3d with same display mode
if (video_stereo_mode == display_stereo_mode && DestRect.y1 == 0.0f && DestRect.y2 * 2.0f == gui.Height() && !stereo_invert)
{
SrcRect.y2 *= 2.0f;
DestRect.y2 *= 2.0f;
video_stereo_mode = RENDER_STEREO_MODE_OFF;
display_stereo_mode = RENDER_STEREO_MODE_OFF;
}
else if (stereo_invert)
{
SrcRect.y1 += m_hints.height / 2;
SrcRect.y2 += m_hints.height / 2;
}
break;

default: break;
}
if (display_stereo_mode == RENDER_STEREO_MODE_SPLIT_VERTICAL)
DestRect.x2 *= 2.0f;
else if (display_stereo_mode == RENDER_STEREO_MODE_SPLIT_HORIZONTAL)
DestRect.y2 *= 2.0f;

if (gui != display)
{
Expand All @@ -729,7 +695,7 @@ void OMXPlayerVideo::SetVideoRect(const CRect &InSrcRect, const CRect &InDestRec
DestRect.y1 *= yscale;
DestRect.y2 *= yscale;
}
m_omxVideo.SetVideoRect(SrcRect, DestRect, video_stereo_mode, display_stereo_mode);
m_omxVideo.SetVideoRect(SrcRect, DestRect, m_video_stereo_mode, m_display_stereo_mode, m_StereoInvert);
}

void OMXPlayerVideo::RenderUpdateCallBack(const void *ctx, const CRect &SrcRect, const CRect &DestRect)
Expand Down
36 changes: 14 additions & 22 deletions xbmc/cores/omxplayer/OMXVideo.cpp
Expand Up @@ -221,15 +221,6 @@ bool COMXVideo::PortSettingsChanged()
OMX_INIT_STRUCTURE(configDisplay);
configDisplay.nPortIndex = m_omx_render.GetInputPort();

configDisplay.set = OMX_DISPLAY_SET_TRANSFORM;
configDisplay.transform = m_transform;
omx_err = m_omx_render.SetConfig(OMX_IndexConfigDisplayRegion, &configDisplay);
if(omx_err != OMX_ErrorNone)
{
CLog::Log(LOGWARNING, "%s::%s - could not set transform : %d", CLASSNAME, __func__, m_transform);
return false;
}

if(m_hdmi_clock_sync)
{
OMX_CONFIG_LATENCYTARGETTYPE latencyTarget;
Expand Down Expand Up @@ -848,7 +839,7 @@ void COMXVideo::Reset(void)
}

///////////////////////////////////////////////////////////////////////////////////////////
void COMXVideo::SetVideoRect(const CRect& SrcRect, const CRect& DestRect, RENDER_STEREO_MODE video_mode, RENDER_STEREO_MODE display_mode)
void COMXVideo::SetVideoRect(const CRect& SrcRect, const CRect& DestRect, RENDER_STEREO_MODE video_mode, RENDER_STEREO_MODE display_mode, bool stereo_invert)
{
CSingleLock lock (m_critSection);
if(!m_is_open)
Expand All @@ -858,7 +849,7 @@ void COMXVideo::SetVideoRect(const CRect& SrcRect, const CRect& DestRect, RENDER

OMX_INIT_STRUCTURE(configDisplay);
configDisplay.nPortIndex = m_omx_render.GetInputPort();
configDisplay.set = (OMX_DISPLAYSETTYPE)(OMX_DISPLAY_SET_DEST_RECT|OMX_DISPLAY_SET_SRC_RECT|OMX_DISPLAY_SET_FULLSCREEN|OMX_DISPLAY_SET_NOASPECT|OMX_DISPLAY_SET_MODE);
configDisplay.set = (OMX_DISPLAYSETTYPE)(OMX_DISPLAY_SET_DEST_RECT|OMX_DISPLAY_SET_SRC_RECT|OMX_DISPLAY_SET_FULLSCREEN|OMX_DISPLAY_SET_NOASPECT|OMX_DISPLAY_SET_MODE|OMX_DISPLAY_SET_TRANSFORM);
configDisplay.dest_rect.x_offset = lrintf(DestRect.x1);
configDisplay.dest_rect.y_offset = lrintf(DestRect.y1);
configDisplay.dest_rect.width = lrintf(DestRect.Width());
Expand All @@ -871,23 +862,24 @@ void COMXVideo::SetVideoRect(const CRect& SrcRect, const CRect& DestRect, RENDER

configDisplay.fullscreen = OMX_FALSE;
configDisplay.noaspect = OMX_TRUE;
configDisplay.mode = OMX_DISPLAY_MODE_LETTERBOX;
configDisplay.transform = m_transform;

if (video_mode == RENDER_STEREO_MODE_SPLIT_HORIZONTAL && display_mode == RENDER_STEREO_MODE_SPLIT_HORIZONTAL)
configDisplay.mode = OMX_DISPLAY_MODE_STEREO_TOP_TO_TOP;
else if (video_mode == RENDER_STEREO_MODE_SPLIT_HORIZONTAL && display_mode == RENDER_STEREO_MODE_SPLIT_VERTICAL)
configDisplay.mode = OMX_DISPLAY_MODE_STEREO_TOP_TO_LEFT;
else if (video_mode == RENDER_STEREO_MODE_SPLIT_VERTICAL && display_mode == RENDER_STEREO_MODE_SPLIT_HORIZONTAL)
configDisplay.mode = OMX_DISPLAY_MODE_STEREO_LEFT_TO_TOP;
else if (video_mode == RENDER_STEREO_MODE_SPLIT_VERTICAL && display_mode == RENDER_STEREO_MODE_SPLIT_VERTICAL)
configDisplay.mode = OMX_DISPLAY_MODE_STEREO_LEFT_TO_LEFT;
if (video_mode == RENDER_STEREO_MODE_SPLIT_HORIZONTAL)
configDisplay.transform = (OMX_DISPLAYTRANSFORMTYPE)(configDisplay.transform | DISPMANX_STEREOSCOPIC_TB);
else if (video_mode == RENDER_STEREO_MODE_SPLIT_VERTICAL)
configDisplay.transform = (OMX_DISPLAYTRANSFORMTYPE)(configDisplay.transform | DISPMANX_STEREOSCOPIC_SBS);
else
configDisplay.mode = OMX_DISPLAY_MODE_LETTERBOX;
configDisplay.transform = (OMX_DISPLAYTRANSFORMTYPE)(configDisplay.transform | DISPMANX_STEREOSCOPIC_MONO);

if (stereo_invert)
configDisplay.transform = (OMX_DISPLAYTRANSFORMTYPE)(configDisplay.transform | DISPMANX_STEREOSCOPIC_INVERT);

m_omx_render.SetConfig(OMX_IndexConfigDisplayRegion, &configDisplay);

CLog::Log(LOGDEBUG, "%s::%s %d,%d,%d,%d -> %d,%d,%d,%d mode:%d", CLASSNAME, __func__,
CLog::Log(LOGDEBUG, "%s::%s %d,%d,%d,%d -> %d,%d,%d,%d t:%x", CLASSNAME, __func__,
configDisplay.src_rect.x_offset, configDisplay.src_rect.y_offset, configDisplay.src_rect.width, configDisplay.src_rect.height,
configDisplay.dest_rect.x_offset, configDisplay.dest_rect.y_offset, configDisplay.dest_rect.width, configDisplay.dest_rect.height, configDisplay.mode);
configDisplay.dest_rect.x_offset, configDisplay.dest_rect.y_offset, configDisplay.dest_rect.width, configDisplay.dest_rect.height, configDisplay.transform);
}

int COMXVideo::GetInputBufferSize()
Expand Down
2 changes: 1 addition & 1 deletion xbmc/cores/omxplayer/OMXVideo.h
Expand Up @@ -60,7 +60,7 @@ class COMXVideo
void Reset(void);
void SetDropState(bool bDrop);
std::string GetDecoderName() { return m_video_codec_name; };
void SetVideoRect(const CRect& SrcRect, const CRect& DestRect, RENDER_STEREO_MODE video_mode, RENDER_STEREO_MODE display_mode);
void SetVideoRect(const CRect& SrcRect, const CRect& DestRect, RENDER_STEREO_MODE video_mode, RENDER_STEREO_MODE display_mode, bool stereo_invert);
int GetInputBufferSize();
bool GetPlayerInfo(double &match, double &phase, double &pll);
void SubmitEOS();
Expand Down
11 changes: 10 additions & 1 deletion xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp
Expand Up @@ -283,7 +283,9 @@ bool CEGLNativeTypeRaspberryPI::SetNativeResolution(const RESOLUTION_INFO &res)
/* inform TV of any 3D settings. Note this property just applies to next hdmi mode change, so no need to call for 2D modes */
HDMI_PROPERTY_PARAM_T property;
property.property = HDMI_PROPERTY_3D_STRUCTURE;
if (res.dwFlags & D3DPRESENTFLAG_MODE3DSBS)
if (CSettings::GetInstance().GetBool("videoplayer.framepacking") && CSettings::GetInstance().GetBool("videoplayer.supportmvc"))
property.param1 = HDMI_3D_FORMAT_FRAME_PACKING;
else if (res.dwFlags & D3DPRESENTFLAG_MODE3DSBS)
property.param1 = HDMI_3D_FORMAT_SBS_HALF;
else if (res.dwFlags & D3DPRESENTFLAG_MODE3DTB)
property.param1 = HDMI_3D_FORMAT_TB_HALF;
Expand Down Expand Up @@ -383,6 +385,13 @@ bool CEGLNativeTypeRaspberryPI::SetNativeResolution(const RESOLUTION_INFO &res)
DISPMANX_TRANSFORM_T transform = DISPMANX_NO_ROTATE;
DISPMANX_UPDATE_HANDLE_T dispman_update = m_DllBcmHost->vc_dispmanx_update_start(0);

if (res.dwFlags & D3DPRESENTFLAG_MODE3DSBS)
transform = DISPMANX_STEREOSCOPIC_SBS;
else if (res.dwFlags & D3DPRESENTFLAG_MODE3DTB)
transform = DISPMANX_STEREOSCOPIC_TB;
else
transform = DISPMANX_STEREOSCOPIC_MONO;

CLog::Log(LOGDEBUG, "EGL set resolution %dx%d -> %dx%d @ %.2f fps (%d,%d) flags:%x aspect:%.2f\n",
m_width, m_height, dst_rect.width, dst_rect.height, res.fRefreshRate, GETFLAGS_GROUP(res.dwFlags), GETFLAGS_MODE(res.dwFlags), (int)res.dwFlags, res.fPixelRatio);

Expand Down

0 comments on commit 50a94e5

Please sign in to comment.