1use serde::{Deserialize, Serialize};
2use viser_ffmpeg::{
3 Codec, RES_360P, RES_480P, RES_720P, RES_1080P, RES_1440P, RES_2160P, Resolution,
4};
5use viser_ladder::Opts as LadderOpts;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
9#[serde(rename_all = "snake_case")]
10pub enum DeviceClass {
11 Mobile,
13 Desktop,
15 Tv,
17 Tv4k,
19}
20
21#[derive(Debug, Clone, Serialize, Deserialize)]
23pub struct Profile {
24 pub name: String,
26 pub device: DeviceClass,
28 pub description: String,
30 pub vmaf_model: String,
32 pub max_res: Resolution,
34 pub resolutions: Vec<Resolution>,
36 pub codecs: Vec<Codec>,
38 pub ladder_opts: LadderOpts,
40}
41
42pub fn mobile_profile() -> Profile {
44 Profile {
45 name: "Mobile".into(),
46 device: DeviceClass::Mobile,
47 description: "Smartphones and small tablets. Screen <7 inches.".into(),
48 vmaf_model: "vmaf_v0.6.1".into(),
49 max_res: RES_720P,
50 resolutions: vec![RES_360P, RES_480P, RES_720P],
51 codecs: vec![Codec::SvtAv1, Codec::X264],
52 ladder_opts: LadderOpts {
53 num_rungs: 4,
54 min_bitrate: 150.0,
55 max_bitrate: 3000.0,
56 min_vmaf: 50.0,
57 max_vmaf: 95.0,
58 audio_bitrate_kbps: 0.0,
59 },
60 }
61}
62
63pub fn desktop_profile() -> Profile {
65 Profile {
66 name: "Desktop".into(),
67 device: DeviceClass::Desktop,
68 description: "Laptops and desktop monitors. 13-27 inch screens.".into(),
69 vmaf_model: "vmaf_v0.6.1".into(),
70 max_res: RES_1080P,
71 resolutions: vec![RES_480P, RES_720P, RES_1080P],
72 codecs: vec![Codec::SvtAv1, Codec::X265, Codec::X264],
73 ladder_opts: LadderOpts::default(),
74 }
75}
76
77pub fn tv_profile() -> Profile {
79 Profile {
80 name: "TV (1080p)".into(),
81 device: DeviceClass::Tv,
82 description: "TVs and large displays. 40-65 inch screens.".into(),
83 vmaf_model: "vmaf_v0.6.1".into(),
84 max_res: RES_1080P,
85 resolutions: vec![RES_480P, RES_720P, RES_1080P],
86 codecs: vec![Codec::SvtAv1, Codec::X265, Codec::X264],
87 ladder_opts: LadderOpts {
88 num_rungs: 8,
89 min_bitrate: 200.0,
90 max_bitrate: 12000.0,
91 min_vmaf: 40.0,
92 max_vmaf: 0.0,
93 audio_bitrate_kbps: 0.0,
94 },
95 }
96}
97
98pub fn tv_4k_profile() -> Profile {
100 Profile {
101 name: "TV (4K)".into(),
102 device: DeviceClass::Tv4k,
103 description: "4K TVs. 55-85 inch screens.".into(),
104 vmaf_model: "vmaf_4k_v0.6.1".into(),
105 max_res: RES_2160P,
106 resolutions: vec![RES_720P, RES_1080P, RES_1440P, RES_2160P],
107 codecs: vec![Codec::SvtAv1, Codec::X265],
108 ladder_opts: LadderOpts {
109 num_rungs: 8,
110 min_bitrate: 1000.0,
111 max_bitrate: 25000.0,
112 min_vmaf: 40.0,
113 max_vmaf: 97.0,
114 audio_bitrate_kbps: 0.0,
115 },
116 }
117}
118
119pub fn all_profiles() -> Vec<Profile> {
121 vec![mobile_profile(), desktop_profile(), tv_profile(), tv_4k_profile()]
122}