1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
//! Extra stuff from the libvmaf git repo that you’ll probably need.
use std::path::PathBuf;
use lazy_static::lazy_static;
use tempfile::{NamedTempFile, TempDir};


///////////////////////////////////////////////////////////////////////////////
// CORE
///////////////////////////////////////////////////////////////////////////////

const buildtype_docs_only_stub_msg: &'static str =
    "stub for docs.rs only (when cargo feature = 'buildtype-docs-only')";

/// Returns the string contents of the VMAF 'default' model that this library
/// was compiled with. 
/// 
/// Regarding the return tuple. I have no idea what the first is, in
/// relation to the second. Yet the first component (in the tuple) is
/// what you give VMAF (dumped to a file).
/// 
/// The second is also for VMAF, but it looks for it with the same file
/// path as the first, except ending with a `.model` extension. There is
/// no documentation about this, yet it seems to be what it wants at
/// runtime. 
#[cfg(not(feature="buildtype-docs-only"))]
pub fn get_vmaf_def_model() -> (&'static str, &'static str) {
    let x = include_str!(concat!(env!("OUT_DIR"), "/vmaf/release/vmaf_v0.6.1.pkl"));
    let y = include_str!(concat!(env!("OUT_DIR"), "/vmaf/release/vmaf_v0.6.1.pkl.model"));
    (x, y)
}

/// Returns the string contents of the VMAF '4K' model that this library
/// was compiled with. 
/// 
/// Regarding the return tuple. I have no idea what the first is, in
/// relation to the second. Yet the first component (in the tuple) is
/// what you give VMAF (dumped to a file).
/// 
/// The second is also for VMAF, but it looks for it with the same file
/// path as the first, except ending with a `.model` extension. There is
/// no documentation about this, yet it seems to be what it wants at
/// runtime. 
#[cfg(not(feature="buildtype-docs-only"))]
pub fn get_vmaf_4k_model() -> (&'static str, &'static str) {
    let x = include_str!(concat!(env!("OUT_DIR"), "/vmaf/release/vmaf_4k_v0.6.1.pkl"));
    let y = include_str!(concat!(env!("OUT_DIR"), "/vmaf/release/vmaf_4k_v0.6.1.pkl.model"));
    (x, y)
}

/// Returns the string contents of the VMAF 'default' model that this library
/// was compiled with. 
/// 
/// Regarding the return tuple. I have no idea what the first is, in
/// relation to the second. Yet the first component (in the tuple) is
/// what you give VMAF (dumped to a file).
/// 
/// The second is also for VMAF, but it looks for it with the same file
/// path as the first, except ending with a `.model` extension. There is
/// no documentation about this, yet it seems to be what it wants at
/// runtime. 
#[cfg(feature="buildtype-docs-only")]
pub fn get_vmaf_def_model() -> (&'static str, &'static str) {panic!(buildtype_docs_only_stub_msg)}


/// Returns the string contents of the VMAF '4K' model that this library
/// was compiled with. 
/// 
/// Regarding the return tuple. I have no idea what the first is, in
/// relation to the second. Yet the first component (in the tuple) is
/// what you give VMAF (dumped to a file).
/// 
/// The second is also for VMAF, but it looks for it with the same file
/// path as the first, except ending with a `.model` extension. There is
/// no documentation about this, yet it seems to be what it wants at
/// runtime. 
#[cfg(feature="buildtype-docs-only")]
pub fn get_vmaf_4k_model() -> (&'static str, &'static str) {panic!(buildtype_docs_only_stub_msg)}


///////////////////////////////////////////////////////////////////////////////
// HIGHER LEVEL UTILS - FILE-SYSTEM
///////////////////////////////////////////////////////////////////////////////

/// Internal - created by the lazy static macro.
struct TmpVmafModelFile {
    /// Keep this in memory, when it gets ‘Dropped’, it’ll remove the tmp
    /// directory.
    dir: TempDir,
    path: PathBuf,
}

lazy_static! {
    static ref TMP_VMAF_DEF_MODEL_FILE: TmpVmafModelFile = {
        // INIT DIR
        let mut root_dir = TempDir::new().expect("TempDir::new() failed");
        // FILE PATHS
        let mut model_pkg = PathBuf::from(root_dir.path())
            .join("vmaf_v0.6.1.pkl");
        let mut model_other = PathBuf::from(root_dir.path())
            .join("vmaf_v0.6.1.pkl.model");
        // FILL FILES
        let (pkg, other) = get_vmaf_def_model();
        std::fs::write(&model_pkg, pkg).expect("TmpVmafModelFile::new_tmp");
        std::fs::write(&model_other, other).expect("TmpVmafModelFile::new_tmp");
        // DONE
        TmpVmafModelFile {
            dir: root_dir,
            path: model_pkg,
        }
    };

    static ref TMP_VMAF_4K_MODEL_FILE: TmpVmafModelFile = {
        // INIT DIR
        let mut root_dir = TempDir::new().expect("TempDir::new() failed");
        // FILE PATHS
        let mut model_pkg = PathBuf::from(root_dir.path())
            .join("vmaf_4k_v0.6.1.pkl");
        let mut model_other = PathBuf::from(root_dir.path())
            .join("vmaf_4k_v0.6.1.pkl.model");
        // FILL FILES
        let (pkg, other) = get_vmaf_4k_model();
        std::fs::write(&model_pkg, pkg).expect("TmpVmafModelFile::new_tmp");
        std::fs::write(&model_other, other).expect("TmpVmafModelFile::new_tmp");
        // DONE
        TmpVmafModelFile {
            dir: root_dir,
            path: model_pkg,
        }
    };
}


/// The VMAF default model.
/// 
/// This internally creates a temporary file that lasts for the duration of th
/// process. The temporary file is automatically removed at the end of the
/// process (or presumably by the OS following a reboot).
///
/// This is a relatively cheap operation in the sense that this only happens
/// once. All subsequent calls point to the original file (i.e. this is an
/// idempotent operation).
pub fn get_def_model_path() -> PathBuf {
    TMP_VMAF_DEF_MODEL_FILE.path.clone()
}


/// The VMAF 4K model.
/// 
/// This internally creates a temporary file that lasts for the duration of th
/// process. The temporary file is automatically removed at the end of the
/// process (or presumably by the OS following a reboot).
///
/// This is a relatively cheap operation in the sense that this only happens
/// once. All subsequent calls point to the original file (i.e. this is an
/// idempotent operation). 
pub fn get_4k_model_path() -> PathBuf {
    TMP_VMAF_4K_MODEL_FILE.path.clone()
}