/* GStreamer
 * Copyright (C) 2007 Sebastien Moutte <sebastien@moutte.net>
 *
 * gstdshow.cpp:
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include <dmodshow.h>
#include <dmoreg.h>

#include "gstdshowutil.h"
#include "gstdshowfakesrc.h"

_COM_SMARTPTR_TYPEDEF(IDMOWrapperFilter, __uuidof(IDMOWrapperFilter));

IPin * 
gst_dshow_get_pin_from_filter (IBaseFilter *filter, PIN_DIRECTION pindir)
{
  IEnumPinsPtr enumpins;
  IPinPtr pin;
  HRESULT hres; 

  hres = filter->EnumPins (&enumpins);
  if (FAILED(hres)) {
    return NULL;
  }

  while (enumpins->Next (1, &pin, NULL) == S_OK)
  {
    PIN_DIRECTION pindirtmp;
    hres = pin->QueryDirection (&pindirtmp);
    if (hres == S_OK && pindir == pindirtmp) {
      return pin;
    }
    pin.Release();
  }

  return NULL;
}

IBaseFilter * 
gst_dshow_find_filter(CLSID input_majortype, CLSID input_subtype, 
                      CLSID output_majortype, CLSID output_subtype, 
                      PreferredFilter *preferred_filters)
{
  HRESULT hres;
  GUID inTypes[2];
  GUID outTypes[2];
  IFilterMapper2Ptr mapper;
  IEnumMonikerPtr enum_moniker;
  IMonikerPtr moniker;
  ULONG fetched;
  IBaseFilter *filter;

  /* First, see if any of our preferred filters is available.
   * If not, we fall back to the highest-ranked installed filter */
  if (preferred_filters) {
    while (preferred_filters->filter_guid) 
    {
      /* If the filter is a DMO, we need to do this a bit differently */
      if (preferred_filters->dmo_category) 
      {
        IDMOWrapperFilterPtr wrapper;

        hres = CoCreateInstance (CLSID_DMOWrapperFilter, NULL, 
          CLSCTX_INPROC,
          IID_IBaseFilter, (void **)&filter);
        if (SUCCEEDED(hres)) {
          hres = filter->QueryInterface (&wrapper);
          if (SUCCEEDED(hres)) {
            hres = wrapper->Init (*preferred_filters->filter_guid, 
                *preferred_filters->dmo_category);
            if (SUCCEEDED(hres))
              return filter;
          }
          filter->Release();
        }
      }
      else 
      {
        hres = CoCreateInstance (*preferred_filters->filter_guid, 
          NULL, CLSCTX_INPROC,
          IID_IBaseFilter, (void **)&filter);
        if (SUCCEEDED(hres))
          return filter;
      }

      /* Continue to the next filter */
      preferred_filters++;
    }
  }

  hres = CoCreateInstance(CLSID_FilterMapper2, NULL, CLSCTX_INPROC, 
      IID_IFilterMapper2, (void **) &mapper);
  if (FAILED(hres))
    return NULL;
  
  inTypes[0] = input_majortype;
  inTypes[1] = input_subtype;
  outTypes[0] = output_majortype;
  outTypes[1] = output_subtype;

  hres = mapper->EnumMatchingFilters (&enum_moniker, 0, 
          FALSE, MERIT_DO_NOT_USE+1, 
          TRUE, 1, inTypes, NULL, NULL, FALSE, 
          TRUE, 1, outTypes, NULL, NULL);
  if (FAILED(hres))
    return NULL;
  
  enum_moniker->Reset ();

  while(enum_moniker->Next (1, &moniker, &fetched) == S_OK)
  {
    hres = moniker->BindToObject(NULL, NULL, 
          IID_IBaseFilter, (void**)&filter);
    if(SUCCEEDED(hres)) {
      return filter;
    }
    moniker.Release ();
  }

  return NULL;
}

