Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(18)

Side by Side Diff: chrome/renderer/media/data_source_impl.cc

Issue 115841: Remove DataSourceImpl from chrome/renderer/media... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/renderer/media/data_source_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this
2 // source code is governed by a BSD-style license that can be found in the
3 // LICENSE file.
4
5 #include "base/compiler_specific.h"
6 #include "base/message_loop.h"
7 #include "base/process_util.h"
8 #include "chrome/renderer/media/data_source_impl.h"
9 #include "chrome/renderer/render_view.h"
10 #include "chrome/renderer/webmediaplayer_delegate_impl.h"
11 #include "chrome/renderer/render_thread.h"
12 #include "media/base/filter_host.h"
13 #include "net/base/load_flags.h"
14 #include "net/base/net_errors.h"
15 #include "webkit/glue/webappcachecontext.h"
16
17 DataSourceImpl::DataSourceImpl(WebMediaPlayerDelegateImpl* delegate)
18 : delegate_(delegate),
19 render_loop_(RenderThread::current()->message_loop()),
20 stopped_(false),
21 download_event_(false, false),
22 downloaded_bytes_(0),
23 total_bytes_(0),
24 total_bytes_known_(false),
25 download_completed_(false),
26 resource_loader_bridge_(NULL),
27 read_event_(false, false),
28 ALLOW_THIS_IN_INITIALIZER_LIST(
29 read_callback_(this, &DataSourceImpl::OnDidFileStreamRead)),
30 stream_(NULL),
31 last_read_size_(0),
32 position_(0),
33 io_loop_(delegate->view()->GetMessageLoopForIO()),
34 seek_event_(false, false) {
35 }
36
37 DataSourceImpl::~DataSourceImpl() {
38 }
39
40 void DataSourceImpl::Stop() {
41 AutoLock auto_lock(lock_);
42 if (stopped_)
43 return;
44 stopped_ = true;
45
46 // Wakes up demuxer waiting on |read_event_| in Read().
47 read_event_.Signal();
48 // Wakes up demuxer waiting on |seek_event_| in SetPosition().
49 seek_event_.Signal();
50 // Wakes up demuxer waiting on |download_event_| in Read() or SetPosition().
51 download_event_.Signal();
52
53 render_loop_->PostTask(FROM_HERE,
54 NewRunnableMethod(this, &DataSourceImpl::OnDestroy));
55 }
56
57 bool DataSourceImpl::Initialize(const std::string& url) {
58 media_format_.SetAsString(media::MediaFormat::kMimeType,
59 media::mime_type::kApplicationOctetStream);
60 media_format_.SetAsString(media::MediaFormat::kURL, url);
61 render_loop_->PostTask(FROM_HERE,
62 NewRunnableMethod(this, &DataSourceImpl::OnInitialize, url));
63 return true;
64 }
65
66 size_t DataSourceImpl::Read(uint8* data, size_t size) {
67 DCHECK(stream_.get());
68 // Wait until we have downloaded the requested bytes.
69 while (true) {
70 {
71 AutoLock auto_lock(lock_);
72 if (stopped_ || download_completed_ ||
73 position_ + size <= downloaded_bytes_)
74 break;
75 }
76 download_event_.Wait();
77 }
78
79 last_read_size_ = media::DataSource::kReadError;
80 if (logging::DEBUG_MODE) {
81 AutoLock auto_lock(lock_);
82 DCHECK(stopped_ || download_completed_ ||
83 position_ + size <= downloaded_bytes_);
84 }
85
86 // Post a task to IO message loop to perform the actual reading.
87 bool task_posted = false;
88 {
89 AutoLock auto_lock(lock_);
90 if (!stopped_) {
91 io_loop_->PostTask(FROM_HERE,
92 NewRunnableMethod(this, &DataSourceImpl::OnReadFileStream,
93 data, size));
94 task_posted = true;
95 }
96 }
97
98 if (task_posted)
99 read_event_.Wait();
100
101 {
102 AutoLock auto_lock(lock_);
103 if (!stopped_)
104 return last_read_size_;
105 return media::DataSource::kReadError;
106 }
107 }
108
109 bool DataSourceImpl::GetPosition(int64* position_out) {
110 AutoLock auto_lock(lock_);
111 *position_out = position_;
112 return true;
113 }
114
115 bool DataSourceImpl::SetPosition(int64 position) {
116 DCHECK(stream_.get());
117 while (true) {
118 {
119 AutoLock auto_lock(lock_);
120 if (stopped_ || download_completed_ || position < downloaded_bytes_)
121 break;
122 }
123 download_event_.Wait();
124 }
125
126 if (logging::DEBUG_MODE) {
127 AutoLock auto_lock(lock_);
128 DCHECK(stopped_ || download_completed_ || position < downloaded_bytes_);
129 }
130
131 // Perform the seek operation on IO message loop.
132 bool task_posted = false;
133 {
134 AutoLock auto_lock(lock_);
135 if (!stopped_) {
136 io_loop_->PostTask(FROM_HERE,
137 NewRunnableMethod(this,
138 &DataSourceImpl::OnSeekFileStream, net::FROM_BEGIN, position));
139 task_posted = true;
140 }
141 }
142 if (task_posted)
143 seek_event_.Wait();
144
145 if (logging::DEBUG_MODE) {
146 AutoLock auto_lock_(lock_);
147 DCHECK(stopped_ || position == position_);
148 }
149 return true;
150 }
151
152 bool DataSourceImpl::GetSize(int64* size_out) {
153 AutoLock auto_lock(lock_);
154 if (total_bytes_known_) {
155 *size_out = total_bytes_;
156 return true;
157 }
158 *size_out = 0;
159 return false;
160 }
161
162 bool DataSourceImpl::IsSeekable() {
163 // If URI is file then it is seekable.
164 // TODO(hclam): make other protocols seekable.
165 return uri_.find("file:///") == 0;
166 }
167
168 void DataSourceImpl::OnCreateFileStream(base::PlatformFile file) {
169 AutoLock auto_lock(lock_);
170 if (stopped_)
171 return;
172 stream_.reset(
173 new net::FileStream(
174 file, base::PLATFORM_FILE_READ | base::PLATFORM_FILE_ASYNC));
175 // TODO(hclam): maybe we should check the validity of the file handle.
176 host_->InitializationComplete();
177 }
178
179 void DataSourceImpl::OnReadFileStream(uint8* data, size_t size) {
180 int error = net::ERR_IO_PENDING;
181 {
182 AutoLock auto_lock(lock_);
183 if (!stopped_) {
184 // net::FileStream::Read wants a char*, not uint8*.
185 char* c_data = reinterpret_cast<char*>(data);
186 COMPILE_ASSERT(sizeof(*c_data) == sizeof(*data), data_not_sizeof_char);
187 error = stream_->Read(c_data, size, &read_callback_);
188 }
189 }
190
191 // Since the file handle is asynchronous, return value other than
192 // ERROR_IO_PENDING is an error.
193 if (error != net::ERR_IO_PENDING) {
194 HandleError(media::PIPELINE_ERROR_READ);
195 }
196 }
197
198 void DataSourceImpl::OnSeekFileStream(net::Whence whence, int64 position) {
199 {
200 AutoLock auto_lock(lock_);
201 if (!stopped_)
202 position_ = stream_->Seek(whence, position);
203 }
204 seek_event_.Signal();
205 }
206
207 void DataSourceImpl::OnDidFileStreamRead(int size) {
208 if (size < 0) {
209 HandleError(media::PIPELINE_ERROR_READ);
210 } else {
211 AutoLock auto_lock(lock_);
212 position_ += size;
213 }
214 last_read_size_ = size;
215 read_event_.Signal();
216 }
217
218 void DataSourceImpl::OnInitialize(std::string uri) {
219 uri_ = uri;
220 // Create the resource loader bridge.
221 resource_loader_bridge_.reset(
222 RenderThread::current()->resource_dispatcher()->CreateBridge(
223 "GET",
224 GURL(uri),
225 GURL(uri),
226 GURL(), // TODO(hclam): provide referer here.
227 "null", // TODO(abarth): provide frame_origin
228 "null", // TODO(abarth): provide main_frame_origin
229 std::string(), // Provide no header.
230 // Prefer to load from cache, also enable downloading the file, the
231 // resource will be saved to a single response data file if it's possible.
232 net::LOAD_PREFERRING_CACHE | net::LOAD_ENABLE_DOWNLOAD_FILE,
233 base::GetCurrentProcId(),
234 ResourceType::MEDIA,
235 0,
236 // TODO(michaeln): delegate->mediaplayer->frame->
237 // app_cache_context()->context_id()
238 // For now don't service media resource requests from the appcache.
239 WebAppCacheContext::kNoAppCacheContextId,
240 delegate_->view()->routing_id()));
241 // Start the resource loading.
242 resource_loader_bridge_->Start(this);
243 }
244
245 void DataSourceImpl::OnDestroy() {
246 DCHECK(MessageLoop::current() == render_loop_);
247 resource_loader_bridge_->Cancel();
248 resource_loader_bridge_.reset();
249 }
250
251 void DataSourceImpl::OnDownloadProgress(uint64 position, uint64 size) {
252 {
253 AutoLock auto_lock(lock_);
254 downloaded_bytes_ = position;
255 if (!total_bytes_known_) {
256 if (size == kuint64max) {
257 // If we receive an invalid value for size, we keep on updating the
258 // total number of bytes.
259 total_bytes_ = position;
260 } else {
261 total_bytes_ = size;
262 total_bytes_known_ = true;
263 }
264 }
265 }
266 host_->SetBufferedBytes(downloaded_bytes_);
267 download_event_.Signal();
268 }
269
270 void DataSourceImpl::OnUploadProgress(uint64 position, uint64 size) {
271 // We don't care about upload progress.
272 }
273
274 void DataSourceImpl::OnReceivedRedirect(const GURL& new_url) {
275 // TODO(hclam): what to do here? fire another resource request or show an
276 // error?
277 }
278
279 void DataSourceImpl::OnReceivedResponse(
280 const webkit_glue::ResourceLoaderBridge::ResponseInfo& info,
281 bool content_filtered) {
282 #if defined(OS_POSIX)
283 base::PlatformFile response_data_file = info.response_data_file.fd;
284 #elif defined(OS_WIN)
285 base::PlatformFile response_data_file = info.response_data_file;
286 #endif
287
288 if (response_data_file != base::kInvalidPlatformFileValue) {
289 DCHECK(!position_ && !downloaded_bytes_);
290 if (info.content_length != -1) {
291 total_bytes_known_ = true;
292 total_bytes_ = info.content_length;
293 host_->SetTotalBytes(total_bytes_);
294 }
295
296 {
297 // Post a task to the IO message loop to create the file stream.
298 // We don't want to post any more tasks once we are stopped.
299 AutoLock auto_lock(lock_);
300 if (!stopped_) {
301 io_loop_->PostTask(FROM_HERE,
302 NewRunnableMethod(this, &DataSourceImpl::OnCreateFileStream,
303 response_data_file));
304 }
305 }
306 } else {
307 // TODO(hclam): handle the fallback case of using memory buffer here.
308 HandleError(media::PIPELINE_ERROR_NETWORK);
309 }
310 }
311
312 void DataSourceImpl::OnReceivedData(const char* data, int len) {
313 // TODO(hclam): we will get this method call when browser process fails
314 // to provide us with a file handle, come up with some fallback mechanism.
315 }
316
317 void DataSourceImpl::OnCompletedRequest(const URLRequestStatus& status,
318 const std::string& security_info) {
319 {
320 AutoLock auto_lock(lock_);
321 total_bytes_known_ = true;
322 download_completed_ = true;
323 }
324 if (status.status() != URLRequestStatus::SUCCESS) {
325 HandleError(media::PIPELINE_ERROR_NETWORK);
326 }
327 }
328
329 void DataSourceImpl::HandleError(media::PipelineError error) {
330 AutoLock auto_lock(lock_);
331 if (!stopped_) {
332 host_->Error(error);
333 }
334 }
335
336 std::string DataSourceImpl::GetURLForDebugging() {
337 return uri_;
338 }
339
340 const media::MediaFormat& DataSourceImpl::media_format() {
341 return media_format_;
342 }
OLDNEW
« no previous file with comments | « chrome/renderer/media/data_source_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698