当前位置: 首页 > article >正文

通过大疆PSDK,将第三方摄像头的视频流推到M300遥控器显示

1.首先确保跑通了大疆官方的demo,demo功能是可以将本地h264的视频文件推到遥控器显示。

2.将264格式设置为普通264(默认为大疆264),更改demo里的代码如下

   //returnCode = DjiPayloadCamera_SetVideoStreamType(DJI_CAMERA_VIDEO_STREAM_TYPE_H264_DJI_FORMAT);
    returnCode = DjiPayloadCamera_SetVideoStreamType(DJI_CAMERA_VIDEO_STREAM_TYPE_H264_CUSTOM_FORMAT);
    if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
        USER_LOG_ERROR("DJI camera set video stream error.");
        return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
    }
    //s_cameraVideoStreamType = DJI_CAMERA_VIDEO_STREAM_TYPE_H264_DJI_FORMAT;
    s_cameraVideoStreamType = DJI_CAMERA_VIDEO_STREAM_TYPE_H264_CUSTOM_FORMAT;

3.通过ffmpeg将获取的摄像头数据进行264编码,然后通过DjiPayloadCamera_SendVideoStream函数将编码完的一帧数据发送出去,主要实现如下,以供参考。

void Ffmpeg_Encoder_Init()

{

av_register_all();

avcodec_register_all();

m_pRGBFrame = new AVFrame[1];//RGB帧数据赋值

m_pYUVFrame = new AVFrame[1];//YUV帧数据赋值

c = NULL;//解码器指针对象赋初值

}

void Ffmpeg_Encoder_Setpara(AVCodecID mycodeid, int vwidth, int vheight)

{

pCodecH264 = avcodec_find_encoder(mycodeid);//查找h264编码器

if (!pCodecH264)

{

fprintf(stderr, "h264 codec not found\n");

exit(1);

}

width = vwidth;

height = vheight;

c = avcodec_alloc_context3(pCodecH264);//函数用于分配一个AVCodecContext并设置默认值,如果失败返回NULL,并可用av_free()进行释放

c = avcodec_alloc_context3(pCodecH264);//函数用于分配一个AVCodecContext并设置默认值,如果失败返回NULL,并可用av_free()进行释放

c->bit_rate = 400000; //设置采样参数,即比特率

c->width = vwidth;//设置编码视频宽度

c->height = vheight; //设置编码视频高度

c->time_base.den = 25;//设置帧率,num为分子和den为分母,如果是1/25则表示25帧/s

c->time_base.num = 1;

c->gop_size = 25; //设置GOP大小,该值表示每25帧会插入一个I帧

c->pix_fmt = AV_PIX_FMT_YUV420P;//设置像素格式

c->profile = FF_PROFILE_H264_BASELINE;//仅支持I帧P帧

av_opt_set(c->priv_data, "tune", "zerolatency", 0);//设置编码器的延时,解决前面的几十帧不出数据的情况

if (avcodec_open2(c, pCodecH264, NULL) < 0)return;//打开编码器

nDataLen = vwidth*vheight * 3;//计算图像rgb数据区长度

yuv_buff = new uint8_t[nDataLen / 2];//初始化数据区,为yuv图像帧准备填充缓存

rgb_buff = new uint8_t[nDataLen];//初始化数据区,为rgb图像帧准备填充缓存

outbuf_size = 100000;//初始化编码输出数据区

outbuf = new uint8_t[outbuf_size];

scxt = sws_getContext(c->width, c->height, AV_PIX_FMT_BGR24, c->width, c->height, AV_PIX_FMT_YUV420P, SWS_POINT, NULL, NULL, NULL);//初始化格式转换函数

}

void Ffmpeg_Encoder_Encode(FILE *file, uint8_t *data)

{

av_init_packet(&pkt);

memcpy(rgb_buff, data, nDataLen);//拷贝图像数据到rgb图像帧缓存中准备处理

avpicture_fill((AVPicture*)m_pRGBFrame, (uint8_t*)rgb_buff, AV_PIX_FMT_RGB24, width, height);//将rgb_buff填充到m_pRGBFrame

//av_image_fill_arrays((AVPicture*)m_pRGBFrame, (uint8_t*)rgb_buff, AV_PIX_FMT_RGB24, width, height);

avpicture_fill((AVPicture*)m_pYUVFrame, (uint8_t*)yuv_buff, AV_PIX_FMT_YUV420P, width, height);//将yuv_buff填充到m_pYUVFrame

sws_scale(scxt, m_pRGBFrame->data, m_pRGBFrame->linesize, 0, c->height, m_pYUVFrame->data, m_pYUVFrame->linesize);// 将RGB转化为YUV

int myoutputlen = 0;

int returnvalue = avcodec_encode_video2(c, &pkt, m_pYUVFrame, &myoutputlen);

if (returnvalue == 0)

{

unsigned long dataLength = pkt.size;

int lengthOfDataHaveBeenSent = 0;

while (dataLength - lengthOfDataHaveBeenSent) { //如果发送完成一帧

uint16_t lengthOfDataToBeSent = USER_UTIL_MIN(60000,dataLength - lengthOfDataHaveBeenSent);

DjiPayloadCamera_SendVideoStream((const uint8_t *) pkt.data + lengthOfDataHaveBeenSent,lengthOfDataToBeSent); //发送一帧

lengthOfDataHaveBeenSent += lengthOfDataToBeSent; //发送的大小

}

}

av_free_packet(&pkt);

}

void Ffmpeg_Encoder_Close()

{

delete[]m_pRGBFrame;

delete[]m_pYUVFrame;

delete[]rgb_buff;

delete[]yuv_buff;

delete[]outbuf;

sws_freeContext(scxt);

avcodec_close(c);//关闭编码器

av_free(c);

}

int main()

{

//开启大疆服务

main1();



cv::VideoCapture capture(10);

if (!capture.isOpened()) {

printf("Failed to open camera");

}

cv::Mat imageTemp;

capture >> imageTemp;

Ffmpeg_Encoder_Init();//初始化编码器

Ffmpeg_Encoder_Setpara(AV_CODEC_ID_H264, imageTemp.cols, imageTemp.rows);//设置编码器参数

//图象编码

FILE *f = NULL;

char * filename = "myData.h264";

fopen_s(&f, filename, "wb");//打开文件存储编码完成数据

while(1)

{

capture >> imageTemp;

Ffmpeg_Encoder_Encode(f, (uchar*)imageTemp.data);//编码

//imshow("send", imageTemp);

cv::waitKey(30);

}

return 0;

}

http://www.kler.cn/a/228679.html

相关文章:

  • EasyControl:首个登陆AWS Marketplace的中国MDM先锋
  • JS宏进阶:正则表达式介绍
  • OpenCV简介、OpenCV安装
  • 语音技术在播客领域的应用(2)
  • AUTOSAR从入门到精通-城市NOA(领航辅助驾驶)
  • 大模型UI:Gradio全解11——Chatbot:融合大模型的聊天机器人(4)
  • Android 应用添加系统签名权限的几种方式实现介绍
  • 算法每日一题: 使用循环数组所有元素相等的最少秒数 | 哈希
  • 按时间维度统计次数案例
  • Unity 开发注意事项
  • arping交叉编译
  • 【C++】类和对象(2)
  • DL/T1578-2021电力线路多旋翼无人机巡检系
  • [Python] 什么是逻辑回归模型?使用scikit-learn中的LogisticRegression来解决乳腺癌数据集上的二分类问题
  • 典型数据结构的模板实现
  • Python调用pyspark报错整理
  • Class 类
  • SpringBoot实战项目第一天
  • 为什么选择AGPL3.0开源协议
  • ROS从入门到精通4-1:Docker安装与常用命令总结
  • Windows自动化实现:系统通知和任务栏图标自定义
  • jmeter-04创建请求
  • 类银河恶魔城学习记录1-5 CollisionCheck源代码 P32
  • 2024 高级前端面试题之 性能优化模块 「精选篇」
  • 华为机考入门python3--(8)牛客8-合并表记录
  • RedHat8.4安装邮件服务器