summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-01-15 02:07:51 +0000
committerscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-01-15 02:07:51 +0000
commitcd5d1ee7279537830a95169766f81fec69b6bd1b (patch)
tree2bfd6de0eb22a9aeb5da66fd346bc1d1e912af0d /media
parentb89b5632c6d7c222fcef32ee2911d091641eefb7 (diff)
downloadchromium_src-cd5d1ee7279537830a95169766f81fec69b6bd1b.zip
chromium_src-cd5d1ee7279537830a95169766f81fec69b6bd1b.tar.gz
chromium_src-cd5d1ee7279537830a95169766f81fec69b6bd1b.tar.bz2
Checking in filter factory code.
Read the comments in media/base/factory.h for details. Review URL: http://codereview.chromium.org/17257 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@8071 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r--media/base/factory.h136
-rw-r--r--media/build/media.vcproj4
2 files changed, 140 insertions, 0 deletions
diff --git a/media/base/factory.h b/media/base/factory.h
new file mode 100644
index 0000000..f735fe1
--- /dev/null
+++ b/media/base/factory.h
@@ -0,0 +1,136 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// A filter factory handles the creation of filters given a FilterType (i.e.,
+// FILTER_AUDIO_DECODER) and a MediaFormat. Generally a filter factory handles
+// creating a single type of filter, with multiple factories combined into a
+// FilterFactoryCollection. We use some template tricks to enforce type-safety
+// and eliminate casting for callers.
+//
+// The majority of applications will only use FilterFactoryCollection since
+// filter factory classes can be created from templates:
+// FilterFactoryCollection filter_factory = new FilterFactoryCollection();
+// filter_factory->AddFactory(new TypeFilterFactory<YourAudioDecoder>());
+// filter_factory->AddFactory(new TypeFilterFactory<YourAudioRenderer>());
+// etc...
+// AudioDecoderInterface* filter;
+// if (filter_factory->Create<AudioDecoderInterface>(media_format, &filter) {
+// do stuff with the filter...
+// }
+//
+// The only requirement is that your filter implementation provide a static
+// Create method with the following signature:
+//
+// Returns true and assigns |filter_out| if the filter was created, false
+// and assigns NULL otherwise.
+// static bool Create(MediaFormat* media_format, YourFilterType** filter_out);
+//
+
+#ifndef MEDIA_BASE_FACTORY_H_
+#define MEDIA_BASE_FACTORY_H_
+
+#include <vector>
+
+#include "base/ref_counted.h"
+#include "media/base/filters.h"
+
+namespace media {
+
+class FilterFactoryCollection;
+
+class FilterFactory : base::RefCountedThreadSafe<FilterFactory> {
+ public:
+ // Creates a filter implementing the specified interface. Hides the casting
+ // and FilterType constants from the callers and produces cleaner code:
+ // AudioDecoderInterface* filter = NULL;
+ // bool success = Create<AudioDecoderInterface>(media_format, &filter);
+ template <class T>
+ bool Create(const MediaFormat* media_format, T** filter_out) {
+ return Create(T::kFilterType, media_format,
+ reinterpret_cast<MediaFilterInterface**>(filter_out));
+ }
+
+ protected:
+ // For accessing the protected version of Create.
+ friend class FilterFactoryCollection;
+
+ // Attempt to create a filter of the given type using the information stored
+ // in |media_format|. If successful, the filter is assigned to |filter_out|
+ // and the method returns true. If the filter cannot be created for any
+ // reason, |filter_out| is assigned NULL and false it returned.
+ //
+ // It is assumed that |filter_out| can be safely casted to the corresponding
+ // interface type (i.e., FILTER_AUDIO_DECODER -> AudioDecoderInterface).
+ virtual bool Create(FilterType filter_type, const MediaFormat* media_format,
+ MediaFilterInterface** filter_out) = 0;
+
+ friend class base::RefCountedThreadSafe<FilterFactory>;
+ virtual ~FilterFactory() {}
+};
+
+
+// Helper template class for implementing trivial filter factories. If your
+// filter does not require any special handling during creation, you can create
+// a factory for it using this class. It requires the following static method:
+// bool Create(MediaFormat* media_format, YourFilterType** filter_out)
+//
+// You can create the filter factory like so:
+// new TypeFilterFactory<YourFilterType>()
+template <class T>
+class TypeFilterFactory : public FilterFactory {
+ public:
+ TypeFilterFactory() {}
+
+ protected:
+ // Attempts to create a filter of the template type. Assumes a static method
+ // Create is declared.
+ virtual bool Create(FilterType filter_type, const MediaFormat* media_format,
+ MediaFilterInterface** filter_out) {
+ T* typed_out;
+ if (T::kFilterType == filter_type && T::Create(media_format, &typed_out)) {
+ *filter_out = typed_out;
+ return true;
+ }
+ return false;
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TypeFilterFactory);
+};
+
+
+// Maintains a collection of FilterFactories.
+class FilterFactoryCollection : public FilterFactory {
+ public:
+ FilterFactoryCollection() {}
+
+ // Adds a factory to the end of the collection.
+ void AddFactory(FilterFactory* factory) {
+ factories_.push_back(factory);
+ }
+
+ protected:
+ // Attempts to create a filter by walking down the list of filter factories.
+ bool Create(FilterType filter_type, const MediaFormat* media_format,
+ MediaFilterInterface** filter_out) {
+ for (FactoryVector::iterator factory = factories_.begin();
+ factory != factories_.end();
+ ++factory) {
+ if ((*factory)->Create(filter_type, media_format, filter_out)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private:
+ typedef std::vector< scoped_refptr<FilterFactory> > FactoryVector;
+ FactoryVector factories_;
+
+ DISALLOW_COPY_AND_ASSIGN(FilterFactoryCollection);
+};
+
+} // namespace media
+
+#endif // MEDIA_BASE_FACTORY_H_
diff --git a/media/build/media.vcproj b/media/build/media.vcproj
index 9b4ad5f..36d944d 100644
--- a/media/build/media.vcproj
+++ b/media/build/media.vcproj
@@ -137,6 +137,10 @@
>
</File>
<File
+ RelativePath="..\base\factory.h"
+ >
+ </File>
+ <File
RelativePath="..\base\filter_host.h"
>
</File>