Skip to content

Commit

Permalink
vo_drm: 30bpp support
Browse files Browse the repository at this point in the history
  • Loading branch information
xantoz committed Sep 22, 2019
1 parent 2d1d815 commit e2f9653
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 13 deletions.
9 changes: 4 additions & 5 deletions DOCS/man/vo.rst
Original file line number Diff line number Diff line change
Expand Up @@ -548,11 +548,10 @@ Available video output drivers are:
xrgb2101010 is a packed 30 bits per pixel/10 bits per channel packed RGB
format with 2 bits of padding.

Unless you have an Intel graphics card, a recent kernel and a recent
version of mesa (>=18) xrgb2101010 is unlikely to work for you.

This currently only has an effect when used together with the ``drm``
backend for the ``gpu`` VO. The ``drm`` VO always uses xrgb8888.
There are cases when xrgb2101010 will work with the ``drm`` VO, but not
with the ``drm`` backend for the ``gpu`` VO. This is because with the
``gpu`` VO, in addition to requiring support in your DRM driver,
requires support for xrgb2101010 in your EGL driver

``--drm-draw-surface-size=<[WxH]>``
Sets the size of the surface used on the draw plane. The surface will
Expand Down
1 change: 1 addition & 0 deletions RELEASE_NOTES
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Added
~~~~~

- vo_gpu: Vulkan API implementation based on libplacebo.
- vo_drm: Add 30bpp support.

Changed
~~~~~~~
Expand Down
61 changes: 53 additions & 8 deletions video/out/vo_drm.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,13 @@
#include "video/sws_utils.h"
#include "vo.h"

#define IMGFMT IMGFMT_BGR0
#define IMGFMT_XRGB8888 IMGFMT_BGR0
#if BYTE_ORDER == BIG_ENDIAN
#define IMGFMT_XRGB2101010 pixfmt2imgfmt(AV_PIX_FMT_GBRP10BE)
#else
#define IMGFMT_XRGB2101010 pixfmt2imgfmt(AV_PIX_FMT_GBRP10LE)
#endif

#define BYTES_PER_PIXEL 4
#define BITS_PER_PIXEL 32
#define USE_MASTER 0
Expand Down Expand Up @@ -70,6 +76,9 @@ struct priv {
bool active;
bool pflip_happening;

uint32_t depth;
enum mp_imgfmt imgfmt;

int32_t screen_w;
int32_t screen_h;
struct mp_image *last_input;
Expand Down Expand Up @@ -99,6 +108,8 @@ static void fb_destroy(int fd, struct framebuffer *buf)

static bool fb_setup_single(struct vo *vo, int fd, struct framebuffer *buf)
{
struct priv *p = vo->priv;

buf->handle = 0;

// create dumb buffer
Expand All @@ -116,7 +127,7 @@ static bool fb_setup_single(struct vo *vo, int fd, struct framebuffer *buf)
buf->handle = creq.handle;

// create framebuffer object for the dumb-buffer
if (drmModeAddFB(fd, buf->width, buf->height, 24, creq.bpp, buf->stride,
if (drmModeAddFB(fd, buf->width, buf->height, p->depth, creq.bpp, buf->stride,
buf->handle, &buf->fb)) {
MP_ERR(vo, "Cannot create framebuffer: %s\n", mp_strerror(errno));
goto err;
Expand Down Expand Up @@ -280,15 +291,15 @@ static int reconfig(struct vo *vo, struct mp_image_params *params)
mp_sws_set_from_cmdline(p->sws, vo->global);
p->sws->src = *params;
p->sws->dst = (struct mp_image_params) {
.imgfmt = IMGFMT,
.imgfmt = p->imgfmt,
.w = w,
.h = h,
.p_w = 1,
.p_h = 1,
};

talloc_free(p->cur_frame);
p->cur_frame = mp_image_alloc(IMGFMT, p->screen_w, p->screen_h);
p->cur_frame = mp_image_alloc(p->imgfmt, p->screen_w, p->screen_h);
mp_image_params_guess_csp(&p->sws->dst);
mp_image_set_params(p->cur_frame, &p->sws->dst);
p->cur_frame[0].w = p->screen_w;
Expand Down Expand Up @@ -337,10 +348,36 @@ static void draw_image(struct vo *vo, mp_image_t *mpi)
}

struct framebuffer *front_buf = &p->bufs[p->front_buf];
memcpy_pic(front_buf->map, p->cur_frame->planes[0],
p->cur_frame->w * BYTES_PER_PIXEL, p->cur_frame->h,
front_buf->stride,
p->cur_frame->stride[0]);

if (p->depth == 30) {
// Pack GBRP10 image into XRGB2101010 for DRM
const int w = p->cur_frame->w;
const int h = p->cur_frame->h;

const int g_padding = p->cur_frame->stride[0]/sizeof(uint16_t) - w;
const int b_padding = p->cur_frame->stride[1]/sizeof(uint16_t) - w;
const int r_padding = p->cur_frame->stride[2]/sizeof(uint16_t) - w;
const int fbuf_padding = front_buf->stride/sizeof(uint32_t) - w;

uint16_t *g_ptr = (uint16_t*)p->cur_frame->planes[0];
uint16_t *b_ptr = (uint16_t*)p->cur_frame->planes[1];
uint16_t *r_ptr = (uint16_t*)p->cur_frame->planes[2];
uint32_t *fbuf_ptr = (uint32_t*)front_buf->map;
for (unsigned y = 0; y < h; ++y) {
for (unsigned x = 0; x < w; ++x) {
*fbuf_ptr++ = (*r_ptr++ << 20) | (*g_ptr++ << 10) | (*b_ptr++);
}
g_ptr += g_padding;
b_ptr += b_padding;
r_ptr += r_padding;
fbuf_ptr += fbuf_padding;
}
} else {
memcpy_pic(front_buf->map, p->cur_frame->planes[0],
p->cur_frame->w * BYTES_PER_PIXEL, p->cur_frame->h,
front_buf->stride,
p->cur_frame->stride[0]);
}
}

if (mpi != p->last_input) {
Expand Down Expand Up @@ -426,6 +463,14 @@ static int preinit(struct vo *vo)
goto err;
}

if (vo->opts->drm_opts->drm_format == DRM_OPTS_FORMAT_XRGB2101010) {
p->depth = 30;
p->imgfmt = IMGFMT_XRGB2101010;
} else {
p->depth = 24;
p->imgfmt = IMGFMT_XRGB8888;
}

if (!fb_setup_double_buffering(vo)) {
MP_ERR(vo, "Failed to set up double buffering.\n");
goto err;
Expand Down

0 comments on commit e2f9653

Please sign in to comment.