Home | History | Annotate | Download | only in win
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "media/video/capture/win/filter_base_win.h"
      6 
      7 #pragma comment(lib, "strmiids.lib")
      8 
      9 namespace media {
     10 
     11 // Implement IEnumPins.
     12 class PinEnumerator FINAL
     13     : public IEnumPins,
     14       public base::RefCounted<PinEnumerator> {
     15  public:
     16   explicit PinEnumerator(FilterBase* filter)
     17       : filter_(filter),
     18       index_(0) {
     19   }
     20 
     21   ~PinEnumerator() {
     22   }
     23 
     24   // IUnknown implementation.
     25   STDMETHOD(QueryInterface)(REFIID iid, void** object_ptr) {
     26     if (iid == IID_IEnumPins || iid == IID_IUnknown) {
     27       AddRef();
     28       *object_ptr = static_cast<IEnumPins*>(this);
     29       return S_OK;
     30     }
     31     return E_NOINTERFACE;
     32   }
     33 
     34   STDMETHOD_(ULONG, AddRef)() {
     35     base::RefCounted<PinEnumerator>::AddRef();
     36     return 1;
     37   }
     38 
     39   STDMETHOD_(ULONG, Release)() {
     40     base::RefCounted<PinEnumerator>::Release();
     41     return 1;
     42   }
     43 
     44   // Implement IEnumPins.
     45   STDMETHOD(Next)(ULONG count, IPin** pins, ULONG* fetched) {
     46     ULONG pins_fetched = 0;
     47     while (pins_fetched < count && filter_->NoOfPins() > index_) {
     48       IPin* pin = filter_->GetPin(index_++);
     49       pin->AddRef();
     50       pins[pins_fetched++] = pin;
     51     }
     52 
     53     if (fetched)
     54       *fetched =  pins_fetched;
     55 
     56     return pins_fetched == count ? S_OK : S_FALSE;
     57   }
     58 
     59   STDMETHOD(Skip)(ULONG count) {
     60     if (filter_->NoOfPins()- index_ > count) {
     61       index_ += count;
     62       return S_OK;
     63     }
     64     index_ = 0;
     65     return S_FALSE;
     66   }
     67 
     68   STDMETHOD(Reset)() {
     69     index_ = 0;
     70     return S_OK;
     71   }
     72 
     73   STDMETHOD(Clone)(IEnumPins** clone) {
     74     PinEnumerator* pin_enum = new PinEnumerator(filter_);
     75     pin_enum->AddRef();
     76     pin_enum->index_ = index_;
     77     *clone = pin_enum;
     78     return S_OK;
     79   }
     80 
     81  private:
     82   scoped_refptr<FilterBase> filter_;
     83   size_t index_;
     84 };
     85 
     86 FilterBase::FilterBase() : state_(State_Stopped) {
     87 }
     88 
     89 FilterBase::~FilterBase() {
     90 }
     91 
     92 STDMETHODIMP FilterBase::EnumPins(IEnumPins** enum_pins) {
     93   *enum_pins = new PinEnumerator(this);
     94   (*enum_pins)->AddRef();
     95   return S_OK;
     96 }
     97 
     98 STDMETHODIMP FilterBase::FindPin(LPCWSTR id, IPin** pin) {
     99   return E_NOTIMPL;
    100 }
    101 
    102 STDMETHODIMP FilterBase::QueryFilterInfo(FILTER_INFO* info) {
    103   info->pGraph = owning_graph_;
    104   info->achName[0] = L'\0';
    105   if (info->pGraph)
    106     info->pGraph->AddRef();
    107   return S_OK;
    108 }
    109 
    110 STDMETHODIMP FilterBase::JoinFilterGraph(IFilterGraph* graph, LPCWSTR name) {
    111   owning_graph_ = graph;
    112   return S_OK;
    113 }
    114 
    115 STDMETHODIMP FilterBase::QueryVendorInfo(LPWSTR *pVendorInfo) {
    116   return S_OK;
    117 }
    118 
    119 // Implement IMediaFilter.
    120 STDMETHODIMP FilterBase::Stop() {
    121   state_ = State_Stopped;
    122   return S_OK;
    123 }
    124 
    125 STDMETHODIMP FilterBase::Pause() {
    126   state_ = State_Paused;
    127   return S_OK;
    128 }
    129 
    130 STDMETHODIMP FilterBase::Run(REFERENCE_TIME start) {
    131   state_ = State_Running;
    132   return S_OK;
    133 }
    134 
    135 STDMETHODIMP FilterBase::GetState(DWORD msec_timeout, FILTER_STATE* state) {
    136   *state = state_;
    137   return S_OK;
    138 }
    139 
    140 STDMETHODIMP FilterBase::SetSyncSource(IReferenceClock* clock) {
    141   return S_OK;
    142 }
    143 
    144 STDMETHODIMP FilterBase::GetSyncSource(IReferenceClock** clock) {
    145   return E_NOTIMPL;
    146 }
    147 
    148 // Implement from IPersistent.
    149 STDMETHODIMP FilterBase::GetClassID(CLSID* class_id) {
    150   NOTREACHED();
    151   return E_NOTIMPL;
    152 }
    153 
    154 // Implement IUnknown.
    155 STDMETHODIMP FilterBase::QueryInterface(REFIID id, void** object_ptr) {
    156   if (id == IID_IMediaFilter || id == IID_IUnknown) {
    157     *object_ptr = static_cast<IMediaFilter*>(this);
    158   } else if (id == IID_IPersist) {
    159     *object_ptr = static_cast<IPersist*>(this);
    160   } else {
    161     return E_NOINTERFACE;
    162   }
    163   AddRef();
    164   return S_OK;
    165 }
    166 
    167 ULONG STDMETHODCALLTYPE FilterBase::AddRef() {
    168   base::RefCounted<FilterBase>::AddRef();
    169   return 1;
    170 }
    171 
    172 ULONG STDMETHODCALLTYPE FilterBase::Release() {
    173   base::RefCounted<FilterBase>::Release();
    174   return 1;
    175 }
    176 
    177 }  // namespace media
    178