FFmpeg源码:ffio_read_indirect函数分析

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

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函数分析

FFmpeg源码:ffio_read_indirect函数分析

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

一、ffio_read_indirect函数的声明

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

cpp 复制代码
/**
 * Read size bytes from AVIOContext, returning a pointer.
 * Note that the data pointed at by the returned pointer is only
 * valid until the next call that references the same IO context.
 * @param s IO context
 * @param buf pointer to buffer into which to assemble the requested
 *    data if it is not available in contiguous addresses in the
 *    underlying buffer
 * @param size number of bytes requested
 * @param data address at which to store pointer: this will be a
 *    a direct pointer into the underlying buffer if the requested
 *    number of bytes are available at contiguous addresses, otherwise
 *    will be a copy of buf
 * @return number of bytes read or AVERROR
 */
int ffio_read_indirect(AVIOContext *s, unsigned char *buf, int size, const unsigned char **data);

该函数的作用是:

情况一:如果AVIOContext输入缓冲区中还未被读取的数据量(s->buf_end - s->buf_ptr)不小于计划要读取的字节数(size),并且该媒体文件被打开是不是为了写入的(!s->write_flag为真),让"*data"指向"输入缓冲区中当前读取到的位置(s->buf_ptr)",然后让s->buf_ptr指向原来的位置之后的size个字节的位置。也就是说,如果AVIOContext输入缓冲区中的数据足够,直接从输入缓冲区中读取数据。

情况二:如果不满足"情况一"的条件(AVIOContext输入缓冲区中的数据不足),首先尝试从输入缓冲区中读取size个字节数据,如果输入缓冲区中没有数据或者数据已被读完或者读完后还不够size个字节,通过文件描述符去读取本地媒体文件中的数据或者通过socket接收网络流中的数据,直到读取到总共size个字节为止(除非出错)。将读取到的数据保存到形参buf指向的缓冲区中,让"*data"指向buf。

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

形参buf:输出型参数。仅当符合上述"情况二"的条件时有意义,保存读上来的数据的缓冲区。

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

形参data:输出型参数。"情况一"和"情况二"时皆有意义,"*data"指向保存读上来的数据的缓冲区。

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

二、ffio_read_indirect函数的定义

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

cpp 复制代码
int ffio_read_indirect(AVIOContext *s, unsigned char *buf, int size, const unsigned char **data)
{
    if (s->buf_end - s->buf_ptr >= size && !s->write_flag) {
        *data = s->buf_ptr;
        s->buf_ptr += size;
        return size;
    } else {
        *data = buf;
        return avio_read(s, buf, size);
    }
}

可以看到该函数内部调用了avio_read函数,可以看作是对avio_read函数的封装。

相关推荐
小狮子安度因1 天前
ffplay数据结构分析
数据结构·ffmpeg
小狮子安度因1 天前
ffplay音频重采样
ffmpeg·音视频
小狮子安度因2 天前
AAC ADTS格式分析
网络·ffmpeg·aac
勘察加熊人2 天前
ffmpeg切割音频
ffmpeg·音视频
xiaohouzi1122333 天前
Python读取视频-硬解和软解
python·opencv·ffmpeg·视频编解码·gstreamer
kimble_xia@oracle4 天前
性能优化笔记
ffmpeg
wang_chao1184 天前
RK3399平台ffmpeg-VPU硬编码录制USB摄像头视频、H264或MJPEG编码
ffmpeg·音视频
鹅毛在路上了5 天前
C++, ffmpeg, libavcodec-RTSP拉流,opencv实时预览
c++·opencv·ffmpeg
Hi202402177 天前
Orin-Apollo园区版本:订阅多个摄像头画面拼接与硬编码RTMP推流
ffmpeg·apollo·orin·图像拼接·图传
蓝纹绿茶7 天前
Python程序使用了Ffmpeg,结束程序后,文件夹中仍然生成音频、视频文件
python·ubuntu·ffmpeg·音视频