Skip to content
This repository

[gl/renderer] - pass the video orientation down to the gl renderer and... #1144

Merged
merged 4 commits into from almost 2 years ago

3 participants

Memphiz Joakim Plate davilla
Memphiz
Owner

...rotate the video texture accordingly.

This is not complete. Its for getting some feedback from more experienced devs. Its ment to finally close the trac ticket http://trac.xbmc.org/ticket/12231

  1. This only implements rotation for OpenGL - i know. But i'm unsure if everything is right here. It crashs when using the Software Renderer (during libswscale) - i have no clue why this could happen.

  2. I didn't get the knot out of my brain for reordering the points for GLES - there we use triangles and i just have not a freaken idea how to handle it correctly there.

  3. All the GL HW Renderers are adapted blindly.

All in all i'm more then unsure with this stuff and hope someone can guide me.

Memphiz
Owner

Ok updated once more. I decided the following approach

  1. Use CPoint[4]
  2. Leave m_destRect untouched
  3. Let the baseclass do the rotation - with option of overwriting in e.x. gles renderer (still no solution there with the triangle points)

I also adapted the winrenderer.

Its still assuming that pixels are square. Any hint on how to get the pixel aspect ratio?

Furthermore its still crashing when using gl software rendering (guess what - its swscale again - but a different thing this time - i have the feeling the cachedcontext stuff might be wonky).

Memphiz
Owner

Successfully tested so far:

OSX: all renderings working, beside software rendering is crashing in swscale - VDA needs testing (don't have a mashine with VDA support)
Linux: all renderings are working including software rendering (no crash in swscale here - strange) and VDPAU
Windows: to be tested in software rendering (no DXVA support - maybe someone could give hints?)
GLES: to be implemented

If anyone wants to test - i have orientated movies in my folder on the teamftp...

Memphiz
Owner

Ok - sorted the gles orientation aswell.

Works with VTB and GLSL singlepass (no other settings available on ios).

Untested is OpenMax (should work ^^).
Untested aswell multipass (which isn't even hooked up in gles renderer) and software modes - no clue which devices with gles support these.

Memphiz
Owner

Once again windows is completly different. Rotation works with Software rendering, but doesn't with Pixel Shader or DXVA setting.

I was not able to figure out an easy way howto rotate on render with these 2 settings. @elupus do you have any idea how we can make windows working?

If not i'm willing to merge this someday even if video rotation is not working on all our renderers.

Joakim Plate
Collaborator
elupus commented

Not really no. DXVA probably have something built in to do it. But can't say i know how. For pixelshader case it aught to be in CYUV2RGBShader::PrepareParameters WinShaders.cpp

Memphiz
Owner

Ok thx @elupus added rotation for pixel shader rendering on windows (and tested briefly).

davilla
Collaborator

tested working under VDA (nvidia) on osx for all four orientation test files.

Memphiz
Owner

thx davilla for the test. So the only things which are untested are vaapi and omxplayer. But the fact that all others worked and the approach is the same on all of these i think they will just work.[tm]

So if any one could give a hint on how to determine the pixel aspect ratio i could take it into account in the calculation.

The question is if the autorotation of videos should be an option like we have for pictures already?

Memphiz
Owner

Ok i have added an optimisation so that the draw points are only recalculated if either destrect or orientation changes (before it was calculated on each frame).

Beside that i added a new Renderfeature RENDERFEATURE_ROTATION to the renderers and use this to determine if the renderer supports rotating the video.

I also added a new filter FILTER_ROTATE to the codecs.

If the renderer doesn't support rotation the filter will be set in the codec instead. For FFMPEG codec i have implemented support for this filter already.

This fixes rotation when rendering with DXVA under windows. Though this still doesn't work when hardware decoding is enabled and the renderer doesn't support orientation (so to say - it doesn't work for DXVA2 hw decoding).

Am i still on track guys? ;)

Not much more todo imho. Basically every constellation on every platform should be able to handle videos with orientation with this PR, but windows with dxva2 hw doesn't.

I've also tested VAAPI - though my test movies didn't get decoded with it, i can confirm that normal oriented movies are still working with VAAPI ;)

Memphiz
Owner

@jmarshallnz i guess i found out that i can get the pixel aspect ratio by using g_graphicsContext.GetScalingPixelRatio(); ... but i don't get how to apply it to that diff value. I bet you know :)

Memphiz added some commits
Memphiz Memphiz [gl/gles/win/renderer] - pass the video orientation down to the gl re…
…nderer and rotate the video texture accordingly, this handles linuxgl (software, vaapi, vdpau, vda), linuxgles (software, vtb) and windows gl renderers (all except DXVA2 hw decoder) - fixes #12231
048cd71
Memphiz Memphiz [baserenderer] - make Supports(ERENDERFEATURE) a virtual member of ba…
…serenderer (defaulting to return false)

- add RENDERFEATURE_ROTATION
- in BaseRenderer if the renderer doesn't support RENDERFEATURE_ROTATION - don't rotate the draw points but treat it as 0 degree rotation
3a9510a
Memphiz Memphiz [renderers] - GL, GLES support RENDERFEATURE_ROTATION for all renderm…
…ethods, windows for all but DXVA rendering
b2dd54e
Memphiz Memphiz [filter] - add a new codec filter FILTER_ROTATE, in dvdplayervideo pr…
…ocess if the renderer doesn't support rotation - set FILTER_ROTATE in codec flags

- for DVDVideoCodecFFmpeg use ffmpeg filters to rotate video based on the orientation hint when FILTER_ROTATE filter is set
ab6f1fd
Memphiz Memphiz merged commit 99f7407 into from
Memphiz Memphiz closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 4 unique commits by 1 author.

Aug 01, 2012
Memphiz Memphiz [gl/gles/win/renderer] - pass the video orientation down to the gl re…
…nderer and rotate the video texture accordingly, this handles linuxgl (software, vaapi, vdpau, vda), linuxgles (software, vtb) and windows gl renderers (all except DXVA2 hw decoder) - fixes #12231
048cd71
Memphiz Memphiz [baserenderer] - make Supports(ERENDERFEATURE) a virtual member of ba…
…serenderer (defaulting to return false)

- add RENDERFEATURE_ROTATION
- in BaseRenderer if the renderer doesn't support RENDERFEATURE_ROTATION - don't rotate the draw points but treat it as 0 degree rotation
3a9510a
Memphiz Memphiz [renderers] - GL, GLES support RENDERFEATURE_ROTATION for all renderm…
…ethods, windows for all but DXVA rendering
b2dd54e
Memphiz Memphiz [filter] - add a new codec filter FILTER_ROTATE, in dvdplayervideo pr…
…ocess if the renderer doesn't support rotation - set FILTER_ROTATE in codec flags

- for DVDVideoCodecFFmpeg use ffmpeg filters to rotate video based on the orientation hint when FILTER_ROTATE filter is set
ab6f1fd
This page is out of date. Refresh to see the latest.
85 xbmc/cores/VideoRenderers/BaseRenderer.cpp
@@ -38,6 +38,15 @@ CBaseRenderer::CBaseRenderer()
38 38 m_sourceHeight = 480;
39 39 m_resolution = RES_DESKTOP;
40 40 m_fps = 0.0f;
  41 + m_renderOrientation = 0;
  42 + m_oldRenderOrientation = 0;
  43 + m_oldDestRect.SetRect(0.0f, 0.0f, 0.0f, 0.0f);
  44 +
  45 + for(int i=0; i < 4; i++)
  46 + {
  47 + m_rotatedDestCoords[i].x = 0;
  48 + m_rotatedDestCoords[i].y = 0;
  49 + }
41 50 }
42 51
43 52 CBaseRenderer::~CBaseRenderer()
@@ -232,6 +241,73 @@ void CBaseRenderer::GetVideoRect(CRect &source, CRect &dest)
232 241 dest = m_destRect;
233 242 }
234 243
  244 +inline void CBaseRenderer::ReorderDrawPoints()
  245 +{
  246 + // 0 - top left, 1 - top right, 2 - bottom right, 3 - bottom left
  247 + float origMat[4][2] = {{m_destRect.x1, m_destRect.y1},
  248 + {m_destRect.x2, m_destRect.y1},
  249 + {m_destRect.x2, m_destRect.y2},
  250 + {m_destRect.x1, m_destRect.y2}};
  251 + bool changeAspect = false;
  252 + int pointOffset = 0;
  253 +
  254 + switch (m_renderOrientation)
  255 + {
  256 + case 90:
  257 + pointOffset = 1;
  258 + changeAspect = true;
  259 + break;
  260 + case 180:
  261 + pointOffset = 2;
  262 + break;
  263 + case 270:
  264 + pointOffset = 3;
  265 + changeAspect = true;
  266 + break;
  267 + }
  268 +
  269 + // if renderer doesn't support rotation
  270 + // treat orientation as 0 degree so that
  271 + // ffmpeg might handle it.
  272 + if (!Supports(RENDERFEATURE_ROTATION))
  273 + {
  274 + pointOffset = 0;
  275 + changeAspect = false;
  276 + }
  277 +
  278 +
  279 + int diff = (m_destRect.Height() - m_destRect.Width()) / 2;
  280 +
  281 + for (int destIdx=0, srcIdx=pointOffset; destIdx < 4; destIdx++, srcIdx = ++srcIdx % 4)
  282 + {
  283 + m_rotatedDestCoords[destIdx].x = origMat[srcIdx][0];
  284 + m_rotatedDestCoords[destIdx].y = origMat[srcIdx][1];
  285 +
  286 + if (changeAspect)
  287 + {
  288 + switch (srcIdx)
  289 + {
  290 + case 0:
  291 + m_rotatedDestCoords[destIdx].x -= diff;
  292 + m_rotatedDestCoords[destIdx].y += diff;
  293 + break;
  294 + case 1:
  295 + m_rotatedDestCoords[destIdx].x += diff;
  296 + m_rotatedDestCoords[destIdx].y += diff;
  297 + break;
  298 + case 2:
  299 + m_rotatedDestCoords[destIdx].x += diff;
  300 + m_rotatedDestCoords[destIdx].y -= diff;
  301 + break;
  302 + case 3:
  303 + m_rotatedDestCoords[destIdx].x -= diff;
  304 + m_rotatedDestCoords[destIdx].y -= diff;
  305 + break;
  306 + }
  307 + }
  308 + }
  309 +}
  310 +
235 311 void CBaseRenderer::CalcNormalDisplayRect(float offsetX, float offsetY, float screenWidth, float screenHeight, float inputFrameRatio, float zoomAmount, float verticalShift)
236 312 {
237 313 // if view window is empty, set empty destination
@@ -308,6 +384,15 @@ void CBaseRenderer::CalcNormalDisplayRect(float offsetX, float offsetY, float sc
308 384 m_sourceRect.y2 += (m_destRect.y2 - original.y2) * scaleY;
309 385 }
310 386 }
  387 +
  388 + if (m_oldDestRect != m_destRect || m_oldRenderOrientation != m_renderOrientation)
  389 + {
  390 + // adapt the drawing rect points if we have to rotate
  391 + // and either destrect or orientation changed
  392 + ReorderDrawPoints();
  393 + m_oldDestRect = m_destRect;
  394 + m_oldRenderOrientation = m_renderOrientation;
  395 + }
311 396 }
312 397
313 398 //***************************************************************************************
15 xbmc/cores/VideoRenderers/BaseRenderer.h
@@ -56,7 +56,8 @@ enum ERENDERFEATURE
56 56 RENDERFEATURE_CONTRAST,
57 57 RENDERFEATURE_NOISE,
58 58 RENDERFEATURE_SHARPNESS,
59   - RENDERFEATURE_NONLINSTRETCH
  59 + RENDERFEATURE_NONLINSTRETCH,
  60 + RENDERFEATURE_ROTATION
60 61 };
61 62
62 63 struct DVDVideoPicture;
@@ -77,6 +78,8 @@ class CBaseRenderer
77 78
78 79 virtual unsigned int GetProcessorSize() { return 0; }
79 80
  81 + virtual bool Supports(ERENDERFEATURE feature) { return false; }
  82 +
80 83 // Supported pixel formats, can be called before configure
81 84 std::vector<ERenderFormat> SupportedFormats() { return std::vector<ERenderFormat>(); }
82 85
@@ -90,12 +93,22 @@ class CBaseRenderer
90 93 void CalculateFrameAspectRatio(unsigned int desired_width, unsigned int desired_height);
91 94 void ManageDisplay();
92 95
  96 + virtual void ReorderDrawPoints();//might be overwritten (by egl e.x.)
  97 +
93 98 RESOLUTION m_resolution; // the resolution we're running in
94 99 unsigned int m_sourceWidth;
95 100 unsigned int m_sourceHeight;
96 101 float m_sourceFrameRatio;
97 102 float m_fps;
98 103
  104 + unsigned int m_renderOrientation; // orientation of the video in degress counter clockwise
  105 + unsigned int m_oldRenderOrientation; // orientation of the previous frame
  106 + // for drawing the texture with glVertex4f (holds all 4 corner points of the destination rect
  107 + // with correct orientation based on m_renderOrientation
  108 + // 0 - top left, 1 - top right, 2 - bottom right, 3 - bottom left
  109 + CPoint m_rotatedDestCoords[4];
  110 +
99 111 CRect m_destRect;
  112 + CRect m_oldDestRect; // destrect of the previous frame
100 113 CRect m_sourceRect;
101 114 };
93 xbmc/cores/VideoRenderers/LinuxRendererGL.cpp
@@ -267,10 +267,11 @@ bool CLinuxRendererGL::ValidateRenderTarget()
267 267 return false;
268 268 }
269 269
270   -bool CLinuxRendererGL::Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_format)
  270 +bool CLinuxRendererGL::Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_format, unsigned int orientation)
271 271 {
272 272 m_sourceWidth = width;
273 273 m_sourceHeight = height;
  274 + m_renderOrientation = orientation;
274 275 m_fps = fps;
275 276
276 277 // Save the flags.
@@ -698,39 +699,39 @@ void CLinuxRendererGL::DrawBlackBars()
698 699 glBegin(GL_QUADS);
699 700
700 701 //top quad
701   - if (m_destRect.y1 > 0.0)
  702 + if (m_rotatedDestCoords[0].y > 0.0)
702 703 {
703   - glVertex4f(0.0, 0.0, 0.0, 1.0);
704   - glVertex4f(g_graphicsContext.GetWidth(), 0.0, 0.0, 1.0);
705   - glVertex4f(g_graphicsContext.GetWidth(), m_destRect.y1, 0.0, 1.0);
706   - glVertex4f(0.0, m_destRect.y1, 0.0, 1.0);
  704 + glVertex4f(0.0, 0.0, 0.0, 1.0);
  705 + glVertex4f(g_graphicsContext.GetWidth(), 0.0, 0.0, 1.0);
  706 + glVertex4f(g_graphicsContext.GetWidth(), m_rotatedDestCoords[0].y, 0.0, 1.0);
  707 + glVertex4f(0.0, m_rotatedDestCoords[0].y, 0.0, 1.0);
707 708 }
708 709
709 710 //bottom quad
710   - if (m_destRect.y2 < g_graphicsContext.GetHeight())
  711 + if (m_rotatedDestCoords[2].y < g_graphicsContext.GetHeight())
711 712 {
712   - glVertex4f(0.0, m_destRect.y2, 0.0, 1.0);
713   - glVertex4f(g_graphicsContext.GetWidth(), m_destRect.y2, 0.0, 1.0);
  713 + glVertex4f(0.0, m_rotatedDestCoords[2].y, 0.0, 1.0);
  714 + glVertex4f(g_graphicsContext.GetWidth(), m_rotatedDestCoords[2].y, 0.0, 1.0);
714 715 glVertex4f(g_graphicsContext.GetWidth(), g_graphicsContext.GetHeight(), 0.0, 1.0);
715 716 glVertex4f(0.0, g_graphicsContext.GetHeight(), 0.0, 1.0);
716 717 }
717 718
718 719 //left quad
719   - if (m_destRect.x1 > 0.0)
  720 + if (m_rotatedDestCoords[0].x > 0.0)
720 721 {
721   - glVertex4f(0.0, m_destRect.y1, 0.0, 1.0);
722   - glVertex4f(m_destRect.x1, m_destRect.y1, 0.0, 1.0);
723   - glVertex4f(m_destRect.x1, m_destRect.y2, 0.0, 1.0);
724   - glVertex4f(0.0, m_destRect.y2, 0.0, 1.0);
  722 + glVertex4f(0.0, m_rotatedDestCoords[0].y, 0.0, 1.0);
  723 + glVertex4f(m_rotatedDestCoords[0].x, m_rotatedDestCoords[0].y, 0.0, 1.0);
  724 + glVertex4f(m_rotatedDestCoords[0].x, m_rotatedDestCoords[2].y, 0.0, 1.0);
  725 + glVertex4f(0.0, m_rotatedDestCoords[2].y, 0.0, 1.0);
725 726 }
726 727
727 728 //right quad
728   - if (m_destRect.x2 < g_graphicsContext.GetWidth())
  729 + if (m_rotatedDestCoords[2].x < g_graphicsContext.GetWidth())
729 730 {
730   - glVertex4f(m_destRect.x2, m_destRect.y1, 0.0, 1.0);
731   - glVertex4f(g_graphicsContext.GetWidth(), m_destRect.y1, 0.0, 1.0);
732   - glVertex4f(g_graphicsContext.GetWidth(), m_destRect.y2, 0.0, 1.0);
733   - glVertex4f(m_destRect.x2, m_destRect.y2, 0.0, 1.0);
  731 + glVertex4f(m_rotatedDestCoords[2].x, m_rotatedDestCoords[0].y, 0.0, 1.0);
  732 + glVertex4f(g_graphicsContext.GetWidth(), m_rotatedDestCoords[0].y, 0.0, 1.0);
  733 + glVertex4f(g_graphicsContext.GetWidth(), m_rotatedDestCoords[2].y, 0.0, 1.0);
  734 + glVertex4f(m_rotatedDestCoords[2].x, m_rotatedDestCoords[2].y, 0.0, 1.0);
734 735 }
735 736
736 737 glEnd();
@@ -1258,22 +1259,22 @@ void CLinuxRendererGL::RenderSinglePass(int index, int field)
1258 1259 glMultiTexCoord2fARB(GL_TEXTURE0, planes[0].rect.x1, planes[0].rect.y1);
1259 1260 glMultiTexCoord2fARB(GL_TEXTURE1, planes[1].rect.x1, planes[1].rect.y1);
1260 1261 glMultiTexCoord2fARB(GL_TEXTURE2, planes[2].rect.x1, planes[2].rect.y1);
1261   - glVertex4f(m_destRect.x1, m_destRect.y1, 0, 1.0f );
  1262 + glVertex4f(m_rotatedDestCoords[0].x, m_rotatedDestCoords[0].y, 0, 1.0f );//top left
1262 1263
1263 1264 glMultiTexCoord2fARB(GL_TEXTURE0, planes[0].rect.x2, planes[0].rect.y1);
1264 1265 glMultiTexCoord2fARB(GL_TEXTURE1, planes[1].rect.x2, planes[1].rect.y1);
1265 1266 glMultiTexCoord2fARB(GL_TEXTURE2, planes[2].rect.x2, planes[2].rect.y1);
1266   - glVertex4f(m_destRect.x2, m_destRect.y1, 0, 1.0f);
  1267 + glVertex4f(m_rotatedDestCoords[1].x, m_rotatedDestCoords[1].y, 0, 1.0f );//top right
1267 1268
1268 1269 glMultiTexCoord2fARB(GL_TEXTURE0, planes[0].rect.x2, planes[0].rect.y2);
1269 1270 glMultiTexCoord2fARB(GL_TEXTURE1, planes[1].rect.x2, planes[1].rect.y2);
1270 1271 glMultiTexCoord2fARB(GL_TEXTURE2, planes[2].rect.x2, planes[2].rect.y2);
1271   - glVertex4f(m_destRect.x2, m_destRect.y2, 0, 1.0f);
  1272 + glVertex4f(m_rotatedDestCoords[2].x, m_rotatedDestCoords[2].y, 0, 1.0f );//bottom right
1272 1273
1273 1274 glMultiTexCoord2fARB(GL_TEXTURE0, planes[0].rect.x1, planes[0].rect.y2);
1274 1275 glMultiTexCoord2fARB(GL_TEXTURE1, planes[1].rect.x1, planes[1].rect.y2);
1275 1276 glMultiTexCoord2fARB(GL_TEXTURE2, planes[2].rect.x1, planes[2].rect.y2);
1276   - glVertex4f(m_destRect.x1, m_destRect.y2, 0, 1.0f);
  1277 + glVertex4f(m_rotatedDestCoords[3].x, m_rotatedDestCoords[3].y, 0, 1.0f );//bottom left
1277 1278
1278 1279 glEnd();
1279 1280 VerifyGLState();
@@ -1471,16 +1472,16 @@ void CLinuxRendererGL::RenderMultiPass(int index, int field)
1471 1472 glBegin(GL_QUADS);
1472 1473
1473 1474 glMultiTexCoord2fARB(GL_TEXTURE0, 0.0f , 0.0f);
1474   - glVertex4f(m_destRect.x1, m_destRect.y1, 0, 1.0f );
  1475 + glVertex4f(m_rotatedDestCoords[0].x, m_rotatedDestCoords[0].y, 0, 1.0f );
1475 1476
1476 1477 glMultiTexCoord2fARB(GL_TEXTURE0, imgwidth, 0.0f);
1477   - glVertex4f(m_destRect.x2, m_destRect.y1, 0, 1.0f);
  1478 + glVertex4f(m_rotatedDestCoords[1].x, m_rotatedDestCoords[1].y, 0, 1.0f );
1478 1479
1479 1480 glMultiTexCoord2fARB(GL_TEXTURE0, imgwidth, imgheight);
1480   - glVertex4f(m_destRect.x2, m_destRect.y2, 0, 1.0f);
1481   -
  1481 + glVertex4f(m_rotatedDestCoords[2].x, m_rotatedDestCoords[2].y, 0, 1.0f );
  1482 +
1482 1483 glMultiTexCoord2fARB(GL_TEXTURE0, 0.0f , imgheight);
1483   - glVertex4f(m_destRect.x1, m_destRect.y2, 0, 1.0f);
  1484 + glVertex4f(m_rotatedDestCoords[3].x, m_rotatedDestCoords[3].y, 0, 1.0f );
1484 1485
1485 1486 glEnd();
1486 1487
@@ -1548,17 +1549,17 @@ void CLinuxRendererGL::RenderVDPAU(int index, int field)
1548 1549 glBegin(GL_QUADS);
1549 1550 if (m_textureTarget==GL_TEXTURE_2D)
1550 1551 {
1551   - glTexCoord2f(0.0, 0.0); glVertex2f(m_destRect.x1, m_destRect.y1);
1552   - glTexCoord2f(1.0, 0.0); glVertex2f(m_destRect.x2, m_destRect.y1);
1553   - glTexCoord2f(1.0, 1.0); glVertex2f(m_destRect.x2, m_destRect.y2);
1554   - glTexCoord2f(0.0, 1.0); glVertex2f(m_destRect.x1, m_destRect.y2);
  1552 + glTexCoord2f(0.0, 0.0); glVertex2f(m_rotatedDestCoords[0].x, m_rotatedDestCoords[0].y);
  1553 + glTexCoord2f(1.0, 0.0); glVertex2f(m_rotatedDestCoords[1].x, m_rotatedDestCoords[1].y);
  1554 + glTexCoord2f(1.0, 1.0); glVertex2f(m_rotatedDestCoords[2].x, m_rotatedDestCoords[2].y);
  1555 + glTexCoord2f(0.0, 1.0); glVertex2f(m_rotatedDestCoords[3].x, m_rotatedDestCoords[3].y);
1555 1556 }
1556 1557 else
1557 1558 {
1558   - glTexCoord2f(m_destRect.x1, m_destRect.y1); glVertex4f(m_destRect.x1, m_destRect.y1, 0.0f, 0.0f);
1559   - glTexCoord2f(m_destRect.x2, m_destRect.y1); glVertex4f(m_destRect.x2, m_destRect.y1, 1.0f, 0.0f);
1560   - glTexCoord2f(m_destRect.x2, m_destRect.y2); glVertex4f(m_destRect.x2, m_destRect.y2, 1.0f, 1.0f);
1561   - glTexCoord2f(m_destRect.x1, m_destRect.y2); glVertex4f(m_destRect.x1, m_destRect.y2, 0.0f, 1.0f);
  1559 + glTexCoord2f(m_rotatedDestCoords[0].x, m_rotatedDestCoords[0].y); glVertex4f(m_rotatedDestCoords[0].x, m_rotatedDestCoords[0].y, 0.0f, 0.0f);
  1560 + glTexCoord2f(m_rotatedDestCoords[1].x, m_rotatedDestCoords[1].y); glVertex4f(m_rotatedDestCoords[1].x, m_rotatedDestCoords[1].y, 1.0f, 0.0f);
  1561 + glTexCoord2f(m_rotatedDestCoords[2].x, m_rotatedDestCoords[2].y); glVertex4f(m_rotatedDestCoords[2].x, m_rotatedDestCoords[2].y, 1.0f, 1.0f);
  1562 + glTexCoord2f(m_rotatedDestCoords[3].x, m_rotatedDestCoords[3].y); glVertex4f(m_rotatedDestCoords[3].x, m_rotatedDestCoords[3].y, 0.0f, 1.0f);
1562 1563 }
1563 1564 glEnd();
1564 1565 VerifyGLState();
@@ -1637,10 +1638,10 @@ void CLinuxRendererGL::RenderVAAPI(int index, int field)
1637 1638 VerifyGLState();
1638 1639
1639 1640 glBegin(GL_QUADS);
1640   - glTexCoord2f(0.0, 0.0); glVertex2f(m_destRect.x1, m_destRect.y1);
1641   - glTexCoord2f(1.0, 0.0); glVertex2f(m_destRect.x2, m_destRect.y1);
1642   - glTexCoord2f(1.0, 1.0); glVertex2f(m_destRect.x2, m_destRect.y2);
1643   - glTexCoord2f(0.0, 1.0); glVertex2f(m_destRect.x1, m_destRect.y2);
  1641 + glTexCoord2f(0.0, 0.0); glVertex2f(m_rotatedDestCoords[0].x, m_rotatedDestCoords[0].y);
  1642 + glTexCoord2f(1.0, 0.0); glVertex2f(m_rotatedDestCoords[1].x, m_rotatedDestCoords[1].y);
  1643 + glTexCoord2f(1.0, 1.0); glVertex2f(m_rotatedDestCoords[2].x, m_rotatedDestCoords[2].y);
  1644 + glTexCoord2f(0.0, 1.0); glVertex2f(m_rotatedDestCoords[3].x, m_rotatedDestCoords[3].y);
1644 1645 glEnd();
1645 1646
1646 1647 VerifyGLState();
@@ -1676,16 +1677,16 @@ void CLinuxRendererGL::RenderSoftware(int index, int field)
1676 1677
1677 1678 glBegin(GL_QUADS);
1678 1679 glTexCoord2f(planes[0].rect.x1, planes[0].rect.y1);
1679   - glVertex4f(m_destRect.x1, m_destRect.y1, 0, 1.0f );
  1680 + glVertex4f(m_rotatedDestCoords[0].x, m_rotatedDestCoords[0].y, 0, 1.0f );
1680 1681
1681 1682 glTexCoord2f(planes[0].rect.x2, planes[0].rect.y1);
1682   - glVertex4f(m_destRect.x2, m_destRect.y1, 0, 1.0f);
  1683 + glVertex4f(m_rotatedDestCoords[1].x, m_rotatedDestCoords[1].y, 0, 1.0f);
1683 1684
1684 1685 glTexCoord2f(planes[0].rect.x2, planes[0].rect.y2);
1685   - glVertex4f(m_destRect.x2, m_destRect.y2, 0, 1.0f);
  1686 + glVertex4f(m_rotatedDestCoords[2].x, m_rotatedDestCoords[2].y, 0, 1.0f);
1686 1687
1687 1688 glTexCoord2f(planes[0].rect.x1, planes[0].rect.y2);
1688   - glVertex4f(m_destRect.x1, m_destRect.y2, 0, 1.0f);
  1689 + glVertex4f(m_rotatedDestCoords[3].x, m_rotatedDestCoords[3].y, 0, 1.0f);
1689 1690
1690 1691 glEnd();
1691 1692
@@ -2838,6 +2839,7 @@ void CLinuxRendererGL::ToRGBFrame(YV12Image* im, unsigned flipIndexPlane, unsign
2838 2839 im->width, im->height, srcFormat,
2839 2840 im->width, im->height, PIX_FMT_BGRA,
2840 2841 SWS_FAST_BILINEAR | SwScaleCPUFlags(), NULL, NULL, NULL);
  2842 +
2841 2843 uint8_t *dst[] = { m_rgbBuffer, 0, 0, 0 };
2842 2844 int dstStride[] = { m_sourceWidth * 4, 0, 0, 0 };
2843 2845 m_dllSwScale->sws_scale(m_context, src, srcStride, 0, im->height, dst, dstStride);
@@ -3160,6 +3162,9 @@ bool CLinuxRendererGL::Supports(ERENDERFEATURE feature)
3160 3162 return true;
3161 3163 }
3162 3164
  3165 + if (feature == RENDERFEATURE_ROTATION)
  3166 + return true;
  3167 +
3163 3168 return false;
3164 3169 }
3165 3170
4 xbmc/cores/VideoRenderers/LinuxRendererGL.h
@@ -130,7 +130,7 @@ class CLinuxRendererGL : public CBaseRenderer
130 130 bool RenderCapture(CRenderCapture* capture);
131 131
132 132 // Player functions
133   - virtual bool Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_format);
  133 + virtual bool Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_formatl, unsigned int orientation);
134 134 virtual bool IsConfigured() { return m_bConfigured; }
135 135 virtual int GetImage(YV12Image *image, int source = AUTOSOURCE, bool readonly = false);
136 136 virtual void ReleaseImage(int source, bool preserve = false);
@@ -235,7 +235,7 @@ class CLinuxRendererGL : public CBaseRenderer
235 235 unsigned short m_renderMethod;
236 236 RenderQuality m_renderQuality;
237 237 unsigned int m_flipindex; // just a counter to keep track of if a image has been uploaded
238   -
  238 +
239 239 // Raw data used by renderer
240 240 int m_currentField;
241 241 int m_reloadShaders;
79 xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp
@@ -158,10 +158,11 @@ bool CLinuxRendererGLES::ValidateRenderTarget()
158 158 return false;
159 159 }
160 160
161   -bool CLinuxRendererGLES::Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_format)
  161 +bool CLinuxRendererGLES::Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_format, unsigned int orientation)
162 162 {
163 163 m_sourceWidth = width;
164 164 m_sourceHeight = height;
  165 + m_renderOrientation = orientation;
165 166
166 167 // Save the flags.
167 168 m_iFlags = flags;
@@ -725,6 +726,24 @@ void CLinuxRendererGLES::UnInit()
725 726 m_bConfigured = false;
726 727 }
727 728
  729 +inline void CLinuxRendererGLES::ReorderDrawPoints()
  730 +{
  731 +
  732 + CBaseRenderer::ReorderDrawPoints();//call base impl. for rotating the points
  733 +
  734 + //corevideo is flipped in y
  735 + if(m_renderMethod & RENDER_CVREF)
  736 + {
  737 + CPoint tmp;
  738 + tmp = m_rotatedDestCoords[0];
  739 + m_rotatedDestCoords[0] = m_rotatedDestCoords[3];
  740 + m_rotatedDestCoords[3] = tmp;
  741 + tmp = m_rotatedDestCoords[1];
  742 + m_rotatedDestCoords[1] = m_rotatedDestCoords[2];
  743 + m_rotatedDestCoords[2] = tmp;
  744 + }
  745 +}
  746 +
728 747 void CLinuxRendererGLES::Render(DWORD flags, int index)
729 748 {
730 749 // If rendered directly by the hardware
@@ -846,11 +865,12 @@ void CLinuxRendererGLES::RenderSinglePass(int index, int field)
846 865 glEnableVertexAttribArray(Vloc);
847 866
848 867 // Setup vertex position values
849   - m_vert[0][0] = m_vert[3][0] = m_destRect.x1;
850   - m_vert[0][1] = m_vert[1][1] = m_destRect.y1;
851   - m_vert[1][0] = m_vert[2][0] = m_destRect.x2;
852   - m_vert[2][1] = m_vert[3][1] = m_destRect.y2;
853   - m_vert[0][2] = m_vert[1][2] = m_vert[2][2] = m_vert[3][2] = 0.0f;
  868 + for(int i = 0; i < 4; i++)
  869 + {
  870 + m_vert[i][0] = m_rotatedDestCoords[i].x;
  871 + m_vert[i][1] = m_rotatedDestCoords[i].y;
  872 + m_vert[i][2] = 0.0f;// set z to 0
  873 + }
854 874
855 875 // Setup texture coordinates
856 876 for (int i=0; i<3; i++)
@@ -1111,13 +1131,14 @@ void CLinuxRendererGLES::RenderSoftware(int index, int field)
1111 1131 glEnableVertexAttribArray(colLoc);
1112 1132
1113 1133 // Set vertex coordinates
1114   - ver[0][0] = ver[3][0] = m_destRect.x1;
1115   - ver[0][1] = ver[1][1] = m_destRect.y1;
1116   - ver[1][0] = ver[2][0] = m_destRect.x2;
1117   - ver[2][1] = ver[3][1] = m_destRect.y2;
1118   - ver[0][2] = ver[1][2] = ver[2][2] = ver[3][2] = 0.0f;
1119   - ver[0][3] = ver[1][3] = ver[2][3] = ver[3][3] = 1.0f;
1120   -
  1134 + for(int i = 0; i < 4; i++)
  1135 + {
  1136 + ver[i][0] = m_rotatedDestCoords[i].x;
  1137 + ver[i][1] = m_rotatedDestCoords[i].y;
  1138 + ver[i][2] = 0.0f;// set z to 0
  1139 + ver[i][3] = 1.0f;
  1140 + }
  1141 +
1121 1142 // Set texture coordinates
1122 1143 tex[0][0] = tex[3][0] = planes[0].rect.x1;
1123 1144 tex[0][1] = tex[1][1] = planes[0].rect.y1;
@@ -1175,12 +1196,13 @@ void CLinuxRendererGLES::RenderOpenMax(int index, int field)
1175 1196 glEnableVertexAttribArray(colLoc);
1176 1197
1177 1198 // Set vertex coordinates
1178   - ver[0][0] = ver[3][0] = m_destRect.x1;
1179   - ver[0][1] = ver[1][1] = m_destRect.y2;
1180   - ver[1][0] = ver[2][0] = m_destRect.x2;
1181   - ver[2][1] = ver[3][1] = m_destRect.y1;
1182   - ver[0][2] = ver[1][2] = ver[2][2] = ver[3][2] = 0.0f;
1183   - ver[0][3] = ver[1][3] = ver[2][3] = ver[3][3] = 1.0f;
  1199 + for(int i = 0; i < 4; i++)
  1200 + {
  1201 + ver[i][0] = m_rotatedDestCoords[i].x;
  1202 + ver[i][1] = m_rotatedDestCoords[i].y;
  1203 + ver[i][2] = 0.0f;// set z to 0
  1204 + ver[i][3] = 1.0f;
  1205 + }
1184 1206
1185 1207 // Set texture coordinates
1186 1208 tex[0][0] = tex[3][0] = 0;
@@ -1238,13 +1260,14 @@ void CLinuxRendererGLES::RenderCoreVideoRef(int index, int field)
1238 1260 glEnableVertexAttribArray(texLoc);
1239 1261 glEnableVertexAttribArray(colLoc);
1240 1262
1241   - // Set vertex coordinates
1242   - ver[0][0] = ver[3][0] = m_destRect.x1;
1243   - ver[0][1] = ver[1][1] = m_destRect.y2;
1244   - ver[1][0] = ver[2][0] = m_destRect.x2;
1245   - ver[2][1] = ver[3][1] = m_destRect.y1;
1246   - ver[0][2] = ver[1][2] = ver[2][2] = ver[3][2] = 0.0f;
1247   - ver[0][3] = ver[1][3] = ver[2][3] = ver[3][3] = 1.0f;
  1263 + // Set vertex coordinates
  1264 + for(int i = 0; i < 4; i++)
  1265 + {
  1266 + ver[i][0] = m_rotatedDestCoords[i].x;
  1267 + ver[i][1] = m_rotatedDestCoords[i].y;
  1268 + ver[i][2] = 0.0f;// set z to 0
  1269 + ver[i][3] = 1.0f;
  1270 + }
1248 1271
1249 1272 // Set texture coordinates (corevideo is flipped in y)
1250 1273 tex[0][0] = tex[3][0] = 0;
@@ -1798,6 +1821,9 @@ bool CLinuxRendererGLES::Supports(ERENDERFEATURE feature)
1798 1821 if (feature == RENDERFEATURE_NONLINSTRETCH)
1799 1822 return false;
1800 1823
  1824 + if (feature == RENDERFEATURE_ROTATION)
  1825 + return true;
  1826 +
1801 1827 return false;
1802 1828 }
1803 1829
@@ -1892,3 +1918,4 @@ void CLinuxRendererGLES::AddProcessor(struct __CVBuffer *cvBufferRef)
1892 1918
1893 1919
1894 1920 #endif
  1921 +
3  xbmc/cores/VideoRenderers/LinuxRendererGLES.h
@@ -129,7 +129,7 @@ class CLinuxRendererGLES : public CBaseRenderer
129 129 bool RenderCapture(CRenderCapture* capture);
130 130
131 131 // Player functions
132   - virtual bool Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_format);
  132 + virtual bool Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_formatunsigned, unsigned int orientation);
133 133 virtual bool IsConfigured() { return m_bConfigured; }
134 134 virtual int GetImage(YV12Image *image, int source = AUTOSOURCE, bool readonly = false);
135 135 virtual void ReleaseImage(int source, bool preserve = false);
@@ -137,6 +137,7 @@ class CLinuxRendererGLES : public CBaseRenderer
137 137 virtual unsigned int PreInit();
138 138 virtual void UnInit();
139 139 virtual void Reset(); /* resets renderer after seek for example */
  140 + virtual void ReorderDrawPoints();
140 141
141 142 virtual void RenderUpdate(bool clear, DWORD flags = 0, DWORD alpha = 255);
142 143
4 xbmc/cores/VideoRenderers/RenderManager.cpp
@@ -228,7 +228,7 @@ CStdString CXBMCRenderManager::GetVSyncState()
228 228 return state;
229 229 }
230 230
231   -bool CXBMCRenderManager::Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_format)
  231 +bool CXBMCRenderManager::Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_format, unsigned int orientation)
232 232 {
233 233 /* make sure any queued frame was fully presented */
234 234 double timeout = m_presenttime + 0.1;
@@ -248,7 +248,7 @@ bool CXBMCRenderManager::Configure(unsigned int width, unsigned int height, unsi
248 248 return false;
249 249 }
250 250
251   - bool result = m_pRenderer->Configure(width, height, d_width, d_height, fps, flags, format, extended_format);
  251 + bool result = m_pRenderer->Configure(width, height, d_width, d_height, fps, flags, format, extended_format, orientation);
252 252 if(result)
253 253 {
254 254 if( flags & CONF_FLAGS_FULLSCREEN )
2  xbmc/cores/VideoRenderers/RenderManager.h
@@ -66,7 +66,7 @@ class CXBMCRenderManager
66 66 void SetViewMode(int iViewMode);
67 67
68 68 // Functions called from mplayer
69   - bool Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_format);
  69 + bool Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_format, unsigned int orientation);
70 70 bool IsConfigured();
71 71
72 72 int AddVideoPicture(DVDVideoPicture& picture);
88 xbmc/cores/VideoRenderers/VideoShaders/WinVideoFilter.cpp
@@ -307,13 +307,13 @@ bool CYUV2RGBShader::Create(unsigned int sourceWidth, unsigned int sourceHeight,
307 307 return true;
308 308 }
309 309
310   -void CYUV2RGBShader::Render(CRect sourceRect, CRect destRect,
  310 +void CYUV2RGBShader::Render(CRect sourceRect, CPoint destPoints[4],
311 311 float contrast,
312 312 float brightness,
313 313 unsigned int flags,
314 314 YUVBuffer* YUVbuf)
315 315 {
316   - PrepareParameters(sourceRect, destRect,
  316 + PrepareParameters(sourceRect, destPoints,
317 317 contrast, brightness, flags);
318 318 UploadToGPU(YUVbuf);
319 319 SetShaderParameters(YUVbuf);
@@ -330,13 +330,18 @@ CYUV2RGBShader::~CYUV2RGBShader()
330 330 }
331 331
332 332 void CYUV2RGBShader::PrepareParameters(CRect sourceRect,
333   - CRect destRect,
  333 + CPoint destPoints[4],
334 334 float contrast,
335 335 float brightness,
336 336 unsigned int flags)
337 337 {
338 338 //See RGB renderer for comment on this
339 339 #define CHROMAOFFSET_HORIZ 0.25f
  340 + CRect destRect;
  341 + destRect.x1 = destPoints[0].x;
  342 + destRect.y1 = destPoints[0].y;
  343 + destRect.x2 = destPoints[2].x;
  344 + destRect.y2 = destPoints[2].y;
340 345
341 346 if (m_sourceRect != sourceRect || m_destRect != destRect)
342 347 {
@@ -346,34 +351,31 @@ void CYUV2RGBShader::PrepareParameters(CRect sourceRect,
346 351 CUSTOMVERTEX* v;
347 352 CWinShader::LockVertexBuffer((void**)&v);
348 353
349   - v[0].x = destRect.x1;
350   - v[0].y = destRect.y1;
  354 + for(int i = 0; i < 4; i++)
  355 + {
  356 + v[i].x = destPoints[i].x;
  357 + v[i].y = destPoints[i].y;
  358 + }
  359 +
351 360 v[0].tu = sourceRect.x1 / m_sourceWidth;
352 361 v[0].tv = sourceRect.y1 / m_sourceHeight;
353 362 v[0].tu2 = v[0].tu3 = (sourceRect.x1 / 2.0f + CHROMAOFFSET_HORIZ) / (m_sourceWidth>>1);
354 363 v[0].tv2 = v[0].tv3 = (sourceRect.y1 / 2.0f + CHROMAOFFSET_HORIZ) / (m_sourceHeight>>1);
355 364
356   - v[1].x = destRect.x2;
357   - v[1].y = destRect.y1;
358 365 v[1].tu = sourceRect.x2 / m_sourceWidth;
359 366 v[1].tv = sourceRect.y1 / m_sourceHeight;
360 367 v[1].tu2 = v[1].tu3 = (sourceRect.x2 / 2.0f + CHROMAOFFSET_HORIZ) / (m_sourceWidth>>1);
361 368 v[1].tv2 = v[1].tv3 = (sourceRect.y1 / 2.0f + CHROMAOFFSET_HORIZ) / (m_sourceHeight>>1);
362 369
363   - v[2].x = destRect.x2;
364   - v[2].y = destRect.y2;
365 370 v[2].tu = sourceRect.x2 / m_sourceWidth;
366 371 v[2].tv = sourceRect.y2 / m_sourceHeight;
367 372 v[2].tu2 = v[2].tu3 = (sourceRect.x2 / 2.0f + CHROMAOFFSET_HORIZ) / (m_sourceWidth>>1);
368 373 v[2].tv2 = v[2].tv3 = (sourceRect.y2 / 2.0f + CHROMAOFFSET_HORIZ) / (m_sourceHeight>>1);
369 374
370   - v[3].x = destRect.x1;
371   - v[3].y = destRect.y2;
372 375 v[3].tu = sourceRect.x1 / m_sourceWidth;
373 376 v[3].tv = sourceRect.y2 / m_sourceHeight;
374 377 v[3].tu2 = v[3].tu3 = (sourceRect.x1 / 2.0f + CHROMAOFFSET_HORIZ) / (m_sourceWidth>>1);
375 378 v[3].tv2 = v[3].tv3 = (sourceRect.y2 / 2.0f + CHROMAOFFSET_HORIZ) / (m_sourceHeight>>1);
376   -
377 379 // -0.5 offset to compensate for D3D rasterization
378 380 // set z and rhw
379 381 for(int i = 0; i < 4; i++)
@@ -556,9 +558,9 @@ void CConvolutionShader1Pass::Render(CD3DTexture &sourceTexture,
556 558 unsigned int sourceWidth, unsigned int sourceHeight,
557 559 unsigned int destWidth, unsigned int destHeight,
558 560 CRect sourceRect,
559   - CRect destRect)
  561 + CPoint destPoints[4])
560 562 {
561   - PrepareParameters(sourceWidth, sourceHeight, sourceRect, destRect);
  563 + PrepareParameters(sourceWidth, sourceHeight, sourceRect, destPoints);
562 564 float texSteps[] = { 1.0f/(float)sourceWidth, 1.0f/(float)sourceHeight};
563 565 SetShaderParameters(sourceTexture, &texSteps[0], sizeof(texSteps)/sizeof(texSteps[0]));
564 566 Execute(NULL,4);
@@ -566,8 +568,14 @@ void CConvolutionShader1Pass::Render(CD3DTexture &sourceTexture,
566 568
567 569 void CConvolutionShader1Pass::PrepareParameters(unsigned int sourceWidth, unsigned int sourceHeight,
568 570 CRect sourceRect,
569   - CRect destRect)
  571 + CPoint destPoints[4])
570 572 {
  573 + CRect destRect;
  574 + destRect.x1 = destPoints[0].x;
  575 + destRect.y1 = destPoints[0].y;
  576 + destRect.x2 = destPoints[2].x;
  577 + destRect.y2 = destPoints[2].y;
  578 +
571 579 if(m_sourceWidth != sourceWidth || m_sourceHeight != sourceHeight
572 580 || m_sourceRect != sourceRect || m_destRect != destRect)
573 581 {
@@ -579,23 +587,21 @@ void CConvolutionShader1Pass::PrepareParameters(unsigned int sourceWidth, unsign
579 587 CUSTOMVERTEX* v;
580 588 CWinShader::LockVertexBuffer((void**)&v);
581 589
582   - v[0].x = destRect.x1;
583   - v[0].y = destRect.y1;
  590 + for(int i = 0; i < 4; i++)
  591 + {
  592 + v[i].x = destPoints[i].x;
  593 + v[i].y = destPoints[i].y;
  594 + }
  595 +
584 596 v[0].tu = sourceRect.x1 / sourceWidth;
585 597 v[0].tv = sourceRect.y1 / sourceHeight;
586 598
587   - v[1].x = destRect.x2;
588   - v[1].y = destRect.y1;
589 599 v[1].tu = sourceRect.x2 / sourceWidth;
590 600 v[1].tv = sourceRect.y1 / sourceHeight;
591 601
592   - v[2].x = destRect.x2;
593   - v[2].y = destRect.y2;
594 602 v[2].tu = sourceRect.x2 / sourceWidth;
595 603 v[2].tv = sourceRect.y2 / sourceHeight;
596 604
597   - v[3].x = destRect.x1;
598   - v[3].y = destRect.y2;
599 605 v[3].tu = sourceRect.x1 / sourceWidth;
600 606 v[3].tv = sourceRect.y2 / sourceHeight;
601 607
@@ -687,14 +693,14 @@ void CConvolutionShaderSeparable::Render(CD3DTexture &sourceTexture,
687 693 unsigned int sourceWidth, unsigned int sourceHeight,
688 694 unsigned int destWidth, unsigned int destHeight,
689 695 CRect sourceRect,
690   - CRect destRect)
  696 + CPoint destPoints[4])
691 697 {
692 698 LPDIRECT3DDEVICE9 pD3DDevice = g_Windowing.Get3DDevice();
693 699
694 700 if(m_destWidth != destWidth || m_sourceHeight != sourceHeight)
695 701 CreateIntermediateRenderTarget(destWidth, sourceHeight);
696 702
697   - PrepareParameters(sourceWidth, sourceHeight, destWidth, destHeight, sourceRect, destRect);
  703 + PrepareParameters(sourceWidth, sourceHeight, destWidth, destHeight, sourceRect, destPoints);
698 704 float texSteps1[] = { 1.0f/(float)sourceWidth, 1.0f/(float)sourceHeight};
699 705 float texSteps2[] = { 1.0f/(float)destWidth, 1.0f/(float)(sourceHeight)};
700 706 SetShaderParameters(sourceTexture, &texSteps1[0], sizeof(texSteps1)/sizeof(texSteps1[0]), &texSteps2[0], sizeof(texSteps2)/sizeof(texSteps2[0]));
@@ -772,8 +778,14 @@ bool CConvolutionShaderSeparable::ClearIntermediateRenderTarget()
772 778 void CConvolutionShaderSeparable::PrepareParameters(unsigned int sourceWidth, unsigned int sourceHeight,
773 779 unsigned int destWidth, unsigned int destHeight,
774 780 CRect sourceRect,
775   - CRect destRect)
  781 + CPoint destPoints[4])
776 782 {
  783 + CRect destRect;
  784 + destRect.x1 = destPoints[0].x;
  785 + destRect.y1 = destPoints[0].y;
  786 + destRect.x2 = destPoints[2].x;
  787 + destRect.y2 = destPoints[2].y;
  788 +
777 789 if(m_sourceWidth != sourceWidth || m_sourceHeight != sourceHeight
778 790 || m_destWidth != destWidth || m_destHeight != destHeight
779 791 || m_sourceRect != sourceRect || m_destRect != destRect)
@@ -812,12 +824,12 @@ void CConvolutionShaderSeparable::PrepareParameters(unsigned int sourceWidth, un
812 824 v[0].tu = sourceRect.x1 / sourceWidth;
813 825 v[0].tv = sourceRect.y1 / sourceHeight;
814 826
815   - v[1].x = destRect.x2 - destRect.x1;
  827 + v[1].x = destPoints[1].x - destPoints[0].x;
816 828 v[1].y = 0;
817 829 v[1].tu = sourceRect.x2 / sourceWidth;
818 830 v[1].tv = sourceRect.y1 / sourceHeight;
819 831
820   - v[2].x = destRect.x2 - destRect.x1;
  832 + v[2].x = destPoints[1].x - destPoints[0].x;
821 833 v[2].y = sourceRect.y2 - sourceRect.y1;
822 834 v[2].tu = sourceRect.x2 / sourceWidth;
823 835 v[2].tv = sourceRect.y2 / sourceHeight;
@@ -829,23 +841,23 @@ void CConvolutionShaderSeparable::PrepareParameters(unsigned int sourceWidth, un
829 841
830 842 // Pass 2: pass the horizontal data untouched, resize vertical dimension for final result.
831 843
832   - v[4].x = destRect.x1;
833   - v[4].y = destRect.y1;
  844 + v[4].x = destPoints[0].x;
  845 + v[4].y = destPoints[0].y;
834 846 v[4].tu = 0;
835 847 v[4].tv = 0;
836 848
837   - v[5].x = destRect.x2;
838   - v[5].y = destRect.y1;
839   - v[5].tu = (destRect.x2 - destRect.x1) / destWidth;
  849 + v[5].x = destPoints[1].x;
  850 + v[5].y = destPoints[1].y;
  851 + v[5].tu = (destPoints[1].x - destPoints[0].x) / destWidth;
840 852 v[5].tv = 0;
841 853
842   - v[6].x = destRect.x2;
843   - v[6].y = destRect.y2;
844   - v[6].tu = (destRect.x2 - destRect.x1) / destWidth;
  854 + v[6].x = destPoints[2].x;
  855 + v[6].y = destPoints[2].y;
  856 + v[6].tu = (destPoints[1].x - destPoints[0].x) / destWidth;
845 857 v[6].tv = (sourceRect.y2 - sourceRect.y1) / sourceHeight;
846 858
847   - v[7].x = destRect.x1;
848   - v[7].y = destRect.y2;
  859 + v[7].x = destPoints[3].x;
  860 + v[7].y = destPoints[3].y;
849 861 v[7].tu = 0;
850 862 v[7].tv = (sourceRect.y2 - sourceRect.y1) / sourceHeight;
851 863
14 xbmc/cores/VideoRenderers/VideoShaders/WinVideoFilter.h
@@ -70,7 +70,7 @@ class CYUV2RGBShader : public CWinShader
70 70 public:
71 71 virtual bool Create(unsigned int sourceWidth, unsigned int sourceHeight, ERenderFormat fmt);
72 72 virtual void Render(CRect sourceRect,
73   - CRect destRect,
  73 + CPoint destPoints[4],
74 74 float contrast,
75 75 float brightness,
76 76 unsigned int flags,
@@ -79,7 +79,7 @@ class CYUV2RGBShader : public CWinShader
79 79
80 80 protected:
81 81 virtual void PrepareParameters(CRect sourceRect,
82   - CRect destRect,
  82 + CPoint destPoints[4],
83 83 float contrast,
84 84 float brightness,
85 85 unsigned int flags);
@@ -111,7 +111,7 @@ class CConvolutionShader : public CWinShader
111 111 unsigned int sourceWidth, unsigned int sourceHeight,
112 112 unsigned int destWidth, unsigned int destHeight,
113 113 CRect sourceRect,
114   - CRect destRect) = 0;
  114 + CPoint destPoints[4]) = 0;
115 115 virtual ~CConvolutionShader();
116 116
117 117 protected:
@@ -138,12 +138,12 @@ class CConvolutionShader1Pass : public CConvolutionShader
138 138 unsigned int sourceWidth, unsigned int sourceHeight,
139 139 unsigned int destWidth, unsigned int destHeight,
140 140 CRect sourceRect,
141   - CRect destRect);
  141 + CPoint destPoints[4]);
142 142
143 143 protected:
144 144 virtual void PrepareParameters(unsigned int sourceWidth, unsigned int sourceHeight,
145 145 CRect sourceRect,
146   - CRect destRect);
  146 + CPoint destPoints[4]);
147 147 virtual void SetShaderParameters(CD3DTexture &sourceTexture, float* texSteps, int texStepsCount);
148 148
149 149
@@ -161,7 +161,7 @@ class CConvolutionShaderSeparable : public CConvolutionShader
161 161 unsigned int sourceWidth, unsigned int sourceHeight,
162 162 unsigned int destWidth, unsigned int destHeight,
163 163 CRect sourceRect,
164   - CRect destRect);
  164 + CPoint destPoints[4]);
165 165 virtual ~CConvolutionShaderSeparable();
166 166
167 167 protected:
@@ -171,7 +171,7 @@ class CConvolutionShaderSeparable : public CConvolutionShader
171 171 virtual void PrepareParameters(unsigned int sourceWidth, unsigned int sourceHeight,
172 172 unsigned int destWidth, unsigned int destHeight,
173 173 CRect sourceRect,
174   - CRect destRect);
  174 + CPoint destPoints[4]);
175 175 virtual void SetShaderParameters(CD3DTexture &sourceTexture, float* texSteps1, int texStepsCount1, float* texSteps2, int texStepsCount2);
176 176
177 177 private:
23 xbmc/cores/VideoRenderers/WinRenderer.cpp
@@ -211,7 +211,7 @@ bool CWinRenderer::UpdateRenderMethod()
211 211 return true;
212 212 }
213 213
214   -bool CWinRenderer::Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_format)
  214 +bool CWinRenderer::Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_format, unsigned int orientation)
215 215 {
216 216 if(m_sourceWidth != width
217 217 || m_sourceHeight != height)
@@ -225,6 +225,7 @@ bool CWinRenderer::Configure(unsigned int width, unsigned int height, unsigned i
225 225 m_bFilterInitialized = false;
226 226 }
227 227
  228 + m_renderOrientation = orientation;
228 229 m_fps = fps;
229 230 m_flags = flags;
230 231 m_format = format;
@@ -780,10 +781,10 @@ void CWinRenderer::ScaleFixedPipeline()
780 781
781 782 VERTEX vertex[] =
782 783 {
783   - {m_destRect.x1, m_destRect.y1, 0.0f, 1.0f, diffuse, specular, m_sourceRect.x1 / srcWidth, m_sourceRect.y1 / srcHeight},
784   - {m_destRect.x2, m_destRect.y1, 0.0f, 1.0f, diffuse, specular, m_sourceRect.x2 / srcWidth, m_sourceRect.y1 / srcHeight},
785   - {m_destRect.x2, m_destRect.y2, 0.0f, 1.0f, diffuse, specular, m_sourceRect.x2 / srcWidth, m_sourceRect.y2 / srcHeight},
786   - {m_destRect.x1, m_destRect.y2, 0.0f, 1.0f, diffuse, specular, m_sourceRect.x1 / srcWidth, m_sourceRect.y2 / srcHeight},
  784 + {m_rotatedDestCoords[0].x, m_rotatedDestCoords[0].y, 0.0f, 1.0f, diffuse, specular, m_sourceRect.x1 / srcWidth, m_sourceRect.y1 / srcHeight},
  785 + {m_rotatedDestCoords[1].x, m_rotatedDestCoords[1].y, 0.0f, 1.0f, diffuse, specular, m_sourceRect.x2 / srcWidth, m_sourceRect.y1 / srcHeight},
  786 + {m_rotatedDestCoords[2].x, m_rotatedDestCoords[2].y, 0.0f, 1.0f, diffuse, specular, m_sourceRect.x2 / srcWidth, m_sourceRect.y2 / srcHeight},
  787 + {m_rotatedDestCoords[3].x, m_rotatedDestCoords[3].y, 0.0f, 1.0f, diffuse, specular, m_sourceRect.x1 / srcWidth, m_sourceRect.y2 / srcHeight},
787 788 };
788 789
789 790 // Compensate for D3D coordinates system
@@ -861,7 +862,7 @@ void CWinRenderer::Stage1()
861 862 {
862 863 if (!m_bUseHQScaler)
863 864 {
864   - m_colorShader->Render(m_sourceRect, m_destRect,
  865 + m_colorShader->Render(m_sourceRect, m_rotatedDestCoords,
865 866 g_settings.m_currentVideoSettings.m_Contrast,
866 867 g_settings.m_currentVideoSettings.m_Brightness,
867 868 m_flags,
@@ -879,7 +880,7 @@ void CWinRenderer::Stage1()
879 880 CRect srcRect(0.0f, 0.0f, m_sourceWidth, m_sourceHeight);
880 881 CRect rtRect(0.0f, 0.0f, m_sourceWidth, m_sourceHeight);
881 882
882   - m_colorShader->Render(srcRect, rtRect,
  883 + m_colorShader->Render(srcRect, m_rotatedDestCoords,
883 884 g_settings.m_currentVideoSettings.m_Contrast,
884 885 g_settings.m_currentVideoSettings.m_Brightness,
885 886 m_flags,
@@ -895,7 +896,7 @@ void CWinRenderer::Stage1()
895 896
896 897 void CWinRenderer::Stage2()
897 898 {
898   - m_scalerShader->Render(m_IntermediateTarget, m_sourceWidth, m_sourceHeight, m_destWidth, m_destHeight, m_sourceRect, m_destRect);
  899 + m_scalerShader->Render(m_IntermediateTarget, m_sourceWidth, m_sourceHeight, m_destWidth, m_destHeight, m_sourceRect, m_rotatedDestCoords);
899 900 }
900 901
901 902 void CWinRenderer::RenderProcessor(DWORD flags)
@@ -1033,6 +1034,12 @@ bool CWinRenderer::Supports(ERENDERFEATURE feature)
1033 1034 if(feature == RENDERFEATURE_CONTRAST)
1034 1035 return true;
1035 1036
  1037 + if(feature == RENDERFEATURE_ROTATION)
  1038 + {
  1039 + if (m_renderMethod != RENDER_DXVA)
  1040 + return true;
  1041 + }
  1042 +
1036 1043 return false;
1037 1044 }
1038 1045
2  xbmc/cores/VideoRenderers/WinRenderer.h
@@ -155,7 +155,7 @@ class CWinRenderer : public CBaseRenderer
155 155 bool RenderCapture(CRenderCapture* capture);
156 156
157 157 // Player functions
158   - virtual bool Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_format);
  158 + virtual bool Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_format, unsigned int orientation);
159 159 virtual int GetImage(YV12Image *image, int source = AUTOSOURCE, bool readonly = false);
160 160 virtual void ReleaseImage(int source, bool preserve = false);
161 161 virtual bool AddVideoPicture(DVDVideoPicture* picture);
1  xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h
@@ -214,6 +214,7 @@ class CDVDVideoCodec
214 214 FILTER_DEINTERLACE_ANY = 0xf, /* use any deinterlace mode */
215 215 FILTER_DEINTERLACE_FLAGGED = 0x10, /* only deinterlace flagged frames */
216 216 FILTER_DEINTERLACE_HALFED = 0x20, /* do half rate deinterlacing */
  217 + FILTER_ROTATE = 0x40, /* rotate image according to the codec hints */
217 218 };
218 219
219 220 /*
18 xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
@@ -366,6 +366,24 @@ unsigned int CDVDVideoCodecFFmpeg::SetFilters(unsigned int flags)
366 366 if(m_pHardware)
367 367 return 0;
368 368
  369 + if(flags & FILTER_ROTATE)
  370 + {
  371 + switch(m_iOrientation)
  372 + {
  373 + case 90:
  374 + m_filters_next += "transpose=1";
  375 + break;
  376 + case 180:
  377 + m_filters_next += "vflip,hflip";
  378 + break;
  379 + case 270:
  380 + m_filters_next += "transpose=2";
  381 + break;
  382 + default:
  383 + break;
  384 + }
  385 + }
  386 +
369 387 if(flags & FILTER_DEINTERLACE_YADIF)
370 388 {
371 389 if(flags & FILTER_DEINTERLACE_HALFED)
5 xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
@@ -526,6 +526,9 @@ void CDVDPlayerVideo::Process()
526 526 if (mDeintMode == VS_DEINTERLACEMODE_AUTO && mFilters)
527 527 mFilters |= CDVDVideoCodec::FILTER_DEINTERLACE_FLAGGED;
528 528 }
  529 +
  530 + if (!g_renderManager.Supports(RENDERFEATURE_ROTATION))
  531 + mFilters |= CDVDVideoCodec::FILTER_ROTATE;
529 532
530 533 mFilters = m_pVideoCodec->SetFilters(mFilters);
531 534
@@ -1120,7 +1123,7 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts)
1120 1123 }
1121 1124
1122 1125 CLog::Log(LOGDEBUG,"%s - change configuration. %dx%d. framerate: %4.2f. format: %s",__FUNCTION__,pPicture->iWidth, pPicture->iHeight, config_framerate, formatstr.c_str());
1123   - if(!g_renderManager.Configure(pPicture->iWidth, pPicture->iHeight, pPicture->iDisplayWidth, pPicture->iDisplayHeight, config_framerate, flags, pPicture->format, pPicture->extended_format))
  1126 + if(!g_renderManager.Configure(pPicture->iWidth, pPicture->iHeight, pPicture->iDisplayWidth, pPicture->iDisplayHeight, config_framerate, flags, pPicture->format, pPicture->extended_format, m_hints.orientation))
1124 1127 {
1125 1128 CLog::Log(LOGERROR, "%s - failed to configure renderer", __FUNCTION__);
1126 1129 return EOS_ABORT;

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.