|
@@ -1,145 +1,136 @@
|
|
|
#!/usr/bin/python3
|
|
#!/usr/bin/python3
|
|
|
|
|
+import time
|
|
|
|
|
+import threading
|
|
|
|
|
+import os
|
|
|
|
|
+import stat
|
|
|
import sys
|
|
import sys
|
|
|
import gi
|
|
import gi
|
|
|
gi.require_version('Gst', '1.0')
|
|
gi.require_version('Gst', '1.0')
|
|
|
gi.require_version('GstNet', '1.0')
|
|
gi.require_version('GstNet', '1.0')
|
|
|
from gi.repository import Gst, GstNet
|
|
from gi.repository import Gst, GstNet
|
|
|
-import time
|
|
|
|
|
-import threading
|
|
|
|
|
-import os
|
|
|
|
|
-import stat
|
|
|
|
|
-
|
|
|
|
|
-WIDTH = 1024
|
|
|
|
|
-HEIGHT = 576
|
|
|
|
|
|
|
|
|
|
-WIDTH = 1280
|
|
|
|
|
|
|
+WIDTH = 1280
|
|
|
HEIGHT = 720
|
|
HEIGHT = 720
|
|
|
|
|
|
|
|
-SCREEN_WIDTH = 1280
|
|
|
|
|
-SCREEN_HEIGHT = 720
|
|
|
|
|
-
|
|
|
|
|
-SCREEN_WIDTH = 1920
|
|
|
|
|
-SCREEN_HEIGHT = 1080
|
|
|
|
|
-
|
|
|
|
|
SCREEN_WIDTH = 800
|
|
SCREEN_WIDTH = 800
|
|
|
SCREEN_HEIGHT = 600
|
|
SCREEN_HEIGHT = 600
|
|
|
|
|
|
|
|
def bus_call(bus, msg, *args):
|
|
def bus_call(bus, msg, *args):
|
|
|
- if msg.type == Gst.MessageType.EOS:
|
|
|
|
|
- print("End-of-stream")
|
|
|
|
|
- loop.quit()
|
|
|
|
|
- return
|
|
|
|
|
- elif msg.type == Gst.MessageType.ERROR:
|
|
|
|
|
- print("GST ERROR", msg.parse_error())
|
|
|
|
|
- loop.quit()
|
|
|
|
|
- return
|
|
|
|
|
- return True
|
|
|
|
|
|
|
+ if msg.type == Gst.MessageType.EOS:
|
|
|
|
|
+ print("End-of-stream")
|
|
|
|
|
+ loop.quit()
|
|
|
|
|
+ return
|
|
|
|
|
+ elif msg.type == Gst.MessageType.ERROR:
|
|
|
|
|
+ print("GST ERROR", msg.parse_error())
|
|
|
|
|
+ loop.quit()
|
|
|
|
|
+ return
|
|
|
|
|
+ return True
|
|
|
|
|
|
|
|
zoom = 1
|
|
zoom = 1
|
|
|
def quit():
|
|
def quit():
|
|
|
- pipeline.send_event(Gst.Event.new_eos())
|
|
|
|
|
|
|
+ pipeline.send_event(Gst.Event.new_eos())
|
|
|
|
|
|
|
|
def set_preview(val):
|
|
def set_preview(val):
|
|
|
- if val == 0:
|
|
|
|
|
- videosrc.set_property("preview-x", SCREEN_WIDTH)
|
|
|
|
|
- videosrc.set_property("preview-y", SCREEN_HEIGHT)
|
|
|
|
|
- else:
|
|
|
|
|
- videosrc.set_property("preview-x", 0)
|
|
|
|
|
- videosrc.set_property("preview-y", 0)
|
|
|
|
|
|
|
+ if val == 0:
|
|
|
|
|
+ videosrc.set_property("preview-x", SCREEN_WIDTH)
|
|
|
|
|
+ videosrc.set_property("preview-y", SCREEN_HEIGHT)
|
|
|
|
|
+ else:
|
|
|
|
|
+ videosrc.set_property("preview-x", 0)
|
|
|
|
|
+ videosrc.set_property("preview-y", 0)
|
|
|
|
|
|
|
|
def set_zoom(target):
|
|
def set_zoom(target):
|
|
|
- global zoom
|
|
|
|
|
- if target < zoom:
|
|
|
|
|
- direction = -1
|
|
|
|
|
- else:
|
|
|
|
|
- direction = 1
|
|
|
|
|
-
|
|
|
|
|
- target=min(target, 1)
|
|
|
|
|
- target=max(target, 0.40)
|
|
|
|
|
-
|
|
|
|
|
- while abs(target-zoom) > 0.01: #fuck IEEE floats
|
|
|
|
|
- zoom = zoom + direction*0.015
|
|
|
|
|
- zoom = min(zoom, 1)
|
|
|
|
|
- zoom = max(zoom, 0.4)
|
|
|
|
|
- videosrc.set_property("roi-x", (1-zoom)/2)
|
|
|
|
|
- videosrc.set_property("roi-y", (1-zoom)/2)
|
|
|
|
|
- videosrc.set_property("roi-w", zoom)
|
|
|
|
|
- videosrc.set_property("roi-h", zoom)
|
|
|
|
|
- time.sleep(0.03)
|
|
|
|
|
|
|
+ global zoom
|
|
|
|
|
+ if target < zoom:
|
|
|
|
|
+ direction = -1
|
|
|
|
|
+ else:
|
|
|
|
|
+ direction = 1
|
|
|
|
|
+
|
|
|
|
|
+ target=min(target, 1)
|
|
|
|
|
+ target=max(target, 0.40)
|
|
|
|
|
+
|
|
|
|
|
+ while abs(target-zoom) > 0.01: #fuck IEEE floats
|
|
|
|
|
+ zoom = zoom + direction*0.015
|
|
|
|
|
+ zoom = min(zoom, 1)
|
|
|
|
|
+ zoom = max(zoom, 0.4)
|
|
|
|
|
+ videosrc.set_property("roi-x", (1-zoom)/2)
|
|
|
|
|
+ videosrc.set_property("roi-y", (1-zoom)/2)
|
|
|
|
|
+ videosrc.set_property("roi-w", zoom)
|
|
|
|
|
+ videosrc.set_property("roi-h", zoom)
|
|
|
|
|
+ time.sleep(0.03)
|
|
|
|
|
|
|
|
|
|
|
|
|
def control():
|
|
def control():
|
|
|
- FIFO="/tmp/picamfifo"
|
|
|
|
|
- if os.path.exists(FIFO):
|
|
|
|
|
- if stat.S_ISFIFO(os.stat(FIFO).st_mode):
|
|
|
|
|
- pass
|
|
|
|
|
- else:
|
|
|
|
|
- os.remove(FIFO)
|
|
|
|
|
- os.mkfifo(FIFO)
|
|
|
|
|
- else:
|
|
|
|
|
- os.mkfifo(FIFO)
|
|
|
|
|
-
|
|
|
|
|
- while True:
|
|
|
|
|
- with open(FIFO) as fifo:
|
|
|
|
|
- line=fifo.read().strip()
|
|
|
|
|
- print("Got: ", line)
|
|
|
|
|
- if "=" not in line:
|
|
|
|
|
- print("Invalid line.")
|
|
|
|
|
- continue
|
|
|
|
|
- key = line.split("=")[0]
|
|
|
|
|
- val = line.split("=")[1]
|
|
|
|
|
-
|
|
|
|
|
- if key == "preview":
|
|
|
|
|
- set_preview(int(val))
|
|
|
|
|
-
|
|
|
|
|
- if key == "zoom":
|
|
|
|
|
- set_zoom(float(val))
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
|
|
+ FIFO="/tmp/picamfifo"
|
|
|
|
|
+ if os.path.exists(FIFO):
|
|
|
|
|
+ if stat.S_ISFIFO(os.stat(FIFO).st_mode):
|
|
|
|
|
+ pass
|
|
|
|
|
+ else:
|
|
|
|
|
+ os.remove(FIFO)
|
|
|
|
|
+ os.mkfifo(FIFO)
|
|
|
|
|
+ else:
|
|
|
|
|
+ os.mkfifo(FIFO)
|
|
|
|
|
+
|
|
|
|
|
+ while True:
|
|
|
|
|
+ with open(FIFO) as fifo:
|
|
|
|
|
+ line=fifo.read().strip()
|
|
|
|
|
+ print("Got: ", line)
|
|
|
|
|
+ if "=" not in line:
|
|
|
|
|
+ print("Invalid line.")
|
|
|
|
|
+ continue
|
|
|
|
|
+ key = line.split("=")[0]
|
|
|
|
|
+ val = line.split("=")[1]
|
|
|
|
|
+
|
|
|
|
|
+ if key == "preview":
|
|
|
|
|
+ set_preview(int(val))
|
|
|
|
|
+
|
|
|
|
|
+ if key == "zoom":
|
|
|
|
|
+ set_zoom(float(val))
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
if __name__ == "__main__":
|
|
if __name__ == "__main__":
|
|
|
- if 'LD_LIBRARY_PATH' not in os.environ:
|
|
|
|
|
- os.environ['LD_LIBRARY_PATH'] = '/usr/local/lib'
|
|
|
|
|
- os.execv(sys.argv[0], sys.argv)
|
|
|
|
|
- # initialization
|
|
|
|
|
- Gst.init(None)
|
|
|
|
|
-
|
|
|
|
|
- videocodec = "video/x-h264, width=%d, height=%d, framerate=25/1, profile=high ! h264parse" % (WIDTH, HEIGHT)
|
|
|
|
|
- p = "rpicamsrc sensor-mode=4 bitrate=0 quantisation-parameter=12 do-timestamp=true keyframe-interval=5 name=src ! "+videocodec+" ! matroskamux streamable=true ! tcpserversink host=0.0.0.0 port=5000 sync-method=next-keyframe blocksize=16384"
|
|
|
|
|
- print(p)
|
|
|
|
|
|
|
+ if 'LD_LIBRARY_PATH' not in os.environ:
|
|
|
|
|
+ os.environ['LD_LIBRARY_PATH'] = '/usr/local/lib'
|
|
|
|
|
+ os.execv(sys.argv[0], sys.argv)
|
|
|
|
|
+ # initialization
|
|
|
|
|
+ Gst.init(None)
|
|
|
|
|
+
|
|
|
|
|
+ videocodec = "video/x-h264, width=%d, height=%d, framerate=25/1, profile=high ! h264parse" % (WIDTH, HEIGHT)
|
|
|
|
|
+ p = "rpicamsrc sensor-mode=4 bitrate=0 quantisation-parameter=12 do-timestamp=true keyframe-interval=5 name=src ! "+videocodec+" ! matroskamux streamable=true ! tcpserversink host=0.0.0.0 port=5000 sync-method=next-keyframe blocksize=16384"
|
|
|
|
|
+ print(p)
|
|
|
#
|
|
#
|
|
|
- pipeline = Gst.parse_launch (p)
|
|
|
|
|
- if pipeline == None:
|
|
|
|
|
- print ("Failed to create pipeline")
|
|
|
|
|
- sys.exit(0)
|
|
|
|
|
-
|
|
|
|
|
- clock = GstNet.NetClientClock.new('CamVoctoClock', '192.168.2.123', 9998, 0)
|
|
|
|
|
- #print("Waiting for clock sync")
|
|
|
|
|
- #clock.wait_for_sync(Gst.CLOCK_TIME_NONE)
|
|
|
|
|
- #clock.do_wait(Gst.CLOCK_TIME_NONE)
|
|
|
|
|
- #print("Clock synced")
|
|
|
|
|
- pipeline.set_start_time(Gst.CLOCK_TIME_NONE)
|
|
|
|
|
- if clock is not None:
|
|
|
|
|
- pass
|
|
|
|
|
- #pipeline.use_clock(clock)
|
|
|
|
|
-
|
|
|
|
|
- videosrc = pipeline.get_by_name ("src")
|
|
|
|
|
- videosrc.set_property("preview", 1)
|
|
|
|
|
- videosrc.set_property("preview-w", SCREEN_WIDTH)
|
|
|
|
|
- videosrc.set_property("preview-h", SCREEN_HEIGHT)
|
|
|
|
|
- videosrc.set_property("fullscreen", False)
|
|
|
|
|
- #videosrc.set_property("bitrate", 14000000)
|
|
|
|
|
- # videosrc.set_property("bitrate", 25000000)
|
|
|
|
|
- videosrc.set_property("rotation", 180)
|
|
|
|
|
- set_preview(0)
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- # run
|
|
|
|
|
- pipeline.set_state(Gst.State.PLAYING)
|
|
|
|
|
- t = threading.Thread(target=control, daemon=True)
|
|
|
|
|
- t.start()
|
|
|
|
|
- while True:
|
|
|
|
|
- time.sleep(10000)
|
|
|
|
|
-
|
|
|
|
|
- # cleanup
|
|
|
|
|
- pipeline.set_state(Gst.State.NULL)
|
|
|
|
|
|
|
+ pipeline = Gst.parse_launch (p)
|
|
|
|
|
+ if pipeline == None:
|
|
|
|
|
+ print ("Failed to create pipeline")
|
|
|
|
|
+ sys.exit(0)
|
|
|
|
|
+
|
|
|
|
|
+ clock = GstNet.NetClientClock.new('CamVoctoClock', '192.168.2.123', 9998, 0)
|
|
|
|
|
+ #print("Waiting for clock sync")
|
|
|
|
|
+ #clock.wait_for_sync(Gst.CLOCK_TIME_NONE)
|
|
|
|
|
+ #clock.do_wait(Gst.CLOCK_TIME_NONE)
|
|
|
|
|
+ #print("Clock synced")
|
|
|
|
|
+ pipeline.set_start_time(Gst.CLOCK_TIME_NONE)
|
|
|
|
|
+ if clock is not None:
|
|
|
|
|
+ pass
|
|
|
|
|
+ #pipeline.use_clock(clock)
|
|
|
|
|
+
|
|
|
|
|
+ videosrc = pipeline.get_by_name ("src")
|
|
|
|
|
+ videosrc.set_property("preview", 1)
|
|
|
|
|
+ videosrc.set_property("preview-w", SCREEN_WIDTH)
|
|
|
|
|
+ videosrc.set_property("preview-h", SCREEN_HEIGHT)
|
|
|
|
|
+ videosrc.set_property("fullscreen", False)
|
|
|
|
|
+ #videosrc.set_property("bitrate", 14000000)
|
|
|
|
|
+ # videosrc.set_property("bitrate", 25000000)
|
|
|
|
|
+ videosrc.set_property("rotation", 180)
|
|
|
|
|
+ set_preview(0)
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ # run
|
|
|
|
|
+ pipeline.set_state(Gst.State.PLAYING)
|
|
|
|
|
+ t = threading.Thread(target=control, daemon=True)
|
|
|
|
|
+ t.start()
|
|
|
|
|
+ while True:
|
|
|
|
|
+ time.sleep(10000)
|
|
|
|
|
+
|
|
|
|
|
+ # cleanup
|
|
|
|
|
+ pipeline.set_state(Gst.State.NULL)
|
|
|
|
|
|