static void CreateBuffers(vout_display_t *vd, const vout_display_cfg_t *cfg) { const video_format_t *fmt = &vd->source; vout_display_sys_t *sys = vd->sys; xcb_connection_t *conn = sys->conn; xcb_create_pixmap(conn, 32, sys->drawable.crop, sys->root, fmt->i_visible_width, fmt->i_visible_height); xcb_create_pixmap(conn, 32, sys->drawable.scale, sys->root, cfg->display.width, cfg->display.height); xcb_render_create_picture(conn, sys->picture.crop, sys->drawable.crop, sys->format.argb, 0, NULL); xcb_render_create_picture(conn, sys->picture.scale, sys->drawable.scale, sys->format.argb, 0, NULL); vout_display_place_t *place = &sys->place; vout_display_PlacePicture(place, fmt, cfg); /* Homogeneous coordinates transform from destination(place) * to source(fmt) */ int32_t ax = place->height; /* multiply x instead of dividing y */ int32_t ay = place->width; /* multiply y instead of dividing x */ int32_t bx = 0; int32_t by = 0; switch (fmt->orientation) { case ORIENT_TOP_LEFT: case ORIENT_LEFT_TOP: break; case ORIENT_TOP_RIGHT: case ORIENT_RIGHT_TOP: ax *= -1; bx -= place->width; break; case ORIENT_BOTTOM_LEFT: case ORIENT_LEFT_BOTTOM: ay *= -1; by -= place->height; break; case ORIENT_BOTTOM_RIGHT: case ORIENT_RIGHT_BOTTOM: ax *= -1; ay *= -1; bx -= place->width; by -= place->height; break; } sys->src_x = bx; sys->src_y = by; xcb_render_transform_t transform = { 0, 0, 0, 0, 0, 0, /* Multiply z by width and height to compensate for x and y above */ 0, 0, place->width * place->height, }; if (ORIENT_IS_SWAP(fmt->orientation)) { transform.matrix12 = ay * fmt->i_visible_width; transform.matrix21 = ax * fmt->i_visible_height; } else { transform.matrix11 = ax * fmt->i_visible_width; transform.matrix22 = ay * fmt->i_visible_height; } xcb_render_set_picture_transform(conn, sys->picture.crop, transform); if (likely(sys->filter != NULL)) xcb_render_set_picture_filter(conn, sys->picture.crop, strlen(sys->filter), sys->filter, 0, NULL); }
static void Display(vout_display_t *vd, picture_t *picture, subpicture_t *subpicture) { vout_display_sys_t *sys = vd->sys; /* */ video_format_t fmt = vd->fmt; if (ORIENT_IS_SWAP(vd->source.orientation)) { fmt.i_sar_num = vd->source.i_sar_den; fmt.i_sar_den = vd->source.i_sar_num; } else { fmt.i_sar_num = vd->source.i_sar_num; fmt.i_sar_den = vd->source.i_sar_den; } /* */ char type; if (picture->b_progressive) type = 'p'; else if (picture->b_top_field_first) type = 't'; else type = 'b'; if (type != 'p') { msg_Warn(vd, "Received a non progressive frame, " "it will be written as progressive."); type = 'p'; } /* */ if (!sys->is_first) { const char *header; char buffer[5]; if (sys->is_yuv4mpeg2) { /* MPlayer compatible header, unfortunately it doesn't tell you * the exact fourcc used. */ header = "YUV4MPEG2"; } else { snprintf(buffer, sizeof(buffer), "%4.4s", (const char*)&fmt.i_chroma); header = buffer; } fprintf(sys->f, "%s W%d H%d F%d:%d I%c A%d:%d\n", header, fmt.i_visible_width, fmt.i_visible_height, fmt.i_frame_rate, fmt.i_frame_rate_base, type, fmt.i_sar_num, fmt.i_sar_den); sys->is_first = true; } /* */ fprintf(sys->f, "FRAME\n"); for (int i = 0; i < picture->i_planes; i++) { const plane_t *plane = &picture->p[i]; const uint8_t *pixels = plane->p_pixels; pixels += (vd->fmt.i_x_offset * plane->i_visible_pitch) / vd->fmt.i_visible_height; for( int y = 0; y < plane->i_visible_lines; y++) { const size_t written = fwrite(pixels, 1, plane->i_visible_pitch, sys->f); if (written != (size_t)plane->i_visible_pitch) msg_Warn(vd, "only %zd of %d bytes written", written, plane->i_visible_pitch); pixels += plane->i_pitch; } } fflush(sys->f); /* */ picture_Release(picture); VLC_UNUSED(subpicture); }