Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #9 from Raptor399/iscompatible

Making streaming and transcoding logic better configurable
  • Loading branch information...
commit c761b087141e99bc2417f734f52220ea38da6309 2 parents b664f8d + 17ada5e
@Raptor399 Raptor399 authored
Showing with 782 additions and 41 deletions.
  1. +1 −0  CHANGELOG
  2. +60 −0 src/main/java/net/pms/configuration/RendererConfiguration.java
  3. +3 −7 src/main/java/net/pms/dlna/DLNAResource.java
  4. +12 −2 src/main/java/net/pms/dlna/FileTranscodeVirtualFolder.java
  5. +16 −1 src/main/java/net/pms/formats/DVRMS.java
  6. +4 −1 src/main/java/net/pms/formats/FLAC.java
  7. +63 −7 src/main/java/net/pms/formats/Format.java
  8. +5 −1 src/main/java/net/pms/formats/GIF.java
  9. +16 −1 src/main/java/net/pms/formats/ISO.java
  10. +15 −0 src/main/java/net/pms/formats/JPG.java
  11. +17 −3 src/main/java/net/pms/formats/M4A.java
  12. +20 −1 src/main/java/net/pms/formats/MKV.java
  13. +17 −1 src/main/java/net/pms/formats/MP3.java
  14. +18 −1 src/main/java/net/pms/formats/MPG.java
  15. +17 −1 src/main/java/net/pms/formats/OGG.java
  16. +5 −1 src/main/java/net/pms/formats/PNG.java
  17. +16 −10 src/main/java/net/pms/formats/RAW.java
  18. +5 −1 src/main/java/net/pms/formats/TIF.java
  19. +16 −1 src/main/java/net/pms/formats/WAV.java
  20. +25 −1 src/main/java/net/pms/formats/WEB.java
  21. +321 −0 src/test/java/net/pms/test/formats/FormatRecognitionTest.java
  22. +110 −0 src/test/java/net/pms/test/formats/FormatTest.java
View
1  CHANGELOG
@@ -21,6 +21,7 @@ Changelog:
Migrated PMS source to GitHub (https://github.com/ps3mediaserver/ps3mediaserver)
Added commit information
Added subtitle HTTP header support for SamsungAllShare (thanks, SamiMakinen!)
+ Made streaming and transcoding logic better configurable (thanks, StreamHD!)
2011-11-20 - 1.50.0
View
60 src/main/java/net/pms/configuration/RendererConfiguration.java
@@ -9,6 +9,8 @@
import java.util.regex.Pattern;
import net.pms.Messages;
+import net.pms.PMS;
+import net.pms.dlna.DLNAMediaInfo;
import net.pms.dlna.MediaInfoParser;
import net.pms.dlna.RootFolder;
import net.pms.formats.Format;
@@ -167,6 +169,28 @@ public static RendererConfiguration getRendererConfigurationByUAAHH(String heade
}
return null;
}
+
+ /**
+ * Tries to find a matching renderer configuration based on the name of
+ * the renderer. Returns true if the provided name is equal to or a
+ * substring of the renderer name defined in a configuration, where case
+ * does not matter.
+ *
+ * @param name The renderer name to match.
+ * @return The matching renderer configuration or <code>null</code>
+ *
+ * @since 1.50.1
+ */
+ public static RendererConfiguration getRendererConfigurationByName(String name) {
+ for (RendererConfiguration conf : renderersConfs) {
+ if (conf.getRendererName().toLowerCase().contains(name.toLowerCase())) {
+ return conf;
+ }
+ }
+
+ return null;
+ }
+
private final PropertiesConfiguration configuration;
private FormatConfiguration formatConfiguration;
@@ -826,4 +850,40 @@ public boolean isDLNATreeHack() {
public boolean isChunkedTransfer() {
return getBoolean(CHUNKED_TRANSFER, false);
}
+
+ /**
+ * Returns whether or not the renderer can handle the given format
+ * natively, based on its configuration in the renderer.conf. If it can
+ * handle a format natively, content can be streamed to the renderer. If
+ * not, content should be transcoded before sending it to the renderer.
+ *
+ * @param mediainfo The {@link DLNAMediaInfo} information parsed from the
+ * media file.
+ * @param format The {@link Format} to test compatibility for.
+ * @return True if the renderer natively supports the format, false
+ * otherwise.
+ */
+ public boolean isCompatible(DLNAMediaInfo mediainfo, Format format) {
+ if (isMediaParserV2() && mediainfo != null) {
+ // Use the configured "Supported" lines in the renderer.conf
+ // to see if any of them match the MediaInfo library
+ if (getFormatConfiguration().match(mediainfo) != null) {
+ return true;
+ }
+ }
+
+ if (format != null) {
+ String noTranscode = "";
+
+ if (PMS.getConfiguration() != null) {
+ noTranscode = PMS.getConfiguration().getNoTranscode();
+ }
+
+ // Is the format among the ones to be streamed?
+ return format.skip(noTranscode, getStreamedExtensions());
+ } else {
+ // Not natively supported.
+ return false;
+ }
+ }
}
View
10 src/main/java/net/pms/dlna/DLNAResource.java
@@ -543,15 +543,13 @@ public void addChild(DLNAResource child) {
}
boolean hasSubsToTranscode = false;
-
if (!PMS.getConfiguration().isMencoderDisableSubs()) {
hasSubsToTranscode = (PMS.getConfiguration().getUseSubtitles() && child.isSrtFile()) || hasEmbeddedSubs;
}
boolean isIncompatible = false;
- // FIXME: Remove PS3 specific logic to support other renderers
- if (!parserV2 && !child.getExt().ps3compatible()) {
+ if (!child.getExt().isCompatible(child.getMedia(),getDefaultRenderer())) {
isIncompatible = true;
}
@@ -591,8 +589,7 @@ public void addChild(DLNAResource child) {
}
}
}
- } else if (!child.getExt().ps3compatible() && !child.isFolder()) {
- // FIXME: Remove PS3 specific logic to support other renderers
+ } else if (!child.getExt().isCompatible(child.getMedia(),getDefaultRenderer()) && !child.isFolder()) {
getChildren().remove(child);
}
}
@@ -603,8 +600,7 @@ public void addChild(DLNAResource child) {
newChild.first = child;
child.second = newChild;
- // FIXME: Remove PS3 specific logic to support other renderers
- if (!newChild.getExt().ps3compatible() && newChild.getExt().getProfiles().size() > 0) {
+ if (!newChild.getExt().isCompatible(newChild.getMedia(),getDefaultRenderer()) && newChild.getExt().getProfiles().size() > 0) {
newChild.setPlayer(PMS.get().getPlayer(newChild.getExt().getProfiles().get(0), newChild.getExt()));
}
if (child.getMedia() != null && child.getMedia().isSecondaryFormatValid()) {
View
14 src/main/java/net/pms/dlna/FileTranscodeVirtualFolder.java
@@ -19,6 +19,7 @@
package net.pms.dlna;
import net.pms.PMS;
+import net.pms.configuration.RendererConfiguration;
import net.pms.dlna.virtual.VirtualFolder;
import net.pms.encoders.MEncoderVideo;
import net.pms.encoders.Player;
@@ -102,13 +103,22 @@ public void resolve() {
// meskibob: I think it'd be a good idea to add a "Stream" option (for PS3 compatible containers) to the #Transcode# folder in addition to the current options already in there.
DLNAResource justStreamed = ref.clone();
- // FIXME: Remove PS3 specific logic to support other renderers
- if (justStreamed.getExt() != null && (justStreamed.getExt().ps3compatible() || justStreamed.isSkipTranscode())) {
+ RendererConfiguration renderer = null;
+
+ if (this.getParent() != null) {
+ renderer = this.getParent().getDefaultRenderer();
+ }
+
+ if (justStreamed.getExt() != null && (justStreamed.getExt().isCompatible(ref.getMedia(), renderer) || justStreamed.isSkipTranscode())) {
justStreamed.setPlayer(null);
justStreamed.setMedia(ref.getMedia());
justStreamed.setNoName(true);
addChildInternal(justStreamed);
addChapterFile(justStreamed);
+
+ if (renderer != null) {
+ logger.debug("Duplicate " + ref.getName() + " for direct streaming to renderer: " + renderer.getRendererName());
+ }
}
}
}
View
17 src/main/java/net/pms/formats/DVRMS.java
@@ -22,6 +22,8 @@
import net.pms.PMS;
+import net.pms.configuration.RendererConfiguration;
+import net.pms.dlna.DLNAMediaInfo;
import net.pms.encoders.FFMpegDVRMSRemux;
import net.pms.encoders.Player;
@@ -49,11 +51,24 @@ public DVRMS() {
type = VIDEO;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public String[] getId() {
- return new String[]{"dvr-ms", "dvr"};
+ return new String[] { "dvr-ms", "dvr" };
}
+ /**
+ * @deprecated Use {@link #isCompatible(DLNAMediaInfo, RendererConfiguration)} instead.
+ * <p>
+ * Returns whether or not a format can be handled by the PS3 natively.
+ * This means the format can be streamed to PS3 instead of having to be
+ * transcoded.
+ *
+ * @return True if the format can be handled by PS3, false otherwise.
+ */
+ @Deprecated
@Override
public boolean ps3compatible() {
return false;
View
5 src/main/java/net/pms/formats/FLAC.java
@@ -23,8 +23,11 @@ public FLAC() {
secondaryFormat = new AudioAsVideo();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public String[] getId() {
- return new String[]{"flac", "mlp", "fla"};
+ return new String[] { "flac", "mlp", "fla" };
}
}
View
70 src/main/java/net/pms/formats/Format.java
@@ -21,6 +21,7 @@
import java.util.ArrayList;
import java.util.StringTokenizer;
+import net.pms.PMS;
import net.pms.configuration.RendererConfiguration;
import net.pms.dlna.DLNAMediaInfo;
import net.pms.dlna.InputFile;
@@ -30,6 +31,9 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+/**
+ * Abstract class to store known information about a given format.
+ */
public abstract class Format implements Cloneable {
private static final Logger logger = LoggerFactory.getLogger(Format.class);
@@ -44,8 +48,20 @@ public int getType() {
public static final int AUDIO = 1;
public static final int IMAGE = 2;
+ /**
+ * The identifier (filename extension or protocol) that was matched for a
+ * particular filename or URL. Requires {@link #match(String)} to be called
+ * first.
+ */
protected String matchedId;
+ /**
+ * Returns the identifier (filename extension or protocol) that was matched
+ * for a particular filename or URL. Requires {@link #match(String)} to be
+ * called first.
+ *
+ * @return The matched identifier.
+ */
public String getMatchedId() {
return matchedId;
}
@@ -66,20 +82,45 @@ public void setType(int type) {
}
}
+ /**
+ * Returns the identifiers that can be used to identify a particular
+ * format. Valid identifiers are filename extensions or URL protocols,
+ * e.g. "mp3" or "http". Identifiers are expected to be in lower case.
+ *
+ * @return An array of identifiers.
+ */
public abstract String[] getId();
/**
+ * @deprecated Use {@link #isCompatible(DLNAMediaInfo, RendererConfiguration)} instead.
+ * <p>
* Returns whether or not a format can be handled by the PS3 natively.
* This means the format can be streamed to PS3 instead of having to be
* transcoded.
- * <p>
- * FIXME: There are many more renderers; mere PS3 compatibility doesn't
- * cut it any more. Come up with a better solution, for example a
- * RendererConfiguration.isStreamable(Format f).
*
* @return True if the format can be handled by PS3, false otherwise.
*/
+ @Deprecated
public abstract boolean ps3compatible();
+
+ /**
+ * Returns whether or not a format can be handled by the renderer natively.
+ * This means the format can be streamed instead of having to be transcoded.
+ *
+ * @return True if the format can be handled by the renderer, false otherwise.
+ *
+ * @since 1.50.1
+ */
+ public boolean isCompatible(DLNAMediaInfo media, RendererConfiguration renderer) {
+ if (renderer != null) {
+ // Let the renderer configuration decide on native compatibility
+ return renderer.isCompatible(media, this);
+ } else {
+ // Is this format among the ones configured in PMS to be streamed?
+ return skip(PMS.getConfiguration().getNoTranscode(), null);
+ }
+ }
+
public abstract boolean transcodable();
public abstract ArrayList<Class<? extends Player>> getProfiles();
@@ -150,21 +191,36 @@ public void parse(DLNAMediaInfo media, InputFile file, int type, RendererConfigu
logger.trace("Parsing results: " + file + " / " + media);
}
- public boolean skip(String extensions, String another_set_of_extensions) {
+ /**
+ * Returns whether or not the matched identifier of this format is among
+ * the list of supplied extensions.
+ *
+ * @param extensions String of comma separated extensions
+ * @param moreExtensions String of comma separated extensions
+ *
+ * @return True if this format matches any extension, false otherwise.
+ *
+ * @see #match(String)
+ */
+ public boolean skip(String extensions, String moreExtensions) {
if (extensions != null && extensions.length() > 0) {
StringTokenizer st = new StringTokenizer(extensions, ",");
+
while (st.hasMoreTokens()) {
String id = st.nextToken().toLowerCase();
+
if (matchedId != null && matchedId.toLowerCase().equals(id)) {
return true;
}
}
}
- if (another_set_of_extensions != null && another_set_of_extensions.length() > 0) {
- StringTokenizer st = new StringTokenizer(another_set_of_extensions, ",");
+ if (moreExtensions != null && moreExtensions.length() > 0) {
+ StringTokenizer st = new StringTokenizer(moreExtensions, ",");
+
while (st.hasMoreTokens()) {
String id = st.nextToken().toLowerCase();
+
if (matchedId != null && matchedId.toLowerCase().equals(id)) {
return true;
}
View
6 src/main/java/net/pms/formats/GIF.java
@@ -19,9 +19,13 @@
package net.pms.formats;
public class GIF extends JPG {
+
+ /**
+ * {@inheritDoc}
+ */
@Override
public String[] getId() {
- return new String[]{"gif"};
+ return new String[] { "gif" };
}
@Override
View
17 src/main/java/net/pms/formats/ISO.java
@@ -20,11 +20,13 @@
import java.util.ArrayList;
+import net.pms.configuration.RendererConfiguration;
+import net.pms.dlna.DLNAMediaInfo;
import net.pms.encoders.MEncoderVideo;
import net.pms.encoders.Player;
public class ISO extends MPG {
- public static final String[] ISO_EXTENSIONS = new String[]{"iso", "img", /*"bin", "mdf", "nrg", "bwt", "cif","ccd", "vcd", "fcd"*/};
+ public static final String[] ISO_EXTENSIONS = new String[] { "iso", "img", /*"bin", "mdf", "nrg", "bwt", "cif","ccd", "vcd", "fcd"*/ };
@Override
public ArrayList<Class<? extends Player>> getProfiles() {
@@ -33,10 +35,23 @@
return list;
}
+ /**
+ * @deprecated Use {@link #isCompatible(DLNAMediaInfo, RendererConfiguration)} instead.
+ * <p>
+ * Returns whether or not a format can be handled by the PS3 natively.
+ * This means the format can be streamed to PS3 instead of having to be
+ * transcoded.
+ *
+ * @return True if the format can be handled by PS3, false otherwise.
+ */
+ @Deprecated
public boolean ps3compatible() {
return false;
}
+ /**
+ * {@inheritDoc}
+ */
public String[] getId() {
return ISO_EXTENSIONS;
}
View
15 src/main/java/net/pms/formats/JPG.java
@@ -20,6 +20,8 @@
import java.util.ArrayList;
+import net.pms.configuration.RendererConfiguration;
+import net.pms.dlna.DLNAMediaInfo;
import net.pms.encoders.Player;
public class JPG extends Format {
@@ -27,11 +29,24 @@ public JPG() {
type = IMAGE;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public String[] getId() {
return new String[]{"jpeg", "jpg", "jpe", "mpo"};
}
+ /**
+ * @deprecated Use {@link #isCompatible(DLNAMediaInfo, RendererConfiguration)} instead.
+ * <p>
+ * Returns whether or not a format can be handled by the PS3 natively.
+ * This means the format can be streamed to PS3 instead of having to be
+ * transcoded.
+ *
+ * @return True if the format can be handled by PS3, false otherwise.
+ */
+ @Deprecated
@Override
public boolean ps3compatible() {
return true;
View
20 src/main/java/net/pms/formats/M4A.java
@@ -13,19 +13,33 @@
*/
package net.pms.formats;
+import net.pms.configuration.RendererConfiguration;
+import net.pms.dlna.DLNAMediaInfo;
+
public class M4A extends OGG {
@Override
public boolean transcodable() {
return true;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public String[] getId() {
- return new String[]{
- "wma", "m4a", "aac"
- };
+ return new String[] { "wma", "m4a", "aac" };
}
+ /**
+ * @deprecated Use {@link #isCompatible(DLNAMediaInfo, RendererConfiguration)} instead.
+ * <p>
+ * Returns whether or not a format can be handled by the PS3 natively.
+ * This means the format can be streamed to PS3 instead of having to be
+ * transcoded.
+ *
+ * @return True if the format can be handled by PS3, false otherwise.
+ */
+ @Deprecated
@Override
public boolean ps3compatible() {
return false;
View
21 src/main/java/net/pms/formats/MKV.java
@@ -18,12 +18,31 @@
*/
package net.pms.formats;
+import net.pms.configuration.RendererConfiguration;
+import net.pms.dlna.DLNAMediaInfo;
+
public class MKV extends MPG {
+
+ /**
+ * @deprecated Use {@link #isCompatible(DLNAMediaInfo, RendererConfiguration)} instead.
+ * <p>
+ * Returns whether or not a format can be handled by the PS3 natively.
+ * This means the format can be streamed to PS3 instead of having to be
+ * transcoded.
+ *
+ * @return True if the format can be handled by PS3, false otherwise.
+ */
+ @Deprecated
public boolean ps3compatible() {
return false;
}
+ /**
+ * {@inheritDoc}
+ */
public String[] getId() {
- return new String[]{"mkv", "dv", "ty", "mov", "ogm", "ogv", "hdmov", "hdm", "rmv", "rmvb", "rm", "asf", "evo", "asx", "flv", "m2v", "3gp", "3g2"};
+ return new String[] { "mkv", "dv", "ty", "mov", "ogm", "ogv", "hdmov",
+ "hdm", "rmv", "rmvb", "rm", "asf", "evo", "asx", "flv", "m2v",
+ "3gp", "3g2" };
}
}
View
18 src/main/java/net/pms/formats/MP3.java
@@ -20,6 +20,9 @@
import java.util.ArrayList;
+import net.pms.PMS;
+import net.pms.configuration.RendererConfiguration;
+import net.pms.dlna.DLNAMediaInfo;
import net.pms.encoders.Player;
public class MP3 extends Format {
@@ -27,11 +30,24 @@ public MP3() {
type = AUDIO;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public String[] getId() {
- return new String[]{"mp3"};
+ return new String[] { "mp3" };
}
+ /**
+ * @deprecated Use {@link #isCompatible(DLNAMediaInfo, RendererConfiguration)} instead.
+ * <p>
+ * Returns whether or not a format can be handled by the PS3 natively.
+ * This means the format can be streamed to PS3 instead of having to be
+ * transcoded.
+ *
+ * @return True if the format can be handled by PS3, false otherwise.
+ */
+ @Deprecated
@Override
public boolean ps3compatible() {
return true;
View
19 src/main/java/net/pms/formats/MPG.java
@@ -21,6 +21,8 @@
import java.util.ArrayList;
import net.pms.PMS;
+import net.pms.configuration.RendererConfiguration;
+import net.pms.dlna.DLNAMediaInfo;
import net.pms.encoders.FFMpegVideo;
import net.pms.encoders.MEncoderAviSynth;
import net.pms.encoders.MEncoderVideo;
@@ -62,11 +64,26 @@ public MPG() {
type = VIDEO;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public String[] getId() {
- return new String[]{"mpg", "mpeg", "mpe", "mod", "tivo", "ty", "tmf", "ts", "tp", "m2t", "m2ts", "m2p", "mts", "mp4", "m4v", "avi", "wmv", "wm", "vob", "divx", "div", "vdr"};
+ return new String[] { "mpg", "mpeg", "mpe", "mod", "tivo", "ty", "tmf",
+ "ts", "tp", "m2t", "m2ts", "m2p", "mts", "mp4", "m4v", "avi",
+ "wmv", "wm", "vob", "divx", "div", "vdr" };
}
+ /**
+ * @deprecated Use {@link #isCompatible(DLNAMediaInfo, RendererConfiguration)} instead.
+ * <p>
+ * Returns whether or not a format can be handled by the PS3 natively.
+ * This means the format can be streamed to PS3 instead of having to be
+ * transcoded.
+ *
+ * @return True if the format can be handled by PS3, false otherwise.
+ */
+ @Deprecated
@Override
public boolean ps3compatible() {
return true;
View
18 src/main/java/net/pms/formats/OGG.java
@@ -21,6 +21,8 @@
import java.util.ArrayList;
import net.pms.PMS;
+import net.pms.configuration.RendererConfiguration;
+import net.pms.dlna.DLNAMediaInfo;
import net.pms.encoders.FFMpegAudio;
import net.pms.encoders.MPlayerAudio;
import net.pms.encoders.Player;
@@ -45,11 +47,25 @@ public boolean transcodable() {
return a;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public String[] getId() {
- return new String[]{"dts", "mka", "ape", "ogg", "shn", "mpc", "ra", "mp2", "wv", "oma", "aa3", "at3", "aif", "aiff"};
+ return new String[] { "dts", "mka", "ape", "ogg", "shn", "mpc", "ra",
+ "mp2", "wv", "oma", "aa3", "at3", "aif", "aiff" };
}
+ /**
+ * @deprecated Use {@link #isCompatible(DLNAMediaInfo, RendererConfiguration)} instead.
+ * <p>
+ * Returns whether or not a format can be handled by the PS3 natively.
+ * This means the format can be streamed to PS3 instead of having to be
+ * transcoded.
+ *
+ * @return True if the format can be handled by PS3, false otherwise.
+ */
+ @Deprecated
@Override
public boolean ps3compatible() {
return false;
View
6 src/main/java/net/pms/formats/PNG.java
@@ -19,9 +19,13 @@
package net.pms.formats;
public class PNG extends JPG {
+
+ /**
+ * {@inheritDoc}
+ */
@Override
public String[] getId() {
- return new String[]{"png"};
+ return new String[] { "png" };
}
@Override
View
26 src/main/java/net/pms/formats/RAW.java
@@ -13,11 +13,26 @@
import net.pms.io.ProcessWrapperImpl;
public class RAW extends JPG {
+
+ /**
+ * {@inheritDoc}
+ */
@Override
public String[] getId() {
- return new String[]{"arw", "cr2", "crw", "dng", "raf", "mrw", "nef", "pef", "srf", "orf"};
+ return new String[] { "arw", "cr2", "crw", "dng", "raf", "mrw", "nef",
+ "pef", "srf", "orf" };
}
+ /**
+ * @deprecated Use {@link #isCompatible(DLNAMediaInfo, RendererConfiguration)} instead.
+ * <p>
+ * Returns whether or not a format can be handled by the PS3 natively.
+ * This means the format can be streamed to PS3 instead of having to be
+ * transcoded.
+ *
+ * @return True if the format can be handled by PS3, false otherwise.
+ */
+ @Deprecated
@Override
public boolean ps3compatible() {
return false;
@@ -87,13 +102,4 @@ public void parse(DLNAMediaInfo media, InputFile file, int type, RendererConfigu
e.printStackTrace();
}
}
-
- /*
- * Force this format to be transcoded (RAW support broken in rev 409 and earlier)
- * @see net.pms.formats.Format#skip(java.lang.String, java.lang.String)
- */
- @Override
- public boolean skip(String extensions, String anotherSetOfExtensions) {
- return true;
- }
}
View
6 src/main/java/net/pms/formats/TIF.java
@@ -19,9 +19,13 @@
package net.pms.formats;
public class TIF extends JPG {
+
+ /**
+ * {@inheritDoc}
+ */
@Override
public String[] getId() {
- return new String[]{"tif", "tiff"};
+ return new String[] { "tif", "tiff" };
}
@Override
View
17 src/main/java/net/pms/formats/WAV.java
@@ -21,6 +21,8 @@
import java.util.ArrayList;
import net.pms.PMS;
+import net.pms.configuration.RendererConfiguration;
+import net.pms.dlna.DLNAMediaInfo;
import net.pms.encoders.FFMpegAudio;
import net.pms.encoders.MPlayerAudio;
import net.pms.encoders.Player;
@@ -49,11 +51,24 @@ public boolean transcodable() {
return a;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public String[] getId() {
- return new String[]{"wav"};
+ return new String[] { "wav" };
}
+ /**
+ * @deprecated Use {@link #isCompatible(DLNAMediaInfo, RendererConfiguration)} instead.
+ * <p>
+ * Returns whether or not a format can be handled by the PS3 natively.
+ * This means the format can be streamed to PS3 instead of having to be
+ * transcoded.
+ *
+ * @return True if the format can be handled by PS3, false otherwise.
+ */
+ @Deprecated
@Override
public boolean ps3compatible() {
return true;
View
26 src/main/java/net/pms/formats/WEB.java
@@ -21,6 +21,8 @@
import java.util.ArrayList;
import net.pms.PMS;
+import net.pms.configuration.RendererConfiguration;
+import net.pms.dlna.DLNAMediaInfo;
import net.pms.encoders.MEncoderWebVideo;
import net.pms.encoders.MPlayerWebAudio;
import net.pms.encoders.MPlayerWebVideoDump;
@@ -29,6 +31,16 @@
import net.pms.encoders.VideoLanVideoStreaming;
public class WEB extends Format {
+ /**
+ * @deprecated Use {@link #isCompatible(DLNAMediaInfo, RendererConfiguration)} instead.
+ * <p>
+ * Returns whether or not a format can be handled by the PS3 natively.
+ * This means the format can be streamed to PS3 instead of having to be
+ * transcoded.
+ *
+ * @return True if the format can be handled by PS3, false otherwise.
+ */
+ @Deprecated
@Override
public boolean ps3compatible() {
return type == IMAGE;
@@ -61,13 +73,25 @@ public boolean ps3compatible() {
return a;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public String[] getId() {
- return new String[]{"http", "mms", "rtsp", "rtp", "udp", "screen"};
+ return new String[] { "http", "mms", "rtsp", "rtp", "udp", "screen" };
}
@Override
public boolean transcodable() {
return true;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isCompatible(DLNAMediaInfo media, RendererConfiguration renderer) {
+ // Emulating ps3compatible()
+ return type == IMAGE;
+ }
}
View
321 src/test/java/net/pms/test/formats/FormatRecognitionTest.java
@@ -0,0 +1,321 @@
+/*
+ * 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.test.formats;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.ArrayList;
+
+import net.pms.configuration.RendererConfiguration;
+import net.pms.dlna.DLNAMediaAudio;
+import net.pms.dlna.DLNAMediaInfo;
+import net.pms.formats.DVRMS;
+import net.pms.formats.Format;
+import net.pms.formats.GIF;
+import net.pms.formats.ISO;
+import net.pms.formats.JPG;
+import net.pms.formats.M4A;
+import net.pms.formats.MKV;
+import net.pms.formats.MP3;
+import net.pms.formats.MPG;
+import net.pms.formats.OGG;
+import net.pms.formats.PNG;
+import net.pms.formats.RAW;
+import net.pms.formats.TIF;
+import net.pms.formats.WAV;
+import net.pms.formats.WEB;
+import net.pms.network.HTTPResource;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.LoggerFactory;
+
+import ch.qos.logback.classic.LoggerContext;
+
+
+/**
+ * Test the recognition of formats.
+ */
+public class FormatRecognitionTest {
+ @Before
+ public void setUp() {
+ // Silence all log messages from the PMS code that is being tested
+ LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
+ context.reset();
+
+ // Initialize the RendererConfiguration
+ RendererConfiguration.loadRendererConfigurations();
+ }
+
+ /**
+ * Test some basic functionality of {@link RendererConfiguration#isCompatible(DLNAMediaInfo, Format)}
+ */
+ @Test
+ public void testRendererConfigurationBasics() {
+ RendererConfiguration conf = RendererConfiguration.getRendererConfigurationByName("Playstation 3");
+ assertNotNull("No renderer named \"Playstation 3\" found.", conf);
+ assertEquals("With nothing provided isCompatible() should return false", false,
+ conf.isCompatible(null, null));
+ }
+
+ /**
+ * Test the compatibility of the Playstation 3 with the GIF format.
+ */
+ @Test
+ public void testPlaystationImageGifCompatibility() {
+ RendererConfiguration conf = RendererConfiguration.getRendererConfigurationByName("Playstation 3");
+ assertNotNull("No renderer named \"Playstation 3\" found.", conf);
+
+ // Construct GIF information
+ DLNAMediaInfo info = new DLNAMediaInfo();
+ info.setContainer("gif");
+ Format format = new GIF();
+ format.match("test.gif");
+ assertEquals("PS3 is reported to be incompatible with GIF", true,
+ conf.isCompatible(info, format));
+ }
+
+ /**
+ * Test the compatibility of the Playstation 3 with the PNG format.
+ */
+ @Test
+ public void testPlaystationImagePngCompatibility() {
+ RendererConfiguration conf = RendererConfiguration.getRendererConfigurationByName("Playstation 3");
+ assertNotNull("No renderer named \"Playstation 3\" found.", conf);
+
+ // Construct JPG information
+ DLNAMediaInfo info = new DLNAMediaInfo();
+ info.setContainer("png");
+ Format format = new PNG();
+ format.match("test.png");
+ assertEquals("PS3 is reported to be incompatible with PNG", true,
+ conf.isCompatible(info, format));
+ }
+
+ /**
+ * Test the compatibility of the Playstation 3 with the TIFF format.
+ */
+ @Test
+ public void testPlaystationImageTiffCompatibility() {
+ RendererConfiguration conf = RendererConfiguration.getRendererConfigurationByName("Playstation 3");
+ assertNotNull("No renderer named \"Playstation 3\" found.", conf);
+
+ // Construct JPG information
+ DLNAMediaInfo info = new DLNAMediaInfo();
+ info.setContainer("tiff");
+ Format format = new TIF();
+ format.match("test.tiff");
+ assertEquals("PS3 is reported to be incompatible with TIFF", true,
+ conf.isCompatible(info, format));
+ }
+
+ /**
+ * Test the compatibility of the Playstation 3 with the MP3 format.
+ */
+ @Test
+ public void testPlaystationAudioMp3Compatibility() {
+ RendererConfiguration conf = RendererConfiguration.getRendererConfigurationByName("Playstation 3");
+ assertNotNull("No renderer named \"Playstation 3\" found.", conf);
+
+ // Construct regular two channel MP3 information
+ DLNAMediaInfo info = new DLNAMediaInfo();
+ info.setContainer("mp3");
+ info.setMimeType(HTTPResource.AUDIO_MP3_TYPEMIME);
+ DLNAMediaAudio audio = new DLNAMediaAudio();
+ audio.setNrAudioChannels(2);
+ ArrayList<DLNAMediaAudio> audioCodes = new ArrayList<DLNAMediaAudio>();
+ audioCodes.add(audio);
+ info.setAudioCodes(audioCodes);
+ Format format = new MP3();
+ format.match("test.mp3");
+ assertEquals("PS3 is reported to be incompatible with MP3", true,
+ conf.isCompatible(info, format));
+
+ // Construct five channel MP3 that the PS3 does not support natively
+ audio.setNrAudioChannels(5);
+ assertEquals("PS3 is reported to be incompatible with MP3", false,
+ conf.isCompatible(info, format));
+ }
+
+ /**
+ * Test the compatibility of the Playstation 3 with the MPG format.
+ */
+ @Test
+ public void testPlaystationVideoMpgCompatibility() {
+ RendererConfiguration conf = RendererConfiguration.getRendererConfigurationByName("Playstation 3");
+ assertNotNull("No renderer named \"Playstation 3\" found.", conf);
+
+ // Construct regular two channel MPG information
+ DLNAMediaInfo info = new DLNAMediaInfo();
+ info.setContainer("avi");
+ DLNAMediaAudio audio = new DLNAMediaAudio();
+ audio.setCodecA("ac3");
+ audio.setNrAudioChannels(5);
+ ArrayList<DLNAMediaAudio> audioCodes = new ArrayList<DLNAMediaAudio>();
+ audioCodes.add(audio);
+ info.setAudioCodes(audioCodes);
+ info.setCodecV("mp4");
+ Format format = new MPG();
+ format.match("test.avi");
+ assertEquals("PS3 is reported to be incompatible with MPG", true,
+ conf.isCompatible(info, format));
+
+ // Construct MPG with wmv codec that the PS3 does not support natively
+ info.setCodecV("wmv");
+ assertEquals("PS3 is reported to be compatible with MPG with wmv codec", false,
+ conf.isCompatible(info, format));
+ }
+
+ /**
+ * Test the compatibility of the Playstation 3 with the MPG format.
+ */
+ @Test
+ public void testPlaystationVideoMkvCompatibility() {
+ RendererConfiguration conf = RendererConfiguration.getRendererConfigurationByName("Playstation 3");
+ assertNotNull("No renderer named \"Playstation 3\" found.", conf);
+
+ // Construct MKV information
+ DLNAMediaInfo info = new DLNAMediaInfo();
+ info.setContainer("mkv");
+ DLNAMediaAudio audio = new DLNAMediaAudio();
+ audio.setCodecA("ac3");
+ audio.setNrAudioChannels(5);
+ ArrayList<DLNAMediaAudio> audioCodes = new ArrayList<DLNAMediaAudio>();
+ audioCodes.add(audio);
+ info.setAudioCodes(audioCodes);
+ info.setCodecV("mp4");
+ Format format = new MPG();
+ format.match("test.mkv");
+ assertEquals("PS3 is reported to be incompatible with MKV", false,
+ conf.isCompatible(info, format));
+ }
+
+ /**
+ * Test the backwards compatibility of
+ * {@link Format#isCompatible(DLNAMediaInfo, RendererConfiguration)} and
+ * {@link Format#ps3compatible()}.
+ *
+ */
+ @SuppressWarnings("deprecation")
+ @Test
+ public void testBackwardsCompatibility() {
+ // Testing ps3compatible(), so use renderer Playstation 3
+ RendererConfiguration conf = RendererConfiguration.getRendererConfigurationByName("Playstation 3");
+ assertNotNull("No renderer named \"Playstation 3\" found.", conf);
+
+ // DVRMS: false
+ DLNAMediaInfo info = new DLNAMediaInfo();
+ info.setContainer("dvr");
+ Format format = new DVRMS();
+ format.match("test.dvr");
+ assertEquals("isCompatible() reporting different outcome than ps3compatible() for DVRMS",
+ format.ps3compatible(), conf.isCompatible(info, format));
+
+ // ISO: false
+ info = new DLNAMediaInfo();
+ info.setContainer("iso");
+ format = new ISO();
+ format.match("test.iso");
+ assertEquals("isCompatible() reporting different outcome than ps3compatible() for ISO",
+ format.ps3compatible(), conf.isCompatible(info, format));
+
+ // JPG: true
+ info = new DLNAMediaInfo();
+ info.setContainer("jpg");
+ format = new JPG();
+ format.match("test.jpeg");
+ assertEquals("isCompatible() reporting different outcome than ps3compatible() for JPG",
+ format.ps3compatible(), conf.isCompatible(info, format));
+
+ // M4A: false
+ info = new DLNAMediaInfo();
+ info.setContainer("m4a");
+ format = new M4A();
+ format.match("test.m4a");
+ assertEquals("isCompatible() reporting different outcome than ps3compatible() for M4A",
+ format.ps3compatible(), conf.isCompatible(info, format));
+
+ // MKV: false
+ info = new DLNAMediaInfo();
+ info.setContainer("mkv");
+ format = new MKV();
+ format.match("test.mkv");
+ assertEquals("isCompatible() reporting different outcome than ps3compatible() for MKV",
+ format.ps3compatible(), conf.isCompatible(info, format));
+
+ // MP3: true
+ info = new DLNAMediaInfo();
+ info.setContainer("mp3");
+ format = new MP3();
+ format.match("test.mp3");
+ assertEquals("isCompatible() reporting different outcome than ps3compatible() for MP3",
+ format.ps3compatible(), conf.isCompatible(info, format));
+
+ // MPG: true
+ info = new DLNAMediaInfo();
+ info.setContainer("avi");
+ format = new MPG();
+ format.match("test.mpg");
+ assertEquals("isCompatible() reporting different outcome than ps3compatible() for MPG",
+ format.ps3compatible(), conf.isCompatible(info, format));
+
+ // OGG: false
+ info = new DLNAMediaInfo();
+ info.setContainer("ogg");
+ format = new OGG();
+ format.match("test.ogg");
+ assertEquals("isCompatible() reporting different outcome than ps3compatible() for OGG",
+ format.ps3compatible(), conf.isCompatible(info, format));
+
+ // RAW: false
+ info = new DLNAMediaInfo();
+ info.setContainer("raw");
+ format = new RAW();
+ format.match("test.arw");
+ assertEquals("isCompatible() reporting different outcome than ps3compatible() for RAW",
+ format.ps3compatible(), conf.isCompatible(info, format));
+
+ // WAV: true
+ info = new DLNAMediaInfo();
+ info.setContainer("wav");
+ format = new WAV();
+ format.match("test.wav");
+ assertEquals("isCompatible() reporting different outcome than ps3compatible() for WAV",
+ format.ps3compatible(), conf.isCompatible(info, format));
+
+ // WEB: type=IMAGE
+ info = new DLNAMediaInfo();
+ info.setContainer("jpg");
+ format = new WEB();
+ format.match("http://test.org/");
+ format.setType(Format.IMAGE);
+ assertEquals("isCompatible() reporting different outcome than ps3compatible() for WEB image",
+ format.ps3compatible(), conf.isCompatible(info, format));
+
+ // WEB: type=VIDEO
+ info = new DLNAMediaInfo();
+ info.setContainer("avi");
+ format.setType(Format.VIDEO);
+ assertEquals("isCompatible() reporting different outcome than ps3compatible() for WEB video",
+ format.ps3compatible(), conf.isCompatible(info, format));
+
+ }
+}
View
110 src/test/java/net/pms/test/formats/FormatTest.java
@@ -0,0 +1,110 @@
+/*
+ * 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.test.formats;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.ArrayList;
+
+import net.pms.configuration.RendererConfiguration;
+import net.pms.dlna.DLNAMediaAudio;
+import net.pms.dlna.DLNAMediaInfo;
+import net.pms.formats.DVRMS;
+import net.pms.formats.FLAC;
+import net.pms.formats.Format;
+import net.pms.formats.GIF;
+import net.pms.formats.ISO;
+import net.pms.formats.JPG;
+import net.pms.formats.M4A;
+import net.pms.formats.MKV;
+import net.pms.formats.MP3;
+import net.pms.formats.MPG;
+import net.pms.formats.OGG;
+import net.pms.formats.PNG;
+import net.pms.formats.RAW;
+import net.pms.formats.TIF;
+import net.pms.formats.WAV;
+import net.pms.formats.WEB;
+import net.pms.network.HTTPResource;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.LoggerFactory;
+
+import ch.qos.logback.classic.LoggerContext;
+
+
+/**
+ * Test basic functionality of {@link Format}.
+ */
+public class FormatTest {
+ @Before
+ public void setUp() {
+ // Silence all log messages from the PMS code that is being tested
+ LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
+ context.reset();
+ }
+
+ /**
+ * Test edge cases for {@link Format#match(String)}.
+ */
+ @Test
+ public void testFormatEdgeCases() {
+ // Empty string
+ assertEquals("MP3 matches \"\"", false, new MP3().match(""));
+
+ // Null string
+ assertEquals("MP3 matches null", false, new MP3().match(null));
+
+ // Mixed case
+ assertEquals("TIFF does not match \"tEsT.TiFf\"", true, new TIF().match("tEsT.TiFf"));
+
+ // Starting with identifier instead of ending
+ assertEquals("TIFF matches \"tiff.test\"", false, new TIF().match("tiff.test"));
+
+ // Substring
+ assertEquals("TIFF matches \"not.tiff.but.mp3\"", false, new TIF().match("not.tiff.but.mp3"));
+ }
+
+ /**
+ * Test if {@link Format#match(String)} manages to match the identifiers
+ * specified in each format with getId().
+ */
+ @Test
+ public void testFormatIdentifiers() {
+ // Identifier tests based on the identifiers defined in getId() of each class
+ assertEquals("DVRMS does not match \"test.dvr\"", true, new DVRMS().match("test.dvr"));
@chocolateboy Owner

"Does not match"? Shouldn't these read e.g. "GIF matches 'test.gif'"?

@Raptor399 Owner

I don't know what the convention is for these messages.
I noticed they were printed upon failure, so I decided to help the person watching the output by outlining the error, as if it were a log message. A failing test will now print this:

Results :

Failed tests:   testFormatIdentifiers(net.pms.test.formats.FormatTest): GIF does not match "test.gif" expected:<false> but was:<true>

Tests run: 15, Failures: 1, Errors: 0, Skipped: 0

If the convention is to describe the assertion instead of the failure, all messages in all my tests will need to be negated.

@chocolateboy Owner

The convention is to describe the expected behaviour.

@Raptor399 Owner

Ah, okay. I'll correct all messages then.
Thanks for filling me in!

@chocolateboy Owner

Unfortunately, it's not clearly specced in the documentation or in practice, which is one of the many reasons why I hate JUnit :-) Either way, "GIF should match 'test.gif'" &c. should be clearer to read in both the test output and - more importantly - the test code than "GIF does not match 'test.gif'" &c.

@Raptor399 Owner

Updates committed in c81e01f.

@chocolateboy Owner

Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ assertEquals("FLAC does not match \"test.flac\"", true, new FLAC().match("test.flac"));
+ assertEquals("GIF does not match \"test.gif\"", true, new GIF().match("test.gif"));
+ assertEquals("ISO does not match \"test.iso\"", true, new ISO().match("test.iso"));
+ assertEquals("JPG does not match \"test.jpg\"", true, new JPG().match("test.jpg"));
+ assertEquals("M4A does not match \"test.wma\"", true, new M4A().match("test.wma"));
+ assertEquals("MKV does not match \"test.mkv\"", true, new MKV().match("test.mkv"));
+ assertEquals("MP3 does not match \"test.mp3\"", true, new MP3().match("test.mp3"));
+ assertEquals("MPG does not match \"test.mpg\"", true, new MPG().match("test.mpg"));
+ assertEquals("OGG does not match \"test.ogg\"", true, new OGG().match("test.ogg"));
+ assertEquals("PNG does not match \"test.png\"", true, new PNG().match("test.png"));
+ assertEquals("RAW does not match \"test.arw\"", true, new RAW().match("test.arw"));
+ assertEquals("TIF does not match \"test.tiff\"", true, new TIF().match("test.tiff"));
+ assertEquals("WAV does not match \"test.wav\"", true, new WAV().match("test.wav"));
+ assertEquals("WEB does not match \"http\"", true, new WEB().match("http://test.org/"));
+ }
+}

2 comments on commit c761b08

@Raptor399
Owner

This commit introduces a regression where selecting a VirtualVideoAction results in a "Corrupted data" message.

When the VirtualVideoAction child is added in DLNAResource, the logic decides to have MEncoder assigned as player of choice. However, VirtualVideoAction comes with an MPEG movie which is supposed to be streamed instead of transcoded.

@Raptor399
Owner

Fix for the regression committed in 9630b99.

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