FFmpeg开发之旅(二)---音频解码

【写在前面】

        前面我介绍了视频解码的流程,发现基础讲得有点少。

        因此这里附上一些额外的基础内容:理解PCM音频数据格式

        本篇主要内容:

        1、FFmpeg音频解码基本流程

        2、libswresample的基本使用方法


 【正文开始】

        实际上音频解码和视频解码的流程是一样的,因此就不花篇幅讲流程了。

        这里先简单说一下不同的地方:

    //找到音频流的索引
    audioIndex = av_find_best_stream(formatContext, AVMEDIA_TYPE_AUDIO, -1, -1, nullptr, 0);

        在第二个参数,改为 AVMEDIA_TYPE_AUDIO 即可。

        然后从解复用到解码出 PCM,和视频解码的流程是一样的。

        视频解码见:https://blog.youkuaiyun.com/u011283226/article/details/100868821

        当然,本篇文章就这样结束也不太好,那么就简单讲一下关于 libswresample 的使用方法吧。

        libswresample 是FFmpeg提供的重采样( Resample )库,所谓的重采样也可以简单理解为:样本转换,因此 libswresample 提供一组高度优化的样本转换函数,不管是采样类型,声道格式等等都可以进行转换。

        要想使用 libswresample,首先得分配一个SwrContext ,它有两种分配方式:

        1、使用 swr_alloc() 分配一个 SwrContext 指针,并且必须使用 av_opt_set_*() 来设置参数。

具体的参数在 FFmpeg 源码下的 libswresample / options.c 中。

如果你下载了Qt的源码,那么其中就包含了FFmpeg的源码( 因为 Chromium 源码包含FFmpeg,而Qt包含 Chromium ),它在 qtwebengine 中。

        2、使用 swr_alloc_set_opts() 分配的同时设置一些参数。

    SwrContext *swrContext = swr_alloc_set_opts(nullptr, int64_t(codecContext->channel_layout), AV_SAMPLE_FMT_S32, codecContext->sample_rate,
                                                int64_t(codecContext->channel_layout), codecContext->sample_fmt, codecContext->sample_rate,
                                                0, nullptr);
    swr_init(swrContext);

        我使用第二种方式分配,因为这里不需要那么多参数。

        注意,分配了 SwrContext 后,必须使用 swr_init() 来进行初始化。

        然后,当我们使用 avcodec_receive_frame() 获取到一帧解码的数据后,就可以进行转换了:

    int size = av_samples_get_buffer_size(nullptr, frame->channels, frame->nb_samples, AV_SAMPLE_FMT_S32, 0);
    uint8_t *buf = new uint8_t[size];
    swr_convert(swrContext, &buf, frame->nb_samples, const_cast<const uint8_t**>(frame->data), frame->nb_samples);
    delete[] buf;

        1、使用 av_samples_get_buffer_size() 来获取给定音频参数所需的缓冲大小。

        2、new (分配) 一个缓冲区。

        3、使用 swr_convert() 来进行转换,in -> out。

因为FFmpeg的注释已经足够详细了,所以我从不讲参数。

        4、转换完成后的数据存储在 buf 中了,记住别忘了 delete。 


【结语】

        本篇实在是没什么好写的,因为FFmpeg的抽象,所以解码视频和音频的流程基本差不多。

        不过,解码字幕的时候倒是有些不同,这在后面会进行讲解的。

        最后,附上项目地址:https://github.com/mengps/FFmpeg-Learn,可以自己尝试一下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦起丶

您的鼓励和支持是我创作最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值