• FFMpeg AVFrame 的概念.


    FFMpeg AVFrame 的概念.

    拿这个简单的例子测试一下吧。

    $ cat avframe.c
    #include "libavcodec/avcodec.h"

    // 测试 frame 概念, 查找内存泄漏
    void av_frame_test()
    {
        AVFrame *frame = NULL;
        int ret = 0;

        frame = av_frame_alloc();
        // 1024 *2 * (16/8) =
        frame->nb_samples     = 1024;
        frame->format         = AV_SAMPLE_FMT_S16;//AV_SAMPLE_FMT_S16P AV_SAMPLE_FMT_S16
        frame->channel_layout = AV_CH_LAYOUT_MONO;    //AV_CH_LAYOUT_MONO AV_CH_LAYOUT_STEREO
        ret = av_frame_get_buffer(frame, 0);    // 根据格式分配内存
        if(frame->buf && frame->buf[0])
            printf("%s(%d) 1 frame->buf[0]->size = %d\n", __FUNCTION__, __LINE__, frame->buf[0]->size);    //受frame->format等参数影响
        if(frame->buf && frame->buf[1])
            printf("%s(%d) 1 frame->buf[1]->size = %d\n", __FUNCTION__, __LINE__, frame->buf[1]->size);    //受frame->format等参数影响

        if(frame->buf && frame->buf[0])        // 打印referenc-counted,必须保证传入的是有效指针
            printf("%s(%d) ref_count1(frame) = %d\n", __FUNCTION__, __LINE__, av_buffer_get_ref_count(frame->buf[0]));

        ret = av_frame_make_writable(frame);    // 当frame本身为空时不能make writable
        printf("av_frame_make_writable ret = %d\n", ret);

        if(frame->buf && frame->buf[0])        // 打印referenc-counted,必须保证传入的是有效指针
            printf("%s(%d) ref_count2(frame) = %d\n", __FUNCTION__, __LINE__, av_buffer_get_ref_count(frame->buf[0]));

        av_frame_unref(frame);        // 释放frame, 当bufs refcount 为0时, 会执行buf释放器,释放buf
        if(frame->buf && frame->buf[0])        // 已释放,frame->buf 为0, 不会打印该行了
            printf("%s(%d) ref_count3(frame) = %d\n", __FUNCTION__, __LINE__, av_buffer_get_ref_count(frame->buf[0]));

        av_frame_free(&frame);
    }

    hjj@hjj-OP7090:/$ cat main.c
    #include <stdio.h>
    void av_frame_test();
    int main()
    {
        av_frame_test();
        printf("finished!\n");
        return 0;
    }

    可以查一下AVFrame 在哪里释放内存的,实际上是在这里。

    (gdb) bt
      #0  av_free (ptr=0x5555555595c0) at libavutil/mem.c:224
      #1  0x00007ffff7cea5b5 in av_buffer_default_free (opaque=0x0, data=0x5555555595c0 "") at libavutil/buffer.c:64
      #2  0x00007ffff7cea7b1 in buffer_replace (dst=0x555555559460, src=0x0) at libavutil/buffer.c:120
      #3  0x00007ffff7cea808 in av_buffer_unref (buf=0x555555559460) at libavutil/buffer.c:130
      #4  0x00007ffff7cfadc9 in av_frame_unref (frame=0x555555559340) at libavutil/frame.c:563
      #5  0x0000555555555420 in av_frame_test () at avframe.c:29
      #6  0x00005555555554a6 in main () at main.c:5

  • 相关阅读:
    leetcode 9. 回文数
    博客园主题样式更改总结
    Java 序列化和反序列化为什么要实现 Serializable 接口呢?
    交换机与路由技术-16-生成树协议STP
    如何使用mysql binlog 恢复数据
    防火墙导致Linux发送网络报文出现errno等于1的错误码
    2366. 将数组排序的最少替换次数
    Dubbo之多协议、多注册中心、多版本。
    单片机C语言实例:14、音频输出
    计算系统概论ics第五章习题
  • 原文地址:https://blog.csdn.net/hejinjing_tom_com/article/details/125545275