基于 FFmpeg 的 H264 转 MP4 步骤总结

本篇为步骤总结(建议大家结合理解):

                具体代码请前往基于 FFmpeg 实现 H.264 转 MP4 视频转码-优快云博客

1. 初始化

  • 注册组件:调用 av_register_all 函数,注册 FFmpeg 库中所有可用的编解码器、格式解析器等组件,为后续音视频处理奠定基础。
  • 分配上下文:使用 avformat_alloc_context 函数分别为输入和输出文件分配 AVFormatContext 结构体,用于存储文件的格式、流信息等。
  • 分配 AVPacket 内存:通过 malloc 函数为 AVPacket 分配内存,AVPacket 用于存储从输入文件读取的编码数据或将要写入输出文件的编码数据。
  • 初始化视频流索引:将视频流索引 videoIndex 初始化为 -1,后续查找视频流时,若找到会更新该值。
2. 打开 H264 文件并获取信息
  • 打开文件:使用 avformat_open_input 函数尝试打开指定路径的 H264 文件,并将文件的格式信息填充到输入格式上下文 inFormatContext 中。若打开失败,输出错误信息并终止操作。
  • 获取流信息:调用 avformat_find_stream_info 函数读取文件的流信息,填充 inFormatContext 中的流相关字段,如每个流的编解码器、时间基等。若获取失败,输出错误信息并终止操作。
  • 查找视频流:遍历输入文件中的所有流,通过判断流的编码类型是否为 AVMEDIA_TYPE_VIDEO 来找到视频流。若找到,记录其索引到 videoIndex 中;若未找到,输出提示信息。
3. 准备输出文件
  • 猜测输出格式:利用 av_guess_format 函数根据输出文件的路径猜测输出文件的格式。若猜测失败,输出错误信息并终止操作。
  • 设置输出格式:将猜测得到的输出格式赋值给输出格式上下文 outFormatContext 的 oformat 字段,确定输出文件的格式。
  • 打开 I/O 流:使用 avio_open 函数以写入模式打开输出文件的 I/O 流,用于后续向文件中写入数据。若打开失败,输出错误信息并终止操作。
  • 创建新视频流:调用 avformat_new_stream 函数在输出格式上下文中创建一个新的视频流,用于存储转码后的视频数据。若创建失败,输出错误信息并终止操作。
  • 复制编解码器参数:使用 avcodec_parameters_copy 函数将输入文件中视频流的编解码器参数复制到新创建的输出视频流中,确保输出视频的编码设置与输入视频一致。
  • 写入文件头:调用 avformat_write_header 函数写入输出文件的头信息,包含文件的格式、流信息等,为后续写入数据做准备。若写入失败,输出错误信息并终止操作。
  • 分配 AVPacket 内存:根据新视频流的宽度和高度计算所需的内存大小,使用 av_new_packet 函数为 AVPacket 分配内存。若分配失败,输出错误信息并终止操作。
4. 循环转码并写入数据
  • 读取帧数据:使用 av_read_frame 函数从输入文件中循环读取一帧数据,存储到 AVPacket 中。当读取到文件末尾或出现错误时,循环结束。
  • 处理视频帧:检查读取的数据包是否属于视频流(通过 stream_index 判断),若是则进行处理:
    • 处理时间戳:若数据包的显示时间戳(PTS)为无效值(AV_NOPTS_VALUE),根据帧数、时间基和帧率重新计算 PTS、解码时间戳(DTS)和数据包的时长。若 PTS 小于 DTS,认为是异常帧,跳过该帧。
    • 时间基转换:使用 av_rescale_q_rnd 和 av_rescale_q 函数将 PTSDTS 和时长从输入视频流的时间基转换到输出视频流的时间基。
    • 设置数据包属性:将 pos 设置为 -1 表示未知位置,设置 flags 标记为关键帧,将 stream_index 设置为 0。
  • 写入数据:调用 av_interleaved_write_frame 函数将处理后的 AVPacket 写入输出文件。若写入失败,输出错误信息。
  • 重置 AVPacket:使用 av_packet_unref 函数释放 AVPacket 中的数据和引用,以便下次使用。
5. 清理资源
  • 写入文件尾:调用 av_write_trailer 函数写入输出文件的尾信息,包含文件的结束标志等。
  • 关闭 I/O 流:使用 avio_close 函数关闭输出文件的 I/O 流,释放相关资源。
  • 释放上下文:使用 av_free 函数分别释放输出和输入格式上下文占用的内存。
  • 输出成功信息:最后输出转码成功的提示信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值