import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo

This commit is contained in:
Roy Tam 2018-01-19 03:59:58 +08:00
commit dcd9973243
150858 changed files with 23884658 additions and 0 deletions

View file

@ -0,0 +1,52 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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 "FlacDecoder.h"
#include "FlacDemuxer.h"
#include "MediaDecoderStateMachine.h"
#include "MediaFormatReader.h"
#include "MediaPrefs.h"
namespace mozilla {
MediaDecoder*
FlacDecoder::Clone(MediaDecoderOwner* aOwner)
{
if (!IsEnabled())
return nullptr;
return new FlacDecoder(aOwner);
}
MediaDecoderStateMachine*
FlacDecoder::CreateStateMachine()
{
RefPtr<MediaDecoderReader> reader =
new MediaFormatReader(this, new FlacDemuxer(GetResource()));
return new MediaDecoderStateMachine(this, reader);
}
/* static */ bool
FlacDecoder::IsEnabled()
{
#ifdef MOZ_FFVPX
return MediaPrefs::FlacEnabled();
#else
// Until bug 1295886 is fixed.
return false;
#endif
}
/* static */ bool
FlacDecoder::CanHandleMediaType(const nsACString& aType,
const nsAString& aCodecs)
{
return IsEnabled() &&
(aType.EqualsASCII("audio/flac") || aType.EqualsASCII("audio/x-flac") ||
aType.EqualsASCII("application/x-flac"));
}
} // namespace mozilla

View file

@ -0,0 +1,30 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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 FLAC_DECODER_H_
#define FLAC_DECODER_H_
#include "MediaDecoder.h"
namespace mozilla {
class FlacDecoder : public MediaDecoder {
public:
// MediaDecoder interface.
explicit FlacDecoder(MediaDecoderOwner* aOwner) : MediaDecoder(aOwner) {}
MediaDecoder* Clone(MediaDecoderOwner* aOwner) override;
MediaDecoderStateMachine* CreateStateMachine() override;
// Returns true if the Flac backend is pref'ed on, and we're running on a
// platform that is likely to have decoders for the format.
static bool IsEnabled();
static bool CanHandleMediaType(const nsACString& aType,
const nsAString& aCodecs);
};
} // namespace mozilla
#endif // !FLAC_DECODER_H_

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,108 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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 FLAC_DEMUXER_H_
#define FLAC_DEMUXER_H_
#include "mozilla/Attributes.h"
#include "MediaDataDemuxer.h"
#include "MediaResource.h"
namespace mozilla {
namespace flac {
class Frame;
class FrameParser;
}
class FlacTrackDemuxer;
class FlacDemuxer : public MediaDataDemuxer {
public:
// MediaDataDemuxer interface.
explicit FlacDemuxer(MediaResource* aSource);
RefPtr<InitPromise> Init() override;
bool HasTrackType(TrackInfo::TrackType aType) const override;
uint32_t GetNumberTracks(TrackInfo::TrackType aType) const override;
already_AddRefed<MediaTrackDemuxer> GetTrackDemuxer(
TrackInfo::TrackType aType, uint32_t aTrackNumber) override;
bool IsSeekable() const override;
// Return true if a valid flac frame header could be found.
static bool FlacSniffer(const uint8_t* aData, const uint32_t aLength);
private:
bool InitInternal();
RefPtr<MediaResource> mSource;
RefPtr<FlacTrackDemuxer> mTrackDemuxer;
};
class FlacTrackDemuxer : public MediaTrackDemuxer {
public:
explicit FlacTrackDemuxer(MediaResource* aSource);
// Initializes the track demuxer by reading the first frame for meta data.
// Returns initialization success state.
bool Init();
// MediaTrackDemuxer interface.
UniquePtr<TrackInfo> GetInfo() const override;
RefPtr<SeekPromise> Seek(media::TimeUnit aTime) override;
RefPtr<SamplesPromise> GetSamples(int32_t aNumSamples = 1) override;
void Reset() override;
int64_t GetResourceOffset() const override;
media::TimeIntervals GetBuffered() override;
RefPtr<SkipAccessPointPromise> SkipToNextRandomAccessPoint(
media::TimeUnit aTimeThreshold) override;
bool IsSeekable() const;
private:
// Destructor.
~FlacTrackDemuxer();
// Returns the estimated stream duration, or a 0-duration if unknown.
media::TimeUnit Duration() const;
media::TimeUnit TimeAtEnd();
// Fast approximate seeking to given time.
media::TimeUnit FastSeek(const media::TimeUnit& aTime);
// Seeks by scanning the stream up to the given time for more accurate results.
media::TimeUnit ScanUntil(const media::TimeUnit& aTime);
// Finds the next valid frame and return it.
const flac::Frame& FindNextFrame();
// Returns the next ADTS frame, if available.
already_AddRefed<MediaRawData> GetNextFrame(const flac::Frame& aFrame);
// Reads aSize bytes into aBuffer from the source starting at aOffset.
// Returns the actual size read.
int32_t Read(uint8_t* aBuffer, int64_t aOffset, int32_t aSize);
// Returns the average frame length derived from the previously parsed frames.
double AverageFrameLength() const;
// The (hopefully) Flac resource.
MediaResourceIndex mSource;
// Flac frame parser used to detect frames and extract side info.
nsAutoPtr<flac::FrameParser> mParser;
// Total duration of parsed frames.
media::TimeUnit mParsedFramesDuration;
// Sum of parsed frames' lengths in bytes.
uint64_t mTotalFrameLen;
// Audio track config info.
UniquePtr<AudioInfo> mInfo;
};
} // mozilla
#endif // !FLAC_DEMUXER_H_

View file

@ -0,0 +1,251 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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 "FlacFrameParser.h"
#include "mp4_demuxer/ByteReader.h"
#include "nsTArray.h"
#include "OggCodecState.h"
#include "OpusParser.h"
#include "VideoUtils.h"
using mp4_demuxer::ByteReader;
namespace mozilla
{
#define OGG_FLAC_METADATA_TYPE_STREAMINFO 0x7F
#define FLAC_STREAMINFO_SIZE 34
#define BITMASK(x) ((1ULL << x)-1)
enum
{
FLAC_METADATA_TYPE_STREAMINFO = 0,
FLAC_METADATA_TYPE_PADDING,
FLAC_METADATA_TYPE_APPLICATION,
FLAC_METADATA_TYPE_SEEKTABLE,
FLAC_METADATA_TYPE_VORBIS_COMMENT,
FLAC_METADATA_TYPE_CUESHEET,
FLAC_METADATA_TYPE_PICTURE,
FLAC_METADATA_TYPE_INVALID = 127
};
FlacFrameParser::FlacFrameParser()
: mMinBlockSize(0)
, mMaxBlockSize(0)
, mMinFrameSize(0)
, mMaxFrameSize(0)
, mNumFrames(0)
, mFullMetadata(false)
, mPacketCount(0)
{
}
FlacFrameParser::~FlacFrameParser()
{
}
uint32_t
FlacFrameParser::HeaderBlockLength(const uint8_t* aPacket) const
{
uint32_t extra = 4;
if (aPacket[0] == 'f') {
// This must be the first block read, which contains the fLaC signature.
aPacket += 4;
extra += 4;
}
return (BigEndian::readUint32(aPacket) & BITMASK(24)) + extra;
}
bool
FlacFrameParser::DecodeHeaderBlock(const uint8_t* aPacket, size_t aLength)
{
if (aLength < 4 || aPacket[0] == 0xff) {
// Not a header block.
return false;
}
ByteReader br(aPacket, aLength);
mPacketCount++;
if (aPacket[0] == 'f') {
if (mPacketCount != 1 || memcmp(br.Read(4), "fLaC", 4) ||
br.Remaining() != FLAC_STREAMINFO_SIZE + 4) {
return false;
}
aPacket += 4;
aLength -= 4;
}
uint8_t blockHeader = br.ReadU8();
// blockType is a misnomer as it could indicate here either a packet type
// should it points to the start of a Flac in Ogg metadata, or an actual
// block type as per the flac specification.
uint32_t blockType = blockHeader & 0x7f;
bool lastBlock = blockHeader & 0x80;
if (blockType == OGG_FLAC_METADATA_TYPE_STREAMINFO) {
if (mPacketCount != 1 || memcmp(br.Read(4), "FLAC", 4) ||
br.Remaining() != FLAC_STREAMINFO_SIZE + 12) {
return false;
}
uint32_t major = br.ReadU8();
if (major != 1) {
// unsupported version;
return false;
}
br.ReadU8(); // minor version
mNumHeaders = Some(uint32_t(br.ReadU16()));
br.Read(4); // fLaC
blockType = br.ReadU8() & BITMASK(7);
// First METADATA_BLOCK_STREAMINFO
if (blockType != FLAC_METADATA_TYPE_STREAMINFO) {
// First block must be a stream info.
return false;
}
}
uint32_t blockDataSize = br.ReadU24();
const uint8_t* blockDataStart = br.Peek(blockDataSize);
if (!blockDataStart) {
// Incomplete block.
return false;
}
switch (blockType) {
case FLAC_METADATA_TYPE_STREAMINFO:
{
if (mPacketCount != 1 || blockDataSize != FLAC_STREAMINFO_SIZE) {
// STREAMINFO must be the first metadata block found, and its size
// is constant.
return false;
}
mMinBlockSize = br.ReadU16();
mMaxBlockSize = br.ReadU16();
mMinFrameSize = br.ReadU24();
mMaxFrameSize = br.ReadU24();
uint64_t blob = br.ReadU64();
uint32_t sampleRate = (blob >> 44) & BITMASK(20);
if (!sampleRate) {
return false;
}
uint32_t numChannels = ((blob >> 41) & BITMASK(3)) + 1;
if (numChannels > FLAC_MAX_CHANNELS) {
return false;
}
uint32_t bps = ((blob >> 36) & BITMASK(5)) + 1;
if (bps > 24) {
return false;
}
mNumFrames = blob & BITMASK(36);
mInfo.mMimeType = "audio/flac";
mInfo.mRate = sampleRate;
mInfo.mChannels = numChannels;
mInfo.mBitDepth = bps;
mInfo.mCodecSpecificConfig->AppendElements(blockDataStart, blockDataSize);
CheckedInt64 duration =
SaferMultDiv(mNumFrames, USECS_PER_S, sampleRate);
mInfo.mDuration = duration.isValid() ? duration.value() : 0;
mParser = new OpusParser;
break;
}
case FLAC_METADATA_TYPE_VORBIS_COMMENT:
{
if (!mParser) {
// We must have seen a valid streaminfo first.
return false;
}
nsTArray<uint8_t> comments(blockDataSize + 8);
comments.AppendElements("OpusTags", 8);
comments.AppendElements(blockDataStart, blockDataSize);
if (!mParser->DecodeTags(comments.Elements(), comments.Length())) {
return false;
}
break;
}
default:
break;
}
if (mNumHeaders && mPacketCount > mNumHeaders.ref() + 1) {
// Received too many header block. assuming invalid.
return false;
}
if (lastBlock || (mNumHeaders && mNumHeaders.ref() + 1 == mPacketCount)) {
mFullMetadata = true;
}
return true;
}
int64_t
FlacFrameParser::BlockDuration(const uint8_t* aPacket, size_t aLength) const
{
if (!mInfo.IsValid()) {
return -1;
}
if (mMinBlockSize == mMaxBlockSize) {
// block size is fixed, use this instead of looking at the frame header.
return mMinBlockSize;
}
// TODO
return 0;
}
bool
FlacFrameParser::IsHeaderBlock(const uint8_t* aPacket, size_t aLength) const
{
// Ogg Flac header
// The one-byte packet type 0x7F
// The four-byte ASCII signature "FLAC", i.e. 0x46, 0x4C, 0x41, 0x43
// Flac header:
// "fLaC", the FLAC stream marker in ASCII, meaning byte 0 of the stream is 0x66, followed by 0x4C 0x61 0x43
// If we detect either a ogg or plain flac header, then it must be valid.
if (aLength < 4 || aPacket[0] == 0xff) {
// A header is at least 4 bytes.
return false;
}
if (aPacket[0] == 0x7f) {
// Ogg packet
ByteReader br(aPacket + 1, aLength - 1);
const uint8_t* signature = br.Read(4);
return signature && !memcmp(signature, "FLAC", 4);
}
ByteReader br(aPacket, aLength - 1);
const uint8_t* signature = br.Read(4);
if (signature && !memcmp(signature, "fLaC", 4)) {
// Flac start header, must have STREAMINFO as first metadata block;
if (!br.CanRead8()) {
return false;
}
uint32_t blockType = br.ReadU8() & 0x7f;
return blockType == FLAC_METADATA_TYPE_STREAMINFO;
}
char type = aPacket[0] & 0x7f;
return type >= 1 && type <= 6;
}
MetadataTags*
FlacFrameParser::GetTags() const
{
MetadataTags* tags;
tags = new MetadataTags;
for (uint32_t i = 0; i < mParser->mTags.Length(); i++) {
OggCodecState::AddVorbisComment(tags,
mParser->mTags[i].Data(),
mParser->mTags[i].Length());
}
return tags;
}
} // namespace mozilla

View file

@ -0,0 +1,64 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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 FLAC_FRAME_PARSER_H_
#define FLAC_FRAME_PARSER_H_
#include "mozilla/Maybe.h"
#include "nsAutoPtr.h"
#include "MediaDecoder.h" // For MetadataTags
#include "MediaInfo.h"
#include "MediaResource.h"
namespace mozilla
{
class OpusParser;
// Decode a Flac Metadata block contained in either a ogg packet
// (https://xiph.org/flac/ogg_mapping.html) or in flac container
// (https://xiph.org/flac/format.html#frame_header)
class FlacFrameParser
{
public:
FlacFrameParser();
~FlacFrameParser();
bool IsHeaderBlock(const uint8_t* aPacket, size_t aLength) const;
// Return the length of the block header (METADATA_BLOCK_HEADER+
// METADATA_BLOCK_DATA), aPacket must point to at least 4
// bytes and to a valid block header start (as determined by IsHeaderBlock).
uint32_t HeaderBlockLength(const uint8_t* aPacket) const;
bool DecodeHeaderBlock(const uint8_t* aPacket, size_t aLength);
bool HasFullMetadata() const { return mFullMetadata; }
// Return the duration in frames found in the block. -1 if error
// such as invalid packet.
int64_t BlockDuration(const uint8_t* aPacket, size_t aLength) const;
// Return a hash table with tag metadata.
MetadataTags* GetTags() const;
AudioInfo mInfo;
private:
bool ReconstructFlacGranulepos(void);
Maybe<uint32_t> mNumHeaders;
uint32_t mMinBlockSize;
uint32_t mMaxBlockSize;
uint32_t mMinFrameSize;
uint32_t mMaxFrameSize;
uint64_t mNumFrames;
bool mFullMetadata;
uint32_t mPacketCount;
// Used to decode the vorbis comment metadata.
nsAutoPtr<OpusParser> mParser;
};
}
#endif // FLAC_FRAME_PARSER_H_

24
dom/media/flac/moz.build Normal file
View file

@ -0,0 +1,24 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
EXPORTS += [
'FlacDecoder.h',
'FlacDemuxer.h',
'FlacFrameParser.h',
]
UNIFIED_SOURCES += [
'FlacDecoder.cpp',
'FlacDemuxer.cpp',
'FlacFrameParser.cpp',
]
CXXFLAGS += CONFIG['MOZ_LIBVPX_CFLAGS']
FINAL_LIBRARY = 'xul'
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wno-error=shadow']