android librtmp 推送h264流 aac流 基本过程总结五 推流aac

来源:互联网 发布:ubuntu 安装分区建议 编辑:程序博客网 时间:2024/05/22 10:39

android librtmp 推送h264流 aac流 基本过程总结三 推流aac

1,aac 编码初始化
定义编码的结构体
typedef struct AudioEncodeFaacInformation{faacEncHandle   hEncoder;faacEncConfigurationPtr pConfiguration;int init_flag;unsigned long   nInputSamples;unsigned long   nMaxOutputBytes;}AudioEncodeFaac;

int Audio_Encode_Init_Faac(AudioEncodeFaac *args, int nSampleRate, int channel){int ret = 0;if (args == NULL)return -1;memset(args, 0, sizeof(AudioEncodeFaac));args->hEncoder = faacEncOpen(nSampleRate, channel, &args->nInputSamples, &args->nMaxOutputBytes);args->pConfiguration = faacEncGetCurrentConfiguration(args->hEncoder);if (args->pConfiguration == NULL){goto end;}// 设置编码配置信息  /*PCM Sample Input Format0   FAAC_INPUT_NULL         invalid, signifies a misconfigured config1   FAAC_INPUT_16BIT        native endian 16bit2   FAAC_INPUT_24BIT        native endian 24bit in 24 bits      (not implemented)3   FAAC_INPUT_32BIT        native endian 24bit in 32 bits      (DEFAULT)4   FAAC_INPUT_FLOAT        32bit floating point*/args->pConfiguration->inputFormat = FAAC_INPUT_16BIT;// AAC object types   //#define MAIN 1  //#define LOW  2  //#define SSR  3  //#define LTP  4  args->pConfiguration->aacObjectType = LOW;args->pConfiguration->bitRate = 48000;// or 0args->pConfiguration->bandWidth = 64000;//or 0 or 32000args->pConfiguration->useLfe = 1;args->pConfiguration->allowMidside = 1;/*下面可以选择设置*///outputformat 0 = Raw; 1 = ADTS  args->pConfiguration->outputFormat = 1;//1会增加7个字节的头,0则是裸流// 重置编码器的配置信息  ret = faacEncSetConfiguration(args->hEncoder, args->pConfiguration);args->init_flag = 1;end:if (ret < 0){dm_printf("faac set fail");faacEncClose(args->hEncoder);}return ret;}

2, 编码一桢pcm数据
注意:faac默认的是先缓存4帧,这个看faac的源码就知道了,在开始编码,另外一桢采样点个数也是固定的1024
int Audio_Encode_PCM_Faac(AudioEncodeFaac *args, char *buf, char *out_buf, int *len){int ret = 0;if (args == NULL || args->init_flag == 0)return -1;ret  = faacEncEncode(args->hEncoder, (int32_t *)buf, args->nInputSamples, (unsigned char *)out_buf, args->nMaxOutputBytes);if (ret > 0){*len = ret;}return ret;}

3. 释放faac编码资源
int Audio_Encode_Release_Faac(AudioEncodeFaac *args){int ret = 0;if (args == NULL || args->init_flag == 0)return -1;faacEncClose(args->hEncoder);return ret;}
4,获取faac特殊信息
因为rtmp发送aac头的时候需要aac一些基本信息,2个字节,
int Audio_Encode_Get_Faac_Config(AudioEncodeFaac *args, char **buf, int *len){if (args == NULL || args->init_flag == 0)return -1;faacEncGetDecoderSpecificInfo(args->hEncoder, (unsigned char **)buf, (unsigned long int *)len);return 0;}
如果需要了解这两个字节的基本含义可以查看下图
参考链接:http://www.360doc.com/content/15/0720/10/26719081_486151271.shtml

5,rtmp发送aac头
int  send_rtmp_audio_spec(RTMP* m_pRtmp, unsigned char *spec_buf, unsigned int spec_len) {if (m_pRtmp == NULL) {dm_printf("rtmp not connect");return -1;}RTMPPacket * packet = NULL;int ret = 0;    unsigned char * body = NULL;    unsigned int len = 0;    len = spec_len;  /*spec data长度,一般是2*/    packet = (RTMPPacket *)malloc(RTMP_HEAD_SIZE+len+2);    memset(packet,0,RTMP_HEAD_SIZE);    packet->m_body = (char *)packet + RTMP_HEAD_SIZE;    body = (unsigned char *)packet->m_body;    /*AF 00 + AAC RAW data*/    body[0] = 0xAF;    body[1] = 0x00;    memcpy(&body[2],spec_buf,len); /*spec_buf是AAC sequence header数据*/    packet->m_packetType = RTMP_PACKET_TYPE_AUDIO;    packet->m_nBodySize = len + 2;    packet->m_nChannel = 0x05;    packet->m_nTimeStamp = 0;    packet->m_hasAbsTimestamp = 0;    packet->m_headerType = RTMP_PACKET_SIZE_LARGE;    packet->m_nInfoField2 = m_pRtmp->m_stream_id;if (RTMP_IsConnected(m_pRtmp)) {/*调用发送接口*/ret = RTMP_SendPacket(m_pRtmp, packet, TRUE);if (ret != 1) {dm_printf("send_rtmp_audio_spec fail");ret = -1;}}free(packet);return ret;} 


6, rtmp发送一桢aac流
请参考上一节x264的发送过程完成对应的初始化
定义结构体
typedef struct rtmp_infor{char *aac_buf;char *x264_buf;int nal_len[20];int nal_count;int audio_first;int video_first;int init_flag;RTMP *prtmp ;X264Args x264args;AudioEncodeFaac aacargs;}RTMPInfor;

int RTMP_Send_Audio(unsigned char *data, int timestamp)//return 1 result add timestamp{int ret = 0;int len = 0;int spec_len = 0;char *config = NULL;if (data == NULL)return -1;if (!rtmp_infor.init_flag){dm_printf("RTMP_Send Not Init");return -1;}pthread_mutex_lock(&thread_lock_rtmp_send);ret = Audio_Encode_PCM_Faac(&rtmp_infor.aacargs, (char *)data, (char *)rtmp_infor.aac_buf, &len);if (ret < 0){dm_printf("Audio_Encode_PCM_Faac fail");goto end;}if (len > 0){if (rtmp_infor.audio_first == 0){Audio_Encode_Get_Faac_Config(&rtmp_infor.aacargs, &config, &spec_len);send_rtmp_audio_spec(rtmp_infor.prtmp, (unsigned char *)config, spec_len);if (config != NULL)free(config);rtmp_infor.audio_first = 1;}send_rtmp_audio(rtmp_infor.prtmp, (unsigned char *)rtmp_infor.aac_buf, len, timestamp);}end:if (len > 0)ret = 1;pthread_mutex_unlock(&thread_lock_rtmp_send);return ret;}



0 0
原创粉丝点击