Decode a media packet with audio samples into an {@code AudioFrame}.

@param mediaPacket packet with audio samples.

@return an {@code AudioFrame} with normalized PCM audio samples.

@throws JavaAVException if audio packet could not be decoded.
195867
public AudioFrame decodeAudio(MediaPacket mediaPacket) throws JavaAVException {
		if (state != State.Opened)
			throw new JavaAVException("Could not decode audio, decoder is not opened.");

		if (codec.getType() != MediaType.AUDIO)
			throw new JavaAVException("Could not decode audio, this is a non-audio decoder.");

		if (mediaPacket == null)
			throw new JavaAVException("No audio passed to decode.");

		AudioFrame frame = null;
		ByteBuffer packetData = mediaPacket.getData();

		if (packetData != null) {
			avPacket.data(new BytePointer(packetData));
			avPacket.size(packetData.limit());
		}
		else {
			avPacket.data(null);
			avPacket.size(0);
		}

		while (avPacket.size() > 0) {
			// reset frame values
			avcodec_get_frame_defaults(avFrame);

			int len = avcodec_decode_audio4(avContext, avFrame, gotFrame, avPacket);

			if (len > 0) {
				avPacket.data(avPacket.data().position(len));
				avPacket.size(avPacket.size() - len);
			}

			if (len > 0 && gotFrame[0] != 0) {
				AVRational time_base = avContext.time_base();

				long pts = av_frame_get_best_effort_timestamp(avFrame);
				long timestamp = 1000000L * pts * time_base.num() / time_base.den();

				int sampleFormat = avFrame.format();
				int isPlanar = av_sample_fmt_is_planar(sampleFormat);
				int planes = isPlanar != 0 ? avFrame.channels() : 1;
				int bufferSize = av_samples_get_buffer_size((int[]) null, avContext.channels(), avFrame.nb_samples(), avContext.sample_fmt(), 1) / planes;

				SampleFormat format = SampleFormat.byId(sampleFormat);
				ChannelLayout channelLayout = ChannelLayout.byId(avFrame.channel_layout());

				AudioFormat audioFormat = new AudioFormat(format, channelLayout, avFrame.channels(), avFrame.sample_rate());

				frame = new AudioFrame(audioFormat, avFrame.nb_samples());
				frame.setKeyFrame(avFrame.key_frame() != 0);
				frame.setTimestamp(timestamp);

				for (int i = 0; i < planes; i++) {
					BytePointer pointer = avFrame.data(i).capacity(bufferSize);
					ByteBuffer buffer = pointer.asBuffer();
					buffer.position(0);

					frame.getPlane(i).asByteBuffer().put(buffer);
				}
			}
			else {
				break;
			}
		}

		av_free_packet(avPacket);

		return frame;
	}
883624
public void decode(SeekPoint from, SeekPoint to) throws IOException {
        // position random access file
        if (!(inputStream instanceof RandomFileInputStream)) throw new IOException("Not a RandomFileInputStream: " + inputStream.getClass().getName());
        ((RandomFileInputStream)inputStream).seek(from.getStreamOffset());
        bitStream.reset();
        samplesDecoded = from.getSampleNumber();
        
        //state = DECODER_SEARCH_FOR_FRAME_SYNC;
        try {
            while (true) {
                //switch (state) {
                //case DECODER_SEARCH_FOR_METADATA :
                //    readStreamSync();
                //    break;
                //case DECODER_READ_METADATA :
                //    Metadata metadata = readNextMetadata();
                //    if (metadata == null) break;
                //    break;
                //case DECODER_SEARCH_FOR_FRAME_SYNC :
                findFrameSync();
                //    break;
                //case DECODER_READ_FRAME :
                try {
                    readFrame();
                    frameListeners.processFrame(frame);
                    callPCMProcessors(frame);
                } catch (FrameDecodeException e) {
                    badFrames++;
                }
                //frameListeners.processFrame(frame);
                //callPCMProcessors(frame);
                //System.out.println(samplesDecoded +" "+ to.getSampleNumber());
                if (to != null && samplesDecoded >= to.getSampleNumber()) return;
                //    break;
                //case DECODER_END_OF_STREAM :
                //case DECODER_ABORTED :
                //    return;
                //default :
                //    throw new IOException("Unknown state: " + state);
                //}
            }
        } catch (EOFException e) {
            eof = true;
        }
    }
1053589
protected static String decode(String component, String charset)
            throws URIException {
        if (component == null) {
            throw new IllegalArgumentException(
                    "Component array of chars may not be null");
        }
        byte[] rawdata = null;
        //     try {
        rawdata = LaxURLCodec.decodeUrlLoose(EncodingUtil
                .getAsciiBytes(component));
        //     } catch (DecoderException e) {
        //         throw new URIException(e.getMessage());
        //     }
        return EncodingUtil.getString(rawdata, charset);
    }
1353835
public static AudioInputStream setupAudioStream (InputStream in)
        throws UnsupportedAudioFileException, IOException
    {
        AudioInputStream stream = AudioSystem.getAudioInputStream(in);
        AudioFormat format = stream.getFormat();
        if (format.getEncoding() != AudioFormat.Encoding.PCM_SIGNED) {
            stream = AudioSystem.getAudioInputStream(
                new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
                                format.getSampleRate(),
                                16,
                                format.getChannels(),
                                format.getChannels() * 2,
                                format.getSampleRate(),
                                false), stream);
        }

        return stream;
    }
589060
private int readPacket(byte[] packet, int offset, int psize)
            throws IOException {
        int length = 0;
        try {
            while (length < psize) {
                int len = stream.read(packet, offset + length, psize - length);
                if (len == -1) {
                    return length;
                }
                length += len;
            }
            return length;
        } catch (Exception e) {
        	logger.error(e);
        }
        return length;
    }
958155
@Override
    public boolean isConversionSupported(
            AudioFormat targetFormat,
            AudioFormat sourceFormat) {
        LOG.log(Level.FINE, ">TFormatConversionProvider.isConversionSupported(AudioFormat, AudioFormat):");
        LOG.log(Level.FINE, "class: {0}", getClass().getName());
        LOG.log(Level.FINE, "checking if conversion possible");
        LOG.log(Level.FINE, "from: {0}", sourceFormat);
        LOG.log(Level.FINE, "to: {0}", targetFormat);
        AudioFormat[] aTargetFormats = getTargetFormats(targetFormat.getEncoding(), sourceFormat);
        for (AudioFormat aTargetFormat : aTargetFormats) {
            LOG.log(Level.FINE, "checking against possible target format: {0}", aTargetFormat);
            if (aTargetFormat != null && AudioFormats.matches(aTargetFormat, targetFormat)) {
                LOG.log(Level.FINE, "<result=true");
                return true;
            }
        }
        LOG.log(Level.FINE, "<result=false");
        return false;
    }
288686
public static Codec getDecoderById(CodecID codecId) throws JavaAVException {
		if (codecId == null)
			throw new NullPointerException("CodecID is null.");

		AVCodec avCodec = avcodec_find_decoder(codecId.value());

		if (avCodec == null || avCodec.isNull())
			throw new JavaAVException("Decoder not found: " + codecId.toString());

		Codec codec = new Codec();
		codec.avCodec = avCodec;

		return codec;
	}
654064
public ByteBuffer encode(Packet packet, GroupContext groupContext, ChannelContext channelContext) {
        SimplePacket helloPacket  = (SimplePacket) packet;
        byte[] body = helloPacket.getBody();
        int bodyLen = 0;
        if(body != null){
            bodyLen = body.length;
        }

        //Bytebuffer总长度 = 消息头+消息体的长度
        int allLen = SimplePacket.HEADER_LENGTH+bodyLen;
        //创建新的Bytebuffer
        ByteBuffer buf = ByteBuffer.allocate(allLen);
        //设置字节序
        buf.order(groupContext.getByteOrder());
        //写入消息头
        buf.putInt(bodyLen);
        //写入消息体
        if(body != null){
            buf.put(body);
        }
        return buf;
    }
319996
@Override
    public AudioFileFormat getAudioFileFormat(InputStream inputStream, long medialength) throws UnsupportedAudioFileException, IOException {
        return getAudioFileFormat(inputStream, (int) medialength, AudioSystem.NOT_SPECIFIED);
    }
834912
public static byte[] decode(final byte[] compressed) throws IOException {
        ByteArrayInputStream byteIn = new ByteArrayInputStream(compressed);
        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
        GZIPInputStream gzIn = null;
        try {
            gzIn = new GZIPInputStream(byteIn);
            int read;
            byte[] buffer = new byte[BUFFER_SIZE];
            do {
                read = gzIn.read(buffer);
                if (read > 0) {
                    byteOut.write(buffer, 0, read);
                }
            } while (read >= 0);
            return byteOut.toByteArray();
        } finally {
            gzIn.close();
            byteOut.close();
        }
    }
1015409
public void processPacket(OggPacket packet) {
        SkeletonPacket skel = SkeletonPacketFactory.create(packet);

        // First packet must be the head
        if (packet.isBeginningOfStream()) {
            fishead = (SkeletonFishead)skel;
        } else if (skel instanceof SkeletonFisbone) {
            SkeletonFisbone bone = (SkeletonFisbone)skel;
            fisbones.add(bone);
            bonesByStream.put(bone.getSerialNumber(), bone);
        } else if (skel instanceof SkeletonKeyFramePacket) {
            keyFrames.add((SkeletonKeyFramePacket)skel);
        } else {
            throw new IllegalStateException("Unexpected Skeleton " + skel);
        }

        if (packet.isEndOfStream()) {
            hasWholeStream = true;
        }
    }
858559
@Override
    public JingleMediaSession createMediaSession(PayloadType payloadType, final TransportCandidate remote, final TransportCandidate local, final JingleSession jingleSession) {
        return new AudioMediaSession(payloadType, remote, local, null,null);
    }
146860
public RTPFormats negotiateAudio(SessionDescription sdp, RTPFormats formats) {
    	this.audio.clean();
    	MediaDescriptorField descriptor = sdp.getAudioDescriptor();
    	descriptor.getFormats().intersection(formats, this.audio);
    	return this.audio;
    }
66289
@Override
    public ITag readTag() {
        //log.debug("Read tag");
        ITag tag = null;
        try {
            lock.acquire();
            //empty-out the pre-streaming tags first
            if (!firstTags.isEmpty()) {
                log.debug("Returning pre-tag");
                // Return first tags before media data
                return firstTags.removeFirst();
            }
            //log.debug("Read tag - sample {} prevFrameSize {} audio: {} video: {}", new Object[]{currentSample, prevFrameSize, audioCount, videoCount});

            //get the current frame
            MP4Frame frame = frames.get(currentFrame);
            log.debug("Playback {}", frame);

            int sampleSize = frame.getSize();

            int time = (int) Math.round(frame.getTime() * 1000.0);
            //log.debug("Read tag - dst: {} base: {} time: {}", new Object[]{frameTs, baseTs, time});

            long samplePos = frame.getOffset();
            //log.debug("Read tag - samplePos {}", samplePos);

            //determine frame type and packet body padding
            byte type = frame.getType();

            //create a byte buffer of the size of the sample
            ByteBuffer data = ByteBuffer.allocate(sampleSize + 2);
            try {
                //log.debug("Writing audio prefix");
                data.put(MP4Reader.PREFIX_AUDIO_FRAME);
                //do we need to add the mdat offset to the sample position?
                dataSource.position(samplePos);
                dataSource.read(data);
            } catch (IOException e) {
                log.error("Error on channel position / read", e);
            }

            //chunk the data
            IoBuffer payload = IoBuffer.wrap(data.array());

            //create the tag
            tag = new Tag(type, time, payload.limit(), payload, prevFrameSize);
            //log.debug("Read tag - type: {} body size: {}", (type == TYPE_AUDIO ? "Audio" : "Video"), tag.getBodySize());

            //increment the sample number
            currentFrame++;
            //set the frame / tag size
            prevFrameSize = tag.getBodySize();
        } catch (InterruptedException e) {
            log.warn("Exception acquiring lock", e);
        } finally {
            lock.release();
        }
        //log.debug("Tag: {}", tag);
        return tag;
    }
371574
public Packet decode(ByteBuffer buffer, int limit, int position, int readableLength, ChannelContext channelContext) throws AioDecodeException {
        int realableLength = limit - position;
        //收到的数据组不了业务包,则返回null以告诉框架数据不够
        if(realableLength < SimplePacket.HEADER_LENGTH){
            return null;
        }

        //读取消息体的长度
        int bodyLength = buffer.getInt();
        if(bodyLength <0){
            throw new AioDecodeException("bodyLength [" + bodyLength + "] is not right, remote:" + channelContext.getClientNode());
        }
        //计算本次需要的数据长度
        int needLength = SimplePacket.HEADER_LENGTH + bodyLength;
        //收到的数据是否足够组包
        int isDateEnough = realableLength - needLength;
        if(isDateEnough < 0){
            return null;
        }
        else{//组包成功
            SimplePacket pack = new SimplePacket();
            if(bodyLength > 0){
                byte[] dist = new byte[bodyLength];
                buffer.get(dist);
                pack.setBody(dist);
            }
            return pack;
        }
    }
362612
public static TheoraPacket create(OggPacket packet) {
        byte type = packet.getData()[0];

        // Special header types detection
        if(isTheoraSpecial(packet)) {
            switch(type) {
            case (byte)TYPE_IDENTIFICATION:
                return new TheoraInfo(packet);
            case (byte)TYPE_COMMENTS:
                return new TheoraComments(packet);
            case (byte)TYPE_SETUP:
                return new TheoraSetup(packet);
            }
        }

        return new TheoraVideoData(packet);
    }
924412
public void negotiateFormats(MediaDescriptionField media) {
		// Clean currently offered formats
		this.offeredFormats.clean();
		
		// Map payload types to RTP Format
        for (String payloadType : media.getPayloadTypes()) {
        	RTPFormat format;
        	try {
				int payloadTypeInt = Integer.parseInt(payloadType);

				if(payloadTypeInt < AVProfile.DYNAMIC_PT_MIN || payloadTypeInt > AVProfile.DYNAMIC_PT_MAX) {
					// static payload type
					format = AVProfile.getFormat(payloadTypeInt, AVProfile.AUDIO);
				} else {
					// dynamic payload type
					final RtpMapAttribute codecSdp = media.getFormat(payloadTypeInt);
					final String codecName = codecSdp.getCodec();
					final RTPFormat staticFormat = AVProfile.getFormat(codecName);

					// Check if code is supported
					final boolean supported = staticFormat != null && staticFormat.getClockRate() == codecSdp.getClockRate();
					if(supported) {
						format = new RTPFormat(payloadTypeInt, staticFormat.getFormat(), staticFormat.getClockRate());
					} else {
						format = null;
					}
				}
			} catch (NumberFormatException e) {
        		format = null;
			}

			if(format != null) {
        		this.offeredFormats.add(format);
			} else {
        		if (logger.isDebugEnabled()) {
					logger.debug(this.mediaType + " channel " + this.ssrc + " dropped unsupported RTP payload type " + payloadType);
				}
			}
        }
		
		// Negotiate the formats and store intersection
		this.negotiatedFormats.clean();
		this.supportedFormats.intersection(this.offeredFormats, this.negotiatedFormats);
		
		// Apply formats
		setFormats(this.negotiatedFormats);
		this.negotiated = true;
	}