15AH, San Francisco

California, United States.

Send Your Mail At:

tianyingkejishe@sina.cn

Working Hours

Mon-Sat: 9.30am To 7.00pm

作者标题

Autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et dolore feugait.

Author Archive by stormwind

【ffmpeg】二、linux编译ffmpeg.so脚本改良与裁编

前言:在上一章已经介绍了,如何进行编译ffmpeg.so的一个完整过程。但是用的编译脚本较为基础,本章将要介绍如何优化以及ffmpeg的指定模块编译(裁剪)。注意,本系列从第二篇开始,会对脚本结构进行微调,目的是为了大家能举一反三,在使用中做到逐渐熟练其原理。

一、脚本优化

对于脚本优化,这里我将利用脚本中的function关键字进行脚本的提取,与上一篇不同,为了对比学习,这次针对单架构arm64-v8a(向下兼容64和32位)进行编译,脚本如下:

build_androidv8.sh

内容:

#!/bin/bash
make clean
 
API=21
NDK=/home/liuzihui/softwaresCus/ndkr21/android-ndk-r21e
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64
SYSROOT=$TOOLCHAIN/sysroot
#function方法名后面一定要有空格,否则报错
function build_android {
echo "===========================1========================"
./configure \
  --prefix=$OUTPUT \
  --target-os=android \
  --arch=$ARCH \
  --cpu=$CPU \
  --enable-asm \
  --enable-neon \
  --enable-cross-compile \
  --enable-shared \
  --disable-static \
  --disable-doc \
  --disable-ffplay \
  --disable-ffprobe \
  --disable-symver \
  --disable-ffmpeg \
  --sysroot=$SYSROOT \
  --cross-prefix=$CROSS_PREFIX \
  --cc=$CC \
  --cxx=$CXX \
  --extra-cflags="-fPIC" \
  $ADDITIONAL_CONFIGURE_FLAG
echo "===========================2========================"
make clean
make
make install
}
 
#arm64-v8a
ARCH=arm64
CPU=armv8-a
OUTPUT=/home/liuzihui/softwaresCus/ffmpegSource/ffmpeg-4.2.2/android/$CPU
CROSS_PREFIX=$TOOLCHAIN/bin/aarch64-linux-android-       #AR AS LD等通用
CC=$TOOLCHAIN/bin/aarch64-linux-android$API-clang     #CC单独指定,非通用
CXX=$TOOLCHAIN/bin/aarch64-linux-android$API-clang++  #CXX单独指定,非通用
ADDITIONAL_CONFIGURE_FLAG= #自定义附件选项,比如加”--disable-xxx –enable-xx”,其中,引号要带上
build_android

注意:这里和上一章不同的是用到了function关键字进行封装,然后部分变量定义(如ARCH、CPU等)放在了下面(其实这样做有别的好处,即多架构编译,后面文章会讲到)。

在上一篇文章中的ffmpeg-4.2.2源码目录下,终端命令:赋予权限和执行脚本:

chmod +x build_androidv8.sh
./build_androidv8.sh

效果:

二、指定模块编译(裁剪)

裁剪的意思是只编译部分我们需要的ffmpeg模块,这样不仅可以减小输出包大小,也能大幅度提高编译速度。

但是在介绍裁剪之前,我们需要了解哪些能裁剪,这就要了解ffmpeg8大模块他们之前的依赖关系:

由此可以看出,avtuil是一个非常底层的模块,不可以不编译,其余模块可以按照他们的依赖关系,进行选择性编译,下面就编译 arm64-v8a 架构下avfilter模块作为示例:

build_androidv8cut.sh

#!/bin/bash
make clean
 
API=21
NDK=/home/liuzihui/softwaresCus/ndkr21/android-ndk-r21e
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64
SYSROOT=$TOOLCHAIN/sysroot
 
function build_android {
echo "===========================1========================"
./configure \
  --prefix=$OUTPUT \
  --target-os=android \
  --arch=$ARCH \
  --cpu=$CPU \
  --enable-asm \
  --enable-neon \
  --enable-cross-compile \
  --enable-shared \
  --disable-static \
  --disable-doc \
  --disable-ffplay \
  --disable-ffprobe \
  --disable-symver \
  --disable-ffmpeg \
  --sysroot=$SYSROOT \
  --cross-prefix=$CROSS_PREFIX \
  --cc=$CC \
  --cxx=$CXX \
  --extra-cflags="-fPIC" \
  $ADDITIONAL_CONFIGURE_FLAG
echo "===========================2========================"
make clean
make
make install
}
 
#arm64-v8a
ARCH=arm64
CPU=armv8-a
OUTPUT=/home/liuzihui/softwaresCus/ffmpegSource/ffmpeg-4.2.2/android/$CPU
CROSS_PREFIX=$TOOLCHAIN/bin/aarch64-linux-android-       #AR AS LD等通用
CC=$TOOLCHAIN/bin/aarch64-linux-android$API-clang     #CC单独指定,非通用
CXX=$TOOLCHAIN/bin/aarch64-linux-android$API-clang++  #CXX单独指定,非通用
ADDITIONAL_CONFIGURE_FLAG="--disable-avdevice --disable-avcodec --disable-avformat --disable-swresample --disable-swscale --disable-postproc --enable-avfilter"
#avdevice,avcodec,avformat,swresample,swscale,postproc,avfilter可选不编译(都是默认开启的,avutil基本的,也是默认开启),为了提升编译速度和仅供演示,这里仅开启avfilter
build_android

注意:这里用 ADDITIONAL_CONFIGURE_FLAG 自定义变量指定了可编译选项,具体项目变量可自己定义别的名称,也可以不用该变量,直接写在./configure编译脚本中。

依然在ffmpeg-4.2.2源码目录下,终端命令:赋予权限和执行脚本:

chmod +x build_androidv8cut.sh
./build_androidv8cut.sh

效果:(libvutil.so是基础so,必生成,libavfilter.so即是我们指定模块编译的,且编译过程中我们可以看到,编译速度有大幅提升) 

【ffmpeg】一、linux编译ffmpeg.so入门

前言:在使用android进行音视频开发的时候,ffmpeg是一个利器。但是由于ffmpeg的编译涉及到交叉编译,让很多新手感到头疼。本系列将以多篇文章讲述如何编译so以及多种角度阐述原理。

本文使用环境:

编译环境:ubuntu16.04(在VMware15.5中运行)

ndk版本:android-ndk-r21e

ffmpeg版本:4.2.2

至于ndk版本的一点说明:

ndk:在ndk17以前,都是使用gcc编译,官方从ndk17及以后,全面改用效率更高的clang编译器进行编译。且clang对ffmpeg版本没有很高的要求。

如果ndk选用不当(如ndk17以下使用clang编译),会造成意想不到的错误。本文选用较为稳定的组合进行演示,即:ndk21(clang编译器)+ ffmpeg4.2.2

至于ubuntu登录系统的说明:

本文登录用户按照最常见场景的原则,使用普通用户登录模式,后续linux命令行执行角色都是这个普通用户,非root模式。

步骤一、准备工作

1、进入ubuntu系统桌面,在根目录下新建一个目录,如:/home/liuzihui/softwaresCus,然后新建两个目录,分别用于存放ffmpeg源码和ndk工具包。

注意:若vmware虚拟机里的ubuntu无法联网,也可以从windows里先下载好,再拷贝到wmware虚拟机里的ubuntu中的ffmpegSource目录中来。

ffmpeg网址(4.2.2版本):Download FFmpeg

2、ffmpeg源码下载:

在ffmpegSource目录下,在当前目录的终端(terminal)里使用命令下载ffmpeg4.2.2源码:

wget https://ffmpeg.org/releases/ffmpeg-4.2.2.tar.gz

 然后依然在当前目录的终端中,使用命令进行解压:

tar -zxvf ffmpeg-4.2.2.tar.gz

3、ndk使用21Linux版本

可以先从windows里下载好,完成后再放到ubuntu中刚才的(图1)中的ndkr21目录中:

NDK 下载  |  Android NDK  |  Android Developers

在ndkr21目录(图1中新建好的)执行终端解压命令:

unzip android-ndk-r21e-linux-x86_64.zip

说明:在很多教程中,都说ndk需要设置linux的环境变量,其实是不用的,完全可以在后续操作中写明全路径避免掉配置环境变量带来的研究成本。

步骤二:正式编译

经过步骤一,ffmpeg4.2.2和ndkR21的源码和工具包全部已经下载完毕,准备工作已经做好。接下来进行编译的具体讲解。

1、我们进入到(图3)中的 /home/liuzihui/softwaresCus/ffmpegSource/ffmpeg-4.2.2 目录中,新增一个编译用的脚本文件:build_androidv7.sh(可以先在windows新增并编辑,然后拷贝到该目录下),内容如下:

#!/bin/bash
make clean
#变量定义,变量前面的export可要可不要,如export API
API=21   #选择一个ndk有的,且期望兼容的android版本
ARCH=arm
CPU=armv7-a
OUTPUT=/home/liuzihui/softwaresCus/ffmpegSource/ffmpeg-4.2.2/android/$CPU #so输出路径,写好进行,编译完成后自动生成该目录
NDK=/home/liuzihui/softwaresCus/ndkr21/android-ndk-r21e
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64 #有的ndk是叫darwin-x86_64,看ndk目录对应
SYSROOT=$TOOLCHAIN/sysroot
 
echo "===========================1========================"
./configure \
  --prefix=$OUTPUT \
  --target-os=android \
  --arch=$ARCH \
  --cpu=$CPU \
  --enable-asm \
  --enable-neon \
  --enable-cross-compile \
  --enable-shared \
  --disable-static \
  --disable-doc \
  --disable-ffplay \
  --disable-ffprobe \
  --disable-symver \
  --disable-ffmpeg \
  --sysroot=$SYSROOT \
  --cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
  --cc=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang \
  --cxx=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang++ \
  --extra-cflags="-fPIC"
echo "===========================2========================"
make clean
make
make install

我需要对上述sh脚本进行一些讲解:

①API、ARCH、CPU、OUTPUT、NDK、TOOLCHAIN、SYSROOT是脚本语言的一种写法,可以理解为变量定义。网上有的在之前加了export xx,其实可加可不加。其中OUTPUT的输出目录,不需要手动创建,脚本会自行新建;

②echo进行了一个打印,这样做的好处就是在编译时,可以一开始就明显看到哪里脚本哪里没有配置对,利于排障。有一点需要注意,即使我们写错了脚本,但是编译过程虽然报错,但是依然在执行,且生成了一些so文件,这是为什么?是因为他帮我们执行了默认的脚本,这点需要注意,最好多次实践比较下;

③最重要的是cc和cxx的强制指定。因为在有些教程中,提及到了cc_default、cxx_default的问题,甚至要去修改ffmepg源码文件。其实这里大可不必大费周章且可维护性不强,直接在这里指定cc和cxx的路径,可以直接找到位于ndk路径中的cc和cxx的clang编译器(如:/home/liuzihui/softwaresCus/ndkr21/android-ndk-r21e/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi21-clang)

而cross-prefix前缀是留给AR、AS、LD用的,需要指定下,且脚本中已指定;

④ffmpeg4.2.2源码中已经支持直接指定target-os=android,而非旧版本的linux,故无需再修改configure文件中的SLIBNAME_WITH_MAJOR命名;

⑤本脚本只对armeabi-v7a架构进行了编译,若要编译arm64-v8a,请关注博主后续分享;

⑥在windows编辑好的build_androidv7.sh文件,拷贝到linux中,一般会遇到dox文件格式转unix文件格式的问题(比如报错:/bin/bash^M: bad interpreter),解决方案:

i、方案一:sed -i ‘s/\r//’ build_androidv7.sh;

ii、方案二:可以先vim该脚本文件,然后执行“: set ff=unix”,然后:wq保存。若在编译的时候,还是有问题,这时候可以右击该sh文件,选择open with gedit打开,再保存一下;

⑦请注意,脚本内容中./configure后续的命令项中不要加任何注释,否则在某些系统环境中会出问题,且要确保\符号后面没有多余不可见的空格字符串;

⑧本次sh脚本,会编译出libavdevice,libavcodec,libavfilter,libavformat,libavutil,libswresample,libswscale共7个so文件,后续文章会讲解如何进行so裁剪。

2、脚本写好后,接下来就是编译了(注意,要在 /home/liuzihui/softwaresCus/ffmpegSource/ffmpeg-4.2.2 目录下执行terminal终端命令,如下图)

①赋予build_androidv7.sh、configure两个文件的可执行权限:

chmod +x build_androidv7.sh
chmod +x configure

  ②执行编译脚本:

./build_androidv7.sh

③等待几分钟,便可以看到 /home/liuzihui/softwaresCus/ffmpegSource/ffmpeg-4.2.2 目录下自动生成了android目录,且lib目录里有我们需要的so文件,同时ffmpeg-4.2.2目录下也自动生成了本次编译生成的宏头文件config.h,里面记录了脚本过程:

④若想重新编译,先删除android目录,再次执行./build_androidv7.sh命令即可。ctrl+C快捷键可以中断编译。

【ffmpeg】使用FFmpeg和FFplay实现UDP流媒体的推送与拉取:单播、组播与广播【ffmpeg】

一、单播

ffmpeg -re -stream_loop -1 -i 123.mp4 -f mpegts  "udp://localhost:12345"
ffplay  udp://localhost:12345

二、多播

ffmpeg -re -stream_loop -1 -i 123.mp4 -f mpegts  "udp://localhost:12345"?multicast=1
ffplay  udp://localhost:12345?multicast=1

三、广播

ffmpeg -re -stream_loop -1 -i 123.mp4 -f mpegts  "udp://255.255.255.255:12345"?multicast=1
ffplay  udp://255.255.255.255:12345?multicast=1

【ubuntu】升级GLIBC高版本方法,解决:version `GLIBC_2.34‘ not found

1.编辑源:打开源文件

sudo vi /etc/apt/sources.list

2.添加高版本的源:把此行源添加到最后一行

deb http://mirrors.aliyun.com/ubuntu/ jammy main

3.更新源

sudo apt update

4.安装高版本GLIBC

sudo apt install libc6

5.查看结果:如下图所示

strings /lib/x86_64-linux-gnu/libc.so.6 |grep GLIBC_

6.添加路径:打开环境配置文件

sudo gedit /etc/bash.bashrc或者sudo vim /etc/bash.bashrc

7.配置环境:把下方代码加到刚才打开的配置文件的最后一行

PATH=$PATH:/usr/local/host/bin

注意:/etc/bash.bashrc 这个路径要换成自己的路径

8.使环境变量生效

source ~/.bash.bashrc

【git】git clone拉取项目时报错xxx bytes of body are still expected【git】

尝试了网友们的各种方法:

1、可能缓存区溢出,执行以下语句,将缓存设置为500M或者更大

git config http.postBuffer 524288000

2、可能项目过大,先进行浅克隆,然后更新远程库到本地

git clone  https://github.com/ycwu1997/MC-Net.git --depth=1 
git fetch --unshallow

使用以上两种方法都未解决,但大家也可以试试,我最终是通过第三个方法解决的:

3、可能下载速度慢,执行以下命令(不知道为什么是这个原因,因为我网速是没问题的。。。)

git config --global http.lowSpeedLimit 0 
git config --global http.lowSpeedTime 999999

【n2n】N2N参数讲解

一、supernode

sudo nohup supernode -l 7443 -v &

注:supernode需要运行在公网上。使用nobup后台运行,-l 7443监听7443端口,-v用于输出日志,便于调试。 查看日志tail -f nohup.out

二、edgenode

edge -a 10.233.233.1 -c N2NNetwork -k 85f7a0affa50d933485a215eb10fb921 -l 106.53.85.19:7443 -p 3447 -m 16:0c:98:c8:b7:92

edge -a 10.233.233.2 -c N2NNetwork -k 85f7a0affa50d933485a215eb10fb921 -l 106.53.85.19:7443 -p 3447 -m 6e:30:77:c9:4f:bf

edge -a 10.233.233.3 -c N2NNetwork -k 85f7a0affa50d933485a215eb10fb921 -l 106.53.85.19:7443 -p 3447 -m 82:e9:fc:be:e9:a7

参数说明:

  • “-a <IP地址>”选项(静态地)指定了分配给 TAP 接口的 VPN 的 IP 地址。如果你想要使用 DHCP,你需要在其中一台边缘节点上配置一台 DHCP 服务器,然后使用“-a dhcp:0.0.0.0”选项来代替。
  • “-c <组名>”选项指定了 VPN 组的名字(最大长度为 16 个字节)。这个选项可以被用来在同样一组节点中创建多个 VPN。
  • “-k <密钥>”选项指定了一个由 twofish 加密的密钥来使用。如果你想要将密钥从命令行中隐藏,你可以使用 N2N_KEY 环境变量。
  • “-l <IP地址:端口>”选项指定了超级节点的监听 IP 地址和端口号。为了冗余,你可以指定最多两个不同的超级节点(比如 -l <超级节点 A> -l <超级节点 B>)。
  • “-p <端口>” 边缘节点暴露端口
  • “-m ”给 TAP 接口分配了一个静态的 MAC 地址。不使用这个参数的话,edge 命令将会随机生成一个 MAC 地址。事实上,为一个 VPN 接口强制指定一个静态的 MAC 地址是被强烈推荐的做法。否则,比如当你在一个节点上重启了 edge 守护程序的时候,其它节点的 ARP 缓存将会由于新生成的 MAC 地址而遭到污染,它们将不能向这个节点发送数据,直到被污染的 ARP 记录被消除。

注:以上3条命令为三台机器上执行的,其中10.233.233.1,运行在supernode节点上,另外其中ip自定义,但是需要注意别与需要组网的机器中的IP冲突了,不然会找不到路由!

【phy】yt8521 phy芯片驱动移植

1、准备驱动文件

2、添加到相应目录

把motorcomm.c、yt8614-phy.h放到Linux的linux-5.19.1/drivers/net/phy/

把motorcomm_phy.h放到Linux的linux-5.19.1/include/linux/

3、修改Makefile

增加:obj-$(CONFIG_MOTORCOMM_PHY) += motorcomm.o

4、修改Kconfig

增加:

config MOTORCOMM_PHY
        tristate "Motorcomm PHYs"
        help
          Enables support for Motorcomm network PHYs.
          Currently supports the YT8511 gigabit PHY.