Home | History | Annotate | Download | only in functional
      1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 #
      5 # This module is handler for incoming data to the pywebsocket standalone server
      6 # (source is in http://code.google.com/p/pywebsocket/source/browse/trunk/src/).
      7 # It follows the conventions of the pywebsocket server and in our case receives
      8 # and stores incoming frames to disk.
      9 
     10 import Queue
     11 import os
     12 import sys
     13 import threading
     14 
     15 _NUMBER_OF_WRITER_THREADS = 10
     16 
     17 _HOME_ENV_NAME = 'HOMEPATH' if 'win32' == sys.platform else 'HOME'
     18 _WORKING_DIR = os.path.join(os.environ[_HOME_ENV_NAME], 'webrtc_video_quality')
     19 
     20 # I couldn't think of other way to handle this but through a global variable
     21 g_frame_number_counter = 0
     22 g_frames_queue = Queue.Queue()
     23 
     24 
     25 def web_socket_do_extra_handshake(request):
     26   pass  # Always accept.
     27 
     28 
     29 def web_socket_transfer_data(request):
     30   while True:
     31     data = request.ws_stream.receive_message()
     32     if data is None:
     33       return
     34 
     35     # We assume we will receive only frames, i.e. binary data
     36     global g_frame_number_counter
     37     frame_number = str(g_frame_number_counter)
     38     g_frame_number_counter += 1
     39     g_frames_queue.put((frame_number, data))
     40 
     41 
     42 class FrameWriterThread(threading.Thread):
     43   """Writes received frames to disk.
     44 
     45   The frames are named in the format frame_xxxx, where xxxx is the 0-padded
     46   frame number. The frames and their numbers are obtained from a synchronized
     47   queue. The frames are written in the directory specified by _WORKING_DIR.
     48   """
     49   def __init__(self, queue):
     50     threading.Thread.__init__(self)
     51     self._queue = queue
     52 
     53   def run(self):
     54     while True:
     55       frame_number, frame_data = self._queue.get()
     56       file_name = 'frame_' + frame_number.zfill(4)
     57       file_name = os.path.join(_WORKING_DIR, file_name)
     58       frame = open(file_name, "wb")
     59       frame.write(frame_data)
     60       frame.close()
     61       self._queue.task_done()
     62 
     63 
     64 def start_threads():
     65   for i in range(_NUMBER_OF_WRITER_THREADS):
     66     t = FrameWriterThread(g_frames_queue)
     67     t.setDaemon(True)
     68     t.start()
     69   g_frames_queue.join()
     70 
     71 
     72 # This handler's entire code is imported as 'it is' and then incorporated in the
     73 # code of the standalone pywebsocket server. If we put this start_threads() call
     74 # inside a if __name__ == '__main__' clause it wouldn't run this code at all
     75 # (tested).
     76 start_threads()
     77