如何把非1024的采样数放入aac编码器

一. aac对数据规格要求

二、代码实现

1.初始化

2.填入数据

3.取数据

三.图解

一. aac对放入的采样数要求

我们知道aac每次接受的字节数是固定的,在之前的文章里有介绍libfdk_aac音频采样数和编码字节数注意

它支持的采样数和编码字节数分别是:

fdk_aac 支持的音频采样率:7350 8000 11025 12000 16000 22050 24000 32000 44100

48000 64000 88200 96000 fdk_aac 样本类型:只支持AV_SAMPLE_FMT_S16输入.

ffmpeg本身自带的aac并不支持AV_SAMPLE_FMT_S16的,需要重采样为AV_SAMPLE_FMT_FLTP
av_opt_set(encodec_ctx_a->priv_data, "profile", "lc", 0);

2048 HE-AAC v1/v2 1024: Default configuration.//AAC-LC 1024

512: Default length in LD/ELD configuration.

480: Length in LD/ELD configuration.

256: Length for ELD reduced delay mode (x2).

240:Length for ELD reduced delay mode (x2).

128: Length for ELD reduced delay mode (x4).

120: Length for ELD reduced delay mode (x4). */

当我们得到的采样数是不规则的,比如decklink的采集卡每次的到的采样数帧率有关,为48000/fps。那么25fps,就是1920,60fps,是800。

那么我们就需要一个缓存,来每次读取1024个采样。

这里使用ffmpeg的重采样的缓存机制

二、代码实现

1.初始化

cpp 复制代码
void swr()
{
    if(asc != NULL) swr_free(&asc);
    asc = swr_alloc_set_opts(asc,
							 AV_CH_LAYOUT_STEREO, AV_SAMPLE_FMT_S16, 48000,
							 AV_CH_LAYOUT_STEREO, AV_SAMPLE_FMT_S16, 48000, 0, 0);
    if (!asc)
	{
		printf("swr_alloc_set_opts failed!\n");
		return ;
	}
	int ret_asc = swr_init(asc);
	if (ret_asc != 0)
	{
		printf("swr_init failed!\n");
		char err[1024] = {0};
		av_strerror(ret_asc, err, sizeof(err) - 1);
		return ;
	}
}

2.填入数据

cpp 复制代码
int fifo_size_1 = 0;
    int len = swr_convert(asc, 0, 0,
    (const uint8_t **)pcm_BMG->data, pcm_BMG->nb_samples); 

3.取数据

cpp 复制代码
  while(1)
    {
        int CIRCLE = 0;
            fifo_size_1 = swr_get_out_samples(asc, 0);
            if (fifo_size_1 >= 1024)
            {
                int len = swr_convert(asc, p_pcm_enc->data, p_pcm_enc->nb_samples,
                                      0, 0);
                if(CIRCLE != 0) p_pcm_enc->pts = p_pcm_enc->pts  + CIRCLE * 1024 * (1000000 / 48000);//第一帧的pts
                else p_pcm_enc->pts = pcm_BMG->pts - (fifo_size_1 - p_pcm_enc->nb_samples) * (1000000 / 48000);
                //long long swr_pts = swr_next_pts(asc, pcm_BMG->pts); 这个函数计算出的pts有误,亦或是我没有用对,望斧正
                CIRCLE++;
            }
            else {break;}
 

        re = avcodec_send_frame(encodec_ctx_a, p_pcm_enc);
        if(send_pkt_a.size != 0 && b_alloc == true) av_packet_unref(&send_pkt_a);

        while (re >= 0)
        {
           re = avcodec_receive_packet(encodec_ctx_a, &send_pkt_a);
        }
  }

三.图解

x:缓存中的采样数
y:这次放入的采样数
p0:取出的1024包的pts
py:这次放入缓存包的pts
则:
p0 = py - (x-y)(1/48000)

相关推荐
yunhuibin3 小时前
ffmpeg面向对象——拉流协议匹配机制探索
学习·ffmpeg
cuijiecheng20189 小时前
音视频入门基础:FLV专题(13)——FFmpeg源码中,解析任意Type值的SCRIPTDATAVALUE类型的实现
ffmpeg·音视频
小神.Chen1 天前
YouTube音视频合并批处理基于 FFmpeg的
ffmpeg·音视频
昱禹3 天前
记一次因视频编码无法在浏览器播放、编码视频报错问题
linux·python·opencv·ffmpeg·音视频
寻找09之夏3 天前
【FFmpeg 深度解析】:全方位视频合成
ffmpeg·音视频
zanglengyu3 天前
ffmpeg取rtsp流音频数据保存声音为wav文件
ffmpeg·音视频
cuijiecheng20183 天前
音视频入门基础:FLV专题(11)——FFmpeg源码中,解析SCRIPTDATASTRING类型的ScriptDataValue的实现
ffmpeg·音视频
汪子熙3 天前
什么是 LDAC、SBC 和 AAC 音频编码技术
ffmpeg·音视频·aac
cpp_learners3 天前
Windows环境 源码编译 FFmpeg
windows·ffmpeg·源码编译·ffmpeg源码编译
cuijiecheng20184 天前
音视频入门基础:FLV专题(8)——FFmpeg源码中,解码Tag header的实现
ffmpeg·音视频