package org.jcodec.codecs.aac; import java.io.IOException; import java.nio.ByteBuffer; import org.jcodec.codecs.aac.ADTSParser.Header; import org.jcodec.common.AudioCodecMeta; import org.jcodec.common.AudioDecoder; import org.jcodec.common.AudioFormat; import org.jcodec.common.io.NIOUtils; import org.jcodec.common.logging.Logger; import org.jcodec.common.model.AudioBuffer; import net.sourceforge.jaad.aac.AACException; import net.sourceforge.jaad.aac.Decoder; import net.sourceforge.jaad.aac.SampleBuffer; /** * This class is part of JCodec ( www.jcodec.org ) This software is distributed * under FreeBSD License * * Wraps around the JAAD decoder and implements an AudioDecoder interface. * * @author Stanislav Vitvitskyy */ public class AACDecoder implements AudioDecoder { private Decoder decoder; public AACDecoder(ByteBuffer decoderSpecific) throws AACException { if (decoderSpecific.remaining() >= 7) { Header header = ADTSParser.read(decoderSpecific); if (header != null) { decoderSpecific = AACUtils.adtsToStreamInfo(header); } Logger.info("Creating AAC decoder from ADTS header."); } decoder = new Decoder(NIOUtils.toArray(decoderSpecific)); } @Override public AudioBuffer decodeFrame(ByteBuffer frame, ByteBuffer dst) throws IOException { // Internally all AAC streams are ADTS wrapped ADTSParser.read(frame); SampleBuffer sampleBuffer = new SampleBuffer(); decoder.decodeFrame(NIOUtils.toArray(frame), sampleBuffer); if (sampleBuffer.isBigEndian()) { // Not a simple setter! This will also swap the order of bytes inside the buffer. sampleBuffer.setBigEndian(false); } return new AudioBuffer(ByteBuffer.wrap(sampleBuffer.getData()), toAudioFormat(sampleBuffer), 0); } private AudioFormat toAudioFormat(SampleBuffer sampleBuffer) { return new AudioFormat(sampleBuffer.getSampleRate(), sampleBuffer.getBitsPerSample(), sampleBuffer.getChannels(), true, sampleBuffer.isBigEndian()); } @Override public AudioCodecMeta getCodecMeta(ByteBuffer data) throws IOException { SampleBuffer sampleBuffer = new SampleBuffer(); decoder.decodeFrame(NIOUtils.toArray(data), sampleBuffer); sampleBuffer.setBigEndian(false); return new AudioCodecMeta(toAudioFormat(sampleBuffer)); } public static int probe(ByteBuffer data) { if (data.remaining() < 7) return 0; Header header = ADTSParser.read(data); if (header != null) return 100; return 0; } }