Bug 1747760 - P5: Handle flac codec specific data using flac codec specific variant. r=kinetik

This also populates flac codec specific data for flac in mp4, which appears to
have been overlooked.

Depends on D134730

Differential Revision: https://phabricator.services.mozilla.com/D134731
This commit is contained in:
Bryce Seager van Dyk 2022-05-17 23:09:06 +00:00
Родитель a56255ef1f
Коммит 8ea4c13088
4 изменённых файлов: 47 добавлений и 5 удалений

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

@ -141,6 +141,10 @@ class FrameHeader {
if (mValid) {
// Set the mimetype to make it a valid AudioInfo.
mInfo.mMimeType = "audio/flac";
// Set the codec specific data to flac, but leave it empty since we don't
// have METADATA_BLOCK_STREAMINFO in the frame.
mInfo.mCodecSpecificConfig =
AudioCodecSpecificVariant{FlacCodecSpecificData{}};
}
return mValid;
@ -666,11 +670,19 @@ UniquePtr<TrackInfo> FlacTrackDemuxer::GetInfo() const {
info->mTags.AppendElement(MetadataTag(entry.GetKey(), entry.GetData()));
}
}
MOZ_ASSERT(info->IsAudio() &&
info->GetAsAudioInfo()
->mCodecSpecificConfig.is<FlacCodecSpecificData>(),
"Should get flac specific data from parser");
return info;
} else if (mParser->FirstFrame().Info().IsValid()) {
// Use the first frame header.
UniquePtr<TrackInfo> info = mParser->FirstFrame().Info().Clone();
info->mDuration = Duration();
MOZ_ASSERT(info->IsAudio() &&
info->GetAsAudioInfo()
->mCodecSpecificConfig.is<FlacCodecSpecificData>(),
"Should get flac specific data from parser");
return info;
}
return nullptr;

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

@ -37,7 +37,7 @@ FlacFrameParser::FlacFrameParser()
mMaxFrameSize(0),
mNumFrames(0),
mFullMetadata(false),
mPacketCount(0) {}
mPacketCount(0){};
FlacFrameParser::~FlacFrameParser() = default;
@ -141,11 +141,11 @@ Result<Ok, nsresult> FlacFrameParser::DecodeHeaderBlock(const uint8_t* aPacket,
mInfo.mRate = sampleRate;
mInfo.mChannels = numChannels;
mInfo.mBitDepth = bps;
AudioCodecSpecificBinaryBlob codecSpecificBlob;
codecSpecificBlob.mBinaryBlob->AppendElements(blockDataStart,
blockDataSize);
FlacCodecSpecificData flacCodecSpecificData;
flacCodecSpecificData.mStreamInfoBinaryBlob->AppendElements(
blockDataStart, blockDataSize);
mInfo.mCodecSpecificConfig =
AudioCodecSpecificVariant{std::move(codecSpecificBlob)};
AudioCodecSpecificVariant{std::move(flacCodecSpecificData)};
auto duration = FramesToTimeUnit(mNumFrames, sampleRate);
mInfo.mDuration = duration.IsValid() ? duration : media::TimeUnit::Zero();
mParser = MakeUnique<OpusParser>();

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

@ -177,7 +177,14 @@ MediaResult MP4AudioInfo::Update(const Mp4parseTrackInfo* track,
} else if (codecType == MP4PARSE_CODEC_AAC) {
mMimeType = "audio/mp4a-latm"_ns;
} else if (codecType == MP4PARSE_CODEC_FLAC) {
MOZ_ASSERT(extraData.length == 0,
"FLAC doesn't expect extra data so doesn't handle it!");
mMimeType = "audio/flac"_ns;
FlacCodecSpecificData flacCodecSpecificData{};
flacCodecSpecificData.mStreamInfoBinaryBlob->AppendElements(
mp4ParseSampleCodecSpecific.data, mp4ParseSampleCodecSpecific.length);
mCodecSpecificConfig =
AudioCodecSpecificVariant{std::move(flacCodecSpecificData)};
} else if (codecType == MP4PARSE_CODEC_MP3) {
// mp3 in mp4 can contain ES_Descriptor info (it also has a flash in mp4
// specific box, which the rust parser recognizes). However, we don't

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

@ -36,6 +36,29 @@ FFmpegAudioDecoder<LIBAV_VER>::FFmpegAudioDecoder(FFmpegLibWrapper* aLib,
}
}
if (mCodecID == AV_CODEC_ID_FLAC) {
MOZ_DIAGNOSTIC_ASSERT(
aConfig.mCodecSpecificConfig.is<FlacCodecSpecificData>());
// Gracefully handle bad data. If don't hit the preceding assert once this
// has been shipped for awhile, we can remove it and make the following code
// non-conditional.
if (aConfig.mCodecSpecificConfig.is<FlacCodecSpecificData>()) {
const FlacCodecSpecificData& flacCodecSpecificData =
aConfig.mCodecSpecificConfig.as<FlacCodecSpecificData>();
if (flacCodecSpecificData.mStreamInfoBinaryBlob->IsEmpty()) {
// Flac files without headers will be missing stream info. In this case
// we don't want to feed ffmpeg empty extra data as it will fail, just
// early return.
return;
}
// Use a new MediaByteBuffer as the object will be modified during
// initialization.
mExtraData = new MediaByteBuffer;
mExtraData->AppendElements(*flacCodecSpecificData.mStreamInfoBinaryBlob);
return;
}
}
RefPtr<MediaByteBuffer> audioCodecSpecificBinaryBlob =
ForceGetAudioCodecSpecificBlob(aConfig.mCodecSpecificConfig);
if (audioCodecSpecificBinaryBlob && audioCodecSpecificBinaryBlob->Length()) {