Skip to content

Commit 76187b7

Browse files
Googlerjwcullen
authored andcommitted
Internal change
PiperOrigin-RevId: 859710915
1 parent e6947b1 commit 76187b7

File tree

5 files changed

+321
-0
lines changed

5 files changed

+321
-0
lines changed

iamf/cli/proto_conversion/proto_to_obu/BUILD

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,20 @@ cc_library(
144144
],
145145
)
146146

147+
cc_library(
148+
name = "metadata_obu_generator",
149+
srcs = ["metadata_obu_generator.cc"],
150+
hdrs = ["metadata_obu_generator.h"],
151+
deps = [
152+
"//iamf/cli/proto:metadata_obu_cc_proto",
153+
"//iamf/obu:metadata_obu",
154+
"//iamf/obu:obu_header",
155+
"@abseil-cpp//absl/status",
156+
"@abseil-cpp//absl/status:statusor",
157+
"@com_google_protobuf//:protobuf",
158+
],
159+
)
160+
147161
cc_library(
148162
name = "mix_presentation_generator",
149163
srcs = ["mix_presentation_generator.cc"],
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Copyright (c) 2026, Alliance for Open Media. All rights reserved
3+
*
4+
* This source code is subject to the terms of the BSD 3-Clause Clear License
5+
* and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear
6+
* License was not distributed with this source code in the LICENSE file, you
7+
* can obtain it at www.aomedia.org/license/software-license/bsd-3-c-c. If the
8+
* Alliance for Open Media Patent License 1.0 was not distributed with this
9+
* source code in the PATENTS file, you can obtain it at
10+
* www.aomedia.org/license/patent.
11+
*/
12+
13+
#include "iamf/cli/proto_conversion/proto_to_obu/metadata_obu_generator.h"
14+
15+
#include <list>
16+
#include <utility>
17+
18+
#include "absl/status/status.h"
19+
#include "absl/status/statusor.h"
20+
#include "iamf/cli/proto/metadata_obu.pb.h"
21+
#include "iamf/obu/metadata_obu.h"
22+
#include "iamf/obu/obu_header.h"
23+
24+
namespace iamf_tools {
25+
26+
namespace {
27+
28+
MetadataObu CreateMetadataITUTT35(
29+
const iamf_tools_cli_proto::MetadataITUTT35& metadata_itu_t_t35) {
30+
MetadataITUTT35 metadata_itu_t_t35_obu;
31+
metadata_itu_t_t35_obu.itu_t_t35_country_code =
32+
metadata_itu_t_t35.itu_t_t35_country_code();
33+
if (metadata_itu_t_t35.has_itu_t_t35_country_code_extension_byte() &&
34+
metadata_itu_t_t35.itu_t_t35_country_code() == 0xff) {
35+
metadata_itu_t_t35_obu.itu_t_t35_country_code_extension_byte =
36+
metadata_itu_t_t35.itu_t_t35_country_code_extension_byte();
37+
}
38+
metadata_itu_t_t35_obu.itu_t_t35_payload_bytes = {
39+
metadata_itu_t_t35.itu_t_t35_payload_bytes().begin(),
40+
metadata_itu_t_t35.itu_t_t35_payload_bytes().end()};
41+
return MetadataObu::Create(ObuHeader(kObuIaMetadata),
42+
std::move(metadata_itu_t_t35_obu));
43+
}
44+
45+
using ::iamf_tools::MetadataIamfTags;
46+
MetadataObu CreateMetadataIamfTags(
47+
const iamf_tools_cli_proto::MetadataIamfTags& metadata_iamf_tags) {
48+
MetadataIamfTags metadata_iamf_tags_obu;
49+
for (const auto& tag : metadata_iamf_tags.tags()) {
50+
metadata_iamf_tags_obu.tags.push_back(
51+
{.tag_name = tag.name(), .tag_value = tag.value()});
52+
}
53+
return MetadataObu::Create(ObuHeader(kObuIaMetadata),
54+
std::move(metadata_iamf_tags_obu));
55+
}
56+
57+
absl::StatusOr<MetadataObu> CreateMetadataObu(
58+
const iamf_tools_cli_proto::MetadataObuMetadata& metadata_obu_metadata) {
59+
if (metadata_obu_metadata.has_metadata_itu_t_t35()) {
60+
return CreateMetadataITUTT35(metadata_obu_metadata.metadata_itu_t_t35());
61+
} else if (metadata_obu_metadata.has_metadata_iamf_tags()) {
62+
return CreateMetadataIamfTags(metadata_obu_metadata.metadata_iamf_tags());
63+
} else {
64+
return absl::InvalidArgumentError(
65+
"MetadataObuMetadata must have one of the metadata fields set.");
66+
}
67+
return absl::OkStatus();
68+
}
69+
70+
} // namespace
71+
72+
absl::Status MetadataObuGenerator::Generate(
73+
std::list<MetadataObu>& metadata_obus) {
74+
for (const auto& metadata_obu_metadata : metadata_obu_metadata_) {
75+
absl::StatusOr<MetadataObu> metadata_obu =
76+
CreateMetadataObu(metadata_obu_metadata);
77+
if (!metadata_obu.ok()) {
78+
return metadata_obu.status();
79+
}
80+
metadata_obus.push_back(*std::move(metadata_obu));
81+
}
82+
return absl::OkStatus();
83+
}
84+
85+
} // namespace iamf_tools
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright (c) 2026, Alliance for Open Media. All rights reserved
3+
*
4+
* This source code is subject to the terms of the BSD 3-Clause Clear License
5+
* and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear
6+
* License was not distributed with this source code in the LICENSE file, you
7+
* can obtain it at www.aomedia.org/license/software-license/bsd-3-c-c. If the
8+
* Alliance for Open Media Patent License 1.0 was not distributed with this
9+
* source code in the PATENTS file, you can obtain it at
10+
* www.aomedia.org/license/patent.
11+
*/
12+
#ifndef CLI_PROTO_CONVERSION_PROTO_TO_OBU_METADATA_OBU_GENERATOR_H_
13+
#define CLI_PROTO_CONVERSION_PROTO_TO_OBU_METADATA_OBU_GENERATOR_H_
14+
15+
#include <list>
16+
17+
#include "absl/status/status.h"
18+
#include "iamf/cli/proto/metadata_obu.pb.h"
19+
#include "iamf/obu/metadata_obu.h"
20+
#include "src/google/protobuf/repeated_ptr_field.h"
21+
22+
namespace iamf_tools {
23+
24+
class MetadataObuGenerator {
25+
public:
26+
/*!\brief Constructor.
27+
* \param metadata_obu_metadata Input Metadata OBU metadata.
28+
*/
29+
MetadataObuGenerator(
30+
const ::google::protobuf::RepeatedPtrField<
31+
iamf_tools_cli_proto::MetadataObuMetadata>& metadata_obu_metadata)
32+
: metadata_obu_metadata_(metadata_obu_metadata) {}
33+
34+
/*!\brief Generates a list of Metadata OBUs from the input metadata.
35+
*
36+
* \param metadata_obus Output list of Metadata OBUs.
37+
* \return `absl::OkStatus()` on success. A specific status on failure.
38+
*/
39+
absl::Status Generate(std::list<MetadataObu>& metadata_obus);
40+
41+
private:
42+
const ::google::protobuf::RepeatedPtrField<
43+
iamf_tools_cli_proto::MetadataObuMetadata>
44+
metadata_obu_metadata_;
45+
};
46+
47+
} // namespace iamf_tools
48+
49+
#endif // CLI_PROTO_CONVERSION_PROTO_TO_OBU_METADATA_OBU_GENERATOR_H_

iamf/cli/proto_conversion/proto_to_obu/tests/BUILD

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,18 @@ cc_test(
152152
],
153153
)
154154

155+
cc_test(
156+
name = "metadata_obu_generator_test",
157+
srcs = ["metadata_obu_generator_test.cc"],
158+
deps = [
159+
"//iamf/cli/proto:metadata_obu_cc_proto",
160+
"//iamf/cli/proto_conversion/proto_to_obu:metadata_obu_generator",
161+
"//iamf/obu:metadata_obu",
162+
"@com_google_googletest//:gtest_main",
163+
"@com_google_protobuf//:protobuf",
164+
],
165+
)
166+
155167
cc_test(
156168
name = "mix_presentation_generator_test",
157169
srcs = ["mix_presentation_generator_test.cc"],
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
/*
2+
* Copyright (c) 2026, Alliance for Open Media. All rights reserved
3+
*
4+
* This source code is subject to the terms of the BSD 3-Clause Clear License
5+
* and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear
6+
* License was not distributed with this source code in the LICENSE file, you
7+
* can obtain it at www.aomedia.org/license/software-license/bsd-3-c-c. If the
8+
* Alliance for Open Media Patent License 1.0 was not distributed with this
9+
* source code in the PATENTS file, you can obtain it at
10+
* www.aomedia.org/license/patent.
11+
*/
12+
13+
#include "iamf/cli/proto_conversion/proto_to_obu/metadata_obu_generator.h"
14+
15+
#include <cstdint>
16+
#include <list>
17+
#include <variant>
18+
#include <vector>
19+
20+
#include "gmock/gmock.h"
21+
#include "gtest/gtest.h"
22+
#include "iamf/cli/proto/metadata_obu.pb.h"
23+
#include "iamf/obu/metadata_obu.h"
24+
#include "src/google/protobuf/repeated_ptr_field.h"
25+
26+
namespace iamf_tools {
27+
namespace {
28+
29+
using ::absl_testing::IsOk;
30+
using ::iamf_tools_cli_proto::MetadataObuMetadata;
31+
using ::testing::ElementsAre;
32+
using ::testing::FieldsAre;
33+
using ::testing::Not;
34+
35+
TEST(MetadataObuGeneratorTest, EmptyInputGeneratesEmptyOutput) {
36+
google::protobuf::RepeatedPtrField<MetadataObuMetadata> metadata_obu_metadata;
37+
MetadataObuGenerator generator(metadata_obu_metadata);
38+
std::list<MetadataObu> metadata_obus;
39+
40+
EXPECT_THAT(generator.Generate(metadata_obus), IsOk());
41+
EXPECT_TRUE(metadata_obus.empty());
42+
}
43+
44+
TEST(MetadataObuGeneratorTest, FailsWhenNoMetadataIsSet) {
45+
google::protobuf::RepeatedPtrField<MetadataObuMetadata> metadata_obu_metadata;
46+
metadata_obu_metadata.Add();
47+
MetadataObuGenerator generator(metadata_obu_metadata);
48+
std::list<MetadataObu> metadata_obus;
49+
50+
EXPECT_THAT(generator.Generate(metadata_obus), Not(IsOk()));
51+
}
52+
53+
TEST(MetadataObuGeneratorTest, GeneratesMetadataItuT35) {
54+
google::protobuf::RepeatedPtrField<MetadataObuMetadata> metadata_obu_metadata;
55+
auto* metadata = metadata_obu_metadata.Add();
56+
auto* itu_t_t35 = metadata->mutable_metadata_itu_t_t35();
57+
itu_t_t35->set_itu_t_t35_country_code(1);
58+
itu_t_t35->set_itu_t_t35_payload_bytes("abc");
59+
60+
MetadataObuGenerator generator(metadata_obu_metadata);
61+
std::list<MetadataObu> metadata_obus;
62+
63+
EXPECT_THAT(generator.Generate(metadata_obus), IsOk());
64+
EXPECT_EQ(metadata_obus.size(), 1);
65+
66+
auto generated_metadata =
67+
std::get_if<MetadataITUTT35>(&metadata_obus.front().GetMetadataVariant());
68+
ASSERT_THAT(generated_metadata, Not(testing::IsNull()));
69+
70+
EXPECT_EQ(generated_metadata->itu_t_t35_country_code, 1);
71+
EXPECT_FALSE(
72+
generated_metadata->itu_t_t35_country_code_extension_byte.has_value());
73+
EXPECT_EQ(generated_metadata->itu_t_t35_payload_bytes,
74+
std::vector<uint8_t>({'a', 'b', 'c'}));
75+
}
76+
77+
TEST(MetadataObuGeneratorTest, GeneratesMetadataItuT35WithExtension) {
78+
google::protobuf::RepeatedPtrField<MetadataObuMetadata> metadata_obu_metadata;
79+
auto* metadata = metadata_obu_metadata.Add();
80+
auto* itu_t_t35 = metadata->mutable_metadata_itu_t_t35();
81+
itu_t_t35->set_itu_t_t35_country_code(0xff);
82+
itu_t_t35->set_itu_t_t35_country_code_extension_byte(2);
83+
itu_t_t35->set_itu_t_t35_payload_bytes("abc");
84+
85+
MetadataObuGenerator generator(metadata_obu_metadata);
86+
std::list<MetadataObu> metadata_obus;
87+
88+
EXPECT_THAT(generator.Generate(metadata_obus), IsOk());
89+
EXPECT_EQ(metadata_obus.size(), 1);
90+
91+
auto generated_metadata =
92+
std::get_if<MetadataITUTT35>(&metadata_obus.front().GetMetadataVariant());
93+
ASSERT_THAT(generated_metadata, Not(testing::IsNull()));
94+
95+
EXPECT_EQ(generated_metadata->itu_t_t35_country_code, 0xff);
96+
EXPECT_EQ(generated_metadata->itu_t_t35_country_code_extension_byte, 2);
97+
EXPECT_EQ(generated_metadata->itu_t_t35_payload_bytes,
98+
std::vector<uint8_t>({'a', 'b', 'c'}));
99+
}
100+
101+
TEST(MetadataObuGeneratorTest, GeneratesMetadataIamfTags) {
102+
google::protobuf::RepeatedPtrField<MetadataObuMetadata> metadata_obu_metadata;
103+
auto* metadata = metadata_obu_metadata.Add();
104+
auto* iamf_tags = metadata->mutable_metadata_iamf_tags();
105+
auto* tag = iamf_tags->add_tags();
106+
tag->set_name("key");
107+
tag->set_value("value");
108+
109+
MetadataObuGenerator generator(metadata_obu_metadata);
110+
std::list<MetadataObu> metadata_obus;
111+
112+
EXPECT_THAT(generator.Generate(metadata_obus), IsOk());
113+
EXPECT_EQ(metadata_obus.size(), 1);
114+
115+
auto generated_metadata = std::get_if<MetadataIamfTags>(
116+
&metadata_obus.front().GetMetadataVariant());
117+
ASSERT_THAT(generated_metadata, Not(testing::IsNull()));
118+
EXPECT_THAT(generated_metadata->tags, ElementsAre(FieldsAre("key", "value")));
119+
}
120+
121+
TEST(MetadataObuGeneratorTest, GeneratesMultipleMetadataObus) {
122+
google::protobuf::RepeatedPtrField<MetadataObuMetadata> metadata_obu_metadata;
123+
124+
// Add a MetadataITUTT35 OBU.
125+
auto* metadata_itu_t_t35 =
126+
metadata_obu_metadata.Add()->mutable_metadata_itu_t_t35();
127+
metadata_itu_t_t35->set_itu_t_t35_country_code(1);
128+
metadata_itu_t_t35->set_itu_t_t35_payload_bytes("abc");
129+
130+
// Add a MetadataIamfTags OBU.
131+
auto* iamf_tags = metadata_obu_metadata.Add()->mutable_metadata_iamf_tags();
132+
auto* tag = iamf_tags->add_tags();
133+
tag->set_name("key");
134+
tag->set_value("value");
135+
136+
MetadataObuGenerator generator(metadata_obu_metadata);
137+
std::list<MetadataObu> metadata_obus;
138+
139+
EXPECT_THAT(generator.Generate(metadata_obus), IsOk());
140+
EXPECT_EQ(metadata_obus.size(), 2);
141+
142+
// Validate the first OBU.
143+
auto generated_metadata_itu_t_t35 =
144+
std::get_if<MetadataITUTT35>(&metadata_obus.front().GetMetadataVariant());
145+
ASSERT_THAT(generated_metadata_itu_t_t35, Not(testing::IsNull()));
146+
EXPECT_EQ(generated_metadata_itu_t_t35->itu_t_t35_country_code, 1);
147+
EXPECT_FALSE(generated_metadata_itu_t_t35
148+
->itu_t_t35_country_code_extension_byte.has_value());
149+
EXPECT_EQ(generated_metadata_itu_t_t35->itu_t_t35_payload_bytes,
150+
std::vector<uint8_t>({'a', 'b', 'c'}));
151+
152+
// Validate the second OBU.
153+
auto generated_metadata_iamf_tags =
154+
std::get_if<MetadataIamfTags>(&metadata_obus.back().GetMetadataVariant());
155+
ASSERT_THAT(generated_metadata_iamf_tags, Not(testing::IsNull()));
156+
EXPECT_THAT(generated_metadata_iamf_tags->tags,
157+
ElementsAre(FieldsAre("key", "value")));
158+
}
159+
160+
} // namespace
161+
} // namespace iamf_tools

0 commit comments

Comments
 (0)