背景
NV12フォーマットのGEM FLINK名からテクスチャを生成する
を元に YUV420
フォーマットで生成するにあたって、offset値に困った。
その調査ログである。
wayland + gstreamer-vaapiの環境の話。
TL;DR
offset値は drmプロトコルのwl_drmインターフェースのcreate_planar_bufferリクエストで見える。
offset値の元となるplanerレイアウト値は、i965_drv_video.c の i965_check_alloc_surface_bo() で設定している。
create_planarリクエスト
libvaのi965_output_wayland.cのva_GetSurfaceBufferWl()で設定/リクエストしている。
offsets[0] = 0;
pitches[0] = obj_surface->width;
offsets[1] = obj_surface->width * obj_surface->y_cb_offset;
pitches[1] = obj_surface->cb_cr_pitch;
offsets[2] = obj_surface->width * obj_surface->y_cr_offset
pitches[2] = obj_surface->cb_cr_pitch;
planarレイアウト
#define ALIGN(i, n) (((i) + (n) - 1) & ~((n) - 1))
bufferの情報は、 struct object_surface *obj_surface
が所有している。
struct object_surface
{
struct object_base base;
VASurfaceStatus status;
VASubpictureID subpic[I965_MAX_SUBPIC_SUM];
struct object_subpic *obj_subpic[I965_MAX_SUBPIC_SUM];
unsigned int subpic_render_idx;
int width; // default: ALIGN(width, 16)
int height; // default: ALIGN(height, 16)
int size;
int orig_width;
int orig_height;
int flags;
unsigned int fourcc;
dri_bo *bo;
VAImageID locked_image_id;
void (*free_private_data)(void **data);
void *private_data;
unsigned int subsampling;
int x_cb_offset; // X offset is always 0
int y_cb_offset;
int x_cr_offset;
int y_cr_offset;
int cb_cr_width;
int cb_cr_height;
int cb_cr_pitch;
};
確認コード
https://wandbox.org/permlink/RZNwzBcMr0HFGHPS
https://gist.github.com/yuu/d7bd9413d6d1d90fa12638cdec658ec6
wayland_debugのログ↓
// id, name, width, height, format, offset0, stride0, offset1, stride1, offset2, stride2
[2610092.529] -> wl_drm@14.create_planar_buffer(new id wl_buffer@13, 7, 320, 240, 842093913, 0, 320, 96000, 160, 76800, 160)
一緒ですね!終わり。