Ask a questionAsk a question
 

AnswerVMR9Allocator example question

  • Friday, November 06, 2009 4:05 PMDJGuy Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hey Guys,

    I have written a video mixer based on VMR9Allocator example. I have changed the code so that it renders to a flat 2D quad and besides that the only thing I have really changed is that I do my rendering in a separate thread rather than rendering inside the PresentImage method like the example does. 

    Everything seems to work great except that now while the video is playing I can see it flicker every now and again. It does not flicker at all in the original VMR9Allocator example. I have been stepping through my code for days and none of the direct3d calls are failing. I cannot figure out what could cause this little flicker every now and again. I can only guess that the flicker is somehow caused by the fact that I am rendering my scene in a separate thread.

    Does anyone have any ideas what the problem might be off the top your head? I'm just hoping that maybe someone has encountered this before and could help me out.

    Thanks

Answers

  • Friday, November 06, 2009 10:21 PMDJGuy Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    First of all thank you Chris for your response!

    Secondly I figured out how to solve the flickering by reviewing the MultiVMR9 sample code very closely. If I set the lpAllocInfo->dwFlags = VMR9AllocFlag_OffscreenSurface  parameter to in the  IVMRSurfaceAllocator9::InitializeDevice method instead of setting it to |= VMR9AllocFlag_TextureSurface  AND also do not call SetNumberOfStreams from the IID_IVMRFilterConfig9 interface then everything works when rendering from a separate thread. Otherwise you get flicker.

    I am not sure what the setting of the VMR9AllocFlag_OffscreenSurface  flag coupled with NOT calling SetNumberOfStreams does exactly, but it solves the flickering problem somehow.

    Anyway, hopefully my post will help others avoid over a weeks worth of debugging and stepping through code to find the solution :)

All Replies

  • Friday, November 06, 2009 7:57 PMChris P_MVPUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    As I understand it you should render only in the PresentImage method if you want to be in sync with the display.  If you render asynchronously then you are out of sync with the display refresh rate and will be subject to artifacts such as tearing and flicker.
    www.chrisnet.net
  • Friday, November 06, 2009 9:26 PMDJGuy Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Ok, that would definitely explain some of the behavior that I am experiencing. However, I just finished stepping through the MultiVMR9 sample code and in there Microsoft draws the video frames to a texture in PresentImage, and then uses a separate thread to render to the screen using D3D which is almost exactly what I am doing in my current code, but their example does NOT produce the flicker. 

    I have been comparing my code with that of the MultiVMR9 example to determine what it is they are doing different from my code, but I have not been able to find anything significant. 

    I realize that I could just copy Microsoft and use their MultiVMR9 example as a base, but honestly I would like to understand why their code works and mine doesn't. Also the MultiVMR9 sample's structure is just far more complicated than it needs to be concerning the number of layers/object classes and how they interact with one another. I would rather have a clean piece of code that will make sense.

    I will continue to dissect the MultiVMR9 code in hopes to solve this problem. In the mean time if anyone can give me anymore insight to what the MultiVMR9 code is doing to prevent the flicker/tearing that would be great. Thanks.

  • Friday, November 06, 2009 10:21 PMDJGuy Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    First of all thank you Chris for your response!

    Secondly I figured out how to solve the flickering by reviewing the MultiVMR9 sample code very closely. If I set the lpAllocInfo->dwFlags = VMR9AllocFlag_OffscreenSurface  parameter to in the  IVMRSurfaceAllocator9::InitializeDevice method instead of setting it to |= VMR9AllocFlag_TextureSurface  AND also do not call SetNumberOfStreams from the IID_IVMRFilterConfig9 interface then everything works when rendering from a separate thread. Otherwise you get flicker.

    I am not sure what the setting of the VMR9AllocFlag_OffscreenSurface  flag coupled with NOT calling SetNumberOfStreams does exactly, but it solves the flickering problem somehow.

    Anyway, hopefully my post will help others avoid over a weeks worth of debugging and stepping through code to find the solution :)
  • Friday, November 06, 2009 11:00 PMChris P_MVPUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    By not calling SetNumberOfStreams the VMR isn't placed into mixing mode.

    By using VMR9AllocFlag_OffscreenSurface you are preventing the use of the overlay surface.

    Not sure why that particular combination was giving you grief, but interesting that it yielded the solution.

    www.chrisnet.net