From 7d17f11175a52e663e76f5d732e207f0641e860a Mon Sep 17 00:00:00 2001 From: Andrew Brampton Date: Wed, 20 Mar 2024 10:39:17 -0700 Subject: [PATCH] Add support for parsing all the codec flags * Add support for parsing all the codec flags, e.g IntraFrameOnly, Lossy and Lossless. --- .../java/net/bramp/ffmpeg/info/Codec.java | 59 ++++++++++++- .../java/net/bramp/ffmpeg/info/CodecTest.java | 82 +++++++++++++++++++ 2 files changed, 137 insertions(+), 4 deletions(-) create mode 100644 src/test/java/net/bramp/ffmpeg/info/CodecTest.java diff --git a/src/main/java/net/bramp/ffmpeg/info/Codec.java b/src/main/java/net/bramp/ffmpeg/info/Codec.java index 6f41f45a..3b244c02 100644 --- a/src/main/java/net/bramp/ffmpeg/info/Codec.java +++ b/src/main/java/net/bramp/ffmpeg/info/Codec.java @@ -25,6 +25,15 @@ public class Codec { /** What type of codec is this */ private final CodecType type; + /** Intra frame only codec */ + final boolean intraFrameOnly; + + /** Codec supports lossy compression */ + final boolean lossyCompression; + + /** Codeco supports lessless compression */ + final boolean losslessCompression; + /** * @param name short codec name * @param longName long codec name @@ -35,6 +44,8 @@ public class Codec { * ..V... = Video codec * ..A... = Audio codec * ..S... = Subtitle codec + * ..D... = Data codec + * ..T... = Attachment codec * ...I.. = Intra frame-only codec * ....L. = Lossy compression * .....S = Lossless compression @@ -45,9 +56,19 @@ public Codec(String name, String longName, String flags) { this.longName = Preconditions.checkNotNull(longName).trim(); Preconditions.checkNotNull(flags); - Preconditions.checkArgument(flags.length() == 6, "Format flags is invalid '%s'", flags); - this.canDecode = flags.charAt(0) == 'D'; - this.canEncode = flags.charAt(1) == 'E'; + Preconditions.checkArgument(flags.length() == 6, "Codec flags is invalid '%s'", flags); + + switch (flags.charAt(0)) { + case 'D': this.canDecode = true; break; + case '.': this.canDecode = false; break; + default: throw new IllegalArgumentException("Invalid decoding value '" + flags.charAt(0) + "'"); + } + + switch (flags.charAt(1)) { + case 'E': this.canEncode = true; break; + case '.': this.canEncode = false; break; + default: throw new IllegalArgumentException("Invalid encoding value '" + flags.charAt(1) + "'"); + } switch (flags.charAt(2)) { case 'V': @@ -69,7 +90,24 @@ public Codec(String name, String longName, String flags) { throw new IllegalArgumentException("Invalid codec type '" + flags.charAt(2) + "'"); } - // TODO There are more flags to parse + switch (flags.charAt(3)) { + case 'I': this.intraFrameOnly = true; break; + case '.': this.intraFrameOnly = false; break; + default: throw new IllegalArgumentException("Invalid encoding value '" + flags.charAt(3) + "'"); + } + + switch (flags.charAt(4)) { + case 'L': this.lossyCompression = true; break; + case '.': this.lossyCompression = false; break; + default: throw new IllegalArgumentException("Invalid lossy compression value '" + flags.charAt(4) + "'"); + } + + switch (flags.charAt(5)) { + case 'S': this.losslessCompression = true; break; + case '.': this.losslessCompression = false; break; + default: throw new IllegalArgumentException("Invalid lossless compression value '" + flags.charAt(5) + "'"); + } + } @Override @@ -106,4 +144,17 @@ public boolean getCanEncode() { public CodecType getType() { return type; } + + public boolean isIntraFrameOnly() { + return intraFrameOnly; + } + + public boolean supportsLossyCompression() { + return lossyCompression; + } + + public boolean supportsLosslessCompression() { + return losslessCompression; + } + } diff --git a/src/test/java/net/bramp/ffmpeg/info/CodecTest.java b/src/test/java/net/bramp/ffmpeg/info/CodecTest.java new file mode 100644 index 00000000..428087c9 --- /dev/null +++ b/src/test/java/net/bramp/ffmpeg/info/CodecTest.java @@ -0,0 +1,82 @@ +package net.bramp.ffmpeg.info; + +import static org.hamcrest.Matchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.Test; + +import net.bramp.ffmpeg.shared.CodecType; + +public class CodecTest { + @Test + public void testCodecConstructor() { + Codec c1 = new Codec("012v", "Uncompressed 4:2:2 10-bit", "D.VI.S"); + assertThat(c1.getName(), is("012v")); + assertThat(c1.getLongName(), is("Uncompressed 4:2:2 10-bit")); + assertThat(c1.getCanDecode(), is(true)); + assertThat(c1.getCanEncode(), is(false)); + assertThat(c1.getType(), is(CodecType.VIDEO)); + assertThat(c1.isIntraFrameOnly(), is(true)); + assertThat(c1.supportsLossyCompression(), is(false)); + assertThat(c1.losslessCompression, is(true)); + + Codec c2 = new Codec("4xm", "4X Movie", "D.V.L."); + assertThat(c2.getName(), is("4xm")); + assertThat(c2.getLongName(), is("4X Movie")); + assertThat(c2.getCanDecode(), is(true)); + assertThat(c2.getCanEncode(), is(false)); + assertThat(c2.getType(), is(CodecType.VIDEO)); + assertThat(c2.isIntraFrameOnly(), is(false)); + assertThat(c2.supportsLossyCompression(), is(true)); + assertThat(c2.supportsLosslessCompression(), is(false)); + + Codec c3 = new Codec("alias_pix", "Alias/Wavefront PIX image", "DEVI.S"); + assertThat(c3.getName(), is("alias_pix")); + assertThat(c3.getLongName(), is("Alias/Wavefront PIX image")); + assertThat(c3.getCanDecode(), is(true)); + assertThat(c3.getCanEncode(), is(true)); + assertThat(c3.getType(), is(CodecType.VIDEO)); + assertThat(c3.isIntraFrameOnly(), is(true)); + assertThat(c3.supportsLossyCompression(), is(false)); + assertThat(c3.supportsLosslessCompression(), is(true)); + + Codec c4 = new Codec("binkaudio_rdft", "Bink Audio (RDFT)", "D.AIL."); + assertThat(c4.getType(), is(CodecType.AUDIO)); + + Codec c6 = new Codec("mov_text", "MOV text", "DES..."); + assertThat(c6.getType(), is(CodecType.SUBTITLE)); + + Codec c7 = new Codec("bin_data", "binary data", "..D..."); + assertThat(c7.getType(), is(CodecType.DATA)); + } + + @Test(expected = IllegalArgumentException.class) + public void testBadDecodeValue() { + new Codec("test", "test", "X.V..."); + } + + @Test(expected = IllegalArgumentException.class) + public void testBadEncodeValue() { + new Codec("test", "test", ".XV..."); + } + + @Test(expected = IllegalArgumentException.class) + public void testBadCodecValue() { + new Codec("test", "test", "..X..."); + } + + @Test(expected = IllegalArgumentException.class) + public void testBadIntraFrameOnlyValue() { + new Codec("test", "test", "..VX.."); + } + + @Test(expected = IllegalArgumentException.class) + public void testBadLossyValue() { + new Codec("test", "test", "..V.X."); + } + + @Test(expected = IllegalArgumentException.class) + public void testBadLosslessValue() { + new Codec("test", "test", "..V..X"); + } +}