Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > Hardware & Software > Software players

Closed Thread
 
Thread Tools Search this Thread Display Modes
Old 6th August 2012, 03:24   #20021  |  Link
TheCatcher
Registered User
 
Join Date: Jul 2012
Posts: 7
Quote:
Originally Posted by JanWillem32 View Post
@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.

Quote:
The usage of GetWindowPlacement() is wrong for when your window is a layered item: http://msdn.microsoft.com/en-us/libr...=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.

Quote:
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/libr...=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.

Code:
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.



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



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.





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
TheCatcher is offline  
Old 6th August 2012, 08:00   #20022  |  Link
betaking
Fantasy Codecs writer
 
betaking's Avatar
 
Join Date: Nov 2007
Location: Yang Zhou,Jiang Su,China
Posts: 392
S.Chinese update
http://www.mediafire.com/?ccx5kgxaugmpj7n
betaking is offline  
Old 6th August 2012, 10:37   #20023  |  Link
ryrynz
Registered User
 
ryrynz's Avatar
 
Join Date: Mar 2009
Posts: 3,650
Any major components left for 1.6.3 final?
ryrynz is offline  
Old 6th August 2012, 14:29   #20024  |  Link
TheCatcher
Registered User
 
Join Date: Jul 2012
Posts: 7
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:
Code:
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:
Code:
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.

Last edited by TheCatcher; 6th August 2012 at 14:31.
TheCatcher is offline  
Old 6th August 2012, 16:30   #20025  |  Link
JanWillem32
Registered User
 
JanWillem32's Avatar
 
Join Date: Oct 2010
Location: The Netherlands
Posts: 1,083
Quote:
Originally Posted by TheCatcher View Post
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.
Quote:
Originally Posted by TheCatcher View Post
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.
__________________
development folder, containing MPC-HC experimental tester builds, pixel shaders and more: http://www.mediafire.com/?xwsoo403c53hv

Last edited by JanWillem32; 6th August 2012 at 19:56. Reason: missed the per-pixel interleave part...
JanWillem32 is offline  
Old 6th August 2012, 20:37   #20026  |  Link
TheCatcher
Registered User
 
Join Date: Jul 2012
Posts: 7
Quote:
Originally Posted by JanWillem32 View Post
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...

Quote:
Originally Posted by JanWillem32 View Post
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.

Quote:
Originally Posted by JanWillem32 View Post
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.

Last edited by TheCatcher; 6th August 2012 at 20:39.
TheCatcher is offline  
Old 6th August 2012, 22:54   #20027  |  Link
JanWillem32
Registered User
 
JanWillem32's Avatar
 
Join Date: Oct 2010
Location: The Netherlands
Posts: 1,083
Quote:
Originally Posted by TheCatcher View Post
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.
Quote:
Originally Posted by TheCatcher View Post
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.
Quote:
Originally Posted by TheCatcher View Post
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.
Quote:
Originally Posted by TheCatcher View Post
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:
Code:
// (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
}
__________________
development folder, containing MPC-HC experimental tester builds, pixel shaders and more: http://www.mediafire.com/?xwsoo403c53hv
JanWillem32 is offline  
Old 7th August 2012, 07:18   #20028  |  Link
madshi
Registered Developer
 
Join Date: Sep 2006
Posts: 9,140
> 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.
madshi is offline  
Old 7th August 2012, 07:52   #20029  |  Link
TheCatcher
Registered User
 
Join Date: Jul 2012
Posts: 7
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.

Code:
// 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.

Code:
// 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...

Last edited by TheCatcher; 7th August 2012 at 08:26.
TheCatcher is offline  
Old 7th August 2012, 13:15   #20030  |  Link
turbojet
Registered User
 
Join Date: May 2008
Posts: 1,840
Quote:
Originally Posted by keneo View Post
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.

Quote:
-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
turbojet is offline  
Old 7th August 2012, 18:08   #20031  |  Link
JanWillem32
Registered User
 
JanWillem32's Avatar
 
Join Date: Oct 2010
Location: The Netherlands
Posts: 1,083
@TheCatcher: DirectX 9 only allows integers for the loop counter register, the rest are always floats: http://msdn.microsoft.com/en-us/libr...=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.)
Code:
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.
__________________
development folder, containing MPC-HC experimental tester builds, pixel shaders and more: http://www.mediafire.com/?xwsoo403c53hv
JanWillem32 is offline  
Old 7th August 2012, 20:03   #20032  |  Link
Reino
Registered User
 
Reino's Avatar
 
Join Date: Nov 2005
Posts: 693
Quote:
Originally Posted by Underground78 View Post
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.
__________________
My hobby website
Reino is offline  
Old 8th August 2012, 07:07   #20033  |  Link
TheCatcher
Registered User
 
Join Date: Jul 2012
Posts: 7
Quote:
Originally Posted by JanWillem32 View Post
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).

Code:
// 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.

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;
}
TheCatcher is offline  
Old 8th August 2012, 21:38   #20034  |  Link
JanWillem32
Registered User
 
JanWillem32's Avatar
 
Join Date: Oct 2010
Location: The Netherlands
Posts: 1,083
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/libr...=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).
__________________
development folder, containing MPC-HC experimental tester builds, pixel shaders and more: http://www.mediafire.com/?xwsoo403c53hv
JanWillem32 is offline  
Old 9th August 2012, 00:43   #20035  |  Link
betaking
Fantasy Codecs writer
 
betaking's Avatar
 
Join Date: Nov 2007
Location: Yang Zhou,Jiang Su,China
Posts: 392
S.Chinese update
http://www.mediafire.com/?j2grwjyp6ivy4jj
betaking is offline  
Old 9th August 2012, 16:45   #20036  |  Link
TheCatcher
Registered User
 
Join Date: Jul 2012
Posts: 7
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.
TheCatcher is offline  
Old 9th August 2012, 20:02   #20037  |  Link
JanWillem32
Registered User
 
JanWillem32's Avatar
 
Join Date: Oct 2010
Location: The Netherlands
Posts: 1,083
I optimized the primary SBS to checkerboard pixel shader:
Code:
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:
Code:
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);
}
__________________
development folder, containing MPC-HC experimental tester builds, pixel shaders and more: http://www.mediafire.com/?xwsoo403c53hv
JanWillem32 is offline  
Old 10th August 2012, 21:20   #20038  |  Link
jffulcrum
Registered User
 
Join Date: Aug 2006
Posts: 21
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:
Code:
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:
Code:
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:

Code:
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:

Code:
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:
Code:
[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.
jffulcrum is offline  
Old 11th August 2012, 08:08   #20039  |  Link
v0lt
Registered User
 
Join Date: Dec 2008
Posts: 1,968
@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.

Last edited by v0lt; 12th August 2012 at 04:12.
v0lt is offline  
Old 11th August 2012, 09:42   #20040  |  Link
bozek
Registered User
 
Join Date: Aug 2009
Posts: 61
What's up with the MPC-BE?
bozek is offline  
Closed Thread

Tags
dxva, h264, home cinema, media player classic, mpc-hc

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 12:37.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.