www in docker support
This commit is contained in:
parent
539a848e95
commit
c227fce036
2145 changed files with 399596 additions and 58 deletions
|
|
@ -0,0 +1,239 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.jcodec.codecs.aac.AACDecoder;
|
||||
import org.jcodec.codecs.h264.BufferH264ES;
|
||||
import org.jcodec.codecs.h264.H264Decoder;
|
||||
import org.jcodec.codecs.mjpeg.JpegDecoder;
|
||||
import org.jcodec.codecs.mpeg12.MPEGDecoder;
|
||||
import org.jcodec.codecs.mpeg4.MPEG4Decoder;
|
||||
import org.jcodec.codecs.ppm.PPMEncoder;
|
||||
import org.jcodec.codecs.prores.ProresDecoder;
|
||||
import org.jcodec.codecs.vpx.VP8Decoder;
|
||||
import org.jcodec.codecs.wav.WavDemuxer;
|
||||
import org.jcodec.common.io.FileChannelWrapper;
|
||||
import org.jcodec.common.io.NIOUtils;
|
||||
import org.jcodec.common.logging.Logger;
|
||||
import org.jcodec.common.model.ColorSpace;
|
||||
import org.jcodec.common.model.Picture;
|
||||
import org.jcodec.common.tools.MathUtil;
|
||||
import org.jcodec.containers.imgseq.ImageSequenceDemuxer;
|
||||
import org.jcodec.containers.mkv.demuxer.MKVDemuxer;
|
||||
import org.jcodec.containers.mp3.MPEGAudioDemuxer;
|
||||
import org.jcodec.containers.mp4.demuxer.MP4Demuxer;
|
||||
import org.jcodec.containers.mps.MPSDemuxer;
|
||||
import org.jcodec.containers.mps.MTSDemuxer;
|
||||
import org.jcodec.containers.webp.WebpDemuxer;
|
||||
import org.jcodec.containers.y4m.Y4MDemuxer;
|
||||
import org.jcodec.platform.Platform;
|
||||
import org.jcodec.scale.ColorUtil;
|
||||
import org.jcodec.scale.Transform;
|
||||
|
||||
public class JCodecUtil {
|
||||
private static final Map<Codec, Class<?>> decoders = new HashMap<>();
|
||||
|
||||
private static final Map<Format, Class<?>> demuxers = new HashMap<>();
|
||||
|
||||
static {
|
||||
decoders.put(Codec.VP8, VP8Decoder.class);
|
||||
decoders.put(Codec.PRORES, ProresDecoder.class);
|
||||
decoders.put(Codec.MPEG2, MPEGDecoder.class);
|
||||
decoders.put(Codec.H264, H264Decoder.class);
|
||||
decoders.put(Codec.AAC, AACDecoder.class);
|
||||
decoders.put(Codec.MPEG4, MPEG4Decoder.class);
|
||||
demuxers.put(Format.MPEG_TS, MTSDemuxer.class);
|
||||
demuxers.put(Format.MPEG_PS, MPSDemuxer.class);
|
||||
demuxers.put(Format.MOV, MP4Demuxer.class);
|
||||
demuxers.put(Format.WEBP, WebpDemuxer.class);
|
||||
demuxers.put(Format.MPEG_AUDIO, MPEGAudioDemuxer.class);
|
||||
}
|
||||
|
||||
public static Format detectFormat(File f) throws IOException {
|
||||
return detectFormatBuffer(NIOUtils.fetchFromFileL(f, 204800));
|
||||
}
|
||||
|
||||
public static Format detectFormatChannel(ReadableByteChannel f) throws IOException {
|
||||
return detectFormatBuffer(NIOUtils.fetchFromChannel(f, 204800));
|
||||
}
|
||||
|
||||
public static Format detectFormatBuffer(ByteBuffer b) {
|
||||
int maxScore = 0;
|
||||
Format selected = null;
|
||||
for (Map.Entry<Format, Class<?>> vd : demuxers.entrySet()) {
|
||||
int score = probe(b.duplicate(), vd.getValue());
|
||||
if (score > maxScore) {
|
||||
selected = vd.getKey();
|
||||
maxScore = score;
|
||||
}
|
||||
}
|
||||
return selected;
|
||||
}
|
||||
|
||||
public static Codec detectDecoder(ByteBuffer b) {
|
||||
int maxScore = 0;
|
||||
Codec selected = null;
|
||||
for (Map.Entry<Codec, Class<?>> vd : decoders.entrySet()) {
|
||||
int score = probe(b.duplicate(), vd.getValue());
|
||||
if (score > maxScore) {
|
||||
selected = vd.getKey();
|
||||
maxScore = score;
|
||||
}
|
||||
}
|
||||
return selected;
|
||||
}
|
||||
|
||||
private static int probe(ByteBuffer b, Class<?> vd) {
|
||||
try {
|
||||
return Platform.invokeStaticMethod(vd, "probe", new Object[] { b });
|
||||
} catch (Exception e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static VideoDecoder getVideoDecoder(String fourcc) {
|
||||
if ("apch".equals(fourcc) || "apcs".equals(fourcc) || "apco".equals(fourcc) || "apcn".equals(fourcc) || "ap4h"
|
||||
.equals(fourcc))
|
||||
return new ProresDecoder();
|
||||
if ("m2v1".equals(fourcc))
|
||||
return new MPEGDecoder();
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void savePictureAsPPM(Picture pic, File file) throws IOException {
|
||||
Transform transform = ColorUtil.getTransform(pic.getColor(), ColorSpace.RGB);
|
||||
Picture rgb = Picture.create(pic.getWidth(), pic.getHeight(), ColorSpace.RGB);
|
||||
transform.transform(pic, rgb);
|
||||
NIOUtils.writeTo(new PPMEncoder().encodeFrame(rgb), file);
|
||||
}
|
||||
|
||||
public static byte[] asciiString(String fourcc) {
|
||||
char[] ch = fourcc.toCharArray();
|
||||
byte[] result = new byte[ch.length];
|
||||
for (int i = 0; i < ch.length; i++)
|
||||
result[i] = (byte)ch[i];
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void writeBER32(ByteBuffer buffer, int value) {
|
||||
buffer.put((byte)(value >> 21 | 0x80));
|
||||
buffer.put((byte)(value >> 14 | 0x80));
|
||||
buffer.put((byte)(value >> 7 | 0x80));
|
||||
buffer.put((byte)(value & 0x7F));
|
||||
}
|
||||
|
||||
public static void writeBER32Var(ByteBuffer bb, int value) {
|
||||
for (int i = 0, bits = MathUtil.log2(value); i < 4 && bits > 0; i++) {
|
||||
bits -= 7;
|
||||
int out = value >> bits;
|
||||
if (bits > 0)
|
||||
out |= 0x80;
|
||||
bb.put((byte)out);
|
||||
}
|
||||
}
|
||||
|
||||
public static int readBER32(ByteBuffer input) {
|
||||
int size = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
byte b = input.get();
|
||||
size = size << 7 | b & Byte.MAX_VALUE;
|
||||
if ((b & 0xFF) >> 7 == 0)
|
||||
break;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
public static int[] getAsIntArray(ByteBuffer yuv, int size) {
|
||||
byte[] b = new byte[size];
|
||||
int[] result = new int[size];
|
||||
yuv.get(b);
|
||||
for (int i = 0; i < b.length; i++)
|
||||
result[i] = b[i] & 0xFF;
|
||||
return result;
|
||||
}
|
||||
|
||||
public static String removeExtension(String name) {
|
||||
if (name == null)
|
||||
return null;
|
||||
return name.replaceAll("\\.[^\\.]+$", "");
|
||||
}
|
||||
|
||||
public static Demuxer createDemuxer(Format format, File input) throws IOException {
|
||||
FileChannelWrapper ch = null;
|
||||
if (format != Format.IMG)
|
||||
ch = NIOUtils.readableChannel(input);
|
||||
if (Format.MOV == format)
|
||||
return MP4Demuxer.createMP4Demuxer(ch);
|
||||
if (Format.MPEG_PS == format)
|
||||
return new MPSDemuxer(ch);
|
||||
if (Format.MKV == format)
|
||||
return new MKVDemuxer(ch);
|
||||
if (Format.IMG == format)
|
||||
return new ImageSequenceDemuxer(input.getAbsolutePath(), Integer.MAX_VALUE);
|
||||
if (Format.Y4M == format)
|
||||
return new Y4MDemuxer(ch);
|
||||
if (Format.WEBP == format)
|
||||
return new WebpDemuxer(ch);
|
||||
if (Format.H264 == format)
|
||||
return new BufferH264ES(NIOUtils.fetchAllFromChannel(ch));
|
||||
if (Format.WAV == format)
|
||||
return new WavDemuxer(ch);
|
||||
if (Format.MPEG_AUDIO == format)
|
||||
return new MPEGAudioDemuxer(ch);
|
||||
Logger.error("Format " + String.valueOf(format) + " is not supported");
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Tuple._2<Integer, Demuxer> createM2TSDemuxer(File input, TrackType targetTrack) throws IOException {
|
||||
FileChannelWrapper ch = NIOUtils.readableChannel(input);
|
||||
MTSDemuxer mts = new MTSDemuxer(ch);
|
||||
Set<Integer> programs = mts.getPrograms();
|
||||
if (programs.size() == 0) {
|
||||
Logger.error("The MPEG TS stream contains no programs");
|
||||
return null;
|
||||
}
|
||||
Tuple._2<Integer, Demuxer> found = null;
|
||||
for (Integer pid : programs) {
|
||||
ReadableByteChannel program = mts.getProgram(pid.intValue());
|
||||
if (found != null) {
|
||||
program.close();
|
||||
continue;
|
||||
}
|
||||
MPSDemuxer demuxer = new MPSDemuxer(program);
|
||||
if ((targetTrack == TrackType.AUDIO && demuxer.getAudioTracks().size() > 0) || (targetTrack == TrackType.VIDEO &&
|
||||
demuxer.getVideoTracks().size() > 0)) {
|
||||
found = Tuple.pair(pid, demuxer);
|
||||
Logger.info("Using M2TS program: " + pid + " for " + String.valueOf(targetTrack) + " track.");
|
||||
continue;
|
||||
}
|
||||
program.close();
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
public static AudioDecoder createAudioDecoder(Codec codec, ByteBuffer decoderSpecific) throws IOException {
|
||||
if (Codec.AAC == codec)
|
||||
return new AACDecoder(decoderSpecific);
|
||||
Logger.error("Codec " + String.valueOf(codec) + " is not supported");
|
||||
return null;
|
||||
}
|
||||
|
||||
public static VideoDecoder createVideoDecoder(Codec codec, ByteBuffer decoderSpecific) {
|
||||
if (Codec.H264 == codec)
|
||||
return (decoderSpecific != null) ? H264Decoder.createH264DecoderFromCodecPrivate(decoderSpecific) :
|
||||
new H264Decoder();
|
||||
if (Codec.MPEG2 == codec)
|
||||
return new MPEGDecoder();
|
||||
if (Codec.VP8 == codec)
|
||||
return new VP8Decoder();
|
||||
if (Codec.JPEG == codec)
|
||||
return new JpegDecoder();
|
||||
Logger.error("Codec " + String.valueOf(codec) + " is not supported");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue