OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/base/android/media_player_bridge.h" | 5 #include "media/base/android/media_player_bridge.h" |
6 | 6 |
7 #include "base/android/jni_android.h" | 7 #include "base/android/jni_android.h" |
8 #include "base/android/jni_string.h" | 8 #include "base/android/jni_string.h" |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 10 matching lines...) Expand all Loading... |
21 | 21 |
22 namespace media { | 22 namespace media { |
23 | 23 |
24 MediaPlayerBridge::MediaPlayerBridge( | 24 MediaPlayerBridge::MediaPlayerBridge( |
25 int player_id, | 25 int player_id, |
26 const GURL& url, | 26 const GURL& url, |
27 const GURL& first_party_for_cookies, | 27 const GURL& first_party_for_cookies, |
28 const std::string& user_agent, | 28 const std::string& user_agent, |
29 bool hide_url_log, | 29 bool hide_url_log, |
30 MediaPlayerManager* manager, | 30 MediaPlayerManager* manager, |
31 const RequestMediaResourcesCB& request_media_resources_cb, | 31 const OnDecoderResourcesReleasedCB& on_decoder_resources_released_cb, |
32 const GURL& frame_url, | 32 const GURL& frame_url, |
33 bool allow_credentials) | 33 bool allow_credentials) |
34 : MediaPlayerAndroid(player_id, | 34 : MediaPlayerAndroid(player_id, |
35 manager, | 35 manager, |
36 request_media_resources_cb, | 36 on_decoder_resources_released_cb, |
37 frame_url), | 37 frame_url), |
38 prepared_(false), | 38 prepared_(false), |
39 pending_play_(false), | 39 pending_play_(false), |
40 should_seek_on_prepare_(false), | 40 should_seek_on_prepare_(false), |
41 url_(url), | 41 url_(url), |
42 first_party_for_cookies_(first_party_for_cookies), | 42 first_party_for_cookies_(first_party_for_cookies), |
43 user_agent_(user_agent), | 43 user_agent_(user_agent), |
44 hide_url_log_(hide_url_log), | 44 hide_url_log_(hide_url_log), |
45 width_(0), | 45 width_(0), |
46 height_(0), | 46 height_(0), |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 | 103 |
104 AttachListener(j_media_player_bridge_.obj()); | 104 AttachListener(j_media_player_bridge_.obj()); |
105 } | 105 } |
106 | 106 |
107 void MediaPlayerBridge::SetDuration(base::TimeDelta duration) { | 107 void MediaPlayerBridge::SetDuration(base::TimeDelta duration) { |
108 duration_ = duration; | 108 duration_ = duration; |
109 } | 109 } |
110 | 110 |
111 void MediaPlayerBridge::SetVideoSurface(gfx::ScopedJavaSurface surface) { | 111 void MediaPlayerBridge::SetVideoSurface(gfx::ScopedJavaSurface surface) { |
112 if (j_media_player_bridge_.is_null()) { | 112 if (j_media_player_bridge_.is_null()) { |
113 if (surface.IsEmpty()) | 113 if (!surface.IsEmpty()) |
114 return; | 114 surface_ = surface.Pass(); |
115 Prepare(); | 115 return; |
116 } | 116 } |
117 | 117 |
118 JNIEnv* env = base::android::AttachCurrentThread(); | 118 JNIEnv* env = base::android::AttachCurrentThread(); |
119 CHECK(env); | 119 CHECK(env); |
| 120 |
120 Java_MediaPlayerBridge_setSurface( | 121 Java_MediaPlayerBridge_setSurface( |
121 env, j_media_player_bridge_.obj(), surface.j_surface().obj()); | 122 env, j_media_player_bridge_.obj(), surface.j_surface().obj()); |
122 } | 123 } |
123 | 124 |
124 void MediaPlayerBridge::Prepare() { | 125 void MediaPlayerBridge::Prepare() { |
125 DCHECK(j_media_player_bridge_.is_null()); | 126 DCHECK(j_media_player_bridge_.is_null()); |
126 CreateJavaMediaPlayerBridge(); | 127 CreateJavaMediaPlayerBridge(); |
127 if (url_.SchemeIsFileSystem() || url_.SchemeIsBlob()) { | 128 if (url_.SchemeIsFileSystem() || url_.SchemeIsBlob()) { |
128 manager()->GetMediaResourceGetter()->GetPlatformPathFromURL( | 129 manager()->GetMediaResourceGetter()->GetPlatformPathFromURL( |
129 url_, | 130 url_, |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 env, user_agent_); | 175 env, user_agent_); |
175 | 176 |
176 if (!Java_MediaPlayerBridge_setDataSource( | 177 if (!Java_MediaPlayerBridge_setDataSource( |
177 env, j_media_player_bridge_.obj(), j_context, j_url_string.obj(), | 178 env, j_media_player_bridge_.obj(), j_context, j_url_string.obj(), |
178 j_cookies.obj(), j_user_agent.obj(), hide_url_log_)) { | 179 j_cookies.obj(), j_user_agent.obj(), hide_url_log_)) { |
179 OnMediaError(MEDIA_ERROR_FORMAT); | 180 OnMediaError(MEDIA_ERROR_FORMAT); |
180 return; | 181 return; |
181 } | 182 } |
182 } | 183 } |
183 | 184 |
184 request_media_resources_cb_.Run(player_id()); | |
185 if (!Java_MediaPlayerBridge_prepareAsync(env, j_media_player_bridge_.obj())) | 185 if (!Java_MediaPlayerBridge_prepareAsync(env, j_media_player_bridge_.obj())) |
186 OnMediaError(MEDIA_ERROR_FORMAT); | 186 OnMediaError(MEDIA_ERROR_FORMAT); |
187 } | 187 } |
188 | 188 |
189 bool MediaPlayerBridge::InterceptMediaUrl( | 189 bool MediaPlayerBridge::InterceptMediaUrl( |
190 const std::string& url, int* fd, int64* offset, int64* size) { | 190 const std::string& url, int* fd, int64* offset, int64* size) { |
191 // Sentinel value to check whether the output arguments have been set. | 191 // Sentinel value to check whether the output arguments have been set. |
192 const int kUnsetValue = -1; | 192 const int kUnsetValue = -1; |
193 | 193 |
194 *fd = kUnsetValue; | 194 *fd = kUnsetValue; |
(...skipping 10 matching lines...) Expand all Loading... |
205 return false; | 205 return false; |
206 } | 206 } |
207 | 207 |
208 void MediaPlayerBridge::OnDidSetDataUriDataSource(JNIEnv* env, jobject obj, | 208 void MediaPlayerBridge::OnDidSetDataUriDataSource(JNIEnv* env, jobject obj, |
209 jboolean success) { | 209 jboolean success) { |
210 if (!success) { | 210 if (!success) { |
211 OnMediaError(MEDIA_ERROR_FORMAT); | 211 OnMediaError(MEDIA_ERROR_FORMAT); |
212 return; | 212 return; |
213 } | 213 } |
214 | 214 |
215 request_media_resources_cb_.Run(player_id()); | |
216 if (!Java_MediaPlayerBridge_prepareAsync(env, j_media_player_bridge_.obj())) | 215 if (!Java_MediaPlayerBridge_prepareAsync(env, j_media_player_bridge_.obj())) |
217 OnMediaError(MEDIA_ERROR_FORMAT); | 216 OnMediaError(MEDIA_ERROR_FORMAT); |
218 } | 217 } |
219 | 218 |
220 void MediaPlayerBridge::OnCookiesRetrieved(const std::string& cookies) { | 219 void MediaPlayerBridge::OnCookiesRetrieved(const std::string& cookies) { |
221 cookies_ = cookies; | 220 cookies_ = cookies; |
222 manager()->GetMediaResourceGetter()->GetAuthCredentials( | 221 manager()->GetMediaResourceGetter()->GetAuthCredentials( |
223 url_, | 222 url_, |
224 base::Bind(&MediaPlayerBridge::OnAuthCredentialsRetrieved, | 223 base::Bind(&MediaPlayerBridge::OnAuthCredentialsRetrieved, |
225 weak_factory_.GetWeakPtr())); | 224 weak_factory_.GetWeakPtr())); |
226 } | 225 } |
227 | 226 |
228 void MediaPlayerBridge::OnAuthCredentialsRetrieved( | 227 void MediaPlayerBridge::OnAuthCredentialsRetrieved( |
229 const base::string16& username, const base::string16& password) { | 228 const base::string16& username, const base::string16& password) { |
230 GURL::ReplacementsW replacements; | 229 GURL::ReplacementsW replacements; |
231 if (!username.empty()) { | 230 if (!username.empty()) { |
232 replacements.SetUsernameStr(username); | 231 replacements.SetUsernameStr(username); |
233 if (!password.empty()) | 232 if (!password.empty()) |
234 replacements.SetPasswordStr(password); | 233 replacements.SetPasswordStr(password); |
235 url_ = url_.ReplaceComponents(replacements); | 234 url_ = url_.ReplaceComponents(replacements); |
236 } | 235 } |
237 ExtractMediaMetadata(url_.spec()); | 236 ExtractMediaMetadata(url_.spec()); |
238 } | 237 } |
239 | 238 |
240 void MediaPlayerBridge::ExtractMediaMetadata(const std::string& url) { | 239 void MediaPlayerBridge::ExtractMediaMetadata(const std::string& url) { |
241 if (url.empty()) { | 240 if (url.empty()) { |
242 OnMediaError(MEDIA_ERROR_FORMAT); | 241 OnMediaError(MEDIA_ERROR_FORMAT); |
| 242 on_decoder_resources_released_cb_.Run(player_id()); |
243 return; | 243 return; |
244 } | 244 } |
245 | 245 |
246 int fd; | 246 int fd; |
247 int64 offset; | 247 int64 offset; |
248 int64 size; | 248 int64 size; |
249 if (InterceptMediaUrl(url, &fd, &offset, &size)) { | 249 if (InterceptMediaUrl(url, &fd, &offset, &size)) { |
250 manager()->GetMediaResourceGetter()->ExtractMediaMetadata( | 250 manager()->GetMediaResourceGetter()->ExtractMediaMetadata( |
251 fd, offset, size, | 251 fd, offset, size, |
252 base::Bind(&MediaPlayerBridge::OnMediaMetadataExtracted, | 252 base::Bind(&MediaPlayerBridge::OnMediaMetadataExtracted, |
253 weak_factory_.GetWeakPtr())); | 253 weak_factory_.GetWeakPtr())); |
254 } else { | 254 } else { |
255 manager()->GetMediaResourceGetter()->ExtractMediaMetadata( | 255 manager()->GetMediaResourceGetter()->ExtractMediaMetadata( |
256 url, cookies_, user_agent_, | 256 url, cookies_, user_agent_, |
257 base::Bind(&MediaPlayerBridge::OnMediaMetadataExtracted, | 257 base::Bind(&MediaPlayerBridge::OnMediaMetadataExtracted, |
258 weak_factory_.GetWeakPtr())); | 258 weak_factory_.GetWeakPtr())); |
259 } | 259 } |
260 } | 260 } |
261 | 261 |
262 void MediaPlayerBridge::OnMediaMetadataExtracted( | 262 void MediaPlayerBridge::OnMediaMetadataExtracted( |
263 base::TimeDelta duration, int width, int height, bool success) { | 263 base::TimeDelta duration, int width, int height, bool success) { |
264 if (success) { | 264 if (success) { |
265 duration_ = duration; | 265 duration_ = duration; |
266 width_ = width; | 266 width_ = width; |
267 height_ = height; | 267 height_ = height; |
268 } | 268 } |
269 manager()->OnMediaMetadataChanged( | 269 manager()->OnMediaMetadataChanged( |
270 player_id(), duration_, width_, height_, success); | 270 player_id(), duration_, width_, height_, success); |
| 271 on_decoder_resources_released_cb_.Run(player_id()); |
271 } | 272 } |
272 | 273 |
273 void MediaPlayerBridge::Start() { | 274 void MediaPlayerBridge::Start() { |
274 if (j_media_player_bridge_.is_null()) { | 275 if (j_media_player_bridge_.is_null()) { |
275 pending_play_ = true; | 276 pending_play_ = true; |
276 Prepare(); | 277 Prepare(); |
277 } else { | 278 } else { |
278 if (prepared_) | 279 if (prepared_) |
279 StartInternal(); | 280 StartInternal(); |
280 else | 281 else |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
318 JNIEnv* env = base::android::AttachCurrentThread(); | 319 JNIEnv* env = base::android::AttachCurrentThread(); |
319 return Java_MediaPlayerBridge_getVideoHeight( | 320 return Java_MediaPlayerBridge_getVideoHeight( |
320 env, j_media_player_bridge_.obj()); | 321 env, j_media_player_bridge_.obj()); |
321 } | 322 } |
322 | 323 |
323 void MediaPlayerBridge::SeekTo(base::TimeDelta timestamp) { | 324 void MediaPlayerBridge::SeekTo(base::TimeDelta timestamp) { |
324 // Record the time to seek when OnMediaPrepared() is called. | 325 // Record the time to seek when OnMediaPrepared() is called. |
325 pending_seek_ = timestamp; | 326 pending_seek_ = timestamp; |
326 should_seek_on_prepare_ = true; | 327 should_seek_on_prepare_ = true; |
327 | 328 |
328 if (j_media_player_bridge_.is_null()) | 329 if (prepared_) |
329 Prepare(); | |
330 else if (prepared_) | |
331 SeekInternal(GetCurrentTime(), timestamp); | 330 SeekInternal(GetCurrentTime(), timestamp); |
332 } | 331 } |
333 | 332 |
334 base::TimeDelta MediaPlayerBridge::GetCurrentTime() { | 333 base::TimeDelta MediaPlayerBridge::GetCurrentTime() { |
335 if (!prepared_) | 334 if (!prepared_) |
336 return pending_seek_; | 335 return pending_seek_; |
337 JNIEnv* env = base::android::AttachCurrentThread(); | 336 JNIEnv* env = base::android::AttachCurrentThread(); |
338 return base::TimeDelta::FromMilliseconds( | 337 return base::TimeDelta::FromMilliseconds( |
339 Java_MediaPlayerBridge_getCurrentPosition( | 338 Java_MediaPlayerBridge_getCurrentPosition( |
340 env, j_media_player_bridge_.obj())); | 339 env, j_media_player_bridge_.obj())); |
341 } | 340 } |
342 | 341 |
343 base::TimeDelta MediaPlayerBridge::GetDuration() { | 342 base::TimeDelta MediaPlayerBridge::GetDuration() { |
344 if (!prepared_) | 343 if (!prepared_) |
345 return duration_; | 344 return duration_; |
346 JNIEnv* env = base::android::AttachCurrentThread(); | 345 JNIEnv* env = base::android::AttachCurrentThread(); |
347 const int duration_ms = | 346 const int duration_ms = |
348 Java_MediaPlayerBridge_getDuration(env, j_media_player_bridge_.obj()); | 347 Java_MediaPlayerBridge_getDuration(env, j_media_player_bridge_.obj()); |
349 return duration_ms < 0 ? media::kInfiniteDuration() | 348 return duration_ms < 0 ? media::kInfiniteDuration() |
350 : base::TimeDelta::FromMilliseconds(duration_ms); | 349 : base::TimeDelta::FromMilliseconds(duration_ms); |
351 } | 350 } |
352 | 351 |
353 void MediaPlayerBridge::Release() { | 352 void MediaPlayerBridge::Release() { |
| 353 on_decoder_resources_released_cb_.Run(player_id()); |
354 if (j_media_player_bridge_.is_null()) | 354 if (j_media_player_bridge_.is_null()) |
355 return; | 355 return; |
356 | 356 |
357 time_update_timer_.Stop(); | 357 time_update_timer_.Stop(); |
358 if (prepared_) { | 358 if (prepared_) { |
359 pending_seek_ = GetCurrentTime(); | 359 pending_seek_ = GetCurrentTime(); |
360 should_seek_on_prepare_ = true; | 360 should_seek_on_prepare_ = true; |
361 } | 361 } |
362 | 362 |
363 prepared_ = false; | 363 prepared_ = false; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
406 duration_ = GetDuration(); | 406 duration_ = GetDuration(); |
407 | 407 |
408 // If media player was recovered from a saved state, consume all the pending | 408 // If media player was recovered from a saved state, consume all the pending |
409 // events. | 409 // events. |
410 if (should_seek_on_prepare_) { | 410 if (should_seek_on_prepare_) { |
411 PendingSeekInternal(pending_seek_); | 411 PendingSeekInternal(pending_seek_); |
412 pending_seek_ = base::TimeDelta::FromMilliseconds(0); | 412 pending_seek_ = base::TimeDelta::FromMilliseconds(0); |
413 should_seek_on_prepare_ = false; | 413 should_seek_on_prepare_ = false; |
414 } | 414 } |
415 | 415 |
| 416 if (!surface_.IsEmpty()) |
| 417 SetVideoSurface(surface_.Pass()); |
| 418 |
416 if (pending_play_) { | 419 if (pending_play_) { |
417 StartInternal(); | 420 StartInternal(); |
418 pending_play_ = false; | 421 pending_play_ = false; |
419 } | 422 } |
420 | 423 |
421 UpdateAllowedOperations(); | 424 UpdateAllowedOperations(); |
422 manager()->OnMediaMetadataChanged( | 425 manager()->OnMediaMetadataChanged( |
423 player_id(), duration_, width_, height_, true); | 426 player_id(), duration_, width_, height_, true); |
424 } | 427 } |
425 | 428 |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
525 | 528 |
526 GURL MediaPlayerBridge::GetUrl() { | 529 GURL MediaPlayerBridge::GetUrl() { |
527 return url_; | 530 return url_; |
528 } | 531 } |
529 | 532 |
530 GURL MediaPlayerBridge::GetFirstPartyForCookies() { | 533 GURL MediaPlayerBridge::GetFirstPartyForCookies() { |
531 return first_party_for_cookies_; | 534 return first_party_for_cookies_; |
532 } | 535 } |
533 | 536 |
534 } // namespace media | 537 } // namespace media |
OLD | NEW |