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
     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     if (!pin_enum)
     76       return E_OUTOFMEMORY;
     77     pin_enum->AddRef();
     78     pin_enum->index_ = index_;
     79     *clone = pin_enum;
     80     return S_OK;
     81   }
     82 
     83  private:
     84   scoped_refptr<FilterBase> filter_;
     85   size_t index_;
     86 };
     87 
     88 FilterBase::FilterBase() : state_(State_Stopped) {
     89 }
     90 
     91 FilterBase::~FilterBase() {
     92 }
     93 
     94 STDMETHODIMP FilterBase::EnumPins(IEnumPins** enum_pins) {
     95   *enum_pins = new PinEnumerator(this);
     96   (*enum_pins)->AddRef();
     97   return S_OK;
     98 }
     99 
    100 STDMETHODIMP FilterBase::FindPin(LPCWSTR id, IPin** pin) {
    101   return E_NOTIMPL;
    102 }
    103 
    104 STDMETHODIMP FilterBase::QueryFilterInfo(FILTER_INFO* info) {
    105   info->pGraph = owning_graph_;
    106   info->achName[0] = L'\0';
    107   if (info->pGraph)
    108     info->pGraph->AddRef();
    109   return S_OK;
    110 }
    111 
    112 STDMETHODIMP FilterBase::JoinFilterGraph(IFilterGraph* graph, LPCWSTR name) {
    113   owning_graph_ = graph;
    114   return S_OK;
    115 }
    116 
    117 STDMETHODIMP FilterBase::QueryVendorInfo(LPWSTR *pVendorInfo) {
    118   return S_OK;
    119 }
    120 
    121 // Implement IMediaFilter.
    122 STDMETHODIMP FilterBase::Stop() {
    123   state_ = State_Stopped;
    124   return S_OK;
    125 }
    126 
    127 STDMETHODIMP FilterBase::Pause() {
    128   state_ = State_Paused;
    129   return S_OK;
    130 }
    131 
    132 STDMETHODIMP FilterBase::Run(REFERENCE_TIME start) {
    133   state_ = State_Running;
    134   return S_OK;
    135 }
    136 
    137 STDMETHODIMP FilterBase::GetState(DWORD msec_timeout, FILTER_STATE* state) {
    138   *state = state_;
    139   return S_OK;
    140 }
    141 
    142 STDMETHODIMP FilterBase::SetSyncSource(IReferenceClock* clock) {
    143   return S_OK;
    144 }
    145 
    146 STDMETHODIMP FilterBase::GetSyncSource(IReferenceClock** clock) {
    147   return E_NOTIMPL;
    148 }
    149 
    150 // Implement from IPersistent.
    151 STDMETHODIMP FilterBase::GetClassID(CLSID* class_id) {
    152   NOTREACHED();
    153   return E_NOTIMPL;
    154 }
    155 
    156 // Implement IUnknown.
    157 STDMETHODIMP FilterBase::QueryInterface(REFIID id, void** object_ptr) {
    158   if (id == IID_IMediaFilter || id == IID_IUnknown) {
    159     *object_ptr = static_cast<IMediaFilter*>(this);
    160   } else if (id == IID_IPersist) {
    161     *object_ptr = static_cast<IPersist*>(this);
    162   } else {
    163     return E_NOINTERFACE;
    164   }
    165   AddRef();
    166   return S_OK;
    167 }
    168 
    169 ULONG STDMETHODCALLTYPE FilterBase::AddRef() {
    170   base::RefCounted<FilterBase>::AddRef();
    171   return 1;
    172 }
    173 
    174 ULONG STDMETHODCALLTYPE FilterBase::Release() {
    175   base::RefCounted<FilterBase>::Release();
    176   return 1;
    177 }
    178 
    179 }  // namespace media
    180