feat: Add support for ALAC codec (#1299)
Co-authored-by: Cosmin Stejerean <cstejerean@meta.com>
This commit is contained in:
parent
35c2f46428
commit
b68ec87f6a
|
@ -1477,6 +1477,15 @@ class PackagerFunctionalTest(PackagerAppTest):
|
|||
self.assertPackageSuccess(streams, flags)
|
||||
self._CheckTestResults('flac-with-encryption', verify_decryption=True)
|
||||
|
||||
def testAlac(self):
|
||||
streams = [
|
||||
self._GetStream('audio', test_file='bear-alac.mp4'),
|
||||
]
|
||||
flags = self._GetFlags(output_dash=True)
|
||||
|
||||
self.assertPackageSuccess(streams, flags)
|
||||
self._CheckTestResults('audio-alac')
|
||||
|
||||
def testAv1Mp4WithEncryption(self):
|
||||
self.assertPackageSuccess(
|
||||
self._GetStreams(['video'], test_files=['bear-av1.mp4']),
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--Generated with https://github.com/shaka-project/shaka-packager version <tag>-<hash>-<test>-->
|
||||
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" minBufferTime="PT2S" type="static" mediaPresentationDuration="PT2.739955S">
|
||||
<Period id="0">
|
||||
<AdaptationSet id="0" contentType="audio" subsegmentAlignment="true">
|
||||
<Representation id="0" bandwidth="1046256" codecs="alac" mimeType="audio/mp4" audioSamplingRate="44100">
|
||||
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
|
||||
<BaseURL>bear-alac-audio.mp4</BaseURL>
|
||||
<SegmentBase indexRange="762-829" timescale="44100">
|
||||
<Initialization range="0-761"/>
|
||||
</SegmentBase>
|
||||
</Representation>
|
||||
</AdaptationSet>
|
||||
</Period>
|
||||
</MPD>
|
|
@ -25,6 +25,8 @@ std::string AudioCodecToString(Codec codec) {
|
|||
return "AAC";
|
||||
case kCodecAC3:
|
||||
return "AC3";
|
||||
case kCodecALAC:
|
||||
return "ALAC";
|
||||
case kCodecDTSC:
|
||||
return "DTSC";
|
||||
case kCodecDTSE:
|
||||
|
@ -138,6 +140,8 @@ std::string AudioStreamInfo::GetCodecString(Codec codec,
|
|||
return "mp4a.40." + absl::StrFormat("%hhu", audio_object_type);
|
||||
case kCodecAC3:
|
||||
return "ac-3";
|
||||
case kCodecALAC:
|
||||
return "alac";
|
||||
case kCodecDTSC:
|
||||
return "dtsc";
|
||||
case kCodecDTSE:
|
||||
|
|
|
@ -23,6 +23,7 @@ enum FourCC : uint32_t {
|
|||
FOURCC_ac_3 = 0x61632d33, // "ac-3"
|
||||
FOURCC_ac_4 = 0x61632d34, // "ac-4"
|
||||
FOURCC_ac3d = 0x61633364,
|
||||
FOURCC_alac = 0x616c6163,
|
||||
FOURCC_apad = 0x61706164,
|
||||
FOURCC_av01 = 0x61763031,
|
||||
FOURCC_av1C = 0x61763143,
|
||||
|
|
|
@ -41,6 +41,7 @@ enum Codec {
|
|||
kCodecAAC = kCodecAudio,
|
||||
kCodecAC3,
|
||||
kCodecAC4,
|
||||
kCodecALAC,
|
||||
// TODO(kqyang): Use kCodecDTS and a kDtsStreamFormat for the various DTS
|
||||
// streams.
|
||||
kCodecDTSC,
|
||||
|
|
|
@ -1969,6 +1969,27 @@ size_t FlacSpecific::ComputeSizeInternal() {
|
|||
return HeaderSize() + data.size();
|
||||
}
|
||||
|
||||
ALACSpecific::ALACSpecific() = default;
|
||||
ALACSpecific::~ALACSpecific() = default;
|
||||
|
||||
FourCC ALACSpecific::BoxType() const {
|
||||
return FOURCC_alac;
|
||||
}
|
||||
|
||||
bool ALACSpecific::ReadWriteInternal(BoxBuffer* buffer) {
|
||||
RCHECK(ReadWriteHeaderInternal(buffer));
|
||||
size_t size = buffer->Reading() ? buffer->BytesLeft() : data.size();
|
||||
RCHECK(buffer->ReadWriteVector(&data, size));
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t ALACSpecific::ComputeSizeInternal() {
|
||||
// This box is optional. Skip it if not initialized.
|
||||
if (data.empty())
|
||||
return 0;
|
||||
return HeaderSize() + data.size();
|
||||
}
|
||||
|
||||
AudioSampleEntry::AudioSampleEntry() = default;
|
||||
AudioSampleEntry::~AudioSampleEntry() = default;
|
||||
|
||||
|
@ -2011,6 +2032,7 @@ bool AudioSampleEntry::ReadWriteInternal(BoxBuffer* buffer) {
|
|||
RCHECK(buffer->TryReadWriteChild(&dops));
|
||||
RCHECK(buffer->TryReadWriteChild(&dfla));
|
||||
RCHECK(buffer->TryReadWriteChild(&mhac));
|
||||
RCHECK(buffer->TryReadWriteChild(&alac));
|
||||
|
||||
// Somehow Edge does not support having sinf box before codec_configuration,
|
||||
// box, so just do it in the end of AudioSampleEntry. See
|
||||
|
@ -2036,6 +2058,7 @@ size_t AudioSampleEntry::ComputeSizeInternal() {
|
|||
sizeof(samplesize) + sizeof(samplerate) + sinf.ComputeSize() +
|
||||
esds.ComputeSize() + ddts.ComputeSize() + dac3.ComputeSize() +
|
||||
dec3.ComputeSize() + dops.ComputeSize() + dfla.ComputeSize() +
|
||||
dac4.ComputeSize() + mhac.ComputeSize() + alac.ComputeSize() +
|
||||
dac4.ComputeSize() + mhac.ComputeSize() + udts.ComputeSize() +
|
||||
// Reserved and predefined bytes.
|
||||
6 + 8 + // 6 + 8 bytes reserved.
|
||||
|
|
|
@ -382,6 +382,15 @@ struct FlacSpecific : FullBox {
|
|||
std::vector<uint8_t> data;
|
||||
};
|
||||
|
||||
// ALAC specific decoder configuration box:
|
||||
// https://wiki.multimedia.cx/index.php/Apple_Lossless_Audio_Coding
|
||||
// We do not care about the actual data inside, which is simply copied over.
|
||||
struct ALACSpecific : FullBox {
|
||||
DECLARE_BOX_METHODS(ALACSpecific);
|
||||
|
||||
std::vector<uint8_t> data;
|
||||
};
|
||||
|
||||
struct AudioSampleEntry : Box {
|
||||
DECLARE_BOX_METHODS(AudioSampleEntry);
|
||||
|
||||
|
@ -409,6 +418,7 @@ struct AudioSampleEntry : Box {
|
|||
OpusSpecific dops;
|
||||
FlacSpecific dfla;
|
||||
MHAConfiguration mhac;
|
||||
ALACSpecific alac;
|
||||
};
|
||||
|
||||
struct WebVTTConfigurationBox : Box {
|
||||
|
|
|
@ -102,6 +102,8 @@ Codec FourCCToCodec(FourCC fourcc) {
|
|||
return kCodecEAC3;
|
||||
case FOURCC_ac_4:
|
||||
return kCodecAC4;
|
||||
case FOURCC_alac:
|
||||
return kCodecALAC;
|
||||
case FOURCC_fLaC:
|
||||
return kCodecFlac;
|
||||
case FOURCC_mha1:
|
||||
|
@ -514,6 +516,9 @@ bool MP4MediaParser::ParseMoov(BoxReader* reader) {
|
|||
return false;
|
||||
}
|
||||
break;
|
||||
case FOURCC_alac:
|
||||
codec_config = entry.alac.data;
|
||||
break;
|
||||
case FOURCC_fLaC:
|
||||
codec_config = entry.dfla.data;
|
||||
break;
|
||||
|
|
|
@ -76,6 +76,8 @@ FourCC CodecToFourCC(Codec codec, H26xStreamFormat h26x_stream_format) {
|
|||
return FOURCC_mp4a;
|
||||
case kCodecAC3:
|
||||
return FOURCC_ac_3;
|
||||
case kCodecALAC:
|
||||
return FOURCC_alac;
|
||||
case kCodecDTSC:
|
||||
return FOURCC_dtsc;
|
||||
case kCodecDTSH:
|
||||
|
@ -512,6 +514,9 @@ bool MP4Muxer::GenerateAudioTrak(const AudioStreamInfo* audio_info,
|
|||
case kCodecAC4:
|
||||
audio.dac4.data = audio_info->codec_config();
|
||||
break;
|
||||
case kCodecALAC:
|
||||
audio.alac.data = audio_info->codec_config();
|
||||
break;
|
||||
case kCodecFlac:
|
||||
audio.dfla.data = audio_info->codec_config();
|
||||
break;
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue