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

ru.sbtqa.monte.media.Buffer Maven / Gradle / Ivy

There is a newer version: 1.1.0-JAVA7
Show newest version
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ru.sbtqa.monte.media;

import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.WritableRaster;
import java.util.Arrays;
import java.util.EnumSet;
import ru.sbtqa.monte.media.math.Rational;
import ru.sbtqa.monte.media.util.Methods;

/**
 * A {@code Buffer} carries media data from one media processing unit to
 * another.
 *
 * @author Werner Randelshofer
 * @version 1.0 2011-03-12 Created.
 */
public class Buffer {

    /**
     * A flag mask that describes the boolean attributes for this buffer.
     */
    public EnumSet flags = EnumSet.noneOf(BufferFlag.class);
    /**
     * Values which are not specified must have this value.
     */
    public static final int NOT_SPECIFIED = -1;
    /**
     * The track number. This can be set to NOT_SPECIFIED or to a number >=
     * 0.
     */
    public int track;
    /**
     * Header information, such as RTP header for this chunk.
     */
    public Object header;
    /**
     * The header offset. This field is only used if {@code header} is an array.
     */
    public int headerOffset;
    /**
     * The header length. This field is only used if {@code header} is an array.
     */
    public int headerLength;

    /**
     * The media data.
     */
    public Object data;
    /**
     * The data offset. This field is only used if {@code data} is an array.
     */
    public int offset;
    /**
     * The data length. This field is only used if {@code data} is an array.
     */
    public int length;
    /**
     * Duration of a sample in seconds. Multiply this with {@code sampleCount}
     * to get the buffer duration.
     */
    public Rational sampleDuration;
    /**
     * The time stamp of this buffer in seconds.
     */
    public Rational timeStamp;
    /**
     * The format of the data in this buffer.
     */
    public Format format;
    /**
     * The number of samples in the data field.
     */
    public int sampleCount = 1;

    /**
     * Sequence number of the buffer. This can be used for debugging.
     */
    public long sequenceNumber;

    /**
     * Sets all variables of this buffer to that buffer except for {@code data},
     * {@code offset}, {@code length} and {@code header}.
     *
     * @param that TODO
     */
    public void setMetaTo(Buffer that) {
        this.flags = EnumSet.copyOf(that.flags);
        //this.data=that.data;
        //this.offset=that.offset;
        //this.length=that.length;
        //this.header=that.header;
        this.track = that.track;
        this.sampleDuration = that.sampleDuration;
        this.timeStamp = that.timeStamp;
        this.format = that.format;
        this.sampleCount = that.sampleCount;
        this.format = that.format;
        this.sequenceNumber = that.sequenceNumber;
    }

    /**
     * Sets {@code data}, {@code offset}, {@code length} and {@code header} of
     * this buffer to that buffer. Note that this method creates copies of the
     * {@code data} and {@code header}, so that these fields in that buffer can
     * be discarded without affecting the contents of this buffer.
     * 
     * FIXME - This method does not always create a copy!!
     *
     * @param that TODO
     */
    public void setDataTo(Buffer that) {
        this.offset = that.offset;
        this.length = that.length;
        this.data = copy(that.data, this.data);
        this.header = copy(that.header, this.header);

    }

    private Object copy(Object from, Object into) {
        if (from instanceof byte[]) {
            byte[] b = (byte[]) from;
            if (!(into instanceof byte[]) || ((byte[]) into).length < b.length) {
                into = new byte[b.length];
            }
            System.arraycopy(b, 0, (byte[]) into, 0, b.length);
        } else if (from instanceof BufferedImage) {
            // FIXME - Try to reuse BufferedImage in output!
            BufferedImage img = (BufferedImage) from;
            ColorModel cm = img.getColorModel();
            boolean isAlphaPremultiplied = cm.isAlphaPremultiplied();
            WritableRaster raster = img.copyData(null);
            into = new BufferedImage(cm, raster, isAlphaPremultiplied, null);
        } else if (from instanceof Cloneable) {
            try {
                into = Methods.invoke(from, "clone");
            } catch (NoSuchMethodException ex) {
                into = from;
            }
        } else {
            // FIXME - This is very fragile, since we do not know, if the
            //         input data stays valid until the output data is processed!
            into = from;
        }

        return into;
    }

    /**
     * Returns true if the specified flag is set.
     *
     * @param flag TODO
     * @return TODO
     */
    public boolean isFlag(BufferFlag flag) {
        return flags.contains(flag);
    }

    /**
     * Convenience method for setting a flag.
     *
     * @param flag TODO
     */
    public void setFlag(BufferFlag flag) {
        setFlag(flag, true);
    }

    /**
     * Convenience method for clearing a flag.
     *
     * @param flag TODO
     */
    public void clearFlag(BufferFlag flag) {
        setFlag(flag, false);
    }

    /**
     * Sets or clears the specified flag.
     *
     * @param flag TODO
     * @param value TODO
     */
    public void setFlag(BufferFlag flag, boolean value) {
        if (value) {
            flags.add(flag);
        } else {
            flags.remove(flag);
        }
    }

    /**
     * Clears all flags, and then sets the specified flag.
     *
     * @param flags TODO
     */
    public void setFlagsTo(BufferFlag... flags) {
        if (flags.length == 0) {
            this.flags = EnumSet.noneOf(BufferFlag.class);
        } else {
            this.flags = EnumSet.copyOf(Arrays.asList(flags));
        }
    }

    /**
     * Clears all flags, and then sets the specified flag.
     *
     * @param flags TODO
     */
    public void setFlagsTo(EnumSet flags) {
        if (flags == null) {
            this.flags = EnumSet.noneOf(BufferFlag.class);
        } else {
            this.flags = EnumSet.copyOf(flags);
        }
    }

    public void clearFlags() {
        flags.clear();
    }

    @Override
    public String toString() {
        return super.toString() + "{"
              +//
              "tr#:" + track
              +//
              ",seq#:" + sequenceNumber
              +//
              ",ts:" + timeStamp
              +//
              ",duration:" + sampleDuration
              +//
              ",#samples:" + sampleCount
              +//
              ",flags:" + flags
              +//
              ",format:" + format
              +//
              ",data:" + data
              +//
              ",offset:" + offset
              +//
              ",length:" + length
              +//
              ",header:" + data
              +//
              ",hOffset:" + headerOffset
              +//
              ",hLength:" + headerLength
              +//
              "}";
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy