~ubuntu-branches/ubuntu/lucid/webkit/lucid-updates

« back to all changes in this revision

Viewing changes to WebCore/html/HTMLMediaElement.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Gustavo Noronha Silva
  • Date: 2010-02-04 19:30:57 UTC
  • mfrom: (1.2.8 upstream) (4.3.9 sid)
  • Revision ID: james.westby@ubuntu.com-20100204193057-d3018lm1fipb0703
* New upstream release
* debian/copyright:
- Updated with changes since 1.1.19.

Show diffs side-by-side

added added

removed removed

Lines of Context:
132
132
    document()->unregisterForMediaVolumeCallbacks(this);
133
133
}
134
134
 
 
135
void HTMLMediaElement::willMoveToNewOwnerDocument()
 
136
{
 
137
    document()->unregisterForDocumentActivationCallbacks(this);
 
138
    document()->unregisterForMediaVolumeCallbacks(this);
 
139
    HTMLElement::willMoveToNewOwnerDocument();
 
140
}
 
141
 
 
142
void HTMLMediaElement::didMoveToNewOwnerDocument()
 
143
{
 
144
    document()->registerForDocumentActivationCallbacks(this);
 
145
    document()->registerForMediaVolumeCallbacks(this);
 
146
    HTMLElement::didMoveToNewOwnerDocument();
 
147
}
 
148
 
 
149
 
135
150
bool HTMLMediaElement::checkDTD(const Node* newChild)
136
151
{
137
152
    return newChild->hasTagName(sourceTag) || HTMLElement::checkDTD(newChild);
255
270
void HTMLMediaElement::removedFromDocument()
256
271
{
257
272
    if (m_networkState > NETWORK_EMPTY)
258
 
        pause();
 
273
        pause(processingUserGesture());
259
274
    if (m_isFullscreen)
260
275
        exitFullscreen();
261
276
    HTMLElement::removedFromDocument();
406
421
    return canPlay;
407
422
}
408
423
 
409
 
void HTMLMediaElement::load(ExceptionCode& ec)
 
424
void HTMLMediaElement::load(bool isUserGesture, ExceptionCode& ec)
410
425
{
411
 
    if (m_restrictions & RequireUserGestureForLoadRestriction && !processingUserGesture())
 
426
    if (m_restrictions & RequireUserGestureForLoadRestriction && !isUserGesture)
412
427
        ec = INVALID_STATE_ERR;
413
428
    else {
414
429
        prepareForLoad();
571
586
        m_player = MediaPlayer::create(this);
572
587
#endif
573
588
 
 
589
    m_player->setAutobuffer(autobuffer());
574
590
    m_player->setPreservesPitch(m_webkitPreservesPitch);
575
591
    updateVolume();
576
592
 
1078
1094
 
1079
1095
bool HTMLMediaElement::ended() const
1080
1096
{
1081
 
    return endedPlayback();
 
1097
    // 4.8.10.8 Playing the media resource
 
1098
    // The ended attribute must return true if the media element has ended 
 
1099
    // playback and the direction of playback is forwards, and false otherwise.
 
1100
    return endedPlayback() && m_playbackRate > 0;
1082
1101
}
1083
1102
 
1084
1103
bool HTMLMediaElement::autoplay() const
1101
1120
    setBooleanAttribute(autobufferAttr, b);
1102
1121
}
1103
1122
 
1104
 
void HTMLMediaElement::play()
 
1123
void HTMLMediaElement::play(bool isUserGesture)
1105
1124
{
1106
 
    if (m_restrictions & RequireUserGestureForRateChangeRestriction && !processingUserGesture())
 
1125
    if (m_restrictions & RequireUserGestureForRateChangeRestriction && !isUserGesture)
1107
1126
        return;
1108
1127
 
1109
1128
    playInternal();
1136
1155
    updatePlayState();
1137
1156
}
1138
1157
 
1139
 
void HTMLMediaElement::pause()
 
1158
void HTMLMediaElement::pause(bool isUserGesture)
1140
1159
{
1141
 
    if (m_restrictions & RequireUserGestureForRateChangeRestriction && !processingUserGesture())
 
1160
    if (m_restrictions & RequireUserGestureForRateChangeRestriction && !isUserGesture)
1142
1161
        return;
1143
1162
 
1144
1163
    pauseInternal();
1216
1235
{
1217
1236
    if (m_muted != muted) {
1218
1237
        m_muted = muted;
1219
 
        updateVolume();
 
1238
        // Avoid recursion when the player reports volume changes.
 
1239
        if (!processingMediaPlayerCallback()) {
 
1240
            if (m_player && m_player->supportsMuting()) {
 
1241
                m_player->setMuted(m_muted);
 
1242
                if (renderer())
 
1243
                    renderer()->updateFromElement();
 
1244
            } else
 
1245
                updateVolume();
 
1246
        }
1220
1247
        scheduleEvent(eventNames().volumechangeEvent);
1221
1248
    }
1222
1249
}
1238
1265
            // Because a media element stays in non-paused state when it reaches end, playback resumes 
1239
1266
            // when the slider is dragged from the end to another position unless we pause first. Do 
1240
1267
            // a "hard pause" so an event is generated, since we want to stay paused after scrubbing finishes.
1241
 
            pause();
 
1268
            pause(processingUserGesture());
1242
1269
        } else {
1243
1270
            // Not at the end but we still want to pause playback so the media engine doesn't try to
1244
1271
            // continue playing during scrubbing. Pause without generating an event as we will 
1392
1419
{
1393
1420
    beginProcessingMediaPlayerCallback();
1394
1421
 
 
1422
    // Always call scheduleTimeupdateEvent when the media engine reports a time discontinuity, 
 
1423
    // it will only queue a 'timeupdate' event if we haven't already posted one at the current
 
1424
    // movie time.
 
1425
    scheduleTimeupdateEvent(false);
 
1426
 
1395
1427
    // 4.8.10.10 step 12 & 13.  Needed if no ReadyState change is associated with the seek.
1396
 
    if (m_readyState >= HAVE_CURRENT_DATA && m_seeking) {
 
1428
    if (m_readyState >= HAVE_CURRENT_DATA && m_seeking)
1397
1429
        finishSeek();
1398
 
    }
1399
1430
    
1400
1431
    float now = currentTime();
1401
1432
    float dur = duration();
1407
1438
        } else {
1408
1439
            if (!m_sentEndEvent) {
1409
1440
                m_sentEndEvent = true;
1410
 
                scheduleTimeupdateEvent(false);
1411
1441
                scheduleEvent(eventNames().endedEvent);
1412
1442
            }
1413
1443
        }
1422
1452
void HTMLMediaElement::mediaPlayerVolumeChanged(MediaPlayer*)
1423
1453
{
1424
1454
    beginProcessingMediaPlayerCallback();
 
1455
    if (m_player)
 
1456
        m_volume = m_player->volume();
1425
1457
    updateVolume();
1426
1458
    endProcessingMediaPlayerCallback();
1427
1459
}
1428
1460
 
 
1461
void HTMLMediaElement::mediaPlayerMuteChanged(MediaPlayer*)
 
1462
{
 
1463
    beginProcessingMediaPlayerCallback();
 
1464
    if (m_player)
 
1465
        setMuted(m_player->muted());
 
1466
    endProcessingMediaPlayerCallback();
 
1467
}
 
1468
 
1429
1469
void HTMLMediaElement::mediaPlayerDurationChanged(MediaPlayer*)
1430
1470
{
1431
1471
    beginProcessingMediaPlayerCallback();
1538
1578
 
1539
1579
bool HTMLMediaElement::endedPlayback() const
1540
1580
{
1541
 
    if (!m_player || m_readyState < HAVE_METADATA)
1542
 
        return false;
1543
 
    
1544
1581
    float dur = duration();
1545
 
    return !isnan(dur) && currentTime() >= dur && !loop();
 
1582
    if (!m_player || isnan(dur))
 
1583
        return false;
 
1584
 
 
1585
    // 4.8.10.8 Playing the media resource
 
1586
 
 
1587
    // A media element is said to have ended playback when the element's 
 
1588
    // readyState attribute is HAVE_METADATA or greater, 
 
1589
    if (m_readyState < HAVE_METADATA)
 
1590
        return false;
 
1591
    
 
1592
    // and the current playback position is the end of the media resource and the direction 
 
1593
    // of playback is forwards and the media element does not have a loop attribute specified,
 
1594
    float now = currentTime();
 
1595
    if (m_playbackRate > 0)
 
1596
        return now >= dur && !loop();
 
1597
    
 
1598
    // or the current playback position is the earliest possible position and the direction 
 
1599
    // of playback is backwards
 
1600
    if (m_playbackRate < 0)
 
1601
        return now <= 0;
 
1602
 
 
1603
    return false;
1546
1604
}
1547
1605
 
1548
1606
bool HTMLMediaElement::stoppedDueToErrors() const
1703
1761
        //  MEDIA_ERR_ABORTED while the abortEvent is being sent, but cleared immediately afterwards).
1704
1762
        // This behavior is not specified but it seems like a sensible thing to do.
1705
1763
        ExceptionCode ec;
1706
 
        load(ec);
 
1764
        load(processingUserGesture(), ec);
1707
1765
    }
1708
1766
 
1709
1767
    if (renderer())
1820
1878
    return m_player ? m_player->platformMedia() : NoPlatformMedia;
1821
1879
}
1822
1880
 
1823
 
void HTMLMediaElement::webkitEnterFullScreen(ExceptionCode& ec)
1824
 
{
1825
 
    if (m_isFullscreen)
1826
 
        return;
1827
 
 
1828
 
    // Generate an exception if this isn't called in response to a user gesture, or if the 
1829
 
    // element does not support fullscreen.
1830
 
    if (!processingUserGesture() || !supportsFullscreen()) {
1831
 
        ec = INVALID_STATE_ERR;
1832
 
        return;
1833
 
    }
1834
 
 
1835
 
    enterFullscreen();
1836
 
}
1837
 
 
1838
 
void HTMLMediaElement::webkitExitFullScreen()
1839
 
{
1840
 
    if (m_isFullscreen)
1841
 
        exitFullscreen();
1842
 
}
1843
 
 
1844
 
bool HTMLMediaElement::webkitSupportsFullscreen()
1845
 
{
1846
 
    return supportsFullscreen();
1847
 
}
1848
 
 
1849
 
bool HTMLMediaElement::webkitDisplayingFullscreen()
1850
 
{
1851
 
    return m_isFullscreen;
1852
 
}
1853
 
 
1854
1881
bool HTMLMediaElement::hasClosedCaptions() const
1855
1882
{
1856
1883
    return m_player && m_player->hasClosedCaptions();