FFmpeg编解码处理4-音频编码

本文是FFmpeg编解码处理系列的第四篇,主要讲解音频编码。内容涵盖打开音频编码器、判断是否需要音频FIFO、音频FIFO接口函数的使用,以及编码音频帧的关键步骤。介绍了在编码过程中如何处理音频帧尺寸变化的问题,以及音频FIFO的作用和实现。
摘要由CSDN通过智能技术生成

FFmpeg 编解码处理系列笔记: [0]. FFmpeg时间戳详解 [1]. FFmpeg编解码处理1-转码全流程简介 [2]. FFmpeg编解码处理2-编解码API详解 [3]. FFmpeg编解码处理3-视频编码 [4]. FFmpeg编解码处理4-音频编码

基于 FFmpeg 4.1 版本。

1. 音频编码

编码使用 avcodec_send_frame() 和 avcodec_receive_packet() 两个函数。

音频编码的步骤: [1] 初始化打开输出文件时构建编码器上下文 [2] 音频帧编码 [2.1] 将滤镜输出的音频帧写入音频 FIFO [2.2] 按音频编码器中要求的音频帧尺寸从音频 FIFO 中取出音频帧 [2.3] 为音频帧生成 pts [2.4] 将音频帧送入编码器,从编码器取出编码帧 [2.5] 更新编码帧流索引 [2.6] 将帧中时间参数按输出封装格式的时间基进行转换

1.1 打开视频编码器

完整源码在 open_output_file() 函数中,下面摘出关键部分:

// 3. 构建AVCodecContext
    if (dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO ||
        dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO)          // 音频流或视频流
    {
        // 3.1 查找编码器AVCodec,本例使用与解码器相同的编码器
        AVCodec *encoder = NULL;
        if ((dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO) && (strcmp(v_enc_name, "copy") != 0))
        {
            encoder = avcodec_find_encoder_by_name(v_enc_name);
        }
        else if ((dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) && (strcmp(a_enc_name, "copy") != 0))
        {
            encoder = avcodec_find_encoder_by_name(a_enc_name);
        }
        else 
        {
            encoder = avcodec_find_encoder(dec_ctx->codec_id);
        }
​
        if (!encoder)
        {
            av_log(NULL, AV_LOG_FATAL, "Necessary encoder not found\n");
            return AVERROR_INVALIDDATA;
        }
        // 3.2 AVCodecContext初始化:分配结构体,使用AVCodec初始化AVCodecContext相应成员为默认值
        AVCodecContext *enc_ctx = avcodec_alloc_context3(encoder);
        if (!enc_ctx)
        {
            av_log(NULL, AV_LOG_FATAL, "Failed to allocate the encoder context\n");
            return AVERROR(ENOMEM);
        }
​
        // 3.3 AVCodecContext初始化:配置图像/声音相关属性
        /* In this example, we transcode to same properties (picture size,
         * sample rate etc.). These properties can be changed for output
         * streams easily using filters */
        if (dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO)
        {
            enc_ctx->height = dec_ctx->height;              // 图像高
            enc_ctx->width = dec_ctx->width;                // 图像宽
            enc_ctx->sample_aspect_ratio = dec_ctx->sample_aspect_ratio; // 采样宽高比:像素宽/像素高
            /* take first format from list of supported formats */
            if (encoder->pix_fmts)  // 编码器支持的像素格式列表
            {
                enc_ctx->pix_fmt
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值