vmaf_sys/extras.rs
1//! Extra stuff from the libvmaf git repo that you’ll probably need.
2use std::path::PathBuf;
3use lazy_static::lazy_static;
4use tempfile::{NamedTempFile, TempDir};
5
6
7///////////////////////////////////////////////////////////////////////////////
8// CORE
9///////////////////////////////////////////////////////////////////////////////
10
11const buildtype_docs_only_stub_msg: &'static str =
12 "stub for docs.rs only (when cargo feature = 'buildtype-docs-only')";
13
14/// Returns the string contents of the VMAF 'default' model that this library
15/// was compiled with.
16///
17/// Regarding the return tuple. I have no idea what the first is, in
18/// relation to the second. Yet the first component (in the tuple) is
19/// what you give VMAF (dumped to a file).
20///
21/// The second is also for VMAF, but it looks for it with the same file
22/// path as the first, except ending with a `.model` extension. There is
23/// no documentation about this, yet it seems to be what it wants at
24/// runtime.
25#[cfg(not(feature="buildtype-docs-only"))]
26pub fn get_vmaf_def_model() -> (&'static str, &'static str) {
27 let x = include_str!(concat!(env!("OUT_DIR"), "/vmaf/release/vmaf_v0.6.1.pkl"));
28 let y = include_str!(concat!(env!("OUT_DIR"), "/vmaf/release/vmaf_v0.6.1.pkl.model"));
29 (x, y)
30}
31
32/// Returns the string contents of the VMAF '4K' model that this library
33/// was compiled with.
34///
35/// Regarding the return tuple. I have no idea what the first is, in
36/// relation to the second. Yet the first component (in the tuple) is
37/// what you give VMAF (dumped to a file).
38///
39/// The second is also for VMAF, but it looks for it with the same file
40/// path as the first, except ending with a `.model` extension. There is
41/// no documentation about this, yet it seems to be what it wants at
42/// runtime.
43#[cfg(not(feature="buildtype-docs-only"))]
44pub fn get_vmaf_4k_model() -> (&'static str, &'static str) {
45 let x = include_str!(concat!(env!("OUT_DIR"), "/vmaf/release/vmaf_4k_v0.6.1.pkl"));
46 let y = include_str!(concat!(env!("OUT_DIR"), "/vmaf/release/vmaf_4k_v0.6.1.pkl.model"));
47 (x, y)
48}
49
50/// Returns the string contents of the VMAF 'default' model that this library
51/// was compiled with.
52///
53/// Regarding the return tuple. I have no idea what the first is, in
54/// relation to the second. Yet the first component (in the tuple) is
55/// what you give VMAF (dumped to a file).
56///
57/// The second is also for VMAF, but it looks for it with the same file
58/// path as the first, except ending with a `.model` extension. There is
59/// no documentation about this, yet it seems to be what it wants at
60/// runtime.
61#[cfg(feature="buildtype-docs-only")]
62pub fn get_vmaf_def_model() -> (&'static str, &'static str) {panic!(buildtype_docs_only_stub_msg)}
63
64
65/// Returns the string contents of the VMAF '4K' model that this library
66/// was compiled with.
67///
68/// Regarding the return tuple. I have no idea what the first is, in
69/// relation to the second. Yet the first component (in the tuple) is
70/// what you give VMAF (dumped to a file).
71///
72/// The second is also for VMAF, but it looks for it with the same file
73/// path as the first, except ending with a `.model` extension. There is
74/// no documentation about this, yet it seems to be what it wants at
75/// runtime.
76#[cfg(feature="buildtype-docs-only")]
77pub fn get_vmaf_4k_model() -> (&'static str, &'static str) {panic!(buildtype_docs_only_stub_msg)}
78
79
80///////////////////////////////////////////////////////////////////////////////
81// HIGHER LEVEL UTILS - FILE-SYSTEM
82///////////////////////////////////////////////////////////////////////////////
83
84/// Internal - created by the lazy static macro.
85struct TmpVmafModelFile {
86 /// Keep this in memory, when it gets ‘Dropped’, it’ll remove the tmp
87 /// directory.
88 dir: TempDir,
89 path: PathBuf,
90}
91
92lazy_static! {
93 static ref TMP_VMAF_DEF_MODEL_FILE: TmpVmafModelFile = {
94 // INIT DIR
95 let mut root_dir = TempDir::new().expect("TempDir::new() failed");
96 // FILE PATHS
97 let mut model_pkg = PathBuf::from(root_dir.path())
98 .join("vmaf_v0.6.1.pkl");
99 let mut model_other = PathBuf::from(root_dir.path())
100 .join("vmaf_v0.6.1.pkl.model");
101 // FILL FILES
102 let (pkg, other) = get_vmaf_def_model();
103 std::fs::write(&model_pkg, pkg).expect("TmpVmafModelFile::new_tmp");
104 std::fs::write(&model_other, other).expect("TmpVmafModelFile::new_tmp");
105 // DONE
106 TmpVmafModelFile {
107 dir: root_dir,
108 path: model_pkg,
109 }
110 };
111
112 static ref TMP_VMAF_4K_MODEL_FILE: TmpVmafModelFile = {
113 // INIT DIR
114 let mut root_dir = TempDir::new().expect("TempDir::new() failed");
115 // FILE PATHS
116 let mut model_pkg = PathBuf::from(root_dir.path())
117 .join("vmaf_4k_v0.6.1.pkl");
118 let mut model_other = PathBuf::from(root_dir.path())
119 .join("vmaf_4k_v0.6.1.pkl.model");
120 // FILL FILES
121 let (pkg, other) = get_vmaf_4k_model();
122 std::fs::write(&model_pkg, pkg).expect("TmpVmafModelFile::new_tmp");
123 std::fs::write(&model_other, other).expect("TmpVmafModelFile::new_tmp");
124 // DONE
125 TmpVmafModelFile {
126 dir: root_dir,
127 path: model_pkg,
128 }
129 };
130}
131
132
133/// The VMAF default model.
134///
135/// This internally creates a temporary file that lasts for the duration of th
136/// process. The temporary file is automatically removed at the end of the
137/// process (or presumably by the OS following a reboot).
138///
139/// This is a relatively cheap operation in the sense that this only happens
140/// once. All subsequent calls point to the original file (i.e. this is an
141/// idempotent operation).
142pub fn get_def_model_path() -> PathBuf {
143 TMP_VMAF_DEF_MODEL_FILE.path.clone()
144}
145
146
147/// The VMAF 4K model.
148///
149/// This internally creates a temporary file that lasts for the duration of th
150/// process. The temporary file is automatically removed at the end of the
151/// process (or presumably by the OS following a reboot).
152///
153/// This is a relatively cheap operation in the sense that this only happens
154/// once. All subsequent calls point to the original file (i.e. this is an
155/// idempotent operation).
156pub fn get_4k_model_path() -> PathBuf {
157 TMP_VMAF_4K_MODEL_FILE.path.clone()
158}