How to set the GOP size on VC-1 encoder in Media Foundation? - ms-media-foundation

I'm trying to set the GOP size (number of frames) and set the "closed GOP" flag on VC-1 encoder (WMVideo9 Encoder MFT) in Media Foundation, but I don't see a way to do it. M$ created a thousands of interfaces, but most of them are useless.
(I even tried using async codecs that apparently can benefit from the GPU, etc... LOL, what a joke that is...)
Back to the problem...
For example, there is an IWMCodecProps interface exposed by the IMFTransform, but it's read only. There are tons of attributes accessible through the IMFAttributes, but I don't see one for setting the GOP size and closing the GOP.
Is it possible at all? Looks like M$ is pushing away everybody coding for money. Media foundation is good for playing around only....
P.S.
Not being able to answer is not the the reason for downvoting.

Have a look at ICodecAPI interface. It exposes a lot of settings for video encoding. You would also want have a look at following ICodecAPI properties.
CODECAPI_AVEncMPVGOPSize
CODECAPI_AVEncMPVGOPOpen
CODECAPI_AVEncMPVGOPSInSeq

GOP size analog for VC-1 encoder, which is Windows Media Video 9 Encoder in Windows Media Video 9 Advanced Profile mode, is MFPKEY_KEYDIST Property.
Specifies the maximum time, in milliseconds, between key frames in the codec output.
Compare to GOP size coming from MPEG-2, which number of frames between neighboring I-frames.

Related

Preview issues for 1080P video using DirectShow

I am using DirectShow in my application to capture video from webcams. I have issues while using cameras to preview and capture 1080P videos. Eg: HD Pro Webcam C910 camera of Logitech.
1080P video preview was very jerky and no HD clarity was observed. I could see that the enumerated device name was "USB Video Device"
Today we installed Logitech webcam software on these XP machines . In that application, we could see the 1080P video without any jerking. Also we recorded 1080P video in the Logitech application and saw them in high quality.
But when I test my application,
I can see that the enumerated device name has been changed to "Logitech Pro Webcam C910" instead of the "USB Video Device" as in the previous case.
The CPU eaten up by my application is 20%, but the process "SYSTEM" eats up 60%+ and the overall CPU revolves around 100%
Even though the video quality has been greatly improved, the jerks are still there, may be due to the 100% CPU.
When I closed my application, the high CPU utlizaton by "System" process goes away.
Regarding my application - It uses ICaptureGraphBuilder2::RenderStream to create Preview and Capture streams.
In Capture Stream, I connect Camera filter to NULL renderer with sample grabber as the intermediate filter.
In preview stream, I have
g_pBuild->RenderStream(&PIN_CATEGORY_PREVIEW,&MEDIATYPE_Video,cam,NULL,NULL);
Preview is displayed on a windows as specified using IVideoWindow interface. I use the following
g_vidWin->put_Owner((OAHWND)(HWND)hWnd);
g_vidWin->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS);
g_vidWin->put_MessageDrain((OAHWND)hWnd);
I tried setting Frame rate to different values ( AvgTimePerFrame = 500000 ( 20 fps ) and 666667(15 fps) etc.
But all the trials, still give the same result. Clarity has become more, but some jerks still remain and CPU is almost 100% due to 60+ % utlilization by "System". When I close my video application, usage by "System" goes back to 1-2 %.
Any help on this is most welcome.
Thanks in advance,
Use IAMStreamConfig.SetFormat() to select the frame rate, dimensions, color space, and compression of the output streams (Capture and Preview) from a capture device.
Aside: The comment above of "It doesn't change the source filter's own rate" is completely wrong. The whole purpose of this interface is to define the output format and framerate of the captured video.
Use IAMStreamConfig.GetStreamCaps() to determine what frames rates, dimensions, color spaces, and compression formats are available. Most cameras provide a number different formats.
It sounds like the fundamental issue you're facing is that USB bandwidth (at least prior to USB3) can't sustain 30fps 1080P without compression. I'm most familiar with the Microsoft LifeCam Studio family of USB cameras, and these devices perform hardware compression to send the video over the wire, and then eat up a substantial fraction of your CPU on the receiving end converting the compressed video from Motion JPEG into a YUV format. Presumably the Logitech cameras work in a similar fashion.
The framerate that cameras produce is influenced by the additional workload of performing auto-focus, auto-color correction, and auto-exposure in software. Try disabling all these features on your camera if possible. In the era of Skype, camera software and hardware has become less attentive to maintaining a high framerate in favor of better image quality.
The DirectShow timing model for capture continues to work even if the camera can't produce frames at the requested rate as long as the camera indicates that frames are missing. It does this using "dropped frame" count field which rides along with each captured frame. The sum of the dropped frames plus the "real" frames must equal the requested frame rate set via IAMStreamConfig.SetFormat().
Using the LifeCam Studio on an I7 I have captured at 30fps 720p with preview, compressed to H.264 and written an .mp4 file to disk using around 30% of the CPU, but only if all the auto-focus/color/exposure settings on the camera are disabled.

How to play IMFMediaSample in media foundation?

I am able to extract samples out of a video using the readSample method. Now how can I play the data present in those samples? Or how to play IMFSample ?
Sample IMFSample is a block of data, such as video frame or a chunk of audio sequence. This is a tiny piece of data to be played alone. The API addresses more sophisticated playback scenarios, such as where playback is a session where one or more streams are streamed in sync.
Be sure to check Getting Started with MFPlay on MSDN to see how playback is set up with Media Foundation.

High Resolution Capture and Encoding

I'm using two custom push filters to inject audio and video (uncompressed RGB) into a DirectShow graph. I'm making a video capture application, so I'd like to encode the frames as they come in and store them in a file.
Up until now, I've used the ASF Writer to encode the input to a WMV file, but it appears the renderer is too slow to process high resolution input (such as 1920x1200x32). At least, FillBuffer() seems to only be able to process around 6-15 FPS, which obviously isn't fast enough.
I've tried increasing the cBuffers count in DecideBufferSize(), but that only pushes the problem to a later point, of course.
What are my options to speed up the process? What's the right way to do live high res encoding via DirectShow? I eventually want to end up with a WMV video, but maybe that has to be a post-processing step.
You have great answers posted here to your question: High resolution capture and encoding too slow. The task is too complex for the CPU in your system, which is just not fast enough to perform realtime video encoding in the configuration you set it to work.

BitmapData and JpegEncoder Limitations

I am trying to save out a large image from flash using bitmapdata and the jpegencoder. I am looking into the limitations of this process and have noticed you can only set bitmapdata pizel width and height to a certain amount and this might be flexible with what you set the jpegencoder quality to (1-100).
Does anyone know what the specific limitations of these two things are? I'm basically trying to see just how large of an image I can save out (because I need to use the image exported for printing purposes, so I need it as high quality as possible).
I have read articles that say in fp 10 you can render up to something like 16,000 px. But I tried an image that is 3500 x 3500 and it timed out. So not sure if this is correct information.
The image size limit up to Flash Player 9 is 2880x2880, Flash 10 increased this limit to 4096x4096. This applies also for the Stage, Sprites and MovieClips.
The quality used for the JPGEncoder class does not circumvent this limitation as this is tied to the Flash core.

WMP in c# play rate

I am using wmp in my windows application. I want to change the rate of the play speed.
It is possible for some type of files e.g; avi. But its not possible for some types, eg; wmv,mpeg etc. Is there any other way to change rate. Please, its urgent. Thanx in advance
Its possible, but your choice of using windows media player will limit your choices. Windows media player uses a very simple graphfilter to control playback. This will make it impossible to change the rate for formats which require more complex filters. The general way to change the rate is to either repeat or drop frames in the video.
I am not sure about wmv, but if memory serves me right, wmv is just a container format like AVI, so the graphfilter that is used varies from file to file.
mpeg has 3 kinds of frames. only the i frame is complete. the p and b frames are not so you cant really repeat or drop the frames easily.
Dont know how to help you with this, but you will have better choices if your using directshow so that you can change graphfilters to duplicate/drop frames.

Resources