ChinaFFmpeg

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 1021|回复: 0

[Linux] FFmpeg 自定义 AVIO 缓冲实现 MP4 数据流的合并和文件写入

[复制链接]
发表于 2024-4-26 15:57:03 | 显示全部楼层 |阅读模式
问题描述
我正在使用 FFmpeg 库进行视频处理,特别是利用 AVIO 定义自定义的内存缓冲区来合并多个视频和音频流生成 MP4 文件。我的目标是将合并后的数据流先缓存在内存中,然后再统一写入到磁盘文件中。这样做的目的是为了减少磁盘 IO 操作和提高性能。
实现细节
我设置了一个自定义的 AVIOContext,使用一个较大的内存缓冲区来暂存数据。在所有数据被处理并存入这个缓冲区后,我再将缓冲区的内容写入到最终的 MP4 文件中。我遇到的问题是,当我将内存缓冲区设定得比较小(例如 512 KB),生成的 MP4 文件无法被正确播放。如果我增加缓冲区的大小(例如到 5 MB),则文件可以正常播放。
具体代码
以下是我设置 AVIO 和处理写入的相关代码片段:
[AppleScript] 纯文本查看 复制代码
// 初始化缓冲区
BufferData* init_buffer(size_t size) {
    BufferData *bd = (BufferData*) av_malloc(sizeof(BufferData));
    if (!bd) return NULL;
    bd->buf = (uint8_t*) av_malloc(size);
    if (!bd->buf) {
        av_free(bd);
        return NULL;
    }
    bd->size = size;
    bd->pos = 0;
    return bd;
}

// 自定义的写入函数
int write_packet(void *opaque, uint8_t *buf, int buf_size) {
    BufferData *bd = (BufferData *)opaque;
    if (bd->pos + buf_size > bd->size) {
        save_buffer_to_file(bd->buf, bd->pos);
        bd->pos = 0;
    }
    memcpy(bd->buf + bd->pos, buf, buf_size);
    bd->pos += buf_size;
    return buf_size;
}

// 缓冲区到文件的写入
void save_buffer_to_file(uint8_t *buffer, size_t size) {
    FILE *file = fopen("output.mp4", "ab");
    if (file) {
        fwrite(buffer, 1, size, file);
        fclose(file);
    } else {
        fprintf(stderr, "Failed to open output file\n");
    }
}
遇到的问题
当我将缓冲区大小设置为较小值时,生成的文件无法播放,出现的具体错误为:“moov atom not found”。而当缓冲区足够大时,该问题不再出现。
寻求的帮助
我想了解是否有更好的方法来管理这种缓冲区写入,以确保即使在较小的缓冲区设置下,也能生成有效的 MP4 文件。另外,我对如何优化这一过程以避免潜在的性能问题也很感兴趣。

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|Archiver|ChinaFFmpeg

GMT+8, 2024-12-27 05:24 , Processed in 0.074760 second(s), 16 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表