| 319 | |
| 320 | |
| 321 | [=#video-sync] |
| 322 | == Analog Video Capture Sync and determining loss of signal/sync |
| 323 | A common issue when capturing analog video via the adv7180 sensor is that the Video does not synchronize properly if the signal is lost and re-acquired. This is because the nature of the adv7180 (and most analog video decoders) is that they start presenting decoded video pixel data before they see a vertical sync indicating the start of a frame. This will confuse the IMX6 capture and cause an image that either continually rolls vertically or appears split horizontally. |
| 324 | |
| 325 | On stream startup the IMX6 capture driver will throw away the first few frames in order to avoid this problem via a [https://github.com/Gateworks/linux-imx6/commit/e09b4fdae1a68f164614e218e3f95b1dcc570c7d patch in the Gateworks kernel]. |
| 326 | |
| 327 | However, if this issue is occurring because your analog video signal is intermittent you must detect the loss of sync and restart capture. |
| 328 | |
| 329 | This issue appears to be more prevalent if you are using the IMX6 hardware de-interlacer. If you want to try capturing interlaced video to avoid this you can capture 1 field of the video (half height) and resize it to full height as follows: |
| 330 | {{{#!bash |
| 331 | # setup pipeline using MODE0 (raw) |
| 332 | MODE=0 media-ctl-setup adv7180 > adv7180_raw |
| 333 | . ./adv7180_raw |
| 334 | # launch gstreamer |
| 335 | gst-launch-1.0 v4l2src device=$DEVICE ! $GST_CONVERT ! video/x-raw,width=640,height=480 ! kmssink can-scale=false |
| 336 | }}} |
| 337 | |
| 338 | If you are wanting to use the hardware de-interlacer you can detect the loss of sync in two possible ways using v4l2 event notifiers (available in 5.4+ kernel): |
| 339 | 1. via the adv7180 V4L2_EVENT_SOURCE_CHANGE event is supposed to fire when a source changes status |
| 340 | 2. via the imx6 capture driver 'Frame Interval Monitor' which works by using math to determine if it thinks frames are coming in at an inappropriate interval |
| 341 | |
| 342 | The way you would use these notifiers is to use the VIDIOC_SUBSCRIBE_EVENT ioctl in an application to subscribe to the specific event you want. If you are using gst-launch to create a simple pipeline from userspace you can use the v4l2-ctl wait-for-event, poll-for-event, or --epoll-for-event parameters to wait for or check for an event meaning you would launch the pipeline in the background, wait for an event, then kill and restart the pipeline. I'll give you examples of using gst-launch. |
| 343 | |
| 344 | For example to catch the V4L2_EVENT_SOURCE_CHANGE from the adv7180 via shell: |
| 345 | {{{#!bash |
| 346 | # setup pipeline |
| 347 | media-ctl-setup adv7180 > adv7180_deinterlace |
| 348 | . ./adv7180_deinterlace |
| 349 | # launch gstreamer in background |
| 350 | gst-launch-1.0 v4l2src device=$DEVICE ! $GST_CONVERT ! kmssink & |
| 351 | # wait for a V4L2_EVENT_SOURCE_CHANGE event (id=1) |
| 352 | v4l2-ctl --device=$DEVICE --wait-for-event=5 |
| 353 | # now you can kill and restart gstreamer |
| 354 | }}} |
| 355 | |
| 356 | The downside of this is that I the adv7180 does not consistently give you interrupts on signal loss and detection from our experience. |
| 357 | |
| 358 | The other method is to use the IMX6 capture 'Frame Interval Monitor'. The downside to this is that it can take a bit of tuning and that it only is available on the ipu_csi capture device meaning you can't use the de-interlacer and will get only the even or odd lines (half height) |
| 359 | |
| 360 | To use the FIM method you would do something like the following steps: |
| 361 | {{{#!bash |
| 362 | # setup pipeline |
| 363 | media-ctl-setup adv7180 > adv7180_deinterlace |
| 364 | . ./adv7180_deinterlace |
| 365 | # enable frame interval monitor |
| 366 | v4l2-ctl --device $DEVICE --set-ctrl=fim_enable=1 |
| 367 | # you may need to adjust fim_num_average/fim_tolerance_min/fim_tolerance_max/fim_num_skip to your liking |
| 368 | # launch gstreamer in background |
| 369 | gst-launch-1.0 v4l2src device=$DEVICE ! $GST_CONVERT ! kmssink & |
| 370 | # wait for a V4L2_EVENT_IMX_FRAME_INTERVAL_ERROR event (id=0x08000001) |
| 371 | v4l2-ctl --device=$DEVICE --wait-for-event=0x08000001 |
| 372 | # now you can kill and restart gstreamer |
| 373 | }}} |