Browse Source

feat: ui 增加crf选择能力

hexleo 4 years ago
parent
commit
5f93f1f4b0

+ 0 - 2
Android/PlayerProj/animtool/src/main/java/com/tencent/qgame/playerproj/animtool/AnimTool.java

@@ -327,7 +327,6 @@ public class AnimTool {
                         "-crf", Integer.toString(commonArg.crf),
                         "-profile:v", "main",
                         "-level", "4.0",
-                        "-bf", "0",
                         "-tag:v", "hvc1",
                         "-bufsize", "2000k",
                         "-y", videoPath + TEMP_VIDEO_FILE};
@@ -339,7 +338,6 @@ public class AnimTool {
                         "-b:v", commonArg.bitrate + "k",
                         "-profile:v", "main",
                         "-level", "4.0",
-                        "-bf", "0",
                         "-tag:v", "hvc1",
                         "-bufsize", "2000k",
                         "-y", videoPath + TEMP_VIDEO_FILE};

+ 18 - 11
Android/PlayerProj/animtool/src/main/java/com/tencent/qgame/playerproj/animtool/CommonArgTool.java

@@ -138,14 +138,14 @@ class CommonArgTool {
         }
 
         // 计算出 16倍数的视频
-        int[] size = calSizeFill(commonArg.outputW, commonArg.outputH, 0, 0);
+        int[] size = calSizeFill(commonArg.outputW, commonArg.outputH);
         // 得到最终视频宽高
         commonArg.outputW += size[0];
         commonArg.outputH += size[1];
 
         if (commonArg.outputW > 1504 || commonArg.outputH > 1504) {
             String msg = "[Warning] Output video width:" + commonArg.outputW + " or height:" + commonArg.outputH
-                    + " is over 1504. Some devices will display exception, like video turn green!";
+                    + " is over 1504. Some devices will display exception. For example green screen!";
             TLog.w(TAG, msg);
             if (toolListener != null) {
                 toolListener.onWarning(msg);
@@ -170,27 +170,34 @@ class CommonArgTool {
         }
 
         // 码率检查
-        if (commonArg.bitrate <= 0) {
+        if (!commonArg.enableCrf && commonArg.bitrate <= 0) {
             TLog.e(TAG, "bitrate=" + commonArg.bitrate);
             return false;
         }
 
+        // crf检查
+        if (commonArg.enableCrf && (commonArg.crf < 0 || commonArg.crf > 51)) {
+            TLog.e(TAG, "crf=" + commonArg.crf + ", no in [0, 51]");
+            return false;
+        }
+
         return true;
     }
 
     /**
      * 寻找最小wFill & hFill情况下 整个视频宽高能被16整除
      */
-    private static int[] calSizeFill(int outW, int outH, int wFill, int hFill) {
-        boolean wCheck = (outW + wFill)% 16 == 0;
-        boolean hCheck = (outH + hFill) % 16 == 0;
-
-        if (wCheck && hCheck) {
-            return new int[]{wFill, hFill};
+    private static int[] calSizeFill(int outW, int outH) {
+        int wFill = 0;
+        if (outW % 16 != 0) {
+            wFill = ((outW / 16) + 1) * 16 - outW;
         }
 
-        // 递归计算
-        return calSizeFill(outW, outH, wCheck? wFill : wFill + 1, hCheck? hFill : hFill + 1);
+        int hFill = 0;
+        if (outH % 16 != 0) {
+            hFill = ((outH / 16) + 1) * 16 - outH;
+        }
+        return new int[]{wFill, hFill};
     }
 
 

+ 83 - 6
Android/PlayerProj/animtool/src/main/java/com/tencent/qgame/playerproj/animtool/ui/ToolUI.java

@@ -11,6 +11,8 @@ import java.awt.GridLayout;
 import java.awt.Toolkit;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
 import java.io.File;
@@ -58,7 +60,15 @@ public class ToolUI {
     private final JTextArea txtAreaLog = new JTextArea();
     private final JTextField textAudioPath = new JTextField();
     private final JPanel panelAudioPath = new JPanel();
+
+    private final JPanel panelBitrate = new JPanel();
     private final JTextField textBitrate = new JTextField();
+    private final JPanel panelCrf = new JPanel();
+    private final JTextField textCrf = new JTextField();
+
+    private final ButtonGroup groupQuality = new ButtonGroup();
+    private final JRadioButton btnBitrate = new JRadioButton("bitrate");
+    private final JRadioButton btnCrf = new JRadioButton("crf");
 
     private final JLabel labelOutInfo = new JLabel();
     private final Dimension labelSize = new Dimension(100, 20);
@@ -67,6 +77,19 @@ public class ToolUI {
 
     private boolean needAudio = false;
 
+    private final ItemListener qualityGroupListener = new ItemListener() {
+        @Override
+        public void itemStateChanged(ItemEvent itemEvent) {
+            if (itemEvent.getSource() == btnBitrate) {
+                panelBitrate.setVisible(true);
+                panelCrf.setVisible(false);
+            } else if (itemEvent.getSource() == btnCrf) {
+                panelBitrate.setVisible(false);
+                panelCrf.setVisible(true);
+            }
+        }
+    };
+
     public ToolUI() {
         TLog.logger = new TLog.ITLog() {
             @Override
@@ -105,8 +128,18 @@ public class ToolUI {
             textInputPath.setText(commonArg.inputPath);
             textAudioPath.setText(commonArg.audioPath);
             textBitrate.setText(String.valueOf(commonArg.bitrate));
+            textCrf.setText(String.valueOf(commonArg.crf));
+            groupQuality.setSelected(commonArg.enableCrf ? btnCrf.getModel() : btnBitrate.getModel(), true);
+            if (commonArg.enableCrf) {
+                panelBitrate.setVisible(false);
+                panelCrf.setVisible(true);
+            } else {
+                panelBitrate.setVisible(true);
+                panelCrf.setVisible(false);
+            }
+
             float scale = commonArg.scale;
-            for (int i=0; i<scaleArray.length ; i++) {
+            for (int i = 0; i < scaleArray.length ; i++) {
                 if (scaleArray[i] == scale) {
                     boxScale.setSelectedIndex(i);
                     break;
@@ -165,7 +198,9 @@ public class ToolUI {
             }
         }
         try {
+            commonArg.enableCrf = groupQuality.isSelected(btnCrf.getModel());
             commonArg.bitrate = Integer.parseInt(textBitrate.getText());
+            commonArg.crf = Integer.parseInt(textCrf.getText());
         } catch (NumberFormatException e) {
             TLog.e(TAG, "bitrate format error " + textBitrate.getText() + e.getMessage());
         }
@@ -231,8 +266,12 @@ public class ToolUI {
         panel.add(getCodecLayout());
         // fps
         panel.add(getFpsLayout());
+        // bitrate/crf switch
+        panel.add(getQualityLayout());
         // bitrate
         panel.add(getBitrateLayout());
+        // crf
+        panel.add(getCrfLayout());
         // scale
         panel.add(getScaleLayout());
         // path
@@ -282,18 +321,50 @@ public class ToolUI {
         return panel;
     }
 
-    private JPanel getBitrateLayout() {
+    private JPanel getQualityLayout() {
         JPanel panel = new JPanel();
         panel.setLayout(new FlowLayout(FlowLayout.LEFT));
-        JLabel label = new JLabel("bitrate");
+
+        JLabel label = new JLabel("quality");
         label.setPreferredSize(labelSize);
         panel.add(label);
-        textBitrate.setPreferredSize(new Dimension(60, 20));
-        panel.add(textBitrate);
-        panel.add(new JLabel("k (default 2000k)"));
+
+        JPanel panelRadio = new JPanel();
+        panelRadio.setLayout(new GridLayout(1, 2));
+        panelRadio.add(btnBitrate);
+        panelRadio.add(btnCrf);
+        groupQuality.add(btnBitrate);
+        groupQuality.add(btnCrf);
+        groupQuality.setSelected(btnBitrate.getModel(), true);
+        btnBitrate.addItemListener(qualityGroupListener);
+        btnCrf.addItemListener(qualityGroupListener);
+        panel.add(panelRadio);
+
         return panel;
     }
 
+    private JPanel getBitrateLayout() {
+        panelBitrate.setLayout(new FlowLayout(FlowLayout.LEFT));
+        JLabel label = new JLabel("bitrate");
+        label.setPreferredSize(labelSize);
+        panelBitrate.add(label);
+        textBitrate.setPreferredSize(new Dimension(60, 20));
+        panelBitrate.add(textBitrate);
+        panelBitrate.add(new JLabel("k (default 2000k)"));
+        return panelBitrate;
+    }
+
+    private JPanel getCrfLayout() {
+        panelCrf.setLayout(new FlowLayout(FlowLayout.LEFT));
+        JLabel label = new JLabel("crf");
+        label.setPreferredSize(labelSize);
+        panelCrf.add(label);
+        textCrf.setPreferredSize(new Dimension(60, 20));
+        panelCrf.add(textCrf);
+        panelCrf.add(new JLabel("[0, 51] (default 29)"));
+        return panelCrf;
+    }
+
     private JPanel getScaleLayout() {
         JPanel panel = new JPanel();
         panel.setLayout(new FlowLayout(FlowLayout.LEFT));
@@ -476,6 +547,8 @@ public class ToolUI {
             String scale = props.getProperty("scale", String.valueOf(scaleArray[0]));
             String audioPath = props.getProperty("audioPath", "");
             String bitrate = props.getProperty("bitrate", String.valueOf(commonArg.bitrate));
+            String enableCrf = props.getProperty("enableCrf", String.valueOf(commonArg.enableCrf));
+            String crf = props.getProperty("crf", String.valueOf(commonArg.crf));
 
             int v = Integer.parseInt(version);
             // 版本不符直接返回默认值
@@ -486,6 +559,8 @@ public class ToolUI {
             commonArg.inputPath = inputPath;
             commonArg.audioPath = audioPath;
             commonArg.bitrate = Integer.parseInt(bitrate);
+            commonArg.enableCrf = Boolean.TRUE.toString().equals(enableCrf);
+            commonArg.crf = Integer.parseInt(crf);
         } catch (Exception e) {
             TLog.e(TAG, "getProperties error:" + e.getMessage());
         }
@@ -501,6 +576,8 @@ public class ToolUI {
         props.setProperty("audioPath", commonArg.audioPath == null ? "" : commonArg.audioPath);
         props.setProperty("scale", String.valueOf(commonArg.scale));
         props.setProperty("bitrate", String.valueOf(commonArg.bitrate));
+        props.setProperty("crf", String.valueOf(commonArg.crf));
+        props.setProperty("enableCrf", String.valueOf(commonArg.enableCrf));
         props.store(new OutputStreamWriter(new FileOutputStream(PROPERTIES_FILE), StandardCharsets.UTF_8), "");
     }