v1
This commit is contained in:
148
try_1.cpp
Normal file
148
try_1.cpp
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Based on this example
|
||||
* https://stackoverflow.com/a/26402282/3312367
|
||||
*/
|
||||
#include <gst/gst.h>
|
||||
#include <gst/app/gstappsink.h>
|
||||
//#include <stdlib.h>
|
||||
#include <cstdlib>
|
||||
#include <deque>
|
||||
|
||||
#include "opencv2/opencv.hpp"
|
||||
//using namespace cv;
|
||||
|
||||
// TODO: use synchronized deque
|
||||
std::deque<cv::Mat> frameQueue;
|
||||
|
||||
GstFlowReturn new_preroll(GstAppSink *appsink, gpointer data) {
|
||||
g_print ("Got preroll!\n");
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
|
||||
GstFlowReturn new_sample(GstAppSink *appsink, gpointer data) {
|
||||
static int framecount = 0;
|
||||
framecount++;
|
||||
|
||||
GstSample *sample = gst_app_sink_pull_sample(appsink);
|
||||
GstCaps *caps = gst_sample_get_caps(sample);
|
||||
GstBuffer *buffer = gst_sample_get_buffer(sample);
|
||||
const GstStructure *info = gst_sample_get_info(sample);
|
||||
|
||||
// ---- Read frame and convert to opencv format ---------------
|
||||
|
||||
GstMapInfo map;
|
||||
gst_buffer_map (buffer, &map, GST_MAP_READ);
|
||||
|
||||
// convert gstreamer data to OpenCV Mat, you could actually
|
||||
// resolve height / width from caps...
|
||||
cv::Mat frame(cv::Size(320, 240), CV_8UC3, (char*)map.data, cv::Mat::AUTO_STEP);
|
||||
int frameSize = map.size;
|
||||
|
||||
// TODO: synchronize this....
|
||||
frameQueue.push_back(frame);
|
||||
|
||||
gst_buffer_unmap(buffer, &map);
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
// print dot every 30 frames
|
||||
if (framecount%30 == 0) {
|
||||
g_print (".");
|
||||
}
|
||||
|
||||
// show caps on first frame
|
||||
if (framecount == 1) {
|
||||
g_print ("%s\n", gst_caps_to_string(caps));
|
||||
}
|
||||
|
||||
gst_sample_unref (sample);
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
|
||||
static gboolean my_bus_callback (GstBus *bus, GstMessage *message, gpointer data) {
|
||||
g_print ("Got %s message\n", GST_MESSAGE_TYPE_NAME (message));
|
||||
switch (GST_MESSAGE_TYPE (message)) {
|
||||
case GST_MESSAGE_ERROR: {
|
||||
GError *err;
|
||||
gchar *debug;
|
||||
|
||||
gst_message_parse_error (message, &err, &debug);
|
||||
g_print ("Error: %s\n", err->message);
|
||||
g_error_free (err);
|
||||
g_free (debug);
|
||||
break;
|
||||
}
|
||||
case GST_MESSAGE_EOS:
|
||||
/* end-of-stream */
|
||||
break;
|
||||
default:
|
||||
/* unhandled message */
|
||||
break;
|
||||
}
|
||||
/* we want to be notified again the next time there is a message
|
||||
* on the bus, so returning TRUE (FALSE means we want to stop watching
|
||||
* for messages on the bus and our callback should not be called again)
|
||||
*/
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[]) {
|
||||
GError *error = NULL;
|
||||
|
||||
gst_init (&argc, &argv);
|
||||
|
||||
gchar *descr = g_strdup(
|
||||
"videotestsrc pattern=ball ! "
|
||||
"video/x-raw,format=RGB ! "
|
||||
"videoconvert ! "
|
||||
"appsink name=sink sync=true"
|
||||
);
|
||||
GstElement *pipeline = gst_parse_launch (descr, &error);
|
||||
|
||||
if (error != NULL) {
|
||||
g_print ("could not construct pipeline: %s\n", error->message);
|
||||
g_error_free (error);
|
||||
exit (-1);
|
||||
}
|
||||
|
||||
/* get sink */
|
||||
GstElement *sink = gst_bin_get_by_name (GST_BIN (pipeline), "sink");
|
||||
|
||||
gst_app_sink_set_emit_signals((GstAppSink*)sink, true);
|
||||
gst_app_sink_set_drop((GstAppSink*)sink, true);
|
||||
gst_app_sink_set_max_buffers((GstAppSink*)sink, 1);
|
||||
GstAppSinkCallbacks callbacks = { NULL, new_preroll, new_sample };
|
||||
gst_app_sink_set_callbacks (GST_APP_SINK(sink), &callbacks, NULL, NULL);
|
||||
|
||||
GstBus *bus;
|
||||
guint bus_watch_id;
|
||||
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
|
||||
bus_watch_id = gst_bus_add_watch (bus, my_bus_callback, NULL);
|
||||
gst_object_unref (bus);
|
||||
|
||||
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
|
||||
|
||||
cv::namedWindow("edges", 1);
|
||||
bool is_terminated = false;
|
||||
while (!is_terminated) {
|
||||
// g_main_iteration(false);
|
||||
g_main_context_iteration(NULL, false);
|
||||
// TODO: synchronize...
|
||||
if (frameQueue.size() > 0) {
|
||||
// this lags pretty badly even when grabbing frames from webcam
|
||||
cv::Mat frame = frameQueue.front();
|
||||
cv::Mat edges;
|
||||
cvtColor(frame, edges, cv::COLOR_BGR2BGRA);
|
||||
// GaussianBlur(edges, edges, Size(7,7), 1.5, 1.5);
|
||||
// Canny(edges, edges, 0, 30, 3);
|
||||
cv::imshow("edges", edges);
|
||||
cv::waitKey(30);
|
||||
frameQueue.clear();
|
||||
}
|
||||
}
|
||||
|
||||
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
|
||||
gst_object_unref (GST_OBJECT (pipeline));
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user