/* * Compare the software on the local global zone and source system global * zone. Used when we are trying to attach a zone during migration or * when checking if a ZFS snapshot is still usable for a ZFS clone. * l_handle is for the local system and s_handle is for the source system. * These have a snapshot of the appropriate packages and patches in the global * zone for the two machines. * The functions called here can print any messages that are needed to * inform the user about package or patch problems. * The flag parameter controls how the messages are printed. If the * SW_CMP_SILENT bit is set in the flag then no messages will be printed * but we still compare the sw and return an error if there is a mismatch. */ int sw_cmp(zone_dochandle_t l_handle, zone_dochandle_t s_handle, uint_t flag) { char *hdr; int res = Z_OK; /* * Check the source host for pkgs (and versions) that are not on the * local host. */ if (!(flag & SW_CMP_SILENT)) hdr = gettext("These packages installed on the source system " "are inconsistent with this system:\n"); if (pkg_check(hdr, s_handle, l_handle, flag | SW_CMP_SRC) != Z_OK) res = Z_ERR; /* * Now check the local host for pkgs that were not on the source host. * We already handled version mismatches in the loop above. */ if (!(flag & SW_CMP_SILENT)) hdr = gettext("These packages installed on this system were " "not installed on the source system:\n"); if (pkg_check(hdr, l_handle, s_handle, flag | SW_CMP_NONE) != Z_OK) res = Z_ERR; /* * Check the source host for patches that are not on the local host. */ if (!(flag & SW_CMP_SILENT)) hdr = gettext("These patches installed on the source system " "are inconsistent with this system:\n"); if (patch_check(hdr, s_handle, l_handle, flag | SW_CMP_SRC) != Z_OK) res = Z_ERR; /* * Check the local host for patches that were not on the source host. * We already handled version mismatches in the loop above. */ if (!(flag & SW_CMP_SILENT)) hdr = gettext("These patches installed on this system were " "not installed on the source system:\n"); if (patch_check(hdr, l_handle, s_handle, flag | SW_CMP_NONE) != Z_OK) res = Z_ERR; return (res); }
static GstFlowReturn gst_patchdetect_transform_ip (GstBaseTransform * trans, GstBuffer * buf) { GstPatchdetect *patchdetect = GST_PATCHDETECT (trans); Frame frame; Point *points; int i, j; int blocks_x, blocks_y; int n_points; int n_patches; Patch *patches; guint8 *patchpix; int vec1_x, vec1_y; int vec2_x, vec2_y; Color detected_colors[24]; gboolean detected = FALSE; frame.y = GST_BUFFER_DATA (buf); frame.ystride = gst_video_format_get_row_stride (patchdetect->format, 0, patchdetect->width); frame.u = frame.y + gst_video_format_get_component_offset (patchdetect->format, 1, patchdetect->width, patchdetect->height); frame.ustride = gst_video_format_get_row_stride (patchdetect->format, 1, patchdetect->width); frame.v = frame.y + gst_video_format_get_component_offset (patchdetect->format, 2, patchdetect->width, patchdetect->height); frame.vstride = gst_video_format_get_row_stride (patchdetect->format, 2, patchdetect->width); frame.width = patchdetect->width; frame.height = patchdetect->height; frame.t = patchdetect->t; patchdetect->t++; blocks_y = (patchdetect->height & (~7)) / 8; blocks_x = (patchdetect->width & (~7)) / 8; patchpix = g_malloc0 (patchdetect->width * patchdetect->height); patches = g_malloc0 (sizeof (Patch) * 256); n_patches = 0; for (j = 0; j < blocks_y; j += 4) { for (i = 0; i < blocks_x; i += 4) { Stats block = { 0 }; get_block_stats (&frame, i * 8, j * 8, &block); patches[n_patches].val = n_patches + 2; if (block.match) { if (patch_check (&frame, patchpix, i * 8, j * 8, 8, 8)) { patch_start (&frame, patchpix, patches + n_patches, i * 8, j * 8, 8, 8); patches[n_patches].y = block.y; patches[n_patches].u = block.u; patches[n_patches].v = block.v; patch_grow (&frame, patchpix, patches + n_patches); n_patches++; g_assert (n_patches < 256); } } } } { int n; for (n = 0; n < n_patches; n++) { Patch *patch = &patches[n]; int xsum; int ysum; if (patch->count > 10000) continue; patch->valid = TRUE; xsum = 0; ysum = 0; for (j = patch->ymin; j < patch->ymax; j++) { for (i = patch->xmin; i < patch->xmax; i++) { if (patchpix[j * frame.width + i] != patch->val) continue; xsum += i; ysum += j; } } patch->cen_x = xsum / patch->count; patch->cen_y = ysum / patch->count; } } points = g_malloc0 (sizeof (Point) * 1000); n_points = 0; for (i = 0; i < n_patches; i++) { for (j = i + 1; j < n_patches; j++) { int dist_x, dist_y; if (i == j) continue; dist_x = patches[i].cen_x - patches[j].cen_x; dist_y = patches[i].cen_y - patches[j].cen_y; if (dist_x < 0) { dist_x = -dist_x; dist_y = -dist_y; } if (ABS (2 * dist_y) < dist_x && dist_x < 100) { points[n_points].x = dist_x; points[n_points].y = dist_y; points[n_points].valid = TRUE; points[n_points].patch1 = i; points[n_points].patch2 = j; n_points++; g_assert (n_points < 1000); } } } { int dist; int ave_x = 0, ave_y = 0; for (dist = 50; dist >= 10; dist -= 5) { int sum_x, sum_y; int n_valid; sum_x = 0; sum_y = 0; n_valid = 0; for (i = 0; i < n_points; i++) { if (!points[i].valid) continue; sum_x += points[i].x; sum_y += points[i].y; n_valid++; } if (n_valid == 0) continue; ave_x = sum_x / n_valid; ave_y = sum_y / n_valid; for (i = 0; i < n_points; i++) { int d; if (!points[i].valid) continue; d = (points[i].x - ave_x) * (points[i].x - ave_x); d += (points[i].y - ave_y) * (points[i].y - ave_y); if (d > dist * dist) points[i].valid = FALSE; } } vec1_x = ave_x; vec1_y = ave_y; } n_points = 0; for (i = 0; i < n_patches; i++) { for (j = i + 1; j < n_patches; j++) { int dist_x, dist_y; if (i == j) continue; dist_x = patches[i].cen_x - patches[j].cen_x; dist_y = patches[i].cen_y - patches[j].cen_y; if (dist_y < 0) { dist_x = -dist_x; dist_y = -dist_y; } if (ABS (2 * dist_x) < dist_y && dist_y < 100) { points[n_points].x = dist_x; points[n_points].y = dist_y; points[n_points].valid = TRUE; points[n_points].patch1 = i; points[n_points].patch2 = j; n_points++; g_assert (n_points < 1000); } } } { int dist; int ave_x = 0, ave_y = 0; for (dist = 50; dist >= 10; dist -= 5) { int sum_x, sum_y; int n_valid; sum_x = 0; sum_y = 0; n_valid = 0; for (i = 0; i < n_points; i++) { if (!points[i].valid) continue; sum_x += points[i].x; sum_y += points[i].y; n_valid++; } if (n_valid == 0) continue; ave_x = sum_x / n_valid; ave_y = sum_y / n_valid; for (i = 0; i < n_points; i++) { int d; if (!points[i].valid) continue; d = (points[i].x - ave_x) * (points[i].x - ave_x); d += (points[i].y - ave_y) * (points[i].y - ave_y); if (d > dist * dist) points[i].valid = FALSE; } } vec2_x = ave_x; vec2_y = ave_y; } #if 0 for (i = 0; i < n_points; i++) { if (!points[i].valid) continue; paint_block (&frame, 4 * points[i].x, 240 + 4 * points[i].y, 16); } #endif #if 0 paint_block (&frame, 360, 240, 16); paint_block (&frame, 360 + vec1_x, 240 + vec1_y, 16); paint_block (&frame, 360 + vec2_x, 240 + vec2_y, 16); #endif { double m00, m01, m10, m11; double det; double v1, v2; double ave_v1 = 0, ave_v2 = 0; det = vec1_x * vec2_y - vec1_y * vec2_x; m00 = vec2_y / det; m01 = -vec2_x / det; m10 = -vec1_y / det; m11 = vec1_x / det; for (i = 0; i < n_patches - 1; i++) { int count = 0; double sum_v1 = 0; double sum_v2 = 0; if (!patches[i].valid) continue; n_points = 0; for (j = i + 1; j < n_patches; j++) { int diff_x = patches[j].cen_x - patches[i].cen_x; int diff_y = patches[j].cen_y - patches[i].cen_y; if (!patches[j].valid) continue; v1 = diff_x * m00 + diff_y * m01; v2 = diff_x * m10 + diff_y * m11; if (v1 > -0.5 && v1 < 5.5 && v2 > -0.5 && v2 < 3.5 && ABS (v1 - rint (v1)) < 0.1 && ABS (v2 - rint (v2)) < 0.1) { sum_v1 += v1 - rint (v1); sum_v2 += v2 - rint (v2); count++; } } ave_v1 = sum_v1 / count; ave_v2 = sum_v2 / count; if (count > 20) { int k; for (j = 0; j < 4; j++) { for (k = 0; k < 6; k++) { Stats block; int xx; int yy; xx = patches[i].cen_x + (ave_v1 + k) * vec1_x + (ave_v2 + j) * vec2_x; yy = patches[i].cen_y + (ave_v1 + k) * vec1_y + (ave_v2 + j) * vec2_y; get_block_stats (&frame, xx - 4, yy - 4, &block); //GST_ERROR("%d %d: %d %d %d", k, j, block.y, block.u, block.v); detected_colors[k + j * 6].y = block.y; detected_colors[k + j * 6].u = block.u; detected_colors[k + j * 6].v = block.v; paint_block (&frame, xx - 4, yy - 4, 16); } } detected = TRUE; #if 0 for (j = i + 1; j < n_patches; j++) { int diff_x = patches[j].cen_x - patches[i].cen_x; int diff_y = patches[j].cen_y - patches[i].cen_y; int xx; int yy; if (!patches[j].valid) continue; v1 = diff_x * m00 + diff_y * m01; v2 = diff_x * m10 + diff_y * m11; if (v1 > -0.5 && v1 < 5.5 && v2 > -0.5 && v2 < 3.5 && ABS (v1 - rint (v1)) < 0.1 && ABS (v2 - rint (v2)) < 0.1) { v1 = rint (v1); v2 = rint (v2); xx = patches[i].cen_x + (ave_v1 + v1) * vec1_x + (ave_v2 + v2) * vec2_x; yy = patches[i].cen_y + (ave_v1 + v1) * vec1_y + (ave_v2 + v2) * vec2_y; paint_block (&frame, patches[j].cen_x, patches[j].cen_y, 128); paint_block (&frame, xx, yy, 16); } } paint_block (&frame, patches[i].cen_x, patches[i].cen_y, 240); #endif break; } } } #define N 10 if (detected) { int i, j, k; int n = N; double diff = 0; double matrix[10][10] = { {0} }; double vy[10] = { 0 }; double vu[10] = { 0 }; double vv[10] = { 0 }; double *by = patchdetect->by; double *bu = patchdetect->bu; double *bv = patchdetect->bv; double flip_diff = 0; for (i = 0; i < 24; i++) { diff += ABS (detected_colors[i].y - patch_colors[i].y); diff += ABS (detected_colors[i].u - patch_colors[i].u); diff += ABS (detected_colors[i].v - patch_colors[i].v); flip_diff += ABS (detected_colors[23 - i].y - patch_colors[i].y); flip_diff += ABS (detected_colors[23 - i].u - patch_colors[i].u); flip_diff += ABS (detected_colors[23 - i].v - patch_colors[i].v); } GST_ERROR ("uncorrected error %g (flipped %g)", diff / 24.0, flip_diff / 24.0); if (flip_diff < diff) { for (i = 0; i < 12; i++) { Color tmp; tmp = detected_colors[i]; detected_colors[i] = detected_colors[23 - i]; detected_colors[23 - i] = tmp; } } for (i = 0; i < 24; i++) { int dy = detected_colors[i].y - patch_colors[i].y; int du = detected_colors[i].u - patch_colors[i].u; int dv = detected_colors[i].v - patch_colors[i].v; int py = detected_colors[i].y - 128; int pu = detected_colors[i].u - 128; int pv = detected_colors[i].v - 128; int w = (i < 18) ? 1 : 2; double z[10]; diff += ABS (dy) + ABS (du) + ABS (dv); z[0] = 1; z[1] = py; z[2] = pu; z[3] = pv; z[4] = py * py; z[5] = py * pu; z[6] = py * pv; z[7] = pu * pu; z[8] = pu * pv; z[9] = pv * pv; for (j = 0; j < n; j++) { for (k = 0; k < n; k++) { matrix[j][k] += w * z[j] * z[k]; } vy[j] += w * dy * z[j]; vu[j] += w * du * z[j]; vv[j] += w * dv * z[j]; } } invert_matrix (matrix, n); for (i = 0; i < n; i++) { by[i] = 0; bu[i] = 0; bv[i] = 0; for (j = 0; j < n; j++) { by[i] += matrix[i][j] * vy[j]; bu[i] += matrix[i][j] * vu[j]; bv[i] += matrix[i][j] * vv[j]; } } //GST_ERROR("a %g %g %g b %g %g %g", ay, au, av, by, bu, bv); diff = 0; for (i = 0; i < 24; i++) { double cy, cu, cv; double z[10]; int py = detected_colors[i].y - 128; int pu = detected_colors[i].u - 128; int pv = detected_colors[i].v - 128; z[0] = 1; z[1] = py; z[2] = pu; z[3] = pv; z[4] = py * py; z[5] = py * pu; z[6] = py * pv; z[7] = pu * pu; z[8] = pu * pv; z[9] = pv * pv; cy = 0; cu = 0; cv = 0; for (j = 0; j < n; j++) { cy += by[j] * z[j]; cu += bu[j] * z[j]; cv += bv[j] * z[j]; } diff += fabs (patch_colors[i].y - (128 + py - cy)); diff += fabs (patch_colors[i].u - (128 + pu - cu)); diff += fabs (patch_colors[i].v - (128 + pv - cv)); } GST_ERROR ("average error %g", diff / 24.0); patchdetect->valid = 3000; } if (patchdetect->valid > 0) { int n = N; guint8 *u1, *u2; guint8 *v1, *v2; double *by = patchdetect->by; double *bu = patchdetect->bu; double *bv = patchdetect->bv; patchdetect->valid--; u1 = g_malloc (frame.width); u2 = g_malloc (frame.width); v1 = g_malloc (frame.width); v2 = g_malloc (frame.width); for (j = 0; j < frame.height; j += 2) { for (i = 0; i < frame.width / 2; i++) { u1[2 * i + 0] = frame.u[(j / 2) * frame.ustride + i]; u1[2 * i + 1] = u1[2 * i + 0]; u2[2 * i + 0] = u1[2 * i + 0]; u2[2 * i + 1] = u1[2 * i + 0]; v1[2 * i + 0] = frame.v[(j / 2) * frame.vstride + i]; v1[2 * i + 1] = v1[2 * i + 0]; v2[2 * i + 0] = v1[2 * i + 0]; v2[2 * i + 1] = v1[2 * i + 0]; } for (i = 0; i < frame.width; i++) { int k; double z[10]; double cy, cu, cv; int y, u, v; int py, pu, pv; y = frame.y[(j + 0) * frame.ystride + i]; u = u1[i]; v = v1[i]; py = y - 128; pu = u - 128; pv = v - 128; z[0] = 1; z[1] = py; z[2] = pu; z[3] = pv; z[4] = py * py; z[5] = py * pu; z[6] = py * pv; z[7] = pu * pu; z[8] = pu * pv; z[9] = pv * pv; cy = 0; cu = 0; cv = 0; for (k = 0; k < n; k++) { cy += by[k] * z[k]; cu += bu[k] * z[k]; cv += bv[k] * z[k]; } frame.y[(j + 0) * frame.ystride + i] = CLAMP (rint (y - cy), 0, 255); u1[i] = CLAMP (rint (u - cu), 0, 255); v1[i] = CLAMP (rint (v - cv), 0, 255); y = frame.y[(j + 1) * frame.ystride + i]; u = u2[i]; v = v2[i]; py = y - 128; pu = u - 128; pv = v - 128; z[0] = 1; z[1] = py; z[2] = pu; z[3] = pv; z[4] = py * py; z[5] = py * pu; z[6] = py * pv; z[7] = pu * pu; z[8] = pu * pv; z[9] = pv * pv; cy = 0; cu = 0; cv = 0; for (k = 0; k < n; k++) { cy += by[k] * z[k]; cu += bu[k] * z[k]; cv += bv[k] * z[k]; } frame.y[(j + 1) * frame.ystride + i] = CLAMP (rint (y - cy), 0, 255); u2[i] = CLAMP (rint (u - cu), 0, 255); v2[i] = CLAMP (rint (v - cv), 0, 255); } for (i = 0; i < frame.width / 2; i++) { frame.u[(j / 2) * frame.ustride + i] = (u1[2 * i + 0] + u1[2 * i + 1] + u2[2 * i + 0] + u2[2 * i + 1] + 2) >> 2; frame.v[(j / 2) * frame.vstride + i] = (v1[2 * i + 0] + v1[2 * i + 1] + v2[2 * i + 0] + v2[2 * i + 1] + 2) >> 2; } } g_free (u1); g_free (u2); g_free (v1); g_free (v2); }