tight: Implement quality control
parent
17e0d6036f
commit
25626a9048
|
@ -57,6 +57,8 @@ enum rfb_encodings {
|
|||
RFB_ENCODING_ZRLE = 16,
|
||||
RFB_ENCODING_CURSOR = -239,
|
||||
RFB_ENCODING_DESKTOPSIZE = -223,
|
||||
RFB_ENCODING_JPEG_HIGHQ = -23,
|
||||
RFB_ENCODING_JPEG_LOWQ = -32,
|
||||
};
|
||||
|
||||
enum rfb_server_to_client_msg_type {
|
||||
|
|
|
@ -24,8 +24,16 @@ struct nvnc_fb;
|
|||
struct pixman_region16;
|
||||
struct rfb_pixel_format;
|
||||
|
||||
enum tight_quality {
|
||||
TIGHT_QUALITY_UNSPEC = 0,
|
||||
TIGHT_QUALITY_LOSSLESS,
|
||||
TIGHT_QUALITY_LOW,
|
||||
TIGHT_QUALITY_HIGH,
|
||||
};
|
||||
|
||||
struct tight_encoder {
|
||||
z_stream zs[4];
|
||||
enum tight_quality quality;
|
||||
};
|
||||
|
||||
int tight_encoder_init(struct tight_encoder*);
|
||||
|
|
|
@ -449,6 +449,8 @@ static int on_client_set_encodings(struct nvnc_client* client)
|
|||
case RFB_ENCODING_ZRLE:
|
||||
case RFB_ENCODING_CURSOR:
|
||||
case RFB_ENCODING_DESKTOPSIZE:
|
||||
case RFB_ENCODING_JPEG_HIGHQ:
|
||||
case RFB_ENCODING_JPEG_LOWQ:
|
||||
client->encodings[n++] = encoding;
|
||||
}
|
||||
}
|
||||
|
|
49
src/tight.c
49
src/tight.c
|
@ -38,6 +38,27 @@
|
|||
|
||||
#define TIGHT_MAX_WIDTH 2048
|
||||
|
||||
enum tight_quality tight_get_quality(struct tight_encoder* self)
|
||||
{
|
||||
struct nvnc_client* client =
|
||||
container_of(self, struct nvnc_client, tight_encoder);
|
||||
|
||||
/* Note: The standard specifies that 16 is OK too, but we can only
|
||||
* handle 32
|
||||
*/
|
||||
if (client->pixfmt.bits_per_pixel != 32)
|
||||
return TIGHT_QUALITY_LOSSLESS;
|
||||
|
||||
for (size_t i = 0; i < client->n_encodings; ++i)
|
||||
switch (client->encodings[i]) {
|
||||
case RFB_ENCODING_JPEG_HIGHQ: return TIGHT_QUALITY_HIGH;
|
||||
case RFB_ENCODING_JPEG_LOWQ: return TIGHT_QUALITY_LOW;
|
||||
default:;
|
||||
}
|
||||
|
||||
return TIGHT_QUALITY_LOSSLESS;
|
||||
}
|
||||
|
||||
int tight_init_zstream(z_stream* zx)
|
||||
{
|
||||
int rc = deflateInit2(zx,
|
||||
|
@ -103,7 +124,14 @@ int tight_encode_box_jpeg(struct tight_encoder* self, struct vec* dst,
|
|||
unsigned char* buffer = NULL;
|
||||
size_t size = 0;
|
||||
|
||||
int quality = 50; /* 1 - 100 */
|
||||
int quality; /* 1 - 100 */
|
||||
|
||||
switch (self->quality) {
|
||||
case TIGHT_QUALITY_HIGH: quality = 66; break;
|
||||
case TIGHT_QUALITY_LOW: quality = 33; break;
|
||||
default: abort();
|
||||
}
|
||||
|
||||
enum TJPF tjfmt = get_jpeg_pixfmt(fb->fourcc_format);
|
||||
if (tjfmt == TJPF_UNKNOWN)
|
||||
return -1;
|
||||
|
@ -179,7 +207,6 @@ int tight_encode_box_basic(struct tight_encoder* self, struct vec* dst,
|
|||
uint32_t x, uint32_t y_start,
|
||||
uint32_t stride, uint32_t width, uint32_t height)
|
||||
{
|
||||
printf("Encode %u %u %u %u\n", x, y_start, width, height);
|
||||
struct nvnc_client* client =
|
||||
container_of(self, struct nvnc_client, tight_encoder);
|
||||
|
||||
|
@ -248,8 +275,22 @@ int tight_encode_box(struct tight_encoder* self, struct vec* dst,
|
|||
uint32_t x, uint32_t y,
|
||||
uint32_t stride, uint32_t width, uint32_t height)
|
||||
{
|
||||
// return tight_encode_box_basic(self, dst, fb, src_fmt, x, y, stride, width, height);
|
||||
return tight_encode_box_jpeg(self, dst, fb, x, y, stride, width, height);
|
||||
if (self->quality == TIGHT_QUALITY_UNSPEC)
|
||||
self->quality = tight_get_quality(self);
|
||||
|
||||
switch (self->quality) {
|
||||
case TIGHT_QUALITY_LOSSLESS:
|
||||
return tight_encode_box_basic(self, dst, fb, src_fmt, x, y,
|
||||
stride, width, height);
|
||||
case TIGHT_QUALITY_HIGH:
|
||||
case TIGHT_QUALITY_LOW:
|
||||
return tight_encode_box_jpeg(self, dst, fb, x, y, stride,
|
||||
width, height);
|
||||
case TIGHT_QUALITY_UNSPEC:;
|
||||
}
|
||||
|
||||
abort();
|
||||
return -1;
|
||||
}
|
||||
|
||||
int tight_encode_frame(struct tight_encoder* self, struct vec* dst,
|
||||
|
|
Loading…
Reference in New Issue