tenfourfox/media/libstagefright/binding/DecoderData.cpp
Cameron Kaiser c9b2922b70 hello FPR
2017-04-19 00:56:45 -07:00

191 lines
5.1 KiB
C++

/* 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 "mp4_demuxer/Adts.h"
#include "mp4_demuxer/AnnexB.h"
#include "mp4_demuxer/ByteReader.h"
#include "mp4_demuxer/DecoderData.h"
#include <media/stagefright/foundation/ABitReader.h>
#include "media/stagefright/MetaData.h"
#include "media/stagefright/MediaDefs.h"
#include "media/stagefright/Utils.h"
#include "mozilla/ArrayUtils.h"
#include "include/ESDS.h"
using namespace stagefright;
namespace mp4_demuxer
{
static int32_t
FindInt32(const MetaData* mMetaData, uint32_t mKey)
{
int32_t value;
if (!mMetaData->findInt32(mKey, &value))
return 0;
return value;
}
static int64_t
FindInt64(const MetaData* mMetaData, uint32_t mKey)
{
int64_t value;
if (!mMetaData->findInt64(mKey, &value))
return 0;
return value;
}
template <typename T, size_t N>
static bool
FindData(const MetaData* aMetaData, uint32_t aKey, mozilla::Vector<T, N>* aDest)
{
const void* data;
size_t size;
uint32_t type;
aDest->clear();
// There's no point in checking that the type matches anything because it
// isn't set consistently in the MPEG4Extractor.
if (!aMetaData->findData(aKey, &type, &data, &size) || size % sizeof(T)) {
return false;
}
aDest->append(reinterpret_cast<const T*>(data), size / sizeof(T));
return true;
}
template <typename T>
static bool
FindData(const MetaData* aMetaData, uint32_t aKey, nsTArray<T>* aDest)
{
const void* data;
size_t size;
uint32_t type;
aDest->Clear();
// There's no point in checking that the type matches anything because it
// isn't set consistently in the MPEG4Extractor.
if (!aMetaData->findData(aKey, &type, &data, &size) || size % sizeof(T)) {
return false;
}
aDest->AppendElements(reinterpret_cast<const T*>(data), size / sizeof(T));
return true;
}
static bool
FindData(const MetaData* aMetaData, uint32_t aKey, mozilla::MediaByteBuffer* aDest)
{
return FindData(aMetaData, aKey, static_cast<nsTArray<uint8_t>*>(aDest));
}
bool
CryptoFile::DoUpdate(const uint8_t* aData, size_t aLength)
{
ByteReader reader(aData, aLength);
while (reader.Remaining()) {
PsshInfo psshInfo;
if (!reader.ReadArray(psshInfo.uuid, 16)) {
return false;
}
if (!reader.CanReadType<uint32_t>()) {
return false;
}
auto length = reader.ReadType<uint32_t>();
if (!reader.ReadArray(psshInfo.data, length)) {
return false;
}
pssh.AppendElement(psshInfo);
}
return true;
}
static void
UpdateTrackInfo(mozilla::TrackInfo& aConfig,
const MetaData* aMetaData,
const char* aMimeType)
{
mozilla::CryptoTrack& crypto = aConfig.mCrypto;
aConfig.mMimeType = aMimeType;
aConfig.mDuration = FindInt64(aMetaData, kKeyDuration);
aConfig.mMediaTime = FindInt64(aMetaData, kKeyMediaTime);
aConfig.mTrackId = FindInt32(aMetaData, kKeyTrackID);
aConfig.mCrypto.mValid = aMetaData->findInt32(kKeyCryptoMode, &crypto.mMode) &&
aMetaData->findInt32(kKeyCryptoDefaultIVSize, &crypto.mIVSize) &&
FindData(aMetaData, kKeyCryptoKey, &crypto.mKeyId);
}
void
MP4AudioInfo::Update(const MetaData* aMetaData,
const char* aMimeType)
{
UpdateTrackInfo(*this, aMetaData, aMimeType);
mChannels = FindInt32(aMetaData, kKeyChannelCount);
mBitDepth = FindInt32(aMetaData, kKeySampleSize);
mRate = FindInt32(aMetaData, kKeySampleRate);
mProfile = FindInt32(aMetaData, kKeyAACProfile);
if (FindData(aMetaData, kKeyESDS, mExtraData)) {
ESDS esds(mExtraData->Elements(), mExtraData->Length());
const void* data;
size_t size;
if (esds.getCodecSpecificInfo(&data, &size) == OK) {
const uint8_t* cdata = reinterpret_cast<const uint8_t*>(data);
mCodecSpecificConfig->AppendElements(cdata, size);
if (size > 1) {
ABitReader br(cdata, size);
mExtendedProfile = br.getBits(5);
if (mExtendedProfile == 31) { // AAC-ELD => additional 6 bits
mExtendedProfile = 32 + br.getBits(6);
}
}
}
}
}
bool
MP4AudioInfo::IsValid() const
{
return mChannels > 0 && mRate > 0 &&
(!mMimeType.Equals(MEDIA_MIMETYPE_AUDIO_AAC) ||
mProfile > 0 || mExtendedProfile > 0);
}
void
MP4VideoInfo::Update(const MetaData* aMetaData, const char* aMimeType)
{
UpdateTrackInfo(*this, aMetaData, aMimeType);
mDisplay.width = FindInt32(aMetaData, kKeyDisplayWidth);
mDisplay.height = FindInt32(aMetaData, kKeyDisplayHeight);
mImage.width = FindInt32(aMetaData, kKeyWidth);
mImage.height = FindInt32(aMetaData, kKeyHeight);
FindData(aMetaData, kKeyAVCC, mExtraData);
if (!mExtraData->Length()) {
if (FindData(aMetaData, kKeyESDS, mExtraData)) {
ESDS esds(mExtraData->Elements(), mExtraData->Length());
const void* data;
size_t size;
if (esds.getCodecSpecificInfo(&data, &size) == OK) {
const uint8_t* cdata = reinterpret_cast<const uint8_t*>(data);
mCodecSpecificConfig->AppendElements(cdata, size);
}
}
}
}
bool
MP4VideoInfo::IsValid() const
{
return mDisplay.width > 0 && mDisplay.height > 0;
}
}