Android端PCM编码AAC的软编和硬编

本文介绍了Android平台下使用libfdk_aac库和MediaCodec进行AAC音频编码的实现过程,包括编码参数配置、PCM到AAC的转换以及编码流程。在libfdk_aac中,涉及了ffmpeg API的使用,而在MediaCodec中,重点是输入输出队列的管理和添加ADTS头部。文章探讨了编码过程中遇到的问题,如pts设置和时间基的调整,并指出硬编码在速度和效率上的优势。
摘要由CSDN通过智能技术生成

第六章的内容有点多,现在学习一下音视频的软编和硬编。

使用libfdk_aac进行编码

书上的源码是采用ffmpeg的api进行编码的,当然你也可单独编译libfdk_aac来进行编码。首先我们还是需要配置采样率,声道,码率等参数进行初始化。
接着我们探测输出文件,让ffmpeg自动根据文件名探测格式。

  int ret;
    av_register_all();
    avFormatContext = avformat_alloc_context();
    LOGI("aacFilePath is %s ", aacFilePath);
    //一种方法
    //先探测格式,然后设置到avFormatContext中
//    AVOutputFormat *fmt = av_guess_format(NULL, aacFilePath, NULL);
//    avFormatContext->oformat = fmt;

    //直接根据输出文件的名字来自动探测格式
    if ((ret = avformat_alloc_output_context2(&avFormatContext, nullptr, nullptr, aacFilePath)) !=
        0) {
        LOGI("avFormatContext   alloc   failed : %s", av_err2str(ret));
        return -1;
    }
    if (ret = avio_open2(&avFormatContext->pb, aacFilePath, AVIO_FLAG_WRITE, nullptr, nullptr)) {
        LOGI("Could not avio open fail %s", av_err2str(ret));
        return -1;
    }

接下来我们创建一个音频流,并且获取音频流的编解码器上下文。

    AVCodec *codec;
    AVSampleFormat preferedSampleFMT = AV_SAMPLE_FMT_S16;
    int preferedChannels = audioChannels;
    int preferedSampleRate = audioSampleRate;
    audioStream = avformat_new_stream(avFormatContext, nullptr);
    audioStream->id = 1;
    avCodecContext = audioStream->codec;

配置编解码上下文的参数,主要需要配置的有

  • 编解码器类型
  • 采样率
  • 比特率
  • 解码器的id,从之前探测的oformat可以获取
  • 采样格式
  • 通道数
  • AAC的规格,大概一下集中
    MPEG-2 AAC LC 低复杂度规格(Low Complexity)
    MPEG-2 AAC Main 主规格
    MPEG-2 AAC SSR 可变采样率规格(Scaleable Sample Rate)
    MPEG-4 AAC LC 低复杂度规格(Low Complexity),现在的手机比较常见的 MP4 文件中的音频部份就包括了该规格音频文件
    MPEG-4 AAC Main 主规格
    MPEG-4 AAC SSR 可变采样率规格(Scaleable Sample Rate)
    MPEG-4 AAC LTP 长时期预测规格(Long Term Predicition)
    MPEG-4 AAC LD 低延迟规格(Low Delay)
    MPEG-4 AAC HE 高效率规格(High Efficiency)
 avCodecContext->codec_type = AVMEDIA_TYPE_AUDIO;
    avCodecContext->sample_rate = audioSampleRate;
    if (publishBitRate > 0) {
        avCodecContext->bit_rate = publishBitRate;
    } else {
        avCodecContext->bit_rate = PUBLISH_BITE_RATE;

    }
    avCodecContext->codec_id = avFormatContext->oformat->audio_codec;
    avCodecContext->sample_fmt = preferedSampleFMT;
    LOGI("audioChannels is %d", audioChannels);
    avCodecContext->channel_layout =
            preferedChannels == 1 ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO;
    avCodecContext->channels = av_get_channel_layout_nb_channels(avCodecContext->channel_layout);
    //配置编码aac规格
    avCodecContext->profile = FF_PROFILE_AAC_LOW;
    LOGI("avCodecContext->channels is %d", avCodecContext->channels);

    if (avFormatContext->oformat->flags & AVFMT_GLOBALHEADER) {
        avCodecContext->flags |= CODEC_FLAG_GLOBAL_HEADER;
    }

找到对应的编解码器,并获取编解码器支持的采样格式,采样率,并进行一定条件下的筛选。书上的代码是如果采样格式不支持就直接使用支持的格式的第一个,采样率选取的是最接近的一个。

  //使用之前探测格式来找
    codec = avcodec_find_encoder(avCodecContext->codec_id);
    if (!codec) {
        LOGI("Couldn't find a valid audio codec");
        return -1;
    }

    if (codec->sample_fmts) {
        /* check if the prefered sample format for this codec is supported.
         * this is because, depending on th
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值