__has_include

VS

在搞音视频的过程中,早期为了快速实现功能,会用到一些开源库,比如FFMpeg、OpenCV、LibYUV 等,这些大名鼎鼎的开源库能够解决音视频领域的很多问题,编解码、边缘检测、RGB-YUV格式转换等等。

这几个开源库还都是C/C++的,完美解决跨平台的问题,所以早期可以快速上线,但也会带来增加包大小的问题,这是最明显的,另外开源方案也并非没有BUG。对开源库做裁剪减少大小/提issue等待官方处理、自己处理BUG等这些成本相对也不小。

另一个选择就是使用其他的替代方案:比如原生的技术实现、解决指定问题独立模块算法、DIY

\ 编解码 边缘检测 格式转换
开源方案 FFmpeg OpenCV LibYUV
替代方案 VideoToolBox/MediaCodec 边界跟踪算法Suzuki85 DIY
说明 软解-> 硬解 边界跟踪算法Suzuki85 就是 OpenCV 内部的一种边缘检测方案 自己处理像素数据

后期通过替代方案可以解决上面提到的问题,主要是包大小问题。另外也可以自己动手加深了解开源的技术方案

__has_include

通过替代方案可以移除开源库,但是接入开源方案实现功能的相关代码就没必要移除了。所以可以通过条件编译做一个区分。
正好__has_include这个宏可以满足要求

  • 描述
    此宏传入一个你想引入文件的名称作为参数,如果该文件能够被引入则返回1,否则返回0。
  • 用法
1
2
3
4
5
#if __has_include(<XXX/XXX.h>)
#import <XXX/XXX.h>
#else
#import "YYY.h"
#endif

项目中的实际用法:

1
2
3
4
5
6
7
8
9
#if __cplusplus && __has_include(<Libyuv/libyuv.h>)
#include <Libyuv/libyuv.h>
#endif

#if __cplusplus && __has_include(<Libyuv/libyuv.h>)
...
#else
...
#endif
1
2
3
4
5
#if __has_include(<opencv2/imgcodecs/ios.h>)
contourArr = [OpenCVWrapper findContours:image];
#else
contourArr = [PContour findContours:image threshold:threshold];
#endif
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#if __cplusplus && __has_include(<ffmpeg/avformat.h>)

extern "C" {
#include "ffmpeg/timestamp.h"
#include "ffmpeg/avformat.h"
#include "ffmpeg/bsf.h"
#include "ffmpeg/swscale.h"
#include "ffmpeg/swresample.h"
#include "ffmpeg/avformat.h"
#include "ffmpeg/imgutils.h"
#include "ffmpeg/samplefmt.h"
}

#endif
...
#endif