I'm working on a custom video player using the Media Foundation framework.
Currently, I can play, pause, stop or change the rate of the playback using an IMFMediaSession.
I can also retrieve a single frame using an IMFSourceReader.
I am currently able to render a frame (IMFSample) to a window area (a HWND) but only when the media session is stopped.
My goal is to be able to render a frame while the media session is paused.
(= doing frame-stepping using a source reader and not the media session)
I'm using GetDC, CreateBitmap, SelectObject and BitBlt to render my frame.
I tried using directd3d interfaces to fill it with a solid color (I'm really new to direct3d so followed a basic tutorial) but it didn't work.
Here is what I did : retrieving an IDirect3DDeviceManager9 with MR_VIDEO_ACCELERATION_SERVICE, doing OpenDeviceHandle, LockDevice, Clear, Begin/EndScene and Present.
None of these calls fail but I suspect the EVR is still painting the last frame.
So basically, I want the EVR to stop repainting its frame when I want and of course, I need to re-enable its painting process.
Any idea how to do that ?
Thanks
I finally got it working.
If you're interested, do the following:
retrieve IMFVideoDisplayControl and IMFVideoMixerBitmap from the media session using MFGetService
set up MFVideoAlphaBitmap structure and feed it to IMFVideoMixerBitmap::SetAlphaBitmap (there is a working example at the dedicated MSDN page)
call IMFVideoDisplayControl::RepaintVideo to update the output
To hide the previous content, don't set the alpha so that it's opaque.
Call IMFVideoMixerBitmap::ClearAlphaBitmap to get the previous content back.
And voilà !
Related
I am trying to make an application that will "trigger" when a certain image is shown on screen. I have the app streaming the camera to the screen inside the app using AVCaptureSession. Now i was wondering how to make some sort of EventHandler for each frame of the video, in which i will check to see if the image contains one of my triggers. Does anyone know the best way to handle this? I could not find any resources on an OnFrame EventHandler for AVCaptureSession.
This is the tutorial i followed for showing the camera on screen
https://github.com/messier16/FullCameraPage/blob/master/FullCameraApp.iOS/CameraPageRenderer.cs
Any advice is awesome. Thank you!
I ended up doing a while loop inside of overriden ViewWillAppear() to grab the frame consistently
I'm working in a legacy application using MFC.
We have a mechanism to enable/disable controls depending on some business logic.
This mechanism is implemented in the CView-derived class. The way it works is all the views in the application derived from a common CView-derived class (CBaseView) and on the PreTranslateMessage all controls of the view are enabled/disabled.
This worked fine so far because all controls send at least WM_PAINT message when they need to be painted. So the system worked without the user having to move the mouse or anything. I recently added some drawing features and I had to use WS_EX_COMPOSITE to get ride of some flickering. With this flag activated my CView-derived class is not getting any called to PreTranslateMessage when creating the view....so the controls are not disabled until the user moves the mouse over the control.
I understand there is no way to send WM_PAINT using WS_EX_COMPOSITE but is there other message I can use to get the same behaviour???
Edited:
I am currently using the OnIdle approach but it has a big drawback, the windows doesn't become idle until after drawing all the controls...so when you enter the screen al controls are enabled and inmediately they are disabled...this makes a quite ugly effect!
More solutions???
Thanks in advance...
The logical place to enable/disable controls would be CView::OnUpdate, it is called by the framework after the view's document has been modified and from OnInitialUpdate(); you can also call this function if there is some change that would trigger re-evaluation of your business logic.
EDIT
After reading the question a bit more closely, what you could also do is to post a private message at the end of OnInitialUpdate and "catch" it in your PreTranslateMessage:
PostMessage(WM_APP, 0, 0);
Calling InvalidateRect followed by UpdateWindow against the window in question will mark the entire client area as dirty and force an immediate repaint. Remember that WM_PAINT is not really a message, in the queue in the usual sense, it is pushed out after all other messages have been processed for that window, which would include any invalidations of the area being drawn. No message is generated at all if there are no invalid segments of the active window display.
I'm new to GPUImage, but I think that it is really nice: good work Brad. I love the way the filters chain together so cleanly.
GOAL
I'm trying to wire up the following:
* create an openGL scene
* apply some filters (irrelevant to the discussion below)
* record to video
PROBLEM
My problem is I'm not clear how to connect up the recording. Unfortunately, interacting with opengl-es does not give me enough detail to work out what to do.
ATTEMPT
I have two starting points from the examples in the package:
* CubeExample - getting raw openGL to interact with GPUImage
* SimpleVideoFileFilter - recoding a video file through filters to a new file
I started with the CubeExample, substituted the videoCamera filter for GPUImageSolidColorGenerator (as an aside, I'm not sure how to start with no filter). This allowed me to be able to create a mesh, render it and interact with it. Then I thought that I'd simply add on a GPUImageMovieWriter filter as per the instructions given in filtering and re-encoding a movie, but that requires coordination between the GPUImageMovie (the source) and the writer. As I'm not wanting a camera stream or a video file as the source, but an animated openGL sequence, I'm not clear how to do it. I've tried adding a videoInputReadCallback to the movieWriter:
movieWriter.videoInputReadyCallback = ^{
[renderer nextFrame];
[movieWriter newFrameReadyAtTime:renderer.cmTime atIndex:0];
};
where nextFrame is creates the next frame, calls endProcessing when done and sets the CMTime. Without the newFrameReadyAtTime:atIndex: call, it works fine (animated image rendered as expected to the screen) except that it creates a video with only one frame in it. With the newFrameReadyAtTime:atIndex: call, I get the message
Problem appending pixel buffer at time: 6
before it dies, which makes me think that the movieWriter is not yet ready for the renderer to present its frame, but I'm not sure what to do about it. I've tried many other things, but to no avail. From the description in Interacting with OpenGL-ES (see link above), it seems like it should be easy, but I'm not having any luck.
REQUEST
To make the question more relevant to others, I would just like it if someone might be able to post an example of creating an openGL scene (eg a triangle) and connecting it to GPUImageMovieWriter to record to a file, perhaps rotating the triangle for 10 frames so that we can see that more than a still image is created.
thanks.
How do I prevent my GUI from redraw when it comes back from lock screen after receiving a UILocalNotification? In didReceiveLocalNotification I present a modal view, but the old state of my view controllers is shown for a moment before that. How do I prevent this?
Also the order of events I get when I come back on local notification from background is as following:
1. UIApplicationWillEnterForegroundNotification
2. UIApplicationDidBecomeActiveNotification
3. didReceiveLocalNotification
When I come from lock screen:
1. didReceiveLocalNotification
2. UIApplicationDidBecomeActiveNotification
Why is this difference and whether there is something else I'm missing?
Thanks
Here's how it was solved. May be it's not the way, but it worked for me. Since my application is voip/audio, it doesn't come to didFinishLaunchingWithOptions... I found out, that iOS uses a cached image from a previous state for animation when it resumes from background or from sleep mode. So the solution is basically to exchange this cached image with my default.png image. I do it in applicationWillResignActive delegate. There I add a modal view with a Default.png picture and dismiss it in applicationDidBecomeActive. This is really in short. Hopefully it will help somebody else with the same problem.
You can provide a custom image that is displayed when launching/resuming from a local notification. Simply set the alertLaunchImage property on your local notification to the name of the correct image.
From the Docs:
The string is a filename of an image file in the application bundle. This image is a launching image specified for a given notification; when the user taps the action button (for example, “View”) or moves the action slider, the image is used in place of the default launching image. If the value of this property is nil (the default), the system either uses the previous snapshot, uses the image identified by the UILaunchImageFile key in the application’s Info.plist file, or falls back to Default.png.
alertLaunchImage
How do I prevent my GUI from redraw when it comes back from lock screen after receiving a UILocalNotification? In didReceiveLocalNotification I present a modal view, but the old state of my view controllers is shown for a moment before that. How do I prevent this?
Also the order of events I get when I come back on local notification from background is as following:
1. UIApplicationWillEnterForegroundNotification
2. UIApplicationDidBecomeActiveNotification
3. didReceiveLocalNotification
When I come from lock screen:
1. didReceiveLocalNotification
2. UIApplicationDidBecomeActiveNotification
Why is this difference and whether there is something else I'm missing?
Thanks
Here's how it was solved. May be it's not the way, but it worked for me. Since my application is voip/audio, it doesn't come to didFinishLaunchingWithOptions... I found out, that iOS uses a cached image from a previous state for animation when it resumes from background or from sleep mode. So the solution is basically to exchange this cached image with my default.png image. I do it in applicationWillResignActive delegate. There I add a modal view with a Default.png picture and dismiss it in applicationDidBecomeActive. This is really in short. Hopefully it will help somebody else with the same problem.
You can provide a custom image that is displayed when launching/resuming from a local notification. Simply set the alertLaunchImage property on your local notification to the name of the correct image.
From the Docs:
The string is a filename of an image file in the application bundle. This image is a launching image specified for a given notification; when the user taps the action button (for example, “View”) or moves the action slider, the image is used in place of the default launching image. If the value of this property is nil (the default), the system either uses the previous snapshot, uses the image identified by the UILaunchImageFile key in the application’s Info.plist file, or falls back to Default.png.
alertLaunchImage