如何现金流量表自动生成版 AAC ADTS 基本流与 Android MediaCodec

spydroid-ipcamera-master
org.eclipse.jdt.core.prefs
bangers.eot
bangers.woff
sunshiney.eot
sunshiney.woff
blue-button.png
camera.png
facebook.png
install.jpg
red-button.png
speaker.png
spydroid.png
#vlc.less#
accordion.less
fonts.less
mixins.less
styles.css
styles.less
credits.htm
majorkernelpanic
acra-4.4.0.jar
android-support-v4.jar
GoogleAdMobAdsSdk-6.1.0.jar
sc-light-jdk15on-1.47.0.2.jar
scpkix-jdk15on-1.47.0.2.jar
scprov-jdk15on-1.47.0.2.jar
preview.xml
drawable-hdpi
background.png
settings.png
drawable-ldpi
settings.png
drawable-mdpi
settings.png
preview.xml
spydroid.xml
tablet.xml
layout-sw600dp
preview.xml
spydroid.xml
tablet.xml
animals_cat.mp3
animals_dog.mp3
funny_fart.mp3
funny_fart2.mp3
funny_snoring.mp3
scary_breath.mp3
scary_evil_laughter.mp3
scary_horror.mp3
scary_insane_laughter.mp3
scary_long_growl.mp3
scary_thunder.mp3
war_explosion.mp3
war_gunshot.mp3
arrays.xml
strings.xml
strings.xml
strings.xml
strings.xml
preferences.xml
majorkernelpanic
exceptions
.classpath
.gitignore
AndroidManifest.xml
proguard-project.txt
proguard.cfg
project.properties
源码说明.txt
* Copyright (C)
GUIGUI Simon,
* This file is part of libstreaming (/fyhertz/libstreaming)
* Spydr you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software F either version 3 of the License, or
* (at your option) any later version.
* This source code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along w if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
package net.majorkernelpanic.streaming.
import java.io.F
import java.io.IOE
import java.io.RandomAccessF
import java.lang.reflect.F
import java.net.InetA
import java.nio.ByteB
import net.majorkernelpanic.streaming.SessionB
import net.majorkernelpanic.streaming.rtp.AACADTSP
import net.majorkernelpanic.streaming.rtp.AACLATMP
import net.majorkernelpanic.streaming.rtp.MediaCodecInputS
import android.annotation.SuppressL
import android.content.SharedP
import android.content.SharedPreferences.E
import android.media.AudioF
import android.media.AudioR
import android.media.MediaC
import android.media.MediaCodecI
import android.media.MediaF
import android.media.MediaR
import android.os.B
import android.os.E
import android.service.textservice.SpellCheckerService.S
import android.util.L
* A class for streaming AAC from the camera of an android device using RTP.
* You should use a {@link Session} instantiated with {@link SessionBuilder} instead of using this class directly.
* Call {@link #setDestinationAddress(InetAddress)}, {@link #setDestinationPorts(int)} and {@link #setAudioQuality(AudioQuality)}
* to configure the stream. You can then call {@link #start()} to start the RTP stream.
* Call {@link #stop()} to stop the stream.
public class AACStream extends AudioStream {
public final static String TAG = &AACStream&;
/** MPEG-4 Audio Object Types supported by ADTS. **/
private static final String[] AUDIO_OBJECT_TYPES = {
&AAC Main&,
&AAC LC (Low Complexity)&,
&AAC SSR (Scalable Sample Rate)&, // 3
&AAC LTP (Long Term Prediction)&
/** There are 13 supported frequencies by ADTS. **/
public static final int[] AUDIO_SAMPLING_RATES = {
96000, // 0
88200, // 1
64000, // 2
48000, // 3
44100, // 4
32000, // 5
24000, // 6
22050, // 7
16000, // 8
12000, // 9
11025, // 10
private String mSessionDescription =
private int mProfile, mSamplingRateIndex, mChannel, mC
private SharedPreferences mSettings =
private AudioRecord mAudioRecord =
private Thread mThread =
public AACStream() {
if (!AACStreamingSupported()) {
Log.e(TAG,&AAC not supported on this phone&);
throw new RuntimeException(&AAC not supported by this phone !&);
Log.d(TAG,&AAC supported on this phone&);
private static boolean AACStreamingSupported() {
if (Build.VERSION.SDK_INT&14)
MediaRecorder.OutputFormat.class.getField(&AAC_ADTS&);
} catch (Exception e) {
* Some data (the actual sampling rate used by the phone and the AAC profile) needs to be stored once {@link #getSessionDescription()} is called.
* @param prefs The SharedPreferences that will be used to store the sampling rate
public void setPreferences(SharedPreferences prefs) {
mSettings =
public synchronized void start() throws IllegalStateException, IOException {
configure();
if (!mStreaming) {
super.start();
public synchronized void configure() throws IllegalStateException, IOException {
super.configure();
mQuality = mRequestedQuality.clone();
// Checks if the user has supplied an exotic sampling rate
for (;i&AUDIO_SAMPLING_RATES.i++) {
if (AUDIO_SAMPLING_RATES[i] == mQuality.samplingRate) {
mSamplingRateIndex =
// If he did, we force a reasonable one: 16 kHz
if (i&12) mQuality.samplingRate = 16000;
if (mMode != mRequestedMode || mPacketizer==null) {
mMode = mRequestedM
if (mMode == MODE_MEDIARECORDER_API) {
mPacketizer = new AACADTSPacketizer();
mPacketizer = new AACLATMPacketizer();
if (mMode == MODE_MEDIARECORDER_API) {
testADTS();
// All the MIME types parameters used here are described in RFC 3640
// SizeLength: 13 bits will be enough because ADTS uses 13 bits for frame length
// config: contains the object type + the sampling rate + the channel number
// TODO: streamType always 5 ? profile-level-id always 15 ?
mSessionDescription = &m=audio &+String.valueOf(getDestinationPorts()[0])+& RTP/AVP 96\r\n& +
&a=rtpmap:96 mpeg4-generic/&+mQuality.samplingRate+&\r\n&+
&a=fmtp:96 streamtype=5; profile-level-id=15; mode=AAC- config=&+Integer.toHexString(mConfig)+&; SizeLength=13; IndexLength=3; IndexDeltaLength=3;\r\n&;
mProfile = 2; // AAC LC
mChannel = 1;
mConfig = mProfile&&11 | mSamplingRateIndex&&7 | mChannel&&3;
mSessionDescription = &m=audio &+String.valueOf(getDestinationPorts()[0])+& RTP/AVP 96\r\n& +
&a=rtpmap:96 mpeg4-generic/&+mQuality.samplingRate+&\r\n&+
&a=fmtp:96 streamtype=5; profile-level-id=15; mode=AAC- config=&+Integer.toHexString(mConfig)+&; SizeLength=13; IndexLength=3; IndexDeltaLength=3;\r\n&;
protected void encodeWithMediaRecorder() throws IOException {
testADTS();
((AACADTSPacketizer)mPacketizer).setSamplingRate(mQuality.samplingRate);
super.encodeWithMediaRecorder();
@SuppressLint({ &InlinedApi&, &NewApi& })
protected void encodeWithMediaCodec() throws IOException {
final int bufferSize = AudioRecord.getMinBufferSize(mQuality.samplingRate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT)*2;
((AACLATMPacketizer)mPacketizer).setSamplingRate(mQuality.samplingRate);
mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, mQuality.samplingRate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize);
mMediaCodec = MediaCodec.createEncoderByType(&audio/mp4a-latm&);
MediaFormat format = new MediaFormat();
format.setString(MediaFormat.KEY_MIME, &audio/mp4a-latm&);
format.setInteger(MediaFormat.KEY_BIT_RATE, mQuality.bitRate);
format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
format.setInteger(MediaFormat.KEY_SAMPLE_RATE, mQuality.samplingRate);
format.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);
format.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, bufferSize);
mMediaCodec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
mAudioRecord.startRecording();
mMediaCodec.start();
final MediaCodecInputStream inputStream = new MediaCodecInputStream(mMediaCodec);
final ByteBuffer[] inputBuffers = mMediaCodec.getInputBuffers();
mThread = new Thread(new Runnable() {
public void run() {
int len = 0, bufferIndex = 0;
while (!Thread.interrupted()) {
bufferIndex = mMediaCodec.dequeueInputBuffer(10000);
if (bufferIndex&=0) {
inputBuffers[bufferIndex].clear();
len = mAudioRecord.read(inputBuffers[bufferIndex], bufferSize);
if (len ==
AudioRecord.ERROR_INVALID_OPERATION || len == AudioRecord.ERROR_BAD_VALUE) {
Log.e(TAG,&An error occured with the AudioRecord API !&);
//Log.v(TAG,&Pushing raw audio to the decoder: len=&+len+& bs: &+inputBuffers[bufferIndex].capacity());
mMediaCodec.queueInputBuffer(bufferIndex, 0, len, System.nanoTime()/1000, 0);
} catch (RuntimeException e) {
e.printStackTrace();
mThread.start();
// The packetizer encapsulates this stream in an RTP stream and send it over the network
mPacketizer.setDestination(mDestination, mRtpPort, mRtcpPort);
mPacketizer.setInputStream(inputStream);
mPacketizer.start();
mStreaming =
/** Stops the stream. */
public synchronized void stop() {
if (mStreaming) {
if (mMode==MODE_MEDIACODEC_API) {
Log.d(TAG, &Interrupting threads...&);
mThread.interrupt();
mAudioRecord.stop();
mAudioRecord.release();
mAudioRecord =
super.stop();
* Returns a description of the stream using SDP. It can then be included in an SDP file.
* Will fail if called when streaming.
public String getSessionDescription() throws IllegalStateException {
if (mSessionDescription == null) throw new IllegalStateException(&You need to call configure() first !&);
return mSessionD
* Records a short sample of AAC ADTS from the microphone to find out what the sampling rate really is
* On some phone indeed, no error will be reported if the sampling rate used differs from the
* one selected with setAudioSamplingRate
* @throws IOException
* @throws IllegalStateException
@SuppressLint(&InlinedApi&)
private void testADTS() throws IllegalStateException, IOException {
setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
Field name = MediaRecorder.OutputFormat.class.getField(&AAC_ADTS&);
setOutputFormat(name.getInt(null));
catch (Exception ignore) {
setOutputFormat(6);
String key = PREF_PREFIX+&aac-&+mQuality.samplingR
if (mSettings!=null) {
if (mSettings.contains(key)) {
String[] s = mSettings.getString(key, &&).split(&,&);
mQuality.samplingRate = Integer.valueOf(s[0]);
mConfig = Integer.valueOf(s[1]);
mChannel = Integer.valueOf(s[2]);
final String TESTFILE = Environment.getExternalStorageDirectory().getPath()+&/spydroid-test.adts&;
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
throw new IllegalStateException(&No external storage or external storage not ready !&);
// The structure of an ADTS packet is described here: http://wiki.multimedia.cx/index.php?title=ADTS
// ADTS header is 7 or 9 bytes long
byte[] buffer = new byte[9];
mMediaRecorder = new MediaRecorder();
mMediaRecorder.setAudioSource(mAudioSource);
mMediaRecorder.setOutputFormat(mOutputFormat);
mMediaRecorder.setAudioEncoder(mAudioEncoder);
mMediaRecorder.setAudioChannels(1);
mMediaRecorder.setAudioSamplingRate(mQuality.samplingRate);
mMediaRecorder.setAudioEncodingBitRate(mQuality.bitRate);
mMediaRecorder.setOutputFile(TESTFILE);
mMediaRecorder.setMaxDuration(1000);
mMediaRecorder.prepare();
mMediaRecorder.start();
// We record for 1 sec
// TODO: use the MediaRecorder.OnInfoListener
Thread.sleep(2000);
} catch (InterruptedException e) {}
mMediaRecorder.stop();
mMediaRecorder.release();
mMediaRecorder =
File file = new File(TESTFILE);
RandomAccessFile raf = new RandomAccessFile(file, &r&);
// ADTS packets start with a sync word: 12bits set to 1
while (true) {
if ( (raf.readByte()&0xFF) == 0xFF ) {
buffer[0] = raf.readByte();
if ( (buffer[0]&0xF0) == 0xF0)
raf.read(buffer,1,5);
mSamplingRateIndex = (buffer[1]&0x3C)&&2 ;
mProfile = ( (buffer[1]&0xC0) && 6 ) + 1 ;
mChannel = (buffer[1]&0x01) && 2 | (buffer[2]&0xC0) && 6 ;
mQuality.samplingRate = AUDIO_SAMPLING_RATES[mSamplingRateIndex];
// 5 bits for the object type / 4 bits for the sampling rate / 4 bits for the channel / padding
mConfig = mProfile&&11 | mSamplingRateIndex&&7 | mChannel&&3;
Log.i(TAG,&MPEG VERSION: & + ( (buffer[0]&0x08) && 3 ) );
Log.i(TAG,&PROTECTION: & + (buffer[0]&0x01) );
Log.i(TAG,&PROFILE: & + AUDIO_OBJECT_TYPES[ mProfile ] );
Log.i(TAG,&SAMPLING FREQUENCY: & + mQuality.samplingRate );
Log.i(TAG,&CHANNEL: & + mChannel );
raf.close();
if (mSettings!=null) {
Editor editor = mSettings.edit();
editor.putString(key, mQuality.samplingRate+&,&+mConfig+&,&+mChannel);
if (!file.delete()) Log.e(TAG,&Temp file could not be erased&);
Copyright(C)
OKBASE.NET All Rights Reserved 好库网 版权所有AAC ADTS音频解码之路 - Firefly-RK3288 - Firefly开源社区 -
Powered by Discuz! Archiver
jingjin221
AAC ADTS音频解码之路
本帖最后由 jingjin221 于
11:51 编辑
我这里有一份从TS流中解复用过后的AAC码流,用OMXCODEC来解码始终解码不出来,请大家帮忙验证一下,红色部分为错误打印信息E/OMXCodec(6058):& &
ERROR(0x95)
经过调试发现,是在SoftAAC2::onQueueFilledaacDecoder_ConfigRaw 出问题了导致如上问题!
参考 .cn/s/blog_645b74b90101e9br.html 这个帖子得知在向AAC解码器送真实数据前会调用aacDecoder_ConfigRaw 去重新获取aac的一些信息,如sampleRate和numChannels,保存在CStreamInfo结构体中。而我是直接送的音频数据包括ADTS头部
但是要送的这个起始数据究竟是如何得到的呢?我尝试播放M4A的歌曲来查看这个起始数据,发现起始数据一般是2个字节,但是具体内容就不同了!求大神分析!我尝试自己伪造起始数据,aacDecoder_ConfigRaw通过了,但是解码的时候还是失败了啊!!!
jingjin221
本帖最后由 jingjin221 于
11:53 编辑
经过半天的调试,AAC解码已经正常结贴了吧!做如下总结,也可以希望以后的同学们少走弯路
1.我起初在OMXCODEC下调试,MP3解码没有问题,AAC始终不行,调试发现是由于少送了CSD信息,另外需要设置关键配置meta-&setInt32(kKeyIsADTS, 1);于是自己根据ADTS HEADER构造了CSD信息,但是送入解码器总是出现奇奇怪怪的问题。实在无法解释,于是放弃OMXCODEC,利用ACODEC来解码
2.利用ACODEC解码在JAVA层也就是MEDIACODEC,需要配置信息如下
& && &if(audio_cfg.stream_type == AUDIO_MP3)
& && && && && & mimetype = MEDIA_MIMETYPE_AUDIO_MPEG;
& && && && && & format-&setString(&mime&, mimetype);
& && && && && & s-&mSampleRate = audio_cfg.sampling_
& && &else if(audio_cfg.stream_type == AUDIO_AAC_ADTS)
& && && && && & mimetype = MEDIA_MIMETYPE_AUDIO_AAC;
& && && && && & format-&setString(&mime&, mimetype);
& && && && && & s-&mSampleRate = audio_cfg.sampling_frequency/2;
& && && && && & format-&setInt32(&is-adts&, 1);
& && && && && & format-&setInt32(&aac-profile&, 0x0002);
& && &channel_configuration = audio_cfg.channel_
& && &format-&setInt32(&sample-rate&, s-&mSampleRate);
& && &format-&setInt32(&channel-count&, channel_configuration);
当然还需自己构造CSD头部,参考如下ADTS解析函数
static int AAC_ADTS_header_parse(uint8_t *p_data)
& & uint8_t mpeg_version, layer, profile, sampling_frequency_index, channel_
& & uint16_t frame_
& & if(!((p_data == 0xFF) && ((p_data & 0xF0) == 0xF0)))& && &//ADTS syncword all 12 bits must be 1
& && &return -1;
& & para.audio.stream_type = AUDIO_AAC_ADTS;
& & 0 for MPEG-4
& & 1 for MPEG-2
& & mpeg_version = (p_data&0x08) && 3;
& & printf(&mpeg_version is %d\n&, mpeg_version);
& & 0: Main profile
& & 1: Low Complexity profile (LC)
& & 2: Scalable Sampling Rate profile (SSR)
& & 3: (reserved)
& & profile = (p_data&0xC0)&&6;
& & printf(&profile is %d\n&, profile);
& & para.audio.profile =
& & There are 13 supported frequencies:
& & 0: 96000 Hz
& & 1: 88200 Hz
& & 2: 64000 Hz
& & 3: 48000 Hz
& & 4: 44100 Hz
& & 5: 32000 Hz
& & 6: 24000 Hz
& & 7: 22050 Hz
& & 8: 16000 Hz
& & 9: 12000 Hz
& & 10: 11025 Hz
& & 11: 8000 Hz
& & 12: 7350 Hz
& & 13: Reserved
& & 14: Reserved
& & 15: frequency is written explictly
& & unsigned int Sampling_Frequencies = {9, 6, 4, 2, 1, 1, 7350};
& & sampling_frequency_index = (p_data&0x3C) && 2;& &//check the table Sampling Frequencies
& & printf(&sampling_frequency_index is %d\n&, sampling_frequency_index);
& & para.audio.sampling_frequency = Sampling_F
& & 0: Defined in AOT Specifc Config
& & 1: 1 channel: front-center
& & 2: 2 channels: front-left, front-right
& & 3: 3 channels: front-center, front-left, front-right
& & 4: 4 channels: front-center, front-left, front-right, back-center
& & 5: 5 channels: front-center, front-left, front-right, back-left, back-right
& & 6: 6 channels: front-center, front-left, front-right, back-left, back-right, LFE-channel
& & 7: 8 channels: front-center, front-left, front-right, side-left, side-right, back-left, back-right, LFE-channel
& & 8-15: Reserved
& & channel_configuration = ((p_data&0x01) && 1) | ((p_data&0xC0)&&6);& &
& & printf(&channel_configuration is %d\n&, channel_configuration);
& & para.audio.channel_configuration = channel_
& & para.audio.csd = (profile && 4) | (sampling_frequency_index && 1);
& & para.audio.csd = ((sampling_frequency_index & 0x01) && 7) | (channel_configuration && 3);
& & printf(&csd-0\n&, para.audio.csd, para.audio.csd);
& & return 0;
3.不知道为什么在AAC下,明明解析出来的采样率是48K,送进解码器出来的声音明显频率高了,我只要在初始化的时候进行了分频操作!
4.ACODEC比OMXCODEC靠谱多了,也许是该死是READ造成的吧!5.在送数据的时候其实并不用剥去ADTS头部
6.靠谱的ANDROID论坛还是.国内怎么就出不了这种网站呢?
jingjin221
再附上音频解码的核心代码吧!static int audio_decoder_init(StagefrightContext *s, struct audio_config audio_cfg){
#ifdef AUDIO_DECODER
//#define PCM_FILE_PLAY_DEBUG
#ifdef PCM_FILE_PLAY_DEBUG
& & & & audio_pcm_play(s);
& & & & return 0;
& & & & int ret = 0;
& & & & sp&MetaData&
& & & & const char*
& & & & int32_t channel_
& & & & printf(&%s_%d\n&, __FUNCTION__,__LINE__);
#if (defined OMXCODEC)
& & & & meta = new MetaD
& & & & if (meta == NULL) {
& & & & & & & & printf(&cannot allocate MetaData&);
& & & & & & & & return -1;
& & & & if(audio_cfg.stream_type == AUDIO_MP3)
& & & & & & & & mimetype = MEDIA_MIMETYPE_AUDIO_MPEG;
& & & & & & & & meta-&setCString(kKeyMIMEType, mimetype);
& & & & else if(audio_cfg.stream_type == AUDIO_AAC_ADTS)
& & & & & & & & mimetype = MEDIA_MIMETYPE_AUDIO_AAC;
& & & & & & & & meta-&setCString(kKeyMIMEType, mimetype);
& & & & & & & & meta-&setInt32(kKeyIsADTS, 1);
& & & & & & & & meta-&setInt32(kKeyAACProfile, 0x0002);
& & & & s-&mSampleRate = audio_cfg.sampling_
& & & & channel_configuration = audio_cfg.channel_
& & & & meta-&setInt32(kKeySampleRate, s-&mSampleRate);
& & & & meta-&setInt32(kKeyChannelCount, channel_configuration);
& & & & s-&mAudioSource = new sp&MediaSource&();
& & & & *s-&mAudioSource= new CStageFrightAudioSource(s, meta);
& & & & if (s-&mAudioSource == NULL) {
& & & & & & & & s-&mAudioSource = NULL;
& & & & & & & & printf(&Cannot obtain source / mClient&);
& & & & & & & & return -1;
& & & & if (s-&mClient.connect() !=OK) {
& & & & & & & & printf(&Cannot connect OMX mClient\n&);
& & & & & & & & ret = -1;
& & & & & & & &
& & & & & & }
& & & & s-&mAudioDecoder= new sp&MediaSource&();
& & & & printf(&[%s]@OMXCodec::Create____________________________START\n&, __FUNCTION__);
& & & & *s-&mAudioDecoder = OMXCodec::Create(s-&mClient.interface(),
& & & & & & & & meta,
& & & & & & & & false,
& & & & & & & & *s-&mAudioSource,
& & & & & & & & NULL,
& & & & & & & & OMXCodec::kSoftwareCodecsOnly,
& & & & & & & & NULL);
& & & & if (!(s-&mAudioDecoder != NULL && (*s-&mAudioDecoder)-&start() ==OK)) {
& & & & & & & & printf(&[%s]@Cannot start decoder\n&, __FUNCTION__);
& & & & & & & & ret = -1;
& & & & & & & & s-&mClient.disconnect();
& & & & & & & & s-&mAudioSource = NULL;
& & & & & & & & s-&mAudioDecoder = NULL;
& & & & & & & &
& & & & printf(&[%s]@OMXCodec::Create____________________________END\n&, __FUNCTION__);
#elif (defined ACODEC)
& & & & sp&AMessage&
& & & & format = new AM
& & & & if(format == NULL) {
& & & & & & & & printf(&cannot allocate format\n&);
& & & & & & & & return -1;
& & & & if(audio_cfg.stream_type == AUDIO_MP3)
& & & & & & & & mimetype = MEDIA_MIMETYPE_AUDIO_MPEG;
& & & & & & & & format-&setString(&mime&, mimetype);
& & & & & & & & s-&mSampleRate = audio_cfg.sampling_
& & & & else if(audio_cfg.stream_type == AUDIO_AAC_ADTS)
& & & & & & & & mimetype = MEDIA_MIMETYPE_AUDIO_AAC;
& & & & & & & & format-&setString(&mime&, mimetype);
& & & & & & & & s-&mSampleRate = audio_cfg.sampling_frequency/2;
& & & & & & & & format-&setInt32(&is-adts&, 1);
& & & & & & & & format-&setInt32(&aac-profile&, 0x0002);
& & & & channel_configuration = audio_cfg.channel_
& & & & format-&setInt32(&sample-rate&, s-&mSampleRate);
& & & & format-&setInt32(&channel-count&, channel_configuration);
& & & & printf(&[%s]@ACodec::Create____________________________START\n&, __FUNCTION__);
& & & & sp&ALooper& mLooper = new AL
& & & & mLooper-&setName(&MediaCodec_Adio_looper&);
& & & & mLooper-&start(
& & & && && && &false,& && &// runOnCallingThread
& & & && && && &false,& && & // canCallJava
& & & && && && &PRIORITY_FOREGROUND);
& & & & s-&mACodecAudioDecoder = MediaCodec::CreateByType(
& && && && && & mLooper, mimetype, false /* encoder */);
& & & & if(s-&mACodecAudioDecoder == NULL)
& & & & & & & & printf(&Failed to create mACodecAudioDecoder\n&);
& & & & & & & & return -1;
& & & & ret = s-&mACodecAudioDecoder-&configure(
& && && && && & format, NULL /* surface */,
& && && && && & NULL /* crypto */,
& && && && && & 0 /* flags */);
& & & & if(ret != OK)
& & & & & & & & printf(&Failed to configure mACodecAudioDecoder\n&);
& & & & & & & & return -1;
& & & & printf(&[%s]@ACodec::Create____________________________END\n&, __FUNCTION__);
& & & & ret= s-&mACodecAudioDecoder-&start();
& & & & if(ret != OK)
& & & & & & & & printf(&Failed to start mACodecAudioDecoder\n&);
& & & & & & & & return -1;
& & & & ret = s-&mACodecAudioDecoder-&getInputBuffers(&s-&mAudioInBuffers);
& & & & if(ret != OK)
& & & & & & & & printf(&Failed to getInputBuffers mACodecAudioDecoder\n&);
& & & & & & & & return -1;
& & & & ret = s-&mACodecAudioDecoder-&getOutputBuffers(&s-&mAudioOutBuffers);
& & & & if(ret != OK)
& & & & & & & & printf(&Failed to getOutputBuffers mACodecAudioDecoder\n&);
& & & & & & & & return -1;
& & & & printf(&got %d input and %d output buffers&, s-&mAudioInBuffers.size(), s-&mAudioOutBuffers.size());
#endif& & & &
static void* audio_decode_sound_thread(void *arg)
& & & & status_
& & & & StagefrightContext *s = (StagefrightContext*)
& & & & MediaBuffer *buffer = NULL;
& & & & printf(&[%s]Thread id:%d/n&, __FUNCTION__, gettid());
& & & & if(audio_decoder_init(s, para.audio) == -1)
& & & & & & & & return NULL;
& & & & size_t frameCount = 0;
& & & & if (AudioTrack::getMinFrameCount(&frameCount, AUDIO_STREAM_DEFAULT, s-&mSampleRate) != NO_ERROR) {
& & & && &return NULL;
& & & & int nbChannels = 2;
& & & & int audioFormat = ENCODING_PCM_16BIT;
& & & & size_t size =frameCount * nbChannels * (audioFormat == ENCODING_PCM_16BIT ? 2 : 1);
& & & & printf(&size is %d, s-&mSampleRate is %d\n&, size, s-&mSampleRate);
& & & & s-&mAudioTrack = new AudioTrack(AUDIO_STREAM_MUSIC,
& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & s-&mSampleRate,
& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & AUDIO_FORMAT_PCM_16_BIT,
& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & AUDIO_CHANNEL_OUT_STEREO,
& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & 0,
& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & AUDIO_OUTPUT_FLAG_NONE,
& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & NULL,
& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & NULL,
& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & 0);
& & & & if ((err = s-&mAudioTrack-&initCheck()) != OK) {
& & & & & & & & printf(&AudioTrack initCheck failed\n&);
& & & & & & & & s-&mAudioTrack.clear();
& & & & s-&mAudioTrack-&setVolume(1.0f);
& & & & s-&mAudioTrack-&start();
#if (defined OMXCODEC)
& & & & while(1)
& & & & & & & & status_t status = (*s-&mAudioDecoder)-&read(&buffer, NULL);
& & & & & & & & if (status == OK) {& & & &
& & & & & & & & & & & & printf(&%s@AUDIO DECODER OK\n&, __FUNCTION__);
& & & & & & & & & & & & if (buffer-&range_length() == 0)
& & & & & & & & & & & & {
& & & & & & & & & & & & & & & & printf(&%s:ERROR_BUFFER_TOO_SMALL\n&, __FUNCTION__);
& & & & & & & & & & & & & & & & status = ERROR_BUFFER_TOO_SMALL;
& & & & & & & & & & & & & & & & buffer-&release();
& & & & & & & & & & & & & & & & buffer = NULL;
& & & & & & & & & & & & & & & &
& & & & & & & & & & & & }
& & & & & & & & & & & & //printf(&BUFFER RANGE LENGTH[%d]\n&, buffer-&range_length());
& & & & & & & & }
& & & & & & & & else
& & & & & & & & & & & & ;//printf(&%s@AUDIO DECODER NOT OK\n&, __FUNCTION__);
& & & & & & & & if(status == OK) {
& & & & & & & & & & & & sp&MetaData& outFormat = (*s-&mAudioDecoder)-&getFormat();
& & & & & & & & & & & & outFormat-&findInt32(kKeySampleRate, &s-&mSampleRate);
& & & & & & & & & & & & printf(&SAMPLERATE[%d]\n&, s-&mSampleRate);
& & & & & & & & }
& & & & & & & & if (status == OK) {& & & &
& & & & & & & & & & & & s-&mAudioTrack-&write(buffer-&data(), buffer-&range_length());
& & & & & & & & & & & & buffer-&release();
& & & & & & & & & & & & buffer = NULL;
& & & & & & & & }
#elif (defined ACODEC)
& & & & static int first_flag =
& & & & int sampleS
& & & & static int64_t kTimeout_audio = 10000;
& & & & size_t inI
& & & & size_t outI
& & & & size_
& & & & size_
& & & & int64_t presentationTimeUs;
& & & & uint32_
& & & & while(1)
& & & & & & & & err = s-&mACodecAudioDecoder-&dequeueInputBuffer(&inIndex, kTimeout_audio);
& & & & & & & & if (err == OK) {
& & & & & & & & & & & & //printf(&filling input buffer %d\n&, inIndex);
& & & & & & & & & & & &
& & & & & & & & & & & & const sp&ABuffer& &buffer = s-&mAudioInBuffers.itemAt(inIndex);
if((para.audio.stream_type == AUDIO_AAC_ADTS) && first_flag)
& & & & & & & & memcpy((uint8_t *)buffer-&data(), para.audio.csd, 2);
& & & & & & & & sampleSize = 2;
& & & & & & & & first_flag =
& & & & & & & & & & & & sampleSize = audio_read_one_frame((uint8_t *)buffer-&data());
& & & & & & & & & & & & presentationTimeUs = 0;
& & & & & & & & & & & & if(sampleSize &= 0)
& & & & & & & & & & & & & & & &
& & & & & & & & & & & & if (buffer-&capacity() & sampleSize) {
& & & & & & & & & & & & & & & & printf(&buffer capacity overflow\n&);
& & & & & & & & & & & & & & & &
& & & & & & & & & & & & }
& & & & & & & & & & & &
& & & & & & & & & & & & buffer-&setRange(0, sampleSize);
& & & & & & & & & & & &
& & & & & & & & & & & & err = s-&mACodecAudioDecoder-&queueInputBuffer(
& & & & & & & & & & & & & & & & inIndex,
& & & & & & & & & & & & & & & & 0 /* offset */,
& & & & & & & & & & & & & & & & buffer-&size(),
& & & & & & & & & & & & & & & & presentationTimeUs,
& & & & & & & & & & & & & & & & 0 /* flag*/);
& & & & & & & & & & & & //printf(&queueInputBuffer err is %d\n&, err);
& & & & & & & & }
& & & & & & & & err = s-&mACodecAudioDecoder-&dequeueOutputBuffer(&outIndex, &offset, &len, &presentationTimeUs, &flags, kTimeout_audio);
& & & & & & & & //printf(&dequeueOutputBuffer err is %d\n&, err);
& & & & & & & & if (err == OK) {
& & & & & & & & & & & & & & & & s-&mACodecAudioDecoder-&getOutputBuffers(&s-&mAudioOutBuffers);
& & & & & & & & & & & & & & & & //printf(&got %d output buffers&, s-&mAudioOutBuffers.size());
& & & & & & & & & & & & & & & & const sp&ABuffer& &buffer = s-&mAudioOutBuffers.itemAt(outIndex);
& & & & & & & & & & & & & & & & //printf(&output buffers[%d] size[%d]\n&,outIndex, buffer-&size());
& & & & & & & & & & & & & & & & s-&mAudioTrack-&write(buffer-&data(), buffer-&size());
& & & & & & & & & & & & & & & & s-&mACodecAudioDecoder-&releaseOutputBuffer(outIndex);
& & & & & & & & }
技术贴,顶起来~
你好,我也遇到同样的问题,可以请教一下吗。我的QQ:
jingjin221
你好,我也遇到同样的问题,可以请教一下吗。我的QQ:
你能告诉我哪些文件萤火虫SDK改变 - https://bitbucket.org/T-Firefly/firenow-lollipop/src修复AAC ADTS?
然后,可以在标记红色部分改变或增加
Can you tell me which files to change in Firefly SDK - https://bitbucket.org/T-Firefly/firenow-lollipop/src to fix AAC ADTS?
Then can mark parts in red to change or add.
jingjin221
dewettie 发表于
你能告诉我哪些文件萤火虫SDK改变 - https://bitbucket.org/T-Firefly/firenow-lollipop/src修复AAC...
你的软硬件平台是什么?
jingjin221 发表于
你的软硬件平台是什么?
萤火虫RK3288 - 棒棒堂5.1 - Firenow SDK
HPH RK3288电视盒 - 棒棒堂5.1 - Firenow SDK
下面是我使用SDK的源代码的框架文件夹 - https://bitbucket.org/T-Firefly/firenow-lollipop/src/1c8f102b1847793bccf265be39738e/frameworks?at=Firefly-RK3288.请告诉哪些文件要修改或添加为您修复。
Firefly RK3288 - Lollipop 5.1 - Firenow SDK
HPH RK3288 TV Box - Lollipop 5.1 - Firenow SDK
Here is the frameworks folder of the source code of the SDK I use - https://bitbucket.org/T-Firefly/firenow-lollipop/src/1c8f102b1847793bccf265be39738e/frameworks?at=Firefly-RK3288. Please tell which files to modify or add for your fix.
查看完整版本:}

我要回帖

更多关于 axure如何生成流程图 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信