v4l2src capture/render with single png image captures (dangling reference)

Steve Evers steve.evers at veravanti.com
Fri Dec 4 14:47:26 PST 2015


Hello,


I have a static pipeline for capturing video via a v4l2src plugin and rendering this to an overlaysink. I have tee'ed this pipeline in order to take snapshot png's of the live video input being rendered as show below.

v4l2src -> tee --> imxvideoconvert_g2d -> queue -> overlaysink
               |
               --> queue -> valve -> videoconvert -> pngenc -> multifilesink

I can construct and teardown the pipeline and reconstruct the pipeline fine if I do not take pictures.


To take pictures, the valve is initially placed in drop mode ("drop==TRUE"). When a picture is desired, the valve is placed in passthrough mode ("drop==FALSE") to allow a frame to propogate to the pngenc sink at which point a padprobe callback is called to again turn off the upstream valve ("drop==TRUE"). I can take unlimited pictures successfully in this manor on the pipeline using this design, but when I teardown the pipeline after taking at least one picture, I am left with a residual reference to the v4l2src element and cannot rebuild the pipeline because of this.

Any ideas on what the object reference problem can be when the valve is used in this manor?


The include debug spew logs one pipeline construction/destruction with no image capture, immediately followed by a construction/destruction which takes one image. The error can be seen in the second pipeline destruction which has a v4l2src element with 2 references instead of 1 ("capture_src: 2"). Moduel source is include below the debug spew.



*************** debug spew ***************


main entry

state: NONE

************************* usage *************************
* k: live exam video                                    *
* h: return to home:                                    *
* q: exit executable                                    *
* s: save image                                         *
* g: save current pipeline graph                        *
************************* usage *************************

keyboard_gsource_func entry
handle_keyboard entry
destroyPipeline entry
pipeline does not exist
destroyPipeline exit
initPipeline entry
init PIPELINE_LIVE
initCapture entry
0:00:17.874405003 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':src> set parent (ref and sink)
0:00:17.874652669 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<capture_src> set parent (ref and sink)
initCapture exit
initDisplay entry
0:00:17.878431336 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':sink> set parent (ref and sink)
0:00:17.878633336 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':src> set parent (ref and sink)
display(/dev/fb2) resolution is (1920x1080).
0:00:17.887805336 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':sink> set parent (ref and sink)
====== OVERLAYSINK: 4.0.3 build on Nov  6 2015 14:19:51. ======
0:00:17.898062003 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':sink> set parent (ref and sink)
0:00:17.898250003 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':src> set parent (ref and sink)
0:00:17.898466336 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<video_convert> set parent (ref and sink)
0:00:17.898591336 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<video_queue> set parent (ref and sink)
0:00:17.898689003 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<video_sink> set parent (ref and sink)
initDisplay exit
initImg entry
0:00:17.912533336 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':sink> set parent (ref and sink)
0:00:17.912699336 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':src> set parent (ref and sink)
0:00:17.913053669 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':src> set parent (ref and sink)
0:00:17.913202003 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':sink> set parent (ref and sink)
0:00:17.915506003 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':sink> set parent (ref and sink)
0:00:17.915615669 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':src> set parent (ref and sink)
0:00:17.919927003 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':sink> set parent (ref and sink)
0:00:17.920039003 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':src> set parent (ref and sink)
0:00:17.925385336 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':sink> set parent (ref and sink)
attach_img_encode_sink_probe entry
attach_img_encode_sink_probe exit
0:00:17.925730669 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<img_queue> set parent (ref and sink)
0:00:17.925821003 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<img_valve> set parent (ref and sink)
0:00:17.925894336 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<img_converter> set parent (ref and sink)
0:00:17.925966003 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<img_pngEnc> set parent (ref and sink)
0:00:17.926036669 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<img_sink> set parent (ref and sink)
initImg exit
0:00:17.934316669 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':sink> set parent (ref and sink)
state: NONE
0:00:17.934498003 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<tee> set parent (ref and sink)
0:00:17.934821336 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':sink> set parent (ref and sink)
0:00:17.934922336 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':src> set parent (ref and sink)
0:00:17.935021669 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<capsfilter0> set parent (ref and sink)
linkTee entry
linkTeeDynamic entry
0:00:17.935744669 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':src_0> set parent (ref and sink)
Obtained request pad src_0 from tee.
Obtained pad sink for branch video_convert.
linkTeeDynamic exit
linkTee exit
linkTee entry
linkTeeDynamic entry
0:00:17.937632336 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':src_1> set parent (ref and sink)
Obtained request pad src_1 from tee.
Obtained pad sink for branch img_queue.
linkTeeDynamic exit
linkTee exit
initPipeline exit
startPipeline entry
  PIPELINE_FLATTENED_LIVE
state: LIVE
display(/dev/fb2) resolution is (1920x1080).
display(/dev/fb0) resolution is (1920x1080).
display(/dev/fb2) resolution is (1920x1080).
0:00:18.367811336 WARN v4l2 /gst-plugins-good-1.4.1/sys/v4l2/gstv4l2bufferpool.c:658:gst_v4l2_buffer_pool_start:<capture_src:pool:src> using 4 buffers instead of 2
0:00:19.442526003 WARN default /gst-plugins-base-1.4.1/gst-libs/gst/video/gstvideopool.c:189:video_buffer_pool_set_config:<videobufferpool1> no caps in config
keyboard_gsource_func entry
handle_keyboard entry
navigate home
destroyPipeline entry
capture_src != NULL
capture_src::device-fd:9
capture_src: 7
tee ref_count: 4
video_queue ref_count: 6
video_convert ref_count: 5
video_sink ref_count: 8
img_queue ref_count: 6
img_valve ref_count: 4
img_converter ref_count: 4
img_pngEnc ref_count: 4
img_sink ref_count: 4
remove_img_encode_sink_probe entry

0:00:23.097931003 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<img_converter:sink> dispose

remove_img_encode_sink_probe exit
Total showed frames (54), display master blited (54), playing for (0:00:04.775867667), fps (11.307).
Total showed frames (54), display slave blited (54), playing for (0:00:04.775867667), fps (11.307).
state: NONE
data->pipeline ref_count: 1
capture_src: 1
tee ref_count: 1
video_queue ref_count: 1
video_convert ref_count: 1
video_sink ref_count: 1
img_queue ref_count: 1
img_valve ref_count: 1
img_converter ref_count: 1
img_pngEnc ref_count: 1
img_sink ref_count: 1
capture_src != NULL
capture_src::device-fd:-1
destroyPipeline exit
handle_keyboard exit
keyboard_gsource_func exit
0:00:23.194379670 DEBUG GST_REFCOUNTING gstpipeline.c:227:gst_pipeline_dispose:<pipeline> dispose
0:00:23.194505670 DEBUG GST_REFCOUNTING gstbin.c:516:gst_bin_dispose:<pipeline> dispose
0:00:23.194917337 INFO  GST_REFCOUNTING gstelement.c:2873:gst_element_dispose:<capsfilter0> dispose
0:00:23.195065337 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':sink> dispose
0:00:23.195215337 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':src> dispose
0:00:23.195355670 INFO  GST_REFCOUNTING gstelement.c:2917:gst_element_dispose:<capsfilter0> parent class dispose
0:00:23.195465337 INFO  GST_REFCOUNTING gstelement.c:2948:gst_element_finalize:<capsfilter0> finalize
0:00:23.195552003 INFO  GST_REFCOUNTING gstelement.c:2953:gst_element_finalize:<capsfilter0> finalize parent
0:00:23.195932003 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':src_0> dispose
0:00:23.196092003 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':src_1> dispose
0:00:23.196222337 INFO  GST_REFCOUNTING gstelement.c:2873:gst_element_dispose:<tee> dispose
0:00:23.196336003 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':sink> dispose
0:00:23.196464670 INFO  GST_REFCOUNTING gstelement.c:2917:gst_element_dispose:<tee> parent class dispose
0:00:23.196568003 INFO  GST_REFCOUNTING gstelement.c:2948:gst_element_finalize:<tee> finalize
0:00:23.196652337 INFO  GST_REFCOUNTING gstelement.c:2953:gst_element_finalize:<tee> finalize parent
0:00:23.196930670 INFO  GST_REFCOUNTING gstelement.c:2873:gst_element_dispose:<img_sink> dispose
0:00:23.197039337 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':sink> dispose
0:00:23.197157670 INFO  GST_REFCOUNTING gstelement.c:2917:gst_element_dispose:<img_sink> parent class dispose
0:00:23.197262337 INFO  GST_REFCOUNTING gstelement.c:2948:gst_element_finalize:<img_sink> finalize
0:00:23.197348337 INFO  GST_REFCOUNTING gstelement.c:2953:gst_element_finalize:<img_sink> finalize parent
0:00:23.197625337 INFO  GST_REFCOUNTING gstelement.c:2873:gst_element_dispose:<img_pngEnc> dispose
0:00:23.197735670 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':sink> dispose
0:00:23.197864670 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':src> dispose
0:00:23.197978003 INFO  GST_REFCOUNTING gstelement.c:2917:gst_element_dispose:<img_pngEnc> parent class dispose
0:00:23.198080670 INFO  GST_REFCOUNTING gstelement.c:2948:gst_element_finalize:<img_pngEnc> finalize
0:00:23.198164670 INFO  GST_REFCOUNTING gstelement.c:2953:gst_element_finalize:<img_pngEnc> finalize parent
0:00:23.198347337 INFO  GST_REFCOUNTING gstelement.c:2873:gst_element_dispose:<img_converter> dispose
0:00:23.198454337 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':sink> dispose
0:00:23.198587337 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':src> dispose
0:00:23.198704670 INFO  GST_REFCOUNTING gstelement.c:2917:gst_element_dispose:<img_converter> parent class dispose
0:00:23.198803670 INFO  GST_REFCOUNTING gstelement.c:2948:gst_element_finalize:<img_converter> finalize
0:00:23.198890670 INFO  GST_REFCOUNTING gstelement.c:2953:gst_element_finalize:<img_converter> finalize parent
0:00:23.199169003 INFO  GST_REFCOUNTING gstelement.c:2873:gst_element_dispose:<img_valve> dispose
0:00:23.199279670 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':src> dispose
0:00:23.199420337 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':sink> dispose
0:00:23.199545670 INFO  GST_REFCOUNTING gstelement.c:2917:gst_element_dispose:<img_valve> parent class dispose
0:00:23.199641337 INFO  GST_REFCOUNTING gstelement.c:2948:gst_element_finalize:<img_valve> finalize
0:00:23.199725337 INFO  GST_REFCOUNTING gstelement.c:2953:gst_element_finalize:<img_valve> finalize parent
0:00:23.199890337 INFO  GST_REFCOUNTING gstelement.c:2873:gst_element_dispose:<img_queue> dispose
0:00:23.200001337 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':sink> dispose
0:00:23.200145670 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':src> dispose
0:00:23.200273003 INFO  GST_REFCOUNTING gstelement.c:2917:gst_element_dispose:<img_queue> parent class dispose
0:00:23.200383670 INFO  GST_REFCOUNTING gstelement.c:2948:gst_element_finalize:<img_queue> finalize
0:00:23.200469337 INFO  GST_REFCOUNTING gstelement.c:2953:gst_element_finalize:<img_queue> finalize parent
0:00:23.200741670 INFO  GST_REFCOUNTING gstelement.c:2873:gst_element_dispose:<video_sink> dispose
0:00:23.200852337 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':sink> dispose
0:00:23.200988337 INFO  GST_REFCOUNTING gstelement.c:2917:gst_element_dispose:<video_sink> parent class dispose
0:00:23.201091670 INFO  GST_REFCOUNTING gstelement.c:2948:gst_element_finalize:<video_sink> finalize
0:00:23.201178003 INFO  GST_REFCOUNTING gstelement.c:2953:gst_element_finalize:<video_sink> finalize parent
0:00:23.201485003 INFO  GST_REFCOUNTING gstelement.c:2873:gst_element_dispose:<video_queue> dispose
0:00:23.201596003 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':sink> dispose
0:00:23.201736337 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':src> dispose
0:00:23.201868670 INFO  GST_REFCOUNTING gstelement.c:2917:gst_element_dispose:<video_queue> parent class dispose
0:00:23.201979003 INFO  GST_REFCOUNTING gstelement.c:2948:gst_element_finalize:<video_queue> finalize
0:00:23.202240337 INFO  GST_REFCOUNTING gstelement.c:2953:gst_element_finalize:<video_queue> finalize parent
0:00:23.202420003 INFO  GST_REFCOUNTING gstelement.c:2873:gst_element_dispose:<video_convert> dispose
0:00:23.202529670 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':sink> dispose
0:00:23.202657670 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':src> dispose
0:00:23.202772337 INFO  GST_REFCOUNTING gstelement.c:2917:gst_element_dispose:<video_convert> parent class dispose
0:00:23.203366003 INFO  GST_REFCOUNTING gstelement.c:2948:gst_element_finalize:<video_convert> finalize
0:00:23.203470003 INFO  GST_REFCOUNTING gstelement.c:2953:gst_element_finalize:<video_convert> finalize parent
0:00:23.203664670 INFO  GST_REFCOUNTING gstelement.c:2873:gst_element_dispose:<capture_src> dispose
0:00:23.203777670 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':src> dispose
0:00:23.203897670 INFO  GST_REFCOUNTING gstelement.c:2917:gst_element_dispose:<capture_src> parent class dispose
0:00:23.204007670 INFO  GST_REFCOUNTING gstelement.c:2948:gst_element_finalize:<capture_src> finalize
0:00:23.204098670 INFO  GST_REFCOUNTING gstelement.c:2953:gst_element_finalize:<capture_src> finalize parent
0:00:23.204211670 INFO  GST_REFCOUNTING gstelement.c:2873:gst_element_dispose:<pipeline> dispose
0:00:23.204305670 INFO  GST_REFCOUNTING gstelement.c:2917:gst_element_dispose:<pipeline> parent class dispose
0:00:23.204401670 INFO  GST_REFCOUNTING gstelement.c:2948:gst_element_finalize:<pipeline> finalize
0:00:23.204486003 INFO  GST_REFCOUNTING gstelement.c:2953:gst_element_finalize:<pipeline> finalize parent
state: NONE
startPipeline exit
handle_keyboard exit
keyboard_gsource_func exit
keyboard_gsource_func entry
handle_keyboard entry
destroyPipeline entry
pipeline does not exist
destroyPipeline exit
initPipeline entry
init PIPELINE_LIVE
initCapture entry
0:00:26.425296337 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':src> set parent (ref and sink)
0:00:26.425576670 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<capture_src> set parent (ref and sink)
initCapture exit
initDisplay entry
0:00:26.426165004 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':sink> set parent (ref and sink)
0:00:26.426510670 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':src> set parent (ref and sink)
0:00:26.426853337 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':sink> set parent (ref and sink)
====== OVERLAYSINK: 4.0.3 build on Nov  6 2015 14:19:51. ======
0:00:26.427302337 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':sink> set parent (ref and sink)
0:00:26.427548004 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':src> set parent (ref and sink)
0:00:26.427823670 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<video_convert> set parent (ref and sink)
0:00:26.428006004 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<video_queue> set parent (ref and sink)
0:00:26.428178337 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<video_sink> set parent (ref and sink)
initDisplay exit
initImg entry
0:00:26.447411004 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':sink> set parent (ref and sink)
0:00:26.447564670 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':src> set parent (ref and sink)
0:00:26.447753337 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':src> set parent (ref and sink)
0:00:26.447899004 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':sink> set parent (ref and sink)
0:00:26.448032337 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':sink> set parent (ref and sink)
0:00:26.448127337 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':src> set parent (ref and sink)
0:00:26.448259670 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':sink> set parent (ref and sink)
0:00:26.448385337 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':src> set parent (ref and sink)
0:00:26.448519670 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':sink> set parent (ref and sink)
attach_img_encode_sink_probe entry
attach_img_encode_sink_probe exit
0:00:26.448747670 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<img_queue> set parent (ref and sink)
0:00:26.448825004 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<img_valve> set parent (ref and sink)
0:00:26.448896337 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<img_converter> set parent (ref and sink)
0:00:26.448965004 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<img_pngEnc> set parent (ref and sink)
0:00:26.449033004 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<img_sink> set parent (ref and sink)
initImg exit
0:00:26.457175670 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':sink> set parent (ref and sink)
state: NONE
0:00:26.457319337 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<tee> set parent (ref and sink)
0:00:26.457462670 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':sink> set parent (ref and sink)
0:00:26.457560004 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':src> set parent (ref and sink)
0:00:26.457644670 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<capsfilter1> set parent (ref and sink)
linkTee entry
linkTeeDynamic entry
0:00:26.458222337 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':src_0> set parent (ref and sink)
Obtained request pad src_0 from tee.
Obtained pad sink for branch video_convert.
linkTeeDynamic exit
linkTee exit
linkTee entry
linkTeeDynamic entry
0:00:26.460143004 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':src_1> set parent (ref and sink)
Obtained request pad src_1 from tee.
Obtained pad sink for branch img_queue.
linkTeeDynamic exit
linkTee exit
initPipeline exit
startPipeline entry
  PIPELINE_FLATTENED_LIVE
state: LIVE
display(/dev/fb2) resolution is (1920x1080).
display(/dev/fb0) resolution is (1920x1080).
display(/dev/fb2) resolution is (1920x1080).
0:00:26.898655004 WARN v4l2 /gst-plugins-good-1.4.1/sys/v4l2/gstv4l2bufferpool.c:658:gst_v4l2_buffer_pool_start:<capture_src:pool:src> using 4 buffers instead of 2
0:00:27.974872004 WARN default /gst-plugins-base-1.4.1/gst-libs/gst/video/gstvideopool.c:189:video_buffer_pool_set_config:<videobufferpool3> no caps in config
keyboard_gsource_func entry
handle_keyboard entry
save image
Save image to 20151127T231604.png
captureImage entry
captureImage exit
handle_keyboard exit
keyboard_gsource_func exit
image_cb entry
image_cb exit
keyboard_gsource_func entry
handle_keyboard entry
navigate home
destroyPipeline entry
capture_src != NULL
capture_src::device-fd:11
capture_src: 7
tee ref_count: 4
video_queue ref_count: 6
video_convert ref_count: 5
video_sink ref_count: 7
img_queue ref_count: 6
img_valve ref_count: 4
img_converter ref_count: 4
img_pngEnc ref_count: 4
img_sink ref_count: 4
remove_img_encode_sink_probe entry

0:00:32.056686671 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<img_converter:sink> dispose

remove_img_encode_sink_probe exit
Total showed frames (51), display master blited (51), playing for (0:00:05.210536001), fps (9.788).
Total showed frames (51), display slave blited (51), playing for (0:00:05.210536001), fps (9.788).
state: NONE
data->pipeline ref_count: 1
capture_src: 2
tee ref_count: 1
video_queue ref_count: 1
video_convert ref_count: 1
video_sink ref_count: 1
img_queue ref_count: 1
img_valve ref_count: 1
img_converter ref_count: 1
img_pngEnc ref_count: 1
img_sink ref_count: 1
capture_src != NULL
capture_src::device-fd:-1
destroyPipeline exit
handle_keyboard exit
keyboard_gsource_func exit
0:00:32.155537338 DEBUG GST_REFCOUNTING gstpipeline.c:227:gst_pipeline_dispose:<pipeline> dispose
0:00:32.155659671 DEBUG GST_REFCOUNTING gstbin.c:516:gst_bin_dispose:<pipeline> dispose
0:00:32.156073004 INFO  GST_REFCOUNTING gstelement.c:2873:gst_element_dispose:<capsfilter1> dispose
0:00:32.156205671 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':sink> dispose
0:00:32.156350671 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':src> dispose
0:00:32.156470004 INFO  GST_REFCOUNTING gstelement.c:2917:gst_element_dispose:<capsfilter1> parent class dispose
0:00:32.156578671 INFO  GST_REFCOUNTING gstelement.c:2948:gst_element_finalize:<capsfilter1> finalize
0:00:32.156665338 INFO  GST_REFCOUNTING gstelement.c:2953:gst_element_finalize:<capsfilter1> finalize parent
0:00:32.157041338 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':src_0> dispose
0:00:32.157200338 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':src_1> dispose
0:00:32.157330338 INFO  GST_REFCOUNTING gstelement.c:2873:gst_element_dispose:<tee> dispose
0:00:32.157443004 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':sink> dispose
0:00:32.157571671 INFO  GST_REFCOUNTING gstelement.c:2917:gst_element_dispose:<tee> parent class dispose
0:00:32.157673671 INFO  GST_REFCOUNTING gstelement.c:2948:gst_element_finalize:<tee> finalize
0:00:32.157757338 INFO  GST_REFCOUNTING gstelement.c:2953:gst_element_finalize:<tee> finalize parent
0:00:32.158036338 INFO  GST_REFCOUNTING gstelement.c:2873:gst_element_dispose:<img_sink> dispose
0:00:32.158146338 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':sink> dispose
0:00:32.158264004 INFO  GST_REFCOUNTING gstelement.c:2917:gst_element_dispose:<img_sink> parent class dispose
0:00:32.158371671 INFO  GST_REFCOUNTING gstelement.c:2948:gst_element_finalize:<img_sink> finalize
0:00:32.158455338 INFO  GST_REFCOUNTING gstelement.c:2953:gst_element_finalize:<img_sink> finalize parent
0:00:32.158733338 INFO  GST_REFCOUNTING gstelement.c:2873:gst_element_dispose:<img_pngEnc> dispose
0:00:32.158843671 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':sink> dispose
0:00:32.158968338 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':src> dispose
0:00:32.159082004 INFO  GST_REFCOUNTING gstelement.c:2917:gst_element_dispose:<img_pngEnc> parent class dispose
0:00:32.159203004 INFO  GST_REFCOUNTING gstelement.c:2948:gst_element_finalize:<img_pngEnc> finalize
0:00:32.159287671 INFO  GST_REFCOUNTING gstelement.c:2953:gst_element_finalize:<img_pngEnc> finalize parent
0:00:32.159468338 INFO  GST_REFCOUNTING gstelement.c:2873:gst_element_dispose:<img_converter> dispose
0:00:32.159574004 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':sink> dispose
0:00:32.159701004 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':src> dispose
0:00:32.159817004 INFO  GST_REFCOUNTING gstelement.c:2917:gst_element_dispose:<img_converter> parent class dispose
0:00:32.159921338 INFO  GST_REFCOUNTING gstelement.c:2948:gst_element_finalize:<img_converter> finalize
0:00:32.160003671 INFO  GST_REFCOUNTING gstelement.c:2953:gst_element_finalize:<img_converter> finalize parent
0:00:32.160281004 INFO  GST_REFCOUNTING gstelement.c:2873:gst_element_dispose:<img_valve> dispose
0:00:32.160392338 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':src> dispose
0:00:32.160533671 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':sink> dispose
0:00:32.160658671 INFO  GST_REFCOUNTING gstelement.c:2917:gst_element_dispose:<img_valve> parent class dispose
0:00:32.160753004 INFO  GST_REFCOUNTING gstelement.c:2948:gst_element_finalize:<img_valve> finalize
0:00:32.160835671 INFO  GST_REFCOUNTING gstelement.c:2953:gst_element_finalize:<img_valve> finalize parent
0:00:32.160994004 INFO  GST_REFCOUNTING gstelement.c:2873:gst_element_dispose:<img_queue> dispose
0:00:32.161101671 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':sink> dispose
0:00:32.161246671 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':src> dispose
0:00:32.161373671 INFO  GST_REFCOUNTING gstelement.c:2917:gst_element_dispose:<img_queue> parent class dispose
0:00:32.161486671 INFO  GST_REFCOUNTING gstelement.c:2948:gst_element_finalize:<img_queue> finalize
0:00:32.161573338 INFO  GST_REFCOUNTING gstelement.c:2953:gst_element_finalize:<img_queue> finalize parent
0:00:32.161851338 INFO  GST_REFCOUNTING gstelement.c:2873:gst_element_dispose:<video_sink> dispose
0:00:32.161964004 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':sink> dispose
0:00:32.162225004 INFO  GST_REFCOUNTING gstelement.c:2917:gst_element_dispose:<video_sink> parent class dispose
0:00:32.162338671 INFO  GST_REFCOUNTING gstelement.c:2948:gst_element_finalize:<video_sink> finalize
0:00:32.162427004 INFO  GST_REFCOUNTING gstelement.c:2953:gst_element_finalize:<video_sink> finalize parent
0:00:32.162707338 INFO  GST_REFCOUNTING gstelement.c:2873:gst_element_dispose:<video_queue> dispose
0:00:32.162827671 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':sink> dispose
0:00:32.162970338 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':src> dispose
0:00:32.163104338 INFO  GST_REFCOUNTING gstelement.c:2917:gst_element_dispose:<video_queue> parent class dispose
0:00:32.163214671 INFO  GST_REFCOUNTING gstelement.c:2948:gst_element_finalize:<video_queue> finalize
0:00:32.163300338 INFO  GST_REFCOUNTING gstelement.c:2953:gst_element_finalize:<video_queue> finalize parent
0:00:32.163464338 INFO  GST_REFCOUNTING gstelement.c:2873:gst_element_dispose:<video_convert> dispose
0:00:32.163568671 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':sink> dispose
0:00:32.163694671 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':src> dispose
0:00:32.163808338 INFO  GST_REFCOUNTING gstelement.c:2917:gst_element_dispose:<video_convert> parent class dispose
0:00:32.164401338 INFO  GST_REFCOUNTING gstelement.c:2948:gst_element_finalize:<video_convert> finalize
0:00:32.164504671 INFO  GST_REFCOUNTING gstelement.c:2953:gst_element_finalize:<video_convert> finalize parent
0:00:32.164702338 INFO  GST_REFCOUNTING gstelement.c:2873:gst_element_dispose:<pipeline> dispose
0:00:32.164799338 INFO  GST_REFCOUNTING gstelement.c:2917:gst_element_dispose:<pipeline> parent class dispose
0:00:32.164894004 INFO  GST_REFCOUNTING gstelement.c:2948:gst_element_finalize:<pipeline> finalize
0:00:32.164979004 INFO  GST_REFCOUNTING gstelement.c:2953:gst_element_finalize:<pipeline> finalize parent
state: NONE
startPipeline exit
handle_keyboard exit
keyboard_gsource_func exit
keyboard_gsource_func entry
handle_keyboard entry
destroyPipeline entry
pipeline does not exist
destroyPipeline exit
initPipeline entry
init PIPELINE_LIVE
initCapture entry
0:00:35.049455671 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':src> set parent (ref and sink)
0:00:35.049915005 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<capture_src> set parent (ref and sink)
initCapture exit
initDisplay entry
0:00:35.050860338 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':sink> set parent (ref and sink)
0:00:35.051347005 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':src> set parent (ref and sink)
0:00:35.051823338 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':sink> set parent (ref and sink)
====== OVERLAYSINK: 4.0.3 build on Nov  6 2015 14:19:51. ======
0:00:35.052605671 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':sink> set parent (ref and sink)
0:00:35.052988671 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':src> set parent (ref and sink)
0:00:35.053397005 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<video_convert> set parent (ref and sink)
0:00:35.053709338 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<video_queue> set parent (ref and sink)
0:00:35.054010338 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<video_sink> set parent (ref and sink)
initDisplay exit
initImg entry
0:00:35.069983338 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':sink> set parent (ref and sink)
0:00:35.070205338 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':src> set parent (ref and sink)
0:00:35.070443005 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':src> set parent (ref and sink)
0:00:35.070618671 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':sink> set parent (ref and sink)
0:00:35.070747671 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':sink> set parent (ref and sink)
0:00:35.070845005 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':src> set parent (ref and sink)
0:00:35.070976005 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':sink> set parent (ref and sink)
0:00:35.071070005 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':src> set parent (ref and sink)
0:00:35.071205005 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':sink> set parent (ref and sink)
attach_img_encode_sink_probe entry
attach_img_encode_sink_probe exit
0:00:35.071433005 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<img_queue> set parent (ref and sink)
0:00:35.071510338 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<img_valve> set parent (ref and sink)
0:00:35.071581671 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<img_converter> set parent (ref and sink)
0:00:35.071651338 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<img_pngEnc> set parent (ref and sink)
0:00:35.071720338 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<img_sink> set parent (ref and sink)
initImg exit
0:00:35.079779671 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':sink> set parent (ref and sink)
state: NONE
0:00:35.079923671 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<tee> set parent (ref and sink)
0:00:35.080066671 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':sink> set parent (ref and sink)
0:00:35.080165338 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':src> set parent (ref and sink)
0:00:35.080248005 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<capsfilter2> set parent (ref and sink)
linkTee entry
linkTeeDynamic entry
0:00:35.080862005 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':src_0> set parent (ref and sink)
Obtained request pad src_0 from tee.
Obtained pad sink for branch video_convert.
linkTeeDynamic exit
linkTee exit
linkTee entry
linkTeeDynamic entry
0:00:35.082806005 DEBUG GST_REFCOUNTING gstobject.c:692:gst_object_set_parent:<'':src_1> set parent (ref and sink)
Obtained request pad src_1 from tee.
Obtained pad sink for branch img_queue.
linkTeeDynamic exit
linkTee exit
initPipeline exit
startPipeline entry
  PIPELINE_FLATTENED_LIVE
state: LIVE
display(/dev/fb2) resolution is (1920x1080).
display(/dev/fb0) resolution is (1920x1080).
display(/dev/fb2) resolution is (1920x1080).
0:00:35.471775671 v4l2allocator /gst-plugins-good-1.4.1/sys/v4l2/gstv4l2allocator.c:650:gst_v4l2_allocator_new:<capture_src:pool:src:allocator> No memory model supported by GStreamer for this device
0:00:35.471860671 v4l2 /gst-plugins-good-1.4.1/sys/v4l2/gstv4l2bufferpool.c:1452:gst_v4l2_buffer_pool_new:<capture_src:pool:src> Failed to create V4L2 allocator
0:00:35.471948005 v4l2 /gst-plugins-good-1.4.1/sys/v4l2/gstv4l2object.c:2294:gst_v4l2_object_setup_pool:<capture_src> error: Could not map buffers from device '/dev/video0'
0:00:35.471985338 v4l2 /gst-plugins-good-1.4.1/sys/v4l2/gstv4l2object.c:2294:gst_v4l2_object_setup_pool:<capture_src> error: Failed to create buffer pool: Device or resource busy
0:00:35.472223338 basesrc /gstreamer-1.4.1/libs/gst/base/gstbasesrc.c:2933:gst_base_src_loop:<capture_src> error: Internal data flow error.
0:00:35.472277005 basesrc /gstreamer-1.4.1/libs/gst/base/gstbasesrc.c:2933:gst_base_src_loop:<capture_src> error: streaming task paused, reason not-negotiated (-4)
keyboard_gsource_func entry
handle_keyboard entry
navigate home
destroyPipeline entry
capture_src != NULL
capture_src::device-fd:15
capture_src: 8
tee ref_count: 4
video_queue ref_count: 6
video_convert ref_count: 4
video_sink ref_count: 5
img_queue ref_count: 6
img_valve ref_count: 4
img_converter ref_count: 4
img_pngEnc ref_count: 4
img_sink ref_count: 4
remove_img_encode_sink_probe entry

0:00:39.970354005 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<img_converter:sink> dispose

remove_img_encode_sink_probe exit
state: NONE
data->pipeline ref_count: 1
capture_src: 1
tee ref_count: 1
video_queue ref_count: 1
video_convert ref_count: 1
video_sink ref_count: 1
img_queue ref_count: 1
img_valve ref_count: 1
img_converter ref_count: 1
img_pngEnc ref_count: 1
img_sink ref_count: 1
capture_src != NULL
capture_src::device-fd:-1
destroyPipeline exit
handle_keyboard exit
keyboard_gsource_func exit
0:00:40.085397339 DEBUG GST_REFCOUNTING gstpipeline.c:227:gst_pipeline_dispose:<pipeline> dispose
0:00:40.085518672 DEBUG GST_REFCOUNTING gstbin.c:516:gst_bin_dispose:<pipeline> dispose
0:00:40.085929339 INFO  GST_REFCOUNTING gstelement.c:2873:gst_element_dispose:<capsfilter2> dispose
0:00:40.086062005 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':sink> dispose
0:00:40.086208339 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':src> dispose
0:00:40.086336672 INFO  GST_REFCOUNTING gstelement.c:2917:gst_element_dispose:<capsfilter2> parent class dispose
0:00:40.086441005 INFO  GST_REFCOUNTING gstelement.c:2948:gst_element_finalize:<capsfilter2> finalize
0:00:40.086536672 INFO  GST_REFCOUNTING gstelement.c:2953:gst_element_finalize:<capsfilter2> finalize parent
0:00:40.086908672 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':src_0> dispose
0:00:40.087078339 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':src_1> dispose
0:00:40.087211672 INFO  GST_REFCOUNTING gstelement.c:2873:gst_element_dispose:<tee> dispose
0:00:40.087324339 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':sink> dispose
0:00:40.087464005 INFO  GST_REFCOUNTING gstelement.c:2917:gst_element_dispose:<tee> parent class dispose
0:00:40.087579672 INFO  GST_REFCOUNTING gstelement.c:2948:gst_element_finalize:<tee> finalize
0:00:40.087663339 INFO  GST_REFCOUNTING gstelement.c:2953:gst_element_finalize:<tee> finalize parent
0:00:40.087939339 INFO  GST_REFCOUNTING gstelement.c:2873:gst_element_dispose:<img_sink> dispose
0:00:40.088050005 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':sink> dispose
0:00:40.088166005 INFO  GST_REFCOUNTING gstelement.c:2917:gst_element_dispose:<img_sink> parent class dispose
0:00:40.088272672 INFO  GST_REFCOUNTING gstelement.c:2948:gst_element_finalize:<img_sink> finalize
0:00:40.088358672 INFO  GST_REFCOUNTING gstelement.c:2953:gst_element_finalize:<img_sink> finalize parent
0:00:40.088637672 INFO  GST_REFCOUNTING gstelement.c:2873:gst_element_dispose:<img_pngEnc> dispose
0:00:40.088748005 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':sink> dispose
0:00:40.088875339 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':src> dispose
0:00:40.088988005 INFO  GST_REFCOUNTING gstelement.c:2917:gst_element_dispose:<img_pngEnc> parent class dispose
0:00:40.089091005 INFO  GST_REFCOUNTING gstelement.c:2948:gst_element_finalize:<img_pngEnc> finalize
0:00:40.089176005 INFO  GST_REFCOUNTING gstelement.c:2953:gst_element_finalize:<img_pngEnc> finalize parent
0:00:40.089343339 INFO  GST_REFCOUNTING gstelement.c:2873:gst_element_dispose:<img_converter> dispose
0:00:40.089462005 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':sink> dispose
0:00:40.089591339 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':src> dispose
0:00:40.089711672 INFO  GST_REFCOUNTING gstelement.c:2917:gst_element_dispose:<img_converter> parent class dispose
0:00:40.089810339 INFO  GST_REFCOUNTING gstelement.c:2948:gst_element_finalize:<img_converter> finalize
0:00:40.089894672 INFO  GST_REFCOUNTING gstelement.c:2953:gst_element_finalize:<img_converter> finalize parent
0:00:40.090170005 INFO  GST_REFCOUNTING gstelement.c:2873:gst_element_dispose:<img_valve> dispose
0:00:40.090283339 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':src> dispose
0:00:40.090425339 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':sink> dispose
0:00:40.090551339 INFO  GST_REFCOUNTING gstelement.c:2917:gst_element_dispose:<img_valve> parent class dispose
0:00:40.090647672 INFO  GST_REFCOUNTING gstelement.c:2948:gst_element_finalize:<img_valve> finalize
0:00:40.090733339 INFO  GST_REFCOUNTING gstelement.c:2953:gst_element_finalize:<img_valve> finalize parent
0:00:40.090896672 INFO  GST_REFCOUNTING gstelement.c:2873:gst_element_dispose:<img_queue> dispose
0:00:40.091003339 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':sink> dispose
0:00:40.091148339 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':src> dispose
0:00:40.091280672 INFO  GST_REFCOUNTING gstelement.c:2917:gst_element_dispose:<img_queue> parent class dispose
0:00:40.091391005 INFO  GST_REFCOUNTING gstelement.c:2948:gst_element_finalize:<img_queue> finalize
0:00:40.091476339 INFO  GST_REFCOUNTING gstelement.c:2953:gst_element_finalize:<img_queue> finalize parent
0:00:40.091749672 INFO  GST_REFCOUNTING gstelement.c:2873:gst_element_dispose:<video_sink> dispose
0:00:40.091860005 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':sink> dispose
0:00:40.091978672 INFO  GST_REFCOUNTING gstelement.c:2917:gst_element_dispose:<video_sink> parent class dispose
0:00:40.092206339 INFO  GST_REFCOUNTING gstelement.c:2948:gst_element_finalize:<video_sink> finalize
0:00:40.092299339 INFO  GST_REFCOUNTING gstelement.c:2953:gst_element_finalize:<video_sink> finalize parent
0:00:40.092583339 INFO  GST_REFCOUNTING gstelement.c:2873:gst_element_dispose:<video_queue> dispose
0:00:40.092697339 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':sink> dispose
0:00:40.092839672 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':src> dispose
0:00:40.092971005 INFO  GST_REFCOUNTING gstelement.c:2917:gst_element_dispose:<video_queue> parent class dispose
0:00:40.093083339 INFO  GST_REFCOUNTING gstelement.c:2948:gst_element_finalize:<video_queue> finalize
0:00:40.093171005 INFO  GST_REFCOUNTING gstelement.c:2953:gst_element_finalize:<video_queue> finalize parent
0:00:40.093336005 INFO  GST_REFCOUNTING gstelement.c:2873:gst_element_dispose:<video_convert> dispose
0:00:40.093441672 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':sink> dispose
0:00:40.093573339 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':src> dispose
0:00:40.093687672 INFO  GST_REFCOUNTING gstelement.c:2917:gst_element_dispose:<video_convert> parent class dispose
0:00:40.093792005 INFO  GST_REFCOUNTING gstelement.c:2948:gst_element_finalize:<video_convert> finalize
0:00:40.093878005 INFO  GST_REFCOUNTING gstelement.c:2953:gst_element_finalize:<video_convert> finalize parent
0:00:40.094060005 INFO  GST_REFCOUNTING gstelement.c:2873:gst_element_dispose:<capture_src> dispose
0:00:40.094167339 DEBUG GST_REFCOUNTING gstpad.c:662:gst_pad_dispose:<'':src> dispose
0:00:40.094282339 INFO  GST_REFCOUNTING gstelement.c:2917:gst_element_dispose:<capture_src> parent class dispose
0:00:40.094393339 INFO  GST_REFCOUNTING gstelement.c:2948:gst_element_finalize:<capture_src> finalize
0:00:40.094480005 INFO  GST_REFCOUNTING gstelement.c:2953:gst_element_finalize:<capture_src> finalize parent
0:00:40.094579672 INFO  GST_REFCOUNTING gstelement.c:2873:gst_element_dispose:<pipeline> dispose
0:00:40.094669339 INFO  GST_REFCOUNTING gstelement.c:2917:gst_element_dispose:<pipeline> parent class dispose
0:00:40.094764005 INFO  GST_REFCOUNTING gstelement.c:2948:gst_element_finalize:<pipeline> finalize
0:00:40.094846339 INFO  GST_REFCOUNTING gstelement.c:2953:gst_element_finalize:<pipeline> finalize parent
state: NONE
startPipeline exit
handle_keyboard exit
keyboard_gsource_func exit
keyboard_gsource_func entry
handle_keyboard entry
quit
handle_keyboard exit
keyboard_gsource_func exit
g_client_loop exit
main exit


*************** module source code ***************


#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <gst/gst.h>

#define IMX6

/* capture dims */
#define CAPTURE_W   512
#define CAPTURE_H   512
/* main display screen dims */
#define SCREEN_W    1920
#define SCREEN_H    1080
/* main display video dims */
#define VIDEO_W     1000
#define VIDEO_H     1000

 typedef enum {
  LIVE,
  LIVE_PAUSE,
  NONE,
  NUM_STATES = NONE,
} PipelineState_t;

typedef enum {
  PIPELINE_FLATTENED_LIVE,
  NUM_PIPELINE_TYPES
} PipelineType_t;

typedef struct {
  /* gst stuctures */
  GstElement *pipeline;

  /* Flattened evaluation */
  GstElement *capture_src;
  GstElement *video_convert;
  GstElement *video_queue;
  GstElement *video_sink;
  GstElement *img_queue;
  GstElement *img_valve;
  GstElement *img_converter;
  GstElement *img_pngEnc;
  GstElement *img_sink;

  /* image encoder sink probe */
  gulong img_encode_sink_probe_id;
  GstPad *img_encode_block_pad;

  GstElement *aux_bin;
  GstElement *encode_bin;
  GstElement *encode_filesink;
  GstElement *img_filesink;
  GstElement *decode_bin;
  GstElement *flushPipline;

  GstElement *tee;
  GstElement *valve;
  GstCaps *caps;
  GstPad *encode_src;
  GstPad *decode_sink;

  // main loop
  GMainLoop *main_loop;

  /* current pipeline type */
  PipelineType_t pipeline_type;
  PipelineState_t state;

  /* pad probe locks */
  gint in_image_capture_probe;
  gint in_encode_stop_probe;

} GstData_t;

// debug macro controls
#ifndef DEBUG
#define DEBUG
#endif

// enable function stack trace
#define TRACE
#ifdef TRACE
#define TRACE_ENTRY() g_print("%s entry\n", __FUNCTION__)
#define TRACE_EXIT() g_print("%s exit\n", __FUNCTION__)
#else
#define TRACE_ENTRY()
#define TRACE_EXIT()
#endif

#define ENABLE_MESSAGE_CB_PRINT
#ifdef ENABLE_MESSAGE_CB_PRINT
#define MESSAGE_CB_PRINT(...) g_print(__VA_ARGS__)
#else
#define MESSAGE_CB_PRINT(...)
#endif

static const char* s_stateDescription[] = {
    "LIVE",
    "LIVE_PAUSE",
    "NONE" };

static char filename[65];
GMainLoop *g_client_loop;
GIOChannel *g_io_stdin;
GSource* g_keyboardWatchPipe = NULL;
static guint g_keyboardWatchPipe_id;
GSource* g_keyboardWatch = NULL;
static guint g_keyboardWatch_id;

gboolean keyboard_gsource_func (GIOChannel *source, GIOCondition condition, GstData_t *data);
static int setState (GstData_t *data, PipelineState_t state);
static inline PipelineState_t getState (GstData_t *data);
static gboolean message_cb (GstBus * bus, GstMessage * message, gpointer data);
static gint initCapture (GstData_t *data);
static gint initDisplay (GstData_t *data);
static gint initImg (GstData_t *data);
static GstPadProbeReturn image_cb (GstPad *pad, GstPadProbeInfo *info, gpointer userdata);
static GstPad* linkTeeDynamic (GstElement *tee, GstElement *sink);
static int linkTee (GstElement *tee, GstElement *sink);


/* image encode sink probe callback */
static GstPadProbeReturn image_cb (GstPad *pad, GstPadProbeInfo *info, gpointer userdata) {
  GstData_t *data = (GstData_t *) userdata;
  TRACE_ENTRY();

  if (!g_atomic_int_compare_and_exchange (&data->in_image_capture_probe, FALSE, TRUE)) {
    TRACE_EXIT();
    return GST_PAD_PROBE_OK;
  }
  GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(data->pipeline), GST_DEBUG_GRAPH_SHOW_ALL, __FUNCTION__);

  /* drop frames on the upstream valve element */
  g_object_set(data->img_valve, "drop", TRUE, NULL);

  TRACE_EXIT();
  return GST_PAD_PROBE_PASS;
}


/* attach png image encode probe control */
void attach_img_encode_sink_probe (GstData_t *data) {
  TRACE_ENTRY();

  /* add pad probe */
  data->img_encode_block_pad = gst_element_get_static_pad(data->img_converter, "sink");
  data->img_encode_sink_probe_id = gst_pad_add_probe(data->img_encode_block_pad, GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_BLOCK, image_cb, data, NULL);

  TRACE_EXIT();
}


/* remove png image encode probe control */
void remove_img_encode_sink_probe (GstData_t *data) {
  TRACE_ENTRY();

  gst_pad_remove_probe(data->img_encode_block_pad, data->img_encode_sink_probe_id);
  data->img_encode_sink_probe_id = 0;
  gst_object_unref(data->img_encode_block_pad);

  TRACE_EXIT();
}


/* initialize a pipeline which captures/renders v4l2 input and captures/encodes single
   png images off the v4l2 streame using a valve/pngenc compination */
int initPipeline (GstData_t * data, PipelineType_t pipeline_type, char *clip_filename) {
  TRACE_ENTRY();

  if (pipeline_type == PIPELINE_FLATTENED_LIVE) {

    if (getState(data) != NONE) {
      g_printerr("initPipeline() called when pipeline already exists\n");
      TRACE_EXIT();
      return -1;
    }
    memset(data, 0, sizeof(GstData_t));
    data->pipeline_type = PIPELINE_FLATTENED_LIVE;

    // create specific context
    if (data->main_loop) {
      g_printerr("data->main_loop should be NULL");
    }
    GMainContext* context = g_main_context_new();
    data->main_loop = g_main_loop_new(context, FALSE);
    // attach console command line control in leu of API calls
    g_keyboardWatchPipe = g_io_create_watch(g_io_stdin, G_IO_IN);
    g_source_set_callback(g_keyboardWatchPipe, (GSourceFunc)keyboard_gsource_func, (gpointer)data, NULL);
    g_keyboardWatchPipe_id = g_source_attach(g_keyboardWatchPipe, context);

    g_main_context_unref(context);

    g_print("init PIPELINE_LIVE\n");

    /* Create the empty pipeline */
    data->pipeline = gst_pipeline_new("pipeline");

    /* Create the elements */
    initCapture(data);
    initDisplay(data);
    initImg(data);

    data->tee = gst_element_factory_make("tee", "tee");

    setState(data, NONE);

    /* set the capture and decide capabilities */
    data->caps =  gst_caps_new_simple("video/x-raw",
                                      "format",G_TYPE_STRING, "BGRx",
                                      "width", G_TYPE_INT, CAPTURE_W,
                                      "height", G_TYPE_INT, CAPTURE_H,
                                      "framerate", GST_TYPE_FRACTION, 30, 1,
                                      NULL);

    if (!data->pipeline || !data->tee || !data->caps) {
      g_printerr ("Not all elements could be created.\n");
      gst_caps_unref(data->caps);
      TRACE_EXIT();
      return -1;
    }

    /* check the links */

    /* add tee to the pipeline */
    gst_bin_add_many(GST_BIN(data->pipeline), data->tee, NULL);

    /* Link capture to tee */
    if (GST_PAD_LINK_FAILED(gst_element_link_filtered(data->capture_src, data->tee, data->caps))){
      g_printerr("Capture could not link tee and capture_src\n");
      TRACE_EXIT();
      return -1;
    }

    /* link the tee to downstream video render and image multifilesink */
    if (!linkTee(data->tee, data->video_convert) || !linkTee(data->tee, data->img_queue)) {
      g_printerr("Tee could not be linked.\n");
      TRACE_EXIT();
      return -1;
    }

    /* add bus watch */
    GstBus *bus;
    bus = gst_pipeline_get_bus(GST_PIPELINE(data->pipeline));
    if (gst_bus_add_watch(bus, message_cb, (GstData_t*)data) == 0) {
      g_print("gst_bus_add_watch() failure: pipe already has bus\n");
    }

    gst_caps_unref(data->caps);
    gst_object_unref(bus);

    GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(data->pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "initPipeline-LIVE");

  } else {
    g_printerr ("Invalid pipeline type\n");
    TRACE_EXIT();
    return -1;
  }

  TRACE_EXIT();
  return 1;
}


/* initialize png imaging pipeline elements */
static gint initImg (GstData_t *data) {
  GstPad *image_queue_src_pad;
  gint retVal = -1;
  TRACE_ENTRY();

  data->img_queue = gst_element_factory_make("queue", "img_queue");
  data->img_valve = gst_element_factory_make("valve", "img_valve");
  data->img_converter = gst_element_factory_make("videoconvert", "img_converter");
  data->img_pngEnc = gst_element_factory_make("pngenc", "img_pngEnc");
  data->img_sink = gst_element_factory_make("multifilesink", "img_sink");

  image_queue_src_pad = gst_element_get_static_pad(data->img_queue, "src");
  gst_pad_use_fixed_caps(image_queue_src_pad);

  if (data->img_queue && data->img_valve && data->img_converter &&
      data->img_pngEnc && data->img_sink && image_queue_src_pad) {

    g_object_set(data->img_valve, "drop", TRUE, NULL);
    g_object_set(data->img_sink, "location", "frame%05d.png", NULL);
    g_object_set(data->img_sink, "async", 0, NULL);
    g_object_set(data->img_sink, "enable-last-sample", FALSE, NULL);
    g_object_set(data->img_converter, "qos", FALSE, NULL);
    g_object_set(data->img_pngEnc, "snapshot", FALSE, NULL);

    attach_img_encode_sink_probe(data);

    /* add and link elements */
    gst_bin_add_many(GST_BIN(data->pipeline), data->img_queue, data->img_valve, data->img_converter, data->img_pngEnc, data->img_sink, NULL);
    gst_element_link_many(data->img_queue, data->img_valve, data->img_converter, data->img_pngEnc, data->img_sink, NULL);

    /* cleanup */
    gst_object_unref(GST_OBJECT(image_queue_src_pad));

    retVal = 0;

    TRACE_EXIT();

  } else {
    g_print("element construction failure\n");

    if (image_queue_src_pad) gst_object_unref(GST_OBJECT(image_queue_src_pad));
    data->img_queue = NULL;
    data->img_valve = NULL;
    data->img_converter = NULL;
    data->img_pngEnc = NULL;
    data->img_sink = NULL;

    TRACE_EXIT();
  }

  return retVal;
}

/* initialize video capture pipeline elements */
static gint initCapture (GstData_t *data) {
  gint retVal = -1;
  TRACE_ENTRY();

  data->capture_src = gst_element_factory_make("v4l2src", "capture_src");

  if (data->capture_src) {
    g_object_set(data->capture_src, "device", "/dev/video0", "do-timestamp", TRUE, NULL);

    /* add element to pipeline */
    gst_bin_add(GST_BIN(data->pipeline), data->capture_src);

    TRACE_EXIT();
    retVal = 0;
  } else {
    g_print("!data->capture_src\n");
    TRACE_EXIT();
    return retVal;
  }

  return retVal;
}


/* initialize video render pipeline elements */
static gint initDisplay (GstData_t *data) {
  gint retVal = -1;
  TRACE_ENTRY();

  data->video_queue = gst_element_factory_make("queue", "video_queue");
  data->video_sink = gst_element_factory_make ("overlaysink", "video_sink");
  data->video_convert = gst_element_factory_make ("imxvideoconvert_g2d", "video_convert");

  if (data->video_sink && data->video_convert) {

    g_object_set(data->video_sink, "overlay-top", ((SCREEN_H - VIDEO_H)),
                 "overlay-left", ((1536 - VIDEO_W) / 2),
                 "overlay-width", VIDEO_W,
                 "overlay-height", VIDEO_H,
                 "display-slave", 1, NULL);

    /* add and link elements */
    gst_bin_add_many(GST_BIN(data->pipeline), data->video_convert, data->video_queue, data->video_sink, NULL);
    gst_element_link_many(data->video_convert, data->video_queue, data->video_sink, NULL);

    retVal = 0;
    TRACE_EXIT();

  } else {
    g_print("!data->video_sink || !data->video_convert\n");
    data->video_sink = NULL;
    data->video_convert = NULL;
    TRACE_EXIT();
    return retVal;
  }

  return retVal;
}

/* link either the video render or image capture downstream pipeline elements */
static GstPad* linkTeeDynamic (GstElement *tee, GstElement *sink) {
  GstPadTemplate *tee_pad_template;
  GstPad *tee_pad, *sink_pad;
  GstElementClass *klass;
  GstPad *ret = NULL;
  TRACE_ENTRY();

  if (!GST_IS_ELEMENT(tee)) g_printerr("!GST_IS_ELEMENT(tee)\n");
  if (!GST_IS_ELEMENT(sink)) g_printerr("!GST_IS_ELEMENT(sink)\n");

  // check the arguments are valid
  klass = GST_ELEMENT_GET_CLASS (tee);
  // template for tee pad
  tee_pad_template = gst_element_class_get_pad_template(klass, "src_%u");

  /* request the tee pad */
  tee_pad = gst_element_request_pad(tee, tee_pad_template, NULL, NULL);
  g_print("Obtained request pad %s from %s.\n", gst_pad_get_name(tee_pad), GST_ELEMENT_NAME(tee));

  /* get the sink pad */
  sink_pad = gst_element_get_static_pad(sink, "sink");
  g_print("Obtained pad %s for branch %s.\n", gst_pad_get_name(sink_pad), GST_ELEMENT_NAME(sink));

  // Link the pads
  if (GST_PAD_LINK_FAILED(gst_pad_link(tee_pad, sink_pad))){
    g_printerr("%s could not be linked to %s.\n", GST_ELEMENT_NAME(tee), GST_ELEMENT_NAME(sink));
    gst_object_unref(tee_pad);
  } else {
    ret = tee_pad;
  }

  // cleanup
  gst_object_unref(sink_pad);

  TRACE_EXIT();
  return ret;
}


/* link either the video render or image capture downstream pipeline elements */
static int linkTee (GstElement *tee, GstElement *sink) {
  GstPad *tee_src_pad;
  TRACE_ENTRY();

  tee_src_pad = linkTeeDynamic(tee, sink);
  if(tee_src_pad) {
    gst_object_unref(tee_src_pad);
    TRACE_EXIT();
    return 1;
  } else {
    g_printerr("linkTeeDynamic() failure\n");
    TRACE_EXIT();
    return 0;
  }
}


int captureImage (GstData_t *data, char* filename) {
  TRACE_ENTRY();

  data->in_image_capture_probe = FALSE;

  if (data->pipeline_type == PIPELINE_FLATTENED_LIVE) {
    g_object_set(data->img_sink, "location", filename, NULL);
    g_object_set(data->img_valve, "drop", FALSE, NULL);
  } else {
    g_object_set(data->img_filesink, "location", filename, NULL);
    g_object_set(data->valve, "drop", FALSE, NULL);
  }

  TRACE_EXIT();
  return 1;
}


int startPipeline (GstData_t *data) {

  PipelineState_t state = getState(data);
  int ret = 0;

  TRACE_ENTRY();

  switch(data->pipeline_type) {

    case PIPELINE_FLATTENED_LIVE:
      g_print("  PIPELINE_FLATTENED_LIVE \n");

      if (state == NONE) {
        setState(data, LIVE);
        gst_element_set_state(data->pipeline, GST_STATE_PLAYING);

        g_main_loop_run(data->main_loop);

        gst_object_unref(data->pipeline);
        data->pipeline = NULL;
        setState(data, NONE);
        ret = 1;
      } else {
        g_print("%s invalid state \n", __FUNCTION__);
      }
      break;

    default:
      g_printerr("  invalid pipeline_type\n");
      break;
  }

  TRACE_EXIT();
  return ret;
}

/* destroy pipeline and unref its elements */
int destroyPipeline (GstData_t *data) {
  TRACE_ENTRY();

  if (data->pipeline && (data->pipeline_type == PIPELINE_FLATTENED_LIVE)) {

    gint device_fd;
    if (data->capture_src != NULL) {
      g_print("capture_src != NULL\n");
      g_object_get(data->capture_src, "device-fd", &device_fd, NULL);
      g_print("capture_src::device-fd:%d\n", device_fd);
    } else {
      g_print("capture_src == NULL\n");
    }

    /* inspect pipeline element references */
    if (data->capture_src) g_print("capture_src: %d\n", GST_OBJECT_REFCOUNT_VALUE(data->capture_src));
    if (data->tee) g_print("tee ref_count: %d\n", GST_OBJECT_REFCOUNT_VALUE(data->tee));
    if (data->video_queue) g_print("video_queue ref_count: %d\n", GST_OBJECT_REFCOUNT_VALUE(data->video_queue));
    if (data->video_convert) g_print("video_convert ref_count: %d\n", GST_OBJECT_REFCOUNT_VALUE(data->video_convert));
    if (data->video_sink) g_print("video_sink ref_count: %d\n", GST_OBJECT_REFCOUNT_VALUE(data->video_sink));
    if (data->img_queue) g_print("img_queue ref_count: %d\n", GST_OBJECT_REFCOUNT_VALUE(data->img_queue));
    if (data->img_valve) g_print("img_valve ref_count: %d\n", GST_OBJECT_REFCOUNT_VALUE(data->img_valve));
    if (data->img_converter) g_print("img_converter ref_count: %d\n", GST_OBJECT_REFCOUNT_VALUE(data->img_converter));
    if (data->img_pngEnc) g_print("img_pngEnc ref_count: %d\n", GST_OBJECT_REFCOUNT_VALUE(data->img_pngEnc));
    if (data->img_sink) g_print("img_sink ref_count: %d\n", GST_OBJECT_REFCOUNT_VALUE(data->img_sink));

    remove_img_encode_sink_probe(data);

    /* terminate pipeline */
    if (gst_element_set_state(data->pipeline, GST_STATE_NULL) == GST_STATE_CHANGE_ASYNC) {
      g_print("GST_STATE_CHANGE_ASYNC\n");
      gboolean waitForNullState = TRUE;
      while (waitForNullState) {
        sleep(1);
        GstState state[2];
        int i = 0;
        GstStateChangeReturn stateChangeRet = gst_element_get_state(data->pipeline, &state[0], &state[1], 1000000000);
        if (stateChangeRet == GST_STATE_CHANGE_SUCCESS) {
          MESSAGE_CB_PRINT("***** message: oldstate/newstate/pending: ");
          for (i = 0; i < 2; i++) {
            switch (state[i]) {
            case GST_STATE_VOID_PENDING:
                MESSAGE_CB_PRINT(" PENDING ");
                break;
            case GST_STATE_NULL:
                MESSAGE_CB_PRINT(" NULL    ");
                break;
            case GST_STATE_READY:
                MESSAGE_CB_PRINT(" READY   ");
                break;
            case GST_STATE_PAUSED:
                MESSAGE_CB_PRINT(" PAUSED  ");
                break;
            case GST_STATE_PLAYING:
                MESSAGE_CB_PRINT(" PLAYING ");
                break;
            }
          }
        }
      } // while (waitForNullState)
    }
    setState(data, NONE);

    g_print("data->pipeline ref_count: %d\n", ((GObject*)(data->pipeline))->ref_count);

    /* inspect pipeline element references */
    if (data->capture_src) g_print("capture_src: %d\n", GST_OBJECT_REFCOUNT_VALUE(data->capture_src));
    if (data->tee) g_print("tee ref_count: %d\n", GST_OBJECT_REFCOUNT_VALUE(data->tee));
    if (data->video_queue) g_print("video_queue ref_count: %d\n", GST_OBJECT_REFCOUNT_VALUE(data->video_queue));
    if (data->video_convert) g_print("video_convert ref_count: %d\n", GST_OBJECT_REFCOUNT_VALUE(data->video_convert));
    if (data->video_sink) g_print("video_sink ref_count: %d\n", GST_OBJECT_REFCOUNT_VALUE(data->video_sink));
    if (data->img_queue) g_print("img_queue ref_count: %d\n", GST_OBJECT_REFCOUNT_VALUE(data->img_queue));
    if (data->img_valve) g_print("img_valve ref_count: %d\n", GST_OBJECT_REFCOUNT_VALUE(data->img_valve));
    if (data->img_converter) g_print("img_converter ref_count: %d\n", GST_OBJECT_REFCOUNT_VALUE(data->img_converter));
    if (data->img_pngEnc) g_print("img_pngEnc ref_count: %d\n", GST_OBJECT_REFCOUNT_VALUE(data->img_pngEnc));
    if (data->img_sink) g_print("img_sink ref_count: %d\n", GST_OBJECT_REFCOUNT_VALUE(data->img_sink));

    if (data->capture_src != NULL) {
      g_print("capture_src != NULL\n");
      g_object_get(data->capture_src, "device-fd", &device_fd, NULL);
      g_print("capture_src::device-fd:%d\n", device_fd);
    } else {
      g_print("capture_src == NULL\n");
    }

    /* exit gstreamer pipe loop */
    g_main_loop_quit(data->main_loop);
    g_main_loop_unref(data->main_loop);
    data->main_loop = NULL;

    TRACE_EXIT();
    return 1;

  } else {
    g_print("pipeline does not exist\n");
    TRACE_EXIT();
    return -1;
  }
}


static void print_usage() {
    g_print("\n");
    g_print("************************* usage *************************\n");
    g_print("* k: live exam video                                    *\n");
    g_print("* h: return to home:                                    *\n");
    g_print("* q: exit executable                                    *\n");
    g_print("* s: save image                                         *\n");
    g_print("* g: save current pipeline graph                        *\n");
    g_print("************************* usage *************************\n");
    g_print("\n");
}


/* console keyboard control */
static gboolean handle_keyboard (GIOChannel* source, GstData_t* data) {

  gchar *str = NULL;
  char timestr[60];
  struct tm *t_tm;
  time_t t;
  TRACE_ENTRY();

  if (g_io_channel_read_line((GIOChannel *)source, &str, NULL, NULL, NULL) != G_IO_STATUS_NORMAL) {
    g_printerr("g_io_channel_read_line() != G_IO_STATUS_NORMAL\n");
    return TRUE;
  }

  switch (g_ascii_tolower (str[0])) {

  case 'k':

    // destroy current pipeline
    destroyPipeline(data);

    /* build pipeline */
    initPipeline(data, PIPELINE_FLATTENED_LIVE, NULL);

    /* dump pipeline to dot file */
    GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(data->pipeline),
                              GST_DEBUG_GRAPH_SHOW_ALL,
                              "live_flattened-");

    /* Start playing the pipeline */
    startPipeline(data);

    break;

  case 'h':

    g_print("navigate home\n");

    /* return to home */
    if (getState(data) == LIVE) {
      destroyPipeline(data);
    } else {
      g_print("Invalid cmd\n");
    }
    break;

  case 'q':

    /* exit app */
    g_print("quit\n");
    if (data->main_loop != NULL) {
      destroyPipeline(data);
    } else {
      // destroy pipeline management loop
      g_main_loop_quit(g_client_loop);
    }
    break;

  case 's':

    g_print("save image\n");

    /* save image */
    time(&t);
    t_tm = localtime(&t);
    strftime(timestr, 60, "%Y%m%dT%H%M%S", t_tm);
    sprintf(filename, "%s.png", timestr);
    g_print ("Save image to %s\n", filename);
    captureImage(data, filename);
    break;

  case 'g':

    g_print("create pipeline dot\n");

    /* dump current pipeline */
    time(&t);
    t_tm = localtime(&t);
    strftime(timestr, 60, "%Y%m%dT%H%M%S", t_tm);
    sprintf(filename, "%s-%s", __FUNCTION__, timestr);

    g_print("Saving pipeline graph to %s.dot\n", filename);

    GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(data->pipeline),
                              GST_DEBUG_GRAPH_SHOW_ALL,
                              filename);
    break;

  case '?':

    print_usage();
    break;

  default:

    g_printerr("invalid command\n");
    break;
  }

  g_free (str);

  TRACE_EXIT();
  return TRUE;
}


gboolean keyboard_gsource_func (GIOChannel *source, GIOCondition condition, GstData_t *data)
{
  gboolean retVal;
  TRACE_ENTRY();

  retVal = handle_keyboard(g_io_stdin, data);

  TRACE_EXIT();
  return retVal;
}


int main (int argc, char *argv[]) {
  GstData_t data;
  GMainContext* cl_context = NULL;
  TRACE_ENTRY();

  /* Initialize GStreamer */
  gst_init(&argc, &argv);
  memset(&data, 0, sizeof(data));
  setState(&data, NONE);

  /* Create a GLib Main Loop and set it to run */
  cl_context = g_main_context_new();
  g_client_loop = g_main_loop_new(cl_context, FALSE);
  /* Add a keyboard watch so we get notified of keystrokes */
  g_io_stdin = g_io_channel_unix_new(fileno(stdin));

  // create keyboard watch and add to cl g_client_loop
  g_keyboardWatch = g_io_create_watch(g_io_stdin, G_IO_IN);
  g_source_set_callback(g_keyboardWatch, (GSourceFunc)keyboard_gsource_func, (gpointer)&data, NULL);
  g_keyboardWatch_id = g_source_attach(g_keyboardWatch, cl_context);

  // release contexts
  g_main_context_unref(cl_context);
  cl_context = NULL;

  print_usage();

  g_main_loop_run(g_client_loop);

  /* command line 'q' will exit g_client_loop */
  g_print("g_client_loop exit\n");

  /* Free resources */
  /* release keyboard GSource */
  g_source_unref(g_keyboardWatch);
  g_keyboardWatch = NULL;

  /* unref client loop */
  g_main_loop_unref(g_client_loop);
  g_client_loop = NULL;

  /* unref keyboard io */
  g_io_channel_unref(g_io_stdin);
  g_io_stdin = NULL;

  TRACE_EXIT();
  return 0;
}


/* pipeline bus message handling */
static gboolean message_cb (GstBus * bus, GstMessage * message, gpointer data) {

  GstData_t* gst_data = (GstData_t*)data;
  GError *err = NULL;
  gchar *name, *debug = NULL;

  name = gst_object_get_path_string(message->src);

  switch (GST_MESSAGE_TYPE(message)) {

    case GST_MESSAGE_STEP_START:
    {
      MESSAGE_CB_PRINT("***** message: %s\n", "GST_MESSAGE_STEP_START");
      gint64 current_time_nsec;
      if (gst_element_query_position(gst_data->pipeline, GST_FORMAT_TIME, &current_time_nsec)) {
        MESSAGE_CB_PRINT("current position: %lld\n", current_time_nsec);
      } else {
        g_printerr("%d: gst_element_query_position() failure\n", __LINE__);
      }
      break;
    }

    case GST_MESSAGE_STEP_DONE:
    {
      MESSAGE_CB_PRINT("***** message: %s\n", "GST_MESSAGE_STEP_DONE");
      gint64 current_time_nsec;
      if (gst_element_query_position(gst_data->pipeline, GST_FORMAT_TIME, &current_time_nsec)) {
        MESSAGE_CB_PRINT("current position: %lld\n", current_time_nsec);
      } else {
        g_printerr("%d: gst_element_query_position() failure\n", __LINE__);
      }
      break;
    }

    case GST_MESSAGE_RESET_TIME:
      MESSAGE_CB_PRINT("***** message: %s\n", "GST_MESSAGE_RESET_TIME");

      if (GST_IS_ELEMENT(gst_data->pipeline)) {
        MESSAGE_CB_PRINT("GST_IS_ELEMENT(gst_data->pipeline)\n");
        GstState state[2];
        int i = 0;
        GstStateChangeReturn stateChangeRet = gst_element_get_state(gst_data->pipeline, &state[0], &state[1], 1000000000);
        if (stateChangeRet == GST_STATE_CHANGE_SUCCESS) {
          MESSAGE_CB_PRINT("***** message: oldstate/newstate/pending: ");
          for (i = 0; i < 2; i++) {
              switch (state[i]) {
              case GST_STATE_VOID_PENDING:
                  MESSAGE_CB_PRINT(" PENDING ");
                  break;
              case GST_STATE_NULL:
                  MESSAGE_CB_PRINT(" NULL    ");
                  break;
              case GST_STATE_READY:
                  MESSAGE_CB_PRINT(" READY   ");
                  break;
              case GST_STATE_PAUSED:
                  MESSAGE_CB_PRINT(" PAUSED  ");
                  break;
              case GST_STATE_PLAYING:
                  MESSAGE_CB_PRINT(" PLAYING ");
                  break;
              }
          }
          MESSAGE_CB_PRINT("\n");

        } else if (stateChangeRet == GST_STATE_CHANGE_FAILURE) {
          MESSAGE_CB_PRINT("GST_STATE_CHANGE_FAILURE\n");
        } else if (stateChangeRet == GST_STATE_CHANGE_ASYNC) {
          MESSAGE_CB_PRINT("GST_STATE_CHANGE_ASYNC\n");
        } else {
          MESSAGE_CB_PRINT("unknown gst_element_get_state() failure\n");
        }
      } else {
        g_print("!GST_IS_ELEMENT(gst_data->pipeline)\n");
      }
      break;

    case GST_MESSAGE_ERROR:
    {
      g_print("***** message: %s\n", "GST_MESSAGE_ERROR");
      gst_message_parse_error (message, &err, &debug);

      g_printerr ("ERROR: from element %s: %s\n", name, err->message);
      if (debug != NULL)
        g_printerr ("Additional debug info:\n%s\n", debug);

      g_error_free (err);
      g_free (debug);
      break;
    }

    case GST_MESSAGE_WARNING:{
      MESSAGE_CB_PRINT("***** message: %s\n", "GST_MESSAGE_WARNING");
      gst_message_parse_warning (message, &err, &debug);

      g_printerr ("ERROR: from element %s: %s\n", name, err->message);
      if (debug != NULL)
        g_printerr ("Additional debug info:\n%s\n", debug);

      g_error_free (err);
      g_free (debug);
      break;
    }

    case GST_MESSAGE_EOS:
      MESSAGE_CB_PRINT("***** message: %s\n", "GST_MESSAGE_EOS");
      break;

    case GST_MESSAGE_STATE_CHANGED:
    {
      GstState state[3];
      int i = 0;
      gst_message_parse_state_changed(message, &state[0], &state[1], &state[2]);

      MESSAGE_CB_PRINT("***** message: oldstate/newstate/pending: ");
      for (i = 0; i < 3; i++) {
          switch (state[i]) {
          case GST_STATE_VOID_PENDING:
              MESSAGE_CB_PRINT(" PENDING ");
              break;
          case GST_STATE_NULL:
              MESSAGE_CB_PRINT(" NULL    ");
              break;
          case GST_STATE_READY:
              MESSAGE_CB_PRINT(" READY   ");
              break;
          case GST_STATE_PAUSED:
              MESSAGE_CB_PRINT(" PAUSED  ");
              break;
          case GST_STATE_PLAYING:
              MESSAGE_CB_PRINT(" PLAYING ");
              break;
          }
      }
      MESSAGE_CB_PRINT("\n");
      break;
    }

    case GST_MESSAGE_QOS:
    {
      GstFormat format = GST_FORMAT_BUFFERS;
      guint64 processed, dropped;
      gint64 jitter;
      gdouble proportion;
      gint quality;

      gst_message_parse_qos_stats(message,
                                  &format,
                                  &processed,
                                  &dropped);
      gst_message_parse_qos_values(message,
                                   &jitter,
                                   &proportion,
                                   &quality);

      MESSAGE_CB_PRINT("***** message: GST_MESSAGE_QOS, processed=%lld dropped=%lld jitter=%lld proportion=%g quality=%d\n", \
                       processed, dropped, jitter, proportion, quality);
      break;
    }

    default:
      MESSAGE_CB_PRINT("***** message: %s\n", GST_MESSAGE_TYPE_NAME(message));
      break;

  }

  g_free(name);

  return TRUE;
}


static int setState (GstData_t *data, PipelineState_t state) {
  data->state = state;
  if (s_stateDescription[data->state]) {
    g_print("state: %s\n", s_stateDescription[data->state]);
  }
  return 1;
}
static inline PipelineState_t getState (GstData_t *data) {
  return data->state;
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/gstreamer-devel/attachments/20151204/62483663/attachment-0001.html>


More information about the gstreamer-devel mailing list