def send_detection_data(self, image_width, image_height, image, detection_result): """ Send detection data and return status """ if self._send_buffer.full() is True: log_error("Send detection data failed for buffer is full") return False image_data = None if isinstance(image, AclImage): image_data = DataBuf(image.data(), image.size).copy_to_local() elif isinstance(image, np.ndarray): image_data = image else: log_error("Invalid data to send") return False request_msg = pm.image_frame_request(image_width, image_height, image_data.tobytes(), detection_result) self.send_message(request_msg) self._send_buffer.put(image_data) self._release_send_success_data() return True
def create_threads(detector): config = configparser.ConfigParser() config.read(FACE_DETEC_CONF) video_decoders = [] for item in config['videostream']: preprocesser = Preprocess(config['videostream'][item], len(video_decoders), MODEL_WIDTH, MODEL_HEIGHT) video_decoders.append(preprocesser) rtsp_num = len(video_decoders) if rtsp_num == 0: log_error("No video stream name or addr configuration in ", FACE_DETEC_CONF) return None, None postprocessor = Postprocess(detector) display_channel = int(config['display']['channel']) if (display_channel is None) or (display_channel >= rtsp_num): log_info("No video to display, display configuration: ", config['display']['channel']) else: video_decoders[display_channel].set_display(True) ret = postprocessor.create_presenter_channel(FACE_DETEC_CONF) if ret == False: log_error("Create presenter channel failed") return None, None return video_decoders, postprocessor
def main(): #初始化acl acl_resource = AclResource() acl_resource.init() #创建一个检测网络实例,当前使用vgg_ssd网络.当更换检测网络时,在此实例化新的网络 detector = VggSsd(acl_resource, MODEL_PATH, MODEL_WIDTH, MODEL_HEIGHT) video_decoders, postprocessor = create_threads(detector) if video_decoders is None: log_error("Please check the configuration in %s is valid" % (FACE_DETEC_CONF)) return while True: all_process_fin = True for decoder in video_decoders: ret, data = decoder.get_data() if ret == False: log_info("Read data ret ", ret) continue if data: detect_results = detector.execute(data) postprocessor.process(data, detect_results) all_process_fin = False if all_process_fin: log_info("all video decoder finish") break postprocessor.exit() log_info("sample execute end")
def __init__(self, image, width=0, height=0, size=0, memory_type=const.MEMORY_NORMAL): """Create AclImage instance Args: image: image data, binary, numpy array or file path width: image width. if image is jpeg or png file, this arg is not nesscessary height: image height. if image is jpeg or png file, this arg is not nesscessary size: image data size. if image is file path, this arg is not nesscessary memory_type: memory type of image data. if image is file path, this arg is not nesscessary """ self._data = None self._memory_type = memory_type self.width = 0 self.height = 0 self.size = 0 self._encode_format = const.ENCODE_FORMAT_UNKNOW self._load_ok = True if isinstance(image, str): self._instance_by_image_file(image, width, height) elif isinstance(image, int): self._instance_by_buffer(image, width, height, size) elif isinstance(image, np.ndarray): self._instance_by_nparray(image, width, height) else: acl_log.log_error("Create instance failed for " "unknow image data type")
def read(self, no_wait=False): """Read decoded frame no_wait: Get image without wait. If set this arg True, and return image is None, should call is_finished() method to confirm decode finish or failed Returns: 1. const.SUCCESS, not None: get image success 2. const.SUCCESS, None: all frames decoded and be token off 3. const.FAILED, None: Has frame not decoded, but no image decoded, it means decode video failed """ image = None ret = const.SUCCESS # received eos frame and all received frame decode complete if no_wait or self.is_finished(): try: image = self._frame_queue.get_nowait() except: acl_log.log_info("No decode frame in queue anymore") else: try: image = self._frame_queue.get(timeout=READ_TIMEOUT) except: ret = const.FAILED acl_log.log_error("Read channel id %d frame timeout, " "receive frame %d, decoded %d" % (self._channel_id, self._decode_cnt, self._decode_complete_cnt)) return ret, image
def recv_msg(self): """Receive message from presenter server Returns: msg_name: received message name msg_body: received message data """ # Step1: read msg head msg_total_len, msg_name_len = self._read_msg_head(5) if msg_total_len is None: log_error("msg total len is None.") return None, None # Step2: read msg name ret, msg_name = self._read_msg_name(msg_name_len) if not ret: return None, None # Step3: read msg body msg_body_len = msg_total_len - 5 - msg_name_len if msg_body_len < 0: log_error("msg total len is 0") return None, None ret, msg_body = self._read_msg_body(msg_body_len) if not ret: return None, None return msg_name, msg_body
def execute(self, input_list): """ inference input data Args: input_list: input data list, support AclImage, numpy array and {'data': ,'size':} dict returns: inference result data, which is a numpy array list, each corresponse to a model output """ ret = self._gen_input_dataset(input_list) if ret == const.FAILED: log_error("Gen model input dataset failed") return None ret = acl.mdl.execute(self._model_id, self._input_dataset, self._output_dataset) if ret != const.ACL_ERROR_NONE: log_error("Execute model failed for acl.mdl.execute error ", ret) return None self._release_dataset(self._input_dataset) self._input_dataset = None return self._output_dataset_to_numpy()
def jpegd(self, image): """ jepg image to yuv image """ # Create conversion output image desc output_desc, out_buffer = self._gen_jpegd_out_pic_desc(image) ret = acl.media.dvpp_jpeg_decode_async(self._dvpp_channel_desc, image.data(), image.size, output_desc, self._stream) if ret != constants.ACL_ERROR_NONE: log_error("dvpp_jpeg_decode_async failed ret={}".format(ret)) return None ret = acl.rt.synchronize_stream(self._stream) if ret != constants.ACL_ERROR_NONE: log_error("dvpp_jpeg_decode_async failed ret={}".format(ret)) return None # Return the decoded AclImage instance stride_width = utils.align_up128(image.width) stride_height = utils.align_up16(image.height) stride_size = utils.yuv420sp_size(stride_width, stride_height) return AclImage(out_buffer, stride_width, stride_height, stride_size, constants.MEMORY_DVPP)
def send_msg(self, data): try: self._sock_client.sendall(data) except Exception as e: log_error("Send msg failed") return 1 return 0
def _get_param(self): container = av.open(self._stream_name) stream = [s for s in container.streams if s.type == 'video'] if len(stream) == 0: # The stream is not video acl_log.log_error("%s has no video stream" % (self._stream_name)) return const.FAILED ret, profile = self._get_profile(stream) if ret: acl_log.log_error("%s is not annex-b format, decode failed" % (self._stream_name)) return const.FAILED video_context = container.streams.video[0].codec_context codec_id_name = video_context.name ret, self._entype = self._get_entype(codec_id_name, profile) if ret: return const.FAILED self._width = video_context.width self._height = video_context.height acl_log.log_info("Get %s infomation: width %d, height %d, profile %d, " "codec %s, entype %d" % (self._stream_name, self._width, self._height, profile, codec_id_name, self._entype)) container.close() return const.SUCCESS
def _pyav_vdec(self): frame = 0 video = av.open(self._stream_name) stream = [s for s in video.streams if s.type == 'video'] acl_log.log_info("Start decode %s frames" % (self._stream_name)) for packet in video.demux([stream[0]]): # Get frame data from packet and copy to dvpp frame_data, data_size = self._prepare_frame_data(packet) if data_size == 0: # Last packet size is 0, no frame to decode anymore break if self._vdec.process(frame_data, data_size, [self._channel_id, frame]): acl_log.log_error("Dvpp vdec deocde frame %d failed, " "stop decode" % (frame)) self._status = DECODE_STATUS_ERROR break frame += 1 # The status chang to stop when app stop decode if self._status != DECODE_STATUS_RUNNING: acl_log.log_info("Decode status change to %d, stop decode" % (self._status)) break
def __del__(self): self.open_status.value = STATUS_EXITING log_info("Presenter channel close...") self._send_heart_beat_message() if STATUS_OK == self._wait_open_status(STATUS_EXITTED): log_info("Presenter channel closed") else: log_error("Presenter channel close failed for presenter agent no response")
def create_presenter_channel(self, config_file): self._display = True self._channel = presenter_channel.open_channel(config_file) if self._channel == None: log_error("Open presenter channel failed") return False return True
def _open(self): ret = libatlas.OpenCameraEx(self._id, self._fps, self._width, self._height) if (ret != CAMERA_OK): log_error("Open camera %d failed ,ret = %d" % (self._id, ret)) return CAMERA_ERROR self._status = CAMERA_OPENED return CAMERA_OK
def _gen_resize_out_pic_desc(self, resize_width, resize_height, output_size): out_buffer, ret = acl.media.dvpp_malloc(output_size) if ret != constants.ACL_ERROR_NONE: log_error("Dvpp malloc failed, error: ", ret) return None pic_desc = self._gen_output_pic_desc(resize_width, resize_height, out_buffer, output_size) return pic_desc, out_buffer
def open_channel(config_file): server_ip, port, channel_name, content_type = get_channel_config( config_file) channel = PresenterChannel(server_ip, port, channel_name, content_type) ret = channel.startup() if ret: log_error("ERROR:Open channel failed") return None return channel
def _release_databuffer(self, data_buffer, free_memory=False): if free_memory: data_addr = acl.get_data_buffer_addr(data_buffer) if data_addr: acl.rt.free(data_addr) ret = acl.destroy_data_buffer(data_buffer) if ret != const.ACL_ERROR_NONE: log_error("Destroy data buffer error ", ret)
def copy_to_dvpp(self): """Copy image data to dvpp""" device_ptr = utils.copy_data_to_dvpp(self.data(), self.size, self._run_mode) if device_ptr is None: acl_log.log_error("Copy image to dvpp failed") return None return AclImage(device_ptr, self.width, self.height, self.size, const.MEMORY_DVPP)
def _keep_alive(self): msg = pm.heartbeat_message() while True: if self._closed: log_error("Heard beat thread exit") break self.socket.send_msg(msg) time.sleep(2)
def read(self): """Read frame from camera""" frame_data = CameraOutputC() ret = libatlas.ReadCameraFrame(self._id, byref(frame_data)) if (ret != CAMERA_OK): log_error("Read camera %d failed" % (self._id)) return None return AclImage(addressof(frame_data.data.contents), self._width, self._height, self._size, const.MEMORY_DVPP)
def _create_input_pic_stream_desc(self, input_data, input_size): stream_desc = acl.media.dvpp_create_stream_desc() if stream_desc is None: acl_log.log_error("Create dvpp vdec input pic stream desc failed") return None acl.media.dvpp_set_stream_desc_size(stream_desc, input_size) acl.media.dvpp_set_stream_desc_data(stream_desc, input_data) return stream_desc
def _get_jpegd_memory_size(self, image): if image.is_local(): size, ret = acl.media.dvpp_jpeg_predict_dec_size( \ image.data(), image.size, constants.PIXEL_FORMAT_YUV_SEMIPLANAR_420) if ret != constants.ACL_ERROR_NONE: log_error("Predict jpeg decode size failed, return ", ret) return False, 0 return True, size else: return True, int( utils.yuv420sp_size(image.width, image.height) * 3)
def _process_detect_data(self, detect_results, frame_data): results_list = self._detector.post_process(detect_results, frame_data) ret = True if frame_data.display and frame_data.jpg_image: ret = self._channel.send_detection_data(frame_data.frame_width, frame_data.frame_height, frame_data.jpg_image, results_list) if ret == False: log_error("Send data to presenter server failed") return ret
def _get_image_format_by_suffix(self, filename): suffix = os.path.splitext(filename)[-1].strip().lower() if (suffix == ".jpg") or (suffix == ".jpeg"): image_format = ENCODE_FORMAT_JPEG elif suffix == ".png": image_format = ENCODE_FORMAT_PNG elif suffix == ".yuv": image_format = ENCODE_FORMAT_YUV420_SP else: log_error("Unsupport image format: ", suffix) image_format = ENCODE_FORMAT_UNKNOW return image_format
def _read_msg_head(self, read_len): ret, msg_head = self._read_socket(read_len) if not ret: log_error("socket receive msg head null") return None, None # in Struct(), 'I' is unsigned int, 'B' is unsigned char msg_head_data = struct.Struct('IB') (msg_total_len, msg_name_len) = msg_head_data.unpack(msg_head) msg_total_len = socket.ntohl(msg_total_len) return msg_total_len, msg_name_len
def _get_profile(self, stream): # Annex-b format h264 extradata is start with 0x000001 or 0x00000001 extradata = np.frombuffer(stream[0].codec_context.extradata, np.ubyte) if (extradata[0:3] == [0, 0, 1]).all(): profile_id = extradata[4] elif (extradata[0:4] == [0, 0, 0, 1]).all(): profile_id = extradata[5] else: acl_log.log_error("The stream %s is not annex-b h264, " "can not decode it" % (self._stream_name)) return const.FAILED, None return const.SUCCESS, profile_id
def _release_dataset(self, dataset, free_memory=False): if not dataset: return num = acl.mdl.get_dataset_num_buffers(dataset) for i in range(num): data_buf = acl.mdl.get_dataset_buffer(dataset, i) if data_buf: self._release_databuffer(data_buf, free_memory) ret = acl.mdl.destroy_dataset(dataset) if ret != const.ACL_ERROR_NONE: log_error("Destroy data buffer error ", ret)
def _read_msg_name(self, msg_name_len): ret, msg_name = self._read_socket(msg_name_len) if not ret: log_error("Socket receive msg but name is null") return False, None try: msg_name = msg_name.decode("utf-8") except: log_error("Msg name decode to utf-8 error") return False, None return True, msg_name
def _get_pic_desc_data(self, pic_desc, user_data): pic_data = acl.media.dvpp_get_pic_desc_data(pic_desc) pic_data_size = acl.media.dvpp_get_pic_desc_size(pic_desc) ret_code = acl.media.dvpp_get_pic_desc_ret_code(pic_desc) if ret_code: channel_id, frame_id = user_data acl_log.log_error("Decode channel %d frame %d failed, error %d" % (channel_id, frame_id, ret_code)) acl.media.dvpp_free(pic_data) else: image = AclImage(pic_data, self._width, self._height, pic_data_size, const.MEMORY_DVPP) self._frame_queue.put(image) acl.media.dvpp_destroy_pic_desc(pic_desc)
def send_msg(self, data): """Send message to presenter server Args: data: message data Returns: 0 send success 1 send failed """ try: self._sock_client.sendall(data) except: log_error("Send msg failed") return 1 return 0