diff options
author | Shreesh Adiga <16567adigashreesh@gmail.com> | 2020-11-26 21:35:20 +0530 |
---|---|---|
committer | avih <avih@users.noreply.github.com> | 2020-11-27 15:31:24 +0200 |
commit | 4d80314c5c8838cf04bc53b75a123d281f8d30a3 (patch) | |
tree | e981f6ac0ec4378b29a747e54476e2785a8acd22 /video/out | |
parent | 4dd5fdc0876e30de6ddabc1a8ab0263a1d4404d3 (diff) | |
download | mpv-4d80314c5c8838cf04bc53b75a123d281f8d30a3.tar.bz2 mpv-4d80314c5c8838cf04bc53b75a123d281f8d30a3.tar.xz |
vo_sixel: use draw_frame instead of draw_image
draw_image is deprecated, and draw_frame allows better
behavior, like rendering the osd without image.
e.g. `mpv --vo=sixel --idle --force-window`.
Diffstat (limited to 'video/out')
-rw-r--r-- | video/out/vo_sixel.c | 49 |
1 files changed, 36 insertions, 13 deletions
diff --git a/video/out/vo_sixel.c b/video/out/vo_sixel.c index 46c289dafe..f4ba8db7c7 100644 --- a/video/out/vo_sixel.c +++ b/video/out/vo_sixel.c @@ -70,6 +70,7 @@ struct priv { sixel_dither_t *dither; sixel_dither_t *testdither; uint8_t *buffer; + bool skip_frame_draw; // The dimensions that will be actually // be used after processing user inputs @@ -317,28 +318,45 @@ static int reconfig(struct vo *vo, struct mp_image_params *params) return 0; } -static void draw_image(struct vo *vo, mp_image_t *mpi) +static void draw_frame(struct vo *vo, struct vo_frame *frame) { struct priv *priv = vo->priv; - struct mp_image src = *mpi; SIXELSTATUS status; + struct mp_image *mpi = NULL; - struct mp_rect src_rc = priv->src_rect; - src_rc.x0 = MP_ALIGN_DOWN(src_rc.x0, mpi->fmt.align_x); - src_rc.y0 = MP_ALIGN_DOWN(src_rc.y0, mpi->fmt.align_y); - mp_image_crop_rc(&src, src_rc); + if (frame->repeat && !frame->redraw) { + // Frame is repeated, and no need to update OSD either + priv->skip_frame_draw = true; + return; + } else { + // Either frame is new, or OSD has to be redrawn + priv->skip_frame_draw = false; + } - // Downscale the image - mp_sws_scale(priv->sws, priv->frame, &src); + // Normal case where we have to draw the frame and the image is not NULL + if (frame->current) { + mpi = mp_image_new_ref(frame->current); + struct mp_rect src_rc = priv->src_rect; + src_rc.x0 = MP_ALIGN_DOWN(src_rc.x0, mpi->fmt.align_x); + src_rc.y0 = MP_ALIGN_DOWN(src_rc.y0, mpi->fmt.align_y); + mp_image_crop_rc(mpi, src_rc); + + // scale/pan to our dest rect + mp_sws_scale(priv->sws, priv->frame, mpi); + } else { + // Image is NULL, so need to clear image and draw OSD + mp_image_clear(priv->frame, 0, 0, priv->width, priv->height); + } struct mp_osd_res dim = { .w = priv->width, .h = priv->height }; osd_draw_on_image(vo->osd, dim, mpi ? mpi->pts : 0, 0, priv->frame); + // Copy from mpv to RGB format as required by libsixel - memcpy_pic(priv->buffer, priv->frame->planes[0], priv->width * depth, priv->height, - priv->width * depth, priv->frame->stride[0]); + memcpy_pic(priv->buffer, priv->frame->planes[0], priv->width * depth, + priv->height, priv->width * depth, priv->frame->stride[0]); // Even if either of these prepare palette functions fail, on re-running them // they should try to re-initialize the dithers, so it shouldn't dereference @@ -351,11 +369,12 @@ static void draw_image(struct vo *vo, mp_image_t *mpi) } if (SIXEL_FAILED(status)) { - MP_WARN(vo, "draw_image: prepare_palette returned error: %s\n", + MP_WARN(vo, "draw_frame: prepare_palette returned error: %s\n", sixel_helper_format_error(status)); } - talloc_free(mpi); + if (mpi) + talloc_free(mpi); } static int sixel_write(char *data, int size, void *priv) @@ -367,6 +386,10 @@ static void flip_page(struct vo *vo) { struct priv* priv = vo->priv; + // If frame is repeated and no update required, then we skip encoding + if (priv->skip_frame_draw) + return; + // Make sure that image and dither are valid before drawing if (priv->buffer == NULL || priv->dither == NULL) return; @@ -472,7 +495,7 @@ const struct vo_driver video_out_sixel = { .query_format = query_format, .reconfig = reconfig, .control = control, - .draw_image = draw_image, + .draw_frame = draw_frame, .flip_page = flip_page, .uninit = uninit, .priv_size = sizeof(struct priv), |