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