FFmpeg源码:avio_read_partial函数分析

=================================================================

AVIOContext结构体和其相关的函数分析:

FFmpeg源码:avio_r8、avio_rl16、avio_rl24、avio_rl32、avio_rl64函数分析

FFmpeg源码:read_packet_wrapper、fill_buffer函数分析

FFmpeg源码:avio_read函数分析

FFmpeg源码:avio_seek函数分析

FFmpeg源码:avio_skip函数分析

FFmpeg源码:avio_tell函数分析

FFmpeg源码:ffurl_seek2、ffurl_seek、avio_size函数分析

FFmpeg源码:avio_feof函数分析

FFmpeg源码:avio_read_partial函数分析

=================================================================

一、avio_read_partial函数的声明

avio_read_partial函数声明在FFmpeg源码(本文演示用的FFmpeg源码版本为7.0.1)的头文件libavformat/avio.h中:

/*** Read size bytes from AVIOContext into buf. Unlike avio_read(), this is allowed* to read fewer bytes than requested. The missing bytes can be read in the next* call. This always tries to read at least 1 byte.* Useful to reduce latency in certain cases.* @return number of bytes read or AVERROR*/
int avio_read_partial(AVIOContext *s, unsigned char *buf, int size);

该函数的作用是:

情况一:如果该媒体文件被打开是为了进行写入,对本地媒体文件或网络流进行读取,读取size个字节,将读上来的数据保存到形参buf指向的缓冲区中。

情况二:如果该媒体文件被打开不是为了进行写入,首先判断AVIOContext输入缓冲区中的数据被读取的状态,根据结果又会分为下面两种情况:

1.如果输入缓冲区中没有数据或者数据已被读完,通过文件描述符去读取本地媒体文件中的数据,或者通过socket接收网络流中的数据,让读上来的数据填满整个AVIOContext输入缓冲区。再读取输入缓冲区的数据,尝试读取size个字节,如果输入缓冲区读完了还没到size个字节,不继续进行读取。

2.如果输入缓冲区中存在数据且数据还未被读完,读取输入缓冲区的数据,尝试读取size个字节。如果输入缓冲区读完了还没到size个字节,不继续进行读取。

该函数的用法跟avio_read函数比较相似,不同点在于:avio_read函数保证读取size个字节数据(除非出错)。而使用avio_read_partial函数,即使输入缓冲区读取完了还没到size个字节,也不会继续对本地媒体文件或网络流进行读取,而是直接返回。由于从输入缓冲区(内存)读取的速度是远高于从本地媒体文件(硬盘)或网络流(socket)读取的,所以跟avio_read函数相比,使用avio_read_partial函数在某些情况下可用于减少延迟。

形参s:既是输入型参数也是输出型参数。指向一个AVIOContext(字节流上下文结构体)变量。执行avio_read函数后,s->buf_ptr等成员会发生相应变化。

形参buf:输出型参数。保存读上来的数据的缓冲区。

形参size:输入型参数。要读取的字节数。

返回值:返回一个非负数表示成功,此时返回实际读取到的字节数;返回一个负数表示出错。

二、avio_read_partial函数的定义

avio_read_partial函数定义在源文件libavformat/aviobuf.c中:

int avio_read_partial(AVIOContext *s, unsigned char *buf, int size)
{int len;if (size < 0)return AVERROR(EINVAL);if (s->read_packet && s->write_flag) {len = read_packet_wrapper(s, buf, size);if (len > 0)s->pos += len;return len;}len = s->buf_end - s->buf_ptr;if (len == 0) {fill_buffer(s);len = s->buf_end - s->buf_ptr;}if (len > size)len = size;memcpy(buf, s->buf_ptr, len);s->buf_ptr += len;if (!len) {if (s->error)      return s->error;if (avio_feof(s))  return AVERROR_EOF;}return len;
}

三、avio_read_partial函数的内部实现分析

avio_read_partial函数中,首先判断要读取的字节数是否小于0,如果小于0,返回AVERROR(EINVAL)表示出错:

    if (size < 0)return AVERROR(EINVAL);

如果指向读取数据包的回调函数存在(s->read_packet为真),并且该媒体文件被打开是为了写入的(s->write_flag为真),通过read_packet_wrapper函数对本地媒体文件或网络流进行读取,读取size个字节,将读上来的数据保存到形参buf指向的缓冲区中,返回实际读取到的字节数:

    if (s->read_packet && s->write_flag) {len = read_packet_wrapper(s, buf, size);if (len > 0)s->pos += len;return len;}

 如果不满足上面情况,判断AVIOContext输入缓冲区中还有多少数据未被读取。如果输入缓冲区中没有数据或者数据已被读完,调用fill_buffer函数,通过文件描述符去读取本地媒体文件中的数据,或者通过socket接收网络流中的数据,让读上来的数据填满整个AVIOContext输入缓冲区。重新得到AVIOContext输入缓冲区中未被读取的数据的字节数,赋值给变量len:

    len = s->buf_end - s->buf_ptr;if (len == 0) {fill_buffer(s);len = s->buf_end - s->buf_ptr;}

读取输入缓冲区的数据,尝试读取size个字节。如果输入缓冲区读取完了还没到size个字节,不继续进行读取:

    if (len > size)len = size;memcpy(buf, s->buf_ptr, len);s->buf_ptr += len;

成功读取,返回实际读取到的字节数;否则返回负数表示出错:

    if (!len) {if (s->error)      return s->error;if (avio_feof(s))  return AVERROR_EOF;}return len;

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

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

相关文章

编译器gcc/g++

gcc 只用来编译C g 编译C/C 1.预处理&#xff08;进行宏替换/去注释/条件编译/头文件展开等&#xff09; 先创建 code.c 文件 -E --> 从现在开始&#xff0c;进行程序的翻译&#xff0c;一旦预处理做完&#xff0c;就停下来 -o --> 表明 -o 后面的文件名称 code…

wordpress建DTC独立站为产品添加价格区间选择

要在WordPress中为DTC独立站的产品添加价格区间选择功能&#xff0c;可以通过以下步骤实现&#xff1a; 添加自定义字段&#xff1a;首先&#xff0c;需要在产品后台添加一个自定义字段&#xff0c;用于设置价格区间的最大值。这可以通过添加代码到子主题的 function.php 文件…

一.安装版本为19c的Oracle数据库管理系统(Oracle系列)

1.数据库版本信息&#xff1a; 版本信息&#xff1a; 或者直接由命令查出来&#xff1a; 2.操作系统的版本信息 3.安装包下载与上传 可以去oracle官网下载也可以从其他人的百度网盘链接中下载&#xff1a; 使用xftp工具或者其他的工具&#xff08;mobaxterm&#xff09;上传到l…

DimensionX 部署笔记

目录 生成视频用CogVideoX-5b-I2V 推理代码&#xff1a; DimensionX 生成视频用CogVideoX-5b-I2V 推理代码&#xff1a; 可以生成&#xff0c;从左向右旋转的&#xff0c;也可以生成从上往下旋转的&#xff1a; import torch from diffusers import CogVideoXImageToVideo…

uni-app移动端与PC端兼容预览PDF文件

过程遇到的问题 1、如果用的是最新的版本的pdfjs的话&#xff0c;就会报Promise.withResolvers 不是一个方法的错误&#xff0c;原因是Promise.withResolvers是ES15新特性&#xff0c;想了解可参考链接&#xff0c;这里的解决方案是将插件里的涉及到Promise.withResolvers的地…

Node.js | Yarn下载安装与环境配置

一、安装Node.js Yarn 是 Node.js 下的包管理工具&#xff0c;因此想要使用 Yarn 就必须先下载 Node.js。 推荐参考&#xff1a;Node.js | npm下载安装及环境配置教程 二、Yarn安装 打开cmd&#xff0c;输入以下命令&#xff1a; npm install -g yarn检查是否安装成功&…

简单的卡尔曼滤波器C#代码

用卡尔曼滤波来平滑温度数据&#xff0c;使得温度曲线变得更加平滑&#xff08;即去噪声&#xff0c;避免短期内的剧烈波动&#xff09;。在这种情况下&#xff0c;卡尔曼滤波的目标是基于传感器的噪声数据来估计真实的温度&#xff0c;从而降低噪声的影响。 简单的温度卡尔曼…

开源TTS语音克隆神器GPT-SoVITS_V2版本地整合包部署与远程使用生成音频

文章目录 前言1.GPT-SoVITS V2下载2.本地运行GPT-SoVITS V23.简单使用演示4.安装内网穿透工具4.1 创建远程连接公网地址 5. 固定远程访问公网地址 前言 本文主要介绍如何在Windows系统电脑使用整合包一键部署开源TTS语音克隆神器GPT-SoVITS&#xff0c;并结合cpolar内网穿透工…

分布式系统学习笔记

除了分布式爬虫系统&#xff0c;还有许多分布式系统值得学习和实践&#xff0c;它们在不同领域有广泛应用&#xff0c;积累相关经验对找工作非常有帮助。以下是一些常见的分布式系统类型及学习建议&#xff1a; 1. 分布式存储系统 应用场景&#xff1a; 大规模数据的存储与访…

[Docker#11] 容器编排 | .yml | up | 实验: 部署WordPress

目录 1. 什么是 Docker Compose 生活案例 2. 为什么要使用 Docker Compose Docker Compose 的安装 Docker Compose 的功能 使用步骤 核心功能 Docker Compose 使用场景 Docker Compose 文件&#xff08;docker-compose.yml&#xff09; 模仿示例 文件基本结构及常见…

鸿蒙NEXT应用示例:切换图片动画

【引言】 在鸿蒙NEXT应用开发中&#xff0c;实现图片切换动画是一项常见的需求。本文将介绍如何使用鸿蒙应用框架中的组件和动画功能&#xff0c;实现不同类型的图片切换动画效果。 【环境准备】 电脑系统&#xff1a;windows 10 开发工具&#xff1a;DevEco Studio NEXT B…

Spring Cloud Gateway(分发请求)

Spring Cloud Gateway 的过滤器和 Spring MVC 的拦截器的区别 过滤器用于整个微服务系统的网关层控制&#xff0c;拦截器则用于单个微服务内部的控制层请求处理。 1. 作用范围 Spring Cloud Gateway 过滤器&#xff1a;过滤器的作用范围是在网关层&#xff0c;主要在请求进入后…

【spring 】Spring Cloud Gateway 的Filter学习

介绍和使用场景 Spring Cloud Gateway 是一个基于 Spring Framework 5 和 Project Reactor 的 API 网关&#xff0c;它旨在为微服务架构提供一种简单而有效的方式来处理请求路由、过滤、限流等功能。在 Spring Cloud Gateway 中&#xff0c;Filter 扮演着非常重要的角色&#…

opencv(c++)图像的灰度转换

opencv(c)图像的灰度转换 quickopencv.h #pragma once #include <opencv2/opencv.hpp> using namespace cv; class QuickDemo { public:void colorSpace_Demo(Mat& image); };quickopencv.cpp #include "quickopencv.h"// QuickDemo类中的颜色空间演示函…

problem forward和solution backward有什么区别

Note: 在具体研究中&#xff0c;problem forward是先提出问题&#xff0c;然后围绕着科学问题设计出完美的解决方案&#xff1b;而solution backward是先盘算自己有哪些技术&#xff0c;有哪些解决方案&#xff0c;反过来去寻找和定义问题。

C++构造函数详解

构造函数详解&#xff1a;C 中对象初始化与构造函数的使用 在 C 中&#xff0c;构造函数是一种特殊的成员函数&#xff0c;它在创建对象时自动调用&#xff0c;用来初始化对象的状态。构造函数帮助我们确保每个对象在被创建时就处于一个有效的状态&#xff0c;并且在不传递任何…

LeetCode 445.两数相加 II

题目&#xff1a; 给你两个 非空 链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。 你可以假设除了数字 0 之外&#xff0c;这两个数字都不会以零开头。 思路&#xff1a;反转链表 两数相加 I 代码&…

使用WebSocket技术实现Web应用中的实时数据更新

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 使用WebSocket技术实现Web应用中的实时数据更新 使用WebSocket技术实现Web应用中的实时数据更新 使用WebSocket技术实现Web应用中…

基于STM32的智能路灯控制系统设计

引言 随着城市建设的发展&#xff0c;路灯管理逐渐成为智慧城市建设的重要组成部分。传统路灯系统无法根据环境条件进行智能调节&#xff0c;导致能源浪费。本项目基于STM32微控制器设计了一种智能路灯控制系统&#xff0c;系统能够根据光照强度和周围人员活动情况&#xff0c…

奇文网盘部署指南

内容来自官方 官方地址 https://pan.qiwenshare.com/docs/guide/install.html#%E5%90%8E%E5%8F%B0 #下载编译 #后台 git clone https://gitee.com/qiwen-cloud/qiwen-file.git本项目是本质上是一个maven工程&#xff0c;因此&#xff0c;在命令行执行普通的maven编译命令即可…