Bug 1110534: Simplify MP4 extradata handling. r=kentuckyfriedtakahe

This commit is contained in:
Jean-Yves Avenard 2014-12-23 14:36:09 +11:00
Родитель ac92460241
Коммит 8f57ec0db8
19 изменённых файлов: 80 добавлений и 62 удалений

Просмотреть файл

@ -262,8 +262,8 @@ AndroidDecoderModule::CreateAudioDecoder(const mp4_demuxer::AudioDecoderConfig&
if (!format->GetByteBuffer(NS_LITERAL_CSTRING("csd-0"))) {
uint8_t* csd0 = new uint8_t[2];
csd0[0] = aConfig.audio_specific_config[0];
csd0[1] = aConfig.audio_specific_config[1];
csd0[0] = (*aConfig.audio_specific_config)[0];
csd0[1] = (*aConfig.audio_specific_config)[1];
jobject buffer = env->NewDirectByteBuffer(csd0, 2);
format->SetByteBuffer(NS_LITERAL_CSTRING("csd-0"), buffer);

Просмотреть файл

@ -293,7 +293,7 @@ AppleATDecoder::DecodeSample(mp4_demuxer::MP4Sample* aSample)
nsresult
AppleATDecoder::GetInputAudioDescription(AudioStreamBasicDescription& aDesc,
const mozilla::Vector<uint8_t>& aExtraData)
const nsTArray<uint8_t>& aExtraData)
{
// Request the properties from CoreAudio using the codec magic cookie
AudioFormatInfo formatInfo;
@ -302,8 +302,8 @@ AppleATDecoder::GetInputAudioDescription(AudioStreamBasicDescription& aDesc,
if (mFormatID == kAudioFormatMPEG4AAC) {
formatInfo.mASBD.mFormatFlags = mConfig.extended_profile;
}
formatInfo.mMagicCookieSize = aExtraData.length();
formatInfo.mMagicCookie = aExtraData.begin();
formatInfo.mMagicCookieSize = aExtraData.Length();
formatInfo.mMagicCookie = aExtraData.Elements();
UInt32 formatListSize;
// Attempt to retrieve the default format using
@ -374,7 +374,7 @@ AppleATDecoder::SetupDecoder(mp4_demuxer::MP4Sample* aSample)
// This will provide us with an updated magic cookie for use with
// GetInputAudioDescription.
if (NS_SUCCEEDED(GetImplicitAACMagicCookie(aSample)) &&
!mMagicCookie.length()) {
!mMagicCookie.Length()) {
// nothing found yet, will try again later
return NS_ERROR_NOT_INITIALIZED;
}
@ -387,8 +387,8 @@ AppleATDecoder::SetupDecoder(mp4_demuxer::MP4Sample* aSample)
PodZero(&inputFormat);
nsresult rv =
GetInputAudioDescription(inputFormat,
mMagicCookie.length() ?
mMagicCookie : mConfig.extra_data);
mMagicCookie.Length() ?
mMagicCookie : *mConfig.extra_data);
if (NS_FAILED(rv)) {
return rv;
}
@ -449,7 +449,7 @@ _MetadataCallback(void* aAppleATDecoder,
decoder->mFileStreamError = true;
return;
}
decoder->mMagicCookie.append(data.get(), size);
decoder->mMagicCookie.AppendElements(data.get(), size);
}
}
@ -495,7 +495,7 @@ AppleATDecoder::GetImplicitAACMagicCookie(const mp4_demuxer::MP4Sample* aSample)
NS_WARNING("Couldn't parse sample");
}
if (status || mFileStreamError || mMagicCookie.length()) {
if (status || mFileStreamError || mMagicCookie.Length()) {
// We have decoded a magic cookie or an error occurred as such
// we won't need the stream any longer.
AudioFileStreamClose(mStream);

Просмотреть файл

@ -36,7 +36,7 @@ public:
const mp4_demuxer::AudioDecoderConfig& mConfig;
// Use to extract magic cookie for HE-AAC detection.
mozilla::Vector<uint8_t> mMagicCookie;
nsTArray<uint8_t> mMagicCookie;
// Will be set to true should an error occurred while attempting to retrieve
// the magic cookie property.
bool mFileStreamError;
@ -53,7 +53,7 @@ private:
void SubmitSample(nsAutoPtr<mp4_demuxer::MP4Sample> aSample);
nsresult DecodeSample(mp4_demuxer::MP4Sample* aSample);
nsresult GetInputAudioDescription(AudioStreamBasicDescription& aDesc,
const mozilla::Vector<uint8_t>& aExtraData);
const nsTArray<uint8_t>& aExtraData);
// Setup AudioConverter once all information required has been gathered.
// Will return NS_ERROR_NOT_INITIALIZED if more data is required.
nsresult SetupDecoder(mp4_demuxer::MP4Sample* aSample);

Просмотреть файл

@ -404,8 +404,8 @@ AppleVDADecoder::InitializeSession()
CFDictionaryRef
AppleVDADecoder::CreateDecoderSpecification()
{
const uint8_t* extradata = mConfig.extra_data.begin();
int extrasize = mConfig.extra_data.length();
const uint8_t* extradata = mConfig.extra_data->Elements();
int extrasize = mConfig.extra_data->Length();
OSType format = 'avc1';
AutoCFRelease<CFNumberRef> avc_width =

Просмотреть файл

@ -260,7 +260,7 @@ AppleVTDecoder::InitializeSession()
#ifdef LOG_MEDIA_SHA1
SHA1Sum avc_hash;
avc_hash.update(mConfig.extra_data.begin(), mConfig.extra_data.length());
avc_hash.update(mConfig.extra_data->Elements(), mConfig.extra_data->Length());
uint8_t digest_buf[SHA1Sum::kHashSize];
avc_hash.finish(digest_buf);
nsAutoCString avc_digest;
@ -268,7 +268,7 @@ AppleVTDecoder::InitializeSession()
avc_digest.AppendPrintf("%02x", digest_buf[i]);
}
LOG("AVCDecoderConfig %ld bytes sha1 %s",
mConfig.extra_data.length(), avc_digest.get());
mConfig.extra_data->Length(), avc_digest.get());
#endif // LOG_MEDIA_SHA1
AutoCFRelease<CFDictionaryRef> extensions = CreateDecoderExtensions();
@ -312,8 +312,8 @@ AppleVTDecoder::CreateDecoderExtensions()
{
AutoCFRelease<CFDataRef> avc_data =
CFDataCreate(kCFAllocatorDefault,
mConfig.extra_data.begin(),
mConfig.extra_data.length());
mConfig.extra_data->Elements(),
mConfig.extra_data->Length());
const void* atomsKey[] = { CFSTR("avcC") };
const void* atomsValue[] = { avc_data };

Просмотреть файл

@ -278,9 +278,8 @@ EMEAudioDecoder::GmpInit()
mAudioChannels = mConfig.channel_count;
nsTArray<uint8_t> extraData;
extraData.AppendElements(&mConfig.audio_specific_config[0],
mConfig.audio_specific_config.length());
extraData.AppendElements(mConfig.audio_specific_config->Elements(),
mConfig.audio_specific_config->Length());
mGMP->InitDecode(kGMPAudioCodecAAC,
mAudioChannels,
mConfig.bits_per_sample,

Просмотреть файл

@ -277,8 +277,8 @@ EMEH264Decoder::GmpInit()
nsTArray<uint8_t> codecSpecific;
codecSpecific.AppendElement(0); // mPacketizationMode.
codecSpecific.AppendElements(mConfig.extra_data.begin(),
mConfig.extra_data.length());
codecSpecific.AppendElements(mConfig.extra_data->Elements(),
mConfig.extra_data->Length());
rv = mGMP->InitDecode(codec,
codecSpecific,

Просмотреть файл

@ -24,8 +24,7 @@ FFmpegAudioDecoder<LIBAV_VER>::FFmpegAudioDecoder(
, mCallback(aCallback)
{
MOZ_COUNT_CTOR(FFmpegAudioDecoder);
mExtraData.append(aConfig.audio_specific_config.begin(),
aConfig.audio_specific_config.length());
mExtraData = aConfig.audio_specific_config;
}
nsresult

Просмотреть файл

@ -8,7 +8,6 @@
#include <unistd.h>
#include "MediaTaskQueue.h"
#include "mp4_demuxer/mp4_demuxer.h"
#include "FFmpegLibs.h"
#include "FFmpegLog.h"
#include "FFmpegDataDecoder.h"
@ -94,11 +93,11 @@ FFmpegDataDecoder<LIBAV_VER>::Init()
mCodecContext->thread_type = FF_THREAD_SLICE | FF_THREAD_FRAME;
mCodecContext->thread_safe_callbacks = false;
mCodecContext->extradata_size = mExtraData.length();
mCodecContext->extradata_size = mExtraData->Length();
for (int i = 0; i < FF_INPUT_BUFFER_PADDING_SIZE; i++) {
mExtraData.append(0);
mExtraData->AppendElement(0);
}
mCodecContext->extradata = mExtraData.begin();
mCodecContext->extradata = mExtraData->Elements();
if (codec->capabilities & CODEC_CAP_DR1) {
mCodecContext->flags |= CODEC_FLAG_EMU_EDGE;

Просмотреть файл

@ -9,8 +9,8 @@
#include "PlatformDecoderModule.h"
#include "FFmpegLibs.h"
#include "mozilla/Vector.h"
#include "mozilla/StaticMutex.h"
#include "mp4_demuxer/mp4_demuxer.h"
namespace mozilla
{
@ -41,7 +41,7 @@ protected:
MediaTaskQueue* mTaskQueue;
AVCodecContext* mCodecContext;
AVFrame* mFrame;
Vector<uint8_t> mExtraData;
nsRefPtr<mp4_demuxer::ByteBuffer> mExtraData;
private:
static bool sFFmpegInitDone;

Просмотреть файл

@ -32,7 +32,7 @@ FFmpegH264Decoder<LIBAV_VER>::FFmpegH264Decoder(
, mImageContainer(aImageContainer)
{
MOZ_COUNT_CTOR(FFmpegH264Decoder);
mExtraData.append(aConfig.extra_data.begin(), aConfig.extra_data.length());
mExtraData = aConfig.extra_data;
}
nsresult

Просмотреть файл

@ -46,8 +46,8 @@ GonkAudioDecoderManager::GonkAudioDecoderManager(
{
MOZ_COUNT_CTOR(GonkAudioDecoderManager);
MOZ_ASSERT(mAudioChannels);
mUserData.AppendElements(&aConfig.audio_specific_config[0],
aConfig.audio_specific_config.length());
mUserData.AppendElements(aConfig.audio_specific_config->Elements(),
aConfig.audio_specific_config->Length());
// Pass through mp3 without applying an ADTS header.
if (strcmp(aConfig.mime_type, "audio/mp4a-latm") != 0) {
mUseAdts = false;

Просмотреть файл

@ -83,8 +83,8 @@ WMFAudioMFTManager::WMFAudioMFTManager(
} else if (!strcmp(aConfig.mime_type, "audio/mp4a-latm")) {
mStreamType = AAC;
AACAudioSpecificConfigToUserData(aConfig.aac_profile,
&aConfig.audio_specific_config[0],
aConfig.audio_specific_config.length(),
aConfig.audio_specific_config->Elements(),
aConfig.audio_specific_config->Length(),
mUserData);
} else {
mStreamType = Unknown;

Просмотреть файл

@ -23,7 +23,7 @@ AnnexB::ConvertSample(MP4Sample* aSample)
}
MOZ_ASSERT(aSample->data);
MOZ_ASSERT(aSample->size >= ArrayLength(kAnnexBDelimiter));
MOZ_ASSERT(aSample->prefix_data);
MOZ_ASSERT(aSample->extra_data);
uint8_t* d = aSample->data;
while (d + 4 < aSample->data + aSample->size) {
@ -38,13 +38,13 @@ AnnexB::ConvertSample(MP4Sample* aSample)
// Prepend the Annex B header with SPS and PPS tables to keyframes.
if (aSample->is_sync_point) {
aSample->Prepend(&(*aSample->prefix_data)[0],
aSample->prefix_data->Length());
nsRefPtr<ByteBuffer> annexB = ConvertExtraDataToAnnexB(aSample->extra_data);
aSample->Prepend(annexB->Elements(), annexB->Length());
}
}
already_AddRefed<nsRcTArray<uint8_t>>
AnnexB::ConvertExtraDataToAnnexB(mozilla::Vector<uint8_t>& aExtraData)
already_AddRefed<ByteBuffer>
AnnexB::ConvertExtraDataToAnnexB(const ByteBuffer* aExtraData)
{
// AVCC 6 byte header looks like:
// +------+------+------+------+------+------+------+------+
@ -61,9 +61,9 @@ AnnexB::ConvertExtraDataToAnnexB(mozilla::Vector<uint8_t>& aExtraData)
// [5] | unused | numSps |
// +------+------+------+------+------+------+------+------+
nsRefPtr<nsRcTArray<uint8_t>> annexB = new nsRcTArray<uint8_t>();
nsRefPtr<ByteBuffer> annexB = new ByteBuffer;
ByteReader reader(aExtraData);
ByteReader reader(*aExtraData);
const uint8_t* ptr = reader.Read(5);
if (ptr && ptr[0] == 1) {
// Append SPS then PPS
@ -79,7 +79,7 @@ AnnexB::ConvertExtraDataToAnnexB(mozilla::Vector<uint8_t>& aExtraData)
void
AnnexB::ConvertSPSOrPPS(ByteReader& aReader, uint8_t aCount,
nsTArray<uint8_t>* aAnnexB)
ByteBuffer* aAnnexB)
{
for (int i = 0; i < aCount; i++) {
uint16_t length = aReader.ReadU16();

Просмотреть файл

@ -75,6 +75,12 @@ FindData(sp<MetaData>& aMetaData, uint32_t aKey, nsTArray<T>* aDest)
return true;
}
static bool
FindData(sp<MetaData>& aMetaData, uint32_t aKey, ByteBuffer* aDest)
{
return FindData(aMetaData, aKey, static_cast<nsTArray<uint8_t>*>(aDest));
}
bool
CryptoFile::DoUpdate(sp<MetaData>& aMetaData)
{
@ -146,14 +152,14 @@ AudioDecoderConfig::Update(sp<MetaData>& aMetaData, const char* aMimeType)
frequency_index = Adts::GetFrequencyIndex(samples_per_second);
aac_profile = FindInt32(aMetaData, kKeyAACProfile);
if (FindData(aMetaData, kKeyESDS, &extra_data)) {
ESDS esds(&extra_data[0], extra_data.length());
if (FindData(aMetaData, kKeyESDS, extra_data)) {
ESDS esds(extra_data->Elements(), extra_data->Length());
const void* data;
size_t size;
if (esds.getCodecSpecificInfo(&data, &size) == OK) {
const uint8_t* cdata = reinterpret_cast<const uint8_t*>(data);
audio_specific_config.append(cdata, size);
audio_specific_config->AppendElements(cdata, size);
if (size > 1) {
ABitReader br(cdata, size);
extended_profile = br.getBits(5);
@ -182,11 +188,10 @@ VideoDecoderConfig::Update(sp<MetaData>& aMetaData, const char* aMimeType)
image_width = FindInt32(aMetaData, kKeyWidth);
image_height = FindInt32(aMetaData, kKeyHeight);
if (FindData(aMetaData, kKeyAVCC, &extra_data) && extra_data.length() >= 7) {
if (FindData(aMetaData, kKeyAVCC, extra_data) && extra_data->Length() >= 7) {
// Set size of the NAL length to 4. The demuxer formats its output with
// this NAL length size.
extra_data[4] |= 3;
annex_b = AnnexB::ConvertExtraDataToAnnexB(extra_data);
(*extra_data)[4] |= 3;
}
}
@ -205,6 +210,7 @@ MP4Sample::MP4Sample()
, is_sync_point(0)
, data(nullptr)
, size(0)
, extra_data(nullptr)
{
}
@ -217,7 +223,7 @@ MP4Sample::MP4Sample(const MP4Sample& copy)
, is_sync_point(copy.is_sync_point)
, size(copy.size)
, crypto(copy.crypto)
, prefix_data(copy.prefix_data)
, extra_data(copy.extra_data)
{
extra_buffer = data = new uint8_t[size];
memcpy(data, copy.data, size);

Просмотреть файл

@ -22,13 +22,13 @@ public:
static void ConvertSample(MP4Sample* aSample);
// Parse an AVCC box and construct the Annex B sample header.
static already_AddRefed<nsRcTArray<uint8_t>> ConvertExtraDataToAnnexB(
mozilla::Vector<uint8_t>& aExtraData);
static already_AddRefed<ByteBuffer> ConvertExtraDataToAnnexB(
const ByteBuffer* aExtraData);
private:
// AVCC box parser helper.
static void ConvertSPSOrPPS(ByteReader& aReader, uint8_t aCount,
nsTArray<uint8_t>* aAnnexB);
ByteBuffer* aAnnexB);
};
} // namespace mp4_demuxer

Просмотреть файл

@ -28,6 +28,10 @@ public:
: mPtr(&aData[0]), mRemaining(aData.Length())
{
}
explicit ByteReader(const nsTArray<uint8_t>& aData)
: mPtr(&aData[0]), mRemaining(aData.Length())
{
}
void SetData(const nsTArray<uint8_t>& aData)
{

Просмотреть файл

@ -9,6 +9,7 @@
#include "mozilla/Vector.h"
#include "nsTArray.h"
#include "nsAutoPtr.h"
#include "nsRefPtr.h"
namespace stagefright
{
@ -30,6 +31,8 @@ private:
~nsRcTArray() {}
};
typedef nsRcTArray<uint8_t> ByteBuffer;
struct PsshInfo
{
PsshInfo() {}
@ -99,6 +102,8 @@ public:
, frequency_index(0)
, aac_profile(0)
, extended_profile(0)
, extra_data(new ByteBuffer)
, audio_specific_config(new ByteBuffer)
{
}
@ -108,8 +113,8 @@ public:
int8_t frequency_index;
int8_t aac_profile;
int8_t extended_profile;
mozilla::Vector<uint8_t> extra_data;
mozilla::Vector<uint8_t> audio_specific_config;
nsRefPtr<ByteBuffer> extra_data;
nsRefPtr<ByteBuffer> audio_specific_config;
void Update(stagefright::sp<stagefright::MetaData>& aMetaData,
const char* aMimeType);
@ -122,7 +127,14 @@ private:
class VideoDecoderConfig : public TrackConfig
{
public:
VideoDecoderConfig() : display_width(0), display_height(0) {}
VideoDecoderConfig()
: display_width(0)
, display_height(0)
, image_width(0)
, image_height(0)
, extra_data(new ByteBuffer)
{
}
int32_t display_width;
int32_t display_height;
@ -130,8 +142,7 @@ public:
int32_t image_width;
int32_t image_height;
mozilla::Vector<uint8_t> extra_data; // Unparsed AVCDecoderConfig payload.
nsRefPtr<nsRcTArray<uint8_t>> annex_b; // Parsed version for sample prepend.
nsRefPtr<ByteBuffer> extra_data; // Unparsed AVCDecoderConfig payload.
void Update(stagefright::sp<stagefright::MetaData>& aMetaData,
const char* aMimeType);
@ -161,7 +172,7 @@ public:
size_t size;
CryptoSample crypto;
nsRefPtr<nsRcTArray<uint8_t>> prefix_data;
nsRefPtr<ByteBuffer> extra_data;
void Prepend(const uint8_t* aData, size_t aSize);

Просмотреть файл

@ -216,7 +216,7 @@ MP4Demuxer::DemuxVideoSample()
if (mPrivate->mVideoIterator) {
nsAutoPtr<MP4Sample> sample(mPrivate->mVideoIterator->GetNext());
if (sample) {
sample->prefix_data = mVideoConfig.annex_b;
sample->extra_data = mVideoConfig.extra_data;
if (sample->crypto.valid) {
sample->crypto.mode = mVideoConfig.crypto.mode;
sample->crypto.key.AppendElements(mVideoConfig.crypto.key);
@ -235,7 +235,7 @@ MP4Demuxer::DemuxVideoSample()
}
sample->Update(mVideoConfig.media_time);
sample->prefix_data = mVideoConfig.annex_b;
sample->extra_data = mVideoConfig.extra_data;
return sample.forget();
}