| Index: chrome/renderer/media/buffered_data_source.h
|
| ===================================================================
|
| --- chrome/renderer/media/buffered_data_source.h (revision 0)
|
| +++ chrome/renderer/media/buffered_data_source.h (revision 0)
|
| @@ -0,0 +1,227 @@
|
| +// Copyright (c) 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.
|
| +
|
| +#ifndef CHROME_RENDERER_MEDIA_BUFFERED_DATA_SOURCE_H_
|
| +#define CHROME_RENDERER_MEDIA_BUFFERED_DATA_SOURCE_H_
|
| +
|
| +#include <deque>
|
| +#include <string>
|
| +
|
| +#include "base/lock.h"
|
| +#include "base/scoped_ptr.h"
|
| +#include "base/waitable_event.h"
|
| +#include "media/base/factory.h"
|
| +#include "media/base/filters.h"
|
| +#include "media/base/media_format.h"
|
| +#include "media/base/pipeline.h"
|
| +#include "net/base/completion_callback.h"
|
| +#include "net/base/file_stream.h"
|
| +#include "webkit/glue/resource_loader_bridge.h"
|
| +#include "googleurl/src/gurl.h"
|
| +
|
| +class WebMediaPlayerDelegateImpl;
|
| +
|
| +/////////////////////////////////////////////////////////////////////////////
|
| +// BufferedResourceLoader
|
| +// This class works inside demuxer thread and render thread. It contains a
|
| +// resource loader bridge and does the actual resource loading. This object
|
| +// does buffering internally, it defers the resource loading if buffer is
|
| +// full and un-defers the resource loading if it is under buffered.
|
| +class BufferedResourceLoader :
|
| + public base::RefCountedThreadSafe<BufferedResourceLoader>,
|
| + public webkit_glue::ResourceLoaderBridge::Peer {
|
| + public:
|
| + BufferedResourceLoader(int route_id,
|
| + const GURL& url,
|
| + int64 first_byte_position,
|
| + int64 last_byte_position);
|
| + virtual ~BufferedResourceLoader();
|
| +
|
| + // Start the resource loading with the specified URL and range.
|
| + // This method call can operate in two modes, synchronous and asynchronous.
|
| + // If |start_callback| is NULL, this method operates in synchronous mode and
|
| + // it returns true if the load has started successfully, false otherwise. It
|
| + // returns only if a resource is received from the server or this loader is
|
| + // called to stop.
|
| + // If |start_callback| is not NULL, this method operates in asynchronous mode
|
| + // and it returns net::ERR_IO_PENDING if the request is going to start.
|
| + // Once there's a response from the server, success or fail |start_callback|
|
| + // is called with the result.
|
| + // Note that |start_callback| is called within a lock to prevent invoking an
|
| + // invalid callback method while this object is called to stop.
|
| + int Start(net::CompletionCallback* callback);
|
| +
|
| + // Stops this loader. Wakes up all synchronous actions.
|
| + void Stop();
|
| +
|
| + // Reads the specified |size| into |buffer| and returns number of bytes copied
|
| + // into the buffer. Returns 0 if the response has completed and there's no
|
| + // no buffer left. Returns media::kReadError on error. The read starts from
|
| + // the current position referred by calling GetOffset(). This method call is
|
| + // synchronous, it returns only the required amount of bytes is read, the
|
| + // loader is stopped, this resource loading has completed or the read has
|
| + // timed out. Read() and SeekForward() cannot be called concurrently.
|
| + size_t Read(uint8* buffer, size_t size);
|
| +
|
| + // Seek forward to |position| in bytes in the entire instance of the media
|
| + // object, returns true if successful. If the seek operation cannot be
|
| + // performed because it's seeking backward, the loader has been stopped,
|
| + // the seek |position| exceed bufferable range or the seek operation has
|
| + // timed out, returns false.
|
| + // There cannot be SeekForward() while another thread is calling Read().
|
| + bool SeekForward(int64 position);
|
| +
|
| + // Returns the position in bytes that this loader is downloading from.
|
| + int64 GetOffset();
|
| +
|
| + // Gets and sets the buffering limit of this loader.
|
| + int64 GetBufferLimit();
|
| + void SetBufferLimit(size_t buffe_limit);
|
| +
|
| + // Gets and sets the timeout for the synchronous operations.
|
| + size_t GetTimeout();
|
| + void SetTimeout(size_t milliseconds);
|
| +
|
| + // Gets the content length in bytes of the instance after this loader has been
|
| + // started.
|
| + int64 content_length() { return content_length_; }
|
| +
|
| + /////////////////////////////////////////////////////////////////////////////
|
| + // webkit_glue::ResourceLoaderBridge::Peer implementations.
|
| + virtual void OnUploadProgress(uint64 position, uint64 size) {}
|
| + virtual void OnReceivedRedirect(const GURL& new_url);
|
| + virtual void OnReceivedResponse(
|
| + const webkit_glue::ResourceLoaderBridge::ResponseInfo& info,
|
| + bool content_filtered);
|
| + virtual void OnReceivedData(const char* data, int len);
|
| + virtual void OnCompletedRequest(const URLRequestStatus& status,
|
| + const std::string& security_info);
|
| + std::string GetURLForDebugging() { return url_.spec(); }
|
| +
|
| + private:
|
| + // Append buffer to the queue of buffers.
|
| + void AppendToBuffer(const uint8* buffer, size_t size);
|
| + void SignalComplete();
|
| + bool ShouldEnableDefer();
|
| + bool ShouldDisableDefer();
|
| +
|
| + void OnStart();
|
| + void OnDestroy();
|
| + void OnDisableDeferLoading();
|
| + void OnEnableDeferLoading();
|
| +
|
| + void InvokeAndResetStartCallback(int error);
|
| +
|
| + struct Buffer {
|
| + Buffer(size_t len) : taken(0), size(len), data(new uint8[len]) { }
|
| +
|
| + // The amount of buffer in bytes consumed in this buffer starting from
|
| + // index 0.
|
| + size_t taken;
|
| + size_t size;
|
| + scoped_array<uint8> data;
|
| + };
|
| +
|
| + scoped_ptr<net::CompletionCallback> start_callback_;
|
| + scoped_ptr<webkit_glue::ResourceLoaderBridge> bridge_;
|
| + int64 offset_;
|
| + int64 content_length_;
|
| +
|
| + std::deque<Buffer*> buffers_;
|
| + size_t buffered_bytes_;
|
| + size_t buffer_limit_;
|
| + base::WaitableEvent buffer_event_;
|
| +
|
| + bool deferred_;
|
| + bool stopped_;
|
| + bool completed_;
|
| + bool range_requested_;
|
| + bool async_start_;
|
| +
|
| + int route_id_;
|
| + GURL url_;
|
| + int64 first_byte_position_;
|
| + int64 last_byte_position_;
|
| +
|
| + MessageLoop* render_loop_;
|
| + // A lock that protects usage of the following members:
|
| + // - buffers_
|
| + // - buffered_bytes_
|
| + // - buffered_limit_
|
| + // - deferred_
|
| + // - stopped_
|
| + // - completed_
|
| + Lock lock_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(BufferedResourceLoader);
|
| +};
|
| +
|
| +class BufferedDataSource : public media::DataSource {
|
| + public:
|
| + // Methods called from pipeline thread
|
| + // Static methods for creating this class.
|
| + static media::FilterFactory* CreateFactory(
|
| + WebMediaPlayerDelegateImpl* delegate) {
|
| + return new media::FilterFactoryImpl1<BufferedDataSource,
|
| + WebMediaPlayerDelegateImpl*>(delegate);
|
| + }
|
| + virtual bool Initialize(const std::string& url);
|
| +
|
| + // media::MediaFilter implementation.
|
| + virtual void Stop();
|
| +
|
| + // media::DataSource implementation.
|
| + // Called from demuxer thread.
|
| + virtual size_t Read(uint8* data, size_t size);
|
| + virtual bool GetPosition(int64* position_out);
|
| + virtual bool SetPosition(int64 position);
|
| + virtual bool GetSize(int64* size_out);
|
| + virtual bool IsSeekable();
|
| +
|
| + const media::MediaFormat& media_format();
|
| +
|
| + private:
|
| + friend class media::FilterFactoryImpl1<BufferedDataSource,
|
| + WebMediaPlayerDelegateImpl*>;
|
| + // Call to filter host to trigger an error, be sure not to call this method
|
| + // while the lock is acquired.
|
| + void HandleError(media::PipelineError error);
|
| +
|
| + // Callback method from BufferedResourceLoader for the initial url request.
|
| + // |error| is net::OK if the request has started successfully or |error| is
|
| + // a code representing the actual network error.
|
| + void InitialRequestStarted(int error);
|
| + void OnInitialRequestStarted(int error);
|
| +
|
| + explicit BufferedDataSource(WebMediaPlayerDelegateImpl* delegate);
|
| + virtual ~BufferedDataSource();
|
| +
|
| + media::MediaFormat media_format_;
|
| + GURL url_;
|
| +
|
| + // Pointer to the delegate which provides access to RenderView, this is set
|
| + // in construction and can be accessed in all threads safely.
|
| + // TODO(hclam): get rid of this and save the routing id and pointer to
|
| + // ResourceDispatcher.
|
| + WebMediaPlayerDelegateImpl* delegate_;
|
| +
|
| + // A common lock for protecting members accessed by multiple threads.
|
| + Lock lock_;
|
| + bool stopped_;
|
| +
|
| + // Members used for reading.
|
| + int64 position_;
|
| + // Members for total bytes of the requested object.
|
| + int64 total_bytes_;
|
| +
|
| + // Members related to resource loading with RenderView.
|
| + scoped_refptr<BufferedResourceLoader> buffered_resource_loader_;
|
| +
|
| + // The message loop of the pipeline thread.
|
| + MessageLoop* pipeline_loop_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(BufferedDataSource);
|
| +};
|
| +
|
| +#endif // CHROME_RENDERER_MEDIA_BUFFERED_DATA_SOURCE_H_
|
|
|