Bug 880062 - Make WMF video backend call MediaDecoder::SetMediaSeekable(false) when it can't seek like it's supposed to. r=padenot

This commit is contained in:
Chris Pearce 2013-06-13 10:15:23 +12:00
Родитель 6e15ac0832
Коммит d9b89bdb0d
7 изменённых файлов: 142 добавлений и 10 удалений

Просмотреть файл

@ -38,7 +38,7 @@ MOCHITEST_FILES = \
can_play_type_ogg.js \
can_play_type_wave.js \
can_play_type_webm.js \
can_play_type_dash.js \
can_play_type_dash.js \
can_play_type_mpeg.js \
cancellable_request.sjs \
dynamic_redirect.sjs \
@ -138,6 +138,7 @@ MOCHITEST_FILES = \
test_streams_tracks.html \
$(filter disabled-for-intermittent-failures--bug-608634, test_error_in_video_document.html) \
test_timeupdate_small_files.html \
test_unseekable.html \
$(NULL)
# Disabled on Windows for frequent intermittent failures
@ -187,6 +188,7 @@ MOCHITEST_FILES += \
audio-gaps.ogg \
badtags.ogg \
beta-phrasebook.ogg \
big-buck-bunny-unseekable.mp4 \
bogus.ogv \
bug495129.ogv \
bug495794.ogg \
@ -230,6 +232,7 @@ MOCHITEST_FILES += \
variable-preskip.opus \
dirac.ogg \
multiple-bos.ogg \
no-cues.webm \
owl.mp3 \
split.webm \
seek.ogv \

Двоичные данные
content/media/test/big-buck-bunny-unseekable.mp4 Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -315,6 +315,27 @@ var gSeekTests = [
{ name:"bogus.duh", type:"bogus/duh", duration:123 }
];
function IsWindows8OrLater() {
var re = /Windows NT (\d.\d)/;
var winver = navigator.userAgent.match(re);
return winver && winver.length == 2 && parseFloat(winver[1]) >= 6.2;
}
// These are files that are non seekable, due to problems with the media,
// for example broken or missing indexes.
var gUnseekableTests = [
{ name:"no-cues.webm", type:"video/webm" },
{ name:"bogus.duh", type:"bogus/duh"}
];
// Unfortunately big-buck-bunny-unseekable.mp4 is doesn't play on Windows 7, so
// only include it in the unseekable tests if we're on later versions of Windows.
if (navigator.userAgent.indexOf("Windows") == -1 ||
IsWindows8OrLater()) {
gUnseekableTests = gUnseekableTests.concat([
{ name:"big-buck-bunny-unseekable.mp4", type:"video/mp4" }
]);
}
// These are files suitable for using with a "new Audio" constructor.
var gAudioTests = [
{ name:"r11025_s16_c1.wav", type:"audio/x-wav", duration:1.0 },

Двоичные данные
content/media/test/no-cues.webm Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1,101 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Media test: unseekable</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script type="text/javascript" src="manifest.js"></script>
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
/*
Test that unseekable media can't be seeked. We load a media that shouldn't
be seekable, and play through once. While playing through we repeatedly try
to seek and check that nothing happens when we do. We also verify that the
seekable ranges are empty.
*/
var manager = new MediaTestManager;
var onseeking = function(event) {
var v = event.target;
v.actuallySeeked = true;
};
var onseeked = function(event) {
var v = event.target;
v.actuallySeeked = true;
};
var ontimeupdate = function(event) {
var v = event.target;
// Check that when we seek nothing happens.
var t = v.currentTime;
v.currentTime = v.currentTime /= 2;
ok(Math.abs(t - v.currentTime) < 0.01, "Current time shouldn't change when seeking in unseekable media: " + v.name);
// Check that the seekable ranges are empty.
is(v.seekable.length, 0, "Should have no seekable ranges in unseekable media: " + v.name);
};
var onended = function(event) {
var v = event.target;
// Remove the event listeners so that they can't run if there are any pending
// events.
v.removeEventListener("seeking", onseeking, false);
v.removeEventListener("seeked", onseeked, false);
v.removeEventListener("timeupdate", ontimeupdate, false);
v.removeEventListener("ended", onended, false);
v.src = "";
if (v.parentNode) {
v.parentNode.removeChild(v);
}
// Verify that none of the seeks we did in timeupdate actually seeked.
ok(!v.actuallySeeked, "Should not be able to seek in unseekable media: " + v.name);
manager.finished(v.token);
}
function startTest(test, token) {
var v = document.createElement('video');
manager.started(token);
v.name = test.name;
v.src = test.name;
v.token = token;
v.autoplay = "true";
v.actuallySeeked = false;
v.addEventListener("seeking", onseeking, false);
v.addEventListener("seeked", onseeked, false);
v.addEventListener("timeupdate", ontimeupdate, false);
v.addEventListener("ended", onended, false);
document.body.appendChild(v);
}
function canPlay(candidates) {
var v = document.createElement("video");
var resources = candidates.filter(function(x){return v.canPlayType(x.type);});
return (resources.length > 0);
}
if (canPlay(gUnseekableTests)) {
manager.runTests(gUnseekableTests, startTest);
} else {
todo(false, "No files of supported format to test");
}
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -52,7 +52,6 @@ WMFReader::WMFReader(AbstractMediaDecoder* aDecoder)
mAudioFrameOffset(0),
mHasAudio(false),
mHasVideo(false),
mCanSeek(false),
mUseHwAccel(false),
mMustRecaptureAudioPosition(true),
mIsMP3Enabled(WMFDecoder::IsMP3Supported())
@ -583,14 +582,21 @@ WMFReader::ReadMetadata(VideoInfo* aInfo,
// Abort if both video and audio failed to initialize.
NS_ENSURE_TRUE(mInfo.mHasAudio || mInfo.mHasVideo, NS_ERROR_FAILURE);
// Get the duration, and report it to the decoder if we have it.
int64_t duration = 0;
if (SUCCEEDED(GetSourceReaderDuration(mSourceReader, duration))) {
hr = GetSourceReaderDuration(mSourceReader, duration);
if (SUCCEEDED(hr)) {
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
mDecoder->SetMediaDuration(duration);
}
hr = GetSourceReaderCanSeek(mSourceReader, mCanSeek);
NS_ASSERTION(SUCCEEDED(hr), "Can't determine if resource is seekable");
// We can seek if we get a duration *and* the reader reports that it's
// seekable.
bool canSeek = false;
if (FAILED(hr) ||
FAILED(GetSourceReaderCanSeek(mSourceReader, canSeek)) ||
!canSeek) {
mDecoder->SetMediaSeekable(false);
}
*aInfo = mInfo;
*aTags = nullptr;
@ -986,9 +992,11 @@ WMFReader::Seek(int64_t aTargetUs,
LOG("WMFReader::Seek() %lld", aTargetUs);
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
if (!mCanSeek) {
return NS_ERROR_FAILURE;
}
#ifdef DEBUG
bool canSeek = false;
GetSourceReaderCanSeek(mSourceReader, canSeek);
NS_ASSERTION(canSeek, "WMFReader::Seek() should only be called if we can seek!");
#endif
nsresult rv = ResetDecode();
NS_ENSURE_SUCCESS(rv, rv);

Просмотреть файл

@ -109,7 +109,6 @@ private:
bool mHasAudio;
bool mHasVideo;
bool mCanSeek;
bool mUseHwAccel;
// We can't call WMFDecoder::IsMP3Supported() on non-main threads, since it