记录FFmpeg遇见的坑

这篇博客记录了在使用FFmpeg过程中遇到的一些问题,包括音频帧克隆失败、解码后编码导致的卡顿、AAC文件时长错误、RTMP流连接超时以及音频编码警告等,并给出了相应的解决办法。同时提到了编译MP3lame和x264的相关步骤,以及内存管理在避免声音问题中的作用。
摘要由CSDN通过智能技术生成

利用av_frame_clone可以将一个frame clone后,其实也只是v_frame_alloc()+av_frame_ref()。但是有时候在音频帧的clone后不知道为什么会导致了返回了NULL。这个时候就懵逼了。这个debug进去后发现了一个问题,就是channel_layout没有设置导致的。这个因为是我手动设置解码器,所以忘记弄了,这个一般直接读取的话没有那个错误。


假如你用ffmpeg解码后再进行编码,不知为什么如果源过快时候会发现画面卡顿,音频声音差,只要你将输入源sleep,情况明显改善。这时,其实是内存污染作怪。在ffmpeg里面,解码后的avframe内存还是归ffmpeg管理,当你每次读包解码时候,过快这样就会导致那种情况了。你要做的是用av_frame_clone,那样的话那个就可以了。


假如你将一个音频文件转码成aac文件结尾的文件,这个时候你会发现有个问题是,不知道为什么文件的播放时间总是会比我们实际的时间会长,而且这种长度会随着本来的音频时间长度成线性关系增加。这时,你可能会怀疑自己的编码是不是哪里出了问题。但事实上不是,那是因为aac文件播放本来就有adts,而在ffmpeg里面计算aac文件播放的duration时间,跟踪源码发现ffmpeg里面计算文件是长度是对比视频跟音频的长度,取其最大的。代码如下



static void estimate_timings_from_bit_rate(AVFormatContext *ic)
{
    int64_t filesize, duration;
    int i, show_warning = 0;
    AVStream *st;

    /* if bit_rate is already set, we believe it */
    if (ic->bit_rate <= 0) {
        int64_t bit_rate = 0;
        for (i = 0; i < ic->nb_streams; i++) {
            st = ic->streams[i];
            if (st->codecpar->bit_rate <= 0 && st->internal->avctx->bit_rate > 0)
                st->codecpar->bit_rate = st->internal->avctx->bit_rate;
            if (st->codecpar->bit_rate > 0) {
                if (INT64_MAX - st->codecpar->bit_rate < bit_rate) {
                    bit_rate = 0;
                    break;
                }
                bit_rate += st->codecpar->bit_rate;
            } else if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->codec_info_nb_frames > 1) {
                // If we have a videostream with packets but without a bitrate
                // then consider the sum not known
                bit_rate = 0;
                break;
            }
        }
        ic->bit_rate = bit_rate;
    }

    /* if duration is already set, we believe it */
    if (ic->duration == AV_NOPTS_VALUE &&
        ic->bit_rate != 0) {
        filesize = ic->pb ? avio_size(ic->pb) : 0;
        if (filesize > ic->internal->data_offset) {
            filesize -= ic->internal->data_offset;
            for (i = 0; i < ic->nb_streams; i++) {
                st      = ic->streams[i];
             
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Android中的FFmpeg库提供了强大的功能,可以用来实现行车记录仪的视频录制功能。 首先,我们需要在Android项目中集成FFmpeg库。可以通过在build.gradle文件中添加FFmpeg库的依赖来实现。然后,在代码中使用JNI来调用FFmpeg库的相关功能。 接下来,我们需要实现视频录制的逻辑。首先,要初始化音视频的采集参数,包括视频帧率、分辨率、音频采样率等。然后,通过Android的Camera API来获取相机实例,并设置预览参数。接着,通过FFmpeg来编码音视频数据,并将编码后的数据写入到视频文件中。 在录制过程中,我们可以通过Android的传感器API获取设备的加速度、方向等信息,以及通过GPS模块获取位置信息,并将这些信息写入到视频文件的metadata中。 另外,为了提高录制的实时性和稳定性,我们可以使用多线程技术来实现数据的采集、编码和写入操作,并使用缓冲队列来平衡不同线程之间的数据传输。此外,也可以通过设置合理的编码参数,如码率、GOP等来控制视频文件的质量和大小。 最后,当需要停止录制时,我们只需要释放相机资源,并关闭FFmpeg的编码和写入操作,最终生成的视频文件就是我们所期望的行车记录仪视频。 综上所述,通过Android中的FFmpeg库,我们可以实现行车记录仪的视频录制功能,并将视频、音频数据以及其他相关信息进行编码和写入。这样,我们就可以轻松实现行车记录仪这种实用的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值