mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-27 19:24:06 +00:00
Move encoding to API.
- Api->encoder_encode can now be called repeatedly to start encoder jobs and to retrieve the results. Conflicts: src/encmain.c
This commit is contained in:
parent
9a3edce3fc
commit
4e5326d3d5
|
@ -203,7 +203,6 @@ int main(int argc, char *argv[])
|
||||||
// Start coding cycle while data on input and not on the last frame
|
// Start coding cycle while data on input and not on the last frame
|
||||||
encoder_state_t *state = &enc->states[current_encoder_state];
|
encoder_state_t *state = &enc->states[current_encoder_state];
|
||||||
while (cfg->frames == 0 || frames_started < cfg->frames) {
|
while (cfg->frames == 0 || frames_started < cfg->frames) {
|
||||||
image_t *img_out = NULL;
|
|
||||||
frames_started += 1;
|
frames_started += 1;
|
||||||
|
|
||||||
|
|
||||||
|
@ -223,24 +222,11 @@ int main(int argc, char *argv[])
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
encoder_next_frame(&enc->states[current_encoder_state], img_in);
|
image_t *img_out = NULL;
|
||||||
|
api->encoder_encode(enc, img_in, &img_out, NULL);
|
||||||
|
|
||||||
CHECKPOINT_MARK("read source frame: %d", encoder_states[current_encoder_state].global->frame + cfg->seek);
|
|
||||||
|
|
||||||
// The actual coding happens here, after this function we have a coded frame
|
|
||||||
encode_one_frame(&enc->states[current_encoder_state]);
|
|
||||||
|
|
||||||
//Switch to the next encoder
|
|
||||||
current_encoder_state = (current_encoder_state + 1) % (encoder->owf + 1);
|
|
||||||
state = &enc->states[current_encoder_state];
|
|
||||||
|
|
||||||
if (frames_started >= enc->num_encoder_states && !state->stats_done) {
|
|
||||||
threadqueue_waitfor(encoder->threadqueue, state->tqj_bitstream_written);
|
|
||||||
img_out = image_make_subimage(state->tile->frame->rec, 0, 0, state->tile->frame->width, state->tile->frame->height);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If all frame encoders are in use, wait for the next encoder to finish.
|
|
||||||
if (img_out != NULL) {
|
if (img_out != NULL) {
|
||||||
|
state = &enc->states[enc->cur_state_num];
|
||||||
double frame_psnr[3] = { 0.0, 0.0, 0.0 };
|
double frame_psnr[3] = { 0.0, 0.0, 0.0 };
|
||||||
encoder_compute_stats(state, recout, frame_psnr, &bitstream_length);
|
encoder_compute_stats(state, recout, frame_psnr, &bitstream_length);
|
||||||
|
|
||||||
|
@ -262,14 +248,20 @@ int main(int argc, char *argv[])
|
||||||
do {
|
do {
|
||||||
double frame_psnr[3] = { 0.0, 0.0, 0.0 };
|
double frame_psnr[3] = { 0.0, 0.0, 0.0 };
|
||||||
encoder_state_t *state = &enc->states[current_encoder_state];
|
encoder_state_t *state = &enc->states[current_encoder_state];
|
||||||
|
image_t *img_out = NULL;
|
||||||
|
api->encoder_encode(enc, NULL, &img_out, NULL);
|
||||||
|
|
||||||
|
if (img_out != NULL) {
|
||||||
|
encoder_state_t *state = &enc->states[current_encoder_state];
|
||||||
|
|
||||||
if (!state->stats_done) {
|
|
||||||
encoder_compute_stats(state, recout, frame_psnr, &bitstream_length);
|
encoder_compute_stats(state, recout, frame_psnr, &bitstream_length);
|
||||||
print_frame_info(state, frame_psnr);
|
print_frame_info(state, frame_psnr);
|
||||||
frames_done += 1;
|
frames_done += 1;
|
||||||
psnr_sum[0] += frame_psnr[0];
|
psnr_sum[0] += frame_psnr[0];
|
||||||
psnr_sum[1] += frame_psnr[1];
|
psnr_sum[1] += frame_psnr[1];
|
||||||
psnr_sum[2] += frame_psnr[2];
|
psnr_sum[2] += frame_psnr[2];
|
||||||
|
|
||||||
|
image_free(img_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
current_encoder_state = (current_encoder_state + 1) % (encoder->owf + 1);
|
current_encoder_state = (current_encoder_state + 1) % (encoder->owf + 1);
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "encoder.h"
|
#include "encoder.h"
|
||||||
#include "strategyselector.h"
|
#include "strategyselector.h"
|
||||||
#include "encoderstate.h"
|
#include "encoderstate.h"
|
||||||
|
#include "checkpoint.h"
|
||||||
|
|
||||||
|
|
||||||
static void kvazaar_close(kvz_encoder *encoder)
|
static void kvazaar_close(kvz_encoder *encoder)
|
||||||
|
@ -70,6 +71,7 @@ static kvz_encoder * kvazaar_open(config_t *cfg)
|
||||||
|
|
||||||
encoder->num_encoder_states = cfg->owf + 1;
|
encoder->num_encoder_states = cfg->owf + 1;
|
||||||
encoder->cur_state_num = 0;
|
encoder->cur_state_num = 0;
|
||||||
|
encoder->frames_started = 0;
|
||||||
encoder->states = MALLOC(encoder_state_t, encoder->num_encoder_states);
|
encoder->states = MALLOC(encoder_state_t, encoder->num_encoder_states);
|
||||||
if (!encoder->states) {
|
if (!encoder->states) {
|
||||||
goto kvazaar_open_failure;
|
goto kvazaar_open_failure;
|
||||||
|
@ -104,8 +106,29 @@ kvazaar_open_failure:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int kvazaar_encode(kvz_encoder *encoder, kvz_picture *pic_in, kvz_picture *pic_out, kvz_payload **payload)
|
static int kvazaar_encode(kvz_encoder *enc, kvz_picture *img_in, kvz_picture **img_out, kvz_payload **payload)
|
||||||
{
|
{
|
||||||
|
// If img_in is NULL, just return the next unfinished frame.
|
||||||
|
if (img_in != NULL) {
|
||||||
|
encoder_state_t *state = &enc->states[enc->cur_state_num];
|
||||||
|
|
||||||
|
enc->frames_started += 1;
|
||||||
|
encoder_next_frame(state, img_in);
|
||||||
|
|
||||||
|
CHECKPOINT_MARK("read source frame: %d", state->global->frame + enc->control->cfg->seek);
|
||||||
|
|
||||||
|
// The actual coding happens here, after this function we have a coded frame
|
||||||
|
encode_one_frame(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
enc->cur_state_num = (enc->cur_state_num + 1) % (enc->num_encoder_states);
|
||||||
|
encoder_state_t *state = &enc->states[enc->cur_state_num];
|
||||||
|
|
||||||
|
if (enc->frames_started >= enc->num_encoder_states && !state->stats_done) {
|
||||||
|
threadqueue_waitfor(enc->control->threadqueue, state->tqj_bitstream_written);
|
||||||
|
*img_out = image_make_subimage(state->tile->frame->rec, 0, 0, state->tile->frame->width, state->tile->frame->height);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,8 +90,9 @@ typedef struct image_t {
|
||||||
typedef struct kvz_encoder {
|
typedef struct kvz_encoder {
|
||||||
encoder_control_t* control;
|
encoder_control_t* control;
|
||||||
encoder_state_t* states;
|
encoder_state_t* states;
|
||||||
int num_encoder_states;
|
unsigned num_encoder_states;
|
||||||
int cur_state_num;
|
unsigned cur_state_num;
|
||||||
|
unsigned frames_started;
|
||||||
|
|
||||||
size_t bitstream_length;
|
size_t bitstream_length;
|
||||||
} kvz_encoder;
|
} kvz_encoder;
|
||||||
|
@ -115,7 +116,7 @@ typedef struct kvz_api {
|
||||||
// \param pic_out Picture containing the reconstructed data.
|
// \param pic_out Picture containing the reconstructed data.
|
||||||
// \param nals_out The first NAL containing bitstream generated, or NULL.
|
// \param nals_out The first NAL containing bitstream generated, or NULL.
|
||||||
// \return 1 on success, negative on error.
|
// \return 1 on success, negative on error.
|
||||||
int (*encoder_encode)(kvz_encoder *encoder, kvz_picture *pic_in, kvz_picture *pic_out, kvz_payload **payload);
|
int (*encoder_encode)(kvz_encoder *encoder, kvz_picture *pic_in, kvz_picture **pic_out, kvz_payload **payload);
|
||||||
} kvz_api;
|
} kvz_api;
|
||||||
|
|
||||||
// Append API version to the getters name to prevent linking against incompatible versions.
|
// Append API version to the getters name to prevent linking against incompatible versions.
|
||||||
|
|
Loading…
Reference in a new issue