vs_show(...) 主要代码都是处理窗口变化的
int vs_show (void *ctx, unsigned char *data[4], int stride[4])
{
// 首选检查 sws 是否有效, 根据当前窗口大小决定
Ctx *c = (Ctx*)ctx;
Window root;
int x, y;
unsigned int cx, cy, border, depth;
XGetGeometry(c->display, c->window, &root, &x, &y, &cx, &cy, &border, &depth);
if (cx != c->curr_width || cy != c->curr_height) {
avpicture_free(&c->pic_target);
sws_freeContext(c->sws);
c->sws = sws_getContext(c->v_width, c->v_height, PIX_FMT_YUV420P,
cx, cy, c->target_pixfmt,
SWS_FAST_BILINEAR, 0, 0, 0);
avpicture_alloc(&c->pic_target, c->target_pixfmt, cx, cy);
c->curr_width = cx;
c->curr_height = cy;
// re create image
XShmDetach(c->display, &c->segment);
shmdt(c->segment.shmaddr);
shmctl(c->segment.shmid, IPC_RMID, 0);
XDestroyImage(c->image);
c->image = XShmCreateImage(c->display, c->vinfo.visual, depth, ZPixmap, 0,
&c->segment, cx, cy);
c->segment.shmid = shmget(IPC_PRIVATE,
c->image->bytes_per_line * c->image->height,
IPC_CREAT | 0777);
c->segment.shmaddr = (char*)shmat(c->segment.shmid, 0, 0);
c->image->data = c->segment.shmaddr;
c->segment.readOnly = 0;
XShmAttach(c->display, &c->segment);
}
//
sws_scale(c->sws, data, stride, 0, c->v_height, c->pic_target.data, c->pic_target.linesize);
// cp to image
unsigned char *p = c->pic_target.data[0], *q = (unsigned char*)c->image->data;
int xx = MIN(c->image->bytes_per_line, c->pic_target.linesize[0]);
for (int i = 0; i < c->curr_height; i++) {
memcpy(q, p, xx);
p += c->image->bytes_per_line;
q += c->pic_target.linesize[0];
}
// 显示到 X 上
XShmPutImage(c->display, c->window, c->gc, c->image, 0, 0, 0, 0, c->curr_width, c->curr_height, 1);
return 1;
}