㈠ 大部分手機廠家不用麒麟海思的晶元,其原因是什麼
一方面是麒麟晶元的產量不足以供應其他的廠商。另一方面麒麟晶元也是華為的一項核心技術,並不是可以外出出售的。
華為手機的麒麟晶元是我國國產晶元當中目前可以量產使用的核心處理器之一,對華為公司來說是非常重要的一項核心技術。由於華為公司本身的技術差距以及沉澱實力,因此他們本身的晶元產量不足以供應其他的廠家。同時華為對於自己的晶元技術也是非常看重並且嚴格保密的。
一:在同等價格下,麒麟晶元的價格非常高昂。
麒麟海思晶元是華為沉澱了許多年,花費了大量人力物力所生產出來的國產研發晶元。由於華為本身的技術實力肯定要比高通和聯發科等其他廠商要遜色許多,因此麒麟晶元的單個晶元造價以及研發價格是非常高昂的。因此許多廠商為了保證自己的手機生產的利潤,購買麒麟晶元就是一種非常不劃算的做法。
㈡ 學音視頻開發需要學數字邏輯嗎
總體來講,音視頻開發是有一定的技術門檻的,我覺得至少需要在這個領域踏踏實實積累個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;
}