Skip to content

Commit

Permalink
同步代码优化 使用ArrayBlockingQueue
Browse files Browse the repository at this point in the history
  • Loading branch information
eric committed Jan 4, 2018
1 parent 1b4886e commit f0c54d8
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 24 deletions.
63 changes: 39 additions & 24 deletions rtmpfile/src/main/java/com/wangheart/rtmpfile/audio/AudioCodec.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import android.media.MediaExtractor;
import android.media.MediaFormat;

import com.wangheart.rtmpfile.utils.ADTSUtils;
import com.wangheart.rtmpfile.utils.LogUtils;

import java.io.BufferedInputStream;
Expand All @@ -14,7 +15,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.concurrent.ArrayBlockingQueue;

/**
* Author : eric
Expand All @@ -41,18 +42,23 @@ public class AudioCodec {
private BufferedOutputStream bos;
private FileInputStream fis;
private BufferedInputStream bis;
private ArrayList<byte[]> chunkPCMDataContainer;//PCM数据块容器
private OnCompleteListener onCompleteListener;
private OnProgressListener onProgressListener;
private long fileTotalSize;
private long decodeSize;

private int key_channel_count;
private int key_bit_rate;
private int key_sample_rate;
private int sampleRateType;

private ArrayBlockingQueue<byte[]> queue;


public static AudioCodec newInstance() {
return new AudioCodec();
}


/**
* 设置输入输出文件位置
*
Expand Down Expand Up @@ -86,7 +92,7 @@ public void prepare() {
} catch (IOException e) {
e.printStackTrace();
}
chunkPCMDataContainer = new ArrayList<>();
queue = new ArrayBlockingQueue<byte[]>(10);
initMediaDecode();//解码器
initAACMediaEncode();//AAC编码器
}
Expand All @@ -102,9 +108,12 @@ private void initMediaDecode() {
MediaFormat format = mediaExtractor.getTrackFormat(i);
String mime = format.getString(MediaFormat.KEY_MIME);
if (mime.startsWith("audio")) {//获取音频轨道
// format.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 200 * 1024);
mediaExtractor.selectTrack(i);//选择此音频轨道
LogUtils.d("mime:" + mime);
key_bit_rate = format.getInteger(MediaFormat.KEY_BIT_RATE);
key_channel_count = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
key_sample_rate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
sampleRateType = ADTSUtils.getSampleRateType(key_sample_rate);
mediaDecode = MediaCodec.createDecoderByType(mime);//创建Decode解码器
mediaDecode.configure(format, null, null, 0);
break;
Expand All @@ -131,8 +140,10 @@ private void initMediaDecode() {
*/
private void initAACMediaEncode() {
try {
MediaFormat encodeFormat = MediaFormat.createAudioFormat(MediaFormat.MIMETYPE_AUDIO_AAC, 44100, 2);//参数对应-> mime type、采样率、声道数
encodeFormat.setInteger(MediaFormat.KEY_BIT_RATE, 96000);//比特率
LogUtils.d(key_bit_rate + " " + key_channel_count + " " + key_sample_rate + " " + sampleRateType);
MediaFormat encodeFormat = MediaFormat.createAudioFormat(MediaFormat.MIMETYPE_AUDIO_AAC,
key_sample_rate, key_channel_count);//参数对应-> mime type、采样率、声道数
encodeFormat.setInteger(MediaFormat.KEY_BIT_RATE, key_bit_rate);//比特率
encodeFormat.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);
encodeFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 100 * 1024);
mediaEncode = MediaCodec.createEncoderByType(MediaFormat.MIMETYPE_AUDIO_AAC);
Expand Down Expand Up @@ -167,32 +178,35 @@ public void startAsync() {
}

/**
* 将PCM数据存入{@link #chunkPCMDataContainer}
* 将PCM数据存入队列
*
* @param pcmChunk PCM数据块
*/
private void putPCMData(byte[] pcmChunk) {
synchronized (AudioCodec.class) {//记得加锁
chunkPCMDataContainer.add(pcmChunk);
try {
LogUtils.d("put queue size:"+queue.size());
queue.put(pcmChunk);
} catch (InterruptedException e) {
e.printStackTrace();
LogUtils.e("queue put error");
}
}

/**
* 在Container中{@link #chunkPCMDataContainer}取出PCM数据
* 在Container中队列取出PCM数据
*
* @return PCM数据块
*/
private byte[] getPCMData() {
synchronized (AudioCodec.class) {//记得加锁
LogUtils.d("getPCM:" + chunkPCMDataContainer.size());
if (chunkPCMDataContainer.isEmpty()) {
try {
if(queue.isEmpty()){
return null;
}

byte[] pcmChunk = chunkPCMDataContainer.get(0);//每次取出index 0 的数据
chunkPCMDataContainer.remove(pcmChunk);//取出后将此数据remove掉 既能保证PCM数据块的取出顺序 又能及时释放内存
return pcmChunk;
return queue.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}


Expand All @@ -218,8 +232,9 @@ private void srcAudioFormatToPCM() {
mediaDecode.queueInputBuffer(inputIndex, 0, sampleSize, 0, 0);//通知MediaDecode解码刚刚传入的数据
mediaExtractor.advance();//MediaExtractor移动到下一取样处
decodeSize += sampleSize;
if(onProgressListener!=null){
onProgressListener.progress(decodeSize,fileTotalSize);
LogUtils.d("read:" + sampleSize);
if (onProgressListener != null) {
onProgressListener.progress(decodeSize, fileTotalSize);
}
}
}
Expand Down Expand Up @@ -302,7 +317,7 @@ private void dstAudioFormatFromPCM() {
*/
private void addADTStoPacket(byte[] packet, int packetLen) {
int profile = 2; // AAC LC
int freqIdx = 4; // 44.1KHz
int freqIdx = sampleRateType; // 44.1KHz
int chanCfg = 2; // CPE


Expand Down Expand Up @@ -396,13 +411,13 @@ private class EncodeRunnable implements Runnable {
@Override
public void run() {
long t = System.currentTimeMillis();
while (!codeOver || !chunkPCMDataContainer.isEmpty()) {
while (!codeOver || !queue.isEmpty()) {
dstAudioFormatFromPCM();
}
if (onCompleteListener != null) {
onCompleteListener.completed();
}
LogUtils.d("size:" + fileTotalSize + " decodeSize:" + decodeSize + "time:" + (System.currentTimeMillis() - t));
LogUtils.w("size:" + fileTotalSize + " decodeSize:" + decodeSize + "time:" + (System.currentTimeMillis() - t));
}
}

Expand All @@ -418,7 +433,7 @@ public interface OnCompleteListener {
* 转码进度监听器
*/
public interface OnProgressListener {
void progress(long current,long total);
void progress(long current, long total);
}

/**
Expand Down
38 changes: 38 additions & 0 deletions rtmpfile/src/main/java/com/wangheart/rtmpfile/utils/ADTSUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.wangheart.rtmpfile.utils;

import java.util.HashMap;
import java.util.Map;

/**
* Author : eric
* CreateDate : 2018/1/4 15:28
* Email : ericli_wang@163.com
* Version : 2.0
* Desc :
* Modified :
*/

public class ADTSUtils {
private static Map<String, Integer> SAMPLE_RATE_TYPE;

static {
SAMPLE_RATE_TYPE = new HashMap<>();
SAMPLE_RATE_TYPE.put("96000", 0);
SAMPLE_RATE_TYPE.put("88200", 1);
SAMPLE_RATE_TYPE.put("64000", 2);
SAMPLE_RATE_TYPE.put("48000", 3);
SAMPLE_RATE_TYPE.put("44100", 4);
SAMPLE_RATE_TYPE.put("32000", 5);
SAMPLE_RATE_TYPE.put("24000", 6);
SAMPLE_RATE_TYPE.put("22050", 7);
SAMPLE_RATE_TYPE.put("16000", 8);
SAMPLE_RATE_TYPE.put("12000", 9);
SAMPLE_RATE_TYPE.put("11025", 10);
SAMPLE_RATE_TYPE.put("8000", 11);
SAMPLE_RATE_TYPE.put("7350", 12);
}

public static int getSampleRateType(int sampleRate) {
return SAMPLE_RATE_TYPE.get(sampleRate + "");
}
}

0 comments on commit f0c54d8

Please sign in to comment.