Bug 839031 - Store the Content-Type/MIME-Type on MediaResource. r=padenot

This commit is contained in:
Chris Pearce 2013-02-15 14:10:58 +13:00
parent 8562d13911
commit add497074c
6 changed files with 62 additions and 45 deletions

View File

@ -257,11 +257,6 @@ public:
// full MIME type including the optional codecs parameter.
static mozilla::CanPlayStatus GetCanPlay(const nsAString& aType);
/**
* 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.
@ -899,13 +894,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;
// Audio Channel Type.
mozilla::dom::AudioChannelType mAudioChannelType;

View File

@ -1091,11 +1091,6 @@ nsresult nsHTMLMediaElement::LoadResource()
if (other && other->mDecoder) {
// 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;
}
@ -1248,7 +1243,6 @@ NS_IMETHODIMP nsHTMLMediaElement::MozLoadFrom(nsIDOMHTMLMediaElement* aOther)
ChangeDelayLoadStatus(false);
return rv;
}
mMimeType = other->mMimeType;
SetPlaybackRate(mDefaultPlaybackRate);
DispatchAsyncEvent(NS_LITERAL_STRING("loadstart"));
@ -2322,20 +2316,20 @@ nsresult nsHTMLMediaElement::InitializeDecoderForChannel(nsIChannel *aChannel,
nsAutoCString mimeType;
aChannel->GetContentType(mMimeType);
NS_ASSERTION(!mMimeType.IsEmpty(), "We should have the Content-Type.");
aChannel->GetContentType(mimeType);
NS_ASSERTION(!mimeType.IsEmpty(), "We should have the Content-Type.");
nsRefPtr<MediaDecoder> decoder = CreateDecoder(mMimeType);
nsRefPtr<MediaDecoder> 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)
@ -3506,11 +3500,6 @@ NS_IMETHODIMP nsHTMLMediaElement::GetMozFragmentEnd(double *aTime)
return NS_OK;
}
void nsHTMLMediaElement::GetMimeType(nsCString& aMimeType)
{
aMimeType = mMimeType;
}
void nsHTMLMediaElement::NotifyAudioAvailableListener()
{
if (mDecoder) {

View File

@ -22,11 +22,13 @@ class BufferMediaResource : public MediaResource
public:
BufferMediaResource(const uint8_t* aBuffer,
uint32_t aLength,
nsIPrincipal* aPrincipal) :
nsIPrincipal* aPrincipal,
const nsACString& aContentType) :
mBuffer(aBuffer),
mLength(aLength),
mOffset(0),
mPrincipal(aPrincipal)
mPrincipal(aPrincipal),
mContentType(aContentType)
{
MOZ_COUNT_CTOR(BufferMediaResource);
}
@ -134,11 +136,17 @@ public:
bool IsTransportSeekable() MOZ_OVERRIDE { return true; }
virtual const nsACString& GetContentType() const MOZ_OVERRIDE
{
return mContentType;
}
private:
const uint8_t * mBuffer;
uint32_t mLength;
uint32_t mOffset;
nsCOMPtr<nsIPrincipal> mPrincipal;
const nsAutoCString mContentType;
};
}

View File

@ -50,8 +50,10 @@ static const uint32_t HTTP_PARTIAL_RESPONSE_CODE = 206;
namespace mozilla {
ChannelMediaResource::ChannelMediaResource(MediaDecoder* aDecoder,
nsIChannel* aChannel, nsIURI* aURI)
: BaseMediaResource(aDecoder, aChannel, aURI),
nsIChannel* aChannel,
nsIURI* aURI,
const nsACString& aContentType)
: BaseMediaResource(aDecoder, aChannel, aURI, aContentType),
mOffset(0), mSuspendCount(0),
mReopenOnError(false), mIgnoreClose(false),
mCacheStream(this),
@ -704,7 +706,10 @@ MediaResource* ChannelMediaResource::CloneData(MediaDecoder* aDecoder)
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
NS_ASSERTION(mCacheStream.IsAvailableForSharing(), "Stream can't be cloned");
ChannelMediaResource* resource = new ChannelMediaResource(aDecoder, nullptr, mURI);
ChannelMediaResource* resource = new ChannelMediaResource(aDecoder,
nullptr,
mURI,
GetContentType());
if (resource) {
// Initially the clone is treated as suspended by the cache, because
// we don't have a channel. If the cache needs to read data from the clone
@ -916,11 +921,9 @@ ChannelMediaResource::RecreateChannel()
// 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.
nsAutoCString contentType;
element->GetMimeType(contentType);
NS_ASSERTION(!contentType.IsEmpty(),
NS_ASSERTION(!GetContentType().IsEmpty(),
"When recreating a channel, we should know the Content-Type.");
mChannel->SetContentType(contentType);
mChannel->SetContentType(GetContentType());
return rv;
}
@ -1241,8 +1244,11 @@ ChannelMediaResource::PossiblyResume()
class FileMediaResource : public BaseMediaResource
{
public:
FileMediaResource(MediaDecoder* aDecoder, nsIChannel* aChannel, nsIURI* aURI) :
BaseMediaResource(aDecoder, aChannel, aURI),
FileMediaResource(MediaDecoder* aDecoder,
nsIChannel* aChannel,
nsIURI* aURI,
const nsACString& aContentType) :
BaseMediaResource(aDecoder, aChannel, aURI, aContentType),
mSize(-1),
mLock("FileMediaResource.mLock"),
mSizeInitialized(false)
@ -1503,7 +1509,7 @@ MediaResource* FileMediaResource::CloneData(MediaDecoder* aDecoder)
if (NS_FAILED(rv))
return nullptr;
return new FileMediaResource(aDecoder, channel, mURI);
return new FileMediaResource(aDecoder, channel, mURI, GetContentType());
}
nsresult FileMediaResource::ReadFromCache(char* aBuffer, int64_t aOffset, uint32_t aCount)
@ -1581,11 +1587,14 @@ MediaResource::Create(MediaDecoder* aDecoder, nsIChannel* aChannel)
nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, nullptr);
nsAutoCString contentType;
aChannel->GetContentType(contentType);
nsCOMPtr<nsIFileChannel> fc = do_QueryInterface(aChannel);
if (fc || IsBlobURI(uri)) {
return new FileMediaResource(aDecoder, aChannel, uri);
return new FileMediaResource(aDecoder, aChannel, uri, contentType);
}
return new ChannelMediaResource(aDecoder, aChannel, uri);
return new ChannelMediaResource(aDecoder, aChannel, uri, contentType);
}
void BaseMediaResource::MoveLoadsToBackground() {

View File

@ -367,6 +367,11 @@ public:
// Notify that the last data byte range was loaded.
virtual void NotifyLastByteRange() { }
// Returns the content type of the resource. This is copied from the
// nsIChannel when the MediaResource is created. Safe to call from
// any thread.
virtual const nsACString& GetContentType() const = 0;
};
class BaseMediaResource : public MediaResource {
@ -375,19 +380,29 @@ public:
virtual void MoveLoadsToBackground();
protected:
BaseMediaResource(MediaDecoder* aDecoder, nsIChannel* aChannel, nsIURI* aURI) :
BaseMediaResource(MediaDecoder* aDecoder,
nsIChannel* aChannel,
nsIURI* aURI,
const nsACString& aContentType) :
mDecoder(aDecoder),
mChannel(aChannel),
mURI(aURI),
mContentType(aContentType),
mLoadInBackground(false)
{
MOZ_COUNT_CTOR(BaseMediaResource);
NS_ASSERTION(!mContentType.IsEmpty(), "Must know content type");
}
virtual ~BaseMediaResource()
{
MOZ_COUNT_DTOR(BaseMediaResource);
}
virtual const nsACString& GetContentType() const MOZ_OVERRIDE
{
return mContentType;
}
// Set the request's load flags to aFlags. If the request is part of a
// load group, the request is removed from the group, the flags are set, and
// then the request is added back to the load group.
@ -406,6 +421,11 @@ protected:
// main thread only.
nsCOMPtr<nsIURI> mURI;
// Content-Type of the channel. This is copied from the nsIChannel when the
// MediaResource is created. This is constant, so accessing from any thread
// is safe.
const nsAutoCString mContentType;
// True if MoveLoadsToBackground() has been called, i.e. the load event
// has been fired, and all channel loads will be in the background.
bool mLoadInBackground;
@ -422,7 +442,10 @@ protected:
class ChannelMediaResource : public BaseMediaResource
{
public:
ChannelMediaResource(MediaDecoder* aDecoder, nsIChannel* aChannel, nsIURI* aURI);
ChannelMediaResource(MediaDecoder* aDecoder,
nsIChannel* aChannel,
nsIURI* aURI,
const nsACString& aContentType);
~ChannelMediaResource();
// These are called on the main thread by MediaCache. These must

View File

@ -419,7 +419,7 @@ MediaDecodeTask::CreateReader()
BufferMediaResource* resource =
new BufferMediaResource(static_cast<uint8_t*> (mBuffer),
mLength, mPrincipal);
mLength, mPrincipal, mContentType);
MOZ_ASSERT(!mBufferDecoder);
mBufferDecoder = new BufferDecoder(resource);