#!/usr/bin/env python

import fcntl, sys, os
from v4l2 import *
from threading import Thread, Lock
import time
import numpy as np
import scipy.misc as misc
import cv2
import tools


class Streamer(Thread):

  _width = 640
  _height = 480
  _frameRate = 30
  _fmt = V4L2_PIX_FMT_YUYV
  _curFrame = None
  _running = False
  _mutex = Lock()

  def __init__(self, devName):
    Thread.__init__(self)
    if not os.path.exists(devName):
      print "Warning: device does not exist",devName
    self._device = open(devName, 'wr', 0)
    capability = v4l2_capability()
    print "Get capabilities result: %s" % (fcntl.ioctl(self._device, VIDIOC_QUERYCAP, capability))
    print "Capabilities: %s" % hex(capability.capabilities)
    print "V4l2 driver: %s" % capability.driver

    format = v4l2_format()
    format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT
    format.fmt.pix.pixelformat = self._fmt
    format.fmt.pix.width = self._width
    format.fmt.pix.height = self._height
    format.fmt.pix.field = V4L2_FIELD_NONE
    format.fmt.pix.bytesperline = self._width * 2
    format.fmt.pix.sizeimage = self._width * self._height * 2
    format.fmt.pix.colorspace = V4L2_COLORSPACE_JPEG

    print "Set format result: %s" % (fcntl.ioctl(self._device, VIDIOC_S_FMT, format))
    self._curFrame = np.zeros((self._height, self._width, 2), dtype=np.uint8)

  def updateFrame(self, frame):
    frame = misc.imresize(frame, (self._height, self._width))
    buff = tools.ConvertToYUYV(frame)
    self._mutex.acquire()
    self._curFrame = buff
    self._mutex.release()

  def start(self):
    print "Starting Streamer on %s" % self._device
    self._running = True
    Thread.start(self)

  def stop(self):
    self._running = False
    self.join()

  def run(self):
    while self._running:
      self._mutex.acquire()
      self._device.write(self._curFrame)
      self._mutex.release()
      time.sleep(1./self._frameRate)