1 /*
2  * Copyright (c) 2023, 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 #include "iamf/cli/proto_conversion/proto_to_obu/arbitrary_obu_generator.h"
13 
14 #include <algorithm>
15 #include <cstdint>
16 #include <list>
17 #include <optional>
18 #include <vector>
19 
20 #include "absl/base/no_destructor.h"
21 #include "absl/log/log.h"
22 #include "absl/status/status.h"
23 #include "absl/strings/str_cat.h"
24 #include "iamf/cli/proto/arbitrary_obu.pb.h"
25 #include "iamf/cli/proto_conversion/lookup_tables.h"
26 #include "iamf/cli/proto_conversion/proto_utils.h"
27 #include "iamf/common/utils/macros.h"
28 #include "iamf/common/utils/map_utils.h"
29 #include "iamf/obu/arbitrary_obu.h"
30 #include "iamf/obu/obu_header.h"
31 
32 namespace iamf_tools {
33 
34 namespace {
CopyArbitraryObuType(iamf_tools_cli_proto::ArbitraryObuType arbitrary_obu_type,ObuType & output_obu_type)35 absl::Status CopyArbitraryObuType(
36     iamf_tools_cli_proto::ArbitraryObuType arbitrary_obu_type,
37     ObuType& output_obu_type) {
38   static const auto kProtoArbitraryObuTypeToObuType = BuildStaticMapFromPairs(
39       LookupTables::kProtoArbitraryObuTypeAndInternalObuTypes);
40 
41   return CopyFromMap(*kProtoArbitraryObuTypeToObuType, arbitrary_obu_type,
42                      "Internal version of proto `ArbitraryObuType`",
43                      output_obu_type);
44 }
45 }  // namespace
46 
Generate(std::list<ArbitraryObu> & arbitrary_obus)47 absl::Status ArbitraryObuGenerator::Generate(
48     std::list<ArbitraryObu>& arbitrary_obus) {
49   // Arbitrary OBU-related parameters.
50   for (const auto& arbitrary_obu_metadata : arbitrary_obu_metadata_) {
51     ObuType obu_type;
52     RETURN_IF_NOT_OK(
53         CopyArbitraryObuType(arbitrary_obu_metadata.obu_type(), obu_type));
54 
55     ArbitraryObu::InsertionHook insertion_hook;
56     std::optional<int64_t> insertion_tick = std::nullopt;
57     switch (arbitrary_obu_metadata.insertion_hook()) {
58       using enum iamf_tools_cli_proto::InsertionHook;
59       using enum ArbitraryObu::InsertionHook;
60       case INSERTION_HOOK_BEFORE_DESCRIPTORS:
61         insertion_hook = kInsertionHookBeforeDescriptors;
62         break;
63       case INSERTION_HOOK_AFTER_DESCRIPTORS:
64         insertion_hook = kInsertionHookAfterDescriptors;
65         break;
66       case INSERTION_HOOK_AFTER_IA_SEQUENCE_HEADER:
67         insertion_hook = kInsertionHookAfterIaSequenceHeader;
68         break;
69       case INSERTION_HOOK_AFTER_CODEC_CONFIGS:
70         insertion_hook = kInsertionHookAfterCodecConfigs;
71         break;
72       case INSERTION_HOOK_AFTER_AUDIO_ELEMENTS:
73         insertion_hook = kInsertionHookAfterAudioElements;
74         break;
75       case INSERTION_HOOK_AFTER_MIX_PRESENTATIONS:
76         insertion_hook = kInsertionHookAfterMixPresentations;
77         break;
78       case INSERTION_HOOK_BEFORE_PARAMETER_BLOCKS_AT_TICK:
79         insertion_hook = kInsertionHookBeforeParameterBlocksAtTick;
80         insertion_tick = arbitrary_obu_metadata.insertion_tick();
81         break;
82       case INSERTION_HOOK_AFTER_PARAMETER_BLOCKS_AT_TICK:
83         insertion_hook = kInsertionHookAfterParameterBlocksAtTick;
84         insertion_tick = arbitrary_obu_metadata.insertion_tick();
85         break;
86       case INSERTION_HOOK_AFTER_AUDIO_FRAMES_AT_TICK:
87         insertion_hook = kInsertionHookAfterAudioFramesAtTick;
88         insertion_tick = arbitrary_obu_metadata.insertion_tick();
89         break;
90       default:
91         return absl::InvalidArgumentError(
92             absl::StrCat("Unknown insertion hook= ",
93                          arbitrary_obu_metadata.insertion_hook()));
94     }
95 
96     std::vector<uint8_t> payload(arbitrary_obu_metadata.payload().size());
97     std::transform(arbitrary_obu_metadata.payload().begin(),
98                    arbitrary_obu_metadata.payload().end(), payload.begin(),
99                    [](char c) { return static_cast<uint8_t>(c); });
100 
101     arbitrary_obus.emplace_back(
102         obu_type, GetHeaderFromMetadata(arbitrary_obu_metadata.obu_header()),
103         payload, insertion_hook, insertion_tick,
104         arbitrary_obu_metadata.invalidates_bitstream());
105   }
106 
107   // Examine arbitrary OBUs.
108   for (const auto& arbitrary_obu : arbitrary_obus) {
109     arbitrary_obu.PrintObu();
110   }
111   return absl::OkStatus();
112 }
113 
114 }  // namespace iamf_tools
115