x264_param_default_preset(¶ms, “ultrafast”, “zerolatency”);//优化编码延迟?
变量参数编码前赋值:
params.i_csp = (csp == 17) ? X264_CSP_NV12 : csp;//编码比特流的CSP,仅支持i420,色彩空间设置
#ifdef SQUARE_AND_ROTATE
params.i_width = w;
params.i_height = h;
#else
params.i_width = width;
params.i_height = height;
#endif
params.vui.i_sar_width = 1;
params.vui.i_sar_height = 1; //设置长宽比
params.i_fps_num = fpsnum;//帧率分子
params.i_fps_den = fpsden;//帧率分母
params.i_timebase_num = 1;
params.i_timebase_den = 1000;//ms
params.i_keyint_max = fpsnum/fpsden;
params.i_keyint_min = fpsnum/fpsden;//X264_KEYINT_MIN_AUTO
params.b_repeat_headers = 0;//
params.b_annexb = 0;
params.b_deblocking_filter = 1;
params.rc.f_rf_constant = 33;
params.rc.i_bitrate = bitrate;
初始化编码器:
enc = x264_encoder_open(¶ms);
获取整个流的pps和SPS:
int s = x264_encoder_headers(enc, &nals, &nal_count);
x264编码:
初始化图片信息:
x264_picture_t picin, picout;
x264_picture_init(&picin);
对图片信息参数设定:
picin.i_pts = ts;
picin.i_type = X264_TYPE_AUTO;
picin.i_qpplus1 = 0;
picin.img.i_csp = (csp == 17) ? X264_CSP_NV12 : csp;//special hack for android
。。。。。。。
。。。。。。。
。。。。。
对帧进行x264编码:
ret = x264_encoder_encode(enc, &nals, &nnal, &picin, &picout);
总结
(1)初始化并设定x264_param_t
(2)初始化并设定 x264_picture_t
(3)x264编码
二、音频编解码·实战篇WAV转至AAC(AAC编码)
这里利用FAAC来实现AAC编码。另外,WAV的数据段是PCM,代码会出
现很多PCM缩写。
1 下载安装 FAAC
这里的安装过程是在 Mac 和 Linux 上实现的,Windows可以类似参考。
wget http://downloads.sourceforge.net/faac/faac-1.28.tar.gz
tar zxvf faac-1.28.tar.gz
cd faac-1.28
./configure
make
sudo make install
如果才用默认的 configure 中的 prefix path,那么安装后的 lib 和 .h 文件分别在/usr/local/lib
和/usr/local/include
,后面编译的时候会用到。
2 FAAC API
2.1 Open FAAC engine
Prototype:
faacEncHandle faacEncOpen
// 返回一个FAAC的handle(
unsigned long nSampleRate, // 采样率,单位是bps
unsigned long nChannels, // 声道,1为单声道,2为双声道
unsigned long &nInputSamples, // 传引用,得到每次调用编码时所应接收的原始数据长度
unsigned long &nMaxOutputBytes // 传引用,得到每次调用编码时生成的AAC数据的最大长度);
2.2 Get/Set encoding configuration
Prototype:
获取编码器的配置:
faacEncConfigurationPtr faacEncGetCurrentConfiguration // 得到指向当前编码器配置的指针
(
faacEncHandle hEncoder // FAAC的handle
);
设定编码器的配置:
int FAACAPI faacEncSetConfiguration
(
faacDecHandle hDecoder, // 此前得到的FAAC的handle
faacEncConfigurationPtr config // FAAC编码器的配置
);
2.3 Encode
Prototype:
int faacEncEncode
(
faacEncHandle hEncoder, // FAAC的handle
short *inputBuffer, // WAV原始数据
unsigned int samplesInput, // 调用faacEncOpen时得到的nInputSamples值
unsigned char *outputBuffer,// 至少具有调用faacEncOpen时得到的nMaxOutputBytes字节长度的缓冲区
unsigned int bufferSize // outputBuffer缓冲区的实际大小
);
2.4 Close FAAC engine
Prototype
void faacEncClose
(
faacEncHandle hEncoder // 此前得到的FAAC handle
);
3 流程
3.1 做什么准备?
采样率,声道数(双声道还是单声道?),还有你的WAV的单个样本是8位的还是16位的?
3.2 开启FAAC编码器,做编码前的准备
- 调用
faacEncOpen
开启FAAC编码器后,得到了单次输入样本数nInputSamples
和输出数据最大字节数nMaxOutputBytes
; - 根据
nInputSamples
和nMaxOutputBytes
,分别为WAV数据和将要得到的AAC数据创建缓冲区; - 调用
faacEncGetCurrentConfiguration
获取当前配置,修改完配置后,调用faacEncSetConfiguration
设置新配置。
3.3 开始编码
调用faacEncEncode
,该准备的刚才都准备好了,很简单。
3.4 善后
关闭编码器,另外别忘了释放缓冲区,如果使用了文件流,也别忘记了关闭。
4 测试程序
4.1 完整代码
将WAV
格式音频文件/home/michael/Development/testspace/in.wav
转至AAC
格式文件/home/michael/Development/testspace/out.aac
。
#include <faac.h>
#include <stdio.h>
typedef unsigned long ULONG;
typedef unsigned int UINT;
typedef unsigned char BYTE;
typedef char _TCHAR;
int main(int argc, _TCHAR* argv[])
{
ULONG nSampleRate = 11025; // 采样率
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; // WAV file for input
FILE* fpOut; // AAC file for output
fpIn = fopen(“/home/michael/Development/testspace/in.wav”, “rb”);
fpOut = fopen(“/home/michael/Development/testspace/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 = new BYTE [nPCMBufferSize];
pbAACBuffer = new BYTE [nMaxOutputBytes];
// (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);
// (3) Encode
nRet = faacEncEncode(
hEncoder, (int*) pbPCMBuffer, nInputSamples, pbAACBuffer, nMaxOutputBytes);
fwrite(pbAACBuffer, 1, nRet, fpOut);
printf(“%d: faacEncEncode returns %d\n”, i, nRet);
最后
小编这些年深知大多数初中级Android工程师,想要提升自己,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人
都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
如果你需要这些资料, ⬅ 专栏获取
xfRF-1719183608853)]
[外链图片转存中…(img-wr3sJnoQ-1719183608854)]
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人
都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
如果你需要这些资料, ⬅ 专栏获取