Skip to content

Commit

Permalink
Implement MixPresentationLayout::ReadAndValidate and LoudspeakersSsCo…
Browse files Browse the repository at this point in the history
…nventionLayout::Read.

PiperOrigin-RevId: 632589083
  • Loading branch information
Googler authored and jwcullen committed May 14, 2024
1 parent 65507c2 commit 9338c24
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 0 deletions.
75 changes: 75 additions & 0 deletions iamf/obu/mix_presentation.cc
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,70 @@ absl::Status ValidateNumSubMixes(DecodedUleb128 num_sub_mixes) {

} // namespace

absl::Status MixPresentationLayout::ReadAndValidate(ReadBitBuffer& rb) {
// Read the `loudness_layout` portion of a `MixPresentationLayout`.
uint8_t layout_type;
RETURN_IF_NOT_OK(rb.ReadUnsignedLiteral(2, layout_type));
loudness_layout.layout_type = static_cast<Layout::LayoutType>(layout_type);

// Read the specific type of `Layout` dependent on `layout_type`.
switch (loudness_layout.layout_type) {
using enum Layout::LayoutType;
case kLayoutTypeLoudspeakersSsConvention:
// Implement LoudspeakersSsConventionLayout::ReadAndValidate
RETURN_IF_NOT_OK(std::get<LoudspeakersSsConventionLayout>(
loudness_layout.specific_layout)
.Read(rb));
break;
case kLayoutTypeReserved0:
case kLayoutTypeReserved1:
return absl::InvalidArgumentError("Layout is not supported.");
case kLayoutTypeBinaural:
return absl::UnimplementedError("Binaural layout is not supported.");
break;
}

// Read the `loudness` portion of a `MixPresentationLayout`.
uint8_t info_type;
RETURN_IF_NOT_OK(rb.ReadUnsignedLiteral(8, info_type));
loudness.info_type = static_cast<LoudnessInfo::InfoTypeBitmask>(info_type);
RETURN_IF_NOT_OK(rb.ReadSigned16(loudness.integrated_loudness));
RETURN_IF_NOT_OK(rb.ReadSigned16(loudness.digital_peak));

// Conditionally read `true_peak` based on `info_type`.
if (loudness.info_type & LoudnessInfo::kTruePeak) {
RETURN_IF_NOT_OK(rb.ReadSigned16(loudness.true_peak));
}
// Conditionally read `anchored_loudness` based on `info_type`.
if (loudness.info_type & LoudnessInfo::kAnchoredLoudness) {
RETURN_IF_NOT_OK(rb.ReadUnsignedLiteral(
8, loudness.anchored_loudness.num_anchored_loudness));

for (int i = 0; i < loudness.anchored_loudness.num_anchored_loudness; ++i) {
AnchoredLoudnessElement anchor_loudness_element;
uint8_t anchor_element;
RETURN_IF_NOT_OK(rb.ReadUnsignedLiteral(8, anchor_element));
anchor_loudness_element.anchor_element =
static_cast<AnchoredLoudnessElement::AnchorElement>(anchor_element);
RETURN_IF_NOT_OK(
rb.ReadSigned16(anchor_loudness_element.anchored_loudness));
loudness.anchored_loudness.anchor_elements.push_back(
anchor_loudness_element);
}
RETURN_IF_NOT_OK(ValidateUniqueAnchorElements(
loudness.anchored_loudness.anchor_elements));
}
// Conditionally read `layout_extension` based on `info_type`.
if (loudness.info_type & LoudnessInfo::kAnyLayoutExtension) {
RETURN_IF_NOT_OK(rb.ReadULeb128(loudness.layout_extension.info_type_size));
RETURN_IF_NOT_OK(
rb.ReadUint8Vector(loudness.layout_extension.info_type_size,
loudness.layout_extension.info_type_bytes));
}

return absl::OkStatus();
}

absl::Status SubMixAudioElement::ReadAndValidate(const int32_t& count_label,
ReadBitBuffer& rb) {
// Read the main portion of an `SubMixAudioElement`.
Expand Down Expand Up @@ -254,6 +318,17 @@ absl::Status LoudspeakersSsConventionLayout::Write(bool& found_stereo_layout,
return wb.WriteUnsignedLiteral(reserved, 2);
}

// Reads and validates a `LoudspeakersSsConventionLayout`
// TODO(b/339855338): Set `found_stereo_layout` to true if it is a stereo layout
// and check that its been found in MixPresentationSubMix::Read.
absl::Status LoudspeakersSsConventionLayout::Read(ReadBitBuffer& rb) {
uint8_t sound_system;
RETURN_IF_NOT_OK(rb.ReadUnsignedLiteral(4, sound_system));
sound_system = static_cast<SoundSystem>(sound_system);
RETURN_IF_NOT_OK(rb.ReadUnsignedLiteral(2, reserved));
return absl::OkStatus();
}

absl::Status LoudspeakersReservedBinauralLayout::Write(
WriteBitBuffer& wb) const {
RETURN_IF_NOT_OK(wb.WriteUnsignedLiteral(reserved, 6));
Expand Down
16 changes: 16 additions & 0 deletions iamf/obu/mix_presentation.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,14 @@ struct LoudspeakersSsConventionLayout {
*/
absl::Status Write(bool& found_stereo_layout, WriteBitBuffer& wb) const;

/*\!brief Reads the layout from the buffer.
*
* \param rb Buffer to read from.
* \return `absl::OkStatus()` if the layout is valid. A specific status if the
* read fails.
*/
absl::Status Read(ReadBitBuffer& rb);

/*\!brief Prints logging information about the layout. */
void Print() const;

Expand Down Expand Up @@ -246,6 +254,14 @@ struct MixPresentationLayout {
friend bool operator==(const MixPresentationLayout& lhs,
const MixPresentationLayout& rhs) = default;

/*\!brief Reads and validates the MixPresentationLayout from the buffer.
*
* \param rb Buffer to read from.
* \return `absl::OkStatus()` if the layout is valid. A specific status if the
* read fails.
*/
absl::Status ReadAndValidate(ReadBitBuffer& rb);

Layout loudness_layout;
LoudnessInfo loudness;
};
Expand Down
37 changes: 37 additions & 0 deletions iamf/obu/tests/mix_presentation_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -955,5 +955,42 @@ TEST(ReadSubMixAudioElementTest, AllFieldsPresent) {
EXPECT_EQ(audio_element, expected_submix_audio_element);
}

// TODO(b/339855295): Add more tests.
TEST(ReadMixPresentationLayoutTest, LoudSpeakerWithAnchoredLoudness) {
std::vector<uint8_t> source = {
// Start Layout.
(Layout::kLayoutTypeLoudspeakersSsConvention << 6) |
LoudspeakersSsConventionLayout::kSoundSystemA_0_2_0,
LoudnessInfo::kAnchoredLoudness, 0, 18, 0, 19,
// Start anchored loudness.
2, AnchoredLoudnessElement::kAnchorElementAlbum, 0, 20,
AnchoredLoudnessElement::kAnchorElementDialogue, 0, 21,
// End anchored loudness.
// End Layout.
};
ReadBitBuffer buffer(1024, &source);
MixPresentationLayout layout;
EXPECT_TRUE(layout.ReadAndValidate(buffer).ok());
EXPECT_EQ(layout.loudness_layout.layout_type,
Layout::kLayoutTypeLoudspeakersSsConvention);
EXPECT_EQ(std::get<LoudspeakersSsConventionLayout>(
layout.loudness_layout.specific_layout),
LoudspeakersSsConventionLayout(
{.sound_system =
LoudspeakersSsConventionLayout::kSoundSystemA_0_2_0}));
EXPECT_EQ(layout.loudness.info_type, LoudnessInfo::kAnchoredLoudness);
EXPECT_EQ(layout.loudness.anchored_loudness.num_anchored_loudness, 2);
EXPECT_EQ(layout.loudness.anchored_loudness.anchor_elements[0].anchor_element,
AnchoredLoudnessElement::kAnchorElementAlbum);
EXPECT_EQ(
layout.loudness.anchored_loudness.anchor_elements[0].anchored_loudness,
20);
EXPECT_EQ(layout.loudness.anchored_loudness.anchor_elements[1].anchor_element,
AnchoredLoudnessElement::kAnchorElementDialogue);
EXPECT_EQ(
layout.loudness.anchored_loudness.anchor_elements[1].anchored_loudness,
21);
}

} // namespace
} // namespace iamf_tools

0 comments on commit 9338c24

Please sign in to comment.