Log in

View Full Version : Media Player Classic Home Cinema (MPC-HC) - DXVA!


Pages : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 [401] 402 403 404 405 406 407 408 409 410

ageback
3rd August 2012, 05:03
S.Chinese update
https://dl.dropbox.com/u/132862/mplayerc.sc.rc.txt

LigH
3rd August 2012, 07:50
Congratulations for "The thread of thousand pages" :)

assuming a board default of 20 posts per page

ryrynz
3rd August 2012, 08:30
I was wondering if someone was going to say something.. I thought about posting IT'S OVER 1000!! earlier today but decided against it :D

patch1
3rd August 2012, 13:59
Track it here (https://github.com/mpc-hc/mpc-hc/commits/master) at github. As usual, development builds available at http://xhmikosr.1f0.de/mpc-hc/

Is there a reasonably simple way to correlate build number with commit history entry. I find it useful to see what changes I should watch out for when loading a new version of mpc-hc

ryrynz
3rd August 2012, 14:41
yup the hash is right beside the build number in Help -> About...

For example listed in my MPC-HC copy in Help -> About...

1.6.3.5713 (3a1c0fa)

Matches with build number

3a1c0fad69

v0lt
3rd August 2012, 17:43
Matches with build number

3a1c0fad69
This is a mockery.

Underground78
3rd August 2012, 18:24
See audio decoder settings.
It can probably be useful, I think it makes sense to add it.

yup the hash is right beside the build number in Help -> About...

For example listed in my MPC-HC copy in Help -> About...

1.6.3.5713 (3a1c0fa)

Matches with build number

3a1c0fad69

If you are just interested in seeing the last few changes, http://github.com/mpc-hc/mpc-hc/commit/<shorthashhere> (e.g. http://github.com/mpc-hc/mpc-hc/commit/3a1c0fa) and then click on the parent hash to go to the previous commit.

I'm considering doing a simple log viewer for people that prefer using the old fashioned build number.

v0lt
3rd August 2012, 18:35
It can probably be useful, I think it makes sense to add it.

mpc-hc_audiomixer_3.7z (http://www.mediafire.com/?mn68dsqsfs7dz1l)
Yet another test build. And then see what happens.

Underground78
3rd August 2012, 18:58
mpc-hc_audiomixer_3.7z (http://www.mediafire.com/?mn68dsqsfs7dz1l)
Yet another test build. And then see what happens.
It seems to work fine for me, I tested it with my channel order samples (http://www.mediafire.com/?ilo6w4zotu9ca).

In Options>Subtitles>Delay Interval, I can't enter - (minus sign). mpc-hc64.exe 1.6.3.5696 on Win7 x64.

GL
That's because putting a negative number here doesn't really make sense. If you press F1/F2 (default key bindings but you can change them in Options > Keys), it will subtract/add the value you set in "Delay interval".

Mosley
3rd August 2012, 20:31
See audio decoder settings.

Sorry but.... where? In "MPC Audio Decoder" (during playback) there isn't nothing. And I don't see any menu option related to the audio decoder settings. Not even in the the menu page with the internal filters. What's exactly the path to find it? :confused:

Many thanks...

Underground78
3rd August 2012, 20:33
Sorry but.... where? In "MPC Audio Decoder" (during playback) there isn't nothing. And I don't see any menu option related to the audio decoder settings. Not even in the the menu page with the internal filters. What's exactly the path to find it? :confused:

Many thanks...
In the audio decoder settings you have a combobox that lets you choose the channels configuration (stereo, etc).

ryrynz
4th August 2012, 10:53
I'm considering doing a simple log viewer for people that prefer using the old fashioned build number.

Sounds like a good idea.

betaking
5th August 2012, 02:16
S.Chinese update
http://www.mediafire.com/?udt1imv5mm8bdd5

v0lt
5th August 2012, 06:18
mpc-hc_audiomixer_6.7z (http://www.mediafire.com/?faz867h7iglbkev)
redid the audio decoder settings window

TheCatcher
5th August 2012, 10:42
I modified a recent pull of MPC-HC source code to support SBS 3D on older DLP TVs, that require the right and left screen data to be pixel interleaved.

I did it with a couple of DX9 (ps_2_0) Post-Resize Pixel Shaders (one for right side first, and the other for left side first). And a change to the DX9RenderingEngine.cpp, to add 4 additional parameters to the fConstant array that is passed to the Post-Resize Pixel Shaders.

The 4 additional parameters are the offset and width of the video data relative to the m_TemporaryScreenSpaceTextureSize. And the position of the MPC-HC Window relative to the screen. The offset to the video data was necessary to make sure when I interleaved the pixels, I didn't mix in any surrounding non-video data. The position of the window relative to the screen was necessary so that, in windowed mode, I would know whether to pull the first pixel of each line from the right or left side of the frame.

Since this requires additional parameters to be passed to the Pixel Shaders, I wasn't sure if this is a change that the people responsible for the source repository would be interested in. I plan on keeping it in the versions of MPC-HC that I run. If it is something that someone would like to add to the source repository, here is the source code modification, that I am using...

DX9RenderingEngine.cpp -> Line 451-453
From:
float fConstData[][4] = {
{(float)m_TemporaryScreenSpaceTextureSize.cx, (float)m_TemporaryScreenSpaceTextureSize.cy, (float)(counter++), (float)diff / CLOCKS_PER_SEC},
{1.0f / m_TemporaryScreenSpaceTextureSize.cx, 1.0f / m_TemporaryScreenSpaceTextureSize.cy, 0, 0},
};

To:
CWnd *pMainWnd = AfxGetApp()->m_pMainWnd;
WINDOWPLACEMENT Place;
Place.length = sizeof(WINDOWPLACEMENT);
EXECUTE_ASSERT(GetWindowPlacement(pMainWnd->m_hWnd,&Place));

float fConstData[][4] = {
{(float)m_TemporaryScreenSpaceTextureSize.cx, (float)m_TemporaryScreenSpaceTextureSize.cy, (float)(counter++), (float)diff / CLOCKS_PER_SEC},
{1.0f / m_TemporaryScreenSpaceTextureSize.cx, 1.0f / m_TemporaryScreenSpaceTextureSize.cy, (float)destRect.left, (float)( destRect.right + 1 ) - destRect.left },
{(float)Place.rcNormalPosition.top, (float)Place.rcNormalPosition.left, (float)0, (float)0 },
};

If anyone is interested, let me know, and I will post the code for the Post-Resize Pixel Shaders.

Anarchitektur
5th August 2012, 13:55
mpc-hc_audiomixer_6.7z (http://www.mediafire.com/?faz867h7iglbkev)
redid the audio decoder settings window

"mixer" checkbox does not stay ticked

JanWillem32
5th August 2012, 18:59
@TheCatcher: If it's useful to add the top and left monitor-relative window coordinates as variables for the pixel shaders, I don't mind helping out a bit. Your code needs a lot of refining, though.
The usage of GetWindowPlacement() is wrong for when your window is a layered item: http://msdn.microsoft.com/en-us/library/windows/desktop/ms632611%28v=vs.85%29.aspx .
Use GetWindowRect() to get desktop-relative coordinates (and if more info is required, use GetWindowInfo() to retrieve the full window class info).
Using the coordinates 'raw' is wrong as well. For a multi-monitor setup of 4 1920×1080 monitors in a 2×2 setup with the top left monitor set as main monitor, the desktop interval for the bottom-right monitor will be [(1920, 1080), (3840, 2160)). Use GetMonitorInfo() and offset the desktop-relative coordinates with top-left point of the monitor rectangle to get monitor-relative coordinates.
Using "pMainWnd->m_hWnd" is wrong as well, as that's the main player's window (which can even be on another monitor). We have "m_hWnd" available in the renderer classes themselves for the video window.
For the Post-Resize pass, "(float)destRect.left, (float)( destRect.right + 1 ) - destRect.left" is useless. "destRect.left" is 0, and "destRect.right" is equal to "m_TemporaryScreenSpaceTextureSize.cx", which is already available. (The Post-Resize pass does no re-positioning, that's only done in the resizer pass before it.) For integer coordinates on Windows, it's already custom to have the left and top items inclusive and the right and bottom items exclusive: http://msdn.microsoft.com/en-us/library/windows/desktop/dd162897%28v=vs.85%29.aspx . You simply do right minus left and bottom minus top to get the size of a RECT.
If you need any more info or help, please just ask me.

v0lt
5th August 2012, 20:04
Interesting observation.
If you have a stereo track, in which the left and right channels are identical. Then when mixing 2.0 to 5.1, you will not hear the rear speakers.
With ordinary stereo tracks no such problem.
:)

v0lt
5th August 2012, 20:17
"mixer" checkbox does not stay ticked
It fixed.
r5597+ (http://www.mediafire.com/?xfgh33iws56bhк5597)

JanWillem32
6th August 2012, 00:36
Mixing audio indeed works like that; the simple mono center is a per sample left+right and the simple width is a left-right (actually also mono, the same output is sent to all surround channels). If the data in the left and right is the same, left-right will be zero. Note that the interval of the output samples increases from a base interval of [-1, 1] to [-2, 2] for both equations (there's a clipping risk, just as with other mixing options).
When the phase of left and right are off by even a µs, the samples won't align, and doing a per-sample left+right and left-right won't work. You need to do continuous Fourier transforms on the tracks to correlate them spectrally in such a case. Such filters are much more expensive in processing but benefit greatly from single-precision floating point optimizations in SSE and AVX code. Such filters can also do more advanced extractions of channels, but are prone to artifacts. (For once, Fourier transforms on audio data won't let very low bass sounds through because of a limit in the sampling window. You need to add a low-pass filter to output those to the LFE channel.)
It's been a while since I worked with audio filters, but those are pretty much the basics of what I can remember about channel expansion filters.

TheCatcher
6th August 2012, 03:24
@TheCatcher: If it's useful to add the top and left monitor-relative window coordinates as variables for the pixel shaders, I don't mind helping out a bit. Your code needs a lot of refining, though.

No argument from me on that. I was just using OutputDebugString to find variables that looked like they made sense. I'm glad to make whatever changes seem appropriate to make it work better and more efficiently.

The usage of GetWindowPlacement() is wrong for when your window is a layered item: http://msdn.microsoft.com/en-us/library/windows/desktop/ms632611%28v=vs.85%29.aspx .
Use GetWindowRect() to get desktop-relative coordinates (and if more info is required, use GetWindowInfo() to retrieve the full window class info).
Using the coordinates 'raw' is wrong as well. For a multi-monitor setup of 4 1920×1080 monitors in a 2×2 setup with the top left monitor set as main monitor, the desktop interval for the bottom-right monitor will be [(1920, 1080), (3840, 2160)). Use GetMonitorInfo() and offset the desktop-relative coordinates with top-left point of the monitor rectangle to get monitor-relative coordinates.
Using "pMainWnd->m_hWnd" is wrong as well, as that's the main player's window (which can even be on another monitor). We have "m_hWnd" available in the renderer classes themselves for the video window.

m_hWnd it is, I wasn't real happy about going all the way back to the app class to get a window handle. Having a rendering window handle available makes a lot more sense. I implemented the local m_hWnd and the monitor coordinates that the upper left corner of the window is on, in this version of the code.

For the Post-Resize pass, "(float)destRect.left, (float)( destRect.right + 1 ) - destRect.left" is useless. "destRect.left" is 0, and "destRect.right" is equal to "m_TemporaryScreenSpaceTextureSize.cx", which is already available. (The Post-Resize pass does no re-positioning, that's only done in the resizer pass before it.) For integer coordinates on Windows, it's already custom to have the left and top items inclusive and the right and bottom items exclusive: http://msdn.microsoft.com/en-us/library/windows/desktop/dd162897%28v=vs.85%29.aspx . You simply do right minus left and bottom minus top to get the size of a RECT.
If you need any more info or help, please just ask me.

I was counting on the Post-Resize pass not doing any repositioning (or resizing). If it did, my entire shader idea would fail miserably. But it does appear that the destRect values aren't necessarily unused, 0, and equal to m_TemporaryScreenSpaceTextureSize.cx.

It looks like, if maintaining the aspect ratio, causes the black bars to be inserted on the sides or the top and bottom of the texture, the destRect values are used as offsets to where the source video data ended up, withing the m_TemporaryScreenSpaceTextureSize values. I have some examples of screen shots and OutputDebugStrings near the end of this post, that show the situations that cause the destRect values to become necessary.

Knowing where the source video data ended up is crucial to properly interleaving the pixels.

For SBS 3D images, the destRect.top value doesn't come into play. But the offset to the source video data and the width in destRect.left and destRect.right are needed to keep me from interleaving the valid video source pixels into the black surrounding pixels.

At some point I may end up doing a shader to handle top and bottom split 3D images (I'm pretty sure top and bottom split 3D images are what 3D BlueRay disks use). When I do that, I will probably also have to pass in the destRect.top and (destRect.bottom+1 - destRect.top) values.

This is the code I am currently using. It appears to be working. I can move the window around and resize the and the left and right sides don't transpose themselves.


RECT sWndRect;
GetWindowRect( m_hWnd, &sWndRect );

POINT sWindowOrigin = { sWndRect.left, sWndRect.top };
MONITORINFO sMonitorInfo;
sMonitorInfo.cbSize = sizeof(sMonitorInfo);
GetMonitorInfo(MonitorFromPoint( sWindowOrigin,
MONITOR_DEFAULTTONEAREST), &sMonitorInfo);

POINT sMonitorAdjustedWindOrigin = {
sWndRect.left - sMonitorInfo.rcWork.left,
sWndRect.top - sMonitorInfo.rcWork.top };

float fConstData[][4] = {
{ (float)m_TemporaryScreenSpaceTextureSize.cx,
(float)m_TemporaryScreenSpaceTextureSize.cy,
(float)(counter++),
(float)diff / CLOCKS_PER_SEC},
{ 1.0f / m_TemporaryScreenSpaceTextureSize.cx,
1.0f / m_TemporaryScreenSpaceTextureSize.cy,
(float)destRect.left,
(float)( destRect.right + 1 ) - destRect.left },
{ (float)sMonitorAdjustedWindOrigin.y,
(float)sMonitorAdjustedWindOrigin.x,
(float)0, (float)0 },
};


If I misinterpreted what you meant about the destRect values, or there is another / better way, I'm open to suggestions.

This is an image capture taken when destRect.top was 0, destRect.left was 57, and destRect.right was 526.

http://www.syaeger.com/images/MPC-HC-destrect.top=0,left=57,bottom=254,right=526.jpg

This is an image capture taken when destRect.top was 23, destRect.left was 0, and destRect.right was 380.

http://www.syaeger.com/images/MPC-HC-destrect.top=23,left=0,bottom=228,right=380.jpg

Here is what those images look like when my 3D shader isn't running...

This next image is a good example of why I need the destRect.left and right values. If I pull one of the pixels, just to the right of the center and move it all the way to the left edge, it will be surrounded by black pixels, not the pixels from the other eye's image.

http://www.syaeger.com/images/MPC-HC-destrect.top=0,left=57,bottom=254,right=526-NoShader.jpg

http://www.syaeger.com/images/MPC-HC-destrect.top=23,left=0,bottom=228,right=380-NoShader.jpg

The values I am getting in my OutputDebugString statements seem to be valid. And the 3D output seems to be solid. But I'm definitely open to making changes that would make it more efficient.

Here are some of the values output by the OutputDebugStrings.

The first 4 groups are checking the destRect values for 2 different window sizes on primary and secondary monitors.

Within the groups, the small group containing the sPlace and sWindowInfo values are just there for comparison. The next small group with sWndRect and sMonitorInfo values are there just for information, some of the values are used to calculate the final values that become the parameters to the Pixel Shader.

MPC-HC-destrect.top=23,left=0,bottom=228,right=380.jpg on primary monitor
------------------------------------------------------
sPlace.rcNormalPosition.top=490,left=1038,bottom=872,right=1434
sWindowInfo.cyWindowBorders=0,cxWindowBorders=0

sWndRect.top=540,left=1046,bottom=792,right=1426
sMonitorInfo.rcMonitor.top=0,left=0,bottom=1004,right=1824
sMonitorInfo.rcWork.top=0,left=0,bottom=922,right=1824

sMonitorAdjustedWindOrigin.y=540,x=1046,
m_TemporaryScreenSpaceTextureSize.cx=1824,cy=1038
destrect.top=23,left=0,bottom=228,right=380

MPC-HC-destrect.top=23,left=0,bottom=228,right=380.jpg on secondary 2D monitor, to the right of the primary monitor
------------------------------------------------------
sPlace.rcNormalPosition.top=338,left=2349,bottom=720,right=2745
sWindowInfo.cyWindowBorders=0,cxWindowBorders=0

sWndRect.top=388,left=2357,bottom=640,right=2737
sMonitorInfo.rcMonitor.top=0,left=1824,bottom=1200,right=3744
sMonitorInfo.rcWork.top=0,left=1824,bottom=1200,right=3744

sMonitorAdjustedWindOrigin.y=388,x=533
m_TemporaryScreenSpaceTextureSize.cx=1920,cy=1200
destrect.top=23,left=0,bottom=228,right=380


MPC-HC-destrect.top=0,left=57,bottom=254,right=526.jpg on primary monitor
------------------------------------------------------
sPlace.rcNormalPosition.top=503,left=868,bottom=887,right=1468
sWindowInfo.cyWindowBorders=0,cxWindowBorders=0

sWndRect.top=553,left=876,bottom=807,right=1460
sMonitorInfo.rcMonitor.top=0,left=0,bottom=1004,right=1824
sMonitorInfo.rcWork.top=0,left=0,bottom=922,right=1824

sMonitorAdjustedWindOrigin.y=553,x=876
m_TemporaryScreenSpaceTextureSize.cx=1824,cy=1038
destrect.top=0,left=57,bottom=254,right=526

MPC-HC-destrect.top=0,left=57,bottom=254,right=526.jpg on secondary monitor, to the right of the primary monitor
------------------------------------------------------
sPlace.rcNormalPosition.top=237,left=2027,bottom=621,right=2627
sWindowInfo.cyWindowBorders=0,cxWindowBorders=0

sWndRect.top=287,left=2035,bottom=541,right=2619
sMonitorInfo.rcMonitor.top=0,left=1824,bottom=1200,right=3744
sMonitorInfo.rcWork.top=0,left=1824,bottom=1200,right=3744

sMonitorAdjustedWindOrigin.y=287,x=211
m_TemporaryScreenSpaceTextureSize.cx=1920,cy=1200
destrect.top=0,left=57,bottom=254,right=526

These next 2 groups are testing negative monitor coordinates, by changing the 2D monitor on the right to the primary monitor and the 3D monitor on the left to the secondary monitor.

Full Screen, Video displayed on the Secondary 3D monitor, on the left of the primary 2d monitor
--------------------------------------------
sPlace.rcNormalPosition.top=0,left=-1824,bottom=1004,right=0

WndRect.top=0,left=-1824,bottom=1004,right=0
sMonitorInfo.rcMonitor.top=0,left=-1824,bottom=1004,right=0
sMonitorInfo.rcWork.top=0,left=-1824,bottom=1004,right=0

sMonitorAdjustedWindOrigin.y=0,x=0
m_TemporaryScreenSpaceTextureSize.cx=1824,cy=1038
destrect.top=8,left=0,bottom=994,right=1824


Windowed, displayed on the Secondary 3D monitor, on the left of the primary 2d monitor
--------------------------------------------
sPlace.rcNormalPosition.top=191,left=-1654,bottom=909,right=-591

sWndRect.top=241,left=-1646,bottom=829,right=-599
sMonitorInfo.rcMonitor.top=0,left=-1824,bottom=1004,right=0
sMonitorInfo.rcWork.top=0,left=-1824,bottom=1004,right=0

sMonitorAdjustedWindOrigin.y=241,x=178
m_TemporaryScreenSpaceTextureSize.cx=1824,cy=1038
destrect.top=10,left=0,bottom=576,right=1047

betaking
6th August 2012, 08:00
S.Chinese update
http://www.mediafire.com/?ccx5kgxaugmpj7n

ryrynz
6th August 2012, 10:37
Any major components left for 1.6.3 final?

TheCatcher
6th August 2012, 14:29
After my last post, I decided to add a couple more shaders to support Top and Bottom encoded 3D video streams.

So that I can determine where the lower half of the video data starts, I've changed the parameters I am sending to the Post-Resize Pixel shader to include the destRect.top and ((destRect.bottom+1)-destRect.top) values.

From:

float fConstData[][4] = {
{ (float)m_TemporaryScreenSpaceTextureSize.cx,
(float)m_TemporaryScreenSpaceTextureSize.cy,
(float)(counter++),
(float)diff / CLOCKS_PER_SEC},
{ 1.0f / m_TemporaryScreenSpaceTextureSize.cx,
1.0f / m_TemporaryScreenSpaceTextureSize.cy,
(float)destRect.left,
(float)( destRect.right + 1 ) - destRect.left },
{ (float)sMonitorAdjustedWindOrigin.y,
(float)sMonitorAdjustedWindOrigin.x,
(float)0, (float)0 },
};


To:

float fConstData[][4] = {
{ (float)m_TemporaryScreenSpaceTextureSize.cx,
(float)m_TemporaryScreenSpaceTextureSize.cy,
(float)(counter++),
(float)diff / CLOCKS_PER_SEC},
{ 1.0f / m_TemporaryScreenSpaceTextureSize.cx,
1.0f / m_TemporaryScreenSpaceTextureSize.cy,
(float)sMonitorAdjustedWindOrigin.y,
(float)sMonitorAdjustedWindOrigin.x },
{ (float)destRect.left,
(float)( destRect.right + 1 ) - destRect.left,
(float)destRect.top,
(float)( destRect.bottom + 1 ) - destRect.top },
};


I moved the Monitor Adjusted Window Origin values from the third quad parameter into the second quad. And I put all the destRect values together in the third quad.

JanWillem32
6th August 2012, 16:30
I was counting on the Post-Resize pass not doing any repositioning (or resizing). If it did, my entire shader idea would fail miserably. But it does appear that the destRect values aren't necessarily unused, 0, and equal to m_TemporaryScreenSpaceTextureSize.cx.Ah yes, I remember the window texturing bug in the trunk renderer now. (It's more likely a lazily implemented feature though.) The renderer allocates the post-resize textures and backbuffers at the size of the monitor it starts on and fills them with black at the start of each frame. (And it doesn't adjust them when switching to another monitor of a different resolution.) My version of the renderer allocates at window size and re-adjusts every time the window size changes.I'm pretty sure top and bottom split 3D images are what 3D BlueRay disks use.Blu-Ray uses one main video stream (left or right) and one delta stream to generate the other view. The decoder delivers two separate surfaces after decoding. The transport of 3D mode surfaces over HDMI, DP and SDI are also different.

TheCatcher
6th August 2012, 20:37
My version of the renderer allocates at window size and re-adjusts every time the window size changes.

When I started this, I was expecting the image to be at the upper left corner of the texture. My son is the video expert in our family (he is in charge of the video editing software for Red Cameras), when I told him, in windowed mode, I was pretty sure the video image wasn't in the upper left corner, he said I was crazy...

Blu-Ray uses one main video stream (left or right) and one delta stream to generate the other view. The decoder delivers two separate surfaces after decoding. The transport of 3D mode surfaces over HDMI, DP and SDI are also different.

I decided not to do the Blu-Ray data format, just the the SBS 3D file format, and the Top and Bottom (TAB) 3D file format (a lot of the Passive 3D HDTV owners seem to like the TAB 3D file format). For the TAB format, the top half of the frame is one eye's view and the bottom half is the other eye's view. Almost exactly like the SBS format, except TAB does a horizontal split, instead of a vertical split.

As far as I can see, the geometry for 1080p to 1080p changes from 960*1080 to 1920*540 per frame in this transformation. The down-sizing stage is simple (2-pixel average vertically), but the horizontal doubling is a more involved operation. Did you implement a one- or two-pass filter for the procedure?

The data in the SBS and the TAB data files already contain 2 video frames at half the final frame resolution. All the shader has to do is move the existing pixels around to create the DLP's checkerboard pattern. So I was able implement each of them as one-pass shaders.

I haven't tested the TAB Shaders yet, I will test them, today, after work. There is a possibility the TAB Shaders might end up using more storage variables than DX9 allows. So I might have to make them DX10, ps_3_0 shaders.

When I modified the SBS Shaders, to make sure they pulled the source pixels from dead center of the pixel (so the color wouldn't be muddied by the surrounding pixels), I ended up having to do a lot of optimizing to get the storage variable count back down, to be DX9 compatible.

JanWillem32
6th August 2012, 22:54
When I started this, I was expecting the image to be at the upper left corner of the texture. My son is the video expert in our family (he is in charge of the video editing software for Red Cameras), when I told him, in windowed mode, I was pretty sure the video image wasn't in the upper left corner, he said I was crazy...My predecessors that worked on the renderers were not DirectX specialists, and it shows in cases like this. Oh well, it could have been worse. However, I did import another renderer that had much better organization when I really started working on the project, instead of editing the original one.The data in the SBS and the TAB data files already contain 2 video frames at half the final frame resolution. All the shader has to do is move the existing pixels around to create the DLP's checkerboard pattern. So I was able implement each of them as one-pass shaders.I don't know the organization of the checkerboard pattern, but switching between layouts of 960*1080 and 1920*540 source images does require interpolation, even while the number of pixels remains the same.I haven't tested the TAB Shaders yet, I will test them, today, after work. There is a possibility the TAB Shaders might end up using more storage variables than DX9 allows. So I might have to make them DX10, ps_3_0 shaders.DirectX 10 starts at level 4.0. The shader language for those levels is not compatible with DirectX 9 levels, by the way.When I modified the SBS Shaders, to make sure they pulled the source pixels from dead center of the pixel (so the color wouldn't be muddied by the surrounding pixels), I ended up having to do a lot of optimizing to get the storage variable count back down, to be DX9 compatible.I set the sampler state to nearest neighbor for the renderer in the trunk build. It was one of the last modifications I made to the renderer in the trunk before I imported another and started working on that. Aligning to the pixel centers is still important, of course.

I thought you were trying to transform to a different interleaved format at first... Oh well, it's still a good example:// (C) 2012 Jan-Willem Krans (janwillem32 <at> hotmail.com)
// This file is part of Video pixel shader pack.
// This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

// Prototype
// This shader should be run as a screen space pixel shader.
// This shader requires compiling with ps_2_0, but higher is better, see http://en.wikipedia.org/wiki/Pixel_shader to look up what PS version your video card supports.
// Use this shader to convert a SBS 3D image to interleave per scan line 3D format, while doubling the width of the image by Mitchell-Netravali cubic5 interpolation.
// This shader requires the source image (split halves) to span the full width of the screen space and have the top pixel row aligned to even.

sampler s0;
float2 c0;
float2 c1;
// average two pixels per sample, as the output is half-height
#define sp(a, b) float4 a = tex2D(s0, float2(coord+b*fx*c1.x, tex.y))+tex2D(s0, float2(coord+b*fx*c1.x, tex.y+c1.y));

float4 main(float2 tex : TEXCOORD0) : COLOR
{
float offset = 0;
float n = frac(tex.y*c0.y/2.);
if(n > .5) offset = .5+.5*c1.x;// even y top, odd y bottom

// double the width
float coord = (tex.x/2.+offset)*c0.x;// assign the output position, normalized to texture width in pixels
float t = frac(coord);// calculate the difference between the output pixel and the original surrounding two pixels
// adjust sampling matrix to put the ouput pixel on Q2+.25
float fx;
if(t > .5) {coord = (coord-t+1.5)*c1.x; fx = -1;}
else {coord = (coord-t+.5)*c1.x; fx = 1;}

sp(Q0, -2) sp(Q1, -1) sp(Q2, 0) sp(Q3, 1) sp(Q4, 2)// original pixels
return Q0*25/20736.*.5+Q2*16632/20736.*.5+Q3*5234/20736.*.5-Q1*770/20736.*.5-Q4*385/20736.*.5;// output interpolated value
}

madshi
7th August 2012, 07:18
> I set the sampler state to nearest neighbor

Same here in madVR. It helps finding pixel addressing bugs and makes sure there's no unintentional blurring. Plus, it might be ever so slightly faster.

TheCatcher
7th August 2012, 07:52
I am far from a DirectX or video programming expert. I'm probably not even novice level. Before last week, I'd never seen any shader code. The last time I did any video code was probably close to 25 years ago on the old Amiga computers.

When I started this I was writing the shader code in the shader assembly langauge. My son told me about the C-style shader code that was available for it... Though I tend to prefer assembly languages, the C-style code sure makes the shaders easy.

Here are the shader routines for the SBS file formats. I called the first one "3D-SBS-DLP-CheckerBoard-Normal". It is for the case when the image on the left of the video frame is for the left eye, and the image on the right of the video frame is for the right eye. If the destination pixel calculation is even, we are placing a pixel that will be displayed to the left eye. For this one, if the destination pixel calculation is odd, we pull the source pixel from the right side.



// 3D-SBS-DLP-CheckerBoard-Normal
// Normal - The video image on the left is displayed to the left eye, on even offset pixels
// The video image on the right is displayed to the right eye, on odd offset pixels

// Instructions:
// "View" Menu -> "Shader Editor" Item
// Enter "3D-SBS-DLP-CheckerBoard-Normal" in the top left box, and press the "Enter" key.
// Select "ps_2_0" from the smaller top (on the middle / right)
// Paste in the code for th "3D-SBS-DLP-CheckerBoard-Normal" shader.
// Close the Shaders Editor (x in upper left, next to name)
// "Play" Menu -> "Shaders" Sub-Menu Item -> "Select Shaders..." Item
// Check the "Enable post-resize pixel shaders" checkbox
// Click once in the window under the "Enable post-resize pixel shaders"
// select the "3D-SBS-DLP-CheckerBoard-Normal" shader from the drop down list on the top
// Click the "Add" button
// Click the "OK" button
// ps_2_0


sampler s0 : register(s0);
float4 p0 : register(c0);
float4 p1 : register(c1);
float4 p2 : register(c2);

#define width (p0[0]) // These 2 values are used in combination with the monitor_* values
#define height (p0[1]) // to determine if the destination pixel is on an odd or even offset
#define counter (p0[2]) // These 2 values are not used in this shader
#define clock (p0[3])
#define one_over_width (p1[0]) // These 2 values are used to calculate integer pixel offsets and
#define one_over_height (p1[1]) // to reposition the pixel offsets to the center of the source pixel
#define monitor_top (p1[2]) // These 2 values are used to determine if the output pixel
#define monitor_left (p1[3]) // is displayed to the right or left eye
#define video_left (p2[0]) // These 2 values are used for SBS, to calculate where
#define video_width (p2[1]) // to pull the source pixel from...
#define video_top (p2[2]) // These 2 values are used for TAB, to calculate where
#define video_height (p2[3]) // to pull the source pixel from...

#define PI acos(-1)

float4 main(float2 tex : TEXCOORD0) : COLOR
{
// Default the output color to the color of the pixel at the current coordinate
float4 output = tex2D(s0, tex);

// Integer math will be slower on a VPU but it will eliminate any possiblity of round off errors
int iCurPixel = tex.x / one_over_width;

// This value is used in combination with the video_left value, to be sure we don't change any of
// pixels that don't contain actual video data
int iVideoRight = video_left + video_width;

// If we are currently putting a pixel on the screen, that contains video image data
// Then figure out where we need to get the pixel from
if( ( iCurPixel > video_left ) && ( iCurPixel <= iVideoRight ) )
{
// Calculate a pixel offset into the frame on the left side of the video data
int iPixelOffset = ( ( iCurPixel - video_left ) / 2 ) + video_left; // Don't round up!

// Check to see if we need to be using data from the frame on the right side of the video data
if( (monitor_top+monitor_left+(int)(tex.y * height)+(int)(tex.x * width)) % 2 == 1 )
{
// Adjust the pixel offset, in to the video frame on the right side of the video data
iPixelOffset += (int)(video_width / 2);
}

// Use this 1/2 pixel width value to center our X coordinate over the pixel data,
// so we don't get color bleed
float fHalfPixelWidth = one_over_width / 2;

// Adjust the X coordinate of the source color to the correct side of the video image
// using the pixel offset we just calculated, and apply 1/2 pixel offset, so we don't
// get color bleed
// Since we didn't modify the Y coordinate, we can hopefully assume it is already at the center
// of the pixel
float2 Color = tex;
Color.x = clamp( ( iPixelOffset * one_over_width ) + fHalfPixelWidth, 0.0f,1.0f) ;

// Replace the default pixel color with the pixel color from the location we just calculated
output = tex2D(s0, Color);
}

return output;
}



This is the second one. I call this one "3D-SBS-DLP-CheckerBoard-Reversed". It is for the case when the image on the left of the video frame is for the right eye, and the image on the right of the video frame is for the left eye. In the actual code, there is literally only 1 byte that is different than the code in the first one. If the destination pixel calculation is even, we are placing a pixel that will be displayed to the left eye. For this one, if the destination pixel calculation is even, we pull the source pixel from the right side.



// 3D-SBS-DLP-CheckerBoard-Reversed
// Reversed - The video image on the right is displayed to the left eye, on even offset pixels
// The video image on the left is displayed to the right eye, on odd offset pixels

// Instructions:
// "View" Menu -> "Shader Editor" Item
// Enter "3D-SBS-DLP-CheckerBoard-Reversed" in the top left box, and press the "Enter" key.
// Select "ps_2_0" from the smaller top (on the middle / right)
// Paste in the code for th "3D-SBS-DLP-CheckerBoard-Reversed" shader.
// Close the Shaders Editor (x in upper left, next to name)
// "Play" Menu -> "Shaders" Sub-Menu Item -> "Select Shaders..." Item
// Check the "Enable post-resize pixel shaders" checkbox
// Click once in the window under the "Enable post-resize pixel shaders"
// select the "3D-SBS-DLP-CheckerBoard-Reversed" shader from the drop down list on the top
// Click the "Add" button
// Click the "OK" button
// ps_2_0


sampler s0 : register(s0);
float4 p0 : register(c0);
float4 p1 : register(c1);
float4 p2 : register(c2);

#define width (p0[0]) // These 2 values are used in combination with the monitor_* values
#define height (p0[1]) // to determine if the destination pixel is on an odd or even offset
#define counter (p0[2]) // These 2 values are not used in this shader
#define clock (p0[3])
#define one_over_width (p1[0]) // These 2 values are used to calculate integer pixel offsets and
#define one_over_height (p1[1]) // to reposition the pixel offsets to the center of the source pixel
#define monitor_top (p1[2]) // These 2 values are used to determine if the output pixel
#define monitor_left (p1[3]) // is displayed to the right or left eye
#define video_left (p2[0]) // These 2 values are used for SBS, to calculate where
#define video_width (p2[1]) // to pull the source pixel from...
#define video_top (p2[2]) // These 2 values are used for TAB, to calculate where
#define video_height (p2[3]) // to pull the source pixel from...

#define PI acos(-1)

float4 main(float2 tex : TEXCOORD0) : COLOR
{
// Default the output color to the color of the pixel at the current coordinate
float4 output = tex2D(s0, tex);

// Integer math will be slower on a VPU but it will eliminate any possiblity of round off errors
int iCurPixel = tex.x / one_over_width;

// This value is used in combination with the video_left value, to be sure we don't change any of
// pixels that don't contain actual video data
int iVideoRight = video_left + video_width;

// If we are currently putting a pixel on the screen, that contains video image data
// Then figure out where we need to get the pixel from
if( ( iCurPixel > video_left ) && ( iCurPixel <= iVideoRight ) )
{
// Calculate a pixel offset into the frame on the left side of the video data
int iPixelOffset = ( ( iCurPixel - video_left ) / 2 ) + video_left; // Don't round up!

// Check to see if we need to be using data from the frame on the right side of the video data
if( (monitor_top+monitor_left+(int)(tex.y * height)+(int)(tex.x * width)) % 2 == 0 )
{
// Adjust the pixel offset, in to the video frame on the right side of the video data
iPixelOffset += (int)(video_width / 2);
}

// Use this 1/2 pixel width value to center our X coordinate over the pixel data,
// so we don't get color bleed
float fHalfPixelWidth = one_over_width / 2;

// Adjust the X coordinate of the source color to the correct side of the video image
// using the pixel offset we just calculated, and apply 1/2 pixel offset, so we don't
// get color bleed
// Since we didn't modify the Y coordinate, we can hopefully assume it is already at the center
// of the pixel
float2 Color = tex;
Color.x = clamp( ( iPixelOffset * one_over_width ) + fHalfPixelWidth, 0.0f,1.0f) ;

// Replace the default pixel color with the pixel color from the location we just calculated
output = tex2D(s0, Color);
}

return output;
}



When creating a DLP Checkerboard output frame, we really don't want the colors of the adjacent pixels to be blended together. The TI DLP chip will be separating the odd and even pixels, to form 2 separate right and left eye video frames, that are displayed consecutively. Though they are right and left eye images of the same scene, the video separation created by the distance to the elements in the frame, could create drastically different colored pixels adjacent to each other in the checkerboard pattern. Those pixels need to maintain their original colors in the final right and left eye frames. So keeping the pixels as close to their original colors as possible is very important. So it sounds like the "Nearest Neighbor" setting is exactly what I need...

turbojet
7th August 2012, 13:15
Thanks for the tip. I took a look at autohotkey but it seems to be missing some key abilities:

-I don't think I can use it to extract info about the currently playing MPC file: filename, current position, etc... Thats really important here.

You can get filename from the window title. Elapsed and total time from static2 class.

-Also, I would like the hot keys to be available only while an MPC window is active. But, from what I can tell, autohotkey only lets you assign hot keys globally. That's a big problem if we want to use plain letters like 'A' 'B' 'C' as hotkeys in MPC.

#IfWinActive, ahk_class MediaPlayerClassicW
will restrict hotkeys to MPC-HC

JanWillem32
7th August 2012, 18:08
@TheCatcher: DirectX 9 only allows integers for the loop counter register, the rest are always floats: http://msdn.microsoft.com/en-us/library/windows/desktop/bb219858%28v=vs.85%29.aspx . The HLSL compiler in DirectX 9 mode can generate operations for floating-point that are usually integer-only. (You can check the output assembly of the compiler.)
Even under DirectX 10 rules, the hardware is required to support all integer operands, but may emulate the arithmetic operations using the floating-point units.
I used your code as a template. This is probably not a fully optimized version yet, but may help you further: (It only works in full screen for the trunk build. For my builds, it needs a window aligned on even pixel offsets, and video filling the width of the visible window.)sampler s0;
float2 c0;
float2 pc1;// temp, remove on final

// prototyped, resolve for final
//float4 c1;
//float4 c2;
/*
c0.x These 2 values are used in combination with the monitor_* values
c0.y to determine if the destination pixel is on an odd or even offset
c1.x These 2 values are used to calculate integer pixel offsets and
c1.y to reposition the pixel offsets to the center of the source pixel
c1.z These 2 values are used to determine if the output pixel
c1.w is displayed to the right or left eye
c2.x These 2 values are used for SBS, to calculate where
c2.y to pull the source pixel from...
c2.z These 2 values are used for TAB, to calculate where
c2.w to pull the source pixel from...
*/
float4 main(float2 tex : TEXCOORD0) : COLOR
{
float4 c1 = {pc1, 0, 0};// temp, remove on final
float4 c2 = {0, c0.x, 0, c0.y};// temp, remove on final

float2 CurPixel = tex * c0;
float VideoRight = c2.x + c2.y;

// If we are currently putting a pixel on the screen, that contains video image data
// Then figure out where we need to get the pixel from
// these compares probably could use an epsilon, else using VPOS would make it easier
if((CurPixel.x >= c2.x) && (CurPixel.x <= VideoRight)) {
float ox = tex.x-c1.x*c2.x;// normalized video-relative x position
float PixelOffset = -.5*ox;// the two images are half-width, compensate for that

float2 MonitorPos = CurPixel+c2.xz;// to monitor-relative coordinates
// Check to see if we need to be using data from the frame on the right side of the video data
float2 n = frac(MonitorPos*.5);

// Adjust the pixel offset, in to the video frame on the right side of the video data where required
if(n.x >= .5) {
PixelOffset -= c1.x*.5;// round half-pixel offsets down
if(n.y < .5) PixelOffset += c1.x*.5*c2.y;}
else if(n.y >= .5) PixelOffset += c1.x*.5*c2.y;

// Adjust the X coordinate of the source color to the correct side of the video image
// using the pixel offset we just calculated
tex.x += PixelOffset;}

return tex2D(s0, tex);
}I don't mind changing the renderers to include these extra variables. Adding the top-left corner relative to monitor position in c1.zw is perfectly fine, but I do prefer the conventional left-top-right-bottom or left-top-width-height order for the video area in c2.xyzw.

Reino
7th August 2012, 20:03
I'm considering doing a simple log viewer for people that prefer using the old fashioned build number.Unless you can append MPC-HC's build number on Github (1.6.3.5757 (8701ded349) for instance would be a lot better), I would very much welcome that.

TheCatcher
8th August 2012, 07:07
I don't mind changing the renderers to include these extra variables. Adding the top-left corner relative to monitor position in c1.zw is perfectly fine, but I do prefer the conventional left-top-right-bottom or left-top-width-height order for the video area in c2.xyzw.

Sounds great, I will modify my shader code and the parameter passing to put the offets to the video data (in C2) in left-top-width-height order.

I got the Pixel Shaders for Top And Bottom (TAB) 3D file format to 3D DLP Checkerboard working today. And while I was doing it, I identified a problem with my SBS Pixel Shaders.

The only code byte different between the two SBS shaders, is backwards. The SBS Normal Shader's modulo 2 compare should be to 0, not 1. And the SBS Reversed Shader's modulo 2 compare should be to 1, not 0.

Logically this change doesn't make sense to me. But it turned out the source SBS video I was using was reversed. So, though logically it doesn't make sense. The reality of it is that it works correctly after making this change. And the TAB 3D file format works this way also.

So the only conclusions I can come up with are...

1. One of the four variables that I am adding up to perform the modulo 2 on, must contain a relative 1 value, instead of a relative 0 value.

2. Somehow one of the (int) conversion on the tex.x and tex.y multiplies by the width and height of the textures are ending up one number higher than they should be...

Or

3. My video card settings are offset from the HDTV by one pixel... Which doesn't make sense, because the NVidia software required me to use its reversed mode for this reversed SBS file also...

I haven't seen the source code to other 3D SBS and TAB video players... maybe this is just the way it is - modulo 0 when it seems like it should be modulo 1, and vice versa...

None of these options makes sense to me. I will look into this later in the week, when I get another chance to play with the code.

Here is the working Pixel Shader code for the Normal Top and Bottom conversion to DLP Checkerboard format (Normal being left eye's image on top).



// 3D-TAB-DLP-CheckerBoard-Normal
// Normal - The video image on the top is displayed to the left eye, on even offset pixels
// The video image on the bottom is displayed to the right eye, on odd offset pixels

// Instructions:
// "View" Menu -> "Shader Editor" Item
// Enter "3D-TAB-DLP-CheckerBoard-Normal" in the top left box, and press the "Enter" key.
// Select "ps_2_0" from the smaller top (on the middle / right)
// Paste in the code for th "3D-TAB-DLP-CheckerBoard-Normal" shader.
// Close the Shaders Editor (x in upper left, next to name)
// "Play" Menu -> "Shaders" Sub-Menu Item -> "Select Shaders..." Item
// Check the "Enable post-resize pixel shaders" checkbox
// Click once in the window under the "Enable post-resize pixel shaders"
// select the "3D-TAB-DLP-CheckerBoard-Normal" shader from the drop down list on the top
// Click the "Add" button
// Click the "OK" button
// ps_2_0


sampler s0 : register(s0);
float4 p0 : register(c0);
float4 p1 : register(c1);
float4 p2 : register(c2);

#define width (p0[0]) // These 2 values are used in combination with the monitor_* values
#define height (p0[1]) // to determine if the destination pixel is on an odd or even offset
#define counter (p0[2]) // These 2 values are not used in this shader
#define clock (p0[3])
#define one_over_width (p1[0]) // These 2 values are used to calculate integer pixel offsets and
#define one_over_height (p1[1]) // to reposition the pixel offsets to the center of the source pixel
#define monitor_top (p1[2]) // These 2 values are used to determine if the output pixel
#define monitor_left (p1[3]) // is displayed to the right SBS, to calculate where
#define video_width (p2[1]) // to pull the source pixel from...
#define video_top (p2[2]) // These 2 values are used for TAB, to calculate where
#define video_height (p2[3]) // to pull the source pixel from...

#define PI acos(-1)

float4 main(float2 tex : TEXCOORD0) : COLOR
{
// Default the output color to the color of the pixel at the current coordinate
float4 output = tex2D(s0, tex);

// Integer math will be slower on a VPU but it will eliminate any possiblity of round off errors
int iCurPixel = tex.y / one_over_height;

// This value is used in combination with the video_top value, to be sure we don't change any of
// pixels that don't contain actual video data
int iVideoBottom = video_top + video_height;

// If we are currently putting a pixel on the screen, that contains video image data
// Then figure out where we need to get the pixel from
if( ( iCurPixel > video_top ) && ( iCurPixel <= iVideoBottom ) )
{
// Calculate a pixel offset into the frame on the top half of the video data
int iPixelOffset = ( ( iCurPixel - video_top ) / 2 ) + video_top; // Don't round up!

// Check to see if we need to be using data from the frame on the bottom half of the video data
if( (monitor_top+monitor_left+(int)(tex.y * height)+(int)(tex.x * width)) % 2 == 0 )
{
// Adjust the pixel offset, in to the video frame on the bottom half of the video data
iPixelOffset += (int)(video_height / 2);
}

// Use this 1/2 pixel width value to center our X coordinate over the pixel data,
// so we don't get color bleed
float fHalfPixelheight = one_over_height / 2;

// Adjust the Y coordinate of the source color to the correct half of the video image
// using the pixel offset we just calculated, and apply 1/2 pixel offset, so we don't
// get color bleed
// Since we didn't modify the X coordinate, we can hopefully assume it is already at the center
// of the pixel
float2 Color = tex;
Color.y = clamp( ( iPixelOffset * one_over_height ) + fHalfPixelheight, 0.0f,1.0f) ;

// Replace the default pixel color with the pixel color from the location we just calculated
output = tex2D(s0, Color);
}

return output;
}



Here is the working Reversed TAB Pixel Shader code.



// 3D-TAB-DLP-CheckerBoard-Reversed
// Reversed - The video image on the right is displayed to the left eye, on even offset pixels
// The video image on the left is displayed to the right eye, on odd offset pixels

// Instructions:
// "View" Menu -> "Shader Editor" Item
// Enter "3D-TAB-DLP-CheckerBoard-Reversed" in the top left box, and press the "Enter" key.
// Select "ps_2_0" from the smaller top (on the middle / right)
// Paste in the code for th "3D-TAB-DLP-CheckerBoard-Reversed" shader.
// Close the Shaders Editor (x in upper left, next to name)
// "Play" Menu -> "Shaders" Sub-Menu Item -> "Select Shaders..." Item
// Check the "Enable post-resize pixel shaders" checkbox
// Click once in the window under the "Enable post-resize pixel shaders"
// select the "3D-TAB-DLP-CheckerBoard-Reversed" shader from the drop down list on the top
// Click the "Add" button
// Click the "OK" button
// ps_2_0

sampler s0 : register(s0);
float4 p0 : register(c0);
float4 p1 : register(c1);
float4 p2 : register(c2);

#define width (p0[0]) // These 2 values are used in combination with the monitor_* values
#define height (p0[1]) // to determine if the destination pixel is on an odd or even offset
#define counter (p0[2]) // These 2 values are not used in this shader
#define clock (p0[3])
#define one_over_width (p1[0]) // These 2 values are used to calculate integer pixel offsets and
#define one_over_height (p1[1]) // to reposition the pixel offsets to the center of the source pixel
#define monitor_top (p1[2]) // These 2 values are used to determine if the output pixel
#define monitor_left (p1[3]) // is displayed to the right SBS, to calculate where
#define video_width (p2[1]) // to pull the source pixel from...
#define video_top (p2[2]) // These 2 values are used for TAB, to calculate where
#define video_height (p2[3]) // to pull the source pixel from...

#define PI acos(-1)

float4 main(float2 tex : TEXCOORD0) : COLOR
{
// Default the output color to the color of the pixel at the current coordinate
float4 output = tex2D(s0, tex);

// Integer math will be slower on a VPU but it will eliminate any possiblity of round off errors
int iCurPixel = tex.y / one_over_height;

// This value is used in combination with the video_top value, to be sure we don't change any of
// pixels that don't contain actual video data
int iVideoBottom = video_top + video_height;

// If we are currently putting a pixel on the screen, that contains video image data
// Then figure out where we need to get the pixel from
if( ( iCurPixel > video_top ) && ( iCurPixel <= iVideoBottom ) )
{
// Calculate a pixel offset into the frame on the top half of the video data
int iPixelOffset = ( ( iCurPixel - video_top ) / 2 ) + video_top; // Don't round up!

// Check to see if we need to be using data from the frame on the bottom half of the video data
if( (monitor_top+monitor_left+(int)(tex.y * height)+(int)(tex.x * width)) % 2 == 1 )
{
// Adjust the pixel offset, in to the video frame on the bottom half of the video data
iPixelOffset += (int)(video_height / 2);
}

// Use this 1/2 pixel width value to center our X coordinate over the pixel data,
// so we don't get color bleed
float fHalfPixelheight = one_over_height / 2;

// Adjust the Y coordinate of the source color to the correct half of the video image
// using the pixel offset we just calculated, and apply 1/2 pixel offset, so we don't
// get color bleed
// Since we didn't modify the X coordinate, we can hopefully assume it is already at the center
// of the pixel
float2 Color = tex;
Color.y = clamp( ( iPixelOffset * one_over_height ) + fHalfPixelheight, 0.0f,1.0f) ;

// Replace the default pixel color with the pixel color from the location we just calculated
output = tex2D(s0, Color);
}

return output;
}

JanWillem32
8th August 2012, 21:38
I think you missed the thing I noted before; DirectX 9 has no support for integers other than the loop counter. Not a single integer is used in the output assembly of your shaders. The integer modulo you put in the shader is approximated by doing many floating-point operations (most notable arithmetic saturation and extraction of the fractional component). The prototpe I posted has "float2 n = frac(MonitorPos*.5);", to only calculate a floating-point fractional part once, and use that directly. The FRC instruction is native to the assembly under PS 2.0 and onward rules: http://msdn.microsoft.com/en-us/library/windows/desktop/bb219854%28v=vs.85%29.aspx .

Integer modulo is expensive even on systems that do support it. For an x86 CPU, IDIV (signed) and DIV (unsigned) instructions are used to perform division (to the RAX[64-bit], EAX[32-bit], AX[16-bit] or AL[8-bit] register) and modulo (to the RDX, EDX, DX or AH register) simultaneously. It can take up to 197 clocks to perform. For calculating modulo of x with a right-hand operand of 2, 4, 8 and 16, we optimize using the single-clock AND/TEST instruction: x & 1, x & 3, x & 7, x & 15. I haven't seen a compiler do this optimization yet. So, the standard tests for odd and even are: "if(x&1) {" (TEST reg 1, JZ label) and "if(!(x&1)) {" (TEST reg 1, JNZ label).

betaking
9th August 2012, 00:43
S.Chinese update
http://www.mediafire.com/?j2grwjyp6ivy4jj

TheCatcher
9th August 2012, 16:45
Yep, I missed that point... I've made the changes, switched all the artificial ints over to floats, modified the modulo 2 code to be a

if (value - float(value) < 0.5f)

for normal and

if (value - float(value) >= 0.5f)

for reversed.

Also changed the passed in offsets to the video to be left-top-width-height.

The size went from over 60 slots / instructions to around 30. It still seems to be backwards. I will figure out what is up with that later this week.

JanWillem32
9th August 2012, 20:02
I optimized the primary SBS to checkerboard pixel shader:sampler s0;
float2 c0;
float4 c1;
float4 c2;
/*
c0.x screen width These 2 values are used in combination with the monitor-relative values to determine if the destination pixel is on an odd or even offset
c0.y screen height
c1.x 1/screen width These 2 values are used to calculate whole pixel offsets relative to the normalized space
c1.y 1/screen height
c1.z window left to monitor These 2 values are used to determine if the output pixel is displayed to the right or left eye
c1.w window top to monitor
c2.x video left to window These 2 values are used for SBS, to calculate where to pull the source pixel from...
c2.z video width
c2.y video top to window These 2 values are used for TAB, to calculate where to pull the source pixel from...
c2.w video height
For this shader to work correctly, the video width on screen has to be an even amount.*/

float4 main(float2 tex : TEXCOORD0) : COLOR
{
float2 CurPixel = tex*c0;
float VideoRight = c2.x+c2.z;

// If we are currently putting a pixel on the screen, that contains video image data
// Then figure out where we need to get the pixel from
// these compares probably could use an epsilon, else using VPOS would make it easier
if((CurPixel.x >= c2.x) && (CurPixel.x <= VideoRight)) {
float ox = CurPixel.x-c2.x;// video-relative x position
float PixelOffset = floor(-.5*ox);// the two images are half-width, compensate for that, round half-pixel offsets down

float2 MonitorPos = CurPixel-c2.xy;// to monitor-relative coordinates
// Check to see if we need to be using data from the frame on the right side of the video data
float n = frac(dot(1, MonitorPos)*.5-.25);
// Adjust the pixel offset, in to the video frame on the right side of the video data where required
if(n >= .5) PixelOffset += .5*c2.z;

// Adjust the X coordinate of the source position to the correct side of the video image using the pixel offset we just calculated
tex.x += PixelOffset*c1.x;}

return tex2D(s0, tex);
}This code compiles to 1 sampling and 19 arithmetic instructions under PS 3.0 rules. When not using the new variables in the registers (the non-adaptive state), it's 1 sampling and 18 arithmetic instructions:sampler s0;
float2 c0;
float2 pc1;// temp, remove on final

// prototyped, resolve for final
//float4 c1;
//float4 c2;
/*
c0.x screen width These 2 values are used in combination with the monitor-relative values to determine if the destination pixel is on an odd or even offset
c0.y screen height
c1.x 1/screen width These 2 values are used to calculate whole pixel offsets relative to the normalized space
c1.y 1/screen height
c1.z window left to monitor These 2 values are used to determine if the output pixel is displayed to the right or left eye
c1.w window top to monitor
c2.x video left to window These 2 values are used for SBS, to calculate where to pull the source pixel from...
c2.z video width
c2.y video top to window These 2 values are used for TAB, to calculate where to pull the source pixel from...
c2.w video height
For this shader to work correctly, the video width on screen has to be an even amount.*/

float4 main(float2 tex : TEXCOORD0) : COLOR
{
float4 c1 = {pc1, 0, 0};// temp, remove on final
float4 c2 = {0, 0, c0};// temp, remove on final

float2 CurPixel = tex*c0;
float VideoRight = c2.x+c2.z;

// If we are currently putting a pixel on the screen, that contains video image data
// Then figure out where we need to get the pixel from
// these compares probably could use an epsilon, else using VPOS would make it easier
if((CurPixel.x >= c2.x) && (CurPixel.x <= VideoRight)) {
float ox = CurPixel.x-c2.x;// video-relative x position
float PixelOffset = floor(-.5*ox);// the two images are half-width, compensate for that, round half-pixel offsets down

float2 MonitorPos = CurPixel-c2.xy;// to monitor-relative coordinates
// Check to see if we need to be using data from the frame on the right side of the video data
float n = frac(dot(1, MonitorPos)*.5-.25);

// Adjust the pixel offset, in to the video frame on the right side of the video data where required
if(n >= .5) PixelOffset += .5*c2.z;

// Adjust the X coordinate of the source position to the correct side of the video image using the pixel offset we just calculated
tex.x += PixelOffset*c1.x;}

return tex2D(s0, tex);
}

jffulcrum
10th August 2012, 21:20
Have some misunderstanding of the DXVA support for WMV3 (VC-1) in MPC-HC after about 5000 builds. With one video DXVA in MPC Video Decoder with all checks skipped is not in use:

MediaInfo:
ID : 2
Format : VC-1
Format profile : MP@ML
Codec ID : WMV3
Codec ID/Info : Windows Media Video 9
Codec ID/Hint : WMV3
Description of the codec : Windows Media Video 9
Duration : 4mn 25s
Bit rate mode : Variable
Bit rate : 1 500 Kbps
Width : 696 pixels
Height : 412 pixels
Display aspect ratio : 16:9
Frame rate : 25.000 fps
Bit depth : 8 bits
Scan type : Progressive
Compression mode : Lossy
Bits/(Pixel*Frame) : 0.209
Stream size : 47.5 MiB (84%)

Here is what DXVA Checker utility trace have during playback in MPC-HC:
DXVA2_ProcessDeviceDestroyed, 1800, 00:00:03.1345956
DXVA2_ProcessDeviceDestroyed, 1800, 00:00:03.1347092
DXVA2_ProcessDeviceCreated, mpc-hc64, 00:00:08.6857561
DXVA2_ProcessDeviceCreated, mpc-hc64, 00:00:08.6858225
DXVA2_ProcessDeviceDestroyed, mpc-hc64, 00:00:08.7013206
DXVA2_ProcessDeviceDestroyed, mpc-hc64, 00:00:08.7013597
DXVA2_ProcessDeviceCreated, mpc-hc64, 00:00:08.7521071
DXVA2_ProcessDeviceCreated, mpc-hc64, 00:00:08.7521567
DXVA2_ProcessBlt, mpc-hc64, 00:00:08.7534609
DXVA2_ProcessBlt, mpc-hc64, 00:00:08.7574633
DXVA2_ProcessBlt, mpc-hc64, 00:00:08.7604663
DXVA2_ProcessBlt, mpc-hc64, 00:00:08.7624646
DXVA2_ProcessBlt, mpc-hc64, 00:00:08.7644756

The last device created is a 'Device: BobDevice RenderTarget: NV12 Size: 768x412' - so no DXVA decoding

Here is another video, with working DXVA:

ID : 2
Format : VC-1
Format profile : MP@HL
Codec ID : WMV3
Codec ID/Info : Windows Media Video 9
Codec ID/Hint : WMV3
Description of the codec : Windows Media Video 9 - Professional
Duration : 1mn 3s
Bit rate mode : Constant
Bit rate : 11.0 Mbps
Width : 1 280 pixels
Height : 720 pixels
Display aspect ratio : 16:9
Frame rate : 29.970 fps
Bit depth : 8 bits
Scan type : Progressive
Compression mode : Lossy
Bits/(Pixel*Frame) : 0.398
Stream size : 83.6 MiB

And the trace is:

DXVA2_ProcessDeviceCreated, mpc-hc64, 00:00:03.8030614
DXVA2_ProcessDeviceCreated, mpc-hc64, 00:00:03.8031243
DXVA2_DecodeDeviceCreated, mpc-hc64, 00:00:03.8093286
DXVA2_DecodeDeviceBeginFrame, mpc-hc64, 00:00:03.8334641
DXVA2_DecodeDeviceGetBuffer, mpc-hc64, 00:00:03.8370296
DXVA2_DecodeDeviceGetBuffer, mpc-hc64, 00:00:03.8370321
DXVA2_DecodeDeviceGetBuffer, mpc-hc64, 00:00:03.8370349
DXVA2_DecodeDeviceExecute, mpc-hc64, 00:00:03.8370383
DXVA2_DecodeDeviceEndFrame, mpc-hc64, 00:00:03.8370771
DXVA2_DecodeDeviceBeginFrame, mpc-hc64, 00:00:03.8387586
DXVA2_DecodeDeviceGetBuffer, mpc-hc64, 00:00:03.8387688
DXVA2_DecodeDeviceGetBuffer, mpc-hc64, 00:00:03.8387716
DXVA2_DecodeDeviceGetBuffer, mpc-hc64, 00:00:03.8387775
DXVA2_DecodeDeviceExecute, mpc-hc64, 00:00:03.8387788
DXVA2_DecodeDeviceEndFrame, mpc-hc64, 00:00:03.8387936
DXVA2_DecodeDeviceBeginFrame, mpc-hc64, 00:00:03.8389860
DXVA2_DecodeDeviceGetBuffer, mpc-hc64, 00:00:03.8389922
DXVA2_DecodeDeviceGetBuffer, mpc-hc64, 00:00:03.8389932
DXVA2_DecodeDeviceGetBuffer, mpc-hc64, 00:00:03.8389950
DXVA2_DecodeDeviceExecute, mpc-hc64, 00:00:03.8389956
DXVA2_DecodeDeviceEndFrame, mpc-hc64, 00:00:03.8390025
DXVA2_DecodeDeviceBeginFrame, mpc-hc64, 00:00:03.8392582
DXVA2_DecodeDeviceGetBuffer, mpc-hc64, 00:00:03.8392650
DXVA2_DecodeDeviceGetBuffer, mpc-hc64, 00:00:03.8392662
DXVA2_DecodeDeviceGetBuffer, mpc-hc64, 00:00:03.8392678
DXVA2_DecodeDeviceExecute, mpc-hc64, 00:00:03.8392687
DXVA2_DecodeDeviceEndFrame, mpc-hc64, 00:00:03.8392762
DXVA2_DecodeDeviceBeginFrame, mpc-hc64, 00:00:03.8395024
DXVA2_DecodeDeviceBeginFrame, mpc-hc64, 00:00:03.8427427
DXVA2_DecodeDeviceBeginFrame, mpc-hc64, 00:00:03.8467446
DXVA2_DecodeDeviceBeginFrame, mpc-hc64, 00:00:03.8507470
DXVA2_DecodeDeviceGetBuffer, mpc-hc64, 00:00:03.8507579
DXVA2_DecodeDeviceGetBuffer, mpc-hc64, 00:00:03.8507597
DXVA2_DecodeDeviceGetBuffer, mpc-hc64, 00:00:03.8507666
DXVA2_DecodeDeviceExecute, mpc-hc64, 00:00:03.8507678
DXVA2_DecodeDeviceEndFrame, mpc-hc64, 00:00:03.8507815
DXVA2_DecodeDeviceBeginFrame, mpc-hc64, 00:00:03.8508879
DXVA2_DecodeDeviceBeginFrame, mpc-hc64, 00:00:03.8547464
DXVA2_DecodeDeviceGetBuffer, mpc-hc64, 00:00:03.8547554
DXVA2_DecodeDeviceGetBuffer, mpc-hc64, 00:00:03.8547563
DXVA2_DecodeDeviceGetBuffer, mpc-hc64, 00:00:03.8547728
DXVA2_DecodeDeviceExecute, mpc-hc64, 00:00:03.8547740
DXVA2_DecodeDeviceEndFrame, mpc-hc64, 00:00:03.8547914
DXVA2_DecodeDeviceBeginFrame, mpc-hc64, 00:00:03.8549084
DXVA2_ProcessBlt, mpc-hc64, 00:00:03.8557654

And the last device created is: 'Device: ModeVC1_VLD Size: 1280x720'

With both videos DXVA Checker 'Check Decoders' button results with this:
[DS] WMVideo Decoder DMO [DXVA1] [WMV3 696x412]
-
[MF] WMVideo Decoder MFT [DXVA2] [WMV3 696x412]
ModeVC1_VLD2010: DXVA2
ModeVC1_VLD: DXVA2
ModeVC1_IDCT: DXVA2
ModeWMV9_IDCT: DXVA2
ModeVC1_MoComp: DXVA2
ModeWMV9_MoComp: DXVA2
ModeVC1_PostProc: DXVA2
ModeWMV9_PostProc: DXVA2

ModeVC1_VLD2010: DXVA2 is marked red and is actually used as Decode Device if select 'Play' - and the CPU load is zero even with only one core active.

System is Win7 Pro x64, video board is a NVIDIA GTX 590 with 304.79 Driver.

Is videos with resolutions below 1280 is just banned from DXVA in MPC-HC after https://github.com/mpc-hc/mpc-hc/commit/ad48e5edf7eb5674f888a51f53bd3e866ce93fc1 commit? Cause the 4992 build from http://www.xvidvideo.ru/media-player-classic-home-cinema-x86-x64/media-player-classic-homecinema-x86-x64-1-6-3-4992.html use DXVA with both files.

v0lt
11th August 2012, 08:08
@jffulcrum

Most of WMV3 videos has problems when playing in DXVA mode, if the frame width is less or equal than 720.

Here runs a simple rule, if the format is WMV3, and frame width is less or equal than 720, then DXVA is not used. This rule is constant, it will not be optional.

MPC-HC v5349 or later.

bozek
11th August 2012, 09:42
What's up with the MPC-BE?

ryrynz
11th August 2012, 12:04
If your talking the MPC-BE project at sourceforge (http://sourceforge.net/projects/mpcbe/) it's a fork of MPC-HC currently in beta and only for selected beta testers, it's unknown if any of that code will ever make it into MPC-HC.

If your talking the old MPC-BE, some of it was already integrated into MPC-HC. Bobdynlan created a branch to refine and improve the UI to eventually be merged into MPC-HC.
When that will merge I don't know, he's been inactive for awhile now after creating the branch with no progress shown to date.

jffulcrum
11th August 2012, 18:58
v0lt

This rule is constant, it will not be optional.

But we already have 'Disable DXVA for SD' flag for H.264, why not to have the same for WMV3? I have some library of WMV3 videos and with 4992 all of them played normal in DXVA mode, even 2007 dated ones.

MPC-HC v5323

According to already given link https://github.com/mpc-hc/mpc-hc/commit/ad48e5edf7eb5674f888a51f53bd3e866ce93fc1 the 5323 commit was cancelled.

bozek
11th August 2012, 19:08
Well, no offense but I really don't care about the UI. The things that I do appreciate about the BE still haven't found their way in the 'standard' version. I'm talking about the ability to force 0-255 output or icons by filetype.

The BE mod is dead and the MPC-BE seems to have died before it was even born and if not, I don't really see the point for all the secretiveness. After all, it's supposed to be a GPL software... :confused:

r4in
11th August 2012, 21:56
Just a quick question: why is there still not implemented feature to play files that are being downloaded? Every other major players now support it. Honestly, who the hell cares about GUI, but this feature is a must. MPC used be my player of choice, but because of this, I am forced to use PotPlayer.

Thank you. Once it's implemented, you can count on me with donation.

v0lt
12th August 2012, 04:10
But we already have 'Disable DXVA for SD' flag for H.264, why not to have the same for WMV3?
This is a bad idea.

According to already given link https://github.com/mpc-hc/mpc-hc/commit/ad48e5edf7eb5674f888a51f53bd3e866ce93fc1 the 5323 commit was cancelled.
Excuse me. I mixed up the сhangeset number.
Changeset 5347 (http://sourceforge.net/apps/trac/mpc-hc/changeset/5347/)
Changeset 5349 (http://sourceforge.net/apps/trac/mpc-hc/changeset/5349/)

roytam1
12th August 2012, 07:54
TC/JA translations updated, please check them out!
http://sourceforge.net/apps/trac/mpc-hc/ticket/1644
http://sourceforge.net/apps/trac/mpc-hc/ticket/1647

Underground78
12th August 2012, 09:24
Unless you can append MPC-HC's build number on Github (1.6.3.5757 (8701ded349) for instance would be a lot better), I would very much welcome that.
I know that the hash is in the About dialog right? But I will probably do that when I find some times.

I'm talking about the ability to force 0-255 output or icons by filetype.
Isn't View > Renderer Settings > Output range > 0-255 what you are looking for?
As for the icons, I'm not sure I understand correctly but currently the icons are different for each extension. If it's not what you want but you have icons you love, it's pretty easy to build a custom icon lib.

Obveron
12th August 2012, 14:14
I wonder if it would be possible to accurately duplicate the OSD and right-click menus across the screen in situations when we put our 3DTVs into top-bottom/side-by-side. Obviously we'd have to manually select an option that tells MPC-HC we're putting our TV into a 3D mode, but it would allow us to control playback in 3D without the OSD being all messed up.

Reino
12th August 2012, 20:52
@ Underground78: I know about the About-dialog, but this is before downloading. At Github you can only see the hash-code and at XhmikosR's website (which appears to be offline atm :() only the build-code. If Github would show both, you would actually know what kind of MPC-HC build you're downloading.

nevcairiel
12th August 2012, 21:02
(which appears to be offline atm :()

Seems online to me, and since i'm hosting it, i think i would notice. :D