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

org.libav.avformat.FormatContextWrapper54 Maven / Gradle / Ivy

/*
 * 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.avformat;

import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.PointerByReference;
import java.nio.charset.Charset;
import org.libav.LibavException;
import org.libav.avcodec.IPacketWrapper;
import org.libav.avformat.bridge.AVFormatContext54;
import org.libav.avformat.bridge.IAVFormatLibrary;
import org.libav.avutil.bridge.IAVUtilLibrary;
import org.libav.bridge.CustomNativeString;
import org.libav.bridge.LibraryManager;

/**
 * Wrapper class for the AVFormatContext54.
 * 
 * @author Ondrej Perutka
 */
public class FormatContextWrapper54 extends AbstractFormatContextWrapper {
    
    private static final IAVFormatLibrary formatLib;
    
    static {
        LibraryManager lm = LibraryManager.getInstance();
        formatLib = lm.getAVFormatLibraryWrapper().getLibrary();
    }
    
    private AVFormatContext54 context;
    private boolean outputContext;
    
    /**
     * Create a new wrapper for the given format context.
     * 
     * @param context a format context structure
     */
    public FormatContextWrapper54(AVFormatContext54 context) {
        this.context = context;
        this.outputContext = false;
    }
    
    @Override
    public Pointer getPointer() {
        if (isClosed())
            return null;
        
        return context.getPointer();
    }
    
    @Override
    public void close() {
        if (isClosed())
            return;
        
        if (outputContext) {
            if (getIOContext() != null && (getOutputFormat().getFlags() & IAVFormatLibrary.AVFMT_NOFILE) == 0)
                formatLib.avio_close(getIOContext().getPointer());
            LibraryManager.getInstance().getAVUtilLibraryWrapper().getLibrary().av_free(context.getPointer());
        } else {
            PointerByReference ps = new PointerByReference(context.getPointer());
            formatLib.avformat_close_input(ps);
        }
        
        context = null;
        streams = null;
    }
    
    @Override
    public boolean isClosed() {
        return context == null;
    }
    
    @Override
    public void findStreamInfo() throws LibavException {
        if (isClosed())
            return;
        
        int result = formatLib.avformat_find_stream_info(context.getPointer(), null);
        if (result < 0)
            throw new LibavException(result);
    }
    
    @Override
    public IStreamWrapper[] getStreams() {
        if (isClosed())
            return null;
        
        if (streams != null)
            return streams;
        
        getStreamCount();
        Pointer pStrms = (Pointer)context.readField("streams");
        if (pStrms == null)
            return null;
        
        Pointer[] strms = pStrms.getPointerArray(0, streamCount);
        streams = new IStreamWrapper[streamCount];
        for (int i = 0; i < streamCount; i++)
            streams[i] = strms[i] == null ? null : StreamWrapperFactory.getInstance().wrap(strms[i]);
        
        return streams;
    }

    @Override
    public int getStreamCount() {
        if (isClosed())
            return 0;
        
        if (streamCount == null)
            streamCount = (Integer)context.readField("nb_streams");
        
        return streamCount;
    }
    
    @Override
    public void setStream(int streamIndex, IStreamWrapper stream) {
        if (isClosed())
            return;
        
        getStreams();
        streams[streamIndex] = stream;
        Pointer pStrms = (Pointer)context.readField("streams");
        pStrms.write(Native.POINTER_SIZE * streamIndex, new Pointer[] { stream == null ? null : stream.getPointer() }, 0, 1);
    }
    
    @Override
    public IStreamWrapper newStream() throws LibavException {
        if (isClosed())
            return null;
        
        Pointer pStream = formatLib.avformat_new_stream(context.getPointer(), null);
        if (pStream == null)
            throw new LibavException("unable to create a new stream");
        
        streams = null;
        
        return StreamWrapperFactory.getInstance().wrap(pStream);
    }

    @Override
    public String getFileName() {
        if (isClosed())
            return null;
        
        if (fileName == null) {
            byte[] data = (byte[])context.readField("filename");
            fileName = new String(data, Charset.forName("UTF-8"));
        }
        
        return fileName;
    }

    @Override
    public void setFileName(String fileName) {
        if (isClosed())
            return;
        
        this.fileName = fileName;
        byte[] tmp = fileName.getBytes(Charset.forName("UTF-8"));
        byte[] data = new byte[AVFormatContext54.MAX_FILENAME_LENGTH];
        for (int i = 0; i < data.length; i++) {
            if (i < tmp.length)
                data[i] = tmp[i];
            else
                data[i] = 0;
        }
        data[data.length - 1] = 0;
        context.writeField("filename", data);
    }

    @Override
    public IIOContextWrapper getIOContext() {
        if (isClosed())
            return null;
        
        if (ioContext == null) {
            Pointer p = (Pointer)context.readField("pb");
            ioContext = p == null ? null : IOContextWrapperFactory.getInstance().wrap(p);
        }
        
        return ioContext;
    }

    @Override
    public void setIOContext(IIOContextWrapper ioContext) {
        if (isClosed())
            return;
        
        this.ioContext = ioContext;
        context.writeField("pb", ioContext == null ? null : ioContext.getPointer());
    }

    @Override
    public IOutputFormatWrapper getOutputFormat() {
        if (isClosed())
            return null;
        
        if (outputFormat == null) {
            Pointer p = (Pointer)context.readField("oformat");
            outputFormat = p == null ? null : OutputFormatWrapperFactory.getInstance().wrap(p);
        }
        
        return outputFormat;
    }

    @Override
    public void setOutputFormat(IOutputFormatWrapper outputFormat) {
        if (isClosed())
            return;
        
        this.outputFormat = outputFormat;
        context.writeField("oformat", outputFormat == null ? null : outputFormat.getPointer());
    }
    
    @Override
    public IInputFormatWrapper getInputFormat() {
        if (isClosed())
            return null;
        
        if (inputFormat == null) {
            Pointer p = (Pointer)context.readField("iformat");
            inputFormat = p == null ? null : InputFormatWrapperFactory.getInstance().wrap(p);
        }
        
        return inputFormat;
    }
    
    @Override
    public long getDuration() {
        if (isClosed())
            return 0;
        
        if (duration == null)
            duration = (Long)context.readField("duration") * 1000 / IAVUtilLibrary.AV_TIME_BASE;
        
        return duration;
    }
    
    @Override
    public Pointer getPrivateData() {
        if (isClosed())
            return null;
        
        if (privateData == null)
            privateData = (Pointer)context.readField("priv_data");
        
        return privateData;
    }
    
    @Override
    public void play() {
        if (isClosed())
            return;
        
        formatLib.av_read_play(context.getPointer());
    }
    
    @Override
    public void pause() {
        if (isClosed())
            return;
        
        formatLib.av_read_pause(context.getPointer());
    }
    
    @Override
    public boolean readNextPacket(IPacketWrapper packet) {
        if (isClosed())
            return false;
        
        int result = formatLib.av_read_frame(context.getPointer(), packet.getPointer());
        packet.clearWrapperCache();
        
        return result >= 0;
    }
    
    @Override
    public void writeHeader() throws LibavException {
        if (isClosed())
            return;
        
        int result = formatLib.avformat_write_header(context.getPointer(), null);
        if (result < 0)
            throw new LibavException(result);
    }
    
    @Override
    public void writeTrailer() throws LibavException {
        if (isClosed())
            return;
        
        int res = formatLib.av_write_trailer(context.getPointer());
        if (res != 0)
            throw new LibavException(res);
    }
    
    @Override
    public void writePacket(IPacketWrapper packet) throws LibavException {
        if (isClosed())
            return;
        
        int res = formatLib.av_write_frame(context.getPointer(), packet.getPointer());
        if (res != 0)
            throw new LibavException(res);
    }
    
    @Override
    public void interleavedWritePacket(IPacketWrapper packet) throws LibavException {
        if (isClosed())
            return;
        
        int res = formatLib.av_interleaved_write_frame(context.getPointer(), packet.getPointer());
        if (res != 0)
            throw new LibavException(res);
    }
    
    @Override
    public void seekFile(long minTime, long time, long maxTime) throws LibavException {
        if (isClosed())
            return;
        
        long tb = IAVUtilLibrary.AV_TIME_BASE / 1000;
        formatLib.avformat_seek_file(context.getPointer(), -1, minTime * tb, time * tb, maxTime * tb, 0);
    }
    
    private static FormatContextWrapper54 allocateContext() throws LibavException {
        Pointer ptr = formatLib.avformat_alloc_context();
        if (ptr == null)
            throw new LibavException("unable to allocate a format context");
        
        return new FormatContextWrapper54(new AVFormatContext54(ptr));
    }
    
    public static FormatContextWrapper54 openMedia(String url) throws LibavException {
        CustomNativeString cnsUrl = new CustomNativeString(url, "UTF-8", 1);
        
        PointerByReference avfcByRef = new PointerByReference();
        int result = formatLib.avformat_open_input(avfcByRef, cnsUrl.getPointer(), null, null);
        if (result < 0)
            throw new LibavException(result);
        
        return new FormatContextWrapper54(new AVFormatContext54(avfcByRef.getValue()));
    }
    
    public static FormatContextWrapper54 createMedia(String url, String outputFormatName) throws LibavException {
        CustomNativeString cnsUrl = new CustomNativeString(url, "UTF-8", 1);
        FormatContextWrapper54 result = allocateContext();
        result.outputContext = true;
        
        CustomNativeString ofn = outputFormatName == null ? null : new CustomNativeString(outputFormatName, "UTF-8", 1);
        Pointer pOfn = ofn == null ? null : ofn.getPointer();
        Pointer of = formatLib.av_guess_format(pOfn, cnsUrl.getPointer(), pOfn);
        if (of == null)
            throw new LibavException("unknown format: " + outputFormatName);
        result.setOutputFormat(OutputFormatWrapperFactory.getInstance().wrap(of));
        result.setFileName(url);
        
        PointerByReference avioc = new PointerByReference(null);
        if ((result.getOutputFormat().getFlags() & IAVFormatLibrary.AVFMT_NOFILE) == 0) {
            result.setIOContext(null);
            int res = formatLib.avio_open(avioc, cnsUrl.getPointer(), IAVFormatLibrary.AVIO_FLAG_WRITE);
            if (res < 0) {
                result.close();
                throw new LibavException(res);
            }
            result.setIOContext(avioc.getValue() == null ? null : IOContextWrapperFactory.getInstance().wrap(avioc.getValue()));
        }
        
        return result;
    }
    
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy