Menu

Adding audio filters to DxText sample

Gordon
2005-08-28
2012-10-29
  • Gordon

    Gordon - 2005-08-28

    First off, my congratulations for a fine piece of work!

    For my application I need the audio track as well as video. The DxText sample works well, and I've been able to add the two filters necessary for audio (MPEG decoder and renderer), but things refuse to connect. I've gotten what I believe to be valid objects to the pins of these filters, but the program fails at m_graphBuilder.Connect.

    I'm trying this in C# which I (admittedly) don't know all that well. I have a working app in VB where I've done everything using the Quartz library, but I'd like to see about integrating the SampleGrabber interface. In my VB app, I use a third-party text overlay filter in a custom-built graph, but I think I'd like to do it myself. Looks like I'll have more control over stuff.

     
    • Gordon

      Gordon - 2005-08-29

      Yippee! Worked first time out of the box! Now I can get some sleep!! <g>

      Worked with MPEG and all but one of the AVI files I keep around for testing. After 1.1 comes out, I'll revisit the WMV issue.

      Thanks again!!

       
    • snarfle

      snarfle - 2005-08-29

      Glad it is working for you. We are on the verge of releasing v1.1 which has more interfaces defined, more interfaces tested, and more samples.

      I am a big believer in using GraphEdit to troubleshoot these kinds of problems. Have you tried that?

      I'm a little confused about your comment that you have added the MPEG decoder for playing the audio. It is not immediately clear to me why you would need that. I would expect the audio to be wav.

      Are you trying to preview? Or just direct the output to the avi muxer? Tell us more about your graph.

       
    • Gordon

      Gordon - 2005-08-29

      Thanks for the reply.

      Yes, I'm using GraphEdit. And as an FYI, I'm running MPEG-1 files, though the same issues occur with AVI (DxText doesn't like WMV files, apparently).

      Here's what I get.

      1. With the unmodified DxText sample I get the expected video-only graph. There's the Ds.NET source renderer, and auto-inserted is the MPEG splitter, the MPEG video decompressor, and all downstream filters to the renderer (colorspace, AVI decompressor, etc.). There are no audio filters at all.

      2. I've added some code to insert the audio filters I know the graph will need, the MPEG audio decompressor and the DirectSound renderer. When I run the code, these show up in GraphEdit, but of course they are not connected.

      The piece I'm missing is connecting the splitter to the audio side of the stream. I can get the pins to the audio decompressor and audio renderer, but I suspect these won't connect because they are downstream from the splitter, and I need to render left-to-right.

      I can connect up the graph the way I want using the QuartzLib, but I must be missing something simple here. Perhaps I need a reference to the splitter, and connect from there? What is the best way to get an object reference to a filter that is automatically inserted?

      Anyway, I'm using this to add the decompressor:

      ibfDecompressor = (IBaseFilter) new CMpegAudioCodec();
      hr = m_graphBuilder.AddFilter( ibfDecompressor, "MPEG Audio Decoder" );

      And this for the renderer:

      ibfRenderer = (IBaseFilter) new AudioRender();
      hr = m_graphBuilder.AddFilter( ibfRenderer, "Default DirectSound Renderer" );

      Finding the in and out pins for these with DsFindPin works, and GraphEdit shows the correct filters have been added. What doesn't work is m_graphBuilder.Connect. I've tried connecting the pins at various points (before adding Ds.NET Grabber, after, etc.), but no luck.

       
      • snarfle

        snarfle - 2005-08-29

        The piece I don't see you describing is the audio source device.

        If you are capturing live data (which I assume you are since you are using DxText), then you probably want live audio. Use GetDevicesOfCat(FilterCategory.AudioInputDevice) to get the list of available devices. Add the right one to the graph with IFilterGraph2.AddSourceFilterForMoniker, and then connect them as appropriate.

        Hopefully that's what's missing here.

         
    • Gordon

      Gordon - 2005-08-29

      As I noted, I'm running MPEG-1 files on playback, which uses interleaved audio. The splitter gets added automatically in the graph, and it's the audio side of the form that need the help with.

      Though the DxText sample uses the "capture.cs" class, and is found in the Capture example directory, it's been revised by someone to accept a filename, which is rendered with m_graphBuilder.AddSourceFilter. At least in the 1.0 download, DxText isn't for capturing. (Which is good, because I want to open existing files.)

      FWIW, using QuartzTypeLib there is a wrapper function added to an interface called IPinInfo that will auto-connect pins if you select from the sourcefile output. Assuming the filters you've added into the graph are well-behaved, they'll connect themselves correctly, on both sides of the MPEG splitter.

      This is what makes it a little easier with Quartz, although that's about the only thing! <g>

       
      • snarfle

        snarfle - 2005-08-29

        Ok, my bad. I was sure the DxText was a capture program, but you are quite right, it is a player app. I knew we weren't connecting somehow, but it didn't click.

        The automated functions provided by quartz are probably ICaptureGraphBuilder2.RenderStream() under the covers. See what you get in GraphEdit from right-clicking on the unconnected pin of the splitter and choosing render pin.

        You should be able to achieve the same results programmatically with:

        hr = icgb.RenderStream(null, null, (IBaseFilter)ibfSplitter, null, null);

        The trick is getting the ibfSplitter. Or do you already have it?

         
    • Gordon

      Gordon - 2005-08-29

      Thanks for the help...much appreciated.

      In GraphEdit, right-clicking on the unconnected "Audio" pin of the MPEG-I Stream Splitter does indeed connect up the rest of the graph.

      I was not able to have much success with the RenderStream idea. I'm pretty sure I have the right pointer to the splitter filter, as I decided to manually add that too, right after the FileReader.

      So to recap, I'm adding the following filters up front:

      MPEG-I Stream Splitter
      MPEG Audio Decoder
      Default DirectSound Renderer
      Ds.NET Grabber (same as the original sample)

      I tried adding RenderStream in a couple of logical places (it has to be after the other pins are connected I imagine), but no luck.

      Are there any samples of video and audio from file sources in custom filtergraphs among the new 1.1 files? Would love to see one.

      Thanks, again.

       
      • snarfle

        snarfle - 2005-08-29

        Sorry, no audio samples. However, I just updated DxText to support it.

        Starting from the original file, add

        ICaptureGraphBuilder2 icgb = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();
        hr = icgb.SetFiltergraph(m_graphBuilder);
        DsError.ThrowExceptionForHR( hr );

        near the top of SetupGraph, then add

        hr = icgb.RenderStream(null, MediaType.Audio, capFilter, null, null);
        DsError.ThrowExceptionForHR( hr );

        just before the call to SaveSizeInfo(). Works with my avi file.

         

Log in to post a comment.