I'm running the following gstreamer pipeline
rtspsrc location=rtsp://root:pass@192.168.1.14/ufirststream ! decodebin ! videoconvert n-threads=4 ! videoscale n-threads=4 ! capsfilter caps="video/x-raw" ! gvadetect model=/home/dldevmax/projects/gva/data/models/intel/face/FP32/face-detection-retail-0004.xml model-proc=/home/dldevmax/projects/gva/data/models/intel/face/FP32/face-detection-retail-0004.json ! queue ! gvawatermark name=gvawatermark ! tee name=tp tp. ! queue ! videoconvert ! fpsdisplaysink video-sink=xvimagesink sync=false tp. ! queue ! videoconvert ! jpegenc ! multifilesink location=out/img1_%03d.jpeg tp. ! queue ! videoconvert ! appsink name=application I'm able to obtain the GST_VIDEO_REGION_OF_INTEREST_META_API_TYPE meta data on every sample that contains a recognized face. I would like to store those faces as jpg files on the local filesystem. I have the bounding boxes but am running into a ton of problems trying to first store the complete frame. If I can store the complete frame it would be easy for me to obtain the regions that contain the faces because I have the bounding boxes. A better solution would be to figure out how to just save the faces directly but at this point I cannot even seem to be able to save the complete frame properly. Any advice on either? My attempt to store the complete frame is in dump_frame in the code below. I also saving the frames using a multisink and if I could correlate that stored frame to the frame associated with my face regions ... that would work too. #include <gst/gst.h> #include <stdio.h> #include <gst/video/video.h> #include <gst/video/gstvideometa.h> #include <gdk-pixbuf/gdk-pixbuf.h> /** Play a simple RTSP Stream to a screen. We use the gst_parse_launch to run the pipeline https://gstreamer.freedesktop.org/documentation/application-development/advanced/pipeline-manipulation.html?gi-language=python **/ typedef struct __AllElements { GstElement *pipeline; GstElement *rtspsrc; GstElement *detect; GstElement *watermark; GstElement *appsink; } Allelements; static GstFlowReturn new_sample (GstElement *sink, Allelements *data); void print_meta(GstSample * pSample, GstBuffer *buffer) ; int main (int argc, char *argv[]) { GstElement *pipeline; GstBus *bus; /* Initialize GStreamer */ gst_init (&argc, &argv); /* Build the pipeline */ gchar *input_file = "rtsp://root:pass@192.168.1.14/ufirststream"; gchar *detection_model = "/home/dldevmax/projects/gva/data/models/intel/face/FP32/face-detection-retail-0004.xml"; gchar *device = "cpu"; gchar *model_proc = "/home/dldevmax/projects/gva/data/models/intel/face/FP32/face-detection-retail-0004.json"; gchar const *preprocess_pipeline = "decodebin ! videoconvert n-threads=4 ! videoscale n-threads=4 "; gchar const *capfilter = "video/x-raw"; gchar const *screensink = " videoconvert ! fpsdisplaysink video-sink=xvimagesink sync=false"; //gchar const *filesink = " videoconvert ! pngenc ! multifilesink location=frame%05d.png"; gchar const *filesink = " videoconvert ! jpegenc ! multifilesink location=out/img1_%03d.jpeg"; gchar const *appsink = " videoconvert ! appsink name=application"; // Build the pipeline char *launch_str = g_strdup_printf("rtspsrc location=%s ! %s ! capsfilter caps=\"%s\" ! " "gvadetect model=%s model-proc=%s ! queue ! " "gvawatermark name=gvawatermark ! tee name=tp " "tp. ! queue ! %s tp. ! queue ! %s tp. ! queue ! %s", input_file, preprocess_pipeline, capfilter, detection_model, model_proc, screensink, filesink, appsink); g_print("PIPELINE: %s \n", launch_str); // sleep(10); pipeline = gst_parse_launch(launch_str, NULL); g_free(launch_str); Allelements element; GstElement *sink = gst_bin_get_by_name (GST_BIN (pipeline), "application"); g_object_set (sink, "sync", TRUE, NULL); g_object_set (sink, "emit-signals", TRUE, NULL); g_signal_connect (sink, "new-sample", G_CALLBACK (new_sample), &element); /* Start playing */ gst_element_set_state (pipeline, GST_STATE_PLAYING); /* Wait until error or EOS */ bus = gst_element_get_bus (pipeline); int ret_code = 0; GstMessage *msg = gst_bus_poll(bus, (GstMessageType)(GST_MESSAGE_ERROR | GST_MESSAGE_EOS), -1); if (msg && GST_MESSAGE_TYPE(msg) == GST_MESSAGE_ERROR) { GError *err = NULL; gchar *dbg_info = NULL; gst_message_parse_error(msg, &err, &dbg_info); g_printerr("ERROR from element %s: %s\n", GST_OBJECT_NAME(msg->src), err->message); g_printerr("Debugging info: %s\n", (dbg_info) ? dbg_info : "none"); g_error_free(err); g_free(dbg_info); ret_code = -1; } if (msg) gst_message_unref(msg); // Free resources gst_object_unref(bus); gst_element_set_state(pipeline, GST_STATE_NULL); gst_object_unref(pipeline); return ret_code; } static GstFlowReturn new_sample(GstElement *sink, Allelements *data) { GstBuffer *pBuffer; GstSample *pSample = gst_base_sink_get_last_sample(GST_BASE_SINK(sink)); if(pSample != NULL) { pBuffer = gst_sample_get_buffer(pSample); if(pBuffer != NULL) { print_meta(pSample, pBuffer); gst_buffer_unref(pBuffer); } gst_sample_unref(pSample); } return 0; } void dump_frame(GstSample *sample, guint8 *pixels) { GstBuffer *buffer; GstCaps *caps; GstStructure *s; GstMapInfo map; GError *pError = NULL; caps = gst_sample_get_caps (sample); if (!caps) { g_print ("could not get snapshot format\n"); return; } s = gst_caps_get_structure (caps, 0); int width, height; gst_structure_get_int (s, "width", &width); gst_structure_get_int (s, "height", &height); buffer = gst_sample_get_buffer (sample); gst_buffer_map(buffer, &map, GST_MAP_READ); g_print("This buffer has %lu bytes and is off %d x %d\n", map.size, width, height); int rowstride = GST_ROUND_UP_4(width * 3); printf("rowstride is %d\n", rowstride); GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data (pixels,GDK_COLORSPACE_RGB,FALSE,8,width, height,rowstride,NULL,NULL); gdk_pixbuf_save(pixbuf, "frame.jpg", "jpeg", &pError, NULL); gst_buffer_unmap (buffer, &map); } void copy_face(GstSample * pSample, GstBuffer * pBuffer) { GstVideoFrame videoFrame; GstVideoInfo videoInfo; GstCaps *caps = gst_sample_get_caps(pSample); gst_video_info_init(&videoInfo); gst_video_info_from_caps(&videoInfo, caps); gst_video_frame_map(&videoFrame, &videoInfo, pBuffer, 0); g_print("width == %d\n", videoInfo.width); g_print("height == %d\n", videoInfo.height); g_print("size == %ld\n", videoInfo.size); guint8 *pixels = GST_VIDEO_FRAME_PLANE_DATA(&videoFrame, 0); dump_frame(pSample, pixels); gst_video_frame_unmap(&videoFrame); } void print_meta(GstSample * pSample, GstBuffer *buffer) { gpointer state = NULL; GstMeta *meta = NULL; while ((meta = gst_buffer_iterate_meta_filtered(buffer, &state, GST_VIDEO_REGION_OF_INTEREST_META_API_TYPE)) != NULL) { GstVideoRegionOfInterestMeta *roi_meta = (GstVideoRegionOfInterestMeta*)meta; printf("Object bounding box %d,%d,%d,%d\n", roi_meta->x, roi_meta->y, roi_meta->w, roi_meta->h); for (GList *l = roi_meta->params; l; l = g_list_next(l)) { GstStructure *structure = (GstStructure *) l->data; printf(" Attribute %s\n", gst_structure_get_name(structure)); if (gst_structure_has_field(structure, "label")) { printf(" label=%s\n", gst_structure_get_string(structure, "label")); } if (gst_structure_has_field(structure, "confidence")) { double confidence; gst_structure_get_double(structure, "confidence", &confidence); printf(" confidence=%.2f\n", confidence); } } copy_face(pSample, buffer); } } -- Sent from: http://gstreamer-devel.966125.n4.nabble.com/ _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Free forum by Nabble | Edit this page |