// Copyright (c) 2006-2009 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. // The pipeline is the public API clients use for playing back media. Clients // provide a filter factory containing the filters they want the pipeline to // use to render media. #ifndef MEDIA_BASE_PIPELINE_H_ #define MEDIA_BASE_PIPELINE_H_ #include #include "base/task.h" #include "media/base/factory.h" namespace base { class TimeDelta; } namespace media { // Error definitions for pipeline. All codes indicate an error except: // PIPELINE_OK indicates the pipeline is running normally. // PIPELINE_STOPPING is used internally when Pipeline::Stop() is called. enum PipelineError { PIPELINE_OK, PIPELINE_STOPPING, PIPELINE_ERROR_URL_NOT_FOUND, PIPELINE_ERROR_NETWORK, PIPELINE_ERROR_DECODE, PIPELINE_ERROR_ABORT, PIPELINE_ERROR_INITIALIZATION_FAILED, PIPELINE_ERROR_REQUIRED_FILTER_MISSING, PIPELINE_ERROR_OUT_OF_MEMORY, PIPELINE_ERROR_COULD_NOT_RENDER, PIPELINE_ERROR_READ, PIPELINE_ERROR_AUDIO_HARDWARE, // Demuxer related errors. DEMUXER_ERROR_COULD_NOT_OPEN, DEMUXER_ERROR_COULD_NOT_PARSE, DEMUXER_ERROR_NO_SUPPORTED_STREAMS, DEMUXER_ERROR_COULD_NOT_CREATE_THREAD, }; // Base class for Pipeline class which allows for read-only access to members. // Filters are allowed to access the PipelineStatus interface but are not given // access to the client Pipeline methods. class PipelineStatus { public: // Returns the current initialization state of the pipeline. Clients can // examine this to determine if it is acceptable to call SetRate/SetVolume/ // Seek after calling Start on the pipeline. Note that this will be // set to true prior to a call to the client's |init_complete_callback| if // initialization is successful. virtual bool IsInitialized() const = 0; // Get the duration of the media in microseconds. If the duration has not // been determined yet, then returns 0. virtual base::TimeDelta GetDuration() const = 0; // Get the approximate amount of playable data buffered so far in micro- // seconds. virtual base::TimeDelta GetBufferedTime() const = 0; // Get the total size of the media file. If the size has not yet been // determined or can not be determined, this value is 0. virtual int64 GetTotalBytes() const = 0; // Get the total number of bytes that are buffered on the client and ready to // be played. virtual int64 GetBufferedBytes() const = 0; // Gets the size of the video output in pixel units. If there is no video // or the video has not been rendered yet, the width and height will be 0. virtual void GetVideoSize(size_t* width_out, size_t* height_out) const = 0; // Gets the current volume setting being used by the audio renderer. When // the pipeline is started, this value will be 1.0f. Valid values range // from 0.0f to 1.0f. virtual float GetVolume() const = 0; // Gets the current playback rate of the pipeline. When the pipeline is // started, the playback rate will be 0.0f. A rate of 1.0f indicates // that the pipeline is rendering the media at the standard rate. Valid // values for playback rate are >= 0.0f. virtual float GetPlaybackRate() const = 0; // Gets the current pipeline time in microseconds. For a pipeline "time" // progresses from 0 to the end of the media. This time base is updated // by the audio renderer to allow for synchronization of audio and video. // Note that a more accurate time may be obtained by calling the // GetInterpolatedTime method which estimates the position of the audio // device based on a combination of the last time the audio device reported // it's position and the current system time. virtual base::TimeDelta GetTime() const = 0; // Gets the current pipeline time in microseconds. For a pipeline "time" // progresses from 0 to the end of the media. Becuase this method provides // an estimated time, it is possible that subsequent calls to this method will // actually progress backwards slightly, so callers must not assume that this // method will always return times larger than the last one. virtual base::TimeDelta GetInterpolatedTime() const = 0; // Gets the current error status for the pipeline. If the pipeline is // operating correctly, this will return OK. virtual PipelineError GetError() const = 0; // If the |major_mime_type| exists in the pipeline and is being rendered, this // method will return true. Types are defined in media/base/media_foramt.h. // For example, to determine if a pipeline contains video: // bool has_video = pipeline->IsRendered(mime_type::kMajorTypeVideo); virtual bool IsRendered(const std::string& major_mime_type) const = 0; protected: virtual ~PipelineStatus() {} }; // Client-provided callbacks for various pipeline operations. // // TODO(scherkus): consider returning a PipelineError instead of a bool, or // perhaps a client callback interface. typedef Callback1::Type PipelineCallback; class Pipeline : public PipelineStatus { public: // Build a pipeline to render the given URI using the given filter factory to // construct a filter chain. Returns true if successful, false otherwise // (i.e., pipeline already started). Note that a return value of true // only indicates that the initialization process has started successfully. // Pipeline initialization is an inherently asynchronous process. Clients // should not call SetPlaybackRate(), Seek(), or SetVolume() until // initialization is complete. Clients can either poll the IsInitialized() // method (which is discouraged) or use the |start_callback| as described // below. // // This method is asynchronous and can execute a callback when completed. // If the caller provides a |start_callback|, it will be called when the // pipeline initialization completes. If successful, the callback's bool // parameter will be true. If the callback is called with false, then the // client can use the GetError() method to obtain more information about the // reason initialization failed. The prototype for the client callback is: // void Client::PipelineInitComplete(bool init_was_successful); // // Note that clients must not call the Stop method from within the // |start_callback|. Other methods, including SetPlaybackRate(), Seek(), and // SetVolume() may be called. The client will be called on a thread owned by // the pipeline class, not on the thread that originally called the Start() // method. virtual bool Start(FilterFactory* filter_factory, const std::string& uri, PipelineCallback* start_callback) = 0; // Stops the pipeline and resets to an uninitialized state. This method // will block the calling thread until the pipeline has been completely // torn down and reset to an uninitialized state. After calling Stop, it // is acceptable to call Start again since Stop leaves the pipeline // in a state identical to a newly created pipeline. // Calling this method is not strictly required because the pipeline // destructor will stop it pipeline if it has not been stopped already. virtual void Stop() = 0; // Attempt to adjust the playback rate. Setting a playback rate of 0.0f pauses // all rendering of the media. A rate of 1.0f indicates a normal playback // rate. Values for the playback rate must be greater than or equal to 0.0f. // TODO(ralphl): What about maximum rate? Does HTML5 specify a max? // // This method must be called only after initialization has completed. virtual void SetPlaybackRate(float playback_rate) = 0; // Attempt to seek to the position specified by time. |seek_callback| will be // executed when the all filters in the pipeline have processed the seek. // The callback will return true if the seek was carried out, false otherwise // (i.e., streaming media). // // This method must be called only after initialization has completed. virtual void Seek(base::TimeDelta time, PipelineCallback* seek_callback) = 0; // Attempt to set the volume of the audio renderer. Valid values for volume // range from 0.0f (muted) to 1.0f (full volume). This value affects all // channels proportionately for multi-channel audio streams. // // This method must be called only after initialization has completed. virtual void SetVolume(float volume) = 0; protected: virtual ~Pipeline() {} }; } // namespace media #endif // MEDIA_BASE_PIPELINE_H_