Creating a IMFMediaSource instance with a video file - c++

Currently, I am trying to create a virtual camera with the Media Foundation API. However, creating a virtual camera requires a IMFMediaSource, which is used to provide video source to the camera.
It would be appreciated if anyone can help me to answer the following questions
How to create a media source from a given video path? A code example or a step by step tutorial could really help me to understand how can I use the API.
How does the video "goes into" the IMFMediaSource? Is it loaded into the memory?
How is the video processed before getting outputed as a stream?

Related

Convert frames to video on demand

I'm working on a c++ project that generates frames to be converted to a video later.
The project currently dumps all frames as jpg or png files in a folder and then I run ffmpeg manually to generate a mp4 video file.
This project runs on a web server and an ios/android app (under development) will call this web server to have the video generated and downloaded.
The web service is pretty much done and working fine.
I don't like this approach for obvious reasons like a server dependency, cost etc...
I successfully created a POC that exposes the frame generator lib to android and I got it to save the frames in a folder, my next step now is to convert it to video. I considered using any ffmpeg for android/ios lib and just call it when the frames are done.
Although it seems like I fixed half of the problem, I found a new one which is... each frame depending on the configuration could end up having 200kb+ in size, so depending on the amount of frames, it will take a lot of space from the user's device.
I'm sure this will become a huge problem very easily.
So I believe that the ideal solution would be to generate the mp4 file on demand as each frame is created, so in the end there would be no storage space being taken as I woudn't need to save a file for the frame.
The problem is that I don't know how to do that, I don't know much about ffmpeg, I know it's open source but I have no idea how to include a reference to it from the frames generator and generate the video "on demand".
I heard about libav as well but again, same problem...
I would really appreciate any sugestion on how to do it. What I need is basically a way to generate a mp4 video file given a list of frames.
thanks for any help!

How to feed video data into a DirectShow filter to compress/encode and save to file?

First of all, here is what I'm trying to accomplish:
We'd like to add the capability to our commercial application to generate a video file to visualize data. It should be saved in a reasonably compressed format. It is important that the encoding library/codecs are licensed such that we're allowed to use and sell our software without restriction. It's also important that the media format can easily be played by a customer, i.e. can be played by Windows Media Player without requiring a codec pack to be installed.
I'm trying to use DirectShow in c++ by creating a source filter with one output pin that generates the video. I'm closely following the DirectShow samples called Bouncing Ball and Push Source. In GraphEdit I can successfully connect to a video renderer and see the video play. I have also managed to connect to AVI Mux and then file writer to write an uncompressed AVI file. The only issue with this is the huge file size. However, I have not been able to save the video in a compressed format. This problem also happens with the Ball and Push Source samples.
I can connect the output pin to a WM ASF Writer, but when I click play I get "This graph can't play. Unspecified error (Return code: 0x80004005)."
I can't even figure out how to connect to the WMVideo9 Encoder DMO ("These filters cannot agree on a connection"). I could successfully save to mjpeg, but compression was not very substantial.
Please let me know if I'm doing something wrong in GraphEdit or if my source filter code needs to be modified. Alternatively, if there is another (non-DirectShow) option that would work for me I'm open to suggestions. Thanks.
You don't give details to help you with your modification of the filters, however Ball sample generates output which can be written to a file.
Your choice of WM ASF Writer filter is okay - it is a stock filter and it is more or less easy to deal with. There is however a caveat: you need to select video only profile on the filter first, and then connect video input. WM ASF Writer won't run with an unconnected input pin, and in default state it also has an audio input. Of course this can also be done programmatically.
The graph can be as simple as this, and it can be run and it generates a playable file.

Strategy for accessing native camera events on Google Glass using a Service

Background:
I have a google glass, and I am thinking on an app that can grab any/all images a user takes using the native camera, and passing those images to an online service (e.g. Twitter or Google+). Kind of like a life-blogging style application.
In my first prototype, I implemented a FileObserver Service that watches for new files in the directory that glass stores its camera preview thumbnails (sdcard/google_cached_files/). The preview files always started with t_, so once I saw a new file there, I uploaded it to my webservice. This was working very well, but in Glass XE11 this cache file was moved out of my reach (/data/private-cache).
So now, I am watching the folder sdcard/DCIM/Camera/ for new .jpg files. This works ok, but the camera is storing the full size image there, so I have to wait 5-8 sec before the image is available for upload.
The Question:
Should it be possible to have background service running on glass that can intercept the camera event, and grab the thumbnail or the full image as a byte array from the Bundle so that I don't have to wait for it to write to disk before accessing it?
I have been reading up more on android development, and I suspect the answer involves implementing a BroadcastReciever in my service, but I wanted to check with the experts before going down the wrong path.
Many thanks in advance
Richie
Yes. Implement a PreviewCallback. Same way it worked for phones, example here: http://www.dynamsoft.com/blog/webcam/how-to-implement-a-simple-barcode-scan-application-on-android/
I tested it on Google Glass and it works. In this post ( http://datawillconfess.blogspot.com.es/2013/11/google-glass-gdk.html ) I list the parameters (below the video) which the camera returns after doing:
Camera m_camera = Camera.open(0);
m_params = m_camera.getParameters();
m_params.setPreviewFormat(ImageFormat.NV21);
m_camera.setParameters(m_params);
m_params = m_camera.getParameters();
m_params.setPreviewSize(320,240);
m_params.set("focus-mode",(String)"infinity");
m_params.set("autofocus", "false");
m_params.set("whitebalance",(String)"daylight");
m_params.set("auto-whitebalance-lock",(String)"true");
m_camera.setParameters(m_params);
String s = m_params.flatten();
Log.i("CAMERA PARAMETERS", "="+s);

Get native video resolution of a video file

I'm currently writing some custom EVR for a Media Foundation player.
So far everything work, but i'm in need of finding the native resolution of the video file i'm rendering.
I try to use the IBasicFilter2 Interface to use the getVideoSize, get_VideoHeight or other get_SourceWidth etc... but it always return me a E_NOINTERFACE...
So do someone have an esay way of getting resolution of a video file? Even if it's with a nice light library...just the size nothing else...Windows manage to find it inside the file browser, but i'm totally unable to get it from code...
Thanks!
You can use IMediaDet in DirectShow to get information on the streams in a media file including the resolution of video streams.
There are come caveats though so you might want a backup method.
You need suitable DirectShow filters registered which understand the media file being examined. It's possible that you may have a filter installed that gives wrong results - e.g. an audio only filter is registered for a media type that ignores any video streams in the file.
It's currently deprecated with no indication on the MSDN reference page of what is replacing this functionality. It can also be a pain to build as the headers have been removed from the Windows SDK.
Here's one case in point where that method doesn't work...
Get MP4 stream lengths

Display streaming video in desktop app

I have a Windows native desktop app (C++/Delphi), and I'm successfully using Directshow to display live video in it from a 'local' video capture device.
The next thing I want to do is display video from a 'remote' capture device, streamed over the LAN.
To stream the video, I guess I can use something like Expression Encoder or VLC, but I'm not sure what's the easiest way to receive/decode the streamed video. Inserting an ActiveX VLC or Flash player might be one option (although the licensing may be an issue then), but I was wondering if there's any way to achieve this with Directshow...
Application needs to run on XP, and the video decoding should ideally be royalty free.
Suggestions, please!
Using Directshow for receiving and displaying your video can work, but the simplicity, "openness" and performances will depend on the video format and streaming method you'll be using.
A lot of open/free source filters exist for RTSP (e.g. based on live555), but you may also find that creating your own source filter is a better fit.
The best solution won't be the same for H264 diffusion through RTP/RTSP and for MJPEG diffusion through simple UDP.