Skip to content

Commit 700e7c4

Browse files
committed
Use correct audio bitrates for target filesize mode, warn if no br left for video
1 parent a56d2e5 commit 700e7c4

File tree

3 files changed

+55
-12
lines changed

3 files changed

+55
-12
lines changed

ff-utils-winforms/Nmkoder.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,7 @@
417417
<Compile Include="UI\Tasks\QuickConvertUi.cs" />
418418
<Compile Include="UI\ThumbnailView.cs" />
419419
<Compile Include="UI\UiUtils.cs" />
420+
<Compile Include="Utils\BitrateCalculation.cs" />
420421
<Compile Include="Utils\BitratePlottingUtils.cs" />
421422
<Compile Include="Utils\ColorDataUtils.cs" />
422423
<Compile Include="Utils\ConcatUtils.cs" />

ff-utils-winforms/UI/Tasks/QuickConvertUi.cs

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -277,18 +277,7 @@ private static int GetVideoKbps()
277277

278278
if ((QualityMode)Program.mainForm.encQualModeBox.SelectedIndex == QualityMode.TargetMbytes)
279279
{
280-
bool aud = !CodecUtils.GetCodec(GetCurrentCodecA()).DoesNotEncode;
281-
int audioTracks = form.streamList.CheckedItems.Cast<ListViewItem>().Where(x => ((StreamListEntry)x.Tag).Stream.Type == Stream.StreamType.Audio).Count();
282-
int audioBps = aud ? ((int)form.encAudQualUpDown.Value * 1024) * audioTracks : 0;
283-
double durationSecs = TrackList.current.File.DurationMs / (double)1000;
284-
float targetMbytes = form.encVidQualityBox.Text.GetFloat();
285-
long targetBits = (long)Math.Round(targetMbytes * 8 * 1024 * 1024);
286-
int targetVidBitrate = (int)Math.Floor(targetBits / durationSecs) - audioBps; // Round down since undershooting is better than overshooting here
287-
string brTotal = (((float)targetVidBitrate + audioBps) / 1024).ToString("0.0");
288-
string brVid = ((float)targetVidBitrate / 1024).ToString("0");
289-
string brAud = ((float)audioBps / 1024).ToString("0");
290-
Logger.Log($"Target Filesize Mode: Using bitrate of {brTotal} kbps ({brVid}k Video, {brAud}k Audio) over {durationSecs.ToString("0.0")} seconds to hit {targetMbytes} megabytes.");
291-
return ((float)targetVidBitrate / 1024).RoundToInt();
280+
return BitrateCalculation.GetTargetSizeKbps(CodecUtils.GetCodec(GetCurrentCodecA()));
292281
}
293282

294283
return 0;
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
using Nmkoder.Data;
2+
using Nmkoder.Data.Codecs;
3+
using Nmkoder.Data.Streams;
4+
using Nmkoder.Data.Ui;
5+
using Nmkoder.Extensions;
6+
using Nmkoder.Forms;
7+
using Nmkoder.IO;
8+
using Nmkoder.Main;
9+
using Nmkoder.UI;
10+
using System;
11+
using System.Collections.Generic;
12+
using System.Linq;
13+
using System.Text;
14+
using System.Threading.Tasks;
15+
using System.Windows.Forms;
16+
17+
namespace Nmkoder.Utils
18+
{
19+
class BitrateCalculation
20+
{
21+
public static int GetTargetSizeKbps(IEncoder aCodec, bool silent = false)
22+
{
23+
MainForm form = Program.mainForm;
24+
bool aud = !aCodec.DoesNotEncode;
25+
26+
string audArgs = CodecUtils.GetAudioArgsForEachStream(TrackList.current.File, (int)form.encAudQualUpDown.Value, form.encAudChannelsBox.GetInt());
27+
28+
List<int> audioBitrates = audArgs.Split("-b:a:").Where(x => x.Contains("k ")).Select(x => x.Split(' ')[1].GetInt()).ToList(); //aud ? ((int)form.encAudQualUpDown.Value * 1024) * audioTracks : 0;
29+
int audioBps = audioBitrates.Select(x => x * 1024).Sum();
30+
31+
double durationSecs = TrackList.current.File.DurationMs / (double)1000;
32+
float targetMbytes = form.encVidQualityBox.Text.GetFloat();
33+
long targetBits = (long)Math.Round(targetMbytes * 8 * 1024 * 1024);
34+
int targetVidBitrate = (int)Math.Floor(targetBits / durationSecs) - audioBps; // Round down since undershooting is better than overshooting here
35+
36+
string brTotal = (((float)targetVidBitrate + audioBps) / 1024).ToString("0.0");
37+
string brVid = ((float)targetVidBitrate / 1024).ToString("0");
38+
string brAud = ((float)audioBps / 1024).ToString("0");
39+
40+
if (targetVidBitrate < 0)
41+
{
42+
RunTask.Cancel($"Target Filesize Mode:\n\nNo bitrate left for video ({brVid}k) after {audioBitrates.Count} audio tracks ({string.Join(" + ", audioBitrates.Select(x => $"{x}k"))} = {brAud}k)." +
43+
$"\n\nUse a lower audio bitrate or fewer/no audio tracks.");
44+
return -1;
45+
}
46+
47+
if (!silent)
48+
Logger.Log($"Target Filesize Mode: Using bitrate of {brTotal} kbps ({brVid}k Video, {brAud}k Audio) over {durationSecs.ToString("0.0")} seconds to hit {targetMbytes} megabytes.");
49+
50+
return ((float)targetVidBitrate / 1024).RoundToInt();
51+
}
52+
}
53+
}

0 commit comments

Comments
 (0)