Package org.red5.app.sip.trancoders

Source Code of org.red5.app.sip.trancoders.NellyToPcmTranscoder

package org.red5.app.sip.trancoders;

import org.slf4j.Logger;
import org.red5.logging.Red5LoggerFactory;
import org.red5.app.sip.codecs.Codec;
import org.red5.app.sip.codecs.asao.ByteStream;
import org.red5.app.sip.codecs.asao.Decoder;
import org.red5.app.sip.codecs.asao.DecoderMap;
import org.red5.app.sip.stream.RtpStreamSender;

public class NellyToPcmTranscoder implements Transcoder {
    protected static Logger log = Red5LoggerFactory.getLogger( NellyToPcmTranscoder.class, "sip" );

    private static final int NELLYMOSER_DECODED_PACKET_SIZE = 256;
    private static final int NELLYMOSER_ENCODED_PACKET_SIZE = 64;
   
    private Codec sipCodec = null// Sip codec to be used on audio session
    private Decoder decoder;
    private DecoderMap decoderMap;   
    float[] tempBuffer;        // Temporary buffer with received PCM audio from FlashPlayer.   
    int tempBufferRemaining = 0;   // Floats remaining on temporary buffer.
    float[] encodingBuffer;      // Encoding buffer used to encode to final codec format;   
    int encodingOffset = 0;      // Offset of encoding buffer.   
    boolean asao_buffer_processed = false;    // Indicates whether the current asao buffer was processed.
    boolean hasInitilializedBuffers = false// Indicates whether the handling buffers have already been initialized.

    public NellyToPcmTranscoder(Codec sipCodec) {
      this.sipCodec = sipCodec;
      decoder = new Decoder();
        decoderMap = null;
    }

    public int getOutgoingEncodedFrameSize() {
      return sipCodec.getOutgoingEncodedFrameSize();
    }

    public int getCodecId() {
      return sipCodec.getCodecId();
    }
   
    public int getOutgoingPacketization() {
      return sipCodec.getOutgoingPacketization();
    }
   
    private int fillRtpPacketBuffer(byte[] asaoBuffer, byte[] transcodedData, int dataOffset) {
        int copyingSize = 0;
        int finalCopySize = 0;
        byte[] codedBuffer = new byte[sipCodec.getOutgoingEncodedFrameSize()];

        try {
          if ((tempBufferRemaining + encodingOffset) >= sipCodec.getOutgoingDecodedFrameSize()) {
            copyingSize = encodingBuffer.length - encodingOffset;
               
                System.arraycopy(tempBuffer, tempBuffer.length-tempBufferRemaining,
                    encodingBuffer, encodingOffset, copyingSize);

                encodingOffset = sipCodec.getOutgoingDecodedFrameSize();
                tempBufferRemaining -= copyingSize;
                finalCopySize = sipCodec.getOutgoingDecodedFrameSize();
            }
            else {
                if (tempBufferRemaining > 0) {
                    System.arraycopy(tempBuffer, tempBuffer.length - tempBufferRemaining,
                        encodingBuffer, encodingOffset, tempBufferRemaining);
                       
                    encodingOffset += tempBufferRemaining;
                    finalCopySize += tempBufferRemaining;
                    tempBufferRemaining = 0;
                }

                // Decode new asao packet.
                asao_buffer_processed = true;
                ByteStream audioStream = new ByteStream( asaoBuffer, 1, NELLYMOSER_ENCODED_PACKET_SIZE );
                decoderMap = decoder.decode( decoderMap, audioStream.bytes, 1, tempBuffer, 0 );

                //tempBuffer = ResampleUtils.normalize(tempBuffer, 256);   // normalise volume
                tempBufferRemaining = tempBuffer.length;

                if ( tempBuffer.length <= 0 ) {
                    log.error("Asao decoder Error." );
                }

                // Try to complete the encodingBuffer with necessary data.
                if ( ( encodingOffset + tempBufferRemaining ) > sipCodec.getOutgoingDecodedFrameSize() ) {
                    copyingSize = encodingBuffer.length - encodingOffset;
                }
                else {
                    copyingSize = tempBufferRemaining;
                }

                System.arraycopy(tempBuffer, 0, encodingBuffer, encodingOffset, copyingSize);

                encodingOffset += copyingSize;
                tempBufferRemaining -= copyingSize;
                finalCopySize += copyingSize;
            }

            if (encodingOffset == encodingBuffer.length)
            {
                int encodedBytes = sipCodec.pcmToCodec( encodingBuffer, codedBuffer );

                if ( encodedBytes == sipCodec.getOutgoingEncodedFrameSize() ) {
                    System.arraycopy(codedBuffer, 0, transcodedData, dataOffset, codedBuffer.length);
                }
                else {
                    //println( "fillRtpPacketBuffer", "Failure encoding buffer." );
                }
            }
        }
        catch ( Exception e ) {         
          log.error("Exception - " + e.toString());         
            e.printStackTrace();
        }

        return finalCopySize;
    }

    public void transcode(byte[] asaoBuffer, int offset, int num, byte[] transcodedData, int dataOffset, RtpStreamSender rtpSender) { 
        asao_buffer_processed = false;

        if (!hasInitilializedBuffers) {
            tempBuffer = new float[NELLYMOSER_DECODED_PACKET_SIZE];
            encodingBuffer = new float[sipCodec.getOutgoingDecodedFrameSize()];
            hasInitilializedBuffers = true;
        }

        if (num > 0) {
            do {
                int encodedBytes = fillRtpPacketBuffer( asaoBuffer, transcodedData, dataOffset );
                //println( "send", sipCodec.getCodecName() + " encoded " + encodedBytes + " bytes." );

                if ( encodedBytes == 0 ) {
                    break;
                }

                if ( encodingOffset == sipCodec.getOutgoingDecodedFrameSize() ) {
//                  System.out.println("Send this audio to asterisk.");
                    rtpSender.sendTranscodedData();
                    encodingOffset = 0;
                }

                //println( "send", "asao_buffer_processed = ["
                //        + asao_buffer_processed + "] ." );
            }
            while ( !asao_buffer_processed );
        }
        else if ( num < 0 ) {
            log.debug("Closing" );
        }
    }

  public void transcode(byte[] codedBuffer) {
    // TODO Auto-generated method stub
   
  }

  public int getIncomingEncodedFrameSize() {
    // TODO Auto-generated method stub
    return 0;
  }
}
TOP

Related Classes of org.red5.app.sip.trancoders.NellyToPcmTranscoder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.