当前位置: 首页 > news >正文

FFmpeg 视频旋转信息处理:3.4 vs 7.0.2

1. 概述

FFmpeg 在处理视频旋转信息方面经历了重要的架构变化。本文档详细对比了 FFmpeg 3.4 和 7.0.2 在封装(muxing)和解封装(demuxing)视频旋转信息时的差异,并提供兼容性解决方案。文档内容由Claude Sonnet 4辅助撰写,如有疏漏还请斧正。

  • FFmpeg 3.4:支持 metadata 和 side data 双重机制
  • FFmpeg 7.0.2:主要依赖 side data 机制,弱化 metadata 支持

2. 旋转信息存储机制

存储方式FFmpeg 3.4FFmpeg 7.0.2说明
Stream Metadata✅ 读写支持❌ 仅读取(兼容性)stream->metadata["rotate"]
Side Data✅ 读写支持✅ 主要方式AV_PKT_DATA_DISPLAYMATRIX
容器原生格式✅ 支持✅ 支持MP4 tkhd atom 等
// Metadata 格式(字符串)
stream->metadata["rotate"] = "90"  // 90度旋转// Side Data 格式(3x3 变换矩阵)
int32_t displaymatrix[9] = {cos(θ), -sin(θ), 0,sin(θ),  cos(θ), 0,0,       0,      1
};

3. 解封装(Demuxing)对比

3.1 FFmpeg 3.4 解封装行为

// FFmpeg 3.4 读取流程
void ffmpeg34_demux_rotation() {// 1. 从容器读取 displaymatrixuint8_t *displaymatrix = read_container_displaymatrix();// 2. 设置 side dataav_stream_add_side_data(stream, AV_PKT_DATA_DISPLAYMATRIX, displaymatrix, size);// 3. 同时设置 metadata(便于应用程序使用)if (displaymatrix) {double rotation = av_display_rotation_get((int32_t*)displaymatrix);av_dict_set(&stream->metadata, "rotate", av_asprintf("%.0f", -rotation), AV_DICT_DONT_STRDUP_VAL);}
}// 应用程序读取(推荐方式)
int getRotation_v34(AVStream *stream) {// 方式1:从 metadata 读取(简单)AVDictionaryEntry *t = av_dict_get(stream->metadata, "rotate", NULL, 0);if (t) return atoi(t->value);// 方式2:从 side data 读取(精确)uint8_t *displaymatrix = av_stream_get_side_data(stream, AV_PKT_DATA_DISPLAYMATRIX, NULL);if (displaymatrix) {return (int)(-av_display_rotation_get((int32_t*)displaymatrix));}return 0;
}

3.2 FFmpeg 7.0.2 解封装行为

// FFmpeg 7.0.2 读取流程
void ffmpeg70_demux_rotation() {// 1. 从容器读取 displaymatrixuint8_t *displaymatrix = read_container_displaymatrix();// 2. 只设置 side dataav_packet_side_data_add(&stream->codecpar->coded_side_data,&stream->codecpar->nb_coded_side_data,AV_PKT_DATA_DISPLAYMATRIX, displaymatrix, size, 0);// 3. 不再自动设置 metadata// stream->metadata["rotate"] 为空!
}// 应用程序读取(新方式)
int getRotation_v70(AVStream *stream) {// 只能从 side data 读取AVPacketSideData *side_data = av_packet_side_data_get(stream->codecpar->coded_side_data,stream->codecpar->nb_coded_side_data,AV_PKT_DATA_DISPLAYMATRIX);if (side_data && side_data->size >= 9 * sizeof(int32_t)) {double rotation = av_display_rotation_get((int32_t*)side_data->data);return (int)(-rotation);}return 0;
}

4. 封装(Muxing)对比

4.1 FFmpeg 3.4 封装行为

// FFmpeg 3.4 支持多种设置方式// 方式1:通过 metadata 设置(推荐)
int setRotation_v34_metadata(AVStream *stream, int degrees) {char rotation_str[16];snprintf(rotation_str, sizeof(rotation_str), "%d", degrees);// 设置 metadata,muxer 会自动转换为 displaymatrixreturn av_dict_set(&stream->metadata, "rotate", rotation_str, 0);
}// 方式2:直接设置 side data
int setRotation_v34_sidedata(AVStream *stream, int degrees) {uint8_t *displaymatrix = av_stream_new_side_data(stream, AV_PKT_DATA_DISPLAYMATRIX, 9 * sizeof(int32_t));if (!displaymatrix) return -1;av_display_rotation_set((int32_t*)displaymatrix, -(double)degrees);return 0;
}

4.2 FFmpeg 7.0.2 封装行为

// FFmpeg 7.0.2 主要通过 side data 设置int setRotation_v70(AVStream *stream, int degrees) {// metadata 方式可能无效,必须使用 side dataint32_t *displaymatrix = (int32_t*)av_packet_side_data_new(&stream->codecpar->coded_side_data,&stream->codecpar->nb_coded_side_data,AV_PKT_DATA_DISPLAYMATRIX,9 * sizeof(int32_t),0);if (!displaymatrix) return -1;av_display_rotation_set(displaymatrix, -(double)degrees);return 0;
}

5. 总结

FFmpeg 在处理视频旋转信息方面的变化反映了其向更标准化、更精确方向的演进:

  • FFmpeg 3.4:过渡期版本,同时支持 metadata 和 side data
  • FFmpeg 7.0.2:现代化版本,主要依赖标准化的 side data

开发者应该:

  1. 在新项目中优先使用 side data API
  2. 保持对旧版本的兼容性支持
  3. 进行充分的跨版本测试
  4. 关注 FFmpeg 的未来发展趋势

这种变化虽然增加了开发复杂度,但提供了更好的标准兼容性和更精确的旋转信息处理能力。

http://www.dtcms.com/a/321623.html

相关文章:

  • 开发避坑指南(22):Vue3响应式编程中this绑定机制与解决方案
  • C++ 部署LSTM(.onnx)
  • 大模型中的核心参数temperature 您知道是什么东东吗?
  • KEIL 环境下 printf 导致程序无法执行的解决方案
  • GPT5评测对比与使用
  • 2025年城市建设与智慧交通国际会议(ICUCIT 2025)
  • OpenAI重磅开源回归!GPT-OSS-120B/20B登陆星辰MaaS
  • 【长度最小的子数组】
  • C++ 红黑树实现详解:理论+代码+图解
  • 主流多模态大模型使用总结
  • GPT-5测评:AI新纪元的开启还是炒作?
  • 【SpringBoot】01 基础入门-SpringBoot2:从核心技术到响应式编程
  • Jenkins自动化构建部署Java、Web前后端项目
  • 使用Python将中文语音翻译成英语音频
  • 达梦DISQL执行SQL和SQL脚本
  • 医疗数据中台架构实战:Java实现高可用、低耦合的数据治理方案
  • 30人大型视频会议设备清单
  • 零基础小白如何使用QGIS制作研究区地形区位图教程
  • 参数服务器 server and client
  • 一文可视化分析2025年6月计算机视觉顶刊IJCV前沿热点
  • 满足高性能AI服务器的企业SSD有哪些?三星PM1743与Solidigm PS1010
  • Ⅹ—6.计算机二级综合题27---30套
  • 研发流程管理经验分享
  • 部署ELK8.18对日志进行收集、展示
  • 1Panel Agent 证书绕过实现远程命令执行漏洞复现(CVE-2025-54424)
  • 【Spring Boot 快速入门】八、登录认证
  • Java 大视界 -- Java 大数据机器学习模型在金融风险传染路径模拟与防控策略制定中的应用(387)
  • [Oracle] LEAST()函数
  • CORS 跨域问题 Next.js 跨域问题放通
  • HttpURLConnection (JDK原生)和Hutool HTTP工具的区别