Skip to content

Commit

Permalink
feat: Add support for ALAC codec (shaka-project#1299)
Browse files Browse the repository at this point in the history
Co-authored-by: Cosmin Stejerean <[email protected]>
  • Loading branch information
wjywbs and cosmin committed Feb 26, 2024
1 parent 35c2f46 commit b68ec87
Show file tree
Hide file tree
Showing 11 changed files with 73 additions and 0 deletions.
9 changes: 9 additions & 0 deletions packager/app/test/packager_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1477,6 +1477,15 @@ def testFlacWithEncryption(self):
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']),
Expand Down
Binary file not shown.
15 changes: 15 additions & 0 deletions packager/app/test/testdata/audio-alac/output.mpd
Original file line number Diff line number Diff line change
@@ -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>
4 changes: 4 additions & 0 deletions packager/media/base/audio_stream_info.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down
1 change: 1 addition & 0 deletions packager/media/base/fourccs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions packager/media/base/stream_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ enum Codec {
kCodecAAC = kCodecAudio,
kCodecAC3,
kCodecAC4,
kCodecALAC,
// TODO(kqyang): Use kCodecDTS and a kDtsStreamFormat for the various DTS
// streams.
kCodecDTSC,
Expand Down
23 changes: 23 additions & 0 deletions packager/media/formats/mp4/box_definitions.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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
Expand All @@ -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.
Expand Down
10 changes: 10 additions & 0 deletions packager/media/formats/mp4/box_definitions.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -409,6 +418,7 @@ struct AudioSampleEntry : Box {
OpusSpecific dops;
FlacSpecific dfla;
MHAConfiguration mhac;
ALACSpecific alac;
};

struct WebVTTConfigurationBox : Box {
Expand Down
5 changes: 5 additions & 0 deletions packager/media/formats/mp4/mp4_media_parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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;
Expand Down
5 changes: 5 additions & 0 deletions packager/media/formats/mp4/mp4_muxer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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;
Expand Down
Binary file added packager/media/test/data/bear-alac.mp4
Binary file not shown.

0 comments on commit b68ec87

Please sign in to comment.