@@ -119,7 +119,30 @@ impl MP4Encoder {
119119 audio_config : Option < AudioInfo > ,
120120 output_height : Option < u32 > ,
121121 ) -> Result < Self , InitError > {
122- Self :: init_with_options ( output, video_config, audio_config, output_height, false )
122+ Self :: init_with_options (
123+ output,
124+ video_config,
125+ audio_config,
126+ output_height,
127+ false ,
128+ false ,
129+ )
130+ }
131+
132+ pub fn init_ultra (
133+ output : PathBuf ,
134+ video_config : VideoInfo ,
135+ audio_config : Option < AudioInfo > ,
136+ output_height : Option < u32 > ,
137+ ) -> Result < Self , InitError > {
138+ Self :: init_with_options (
139+ output,
140+ video_config,
141+ audio_config,
142+ output_height,
143+ false ,
144+ true ,
145+ )
123146 }
124147
125148 pub fn init_instant_mode (
@@ -128,7 +151,14 @@ impl MP4Encoder {
128151 audio_config : Option < AudioInfo > ,
129152 output_height : Option < u32 > ,
130153 ) -> Result < Self , InitError > {
131- Self :: init_with_options ( output, video_config, audio_config, output_height, true )
154+ Self :: init_with_options (
155+ output,
156+ video_config,
157+ audio_config,
158+ output_height,
159+ true ,
160+ false ,
161+ )
132162 }
133163
134164 fn init_with_options (
@@ -137,6 +167,7 @@ impl MP4Encoder {
137167 audio_config : Option < AudioInfo > ,
138168 output_height : Option < u32 > ,
139169 instant_mode : bool ,
170+ ultra_quality : bool ,
140171 ) -> Result < Self , InitError > {
141172 info ! (
142173 width = video_config. width,
@@ -227,18 +258,22 @@ impl MP4Encoder {
227258
228259 let bitrate = if instant_mode {
229260 get_instant_mode_bitrate ( output_width as f32 , output_height as f32 , fps)
261+ } else if ultra_quality {
262+ get_ultra_bitrate ( output_width as f32 , output_height as f32 , fps)
230263 } else {
231264 get_average_bitrate ( output_width as f32 , output_height as f32 , fps)
232265 } ;
233266
234- debug ! ( instant_mode, "recording bitrate: {bitrate}" ) ;
267+ debug ! ( instant_mode, ultra_quality , "recording bitrate: {bitrate}" ) ;
235268
236269 let keyframe_interval = if instant_mode {
237270 fps as i32
238271 } else {
239272 ( fps * 2.0 ) as i32
240273 } ;
241274
275+ let allow_frame_reordering = ultra_quality && !instant_mode;
276+
242277 output_settings. insert (
243278 av:: video_settings_keys:: compression_props ( ) ,
244279 ns:: Dictionary :: with_keys_values (
@@ -250,7 +285,7 @@ impl MP4Encoder {
250285 ] ,
251286 & [
252287 ns:: Number :: with_f32 ( bitrate) . as_id_ref ( ) ,
253- ns:: Number :: with_bool ( false ) . as_id_ref ( ) ,
288+ ns:: Number :: with_bool ( allow_frame_reordering ) . as_id_ref ( ) ,
254289 ns:: Number :: with_f32 ( fps) . as_id_ref ( ) ,
255290 ns:: Number :: with_i32 ( keyframe_interval) . as_id_ref ( ) ,
256291 ] ,
@@ -935,10 +970,19 @@ fn timescale_value_to_duration(value: i64, timescale: i32) -> Duration {
935970 Duration :: from_nanos ( nanos)
936971}
937972
973+ const MIN_STUDIO_BITRATE : f32 = 8_000_000.0 ;
974+ const MAX_ULTRA_BITRATE : f32 = 120_000_000.0 ;
975+
938976fn get_average_bitrate ( width : f32 , height : f32 , fps : f32 ) -> f32 {
939- 5_000_000.0
940- + width * height / ( 1920.0 * 1080.0 ) * 2_000_000.0
941- + fps. min ( 60.0 ) / 30.0 * 5_000_000.0
977+ let pixels = width * height;
978+ let fps_factor = fps. min ( 60.0 ) / 30.0 ;
979+ ( pixels * fps_factor * 5.0 ) . max ( MIN_STUDIO_BITRATE )
980+ }
981+
982+ fn get_ultra_bitrate ( width : f32 , height : f32 , fps : f32 ) -> f32 {
983+ let pixels = width * height;
984+ let fps_factor = fps. min ( 60.0 ) / 30.0 ;
985+ ( pixels * fps_factor * 10.0 ) . clamp ( MIN_STUDIO_BITRATE , MAX_ULTRA_BITRATE )
942986}
943987
944988fn get_instant_mode_bitrate ( width : f32 , height : f32 , fps : f32 ) -> f32 {
0 commit comments