diff options
author | Kacper Michajłow <kasper93@gmail.com> | 2023-09-09 02:27:15 +0200 |
---|---|---|
committer | Dudemanguy <random342@airmail.cc> | 2023-09-09 00:49:19 +0000 |
commit | 09da37356d529a2e37b4069aeebda3902991b6c8 (patch) | |
tree | 0d001ce1c413fe5fb6e104e829f8e005ea1c28e0 /player/video.c | |
parent | 385719056eba3fe9f25e2417fbdaafce07c0ac47 (diff) | |
download | mpv-09da37356d529a2e37b4069aeebda3902991b6c8.tar.bz2 mpv-09da37356d529a2e37b4069aeebda3902991b6c8.tar.xz |
player/video: apply crop for all frames in vo_frame
Sometimes needed when frames are extracted out of order, for example in
case of screenshot.
Diffstat (limited to 'player/video.c')
-rw-r--r-- | player/video.c | 71 |
1 files changed, 39 insertions, 32 deletions
diff --git a/player/video.c b/player/video.c index e67fa66785..22e0dcf51b 100644 --- a/player/video.c +++ b/player/video.c @@ -1010,6 +1010,41 @@ static void calculate_frame_duration(struct MPContext *mpctx) MP_STATS(mpctx, "value %f frame-duration-approx", MPMAX(0, approx_duration)); } +static void apply_video_crop(struct vo *vo, struct mp_image_params *p) +{ + struct m_geometry *gm = &vo->opts->video_crop; + struct mp_rect rc = {0}; + if (gm->xy_valid || (gm->wh_valid && (gm->w > 0 || gm->w_per > 0 || + gm->h > 0 || gm->h_per > 0))) + { + m_rect_apply(&rc, p->w, p->h, gm); + } + if (rc.x1 > 0 && rc.y1 > 0) { + p->crop = rc; + if (!mp_image_crop_valid(p)) { + char *str = m_option_type_rect.print(NULL, gm); + MP_WARN(vo, "Ignoring invalid --video-crop=%s for %dx%d image\n", + str, p->w, p->h); + talloc_free(str); + if (vo->params) { + p->crop = vo->params->crop; + *gm = (struct m_geometry){ + .x = p->crop.x0, + .y = p->crop.y0, + .w = mp_rect_w(p->crop), + .h = mp_rect_h(p->crop), + .xy_valid = true, + .wh_valid = true, + }; + } + if (!mp_image_crop_valid(p)) { + p->crop = (struct mp_rect){0}; + *gm = (struct m_geometry){0}; + } + } + } +} + void write_video(struct MPContext *mpctx) { struct MPOpts *opts = mpctx->opts; @@ -1127,40 +1162,12 @@ void write_video(struct MPContext *mpctx) } } + // Inject vo crop to notify and reconfig if needed + for (int n = 0; n < mpctx->num_next_frames; n++) + apply_video_crop(vo, &mpctx->next_frames[n]->params); + // Filter output is different from VO input? struct mp_image_params *p = &mpctx->next_frames[0]->params; - // Inject vo crop to notify and reconfig if needed - struct m_geometry *gm = &vo->opts->video_crop; - struct mp_rect rc = {0}; - if (gm->xy_valid || (gm->wh_valid && (gm->w > 0 || gm->w_per > 0 || - gm->h > 0 || gm->h_per > 0))) - { - m_rect_apply(&rc, p->w, p->h, gm); - } - if (rc.x1 > 0 && rc.y1 > 0) { - p->crop = rc; - if (!mp_image_crop_valid(p)) { - char *str = m_option_type_rect.print(NULL, gm); - MP_WARN(vo, "Ignoring invalid --video-crop=%s for %dx%d image\n", - str, p->w, p->h); - talloc_free(str); - if (vo->params) { - p->crop = vo->params->crop; - *gm = (struct m_geometry){ - .x = p->crop.x0, - .y = p->crop.y0, - .w = mp_rect_w(p->crop), - .h = mp_rect_h(p->crop), - .xy_valid = true, - .wh_valid = true, - }; - } - if (!mp_image_crop_valid(p)) { - p->crop = (struct mp_rect){0}; - *gm = (struct m_geometry){0}; - } - } - } if (!vo->params || !mp_image_params_equal(p, vo->params)) { // Changing config deletes the current frame; wait until it's finished. if (vo_still_displaying(vo)) { |