首先要确认使用的PSDK链路是哪一种,假如使用的是妙算2工程,则在payload-sdk\samples\sample_c\platform\linux\manifold2\application\dji_sdk_config.h文件中。
查看CONFIG_HARDWARE_CONNECTION的设置。
获取视频流功能必须要配置为BULK或NETWORK,其中NETWORK建议使用USB网卡,目前仅支持AX88179和RTL8152型号,其他型号的网卡暂不支持,已使用这些型号的开发者建议直接查看底部组件版本确认步骤。
以BULK为例:
从环境排查起,首先要检查bulk节点是否有正常拉起。如果有使用官方的bulk配置脚本,使用指令应可以搜索到两个节点。
如果无法搜索到两个节点,参考此文章重新配置:Linux平台配置BULK
确定有两个bulk节点生成以后,可以使用以下脚本测试BULK节点的数据收发,看是否正常。(如果不想做太复杂的测试,可以跳转到底部,查看最后一步)
其中,your_VID,your_PID和节点的信息可以通过此文章确认,需要注意的是,测试的节点需和PSDK中配置的节点信息保持一致。PSDK代码中的BULK节点配置
gcc -o bulk_device bulk-device.c -I/usr/include -lusb-1.0 -lpthread
bulk-device.c
#include "stdint.h"
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <libusb-1.0/libusb.h>
#include "pthread.h"
void device_Thread()
{
int32_t ret;
int32_t ep1, ep2;
int32_t actualLen, len;
char sendbuf[] = "USB bulk device data ...";
char readbuf[128] = {0};
//device bulk
ep1 = open("/dev/usb-ffs/bulk/ep1", O_RDWR);
if (ep1 < 0)
{
printf("open ep1 failed, ret[%d]", ret);
return -1;
}
ep2 = open("/dev/usb-ffs/bulk/ep2", O_RDWR);
if (ep2 < 0)
{
printf("open ep2 failed, ret[%d]", ret);
return -1;
}
while(1)
{
//read
actualLen = read(ep2, (uint8_t *)&readbuf[0], 128);
if (actualLen < 0)
{
printf("USB device read failed[%d]\n",actualLen);
}
else
{
printf("USB device recive data\t\t[%s], \tlen[%d]\n", (uint8_t *)&readbuf[0], actualLen);
//send
actualLen = write(ep1, &sendbuf[0], strlen(sendbuf));
//printf("device send ... \n");
}
sleep(1);
}
close(ep1);
close(ep2);
return;
}
int main()
{
int32_t ret;
int32_t actualLen, len;
static pthread_t deviceThread = 0;
struct libusb_device_handle *handle = NULL;
char sendbuf[] = "USB bulk host data ...";
char readbuf[128] = {0};
//host libusb
//char sendbuf[] = "bulk linker loop";
//char readbuf[128] = {0};
ret = libusb_init(NULL);
if (ret < 0) {
printf("libusb_init failed\n");
return -1;
}
handle = libusb_open_device_with_vid_pid(NULL, your_VID, your_PID);
if (handle == NULL) {
printf("libusb_open_device_with_vid_pid failed\n");
return -1;
}
ret = libusb_claim_interface(handle, 2);//Num
if (ret != LIBUSB_SUCCESS) {
printf("libusb claim interface error, ret[%d]\n", ret);
libusb_close(handle);
return -1;
}
if (pthread_create(&deviceThread, NULL, device_Thread, NULL) != 0) {
printf("create monitor task fail.\n");
return -1;
}
sleep(2);
//send
ret = libusb_bulk_transfer(handle, 0x0*, (uint8_t *) sendbuf, strlen(sendbuf), &actualLen, 50);
if (ret < 0) {
printf("libusb_bulk_transfer send failed[%d], endpointOut[%x], len[%d]\n",ret, 0x0*, strlen(sendbuf));
//return -1;
}
while(1)
{
//read
memset(&readbuf[0], 0x0, sizeof(readbuf));
ret = libusb_bulk_transfer(handle, 0x**, &readbuf[0], 128, &actualLen, 50);
//printf("libusb_bulk_transfer read_len[%d], ret[%d]\n", actualLen, ret);
if (0 == ret)
printf("USB host recive data\t\t[%s], \tread_len[%d]\n", &readbuf[0], actualLen);
sleep(2);
ret = libusb_bulk_transfer(handle, 0x0*, (uint8_t *) sendbuf, strlen(sendbuf), &actualLen, 50);
if (ret < 0) {
printf("USB host send failed[%d]\n",ret);
//return -1;
}
}
return 0;
}
如果测试数据收发没有问题,可以进行下一步,检查FFMPEG和OPENCV的版本与配置。
组件版本确认:
我们本地调试使用的ffmpeg版本和配置为:
ffmpeg version 4.4 Copyright (c) 2000-2021 the FFmpeg developers
built with gcc 10 (Debian 10.2.1-6)
configuration: --enable-shared --enable-swscale --enable-gpl --enable-nonfree --enable-pic --enable-version3 --enable-postproc --enable-pthreads --enable-static --enable-libvorbis --enable-libvpx
rsp@CUBE:~$ opencv_version
4.9.0
另外LIBUSB组件没有安装的话也会影响此功能的正常使用,可以在使用cmake .. 指令时进行确认,如未安装,可以使用以下指令安装:
sudo apt update
sudo apt install libusb-1.0-0-dev
验证安装完成:dpkg -l | grep libusb
可能遇到的问题:
1、报错
[167.697][core]-[Error]-[DjiLiveview_FindLiveviewSource:1165) Can not found the liveview source. Probably the payload is not mounted on position 0 correctly. Please check the mount position of payload.
[167.697][liveview]-[Error]-[DjiLiveview_StartH264Stream:546) Can't find source, errno: 0x00000100.
这个表示position 0的地方没有挂载DJI负载相机,需要检查下挂载位置是否与代码调用的数值对应。代码position 0/1/2分别对应实际位置是面朝飞机正面,机身右下方位置(0)、机身左下方位置(1)、机身上方位置(2)。
2、确认以上信息无误,仍无法获取视频流,可以在代码调用的地方加一些打印,看代码具体是卡在了哪个地方,我们建议使用妙算2的工程,其他工程可能会出现更新不及时或者长时间不维护的情况,为了避免已知问题的影响,建议使用妙算2的工程。
3、关于链路测试,还有一种方式,可以使用DjiTest_LiveviewRunSample(1); 来进行测试。像直接在main.c中添加调用。
然后在payload-sdk\samples\sample_c\module_sample\liveview\test_liveview.c文件的DjiTest_FpvCameraStreamCallback和DjiTest_PayloadCameraStreamCallback两个回调中分别加入打印。如果有进入这两个回调函数,并且当前目录下会生成以时间命名.h264为后缀的视频流文件,则说明获取视频流的链路是没问题的,此时可以重点排查软件环境相关的问题。
评论
0 条评论
请登录写评论。