def get_frame_ts_table(video): vr = VideoReader(video, ctx=cpu(0)) return [int(vr.get_frame_timestamp(i)[1] * 1000) for i in range(len(vr))]
def run_data_worker(idx, args, data_queue, safe_gap=10000, nframes=10): assert args.interval * nframes < safe_gap videos = [i for i in os.listdir(args.data_dir) if i.endswith('.mp4')] videos = [os.path.join(args.data_dir, i) for i in videos] sub_videos = [] for i, v in enumerate(videos): if i % args.num_data_threads == idx: sub_videos.append(v) for video in sub_videos: txt = glob.glob(video + '_*.txt')[0] annos = read_anno_txt(txt) vr = VideoReader(video, ctx=cpu(idx)) vid = os.path.basename(video) frame_ts_table = [ int(vr.get_frame_timestamp(i)[1] * 1000) for i in range(len(vr)) ] frame_ids = [] t = fid = aid = 0 # three trace pointers # O(N+M), N=len(intervals), M=len(vr) while aid < len(annos) and \ t < max(args.interval // 2, annos[aid]['Time'] - safe_gap): # Extract negative example # NOTE: for simplicity, this implementation the segment # from last positive anno to the video end while fid < len(vr) and frame_ts_table[fid] < t: fid += 1 if len(frame_ids) < nframes: frame_ids.append(fid) else: frame_ids.pop(0) frame_ids.append(fid) if len(frame_ids) == nframes: frames = [ cv2.resize(img[:, :, ::-1], (640, 360)) for img in list(vr.get_batch(frame_ids).asnumpy()) ] data_queue.put((frames, 0, vid, t)) t += args.interval if t >= annos[aid]['Time'] - safe_gap: # Extract positive example frame_ids.clear() for i in range(nframes - 1, -1, -1): # i = 9, 8, ..., 0 when nframes = 10 t = annos[aid]['Time'] - args.interval * i while frame_ts_table[fid] < t: fid += 1 frame_ids.append(fid) frames = [ cv2.resize(img[:, :, ::-1], (640, 360)) for img in list(vr.get_batch(frame_ids).asnumpy()) ] data_queue.put((frames, 1, vid, t)) frame_ids.clear() t = annos[aid]['Time'] + safe_gap while aid < len(annos) and t >= annos[aid]['Time'] - safe_gap: aid += 1
def video_legal(video_path, remove_illegal=True): # 检查切出来的视频是否可读 try: cv_wrong = False cap = cv2.VideoCapture(str(video_path)) flag, f = cap.read() if not flag: cv_wrong = True cap.release() if cv_wrong: # opencv检测出视频不正常,删掉 print("opencv remove", video_path, flush=True) if remove_illegal: os.remove(str(video_path)) return False vr = VideoReader(str(video_path)) last_timestamp = [-100, -100] video_wrong = False if (len(vr) > 1 and len(vr.get_key_indices()) > 1) else True if video_wrong: print("len vr {} and len(vr.get_key_indices()) {}".format( len(vr), len(vr.get_key_indices())), video_path, flush=True) if remove_illegal: os.remove(str(video_path)) return False for i in range(len(vr)): # 解决卡住 tmp = vr.get_frame_timestamp(i) if last_timestamp[0] == tmp[0] and last_timestamp[1] <= tmp[1]: print("last_timestamp", i, video_path, last_timestamp[0], tmp[0], last_timestamp[1], tmp[1], flush=True) video_wrong = True break last_timestamp = tmp if video_wrong: print("timestamp error", video_path, flush=True) if remove_illegal: os.remove(str(video_path)) return False for i in range(len(vr)): # 解决decord._ffi.base.DECORDError: [18:09:55] /io/decord/src/video/ffmpeg -loglevel quiet/threaded_decoder.cc:288: [18:08:29] /io/decord/src/video/ffmpeg -loglevel quiet/threaded_decoder.cc:216: Check failed: avcodec_send_packet(dec_ctx_.get(), pkt.get()) >= 0 (-1094995529 vs. 0) Thread worker: Error sending packet. try: _t = vr[i] except Exception as e: print("DECORDError", e, i, video_path, flush=True) if remove_illegal: os.remove(str(video_path)) return False except: print("remove video format exception", video_path, flush=True) if remove_illegal: os.remove(str(video_path)) return False return True