您当前位置: 首页 »

音视频_图像相关

分类目录归档: 音视频_图像相关

Why We Created SRT and the Difference Between SRT and UDT

Article Form :
https://www.haivision.com/blog/broadcast-video/created-srt-difference-srt-udt/

Editor’s Note: This post originally appeared on the GitHub Wiki for SRT. It has been slightly modified for formatting. 

Some people have asked us why we’re using the UDT library within our SRT protocol. Actually, some people claimed that SRT is just a slightly modified version of UDT and that UDT is known to be useless for live video transmission. Guess what, the latter is true. UDT has been designed for high throughput file transmission over public networks. However, SRT is far from being a slightly modified version of UDT. I’ll get into the details, but will start with a little bit of history.

Haivision has always been known for lowest latency video transmission across IP based networks — typically MPEG-TS unicast or multicast streams over the UDP protocol. This solution is perfect for protected networks and if packet lossbecame a problem, enabling forward error correction (FEC) fixed it. At some point we were getting questioned as to whether it would be possible to achieve the same latency between customer sites in different locations, between different cities, countries or even continents.

Of course it’s possible with satellite links or dedicated MPLS networks, but those are quite expensive solutions, so people wanted to use their public internet connectivity instead. While it’s possible to go with FEC in some cases, that’s not a reliable solution, as the amount of recoverable packet loss is limited, unless you accept a significant amount of bandwidth overhead.

After evaluating the pros and cons of different third party solutions, we found that none satisfied all our requirements. The lack of insight into the underlying technology drove us to the the decision to develop our own solution, which we then could deeply integrate into products. That way, it would become the “glue” that enables us to transmit streams between all our different products, locally or across far distances, while maintaining our low latency proposition.

There were a few of possible choices to consider:

  • The TCP based approach. Problem for live streaming: Network congestion, too slow packet loss recovery.
  • The UDP based Approach. General problem: Packet lossjitter, packet re-ordering, delay
  • Reliable UDP. Adds framing and selective retransmit.

Having had a history with UDT for data transmission, I remembered its packet loss recovery abilities and just started playing with it. Though not designed for live streaming at all, it kind of worked when using really big buffers. I handed it over to one of our extremely talented networking guys in the embedded software team (thanks, Jean!) and asked him whether he’d be able to make this a low latency live streaming solution. I didn’t hear anything back for quite a while and had almost lost my hope, when he contacted me to tell me he had to rewrite the whole packet retransmissionfunctionality in order to be able to react to packet loss immediately when it happens and that he added an encryption protocol, which he had specified and implemented for other use cases before. Nice 🙂

We started testing sending low latency live streams back and forth between Germany and Montreal and it worked! However, we didn’t get the latency down to a level we had hoped to achieve. The problem we faced turned out to be timing related (as it often is in media).

Bad Signal

What happened was this: 

The characteristics of the original stream on the source network got completely changed by the transmission over the public internet. The reasons are delay, jitterpacket loss and its recovery on the dirty network. The signal on the receiver side had completely different characteristics, which led to problems with decoding, as the audio and video decoders didn’t get the packets at the expected times. This can be handled by buffering, but that’s not what you want in low latency setups.

The solution was to come up with a mechanism that recreates the signal characteristics on the receiver side. That way we were able to dramatically reduce the buffering. This functionality is part of the SRT protocol itself, so once the data comes out of the SRT protocol on the receiver side, the stream characteristics have been properly recovered.

The result is a happy decoder: 

Good Signal

We publicly showed SRT (Secure Reliable Transport) for the first time at IBC 2013, where we were the only ones to show an HEVC encoded live stream, camera to glass, from a hotel suite outside the exhibition directly onto the show floor, using the network provided by the RAI. Everybody who has been at a show like this knows how bad these networks can get. And the network was bad. So bad that we expected the whole demo to fall apart, having pulled the first trial version of SRT directly from the labs. The excitement was huge, when we realized that the transmission still worked fine!

Since then, we added SRT to all our products, enabling us to send high quality, low latency video from and to any endpoint, including our mobile applications. Of course there were improvements to be made and the protocol matured on the way. Until NAB 2017, where we announced that SRT is now Open Source.

You can learn more about SRT at the SRT Alliance website here.

To view the SRT on GitHub and start contributing to this open-source movement, click here!

2019-06-10 | | udt, 网络协议, 音视频_图像相关

Why We Created SRT and the Difference Between SRT and UDT已关闭评论

【webrtc、gclient】cpid更新失败代理新的配置方案

首先按照原先的配置方案如下:

1. 设置http_proxy和https_proxy环境变量

2. 设置winhttp代理

3. 配置git代理

但在执行gclient自身更新时,总是发现cipd更新失败。简单跟踪了一下cpid,发现cpid的更新有两种,第一种是cpid自身自动更新,另一种是通过执行bootstrap来更新cpid。
cpid是使用go写的,虽然网上一堆教程说配置了http_proxy之后就可以等等,但这其中cpid存在一个问题,即在进行https请求时,会对证书做校验,若https_proxy配置的代理是一个https真实代理服务器,那么cpid做校验时会失败,具体未看代码,估计webdav执行过程中需要用到https中的证书做登录校验。

至于对cipd的更新处理方式为:

因此将https_proxy有意配置成http服务器,即可破。这会让cipd自更新时强制通过ensure方式进行更新

同时在其他一些脚本执行时,似乎用到了类似原先的csript,因此最好在ie代理时也配上相应的代理服务器地址。这样就可以正常更新gclient了。

2019-01-15 | | shell, windows-shell, 音视频_图像相关

【webrtc、gclient】cpid更新失败代理新的配置方案已关闭评论

【ios、x264】将静态库打包成动态库,链接时的text relocations错误

最近在ios上出现将多个sdk放到一个app时,有各种开源静态库冲突的问题;于是考虑将自己用到的库进行打包成动态库版本,以此解决冲突问题。

在进行打包成动态库时,发现x264问题最大。打包出来的库在链接期出现text relocations错误,网上找了以后发现基本都是进行忽略这个错误,事实上这个错误忽略了没用,app启动时还是会出现相应的crash。

换了几个版本的xcode进行测试,发现x264编译会出现不同情况的告警和错误,根据底部罗列的参考文章,估计xcode的编译器可能也有一些bug。

后来模仿android上的编译方式,在x264里加入了–enable-pic和–disable-asm顺利编译通过,但由于osx和xcode版本的因素,模拟器上的并没有编译出来,仅仅编译了armv7和arm64。

 

参考文章:

MacOSX下编译linphone(text-relocation错误说明)

libxxx.so- text relocations问题的终极解决方案(android)

Linker error when using incremental builds on iPhone

Android Gradle编译so库或运行时出现 text relocations 崩溃的正确解决方法

2018-06-15 | | [linux总结], unix编程环境学习, 编码技巧, 音视频_图像相关, 音视频编解码

【ios、x264】将静态库打包成动态库,链接时的text relocations错误已关闭评论

【h264、baseline、flv】使用baseline做双向强交互直播不利的几点因素

再说baseline做强交互不利因素之前,先说说现在直播的场景情况。

 

场景如上图,推流段不是移动平台,就是PC机。当然最近几年也出现专门用来推流的定制盒子,本质不是一个嵌入式windows,就是一个android设备(android设备较多)。

  • 而对于PC机作为推流端来说其实问题并不大,只要在保证带宽足够理想的情况下,采用264的任何一种profile都能尽可能的做到最大延时接近编码器固有延时的效果。同样对于使用何种容器来说问题都不大。

 

  • 但对于移动设备来说,需要匹配的情景就很多了,主要是由于移动设备的电池续航能力、操作系统小类别太多、整体性能表现。在使用264编解码时,一般尽量采用硬编解码,对于实在没有办法的情况下才使用软编解码。就仅仅一个硬编解码上就存在诸多差异,例如有些profile硬件不支持,或者rom上存在一些问题导致本该支持的profile,支持的不好或者根本不支持。

 

  • 除了上述提到的问题以外,其实还有一个隐形问题,那就是用户使用习惯问题。现在的用户越来越偏向于使用web方式展现的产品,一方面对于开发者来说,界面改动较为简单灵活,另一方面对于用户来说,只需要打开浏览器即可,简化使用步骤。

然而上述提到的这些问题,就造就了可能大家会想到flash、h5和native应用,对于native应用来说还好,开发起来虽然周期长,但可塑性比较强。对于flash和h5来说可选择余地就非常小了。

暂时不说flash和h5本身在做双向强交互直播是否可行,先说一说两者采用的协议类型。对于flash来说:

  • 通讯协议为rtmp系列协议(包括rtmpt等),协议本身并不是太复杂,但涉及当初并不是用来做双向强交互的直播协议,因此协议本身就没有在双向强交互上做太多的考虑。

 

  • 由于协议本身所承载的流媒体容器格式为flv或f4v,现在大部分直播平台基本采用的是flv作为容器,同时flv也是一种较为简单易用的容器

 

  • 但由于flv容器格式的限制,在adobe官方手册中就已经说明,flv容器支持的264的profile范围中,目前仅对baseline、extended、main、high、high10、high4:2:2、high4:4:4,在经过简单测试之后,如果不考虑flash端推流的情况下,用户电脑(移动端一般用h5,不用flash)性能具备一定保证的情况下,再根据官方手册并测试(as3手册),没有实际去测试过high10,不过脑补得知high10也是可以的,但延时太大,也有可能会引起其他flash异常。因此往往最佳的选择就在baseline、main、high中选择,因为他们的颜色编码是8bit的。从解码效率和广泛性来说,这三种都可以。

 

  • 但由于是双向直播,因此,在这时就需要考虑编解码器的时延问题。这时,大家一贯的做法就是关闭B帧编码,这样即可极大的提高编解码延时。当关闭了B帧编码之后,剩下几种profile互相比拼的就是在给定的一个平均分辨率、gop的情况下,编解码固有时延和数据码率,以及支持的广泛性。实测之后发现high其实在不同浏览器的flash上表现存在一定差异,主要情形为编解码速度、性能开销等等。因此在flash上使用high这种方式时,还需要综合考虑。

 

接下来说一说h5方式的直播:

  • h5方式的直播一般是通过websocket进行通讯,协议是hls,容器格式为ts、ps。然而我对hls和ts、ps都不是很了解。

 

  • h5支持还有待进一步推广,目前在较新的chrome系浏览器和较新的firefox浏览器上均支持较好。IE系暂时较弱(我把edge理解成IE系)。

 

  • 就目前来说,从开发手机端开发难度,和各手机厂商的支持力度上,无论是webview app还是native app来说,hls+ps/ts也是较优选择。

 

  • 通过看了苹果官方的FAQ得知,hls协议似乎仅仅支持baseline、main、high三种,不清楚是由于ts、ps容器特性导致的,还是hls协议特点。因此在决定使用哪一种profile时,又回到了和flash一样的情况下。

 

通过以上可以得知,实际上在使用x264编码时,最终在profile的选择上基本就限制在了baseline、main、high三种。从算法复杂度上来上讲,baseline是最为简单,而high是较为最为复杂(主要是预测模型比前两者多不少)。

不过在实际工程应用中,我们还是做了一个比较脑残又没有办法的决定,那就是使用baseline。原因有二:

  1. 我们使用的编码库是openh264,早期版本的openh264宏块分割方式较小,也仅仅支持baseline,对main也只是仅限于试验阶段。
  2. 在同样的profile级别下,参数大致相同的情况下,openh264的编码时延比x264的utral模式下略高,但码率略低(未做定量测试,简单定性测试得到的结论)。编码完的数据解码出来的视觉感受差别不大,反正都是渣画质。

考虑到使用场景和当时网络的大环境,确实选择openh264,即是无奈的选择,也是一个极其脑残的选择。说无奈主要是现实,说脑残是因为压根就没有做过定性分析。。。。。。

然后接下来就开始“数落数落”baseline不适合做双向强交互直播的原因。在看x264的代码时,偶然对编码中的预测做了少许的了解。

—- 我是装逼的分割线 1号 —-

传统上对一副图像的处理,一般的理论是基于“分割”,由于图像一般情况下具有前景和后景之分,也就是说,前景和背景之间存在着大量的局部图像细节,对于图像压缩中的思路往往是,尽量将相似的区域用差别不大的统一一个区域去表达,对于差异较大的区域,尽量在用较多的数据量去存储以此保留图像的局部细节。

那么就会存在如何分割图像的问题。如果是一副简单单值图,例如大学时代我做的非矢量图压缩(理论基础差不多),那么只需要根据图像分辨率,做相应的最佳分割快大小计算,并做简单切割即可。将区域内的有色的点和无色的点进行记录,并按做纵向或横向切割成色带,记录色带中有色点或者无色点的坐标值即可。整个思路转换成代码思维,类似于多级联映射表。当然这个做法的关键还在于公式如何设计,即如何动态计算切割区域的大小。由于是做印章方面,所以图像不会太大,因此公式也非常简单。

最终压缩可以理解成单值图的无损压缩,实测试之后,和转换成矢量图之后的文件大小相比,应该两者都会比现在主流的大部分图像编码小非常多。

接着通过类似7z、rar工具里面的二进制压缩算法进行再次压缩,文件最大还能缩小60%左右。一个500k的位图最终生成文件在3k左右。

—- 我是装逼的分割线 2号 —-

由于有上面的实践基础,因此在理解264的压缩时,我也能够理解到“分割”时的重要性。

首先,在baseline模式下,x264的预测模型相对于其他high来说,非常简单。这样的情况就决定了,在局部的细节切块相比high来说有着很多不足,对二进制数据进行压缩前就已经输在起跑线了。即细节丢失比high多。

其次在编码算法上(或者说压缩算法上),baseline仅仅使用cavlc,而对其他两者来说他们既可以使用cavlc也可以使用cabac。没有做过定性或者定考量分析,但通过网上资料获知,cavlc的效率似乎没有cabac高,具体在哪些指标有所体现目前暂时并不清楚。

因此,可以得知。baseline除了在实时性上满足了双向强交互直播对时间的要求,对于相同质量下的压缩比并不是很好。但又由于baseline相对其他profile的简单特点,其实广泛性还是比较不错的。

手里有台android 2.3时代的三星手机,对baseline的视频进行解码,手机基本可以应付(不清楚是硬解还是软解,因为当时的arm好像还有没有对264硬解做太多优化),但相同视频长度的main和high的话,那就有点头疼了。看来baseline对老旧手机还是比较“良好”的。

2017-11-22 | | matlab, 数据结构 & 算法, 音视频_图像相关, 音视频编解码

【h264、baseline、flv】使用baseline做双向强交互直播不利的几点因素已关闭评论

【x264、宏块、邻居】x264中对宏块预测方向与邻居类型的定义

在x264中,由于单一宏块预测方向与264规范定义实际上是一直的,即预测方向只有:左(left)、上(top)、左上(left-top)、右上(right-top)。

没有其他的另外四个方向,估计可能是zig-zag的数据排列有关,或只是由于对称关系,不需要做重复预测。

有上述4中预测方向,x264中定义了几种邻居关系(下面拿I帧4×4的宏块距离说明):

  • 垂直方向,即I_PRED_4x4_V、I_PRED_4x4_DC_TOP,实际上是向上方向预测(top)
  • 水平方向,即I_PRED_4x4_H、I_PRED_4x4_HU、I_PRED_4x4_DC_LEFT,实际上是向左方向预测(left)
  • 左边和向上方向,即I_PRED_4x4_DC
  • 向上旋转到右上方向,即I_PRED_4x4_DDL、I_PRED_4x4_VL
  • 左边旋转到向上方向,即I_PRED_4x4_DDR、I_PRED_4x4_VR、I_PRED_4x4_HD
  • 左边旋转到向上方向,即I_PRED_4x4_VL
  • I_PRED_4x4_DC_128代表自身?
2017-11-21 | | 数据结构 & 算法, 音视频_图像相关, 音视频编解码

【x264、宏块、邻居】x264中对宏块预测方向与邻居类型的定义已关闭评论

【x264、视频、编码、宏块】编码成不同帧时,宏块参数的变化情况

出于好奇最近在看x264的源代码。

对于不管是263、264还265编码来说,图像的压缩大题思路实际上是没有太大变化的。

对图像的压缩和编码,分为相关和非相关部分。又由于263、264、265并没有定义一定是无损压缩,所以在压缩和编码上与音频的编码和压缩也有着相似的处理方式;即,按照人的视觉特性进行编码(人眼分辨画面细节的能力是有限的)。

相关性压缩(和编码)又分为帧内相关和帧间相关,即编码出来的I帧就是我们所说帧内相关,B、P帧则是帧间相关。

对于非相关编码部分,大部分都集中在图像的前期处理上,例如归一化、白平衡、色度调节等。步骤大致如下:

  • 在图像预处理完成后(归一化、降噪等),接下来就是x264较多需要做的事情图像编码与压缩(虽然x264自身也会做一些降噪、再降噪、色度调节等)。
  • 先说编码部分,x264里面先将一副raw数据(可能是yuv420,可能是yv12等等),进行切块(即宏块分割,图像简单预测)。
  • 将分割好的图像在做块内再分割(细节预测,找出图像细节部分,对细节部分在切割,变成小块)
  • 接着又对每一个块做相邻之间的差异化计算(其实就是求出差异),这个过程是最复杂的一个。

 

下面是对于不同类型帧切块分类的说明其他具体的解释会在后续说:

 


 

其中对于不同类型的输出帧,宏块的大小如下:

I帧:

16*16、8*8、4*4


P帧:

L0、8*8、SKIP


B帧:

DIRECT、L0L0、L0L1、L0BI、L1L0、L1L1、L1BI、BIL0、BIL1、BIBI、8*8、SKIP

 


 

 

2017-11-20 | | 音视频_图像相关, 音视频编解码

【x264、视频、编码、宏块】编码成不同帧时,宏块参数的变化情况已关闭评论

【webrtc、ios sdk 11、 xcode9】webrtc在xcode 9下的uuid_t编译错误

最近osx环境无意间升级了所有的包,并把xcode升级到了9。按部就班的继续编译之前可以正常编译的webrtc,后来不料,除了这么一个错误:

error: nullability specifier ‘_Nullable’ cannot be applied to non-pointer type ‘uuid_t’ (aka ‘unsigned char [16]’)

 

东查西查。最后就查到了之前的猜测,这里有解释:

https://forums.xamarin.com/discussion/103773/will-there-be-support-for-ios-11-sdk

因为xcode自带的是ios sdk 11的。就目前来说,这一点比较坑人,因为ios sdk 11的库和ios sdk 10的库在部分函数上的定义上有所区别。

而webrtc和相应的depot_tools也是今年年初的,因此使用的第三方clang编译器也相对xcode 9的步调来说老了一些。

为了不想增加麻烦,也就不打算用gclient了,因为当时不是我去拿的webrtc代码,也不知道会不会有坑。就果断把xcode降级为xcode 8。

xcode 8的下载地址:

https://developer.apple.com/download/more/

降级的方法:

http://osxdaily.com/2012/02/20/uninstall-xcode/

 

看来用第三方编译器也是让人比较头疼的一件事情。有时候ios上遇到的坑不比android少。。。

 

2017-11-01 | | [奇葩类]求上进系列, iOS, 移动开发, 编码技巧, 音视频_图像相关

【webrtc、ios sdk 11、 xcode9】webrtc在xcode 9下的uuid_t编译错误已关闭评论

【编译、ffmpeg、msvc】windows下编译ffmpeg

由于最近使用的ffmpeg及其相关的库太过于老旧,所以需要进行更新。

对于视频方面的编码主要用到h264,音频则用到mp3、aac、speex。

其中最为坑的,还是mp3和aac。因为mp3中的分支太多,为了简化问题,最后还是选用lamemp3作为编码器。在ffmpeg 3.0开始,ffmpeg就停止了aacplus的使用,改为使用fdk aac。并且ffmpeg还自带了一个aac编码器。

在编译过程中由于没有注意到这个问题,因此使用了内置编码器,导致he aac编码出来的数据缺少sbr段。因此需要外部加入fdk aac来完成。

 

  • 先说一说需要提前做的一些准备:

1、lamemp3源代码

2、speex源代码

3、fdk_aac源代码

4、x264源代码

5、ffmpeg源代码

6、安装msys2极其相应的工具(如果在windows上编译)

7、vs2015(如果在windows上编译)

 

lamemp3编译步骤:

直接代开源代码下vc_solution目录,使用vs2015编译即可

 

speex编译步骤:

打开win32目录下的vs2008直接用vs2015编译即可

 

fdk_aac编译步骤:

fdk_aac编译比较坑,不能在msys2中编译,需要用nmake(vs工具链)直接编译就好……

 

x264编译步骤:

在msys2中直接编译即可

 

ffmpeg编译步骤:

1,将speex、mp3、aac中include的部分代码拷贝到ffmpeg根目录下

2,在将相应的lib文件拷贝到根目录下的某个文件,这里用3rdparty来代表目录

3,执行编译命令

./configure –prefix=/c/work/github/ffmpeg_src_3.2/out –toolchain=msvc –enable-libx264 –enable-libmp3lame –enable-libfdk-aac –enable-nonfree –enable-libspeex –enable-gpl –extra-cflags=-IC:\\work\\github\\ffmpeg_src_3.2 –enable-shared –extra-ldflags=-LIBPATH:C:\\work\\github\\ffmpeg_src_3.2\\3rdparty\\lib

4,执行make和 make install之后即可

 

2017-08-31 | | win, 编码技巧, 音视频_图像相关, 音视频编解码

【编译、ffmpeg、msvc】windows下编译ffmpeg已关闭评论

【vs2013、msys2】vs2013命令行环境变量不继承到msys2

编译一些开源的时候不得不需要用到msys2。所以需要现在vs2013的命令行环境中启动msys2环境,这样就可以把vs的命令行环境变量继承到msys2。

目前最新版本的msys2会出现不继承的情况,主要由于msys2 中/etc/profile文件中继承脚本的过滤了vs的一些有效环境,参考csdn上一个博客的修改方法,修改成如下:

 

2017-05-17 | | [奇葩类]求上进系列, 编码技巧, 音视频_图像相关, 音视频容器, 音视频编解码

【vs2013、msys2】vs2013命令行环境变量不继承到msys2已关闭评论

【winxp、vista、webrtc、chromium】放弃支持xp的路上webrtc跟上了!

最近拿了59的分支代码,后来偶然看到webrtc把wavein/waveout函数族相关的代码删除掉,看git注释另外根据chrome弃疗的心语路程,webrtc终于放弃xp了。

但苦了我了。。。。。。因为国内还有着一大群xp用户。。。。

2017-05-08 | | *生活*, 思考, 音视频_图像相关, 音视频容器, 音视频编解码

【winxp、vista、webrtc、chromium】放弃支持xp的路上webrtc跟上了!已关闭评论

【chrome、webrtc】python-boto代理设置

webrtc最近半年的时间里又改代码框架,又改下载脚本!真***法科!

 

目前除了使用到python-curl、git、还用到了一个叫做python-boto的玩意,用来从aws上下东西的。不理解为啥不用自家的云。。。。

现在拿webrtc的代码,除了需要配置git、python-curl的代理,还需要配python-boto的代理。

python-boto的代理配置方式如下:

1,在某个目录中创建一个.cfg后缀的文件

2,然后填入内容如:

  1. [Boto]
    proxy=127.0.0.1
    proxy_port = 10808

3,命令行中输入!

  1. NO_AUTH_BOTO_CONFIG=C:\work\depot_tools\boto.cfg

2017-05-08 | | shell, windows-shell, 编码技巧, 音视频_图像相关, 音视频容器, 音视频编解码

【chrome、webrtc】python-boto代理设置已关闭评论

【c++11、webrtc、stl】利用stl“就地构造”提高代码性能

最近在看webrtc的trunk上最新的代码,今天无意间留意到了stl容器中的“std::vector<T>::emplace_back”。事实上在接触webrtc之初我就经常能看到这个方法的使用,只不过那时候的对webrtc完全不了解,所焦点都在webrtc是个什么东西上。

 

后来查stl官方文档,看到的解释为:

构造并插入元素

同时网站上也给出了列子,但并不是很明确。看vs2015中对该函数的实现,实在看不懂(因为和push_back的一个分支实现很非常相似)。google看到这个函数代表在vector内部进行构造并放到数组里。

这样做的好处在于不需要去特意写移动构造函数,也不需要进行任何移动操作。间接的加快了性能。

 

 

 

ps:由于网上的说法存在问题,所这里要明确更正一下。

emplace_backpush_back两个函数都是通过“布局new”的方式将元素对象的内存放到自己的中(并非栈中)。

 

 

2017-05-02 | | 思考, 算法导论, 编码技巧, 音视频_图像相关, 音视频容器, 音视频编解码

【c++11、webrtc、stl】利用stl“就地构造”提高代码性能已关闭评论

【MacOSX、iOS、跨平台编译】在跨平台编译时MacOSX Serria/XCode是我遇到bug最多的平台

最近被安排来搞定android、ios、mac、windows下的webrtc、ffmpeg和x264的编译问题。

除了由于webrtc配置工程的问题在windows下我自己的搭建环境无法使用,最终求助于之前使用的虚拟机环境以外,android下的webrtc都比较顺利,同样也是编译anroid环境的和windows环境的ffmpeg,相对来说也是比较顺畅(虽然还是出现了一些坎坷)。

但在Mac环境下编译webrtc、ffmpeg和x264就没有那么幸运了。简直就是人间地狱,首先说明一下,这个Mac机原先是有其他开发者在上面编译成功过这三个工程的,到我之后就开始出现了一大堆问题(当然也有可能我用的是用户新帐号的缘故)。

 

人间地狱的开始

  • 先说一说编译webrtc遇到的坑爹问题。由于webrtc编译环境我们只输出静态库,并不输出一个framework或者app,所以并不需要关心太多app层面的问题(如证书相关)。虽知道在webrtc的gyp检查项目中会对证书冲突做检查,由于机器中存在多个证书,导致gyp阶段无法生成正确的编译配置参数。导致折腾了一周,最后才发现和证书有关。虽然这个问题和gyp有一定的关系,但也只是我对mac上编译和交叉编译的被坑的起点。

 

  • 接着是x264和ffmpeg编译时,由于给我的工程之前都是能够成功编译的,现如今拿过来,除了Mac平台可以通过以外,真机和模拟器都不行。折腾来折腾去几天,最后发现是clang去找依赖的时候找错了,找了mac的依赖环境,而不是去找iphoneos的依赖,然后怎么调都没用。很是坑爹,就拿网上的现成脚本来跑也是不行。

最后去查config.log,发现一堆错误,其中ffmpeg的错误还有一个叫做gas-preprocessor.pl的执行错误,由于是通过git直接从网上拿下来的脚本,在没有任何修改的情况下,通过sftp发到mac里面,给了执行权限之后通过命令行直接执行一点问题都没有,但通过configure执行时就一直报没有权限的错,怎么也想不明白;后来试着用curl拿文件,居然通了。当时我就估计如果不是字符集的问题,就是权限标记位的问题。

接着再继续修改关于依赖的问题,仅仅一个交叉编译工具clang,居然在不同的工程里面对同一个路径参数能够出现多种不同的行为,后来还特意看了一下clang是不是GNU开源社区的代码,通过–version看到的内容如下:

Apple LLVM version 8.0.0 (clang-800.0.42.1)
Target: x86_64-apple-darwin16.4.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

可见这个坑是苹果自己的。可能是由于命令行的长度的不同,导致解析命令行的bug?或者其他什么坑爹问题?反正我是不知道了,近几年开始苹果的产品也不见得有多少优势了,正在被一点点拉小差距。如果不是为了混口饭吃,苹果的任何产品我真的不想去碰!

2017-03-20 | | linux-shell, shell, unix编程环境学习, 图像处理, 音视频_图像相关, 音视频编解码

【MacOSX、iOS、跨平台编译】在跨平台编译时MacOSX Serria/XCode是我遇到bug最多的平台已关闭评论

【MAC、iOS、Webrtc】由于证书问题导致webrtc编译隐形失败问题

由于最近在接手一些脏活累活,所以就被拉来解决一下ios下关于播放设备切换的问题,实际上当听到这个问题的现象是基本可以判断播放设备切换的时候没有重设播放参数引起的。

后面说为了给我个环境去调一下,iMac拿过来很开心的执行编译,谁知道编译隐形失败。。。之所以说隐形失败是gyt_webrtc和ninjia没有报错什么让人感觉在意的错。

捣腾了几天,七弄八弄的最后查到由于在执行gyp_webrtc后通过gyp生成的ninja中有几个主要工程配置没有生成。

当时由于感觉找到完整的问题了,今天过来就直接干脆手动执行后续的步骤把整个编译执行完成。起初发现有问题,因为i386的构架被打包到静态库了,然后网上找到删除掉i386方法,随之删掉i386手工合成最终的包,加入到xcode工程里面跑,结果连接失败,出现符号找不到。

继续查问题,最终还是留意到了gyp_webrtc的错误,错误如下:

iMac:build hyt$ ./ios.sh release
Updating projects from gyp files...
Traceback (most recent call last):
  File "../src/webrtc/build/gyp_webrtc", line 115, in &amp;lt;module&amp;gt;
    gyp_rc = gyp.main(args)
  File "/Users/hyt/webrtc/src/chromium/src/tools/gyp/pylib/gyp/__init__.py", line 538, in main
    return gyp_main(args)
  File "/Users/hyt/webrtc/src/chromium/src/tools/gyp/pylib/gyp/__init__.py", line 523, in gyp_main
    generator.GenerateOutput(flat_list, targets, data, params)
  File "/Users/hyt/webrtc/src/chromium/src/tools/gyp/pylib/gyp/generator/ninja.py", line 2469, in GenerateOutput
    pool.map(CallGenerateOutputForConfig, arglists)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/pool.py", line 251, in map
    return self.map_async(func, iterable, chunksize).get()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/pool.py", line 567, in get
    raise self._value
AssertionError: Multiple codesigning fingerprints for identity: iPhone Developer

网上查到主要是证书冲突问题。
解决步骤大致如下:

1,列出有效证书

security find-identity

2,寻找证书配置gyp文件

find . -name common.gypi | xargs grep CODE_SIGN_IDENTITY

会看到这么几行:

./chromium/src/build/common.gypi: ‘CODE_SIGN_IDENTITY[sdk=iphoneos*]’: ‘iPhone Developer’,
./chromium/src/build/common.gypi: ‘CODE_SIGN_IDENTITY[sdk=iphoneos*]’: ”,

3,用之前证书列表中Valid identities only的字段替换‘iPhone Developer’里面的内容

 

4,重新执行gyp_webrtc即可

2017-03-01 | | [linux总结], chromium, iOS, 移动开发, 音视频_图像相关

【MAC、iOS、Webrtc】由于证书问题导致webrtc编译隐形失败问题已关闭评论

【c++11、编译】较新版本的chromium和webrtc代码已经开始用c++11了

在最近webrtc的几个版本里,我一直尝试在windows上搭建编译环境。因为用惯了vs 2010,并且vs 2010之后的版本存在一个xp runtime的问题,所以一直想在vs 2010上编译。但是用不行,一直报错。

最近在看c++11标准,对比vs 2010 、vs 2013、vs 2015之后发现确实在c++11的支持上,vs 2015会更全面一些,所以最终还是只能用vs 2015作为编译环境来使用。

2017-02-06 | | win, 编码技巧, 音视频_图像相关

【c++11、编译】较新版本的chromium和webrtc代码已经开始用c++11了已关闭评论