若该文为原创文章,转载请注明原文出处
在传输RTSP时,需要使用到 AAC,T31采集的音频数据为PCM,记录下使用faac库,把PCM数据编码成AAC数据 。
1、硬件:T31X+SC5235
2、开发环境: ubuntu16.04-64bit
3、编译器:mips-gcc540-glibc222-32bit-r3.3.0.tar.gz
注:板子和和WIFI模块是某淘上淘的,使用的是RTL8188,使用的是USB接口,uboot和内核是自己裁剪移植的,内核默认自带WIFI驱动,所以不用移植可以直接使用。
移植过程相对简单,交叉编译一下就可以,基本没问题。
- ./configure --host=mips-linux-gnu --target=mips-linux-gnu --prefix=/home/yifeng/Downloads/faac-1.28/lib
- make
- make install
编译时遇到的问题:
1、mpeg4ip.h:126:58: error: ambiguating new declaration of 'char* strcasestr(const char*, const char*)'
处理:
从123行开始修改此文件mpeg4ip.h,到129行结束。
修改前:
- #ifdef __cplusplus
- extern "C" {undefined
- #endif
- char *strcasestr(const char *haystack, const char *needle);
- #ifdef __cplusplus
- }
- #endif
修改后:
- #ifdef __cplusplus
- extern "C++" {undefined
- #endif
- const char *strcasestr(const char *haystack, const char *needle);
- #ifdef __cplusplus
- }
- #endif
2、在不修改源码的情况下,faac的内存占用非常高,每路音频在13M左右。如果多路音频的话,内存将很快耗尽。
搜索MAX_CHANNELS的定义,默认是6 和64,全部改成1(一般都是单声道)。
重新编译,运行,内存占用降为2.5M左右。
这里测试是把PCM文件编码成AAC,没有实时采集。
把编译好的/faac-1.28/lib/下的so文件拷贝到开发板/usr/lib上。
1、代码
pcm_encode_aac.c
- /*!
- *****************************************************************************
- *
- * Copyright ? 2017-2018 yifeng. All Rights Reserved.
- *
- * \file sample-Ai.c
- * \author yifeng
- * \version 1.0
- * \date 2022年2月3日
- * \brief sample-Ai
- *
- *----------------------------------------------------------------------------
- * \attention
- *
- *
- *****************************************************************************
- */
- /*****************************************************************************
- change history:
- 1.date : 2022年2月3日
- author: yifeng
- change: create file
-
- *****************************************************************************/
-
-
-
- /*==========================================================================================
- 本源程序包括的头文件
- 建议:包含本项目的文件使用 #include "文件名.扩展名" ,
- 包含系统库的文件使用 #include <文件名.扩展名> 。
- ==========================================================================================*/
- #include <unistd.h>
- #include <sys/ioctl.h>
- #include <sys/prctl.h>
- #include <string.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #include <stdint.h>
- #include <errno.h>
- #include <pthread.h>
- #include <semaphore.h>
- #include <fcntl.h>
- #include <sys/time.h>
-
- #include "faac/faac.h"
- #include <imp/imp_audio.h>
- #include <imp/imp_log.h>
-
-
- #define TAG "Sample-AI"
-
- typedef unsigned long ULONG;
- typedef unsigned int UINT;
- typedef unsigned char BYTE;
- typedef char _TCHAR;
-
-
-
- int main(int argc, _TCHAR* argv[])
- {
- ULONG nSampleRate = 16000; // 采样率
- UINT nChannels = 1; // 声道数
- UINT nPCMBitSize = 16; // 单样本位数
- ULONG nInputSamples = 0;
- ULONG nMaxOutputBytes = 0;
-
- int nRet;
- faacEncHandle hEncoder;
- faacEncConfigurationPtr pConfiguration;
-
- int nBytesRead;
- int nPCMBufferSize;
- BYTE* pbPCMBuffer;
- BYTE* pbAACBuffer;
-
- FILE* fpIn; // PCM file for input
- FILE* fpOut; // AAC file for output
-
- fpIn = fopen("in.pcm", "rb");
- fpOut = fopen("out.aac", "wb");
-
- // (1) Open FAAC engine
- hEncoder = faacEncOpen(nSampleRate, nChannels, &nInputSamples, &nMaxOutputBytes);
- if(hEncoder == NULL)
- {
- printf("[ERROR] Failed to call faacEncOpen()\n");
- return -1;
- }
-
- nPCMBufferSize = nInputSamples * nPCMBitSize / 8;
- pbPCMBuffer = malloc(nPCMBufferSize);
- pbAACBuffer = malloc(nMaxOutputBytes);
- printf("nPCMBufferSize is %d, nInputSamples is %d\n", nPCMBufferSize, nInputSamples);
- // (2.1) Get current encoding configuration
- pConfiguration = faacEncGetCurrentConfiguration(hEncoder);
- pConfiguration->inputFormat = FAAC_INPUT_16BIT;
-
- // (2.2) Set encoding configuration
- nRet = faacEncSetConfiguration(hEncoder, pConfiguration);
-
- for(int i = 0; 1; i++)
- {
- // 读入的实际字节数,最大不会超过nPCMBufferSize,一般只有读到文件尾时才不是这个值
- nBytesRead = fread(pbPCMBuffer, 1, nPCMBufferSize, fpIn);
-
- // 输入样本数,用实际读入字节数计算,一般只有读到文件尾时才不是nPCMBufferSize/(nPCMBitSize/8);
- nInputSamples = nBytesRead / (nPCMBitSize / 8);
- printf("nInputSamples is %d\n", nInputSamples);
- // (3) Encode
- nRet = faacEncEncode(
- hEncoder, (int*) pbPCMBuffer, nInputSamples, pbAACBuffer, nMaxOutputBytes);
-
- fwrite(pbAACBuffer, 1, nRet, fpOut);
-
- printf("%d: faacEncEncode returns %d\n", i, nRet);
-
- if(nBytesRead <= 0)
- {
- break;
- }
- }
-
- // (4) Close FAAC engine
- nRet = faacEncClose(hEncoder);
-
- free(pbPCMBuffer);
- free(pbAACBuffer);
- fclose(fpIn);
- fclose(fpOut);
-
- //getchar();
-
- return 0;
- }
Makefile
- INCLUDE=-I./ -I../include
- LIBS= ../lib/glibc/libimp.a ../lib/glibc/libalog.a ../lib/faac/libfaac.a -lpthread -lm -lrt -ldl
- all:pcm_encode_aac
- pcm_encode_aac:
- mips-linux-gnu-gcc -o pcm_encode_aac -O2 -w -march=mips32r2 pcm_encode_aac.c sample-common.c $(INCLUDE) $(LIBS)
- clean:
- rm -rf pcm_encode_aac
库自行添加。
使用make生成可执行文件,通过tftp方式把pcm文件和可执行文件上传到开发板上运行。
如有侵权,请及时联系博主删除。