summaryrefslogtreecommitdiffstats
path: root/chrome/renderer/media/data_source_impl.h
blob: d76f0d4fe32b9c69e0f82e23425e5b6026e94389 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
// 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.
//
// A Chrome specific data source for video stack pipeline. The actual resource
// loading would happen in the browser process. This class is given a file
// handle and will ask for progress of downloading from RenderView which
// delegates requests to browser process through IPC. Asynchronous IO will be
// performed on the file handle.
//
// This class is access by 4 different threads during it's lifetime, namely:
// 1. Render thread
//    Thread that runs WebKit objects and construct this class. Updates about
//    progress for resource loading also happens in this thread.
// 2. Pipeline thread
//    Closing thread of the video stack pipeline, it initialized this class
//    and performs stopping in an orderly fashion.
// 3. Demuxer thread
//    Thread created by the pipeline and ask for data from this class.
//    media::DataSource methods are called from this thread.
// 4. IO thread
//    Performs file stream construction and callback of read completion also
//    comes from this thread.
//
// Methods in the class categorized by the thread(s) they are running on:
//
// Render thread
//   +-- DataSourceImpl()
//   |     Perform construction of this class.
//   |-- static CreateFactory()
//   |     Called during construction of this class.
//   |-- OnInitialize()
//   |     Task posted by Initialize() to kick start resource loading.
//   |-- OnCancel()
//   |     Cancel the resource loading.
//   |-- OnDownloadProgress()
//   |     Receives download progress information for the response data file.
//   |-- OnUploadProgress()
//   |-- OnReceivedRedirect()
//   |-- OnReceivedResponse()
//   |-- OnReceivedData()
//   |-- OnCompletedRequest()
//   |-- GetURLForDebugging()
//   \-- OnDestroy()
//
// Pipeline thread
//   +-- Initialize()
//   |     Performs initialization of data source in the pipeline.
//   \-- Stop()
//         Cease all activities during pipeline tear down.
//
// Demuxer thread
//   +-- Read()
//   |     Called to read from the media file.
//   |-- GetPosition()
//   |     Called to obtain current position in the file.
//   |-- SetPosition()
//   |     Performs a seek operation.
//   |-- GetSize()
//   |     Retrieve the size of the resource.
//   \-- IsSeekable()
//         Returns true if URL is file:/// or else false.
//
// IO thread
//   +-- OnCreateFileStream()
//   |     Callback for construction of net::FileStream in an IO message loop.
//   |-- OnReadFileStream()
//   |     Actual read operation on FileStream performs here.
//   |-- OnSeekFileStream()
//   |     Actual seek operation happens here.
//   \-- OnDidFileStreamRead()
//         Callback for asynchronous file read completion.


#ifndef CHROME_RENDERER_MEDIA_DATA_SOURCE_IMPL_H_
#define CHROME_RENDERER_MEDIA_DATA_SOURCE_IMPL_H_

#include <string>

#include "base/lock.h"
#include "base/platform_file.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"

class WebMediaPlayerDelegateImpl;

class DataSourceImpl : public media::DataSource,
                       public webkit_glue::ResourceLoaderBridge::Peer {
 public:
  // Methods called from render thread ----------------------------------------
  // Static methods for creating this class.
  static media::FilterFactory* CreateFactory(
    WebMediaPlayerDelegateImpl* delegate) {
      return new media::FilterFactoryImpl1<DataSourceImpl,
        WebMediaPlayerDelegateImpl*>(delegate);
  }

  // webkit_glue::ResourceLoaderBridge::Peer implementations, receive events
  // for resource loading.
  virtual void OnDownloadProgress(uint64 position, uint64 size);
  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);
  virtual std::string GetURLForDebugging();

  // Methods called from pipeline thread --------------------------------------
  virtual bool Initialize(const std::string& url);
  // media::MediaFilter implementation.
  virtual void Stop();

  // Methods called from demuxer thread ---------------------------------------
  // media::DataSource implementation.
  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<DataSourceImpl,
                                         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);

  // Methods called from render thread ----------------------------------------
  explicit DataSourceImpl(WebMediaPlayerDelegateImpl* delegate);
  virtual ~DataSourceImpl();

  // Tasks to be posted on render thread.
  void OnInitialize(std::string uri);
  void OnCancel();
  void OnDestroy();

  // Methods called from IO thread --------------------------------------------
  // Handlers for file reading.
  void OnCreateFileStream(base::PlatformFile file);
  void OnReadFileStream(uint8* data, size_t size);
  void OnSeekFileStream(net::Whence whence, int64 position);
  void OnDidFileStreamRead(int size);

  media::MediaFormat media_format_;

  // Pointer to the delegate which provides access to RenderView, this is set
  // in construction and can be accessed in all threads safely.
  WebMediaPlayerDelegateImpl* delegate_;

  // Message loop of render thread.
  MessageLoop* render_loop_;

  // A common lock for protecting members accessed by multiple threads.
  Lock lock_;
  bool stopped_;

  // URI to the resource being downloaded.
  std::string uri_;

  // Members for keeping track of downloading progress.
  base::WaitableEvent download_event_;
  int64 downloaded_bytes_;
  int64 total_bytes_;
  bool total_bytes_known_;
  bool download_completed_;

  // Members related to resource loading with RenderView.
  scoped_ptr<webkit_glue::ResourceLoaderBridge> resource_loader_bridge_;

  // Members used for reading.
  base::WaitableEvent read_event_;
  net::CompletionCallbackImpl<DataSourceImpl> read_callback_;
  scoped_ptr<net::FileStream> stream_;
  size_t last_read_size_;
  int64 position_;
  MessageLoop* io_loop_;

  // Events for other operations on stream_.
  base::WaitableEvent seek_event_;

  DISALLOW_COPY_AND_ASSIGN(DataSourceImpl);
};

#endif  // CHROME_RENDERER_MEDIA_DATA_SOURCE_IMPL_H_