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