Hatena::Groupcoders

ラシウラ出張所 このページをアンテナに追加 RSSフィード

2007/07/19

[][] DirectShowフィルタを列挙するコマンドラインツール  DirectShowフィルタを列挙するコマンドラインツール - ラシウラ出張所 を含むブックマーク はてなブックマーク -  DirectShowフィルタを列挙するコマンドラインツール - ラシウラ出張所  DirectShowフィルタを列挙するコマンドラインツール - ラシウラ出張所 のブックマークコメント

.NET 2.0以上でかつDirectShowLibを使います。

ソースコード

listfilters.cs

using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using DirectShowLib;

namespace listfilters {
  class Program {
    static void Main(string[] args) {
      IFilterMapper3 filterMapper = new FilterMapper2() as IFilterMapper3;
      ICreateDevEnum devEnum;
      filterMapper.GetICreateDevEnum(out devEnum);
      Guid[] categories = new Guid[] {
        FilterCategory.LegacyAmFilterCategory,
        FilterCategory.AudioCompressorCategory,
        FilterCategory.VideoCompressorCategory,
        //FilterCategory.BDASourceFiltersCategory,
      };
      foreach (Guid category in categories) {
        //Console.WriteLine();
        //Console.WriteLine("new category: " + category);
        
        IEnumMoniker monikers;
        devEnum.CreateClassEnumerator(category, out monikers, CDef.None);
        monikers.Reset();
        IntPtr count = new IntPtr();
        IMoniker[] moniker = new IMoniker[1];
        while (monikers.Next(1, moniker, count) == 0) {
          Console.WriteLine("Filter: \"" + GetFilterName(moniker[0]) + "\"");
          try {
            IBaseFilter filter = GetFilter(moniker[0]);
            IEnumPins pins;
            filter.EnumPins(out pins);
            int pinCount;
            IPin[] pin = new IPin[1];
            while (pins.Next(1, pin, out pinCount) == 0) {
              PinInfo info;
              pin[0].QueryPinInfo(out info);
              Console.WriteLine("  Pin " + info.dir + ": \"" + info.name + "\"");
            }
          } catch (Exception ex) {
            //Console.WriteLine(ex);
          } finally {
            Marshal.ReleaseComObject(moniker[0]);
          }
        }
        Marshal.ReleaseComObject(monikers);
      }
      Marshal.ReleaseComObject(devEnum);
    }
    
    static IBaseFilter GetFilter(IMoniker filterMoniker) {
      object filterObj;
      Guid baseFilterId = typeof(IBaseFilter).GUID;
      filterMoniker.BindToObject(null, null, ref baseFilterId, out filterObj);
      IBaseFilter filter = filterObj as IBaseFilter;
      return filter;
    }
    
    static string GetFilterName(IMoniker filterMoniker) {
      object bagObj;
      Guid propertyBagId = typeof(IPropertyBag).GUID;
      filterMoniker.BindToStorage(null, null, ref propertyBagId, out bagObj);
      IPropertyBag bag = bagObj as IPropertyBag;
      object nameObj;
      bag.Read("FriendlyName", out nameObj, null);
      string name = nameObj as string;
      Marshal.ReleaseComObject(bagObj);
      return name;
    }
  }
}

ビルド

csc.exe /r:DirectShowLib-2005.dll /platform:x86 listfilters.cs

実行例

$ ./listfilters.exe 
Filter: "WMAudio Decoder DMO"
  Pin Input: "in0"
  Pin Output: "out0"
Filter: "WMAPro over S/PDIF DMO"
  Pin Input: "in0"
  Pin Output: "out0"
Filter: "WMSpeech Decoder DMO"
  Pin Input: "in0"
  Pin Output: "out0"
...

コマンドラインツールだけれど、フィルタによっては、アクセス時にダイアログを出すものがあります。

また、実際にピンを接続したあとで新たなピンが出てくるフィルタもあります(AVI MuxのInputなど)。

ヒント

  • DirectShow自体になれていないなら、GraphEditでマルチメディアデータをいろいろいじるところからはじめる
    • source/splitter/audio encoder/audio decoder/video decoder/video encoder/muxer/sink概念くらいは理解しておく必要はある

履歴