   Direct3D9/DirectShow/VMR9  IVMRImagePresenter9::PresentImage
  Hello, everybody!I am looking for some help by advices and code, about Direct3D9/DirectShow/VMR9.Environment: Windows XP x64, Visual Studio 2008 SP1, Windows SDK 6.0/6.1/7.0, DirectX SDK 2009/03.We have a main thread, running&rendering a Direct3D9/DXUT scene.Also we initiate a DirectShow thread by CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);We use a custom A/P based on IVMRSurfaceAllocator9 and IVMRImagePresenter9 interfaces.Windows SDK samples present a scene rendered directly from IVMRImagePresenter9::PresentImage thread.But our DirectShow/VMR9 threads are supposed to be helpers which should not perform any rendering calls.Thus, we have to pass the texture from that thread into the main thread, so that it can be used for rendering.The question is how to make it, how to pass the texture from IVMRImagePresenter9::PresentImage thread into main thread?   
Quote:Original post by KoichiSenadaWe use a custom A/P based on IVMRSurfaceAllocator9 and IVMRImagePresenter9 interfaces.Windows SDK samples present a scene rendered directly from IVMRImagePresenter9::PresentImage thread.But our DirectShow/VMR9 threads are supposed to be helpers which should not perform any rendering calls.Thus, we have to pass the texture from that thread into the main thread, so that it can be used for rendering.The question is how to make it, how to pass the texture from IVMRImagePresenter9::PresentImage thread into main thread?Well, if you've got your own allocator-presenter, your own PresentImage function should be getting called with a VMR9PresentationInfo struct, which contains the surface to present - you just need to copy that surface to your own surface which can be accessed by the main thread.   ;Quote:Original post by Evil SteveWell, if you've got your own allocator-presenter, your own PresentImage function should be getting called with a VMR9PresentationInfo struct, which contains the surface to present - you just need to copy that surface to your own surface which can be accessed by the main thread.Well, that's exactly what I know! But thank you. :)In my own PresentImage I have IDirect3DTexture9 texture.So how do I pass that texture to the main thread successfully?I suppose the question is how to make a proper use of CAutoLock and SmartPtr<IDirect3DTexture9>Any ideas?;Quote:Original post by KoichiSenadaIn my own PresentImage I have IDirect3DTexture9 texture.So how do I pass that texture to the main thread successfully?I suppose the question is how to make a proper use of CAutoLock and SmartPtr<IDirect3DTexture9>Any ideas?Ah, I see. If you're creating the device, then you'll have had to use the D3DCREATE_MULTITHREADED flag, which makes D3D take care of that stuff. You can just lock both surfaces and copy the contents (Or use StretchRect, UpdateSurface, etc). I wouldn't pass the surface pointer directly out of your DirectShow thread though.I've used DirectShow before, but I've not got as far as copying the pixel data around with VMR-9. In my system, I use a critical section to restrict access to a buffer containing the pixel data. Psuedocode:// Worker thread:PresentImage():   Enter critical section   Copy contents of frame into buffer   Leave critical sectionEnd PresentImage// Main thread:Render():   LockRect() top level of texture   Enter critical section   Copy contents of buffer into texture   Leave critical section   UnlockRect() for texture   Render with textureEnd PresentImageIn reality it's a bit more complicated because I have two buffers to reduce the time spent waiting for the other thread.   ;Quote:Original post by Evil SteveIn my system, I use a critical section to restrict access to a buffer containing the pixel data.In reality it's a bit more complicated because I have two buffers to reduce the time spent waiting for the other thread.It's clear that some use of critical sections is required.Though I supposed we could pass pointers to textures and that would be enough.Then I thought locking and copying textures would be enough.Now I see that some kind of buffers are required.What are those buffers? Byte arrays?;Quote:Original post by KoichiSenadaIt's clear that some use of critical sections is required.Though I supposed we could pass pointers to textures and that would be enough.Then I thought locking and copying textures would be enough.Now I see that some kind of buffers are required.What are those buffers? Byte arrays?The buffers I use are byte arrays. I only need to use them because DirectShow gives you raw bitmap data though, not surfaces.You may not need to use critical sections at all, since D3D will be doing that itself if you create the device - then you can just copy the contents of the surface into the texture and not need to worry about it being used across multiple threads.   ;Quote:Original post by Evil SteveThe buffers I use are byte arrays. I only need to use them because DirectShow gives you raw bitmap data though, not surfaces.What gives you raw bitmap data?IVMRImagePresenter9::PresentImage method gives you a VMR9PresentationInfo structure with a IDirect3DSurface9 *lpSurf.That surface seems to be something more convenient than an array of raw bitmap data bytes.So how do we pass that surface/texture to the main thread?Quote:Original post by Evil SteveYou may not need to use critical sections at all, since D3D will be doing that itself if you create the device - then you can just copy the contents of the surface into the texture and not need to worry about it being used across multiple threads.Can you please be more specific about the multithreading issue in this case?;Quote:Original post by KoichiSenadaQuote:Original post by Evil SteveThe buffers I use are byte arrays. I only need to use them because DirectShow gives you raw bitmap data though, not surfaces.What gives you raw bitmap data?The IMediaSample* interface passed to CBaseVideoRenderer::DoRenderSample() - although that's for plain DirectShow, not VMR-9.Quote:Original post by KoichiSenadaThat surface seems to be something more convenient than an array of raw bitmap data bytes.So how do we pass that surface/texture to the main thread?Yes, it's a D3D surface. A texture is a collection of 1 or more surfaces, and each surface is pretty much just pixel data.Quote:Original post by KoichiSenadaQuote:Original post by Evil SteveYou may not need to use critical sections at all, since D3D will be doing that itself if you create the device - then you can just copy the contents of the surface into the texture and not need to worry about it being used across multiple threads.Can you please be more specific about the multithreading issue in this case?In order to use a device from multiple threads, you must create it with the D3DCREATE_MULTITHREADED flag. Doing that tells D3D that it needs to lock the device for pretty much every function call, and makes access to it thread-safe.   