summaryrefslogtreecommitdiffstats
path: root/video/out/vo_gpu_next.c
diff options
context:
space:
mode:
Diffstat (limited to 'video/out/vo_gpu_next.c')
-rw-r--r--video/out/vo_gpu_next.c39
1 files changed, 34 insertions, 5 deletions
diff --git a/video/out/vo_gpu_next.c b/video/out/vo_gpu_next.c
index 599ea758d4..da613f498b 100644
--- a/video/out/vo_gpu_next.c
+++ b/video/out/vo_gpu_next.c
@@ -481,17 +481,36 @@ static bool map_frame(pl_gpu gpu, pl_tex *tex, const struct pl_source_frame *src
enum pl_chroma_location chroma = mp_chroma_to_pl(par->chroma_location);
int planes = plane_data_from_imgfmt(data, &frame->repr.bits, mpi->imgfmt);
+ bool img_vflipped = false;
for (int n = 0; n < planes; n++) {
data[n].width = mp_image_plane_w(mpi, n);
data[n].height = mp_image_plane_h(mpi, n);
- data[n].row_stride = mpi->stride[n];
- data[n].pixels = mpi->planes[n];
+ bool vflipped = mpi->stride[n] < 0;
+ if (vflipped) {
+ int h = mp_image_plane_h(mpi, n);
+ data[n].pixels = mpi->planes[n] + (h - 1) * mpi->stride[n];
+ data[n].row_stride = -mpi->stride[n];
+ } else {
+ data[n].pixels = mpi->planes[n];
+ data[n].row_stride = mpi->stride[n];
+ }
+
+ // libplacebo can't deal with images that have partially flipped
+ // textures. We could work around this by blitting them to fresh
+ // (unflipped) textures, but it's an unlikely enough case to warrant
+ // just erroring out instead. (Usually, all planes will be flipped or
+ // unflipped simultaneously, e.g. by the `vflip` filter)
+ if (n > 0 && img_vflipped != vflipped) {
+ MP_ERR(vo, "Inconsistently flipped planes!\n");
+ return false;
+ }
+ img_vflipped = vflipped;
pl_buf buf = get_dr_buf(mpi);
if (buf) {
- data[n].pixels = NULL;
data[n].buf = buf;
- data[n].buf_offset = mpi->planes[n] - buf->data;
+ data[n].buf_offset = (uint8_t *) data[n].pixels - buf->data;
+ data[n].pixels = NULL;
} else if (gpu->limits.callbacks) {
data[n].callback = talloc_free;
data[n].priv = mp_image_new_ref(mpi);
@@ -504,8 +523,11 @@ static bool map_frame(pl_gpu gpu, pl_tex *tex, const struct pl_source_frame *src
return false;
}
- if (mpi->fmt.xs[n] || mpi->fmt.ys[n])
+ if (mpi->fmt.xs[n] || mpi->fmt.ys[n]) {
pl_chroma_location_offset(chroma, &plane->shift_x, &plane->shift_y);
+ if (vflipped)
+ plane->shift_y = -plane->shift_y;
+ }
}
#ifdef PL_HAVE_LAV_DOLBY_VISION
@@ -668,6 +690,13 @@ static void apply_crop(struct pl_frame *frame, struct mp_rect crop,
frame->crop.y0 = height - frame->crop.y0;
frame->crop.y1 = height - frame->crop.y1;
}
+
+ struct mp_image *mpi = frame->user_data;
+ if (mpi && mpi->stride[0] < 0) {
+ // Adjust for vertically flipped planes
+ frame->crop.y0 = height - frame->crop.y0;
+ frame->crop.y1 = height - frame->crop.y1;
+ }
}
static void draw_frame(struct vo *vo, struct vo_frame *frame)