def thread_function(thr_id, network_name, input_layer, output_layer, input_dimension, ip, port, disp_buf, src_type, src_name):
    if (src_type == 'Camera'):
        cam = cv2.VideoCapture(thr_id)
        if (not cam.isOpened()):
            log.error('Failed to open the UVC camera {}'.format(thr_id))
            return
        cam.set(cv2.CAP_PROP_FRAME_WIDTH, CAM_WIDTH)
        cam.set(cv2.CAP_PROP_FRAME_HEIGHT, CAM_HEIGHT)
        cam.set(cv2.CAP_PROP_FPS, CAM_FPS)
        cam.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*'MJPG'))
    elif (src_type == 'Video'):
        cam = cv2.VideoCapture(src_name)
    fps = 0
    inf_fps = 0
    dropped_fps = 0
    cam_start_time = time()
    channel = grpc.insecure_channel('{}:{}'.format(ip, port))
    stub = prediction_service_pb2_grpc.PredictionServiceStub(channel)
    request = predict_pb2.PredictRequest()
    request.model_spec.name = network_name
    global exit_ok
    while (exit_ok == False):
        (ret, frame) = cam.read()
        if (src_type == 'Video'):
            if (not ret):
                cam.set(cv2.CAP_PROP_POS_FRAMES, 0)
                continue
            else:
                sleep(((1000 / CAM_FPS) / 1000))
        fps = (fps + 1)
        if (((time() - cam_start_time) * 1000) >= 1000):
            log.warning('{}{} fps: {}, Inf fps: {}, dropped fps: {}'.format(src_type, thr_id, fps, inf_fps, dropped_fps))
            fps = 0
            inf_fps = 0
            dropped_fps = 0
            cam_start_time = time()
        image = cv2.resize(frame, (input_dimension, input_dimension))
        image = image.transpose(2, 0, 1).reshape(1, 3, input_dimension, input_dimension)
        image = image.astype('float32')
        inf_time = time()
        request.inputs[input_layer].CopyFrom(make_tensor_proto(image, shape=None))
        try:
            result = stub.Predict(request, 10.0)
        except Exception as e:
            log.error('Caught exception {}'.format(e))
            cam.release()
            return
        duration = (time() - inf_time)
        res = make_ndarray(result.outputs[output_layer])
        if (not res.any()):
            log.error('Thr{}: Predictions came back with wrong output layer name'.format(thr_id))
            dropped_fps = (dropped_fps + 1)
            disp_buf[thr_id] = frame
        else:
            log.debug('Predictions came back fine')
            inf_fps = (inf_fps + 1)
            disp_buf[thr_id] = parse_output(thr_id, res, frame)
    cam.release()
    log.warning('Exiting thread {}'.format(thr_id))
def thread_function(thr_id, network_name, input_layer, output_layer, input_dimension, ip, port, disp_buf, src_type, src_name):
    if (src_type == 'Camera'):
        cam = cv2.VideoCapture(thr_id)
        if (not cam.isOpened()):
            log.error('Failed to open the UVC camera {}'.format(thr_id))
            return
        cam.set(cv2.CAP_PROP_FRAME_WIDTH, CAM_WIDTH)
        cam.set(cv2.CAP_PROP_FRAME_HEIGHT, CAM_HEIGHT)
        cam.set(cv2.CAP_PROP_FPS, CAM_FPS)
        cam.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*'MJPG'))
    elif (src_type == 'Video'):
        cam = cv2.VideoCapture(src_name)
    fps = 0
    inf_fps = 0
    dropped_fps = 0
    cam_start_time = time()
    channel = grpc.insecure_channel('{}:{}'.format(ip, port))
    stub = prediction_service_pb2_grpc.PredictionServiceStub(channel)
    request = predict_pb2.PredictRequest()
    request.model_spec.name = network_name
    global exit_ok
    while (exit_ok == False):
        (ret, frame) = cam.read()
        if (src_type == 'Video'):
            if (not ret):
                cam.set(cv2.CAP_PROP_POS_FRAMES, 0)
                continue
            else:
                sleep(((1000 / CAM_FPS) / 1000))
        fps = (fps + 1)
        if (((time() - cam_start_time) * 1000) >= 1000):
            log.warning('{}{} fps: {}, Inf fps: {}, dropped fps: {}'.format(src_type, thr_id, fps, inf_fps, dropped_fps))
            fps = 0
            inf_fps = 0
            dropped_fps = 0
            cam_start_time = time()
        image = cv2.resize(frame, (input_dimension, input_dimension))
        image = image.transpose(2, 0, 1).reshape(1, 3, input_dimension, input_dimension)
        image = image.astype('float32')
        inf_time = time()
        request.inputs[input_layer].CopyFrom(make_tensor_proto(image, shape=None))
        try:
            result = stub.Predict(request, 10.0)
        except Exception as e:
            log.error('Caught exception {}'.format(e))
            cam.release()
            return
        duration = (time() - inf_time)
        res = make_ndarray(result.outputs[output_layer])
        if (not res.any()):
            log.error('Thr{}: Predictions came back with wrong output layer name'.format(thr_id))
            dropped_fps = (dropped_fps + 1)
            disp_buf[thr_id] = frame
        else:
            log.debug('Predictions came back fine')
            inf_fps = (inf_fps + 1)
            disp_buf[thr_id] = parse_output(thr_id, res, frame)
    cam.release()
    log.warning('Exiting thread {}'.format(thr_id))