other_video_transcoding 0.6.0 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e35c9d638ce45ae7407b8a3d88f0a785b515683c30e55b2d325e3cc243c15431
4
- data.tar.gz: ae7a7405f0b57be44ee16dfc6b48c877730b4b6cd6933410a6ec3828bea124ef
3
+ metadata.gz: 325b662c56c03a0cac33994a3ab165381fe801615072c87188de4b8f6bd954f7
4
+ data.tar.gz: c26a3551deed5d3966168b881da8730672024b8363fc1e0e8611a27ca5ec9426
5
5
  SHA512:
6
- metadata.gz: 15c29bac8aa3f7cb7ba9dcf6cf5c22e2c99f3b8ab8a709652166c885c5e2207873abdd2319c86cc5745aac977bab6911e50407356caa730976af465a88089dcb
7
- data.tar.gz: 56d94453fda02a51ac29ddbdc904192874712f4ea3457a647383c2628bd54ebe636447771940e80ee6335a74e16ccef0fd14d6785e9a2998a22acf7b12c2f027
6
+ metadata.gz: dafd0f33a13e2b0f90db7e8ab8d0d7db19577177128dd133538593f762daddbf06c1ebf2735f05828b96255fc7970ce091434b78d9d80780598e9f18555ec5b1
7
+ data.tar.gz: 8d294809aceafa52a1b73007593d9e36ca966e4aa15a43b4a4ca99c74f9df23bfb8c0c892b9ddba6d3fe009798f8de35480c942cbb26db2b3fd7c8b913022e6a
data/CHANGELOG.md CHANGED
@@ -2,6 +2,103 @@
2
2
 
3
3
  This single document contains all of the notes created for each [release](https://github.com/donmelton/other_video_transcoding/releases).
4
4
 
5
+ ## [0.10.0](https://github.com/donmelton/other_video_transcoding/releases/tag/0.10.0)
6
+
7
+ Thursday, January 27, 2022
8
+
9
+ * Add a `--nvenc-gpu-only` option to `other-transcode` to keep data on the GPU for greater speed, if possible. Deinterlacing is allowed but cropping, scaling, detelecining, setting frame rates and burning subtitles will prevent this from working and may actually slow things down. Performance can also be affected negatively depending on PC configuration. Please note that the `--nvenc-gpu-only` option requires `ffmpeg` version 5.0 or later.
10
+ * Add a `--x264-cbr` option to `other-transcode` to simplify access to constant bitrate (CBR) ratecontrol. Despite the name, actual output bitrates from the `x264` encoder are variable and below what might be expected. So, default video bitrate targets are raised to accommodate this.
11
+ * Enable proper crop detection in `other-transcode` for 4K UHD Blu-ray rips and other media with a 10-bit color depth. This was done by changing the `limit` value passed to the `cropdetect` filter from an integer constant to a floating point equation. Via [ #52](https://github.com/donmelton/other_video_transcoding/issues/52).
12
+ * Modify `other-transcode` to add a workaround for the mapping of BT.470 M and BT.470 BG color transfer characteristics from values returned from `ffprobe` to values actually used by `ffmpeg`. Via [ #112](https://github.com/donmelton/other_video_transcoding/issues/112).
13
+ * Modify `other-transcode` to allow parentheses within the argument to the `--yadif-params`, `--x264-params` and `--x265-params` options. Via [ #119](https://github.com/donmelton/other_video_transcoding/issues/119).
14
+ * Modify `ask-ffmpeg-log` to fix detection of frame counts less than five digits within `.log` files from very short duration videos. Via [ #126](https://github.com/donmelton/other_video_transcoding/issues/126).
15
+ * Modify `ask-ffmpeg-log` to fix detection of statistics within `.log` files not generated by `other-transcode`.
16
+ * Remove the deprecated `--nvenc-rc-mode` and `--aac-stereo` options from `other-transcode`.
17
+ * Update all copyright notices to the year 2022.
18
+
19
+ ## [0.9.0](https://github.com/donmelton/other_video_transcoding/releases/tag/0.9.0)
20
+
21
+ Saturday, June 5, 2021
22
+
23
+ Nvidia encoders:
24
+
25
+ * Add a `--nvenc-recommended` option to `other-transcode` which easily and optimally configures the Nvidia H.264 and HEVC video encoders, equivalent to using:
26
+ * `--nvenc-spatial-aq --nvenc-lookahead 32 --nvenc-bframe-refs middle`
27
+ * The `--nvenc-bframe-refs` option is also new and using `middle` as its argument increases compression efficiency. However, it's not supported on all Nvidia hardware. Which means, neither is the `--nvenc-recommended` option.
28
+ * So, using `--nvenc-recommended` for H.264 encoding requires at minimum a fourth generation Pascal-based GPU like the GTX 1080. And using it for HEVC encoding requires at minimum a more recent sixth generation Turing-based model like the GTX 1660 or RTX 2070.
29
+ * Add a `--nvenc-cq` option to `other-transcode` to allow constant quality (CQ) ratecontrol. This option ignores the target video bitrate and takes a single numerical argument between `1` and `51` with lower values indicating higher quality. However, only values between `25` and `30` are really practical for 1080p content. It's recommended to start with `--nvenc-cq 28` and adjust as needed. Fractional values are also supported.
30
+ * While CQ ratecontrol can adapt better to extremely dynamic content compared to the default average bitrate (ABR) ratecontrol system, the output bitrates produced by CQ can vary significantly and it can be slightly more prone to color banding with the H.264 encoder. So, for now, consider the `--nvenc-cq` option an experimental feature.
31
+ * Deprecate the `--nvenc-rc-mode` option in `other-transcode` because maximum rate and buffer size values are already specified so an explicit ratecontrol mode is not required.
32
+
33
+ Audio:
34
+
35
+ * Modify `other-transcode` to no longer explicitly set audio bitrates and instead rely on the defaults from the audio encoders included with `ffmpeg`. This is being done to both simplify the code in `other-transcode` and to leverage the judgement of the audio encoder developers, which means:
36
+ * AC-3 surround audio is lowered from 640 Kbps to 448 Kbps.
37
+ * Dolby Digital Plus (Enhanced AC-3) surround audio is raised from 384 Kbps to 448 Kbps.
38
+ * AAC stereo audio is lowered from 256 Kbps to 128 Kbps when using the native `ffmpeg` or Apple AudioToolbox encoders.
39
+ * If desired, use the `--surround-bitrate` and `--stereo-bitrate` options to restore the previous default audio bitrates.
40
+ * Add a `--aac-only` option to `other-transcode` to force transcoding of all audio into AAC format, copying only tracks which are already in that format. Surround tracks are converted to a 5.1-channel AAC format at 341 Kbps when using the native `ffmpeg` encoder. This channel layout is compatible with most playback devices. Allowing more than 5.1 channels would significantly reduce playback compatibility.
41
+ * Deprecate the `--aac-stereo` option in `other-transcode` and replace with a new `--eac3-aac` option, which uses Dolby Digital Plus format only for surround audio with AAC format for stereo audio. Since the `--aac-stereo` option only made sense when used in combination with the `--eac3` option, this makes `--eac3-aac` more convenient.
42
+
43
+ Other changes:
44
+
45
+ * Change the default ratecontrol maximum rate and buffer size values in `other-transcode`, as well as how those values increased when the target video bitrate is increased. The default values now also differ depending on whether the output video is in H.264 or HEVC format.
46
+ * Modify the `--rc-maxrate` and `--rc-bufsize` options in `other-transcode` to allow specific bitrates as arguments and not just multiples of the video bitrate target. These options are most useful for lowering maximum rate and buffer size values. To raise those values, increase the target video bitrate instead.
47
+ * Change the pixel format and force a Main 10 video profile in `other-transcode` when using the Apple VideoToolbox encoder to create output with a 10-bit color depth. Correct generation of 10-bit output requires macOS Big Sur or later.
48
+ * Modify `other-transcode` to copy the three basic color properties (primaries, transer and space) from the input to the output when those properties are availabe. Otherwise use some sensible defaults.
49
+ * Modify `other-transcode` to force a H.264 level when using `--x264` with slower presets. This ensures that the `x264` encoder continues to generate a video stream compatible with most playback devices when those presets are used.
50
+ * Modify `other-transcode` to remove the hack which avoids using the Matroksa muxer `-disposition` option in old versions of `ffmpeg`. This means version 4.3 or later of `ffmpeg` is now required to run `other-transcode`.
51
+
52
+ ## [0.8.0](https://github.com/donmelton/other_video_transcoding/releases/tag/0.8.0)
53
+
54
+ Saturday, February 13, 2021
55
+
56
+ * Modify `other-transcode` to:
57
+ * No longer automatically deinterlace video with a frame rate of 29.97 FPS.
58
+ * No longer change the frame rate of any video in MPEG-2 format which was automatically deinterlaced.
59
+ * Only automatically deinterlace non-progressive video.
60
+ * Apply any automatic or explicit deinterlacing to all frames of the video, not just the interlaced frames.
61
+ * Force a constant frame rate for any video in MPEG-2 format at 29.97 FPS.
62
+ * Add a `--yadif-params` option to `other-transcode` to allow customization of the `yadif` filter used for deinterlacing.
63
+ * Remove the deprecated `--all-eac3` option of `other-transcode`.
64
+
65
+ ## [0.7.0](https://github.com/donmelton/other_video_transcoding/releases/tag/0.7.0)
66
+
67
+ Monday, January 4, 2021
68
+
69
+ * Modify `other-transcode` to lower default target bitrates in order to significantly reduce the size of transcoded output at the risk of a slight reduction in perceived quality. Via [ #89](https://github.com/donmelton/other_video_transcoding/issues/89).
70
+
71
+ H.264 video:
72
+
73
+ Resolution | old | new
74
+ --- | --- | ---
75
+ 1080p (Blu-ray video) | 8000 Kbps | 6000 Kbps
76
+ 720p | 4000 Kbps | 3000 Kbps
77
+ 480p (DVD video) | 2000 Kbps | 1500 Kbps
78
+
79
+ HEVC video:
80
+
81
+ Resolution | old | new
82
+ --- | --- | ---
83
+ 1080p (Blu-ray video) | 6000 Kbps | 4000 Kbps
84
+ 720p | 3000 Kbps | 2000 Kbps
85
+ 480p (DVD video) | 1500 Kbps | 1000 Kbps
86
+
87
+ Dolby Digital Plus (Enhanced AC-3) audio:
88
+
89
+ Channels | old | new
90
+ --- | --- | ---
91
+ Surround | 640 Kbps | 384 Kbps
92
+ Stereo | 256 Kbps | 192 Kbps
93
+ Mono | 128 Kbps | 96 Kbps
94
+
95
+ Note: There are no changes to default target bitrates for Dolby Digital (AC-3) and AAC audio formats.
96
+
97
+ * Change the `--eac3` option in `other-transcode` to use Dolby Digital Plus format for _all_ transcoded audio instead of just surround output.
98
+ * Deprecate the `--all-eac3` option in `other-transcode` since the `--eac3` option now has the same behavior.
99
+ * Add a `--aac-stereo` option to `other-transcode`. This uses AAC format for transcoded stereo audio output so it can be paired with `--eac3` to get that option's old behavior.
100
+ * Add a `--8-bit-vc1` option. When the color depth is currently 10-bit, this option uses an 8-bit color depth _for video inputs in VC-1 format only_.
101
+
5
102
  ## [0.6.0](https://github.com/donmelton/other_video_transcoding/releases/tag/0.6.0)
6
103
 
7
104
  Tuesday, December 22, 2020
@@ -9,7 +106,7 @@ Tuesday, December 22, 2020
9
106
  * Lower the default target bitrates for 8-bit HEVC video in `other-transcode` to match the defaults for 10-bit HEVC video. This means, for example, the default target for HEVC at a 1080p resolution will be 6000 Kbps no matter the output bit depth.
10
107
  * Modify `other-transcode` to set the video buffer size equal to the maximum video bitrate when using an Nvidia encoder, essentially adding `--rc-bufsize 3` to the command line. Previously the buffer size was never explicitly set so `ffmpeg` would use a default value of twice the target bitrate. Since the maximum bitrate is normally three times the target bitrate this meant the buffer size was actually smaller than the maximum. While this didn't cause any known problems, Nvidia recommends a larger buffer size to improve quality. However, using `--rc-bufsize 0` will restore the old behavior and the default value from `ffmpeg`.
11
108
  * Ignore the `--nvenc-lookahead` option in `other-transcode` when the argument is `0` since such a value won't change the behavior of an Nvidia encoder anyway.
12
- * Add a `--limit-ac3-surround` option to `other-transcode` which prevents surround audio in AC-3 or Dolby Digital Plus (Enhanced AC-3) format from being copied instead of transcoded when the orginal bitrate is above the transcoding bitrate. This allows setting a lower target with the `--surround-bitrate` option in order to force higher-bitrate tracks to be transcoded instead of copied.
109
+ * Add a `--limit-ac3-surround` option to `other-transcode` which prevents surround audio in AC-3 or Dolby Digital Plus (Enhanced AC-3) format from being copied instead of transcoded when the orginal bitrate is above the transcoding bitrate. This allows setting a lower target with the `--surround-bitrate` option in order to force higher-bitrate tracks to be transcoded instead of copied.
13
110
  * Reduce the minimum bitrates for Dolby Digital Plus audio in `other-transcode` from 256, 128 and 64 Kbps for surround, stereo and mono layouts to 192, 96 and 48 Kbps. The default bitrates for Dolby Digital Plus audio remain the same and this change does not affect audio output in AC-3 or AAC formats.
14
111
 
15
112
  ## [0.5.0](https://github.com/donmelton/other_video_transcoding/releases/tag/0.5.0)
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2019-2020 Don Melton
1
+ Copyright (c) 2019-2022 Don Melton
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  of this software and associated documentation files (the "Software"), to deal
data/bin/ask-ffmpeg-log CHANGED
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # ask-ffmpeg-log
4
4
  #
5
- # Copyright (c) 2019-2020 Don Melton
5
+ # Copyright (c) 2019-2022 Don Melton
6
6
  #
7
7
 
8
8
  require 'abbrev'
@@ -16,8 +16,8 @@ module Transcoding
16
16
  class Command
17
17
  def about
18
18
  <<-HERE
19
- ask-ffmpeg-log 0.6.0
20
- Copyright (c) 2019-2020 Don Melton
19
+ ask-ffmpeg-log 0.10.0
20
+ Copyright (c) 2019-2022 Don Melton
21
21
  HERE
22
22
  end
23
23
 
@@ -138,9 +138,9 @@ Options:
138
138
  fail "not a ffmpeg-generated `.log` file: #{log}"
139
139
  end
140
140
 
141
- stats = content.match(/^frame=.*[.0-9]+x */m).to_s.lines.last.to_s.rstrip
141
+ stats = content.match(/^frame=.* speed= *[.0-9]+x */m).to_s.lines.last.to_s.rstrip
142
142
 
143
- if stats =~ /frame=([0-9]+) fps=( *[.0-9]+)/
143
+ if stats =~ /frame=( *[0-9]+) fps=( *[.0-9]+)/
144
144
  frames = $1
145
145
  fps = $2
146
146
  seconds = frames.to_f / fps.lstrip.to_f
data/bin/other-transcode CHANGED
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # other-transcode
4
4
  #
5
- # Copyright (c) 2019-2020 Don Melton
5
+ # Copyright (c) 2019-2022 Don Melton
6
6
  #
7
7
 
8
8
  require 'English'
@@ -18,8 +18,8 @@ module Transcoding
18
18
  class Command
19
19
  def about
20
20
  <<-HERE
21
- other-transcode 0.6.0
22
- Copyright (c) 2019-2020 Don Melton
21
+ other-transcode 0.10.0
22
+ Copyright (c) 2019-2022 Don Melton
23
23
  HERE
24
24
  end
25
25
 
@@ -91,8 +91,9 @@ Video options:
91
91
  --x264 use x264 software video encoder
92
92
  --x265 use x265 " " "
93
93
  --10-bit, --no-10-bit
94
- use 10-bit pixel format (default: not used for H.264,
94
+ use 10-bit color depth (default: not used for H.264,
95
95
  used for HEVC with Nvidia, Intel and x265 encoders)
96
+ --8-bit-vc1 use 8-bit color depth for VC-1 format only
96
97
  --preset NAME apply video encoder preset
97
98
  --decode vc1|all|none
98
99
  set scope of automatic hardware decoder acceleration
@@ -127,7 +128,7 @@ Video options:
127
128
  --deinterlace reduce interlace artifacts without changing frame rate
128
129
  (applied automatically for some inputs)
129
130
  --rate FPS force constant video frame rate
130
- (`24000/1001` applied automatically for some inputs)
131
+ (disables automatic deinterlacing)
131
132
  --detelecine drop duplicate frames to restore original frame rate
132
133
  (disables any deinterlacing and forced frame rate)
133
134
  --no-filters disable any automatic adjustments via filters
@@ -136,15 +137,23 @@ Video options:
136
137
 
137
138
  def usage10
138
139
  <<-HERE
139
- --rc-maxrate FACTOR, --rc-bufsize FACTOR
140
+ --yadif-params KEY=VALUE[:KEY=VALUE]...
141
+ override yadif deinterlace filter configuration
142
+ --rc-maxrate FACTOR, --rc-bufsize FACTOR|BITRATE
140
143
  set ratecontrol maximum rate and/or buffer size
141
- as multiple of video bitrate target
144
+ as multiple of video bitrate target or specific bitrate
142
145
  --copy-video disable transcoding and copy original video track
143
146
 
144
147
  Apple Video Toolbox encoder options:
145
148
  --vt-allow-sw allow software encoding
146
149
 
147
150
  Nvidia video encoder options:
151
+ --nvenc-recommended
152
+ apply optimal quality settings, equivalent to using:
153
+ `--nvenc-spatial-aq`
154
+ `--nvenc-lookahead 32`
155
+ `--nvenc-bframe-refs middle`
156
+ (not supported on all Nvidia hardware)
148
157
  --nvenc-spatial-aq
149
158
  enable spatial adaptive quantization (AQ)
150
159
  --nvenc-temporal-aq
@@ -157,8 +166,12 @@ Nvidia video encoder options:
157
166
  set number of reference frames
158
167
  --nvenc-bframes FRAMES
159
168
  set maximum number of B-frames
160
- --nvenc-rc-mode vbr|vbr_hq
161
- set ratecontrol mode (default: vbr)
169
+ --nvenc-bframe-refs each|middle
170
+ set mode for using B-frames as reference frames
171
+ --nvenc-cq QUALITY
172
+ use constant quality (CQ) ratecontrol at target quality
173
+ --nvenc-gpu-only
174
+ keep data on GPU for greater speed, if possible
162
175
 
163
176
  Intel Quick Sync video encoder options:
164
177
  --qsv-refs FRAMES
@@ -182,6 +195,9 @@ Video Acceleration API encoder options:
182
195
  set numeric level of compression
183
196
 
184
197
  x264 software video encoder options:
198
+ --x264-cbr use constant bitrate (CBR) ratecontrol
199
+ with variable bitrate output
200
+ (raises default video bitrate targets)
185
201
  --x264-avbr use average variable bitrate (AVBR) ratecontrol
186
202
  --x264-mbtree use macroblock-tree ratecontrol (disables AVBR if in use)
187
203
  --x264-quick increase encoding speed by 70-80%
@@ -238,34 +254,39 @@ Audio options:
238
254
  def usage15
239
255
  <<-HERE
240
256
  --surround-bitrate BITRATE
241
- set surround audio bitrate (default: 640)
257
+ set surround audio bitrate (default: 448)
242
258
  --stereo-bitrate BITRATE
243
- set stereo audio bitrate (default: 256)
259
+ set stereo audio bitrate (default: 128)
244
260
  HERE
245
261
  end
246
262
 
247
263
  def usage16
248
264
  <<-HERE
249
265
  --mono-bitrate BITRATE
250
- set mono audio bitrate (default: 50% of stereo bitrate)
266
+ set mono audio bitrate (default: ~50% of stereo bitrate)
251
267
  HERE
252
268
  end
253
269
 
254
270
  def usage17
255
271
  <<-HERE
256
- --eac3 use Enhanced AC-3 format for surround audio
272
+ --eac3 use Dolby Digital Plus (E-AC-3) format for all audio
273
+ (default bitrates: 448 for surround, 192 for stereo)
257
274
  HERE
258
275
  end
259
276
 
260
277
  def usage18
261
278
  <<-HERE
262
- --all-eac3 " " " " " all audio
279
+ --eac3-aac use Dolby Digital Plus format only for surround audio
280
+ with AAC format for stereo audio
281
+ --aac-only use AAC format for all audio,
282
+ disabling passthrough of audio in other formats
283
+ (default bitrates: 341 for surround, 128 for stereo)
263
284
  --limit-ac3-surround
264
285
  don't copy surround audio in AC-3 format
265
- when orginal bitrate is above transcoding bitrate
286
+ when orginal bitrate is above passthrough bitrate
266
287
  --keep-ac3-stereo
267
288
  copy stereo and mono audio in AC-3 format
268
- even when orginal bitrate is above transcoding bitrate
289
+ even when orginal bitrate is above passthrough bitrate
269
290
  --pass-dts enable passthrough of audio in DTS and DTS-ES formats
270
291
  HERE
271
292
  end
@@ -307,13 +328,13 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
307
328
  @detect = false
308
329
  @preview = false
309
330
  @format = :mkv
310
- @mkv_options = []
311
331
  @copy_track_names = false
312
332
  @max_muxing_queue_size = nil
313
333
  @dry_run = false
314
334
  @hevc = false
315
335
  @encoder = nil
316
336
  @ten_bit = nil
337
+ @eight_bit_vc1 = false
317
338
  @preset = nil
318
339
  @decode_scope = :vc1
319
340
  @decode_method = nil
@@ -330,6 +351,7 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
330
351
  @rate = nil
331
352
  @detelecine = false
332
353
  @enable_filters = true
354
+ @yadif_params = nil
333
355
  @maxrate = nil
334
356
  @bufsize = nil
335
357
  @vt_allow_sw = false
@@ -339,7 +361,9 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
339
361
  @nvenc_multipass = nil
340
362
  @nvenc_refs = nil
341
363
  @nvenc_bframes = nil
342
- @nvenc_rc_mode = 'vbr'
364
+ @nvenc_bframe_refs = nil
365
+ @nvenc_cq = nil
366
+ @nvenc_gpu_only = false
343
367
  @qsv_refs = nil
344
368
  @qsv_bframes = nil
345
369
  @amf_quality = nil
@@ -359,11 +383,12 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
359
383
  :title => nil,
360
384
  :width => :surround
361
385
  }]
362
- @surround_bitrate = 640
363
- @stereo_bitrate = 256
386
+ @surround_bitrate = nil
387
+ @stereo_bitrate = nil
364
388
  @mono_bitrate = nil
365
389
  @surround_encoder = 'ac3'
366
390
  @stereo_encoder = nil
391
+ @aac_fallback_encoder = 'aac'
367
392
  @keep_ac3_surround = true
368
393
  @keep_ac3_stereo = false
369
394
  @pass_dts = false
@@ -502,6 +527,12 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
502
527
 
503
528
  opts.on '--[no-]10-bit' do |arg|
504
529
  @ten_bit = arg
530
+ @eight_bit_vc1 = false
531
+ @encoder = nil if @encoder == 'copy'
532
+ end
533
+
534
+ opts.on '--8-bit-vc1' do
535
+ @eight_bit_vc1 = true
505
536
  @encoder = nil if @encoder == 'copy'
506
537
  end
507
538
 
@@ -554,6 +585,7 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
554
585
  @target = [arg.to_i, 1].max
555
586
  end
556
587
 
588
+ @nvenc_cq = nil
557
589
  @encoder = nil if @encoder == 'copy'
558
590
  end
559
591
 
@@ -624,6 +656,14 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
624
656
  @enable_filters = false
625
657
  end
626
658
 
659
+ opts.on '--yadif-params ARG' do |arg|
660
+ arg.split ':' do |param|
661
+ fail UsageError, "invalid argument: #{arg}" unless param =~ /^[\w\-]+=[\w\-\.,\(\)]+$/
662
+ end
663
+
664
+ @yadif_params = arg
665
+ end
666
+
627
667
  opts.on '--rc-maxrate ARG', Float do |arg|
628
668
  @maxrate = arg
629
669
  @encoder = nil if @encoder == 'copy'
@@ -652,6 +692,13 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
652
692
  @vt_allow_sw = true
653
693
  end
654
694
 
695
+ opts.on '--nvenc-recommended' do
696
+ @encoder = @hevc ? 'hevc_nvenc' : 'h264_nvenc'
697
+ @nvenc_spatial_aq = true
698
+ @nvenc_lookahead = 32
699
+ @nvenc_bframe_refs = 'middle'
700
+ end
701
+
655
702
  opts.on '--nvenc-spatial-aq' do
656
703
  @encoder = @hevc ? 'hevc_nvenc' : 'h264_nvenc'
657
704
  @nvenc_spatial_aq = true
@@ -693,17 +740,29 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
693
740
  @nvenc_bframes = [[arg, 0].max, 4].min
694
741
  end
695
742
 
696
- opts.on '--nvenc-rc-mode ARG' do |arg|
743
+ opts.on '--nvenc-bframe-refs ARG' do |arg|
697
744
  @encoder = @hevc ? 'hevc_nvenc' : 'h264_nvenc'
698
745
 
699
- @nvenc_rc_mode = case arg
700
- when 'vbr', 'vbr_hq'
746
+ @nvenc_bframe_refs = case arg
747
+ when 'each', 'middle'
701
748
  arg
702
749
  else
703
- fail UsageError, "invalid rate control argument: #{arg}"
750
+ fail UsageError, "invalid B-frames as references argument: #{arg}"
704
751
  end
705
752
  end
706
753
 
754
+ opts.on '--nvenc-cq ARG', Float do |arg|
755
+ @encoder = @hevc ? 'hevc_nvenc' : 'h264_nvenc'
756
+ @nvenc_cq = [[arg, 1].max, 51].min.to_s.sub(/\.0$/, '')
757
+ end
758
+
759
+ opts.on '--nvenc-gpu-only' do
760
+ @encoder = @hevc ? 'hevc_nvenc' : 'h264_nvenc'
761
+ @decode_scope = :all
762
+ @decode_method = 'cuda'
763
+ @nvenc_gpu_only = true
764
+ end
765
+
707
766
  opts.on '--qsv-refs ARG', Integer do |arg|
708
767
  @encoder = @hevc ? 'hevc_qsv' : 'h264_qsv'
709
768
  @qsv_refs = [arg, 0].max
@@ -750,6 +809,16 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
750
809
  @vaapi_compression = [arg, 0].max
751
810
  end
752
811
 
812
+ opts.on '--x264-cbr' do
813
+ @encoder = 'libx264'
814
+ @hevc = false
815
+ @x264_mbtree = true
816
+ @x264_avbr = false
817
+ @x264_params = nil
818
+ @maxrate = 1.0
819
+ @bufsize = nil
820
+ end
821
+
753
822
  opts.on '--x264-avbr' do
754
823
  @encoder = 'libx264'
755
824
  @hevc = false
@@ -776,7 +845,7 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
776
845
 
777
846
  opts.on '--x264-params ARG' do |arg|
778
847
  arg.split ':' do |param|
779
- fail UsageError, "invalid argument: #{arg}" unless param =~ /^[\w\-]+=[\w\-\.,]+$/
848
+ fail UsageError, "invalid argument: #{arg}" unless param =~ /^[\w\-]+=[\w\-\.,\(\)]+$/
780
849
  end
781
850
 
782
851
  @encoder = 'libx264'
@@ -789,7 +858,7 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
789
858
 
790
859
  opts.on '--x265-params ARG' do |arg|
791
860
  arg.split ':' do |param|
792
- fail UsageError, "invalid argument: #{arg}" unless param =~ /^[\w\-]+=[\w\-\.,]+$/
861
+ fail UsageError, "invalid argument: #{arg}" unless param =~ /^[\w\-]+=[\w\-\.,\(\)]+$/
793
862
  end
794
863
 
795
864
  @encoder = 'libx265'
@@ -840,6 +909,7 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
840
909
 
841
910
  opts.on '--stereo-bitrate ARG', Integer do |arg|
842
911
  @stereo_bitrate = arg
912
+ @mono_bitrate ||= @stereo_bitrate / 2
843
913
  end
844
914
 
845
915
  opts.on '--mono-bitrate ARG', Integer do |arg|
@@ -848,11 +918,17 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
848
918
 
849
919
  opts.on '--eac3' do
850
920
  @surround_encoder = 'eac3'
921
+ @stereo_encoder = 'eac3'
851
922
  end
852
923
 
853
- opts.on '--all-eac3' do
924
+ opts.on '--eac3-aac' do
854
925
  @surround_encoder = 'eac3'
855
- @stereo_encoder = 'eac3'
926
+ @stereo_encoder = nil
927
+ end
928
+
929
+ opts.on '--aac-only' do
930
+ @surround_encoder = nil
931
+ @stereo_encoder = nil
856
932
  end
857
933
 
858
934
  opts.on '--limit-ac3-surround' do
@@ -861,10 +937,12 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
861
937
 
862
938
  opts.on '--keep-ac3-stereo' do
863
939
  @keep_ac3_stereo = true
940
+ @surround_encoder ||= 'ac3'
864
941
  end
865
942
 
866
943
  opts.on '--pass-dts' do
867
944
  @pass_dts = true
945
+ @surround_encoder ||= 'ac3'
868
946
  end
869
947
 
870
948
  opts.on '--add-subtitle ARG' do |arg|
@@ -917,15 +995,6 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
917
995
  def configure(path)
918
996
  @audio_selections.uniq!
919
997
  @subtitle_selections.uniq!
920
- min_bitrate = @surround_encoder == 'eac3' ? 192 : 256
921
- @surround_bitrate = [[@surround_bitrate, min_bitrate].max, (@surround_encoder == 'ac3' ? 640 : 768)].min
922
- @stereo_bitrate = [[@stereo_bitrate, min_bitrate / 2].max, (@stereo_encoder == 'eac3' ? 768 : 320)].min
923
-
924
- if @mono_bitrate.nil?
925
- @mono_bitrate = @stereo_bitrate / 2
926
- else
927
- @mono_bitrate = [[@mono_bitrate, min_bitrate / 4].max, (@stereo_encoder == 'eac3' ? 768 : 256)].min
928
- end
929
998
 
930
999
  [
931
1000
  ['ffprobe', '-loglevel', 'quiet', '-version'],
@@ -965,24 +1034,32 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
965
1034
  end
966
1035
  end
967
1036
 
1037
+ @nvenc_cq = nil unless @encoder =~ /nvenc$/
968
1038
  @ten_bit = (@hevc and @encoder =~ /(nvenc|qsv|x265)$/ ? true : false) if @ten_bit.nil?
969
- @target_2160p ||= @hevc ? 12000 : 16000
970
- @target_1080p ||= @hevc ? 6000 : 8000
971
- @target_720p ||= @hevc ? 3000 : 4000
972
- @target_480p ||= @hevc ? 1500 : 2000
1039
+
1040
+ if @encoder == 'libx264' and @x264_mbtree and @maxrate == 1.0
1041
+ @target_2160p ||= 15000
1042
+ @target_1080p ||= 7500
1043
+ @target_720p ||= 4500
1044
+ @target_480p ||= 2250
1045
+ else
1046
+ @target_2160p ||= @hevc ? 8000 : 12000
1047
+ @target_1080p ||= @hevc ? 4000 : 6000
1048
+ @target_720p ||= @hevc ? 2000 : 3000
1049
+ @target_480p ||= @hevc ? 1000 : 1500
1050
+ end
1051
+
973
1052
  @decode_method ||= @encoder =~ /nvenc$/ ? 'cuda' : 'auto'
974
1053
 
975
1054
  if @stereo_encoder.nil?
976
1055
  if encoders =~ /aac_at/ or encoders =~ /libfdk_aac/
977
1056
  @stereo_encoder = $MATCH
1057
+ @aac_fallback_encoder = 'libfdk_aac' if encoders =~ /libfdk_aac/
978
1058
  else
979
1059
  @stereo_encoder = 'aac'
980
1060
  end
981
- end
982
1061
 
983
- if @format == :mkv
984
- capabilities = get_muxer_capabilities
985
- @mkv_options = ['-default_mode', 'passthrough'] if capabilities =~ /passthrough/
1062
+ @surround_encoder ||= @stereo_encoder
986
1063
  end
987
1064
  end
988
1065
 
@@ -1032,17 +1109,17 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
1032
1109
  IO.popen([
1033
1110
  'ffmpeg',
1034
1111
  '-loglevel', 'quiet',
1035
- '-nostdin'
1036
- ] + (encoder =~ /vaapi$/ ? ['-vaapi_device', '/dev/dri/renderD128'] : []) + [
1112
+ '-nostdin',
1113
+ *(encoder =~ /vaapi$/ ? ['-vaapi_device', '/dev/dri/renderD128'] : []),
1037
1114
  '-i', path,
1038
- '-frames:v', '1'
1039
- ] + (encoder =~ /vaapi$/ ? ['-filter:v', 'format=nv12,hwupload'] : []) + [
1115
+ '-frames:v', '1',
1116
+ *(encoder =~ /vaapi$/ ? ['-filter:v', 'format=nv12,hwupload'] : []),
1040
1117
  '-c:v', encoder,
1041
- '-b:v', '1000k'
1042
- ] + (encoder =~ /nvenc$/ ? ['-rc:v', @nvenc_rc_mode] : []) +
1043
- (encoder == 'h264_qsv' ? ['-look_ahead:v', '1'] : []) +
1044
- (encoder == 'hevc_qsv' ? ['-load_plugin:v', 'hevc_hw'] : []) +
1045
- (encoder =~ /amf$/ ? ['-rc:v', 'vbr_latency'] : []) + [
1118
+ '-b:v', '1000k',
1119
+ *(encoder =~ /nvenc$/ ? ['-rc:v', 'vbr'] : []),
1120
+ *(encoder == 'h264_qsv' ? ['-look_ahead:v', '1'] : []),
1121
+ *(encoder == 'hevc_qsv' ? ['-load_plugin:v', 'hevc_hw'] : []),
1122
+ *(encoder =~ /amf$/ ? ['-rc:v', 'vbr_latency'] : []),
1046
1123
  '-an',
1047
1124
  '-sn',
1048
1125
  '-ignore_unknown',
@@ -1060,30 +1137,6 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
1060
1137
  $CHILD_STATUS.exitstatus == 0
1061
1138
  end
1062
1139
 
1063
- def get_muxer_capabilities
1064
- Kernel.warn 'Getting muxer capabilities...'
1065
- output = ''
1066
-
1067
- begin
1068
- IO.popen([
1069
- 'ffmpeg',
1070
- '-loglevel', 'quiet',
1071
- '-h', 'muxer=matroska'
1072
- ], :err=>[:child, :out]) do |io|
1073
- io.each do |line|
1074
- Kernel.warn line if @debug
1075
- output += line
1076
- end
1077
- end
1078
- rescue SystemCallError => e
1079
- raise "getting muxer capabilities failed: #{e}"
1080
- end
1081
-
1082
- fail 'getting muxer capabilities failed' unless $CHILD_STATUS.exitstatus == 0
1083
-
1084
- output
1085
- end
1086
-
1087
1140
  def process_input(path)
1088
1141
  seconds = Time.now.tv_sec
1089
1142
 
@@ -1145,16 +1198,16 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
1145
1198
  ffmpeg_command = [
1146
1199
  'ffmpeg',
1147
1200
  '-loglevel', (@debug ? 'verbose' : 'error'),
1148
- '-stats'
1149
- ] + time_options +
1150
- decode_options + [
1151
- '-i', path
1152
- ] + (@max_muxing_queue_size.nil? ? [] : ['-max_muxing_queue_size', @max_muxing_queue_size.to_s]) +
1153
- encode_options +
1154
- get_audio_options(media_info) +
1155
- get_subtitle_options(media_info, burn_subtitle) + [
1156
- '-metadata:g', 'title='
1157
- ] + (@format == :mkv ? @mkv_options : ['-movflags', 'disable_chpl']) + [
1201
+ '-stats',
1202
+ *time_options,
1203
+ *decode_options,
1204
+ '-i', path,
1205
+ *(@max_muxing_queue_size.nil? ? [] : ['-max_muxing_queue_size', @max_muxing_queue_size.to_s]),
1206
+ *encode_options,
1207
+ *get_audio_options(media_info),
1208
+ *get_subtitle_options(media_info, burn_subtitle),
1209
+ '-metadata:g', 'title=',
1210
+ *(@format == :mkv ? ['-default_mode', 'passthrough'] : ['-movflags', 'disable_chpl']),
1158
1211
  output_path
1159
1212
  ]
1160
1213
 
@@ -1314,10 +1367,11 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
1314
1367
  index += 1
1315
1368
  puts "\##{index} subtitle:"
1316
1369
  print " format = #{stream['codec_name']}"
1317
- frames = stream.fetch('tags', {}).fetch('NUMBER_OF_FRAMES-eng', '')
1370
+ tags = stream.fetch('tags', {})
1371
+ frames = tags.fetch('NUMBER_OF_FRAMES', tags.fetch('NUMBER_OF_FRAMES-eng', ''))
1318
1372
  puts frames.empty? ? '' : " / #{frames} " + (frames == 1 ? 'frame' : 'frames')
1319
- puts " language = #{stream.fetch('tags', {}).fetch('language', '')}"
1320
- title = stream.fetch('tags', {}).fetch('title', '')
1373
+ puts " language = #{tags.fetch('language', '')}"
1374
+ title = tags.fetch('title', '')
1321
1375
  puts " title = #{title}" unless title.empty?
1322
1376
  default = (stream['disposition']['default'] == 1)
1323
1377
  forced = (stream['disposition']['forced'] == 1)
@@ -1332,8 +1386,8 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
1332
1386
  end
1333
1387
 
1334
1388
  def get_bitrate(stream)
1335
- bitrate = stream.fetch('bit_rate', '')
1336
- bitrate = stream.fetch('tags', {}).fetch('BPS-eng', '') if bitrate.empty?
1389
+ tags = stream.fetch('tags', {})
1390
+ bitrate = stream.fetch('bit_rate', tags.fetch('BPS', tags.fetch('BPS-eng', '')))
1337
1391
  return nil if bitrate.empty?
1338
1392
 
1339
1393
  bitrate.to_i / 1000
@@ -1398,7 +1452,7 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
1398
1452
  '-ss', position.to_s,
1399
1453
  '-i', path,
1400
1454
  '-frames:v', '15',
1401
- '-filter:v', 'cropdetect=24:2',
1455
+ '-filter:v', 'cropdetect=24.0/255:2',
1402
1456
  '-an',
1403
1457
  '-sn',
1404
1458
  '-ignore_unknown',
@@ -1570,28 +1624,22 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
1570
1624
  end
1571
1625
 
1572
1626
  deinterlace = @deinterlace
1573
- rate = @rate
1574
-
1575
- if @enable_filters
1576
- if video['avg_frame_rate'] == '30000/1001' or video.fetch('field_order', 'progressive') != 'progressive'
1577
- deinterlace = true
1578
1627
 
1579
- if video['codec_name'] == 'mpeg2video' and video['avg_frame_rate'] != '25/1'
1580
- rate = '24000/1001'
1581
- end
1582
- end
1628
+ if @enable_filters and video.fetch('field_order', 'progressive') != 'progressive'
1629
+ deinterlace = true
1583
1630
  end
1584
1631
 
1585
1632
  frame_rate_filter = nil
1586
1633
 
1587
- if deinterlace
1588
- frame_rate_filter = 'yadif=deint=interlaced' unless @encoder == 'copy'
1634
+ if deinterlace and @encoder != 'copy'
1635
+ frame_rate_filter = 'yadif'
1636
+ frame_rate_filter += "=#{@yadif_params}" unless @yadif_params.nil?
1589
1637
  end
1590
1638
 
1591
- unless rate.nil?
1639
+ unless @rate.nil?
1592
1640
  frame_rate_filter = '' if frame_rate_filter.nil?
1593
1641
  frame_rate_filter += ',' unless frame_rate_filter.empty?
1594
- frame_rate_filter += "fps=#{rate}"
1642
+ frame_rate_filter += "fps=#{@rate}"
1595
1643
  end
1596
1644
 
1597
1645
  if @detelecine
@@ -1601,12 +1649,6 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
1601
1649
  width = video['width'].to_i
1602
1650
  height = video['height'].to_i
1603
1651
 
1604
- if width == 720 and height == 576 and video['codec_name'] == 'mpeg2video'
1605
- pal = true
1606
- else
1607
- pal = false
1608
- end
1609
-
1610
1652
  if crop.nil? or (crop == {:width => width, :height => height, :x => 0, :y => 0})
1611
1653
  crop_filter = nil
1612
1654
  else
@@ -1639,6 +1681,8 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
1639
1681
  decode_options = []
1640
1682
  end
1641
1683
 
1684
+ nvenc_gpu_only = false
1685
+
1642
1686
  if (@decode_scope == :vc1 and video['codec_name'] == 'vc1') or @decode_scope == :all
1643
1687
  if @encoder =~ /vaapi$/
1644
1688
  decode_options = [
@@ -1655,6 +1699,18 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
1655
1699
 
1656
1700
  decode_options += ['-hwaccel', decode_method]
1657
1701
 
1702
+ if @nvenc_gpu_only and
1703
+ decode_method == 'cuda' and
1704
+ @encoder =~ /nvenc$/ and
1705
+ overlay_filter.nil? and
1706
+ (frame_rate_filter.nil? or frame_rate_filter !~ /fps=/) and
1707
+ crop_filter.nil? and
1708
+ scale_filter.nil?
1709
+ decode_options += ['-hwaccel_output_format', 'cuda']
1710
+ nvenc_gpu_only = true
1711
+ frame_rate_filter.sub!(/^yadif/, 'yadif_cuda') unless frame_rate_filter.nil?
1712
+ end
1713
+
1658
1714
  if decode_method == 'qsv' and
1659
1715
  overlay_filter.nil? and
1660
1716
  frame_rate_filter.nil? and
@@ -1687,15 +1743,27 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
1687
1743
  end
1688
1744
  end
1689
1745
 
1746
+ ten_bit = (@ten_bit ? (@eight_bit_vc1 ? (video['codec_name'] != 'vc1') : true) : false)
1747
+ pix_fmt = true
1748
+
1690
1749
  if @encoder =~ /vaapi$/ and not decode_options.include?('-hwaccel')
1691
1750
  conversion_filter = 'format=nv12,hwupload'
1751
+ elsif nvenc_gpu_only
1752
+ conversion_filter = "scale_cuda=format=#{ten_bit ? 'p010le' : 'yuv420p'}"
1753
+ pix_fmt = false
1692
1754
  else
1693
1755
  conversion_filter = nil
1694
1756
  end
1695
1757
 
1758
+ encode_options = []
1759
+
1696
1760
  if @encoder == 'copy'
1697
1761
  filter = ''
1698
1762
  else
1763
+ if video['codec_name'] == 'mpeg2video' and video['avg_frame_rate'] == '30000/1001'
1764
+ encode_options += ['-vsync', 'cfr']
1765
+ end
1766
+
1699
1767
  filter = overlay_filter.nil? ? '' : overlay_filter
1700
1768
  filter += frame_rate_filter.nil? ? '' : ",#{frame_rate_filter}"
1701
1769
  filter += crop_filter.nil? ? '' : ",#{crop_filter}"
@@ -1705,7 +1773,7 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
1705
1773
  end
1706
1774
 
1707
1775
  if overlay_filter.nil?
1708
- encode_options = [
1776
+ encode_options += [
1709
1777
  '-map', "0:#{video['index']}"
1710
1778
  ]
1711
1779
 
@@ -1715,66 +1783,65 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
1715
1783
  ]
1716
1784
  end
1717
1785
  else
1718
- encode_options = [
1786
+ encode_options += [
1719
1787
  '-filter_complex', "[0:#{video['index']}]#{filter}[v]",
1720
1788
  '-map', '[v]'
1721
1789
  ]
1722
1790
  end
1723
1791
 
1724
- hdr = ((video.fetch('pix_fmt', 'yuv420p') == 'yuv420p10le') and @ten_bit)
1792
+ color_primaries = video['color_primaries']
1793
+ color_trc = video['color_transfer']
1794
+ color_trc = 'gamma22' if color_trc == 'bt470m'
1795
+ color_trc = 'gamma28' if color_trc == 'bt470bg'
1796
+ colorspace = video['color_space']
1725
1797
 
1726
- if hdr
1727
- color_primaries = 'bt2020'
1728
- color_trc = 'smpte2084'
1729
- colorspace = 'bt2020nc'
1730
- else
1731
- color_primaries = 'bt709'
1732
- color_trc = 'bt709'
1733
- colorspace = 'bt709'
1798
+ if (video.fetch('pix_fmt', 'yuv420p') == 'yuv420p10le') and ten_bit
1799
+ color_primaries ||= 'bt2020'
1800
+ color_trc ||= 'smpte2084'
1801
+ colorspace ||= 'bt2020nc'
1734
1802
  end
1735
1803
 
1736
1804
  if width > 1920 or height > 1080
1805
+ level = '5.1'
1737
1806
  bitrate = @target_2160p
1738
- max_bitrate = 40000
1739
- max_dpb_mbs = 184320
1807
+ max_bitrate = @hevc ? 25000 : 135000 # Level 5 HEVC Main 10 or H.264 Main
1740
1808
  elsif width > 1280 or height > 720
1809
+ level = '4'
1741
1810
  bitrate = @target_1080p
1742
- max_bitrate = 20000
1743
- max_dpb_mbs = 32768
1811
+ max_bitrate = @hevc ? 12000 : 20000 # Level 4
1744
1812
  elsif width > 720 or height > 576
1813
+ level = '3.1'
1745
1814
  bitrate = @target_720p
1746
- max_bitrate = 10000
1747
- max_dpb_mbs = 18000
1815
+ max_bitrate = @hevc ? 10000 : 14000 # Level 3.1
1748
1816
  else
1817
+ color_primaries ||= (width == 720 and height == 576 and video['codec_name'] == 'mpeg2video') ? 'bt470bg' : 'smpte170m'
1818
+ colorspace ||= 'smpte170m'
1819
+ level = '3'
1749
1820
  bitrate = @target_480p
1750
- max_bitrate = 5000
1751
- max_dpb_mbs = 8100
1752
-
1753
- unless hdr
1754
- color_primaries = pal ? 'bt470bg' : 'smpte170m'
1755
- colorspace = 'smpte170m'
1756
- end
1821
+ max_bitrate = @hevc ? 6000 : 10000 # Level 3
1757
1822
  end
1758
1823
 
1824
+ color_primaries ||= 'bt709'
1825
+ color_trc ||= 'bt709'
1826
+ colorspace ||= 'bt709'
1759
1827
  bitrate = @target unless @target.nil?
1760
1828
  bitrate = [bitrate, max_bitrate].min
1761
- maxrate = 0
1762
- bufsize = 0
1763
1829
 
1764
1830
  if @encoder =~ /(nvenc|hevc_qsv|libx26[45])$/
1765
- if @maxrate.nil?
1766
- maxrate = bitrate * 3
1767
- else
1768
- maxrate = [[(bitrate * @maxrate).to_i, (bitrate * 1.5).to_i].max, bitrate * 3].min
1831
+ maxrate = [max_bitrate, bitrate * 2].max
1832
+
1833
+ unless @maxrate.nil?
1834
+ maxrate = [[(@maxrate < bitrate ? bitrate * @maxrate : @maxrate).to_i, bitrate].max, maxrate].min
1769
1835
  end
1770
1836
 
1771
- if @bufsize.nil?
1772
- bufsize = maxrate if @encoder =~ /(nvenc|libx26[45])$/
1773
- else
1774
- unless @bufsize == 0 and @encoder =~ /nvenc$/
1775
- bufsize = [[(bitrate * @bufsize).to_i, bitrate].max, bitrate * 4].min
1776
- end
1837
+ bufsize = @encoder == 'hevc_qsv' ? 0 : maxrate
1838
+
1839
+ unless @bufsize.nil?
1840
+ bufsize = [[(@bufsize < bitrate ? bitrate * @bufsize : @bufsize).to_i, bitrate].max, maxrate].min
1777
1841
  end
1842
+ else
1843
+ maxrate = 0
1844
+ bufsize = 0
1778
1845
  end
1779
1846
 
1780
1847
  unless @preset.nil?
@@ -1806,7 +1873,7 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
1806
1873
  text = "#{sprintf("%2d", video['index'])} = #{@encoder}"
1807
1874
 
1808
1875
  unless @encoder == 'copy'
1809
- text += " / #{bitrate} Kbps"
1876
+ text += @nvenc_cq.nil? ? " / #{bitrate} Kbps" : " / #{@nvenc_cq} CQ"
1810
1877
  text += " / #{@preset}" unless @preset.nil?
1811
1878
  end
1812
1879
 
@@ -1816,21 +1883,25 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
1816
1883
 
1817
1884
  Kernel.warn text
1818
1885
  encode_options += ['-c:v', @encoder]
1819
- encode_options += ['-pix_fmt:v', (@encoder =~ /(nvenc|qsv)$/ ? 'p010le' : 'yuv420p10le')] if @ten_bit
1820
- encode_options += ['-b:v', "#{bitrate}k"] unless @encoder == 'copy'
1886
+ encode_options += ['-pix_fmt:v', (@encoder =~ /(videotoolbox|nvenc|qsv)$/ ? 'p010le' : 'yuv420p10le')] if ten_bit and pix_fmt
1887
+ encode_options += (@nvenc_cq.nil? ? ['-b:v', "#{bitrate}k"] : ['-cq:v', @nvenc_cq]) unless @encoder == 'copy'
1821
1888
  encode_options += ['-maxrate:v', "#{maxrate}k"] if maxrate > 0
1822
1889
  encode_options += ['-bufsize:v', "#{bufsize}k"] if bufsize > 0
1823
1890
  encode_options += ['-preset:v', @preset] unless @preset.nil?
1824
- encode_options += ['-allow_sw:v', '1'] if @encoder =~ /videotoolbox$/ and @vt_allow_sw
1891
+
1892
+ if @encoder =~ /videotoolbox$/
1893
+ encode_options += ['-allow_sw:v', '1'] if @vt_allow_sw
1894
+ encode_options += ['-profile:v', 'main10'] if ten_bit
1895
+ end
1825
1896
 
1826
1897
  if @encoder =~ /nvenc$/
1827
- encode_options += ['-rc:v', @nvenc_rc_mode]
1828
1898
  encode_options += ['-spatial-aq:v', '1'] if @nvenc_spatial_aq
1829
1899
  encode_options += ['-temporal-aq:v', '1'] if @nvenc_temporal_aq
1830
1900
  encode_options += ['-rc-lookahead:v', @nvenc_lookahead.to_s] unless @nvenc_lookahead.nil?
1831
1901
  encode_options += ['-multipass:v', @nvenc_multipass] unless @nvenc_multipass.nil?
1832
1902
  encode_options += ['-refs:v', @nvenc_refs.to_s] unless @nvenc_refs.nil?
1833
1903
  encode_options += ['-bf:v', @nvenc_bframes.to_s] unless @nvenc_bframes.nil?
1904
+ encode_options += ['-b_ref_mode:v', @nvenc_bframe_refs] unless @nvenc_bframe_refs.nil?
1834
1905
  end
1835
1906
 
1836
1907
  if @encoder =~ /qsv$/
@@ -1866,20 +1937,10 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
1866
1937
  ]
1867
1938
  end
1868
1939
  else
1869
- max_refs = [(max_dpb_mbs / (((width + 15) / 16) * ((height + 15) / 16))), 16].min
1870
-
1871
1940
  case @preset
1872
- when 'slow'
1873
- refs = 5
1874
- when 'slower'
1875
- refs = 8
1876
- when 'veryslow', 'placebo'
1877
- refs = 16
1878
- else
1879
- refs = 0
1941
+ when 'slow', 'slower', 'veryslow', 'placebo'
1942
+ encode_options += ['-level:v', level]
1880
1943
  end
1881
-
1882
- encode_options += ['-refs:v', max_refs.to_s] if refs > max_refs
1883
1944
  end
1884
1945
 
1885
1946
  encode_options += ['-x264-params:v', @x264_params] unless @x264_params.nil?
@@ -1889,7 +1950,7 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
1889
1950
  encode_options += ['-x265-params:v', @x265_params] unless @x265_params.nil?
1890
1951
  end
1891
1952
 
1892
- unless @ten_bit
1953
+ unless ten_bit
1893
1954
  encode_options += ['-profile:v', 'high'] if @encoder =~ /^(h264_nvenc|h264_amf|libx264)$/
1894
1955
  end
1895
1956
 
@@ -1932,15 +1993,7 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
1932
1993
 
1933
1994
  audio_tracks = [{
1934
1995
  :stream => main_audio,
1935
- :width => width,
1936
- :bitrate => case width
1937
- when :stereo
1938
- @stereo_bitrate
1939
- when :surround
1940
- @surround_bitrate
1941
- when :original
1942
- nil
1943
- end
1996
+ :width => width
1944
1997
  }]
1945
1998
 
1946
1999
  titles = {}
@@ -1954,15 +2007,6 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
1954
2007
 
1955
2008
  width = selection[:width]
1956
2009
 
1957
- bitrate = case width
1958
- when :stereo
1959
- @stereo_bitrate
1960
- when :surround
1961
- @surround_bitrate
1962
- when :original
1963
- nil
1964
- end
1965
-
1966
2010
  unless selection[:track].nil?
1967
2011
  audio_track = 0
1968
2012
 
@@ -1974,8 +2018,7 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
1974
2018
  if audio_track == selection[:track]
1975
2019
  audio_tracks += [{
1976
2020
  :stream => stream,
1977
- :width => width,
1978
- :bitrate => bitrate
2021
+ :width => width
1979
2022
  }]
1980
2023
 
1981
2024
  break
@@ -1992,8 +2035,7 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
1992
2035
  stream['index'] != main_audio['index']
1993
2036
  audio_tracks += [{
1994
2037
  :stream => stream,
1995
- :width => width,
1996
- :bitrate => bitrate
2038
+ :width => width
1997
2039
  }]
1998
2040
  end
1999
2041
  end
@@ -2008,8 +2050,7 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
2008
2050
  if title =~ /#{selection[:title]}/i and stream['index'] != main_audio['index']
2009
2051
  audio_tracks += [{
2010
2052
  :stream => stream,
2011
- :width => width,
2012
- :bitrate => bitrate
2053
+ :width => width
2013
2054
  }]
2014
2055
 
2015
2056
  titles[stream['index']] = title
@@ -2035,23 +2076,32 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
2035
2076
  if track[:width] == :original
2036
2077
  encoder = 'copy'
2037
2078
  else
2079
+ input_bitrate = track[:stream].fetch('bit_rate', '256').to_i / 1000
2038
2080
  dts = (codec_name == 'dts' and track[:stream].fetch('profile', 'DTS') =~ /^DTS(?:-ES)?$/)
2039
2081
 
2040
2082
  if track[:width] == :surround
2041
- if ((codec_name == @surround_encoder or codec_name == 'ac3') and
2042
- (@keep_ac3_surround or (track[:stream]['bit_rate'].to_i / 1000) <= @surround_bitrate)) or
2083
+ if (@surround_encoder =~ /aac/ and codec_name == 'aac') or
2084
+ (@surround_encoder =~ /ac3$/ and
2085
+ (codec_name == @surround_encoder or codec_name == 'ac3') and
2086
+ (@keep_ac3_surround or input_bitrate <= (@surround_bitrate.nil? ? 640 : @surround_bitrate))) or
2043
2087
  (@pass_dts and dts)
2044
2088
  encoder = 'copy'
2045
2089
  elsif input_channels > 2
2046
2090
  encoder = @surround_encoder
2047
2091
  bitrate = @surround_bitrate
2092
+
2093
+ if encoder =~ /aac/
2094
+ encoder = @aac_fallback_encoder if encoder == 'aac_at'
2095
+ channels = 6
2096
+ end
2048
2097
  end
2049
2098
  end
2050
2099
 
2051
2100
  if encoder.nil?
2052
2101
  if input_channels <= 2 and (codec_name == 'aac' or
2053
- ((codec_name == @surround_encoder or codec_name == 'ac3') and
2054
- (@keep_ac3_stereo or (track[:stream]['bit_rate'].to_i / 1000) <= @stereo_bitrate)) or
2102
+ (@surround_encoder =~ /ac3$/ and
2103
+ (codec_name == @surround_encoder or codec_name == 'ac3') and
2104
+ (@keep_ac3_stereo or input_bitrate <= (@stereo_bitrate.nil? ? 256 : @stereo_bitrate))) or
2055
2105
  (@pass_dts and dts))
2056
2106
  encoder = 'copy'
2057
2107
  else
@@ -2080,19 +2130,19 @@ Requires `ffprobe`, `ffmpeg` and `mkvpropedit`.
2080
2130
  configurations[input_index] = configuration
2081
2131
  text = "#{sprintf("%2d", input_index)} = #{encoder}"
2082
2132
  text += " / #{bitrate} Kbps" unless bitrate.nil?
2083
- text += ' / stereo' unless channels.nil?
2133
+ text += ' / stereo' unless channels.nil? or channels > 2
2084
2134
  text += " / #{titles[input_index]}" if titles.has_key?(input_index)
2085
2135
  Kernel.warn text
2086
2136
  copy_track_name = (@copy_track_names or titles.has_key?(input_index))
2087
2137
 
2088
2138
  options += [
2089
2139
  '-map', "0:#{input_index}",
2090
- "-c:a:#{index}", encoder
2091
- ] + (encoder == 'aac_at' ? ["-aac_at_mode:a:#{index}", 'cvbr'] : []) +
2092
- (bitrate.nil? ? [] : ["-b:a:#{index}", "#{bitrate}k"]) +
2093
- (channels.nil? ? [] : ["-ac:a:#{index}", "#{channels}"]) +
2094
- (track[:stream]['sample_rate'] != '48000' ? ["-ar:a:#{index}", '48000'] : []) +
2095
- (copy_track_name ? [] : ["-metadata:s:a:#{index}", 'title=']) + [
2140
+ "-c:a:#{index}", encoder,
2141
+ *(encoder == 'aac_at' ? ["-aac_at_mode:a:#{index}", 'cvbr'] : []),
2142
+ *(bitrate.nil? ? [] : ["-b:a:#{index}", "#{bitrate}k"]),
2143
+ *(channels.nil? ? [] : ["-ac:a:#{index}", "#{channels}"]),
2144
+ *((encoder != 'copy' and track[:stream]['sample_rate'] != '48000') ? ["-ar:a:#{index}", '48000'] : []),
2145
+ *(copy_track_name ? [] : ["-metadata:s:a:#{index}", 'title=']),
2096
2146
  "-disposition:a:#{index}", (index == 0 ? 'default' : '0')
2097
2147
  ]
2098
2148
 
Binary file
Binary file
Binary file
Binary file
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'other_video_transcoding'
3
- s.version = '0.6.0'
3
+ s.version = '0.10.0'
4
4
  s.required_ruby_version = '>= 2.0'
5
5
  s.summary = 'Other tools to transcode videos.'
6
6
  s.description = <<-HERE
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: other_video_transcoding
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Don Melton
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-23 00:00:00.000000000 Z
11
+ date: 2022-01-27 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: " Other Video Transcoding is a package of tools to transcode videos.\n"
14
14
  email: don@blivet.com
@@ -33,6 +33,10 @@ files:
33
33
  - other_video_transcoding-0.3.2.gem
34
34
  - other_video_transcoding-0.4.0.gem
35
35
  - other_video_transcoding-0.5.0.gem
36
+ - other_video_transcoding-0.6.0.gem
37
+ - other_video_transcoding-0.7.0.gem
38
+ - other_video_transcoding-0.8.0.gem
39
+ - other_video_transcoding-0.9.0.gem
36
40
  - other_video_transcoding.gemspec
37
41
  homepage: https://github.com/donmelton/other_video_transcoding
38
42
  licenses:
@@ -53,7 +57,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
53
57
  - !ruby/object:Gem::Version
54
58
  version: '0'
55
59
  requirements: []
56
- rubygems_version: 3.1.2
60
+ rubygems_version: 3.1.6
57
61
  signing_key:
58
62
  specification_version: 4
59
63
  summary: Other tools to transcode videos.