Add snapshot command line flag to set different camera modes

Add --camera_mode (WxH:N/D) to set the camera resolution and frame rate.
Default is still set as 2592x1944:15/1 (5MP@15fps)

Change-Id: If72f575840ea79720bf029aaca48e4fe77b0d90c
diff --git a/snapshot b/snapshot
index 8b6f60e..94e4c78 100755
--- a/snapshot
+++ b/snapshot
@@ -1,11 +1,13 @@
 #!/usr/bin/env python3
 
 import argparse
+import collections
 import contextlib
 import fcntl
 import os
 import select
 import sys
+import re
 import termios
 import time
 import threading
@@ -51,6 +53,21 @@
     t. ! {leaky_q} ! videoconvert ! {sink_caps} ! {sink_element}
     '''
 
+Fraction = collections.namedtuple('Fraction', ('num', 'den'))
+Fraction.__str__ = lambda self: '%s/%s' % (self.num, self.den)
+
+Format = collections.namedtuple('Format', ('width', 'height', 'framerate'))
+
+V4L2_DEVICE = re.compile(r'(?P<w>\d+)x(?P<h>\d+):(?P<num>\d+)/(?P<den>\d+)')
+
+def parse_format(src):
+    match = V4L2_DEVICE.search(src)
+    if match:
+        return Format(width=int(match.group('w')),
+                      height=int(match.group('h')),
+                      framerate=Fraction(int(match.group('num')), int(match.group('den'))))
+    return None
+
 def monitor_connected():
   with open(HDMI_SYSFS_NODE, 'r') as hdmi_status:
     status = hdmi_status.read()
@@ -93,9 +110,14 @@
   return Gst.FlowReturn.OK
 
 
-def run_pipeline(snapinfo):
-  src_caps = SRC_CAPS.format(width=SRC_WIDTH, height=SRC_HEIGHT, rate=SRC_RATE)
-  sink_caps = SINK_CAPS.format(width=SINK_WIDTH, height=SINK_HEIGHT)
+def run_pipeline(snapinfo, camera_mode):
+  fmt = parse_format(camera_mode)
+  if fmt:
+    src_caps = SRC_CAPS.format(width=fmt.width, height=fmt.height, rate=fmt.framerate)
+    sink_caps = SINK_CAPS.format(width=fmt.width, height=fmt.height)
+  else:
+    src_caps = SRC_CAPS.format(width=SRC_WIDTH, height=SRC_HEIGHT, rate=SRC_RATE)
+    sink_caps = SINK_CAPS.format(width=SINK_WIDTH, height=SINK_HEIGHT)
 
   if snapinfo.oneshot or not monitor_connected():
     screen_sink = FAKE_SINK
@@ -269,6 +291,9 @@
       default='jpg',
       choices=('jpg', 'bmp', 'png'),
       help='Format to save, default is JPEG')
+  parser.add_argument('--camera_mode',
+      help='WxH:N/D of the camera resolution and framerate',
+      default='2592x1944:15/1')
   args = parser.parse_args()
 
   try:
@@ -280,7 +305,7 @@
                   'check that your camera is connected')
     with open(AF_SYSFS_NODE, 'w+') as sysfs:
       snap = SnapHelper(sysfs, args.prefix, args.oneshot, args.suffix)
-      run_pipeline(snap)
+      run_pipeline(snap, args.camera_mode)
       snap.exit_keyboard_thread()
   except Exception as ex:
     print(ex)