зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
a56255ef1f
Коммит
8ea4c13088
|
@ -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()) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче