0

I've been looking for a way to grab a frame from a video currently in the hardware overlay, and I've not found anything solid. Everything I find is either for grabbing frames from a video you are playing (in your app) or creating a filter to which I can't find a good example on how I would actually grab the frames in my app (or can the app be an in-memory filter that doesn't need to be "installed" and chosen in player?).

So, my question is how would I go about doing this? I know it's possible with a filter, I've seen it done, I just haven't seen how it's done. Is there a good example somewhere of how to grab frames in a filter and send them to my app? Or is there a way like, hook into some procedure call and get the frame from there somehow?

I've seen hooking done for DirectX to get all the DirectX info, but, hardware overlays are not DirectX, are they? Or can I just hook into DirectX and grab the front buffer from there or something?

I've been searching for resources on this issue but I keep going around in circles and the fact that there are people who want to put the overlays on DirectX surfaces doesn't help, a lot of the results are on that topic.

If it's relevant, I would prefer a solution in C++ (the app I have is in C++ and currently uses the "regular" way of grabbing screenshots from screen, which ofcourse leaves black rectangles for the hardware overlay).

slugster
  • 49,403
  • 14
  • 95
  • 145
Bikonja
  • 909
  • 5
  • 15

2 Answers2

0

There are two ways I know how to grab frames using directshow. The first one is with using the SampleGrabber filter there are many examples available in internet. The second one is with using your custom videorenderer in this case you have to implement your own filter you can use baceclasses project from platform sdk in order to derive from cbasevideorenderer and implement your render method.

AlexTheo
  • 4,004
  • 1
  • 21
  • 35
  • I would like to let the user decide which renderer he or she uses, this is the reason I need overlay grabbing (otherwise I could just say if you want to use this app, you need to use a software renderer). As for the SampleGrabber, on top of it on MSDN it says: "Note [Deprecated. This API may be removed from future releases of Windows.]" which worries me a little. – Bikonja Nov 17 '11 at 10:20
  • In case if you want to give to user a choice to select the output renderer you can use the infinitetee filter : http://msdn.microsoft.com/en-us/library/windows/desktop/dd390336(v=vs.85).aspx which will split your output to rendere and frame grabber filters. Otherwise with the sample grabber you have not any problem because it give you the opportunity to link any renderer you want after... – AlexTheo Nov 17 '11 at 11:12
  • I can't tell, does this method take the frame from overlay and then send it to both the renderer and my desired location (let's say memory accessible by my application) so the benefits of overlay are still there, with a small amount of cpu cycles used to send a copy of the image to another part of memory? If so, I have a follow-up question. How would I get the pins from which to and to which to redirect output to (both the original renderer I want to hook and my memory)? – Bikonja Nov 17 '11 at 12:17
  • No it doesn't send a copy but the same sample to the first renderer and after to the second one so you have a minimum of cpu effort in this case. Try it with graph studio with two renderers... – AlexTheo Nov 17 '11 at 12:28
  • After make wrappers for all of your filters. In infinite tee you will make 2 output pins, connect each of them to correct renderer. – AlexTheo Nov 17 '11 at 12:34
  • I tried placing the infinite tee in graph studio, but couldn't connect it to anything. – Bikonja Nov 17 '11 at 17:35
  • Make sure that you placed it between the renderer and decoder. Did you try it with the graphstudio?? – AlexTheo Nov 17 '11 at 17:45
  • Ah, yes, I connected it now. Okay, so my question is now, how would I programatically place my infinite pin tee filter between the decoder and renderer and how do I catch the frames in the second renderer? Do I need to extend the BaseRenderer and then I get the frames or something? Could you point me to some resources which I could use to realize this? – Bikonja Nov 17 '11 at 17:58
  • Download the platform sdk it contains the baseclasses project so build this project as a static library and link it to you project. Derive from CBaseVideoRenderer : http://msdn.microsoft.com/en-us/library/aa921774.aspx. For infinitetee just take a look in internet there are many examples of usage for this filter. http://msdn.microsoft.com/en-us/library/windows/desktop/dd390337(v=vs.85).aspx and http://msdn.microsoft.com/en-us/library/windows/desktop/dd390337(v=vs.85).aspx – AlexTheo Nov 17 '11 at 19:19
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/5109/discussion-between-alex-theodoridis-and-bikonja) – AlexTheo Nov 17 '11 at 21:17
0

If you need the app's image in first place and hardware overlay is an obstacle to obtain the snapshot, perhaps the easiest would be to make a simple application which starts video playback through overlay (you don't need to stream real samples! just pausing the graph would be suffucuent) and run your application prior to running application of your interest.

This way you would lock the overlay, which is typically a limited resource, e.g. one per video adapter, and the application of interest will be unable to use it.

Roman R.
  • 68,205
  • 6
  • 94
  • 158
  • I thought of that, but then once again the user does not have overlay, meaning, I take away the users freedom to use more or less any renderer they want. – Bikonja Nov 17 '11 at 10:59
  • Overlays don't bring much to user unless it's a very old system. Th epoint is that you don't take too much away from user, but I see your point. I am not aware of any reliable way to grab from overlay, most of utility does do just this: prevent from using the overlay in first place. – Roman R. Nov 17 '11 at 11:03
  • Well, the application will do calculations on the dominant color on various parts of the screen/window so it will hog some cpu cycles, hence my desire to grab any additional cycles I can. Thank you for your insight! – Bikonja Nov 17 '11 at 12:09