/*
 * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

=> PRE-REQUISITES :

1. You must install GStreamer-1.0 on the target board using apt-get, as follows:

   sudo apt-get install gstreamer1.0-tools gstreamer1.0-alsa gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav

2. To check the running gstreamer version, use the following command before you start using the nvgstcapture application:

   gst-inspect-1.0 --version

3. Execute the following commands on the target board's Ubuntu command line:

   export DISPLAY=:0

=> NvGstCapture Usage:

* The nvgstcapture application can capture video data and encapsulate encoded data in a container file.

* The nvgstcapture application supports both command-line and runtime options.


* The nvgstcapture application supports 2 CSI sources NvArgusCamera and NvCamera, default source is NvArgusCamera
   Use --csi-source application option to change the CSI source
   ./nvgstcapture-1.0 --csi-source=0 [NvArgusCamera]
   ./nvgstcapture-1.0 --csi-source=1 [NvCamera]

=> NvGstCapture Application Options:

    Usage:
      A) Prints help for NvArgusCamera : ./nvgstcapture-1.0 --help
      B) Prints help for NvCamera :      ./nvgstcapture-1.0 --help-nvcamerasrc

* Command-line options for NvArgusCamera:

  --prev-res                         Preview width & height.Range: 2 to 12 (5632x4224) e.g., --prev-res=3
  --cus-prev-res                     Custom Preview width & height e.g., --cus-prev-res=1920x1080
  --image-res                        Image width & height. Range: 2 to 12 (5632x4224) e.g., --image-res=3
  --video-res                        Video width & height. Range: 2 to 9 (3896x2192) e.g., --video-res=3
  --csi-source                       CSI Camera Plugin (0=NVArgusCamera 1=NVCamera)
  -m, --mode                         Capture mode value (1=still 2=video)
  -v, --video-enc                    Video encoder type (0=h264[HW] 1=vp8[HW] 2=h265[HW] 3=vp9[HW])
  -b, --enc-bitrate                  Video encoding Bit-rate(in bytes) e.g., --enc-bitrate=4000000
  --enc-profile                      Video encoder profile (Only for H.264) (0=Baseline, 1=Main, 2=High)
  -J, --image-enc                    Image encoder type (0=jpeg_SW[jpegenc] 1=jpeg_HW[nvjpegenc])
  -k, --file-type                    Container file type (0=mp4 1=3gp 2=mkv)
  --file-name                        Captured file name. nvcamtest is used by default
  --orientation                      Camera sensor orientation value
  -w, --whitebalance                 Capture whitebalance value
  --timeout                          Capture timeout value
  --saturation                       Camera Saturation value
  -A, --automate                     Run application in automation mode
  -S, --start-time                   Start capture after specified time in seconds. Default = 5 sec (use with --automate or -A only)
  -Q, --quit-after                   Quit application once automation is done after specified time in seconds. Default = 0 sec (use with --automate or -A only)
  -C, --count                        Number of iterations of automation testcase. Default = 1 (use with --automate or -A only)
  --capture-gap                      Number of milliseconds between successive image/video capture. Default = 250 msec (use with --automate and --capture-auto only)
  --capture-time                     Capture video for specified time in seconds. Default = 10 sec (use with --automate and --capture-auto only)
  --toggle-mode                      Toggle between still and video capture modes for count number of times (use with --automate or -A only)
  --capture-auto                     Do image/video capture in automation mode for count number of times(use with --automate or -A only)
  --enum-wb                          Enumerate all white-balance modes for count number of times (use with --automate or -A only)

Supported resolutions in case of NvArgusCamera
  (2) : 640x480
  (3) : 1280x720
  (4) : 1920x1080
  (5) : 2104x1560
  (6) : 2592x1944
  (7) : 2616x1472
  (8) : 3840x2160
  (9) : 3896x2192
  (10): 4208x3120
  (11): 5632x3168
  (12): 5632x4224

* Runtime options for NvArgusCamera:

  Help : 'h'
  Quit : 'q'
  Set Capture Mode:
      mo:<val>
          (1): image
          (2): video
  Get Capture Mode:
      gmo
  Set sensor orientation:
      so:<val>
          (0): none
          (1): Rotate counter-clockwise 90 degrees
          (2): Rotate 180 degrees
          (3): Rotate clockwise 90 degrees
  Get sensor orientation:
      gso
  Set Whitebalance Mode:
      wb:<val>
          (0): off
          (1): auto
          (2): incandescent
          (3): fluorescent
          (4): warm-fluorescent
          (5): daylight
          (6): cloudy-daylight
          (7): twilight
          (8): shade
          (9): manual
  Get Whitebalance Mode:
      gwb
  Set Saturation (0 to 2):
      st:<val> e.g., st:1.25
  Get Saturation:
      gst
  Capture: enter 'j' OR
           followed by a timer (e.g., jx5000, capture after 5 seconds) OR
           followed by multishot count (e.g., j:6, capture 6 images)
           timer/multihot values are optional, capture defaults to single shot with timer=0s
  Start Recording : enter '1'
  Stop Recording  : enter '0'
  Video snapshot  : enter '2' (While recording video)
  Get Preview Resolution:
      gpcr
  Get Image Capture Resolution:
      gicr
  Get Video Capture Resolution:
      gvcr


Runtime encoder configuration options:

  Set Encoding Bit-rate(in bytes):
      br:<val> e.g., br:4000000
  Get Encoding Bit-rate(in bytes):
      gbr
  Set Encoding Profile(only for H.264):
      ep:<val> e.g., ep:1
          (0): Baseline
          (1): Main
          (2): High
  Get Encoding Profile(only for H.264):
      gep
  Force IDR Frame on video Encoder(only for H.264):
      Enter 'f'

* Command-line options for NvCamera:

  --prev-res                         Preview width & height. USB Range: 0 to 12 (5632x4224) and CSI Range: 2 to 12 (5632x4224) e.g., --prev-res=3
  --cus-prev-res                     Custom Preview width & height [for CSI only] e.g., --cus-prev-res=1920x1080
  --image-res                        Image width & height. Range: 0 to 12 (5632x4224) e.g., --image-res=3
  --video-res                        Video width & height. Range: 0 to 9 (3896x2192) e.g., --video-res=3
  --csi-source                       CSI Camera Plugin (0=NVArgusCamera 1=NVCamera)
  -m, --mode                         Capture mode value (1=still 2=video)
  -v, --video-enc                    Video encoder type (0=h264[HW] 1=vp8[HW] 2=h265[HW] 3=vp9[HW])
  -b, --enc-bitrate                  Video encoding Bit-rate(in bytes) e.g., --enc-bitrate=4000000
  --enc-profile                      Video encoder profile (Only for H.264) (0=Baseline, 1=Main, 2=High)
  -J, --image-enc                    Image encoder type (0=jpeg_SW[jpegenc] 1=jpeg_HW[nvjpegenc])
  -k, --file-type                    Container file type (0=mp4 1=3gp 2=mkv)
  --color-format                     Color format to use (0=I420[default for v4l2],1=NV12[For CSI only and default for CSI], 2=YUY2[For V4L2 only])
  --cap-dev-node                     Video capture device node (0=/dev/video0[default], 1=/dev/video1, 2=/dev/video2) e.g., --cap-dev-node=0
  --svs                              [For USB] (=) chain for video Preview. [For CSI only] use "nvoverlaysink"
  --file-name                        Captured file name. nvcamtest is used by default
  --camsrc                           Camera Source to use (0=v4l2, 1=csi[default], 2=videotest, 3=eglstream)
  --orientation                      [For NVCamera only] Camera sensor orientation value
  -w, --whitebalance                 [For CSI only] Capture whitebalance value
  -s, --scene-mode                   [For NVCamera only] Camera Scene-Mode value
  -c, --color-effect                 [For NVCamera only] Camera Color Effect value
  --auto-exposure                    [For NVCamera only] Camera Auto-Exposure value
  --flash                            [For NVCamera only] Camera Flash value
  --flicker                          [For NVCamera only] Camera Flicker Detection and Avoidance Mode value
  --contrast                         [For NVCamera only] Camera Contrast value
  --saturation                       [For CSI only] Camera Saturation value
  --edge-enhancement                 [For NVCamera only] Camera Edge Enhancement value
  --tnr-strength                     [For NVCamera only] Camera TNR-Strength value
  --tnr-mode                         [For NVCamera only] Camera TNR Mode value
  --sensor-id                        [For NVCamera only] Camera Sensor ID value
  --eglstream-id                     [For NVCamera EGLStream Consumer] Select EGLStream Producer ID value. Default value 0
  --display-id                       [For nvoverlaysink only] Display ID value
  --aeRegion                         [For NVCamera Only] ROI for AE coordinates(top,left,bottom,right) and weight in that order.e.g., --aeRegion="30 40 200 200 1.2"
  --wbRegion                         [For NVCamera Only] ROI for AWB coordinates(top,left,bottom,right) and weight in that order.e.g., --wbRegion="30 40 200 200 1.2"
  --fpsRange                         [For NVCamera Only] FPS range values (low, high) e.g., --fpsRange="15 30"
  --exposure-time                    [For NVCamera only] Capture exposure time value. e.g., --exposure-time=0.033
  --wbGains                          [For NVCamera Only] WB gains values (R, GR, GB, B) in that order. e.g., --wbGains="1.2 1.4 0.8 1.6"
  --overlayConfig                    Overlay Configuration Options index and coordinates in (index, x_pos, y_pos, width, height) order  e.g. --overlayConfig="0, 0, 0, 1280, 720"
  --enable-exif                      Enable Exif data
  --dump-bayer                       Dump bayer data in addition to image capture.
  --eglConfig                        EGL window Coordinates (x_pos y_pos) in that order  e.g., --eglConfig="50 100"
  --aeLock                           [For NVCamera only] Enable auto exposure lock e.g., --aeLock
  --enable-meta                      Enable Sensor MetaData reporting
  --nvvideosink-create-eglstream     [For nvvideosink EGLStream Producer] Enable nvvideosink EGLStream Producer
  --callback                         Enable User callback to set capture settings per frame
  --app-profile                      Enable KPI profiling
  --kpi-numbers                      Enable KPI measurement
  -A, --automate                     Run application in automation mode
  -S, --start-time                   Start capture after specified time in seconds. Default = 5 sec (use with --automate or -A only)
  -Q, --quit-after                   Quit application once automation is done after specified time in seconds. Default = 0 sec (use with --automate or -A only)
  -C, --count                        Number of iterations of automation testcase. Default = 1 (use with --automate or -A only)
  -N, --num-sensors                  Number of sensors  (use with --automate or -A only)
  --capture-gap                      Number of milliseconds between successive image/video capture. Default = 250 msec (use with --automate and --capture-auto only)
  --capture-time                     Capture video for specified time in seconds. Default = 10 sec (use with --automate and --capture-auto only)
  --toggle-mode                      Toggle between still and video capture modes for count number of times (use with --automate or -A only)
  --toggle-sensor                    [For NVCamera only] Toggle between num_sensors if given otherwise between sensor-id 0 and 1 (use with --automate or -A only)
  --capture-auto                     Do image/video capture in automation mode for count number of times(use with --automate or -A only)
  --enum-wb                          [For NVCamera only] Enumerate all white-balance modes for count number of times (use with --automate or -A only)
  --enum-scm                         [For NVCamera only] Enumerate all scene modes for count number of times (use with --automate or -A only)
  --enum-ce                          [For NVCamera only] Enumerate all color-effect modes for count number of times (use with --automate or -A only)
  --enum-ae                          [For NVCamera only] Enumerate all auto-exposure modes for count number of times (use with --automate or -A only)
  --enum-f                           [For NVCamera only] Enumerate all flash modes for count number of times (use with --automate or -A only)
  --enum-fl                          [For NVCamera only] Enumerate all flicker detection and avoidance modes for count number of times (use with --automate or -A only)
  --enum-ct                          [For NVCamera only] Enumerate contrast value through 0 to 1 by a step of 0.1 for count number of times (use with --automate or -A only)
  --enum-st                          [For NVCamera only] Enumerate saturation value through 0 to 2 by a step of 0.1 for count number of times (use with --automate or -A only)
  --enum-ee                          [For NVCamera only] Enumerate edge-enhancement value through 0 to 1 by a step of 0.1 for count number of times (use with --automate or -A only)
  --enum-ts                          [For NVCamera only] Enumerate TNR strength value through 0 to 1 by a step of 0.1 for count number of times (use with --automate or -A only)
  --enum-tnr                         [For NVCamera only] Enumerate all TNR modes for count number of times (use with --automate or -A only)
  --streaming-mode                   [For NVCamera only] Enable streaming mode (1=stream only, 2=stream+record)
  --streaming-file                   File to stream instead of camera input

Supported resolutions in case of NvCamera
  (2) : 640x480
  (3) : 1280x720
  (4) : 1920x1080
  (5) : 2104x1560
  (6) : 2592x1944
  (7) : 2616x1472
  (8) : 3840x2160
  (9) : 3896x2192
  (10): 4208x3120
  (11): 5632x3168
  (12): 5632x4224

* Runtime options for NvCamera:

  Help : 'h'
  Quit : 'q'
  Set Capture Mode:
      mo:<val>
          (1): image
          (2): video
  Get Capture Mode:
      gmo
  Set Sensor Id (0 to 10):
      sid:<val> e.g., sid:2
  Get Sensor Id:
      gsid
  Set sensor orientation:
      so:<val>
          (0): none
          (1): Rotate counter-clockwise 90 degrees
          (2): Rotate 180 degrees
          (3): Rotate clockwise 90 degrees
  Get sensor orientation:
      gso
  Set Whitebalance Mode:
      wb:<val>
          (0): off
          (1): auto
          (2): incandescent
          (3): fluorescent
          (4): warm-fluorescent
          (5): daylight
          (6): cloudy-daylight
          (7): twilight
          (8): shade
          (9): manual
  Get Whitebalance Mode:
      gwb
  Set Scene-Mode:
      scm:<val>
          (0): face-priority
          (1): action
          (2): portrait
          (3): landscape
          (4): night
          (5): night-portrait
          (6): theatre
          (7): beach
          (8): snow
          (9): sunset
          (10): steady-photo
          (11): fireworks
          (12): sports
          (13): party
          (14): candle-light
          (15): barcode
  Get Scene-Mode:
      gscm
  Set Color Effect Mode:
      ce:<val>
          (1): off
          (2): mono
          (3): negative
          (4): solarize
          (5): sepia
          (6): posterize
          (7): aqua
  Get Color Effect Mode:
      gce
  Set Auto-Exposure Mode:
      ae:<val>
          (1): off
          (2): on
          (3): OnAutoFlash
          (4): OnAlwaysFlash
          (5): OnFlashRedEye
  Get Auto-Exposure Mode:
      gae
  Set Flash Mode:
      f:<val>
          (0): off
          (1): on
          (2): torch
          (3): auto
  Get Flash Mode:
      gf
  Set Flicker Detection and Avoidance Mode:
      fl:<val>
          (0): off
          (1): 50Hz
          (2): 60Hz
          (3): auto
  Get Flicker Detection and Avoidance Mode:
      gfl
  Set Contrast (0 to 1):
      ct:<val> e.g., ct:0.75
  Get Contrast:
      gct
  Set Saturation (0 to 2):
      st:<val> e.g., st:1.25
  Get Saturation:
      gst
  Set Exposure Time in seconds:
      ext:<val> e.g., ext:0.033
  Get Exposure Time:
      gext
  Set Auto Exposure Lock(0/1):
      ael:<val> e.g., ael:1
  Get Auto Exposure Lock:
      gael
  Set Edge Enhancement (0 to 1):
      ee:<val> e.g., ee:0.75
  Get Edge Enhancement:
      gee
  Set ROI for AE:
      It needs five values, ROI coordinates(top,left,bottom,right)
      and weight in that order
      aer:<val> e.g., aer:20 20 400 400 1.2
  Get ROI for AE:
      gaer
  Set ROI for AWB:
      It needs five values, ROI coordinates(top,left,bottom,right)
      and weight in that order
      wbr:<val> e.g., wbr:20 20 400 400 1.2
  Get ROI for AWB:
      gwbr
  Set FPS range:
      It needs two values, FPS Range (low, high) in that order
      fpsr:<val> e.g., fpsr:15 30
  Get FPS range:
      gfpsr
  Set WB Gains:
      It needs four values (R, GR, GB, B) in that order
      wbg:<val> e.g., wbg:1.2 2.2 0.8 1.6
  Get WB Gains:
      gwbg
  Set TNR Strength (0 to 1):
      ts:<val> e.g., ts:0.75
  Get TNR Strength:
      gts
  Set TNR Mode:
      tnr:<val>
          (0): NoiseReduction_Off
          (1): NoiseReduction_Fast
          (2): NoiseReduction_HighQuality
  Get TNR Mode:
      gtnr
  Capture: enter 'j' OR
           followed by a timer (e.g., jx5000, capture after 5 seconds) OR
           followed by multishot count (e.g., j:6, capture 6 images)
           timer/multihot values are optional, capture defaults to single shot with timer=0s
  Start Recording : enter '1'
  Stop Recording  : enter '0'
  Video snapshot  : enter '2' (While recording video)
  Set Preview Resolution:
      pcr:<val> e.g., pcr:3
          (2) : 640x480
          (3) : 1280x720
          (4) : 1920x1080
          (5) : 2104x1560
          (6) : 2592x1944
          (7) : 2616x1472
          (8) : 3840x2160
          (9) : 3896x2192
          (10): 4208x3120
          (11): 5632x3168
          (12): 5632x4224
  Note - For preview resolutions 4208x3120 and more use option --svs=nveglglessink
  Get Preview Resolution:
      gpcr
  Set Image Resolution:
      icr:<val> e.g., icr:3
          (2) : 640x480
          (3) : 1280x720
          (4) : 1920x1080
          (5) : 2104x1560
          (6) : 2592x1944
          (7) : 2616x1472
          (8) : 3840x2160
          (9) : 3896x2192
          (10): 4208x3120
          (11): 5632x3168
          (12): 5632x4224
  Get Image Capture Resolution:
      gicr
  Set Video Resolution:
      vcr:<val> e.g., vcr:3
          (2) : 640x480
          (3) : 1280x720
          (4) : 1920x1080
          (5) : 2104x1560
          (6) : 2592x1944
          (7) : 2616x1472
          (8) : 3840x2160
          (9) : 3896x2192
  Get Video Capture Resolution:
      gvcr


Runtime encoder configuration options:

  Set Encoding Bit-rate(in bytes):
      br:<val> e.g., br:4000000
  Get Encoding Bit-rate(in bytes):
      gbr
  Set Encoding Profile(only for H.264):
      ep:<val> e.g., ep:1
          (0): Baseline
          (1): Main
          (2): High
  Get Encoding Profile(only for H.264):
      gep
  Force IDR Frame on video Encoder(only for H.264):
      Enter 'f'

NOTES:

1. The nvgstcapture application generates image and video output files in the same directory as the application itself.

2. Filenames for image and video content are in the formats "nvcamtest(%d).jpg" and "nvcamtest(%d).mp4" respectively,
   where %d is a counter starting from 0 every time you run the application. Rename or move files between runs, to avoid
   overwriting results you want to save.

3. The nvgstcapture application default supports native capture(video only) mode.

4. Advance features, like setting zoom, brightness, exposure, and whitebalance, are not supported with USB-Camera.

5. The nvgstcapture application sets nvjpegenc[HW] by default for Image encoding.

6. User can specify sensor supported custom preview resolution. CSI camera will output at the custom resolution
   but visible preview will be capped at 1080p max. Command:
   ./nvgstcapture-1.0 --prev-res=2 --cus-prev-res=1280x960

7. nvgstcapture-1.0 supports automation. Details of the commands can be found in help. Enlisting a few example commandlines
   of few use-cases:

   i) Capture 50 images with 1080p resolutions:
      ./nvgstcapture-1.0 -A -C 50 --capture-auto --image-res=4

  ii) Capture 5 720p videos, each of length 60 seconds, with a gap of 2 seconds between each recording
      and quit application 10 seconds after that:
      ./nvgstcapture-1.0 -A -C 5 --capture-auto --video-res=3 --capture-time=60 --mode=2 --capture-gap=2000 --quit-after=10

8. Current GST version 1.8.3 which is part of ubuntu distribution 16.04, for h.265 streams only matroska mux container is supported by gstreamer 1.8.3.

9. nvhdmioverlaysink has been deprecated. Use nvoverlaysink with display-id option instead.
   For example to show video on the display with head=1: ./nvgstcapture-1.0 --display-id=1

10. For USB camera use "--cap-dev-node" command line option along with "--camsrc=0" to specify capture node.

11. The vp9 encoder is only supported for jetson-tx2.
