OLD | NEW |
1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // A filter factory handles the creation of filters given a FilterType (i.e., | 5 // A filter factory handles the creation of filters given a FilterType (i.e., |
6 // FILTER_AUDIO_DECODER) and a MediaFormat. Generally a filter factory handles | 6 // FILTER_AUDIO_DECODER) and a MediaFormat. Generally a filter factory handles |
7 // creating a single type of filter, with multiple factories combined into a | 7 // creating a single type of filter, with multiple factories combined into a |
8 // FilterFactoryCollection. We use some template tricks to enforce type-safety | 8 // FilterFactoryCollection. We use some template tricks to enforce type-safety |
9 // and eliminate casting for callers. | 9 // and eliminate casting for callers. |
10 // | 10 // |
11 // The majority of applications will only use FilterFactoryCollection since | 11 // The majority of applications will only use FilterFactoryCollection since |
12 // filter factory classes can be created from templates: | 12 // filter factory classes can be created from templates: |
13 // FilterFactoryCollection filter_factory = new FilterFactoryCollection(); | 13 // FilterFactoryCollection filter_factory = new FilterFactoryCollection(); |
14 // filter_factory->AddFactory(new TypeFilterFactory<YourAudioDecoder>()); | 14 // filter_factory->AddFactory(new TypeFilterFactory<YourAudioDecoder>()); |
15 // filter_factory->AddFactory(new TypeFilterFactory<YourAudioRenderer>()); | 15 // filter_factory->AddFactory(new TypeFilterFactory<YourAudioRenderer>()); |
16 // etc... | 16 // etc... |
17 // AudioDecoder* filter; | 17 // AudioDecoder* filter; |
18 // if (filter_factory->Create<AudioDecoder>(media_format, &filter) { | 18 // if (filter_factory->Create<AudioDecoder>(media_format, &filter) { |
19 // do stuff with the filter... | 19 // do stuff with the filter... |
20 // } | 20 // } |
21 // | 21 // |
22 // The only requirement is that your filter implementation provide a static | 22 // The only requirement is that your filter implementation provide a static |
23 // Create method with the following signature: | 23 // Create method with the following signature: |
24 // | 24 // |
25 // Returns true and assigns |filter_out| if the filter was created, false | 25 // Returns true and assigns |filter_out| if the filter was created, false |
26 // and assigns NULL otherwise. | 26 // and assigns NULL otherwise. |
27 // static bool Create(MediaFormat* media_format, YourFilterType** filter_out); | 27 // static bool Create(MediaFormat& media_format, YourFilterType** filter_out); |
28 // | 28 // |
29 | 29 |
30 #ifndef MEDIA_BASE_FACTORY_H_ | 30 #ifndef MEDIA_BASE_FACTORY_H_ |
31 #define MEDIA_BASE_FACTORY_H_ | 31 #define MEDIA_BASE_FACTORY_H_ |
32 | 32 |
33 #include <vector> | 33 #include <vector> |
34 | 34 |
35 #include "base/ref_counted.h" | 35 #include "base/ref_counted.h" |
36 #include "media/base/filters.h" | 36 #include "media/base/filters.h" |
37 | 37 |
38 namespace media { | 38 namespace media { |
39 | 39 |
40 class FilterFactoryCollection; | 40 class FilterFactoryCollection; |
41 | 41 |
42 class FilterFactory : public base::RefCountedThreadSafe<FilterFactory> { | 42 class FilterFactory : public base::RefCountedThreadSafe<FilterFactory> { |
43 public: | 43 public: |
44 // Creates a filter implementing the specified interface. Hides the casting | 44 // Creates a filter implementing the specified interface. Hides the casting |
45 // and FilterType constants from the callers and produces cleaner code: | 45 // and FilterType constants from the callers and produces cleaner code: |
46 // socped_refptr<MyAudioDecoder> d = Create<MyAudioDecoder>(media_format); | 46 // socped_refptr<MyAudioDecoder> d = Create<MyAudioDecoder>(media_format); |
47 // If the factory does not support the specific filter type or does not | 47 // If the factory does not support the specific filter type or does not |
48 // support the |media_format| then NULL is returned. | 48 // support the |media_format| then NULL is returned. |
49 template <class Filter> | 49 template <class Filter> |
50 Filter* Create(const MediaFormat* media_format) { | 50 Filter* Create(const MediaFormat& media_format) { |
51 return reinterpret_cast<Filter*>(Create(Filter::filter_type(), | 51 return reinterpret_cast<Filter*>(Create(Filter::filter_type(), |
52 media_format)); | 52 media_format)); |
53 } | 53 } |
54 | 54 |
55 protected: | 55 protected: |
56 // For accessing the protected version of Create. | 56 // For accessing the protected version of Create. |
57 friend class FilterFactoryCollection; | 57 friend class FilterFactoryCollection; |
58 | 58 |
59 // Attempt to create a filter of the given type using the information stored | 59 // Attempt to create a filter of the given type using the information stored |
60 // in |media_format|. If successful, the filter is returned. If the filter | 60 // in |media_format|. If successful, the filter is returned. If the filter |
61 // cannot be created for any reason, NULL is returned. | 61 // cannot be created for any reason, NULL is returned. |
62 // | 62 // |
63 // It is assumed that the MediaFilter interface can be safely cast to the | 63 // It is assumed that the MediaFilter interface can be safely cast to the |
64 // corresponding interface type (i.e., FILTER_AUDIO_DECODER -> AudioDecoder). | 64 // corresponding interface type (i.e., FILTER_AUDIO_DECODER -> AudioDecoder). |
65 virtual MediaFilter* Create(FilterType filter_type, | 65 virtual MediaFilter* Create(FilterType filter_type, |
66 const MediaFormat* media_format) = 0; | 66 const MediaFormat& media_format) = 0; |
67 | 67 |
68 friend class base::RefCountedThreadSafe<FilterFactory>; | 68 friend class base::RefCountedThreadSafe<FilterFactory>; |
69 virtual ~FilterFactory() {} | 69 virtual ~FilterFactory() {} |
70 }; | 70 }; |
71 | 71 |
72 | 72 |
73 // Maintains a collection of FilterFactories. | 73 // Maintains a collection of FilterFactories. |
74 class FilterFactoryCollection : public FilterFactory { | 74 class FilterFactoryCollection : public FilterFactory { |
75 public: | 75 public: |
76 FilterFactoryCollection() {} | 76 FilterFactoryCollection() {} |
77 | 77 |
78 // Adds a factory to the end of the collection. | 78 // Adds a factory to the end of the collection. |
79 void AddFactory(FilterFactory* factory) { | 79 void AddFactory(FilterFactory* factory) { |
80 factories_.push_back(factory); | 80 factories_.push_back(factory); |
81 } | 81 } |
82 | 82 |
83 protected: | 83 protected: |
84 // Attempts to create a filter by walking down the list of filter factories. | 84 // Attempts to create a filter by walking down the list of filter factories. |
85 MediaFilter* Create(FilterType filter_type, const MediaFormat* media_format) { | 85 MediaFilter* Create(FilterType filter_type, const MediaFormat& media_format) { |
86 MediaFilter* filter = NULL; | 86 MediaFilter* filter = NULL; |
87 for (FactoryVector::iterator factory = factories_.begin(); | 87 for (FactoryVector::iterator factory = factories_.begin(); |
88 !filter && factory != factories_.end(); | 88 !filter && factory != factories_.end(); |
89 ++factory) { | 89 ++factory) { |
90 filter = (*factory)->Create(filter_type, media_format); | 90 filter = (*factory)->Create(filter_type, media_format); |
91 } | 91 } |
92 return filter; | 92 return filter; |
93 } | 93 } |
94 | 94 |
95 private: | 95 private: |
(...skipping 10 matching lines...) Expand all Loading... |
106 // Create method then they should implement the static method | 106 // Create method then they should implement the static method |
107 // IsMediaFormatSupported. Classes should implement their contructor as private | 107 // IsMediaFormatSupported. Classes should implement their contructor as private |
108 // and make FilterFactoryImpl<MyClass> a friend class. | 108 // and make FilterFactoryImpl<MyClass> a friend class. |
109 template <class Filter> | 109 template <class Filter> |
110 class FilterFactoryImpl0 : public FilterFactory { | 110 class FilterFactoryImpl0 : public FilterFactory { |
111 public: | 111 public: |
112 FilterFactoryImpl0() {} | 112 FilterFactoryImpl0() {} |
113 | 113 |
114 protected: | 114 protected: |
115 virtual MediaFilter* Create(FilterType filter_type, | 115 virtual MediaFilter* Create(FilterType filter_type, |
116 const MediaFormat* media_format) { | 116 const MediaFormat& media_format) { |
117 Filter* filter = NULL; | 117 Filter* filter = NULL; |
118 if (Filter::filter_type() == filter_type && | 118 if (Filter::filter_type() == filter_type && |
119 Filter::IsMediaFormatSupported(media_format)) { | 119 Filter::IsMediaFormatSupported(media_format)) { |
120 filter = new Filter(); | 120 filter = new Filter(); |
121 } | 121 } |
122 return filter; | 122 return filter; |
123 } | 123 } |
124 | 124 |
125 private: | 125 private: |
126 DISALLOW_COPY_AND_ASSIGN(FilterFactoryImpl0); | 126 DISALLOW_COPY_AND_ASSIGN(FilterFactoryImpl0); |
127 }; | 127 }; |
128 | 128 |
129 // This template can be used by classes that need to be constructed with a | 129 // This template can be used by classes that need to be constructed with a |
130 // parameter that needs to be used in the construction of the actual filter. | 130 // parameter that needs to be used in the construction of the actual filter. |
131 // This would usually be a "parent" object which the instantiated filter needs | 131 // This would usually be a "parent" object which the instantiated filter needs |
132 // to communicate with. The class's CreateFactory method would look like: | 132 // to communicate with. The class's CreateFactory method would look like: |
133 // static FilterFactory* CreateFactory(MyRequiredParentClass* parent) { | 133 // static FilterFactory* CreateFactory(MyRequiredParentClass* parent) { |
134 // return new FilterFactoryImpl1<MyClass>(parent); | 134 // return new FilterFactoryImpl1<MyClass>(parent); |
135 // } | 135 // } |
136 // The class would be constructed with the same pointer passed to the | 136 // The class would be constructed with the same pointer passed to the |
137 // CreateFactory method. | 137 // CreateFactory method. |
138 template <class Filter, class A> | 138 template <class Filter, class A> |
139 class FilterFactoryImpl1 : public FilterFactory { | 139 class FilterFactoryImpl1 : public FilterFactory { |
140 public: | 140 public: |
141 explicit FilterFactoryImpl1(A a) : a_(a) {} | 141 explicit FilterFactoryImpl1(A a) : a_(a) {} |
142 | 142 |
143 protected: | 143 protected: |
144 virtual MediaFilter* Create(FilterType filter_type, | 144 virtual MediaFilter* Create(FilterType filter_type, |
145 const MediaFormat* media_format) { | 145 const MediaFormat& media_format) { |
146 Filter* filter = NULL; | 146 Filter* filter = NULL; |
147 if (Filter::filter_type() == filter_type && | 147 if (Filter::filter_type() == filter_type && |
148 Filter::IsMediaFormatSupported(media_format)) { | 148 Filter::IsMediaFormatSupported(media_format)) { |
149 filter = new Filter(a_); | 149 filter = new Filter(a_); |
150 } | 150 } |
151 return filter; | 151 return filter; |
152 } | 152 } |
153 | 153 |
154 private: | 154 private: |
155 A const a_; | 155 A const a_; |
(...skipping 15 matching lines...) Expand all Loading... |
171 template <class Filter> | 171 template <class Filter> |
172 class InstanceFilterFactory : public FilterFactory { | 172 class InstanceFilterFactory : public FilterFactory { |
173 public: | 173 public: |
174 explicit InstanceFilterFactory(Filter* filter) | 174 explicit InstanceFilterFactory(Filter* filter) |
175 : filter_(filter), | 175 : filter_(filter), |
176 create_called_(false) { | 176 create_called_(false) { |
177 } | 177 } |
178 | 178 |
179 protected: | 179 protected: |
180 virtual MediaFilter* Create(FilterType filter_type, | 180 virtual MediaFilter* Create(FilterType filter_type, |
181 const MediaFormat* media_format) { | 181 const MediaFormat& media_format) { |
182 if (Filter::filter_type() == filter_type && | 182 if (Filter::filter_type() == filter_type && |
183 Filter::IsMediaFormatSupported(media_format)) { | 183 Filter::IsMediaFormatSupported(media_format)) { |
184 if (!create_called_) { | 184 if (!create_called_) { |
185 create_called_ = true; | 185 create_called_ = true; |
186 return filter_; | 186 return filter_; |
187 } else { | 187 } else { |
188 NOTREACHED(); | 188 NOTREACHED(); |
189 } | 189 } |
190 } | 190 } |
191 return NULL; | 191 return NULL; |
192 } | 192 } |
193 | 193 |
194 private: | 194 private: |
195 scoped_refptr<Filter> filter_; | 195 scoped_refptr<Filter> filter_; |
196 bool create_called_; | 196 bool create_called_; |
197 | 197 |
198 DISALLOW_COPY_AND_ASSIGN(InstanceFilterFactory); | 198 DISALLOW_COPY_AND_ASSIGN(InstanceFilterFactory); |
199 }; | 199 }; |
200 | 200 |
201 } // namespace media | 201 } // namespace media |
202 | 202 |
203 #endif // MEDIA_BASE_FACTORY_H_ | 203 #endif // MEDIA_BASE_FACTORY_H_ |
OLD | NEW |