您当前位置: 首页 »

编码技巧

分类目录归档: 编码技巧

【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错误已关闭评论

【设计模式】对代理模式的几点理解-

设计模式一直给我的感觉都是天书一样,一方面理解起来困难。另一方面书上的解释也较为枯燥,况且现在也还有很多号称设计模式大神的出现,也可能间接的让大家对同一个模式有了各种千奇百怪的理解。

设计模式这个东西出现初衷本来就是解决工程问题,而在解决工程问题时,每个人的角度不同,观点也就不同,并且在《head frist 设计模式》中,作者也强调过,没有任何一种模式的选择和使用是正确或者错误的,只有适合与否。同时对设计模式理解有偏差,甚至初学者也才会去讨论某某模式好,某某模式如何。对设计模式理解较为全面,工程经验较为丰富的人,只会说某种模式用起来较为自然。

代理模式可以的重点可以看作主要是屏蔽了实现细节,同时也对任务执行做了一个中转。让两个模块之间进行解耦。

例如一个消息队列的实现,对于消息队列来说,实现可复杂可简单。为了让消息队列的使用者能够更清晰的了解如何使用,首先需要对消息队列的一些内置方法进行屏蔽,在C++中,继承是无法做到这一点的,所以只能通过包装的方式来实现。

因此就产生了代理类来将消息队列的实现类进行包装,让消息队列的使用者更加关注与如何使用,让消息队列的实现者来关注如何实现,而对于代理来说,仅仅需要关注如何流转数据和流程即可。

2018-03-07 | | 思考, 程序结构/程序构架, 编码技巧

【设计模式】对代理模式的几点理解-已关闭评论

【C++11,自动变量,迭代】c++11下不同for循环的差别

先看如下代码片段

#include <vecotr>
#include <string>

#include "boost/algorithm/string/split.hpp"
#include "boost/algorithm/string/classification.hpp"
#include "boost/algorithm/string.hpp"

std::vector vStrArray; //里面存着一堆字符串,其中有一个字符串是这样的: " a.kbasdasdsad"

for (auto a : vector)
{
  boost::trim(a);
}
#include
#include

#include "boost/algorithm/string/split.hpp"
#include "boost/algorithm/string/classification.hpp"
#include "boost/algorithm/string.hpp"

std::vector vStrArray; //里面存着一堆字符串,其中有一个字符串是这样的: " a.kbasdasdsad"

for (std::vector::iterator a = vector.begin();
     a != vector.end();
     ++a)
{
  boost::trim(*a);
}

编译环境是vs 2015 update 3
分别执行完以后会发现,A代码片段没有任何变化,B代码片段的” a.kbasdasdsad”变成了”a.kbasdasdsad”。

单步的时候发现,a变量在A代码片段中,实际上是已经对被修改了。后来网上查了几篇资料,怎么也没有找到对auto的详细说明。加上c++ 11每个编译器实现可能存在一定的差异,因此只能认为,在auto修饰的for循环里,变量使用了写时复用的方式来处理。
如果要对vector里面的值进行修改,还是只能使用最原始的迭代器方法。

2018-01-03 | | 编码技巧

【C++11,自动变量,迭代】c++11下不同for循环的差别已关闭评论

【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编译错误已关闭评论

【osx、ios、xcode】编译x264、ffmpeg时出现sysroot警告

在编译x264和ffmpeg时会出现警告,截图如下:

实际上在命令行中已经看到,已经通过sysroot设置过目标平台的sdk的位置,但还是报错。通过google发现,新版本的xcode对sysroot参数关键字做了修改,将–sysroot改为-isysroot ,其他不变,编译通过。

2017-10-31 | | [奇葩类]求上进系列, iOS, 移动开发, 编码技巧

【osx、ios、xcode】编译x264、ffmpeg时出现sysroot警告已关闭评论

【编译、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已关闭评论

【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“就地构造”提高代码性能已关闭评论

【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了已关闭评论

【程序结构、系统构架】有效且高效的程序结构/构架之一

首先看一下下图,下图是stun或者说是NAT穿越时需要用到的NAT检测服务器拓扑组网图:

 

 

目前,PC B和PC A需要进行p2p连接,首要要知道他们所在的网络是呈现哪一种NAT类型。因此就涉及到了NAT检测服务器(stun服务器)和客户端。

NAT检测服务器的功能实际上很简单,就是自身拥有2个或2个以上的IP,并每个IP监听至少2个UDP端口,一共就有4个可连端(即4个socket)。

当客户端与NAT服务器进行通讯时,NAT服务器和客户端都将会知道客户端外网IP:Port,和客户端内网的IP:Port。

但在实际设计NAT检测服务器时,就遇到了一个问题:NAT服务器是否需要记录客户端的IP:Port信息。如果需要记录出于什么目的?如果记录那需要多少存储能力和计算能力?

 

首先分别讨论一下存储和不存储的情况。对于存储客户端IP:Port信息来说,可以有效的统计和判断当前客户端群(带了个“群”字样)的NAT情况,并且能够间接节省掉一个统计数据上报的过程,数据的及时性和有效性也得到了保障。但带来的是服务器程序设计上的复杂性和性能损失,带宽成本相对于不存储的来说或许会更低一些。

对于不存储的情况来说,客户端可以设计的很简单,并专注于NAT类型检测的任务,单点抗压能力可以发挥到最大;但带来的是数据统计与反馈方式需要另辟蹊径,增加了客户端的复杂度,某种程度上来说会增加带宽的支出(需要将IP:Port数据上报)。为了该工作还需要配套一个完整的数据统计与上报模块(服务端+客户端),某种程度上增加数据反馈的不可靠性。

 

在看新版本webrtc的p2p模块时(nat检测服务器),发现服务端并不存储任何客户端的信息,只是由客户端来自行决定是否存储。于是想到了这个问题。

 

对于NAT服务器来说,确实不应该存储过多的客户端信息,但如果在需要可靠性较强的环境中时,NAT检测服务器还是存储一定的客户端信息。并将一些服务器不需要做的计算和存储工作保留在客户端可以有效的达到合理使用的目的。

 

例如:在NAT检测中,往往会出现两种情况,即:

1,多级NAT中的NAT在不同时间段呈现不同的NAT类型(不规则NAT)

2,在单级NAT中,由于IP、Port限制型场景中,由于检测次数的不够充分,将IP:Port误判断成其他类型的NAT。

在这两种情况中时,需要进行定量或者定性统计分析时,如果数据仅仅保存在客户端时,由于样本不够大(NAT检测次数不够多、该局域网内可能不只一个客户端),导致分析不充分,进而影响NAT穿越成功率以及间接影响分享率、分享公平性。

所以需要将此类数据进行服务端统计,并作筛选,才能有效的判断出该NAT环境下较大的概率会呈现哪一种NAT。

2016-12-23 | | 程序结构/程序构架, 编码技巧, 网络协议

【程序结构、系统构架】有效且高效的程序结构/构架之一已关闭评论

【脑筋急转弯】利用set和vector做排序、去重

在看webrtc的代码时,遇到一个ip地址池在set和vector中颠来倒去的代码,顶着看了一会,后来才反应过来。代码如下:

std::set<rtc::SocketAddress> addrs(all_servers_addrs_.begin(),all_servers_addrs_.end());
all_servers_addrs_.assign(addrs.begin(), addrs.end());

原先在all_servers_addrs_中已经保存了一个ip列表,通过导到set之后,首先去重了ip,接着再按照’>’算术运算符来进行排序,接着在通过assign将排序去重后的数据返回vector。

这样做的好处在于,时间复杂度为set排序复杂度+set随机访问的时间复杂度的总和,大致可以避免vector(类似线性表)的较高插入删除复杂度的问题。

2016-12-20 | | [奇葩类]求上进系列, 思考, 编码技巧

【脑筋急转弯】利用set和vector做排序、去重已关闭评论

【matlab、启动错误】在远程桌面中无法启动matlab问题

最近一直在通过远程桌面的方式使用笔记本,突然发现matlab死活都打不开,出现如下错误

555

 

起初以为安装出问题,后来网上看了下才知道是远程桌面的锅。直接用基本登录,问题解决。

2016-11-22 | | matlab, win, 图像处理, 数据结构 & 算法, 编码技巧, 音视频_图像相关

【matlab、启动错误】在远程桌面中无法启动matlab问题已关闭评论

【代码级优化、细枝末节、汇编】关于for一些写法细枝末节的优化

首先先看一下下面两段C++的代码

for_1

for_3

这两段代码唯一的区别在于条件区域的代码不同,一个是在外面先把end的游标获取到,一个是在for执行的过程中动态获取。如果实在想不明白,那就直接上汇编把。

for_2

for_4

实际上在《高效C++》中就提到过关于for条件区域代码每次哪一种写法性能好,哪一种写法性能差。由于end函数在这里的性能开销可以忽略不计,但如果不是调用end而是调用一个性能开销比较大的函数,那么这个for循环会很慢;在多线程模型中,如果for中的条件区域代码是线程间需要同步的,那么有可能这个条件区块代码的执行结果在每一次循环时都会发生变化。

对于这种代码级的优化,实际中最好少用或者不用,但并不是不带着优化的思维去写代码,而是在写的时候就要意识到这块代码可能会成性能瓶颈。

2016-11-19 | | win, windbg, 思考, 算法导论, 编码技巧

【代码级优化、细枝末节、汇编】关于for一些写法细枝末节的优化已关闭评论

奇葩的笔试题,符号优先级

首先说明,本文章讲述的是C、C++方面的奇葩类笔试题,之所以奇葩是因为没有考到C、C++中真正需要关注的部分,也间接能看出出题人对C、C++的了解层度。

 

最近在外面试,有做笔试,也有不做笔试的。因为工作有一些时段,所以不做笔试也算说的去,但一遇到做笔试题往往弄得我哭笑不得。不是拿一些太基础的题来糊弄人,就是拿一些技巧性的题目来糊弄人。最为关键是招聘方所谓的技术人员还很自以为是。面试应该是互相尊重的过程,而不是耀武扬威的一个过程,下面就分享这么一题笔试题,也算是复习一下我自己的基础。

 


int count=0;
int iarraytestA[10] = {11};
int iarraytestB[10] = {11};
int iarraytestC[10] = {11};

while(count < 10)
{
iarraytestA[count++] = count;
}

count = 0;
while(count < 10)
{
iarraytestB[++count] = count;
}

count = 0;
iarraytestC[++count] = count;

 

求iarraytestA和iarraytestB的结果。用vs跑了一下,结果一样:

iarraytestA:0,1,2,3,4,5,6,7,8,9
iarraytestB:11,1,2,3,4,5,6,7,8,9
iarraytestB:11,1,0,0,0,0,0,0,0,0

后来仔细想想,这个应该是算术优先级的问题。这里面的符号有几个:

赋值、自增(前向和后向)、数组寻址

查了一下符号优先级表,发现++运算符的优先级和[]一样,而=的优先级就不用多说,应该是最低的。
由此可以得出上述结论。

首先在这套题里,主要考了笔试C、C++中对这几个符号的认识,另一个这道题最蠢的还在于使用了不该用的技巧在考人。在C、C++规范中对相同优先级的符号做过的约束并不是很明确(C++11有所改善),在高效C++中有大量例子说明不应该使用技巧性过强的写法,这样会导致不同编译或不同编译参数编译出来的代码有不同行为。

这也同样说明了出该笔试题的人对C++也不是那么了解,真正在C++中笔试中有很多类型的题目可以出,但也不是都能出,因为语言规范的原因,对于单纯考算法的问题,也有很多大神做过讨论。我只是觉得学以致用,考什么都不要紧,关键和工作实质内容有没有关联?

ps:另外强烈鄙视钓鱼招聘,叫人过去面试就是为了打探技术方法和商业信息!

2016-11-17 | | [奇葩类]求上进系列, *生活*, 思考, 编码技巧

奇葩的笔试题,符号优先级已关闭评论