Backout ec46cfa51bf8, 4a54f06efee8, de811fbd27b0 & 67ea1314c777 (bug 567077) for causing bug 781141

This commit is contained in:
Ed Morley 2012-08-08 13:11:34 +01:00
Родитель 3d2ce33f14
Коммит 2c3082317d
18 изменённых файлов: 12 добавлений и 433 удалений

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

@ -312,11 +312,6 @@ public:
static bool IsMediaPluginsType(const nsACString& aType);
#endif
/**
* Get the mime type for this element.
*/
void GetMimeType(nsCString& aMimeType);
/**
* Called when a child source element is added to this media element. This
* may queue a task to run the select resource algorithm if appropriate.
@ -877,13 +872,6 @@ protected:
// True if the media's channel's download has been suspended.
bool mDownloadSuspendedByCache;
// The Content-Type for this media. When we are sniffing for the Content-Type,
// and we are recreating a channel after the initial load, we need that
// information to give it as a hint to the channel for it to bypass the
// sniffing phase, that would fail because sniffing only works when applied to
// the first bytes of the stream.
nsCString mMimeType;
};
#endif

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

@ -1041,11 +1041,6 @@ nsresult nsHTMLMediaElement::LoadResource()
if (other) {
// Clone it.
nsresult rv = InitializeDecoderAsClone(other->mDecoder);
// Get the mimetype from the element we clone, since we will not get it via
// the channel, and we won't be able to sniff for it, because we will not
// open a channel to get the beginning of the media (it is likely to already
// be in the cache).
mMimeType = other->mMimeType;
if (NS_SUCCEEDED(rv))
return rv;
}
@ -1084,8 +1079,7 @@ nsresult nsHTMLMediaElement::LoadResource()
nullptr,
loadGroup,
nullptr,
nsICachingChannel::LOAD_BYPASS_LOCAL_CACHE_IF_BUSY |
nsIChannel::LOAD_TREAT_APPLICATION_OCTET_STREAM_AS_UNKNOWN,
nsICachingChannel::LOAD_BYPASS_LOCAL_CACHE_IF_BUSY,
channelPolicy);
NS_ENSURE_SUCCESS(rv,rv);
@ -2424,21 +2418,19 @@ nsresult nsHTMLMediaElement::InitializeDecoderForChannel(nsIChannel *aChannel,
NS_ASSERTION(mDecoder == nullptr, "Shouldn't have a decoder");
nsCAutoString mimeType;
aChannel->GetContentType(mimeType);
aChannel->GetContentType(mMimeType);
NS_ASSERTION(!mMimeType.IsEmpty(), "We should have the Content-Type.");
nsRefPtr<nsMediaDecoder> decoder = CreateDecoder(mMimeType);
nsRefPtr<nsMediaDecoder> decoder = CreateDecoder(mimeType);
if (!decoder) {
nsAutoString src;
GetCurrentSrc(src);
NS_ConvertUTF8toUTF16 mimeUTF16(mMimeType);
NS_ConvertUTF8toUTF16 mimeUTF16(mimeType);
const PRUnichar* params[] = { mimeUTF16.get(), src.get() };
ReportLoadError("MediaLoadUnsupportedMimeType", params, ArrayLength(params));
return NS_ERROR_FAILURE;
}
LOG(PR_LOG_DEBUG, ("%p Created decoder %p for type %s", this, decoder.get(), mMimeType.get()));
LOG(PR_LOG_DEBUG, ("%p Created decoder %p for type %s", this, decoder.get(), mimeType.get()));
MediaResource* resource = MediaResource::Create(decoder, aChannel);
if (!resource)
@ -3514,11 +3506,6 @@ NS_IMETHODIMP nsHTMLMediaElement::GetMozFragmentEnd(double *aTime)
return NS_OK;
}
void nsHTMLMediaElement::GetMimeType(nsCString& aMimeType)
{
aMimeType = mMimeType;
}
void nsHTMLMediaElement::NotifyAudioAvailableListener()
{
if (mDecoder) {

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

@ -688,24 +688,12 @@ ChannelMediaResource::RecreateChannel()
nsCOMPtr<nsILoadGroup> loadGroup = element->GetDocumentLoadGroup();
NS_ENSURE_TRUE(loadGroup, NS_ERROR_NULL_POINTER);
nsresult rv = NS_NewChannel(getter_AddRefs(mChannel),
mURI,
nsnull,
loadGroup,
nsnull,
loadFlags);
// We have cached the Content-Type, which should not change. Give a hint to
// the channel to avoid a sniffing failure, which would be expected because we
// are probably seeking in the middle of the bitstream, and sniffing relies
// on the presence of a magic number at the beginning of the stream.
nsCAutoString contentType;
element->GetMimeType(contentType);
NS_ASSERTION(!contentType.IsEmpty(),
"When recreating a channel, we should know the Content-Type.");
mChannel->SetContentType(contentType);
return rv;
return NS_NewChannel(getter_AddRefs(mChannel),
mURI,
nullptr,
loadGroup,
nullptr,
loadFlags);
}
void

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

@ -108,7 +108,7 @@ MOCHITEST_FILES = \
test_seek2.html \
test_source.html \
test_source_write.html \
test_source_null.html \
test_source_null.html \
test_standalone.html \
test_streams_element_capture.html \
test_streams_element_capture_reset.html \
@ -127,8 +127,6 @@ MOCHITEST_FILES = \
test_media_selection.html \
test_playback.html \
test_seekLies.html \
test_media_sniffer.html \
contentType.sjs \
$(NULL)
# Tests disabled on Linux for frequent intermittent failures
@ -215,9 +213,6 @@ MOCHITEST_FILES += \
video-overhang.ogg \
file_a4_tone.ogg \
detodos.opus \
short.mp4 \
notags.mp3 \
id3tags.mp3 \
$(NULL)
# Wave sample files

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

@ -1,77 +0,0 @@
// Parse the query string, and give us the value for a certain key, or false if
// it does not exist.
function parseQuery(request, key) {
var params = request.queryString.split('?')[0].split('&');
for (var j = 0; j < params.length; ++j) {
var p = params[j];
if (p == key)
return true;
if (p.indexOf(key + "=") == 0)
return p.substring(key.length + 1);
if (p.indexOf("=") < 0 && key == "")
return p;
}
return false;
}
function handleRequest(request, response) {
try {
// Get the filename to send back.
var filename = parseQuery(request, "file");
const CC = Components.Constructor;
const BinaryOutputStream = CC("@mozilla.org/binaryoutputstream;1",
"nsIBinaryOutputStream",
"setOutputStream");
var file = Components.classes["@mozilla.org/file/directory_service;1"].
getService(Components.interfaces.nsIProperties).
get("CurWorkD", Components.interfaces.nsILocalFile);
var fis = Components.classes['@mozilla.org/network/file-input-stream;1'].
createInstance(Components.interfaces.nsIFileInputStream);
var bis = Components.classes["@mozilla.org/binaryinputstream;1"].
createInstance(Components.interfaces.nsIBinaryInputStream);
var paths = "tests/content/media/test/" + filename;
dump(paths + '\n');
var split = paths.split("/");
for(var i = 0; i < split.length; ++i) {
file.append(split[i]);
}
fis.init(file, -1, -1, false);
// handle range requests
var partialstart = 0,
partialend = file.fileSize - 1;
if (request.hasHeader("Range")) {
var range = request.getHeader("Range");
var parts = range.replace(/bytes=/, "").split("-");
var partialstart = parts[0];
var partialend = parts[1];
if (!partialend.length) {
partialend = file.fileSize - 1;
}
response.setStatusLine(request.httpVersion, 206, "Partial Content");
var contentRange = "bytes " + partialstart + "-" + partialend + "/" + file.fileSize;
response.setHeader("Content-Range", contentRange);
}
fis.seek(Components.interfaces.nsISeekableStream.NS_SEEK_SET, partialstart);
bis.setInputStream(fis);
var sendContentType = parseQuery(request, "nomime");
if (sendContentType == false) {
var contentType = parseQuery(request, "type");
if (contentType == false) {
// This should not happen.
dump("No type specified without having \'nomime\' in parameters.");
return;
}
response.setHeader("Content-Type", contentType, false);
}
response.setHeader("Content-Length", ""+bis.available(), false);
var bytes = bis.readBytes(bis.available());
response.write(bytes, bytes.length);
} catch (e) {
dump ("ERROR : " + e + "\n");
}
}

Двоичные данные
content/media/test/id3tags.mp3

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

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

@ -151,19 +151,6 @@ var gPlayTests = [
{ name:"bogus.duh", type:"bogus/duh", duration:Number.NaN }
];
// A file for each type we can support.
var gSnifferTests = [
{ name:"big.wav", type:"audio/x-wav", duration:9.278981, size:102444 },
{ name:"320x240.ogv", type:"video/ogg", width:320, height:240, duration:0.233, size:28942 },
{ name:"seek.webm", type:"video/webm", duration:3.966, size:215529 },
{ name:"short.mp4", type:"video/mp4", duration:0.2, size:29435},
// A mp3 file without id3 tags.
{ name:"notags.mp3", type:"audio/mpeg", duration:0.28, size:2506},
// A mp3 file with id3 tags.
{ name:"id3tags.mp3", type:"audio/mpeg", duration:0.28, size:3530},
{ name:"bogus.duh", type:"bogus/duh" }
];
// Converts a path/filename to a file:// URI which we can load from disk.
// Optionally checks whether the file actually exists on disk at the location
// we've specified.

Двоичные данные
content/media/test/notags.mp3

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

Двоичные данные
content/media/test/short.mp4

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

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

@ -1,70 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Media test: mozStopDownload</title>
<meta charset='utf-8'>
<script type="text/javascript" src="/MochiKit/Base.js"></script>
<script type="text/javascript" src="/MochiKit/DOM.js"></script>
<script type="text/javascript" src="/MochiKit/Style.js"></script>
<script type="text/javascript" src="/MochiKit/Signal.js"></script>
<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 finish_test(element) {
if (element.parentNode)
element.parentNode.removeChild(element);
manager.finished(element.token);
}
function onApplicationOctetStreamLoaded(e) {
var t = e.target;
t.removeEventListener('loadedmetadata', onApplicationOctetStreamLoaded);
ok(true, "The media loads when served with application/octet-stream.");
finish_test(t);
}
function checkApplicationOctetStream(t) {
t.src = t.src.replace("&nomime", "&type=application/octet-stream");
t.addEventListener("loadedmetadata", onApplicationOctetStreamLoaded);
}
function onmetadataloaded(e) {
var t = e.target;
t.removeEventListener('loadedmetadata', onmetadataloaded)
ok(true, "The media loads when served without a Content-Type.");
checkApplicationOctetStream(t);
}
function onerror(e) {
var t = e.target;
t.removeEventListener('error', onerror);
ok(false, "The media could not be loaded." + t.src + "\n");
finish_test(t);
}
function startTest(test, token) {
var elemType = /^audio/.test(test.type) ? "audio" : "video";
var element = document.createElement(elemType);
// This .sjs file serve the media file without Content-Type header, or with a
// specific Content-Type header.
element.src = 'contentType.sjs?file=' + test.name + "&nomime";
element.token = token;
element.controls = true;
element.preload = "metadata";
document.body.appendChild(element);
manager.started(token);
element.addEventListener("loadedmetadata", onmetadataloaded);
element.addEventListener("error", onerror);
}
manager.runTests(gSnifferTests, startTest);
</script>
</pre>
</body>
</html>

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

@ -75,7 +75,6 @@
#define AUDIO_OGG "audio/ogg"
#define AUDIO_WAV "audio/x-wav"
#define AUDIO_WEBM "audio/webm"
#define AUDIO_MP3 "audio/mpeg"
#define BINARY_OCTET_STREAM "binary/octet-stream"

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

@ -27,7 +27,6 @@ PARALLEL_DIRS += \
filepicker \
find \
intl \
mediasniffer \
microformats \
osfile \
parentalcontrols \

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

@ -1,30 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = mediasniffer
LIBRARY_NAME = mediasniffer
LIBXUL_LIBRARY = 1
EXPORT_LIBRARY = 1
MODULE_NAME = nsMediaSnifferModule
IS_COMPONENT = 1
CPPSRCS = \
nsMediaSniffer.cpp \
nsMediaSnifferModule.cpp \
$(NULL)
EXPORTS = \
nsMediaSniffer.h \
$(NULL)
include $(topsrcdir)/config/config.mk
include $(topsrcdir)/config/rules.mk

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

@ -1,107 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 tw=80 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsMediaSniffer.h"
#include "nsMemory.h"
#include "nsIHttpChannel.h"
#include "nsAString.h"
#include "nsMimeTypes.h"
#include "mozilla/ModuleUtils.h"
#include "nsIClassInfoImpl.h"
// The minimum number of bytes that are needed to attempt to sniff an mp4 file.
static const unsigned MP4_MIN_BYTES_COUNT = 12;
// The maximum number of bytes to consider when attempting to sniff a file.
static const PRUint32 MAX_BYTES_SNIFFED = 512;
NS_IMPL_CLASSINFO(nsMediaSniffer, NULL, 0, NS_MEDIA_SNIFFER_CID)
NS_IMPL_ISUPPORTS1(nsMediaSniffer, nsIContentSniffer)
nsMediaSniffer::nsMediaSnifferEntry nsMediaSniffer::sSnifferEntries[] = {
// The string OggS, followed by the null byte.
PATTERN_ENTRY("\xFF\xFF\xFF\xFF\xFF", "OggS", APPLICATION_OGG),
// The string RIFF, followed by four bytes, followed by the string WAVE
PATTERN_ENTRY("\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF", "RIFF\x00\x00\x00\x00WAVE", AUDIO_WAV),
// WebM
PATTERN_ENTRY("\xFF\xFF\xFF\xFF", "\x1A\x45\xDF\xA3", VIDEO_WEBM),
// mp3 without ID3 tags.
PATTERN_ENTRY("\xFF\xFB", "\xFF\xFA", AUDIO_MP3),
// mp3 with ID3 tags, the string "ID3".
PATTERN_ENTRY("\xFF\xFF\xFF", "ID3", AUDIO_MP3)
};
// This function implements mp4 sniffing algorithm, described at
// http://mimesniff.spec.whatwg.org/#signature-for-mp4
static bool MatchesMP4(const PRUint8* aData, const PRUint32 aLength)
{
if (aLength <= MP4_MIN_BYTES_COUNT) {
return false;
}
// Conversion from big endian to host byte order.
PRUint32 boxSize = (PRUint32)(aData[3] | aData[2] << 8 | aData[1] << 16 | aData[0] << 24);
// Boxsize should be evenly divisible by 4.
if (boxSize % 4 || aLength < boxSize) {
return false;
}
// The string "ftyp".
if (aData[4] != 0x66 ||
aData[5] != 0x74 ||
aData[6] != 0x79 ||
aData[7] != 0x70) {
return false;
}
for (PRUint32 i = 2; i <= boxSize / 4 - 1 ; i++) {
if (i == 3) {
continue;
}
// The string "mp4".
if (aData[4*i] == 0x6D &&
aData[4*i+1] == 0x70 &&
aData[4*i+2] == 0x34) {
return true;
}
}
return false;
}
NS_IMETHODIMP
nsMediaSniffer::GetMIMETypeFromContent(nsIRequest* aRequest,
const PRUint8* aData,
const PRUint32 aLength,
nsACString& aSniffedType)
{
const PRUint32 clampedLength = NS_MIN(aLength, MAX_BYTES_SNIFFED);
for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(sSnifferEntries); ++i) {
const nsMediaSnifferEntry& currentEntry = sSnifferEntries[i];
if (clampedLength < currentEntry.mLength || currentEntry.mLength == 0) {
continue;
}
bool matched = true;
for (PRUint32 j = 0; j < currentEntry.mLength; ++j) {
if ((currentEntry.mMask[j] & aData[j]) != currentEntry.mPattern[j]) {
matched = false;
break;
}
}
if (matched) {
aSniffedType.AssignASCII(currentEntry.mContentType);
return NS_OK;
}
}
if (MatchesMP4(aData, clampedLength)) {
aSniffedType.AssignLiteral(VIDEO_MP4);
return NS_OK;
}
// Could not sniff the media type, we are required to set it to
// application/octet-stream.
aSniffedType.AssignLiteral(APPLICATION_OCTET_STREAM);
return NS_ERROR_NOT_AVAILABLE;
}

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

@ -1,41 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 tw=80 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsIModule.h"
#include "nsIFactory.h"
#include "nsIComponentManager.h"
#include "nsIComponentRegistrar.h"
#include "nsIContentSniffer.h"
// ed905ba3-c656-480e-934e-6bc35bd36aff
#define NS_MEDIA_SNIFFER_CID \
{0x3fdd6c28, 0x5b87, 0x4e3e, \
{0x8b, 0x57, 0x8e, 0x83, 0xc2, 0x3c, 0x1a, 0x6d}}
#define NS_MEDIA_SNIFFER_CONTRACTID "@mozilla.org/media/sniffer;1"
class nsMediaSniffer : public nsIContentSniffer
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSICONTENTSNIFFER
protected:
~nsMediaSniffer() {};
#define PATTERN_ENTRY(mask, pattern, contentType) \
{(const PRUint8*)mask, (const PRUint8*)pattern, sizeof(mask) - 1, contentType}
struct nsMediaSnifferEntry {
const PRUint8* mMask;
const PRUint8* mPattern;
const PRUint32 mLength;
const char* mContentType;
};
static nsMediaSnifferEntry sSnifferEntries[];
};

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

@ -1,37 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/ModuleUtils.h"
#include "nsMediaSniffer.h"
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMediaSniffer)
NS_DEFINE_NAMED_CID(NS_MEDIA_SNIFFER_CID);
static const mozilla::Module::CIDEntry kMediaSnifferCIDs[] = {
{ &kNS_MEDIA_SNIFFER_CID, false, NULL, nsMediaSnifferConstructor },
{ NULL }
};
static const mozilla::Module::ContractIDEntry kMediaSnifferContracts[] = {
{ NS_MEDIA_SNIFFER_CONTRACTID, &kNS_MEDIA_SNIFFER_CID },
{ NULL }
};
static const mozilla::Module::CategoryEntry kMediaSnifferCategories[] = {
{ "content-sniffing-services", NS_MEDIA_SNIFFER_CONTRACTID, NS_MEDIA_SNIFFER_CONTRACTID},
{ "net-content-sniffers", NS_MEDIA_SNIFFER_CONTRACTID, NS_MEDIA_SNIFFER_CONTRACTID},
{ NULL }
};
static const mozilla::Module kMediaSnifferModule = {
mozilla::Module::kVersion,
kMediaSnifferCIDs,
kMediaSnifferContracts,
kMediaSnifferCategories
};
NSMODULE_DEFN(nsMediaSnifferModule) = &kMediaSnifferModule;

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

@ -142,7 +142,6 @@ COMPONENT_LIBS += \
htmlpars \
identity \
imglib2 \
mediasniffer \
gkgfx \
gklayout \
docshell \

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

@ -180,7 +180,6 @@
MODULE(nsWindowDataSourceModule) \
MODULE(nsParserModule) \
MODULE(nsImageLib2Module) \
MODULE(nsMediaSnifferModule) \
MODULE(nsGfxModule) \
PROFILER_MODULE \
WIDGET_MODULES \