/* * Copyright (c) 2011 Michael Zucchi * * This file is part of jjmpeg, a java binding to ffmpeg's libraries. * * jjmpeg is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * jjmpeg 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with jjmpeg. If not, see <http://www.gnu.org/licenses/>. */ package au.notzed.jjmpeg; import java.nio.Buffer; import java.nio.ByteBuffer; class AVSamplesNative extends AVNative { public AVSamplesNative(AVObject jobject, ByteBuffer p) { super(jobject, p); } @Override public void dispose() { if (p != null) { super.dispose(); _free(p); } } } /** * Holder for audio samples memory, which has some specific memory * allocation requirements. * @author notzed */ public class AVSamples extends AVObject { final SampleFormat format; Buffer samples; public AVSamples(SampleFormat format) { setNative(new AVSamplesNative(this, AVNative._malloc(AVCodecContext.AVCODEC_MAX_AUDIO_FRAME_SIZE * 2))); this.format = format; samples = format.getBuffer(n.p); } public AVSamples(SampleFormat format, int channels, int frameSize) { setNative(new AVSamplesNative(this, AVNative._malloc(format.getByteSize() * channels * frameSize))); this.format = format; samples = format.getBuffer(n.p); } public ByteBuffer getBuffer() { return n.p; } public Buffer getSamples() { return samples; } public SampleFormat getFormat() { return format; } /** * Drain the samples from src into this. * * This is called repeatedly to create full sample buffers for * encoding. * * @param src * @return true if this is now full and can be encoded. It also * means src may not be fully drained, and so should be called again. */ public boolean fill(AVSamples src) { /* * You know, sometimes when you try to write a fairly simple bit * of code using an existing api you have to wonder: * just what the fuck were they thinking? */ ByteBuffer obuf = getBuffer(); ByteBuffer sbuf = src.getBuffer(); int dremaining = obuf.capacity() - obuf.position(); int sremaining = sbuf.remaining(); if (sremaining > 0) { ByteBuffer ssbuf = sbuf.slice(); int len = Math.min(sremaining, dremaining); ssbuf.limit(ssbuf.position() + len); sbuf.position(sbuf.position() + len); obuf.put(ssbuf); if (!obuf.hasRemaining()) { obuf.rewind(); obuf.limit(obuf.capacity()); return true; } } return false; } /** * Pad out the rest of the buffer with 0. */ public void pad() { ByteBuffer obuf = getBuffer(); for (int i = obuf.position(); i < obuf.capacity(); i++) { obuf.put(i, (byte) 0); } } }