FFmpeg --15-视频解码: AVIO内存输入模式分析

文章目录

avio_alloc_context 作用与原理

基本概念

avio_alloc_context() 是FFmpeg中用于创建自定义I/O上下文的核心函数,它允许开发者将内存缓冲区作为FFmpeg的输入或输出源,替代传统的文件I/O操作。

函数原型分析
c 复制代码
AVIOContext *avio_alloc_context(
    unsigned char *buffer,      // FFmpeg使用的数据缓冲区
    int buffer_size,           // 缓冲区大小
    int write_flag,            // 读写标志:0-FFmpeg读,1-FFmpeg写
    void *opaque,              // 用户数据指针,传递给回调函数
    int (*read_packet)(void *opaque, uint8_t *buf, int buf_size),
    int (*write_packet)(void *opaque, uint8_t *buf, int buf_size),
    int64_t (*seek)(void *opaque, int64_t offset, int whence)
);
参数详细说明
参数 说明
buffer 由av_malloc()分配的内存缓冲区,FFmpeg使用该区域进行数据操作
buffer_size 缓冲区大小,影响I/O性能,建议设置为缓存页大小(如4KB)
write_flag 0: FFmpeg从缓冲区读取(输入模式) 1: FFmpeg向缓冲区写入(输出模式)
opaque 用户自定义数据,会作为第一个参数传递给所有回调函数
read_packet 数据读取回调函数,当FFmpeg需要更多数据时调用
write_packet 数据写入回调函数,当缓冲区有数据需要输出时调用
seek 定位回调函数,支持随机访问时使用

回调函数工作机制

read_packet 回调函数
c 复制代码
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
{
    FILE *in_file = (FILE *)opaque;
    int read_size = fread(buf, 1, buf_size, in_file);
    printf("read_packet read_size:%d, buf_size:%d\n", read_size, buf_size);
    if(read_size <=0) {
        return AVERROR_EOF;     // 数据读取完毕
    }
    return read_size;
}

工作流程:

FFmpeg内部缓冲区数据不足时自动调用

用户从实际数据源(如文件、网络)读取数据到buf

返回实际读取的字节数

返回AVERROR_EOF表示数据结束

write_packet 回调函数
c 复制代码
// 本例中未使用,但机制类似
static int write_packet(void *opaque, uint8_t *buf, int buf_size)
{
    FILE *out_file = (FILE *)opaque;
    return fwrite(buf, 1, buf_size, out_file);
}
seek 回调函数
c 复制代码
// 支持随机访问的示例
static int64_t seek(void *opaque, int64_t offset, int whence)
{
    FILE *file = (FILE *)opaque;
    if(fseek(file, offset, whence) < 0)
        return -1;
    return ftell(file);
}

程序功能概述

这是一个音频解码器程序,主要功能:

  • 从输入文件读取音频数据(如AAC、MP3)
  • 使用FFmpeg进行解码
  • 将解码后的PCM数据写入输出文件

内存I/O模式设置流程

c 复制代码
// 分配I/O缓冲区  
uint8_t *io_buffer = av_malloc(BUF_SIZE);  

// 创建AVIO上下文  
AVIOContext *avio_ctx = avio_alloc_context(  
    io_buffer,          // 缓冲区  
    BUF_SIZE,           // 缓冲区大小  
    0,                  // 读模式(FFmpeg从缓冲区读)  
    (void *)in_file,    // 用户数据(文件指针)  
    read_packet,        // 读取回调  
    NULL,               // 无写入回调  
    NULL                // 无seek支持  
);  

// 关联到格式上下文  
AVFormatContext *format_ctx = avformat_alloc_context();  
format_ctx->pb = avio_ctx;  // 设置自定义I/O  

// 打开输入(注意第二个参数为NULL,因为使用自定义I/O)  
int ret = avformat_open_input(&format_ctx, NULL, NULL, NULL);  

数据流向示意图

复制代码
文件数据 → read_packet回调 → io_buffer → FFmpeg解码器 → PCM输出文件  

解码和格式转换

c 复制代码
static void decode(AVCodecContext *dec_ctx, AVPacket *packet, AVFrame *frame, FILE *outfile)  
{  
    // 发送数据包到解码器  
    avcodec_send_packet(dec_ctx, packet);  

    // 接收解码后的帧  
    while (avcodec_receive_frame(dec_ctx, frame) >= 0) {  
        // 平面格式(Planar)转交错格式(Interleaved)  
        int data_size = av_get_bytes_per_sample(dec_ctx->sample_fmt);  
        for(int i = 0; i < frame->nb_samples; i++) {  
            for(int ch = 0; ch < dec_ctx->channels; ch++) {  
                // 将各通道的数据交错排列写入文件  
                fwrite(frame->data[ch] + data_size * i, 1, data_size, outfile);  
            }  
        }  
    }  
}  

音频格式说明

  • Planar格式 :各通道数据分开存储 LLLLLLRRRRRRLLLLLLRRRRRR...
  • Interleaved格式 :各通道数据交错存储 LRLRLRLRLRLRLRLR...

适用场景

  • 加密媒体处理:解密后数据直接送入FFmpeg
  • 网络流媒体:从网络接收数据实时解码
  • 内存数据处理:数据已在内存中,避免文件I/O开销
  • 自定义协议:实现特殊的数据获取方式

优势

  • 灵活性:可以处理各种非标准数据源
  • 效率:减少磁盘I/O,提高处理速度
  • 控制性:完全控制数据的读取和写入过程

总结

通过avio_alloc_context()实现的内存I/O模式为FFmpeg提供了极大的灵活性,使得开发者能够处理各种特殊的数据源。这种机制的核心在于回调函数的设计,通过用户自定义的读取、写入和定位函数,FFmpeg可以与任何数据源进行交互,而不仅限于传统的文件系统。

在实际应用中,这种模式特别适合处理加密媒体、网络流、内存数据等场景,为多媒体处理提供了强大的扩展能力。

相关推荐
卍郝凝卍8 小时前
NVR(网络视频录像机)和视频网关的工作方式
网络·图像处理·物联网·音视频·视频解决方案
努力犯错11 小时前
Google Veo 3.1 提示词生成器:让 AI 视频创作效率翻倍的免费工具
人工智能·计算机视觉·语言模型·开源·音视频
跨境海王哥13 小时前
TikTok限流:为什么TikTok视频没流量、零播放
音视频
Tracy97315 小时前
DNR6521x_VC1:革新音频体验的AI降噪处理器
人工智能·音视频·xmos模组固件
撬动未来的支点19 小时前
【音视频】弱网环境下h264视频传输优化方案
音视频
aqi0020 小时前
FFmpeg开发笔记(八十八)基于Compose的国产电视直播开源框架MyTV
android·ffmpeg·音视频·直播·流媒体
present122720 小时前
一段音频/视频分离成人声与伴奏,Windows + Anaconda 快速跑通 Spleeter(离线可用)
windows·职场和发展·ffmpeg·音视频·娱乐·媒体
、、、、南山小雨、、、、20 小时前
加载YOLO模型,处理mp4视频
python·yolo·音视频
Likeadust21 小时前
直播卡顿?会议割裂?视频直播点播平台EasyDSS全新升级,一平台终结音视频“老大难”!
音视频