Learning (painfully) how to use the Topology and Session to present a captured video. Nothing fancy - just select a web cam, list its modes, choose a video format and hit "go". In general these are the steps I'm taking to present the video capture:
- List the available devices with
MFEnumDeviceSources()
filtered byMF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID
and let user select one - List the streams based on
GetStreamDescriptorCount()
after activating the source and creating Presentation Descriptors withCreatePresentationDescriptor()
and let the user select a stream (if multiple streams are available) - Display all the supported video formats based on the list of
IMFMediaType
s available throughGetMediaTypeByIndex()
and let the user choose one
Once the exact format is selected I build the Topology this way:
- call
MFCreateTopology()
to create a newIMFTopology
object - create media sink activation with
MFCreateVideoRendererActivate()
- making sure to call
SetCurrentMediaType()
on theIMFMediaTypeHandler
object of the currently selectedIMFStreamDescriptor
- making sure to call
- create the source node with
MFCreateTopologyNode()
, setting its presentation and stream descriptors with the call toSetUnknown()
and adding that node to the Topology- made sure to set its current
IMFMediaType
to the one chosen by user withSetCurrentMediaType()
- made sure to set its current
- create an output node and call
SetObject()
of it providing the previously created media sink activation object (from step 5 above) - connect the source to output with
ConnectOutput()
providing it with the node ID0
When the "preview" button is clicked a session IMFMediaSession
object (created at the app's startup) is set with the new Topology
m_session->SetTopology(MFSESSION_SETTOPOLOGY_IMMEDIATE, pTopo);
And this is where I see something strange. I set the size of the preview video based on the frame dimensions provided by the IMFMediaType
that the user chose and the source seems to be producing the video in that format. However the renderer is handling the pixel aspect ratio incorrectly and is letterboxing/pillarboxing the video while presenting the picture as being stretched either vertically of horizontally.
For the life of me I am unable to find the way to tell the renderer to adjust for the proper pixel aspect ratio (which was set to the proper value in step 5.1 above)
The MS's SDK example only shows how to present captured video for uncompressed formats - it doesn't use the IMFMediaSession
object and works fine for the YUV2
format but not for the MJPG
. In fact it worked so well that I thought moving onto using the session would be easy :)
Using the IMFMediaSession
seems to be the least cumbersome way of supporting compressed video formats, especially the H.264
that's in the newer UVC 1.5
standard and any new (H.265
?) formats that are coming up in the future.