void drive_open_loop(open_loop_params_t *params) { int ref_frequency = params->frequency; int acceleration = params->acceleration; int frequency = open_loop_acceleration(ref_frequency, acceleration); sine_param_t sine_params; sine_params.direction = is_negative(frequency); sine_params.amplitude_pwm = vf_control(abs(frequency)); sine_params.freq_m = abs(frequency); sine_set_params(&sine_params); }
double update_video(struct MPContext *mpctx, double endpts) { struct dec_video *d_video = mpctx->d_video; struct vo *video_out = mpctx->video_out; vf_control(d_video->vfilter, VFCTRL_SET_OSD_OBJ, mpctx->osd); // for vf_sub if (!mpctx->opts->correct_pts) return update_video_nocorrect_pts(mpctx); if (d_video->header->attached_picture) return update_video_attached_pic(mpctx); double pts; while (1) { if (load_next_vo_frame(mpctx, false)) break; pts = MP_NOPTS_VALUE; struct demux_packet *pkt = NULL; while (1) { pkt = demux_read_packet(d_video->header); if (!pkt || pkt->len) break; /* Packets with size 0 are assumed to not correspond to frames, * but to indicate the absence of a frame in formats like AVI * that must have packets at fixed timecode intervals. */ talloc_free(pkt); } if (pkt) pts = pkt->pts; if (pts != MP_NOPTS_VALUE) pts += mpctx->video_offset; if (pts >= mpctx->hrseek_pts - .005) mpctx->hrseek_framedrop = false; int framedrop_type = mpctx->hrseek_active && mpctx->hrseek_framedrop ? 1 : check_framedrop(mpctx, -1); struct mp_image *decoded_frame = video_decode(d_video, pkt, framedrop_type, pts); talloc_free(pkt); if (decoded_frame) { determine_frame_pts(mpctx); filter_video(mpctx, decoded_frame); } else if (!pkt) { if (!load_next_vo_frame(mpctx, true)) return -1; } break; } if (!video_out->frame_loaded) return 0; pts = video_out->next_pts; if (pts == MP_NOPTS_VALUE) { MP_ERR(mpctx, "Video pts after filters MISSING\n"); // Try to use decoder pts from before filters pts = d_video->pts; if (pts == MP_NOPTS_VALUE) pts = d_video->last_pts; } if (endpts == MP_NOPTS_VALUE || pts < endpts) add_frame_pts(mpctx, pts); if (mpctx->hrseek_active && pts < mpctx->hrseek_pts - .005) { vo_skip_frame(video_out); return 0; } mpctx->hrseek_active = false; d_video->pts = pts; if (d_video->last_pts == MP_NOPTS_VALUE) { d_video->last_pts = d_video->pts; } else if (d_video->last_pts > d_video->pts) { MP_WARN(mpctx, "Decreasing video pts: %f < %f\n", d_video->pts, d_video->last_pts); /* If the difference in pts is small treat it as jitter around the * right value (possibly caused by incorrect timestamp ordering) and * just show this frame immediately after the last one. * Treat bigger differences as timestamp resets and start counting * timing of later frames from the position of this one. */ if (d_video->last_pts - d_video->pts > 0.5) d_video->last_pts = d_video->pts; else d_video->pts = d_video->last_pts; } else if (d_video->pts >= d_video->last_pts + 60) { // Assume a PTS difference >= 60 seconds is a discontinuity. MP_WARN(mpctx, "Jump in video pts: %f -> %f\n", d_video->last_pts, d_video->pts); d_video->last_pts = d_video->pts; } double frame_time = d_video->pts - d_video->last_pts; d_video->last_pts = d_video->pts; if (mpctx->d_audio) mpctx->delay -= frame_time; return frame_time; }