1
我試圖通過從網絡攝像頭捕獲視頻並將其寫入文件來實現最簡單的gstreamer-1.0管道。有用。 Howewer,同時記錄非常小的視頻(〜2秒)continiously - 與重啓的循環管道 - 我有時會收到以下錯誤在管道重新啓動:使用v4l2scr重新啓動gstreamer管道的正確方法
libv4l2:錯誤設置pixformat:設備或資源忙
看來,在上一個記錄步驟中,元素沒有正確釋放。
必須做些什麼才能正確地重新啓動管道?
#include <iostream>
#include <thread>
#include <gst/gst.h>
static GstElement* makeCamSrc(int deviceId)
{
GstElement* cam = gst_element_factory_make("v4l2src", "camSrc");
if(!cam)
return NULL;
std::string devPath = std::string("/dev/video") + std::to_string(deviceId);
g_object_set(cam, "device", devPath.c_str(), NULL);
g_object_set(cam, "do-timestamp", true, NULL);
//Setup camera controls
GstStructure* extraCtrls = gst_structure_new("logitech_controls",
"sharpness", G_TYPE_INT, 220,
"contrast", G_TYPE_INT, 100,
"saturation", G_TYPE_INT, 160,
"focus_auto", G_TYPE_BOOLEAN, false,
"white_balance_temperature_auto", G_TYPE_BOOLEAN, false,
"white_balance_temperature", G_TYPE_INT, 3500,
NULL);
g_object_set(cam, "extra-controls" , extraCtrls, NULL);
return cam;
}
int main()
{
gst_init(NULL, NULL);
GstElement* vPipeline = gst_pipeline_new("vPipeline");
GstElement* camSrc = makeCamSrc(1);
GstElement* converter = gst_element_factory_make("videoconvert", "converter");
GstElement* tee = gst_element_factory_make("tee", "tee");
GstElement* vQueue = gst_element_factory_make("queue", "vQueue");
GstElement* vEncoder = gst_element_factory_make("x264enc", "vEncoder");
GstElement* vMuxer = gst_element_factory_make("mp4mux", "muxer");
GstElement* vFileSink = gst_element_factory_make("filesink", "vFileSink");
GstCaps* camCaps = gst_caps_new_simple("video/x-raw",
"format", G_TYPE_STRING, "RGB",
"width", G_TYPE_INT, 1280,
"height", G_TYPE_INT, 720,
NULL);
gst_bin_add_many(GST_BIN(vPipeline), camSrc, converter, tee, vQueue, vEncoder, vMuxer, vFileSink, NULL);
gst_element_link_filtered(camSrc, converter, camCaps);
gst_caps_unref(camCaps);
gst_element_link(converter, tee);
gst_element_link_many(vQueue, vEncoder, vMuxer, vFileSink, NULL);
GstPadTemplate* padTemplate = gst_element_class_get_pad_template(GST_ELEMENT_GET_CLASS(tee), "src_%u");
GstPad* vTeePad = gst_element_request_pad(tee, padTemplate, NULL, NULL);
GstPad* vQueuePad = gst_element_get_static_pad(vQueue, "sink");
gst_pad_link(vTeePad, vQueuePad);
GstBus* bus = gst_element_get_bus(vPipeline);
for(int i = 0; i < 11; ++i)
{
std::string file = std::string("stream_") + std::to_string(i) + std::string(".mp4");
g_object_set(vFileSink, "location", file.c_str(), NULL);
gst_element_set_state(vPipeline, GST_STATE_PLAYING);
std::thread([&]
{
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
gst_element_send_event(vPipeline, gst_event_new_eos());
}).detach();
GstMessage* msg = gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE, (GstMessageType)(GST_MESSAGE_ERROR | GST_MESSAGE_EOS));
if (msg != NULL)
{
if(GST_MESSAGE_TYPE(msg) == GST_MESSAGE_ERROR)
return -1;
gst_message_unref (msg);
}
gst_element_set_state(vPipeline, GST_STATE_NULL);
}
gst_object_unref(vPipeline);
}