Menu

How to setup mpeg2hardware encoder in dxtuner

cesm1980
2010-01-17
2012-10-29
  • cesm1980

    cesm1980 - 2010-01-17

    I recently bought a hardware mpeg2 encoder card, the asus edh2-100, and after
    hours of tries i was finally able to construct the capture graph in Grahedit
    and now i am able to capture mpeg2 files by hardware encoder only by running a
    graph in graphedit. So now the problem is porting this to vb.net, but
    unfortunately i am still a newbie into c#, altough since know tons about
    vb.net i am more or less able to understand a bit c# code, so i was fiddling
    with the sample project "DxTuner" that came with DirectShowSamples-2007-July,
    and i was able to add to the capture graph the hardware encoder devide of my
    card (it's filter type is WDMStreamingMultiplexerDevices). By analyzing the
    code i was able to figure out more or less how the filters are connected, and
    the file writer as well, altough i am having a lot of problems being able to
    connect the WDMStreamingMultiplexerDevice to the tv tuner device and set up
    the file writer to receive the feed of this hardware encoder device...

    Can someone please tell me how to i connect this device to the "ICS audio" and
    "analog ITU video" pins ? I already spent the entire day using google for
    this, and i found absolutly no code showing how to use hardware encoder in tv
    capture programs, and the code in Dxtuner only connects the Capture pi. Here's
    a screenshot of the graph i built in graphedit and in which i successfully
    record mpeg2 files by hardware :

    http://i46.tinypic.com/zmih6e.jpg

     
  • snarfle

    snarfle - 2010-01-18

    While there may be ways to have the automatic graph building functions produce
    this graph for you, it may be simpler in the long run to manually add the 6
    filters to the graph and connect them yourself. Check out the docs for
    IFilterGraph.AddFilter and IPin.Connect. You might find the utility routines
    we have created useful as well (like DsFindPin from DSUtils or ConnectFilters
    from FilterGraphTools.cs).

     
  • cesm1980

    cesm1980 - 2010-01-18

    FINALLY i was able to fully code this in visual basic.net, jeez it was almost
    two ENTIRE days of googling, tweaking and tons of frustations, for about 2-3
    times i was almost about to give up but finally i was able to code this, jeez
    i never tought it was SO difficult, this is all because there is almost no
    vb.net code on the internet about the directshow.net library, and some of the
    problems i had was related to bad convertions from c# to vb.net with online
    converters. And yes i had to use your advice in connecting the pins manually,
    but i also had a huge help of the generated code in graphedit plus program
    even tought just the code itself wouldn't work even on c#...

    In fact as soon as i saw your advice i tried what you said and i meanwhile
    discovered the DxLogoVB application, the ONLY one i found so far coded in
    vb.net using this library and this is what helped me the most :) I even now
    know how to set the channel and fiddling with the crossbar.

    There is two major things i need to do for now :

    Create a second graph to connect to the streaming mpeg2 hardware encoded file
    so that i am able to preview the mpeg2 that is being encoded by hardware, it
    seems it's necessary to have a second graph running after the first one
    starts, i hope i will be able to do this myself, but so far the current
    priority is the next goal :

    Being able to set by code the settings of the hardware encoder (unfortunately
    it's not possible to do this the same way as the channel change is done with
    IAMTVTuner). I noticed that the settings of the WDMStreamingMultiplexerDevice
    are kept in the same session of Graphedit in which i change them, but even if
    i save the graph file and reload it later on GraphEdit after graphedit was
    closed, the settings i changed manually using the dialog pages are NOT kept
    they keep getting back to the defaults.

    But i really need a way to change the hardware encoder settings by code
    without having to change the settings myself in the property dialog pages
    everytime i start the vb.net program... Let's presume that in runtime i set
    myself the settings in the dialog pages of the filter, after i do that is it
    possible to "capture" or save the current contents of the dialog pages'
    settings to a variable so that i can "fill" the filter's settings dialog pages
    with the contents of the previously saved variable just using code? Maybe
    there is a way to do this or not ? I am sure there is a way since the program
    that came with my capture card is able to change those settings in the
    hardware encoder device... Please if you or someone else is able to help me on
    this...

    Well.. since yesterday until this morning i spent several hours in trying
    precisely that method you say, about direct pin connection and i am really
    almost giving up, this is the hardest thing i have ever tried to do, specially
    because i understand very few about c# altough i was still able to try douzens
    of snippets i found online about getpins from filters and absolutly nothing
    worked. For example i tired this code generated by a program that loads grf
    files :

    //Don't forget to add reference to DirectShowLib in your project.
    using System;
    using System.Collections.Generic;
    using System.Runtime.InteropServices.ComTypes;
    using System.Runtime.InteropServices;
    using DirectShowLib;

    namespace graphcode
    {
    class Program
    {
    static void checkHR(int hr, string msg)
    {
    if (hr < 0)
    {
    Console.WriteLine(msg);
    DsError.ThrowExceptionForHR(hr);
    }
    }

    static void BuildGraph(IGraphBuilder pGraph)
    {
    int hr = 0;

    //graph builder
    ICaptureGraphBuilder2 pBuilder = (ICaptureGraphBuilder2)new
    CaptureGraphBuilder2();
    hr = pBuilder.SetFiltergraph(pGraph);
    checkHR(hr, "Can't SetFiltergraph");

    Guid CLSID_TridVidTvTuner0001 = new Guid("{266EEE40-6C63-11CF-
    8A03-00AA006ECB65}"); //kstvtune.ax
    Guid CLSID_TridVidTvAudio0002 = new Guid("{71F96462-78F3-11D0-A18C-
    00A0C9118956}"); //ksxbar.ax
    Guid CLSID_TridVidCrossbar = new Guid("{71F96460-78F3-11D0-A18C-
    00A0C9118956}"); //ksxbar.ax
    Guid CLSID_SigmaTelAudioTopology = new Guid("{17CCA71B-
    ECD7-11D0-B908-00A0C9223196}"); //ksproxy.ax
    Guid CLSID_VideoRenderer = new Guid("{B87BEB7B-8D29-423F-AE4D-6582C10175AC}");
    //quartz.dll

    //add TridVid TvTuner 0001
    IBaseFilter pTridVidTvTuner0001 = (IBaseFilter)Activator.CreateInstance(Type.G
    etTypeFromCLSID(CLSID_TridVidTvTuner0001));
    hr = pGraph.AddFilter(pTridVidTvTuner0001, "TridVid TvTuner 0001");
    checkHR(hr, "Can't add TridVid TvTuner 0001 to graph");

    //add TridVid TvAudio 0002
    IBaseFilter pTridVidTvAudio0002 = (IBaseFilter)Activator.CreateInstance(Type.G
    etTypeFromCLSID(CLSID_TridVidTvAudio0002));
    hr = pGraph.AddFilter(pTridVidTvAudio0002, "TridVid TvAudio 0002");
    checkHR(hr, "Can't add TridVid TvAudio 0002 to graph");

    //connect TridVid TvTuner 0001 and TridVid TvAudio 0002
    hr = pGraph.ConnectDirect(GetPin(pTridVidTvTuner0001, "Analog Audio"),
    GetPin(pTridVidTvAudio0002, "TVAudio In"), null);
    checkHR(hr, "Can't connect TridVid TvTuner 0001 and TridVid TvAudio 0002");

    //add TridVid Crossbar
    IBaseFilter pTridVidCrossbar = (IBaseFilter)Activator.CreateInstance(Type.GetT
    ypeFromCLSID(CLSID_TridVidCrossbar));
    hr = pGraph.AddFilter(pTridVidCrossbar, "TridVid Crossbar");
    checkHR(hr, "Can't add TridVid Crossbar to graph");

    //connect TridVid TvTuner 0001 and TridVid Crossbar
    hr = pGraph.ConnectDirect(GetPin(pTridVidTvTuner0001, "Analog Video"),
    GetPin(pTridVidCrossbar, "0: Video Tuner In"), null);
    checkHR(hr, "Can't connect TridVid TvTuner 0001 and TridVid Crossbar");

    //connect TridVid TvAudio 0002 and TridVid Crossbar
    hr = pGraph.ConnectDirect(GetPin(pTridVidTvAudio0002, "TVAudio Out"),
    GetPin(pTridVidCrossbar, "3: Audio Tuner In"), null);
    checkHR(hr, "Can't connect TridVid TvAudio 0002 and TridVid Crossbar");

    //add SigmaTel Audio Topology
    IBaseFilter pSigmaTelAudioTopology = (IBaseFilter)Activator.CreateInstance(Typ
    e.GetTypeFromCLSID(CLSID_SigmaTelAudioTopology));
    hr = pGraph.AddFilter(pSigmaTelAudioTopology, "SigmaTel Audio Topology");
    checkHR(hr, "Can't add SigmaTel Audio Topology to graph");

    //connect TridVid Crossbar and SigmaTel Audio Topology
    hr = pGraph.ConnectDirect(GetPin(pTridVidCrossbar, "0: Video Decoder Out"),
    GetPin(pSigmaTelAudioTopology, "Analog Video In"), null);
    checkHR(hr, "Can't connect TridVid Crossbar and SigmaTel Audio Topology");

    //connect TridVid Crossbar and SigmaTel Audio Topology
    hr = pGraph.ConnectDirect(GetPin(pTridVidCrossbar, "1: Audio Decoder Out"),
    GetPin(pSigmaTelAudioTopology, "Analog Audio In"), null);
    checkHR(hr, "Can't connect TridVid Crossbar and SigmaTel Audio Topology");

    //add Video Renderer
    IBaseFilter pVideoRenderer = (IBaseFilter)Activator.CreateInstance(Type.GetTyp
    eFromCLSID(CLSID_VideoRenderer));
    hr = pGraph.AddFilter(pVideoRenderer, "Video Renderer");
    checkHR(hr, "Can't add Video Renderer to graph");

    //add Default DirectSound Device
    IBaseFilter pDefaultDirectSoundDevice = (IBaseFilter)new DSoundRender();
    hr = pGraph.AddFilter(pDefaultDirectSoundDevice, "Default DirectSound
    Device");
    checkHR(hr, "Can't add Default DirectSound Device to graph");

    //connect SigmaTel Audio Topology and Video Renderer
    hr = pGraph.ConnectDirect(GetPin(pSigmaTelAudioTopology, "Capture"),
    GetPin(pVideoRenderer, "VMR Input0"), null);
    checkHR(hr, "Can't connect SigmaTel Audio Topology and Video Renderer");

    //connect SigmaTel Audio Topology and Default DirectSound Device
    hr = pGraph.ConnectDirect(GetPin(pSigmaTelAudioTopology, "Audio"),
    GetPin(pDefaultDirectSoundDevice, "Audio Input pin (rendered)"), null);
    checkHR(hr, "Can't connect SigmaTel Audio Topology and Default DirectSound
    Device");

    }

    static void Main(string args)
    {
    try
    {
    IGraphBuilder graph = (IGraphBuilder)new FilterGraph();
    Console.WriteLine("Building graph...");
    BuildGraph(graph);
    Console.WriteLine("Running...");
    IMediaControl mediaControl = (IMediaControl)graph;
    IMediaEvent mediaEvent = (IMediaEvent)graph;
    int hr = mediaControl.Run();
    checkHR(hr, "Can't run the graph");
    bool stop = false;
    int n = 0;
    while (!stop)
    {
    System.Threading.Thread.Sleep(500);
    Console.Write(".");
    EventCode ev;
    IntPtr p1, p2;
    if (mediaEvent.GetEvent(out ev, out p1, out p2, 0) == 0)
    {
    if (ev == EventCode.Complete || ev == EventCode.UserAbort)
    {
    Console.WriteLine("Done!");
    stop = true;
    }
    else
    if (ev == EventCode.ErrorAbort)
    {
    Console.WriteLine("An error occured: HRESULT={0:X}", p1);
    mediaControl.Stop();
    stop = true;
    }
    mediaEvent.FreeEventParams(ev, p1, p2);
    }
    // stop after 10 seconds
    n++;
    if (n > 20)
    {
    Console.WriteLine("stopping..");
    mediaControl.Stop();
    stop = true;
    }
    }
    }
    catch (COMException ex)
    {
    Console.WriteLine("COM error: " + ex.ToString());
    }
    catch (Exception ex)
    {
    Console.WriteLine("Error: " + ex.ToString());
    }
    }
    static IPin GetPin(IBaseFilter filter, string pinname)
    {
    IEnumPins epins;
    int hr = filter.EnumPins(out epins);
    checkHR(hr, "Can't enumerate pins");
    IntPtr fetched = Marshal.AllocCoTaskMem(4);
    IPin pins = new IPin;
    while (epins.Next(1, pins, fetched) == 0)
    {
    PinInfo pinfo;
    pins.QueryPinInfo(out pinfo);
    bool found = (pinfo.name == pinname);
    DsUtils.FreePinInfo(pinfo);
    if (found)
    return pins;
    }
    checkHR(hr,"");
    return null;
    }

    }
    }

    (it's not exactly the code from my device but i found that code online and it
    matched the one i got generated

    Not even this works, simply because the getpins funcion doesn't work and is
    unable to find any pins.

    By the way with the Dxtuner program i am unable to get the tv audio device,
    since it does not show up as a device in FilterCategory.AudioInputDevice
    altough it does show up in Graph Edit as a

     
  • cesm1980

    cesm1980 - 2010-01-18

    OH NO i forgot to delete the previous message i was still writing earlier in
    the day, jeez there isn't a edit function in this forum ? I would like you to
    ignore EVERYTHING i said after "Please if you or someone else is able to help
    me on this...", because the most recent message i meant to send was just until
    that sentence, so just read until there.

     

Log in to post a comment.