㈠ 大部分手机厂家不用麒麟海思的芯片,其原因是什么
一方面是麒麟芯片的产量不足以供应其他的厂商。另一方面麒麟芯片也是华为的一项核心技术,并不是可以外出出售的。
华为手机的麒麟芯片是我国国产芯片当中目前可以量产使用的核心处理器之一,对华为公司来说是非常重要的一项核心技术。由于华为公司本身的技术差距以及沉淀实力,因此他们本身的芯片产量不足以供应其他的厂家。同时华为对于自己的芯片技术也是非常看重并且严格保密的。
一:在同等价格下,麒麟芯片的价格非常高昂。
麒麟海思芯片是华为沉淀了许多年,花费了大量人力物力所生产出来的国产研发芯片。由于华为本身的技术实力肯定要比高通和联发科等其他厂商要逊色许多,因此麒麟芯片的单个芯片造价以及研发价格是非常高昂的。因此许多厂商为了保证自己的手机生产的利润,购买麒麟芯片就是一种非常不划算的做法。
㈡ 学音视频开发需要学数字逻辑吗
总体来讲,音视频开发是有一定的技术门槛的,我觉得至少需要在这个领域踏踏实实积累个3-5年,才能对音视频相关的开发知识有一个整体、深刻的理解。
从技术上来讲,需要从如下两个大类知识点上去积累:
C/C++通用开发知识
音视频开发的主要编程语言就是C和C++。
这块的专业知识积累是通用的,并不局限于某个特定的行业,属于程序员的技术功底。
可以重点关注如下几个方面:
计算机系统的底层工作原理
操作系统原理
程序的编译、链接和加载机制
C/C++语言特性背后蕴含的思想,底层工作原理,适用场景,存在什么样的问题
软件设计原则和设计模式
数据结构和算法
多线程并发编程原理
网络编程
跨平台
操作系统API
软件调试
2. 音视频领域专业知识
这块属于从事音视频行业的专业知识。
这块的专业知识是非常多的,每个功能模块背后涉及很多专业的知识。
音视频的开发可以分为两大块,涉及的内容大致如下:
音视频客户端开发
客户端应用开发
音视频引擎开发
音视频引擎SDK
音视频引擎框架
音视频引擎功能模块
音/视频采集
音/视频渲染
音/视频数据处理
音/视频编/解码
录制
串流
音视频同步
流媒体服务器开发
通用服务器开发知识,需要关注如下几个点
高稳定性
高性能
高并发
高可用
流媒体服务器开发
SFU vs MCU
流媒体协议转换
弱网下的音视频传输协议
录制 & 转码
…
上述内容中,客户端应用开发、音视频引擎SDK、音视频引擎框架、通用服务器开发等主要涉及C/C++通用开发知识,但要设计好这些部分必须对音视频相关的知识和产品业务有比较深刻的理解才能做到。通常,音视频架构师比较关注这些部分。
而音视频引擎底层功能模块和SFU/MCU流媒体服务器的开发,则和音视频的专业知识密切相关。
已经给大家准备好了安装环境和各种视频资料,资料放在自己的群里面:832218493(需要自取)
视频数据可以通过如下方式获得:
USB摄像头
专业的硬件视频采集卡(有软压卡和硬压卡之分)
网络摄像机(支持RTSP协议)
操作系统提供的屏幕录制API
读取音视频文件并解码
订阅流媒体服务器上的流
音频数据可以通过如下方式获得:
声卡
扬声器播放声音的回环采集(依赖操作系统的API)
读取音视频文件并解码
订阅流媒体服务器上的流
支持音频输入的网络摄像机(支持RTSP协议)
支持音频输入的视频采集卡
在手机上,操作系统的SDK会提供相关的音视频采集接口
音/视频渲染
视频渲染一般需要了解OpenGL,而音频渲染需要了解OpenAL
可以通过开源库SDL来快速实现渲染模块
在Windows下使用DirectShow框架,操作系统提供了对应的视频和音频渲染模块(通过GraphEdit可以看到)
在DirectShow中渲染器会涉及到音视频同步的策略,当然,也完全可以自己去实现音视频同步模块
音/视频数据处理
这些模块基本是在编码前或解码后,对视频或音频的原始数据进行某种算法上的处理
视频处理主要包括分辨率转换、色彩空间转换、帧率转换、图像增强、多路视频拼接、添加字幕、添加LOGO图片等,这块对整体的性能影响比较大,往往需要使用SIMD指令进行汇编优化或使用GPU算法进行加速
音频处理主要包括回声消除、噪声抑制、自动增益、混音等,这块往往会涉及比较多的信号处理和数学知识,是音频中比较复杂的一块
音/视频编/解码
视频编/解码
要理解视频的基本编码原理,熟悉视频编码的关键参数和码流格式
目前使用比较多的是H.264,H.265开始逐步在使用,其他的视频编码也有很多,如AVS、VP8、VP9等
视频编码对音视频引擎的性能影响比较大,这块基本都是需要使用GPU加速的,目前的Intel集显对H.264和H.265支持还是比较好的,NVIDIA的独立显卡在编码上存在路数的限制;手机上一般都有对应的硬件加速模块;在性能较好的硬件上,可以考虑开源的X264
音频编/解码
要理解音频的基本编码原理,熟悉音频的关键参数和码流格式
目前使用比较多的是AAC,其他的音频编码也有很多,如G7.11、G.722、OPUS等
在PC上,一般音频的相关模块对性能的影响不明显,但在海思嵌入式系统上,音频模块对性能的影响就不能忽略,因为海思基本没有提供音频的硬件加速模块,而ARM CPU性能也有点弱
录制
需要理解FLV、MP4、TS等容器格式
对于特殊的录制方式要注意软件的处理方式,例如,加片头和片尾的录制功能,追加录制
MP4录制要注意moov box放在文件开始或结束对录制文件的写入和点播的影响
录制时音视频均匀混合的策略
串流
理解视频互动、直播和点播的工作原理
关键评价指标
延迟
首屏时间
同步
流畅性
画质/音质
理解下述的几种音视频传输协议
RTMP
HTTP + FLV / Websocket + FLV
HLS
RTP & RTCP
RTSP
SIP
WebRTC
H.323
弱网下的音视频传输协议
理解TCP协议栈原理
可靠的UDP传输协议
KCP
SRT
QUIC
FEC + 丢包重传机制(如NACK)
音视频的开发并不是完全从零开始,而是有许多可以依赖的开源库,但要用好这些库,需要对上述的音视频专业知识有深刻的理解。
比较常见的音视频开源库,如下:
ffmpeg
可以直接使用ffmpeg的命令行实现转码、切片等常见功能
可以基于FFmpeg API封装开发自己的音视频模块
live555
比较完善的RTSP库
x264
比较常用的H.264编码库
fdkaac
比较常用的AAC编解码库
librtmp
支持rtmp协议,产品化时需要自己进一步完善
pjsip
支持sip协议
webrtc
google开源的webrtc库,有比较好的音/视频引擎,对网络状态的实时评估可以借鉴,回声消除模块也是比较有名的
SDL
比较有名的音视频渲染库
SRS
国内比较知名的RTMP流媒体服务器,支持HLS、HTTP+FLV,4.0版本开始支持WebRTC
OWT
Intel开源的WebRTC套件,支持了WebRTC客户端SDK和分布式的WebRTC MCU服务器
OpenCV
着名的视频算法库
另外,视频的编码和解码可以基于Intel Media SDK和NVIDIA的NVENC来实现。
在海思嵌入式上,海思芯片(如Hi3531D等)提供了硬件的音视频采集、音视频渲染、视频编/解码、视频图像处理等核心功能,这就需要借助于海思提供的SDK进行开发了。
顺便给大家推荐一个学习音视频的学习大纲 需要自取:
C++linux服务器音视频资料分享
QQ群名片
㈢ linux 编译安桌系统 海思
一般是编译之前的配置出问题了,好好看看readme,根据你自己的环境重新configure一下。
㈣ 海思3516DV300搭建交叉编译环境问题记录
刚开始搭建海思交叉编译环境的时候遇到问题:
安装完arm-himix200-linux后,输入arm-himix200-linux -v,会出现如下错误:
xxx@xxx-virtual-machine:~/Downloads/study3516DV300/rp-hi3516dv300-busybox/sample/hifb$ arm-himix200-linux-gcc -v
arm-himix200-linux-gcc: loadlocale.c:130: _nl_intern_locale_data: Assertion `cnt < (sizeof (_nl_value_type_LC_TIME) / sizeof (_nl_value_type_LC_TIME[0]))' failed.
错误方法:
export LC_CTYPE=C.UTF-8
这样做的话,arm-himix200-linux-gcc -v会显示成功,但是当去编译sample时候,会出现这个错误
collect2: fatal error: /opt/hisi-linux/x86-arm/arm-himix200-linux/host_bin/../lib/gcc/arm-linux-gnueabi/6.3.0/../../../../arm-linux-gnueabi/bin/nm terminated with signal 6 [Aborted], core mped
解决方案:
vi ~/.bashrc
最后加入这两句,完成后保存
export LC_ALL=C
export PATH="/opt/hisi-linux/x86-arm/arm-himix100-linux/bin:$PATH"
编辑之后使环境变量生效的命令:source ~/.bashrc
之后编译sample通过,生成sample_hifb文件。
㈤ 物联网实践 | Huawei LiteOS开发环境搭建及Demo程序在Hi3861上编译烧录运行
本次实践是为尝试在嵌有华为海思芯片的 Hi3861 WIFI物联网开发板上配置开发环境并使用配套开发工具( HUAWEI DevEco Device Tool 或 HUAWEI LiteOS Studio )将Demo工程编译烧录和运行。
参照华为海思编撰的 《物联网技术和应用》 进行搭建。
1.确认开发环境已经正确安装后,启动 Huawei LiteOS Studio
2.新建工程, SDK版本 选择 HiHope WiFi_IoT Hi3861SPC025 ;
SDK目录 在HiSpark_Pegasus_TechnologyApplication_IoT_Kit下的 HiHope_WiFi-IoT_Hi3861SPC025 ;
参考目录 选择在HiSpark_Pegasus_TechnologyApplication_IoT_Kit下的 HiHope_Pegasus_HelloWorld 。
目标板Hi3861V100。
3.按F4进入工程配置, 目标板配置 中:厂商 HiSilicon ,选中目标板 Hi3861V00 ,确认。
4. 编译器配置森渗散 中:SConstruct脚本,点击文件夹右侧的放大镜自动搜索SConstruct脚本位置,正常搜索完点确认。
5. 烧录器配置 中:烧录方式选择 HiBurner ,确认。
6. 串口配置 中:成功连接Hi3861板后,端口选择唯一一个COM端口;波特率选择 921600 ,确认。
7.F7 编译 ,成功此氏时终端输出紫色 BUILD SUCCESS 字样。
8.F8 烧录 ,出现HiBurn程序窗口时,按一次喊链Hi3861板上的Ret按键,烧录开始。成功时如图:
9.烧录完成,重新拔插数据线,HelloWorld程序运行正常,OLED屏上显示Hello World字样,Hi3861板上LED灯闪烁。
㈥ 我在编译海思给的例程时,出现这个错误,怎么解决
从你的描述上来看,你应该是直接拷贝了别人的工程或者是例程来编译的吧看直接这样编译的话会出这个问题的,你可以这么做,先把对应编译目录下的.obj文件和其他的调试文件全部删除,但是一定保留源文件和工程文件,这样再重新编译就可以了,这个原因是因为编译的时候需要制定对应的目录的,你从别人那里直接拷过来的话,目录不一致,因此出现找不到文件的问题,只要删除那些非源代码文件就能解决了
㈦ 怎么使用Android源码编译c模块生成可执行文件
1. 在./development目录下创建一目录 如:myhello
2. 进入hello目录,在其下编写自己的.c文件,如: myhello.c
#include <stdio.h>
int main()
{
printf("hello world\n");
exit(0);
//return 0;
}
3. 在hello目录中,编写Android.mk, 内容如下:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := myhelloworld
LOCAL_SRC_FILES := myhello.c
LOCAL_MODULE_TAGS := optional
include $(BUILD_EXECUTABLE)
4. 回到Android源代码顶层目录,进行编译,make myhelloworld
5. 生成的可执行文件位于:out/target/proct/lotus/system/bin/ 目录下
6. adb push 到手机 /data 目录下,然后进入adb shell,到data目录下,执行./myhelloworld 皆可
手动编译连接【arm-eabi-gcc 的目录随andorid的版本而有变化,还有就是需要链接的文件如果比较多时,需要很多-l 就很麻烦了】
7、编译成目标文件:
#$(yourAndroid)/prebuilt/linux-x86/toolchain/[arm-eabi-4.2.1]/bin/arm-eabi-gcc -I bionic/libc/arch-arm/include/ -I bionic/libc/include -I bionic/libc/kernel/common -I bionic/libc/kernel/arch-arm -g -c helloworld.c -o hello.o
8、生成可执行代码:
#$(yourAndroid)/prebuilt/linux-x86/toolchain/[arm-eabi-4.2.1]/bin/arm-eabi-gcc -nostdlib -Bdynamic -Wl,-T,build/core/armelf.x -Wl,-dynamic-linker,/system/bin/linker -Wl,--gc-sections -Wl,-z,noreloc -o helloworld -Lout/target/proct/[generic]/obj/lib -Wl,-rpath-link=out/target/proct/[generic]/obj/lib -lc hello.o -entry=main
其中[ ]中部分根据实际情况修改
**************************************************
实验:
1. 建目录(my Android)/development/test, 在该目录下新建 Android.mk和fb_test.c文件
2. Android.mk文件
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := myfbtest
LOCAL_SRC_FILES := fb_test.c
LOCAL_MODULE_TAGS := optional
include $(BUILD_EXECUTABLE)
3. 以下为fb_test.c
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <linux/kd.h>
#include <stdio.h>
#define FBBIT_PER_PIXEL 32
#define FBBIT_PIXEL_IMAGE 16
#define PIXELS_WIDTH_BYTE 4
#define BYTE_PER_PIXEL 3
#define FB_GRAPHICS_PATH "/dev/graphics/fb0"
#define DEV_TTY0_PATH "/dev/tty0"
#define DISPLAY_ERROR -1
#define DISPLAY_SUCCESS 0
#define GET_BATTERYCAPACITY_ERR -1
#define MAX_STR 255
static struct {
int fd;
void *pixels;
struct fb_fix_screeninfo fixed;
struct fb_var_screeninfo var;
int align_xres;
} fb;
int getBatteryCapacity(void)
{
FILE *in;
char tmpStr[MAX_STR + 1];
char capfile[] = "/sys/class/power_supply/battery/capacity";
if (capfile == NULL)
return GET_BATTERYCAPACITY_ERR;
in = fopen(capfile, "rt");
if (in == NULL)
return GET_BATTERYCAPACITY_ERR;
if (fgets(tmpStr, MAX_STR, in) == NULL) {
printf("Failed to read battery capacity!\n");
fclose(in);
return GET_BATTERYCAPACITY_ERR;
}
printf("Battery capacity(ascii): %s\n", tmpStr);
fclose(in);
return 0;//atoi(tmpStr);
}
static int vt_set_graphicsmode(int graphics)
{
int fd, r;
fd = open(DEV_TTY0_PATH, O_RDWR | O_SYNC);
if (fd < 0)
return DISPLAY_ERROR;
r = ioctl(fd, KDSETMODE, graphics);
close(fd);
return r;
}
int display_init(void)
{
fb.fd = open(FB_GRAPHICS_PATH, O_RDWR);
if (fb.fd < 0)
return DISPLAY_ERROR;
if (ioctl(fb.fd, FBIOGET_FSCREENINFO, &fb.fixed) < 0)
return DISPLAY_ERROR;
if (ioctl(fb.fd, FBIOGET_VSCREENINFO, &fb.var) < 0)
return DISPLAY_ERROR;
fb.align_xres = fb.fixed.line_length /
(fb.var.bits_per_pixel >> BYTE_PER_PIXEL);
fb.pixels = mmap(0, fb.fixed.line_length * fb.var.yres_virtual,
PROT_READ | PROT_WRITE, MAP_SHARED, fb.fd, 0);
if (fb.pixels == MAP_FAILED)
return DISPLAY_ERROR;
vt_set_graphicsmode(KD_GRAPHICS);
memset(fb.pixels, 0, fb.fixed.line_length * fb.var.yres_virtual);
//display_update(fb.pixels, fb.align_xres, fb.var.yres);
fb.var.activate = FB_ACTIVATE_FORCE;
ioctl(fb.fd, FBIOPUT_VSCREENINFO, &fb.var);
printf("display_init ok\n");
return DISPLAY_SUCCESS;
}
void display_on(void)
{
ioctl(fb.fd, FBIOBLANK, FB_BLANK_UNBLANK);
}
void display_off(void)
{
ioctl(fb.fd, FBIOBLANK, FB_BLANK_POWERDOWN);
}
int main()
{
display_init();
display_off();//关显示屏
getBatteryCapacity();
sleep(5);
display_on();//开显示屏
return 0;
}