OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights | 2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights |
3 * reserved. | 3 * reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 Document* document) { | 214 Document* document) { |
215 DocumentElementSetMap& map = DocumentToElementSetMap(); | 215 DocumentElementSetMap& map = DocumentToElementSetMap(); |
216 auto it = map.Find(document); | 216 auto it = map.Find(document); |
217 DCHECK(it != map.end()); | 217 DCHECK(it != map.end()); |
218 WeakMediaElementSet* set = it->value; | 218 WeakMediaElementSet* set = it->value; |
219 set->erase(element); | 219 set->erase(element); |
220 if (set->IsEmpty()) | 220 if (set->IsEmpty()) |
221 map.erase(it); | 221 map.erase(it); |
222 } | 222 } |
223 | 223 |
| 224 String BuildElementErrorMessage(const String& error) { |
| 225 DEFINE_STATIC_LOCAL(const String, element_error_prefix, |
| 226 ("Media element error: ")); |
| 227 StringBuilder builder; |
| 228 builder.Append(element_error_prefix); |
| 229 builder.Append(error); |
| 230 return builder.ToString(); |
| 231 } |
| 232 |
224 class AudioSourceProviderClientLockScope { | 233 class AudioSourceProviderClientLockScope { |
225 STACK_ALLOCATED(); | 234 STACK_ALLOCATED(); |
226 | 235 |
227 public: | 236 public: |
228 AudioSourceProviderClientLockScope(HTMLMediaElement& element) | 237 AudioSourceProviderClientLockScope(HTMLMediaElement& element) |
229 : client_(element.AudioSourceNode()) { | 238 : client_(element.AudioSourceNode()) { |
230 if (client_) | 239 if (client_) |
231 client_->lock(); | 240 client_->lock(); |
232 } | 241 } |
233 ~AudioSourceProviderClientLockScope() { | 242 ~AudioSourceProviderClientLockScope() { |
(...skipping 874 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1108 LoadResource(WebMediaPlayerSource(WebMediaStream(src_object_)), String()); | 1117 LoadResource(WebMediaPlayerSource(WebMediaStream(src_object_)), String()); |
1109 } | 1118 } |
1110 | 1119 |
1111 void HTMLMediaElement::LoadSourceFromAttribute() { | 1120 void HTMLMediaElement::LoadSourceFromAttribute() { |
1112 load_state_ = kLoadingFromSrcAttr; | 1121 load_state_ = kLoadingFromSrcAttr; |
1113 const AtomicString& src_value = FastGetAttribute(srcAttr); | 1122 const AtomicString& src_value = FastGetAttribute(srcAttr); |
1114 | 1123 |
1115 // If the src attribute's value is the empty string ... jump down to the | 1124 // If the src attribute's value is the empty string ... jump down to the |
1116 // failed step below | 1125 // failed step below |
1117 if (src_value.IsEmpty()) { | 1126 if (src_value.IsEmpty()) { |
1118 MediaLoadingFailed(WebMediaPlayer::kNetworkStateFormatError); | 1127 BLINK_MEDIA_LOG << "LoadSourceFromAttribute(" << (void*)this |
1119 BLINK_MEDIA_LOG << "loadSourceFromAttribute(" << (void*)this | |
1120 << "), empty 'src'"; | 1128 << "), empty 'src'"; |
| 1129 MediaLoadingFailed(WebMediaPlayer::kNetworkStateFormatError, |
| 1130 BuildElementErrorMessage("Empty src attribute")); |
1121 return; | 1131 return; |
1122 } | 1132 } |
1123 | 1133 |
1124 KURL media_url = GetDocument().CompleteURL(src_value); | 1134 KURL media_url = GetDocument().CompleteURL(src_value); |
1125 if (!IsSafeToLoadURL(media_url, kComplain)) { | 1135 if (!IsSafeToLoadURL(media_url, kComplain)) { |
1126 MediaLoadingFailed(WebMediaPlayer::kNetworkStateFormatError); | 1136 MediaLoadingFailed( |
| 1137 WebMediaPlayer::kNetworkStateFormatError, |
| 1138 BuildElementErrorMessage("Media load rejected by URL safety check")); |
1127 return; | 1139 return; |
1128 } | 1140 } |
1129 | 1141 |
1130 // No type is available when the url comes from the 'src' attribute so | 1142 // No type is available when the url comes from the 'src' attribute so |
1131 // MediaPlayer will have to pick a media engine based on the file extension. | 1143 // MediaPlayer will have to pick a media engine based on the file extension. |
1132 LoadResource(WebMediaPlayerSource(WebURL(media_url)), String()); | 1144 LoadResource(WebMediaPlayerSource(WebURL(media_url)), String()); |
1133 } | 1145 } |
1134 | 1146 |
1135 void HTMLMediaElement::LoadNextSourceChild() { | 1147 void HTMLMediaElement::LoadNextSourceChild() { |
1136 String content_type; | 1148 String content_type; |
(...skipping 16 matching lines...) Expand all Loading... |
1153 KURL url; | 1165 KURL url; |
1154 if (source.IsURL()) { | 1166 if (source.IsURL()) { |
1155 url = source.GetAsURL(); | 1167 url = source.GetAsURL(); |
1156 DCHECK(IsSafeToLoadURL(url, kComplain)); | 1168 DCHECK(IsSafeToLoadURL(url, kComplain)); |
1157 BLINK_MEDIA_LOG << "loadResource(" << (void*)this << ", " | 1169 BLINK_MEDIA_LOG << "loadResource(" << (void*)this << ", " |
1158 << UrlForLoggingMedia(url) << ", " << content_type << ")"; | 1170 << UrlForLoggingMedia(url) << ", " << content_type << ")"; |
1159 } | 1171 } |
1160 | 1172 |
1161 LocalFrame* frame = GetDocument().GetFrame(); | 1173 LocalFrame* frame = GetDocument().GetFrame(); |
1162 if (!frame) { | 1174 if (!frame) { |
1163 MediaLoadingFailed(WebMediaPlayer::kNetworkStateFormatError); | 1175 MediaLoadingFailed(WebMediaPlayer::kNetworkStateFormatError, |
| 1176 BuildElementErrorMessage( |
| 1177 "Resource load failure: document has no frame")); |
1164 return; | 1178 return; |
1165 } | 1179 } |
1166 | 1180 |
1167 // The resource fetch algorithm | 1181 // The resource fetch algorithm |
1168 SetNetworkState(kNetworkLoading); | 1182 SetNetworkState(kNetworkLoading); |
1169 | 1183 |
1170 // Set m_currentSrc *before* changing to the cache url, the fact that we are | 1184 // Set m_currentSrc *before* changing to the cache url, the fact that we are |
1171 // loading from the app cache is an internal detail not exposed through the | 1185 // loading from the app cache is an internal detail not exposed through the |
1172 // media element API. | 1186 // media element API. |
1173 current_src_ = url; | 1187 current_src_ = url; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1211 // including MediaSource blob URLs. | 1225 // including MediaSource blob URLs. |
1212 if (!source.IsMediaStream() && !url.ProtocolIs("blob") && | 1226 if (!source.IsMediaStream() && !url.ProtocolIs("blob") && |
1213 EffectivePreloadType() == WebMediaPlayer::kPreloadNone) { | 1227 EffectivePreloadType() == WebMediaPlayer::kPreloadNone) { |
1214 BLINK_MEDIA_LOG << "loadResource(" << (void*)this | 1228 BLINK_MEDIA_LOG << "loadResource(" << (void*)this |
1215 << ") : Delaying load because preload == 'none'"; | 1229 << ") : Delaying load because preload == 'none'"; |
1216 DeferLoad(); | 1230 DeferLoad(); |
1217 } else { | 1231 } else { |
1218 StartPlayerLoad(); | 1232 StartPlayerLoad(); |
1219 } | 1233 } |
1220 } else { | 1234 } else { |
1221 MediaLoadingFailed(WebMediaPlayer::kNetworkStateFormatError); | 1235 MediaLoadingFailed( |
| 1236 WebMediaPlayer::kNetworkStateFormatError, |
| 1237 BuildElementErrorMessage(attempt_load |
| 1238 ? "Unable to load URL due to content type" |
| 1239 : "Unable to attach MediaSource")); |
1222 } | 1240 } |
1223 | 1241 |
1224 // If there is no poster to display, allow the media engine to render video | 1242 // If there is no poster to display, allow the media engine to render video |
1225 // frames as soon as they are available. | 1243 // frames as soon as they are available. |
1226 UpdateDisplayState(); | 1244 UpdateDisplayState(); |
1227 | 1245 |
1228 if (GetLayoutObject()) | 1246 if (GetLayoutObject()) |
1229 GetLayoutObject()->UpdateFromElement(); | 1247 GetLayoutObject()->UpdateFromElement(); |
1230 } | 1248 } |
1231 | 1249 |
(...skipping 25 matching lines...) Expand all Loading... |
1257 request_url.SetPass(String()); | 1275 request_url.SetPass(String()); |
1258 | 1276 |
1259 KURL kurl(kParsedURLString, request_url); | 1277 KURL kurl(kParsedURLString, request_url); |
1260 source = WebMediaPlayerSource(WebURL(kurl)); | 1278 source = WebMediaPlayerSource(WebURL(kurl)); |
1261 } | 1279 } |
1262 | 1280 |
1263 LocalFrame* frame = GetDocument().GetFrame(); | 1281 LocalFrame* frame = GetDocument().GetFrame(); |
1264 // TODO(srirama.m): Figure out how frame can be null when | 1282 // TODO(srirama.m): Figure out how frame can be null when |
1265 // coming from executeDeferredLoad() | 1283 // coming from executeDeferredLoad() |
1266 if (!frame) { | 1284 if (!frame) { |
1267 MediaLoadingFailed(WebMediaPlayer::kNetworkStateFormatError); | 1285 MediaLoadingFailed( |
| 1286 WebMediaPlayer::kNetworkStateFormatError, |
| 1287 BuildElementErrorMessage("Player load failure: document has no frame")); |
1268 return; | 1288 return; |
1269 } | 1289 } |
1270 | 1290 |
1271 web_media_player_ = | 1291 web_media_player_ = |
1272 frame->Loader().Client()->CreateWebMediaPlayer(*this, source, this); | 1292 frame->Loader().Client()->CreateWebMediaPlayer(*this, source, this); |
1273 if (!web_media_player_) { | 1293 if (!web_media_player_) { |
1274 MediaLoadingFailed(WebMediaPlayer::kNetworkStateFormatError); | 1294 MediaLoadingFailed(WebMediaPlayer::kNetworkStateFormatError, |
| 1295 BuildElementErrorMessage( |
| 1296 "Player load failure: error creating media player")); |
1275 return; | 1297 return; |
1276 } | 1298 } |
1277 | 1299 |
1278 if (GetLayoutObject()) | 1300 if (GetLayoutObject()) |
1279 GetLayoutObject()->SetShouldDoFullPaintInvalidation(); | 1301 GetLayoutObject()->SetShouldDoFullPaintInvalidation(); |
1280 // Make sure if we create/re-create the WebMediaPlayer that we update our | 1302 // Make sure if we create/re-create the WebMediaPlayer that we update our |
1281 // wrapper. | 1303 // wrapper. |
1282 audio_source_provider_.Wrap(web_media_player_->GetAudioSourceProvider()); | 1304 audio_source_provider_.Wrap(web_media_player_->GetAudioSourceProvider()); |
1283 web_media_player_->SetVolume(EffectiveMediaVolume()); | 1305 web_media_player_->SetVolume(EffectiveMediaVolume()); |
1284 | 1306 |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1507 // 6.18 - Set the element's delaying-the-load-event flag to false. This stops | 1529 // 6.18 - Set the element's delaying-the-load-event flag to false. This stops |
1508 // delaying the load event. | 1530 // delaying the load event. |
1509 SetShouldDelayLoadEvent(false); | 1531 SetShouldDelayLoadEvent(false); |
1510 | 1532 |
1511 UpdateDisplayState(); | 1533 UpdateDisplayState(); |
1512 | 1534 |
1513 if (GetLayoutObject()) | 1535 if (GetLayoutObject()) |
1514 GetLayoutObject()->UpdateFromElement(); | 1536 GetLayoutObject()->UpdateFromElement(); |
1515 } | 1537 } |
1516 | 1538 |
1517 void HTMLMediaElement::NoneSupported() { | 1539 void HTMLMediaElement::NoneSupported(const String& message) { |
1518 BLINK_MEDIA_LOG << "noneSupported(" << (void*)this << ")"; | 1540 BLINK_MEDIA_LOG << "NoneSupported(" << (void*)this << ", message='" << message |
| 1541 << "')"; |
1519 | 1542 |
1520 StopPeriodicTimers(); | 1543 StopPeriodicTimers(); |
1521 load_state_ = kWaitingForSource; | 1544 load_state_ = kWaitingForSource; |
1522 current_source_node_ = nullptr; | 1545 current_source_node_ = nullptr; |
1523 | 1546 |
1524 // 4.8.12.5 | 1547 // 4.8.12.5 |
1525 // The dedicated media source failure steps are the following steps: | 1548 // The dedicated media source failure steps are the following steps: |
1526 | 1549 |
1527 // 1 - Set the error attribute to a new MediaError object whose code attribute | 1550 // 1 - Set the error attribute to a new MediaError object whose code attribute |
1528 // is set to MEDIA_ERR_SRC_NOT_SUPPORTED. | 1551 // is set to MEDIA_ERR_SRC_NOT_SUPPORTED. |
1529 error_ = MediaError::Create(MediaError::kMediaErrSrcNotSupported); | 1552 error_ = MediaError::Create(MediaError::kMediaErrSrcNotSupported, message); |
1530 | 1553 |
1531 // 2 - Forget the media element's media-resource-specific text tracks. | 1554 // 2 - Forget the media element's media-resource-specific text tracks. |
1532 ForgetResourceSpecificTracks(); | 1555 ForgetResourceSpecificTracks(); |
1533 | 1556 |
1534 // 3 - Set the element's networkState attribute to the NETWORK_NO_SOURCE | 1557 // 3 - Set the element's networkState attribute to the NETWORK_NO_SOURCE |
1535 // value. | 1558 // value. |
1536 SetNetworkState(kNetworkNoSource); | 1559 SetNetworkState(kNetworkNoSource); |
1537 | 1560 |
1538 // 4 - Set the element's show poster flag to true. | 1561 // 4 - Set the element's show poster flag to true. |
1539 UpdateDisplayState(); | 1562 UpdateDisplayState(); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1588 for (HTMLSourceElement* source = | 1611 for (HTMLSourceElement* source = |
1589 Traversal<HTMLSourceElement>::FirstChild(*this); | 1612 Traversal<HTMLSourceElement>::FirstChild(*this); |
1590 source; source = Traversal<HTMLSourceElement>::NextSibling(*source)) | 1613 source; source = Traversal<HTMLSourceElement>::NextSibling(*source)) |
1591 source->CancelPendingErrorEvent(); | 1614 source->CancelPendingErrorEvent(); |
1592 } | 1615 } |
1593 | 1616 |
1594 void HTMLMediaElement::NetworkStateChanged() { | 1617 void HTMLMediaElement::NetworkStateChanged() { |
1595 SetNetworkState(GetWebMediaPlayer()->GetNetworkState()); | 1618 SetNetworkState(GetWebMediaPlayer()->GetNetworkState()); |
1596 } | 1619 } |
1597 | 1620 |
1598 void HTMLMediaElement::MediaLoadingFailed(WebMediaPlayer::NetworkState error) { | 1621 void HTMLMediaElement::MediaLoadingFailed(WebMediaPlayer::NetworkState error, |
| 1622 const String& message) { |
| 1623 BLINK_MEDIA_LOG << "MediaLoadingFailed(" << (void*)this << ", " |
| 1624 << static_cast<int>(error) << ", message='" << message |
| 1625 << "')"; |
| 1626 |
1599 StopPeriodicTimers(); | 1627 StopPeriodicTimers(); |
1600 | 1628 |
1601 // If we failed while trying to load a <source> element, the movie was never | 1629 // If we failed while trying to load a <source> element, the movie was never |
1602 // parsed, and there are more <source> children, schedule the next one | 1630 // parsed, and there are more <source> children, schedule the next one |
1603 if (ready_state_ < kHaveMetadata && | 1631 if (ready_state_ < kHaveMetadata && |
1604 load_state_ == kLoadingFromSourceElement) { | 1632 load_state_ == kLoadingFromSourceElement) { |
1605 // resource selection algorithm | 1633 // resource selection algorithm |
1606 // Step 9.Otherwise.9 - Failed with elements: Queue a task, using the DOM | 1634 // Step 9.Otherwise.9 - Failed with elements: Queue a task, using the DOM |
1607 // manipulation task source, to fire a simple event named error at the | 1635 // manipulation task source, to fire a simple event named error at the |
1608 // candidate element. | 1636 // candidate element. |
(...skipping 19 matching lines...) Expand all Loading... |
1628 BLINK_MEDIA_LOG << "mediaLoadingFailed(" << (void*)this | 1656 BLINK_MEDIA_LOG << "mediaLoadingFailed(" << (void*)this |
1629 << ") - no more <source> elements, waiting"; | 1657 << ") - no more <source> elements, waiting"; |
1630 WaitForSourceChange(); | 1658 WaitForSourceChange(); |
1631 } | 1659 } |
1632 | 1660 |
1633 return; | 1661 return; |
1634 } | 1662 } |
1635 | 1663 |
1636 if (error == WebMediaPlayer::kNetworkStateNetworkError && | 1664 if (error == WebMediaPlayer::kNetworkStateNetworkError && |
1637 ready_state_ >= kHaveMetadata) { | 1665 ready_state_ >= kHaveMetadata) { |
1638 MediaEngineError(MediaError::Create(MediaError::kMediaErrNetwork)); | 1666 MediaEngineError(MediaError::Create(MediaError::kMediaErrNetwork, message)); |
1639 } else if (error == WebMediaPlayer::kNetworkStateDecodeError) { | 1667 } else if (error == WebMediaPlayer::kNetworkStateDecodeError) { |
1640 MediaEngineError(MediaError::Create(MediaError::kMediaErrDecode)); | 1668 MediaEngineError(MediaError::Create(MediaError::kMediaErrDecode, message)); |
1641 } else if ((error == WebMediaPlayer::kNetworkStateFormatError || | 1669 } else if ((error == WebMediaPlayer::kNetworkStateFormatError || |
1642 error == WebMediaPlayer::kNetworkStateNetworkError) && | 1670 error == WebMediaPlayer::kNetworkStateNetworkError) && |
1643 load_state_ == kLoadingFromSrcAttr) { | 1671 load_state_ == kLoadingFromSrcAttr) { |
1644 NoneSupported(); | 1672 if (message.IsEmpty()) { |
| 1673 // Generate a more meaningful error message to differentiate the two types |
| 1674 // of MEDIA_SRC_ERR_NOT_SUPPORTED. |
| 1675 NoneSupported(BuildElementErrorMessage( |
| 1676 error == WebMediaPlayer::kNetworkStateFormatError ? "Format error" |
| 1677 : "Network error")); |
| 1678 } else { |
| 1679 NoneSupported(message); |
| 1680 } |
1645 } | 1681 } |
1646 | 1682 |
1647 UpdateDisplayState(); | 1683 UpdateDisplayState(); |
1648 } | 1684 } |
1649 | 1685 |
1650 void HTMLMediaElement::SetNetworkState(WebMediaPlayer::NetworkState state) { | 1686 void HTMLMediaElement::SetNetworkState(WebMediaPlayer::NetworkState state) { |
1651 BLINK_MEDIA_LOG << "setNetworkState(" << (void*)this << ", " | 1687 BLINK_MEDIA_LOG << "setNetworkState(" << (void*)this << ", " |
1652 << static_cast<int>(state) << ") - current state is " | 1688 << static_cast<int>(state) << ") - current state is " |
1653 << static_cast<int>(network_state_); | 1689 << static_cast<int>(network_state_); |
1654 | 1690 |
1655 if (state == WebMediaPlayer::kNetworkStateEmpty) { | 1691 if (state == WebMediaPlayer::kNetworkStateEmpty) { |
1656 // Just update the cached state and leave, we can't do anything. | 1692 // Just update the cached state and leave, we can't do anything. |
1657 SetNetworkState(kNetworkEmpty); | 1693 SetNetworkState(kNetworkEmpty); |
1658 return; | 1694 return; |
1659 } | 1695 } |
1660 | 1696 |
1661 if (state == WebMediaPlayer::kNetworkStateFormatError || | 1697 if (state == WebMediaPlayer::kNetworkStateFormatError || |
1662 state == WebMediaPlayer::kNetworkStateNetworkError || | 1698 state == WebMediaPlayer::kNetworkStateNetworkError || |
1663 state == WebMediaPlayer::kNetworkStateDecodeError) { | 1699 state == WebMediaPlayer::kNetworkStateDecodeError) { |
1664 MediaLoadingFailed(state); | 1700 MediaLoadingFailed(state, web_media_player_->GetErrorMessage()); |
1665 return; | 1701 return; |
1666 } | 1702 } |
1667 | 1703 |
1668 if (state == WebMediaPlayer::kNetworkStateIdle) { | 1704 if (state == WebMediaPlayer::kNetworkStateIdle) { |
1669 if (network_state_ > kNetworkIdle) { | 1705 if (network_state_ > kNetworkIdle) { |
1670 ChangeNetworkStateFromLoadingToIdle(); | 1706 ChangeNetworkStateFromLoadingToIdle(); |
1671 SetShouldDelayLoadEvent(false); | 1707 SetShouldDelayLoadEvent(false); |
1672 } else { | 1708 } else { |
1673 SetNetworkState(kNetworkIdle); | 1709 SetNetworkState(kNetworkIdle); |
1674 } | 1710 } |
(...skipping 2614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4289 kMostlyFillViewportBecomeStableSeconds, BLINK_FROM_HERE); | 4325 kMostlyFillViewportBecomeStableSeconds, BLINK_FROM_HERE); |
4290 } | 4326 } |
4291 | 4327 |
4292 void HTMLMediaElement::ViewportFillDebouncerTimerFired(TimerBase*) { | 4328 void HTMLMediaElement::ViewportFillDebouncerTimerFired(TimerBase*) { |
4293 mostly_filling_viewport_ = true; | 4329 mostly_filling_viewport_ = true; |
4294 if (web_media_player_) | 4330 if (web_media_player_) |
4295 web_media_player_->BecameDominantVisibleContent(mostly_filling_viewport_); | 4331 web_media_player_->BecameDominantVisibleContent(mostly_filling_viewport_); |
4296 } | 4332 } |
4297 | 4333 |
4298 } // namespace blink | 4334 } // namespace blink |
OLD | NEW |