//2. 读取待解码数据包
int av_read_frame(AVFormatContext *s, AVPacket *pkt);
对,就是这么简单,就调用 3 个 API 然后循环读取,送入待解码队列中。
FFmpeg 解码音频为 PCM
这里相当于是读取待解码队列中的数据,进行解码为 PCM 数据
//1. 将待解码数据 AVPacket 送入解码器 0 is ok
int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt);
//2. 分配一个 AVFrame 用于接收解码之后的数据
AVFrame *av_frame_alloc(void);
//对应的释放 API
void av_frame_free(AVFrame **frame);
//3. 接收解码之后的数据 0 is ok
int avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame);
//对解码之后的 PCM 进行统一重采样。规定一些格式,避免不统一而渲染异常
//4. 根据传入的参数来分配一个 SwrContext
struct SwrContext *swr_alloc_set_opts(struct SwrContext *s,
int64_t out_ch_layout, enum AVSampleFormat out_sample_fmt, int out_sample_rate,
int64_t in_ch_layout, enum AVSampleFormat in_sample_fmt, int in_sample_rate,
int log_offset, void *log_ctx);
//4.1 对 SwrContext 进行初始化
int swr_init(struct SwrContext *s);
//4.2 开始重采样
int swr_convert(struct SwrContext *s, uint8_t **out, int out_count,
const uint8_t **in , int in_count);
OpenSLES 渲染 PCM
这里还是以流程的形式介绍 API 含义
//1. 创建播放引擎
result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
//2. 创建混音器
const SLInterfaceID mids[1] = {SL_IID_ENVIRONMENTALREVERB};
const SLboolean mreq[1] = {SL_BOOLEAN_FALSE};
result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
result = (*outputMixObject)->GetInterface(outputMixObject, SL_IID_ENVIRONMENTALREVERB,
&outputMixEnvironmentalReverb);
if (SL_RESULT_SUCCESS == result) {
result = (*outputMixEnvironmentalReverb)->SetEnvironmentalReverbProperties(
outputMixEnvironmentalReverb, &reverbSettings);
(void) result;
}
SLDataLocator_OutputMix outputMix = {SL_DATALOCATOR_OUTPUTMIX, outputMixObject};
SLDataSink audioSnk = {&outputMix, 0};
//3. 配置PCM格式信息
SLDataLocator_AndroidSimpleBufferQueue android_queue = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};
SLDataFormat_PCM pcm = {
SL_DATAFORMAT_PCM,//播放pcm格式的数据
2,//2个声道(立体声)
static_cast(getCurSampleRate(sample_rate)),//44100hz的频率
SL_PCMSAMPLEFORMAT_FIXED_16,//位数 16位
SL_PCMSAMPLEFORMAT_FIXED_16,//和位数一致就行
SL_SPEAKER_FRONT_LEFT