Revision ce702e93 ui/vnc-enc-tight.c

b/ui/vnc-enc-tight.c
72 72
static int tight_send_framebuffer_update(VncState *vs, int x, int y,
73 73
                                         int w, int h);
74 74

  
75
#ifdef CONFIG_VNC_JPEG
76
static const struct {
77
    double jpeg_freq_min;       /* Don't send JPEG if the freq is bellow */
78
    double jpeg_freq_threshold; /* Always send JPEG if the freq is above */
79
    int jpeg_idx;               /* Allow indexed JPEG */
80
    int jpeg_full;              /* Allow full color JPEG */
81
} tight_jpeg_conf[] = {
82
    { 0,   4,  1, 1 },
83
    { 0,   4,  1, 1 },
84
    { 0,   4,  1, 1 },
85
    { 0,   4,  1, 1 },
86
    { 0,   4,  0, 1 },
87
    { 0.1, 4,  0, 1 },
88
    { 0.2, 4,  0, 1 },
89
    { 0.3, 6,  0, 0 },
90
    { 0.4, 8,  0, 0 },
91
    { 0.5, 10, 0, 0 },
92
};
93
#endif
94

  
75 95
#ifdef CONFIG_VNC_PNG
76 96
static const struct {
77 97
    int png_zlib_level, png_filters;
......
1476 1496
#ifdef CONFIG_VNC_JPEG
1477 1497
static int send_sub_rect_jpeg(VncState *vs, int x, int y, int w, int h,
1478 1498
                              int bg, int fg, int colors,
1479
                              VncPalette *palette)
1499
                              VncPalette *palette, bool force)
1480 1500
{
1481 1501
    int ret;
1482 1502

  
1483 1503
    if (colors == 0) {
1484
        if (tight_detect_smooth_image(vs, w, h)) {
1504
        if (force || (tight_jpeg_conf[vs->tight.quality].jpeg_full &&
1505
                      tight_detect_smooth_image(vs, w, h))) {
1485 1506
            int quality = tight_conf[vs->tight.quality].jpeg_quality;
1486 1507

  
1487 1508
            ret = send_jpeg_rect(vs, x, y, w, h, quality);
......
1493 1514
    } else if (colors == 2) {
1494 1515
        ret = send_mono_rect(vs, x, y, w, h, bg, fg);
1495 1516
    } else if (colors <= 256) {
1496
        if (colors > 96 &&
1497
            tight_detect_smooth_image(vs, w, h)) {
1517
        if (force || (colors > 96 &&
1518
                      tight_jpeg_conf[vs->tight.quality].jpeg_idx &&
1519
                      tight_detect_smooth_image(vs, w, h))) {
1498 1520
            int quality = tight_conf[vs->tight.quality].jpeg_quality;
1499 1521

  
1500 1522
            ret = send_jpeg_rect(vs, x, y, w, h, quality);
......
1514 1536
    uint32_t bg = 0, fg = 0;
1515 1537
    int colors;
1516 1538
    int ret = 0;
1539
    bool force_jpeg = false;
1540
    bool allow_jpeg = true;
1517 1541

  
1518 1542
    vnc_framebuffer_update(vs, x, y, w, h, vs->tight.type);
1519 1543

  
......
1521 1545
    vnc_raw_send_framebuffer_update(vs, x, y, w, h);
1522 1546
    vnc_tight_stop(vs);
1523 1547

  
1548
#ifdef CONFIG_VNC_JPEG
1549
    if (vs->tight.quality != -1) {
1550
        double freq = vnc_update_freq(vs, x, y, w, h);
1551

  
1552
        if (freq < tight_jpeg_conf[vs->tight.quality].jpeg_freq_min) {
1553
            allow_jpeg = false;
1554
        }
1555
        if (freq >= tight_jpeg_conf[vs->tight.quality].jpeg_freq_threshold) {
1556
            force_jpeg = true;
1557
            vnc_sent_lossy_rect(vs, x, y, w, h);
1558
        }
1559
    }
1560
#endif
1561

  
1524 1562
    colors = tight_fill_palette(vs, x, y, w * h, &fg, &bg, &palette);
1525 1563

  
1526 1564
#ifdef CONFIG_VNC_JPEG
1527
    if (vs->tight.quality != (uint8_t)-1) {
1528
        ret = send_sub_rect_jpeg(vs, x, y, w, h, bg, fg, colors, palette);
1565
    if (allow_jpeg && vs->tight.quality != (uint8_t)-1) {
1566
        ret = send_sub_rect_jpeg(vs, x, y, w, h, bg, fg, colors, palette,
1567
                                 force_jpeg);
1529 1568
    } else {
1530 1569
        ret = send_sub_rect_nojpeg(vs, x, y, w, h, bg, fg, colors, palette);
1531 1570
    }
......
1548 1587
    return send_solid_rect(vs);
1549 1588
}
1550 1589

  
1551
static int send_rect_simple(VncState *vs, int x, int y, int w, int h)
1590
static int send_rect_simple(VncState *vs, int x, int y, int w, int h,
1591
                            bool split)
1552 1592
{
1553 1593
    int max_size, max_width;
1554 1594
    int max_sub_width, max_sub_height;
......
1559 1599
    max_size = tight_conf[vs->tight.compression].max_rect_size;
1560 1600
    max_width = tight_conf[vs->tight.compression].max_rect_width;
1561 1601

  
1562
    if (w > max_width || w * h > max_size) {
1602
    if (split && (w > max_width || w * h > max_size)) {
1563 1603
        max_sub_width = (w > max_width) ? max_width : w;
1564 1604
        max_sub_height = max_size / max_sub_width;
1565 1605

  
......
1590 1630
        /* If a rectangle becomes too large, send its upper part now. */
1591 1631

  
1592 1632
        if (dy - y >= max_rows) {
1593
            n += send_rect_simple(vs, x, y, w, max_rows);
1633
            n += send_rect_simple(vs, x, y, w, max_rows, true);
1594 1634
            y += max_rows;
1595 1635
            h -= max_rows;
1596 1636
        }
......
1629 1669
            /* Send rectangles at top and left to solid-color area. */
1630 1670

  
1631 1671
            if (y_best != y) {
1632
                n += send_rect_simple(vs, x, y, w, y_best-y);
1672
                n += send_rect_simple(vs, x, y, w, y_best-y, true);
1633 1673
            }
1634 1674
            if (x_best != x) {
1635 1675
                n += tight_send_framebuffer_update(vs, x, y_best,
......
1656 1696
            return n;
1657 1697
        }
1658 1698
    }
1659
    return n + send_rect_simple(vs, x, y, w, h);
1699
    return n + send_rect_simple(vs, x, y, w, h, true);
1660 1700
}
1661 1701

  
1662 1702
static int tight_send_framebuffer_update(VncState *vs, int x, int y,
......
1671 1711
        vs->tight.pixel24 = false;
1672 1712
    }
1673 1713

  
1674
    if (w * h < VNC_TIGHT_MIN_SPLIT_RECT_SIZE)
1675
        return send_rect_simple(vs, x, y, w, h);
1714
    if (vs->tight.quality != -1) {
1715
        double freq = vnc_update_freq(vs, x, y, w, h);
1716

  
1717
        if (freq > tight_jpeg_conf[vs->tight.quality].jpeg_freq_threshold) {
1718
            return send_rect_simple(vs, x, y, w, h, false);
1719
        }
1720
    }
1721

  
1722
    if (w * h < VNC_TIGHT_MIN_SPLIT_RECT_SIZE) {
1723
        return send_rect_simple(vs, x, y, w, h, true);
1724
    }
1676 1725

  
1677 1726
    /* Calculate maximum number of rows in one non-solid rectangle. */
1678 1727

  

Also available in: Unified diff