Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fix global custom MEncoder options (broken in e1b0139)

  • Loading branch information...
commit fe41952f961d9febc7750550656f43a3b51f9615 1 parent 96901c9
@chocolateboy chocolateboy authored
View
1  CHANGELOG
@@ -4,6 +4,7 @@ Changelog:
1.??.? -
Re-fix NPE when toggling HTTP Engine V2
+ Fix global custom MEncoder options
1.52.1 - 2012-04-06
View
32 src/main/java/net/pms/configuration/PmsConfiguration.java
@@ -108,7 +108,7 @@
private static final String KEY_MENCODER_ASS_SHADOW = "mencoder_ass_shadow";
private static final String KEY_MENCODER_AUDIO_LANGS = "mencoder_audiolangs";
private static final String KEY_MENCODER_AUDIO_SUB_LANGS = "mencoder_audiosublangs";
- private static final String KEY_MENCODER_DECODE = "mencoder_decode";
+ private static final String KEY_MENCODER_CUSTOM_OPTIONS = "mencoder_decode"; // TODO (breaking change): should be renamed to e.g. mencoder_custom_options
private static final String KEY_MENCODER_DISABLE_SUBS = "mencoder_disablesubs";
private static final String KEY_MENCODER_FONT_CONFIG = "mencoder_fontconfig";
private static final String KEY_MENCODER_FONT = "mencoder_font";
@@ -159,7 +159,7 @@
private static final String KEY_SORT_METHOD = "key_sort_method";
private static final String KEY_SUBS_COLOR = "subs_color";
private static final String KEY_TEMP_FOLDER_PATH = "temp";
- private static final String KEY_THUMBNAIL_GENERATION_ENABLED = "thumbnails"; // TODO should be renamed e.g. "generate_thumbnails" at some stage
+ private static final String KEY_THUMBNAIL_GENERATION_ENABLED = "thumbnails"; // TODO (breaking change): should be renamed to e.g. generate_thumbnails
private static final String KEY_THUMBNAIL_SEEK_POS = "thumbnail_seek_pos";
private static final String KEY_TRANSCODE_BLOCKS_MULTIPLE_CONNECTIONS = "transcode_block_multiple_connections";
private static final String KEY_TRANSCODE_KEEP_FIRST_CONNECTION = "transcode_keep_first_connection";
@@ -1042,19 +1042,41 @@ public void setMencoderAudioSubLanguages(String value) {
}
/**
+ * @deprecated Use {@link #getMencoderCustomOptions()} instead.
+ * <p>
* Returns custom commandline options to pass on to MEncoder.
* @return The custom options string.
*/
+ @Deprecated
public String getMencoderDecode() {
- return getString(KEY_MENCODER_DECODE, "");
+ return getMencoderCustomOptions();
+ }
+
+ /**
+ * Returns custom commandline options to pass on to MEncoder.
+ * @return The custom options string.
+ */
+ public String getMencoderCustomOptions() {
+ return getString(KEY_MENCODER_CUSTOM_OPTIONS, "");
}
/**
+ * @deprecated Use {@link #setMencoderCustomOptions(String)} instead.
+ * <p>
* Sets custom commandline options to pass on to MEncoder.
* @param value The custom options string.
*/
+ @Deprecated
public void setMencoderDecode(String value) {
- configuration.setProperty(KEY_MENCODER_DECODE, value);
+ setMencoderCustomOptions(value);
+ }
+
+ /**
+ * Sets custom commandline options to pass on to MEncoder.
+ * @param value The custom options string.
+ */
+ public void setMencoderCustomOptions(String value) {
+ configuration.setProperty(KEY_MENCODER_CUSTOM_OPTIONS, value);
}
/**
@@ -1296,7 +1318,7 @@ public boolean isThumbnailGenerationEnabled() {
}
/**
- * @deprecated Use {@link #setThumbnailGenerationEnabled()} instead.
+ * @deprecated Use {@link #setThumbnailGenerationEnabled(boolean)} instead.
* <p>
* Sets the thumbnail generation option.
* This only determines whether a thumbnailer (e.g. dcraw, MPlayer)
View
21 src/main/java/net/pms/dlna/CueFolder.java
@@ -22,7 +22,7 @@
import org.slf4j.LoggerFactory;
public class CueFolder extends DLNAResource {
- private static final Logger logger = LoggerFactory.getLogger(CueFolder.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(CueFolder.class);
private File playlistfile;
public File getPlaylistfile() {
@@ -72,7 +72,7 @@ public void resolve() {
try {
sheet = CueParser.parse(playlistfile);
} catch (IOException e) {
- logger.info("Error in parsing cue: " + e.getMessage());
+ LOGGER.info("Error in parsing cue: " + e.getMessage());
return;
}
@@ -101,7 +101,7 @@ public void resolve() {
}
prec.getSplitRange().setEnd(end);
prec.getMedia().setDuration(prec.getSplitRange().getDuration());
- logger.debug("Track #" + i + " split range: " + prec.getSplitRange().getStartOrZero() + " - " + prec.getSplitRange().getDuration());
+ LOGGER.debug("Track #" + i + " split range: " + prec.getSplitRange().getStartOrZero() + " - " + prec.getSplitRange().getDuration());
}
Position start = track.getIndices().get(0).getPosition();
RealFile r = new RealFile(new File(playlistfile.getParentFile(), f.getFile()));
@@ -117,27 +117,34 @@ public void resolve() {
}
r.getSplitRange().setStart(getTime(start));
r.setSplitTrack(i + 1);
+
if (r.getPlayer() == null) { // assign a splitter engine if file is natively supported by renderer
if (defaultPlayer == null) {
if (r.getExt() == null) {
- logger.error("No file format known for file \"" + r.getName()
- + "\", assuming it is a video for now.");
+ LOGGER.error("No file format known for file \"{}\", assuming it is a video for now.", r.getName());
+ // XXX aren't players supposed to be singletons?
+ // NOTE: needs new signature for getPlayer():
+ // PlayerFactory.getPlayer(MEncoderVideo.class)
defaultPlayer = new MEncoderVideo(PMS.getConfiguration());
} else {
if (r.getExt().isAudio()) {
+ // XXX PlayerFactory.getPlayer(MPlayerAudio.class)
defaultPlayer = new MPlayerAudio(PMS.getConfiguration());
} else {
+ // XXX PlayerFactory.getPlayer(MEncoderVideo.class)
defaultPlayer = new MEncoderVideo(PMS.getConfiguration());
}
}
}
+
r.setPlayer(defaultPlayer);
}
+
if (r.getMedia() != null) {
try {
r.setMedia((DLNAMediaInfo) originalMedia.clone());
} catch (CloneNotSupportedException e) {
- logger.info("Error in cloning media info: " + e.getMessage());
+ LOGGER.info("Error in cloning media info: " + e.getMessage());
}
if (r.getMedia() != null && r.getMedia().getFirstAudioTrack() != null) {
if (r.getExt().isAudio()) {
@@ -167,7 +174,7 @@ public void resolve() {
DLNAResource prec = addedResources.get(addedResources.size() - 1);
prec.getSplitRange().setEnd(prec.getMedia().getDurationInSeconds());
prec.getMedia().setDuration(prec.getSplitRange().getDuration());
- logger.debug("Track #" + childrenNumber() + " split range: " + prec.getSplitRange().getStartOrZero() + " - " + prec.getSplitRange().getDuration());
+ LOGGER.debug("Track #" + childrenNumber() + " split range: " + prec.getSplitRange().getStartOrZero() + " - " + prec.getSplitRange().getDuration());
}
PMS.get().storeFileInCache(playlistfile, Format.PLAYLIST);
View
444 src/main/java/net/pms/encoders/MEncoderVideo.java
@@ -33,6 +33,7 @@
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.List;
import java.util.StringTokenizer;
import javax.swing.JButton;
@@ -89,7 +90,7 @@
import com.sun.jna.Platform;
public class MEncoderVideo extends Player {
- private static final Logger logger = LoggerFactory.getLogger(MEncoderVideo.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(MEncoderVideo.class);
private JTextField mencoder_ass_scale;
private JTextField mencoder_ass_margin;
@@ -99,7 +100,7 @@
private JTextField mencoder_noass_subpos;
private JTextField mencoder_noass_blur;
private JTextField mencoder_noass_outline;
- private JTextField decode;
+ private JTextField mencoder_custom_options;
private JTextField langs;
private JTextField defaultsubs;
private JTextField forcedsub;
@@ -128,17 +129,36 @@
private JCheckBox subs;
private JCheckBox fribidi;
private final PmsConfiguration configuration;
+
+ private static final String[] INVALID_CUSTOM_OPTIONS = {
+ "-of",
+ "-oac",
+ "-ovc",
+ "-mpegopts"
+ };
+
+ private static final String INVALID_CUSTOM_OPTIONS_LIST = Arrays.toString(INVALID_CUSTOM_OPTIONS);
+
public static final int MENCODER_MAX_THREADS = 8;
- protected boolean dts;
public static final String ID = "mencoder";
+
+ // TODO (breaking change): most (probably all) of these
+ // protected fields should be private. And at least two
+ // shouldn't be fields
+
+ @Deprecated
+ protected boolean dvd;
+
+ @Deprecated
+ protected String overriddenMainArgs[];
+
+ protected boolean dts;
protected boolean pcm;
protected boolean mux;
protected boolean ovccopy;
- protected boolean dvd;
protected boolean oaccopy;
protected boolean mpegts;
protected boolean wmv;
- protected String overriddenMainArgs[];
public static final String DEFAULT_CODEC_CONF_SCRIPT =
Messages.getString("MEncoderVideo.68")
@@ -196,9 +216,11 @@ public JComponent config() {
checkBox = new JCheckBox(Messages.getString("MEncoderVideo.0"));
checkBox.setContentAreaFilled(false);
+
if (configuration.getSkipLoopFilterEnabled()) {
checkBox.setSelected(true);
}
+
checkBox.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
configuration.setSkipLoopFilterEnabled((e.getStateChange() == ItemEvent.SELECTED));
@@ -211,15 +233,18 @@ public void itemStateChanged(ItemEvent e) {
mencodermt = new JCheckBox(Messages.getString("MEncoderVideo.35"));
mencodermt.setContentAreaFilled(false);
+
if (configuration.getMencoderMT()) {
mencodermt.setSelected(true);
}
+
mencodermt.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
configuration.setMencoderMT(mencodermt.isSelected());
}
});
+
mencodermt.setEnabled(Platform.isWindows() || Platform.isMac());
builder.add(mencodermt, cc.xy(1, 3));
@@ -227,9 +252,11 @@ public void actionPerformed(ActionEvent e) {
noskip = new JCheckBox(Messages.getString("MEncoderVideo.2"));
noskip.setContentAreaFilled(false);
+
if (configuration.isMencoderNoOutOfSync()) {
noskip.setSelected(true);
}
+
noskip.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
configuration.setMencoderNoOutOfSync((e.getStateChange() == ItemEvent.SELECTED));
@@ -261,9 +288,11 @@ public void actionPerformed(ActionEvent e) {
JPanel customPanel = new JPanel(new BorderLayout());
intelligentsync = new JCheckBox(Messages.getString("MEncoderVideo.3"));
intelligentsync.setContentAreaFilled(false);
+
if (configuration.isMencoderIntelligentSync()) {
intelligentsync.setSelected(true);
}
+
intelligentsync.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
configuration.setMencoderIntelligentSync((e.getStateChange() == ItemEvent.SELECTED));
@@ -279,6 +308,7 @@ public void itemStateChanged(ItemEvent e) {
codecPanel.add(intelligentsync, BorderLayout.NORTH);
codecPanel.add(scrollPaneDefault, BorderLayout.CENTER);
codecPanel.add(customPanel, BorderLayout.SOUTH);
+
while (JOptionPane.showOptionDialog((JFrame) (SwingUtilities.getWindowAncestor((Component) PMS.get().getFrame())),
codecPanel, Messages.getString("MEncoderVideo.34"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, null, null, null) == JOptionPane.OK_OPTION) {
String newCodecparam = textArea.getText();
@@ -295,6 +325,7 @@ public void itemStateChanged(ItemEvent e) {
fakemedia.setFrameRate("23.976");
fakemedia.getAudioCodes().add(audio);
String result[] = getSpecificCodecOptions(newCodecparam, fakemedia, new OutputParams(configuration), "dummy.mpg", "dummy.srt", false, true);
+
if (result.length > 0 && result[0].startsWith("@@")) {
String errorMessage = result[0].substring(2);
JOptionPane.showMessageDialog((JFrame) (SwingUtilities.getWindowAncestor((Component) PMS.get().getFrame())), errorMessage);
@@ -306,13 +337,16 @@ public void itemStateChanged(ItemEvent e) {
}
}
});
+
builder.add(button, cc.xyw(1, 11, 2));
forcefps = new JCheckBox(Messages.getString("MEncoderVideo.4"));
forcefps.setContentAreaFilled(false);
+
if (configuration.isMencoderForceFps()) {
forcefps.setSelected(true);
}
+
forcefps.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
configuration.setMencoderForceFps(e.getStateChange() == ItemEvent.SELECTED);
@@ -323,9 +357,11 @@ public void itemStateChanged(ItemEvent e) {
yadif = new JCheckBox(Messages.getString("MEncoderVideo.26"));
yadif.setContentAreaFilled(false);
+
if (configuration.isMencoderYadif()) {
yadif.setSelected(true);
}
+
yadif.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
configuration.setMencoderYadif(e.getStateChange() == ItemEvent.SELECTED);
@@ -362,12 +398,12 @@ public void keyReleased(KeyEvent e) {
try {
configuration.setMencoderScaleX(Integer.parseInt(scaleX.getText()));
} catch (NumberFormatException nfe) {
- logger.debug("Could not parse scaleX from \"" + scaleX.getText() + "\"");
+ LOGGER.debug("Could not parse scaleX from \"" + scaleX.getText() + "\"");
}
}
});
- builder.add(scaleX, cc.xyw(13, 5, 3));
+ builder.add(scaleX, cc.xyw(13, 5, 3));
builder.addLabel(Messages.getString("MEncoderVideo.30"), cc.xyw(10, 7, 3, CellConstraints.RIGHT, CellConstraints.CENTER));
scaleY = new JTextField("" + configuration.getMencoderScaleY());
scaleY.addKeyListener(new KeyListener() {
@@ -384,10 +420,11 @@ public void keyReleased(KeyEvent e) {
try {
configuration.setMencoderScaleY(Integer.parseInt(scaleY.getText()));
} catch (NumberFormatException nfe) {
- logger.debug("Could not parse scaleY from \"" + scaleY.getText() + "\"");
+ LOGGER.debug("Could not parse scaleY from \"" + scaleY.getText() + "\"");
}
}
});
+
builder.add(scaleY, cc.xyw(13, 7, 3));
if (configuration.isMencoderScaler()) {
@@ -397,13 +434,13 @@ public void keyReleased(KeyEvent e) {
scaleY.setEnabled(false);
}
-
-
videoremux = new JCheckBox("<html>" + Messages.getString("MEncoderVideo.38") + "</html>");
videoremux.setContentAreaFilled(false);
+
if (configuration.isMencoderMuxWhenCompatible()) {
videoremux.setSelected(true);
}
+
videoremux.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
configuration.setMencoderMuxWhenCompatible((e.getStateChange() == ItemEvent.SELECTED));
@@ -417,8 +454,8 @@ public void itemStateChanged(ItemEvent e) {
cmp.setFont(cmp.getFont().deriveFont(Font.BOLD));
builder.addLabel(Messages.getString("MEncoderVideo.6"), cc.xy(1, 21));
- decode = new JTextField(configuration.getMencoderDecode());
- decode.addKeyListener(new KeyListener() {
+ mencoder_custom_options = new JTextField(configuration.getMencoderCustomOptions());
+ mencoder_custom_options.addKeyListener(new KeyListener() {
@Override
public void keyPressed(KeyEvent e) {
}
@@ -429,12 +466,13 @@ public void keyTyped(KeyEvent e) {
@Override
public void keyReleased(KeyEvent e) {
- configuration.setMencoderDecode(decode.getText());
+ configuration.setMencoderCustomOptions(mencoder_custom_options.getText());
}
});
- builder.add(decode, cc.xyw(3, 21, 13));
+ builder.add(mencoder_custom_options, cc.xyw(3, 21, 13));
builder.addLabel(Messages.getString("MEncoderVideo.7"), cc.xyw(1, 23, 15));
+
langs = new JTextField(configuration.getMencoderAudioLanguages());
langs.addKeyListener(new KeyListener() {
@Override
@@ -450,6 +488,7 @@ public void keyReleased(KeyEvent e) {
configuration.setMencoderAudioLanguages(langs.getText());
}
});
+
builder.add(langs, cc.xyw(3, 23, 8));
cmp = builder.addSeparator(Messages.getString("MEncoderVideo.8"), cc.xyw(1, 25, 15));
@@ -457,6 +496,7 @@ public void keyReleased(KeyEvent e) {
cmp.setFont(cmp.getFont().deriveFont(Font.BOLD));
builder.addLabel(Messages.getString("MEncoderVideo.9"), cc.xy(1, 27));
+
defaultsubs = new JTextField(configuration.getMencoderSubLanguages());
defaultsubs.addKeyListener(new KeyListener() {
@Override
@@ -474,6 +514,7 @@ public void keyReleased(KeyEvent e) {
});
builder.addLabel(Messages.getString("MEncoderVideo.94"), cc.xy(5, 27));
+
forcedsub = new JTextField(configuration.getMencoderForcedSubLanguage());
forcedsub.addKeyListener(new KeyListener() {
@Override
@@ -506,13 +547,12 @@ public void keyReleased(KeyEvent e) {
configuration.setMencoderForcedSubTags(forcedtags.getText());
}
});
- builder.add(defaultsubs, cc.xyw(3, 27, 2));
+ builder.add(defaultsubs, cc.xyw(3, 27, 2));
builder.add(forcedsub, cc.xy(7, 27));
-
builder.add(forcedtags, cc.xyw(11, 27, 5));
-
builder.addLabel(Messages.getString("MEncoderVideo.10"), cc.xy(1, 29));
+
defaultaudiosubs = new JTextField(configuration.getMencoderAudioSubLanguages());
defaultaudiosubs.addKeyListener(new KeyListener() {
@Override
@@ -528,9 +568,10 @@ public void keyReleased(KeyEvent e) {
configuration.setMencoderAudioSubLanguages(defaultaudiosubs.getText());
}
});
- builder.add(defaultaudiosubs, cc.xyw(3, 29, 8));
+ builder.add(defaultaudiosubs, cc.xyw(3, 29, 8));
builder.addLabel(Messages.getString("MEncoderVideo.11"), cc.xy(1, 31));
+
Object data[] = new Object[]{
configuration.getMencoderSubCp(),
Messages.getString("MEncoderVideo.96"),
@@ -563,36 +604,44 @@ public void keyReleased(KeyEvent e) {
Messages.getString("MEncoderVideo.123"),
Messages.getString("MEncoderVideo.124")
};
- MyComboBoxModel cbm = new MyComboBoxModel(data);
+ MyComboBoxModel cbm = new MyComboBoxModel(data);
subcp = new JComboBox(cbm);
+
subcp.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
String s = (String) e.getItem();
- if (s.indexOf("/*") > -1) {
- s = s.substring(0, s.indexOf("/*")).trim();
+ int offset = s.indexOf("/*");
+
+ if (offset > -1) {
+ s = s.substring(0, offset).trim();
}
+
configuration.setMencoderSubCp(s);
}
}
});
+
subcp.setEditable(true);
builder.add(subcp, cc.xyw(3, 31, 7));
fribidi = new JCheckBox(Messages.getString("MEncoderVideo.23"));
fribidi.setContentAreaFilled(false);
+
if (configuration.isMencoderSubFribidi()) {
fribidi.setSelected(true);
}
+
fribidi.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
configuration.setMencoderSubFribidi(e.getStateChange() == ItemEvent.SELECTED);
}
});
- builder.add(fribidi, cc.xyw(11, 31, 4));
+ builder.add(fribidi, cc.xyw(11, 31, 4));
builder.addLabel(Messages.getString("MEncoderVideo.24"), cc.xy(1, 33));
+
defaultfont = new JTextField(configuration.getMencoderFont());
defaultfont.addKeyListener(new KeyListener() {
@Override
@@ -608,6 +657,7 @@ public void keyReleased(KeyEvent e) {
configuration.setMencoderFont(defaultfont.getText());
}
});
+
builder.add(defaultfont, cc.xyw(3, 33, 8));
JButton fontselect = new JButton("...");
@@ -623,9 +673,10 @@ public void actionPerformed(ActionEvent e) {
}
}
});
- builder.add(fontselect, cc.xyw(11, 33, 2));
+ builder.add(fontselect, cc.xyw(11, 33, 2));
builder.addLabel(Messages.getString("MEncoderVideo.37"), cc.xyw(1, 35, 3));
+
alternateSubFolder = new JTextField(configuration.getAlternateSubsFolder());
alternateSubFolder.addKeyListener(new KeyListener() {
@Override
@@ -641,6 +692,7 @@ public void keyReleased(KeyEvent e) {
configuration.setAlternateSubsFolder(alternateSubFolder.getText());
}
});
+
builder.add(alternateSubFolder, cc.xyw(3, 35, 8));
JButton select = new JButton("...");
@@ -661,9 +713,10 @@ public void actionPerformed(ActionEvent e) {
}
}
});
- builder.add(select, cc.xyw(11, 35, 2));
+ builder.add(select, cc.xyw(11, 35, 2));
builder.addLabel(Messages.getString("MEncoderVideo.12"), cc.xy(1, 39, CellConstraints.RIGHT, CellConstraints.CENTER));
+
mencoder_ass_scale = new JTextField(configuration.getMencoderAssScale());
mencoder_ass_scale.addKeyListener(new KeyListener() {
@Override
@@ -681,6 +734,7 @@ public void keyReleased(KeyEvent e) {
});
builder.addLabel(Messages.getString("MEncoderVideo.13"), cc.xy(5, 39));
+
mencoder_ass_outline = new JTextField(configuration.getMencoderAssOutline());
mencoder_ass_outline.addKeyListener(new KeyListener() {
@Override
@@ -698,6 +752,7 @@ public void keyReleased(KeyEvent e) {
});
builder.addLabel(Messages.getString("MEncoderVideo.14"), cc.xy(9, 39));
+
mencoder_ass_shadow = new JTextField(configuration.getMencoderAssShadow());
mencoder_ass_shadow.addKeyListener(new KeyListener() {
@Override
@@ -715,6 +770,7 @@ public void keyReleased(KeyEvent e) {
});
builder.addLabel(Messages.getString("MEncoderVideo.15"), cc.xy(13, 39));
+
mencoder_ass_margin = new JTextField(configuration.getMencoderAssMargin());
mencoder_ass_margin.addKeyListener(new KeyListener() {
@Override
@@ -730,16 +786,13 @@ public void keyReleased(KeyEvent e) {
configuration.setMencoderAssMargin(mencoder_ass_margin.getText());
}
});
- builder.add(mencoder_ass_scale, cc.xy(3, 39));
+ builder.add(mencoder_ass_scale, cc.xy(3, 39));
builder.add(mencoder_ass_outline, cc.xy(7, 39));
-
builder.add(mencoder_ass_shadow, cc.xy(11, 39));
-
builder.add(mencoder_ass_margin, cc.xy(15, 39));
-
-
builder.addLabel(Messages.getString("MEncoderVideo.16"), cc.xy(1, 41, CellConstraints.RIGHT, CellConstraints.CENTER));
+
mencoder_noass_scale = new JTextField(configuration.getMencoderNoAssScale());
mencoder_noass_scale.addKeyListener(new KeyListener() {
@Override
@@ -757,6 +810,7 @@ public void keyReleased(KeyEvent e) {
});
builder.addLabel(Messages.getString("MEncoderVideo.17"), cc.xy(5, 41));
+
mencoder_noass_outline = new JTextField(configuration.getMencoderNoAssOutline());
mencoder_noass_outline.addKeyListener(new KeyListener() {
@Override
@@ -774,6 +828,7 @@ public void keyReleased(KeyEvent e) {
});
builder.addLabel(Messages.getString("MEncoderVideo.18"), cc.xy(9, 41));
+
mencoder_noass_blur = new JTextField(configuration.getMencoderNoAssBlur());
mencoder_noass_blur.addKeyListener(new KeyListener() {
@Override
@@ -791,6 +846,7 @@ public void keyReleased(KeyEvent e) {
});
builder.addLabel(Messages.getString("MEncoderVideo.19"), cc.xy(13, 41));
+
mencoder_noass_subpos = new JTextField(configuration.getMencoderNoAssSubPos());
mencoder_noass_subpos.addKeyListener(new KeyListener() {
@Override
@@ -806,12 +862,10 @@ public void keyReleased(KeyEvent e) {
configuration.setMencoderNoAssSubPos(mencoder_noass_subpos.getText());
}
});
- builder.add(mencoder_noass_scale, cc.xy(3, 41));
+ builder.add(mencoder_noass_scale, cc.xy(3, 41));
builder.add(mencoder_noass_outline, cc.xy(7, 41));
-
builder.add(mencoder_noass_blur, cc.xy(11, 41));
-
builder.add(mencoder_noass_subpos, cc.xy(15, 41));
ass = new JCheckBox(Messages.getString("MEncoderVideo.20"));
@@ -852,17 +906,20 @@ public void itemStateChanged(ItemEvent e) {
subs = new JCheckBox(Messages.getString("MEncoderVideo.22"));
subs.setContentAreaFilled(false);
+
if (configuration.getUseSubtitles()) {
subs.setSelected(true);
}
+
subs.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
configuration.setUseSubtitles((e.getStateChange() == ItemEvent.SELECTED));
}
});
- builder.add(subs, cc.xyw(1, 43, 15));
+ builder.add(subs, cc.xyw(1, 43, 15));
builder.addLabel(Messages.getString("MEncoderVideo.92"), cc.xy(1, 45));
+
subq = new JTextField(configuration.getMencoderVobsubSubtitleQuality());
subq.addKeyListener(new KeyListener() {
@Override
@@ -878,11 +935,11 @@ public void keyReleased(KeyEvent e) {
configuration.setMencoderVobsubSubtitleQuality(subq.getText());
}
});
- builder.add(subq, cc.xyw(3, 45, 1));
+ builder.add(subq, cc.xyw(3, 45, 1));
builder.addLabel(Messages.getString("MEncoderVideo.93"), cc.xyw(1, 47, 6));
-
builder.addLabel(Messages.getString("MEncoderVideo.28") + "% ", cc.xy(1, 49, CellConstraints.RIGHT, CellConstraints.CENTER));
+
ocw = new JTextField(configuration.getMencoderOverscanCompensationWidth());
ocw.addKeyListener(new KeyListener() {
@Override
@@ -898,9 +955,10 @@ public void keyReleased(KeyEvent e) {
configuration.setMencoderOverscanCompensationWidth(ocw.getText());
}
});
- builder.add(ocw, cc.xyw(3, 49, 1));
+ builder.add(ocw, cc.xyw(3, 49, 1));
builder.addLabel(Messages.getString("MEncoderVideo.30") + "% ", cc.xy(5, 49));
+
och = new JTextField(configuration.getMencoderOverscanCompensationHeight());
och.addKeyListener(new KeyListener() {
@Override
@@ -916,6 +974,7 @@ public void keyReleased(KeyEvent e) {
configuration.setMencoderOverscanCompensationHeight(och.getText());
}
});
+
builder.add(och, cc.xyw(7, 49, 1));
subColor = new JButton();
@@ -927,13 +986,16 @@ public void actionPerformed(ActionEvent e) {
Color newColor = JColorChooser.showDialog(
(JFrame) (SwingUtilities.getWindowAncestor((Component) PMS.get().getFrame())),
Messages.getString("MEncoderVideo.125"),
- subColor.getBackground());
+ subColor.getBackground()
+ );
+
if (newColor != null) {
subColor.setBackground(newColor);
configuration.setSubsColor(newColor.getRGB());
}
}
});
+
builder.add(subColor, cc.xyw(12, 37, 4));
JCheckBox disableSubs = ((LooksFrame) PMS.get().getFrame()).getTr().getDisableSubs();
@@ -963,6 +1025,7 @@ public void itemStateChanged(ItemEvent e) {
}
}
});
+
if (configuration.isMencoderDisableSubs()) {
disableSubs.setSelected(true);
}
@@ -1002,30 +1065,62 @@ public boolean isTimeSeekable() {
};
}
+ private String[] sanitizeArgs(String[] args) {
+ List<String> sanitized = new ArrayList<String>();
+ int i = 0;
+
+ while (i < args.length) {
+ String name = args[i];
+ String value = null;
+
+ for (String option : INVALID_CUSTOM_OPTIONS) {
+ if (option.equals(name)) {
+ if ((i + 1) < args.length) {
+ value = " " + args[i + 1];
+ ++i;
+ } else {
+ value = "";
+ }
+
+ LOGGER.warn(
+ "Ignoring custom MEncoder option: {}{}; the following options cannot be changed: " + INVALID_CUSTOM_OPTIONS_LIST,
+ name,
+ value
+ );
+
+ break;
+ }
+ }
+
+ if (value == null) {
+ sanitized.add(args[i]);
+ }
+
+ ++i;
+ }
+
+ return sanitized.toArray(new String[sanitized.size()]);
+ }
+
@Override
public String[] args() {
String args[] = null;
String defaultArgs[] = getDefaultArgs();
+
if (overriddenMainArgs != null) {
- args = new String[defaultArgs.length + overriddenMainArgs.length];
- for (int i = 0; i < defaultArgs.length; i++) {
- args[i] = defaultArgs[i];
- }
- for (int i = 0; i < overriddenMainArgs.length; i++) {
- if ("-of".equals(overriddenMainArgs[i]) || "-oac".equals(overriddenMainArgs[i]) || "-ovc".equals(overriddenMainArgs[i]) || "-mpegopts".equals(overriddenMainArgs[i])) {
- logger.info("MEncoder encoder settings: You cannot change Muxer, Muxer options, Video Codec or Audio Codec");
- overriddenMainArgs[i] = "-quiet";
- if (i + 1 < overriddenMainArgs.length) {
- overriddenMainArgs[i + 1] = "-quiet";
- }
- }
- args[i + defaultArgs.length] = overriddenMainArgs[i];
- }
+ // add the sanitized custom MEncoder options.
+ // not cached because they may be changed on the fly in the GUI
+ // XXX if/when we upgrade to org.apache.commons.lang3:
+ // args = ArrayUtils.addAll(defaultArgs, sanitizeArgs(overriddenMainArgs))
+ String[] sanitizedCustomArgs = sanitizeArgs(overriddenMainArgs);
+ args = new String[defaultArgs.length + sanitizedCustomArgs.length];
+ System.arraycopy(defaultArgs, 0, args, 0, defaultArgs.length);
+ System.arraycopy(sanitizedCustomArgs, 0, args, defaultArgs.length, sanitizedCustomArgs.length);
} else {
args = defaultArgs;
}
- return args;
+ return args;
}
@Override
@@ -1035,17 +1130,21 @@ public String executable() {
private int[] getVideoBitrateConfig(String bitrate) {
int bitrates[] = new int[2];
+
if (bitrate.contains("(") && bitrate.contains(")")) {
bitrates[1] = Integer.parseInt(bitrate.substring(bitrate.indexOf("(") + 1, bitrate.indexOf(")")));
}
- if (bitrate.contains("("))
- {
+
+ if (bitrate.contains("(")) {
bitrate = bitrate.substring(0, bitrate.indexOf("(")).trim();
}
+
if (StringUtils.isBlank(bitrate)) {
bitrate = "0";
}
+
bitrates[0] = (int) Double.parseDouble(bitrate);
+
return bitrates;
}
@@ -1056,12 +1155,15 @@ public String executable() {
private String addMaximumBitrateConstraints(String encodeSettings, DLNAMediaInfo media, String quality, RendererConfiguration mediaRenderer, String audioType) {
int defaultMaxBitrates[] = getVideoBitrateConfig(configuration.getMaximumBitrate());
int rendererMaxBitrates[] = new int[2];
+
if (mediaRenderer.getMaxVideoBitrate() != null) {
rendererMaxBitrates = getVideoBitrateConfig(mediaRenderer.getMaxVideoBitrate());
}
+
if ((defaultMaxBitrates[0] == 0 && rendererMaxBitrates[0] > 0) || rendererMaxBitrates[0] < defaultMaxBitrates[0] && rendererMaxBitrates[0] > 0) {
defaultMaxBitrates = rendererMaxBitrates;
}
+
if (mediaRenderer.getCBRVideoBitrate() == 0 && defaultMaxBitrates[0] > 0 && !quality.contains("vrc_buf_size") && !quality.contains("vrc_maxrate") && !quality.contains("vbitrate")) {
// Convert value from Mb to Kb
defaultMaxBitrates[0] = 1000 * defaultMaxBitrates[0];
@@ -1073,6 +1175,7 @@ private String addMaximumBitrateConstraints(String encodeSettings, DLNAMediaInfo
if (media.isHDVideo()) {
bufSize = defaultMaxBitrates[0] / 3;
}
+
if (bufSize > 7000) {
bufSize = 7000;
}
@@ -1104,6 +1207,7 @@ else if ("ac3".equals(audioType)) {
encodeSettings += ":vrc_maxrate=" + defaultMaxBitrates[0] + ":vrc_buf_size=" + bufSize;
}
+
return encodeSettings;
}
@@ -1119,8 +1223,8 @@ public ProcessWrapper launchTranscode(
boolean avisynth = avisynth();
setAudioAndSubs(fileName, media, params, configuration);
-
String subString = null;
+
if (params.sid != null && params.sid.getPlayableFile() != null) {
subString = ProcessUtil.getShortFileNameIfWideChars(params.sid.getPlayableFile().getAbsolutePath());
}
@@ -1130,6 +1234,7 @@ public ProcessWrapper launchTranscode(
newInput.setPush(params.stdin);
dvd = false;
+
if (media != null && media.getDvdtrack() > 0) {
dvd = true;
}
@@ -1137,7 +1242,7 @@ public ProcessWrapper launchTranscode(
// don't honour "Switch to tsMuxeR..." if the resource is being streamed via an MEncoder entry in
// the #--TRANSCODE--# folder
boolean forceMencoder = !configuration.getHideTranscodeEnabled()
- && dlna.isNoName()
+ && dlna.isNoName() // XXX remove this? http://www.ps3mediaserver.org/forum/viewtopic.php?f=11&t=12149
&& (dlna.getParent() instanceof FileTranscodeVirtualFolder);
ovccopy = false;
@@ -1148,13 +1253,13 @@ public ProcessWrapper launchTranscode(
try {
intOCW = Integer.parseInt(configuration.getMencoderOverscanCompensationWidth());
} catch (NumberFormatException e) {
- logger.error("Cannot parse configured MEncoder overscan compensation width: \"" + configuration.getMencoderOverscanCompensationWidth() + "\"");
+ LOGGER.error("Cannot parse configured MEncoder overscan compensation width: \"{}\"", configuration.getMencoderOverscanCompensationWidth());
}
try {
intOCH = Integer.parseInt(configuration.getMencoderOverscanCompensationHeight());
} catch (NumberFormatException e) {
- logger.error("Cannot parse configured MEncoder overscan compensation height: \"" + configuration.getMencoderOverscanCompensationHeight() + "\"");
+ LOGGER.error("Cannot parse configured MEncoder overscan compensation height: \"{}\"", configuration.getMencoderOverscanCompensationHeight());
}
if (
@@ -1173,16 +1278,28 @@ public ProcessWrapper launchTranscode(
intOCH == 0
)
) {
- String sArgs[] = getSpecificCodecOptions(configuration.getCodecSpecificConfig(), media, params, fileName, subString, configuration.isMencoderIntelligentSync(), false);
+ String sArgs[] = getSpecificCodecOptions(
+ configuration.getCodecSpecificConfig(),
+ media,
+ params,
+ fileName,
+ subString,
+ configuration.isMencoderIntelligentSync(),
+ false
+ );
+
boolean nomux = false;
+
for (String s : sArgs) {
if (s.equals("-nomux")) {
nomux = true;
}
}
+
if (!nomux) {
TSMuxerVideo tv = new TSMuxerVideo(configuration);
params.forceFps = media.getValidFps(false);
+
if (media.getCodecV().equals("h264")) {
params.forceType = "V_MPEG4/ISO/AVC";
} else if (media.getCodecV().startsWith("mpeg2")) {
@@ -1190,35 +1307,49 @@ public ProcessWrapper launchTranscode(
} else if (media.getCodecV().equals("vc1")) {
params.forceType = "V_MS/VFW/WVC1";
}
+
return tv.launchTranscode(fileName, dlna, media, params);
}
} else if (params.sid == null && dvd && configuration.isMencoderRemuxMPEG2() && params.mediaRenderer.isMpeg2Supported()) {
- String sArgs[] = getSpecificCodecOptions(configuration.getCodecSpecificConfig(), media, params, fileName, subString, configuration.isMencoderIntelligentSync(), false);
+ String sArgs[] = getSpecificCodecOptions(
+ configuration.getCodecSpecificConfig(),
+ media,
+ params,
+ fileName,
+ subString,
+ configuration.isMencoderIntelligentSync(),
+ false
+ );
+
boolean nomux = false;
+
for (String s : sArgs) {
if (s.equals("-nomux")) {
nomux = true;
}
}
+
if (!nomux) {
ovccopy = true;
}
}
String vcodec = "mpeg2video";
-
wmv = false;
+
if (params.mediaRenderer.isTranscodeToWMV()) {
wmv = true;
vcodec = "wmv2"; // http://wiki.megaframe.org/wiki/Ubuntu_XBOX_360#MEncoder not usable in streaming
}
mpegts = false;
+
if (params.mediaRenderer.isTranscodeToMPEGTSAC3()) {
mpegts = true;
}
oaccopy = false;
+
if (configuration.isRemuxAC3() && params.aid != null && params.aid.isAC3() && !avisynth() && params.mediaRenderer.isTranscodeToAC3()) {
oaccopy = true;
}
@@ -1230,6 +1361,7 @@ public ProcessWrapper launchTranscode(
if (dts) {
oaccopy = true;
}
+
params.losslessaudio = true;
params.forceFps = media.getValidFps(false);
}
@@ -1244,42 +1376,72 @@ public ProcessWrapper launchTranscode(
}
String add = "";
- if (params.mediaRenderer.getCustomMencoderOptions() != null) {
- if (params.mediaRenderer.getCustomMencoderOptions().indexOf("-lavdopts") == -1) {
- add = " -lavdopts debug=0";
- }
- } else if (configuration.getMencoderDecode() == null || configuration.getMencoderDecode().indexOf("-lavdopts") == -1) {
+ String rendererMencoderOptions = params.mediaRenderer.getCustomMencoderOptions(); // default: empty string
+ String mencoderCustomOptions = configuration.getMencoderCustomOptions(); // default: empty string
+
+ String combinedCustomOptions = StringUtils.defaultString(mencoderCustomOptions)
+ + " "
+ + StringUtils.defaultString(rendererMencoderOptions);
+
+ if (!combinedCustomOptions.contains("-lavdopts")) {
add = " -lavdopts debug=0";
}
- String alternativeCodec = "";//"-ac ffac3,ffdca, ";
- if (dvd) {
- alternativeCodec = "";
- }
int channels = wmv ? 2 : configuration.getAudioChannelCount();
+
if (media != null && params.aid != null) {
channels = wmv ? 2 : CodecUtil.getRealChannelCount(configuration, params.aid);
}
- logger.trace("channels=" + channels);
- StringTokenizer st = new StringTokenizer(alternativeCodec + "-channels " + channels + " " + ((params.mediaRenderer.getCustomMencoderOptions()!=null && !(params.mediaRenderer.getCustomMencoderOptions().indexOf("expand=") != -1 && dvd))?(params.mediaRenderer.getCustomMencoderOptions()):configuration.getMencoderDecode()) + add, " ");
+ LOGGER.trace("channels=" + channels);
+
+ if (StringUtils.isNotBlank(rendererMencoderOptions)) {
+ /*
+ * ignore the renderer's custom MEncoder options if a) we're streaming a DVD (i.e. via dvd://)
+ * or b) the renderer's MEncoder options contain overscan settings (those are handled
+ * separately)
+ */
+
+ // XXX we should weed out the unused/unwanted settings and keep the rest
+ // (see sanitizeArgs()) rather than ignoring the options entirely
+ if (rendererMencoderOptions.contains("expand=") || dvd) {
+ rendererMencoderOptions = null;
+ }
+ }
+
+ StringTokenizer st = new StringTokenizer(
+ "-channels " + channels
+ + (StringUtils.isNotBlank(mencoderCustomOptions) ? " " + mencoderCustomOptions : "")
+ + (StringUtils.isNotBlank(rendererMencoderOptions) ? " " + rendererMencoderOptions : "")
+ + add,
+ " "
+ );
+
+ // XXX why does this field (which is used to populate the array returned by args(),
+ // called below) store the renderer-specific (i.e. not global) MEncoder options?
overriddenMainArgs = new String[st.countTokens()];
+
int i = 0;
- boolean processToken = false;
+ boolean handleToken = false;
int nThreads = (dvd || fileName.toLowerCase().endsWith("dvr-ms")) ?
- 1 : configuration.getMencoderMaxThreads();
+ 1 :
+ configuration.getMencoderMaxThreads();
while (st.hasMoreTokens()) {
String token = st.nextToken().trim();
- if (processToken) {
+
+ if (handleToken) {
token += ":threads=" + nThreads;
+
if (configuration.getSkipLoopFilterEnabled() && !avisynth()) {
token += ":skiploopfilter=all";
}
- processToken = false;
+
+ handleToken = false;
}
+
if (token.toLowerCase().contains("lavdopts")) {
- processToken = true;
+ handleToken = true;
}
overriddenMainArgs[i++] = token;
@@ -1290,12 +1452,11 @@ public ProcessWrapper launchTranscode(
String customSettings = params.mediaRenderer.getCustomMencoderQualitySettings();
// Custom settings in PMS may override the settings of the saved configuration
- if (customSettings != null && !"".equals(customSettings.trim())) {
+ if (StringUtils.isNotBlank(customSettings)) {
mainConfig = customSettings;
}
- if (mainConfig.contains("/*")) // in case of
- {
+ if (mainConfig.contains("/*")) {
mainConfig = mainConfig.substring(mainConfig.indexOf("/*"));
}
@@ -1309,6 +1470,7 @@ public ProcessWrapper launchTranscode(
("".equals(mainConfig) ? "" : ":" + mainConfig);
String audioType = "ac3";
+
if (dts) {
audioType = "dts";
} else if (pcm) {
@@ -1320,15 +1482,18 @@ public ProcessWrapper launchTranscode(
int oldc = overriddenMainArgs.length;
overriddenMainArgs = Arrays.copyOf(overriddenMainArgs, overriddenMainArgs.length + st.countTokens());
i = oldc;
+
while (st.hasMoreTokens()) {
overriddenMainArgs[i++] = st.nextToken();
}
}
boolean foundNoassParam = false;
+
if (media != null) {
String sArgs [] = getSpecificCodecOptions(configuration.getCodecSpecificConfig(), media, params, fileName, subString, configuration.isMencoderIntelligentSync(), false);
- for(String s:sArgs) {
+
+ for (String s : sArgs) {
if (s.equals("-noass")) {
foundNoassParam = true;
}
@@ -1375,11 +1540,14 @@ public ProcessWrapper launchTranscode(
assSubColor = assSubColor.substring(2) + "00";
}
}
+
sb.append("-ass-color ").append(assSubColor).append(" -ass-border-color 00000000 -ass-font-scale ").append(configuration.getMencoderAssScale());
// set subtitles font
if (configuration.getMencoderFont() != null && configuration.getMencoderFont().length() > 0) {
- sb.append(" -font ").append(configuration.getMencoderFont()).append(" "); // set font with -font option, workarond for https://github.com/Happy-Neko/ps3mediaserver/commit/52e62203ea12c40628de1869882994ce1065446a#commitcomment-990156 bug
+ // set font with -font option, workarond for
+ // https://github.com/Happy-Neko/ps3mediaserver/commit/52e62203ea12c40628de1869882994ce1065446a#commitcomment-990156 bug
+ sb.append(" -font ").append(configuration.getMencoderFont()).append(" ");
sb.append(" -ass-force-style FontName=").append(configuration.getMencoderFont()).append(",");
} else {
String font = CodecUtil.getDefaultFontPath();
@@ -1408,8 +1576,9 @@ public ProcessWrapper launchTranscode(
try {
userMargin = Integer.parseInt(configuration.getMencoderAssMargin());
} catch (NumberFormatException n) {
- logger.debug("Could not parse SSA margin from \"" + configuration.getMencoderAssMargin() + "\"");
+ LOGGER.debug("Could not parse SSA margin from \"" + configuration.getMencoderAssMargin() + "\"");
}
+
subtitleMargin = subtitleMargin + userMargin;
sb.append(",MarginV=").append(subtitleMargin).append(" ");
@@ -1446,8 +1615,9 @@ public ProcessWrapper launchTranscode(
try {
userMargin = Integer.parseInt(configuration.getMencoderNoAssSubPos());
} catch (NumberFormatException n) {
- logger.debug("Could not parse subpos from \"" + configuration.getMencoderNoAssSubPos() + "\"");
+ LOGGER.debug("Could not parse subpos from \"" + configuration.getMencoderNoAssSubPos() + "\"");
}
+
subtitleMargin = subtitleMargin + userMargin;
sb.append(" -subpos ").append(100 - subtitleMargin).append(" ");
@@ -1476,17 +1646,21 @@ public ProcessWrapper launchTranscode(
int oldc = overriddenMainArgs.length;
overriddenMainArgs = Arrays.copyOf(overriddenMainArgs, overriddenMainArgs.length + st.countTokens());
i = oldc;
- processToken = false;
+ handleToken = false;
+
while (st.hasMoreTokens()) {
String s = st.nextToken();
- if (processToken) {
+
+ if (handleToken) {
s = "-quiet";
- processToken = false;
+ handleToken = false;
}
+
if ((!configuration.isMencoderAss() || dvd) && s.contains("-ass")) {
s = "-quiet";
- processToken = true;
+ handleToken = true;
}
+
overriddenMainArgs[i++] = s;
}
@@ -1502,10 +1676,12 @@ public ProcessWrapper launchTranscode(
cmdArray[2] = "0";
}
- cmdArray[3] = "-quiet";
- if (media != null && media.getDvdtrack() > 0) {
+ if (dvd) {
cmdArray[3] = "-dvd-device";
+ } else {
+ cmdArray[3] = "-quiet";
}
+
if (avisynth && !fileName.toLowerCase().endsWith(".iso")) {
File avsFile = FFMpegVideo.getAVSScript(fileName, params.sid, params.fromFrame, params.toFrame);
cmdArray[4] = ProcessUtil.getShortFileNameIfWideChars(avsFile.getAbsolutePath());
@@ -1515,11 +1691,15 @@ public ProcessWrapper launchTranscode(
cmdArray[4] = "-";
}
}
- cmdArray[5] = "-quiet";
- if (media != null && media.getDvdtrack() > 0) {
+
+ if (dvd) {
cmdArray[5] = "dvd://" + media.getDvdtrack();
+ } else {
+ cmdArray[5] = "-quiet";
}
+
String arguments[] = args();
+
for (i = 0; i < arguments.length; i++) {
cmdArray[6 + i] = arguments[i];
if (arguments[i].contains("format=mpeg2") && media.getAspect() != null && media.getValidAspect(true) != null) {
@@ -1531,6 +1711,7 @@ public ProcessWrapper launchTranscode(
cmdArray[cmdArray.length - 11] = "-quiet";
cmdArray[cmdArray.length - 10] = "-quiet";
cmdArray[cmdArray.length - 9] = "-quiet";
+
if (!dts && !pcm && !avisynth() && params.aid != null && media.getAudioCodes().size() > 1) {
cmdArray[cmdArray.length - 12] = "-aid";
boolean lavf = false; // Need to add support for LAVF demuxing
@@ -1559,13 +1740,16 @@ public ProcessWrapper launchTranscode(
cmdArray[cmdArray.length - 8] = "-fps";
cmdArray[cmdArray.length - 7] = "24000/1001";
}
+
cmdArray[cmdArray.length - 6] = "-ofps";
cmdArray[cmdArray.length - 5] = "24000/1001";
String frameRate = null;
+
if (media != null) {
frameRate = media.getValidFps(true);
}
+
if (frameRate != null) {
cmdArray[cmdArray.length - 5] = frameRate;
if (configuration.isMencoderForceFps()) {
@@ -1612,10 +1796,19 @@ public ProcessWrapper launchTranscode(
boolean deinterlace = configuration.isMencoderYadif();
// Check if the media renderer supports this resolution
- boolean isResolutionTooHighForRenderer = params.mediaRenderer.isVideoRescale() && media != null && (media.getWidth() > params.mediaRenderer.getMaxVideoWidth() || (media.getHeight() > params.mediaRenderer.getMaxVideoHeight()));
+ boolean isResolutionTooHighForRenderer = params.mediaRenderer.isVideoRescale()
+ && media != null
+ && (
+ (media.getWidth() > params.mediaRenderer.getMaxVideoWidth())
+ ||
+ (media.getHeight() > params.mediaRenderer.getMaxVideoHeight())
+ );
// Video scaler and overscan compensation
- boolean scaleBool = isResolutionTooHighForRenderer || (configuration.isMencoderScaler() && (configuration.getMencoderScaleX() != 0 || configuration.getMencoderScaleY() != 0)) || (intOCW > 0 || intOCH > 0);
+ boolean scaleBool = isResolutionTooHighForRenderer
+ || (configuration.isMencoderScaler() && (configuration.getMencoderScaleX() != 0 || configuration.getMencoderScaleY() != 0))
+ || (intOCW > 0 || intOCH > 0);
+
if ((deinterlace || scaleBool) && !avisynth()) {
StringBuilder vfValueOverscanPrepend = new StringBuilder();
StringBuilder vfValueOverscanMiddle = new StringBuilder();
@@ -1692,7 +1885,8 @@ public ProcessWrapper launchTranscode(
scaleHeight = params.mediaRenderer.getMaxVideoHeight();
}
}
- logger.info("Setting video resolution to: " + scaleWidth + "x" + scaleHeight + ", your Video Scaler setting");
+
+ LOGGER.info("Setting video resolution to: " + scaleWidth + "x" + scaleHeight + ", your Video Scaler setting");
vfValueVS.append("scale=").append(scaleWidth).append(":").append(scaleHeight);
@@ -1743,7 +1937,8 @@ public ProcessWrapper launchTranscode(
scaleHeight = params.mediaRenderer.getMaxVideoHeight();
}
}
- logger.info("Setting video resolution to: " + scaleWidth + "x" + scaleHeight + ", the maximum your renderer supports");
+
+ LOGGER.info("Setting video resolution to: " + scaleWidth + "x" + scaleHeight + ", the maximum your renderer supports");
vfValueVS.append("scale=").append(scaleWidth).append(":").append(scaleHeight);
}
@@ -1751,7 +1946,7 @@ public ProcessWrapper launchTranscode(
// Put the string together taking into account overscan compensation and video scaler
if (intOCW > 0 || intOCH > 0) {
vfValueComplete.append(vfValueOverscanPrepend).append(vfValueOverscanMiddle).append(",harddup");
- logger.info("Setting video resolution to: " + scaleWidth + "x" + scaleHeight + ", to fit your overscan compensation");
+ LOGGER.info("Setting video resolution to: " + scaleWidth + "x" + scaleHeight + ", to fit your overscan compensation");
} else {
vfValueComplete.append(vfValueVS);
}
@@ -1792,6 +1987,7 @@ public ProcessWrapper launchTranscode(
}
boolean noMC0NoSkip = false;
+
if (media != null) {
String sArgs[] = getSpecificCodecOptions(configuration.getCodecSpecificConfig(), media, params, fileName, subString, configuration.isMencoderIntelligentSync(), false);
if (sArgs != null && sArgs.length > 0) {
@@ -1800,8 +1996,7 @@ public ProcessWrapper launchTranscode(
for (int s = 0; s < sArgs.length; s++) {
if (sArgs[s].equals("-noass")) {
for (int c = 0; c < cmdArray.length; c++) {
- if (cmdArray[c] != null && cmdArray[c].equals("-ass"))
- {
+ if (cmdArray[c] != null && cmdArray[c].equals("-ass")) {
cmdArray[c] = "-quiet";
}
}
@@ -1947,6 +2142,7 @@ public ProcessWrapper launchTranscode(
if (pcm || dts || mux) {
boolean channels_filter_present = false;
+
for (String s : cmdArray) {
if (StringUtils.isNotBlank(s) && s.startsWith("channels")) {
channels_filter_present = true;
@@ -1988,6 +2184,7 @@ public ProcessWrapper launchTranscode(
audioPipe.deleteLater();
} else {
// remove the -oac switch, otherwise too many video packets errors appears again
+
for (int s = 0; s < cmdArray.length; s++) {
if (cmdArray[s].equals("-oac")) {
cmdArray[s] = "-nosound";
@@ -2054,8 +2251,7 @@ public ProcessWrapper launchTranscode(
"-o", ffAudioPipe.getInputPipe()
};
- if (!params.mediaRenderer.isMuxDTSToMpeg()) // no need to use the PCM trick when media renderer supports DTS
- {
+ if (!params.mediaRenderer.isMuxDTSToMpeg()) { // no need to use the PCM trick when media renderer supports DTS
ffAudioPipe.setModifier(sm);
}
@@ -2066,6 +2262,7 @@ public ProcessWrapper launchTranscode(
} else if (params.stdin != null) {
ffmpegLPCMextract[3] = "-";
}
+
if (fileName.toLowerCase().endsWith(".evo")) {
ffmpegLPCMextract[4] = "-psprobe";
ffmpegLPCMextract[5] = "1000000";
@@ -2074,6 +2271,7 @@ public ProcessWrapper launchTranscode(
if (params.timeseek > 0) {
ffmpegLPCMextract[2] = "" + params.timeseek;
}
+
OutputParams ffaudioparams = new OutputParams(configuration);
ffaudioparams.maxBufferSize = 1;
ffaudioparams.stdin = params.stdin;
@@ -2084,20 +2282,25 @@ public ProcessWrapper launchTranscode(
PrintWriter pwMux = new PrintWriter(f);
pwMux.println("MUXOPT --no-pcr-on-video-pid --no-asyncio --new-audio-pes --vbr --vbv-len=500");
String videoType = "V_MPEG-2";
+
if (params.no_videoencode && params.forceType != null) {
videoType = params.forceType;
}
+
String fps = "";
if (params.forceFps != null) {
fps = "fps=" + params.forceFps + ", ";
}
+
String audioType = "A_LPCM";
if (params.mediaRenderer.isMuxDTSToMpeg()) {
audioType = "A_DTS";
}
+
if (params.lossyaudio) {
audioType = "A_AC3";
}
+
pwMux.println(videoType + ", \"" + ffVideoPipe.getOutputPipe() + "\", " + fps + "level=4.1, insertSEI, contSPS, track=1");
pwMux.println(audioType + ", \"" + ffAudioPipe.getOutputPipe() + "\", track=2");
pwMux.close();
@@ -2105,26 +2308,28 @@ public ProcessWrapper launchTranscode(
ProcessWrapper pipe_process = pipe.getPipeProcess();
pw.attachProcess(pipe_process);
pipe_process.runInNewThread();
+
try {
Thread.sleep(50);
} catch (InterruptedException e) {
}
+
pipe.deleteLater();
params.input_pipes[0] = pipe;
ProcessWrapper ff_pipe_process = ffAudioPipe.getPipeProcess();
pw.attachProcess(ff_pipe_process);
ff_pipe_process.runInNewThread();
+
try {
Thread.sleep(50);
} catch (InterruptedException e) {
}
+
ffAudioPipe.deleteLater();
pw.attachProcess(ffAudio);
ffAudio.runInNewThread();
-
}
-
} else {
boolean directpipe = Platform.isMac() || Platform.isFreeBSD();
if (directpipe) {
@@ -2161,14 +2366,15 @@ public ProcessWrapper launchTranscode(
}
pipe.deleteLater();
}
-
}
pw.runInNewThread();
+
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
+
return pw;
}
@@ -2188,22 +2394,23 @@ public int type() {
}
private String[] getSpecificCodecOptions(String codecParam, DLNAMediaInfo media, OutputParams params, String filename, String srtFileName, boolean enable, boolean verifyOnly) {
-
StringBuilder sb = new StringBuilder();
-
String codecs = enable ? DEFAULT_CODEC_CONF_SCRIPT : "";
codecs += "\n" + codecParam;
StringTokenizer stLines = new StringTokenizer(codecs, "\n");
+
try {
Interpreter interpreter = new Interpreter();
interpreter.setStrictJava(true);
ArrayList<String> types = CodecUtil.getPossibleCodecs();
int rank = 1;
+
if (types != null) {
for (String type : types) {
int r = rank++;
interpreter.set("" + type, r);
String secondaryType = "dummy";
+
if ("matroska".equals(type)) {
secondaryType = "mkv";
interpreter.set(secondaryType, r);
@@ -2217,6 +2424,7 @@ public int type() {
secondaryType = "mpeg1";
interpreter.set(secondaryType, r);
}
+
if (media.getContainer() != null && (media.getContainer().equals(type) || media.getContainer().equals(secondaryType))) {
interpreter.set("container", r);
} else if (media.getCodecV() != null && (media.getCodecV().equals(type) || media.getCodecV().equals(secondaryType))) {
@@ -2233,29 +2441,39 @@ public int type() {
interpreter.set("audio", params.aid != null);
interpreter.set("subtitles", params.sid != null);
interpreter.set("srtfile", srtFileName);
+
if (params.aid != null) {
interpreter.set("samplerate", params.aid.getSampleRate());
}
+
String framerate = media.getValidFps(false);
+
try {
if (framerate != null) {
interpreter.set("framerate", Double.parseDouble(framerate));
}
} catch (NumberFormatException e) {
- logger.debug("Could not parse framerate from \"" + framerate + "\"");
+ LOGGER.debug("Could not parse framerate from \"" + framerate + "\"");
}
+
interpreter.set("duration", media.getDurationInSeconds());
+
if (params.aid != null) {
interpreter.set("channels", params.aid.getNrAudioChannels());
}
+
interpreter.set("height", media.getHeight());
interpreter.set("width", media.getWidth());
+
while (stLines.hasMoreTokens()) {
String line = stLines.nextToken();
+
if (!line.startsWith("#") && line.trim().length() > 0) {
int separator = line.indexOf("::");
+
if (separator > -1) {
String key = null;
+
try {
key = line.substring(0, separator).trim();
String value = line.substring(separator + 2).trim();
@@ -2264,14 +2482,17 @@ public int type() {
if (key.length() == 0) {
key = "1 == 1";
}
+
Object result = interpreter.eval(key);
+
if (result != null && result instanceof Boolean && ((Boolean) result).booleanValue()) {
sb.append(" ");
sb.append(value);
}
}
} catch (Throwable e) {
- logger.debug("Error while executing: " + key + " : " + e.getMessage());
+ LOGGER.debug("Error while executing: " + key + " : " + e.getMessage());
+
if (verifyOnly) {
return new String[]{"@@Error while parsing: " + e.getMessage()};
}
@@ -2282,14 +2503,16 @@ public int type() {
}
}
} catch (EvalError e) {
- logger.debug("BeanShell error: " + e.getMessage());
+ LOGGER.debug("BeanShell error: " + e.getMessage());
}
- String completeLine = sb.toString();
+ String completeLine = sb.toString();
ArrayList<String> args = new ArrayList<String>();
StringTokenizer st = new StringTokenizer(completeLine, " ");
+
while (st.hasMoreTokens()) {
String arg = st.nextToken().trim();
+
if (arg.length() > 0) {
args.add(arg);
}
@@ -2297,6 +2520,7 @@ public int type() {
String definitiveArgs[] = new String[args.size()];
args.toArray(definitiveArgs);
+
return definitiveArgs;
}
}

5 comments on commit fe41952

@SubJunk

One of the recent commits (I'm guessing this one) causes Java to crash while browsing

@Raptor399
Owner

Kudos for daring to clean up the MencoderVideo argument handling!
That's scary territory.

@Raptor399
Owner

No Java crash on OSX while browsing with this commit for me.

@chocolateboy

Kudos for daring to clean up the MencoderVideo argument handling!

Thanks! I've only just begun :-)

One of the recent commits (I'm guessing this one) causes Java to crash while browsing

As the current main contributor to MEncoderVideo, you of all people should know that it's completely unrelated to "browsing" (the changes are only to code reachable from launchTranscode).

@SubJunk

It was just a quick guess based on the timing of the bug, I hadn't looked at the code. However it looks like the new MediaInfo is responsible so I reverted it :) I will do followup with the MediaInfo developer.

Please sign in to comment.
Something went wrong with that request. Please try again.