All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.libav.avcodec.CodecContextWrapper53 Maven / Gradle / Ivy

There is a newer version: 0.2.1
Show newest version
/*
 * Copyright (C) 2012 Ondrej Perutka
 *
 * This program 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.
 *
 * This library 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 this library. If not, see 
 * .
 */
package org.libav.avcodec;

import org.bridj.Pointer;
import org.libav.LibavException;
import org.libav.avcodec.bridge.AVCodecContext53;
import org.libav.avcodec.bridge.AVCodecLibrary;
import org.libav.avutil.bridge.AVSampleFormat;
import org.libav.avutil.bridge.AVUtilLibrary;
import org.libav.bridge.LibraryManager;
import org.libav.util.Rational;

/**
 * Wrapper class for the AVCodecContext53.
 * 
 * @author Ondrej Perutka
 */
public class CodecContextWrapper53 extends AbstractCodecContextWrapper {
    
    private static final AVCodecLibrary codecLib;
    
    private static final boolean avcOpen2;
    private static final boolean avcDecodeAudio4;
    private static final boolean avcEncodeAudio2;
    
    static {
        codecLib = LibraryManager.getInstance().getAVCodecLibrary();
        
        avcOpen2 = codecLib.functionExists("avcodec_open2");
        avcDecodeAudio4 = codecLib.functionExists("avcodec_decode_audio4");
        avcEncodeAudio2 = codecLib.functionExists("avcodec_encode_audio2");
    }
    
    private AVCodecContext53 context;
    
    private Pointer intByRef;
    private IDecodeAudioFunction decodeAudioFunction;
    private IEncodeAudioFunction encodeAudioFunction;
    
    /**
     * Create a new wrapper for the given AVCodecContext.
     * 
     * @param context a codec context structure
     */
    public CodecContextWrapper53(AVCodecContext53 context) {
        this.context = context;
        
        this.intByRef = Pointer.allocateInt();
        
        if (avcDecodeAudio4)
            this.decodeAudioFunction = new DecodeAudio4();
        else
            this.decodeAudioFunction = new DecodeAudio3();
        
        if (avcEncodeAudio2)
            this.encodeAudioFunction = new EncodeAudio2();
        else
            this.encodeAudioFunction = new EncodeAudio();
    }
    
    @Override
    public Pointer getPointer() {
        if (context == null)
            return null;
        
        return Pointer.pointerTo(context);
    }
    
    @Override
    public void open(ICodecWrapper codec) throws LibavException {
        if (this.codec != null)
            close();
        
        int result;
        if (avcOpen2)
            result = codecLib.avcodec_open2(getPointer(), codec.getPointer(), null);
        else
            result = codecLib.avcodec_open(getPointer(), codec.getPointer());
        
        if(result < 0)
            throw new LibavException(result);
        
        this.codec = codec;
    }
    
    @Override
    public void close() {
        if (isClosed())
            return;
        
        codecLib.avcodec_close(getPointer());
        codec = null;
    }
    
    @Override
    public void free() {
        close();
        
        if (context == null)
            return;
        
        AVUtilLibrary lib = LibraryManager.getInstance().getAVUtilLibrary();
        lib.av_free(getPointer());
        context = null;
    }
    
    @Override
    public boolean isClosed() {
        return codec == null;
    }
    
    @Override
    public IFrameWrapper getCodedFrame() {
        if (context == null)
            return null;
        
        if (codedFrame == null) {
            Pointer p = context.coded_frame();
            codedFrame = p == null ? null : FrameWrapperFactory.getInstance().wrap(p);
        }
        
        return codedFrame;
    }
    
    @Override
    public int getCodecType() {
        if (context == null)
            return 0;
        
        if (codecType == null)
            codecType = context.codec_type();
        
        return codecType;
    }
    
    @Override
    public void setCodecType(int codecType) {
        if (context == null)
            return;
        
        context.codec_type(codecType);
        this.codecType = codecType;
    }
    
    @Override
    public int getCodecId() {
        if (context == null)
            return 0;
        
        if (codecId == null)
            codecId = context.codec_id();
        
        return codecId;
    }
    
    @Override
    public void setCodecId(int codecId) {
        if (context == null)
            return;
        
        context.codec_id(codecId);
        this.codecId = codecId;
    }
    
    @Override
    public int getFlags() {
        if (context == null)
            return 0;
        
        if (flags == null)
            flags = context.flags();
        
        return flags;
    }
    
    @Override
    public void setFlags(int flags) {
        if (context == null)
            return;
        
        context.flags(flags);
        this.flags = flags;
    }
    
    @Override
    public int getWidth() {
        if (context == null)
            return 0;
        
        if (width == null)
            width = context.width();
        
        return width;
    }
    
    @Override
    public void setWidth(int width) {
        if (context == null)
            return;
        
        context.width(width);
        this.width = width;
    }
    
    @Override
    public int getHeight() {
        if (context == null)
            return 0;
        
        if (height == null)
            height = context.height();
        
        return height;
    }
    
    @Override
    public void setHeight(int height) {
        if (context == null)
            return;
        
        context.height(height);
        this.height = height;
    }
    
    @Override
    public int getPixelFormat() {
        if (context == null)
            return 0;
        
        if (pixelFormat == null)
            pixelFormat = context.pix_fmt();
        
        return pixelFormat;
    }
    
    @Override
    public void setPixelFormat(int pixelFormat) {
        if (context == null)
            return;
        
        context.pix_fmt(pixelFormat);
        this.pixelFormat = pixelFormat;
    }

    @Override
    public int getBitRate() {
        if (context == null)
            return 0;
        
        if (bitRate == null)
            bitRate = context.bit_rate();
        
        return bitRate;
    }

    @Override
    public void setBitRate(int bitRate) {
        if (context == null)
            return;
        
        context.bit_rate(bitRate);
        this.bitRate = bitRate;
    }

    @Override
    public Rational getTimeBase() {
        if (context == null)
            return null;
        
        if (timeBase == null)
            timeBase = new Rational(context.time_base());
        
        return timeBase;
    }

    @Override
    public void setTimeBase(Rational timeBase) {
        if (context == null)
            return;
        
        context.time_base().num((int)timeBase.getNumerator());
        context.time_base().den((int)timeBase.getDenominator());
        this.timeBase = timeBase;
    }

    @Override
    public int getGopSize() {
        if (context == null)
            return 0;
        
        if (gopSize == null)
            gopSize = context.gop_size();
        
        return gopSize;
    }

    @Override
    public void setGopSize(int gopSize) {
        if (context == null)
            return;
        
        context.gop_size(gopSize);
        this.gopSize = gopSize;
    }

    @Override
    public int getMaxBFrames() {
        if (context == null)
            return 0;
        
        if (maxBFrames == null)
            maxBFrames = context.max_b_frames();
        
        return maxBFrames;
    }

    @Override
    public void setMaxBFrames(int maxBFrames) {
        if (context == null)
            return;
        
        context.max_b_frames(maxBFrames);
        this.maxBFrames = maxBFrames;
    }

    @Override
    public int getMbDecision() {
        if (context == null)
            return 0;
        
        if (mbDecision == null)
            mbDecision = context.mb_decision();
        
        return mbDecision;
    }

    @Override
    public void setMbDecision(int mbDecision) {
        if (context == null)
            return;
        
        context.mb_decision(mbDecision);
        this.mbDecision = mbDecision;
    }

    @Override
    public int getChannels() {
        if (context == null)
            return 0;
        
        if (channels == null)
            channels = context.channels();
        
        return channels;
    }

    @Override
    public void setChannels(int channels) {
        if (context == null)
            return;
        
        context.channels(channels);
        this.channels = channels;
    }

    @Override
    public long getChannelLayout() {
        if (context == null)
            return 0;
        
        if (channelLayout == null)
            channelLayout = context.channel_layout();
        
        return channelLayout;
    }

    @Override
    public void setChannelLayout(long channelLayout) {
        if (context == null)
            return;
        
        context.channel_layout(channelLayout);
        this.channelLayout = channelLayout;
    }

    @Override
    public int getSampleFormat() {
        if (context == null)
            return 0;
        
        if (sampleFormat == null)
            sampleFormat = context.sample_fmt();
        
        return sampleFormat;
    }

    @Override
    public void setSampleFormat(int sampleFormat) {
        if (context == null)
            return;
        
        context.sample_fmt(sampleFormat);
        this.sampleFormat = sampleFormat;
    }

    @Override
    public int getSampleRate() {
        if (context == null)
            return 0;
        
        if (sampleRate == null)
            sampleRate = context.sample_rate();
        
        return sampleRate;
    }

    @Override
    public void setSampleRate(int sampleRate) {
        if (context == null)
            return;
        
        context.sample_rate(sampleRate);
        this.sampleRate = sampleRate;
    }
    
    @Override
    public int getFrameSize() {
        if (context == null)
            return 0;
        
        if (frameSize == null)
            frameSize = context.frame_size();
        
        return frameSize;
    }
    
    @Override
    public boolean decodeVideoFrame(IPacketWrapper packet, IFrameWrapper frame) throws LibavException {
        if (isClosed())
            return false;
        
        intByRef.setInt(0);
        
        int packetSize = packet.getSize();
        int len = codecLib.avcodec_decode_video2(getPointer(), frame.getPointer(), intByRef, packet.getPointer());
        if (len < 0)
            throw new LibavException(len);
        
        packetSize -= len;
        packet.setSize(packetSize);
        packet.setData(packetSize <= 0 ? null : packet.getData().offset(len));
        if (intByRef.getInt() != 0) {
            frame.clearWrapperCache();
            return true;
        }
        
        return false;
    }
    
    @Override
    public boolean encodeVideoFrame(IFrameWrapper frame, IPacketWrapper packet) throws LibavException {
        if (isClosed())
            return false;
        
        int size = codecLib.avcodec_encode_video(getPointer(), packet.getData(), packet.getSize(), frame == null ? null : frame.getPointer());
        if (size < 0)
            throw new LibavException(size);
        else if (size == 0)
            return false;
        
        packet.setSize(size);
        
        return true;
    }
    
    @Override
    public boolean decodeAudioFrame(IPacketWrapper packet, IFrameWrapper frame) throws LibavException {
        if (isClosed())
            return false;
        
        return decodeAudioFunction.decodeAudioFrame(packet, frame);
    }
    
    @Override
    public boolean encodeAudioFrame(IFrameWrapper frame, IPacketWrapper packet) throws LibavException {
        if (isClosed())
            return false;
        
        return encodeAudioFunction.encodeAudioFrame(frame, packet);
    }
    
    private static interface IDecodeAudioFunction {
        boolean decodeAudioFrame(IPacketWrapper packet, IFrameWrapper frame) throws LibavException;
    }
    
    private static interface IEncodeAudioFunction {
        boolean encodeAudioFrame(IFrameWrapper frame, IPacketWrapper packet) throws LibavException;
    }
    
    private class DecodeAudio3 implements IDecodeAudioFunction {
        @Override
        public boolean decodeAudioFrame(IPacketWrapper packet, IFrameWrapper frame) throws LibavException {
            intByRef.setInt(frame.getLineSize().get(0));

            int packetSize = packet.getSize();
            int len = codecLib.avcodec_decode_audio3(getPointer(), frame.getData().get(0).as(Short.class), intByRef, packet.getPointer());
            if (len < 0)
                throw new LibavException(len);

            packetSize -= len;
            packet.setSize(packetSize);
            packet.setData(packetSize <= 0 ? null : packet.getData().offset(len));
            if (intByRef.getInt() > 0) {
                frame.clearWrapperCache();
                frame.getLineSize().set(0, intByRef.getInt());
                frame.setPacketPts(packet.getPts());
                frame.setPacketDts(packet.getDts());
                return true;
            }

            return false;
        }
    }
    
    private class DecodeAudio4 implements IDecodeAudioFunction {
        @Override
        public boolean decodeAudioFrame(IPacketWrapper packet, IFrameWrapper frame) throws LibavException {
            intByRef.setInt(0);
            
            frame.getDefaults();
            int packetSize = packet.getSize();
            int len = codecLib.avcodec_decode_audio4(getPointer(), frame.getPointer(), intByRef, packet.getPointer());
            if (len < 0)
                throw new LibavException(len);
            
            packetSize -= len;
            packet.setSize(packetSize);
            packet.setData(packetSize <= 0 ? null : packet.getData().offset(len));
            if (intByRef.getInt() != 0) {
                frame.getLineSize().set(0, frame.getNbSamples() * getChannels() * AVSampleFormat.getBytesPerSample(getSampleFormat()));
                return true;
            }

            return false;
        }
    }
    
    private class EncodeAudio implements IEncodeAudioFunction {
        @Override
        public boolean encodeAudioFrame(IFrameWrapper frame, IPacketWrapper packet) throws LibavException {
            int bufSize = packet.getSize();
            if (getFrameSize() <= 1) // if it is an PCM encoder
                bufSize = frame == null ? 0 : frame.getLineSize().get(0);
            
            int len = codecLib.avcodec_encode_audio(getPointer(), packet.getData(), bufSize, frame == null ? null : frame.getData().get(0).as(Short.class));
            if (len < 0)
                throw new LibavException(len);
            else if (len == 0)
                return false;

            packet.setSize(len);

            return true;
        }
    }
    
    private class EncodeAudio2 implements IEncodeAudioFunction {
        @Override
        public boolean encodeAudioFrame(IFrameWrapper frame, IPacketWrapper packet) throws LibavException {
            intByRef.setInt(0);
            
            int len = codecLib.avcodec_encode_audio2(getPointer(), packet.getPointer(), frame == null ? null : frame.getPointer(), intByRef);
            if (len < 0)
                throw new LibavException(len);
            
            if (intByRef.getInt() != 0)
                return true;
            
            return false;
        }
    }
    
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy