001package net.bramp.ffmpeg.info; 002 003import com.google.common.base.Preconditions; 004import com.google.errorprone.annotations.Immutable; 005import net.bramp.ffmpeg.shared.CodecType; 006import org.apache.commons.lang3.builder.EqualsBuilder; 007import org.apache.commons.lang3.builder.HashCodeBuilder; 008 009/** 010 * Information about supported Codecs. 011 * 012 * @author bramp 013 */ 014@Immutable 015public class Codec { 016 private final String name; 017 private final String longName; 018 019 /** Can I decode with this codec. */ 020 private final boolean canDecode; 021 022 /** Can I encode with this codec. */ 023 private final boolean canEncode; 024 025 /** What type of codec is this. */ 026 private final CodecType type; 027 028 /** Intra frame only codec. */ 029 final boolean intraFrameOnly; 030 031 /** Codec supports lossy compression. */ 032 final boolean lossyCompression; 033 034 /** Codeco supports lessless compression. */ 035 final boolean losslessCompression; 036 037 /** 038 * Creates a new Codec. 039 * 040 * @param name short codec name 041 * @param longName long codec name 042 * @param flags is expected to be in the following format: 043 * <pre> 044 * D..... = Decoding supported 045 * .E.... = Encoding supported 046 * ..V... = Video codec 047 * ..A... = Audio codec 048 * ..S... = Subtitle codec 049 * ..D... = Data codec 050 * ..T... = Attachment codec 051 * ...I.. = Intra frame-only codec 052 * ....L. = Lossy compression 053 * .....S = Lossless compression 054 * </pre> 055 */ 056 public Codec(String name, String longName, String flags) { 057 this.name = Preconditions.checkNotNull(name).trim(); 058 this.longName = Preconditions.checkNotNull(longName).trim(); 059 060 Preconditions.checkNotNull(flags); 061 Preconditions.checkArgument(flags.length() == 6, "Codec flags is invalid '%s'", flags); 062 063 switch (flags.charAt(0)) { 064 case 'D': 065 this.canDecode = true; 066 break; 067 case '.': 068 this.canDecode = false; 069 break; 070 default: 071 throw new IllegalArgumentException("Invalid decoding value '" + flags.charAt(0) + "'"); 072 } 073 074 switch (flags.charAt(1)) { 075 case 'E': 076 this.canEncode = true; 077 break; 078 case '.': 079 this.canEncode = false; 080 break; 081 default: 082 throw new IllegalArgumentException("Invalid encoding value '" + flags.charAt(1) + "'"); 083 } 084 085 switch (flags.charAt(2)) { 086 case 'V': 087 this.type = CodecType.VIDEO; 088 break; 089 case 'A': 090 this.type = CodecType.AUDIO; 091 break; 092 case 'S': 093 this.type = CodecType.SUBTITLE; 094 break; 095 case 'D': 096 this.type = CodecType.DATA; 097 break; 098 case 'T': 099 this.type = CodecType.ATTACHMENT; 100 break; 101 default: 102 throw new IllegalArgumentException("Invalid codec type '" + flags.charAt(2) + "'"); 103 } 104 105 switch (flags.charAt(3)) { 106 case 'I': 107 this.intraFrameOnly = true; 108 break; 109 case '.': 110 this.intraFrameOnly = false; 111 break; 112 default: 113 throw new IllegalArgumentException("Invalid encoding value '" + flags.charAt(3) + "'"); 114 } 115 116 switch (flags.charAt(4)) { 117 case 'L': 118 this.lossyCompression = true; 119 break; 120 case '.': 121 this.lossyCompression = false; 122 break; 123 default: 124 throw new IllegalArgumentException( 125 "Invalid lossy compression value '" + flags.charAt(4) + "'"); 126 } 127 128 switch (flags.charAt(5)) { 129 case 'S': 130 this.losslessCompression = true; 131 break; 132 case '.': 133 this.losslessCompression = false; 134 break; 135 default: 136 throw new IllegalArgumentException( 137 "Invalid lossless compression value '" + flags.charAt(5) + "'"); 138 } 139 } 140 141 @Override 142 public String toString() { 143 return name + " " + longName; 144 } 145 146 @Override 147 public boolean equals(Object obj) { 148 return EqualsBuilder.reflectionEquals(this, obj); 149 } 150 151 @Override 152 public int hashCode() { 153 return HashCodeBuilder.reflectionHashCode(this); 154 } 155 156 public String getName() { 157 return name; 158 } 159 160 public String getLongName() { 161 return longName; 162 } 163 164 public boolean getCanDecode() { 165 return canDecode; 166 } 167 168 public boolean getCanEncode() { 169 return canEncode; 170 } 171 172 public CodecType getType() { 173 return type; 174 } 175 176 public boolean isIntraFrameOnly() { 177 return intraFrameOnly; 178 } 179 180 /** Returns whether this codec supports lossy compression. */ 181 public boolean supportsLossyCompression() { 182 return lossyCompression; 183 } 184 185 /** Returns whether this codec supports lossless compression. */ 186 public boolean supportsLosslessCompression() { 187 return losslessCompression; 188 } 189}