Package net.pms.encoders

Source Code of net.pms.encoders.AviSynthMEncoder

/*
* PS3 Media Server, for streaming any medias to your PS3.
* Copyright (C) 2008  A.Brochard
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License only.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/
package net.pms.encoders;

import com.jgoodies.forms.builder.PanelBuilder;
import com.jgoodies.forms.factories.Borders;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.StringTokenizer;
import javax.swing.*;
import net.pms.Messages;
import net.pms.PMS;
import net.pms.configuration.PmsConfiguration;
import net.pms.dlna.DLNAMediaSubtitle;
import net.pms.dlna.DLNAResource;
import net.pms.formats.Format;
import net.pms.formats.v2.SubtitleType;
import net.pms.util.PlayerUtil;
import net.pms.util.ProcessUtil;
import org.apache.commons.configuration.event.ConfigurationEvent;
import org.apache.commons.configuration.event.ConfigurationListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class AviSynthMEncoder extends MEncoderVideo {
  private static final Logger LOGGER = LoggerFactory.getLogger(AviSynthMEncoder.class);

  @Deprecated
  public AviSynthMEncoder(PmsConfiguration configuration) {
    this();
  }

  public AviSynthMEncoder() {
  }

  public static final String ID = "avsmencoder";

  private JTextArea textArea;
  private JCheckBox convertfps;
  private JCheckBox interframe;
  private static JCheckBox interframegpu;
  private JCheckBox multithreading;

  @Override
  public JComponent config() {
    FormLayout layout = new FormLayout(
      "left:pref, 0:grow",
      "p, 3dlu, p, 3dlu, p, 3dlu, p, 3dlu, p, 12dlu, p, 3dlu, 0:grow"
    );
    PanelBuilder builder = new PanelBuilder(layout);
    builder.border(Borders.EMPTY);
    builder.opaque(false);

    CellConstraints cc = new CellConstraints();

    JComponent cmp = builder.addSeparator(Messages.getString("NetworkTab.5"), cc.xyw(2, 1, 1));
    cmp = (JComponent) cmp.getComponent(0);
    cmp.setFont(cmp.getFont().deriveFont(Font.BOLD));

    multithreading = new JCheckBox(Messages.getString("MEncoderVideo.35"), configuration.getAvisynthMultiThreading());
    multithreading.setContentAreaFilled(false);
    multithreading.addItemListener(new ItemListener() {
      @Override
      public void itemStateChanged(ItemEvent e) {
        configuration.setAvisynthMultiThreading((e.getStateChange() == ItemEvent.SELECTED));
      }
    });
    builder.add(multithreading, cc.xy(2, 3));

    interframe = new JCheckBox(Messages.getString("AviSynthMEncoder.13"), configuration.getAvisynthInterFrame());
    interframe.setContentAreaFilled(false);
    interframe.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        configuration.setAvisynthInterFrame(interframe.isSelected());
        if (configuration.getAvisynthInterFrame()) {
          JOptionPane.showMessageDialog(
            (JFrame) (SwingUtilities.getWindowAncestor((Component) PMS.get().getFrame())),
            Messages.getString("AviSynthMEncoder.16"),
            Messages.getString("Dialog.Information"),
            JOptionPane.INFORMATION_MESSAGE
          );
        }
      }
    });
    builder.add(interframe, cc.xy(2, 5));

    interframegpu = new JCheckBox(Messages.getString("AviSynthMEncoder.15"), configuration.getAvisynthInterFrameGPU());
    interframegpu.setContentAreaFilled(false);
    interframegpu.addItemListener(new ItemListener() {
      @Override
      public void itemStateChanged(ItemEvent e) {
        configuration.setAvisynthInterFrameGPU((e.getStateChange() == ItemEvent.SELECTED));
      }
    });
    builder.add(interframegpu, cc.xy(2, 7));

    convertfps = new JCheckBox(Messages.getString("AviSynthMEncoder.3"), configuration.getAvisynthConvertFps());
    convertfps.setContentAreaFilled(false);
    convertfps.addItemListener(new ItemListener() {
      @Override
      public void itemStateChanged(ItemEvent e) {
        configuration.setAvisynthConvertFps((e.getStateChange() == ItemEvent.SELECTED));
      }
    });
    builder.add(convertfps, cc.xy(2, 9));

    String aviSynthScriptInstructions = Messages.getString("AviSynthMEncoder.4") +
      Messages.getString("AviSynthMEncoder.5") +
      Messages.getString("AviSynthMEncoder.6") +
      Messages.getString("AviSynthMEncoder.7") +
      Messages.getString("AviSynthMEncoder.8");
    JTextArea aviSynthScriptInstructionsContainer = new JTextArea(aviSynthScriptInstructions);
    aviSynthScriptInstructionsContainer.setEditable(false);
    aviSynthScriptInstructionsContainer.setBorder(BorderFactory.createEtchedBorder());
    aviSynthScriptInstructionsContainer.setBackground(new Color(255, 255, 192));
    aviSynthScriptInstructionsContainer.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createLineBorder(new Color(130, 135, 144)), BorderFactory.createEmptyBorder(3, 5, 3, 5)));
    builder.add(aviSynthScriptInstructionsContainer, cc.xy(2, 11));

    String clip = configuration.getAvisynthScript();
    if (clip == null) {
      clip = "";
    }
    StringBuilder sb = new StringBuilder();
    StringTokenizer st = new StringTokenizer(clip, PMS.AVS_SEPARATOR);
    int i = 0;
    while (st.hasMoreTokens()) {
      if (i > 0) {
        sb.append("\n");
      }
      sb.append(st.nextToken());
      i++;
    }
    textArea = new JTextArea(sb.toString());
    textArea.addKeyListener(new KeyAdapter() {
      @Override
      public void keyReleased(KeyEvent e) {
        StringBuilder sb = new StringBuilder();
        StringTokenizer st = new StringTokenizer(textArea.getText(), "\n");
        int i = 0;
        while (st.hasMoreTokens()) {
          if (i > 0) {
            sb.append(PMS.AVS_SEPARATOR);
          }
          sb.append(st.nextToken());
          i++;
        }
        configuration.setAvisynthScript(sb.toString());
      }
    });

    JScrollPane pane = new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    pane.setPreferredSize(new Dimension(500, 350));
    builder.add(pane, cc.xy(2, 13));

    configuration.addConfigurationListener(new ConfigurationListener() {
      @Override
      public void configurationChanged(ConfigurationEvent event) {
        if (event.getPropertyName() == null) {
          return;
        }
        if ((!event.isBeforeUpdate()) && event.getPropertyName().equals(PmsConfiguration.KEY_GPU_ACCELERATION)) {
          interframegpu.setEnabled(configuration.isGPUAcceleration());
        }
      }
    });

    return builder.getPanel();
  }

  @Override
  public int purpose() {
    return VIDEO_SIMPLEFILE_PLAYER;
  }

  @Override
  public String id() {
    return ID;
  }

  @Override
  public boolean avisynth() {
    return true;
  }

  @Override
  public String name() {
    return "AviSynth/MEncoder";
  }

  @Override
  public boolean isGPUAccelerationReady() {
    return true;
  }

  /*
   * Generate the AviSynth script based on the user's settings
   */
  public static File getAVSScript(String fileName, DLNAMediaSubtitle subTrack, int fromFrame, int toFrame, String frameRateRatio, String frameRateNumber) throws IOException {
    String onlyFileName = fileName.substring(1 + fileName.lastIndexOf('\\'));
    File file = new File(configuration.getTempFolder(), "pms-avs-" + onlyFileName + ".avs");
    try (PrintWriter pw = new PrintWriter(new FileOutputStream(file))) {
      String numerator;
      String denominator;

      if (frameRateRatio != null && frameRateNumber != null) {
        if (frameRateRatio.equals(frameRateNumber)) {
          // No ratio was available
          numerator = frameRateRatio;
          denominator = "1";
        } else {
          String[] frameRateNumDen = frameRateRatio.split("/");
          numerator = frameRateNumDen[0];
          denominator = "1001";
        }
      } else {
        // No framerate was given so we should try the most common one
        numerator = "24000";
        denominator = "1001";
        frameRateNumber = "23.976";
      }

      String assumeFPS = ".AssumeFPS(" + numerator + "," + denominator + ")";

      String directShowFPS = "";
      if (!"0".equals(frameRateNumber)) {
        directShowFPS = ", fps=" + frameRateNumber;
      }

      String convertfps = "";
      if (configuration.getAvisynthConvertFps()) {
        convertfps = ", convertfps=true";
      }

      File f = new File(fileName);
      if (f.exists()) {
        fileName = ProcessUtil.getShortFileNameIfWideChars(fileName);
      }

      String movieLine       = "DirectShowSource(\"" + fileName + "\"" + directShowFPS + convertfps + ")" + assumeFPS;
      String mtLine1         = "";
      String mtLine2         = "";
      String mtLine3         = "";
      String interframeLines = null;
      String interframePath  = configuration.getInterFramePath();

      int Cores = 1;
      if (configuration.getAvisynthMultiThreading()) {
        Cores = configuration.getNumberOfCpuCores();

        // Goes at the start of the file to initiate multithreading
        mtLine1 = "SetMemoryMax(512)\nSetMTMode(3," + Cores + ")\n";

        // Goes after the input line to make multithreading more efficient
        mtLine2 = "SetMTMode(2)";

        // Goes at the end of the file to allow the multithreading to work with MEncoder
        mtLine3 = "SetMTMode(1)\nGetMTMode(false) > 0 ? distributor() : last";
      }

      // True Motion
      if (configuration.getAvisynthInterFrame()) {
        String GPU = "";
        movieLine += ".ConvertToYV12()";

        // Enable GPU to assist with CPU
        if (configuration.getAvisynthInterFrameGPU() && interframegpu.isEnabled()){
          GPU = ", GPU=true";
        }

        interframeLines = "\n" +
          "PluginPath = \"" + interframePath + "\"\n" +
          "LoadPlugin(PluginPath+\"svpflow1.dll\")\n" +
          "LoadPlugin(PluginPath+\"svpflow2.dll\")\n" +
          "Import(PluginPath+\"InterFrame2.avsi\")\n" +
          "InterFrame(Cores=" + Cores + GPU + ", Preset=\"Fast\")\n";
      }

      String subLine = null;
      if (subTrack != null && configuration.isAutoloadExternalSubtitles() && !configuration.isDisableSubtitles()) {
        if (subTrack.getExternalFile() != null) {
          LOGGER.info("AviSynth script: Using subtitle track: " + subTrack);
          String function = "TextSub";
          if (subTrack.getType() == SubtitleType.VOBSUB) {
            function = "VobSub";
          }
          subLine = function + "(\"" + ProcessUtil.getShortFileNameIfWideChars(subTrack.getExternalFile().getAbsolutePath()) + "\")";
        }
      }

      ArrayList<String> lines = new ArrayList<>();

      lines.add(mtLine1);

      boolean fullyManaged = false;
      String script = configuration.getAvisynthScript();
      StringTokenizer st = new StringTokenizer(script, PMS.AVS_SEPARATOR);
      while (st.hasMoreTokens()) {
        String line = st.nextToken();
        if (line.contains("<movie") || line.contains("<sub")) {
          fullyManaged = true;
        }
        lines.add(line);
      }

      lines.add(mtLine2);

      if (configuration.getAvisynthInterFrame()) {
        lines.add(interframeLines);
      }

      lines.add(mtLine3);

      if (fullyManaged) {
        for (String s : lines) {
          if (s.contains("<moviefilename>")) {
            s = s.replace("<moviefilename>", fileName);
          }

          s = s.replace("<movie>", movieLine);
          s = s.replace("<sub>", subLine != null ? subLine : "#");
          pw.println(s);
        }
      } else {
        pw.println(movieLine);
        if (subLine != null) {
          pw.println(subLine);
        }
        pw.println("clip");

      }
    }
    file.deleteOnExit();
    return file;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public boolean isCompatible(DLNAResource resource) {
    Format format = resource.getFormat();

    if (format != null) {
      if (format.getIdentifier() == Format.Identifier.WEB) {
        return false;
      }
    }

    DLNAMediaSubtitle subtitle = resource.getMediaSubtitle();

    // Check whether the subtitle actually has a language defined,
    // Uninitialized DLNAMediaSubtitle objects have a null language.
    if (subtitle != null && subtitle.getLang() != null) {
      // This engine only supports external subtitles
      if (subtitle.getExternalFile() != null) {
        return true;
      }

      return false;
    }

    try {
      String audioTrackName = resource.getMediaAudio().toString();
      String defaultAudioTrackName = resource.getMedia().getAudioTracksList().get(0).toString();

      if (!audioTrackName.equals(defaultAudioTrackName)) {
        // This engine only supports playback of the default audio track
        return false;
      }
    } catch (NullPointerException e) {
      LOGGER.trace("AviSynth/MEncoder cannot determine compatibility based on audio track for " + resource.getSystemName());
    } catch (IndexOutOfBoundsException e) {
      LOGGER.trace("AviSynth/MEncoder cannot determine compatibility based on default audio track for " + resource.getSystemName());
    }

    if (
      PlayerUtil.isVideo(resource, Format.Identifier.MKV) ||
      PlayerUtil.isVideo(resource, Format.Identifier.MPG)
    ) {
      return true;
    }

    return false;
  }
}
TOP

Related Classes of net.pms.encoders.AviSynthMEncoder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.