FFmpeg 基本API avio_write函数内部调用流程分析
1、avio_write 函数定义说明
avio_write 是 FFmpeg 中的一个 I/O 函数,它的作用是向流中写入数据。具体来说,它是通过 AVIOContext 来实现的,AVIOContext 是 FFmpeg 中用于抽象 I/O 操作的数据结构。avio_write 在视频/音频数据流中负责向目标文件(例如媒体文件)写入字节数据。
avio_write 的定义大致如下:
int avio_write(AVIOContext *s, const unsigned char *buf, int size);
- 参数:
- s: 一个指向 AVIOContext 的指针。AVIOContext 结构包含了用于读写数据的各种信息,通常它会绑定到一个具体的文件或网络流。
- buf: 要写入的数据缓冲区(字节数组)。
- size: 要写入的字节数。
- 返回值:
- 如果成功,返回写入的字节数。
- 如果失败,返回负值表示错误。
avio_write主要用途:
- 写入音视频数据:它通常用于将解码后的音视频数据写入到输出文件或流中。它的作用是把内存中的数据传递到硬盘、网络或其他存储介质。
- 流媒体:在 FFmpeg 用于处理网络流媒体时,avio_write 用于将编码后的数据通过网络传输到目标服务器。
2、avio_write 内部调用流程
2.1 直接写入模式
if (s->direct && !s->update_checksum) {avio_flush(s);writeout(s, buf, size);return;
}
2.2 缓冲写入模式
do {int len = FFMIN(s->buf_end - s->buf_ptr, size);memcpy(s->buf_ptr, buf, len);s->buf_ptr += len;if (s->buf_ptr >= s->buf_end)flush_buffer(s);buf += len;size -= len;
} while (size > 0);
2.3 writeout 写入函数
static void writeout(AVIOContext *s, const uint8_t *data, int len)
{FFIOContext *const ctx = ffiocontext(s); // 获取内部上下文if (!s->error) {int ret = 0;// 优先使用 write_data_type 回调(支持数据类型标记)if (s->write_data_type)ret = s->write_data_type(s->opaque, data,len,ctx->current_type,ctx->last_time);else if (s->write_packet)ret = s->write_packet(s->opaque, data, len); // 否则使用 write_packet 回调if (ret < 0) {s->error = ret;} else {// 更新内部字节计数ctx->bytes_written += len;s->bytes_written = ctx->bytes_written;// 更新输出大小统计if (s->pos + len > ctx->written_output_size) {ctx->written_output_size = s->pos + len;}}}if (ctx->current_type == AVIO_DATA_MARKER_SYNC_POINT ||ctx->current_type == AVIO_DATA_MARKER_BOUNDARY_POINT) {ctx->current_type = AVIO_DATA_MARKER_UNKNOWN;}ctx->last_time = AV_NOPTS_VALUE;ctx->writeout_count++;s->pos += len;
}