зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1195723: [flac] P6. Add support for raw flac metadata decoding. r=kamidphish
We also move flac related files to their own flac folder. MozReview-Commit-ID: YnV3HNbjZe --HG-- extra : rebase_source : 59ade40278c324ffc2f4604ec9f93697406f3269
This commit is contained in:
Родитель
6a9478d232
Коммит
467235f54a
|
@ -29,21 +29,9 @@ public:
|
|||
|
||||
#define OGG_FLAC_METADATA_TYPE_STREAMINFO 0x7F
|
||||
#define FLAC_STREAMINFO_SIZE 34
|
||||
#define FLAC_MAX_CHANNELS 8
|
||||
#define FLAC_MIN_BLOCKSIZE 16
|
||||
#define FLAC_MAX_BLOCKSIZE 65535
|
||||
#define FLAC_MIN_FRAME_SIZE 11
|
||||
|
||||
#define BITMASK(x) ((1ULL << x)-1)
|
||||
|
||||
enum
|
||||
{
|
||||
FLAC_CHMODE_INDEPENDENT = 0,
|
||||
FLAC_CHMODE_LEFT_SIDE,
|
||||
FLAC_CHMODE_RIGHT_SIDE,
|
||||
FLAC_CHMODE_MID_SIDE,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
FLAC_METADATA_TYPE_STREAMINFO = 0,
|
||||
|
@ -67,10 +55,22 @@ 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 || aPacket[0] == 0xff) {
|
||||
if (aLength < 4 || aPacket[0] == 0xff) {
|
||||
// Not a header block.
|
||||
return false;
|
||||
}
|
||||
|
@ -78,10 +78,20 @@ FlacFrameParser::DecodeHeaderBlock(const uint8_t* aPacket, size_t 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 = br.ReadU8() & 0x7f;
|
||||
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) ||
|
||||
|
@ -114,7 +124,9 @@ FlacFrameParser::DecodeHeaderBlock(const uint8_t* aPacket, size_t aLength)
|
|||
switch (blockType) {
|
||||
case FLAC_METADATA_TYPE_STREAMINFO:
|
||||
{
|
||||
if (blockDataSize != FLAC_STREAMINFO_SIZE) {
|
||||
if (mPacketCount != 1 || blockDataSize != FLAC_STREAMINFO_SIZE) {
|
||||
// STREAMINFO must be the first metadata block found, and its size
|
||||
// is constant.
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -172,7 +184,7 @@ FlacFrameParser::DecodeHeaderBlock(const uint8_t* aPacket, size_t aLength)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (mNumHeaders && mNumHeaders.ref() + 1 == mPacketCount) {
|
||||
if (lastBlock || (mNumHeaders && mNumHeaders.ref() + 1 == mPacketCount)) {
|
||||
mFullMetadata = true;
|
||||
}
|
||||
|
||||
|
@ -196,7 +208,36 @@ FlacFrameParser::BlockDuration(const uint8_t* aPacket, size_t aLength) const
|
|||
bool
|
||||
FlacFrameParser::IsHeaderBlock(const uint8_t* aPacket, size_t aLength) const
|
||||
{
|
||||
return aLength && aPacket[0] != 0xff;
|
||||
// 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
|
||||
AutoByteReader br(aPacket + 1, aLength - 1);
|
||||
const uint8_t* signature = br.Read(4);
|
||||
return signature && !memcmp(signature, "FLAC", 4);
|
||||
}
|
||||
AutoByteReader 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*
|
|
@ -11,6 +11,7 @@
|
|||
#include "nsAutoPtr.h"
|
||||
#include "MediaDecoder.h" // For MetadataTags
|
||||
#include "MediaInfo.h"
|
||||
#include "MediaResource.h"
|
||||
|
||||
namespace mozilla
|
||||
{
|
||||
|
@ -27,6 +28,10 @@ public:
|
|||
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
|
|
@ -0,0 +1,20 @@
|
|||
# -*- 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 += [
|
||||
'FlacFrameParser.h',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'FlacFrameParser.cpp',
|
||||
]
|
||||
|
||||
CXXFLAGS += CONFIG['MOZ_LIBVPX_CFLAGS']
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
if CONFIG['GNU_CXX']:
|
||||
CXXFLAGS += ['-Wno-error=shadow']
|
|
@ -21,6 +21,7 @@ with Files('GetUserMedia*'):
|
|||
|
||||
DIRS += [
|
||||
'encoder',
|
||||
'flac',
|
||||
'gmp',
|
||||
'gmp-plugin',
|
||||
'gmp-plugin-openh264',
|
||||
|
@ -104,7 +105,6 @@ EXPORTS += [
|
|||
'DOMMediaStream.h',
|
||||
'EncodedBufferCache.h',
|
||||
'FileBlockCache.h',
|
||||
'FlacFrameParser.h',
|
||||
'FrameStatistics.h',
|
||||
'Intervals.h',
|
||||
'Latency.h',
|
||||
|
@ -218,7 +218,6 @@ UNIFIED_SOURCES += [
|
|||
'DOMMediaStream.cpp',
|
||||
'EncodedBufferCache.cpp',
|
||||
'FileBlockCache.cpp',
|
||||
'FlacFrameParser.cpp',
|
||||
'GetUserMediaRequest.cpp',
|
||||
'GraphDriver.cpp',
|
||||
'Latency.cpp',
|
||||
|
|
Загрузка…
Ссылка в новой задаче