After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 770308 - v4l2src: "device busy" error when setting to READY and back to PLAYING
v4l2src: "device busy" error when setting to READY and back to PLAYING
Status: RESOLVED NOTGNOME
Product: GStreamer
Classification: Platform
Component: gst-plugins-good
1.8.0
Other Linux
: Normal normal
: git master
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2016-08-24 00:36 UTC by frank
Modified: 2016-09-06 18:07 UTC
See Also:
GNOME target: ---
GNOME version: 3.7/3.8


Attachments
souce code (5.12 KB, text/x-csrc)
2016-08-24 00:36 UTC, frank
Details
this debug information (244.51 KB, text/plain)
2016-08-24 10:03 UTC, frank
Details

Description frank 2016-08-24 00:36:45 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;
}
Comment 1 Tim-Philipp Müller 2016-08-24 09:16:22 UTC
Does it work if you set the pipeline to NULL and then back to PLAYING?
Comment 2 frank 2016-08-24 10:03:19 UTC
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)
Comment 3 Olivier Crête 2016-08-24 13:12:01 UTC
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?
Comment 4 frank 2016-08-24 14:09:51 UTC
hi
    is NVIDIA Jetson TK1 ubuntu platform, camera device is uvc camera.
Comment 5 Olivier Crête 2016-08-24 15:49:03 UTC
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.
Comment 6 Nicolas Dufresne (ndufresne) 2016-09-06 18:07:58 UTC
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.