一、file_read函数
file_read函数定义在FFmpeg源码(本文演示用的FFmpeg源码版本为7.0.1)的源文件libavformat/file.c中:
#define FFMIN(a,b) ((a) > (b) ? (b) : (a))
static int file_read(URLContext *h, unsigned char *buf, int size)
{
FileContext *c = h->priv_data;
int ret;
size = FFMIN(size, c->blocksize);
ret = read(c->fd, buf, size);
if (ret == 0 && c->follow)
return AVERROR(EAGAIN);
if (ret == 0)
return AVERROR_EOF;
return (ret == -1) ? AVERROR(errno) : ret;
}
该函数的作用是:读取文件描述符为h->priv_data->fd的文件内容,存入形参buf指向的空间中。可以看到该函数内部调用C语言的read函数来读取文件内容。
形参h:输入型参数。 指向一个url(Uniform Resource Locator)上下文结构体。
形参buf:输出型参数。读上来的数据保存在缓冲区buf中。
形参size:输入型参数。要读取的字节数。
返回值:返回实际读取到的字节数。返回AVERROR_EOF表示调用该函数前已到达文件末尾,返回AVERROR(errno)表示出错。
二、file_write函数
file_write函数定义在源文件libavformat/file.c中:
#define FFMIN(a,b) ((a) > (b) ? (b) : (a))
static int file_write(URLContext *h, const unsigned char *buf, int size)
{
FileContext *c = h->priv_data;
int ret;
size = FFMIN(size, c->blocksize);
ret = write(c->fd, buf, size);
return (ret == -1) ? AVERROR(errno) : ret;
}
该函数的作用是:将数据写入文件描述符为h->priv_data->fd的文件内。可以看到该函数内部调用了C语言的write函数来将数据写入文件。
形参h:输入型参数。 指向一个url(Uniform Resource Locator)上下文结构体。
形参buf:输入型参数。指向“存放需要写入到文件或网络流中的数据的缓冲区”。
形参size:输入型参数。要写入文件的字节数。
返回值:返回一个非负数表示写入成功,此时返回实际写入文件的字节数;返回AVERROR(errno)表示出错。
三、file_seek函数
(一)file_seek函数的定义
file_seek函数定义在源文件libavformat/file.c中:
/* XXX: use llseek */
static int64_t file_seek(URLContext *h, int64_t pos, int whence)
{
FileContext *c = h->priv_data;
int64_t ret;
if (whence == AVSEEK_SIZE) {
struct stat st;
ret = fstat(c->fd, &st);
return ret < 0 ? AVERROR(errno) : (S_ISFIFO(st.st_mode) ? 0 : st.st_size);
}
ret = lseek(c->fd, pos, whence);
return ret < 0 ? AVERROR(errno) : ret;
}
该函数的作用是:
情况1,whence的值等于AVSEEK_SIZE时, 返回文件描述符为h->priv_data->fd的文件的大小但不改变读写位置。
情况2,whence的值不等于AVSEEK_SIZE时,改变读写一个文件时读写指针位置。每一个已打开的文件都有一个读写位置,当打开文件时通常其读写位置是指向文件开头,若是以附加的方式打开文件(如O_APPEND),则读写位置会指向文件尾。当read()或write()时,读写位置会随之增加,file_seek函数中使用了lseek()函数来控制该文件的读写位置。
形参h:输入型参数。 指向一个url(Uniform Resource Locator)上下文结构体。
形参pos:输入型参数。仅当whence的值不等于AVSEEK_SIZE时有意义,为偏移量,即每一读写操作所需要移动的距离,单位是字节的数量,可正可负(向前移,向后移)。
形参whence:输入型参数。whence为下列其中一种:
/**
* ORing this as the "whence" parameter to a seek function causes it to
* return the filesize without seeking anywhere. Supporting this is optional.
* If it is not supported then the seek function will return <0.
*/
#define AVSEEK_SIZE 0x10000
/* The possibilities for the third argument to `fseek'.
These values should not be changed. */
#define SEEK_SET 0 /* Seek from beginning of file. */
#define SEEK_CUR 1 /* Seek from current position. */
#define SEEK_END 2 /* Seek from end of file. */
AVSEEK_SIZE:表示不改变读写位置,仅获取文件大小。
SEEK_SET:将读写位置指向文件头后再增加offset个位移量。
SEEK_CUR:以目前的读写位置往后增加offset个位移量。
SEEK_END:将读写位置指向文件尾后再增加offset个位移量。
当whence值为SEEK_CUR或SEEK_END时,参数offet允许负值的出现。
返回值:
whence的值等于AVSEEK_SIZE时,返回文件描述符为h->priv_data->fd的文件的大小,返回AVERROR(errno)表示出错;
whence的值不等于AVSEEK_SIZE时,返回非负数为目前的读写位置,也就是距离文件开头多少个字节,返回AVERROR(errno)表示出错。
(二)file_seek函数的用法示例
file_seek(h,0,AVSEEK_SIZE):不改变读写位置,返回文件描述符为h->priv_data->fd的文件的大小;
file_seek(h,0,SEEK_SET):将读写位置移到文件描述符为h->priv_data->fd的文件的开头,此时返回0;
file_seek(h,0,SEEK_END):将读写位置移到文件尾,此时返回文件描述符为h->priv_data->fd的文件的大小;
file_seek(h,0,SEEK_CUR):取得目前文件位置。此时返回当前读写位置距离文件开头多少个字节;