GNOME Bugzilla – Bug 770308
v4l2src: "device busy" error when setting to READY and back to PLAYING
Last modified: 2016-09-06 18:07:58 UTC
Created attachment 334048 [details] souce code When setting Pipeline for the GST_MESSAGE_READY state of the V4L2SRC element to stop the video, I give a PLAY state again ,The V4L2 element display the "busy device" error, please tell me how to solve this problem, thank you very much. My c code: #include <string.h> #include <gst/gst.h> #include <sys/wait.h> int main (int argc,char *argv[]) { gst_init (&argc, &argv); GstElement *pevPipeline; GstElement *sink; GstElement *camPrevSrc; GstBus *bus; GstMessage *msg; GstElement *tee, *camPrev_Queue, *camRecord_Queue; GstElement *camPrevfilter,*camRecordfilter ,*h264parse; GstCaps *camPrevCaps, *camRecordCaps; gchar *input_device , *camRecordFileName; GstElement *mp4Mux,*nvOmx_H264enc; GstPad *tee_camPrev_pad, *tee_camRecord_pad; GstPad *queue_camPrev_pad, *queue_camRecord_pad; GstElement *fileSink; GstPadTemplate *tee_src_pad_template; pevPipeline = gst_pipeline_new ("xvoverlay"); camPrevSrc = gst_element_factory_make ("v4l2src", NULL); input_device = "/dev/video0"; camPrevfilter = gst_element_factory_make("capsfilter",NULL); camPrevCaps = gst_caps_from_string("video/x-raw,width=1280,height=720,framerate=60/1"); g_object_set(G_OBJECT(camPrevSrc),"device",input_device,NULL); g_object_set(G_OBJECT(camPrevfilter),"caps",camPrevCaps,NULL); //record video picture pipeline fileSink = gst_element_factory_make("filesink",NULL); camRecordCaps = gst_caps_from_string("video/x-raw,width=1280,height=720,framerate=60/1"); tee = gst_element_factory_make("tee", NULL); camPrev_Queue = gst_element_factory_make("queue2",NULL); mp4Mux = gst_element_factory_make("mp4mux",NULL); camRecord_Queue = gst_element_factory_make("queue2",NULL); camRecordfilter = gst_element_factory_make("capsfilter",NULL); camRecordFileName = "/home/ubuntu/family.mp4"; nvOmx_H264enc = gst_element_factory_make("omxh264enc",NULL); //omxh264enc h264parse = gst_element_factory_make("h264parse",NULL); g_object_set(G_OBJECT(camRecordfilter),"caps",camRecordCaps,NULL); g_object_set(G_OBJECT(fileSink),"location",camRecordFileName,NULL); //config and link cam_pipline if ((sink = gst_element_factory_make ("xvimagesink", NULL))) { // } if (sink == NULL) g_error ("Couldn't find a working video sink."); if(!pevPipeline || ! camPrevSrc || !tee || !camPrev_Queue || !camPrevfilter || !sink || !camRecord_Queue || !camRecordfilter || !nvOmx_H264enc|| !h264parse || !mp4Mux || !fileSink){ g_error ("Someting error."); } //src link to sink gst_bin_add_many (GST_BIN (pevPipeline), camPrevSrc, tee ,camPrev_Queue, camPrevfilter,sink, camRecord_Queue,camRecordfilter,nvOmx_H264enc,h264parse,mp4Mux,fileSink,NULL); if(gst_element_link_many(camPrevSrc,tee,NULL) != TRUE || gst_element_link_many(camPrev_Queue,camPrevfilter, sink,NULL) != TRUE || gst_element_link_many(camRecord_Queue,camRecordfilter,nvOmx_H264enc,h264parse,mp4Mux,fileSink,NULL) != TRUE){ g_printerr("Elements could not be linked.\n"); gst_object_unref(pevPipeline); } if(mp4Mux==NULL){ g_printerr("Error: mp4Mux == Null\n"); } if(tee==NULL){ g_printerr("Error: TEE == Null\n"); } tee_src_pad_template = gst_element_class_get_pad_template( GST_ELEMENT_GET_CLASS( tee ), "src_%u" ); if (tee_src_pad_template == NULL){ g_printerr("Error: tee_src_pad_template == Null\n"); } tee_camPrev_pad = gst_element_request_pad(tee,tee_src_pad_template,NULL,NULL); g_print("Obtained reques pad %s for tee_camPrev_pad branch.\n", gst_pad_get_name(tee_camPrev_pad)); queue_camPrev_pad = gst_element_get_static_pad(camPrev_Queue,"sink"); tee_camRecord_pad = gst_element_request_pad(tee,tee_src_pad_template,NULL,NULL); g_print("Obtained reques pad %s for tee_camRecord_pad branch.\n", gst_pad_get_name(tee_src_pad_template)); queue_camRecord_pad = gst_element_get_static_pad(camRecord_Queue,"sink"); if(gst_pad_link(tee_camPrev_pad,queue_camPrev_pad) != GST_PAD_LINK_OK || gst_pad_link(tee_camRecord_pad,queue_camRecord_pad) != GST_PAD_LINK_OK) { g_printerr("Tee could not be linked.\n"); gst_object_unref(pevPipeline); } gst_object_unref(queue_camPrev_pad); gst_object_unref(queue_camRecord_pad); GstStateChangeReturn sret; /* we know what the video sink is in this case (xvimagesink), so we can * just set it directly here now (instead of waiting for a * prepare-window-handle element message in a sync bus handler and setting * it there) */ sret = gst_element_set_state (pevPipeline, GST_STATE_PLAYING); if (sret == GST_STATE_CHANGE_FAILURE) { gst_element_set_state (pevPipeline, GST_STATE_NULL); gst_object_unref (pevPipeline); } bus=gst_element_get_bus(pevPipeline); msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE,GST_MESSAGE_EOS | GST_MESSAGE_ERROR); if (msg != NULL) gst_message_unref (msg); //gst_object_unref (bus); sleep(10); gst_element_set_state (pevPipeline, GST_STATE_READY); /*Stop video*/ sleep(10); gst_element_set_state (pevPipeline, GST_STATE_PLAY); /*play video*/ sleep(10); return 0; }
Does it work if you set the pipeline to NULL and then back to PLAYING?
Created attachment 334066 [details] this debug information hi: I set null and voido_pending state ,all the is same questions,so i submit debug.txt,please tell me how to take this problem,thank you. debug error info: v4l2 gstv4l2object.c:2524:gst_v4l2_object_set_format:<v4l2src0>[00m error: Device '/dev/video0' is busy 0:00:07.581130165 [336m 2837[00m 0xe5a60 [33;01mWARN [00m [00m v4l2 gstv4l2object.c:2524:gst_v4l2_object_set_format:<v4l2src0>[00m error: Call to S_FMT failed for YV12 @ 1280x720: Device or resource busy 0:00:07.581208331 [336m 2837[00m 0xe5a60 [36mINFO [00m [00;01;31;47m GST_ERROR_SYSTEM gstelement.c:1835:gst_element_message_full:<v4l2src0>[00m posting message: Device '/dev/video0' is busy 0:00:07.581292665 [336m 2837[00m 0xe5a60 [36mINFO [00m [00;01;31;47m GST_ERROR_SYSTEM gstelement.c:1858:gst_element_message_full:<v4l2src0>[00m posted error message: Device '/dev/video0' is busy 0:00:07.581399748 [336m 2837[00m 0xe5a60 [33;01mWARN [00m [00m basesrc gstbasesrc.c:2865:gst_base_src_loop:<v4l2src0>[00m error: Internal data flow error. 0:00:07.581442498 [336m 2837[00m 0xe5a60 [33;01mWARN [00m [00m basesrc gstbasesrc.c:2865:gst_base_src_loop:<v4l2src0>[00m error: streaming task paused, reason not-negotiated (-4)
That very much looks like a kernel driver bug? What platform are you on? What is the camera device you're using? Is it on a Tegra board?
hi is NVIDIA Jetson TK1 ubuntu platform, camera device is uvc camera.
In my experience, the NVidia Tegra kernel drivers are particularly crappy, so if you want to use that platform, you must either be ready to invest in fixing their kernel, or you must be ready to work around all kind of bugs they have.
Could also be caused by a buffer not being release, this will cause the V4l2Allocator to old on the device FD, hence lead to busy error on re-open.