def METHOD_NAME(input_frame, out_frame, out_batch, trg_fps, batch_size, image_shape, finish_flag):
    """Produces frames and batch of frames with constant framerate
       from the internal stream of frames"""
    trg_time_step = 1.0 / float(trg_fps)
    batch_shape = [batch_size] + image_shape
    frame_buffer = []
    while not finish_flag.value:
        start_time = time.perf_counter()
        with input_frame.get_lock():
            in_frame_buffer = np.frombuffer(input_frame.get_obj(), dtype=np.uint8)
            frame = np.copy(in_frame_buffer.reshape(image_shape))
        with out_frame.get_lock():
            out_frame_buffer = np.frombuffer(out_frame.get_obj(), dtype=np.uint8)
            np.copyto(out_frame_buffer.reshape(image_shape), frame)
        frame_buffer.append(frame)
        if len(frame_buffer) > batch_size:
            frame_buffer = frame_buffer[-batch_size:]
        if len(frame_buffer) == batch_size:
            with out_batch.get_lock():
                out_batch_buffer = np.frombuffer(out_batch.get_obj(), dtype=np.uint8)
                np.copyto(out_batch_buffer.reshape(batch_shape), frame_buffer)
        end_time = time.perf_counter()
        elapsed_time = end_time - start_time
        rest_time = trg_time_step - elapsed_time
        if rest_time > 0.0:
            time.sleep(rest_time)