Discussion:
PRESENT, VMR and multiple threads in DX9
(too old to reply)
Frederik Anrys
2008-10-27 17:18:58 UTC
Permalink
Hi all,

I am currently facing big problems combining VMR and PRESENT in DX9.

Context:
1. A VMR9 Allocator-Presenter implementation rendering Video to a
TextureSurface using Hardware decoding in a DirectShow graph.

2. A Full screen DirectX application with PRESENT parameters on
PresentInterval.One. This application has a rendering thread which
renders the textures, generated by the VMR9 presenter.

So 1 thread is the VMR generating video frames in a texture. The
rendering thread is reading these frames and texturing them on a quad.




Problem:

If I call SwapChain.Present, I feel the gpu is completely locked/
stalled during the Wait for VSync. That way, my decoder fails to
decode its frames and my whole video playback is jerky. I perfectly
have 60fps in sync with the monitor.

If I set the presentation interval to Immediate, everything works
perfect! VMR9 is not blocked and continues to rendering to a texture.
Although, I can see terrible tearing artifacts while rendering the
video texture. I also can get very high framerates because I am using
a powerfull machine.

I tried almost all settings you can play with in the Present method,
but none seem to work decently!
I also watched the GetRasterStatus() method and wrote something like
this in my rendering thread.

RasterStatus rasterStatus =
allocator.Device.GetRasterStatus(swapChainID);

//Delta is a magic number. (=200).
while (!rasterStatus.InVBlank && (rasterStatus.ScanLine <=
MaxScanlines - Delta) )
{
Thread.Sleep(1);

rasterStatus = allocator.Device.GetRasterStatus(0);
}
swapChain.Present();



The problem with latest method is that the granularity of sleep is way
to coarse for accurately presenting without VSync in immediate mode.
In PresentInterval.One mode, it solves a bit of the problem, but not
in a way that will work in all cases.

Is there any way to sync on the VBlank of a monitor without stalling
the gpu or busy waiting?
I could find many people with problems like mine around the forums,
but none had good good results.

Anyone?

Thanks a lot,
Frederik
Michel Roujansky - Senior developer, Starfish Technologies Ltd
2008-11-01 09:35:29 UTC
Permalink
Post by Frederik Anrys
Hi all,
I am currently facing big problems combining VMR and PRESENT in DX9.
1. A VMR9 Allocator-Presenter implementation rendering Video to a
TextureSurface using Hardware decoding in a DirectShow graph.
2. A Full screen DirectX application with PRESENT parameters on
PresentInterval.One. This application has a rendering thread which
renders the textures, generated by the VMR9 presenter.
So 1 thread is the VMR generating video frames in a texture. The
rendering thread is reading these frames and texturing them on a quad.
If I call SwapChain.Present, I feel the gpu is completely locked/
stalled during the Wait for VSync. That way, my decoder fails to
decode its frames and my whole video playback is jerky. I perfectly
have 60fps in sync with the monitor.
If I set the presentation interval to Immediate, everything works
perfect! VMR9 is not blocked and continues to rendering to a texture.
Although, I can see terrible tearing artifacts while rendering the
video texture. I also can get very high framerates because I am using
a powerfull machine.
I tried almost all settings you can play with in the Present method,
but none seem to work decently!
I also watched the GetRasterStatus() method and wrote something like
this in my rendering thread.
 RasterStatus rasterStatus =
allocator.Device.GetRasterStatus(swapChainID);
 //Delta is a magic number. (=200).
 while (!rasterStatus.InVBlank && (rasterStatus.ScanLine <=
MaxScanlines - Delta) )
 {
     Thread.Sleep(1);
     rasterStatus = allocator.Device.GetRasterStatus(0);
 }
 swapChain.Present();
The problem with latest method is that the granularity of sleep is way
to coarse for accurately presenting without VSync in immediate mode.
In PresentInterval.One mode, it solves a bit of the problem, but not
in a way that will work in all cases.
Is there any way to sync on the VBlank of a monitor without stalling
the gpu or busy waiting?
I could find many people with problems like mine around the forums,
but none had good good results.
Anyone?
Thanks a lot,
Frederik
Did you have a look at the MultiVMR9 sample render engine in the DLL?
They also have a different thread for managing the D3D presentation.
I think the solution is to synchronize the VMR mixing and presentation
to the present main loop, i.e. not letting the VMR free-wheeling (but
still receving the frames at the correct rate).
Frederik
2008-11-06 09:23:41 UTC
Permalink
Post by Michel Roujansky - Senior developer, Starfish Technologies Ltd
Post by Frederik Anrys
Hi all,
I am currently facing big problems combining VMR and PRESENT in DX9.
1. A VMR9 Allocator-Presenter implementation rendering Video to a
TextureSurface using Hardware decoding in a DirectShow graph.
2. A Full screen DirectX application with PRESENT parameters on
PresentInterval.One. This application has a rendering thread which
renders the textures, generated by the VMR9 presenter.
So 1 thread is the VMR generating video frames in a texture. The
rendering thread is reading these frames and texturing them on a quad.
If I call SwapChain.Present, I feel the gpu is completely locked/
stalled during the Wait for VSync. That way, my decoder fails to
decode its frames and my whole video playback is jerky. I perfectly
have 60fps in sync with the monitor.
If I set the presentation interval to Immediate, everything works
perfect! VMR9 is not blocked and continues to rendering to a texture.
Although, I can see terrible tearing artifacts while rendering the
video texture. I also can get very high framerates because I am using
a powerfull machine.
I tried almost all settings you can play with in the Present method,
but none seem to work decently!
I also watched the GetRasterStatus() method and wrote something like
this in my rendering thread.
RasterStatus rasterStatus =
allocator.Device.GetRasterStatus(swapChainID);
//Delta is a magic number. (=200).
while (!rasterStatus.InVBlank && (rasterStatus.ScanLine <=
MaxScanlines - Delta) )
{
Thread.Sleep(1);
rasterStatus = allocator.Device.GetRasterStatus(0);
}
swapChain.Present();
The problem with latest method is that the granularity of sleep is way
to coarse for accurately presenting without VSync in immediate mode.
In PresentInterval.One mode, it solves a bit of the problem, but not
in a way that will work in all cases.
Is there any way to sync on the VBlank of a monitor without stalling
the gpu or busy waiting?
I could find many people with problems like mine around the forums,
but none had good good results.
Anyone?
Thanks a lot,
Frederik
Did you have a look at the MultiVMR9 sample render engine in the DLL?
They also have a different thread for managing the D3D presentation.
I think the solution is to synchronize the VMR mixing and presentation
to the present main loop, i.e. not letting the VMR free-wheeling (but
still receving the frames at the correct rate).
Idd, that is the only good solution! the example does not have a
reference implementation of this however.

I'll figure something out myself.

thx
Frederik
g012
2008-11-15 23:35:00 UTC
Permalink
Hey,

I'm having the exact same issue. And I have no idea how to synchronize with
the VMR mixing, since there is no callback / access to its processing. I did
try to lock with the rendering thread and unlock just before present, with a
Sleep(0), but the video still stalls.
It only works without jerkyness in IMMEDIATE mode, but even if I sleep to
reduce to 60 FPS, there is some tearing visible.

How do other people work around this ?
Post by Frederik
Post by Michel Roujansky - Senior developer, Starfish Technologies Ltd
Post by Frederik Anrys
Hi all,
I am currently facing big problems combining VMR and PRESENT in DX9.
1. A VMR9 Allocator-Presenter implementation rendering Video to a
TextureSurface using Hardware decoding in a DirectShow graph.
2. A Full screen DirectX application with PRESENT parameters on
PresentInterval.One. This application has a rendering thread which
renders the textures, generated by the VMR9 presenter.
So 1 thread is the VMR generating video frames in a texture. The
rendering thread is reading these frames and texturing them on a quad.
If I call SwapChain.Present, I feel the gpu is completely locked/
stalled during the Wait for VSync. That way, my decoder fails to
decode its frames and my whole video playback is jerky. I perfectly
have 60fps in sync with the monitor.
If I set the presentation interval to Immediate, everything works
perfect! VMR9 is not blocked and continues to rendering to a texture.
Although, I can see terrible tearing artifacts while rendering the
video texture. I also can get very high framerates because I am using
a powerfull machine.
I tried almost all settings you can play with in the Present method,
but none seem to work decently!
I also watched the GetRasterStatus() method and wrote something like
this in my rendering thread.
RasterStatus rasterStatus =
allocator.Device.GetRasterStatus(swapChainID);
//Delta is a magic number. (=200).
while (!rasterStatus.InVBlank && (rasterStatus.ScanLine <=
MaxScanlines - Delta) )
{
Thread.Sleep(1);
rasterStatus = allocator.Device.GetRasterStatus(0);
}
swapChain.Present();
The problem with latest method is that the granularity of sleep is way
to coarse for accurately presenting without VSync in immediate mode.
In PresentInterval.One mode, it solves a bit of the problem, but not
in a way that will work in all cases.
Is there any way to sync on the VBlank of a monitor without stalling
the gpu or busy waiting?
I could find many people with problems like mine around the forums,
but none had good good results.
Anyone?
Thanks a lot,
Frederik
Did you have a look at the MultiVMR9 sample render engine in the DLL?
They also have a different thread for managing the D3D presentation.
I think the solution is to synchronize the VMR mixing and presentation
to the present main loop, i.e. not letting the VMR free-wheeling (but
still receving the frames at the correct rate).
Idd, that is the only good solution! the example does not have a
reference implementation of this however.
I'll figure something out myself.
thx
Frederik
Loading...