mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-24 02:24:07 +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
|
||||
encoder_state_t *state = &enc->states[current_encoder_state];
|
||||
while (cfg->frames == 0 || frames_started < cfg->frames) {
|
||||
image_t *img_out = NULL;
|
||||
frames_started += 1;
|
||||
|
||||
|
||||
|
@ -223,24 +222,11 @@ int main(int argc, char *argv[])
|
|||
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) {
|
||||
state = &enc->states[enc->cur_state_num];
|
||||
double frame_psnr[3] = { 0.0, 0.0, 0.0 };
|
||||
encoder_compute_stats(state, recout, frame_psnr, &bitstream_length);
|
||||
|
||||
|
@ -262,14 +248,20 @@ int main(int argc, char *argv[])
|
|||
do {
|
||||
double frame_psnr[3] = { 0.0, 0.0, 0.0 };
|
||||
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);
|
||||
print_frame_info(state, frame_psnr);
|
||||
frames_done += 1;
|
||||
psnr_sum[0] += frame_psnr[0];
|
||||
psnr_sum[1] += frame_psnr[1];
|
||||
psnr_sum[2] += frame_psnr[2];
|
||||
|
||||
image_free(img_out);
|
||||
}
|
||||
|
||||
current_encoder_state = (current_encoder_state + 1) % (encoder->owf + 1);
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "encoder.h"
|
||||
#include "strategyselector.h"
|
||||
#include "encoderstate.h"
|
||||
#include "checkpoint.h"
|
||||
|
||||
|
||||
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->cur_state_num = 0;
|
||||
encoder->frames_started = 0;
|
||||
encoder->states = MALLOC(encoder_state_t, encoder->num_encoder_states);
|
||||
if (!encoder->states) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -90,8 +90,9 @@ typedef struct image_t {
|
|||
typedef struct kvz_encoder {
|
||||
encoder_control_t* control;
|
||||
encoder_state_t* states;
|
||||
int num_encoder_states;
|
||||
int cur_state_num;
|
||||
unsigned num_encoder_states;
|
||||
unsigned cur_state_num;
|
||||
unsigned frames_started;
|
||||
|
||||
size_t bitstream_length;
|
||||
} kvz_encoder;
|
||||
|
@ -115,7 +116,7 @@ typedef struct kvz_api {
|
|||
// \param pic_out Picture containing the reconstructed data.
|
||||
// \param nals_out The first NAL containing bitstream generated, or NULL.
|
||||
// \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;
|
||||
|
||||
// Append API version to the getters name to prevent linking against incompatible versions.
|
||||
|
|
Loading…
Reference in a new issue