void Unix_EntropySource::poll(Entropy_Accumulator& accum) { // refuse to run setuid or setgid, or as root if((getuid() != geteuid()) || (getgid() != getegid()) || (geteuid() == 0)) return; std::lock_guard<std::mutex> lock(m_mutex); if(m_sources.empty()) { auto sources = get_default_sources(); for(auto src : sources) { const std::string path = find_full_path_if_exists(m_trusted_paths, src[0]); if(path != "") { src[0] = path; m_sources.push_back(src); } } } if(m_sources.empty()) return; // still empty, really nothing to try const size_t MS_WAIT_TIME = 32; m_buf.resize(4096); while(!accum.polling_finished()) { while(m_procs.size() < m_concurrent) m_procs.emplace_back(Unix_Process(next_source())); fd_set read_set; FD_ZERO(&read_set); std::vector<int> fds; for(auto& proc : m_procs) { int fd = proc.fd(); if(fd > 0) { fds.push_back(fd); FD_SET(fd, &read_set); } } if(fds.empty()) break; const int max_fd = *std::max_element(fds.begin(), fds.end()); struct ::timeval timeout; timeout.tv_sec = (MS_WAIT_TIME / 1000); timeout.tv_usec = (MS_WAIT_TIME % 1000) * 1000; if(::select(max_fd + 1, &read_set, nullptr, nullptr, &timeout) < 0) return; // or continue? for(auto& proc : m_procs) { int fd = proc.fd(); if(FD_ISSET(fd, &read_set)) { const ssize_t got = ::read(fd, m_buf.data(), m_buf.size()); if(got > 0) accum.add(m_buf.data(), got, BOTAN_ENTROPY_ESTIMATE_SYSTEM_TEXT); else proc.spawn(next_source()); } } } }
static int process_work_frame(AVFilterContext *ctx, int stop) { FrameRateContext *s = ctx->priv; AVFilterLink *outlink = ctx->outputs[0]; int64_t work_next_pts; AVFrame *copy_src1, *copy_src2, *work; int interpolate; ff_dlog(ctx, "process_work_frame()\n"); ff_dlog(ctx, "process_work_frame() pending_input_frames %d\n", s->pending_srce_frames); if (s->srce[s->prev]) ff_dlog(ctx, "process_work_frame() srce prev pts:%"PRId64"\n", s->srce[s->prev]->pts); if (s->srce[s->crnt]) ff_dlog(ctx, "process_work_frame() srce crnt pts:%"PRId64"\n", s->srce[s->crnt]->pts); if (s->srce[s->next]) ff_dlog(ctx, "process_work_frame() srce next pts:%"PRId64"\n", s->srce[s->next]->pts); if (!s->srce[s->crnt]) { // the filter cannot do anything ff_dlog(ctx, "process_work_frame() no current frame cached: move on to next frame, do not output a frame\n"); next_source(ctx); return 0; } work_next_pts = s->pts + s->average_dest_pts_delta; ff_dlog(ctx, "process_work_frame() work crnt pts:%"PRId64"\n", s->pts); ff_dlog(ctx, "process_work_frame() work next pts:%"PRId64"\n", work_next_pts); if (s->srce[s->prev]) ff_dlog(ctx, "process_work_frame() srce prev pts:%"PRId64" at dest time base:%u/%u\n", s->srce_pts_dest[s->prev], s->dest_time_base.num, s->dest_time_base.den); if (s->srce[s->crnt]) ff_dlog(ctx, "process_work_frame() srce crnt pts:%"PRId64" at dest time base:%u/%u\n", s->srce_pts_dest[s->crnt], s->dest_time_base.num, s->dest_time_base.den); if (s->srce[s->next]) ff_dlog(ctx, "process_work_frame() srce next pts:%"PRId64" at dest time base:%u/%u\n", s->srce_pts_dest[s->next], s->dest_time_base.num, s->dest_time_base.den); av_assert0(s->srce[s->next]); // should filter be skipping input frame (output frame rate is lower than input frame rate) if (!s->flush && s->pts >= s->srce_pts_dest[s->next]) { ff_dlog(ctx, "process_work_frame() work crnt pts >= srce next pts: SKIP FRAME, move on to next frame, do not output a frame\n"); next_source(ctx); s->pending_srce_frames--; return 0; } // calculate interpolation interpolate = (int) ((s->pts - s->srce_pts_dest[s->crnt]) * 256.0 / s->average_srce_pts_dest_delta); ff_dlog(ctx, "process_work_frame() interpolate:%d/256\n", interpolate); copy_src1 = s->srce[s->crnt]; if (interpolate > s->interp_end) { ff_dlog(ctx, "process_work_frame() source is:NEXT\n"); copy_src1 = s->srce[s->next]; } if (s->srce[s->prev] && interpolate < -s->interp_end) { ff_dlog(ctx, "process_work_frame() source is:PREV\n"); copy_src1 = s->srce[s->prev]; } // decide whether to blend two frames if ((interpolate >= s->interp_start && interpolate <= s->interp_end) || (interpolate <= -s->interp_start && interpolate >= -s->interp_end)) { double interpolate_scene_score = 0; if (interpolate > 0) { ff_dlog(ctx, "process_work_frame() interpolate source is:NEXT\n"); copy_src2 = s->srce[s->next]; } else { ff_dlog(ctx, "process_work_frame() interpolate source is:PREV\n"); copy_src2 = s->srce[s->prev]; } if ((s->flags & FRAMERATE_FLAG_SCD) && copy_src2) { interpolate_scene_score = get_scene_score(ctx, copy_src1, copy_src2); ff_dlog(ctx, "process_work_frame() interpolate scene score:%f\n", interpolate_scene_score); } // decide if the shot-change detection allows us to blend two frames if (interpolate_scene_score < s->scene_score && copy_src2) { uint16_t src2_factor = abs(interpolate); uint16_t src1_factor = 256 - src2_factor; int plane, line, pixel; // get work-space for output frame work = ff_get_video_buffer(outlink, outlink->w, outlink->h); if (!work) return AVERROR(ENOMEM); av_frame_copy_props(work, s->srce[s->crnt]); ff_dlog(ctx, "process_work_frame() INTERPOLATE to create work frame\n"); for (plane = 0; plane < 4 && copy_src1->data[plane] && copy_src2->data[plane]; plane++) { int cpy_line_width = s->line_size[plane]; uint8_t *cpy_src1_data = copy_src1->data[plane]; int cpy_src1_line_size = copy_src1->linesize[plane]; uint8_t *cpy_src2_data = copy_src2->data[plane]; int cpy_src2_line_size = copy_src2->linesize[plane]; int cpy_src_h = (plane > 0 && plane < 3) ? (copy_src1->height >> s->vsub) : (copy_src1->height); uint8_t *cpy_dst_data = work->data[plane]; int cpy_dst_line_size = work->linesize[plane]; if (plane <1 || plane >2) { // luma or alpha for (line = 0; line < cpy_src_h; line++) { for (pixel = 0; pixel < cpy_line_width; pixel++) { // integer version of (src1 * src1_factor) + (src2 + src2_factor) + 0.5 // 0.5 is for rounding // 128 is the integer representation of 0.5 << 8 cpy_dst_data[pixel] = ((cpy_src1_data[pixel] * src1_factor) + (cpy_src2_data[pixel] * src2_factor) + 128) >> 8; } cpy_src1_data += cpy_src1_line_size; cpy_src2_data += cpy_src2_line_size; cpy_dst_data += cpy_dst_line_size; } } else { // chroma for (line = 0; line < cpy_src_h; line++) { for (pixel = 0; pixel < cpy_line_width; pixel++) { // as above // because U and V are based around 128 we have to subtract 128 from the components. // 32896 is the integer representation of 128.5 << 8 cpy_dst_data[pixel] = (((cpy_src1_data[pixel] - 128) * src1_factor) + ((cpy_src2_data[pixel] - 128) * src2_factor) + 32896) >> 8; } cpy_src1_data += cpy_src1_line_size; cpy_src2_data += cpy_src2_line_size; cpy_dst_data += cpy_dst_line_size; } } }