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}