h264: Set quality according to client's wishes
parent
528eac51a3
commit
b9a5b9a3f1
|
@ -25,7 +25,7 @@ typedef void (*h264_encoder_packet_handler_fn)(const void* payload, size_t size,
|
||||||
uint64_t pts, void* userdata);
|
uint64_t pts, void* userdata);
|
||||||
|
|
||||||
struct h264_encoder* h264_encoder_create(uint32_t width, uint32_t height,
|
struct h264_encoder* h264_encoder_create(uint32_t width, uint32_t height,
|
||||||
uint32_t format);
|
uint32_t format, int quality);
|
||||||
|
|
||||||
void h264_encoder_destroy(struct h264_encoder*);
|
void h264_encoder_destroy(struct h264_encoder*);
|
||||||
|
|
||||||
|
|
|
@ -298,7 +298,7 @@ failure:
|
||||||
}
|
}
|
||||||
|
|
||||||
static int h264_encoder__init_codec_context(struct h264_encoder* self,
|
static int h264_encoder__init_codec_context(struct h264_encoder* self,
|
||||||
const AVCodec* codec)
|
const AVCodec* codec, int quality)
|
||||||
{
|
{
|
||||||
self->codec_ctx = avcodec_alloc_context3(codec);
|
self->codec_ctx = avcodec_alloc_context3(codec);
|
||||||
if (!self->codec_ctx)
|
if (!self->codec_ctx)
|
||||||
|
@ -312,7 +312,7 @@ static int h264_encoder__init_codec_context(struct h264_encoder* self,
|
||||||
c->pix_fmt = AV_PIX_FMT_VAAPI;
|
c->pix_fmt = AV_PIX_FMT_VAAPI;
|
||||||
c->gop_size = INT32_MAX; /* We'll select key frames manually */
|
c->gop_size = INT32_MAX; /* We'll select key frames manually */
|
||||||
c->max_b_frames = 0; /* B-frames are bad for latency */
|
c->max_b_frames = 0; /* B-frames are bad for latency */
|
||||||
c->global_quality = 20;
|
c->global_quality = quality;
|
||||||
|
|
||||||
/* open-h264 requires baseline profile, so we use constrained
|
/* open-h264 requires baseline profile, so we use constrained
|
||||||
* baseline.
|
* baseline.
|
||||||
|
@ -489,7 +489,7 @@ static int find_render_node(char *node, size_t maxlen) {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct h264_encoder* h264_encoder_create(uint32_t width, uint32_t height,
|
struct h264_encoder* h264_encoder_create(uint32_t width, uint32_t height,
|
||||||
uint32_t format)
|
uint32_t format, int quality)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
@ -536,7 +536,7 @@ struct h264_encoder* h264_encoder_create(uint32_t width, uint32_t height,
|
||||||
if (h264_encoder__init_filters(self) < 0)
|
if (h264_encoder__init_filters(self) < 0)
|
||||||
goto filter_failure;
|
goto filter_failure;
|
||||||
|
|
||||||
if (h264_encoder__init_codec_context(self, codec) < 0)
|
if (h264_encoder__init_codec_context(self, codec, quality) < 0)
|
||||||
goto codec_context_failure;
|
goto codec_context_failure;
|
||||||
|
|
||||||
self->codec_ctx->hw_frames_ctx =
|
self->codec_ctx->hw_frames_ctx =
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "usdt.h"
|
#include "usdt.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
typedef void (*open_h264_ready_fn)(void*);
|
typedef void (*open_h264_ready_fn)(void*);
|
||||||
|
|
||||||
|
@ -45,6 +46,9 @@ struct open_h264 {
|
||||||
uint32_t format;
|
uint32_t format;
|
||||||
|
|
||||||
bool needs_reset;
|
bool needs_reset;
|
||||||
|
|
||||||
|
int quality;
|
||||||
|
bool quality_changed;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum open_h264_flags {
|
enum open_h264_flags {
|
||||||
|
@ -112,6 +116,7 @@ struct encoder* open_h264_new(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
self->pts = NVNC_NO_PTS;
|
self->pts = NVNC_NO_PTS;
|
||||||
|
self->quality = 6;
|
||||||
|
|
||||||
return (struct encoder*)self;
|
return (struct encoder*)self;
|
||||||
}
|
}
|
||||||
|
@ -129,8 +134,10 @@ static void open_h264_destroy(struct encoder* enc)
|
||||||
|
|
||||||
static int open_h264_resize(struct open_h264* self, struct nvnc_fb* fb)
|
static int open_h264_resize(struct open_h264* self, struct nvnc_fb* fb)
|
||||||
{
|
{
|
||||||
|
int quality = 51 - round((50.0 / 9.0) * (float)self->quality);
|
||||||
|
|
||||||
struct h264_encoder* encoder = h264_encoder_create(fb->width,
|
struct h264_encoder* encoder = h264_encoder_create(fb->width,
|
||||||
fb->height, fb->fourcc_format);
|
fb->height, fb->fourcc_format, quality);
|
||||||
if (!encoder)
|
if (!encoder)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -146,6 +153,7 @@ static int open_h264_resize(struct open_h264* self, struct nvnc_fb* fb)
|
||||||
self->height = fb->height;
|
self->height = fb->height;
|
||||||
self->format = fb->fourcc_format;
|
self->format = fb->fourcc_format;
|
||||||
self->needs_reset = true;
|
self->needs_reset = true;
|
||||||
|
self->quality_changed = false;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -159,7 +167,8 @@ static int open_h264_encode(struct encoder* enc, struct nvnc_fb* fb,
|
||||||
(void)damage;
|
(void)damage;
|
||||||
|
|
||||||
if (fb->width != self->width || fb->height != self->height ||
|
if (fb->width != self->width || fb->height != self->height ||
|
||||||
fb->fourcc_format != self->format) {
|
fb->fourcc_format != self->format ||
|
||||||
|
self->quality_changed) {
|
||||||
if (open_h264_resize(self, fb) < 0)
|
if (open_h264_resize(self, fb) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -214,9 +223,19 @@ static void open_h264_request_keyframe(struct encoder* enc)
|
||||||
h264_encoder_request_keyframe(self->encoder);
|
h264_encoder_request_keyframe(self->encoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void open_h264_set_quality(struct encoder* enc, int value)
|
||||||
|
{
|
||||||
|
struct open_h264* self = open_h264(enc);
|
||||||
|
if (value == 10)
|
||||||
|
value = 6;
|
||||||
|
self->quality_changed |= self->quality != value;
|
||||||
|
self->quality = value;
|
||||||
|
}
|
||||||
|
|
||||||
struct encoder_impl encoder_impl_open_h264 = {
|
struct encoder_impl encoder_impl_open_h264 = {
|
||||||
.flags = ENCODER_IMPL_FLAG_IGNORES_DAMAGE,
|
.flags = ENCODER_IMPL_FLAG_IGNORES_DAMAGE,
|
||||||
.destroy = open_h264_destroy,
|
.destroy = open_h264_destroy,
|
||||||
.encode = open_h264_encode,
|
.encode = open_h264_encode,
|
||||||
.request_key_frame = open_h264_request_keyframe,
|
.request_key_frame = open_h264_request_keyframe,
|
||||||
|
.set_quality = open_h264_set_quality,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue