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

org.red5.codec.AbstractAudio Maven / Gradle / Ivy

There is a newer version: 2.0.15
Show newest version
package org.red5.codec;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import org.apache.mina.core.buffer.IoBuffer;
import org.red5.util.ByteNibbler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Abstract audio codec implementation.
 *
 */
public class AbstractAudio implements IAudioStreamCodec {

    protected static Logger log = LoggerFactory.getLogger("Audio");

    protected static boolean isTrace = log.isTraceEnabled(), isDebug = log.isDebugEnabled();

    protected AudioCodec codec;

    // whether or not to employ enhanced codec handling
    protected boolean enhanced;

    protected AvMultitrackType multitrackType;

    protected AudioPacketType packetType;

    // defaulting to 48khz, 16bit, stereo
    protected int sampleRate = 48000, sampleSizeInBits = 16, channels = 2;

    // defaulting to unsigned simply to support 8 bit audio / older codecs
    protected boolean signed = true;

    // track id
    protected int trackId;

    // audio channel order
    protected AudioChannelOrder audioChannelOrder = AudioChannelOrder.Unspecified;

    // each entry specifies the speaker layout
    protected AudioChannel[] audioChannelMap;

    // indicates which channels are present in the multi-channel stream
    protected int audioChannelFlags;

    // audio codec specific attributes
    protected transient ConcurrentMap attributes = new ConcurrentHashMap<>();

    @Override
    public AudioCodec getCodec() {
        return codec;
    }

    @Override
    public String getName() {
        return codec.name();
    }

    @Override
    public void setTrackId(int trackId) {
        this.trackId = trackId;
    }

    @Override
    public int getTrackId() {
        return trackId;
    }

    @Override
    public void reset() {
    }

    @Override
    public boolean canHandleData(IoBuffer data) {
        boolean result = false;
        if (data != null && data.limit() > 0) {
            byte flgs = data.get();
            ByteNibbler nibbler = new ByteNibbler(flgs);
            int codecId = nibbler.nibble(4);
            // check codec id against bitstream
            result = codecId == codec.getId();
            if (result) {
                sampleRate = nibbler.nibble(2);
                sampleSizeInBits = nibbler.nibble(1) == 0 ? 8 : 16;
                // PCM and PCM_LE are the same, just the endianess is different, 16 bit are always signed
                signed = (codecId != 3 && codecId != 0) || sampleSizeInBits == 16;
                channels = 1 + nibbler.nibble(1);
                // set the sample rate in kHz (this may change depending upon the codec)
                switch (sampleRate) {
                    case 0:
                        sampleRate = 5500;
                        break;
                    case 1:
                        sampleRate = 11025;
                        break;
                    case 2:
                        sampleRate = 22050;
                        break;
                    case 3: // flash sends this for 48kHz also
                        sampleRate = 44100;
                        break;
                }
            }
        }
        return result;
    }

    @Override
    public boolean addData(IoBuffer data) {
        return false;
    }

    @Override
    public boolean addData(IoBuffer data, int timestamp, boolean amf) {
        return false;
    }

    @Override
    public IoBuffer getDecoderConfiguration() {
        return null;
    }

    @Override
    public boolean isEnhanced() {
        return enhanced;
    }

    @Override
    public AvMultitrackType getMultitrackType() {
        return multitrackType;
    }

    @Override
    public AudioPacketType getPacketType() {
        return packetType;
    }

    public void setSampleRate(int sampleRate) {
        this.sampleRate = sampleRate;
    }

    @Override
    public int getSampleRate() {
        return sampleRate;
    }

    @Override
    public int getSampleSizeInBits() {
        return sampleSizeInBits;
    }

    public void setChannels(int channels) {
        this.channels = channels;
    }

    @Override
    public int getChannels() {
        return channels;
    }

    @Override
    public boolean isSigned() {
        return signed;
    }

    /**
     * Sets an attribute directly on the codec instance.
     *
     * @param key
     * @param value
     */
    public void setAttribute(String key, String value) {
        attributes.put(key, value);
    }

    /**
     * Returns the attribute for a given key.
     *
     * @param key
     * @return String value
     */
    public String getAttribute(String key) {
        return attributes.get(key);
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((codec == null) ? 0 : codec.hashCode());
        result = prime * result + sampleRate;
        result = prime * result + sampleSizeInBits;
        result = prime * result + channels;
        result = prime * result + trackId;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        AbstractAudio other = (AbstractAudio) obj;
        if (codec != other.codec)
            return false;
        if (sampleRate != other.sampleRate)
            return false;
        if (sampleSizeInBits != other.sampleSizeInBits)
            return false;
        if (channels != other.channels)
            return false;
        if (trackId != other.trackId)
            return false;
        return true;
    }

    @Override
    public String toString() {
        if (enhanced) {
            return "Audio [codec=" + codec + ", multitrackType=" + multitrackType + ", sampleRate=" + sampleRate + ", sampleSizeInBits=" + sampleSizeInBits + ", channels=" + channels + ", signed=" + signed + ", trackId=" + trackId + ", audioChannelOrder=" + audioChannelOrder + ", audioChannelMap=" + audioChannelMap + ", audioChannelFlags=" + audioChannelFlags + ", attributes=" + attributes + "]";
        }
        return "Audio [codec=" + codec + ", sampleRate=" + sampleRate + ", sampleSizeInBits=" + sampleSizeInBits + ", channels=" + channels + ", signed=" + signed + ", not enhanced]";
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy