通过大疆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;

}

你可能感兴趣的:(PSDK,大疆开发,摄像头)