1/15/2022

Microsoft TV Technologies and the Video Control COM object

 Around XP and possibly a little bit earlier, the WDM device driver model for Windows device drivers became popular. 

 And the COM object method of  writing programs, with a whole raft of common services that could be accessed and programmed abstractly without knowing the details of the devices or their drivers.

Windows 2000, XP and up until very recently had a COM object group of library code for implementing and using Analog and Digital TV signal media, called Microsoft TV Technologies.

It was hard to understand after learning upwards from missing device drivers, then Directshow Filters and the Graph Edit method of graphically constructing abstract visual Graphs linking filters into running prototypes for understanding how video capture devices worked.. that they related to Microsoft TV Technologies.

Originally the BDA - Broadcast Driver Architecture, defined "How" to "Tune" an Analog or Digital source by firing off a Graph Build process that created a Filter Graph in program memory.

Usually this was expected to be an Analog TV tuner card, or a Digital Video Broadcast (DVB) TV tuner card. But to accommodate, legacy "analog input only" cards with simply s-video or composite they also included an AuxIn type of "Tuning" which treated a Video Capture card as if it were a complete Analog TV tuner.

Once a handle for a COM Object of the Tuner type was obtained, a tuner request object was created by the COM object and then used as a template to "fill out" or complete a Tuning request.. which when executed or "Run" by calling a Video Control method.. caused the Video Control Object to assemble and run the Directshow Graph constructed of filters to accomplish the task.. which included "Rendering" the output to a video window.

The Streaming Buffer Component could also be used with the Video Control to Pause, Rewind and Record the currently viewed stream.

The Video Control COM object could be used by VBscript, Jscript automation scripting via HTML or Windows Shell Host.. or used via Visual C/C++ or Visual Basic. Which offered finer degrees of control.

Or Directshow could be used directly via its GraphBuilder object to build up a custom Graph either partially automatic or manually.

This appeared to be the foundation of Windows Media Center in Windows XP and later.. but I'm not entirely sure how Graph Build automation succeeded with some hardware compression cards.. I suspect the WMC compatible brand label required some sort of WMC helper agent to establish or assist the automation process of completing a graph that had hardware encoders and or decoders for MPEG2.

Although I could see how it might work with plain frame grabber YUV frames that required only a minimal Directshow Graph Filter.

Using the Video Control

The dual nature of Playback versus Record, also led to the separation of Graphs in memory and priority when using a program like Windows Media Center or other Capture software.

When using GraphEdit to view a Playback graph of WMC or Capture software only the Playback graph could be seen in the RunTime Object Table (ROT) if the operating system didn't block access due to different administative priority levels.. like ordinary user versus a system service.

GraphEdit could be "tricked" into "seeing" other spaces, by starting both in the same user space, or running GraphEdit with administrator rights.. or launching GraphEdit with an "at" command to proxy access to the system level space "services" are run launching a command window and then launching GraphEdit from a C:\ prompt

All of which was much easier in XP or 32 bit days, before strict enforcement of user memory spaces were enforced and hid much of the access to the memory space of other programs due to security and malware concerns.


This is a snippet of  VBScript that illustrates how the Video Control "MsVidCtl" is grasped and instantiated, then Objects are created from the Control and used to accomplish automation tasks upon the control.

The "simplified" world view of the Video Control is that there are only three things; Input Devices, Features and Output Devices. Where the word "Devices" is over used in this situation to represent something other than just a Filter in a Graph. Essentially the Video Control does whatever is necessary in the background to "enable" the COM object "controls" to do their function. The "exposed" controls being a set of objects that "look like" a Tuning Source, some minimal closed caption decoding, and finally a Video window.

"


<TITLE>MSVidCtl: NTSC Analog TV</TITLE>


<!--
    This sample requires an analog TV tuner card compatible with the Windows Driver Model.
-->


<OBJECT ID="MSVidCtl" CLASSID="CLSID:B0EDF163-910A-11D2-B632-00C04F79498E"></OBJECT>



<SCRIPT language=vbscript>
option explicit

dim tscontainer 'tuning space collection
dim ts 'Analog TV tuning space
dim tr 'Analog TV tune request


sub window_onload
    MSVidCtl.Width = 800
    MSVidCtl.Height = 600
    
    set tscontainer = CreateObject("BDATuner.SystemTuningSpaces")

    'Get the tuning space with the word "Cable" in its name. 
    'This tuning space works with North American NTSC Cable
    'You can use the tuning space "Antenna" if you are using NTSC terrestrial analog broadcast
    'For other types of analog broadcast, you will need to create your own tuning space
        set ts = tscontainer("Cable")

        set tr = ts.CreateTuneRequest
        
    'By default we will start on channel 5
    tr.Channel = 5
        
    'Pass the tune request to the View() method and then build the graph
    MSVidCtl.View tr
        MSVidCtl.Run

    'This will alpha blend the image mstv.jpg over the video
    dim pict
    dim alpha
    dim tempvidrend
    dim myrect

    dim CurrentPath
    CurrentPath = location.href
    CurrentPath = Replace(CurrentPath,"%20"," ")
    CurrentPath = Replace(CurrentPath,"/","\")
    CurrentPath = Mid(CurrentPath,6,InstrRev(CurrentPath,"\")-6)
    if Mid(CurrentPath, 5, 1) = ":" then CurrentPath = Mid(CurrentPath, 4, Len(CurrentPath)-3)
    
    dim fileLoc
    fileLoc = CurrentPath & "\mstv.jpg"
    set pict = LoadPicture(fileLoc)

    alpha = 35
    set tempvidrend = MSVidCtl.VideoRendererActive
    tempvidrend.MixerBitmapOpacity = alpha
    set myrect = tempvidrend.MixerBitmapPositionRect
    myrect.Top = 20
    myrect.Left = 20
    myrect.Width = 50
    myrect.Height = 20
    tempvidrend.MixerBitmapPositionRect = myrect
    tempvidrend.MixerBitmap = pict

    'Display the channel information
    dl.innertext = MSVidCtl.InputActive.Tune.Channel
    currentchannel.value = MSVidCtl.InputActive.Tune.Channel
end sub

sub startbutton_onclick
    'This starts the graph and begins displaying audio and video
        MSVidCtl.Run
end sub


sub stopbutton_onclick
    'This stops the graph, but does not destroy it
        MSVidCtl.Stop
end sub

sub chanup_onclick
    'Tune to the next channel up
    tr.Channel = tr.Channel + 1
        MSVidCtl.View tr

        dl.innertext = MSVidCtl.InputActive.Tune.Channel
    currentchannel.value = MSVidCtl.InputActive.Tune.Channel
end sub


sub chandown_onclick
    'Tune to the next channel down
    tr.Channel = tr.Channel - 1
        MSVidCtl.View tr

        dl.innertext = MSVidCtl.InputActive.Tune.Channel
    currentchannel.value = MSVidCtl.InputActive.Tune.Channel
end sub

sub enter_onclick
    'Tune to the channel the user entered in the textbox
    tr.channel = currentchannel.value
        MSVidCtl.View tr

        dl.innertext = MSVidCtl.InputActive.Tune.Channel
    currentchannel.value = MSVidCtl.InputActive.Tune.Channel
end sub

</Script>

"

1/04/2022

DirectX GraphEdit Decoding H.264 from Elgato Game Capture HD S-Video

The default DirectShow [MPEG-2 Demultiplexer] worked for the AverMedua C874 once I understood it was in push mode and pushing a TS stream. The PSI and stream IDs had to be mapped to output pins and then the Graph Editor could render the decoded streams.

Similarly the Elgato Game Capture HD was also pushing a TS stream, but made of H.264 video and AAC audio.


 

The trick to getting it to work was to abandon the default Microsoft provided [MPEG-2 Demultiplexer] and manually registering an ArcDemux.ax filter that came with another software package installed on my system. Then it showed up in the available 32 bit Directshow filters in Graph Edit.

 

The Arcsoft ArcDemux filter was not registered with the system for general use.. but filters provided by software makers can be directly referenced by-passing the registry and keeping them somewhat hidden.

The ArcSoft Demux filter has additional media types for both H.264 and AAC, which the MPEG-2 Demultiplexer did not. The C874 had a different type of audio that was supported by default as MPEG Audio 1.

Its also important to be aware the device driver filter for the Elgato Game Capture is 32 bit and shows up under the global Directshow filters list, not the WDM capture devices. On Win7x64 Graph Edit often crashes if you attempt to open the Directshow list.. probably due to some errors in the registered filters for 64 bit Graph Edit. The work around is to use Graph Studio Next or some other Graph editor to get all the filters on one graph,s ave to a file and then open it in the default Microsoft Graph Editor program.

This is still just a proof of concept . There are minor issues.

Audio and Video are clearly captured and provided from the TS pin.

But the auto-rendering function of Graph Edit pulled in some collateral filters from other programs, like the Hauppage AAC filter. It can probably be better optimized to use specific filters.

The Graph file saved also doesn't appear to preserve the PIN assignments and they have to be reassigned upon loading the Graph again.. very strange behavior.

There is also some "drift" in lip sync with this first attempt at a Graph.. possible due to all of the extra filters building out the audio chain.

 

 



Instead of a general purpose Proc-Amp panel like with many other capture devices. Elgato provides a custom popup dialog box when right clicking on the Elgato Game Capture HD filter. It allows many other things than Proc-Amp controls like capture format, audio levels and so on.




This is with the 11/6/2015 2.3.3.42 device driver version. Earlier versions did not include a TS pin as an option for accessing the audio/video stream for Preview or Capture.

In fact misusing the TS pin to provide a Preview of the video stream being captured is kind of weird.. since normally that stream would be sent to a file filter or dumped to a file for storage as a raw .TS or mp2ts file stream. TS is a lossy or packet loss tolerant format which is often used for broadcasts, or in situations where packet of audio or video can be loss and not abort the flow.

Generally "after" the TS stream is captured, to render it suitable for a DVD or long term file storage its more common to transcode or convert it to the PS format and put it in a structured container with meta tag data like a generic file with extension .MP4

The other pins provide uncompressed Video and Audio.. for more immediate Preview use, but at the cost of being less reliable than the TS stream for capturing everything during a capture session.. this is by design as most WDM capture devices offer a tight but laggy capture stream and a fast but lossy capture stream for preview.

In theory this same approach should work with the more current HDS and HD60 versions of the Elgato Game Capture for use with HDMI capture.. but I do not have those products and have not had an opportunity to prove it works with those devices.

A bit of proof it is Interlaced video that is being captured, and with a smaller graph, fewer filters.



Gotta love that there isn't chunky 64x64 Macroblock artifacts, those are Interlaced lines between fields being mashed together into a single frame. The motion blurring is due to the difference in time between the two fields.

The Elgato property page for the capture filter says its capturing in Interlaced 59.97 fields per second (fps) but is nice to get visual confirmation.

Its also a great example of why its better to always capture SD NTSC video in "Interlaced" format.. that image is "mashed together" into one frame and now its impossible to pull it back apart into Interlaced format and try again.. its irretrievably "baked into" the Progressive frame by frame format now.

Truthfully I  should not be pulling the Preview off the MPEG-TS pin, normally you want to store that in a capture file and pull Preview video off the plain "video" pin.. which has a  lower priority and can deliberately drop frames in order to sacrifice the Preview video, in order to always capture every last bit from the MPEG-TS pin at capture time. - That's how the Capture filter/plugin was designed to work in the very beginning by the Microsoft standard.. anticipating people would want to "See" what they are capturing during the capture process.

It was a little controversial and forward thinking at the time since slow CPU and hard drives made it difficult if not impossible to "do two things at one time".. both Preview and Capture.

PC's and hardware eventually caught up however.

Back in the day.. a separate video audio "splitter" or "video distribution amplifier" was used before the capture device to feed a separate video monitor and speakers.. so you could "see" what you were doing.

Ironically.. for a different reason.. but Game Capture would do this .. for different reasons later.. the hardware encoding takes time and adds lag to both the Preview pin and the Capture pin.. so to avoid "game lag" they would try to pass-thru a copy of the raw video feed either though the game capture device.. or do the same thing and use a hardware video distribution amplifier up front before getting to the capture device.


1/02/2022

DirectX GraphEdit Decoding H.264 from AverMedia C874 USB HD

When you build a Graph Edit "Graph" for MPEG2 you often have a WDM capture device driver filter with an Output Pin.

The Output Pin streams video as a multiplexed Audio and Compressed Video format. To turn it back into something you can view you have to Demultiplex it and Decode it using separate workflows from the Demux filter.

DirectX and Windows offer several filters.

The "MPEG-2 Demultiplexer" normally has one Input - MPEG-2 Stream and no pins.

The MPEG-2 Multiplex format is generic and it is used by other A/V streams besides MPEG2, it can be used for MPEG4. Breaking apart the audio from the video works that same way.

1. put a source filter on the graph, perhaps coming from the hardware capture device.

2. put the [ MPEG-2 Demultiplexer ] filter on the graph, right click and configure this filter with one pin


Output Pins

---

New Output Pin

 Name: PSI

Media Type:  MPEG-2 PSI

>> Create ->

 

PID Mappings

---

PID

0x0000

Pin

PSI

MPEG2 PSI Sections

>> [Map]


Press [OK] to close the Properties Dialog box

Hit the Orobus (two arrows chasing each other in a circle) button to "Refresh" the graph and expose the pin you just created

Uisng Graph Edit 64 bit (be sure its 64 bit Graph Edit or Directshow filters will not open and crash Graph Edit) go to the Diret Show filters and put the PSI Parser filter on the graph

Connect the PSI pin from [MPEG-2 Demultiplexer] ->[ PSI Parser]

Execute ('Run') the Graph, while it is running > Right click on PSI Parser filter

[PSI Parser Properties]

Programs Contained in the Transport Stream:

Program Number

PMT PID

(click on the first program number, a list of the PID Stream type Contents, will appear below)

The KEY to using this is the First colum [PID] is in "Decimal" format.

 

You have to convert that Number form Decimal into Hex format to go back to MPEG-2 Demultiplexer and appropriately map PIDs to Elementrary streams coming out the the Output pins.

You can do all of this "live" while the Graph is running.

Example:

 

Mean PIDs in DEC

4113 0x1b ISO/IEC-14496-10/H.264 AVC Video

4352 0x3  ISO/IEC 11172-3 Audio

 

Mean PIDs in HEX

0x1100 MpegVideo Elementary Stream (A/V only)

0x1011 MpegAudio Elementary Stream (A/V only)


https://docs.microsoft.com/en-us/windows/win32/directshow/overview-of-mpeg-2-systems

https://stackoverflow.com/questions/16362132/why-do-i-get-these-artifacts-when-using-microsoft-mpeg-ts-demultiplexer-and-h-26

https://docs.microsoft.com/en-us/windows/win32/directshow/microsoft-mpeg-2-video-decoder

https://stackoverflow.com/questions/4618695/using-microsoft-dtv-dvd-video-decoder-to-play-h264-video

http://www.gdcl.co.uk/mpeg4/

https://github.com/RenderHeads/UnityPlugin-AVProVideo/issues/205

https://en.wikipedia.org/wiki/MPEG_transport_stream


Once the pins are created, you can hit the Orobus (two arrows chasing each other) and stop the Graph, right click on the pins and "render" them based on their content type and mostly if you have the right filters and merits the Graph will build itself.

 

 




The Microsoft DTV-DVD decoder can work starting with Windows 7, its not the best, but its free.