1 #include "common/common_pch.h"
2
3 #include <unordered_map>
4
5 #include "common/bluray/util.h"
6 #include "common/debugging.h"
7 #include "common/id_info.h"
8 #include "common/mm_file_io.h"
9 #include "common/mm_mpls_multi_file_io.h"
10 #include "common/mm_mpls_multi_file_io_p.h"
11 #include "common/path.h"
12 #include "common/strings/formatting.h"
13
14 namespace {
15 debugging_option_c s_debug{"mpls|mpls_multi_io"};
16 }
17
mm_mpls_multi_file_io_c(std::vector<std::filesystem::path> const & file_names,std::string const & display_file_name,mtx::bluray::mpls::parser_cptr const & mpls_parser)18 mm_mpls_multi_file_io_c::mm_mpls_multi_file_io_c(std::vector<std::filesystem::path> const &file_names,
19 std::string const &display_file_name,
20 mtx::bluray::mpls::parser_cptr const &mpls_parser)
21 : mm_file_io_c{*new mm_mpls_multi_file_io_private_c{file_names, display_file_name, mpls_parser}}
22 {
23 }
24
mm_mpls_multi_file_io_c(mm_mpls_multi_file_io_private_c & p)25 mm_mpls_multi_file_io_c::mm_mpls_multi_file_io_c(mm_mpls_multi_file_io_private_c &p)
26 : mm_file_io_c{p}
27 {
28 }
29
~mm_mpls_multi_file_io_c()30 mm_mpls_multi_file_io_c::~mm_mpls_multi_file_io_c() { // NOLINT(modernize-use-equals-default) due to pimpl idiom requiring explicit dtor declaration somewhere
31 }
32
33 std::vector<mtx::bluray::mpls::chapter_t> const &
get_chapters() const34 mm_mpls_multi_file_io_c::get_chapters()
35 const {
36 return p_func()->mpls_parser->get_chapters();
37 }
38
39 mm_io_cptr
open_multi(std::string const & display_file_name)40 mm_mpls_multi_file_io_c::open_multi(std::string const &display_file_name) {
41 try {
42 mm_file_io_c in{display_file_name};
43 return open_multi(in);
44 } catch (mtx::mm_io::exception &) {
45 return mm_io_cptr{};
46 }
47 }
48
49 mm_io_cptr
open_multi(mm_io_c & in)50 mm_mpls_multi_file_io_c::open_multi(mm_io_c &in) {
51 auto mpls_parser = std::make_shared<mtx::bluray::mpls::parser_c>();
52
53 if (!mpls_parser->parse(in) || mpls_parser->get_playlist().items.empty()) {
54 mxdebug_if(s_debug, fmt::format("Not handling because {0}\n", mpls_parser->is_ok() ? "playlist is empty" : "parser not OK"));
55 return mm_io_cptr{};
56 }
57
58 std::vector<std::filesystem::path> file_names;
59
60 for (auto const &item : mpls_parser->get_playlist().items) {
61 auto file = mtx::bluray::find_other_file(mtx::fs::to_path(in.get_file_name()), mtx::fs::to_path("STREAM") / mtx::fs::to_path(fmt::format("{0}.{1}", item.clip_id, balg::to_lower_copy(item.codec_id))));
62 if (file.empty())
63 file = mtx::bluray::find_other_file(mtx::fs::to_path(in.get_file_name()), mtx::fs::to_path("STREAM") / mtx::fs::to_path(fmt::format("{0}.{1}", item.clip_id, "m2ts")));
64
65 if (!file.empty())
66 file_names.push_back(file);
67
68 mxdebug_if(s_debug, fmt::format("Item clip ID: {0} codec ID: {1}: have file? {2} file: {3}\n", item.clip_id, item.codec_id, !file.empty(), file.u8string()));
69 }
70
71 mxdebug_if(s_debug, fmt::format("Number of files left: {0}\n", file_names.size()));
72
73 if (file_names.empty())
74 return mm_io_cptr{};
75
76 return mm_io_cptr{new mm_mpls_multi_file_io_c{file_names, file_names[0].u8string(), mpls_parser}};
77 }
78
79 void
create_verbose_identification_info(mtx::id::info_c & info)80 mm_mpls_multi_file_io_c::create_verbose_identification_info(mtx::id::info_c &info) {
81 auto p = p_func();
82
83 info.add(mtx::id::playlist, true);
84 info.add(mtx::id::playlist_duration, p->mpls_parser->get_playlist().duration.to_ns());
85 info.add(mtx::id::playlist_size, p->total_size);
86 info.add(mtx::id::playlist_chapters, p->mpls_parser->get_chapters().size());
87
88 auto file_names = nlohmann::json::array();
89 for (auto &file : p->files)
90 file_names.push_back(file.u8string());
91
92 info.add(mtx::id::playlist_file, file_names);
93 }
94
95 std::string
get_file_name() const96 mm_mpls_multi_file_io_c::get_file_name()
97 const {
98 return p_func()->display_file_name;
99 }
100
101 std::vector<std::filesystem::path> const &
get_file_names() const102 mm_mpls_multi_file_io_c::get_file_names()
103 const {
104 return p_func()->files;
105 }
106
107 mtx::bluray::mpls::parser_c const &
get_mpls_parser() const108 mm_mpls_multi_file_io_c::get_mpls_parser()
109 const {
110 return *p_func()->mpls_parser;
111 }
112