Skip to content

Commit

Permalink
dtsx and udts boxes handled for MP4 files. DASH MPD uses DTS tags.
Browse files Browse the repository at this point in the history
  • Loading branch information
Roy-Funderburk committed Feb 8, 2024
1 parent 7ef5167 commit 778fa65
Show file tree
Hide file tree
Showing 11 changed files with 124 additions and 1 deletion.
2 changes: 2 additions & 0 deletions packager/media/base/audio_stream_info.cc
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ std::string AudioStreamInfo::GetCodecString(Codec codec,
return "dts-";
case kCodecDTSP:
return "dts+";
case kCodecDTSX:
return "dtsx";
case kCodecEAC3:
return "ec-3";
case kCodecAC4:
Expand Down
2 changes: 2 additions & 0 deletions packager/media/base/fourccs.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ enum FourCC : uint32_t {
FOURCC_dtsl = 0x6474736c,
FOURCC_dtsm = 0x6474732d, // "dts-"
FOURCC_dtsp = 0x6474732b, // "dts+"
FOURCC_dtsx = 0x64747378, // "dtsx"
FOURCC_dvcC = 0x64766343,
FOURCC_dvh1 = 0x64766831,
FOURCC_dvhe = 0x64766865,
Expand Down Expand Up @@ -151,6 +152,7 @@ enum FourCC : uint32_t {
FOURCC_trex = 0x74726578,
FOURCC_trun = 0x7472756e,
FOURCC_udta = 0x75647461,
FOURCC_udts = 0x75647473, // "udts"
FOURCC_url = 0x75726c20, // "url "
FOURCC_urn = 0x75726e20, // "urn "
FOURCC_uuid = 0x75756964,
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 @@ -49,6 +49,7 @@ enum Codec {
kCodecDTSL,
kCodecDTSM,
kCodecDTSP,
kCodecDTSX,
kCodecEAC3,
kCodecFlac,
kCodecOpus,
Expand Down
29 changes: 29 additions & 0 deletions packager/media/codecs/dts_audio_specific_config.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) 2023 Xperi Inc. All Rights Reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "packager/media/codecs/dts_audio_specific_config.h"


#include "packager/base/logging.h"
#include "packager/media/base/bit_reader.h"
#include "packager/media/base/rcheck.h"

namespace shaka {
namespace media {

bool GetDTSXChannelMask(const std::vector<uint8_t> &udts, uint32_t &mask) {
// udts is the DTS-UHD Specific Box: ETSI TS 103 491 V1.2.1 Table B-2
// DecoderProfileCode(6 bits)
// FrameDurationCode(2 bits)
// MaxPayloadCode(3 bits)
// NumPresentationsCode(5 bits)
// ChannelMask (32 bits)
BitReader bit_reader(udts.data(), udts.size());
RCHECK(bit_reader.SkipBits(16));
RCHECK(bit_reader.ReadBits(32, &mask));
return true;
}

} // namespace media
} // namespace shaka
23 changes: 23 additions & 0 deletions packager/media/codecs/dts_audio_specific_config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) 2023 Xperi Inc. All Rights Reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef PACKAGER_MEDIA_CODECS_DTS_AUDIO_SPECIFIC_CONFIG_H_
#define PACKAGER_MEDIA_CODECS_DTS_AUDIO_SPECIFIC_CONFIG_H_

#include <stddef.h>
#include <stdint.h>

#include <vector>

namespace shaka {
namespace media {

class BitReader;

bool GetDTSXChannelMask(const std::vector<uint8_t> &udts, uint32_t &mask);

} // namespace media
} // namespace shaka

#endif // PACKAGER_MEDIA_CODECS_DTS_AUDIO_SPECIFIC_CONFIG_H_
11 changes: 11 additions & 0 deletions packager/media/event/muxer_listener_internal.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <packager/media/base/text_stream_info.h>
#include <packager/media/base/video_stream_info.h>
#include <packager/media/codecs/ac4_audio_util.h>
#include "packager/media/codecs/dts_audio_specific_config.h"
#include <packager/media/codecs/ec3_audio_util.h>
#include <packager/mpd/base/media_info.pb.h>
#include <packager/utils/bytes_to_string_view.h>
Expand Down Expand Up @@ -165,6 +166,16 @@ void AddAudioInfo(const AudioStreamInfo* audio_stream_info,
codec_data->set_ac4_ims_flag(ac4_ims_flag);
codec_data->set_ac4_cbi_flag(ac4_cbi_flag);
}

if (audio_stream_info->codec() == kCodecDTSX) {
auto* codec_data = audio_info->mutable_codec_specific_data();
uint32_t channel_mask;
if (!GetDTSXChannelMask(codec_config, channel_mask)) {
LOG(ERROR) << "Failed to parse DTSX channel mask.";
return;
}
codec_data->set_channel_mask(channel_mask);
}
}

void AddTextInfo(const TextStreamInfo& text_stream_info,
Expand Down
24 changes: 23 additions & 1 deletion packager/media/formats/mp4/box_definitions.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1811,6 +1811,27 @@ size_t DTSSpecific::ComputeSizeInternal() {
sizeof(kDdtsExtraData);
}

UDTSSpecific::UDTSSpecific() = default;
UDTSSpecific::~UDTSSpecific() = default;

FourCC UDTSSpecific::BoxType() const {
return FOURCC_udts;
}

bool UDTSSpecific::ReadWriteInternal(BoxBuffer* buffer) {
RCHECK(ReadWriteHeaderInternal(buffer) &&
buffer->ReadWriteVector(
&data, buffer->Reading() ? buffer->BytesLeft() : data.size()));
return true;
}

size_t UDTSSpecific::ComputeSizeInternal() {
// This box is optional. Skip it if not initialized.
if (data.empty())
return 0;
return HeaderSize() + data.size();
}

AC3Specific::AC3Specific() = default;
AC3Specific::~AC3Specific() = default;

Expand Down Expand Up @@ -1983,6 +2004,7 @@ bool AudioSampleEntry::ReadWriteInternal(BoxBuffer* buffer) {

RCHECK(buffer->TryReadWriteChild(&esds));
RCHECK(buffer->TryReadWriteChild(&ddts));
RCHECK(buffer->TryReadWriteChild(&udts));
RCHECK(buffer->TryReadWriteChild(&dac3));
RCHECK(buffer->TryReadWriteChild(&dec3));
RCHECK(buffer->TryReadWriteChild(&dac4));
Expand Down Expand Up @@ -2014,7 +2036,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() +
dac4.ComputeSize() + mhac.ComputeSize() + udts.ComputeSize() +
// Reserved and predefined bytes.
6 + 8 + // 6 + 8 bytes reserved.
4; // 4 bytes predefined.
Expand Down
7 changes: 7 additions & 0 deletions packager/media/formats/mp4/box_definitions.h
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,12 @@ struct DTSSpecific : Box {
std::vector<uint8_t> extra_data;
};

struct UDTSSpecific : Box {
DECLARE_BOX_METHODS(UDTSSpecific);

std::vector<uint8_t> data;
};

struct AC3Specific : Box {
DECLARE_BOX_METHODS(AC3Specific);

Expand Down Expand Up @@ -396,6 +402,7 @@ struct AudioSampleEntry : Box {

ElementaryStreamDescriptor esds;
DTSSpecific ddts;
UDTSSpecific udts;
AC3Specific dac3;
EC3Specific dec3;
AC4Specific dac4;
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 @@ -90,6 +90,8 @@ Codec FourCCToCodec(FourCC fourcc) {
return kCodecDTSL;
case FOURCC_dtse:
return kCodecDTSE;
case FOURCC_dtsx:
return kCodecDTSX;
case FOURCC_dtsp:
return kCodecDTSP;
case FOURCC_dtsm:
Expand Down Expand Up @@ -491,6 +493,9 @@ bool MP4MediaParser::ParseMoov(BoxReader* reader) {
max_bitrate = entry.ddts.max_bitrate;
avg_bitrate = entry.ddts.avg_bitrate;
break;
case FOURCC_dtsx:
codec_config = entry.udts.data;
break;
case FOURCC_ac_3:
codec_config = entry.dac3.data;
num_channels = static_cast<uint8_t>(GetAc3NumChannels(codec_config));
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 @@ -86,6 +86,8 @@ FourCC CodecToFourCC(Codec codec, H26xStreamFormat h26x_stream_format) {
return FOURCC_dtse;
case kCodecDTSM:
return FOURCC_dtsm;
case kCodecDTSX:
return FOURCC_dtsx;
case kCodecEAC3:
return FOURCC_ec_3;
case kCodecAC4:
Expand Down Expand Up @@ -498,6 +500,9 @@ bool MP4Muxer::GenerateAudioTrak(const AudioStreamInfo* audio_info,
audio.ddts.sampling_frequency = audio_info->sampling_frequency();
audio.ddts.pcm_sample_depth = audio_info->sample_bits();
break;
case kCodecDTSX:
audio.udts.data = audio_info->codec_config();
break;
case kCodecAC3:
audio.dac3.data = audio_info->codec_config();
break;
Expand Down
16 changes: 16 additions & 0 deletions packager/mpd/base/xml/xml_node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ typedef MediaInfo::VideoInfo VideoInfo;
namespace {
const char kEC3Codec[] = "ec-3";
const char kAC4Codec[] = "ac-4";
const char kDTSCCodec[] = "dtsc";
const char kDTSECodec[] = "dtse";
const char kDTSXCodec[] = "dtsx";

std::string RangeToString(const Range& range) {
return absl::StrFormat("%u-%u", range.begin(), range.end());
Expand Down Expand Up @@ -612,6 +615,19 @@ bool RepresentationXmlNode::AddAudioChannelInfo(const AudioInfo& audio_info) {
"1");
}
return ret;
} else if (audio_info.codec() == kDTSCCodec ||
audio_info.codec() == kDTSECodec) {
audio_channel_config_value = base::UintToString(audio_info.num_channels());
audio_channel_config_scheme =
"tag:dts.com,2014:dash:audio_channel_configuration:2012";
} else if (audio_info.codec() == kDTSXCodec) {
const auto& codec_data = audio_info.codec_specific_data();
const uint32_t channel_config =
base::HostToNet32(codec_data.channel_mask());
audio_channel_config_value =
base::HexEncode(&channel_config, sizeof(channel_config));
audio_channel_config_scheme =
"tag:dts.com,2018:uhd:audio_channel_configuration";
} else {
audio_channel_config_value =
absl::StrFormat("%u", audio_info.num_channels());
Expand Down

0 comments on commit 778fa65

Please sign in to comment.