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

Chromium 改造实录:增加 MPEG TS 格式支持

在《选择最新 Chromium,支持 H264 / H265》一文中,记录了我通过升级 Chromium 版本解决了 H264 / H265 视频支持难题。然而难题接踵而至,这次的难题是 MPEG TS 流的支持。

MPEG2-TS 传输流广泛应用于数字电视广播系统,所以是一个不得不支持的格式。通过查询资料,了解到 FFmpeg 是支持 TS 格式的,但 Chromium 中并没有默认开启这个功能。这可能是出于版权、性能或者兼容性的考虑。

关于如何让 Chromium 支持 TS,我请教了一下 AI。AI 给的思路是:

  • 修改 FFmpeg 的配置文件,开启 MPEG TS 的解复用器和解码器;

  • 修改 Chromium for Android 的媒体框架,添加对 MPEG TS 的支持;

  • 修改 Chromium for Android 的网络模块,添加对 MPEG TS 的传输协议的支持。

按照 AI 的建议,我一步步解决了 TS 格式的支持问题。

第一步研究 Chromium 的编译参数。媒体有关的编译选项主要位于 media 目录下的 media_options/gni 文件中。研究了一下,发现一个 enable_mse_mpeg2ts_stream_parser 参数,目前的值是:

enable_mse_mpeg2ts_stream_parser =proprietary_codecs && (enable_cast_receiver || use_fuzzing_engine)

对于 Chromium for Android,上面的值是 false。看起来这个选项是与 MSE(Media Source Extensions) 有关,但实际上也会影响 TS 文件的解析,因为在 mime_util_internal.cc 中有这样的代码:

#if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER)CodecSet mp2t_codecs{H264, MPEG2_AAC, MPEG4_AAC, MP3};AddContainerWithCodecs("video/mp2t", mp2t_codecs);
#endif  // BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER)

TS 容器的 mime type 为 video/mp2t,只有开启了 enable_mse_mpeg2ts_stream_parser,才会加入对 TS 容器的处理。所以首先需要将 enable_mse_mpeg2ts_stream_parser 选项修改为 true。

修改这个参数后,立刻又碰到一个新的错误信息:

03-09 07:44:55.322 31903 32010 V chromium: [VERBOSE1:batching_media_log.cc(35)] MediaEvent: {"error":"FFmpegDemuxer: open context failed"}

稍微捋一下代码,可以发现 open context 的代码实际位于 FFmpegGlue::OpenContext,这个方法中又会调用 FFMPEG 的 avformat_open_input 函数。

接下来的调用流程:

avformat_open_input -> init_input -> av_probe_input_buffer2 -> av_probe_input_format2 -> av_probe_input_format3 -> av_demuxer_iterator

可以很明显看出,av_demuxer_iterator 就是遍历系统的 demuxer,那这个 demuxer 列表来自哪儿呢?

查看其实现文件 allformats.c,可以看到它有如下包含文件:

#include "libavformat/demuxer_list.c"

也就是在 demuxer_list.c 这个文件里面进行了定义。搜索 demuxer_list.c 文件,发现这个文件有多份,位于 third_party/ffmpeg/chromium/config 下。

这个 config 下的文件组织有些讲究,最上一层是 branding,也就是我们在 args.gn 下定义的 ffmpeg_branding 选项,默认是 Chromiium。再下一层是按 OS 划分,接下来就是按 CPU 分。找出你的目标平台,修改 demuxer_list.c,增加一行:

&ff_mpegts_demuxer,

接下来还要修改 FFmpegGlue::OpenContext 方法,在

DCHECK_NE(container_, container_names::CONTAINER_UNKNOWN);

前面增加容器判断:

else if (strcmp(format_context_->iformat->name, "mpegts") == 0)container_ = container_names::CONTAINER_MPEG2TS;

解决了上面的错误后,又会碰到新的错误:

03-04 09:53:29.573 28173 28233 W [FFMPEG]: Could not find codec parameters for stream 0 (Video: h264 ([27][0][0][0] / 0x001B), none): unspecified size
03-04 09:53:29.573 28173 28233 W [FFMPEG]: Consider increasing the value for the 'analyzeduration' (60000000) and 'probesize' (5000000) options
03-04 09:53:29.573 28173 28233 W [FFMPEG]: Could not find codec parameters for stream 1 (Audio: ac3 (AC-3 / 0x332D4341), 0 channels): unspecified sample rate
03-04 09:53:29.573 28173 28233 W [FFMPEG]: Consider increasing the value for the 'analyzeduration' (60000000) and 'probesize' (5000000) options
03-04 09:53:29.573 28173 28233 D [FFMPEG]: After avformat_find_stream_info() pos: 0 bytes read:36960112 seeks:8 frames:292
03-04 09:53:29.574 28173 28247 V chromium: [VERBOSE1:ffmpeg_common.cc(246)] Unknown profile id: -2659
03-04 09:53:29.575 28173 28247 V chromium: [VERBOSE1:batching_media_log.cc(37)] MediaEvent: {"debug":"Warning, FFmpegDemuxer failed to create a valid/supported video decoder configuration from muxed str}
03-04 09:53:29.575 28173 28247 V chromium: [VERBOSE1:batching_media_log.cc(37)] MediaEvent: {"info":"FFmpegDemuxer: skipping invalid or unsupported video track"}
03-04 09:53:29.575 28173 28247 V chromium: [VERBOSE1:ffmpeg_common.cc(122)] Unknown audio CodecID: 86019
03-04 09:53:29.575 28173 28247 V chromium: [VERBOSE1:ffmpeg_common.cc(294)] Unknown AVSampleFormat: -1

看日志,似乎是解码器创建失败,有了前面的经验,直接找到 codec_list.cc 文件,加入如下行:

&ff_h264_decoder,

同时修改 config_components.h 文件, 将:

#define CONFIG_H264_DECODER 0

修改为:

#define CONFIG_H264_DECODER 1

经过这样的修改后,我们会发现出现很多链接错误。没有关系,将缺的代码文件加入编译即可。

需要注意的是,有些底层代码是使用汇编语言编写,在 Android 平台下就是那些以 .S 为后缀的文件。非常神奇的是,clang 直接支持编译汇编语言,所以将这些汇编文件和 C 文件一起加入编译列表即可。

经过这样一番操作,TS 流终于播放起来了。需要说明的是,我测试使用的 TS 流,内部视频采用的 H264 编码,如果采用其他格式编码,修改的过程会有所不同,但思路类似。

经过上述的改造,是否就完美解决问题了呢?并没有。测试下来,发现视频播放出来了,但是没有声音,从日志可以看出:

03-05 21:14:18.706 18936 19047 V chromium: [VERBOSE1:batching_media_log.cc(37)] MediaEvent: {"debug":"Warning, FFmpegDemuxer failed to create a valid/supported audio decoder configuration from muxed str}
03-05 21:14:18.707 18936 19047 V chromium: [VERBOSE1:batching_media_log.cc(37)] MediaEvent: {"info":"FFmpegDemuxer: skipping invalid or unsupported audio track"}

解决的方法类似,但真正解决声音输出,又花费了一番精力,这个留在下一篇继续,敬请关注!

相关文章:

Chromium 改造实录:增加 MPEG TS 格式支持

在《选择最新 Chromium,支持 H264 / H265》一文中,记录了我通过升级 Chromium 版本解决了 H264 / H265 视频支持难题。然而难题接踵而至,这次的难题是 MPEG TS 流的支持。MPEG2-TS 传输流广泛应用于数字电视广播系统,所以是一个不…...

性能优化之-事件代理

js中的事件委托或是事件代理简单理解 事件委托也叫事件代理,“事件代理”即是把原本需要绑定在子元素的响应事件(click、keydown…)委托给父元素,让父元素担当事件监听的职务。事件代理的原理是DOM元素的事件冒泡。 概述&#x…...

MSDS 即化学品安全说明书

MSDS 即化学品安全说明书,亦可译为化学品安全技术说明书或化学品安全数据说明书,是化学品生产商和进口商用来阐明化学品的理化特性(如PH值,闪点,易燃度,反应活性等)以及对使用者的健康&#xff…...

真人手办没法实现网购?我有一个好办法!

记得以前在网上看到过一个冷笑话式的问答,问的是中国最早的手办是什么,有网友回答是秦始皇兵马俑,这个抖机灵式的回答简直妙得让人会心一笑。 你接触过手办吗? 提到手办,大家第一时间想到的,肯定都会是各…...

2019湖南省大学生程序设计竞赛题解(D)

D-Modulo Nine 很妙的类似区间dp, 我自己是想不到,本题解题思路来自学长的博客: 长沙橘子猫 题意 有一个长度为 nnn 的序列,你可以给每个位置填 0∼90\sim90∼9 的一个数,有 mmm 个限制,每个限制 [li,ri…...

【开发】中间件——RocketMQ

分布式消息系统 RocketMQ概念,用途,特性安装RocketMQ掌握RocketMQ的api使用对producer、consumer进行详解了解RocketMQ的存储特点 简介及相关概念JavaAPISpringBoot整合RocketMQ消息的顺序收发消息系统的事务、存储、重试策略消息系统的集群 RocketMQ R…...

36 UnitTest框架 - 参数化

目录 一、参数化环境准备 1、方式一:在终端(cmd)安装parameterized 2、方式二:在Pycharm中安装parameterized 二、参数化 1、什么事参数化? 2、参数化引入案例 (1)需求 (2&a…...

Qt源码阅读(四) 事件循环

事件系统 文章为本人理解,如有理解不到位之处,烦请各位指正。 文章目录事件系统什么是事件循环?事件是如何产生的?sendEventpostEvent事件是如何处理的?事件循环是怎么遍历的?事件过滤器event夹带私货时间Q…...

银行数字化转型导师坚鹏:银行数字化领导力提升之道

银行数字化领导力提升之道 ——融合中西智慧,践行知行合一思想,实现知行果合一 课程背景: 很多银行存在以下问题:不知道如何领导数字员工?不清楚银行数字化领导力模型的内涵?不知道如何开展银行数字化…...

Vue2 -- 自定义单选内容的单选框组件

自定义单选内容的单选框组件 之前做的一个项目,在项目中有一个关于人员权限分配的功能,给人员指定各个模块的权限信息,分为 write 可写权限read 可读权限none 没有权限 项目要求画面中只显示 W R 两个按钮控制指定权限信息,都不…...

让PyTorch训练速度更快,你需要掌握这17种方法

掌握这 17 种方法,用最省力的方式,加速你的 Pytorch 深度学习训练。近日,Reddit 上一个帖子热度爆表。主题内容是关于怎样加速 PyTorch 训练。原文作者是来自苏黎世联邦理工学院的计算机科学硕士生 LORENZ KUHN,文章向我们介绍了在…...

LeetCode-309. 最佳买卖股票时机含冷冻期

目录题目思路动态规划题目来源 309. 最佳买卖股票时机含冷冻期 题目思路 每天最多只可能有三种状态中的一种 0表示当前处于买入状态(持有股票) 1表示当前处于卖出状态(不持有股票) 2表示当前处于冷冻状态 设dp[i][j]表示i - 1天状态为j时所拥有的最大现金 dp[i][0] Math.ma…...

AUTOSAR知识点Com(七):CANSM初认知

目录 1、概述 2、CanSM主要做什么 2.1、CAN控制器状态管理 2.2、CAN收发器状态管理 2.3、Busoff检测 1、概述 CANSM(Controller Area Network State Manager)是AUTOSAR(Automotive Open System Architecture)标准中的一个模块…...

递归:斐波那契数列、递归实现指数型枚举、递归实现排列型枚举

递归&#xff1a;O(2^n) 调用自己 例题及代码模板&#xff1a; 斐波那契数列 输入一个整数 n &#xff0c;求斐波那契数列的第 n 项。 假定从 0 开始&#xff0c;第 0 项为 0。 数据范围 0≤n≤39 样例 输入整数 n5 返回 5 #include <iostream> #include <cstring&g…...

oracle模糊查询时字段内容包含下划线的解决办法

最近项目中遇到一个关于模糊查询问题。表tabA中的字段name的值有下划线的情况&#xff0c;在模糊查询时发现查询的记录不对。 表的结构 表名&#xff1a;tabA id name sex 1 test_601 1 2 test_602 2 3 test16 1 4 t…...

C++:explicit关键字

C中的explicit关键字只能用于修饰只有一个参数的类构造函数&#xff0c;它的作用是表明该构造函数是显示的&#xff0c;而非隐式的&#xff0c;跟它相对应的另一个关键字是implicit&#xff0c;意思是隐藏的&#xff0c;类构造函数默认情况下即声明为implicit(隐式)。那么显示声…...

【C5】bmc wtd,post

文章目录1.bmc_wtd_cpld&#xff1a;syscpld.c中wd_en和wd_kick节点对应寄存器&#xff0c;crontab&#xff0c;FUNCNAME2.AST芯片WDT切换主备&#xff1a;BMC用WDT2作为主备切换的控制器2.1 AC后读取&#xff1a;bmc处于主primary flash&#xff08;设完后&#xff1a;实际主&…...

200.Spark(七):SparkSQL项目实战

一、启动环境 需要启动mysql,hadoop,hive,spark。并且能让spark连接上hive(上一章有讲) #启动mysql,并登录,密码123456 sudo systemctl start mysqld mysql -uroot -p#启动hive cd /opt/module/ myhadoop.sh start#查看启动情况 jpsall#启动hive cd /opt/module/hive/…...

区块链系统:挖矿原理

在比特币的P2P网络中&#xff0c;有一类节点&#xff0c;它们时刻不停地进行计算&#xff0c;试图把新的交易打包成新的区块并附加到区块链上&#xff0c;这类节点就是矿工。因为每打包一个新的区块&#xff0c;打包该区块的矿工就可以获得一笔比特币作为奖励。所以&#xff0c…...

【博弈】【清华冬令营2018模拟】取石子

写完敢说全网没有这么详细的题解了。 注意&#xff1a;题解长是为了方便理解&#xff0c;所以读起来速度应该很快。 题目描述 有 nnn 堆石子&#xff0c;第 iii 堆有 xix_ixi​ 个。 AliceAliceAlice 和 BobBobBob 轮流去石子&#xff08;先后手未定&#xff09;&#xff0c; …...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

工业安全零事故的智能守护者:一体化AI智能安防平台

前言&#xff1a; 通过AI视觉技术&#xff0c;为船厂提供全面的安全监控解决方案&#xff0c;涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面&#xff0c;能够实现对应负责人反馈机制&#xff0c;并最终实现数据的统计报表。提升船厂…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现

摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序&#xff0c;以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务&#xff0c;提供稳定高效的数据处理与业务逻辑支持&#xff1b;利用 uniapp 实现跨平台前…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列&#xff0c;以便知晓哪些列包含有价值的数据&#xff0c;…...

#Uniapp篇:chrome调试unapp适配

chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器&#xff1a;Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...

JS设计模式(4):观察者模式

JS设计模式(4):观察者模式 一、引入 在开发中&#xff0c;我们经常会遇到这样的场景&#xff1a;一个对象的状态变化需要自动通知其他对象&#xff0c;比如&#xff1a; 电商平台中&#xff0c;商品库存变化时需要通知所有订阅该商品的用户&#xff1b;新闻网站中&#xff0…...

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分&#xff1a; 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...

Axure 下拉框联动

实现选省、选完省之后选对应省份下的市区...

在golang中如何将已安装的依赖降级处理,比如:将 go-ansible/v2@v2.2.0 更换为 go-ansible/@v1.1.7

在 Go 项目中降级 go-ansible 从 v2.2.0 到 v1.1.7 具体步骤&#xff1a; 第一步&#xff1a; 修改 go.mod 文件 // 原 v2 版本声明 require github.com/apenella/go-ansible/v2 v2.2.0 替换为&#xff1a; // 改为 v…...

C++--string的模拟实现

一,引言 string的模拟实现是只对string对象中给的主要功能经行模拟实现&#xff0c;其目的是加强对string的底层了解&#xff0c;以便于在以后的学习或者工作中更加熟练的使用string。本文中的代码仅供参考并不唯一。 二,默认成员函数 string主要有三个成员变量&#xff0c;…...