1 /*
2 * Copyright (c) 2024, 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 <cstdint>
14 #include <cstdlib>
15 #include <filesystem>
16 #include <fstream>
17 #include <ios>
18 #include <string>
19
20 #include "absl/flags/flag.h"
21 #include "absl/flags/parse.h"
22 #include "absl/flags/usage.h"
23 #include "absl/log/log.h"
24 #include "iamf/cli/adm_to_user_metadata/app/adm_to_user_metadata_main_lib.h"
25 #include "iamf/cli/adm_to_user_metadata/iamf/user_metadata_generator.h"
26 #include "iamf/obu/ia_sequence_header.h"
27
28 // Flags to control the input ADM BWF file.
29 ABSL_FLAG(std::string, adm_filename, "", "Raw input WAV file in ADM format");
30 // Flags to control the output user metadata.
31 ABSL_FLAG(int32_t, importance_threshold, 0,
32 "Importance value used to skip an audioObject. Clamped to [0, 10]");
33 ABSL_FLAG(std::string, profile_version, "base",
34 "IAMF version to be used : (base/enhanced)");
35 ABSL_FLAG(int32_t, frame_duration_ms, 10, "Frame duration in milliseconds");
36 // Flags to control output files type and location.
37 ABSL_FLAG(bool, write_binary_proto, true,
38 "Whether to write the output as a binary proto or textproto");
39 ABSL_FLAG(std::string, output_file_path, "",
40 "Path to write output spliced wav files and user metadata to");
41
main(int32_t argc,char * argv[])42 int main(int32_t argc, char* argv[]) {
43 absl::SetProgramUsageMessage(argv[0]);
44 absl::ParseCommandLine(argc, argv);
45
46 // Log the IAMF version flag
47 using enum iamf_tools::ProfileVersion;
48 std::string iamf_profile = absl::GetFlag(FLAGS_profile_version);
49 iamf_tools::ProfileVersion profile_version;
50 if (iamf_profile == "enhanced") {
51 profile_version = kIamfBaseEnhancedProfile;
52 } else if (iamf_profile == "base") {
53 profile_version = kIamfBaseProfile;
54 } else {
55 LOG(ERROR) << "Invalid IAMF profile version: " << iamf_profile
56 << ". Please provide a valid profile version with "
57 "--profile_version.";
58 return EXIT_FAILURE;
59 }
60 LOG(INFO) << "Using profile version: " << iamf_profile << ".";
61
62 const std::string adm_filename(absl::GetFlag(FLAGS_adm_filename));
63 if (adm_filename.empty() || !std::filesystem::exists(adm_filename)) {
64 LOG(ERROR) << "ADM filename was not provided or could not be opened. "
65 "Please provide a valid filename with --adm_filename.";
66 return EXIT_FAILURE;
67 }
68
69 // Get the user metadata and write the wav files.
70 const std::string file_prefix =
71 std::filesystem::path(adm_filename).stem().string();
72 const std::filesystem::path output_file_path(
73 absl::GetFlag(FLAGS_output_file_path));
74 std::ifstream adm_file(adm_filename, std::ios::binary | std::ios::in);
75
76 const auto& user_metadata =
77 iamf_tools::adm_to_user_metadata::GenerateUserMetadataAndSpliceWavFiles(
78 file_prefix, absl::GetFlag(FLAGS_frame_duration_ms),
79 absl::GetFlag(FLAGS_importance_threshold), output_file_path, adm_file,
80 profile_version);
81
82 if (!user_metadata.ok()) {
83 LOG(ERROR) << user_metadata.status();
84 return user_metadata.status().raw_code();
85 }
86
87 // Write the user metadata proto file.
88 if (const auto& status =
89 iamf_tools::adm_to_user_metadata::UserMetadataGenerator::
90 WriteUserMetadataToFile(absl::GetFlag(FLAGS_write_binary_proto),
91 output_file_path, *user_metadata);
92 !status.ok()) {
93 LOG(ERROR) << status;
94 return status.raw_code();
95 }
96
97 return EXIT_SUCCESS;
98 }
99