Bug 480376 - Implement mozHasAudio to indicate when there's no audio track available. r=cpearce

This commit is contained in:
Paul ADENOT 2012-04-28 11:01:10 -04:00
parent f65e785137
commit 70eca6f58d
11 changed files with 83 additions and 12 deletions

View File

@ -132,7 +132,7 @@ public:
// Called by the video decoder object, on the main thread,
// when it has read the metadata containing video dimensions,
// etc.
void MetadataLoaded(PRUint32 aChannels, PRUint32 aRate);
void MetadataLoaded(PRUint32 aChannels, PRUint32 aRate, bool aHasAudio);
// Called by the video decoder object, on the main thread,
// when it has read the first frame of the video
@ -794,6 +794,9 @@ protected:
// The CORS mode when loading the media element
mozilla::CORSMode mCORSMode;
// True if the media has an audio track
bool mHasAudio;
};
#endif

View File

@ -177,7 +177,7 @@ nsHTMLAudioElement::MozSetup(PRUint32 aChannels, PRUint32 aRate)
return rv;
}
MetadataLoaded(aChannels, aRate);
MetadataLoaded(aChannels, aRate, true);
mAudioStream->SetVolume(mVolume);
return NS_OK;
}

View File

@ -1459,7 +1459,8 @@ nsHTMLMediaElement::nsHTMLMediaElement(already_AddRefed<nsINodeInfo> aNodeInfo)
mShuttingDown(false),
mLoadIsSuspended(false),
mMediaSecurityVerified(false),
mCORSMode(CORS_NONE)
mCORSMode(CORS_NONE),
mHasAudio(false)
{
#ifdef PR_LOGGING
if (!gMediaElementLog) {
@ -2258,10 +2259,11 @@ void nsHTMLMediaElement::ProcessMediaFragmentURI()
}
}
void nsHTMLMediaElement::MetadataLoaded(PRUint32 aChannels, PRUint32 aRate)
void nsHTMLMediaElement::MetadataLoaded(PRUint32 aChannels, PRUint32 aRate, bool aHasAudio)
{
mChannels = aChannels;
mRate = aRate;
mHasAudio = aHasAudio;
ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_METADATA);
DispatchAsyncEvent(NS_LITERAL_STRING("durationchange"));
DispatchAsyncEvent(NS_LITERAL_STRING("loadedmetadata"));

View File

@ -219,3 +219,11 @@ NS_IMETHODIMP nsHTMLVideoElement::GetMozFrameDelay(double *aMozFrameDelay) {
*aMozFrameDelay = container ? container->GetFrameDelay() : 0;
return NS_OK;
}
/* readonly attribute bool mozHasAudio */
NS_IMETHODIMP nsHTMLVideoElement::GetMozHasAudio(bool *aHasAudio) {
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
*aHasAudio = mHasAudio;
return NS_OK;
}

View File

@ -408,7 +408,8 @@ void nsBuiltinDecoder::AudioAvailable(float* aFrameBuffer,
}
void nsBuiltinDecoder::MetadataLoaded(PRUint32 aChannels,
PRUint32 aRate)
PRUint32 aRate,
bool aHasAudio)
{
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
if (mShuttingDown) {
@ -435,7 +436,7 @@ void nsBuiltinDecoder::MetadataLoaded(PRUint32 aChannels,
// Make sure the element and the frame (if any) are told about
// our new size.
Invalidate();
mElement->MetadataLoaded(aChannels, aRate);
mElement->MetadataLoaded(aChannels, aRate, aHasAudio);
}
if (!mResourceLoaded) {

View File

@ -555,7 +555,8 @@ public:
// Called when the metadata from the media file has been read.
// Call on the main thread only.
void MetadataLoaded(PRUint32 aChannels,
PRUint32 aRate);
PRUint32 aRate,
bool aHasAudio);
// Called when the first frame has been loaded.
// Call on the main thread only.

View File

@ -152,21 +152,23 @@ private:
nsCOMPtr<nsBuiltinDecoder> mDecoder;
public:
nsAudioMetadataEventRunner(nsBuiltinDecoder* aDecoder, PRUint32 aChannels,
PRUint32 aRate) :
PRUint32 aRate, bool aHasAudio) :
mDecoder(aDecoder),
mChannels(aChannels),
mRate(aRate)
mRate(aRate),
mHasAudio(aHasAudio)
{
}
NS_IMETHOD Run()
{
mDecoder->MetadataLoaded(mChannels, mRate);
mDecoder->MetadataLoaded(mChannels, mRate, mHasAudio);
return NS_OK;
}
const PRUint32 mChannels;
const PRUint32 mRate;
const bool mHasAudio;
};
// Owns the global state machine thread and counts of
@ -1515,7 +1517,7 @@ nsresult nsBuiltinDecoderStateMachine::DecodeMetadata()
mDecoder->RequestFrameBufferLength(frameBufferLength);
}
nsCOMPtr<nsIRunnable> metadataLoadedEvent =
new nsAudioMetadataEventRunner(mDecoder, mInfo.mAudioChannels, mInfo.mAudioRate);
new nsAudioMetadataEventRunner(mDecoder, mInfo.mAudioChannels, mInfo.mAudioRate, HasAudio());
NS_DispatchToMainThread(metadataLoadedEvent, NS_DISPATCH_NORMAL);
if (mState == DECODER_STATE_DECODING_METADATA) {

View File

@ -156,6 +156,7 @@ _TEST_FILES = \
test_video_to_canvas.html \
use_large_cache.js \
test_audiowrite.html \
test_mozHasAudio.html \
$(NULL)
# Don't run in suite

View File

@ -47,6 +47,15 @@ var gPausedAfterEndedTests = gSmallTests.concat([
{ name:"small-shot.ogg", type:"video/ogg", duration:0.276 }
]);
// Test the mozHasAudio property
var gMozHasAudioTests = [
{ name:"big.wav", type:"audio/x-wav", duration:9.278981, size:102444, hasAudio:undefined },
{ name:"320x240.ogv", type:"video/ogg", width:320, height:240, duration:0.233, size:28942, hasAudio:false },
{ name:"short-video.ogv", type:"video/ogg", duration:1.081, hasAudio:true },
{ name:"seek.webm", type:"video/webm", duration:3.966, size:215529, hasAudio:false },
{ name:"bogus.duh", type:"bogus/duh" }
];
// These are files that we want to make sure we can play through. We can
// also check metadata. Put files of the same type together in this list so if
// something crashes we have some idea of which backend is responsible.

View File

@ -0,0 +1,41 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test playback of media files that should play OK</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">
var manager = new MediaTestManager;
function onloadedmetadata(e) {
var t = e.target;
is(t.mozHasAudio, t.hasAudio, "The element reports the wrong audio property." + t.token);
manager.finished(t.token);
}
function startTest(test, token) {
var elemType = /^audio/.test(test.type) ? "audio" : "video";
var element = document.createElement(elemType);
element.token = token;
manager.started(token);
element.src = test.name;
element.name = test.name;
element.hasAudio = test.hasAudio;
element.addEventListener("loadedmetadata", onloadedmetadata, false);
element.load();
}
manager.runTests(gMozHasAudioTests, startTest);
</script>
</pre>
</body>
</html>

View File

@ -48,7 +48,7 @@
* @status UNDER_DEVELOPMENT
*/
[scriptable, uuid(E3763903-928B-47C4-AC3B-C47EB43884CA)]
[scriptable, uuid(0a1c8b44-12a4-4316-b39f-feeee48475f8)]
interface nsIDOMHTMLVideoElement : nsIDOMHTMLMediaElement
{
attribute long width;
@ -75,5 +75,8 @@ interface nsIDOMHTMLVideoElement : nsIDOMHTMLMediaElement
// Time which the last painted video frame was late by, in seconds.
readonly attribute double mozFrameDelay;
// True if the video has an audio track available.
readonly attribute bool mozHasAudio;
};