【FFmpeg】FFmpeg 内存结构 ③ ( AVPacket 函数简介 | av_packet_ref 函数 | av_packet_clone 函数 )

news2024/11/23 17:34:39

文章目录

  • 一、av_packet_ref 函数
    • 1、函数原型
    • 2、函数源码分析
    • 3、函数使用代码示例
  • 二、av_packet_clone 函数
    • 1、函数原型
    • 2、函数源码分析


FFmpeg 4.0 版本源码地址 :

  • GitHub : https://github.com/FFmpeg/FFmpeg/tree/release/4.0
  • GitCode : https://gitcode.com/gh_mirrors/ff/FFmpeg/tree/release/4.0
  • FFmpeg/libavcodec/avpacket.c 源码 : https://gitcode.com/gh_mirrors/ff/FFmpeg/blob/release/4.0/libavcodec/avpacket.c




一、av_packet_ref 函数




1、函数原型


av_packet_ref 函数 用于 将 源 AVPacket 结构体的属性 和 buf 数据引用 拷贝复制给 目标 AVPacket 结构体 , AVPacket 中的 实际数据 不会进行复制 , 新创建的 AVPacket 只会复制 实际音视频数据的 指针地址 , 函数原型如下 :

int av_packet_ref(AVPacket *dst, const AVPacket *src)
  • 函数功能 :

    • 将 src 的 结构体字段 复制到 dst ;
    • 拷贝 数据的引用 , 并增加 src 中底层数据的引用计数 ; 拷贝的是引用 , 不会对 src 中的实际数据缓冲区进行内存复制 , 避免不必要的性能开销 ;
  • 参数解析 :

    • AVPacket *dst 参数 : 指向 目标 AVPacket 的指针 , 被赋值的对象 ;
    • const AVPacket *src 参数 : 指向 源 AVPacket 的指针 , 数据源 , 被拷贝的对象 ;
  • 返回值 :

    • 拷贝成功 , 返回 0 ;
    • 拷贝失败 , 返回 负值 , 该负值表示错误码 ;

2、函数源码分析


av_packet_ref 函数的源码如下 :

  • 分析该函数的源码可知 , 该函数执行两个操作 , 分别是 :
    • 第一步 : 复制 源 结构体 中的 字段值 到 目标结构体 中 ;
    • 第二步 : 将 原结构体 的 数据缓冲区 引用 赋值给 目标 数据缓冲区 引用 , 注意 这里 只 复制引用 , 不复制数据 ;
  • 该函数中直接为 AVPacket 结构体字段辅助 , 因此执行该函数之前 , 目标 AVPacket 必须是已经分配好内存 ;
int av_packet_ref(AVPacket *dst, const AVPacket *src)
{
    int ret;

    // 复制源包(src)的属性到目标包(dst),包括时间戳、流索引等元数据。
    ret = av_packet_copy_props(dst, src);
    if (ret < 0)  // 如果属性复制失败,则返回错误码。
        return ret;

    // 检查源包是否有缓冲区 (buf),如果没有,说明需要分配新的缓冲区。
    if (!src->buf) {
        // 为目标包分配缓冲区,大小为源包的数据大小。
        ret = packet_alloc(&dst->buf, src->size);
        if (ret < 0)  // 如果缓冲区分配失败,跳转到错误处理。
            goto fail;
        
        // 如果源包的数据大小不为 0,将数据从源包复制到目标包的缓冲区。
        if (src->size)
            memcpy(dst->buf->data, src->data, src->size);

        // 将目标包的 data 指针指向分配的缓冲区。
        dst->data = dst->buf->data;
    } else {
        // 如果源包有缓冲区,通过引用计数创建缓冲区的引用。
        dst->buf = av_buffer_ref(src->buf);
        if (!dst->buf) {  // 如果引用创建失败,返回内存分配错误。
            ret = AVERROR(ENOMEM);
            goto fail;
        }
        // 目标包的 data 指针直接指向源包的 data。
        dst->data = src->data;
    }

    // 将源包的大小复制到目标包。
    dst->size = src->size;

    // 如果执行成功,返回 0。
    return 0;

fail:
    // 如果发生错误,释放目标包的附加数据(如 side data)以防止资源泄漏。
    av_packet_free_side_data(dst);
    return ret;  // 返回错误码。
}

3、函数使用代码示例


代码示例 :

#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>

int main() {
    AVPacket src_pkt, dst_pkt;

    // 初始化源包和目标包
    // av_init_packet 初始化 AVPacket 结构体,为其成员赋初始值。
    av_init_packet(&src_pkt);
    av_init_packet(&dst_pkt);

    // 为源包分配内存并假设数据已填充
    // src_pkt.data 指向分配的 100 字节内存,用于模拟填充数据。
    src_pkt.data = av_malloc(100);
    src_pkt.size = 100; // 数据大小设置为 100 字节。

    // 创建引用
    // av_packet_ref 创建目标包 dst_pkt 对源包 src_pkt 的引用。
    // 如果失败,打印错误信息并返回 -1。
    if (av_packet_ref(&dst_pkt, &src_pkt) < 0) {
        fprintf(stderr, "Failed to create packet reference.\n");
        return -1;
    }

    // 此时,src_pkt 和 dst_pkt 共享同一底层数据
    // 打印源包和目标包的数据大小以验证共享关系。
    printf("src size: %d, dst size: %d\n", src_pkt.size, dst_pkt.size);

    // 释放引用
    // 使用 av_packet_unref 释放源包和目标包的引用,减少引用计数。
    av_packet_unref(&src_pkt);
    av_packet_unref(&dst_pkt);

    return 0;
}




二、av_packet_clone 函数




1、函数原型


av_packet_clone 函数 用于 克隆一个完整的 AVPacket , 该函数实际上相当于 av_packet_alloc 函数 + av_packet_ref 函数 ;

AVPacket *av_packet_clone(const AVPacket *src)
  • const AVPacket *src 参数 : 指向 需要克隆的源 AVPacket 的指针 ;
  • 返回值 :
    • 拷贝成功 : 返回一个指向 新克隆的 AVPacket 的指针 ;
    • 拷贝失败 : 返回 NULL , 通常是因为内存分配失败 ;

2、函数源码分析


在下面的 av_packet_clone 函数源码中可以分析处 , av_packet_clone 函数相当于

av_packet_alloc 函数 和 av_packet_ref 函数 的总体效果 ;

在 av_packet_clone 函数中 , 先调用了 av_packet_alloc 函数 , 创建 目标 AVPacket ,

然后调用 av_packet_ref 函数 , 将 源 AVPacket 的 数据拷贝给 目标 AVPacket ;

AVPacket *av_packet_clone(const AVPacket *src)
{
    // 为克隆的包分配内存并初始化。
    // 调用 av_packet_alloc 返回一个新的 AVPacket 指针,默认值为初始状态。
    AVPacket *ret = av_packet_alloc();

    // 如果分配失败,直接返回 NULL。
    if (!ret)
        return ret;

    // 使用 av_packet_ref 函数将源包 src 的数据和元信息复制到新包 ret 中。
    // av_packet_ref 返回非零值表示复制失败。
    if (av_packet_ref(ret, src))
        // 如果复制失败,释放已分配的 AVPacket,并将 ret 置为 NULL。
        av_packet_free(&ret);

    // 返回克隆后的 AVPacket 指针(成功)或 NULL(失败)。
    return ret;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2246150.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JavaScript 中 arguments、类数组与数组的深入解析

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: 前端 文章目录 &#x1f4af;前言&#x1f4af;什么是 arguments 对象2.1 arguments 的定义2.2 arguments 的特性2.3 使用场景 &#x1f4af;深入了解 arguments 的结构3.1 arguments 的内部结构arguments 的关键属性 3.2 类数组…

Kafka 工作流程解析:从 Broker 工作原理、节点的服役、退役、副本的生成到数据存储与读写优化

Kafka&#xff1a;分布式消息系统的核心原理与安装部署-CSDN博客 自定义 Kafka 脚本 kf-use.sh 的解析与功能与应用示例-CSDN博客 Kafka 生产者全面解析&#xff1a;从基础原理到高级实践-CSDN博客 Kafka 生产者优化与数据处理经验-CSDN博客 Kafka 工作流程解析&#xff1a…

数位之和c++

题目描述 小杨有 n个正整数&#xff0c;他认为一个正整数是美丽数字当且仅当该正整数每一位数字的总和是 7 的倍数。 小杨想请你编写一个程序判断 n 个正整数哪些是美丽数字。 输入 第一行包含一个正整数 n&#xff0c;代表正整数个数。 之后n 行&#xff0c;每行包含一个…

同三维T4000S系列高清SDI字符叠加器

同三维T4000S系列高清SDI字符叠加器 两个型号&#xff1a; 同三维T4000S-2U (2U机箱&#xff0c;可插1-16张叠加模块) 同三维T4000S1 &#xff08;单路&#xff09; 产品简介 “HD-SDI字符叠加器”可在HD-SDI视频图象信号上叠加日期、时间及中英文字符信息。广泛用于安防监…

重生之我在学环境变量

环境变量 基本概念 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数如&#xff1a;我们在编写C/C代码的时候&#xff0c;在链接的时候&#xff0c;从来不知道我们的所链接的动态静态库在哪里&#xff0c;但 是照样可以链接成功&#…

Flink学习连载文章4-flink中的各种转换操作

首先&#xff0c;先搞一个模板代码&#xff0c;方便后面的操作 #if (${PACKAGE_NAME} && ${PACKAGE_NAME} ! "")package ${PACKAGE_NAME};#end #parse("File Header.java") import org.apache.flink.streaming.api.environment.StreamExecutionEnv…

fastadmin实现站内通知功能

实现效果如下 application/admin/view/common/header.html <style>#notificationMenu {display: none;position: absolute;top: 40px;right: 0;background: #fff;border-radius: 6px;padding: 10px 0;width: 300px;box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);z-inde…

默语博主的推荐:探索技术世界的旅程

这是第一位推荐的博主默语 引言&#xff1a; CSDN中的默语博主是一个值得关注和学习的技术大拿。他的博客内容不仅涵盖了各种热门的技术领域&#xff0c;还能够帮助读者深入了解技术背后的原理和应用。在这篇类博客的内容中&#xff0c;我们将探索默语博主推荐的几篇博客&#…

【漏洞复现】|智互联SRM智联云采系统quickReceiptDetail SQL注入漏洞

漏洞描述 智互联(深圳)科技有限公司SRM智联云采系统针对企业供应链管理难题&#xff0c;及智能化转型升级需求&#xff0c;智联云采依托人工智能、物联网、大数据、云等技术&#xff0c;通过软硬件系统化方案&#xff0c;帮助企业实现供应商关系管理和采购线上化、移动化、智能…

【数据分析】认清、明确

1、什么是数据分析。 - 通过对大量的数据进行科学的分析。 - 得出结论&#xff0c;提出建议&#xff0c;辅助公司企业的决策。2、数据分析分为几步。 - 1.明确目的! - 2.收集数据!自己的数据! 自动化采集的数据! - 3.数据处理! - 4.数据分析!数据分析(业务)数据挖掘(代码算法…

前后端分离,解决vue+axios跨域和proxyTable不生效等问题

看到我这篇文章前可能你以前看过很多类似的文章。至少我是这样的&#xff0c;因为一直没有很好的解决问题。 正文 当我们通过webstorm等IDE开发工具启动项目的时候&#xff0c;通过命令控制台可以观察到启动项目的命令 如下&#xff1a; webpack-dev-server --inline --prog…

WPF中如何让Textbox显示为一条直线

由于Textbox直接使用是一条直线 设置如下代码 可以让Textbox变为直线输入 <Style TargetType"TextBox"x:Key"UsernameTextBoxStyle"><Setter Property"Template"><Setter.Value><ControlTemplate TargetType"{x:Typ…

TSmaster Measurement setup(测量设置)

文章目录 1、Measurement setup功能介绍2、数据流过滤3、Measurement Filter 测量过滤器3.1 插入过滤器3.2 设置过滤数据3.3 过滤条件的失能3.4 窗口缩放 1、Measurement setup功能介绍 Measurement setup 窗体主要包含三个功能&#xff1a; 提供一个面板&#xff0c;用户能够…

[Unity Demo]从零开始制作空洞骑士Hollow Knight第二十集:制作专门渲染HUD的相机HUD Camera和画布HUD Canvas

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、制作HUD Camera以及让两个相机同时渲染屏幕二、制作HUD Canvas 1.制作法力条Soul Orb引入库2.制作生命条Health读入数据3.制作吉欧统计数Geo Counter4.制作…

万字长文解析Golang高性能内存缓存库BigCache

项目地址 BigCache 是一个快速&#xff0c;支持并发访问&#xff0c;自淘汰的内存型缓存&#xff0c;可以在存储大量元素时依然保持高性能。BigCache将元素保存在堆上却避免了GC的开销。 背景介绍 BigCache的作者在项目里遇到了如下的需求&#xff1a; 支持http协议支持 10…

vulfocus在线靶场:骑士cms_cve_2020_35339:latest 速通手册

目录 一、启动环境&#xff0c;访问页面&#xff0c;ip:端口号/index.php?madmin,进入后台管理页面&#xff0c;账号密码都是adminadmin 二、进入之后&#xff0c;根据图片所示&#xff0c;地址后追加一下代码&#xff0c;保存修改 ​三、新开标签页访问&#xff1a;①ip:端…

【数据结构】归并排序 —— 递归及非递归解决归并排序

归并排序 一、归并排序1、归并排序的思想2、归并排序代码实现&#xff08;递归&#xff09;<1> 归并排序的递归区间<2> 归并排序的稳定性<3> 拷贝 3、归并排序代码实现&#xff08;非递归&#xff09;<1> 循环区间溢出问题 二、总结 一、归并排序 1、…

Java技术复习提升 10异常

10 异常 10.1异常介绍及分类 异常捕获 选中后alttabt->选中try-catch 异常就是程序执行中不正常的情况 注意语法和逻辑错误并不是异常 异常分类有两种 error和exception error是错误 虚拟机无法解决的严重问题 exception是其他因为编程错误或者外在因素导致的一般性的问…

transformer.js(三):底层架构及性能优化指南

Transformer.js 是一个轻量级、功能强大的 JavaScript 库&#xff0c;专注于在浏览器中运行 Transformer 模型&#xff0c;为前端开发者提供了高效实现自然语言处理&#xff08;NLP&#xff09;任务的能力。本文将详细解析 Transformer.js 的底层架构&#xff0c;并提供实用的性…

HCIA笔记3--TCP-UDP-交换机工作原理

1. tcp协议 可靠的连接 1.1 报文格式 1.2 三次握手 1.3 四次挥手 为什么TIME_WAIT需要2MSL的等待时间&#xff1f; &#xff08;a&#xff09; 为了实现可靠的关闭 &#xff08;b&#xff09;为了让过期的报文在网络上消失 对于(a), 假设host发给server的last ack丢了。 ser…