--- a/dom/media/Benchmark.cpp
+++ b/dom/media/Benchmark.cpp
@@ -39,18 +39,19 @@ VP9Benchmark::IsVP9DecodeFast()
#else
bool hasPref = Preferences::HasUserValue(sBenchmarkFpsPref);
uint32_t hadRecentUpdate = Preferences::GetUint(sBenchmarkFpsVersionCheck, 0U);
if (!sHasRunTest && (!hasPref || hadRecentUpdate != sBenchmarkVersionID)) {
sHasRunTest = true;
RefPtr<WebMDemuxer> demuxer =
- new WebMDemuxer(new BufferMediaResource(sWebMSample, sizeof(sWebMSample), nullptr,
- NS_LITERAL_CSTRING("video/webm")));
+ new WebMDemuxer(
+ new BufferMediaResource(sWebMSample, sizeof(sWebMSample), nullptr,
+ MediaContainerType(MEDIAMIMETYPE("video/webm"))));
RefPtr<Benchmark> estimiser =
new Benchmark(demuxer,
{
Preferences::GetInt("media.benchmark.frames", 300), // frames to measure
1, // start benchmarking after decoding this frame.
8, // loop after decoding that many frames.
TimeDuration::FromMilliseconds(
Preferences::GetUint("media.benchmark.timeout", 1000))
--- a/dom/media/BufferMediaResource.h
+++ b/dom/media/BufferMediaResource.h
@@ -18,22 +18,22 @@ namespace mozilla {
// on top of it. The Read implementation involves copying memory, which is
// unfortunate, but the MediaResource interface mandates that.
class BufferMediaResource : public MediaResource
{
public:
BufferMediaResource(const uint8_t* aBuffer,
uint32_t aLength,
nsIPrincipal* aPrincipal,
- const nsACString& aContentType) :
+ const MediaContainerType& aContainerType) :
mBuffer(aBuffer),
mLength(aLength),
mOffset(0),
mPrincipal(aPrincipal),
- mContentType(aContentType)
+ mContainerType(aContainerType)
{
}
protected:
virtual ~BufferMediaResource()
{
}
@@ -100,40 +100,40 @@ private:
nsresult GetCachedRanges(MediaByteRangeSet& aRanges) override
{
aRanges += MediaByteRange(0, int64_t(mLength));
return NS_OK;
}
bool IsTransportSeekable() override { return true; }
- const nsCString& GetContentType() const override
+ const MediaContainerType& GetContentType() const override
{
- return mContentType;
+ return mContainerType;
}
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override
{
// Not owned:
// - mBuffer
// - mPrincipal
size_t size = MediaResource::SizeOfExcludingThis(aMallocSizeOf);
- size += mContentType.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
+ size += mContainerType.SizeOfExcludingThis(aMallocSizeOf);
return size;
}
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override
{
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
}
private:
const uint8_t * mBuffer;
uint32_t mLength;
uint32_t mOffset;
nsCOMPtr<nsIPrincipal> mPrincipal;
- const nsCString mContentType;
+ const MediaContainerType mContainerType;
};
} // namespace mozilla
#endif
--- a/dom/media/MediaDecoder.cpp
+++ b/dom/media/MediaDecoder.cpp
@@ -832,21 +832,18 @@ MediaDecoder::EnsureTelemetryReported()
nsTArray<nsCString> codecs;
if (mInfo->HasAudio() && !mInfo->mAudio.GetAsAudioInfo()->mMimeType.IsEmpty()) {
codecs.AppendElement(mInfo->mAudio.GetAsAudioInfo()->mMimeType);
}
if (mInfo->HasVideo() && !mInfo->mVideo.GetAsVideoInfo()->mMimeType.IsEmpty()) {
codecs.AppendElement(mInfo->mVideo.GetAsVideoInfo()->mMimeType);
}
if (codecs.IsEmpty()) {
- if (mResource->GetContentType().IsEmpty()) {
- NS_WARNING("Somehow the resource's content type is empty");
- return;
- }
- codecs.AppendElement(nsPrintfCString("resource; %s", mResource->GetContentType().get()));
+ codecs.AppendElement(nsPrintfCString("resource; %s",
+ mResource->GetContentType().OriginalString().Data()));
}
for (const nsCString& codec : codecs) {
DECODER_LOG("Telemetry MEDIA_CODEC_USED= '%s'", codec.get());
Telemetry::Accumulate(Telemetry::ID::MEDIA_CODEC_USED, codec);
}
mTelemetryReported = true;
}
--- a/dom/media/MediaResource.cpp
+++ b/dom/media/MediaResource.cpp
@@ -60,18 +60,18 @@ MediaResource::Destroy()
NS_IMPL_ADDREF(MediaResource)
NS_IMPL_RELEASE_WITH_DESTROY(MediaResource, Destroy())
NS_IMPL_QUERY_INTERFACE0(MediaResource)
ChannelMediaResource::ChannelMediaResource(MediaResourceCallback* aCallback,
nsIChannel* aChannel,
nsIURI* aURI,
- const nsACString& aContentType)
- : BaseMediaResource(aCallback, aChannel, aURI, aContentType),
+ const MediaContainerType& aContainerType)
+ : BaseMediaResource(aCallback, aChannel, aURI, aContainerType),
mOffset(0),
mReopenOnError(false),
mIgnoreClose(false),
mCacheStream(this),
mLock("ChannelMediaResource.mLock"),
mIgnoreResume(false),
mSuspendAgent(mChannel)
{
@@ -832,19 +832,17 @@ ChannelMediaResource::RecreateChannel()
nullptr, // aCallbacks
loadFlags);
NS_ENSURE_SUCCESS(rv, rv);
// 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.
- NS_ASSERTION(!GetContentType().IsEmpty(),
- "When recreating a channel, we should know the Content-Type.");
- mChannel->SetContentType(GetContentType());
+ mChannel->SetContentType(GetContentType().OriginalString());
mSuspendAgent.NotifyChannelOpened(mChannel);
// Tell the cache to reset the download status when the channel is reopened.
mCacheStream.NotifyChannelRecreated();
return rv;
}
@@ -1106,18 +1104,18 @@ ChannelSuspendAgent::IsSuspended()
// FileMediaResource
class FileMediaResource : public BaseMediaResource
{
public:
FileMediaResource(MediaResourceCallback* aCallback,
nsIChannel* aChannel,
nsIURI* aURI,
- const nsACString& aContentType) :
- BaseMediaResource(aCallback, aChannel, aURI, aContentType),
+ const MediaContainerType& aContainerType) :
+ BaseMediaResource(aCallback, aChannel, aURI, aContainerType),
mSize(-1),
mLock("FileMediaResource.mLock"),
mSizeInitialized(false)
{
}
~FileMediaResource()
{
}
@@ -1492,25 +1490,29 @@ MediaResource::Create(MediaResourceCallb
// If the channel was redirected, we want the post-redirect URI;
// but if the URI scheme was expanded, say from chrome: to jar:file:,
// we want the original URI.
nsCOMPtr<nsIURI> uri;
nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, nullptr);
- nsAutoCString contentType;
- aChannel->GetContentType(contentType);
+ nsAutoCString contentTypeString;
+ aChannel->GetContentType(contentTypeString);
+ Maybe<MediaContainerType> containerType = MakeMediaContainerType(contentTypeString);
+ if (!containerType) {
+ return nullptr;
+ }
nsCOMPtr<nsIFileChannel> fc = do_QueryInterface(aChannel);
RefPtr<MediaResource> resource;
if (fc || IsBlobURI(uri)) {
- resource = new FileMediaResource(aCallback, aChannel, uri, contentType);
+ resource = new FileMediaResource(aCallback, aChannel, uri, *containerType);
} else {
- resource = new ChannelMediaResource(aCallback, aChannel, uri, contentType);
+ resource = new ChannelMediaResource(aCallback, aChannel, uri, *containerType);
}
return resource.forget();
}
void BaseMediaResource::SetLoadInBackground(bool aLoadInBackground) {
if (aLoadInBackground == mLoadInBackground) {
return;
}
--- a/dom/media/MediaResource.h
+++ b/dom/media/MediaResource.h
@@ -11,16 +11,17 @@
#include "nsIURI.h"
#include "nsISeekableStream.h"
#include "nsIStreamingProtocolController.h"
#include "nsIStreamListener.h"
#include "nsIChannelEventSink.h"
#include "nsIInterfaceRequestor.h"
#include "Intervals.h"
#include "MediaCache.h"
+#include "MediaContainerType.h"
#include "MediaData.h"
#include "MediaResourceCallback.h"
#include "mozilla/Atomics.h"
#include "mozilla/Attributes.h"
#include "mozilla/TimeStamp.h"
#include "nsThreadUtils.h"
#include <algorithm>
@@ -332,20 +333,20 @@ public:
// Ensure that the media cache writes any data held in its partial block.
// Called on the main thread only.
virtual void FlushCache() { }
// Notify that the last data byte range was loaded.
virtual void NotifyLastByteRange() { }
- // Returns the content type of the resource. This is copied from the
+ // Returns the container content type of the resource. This is copied from the
// nsIChannel when the MediaResource is created. Safe to call from
// any thread.
- virtual const nsCString& GetContentType() const = 0;
+ virtual const MediaContainerType& GetContentType() const = 0;
// Return true if the stream is a live stream
virtual bool IsRealTime() {
return false;
}
// Returns true if the resource is a live stream.
virtual bool IsLiveStream()
@@ -378,17 +379,17 @@ public:
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override
{
// Might be useful to track in the future:
// - mChannel
// - mURI (possibly owned, looks like just a ref from mChannel)
// Not owned:
// - mCallback
size_t size = MediaResource::SizeOfExcludingThis(aMallocSizeOf);
- size += mContentType.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
+ size += mContainerType.SizeOfExcludingThis(aMallocSizeOf);
return size;
}
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override
{
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
}
@@ -398,33 +399,32 @@ public:
{
return mContentURL;
}
protected:
BaseMediaResource(MediaResourceCallback* aCallback,
nsIChannel* aChannel,
nsIURI* aURI,
- const nsACString& aContentType) :
+ const MediaContainerType& aContainerType) :
mCallback(aCallback),
mChannel(aChannel),
mURI(aURI),
- mContentType(aContentType),
+ mContainerType(aContainerType),
mLoadInBackground(false)
{
- NS_ASSERTION(!mContentType.IsEmpty(), "Must know content type");
mURI->GetSpec(mContentURL);
}
virtual ~BaseMediaResource()
{
}
- const nsCString& GetContentType() const override
+ const MediaContainerType& GetContentType() const override
{
- return mContentType;
+ return mContainerType;
}
// 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.
void ModifyLoadFlags(nsLoadFlags aFlags);
// Dispatches an event to call MediaDecoder::NotifyBytesConsumed(aNumBytes, aOffset)
@@ -439,17 +439,17 @@ protected:
// URI in case the stream needs to be re-opened. Access from
// 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 nsCString mContentType;
+ const MediaContainerType mContainerType;
// Copy of the url of the channel resource.
nsCString mContentURL;
// True if SetLoadInBackground() has been called with
// aLoadInBackground = true, i.e. when the document load event is not
// blocked by this resource, and all channel loads will be in the
// background.
@@ -506,17 +506,17 @@ private:
* thread operations are delegated directly to that object.
*/
class ChannelMediaResource : public BaseMediaResource
{
public:
ChannelMediaResource(MediaResourceCallback* aDecoder,
nsIChannel* aChannel,
nsIURI* aURI,
- const nsACString& aContentType);
+ const MediaContainerType& aContainerType);
~ChannelMediaResource();
// These are called on the main thread by MediaCache. These must
// not block or grab locks, because the media cache is holding its lock.
// Notify that data is available from the cache. This can happen even
// if this stream didn't read any data, since another stream might have
// received data for the same resource.
void CacheClientNotifyDataReceived();
--- a/dom/media/gtest/MockMediaResource.cpp
+++ b/dom/media/gtest/MockMediaResource.cpp
@@ -5,20 +5,21 @@
#include "MockMediaResource.h"
#include <sys/types.h>
#include <sys/stat.h>
namespace mozilla
{
-MockMediaResource::MockMediaResource(const char* aFileName, const nsACString& aContentType)
+MockMediaResource::MockMediaResource(const char* aFileName,
+ const MediaContainerType& aContainerType)
: mFileHandle(nullptr)
, mFileName(aFileName)
- , mContentType(aContentType)
+ , mContainerType(aContainerType)
{
}
nsresult
MockMediaResource::Open(nsIStreamListener** aStreamListener)
{
mFileHandle = fopen(mFileName, "rb");
if (mFileHandle == nullptr) {
--- a/dom/media/gtest/MockMediaResource.h
+++ b/dom/media/gtest/MockMediaResource.h
@@ -10,17 +10,19 @@
#include "mozilla/Atomics.h"
namespace mozilla
{
class MockMediaResource : public MediaResource
{
public:
- explicit MockMediaResource(const char* aFileName, const nsACString& aMimeType = NS_LITERAL_CSTRING("video/mp4"));
+ explicit MockMediaResource(const char* aFileName,
+ const MediaContainerType& aMimeType =
+ MediaContainerType(MEDIAMIMETYPE("video/mp4")));
nsIURI* URI() const override { return nullptr; }
nsresult Close() override { return NS_OK; }
void Suspend(bool aCloseImmediately) override {}
void Resume() override {}
already_AddRefed<nsIPrincipal> GetCurrentPrincipal() override
{
return nullptr;
}
@@ -54,30 +56,30 @@ public:
nsresult rv = ReadAt(aOffset, aBuffer, aCount, &bytesRead);
NS_ENSURE_SUCCESS(rv, rv);
return bytesRead == aCount ? NS_OK : NS_ERROR_FAILURE;
}
bool IsTransportSeekable() override { return true; }
nsresult Open(nsIStreamListener** aStreamListener) override;
nsresult GetCachedRanges(MediaByteRangeSet& aRanges) override;
- const nsCString& GetContentType() const override
+ const MediaContainerType& GetContentType() const override
{
- return mContentType;
+ return mContainerType;
}
void MockClearBufferedRanges();
void MockAddBufferedRange(int64_t aStart, int64_t aEnd);
protected:
virtual ~MockMediaResource();
private:
FILE* mFileHandle;
const char* mFileName;
MediaByteRangeSet mRanges;
Atomic<int> mEntry;
- const nsCString mContentType;
+ const MediaContainerType mContainerType;
};
} // namespace mozilla
#endif
--- a/dom/media/gtest/TestMediaDataDecoder.cpp
+++ b/dom/media/gtest/TestMediaDataDecoder.cpp
@@ -46,31 +46,31 @@ private:
TEST(MediaDataDecoder, H264)
{
if (!DecoderTraits::IsMP4SupportedType(
MediaContainerType(MEDIAMIMETYPE("video/mp4")),
/* DecoderDoctorDiagnostics* */ nullptr)) {
EXPECT_TRUE(true);
} else {
RefPtr<MediaResource> resource =
- new MockMediaResource("gizmo.mp4", NS_LITERAL_CSTRING("video/mp4"));
+ new MockMediaResource("gizmo.mp4", MediaContainerType(MEDIAMIMETYPE("video/mp4")));
nsresult rv = resource->Open(nullptr);
EXPECT_TRUE(NS_SUCCEEDED(rv));
BenchmarkRunner runner(new Benchmark(new MP4Demuxer(resource)));
EXPECT_GT(runner.Run(), 0u);
}
}
TEST(MediaDataDecoder, VP9)
{
if (!WebMDecoder::IsSupportedType(MediaContainerType(MEDIAMIMETYPE("video/webm")))) {
EXPECT_TRUE(true);
} else {
RefPtr<MediaResource> resource =
- new MockMediaResource("vp9cake.webm", NS_LITERAL_CSTRING("video/webm"));
+ new MockMediaResource("vp9cake.webm", MediaContainerType(MEDIAMIMETYPE("video/webm")));
nsresult rv = resource->Open(nullptr);
EXPECT_TRUE(NS_SUCCEEDED(rv));
BenchmarkRunner runner(new Benchmark(new WebMDemuxer(resource)));
EXPECT_GT(runner.Run(), 0u);
}
}
--- a/dom/media/mediasource/ContainerParser.cpp
+++ b/dom/media/mediasource/ContainerParser.cpp
@@ -21,22 +21,22 @@
#include "nsAutoPtr.h"
#include "SourceBufferResource.h"
#include <algorithm>
extern mozilla::LogModule* GetMediaSourceSamplesLog();
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
-#define MSE_DEBUG(name, arg, ...) MOZ_LOG(GetMediaSourceSamplesLog(), mozilla::LogLevel::Debug, (TOSTRING(name) "(%p:%s)::%s: " arg, this, mType.get(), __func__, ##__VA_ARGS__))
-#define MSE_DEBUGV(name, arg, ...) MOZ_LOG(GetMediaSourceSamplesLog(), mozilla::LogLevel::Verbose, (TOSTRING(name) "(%p:%s)::%s: " arg, this, mType.get(), __func__, ##__VA_ARGS__))
+#define MSE_DEBUG(name, arg, ...) MOZ_LOG(GetMediaSourceSamplesLog(), mozilla::LogLevel::Debug, (TOSTRING(name) "(%p:%s)::%s: " arg, this, mType.OriginalString().Data(), __func__, ##__VA_ARGS__))
+#define MSE_DEBUGV(name, arg, ...) MOZ_LOG(GetMediaSourceSamplesLog(), mozilla::LogLevel::Verbose, (TOSTRING(name) "(%p:%s)::%s: " arg, this, mType.OriginalString().Data(), __func__, ##__VA_ARGS__))
namespace mozilla {
-ContainerParser::ContainerParser(const nsACString& aType)
+ContainerParser::ContainerParser(const MediaContainerType& aType)
: mHasInitData(false)
, mType(aType)
{
}
ContainerParser::~ContainerParser() = default;
MediaResult
@@ -110,17 +110,17 @@ ContainerParser::MediaHeaderRange()
MediaByteRange
ContainerParser::MediaSegmentRange()
{
return mCompleteMediaSegmentRange;
}
class WebMContainerParser : public ContainerParser {
public:
- explicit WebMContainerParser(const nsACString& aType)
+ explicit WebMContainerParser(const MediaContainerType& aType)
: ContainerParser(aType)
, mParser(0)
, mOffset(0)
{}
static const unsigned NS_PER_USEC = 1000;
static const unsigned USEC_PER_SEC = 1000000;
@@ -200,17 +200,18 @@ public:
return NS_ERROR_NOT_AVAILABLE;
}
if (initSegment) {
mOffset = 0;
mParser = WebMBufferedParser(0);
mOverlappedMapping.Clear();
mInitData = new MediaByteBuffer();
- mResource = new SourceBufferResource(NS_LITERAL_CSTRING("video/webm"));
+ mResource = new SourceBufferResource(
+ MediaContainerType(MEDIAMIMETYPE("video/webm")));
mCompleteMediaHeaderRange = MediaByteRange();
mCompleteMediaSegmentRange = MediaByteRange();
}
// XXX if it only adds new mappings, overlapped but not available
// (e.g. overlap < 0) frames are "lost" from the reported mappings here.
nsTArray<WebMTimeDataOffset> mapping;
mapping.AppendElements(mOverlappedMapping);
@@ -334,17 +335,17 @@ private:
nsTArray<WebMTimeDataOffset> mOverlappedMapping;
int64_t mOffset;
Maybe<WebMTimeDataOffset> mLastMapping;
};
#ifdef MOZ_FMP4
class MP4ContainerParser : public ContainerParser {
public:
- explicit MP4ContainerParser(const nsACString& aType)
+ explicit MP4ContainerParser(const MediaContainerType& aType)
: ContainerParser(aType)
{}
MediaResult IsInitSegmentPresent(MediaByteBuffer* aData) override
{
ContainerParser::IsInitSegmentPresent(aData);
// Each MP4 atom has a chunk size and chunk type. The root chunk in an MP4
// file is the 'ftyp' atom followed by a file type. We just check for a
@@ -373,19 +374,19 @@ public:
RESULT_DETAIL("Invalid Box:%s", parser.LastInvalidBox()));
}
return parser.StartWithMediaSegment() ? NS_OK : NS_ERROR_NOT_AVAILABLE;
}
private:
class AtomParser {
public:
- AtomParser(const nsACString& aType, const MediaByteBuffer* aData)
+ AtomParser(const MediaContainerType& aType, const MediaByteBuffer* aData)
{
- const nsCString mType(aType); // for logging macro.
+ const MediaContainerType mType(aType); // for logging macro.
mp4_demuxer::ByteReader reader(aData);
mp4_demuxer::AtomType initAtom("ftyp");
mp4_demuxer::AtomType mediaAtom("moof");
// Valid top-level boxes defined in ISO/IEC 14496-12 (Table 1)
static const mp4_demuxer::AtomType validBoxes[] = {
"ftyp", "moov", // init segment
"pdin", "free", "sidx", // optional prior moov box
@@ -466,17 +467,18 @@ private:
public:
MediaResult ParseStartAndEndTimestamps(MediaByteBuffer* aData,
int64_t& aStart,
int64_t& aEnd) override
{
bool initSegment = NS_SUCCEEDED(IsInitSegmentPresent(aData));
if (initSegment) {
- mResource = new SourceBufferResource(NS_LITERAL_CSTRING("video/mp4"));
+ mResource = new SourceBufferResource(
+ MediaContainerType(MEDIAMIMETYPE("video/mp4")));
mStream = new MP4Stream(mResource);
// We use a timestampOffset of 0 for ContainerParser, and require
// consumers of ParseStartAndEndTimestamps to add their timestamp offset
// manually. This allows the ContainerParser to be shared across different
// timestampOffsets.
mParser = new mp4_demuxer::MoofParser(mStream, 0, /* aIsAudio = */ false);
mInitData = new MediaByteBuffer();
} else if (!mStream || !mParser) {
@@ -542,17 +544,17 @@ private:
RefPtr<MP4Stream> mStream;
nsAutoPtr<mp4_demuxer::MoofParser> mParser;
};
#endif // MOZ_FMP4
#ifdef MOZ_FMP4
class ADTSContainerParser : public ContainerParser {
public:
- explicit ADTSContainerParser(const nsACString& aType)
+ explicit ADTSContainerParser(const MediaContainerType& aType)
: ContainerParser(aType)
{}
typedef struct {
size_t header_length; // Length of just the initialization data.
size_t frame_length; // Includes header_length;
uint8_t aac_frames; // Number of AAC frames in the ADTS frame.
bool have_crc;
@@ -687,27 +689,29 @@ public:
int64_t GetRoundingError() override
{
return 0;
}
};
#endif // MOZ_FMP4
/*static*/ ContainerParser*
-ContainerParser::CreateForMIMEType(const nsACString& aType)
+ContainerParser::CreateForMIMEType(const MediaContainerType& aType)
{
- if (aType.LowerCaseEqualsLiteral("video/webm") || aType.LowerCaseEqualsLiteral("audio/webm")) {
+ if (aType.Type() == MEDIAMIMETYPE("video/webm")
+ || aType.Type() == MEDIAMIMETYPE("audio/webm")) {
return new WebMContainerParser(aType);
}
#ifdef MOZ_FMP4
- if (aType.LowerCaseEqualsLiteral("video/mp4") || aType.LowerCaseEqualsLiteral("audio/mp4")) {
+ if (aType.Type() == MEDIAMIMETYPE("video/mp4")
+ || aType.Type() == MEDIAMIMETYPE("audio/mp4")) {
return new MP4ContainerParser(aType);
}
- if (aType.LowerCaseEqualsLiteral("audio/aac")) {
+ if (aType.Type() == MEDIAMIMETYPE("audio/aac")) {
return new ADTSContainerParser(aType);
}
#endif
return new ContainerParser(aType);
}
#undef MSE_DEBUG
--- a/dom/media/mediasource/ContainerParser.h
+++ b/dom/media/mediasource/ContainerParser.h
@@ -3,28 +3,28 @@
/* 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/. */
#ifndef MOZILLA_CONTAINERPARSER_H_
#define MOZILLA_CONTAINERPARSER_H_
#include "mozilla/RefPtr.h"
-#include "nsString.h"
+#include "MediaContainerType.h"
#include "MediaResource.h"
#include "MediaResult.h"
namespace mozilla {
class MediaByteBuffer;
class SourceBufferResource;
class ContainerParser {
public:
- explicit ContainerParser(const nsACString& aType);
+ explicit ContainerParser(const MediaContainerType& aType);
virtual ~ContainerParser();
// Return true if aData starts with an initialization segment.
// The base implementation exists only for debug logging and is expected
// to be called first from the overriding implementation.
// Return NS_OK if segment is present, NS_ERROR_NOT_AVAILABLE if no sufficient
// data is currently available to make a determination. Any other value
// indicates an error.
@@ -68,23 +68,23 @@ public:
MediaByteRange InitSegmentRange();
// Returns the byte range of the first complete media segment header,
// or an empty range if not complete.
MediaByteRange MediaHeaderRange();
// Returns the byte range of the first complete media segment or an empty
// range if not complete.
MediaByteRange MediaSegmentRange();
- static ContainerParser* CreateForMIMEType(const nsACString& aType);
+ static ContainerParser* CreateForMIMEType(const MediaContainerType& aType);
protected:
RefPtr<MediaByteBuffer> mInitData;
RefPtr<SourceBufferResource> mResource;
bool mHasInitData;
MediaByteRange mCompleteInitSegmentRange;
MediaByteRange mCompleteMediaHeaderRange;
MediaByteRange mCompleteMediaSegmentRange;
- const nsCString mType;
+ const MediaContainerType mType;
};
} // namespace mozilla
#endif /* MOZILLA_CONTAINERPARSER_H_ */
--- a/dom/media/mediasource/MediaSource.cpp
+++ b/dom/media/mediasource/MediaSource.cpp
@@ -238,18 +238,17 @@ MediaSource::AddSourceBuffer(const nsASt
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return nullptr;
}
Maybe<MediaContainerType> containerType = MakeMediaContainerType(aType);
if (!containerType) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return nullptr;
}
- const nsACString& mimeType = containerType->Type().AsString();
- RefPtr<SourceBuffer> sourceBuffer = new SourceBuffer(this, mimeType);
+ RefPtr<SourceBuffer> sourceBuffer = new SourceBuffer(this, *containerType);
if (!sourceBuffer) {
aRv.Throw(NS_ERROR_FAILURE); // XXX need a better error here
return nullptr;
}
mSourceBuffers->Append(sourceBuffer);
MSE_DEBUG("sourceBuffer=%p", sourceBuffer.get());
return sourceBuffer.forget();
}
--- a/dom/media/mediasource/MediaSourceResource.h
+++ b/dom/media/mediasource/MediaSourceResource.h
@@ -8,27 +8,29 @@
#define MOZILLA_MEDIASOURCERESOURCE_H_
#include "MediaResource.h"
#include "mozilla/Monitor.h"
#include "mozilla/Logging.h"
extern mozilla::LogModule* GetMediaSourceLog();
-#define MSE_DEBUG(arg, ...) MOZ_LOG(GetMediaSourceLog(), mozilla::LogLevel::Debug, ("MediaSourceResource(%p:%s)::%s: " arg, this, mType.get(), __func__, ##__VA_ARGS__))
+#define MSE_DEBUG(arg, ...) MOZ_LOG(GetMediaSourceLog(), mozilla::LogLevel::Debug, ("MediaSourceResource(%p:%s)::%s: " arg, this, mType.OriginalString().Data(), __func__, ##__VA_ARGS__))
#define UNIMPLEMENTED() MSE_DEBUG("UNIMPLEMENTED FUNCTION at %s:%d", __FILE__, __LINE__)
namespace mozilla {
class MediaSourceResource final : public MediaResource
{
public:
explicit MediaSourceResource(nsIPrincipal* aPrincipal = nullptr)
: mPrincipal(aPrincipal)
+ // Fake-but-valid MIME type, unused but necessary to implement GetContentType().
+ , mType(MEDIAMIMETYPE("application/x.mediasource"))
, mMonitor("MediaSourceResource")
, mEnded(false)
{}
nsresult Close() override { return NS_OK; }
void Suspend(bool aCloseImmediately) override { UNIMPLEMENTED(); }
void Resume() override { UNIMPLEMENTED(); }
bool CanClone() override { UNIMPLEMENTED(); return false; }
@@ -57,17 +59,17 @@ public:
nsresult GetCachedRanges(MediaByteRangeSet& aRanges) override
{
UNIMPLEMENTED();
aRanges += MediaByteRange(0, GetLength());
return NS_OK;
}
bool IsTransportSeekable() override { return true; }
- const nsCString& GetContentType() const override { return mType; }
+ const MediaContainerType& GetContentType() const override { return mType; }
bool IsLiveStream() override
{
MonitorAutoLock mon(mMonitor);
return !mEnded;
}
void SetEnded(bool aEnded)
{
@@ -80,28 +82,28 @@ public:
MonitorAutoLock mon(mMonitor);
return !mEnded;
}
private:
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override
{
size_t size = MediaResource::SizeOfExcludingThis(aMallocSizeOf);
- size += mType.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
+ size += mType.SizeOfExcludingThis(aMallocSizeOf);
return size;
}
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override
{
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
}
RefPtr<nsIPrincipal> mPrincipal;
- const nsCString mType;
+ const MediaContainerType mType;
Monitor mMonitor;
bool mEnded; // protected by mMonitor
};
} // namespace mozilla
#undef MSE_DEBUG
#undef UNIMPLEMENTED
--- a/dom/media/mediasource/SourceBuffer.cpp
+++ b/dom/media/mediasource/SourceBuffer.cpp
@@ -30,19 +30,19 @@
#endif
struct JSContext;
class JSObject;
extern mozilla::LogModule* GetMediaSourceLog();
extern mozilla::LogModule* GetMediaSourceAPILog();
-#define MSE_DEBUG(arg, ...) MOZ_LOG(GetMediaSourceLog(), mozilla::LogLevel::Debug, ("SourceBuffer(%p:%s)::%s: " arg, this, mType.get(), __func__, ##__VA_ARGS__))
-#define MSE_DEBUGV(arg, ...) MOZ_LOG(GetMediaSourceLog(), mozilla::LogLevel::Verbose, ("SourceBuffer(%p:%s)::%s: " arg, this, mType.get(), __func__, ##__VA_ARGS__))
-#define MSE_API(arg, ...) MOZ_LOG(GetMediaSourceAPILog(), mozilla::LogLevel::Debug, ("SourceBuffer(%p:%s)::%s: " arg, this, mType.get(), __func__, ##__VA_ARGS__))
+#define MSE_DEBUG(arg, ...) MOZ_LOG(GetMediaSourceLog(), mozilla::LogLevel::Debug, ("SourceBuffer(%p:%s)::%s: " arg, this, mType.OriginalString().Data(), __func__, ##__VA_ARGS__))
+#define MSE_DEBUGV(arg, ...) MOZ_LOG(GetMediaSourceLog(), mozilla::LogLevel::Verbose, ("SourceBuffer(%p:%s)::%s: " arg, this, mType.OriginalString().Data(), __func__, ##__VA_ARGS__))
+#define MSE_API(arg, ...) MOZ_LOG(GetMediaSourceAPILog(), mozilla::LogLevel::Debug, ("SourceBuffer(%p:%s)::%s: " arg, this, mType.OriginalString().Data(), __func__, ##__VA_ARGS__))
namespace mozilla {
using media::TimeUnit;
typedef SourceBufferAttributes::AppendState AppendState;
namespace dom {
@@ -292,21 +292,22 @@ void
SourceBuffer::Ended()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(IsAttached());
MSE_DEBUG("Ended");
mTrackBuffersManager->Ended();
}
-SourceBuffer::SourceBuffer(MediaSource* aMediaSource, const nsACString& aType)
+SourceBuffer::SourceBuffer(MediaSource* aMediaSource,
+ const MediaContainerType& aType)
: DOMEventTargetHelper(aMediaSource->GetParentObject())
, mMediaSource(aMediaSource)
- , mCurrentAttributes(aType.LowerCaseEqualsLiteral("audio/mpeg") ||
- aType.LowerCaseEqualsLiteral("audio/aac"))
+ , mCurrentAttributes(aType.Type() == MEDIAMIMETYPE("audio/mpeg") ||
+ aType.Type() == MEDIAMIMETYPE("audio/aac"))
, mUpdating(false)
, mActive(false)
, mType(aType)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aMediaSource);
mTrackBuffersManager =
--- a/dom/media/mediasource/SourceBuffer.h
+++ b/dom/media/mediasource/SourceBuffer.h
@@ -3,31 +3,31 @@
/* 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/. */
#ifndef mozilla_dom_SourceBuffer_h_
#define mozilla_dom_SourceBuffer_h_
#include "mozilla/MozPromise.h"
+#include "MediaContainerType.h"
#include "MediaSource.h"
#include "js/RootingAPI.h"
#include "mozilla/Assertions.h"
#include "mozilla/Atomics.h"
#include "mozilla/Attributes.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/dom/SourceBufferBinding.h"
#include "mozilla/dom/TypedArray.h"
#include "mozilla/mozalloc.h"
#include "nsCOMPtr.h"
#include "nsCycleCollectionNoteChild.h"
#include "nsCycleCollectionParticipant.h"
#include "nsISupports.h"
-#include "nsString.h"
#include "nscore.h"
#include "TrackBuffersManager.h"
#include "SourceBufferTask.h"
class JSObject;
struct JSContext;
namespace mozilla {
@@ -94,17 +94,17 @@ public:
IMPL_EVENT_HANDLER(error);
IMPL_EVENT_HANDLER(abort);
/** End WebIDL Methods. */
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(SourceBuffer, DOMEventTargetHelper)
- SourceBuffer(MediaSource* aMediaSource, const nsACString& aType);
+ SourceBuffer(MediaSource* aMediaSource, const MediaContainerType& aType);
MediaSource* GetParentObject() const;
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
// Notify the SourceBuffer that it has been detached from the
// MediaSource's sourceBuffer list.
void Detach();
@@ -172,17 +172,17 @@ private:
SourceBufferAttributes mCurrentAttributes;
bool mUpdating;
mozilla::Atomic<bool> mActive;
MozPromiseRequestHolder<SourceBufferTask::AppendPromise> mPendingAppend;
MozPromiseRequestHolder<SourceBufferTask::RangeRemovalPromise> mPendingRemoval;
- const nsCString mType;
+ const MediaContainerType mType;
RefPtr<TimeRanges> mBuffered;
};
} // namespace dom
} // namespace mozilla
--- a/dom/media/mediasource/SourceBufferResource.cpp
+++ b/dom/media/mediasource/SourceBufferResource.cpp
@@ -14,18 +14,18 @@
#include "MediaData.h"
mozilla::LogModule* GetSourceBufferResourceLog()
{
static mozilla::LazyLogModule sLogModule("SourceBufferResource");
return sLogModule;
}
-#define SBR_DEBUG(arg, ...) MOZ_LOG(GetSourceBufferResourceLog(), mozilla::LogLevel::Debug, ("SourceBufferResource(%p:%s)::%s: " arg, this, mType.get(), __func__, ##__VA_ARGS__))
-#define SBR_DEBUGV(arg, ...) MOZ_LOG(GetSourceBufferResourceLog(), mozilla::LogLevel::Verbose, ("SourceBufferResource(%p:%s)::%s: " arg, this, mType.get(), __func__, ##__VA_ARGS__))
+#define SBR_DEBUG(arg, ...) MOZ_LOG(GetSourceBufferResourceLog(), mozilla::LogLevel::Debug, ("SourceBufferResource(%p:%s)::%s: " arg, this, mType.OriginalString().Data(), __func__, ##__VA_ARGS__))
+#define SBR_DEBUGV(arg, ...) MOZ_LOG(GetSourceBufferResourceLog(), mozilla::LogLevel::Verbose, ("SourceBufferResource(%p:%s)::%s: " arg, this, mType.OriginalString().Data(), __func__, ##__VA_ARGS__))
namespace mozilla {
nsresult
SourceBufferResource::Close()
{
ReentrantMonitorAutoEnter mon(mMonitor);
SBR_DEBUG("Close");
@@ -163,17 +163,17 @@ SourceBufferResource::Ended()
mon.NotifyAll();
}
SourceBufferResource::~SourceBufferResource()
{
SBR_DEBUG("");
}
-SourceBufferResource::SourceBufferResource(const nsACString& aType)
+SourceBufferResource::SourceBufferResource(const MediaContainerType& aType)
: mType(aType)
, mMonitor("mozilla::SourceBufferResource::mMonitor")
, mOffset(0)
, mClosed(false)
, mEnded(false)
{
SBR_DEBUG("");
}
--- a/dom/media/mediasource/SourceBufferResource.h
+++ b/dom/media/mediasource/SourceBufferResource.h
@@ -10,17 +10,16 @@
#include "MediaCache.h"
#include "MediaResource.h"
#include "ResourceQueue.h"
#include "mozilla/Attributes.h"
#include "mozilla/ReentrantMonitor.h"
#include "nsCOMPtr.h"
#include "nsError.h"
#include "nsIPrincipal.h"
-#include "nsString.h"
#include "nsTArray.h"
#include "nscore.h"
#include "mozilla/Logging.h"
#define UNIMPLEMENTED() { /* Logging this is too spammy to do by default */ }
class nsIStreamListener;
@@ -33,17 +32,17 @@ namespace dom {
class SourceBuffer;
} // namespace dom
class SourceBufferResource final : public MediaResource
{
public:
- explicit SourceBufferResource(const nsACString& aType);
+ explicit SourceBufferResource(const MediaContainerType& aType);
nsresult Close() override;
void Suspend(bool aCloseImmediately) override { UNIMPLEMENTED(); }
void Resume() override { UNIMPLEMENTED(); }
already_AddRefed<nsIPrincipal> GetCurrentPrincipal() override { UNIMPLEMENTED(); return nullptr; }
already_AddRefed<MediaResource> CloneData(MediaResourceCallback*) override { UNIMPLEMENTED(); return nullptr; }
void SetReadMode(MediaCacheStream::ReadMode aMode) override { UNIMPLEMENTED(); }
void SetPlaybackRate(uint32_t aBytesPerSecond) override { UNIMPLEMENTED(); }
nsresult ReadAt(int64_t aOffset, char* aBuffer, uint32_t aCount, uint32_t* aBytes) override;
@@ -75,24 +74,24 @@ public:
ReentrantMonitorAutoEnter mon(mMonitor);
if (mInputBuffer.GetLength()) {
aRanges += MediaByteRange(mInputBuffer.GetOffset(),
mInputBuffer.GetLength());
}
return NS_OK;
}
- const nsCString& GetContentType() const override { return mType; }
+ const MediaContainerType& GetContentType() const override { return mType; }
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override
{
ReentrantMonitorAutoEnter mon(mMonitor);
size_t size = MediaResource::SizeOfExcludingThis(aMallocSizeOf);
- size += mType.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
+ size += mType.SizeOfExcludingThis(aMallocSizeOf);
size += mInputBuffer.SizeOfExcludingThis(aMallocSizeOf);
return size;
}
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override
{
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
@@ -133,17 +132,17 @@ public:
mInputBuffer.Dump(aPath);
}
#endif
private:
virtual ~SourceBufferResource();
nsresult ReadAtInternal(int64_t aOffset, char* aBuffer, uint32_t aCount, uint32_t* aBytes, bool aMayBlock);
- const nsCString mType;
+ const MediaContainerType mType;
// Provides synchronization between SourceBuffers and InputAdapters.
// Protects all of the member variables below. Read() will await a
// Notify() (from Seek, AppendData, Ended, or Close) when insufficient
// data is available in mData.
mutable ReentrantMonitor mMonitor;
// The buffer holding resource data.
--- a/dom/media/mediasource/TrackBuffersManager.cpp
+++ b/dom/media/mediasource/TrackBuffersManager.cpp
@@ -18,25 +18,25 @@
#ifdef MOZ_FMP4
#include "MP4Demuxer.h"
#endif
#include <limits>
extern mozilla::LogModule* GetMediaSourceLog();
-#define MSE_DEBUG(arg, ...) MOZ_LOG(GetMediaSourceLog(), mozilla::LogLevel::Debug, ("TrackBuffersManager(%p:%s)::%s: " arg, this, mType.get(), __func__, ##__VA_ARGS__))
-#define MSE_DEBUGV(arg, ...) MOZ_LOG(GetMediaSourceLog(), mozilla::LogLevel::Verbose, ("TrackBuffersManager(%p:%s)::%s: " arg, this, mType.get(), __func__, ##__VA_ARGS__))
+#define MSE_DEBUG(arg, ...) MOZ_LOG(GetMediaSourceLog(), mozilla::LogLevel::Debug, ("TrackBuffersManager(%p:%s)::%s: " arg, this, mType.OriginalString().Data(), __func__, ##__VA_ARGS__))
+#define MSE_DEBUGV(arg, ...) MOZ_LOG(GetMediaSourceLog(), mozilla::LogLevel::Verbose, ("TrackBuffersManager(%p:%s)::%s: " arg, this, mType.OriginalString().Data(), __func__, ##__VA_ARGS__))
mozilla::LogModule* GetMediaSourceSamplesLog()
{
static mozilla::LazyLogModule sLogModule("MediaSourceSamples");
return sLogModule;
}
-#define SAMPLE_DEBUG(arg, ...) MOZ_LOG(GetMediaSourceSamplesLog(), mozilla::LogLevel::Debug, ("TrackBuffersManager(%p:%s)::%s: " arg, this, mType.get(), __func__, ##__VA_ARGS__))
+#define SAMPLE_DEBUG(arg, ...) MOZ_LOG(GetMediaSourceSamplesLog(), mozilla::LogLevel::Debug, ("TrackBuffersManager(%p:%s)::%s: " arg, this, mType.OriginalString().Data(), __func__, ##__VA_ARGS__))
namespace mozilla {
using dom::SourceBufferAppendMode;
using media::TimeUnit;
using media::TimeInterval;
using media::TimeIntervals;
typedef SourceBufferTask::AppendBufferResult AppendBufferResult;
@@ -80,17 +80,17 @@ public:
}
private:
RefPtr<AbstractMediaDecoder> mDecoder;
nsTArray<uint8_t> mInitData;
nsString mInitDataType;
};
TrackBuffersManager::TrackBuffersManager(MediaSourceDecoder* aParentDecoder,
- const nsACString& aType)
+ const MediaContainerType& aType)
: mInputBuffer(new MediaByteBuffer)
, mBufferFull(false)
, mFirstInitializationSegmentReceived(false)
, mNewMediaSegmentStarted(false)
, mActiveTrack(false)
, mType(aType)
, mParser(ContainerParser::CreateForMIMEType(aType))
, mProcessedInput(0)
@@ -805,25 +805,25 @@ TrackBuffersManager::ShutdownDemuxers()
mLastParsedEndTime.reset();
}
void
TrackBuffersManager::CreateDemuxerforMIMEType()
{
ShutdownDemuxers();
- if (mType.LowerCaseEqualsLiteral("video/webm") ||
- mType.LowerCaseEqualsLiteral("audio/webm")) {
+ if (mType.Type() == MEDIAMIMETYPE("video/webm") ||
+ mType.Type() == MEDIAMIMETYPE("audio/webm")) {
mInputDemuxer = new WebMDemuxer(mCurrentInputBuffer, true /* IsMediaSource*/ );
return;
}
#ifdef MOZ_FMP4
- if (mType.LowerCaseEqualsLiteral("video/mp4") ||
- mType.LowerCaseEqualsLiteral("audio/mp4")) {
+ if (mType.Type() == MEDIAMIMETYPE("video/mp4")
+ || mType.Type() == MEDIAMIMETYPE("audio/mp4")) {
mInputDemuxer = new MP4Demuxer(mCurrentInputBuffer);
return;
}
#endif
NS_WARNING("Not supported (yet)");
return;
}
@@ -1693,18 +1693,18 @@ TrackBuffersManager::InsertFrames(TrackB
// 15. Remove decoding dependencies of the coded frames removed in the previous step:
// Remove all coded frames between the coded frames removed in the previous step and the next random access point after those removed frames.
TimeIntervals intersection = trackBuffer.mBufferedRanges;
intersection.Intersection(aIntervals);
if (intersection.Length()) {
if (aSamples[0]->mKeyframe &&
- (mType.LowerCaseEqualsLiteral("video/webm") ||
- mType.LowerCaseEqualsLiteral("audio/webm"))) {
+ (mType.Type() == MEDIAMIMETYPE("video/webm")
+ || mType.Type() == MEDIAMIMETYPE("audio/webm"))) {
// We are starting a new GOP, we do not have to worry about breaking an
// existing current coded frame group. Reset the next insertion index
// so the search for when to start our frames removal can be exhaustive.
// This is a workaround for bug 1276184 and only until either bug 1277733
// or bug 1209386 is fixed.
// With the webm container, we can't always properly determine the
// duration of the last frame, which may cause the last frame of a cluster
// to overlap the following frame.
--- a/dom/media/mediasource/TrackBuffersManager.h
+++ b/dom/media/mediasource/TrackBuffersManager.h
@@ -8,25 +8,25 @@
#define MOZILLA_TRACKBUFFERSMANAGER_H_
#include "mozilla/Atomics.h"
#include "mozilla/Maybe.h"
#include "mozilla/Monitor.h"
#include "AutoTaskQueue.h"
#include "mozilla/dom/SourceBufferBinding.h"
+#include "MediaContainerType.h"
#include "MediaData.h"
#include "MediaDataDemuxer.h"
#include "MediaResult.h"
#include "MediaSourceDecoder.h"
#include "SourceBufferTask.h"
#include "TimeUnits.h"
#include "nsAutoPtr.h"
#include "nsProxyRelease.h"
-#include "nsString.h"
#include "nsTArray.h"
namespace mozilla {
class ContainerParser;
class MediaByteBuffer;
class MediaRawData;
class MediaSourceDemuxer;
@@ -86,17 +86,17 @@ public:
typedef TrackInfo::TrackType TrackType;
typedef MediaData::Type MediaType;
typedef nsTArray<RefPtr<MediaRawData>> TrackBuffer;
typedef SourceBufferTask::AppendPromise AppendPromise;
typedef SourceBufferTask::RangeRemovalPromise RangeRemovalPromise;
// Interface for SourceBuffer
TrackBuffersManager(MediaSourceDecoder* aParentDecoder,
- const nsACString& aType);
+ const MediaContainerType& aType);
// Queue a task to add data to the end of the input buffer and run the MSE
// Buffer Append Algorithm
// 3.5.5 Buffer Append Algorithm.
// http://w3c.github.io/media-source/index.html#sourcebuffer-buffer-append
RefPtr<AppendPromise> AppendData(MediaByteBuffer* aData,
const SourceBufferAttributes& aAttributes);
@@ -207,17 +207,17 @@ private:
RefPtr<MediaByteBuffer> mInputBuffer;
// Buffer full flag as per https://w3c.github.io/media-source/#sourcebuffer-buffer-full-flag.
// Accessed on both the main thread and the task queue.
Atomic<bool> mBufferFull;
bool mFirstInitializationSegmentReceived;
// Set to true once a new segment is started.
bool mNewMediaSegmentStarted;
bool mActiveTrack;
- nsCString mType;
+ MediaContainerType mType;
// ContainerParser objects and methods.
// Those are used to parse the incoming input buffer.
// Recreate the ContainerParser and if aReuseInitData is true then
// feed it with the previous init segment found.
void RecreateParser(bool aReuseInitData);
nsAutoPtr<ContainerParser> mParser;
--- a/dom/media/mediasource/gtest/TestContainerParser.cpp
+++ b/dom/media/mediasource/gtest/TestContainerParser.cpp
@@ -8,43 +8,45 @@
#include "ContainerParser.h"
#include "mozilla/ArrayUtils.h"
#include "nsAutoPtr.h"
using namespace mozilla;
TEST(ContainerParser, MIMETypes) {
- const char* content_types[] = {
+ const char* containerTypes[] = {
"video/webm",
"audio/webm",
"video/mp4",
"audio/mp4",
"audio/aac"
};
nsAutoPtr<ContainerParser> parser;
- for (size_t i = 0; i < ArrayLength(content_types); ++i) {
- nsAutoCString content_type(content_types[i]);
- parser = ContainerParser::CreateForMIMEType(content_type);
+ for (size_t i = 0; i < ArrayLength(containerTypes); ++i) {
+ Maybe<MediaContainerType> containerType = MakeMediaContainerType(containerTypes[i]);
+ ASSERT_TRUE(containerType.isSome());
+ parser = ContainerParser::CreateForMIMEType(*containerType);
ASSERT_NE(parser, nullptr);
}
}
already_AddRefed<MediaByteBuffer> make_adts_header()
{
const uint8_t test[] = { 0xff, 0xf1, 0x50, 0x80, 0x03, 0x1f, 0xfc };
RefPtr<MediaByteBuffer> buffer(new MediaByteBuffer);
buffer->AppendElements(test, ArrayLength(test));
return buffer.forget();
}
TEST(ContainerParser, ADTSHeader) {
nsAutoPtr<ContainerParser> parser;
- parser = ContainerParser::CreateForMIMEType(NS_LITERAL_CSTRING("audio/aac"));
+ parser = ContainerParser::CreateForMIMEType(MediaContainerType(
+ MEDIAMIMETYPE("audio/aac")));
ASSERT_NE(parser, nullptr);
// Audio data should have no gaps.
EXPECT_EQ(parser->GetRoundingError(), 0);
// Test a valid header.
RefPtr<MediaByteBuffer> header = make_adts_header();
EXPECT_TRUE(NS_SUCCEEDED(parser->IsInitSegmentPresent(header)));
@@ -96,17 +98,18 @@ TEST(ContainerParser, ADTSHeader) {
EXPECT_EQ(parser->InitSegmentRange(), MediaByteRange(0, int64_t(header->Length())));
// Media segment range should be empty here.
EXPECT_EQ(parser->MediaHeaderRange(), MediaByteRange());
EXPECT_EQ(parser->MediaSegmentRange(), MediaByteRange());
}
TEST(ContainerParser, ADTSBlankMedia) {
nsAutoPtr<ContainerParser> parser;
- parser = ContainerParser::CreateForMIMEType(NS_LITERAL_CSTRING("audio/aac"));
+ parser = ContainerParser::CreateForMIMEType(MediaContainerType(
+ MEDIAMIMETYPE("audio/aac")));
ASSERT_NE(parser, nullptr);
// Audio data should have no gaps.
EXPECT_EQ(parser->GetRoundingError(), 0);
// Test the header only.
RefPtr<MediaByteBuffer> header = make_adts_header();
EXPECT_TRUE(NS_SUCCEEDED(parser->IsInitSegmentPresent(header)));
--- a/dom/media/webaudio/MediaBufferDecoder.cpp
+++ b/dom/media/webaudio/MediaBufferDecoder.cpp
@@ -190,17 +190,17 @@ MediaDecodeTask::CreateReader()
nsCOMPtr<nsIPrincipal> principal;
nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(mDecodeJob.mContext->GetParentObject());
if (sop) {
principal = sop->GetPrincipal();
}
RefPtr<BufferMediaResource> resource =
new BufferMediaResource(static_cast<uint8_t*> (mBuffer),
- mLength, principal, mContainerType.Type().AsString());
+ mLength, principal, mContainerType);
MOZ_ASSERT(!mBufferDecoder);
mBufferDecoder = new BufferDecoder(resource,
new BufferDecoderGMPCrashHelper(mDecodeJob.mContext->GetParentObject()));
// If you change this list to add support for new decoders, please consider
// updating HTMLMediaElement::CreateDecoder as well.