需求:无人机配套的某些低成本摄像机没有拍照功能,只有RTSP视频流的推送,因此可以利用GStreamer框架将视频帧进行保存,来达到拍照的效果。
思路:
在需要拍照的航点,触发信号。在GstVideoReciver.cpp 绑定此信号并进行视频帧的保存。
视频帧保存代码(某大神写的,非原创):
void GstVideoReceiver::takeMyScreenshot(const QString &imageFile)
{
//
gpointer widget = NULL;
GstSample *sample=NULL;
GstMemory* memory;
GstMapInfo info;
if(!_videoSink){
return;
}
g_object_get(G_OBJECT(_videoSink),"widget",&widget,NULL);
if(!widget){
gst_println("failed to get widget");
return;
}
g_object_get(G_OBJECT(_videoSink),"last-sample",&sample,NULL);
if(!sample){
gst_println("failed to get sample!");
return;
}
GstCaps* sample_caps = gst_sample_get_caps(sample);
if(!sample_caps){
gst_println("failed to get sample_caps!");
return;
}
int outwidth,outheight;
GstStructure *s = gst_caps_get_structure(sample_caps,0);
gst_structure_get_int(s,"width",&outwidth);
gst_structure_get_int(s,"height",&outheight);
if(outwidth<=0||outheight<=0){
gst_println("failed to get width or height");
return;
}
memory = gst_buffer_get_memory(gst_sample_get_buffer(sample),0);
if(!memory){
gst_println("failed to get memory!");
return;
}
gst_memory_map(memory,&info,GST_MAP_READ);
QImage save_image(info.data,outwidth,outheight,QImage::Format_RGBA8888);
if(save_image.isNull()){
gst_println("failed to fromData!");
return;
}
gst_println("save file:%s",qPrintable(imageFile));
if(!save_image.save(imageFile)){
gst_println("failed to save image!");
return;
}
}