JCHub

  • Home
  • Category
    • A/V
    • WebRTC
    • Beauty of Programming
    • Linux
    • Windows
    • Moments of Life
    • Campus Life
  • Reference
    • API Reference
    • Utilities
    • AV Test
    • Doc
  • Message Board
  • About
JCHub
Code as My Sword, Lost in Obsession
A/V

一路走好,雷神

今天下班时打开QQ群,看到大家在讨论一个无法相信的消息:雷神离开了。看了新闻,实在不敢相信,天妒英才啊。当初踏入音视频这一行,ffmpeg学习,音视频基础,都是学习他的博客的(雷神博客:http://blog.csdn.net/leixiaohua1020)。后面也加了他的QQ群,在这个平台上学到了很多,很感谢他提供的这么一个平台,以及他无私奉献的精神。 感觉自己也要劳逸结合了,少加班,多锻炼,身体最重要。钱是赚不完的,但是身体确实可以透支完的。 一路走好,雷神!

2016年8月3日 0comments 1929hotness 1likes Jeff Read all
A/V

mp4文件elst研究

elst全称Edit List Box,mp4文件中不一定都含有这个box。该box作用是使某个track的时间戳产生偏移。 结构 在ISO_IEC_14496-12中,elst结构定义如下: segment_duration:表示该edit段的时长,以Movie Header Box(mvhd)中的timescale为单位。 media_time:表示该edit段的起始时间,以track中Media Header Box(mdhd)中的timescale为单位。如果值为-1,表示是空edit,一个track中最后一个edit不能为空。 media_rate:edit段的速率为0的话,edit段相当于一个"dwell",即画面停止。画面会在media_time点上停止segment_duration时间。否则这个值始终为1。 例子 现在我们手里有个mp4文件,我们要让封装的视频延迟10秒才开始显示,封装的音频不变,这个可以通过修改视频的时间戳实现,将视频的所有时间戳都加上10秒,但是一个个改太麻烦了,此时elst就派上用场了,我们要通过它让视频时间戳偏移10秒。 下面我们先动手操作番,了解elst如何起作用。 1)找一个没有elst box的mp4文件:test.mp4,假设我放在D:\\bin目录下。至于mp4有没有包含elst可以用文章末尾链接提供的mp4分析工具Mp4Reader分析下。用mediainfo查看该视频的信息: 该mp4音视频时长都为3分32秒。 2)得到带elst的mp4。到https://gpac.wp.mines-telecom.fr/mp4box/ 下载windows下的mp4box,按提示一步步安装。 打开windows cmd命令行,cd到test.mp4目录,然后敲入Mp4Box的命令: [crayon-69d0d917419cb898022677/] 得到: 由此可知test.mp4中,视频的track id 为1,音频track id为2。 3)接着我们敲如下命令: [crayon-69d0d917419d8871360717/] 由于我们只对视频操作,视频track id是1,所以是#1:delay=10000。得到: 此时在bin目录下会生成一个delay_10s.mp4,该mp4中视频track延迟了10秒,音频track不变。mediainfo查看delay_10s.mp4信息: 可以看到视频的时长多了10秒 4)打开mp4reader查看视频track的elst信息: 也就是: [crayon-69d0d917419dc402420439/] 可以看到有两个elst entry,第一个为空,Segment-duration为6000,由于timescale为600(该timescale在mvhd中获 得),6000除以timescale刚好为10秒。由此可知我们要延迟播放某个track,可以在elst中插入一个空的entry,Segment-duration设置为需要延迟播放的时间,Media-Time设置为-1,然后在插入一个entry,Segment-duration设置为正常播放时间,Media-Time也就是起始时间设置为0。 5)播放器验证。我们使用vlc播放器打开delay_10s.mp4: 前10秒视频没有播放,而声音正常播放,到第10秒时视频才开始播放,等声音播放结束后,视频还会播放10秒,可以看出视频确实是推迟了10秒播放,此时音视频已经不同步了。 不是所有的播放器都支持elst的,我测试了下,vlc与potplayer支持,windows自带播放器就不支持。 ffmpeg相关代码分析 下面结合ffmpeg中相关代码以及上面的视频延迟10秒的例子分析,看ffmpeg中对elst数据如何处理。ffmpeg中elst entry数据存放在MOVElst 结构体中: [crayon-69d0d917419df287604961/] duration对应mp4标准中的segment_duration time对应mp4标准中的media_time 在ffmpeg源码libavformat\mov.c中的mov_build_index函数中有如下代码: [crayon-69d0d917419e3478026222/] 第8行代码中可以知道,如果e->time == -1,也就是第一个elst为空,此时得到empty_duration,按前面的例 子该值为10*timescale,下一个for循环得到start_time =e->time,值为0。 在第26行代码中,可知sc->time_offset =0 -10*timescale = -10timescale,然后所有dts都要减去该sc->time_offse,最后结果是都加上10timescale,与原来时间戳比相当于延迟了10s。所以当mp4存在elst时,dts要按如下计算: 1.参考上述ffmpeg代码得到time_offset 2.解码时间戳dts = sample_delta * n – time_offset,其中sample_delta在stts中获得,如果存在B帧,还要从ctts中获得sample_offset,此时: 显示时间戳pts= dts+ sample_offset 否则pts = dts。 接下来我们使用ffmpeg验证下,打印出所有viedeo packet的dts与pts: 可以看到所有时间戳都偏移了230000,也就是10timescale,在video track的mdhd中可知timescale为23000,刚好是10timescale = 23000*10: 由此可知elst的作用就是使某个track时间戳偏移,达到延迟播放的效果。在我们解析mp4文件时,如果存在elst,一定要解析,然后配合stts与ctts,这样才可以得到正确的时间戳。 相关下载 Mp4Reader:https://pan.baidu.com/s/1cBC_yRR-BUfMGpUnC2LN8g

2016年6月16日 1comments 5326hotness 11likes Jeff Read all
Windows

Visual Studio检查内存泄露方法

在测试自己写的程序时,我们一般都会去任务管理器查看程序内存状况,看内存是否随着时间一直增长,如果一直增长,那恭喜了,程序内存泄露了。 编写程序时要养成良好习惯,申请的内存要记得释放,遇到内存泄露时要认真查看申请的内存释放了没,除此之外,我们也可以通过第三方帮助我们发现程序内存泄露状况。 _CrtDumpMemoryLeaks函数 系统自带的 C Run-Time (CRT)库可以帮助我们检测内存泄露,使用很简单。 1)包含相应头文件 [crayon-69d0d91743882381992202/] 2)在程序退出地方,加上: [crayon-69d0d9174388c260550264/] 在调用_CrtDumpMemoryLeaks函数前我们要确保释放了该释放的内存,最后程序结束后在Output窗口就会打印出内存泄露信息。 3)如果我们程序有多个退出点,需要都添加上_CrtDumpMemoryLeaks函数,比较麻烦,此刻_CrtSetDbgFlag 函数就比较方便了。在程序初始化地方加上: [crayon-69d0d9174388f435559060/] 这个函数会在我们程序每个退出点自动执行_CrtDumpMemoryLeaks 函数。 对于如何定位内存泄露代码以及其他使用,可以看下MSDN上的介绍:https://msdn.microsoft.com/en-us/library/x98tx3cf.aspx。 Visual Leak Detector(VLD)插件 给我们的VS装上该插件,下载地址:https://vld.codeplex.com/,使用方法很简单,安装完插件后,在我们要检测的文件加上 [crayon-69d0d91743893421430409/] 然后在debug模式下运行,在Output窗口即可查看详细泄露信息,其实该插件原理就是上一节说到的CRT库。比如我们下面一段测试代码: [crayon-69d0d91743897081631967/] 上述代码我们注释掉了delete部分,debug运行结束后我们可以看到Output窗口显示泄露了10字节,同时打印出泄露的堆栈,如果程序复杂的话,我们可以在Output窗口双击泄露的堆栈定位到相应代码。 VS2015内存快照 在VS2015引入了强大的内存查看工具,在程序运行时,右侧窗口我们可以查看程序内存状况。通过截取某两个不同时刻的内存快照,进行对比,可以快速找到泄露部分。同样还是上面的测试代码,不过得注释掉include vld头文件这一行,我们按如下步骤定位泄露部分。 1)在LeakTest处打个断点,debug运行,在右侧窗口->Memory Usage标签页中启用Heap Profiling。 2)点击Take Snapshot,相当于一次拍照(这图标就是一个相机),此刻下面即可显示当前分配的内存大小,堆大小。 3)执行完测试函数后,我们再次点击Take Snapshot按钮,此刻提示了与上一次快照的变化。 4)点击括号处(+1)或(+0.04KB)变化部分链接。 5)在左侧窗口查看与前一次快照对比,具体什么数据造成内存变化。 6)双击后查看定义为char类型数据的具体实例,我们程序中只定义了一个char类型数据,所以只有一个实例,再双击某个实例可以定位到具体代码,同时查看相应堆栈调用,由于测试程序太简单了,所以这里看不到。 拿我以前写的一个复杂程序举例,程序中我定义了多个CString类型数据,点击查看CString数据具体实例。 我们可以看到多个CString数据实例,点击某个实例就可以看到堆栈调用了,双击具体的堆栈调用可以定位到具体代码。 详细使用可以参考微软官方博客:https://blogs.msdn.microsoft.com/vcblog/2015/10/21/memory-profiling-in-visual-c-2015/,我就不细说了。

2016年6月7日 1comments 5877hotness 35likes Jeff Read all
A/V

PCM音量控制

一、声音的相关概念 声音是介质振动在听觉系统中产生的反应。声音总可以被分解为不同频率不同强度正弦波的叠加(傅里叶变换)。 声音有两个基本的物理属性:频率与振幅。声音的振幅就是音量,频率的高低就是指音调,频率用赫兹(Hz)作单位。人耳只能听到20Hz到20khz范围的声音。 模拟音频(Analogous Audio),用连续的电流或电压表示的音频信号,在时间和振幅上是连续。在过去记录声音记录的都是模拟音频,比如机械录音(以留声机、机械唱片为代表)、光学录音(以电影胶片为代表)、磁性录音(以磁带录音为代表)等模拟录音方式。 数字音频(Digital Audio),通过采样和量化技术获得的离散性(数字化)音频数据。计算机内部处理的是二进制数据,处理的都是数字音频,所以需要将模拟音频通过采样、量化转换成有限个数字表示的离散序列(即实现音频数字化)。 采样频率(Sampling Rate),单位时间内采集的样本数,是采样周期的倒数,指两个采样之间的时间间隔。采样频率必须至少是信号中最大频率分量频率的两倍,否则就不能从信号采样中恢复原始信号,这其实就是著名的香农采样定理。CD音质采样率为 44.1 kHz,其他常用采样率:22.05KHz,11.025KHz,一般网络和移动通信的音频采样率:8KHz。 量化深度,表示一个样本的二进制的位数,即样本的比特数。量化是将经过采样得到的离散数据转换成二进制数的过程,量化深度表示每个采样点用多少比特表示,在计算机中音频的量化深度一般为4、8、16、32位(bit)等。例如:量化深度为8bit时,每个采样点可以表示256个不同的量化值,而量化深度为16bit时,每个采样点可以表示65536个不同的量化值。量化深度的大小影响到声音的质量,显然,位数越多,量化后的波形越接近原始波形,声音的质量越高,而需要的存储空间也越多;位数越少,声音的质量越低,需要的存储空间越少。CD音质采用的是16 bits,移动通信 8bits。 声道数,记录声音时,如果每次生成一个声波数据,称为单声道;每次生成两个声波数据,称为双声道。使用双声道记录声音,能够在一定程度上再现声音的方位,反映人耳的听觉特性。 数字音频存储大小。采样频率、量化深度数越高,声音质量也越高,保存这段声音所用的空间也就越大。立体声(双声道)存储大小是单声道文件的两倍。即:文件大小(B)=采样频率(Hz)×录音时间(S)×(量化深度/8)×声道数(单声道为1,立体声为2) 如:录制1分钟采样频率为44.1KHz,量化深度为16位,立体声的声音(CD音质),文件大小为: 44.1×1000×60×(16/8)×2=10584000B≈10.09M 二、PCM 音频编码,指将模拟音频转换成数字音频并以某种格式存储的技术或过程。 PCM(Pulse Code Modulation)编码,即通过脉冲编码调制方法生成数字音频数据的技术或格式,是一种无损编码格式,是音频模拟信号数字化的一种方法,需要经过采样、量化和编码过程,以实现音频模拟信号数字化。 首先从6个方面描述PCM: 1)采样率; 2)符号:表示样本数据是否是有符号位,比如用一字节表示的样本数据,有符号的话表示范围为-128~127,无符号就是0~255,; 3)字节序:字节序分为大端与小端; 4)样本大小:决定了每个样本由多少位组成,即前面说到的量化深度,一般16位是最常见的; 5)声道数:分为单声道与双声道。 6)整形或浮点型:大多数格式的PCM样本数据使用整形表示,然而在一些对精度要求高的应用方面,使用浮点类型表示PCM样本数据。 打开ffmpeg,敲:ffmpeg -formats命令,获取ffmpeg支持的音视频格式,在这当中我们可以找到支持的PCM格式 [crayon-69d0d91754fb8823605280/] 比如DE s16be,就表示一个样本用16bits有符号的整形数据表示,字节序为大端。 假设我们有一个PCM signed 16-bit little-endian,双声道的PCM文件。如下是文件中前9个样本: [crayon-69d0d91754fc7748490520/] 每个样本2字节,总共18字节,每个样本取值范围:-32768 ~ 32767。 三、PCM音量控制 通过前面描述我们对PCM有了个了解,知道了在PCM流中数据如何存储。下面我们先看一个真正的音频样本波形: 如果我们放大5倍波形,也就是振幅乘以5,此时我们听到了更大的声音,此时样本波形如下: 假如我们有2048bytesPCM数据,样本大小两个字节,共有1024个样本,我们要放大两倍声音,代码可以按如下写: [crayon-69d0d91754fca606127940/] 这是不是很简单,但是接下来我们还需要考虑两个方面的问题。 数据溢出 因为每个样本取值范围是有限制的,调节音量时不可能随便增大,比如一个signed 16 bits的样本,值为5000,我们放大10倍,由于有符号位16bits数据取值范围为-32768~32767,5000乘以10得到的50000超过了32767,数据溢出了,最后值可能变为-15536,不是我们期望的。此时我们就需要裁剪了,确保数值在正确范围内。如下代码对前面说到的放大两倍声音做了裁剪处理: [crayon-69d0d91754fce983432843/] 对数描述 平时表示声音强度我们都是用分贝(db)作单位的,声学领域中,分贝的定义是声源功率与基准声功率比值的对数乘以10的数值。根据人耳的心理声学模型,人耳对声音感知程度是对数关系,而不是线性关系。人类的听觉反应是基于声音的相对变化而非绝对的变化。对数标度正好能模仿人类耳朵对声音的反应。所以用分贝作单位描述声音强度更符合人类对声音强度的感知。前面我们直接将声音乘以某个值,也就是线性调节,调节音量时会感觉到刚开始音量变化很快,后面调的话好像都没啥变化,使用对数关系调节音量的话声音听起来就会均匀增大。 如下图,横轴表示音量调节滑块,纵坐标表示人耳感知到的音量,图中取了两块横轴变化相同的区域,音量滑块滑动变化一样, 但是人耳感觉到的音量变化是不一样的,在左侧也就是较安静的地方,感觉到音量变化大,在右侧声音较大区域人耳感觉到的音量变化较小。 下面我们讲下音量值乘数取值,这里我只简单的用tan函数模拟,效果也不错,至于使用对数如何调整请参考文末链接: [crayon-69d0d91754fd1961305474/] 上面代码中音量乘数取值为tan (some_level / 100.0 ),最后实现代码如下: [crayon-69d0d91754fd5808895648/] 其中level取值需要具体测试实现,一般使用时level取值为某个范围的几个数,比如取10个数,这样音量就有10个阶跃可以调节。 如下图,最后声音音量近似按对数关系增长了: 如果想了解利用对数关系调节音量的具体实现,请参考: PCM音量控制(高级篇)

2016年6月2日 8comments 12441hotness 5likes Jeff Read all
Beauty of Programming

网络字节转换到本地字节的函数模板

在做视频文件解析开发时,经常需要进行网络字节到本地字节的转换。在视频文件中,相关数据是以网络字节存储的,比如视频的宽,定义为uint_32类型,读取时我们需要转换为本地字节序才可以得到正确结果。 操作系统自带api可以帮助我们进行字节序的转换,如下所示函数与具体平台无关: [crayon-69d0d9175647f927077085/] 我们也可以用c++函数模板实现一个,方便使用,我一般都是用自己的函数模板的: [crayon-69d0d9175648a255886254/]

2016年5月28日 0comments 1489hotness 0likes Jeff Read all
A/V

FlvAnalyzer—强大的flv文件分析工具

在学习视频文件的解析时,刚开始我都是用ultraedit配合标准文档查看,不是很方便,后来在网上看到了一个叫flvparse的程序,虽然做的很粗糙,但是为flv文件的学习提供了帮助。现在我自己对flv,avi,mp4文件都非常了解了。在业余时间也做了一个flv文件的分析程序,完全按照flv标准文档解析,每一个字段都清楚展示出来,可以说是网上最强大的一个flv分析工具了(应该是这样的,还没见过比这好的)。flv在流媒体领域应用很广泛的,想做流媒体,视频直播这一块的都得学习flv封装格式,所以希望这个工具对于那些初学者有所帮助。 为了不跟网上其他工具重名,就取了个FlvAnalyzer的名字,目前发布的是第一版。 FlvAnalyzer V1.0 目前支持如下功能: 1)左侧树状结构显示flv的文件结构信息,可以清楚了解flv文件的结构; 2)点击左侧节点,右侧显示对应hex与ascii信息,这样就不必打开二进制编辑器了; 3)详细显示audio tag与video tag各个字节(精确到bit)的详细信息,了解每个tag是如何构造的,同时右下角黑色输出框显示某个值的意义; 4)程序限制最大200M的文件内容显示,显示太多没必要。 如果遇到使用问题或希望改进的,欢迎提出,其他地方下载的遇到的问题概不负责。 -------------------------------------------------------------------------------------- FlvAnalyzer最新版下载地址:https://pan.baidu.com/s/1vmf6yuYAUh5nOk1CBXy8tQ 提取码: qiah 转眼4年多过去了,4年前业余时间写的工具发现用户挺多的,当然软件也有很多Bug,代码也有4年多没更新了,准备抽出时间开发第二版了,希望这款工具软件能帮助更多人。 -- 2020.08.17

2016年5月23日 22comments 12493hotness 14likes Jeff Read all
A/V

VR全景播放器思路

现在VR是越来越火,VR全景视频在未来会有很大普及,颠覆人们传统看视频方式。目前VR视频都是将不同角度拍摄的视频进行拼接而成的,然后通过特定播放器播放。自己对这也很感兴趣,视频拼接目前还没实力搞,先打算做个全景视频播放器。目前思路如下: 1)获取拼接前的各个角度视频; 2)使用某个游戏引擎(比如unity)或者图像渲染引擎(OGRE,大学毕设用过)构造一个立体的物体,可以是球体,立方体,锥体等等; 3)解码之前获取的各个角度视频,然后映射到构造的立体物体上; 4)由于在游戏引擎的世界中我们可以360度浏览虚拟世界,我们将我们的相机放在前面构造的立体物体内,也就是从立体物体内部角度浏览,这样就可以浏览360度的全景视频了。

2016年5月6日 0comments 1578hotness 0likes Jeff Read all
A/V

VLC播放h264头几秒花屏问题

原来测试解析mp4文件得到的h264码流都是用ffplay,没遇到什么问题,今天用vlc测试了下,发现刚开始时会有点花屏,后面就正常了。 看了下h264码流,sps与pps后第一个nalu类型为sei(附加增强信息),也就是0x00000106起始码开头的,不是I帧,所以会出现这个情况。vlc没有对sei信息做处理,导致把sei与后面数据混在一起解码处理,出现丢数据的假象,而导致花屏。vlc处理首帧的正确姿势是:SPS+ PPS + I frame。后面碰到sei类型nalu数据直接丢掉,然后送给vlc播放,就正常了。后面又测了其他mp4文件,发现这些mp4文件mdat box存储的第一个nalu类型都为sei。所以可以采取丢掉sei,读取完SPS+PPS后送给vlc后,跳过sei,从I帧开始继续送给vlc播放就可以避免播放出现花屏。

2016年5月5日 0comments 3917hotness 15likes Jeff Read all
1…910111213…26
Copyright Statement

Unauthorized reproduction or plagiarism in any form is strictly prohibited. For reprint requests, please contact via email.

Recent Comments
snail Published at 1 weeks ago(03 03202633105 27 27pm26) 多谢,大佬。醍醐灌顶!
dongxuh Published at 8 months ago(07 07202573103 27 27pm25) 真心不错的博客,有机会能一起分享
南南 Published at 9 months ago(07 07202573103 15 15pm25) 写的超棒!
Jeff Published at 11 months ago(05 05202553105 15 15pm25) 2025-03-12的提交已经支持了
Jeff Published at 11 months ago(05 05202553105 15 15pm25) 源视频地址已经不可用了,引用优酷的视频地址,看了下被删了
Ad

COPYRIGHT © 2026 jianchihu.net. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang