Skip to content

Instantly share code, notes, and snippets.

@fador
Created August 22, 2022 06:02
Show Gist options
  • Save fador/23eb5de8c9f2e88241ed0ad4f0a34574 to your computer and use it in GitHub Desktop.
Save fador/23eb5de8c9f2e88241ed0ad4f0a34574 to your computer and use it in GitHub Desktop.
Example of using Kvazaar as a library together with uvgRTP
#define _CRT_SECURE_NO_WARNINGS
#include <uvgrtp/lib.hh>
#include <kvazaar.h>
#define VIDEO_FRAME_MAXLEN 1024*1024
#define INPUT_YUV_FILE "~/WORK/sequences/BQMall_832x480_60.yuv"
#define INPUT_WIDTH 832
#define INPUT_HEIGHT 480
int main(void)
{
const kvz_api* api = kvz_api_get(8);
kvz_config* config = api->config_alloc();
api->config_init(config);
api->config_parse(config, "preset", "ultrafast");
api->config_parse(config, "gop", "0");
api->config_parse(config, "vps-period", "1");
config->width = INPUT_WIDTH;
config->height = INPUT_HEIGHT;
config->qp = 37;
config->wpp = 1;
config->intra_period = 16;
config->aud_enable = 0;
config->calc_psnr = 0;
kvz_encoder* encoder = api->encoder_open(config);
kvz_picture* input_picture = api->picture_alloc(INPUT_WIDTH, INPUT_HEIGHT);
uvgrtp::context ctx;
uvgrtp::session* sess = ctx.create_session("127.0.0.1");
uvgrtp::media_stream* hevc = sess->create_stream(8890, 8880, RTP_FORMAT_H265, RTP_NO_FLAGS);
FILE* input = fopen(INPUT_YUV_FILE, "rb");
uint8_t* frame = new uint8_t[INPUT_WIDTH * INPUT_HEIGHT * 2];
uint8_t* data = new uint8_t[VIDEO_FRAME_MAXLEN];
while (fread(frame, (INPUT_WIDTH*INPUT_HEIGHT*3)>>1, 1, input) > 0) {
uint8_t* ptr = frame;
memcpy(input_picture->y, ptr, INPUT_WIDTH * INPUT_HEIGHT);
ptr += INPUT_WIDTH * INPUT_HEIGHT;
memcpy(input_picture->u, ptr, INPUT_WIDTH * INPUT_HEIGHT >> 2);
ptr += INPUT_WIDTH * INPUT_HEIGHT >> 2;
memcpy(input_picture->v, ptr, INPUT_WIDTH * INPUT_HEIGHT >> 2);
kvz_picture* recon_pic = NULL;
kvz_frame_info frame_info;
kvz_data_chunk* data_out = NULL;
uint32_t len_out = 0;
api->encoder_encode(encoder, input_picture,
&data_out, &len_out,
0, NULL,
&frame_info);
// If we get encoded output
if (data_out != 0) {
uint8_t* ptr = data;
kvz_data_chunk* previous_chunk = 0;
for (kvz_data_chunk* chunk = data_out; chunk != NULL; chunk = chunk->next)
{
memcpy(ptr, chunk->data, chunk->len);
ptr += chunk->len;
previous_chunk = chunk;
}
api->chunk_free(data_out);
static FILE* output = fopen("out.hevc", "wb");
fwrite(data, len_out, 1, output);
fprintf(stderr, "Sending: %d with type: %d\r\n", len_out, data[4]);
if (hevc->push_frame(data, len_out, RTP_NO_FLAGS) != RTP_ERROR::RTP_OK) {
fprintf(stderr, "Failed to send RTP frame!\r\n");
}
else {
fprintf(stderr, "Pushed a frame!\r\n");
}
}
std::this_thread::sleep_for(std::chrono::milliseconds(33));
}
delete[] frame;
delete[] data;
ctx.destroy_session(sess);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment